/**
 * Copyright (c) 2006-2017, JGraph Ltd
 * Copyright (c) 2006-2017, Gaudenz Alder
 */
var mxClient =
{
	/**
	 * Class: mxClient
	 *
	 * Bootstrapping mechanism for the mxGraph thin client. The production version
	 * of this file contains all code required to run the mxGraph thin client, as
	 * well as global constants to identify the browser and operating system in
	 * use. You may have to load chrome://global/content/contentAreaUtils.js in
	 * your page to disable certain security restrictions in Mozilla.
	 * 
	 * Variable: VERSION
	 *
	 * Contains the current version of the mxGraph library. The strings that
	 * communicate versions of mxGraph use the following format.
	 * 
	 * versionMajor.versionMinor.buildNumber.revisionNumber
	 * 
	 * Current version is 3.7.5.
	 */
	VERSION: '3.7.5',

	/**
	 * Variable: IS_IE
	 *
	 * True if the current browser is Internet Explorer 10 or below. Use <mxClient.IS_IE11>
	 * to detect IE 11.
	 */
	IS_IE: navigator.userAgent.indexOf('MSIE') >= 0,

	/**
	 * Variable: IS_IE6
	 *
	 * True if the current browser is Internet Explorer 6.x.
	 */
	IS_IE6: navigator.userAgent.indexOf('MSIE 6') >= 0,

	/**
	 * Variable: IS_IE11
	 *
	 * True if the current browser is Internet Explorer 11.x.
	 */
	IS_IE11: !!navigator.userAgent.match(/Trident\/7\./),

	/**
	 * Variable: IS_EDGE
	 *
	 * True if the current browser is Microsoft Edge.
	 */
	IS_EDGE: !!navigator.userAgent.match(/Edge\//),

	/**
	 * Variable: IS_QUIRKS
	 *
	 * True if the current browser is Internet Explorer and it is in quirks mode.
	 */
	IS_QUIRKS: navigator.userAgent.indexOf('MSIE') >= 0 && (document.documentMode == null || document.documentMode == 5),

	/**
	 * Variable: IS_EM
	 * 
	 * True if the browser is IE11 in enterprise mode (IE8 standards mode).
	 */
	IS_EM: 'spellcheck' in document.createElement('textarea') && document.documentMode == 8,

	/**
	 * Variable: VML_PREFIX
	 * 
	 * Prefix for VML namespace in node names. Default is 'v'.
	 */
	VML_PREFIX: 'v',

	/**
	 * Variable: OFFICE_PREFIX
	 * 
	 * Prefix for VML office namespace in node names. Default is 'o'.
	 */
	OFFICE_PREFIX: 'o',

	/**
	 * Variable: IS_NS
	 *
	 * True if the current browser is Netscape (including Firefox).
	 */
  	IS_NS: navigator.userAgent.indexOf('Mozilla/') >= 0 &&
  		navigator.userAgent.indexOf('MSIE') < 0 &&
  		navigator.userAgent.indexOf('Edge/') < 0,

	/**
	 * Variable: IS_OP
	 *
	 * True if the current browser is Opera.
	 */
  	IS_OP: navigator.userAgent.indexOf('Opera/') >= 0 ||
  		navigator.userAgent.indexOf('OPR/') >= 0,

	/**
	 * Variable: IS_OT
	 *
	 * True if -o-transform is available as a CSS style, ie for Opera browsers
	 * based on a Presto engine with version 2.5 or later.
	 */
  	IS_OT: navigator.userAgent.indexOf('Presto/') >= 0 &&
  		navigator.userAgent.indexOf('Presto/2.4.') < 0 &&
  		navigator.userAgent.indexOf('Presto/2.3.') < 0 &&
  		navigator.userAgent.indexOf('Presto/2.2.') < 0 &&
  		navigator.userAgent.indexOf('Presto/2.1.') < 0 &&
  		navigator.userAgent.indexOf('Presto/2.0.') < 0 &&
  		navigator.userAgent.indexOf('Presto/1.') < 0,
  	
	/**
	 * Variable: IS_SF
	 *
	 * True if the current browser is Safari.
	 */
  	IS_SF: navigator.userAgent.indexOf('AppleWebKit/') >= 0 &&
  		navigator.userAgent.indexOf('Chrome/') < 0 &&
  		navigator.userAgent.indexOf('Edge/') < 0,
  	
	/**
	 * Variable: IS_IOS
	 * 
	 * Returns true if the user agent is an iPad, iPhone or iPod.
	 */
  	IS_IOS: (navigator.userAgent.match(/(iPad|iPhone|iPod)/g) ? true : false),
  		
	/**
	 * Variable: IS_GC
	 *
	 * True if the current browser is Google Chrome.
	 */
  	IS_GC: navigator.userAgent.indexOf('Chrome/') >= 0 &&
		navigator.userAgent.indexOf('Edge/') < 0,
	
	/**
	 * Variable: IS_CHROMEAPP
	 *
	 * True if the this is running inside a Chrome App.
	 */
  	IS_CHROMEAPP: window.chrome != null && chrome.app != null && chrome.app.runtime != null,
		
	/**
	 * Variable: IS_FF
	 *
	 * True if the current browser is Firefox.
	 */
  	IS_FF: navigator.userAgent.indexOf('Firefox/') >= 0,
  	
	/**
	 * Variable: IS_MT
	 *
	 * True if -moz-transform is available as a CSS style. This is the case
	 * for all Firefox-based browsers newer than or equal 3, such as Camino,
	 * Iceweasel, Seamonkey and Iceape.
	 */
  	IS_MT: (navigator.userAgent.indexOf('Firefox/') >= 0 &&
		navigator.userAgent.indexOf('Firefox/1.') < 0 &&
  		navigator.userAgent.indexOf('Firefox/2.') < 0) ||
  		(navigator.userAgent.indexOf('Iceweasel/') >= 0 &&
  		navigator.userAgent.indexOf('Iceweasel/1.') < 0 &&
  		navigator.userAgent.indexOf('Iceweasel/2.') < 0) ||
  		(navigator.userAgent.indexOf('SeaMonkey/') >= 0 &&
  		navigator.userAgent.indexOf('SeaMonkey/1.') < 0) ||
  		(navigator.userAgent.indexOf('Iceape/') >= 0 &&
  		navigator.userAgent.indexOf('Iceape/1.') < 0),

	/**
	 * Variable: IS_SVG
	 *
	 * True if the browser supports SVG.
	 */
  	IS_SVG: navigator.userAgent.indexOf('Firefox/') >= 0 || // FF and Camino
	  	navigator.userAgent.indexOf('Iceweasel/') >= 0 || // Firefox on Debian
	  	navigator.userAgent.indexOf('Seamonkey/') >= 0 || // Firefox-based
	  	navigator.userAgent.indexOf('Iceape/') >= 0 || // Seamonkey on Debian
	  	navigator.userAgent.indexOf('Galeon/') >= 0 || // Gnome Browser (old)
	  	navigator.userAgent.indexOf('Epiphany/') >= 0 || // Gnome Browser (new)
	  	navigator.userAgent.indexOf('AppleWebKit/') >= 0 || // Safari/Google Chrome
	  	navigator.userAgent.indexOf('Gecko/') >= 0 || // Netscape/Gecko
	  	navigator.userAgent.indexOf('Opera/') >= 0 || // Opera
	  	(document.documentMode != null && document.documentMode >= 9), // IE9+

	/**
	 * Variable: NO_FO
	 *
	 * True if foreignObject support is not available. This is the case for
	 * Opera, older SVG-based browsers and all versions of IE.
	 */
  	NO_FO: !document.createElementNS || document.createElementNS('http://www.w3.org/2000/svg',
  		'foreignObject') != '[object SVGForeignObjectElement]' || navigator.userAgent.indexOf('Opera/') >= 0,

	/**
	 * Variable: IS_VML
	 *
	 * True if the browser supports VML.
	 */
  	IS_VML: navigator.appName.toUpperCase() == 'MICROSOFT INTERNET EXPLORER',

	/**
	 * Variable: IS_WIN
	 *
	 * True if the client is a Windows.
	 */
  	IS_WIN: navigator.appVersion.indexOf('Win') > 0,

	/**
	 * Variable: IS_MAC
	 *
	 * True if the client is a Mac.
	 */
  	IS_MAC: navigator.appVersion.indexOf('Mac') > 0,

	/**
	 * Variable: IS_TOUCH
	 * 
	 * True if this device supports touchstart/-move/-end events (Apple iOS,
	 * Android, Chromebook and Chrome Browser on touch-enabled devices).
	 */
  	IS_TOUCH: 'ontouchstart' in document.documentElement,

	/**
	 * Variable: IS_POINTER
	 * 
	 * True if this device supports Microsoft pointer events (always false on Macs).
	 */
  	IS_POINTER: window.PointerEvent != null && !(navigator.appVersion.indexOf('Mac') > 0),

	/**
	 * Variable: IS_LOCAL
	 *
	 * True if the documents location does not start with http:// or https://.
	 */
  	IS_LOCAL: document.location.href.indexOf('http://') < 0 &&
  			  document.location.href.indexOf('https://') < 0,

	/**
	 * Function: isBrowserSupported
	 *
	 * Returns true if the current browser is supported, that is, if
	 * <mxClient.IS_VML> or <mxClient.IS_SVG> is true.
	 * 
	 * Example:
	 * 
	 * (code)
	 * if (!mxClient.isBrowserSupported())
	 * {
	 *   mxUtils.error('Browser is not supported!', 200, false);
	 * }
	 * (end)
	 */
	isBrowserSupported: function()
	{
		return mxClient.IS_VML || mxClient.IS_SVG;
	},

	/**
	 * Function: link
	 *
	 * Adds a link node to the head of the document. Use this
	 * to add a stylesheet to the page as follows:
	 *
	 * (code)
	 * mxClient.link('stylesheet', filename);
	 * (end)
	 *
	 * where filename is the (relative) URL of the stylesheet. The charset
	 * is hardcoded to ISO-8859-1 and the type is text/css.
	 * 
	 * Parameters:
	 * 
	 * rel - String that represents the rel attribute of the link node.
	 * href - String that represents the href attribute of the link node.
	 * doc - Optional parent document of the link node.
	 */
	link: function(rel, href, doc)
	{
		doc = doc || document;

		// Workaround for Operation Aborted in IE6 if base tag is used in head
		if (mxClient.IS_IE6)
		{
			doc.write('<link rel="' + rel + '" href="' + href + '" charset="UTF-8" type="text/css"/>');
		}
		else
		{	
			var link = doc.createElement('link');
			
			link.setAttribute('rel', rel);
			link.setAttribute('href', href);
			link.setAttribute('charset', 'UTF-8');
			link.setAttribute('type', 'text/css');
			
			var head = doc.getElementsByTagName('head')[0];
	   		head.appendChild(link);
		}
	},
	
	/**
	 * Function: include
	 *
	 * Dynamically adds a script node to the document header.
	 * 
	 * In production environments, the includes are resolved in the mxClient.js
	 * file to reduce the number of requests required for client startup. This
	 * function should only be used in development environments, but not in
	 * production systems.
	 */
	include: function(src)
	{
		document.write('<script src="'+src+'"></script>');
	},
	
	/**
	 * Function: dispose
	 * 
	 * Frees up memory in IE by resolving cyclic dependencies between the DOM
	 * and the JavaScript objects.
	 */
	dispose: function()
	{
		// Cleans all objects where listeners have been added
		for (var i = 0; i < mxEvent.objects.length; i++)
		{
			if (mxEvent.objects[i].mxListenerList != null)
			{
				mxEvent.removeAllListeners(mxEvent.objects[i]);
			}
		}
	}

};

/**
 * Variable: mxLoadResources
 * 
 * Optional global config variable to toggle loading of the two resource files
 * in <mxGraph> and <mxEditor>. Default is true. NOTE: This is a global variable,
 * not a variable of mxClient.
 *
 * (code)
 * <script type="text/javascript">
 * 		var mxLoadResources = false;
 * </script>
 * <script type="text/javascript" src="/path/to/core/directory/js/mxClient.js"></script>
 * (end)
 */
if (typeof(mxLoadResources) == 'undefined')
{
	mxLoadResources = true;
}

/**
 * Variable: mxForceIncludes
 * 
 * Optional global config variable to force loading the JavaScript files in
 * development mode. Default is undefined. NOTE: This is a global variable,
 * not a variable of mxClient.
 *
 * (code)
 * <script type="text/javascript">
 * 		var mxLoadResources = true;
 * </script>
 * <script type="text/javascript" src="/path/to/core/directory/js/mxClient.js"></script>
 * (end)
 */
if (typeof(mxForceIncludes) == 'undefined')
{
	mxForceIncludes = false;
}

/**
 * Variable: mxResourceExtension
 * 
 * Optional global config variable to specify the extension of resource files.
 * Default is true. NOTE: This is a global variable, not a variable of mxClient.
 *
 * (code)
 * <script type="text/javascript">
 * 		var mxResourceExtension = '.txt';
 * </script>
 * <script type="text/javascript" src="/path/to/core/directory/js/mxClient.js"></script>
 * (end)
 */
if (typeof(mxResourceExtension) == 'undefined')
{
	mxResourceExtension = '.txt';
}

/**
 * Variable: mxLoadStylesheets
 * 
 * Optional global config variable to toggle loading of the CSS files when
 * the library is initialized. Default is true. NOTE: This is a global variable,
 * not a variable of mxClient.
 *
 * (code)
 * <script type="text/javascript">
 * 		var mxLoadStylesheets = false;
 * </script>
 * <script type="text/javascript" src="/path/to/core/directory/js/mxClient.js"></script>
 * (end)
 */
if (typeof(mxLoadStylesheets) == 'undefined')
{
	mxLoadStylesheets = true;
}

/**
 * Variable: basePath
 *
 * Basepath for all URLs in the core without trailing slash. Default is '.'.
 * Set mxBasePath prior to loading the mxClient library as follows to override
 * this setting:
 *
 * (code)
 * <script type="text/javascript">
 * 		mxBasePath = '/path/to/core/directory';
 * </script>
 * <script type="text/javascript" src="/path/to/core/directory/js/mxClient.js"></script>
 * (end)
 * 
 * When using a relative path, the path is relative to the URL of the page that
 * contains the assignment. Trailing slashes are automatically removed.
 */
if (typeof(mxBasePath) != 'undefined' && mxBasePath.length > 0)
{
	// Adds a trailing slash if required
	if (mxBasePath.substring(mxBasePath.length - 1) == '/')
	{
		mxBasePath = mxBasePath.substring(0, mxBasePath.length - 1);
	}

	mxClient.basePath = mxBasePath;
}
else
{
	mxClient.basePath = '.';
}

/**
 * Variable: imageBasePath
 *
 * Basepath for all images URLs in the core without trailing slash. Default is
 * <mxClient.basePath> + '/images'. Set mxImageBasePath prior to loading the
 * mxClient library as follows to override this setting:
 *
 * (code)
 * <script type="text/javascript">
 * 		mxImageBasePath = '/path/to/image/directory';
 * </script>
 * <script type="text/javascript" src="/path/to/core/directory/js/mxClient.js"></script>
 * (end)
 * 
 * When using a relative path, the path is relative to the URL of the page that
 * contains the assignment. Trailing slashes are automatically removed.
 */
if (typeof(mxImageBasePath) != 'undefined' && mxImageBasePath.length > 0)
{
	// Adds a trailing slash if required
	if (mxImageBasePath.substring(mxImageBasePath.length - 1) == '/')
	{
		mxImageBasePath = mxImageBasePath.substring(0, mxImageBasePath.length - 1);
	}

	mxClient.imageBasePath = mxImageBasePath;
}
else
{
	mxClient.imageBasePath = mxClient.basePath + '/images';	
}

/**
 * Variable: language
 *
 * Defines the language of the client, eg. en for english, de for german etc.
 * The special value 'none' will disable all built-in internationalization and
 * resource loading. See <mxResources.getSpecialBundle> for handling identifiers
 * with and without a dash.
 * 
 * Set mxLanguage prior to loading the mxClient library as follows to override
 * this setting:
 *
 * (code)
 * <script type="text/javascript">
 * 		mxLanguage = 'en';
 * </script>
 * <script type="text/javascript" src="js/mxClient.js"></script>
 * (end)
 * 
 * If internationalization is disabled, then the following variables should be
 * overridden to reflect the current language of the system. These variables are
 * cleared when i18n is disabled.
 * <mxEditor.askZoomResource>, <mxEditor.lastSavedResource>,
 * <mxEditor.currentFileResource>, <mxEditor.propertiesResource>,
 * <mxEditor.tasksResource>, <mxEditor.helpResource>, <mxEditor.outlineResource>,
 * <mxElbowEdgeHandler.doubleClickOrientationResource>, <mxUtils.errorResource>,
 * <mxUtils.closeResource>, <mxGraphSelectionModel.doneResource>,
 * <mxGraphSelectionModel.updatingSelectionResource>, <mxGraphView.doneResource>,
 * <mxGraphView.updatingDocumentResource>, <mxCellRenderer.collapseExpandResource>,
 * <mxGraph.containsValidationErrorsResource> and
 * <mxGraph.alreadyConnectedResource>.
 */
if (typeof(mxLanguage) != 'undefined' && mxLanguage != null)
{
	mxClient.language = mxLanguage;
}
else
{
	mxClient.language = (mxClient.IS_IE) ? navigator.userLanguage : navigator.language;
}

/**
 * Variable: defaultLanguage
 * 
 * Defines the default language which is used in the common resource files. Any
 * resources for this language will only load the common resource file, but not
 * the language-specific resource file. Default is 'en'.
 * 
 * Set mxDefaultLanguage prior to loading the mxClient library as follows to override
 * this setting:
 *
 * (code)
 * <script type="text/javascript">
 * 		mxDefaultLanguage = 'de';
 * </script>
 * <script type="text/javascript" src="js/mxClient.js"></script>
 * (end)
 */
if (typeof(mxDefaultLanguage) != 'undefined' && mxDefaultLanguage != null)
{
	mxClient.defaultLanguage = mxDefaultLanguage;
}
else
{
	mxClient.defaultLanguage = 'en';
}

// Adds all required stylesheets and namespaces
if (mxLoadStylesheets)
{
	mxClient.link('stylesheet', mxClient.basePath + '/css/common.css');
}

/**
 * Variable: languages
 *
 * Defines the optional array of all supported language extensions. The default
 * language does not have to be part of this list. See
 * <mxResources.isLanguageSupported>.
 *
 * (code)
 * <script type="text/javascript">
 * 		mxLanguages = ['de', 'it', 'fr'];
 * </script>
 * <script type="text/javascript" src="js/mxClient.js"></script>
 * (end)
 * 
 * This is used to avoid unnecessary requests to language files, ie. if a 404
 * will be returned.
 */
if (typeof(mxLanguages) != 'undefined' && mxLanguages != null)
{
	mxClient.languages = mxLanguages;
}

// Adds required namespaces, stylesheets and memory handling for older IE browsers
if (mxClient.IS_VML)
{
	if (mxClient.IS_SVG)
	{
		mxClient.IS_VML = false;
	}
	else
	{
		// Enables support for IE8 standards mode. Note that this requires all attributes for VML
		// elements to be set using direct notation, ie. node.attr = value. The use of setAttribute
		// is not possible.
		if (document.documentMode == 8)
		{
			document.namespaces.add(mxClient.VML_PREFIX, 'urn:schemas-microsoft-com:vml', '#default#VML');
			document.namespaces.add(mxClient.OFFICE_PREFIX, 'urn:schemas-microsoft-com:office:office', '#default#VML');
		}
		else
		{
			document.namespaces.add(mxClient.VML_PREFIX, 'urn:schemas-microsoft-com:vml');
			document.namespaces.add(mxClient.OFFICE_PREFIX, 'urn:schemas-microsoft-com:office:office');
		}

		// Workaround for limited number of stylesheets in IE (does not work in standards mode)
		if (mxClient.IS_QUIRKS && document.styleSheets.length >= 30)
		{
			(function()
			{
				var node = document.createElement('style');
				node.type = 'text/css';
				node.styleSheet.cssText = mxClient.VML_PREFIX + '\\:*{behavior:url(#default#VML)}' +
		        	mxClient.OFFICE_PREFIX + '\\:*{behavior:url(#default#VML)}';
		        document.getElementsByTagName('head')[0].appendChild(node);
			})();
		}
		else
		{
			document.createStyleSheet().cssText = mxClient.VML_PREFIX + '\\:*{behavior:url(#default#VML)}' +
		    	mxClient.OFFICE_PREFIX + '\\:*{behavior:url(#default#VML)}';
		}
	    
	    if (mxLoadStylesheets)
	    {
	    	mxClient.link('stylesheet', mxClient.basePath + '/css/explorer.css');
	    }
	
		// Cleans up resources when the application terminates
		window.attachEvent('onunload', mxClient.dispose);
	}
}

/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
var mxLog =
{
	/**
	 * Class: mxLog
	 * 
	 * A singleton class that implements a simple console.
	 * 
	 * Variable: consoleName
	 * 
	 * Specifies the name of the console window. Default is 'Console'.
	 */
	consoleName: 'Console',
	
	/**
	 * Variable: TRACE
	 * 
	 * Specified if the output for <enter> and <leave> should be visible in the
	 * console. Default is false.
	 */
	TRACE: false,

	/**
	 * Variable: DEBUG
	 * 
	 * Specifies if the output for <debug> should be visible in the console.
	 * Default is true.
	 */
	DEBUG: true,

	/**
	 * Variable: WARN
	 * 
	 * Specifies if the output for <warn> should be visible in the console.
	 * Default is true.
	 */
	WARN: true,

	/**
	 * Variable: buffer
	 * 
	 * Buffer for pre-initialized content.
	 */
	buffer: '',
	
	/**
	 * Function: init
	 *
	 * Initializes the DOM node for the console. This requires document.body to
	 * point to a non-null value. This is called from within <setVisible> if the
	 * log has not yet been initialized.
	 */
	init: function()
	{
		if (mxLog.window == null && document.body != null)
		{
			var title = mxLog.consoleName + ' - mxGraph ' + mxClient.VERSION;

			// Creates a table that maintains the layout
			var table = document.createElement('table');
			table.setAttribute('width', '100%');
			table.setAttribute('height', '100%');

			var tbody = document.createElement('tbody');
			var tr = document.createElement('tr');
			var td = document.createElement('td');
			td.style.verticalAlign = 'top';
				
			// Adds the actual console as a textarea
			mxLog.textarea = document.createElement('textarea');
			mxLog.textarea.setAttribute('wrap', 'off');
			mxLog.textarea.setAttribute('readOnly', 'true');
			mxLog.textarea.style.height = '100%';
			mxLog.textarea.style.resize = 'none';
			mxLog.textarea.value = mxLog.buffer;

			// Workaround for wrong width in standards mode
			if (mxClient.IS_NS && document.compatMode != 'BackCompat')
			{
				mxLog.textarea.style.width = '99%';
			}
			else
			{
				mxLog.textarea.style.width = '100%';
			}
			
			td.appendChild(mxLog.textarea);
			tr.appendChild(td);
			tbody.appendChild(tr);

			// Creates the container div
			tr = document.createElement('tr');
			mxLog.td = document.createElement('td');
			mxLog.td.style.verticalAlign = 'top';
			mxLog.td.setAttribute('height', '30px');
			
			tr.appendChild(mxLog.td);
			tbody.appendChild(tr);
			table.appendChild(tbody);

			// Adds various debugging buttons
			mxLog.addButton('Info', function (evt)
			{
				mxLog.info();
			});
		
			mxLog.addButton('DOM', function (evt)
			{
				var content = mxUtils.getInnerHtml(document.body);
				mxLog.debug(content);
			});
	
			mxLog.addButton('Trace', function (evt)
			{
				mxLog.TRACE = !mxLog.TRACE;
				
				if (mxLog.TRACE)
				{
					mxLog.debug('Tracing enabled');
				}
				else
				{
					mxLog.debug('Tracing disabled');
				}
			});	

			mxLog.addButton('Copy', function (evt)
			{
				try
				{
					mxUtils.copy(mxLog.textarea.value);
				}
				catch (err)
				{
					mxUtils.alert(err);
				}
			});			

			mxLog.addButton('Show', function (evt)
			{
				try
				{
					mxUtils.popup(mxLog.textarea.value);
				}
				catch (err)
				{
					mxUtils.alert(err);
				}
			});	
			
			mxLog.addButton('Clear', function (evt)
			{
				mxLog.textarea.value = '';
			});

			// Cross-browser code to get window size
			var h = 0;
			var w = 0;
			
			if (typeof(window.innerWidth) === 'number')
			{
				h = window.innerHeight;
				w = window.innerWidth;
			}
			else
			{
				h = (document.documentElement.clientHeight || document.body.clientHeight);
				w = document.body.clientWidth;
			}

			mxLog.window = new mxWindow(title, table, Math.max(0, w - 320), Math.max(0, h - 210), 300, 160);
			mxLog.window.setMaximizable(true);
			mxLog.window.setScrollable(false);
			mxLog.window.setResizable(true);
			mxLog.window.setClosable(true);
			mxLog.window.destroyOnClose = false;
			
			// Workaround for ignored textarea height in various setups
			if (((mxClient.IS_NS || mxClient.IS_IE) && !mxClient.IS_GC &&
				!mxClient.IS_SF && document.compatMode != 'BackCompat') ||
				document.documentMode == 11)
			{
				var elt = mxLog.window.getElement();
				
				var resizeHandler = function(sender, evt)
				{
					mxLog.textarea.style.height = Math.max(0, elt.offsetHeight - 70) + 'px';
				}; 
				
				mxLog.window.addListener(mxEvent.RESIZE_END, resizeHandler);
				mxLog.window.addListener(mxEvent.MAXIMIZE, resizeHandler);
				mxLog.window.addListener(mxEvent.NORMALIZE, resizeHandler);

				mxLog.textarea.style.height = '92px';
			}
		}
	},
	
	/**
	 * Function: info
	 * 
	 * Writes the current navigator information to the console.
	 */
	info: function()
	{
		mxLog.writeln(mxUtils.toString(navigator));
	},
			
	/**
	 * Function: addButton
	 * 
	 * Adds a button to the console using the given label and function.
	 */
	addButton: function(lab, funct)
	{
		var button = document.createElement('button');
		mxUtils.write(button, lab);
		mxEvent.addListener(button, 'click', funct);
		mxLog.td.appendChild(button);
	},
				
	/**
	 * Function: isVisible
	 * 
	 * Returns true if the console is visible.
	 */
	isVisible: function()
	{
		if (mxLog.window != null)
		{
			return mxLog.window.isVisible();
		}
		
		return false;
	},
	

	/**
	 * Function: show
	 * 
	 * Shows the console.
	 */
	show: function()
	{
		mxLog.setVisible(true);
	},

	/**
	 * Function: setVisible
	 * 
	 * Shows or hides the console.
	 */
	setVisible: function(visible)
	{
		if (mxLog.window == null)
		{
			mxLog.init();
		}

		if (mxLog.window != null)
		{
			mxLog.window.setVisible(visible);
		}
	},

	/**
	 * Function: enter
	 * 
	 * Writes the specified string to the console
	 * if <TRACE> is true and returns the current 
	 * time in milliseconds.
	 *
	 * Example:
	 * 
	 * (code)
	 * mxLog.show();
	 * var t0 = mxLog.enter('Hello');
	 * // Do something
	 * mxLog.leave('World!', t0);
	 * (end)
	 */
	enter: function(string)
	{
		if (mxLog.TRACE)
		{
			mxLog.writeln('Entering '+string);
			
			return new Date().getTime();
		}
	},

	/**
	 * Function: leave
	 * 
	 * Writes the specified string to the console
	 * if <TRACE> is true and computes the difference
	 * between the current time and t0 in milliseconds.
	 * See <enter> for an example.
	 */
	leave: function(string, t0)
	{
		if (mxLog.TRACE)
		{
			var dt = (t0 != 0) ? ' ('+(new Date().getTime() - t0)+' ms)' : '';
			mxLog.writeln('Leaving '+string+dt);
		}
	},
	
	/**
	 * Function: debug
	 * 
	 * Adds all arguments to the console if <DEBUG> is enabled.
	 *
	 * Example:
	 * 
	 * (code)
	 * mxLog.show();
	 * mxLog.debug('Hello, World!');
	 * (end)
	 */
	debug: function()
	{
		if (mxLog.DEBUG)
		{
			mxLog.writeln.apply(this, arguments);
		}
	},
	
	/**
	 * Function: warn
	 * 
	 * Adds all arguments to the console if <WARN> is enabled.
	 *
	 * Example:
	 * 
	 * (code)
	 * mxLog.show();
	 * mxLog.warn('Hello, World!');
	 * (end)
	 */
	warn: function()
	{
		if (mxLog.WARN)
		{
			mxLog.writeln.apply(this, arguments);
		}
	},

	/**
	 * Function: write
	 * 
	 * Adds the specified strings to the console.
	 */
	write: function()
	{
		var string = '';
		
		for (var i = 0; i < arguments.length; i++)
		{
			string += arguments[i];
			
			if (i < arguments.length - 1)
			{
				string += ' ';
			}
		}
		
		if (mxLog.textarea != null)
		{
			mxLog.textarea.value = mxLog.textarea.value + string;

			// Workaround for no update in Presto 2.5.22 (Opera 10.5)
			if (navigator.userAgent.indexOf('Presto/2.5') >= 0)
			{
				mxLog.textarea.style.visibility = 'hidden';
				mxLog.textarea.style.visibility = 'visible';
			}
			
			mxLog.textarea.scrollTop = mxLog.textarea.scrollHeight;
		}
		else
		{
			mxLog.buffer += string;
		}
	},
	
	/**
	 * Function: writeln
	 * 
	 * Adds the specified strings to the console, appending a linefeed at the
	 * end of each string.
	 */
	writeln: function()
	{
		var string = '';
		
		for (var i = 0; i < arguments.length; i++)
		{
			string += arguments[i];
			
			if (i < arguments.length - 1)
			{
				string += ' ';
			}
		}

		mxLog.write(string + '\n');
	}
	
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
var mxObjectIdentity =
{
	/**
	 * Class: mxObjectIdentity
	 * 
	 * Identity for JavaScript objects and functions. This is implemented using
	 * a simple incrementing counter which is stored in each object under
	 * <FIELD_NAME>.
	 * 
	 * The identity for an object does not change during its lifecycle.
	 * 
	 * Variable: FIELD_NAME
	 * 
	 * Name of the field to be used to store the object ID. Default is
	 * <code>mxObjectId</code>.
	 */
	FIELD_NAME: 'mxObjectId',

	/**
	 * Variable: counter
	 * 
	 * Current counter.
	 */
	counter: 0,

	/**
	 * Function: get
	 * 
	 * Returns the ID for the given object or function or null if no object
	 * is specified.
	 */
	get: function(obj)
	{
		if (obj != null)
		{
			if (obj[mxObjectIdentity.FIELD_NAME] == null)
			{
				if (typeof obj === 'object')
				{
					var ctor = mxUtils.getFunctionName(obj.constructor);
					obj[mxObjectIdentity.FIELD_NAME] = ctor + '#' + mxObjectIdentity.counter++;
				}
				else if (typeof obj === 'function')
				{
					obj[mxObjectIdentity.FIELD_NAME] = 'Function#' + mxObjectIdentity.counter++;
				}
			}
			
			return obj[mxObjectIdentity.FIELD_NAME];
		}
		
		return null;
	},

	/**
	 * Function: clear
	 * 
	 * Deletes the ID from the given object or function.
	 */
	clear: function(obj)
	{
		if (typeof(obj) === 'object' || typeof obj === 'function')
		{
			delete obj[mxObjectIdentity.FIELD_NAME];
		}
	}

};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxDictionary
 *
 * A wrapper class for an associative array with object keys. Note: This
 * implementation uses <mxObjectIdentitiy> to turn object keys into strings.
 * 
 * Constructor: mxEventSource
 *
 * Constructs a new dictionary which allows object to be used as keys.
 */
function mxDictionary()
{
	this.clear();
};

/**
 * Function: map
 *
 * Stores the (key, value) pairs in this dictionary.
 */
mxDictionary.prototype.map = null;

/**
 * Function: clear
 *
 * Clears the dictionary.
 */
mxDictionary.prototype.clear = function()
{
	this.map = {};
};

/**
 * Function: get
 *
 * Returns the value for the given key.
 */
mxDictionary.prototype.get = function(key)
{
	var id = mxObjectIdentity.get(key);
	
	return this.map[id];
};

/**
 * Function: put
 *
 * Stores the value under the given key and returns the previous
 * value for that key.
 */
mxDictionary.prototype.put = function(key, value)
{
	var id = mxObjectIdentity.get(key);
	var previous = this.map[id];
	this.map[id] = value;
	
	return previous;
};

/**
 * Function: remove
 *
 * Removes the value for the given key and returns the value that
 * has been removed.
 */
mxDictionary.prototype.remove = function(key)
{
	var id = mxObjectIdentity.get(key);
	var previous = this.map[id];
	delete this.map[id];
	
	return previous;
};

/**
 * Function: getKeys
 *
 * Returns all keys as an array.
 */
mxDictionary.prototype.getKeys = function()
{
	var result = [];
	
	for (var key in this.map)
	{
		result.push(key);
	}
	
	return result;
};

/**
 * Function: getValues
 *
 * Returns all values as an array.
 */
mxDictionary.prototype.getValues = function()
{
	var result = [];
	
	for (var key in this.map)
	{
		result.push(this.map[key]);
	}
	
	return result;
};

/**
 * Function: visit
 *
 * Visits all entries in the dictionary using the given function with the
 * following signature: function(key, value) where key is a string and
 * value is an object.
 * 
 * Parameters:
 * 
 * visitor - A function that takes the key and value as arguments.
 */
mxDictionary.prototype.visit = function(visitor)
{
	for (var key in this.map)
	{
		visitor(key, this.map[key]);
	}
};
/**
 * Copyright (c) 2006-2016, JGraph Ltd
 * Copyright (c) 2006-2016, Gaudenz Alder
 */
var mxResources =
{
	/**
	 * Class: mxResources
	 * 
	 * Implements internationalization. You can provide any number of 
	 * resource files on the server using the following format for the 
	 * filename: name[-en].properties. The en stands for any lowercase 
	 * 2-character language shortcut (eg. de for german, fr for french).
	 *
	 * If the optional language extension is omitted, then the file is used as a 
	 * default resource which is loaded in all cases. If a properties file for a 
	 * specific language exists, then it is used to override the settings in the 
	 * default resource. All entries in the file are of the form key=value. The
	 * values may then be accessed in code via <get>. Lines without 
	 * equal signs in the properties files are ignored.
	 *
	 * Resource files may either be added programmatically using
	 * <add> or via a resource tag in the UI section of the 
	 * editor configuration file, eg:
	 * 
	 * (code)
	 * <mxEditor>
	 *   <ui>
	 *     <resource basename="examples/resources/mxWorkflow"/>
	 * (end)
	 * 
	 * The above element will load examples/resources/mxWorkflow.properties as well
	 * as the language specific file for the current language, if it exists.
	 * 
	 * Values may contain placeholders of the form {1}...{n} where each placeholder
	 * is replaced with the value of the corresponding array element in the params
	 * argument passed to <mxResources.get>. The placeholder {1} maps to the first
	 * element in the array (at index 0).
	 * 
	 * See <mxClient.language> for more information on specifying the default
	 * language or disabling all loading of resources.
	 * 
	 * Lines that start with a # sign will be ignored.
	 * 
	 * Special characters
	 * 
	 * To use unicode characters, use the standard notation (eg. \u8fd1) or %u as a
	 * prefix (eg. %u20AC will display a Euro sign). For normal hex encoded strings,
	 * use % as a prefix, eg. %F6 will display a "o umlaut" (&ouml;).
	 * 
	 * See <resourcesEncoded> to disable this. If you disable this, make sure that
	 * your files are UTF-8 encoded.
	 * 
	 * Asynchronous loading
	 * 
	 * By default, the core adds two resource files synchronously at load time.
	 * To load these files asynchronously, set <mxLoadResources> to false
	 * before loading mxClient.js and use <mxResources.loadResources> instead.
	 * 
	 * Variable: resources
	 * 
	 * Associative array that maps from keys to values.
	 */
	resources: [],

	/**
	 * Variable: extension
	 * 
	 * Specifies the extension used for language files. Default is <mxResourceExtension>.
	 */
	extension: mxResourceExtension,

	/**
	 * Variable: resourcesEncoded
	 * 
	 * Specifies whether or not values in resource files are encoded with \u or
	 * percentage. Default is false.
	 */
	resourcesEncoded: false,

	/**
	 * Variable: loadDefaultBundle
	 * 
	 * Specifies if the default file for a given basename should be loaded.
	 * Default is true.
	 */
	loadDefaultBundle: true,

	/**
	 * Variable: loadDefaultBundle
	 * 
	 * Specifies if the specific language file file for a given basename should
	 * be loaded. Default is true.
	 */
	loadSpecialBundle: true,

	/**
	 * Function: isLanguageSupported
	 * 
	 * Hook for subclassers to disable support for a given language. This
	 * implementation returns true if lan is in <mxClient.languages>.
	 * 
	 * Parameters:
	 *
	 * lan - The current language.
	 */
	isLanguageSupported: function(lan)
	{
		if (mxClient.languages != null)
		{
			return mxUtils.indexOf(mxClient.languages, lan) >= 0;
		}
		
		return true;
	},

	/**
	 * Function: getDefaultBundle
	 * 
	 * Hook for subclassers to return the URL for the special bundle. This
	 * implementation returns basename + <extension> or null if
	 * <loadDefaultBundle> is false.
	 * 
	 * Parameters:
	 * 
	 * basename - The basename for which the file should be loaded.
	 * lan - The current language.
	 */
	getDefaultBundle: function(basename, lan)
	{
		if (mxResources.loadDefaultBundle || !mxResources.isLanguageSupported(lan))
		{
			return basename + mxResources.extension;
		}
		else
		{
			return null;
		}
	},

	/**
	 * Function: getSpecialBundle
	 * 
	 * Hook for subclassers to return the URL for the special bundle. This
	 * implementation returns basename + '_' + lan + <extension> or null if
	 * <loadSpecialBundle> is false or lan equals <mxClient.defaultLanguage>.
	 * 
	 * If <mxResources.languages> is not null and <mxClient.language> contains
	 * a dash, then this method checks if <isLanguageSupported> returns true
	 * for the full language (including the dash). If that returns false the
	 * first part of the language (up to the dash) will be tried as an extension.
	 * 
	 * If <mxResources.language> is null then the first part of the language is
	 * used to maintain backwards compatibility.
	 * 
	 * Parameters:
	 * 
	 * basename - The basename for which the file should be loaded.
	 * lan - The language for which the file should be loaded.
	 */
	getSpecialBundle: function(basename, lan)
	{
		if (mxClient.languages == null || !this.isLanguageSupported(lan))
		{
			var dash = lan.indexOf('-');
			
			if (dash > 0)
			{
				lan = lan.substring(0, dash);
			}
		}

		if (mxResources.loadSpecialBundle && mxResources.isLanguageSupported(lan) && lan != mxClient.defaultLanguage)
		{
			return basename + '_' + lan + mxResources.extension;
		}
		else
		{
			return null;
		}
	},

	/**
	 * Function: add
	 * 
	 * Adds the default and current language properties file for the specified
	 * basename. Existing keys are overridden as new files are added. If no
	 * callback is used then the request is synchronous.
	 *
	 * Example:
	 * 
	 * At application startup, additional resources may be 
	 * added using the following code:
	 * 
	 * (code)
	 * mxResources.add('resources/editor');
	 * (end)
	 * 
	 * Parameters:
	 * 
	 * basename - The basename for which the file should be loaded.
	 * lan - The language for which the file should be loaded.
	 * callback - Optional callback for asynchronous loading.
	 */
	add: function(basename, lan, callback)
	{
		lan = (lan != null) ? lan : ((mxClient.language != null) ?
			mxClient.language.toLowerCase() : mxConstants.NONE);
		
		if (lan != mxConstants.NONE)
		{
			var defaultBundle = mxResources.getDefaultBundle(basename, lan);
			var specialBundle = mxResources.getSpecialBundle(basename, lan);
			
			var loadSpecialBundle = function()
			{
				if (specialBundle != null)
				{
					if (callback)
					{
						mxUtils.get(specialBundle, function(req)
						{
							mxResources.parse(req.getText());
							callback();
						}, function()
						{
							callback();
						});
					}
					else
					{
						try
						{
					   		var req = mxUtils.load(specialBundle);
					   		
					   		if (req.isReady())
					   		{
					 	   		mxResources.parse(req.getText());
					   		}
				   		}
				   		catch (e)
				   		{
				   			// ignore
					   	}
					}
				}
				else if (callback != null)
				{
					callback();
				}
			}
			
			if (defaultBundle != null)
			{
				if (callback)
				{
					mxUtils.get(defaultBundle, function(req)
					{
						mxResources.parse(req.getText());
						loadSpecialBundle();
					}, function()
					{
						loadSpecialBundle();
					});
				}
				else
				{
					try
					{
				   		var req = mxUtils.load(defaultBundle);
				   		
				   		if (req.isReady())
				   		{
				 	   		mxResources.parse(req.getText());
				   		}
				   		
				   		loadSpecialBundle();
				  	}
				  	catch (e)
				  	{
				  		// ignore
				  	}
				}
			}
			else
			{
				// Overlays the language specific file (_lan-extension)
				loadSpecialBundle();
			}
		}
	},

	/**
	 * Function: parse
	 * 
	 * Parses the key, value pairs in the specified
	 * text and stores them as local resources.
	 */
	parse: function(text)
	{
		if (text != null)
		{
			var lines = text.split('\n');
			
			for (var i = 0; i < lines.length; i++)
			{
				if (lines[i].charAt(0) != '#')
				{
					var index = lines[i].indexOf('=');
					
					if (index > 0)
					{
						var key = lines[i].substring(0, index);
						var idx = lines[i].length;
						
						if (lines[i].charCodeAt(idx - 1) == 13)
						{
							idx--;
						}
						
						var value = lines[i].substring(index + 1, idx);
						
						if (this.resourcesEncoded)
						{
							value = value.replace(/\\(?=u[a-fA-F\d]{4})/g,"%");
							mxResources.resources[key] = unescape(value);
						}
						else
						{
							mxResources.resources[key] = value;
						}
					}
				}
			}
		}
	},

	/**
	 * Function: get
	 * 
	 * Returns the value for the specified resource key.
	 *
	 * Example:
	 * To read the value for 'welomeMessage', use the following:
	 * (code)
	 * var result = mxResources.get('welcomeMessage') || '';
	 * (end)
	 *
	 * This would require an entry of the following form in
	 * one of the English language resource files:
	 * (code)
	 * welcomeMessage=Welcome to mxGraph!
	 * (end)
	 * 
	 * The part behind the || is the string value to be used if the given
	 * resource is not available.
	 * 
	 * Parameters:
	 * 
	 * key - String that represents the key of the resource to be returned.
	 * params - Array of the values for the placeholders of the form {1}...{n}
	 * to be replaced with in the resulting string.
	 * defaultValue - Optional string that specifies the default return value.
	 */
	get: function(key, params, defaultValue)
	{
		var value = mxResources.resources[key];
		
		// Applies the default value if no resource was found
		if (value == null)
		{
			value = defaultValue;
		}
		
		// Replaces the placeholders with the values in the array
		if (value != null && params != null)
		{
			value = mxResources.replacePlaceholders(value, params);
		}
		
		return value;
	},

	/**
	 * Function: replacePlaceholders
	 * 
	 * Replaces the given placeholders with the given parameters.
	 * 
	 * Parameters:
	 * 
	 * value - String that contains the placeholders.
	 * params - Array of the values for the placeholders of the form {1}...{n}
	 * to be replaced with in the resulting string.
	 */
	replacePlaceholders: function(value, params)
	{
		var result = [];
		var index = null;
		
		for (var i = 0; i < value.length; i++)
		{
			var c = value.charAt(i);

			if (c == '{')
			{
				index = '';
			}
			else if (index != null && 	c == '}')
			{
				index = parseInt(index)-1;
				
				if (index >= 0 && index < params.length)
				{
					result.push(params[index]);
				}
				
				index = null;
			}
			else if (index != null)
			{
				index += c;
			}
			else
			{
				result.push(c);
			}
		}
		
		return result.join('');
	},

	/**
	 * Function: loadResources
	 * 
	 * Loads all required resources asynchronously. Use this to load the graph and
	 * editor resources if <mxLoadResources> is false.
	 * 
	 * Parameters:
	 * 
	 * callback - Callback function for asynchronous loading.
	 */
	loadResources: function(callback)
	{
		mxResources.add(mxClient.basePath+'/resources/editor', null, function()
		{
			mxResources.add(mxClient.basePath+'/resources/graph', null, callback);
		});
	}

};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxPoint
 *
 * Implements a 2-dimensional vector with double precision coordinates.
 * 
 * Constructor: mxPoint
 *
 * Constructs a new point for the optional x and y coordinates. If no
 * coordinates are given, then the default values for <x> and <y> are used.
 */
function mxPoint(x, y)
{
	this.x = (x != null) ? x : 0;
	this.y = (y != null) ? y : 0;
};

/**
 * Variable: x
 *
 * Holds the x-coordinate of the point. Default is 0.
 */
mxPoint.prototype.x = null;

/**
 * Variable: y
 *
 * Holds the y-coordinate of the point. Default is 0.
 */
mxPoint.prototype.y = null;

/**
 * Function: equals
 * 
 * Returns true if the given object equals this point.
 */
mxPoint.prototype.equals = function(obj)
{
	return obj != null && obj.x == this.x && obj.y == this.y;
};

/**
 * Function: clone
 *
 * Returns a clone of this <mxPoint>.
 */
mxPoint.prototype.clone = function()
{
	// Handles subclasses as well
	return mxUtils.clone(this);
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxRectangle
 *
 * Extends <mxPoint> to implement a 2-dimensional rectangle with double
 * precision coordinates.
 * 
 * Constructor: mxRectangle
 *
 * Constructs a new rectangle for the optional parameters. If no parameters
 * are given then the respective default values are used.
 */
function mxRectangle(x, y, width, height)
{
	mxPoint.call(this, x, y);

	this.width = (width != null) ? width : 0;
	this.height = (height != null) ? height : 0;
};

/**
 * Extends mxPoint.
 */
mxRectangle.prototype = new mxPoint();
mxRectangle.prototype.constructor = mxRectangle;

/**
 * Variable: width
 *
 * Holds the width of the rectangle. Default is 0.
 */
mxRectangle.prototype.width = null;

/**
 * Variable: height
 *
 * Holds the height of the rectangle. Default is 0.
 */
mxRectangle.prototype.height = null;

/**
 * Function: setRect
 * 
 * Sets this rectangle to the specified values
 */
mxRectangle.prototype.setRect = function(x, y, w, h)
{
    this.x = x;
    this.y = y;
    this.width = w;
    this.height = h;
};

/**
 * Function: getCenterX
 * 
 * Returns the x-coordinate of the center point.
 */
mxRectangle.prototype.getCenterX = function ()
{
	return this.x + this.width/2;
};

/**
 * Function: getCenterY
 * 
 * Returns the y-coordinate of the center point.
 */
mxRectangle.prototype.getCenterY = function ()
{
	return this.y + this.height/2;
};

/**
 * Function: add
 *
 * Adds the given rectangle to this rectangle.
 */
mxRectangle.prototype.add = function(rect)
{
	if (rect != null)
	{
		var minX = Math.min(this.x, rect.x);
		var minY = Math.min(this.y, rect.y);
		var maxX = Math.max(this.x + this.width, rect.x + rect.width);
		var maxY = Math.max(this.y + this.height, rect.y + rect.height);
		
		this.x = minX;
		this.y = minY;
		this.width = maxX - minX;
		this.height = maxY - minY;
	}
};

/**
 * Function: intersect
 * 
 * Changes this rectangle to where it overlaps with the given rectangle.
 */
mxRectangle.prototype.intersect = function(rect)
{
	if (rect != null)
	{
		var r1 = this.x + this.width;
		var r2 = rect.x + rect.width;
		
		var b1 = this.y + this.height;
		var b2 = rect.y + rect.height;
		
		this.x = Math.max(this.x, rect.x);
		this.y = Math.max(this.y, rect.y);
		this.width = Math.min(r1, r2) - this.x;
		this.height = Math.min(b1, b2) - this.y;
	}
};

/**
 * Function: grow
 *
 * Grows the rectangle by the given amount, that is, this method subtracts
 * the given amount from the x- and y-coordinates and adds twice the amount
 * to the width and height.
 */
mxRectangle.prototype.grow = function(amount)
{
	this.x -= amount;
	this.y -= amount;
	this.width += 2 * amount;
	this.height += 2 * amount;
};

/**
 * Function: getPoint
 * 
 * Returns the top, left corner as a new <mxPoint>.
 */
mxRectangle.prototype.getPoint = function()
{
	return new mxPoint(this.x, this.y);
};

/**
 * Function: rotate90
 * 
 * Rotates this rectangle by 90 degree around its center point.
 */
mxRectangle.prototype.rotate90 = function()
{
	var t = (this.width - this.height) / 2;
	this.x += t;
	this.y -= t;
	var tmp = this.width;
	this.width = this.height;
	this.height = tmp;
};

/**
 * Function: equals
 * 
 * Returns true if the given object equals this rectangle.
 */
mxRectangle.prototype.equals = function(obj)
{
	return obj != null && obj.x == this.x && obj.y == this.y &&
		obj.width == this.width && obj.height == this.height;
};

/**
 * Function: fromRectangle
 * 
 * Returns a new <mxRectangle> which is a copy of the given rectangle.
 */
mxRectangle.fromRectangle = function(rect)
{
	return new mxRectangle(rect.x, rect.y, rect.width, rect.height);
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
var mxEffects =
{

	/**
	 * Class: mxEffects
	 * 
	 * Provides animation effects.
	 */

	/**
	 * Function: animateChanges
	 * 
	 * Asynchronous animated move operation. See also: <mxMorphing>.
	 * 
	 * Example:
	 * 
	 * (code)
	 * graph.model.addListener(mxEvent.CHANGE, function(sender, evt)
	 * {
	 *   var changes = evt.getProperty('edit').changes;
	 * 
	 *   if (changes.length < 10)
	 *   {
	 *     mxEffects.animateChanges(graph, changes);
	 *   }
	 * });
	 * (end)
	 * 
	 * Parameters:
	 * 
	 * graph - <mxGraph> that received the changes.
	 * changes - Array of changes to be animated.
	 * done - Optional function argument that is invoked after the
	 * last step of the animation.
	 */
	animateChanges: function(graph, changes, done)
	{
		var maxStep = 10;
		var step = 0;

		var animate = function() 
		{
			var isRequired = false;
			
			for (var i = 0; i < changes.length; i++)
			{
				var change = changes[i];
				
				if (change instanceof mxGeometryChange ||
					change instanceof mxTerminalChange ||
					change instanceof mxValueChange ||
					change instanceof mxChildChange ||
					change instanceof mxStyleChange)
				{
					var state = graph.getView().getState(change.cell || change.child, false);
					
					if (state != null)
					{
						isRequired = true;
					
						if (change.constructor != mxGeometryChange || graph.model.isEdge(change.cell))
						{
							mxUtils.setOpacity(state.shape.node, 100 * step / maxStep);
						}
						else
						{
							var scale = graph.getView().scale;					

							var dx = (change.geometry.x - change.previous.x) * scale;
							var dy = (change.geometry.y - change.previous.y) * scale;
							
							var sx = (change.geometry.width - change.previous.width) * scale;
							var sy = (change.geometry.height - change.previous.height) * scale;
							
							if (step == 0)
							{
								state.x -= dx;
								state.y -= dy;
								state.width -= sx;
								state.height -= sy;
							}
							else
							{
								state.x += dx / maxStep;
								state.y += dy / maxStep;
								state.width += sx / maxStep;
								state.height += sy / maxStep;
							}
							
							graph.cellRenderer.redraw(state);
							
							// Fades all connected edges and children
							mxEffects.cascadeOpacity(graph, change.cell, 100 * step / maxStep);
						}
					}
				}
			}

			if (step < maxStep && isRequired)
			{
				step++;
				window.setTimeout(animate, delay);
			}
			else if (done != null)
			{
				done();
			}
		};
		
		var delay = 30;
		animate();
	},
    
	/**
	 * Function: cascadeOpacity
	 * 
	 * Sets the opacity on the given cell and its descendants.
	 * 
	 * Parameters:
	 * 
	 * graph - <mxGraph> that contains the cells.
	 * cell - <mxCell> to set the opacity for.
	 * opacity - New value for the opacity in %.
	 */
    cascadeOpacity: function(graph, cell, opacity)
	{
		// Fades all children
		var childCount = graph.model.getChildCount(cell);
		
		for (var i=0; i<childCount; i++)
		{
			var child = graph.model.getChildAt(cell, i);
			var childState = graph.getView().getState(child);
			
			if (childState != null)
			{
				mxUtils.setOpacity(childState.shape.node, opacity);
				mxEffects.cascadeOpacity(graph, child, opacity);
			}
		}
		
		// Fades all connected edges
		var edges = graph.model.getEdges(cell);
		
		if (edges != null)
		{
			for (var i=0; i<edges.length; i++)
			{
				var edgeState = graph.getView().getState(edges[i]);
				
				if (edgeState != null)
				{
					mxUtils.setOpacity(edgeState.shape.node, opacity);
				}
			}
		}
	},

	/**
	 * Function: fadeOut
	 * 
	 * Asynchronous fade-out operation.
	 */
	fadeOut: function(node, from, remove, step, delay, isEnabled)
	{
		step = step || 40;
		delay = delay || 30;
		
		var opacity = from || 100;
		
		mxUtils.setOpacity(node, opacity);
		
		if (isEnabled || isEnabled == null)
		{
			var f = function()
			{
			    opacity = Math.max(opacity-step, 0);
				mxUtils.setOpacity(node, opacity);
				
				if (opacity > 0)
				{
					window.setTimeout(f, delay);
				}
				else
				{
					node.style.visibility = 'hidden';
					
					if (remove && node.parentNode)
					{
						node.parentNode.removeChild(node);
					}
				}
			};
			window.setTimeout(f, delay);
		}
		else
		{
			node.style.visibility = 'hidden';
			
			if (remove && node.parentNode)
			{
				node.parentNode.removeChild(node);
			}
		}
	}

};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
var mxUtils =
{
	/**
	 * Class: mxUtils
	 * 
	 * A singleton class that provides cross-browser helper methods.
	 * This is a global functionality. To access the functions in this
	 * class, use the global classname appended by the functionname.
	 * You may have to load chrome://global/content/contentAreaUtils.js
	 * to disable certain security restrictions in Mozilla for the <open>,
	 * <save>, <saveAs> and <copy> function.
	 * 
	 * For example, the following code displays an error message:
	 * 
	 * (code)
	 * mxUtils.error('Browser is not supported!', 200, false);
	 * (end)
	 * 
	 * Variable: errorResource
	 * 
	 * Specifies the resource key for the title of the error window. If the
	 * resource for this key does not exist then the value is used as
	 * the title. Default is 'error'.
	 */
	errorResource: (mxClient.language != 'none') ? 'error' : '',
	
	/**
	 * Variable: closeResource
	 * 
	 * Specifies the resource key for the label of the close button. If the
	 * resource for this key does not exist then the value is used as
	 * the label. Default is 'close'.
	 */
	closeResource: (mxClient.language != 'none') ? 'close' : '',

	/**
	 * Variable: errorImage
	 * 
	 * Defines the image used for error dialogs.
	 */
	errorImage: mxClient.imageBasePath + '/error.gif',
	
	/**
	 * Function: removeCursors
	 * 
	 * Removes the cursors from the style of the given DOM node and its
	 * descendants.
	 * 
	 * Parameters:
	 * 
	 * element - DOM node to remove the cursor style from.
	 */
	removeCursors: function(element)
	{
		if (element.style != null)
		{
			element.style.cursor = '';
		}
		
		var children = element.childNodes;
		
		if (children != null)
		{
	        var childCount = children.length;
	        
	        for (var i = 0; i < childCount; i += 1)
	        {
	            mxUtils.removeCursors(children[i]);
	        }
	    }
	},

	/**
	 * Function: getCurrentStyle
	 * 
	 * Returns the current style of the specified element.
	 * 
	 * Parameters:
	 * 
	 * element - DOM node whose current style should be returned.
	 */
	getCurrentStyle: function()
	{
		if (mxClient.IS_IE)
		{
			return function(element)
			{
				return (element != null) ? element.currentStyle : null;
			};
		}
		else
		{
			return function(element)
			{
				return (element != null) ?
					window.getComputedStyle(element, '') :
					null;
			};
		}
	}(),
	
	/**
	 * Function: parseCssNumber
	 * 
	 * Parses the given CSS numeric value adding handling for the values thin,
	 * medium and thick (2, 4 and 6).
	 */
	parseCssNumber: function(value)
	{
		if (value == 'thin')
		{
			value = '2';
		}
		else if (value == 'medium')
		{
			value = '4';
		}
		else if (value == 'thick')
		{
			value = '6';
		}
		
		value = parseFloat(value);
		
		if (isNaN(value))
		{
			value = 0;
		}
		
		return value;
	},

	/**
	 * Function: setPrefixedStyle
	 * 
	 * Adds the given style with the standard name and an optional vendor prefix for the current
	 * browser.
	 * 
	 * (code)
	 * mxUtils.setPrefixedStyle(node.style, 'transformOrigin', '0% 0%');
	 * (end)
	 */
	setPrefixedStyle: function()
	{
		var prefix = null;
		
		if (mxClient.IS_OT)
		{
			prefix = 'O';
		}
		else if (mxClient.IS_SF || mxClient.IS_GC)
		{
			prefix = 'Webkit';
		}
		else if (mxClient.IS_MT)
		{
			prefix = 'Moz';
		}
		else if (mxClient.IS_IE && document.documentMode >= 9 && document.documentMode < 10)
		{
			prefix = 'ms';
		}

		return function(style, name, value)
		{
			style[name] = value;
			
			if (prefix != null && name.length > 0)
			{
				name = prefix + name.substring(0, 1).toUpperCase() + name.substring(1);
				style[name] = value;
			}
		};
	}(),
	
	/**
	 * Function: hasScrollbars
	 * 
	 * Returns true if the overflow CSS property of the given node is either
	 * scroll or auto.
	 * 
	 * Parameters:
	 * 
	 * node - DOM node whose style should be checked for scrollbars.
	 */
	hasScrollbars: function(node)
	{
		var style = mxUtils.getCurrentStyle(node);

		return style != null && (style.overflow == 'scroll' || style.overflow == 'auto');
	},
	
	/**
	 * Function: bind
	 * 
	 * Returns a wrapper function that locks the execution scope of the given
	 * function to the specified scope. Inside funct, the "this" keyword
	 * becomes a reference to that scope.
	 */
	bind: function(scope, funct)
	{
		return function()
		{
			return funct.apply(scope, arguments);
		};
	},
	
	/**
	 * Function: eval
	 * 
	 * Evaluates the given expression using eval and returns the JavaScript
	 * object that represents the expression result. Supports evaluation of
	 * expressions that define functions and returns the function object for
	 * these expressions.
	 * 
	 * Parameters:
	 * 
	 * expr - A string that represents a JavaScript expression.
	 */
	eval: function(expr)
	{
		var result = null;

		if (expr.indexOf('function') >= 0)
		{
			try
			{
				eval('var _mxJavaScriptExpression='+expr);
				result = _mxJavaScriptExpression;
				// TODO: Use delete here?
				_mxJavaScriptExpression = null;
			}
			catch (e)
			{
				mxLog.warn(e.message + ' while evaluating ' + expr);
			}
		}
		else
		{
			try
			{
				result = eval(expr);
			}
			catch (e)
			{
				mxLog.warn(e.message + ' while evaluating ' + expr);
			}
		}
		
		return result;
	},
	
	/**
	 * Function: findNode
	 * 
	 * Returns the first node where attr equals value.
	 * This implementation does not use XPath.
	 */
	findNode: function(node, attr, value)
	{
		if (node.nodeType == mxConstants.NODETYPE_ELEMENT)
		{
			var tmp = node.getAttribute(attr);
	
			if (tmp != null && tmp == value)
			{
				return node;
			}
		}
		
		node = node.firstChild;
		
		while (node != null)
		{
			var result = mxUtils.findNode(node, attr, value);
			
			if (result != null)
			{
				return result;
			}
			
			node = node.nextSibling;
		}
		
		return null;
	},

	/**
	 * Function: getFunctionName
	 * 
	 * Returns the name for the given function.
	 * 
	 * Parameters:
	 * 
	 * f - JavaScript object that represents a function.
	 */
	getFunctionName: function(f)
	{
		var str = null;

		if (f != null)
		{
			if (f.name != null)
			{
				str = f.name;
			}
			else
			{
				str = mxUtils.trim(f.toString());
				
				if (/^function\s/.test(str))
				{
					str = mxUtils.ltrim(str.substring(9));
					var idx2 = str.indexOf('(');
					
					if (idx2 > 0)
					{
						str = str.substring(0, idx2);
					}
				}
			}
		}
		
		return str;
	},

	/**
	 * Function: indexOf
	 * 
	 * Returns the index of obj in array or -1 if the array does not contain
	 * the given object.
	 * 
	 * Parameters:
	 * 
	 * array - Array to check for the given obj.
	 * obj - Object to find in the given array.
	 */
	indexOf: function(array, obj)
	{
		if (array != null && obj != null)
		{
			for (var i = 0; i < array.length; i++)
			{
				if (array[i] == obj)
				{
					return i;
				}
			}
		}
		
		return -1;
	},

	/**
	 * Function: forEach
	 * 
	 * Calls the given function for each element of the given array and returns
	 * the array.
	 * 
	 * Parameters:
	 * 
	 * array - Array that contains the elements.
	 * fn - Function to be called for each object.
	 */
	forEach: function(array, fn)
	{
		if (array != null && fn != null)
		{
			for (var i = 0; i < array.length; i++)
			{
				fn(array[i]);
			}
		}
		
		return array;
	},

	/**
	 * Function: remove
	 * 
	 * Removes all occurrences of the given object in the given array or
	 * object. If there are multiple occurrences of the object, be they
	 * associative or as an array entry, all occurrences are removed from
	 * the array or deleted from the object. By removing the object from
	 * the array, all elements following the removed element are shifted
	 * by one step towards the beginning of the array.
	 * 
	 * The length of arrays is not modified inside this function.
	 * 
	 * Parameters:
	 * 
	 * obj - Object to find in the given array.
	 * array - Array to check for the given obj.
	 */
	remove: function(obj, array)
	{
		var result = null;
		
		if (typeof(array) == 'object')
		{
			var index = mxUtils.indexOf(array, obj);
			
			while (index >= 0)
			{
				array.splice(index, 1);
				result = obj;
				index = mxUtils.indexOf(array, obj);
			}
		}

		for (var key in array)
		{
			if (array[key] == obj)
			{
				delete array[key];
				result = obj;
			}
		}
		
		return result;
	},
	
	/**
	 * Function: isNode
	 * 
	 * Returns true if the given value is an XML node with the node name
	 * and if the optional attribute has the specified value.
	 * 
	 * This implementation assumes that the given value is a DOM node if the
	 * nodeType property is numeric, that is, if isNaN returns false for
	 * value.nodeType.
	 * 
	 * Parameters:
	 * 
	 * value - Object that should be examined as a node.
	 * nodeName - String that specifies the node name.
	 * attributeName - Optional attribute name to check.
	 * attributeValue - Optional attribute value to check.
	 */
	 isNode: function(value, nodeName, attributeName, attributeValue)
	 {
	 	if (value != null && !isNaN(value.nodeType) && (nodeName == null ||
	 		value.nodeName.toLowerCase() == nodeName.toLowerCase()))
 		{
 			return attributeName == null ||
 				value.getAttribute(attributeName) == attributeValue;
 		}
	 	
	 	return false;
	 },
	
	/**
	 * Function: isAncestorNode
	 * 
	 * Returns true if the given ancestor is an ancestor of the
	 * given DOM node in the DOM. This also returns true if the
	 * child is the ancestor.
	 * 
	 * Parameters:
	 * 
	 * ancestor - DOM node that represents the ancestor.
	 * child - DOM node that represents the child.
	 */
	 isAncestorNode: function(ancestor, child)
	 {
	 	var parent = child;
	 	
	 	while (parent != null)
	 	{
	 		if (parent == ancestor)
	 		{
	 			return true;
	 		}

	 		parent = parent.parentNode;
	 	}
	 	
	 	return false;
	 },

	/**
	 * Function: getChildNodes
	 * 
	 * Returns an array of child nodes that are of the given node type.
	 * 
	 * Parameters:
	 * 
	 * node - Parent DOM node to return the children from.
	 * nodeType - Optional node type to return. Default is
	 * <mxConstants.NODETYPE_ELEMENT>.
	 */
	getChildNodes: function(node, nodeType)
	{
		nodeType = nodeType || mxConstants.NODETYPE_ELEMENT;
		
		var children = [];
		var tmp = node.firstChild;
		
		while (tmp != null)
		{
			if (tmp.nodeType == nodeType)
			{
				children.push(tmp);
			}
			
			tmp = tmp.nextSibling;
		}
		
		return children;
	},

	/**
	 * Function: importNode
	 * 
	 * Cross browser implementation for document.importNode. Uses document.importNode
	 * in all browsers but IE, where the node is cloned by creating a new node and
	 * copying all attributes and children into it using importNode, recursively.
	 * 
	 * Parameters:
	 * 
	 * doc - Document to import the node into.
	 * node - Node to be imported.
	 * allChildren - If all children should be imported.
	 */
	importNode: function(doc, node, allChildren)
	{
		if (mxClient.IS_IE && (document.documentMode == null || document.documentMode < 10))
		{
			switch (node.nodeType)
			{
				case 1: /* element */
				{
					var newNode = doc.createElement(node.nodeName);
					
					if (node.attributes && node.attributes.length > 0)
					{
						for (var i = 0; i < node.attributes.length; i++)
						{
							newNode.setAttribute(node.attributes[i].nodeName,
								node.getAttribute(node.attributes[i].nodeName));
						}
						
						if (allChildren && node.childNodes && node.childNodes.length > 0)
						{
							for (var i = 0; i < node.childNodes.length; i++)
							{
								newNode.appendChild(mxUtils.importNode(doc, node.childNodes[i], allChildren));
							}
						}
					}
					
					return newNode;
					break;
				}
				case 3: /* text */
			    case 4: /* cdata-section */
			    case 8: /* comment */
			    {
			      return doc.createTextNode(node.value);
			      break;
			    }
			};
		}
		else
		{
			return doc.importNode(node, allChildren);
		}
	},

	/**
	 * Function: createXmlDocument
	 * 
	 * Returns a new, empty XML document.
	 */
	createXmlDocument: function()
	{
		var doc = null;
		
		if (document.implementation && document.implementation.createDocument)
		{
			doc = document.implementation.createDocument('', '', null);
		}
		else if (window.ActiveXObject)
		{
			doc = new ActiveXObject('Microsoft.XMLDOM');
	 	}
	 	
	 	return doc;
	},

	/**
	 * Function: parseXml
	 * 
	 * Parses the specified XML string into a new XML document and returns the
	 * new document.
	 * 
	 * Example:
	 * 
	 * (code)
	 * var doc = mxUtils.parseXml(
	 *   '<mxGraphModel><root><MyDiagram id="0"><mxCell/></MyDiagram>'+
	 *   '<MyLayer id="1"><mxCell parent="0" /></MyLayer><MyObject id="2">'+
	 *   '<mxCell style="strokeColor=blue;fillColor=red" parent="1" vertex="1">'+
	 *   '<mxGeometry x="10" y="10" width="80" height="30" as="geometry"/>'+
	 *   '</mxCell></MyObject></root></mxGraphModel>');
	 * (end)
	 * 
	 * Parameters:
	 * 
	 * xml - String that contains the XML data.
	 */
	parseXml: function()
	{
		if (window.DOMParser)
		{
			return function(xml)
			{
				var parser = new DOMParser();
				
				return parser.parseFromString(xml, 'text/xml');
			};
		}
		else // IE<=9
		{
			return function(xml)
			{
				var result = mxUtils.createXmlDocument();
				result.async = false;
				// Workaround for parsing errors with SVG DTD
				result.validateOnParse = false;
				result.resolveExternals = false;
				result.loadXML(xml);
				
				return result;
			};
		}
	}(),

	/**
	 * Function: clearSelection
	 * 
	 * Clears the current selection in the page.
	 */
	clearSelection: function()
	{
		if (document.selection)
		{
			return function()
			{
				document.selection.empty();
			};
		}
		else if (window.getSelection)
		{
			return function()
			{
				window.getSelection().removeAllRanges();
			};
		}
		else
		{
			return function() { };
		}
	}(),

	/**
	 * Function: getPrettyXML
	 * 
	 * Returns a pretty printed string that represents the XML tree for the
	 * given node. This method should only be used to print XML for reading,
	 * use <getXml> instead to obtain a string for processing.
	 * 
	 * Parameters:
	 * 
	 * node - DOM node to return the XML for.
	 * tab - Optional string that specifies the indentation for one level.
	 * Default is two spaces.
	 * indent - Optional string that represents the current indentation.
	 * Default is an empty string.
	 */
	getPrettyXml: function(node, tab, indent)
	{
		var result = [];
		
		if (node != null)
		{
			tab = tab || '  ';
			indent = indent || '';
			
			if (node.nodeType == mxConstants.NODETYPE_TEXT)
			{
				result.push(node.value);
			}
			else
			{
				result.push(indent + '<' + node.nodeName);
				
				// Creates the string with the node attributes
				// and converts all HTML entities in the values
				var attrs = node.attributes;
				
				if (attrs != null)
				{
					for (var i = 0; i < attrs.length; i++)
					{
						var val = mxUtils.htmlEntities(attrs[i].value);
						result.push(' ' + attrs[i].nodeName + '="' + val + '"');
					}
				}

				// Recursively creates the XML string for each
				// child nodes and appends it here with an
				// indentation
				var tmp = node.firstChild;
				
				if (tmp != null)
				{
					result.push('>\n');
					
					while (tmp != null)
					{
						result.push(mxUtils.getPrettyXml(tmp, tab, indent + tab));
						tmp = tmp.nextSibling;
					}
					
					result.push(indent + '</'+node.nodeName + '>\n');
				}
				else
				{
					result.push('/>\n');
				}
			}
		}
		
		return result.join('');
	},
	
	/**
	 * Function: removeWhitespace
	 * 
	 * Removes the sibling text nodes for the given node that only consists
	 * of tabs, newlines and spaces.
	 * 
	 * Parameters:
	 * 
	 * node - DOM node whose siblings should be removed.
	 * before - Optional boolean that specifies the direction of the traversal.
	 */
	removeWhitespace: function(node, before)
	{
		var tmp = (before) ? node.previousSibling : node.nextSibling;
		
		while (tmp != null && tmp.nodeType == mxConstants.NODETYPE_TEXT)
		{
			var next = (before) ? tmp.previousSibling : tmp.nextSibling;
			var text = mxUtils.getTextContent(tmp);
			
			if (mxUtils.trim(text).length == 0)
			{
				tmp.parentNode.removeChild(tmp);
			}
			
			tmp = next;
		}
	},
	
	/**
	 * Function: htmlEntities
	 * 
	 * Replaces characters (less than, greater than, newlines and quotes) with
	 * their HTML entities in the given string and returns the result.
	 * 
	 * Parameters:
	 * 
	 * s - String that contains the characters to be converted.
	 * newline - If newlines should be replaced. Default is true.
	 */
	htmlEntities: function(s, newline)
	{
		s = String(s || '');
		
		s = s.replace(/&/g,'&amp;'); // 38 26
		s = s.replace(/"/g,'&quot;'); // 34 22
		s = s.replace(/\'/g,'&#39;'); // 39 27
		s = s.replace(/</g,'&lt;'); // 60 3C
		s = s.replace(/>/g,'&gt;'); // 62 3E

		if (newline == null || newline)
		{
			s = s.replace(/\n/g, '&#xa;');
		}
		
		return s;
	},
	
	/**
	 * Function: isVml
	 * 
	 * Returns true if the given node is in the VML namespace.
	 * 
	 * Parameters:
	 * 
	 * node - DOM node whose tag urn should be checked.
	 */
	isVml: function(node)
	{
		return node != null && node.tagUrn == 'urn:schemas-microsoft-com:vml';
	},

	/**
	 * Function: getXml
	 * 
	 * Returns the XML content of the specified node. For Internet Explorer,
	 * all \r\n\t[\t]* are removed from the XML string and the remaining \r\n
	 * are replaced by \n. All \n are then replaced with linefeed, or &#xa; if
	 * no linefeed is defined.
	 * 
	 * Parameters:
	 * 
	 * node - DOM node to return the XML for.
	 * linefeed - Optional string that linefeeds are converted into. Default is
	 * &#xa;
	 */
	getXml: function(node, linefeed)
	{
		var xml = '';

		if (window.XMLSerializer != null)
		{
			var xmlSerializer = new XMLSerializer();
			xml = xmlSerializer.serializeToString(node);     
		}
		else if (node.xml != null)
		{
			xml = node.xml.replace(/\r\n\t[\t]*/g, '').
				replace(/>\r\n/g, '>').
				replace(/\r\n/g, '\n');
		}

		// Replaces linefeeds with HTML Entities.
		linefeed = linefeed || '&#xa;';
		xml = xml.replace(/\n/g, linefeed);
		  
		return xml;
	},
	
	/**
	 * Function: extractTextWithWhitespace
	 * 
	 * Returns the text content of the specified node.
	 * 
	 * Parameters:
	 * 
	 * elems - DOM nodes to return the text for.
	 */
	extractTextWithWhitespace: function(elems)
	{
	    // Known block elements for handling linefeeds (list is not complete)
		var blocks = ['BLOCKQUOTE', 'DIV', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'OL', 'P', 'PRE', 'TABLE', 'UL'];
		var ret = [];
		
		function doExtract(elts)
		{
			// Single break should be ignored
			if (elts.length == 1 && (elts[0].nodeName == 'BR' ||
				elts[0].innerHTML == '\n'))
			{
				return;
			}
			
		    for (var i = 0; i < elts.length; i++)
		    {
		        var elem = elts[i];

				// DIV with a br or linefeed forces a linefeed
				if (elem.nodeName == 'BR' || elem.innerHTML == '\n' ||
					((elts.length == 1 || i == 0) && (elem.nodeName == 'DIV' &&
					elem.innerHTML.toLowerCase() == '<br>')))
		    	{
	    			ret.push('\n');
		    	}
				else
				{
			        if (elem.nodeType === 3 || elem.nodeType === 4)
			        {
			        	if (elem.nodeValue.length > 0)
			        	{
			        		ret.push(elem.nodeValue);
			        	}
			        }
			        else if (elem.nodeType !== 8 && elem.childNodes.length > 0)
					{
						doExtract(elem.childNodes);
					}
			        
	        		if (i < elts.length - 1 && mxUtils.indexOf(blocks, elts[i + 1].nodeName) >= 0)
	        		{
	        			ret.push('\n');		
	        		}
				}
		    }
		};
		
		doExtract(elems);
	    
	    return ret.join('');
	},

	/**
	 * Function: replaceTrailingNewlines
	 * 
	 * Replaces each trailing newline with the given pattern.
	 */
	replaceTrailingNewlines: function(str, pattern)
	{
		// LATER: Check is this can be done with a regular expression
		var postfix = '';
		
		while (str.length > 0 && str.charAt(str.length - 1) == '\n')
		{
			str = str.substring(0, str.length - 1);
			postfix += pattern;
		}
		
		return str + postfix;
	},

	/**
	 * Function: getTextContent
	 * 
	 * Returns the text content of the specified node.
	 * 
	 * Parameters:
	 * 
	 * node - DOM node to return the text content for.
	 */
	getTextContent: function(node)
	{
		if (node.innerText !== undefined)
		{
			return node.innerText;
		}
		else
		{
			return (node != null) ? node[(node.textContent === undefined) ? 'text' : 'textContent'] : '';
		}
	},
	
	/**
	 * Function: setTextContent
	 * 
	 * Sets the text content of the specified node.
	 * 
	 * Parameters:
	 * 
	 * node - DOM node to set the text content for.
	 * text - String that represents the text content.
	 */
	setTextContent: function(node, text)
	{
		if (node.innerText !== undefined)
		{
			node.innerText = text;
		}
		else
		{
			node[(node.textContent === undefined) ? 'text' : 'textContent'] = text;
		}
	},
	
	/**
	 * Function: getInnerHtml
	 * 
	 * Returns the inner HTML for the given node as a string or an empty string
	 * if no node was specified. The inner HTML is the text representing all
	 * children of the node, but not the node itself.
	 * 
	 * Parameters:
	 * 
	 * node - DOM node to return the inner HTML for.
	 */
	getInnerHtml: function()
	{
		if (mxClient.IS_IE)
		{
			return function(node)
			{
				if (node != null)
				{
					return node.innerHTML;
				}
				
				return '';
			};
		}
		else
		{
			return function(node)
			{
				if (node != null)
				{
					var serializer = new XMLSerializer();
					return serializer.serializeToString(node);
				}
				
				return '';
			};
		}
	}(),

	/**
	 * Function: getOuterHtml
	 * 
	 * Returns the outer HTML for the given node as a string or an empty
	 * string if no node was specified. The outer HTML is the text representing
	 * all children of the node including the node itself.
	 * 
	 * Parameters:
	 * 
	 * node - DOM node to return the outer HTML for.
	 */
	getOuterHtml: function()
	{
		if (mxClient.IS_IE)
		{
			return function(node)
			{
				if (node != null)
				{
					if (node.outerHTML != null)
					{
						return node.outerHTML;
					}
					else
					{
						var tmp = [];
						tmp.push('<'+node.nodeName);
						
						var attrs = node.attributes;
						
						if (attrs != null)
						{
							for (var i = 0; i < attrs.length; i++)
							{
								var value = attrs[i].value;
								
								if (value != null && value.length > 0)
								{
									tmp.push(' ');
									tmp.push(attrs[i].nodeName);
									tmp.push('="');
									tmp.push(value);
									tmp.push('"');
								}
							}
						}
						
						if (node.innerHTML.length == 0)
						{
							tmp.push('/>');
						}
						else
						{
							tmp.push('>');
							tmp.push(node.innerHTML);
							tmp.push('</'+node.nodeName+'>');
						}
						
						return tmp.join('');
					}
				}
				
				return '';
			};
		}
		else
		{
			return function(node)
			{
				if (node != null)
				{
					var serializer = new XMLSerializer();
					return serializer.serializeToString(node);
				}
				
				return '';
			};
		}
	}(),
	
	/**
	 * Function: write
	 * 
	 * Creates a text node for the given string and appends it to the given
	 * parent. Returns the text node.
	 * 
	 * Parameters:
	 * 
	 * parent - DOM node to append the text node to.
	 * text - String representing the text to be added.
	 */
	write: function(parent, text)
	{
		var doc = parent.ownerDocument;
		var node = doc.createTextNode(text);
		
		if (parent != null)
		{
			parent.appendChild(node);
		}
		
		return node;
	},
	
	/**
	 * Function: writeln
	 * 
	 * Creates a text node for the given string and appends it to the given
	 * parent with an additional linefeed. Returns the text node.
	 * 
	 * Parameters:
	 * 
	 * parent - DOM node to append the text node to.
	 * text - String representing the text to be added.
	 */
	writeln: function(parent, text)
	{
		var doc = parent.ownerDocument;
		var node = doc.createTextNode(text);
		
		if (parent != null)
		{
			parent.appendChild(node);
			parent.appendChild(document.createElement('br'));
		}
		
		return node;
	},
	
	/**
	 * Function: br
	 * 
	 * Appends a linebreak to the given parent and returns the linebreak.
	 * 
	 * Parameters:
	 * 
	 * parent - DOM node to append the linebreak to.
	 */
	br: function(parent, count)
	{
		count = count || 1;
		var br = null;
		
		for (var i = 0; i < count; i++)
		{
			if (parent != null)
			{
				br = parent.ownerDocument.createElement('br');
				parent.appendChild(br);
			}
		}
		
		return br;
	},
		
	/**
	 * Function: button
	 * 
	 * Returns a new button with the given level and function as an onclick
	 * event handler.
	 * 
	 * (code)
	 * document.body.appendChild(mxUtils.button('Test', function(evt)
	 * {
	 *   alert('Hello, World!');
	 * }));
	 * (end)
	 * 
	 * Parameters:
	 * 
	 * label - String that represents the label of the button.
	 * funct - Function to be called if the button is pressed.
	 * doc - Optional document to be used for creating the button. Default is the
	 * current document.
	 */
	button: function(label, funct, doc)
	{
		doc = (doc != null) ? doc : document;
		
		var button = doc.createElement('button');
		mxUtils.write(button, label);

		mxEvent.addListener(button, 'click', function(evt)
		{
			funct(evt);
		});
		
		return button;
	},
	
	/**
	 * Function: para
	 * 
	 * Appends a new paragraph with the given text to the specified parent and
	 * returns the paragraph.
	 * 
	 * Parameters:
	 * 
	 * parent - DOM node to append the text node to.
	 * text - String representing the text for the new paragraph.
	 */
	para: function(parent, text)
	{
		var p = document.createElement('p');
		mxUtils.write(p, text);

		if (parent != null)
		{
			parent.appendChild(p);
		}
		
		return p;
	},

	/**
	 * Function: addTransparentBackgroundFilter
	 * 
	 * Adds a transparent background to the filter of the given node. This
	 * background can be used in IE8 standards mode (native IE8 only) to pass
	 * events through the node.
	 */
	addTransparentBackgroundFilter: function(node)
	{
		node.style.filter += 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' +
			mxClient.imageBasePath + '/transparent.gif\', sizingMethod=\'scale\')';
	},

	/**
	 * Function: linkAction
	 * 
	 * Adds a hyperlink to the specified parent that invokes action on the
	 * specified editor.
	 * 
	 * Parameters:
	 * 
	 * parent - DOM node to contain the new link.
	 * text - String that is used as the link label.
	 * editor - <mxEditor> that will execute the action.
	 * action - String that defines the name of the action to be executed.
	 * pad - Optional left-padding for the link. Default is 0.
	 */
	linkAction: function(parent, text, editor, action, pad)
	{
		return mxUtils.link(parent, text, function()
		{
			editor.execute(action);
		}, pad);
	},

	/**
	 * Function: linkInvoke
	 * 
	 * Adds a hyperlink to the specified parent that invokes the specified
	 * function on the editor passing along the specified argument. The
	 * function name is the name of a function of the editor instance,
	 * not an action name.
	 * 
	 * Parameters:
	 * 
	 * parent - DOM node to contain the new link.
	 * text - String that is used as the link label.
	 * editor - <mxEditor> instance to execute the function on.
	 * functName - String that represents the name of the function.
	 * arg - Object that represents the argument to the function.
	 * pad - Optional left-padding for the link. Default is 0.
	 */
	linkInvoke: function(parent, text, editor, functName, arg, pad)
	{
		return mxUtils.link(parent, text, function()
		{
			editor[functName](arg);
		}, pad);
	},
	
	/**
	 * Function: link
	 * 
	 * Adds a hyperlink to the specified parent and invokes the given function
	 * when the link is clicked.
	 * 
	 * Parameters:
	 * 
	 * parent - DOM node to contain the new link.
	 * text - String that is used as the link label.
	 * funct - Function to execute when the link is clicked.
	 * pad - Optional left-padding for the link. Default is 0.
	 */
	link: function(parent, text, funct, pad)
	{
		var a = document.createElement('span');
		
		a.style.color = 'blue';
		a.style.textDecoration = 'underline';
		a.style.cursor = 'pointer';
		
		if (pad != null)
		{
			a.style.paddingLeft = pad+'px';
		}
		
		mxEvent.addListener(a, 'click', funct);
		mxUtils.write(a, text);
		
		if (parent != null)
		{
			parent.appendChild(a);
		}
		
		return a;
	},

	/**
	 * Function: fit
	 * 
	 * Makes sure the given node is inside the visible area of the window. This
	 * is done by setting the left and top in the style. 
	 */
	fit: function(node)
	{
		var left = parseInt(node.offsetLeft);
		var width = parseInt(node.offsetWidth);
			
		var offset = mxUtils.getDocumentScrollOrigin(node.ownerDocument);
		var sl = offset.x;
		var st = offset.y;

		var b = document.body;
		var d = document.documentElement;
		var right = (sl) + (b.clientWidth || d.clientWidth);
		
		if (left + width > right)
		{
			node.style.left = Math.max(sl, right - width) + 'px';
		}
		
		var top = parseInt(node.offsetTop);
		var height = parseInt(node.offsetHeight);
		
		var bottom = st + Math.max(b.clientHeight || 0, d.clientHeight);
		
		if (top + height > bottom)
		{
			node.style.top = Math.max(st, bottom - height) + 'px';
		}
	},

	/**
	 * Function: load
	 * 
	 * Loads the specified URL *synchronously* and returns the <mxXmlRequest>.
	 * Throws an exception if the file cannot be loaded. See <mxUtils.get> for
	 * an asynchronous implementation.
	 *
	 * Example:
	 * 
	 * (code)
	 * try
	 * {
	 *   var req = mxUtils.load(filename);
	 *   var root = req.getDocumentElement();
	 *   // Process XML DOM...
	 * }
	 * catch (ex)
	 * {
	 *   mxUtils.alert('Cannot load '+filename+': '+ex);
	 * }
	 * (end)
	 * 
	 * Parameters:
	 * 
	 * url - URL to get the data from.
	 */
	load: function(url)
	{
		var req = new mxXmlRequest(url, null, 'GET', false);
		req.send();
		
		return req;
	},

	/**
	 * Function: get
	 * 
	 * Loads the specified URL *asynchronously* and invokes the given functions
	 * depending on the request status. Returns the <mxXmlRequest> in use. Both
	 * functions take the <mxXmlRequest> as the only parameter. See
	 * <mxUtils.load> for a synchronous implementation.
	 *
	 * Example:
	 * 
	 * (code)
	 * mxUtils.get(url, function(req)
	 * {
	 *    var node = req.getDocumentElement();
	 *    // Process XML DOM...
	 * });
	 * (end)
	 * 
	 * So for example, to load a diagram into an existing graph model, the
	 * following code is used.
	 * 
	 * (code)
	 * mxUtils.get(url, function(req)
	 * {
	 *   var node = req.getDocumentElement();
	 *   var dec = new mxCodec(node.ownerDocument);
	 *   dec.decode(node, graph.getModel());
	 * });
	 * (end)
	 * 
	 * Parameters:
	 * 
	 * url - URL to get the data from.
	 * onload - Optional function to execute for a successful response.
	 * onerror - Optional function to execute on error.
	 * binary - Optional boolean parameter that specifies if the request is
	 * binary.
	 * timeout - Optional timeout in ms before calling ontimeout.
	 * ontimeout - Optional function to execute on timeout.
	 */
	get: function(url, onload, onerror, binary, timeout, ontimeout)
	{
		var req = new mxXmlRequest(url, null, 'GET');
		
		if (binary != null)
		{
			req.setBinary(binary);
		}
		
		req.send(onload, onerror, timeout, ontimeout);
		
		return req;
	},

	/**
	 * Function: getAll
	 * 
	 * Loads the URLs in the given array *asynchronously* and invokes the given function
	 * if all requests returned with a valid 2xx status. The error handler is invoked
	 * once on the first error or invalid response.
	 *
	 * Parameters:
	 * 
	 * urls - Array of URLs to be loaded.
	 * onload - Callback with array of <mxXmlRequests>.
	 * onerror - Optional function to execute on error.
	 */
	getAll: function(urls, onload, onerror)
	{
		var remain = urls.length;
		var result = [];
		var errors = 0;
		var err = function()
		{
			if (errors == 0 && onerror != null)
			{
				onerror();
			}

			errors++;
		};
		
		for (var i = 0; i < urls.length; i++)
		{
			(function(url, index)
			{
				mxUtils.get(url, function(req)
				{
					var status = req.getStatus();
					
					if (status < 200 || status > 299)
					{
						err();
					}
					else
					{
						result[index] = req;
						remain--;
						
						if (remain == 0)
						{
							onload(result);
						}
					}
				}, err);
			})(urls[i], i);
		}
		
		if (remain == 0)
		{
			onload(result);			
		}
	},
	
	/**
	 * Function: post
	 * 
	 * Posts the specified params to the given URL *asynchronously* and invokes
	 * the given functions depending on the request status. Returns the
	 * <mxXmlRequest> in use. Both functions take the <mxXmlRequest> as the
	 * only parameter. Make sure to use encodeURIComponent for the parameter
	 * values.
	 *
	 * Example:
	 * 
	 * (code)
	 * mxUtils.post(url, 'key=value', function(req)
	 * {
	 * 	mxUtils.alert('Ready: '+req.isReady()+' Status: '+req.getStatus());
	 *  // Process req.getDocumentElement() using DOM API if OK...
	 * });
	 * (end)
	 * 
	 * Parameters:
	 * 
	 * url - URL to get the data from.
	 * params - Parameters for the post request.
	 * onload - Optional function to execute for a successful response.
	 * onerror - Optional function to execute on error.
	 */
	post: function(url, params, onload, onerror)
	{
		return new mxXmlRequest(url, params).send(onload, onerror);
	},
	
	/**
	 * Function: submit
	 * 
	 * Submits the given parameters to the specified URL using
	 * <mxXmlRequest.simulate> and returns the <mxXmlRequest>.
	 * Make sure to use encodeURIComponent for the parameter
	 * values.
	 * 
	 * Parameters:
	 * 
	 * url - URL to get the data from.
	 * params - Parameters for the form.
	 * doc - Document to create the form in.
	 * target - Target to send the form result to.
	 */
	submit: function(url, params, doc, target)
	{
		return new mxXmlRequest(url, params).simulate(doc, target);
	},
	
	/**
	 * Function: loadInto
	 * 
	 * Loads the specified URL *asynchronously* into the specified document,
	 * invoking onload after the document has been loaded. This implementation
	 * does not use <mxXmlRequest>, but the document.load method.
	 * 
	 * Parameters:
	 * 
	 * url - URL to get the data from.
	 * doc - The document to load the URL into.
	 * onload - Function to execute when the URL has been loaded.
	 */
	loadInto: function(url, doc, onload)
	{
		if (mxClient.IS_IE)
		{
			doc.onreadystatechange = function ()
			{
				if (doc.readyState == 4)
				{
					onload();
				}
			};
		}
		else
		{
			doc.addEventListener('load', onload, false);
		}
		
		doc.load(url);
	},
	
	/**
	 * Function: getValue
	 * 
	 * Returns the value for the given key in the given associative array or
	 * the given default value if the value is null.
	 * 
	 * Parameters:
	 * 
	 * array - Associative array that contains the value for the key.
	 * key - Key whose value should be returned.
	 * defaultValue - Value to be returned if the value for the given
	 * key is null.
	 */
	getValue: function(array, key, defaultValue)
	{
		var value = (array != null) ? array[key] : null;

		if (value == null)
		{
			value = defaultValue;			
		}
		
		return value;
	},
	
	/**
	 * Function: getNumber
	 * 
	 * Returns the numeric value for the given key in the given associative
	 * array or the given default value (or 0) if the value is null. The value
	 * is converted to a numeric value using the Number function.
	 * 
	 * Parameters:
	 * 
	 * array - Associative array that contains the value for the key.
	 * key - Key whose value should be returned.
	 * defaultValue - Value to be returned if the value for the given
	 * key is null. Default is 0.
	 */
	getNumber: function(array, key, defaultValue)
	{
		var value = (array != null) ? array[key] : null;

		if (value == null)
		{
			value = defaultValue || 0;			
		}
		
		return Number(value);
	},
	
	/**
	 * Function: getColor
	 * 
	 * Returns the color value for the given key in the given associative
	 * array or the given default value if the value is null. If the value
	 * is <mxConstants.NONE> then null is returned.
	 * 
	 * Parameters:
	 * 
	 * array - Associative array that contains the value for the key.
	 * key - Key whose value should be returned.
	 * defaultValue - Value to be returned if the value for the given
	 * key is null. Default is null.
	 */
	getColor: function(array, key, defaultValue)
	{
		var value = (array != null) ? array[key] : null;

		if (value == null)
		{
			value = defaultValue;
		}
		else if (value == mxConstants.NONE)
		{
			value = null;
		}
		
		return value;
	},

	/**
	 * Function: clone
	 * 
	 * Recursively clones the specified object ignoring all fieldnames in the
	 * given array of transient fields. <mxObjectIdentity.FIELD_NAME> is always
	 * ignored by this function.
	 * 
	 * Parameters:
	 * 
	 * obj - Object to be cloned.
	 * transients - Optional array of strings representing the fieldname to be
	 * ignored.
	 * shallow - Optional boolean argument to specify if a shallow clone should
	 * be created, that is, one where all object references are not cloned or,
	 * in other words, one where only atomic (strings, numbers) values are
	 * cloned. Default is false.
	 */
	clone: function(obj, transients, shallow)
	{
		shallow = (shallow != null) ? shallow : false;
		var clone = null;
		
		if (obj != null && typeof(obj.constructor) == 'function')
		{
			clone = new obj.constructor();
			
		    for (var i in obj)
		    {
		    	if (i != mxObjectIdentity.FIELD_NAME && (transients == null ||
		    		mxUtils.indexOf(transients, i) < 0))
		    	{
			    	if (!shallow && typeof(obj[i]) == 'object')
			    	{
			            clone[i] = mxUtils.clone(obj[i]);
			        }
			        else
			        {
			            clone[i] = obj[i];
			        }
				}
		    }
		}
		
	    return clone;
	},

	/**
	 * Function: equalPoints
	 * 
	 * Compares all mxPoints in the given lists.
	 * 
	 * Parameters:
	 * 
	 * a - Array of <mxPoints> to be compared.
	 * b - Array of <mxPoints> to be compared.
	 */
	equalPoints: function(a, b)
	{
		if ((a == null && b != null) || (a != null && b == null) ||
			(a != null && b != null && a.length != b.length))
		{
			return false;
		}
		else if (a != null && b != null)
		{
			for (var i = 0; i < a.length; i++)
			{
				if (a[i] == b[i] || (a[i] != null && !a[i].equals(b[i])))
				{
					return false;
				}
			}
		}
		
		return true;
	},

	/**
	 * Function: equalEntries
	 * 
	 * Returns true if all properties of the given objects are equal. Values
	 * with NaN are equal to NaN and unequal to any other value.
	 * 
	 * Parameters:
	 * 
	 * a - First object to be compared.
	 * b - Second object to be compared.
	 */
	equalEntries: function(a, b)
	{
		if ((a == null && b != null) || (a != null && b == null) ||
			(a != null && b != null && a.length != b.length))
		{
			return false;
		}
		else if (a != null && b != null)
		{
			// Counts keys in b to check if all values have been compared
			var count = 0;
			
			for (var key in b)
			{
				count++;
			}
			
			for (var key in a)
			{
				count--
				
				if ((!mxUtils.isNaN(a[key]) || !mxUtils.isNaN(b[key])) && a[key] != b[key])
				{
					return false;
				}
			}
		}
		
		return count == 0;
	},
	
	/**
	 * Function: removeDuplicates
	 * 
	 * Removes all duplicates from the given array.
	 */
	removeDuplicates: function(arr)
	{
		var dict = new mxDictionary();
		var result = [];
		
		for (var i = 0; i < arr.length; i++)
		{
			if (!dict.get(arr[i]))
			{
				result.push(arr[i]);
				dict.put(arr[i], true);
			}
		}

		return result;
	},
	
	/**
	 * Function: isNaN
	 *
	 * Returns true if the given value is of type number and isNaN returns true.
	 */
	isNaN: function(value)
	{
		return typeof(value) == 'number' && isNaN(value);
	},
	
	/**
	 * Function: extend
	 *
	 * Assigns a copy of the superclass prototype to the subclass prototype.
	 * Note that this does not call the constructor of the superclass at this
	 * point, the superclass constructor should be called explicitely in the
	 * subclass constructor. Below is an example.
	 * 
	 * (code)
	 * MyGraph = function(container, model, renderHint, stylesheet)
	 * {
	 *   mxGraph.call(this, container, model, renderHint, stylesheet);
	 * }
	 * 
	 * mxUtils.extend(MyGraph, mxGraph);
	 * (end)
	 * 
	 * Parameters:
	 * 
	 * ctor - Constructor of the subclass.
	 * superCtor - Constructor of the superclass.
	 */
	extend: function(ctor, superCtor)
	{
		var f = function() {};
		f.prototype = superCtor.prototype;
		
		ctor.prototype = new f();
		ctor.prototype.constructor = ctor;
	},

	/**
	 * Function: toString
	 * 
	 * Returns a textual representation of the specified object.
	 * 
	 * Parameters:
	 * 
	 * obj - Object to return the string representation for.
	 */
	toString: function(obj)
	{
	    var output = '';
	    
	    for (var i in obj)
	    {
	    	try
	    	{
			    if (obj[i] == null)
			    {
		            output += i + ' = [null]\n';
			    }
			    else if (typeof(obj[i]) == 'function')
			    {
		            output += i + ' => [Function]\n';
		        }
		        else if (typeof(obj[i]) == 'object')
		        {
		        	var ctor = mxUtils.getFunctionName(obj[i].constructor); 
		            output += i + ' => [' + ctor + ']\n';
		        }
		        else
		        {
		            output += i + ' = ' + obj[i] + '\n';
		        }
	    	}
	    	catch (e)
	    	{
	    		output += i + '=' + e.message;
	    	}
	    }
	    
	    return output;
	},

	/**
	 * Function: toRadians
	 * 
	 * Converts the given degree to radians.
	 */
	toRadians: function(deg)
	{
		return Math.PI * deg / 180;
	},

	/**
	 * Function: toDegree
	 * 
	 * Converts the given radians to degree.
	 */
	toDegree: function(rad)
	{
		return rad * 180 / Math.PI;
	},
	
	/**
	 * Function: arcToCurves
	 * 
	 * Converts the given arc to a series of curves.
	 */
	arcToCurves: function(x0, y0, r1, r2, angle, largeArcFlag, sweepFlag, x, y)
	{
		x -= x0;
		y -= y0;
		
        if (r1 === 0 || r2 === 0) 
        {
        	return result;
        }
        
        var fS = sweepFlag;
        var psai = angle;
        r1 = Math.abs(r1);
        r2 = Math.abs(r2);
        var ctx = -x / 2;
        var cty = -y / 2;
        var cpsi = Math.cos(psai * Math.PI / 180);
        var spsi = Math.sin(psai * Math.PI / 180);
        var rxd = cpsi * ctx + spsi * cty;
        var ryd = -1 * spsi * ctx + cpsi * cty;
        var rxdd = rxd * rxd;
        var rydd = ryd * ryd;
        var r1x = r1 * r1;
        var r2y = r2 * r2;
        var lamda = rxdd / r1x + rydd / r2y;
        var sds;
        
        if (lamda > 1) 
        {
        	r1 = Math.sqrt(lamda) * r1;
        	r2 = Math.sqrt(lamda) * r2;
        	sds = 0;
        }  
        else
        {
        	var seif = 1;
            
        	if (largeArcFlag === fS) 
        	{
        		seif = -1;
        	}
            
        	sds = seif * Math.sqrt((r1x * r2y - r1x * rydd - r2y * rxdd) / (r1x * rydd + r2y * rxdd));
        }
        
        var txd = sds * r1 * ryd / r2;
        var tyd = -1 * sds * r2 * rxd / r1;
        var tx = cpsi * txd - spsi * tyd + x / 2;
        var ty = spsi * txd + cpsi * tyd + y / 2;
        var rad = Math.atan2((ryd - tyd) / r2, (rxd - txd) / r1) - Math.atan2(0, 1);
        var s1 = (rad >= 0) ? rad : 2 * Math.PI + rad;
        rad = Math.atan2((-ryd - tyd) / r2, (-rxd - txd) / r1) - Math.atan2((ryd - tyd) / r2, (rxd - txd) / r1);
        var dr = (rad >= 0) ? rad : 2 * Math.PI + rad;
        
        if (fS == 0 && dr > 0) 
        {
        	dr -= 2 * Math.PI;
        }
        else if (fS != 0 && dr < 0) 
        {
        	dr += 2 * Math.PI;
        }
        
        var sse = dr * 2 / Math.PI;
        var seg = Math.ceil(sse < 0 ? -1 * sse : sse);
        var segr = dr / seg;
        var t = 8/3 * Math.sin(segr / 4) * Math.sin(segr / 4) / Math.sin(segr / 2);
        var cpsir1 = cpsi * r1;
        var cpsir2 = cpsi * r2;
        var spsir1 = spsi * r1;
        var spsir2 = spsi * r2;
        var mc = Math.cos(s1);
        var ms = Math.sin(s1);
        var x2 = -t * (cpsir1 * ms + spsir2 * mc);
        var y2 = -t * (spsir1 * ms - cpsir2 * mc);
        var x3 = 0;
        var y3 = 0;

		var result = [];
        
        for (var n = 0; n < seg; ++n) 
        {
            s1 += segr;
            mc = Math.cos(s1);
            ms = Math.sin(s1);
            
            x3 = cpsir1 * mc - spsir2 * ms + tx;
            y3 = spsir1 * mc + cpsir2 * ms + ty;
            var dx = -t * (cpsir1 * ms + spsir2 * mc);
            var dy = -t * (spsir1 * ms - cpsir2 * mc);
            
            // CurveTo updates x0, y0 so need to restore it
            var index = n * 6;
            result[index] = Number(x2 + x0);
            result[index + 1] = Number(y2 + y0);
            result[index + 2] = Number(x3 - dx + x0);
            result[index + 3] = Number(y3 - dy + y0);
            result[index + 4] = Number(x3 + x0);
            result[index + 5] = Number(y3 + y0);
            
			x2 = x3 + dx;
            y2 = y3 + dy;
        }
        
        return result;
	},

	/**
	 * Function: getBoundingBox
	 * 
	 * Returns the bounding box for the rotated rectangle.
	 * 
	 * Parameters:
	 * 
	 * rect - <mxRectangle> to be rotated.
	 * angle - Number that represents the angle (in degrees).
	 * cx - Optional <mxPoint> that represents the rotation center. If no
	 * rotation center is given then the center of rect is used.
	 */
	getBoundingBox: function(rect, rotation, cx)
	{
        var result = null;

        if (rect != null && rotation != null && rotation != 0)
        {
            var rad = mxUtils.toRadians(rotation);
            var cos = Math.cos(rad);
            var sin = Math.sin(rad);

            cx = (cx != null) ? cx : new mxPoint(rect.x + rect.width / 2, rect.y  + rect.height / 2);

            var p1 = new mxPoint(rect.x, rect.y);
            var p2 = new mxPoint(rect.x + rect.width, rect.y);
            var p3 = new mxPoint(p2.x, rect.y + rect.height);
            var p4 = new mxPoint(rect.x, p3.y);

            p1 = mxUtils.getRotatedPoint(p1, cos, sin, cx);
            p2 = mxUtils.getRotatedPoint(p2, cos, sin, cx);
            p3 = mxUtils.getRotatedPoint(p3, cos, sin, cx);
            p4 = mxUtils.getRotatedPoint(p4, cos, sin, cx);

            result = new mxRectangle(p1.x, p1.y, 0, 0);
            result.add(new mxRectangle(p2.x, p2.y, 0, 0));
            result.add(new mxRectangle(p3.x, p3.y, 0, 0));
            result.add(new mxRectangle(p4.x, p4.y, 0, 0));
        }

        return result;
	},

	/**
	 * Function: getRotatedPoint
	 * 
	 * Rotates the given point by the given cos and sin.
	 */
	getRotatedPoint: function(pt, cos, sin, c)
	{
		c = (c != null) ? c : new mxPoint();
		var x = pt.x - c.x;
		var y = pt.y - c.y;

		var x1 = x * cos - y * sin;
		var y1 = y * cos + x * sin;

		return new mxPoint(x1 + c.x, y1 + c.y);
	},
	
	/**
	 * Returns an integer mask of the port constraints of the given map
	 * @param dict the style map to determine the port constraints for
	 * @param defaultValue Default value to return if the key is undefined.
	 * @return the mask of port constraint directions
	 * 
	 * Parameters:
	 * 
	 * terminal - <mxCelState> that represents the terminal.
	 * edge - <mxCellState> that represents the edge.
	 * source - Boolean that specifies if the terminal is the source terminal.
	 * defaultValue - Default value to be returned.
	 */
	getPortConstraints: function(terminal, edge, source, defaultValue)
	{
		var value = mxUtils.getValue(terminal.style, mxConstants.STYLE_PORT_CONSTRAINT,
			mxUtils.getValue(edge.style, (source) ? mxConstants.STYLE_SOURCE_PORT_CONSTRAINT :
				mxConstants.STYLE_TARGET_PORT_CONSTRAINT, null));
		
		if (value == null)
		{
			return defaultValue;
		}
		else
		{
			var directions = value.toString();
			var returnValue = mxConstants.DIRECTION_MASK_NONE;
			var constraintRotationEnabled = mxUtils.getValue(terminal.style, mxConstants.STYLE_PORT_CONSTRAINT_ROTATION, 0);
			var rotation = 0;
			
			if (constraintRotationEnabled == 1)
			{
				rotation = mxUtils.getValue(terminal.style, mxConstants.STYLE_ROTATION, 0);
			}
			
			var quad = 0;

			if (rotation > 45)
			{
				quad = 1;
				
				if (rotation >= 135)
				{
					quad = 2;
				}
			}
			else if (rotation < -45)
			{
				quad = 3;
				
				if (rotation <= -135)
				{
					quad = 2;
				}
			}

			if (directions.indexOf(mxConstants.DIRECTION_NORTH) >= 0)
			{
				switch (quad)
				{
					case 0:
						returnValue |= mxConstants.DIRECTION_MASK_NORTH;
						break;
					case 1:
						returnValue |= mxConstants.DIRECTION_MASK_EAST;
						break;
					case 2:
						returnValue |= mxConstants.DIRECTION_MASK_SOUTH;
						break;
					case 3:
						returnValue |= mxConstants.DIRECTION_MASK_WEST;
						break;
				}
			}
			if (directions.indexOf(mxConstants.DIRECTION_WEST) >= 0)
			{
				switch (quad)
				{
					case 0:
						returnValue |= mxConstants.DIRECTION_MASK_WEST;
						break;
					case 1:
						returnValue |= mxConstants.DIRECTION_MASK_NORTH;
						break;
					case 2:
						returnValue |= mxConstants.DIRECTION_MASK_EAST;
						break;
					case 3:
						returnValue |= mxConstants.DIRECTION_MASK_SOUTH;
						break;
				}
			}
			if (directions.indexOf(mxConstants.DIRECTION_SOUTH) >= 0)
			{
				switch (quad)
				{
					case 0:
						returnValue |= mxConstants.DIRECTION_MASK_SOUTH;
						break;
					case 1:
						returnValue |= mxConstants.DIRECTION_MASK_WEST;
						break;
					case 2:
						returnValue |= mxConstants.DIRECTION_MASK_NORTH;
						break;
					case 3:
						returnValue |= mxConstants.DIRECTION_MASK_EAST;
						break;
				}
			}
			if (directions.indexOf(mxConstants.DIRECTION_EAST) >= 0)
			{
				switch (quad)
				{
					case 0:
						returnValue |= mxConstants.DIRECTION_MASK_EAST;
						break;
					case 1:
						returnValue |= mxConstants.DIRECTION_MASK_SOUTH;
						break;
					case 2:
						returnValue |= mxConstants.DIRECTION_MASK_WEST;
						break;
					case 3:
						returnValue |= mxConstants.DIRECTION_MASK_NORTH;
						break;
				}
			}

			return returnValue;
		}
	},
	
	/**
	 * Function: reversePortConstraints
	 * 
	 * Reverse the port constraint bitmask. For example, north | east
	 * becomes south | west
	 */
	reversePortConstraints: function(constraint)
	{
		var result = 0;
		
		result = (constraint & mxConstants.DIRECTION_MASK_WEST) << 3;
		result |= (constraint & mxConstants.DIRECTION_MASK_NORTH) << 1;
		result |= (constraint & mxConstants.DIRECTION_MASK_SOUTH) >> 1;
		result |= (constraint & mxConstants.DIRECTION_MASK_EAST) >> 3;
		
		return result;
	},
	
	/**
	 * Function: findNearestSegment
	 * 
	 * Finds the index of the nearest segment on the given cell state for
	 * the specified coordinate pair.
	 */
	findNearestSegment: function(state, x, y)
	{
		var index = -1;
		
		if (state.absolutePoints.length > 0)
		{
			var last = state.absolutePoints[0];
			var min = null;
			
			for (var i = 1; i < state.absolutePoints.length; i++)
			{
				var current = state.absolutePoints[i];
				var dist = mxUtils.ptSegDistSq(last.x, last.y,
					current.x, current.y, x, y);
				
				if (min == null || dist < min)
				{
					min = dist;
					index = i - 1;
				}

				last = current;
			}
		}
		
		return index;
	},

	/**
	 * Function: getDirectedBounds
	 * 
	 * Adds the given margins to the given rectangle and rotates and flips the
	 * rectangle according to the respective styles in style.
	 */
	getDirectedBounds: function (rect, m, style, flipH, flipV)
	{
		var d = mxUtils.getValue(style, mxConstants.STYLE_DIRECTION, mxConstants.DIRECTION_EAST);
		flipH = (flipH != null) ? flipH : mxUtils.getValue(style, mxConstants.STYLE_FLIPH, false);
		flipV = (flipV != null) ? flipV : mxUtils.getValue(style, mxConstants.STYLE_FLIPV, false);

		m.x = Math.round(Math.max(0, Math.min(rect.width, m.x)));
		m.y = Math.round(Math.max(0, Math.min(rect.height, m.y)));
		m.width = Math.round(Math.max(0, Math.min(rect.width, m.width)));
		m.height = Math.round(Math.max(0, Math.min(rect.height, m.height)));
		
		if ((flipV && (d == mxConstants.DIRECTION_SOUTH || d == mxConstants.DIRECTION_NORTH)) ||
			(flipH && (d == mxConstants.DIRECTION_EAST || d == mxConstants.DIRECTION_WEST)))
		{
			var tmp = m.x;
			m.x = m.width;
			m.width = tmp;
		}
			
		if ((flipH && (d == mxConstants.DIRECTION_SOUTH || d == mxConstants.DIRECTION_NORTH)) ||
			(flipV && (d == mxConstants.DIRECTION_EAST || d == mxConstants.DIRECTION_WEST)))
		{
			var tmp = m.y;
			m.y = m.height;
			m.height = tmp;
		}
		
		var m2 = mxRectangle.fromRectangle(m);
		
		if (d == mxConstants.DIRECTION_SOUTH)
		{
			m2.y = m.x;
			m2.x = m.height;
			m2.width = m.y;
			m2.height = m.width;
		}
		else if (d == mxConstants.DIRECTION_WEST)
		{
			m2.y = m.height;
			m2.x = m.width;
			m2.width = m.x;
			m2.height = m.y;
		}
		else if (d == mxConstants.DIRECTION_NORTH)
		{
			m2.y = m.width;
			m2.x = m.y;
			m2.width = m.height;
			m2.height = m.x;
		}
		
		return new mxRectangle(rect.x + m2.x, rect.y + m2.y, rect.width - m2.width - m2.x, rect.height - m2.height - m2.y);
	},

	/**
	 * Function: getPerimeterPoint
	 * 
	 * Returns the intersection between the polygon defined by the array of
	 * points and the line between center and point.
	 */
	getPerimeterPoint: function (pts, center, point)
	{
		var min = null;
		
		for (var i = 0; i < pts.length - 1; i++)
		{
			var pt = mxUtils.intersection(pts[i].x, pts[i].y, pts[i + 1].x, pts[i + 1].y,
				center.x, center.y, point.x, point.y);
			
			if (pt != null)
			{
				var dx = point.x - pt.x;
				var dy = point.y - pt.y;
				var ip = {p: pt, distSq: dy * dy + dx * dx};
				
				if (ip != null && (min == null || min.distSq > ip.distSq))
				{
					min = ip;
				}
			}
		}
		
		return (min != null) ? min.p : null;
	},

	/**
	 * Function: rectangleIntersectsSegment
	 * 
	 * Returns true if the given rectangle intersects the given segment.
	 * 
	 * Parameters:
	 * 
	 * bounds - <mxRectangle> that represents the rectangle.
	 * p1 - <mxPoint> that represents the first point of the segment.
	 * p2 - <mxPoint> that represents the second point of the segment.
	 */
	rectangleIntersectsSegment: function(bounds, p1, p2)
	{
		var top = bounds.y;
		var left = bounds.x;
		var bottom = top + bounds.height;
		var right = left + bounds.width;
			
		// Find min and max X for the segment
		var minX = p1.x;
		var maxX = p2.x;
		
		if (p1.x > p2.x)
		{
		  minX = p2.x;
		  maxX = p1.x;
		}
		
		// Find the intersection of the segment's and rectangle's x-projections
		if (maxX > right)
		{
		  maxX = right;
		}
		
		if (minX < left)
		{
		  minX = left;
		}
		
		if (minX > maxX) // If their projections do not intersect return false
		{
		  return false;
		}
		
		// Find corresponding min and max Y for min and max X we found before
		var minY = p1.y;
		var maxY = p2.y;
		var dx = p2.x - p1.x;
		
		if (Math.abs(dx) > 0.0000001)
		{
		  var a = (p2.y - p1.y) / dx;
		  var b = p1.y - a * p1.x;
		  minY = a * minX + b;
		  maxY = a * maxX + b;
		}
		
		if (minY > maxY)
		{
		  var tmp = maxY;
		  maxY = minY;
		  minY = tmp;
		}
		
		// Find the intersection of the segment's and rectangle's y-projections
		if (maxY > bottom)
		{
		  maxY = bottom;
		}
		
		if (minY < top)
		{
		  minY = top;
		}
		
		if (minY > maxY) // If Y-projections do not intersect return false
		{
		  return false;
		}
		
		return true;
	},
	
	/**
	 * Function: contains
	 * 
	 * Returns true if the specified point (x, y) is contained in the given rectangle.
	 * 
	 * Parameters:
	 * 
	 * bounds - <mxRectangle> that represents the area.
	 * x - X-coordinate of the point.
	 * y - Y-coordinate of the point.
	 */
	contains: function(bounds, x, y)
	{
		return (bounds.x <= x && bounds.x + bounds.width >= x &&
				bounds.y <= y && bounds.y + bounds.height >= y);
	},

	/**
	 * Function: intersects
	 * 
	 * Returns true if the two rectangles intersect.
	 * 
	 * Parameters:
	 * 
	 * a - <mxRectangle> to be checked for intersection.
	 * b - <mxRectangle> to be checked for intersection.
	 */
	intersects: function(a, b)
	{
		var tw = a.width;
		var th = a.height;
		var rw = b.width;
		var rh = b.height;
		
		if (rw <= 0 || rh <= 0 || tw <= 0 || th <= 0)
		{
		    return false;
		}
		
		var tx = a.x;
		var ty = a.y;
		var rx = b.x;
		var ry = b.y;
		
		rw += rx;
		rh += ry;
		tw += tx;
		th += ty;

		return ((rw < rx || rw > tx) &&
			(rh < ry || rh > ty) &&
			(tw < tx || tw > rx) &&
			(th < ty || th > ry));
	},

	/**
	 * Function: intersects
	 * 
	 * Returns true if the two rectangles intersect.
	 * 
	 * Parameters:
	 * 
	 * a - <mxRectangle> to be checked for intersection.
	 * b - <mxRectangle> to be checked for intersection.
	 */
	intersectsHotspot: function(state, x, y, hotspot, min, max)
	{
		hotspot = (hotspot != null) ? hotspot : 1;
		min = (min != null) ? min : 0;
		max = (max != null) ? max : 0;
		
		if (hotspot > 0)
		{
			var cx = state.getCenterX();
			var cy = state.getCenterY();
			var w = state.width;
			var h = state.height;
			
			var start = mxUtils.getValue(state.style, mxConstants.STYLE_STARTSIZE) * state.view.scale;

			if (start > 0)
			{
				if (mxUtils.getValue(state.style, mxConstants.STYLE_HORIZONTAL, true))
				{
					cy = state.y + start / 2;
					h = start;
				}
				else
				{
					cx = state.x + start / 2;
					w = start;
				}
			}

			w = Math.max(min, w * hotspot);
			h = Math.max(min, h * hotspot);
			
			if (max > 0)
			{
				w = Math.min(w, max);
				h = Math.min(h, max);
			}
			
			var rect = new mxRectangle(cx - w / 2, cy - h / 2, w, h);
			var alpha = mxUtils.toRadians(mxUtils.getValue(state.style, mxConstants.STYLE_ROTATION) || 0);
			
			if (alpha != 0)
			{
				var cos = Math.cos(-alpha);
				var sin = Math.sin(-alpha);
				var cx = new mxPoint(state.getCenterX(), state.getCenterY());
				var pt = mxUtils.getRotatedPoint(new mxPoint(x, y), cos, sin, cx);
				x = pt.x;
				y = pt.y;
			}
			
			return mxUtils.contains(rect, x, y);			
		}
		
		return true;
	},

	/**
	 * Function: getOffset
	 * 
	 * Returns the offset for the specified container as an <mxPoint>. The
	 * offset is the distance from the top left corner of the container to the
	 * top left corner of the document.
	 * 
	 * Parameters:
	 * 
	 * container - DOM node to return the offset for.
	 * scollOffset - Optional boolean to add the scroll offset of the document.
	 * Default is false.
	 */
	getOffset: function(container, scrollOffset)
	{
		var offsetLeft = 0;
		var offsetTop = 0;
		
		// Ignores document scroll origin for fixed elements
		var fixed = false;
		var node = container;
		var b = document.body;
		var d = document.documentElement;

		while (node != null && node != b && node != d && !fixed)
		{
			var style = mxUtils.getCurrentStyle(node);
			
			if (style != null)
			{
				fixed = fixed || style.position == 'fixed';
			}
			
			node = node.parentNode;
		}
		
		if (!scrollOffset && !fixed)
		{
			var offset = mxUtils.getDocumentScrollOrigin(container.ownerDocument);
			offsetLeft += offset.x;
			offsetTop += offset.y;
		}
		
		var r = container.getBoundingClientRect();
		
		if (r != null)
		{
			offsetLeft += r.left;
			offsetTop += r.top;
		}
		
		return new mxPoint(offsetLeft, offsetTop);
	},

	/**
	 * Function: getDocumentScrollOrigin
	 * 
	 * Returns the scroll origin of the given document or the current document
	 * if no document is given.
	 */
	getDocumentScrollOrigin: function(doc)
	{
		if (mxClient.IS_QUIRKS)
		{
			return new mxPoint(doc.body.scrollLeft, doc.body.scrollTop);
		}
		else
		{
			var wnd = doc.defaultView || doc.parentWindow;
			
			var x = (wnd != null && window.pageXOffset !== undefined) ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft;
			var y = (wnd != null && window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
			
			return new mxPoint(x, y);
		}
	},
	
	/**
	 * Function: getScrollOrigin
	 * 
	 * Returns the top, left corner of the viewrect as an <mxPoint>.
	 * 
	 * Parameters:
	 * 
	 * node - DOM node whose scroll origin should be returned.
	 * includeAncestors - Whether the scroll origin of the ancestors should be
	 * included. Default is false.
	 * includeDocument - Whether the scroll origin of the document should be
	 * included. Default is true.
	 */
	getScrollOrigin: function(node, includeAncestors, includeDocument)
	{
		includeAncestors = (includeAncestors != null) ? includeAncestors : false;
		includeDocument = (includeDocument != null) ? includeDocument : true;
		
		var doc = (node != null) ? node.ownerDocument : document;
		var b = doc.body;
		var d = doc.documentElement;
		var result = new mxPoint();
		var fixed = false;

		while (node != null && node != b && node != d)
		{
			if (!isNaN(node.scrollLeft) && !isNaN(node.scrollTop))
			{
				result.x += node.scrollLeft;
				result.y += node.scrollTop;
			}
			
			var style = mxUtils.getCurrentStyle(node);
			
			if (style != null)
			{
				fixed = fixed || style.position == 'fixed';
			}

			node = (includeAncestors) ? node.parentNode : null;
		}

		if (!fixed && includeDocument)
		{
			var origin = mxUtils.getDocumentScrollOrigin(doc);

			result.x += origin.x;
			result.y += origin.y;
		}
		
		return result;
	},

	/**
	 * Function: convertPoint
	 * 
	 * Converts the specified point (x, y) using the offset of the specified
	 * container and returns a new <mxPoint> with the result.
	 * 
	 * (code)
	 * var pt = mxUtils.convertPoint(graph.container,
	 *   mxEvent.getClientX(evt), mxEvent.getClientY(evt));
	 * (end)
	 * 
	 * Parameters:
	 * 
	 * container - DOM node to use for the offset.
	 * x - X-coordinate of the point to be converted.
	 * y - Y-coordinate of the point to be converted.
	 */
	convertPoint: function(container, x, y)
	{
		var origin = mxUtils.getScrollOrigin(container, false);
		var offset = mxUtils.getOffset(container);

		offset.x -= origin.x;
		offset.y -= origin.y;
		
		return new mxPoint(x - offset.x, y - offset.y);
	},
	
	/**
	 * Function: ltrim
	 * 
	 * Strips all whitespaces from the beginning of the string. Without the
	 * second parameter, this will trim these characters:
	 * 
	 * - " " (ASCII 32 (0x20)), an ordinary space
	 * - "\t" (ASCII 9 (0x09)), a tab
	 * - "\n" (ASCII 10 (0x0A)), a new line (line feed)
	 * - "\r" (ASCII 13 (0x0D)), a carriage return
	 * - "\0" (ASCII 0 (0x00)), the NUL-byte
	 * - "\x0B" (ASCII 11 (0x0B)), a vertical tab
	 */
	ltrim: function(str, chars)
	{
		chars = chars || "\\s";
		
		return (str != null) ? str.replace(new RegExp("^[" + chars + "]+", "g"), "") : null;
	},
	
	/**
	 * Function: rtrim
	 * 
	 * Strips all whitespaces from the end of the string. Without the second
	 * parameter, this will trim these characters:
	 * 
	 * - " " (ASCII 32 (0x20)), an ordinary space
	 * - "\t" (ASCII 9 (0x09)), a tab
	 * - "\n" (ASCII 10 (0x0A)), a new line (line feed)
	 * - "\r" (ASCII 13 (0x0D)), a carriage return
	 * - "\0" (ASCII 0 (0x00)), the NUL-byte
	 * - "\x0B" (ASCII 11 (0x0B)), a vertical tab
	 */
	rtrim: function(str, chars)
	{
		chars = chars || "\\s";
		
		return (str != null) ? str.replace(new RegExp("[" + chars + "]+$", "g"), "") : null;
	},
	
	/**
	 * Function: trim
	 * 
	 * Strips all whitespaces from both end of the string.
	 * Without the second parameter, Javascript function will trim these
	 * characters:
	 * 
	 * - " " (ASCII 32 (0x20)), an ordinary space
	 * - "\t" (ASCII 9 (0x09)), a tab
	 * - "\n" (ASCII 10 (0x0A)), a new line (line feed)
	 * - "\r" (ASCII 13 (0x0D)), a carriage return
	 * - "\0" (ASCII 0 (0x00)), the NUL-byte
	 * - "\x0B" (ASCII 11 (0x0B)), a vertical tab
	 */
	trim: function(str, chars)
	{
		return mxUtils.ltrim(mxUtils.rtrim(str, chars), chars);
	},
	
	/**
	 * Function: isNumeric
	 * 
	 * Returns true if the specified value is numeric, that is, if it is not
	 * null, not an empty string, not a HEX number and isNaN returns false.
	 * 
	 * Parameters:
	 * 
	 * n - String representing the possibly numeric value.
	 */
	isNumeric: function(n)
	{
		return !isNaN(parseFloat(n)) && isFinite(n) && (typeof(n) != 'string' || n.toLowerCase().indexOf('0x') < 0);
	},

	/**
	 * Function: isInteger
	 * 
	 * Returns true if the given value is an valid integer number.
	 * 
	 * Parameters:
	 * 
	 * n - String representing the possibly numeric value.
	 */
	isInteger: function(n)
	{
		return String(parseInt(n)) === String(n);
	},

	/**
	 * Function: mod
	 * 
	 * Returns the remainder of division of n by m. You should use this instead
	 * of the built-in operation as the built-in operation does not properly
	 * handle negative numbers.
	 */
	mod: function(n, m)
	{
		return ((n % m) + m) % m;
	},

	/**
	 * Function: intersection
	 * 
	 * Returns the intersection of two lines as an <mxPoint>.
	 * 
	 * Parameters:
	 * 
	 * x0 - X-coordinate of the first line's startpoint.
	 * y0 - X-coordinate of the first line's startpoint.
	 * x1 - X-coordinate of the first line's endpoint.
	 * y1 - Y-coordinate of the first line's endpoint.
	 * x2 - X-coordinate of the second line's startpoint.
	 * y2 - Y-coordinate of the second line's startpoint.
	 * x3 - X-coordinate of the second line's endpoint.
	 * y3 - Y-coordinate of the second line's endpoint.
	 */
	intersection: function (x0, y0, x1, y1, x2, y2, x3, y3)
	{
		var denom = ((y3 - y2) * (x1 - x0)) - ((x3 - x2) * (y1 - y0));
		var nume_a = ((x3 - x2) * (y0 - y2)) - ((y3 - y2) * (x0 - x2));
		var nume_b = ((x1 - x0) * (y0 - y2)) - ((y1 - y0) * (x0 - x2));

		var ua = nume_a / denom;
		var ub = nume_b / denom;
		
		if(ua >= 0.0 && ua <= 1.0 && ub >= 0.0 && ub <= 1.0)
		{
			// Get the intersection point
			var x = x0 + ua * (x1 - x0);
			var y = y0 + ua * (y1 - y0);
			
			return new mxPoint(x, y);
		}
		
		// No intersection
		return null;
	},
	
	/**
	 * Function: ptSegDistSq
	 * 
	 * Returns the square distance between a segment and a point. To get the
	 * distance between a point and a line (with infinite length) use
	 * <mxUtils.ptLineDist>.
	 * 
	 * Parameters:
	 * 
	 * x1 - X-coordinate of the startpoint of the segment.
	 * y1 - Y-coordinate of the startpoint of the segment.
	 * x2 - X-coordinate of the endpoint of the segment.
	 * y2 - Y-coordinate of the endpoint of the segment.
	 * px - X-coordinate of the point.
	 * py - Y-coordinate of the point.
	 */
	ptSegDistSq: function(x1, y1, x2, y2, px, py)
    {
		x2 -= x1;
		y2 -= y1;

		px -= x1;
		py -= y1;

		var dotprod = px * x2 + py * y2;
		var projlenSq;

		if (dotprod <= 0.0)
		{
		    projlenSq = 0.0;
		}
		else
		{
		    px = x2 - px;
		    py = y2 - py;
		    dotprod = px * x2 + py * y2;

		    if (dotprod <= 0.0)
		    {
				projlenSq = 0.0;
		    }
		    else
		    {
				projlenSq = dotprod * dotprod / (x2 * x2 + y2 * y2);
		    }
		}

		var lenSq = px * px + py * py - projlenSq;
		
		if (lenSq < 0)
		{
		    lenSq = 0;
		}
		
		return lenSq;
    },
	
	/**
	 * Function: ptLineDist
	 * 
	 * Returns the distance between a line defined by two points and a point.
	 * To get the distance between a point and a segment (with a specific
	 * length) use <mxUtils.ptSeqDistSq>.
	 * 
	 * Parameters:
	 * 
	 * x1 - X-coordinate of point 1 of the line.
	 * y1 - Y-coordinate of point 1 of the line.
	 * x2 - X-coordinate of point 1 of the line.
	 * y2 - Y-coordinate of point 1 of the line.
	 * px - X-coordinate of the point.
	 * py - Y-coordinate of the point.
	 */
    ptLineDist: function(x1, y1, x2, y2, px, py)
    {
		return Math.abs((y2 - y1) * px - (x2 - x1) * py + x2 * y1 - y2 * x1) /
			Math.sqrt((y2 - y1) * (y2 - y1) + (x2 - x1) * (x2 - x1));
    },
    	
	/**
	 * Function: relativeCcw
	 * 
	 * Returns 1 if the given point on the right side of the segment, 0 if its
	 * on the segment, and -1 if the point is on the left side of the segment.
	 * 
	 * Parameters:
	 * 
	 * x1 - X-coordinate of the startpoint of the segment.
	 * y1 - Y-coordinate of the startpoint of the segment.
	 * x2 - X-coordinate of the endpoint of the segment.
	 * y2 - Y-coordinate of the endpoint of the segment.
	 * px - X-coordinate of the point.
	 * py - Y-coordinate of the point.
	 */
	relativeCcw: function(x1, y1, x2, y2, px, py)
    {
		x2 -= x1;
		y2 -= y1;
		px -= x1;
		py -= y1;
		var ccw = px * y2 - py * x2;
		
		if (ccw == 0.0)
		{
		    ccw = px * x2 + py * y2;
		    
		    if (ccw > 0.0)
		    {
				px -= x2;
				py -= y2;
				ccw = px * x2 + py * y2;
				
				if (ccw < 0.0)
				{
				    ccw = 0.0;
				}
		    }
		}
		
		return (ccw < 0.0) ? -1 : ((ccw > 0.0) ? 1 : 0);
    },
    
	/**
	 * Function: animateChanges
	 * 
	 * See <mxEffects.animateChanges>. This is for backwards compatibility and
	 * will be removed later.
	 */
	animateChanges: function(graph, changes)
	{
		// LATER: Deprecated, remove this function
    	mxEffects.animateChanges.apply(this, arguments);
	},
    
	/**
	 * Function: cascadeOpacity
	 * 
	 * See <mxEffects.cascadeOpacity>. This is for backwards compatibility and
	 * will be removed later.
	 */
    cascadeOpacity: function(graph, cell, opacity)
	{
		mxEffects.cascadeOpacity.apply(this, arguments);
	},

	/**
	 * Function: fadeOut
	 * 
	 * See <mxEffects.fadeOut>. This is for backwards compatibility and
	 * will be removed later.
	 */
	fadeOut: function(node, from, remove, step, delay, isEnabled)
	{
		mxEffects.fadeOut.apply(this, arguments);
	},
	
	/**
	 * Function: setOpacity
	 * 
	 * Sets the opacity of the specified DOM node to the given value in %.
	 * 
	 * Parameters:
	 * 
	 * node - DOM node to set the opacity for.
	 * value - Opacity in %. Possible values are between 0 and 100.
	 */
	setOpacity: function(node, value)
	{
		if (mxUtils.isVml(node))
		{
	    	if (value >= 100)
	    	{
	    		node.style.filter = '';
	    	}
	    	else
	    	{
	    		// TODO: Why is the division by 5 needed in VML?
			    node.style.filter = 'alpha(opacity=' + (value/5) + ')';
	    	}
		}
		else if (mxClient.IS_IE && (typeof(document.documentMode) === 'undefined' || document.documentMode < 9))
	    {
	    	if (value >= 100)
	    	{
	    		node.style.filter = '';
	    	}
	    	else
	    	{
			    node.style.filter = 'alpha(opacity=' + value + ')';
	    	}
		}
		else
		{
		    node.style.opacity = (value / 100);
		}
	},

	/**
	 * Function: createImage
	 * 
	 * Creates and returns an image (IMG node) or VML image (v:image) in IE6 in
	 * quirks mode.
	 * 
	 * Parameters:
	 * 
	 * src - URL that points to the image to be displayed.
	 */
	createImage: function(src)
	{
        var imageNode = null;
        
		if (mxClient.IS_IE6 && document.compatMode != 'CSS1Compat')
		{
        	imageNode = document.createElement(mxClient.VML_PREFIX + ':image');
        	imageNode.setAttribute('src', src);
        	imageNode.style.borderStyle = 'none';
        }
		else
		{
			imageNode = document.createElement('img');
			imageNode.setAttribute('src', src);
			imageNode.setAttribute('border', '0');
		}
		
		return imageNode;
	},

	/**
	 * Function: sortCells
	 * 
	 * Sorts the given cells according to the order in the cell hierarchy.
	 * Ascending is optional and defaults to true.
	 */
	sortCells: function(cells, ascending)
	{
		ascending = (ascending != null) ? ascending : true;
		var lookup = new mxDictionary();
		cells.sort(function(o1, o2)
		{
			var p1 = lookup.get(o1);
			
			if (p1 == null)
			{
				p1 = mxCellPath.create(o1).split(mxCellPath.PATH_SEPARATOR);
				lookup.put(o1, p1);
			}
			
			var p2 = lookup.get(o2);
			
			if (p2 == null)
			{
				p2 = mxCellPath.create(o2).split(mxCellPath.PATH_SEPARATOR);
				lookup.put(o2, p2);
			}
			
			var comp = mxCellPath.compare(p1, p2);
			
			return (comp == 0) ? 0 : (((comp > 0) == ascending) ? 1 : -1);
		});
		
		return cells;
	},

	/**
	 * Function: getStylename
	 * 
	 * Returns the stylename in a style of the form [(stylename|key=value);] or
	 * an empty string if the given style does not contain a stylename.
	 * 
	 * Parameters:
	 * 
	 * style - String of the form [(stylename|key=value);].
	 */
	getStylename: function(style)
	{
		if (style != null)
		{
			var pairs = style.split(';');
			var stylename = pairs[0];
			
			if (stylename.indexOf('=') < 0)
			{
				return stylename;
			}
		}
				
		return '';
	},

	/**
	 * Function: getStylenames
	 * 
	 * Returns the stylenames in a style of the form [(stylename|key=value);]
	 * or an empty array if the given style does not contain any stylenames.
	 * 
	 * Parameters:
	 * 
	 * style - String of the form [(stylename|key=value);].
	 */
	getStylenames: function(style)
	{
		var result = [];
		
		if (style != null)
		{
			var pairs = style.split(';');
			
			for (var i = 0; i < pairs.length; i++)
			{
				if (pairs[i].indexOf('=') < 0)
				{
					result.push(pairs[i]);
				}
			}
		}
				
		return result;
	},

	/**
	 * Function: indexOfStylename
	 * 
	 * Returns the index of the given stylename in the given style. This
	 * returns -1 if the given stylename does not occur (as a stylename) in the
	 * given style, otherwise it returns the index of the first character.
	 */
	indexOfStylename: function(style, stylename)
	{
		if (style != null && stylename != null)
		{
			var tokens = style.split(';');
			var pos = 0;
			
			for (var i = 0; i < tokens.length; i++)
			{
				if (tokens[i] == stylename)
				{
					return pos;
				}
				
				pos += tokens[i].length + 1;
			}
		}

		return -1;
	},
	
	/**
	 * Function: addStylename
	 * 
	 * Adds the specified stylename to the given style if it does not already
	 * contain the stylename.
	 */
	addStylename: function(style, stylename)
	{
		if (mxUtils.indexOfStylename(style, stylename) < 0)
		{
			if (style == null)
			{
				style = '';
			}
			else if (style.length > 0 && style.charAt(style.length - 1) != ';')
			{
				style += ';';
			}
			
			style += stylename;
		}
		
		return style;
	},
	
	/**
	 * Function: removeStylename
	 * 
	 * Removes all occurrences of the specified stylename in the given style
	 * and returns the updated style. Trailing semicolons are not preserved.
	 */
	removeStylename: function(style, stylename)
	{
		var result = [];
		
		if (style != null)
		{
			var tokens = style.split(';');
			
			for (var i = 0; i < tokens.length; i++)
			{
				if (tokens[i] != stylename)
				{
					result.push(tokens[i]);
				}
			}
		}
		
		return result.join(';');
	},
	
	/**
	 * Function: removeAllStylenames
	 * 
	 * Removes all stylenames from the given style and returns the updated
	 * style.
	 */
	removeAllStylenames: function(style)
	{
		var result = [];
		
		if (style != null)
		{
			var tokens = style.split(';');
			
			for (var i = 0; i < tokens.length; i++)
			{
				// Keeps the key, value assignments
				if (tokens[i].indexOf('=') >= 0)
				{
					result.push(tokens[i]);
				}
			}
		}
		
		return result.join(';');
	},

	/**
	 * Function: setCellStyles
	 * 
	 * Assigns the value for the given key in the styles of the given cells, or
	 * removes the key from the styles if the value is null.
	 * 
	 * Parameters:
	 * 
	 * model - <mxGraphModel> to execute the transaction in.
	 * cells - Array of <mxCells> to be updated.
	 * key - Key of the style to be changed.
	 * value - New value for the given key.
	 */
	setCellStyles: function(model, cells, key, value)
	{
		if (cells != null && cells.length > 0)
		{
			model.beginUpdate();
			try
			{
				for (var i = 0; i < cells.length; i++)
				{
					if (cells[i] != null)
					{
						var style = mxUtils.setStyle(model.getStyle(cells[i]), key, value);
						model.setStyle(cells[i], style);
					}
				}
			}
			finally
			{
				model.endUpdate();
			}
		}
	},
	
	/**
	 * Function: setStyle
	 * 
	 * Adds or removes the given key, value pair to the style and returns the
	 * new style. If value is null or zero length then the key is removed from
	 * the style. This is for cell styles, not for CSS styles.
	 * 
	 * Parameters:
	 * 
	 * style - String of the form [(stylename|key=value);].
	 * key - Key of the style to be changed.
	 * value - New value for the given key.
	 */
	setStyle: function(style, key, value)
	{
		var isValue = value != null && (typeof(value.length) == 'undefined' || value.length > 0);
		
		if (style == null || style.length == 0)
		{
			if (isValue)
			{
				style = key + '=' + value + ';';
			}
		}
		else
		{
			if (style.substring(0, key.length + 1) == key + '=')
			{
				var next = style.indexOf(';');
				
				if (isValue)
				{
					style = key + '=' + value + ((next < 0) ? ';' : style.substring(next));
				}
				else
				{
					style = (next < 0 || next == style.length - 1) ? '' : style.substring(next + 1);
				}
			}
			else
			{
				var index = style.indexOf(';' + key + '=');
				
				if (index < 0)
				{
					if (isValue)
					{
						var sep = (style.charAt(style.length - 1) == ';') ? '' : ';';
						style = style + sep + key + '=' + value + ';';
					}
				}
				else
				{
					var next = style.indexOf(';', index + 1);
					
					if (isValue)
					{
						style = style.substring(0, index + 1) + key + '=' + value + ((next < 0) ? ';' : style.substring(next));
					}
					else
					{
						style = style.substring(0, index) + ((next < 0) ? ';' : style.substring(next));
					}
				}
			}
		}
		
		return style;
	},

	/**
	 * Function: setCellStyleFlags
	 * 
	 * Sets or toggles the flag bit for the given key in the cell's styles.
	 * If value is null then the flag is toggled.
	 * 
	 * Example:
	 * 
	 * (code)
	 * var cells = graph.getSelectionCells();
	 * mxUtils.setCellStyleFlags(graph.model,
	 * 			cells,
	 * 			mxConstants.STYLE_FONTSTYLE,
	 * 			mxConstants.FONT_BOLD);
	 * (end)
	 * 
	 * Toggles the bold font style.
	 * 
	 * Parameters:
	 * 
	 * model - <mxGraphModel> that contains the cells.
	 * cells - Array of <mxCells> to change the style for.
	 * key - Key of the style to be changed.
	 * flag - Integer for the bit to be changed.
	 * value - Optional boolean value for the flag.
	 */
	setCellStyleFlags: function(model, cells, key, flag, value)
	{
		if (cells != null && cells.length > 0)
		{
			model.beginUpdate();
			try
			{
				for (var i = 0; i < cells.length; i++)
				{
					if (cells[i] != null)
					{
						var style = mxUtils.setStyleFlag(
							model.getStyle(cells[i]),
							key, flag, value);
						model.setStyle(cells[i], style);
					}
				}
			}
			finally
			{
				model.endUpdate();
			}
		}
	},
	
	/**
	 * Function: setStyleFlag
	 * 
	 * Sets or removes the given key from the specified style and returns the
	 * new style. If value is null then the flag is toggled.
	 * 
	 * Parameters:
	 * 
	 * style - String of the form [(stylename|key=value);].
	 * key - Key of the style to be changed.
	 * flag - Integer for the bit to be changed.
	 * value - Optional boolean value for the given flag.
	 */
	setStyleFlag: function(style, key, flag, value)
	{
		if (style == null || style.length == 0)
		{
			if (value || value == null)
			{
				style = key+'='+flag;
			}
			else
			{
				style = key+'=0';
			}
		}
		else
		{
			var index = style.indexOf(key+'=');
			
			if (index < 0)
			{
				var sep = (style.charAt(style.length-1) == ';') ? '' : ';';

				if (value || value == null)
				{
					style = style + sep + key + '=' + flag;
				}
				else
				{
					style = style + sep + key + '=0';
				}
			}
			else
			{
				var cont = style.indexOf(';', index);
				var tmp = '';
				
				if (cont < 0)
				{
					tmp  = style.substring(index+key.length+1);
				}
				else
				{
					tmp = style.substring(index+key.length+1, cont);
				}
				
				if (value == null)
				{
					tmp = parseInt(tmp) ^ flag;
				}
				else if (value)
				{
					tmp = parseInt(tmp) | flag;
				}
				else
				{
					tmp = parseInt(tmp) & ~flag;
				}
				
				style = style.substring(0, index) + key + '=' + tmp +
					((cont >= 0) ? style.substring(cont) : '');
			}
		}
		
		return style;
	},
	
	/**
	 * Function: getAlignmentAsPoint
	 * 
	 * Returns an <mxPoint> that represents the horizontal and vertical alignment
	 * for numeric computations. X is -0.5 for center, -1 for right and 0 for
	 * left alignment. Y is -0.5 for middle, -1 for bottom and 0 for top
	 * alignment. Default values for missing arguments is top, left.
	 */
	getAlignmentAsPoint: function(align, valign)
	{
		var dx = 0;
		var dy = 0;
		
		// Horizontal alignment
		if (align == mxConstants.ALIGN_CENTER)
		{
			dx = -0.5;
		}
		else if (align == mxConstants.ALIGN_RIGHT)
		{
			dx = -1;
		}

		// Vertical alignment
		if (valign == mxConstants.ALIGN_MIDDLE)
		{
			dy = -0.5;
		}
		else if (valign == mxConstants.ALIGN_BOTTOM)
		{
			dy = -1;
		}
		
		return new mxPoint(dx, dy);
	},
	
	/**
	 * Function: getSizeForString
	 * 
	 * Returns an <mxRectangle> with the size (width and height in pixels) of
	 * the given string. The string may contain HTML markup. Newlines should be
	 * converted to <br> before calling this method. The caller is responsible
	 * for sanitizing the HTML markup.
	 * 
	 * Example:
	 * 
	 * (code)
	 * var label = graph.getLabel(cell).replace(/\n/g, "<br>");
	 * var size = graph.getSizeForString(label);
	 * (end)
	 * 
	 * Parameters:
	 * 
	 * text - String whose size should be returned.
	 * fontSize - Integer that specifies the font size in pixels. Default is
	 * <mxConstants.DEFAULT_FONTSIZE>.
	 * fontFamily - String that specifies the name of the font family. Default
	 * is <mxConstants.DEFAULT_FONTFAMILY>.
	 * textWidth - Optional width for text wrapping.
	 */
	getSizeForString: function(text, fontSize, fontFamily, textWidth)
	{
		fontSize = (fontSize != null) ? fontSize : mxConstants.DEFAULT_FONTSIZE;
		fontFamily = (fontFamily != null) ? fontFamily : mxConstants.DEFAULT_FONTFAMILY;
		var div = document.createElement('div');
		
		// Sets the font size and family
		div.style.fontFamily = fontFamily;
		div.style.fontSize = Math.round(fontSize) + 'px';
		div.style.lineHeight = Math.round(fontSize * mxConstants.LINE_HEIGHT) + 'px';
		
		// Disables block layout and outside wrapping and hides the div
		div.style.position = 'absolute';
		div.style.visibility = 'hidden';
		div.style.display = (mxClient.IS_QUIRKS) ? 'inline' : 'inline-block';
		div.style.zoom = '1';
		
		if (textWidth != null)
		{
			div.style.width = textWidth + 'px';
			div.style.whiteSpace = 'normal';
		}
		else
		{
			div.style.whiteSpace = 'nowrap';
		}
		
		// Adds the text and inserts into DOM for updating of size
		div.innerHTML = text;
		document.body.appendChild(div);
		
		// Gets the size and removes from DOM
		var size = new mxRectangle(0, 0, div.offsetWidth, div.offsetHeight);
		document.body.removeChild(div);
		
		return size;
	},
	
	/**
	 * Function: getViewXml
	 */
	getViewXml: function(graph, scale, cells, x0, y0)
	{
		x0 = (x0 != null) ? x0 : 0;
		y0 = (y0 != null) ? y0 : 0;
		scale = (scale != null) ? scale : 1;

		if (cells == null)
		{
			var model = graph.getModel();
			cells = [model.getRoot()];
		}
		
		var view = graph.getView();
		var result = null;

		// Disables events on the view
		var eventsEnabled = view.isEventsEnabled();
		view.setEventsEnabled(false);

		// Workaround for label bounds not taken into account for image export.
		// Creates a temporary draw pane which is used for rendering the text.
		// Text rendering is required for finding the bounds of the labels.
		var drawPane = view.drawPane;
		var overlayPane = view.overlayPane;

		if (graph.dialect == mxConstants.DIALECT_SVG)
		{
			view.drawPane = document.createElementNS(mxConstants.NS_SVG, 'g');
			view.canvas.appendChild(view.drawPane);

			// Redirects cell overlays into temporary container
			view.overlayPane = document.createElementNS(mxConstants.NS_SVG, 'g');
			view.canvas.appendChild(view.overlayPane);
		}
		else
		{
			view.drawPane = view.drawPane.cloneNode(false);
			view.canvas.appendChild(view.drawPane);
			
			// Redirects cell overlays into temporary container
			view.overlayPane = view.overlayPane.cloneNode(false);
			view.canvas.appendChild(view.overlayPane);
		}

		// Resets the translation
		var translate = view.getTranslate();
		view.translate = new mxPoint(x0, y0);

		// Creates the temporary cell states in the view
		var temp = new mxTemporaryCellStates(graph.getView(), scale, cells);

		try
		{
			var enc = new mxCodec();
			result = enc.encode(graph.getView());
		}
		finally
		{
			temp.destroy();
			view.translate = translate;
			view.canvas.removeChild(view.drawPane);
			view.canvas.removeChild(view.overlayPane);
			view.drawPane = drawPane;
			view.overlayPane = overlayPane;
			view.setEventsEnabled(eventsEnabled);
		}

		return result;
	},
	
	/**
	 * Function: getScaleForPageCount
	 * 
	 * Returns the scale to be used for printing the graph with the given
	 * bounds across the specifies number of pages with the given format. The
	 * scale is always computed such that it given the given amount or fewer
	 * pages in the print output. See <mxPrintPreview> for an example.
	 * 
	 * Parameters:
	 * 
	 * pageCount - Specifies the number of pages in the print output.
	 * graph - <mxGraph> that should be printed.
	 * pageFormat - Optional <mxRectangle> that specifies the page format.
	 * Default is <mxConstants.PAGE_FORMAT_A4_PORTRAIT>.
	 * border - The border along each side of every page.
	 */
	getScaleForPageCount: function(pageCount, graph, pageFormat, border)
	{
		if (pageCount < 1)
		{
			// We can't work with less than 1 page, return no scale
			// change
			return 1;
		}
		
		pageFormat = (pageFormat != null) ? pageFormat : mxConstants.PAGE_FORMAT_A4_PORTRAIT;
		border = (border != null) ? border : 0;
		
		var availablePageWidth = pageFormat.width - (border * 2);
		var availablePageHeight = pageFormat.height - (border * 2);

		// Work out the number of pages required if the
		// graph is not scaled.
		var graphBounds = graph.getGraphBounds().clone();
		var sc = graph.getView().getScale();
		graphBounds.width /= sc;
		graphBounds.height /= sc;
		var graphWidth = graphBounds.width;
		var graphHeight = graphBounds.height;

		var scale = 1;
		
		// The ratio of the width/height for each printer page
		var pageFormatAspectRatio = availablePageWidth / availablePageHeight;
		// The ratio of the width/height for the graph to be printer
		var graphAspectRatio = graphWidth / graphHeight;
		
		// The ratio of horizontal pages / vertical pages for this 
		// graph to maintain its aspect ratio on this page format
		var pagesAspectRatio = graphAspectRatio / pageFormatAspectRatio;
		
		// Factor the square root of the page count up and down 
		// by the pages aspect ratio to obtain a horizontal and 
		// vertical page count that adds up to the page count
		// and has the correct aspect ratio
		var pageRoot = Math.sqrt(pageCount);
		var pagesAspectRatioSqrt = Math.sqrt(pagesAspectRatio);
		var numRowPages = pageRoot * pagesAspectRatioSqrt;
		var numColumnPages = pageRoot / pagesAspectRatioSqrt;

		// These value are rarely more than 2 rounding downs away from
		// a total that meets the page count. In cases of one being less 
		// than 1 page, the other value can be too high and take more iterations 
		// In this case, just change that value to be the page count, since 
		// we know the other value is 1
		if (numRowPages < 1 && numColumnPages > pageCount)
		{
			var scaleChange = numColumnPages / pageCount;
			numColumnPages = pageCount;
			numRowPages /= scaleChange;
		}
		
		if (numColumnPages < 1 && numRowPages > pageCount)
		{
			var scaleChange = numRowPages / pageCount;
			numRowPages = pageCount;
			numColumnPages /= scaleChange;
		}		

		var currentTotalPages = Math.ceil(numRowPages) * Math.ceil(numColumnPages);

		var numLoops = 0;
		
		// Iterate through while the rounded up number of pages comes to
		// a total greater than the required number
		while (currentTotalPages > pageCount)
		{
			// Round down the page count (rows or columns) that is
			// closest to its next integer down in percentage terms.
			// i.e. Reduce the page total by reducing the total
			// page area by the least possible amount

			var roundRowDownProportion = Math.floor(numRowPages) / numRowPages;
			var roundColumnDownProportion = Math.floor(numColumnPages) / numColumnPages;
			
			// If the round down proportion is, work out the proportion to
			// round down to 1 page less
			if (roundRowDownProportion == 1)
			{
				roundRowDownProportion = Math.floor(numRowPages-1) / numRowPages;
			}
			if (roundColumnDownProportion == 1)
			{
				roundColumnDownProportion = Math.floor(numColumnPages-1) / numColumnPages;
			}
			
			// Check which rounding down is smaller, but in the case of very small roundings
			// try the other dimension instead
			var scaleChange = 1;
			
			// Use the higher of the two values
			if (roundRowDownProportion > roundColumnDownProportion)
			{
				scaleChange = roundRowDownProportion;
			}
			else
			{
				scaleChange = roundColumnDownProportion;
			}

			numRowPages = numRowPages * scaleChange;
			numColumnPages = numColumnPages * scaleChange;
			currentTotalPages = Math.ceil(numRowPages) * Math.ceil(numColumnPages);
			
			numLoops++;
			
			if (numLoops > 10)
			{
				break;
			}
		}

		// Work out the scale from the number of row pages required
		// The column pages will give the same value
		var posterWidth = availablePageWidth * numRowPages;
		scale = posterWidth / graphWidth;
		
		// Allow for rounding errors
		return scale * 0.99999;
	},
	
	/**
	 * Function: show
	 * 
	 * Copies the styles and the markup from the graph's container into the
	 * given document and removes all cursor styles. The document is returned.
	 * 
	 * This function should be called from within the document with the graph.
	 * If you experience problems with missing stylesheets in IE then try adding
	 * the domain to the trusted sites.
	 * 
	 * Parameters:
	 * 
	 * graph - <mxGraph> to be copied.
	 * doc - Document where the new graph is created.
	 * x0 - X-coordinate of the graph view origin. Default is 0.
	 * y0 - Y-coordinate of the graph view origin. Default is 0.
	 * w - Optional width of the graph view.
	 * h - Optional height of the graph view.
	 */
	show: function(graph, doc, x0, y0, w, h)
	{
		x0 = (x0 != null) ? x0 : 0;
		y0 = (y0 != null) ? y0 : 0;
		
		if (doc == null)
		{
			var wnd = window.open();
			doc = wnd.document;
		}
		else
		{
			doc.open();
		}

		// Workaround for missing print output in IE9 standards
		if (document.documentMode == 9)
		{
			doc.writeln('<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=9"><![endif]-->');
		}
		
		var bounds = graph.getGraphBounds();
		var dx = Math.ceil(x0 - bounds.x);
		var dy = Math.ceil(y0 - bounds.y);
		
		if (w == null)
		{
			w = Math.ceil(bounds.width + x0) + Math.ceil(Math.ceil(bounds.x) - bounds.x);
		}
		
		if (h == null)
		{
			h = Math.ceil(bounds.height + y0) + Math.ceil(Math.ceil(bounds.y) - bounds.y);
		}
		
		// Needs a special way of creating the page so that no click is required
		// to refresh the contents after the external CSS styles have been loaded.
		// To avoid a click or programmatic refresh, the styleSheets[].cssText
		// property is copied over from the original document.
		if (mxClient.IS_IE || document.documentMode == 11)
		{
			var html = '<html><head>';

			var base = document.getElementsByTagName('base');
			
			for (var i = 0; i < base.length; i++)
			{
				html += base[i].outerHTML;
			}

			html += '<style>';

			// Copies the stylesheets without having to load them again
			for (var i = 0; i < document.styleSheets.length; i++)
			{
				try
				{
					html += document.styleSheets[i].cssText;
				}
				catch (e)
				{
					// ignore security exception
				}
			}

			html += '</style></head><body style="margin:0px;">';
			
			// Copies the contents of the graph container
			html += '<div style="position:absolute;overflow:hidden;width:' + w + 'px;height:' + h + 'px;"><div style="position:relative;left:' + dx + 'px;top:' + dy + 'px;">';
			html += graph.container.innerHTML;
			html += '</div></div></body><html>';

			doc.writeln(html);
			doc.close();
		}
		else
		{
			doc.writeln('<html><head>');
			
			var base = document.getElementsByTagName('base');
			
			for (var i = 0; i < base.length; i++)
			{
				doc.writeln(mxUtils.getOuterHtml(base[i]));
			}
			
			var links = document.getElementsByTagName('link');
			
			for (var i = 0; i < links.length; i++)
			{
				doc.writeln(mxUtils.getOuterHtml(links[i]));
			}
	
			var styles = document.getElementsByTagName('style');
			
			for (var i = 0; i < styles.length; i++)
			{
				doc.writeln(mxUtils.getOuterHtml(styles[i]));
			}

			doc.writeln('</head><body style="margin:0px;"></body></html>');
			doc.close();

			var outer = doc.createElement('div');
			outer.position = 'absolute';
			outer.overflow = 'hidden';
			outer.style.width = w + 'px';
			outer.style.height = h + 'px';

			// Required for HTML labels if foreignObjects are disabled
			var div = doc.createElement('div');
			div.style.position = 'absolute';
			div.style.left = dx + 'px';
			div.style.top = dy + 'px';

			var node = graph.container.firstChild;
			var svg = null;
			
			while (node != null)
			{
				var clone = node.cloneNode(true);
				
				if (node == graph.view.drawPane.ownerSVGElement)
				{
					outer.appendChild(clone);
					svg = clone;
				}
				else
				{
					div.appendChild(clone);
				}
				
				node = node.nextSibling;
			}

			doc.body.appendChild(outer);
			
			if (div.firstChild != null)
			{
				doc.body.appendChild(div);
			}
						
			if (svg != null)
			{
				svg.style.minWidth = '';
				svg.style.minHeight = '';
				svg.firstChild.setAttribute('transform', 'translate(' + dx + ',' + dy + ')');
			}
		}
		
		mxUtils.removeCursors(doc.body);
	
		return doc;
	},
	
	/**
	 * Function: printScreen
	 * 
	 * Prints the specified graph using a new window and the built-in print
	 * dialog.
	 * 
	 * This function should be called from within the document with the graph.
	 * 
	 * Parameters:
	 * 
	 * graph - <mxGraph> to be printed.
	 */
	printScreen: function(graph)
	{
		var wnd = window.open();
		var bounds = graph.getGraphBounds();
		mxUtils.show(graph, wnd.document);
		
		var print = function()
		{
			wnd.focus();
			wnd.print();
			wnd.close();
		};
		
		// Workaround for Google Chrome which needs a bit of a
		// delay in order to render the SVG contents
		if (mxClient.IS_GC)
		{
			wnd.setTimeout(print, 500);
		}
		else
		{
			print();
		}
	},
	
	/**
	 * Function: popup
	 * 
	 * Shows the specified text content in a new <mxWindow> or a new browser
	 * window if isInternalWindow is false.
	 * 
	 * Parameters:
	 * 
	 * content - String that specifies the text to be displayed.
	 * isInternalWindow - Optional boolean indicating if an mxWindow should be
	 * used instead of a new browser window. Default is false.
	 */
	popup: function(content, isInternalWindow)
	{
	   	if (isInternalWindow)
	   	{
			var div = document.createElement('div');
			
			div.style.overflow = 'scroll';
			div.style.width = '636px';
			div.style.height = '460px';
			
			var pre = document.createElement('pre');
		    pre.innerHTML = mxUtils.htmlEntities(content, false).
		    	replace(/\n/g,'<br>').replace(/ /g, '&nbsp;');
			
			div.appendChild(pre);
			
			var w = document.body.clientWidth;
			var h = Math.max(document.body.clientHeight || 0, document.documentElement.clientHeight)
			var wnd = new mxWindow('Popup Window', div,
				w/2-320, h/2-240, 640, 480, false, true);

			wnd.setClosable(true);
			wnd.setVisible(true);
		}
		else
		{
			// Wraps up the XML content in a textarea
			if (mxClient.IS_NS)
			{
			    var wnd = window.open();
				wnd.document.writeln('<pre>'+mxUtils.htmlEntities(content)+'</pre');
			   	wnd.document.close();
			}
			else
			{
			    var wnd = window.open();
			    var pre = wnd.document.createElement('pre');
			    pre.innerHTML = mxUtils.htmlEntities(content, false).
			    	replace(/\n/g,'<br>').replace(/ /g, '&nbsp;');
			   	wnd.document.body.appendChild(pre);
			}
	   	}
	},
	
	/**
	 * Function: alert
	 * 
	 * Displayss the given alert in a new dialog. This implementation uses the
	 * built-in alert function. This is used to display validation errors when
	 * connections cannot be changed or created.
	 * 
	 * Parameters:
	 * 
	 * message - String specifying the message to be displayed.
	 */
	alert: function(message)
	{
		alert(message);
	},
	
	/**
	 * Function: prompt
	 * 
	 * Displays the given message in a prompt dialog. This implementation uses
	 * the built-in prompt function.
	 * 
	 * Parameters:
	 * 
	 * message - String specifying the message to be displayed.
	 * defaultValue - Optional string specifying the default value.
	 */
	prompt: function(message, defaultValue)
	{
		return prompt(message, (defaultValue != null) ? defaultValue : '');
	},
	
	/**
	 * Function: confirm
	 * 
	 * Displays the given message in a confirm dialog. This implementation uses
	 * the built-in confirm function.
	 * 
	 * Parameters:
	 * 
	 * message - String specifying the message to be displayed.
	 */
	confirm: function(message)
	{
		return confirm(message);
	},

	/**
	 * Function: error
	 * 
	 * Displays the given error message in a new <mxWindow> of the given width.
	 * If close is true then an additional close button is added to the window.
	 * The optional icon specifies the icon to be used for the window. Default
	 * is <mxUtils.errorImage>.
	 * 
	 * Parameters:
	 * 
	 * message - String specifying the message to be displayed.
	 * width - Integer specifying the width of the window.
	 * close - Optional boolean indicating whether to add a close button.
	 * icon - Optional icon for the window decoration.
	 */
	error: function(message, width, close, icon)
	{
		var div = document.createElement('div');
		div.style.padding = '20px';

		var img = document.createElement('img');
		img.setAttribute('src', icon || mxUtils.errorImage);
		img.setAttribute('valign', 'bottom');
		img.style.verticalAlign = 'middle';
		div.appendChild(img);

		div.appendChild(document.createTextNode('\u00a0')); // &nbsp;
		div.appendChild(document.createTextNode('\u00a0')); // &nbsp;
		div.appendChild(document.createTextNode('\u00a0')); // &nbsp;
		mxUtils.write(div, message);

		var w = document.body.clientWidth;
		var h = (document.body.clientHeight || document.documentElement.clientHeight);
		var warn = new mxWindow(mxResources.get(mxUtils.errorResource) ||
			mxUtils.errorResource, div, (w-width)/2, h/4, width, null,
			false, true);

		if (close)
		{
			mxUtils.br(div);
			
			var tmp = document.createElement('p');
			var button = document.createElement('button');

			if (mxClient.IS_IE)
			{
				button.style.cssText = 'float:right';
			}
			else
			{
				button.setAttribute('style', 'float:right');
			}

			mxEvent.addListener(button, 'click', function(evt)
			{
				warn.destroy();
			});

			mxUtils.write(button, mxResources.get(mxUtils.closeResource) ||
				mxUtils.closeResource);
			
			tmp.appendChild(button);
			div.appendChild(tmp);
			
			mxUtils.br(div);
			
			warn.setClosable(true);
		}
		
		warn.setVisible(true);
		
		return warn;
	},

	/**
	 * Function: makeDraggable
	 * 
	 * Configures the given DOM element to act as a drag source for the
	 * specified graph. Returns a a new <mxDragSource>. If
	 * <mxDragSource.guideEnabled> is enabled then the x and y arguments must
	 * be used in funct to match the preview location.
	 * 
	 * Example:
	 * 
	 * (code)
	 * var funct = function(graph, evt, cell, x, y)
	 * {
	 *   if (graph.canImportCell(cell))
	 *   {
	 *     var parent = graph.getDefaultParent();
	 *     var vertex = null;
	 *     
	 *     graph.getModel().beginUpdate();
	 *     try
	 *     {
	 * 	     vertex = graph.insertVertex(parent, null, 'Hello', x, y, 80, 30);
	 *     }
	 *     finally
	 *     {
	 *       graph.getModel().endUpdate();
	 *     }
	 *
	 *     graph.setSelectionCell(vertex);
	 *   }
	 * }
	 * 
	 * var img = document.createElement('img');
	 * img.setAttribute('src', 'editors/images/rectangle.gif');
	 * img.style.position = 'absolute';
	 * img.style.left = '0px';
	 * img.style.top = '0px';
	 * img.style.width = '16px';
	 * img.style.height = '16px';
	 * 
	 * var dragImage = img.cloneNode(true);
	 * dragImage.style.width = '32px';
	 * dragImage.style.height = '32px';
	 * mxUtils.makeDraggable(img, graph, funct, dragImage);
	 * document.body.appendChild(img);
	 * (end)
	 * 
	 * Parameters:
	 * 
	 * element - DOM element to make draggable.
	 * graphF - <mxGraph> that acts as the drop target or a function that takes a
	 * mouse event and returns the current <mxGraph>.
	 * funct - Function to execute on a successful drop.
	 * dragElement - Optional DOM node to be used for the drag preview.
	 * dx - Optional horizontal offset between the cursor and the drag
	 * preview.
	 * dy - Optional vertical offset between the cursor and the drag
	 * preview.
	 * autoscroll - Optional boolean that specifies if autoscroll should be
	 * used. Default is mxGraph.autoscroll.
	 * scalePreview - Optional boolean that specifies if the preview element
	 * should be scaled according to the graph scale. If this is true, then
	 * the offsets will also be scaled. Default is false.
	 * highlightDropTargets - Optional boolean that specifies if dropTargets
	 * should be highlighted. Default is true.
	 * getDropTarget - Optional function to return the drop target for a given
	 * location (x, y). Default is mxGraph.getCellAt.
	 */
	makeDraggable: function(element, graphF, funct, dragElement, dx, dy, autoscroll,
			scalePreview, highlightDropTargets, getDropTarget)
	{
		var dragSource = new mxDragSource(element, funct);
		dragSource.dragOffset = new mxPoint((dx != null) ? dx : 0,
			(dy != null) ? dy : mxConstants.TOOLTIP_VERTICAL_OFFSET);
		dragSource.autoscroll = autoscroll;
		
		// Cannot enable this by default. This needs to be enabled in the caller
		// if the funct argument uses the new x- and y-arguments.
		dragSource.setGuidesEnabled(false);
		
		if (highlightDropTargets != null)
		{
			dragSource.highlightDropTargets = highlightDropTargets;
		}
		
		// Overrides function to find drop target cell
		if (getDropTarget != null)
		{
			dragSource.getDropTarget = getDropTarget;
		}
		
		// Overrides function to get current graph
		dragSource.getGraphForEvent = function(evt)
		{
			return (typeof(graphF) == 'function') ? graphF(evt) : graphF;
		};
		
		// Translates switches into dragSource customizations
		if (dragElement != null)
		{
			dragSource.createDragElement = function()
			{
				return dragElement.cloneNode(true);
			};
			
			if (scalePreview)
			{
				dragSource.createPreviewElement = function(graph)
				{
					var elt = dragElement.cloneNode(true);

					var w = parseInt(elt.style.width);
					var h = parseInt(elt.style.height);
					elt.style.width = Math.round(w * graph.view.scale) + 'px';
					elt.style.height = Math.round(h * graph.view.scale) + 'px';
					
					return elt;
				};
			}
		}
		
		return dragSource;
	}

};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
 var mxConstants =
 {
	/**
	 * Class: mxConstants
	 * 
	 * Defines various global constants.
	 * 
	 * Variable: DEFAULT_HOTSPOT
	 * 
	 * Defines the portion of the cell which is to be used as a connectable
	 * region. Default is 0.3. Possible values are 0 < x <= 1. 
	 */
	DEFAULT_HOTSPOT: 0.3,

	/**
	 * Variable: MIN_HOTSPOT_SIZE
	 * 
	 * Defines the minimum size in pixels of the portion of the cell which is
	 * to be used as a connectable region. Default is 8.
	 */
	MIN_HOTSPOT_SIZE: 8,

	/**
	 * Variable: MAX_HOTSPOT_SIZE
	 * 
	 * Defines the maximum size in pixels of the portion of the cell which is
	 * to be used as a connectable region. Use 0 for no maximum. Default is 0.
	 */
	MAX_HOTSPOT_SIZE: 0,

	/**
	 * Variable: RENDERING_HINT_EXACT
	 * 
	 * Defines the exact rendering hint.
	 */
	RENDERING_HINT_EXACT: 'exact',

	/**
	 * Variable: RENDERING_HINT_FASTER
	 * 
	 * Defines the faster rendering hint.
	 */
	RENDERING_HINT_FASTER: 'faster',

	/**
	 * Variable: RENDERING_HINT_FASTEST
	 * 
	 * Defines the fastest rendering hint.
	 */
	RENDERING_HINT_FASTEST: 'fastest',

	/**
	 * Variable: DIALECT_SVG
	 * 
	 * Defines the SVG display dialect name.
	 */
	DIALECT_SVG: 'svg',

	/**
	 * Variable: DIALECT_VML
	 * 
	 * Defines the VML display dialect name.
	 */
	DIALECT_VML: 'vml',

	/**
	 * Variable: DIALECT_MIXEDHTML
	 * 
	 * Defines the mixed HTML display dialect name.
	 */
	DIALECT_MIXEDHTML: 'mixedHtml',

	/**
	 * Variable: DIALECT_PREFERHTML
	 * 
	 * Defines the preferred HTML display dialect name.
	 */
	DIALECT_PREFERHTML: 'preferHtml',

	/**
	 * Variable: DIALECT_STRICTHTML
	 * 
	 * Defines the strict HTML display dialect.
	 */
	DIALECT_STRICTHTML: 'strictHtml',

	/**
	 * Variable: NS_SVG
	 * 
	 * Defines the SVG namespace.
	 */
	NS_SVG: 'http://www.w3.org/2000/svg',

	/**
	 * Variable: NS_XHTML
	 * 
	 * Defines the XHTML namespace.
	 */
	NS_XHTML: 'http://www.w3.org/1999/xhtml',

	/**
	 * Variable: NS_XLINK
	 * 
	 * Defines the XLink namespace.
	 */
	NS_XLINK: 'http://www.w3.org/1999/xlink',

	/**
	 * Variable: SHADOWCOLOR
	 * 
	 * Defines the color to be used to draw shadows in shapes and windows.
	 * Default is gray.
	 */
	SHADOWCOLOR: 'gray',

	/**
	 * Variable: VML_SHADOWCOLOR
	 * 
	 * Used for shadow color in filters where transparency is not supported
	 * (Microsoft Internet Explorer). Default is gray.
	 */
	VML_SHADOWCOLOR: 'gray',

	/**
	 * Variable: SHADOW_OFFSET_X
	 * 
	 * Specifies the x-offset of the shadow. Default is 2.
	 */
	SHADOW_OFFSET_X: 2,

	/**
	 * Variable: SHADOW_OFFSET_Y
	 * 
	 * Specifies the y-offset of the shadow. Default is 3.
	 */
	SHADOW_OFFSET_Y: 3,
	
	/**
	 * Variable: SHADOW_OPACITY
	 * 
	 * Defines the opacity for shadows. Default is 1.
	 */
	SHADOW_OPACITY: 1,
 
	/**
	 * Variable: NODETYPE_ELEMENT
	 * 
	 * DOM node of type ELEMENT.
	 */
	NODETYPE_ELEMENT: 1,

	/**
	 * Variable: NODETYPE_ATTRIBUTE
	 * 
	 * DOM node of type ATTRIBUTE.
	 */
	NODETYPE_ATTRIBUTE: 2,

	/**
	 * Variable: NODETYPE_TEXT
	 * 
	 * DOM node of type TEXT.
	 */
	NODETYPE_TEXT: 3,

	/**
	 * Variable: NODETYPE_CDATA
	 * 
	 * DOM node of type CDATA.
	 */
	NODETYPE_CDATA: 4,
	
	/**
	 * Variable: NODETYPE_ENTITY_REFERENCE
	 * 
	 * DOM node of type ENTITY_REFERENCE.
	 */
	NODETYPE_ENTITY_REFERENCE: 5,

	/**
	 * Variable: NODETYPE_ENTITY
	 * 
	 * DOM node of type ENTITY.
	 */
	NODETYPE_ENTITY: 6,

	/**
	 * Variable: NODETYPE_PROCESSING_INSTRUCTION
	 * 
	 * DOM node of type PROCESSING_INSTRUCTION.
	 */
	NODETYPE_PROCESSING_INSTRUCTION: 7,

	/**
	 * Variable: NODETYPE_COMMENT
	 * 
	 * DOM node of type COMMENT.
	 */
	NODETYPE_COMMENT: 8,
		
	/**
	 * Variable: NODETYPE_DOCUMENT
	 * 
	 * DOM node of type DOCUMENT.
	 */
	NODETYPE_DOCUMENT: 9,

	/**
	 * Variable: NODETYPE_DOCUMENTTYPE
	 * 
	 * DOM node of type DOCUMENTTYPE.
	 */
	NODETYPE_DOCUMENTTYPE: 10,

	/**
	 * Variable: NODETYPE_DOCUMENT_FRAGMENT
	 * 
	 * DOM node of type DOCUMENT_FRAGMENT.
	 */
	NODETYPE_DOCUMENT_FRAGMENT: 11,

	/**
	 * Variable: NODETYPE_NOTATION
	 * 
	 * DOM node of type NOTATION.
	 */
	NODETYPE_NOTATION: 12,
	
	/**
	 * Variable: TOOLTIP_VERTICAL_OFFSET
	 * 
	 * Defines the vertical offset for the tooltip.
	 * Default is 16.
	 */
	TOOLTIP_VERTICAL_OFFSET: 16,

	/**
	 * Variable: DEFAULT_VALID_COLOR
	 * 
	 * Specifies the default valid color. Default is #0000FF.
	 */
	DEFAULT_VALID_COLOR: '#00FF00',

	/**
	 * Variable: DEFAULT_INVALID_COLOR
	 * 
	 * Specifies the default invalid color. Default is #FF0000.
	 */
	DEFAULT_INVALID_COLOR: '#FF0000',

	/**
	 * Variable: OUTLINE_HIGHLIGHT_COLOR
	 * 
	 * Specifies the default highlight color for shape outlines.
	 * Default is #0000FF. This is used in <mxEdgeHandler>.
	 */
	OUTLINE_HIGHLIGHT_COLOR: '#00FF00',

	/**
	 * Variable: OUTLINE_HIGHLIGHT_COLOR
	 * 
	 * Defines the strokewidth to be used for shape outlines.
	 * Default is 5. This is used in <mxEdgeHandler>.
	 */
	OUTLINE_HIGHLIGHT_STROKEWIDTH: 5,

	/**
	 * Variable: HIGHLIGHT_STROKEWIDTH
	 * 
	 * Defines the strokewidth to be used for the highlights.
	 * Default is 3.
	 */
	HIGHLIGHT_STROKEWIDTH: 3,

	/**
	 * Variable: CONSTRAINT_HIGHLIGHT_SIZE
	 * 
	 * Size of the constraint highlight (in px). Default is 2.
	 */
	HIGHLIGHT_SIZE: 2,
	
	/**
	 * Variable: HIGHLIGHT_OPACITY
	 * 
	 * Opacity (in %) used for the highlights (including outline).
	 * Default is 100.
	 */
	HIGHLIGHT_OPACITY: 100,
	
	/**
	 * Variable: CURSOR_MOVABLE_VERTEX
	 * 
	 * Defines the cursor for a movable vertex. Default is 'move'.
	 */
	CURSOR_MOVABLE_VERTEX: 'move',
	
	/**
	 * Variable: CURSOR_MOVABLE_EDGE
	 * 
	 * Defines the cursor for a movable edge. Default is 'move'.
	 */
	CURSOR_MOVABLE_EDGE: 'move',
	
	/**
	 * Variable: CURSOR_LABEL_HANDLE
	 * 
	 * Defines the cursor for a movable label. Default is 'default'.
	 */
	CURSOR_LABEL_HANDLE: 'default',
	
	/**
	 * Variable: CURSOR_TERMINAL_HANDLE
	 * 
	 * Defines the cursor for a terminal handle. Default is 'pointer'.
	 */
	CURSOR_TERMINAL_HANDLE: 'pointer',
	
	/**
	 * Variable: CURSOR_BEND_HANDLE
	 * 
	 * Defines the cursor for a movable bend. Default is 'crosshair'.
	 */
	CURSOR_BEND_HANDLE: 'crosshair',

	/**
	 * Variable: CURSOR_VIRTUAL_BEND_HANDLE
	 * 
	 * Defines the cursor for a movable bend. Default is 'crosshair'.
	 */
	CURSOR_VIRTUAL_BEND_HANDLE: 'crosshair',
	
	/**
	 * Variable: CURSOR_CONNECT
	 * 
	 * Defines the cursor for a connectable state. Default is 'pointer'.
	 */
	CURSOR_CONNECT: 'pointer',

	/**
	 * Variable: HIGHLIGHT_COLOR
	 * 
	 * Defines the color to be used for the cell highlighting.
	 * Use 'none' for no color. Default is #00FF00.
	 */
	HIGHLIGHT_COLOR: '#00FF00',

	/**
	 * Variable: TARGET_HIGHLIGHT_COLOR
	 * 
	 * Defines the color to be used for highlighting a target cell for a new
	 * or changed connection. Note that this may be either a source or
	 * target terminal in the graph. Use 'none' for no color.
	 * Default is #0000FF.
	 */
	CONNECT_TARGET_COLOR: '#0000FF',

	/**
	 * Variable: INVALID_CONNECT_TARGET_COLOR
	 * 
	 * Defines the color to be used for highlighting a invalid target cells
	 * for a new or changed connections. Note that this may be either a source
	 * or target terminal in the graph. Use 'none' for no color. Default is
	 * #FF0000.
	 */
	INVALID_CONNECT_TARGET_COLOR: '#FF0000',

	/**
	 * Variable: DROP_TARGET_COLOR
	 * 
	 * Defines the color to be used for the highlighting target parent cells
	 * (for drag and drop). Use 'none' for no color. Default is #0000FF.
	 */
	DROP_TARGET_COLOR: '#0000FF',

	/**
	 * Variable: VALID_COLOR
	 * 
	 * Defines the color to be used for the coloring valid connection
	 * previews. Use 'none' for no color. Default is #FF0000.
	 */
	VALID_COLOR: '#00FF00',

	/**
	 * Variable: INVALID_COLOR
	 * 
	 * Defines the color to be used for the coloring invalid connection
	 * previews. Use 'none' for no color. Default is #FF0000.
	 */
	INVALID_COLOR: '#FF0000',

	/**
	 * Variable: EDGE_SELECTION_COLOR
	 * 
	 * Defines the color to be used for the selection border of edges. Use
	 * 'none' for no color. Default is #00FF00.
	 */
	EDGE_SELECTION_COLOR: '#00FF00',

	/**
	 * Variable: VERTEX_SELECTION_COLOR
	 * 
	 * Defines the color to be used for the selection border of vertices. Use
	 * 'none' for no color. Default is #00FF00.
	 */
	VERTEX_SELECTION_COLOR: '#00FF00',

	/**
	 * Variable: VERTEX_SELECTION_STROKEWIDTH
	 * 
	 * Defines the strokewidth to be used for vertex selections.
	 * Default is 1.
	 */
	VERTEX_SELECTION_STROKEWIDTH: 1,

	/**
	 * Variable: EDGE_SELECTION_STROKEWIDTH
	 * 
	 * Defines the strokewidth to be used for edge selections.
	 * Default is 1.
	 */
	EDGE_SELECTION_STROKEWIDTH: 1,

	/**
	 * Variable: SELECTION_DASHED
	 * 
	 * Defines the dashed state to be used for the vertex selection
	 * border. Default is true.
	 */
	VERTEX_SELECTION_DASHED: true,

	/**
	 * Variable: SELECTION_DASHED
	 * 
	 * Defines the dashed state to be used for the edge selection
	 * border. Default is true.
	 */
	EDGE_SELECTION_DASHED: true,

	/**
	 * Variable: GUIDE_COLOR
	 * 
	 * Defines the color to be used for the guidelines in mxGraphHandler.
	 * Default is #FF0000.
	 */
	GUIDE_COLOR: '#FF0000',

	/**
	 * Variable: GUIDE_STROKEWIDTH
	 * 
	 * Defines the strokewidth to be used for the guidelines in mxGraphHandler.
	 * Default is 1.
	 */
	GUIDE_STROKEWIDTH: 1,

	/**
	 * Variable: OUTLINE_COLOR
	 * 
	 * Defines the color to be used for the outline rectangle
	 * border.  Use 'none' for no color. Default is #0099FF.
	 */
	OUTLINE_COLOR: '#0099FF',

	/**
	 * Variable: OUTLINE_STROKEWIDTH
	 * 
	 * Defines the strokewidth to be used for the outline rectangle
	 * stroke width. Default is 3.
	 */
	OUTLINE_STROKEWIDTH: (mxClient.IS_IE) ? 2 : 3,

	/**
	 * Variable: HANDLE_SIZE
	 * 
	 * Defines the default size for handles. Default is 6.
	 */
	HANDLE_SIZE: 6,

	/**
	 * Variable: LABEL_HANDLE_SIZE
	 * 
	 * Defines the default size for label handles. Default is 4.
	 */
	LABEL_HANDLE_SIZE: 4,

	/**
	 * Variable: HANDLE_FILLCOLOR
	 * 
	 * Defines the color to be used for the handle fill color. Use 'none' for
	 * no color. Default is #00FF00 (green).
	 */
	HANDLE_FILLCOLOR: '#00FF00',

	/**
	 * Variable: HANDLE_STROKECOLOR
	 * 
	 * Defines the color to be used for the handle stroke color. Use 'none' for
	 * no color. Default is black.
	 */
	HANDLE_STROKECOLOR: 'black',

	/**
	 * Variable: LABEL_HANDLE_FILLCOLOR
	 * 
	 * Defines the color to be used for the label handle fill color. Use 'none'
	 * for no color. Default is yellow.
	 */
	LABEL_HANDLE_FILLCOLOR: 'yellow',

	/**
	 * Variable: CONNECT_HANDLE_FILLCOLOR
	 * 
	 * Defines the color to be used for the connect handle fill color. Use
	 * 'none' for no color. Default is #0000FF (blue).
	 */
	CONNECT_HANDLE_FILLCOLOR: '#0000FF',

	/**
	 * Variable: LOCKED_HANDLE_FILLCOLOR
	 * 
	 * Defines the color to be used for the locked handle fill color. Use
	 * 'none' for no color. Default is #FF0000 (red).
	 */
	LOCKED_HANDLE_FILLCOLOR: '#FF0000',

	/**
	 * Variable: OUTLINE_HANDLE_FILLCOLOR
	 * 
	 * Defines the color to be used for the outline sizer fill color. Use
	 * 'none' for no color. Default is #00FFFF.
	 */
	OUTLINE_HANDLE_FILLCOLOR: '#00FFFF',

	/**
	 * Variable: OUTLINE_HANDLE_STROKECOLOR
	 * 
	 * Defines the color to be used for the outline sizer stroke color. Use
	 * 'none' for no color. Default is #0033FF.
	 */
	OUTLINE_HANDLE_STROKECOLOR: '#0033FF',

	/**
	 * Variable: DEFAULT_FONTFAMILY
	 * 
	 * Defines the default family for all fonts. Default is Arial,Helvetica.
	 */
	DEFAULT_FONTFAMILY: 'Arial,Helvetica',

	/**
	 * Variable: DEFAULT_FONTSIZE
	 * 
	 * Defines the default size (in px). Default is 11.
	 */
	DEFAULT_FONTSIZE: 11,

	/**
	 * Variable: DEFAULT_TEXT_DIRECTION
	 * 
	 * Defines the default value for the <STYLE_TEXT_DIRECTION> if no value is
	 * defined for it in the style. Default value is an empty string which means
	 * the default system setting is used and no direction is set.
	 */
	DEFAULT_TEXT_DIRECTION: '',

	/**
	 * Variable: LINE_HEIGHT
	 * 
	 * Defines the default line height for text labels. Default is 1.2.
	 */
	LINE_HEIGHT: 1.2,

	/**
	 * Variable: WORD_WRAP
	 * 
	 * Defines the CSS value for the word-wrap property. Default is "normal".
	 * Change this to "break-word" to allow long words to be able to be broken
	 * and wrap onto the next line.
	 */
	WORD_WRAP: 'normal',

	/**
	 * Variable: ABSOLUTE_LINE_HEIGHT
	 * 
	 * Specifies if absolute line heights should be used (px) in CSS. Default
	 * is false. Set this to true for backwards compatibility.
	 */
	ABSOLUTE_LINE_HEIGHT: false,

	/**
	 * Variable: DEFAULT_FONTSTYLE
	 * 
	 * Defines the default style for all fonts. Default is 0. This can be set
	 * to any combination of font styles as follows.
	 * 
	 * (code)
	 * mxConstants.DEFAULT_FONTSTYLE = mxConstants.FONT_BOLD | mxConstants.FONT_ITALIC;
	 * (end)
	 */
	DEFAULT_FONTSTYLE: 0,

	/**
	 * Variable: DEFAULT_STARTSIZE
	 * 
	 * Defines the default start size for swimlanes. Default is 40.
	 */
	DEFAULT_STARTSIZE: 40,

	/**
	 * Variable: DEFAULT_MARKERSIZE
	 * 
	 * Defines the default size for all markers. Default is 6.
	 */
	DEFAULT_MARKERSIZE: 6,

	/**
	 * Variable: DEFAULT_IMAGESIZE
	 * 
	 * Defines the default width and height for images used in the
	 * label shape. Default is 24.
	 */
	DEFAULT_IMAGESIZE: 24,

	/**
	 * Variable: ENTITY_SEGMENT
	 * 
	 * Defines the length of the horizontal segment of an Entity Relation.
	 * This can be overridden using <mxConstants.STYLE_SEGMENT> style.
	 * Default is 30.
	 */
	ENTITY_SEGMENT: 30,

	/**
	 * Variable: RECTANGLE_ROUNDING_FACTOR
	 * 
	 * Defines the rounding factor for rounded rectangles in percent between
	 * 0 and 1. Values should be smaller than 0.5. Default is 0.15.
	 */
	RECTANGLE_ROUNDING_FACTOR: 0.15,

	/**
	 * Variable: LINE_ARCSIZE
	 * 
	 * Defines the size of the arcs for rounded edges. Default is 20.
	 */
	LINE_ARCSIZE: 20,

	/**
	 * Variable: ARROW_SPACING
	 * 
	 * Defines the spacing between the arrow shape and its terminals. Default is 0.
	 */
	ARROW_SPACING: 0,

	/**
	 * Variable: ARROW_WIDTH
	 * 
	 * Defines the width of the arrow shape. Default is 30.
	 */
	ARROW_WIDTH: 30,

	/**
	 * Variable: ARROW_SIZE
	 * 
	 * Defines the size of the arrowhead in the arrow shape. Default is 30.
	 */
	ARROW_SIZE: 30,

	/**
	 * Variable: PAGE_FORMAT_A4_PORTRAIT
	 * 
	 * Defines the rectangle for the A4 portrait page format. The dimensions
	 * of this page format are 826x1169 pixels.
	 */
	PAGE_FORMAT_A4_PORTRAIT: new mxRectangle(0, 0, 827, 1169),

	/**
	 * Variable: PAGE_FORMAT_A4_PORTRAIT
	 * 
	 * Defines the rectangle for the A4 portrait page format. The dimensions
	 * of this page format are 826x1169 pixels.
	 */
	PAGE_FORMAT_A4_LANDSCAPE: new mxRectangle(0, 0, 1169, 827),

	/**
	 * Variable: PAGE_FORMAT_LETTER_PORTRAIT
	 * 
	 * Defines the rectangle for the Letter portrait page format. The
	 * dimensions of this page format are 850x1100 pixels.
	 */
	PAGE_FORMAT_LETTER_PORTRAIT: new mxRectangle(0, 0, 850, 1100),

	/**
	 * Variable: PAGE_FORMAT_LETTER_PORTRAIT
	 * 
	 * Defines the rectangle for the Letter portrait page format. The dimensions
	 * of this page format are 850x1100 pixels.
	 */
	PAGE_FORMAT_LETTER_LANDSCAPE: new mxRectangle(0, 0, 1100, 850),

	/**
	 * Variable: NONE
	 * 
	 * Defines the value for none. Default is "none".
	 */
	NONE: 'none',

	/**
	 * Variable: STYLE_PERIMETER
	 * 
	 * Defines the key for the perimeter style. This is a function that defines
	 * the perimeter around a particular shape. Possible values are the
	 * functions defined in <mxPerimeter>. Alternatively, the constants in this
	 * class that start with "PERIMETER_" may be used to access
	 * perimeter styles in <mxStyleRegistry>. Value is "perimeter".
	 */
	STYLE_PERIMETER: 'perimeter',
	
	/**
	 * Variable: STYLE_SOURCE_PORT
	 * 
	 * Defines the ID of the cell that should be used for computing the
	 * perimeter point of the source for an edge. This allows for graphically
	 * connecting to a cell while keeping the actual terminal of the edge.
	 * Value is "sourcePort".
	 */
	STYLE_SOURCE_PORT: 'sourcePort',
	
	/**
	 * Variable: STYLE_TARGET_PORT
	 * 
	 * Defines the ID of the cell that should be used for computing the
	 * perimeter point of the target for an edge. This allows for graphically
	 * connecting to a cell while keeping the actual terminal of the edge.
	 * Value is "targetPort".
	 */
	STYLE_TARGET_PORT: 'targetPort',

	/**
	 * Variable: STYLE_PORT_CONSTRAINT
	 * 
	 * Defines the direction(s) that edges are allowed to connect to cells in.
	 * Possible values are "DIRECTION_NORTH, DIRECTION_SOUTH, 
	 * DIRECTION_EAST" and "DIRECTION_WEST". Value is
	 * "portConstraint".
	 */
	STYLE_PORT_CONSTRAINT: 'portConstraint',

	/**
	 * Variable: STYLE_PORT_CONSTRAINT_ROTATION
	 * 
	 * Define whether port constraint directions are rotated with vertex
	 * rotation. 0 (default) causes port constraints to remain absolute, 
	 * relative to the graph, 1 causes the constraints to rotate with
	 * the vertex. Value is "portConstraintRotation".
	 */
	STYLE_PORT_CONSTRAINT_ROTATION: 'portConstraintRotation',

	/**
	 * Variable: STYLE_SOURCE_PORT_CONSTRAINT
	 * 
	 * Defines the direction(s) that edges are allowed to connect to sources in.
	 * Possible values are "DIRECTION_NORTH, DIRECTION_SOUTH, DIRECTION_EAST"
	 * and "DIRECTION_WEST". Value is "sourcePortConstraint".
	 */
	STYLE_SOURCE_PORT_CONSTRAINT: 'sourcePortConstraint',

	/**
	 * Variable: STYLE_TARGET_PORT_CONSTRAINT
	 * 
	 * Defines the direction(s) that edges are allowed to connect to targets in.
	 * Possible values are "DIRECTION_NORTH, DIRECTION_SOUTH, DIRECTION_EAST"
	 * and "DIRECTION_WEST". Value is "targetPortConstraint".
	 */
	STYLE_TARGET_PORT_CONSTRAINT: 'targetPortConstraint',

	/**
	 * Variable: STYLE_OPACITY
	 * 
	 * Defines the key for the opacity style. The type of the value is 
	 * numeric and the possible range is 0-100. Value is "opacity".
	 */
	STYLE_OPACITY: 'opacity',

	/**
	 * Variable: STYLE_FILL_OPACITY
	 * 
	 * Defines the key for the fill opacity style. The type of the value is 
	 * numeric and the possible range is 0-100. Value is "fillOpacity".
	 */
	STYLE_FILL_OPACITY: 'fillOpacity',

	/**
	 * Variable: STYLE_STROKE_OPACITY
	 * 
	 * Defines the key for the stroke opacity style. The type of the value is 
	 * numeric and the possible range is 0-100. Value is "strokeOpacity".
	 */
	STYLE_STROKE_OPACITY: 'strokeOpacity',

	/**
	 * Variable: STYLE_TEXT_OPACITY
	 * 
	 * Defines the key for the text opacity style. The type of the value is 
	 * numeric and the possible range is 0-100. Value is "textOpacity".
	 */
	STYLE_TEXT_OPACITY: 'textOpacity',

	/**
	 * Variable: STYLE_TEXT_DIRECTION
	 * 
	 * Defines the key for the text direction style. Possible values are
	 * "TEXT_DIRECTION_DEFAULT, TEXT_DIRECTION_AUTO, TEXT_DIRECTION_LTR"
	 * and "TEXT_DIRECTION_RTL". Value is "textDirection".
	 * The default value for the style is defined in <DEFAULT_TEXT_DIRECTION>.
	 * It is used is no value is defined for this key in a given style. This is
	 * an experimental style that is currently ignored in the backends.
	 */
	STYLE_TEXT_DIRECTION: 'textDirection',

	/**
	 * Variable: STYLE_OVERFLOW
	 * 
	 * Defines the key for the overflow style. Possible values are 'visible',
	 * 'hidden', 'fill' and 'width'. The default value is 'visible'. This value
	 * specifies how overlapping vertex labels are handled. A value of
	 * 'visible' will show the complete label. A value of 'hidden' will clip
	 * the label so that it does not overlap the vertex bounds. A value of
	 * 'fill' will use the vertex bounds and a value of 'width' will use the
	 * the vertex width for the label. See <mxGraph.isLabelClipped>. Note that
	 * the vertical alignment is ignored for overflow fill and for horizontal
	 * alignment, left should be used to avoid pixel offsets in Internet Explorer
	 * 11 and earlier or if foreignObjects are disabled. Value is "overflow".
	 */
	STYLE_OVERFLOW: 'overflow',

	/**
	 * Variable: STYLE_ORTHOGONAL
	 * 
	 * Defines if the connection points on either end of the edge should be
	 * computed so that the edge is vertical or horizontal if possible and
	 * if the point is not at a fixed location. Default is false. This is
	 * used in <mxGraph.isOrthogonal>, which also returns true if the edgeStyle
	 * of the edge is an elbow or entity. Value is "orthogonal".
	 */
	STYLE_ORTHOGONAL: 'orthogonal',

	/**
	 * Variable: STYLE_EXIT_X
	 * 
	 * Defines the key for the horizontal relative coordinate connection point
	 * of an edge with its source terminal. Value is "exitX".
	 */
	STYLE_EXIT_X: 'exitX',

	/**
	 * Variable: STYLE_EXIT_Y
	 * 
	 * Defines the key for the vertical relative coordinate connection point
	 * of an edge with its source terminal. Value is "exitY".
	 */
	STYLE_EXIT_Y: 'exitY',

	/**
	 * Variable: STYLE_EXIT_PERIMETER
	 * 
	 * Defines if the perimeter should be used to find the exact entry point
	 * along the perimeter of the source. Possible values are 0 (false) and
	 * 1 (true). Default is 1 (true). Value is "exitPerimeter".
	 */
	STYLE_EXIT_PERIMETER: 'exitPerimeter',

	/**
	 * Variable: STYLE_ENTRY_X
	 * 
	 * Defines the key for the horizontal relative coordinate connection point
	 * of an edge with its target terminal. Value is "entryX".
	 */
	STYLE_ENTRY_X: 'entryX',

	/**
	 * Variable: STYLE_ENTRY_Y
	 * 
	 * Defines the key for the vertical relative coordinate connection point
	 * of an edge with its target terminal. Value is "entryY".
	 */
	STYLE_ENTRY_Y: 'entryY',

	/**
	 * Variable: STYLE_ENTRY_PERIMETER
	 * 
	 * Defines if the perimeter should be used to find the exact entry point
	 * along the perimeter of the target. Possible values are 0 (false) and
	 * 1 (true). Default is 1 (true). Value is "entryPerimeter".
	 */
	STYLE_ENTRY_PERIMETER: 'entryPerimeter',

	/**
	 * Variable: STYLE_WHITE_SPACE
	 * 
	 * Defines the key for the white-space style. Possible values are 'nowrap'
	 * and 'wrap'. The default value is 'nowrap'. This value specifies how
	 * white-space inside a HTML vertex label should be handled. A value of
	 * 'nowrap' means the text will never wrap to the next line until a
	 * linefeed is encountered. A value of 'wrap' means text will wrap when
	 * necessary. This style is only used for HTML labels.
	 * See <mxGraph.isWrapping>. Value is "whiteSpace".
	 */
	STYLE_WHITE_SPACE: 'whiteSpace',

	/**
	 * Variable: STYLE_ROTATION
	 * 
	 * Defines the key for the rotation style. The type of the value is 
	 * numeric and the possible range is 0-360. Value is "rotation".
	 */
	STYLE_ROTATION: 'rotation',

	/**
	 * Variable: STYLE_FILLCOLOR
	 * 
	 * Defines the key for the fill color. Possible values are all HTML color
	 * names or HEX codes, as well as special keywords such as 'swimlane,
	 * 'inherit' or 'indicated' to use the color code of a related cell or the
	 * indicator shape. Value is "fillColor".
	 */
	STYLE_FILLCOLOR: 'fillColor',

	/**
	 * Variable: STYLE_POINTER_EVENTS
	 * 
	 * Specifies if pointer events should be fired on transparent backgrounds.
	 * This style is currently only supported in <mxRectangleShape>. Default
	 * is true. Value is "pointerEvents". This is typically set to
	 * false in groups where the transparent part should allow any underlying
	 * cells to be clickable.
	 */
	STYLE_POINTER_EVENTS: 'pointerEvents',

	/**
	 * Variable: STYLE_SWIMLANE_FILLCOLOR
	 * 
	 * Defines the key for the fill color of the swimlane background. Possible
	 * values are all HTML color names or HEX codes. Default is no background.
	 * Value is "swimlaneFillColor".
	 */
	STYLE_SWIMLANE_FILLCOLOR: 'swimlaneFillColor',

	/**
	 * Variable: STYLE_MARGIN
	 * 
	 * Defines the key for the margin between the ellipses in the double ellipse shape.
	 * Possible values are all positive numbers. Value is "margin".
	 */
	STYLE_MARGIN: 'margin',

	/**
	 * Variable: STYLE_GRADIENTCOLOR
	 * 
	 * Defines the key for the gradient color. Possible values are all HTML color
	 * names or HEX codes, as well as special keywords such as 'swimlane,
	 * 'inherit' or 'indicated' to use the color code of a related cell or the
	 * indicator shape. This is ignored if no fill color is defined. Value is
	 * "gradientColor".
	 */
	STYLE_GRADIENTCOLOR: 'gradientColor',

	/**
	 * Variable: STYLE_GRADIENT_DIRECTION
	 * 
	 * Defines the key for the gradient direction. Possible values are
	 * <DIRECTION_EAST>, <DIRECTION_WEST>, <DIRECTION_NORTH> and
	 * <DIRECTION_SOUTH>. Default is <DIRECTION_SOUTH>. Generally, and by
	 * default in mxGraph, gradient painting is done from the value of
	 * <STYLE_FILLCOLOR> to the value of <STYLE_GRADIENTCOLOR>. Taking the
	 * example of <DIRECTION_NORTH>, this means <STYLE_FILLCOLOR> color at the 
	 * bottom of paint pattern and <STYLE_GRADIENTCOLOR> at top, with a
	 * gradient in-between. Value is "gradientDirection".
	 */
	STYLE_GRADIENT_DIRECTION: 'gradientDirection',

	/**
	 * Variable: STYLE_STROKECOLOR
	 * 
	 * Defines the key for the strokeColor style. Possible values are all HTML
	 * color names or HEX codes, as well as special keywords such as 'swimlane,
	 * 'inherit', 'indicated' to use the color code of a related cell or the
	 * indicator shape or 'none' for no color. Value is "strokeColor".
	 */
	STYLE_STROKECOLOR: 'strokeColor',

	/**
	 * Variable: STYLE_SEPARATORCOLOR
	 * 
	 * Defines the key for the separatorColor style. Possible values are all
	 * HTML color names or HEX codes. This style is only used for
	 * <SHAPE_SWIMLANE> shapes. Value is "separatorColor".
	 */
	STYLE_SEPARATORCOLOR: 'separatorColor',

	/**
	 * Variable: STYLE_STROKEWIDTH
	 * 
	 * Defines the key for the strokeWidth style. The type of the value is 
	 * numeric and the possible range is any non-negative value larger or equal
	 * to 1. The value defines the stroke width in pixels. Note: To hide a
	 * stroke use strokeColor none. Value is "strokeWidth".
	 */
	STYLE_STROKEWIDTH: 'strokeWidth',

	/**
	 * Variable: STYLE_ALIGN
	 * 
	 * Defines the key for the align style. Possible values are <ALIGN_LEFT>,
	 * <ALIGN_CENTER> and <ALIGN_RIGHT>. This value defines how the lines of
	 * the label are horizontally aligned. <ALIGN_LEFT> mean label text lines
	 * are aligned to left of the label bounds, <ALIGN_RIGHT> to the right of
	 * the label bounds and <ALIGN_CENTER> means the center of the text lines
	 * are aligned in the center of the label bounds. Note this value doesn't
	 * affect the positioning of the overall label bounds relative to the
	 * vertex, to move the label bounds horizontally, use
	 * <STYLE_LABEL_POSITION>. Value is "align".
	 */
	STYLE_ALIGN: 'align',

	/**
	 * Variable: STYLE_VERTICAL_ALIGN
	 * 
	 * Defines the key for the verticalAlign style. Possible values are
	 * <ALIGN_TOP>, <ALIGN_MIDDLE> and <ALIGN_BOTTOM>. This value defines how
	 * the lines of the label are vertically aligned. <ALIGN_TOP> means the
	 * topmost label text line is aligned against the top of the label bounds,
	 * <ALIGN_BOTTOM> means the bottom-most label text line is aligned against
	 * the bottom of the label bounds and <ALIGN_MIDDLE> means there is equal
	 * spacing between the topmost text label line and the top of the label
	 * bounds and the bottom-most text label line and the bottom of the label
	 * bounds. Note this value doesn't affect the positioning of the overall
	 * label bounds relative to the vertex, to move the label bounds
	 * vertically, use <STYLE_VERTICAL_LABEL_POSITION>. Value is "verticalAlign".
	 */
	STYLE_VERTICAL_ALIGN: 'verticalAlign',

	/**
	 * Variable: STYLE_LABEL_WIDTH
	 * 
	 * Defines the key for the width of the label if the label position is not
	 * center. Value is "labelWidth".
	 */
	STYLE_LABEL_WIDTH: 'labelWidth',

	/**
	 * Variable: STYLE_LABEL_POSITION
	 * 
	 * Defines the key for the horizontal label position of vertices. Possible
	 * values are <ALIGN_LEFT>, <ALIGN_CENTER> and <ALIGN_RIGHT>. Default is
	 * <ALIGN_CENTER>. The label align defines the position of the label
	 * relative to the cell. <ALIGN_LEFT> means the entire label bounds is
	 * placed completely just to the left of the vertex, <ALIGN_RIGHT> means
	 * adjust to the right and <ALIGN_CENTER> means the label bounds are
	 * vertically aligned with the bounds of the vertex. Note this value
	 * doesn't affect the positioning of label within the label bounds, to move
	 * the label horizontally within the label bounds, use <STYLE_ALIGN>.
	 * Value is "labelPosition".
	 */
	STYLE_LABEL_POSITION: 'labelPosition',

	/**
	 * Variable: STYLE_VERTICAL_LABEL_POSITION
	 * 
	 * Defines the key for the vertical label position of vertices. Possible
	 * values are <ALIGN_TOP>, <ALIGN_BOTTOM> and <ALIGN_MIDDLE>. Default is
	 * <ALIGN_MIDDLE>. The label align defines the position of the label
	 * relative to the cell. <ALIGN_TOP> means the entire label bounds is
	 * placed completely just on the top of the vertex, <ALIGN_BOTTOM> means
	 * adjust on the bottom and <ALIGN_MIDDLE> means the label bounds are
	 * horizontally aligned with the bounds of the vertex. Note this value
	 * doesn't affect the positioning of label within the label bounds, to move
	 * the label vertically within the label bounds, use
	 * <STYLE_VERTICAL_ALIGN>. Value is "verticalLabelPosition".
	 */
	STYLE_VERTICAL_LABEL_POSITION: 'verticalLabelPosition',
	
	/**
	 * Variable: STYLE_IMAGE_ASPECT
	 * 
	 * Defines the key for the image aspect style. Possible values are 0 (do
	 * not preserve aspect) or 1 (keep aspect). This is only used in
	 * <mxImageShape>. Default is 1. Value is "imageAspect".
	 */
	STYLE_IMAGE_ASPECT: 'imageAspect',

	/**
	 * Variable: STYLE_IMAGE_ALIGN
	 * 
	 * Defines the key for the align style. Possible values are <ALIGN_LEFT>,
	 * <ALIGN_CENTER> and <ALIGN_RIGHT>. The value defines how any image in the
	 * vertex label is aligned horizontally within the label bounds of a
	 * <SHAPE_LABEL> shape. Value is "imageAlign".
	 */
	STYLE_IMAGE_ALIGN: 'imageAlign',

	/**
	 * Variable: STYLE_IMAGE_VERTICAL_ALIGN
	 * 
	 * Defines the key for the verticalAlign style. Possible values are
	 * <ALIGN_TOP>, <ALIGN_MIDDLE> and <ALIGN_BOTTOM>. The value defines how
	 * any image in the vertex label is aligned vertically within the label
	 * bounds of a <SHAPE_LABEL> shape. Value is "imageVerticalAlign".
	 */
	STYLE_IMAGE_VERTICAL_ALIGN: 'imageVerticalAlign',

	/**
	 * Variable: STYLE_GLASS
	 * 
	 * Defines the key for the glass style. Possible values are 0 (disabled) and
	 * 1(enabled). The default value is 0. This is used in <mxLabel>. Value is
	 * "glass".
	 */
	STYLE_GLASS: 'glass',

	/**
	 * Variable: STYLE_IMAGE
	 * 
	 * Defines the key for the image style. Possible values are any image URL,
	 * the type of the value is String. This is the path to the image that is
	 * to be displayed within the label of a vertex. Data URLs should use the
	 * following format: data:image/png,xyz where xyz is the base64 encoded
	 * data (without the "base64"-prefix). Note that Data URLs are only
	 * supported in modern browsers. Value is "image".
	 */
	STYLE_IMAGE: 'image',

	/**
	 * Variable: STYLE_IMAGE_WIDTH
	 * 
	 * Defines the key for the imageWidth style. The type of this value is
	 * int, the value is the image width in pixels and must be greater than 0.
	 * Value is "imageWidth".
	 */
	STYLE_IMAGE_WIDTH: 'imageWidth',

	/**
	 * Variable: STYLE_IMAGE_HEIGHT
	 * 
	 * Defines the key for the imageHeight style. The type of this value is
	 * int, the value is the image height in pixels and must be greater than 0.
	 * Value is "imageHeight".
	 */
	STYLE_IMAGE_HEIGHT: 'imageHeight',

	/**
	 * Variable: STYLE_IMAGE_BACKGROUND
	 * 
	 * Defines the key for the image background color. This style is only used
	 * in <mxImageShape>. Possible values are all HTML color names or HEX
	 * codes. Value is "imageBackground".
	 */
	STYLE_IMAGE_BACKGROUND: 'imageBackground',

	/**
	 * Variable: STYLE_IMAGE_BORDER
	 * 
	 * Defines the key for the image border color. This style is only used in
	 * <mxImageShape>. Possible values are all HTML color names or HEX codes.
	 * Value is "imageBorder".
	 */
	STYLE_IMAGE_BORDER: 'imageBorder',

	/**
	 * Variable: STYLE_FLIPH
	 * 
	 * Defines the key for the horizontal image flip. This style is only used
	 * in <mxImageShape>. Possible values are 0 and 1. Default is 0. Value is
	 * "flipH".
	 */
	STYLE_FLIPH: 'flipH',

	/**
	 * Variable: STYLE_FLIPV
	 * 
	 * Defines the key for the vertical flip. Possible values are 0 and 1.
	 * Default is 0. Value is "flipV".
	 */
	STYLE_FLIPV: 'flipV',

	/**
	 * Variable: STYLE_NOLABEL
	 * 
	 * Defines the key for the noLabel style. If this is true then no label is
	 * visible for a given cell. Possible values are true or false (1 or 0).
	 * Default is false. Value is "noLabel".
	 */
	STYLE_NOLABEL: 'noLabel',

	/**
	 * Variable: STYLE_NOEDGESTYLE
	 * 
	 * Defines the key for the noEdgeStyle style. If this is true then no edge
	 * style is applied for a given edge. Possible values are true or false
	 * (1 or 0). Default is false. Value is "noEdgeStyle".
	 */
	STYLE_NOEDGESTYLE: 'noEdgeStyle',

	/**
	 * Variable: STYLE_LABEL_BACKGROUNDCOLOR
	 * 
	 * Defines the key for the label background color. Possible values are all
	 * HTML color names or HEX codes. Value is "labelBackgroundColor".
	 */
	STYLE_LABEL_BACKGROUNDCOLOR: 'labelBackgroundColor',

	/**
	 * Variable: STYLE_LABEL_BORDERCOLOR
	 * 
	 * Defines the key for the label border color. Possible values are all
	 * HTML color names or HEX codes. Value is "labelBorderColor".
	 */
	STYLE_LABEL_BORDERCOLOR: 'labelBorderColor',

	/**
	 * Variable: STYLE_LABEL_PADDING
	 * 
	 * Defines the key for the label padding, ie. the space between the label
	 * border and the label. Value is "labelPadding".
	 */
	STYLE_LABEL_PADDING: 'labelPadding',

	/**
	 * Variable: STYLE_INDICATOR_SHAPE
	 * 
	 * Defines the key for the indicator shape used within an <mxLabel>.
	 * Possible values are all SHAPE_* constants or the names of any new
	 * shapes. The indicatorShape has precedence over the indicatorImage.
	 * Value is "indicatorShape".
	 */
	STYLE_INDICATOR_SHAPE: 'indicatorShape',

	/**
	 * Variable: STYLE_INDICATOR_IMAGE
	 * 
	 * Defines the key for the indicator image used within an <mxLabel>.
	 * Possible values are all image URLs. The indicatorShape has
	 * precedence over the indicatorImage. Value is "indicatorImage".
	 */
	STYLE_INDICATOR_IMAGE: 'indicatorImage',

	/**
	 * Variable: STYLE_INDICATOR_COLOR
	 * 
	 * Defines the key for the indicatorColor style. Possible values are all
	 * HTML color names or HEX codes, as well as the special 'swimlane' keyword
	 * to refer to the color of the parent swimlane if one exists. Value is
	 * "indicatorColor".
	 */
	STYLE_INDICATOR_COLOR: 'indicatorColor',

	/**
	 * Variable: STYLE_INDICATOR_STROKECOLOR
	 * 
	 * Defines the key for the indicator stroke color in <mxLabel>.
	 * Possible values are all color codes. Value is "indicatorStrokeColor".
	 */
	STYLE_INDICATOR_STROKECOLOR: 'indicatorStrokeColor',

	/**
	 * Variable: STYLE_INDICATOR_GRADIENTCOLOR
	 * 
	 * Defines the key for the indicatorGradientColor style. Possible values
	 * are all HTML color names or HEX codes. This style is only supported in
	 * <SHAPE_LABEL> shapes. Value is "indicatorGradientColor".
	 */
	STYLE_INDICATOR_GRADIENTCOLOR: 'indicatorGradientColor',

	/**
	 * Variable: STYLE_INDICATOR_SPACING
	 * 
	 * The defines the key for the spacing between the label and the
	 * indicator in <mxLabel>. Possible values are in pixels. Value is
	 * "indicatorSpacing".
	 */
	STYLE_INDICATOR_SPACING: 'indicatorSpacing',

	/**
	 * Variable: STYLE_INDICATOR_WIDTH
	 * 
	 * Defines the key for the indicator width. Possible values start at 0 (in
	 * pixels). Value is "indicatorWidth".
	 */
	STYLE_INDICATOR_WIDTH: 'indicatorWidth',

	/**
	 * Variable: STYLE_INDICATOR_HEIGHT
	 * 
	 * Defines the key for the indicator height. Possible values start at 0 (in
	 * pixels). Value is "indicatorHeight".
	 */
	STYLE_INDICATOR_HEIGHT: 'indicatorHeight',

	/**
	 * Variable: STYLE_INDICATOR_DIRECTION
	 * 
	 * Defines the key for the indicatorDirection style. The direction style is
	 * used to specify the direction of certain shapes (eg. <mxTriangle>).
	 * Possible values are <DIRECTION_EAST> (default), <DIRECTION_WEST>,
	 * <DIRECTION_NORTH> and <DIRECTION_SOUTH>. Value is "indicatorDirection".
	 */
	STYLE_INDICATOR_DIRECTION: 'indicatorDirection',

	/**
	 * Variable: STYLE_SHADOW
	 * 
	 * Defines the key for the shadow style. The type of the value is Boolean.
	 * Value is "shadow".
	 */
	STYLE_SHADOW: 'shadow',
	
	/**
	 * Variable: STYLE_SEGMENT
	 * 
	 * Defines the key for the segment style. The type of this value is float
	 * and the value represents the size of the horizontal segment of the
	 * entity relation style. Default is ENTITY_SEGMENT. Value is "segment".
	 */
	STYLE_SEGMENT: 'segment',
	
	/**
	 * Variable: STYLE_ENDARROW
	 *
	 * Defines the key for the end arrow marker. Possible values are all
	 * constants with an ARROW-prefix. This is only used in <mxConnector>.
	 * Value is "endArrow".
	 *
	 * Example:
	 * (code)
	 * style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_CLASSIC;
	 * (end)
	 */
	STYLE_ENDARROW: 'endArrow',

	/**
	 * Variable: STYLE_STARTARROW
	 * 
	 * Defines the key for the start arrow marker. Possible values are all
	 * constants with an ARROW-prefix. This is only used in <mxConnector>.
	 * See <STYLE_ENDARROW>. Value is "startArrow".
	 */
	STYLE_STARTARROW: 'startArrow',

	/**
	 * Variable: STYLE_ENDSIZE
	 * 
	 * Defines the key for the endSize style. The type of this value is numeric
	 * and the value represents the size of the end marker in pixels. Value is
	 * "endSize".
	 */
	STYLE_ENDSIZE: 'endSize',

	/**
	 * Variable: STYLE_STARTSIZE
	 * 
	 * Defines the key for the startSize style. The type of this value is
	 * numeric and the value represents the size of the start marker or the
	 * size of the swimlane title region depending on the shape it is used for.
	 * Value is "startSize".
	 */
	STYLE_STARTSIZE: 'startSize',

	/**
	 * Variable: STYLE_SWIMLANE_LINE
	 * 
	 * Defines the key for the swimlaneLine style. This style specifies whether
	 * the line between the title regio of a swimlane should be visible. Use 0
	 * for hidden or 1 (default) for visible. Value is "swimlaneLine".
	 */
	STYLE_SWIMLANE_LINE: 'swimlaneLine',

	/**
	 * Variable: STYLE_ENDFILL
	 * 
	 * Defines the key for the endFill style. Use 0 for no fill or 1 (default)
	 * for fill. (This style is only exported via <mxImageExport>.) Value is
	 * "endFill".
	 */
	STYLE_ENDFILL: 'endFill',

	/**
	 * Variable: STYLE_STARTFILL
	 * 
	 * Defines the key for the startFill style. Use 0 for no fill or 1 (default)
	 * for fill. (This style is only exported via <mxImageExport>.) Value is
	 * "startFill".
	 */
	STYLE_STARTFILL: 'startFill',

	/**
	 * Variable: STYLE_DASHED
	 * 
	 * Defines the key for the dashed style. Use 0 (default) for non-dashed or 1
	 * for dashed. Value is "dashed".
	 */
	STYLE_DASHED: 'dashed',

	/**
	 * Defines the key for the dashed pattern style in SVG and image exports.
	 * The type of this value is a space separated list of numbers that specify
	 * a custom-defined dash pattern. Dash styles are defined in terms of the
	 * length of the dash (the drawn part of the stroke) and the length of the
	 * space between the dashes. The lengths are relative to the line width: a
	 * length of "1" is equal to the line width. VML ignores this style and
	 * uses dashStyle instead as defined in the VML specification. This style
	 * is only used in the <mxConnector> shape. Value is "dashPattern".
	 */
	STYLE_DASH_PATTERN: 'dashPattern',

	/**
	 * Variable: STYLE_FIX_DASH
	 * 
	 * Defines the key for the fixDash style. Use 0 (default) for dash patterns
	 * that depend on the linewidth and 1 for dash patterns that ignore the
	 * line width. Value is "fixDash".
	 */
	STYLE_FIX_DASH: 'fixDash',

	/**
	 * Variable: STYLE_ROUNDED
	 * 
	 * Defines the key for the rounded style. The type of this value is
	 * Boolean. For edges this determines whether or not joins between edges
	 * segments are smoothed to a rounded finish. For vertices that have the
	 * rectangle shape, this determines whether or not the rectangle is
	 * rounded. Use 0 (default) for non-rounded or 1 for rounded. Value is
	 * "rounded".
	 */
	STYLE_ROUNDED: 'rounded',

	/**
	 * Variable: STYLE_CURVED
	 * 
	 * Defines the key for the curved style. The type of this value is
	 * Boolean. It is only applicable for connector shapes. Use 0 (default)
	 * for non-curved or 1 for curved. Value is "curved".
	 */
	STYLE_CURVED: 'curved',

	/**
	 * Variable: STYLE_ARCSIZE
	 * 
	 * Defines the rounding factor for a rounded rectangle in percent (without
	 * the percent sign). Possible values are between 0 and 100. If this value
	 * is not specified then RECTANGLE_ROUNDING_FACTOR * 100 is used. For
	 * edges, this defines the absolute size of rounded corners in pixels. If
	 * this values is not specified then LINE_ARCSIZE is used.
	 * (This style is only exported via <mxImageExport>.) Value is "arcSize".
	 */
	STYLE_ARCSIZE: 'arcSize',

	/**
	 * Variable: STYLE_ABSOLUTE_ARCSIZE
	 * 
	 * Defines the key for the absolute arc size style. This specifies if
	 * arcSize for rectangles is abolute or relative. Possible values are 1
	 * and 0 (default). Value is "absoluteArcSize".
	 */
	STYLE_ABSOLUTE_ARCSIZE: 'absoluteArcSize',

	/**
	 * Variable: STYLE_SOURCE_PERIMETER_SPACING
	 * 
	 * Defines the key for the source perimeter spacing. The type of this value
	 * is numeric. This is the distance between the source connection point of
	 * an edge and the perimeter of the source vertex in pixels. This style
	 * only applies to edges. Value is "sourcePerimeterSpacing".
	 */
	STYLE_SOURCE_PERIMETER_SPACING: 'sourcePerimeterSpacing',

	/**
	 * Variable: STYLE_TARGET_PERIMETER_SPACING
	 * 
	 * Defines the key for the target perimeter spacing. The type of this value
	 * is numeric. This is the distance between the target connection point of
	 * an edge and the perimeter of the target vertex in pixels. This style
	 * only applies to edges. Value is "targetPerimeterSpacing".
	 */
	STYLE_TARGET_PERIMETER_SPACING: 'targetPerimeterSpacing',

	/**
	 * Variable: STYLE_PERIMETER_SPACING
	 * 
	 * Defines the key for the perimeter spacing. This is the distance between
	 * the connection point and the perimeter in pixels. When used in a vertex
	 * style, this applies to all incoming edges to floating ports (edges that
	 * terminate on the perimeter of the vertex). When used in an edge style,
	 * this spacing applies to the source and target separately, if they
	 * terminate in floating ports (on the perimeter of the vertex). Value is
	 * "perimeterSpacing".
	 */
	STYLE_PERIMETER_SPACING: 'perimeterSpacing',

	/**
	 * Variable: STYLE_SPACING
	 * 
	 * Defines the key for the spacing. The value represents the spacing, in
	 * pixels, added to each side of a label in a vertex (style applies to
	 * vertices only). Value is "spacing".
	 */
	STYLE_SPACING: 'spacing',

	/**
	 * Variable: STYLE_SPACING_TOP
	 * 
	 * Defines the key for the spacingTop style. The value represents the
	 * spacing, in pixels, added to the top side of a label in a vertex (style
	 * applies to vertices only). Value is "spacingTop".
	 */
	STYLE_SPACING_TOP: 'spacingTop',

	/**
	 * Variable: STYLE_SPACING_LEFT
	 * 
	 * Defines the key for the spacingLeft style. The value represents the
	 * spacing, in pixels, added to the left side of a label in a vertex (style
	 * applies to vertices only). Value is "spacingLeft".
	 */
	STYLE_SPACING_LEFT: 'spacingLeft',

	/**
	 * Variable: STYLE_SPACING_BOTTOM
	 * 
	 * Defines the key for the spacingBottom style The value represents the
	 * spacing, in pixels, added to the bottom side of a label in a vertex
	 * (style applies to vertices only). Value is "spacingBottom".
	 */
	STYLE_SPACING_BOTTOM: 'spacingBottom',

	/**
	 * Variable: STYLE_SPACING_RIGHT
	 * 
	 * Defines the key for the spacingRight style The value represents the
	 * spacing, in pixels, added to the right side of a label in a vertex (style
	 * applies to vertices only). Value is "spacingRight".
	 */
	STYLE_SPACING_RIGHT: 'spacingRight',

	/**
	 * Variable: STYLE_HORIZONTAL
	 * 
	 * Defines the key for the horizontal style. Possible values are
	 * true or false. This value only applies to vertices. If the <STYLE_SHAPE>
	 * is "SHAPE_SWIMLANE" a value of false indicates that the
	 * swimlane should be drawn vertically, true indicates to draw it
	 * horizontally. If the shape style does not indicate that this vertex is a
	 * swimlane, this value affects only whether the label is drawn
	 * horizontally or vertically. Value is "horizontal".
	 */
	STYLE_HORIZONTAL: 'horizontal',

	/**
	 * Variable: STYLE_DIRECTION
	 * 
	 * Defines the key for the direction style. The direction style is used
	 * to specify the direction of certain shapes (eg. <mxTriangle>).
	 * Possible values are <DIRECTION_EAST> (default), <DIRECTION_WEST>,
	 * <DIRECTION_NORTH> and <DIRECTION_SOUTH>. Value is "direction".
	 */
	STYLE_DIRECTION: 'direction',

	/**
	 * Variable: STYLE_ELBOW
	 * 
	 * Defines the key for the elbow style. Possible values are
	 * <ELBOW_HORIZONTAL> and <ELBOW_VERTICAL>. Default is <ELBOW_HORIZONTAL>.
	 * This defines how the three segment orthogonal edge style leaves its
	 * terminal vertices. The vertical style leaves the terminal vertices at
	 * the top and bottom sides. Value is "elbow".
	 */
	STYLE_ELBOW: 'elbow',

	/**
	 * Variable: STYLE_FONTCOLOR
	 * 
	 * Defines the key for the fontColor style. Possible values are all HTML
	 * color names or HEX codes. Value is "fontColor".
	 */
	STYLE_FONTCOLOR: 'fontColor',

	/**
	 * Variable: STYLE_FONTFAMILY
	 * 
	 * Defines the key for the fontFamily style. Possible values are names such
	 * as Arial; Dialog; Verdana; Times New Roman. The value is of type String.
	 * Value is fontFamily.
	 */
	STYLE_FONTFAMILY: 'fontFamily',

	/**
	 * Variable: STYLE_FONTSIZE
	 * 
	 * Defines the key for the fontSize style (in px). The type of the value
	 * is int. Value is "fontSize".
	 */
	STYLE_FONTSIZE: 'fontSize',

	/**
	 * Variable: STYLE_FONTSTYLE
	 * 
	 * Defines the key for the fontStyle style. Values may be any logical AND
	 * (sum) of <FONT_BOLD>, <FONT_ITALIC> and <FONT_UNDERLINE>.
	 * The type of the value is int. Value is "fontStyle".
	 */
	STYLE_FONTSTYLE: 'fontStyle',
	
	/**
	 * Variable: STYLE_ASPECT
	 * 
	 * Defines the key for the aspect style. Possible values are empty or fixed.
	 * If fixed is used then the aspect ratio of the cell will be maintained
	 * when resizing. Default is empty. Value is "aspect".
	 */
	STYLE_ASPECT: 'aspect',

	/**
	 * Variable: STYLE_AUTOSIZE
	 * 
	 * Defines the key for the autosize style. This specifies if a cell should be
	 * resized automatically if the value has changed. Possible values are 0 or 1.
	 * Default is 0. See <mxGraph.isAutoSizeCell>. This is normally combined with
	 * <STYLE_RESIZABLE> to disable manual sizing. Value is "autosize".
	 */
	STYLE_AUTOSIZE: 'autosize',

	/**
	 * Variable: STYLE_FOLDABLE
	 * 
	 * Defines the key for the foldable style. This specifies if a cell is foldable
	 * using a folding icon. Possible values are 0 or 1. Default is 1. See
	 * <mxGraph.isCellFoldable>. Value is "foldable".
	 */
	STYLE_FOLDABLE: 'foldable',

	/**
	 * Variable: STYLE_EDITABLE
	 * 
	 * Defines the key for the editable style. This specifies if the value of
	 * a cell can be edited using the in-place editor. Possible values are 0 or
	 * 1. Default is 1. See <mxGraph.isCellEditable>. Value is "editable".
	 */
	STYLE_EDITABLE: 'editable',

	/**
	 * Variable: STYLE_BENDABLE
	 * 
	 * Defines the key for the bendable style. This specifies if the control
	 * points of an edge can be moved. Possible values are 0 or 1. Default is
	 * 1. See <mxGraph.isCellBendable>. Value is "bendable".
	 */
	STYLE_BENDABLE: 'bendable',

	/**
	 * Variable: STYLE_MOVABLE
	 * 
	 * Defines the key for the movable style. This specifies if a cell can
	 * be moved. Possible values are 0 or 1. Default is 1. See
	 * <mxGraph.isCellMovable>. Value is "movable".
	 */
	STYLE_MOVABLE: 'movable',

	/**
	 * Variable: STYLE_RESIZABLE
	 * 
	 * Defines the key for the resizable style. This specifies if a cell can
	 * be resized. Possible values are 0 or 1. Default is 1. See
	 * <mxGraph.isCellResizable>. Value is "resizable".
	 */
	STYLE_RESIZABLE: 'resizable',

	/**
	 * Variable: STYLE_RESIZE_WIDTH
	 * 
	 * Defines the key for the resizeWidth style. This specifies if a cell's
	 * width is resized if the parent is resized. If this is 1 then the width
	 * will be resized even if the cell's geometry is relative. If this is 0
	 * then the cell's width will not be resized. Default is not defined. Value
	 * is "resizeWidth".
	 */
	STYLE_RESIZE_WIDTH: 'resizeWidth',

	/**
	 * Variable: STYLE_RESIZE_WIDTH
	 * 
	 * Defines the key for the resizeHeight style. This specifies if a cell's
	 * height if resize if the parent is resized. If this is 1 then the height
	 * will be resized even if the cell's geometry is relative. If this is 0
	 * then the cell's height will not be resized. Default is not defined. Value
	 * is "resizeHeight".
	 */
	STYLE_RESIZE_HEIGHT: 'resizeHeight',

	/**
	 * Variable: STYLE_ROTATABLE
	 * 
	 * Defines the key for the rotatable style. This specifies if a cell can
	 * be rotated. Possible values are 0 or 1. Default is 1. See
	 * <mxGraph.isCellRotatable>. Value is "rotatable".
	 */
	STYLE_ROTATABLE: 'rotatable',

	/**
	 * Variable: STYLE_CLONEABLE
	 * 
	 * Defines the key for the cloneable style. This specifies if a cell can
	 * be cloned. Possible values are 0 or 1. Default is 1. See
	 * <mxGraph.isCellCloneable>. Value is "cloneable".
	 */
	STYLE_CLONEABLE: 'cloneable',

	/**
	 * Variable: STYLE_DELETABLE
	 * 
	 * Defines the key for the deletable style. This specifies if a cell can be
	 * deleted. Possible values are 0 or 1. Default is 1. See
	 * <mxGraph.isCellDeletable>. Value is "deletable".
	 */
	STYLE_DELETABLE: 'deletable',

	/**
	 * Variable: STYLE_SHAPE
	 * 
	 * Defines the key for the shape. Possible values are all constants with
	 * a SHAPE-prefix or any newly defined shape names. Value is "shape".
	 */
	STYLE_SHAPE: 'shape',

	/**
	 * Variable: STYLE_EDGE
	 * 
	 * Defines the key for the edge style. Possible values are the functions
	 * defined in <mxEdgeStyle>. Value is "edgeStyle".
	 */
	STYLE_EDGE: 'edgeStyle',

	/**
	 * Variable: STYLE_JETTY_SIZE
	 * 
	 * Defines the key for the jetty size in <mxEdgeStyle.OrthConnector>.
	 * Default is 10. Possible values are all numeric values or "auto".
	 * Value is "jettySize".
	 */
	STYLE_JETTY_SIZE: 'jettySize',

	/**
	 * Variable: STYLE_SOURCE_JETTY_SIZE
	 * 
	 * Defines the key for the jetty size in <mxEdgeStyle.OrthConnector>.
	 * Default is 10. Possible values are numeric values or "auto". This has
	 * precedence over <STYLE_JETTY_SIZE>. Value is "sourceJettySize".
	 */
	STYLE_SOURCE_JETTY_SIZE: 'sourceJettySize',

	/**
	 * Variable: targetJettySize
	 * 
	 * Defines the key for the jetty size in <mxEdgeStyle.OrthConnector>.
	 * Default is 10. Possible values are numeric values or "auto". This has
	 * precedence over <STYLE_JETTY_SIZE>. Value is "targetJettySize".
	 */
	STYLE_TARGET_JETTY_SIZE: 'targetJettySize',

	/**
	 * Variable: STYLE_LOOP
	 * 
	 * Defines the key for the loop style. Possible values are the functions
	 * defined in <mxEdgeStyle>. Value is "loopStyle".
	 */
	STYLE_LOOP: 'loopStyle',

	/**
	 * Variable: STYLE_ORTHOGONAL_LOOP
	 * 
	 * Defines the key for the orthogonal loop style. Possible values are 0 and
	 * 1. Default is 0. Value is "orthogonalLoop". Use this style to specify
	 * if loops should be routed using an orthogonal router. Currently, this
	 * uses <mxEdgeStyle.OrthConnector> but will be replaced with a dedicated
	 * orthogonal loop router in later releases.
	 */
	STYLE_ORTHOGONAL_LOOP: 'orthogonalLoop',

	/**
	 * Variable: STYLE_ROUTING_CENTER_X
	 * 
	 * Defines the key for the horizontal routing center. Possible values are
	 * between -0.5 and 0.5. This is the relative offset from the center used
	 * for connecting edges. The type of this value is numeric. Value is
	 * "routingCenterX".
	 */
	STYLE_ROUTING_CENTER_X: 'routingCenterX',

	/**
	 * Variable: STYLE_ROUTING_CENTER_Y
	 * 
	 * Defines the key for the vertical routing center. Possible values are
	 * between -0.5 and 0.5. This is the relative offset from the center used
	 * for connecting edges. The type of this value is numeric. Value is
	 * "routingCenterY".
	 */
	STYLE_ROUTING_CENTER_Y: 'routingCenterY',

	/**
	 * Variable: FONT_BOLD
	 * 
	 * Constant for bold fonts. Default is 1.
	 */
	FONT_BOLD: 1,

	/**
	 * Variable: FONT_ITALIC
	 * 
	 * Constant for italic fonts. Default is 2.
	 */
	FONT_ITALIC: 2,

	/**
	 * Variable: FONT_UNDERLINE
	 * 
	 * Constant for underlined fonts. Default is 4.
	 */
	FONT_UNDERLINE: 4,

	/**
	 * Variable: SHAPE_RECTANGLE
	 * 
	 * Name under which <mxRectangleShape> is registered in <mxCellRenderer>.
	 * Default is rectangle.
	 */
	SHAPE_RECTANGLE: 'rectangle',

	/**
	 * Variable: SHAPE_ELLIPSE
	 * 
	 * Name under which <mxEllipse> is registered in <mxCellRenderer>.
	 * Default is ellipse.
	 */
	SHAPE_ELLIPSE: 'ellipse',

	/**
	 * Variable: SHAPE_DOUBLE_ELLIPSE
	 * 
	 * Name under which <mxDoubleEllipse> is registered in <mxCellRenderer>.
	 * Default is doubleEllipse.
	 */
	SHAPE_DOUBLE_ELLIPSE: 'doubleEllipse',

	/**
	 * Variable: SHAPE_RHOMBUS
	 * 
	 * Name under which <mxRhombus> is registered in <mxCellRenderer>.
	 * Default is rhombus.
	 */
	SHAPE_RHOMBUS: 'rhombus',

	/**
	 * Variable: SHAPE_LINE
	 * 
	 * Name under which <mxLine> is registered in <mxCellRenderer>.
	 * Default is line.
	 */
	SHAPE_LINE: 'line',

	/**
	 * Variable: SHAPE_IMAGE
	 * 
	 * Name under which <mxImageShape> is registered in <mxCellRenderer>.
	 * Default is image.
	 */
	SHAPE_IMAGE: 'image',
	
	/**
	 * Variable: SHAPE_ARROW
	 * 
	 * Name under which <mxArrow> is registered in <mxCellRenderer>.
	 * Default is arrow.
	 */
	SHAPE_ARROW: 'arrow',
	
	/**
	 * Variable: SHAPE_ARROW_CONNECTOR
	 * 
	 * Name under which <mxArrowConnector> is registered in <mxCellRenderer>.
	 * Default is arrowConnector.
	 */
	SHAPE_ARROW_CONNECTOR: 'arrowConnector',
	
	/**
	 * Variable: SHAPE_LABEL
	 * 
	 * Name under which <mxLabel> is registered in <mxCellRenderer>.
	 * Default is label.
	 */
	SHAPE_LABEL: 'label',
	
	/**
	 * Variable: SHAPE_CYLINDER
	 * 
	 * Name under which <mxCylinder> is registered in <mxCellRenderer>.
	 * Default is cylinder.
	 */
	SHAPE_CYLINDER: 'cylinder',
	
	/**
	 * Variable: SHAPE_SWIMLANE
	 * 
	 * Name under which <mxSwimlane> is registered in <mxCellRenderer>.
	 * Default is swimlane.
	 */
	SHAPE_SWIMLANE: 'swimlane',
		
	/**
	 * Variable: SHAPE_CONNECTOR
	 * 
	 * Name under which <mxConnector> is registered in <mxCellRenderer>.
	 * Default is connector.
	 */
	SHAPE_CONNECTOR: 'connector',

	/**
	 * Variable: SHAPE_ACTOR
	 * 
	 * Name under which <mxActor> is registered in <mxCellRenderer>.
	 * Default is actor.
	 */
	SHAPE_ACTOR: 'actor',
		
	/**
	 * Variable: SHAPE_CLOUD
	 * 
	 * Name under which <mxCloud> is registered in <mxCellRenderer>.
	 * Default is cloud.
	 */
	SHAPE_CLOUD: 'cloud',
		
	/**
	 * Variable: SHAPE_TRIANGLE
	 * 
	 * Name under which <mxTriangle> is registered in <mxCellRenderer>.
	 * Default is triangle.
	 */
	SHAPE_TRIANGLE: 'triangle',
		
	/**
	 * Variable: SHAPE_HEXAGON
	 * 
	 * Name under which <mxHexagon> is registered in <mxCellRenderer>.
	 * Default is hexagon.
	 */
	SHAPE_HEXAGON: 'hexagon',

	/**
	 * Variable: ARROW_CLASSIC
	 * 
	 * Constant for classic arrow markers.
	 */
	ARROW_CLASSIC: 'classic',

	/**
	 * Variable: ARROW_CLASSIC_THIN
	 * 
	 * Constant for thin classic arrow markers.
	 */
	ARROW_CLASSIC_THIN: 'classicThin',

	/**
	 * Variable: ARROW_BLOCK
	 * 
	 * Constant for block arrow markers.
	 */
	ARROW_BLOCK: 'block',

	/**
	 * Variable: ARROW_BLOCK_THIN
	 * 
	 * Constant for thin block arrow markers.
	 */
	ARROW_BLOCK_THIN: 'blockThin',

	/**
	 * Variable: ARROW_OPEN
	 * 
	 * Constant for open arrow markers.
	 */
	ARROW_OPEN: 'open',

	/**
	 * Variable: ARROW_OPEN_THIN
	 * 
	 * Constant for thin open arrow markers.
	 */
	ARROW_OPEN_THIN: 'openThin',

	/**
	 * Variable: ARROW_OVAL
	 * 
	 * Constant for oval arrow markers.
	 */
	ARROW_OVAL: 'oval',

	/**
	 * Variable: ARROW_DIAMOND
	 * 
	 * Constant for diamond arrow markers.
	 */
	ARROW_DIAMOND: 'diamond',

	/**
	 * Variable: ARROW_DIAMOND_THIN
	 * 
	 * Constant for thin diamond arrow markers.
	 */
	ARROW_DIAMOND_THIN: 'diamondThin',

	/**
	 * Variable: ALIGN_LEFT
	 * 
	 * Constant for left horizontal alignment. Default is left.
	 */
	ALIGN_LEFT: 'left',

	/**
	 * Variable: ALIGN_CENTER
	 * 
	 * Constant for center horizontal alignment. Default is center.
	 */
	ALIGN_CENTER: 'center',

	/**
	 * Variable: ALIGN_RIGHT
	 * 
	 * Constant for right horizontal alignment. Default is right.
	 */
	ALIGN_RIGHT: 'right',

	/**
	 * Variable: ALIGN_TOP
	 * 
	 * Constant for top vertical alignment. Default is top.
	 */
	ALIGN_TOP: 'top',

	/**
	 * Variable: ALIGN_MIDDLE
	 * 
	 * Constant for middle vertical alignment. Default is middle.
	 */
	ALIGN_MIDDLE: 'middle',

	/**
	 * Variable: ALIGN_BOTTOM
	 * 
	 * Constant for bottom vertical alignment. Default is bottom.
	 */
	ALIGN_BOTTOM: 'bottom',

	/**
	 * Variable: DIRECTION_NORTH
	 * 
	 * Constant for direction north. Default is north.
	 */
	DIRECTION_NORTH: 'north',

	/**
	 * Variable: DIRECTION_SOUTH
	 * 
	 * Constant for direction south. Default is south.
	 */
	DIRECTION_SOUTH: 'south',

	/**
	 * Variable: DIRECTION_EAST
	 * 
	 * Constant for direction east. Default is east.
	 */
	DIRECTION_EAST: 'east',

	/**
	 * Variable: DIRECTION_WEST
	 * 
	 * Constant for direction west. Default is west.
	 */
	DIRECTION_WEST: 'west',

	/**
	 * Variable: TEXT_DIRECTION_DEFAULT
	 * 
	 * Constant for text direction default. Default is an empty string. Use
	 * this value to use the default text direction of the operating system. 
	 */
	TEXT_DIRECTION_DEFAULT: '',

	/**
	 * Variable: TEXT_DIRECTION_AUTO
	 * 
	 * Constant for text direction automatic. Default is auto. Use this value
	 * to find the direction for a given text with <mxText.getAutoDirection>. 
	 */
	TEXT_DIRECTION_AUTO: 'auto',

	/**
	 * Variable: TEXT_DIRECTION_LTR
	 * 
	 * Constant for text direction left to right. Default is ltr. Use this
	 * value for left to right text direction.
	 */
	TEXT_DIRECTION_LTR: 'ltr',

	/**
	 * Variable: TEXT_DIRECTION_RTL
	 * 
	 * Constant for text direction right to left. Default is rtl. Use this
	 * value for right to left text direction.
	 */
	TEXT_DIRECTION_RTL: 'rtl',

	/**
	 * Variable: DIRECTION_MASK_NONE
	 * 
	 * Constant for no direction.
	 */
	DIRECTION_MASK_NONE: 0,

	/**
	 * Variable: DIRECTION_MASK_WEST
	 * 
	 * Bitwise mask for west direction.
	 */
	DIRECTION_MASK_WEST: 1,
	
	/**
	 * Variable: DIRECTION_MASK_NORTH
	 * 
	 * Bitwise mask for north direction.
	 */
	DIRECTION_MASK_NORTH: 2,

	/**
	 * Variable: DIRECTION_MASK_SOUTH
	 * 
	 * Bitwise mask for south direction.
	 */
	DIRECTION_MASK_SOUTH: 4,

	/**
	 * Variable: DIRECTION_MASK_EAST
	 * 
	 * Bitwise mask for east direction.
	 */
	DIRECTION_MASK_EAST: 8,
	
	/**
	 * Variable: DIRECTION_MASK_ALL
	 * 
	 * Bitwise mask for all directions.
	 */
	DIRECTION_MASK_ALL: 15,

	/**
	 * Variable: ELBOW_VERTICAL
	 * 
	 * Constant for elbow vertical. Default is horizontal.
	 */
	ELBOW_VERTICAL: 'vertical',

	/**
	 * Variable: ELBOW_HORIZONTAL
	 * 
	 * Constant for elbow horizontal. Default is horizontal.
	 */
	ELBOW_HORIZONTAL: 'horizontal',

	/**
	 * Variable: EDGESTYLE_ELBOW
	 * 
	 * Name of the elbow edge style. Can be used as a string value
	 * for the STYLE_EDGE style.
	 */
	EDGESTYLE_ELBOW: 'elbowEdgeStyle',

	/**
	 * Variable: EDGESTYLE_ENTITY_RELATION
	 * 
	 * Name of the entity relation edge style. Can be used as a string value
	 * for the STYLE_EDGE style.
	 */
	EDGESTYLE_ENTITY_RELATION: 'entityRelationEdgeStyle',

	/**
	 * Variable: EDGESTYLE_LOOP
	 * 
	 * Name of the loop edge style. Can be used as a string value
	 * for the STYLE_EDGE style.
	 */
	EDGESTYLE_LOOP: 'loopEdgeStyle',

	/**
	 * Variable: EDGESTYLE_SIDETOSIDE
	 * 
	 * Name of the side to side edge style. Can be used as a string value
	 * for the STYLE_EDGE style.
	 */
	EDGESTYLE_SIDETOSIDE: 'sideToSideEdgeStyle',

	/**
	 * Variable: EDGESTYLE_TOPTOBOTTOM
	 * 
	 * Name of the top to bottom edge style. Can be used as a string value
	 * for the STYLE_EDGE style.
	 */
	EDGESTYLE_TOPTOBOTTOM: 'topToBottomEdgeStyle',

	/**
	 * Variable: EDGESTYLE_ORTHOGONAL
	 * 
	 * Name of the generic orthogonal edge style. Can be used as a string value
	 * for the STYLE_EDGE style.
	 */
	EDGESTYLE_ORTHOGONAL: 'orthogonalEdgeStyle',

	/**
	 * Variable: EDGESTYLE_SEGMENT
	 * 
	 * Name of the generic segment edge style. Can be used as a string value
	 * for the STYLE_EDGE style.
	 */
	EDGESTYLE_SEGMENT: 'segmentEdgeStyle',
 
	/**
	 * Variable: PERIMETER_ELLIPSE
	 * 
	 * Name of the ellipse perimeter. Can be used as a string value
	 * for the STYLE_PERIMETER style.
	 */
	PERIMETER_ELLIPSE: 'ellipsePerimeter',

	/**
	 * Variable: PERIMETER_RECTANGLE
	 *
	 * Name of the rectangle perimeter. Can be used as a string value
	 * for the STYLE_PERIMETER style.
	 */
	PERIMETER_RECTANGLE: 'rectanglePerimeter',

	/**
	 * Variable: PERIMETER_RHOMBUS
	 * 
	 * Name of the rhombus perimeter. Can be used as a string value
	 * for the STYLE_PERIMETER style.
	 */
	PERIMETER_RHOMBUS: 'rhombusPerimeter',

	/**
	 * Variable: PERIMETER_HEXAGON
	 * 
	 * Name of the hexagon perimeter. Can be used as a string value 
	 * for the STYLE_PERIMETER style.
	 */
	PERIMETER_HEXAGON: 'hexagonPerimeter',

	/**
	 * Variable: PERIMETER_TRIANGLE
	 * 
	 * Name of the triangle perimeter. Can be used as a string value
	 * for the STYLE_PERIMETER style.
	 */
	PERIMETER_TRIANGLE: 'trianglePerimeter'

};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxEventObject
 * 
 * The mxEventObject is a wrapper for all properties of a single event.
 * Additionally, it also offers functions to consume the event and check if it
 * was consumed as follows:
 * 
 * (code)
 * evt.consume();
 * INV: evt.isConsumed() == true
 * (end)
 * 
 * Constructor: mxEventObject
 *
 * Constructs a new event object with the specified name. An optional
 * sequence of key, value pairs can be appended to define properties.
 * 
 * Example:
 *
 * (code)
 * new mxEventObject("eventName", key1, val1, .., keyN, valN)
 * (end)
 */
function mxEventObject(name)
{
	this.name = name;
	this.properties = [];
	
	for (var i = 1; i < arguments.length; i += 2)
	{
		if (arguments[i + 1] != null)
		{
			this.properties[arguments[i]] = arguments[i + 1];
		}
	}
};

/**
 * Variable: name
 *
 * Holds the name.
 */
mxEventObject.prototype.name = null;

/**
 * Variable: properties
 *
 * Holds the properties as an associative array.
 */
mxEventObject.prototype.properties = null;

/**
 * Variable: consumed
 *
 * Holds the consumed state. Default is false.
 */
mxEventObject.prototype.consumed = false;

/**
 * Function: getName
 * 
 * Returns <name>.
 */
mxEventObject.prototype.getName = function()
{
	return this.name;
};

/**
 * Function: getProperties
 * 
 * Returns <properties>.
 */
mxEventObject.prototype.getProperties = function()
{
	return this.properties;
};

/**
 * Function: getProperty
 * 
 * Returns the property for the given key.
 */
mxEventObject.prototype.getProperty = function(key)
{
	return this.properties[key];
};

/**
 * Function: isConsumed
 *
 * Returns true if the event has been consumed.
 */
mxEventObject.prototype.isConsumed = function()
{
	return this.consumed;
};

/**
 * Function: consume
 *
 * Consumes the event.
 */
mxEventObject.prototype.consume = function()
{
	this.consumed = true;
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxMouseEvent
 * 
 * Base class for all mouse events in mxGraph. A listener for this event should
 * implement the following methods:
 * 
 * (code)
 * graph.addMouseListener(
 * {
 *   mouseDown: function(sender, evt)
 *   {
 *     mxLog.debug('mouseDown');
 *   },
 *   mouseMove: function(sender, evt)
 *   {
 *     mxLog.debug('mouseMove');
 *   },
 *   mouseUp: function(sender, evt)
 *   {
 *     mxLog.debug('mouseUp');
 *   }
 * });
 * (end)
 * 
 * Constructor: mxMouseEvent
 *
 * Constructs a new event object for the given arguments.
 * 
 * Parameters:
 * 
 * evt - Native mouse event.
 * state - Optional <mxCellState> under the mouse.
 * 
 */
function mxMouseEvent(evt, state)
{
	this.evt = evt;
	this.state = state;
	this.sourceState = state;
};

/**
 * Variable: consumed
 *
 * Holds the consumed state of this event.
 */
mxMouseEvent.prototype.consumed = false;

/**
 * Variable: evt
 *
 * Holds the inner event object.
 */
mxMouseEvent.prototype.evt = null;

/**
 * Variable: graphX
 *
 * Holds the x-coordinate of the event in the graph. This value is set in
 * <mxGraph.fireMouseEvent>.
 */
mxMouseEvent.prototype.graphX = null;

/**
 * Variable: graphY
 *
 * Holds the y-coordinate of the event in the graph. This value is set in
 * <mxGraph.fireMouseEvent>.
 */
mxMouseEvent.prototype.graphY = null;

/**
 * Variable: state
 *
 * Holds the optional <mxCellState> associated with this event.
 */
mxMouseEvent.prototype.state = null;

/**
 * Variable: sourceState
 * 
 * Holds the <mxCellState> that was passed to the constructor. This can be
 * different from <state> depending on the result of <mxGraph.getEventState>.
 */
mxMouseEvent.prototype.sourceState = null;

/**
 * Function: getEvent
 * 
 * Returns <evt>.
 */
mxMouseEvent.prototype.getEvent = function()
{
	return this.evt;
};

/**
 * Function: getSource
 * 
 * Returns the target DOM element using <mxEvent.getSource> for <evt>.
 */
mxMouseEvent.prototype.getSource = function()
{
	return mxEvent.getSource(this.evt);
};

/**
 * Function: isSource
 * 
 * Returns true if the given <mxShape> is the source of <evt>.
 */
mxMouseEvent.prototype.isSource = function(shape)
{
	if (shape != null)
	{
		return mxUtils.isAncestorNode(shape.node, this.getSource());
	}
	
	return false;
};

/**
 * Function: getX
 * 
 * Returns <evt.clientX>.
 */
mxMouseEvent.prototype.getX = function()
{
	return mxEvent.getClientX(this.getEvent());
};

/**
 * Function: getY
 * 
 * Returns <evt.clientY>.
 */
mxMouseEvent.prototype.getY = function()
{
	return mxEvent.getClientY(this.getEvent());
};

/**
 * Function: getGraphX
 * 
 * Returns <graphX>.
 */
mxMouseEvent.prototype.getGraphX = function()
{
	return this.graphX;
};

/**
 * Function: getGraphY
 * 
 * Returns <graphY>.
 */
mxMouseEvent.prototype.getGraphY = function()
{
	return this.graphY;
};

/**
 * Function: getState
 * 
 * Returns <state>.
 */
mxMouseEvent.prototype.getState = function()
{
	return this.state;
};

/**
 * Function: getCell
 * 
 * Returns the <mxCell> in <state> is not null.
 */
mxMouseEvent.prototype.getCell = function()
{
	var state = this.getState();
	
	if (state != null)
	{
		return state.cell;
	}
	
	return null;
};

/**
 * Function: isPopupTrigger
 *
 * Returns true if the event is a popup trigger.
 */
mxMouseEvent.prototype.isPopupTrigger = function()
{
	return mxEvent.isPopupTrigger(this.getEvent());
};

/**
 * Function: isConsumed
 *
 * Returns <consumed>.
 */
mxMouseEvent.prototype.isConsumed = function()
{
	return this.consumed;
};

/**
 * Function: consume
 *
 * Sets <consumed> to true and invokes preventDefault on the native event
 * if such a method is defined. This is used mainly to avoid the cursor from
 * being changed to a text cursor in Webkit. You can use the preventDefault
 * flag to disable this functionality.
 * 
 * Parameters:
 * 
 * preventDefault - Specifies if the native event should be canceled. Default
 * is true.
 */
mxMouseEvent.prototype.consume = function(preventDefault)
{
	preventDefault = (preventDefault != null) ? preventDefault : true;
	
	if (preventDefault && this.evt.preventDefault)
	{
		this.evt.preventDefault();
	}

	// Workaround for images being dragged in IE
	// Does not change returnValue in Opera
	if (mxClient.IS_IE)
	{
		this.evt.returnValue = true;
	}

	// Sets local consumed state
	this.consumed = true;
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxEventSource
 *
 * Base class for objects that dispatch named events. To create a subclass that
 * inherits from mxEventSource, the following code is used.
 *
 * (code)
 * function MyClass() { };
 *
 * MyClass.prototype = new mxEventSource();
 * MyClass.prototype.constructor = MyClass;
 * (end)
 *
 * Known Subclasses:
 *
 * <mxGraphModel>, <mxGraph>, <mxGraphView>, <mxEditor>, <mxCellOverlay>,
 * <mxToolbar>, <mxWindow>
 * 
 * Constructor: mxEventSource
 *
 * Constructs a new event source.
 */
function mxEventSource(eventSource)
{
	this.setEventSource(eventSource);
};

/**
 * Variable: eventListeners
 *
 * Holds the event names and associated listeners in an array. The array
 * contains the event name followed by the respective listener for each
 * registered listener.
 */
mxEventSource.prototype.eventListeners = null;

/**
 * Variable: eventsEnabled
 *
 * Specifies if events can be fired. Default is true.
 */
mxEventSource.prototype.eventsEnabled = true;

/**
 * Variable: eventSource
 *
 * Optional source for events. Default is null.
 */
mxEventSource.prototype.eventSource = null;

/**
 * Function: isEventsEnabled
 * 
 * Returns <eventsEnabled>.
 */
mxEventSource.prototype.isEventsEnabled = function()
{
	return this.eventsEnabled;
};

/**
 * Function: setEventsEnabled
 * 
 * Sets <eventsEnabled>.
 */
mxEventSource.prototype.setEventsEnabled = function(value)
{
	this.eventsEnabled = value;
};

/**
 * Function: getEventSource
 * 
 * Returns <eventSource>.
 */
mxEventSource.prototype.getEventSource = function()
{
	return this.eventSource;
};

/**
 * Function: setEventSource
 * 
 * Sets <eventSource>.
 */
mxEventSource.prototype.setEventSource = function(value)
{
	this.eventSource = value;
};

/**
 * Function: addListener
 *
 * Binds the specified function to the given event name. If no event name
 * is given, then the listener is registered for all events.
 * 
 * The parameters of the listener are the sender and an <mxEventObject>.
 */
mxEventSource.prototype.addListener = function(name, funct)
{
	if (this.eventListeners == null)
	{
		this.eventListeners = [];
	}
	
	this.eventListeners.push(name);
	this.eventListeners.push(funct);
};

/**
 * Function: removeListener
 *
 * Removes all occurrences of the given listener from <eventListeners>.
 */
mxEventSource.prototype.removeListener = function(funct)
{
	if (this.eventListeners != null)
	{
		var i = 0;
		
		while (i < this.eventListeners.length)
		{
			if (this.eventListeners[i+1] == funct)
			{
				this.eventListeners.splice(i, 2);
			}
			else
			{
				i += 2;
			}
		}
	}
};

/**
 * Function: fireEvent
 *
 * Dispatches the given event to the listeners which are registered for
 * the event. The sender argument is optional. The current execution scope
 * ("this") is used for the listener invocation (see <mxUtils.bind>).
 *
 * Example:
 *
 * (code)
 * fireEvent(new mxEventObject("eventName", key1, val1, .., keyN, valN))
 * (end)
 * 
 * Parameters:
 *
 * evt - <mxEventObject> that represents the event.
 * sender - Optional sender to be passed to the listener. Default value is
 * the return value of <getEventSource>.
 */
mxEventSource.prototype.fireEvent = function(evt, sender)
{
	if (this.eventListeners != null && this.isEventsEnabled())
	{
		if (evt == null)
		{
			evt = new mxEventObject();
		}
		
		if (sender == null)
		{
			sender = this.getEventSource();
		}

		if (sender == null)
		{
			sender = this;
		}

		var args = [sender, evt];
		
		for (var i = 0; i < this.eventListeners.length; i += 2)
		{
			var listen = this.eventListeners[i];
			
			if (listen == null || listen == evt.getName())
			{
				this.eventListeners[i+1].apply(this, args);
			}
		}
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
var mxEvent =
{

	/**
	 * Class: mxEvent
	 * 
	 * Cross-browser DOM event support. For internal event handling,
	 * <mxEventSource> and the graph event dispatch loop in <mxGraph> are used.
	 * 
	 * Memory Leaks:
	 * 
	 * Use this class for adding and removing listeners to/from DOM nodes. The
	 * <removeAllListeners> function is provided to remove all listeners that
	 * have been added using <addListener>. The function should be invoked when
	 * the last reference is removed in the JavaScript code, typically when the
	 * referenced DOM node is removed from the DOM, and helps to reduce memory
	 * leaks in IE6.
	 * 
	 * Variable: objects
	 * 
	 * Contains all objects where any listener was added using <addListener>.
	 * This is used to reduce memory leaks in IE, see <mxClient.dispose>.
	 */
	objects: [],

	 /**
	  * Function: addListener
	  * 
	  * Binds the function to the specified event on the given element. Use
	  * <mxUtils.bind> in order to bind the "this" keyword inside the function
	  * to a given execution scope.
	  */
	addListener: function()
	{
		var updateListenerList = function(element, eventName, funct)
		{
			if (element.mxListenerList == null)
			{
				element.mxListenerList = [];
				mxEvent.objects.push(element);
			}
			
			var entry = {name: eventName, f: funct};
			element.mxListenerList.push(entry);
		};
		
		if (window.addEventListener)
		{
			return function(element, eventName, funct)
			{
				element.addEventListener(eventName, funct, false);
				updateListenerList(element, eventName, funct);
			};
		}
		else
		{
			return function(element, eventName, funct)
			{
				element.attachEvent('on' + eventName, funct);
				updateListenerList(element, eventName, funct);				
			};
		}
	}(),

	/**
	 * Function: removeListener
	 *
	 * Removes the specified listener from the given element.
	 */
	removeListener: function()
	{
		var updateListener = function(element, eventName, funct)
		{
			if (element.mxListenerList != null)
			{
				var listenerCount = element.mxListenerList.length;
				
				for (var i = 0; i < listenerCount; i++)
				{
					var entry = element.mxListenerList[i];
					
					if (entry.f == funct)
					{
						element.mxListenerList.splice(i, 1);
						break;
					}
				}
				
				if (element.mxListenerList.length == 0)
				{
					element.mxListenerList = null;
					
					var idx = mxUtils.indexOf(mxEvent.objects, element);
					
					if (idx >= 0)
					{
						mxEvent.objects.splice(idx, 1);
					}
				}
			}
		};
		
		if (window.removeEventListener)
		{
			return function(element, eventName, funct)
			{
				element.removeEventListener(eventName, funct, false);
				updateListener(element, eventName, funct);
			};
		}
		else
		{
			return function(element, eventName, funct)
			{
				element.detachEvent('on' + eventName, funct);
				updateListener(element, eventName, funct);
			};
		}
	}(),

	/**
	 * Function: removeAllListeners
	 * 
	 * Removes all listeners from the given element.
	 */
	removeAllListeners: function(element)
	{
		var list = element.mxListenerList;

		if (list != null)
		{
			while (list.length > 0)
			{
				var entry = list[0];
				mxEvent.removeListener(element, entry.name, entry.f);
			}
		}
	},
	
	/**
	 * Function: addGestureListeners
	 * 
	 * Adds the given listeners for touch, mouse and/or pointer events. If
	 * <mxClient.IS_POINTER> is true then pointer events will be registered,
	 * else the respective mouse events will be registered. If <mxClient.IS_POINTER>
	 * is false and <mxClient.IS_TOUCH> is true then the respective touch events
	 * will be registered as well as the mouse events.
	 */
	addGestureListeners: function(node, startListener, moveListener, endListener)
	{
		if (startListener != null)
		{
			mxEvent.addListener(node, (mxClient.IS_POINTER) ? 'pointerdown' : 'mousedown', startListener);
		}
		
		if (moveListener != null)
		{
			mxEvent.addListener(node, (mxClient.IS_POINTER) ? 'pointermove' : 'mousemove', moveListener);
		}
		
		if (endListener != null)
		{
			mxEvent.addListener(node, (mxClient.IS_POINTER) ? 'pointerup' : 'mouseup', endListener);
		}
		
		if (!mxClient.IS_POINTER && mxClient.IS_TOUCH)
		{
			if (startListener != null)
			{
				mxEvent.addListener(node, 'touchstart', startListener);
			}
			
			if (moveListener != null)
			{
				mxEvent.addListener(node, 'touchmove', moveListener);
			}
			
			if (endListener != null)
			{
				mxEvent.addListener(node, 'touchend', endListener);
			}
		}
	},
	
	/**
	 * Function: removeGestureListeners
	 * 
	 * Removes the given listeners from mousedown, mousemove, mouseup and the
	 * respective touch events if <mxClient.IS_TOUCH> is true.
	 */
	removeGestureListeners: function(node, startListener, moveListener, endListener)
	{
		if (startListener != null)
		{
			mxEvent.removeListener(node, (mxClient.IS_POINTER) ? 'pointerdown' : 'mousedown', startListener);
		}
		
		if (moveListener != null)
		{
			mxEvent.removeListener(node, (mxClient.IS_POINTER) ? 'pointermove' : 'mousemove', moveListener);
		}
		
		if (endListener != null)
		{
			mxEvent.removeListener(node, (mxClient.IS_POINTER) ? 'pointerup' : 'mouseup', endListener);
		}
		
		if (!mxClient.IS_POINTER && mxClient.IS_TOUCH)
		{
			if (startListener != null)
			{
				mxEvent.removeListener(node, 'touchstart', startListener);
			}
			
			if (moveListener != null)
			{
				mxEvent.removeListener(node, 'touchmove', moveListener);
			}
			
			if (endListener != null)
			{
				mxEvent.removeListener(node, 'touchend', endListener);
			}
		}
	},
	
	/**
	 * Function: redirectMouseEvents
	 *
	 * Redirects the mouse events from the given DOM node to the graph dispatch
	 * loop using the event and given state as event arguments. State can
	 * either be an instance of <mxCellState> or a function that returns an
	 * <mxCellState>. The down, move, up and dblClick arguments are optional
	 * functions that take the trigger event as arguments and replace the
	 * default behaviour.
	 */
	redirectMouseEvents: function(node, graph, state, down, move, up, dblClick)
	{
		var getState = function(evt)
		{
			return (typeof(state) == 'function') ? state(evt) : state;
		};
		
		mxEvent.addGestureListeners(node, function (evt)
		{
			if (down != null)
			{
				down(evt);
			}
			else if (!mxEvent.isConsumed(evt))
			{
				graph.fireMouseEvent(mxEvent.MOUSE_DOWN, new mxMouseEvent(evt, getState(evt)));
			}
		},
		function (evt)
		{
			if (move != null)
			{
				move(evt);
			}
			else if (!mxEvent.isConsumed(evt))
			{
				graph.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt, getState(evt)));
			}
		},
		function (evt)
		{
			if (up != null)
			{
				up(evt);
			}
			else if (!mxEvent.isConsumed(evt))
			{
				graph.fireMouseEvent(mxEvent.MOUSE_UP, new mxMouseEvent(evt, getState(evt)));
			}
		});

		mxEvent.addListener(node, 'dblclick', function (evt)
		{
			if (dblClick != null)
			{
				dblClick(evt);
			}
			else if (!mxEvent.isConsumed(evt))
			{
				var tmp = getState(evt);
				graph.dblClick(evt, (tmp != null) ? tmp.cell : null);
			}
		});
	},

	/**
	 * Function: release
	 * 
	 * Removes the known listeners from the given DOM node and its descendants.
	 * 
	 * Parameters:
	 * 
	 * element - DOM node to remove the listeners from.
	 */
	release: function(element)
	{
		if (element != null)
		{
			mxEvent.removeAllListeners(element);
			
			var children = element.childNodes;
			
			if (children != null)
			{
		        var childCount = children.length;
		        
		        for (var i = 0; i < childCount; i += 1)
		        {
		        	mxEvent.release(children[i]);
		        }
		    }
		}
	},

	/**
	 * Function: addMouseWheelListener
	 * 
	 * Installs the given function as a handler for mouse wheel events. The
	 * function has two arguments: the mouse event and a boolean that specifies
	 * if the wheel was moved up or down.
	 * 
	 * This has been tested with IE 6 and 7, Firefox (all versions), Opera and
	 * Safari. It does currently not work on Safari for Mac.
	 * 
	 * Example:
	 * 
	 * (code)
	 * mxEvent.addMouseWheelListener(function (evt, up)
	 * {
	 *   mxLog.show();
	 *   mxLog.debug('mouseWheel: up='+up);
	 * });
	 *(end)
	 * 
	 * Parameters:
	 * 
	 * funct - Handler function that takes the event argument and a boolean up
	 * argument for the mousewheel direction.
	 */
	addMouseWheelListener: function(funct)
	{
		if (funct != null)
		{
			var wheelHandler = function(evt)
			{
				// IE does not give an event object but the
				// global event object is the mousewheel event
				// at this point in time.
				if (evt == null)
				{
					evt = window.event;
				}
			
				var delta = 0;
				
				if (mxClient.IS_FF)
				{
					delta = -evt.detail / 2;
				}
				else
				{
					delta = evt.wheelDelta / 120;
				}
				
				// Handles the event using the given function
				if (delta != 0)
				{
					funct(evt, delta > 0);
				}
			};
	
			// Webkit has NS event API, but IE event name and details 
			if (mxClient.IS_NS && document.documentMode == null)
			{
				var eventName = (mxClient.IS_SF || 	mxClient.IS_GC) ? 'mousewheel' : 'DOMMouseScroll';
				mxEvent.addListener(window, eventName, wheelHandler);
			}
			else
			{
				mxEvent.addListener(document, 'mousewheel', wheelHandler);
			}
		}
	},
	
	/**
	 * Function: disableContextMenu
	 *
	 * Disables the context menu for the given element.
	 */
	disableContextMenu: function()
	{
		if (mxClient.IS_IE && (typeof(document.documentMode) === 'undefined' || document.documentMode < 9))
		{
			return function(element)
			{
				mxEvent.addListener(element, 'contextmenu', function()
				{
					return false;
				});
			};
		}
		else
		{
			return function(element)
			{
				element.setAttribute('oncontextmenu', 'return false;');
			};		
		}
	}(),
	
	/**
	 * Function: getSource
	 * 
	 * Returns the event's target or srcElement depending on the browser.
	 */
	getSource: function(evt)
	{
		return (evt.srcElement != null) ? evt.srcElement : evt.target;
	},

	/**
	 * Function: isConsumed
	 * 
	 * Returns true if the event has been consumed using <consume>.
	 */
	isConsumed: function(evt)
	{
		return evt.isConsumed != null && evt.isConsumed;
	},

	/**
	 * Function: isTouchEvent
	 * 
	 * Returns true if the event was generated using a touch device (not a pen or mouse).
	 */
	isTouchEvent: function(evt)
	{
		return (evt.pointerType != null) ? (evt.pointerType == 'touch' || evt.pointerType ===
			evt.MSPOINTER_TYPE_TOUCH) : ((evt.mozInputSource != null) ?
					evt.mozInputSource == 5 : evt.type.indexOf('touch') == 0);
	},

	/**
	 * Function: isPenEvent
	 * 
	 * Returns true if the event was generated using a pen (not a touch device or mouse).
	 */
	isPenEvent: function(evt)
	{
		return (evt.pointerType != null) ? (evt.pointerType == 'pen' || evt.pointerType ===
			evt.MSPOINTER_TYPE_PEN) : ((evt.mozInputSource != null) ?
					evt.mozInputSource == 2 : evt.type.indexOf('pen') == 0);
	},

	/**
	 * Function: isMultiTouchEvent
	 * 
	 * Returns true if the event was generated using a touch device (not a pen or mouse).
	 */
	isMultiTouchEvent: function(evt)
	{
		return (evt.type != null && evt.type.indexOf('touch') == 0 && evt.touches != null && evt.touches.length > 1);
	},

	/**
	 * Function: isMouseEvent
	 * 
	 * Returns true if the event was generated using a mouse (not a pen or touch device).
	 */
	isMouseEvent: function(evt)
	{
		return (evt.pointerType != null) ? (evt.pointerType == 'mouse' || evt.pointerType ===
			evt.MSPOINTER_TYPE_MOUSE) : ((evt.mozInputSource != null) ?
				evt.mozInputSource == 1 : evt.type.indexOf('mouse') == 0);
	},
	
	/**
	 * Function: isLeftMouseButton
	 * 
	 * Returns true if the left mouse button is pressed for the given event.
	 * To check if a button is pressed during a mouseMove you should use the
	 * <mxGraph.isMouseDown> property. Note that this returns true in Firefox
	 * for control+left-click on the Mac.
	 */
	isLeftMouseButton: function(evt)
	{
		// Special case for mousemove and mousedown we check the buttons
		// if it exists because which is 0 even if no button is pressed
		if ('buttons' in evt && (evt.type == 'mousedown' || evt.type == 'mousemove'))
		{
			return evt.buttons == 1;
		}
		else if ('which' in evt)
		{
	        return evt.which === 1;
	    }
		else
		{
	        return evt.button === 1;
	    }
	},
	
	/**
	 * Function: isMiddleMouseButton
	 * 
	 * Returns true if the middle mouse button is pressed for the given event.
	 * To check if a button is pressed during a mouseMove you should use the
	 * <mxGraph.isMouseDown> property.
	 */
	isMiddleMouseButton: function(evt)
	{
		if ('which' in evt)
		{
	        return evt.which === 2;
	    }
		else
		{
	        return evt.button === 4;
	    }
	},
	
	/**
	 * Function: isRightMouseButton
	 * 
	 * Returns true if the right mouse button was pressed. Note that this
	 * button might not be available on some systems. For handling a popup
	 * trigger <isPopupTrigger> should be used.
	 */
	isRightMouseButton: function(evt)
	{
		if ('which' in evt)
		{
	        return evt.which === 3;
	    }
		else
		{
	        return evt.button === 2;
	    }
	},

	/**
	 * Function: isPopupTrigger
	 * 
	 * Returns true if the event is a popup trigger. This implementation
	 * returns true if the right button or the left button and control was
	 * pressed on a Mac.
	 */
	isPopupTrigger: function(evt)
	{
		return mxEvent.isRightMouseButton(evt) || (mxClient.IS_MAC && mxEvent.isControlDown(evt) &&
			!mxEvent.isShiftDown(evt) && !mxEvent.isMetaDown(evt) && !mxEvent.isAltDown(evt));
	},

	/**
	 * Function: isShiftDown
	 * 
	 * Returns true if the shift key is pressed for the given event.
	 */
	isShiftDown: function(evt)
	{
		return (evt != null) ? evt.shiftKey : false;
	},

	/**
	 * Function: isAltDown
	 * 
	 * Returns true if the alt key is pressed for the given event.
	 */
	isAltDown: function(evt)
	{
		return (evt != null) ? evt.altKey : false;
	},

	/**
	 * Function: isControlDown
	 * 
	 * Returns true if the control key is pressed for the given event.
	 */
	isControlDown: function(evt)
	{
		return (evt != null) ? evt.ctrlKey : false;
	},

	/**
	 * Function: isMetaDown
	 * 
	 * Returns true if the meta key is pressed for the given event.
	 */
	isMetaDown: function(evt)
	{
		return (evt != null) ? evt.metaKey : false;
	},

	/**
	 * Function: getMainEvent
	 * 
	 * Returns the touch or mouse event that contains the mouse coordinates.
	 */
	getMainEvent: function(e)
	{
		if ((e.type == 'touchstart' || e.type == 'touchmove') && e.touches != null && e.touches[0] != null)
		{
			e = e.touches[0];
		}
		else if (e.type == 'touchend' && e.changedTouches != null && e.changedTouches[0] != null)
		{
			e = e.changedTouches[0];
		}
		
		return e;
	},
	
	/**
	 * Function: getClientX
	 * 
	 * Returns true if the meta key is pressed for the given event.
	 */
	getClientX: function(e)
	{
		return mxEvent.getMainEvent(e).clientX;
	},

	/**
	 * Function: getClientY
	 * 
	 * Returns true if the meta key is pressed for the given event.
	 */
	getClientY: function(e)
	{
		return mxEvent.getMainEvent(e).clientY;
	},

	/**
	 * Function: consume
	 * 
	 * Consumes the given event.
	 * 
	 * Parameters:
	 * 
	 * evt - Native event to be consumed.
	 * preventDefault - Optional boolean to prevent the default for the event.
	 * Default is true.
	 * stopPropagation - Option boolean to stop event propagation. Default is
	 * true.
	 */
	consume: function(evt, preventDefault, stopPropagation)
	{
		preventDefault = (preventDefault != null) ? preventDefault : true;
		stopPropagation = (stopPropagation != null) ? stopPropagation : true;
		
		if (preventDefault)
		{
			if (evt.preventDefault)
			{
				if (stopPropagation)
				{
					evt.stopPropagation();
				}
				
				evt.preventDefault();
			}
			else if (stopPropagation)
			{
				evt.cancelBubble = true;
			}
		}

		// Opera
		evt.isConsumed = true;

		// Other browsers
		if (!evt.preventDefault)
		{
			evt.returnValue = false;
		}
	},
	
	//
	// Special handles in mouse events
	//
	
	/**
	 * Variable: LABEL_HANDLE
	 * 
	 * Index for the label handle in an mxMouseEvent. This should be a negative
	 * value that does not interfere with any possible handle indices. Default
	 * is -1.
	 */
	LABEL_HANDLE: -1,
	
	/**
	 * Variable: ROTATION_HANDLE
	 * 
	 * Index for the rotation handle in an mxMouseEvent. This should be a
	 * negative value that does not interfere with any possible handle indices.
	 * Default is -2.
	 */
	ROTATION_HANDLE: -2,
	
	/**
	 * Variable: CUSTOM_HANDLE
	 * 
	 * Start index for the custom handles in an mxMouseEvent. This should be a
	 * negative value and is the start index which is decremented for each
	 * custom handle. Default is -100.
	 */
	CUSTOM_HANDLE: -100,
	
	/**
	 * Variable: VIRTUAL_HANDLE
	 * 
	 * Start index for the virtual handles in an mxMouseEvent. This should be a
	 * negative value and is the start index which is decremented for each
	 * virtual handle. Default is -100000. This assumes that there are no more
	 * than VIRTUAL_HANDLE - CUSTOM_HANDLE custom handles.
	 * 
	 */
	VIRTUAL_HANDLE: -100000,
	
	//
	// Event names
	//
	
	/**
	 * Variable: MOUSE_DOWN
	 *
	 * Specifies the event name for mouseDown.
	 */
	MOUSE_DOWN: 'mouseDown',
	
	/**
	 * Variable: MOUSE_MOVE
	 *
	 * Specifies the event name for mouseMove. 
	 */
	MOUSE_MOVE: 'mouseMove',
	
	/**
	 * Variable: MOUSE_UP
	 *
	 * Specifies the event name for mouseUp. 
	 */
	MOUSE_UP: 'mouseUp',

	/**
	 * Variable: ACTIVATE
	 *
	 * Specifies the event name for activate.
	 */
	ACTIVATE: 'activate',

	/**
	 * Variable: RESIZE_START
	 *
	 * Specifies the event name for resizeStart.
	 */
	RESIZE_START: 'resizeStart',

	/**
	 * Variable: RESIZE
	 *
	 * Specifies the event name for resize.
	 */
	RESIZE: 'resize',

	/**
	 * Variable: RESIZE_END
	 *
	 * Specifies the event name for resizeEnd.
	 */
	RESIZE_END: 'resizeEnd',

	/**
	 * Variable: MOVE_START
	 *
	 * Specifies the event name for moveStart.
	 */
	MOVE_START: 'moveStart',

	/**
	 * Variable: MOVE
	 *
	 * Specifies the event name for move.
	 */
	MOVE: 'move',

	/**
	 * Variable: MOVE_END
	 *
	 * Specifies the event name for moveEnd.
	 */
	MOVE_END: 'moveEnd',

	/**
	 * Variable: PAN_START
	 *
	 * Specifies the event name for panStart.
	 */
	PAN_START: 'panStart',

	/**
	 * Variable: PAN
	 *
	 * Specifies the event name for pan.
	 */
	PAN: 'pan',

	/**
	 * Variable: PAN_END
	 *
	 * Specifies the event name for panEnd.
	 */
	PAN_END: 'panEnd',

	/**
	 * Variable: MINIMIZE
	 *
	 * Specifies the event name for minimize.
	 */
	MINIMIZE: 'minimize',

	/**
	 * Variable: NORMALIZE
	 *
	 * Specifies the event name for normalize.
	 */
	NORMALIZE: 'normalize',

	/**
	 * Variable: MAXIMIZE
	 *
	 * Specifies the event name for maximize.
	 */
	MAXIMIZE: 'maximize',

	/**
	 * Variable: HIDE
	 *
	 * Specifies the event name for hide.
	 */
	HIDE: 'hide',

	/**
	 * Variable: SHOW
	 *
	 * Specifies the event name for show.
	 */
	SHOW: 'show',

	/**
	 * Variable: CLOSE
	 *
	 * Specifies the event name for close.
	 */
	CLOSE: 'close',

	/**
	 * Variable: DESTROY
	 *
	 * Specifies the event name for destroy.
	 */
	DESTROY: 'destroy',

	/**
	 * Variable: REFRESH
	 *
	 * Specifies the event name for refresh.
	 */
	REFRESH: 'refresh',

	/**
	 * Variable: SIZE
	 *
	 * Specifies the event name for size.
	 */
	SIZE: 'size',
	
	/**
	 * Variable: SELECT
	 *
	 * Specifies the event name for select.
	 */
	SELECT: 'select',

	/**
	 * Variable: FIRED
	 *
	 * Specifies the event name for fired.
	 */
	FIRED: 'fired',

	/**
	 * Variable: FIRE_MOUSE_EVENT
	 *
	 * Specifies the event name for fireMouseEvent.
	 */
	FIRE_MOUSE_EVENT: 'fireMouseEvent',

	/**
	 * Variable: GESTURE
	 *
	 * Specifies the event name for gesture.
	 */
	GESTURE: 'gesture',

	/**
	 * Variable: TAP_AND_HOLD
	 *
	 * Specifies the event name for tapAndHold.
	 */
	TAP_AND_HOLD: 'tapAndHold',

	/**
	 * Variable: GET
	 *
	 * Specifies the event name for get.
	 */
	GET: 'get',

	/**
	 * Variable: RECEIVE
	 *
	 * Specifies the event name for receive.
	 */
	RECEIVE: 'receive',

	/**
	 * Variable: CONNECT
	 *
	 * Specifies the event name for connect.
	 */
	CONNECT: 'connect',

	/**
	 * Variable: DISCONNECT
	 *
	 * Specifies the event name for disconnect.
	 */
	DISCONNECT: 'disconnect',

	/**
	 * Variable: SUSPEND
	 *
	 * Specifies the event name for suspend.
	 */
	SUSPEND: 'suspend',

	/**
	 * Variable: RESUME
	 *
	 * Specifies the event name for suspend.
	 */
	RESUME: 'resume',

	/**
	 * Variable: MARK
	 *
	 * Specifies the event name for mark.
	 */
	MARK: 'mark',

	/**
	 * Variable: ROOT
	 *
	 * Specifies the event name for root.
	 */
	ROOT: 'root',

	/**
	 * Variable: POST
	 *
	 * Specifies the event name for post.
	 */
	POST: 'post',

	/**
	 * Variable: OPEN
	 *
	 * Specifies the event name for open.
	 */
	OPEN: 'open',

	/**
	 * Variable: SAVE
	 *
	 * Specifies the event name for open.
	 */
	SAVE: 'save',

	/**
	 * Variable: BEFORE_ADD_VERTEX
	 *
	 * Specifies the event name for beforeAddVertex.
	 */
	BEFORE_ADD_VERTEX: 'beforeAddVertex',

	/**
	 * Variable: ADD_VERTEX
	 *
	 * Specifies the event name for addVertex.
	 */
	ADD_VERTEX: 'addVertex',

	/**
	 * Variable: AFTER_ADD_VERTEX
	 *
	 * Specifies the event name for afterAddVertex.
	 */
	AFTER_ADD_VERTEX: 'afterAddVertex',

	/**
	 * Variable: DONE
	 *
	 * Specifies the event name for done.
	 */
	DONE: 'done',

	/**
	 * Variable: EXECUTE
	 *
	 * Specifies the event name for execute.
	 */
	EXECUTE: 'execute',

	/**
	 * Variable: EXECUTED
	 *
	 * Specifies the event name for executed.
	 */
	EXECUTED: 'executed',

	/**
	 * Variable: BEGIN_UPDATE
	 *
	 * Specifies the event name for beginUpdate.
	 */
	BEGIN_UPDATE: 'beginUpdate',

	/**
	 * Variable: START_EDIT
	 *
	 * Specifies the event name for startEdit.
	 */
	START_EDIT: 'startEdit',

	/**
	 * Variable: END_UPDATE
	 *
	 * Specifies the event name for endUpdate.
	 */
	END_UPDATE: 'endUpdate',

	/**
	 * Variable: END_EDIT
	 *
	 * Specifies the event name for endEdit.
	 */
	END_EDIT: 'endEdit',

	/**
	 * Variable: BEFORE_UNDO
	 *
	 * Specifies the event name for beforeUndo.
	 */
	BEFORE_UNDO: 'beforeUndo',

	/**
	 * Variable: UNDO
	 *
	 * Specifies the event name for undo.
	 */
	UNDO: 'undo',

	/**
	 * Variable: REDO
	 *
	 * Specifies the event name for redo.
	 */
	REDO: 'redo',

	/**
	 * Variable: CHANGE
	 *
	 * Specifies the event name for change.
	 */
	CHANGE: 'change',

	/**
	 * Variable: NOTIFY
	 *
	 * Specifies the event name for notify.
	 */
	NOTIFY: 'notify',

	/**
	 * Variable: LAYOUT_CELLS
	 *
	 * Specifies the event name for layoutCells.
	 */
	LAYOUT_CELLS: 'layoutCells',

	/**
	 * Variable: CLICK
	 *
	 * Specifies the event name for click.
	 */
	CLICK: 'click',

	/**
	 * Variable: SCALE
	 *
	 * Specifies the event name for scale.
	 */
	SCALE: 'scale',

	/**
	 * Variable: TRANSLATE
	 *
	 * Specifies the event name for translate.
	 */
	TRANSLATE: 'translate',

	/**
	 * Variable: SCALE_AND_TRANSLATE
	 *
	 * Specifies the event name for scaleAndTranslate.
	 */
	SCALE_AND_TRANSLATE: 'scaleAndTranslate',

	/**
	 * Variable: UP
	 *
	 * Specifies the event name for up.
	 */
	UP: 'up',

	/**
	 * Variable: DOWN
	 *
	 * Specifies the event name for down.
	 */
	DOWN: 'down',

	/**
	 * Variable: ADD
	 *
	 * Specifies the event name for add.
	 */
	ADD: 'add',

	/**
	 * Variable: REMOVE
	 *
	 * Specifies the event name for remove.
	 */
	REMOVE: 'remove',
	
	/**
	 * Variable: CLEAR
	 *
	 * Specifies the event name for clear.
	 */
	CLEAR: 'clear',

	/**
	 * Variable: ADD_CELLS
	 *
	 * Specifies the event name for addCells.
	 */
	ADD_CELLS: 'addCells',

	/**
	 * Variable: CELLS_ADDED
	 *
	 * Specifies the event name for cellsAdded.
	 */
	CELLS_ADDED: 'cellsAdded',

	/**
	 * Variable: MOVE_CELLS
	 *
	 * Specifies the event name for moveCells.
	 */
	MOVE_CELLS: 'moveCells',

	/**
	 * Variable: CELLS_MOVED
	 *
	 * Specifies the event name for cellsMoved.
	 */
	CELLS_MOVED: 'cellsMoved',

	/**
	 * Variable: RESIZE_CELLS
	 *
	 * Specifies the event name for resizeCells.
	 */
	RESIZE_CELLS: 'resizeCells',

	/**
	 * Variable: CELLS_RESIZED
	 *
	 * Specifies the event name for cellsResized.
	 */
	CELLS_RESIZED: 'cellsResized',

	/**
	 * Variable: TOGGLE_CELLS
	 *
	 * Specifies the event name for toggleCells.
	 */
	TOGGLE_CELLS: 'toggleCells',

	/**
	 * Variable: CELLS_TOGGLED
	 *
	 * Specifies the event name for cellsToggled.
	 */
	CELLS_TOGGLED: 'cellsToggled',

	/**
	 * Variable: ORDER_CELLS
	 *
	 * Specifies the event name for orderCells.
	 */
	ORDER_CELLS: 'orderCells',

	/**
	 * Variable: CELLS_ORDERED
	 *
	 * Specifies the event name for cellsOrdered.
	 */
	CELLS_ORDERED: 'cellsOrdered',

	/**
	 * Variable: REMOVE_CELLS
	 *
	 * Specifies the event name for removeCells.
	 */
	REMOVE_CELLS: 'removeCells',

	/**
	 * Variable: CELLS_REMOVED
	 *
	 * Specifies the event name for cellsRemoved.
	 */
	CELLS_REMOVED: 'cellsRemoved',

	/**
	 * Variable: GROUP_CELLS
	 *
	 * Specifies the event name for groupCells.
	 */
	GROUP_CELLS: 'groupCells',

	/**
	 * Variable: UNGROUP_CELLS
	 *
	 * Specifies the event name for ungroupCells.
	 */
	UNGROUP_CELLS: 'ungroupCells',

	/**
	 * Variable: REMOVE_CELLS_FROM_PARENT
	 *
	 * Specifies the event name for removeCellsFromParent.
	 */
	REMOVE_CELLS_FROM_PARENT: 'removeCellsFromParent',

	/**
	 * Variable: FOLD_CELLS
	 *
	 * Specifies the event name for foldCells.
	 */
	FOLD_CELLS: 'foldCells',

	/**
	 * Variable: CELLS_FOLDED
	 *
	 * Specifies the event name for cellsFolded.
	 */
	CELLS_FOLDED: 'cellsFolded',

	/**
	 * Variable: ALIGN_CELLS
	 *
	 * Specifies the event name for alignCells.
	 */
	ALIGN_CELLS: 'alignCells',

	/**
	 * Variable: LABEL_CHANGED
	 *
	 * Specifies the event name for labelChanged.
	 */
	LABEL_CHANGED: 'labelChanged',

	/**
	 * Variable: CONNECT_CELL
	 *
	 * Specifies the event name for connectCell.
	 */
	CONNECT_CELL: 'connectCell',

	/**
	 * Variable: CELL_CONNECTED
	 *
	 * Specifies the event name for cellConnected.
	 */
	CELL_CONNECTED: 'cellConnected',

	/**
	 * Variable: SPLIT_EDGE
	 *
	 * Specifies the event name for splitEdge.
	 */
	SPLIT_EDGE: 'splitEdge',

	/**
	 * Variable: FLIP_EDGE
	 *
	 * Specifies the event name for flipEdge.
	 */
	FLIP_EDGE: 'flipEdge',

	/**
	 * Variable: START_EDITING
	 *
	 * Specifies the event name for startEditing.
	 */
	START_EDITING: 'startEditing',

	/**
	 * Variable: EDITING_STARTED
	 *
	 * Specifies the event name for editingStarted.
	 */
	EDITING_STARTED: 'editingStarted',

	/**
	 * Variable: EDITING_STOPPED
	 *
	 * Specifies the event name for editingStopped.
	 */
	EDITING_STOPPED: 'editingStopped',

	/**
	 * Variable: ADD_OVERLAY
	 *
	 * Specifies the event name for addOverlay.
	 */
	ADD_OVERLAY: 'addOverlay',

	/**
	 * Variable: REMOVE_OVERLAY
	 *
	 * Specifies the event name for removeOverlay.
	 */
	REMOVE_OVERLAY: 'removeOverlay',

	/**
	 * Variable: UPDATE_CELL_SIZE
	 *
	 * Specifies the event name for updateCellSize.
	 */
	UPDATE_CELL_SIZE: 'updateCellSize',

	/**
	 * Variable: ESCAPE
	 *
	 * Specifies the event name for escape.
	 */
	ESCAPE: 'escape',

	/**
	 * Variable: DOUBLE_CLICK
	 *
	 * Specifies the event name for doubleClick.
	 */
	DOUBLE_CLICK: 'doubleClick',

	/**
	 * Variable: START
	 *
	 * Specifies the event name for start.
	 */
	START: 'start',

	/**
	 * Variable: RESET
	 *
	 * Specifies the event name for reset.
	 */
	RESET: 'reset'

};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxXmlRequest
 * 
 * XML HTTP request wrapper. See also: <mxUtils.get>, <mxUtils.post> and
 * <mxUtils.load>. This class provides a cross-browser abstraction for Ajax
 * requests.
 * 
 * Encoding:
 * 
 * For encoding parameter values, the built-in encodeURIComponent JavaScript
 * method must be used. For automatic encoding of post data in <mxEditor> the
 * <mxEditor.escapePostData> switch can be set to true (default). The encoding
 * will be carried out using the conte type of the page. That is, the page
 * containting the editor should contain a meta tag in the header, eg.
 * <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 * 
 * Example:
 * 
 * (code)
 * var onload = function(req)
 * {
 *   mxUtils.alert(req.getDocumentElement());
 * }
 * 
 * var onerror = function(req)
 * {
 *   mxUtils.alert('Error');
 * }
 * new mxXmlRequest(url, 'key=value').send(onload, onerror);
 * (end)
 * 
 * Sends an asynchronous POST request to the specified URL.
 * 
 * Example:
 * 
 * (code)
 * var req = new mxXmlRequest(url, 'key=value', 'POST', false);
 * req.send();
 * mxUtils.alert(req.getDocumentElement());
 * (end)
 * 
 * Sends a synchronous POST request to the specified URL.
 * 
 * Example:
 * 
 * (code)
 * var encoder = new mxCodec();
 * var result = encoder.encode(graph.getModel());
 * var xml = encodeURIComponent(mxUtils.getXml(result));
 * new mxXmlRequest(url, 'xml='+xml).send();
 * (end)
 * 
 * Sends an encoded graph model to the specified URL using xml as the
 * parameter name. The parameter can then be retrieved in C# as follows:
 * 
 * (code)
 * string xml = HttpUtility.UrlDecode(context.Request.Params["xml"]);
 * (end)
 * 
 * Or in Java as follows:
 * 
 * (code)
 * String xml = URLDecoder.decode(request.getParameter("xml"), "UTF-8").replace("\n", "&#xa;");
 * (end)
 *
 * Note that the linefeeds should only be replaced if the XML is
 * processed in Java, for example when creating an image.
 * 
 * Constructor: mxXmlRequest
 * 
 * Constructs an XML HTTP request.
 * 
 * Parameters:
 * 
 * url - Target URL of the request.
 * params - Form encoded parameters to send with a POST request.
 * method - String that specifies the request method. Possible values are
 * POST and GET. Default is POST.
 * async - Boolean specifying if an asynchronous request should be used.
 * Default is true.
 * username - String specifying the username to be used for the request.
 * password - String specifying the password to be used for the request.
 */
function mxXmlRequest(url, params, method, async, username, password)
{
	this.url = url;
	this.params = params;
	this.method = method || 'POST';
	this.async = (async != null) ? async : true;
	this.username = username;
	this.password = password;
};

/**
 * Variable: url
 * 
 * Holds the target URL of the request.
 */
mxXmlRequest.prototype.url = null;

/**
 * Variable: params
 * 
 * Holds the form encoded data for the POST request.
 */
mxXmlRequest.prototype.params = null;

/**
 * Variable: method
 * 
 * Specifies the request method. Possible values are POST and GET. Default
 * is POST.
 */
mxXmlRequest.prototype.method = null;

/**
 * Variable: async
 * 
 * Boolean indicating if the request is asynchronous.
 */
mxXmlRequest.prototype.async = null;

/**
 * Variable: binary
 * 
 * Boolean indicating if the request is binary. This option is ignored in IE.
 * In all other browsers the requested mime type is set to
 * text/plain; charset=x-user-defined. Default is false.
 */
mxXmlRequest.prototype.binary = false;

/**
 * Variable: withCredentials
 * 
 * Specifies if withCredentials should be used in HTML5-compliant browsers. Default is
 * false.
 */
mxXmlRequest.prototype.withCredentials = false;

/**
 * Variable: username
 * 
 * Specifies the username to be used for authentication.
 */
mxXmlRequest.prototype.username = null;

/**
 * Variable: password
 * 
 * Specifies the password to be used for authentication.
 */
mxXmlRequest.prototype.password = null;

/**
 * Variable: request
 * 
 * Holds the inner, browser-specific request object.
 */
mxXmlRequest.prototype.request = null;

/**
 * Variable: decodeSimulateValues
 * 
 * Specifies if request values should be decoded as URIs before setting the
 * textarea value in <simulate>. Defaults to false for backwards compatibility,
 * to avoid another decode on the server this should be set to true.
 */
mxXmlRequest.prototype.decodeSimulateValues = false;

/**
 * Function: isBinary
 * 
 * Returns <binary>.
 */
mxXmlRequest.prototype.isBinary = function()
{
	return this.binary;
};

/**
 * Function: setBinary
 * 
 * Sets <binary>.
 */
mxXmlRequest.prototype.setBinary = function(value)
{
	this.binary = value;
};

/**
 * Function: getText
 * 
 * Returns the response as a string.
 */
mxXmlRequest.prototype.getText = function()
{
	return this.request.responseText;
};

/**
 * Function: isReady
 * 
 * Returns true if the response is ready.
 */
mxXmlRequest.prototype.isReady = function()
{
	return this.request.readyState == 4;
};

/**
 * Function: getDocumentElement
 * 
 * Returns the document element of the response XML document.
 */
mxXmlRequest.prototype.getDocumentElement = function()
{
	var doc = this.getXml();
	
	if (doc != null)
	{
		return doc.documentElement;
	}
	
	return null;
};

/**
 * Function: getXml
 * 
 * Returns the response as an XML document. Use <getDocumentElement> to get
 * the document element of the XML document.
 */
mxXmlRequest.prototype.getXml = function()
{
	var xml = this.request.responseXML;
	
	// Handles missing response headers in IE, the first condition handles
	// the case where responseXML is there, but using its nodes leads to
	// type errors in the mxCellCodec when putting the nodes into a new
	// document. This happens in IE9 standards mode and with XML user
	// objects only, as they are used directly as values in cells.
	if (document.documentMode >= 9 || xml == null || xml.documentElement == null)
	{
		xml = mxUtils.parseXml(this.request.responseText);
	}
	
	return xml;
};

/**
 * Function: getText
 * 
 * Returns the response as a string.
 */
mxXmlRequest.prototype.getText = function()
{
	return this.request.responseText;
};

/**
 * Function: getStatus
 * 
 * Returns the status as a number, eg. 404 for "Not found" or 200 for "OK".
 * Note: The NS_ERROR_NOT_AVAILABLE for invalid responses cannot be cought.
 */
mxXmlRequest.prototype.getStatus = function()
{
	return this.request.status;
};

/**
 * Function: create
 * 
 * Creates and returns the inner <request> object.
 */
mxXmlRequest.prototype.create = function()
{
	if (window.XMLHttpRequest)
	{
		return function()
		{
			var req = new XMLHttpRequest();
			
			// TODO: Check for overrideMimeType required here?
			if (this.isBinary() && req.overrideMimeType)
			{
				req.overrideMimeType('text/plain; charset=x-user-defined');
			}

			return req;
		};
	}
	else if (typeof(ActiveXObject) != 'undefined')
	{
		return function()
		{
			// TODO: Implement binary option
			return new ActiveXObject('Microsoft.XMLHTTP');
		};
	}
}();

/**
 * Function: send
 * 
 * Send the <request> to the target URL using the specified functions to
 * process the response asychronously.
 * 
 * Parameters:
 * 
 * onload - Function to be invoked if a successful response was received.
 * onerror - Function to be called on any error.
 * timeout - Optional timeout in ms before calling ontimeout.
 * ontimeout - Optional function to execute on timeout.
 */
mxXmlRequest.prototype.send = function(onload, onerror, timeout, ontimeout)
{
	this.request = this.create();
	
	if (this.request != null)
	{
		if (onload != null)
		{
			this.request.onreadystatechange = mxUtils.bind(this, function()
			{
				if (this.isReady())
				{
					onload(this);
					this.onreadystatechaange = null;
				}
			});
		}

		this.request.open(this.method, this.url, this.async,
			this.username, this.password);
		this.setRequestHeaders(this.request, this.params);
		
		if (window.XMLHttpRequest && this.withCredentials)
		{
			this.request.withCredentials = 'true';
		}
		
		if (!mxClient.IS_QUIRKS && (document.documentMode == null || document.documentMode > 9) &&
			window.XMLHttpRequest && timeout != null && ontimeout != null)
		{
			this.request.timeout = timeout;
			this.request.ontimeout = ontimeout;
		}
				
		this.request.send(this.params);
	}
};

/**
 * Function: setRequestHeaders
 * 
 * Sets the headers for the given request and parameters. This sets the
 * content-type to application/x-www-form-urlencoded if any params exist.
 * 
 * Example:
 * 
 * (code)
 * request.setRequestHeaders = function(request, params)
 * {
 *   if (params != null)
 *   {
 *     request.setRequestHeader('Content-Type',
 *             'multipart/form-data');
 *     request.setRequestHeader('Content-Length',
 *             params.length);
 *   }
 * };
 * (end)
 * 
 * Use the code above before calling <send> if you require a
 * multipart/form-data request.   
 */
mxXmlRequest.prototype.setRequestHeaders = function(request, params)
{
	if (params != null)
	{
		request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	}
};

/**
 * Function: simulate
 * 
 * Creates and posts a request to the given target URL using a dynamically
 * created form inside the given document.
 * 
 * Parameters:
 * 
 * docs - Document that contains the form element.
 * target - Target to send the form result to.
 */
mxXmlRequest.prototype.simulate = function(doc, target)
{
	doc = doc || document;
	var old = null;

	if (doc == document)
	{
		old = window.onbeforeunload;		
		window.onbeforeunload = null;
	}
			
	var form = doc.createElement('form');
	form.setAttribute('method', this.method);
	form.setAttribute('action', this.url);

	if (target != null)
	{
		form.setAttribute('target', target);
	}

	form.style.display = 'none';
	form.style.visibility = 'hidden';
	
	var pars = (this.params.indexOf('&') > 0) ?
		this.params.split('&') :
		this.params.split();

	// Adds the parameters as textareas to the form
	for (var i=0; i<pars.length; i++)
	{
		var pos = pars[i].indexOf('=');
		
		if (pos > 0)
		{
			var name = pars[i].substring(0, pos);
			var value = pars[i].substring(pos+1);
			
			if (this.decodeSimulateValues)
			{
				value = decodeURIComponent(value);
			}
			
			var textarea = doc.createElement('textarea');
			textarea.setAttribute('wrap', 'off');
			textarea.setAttribute('name', name);
			mxUtils.write(textarea, value);
			form.appendChild(textarea);
		}
	}
	
	doc.body.appendChild(form);
	form.submit();
	
	if (form.parentNode != null)
	{
		form.parentNode.removeChild(form);
	}

	if (old != null)
	{		
		window.onbeforeunload = old;
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
var mxClipboard =
{
	/**
	 * Class: mxClipboard
	 * 
	 * Singleton that implements a clipboard for graph cells.
	 *
	 * Example:
	 * 
	 * (code)
	 * mxClipboard.copy(graph);
	 * mxClipboard.paste(graph2);
	 * (end)
	 *
	 * This copies the selection cells from the graph to the clipboard and
	 * pastes them into graph2.
	 * 
	 * For fine-grained control of the clipboard data the <mxGraph.canExportCell>
	 * and <mxGraph.canImportCell> functions can be overridden.
	 * 
	 * To restore previous parents for pasted cells, the implementation for
	 * <copy> and <paste> can be changed as follows.
	 * 
	 * (code)
	 * mxClipboard.copy = function(graph, cells)
	 * {
	 *   cells = cells || graph.getSelectionCells();
	 *   var result = graph.getExportableCells(cells);
	 *   
	 *   mxClipboard.parents = new Object();
	 *   
	 *   for (var i = 0; i < result.length; i++)
	 *   {
	 *     mxClipboard.parents[i] = graph.model.getParent(cells[i]);
	 *   }
	 *   
	 *   mxClipboard.insertCount = 1;
	 *   mxClipboard.setCells(graph.cloneCells(result));
	 *   
	 *   return result;
	 * };
	 * 
	 * mxClipboard.paste = function(graph)
	 * {
	 *   if (!mxClipboard.isEmpty())
	 *   {
	 *     var cells = graph.getImportableCells(mxClipboard.getCells());
	 *     var delta = mxClipboard.insertCount * mxClipboard.STEPSIZE;
	 *     var parent = graph.getDefaultParent();
	 *     
	 *     graph.model.beginUpdate();
	 *     try
	 *     {
	 *       for (var i = 0; i < cells.length; i++)
	 *       {
	 *         var tmp = (mxClipboard.parents != null && graph.model.contains(mxClipboard.parents[i])) ?
	 *              mxClipboard.parents[i] : parent;
	 *         cells[i] = graph.importCells([cells[i]], delta, delta, tmp)[0];
	 *       }
	 *     }
	 *     finally
	 *     {
	 *       graph.model.endUpdate();
	 *     }
	 *     
	 *     // Increments the counter and selects the inserted cells
	 *     mxClipboard.insertCount++;
	 *     graph.setSelectionCells(cells);
	 *   }
	 * };
	 * (end)
	 * 
	 * Variable: STEPSIZE
	 * 
	 * Defines the step size to offset the cells after each paste operation.
	 * Default is 10.
	 */
	STEPSIZE: 10,

	/**
	 * Variable: insertCount
	 * 
	 * Counts the number of times the clipboard data has been inserted.
	 */
	insertCount: 1,

	/**
	 * Variable: cells
	 * 
	 * Holds the array of <mxCells> currently in the clipboard.
	 */
	cells: null,

	/**
	 * Function: setCells
	 * 
	 * Sets the cells in the clipboard. Fires a <mxEvent.CHANGE> event.
	 */
	setCells: function(cells)
	{
		mxClipboard.cells = cells;
	},

	/**
	 * Function: getCells
	 * 
	 * Returns  the cells in the clipboard.
	 */
	getCells: function()
	{
		return mxClipboard.cells;
	},
	
	/**
	 * Function: isEmpty
	 * 
	 * Returns true if the clipboard currently has not data stored.
	 */
	isEmpty: function()
	{
		return mxClipboard.getCells() == null;
	},
	
	/**
	 * Function: cut
	 * 
	 * Cuts the given array of <mxCells> from the specified graph.
	 * If cells is null then the selection cells of the graph will
	 * be used. Returns the cells that have been cut from the graph.
	 *
	 * Parameters:
	 * 
	 * graph - <mxGraph> that contains the cells to be cut.
	 * cells - Optional array of <mxCells> to be cut.
	 */
	cut: function(graph, cells)
	{
		cells = mxClipboard.copy(graph, cells);
		mxClipboard.insertCount = 0;
		mxClipboard.removeCells(graph, cells);
		
		return cells;
	},

	/**
	 * Function: removeCells
	 * 
	 * Hook to remove the given cells from the given graph after
	 * a cut operation.
	 *
	 * Parameters:
	 * 
	 * graph - <mxGraph> that contains the cells to be cut.
	 * cells - Array of <mxCells> to be cut.
	 */
	removeCells: function(graph, cells)
	{
		graph.removeCells(cells);
	},

	/**
	 * Function: copy
	 * 
	 * Copies the given array of <mxCells> from the specified
	 * graph to <cells>. Returns the original array of cells that has
	 * been cloned. Descendants of cells in the array are ignored.
	 * 
	 * Parameters:
	 * 
	 * graph - <mxGraph> that contains the cells to be copied.
	 * cells - Optional array of <mxCells> to be copied.
	 */
	copy: function(graph, cells)
	{
		cells = cells || graph.getSelectionCells();
		var result = graph.getExportableCells(graph.model.getTopmostCells(cells));
		mxClipboard.insertCount = 1;
		mxClipboard.setCells(graph.cloneCells(result));

		return result;
	},

	/**
	 * Function: paste
	 * 
	 * Pastes the <cells> into the specified graph restoring
	 * the relation to <parents>, if possible. If the parents
	 * are no longer in the graph or invisible then the
	 * cells are added to the graph's default or into the
	 * swimlane under the cell's new location if one exists.
	 * The cells are added to the graph using <mxGraph.importCells>
	 * and returned.
	 * 
	 * Parameters:
	 * 
	 * graph - <mxGraph> to paste the <cells> into.
	 */
	paste: function(graph)
	{
		var cells = null;
		
		if (!mxClipboard.isEmpty())
		{
			cells = graph.getImportableCells(mxClipboard.getCells());
			var delta = mxClipboard.insertCount * mxClipboard.STEPSIZE;
			var parent = graph.getDefaultParent();
			cells = graph.importCells(cells, delta, delta, parent);
			
			// Increments the counter and selects the inserted cells
			mxClipboard.insertCount++;
			graph.setSelectionCells(cells);
		}
		
		return cells;
	}

};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxWindow
 * 
 * Basic window inside a document.
 * 
 * Examples:
 * 
 * Creating a simple window.
 *
 * (code)
 * var tb = document.createElement('div');
 * var wnd = new mxWindow('Title', tb, 100, 100, 200, 200, true, true);
 * wnd.setVisible(true); 
 * (end)
 *
 * Creating a window that contains an iframe. 
 * 
 * (code)
 * var frame = document.createElement('iframe');
 * frame.setAttribute('width', '192px');
 * frame.setAttribute('height', '172px');
 * frame.setAttribute('src', 'http://www.example.com/');
 * frame.style.backgroundColor = 'white';
 * 
 * var w = document.body.clientWidth;
 * var h = (document.body.clientHeight || document.documentElement.clientHeight);
 * var wnd = new mxWindow('Title', frame, (w-200)/2, (h-200)/3, 200, 200);
 * wnd.setVisible(true);
 * (end)
 * 
 * To limit the movement of a window, eg. to keep it from being moved beyond
 * the top, left corner the following method can be overridden (recommended):
 * 
 * (code)
 * wnd.setLocation = function(x, y)
 * {
 *   x = Math.max(0, x);
 *   y = Math.max(0, y);
 *   mxWindow.prototype.setLocation.apply(this, arguments);
 * };
 * (end)
 * 
 * Or the following event handler can be used:
 * 
 * (code)
 * wnd.addListener(mxEvent.MOVE, function(e)
 * {
 *   wnd.setLocation(Math.max(0, wnd.getX()), Math.max(0, wnd.getY()));
 * });
 * (end)
 * 
 * To keep a window inside the current window:
 * 
 * (code)
 * mxEvent.addListener(window, 'resize', mxUtils.bind(this, function()
 * {
 *   var iw = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
 *   var ih = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
 *   
 *   var x = this.window.getX();
 *   var y = this.window.getY();
 *   
 *   if (x + this.window.table.clientWidth > iw)
 *   {
 *     x = Math.max(0, iw - this.window.table.clientWidth);
 *   }
 *   
 *   if (y + this.window.table.clientHeight > ih)
 *   {
 *     y = Math.max(0, ih - this.window.table.clientHeight);
 *   }
 *   
 *   if (this.window.getX() != x || this.window.getY() != y)
 *   {
 *     this.window.setLocation(x, y);
 *   }
 * }));
 * (end)
 *
 * Event: mxEvent.MOVE_START
 *
 * Fires before the window is moved. The <code>event</code> property contains
 * the corresponding mouse event.
 *
 * Event: mxEvent.MOVE
 *
 * Fires while the window is being moved. The <code>event</code> property
 * contains the corresponding mouse event.
 *
 * Event: mxEvent.MOVE_END
 *
 * Fires after the window is moved. The <code>event</code> property contains
 * the corresponding mouse event.
 *
 * Event: mxEvent.RESIZE_START
 *
 * Fires before the window is resized. The <code>event</code> property contains
 * the corresponding mouse event.
 *
 * Event: mxEvent.RESIZE
 *
 * Fires while the window is being resized. The <code>event</code> property
 * contains the corresponding mouse event.
 *
 * Event: mxEvent.RESIZE_END
 *
 * Fires after the window is resized. The <code>event</code> property contains
 * the corresponding mouse event.
 *
 * Event: mxEvent.MAXIMIZE
 * 
 * Fires after the window is maximized. The <code>event</code> property
 * contains the corresponding mouse event.
 * 
 * Event: mxEvent.MINIMIZE
 * 
 * Fires after the window is minimized. The <code>event</code> property
 * contains the corresponding mouse event.
 * 
 * Event: mxEvent.NORMALIZE
 * 
 * Fires after the window is normalized, that is, it returned from
 * maximized or minimized state. The <code>event</code> property contains the
 * corresponding mouse event.
 *  
 * Event: mxEvent.ACTIVATE
 * 
 * Fires after a window is activated. The <code>previousWindow</code> property
 * contains the previous window. The event sender is the active window.
 * 
 * Event: mxEvent.SHOW
 * 
 * Fires after the window is shown. This event has no properties.
 * 
 * Event: mxEvent.HIDE
 * 
 * Fires after the window is hidden. This event has no properties.
 * 
 * Event: mxEvent.CLOSE
 * 
 * Fires before the window is closed. The <code>event</code> property contains
 * the corresponding mouse event.
 * 
 * Event: mxEvent.DESTROY
 * 
 * Fires before the window is destroyed. This event has no properties.
 * 
 * Constructor: mxWindow
 * 
 * Constructs a new window with the given dimension and title to display
 * the specified content. The window elements use the given style as a
 * prefix for the classnames of the respective window elements, namely,
 * the window title and window pane. The respective postfixes are appended
 * to the given stylename as follows:
 * 
 *   style - Base style for the window.
 *   style+Title - Style for the window title.
 *   style+Pane - Style for the window pane.
 * 
 * The default value for style is mxWindow, resulting in the following
 * classnames for the window elements: mxWindow, mxWindowTitle and
 * mxWindowPane.
 * 
 * If replaceNode is given then the window replaces the given DOM node in
 * the document.
 * 
 * Parameters:
 * 
 * title - String that represents the title of the new window.
 * content - DOM node that is used as the window content.
 * x - X-coordinate of the window location.
 * y - Y-coordinate of the window location.
 * width - Width of the window.
 * height - Optional height of the window. Default is to match the height
 * of the content at the specified width.
 * minimizable - Optional boolean indicating if the window is minimizable.
 * Default is true.
 * movable - Optional boolean indicating if the window is movable. Default
 * is true.
 * replaceNode - Optional DOM node that the window should replace.
 * style - Optional base classname for the window elements. Default is
 * mxWindow.
 */
function mxWindow(title, content, x, y, width, height, minimizable, movable, replaceNode, style)
{
	if (content != null)
	{
		minimizable = (minimizable != null) ? minimizable : true;
		this.content = content;
		this.init(x, y, width, height, style);
		
		this.installMaximizeHandler();
		this.installMinimizeHandler();
		this.installCloseHandler();
		this.setMinimizable(minimizable);
		this.setTitle(title);
		
		if (movable == null || movable)
		{
			this.installMoveHandler();
		}

		if (replaceNode != null && replaceNode.parentNode != null)
		{
			replaceNode.parentNode.replaceChild(this.div, replaceNode);
		}
		else
		{
			document.body.appendChild(this.div);
		}
	}
};

/**
 * Extends mxEventSource.
 */
mxWindow.prototype = new mxEventSource();
mxWindow.prototype.constructor = mxWindow;

/**
 * Variable: closeImage
 * 
 * URL of the image to be used for the close icon in the titlebar.
 */
mxWindow.prototype.closeImage = mxClient.imageBasePath + '/close.gif';

/**
 * Variable: minimizeImage
 * 
 * URL of the image to be used for the minimize icon in the titlebar.
 */
mxWindow.prototype.minimizeImage = mxClient.imageBasePath + '/minimize.gif';
	
/**
 * Variable: normalizeImage
 * 
 * URL of the image to be used for the normalize icon in the titlebar.
 */
mxWindow.prototype.normalizeImage = mxClient.imageBasePath + '/normalize.gif';
	
/**
 * Variable: maximizeImage
 * 
 * URL of the image to be used for the maximize icon in the titlebar.
 */
mxWindow.prototype.maximizeImage = mxClient.imageBasePath + '/maximize.gif';

/**
 * Variable: normalizeImage
 * 
 * URL of the image to be used for the resize icon.
 */
mxWindow.prototype.resizeImage = mxClient.imageBasePath + '/resize.gif';

/**
 * Variable: visible
 * 
 * Boolean flag that represents the visible state of the window.
 */
mxWindow.prototype.visible = false;

/**
 * Variable: minimumSize
 * 
 * <mxRectangle> that specifies the minimum width and height of the window.
 * Default is (50, 40).
 */
mxWindow.prototype.minimumSize = new mxRectangle(0, 0, 50, 40);

/**
 * Variable: destroyOnClose
 * 
 * Specifies if the window should be destroyed when it is closed. If this
 * is false then the window is hidden using <setVisible>. Default is true.
 */
mxWindow.prototype.destroyOnClose = true;

/**
 * Variable: contentHeightCorrection
 * 
 * Defines the correction factor for computing the height of the contentWrapper.
 * Default is 6 for IE 7/8 standards mode and 2 for all other browsers and modes.
 */
mxWindow.prototype.contentHeightCorrection = (document.documentMode == 8 || document.documentMode == 7) ? 6 : 2;

/**
 * Variable: title
 * 
 * Reference to the DOM node (TD) that contains the title.
 */
mxWindow.prototype.title = null;

/**
 * Variable: content
 * 
 * Reference to the DOM node that represents the window content.
 */
mxWindow.prototype.content = null;

/**
 * Function: init
 * 
 * Initializes the DOM tree that represents the window.
 */
mxWindow.prototype.init = function(x, y, width, height, style)
{
	style = (style != null) ? style : 'mxWindow';
	
	this.div = document.createElement('div');
	this.div.className = style;

	this.div.style.left = x + 'px';
	this.div.style.top = y + 'px';
	this.table = document.createElement('table');
	this.table.className = style;

	// Disables built-in pan and zoom in IE10 and later
	if (mxClient.IS_POINTER)
	{
		this.div.style.touchAction = 'none';
	}
	
	// Workaround for table size problems in FF
	if (width != null)
	{
		if (!mxClient.IS_QUIRKS)
		{
			this.div.style.width = width + 'px'; 
		}
		
		this.table.style.width = width + 'px';
	} 
	
	if (height != null)
	{
		if (!mxClient.IS_QUIRKS)
		{
			this.div.style.height = height + 'px';
		}
		
		this.table.style.height = height + 'px';
	}		
	
	// Creates title row
	var tbody = document.createElement('tbody');
	var tr = document.createElement('tr');
	
	this.title = document.createElement('td');
	this.title.className = style + 'Title';
	
	this.buttons = document.createElement('div');
	this.buttons.style.position = 'absolute';
	this.buttons.style.display = 'inline-block';
	this.buttons.style.right = '4px';
	this.buttons.style.top = '5px';
	this.title.appendChild(this.buttons);
	
	tr.appendChild(this.title);
	tbody.appendChild(tr);
	
	// Creates content row and table cell
	tr = document.createElement('tr');
	this.td = document.createElement('td');
	this.td.className = style + 'Pane';
	
	if (document.documentMode == 7)
	{
		this.td.style.height = '100%';
	}

	this.contentWrapper = document.createElement('div');
	this.contentWrapper.className = style + 'Pane';
	this.contentWrapper.style.width = '100%';
	this.contentWrapper.appendChild(this.content);

	// Workaround for div around div restricts height
	// of inner div if outerdiv has hidden overflow
	if (mxClient.IS_QUIRKS || this.content.nodeName.toUpperCase() != 'DIV')
	{
		this.contentWrapper.style.height = '100%';
	}

	// Puts all content into the DOM
	this.td.appendChild(this.contentWrapper);
	tr.appendChild(this.td);
	tbody.appendChild(tr);
	this.table.appendChild(tbody);
	this.div.appendChild(this.table);
	
	// Puts the window on top of other windows when clicked
	var activator = mxUtils.bind(this, function(evt)
	{
		this.activate();
	});
	
	mxEvent.addGestureListeners(this.title, activator);
	mxEvent.addGestureListeners(this.table, activator);

	this.hide();
};

/**
 * Function: setTitle
 * 
 * Sets the window title to the given string. HTML markup inside the title
 * will be escaped.
 */
mxWindow.prototype.setTitle = function(title)
{
	// Removes all text content nodes (normally just one)
	var child = this.title.firstChild;
	
	while (child != null)
	{
		var next = child.nextSibling;
		
		if (child.nodeType == mxConstants.NODETYPE_TEXT)
		{
			child.parentNode.removeChild(child);
		}
		
		child = next;
	}
	
	mxUtils.write(this.title, title || '');
	this.title.appendChild(this.buttons);
};

/**
 * Function: setScrollable
 * 
 * Sets if the window contents should be scrollable.
 */
mxWindow.prototype.setScrollable = function(scrollable)
{
	// Workaround for hang in Presto 2.5.22 (Opera 10.5)
	if (navigator.userAgent.indexOf('Presto/2.5') < 0)
	{
		if (scrollable)
		{
			this.contentWrapper.style.overflow = 'auto';
		}
		else
		{
			this.contentWrapper.style.overflow = 'hidden';
		}
	}
};

/**
 * Function: activate
 * 
 * Puts the window on top of all other windows.
 */
mxWindow.prototype.activate = function()
{
	if (mxWindow.activeWindow != this)
	{
		var style = mxUtils.getCurrentStyle(this.getElement());
		var index = (style != null) ? style.zIndex : 3;

		if (mxWindow.activeWindow)
		{
			var elt = mxWindow.activeWindow.getElement();
			
			if (elt != null && elt.style != null)
			{
				elt.style.zIndex = index;
			}
		}
		
		var previousWindow = mxWindow.activeWindow;
		this.getElement().style.zIndex = parseInt(index) + 1;
		mxWindow.activeWindow = this;
		
		this.fireEvent(new mxEventObject(mxEvent.ACTIVATE, 'previousWindow', previousWindow));
	}
};

/**
 * Function: getElement
 * 
 * Returuns the outermost DOM node that makes up the window.
 */
mxWindow.prototype.getElement = function()
{
	return this.div;
};

/**
 * Function: fit
 * 
 * Makes sure the window is inside the client area of the window.
 */
mxWindow.prototype.fit = function()
{
	mxUtils.fit(this.div);
};

/**
 * Function: isResizable
 * 
 * Returns true if the window is resizable.
 */
mxWindow.prototype.isResizable = function()
{
	if (this.resize != null)
	{
		return this.resize.style.display != 'none';
	}
	
	return false;
};

/**
 * Function: setResizable
 * 
 * Sets if the window should be resizable. To avoid interference with some
 * built-in features of IE10 and later, the use of the following code is
 * recommended if there are resizable <mxWindow>s in the page:
 * 
 * (code)
 * if (mxClient.IS_POINTER)
 * {
 *   document.body.style.msTouchAction = 'none';
 * }
 * (end)
 */
mxWindow.prototype.setResizable = function(resizable)
{
	if (resizable)
	{
		if (this.resize == null)
		{
			this.resize = document.createElement('img');
			this.resize.style.position = 'absolute';
			this.resize.style.bottom = '2px';
			this.resize.style.right = '2px';

			this.resize.setAttribute('src', mxClient.imageBasePath + '/resize.gif');
			this.resize.style.cursor = 'nw-resize';
			
			var startX = null;
			var startY = null;
			var width = null;
			var height = null;
			
			var start = mxUtils.bind(this, function(evt)
			{
				// LATER: pointerdown starting on border of resize does start
				// the drag operation but does not fire consecutive events via
				// one of the listeners below (does pan instead).
				// Workaround: document.body.style.msTouchAction = 'none'
				this.activate();
				startX = mxEvent.getClientX(evt);
				startY = mxEvent.getClientY(evt);
				width = this.div.offsetWidth;
				height = this.div.offsetHeight;
				
				mxEvent.addGestureListeners(document, null, dragHandler, dropHandler);
				this.fireEvent(new mxEventObject(mxEvent.RESIZE_START, 'event', evt));
				mxEvent.consume(evt);
			});

			// Adds a temporary pair of listeners to intercept
			// the gesture event in the document
			var dragHandler = mxUtils.bind(this, function(evt)
			{
				if (startX != null && startY != null)
				{
					var dx = mxEvent.getClientX(evt) - startX;
					var dy = mxEvent.getClientY(evt) - startY;
	
					this.setSize(width + dx, height + dy);
	
					this.fireEvent(new mxEventObject(mxEvent.RESIZE, 'event', evt));
					mxEvent.consume(evt);
				}
			});
			
			var dropHandler = mxUtils.bind(this, function(evt)
			{
				if (startX != null && startY != null)
				{
					startX = null;
					startY = null;
					mxEvent.removeGestureListeners(document, null, dragHandler, dropHandler);
					this.fireEvent(new mxEventObject(mxEvent.RESIZE_END, 'event', evt));
					mxEvent.consume(evt);
				}
			});
			
			mxEvent.addGestureListeners(this.resize, start, dragHandler, dropHandler);
			this.div.appendChild(this.resize);
		}
		else 
		{
			this.resize.style.display = 'inline';
		}
	}
	else if (this.resize != null)
	{
		this.resize.style.display = 'none';
	}
};
	
/**
 * Function: setSize
 * 
 * Sets the size of the window.
 */
mxWindow.prototype.setSize = function(width, height)
{
	width = Math.max(this.minimumSize.width, width);
	height = Math.max(this.minimumSize.height, height);

	// Workaround for table size problems in FF
	if (!mxClient.IS_QUIRKS)
	{
		this.div.style.width =  width + 'px';
		this.div.style.height = height + 'px';
	}
	
	this.table.style.width =  width + 'px';
	this.table.style.height = height + 'px';

	if (!mxClient.IS_QUIRKS)
	{
		this.contentWrapper.style.height = (this.div.offsetHeight -
			this.title.offsetHeight - this.contentHeightCorrection) + 'px';
	}
};
	
/**
 * Function: setMinimizable
 * 
 * Sets if the window is minimizable.
 */
mxWindow.prototype.setMinimizable = function(minimizable)
{
	this.minimize.style.display = (minimizable) ? '' : 'none';
};

/**
 * Function: getMinimumSize
 * 
 * Returns an <mxRectangle> that specifies the size for the minimized window.
 * A width or height of 0 means keep the existing width or height. This
 * implementation returns the height of the window title and keeps the width.
 */
mxWindow.prototype.getMinimumSize = function()
{
	return new mxRectangle(0, 0, 0, this.title.offsetHeight);
};

/**
 * Function: installMinimizeHandler
 * 
 * Installs the event listeners required for minimizing the window.
 */
mxWindow.prototype.installMinimizeHandler = function()
{
	this.minimize = document.createElement('img');
	
	this.minimize.setAttribute('src', this.minimizeImage);
	this.minimize.setAttribute('title', 'Minimize');
	this.minimize.style.cursor = 'pointer';
	this.minimize.style.marginLeft = '2px';
	this.minimize.style.display = 'none';
	
	this.buttons.appendChild(this.minimize);
	
	var minimized = false;
	var maxDisplay = null;
	var height = null;

	var funct = mxUtils.bind(this, function(evt)
	{
		this.activate();
		
		if (!minimized)
		{
			minimized = true;
			
			this.minimize.setAttribute('src', this.normalizeImage);
			this.minimize.setAttribute('title', 'Normalize');
			this.contentWrapper.style.display = 'none';
			maxDisplay = this.maximize.style.display;
			
			this.maximize.style.display = 'none';
			height = this.table.style.height;
			
			var minSize = this.getMinimumSize();
			
			if (minSize.height > 0)
			{
				if (!mxClient.IS_QUIRKS)
				{
					this.div.style.height = minSize.height + 'px';
				}
				
				this.table.style.height = minSize.height + 'px';
			}
			
			if (minSize.width > 0)
			{
				if (!mxClient.IS_QUIRKS)
				{
					this.div.style.width = minSize.width + 'px';
				}
				
				this.table.style.width = minSize.width + 'px';
			}
			
			if (this.resize != null)
			{
				this.resize.style.visibility = 'hidden';
			}
			
			this.fireEvent(new mxEventObject(mxEvent.MINIMIZE, 'event', evt));
		}
		else
		{
			minimized = false;
			
			this.minimize.setAttribute('src', this.minimizeImage);
			this.minimize.setAttribute('title', 'Minimize');
			this.contentWrapper.style.display = ''; // default
			this.maximize.style.display = maxDisplay;
			
			if (!mxClient.IS_QUIRKS)
			{
				this.div.style.height = height;
			}
			
			this.table.style.height = height;

			if (this.resize != null)
			{
				this.resize.style.visibility = '';
			}
			
			this.fireEvent(new mxEventObject(mxEvent.NORMALIZE, 'event', evt));
		}
		
		mxEvent.consume(evt);
	});
	
	mxEvent.addGestureListeners(this.minimize, funct);
};
	
/**
 * Function: setMaximizable
 * 
 * Sets if the window is maximizable.
 */
mxWindow.prototype.setMaximizable = function(maximizable)
{
	this.maximize.style.display = (maximizable) ? '' : 'none';
};

/**
 * Function: installMaximizeHandler
 * 
 * Installs the event listeners required for maximizing the window.
 */
mxWindow.prototype.installMaximizeHandler = function()
{
	this.maximize = document.createElement('img');
	
	this.maximize.setAttribute('src', this.maximizeImage);
	this.maximize.setAttribute('title', 'Maximize');
	this.maximize.style.cursor = 'default';
	this.maximize.style.marginLeft = '2px';
	this.maximize.style.cursor = 'pointer';
	this.maximize.style.display = 'none';
	
	this.buttons.appendChild(this.maximize);
	
	var maximized = false;
	var x = null;
	var y = null;
	var height = null;
	var width = null;
	var minDisplay = null;

	var funct = mxUtils.bind(this, function(evt)
	{
		this.activate();
		
		if (this.maximize.style.display != 'none')
		{
			if (!maximized)
			{
				maximized = true;
				
				this.maximize.setAttribute('src', this.normalizeImage);
				this.maximize.setAttribute('title', 'Normalize');
				this.contentWrapper.style.display = '';
				minDisplay = this.minimize.style.display;
				this.minimize.style.display = 'none';
				
				// Saves window state
				x = parseInt(this.div.style.left);
				y = parseInt(this.div.style.top);
				height = this.table.style.height;
				width = this.table.style.width;

				this.div.style.left = '0px';
				this.div.style.top = '0px';
				var docHeight = Math.max(document.body.clientHeight || 0, document.documentElement.clientHeight || 0);

				if (!mxClient.IS_QUIRKS)
				{
					this.div.style.width = (document.body.clientWidth - 2) + 'px';
					this.div.style.height = (docHeight - 2) + 'px';
				}

				this.table.style.width = (document.body.clientWidth - 2) + 'px';
				this.table.style.height = (docHeight - 2) + 'px';
				
				if (this.resize != null)
				{
					this.resize.style.visibility = 'hidden';
				}

				if (!mxClient.IS_QUIRKS)
				{
					var style = mxUtils.getCurrentStyle(this.contentWrapper);
		
					if (style.overflow == 'auto' || this.resize != null)
					{
						this.contentWrapper.style.height = (this.div.offsetHeight -
							this.title.offsetHeight - this.contentHeightCorrection) + 'px';
					}
				}

				this.fireEvent(new mxEventObject(mxEvent.MAXIMIZE, 'event', evt));
			}
			else
			{
				maximized = false;
				
				this.maximize.setAttribute('src', this.maximizeImage);
				this.maximize.setAttribute('title', 'Maximize');
				this.contentWrapper.style.display = '';
				this.minimize.style.display = minDisplay;

				// Restores window state
				this.div.style.left = x+'px';
				this.div.style.top = y+'px';
				
				if (!mxClient.IS_QUIRKS)
				{
					this.div.style.height = height;
					this.div.style.width = width;

					var style = mxUtils.getCurrentStyle(this.contentWrapper);
		
					if (style.overflow == 'auto' || this.resize != null)
					{
						this.contentWrapper.style.height = (this.div.offsetHeight -
							this.title.offsetHeight - this.contentHeightCorrection) + 'px';
					}
				}
				
				this.table.style.height = height;
				this.table.style.width = width;

				if (this.resize != null)
				{
					this.resize.style.visibility = '';
				}
				
				this.fireEvent(new mxEventObject(mxEvent.NORMALIZE, 'event', evt));
			}
			
			mxEvent.consume(evt);
		}
	});
	
	mxEvent.addGestureListeners(this.maximize, funct);
	mxEvent.addListener(this.title, 'dblclick', funct);
};
	
/**
 * Function: installMoveHandler
 * 
 * Installs the event listeners required for moving the window.
 */
mxWindow.prototype.installMoveHandler = function()
{
	this.title.style.cursor = 'move';
	
	mxEvent.addGestureListeners(this.title,
		mxUtils.bind(this, function(evt)
		{
			var startX = mxEvent.getClientX(evt);
			var startY = mxEvent.getClientY(evt);
			var x = this.getX();
			var y = this.getY();
						
			// Adds a temporary pair of listeners to intercept
			// the gesture event in the document
			var dragHandler = mxUtils.bind(this, function(evt)
			{
				var dx = mxEvent.getClientX(evt) - startX;
				var dy = mxEvent.getClientY(evt) - startY;
				this.setLocation(x + dx, y + dy);
				this.fireEvent(new mxEventObject(mxEvent.MOVE, 'event', evt));
				mxEvent.consume(evt);
			});
			
			var dropHandler = mxUtils.bind(this, function(evt)
			{
				mxEvent.removeGestureListeners(document, null, dragHandler, dropHandler);
				this.fireEvent(new mxEventObject(mxEvent.MOVE_END, 'event', evt));
				mxEvent.consume(evt);
			});
			
			mxEvent.addGestureListeners(document, null, dragHandler, dropHandler);
			this.fireEvent(new mxEventObject(mxEvent.MOVE_START, 'event', evt));
			mxEvent.consume(evt);
		}));
	
	// Disables built-in pan and zoom in IE10 and later
	if (mxClient.IS_POINTER)
	{
		this.title.style.touchAction = 'none';
	}
};

/**
 * Function: setLocation
 * 
 * Sets the upper, left corner of the window.
 */
 mxWindow.prototype.setLocation = function(x, y)
 {
	this.div.style.left = x + 'px';
	this.div.style.top = y + 'px';
 };

/**
 * Function: getX
 *
 * Returns the current position on the x-axis.
 */
mxWindow.prototype.getX = function()
{
	return parseInt(this.div.style.left);
};

/**
 * Function: getY
 *
 * Returns the current position on the y-axis.
 */
mxWindow.prototype.getY = function()
{
	return parseInt(this.div.style.top);
};

/**
 * Function: installCloseHandler
 *
 * Adds the <closeImage> as a new image node in <closeImg> and installs the
 * <close> event.
 */
mxWindow.prototype.installCloseHandler = function()
{
	this.closeImg = document.createElement('img');
	
	this.closeImg.setAttribute('src', this.closeImage);
	this.closeImg.setAttribute('title', 'Close');
	this.closeImg.style.marginLeft = '2px';
	this.closeImg.style.cursor = 'pointer';
	this.closeImg.style.display = 'none';
	
	this.buttons.appendChild(this.closeImg);

	mxEvent.addGestureListeners(this.closeImg,
		mxUtils.bind(this, function(evt)
		{
			this.fireEvent(new mxEventObject(mxEvent.CLOSE, 'event', evt));
			
			if (this.destroyOnClose)
			{
				this.destroy();
			}
			else
			{
				this.setVisible(false);
			}
			
			mxEvent.consume(evt);
		}));
};

/**
 * Function: setImage
 * 
 * Sets the image associated with the window.
 * 
 * Parameters:
 * 
 * image - URL of the image to be used.
 */
mxWindow.prototype.setImage = function(image)
{
	this.image = document.createElement('img');
	this.image.setAttribute('src', image);
	this.image.setAttribute('align', 'left');
	this.image.style.marginRight = '4px';
	this.image.style.marginLeft = '0px';
	this.image.style.marginTop = '-2px';
	
	this.title.insertBefore(this.image, this.title.firstChild);
};

/**
 * Function: setClosable
 * 
 * Sets the image associated with the window.
 * 
 * Parameters:
 * 
 * closable - Boolean specifying if the window should be closable.
 */
mxWindow.prototype.setClosable = function(closable)
{
	this.closeImg.style.display = (closable) ? '' : 'none';
};

/**
 * Function: isVisible
 * 
 * Returns true if the window is visible.
 */
mxWindow.prototype.isVisible = function()
{
	if (this.div != null)
	{
		return this.div.style.display != 'none';
	}
	
	return false;
};

/**
 * Function: setVisible
 *
 * Shows or hides the window depending on the given flag.
 * 
 * Parameters:
 * 
 * visible - Boolean indicating if the window should be made visible.
 */
mxWindow.prototype.setVisible = function(visible)
{
	if (this.div != null && this.isVisible() != visible)
	{
		if (visible)
		{
			this.show();
		}
		else
		{
			this.hide();
		}
	}
};

/**
 * Function: show
 *
 * Shows the window.
 */
mxWindow.prototype.show = function()
{
	this.div.style.display = '';
	this.activate();
	
	var style = mxUtils.getCurrentStyle(this.contentWrapper);
	
	if (!mxClient.IS_QUIRKS && (style.overflow == 'auto' || this.resize != null))
	{
		this.contentWrapper.style.height = (this.div.offsetHeight -
				this.title.offsetHeight - this.contentHeightCorrection) + 'px';
	}
	
	this.fireEvent(new mxEventObject(mxEvent.SHOW));
};

/**
 * Function: hide
 *
 * Hides the window.
 */
mxWindow.prototype.hide = function()
{
	this.div.style.display = 'none';
	this.fireEvent(new mxEventObject(mxEvent.HIDE));
};

/**
 * Function: destroy
 *
 * Destroys the window and removes all associated resources. Fires a
 * <destroy> event prior to destroying the window.
 */
mxWindow.prototype.destroy = function()
{
	this.fireEvent(new mxEventObject(mxEvent.DESTROY));
	
	if (this.div != null)
	{
		mxEvent.release(this.div);
		this.div.parentNode.removeChild(this.div);
		this.div = null;
	}
	
	this.title = null;
	this.content = null;
	this.contentWrapper = null;
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxForm
 * 
 * A simple class for creating HTML forms.
 * 
 * Constructor: mxForm
 * 
 * Creates a HTML table using the specified classname.
 */
function mxForm(className)
{
	this.table = document.createElement('table');
	this.table.className = className;
	this.body = document.createElement('tbody');
	
	this.table.appendChild(this.body);
};

/**
 * Variable: table
 * 
 * Holds the DOM node that represents the table.
 */
mxForm.prototype.table = null;

/**
 * Variable: body
 * 
 * Holds the DOM node that represents the tbody (table body). New rows
 * can be added to this object using DOM API.
 */
mxForm.prototype.body = false;

/**
 * Function: getTable
 * 
 * Returns the table that contains this form.
 */
mxForm.prototype.getTable = function()
{
	return this.table;
};

/**
 * Function: addButtons
 * 
 * Helper method to add an OK and Cancel button using the respective
 * functions.
 */
mxForm.prototype.addButtons = function(okFunct, cancelFunct)
{
	var tr = document.createElement('tr');
	var td = document.createElement('td');
	tr.appendChild(td);
	td = document.createElement('td');

	// Adds the ok button
	var button = document.createElement('button');
	mxUtils.write(button, mxResources.get('ok') || 'OK');
	td.appendChild(button);

	mxEvent.addListener(button, 'click', function()
	{
		okFunct();
	});
	
	// Adds the cancel button
	button = document.createElement('button');
	mxUtils.write(button, mxResources.get('cancel') || 'Cancel');
	td.appendChild(button);
	
	mxEvent.addListener(button, 'click', function()
	{
		cancelFunct();
	});
	
	tr.appendChild(td);
	this.body.appendChild(tr);
};

/**
 * Function: addText
 * 
 * Adds an input for the given name, type and value and returns it.
 */
mxForm.prototype.addText = function(name, value, type)
{
	var input = document.createElement('input');
	
	input.setAttribute('type', type || 'text');
	input.value = value;
	
	return this.addField(name, input);
};

/**
 * Function: addCheckbox
 * 
 * Adds a checkbox for the given name and value and returns the textfield.
 */
mxForm.prototype.addCheckbox = function(name, value)
{
	var input = document.createElement('input');
	
	input.setAttribute('type', 'checkbox');
	this.addField(name, input);

	// IE can only change the checked value if the input is inside the DOM
	if (value)
	{
		input.checked = true;
	}

	return input;
};

/**
 * Function: addTextarea
 * 
 * Adds a textarea for the given name and value and returns the textarea.
 */
mxForm.prototype.addTextarea = function(name, value, rows)
{
	var input = document.createElement('textarea');
	
	if (mxClient.IS_NS)
	{
		rows--;
	}
	
	input.setAttribute('rows', rows || 2);
	input.value = value;
	
	return this.addField(name, input);
};

/**
 * Function: addCombo
 * 
 * Adds a combo for the given name and returns the combo.
 */
mxForm.prototype.addCombo = function(name, isMultiSelect, size)
{
	var select = document.createElement('select');
	
	if (size != null)
	{
		select.setAttribute('size', size);
	}
	
	if (isMultiSelect)
	{
		select.setAttribute('multiple', 'true');
	}
	
	return this.addField(name, select);
};

/**
 * Function: addOption
 * 
 * Adds an option for the given label to the specified combo.
 */
mxForm.prototype.addOption = function(combo, label, value, isSelected)
{
	var option = document.createElement('option');
	
	mxUtils.writeln(option, label);
	option.setAttribute('value', value);
	
	if (isSelected)
	{
		option.setAttribute('selected', isSelected);
	}
	
	combo.appendChild(option);
};

/**
 * Function: addField
 * 
 * Adds a new row with the name and the input field in two columns and
 * returns the given input.
 */
mxForm.prototype.addField = function(name, input)
{
	var tr = document.createElement('tr');
	var td = document.createElement('td');
	mxUtils.write(td, name);
	tr.appendChild(td);
	
	td = document.createElement('td');
	td.appendChild(input);
	tr.appendChild(td);
	this.body.appendChild(tr);
	
	return input;
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxImage
 *
 * Encapsulates the URL, width and height of an image.
 * 
 * Constructor: mxImage
 * 
 * Constructs a new image.
 */
function mxImage(src, width, height)
{
	this.src = src;
	this.width = width;
	this.height = height;
};

/**
 * Variable: src
 *
 * String that specifies the URL of the image.
 */
mxImage.prototype.src = null;

/**
 * Variable: width
 *
 * Integer that specifies the width of the image.
 */
mxImage.prototype.width = null;

/**
 * Variable: height
 *
 * Integer that specifies the height of the image.
 */
mxImage.prototype.height = null;
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxDivResizer
 * 
 * Maintains the size of a div element in Internet Explorer. This is a
 * workaround for the right and bottom style being ignored in IE.
 * 
 * If you need a div to cover the scrollwidth and -height of a document,
 * then you can use this class as follows:
 * 
 * (code)
 * var resizer = new mxDivResizer(background);
 * resizer.getDocumentHeight = function()
 * {
 *   return document.body.scrollHeight;
 * }
 * resizer.getDocumentWidth = function()
 * {
 *   return document.body.scrollWidth;
 * }
 * resizer.resize();
 * (end)
 * 
 * Constructor: mxDivResizer
 * 
 * Constructs an object that maintains the size of a div
 * element when the window is being resized. This is only
 * required for Internet Explorer as it ignores the respective
 * stylesheet information for DIV elements.
 * 
 * Parameters:
 * 
 * div - Reference to the DOM node whose size should be maintained.
 * container - Optional Container that contains the div. Default is the
 * window.
 */
function mxDivResizer(div, container)
{
	if (div.nodeName.toLowerCase() == 'div')
	{
		if (container == null)
		{
			container = window;
		}

		this.div = div;
		var style = mxUtils.getCurrentStyle(div);
		
		if (style != null)
		{
			this.resizeWidth = style.width == 'auto';
			this.resizeHeight = style.height == 'auto';
		}
		
		mxEvent.addListener(container, 'resize',
			mxUtils.bind(this, function(evt)
			{
				if (!this.handlingResize)
				{
					this.handlingResize = true;
					this.resize();
					this.handlingResize = false;
				}
			})
		);
		
		this.resize();
	}
};

/**
 * Function: resizeWidth
 * 
 * Boolean specifying if the width should be updated.
 */
mxDivResizer.prototype.resizeWidth = true;

/**
 * Function: resizeHeight
 * 
 * Boolean specifying if the height should be updated.
 */
mxDivResizer.prototype.resizeHeight = true;

/**
 * Function: handlingResize
 * 
 * Boolean specifying if the width should be updated.
 */
mxDivResizer.prototype.handlingResize = false;

/**
 * Function: resize
 * 
 * Updates the style of the DIV after the window has been resized.
 */
mxDivResizer.prototype.resize = function()
{
	var w = this.getDocumentWidth();
	var h = this.getDocumentHeight();

	var l = parseInt(this.div.style.left);
	var r = parseInt(this.div.style.right);
	var t = parseInt(this.div.style.top);
	var b = parseInt(this.div.style.bottom);
	
	if (this.resizeWidth &&
		!isNaN(l) &&
		!isNaN(r) &&
		l >= 0 &&
		r >= 0 &&
		w - r - l > 0)
	{
		this.div.style.width = (w - r - l)+'px';
	}
	
	if (this.resizeHeight &&
		!isNaN(t) &&
		!isNaN(b) &&
		t >= 0 &&
		b >= 0 &&
		h - t - b > 0)
	{
		this.div.style.height = (h - t - b)+'px';
	}
};

/**
 * Function: getDocumentWidth
 * 
 * Hook for subclassers to return the width of the document (without
 * scrollbars).
 */
mxDivResizer.prototype.getDocumentWidth = function()
{
	return document.body.clientWidth;
};

/**
 * Function: getDocumentHeight
 * 
 * Hook for subclassers to return the height of the document (without
 * scrollbars).
 */
mxDivResizer.prototype.getDocumentHeight = function()
{
	return document.body.clientHeight;
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxDragSource
 * 
 * Wrapper to create a drag source from a DOM element so that the element can
 * be dragged over a graph and dropped into the graph as a new cell.
 * 
 * Problem is that in the dropHandler the current preview location is not
 * available, so the preview and the dropHandler must match.
 * 
 * Constructor: mxDragSource
 * 
 * Constructs a new drag source for the given element.
 */
function mxDragSource(element, dropHandler)
{
	this.element = element;
	this.dropHandler = dropHandler;
	
	// Handles a drag gesture on the element
	mxEvent.addGestureListeners(element, mxUtils.bind(this, function(evt)
	{
		this.mouseDown(evt);
	}));
	
	// Prevents native drag and drop
	mxEvent.addListener(element, 'dragstart', function(evt)
	{
		mxEvent.consume(evt);
	});
	
	this.eventConsumer = function(sender, evt)
	{
		var evtName = evt.getProperty('eventName');
		var me = evt.getProperty('event');
		
		if (evtName != mxEvent.MOUSE_DOWN)
		{
			me.consume();
		}
	};
};

/**
 * Variable: element
 *
 * Reference to the DOM node which was made draggable.
 */
mxDragSource.prototype.element = null;

/**
 * Variable: dropHandler
 *
 * Holds the DOM node that is used to represent the drag preview. If this is
 * null then the source element will be cloned and used for the drag preview.
 */
mxDragSource.prototype.dropHandler = null;

/**
 * Variable: dragOffset
 *
 * <mxPoint> that specifies the offset of the <dragElement>. Default is null.
 */
mxDragSource.prototype.dragOffset = null;

/**
 * Variable: dragElement
 *
 * Holds the DOM node that is used to represent the drag preview. If this is
 * null then the source element will be cloned and used for the drag preview.
 */
mxDragSource.prototype.dragElement = null;

/**
 * Variable: previewElement
 *
 * Optional <mxRectangle> that specifies the unscaled size of the preview.
 */
mxDragSource.prototype.previewElement = null;

/**
 * Variable: enabled
 *
 * Specifies if this drag source is enabled. Default is true.
 */
mxDragSource.prototype.enabled = true;

/**
 * Variable: currentGraph
 *
 * Reference to the <mxGraph> that is the current drop target.
 */
mxDragSource.prototype.currentGraph = null;

/**
 * Variable: currentDropTarget
 *
 * Holds the current drop target under the mouse.
 */
mxDragSource.prototype.currentDropTarget = null;

/**
 * Variable: currentPoint
 *
 * Holds the current drop location.
 */
mxDragSource.prototype.currentPoint = null;

/**
 * Variable: currentGuide
 *
 * Holds an <mxGuide> for the <currentGraph> if <dragPreview> is not null.
 */
mxDragSource.prototype.currentGuide = null;

/**
 * Variable: currentGuide
 *
 * Holds an <mxGuide> for the <currentGraph> if <dragPreview> is not null.
 */
mxDragSource.prototype.currentHighlight = null;

/**
 * Variable: autoscroll
 *
 * Specifies if the graph should scroll automatically. Default is true.
 */
mxDragSource.prototype.autoscroll = true;

/**
 * Variable: guidesEnabled
 *
 * Specifies if <mxGuide> should be enabled. Default is true.
 */
mxDragSource.prototype.guidesEnabled = true;

/**
 * Variable: gridEnabled
 *
 * Specifies if the grid should be allowed. Default is true.
 */
mxDragSource.prototype.gridEnabled = true;

/**
 * Variable: highlightDropTargets
 *
 * Specifies if drop targets should be highlighted. Default is true.
 */
mxDragSource.prototype.highlightDropTargets = true;

/**
 * Variable: dragElementZIndex
 * 
 * ZIndex for the drag element. Default is 100.
 */
mxDragSource.prototype.dragElementZIndex = 100;

/**
 * Variable: dragElementOpacity
 * 
 * Opacity of the drag element in %. Default is 70.
 */
mxDragSource.prototype.dragElementOpacity = 70;

/**
 * Function: isEnabled
 * 
 * Returns <enabled>.
 */
mxDragSource.prototype.isEnabled = function()
{
	return this.enabled;
};

/**
 * Function: setEnabled
 * 
 * Sets <enabled>.
 */
mxDragSource.prototype.setEnabled = function(value)
{
	this.enabled = value;
};

/**
 * Function: isGuidesEnabled
 * 
 * Returns <guidesEnabled>.
 */
mxDragSource.prototype.isGuidesEnabled = function()
{
	return this.guidesEnabled;
};

/**
 * Function: setGuidesEnabled
 * 
 * Sets <guidesEnabled>.
 */
mxDragSource.prototype.setGuidesEnabled = function(value)
{
	this.guidesEnabled = value;
};

/**
 * Function: isGridEnabled
 * 
 * Returns <gridEnabled>.
 */
mxDragSource.prototype.isGridEnabled = function()
{
	return this.gridEnabled;
};

/**
 * Function: setGridEnabled
 * 
 * Sets <gridEnabled>.
 */
mxDragSource.prototype.setGridEnabled = function(value)
{
	this.gridEnabled = value;
};

/**
 * Function: getGraphForEvent
 * 
 * Returns the graph for the given mouse event. This implementation returns
 * null.
 */
mxDragSource.prototype.getGraphForEvent = function(evt)
{
	return null;
};

/**
 * Function: getDropTarget
 * 
 * Returns the drop target for the given graph and coordinates. This
 * implementation uses <mxGraph.getCellAt>.
 */
mxDragSource.prototype.getDropTarget = function(graph, x, y, evt)
{
	return graph.getCellAt(x, y);
};

/**
 * Function: createDragElement
 * 
 * Creates and returns a clone of the <dragElementPrototype> or the <element>
 * if the former is not defined.
 */
mxDragSource.prototype.createDragElement = function(evt)
{
	return this.element.cloneNode(true);
};

/**
 * Function: createPreviewElement
 * 
 * Creates and returns an element which can be used as a preview in the given
 * graph.
 */
mxDragSource.prototype.createPreviewElement = function(graph)
{
	return null;
};

/**
 * Function: isActive
 * 
 * Returns true if this drag source is active.
 */
mxDragSource.prototype.isActive = function()
{
	return this.mouseMoveHandler != null;
};

/**
 * Function: reset
 * 
 * Stops and removes everything and restores the state of the object.
 */
mxDragSource.prototype.reset = function()
{
	if (this.currentGraph != null)
	{
		this.dragExit(this.currentGraph);
		this.currentGraph = null;
	}
	
	this.removeDragElement();
	this.removeListeners();
	this.stopDrag();
};

/**
 * Function: mouseDown
 * 
 * Returns the drop target for the given graph and coordinates. This
 * implementation uses <mxGraph.getCellAt>.
 * 
 * To ignore popup menu events for a drag source, this function can be
 * overridden as follows.
 * 
 * (code)
 * var mouseDown = dragSource.mouseDown;
 * 
 * dragSource.mouseDown = function(evt)
 * {
 *   if (!mxEvent.isPopupTrigger(evt))
 *   {
 *     mouseDown.apply(this, arguments);
 *   }
 * };
 * (end)
 */
mxDragSource.prototype.mouseDown = function(evt)
{
	if (this.enabled && !mxEvent.isConsumed(evt) && this.mouseMoveHandler == null)
	{
		this.startDrag(evt);
		this.mouseMoveHandler = mxUtils.bind(this, this.mouseMove);
		this.mouseUpHandler = mxUtils.bind(this, this.mouseUp);		
		mxEvent.addGestureListeners(document, null, this.mouseMoveHandler, this.mouseUpHandler);
		
		if (mxClient.IS_TOUCH && !mxEvent.isMouseEvent(evt))
		{
			this.eventSource = mxEvent.getSource(evt);
			mxEvent.addGestureListeners(this.eventSource, null, this.mouseMoveHandler, this.mouseUpHandler);
		}
	}
};

/**
 * Function: startDrag
 * 
 * Creates the <dragElement> using <createDragElement>.
 */
mxDragSource.prototype.startDrag = function(evt)
{
	this.dragElement = this.createDragElement(evt);
	this.dragElement.style.position = 'absolute';
	this.dragElement.style.zIndex = this.dragElementZIndex;
	mxUtils.setOpacity(this.dragElement, this.dragElementOpacity);
};

/**
 * Function: stopDrag
 * 
 * Invokes <removeDragElement>.
 */
mxDragSource.prototype.stopDrag = function()
{
	// LATER: This used to have a mouse event. If that is still needed we need to add another
	// final call to the DnD protocol to add a cleanup step in the case of escape press, which
	// is not associated with a mouse event and which currently calles this method.
	this.removeDragElement();
};

/**
 * Function: removeDragElement
 * 
 * Removes and destroys the <dragElement>.
 */
mxDragSource.prototype.removeDragElement = function()
{
	if (this.dragElement != null)
	{
		if (this.dragElement.parentNode != null)
		{
			this.dragElement.parentNode.removeChild(this.dragElement);
		}
		
		this.dragElement = null;
	}
};

/**
 * Function: graphContainsEvent
 * 
 * Returns true if the given graph contains the given event.
 */
mxDragSource.prototype.graphContainsEvent = function(graph, evt)
{
	var x = mxEvent.getClientX(evt);
	var y = mxEvent.getClientY(evt);
	var offset = mxUtils.getOffset(graph.container);
	var origin = mxUtils.getScrollOrigin();

	// Checks if event is inside the bounds of the graph container
	return x >= offset.x - origin.x && y >= offset.y - origin.y &&
		x <= offset.x - origin.x + graph.container.offsetWidth &&
		y <= offset.y - origin.y + graph.container.offsetHeight;
};

/**
 * Function: mouseMove
 * 
 * Gets the graph for the given event using <getGraphForEvent>, updates the
 * <currentGraph>, calling <dragEnter> and <dragExit> on the new and old graph,
 * respectively, and invokes <dragOver> if <currentGraph> is not null.
 */
mxDragSource.prototype.mouseMove = function(evt)
{
	var graph = this.getGraphForEvent(evt);
	
	// Checks if event is inside the bounds of the graph container
	if (graph != null && !this.graphContainsEvent(graph, evt))
	{
		graph = null;
	}

	if (graph != this.currentGraph)
	{
		if (this.currentGraph != null)
		{
			this.dragExit(this.currentGraph, evt);
		}
		
		this.currentGraph = graph;
		
		if (this.currentGraph != null)
		{
			this.dragEnter(this.currentGraph, evt);
		}
	}
	
	if (this.currentGraph != null)
	{
		this.dragOver(this.currentGraph, evt);
	}

	if (this.dragElement != null && (this.previewElement == null || this.previewElement.style.visibility != 'visible'))
	{
		var x = mxEvent.getClientX(evt);
		var y = mxEvent.getClientY(evt);
		
		if (this.dragElement.parentNode == null)
		{
			document.body.appendChild(this.dragElement);
		}

		this.dragElement.style.visibility = 'visible';
		
		if (this.dragOffset != null)
		{
			x += this.dragOffset.x;
			y += this.dragOffset.y;
		}
		
		var offset = mxUtils.getDocumentScrollOrigin(document);
		
		this.dragElement.style.left = (x + offset.x) + 'px';
		this.dragElement.style.top = (y + offset.y) + 'px';
	}
	else if (this.dragElement != null)
	{
		this.dragElement.style.visibility = 'hidden';
	}
	
	mxEvent.consume(evt);
};

/**
 * Function: mouseUp
 * 
 * Processes the mouse up event and invokes <drop>, <dragExit> and <stopDrag>
 * as required.
 */
mxDragSource.prototype.mouseUp = function(evt)
{
	if (this.currentGraph != null)
	{
		if (this.currentPoint != null && (this.previewElement == null ||
			this.previewElement.style.visibility != 'hidden'))
		{
			var scale = this.currentGraph.view.scale;
			var tr = this.currentGraph.view.translate;
			var x = this.currentPoint.x / scale - tr.x;
			var y = this.currentPoint.y / scale - tr.y;
			
			this.drop(this.currentGraph, evt, this.currentDropTarget, x, y);
		}
		
		this.dragExit(this.currentGraph);
		this.currentGraph = null;
	}

	this.stopDrag();
	this.removeListeners();
	
	mxEvent.consume(evt);
};

/**
 * Function: removeListeners
 * 
 * Actives the given graph as a drop target.
 */
mxDragSource.prototype.removeListeners = function()
{
	if (this.eventSource != null)
	{
		mxEvent.removeGestureListeners(this.eventSource, null, this.mouseMoveHandler, this.mouseUpHandler);
		this.eventSource = null;
	}
	
	mxEvent.removeGestureListeners(document, null, this.mouseMoveHandler, this.mouseUpHandler);
	this.mouseMoveHandler = null;
	this.mouseUpHandler = null;
};

/**
 * Function: dragEnter
 * 
 * Actives the given graph as a drop target.
 */
mxDragSource.prototype.dragEnter = function(graph, evt)
{
	graph.isMouseDown = true;
	graph.isMouseTrigger = mxEvent.isMouseEvent(evt);
	this.previewElement = this.createPreviewElement(graph);
	
	// Guide is only needed if preview element is used
	if (this.isGuidesEnabled() && this.previewElement != null)
	{
		this.currentGuide = new mxGuide(graph, graph.graphHandler.getGuideStates());
	}
	
	if (this.highlightDropTargets)
	{
		this.currentHighlight = new mxCellHighlight(graph, mxConstants.DROP_TARGET_COLOR);
	}
	
	// Consumes all events in the current graph before they are fired
	graph.addListener(mxEvent.FIRE_MOUSE_EVENT, this.eventConsumer);
};

/**
 * Function: dragExit
 * 
 * Deactivates the given graph as a drop target.
 */
mxDragSource.prototype.dragExit = function(graph, evt)
{
	this.currentDropTarget = null;
	this.currentPoint = null;
	graph.isMouseDown = false;
	
	// Consumes all events in the current graph before they are fired
	graph.removeListener(this.eventConsumer);
	
	if (this.previewElement != null)
	{
		if (this.previewElement.parentNode != null)
		{
			this.previewElement.parentNode.removeChild(this.previewElement);
		}
		
		this.previewElement = null;
	}
	
	if (this.currentGuide != null)
	{
		this.currentGuide.destroy();
		this.currentGuide = null;
	}
	
	if (this.currentHighlight != null)
	{
		this.currentHighlight.destroy();
		this.currentHighlight = null;
	}
};

/**
 * Function: dragOver
 * 
 * Implements autoscroll, updates the <currentPoint>, highlights any drop
 * targets and updates the preview.
 */
mxDragSource.prototype.dragOver = function(graph, evt)
{
	var offset = mxUtils.getOffset(graph.container);
	var origin = mxUtils.getScrollOrigin(graph.container);
	var x = mxEvent.getClientX(evt) - offset.x + origin.x - graph.panDx;
	var y = mxEvent.getClientY(evt) - offset.y + origin.y - graph.panDy;

	if (graph.autoScroll && (this.autoscroll == null || this.autoscroll))
	{
		graph.scrollPointToVisible(x, y, graph.autoExtend);
	}

	// Highlights the drop target under the mouse
	if (this.currentHighlight != null && graph.isDropEnabled())
	{
		this.currentDropTarget = this.getDropTarget(graph, x, y, evt);
		var state = graph.getView().getState(this.currentDropTarget);
		this.currentHighlight.highlight(state);
	}

	// Updates the location of the preview
	if (this.previewElement != null)
	{
		if (this.previewElement.parentNode == null)
		{
			graph.container.appendChild(this.previewElement);
			
			this.previewElement.style.zIndex = '3';
			this.previewElement.style.position = 'absolute';
		}
		
		var gridEnabled = this.isGridEnabled() && graph.isGridEnabledEvent(evt);
		var hideGuide = true;

		// Grid and guides
		if (this.currentGuide != null && this.currentGuide.isEnabledForEvent(evt))
		{
			// LATER: HTML preview appears smaller than SVG preview
			var w = parseInt(this.previewElement.style.width);
			var h = parseInt(this.previewElement.style.height);
			var bounds = new mxRectangle(0, 0, w, h);
			var delta = new mxPoint(x, y);
			delta = this.currentGuide.move(bounds, delta, gridEnabled);
			hideGuide = false;
			x = delta.x;
			y = delta.y;
		}
		else if (gridEnabled)
		{
			var scale = graph.view.scale;
			var tr = graph.view.translate;
			var off = graph.gridSize / 2;
			x = (graph.snap(x / scale - tr.x - off) + tr.x) * scale;
			y = (graph.snap(y / scale - tr.y - off) + tr.y) * scale;
		}
		
		if (this.currentGuide != null && hideGuide)
		{
			this.currentGuide.hide();
		}
		
		if (this.previewOffset != null)
		{
			x += this.previewOffset.x;
			y += this.previewOffset.y;
		}

		this.previewElement.style.left = Math.round(x) + 'px';
		this.previewElement.style.top = Math.round(y) + 'px';
		this.previewElement.style.visibility = 'visible';
	}
	
	this.currentPoint = new mxPoint(x, y);
};

/**
 * Function: drop
 * 
 * Returns the drop target for the given graph and coordinates. This
 * implementation uses <mxGraph.getCellAt>.
 */
mxDragSource.prototype.drop = function(graph, evt, dropTarget, x, y)
{
	this.dropHandler(graph, evt, dropTarget, x, y);
	
	// Had to move this to after the insert because it will
	// affect the scrollbars of the window in IE to try and
	// make the complete container visible.
	// LATER: Should be made optional.
	if (graph.container.style.visibility != 'hidden')
	{
		graph.container.focus();
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxToolbar
 * 
 * Creates a toolbar inside a given DOM node. The toolbar may contain icons,
 * buttons and combo boxes.
 * 
 * Event: mxEvent.SELECT
 * 
 * Fires when an item was selected in the toolbar. The <code>function</code>
 * property contains the function that was selected in <selectMode>.
 * 
 * Constructor: mxToolbar
 * 
 * Constructs a toolbar in the specified container.
 *
 * Parameters:
 *
 * container - DOM node that contains the toolbar.
 */
function mxToolbar(container)
{
	this.container = container;
};

/**
 * Extends mxEventSource.
 */
mxToolbar.prototype = new mxEventSource();
mxToolbar.prototype.constructor = mxToolbar;

/**
 * Variable: container
 * 
 * Reference to the DOM nodes that contains the toolbar.
 */
mxToolbar.prototype.container = null;

/**
 * Variable: enabled
 * 
 * Specifies if events are handled. Default is true.
 */
mxToolbar.prototype.enabled = true;

/**
 * Variable: noReset
 * 
 * Specifies if <resetMode> requires a forced flag of true for resetting
 * the current mode in the toolbar. Default is false. This is set to true
 * if the toolbar item is double clicked to avoid a reset after a single
 * use of the item.
 */
mxToolbar.prototype.noReset = false;

/**
 * Variable: updateDefaultMode
 * 
 * Boolean indicating if the default mode should be the last selected
 * switch mode or the first inserted switch mode. Default is true, that
 * is the last selected switch mode is the default mode. The default mode
 * is the mode to be selected after a reset of the toolbar. If this is
 * false, then the default mode is the first inserted mode item regardless
 * of what was last selected. Otherwise, the selected item after a reset is
 * the previously selected item.
 */
mxToolbar.prototype.updateDefaultMode = true;

/**
 * Function: addItem
 * 
 * Adds the given function as an image with the specified title and icon
 * and returns the new image node.
 * 
 * Parameters:
 * 
 * title - Optional string that is used as the tooltip.
 * icon - Optional URL of the image to be used. If no URL is given, then a
 * button is created.
 * funct - Function to execute on a mouse click.
 * pressedIcon - Optional URL of the pressed image. Default is a gray
 * background.
 * style - Optional style classname. Default is mxToolbarItem.
 * factoryMethod - Optional factory method for popup menu, eg.
 * function(menu, evt, cell) { menu.addItem('Hello, World!'); }
 */
mxToolbar.prototype.addItem = function(title, icon, funct, pressedIcon, style, factoryMethod)
{
	var img = document.createElement((icon != null) ? 'img' : 'button');
	var initialClassName = style || ((factoryMethod != null) ?
			'mxToolbarMode' : 'mxToolbarItem');
	img.className = initialClassName;
	img.setAttribute('src', icon);
	
	if (title != null)
	{
		if (icon != null)
		{
			img.setAttribute('title', title);
		}
		else
		{
			mxUtils.write(img, title);
		}
	}
	
	this.container.appendChild(img);

	// Invokes the function on a click on the toolbar item
	if (funct != null)
	{
		mxEvent.addListener(img, 'click', funct);
		
		if (mxClient.IS_TOUCH)
		{
			mxEvent.addListener(img, 'touchend', funct);
		}
	}

	var mouseHandler = mxUtils.bind(this, function(evt)
	{
		if (pressedIcon != null)
		{
			img.setAttribute('src', icon);
		}
		else
		{
			img.style.backgroundColor = '';
		}
	});

	// Highlights the toolbar item with a gray background
	// while it is being clicked with the mouse
	mxEvent.addGestureListeners(img, mxUtils.bind(this, function(evt)
	{
		if (pressedIcon != null)
		{
			img.setAttribute('src', pressedIcon);
		}
		else
		{
			img.style.backgroundColor = 'gray';
		}
		
		// Popup Menu
		if (factoryMethod != null)
		{
			if (this.menu == null)
			{
				this.menu = new mxPopupMenu();
				this.menu.init();
			}
			
			var last = this.currentImg;
			
			if (this.menu.isMenuShowing())
			{
				this.menu.hideMenu();
			}
			
			if (last != img)
			{
				// Redirects factory method to local factory method
				this.currentImg = img;
				this.menu.factoryMethod = factoryMethod;
				
				var point = new mxPoint(
					img.offsetLeft,
					img.offsetTop + img.offsetHeight);
				this.menu.popup(point.x, point.y, null, evt);

				// Sets and overrides to restore classname
				if (this.menu.isMenuShowing())
				{
					img.className = initialClassName + 'Selected';
					
					this.menu.hideMenu = function()
					{
						mxPopupMenu.prototype.hideMenu.apply(this);
						img.className = initialClassName;
						this.currentImg = null;
					};
				}
			}
		}
	}), null, mouseHandler);

	mxEvent.addListener(img, 'mouseout', mouseHandler);
	
	return img;
};

/**
 * Function: addCombo
 * 
 * Adds and returns a new SELECT element using the given style. The element
 * is placed inside a DIV with the mxToolbarComboContainer style classname.
 * 
 * Parameters:
 * 
 * style - Optional style classname. Default is mxToolbarCombo.
 */
mxToolbar.prototype.addCombo = function(style)
{
	var div = document.createElement('div');
	div.style.display = 'inline';
	div.className = 'mxToolbarComboContainer';
	
	var select = document.createElement('select');
	select.className = style || 'mxToolbarCombo';
	div.appendChild(select);
	
	this.container.appendChild(div);
	
	return select;
};

/**
 * Function: addCombo
 * 
 * Adds and returns a new SELECT element using the given title as the
 * default element. The selection is reset to this element after each
 * change.
 * 
 * Parameters:
 * 
 * title - String that specifies the title of the default element.
 * style - Optional style classname. Default is mxToolbarCombo.
 */
mxToolbar.prototype.addActionCombo = function(title, style)
{
	var select = document.createElement('select');
	select.className = style || 'mxToolbarCombo';
	this.addOption(select, title, null);
	
	mxEvent.addListener(select, 'change', function(evt)
	{
		var value = select.options[select.selectedIndex];
		select.selectedIndex = 0;
		
		if (value.funct != null)
		{
			value.funct(evt);
		}
	});
	
	this.container.appendChild(select);
	
	return select;
};

/**
 * Function: addOption
 * 
 * Adds and returns a new OPTION element inside the given SELECT element.
 * If the given value is a function then it is stored in the option's funct
 * field.
 * 
 * Parameters:
 * 
 * combo - SELECT element that will contain the new entry.
 * title - String that specifies the title of the option.
 * value - Specifies the value associated with this option.
 */
mxToolbar.prototype.addOption = function(combo, title, value)
{
	var option = document.createElement('option');
	mxUtils.writeln(option, title);
	
	if (typeof(value) == 'function')
	{
		option.funct = value;
	}
	else
	{
		option.setAttribute('value', value);
	}
	
	combo.appendChild(option);
	
	return option;
};

/**
 * Function: addSwitchMode
 * 
 * Adds a new selectable item to the toolbar. Only one switch mode item may
 * be selected at a time. The currently selected item is the default item
 * after a reset of the toolbar.
 */
mxToolbar.prototype.addSwitchMode = function(title, icon, funct, pressedIcon, style)
{
	var img = document.createElement('img');
	img.initialClassName = style || 'mxToolbarMode';
	img.className = img.initialClassName;
	img.setAttribute('src', icon);
	img.altIcon = pressedIcon;
	
	if (title != null)
	{
		img.setAttribute('title', title);
	}
	
	mxEvent.addListener(img, 'click', mxUtils.bind(this, function(evt)
	{
		var tmp = this.selectedMode.altIcon;
		
		if (tmp != null)
		{
			this.selectedMode.altIcon = this.selectedMode.getAttribute('src');
			this.selectedMode.setAttribute('src', tmp);
		}
		else
		{
			this.selectedMode.className = this.selectedMode.initialClassName;
		}
		
		if (this.updateDefaultMode)
		{
			this.defaultMode = img;
		}
		
		this.selectedMode = img;
		
		var tmp = img.altIcon;
		
		if (tmp != null)
		{
			img.altIcon = img.getAttribute('src');
			img.setAttribute('src', tmp);
		}
		else
		{
			img.className = img.initialClassName+'Selected';
		}
		
		this.fireEvent(new mxEventObject(mxEvent.SELECT));
		funct();
	}));
	
	this.container.appendChild(img);
	
	if (this.defaultMode == null)
	{
		this.defaultMode = img;
		
		// Function should fire only once so
		// do not pass it with the select event
		this.selectMode(img);
		funct();
	}
	
	return img;
};

/**
 * Function: addMode
 * 
 * Adds a new item to the toolbar. The selection is typically reset after
 * the item has been consumed, for example by adding a new vertex to the
 * graph. The reset is not carried out if the item is double clicked.
 * 
 * The function argument uses the following signature: funct(evt, cell) where
 * evt is the native mouse event and cell is the cell under the mouse.
 */
mxToolbar.prototype.addMode = function(title, icon, funct, pressedIcon, style, toggle)
{
	toggle = (toggle != null) ? toggle : true;
	var img = document.createElement((icon != null) ? 'img' : 'button');
	
	img.initialClassName = style || 'mxToolbarMode';
	img.className = img.initialClassName;
	img.setAttribute('src', icon);
	img.altIcon = pressedIcon;

	if (title != null)
	{
		img.setAttribute('title', title);
	}
	
	if (this.enabled && toggle)
	{
		mxEvent.addListener(img, 'click', mxUtils.bind(this, function(evt)
		{
			this.selectMode(img, funct);
			this.noReset = false;
		}));
		
		mxEvent.addListener(img, 'dblclick', mxUtils.bind(this, function(evt)
		{
			this.selectMode(img, funct);
			this.noReset = true;
		}));
		
		if (this.defaultMode == null)
		{
			this.defaultMode = img;
			this.defaultFunction = funct;
			this.selectMode(img, funct);
		}
	}

	this.container.appendChild(img);					

	return img;
};

/**
 * Function: selectMode
 * 
 * Resets the state of the previously selected mode and displays the given
 * DOM node as selected. This function fires a select event with the given
 * function as a parameter.
 */
mxToolbar.prototype.selectMode = function(domNode, funct)
{
	if (this.selectedMode != domNode)
	{
		if (this.selectedMode != null)
		{
			var tmp = this.selectedMode.altIcon;
			
			if (tmp != null)
			{
				this.selectedMode.altIcon = this.selectedMode.getAttribute('src');
				this.selectedMode.setAttribute('src', tmp);
			}
			else
			{
				this.selectedMode.className = this.selectedMode.initialClassName;
			}
		}
		
		this.selectedMode = domNode;
		var tmp = this.selectedMode.altIcon;
		
		if (tmp != null)
		{
			this.selectedMode.altIcon = this.selectedMode.getAttribute('src');
			this.selectedMode.setAttribute('src', tmp);
		}
		else
		{
			this.selectedMode.className = this.selectedMode.initialClassName+'Selected';
		}
		
		this.fireEvent(new mxEventObject(mxEvent.SELECT, "function", funct));
	}
};

/**
 * Function: resetMode
 * 
 * Selects the default mode and resets the state of the previously selected
 * mode.
 */
mxToolbar.prototype.resetMode = function(forced)
{
	if ((forced || !this.noReset) && this.selectedMode != this.defaultMode)
	{
		// The last selected switch mode will be activated
		// so the function was already executed and is
		// no longer required here
		this.selectMode(this.defaultMode, this.defaultFunction);
	}
};

/**
 * Function: addSeparator
 * 
 * Adds the specifies image as a separator.
 * 
 * Parameters:
 * 
 * icon - URL of the separator icon.
 */
mxToolbar.prototype.addSeparator = function(icon)
{
	return this.addItem(null, icon, null);
};

/**
 * Function: addBreak
 * 
 * Adds a break to the container.
 */
mxToolbar.prototype.addBreak = function()
{
	mxUtils.br(this.container);
};

/**
 * Function: addLine
 * 
 * Adds a horizontal line to the container.
 */
mxToolbar.prototype.addLine = function()
{
	var hr = document.createElement('hr');
	
	hr.style.marginRight = '6px';
	hr.setAttribute('size', '1');
	
	this.container.appendChild(hr);
};

/**
 * Function: destroy
 * 
 * Removes the toolbar and all its associated resources.
 */
mxToolbar.prototype.destroy = function ()
{
	mxEvent.release(this.container);
	this.container = null;
	this.defaultMode = null;
	this.defaultFunction = null;
	this.selectedMode = null;
	
	if (this.menu != null)
	{
		this.menu.destroy();
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxUndoableEdit
 * 
 * Implements a composite undoable edit. Here is an example for a custom change
 * which gets executed via the model:
 * 
 * (code)
 * function CustomChange(model, name)
 * {
 *   this.model = model;
 *   this.name = name;
 *   this.previous = name;
 * };
 * 
 * CustomChange.prototype.execute = function()
 * {
 *   var tmp = this.model.name;
 *   this.model.name = this.previous;
 *   this.previous = tmp;
 * };
 * 
 * var name = prompt('Enter name');
 * graph.model.execute(new CustomChange(graph.model, name));
 * (end)
 * 
 * Event: mxEvent.EXECUTED
 * 
 * Fires between START_EDIT and END_EDIT after an atomic change was executed.
 * The <code>change</code> property contains the change that was executed.
 * 
 * Event: mxEvent.START_EDIT
 * 
 * Fires before a set of changes will be executed in <undo> or <redo>.
 * This event contains no properties.
 * 
 * Event: mxEvent.END_EDIT
 *
 * Fires after a set of changeswas executed in <undo> or <redo>.
 * This event contains no properties.
 * 
 * Constructor: mxUndoableEdit
 * 
 * Constructs a new undoable edit for the given source.
 */
function mxUndoableEdit(source, significant)
{
	this.source = source;
	this.changes = [];
	this.significant = (significant != null) ? significant : true;
};

/**
 * Variable: source
 * 
 * Specifies the source of the edit.
 */
mxUndoableEdit.prototype.source = null;

/**
 * Variable: changes
 * 
 * Array that contains the changes that make up this edit. The changes are
 * expected to either have an undo and redo function, or an execute
 * function. Default is an empty array.
 */
mxUndoableEdit.prototype.changes = null;

/**
 * Variable: significant
 * 
 * Specifies if the undoable change is significant.
 * Default is true.
 */
mxUndoableEdit.prototype.significant = null;

/**
 * Variable: undone
 * 
 * Specifies if this edit has been undone. Default is false.
 */
mxUndoableEdit.prototype.undone = false;

/**
 * Variable: redone
 * 
 * Specifies if this edit has been redone. Default is false.
 */
mxUndoableEdit.prototype.redone = false;

/**
 * Function: isEmpty
 * 
 * Returns true if the this edit contains no changes.
 */
mxUndoableEdit.prototype.isEmpty = function()
{
	return this.changes.length == 0;
};

/**
 * Function: isSignificant
 * 
 * Returns <significant>.
 */
mxUndoableEdit.prototype.isSignificant = function()
{
	return this.significant;
};

/**
 * Function: add
 * 
 * Adds the specified change to this edit. The change is an object that is
 * expected to either have an undo and redo, or an execute function.
 */
mxUndoableEdit.prototype.add = function(change)
{
	this.changes.push(change);
};

/**
 * Function: notify
 * 
 * Hook to notify any listeners of the changes after an <undo> or <redo>
 * has been carried out. This implementation is empty.
 */
mxUndoableEdit.prototype.notify = function() { };

/**
 * Function: die
 * 
 * Hook to free resources after the edit has been removed from the command
 * history. This implementation is empty.
 */
mxUndoableEdit.prototype.die = function() { };

/**
 * Function: undo
 * 
 * Undoes all changes in this edit.
 */
mxUndoableEdit.prototype.undo = function()
{
	if (!this.undone)
	{
		this.source.fireEvent(new mxEventObject(mxEvent.START_EDIT));
		var count = this.changes.length;
		
		for (var i = count - 1; i >= 0; i--)
		{
			var change = this.changes[i];
			
			if (change.execute != null)
			{
				change.execute();
			}
			else if (change.undo != null)
			{
				change.undo();
			}
			
			// New global executed event
			this.source.fireEvent(new mxEventObject(mxEvent.EXECUTED, 'change', change));
		}
		
		this.undone = true;
		this.redone = false;
		this.source.fireEvent(new mxEventObject(mxEvent.END_EDIT));
	}
	
	this.notify();
};

/**
 * Function: redo
 * 
 * Redoes all changes in this edit.
 */
mxUndoableEdit.prototype.redo = function()
{
	if (!this.redone)
	{
		this.source.fireEvent(new mxEventObject(mxEvent.START_EDIT));
		var count = this.changes.length;
		
		for (var i = 0; i < count; i++)
		{
			var change = this.changes[i];
			
			if (change.execute != null)
			{
				change.execute();
			}
			else if (change.redo != null)
			{
				change.redo();
			}
			
			// New global executed event
			this.source.fireEvent(new mxEventObject(mxEvent.EXECUTED, 'change', change));
		}
		
		this.undone = false;
		this.redone = true;
		this.source.fireEvent(new mxEventObject(mxEvent.END_EDIT));
	}
	
	this.notify();
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxUndoManager
 *
 * Implements a command history. When changing the graph model, an
 * <mxUndoableChange> object is created at the start of the transaction (when
 * model.beginUpdate is called). All atomic changes are then added to this
 * object until the last model.endUpdate call, at which point the
 * <mxUndoableEdit> is dispatched in an event, and added to the history inside
 * <mxUndoManager>. This is done by an event listener in
 * <mxEditor.installUndoHandler>.
 * 
 * Each atomic change of the model is represented by an object (eg.
 * <mxRootChange>, <mxChildChange>, <mxTerminalChange> etc) which contains the
 * complete undo information. The <mxUndoManager> also listens to the
 * <mxGraphView> and stores it's changes to the current root as insignificant
 * undoable changes, so that drilling (step into, step up) is undone.
 * 
 * This means when you execute an atomic change on the model, then change the
 * current root on the view and click undo, the change of the root will be
 * undone together with the change of the model so that the display represents
 * the state at which the model was changed. However, these changes are not
 * transmitted for sharing as they do not represent a state change.
 *
 * Example:
 * 
 * When adding an undo manager to a graph, make sure to add it
 * to the model and the view as well to maintain a consistent
 * display across multiple undo/redo steps.
 *
 * (code)
 * var undoManager = new mxUndoManager();
 * var listener = function(sender, evt)
 * {
 *   undoManager.undoableEditHappened(evt.getProperty('edit'));
 * };
 * graph.getModel().addListener(mxEvent.UNDO, listener);
 * graph.getView().addListener(mxEvent.UNDO, listener);
 * (end)
 * 
 * The code creates a function that informs the undoManager
 * of an undoable edit and binds it to the undo event of
 * <mxGraphModel> and <mxGraphView> using
 * <mxEventSource.addListener>.
 * 
 * Event: mxEvent.CLEAR
 * 
 * Fires after <clear> was invoked. This event has no properties.
 * 
 * Event: mxEvent.UNDO
 * 
 * Fires afer a significant edit was undone in <undo>. The <code>edit</code>
 * property contains the <mxUndoableEdit> that was undone.
 * 
 * Event: mxEvent.REDO
 * 
 * Fires afer a significant edit was redone in <redo>. The <code>edit</code>
 * property contains the <mxUndoableEdit> that was redone.
 * 
 * Event: mxEvent.ADD
 * 
 * Fires after an undoable edit was added to the history. The <code>edit</code>
 * property contains the <mxUndoableEdit> that was added.
 * 
 * Constructor: mxUndoManager
 *
 * Constructs a new undo manager with the given history size. If no history
 * size is given, then a default size of 100 steps is used.
 */
function mxUndoManager(size)
{
	this.size = (size != null) ? size : 100;
	this.clear();
};

/**
 * Extends mxEventSource.
 */
mxUndoManager.prototype = new mxEventSource();
mxUndoManager.prototype.constructor = mxUndoManager;

/**
 * Variable: size
 * 
 * Maximum command history size. 0 means unlimited history. Default is
 * 100.
 */
mxUndoManager.prototype.size = null;

/**
 * Variable: history
 * 
 * Array that contains the steps of the command history.
 */
mxUndoManager.prototype.history = null;

/**
 * Variable: indexOfNextAdd
 * 
 * Index of the element to be added next.
 */
mxUndoManager.prototype.indexOfNextAdd = 0;

/**
 * Function: isEmpty
 * 
 * Returns true if the history is empty.
 */
mxUndoManager.prototype.isEmpty = function()
{
	return this.history.length == 0;
};

/**
 * Function: clear
 * 
 * Clears the command history.
 */
mxUndoManager.prototype.clear = function()
{
	this.history = [];
	this.indexOfNextAdd = 0;
	this.fireEvent(new mxEventObject(mxEvent.CLEAR));
};

/**
 * Function: canUndo
 * 
 * Returns true if an undo is possible.
 */
mxUndoManager.prototype.canUndo = function()
{
	return this.indexOfNextAdd > 0;
};

/**
 * Function: undo
 * 
 * Undoes the last change.
 */
mxUndoManager.prototype.undo = function()
{
    while (this.indexOfNextAdd > 0)
    {
        var edit = this.history[--this.indexOfNextAdd];
        edit.undo();

		if (edit.isSignificant())
        {
        	this.fireEvent(new mxEventObject(mxEvent.UNDO, 'edit', edit));
            break;
        }
    }
};

/**
 * Function: canRedo
 * 
 * Returns true if a redo is possible.
 */
mxUndoManager.prototype.canRedo = function()
{
	return this.indexOfNextAdd < this.history.length;
};

/**
 * Function: redo
 * 
 * Redoes the last change.
 */
mxUndoManager.prototype.redo = function()
{
    var n = this.history.length;
    
    while (this.indexOfNextAdd < n)
    {
        var edit =  this.history[this.indexOfNextAdd++];
        edit.redo();
        
        if (edit.isSignificant())
        {
        	this.fireEvent(new mxEventObject(mxEvent.REDO, 'edit', edit));
            break;
        }
    }
};

/**
 * Function: undoableEditHappened
 * 
 * Method to be called to add new undoable edits to the <history>.
 */
mxUndoManager.prototype.undoableEditHappened = function(undoableEdit)
{
	this.trim();
	
	if (this.size > 0 &&
		this.size == this.history.length)
	{
		this.history.shift();
	}
	
	this.history.push(undoableEdit);
	this.indexOfNextAdd = this.history.length;
	this.fireEvent(new mxEventObject(mxEvent.ADD, 'edit', undoableEdit));
};

/**
 * Function: trim
 * 
 * Removes all pending steps after <indexOfNextAdd> from the history,
 * invoking die on each edit. This is called from <undoableEditHappened>.
 */
mxUndoManager.prototype.trim = function()
{
	if (this.history.length > this.indexOfNextAdd)
	{
		var edits = this.history.splice(this.indexOfNextAdd,
			this.history.length - this.indexOfNextAdd);
			
		for (var i = 0; i < edits.length; i++)
		{
			edits[i].die();
		}
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 *
 * Class: mxUrlConverter
 * 
 * Converts relative and absolute URLs to absolute URLs with protocol and domain.
 */
var mxUrlConverter = function()
{
	// Empty constructor
};

/**
 * Variable: enabled
 * 
 * Specifies if the converter is enabled. Default is true.
 */
mxUrlConverter.prototype.enabled = true;

/**
 * Variable: baseUrl
 * 
 * Specifies the base URL to be used as a prefix for relative URLs.
 */
mxUrlConverter.prototype.baseUrl = null;

/**
 * Variable: baseDomain
 * 
 * Specifies the base domain to be used as a prefix for absolute URLs.
 */
mxUrlConverter.prototype.baseDomain = null;

/**
 * Function: updateBaseUrl
 * 
 * Private helper function to update the base URL.
 */
mxUrlConverter.prototype.updateBaseUrl = function()
{
	this.baseDomain = location.protocol + '//' + location.host;
	this.baseUrl = this.baseDomain + location.pathname;
	var tmp = this.baseUrl.lastIndexOf('/');
	
	// Strips filename etc
	if (tmp > 0)
	{
		this.baseUrl = this.baseUrl.substring(0, tmp + 1);
	}
};

/**
 * Function: isEnabled
 * 
 * Returns <enabled>.
 */
mxUrlConverter.prototype.isEnabled = function()
{
	return this.enabled;
};

/**
 * Function: setEnabled
 * 
 * Sets <enabled>.
 */
mxUrlConverter.prototype.setEnabled = function(value)
{
	this.enabled = value;
};

/**
 * Function: getBaseUrl
 * 
 * Returns <baseUrl>.
 */
mxUrlConverter.prototype.getBaseUrl = function()
{
	return this.baseUrl;
};

/**
 * Function: setBaseUrl
 * 
 * Sets <baseUrl>.
 */
mxUrlConverter.prototype.setBaseUrl = function(value)
{
	this.baseUrl = value;
};

/**
 * Function: getBaseDomain
 * 
 * Returns <baseDomain>.
 */
mxUrlConverter.prototype.getBaseDomain = function()
{
	return this.baseDomain;
},

/**
 * Function: setBaseDomain
 * 
 * Sets <baseDomain>.
 */
mxUrlConverter.prototype.setBaseDomain = function(value)
{
	this.baseDomain = value;
},

/**
 * Function: isRelativeUrl
 * 
 * Returns true if the given URL is relative.
 */
mxUrlConverter.prototype.isRelativeUrl = function(url)
{
	return url.substring(0, 2) != '//' && url.substring(0, 7) != 'http://' && url.substring(0, 8) != 'https://' && url.substring(0, 10) != 'data:image';
};

/**
 * Function: convert
 * 
 * Converts the given URL to an absolute URL with protol and domain.
 * Relative URLs are first converted to absolute URLs.
 */
mxUrlConverter.prototype.convert = function(url)
{
	if (this.isEnabled() && this.isRelativeUrl(url))
	{
		if (this.getBaseUrl() == null)
		{
			this.updateBaseUrl();
		}
		
		if (url.charAt(0) == '/')
		{
			url = this.getBaseDomain() + url;
		}
		else
		{
			url = this.getBaseUrl() + url;
		}
	}
	
	return url;
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxPanningManager
 *
 * Implements a handler for panning.
 */
function mxPanningManager(graph)
{
	this.thread = null;
	this.active = false;
	this.tdx = 0;
	this.tdy = 0;
	this.t0x = 0;
	this.t0y = 0;
	this.dx = 0;
	this.dy = 0;
	this.scrollbars = false;
	this.scrollLeft = 0;
	this.scrollTop = 0;
	
	this.mouseListener =
	{
	    mouseDown: function(sender, me) { },
	    mouseMove: function(sender, me) { },
	    mouseUp: mxUtils.bind(this, function(sender, me)
	    {
	    	if (this.active)
	    	{
	    		this.stop();
	    	}
	    })
	};
	
	graph.addMouseListener(this.mouseListener);
	
	// Stops scrolling on every mouseup anywhere in the document
	mxEvent.addListener(document, 'mouseup', mxUtils.bind(this, function()
	{
    	if (this.active)
    	{
    		this.stop();
    	}
	}));
	
	var createThread = mxUtils.bind(this, function()
	{
    	this.scrollbars = mxUtils.hasScrollbars(graph.container);
    	this.scrollLeft = graph.container.scrollLeft;
    	this.scrollTop = graph.container.scrollTop;

    	return window.setInterval(mxUtils.bind(this, function()
		{
			this.tdx -= this.dx;
			this.tdy -= this.dy;

			if (this.scrollbars)
			{
				var left = -graph.container.scrollLeft - Math.ceil(this.dx);
				var top = -graph.container.scrollTop - Math.ceil(this.dy);
				graph.panGraph(left, top);
				graph.panDx = this.scrollLeft - graph.container.scrollLeft;
				graph.panDy = this.scrollTop - graph.container.scrollTop;
				graph.fireEvent(new mxEventObject(mxEvent.PAN));
				// TODO: Implement graph.autoExtend
			}
			else
			{
				graph.panGraph(this.getDx(), this.getDy());
			}
		}), this.delay);
	});
	
	this.isActive = function()
	{
		return active;
	};
	
	this.getDx = function()
	{
		return Math.round(this.tdx);
	};
	
	this.getDy = function()
	{
		return Math.round(this.tdy);
	};
	
	this.start = function()
	{
		this.t0x = graph.view.translate.x;
		this.t0y = graph.view.translate.y;
		this.active = true;
	};
	
	this.panTo = function(x, y, w, h)
	{
		if (!this.active)
		{
			this.start();
		}
		
    	this.scrollLeft = graph.container.scrollLeft;
    	this.scrollTop = graph.container.scrollTop;
		
		w = (w != null) ? w : 0;
		h = (h != null) ? h : 0;
		
		var c = graph.container;
		this.dx = x + w - c.scrollLeft - c.clientWidth;
		
		if (this.dx < 0 && Math.abs(this.dx) < this.border)
		{
			this.dx = this.border + this.dx;
		}
		else if (this.handleMouseOut)
		{
			this.dx = Math.max(this.dx, 0);
		}
		else
		{
			this.dx = 0;
		}
		
		if (this.dx == 0)
		{
			this.dx = x - c.scrollLeft;
			
			if (this.dx > 0 && this.dx < this.border)
			{
				this.dx = this.dx - this.border;
			}
			else if (this.handleMouseOut)
			{
				this.dx = Math.min(0, this.dx);
			}
			else
			{
				this.dx = 0;
			}
		}
		
		this.dy = y + h - c.scrollTop - c.clientHeight;

		if (this.dy < 0 && Math.abs(this.dy) < this.border)
		{
			this.dy = this.border + this.dy;
		}
		else if (this.handleMouseOut)
		{
			this.dy = Math.max(this.dy, 0);
		}
		else
		{
			this.dy = 0;
		}
		
		if (this.dy == 0)
		{
			this.dy = y - c.scrollTop;
			
			if (this.dy > 0 && this.dy < this.border)
			{
				this.dy = this.dy - this.border;
			}
			else if (this.handleMouseOut)
			{
				this.dy = Math.min(0, this.dy);
			} 
			else
			{
				this.dy = 0;
			}
		}
		
		if (this.dx != 0 || this.dy != 0)
		{
			this.dx *= this.damper;
			this.dy *= this.damper;
			
			if (this.thread == null)
			{
				this.thread = createThread();
			}
		}
		else if (this.thread != null)
		{
			window.clearInterval(this.thread);
			this.thread = null;
		}
	};
	
	this.stop = function()
	{
		if (this.active)
		{
			this.active = false;
		
			if (this.thread != null)
	    	{
				window.clearInterval(this.thread);
				this.thread = null;
	    	}
			
			this.tdx = 0;
			this.tdy = 0;
			
			if (!this.scrollbars)
			{
				var px = graph.panDx;
				var py = graph.panDy;
		    	
		    	if (px != 0 || py != 0)
		    	{
		    		graph.panGraph(0, 0);
			    	graph.view.setTranslate(this.t0x + px / graph.view.scale, this.t0y + py / graph.view.scale);
		    	}
			}
			else
			{
				graph.panDx = 0;
				graph.panDy = 0;
				graph.fireEvent(new mxEventObject(mxEvent.PAN));
			}
		}
	};
	
	this.destroy = function()
	{
		graph.removeMouseListener(this.mouseListener);
	};
};

/**
 * Variable: damper
 * 
 * Damper value for the panning. Default is 1/6.
 */
mxPanningManager.prototype.damper = 1/6;

/**
 * Variable: delay
 * 
 * Delay in milliseconds for the panning. Default is 10.
 */
mxPanningManager.prototype.delay = 10;

/**
 * Variable: handleMouseOut
 * 
 * Specifies if mouse events outside of the component should be handled. Default is true. 
 */
mxPanningManager.prototype.handleMouseOut = true;

/**
 * Variable: border
 * 
 * Border to handle automatic panning inside the component. Default is 0 (disabled).
 */
mxPanningManager.prototype.border = 0;
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxPopupMenu
 * 
 * Basic popup menu. To add a vertical scrollbar to a given submenu, the
 * following code can be used.
 * 
 * (code)
 * var mxPopupMenuShowMenu = mxPopupMenu.prototype.showMenu;
 * mxPopupMenu.prototype.showMenu = function()
 * {
 *   mxPopupMenuShowMenu.apply(this, arguments);
 *   
 *   this.div.style.overflowY = 'auto';
 *   this.div.style.overflowX = 'hidden';
 *   this.div.style.maxHeight = '160px';
 * };
 * (end)
 * 
 * Constructor: mxPopupMenu
 * 
 * Constructs a popupmenu.
 * 
 * Event: mxEvent.SHOW
 *
 * Fires after the menu has been shown in <popup>.
 */
function mxPopupMenu(factoryMethod)
{
	this.factoryMethod = factoryMethod;
	
	if (factoryMethod != null)
	{
		this.init();
	}
};

/**
 * Extends mxEventSource.
 */
mxPopupMenu.prototype = new mxEventSource();
mxPopupMenu.prototype.constructor = mxPopupMenu;

/**
 * Variable: submenuImage
 * 
 * URL of the image to be used for the submenu icon.
 */
mxPopupMenu.prototype.submenuImage = mxClient.imageBasePath + '/submenu.gif';

/**
 * Variable: zIndex
 * 
 * Specifies the zIndex for the popupmenu and its shadow. Default is 1006.
 */
mxPopupMenu.prototype.zIndex = 10006;

/**
 * Variable: factoryMethod
 * 
 * Function that is used to create the popup menu. The function takes the
 * current panning handler, the <mxCell> under the mouse and the mouse
 * event that triggered the call as arguments.
 */
mxPopupMenu.prototype.factoryMethod = null;

/**
 * Variable: useLeftButtonForPopup
 * 
 * Specifies if popupmenus should be activated by clicking the left mouse
 * button. Default is false.
 */
mxPopupMenu.prototype.useLeftButtonForPopup = false;

/**
 * Variable: enabled
 * 
 * Specifies if events are handled. Default is true.
 */
mxPopupMenu.prototype.enabled = true;

/**
 * Variable: itemCount
 * 
 * Contains the number of times <addItem> has been called for a new menu.
 */
mxPopupMenu.prototype.itemCount = 0;

/**
 * Variable: autoExpand
 * 
 * Specifies if submenus should be expanded on mouseover. Default is false.
 */
mxPopupMenu.prototype.autoExpand = false;

/**
 * Variable: smartSeparators
 * 
 * Specifies if separators should only be added if a menu item follows them.
 * Default is false.
 */
mxPopupMenu.prototype.smartSeparators = false;

/**
 * Variable: labels
 * 
 * Specifies if any labels should be visible. Default is true.
 */
mxPopupMenu.prototype.labels = true;

/**
 * Function: init
 * 
 * Initializes the shapes required for this vertex handler.
 */
mxPopupMenu.prototype.init = function()
{
	// Adds the inner table
	this.table = document.createElement('table');
	this.table.className = 'mxPopupMenu';
	
	this.tbody = document.createElement('tbody');
	this.table.appendChild(this.tbody);

	// Adds the outer div
	this.div = document.createElement('div');
	this.div.className = 'mxPopupMenu';
	this.div.style.display = 'inline';
	this.div.style.zIndex = this.zIndex;
	this.div.appendChild(this.table);

	// Disables the context menu on the outer div
	mxEvent.disableContextMenu(this.div);
};

/**
 * Function: isEnabled
 * 
 * Returns true if events are handled. This implementation
 * returns <enabled>.
 */
mxPopupMenu.prototype.isEnabled = function()
{
	return this.enabled;
};
	
/**
 * Function: setEnabled
 * 
 * Enables or disables event handling. This implementation
 * updates <enabled>.
 */
mxPopupMenu.prototype.setEnabled = function(enabled)
{
	this.enabled = enabled;
};

/**
 * Function: isPopupTrigger
 * 
 * Returns true if the given event is a popupmenu trigger for the optional
 * given cell.
 * 
 * Parameters:
 * 
 * me - <mxMouseEvent> that represents the mouse event.
 */
mxPopupMenu.prototype.isPopupTrigger = function(me)
{
	return me.isPopupTrigger() || (this.useLeftButtonForPopup && mxEvent.isLeftMouseButton(me.getEvent()));
};

/**
 * Function: addItem
 * 
 * Adds the given item to the given parent item. If no parent item is specified
 * then the item is added to the top-level menu. The return value may be used
 * as the parent argument, ie. as a submenu item. The return value is the table
 * row that represents the item.
 * 
 * Paramters:
 * 
 * title - String that represents the title of the menu item.
 * image - Optional URL for the image icon.
 * funct - Function associated that takes a mouseup or touchend event.
 * parent - Optional item returned by <addItem>.
 * iconCls - Optional string that represents the CSS class for the image icon.
 * IconsCls is ignored if image is given.
 * enabled - Optional boolean indicating if the item is enabled. Default is true.
 * active - Optional boolean indicating if the menu should implement any event handling.
 * Default is true.
 */
mxPopupMenu.prototype.addItem = function(title, image, funct, parent, iconCls, enabled, active)
{
	parent = parent || this;
	this.itemCount++;
	
	// Smart separators only added if element contains items
	if (parent.willAddSeparator)
	{
		if (parent.containsItems)
		{
			this.addSeparator(parent, true);
		}

		parent.willAddSeparator = false;
	}

	parent.containsItems = true;
	var tr = document.createElement('tr');
	tr.className = 'mxPopupMenuItem';
	var col1 = document.createElement('td');
	col1.className = 'mxPopupMenuIcon';

	// Adds the given image into the first column
	if (image != null)
	{
		var img = document.createElement('img');
		img.src = image;
		col1.appendChild(img);
	}
	else if (iconCls != null)
	{
		var div = document.createElement('div');
		div.className = iconCls;
		col1.appendChild(div);
	}
	
	tr.appendChild(col1);
	
	if (this.labels)
	{
		var col2 = document.createElement('td');
		col2.className = 'mxPopupMenuItem' +
			((enabled != null && !enabled) ? ' mxDisabled' : '');
		
		mxUtils.write(col2, title);
		col2.align = 'left';
		tr.appendChild(col2);
	
		var col3 = document.createElement('td');
		col3.className = 'mxPopupMenuItem' +
			((enabled != null && !enabled) ? ' mxDisabled' : '');
		col3.style.paddingRight = '6px';
		col3.style.textAlign = 'right';
		
		tr.appendChild(col3);
		
		if (parent.div == null)
		{
			this.createSubmenu(parent);
		}
	}
	
	parent.tbody.appendChild(tr);

	if (active != false && enabled != false)
	{
		var currentSelection = null;
		
		mxEvent.addGestureListeners(tr,
			mxUtils.bind(this, function(evt)
			{
				this.eventReceiver = tr;
				
				if (parent.activeRow != tr && parent.activeRow != parent)
				{
					if (parent.activeRow != null && parent.activeRow.div.parentNode != null)
					{
						this.hideSubmenu(parent);
					}
					
					if (tr.div != null)
					{
						this.showSubmenu(parent, tr);
						parent.activeRow = tr;
					}
				}
				
				// Workaround for lost current selection in page because of focus in IE
				if (mxClient.IS_QUIRKS || document.documentMode == 8)
				{
					currentSelection = document.selection.createRange();
				}
				
				mxEvent.consume(evt);
			}),
			mxUtils.bind(this, function(evt)
			{
				if (parent.activeRow != tr && parent.activeRow != parent)
				{
					if (parent.activeRow != null && parent.activeRow.div.parentNode != null)
					{
						this.hideSubmenu(parent);
					}
					
					if (this.autoExpand && tr.div != null)
					{
						this.showSubmenu(parent, tr);
						parent.activeRow = tr;
					}
				}
		
				// Sets hover style because TR in IE doesn't have hover
				tr.className = 'mxPopupMenuItemHover';
			}),
			mxUtils.bind(this, function(evt)
			{
				// EventReceiver avoids clicks on a submenu item
				// which has just been shown in the mousedown
				if (this.eventReceiver == tr)
				{
					if (parent.activeRow != tr)
					{
						this.hideMenu();
					}
					
					// Workaround for lost current selection in page because of focus in IE
					if (currentSelection != null)
					{
						// Workaround for "unspecified error" in IE8 standards
						try
						{
							currentSelection.select();
						}
						catch (e)
						{
							// ignore
						}

						currentSelection = null;
					}
					
					if (funct != null)
					{
						funct(evt);
					}
				}
				
				this.eventReceiver = null;
				mxEvent.consume(evt);
			})
		);
	
		// Resets hover style because TR in IE doesn't have hover
		mxEvent.addListener(tr, 'mouseout',
			mxUtils.bind(this, function(evt)
			{
				tr.className = 'mxPopupMenuItem';
			})
		);
	}
	
	return tr;
};

/**
 * Adds a checkmark to the given menuitem.
 */
mxPopupMenu.prototype.addCheckmark = function(item, img)
{
	var td = item.firstChild.nextSibling;
	td.style.backgroundImage = 'url(\'' + img + '\')';
	td.style.backgroundRepeat = 'no-repeat';
	td.style.backgroundPosition = '2px 50%';
};

/**
 * Function: createSubmenu
 * 
 * Creates the nodes required to add submenu items inside the given parent
 * item. This is called in <addItem> if a parent item is used for the first
 * time. This adds various DOM nodes and a <submenuImage> to the parent.
 * 
 * Parameters:
 * 
 * parent - An item returned by <addItem>.
 */
mxPopupMenu.prototype.createSubmenu = function(parent)
{
	parent.table = document.createElement('table');
	parent.table.className = 'mxPopupMenu';

	parent.tbody = document.createElement('tbody');
	parent.table.appendChild(parent.tbody);

	parent.div = document.createElement('div');
	parent.div.className = 'mxPopupMenu';

	parent.div.style.position = 'absolute';
	parent.div.style.display = 'inline';
	parent.div.style.zIndex = this.zIndex;
	
	parent.div.appendChild(parent.table);
	
	var img = document.createElement('img');
	img.setAttribute('src', this.submenuImage);
	
	// Last column of the submenu item in the parent menu
	td = parent.firstChild.nextSibling.nextSibling;
	td.appendChild(img);
};

/**
 * Function: showSubmenu
 * 
 * Shows the submenu inside the given parent row.
 */
mxPopupMenu.prototype.showSubmenu = function(parent, row)
{
	if (row.div != null)
	{
		row.div.style.left = (parent.div.offsetLeft +
			row.offsetLeft+row.offsetWidth - 1) + 'px';
		row.div.style.top = (parent.div.offsetTop+row.offsetTop) + 'px';
		document.body.appendChild(row.div);
		
		// Moves the submenu to the left side if there is no space
		var left = parseInt(row.div.offsetLeft);
		var width = parseInt(row.div.offsetWidth);
		var offset = mxUtils.getDocumentScrollOrigin(document);
		
		var b = document.body;
		var d = document.documentElement;
		
		var right = offset.x + (b.clientWidth || d.clientWidth);
		
		if (left + width > right)
		{
			row.div.style.left = Math.max(0, (parent.div.offsetLeft - width + ((mxClient.IS_IE) ? 6 : -6))) + 'px';
		}
		
		mxUtils.fit(row.div);
	}
};

/**
 * Function: addSeparator
 * 
 * Adds a horizontal separator in the given parent item or the top-level menu
 * if no parent is specified.
 * 
 * Parameters:
 * 
 * parent - Optional item returned by <addItem>.
 * force - Optional boolean to ignore <smartSeparators>. Default is false.
 */
mxPopupMenu.prototype.addSeparator = function(parent, force)
{
	parent = parent || this;
	
	if (this.smartSeparators && !force)
	{
		parent.willAddSeparator = true;
	}
	else if (parent.tbody != null)
	{
		parent.willAddSeparator = false;
		var tr = document.createElement('tr');
		
		var col1 = document.createElement('td');
		col1.className = 'mxPopupMenuIcon';
		col1.style.padding = '0 0 0 0px';
		
		tr.appendChild(col1);
		
		var col2 = document.createElement('td');
		col2.style.padding = '0 0 0 0px';
		col2.setAttribute('colSpan', '2');
	
		var hr = document.createElement('hr');
		hr.setAttribute('size', '1');
		col2.appendChild(hr);
		
		tr.appendChild(col2);
		
		parent.tbody.appendChild(tr);
	}
};

/**
 * Function: popup
 * 
 * Shows the popup menu for the given event and cell.
 * 
 * Example:
 * 
 * (code)
 * graph.panningHandler.popup = function(x, y, cell, evt)
 * {
 *   mxUtils.alert('Hello, World!');
 * }
 * (end)
 */
mxPopupMenu.prototype.popup = function(x, y, cell, evt)
{
	if (this.div != null && this.tbody != null && this.factoryMethod != null)
	{
		this.div.style.left = x + 'px';
		this.div.style.top = y + 'px';
		
		// Removes all child nodes from the existing menu
		while (this.tbody.firstChild != null)
		{
			mxEvent.release(this.tbody.firstChild);
			this.tbody.removeChild(this.tbody.firstChild);
		}
		
		this.itemCount = 0;
		this.factoryMethod(this, cell, evt);
		
		if (this.itemCount > 0)
		{
			this.showMenu();
			this.fireEvent(new mxEventObject(mxEvent.SHOW));
		}
	}
};

/**
 * Function: isMenuShowing
 * 
 * Returns true if the menu is showing.
 */
mxPopupMenu.prototype.isMenuShowing = function()
{
	return this.div != null && this.div.parentNode == document.body;
};

/**
 * Function: showMenu
 * 
 * Shows the menu.
 */
mxPopupMenu.prototype.showMenu = function()
{
	// Disables filter-based shadow in IE9 standards mode
	if (document.documentMode >= 9)
	{
		this.div.style.filter = 'none';
	}
	
	// Fits the div inside the viewport
	document.body.appendChild(this.div);
	mxUtils.fit(this.div);
};

/**
 * Function: hideMenu
 * 
 * Removes the menu and all submenus.
 */
mxPopupMenu.prototype.hideMenu = function()
{
	if (this.div != null)
	{
		if (this.div.parentNode != null)
		{
			this.div.parentNode.removeChild(this.div);
		}
		
		this.hideSubmenu(this);
		this.containsItems = false;
		this.fireEvent(new mxEventObject(mxEvent.HIDE));
	}
};

/**
 * Function: hideSubmenu
 * 
 * Removes all submenus inside the given parent.
 * 
 * Parameters:
 * 
 * parent - An item returned by <addItem>.
 */
mxPopupMenu.prototype.hideSubmenu = function(parent)
{
	if (parent.activeRow != null)
	{
		this.hideSubmenu(parent.activeRow);
		
		if (parent.activeRow.div.parentNode != null)
		{
			parent.activeRow.div.parentNode.removeChild(parent.activeRow.div);
		}
		
		parent.activeRow = null;
	}
};

/**
 * Function: destroy
 * 
 * Destroys the handler and all its resources and DOM nodes.
 */
mxPopupMenu.prototype.destroy = function()
{
	if (this.div != null)
	{
		mxEvent.release(this.div);
		
		if (this.div.parentNode != null)
		{
			this.div.parentNode.removeChild(this.div);
		}
		
		this.div = null;
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxAutoSaveManager
 * 
 * Manager for automatically saving diagrams. The <save> hook must be
 * implemented.
 * 
 * Example:
 * 
 * (code)
 * var mgr = new mxAutoSaveManager(editor.graph);
 * mgr.save = function()
 * {
 *   mxLog.show();
 *   mxLog.debug('save');
 * };
 * (end)
 * 
 * Constructor: mxAutoSaveManager
 *
 * Constructs a new automatic layout for the given graph.
 *
 * Arguments:
 * 
 * graph - Reference to the enclosing graph. 
 */
function mxAutoSaveManager(graph)
{
	// Notifies the manager of a change
	this.changeHandler = mxUtils.bind(this, function(sender, evt)
	{
		if (this.isEnabled())
		{
			this.graphModelChanged(evt.getProperty('edit').changes);
		}
	});

	this.setGraph(graph);
};

/**
 * Extends mxEventSource.
 */
mxAutoSaveManager.prototype = new mxEventSource();
mxAutoSaveManager.prototype.constructor = mxAutoSaveManager;

/**
 * Variable: graph
 * 
 * Reference to the enclosing <mxGraph>.
 */
mxAutoSaveManager.prototype.graph = null;

/**
 * Variable: autoSaveDelay
 * 
 * Minimum amount of seconds between two consecutive autosaves. Eg. a
 * value of 1 (s) means the graph is not stored more than once per second.
 * Default is 10.
 */
mxAutoSaveManager.prototype.autoSaveDelay = 10;

/**
 * Variable: autoSaveThrottle
 * 
 * Minimum amount of seconds between two consecutive autosaves triggered by
 * more than <autoSaveThreshhold> changes within a timespan of less than
 * <autoSaveDelay> seconds. Eg. a value of 1 (s) means the graph is not
 * stored more than once per second even if there are more than
 * <autoSaveThreshold> changes within that timespan. Default is 2.
 */
mxAutoSaveManager.prototype.autoSaveThrottle = 2;

/**
 * Variable: autoSaveThreshold
 * 
 * Minimum amount of ignored changes before an autosave. Eg. a value of 2
 * means after 2 change of the graph model the autosave will trigger if the
 * condition below is true. Default is 5.
 */
mxAutoSaveManager.prototype.autoSaveThreshold = 5;

/**
 * Variable: ignoredChanges
 * 
 * Counter for ignored changes in autosave.
 */
mxAutoSaveManager.prototype.ignoredChanges = 0;

/**
 * Variable: lastSnapshot
 * 
 * Used for autosaving. See <autosave>.
 */
mxAutoSaveManager.prototype.lastSnapshot = 0;

/**
 * Variable: enabled
 * 
 * Specifies if event handling is enabled. Default is true.
 */
mxAutoSaveManager.prototype.enabled = true;

/**
 * Variable: changeHandler
 * 
 * Holds the function that handles graph model changes.
 */
mxAutoSaveManager.prototype.changeHandler = null;

/**
 * Function: isEnabled
 * 
 * Returns true if events are handled. This implementation
 * returns <enabled>.
 */
mxAutoSaveManager.prototype.isEnabled = function()
{
	return this.enabled;
};

/**
 * Function: setEnabled
 * 
 * Enables or disables event handling. This implementation
 * updates <enabled>.
 * 
 * Parameters:
 * 
 * enabled - Boolean that specifies the new enabled state.
 */
mxAutoSaveManager.prototype.setEnabled = function(value)
{
	this.enabled = value;
};

/**
 * Function: setGraph
 * 
 * Sets the graph that the layouts operate on.
 */
mxAutoSaveManager.prototype.setGraph = function(graph)
{
	if (this.graph != null)
	{
		this.graph.getModel().removeListener(this.changeHandler);
	}
	
	this.graph = graph;
	
	if (this.graph != null)
	{
		this.graph.getModel().addListener(mxEvent.CHANGE, this.changeHandler);
	}
};

/**
 * Function: save
 * 
 * Empty hook that is called if the graph should be saved.
 */
mxAutoSaveManager.prototype.save = function()
{
	// empty
};

/**
 * Function: graphModelChanged
 * 
 * Invoked when the graph model has changed.
 */
mxAutoSaveManager.prototype.graphModelChanged = function(changes)
{
	var now = new Date().getTime();
	var dt = (now - this.lastSnapshot) / 1000;
	
	if (dt > this.autoSaveDelay ||
		(this.ignoredChanges >= this.autoSaveThreshold &&
		 dt > this.autoSaveThrottle))
	{
		this.save();
		this.reset();
	}
	else
	{
		// Increments the number of ignored changes
		this.ignoredChanges++;
	}
};

/**
 * Function: reset
 * 
 * Resets all counters.
 */
mxAutoSaveManager.prototype.reset = function()
{
	this.lastSnapshot = new Date().getTime();
	this.ignoredChanges = 0;
};

/**
 * Function: destroy
 * 
 * Removes all handlers from the <graph> and deletes the reference to it.
 */
mxAutoSaveManager.prototype.destroy = function()
{
	this.setGraph(null);
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 *
 * Class: mxAnimation
 * 
 * Implements a basic animation in JavaScript.
 * 
 * Constructor: mxAnimation
 * 
 * Constructs an animation.
 * 
 * Parameters:
 * 
 * graph - Reference to the enclosing <mxGraph>.
 */
function mxAnimation(delay)
{
	this.delay = (delay != null) ? delay : 20;
};

/**
 * Extends mxEventSource.
 */
mxAnimation.prototype = new mxEventSource();
mxAnimation.prototype.constructor = mxAnimation;

/**
 * Variable: delay
 * 
 * Specifies the delay between the animation steps. Defaul is 30ms.
 */
mxAnimation.prototype.delay = null;

/**
 * Variable: thread
 * 
 * Reference to the thread while the animation is running.
 */
mxAnimation.prototype.thread = null;

/**
 * Function: isRunning
 * 
 * Returns true if the animation is running.
 */
mxAnimation.prototype.isRunning = function()
{
	return this.thread != null;
};

/**
 * Function: startAnimation
 *
 * Starts the animation by repeatedly invoking updateAnimation.
 */
mxAnimation.prototype.startAnimation = function()
{
	if (this.thread == null)
	{
		this.thread = window.setInterval(mxUtils.bind(this, this.updateAnimation), this.delay);
	}
};

/**
 * Function: updateAnimation
 *
 * Hook for subclassers to implement the animation. Invoke stopAnimation
 * when finished, startAnimation to resume. This is called whenever the
 * timer fires and fires an mxEvent.EXECUTE event with no properties.
 */
mxAnimation.prototype.updateAnimation = function()
{
	this.fireEvent(new mxEventObject(mxEvent.EXECUTE));
};

/**
 * Function: stopAnimation
 *
 * Stops the animation by deleting the timer and fires an <mxEvent.DONE>.
 */
mxAnimation.prototype.stopAnimation = function()
{
	if (this.thread != null)
	{
		window.clearInterval(this.thread);
		this.thread = null;
		this.fireEvent(new mxEventObject(mxEvent.DONE));
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 *
 * Class: mxMorphing
 * 
 * Implements animation for morphing cells. Here is an example of
 * using this class for animating the result of a layout algorithm:
 * 
 * (code)
 * graph.getModel().beginUpdate();
 * try
 * {
 *   var circleLayout = new mxCircleLayout(graph);
 *   circleLayout.execute(graph.getDefaultParent());
 * }
 * finally
 * {
 *   var morph = new mxMorphing(graph);
 *   morph.addListener(mxEvent.DONE, function()
 *   {
 *     graph.getModel().endUpdate();
 *   });
 *   
 *   morph.startAnimation();
 * }
 * (end)
 * 
 * Constructor: mxMorphing
 * 
 * Constructs an animation.
 * 
 * Parameters:
 * 
 * graph - Reference to the enclosing <mxGraph>.
 * steps - Optional number of steps in the morphing animation. Default is 6.
 * ease - Optional easing constant for the animation. Default is 1.5.
 * delay - Optional delay between the animation steps. Passed to <mxAnimation>.
 */
function mxMorphing(graph, steps, ease, delay)
{
	mxAnimation.call(this, delay);
	this.graph = graph;
	this.steps = (steps != null) ? steps : 6;
	this.ease = (ease != null) ? ease : 1.5;
};

/**
 * Extends mxEventSource.
 */
mxMorphing.prototype = new mxAnimation();
mxMorphing.prototype.constructor = mxMorphing;

/**
 * Variable: graph
 * 
 * Specifies the delay between the animation steps. Defaul is 30ms.
 */
mxMorphing.prototype.graph = null;

/**
 * Variable: steps
 * 
 * Specifies the maximum number of steps for the morphing.
 */
mxMorphing.prototype.steps = null;

/**
 * Variable: step
 * 
 * Contains the current step.
 */
mxMorphing.prototype.step = 0;

/**
 * Variable: ease
 * 
 * Ease-off for movement towards the given vector. Larger values are
 * slower and smoother. Default is 4.
 */
mxMorphing.prototype.ease = null;

/**
 * Variable: cells
 * 
 * Optional array of cells to be animated. If this is not specified
 * then all cells are checked and animated if they have been moved
 * in the current transaction.
 */
mxMorphing.prototype.cells = null;

/**
 * Function: updateAnimation
 *
 * Animation step.
 */
mxMorphing.prototype.updateAnimation = function()
{
	var move = new mxCellStatePreview(this.graph);

	if (this.cells != null)
	{
		// Animates the given cells individually without recursion
		for (var i = 0; i < this.cells.length; i++)
		{
			this.animateCell(this.cells[i], move, false);
		}
	}
	else
	{
		// Animates all changed cells by using recursion to find
		// the changed cells but not for the animation itself
		this.animateCell(this.graph.getModel().getRoot(), move, true);
	}
	
	this.show(move);
	
	if (move.isEmpty() || this.step++ >= this.steps)
	{
		this.stopAnimation();
	}
};

/**
 * Function: show
 *
 * Shows the changes in the given <mxCellStatePreview>.
 */
mxMorphing.prototype.show = function(move)
{
	move.show();
};

/**
 * Function: animateCell
 *
 * Animates the given cell state using <mxCellStatePreview.moveState>.
 */
mxMorphing.prototype.animateCell = function(cell, move, recurse)
{
	var state = this.graph.getView().getState(cell);
	var delta = null;

	if (state != null)
	{
		// Moves the animated state from where it will be after the model
		// change by subtracting the given delta vector from that location
		delta = this.getDelta(state);

		if (this.graph.getModel().isVertex(cell) && (delta.x != 0 || delta.y != 0))
		{
			var translate = this.graph.view.getTranslate();
			var scale = this.graph.view.getScale();
			
			delta.x += translate.x * scale;
			delta.y += translate.y * scale;
			
			move.moveState(state, -delta.x / this.ease, -delta.y / this.ease);
		}
	}
	
	if (recurse && !this.stopRecursion(state, delta))
	{
		var childCount = this.graph.getModel().getChildCount(cell);

		for (var i = 0; i < childCount; i++)
		{
			this.animateCell(this.graph.getModel().getChildAt(cell, i), move, recurse);
		}
	}
};

/**
 * Function: stopRecursion
 *
 * Returns true if the animation should not recursively find more
 * deltas for children if the given parent state has been animated.
 */
mxMorphing.prototype.stopRecursion = function(state, delta)
{
	return delta != null && (delta.x != 0 || delta.y != 0);
};

/**
 * Function: getDelta
 *
 * Returns the vector between the current rendered state and the future
 * location of the state after the display will be updated.
 */
mxMorphing.prototype.getDelta = function(state)
{
	var origin = this.getOriginForCell(state.cell);
	var translate = this.graph.getView().getTranslate();
	var scale = this.graph.getView().getScale();
	var x = state.x / scale - translate.x;
	var y = state.y / scale - translate.y;

	return new mxPoint((origin.x - x) * scale, (origin.y - y) * scale);
};

/**
 * Function: getOriginForCell
 *
 * Returns the top, left corner of the given cell. TODO: Improve performance
 * by using caching inside this method as the result per cell never changes
 * during the lifecycle of this object.
 */
mxMorphing.prototype.getOriginForCell = function(cell)
{
	var result = null;
	
	if (cell != null)
	{
		var parent = this.graph.getModel().getParent(cell);
		var geo = this.graph.getCellGeometry(cell);
		result = this.getOriginForCell(parent);
		
		// TODO: Handle offsets
		if (geo != null)
		{
			if (geo.relative)
			{
				var pgeo = this.graph.getCellGeometry(parent);
				
				if (pgeo != null)
				{
					result.x += geo.x * pgeo.width;
					result.y += geo.y * pgeo.height;
				}
			}
			else
			{
				result.x += geo.x;
				result.y += geo.y;
			}
		}
	}
	
	if (result == null)
	{
		var t = this.graph.view.getTranslate();
		result = new mxPoint(-t.x, -t.y);
	}
	
	return result;
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxImageBundle
 *
 * Maps from keys to base64 encoded images or file locations. All values must
 * be URLs or use the format data:image/format followed by a comma and the base64
 * encoded image data, eg. "data:image/gif,XYZ", where XYZ is the base64 encoded
 * image data.
 * 
 * To add a new image bundle to an existing graph, the following code is used:
 * 
 * (code)
 * var bundle = new mxImageBundle(alt);
 * bundle.putImage('myImage', 'data:image/gif,R0lGODlhEAAQAMIGAAAAAICAAICAgP' +
 *   '//AOzp2O3r2////////yH+FUNyZWF0ZWQgd2l0aCBUaGUgR0lNUAAh+QQBCgAHACwAAAAA' +
 *   'EAAQAAADTXi63AowynnAMDfjPUDlnAAJhmeBFxAEloliKltWmiYCQvfVr6lBPB1ggxN1hi' +
 *   'laSSASFQpIV5HJBDyHpqK2ejVRm2AAgZCdmCGO9CIBADs=', fallback);
 * bundle.putImage('mySvgImage', 'data:image/svg+xml,' + encodeURIComponent(
 *   '<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">' +
 *   '<linearGradient id="gradient"><stop offset="10%" stop-color="#F00"/>' +
 *   '<stop offset="90%" stop-color="#fcc"/></linearGradient>' +
 *   '<rect fill="url(#gradient)" width="100%" height="100%"/></svg>'), fallback);
 * graph.addImageBundle(bundle);
 * (end);
 * 
 * Alt is an optional boolean (default is false) that specifies if the value
 * or the fallback should be returned in <getImage>.
 * 
 * The image can then be referenced in any cell style using image=myImage.
 * If you are using mxOutline, you should use the same image bundles in the
 * graph that renders the outline.
 * 
 * The keys for images are resolved in <mxGraph.postProcessCellStyle> and
 * turned into a data URI if the returned value has a short data URI format
 * as specified above.
 * 
 * A typical value for the fallback is a MTHML link as defined in RFC 2557.
 * Note that this format requires a file to be dynamically created on the
 * server-side, or the page that contains the graph to be modified to contain
 * the resources, this can be done by adding a comment that contains the
 * resource in the HEAD section of the page after the title tag.
 * 
 * This type of fallback mechanism should be used in IE6 and IE7. IE8 does
 * support data URIs, but the maximum size is limited to 32 KB, which means
 * all data URIs should be limited to 32 KB.
 */
function mxImageBundle(alt)
{
	this.images = [];
	this.alt = (alt != null) ? alt : false;
};

/**
 * Variable: images
 * 
 * Maps from keys to images.
 */
mxImageBundle.prototype.images = null;

/**
 * Variable: alt
 * 
 * Specifies if the fallback representation should be returned.
 */
mxImageBundle.prototype.images = null;

/**
 * Function: putImage
 * 
 * Adds the specified entry to the map. The entry is an object with a value and
 * fallback property as specified in the arguments.
 */
mxImageBundle.prototype.putImage = function(key, value, fallback)
{
	this.images[key] = {value: value, fallback: fallback};
};

/**
 * Function: getImage
 * 
 * Returns the value for the given key. This returns the value
 * or fallback, depending on <alt>. The fallback is returned if
 * <alt> is true, the value is returned otherwise.
 */
mxImageBundle.prototype.getImage = function(key)
{
	var result = null;
	
	if (key != null)
	{
		var img = this.images[key];
		
		if (img != null)
		{
			result = (this.alt) ? img.fallback : img.value;
		}
	}
	
	return result;
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxImageExport
 * 
 * Creates a new image export instance to be used with an export canvas. Here
 * is an example that uses this class to create an image via a backend using
 * <mxXmlExportCanvas>.
 * 
 * (code)
 * var xmlDoc = mxUtils.createXmlDocument();
 * var root = xmlDoc.createElement('output');
 * xmlDoc.appendChild(root);
 * 
 * var xmlCanvas = new mxXmlCanvas2D(root);
 * var imgExport = new mxImageExport();
 * imgExport.drawState(graph.getView().getState(graph.model.root), xmlCanvas);
 * 
 * var bounds = graph.getGraphBounds();
 * var w = Math.ceil(bounds.x + bounds.width);
 * var h = Math.ceil(bounds.y + bounds.height);
 * 
 * var xml = mxUtils.getXml(root);
 * new mxXmlRequest('export', 'format=png&w=' + w +
 * 		'&h=' + h + '&bg=#F9F7ED&xml=' + encodeURIComponent(xml))
 * 		.simulate(document, '_blank');
 * (end)
 * 
 * Constructor: mxImageExport
 * 
 * Constructs a new image export.
 */
function mxImageExport() { };

/**
 * Variable: includeOverlays
 * 
 * Specifies if overlays should be included in the export. Default is false.
 */
mxImageExport.prototype.includeOverlays = false;

/**
 * Function: drawState
 * 
 * Draws the given state and all its descendants to the given canvas.
 */
mxImageExport.prototype.drawState = function(state, canvas)
{
	if (state != null)
	{
		this.visitStatesRecursive(state, canvas, mxUtils.bind(this, function()
		{
			this.drawCellState.apply(this, arguments);
		}));
				
		// Paints the overlays
		if (this.includeOverlays)
		{
			this.visitStatesRecursive(state, canvas, mxUtils.bind(this, function()
			{
				this.drawOverlays.apply(this, arguments);
			}));
		}
	}
};

/**
 * Function: drawState
 * 
 * Draws the given state and all its descendants to the given canvas.
 */
mxImageExport.prototype.visitStatesRecursive = function(state, canvas, visitor)
{
	if (state != null)
	{
		visitor(state, canvas);
		
		var graph = state.view.graph;
		var childCount = graph.model.getChildCount(state.cell);
		
		for (var i = 0; i < childCount; i++)
		{
			var childState = graph.view.getState(graph.model.getChildAt(state.cell, i));
			this.visitStatesRecursive(childState, canvas, visitor);
		}
	}
};

/**
 * Function: getLinkForCellState
 * 
 * Returns the link for the given cell state and canvas. This returns null.
 */
mxImageExport.prototype.getLinkForCellState = function(state, canvas)
{
	return null;
};

/**
 * Function: drawCellState
 * 
 * Draws the given state to the given canvas.
 */
mxImageExport.prototype.drawCellState = function(state, canvas)
{
	// Experimental feature
	var link = this.getLinkForCellState(state, canvas);
	
	if (link != null)
	{
		canvas.setLink(link);
	}
	
	// Paints the shape and text
	this.drawShape(state, canvas);
	this.drawText(state, canvas);

	if (link != null)
	{
		canvas.setLink(null);
	}
};

/**
 * Function: drawShape
 * 
 * Draws the shape of the given state.
 */
mxImageExport.prototype.drawShape = function(state, canvas)
{
	if (state.shape instanceof mxShape && state.shape.checkBounds())
	{
		canvas.save();
		state.shape.paint(canvas);
		canvas.restore();
	}
};

/**
 * Function: drawText
 * 
 * Draws the text of the given state.
 */
mxImageExport.prototype.drawText = function(state, canvas)
{
	if (state.text != null && state.text.checkBounds())
	{
		canvas.save();
		state.text.paint(canvas);
		canvas.restore();
	}
};

/**
 * Function: drawOverlays
 * 
 * Draws the overlays for the given state. This is called if <includeOverlays>
 * is true.
 */
mxImageExport.prototype.drawOverlays = function(state, canvas)
{
	if (state.overlays != null)
	{
		state.overlays.visit(function(id, shape)
		{
			if (shape instanceof mxShape)
			{
				shape.paint(canvas);
			}
		});
	}
};

/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxAbstractCanvas2D
 *
 * Base class for all canvases. A description of the public API is available in <mxXmlCanvas2D>.
 * All color values of <mxConstants.NONE> will be converted to null in the state.
 * 
 * Constructor: mxAbstractCanvas2D
 *
 * Constructs a new abstract canvas.
 */
function mxAbstractCanvas2D()
{
	/**
	 * Variable: converter
	 * 
	 * Holds the <mxUrlConverter> to convert image URLs.
	 */
	this.converter = this.createUrlConverter();
	
	this.reset();
};

/**
 * Variable: state
 * 
 * Holds the current state.
 */
mxAbstractCanvas2D.prototype.state = null;

/**
 * Variable: states
 * 
 * Stack of states.
 */
mxAbstractCanvas2D.prototype.states = null;

/**
 * Variable: path
 * 
 * Holds the current path as an array.
 */
mxAbstractCanvas2D.prototype.path = null;

/**
 * Variable: rotateHtml
 * 
 * Switch for rotation of HTML. Default is false.
 */
mxAbstractCanvas2D.prototype.rotateHtml = true;

/**
 * Variable: lastX
 * 
 * Holds the last x coordinate.
 */
mxAbstractCanvas2D.prototype.lastX = 0;

/**
 * Variable: lastY
 * 
 * Holds the last y coordinate.
 */
mxAbstractCanvas2D.prototype.lastY = 0;

/**
 * Variable: moveOp
 * 
 * Contains the string used for moving in paths. Default is 'M'.
 */
mxAbstractCanvas2D.prototype.moveOp = 'M';

/**
 * Variable: lineOp
 * 
 * Contains the string used for moving in paths. Default is 'L'.
 */
mxAbstractCanvas2D.prototype.lineOp = 'L';

/**
 * Variable: quadOp
 * 
 * Contains the string used for quadratic paths. Default is 'Q'.
 */
mxAbstractCanvas2D.prototype.quadOp = 'Q';

/**
 * Variable: curveOp
 * 
 * Contains the string used for bezier curves. Default is 'C'.
 */
mxAbstractCanvas2D.prototype.curveOp = 'C';

/**
 * Variable: closeOp
 * 
 * Holds the operator for closing curves. Default is 'Z'.
 */
mxAbstractCanvas2D.prototype.closeOp = 'Z';

/**
 * Variable: pointerEvents
 * 
 * Boolean value that specifies if events should be handled. Default is false.
 */
mxAbstractCanvas2D.prototype.pointerEvents = false;

/**
 * Function: createUrlConverter
 * 
 * Create a new <mxUrlConverter> and returns it.
 */
mxAbstractCanvas2D.prototype.createUrlConverter = function()
{
	return new mxUrlConverter();
};

/**
 * Function: reset
 * 
 * Resets the state of this canvas.
 */
mxAbstractCanvas2D.prototype.reset = function()
{
	this.state = this.createState();
	this.states = [];
};

/**
 * Function: createState
 * 
 * Creates the state of the this canvas.
 */
mxAbstractCanvas2D.prototype.createState = function()
{
	return {
		dx: 0,
		dy: 0,
		scale: 1,
		alpha: 1,
		fillAlpha: 1,
		strokeAlpha: 1,
		fillColor: null,
		gradientFillAlpha: 1,
		gradientColor: null,
		gradientAlpha: 1,
		gradientDirection: null,
		strokeColor: null,
		strokeWidth: 1,
		dashed: false,
		dashPattern: '3 3',
		fixDash: false,
		lineCap: 'flat',
		lineJoin: 'miter',
		miterLimit: 10,
		fontColor: '#000000',
		fontBackgroundColor: null,
		fontBorderColor: null,
		fontSize: mxConstants.DEFAULT_FONTSIZE,
		fontFamily: mxConstants.DEFAULT_FONTFAMILY,
		fontStyle: 0,
		shadow: false,
		shadowColor: mxConstants.SHADOWCOLOR,
		shadowAlpha: mxConstants.SHADOW_OPACITY,
		shadowDx: mxConstants.SHADOW_OFFSET_X,
		shadowDy: mxConstants.SHADOW_OFFSET_Y,
		rotation: 0,
		rotationCx: 0,
		rotationCy: 0
	};
};

/**
 * Function: format
 * 
 * Rounds all numbers to integers.
 */
mxAbstractCanvas2D.prototype.format = function(value)
{
	return Math.round(parseFloat(value));
};

/**
 * Function: addOp
 * 
 * Adds the given operation to the path.
 */
mxAbstractCanvas2D.prototype.addOp = function()
{
	if (this.path != null)
	{
		this.path.push(arguments[0]);
		
		if (arguments.length > 2)
		{
			var s = this.state;

			for (var i = 2; i < arguments.length; i += 2)
			{
				this.lastX = arguments[i - 1];
				this.lastY = arguments[i];
				
				this.path.push(this.format((this.lastX + s.dx) * s.scale));
				this.path.push(this.format((this.lastY + s.dy) * s.scale));
			}
		}
	}
};

/**
 * Function: rotatePoint
 * 
 * Rotates the given point and returns the result as an <mxPoint>.
 */
mxAbstractCanvas2D.prototype.rotatePoint = function(x, y, theta, cx, cy)
{
	var rad = theta * (Math.PI / 180);
	
	return mxUtils.getRotatedPoint(new mxPoint(x, y), Math.cos(rad),
		Math.sin(rad), new mxPoint(cx, cy));
};

/**
 * Function: save
 * 
 * Saves the current state.
 */
mxAbstractCanvas2D.prototype.save = function()
{
	this.states.push(this.state);
	this.state = mxUtils.clone(this.state);
};

/**
 * Function: restore
 * 
 * Restores the current state.
 */
mxAbstractCanvas2D.prototype.restore = function()
{
	if (this.states.length > 0)
	{
		this.state = this.states.pop();
	}
};

/**
 * Function: setLink
 * 
 * Sets the current link. Hook for subclassers.
 */
mxAbstractCanvas2D.prototype.setLink = function(link)
{
	// nop
};

/**
 * Function: scale
 * 
 * Scales the current state.
 */
mxAbstractCanvas2D.prototype.scale = function(value)
{
	this.state.scale *= value;
	this.state.strokeWidth *= value;
};

/**
 * Function: translate
 * 
 * Translates the current state.
 */
mxAbstractCanvas2D.prototype.translate = function(dx, dy)
{
	this.state.dx += dx;
	this.state.dy += dy;
};

/**
 * Function: rotate
 * 
 * Rotates the current state.
 */
mxAbstractCanvas2D.prototype.rotate = function(theta, flipH, flipV, cx, cy)
{
	// nop
};

/**
 * Function: setAlpha
 * 
 * Sets the current alpha.
 */
mxAbstractCanvas2D.prototype.setAlpha = function(value)
{
	this.state.alpha = value;
};

/**
 * Function: setFillAlpha
 * 
 * Sets the current solid fill alpha.
 */
mxAbstractCanvas2D.prototype.setFillAlpha = function(value)
{
	this.state.fillAlpha = value;
};

/**
 * Function: setStrokeAlpha
 * 
 * Sets the current stroke alpha.
 */
mxAbstractCanvas2D.prototype.setStrokeAlpha = function(value)
{
	this.state.strokeAlpha = value;
};

/**
 * Function: setFillColor
 * 
 * Sets the current fill color.
 */
mxAbstractCanvas2D.prototype.setFillColor = function(value)
{
	if (value == mxConstants.NONE)
	{
		value = null;
	}
	
	this.state.fillColor = value;
	this.state.gradientColor = null;
};

/**
 * Function: setGradient
 * 
 * Sets the current gradient.
 */
mxAbstractCanvas2D.prototype.setGradient = function(color1, color2, x, y, w, h, direction, alpha1, alpha2)
{
	var s = this.state;
	s.fillColor = color1;
	s.gradientFillAlpha = (alpha1 != null) ? alpha1 : 1;
	s.gradientColor = color2;
	s.gradientAlpha = (alpha2 != null) ? alpha2 : 1;
	s.gradientDirection = direction;
};

/**
 * Function: setStrokeColor
 * 
 * Sets the current stroke color.
 */
mxAbstractCanvas2D.prototype.setStrokeColor = function(value)
{
	if (value == mxConstants.NONE)
	{
		value = null;
	}
	
	this.state.strokeColor = value;
};

/**
 * Function: setStrokeWidth
 * 
 * Sets the current stroke width.
 */
mxAbstractCanvas2D.prototype.setStrokeWidth = function(value)
{
	this.state.strokeWidth = value;
};

/**
 * Function: setDashed
 * 
 * Enables or disables dashed lines.
 */
mxAbstractCanvas2D.prototype.setDashed = function(value, fixDash)
{
	this.state.dashed = value;
	this.state.fixDash = fixDash;
};

/**
 * Function: setDashPattern
 * 
 * Sets the current dash pattern.
 */
mxAbstractCanvas2D.prototype.setDashPattern = function(value)
{
	this.state.dashPattern = value;
};

/**
 * Function: setLineCap
 * 
 * Sets the current line cap.
 */
mxAbstractCanvas2D.prototype.setLineCap = function(value)
{
	this.state.lineCap = value;
};

/**
 * Function: setLineJoin
 * 
 * Sets the current line join.
 */
mxAbstractCanvas2D.prototype.setLineJoin = function(value)
{
	this.state.lineJoin = value;
};

/**
 * Function: setMiterLimit
 * 
 * Sets the current miter limit.
 */
mxAbstractCanvas2D.prototype.setMiterLimit = function(value)
{
	this.state.miterLimit = value;
};

/**
 * Function: setFontColor
 * 
 * Sets the current font color.
 */
mxAbstractCanvas2D.prototype.setFontColor = function(value)
{
	if (value == mxConstants.NONE)
	{
		value = null;
	}
	
	this.state.fontColor = value;
};

/**
 * Function: setFontColor
 * 
 * Sets the current font color.
 */
mxAbstractCanvas2D.prototype.setFontBackgroundColor = function(value)
{
	if (value == mxConstants.NONE)
	{
		value = null;
	}
	
	this.state.fontBackgroundColor = value;
};

/**
 * Function: setFontColor
 * 
 * Sets the current font color.
 */
mxAbstractCanvas2D.prototype.setFontBorderColor = function(value)
{
	if (value == mxConstants.NONE)
	{
		value = null;
	}
	
	this.state.fontBorderColor = value;
};

/**
 * Function: setFontSize
 * 
 * Sets the current font size.
 */
mxAbstractCanvas2D.prototype.setFontSize = function(value)
{
	this.state.fontSize = parseFloat(value);
};

/**
 * Function: setFontFamily
 * 
 * Sets the current font family.
 */
mxAbstractCanvas2D.prototype.setFontFamily = function(value)
{
	this.state.fontFamily = value;
};

/**
 * Function: setFontStyle
 * 
 * Sets the current font style.
 */
mxAbstractCanvas2D.prototype.setFontStyle = function(value)
{
	if (value == null)
	{
		value = 0;
	}
	
	this.state.fontStyle = value;
};

/**
 * Function: setShadow
 * 
 * Enables or disables and configures the current shadow.
 */
mxAbstractCanvas2D.prototype.setShadow = function(enabled)
{
	this.state.shadow = enabled;
};

/**
 * Function: setShadowColor
 * 
 * Enables or disables and configures the current shadow.
 */
mxAbstractCanvas2D.prototype.setShadowColor = function(value)
{
	if (value == mxConstants.NONE)
	{
		value = null;
	}
	
	this.state.shadowColor = value;
};

/**
 * Function: setShadowAlpha
 * 
 * Enables or disables and configures the current shadow.
 */
mxAbstractCanvas2D.prototype.setShadowAlpha = function(value)
{
	this.state.shadowAlpha = value;
};

/**
 * Function: setShadowOffset
 * 
 * Enables or disables and configures the current shadow.
 */
mxAbstractCanvas2D.prototype.setShadowOffset = function(dx, dy)
{
	this.state.shadowDx = dx;
	this.state.shadowDy = dy;
};

/**
 * Function: begin
 * 
 * Starts a new path.
 */
mxAbstractCanvas2D.prototype.begin = function()
{
	this.lastX = 0;
	this.lastY = 0;
	this.path = [];
};

/**
 * Function: moveTo
 * 
 *  Moves the current path the given coordinates.
 */
mxAbstractCanvas2D.prototype.moveTo = function(x, y)
{
	this.addOp(this.moveOp, x, y);
};

/**
 * Function: lineTo
 * 
 * Draws a line to the given coordinates. Uses moveTo with the op argument.
 */
mxAbstractCanvas2D.prototype.lineTo = function(x, y)
{
	this.addOp(this.lineOp, x, y);
};

/**
 * Function: quadTo
 * 
 * Adds a quadratic curve to the current path.
 */
mxAbstractCanvas2D.prototype.quadTo = function(x1, y1, x2, y2)
{
	this.addOp(this.quadOp, x1, y1, x2, y2);
};

/**
 * Function: curveTo
 * 
 * Adds a bezier curve to the current path.
 */
mxAbstractCanvas2D.prototype.curveTo = function(x1, y1, x2, y2, x3, y3)
{
	this.addOp(this.curveOp, x1, y1, x2, y2, x3, y3);
};

/**
 * Function: arcTo
 * 
 * Adds the given arc to the current path. This is a synthetic operation that
 * is broken down into curves.
 */
mxAbstractCanvas2D.prototype.arcTo = function(rx, ry, angle, largeArcFlag, sweepFlag, x, y)
{
	var curves = mxUtils.arcToCurves(this.lastX, this.lastY, rx, ry, angle, largeArcFlag, sweepFlag, x, y);
	
	if (curves != null)
	{
		for (var i = 0; i < curves.length; i += 6) 
		{
			this.curveTo(curves[i], curves[i + 1], curves[i + 2],
				curves[i + 3], curves[i + 4], curves[i + 5]);
		}
	}
};

/**
 * Function: close
 * 
 * Closes the current path.
 */
mxAbstractCanvas2D.prototype.close = function(x1, y1, x2, y2, x3, y3)
{
	this.addOp(this.closeOp);
};

/**
 * Function: end
 * 
 * Empty implementation for backwards compatibility. This will be removed.
 */
mxAbstractCanvas2D.prototype.end = function() { };
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxXmlCanvas2D
 *
 * Base class for all canvases. The following methods make up the public
 * interface of the canvas 2D for all painting in mxGraph:
 * 
 * - <save>, <restore>
 * - <scale>, <translate>, <rotate>
 * - <setAlpha>, <setFillAlpha>, <setStrokeAlpha>, <setFillColor>, <setGradient>,
 *   <setStrokeColor>, <setStrokeWidth>, <setDashed>, <setDashPattern>, <setLineCap>, 
 *   <setLineJoin>, <setMiterLimit>
 * - <setFontColor>, <setFontBackgroundColor>, <setFontBorderColor>, <setFontSize>,
 *   <setFontFamily>, <setFontStyle>
 * - <setShadow>, <setShadowColor>, <setShadowAlpha>, <setShadowOffset>
 * - <rect>, <roundrect>, <ellipse>, <image>, <text>
 * - <begin>, <moveTo>, <lineTo>, <quadTo>, <curveTo>
 * - <stroke>, <fill>, <fillAndStroke>
 * 
 * <mxAbstractCanvas2D.arcTo> is an additional method for drawing paths. This is
 * a synthetic method, meaning that it is turned into a sequence of curves by
 * default. Subclassers may add native support for arcs.
 * 
 * Constructor: mxXmlCanvas2D
 *
 * Constructs a new abstract canvas.
 */
function mxXmlCanvas2D(root)
{
	mxAbstractCanvas2D.call(this);

	/**
	 * Variable: root
	 * 
	 * Reference to the container for the SVG content.
	 */
	this.root = root;

	// Writes default settings;
	this.writeDefaults();
};

/**
 * Extends mxAbstractCanvas2D
 */
mxUtils.extend(mxXmlCanvas2D, mxAbstractCanvas2D);

/**
 * Variable: textEnabled
 * 
 * Specifies if text output should be enabled. Default is true.
 */
mxXmlCanvas2D.prototype.textEnabled = true;

/**
 * Variable: compressed
 * 
 * Specifies if the output should be compressed by removing redundant calls.
 * Default is true.
 */
mxXmlCanvas2D.prototype.compressed = true;

/**
 * Function: writeDefaults
 * 
 * Writes the rendering defaults to <root>:
 */
mxXmlCanvas2D.prototype.writeDefaults = function()
{
	var elem;
	
	// Writes font defaults
	elem = this.createElement('fontfamily');
	elem.setAttribute('family', mxConstants.DEFAULT_FONTFAMILY);
	this.root.appendChild(elem);
	
	elem = this.createElement('fontsize');
	elem.setAttribute('size', mxConstants.DEFAULT_FONTSIZE);
	this.root.appendChild(elem);
	
	// Writes shadow defaults
	elem = this.createElement('shadowcolor');
	elem.setAttribute('color', mxConstants.SHADOWCOLOR);
	this.root.appendChild(elem);
	
	elem = this.createElement('shadowalpha');
	elem.setAttribute('alpha', mxConstants.SHADOW_OPACITY);
	this.root.appendChild(elem);
	
	elem = this.createElement('shadowoffset');
	elem.setAttribute('dx', mxConstants.SHADOW_OFFSET_X);
	elem.setAttribute('dy', mxConstants.SHADOW_OFFSET_Y);
	this.root.appendChild(elem);
};

/**
 * Function: format
 * 
 * Returns a formatted number with 2 decimal places.
 */
mxXmlCanvas2D.prototype.format = function(value)
{
	return parseFloat(parseFloat(value).toFixed(2));
};

/**
 * Function: createElement
 * 
 * Creates the given element using the owner document of <root>.
 */
mxXmlCanvas2D.prototype.createElement = function(name)
{
	return this.root.ownerDocument.createElement(name);
};

/**
 * Function: save
 * 
 * Saves the drawing state.
 */
mxXmlCanvas2D.prototype.save = function()
{
	if (this.compressed)
	{
		mxAbstractCanvas2D.prototype.save.apply(this, arguments);
	}
	
	this.root.appendChild(this.createElement('save'));
};

/**
 * Function: restore
 * 
 * Restores the drawing state.
 */
mxXmlCanvas2D.prototype.restore = function()
{
	if (this.compressed)
	{
		mxAbstractCanvas2D.prototype.restore.apply(this, arguments);
	}
	
	this.root.appendChild(this.createElement('restore'));
};

/**
 * Function: scale
 * 
 * Scales the output.
 * 
 * Parameters:
 * 
 * scale - Number that represents the scale where 1 is equal to 100%.
 */
mxXmlCanvas2D.prototype.scale = function(value)
{
        var elem = this.createElement('scale');
        elem.setAttribute('scale', value);
        this.root.appendChild(elem);
};

/**
 * Function: translate
 * 
 * Translates the output.
 * 
 * Parameters:
 * 
 * dx - Number that specifies the horizontal translation.
 * dy - Number that specifies the vertical translation.
 */
mxXmlCanvas2D.prototype.translate = function(dx, dy)
{
	var elem = this.createElement('translate');
	elem.setAttribute('dx', this.format(dx));
	elem.setAttribute('dy', this.format(dy));
	this.root.appendChild(elem);
};

/**
 * Function: rotate
 * 
 * Rotates and/or flips the output around a given center. (Note: Due to
 * limitations in VML, the rotation cannot be concatenated.)
 * 
 * Parameters:
 * 
 * theta - Number that represents the angle of the rotation (in degrees).
 * flipH - Boolean indicating if the output should be flipped horizontally.
 * flipV - Boolean indicating if the output should be flipped vertically.
 * cx - Number that represents the x-coordinate of the rotation center.
 * cy - Number that represents the y-coordinate of the rotation center.
 */
mxXmlCanvas2D.prototype.rotate = function(theta, flipH, flipV, cx, cy)
{
	var elem = this.createElement('rotate');
	
	if (theta != 0 || flipH || flipV)
	{
		elem.setAttribute('theta', this.format(theta));
		elem.setAttribute('flipH', (flipH) ? '1' : '0');
		elem.setAttribute('flipV', (flipV) ? '1' : '0');
		elem.setAttribute('cx', this.format(cx));
		elem.setAttribute('cy', this.format(cy));
		this.root.appendChild(elem);
	}
};

/**
 * Function: setAlpha
 * 
 * Sets the current alpha.
 * 
 * Parameters:
 * 
 * value - Number that represents the new alpha. Possible values are between
 * 1 (opaque) and 0 (transparent).
 */
mxXmlCanvas2D.prototype.setAlpha = function(value)
{
	if (this.compressed)
	{
		if (this.state.alpha == value)
		{
			return;
		}
		
		mxAbstractCanvas2D.prototype.setAlpha.apply(this, arguments);
	}
	
	var elem = this.createElement('alpha');
	elem.setAttribute('alpha', this.format(value));
	this.root.appendChild(elem);
};

/**
 * Function: setFillAlpha
 * 
 * Sets the current fill alpha.
 * 
 * Parameters:
 * 
 * value - Number that represents the new fill alpha. Possible values are between
 * 1 (opaque) and 0 (transparent).
 */
mxXmlCanvas2D.prototype.setFillAlpha = function(value)
{
	if (this.compressed)
	{
		if (this.state.fillAlpha == value)
		{
			return;
		}
		
		mxAbstractCanvas2D.prototype.setFillAlpha.apply(this, arguments);
	}
	
	var elem = this.createElement('fillalpha');
	elem.setAttribute('alpha', this.format(value));
	this.root.appendChild(elem);
};

/**
 * Function: setStrokeAlpha
 * 
 * Sets the current stroke alpha.
 * 
 * Parameters:
 * 
 * value - Number that represents the new stroke alpha. Possible values are between
 * 1 (opaque) and 0 (transparent).
 */
mxXmlCanvas2D.prototype.setStrokeAlpha = function(value)
{
	if (this.compressed)
	{
		if (this.state.strokeAlpha == value)
		{
			return;
		}
		
		mxAbstractCanvas2D.prototype.setStrokeAlpha.apply(this, arguments);
	}
	
	var elem = this.createElement('strokealpha');
	elem.setAttribute('alpha', this.format(value));
	this.root.appendChild(elem);
};

/**
 * Function: setFillColor
 * 
 * Sets the current fill color.
 * 
 * Parameters:
 * 
 * value - Hexadecimal representation of the color or 'none'.
 */
mxXmlCanvas2D.prototype.setFillColor = function(value)
{
	if (value == mxConstants.NONE)
	{
		value = null;
	}
	
	if (this.compressed)
	{
		if (this.state.fillColor == value)
		{
			return;
		}
		
		mxAbstractCanvas2D.prototype.setFillColor.apply(this, arguments);
	}
	
	var elem = this.createElement('fillcolor');
	elem.setAttribute('color', (value != null) ? value : mxConstants.NONE);
	this.root.appendChild(elem);
};

/**
 * Function: setGradient
 * 
 * Sets the gradient. Note that the coordinates may be ignored by some implementations.
 * 
 * Parameters:
 * 
 * color1 - Hexadecimal representation of the start color.
 * color2 - Hexadecimal representation of the end color.
 * x - X-coordinate of the gradient region.
 * y - y-coordinate of the gradient region.
 * w - Width of the gradient region.
 * h - Height of the gradient region.
 * direction - One of <mxConstants.DIRECTION_NORTH>, <mxConstants.DIRECTION_EAST>,
 * <mxConstants.DIRECTION_SOUTH> or <mxConstants.DIRECTION_WEST>.
 * alpha1 - Optional alpha of the start color. Default is 1. Possible values
 * are between 1 (opaque) and 0 (transparent).
 * alpha2 - Optional alpha of the end color. Default is 1. Possible values
 * are between 1 (opaque) and 0 (transparent).
 */
mxXmlCanvas2D.prototype.setGradient = function(color1, color2, x, y, w, h, direction, alpha1, alpha2)
{
	if (color1 != null && color2 != null)
	{
		mxAbstractCanvas2D.prototype.setGradient.apply(this, arguments);
		
		var elem = this.createElement('gradient');
		elem.setAttribute('c1', color1);
		elem.setAttribute('c2', color2);
		elem.setAttribute('x', this.format(x));
		elem.setAttribute('y', this.format(y));
		elem.setAttribute('w', this.format(w));
		elem.setAttribute('h', this.format(h));
		
		// Default direction is south
		if (direction != null)
		{
			elem.setAttribute('direction', direction);
		}
		
		if (alpha1 != null)
		{
			elem.setAttribute('alpha1', alpha1);
		}
		
		if (alpha2 != null)
		{
			elem.setAttribute('alpha2', alpha2);
		}
		
		this.root.appendChild(elem);
	}
};

/**
 * Function: setStrokeColor
 * 
 * Sets the current stroke color.
 * 
 * Parameters:
 * 
 * value - Hexadecimal representation of the color or 'none'.
 */
mxXmlCanvas2D.prototype.setStrokeColor = function(value)
{
	if (value == mxConstants.NONE)
	{
		value = null;
	}
	
	if (this.compressed)
	{
		if (this.state.strokeColor == value)
		{
			return;
		}
		
		mxAbstractCanvas2D.prototype.setStrokeColor.apply(this, arguments);
	}
	
	var elem = this.createElement('strokecolor');
	elem.setAttribute('color', (value != null) ? value : mxConstants.NONE);
	this.root.appendChild(elem);
};

/**
 * Function: setStrokeWidth
 * 
 * Sets the current stroke width.
 * 
 * Parameters:
 * 
 * value - Numeric representation of the stroke width.
 */
mxXmlCanvas2D.prototype.setStrokeWidth = function(value)
{
	if (this.compressed)
	{
		if (this.state.strokeWidth == value)
		{
			return;
		}
		
		mxAbstractCanvas2D.prototype.setStrokeWidth.apply(this, arguments);
	}
	
	var elem = this.createElement('strokewidth');
	elem.setAttribute('width', this.format(value));
	this.root.appendChild(elem);
};

/**
 * Function: setDashed
 * 
 * Enables or disables dashed lines.
 * 
 * Parameters:
 * 
 * value - Boolean that specifies if dashed lines should be enabled.
 * value - Boolean that specifies if the stroke width should be ignored
 * for the dash pattern. Default is false.
 */
mxXmlCanvas2D.prototype.setDashed = function(value, fixDash)
{
	if (this.compressed)
	{
		if (this.state.dashed == value)
		{
			return;
		}
		
		mxAbstractCanvas2D.prototype.setDashed.apply(this, arguments);
	}
	
	var elem = this.createElement('dashed');
	elem.setAttribute('dashed', (value) ? '1' : '0');
	
	if (fixDash != null)
	{
		elem.setAttribute('fixDash', (fixDash) ? '1' : '0');
	}
	
	this.root.appendChild(elem);
};

/**
 * Function: setDashPattern
 * 
 * Sets the current dash pattern. Default is '3 3'.
 * 
 * Parameters:
 * 
 * value - String that represents the dash pattern, which is a sequence of
 * numbers defining the length of the dashes and the length of the spaces
 * between the dashes. The lengths are relative to the line width - a length
 * of 1 is equals to the line width.
 */
mxXmlCanvas2D.prototype.setDashPattern = function(value)
{
	if (this.compressed)
	{
		if (this.state.dashPattern == value)
		{
			return;
		}
		
		mxAbstractCanvas2D.prototype.setDashPattern.apply(this, arguments);
	}
	
	var elem = this.createElement('dashpattern');
	elem.setAttribute('pattern', value);
	this.root.appendChild(elem);
};

/**
 * Function: setLineCap
 * 
 * Sets the line cap. Default is 'flat' which corresponds to 'butt' in SVG.
 * 
 * Parameters:
 * 
 * value - String that represents the line cap. Possible values are flat, round
 * and square.
 */
mxXmlCanvas2D.prototype.setLineCap = function(value)
{
	if (this.compressed)
	{
		if (this.state.lineCap == value)
		{
			return;
		}
		
		mxAbstractCanvas2D.prototype.setLineCap.apply(this, arguments);
	}
	
	var elem = this.createElement('linecap');
	elem.setAttribute('cap', value);
	this.root.appendChild(elem);
};

/**
 * Function: setLineJoin
 * 
 * Sets the line join. Default is 'miter'.
 * 
 * Parameters:
 * 
 * value - String that represents the line join. Possible values are miter,
 * round and bevel.
 */
mxXmlCanvas2D.prototype.setLineJoin = function(value)
{
	if (this.compressed)
	{
		if (this.state.lineJoin == value)
		{
			return;
		}
		
		mxAbstractCanvas2D.prototype.setLineJoin.apply(this, arguments);
	}
	
	var elem = this.createElement('linejoin');
	elem.setAttribute('join', value);
	this.root.appendChild(elem);
};

/**
 * Function: setMiterLimit
 * 
 * Sets the miter limit. Default is 10.
 * 
 * Parameters:
 * 
 * value - Number that represents the miter limit.
 */
mxXmlCanvas2D.prototype.setMiterLimit = function(value)
{
	if (this.compressed)
	{
		if (this.state.miterLimit == value)
		{
			return;
		}
		
		mxAbstractCanvas2D.prototype.setMiterLimit.apply(this, arguments);
	}
	
	var elem = this.createElement('miterlimit');
	elem.setAttribute('limit', value);
	this.root.appendChild(elem);
};

/**
 * Function: setFontColor
 * 
 * Sets the current font color. Default is '#000000'.
 * 
 * Parameters:
 * 
 * value - Hexadecimal representation of the color or 'none'.
 */
mxXmlCanvas2D.prototype.setFontColor = function(value)
{
	if (this.textEnabled)
	{
		if (value == mxConstants.NONE)
		{
			value = null;
		}
		
		if (this.compressed)
		{
			if (this.state.fontColor == value)
			{
				return;
			}
			
			mxAbstractCanvas2D.prototype.setFontColor.apply(this, arguments);
		}
		
		var elem = this.createElement('fontcolor');
		elem.setAttribute('color', (value != null) ? value : mxConstants.NONE);
		this.root.appendChild(elem);
	}
};

/**
 * Function: setFontBackgroundColor
 * 
 * Sets the current font background color.
 * 
 * Parameters:
 * 
 * value - Hexadecimal representation of the color or 'none'.
 */
mxXmlCanvas2D.prototype.setFontBackgroundColor = function(value)
{
	if (this.textEnabled)
	{
		if (value == mxConstants.NONE)
		{
			value = null;
		}
		
		if (this.compressed)
		{
			if (this.state.fontBackgroundColor == value)
			{
				return;
			}
			
			mxAbstractCanvas2D.prototype.setFontBackgroundColor.apply(this, arguments);
		}

		var elem = this.createElement('fontbackgroundcolor');
		elem.setAttribute('color', (value != null) ? value : mxConstants.NONE);
		this.root.appendChild(elem);
	}
};

/**
 * Function: setFontBorderColor
 * 
 * Sets the current font border color.
 * 
 * Parameters:
 * 
 * value - Hexadecimal representation of the color or 'none'.
 */
mxXmlCanvas2D.prototype.setFontBorderColor = function(value)
{
	if (this.textEnabled)
	{
		if (value == mxConstants.NONE)
		{
			value = null;
		}
		
		if (this.compressed)
		{
			if (this.state.fontBorderColor == value)
			{
				return;
			}
			
			mxAbstractCanvas2D.prototype.setFontBorderColor.apply(this, arguments);
		}
		
		var elem = this.createElement('fontbordercolor');
		elem.setAttribute('color', (value != null) ? value : mxConstants.NONE);
		this.root.appendChild(elem);
	}
};

/**
 * Function: setFontSize
 * 
 * Sets the current font size. Default is <mxConstants.DEFAULT_FONTSIZE>.
 * 
 * Parameters:
 * 
 * value - Numeric representation of the font size.
 */
mxXmlCanvas2D.prototype.setFontSize = function(value)
{
	if (this.textEnabled)
	{
		if (this.compressed)
		{
			if (this.state.fontSize == value)
			{
				return;
			}
			
			mxAbstractCanvas2D.prototype.setFontSize.apply(this, arguments);
		}
		
		var elem = this.createElement('fontsize');
		elem.setAttribute('size', value);
		this.root.appendChild(elem);
	}
};

/**
 * Function: setFontFamily
 * 
 * Sets the current font family. Default is <mxConstants.DEFAULT_FONTFAMILY>.
 * 
 * Parameters:
 * 
 * value - String representation of the font family. This handles the same
 * values as the CSS font-family property.
 */
mxXmlCanvas2D.prototype.setFontFamily = function(value)
{
	if (this.textEnabled)
	{
		if (this.compressed)
		{
			if (this.state.fontFamily == value)
			{
				return;
			}
			
			mxAbstractCanvas2D.prototype.setFontFamily.apply(this, arguments);
		}
		
		var elem = this.createElement('fontfamily');
		elem.setAttribute('family', value);
		this.root.appendChild(elem);
	}
};

/**
 * Function: setFontStyle
 * 
 * Sets the current font style.
 * 
 * Parameters:
 * 
 * value - Numeric representation of the font family. This is the sum of the
 * font styles from <mxConstants>.
 */
mxXmlCanvas2D.prototype.setFontStyle = function(value)
{
	if (this.textEnabled)
	{
		if (value == null)
		{
			value = 0;
		}
		
		if (this.compressed)
		{
			if (this.state.fontStyle == value)
			{
				return;
			}
			
			mxAbstractCanvas2D.prototype.setFontStyle.apply(this, arguments);
		}
		
		var elem = this.createElement('fontstyle');
		elem.setAttribute('style', value);
		this.root.appendChild(elem);
	}
};

/**
 * Function: setShadow
 * 
 * Enables or disables shadows.
 * 
 * Parameters:
 * 
 * value - Boolean that specifies if shadows should be enabled.
 */
mxXmlCanvas2D.prototype.setShadow = function(value)
{
	if (this.compressed)
	{
		if (this.state.shadow == value)
		{
			return;
		}
		
		mxAbstractCanvas2D.prototype.setShadow.apply(this, arguments);
	}
	
	var elem = this.createElement('shadow');
	elem.setAttribute('enabled', (value) ? '1' : '0');
	this.root.appendChild(elem);
};

/**
 * Function: setShadowColor
 * 
 * Sets the current shadow color. Default is <mxConstants.SHADOWCOLOR>.
 * 
 * Parameters:
 * 
 * value - Hexadecimal representation of the color or 'none'.
 */
mxXmlCanvas2D.prototype.setShadowColor = function(value)
{
	if (this.compressed)
	{
		if (value == mxConstants.NONE)
		{
			value = null;
		}
		
		if (this.state.shadowColor == value)
		{
			return;
		}
		
		mxAbstractCanvas2D.prototype.setShadowColor.apply(this, arguments);
	}
	
	var elem = this.createElement('shadowcolor');
	elem.setAttribute('color', (value != null) ? value : mxConstants.NONE);
	this.root.appendChild(elem);
};

/**
 * Function: setShadowAlpha
 * 
 * Sets the current shadows alpha. Default is <mxConstants.SHADOW_OPACITY>.
 * 
 * Parameters:
 * 
 * value - Number that represents the new alpha. Possible values are between
 * 1 (opaque) and 0 (transparent).
 */
mxXmlCanvas2D.prototype.setShadowAlpha = function(value)
{
	if (this.compressed)
	{
		if (this.state.shadowAlpha == value)
		{
			return;
		}
		
		mxAbstractCanvas2D.prototype.setShadowAlpha.apply(this, arguments);
	}
	
	var elem = this.createElement('shadowalpha');
	elem.setAttribute('alpha', value);
	this.root.appendChild(elem);
	
};

/**
 * Function: setShadowOffset
 * 
 * Sets the current shadow offset.
 * 
 * Parameters:
 * 
 * dx - Number that represents the horizontal offset of the shadow.
 * dy - Number that represents the vertical offset of the shadow.
 */
mxXmlCanvas2D.prototype.setShadowOffset = function(dx, dy)
{
	if (this.compressed)
	{
		if (this.state.shadowDx == dx && this.state.shadowDy == dy)
		{
			return;
		}
		
		mxAbstractCanvas2D.prototype.setShadowOffset.apply(this, arguments);
	}
	
	var elem = this.createElement('shadowoffset');
	elem.setAttribute('dx', dx);
	elem.setAttribute('dy', dy);
	this.root.appendChild(elem);
	
};

/**
 * Function: rect
 * 
 * Puts a rectangle into the drawing buffer.
 * 
 * Parameters:
 * 
 * x - Number that represents the x-coordinate of the rectangle.
 * y - Number that represents the y-coordinate of the rectangle.
 * w - Number that represents the width of the rectangle.
 * h - Number that represents the height of the rectangle.
 */
mxXmlCanvas2D.prototype.rect = function(x, y, w, h)
{
	var elem = this.createElement('rect');
	elem.setAttribute('x', this.format(x));
	elem.setAttribute('y', this.format(y));
	elem.setAttribute('w', this.format(w));
	elem.setAttribute('h', this.format(h));
	this.root.appendChild(elem);
};

/**
 * Function: roundrect
 * 
 * Puts a rounded rectangle into the drawing buffer.
 * 
 * Parameters:
 * 
 * x - Number that represents the x-coordinate of the rectangle.
 * y - Number that represents the y-coordinate of the rectangle.
 * w - Number that represents the width of the rectangle.
 * h - Number that represents the height of the rectangle.
 * dx - Number that represents the horizontal rounding.
 * dy - Number that represents the vertical rounding.
 */
mxXmlCanvas2D.prototype.roundrect = function(x, y, w, h, dx, dy)
{
	var elem = this.createElement('roundrect');
	elem.setAttribute('x', this.format(x));
	elem.setAttribute('y', this.format(y));
	elem.setAttribute('w', this.format(w));
	elem.setAttribute('h', this.format(h));
	elem.setAttribute('dx', this.format(dx));
	elem.setAttribute('dy', this.format(dy));
	this.root.appendChild(elem);
};

/**
 * Function: ellipse
 * 
 * Puts an ellipse into the drawing buffer.
 * 
 * Parameters:
 * 
 * x - Number that represents the x-coordinate of the ellipse.
 * y - Number that represents the y-coordinate of the ellipse.
 * w - Number that represents the width of the ellipse.
 * h - Number that represents the height of the ellipse.
 */
mxXmlCanvas2D.prototype.ellipse = function(x, y, w, h)
{
	var elem = this.createElement('ellipse');
	elem.setAttribute('x', this.format(x));
	elem.setAttribute('y', this.format(y));
	elem.setAttribute('w', this.format(w));
	elem.setAttribute('h', this.format(h));
	this.root.appendChild(elem);
};

/**
 * Function: image
 * 
 * Paints an image.
 * 
 * Parameters:
 * 
 * x - Number that represents the x-coordinate of the image.
 * y - Number that represents the y-coordinate of the image.
 * w - Number that represents the width of the image.
 * h - Number that represents the height of the image.
 * src - String that specifies the URL of the image.
 * aspect - Boolean indicating if the aspect of the image should be preserved.
 * flipH - Boolean indicating if the image should be flipped horizontally.
 * flipV - Boolean indicating if the image should be flipped vertically.
 */
mxXmlCanvas2D.prototype.image = function(x, y, w, h, src, aspect, flipH, flipV)
{
	src = this.converter.convert(src);
	
	// LATER: Add option for embedding images as base64.
	var elem = this.createElement('image');
	elem.setAttribute('x', this.format(x));
	elem.setAttribute('y', this.format(y));
	elem.setAttribute('w', this.format(w));
	elem.setAttribute('h', this.format(h));
	elem.setAttribute('src', src);
	elem.setAttribute('aspect', (aspect) ? '1' : '0');
	elem.setAttribute('flipH', (flipH) ? '1' : '0');
	elem.setAttribute('flipV', (flipV) ? '1' : '0');
	this.root.appendChild(elem);
};

/**
 * Function: begin
 * 
 * Starts a new path and puts it into the drawing buffer.
 */
mxXmlCanvas2D.prototype.begin = function()
{
	this.root.appendChild(this.createElement('begin'));
	this.lastX = 0;
	this.lastY = 0;
};

/**
 * Function: moveTo
 * 
 * Moves the current path the given point.
 * 
 * Parameters:
 * 
 * x - Number that represents the x-coordinate of the point.
 * y - Number that represents the y-coordinate of the point.
 */
mxXmlCanvas2D.prototype.moveTo = function(x, y)
{
	var elem = this.createElement('move');
	elem.setAttribute('x', this.format(x));
	elem.setAttribute('y', this.format(y));
	this.root.appendChild(elem);
	this.lastX = x;
	this.lastY = y;
};

/**
 * Function: lineTo
 * 
 * Draws a line to the given coordinates.
 * 
 * Parameters:
 * 
 * x - Number that represents the x-coordinate of the endpoint.
 * y - Number that represents the y-coordinate of the endpoint.
 */
mxXmlCanvas2D.prototype.lineTo = function(x, y)
{
	var elem = this.createElement('line');
	elem.setAttribute('x', this.format(x));
	elem.setAttribute('y', this.format(y));
	this.root.appendChild(elem);
	this.lastX = x;
	this.lastY = y;
};

/**
 * Function: quadTo
 * 
 * Adds a quadratic curve to the current path.
 * 
 * Parameters:
 * 
 * x1 - Number that represents the x-coordinate of the control point.
 * y1 - Number that represents the y-coordinate of the control point.
 * x2 - Number that represents the x-coordinate of the endpoint.
 * y2 - Number that represents the y-coordinate of the endpoint.
 */
mxXmlCanvas2D.prototype.quadTo = function(x1, y1, x2, y2)
{
	var elem = this.createElement('quad');
	elem.setAttribute('x1', this.format(x1));
	elem.setAttribute('y1', this.format(y1));
	elem.setAttribute('x2', this.format(x2));
	elem.setAttribute('y2', this.format(y2));
	this.root.appendChild(elem);
	this.lastX = x2;
	this.lastY = y2;
};

/**
 * Function: curveTo
 * 
 * Adds a bezier curve to the current path.
 * 
 * Parameters:
 * 
 * x1 - Number that represents the x-coordinate of the first control point.
 * y1 - Number that represents the y-coordinate of the first control point.
 * x2 - Number that represents the x-coordinate of the second control point.
 * y2 - Number that represents the y-coordinate of the second control point.
 * x3 - Number that represents the x-coordinate of the endpoint.
 * y3 - Number that represents the y-coordinate of the endpoint.
 */
mxXmlCanvas2D.prototype.curveTo = function(x1, y1, x2, y2, x3, y3)
{
	var elem = this.createElement('curve');
	elem.setAttribute('x1', this.format(x1));
	elem.setAttribute('y1', this.format(y1));
	elem.setAttribute('x2', this.format(x2));
	elem.setAttribute('y2', this.format(y2));
	elem.setAttribute('x3', this.format(x3));
	elem.setAttribute('y3', this.format(y3));
	this.root.appendChild(elem);
	this.lastX = x3;
	this.lastY = y3;
};

/**
 * Function: close
 * 
 * Closes the current path.
 */
mxXmlCanvas2D.prototype.close = function()
{
	this.root.appendChild(this.createElement('close'));
};

/**
 * Function: text
 * 
 * Paints the given text. Possible values for format are empty string for
 * plain text and html for HTML markup. Background and border color as well
 * as clipping is not available in plain text labels for VML. HTML labels
 * are not available as part of shapes with no foreignObject support in SVG
 * (eg. IE9, IE10).
 * 
 * Parameters:
 * 
 * x - Number that represents the x-coordinate of the text.
 * y - Number that represents the y-coordinate of the text.
 * w - Number that represents the available width for the text or 0 for automatic width.
 * h - Number that represents the available height for the text or 0 for automatic height.
 * str - String that specifies the text to be painted.
 * align - String that represents the horizontal alignment.
 * valign - String that represents the vertical alignment.
 * wrap - Boolean that specifies if word-wrapping is enabled. Requires w > 0.
 * format - Empty string for plain text or 'html' for HTML markup.
 * overflow - Specifies the overflow behaviour of the label. Requires w > 0 and/or h > 0.
 * clip - Boolean that specifies if the label should be clipped. Requires w > 0 and/or h > 0.
 * rotation - Number that specifies the angle of the rotation around the anchor point of the text.
 * dir - Optional string that specifies the text direction. Possible values are rtl and lrt.
 */
mxXmlCanvas2D.prototype.text = function(x, y, w, h, str, align, valign, wrap, format, overflow, clip, rotation, dir)
{
	if (this.textEnabled && str != null)
	{
		if (mxUtils.isNode(str))
		{
			str = mxUtils.getOuterHtml(str);
		}
		
		var elem = this.createElement('text');
		elem.setAttribute('x', this.format(x));
		elem.setAttribute('y', this.format(y));
		elem.setAttribute('w', this.format(w));
		elem.setAttribute('h', this.format(h));
		elem.setAttribute('str', str);
		
		if (align != null)
		{
			elem.setAttribute('align', align);
		}
		
		if (valign != null)
		{
			elem.setAttribute('valign', valign);
		}
		
		elem.setAttribute('wrap', (wrap) ? '1' : '0');
		
		if (format == null)
		{
			format = '';
		}
		
		elem.setAttribute('format', format);
		
		if (overflow != null)
		{
			elem.setAttribute('overflow', overflow);
		}
		
		if (clip != null)
		{
			elem.setAttribute('clip', (clip) ? '1' : '0');
		}
		
		if (rotation != null)
		{
			elem.setAttribute('rotation', rotation);
		}
		
		if (dir != null)
		{
			elem.setAttribute('dir', dir);
		}
		
		this.root.appendChild(elem);
	}
};

/**
 * Function: stroke
 * 
 * Paints the outline of the current drawing buffer.
 */
mxXmlCanvas2D.prototype.stroke = function()
{
	this.root.appendChild(this.createElement('stroke'));
};

/**
 * Function: fill
 * 
 * Fills the current drawing buffer.
 */
mxXmlCanvas2D.prototype.fill = function()
{
	this.root.appendChild(this.createElement('fill'));
};

/**
 * Function: fillAndStroke
 * 
 * Fills the current drawing buffer and its outline.
 */
mxXmlCanvas2D.prototype.fillAndStroke = function()
{
	this.root.appendChild(this.createElement('fillstroke'));
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxSvgCanvas2D
 *
 * Extends <mxAbstractCanvas2D> to implement a canvas for SVG. This canvas writes all
 * calls as SVG output to the given SVG root node.
 * 
 * (code)
 * var svgDoc = mxUtils.createXmlDocument();
 * var root = (svgDoc.createElementNS != null) ?
 * 		svgDoc.createElementNS(mxConstants.NS_SVG, 'svg') : svgDoc.createElement('svg');
 * 
 * if (svgDoc.createElementNS == null)
 * {
 *   root.setAttribute('xmlns', mxConstants.NS_SVG);
 *   root.setAttribute('xmlns:xlink', mxConstants.NS_XLINK);
 * }
 * else
 * {
 *   root.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xlink', mxConstants.NS_XLINK);
 * }
 * 
 * var bounds = graph.getGraphBounds();
 * root.setAttribute('width', (bounds.x + bounds.width + 4) + 'px');
 * root.setAttribute('height', (bounds.y + bounds.height + 4) + 'px');
 * root.setAttribute('version', '1.1');
 * 
 * svgDoc.appendChild(root);
 * 
 * var svgCanvas = new mxSvgCanvas2D(root);
 * (end)
 * 
 * A description of the public API is available in <mxXmlCanvas2D>.
 * 
 * To disable anti-aliasing in the output, use the following code.
 * 
 * (code)
 * graph.view.canvas.ownerSVGElement.setAttribute('shape-rendering', 'crispEdges');
 * (end)
 * 
 * Or set the respective attribute in the SVG element directly.
 * 
 * Constructor: mxSvgCanvas2D
 *
 * Constructs a new SVG canvas.
 * 
 * Parameters:
 * 
 * root - SVG container for the output.
 * styleEnabled - Optional boolean that specifies if a style section should be
 * added. The style section sets the default font-size, font-family and
 * stroke-miterlimit globally. Default is false.
 */
function mxSvgCanvas2D(root, styleEnabled)
{
	mxAbstractCanvas2D.call(this);

	/**
	 * Variable: root
	 * 
	 * Reference to the container for the SVG content.
	 */
	this.root = root;

	/**
	 * Variable: gradients
	 * 
	 * Local cache of gradients for quick lookups.
	 */
	this.gradients = [];

	/**
	 * Variable: defs
	 * 
	 * Reference to the defs section of the SVG document. Only for export.
	 */
	this.defs = null;
	
	/**
	 * Variable: styleEnabled
	 * 
	 * Stores the value of styleEnabled passed to the constructor.
	 */
	this.styleEnabled = (styleEnabled != null) ? styleEnabled : false;
	
	var svg = null;
	
	// Adds optional defs section for export
	if (root.ownerDocument != document)
	{
		var node = root;

		// Finds owner SVG element in XML DOM
		while (node != null && node.nodeName != 'svg')
		{
			node = node.parentNode;
		}
		
		svg = node;
	}

	if (svg != null)
	{
		// Tries to get existing defs section
		var tmp = svg.getElementsByTagName('defs');
		
		if (tmp.length > 0)
		{
			this.defs = svg.getElementsByTagName('defs')[0];
		}
		
		// Adds defs section if none exists
		if (this.defs == null)
		{
			this.defs = this.createElement('defs');
			
			if (svg.firstChild != null)
			{
				svg.insertBefore(this.defs, svg.firstChild);
			}
			else
			{
				svg.appendChild(this.defs);
			}
		}

		// Adds stylesheet
		if (this.styleEnabled)
		{
			this.defs.appendChild(this.createStyle());
		}
	}
};

/**
 * Extends mxAbstractCanvas2D
 */
mxUtils.extend(mxSvgCanvas2D, mxAbstractCanvas2D);

/**
 * Capability check for DOM parser.
 */
(function()
{
	mxSvgCanvas2D.prototype.useDomParser = !mxClient.IS_IE && typeof DOMParser === 'function' && typeof XMLSerializer === 'function';
	
	if (mxSvgCanvas2D.prototype.useDomParser)
	{
		// Checks using a generic test text if the parsing actually works. This is a workaround
		// for older browsers where the capability check returns true but the parsing fails.
		try
		{
			var doc = new DOMParser().parseFromString('test text', 'text/html');
			mxSvgCanvas2D.prototype.useDomParser = doc != null;
		}
		catch (e)
		{
			mxSvgCanvas2D.prototype.useDomParser = false;
		}
	}
})();

/**
 * Variable: path
 * 
 * Holds the current DOM node.
 */
mxSvgCanvas2D.prototype.node = null;

/**
 * Variable: matchHtmlAlignment
 * 
 * Specifies if plain text output should match the vertical HTML alignment.
 * Defaul is true.
 */
mxSvgCanvas2D.prototype.matchHtmlAlignment = true;

/**
 * Variable: textEnabled
 * 
 * Specifies if text output should be enabled. Default is true.
 */
mxSvgCanvas2D.prototype.textEnabled = true;

/**
 * Variable: foEnabled
 * 
 * Specifies if use of foreignObject for HTML markup is allowed. Default is true.
 */
mxSvgCanvas2D.prototype.foEnabled = true;

/**
 * Variable: foAltText
 * 
 * Specifies the fallback text for unsupported foreignObjects in exported
 * documents. Default is '[Object]'. If this is set to null then no fallback
 * text is added to the exported document.
 */
mxSvgCanvas2D.prototype.foAltText = '[Object]';

/**
 * Variable: foOffset
 * 
 * Offset to be used for foreignObjects.
 */
mxSvgCanvas2D.prototype.foOffset = 0;

/**
 * Variable: textOffset
 * 
 * Offset to be used for text elements.
 */
mxSvgCanvas2D.prototype.textOffset = 0;

/**
 * Variable: imageOffset
 * 
 * Offset to be used for image elements.
 */
mxSvgCanvas2D.prototype.imageOffset = 0;

/**
 * Variable: strokeTolerance
 * 
 * Adds transparent paths for strokes.
 */
mxSvgCanvas2D.prototype.strokeTolerance = 0;

/**
 * Variable: refCount
 * 
 * Local counter for references in SVG export.
 */
mxSvgCanvas2D.prototype.refCount = 0;

/**
 * Variable: blockImagePointerEvents
 * 
 * Specifies if a transparent rectangle should be added on top of images to absorb
 * all pointer events. Default is false. This is only needed in Firefox to disable
 * control-clicks on images.
 */
mxSvgCanvas2D.prototype.blockImagePointerEvents = false;

/**
 * Variable: lineHeightCorrection
 * 
 * Correction factor for <mxConstants.LINE_HEIGHT> in HTML output. Default is 1.
 */
mxSvgCanvas2D.prototype.lineHeightCorrection = 1;

/**
 * Variable: pointerEventsValue
 * 
 * Default value for active pointer events. Default is all.
 */
mxSvgCanvas2D.prototype.pointerEventsValue = 'all';

/**
 * Variable: fontMetricsPadding
 * 
 * Padding to be added for text that is not wrapped to account for differences
 * in font metrics on different platforms in pixels. Default is 10.
 */
mxSvgCanvas2D.prototype.fontMetricsPadding = 10;

/**
 * Variable: cacheOffsetSize
 * 
 * Specifies if offsetWidth and offsetHeight should be cached. Default is true.
 * This is used to speed up repaint of text in <updateText>.
 */
mxSvgCanvas2D.prototype.cacheOffsetSize = true;

/**
 * Function: format
 * 
 * Rounds all numbers to 2 decimal points.
 */
mxSvgCanvas2D.prototype.format = function(value)
{
	return parseFloat(parseFloat(value).toFixed(2));
};

/**
 * Function: getBaseUrl
 * 
 * Returns the URL of the page without the hash part. This needs to use href to
 * include any search part with no params (ie question mark alone). This is a
 * workaround for the fact that window.location.search is empty if there is
 * no search string behind the question mark.
 */
mxSvgCanvas2D.prototype.getBaseUrl = function()
{
	var href = window.location.href;
	var hash = href.lastIndexOf('#');
	
	if (hash > 0)
	{
		href = href.substring(0, hash);
	}
	
	return href;
};

/**
 * Function: reset
 * 
 * Returns any offsets for rendering pixels.
 */
mxSvgCanvas2D.prototype.reset = function()
{
	mxAbstractCanvas2D.prototype.reset.apply(this, arguments);
	this.gradients = [];
};

/**
 * Function: createStyle
 * 
 * Creates the optional style section.
 */
mxSvgCanvas2D.prototype.createStyle = function(x)
{
	var style = this.createElement('style');
	style.setAttribute('type', 'text/css');
	mxUtils.write(style, 'svg{font-family:' + mxConstants.DEFAULT_FONTFAMILY +
			';font-size:' + mxConstants.DEFAULT_FONTSIZE +
			';fill:none;stroke-miterlimit:10}');
	
	return style;
};

/**
 * Function: createElement
 * 
 * Private helper function to create SVG elements
 */
mxSvgCanvas2D.prototype.createElement = function(tagName, namespace)
{
	if (this.root.ownerDocument.createElementNS != null)
	{
		return this.root.ownerDocument.createElementNS(namespace || mxConstants.NS_SVG, tagName);
	}
	else
	{
		var elt = this.root.ownerDocument.createElement(tagName);
		
		if (namespace != null)
		{
			elt.setAttribute('xmlns', namespace);
		}
		
		return elt;
	}
};

/**
 * Function: getAlternateContent
 * 
 * Returns the alternate content for the given foreignObject.
 */
mxSvgCanvas2D.prototype.createAlternateContent = function(fo, x, y, w, h, str, align, valign, wrap, format, overflow, clip, rotation)
{
	if (this.foAltText != null)
	{
		var s = this.state;
		var alt = this.createElement('text');
		alt.setAttribute('x', Math.round(w / 2));
		alt.setAttribute('y', Math.round((h + s.fontSize) / 2));
		alt.setAttribute('fill', s.fontColor || 'black');
		alt.setAttribute('text-anchor', 'middle');
		alt.setAttribute('font-size', s.fontSize + 'px');
		alt.setAttribute('font-family', s.fontFamily);
		
		if ((s.fontStyle & mxConstants.FONT_BOLD) == mxConstants.FONT_BOLD)
		{
			alt.setAttribute('font-weight', 'bold');
		}
		
		if ((s.fontStyle & mxConstants.FONT_ITALIC) == mxConstants.FONT_ITALIC)
		{
			alt.setAttribute('font-style', 'italic');
		}
		
		if ((s.fontStyle & mxConstants.FONT_UNDERLINE) == mxConstants.FONT_UNDERLINE)
		{
			alt.setAttribute('text-decoration', 'underline');
		}
		
		mxUtils.write(alt, this.foAltText);
		
		return alt;
	}
	else
	{
		return null;
	}
};

/**
 * Function: createGradientId
 * 
 * Private helper function to create SVG elements
 */
mxSvgCanvas2D.prototype.createGradientId = function(start, end, alpha1, alpha2, direction)
{
	// Removes illegal characters from gradient ID
	if (start.charAt(0) == '#')
	{
		start = start.substring(1);
	}
	
	if (end.charAt(0) == '#')
	{
		end = end.substring(1);
	}
	
	// Workaround for gradient IDs not working in Safari 5 / Chrome 6
	// if they contain uppercase characters
	start = start.toLowerCase() + '-' + alpha1;
	end = end.toLowerCase() + '-' + alpha2;

	// Wrong gradient directions possible?
	var dir = null;
	
	if (direction == null || direction == mxConstants.DIRECTION_SOUTH)
	{
		dir = 's';
	}
	else if (direction == mxConstants.DIRECTION_EAST)
	{
		dir = 'e';
	}
	else
	{
		var tmp = start;
		start = end;
		end = tmp;
		
		if (direction == mxConstants.DIRECTION_NORTH)
		{
			dir = 's';
		}
		else if (direction == mxConstants.DIRECTION_WEST)
		{
			dir = 'e';
		}
	}
	
	return 'mx-gradient-' + start + '-' + end + '-' + dir;
};

/**
 * Function: getSvgGradient
 * 
 * Private helper function to create SVG elements
 */
mxSvgCanvas2D.prototype.getSvgGradient = function(start, end, alpha1, alpha2, direction)
{
	var id = this.createGradientId(start, end, alpha1, alpha2, direction);
	var gradient = this.gradients[id];
	
	if (gradient == null)
	{
		var svg = this.root.ownerSVGElement;

		var counter = 0;
		var tmpId = id + '-' + counter;

		if (svg != null)
		{
			gradient = svg.ownerDocument.getElementById(tmpId);
			
			while (gradient != null && gradient.ownerSVGElement != svg)
			{
				tmpId = id + '-' + counter++;
				gradient = svg.ownerDocument.getElementById(tmpId);
			}
		}
		else
		{
			// Uses shorter IDs for export
			tmpId = 'id' + (++this.refCount);
		}
		
		if (gradient == null)
		{
			gradient = this.createSvgGradient(start, end, alpha1, alpha2, direction);
			gradient.setAttribute('id', tmpId);
			
			if (this.defs != null)
			{
				this.defs.appendChild(gradient);
			}
			else
			{
				svg.appendChild(gradient);
			}
		}

		this.gradients[id] = gradient;
	}

	return gradient.getAttribute('id');
};

/**
 * Function: createSvgGradient
 * 
 * Creates the given SVG gradient.
 */
mxSvgCanvas2D.prototype.createSvgGradient = function(start, end, alpha1, alpha2, direction)
{
	var gradient = this.createElement('linearGradient');
	gradient.setAttribute('x1', '0%');
	gradient.setAttribute('y1', '0%');
	gradient.setAttribute('x2', '0%');
	gradient.setAttribute('y2', '0%');
	
	if (direction == null || direction == mxConstants.DIRECTION_SOUTH)
	{
		gradient.setAttribute('y2', '100%');
	}
	else if (direction == mxConstants.DIRECTION_EAST)
	{
		gradient.setAttribute('x2', '100%');
	}
	else if (direction == mxConstants.DIRECTION_NORTH)
	{
		gradient.setAttribute('y1', '100%');
	}
	else if (direction == mxConstants.DIRECTION_WEST)
	{
		gradient.setAttribute('x1', '100%');
	}
	
	var op = (alpha1 < 1) ? ';stop-opacity:' + alpha1 : '';
	
	var stop = this.createElement('stop');
	stop.setAttribute('offset', '0%');
	stop.setAttribute('style', 'stop-color:' + start + op);
	gradient.appendChild(stop);
	
	op = (alpha2 < 1) ? ';stop-opacity:' + alpha2 : '';
	
	stop = this.createElement('stop');
	stop.setAttribute('offset', '100%');
	stop.setAttribute('style', 'stop-color:' + end + op);
	gradient.appendChild(stop);
	
	return gradient;
};

/**
 * Function: addNode
 * 
 * Private helper function to create SVG elements
 */
mxSvgCanvas2D.prototype.addNode = function(filled, stroked)
{
	var node = this.node;
	var s = this.state;

	if (node != null)
	{
		if (node.nodeName == 'path')
		{
			// Checks if the path is not empty
			if (this.path != null && this.path.length > 0)
			{
				node.setAttribute('d', this.path.join(' '));
			}
			else
			{
				return;
			}
		}

		if (filled && s.fillColor != null)
		{
			this.updateFill();
		}
		else if (!this.styleEnabled)
		{
			// Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=814952
			if (node.nodeName == 'ellipse' && mxClient.IS_FF)
			{
				node.setAttribute('fill', 'transparent');
			}
			else
			{
				node.setAttribute('fill', 'none');
			}
			
			// Sets the actual filled state for stroke tolerance
			filled = false;
		}
		
		if (stroked && s.strokeColor != null)
		{
			this.updateStroke();
		}
		else if (!this.styleEnabled)
		{
			node.setAttribute('stroke', 'none');
		}
		
		if (s.transform != null && s.transform.length > 0)
		{
			node.setAttribute('transform', s.transform);
		}
		
		if (s.shadow)
		{
			this.root.appendChild(this.createShadow(node));
		}
	
		// Adds stroke tolerance
		if (this.strokeTolerance > 0 && !filled)
		{
			this.root.appendChild(this.createTolerance(node));
		}

		// Adds pointer events
		if (this.pointerEvents && (node.nodeName != 'path' ||
			this.path[this.path.length - 1] == this.closeOp))
		{
			node.setAttribute('pointer-events', this.pointerEventsValue);
		}
		// Enables clicks for nodes inside a link element
		else if (!this.pointerEvents && this.originalRoot == null)
		{
			node.setAttribute('pointer-events', 'none');
		}
		
		// Removes invisible nodes from output if they don't handle events
		if ((node.nodeName != 'rect' && node.nodeName != 'path' && node.nodeName != 'ellipse') ||
			(node.getAttribute('fill') != 'none' && node.getAttribute('fill') != 'transparent') ||
			node.getAttribute('stroke') != 'none' || node.getAttribute('pointer-events') != 'none')
		{
			// LATER: Update existing DOM for performance		
			this.root.appendChild(node);
		}
		
		this.node = null;
	}
};

/**
 * Function: updateFill
 * 
 * Transfers the stroke attributes from <state> to <node>.
 */
mxSvgCanvas2D.prototype.updateFill = function()
{
	var s = this.state;
	
	if (s.alpha < 1 || s.fillAlpha < 1)
	{
		this.node.setAttribute('fill-opacity', s.alpha * s.fillAlpha);
	}
	
	if (s.fillColor != null)
	{
		if (s.gradientColor != null)
		{
			var id = this.getSvgGradient(s.fillColor, s.gradientColor, s.gradientFillAlpha, s.gradientAlpha, s.gradientDirection);
			
			if (!mxClient.IS_CHROME_APP && !mxClient.IS_IE && !mxClient.IS_IE11 &&
				!mxClient.IS_EDGE && this.root.ownerDocument == document)
			{
				// Workaround for potential base tag and brackets must be escaped
				var base = this.getBaseUrl().replace(/([\(\)])/g, '\\$1');
				this.node.setAttribute('fill', 'url(' + base + '#' + id + ')');
			}
			else
			{
				this.node.setAttribute('fill', 'url(#' + id + ')');
			}
		}
		else
		{
			this.node.setAttribute('fill', s.fillColor.toLowerCase());
		}
	}
};

/**
 * Function: getCurrentStrokeWidth
 * 
 * Returns the current stroke width (>= 1), ie. max(1, this.format(this.state.strokeWidth * this.state.scale)).
 */
mxSvgCanvas2D.prototype.getCurrentStrokeWidth = function()
{
	return Math.max(1, this.format(this.state.strokeWidth * this.state.scale));
};

/**
 * Function: updateStroke
 * 
 * Transfers the stroke attributes from <state> to <node>.
 */
mxSvgCanvas2D.prototype.updateStroke = function()
{
	var s = this.state;

	this.node.setAttribute('stroke', s.strokeColor.toLowerCase());
	
	if (s.alpha < 1 || s.strokeAlpha < 1)
	{
		this.node.setAttribute('stroke-opacity', s.alpha * s.strokeAlpha);
	}
	
	var sw = this.getCurrentStrokeWidth();
	
	if (sw != 1)
	{
		this.node.setAttribute('stroke-width', sw);
	}
	
	if (this.node.nodeName == 'path')
	{
		this.updateStrokeAttributes();
	}
	
	if (s.dashed)
	{
		this.node.setAttribute('stroke-dasharray', this.createDashPattern(
			((s.fixDash) ? 1 : s.strokeWidth) * s.scale));
	}
};

/**
 * Function: updateStrokeAttributes
 * 
 * Transfers the stroke attributes from <state> to <node>.
 */
mxSvgCanvas2D.prototype.updateStrokeAttributes = function()
{
	var s = this.state;
	
	// Linejoin miter is default in SVG
	if (s.lineJoin != null && s.lineJoin != 'miter')
	{
		this.node.setAttribute('stroke-linejoin', s.lineJoin);
	}
	
	if (s.lineCap != null)
	{
		// flat is called butt in SVG
		var value = s.lineCap;
		
		if (value == 'flat')
		{
			value = 'butt';
		}
		
		// Linecap butt is default in SVG
		if (value != 'butt')
		{
			this.node.setAttribute('stroke-linecap', value);
		}
	}
	
	// Miterlimit 10 is default in our document
	if (s.miterLimit != null && (!this.styleEnabled || s.miterLimit != 10))
	{
		this.node.setAttribute('stroke-miterlimit', s.miterLimit);
	}
};

/**
 * Function: createDashPattern
 * 
 * Creates the SVG dash pattern for the given state.
 */
mxSvgCanvas2D.prototype.createDashPattern = function(scale)
{
	var pat = [];
	
	if (typeof(this.state.dashPattern) === 'string')
	{
		var dash = this.state.dashPattern.split(' ');
		
		if (dash.length > 0)
		{
			for (var i = 0; i < dash.length; i++)
			{
				pat[i] = Number(dash[i]) * scale;
			}
		}
	}
	
	return pat.join(' ');
};

/**
 * Function: createTolerance
 * 
 * Creates a hit detection tolerance shape for the given node.
 */
mxSvgCanvas2D.prototype.createTolerance = function(node)
{
	var tol = node.cloneNode(true);
	var sw = parseFloat(tol.getAttribute('stroke-width') || 1) + this.strokeTolerance;
	tol.setAttribute('pointer-events', 'stroke');
	tol.setAttribute('visibility', 'hidden');
	tol.removeAttribute('stroke-dasharray');
	tol.setAttribute('stroke-width', sw);
	tol.setAttribute('fill', 'none');
	
	// Workaround for Opera ignoring the visiblity attribute above while
	// other browsers need a stroke color to perform the hit-detection but
	// do not ignore the visibility attribute. Side-effect is that Opera's
	// hit detection for horizontal/vertical edges seems to ignore the tol.
	tol.setAttribute('stroke', (mxClient.IS_OT) ? 'none' : 'white');
	
	return tol;
};

/**
 * Function: createShadow
 * 
 * Creates a shadow for the given node.
 */
mxSvgCanvas2D.prototype.createShadow = function(node)
{
	var shadow = node.cloneNode(true);
	var s = this.state;

	// Firefox uses transparent for no fill in ellipses
	if (shadow.getAttribute('fill') != 'none' && (!mxClient.IS_FF || shadow.getAttribute('fill') != 'transparent'))
	{
		shadow.setAttribute('fill', s.shadowColor);
	}
	
	if (shadow.getAttribute('stroke') != 'none')
	{
		shadow.setAttribute('stroke', s.shadowColor);
	}

	shadow.setAttribute('transform', 'translate(' + this.format(s.shadowDx * s.scale) +
		',' + this.format(s.shadowDy * s.scale) + ')' + (s.transform || ''));
	shadow.setAttribute('opacity', s.shadowAlpha);
	
	return shadow;
};

/**
 * Function: setLink
 * 
 * Experimental implementation for hyperlinks.
 */
mxSvgCanvas2D.prototype.setLink = function(link)
{
	if (link == null)
	{
		this.root = this.originalRoot;
	}
	else
	{
		this.originalRoot = this.root;
		
		var node = this.createElement('a');
		
		// Workaround for implicit namespace handling in HTML5 export, IE adds NS1 namespace so use code below
		// in all IE versions except quirks mode. KNOWN: Adds xlink namespace to each image tag in output.
		if (node.setAttributeNS == null || (this.root.ownerDocument != document && document.documentMode == null))
		{
			node.setAttribute('xlink:href', link);
		}
		else
		{
			node.setAttributeNS(mxConstants.NS_XLINK, 'xlink:href', link);
		}
		
		this.root.appendChild(node);
		this.root = node;
	}
};

/**
 * Function: rotate
 * 
 * Sets the rotation of the canvas. Note that rotation cannot be concatenated.
 */
mxSvgCanvas2D.prototype.rotate = function(theta, flipH, flipV, cx, cy)
{
	if (theta != 0 || flipH || flipV)
	{
		var s = this.state;
		cx += s.dx;
		cy += s.dy;
	
		cx *= s.scale;
		cy *= s.scale;

		s.transform = s.transform || '';
		
		// This implementation uses custom scale/translate and built-in rotation
		// Rotation state is part of the AffineTransform in state.transform
		if (flipH && flipV)
		{
			theta += 180;
		}
		else if (flipH != flipV)
		{
			var tx = (flipH) ? cx : 0;
			var sx = (flipH) ? -1 : 1;
	
			var ty = (flipV) ? cy : 0;
			var sy = (flipV) ? -1 : 1;

			s.transform += 'translate(' + this.format(tx) + ',' + this.format(ty) + ')' +
				'scale(' + this.format(sx) + ',' + this.format(sy) + ')' +
				'translate(' + this.format(-tx) + ',' + this.format(-ty) + ')';
		}
		
		if (flipH ? !flipV : flipV)
		{
			theta *= -1;
		}
		
		if (theta != 0)
		{
			s.transform += 'rotate(' + this.format(theta) + ',' + this.format(cx) + ',' + this.format(cy) + ')';
		}
		
		s.rotation = s.rotation + theta;
		s.rotationCx = cx;
		s.rotationCy = cy;
	}
};

/**
 * Function: begin
 * 
 * Extends superclass to create path.
 */
mxSvgCanvas2D.prototype.begin = function()
{
	mxAbstractCanvas2D.prototype.begin.apply(this, arguments);
	this.node = this.createElement('path');
};

/**
 * Function: rect
 * 
 * Private helper function to create SVG elements
 */
mxSvgCanvas2D.prototype.rect = function(x, y, w, h)
{
	var s = this.state;
	var n = this.createElement('rect');
	n.setAttribute('x', this.format((x + s.dx) * s.scale));
	n.setAttribute('y', this.format((y + s.dy) * s.scale));
	n.setAttribute('width', this.format(w * s.scale));
	n.setAttribute('height', this.format(h * s.scale));
	
	this.node = n;
};

/**
 * Function: roundrect
 * 
 * Private helper function to create SVG elements
 */
mxSvgCanvas2D.prototype.roundrect = function(x, y, w, h, dx, dy)
{
	this.rect(x, y, w, h);
	
	if (dx > 0)
	{
		this.node.setAttribute('rx', this.format(dx * this.state.scale));
	}
	
	if (dy > 0)
	{
		this.node.setAttribute('ry', this.format(dy * this.state.scale));
	}
};

/**
 * Function: ellipse
 * 
 * Private helper function to create SVG elements
 */
mxSvgCanvas2D.prototype.ellipse = function(x, y, w, h)
{
	var s = this.state;
	var n = this.createElement('ellipse');
	// No rounding for consistent output with 1.x
	n.setAttribute('cx', Math.round((x + w / 2 + s.dx) * s.scale));
	n.setAttribute('cy', Math.round((y + h / 2 + s.dy) * s.scale));
	n.setAttribute('rx', w / 2 * s.scale);
	n.setAttribute('ry', h / 2 * s.scale);
	this.node = n;
};

/**
 * Function: image
 * 
 * Private helper function to create SVG elements
 */
mxSvgCanvas2D.prototype.image = function(x, y, w, h, src, aspect, flipH, flipV)
{
	src = this.converter.convert(src);
	
	// LATER: Add option for embedding images as base64.
	aspect = (aspect != null) ? aspect : true;
	flipH = (flipH != null) ? flipH : false;
	flipV = (flipV != null) ? flipV : false;
	
	var s = this.state;
	x += s.dx;
	y += s.dy;
	
	var node = this.createElement('image');
	node.setAttribute('x', this.format(x * s.scale) + this.imageOffset);
	node.setAttribute('y', this.format(y * s.scale) + this.imageOffset);
	node.setAttribute('width', this.format(w * s.scale));
	node.setAttribute('height', this.format(h * s.scale));
	
	// Workaround for missing namespace support
	if (node.setAttributeNS == null)
	{
		node.setAttribute('xlink:href', src);
	}
	else
	{
		node.setAttributeNS(mxConstants.NS_XLINK, 'xlink:href', src);
	}
	
	if (!aspect)
	{
		node.setAttribute('preserveAspectRatio', 'none');
	}

	if (s.alpha < 1 || s.fillAlpha < 1)
	{
		node.setAttribute('opacity', s.alpha * s.fillAlpha);
	}
	
	var tr = this.state.transform || '';
	
	if (flipH || flipV)
	{
		var sx = 1;
		var sy = 1;
		var dx = 0;
		var dy = 0;
		
		if (flipH)
		{
			sx = -1;
			dx = -w - 2 * x;
		}
		
		if (flipV)
		{
			sy = -1;
			dy = -h - 2 * y;
		}
		
		// Adds image tansformation to existing transform
		tr += 'scale(' + sx + ',' + sy + ')translate(' + (dx * s.scale) + ',' + (dy * s.scale) + ')';
	}

	if (tr.length > 0)
	{
		node.setAttribute('transform', tr);
	}
	
	if (!this.pointerEvents)
	{
		node.setAttribute('pointer-events', 'none');
	}
	
	this.root.appendChild(node);
	
	// Disables control-clicks on images in Firefox to open in new tab
	// by putting a rect in the foreground that absorbs all events and
	// disabling all pointer-events on the original image tag.
	if (this.blockImagePointerEvents)
	{
		node.setAttribute('style', 'pointer-events:none');
		
		node = this.createElement('rect');
		node.setAttribute('visibility', 'hidden');
		node.setAttribute('pointer-events', 'fill');
		node.setAttribute('x', this.format(x * s.scale));
		node.setAttribute('y', this.format(y * s.scale));
		node.setAttribute('width', this.format(w * s.scale));
		node.setAttribute('height', this.format(h * s.scale));
		this.root.appendChild(node);
	}
};

/**
 * Function: convertHtml
 * 
 * Converts the given HTML string to XHTML.
 */
mxSvgCanvas2D.prototype.convertHtml = function(val)
{
	if (this.useDomParser)
	{
		var doc = new DOMParser().parseFromString(val, 'text/html');

		if (doc != null)
		{
			val = new XMLSerializer().serializeToString(doc.body);
			
			// Extracts body content from DOM
			if (val.substring(0, 5) == '<body')
			{
				val = val.substring(val.indexOf('>', 5) + 1);
			}
			
			if (val.substring(val.length - 7, val.length) == '</body>')
			{
				val = val.substring(0, val.length - 7);
			}
		}
	}
	else if (document.implementation != null && document.implementation.createDocument != null)
	{
		var xd = document.implementation.createDocument('http://www.w3.org/1999/xhtml', 'html', null);
		var xb = xd.createElement('body');
		xd.documentElement.appendChild(xb);
		
		var div = document.createElement('div');
		div.innerHTML = val;
		var child = div.firstChild;
		
		while (child != null)
		{
			var next = child.nextSibling;
			xb.appendChild(xd.adoptNode(child));
			child = next;
		}
		
		return xb.innerHTML;
	}
	else
	{
		var ta = document.createElement('textarea');
		
		// Handles special HTML entities < and > and double escaping
		// and converts unclosed br, hr and img tags to XHTML
		// LATER: Convert all unclosed tags
		ta.innerHTML = val.replace(/&amp;/g, '&amp;amp;').
			replace(/&#60;/g, '&amp;lt;').replace(/&#62;/g, '&amp;gt;').
			replace(/&lt;/g, '&amp;lt;').replace(/&gt;/g, '&amp;gt;').
			replace(/</g, '&lt;').replace(/>/g, '&gt;');
		val = ta.value.replace(/&/g, '&amp;').replace(/&amp;lt;/g, '&lt;').
			replace(/&amp;gt;/g, '&gt;').replace(/&amp;amp;/g, '&amp;').
			replace(/<br>/g, '<br />').replace(/<hr>/g, '<hr />').
			replace(/(<img[^>]+)>/gm, "$1 />");
	}
	
	return val;
};

/**
 * Function: createDiv
 * 
 * Private helper function to create SVG elements
 */
mxSvgCanvas2D.prototype.createDiv = function(str, align, valign, style, overflow)
{
	var s = this.state;

	// Inline block for rendering HTML background over SVG in Safari
	var lh = (mxConstants.ABSOLUTE_LINE_HEIGHT) ? (s.fontSize * mxConstants.LINE_HEIGHT) + 'px' :
		(mxConstants.LINE_HEIGHT * this.lineHeightCorrection);
	
	style = 'display:inline-block;font-size:' + s.fontSize + 'px;font-family:' + s.fontFamily +
		';color:' + s.fontColor + ';line-height:' + lh + ';' + style;

	if ((s.fontStyle & mxConstants.FONT_BOLD) == mxConstants.FONT_BOLD)
	{
		style += 'font-weight:bold;';
	}

	if ((s.fontStyle & mxConstants.FONT_ITALIC) == mxConstants.FONT_ITALIC)
	{
		style += 'font-style:italic;';
	}
	
	if ((s.fontStyle & mxConstants.FONT_UNDERLINE) == mxConstants.FONT_UNDERLINE)
	{
		style += 'text-decoration:underline;';
	}
	
	if (align == mxConstants.ALIGN_CENTER)
	{
		style += 'text-align:center;';
	}
	else if (align == mxConstants.ALIGN_RIGHT)
	{
		style += 'text-align:right;';
	}

	var css = '';
	
	if (s.fontBackgroundColor != null)
	{
		css += 'background-color:' + s.fontBackgroundColor + ';';
	}
	
	if (s.fontBorderColor != null)
	{
		css += 'border:1px solid ' + s.fontBorderColor + ';';
	}
	
	var val = str;
	
	if (!mxUtils.isNode(val))
	{
		val = this.convertHtml(val);
		
		if (overflow != 'fill' && overflow != 'width')
		{
			// Inner div always needed to measure wrapped text
			val = '<div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;' + css + '">' + val + '</div>';
		}
		else
		{
			style += css;
		}
	}

	// Uses DOM API where available. This cannot be used in IE to avoid
	// an opening and two (!) closing TBODY tags being added to tables.
	if (!mxClient.IS_IE && document.createElementNS)
	{
		var div = document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
		div.setAttribute('style', style);
		
		if (mxUtils.isNode(val))
		{
			// Creates a copy for export
			if (this.root.ownerDocument != document)
			{
				div.appendChild(val.cloneNode(true));
			}
			else
			{
				div.appendChild(val);
			}
		}
		else
		{
			div.innerHTML = val;
		}
		
		return div;
	}
	else
	{
		// Serializes for export
		if (mxUtils.isNode(val) && this.root.ownerDocument != document)
		{
			val = val.outerHTML;
		}

		// NOTE: FF 3.6 crashes if content CSS contains "height:100%"
		return mxUtils.parseXml('<div xmlns="http://www.w3.org/1999/xhtml" style="' + style + 
			'">' + val + '</div>').documentElement;
	}
};

/**
 * Invalidates the cached offset size for the given node.
 */
mxSvgCanvas2D.prototype.invalidateCachedOffsetSize = function(node)
{
	delete node.firstChild.mxCachedOffsetWidth;
	delete node.firstChild.mxCachedFinalOffsetWidth;
	delete node.firstChild.mxCachedFinalOffsetHeight;
};

/**
 * Updates existing DOM nodes for text rendering. LATER: Merge common parts with text function below.
 */
mxSvgCanvas2D.prototype.updateText = function(x, y, w, h, align, valign, wrap, overflow, clip, rotation, node)
{
	if (node != null && node.firstChild != null && node.firstChild.firstChild != null &&
		node.firstChild.firstChild.firstChild != null)
	{
		// Uses outer group for opacity and transforms to
		// fix rendering order in Chrome
		var group = node.firstChild;
		var fo = group.firstChild;
		var div = fo.firstChild;

		rotation = (rotation != null) ? rotation : 0;
		
		var s = this.state;
		x += s.dx;
		y += s.dy;
		
		if (clip)
		{
			div.style.maxHeight = Math.round(h) + 'px';
			div.style.maxWidth = Math.round(w) + 'px';
		}
		else if (overflow == 'fill')
		{
			div.style.width = Math.round(w + 1) + 'px';
			div.style.height = Math.round(h + 1) + 'px';
		}
		else if (overflow == 'width')
		{
			div.style.width = Math.round(w + 1) + 'px';
			
			if (h > 0)
			{
				div.style.maxHeight = Math.round(h) + 'px';
			}
		}

		if (wrap && w > 0)
		{
			div.style.width = Math.round(w + 1) + 'px';
		}
		
		// Code that depends on the size which is computed after
		// the element was added to the DOM.
		var ow = 0;
		var oh = 0;
		
		// Padding avoids clipping on border and wrapping for differing font metrics on platforms
		var padX = 2;
		var padY = 2;

		var sizeDiv = div;
		
		if (sizeDiv.firstChild != null && sizeDiv.firstChild.nodeName == 'DIV')
		{
			sizeDiv = sizeDiv.firstChild;
		}
		
		var tmp = (group.mxCachedOffsetWidth != null) ? group.mxCachedOffsetWidth : sizeDiv.offsetWidth;
		ow = tmp + padX;

		// Recomputes the height of the element for wrapped width
		if (wrap && overflow != 'fill')
		{
			if (clip)
			{
				ow = Math.min(ow, w);
			}
			
			div.style.width = ow + 'px';
		}
		
		ow = ((group.mxCachedFinalOffsetWidth != null) ? group.mxCachedFinalOffsetWidth :
			sizeDiv.offsetWidth) + padX;
		oh = ((group.mxCachedFinalOffsetHeight != null) ? group.mxCachedFinalOffsetHeight :
			sizeDiv.offsetHeight) - 2;

		if (clip)
		{
			oh = Math.min(oh, h);
			ow = Math.min(ow, w);
		}

		if (overflow == 'width')
		{
			h = oh;
		}
		else if (overflow != 'fill')
		{
			w = ow;
			h = oh;
		}

		var dx = 0;
		var dy = 0;

		if (align == mxConstants.ALIGN_CENTER)
		{
			dx -= w / 2;
		}
		else if (align == mxConstants.ALIGN_RIGHT)
		{
			dx -= w;
		}
		
		x += dx;
		
		// FIXME: LINE_HEIGHT not ideal for all text sizes, fix for export
		if (valign == mxConstants.ALIGN_MIDDLE)
		{
			dy -= h / 2;
		}
		else if (valign == mxConstants.ALIGN_BOTTOM)
		{
			dy -= h;
		}
		
		// Workaround for rendering offsets
		// TODO: Check if export needs these fixes, too
		if (overflow != 'fill' && mxClient.IS_FF && mxClient.IS_WIN)
		{
			dy -= 2;
		}
		
		y += dy;

		var tr = (s.scale != 1) ? 'scale(' + s.scale + ')' : '';

		if (s.rotation != 0 && this.rotateHtml)
		{
			tr += 'rotate(' + (s.rotation) + ',' + (w / 2) + ',' + (h / 2) + ')';
			var pt = this.rotatePoint((x + w / 2) * s.scale, (y + h / 2) * s.scale,
				s.rotation, s.rotationCx, s.rotationCy);
			x = pt.x - w * s.scale / 2;
			y = pt.y - h * s.scale / 2;
		}
		else
		{
			x *= s.scale;
			y *= s.scale;
		}

		if (rotation != 0)
		{
			tr += 'rotate(' + (rotation) + ',' + (-dx) + ',' + (-dy) + ')';
		}

		group.setAttribute('transform', 'translate(' + Math.round(x) + ',' + Math.round(y) + ')' + tr);
		fo.setAttribute('width', Math.round(Math.max(1, w)));
		fo.setAttribute('height', Math.round(Math.max(1, h)));
	}
};

/**
 * Function: text
 * 
 * Paints the given text. Possible values for format are empty string for plain
 * text and html for HTML markup. Note that HTML markup is only supported if
 * foreignObject is supported and <foEnabled> is true. (This means IE9 and later
 * does currently not support HTML text as part of shapes.)
 */
mxSvgCanvas2D.prototype.text = function(x, y, w, h, str, align, valign, wrap, format, overflow, clip, rotation, dir)
{
	if (this.textEnabled && str != null)
	{
		rotation = (rotation != null) ? rotation : 0;
		
		var s = this.state;
		x += s.dx;
		y += s.dy;
		
		if (this.foEnabled && format == 'html')
		{
			var style = 'vertical-align:top;';
			
			if (clip)
			{
				style += 'overflow:hidden;max-height:' + Math.round(h) + 'px;max-width:' + Math.round(w) + 'px;';
			}
			else if (overflow == 'fill')
			{
				style += 'width:' + Math.round(w + 1) + 'px;height:' + Math.round(h + 1) + 'px;overflow:hidden;';
			}
			else if (overflow == 'width')
			{
				style += 'width:' + Math.round(w + 1) + 'px;';
				
				if (h > 0)
				{
					style += 'max-height:' + Math.round(h) + 'px;overflow:hidden;';
				}
			}

			if (wrap && w > 0)
			{
				style += 'width:' + Math.round(w + 1) + 'px;white-space:normal;word-wrap:' +
					mxConstants.WORD_WRAP + ';';
			}
			else
			{
				style += 'white-space:nowrap;';
			}
			
			// Uses outer group for opacity and transforms to
			// fix rendering order in Chrome
			var group = this.createElement('g');
			
			if (s.alpha < 1)
			{
				group.setAttribute('opacity', s.alpha);
			}

			var fo = this.createElement('foreignObject');
			fo.setAttribute('style', 'overflow:visible;');
			fo.setAttribute('pointer-events', 'all');
			
			var div = this.createDiv(str, align, valign, style, overflow);
			
			// Ignores invalid XHTML labels
			if (div == null)
			{
				return;
			}
			else if (dir != null)
			{
				div.setAttribute('dir', dir);
			}

			group.appendChild(fo);
			this.root.appendChild(group);
			
			// Code that depends on the size which is computed after
			// the element was added to the DOM.
			var ow = 0;
			var oh = 0;
			
			// Padding avoids clipping on border and wrapping for differing font metrics on platforms
			var padX = 2;
			var padY = 2;

			// NOTE: IE is always export as it does not support foreign objects
			if (mxClient.IS_IE && (document.documentMode == 9 || !mxClient.IS_SVG))
			{
				// Handles non-standard namespace for getting size in IE
				var clone = document.createElement('div');
				
				clone.style.cssText = div.getAttribute('style');
				clone.style.display = (mxClient.IS_QUIRKS) ? 'inline' : 'inline-block';
				clone.style.position = 'absolute';
				clone.style.visibility = 'hidden';

				// Inner DIV is needed for text measuring
				var div2 = document.createElement('div');
				div2.style.display = (mxClient.IS_QUIRKS) ? 'inline' : 'inline-block';
				div2.style.wordWrap = mxConstants.WORD_WRAP;
				div2.innerHTML = (mxUtils.isNode(str)) ? str.outerHTML : str;
				clone.appendChild(div2);

				document.body.appendChild(clone);

				// Workaround for different box models
				if (document.documentMode != 8 && document.documentMode != 9 && s.fontBorderColor != null)
				{
					padX += 2;
					padY += 2;
				}

				if (wrap && w > 0)
				{
					var tmp = div2.offsetWidth;
					
					// Workaround for adding padding twice in IE8/IE9 standards mode if label is wrapped
					var padDx = 0;
					
					// For export, if no wrapping occurs, we add a large padding to make
					// sure there is no wrapping even if the text metrics are different.
					// This adds support for text metrics on different operating systems.
					// Disables wrapping if text is not wrapped for given width
					if (!clip && wrap && w > 0 && this.root.ownerDocument != document && overflow != 'fill')
					{
						var ws = clone.style.whiteSpace;
						div2.style.whiteSpace = 'nowrap';
						
						if (tmp < div2.offsetWidth)
						{
							clone.style.whiteSpace = ws;
						}
					}
					
					if (clip)
					{
						tmp = Math.min(tmp, w);
					}
					
					clone.style.width = tmp + 'px';
	
					// Padding avoids clipping on border
					ow = div2.offsetWidth + padX + padDx;
					oh = div2.offsetHeight + padY;
					
					// Overrides the width of the DIV via XML DOM by using the
					// clone DOM style, getting the CSS text for that and
					// then setting that on the DIV via setAttribute
					clone.style.display = 'inline-block';
					clone.style.position = '';
					clone.style.visibility = '';
					clone.style.width = ow + 'px';
					
					div.setAttribute('style', clone.style.cssText);
				}
				else
				{
					// Padding avoids clipping on border
					ow = div2.offsetWidth + padX;
					oh = div2.offsetHeight + padY;
				}

				clone.parentNode.removeChild(clone);
				fo.appendChild(div);
			}
			else
			{
				// Uses document for text measuring during export
				if (this.root.ownerDocument != document)
				{
					div.style.visibility = 'hidden';
					document.body.appendChild(div);
				}
				else
				{
					fo.appendChild(div);
				}

				var sizeDiv = div;
				
				if (sizeDiv.firstChild != null && sizeDiv.firstChild.nodeName == 'DIV')
				{
					sizeDiv = sizeDiv.firstChild;
					
					if (wrap && div.style.wordWrap == 'break-word')
					{
						sizeDiv.style.width = '100%';
					}
				}
				
				var tmp = sizeDiv.offsetWidth;
				
				// Workaround for text measuring in hidden containers
				if (tmp == 0 && div.parentNode == fo)
				{
					div.style.visibility = 'hidden';
					document.body.appendChild(div);
					
					tmp = sizeDiv.offsetWidth;
				}
				
				if (this.cacheOffsetSize)
				{
					group.mxCachedOffsetWidth = tmp;
				}
				
				// Disables wrapping if text is not wrapped for given width
				if (!clip && wrap && w > 0 && this.root.ownerDocument != document &&
					overflow != 'fill' && overflow != 'width')
				{
					var ws = div.style.whiteSpace;
					div.style.whiteSpace = 'nowrap';
					
					if (tmp < sizeDiv.offsetWidth)
					{
						div.style.whiteSpace = ws;
					}
				}

				ow = tmp + padX - 1;

				// Recomputes the height of the element for wrapped width
				if (wrap && overflow != 'fill' && overflow != 'width')
				{
					if (clip)
					{
						ow = Math.min(ow, w);
					}
					
					div.style.width = ow + 'px';
				}

				ow = sizeDiv.offsetWidth;
				oh = sizeDiv.offsetHeight;
				
				if (this.cacheOffsetSize)
				{
					group.mxCachedFinalOffsetWidth = ow;
					group.mxCachedFinalOffsetHeight = oh;
				}

				oh -= padY;
				
				if (div.parentNode != fo)
				{
					fo.appendChild(div);
					div.style.visibility = '';
				}
			}

			if (clip)
			{
				oh = Math.min(oh, h);
				ow = Math.min(ow, w);
			}

			if (overflow == 'width')
			{
				h = oh;
			}
			else if (overflow != 'fill')
			{
				w = ow;
				h = oh;
			}

			if (s.alpha < 1)
			{
				group.setAttribute('opacity', s.alpha);
			}
			
			var dx = 0;
			var dy = 0;

			if (align == mxConstants.ALIGN_CENTER)
			{
				dx -= w / 2;
			}
			else if (align == mxConstants.ALIGN_RIGHT)
			{
				dx -= w;
			}
			
			x += dx;
			
			// FIXME: LINE_HEIGHT not ideal for all text sizes, fix for export
			if (valign == mxConstants.ALIGN_MIDDLE)
			{
				dy -= h / 2;
			}
			else if (valign == mxConstants.ALIGN_BOTTOM)
			{
				dy -= h;
			}
			
			// Workaround for rendering offsets
			// TODO: Check if export needs these fixes, too
			//if (this.root.ownerDocument == document)
			if (overflow != 'fill' && mxClient.IS_FF && mxClient.IS_WIN)
			{
				dy -= 2;
			}
			
			y += dy;

			var tr = (s.scale != 1) ? 'scale(' + s.scale + ')' : '';

			if (s.rotation != 0 && this.rotateHtml)
			{
				tr += 'rotate(' + (s.rotation) + ',' + (w / 2) + ',' + (h / 2) + ')';
				var pt = this.rotatePoint((x + w / 2) * s.scale, (y + h / 2) * s.scale,
					s.rotation, s.rotationCx, s.rotationCy);
				x = pt.x - w * s.scale / 2;
				y = pt.y - h * s.scale / 2;
			}
			else
			{
				x *= s.scale;
				y *= s.scale;
			}

			if (rotation != 0)
			{
				tr += 'rotate(' + (rotation) + ',' + (-dx) + ',' + (-dy) + ')';
			}

			group.setAttribute('transform', 'translate(' + (Math.round(x) + this.foOffset) + ',' +
				(Math.round(y) + this.foOffset) + ')' + tr);
			fo.setAttribute('width', Math.round(Math.max(1, w)));
			fo.setAttribute('height', Math.round(Math.max(1, h)));
			
			// Adds alternate content if foreignObject not supported in viewer
			if (this.root.ownerDocument != document)
			{
				var alt = this.createAlternateContent(fo, x, y, w, h, str, align, valign, wrap, format, overflow, clip, rotation);
				
				if (alt != null)
				{
					fo.setAttribute('requiredFeatures', 'http://www.w3.org/TR/SVG11/feature#Extensibility');
					var sw = this.createElement('switch');
					sw.appendChild(fo);
					sw.appendChild(alt);
					group.appendChild(sw);
				}
			}
		}
		else
		{
			this.plainText(x, y, w, h, str, align, valign, wrap, overflow, clip, rotation, dir);
		}
	}
};

/**
 * Function: createClip
 * 
 * Creates a clip for the given coordinates.
 */
mxSvgCanvas2D.prototype.createClip = function(x, y, w, h)
{
	x = Math.round(x);
	y = Math.round(y);
	w = Math.round(w);
	h = Math.round(h);
	
	var id = 'mx-clip-' + x + '-' + y + '-' + w + '-' + h;

	var counter = 0;
	var tmp = id + '-' + counter;
	
	// Resolves ID conflicts
	while (document.getElementById(tmp) != null)
	{
		tmp = id + '-' + (++counter);
	}
	
	clip = this.createElement('clipPath');
	clip.setAttribute('id', tmp);
	
	var rect = this.createElement('rect');
	rect.setAttribute('x', x);
	rect.setAttribute('y', y);
	rect.setAttribute('width', w);
	rect.setAttribute('height', h);
		
	clip.appendChild(rect);
	
	return clip;
};

/**
 * Function: text
 * 
 * Paints the given text. Possible values for format are empty string for
 * plain text and html for HTML markup.
 */
mxSvgCanvas2D.prototype.plainText = function(x, y, w, h, str, align, valign, wrap, overflow, clip, rotation, dir)
{
	rotation = (rotation != null) ? rotation : 0;
	var s = this.state;
	var size = s.fontSize;
	var node = this.createElement('g');
	var tr = s.transform || '';
	this.updateFont(node);
	
	// Non-rotated text
	if (rotation != 0)
	{
		tr += 'rotate(' + rotation  + ',' + this.format(x * s.scale) + ',' + this.format(y * s.scale) + ')';
	}
	
	if (dir != null)
	{
		node.setAttribute('direction', dir);
	}

	if (clip && w > 0 && h > 0)
	{
		var cx = x;
		var cy = y;
		
		if (align == mxConstants.ALIGN_CENTER)
		{
			cx -= w / 2;
		}
		else if (align == mxConstants.ALIGN_RIGHT)
		{
			cx -= w;
		}
		
		if (overflow != 'fill')
		{
			if (valign == mxConstants.ALIGN_MIDDLE)
			{
				cy -= h / 2;
			}
			else if (valign == mxConstants.ALIGN_BOTTOM)
			{
				cy -= h;
			}
		}
		
		// LATER: Remove spacing from clip rectangle
		var c = this.createClip(cx * s.scale - 2, cy * s.scale - 2, w * s.scale + 4, h * s.scale + 4);
		
		if (this.defs != null)
		{
			this.defs.appendChild(c);
		}
		else
		{
			// Makes sure clip is removed with referencing node
			this.root.appendChild(c);
		}
		
		if (!mxClient.IS_CHROME_APP && !mxClient.IS_IE && !mxClient.IS_IE11 &&
			!mxClient.IS_EDGE && this.root.ownerDocument == document)
		{
			// Workaround for potential base tag
			var base = this.getBaseUrl().replace(/([\(\)])/g, '\\$1');
			node.setAttribute('clip-path', 'url(' + base + '#' + c.getAttribute('id') + ')');
		}
		else
		{
			node.setAttribute('clip-path', 'url(#' + c.getAttribute('id') + ')');
		}
	}

	// Default is left
	var anchor = (align == mxConstants.ALIGN_RIGHT) ? 'end' :
					(align == mxConstants.ALIGN_CENTER) ? 'middle' :
					'start';

	// Text-anchor start is default in SVG
	if (anchor != 'start')
	{
		node.setAttribute('text-anchor', anchor);
	}
	
	if (!this.styleEnabled || size != mxConstants.DEFAULT_FONTSIZE)
	{
		node.setAttribute('font-size', (size * s.scale) + 'px');
	}
	
	if (tr.length > 0)
	{
		node.setAttribute('transform', tr);
	}
	
	if (s.alpha < 1)
	{
		node.setAttribute('opacity', s.alpha);
	}
	
	var lines = str.split('\n');
	var lh = Math.round(size * mxConstants.LINE_HEIGHT);
	var textHeight = size + (lines.length - 1) * lh;

	var cy = y + size - 1;

	if (valign == mxConstants.ALIGN_MIDDLE)
	{
		if (overflow == 'fill')
		{
			cy -= h / 2;
		}
		else
		{
			var dy = ((this.matchHtmlAlignment && clip && h > 0) ? Math.min(textHeight, h) : textHeight) / 2;
			cy -= dy + 1;
		}
	}
	else if (valign == mxConstants.ALIGN_BOTTOM)
	{
		if (overflow == 'fill')
		{
			cy -= h;
		}
		else
		{
			var dy = (this.matchHtmlAlignment && clip && h > 0) ? Math.min(textHeight, h) : textHeight;
			cy -= dy + 2;
		}
	}

	for (var i = 0; i < lines.length; i++)
	{
		// Workaround for bounding box of empty lines and spaces
		if (lines[i].length > 0 && mxUtils.trim(lines[i]).length > 0)
		{
			var text = this.createElement('text');
			// LATER: Match horizontal HTML alignment
			text.setAttribute('x', this.format(x * s.scale) + this.textOffset);
			text.setAttribute('y', this.format(cy * s.scale) + this.textOffset);
			
			mxUtils.write(text, lines[i]);
			node.appendChild(text);
		}

		cy += lh;
	}

	this.root.appendChild(node);
	this.addTextBackground(node, str, x, y, w, (overflow == 'fill') ? h : textHeight, align, valign, overflow);
};

/**
 * Function: updateFont
 * 
 * Updates the text properties for the given node. (NOTE: For this to work in
 * IE, the given node must be a text or tspan element.)
 */
mxSvgCanvas2D.prototype.updateFont = function(node)
{
	var s = this.state;

	node.setAttribute('fill', s.fontColor);
	
	if (!this.styleEnabled || s.fontFamily != mxConstants.DEFAULT_FONTFAMILY)
	{
		node.setAttribute('font-family', s.fontFamily);
	}

	if ((s.fontStyle & mxConstants.FONT_BOLD) == mxConstants.FONT_BOLD)
	{
		node.setAttribute('font-weight', 'bold');
	}

	if ((s.fontStyle & mxConstants.FONT_ITALIC) == mxConstants.FONT_ITALIC)
	{
		node.setAttribute('font-style', 'italic');
	}
	
	if ((s.fontStyle & mxConstants.FONT_UNDERLINE) == mxConstants.FONT_UNDERLINE)
	{
		node.setAttribute('text-decoration', 'underline');
	}
};

/**
 * Function: addTextBackground
 * 
 * Background color and border
 */
mxSvgCanvas2D.prototype.addTextBackground = function(node, str, x, y, w, h, align, valign, overflow)
{
	var s = this.state;

	if (s.fontBackgroundColor != null || s.fontBorderColor != null)
	{
		var bbox = null;
		
		if (overflow == 'fill' || overflow == 'width')
		{
			if (align == mxConstants.ALIGN_CENTER)
			{
				x -= w / 2;
			}
			else if (align == mxConstants.ALIGN_RIGHT)
			{
				x -= w;
			}
			
			if (valign == mxConstants.ALIGN_MIDDLE)
			{
				y -= h / 2;
			}
			else if (valign == mxConstants.ALIGN_BOTTOM)
			{
				y -= h;
			}
			
			bbox = new mxRectangle((x + 1) * s.scale, y * s.scale, (w - 2) * s.scale, (h + 2) * s.scale);
		}
		else if (node.getBBox != null && this.root.ownerDocument == document)
		{
			// Uses getBBox only if inside document for correct size
			try
			{
				bbox = node.getBBox();
				var ie = mxClient.IS_IE && mxClient.IS_SVG;
				bbox = new mxRectangle(bbox.x, bbox.y + ((ie) ? 0 : 1), bbox.width, bbox.height + ((ie) ? 1 : 0));
			}
			catch (e)
			{
				// Ignores NS_ERROR_FAILURE in FF if container display is none.
			}
		}
		else
		{
			// Computes size if not in document or no getBBox available
			var div = document.createElement('div');

			// Wrapping and clipping can be ignored here
			div.style.lineHeight = (mxConstants.ABSOLUTE_LINE_HEIGHT) ? (s.fontSize * mxConstants.LINE_HEIGHT) + 'px' : mxConstants.LINE_HEIGHT;
			div.style.fontSize = s.fontSize + 'px';
			div.style.fontFamily = s.fontFamily;
			div.style.whiteSpace = 'nowrap';
			div.style.position = 'absolute';
			div.style.visibility = 'hidden';
			div.style.display = (mxClient.IS_QUIRKS) ? 'inline' : 'inline-block';
			div.style.zoom = '1';
			
			if ((s.fontStyle & mxConstants.FONT_BOLD) == mxConstants.FONT_BOLD)
			{
				div.style.fontWeight = 'bold';
			}

			if ((s.fontStyle & mxConstants.FONT_ITALIC) == mxConstants.FONT_ITALIC)
			{
				div.style.fontStyle = 'italic';
			}
			
			str = mxUtils.htmlEntities(str, false);
			div.innerHTML = str.replace(/\n/g, '<br/>');
			
			document.body.appendChild(div);
			var w = div.offsetWidth;
			var h = div.offsetHeight;
			div.parentNode.removeChild(div);
			
			if (align == mxConstants.ALIGN_CENTER)
			{
				x -= w / 2;
			}
			else if (align == mxConstants.ALIGN_RIGHT)
			{
				x -= w;
			}
			
			if (valign == mxConstants.ALIGN_MIDDLE)
			{
				y -= h / 2;
			}
			else if (valign == mxConstants.ALIGN_BOTTOM)
			{
				y -= h;
			}
			
			bbox = new mxRectangle((x + 1) * s.scale, (y + 2) * s.scale, w * s.scale, (h + 1) * s.scale);
		}
		
		if (bbox != null)
		{
			var n = this.createElement('rect');
			n.setAttribute('fill', s.fontBackgroundColor || 'none');
			n.setAttribute('stroke', s.fontBorderColor || 'none');
			n.setAttribute('x', Math.floor(bbox.x - 1));
			n.setAttribute('y', Math.floor(bbox.y - 1));
			n.setAttribute('width', Math.ceil(bbox.width + 2));
			n.setAttribute('height', Math.ceil(bbox.height));

			var sw = (s.fontBorderColor != null) ? Math.max(1, this.format(s.scale)) : 0;
			n.setAttribute('stroke-width', sw);
			
			// Workaround for crisp rendering - only required if not exporting
			if (this.root.ownerDocument == document && mxUtils.mod(sw, 2) == 1)
			{
				n.setAttribute('transform', 'translate(0.5, 0.5)');
			}
			
			node.insertBefore(n, node.firstChild);
		}
	}
};

/**
 * Function: stroke
 * 
 * Paints the outline of the current path.
 */
mxSvgCanvas2D.prototype.stroke = function()
{
	this.addNode(false, true);
};

/**
 * Function: fill
 * 
 * Fills the current path.
 */
mxSvgCanvas2D.prototype.fill = function()
{
	this.addNode(true, false);
};

/**
 * Function: fillAndStroke
 * 
 * Fills and paints the outline of the current path.
 */
mxSvgCanvas2D.prototype.fillAndStroke = function()
{
	this.addNode(true, true);
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 *
 * Class: mxVmlCanvas2D
 * 
 * Implements a canvas to be used for rendering VML. Here is an example of implementing a
 * fallback for SVG images which are not supported in VML-based browsers.
 * 
 * (code)
 * var mxVmlCanvas2DImage = mxVmlCanvas2D.prototype.image;
 * mxVmlCanvas2D.prototype.image = function(x, y, w, h, src, aspect, flipH, flipV)
 * {
 *   if (src.substring(src.length - 4, src.length) == '.svg')
 *   {
 *     src = 'http://www.jgraph.com/images/mxgraph.gif';
 *   }
 *   
 *   mxVmlCanvas2DImage.apply(this, arguments);
 * };
 * (end)
 * 
 * To disable anti-aliasing in the output, use the following code.
 * 
 * (code)
 * document.createStyleSheet().cssText = mxClient.VML_PREFIX + '\\:*{antialias:false;)}';
 * (end)
 * 
 * A description of the public API is available in <mxXmlCanvas2D>. Note that
 * there is a known issue in VML where gradients are painted using the outer
 * bounding box of rotated shapes, not the actual bounds of the shape. See
 * also <text> for plain text label restrictions in shapes for VML.
 */
var mxVmlCanvas2D = function(root)
{
	mxAbstractCanvas2D.call(this);

	/**
	 * Variable: root
	 * 
	 * Reference to the container for the SVG content.
	 */
	this.root = root;
};

/**
 * Extends mxAbstractCanvas2D
 */
mxUtils.extend(mxVmlCanvas2D, mxAbstractCanvas2D);

/**
 * Variable: path
 * 
 * Holds the current DOM node.
 */
mxVmlCanvas2D.prototype.node = null;

/**
 * Variable: textEnabled
 * 
 * Specifies if text output should be enabledetB. Default is true.
 */
mxVmlCanvas2D.prototype.textEnabled = true;

/**
 * Variable: moveOp
 * 
 * Contains the string used for moving in paths. Default is 'm'.
 */
mxVmlCanvas2D.prototype.moveOp = 'm';

/**
 * Variable: lineOp
 * 
 * Contains the string used for moving in paths. Default is 'l'.
 */
mxVmlCanvas2D.prototype.lineOp = 'l';

/**
 * Variable: curveOp
 * 
 * Contains the string used for bezier curves. Default is 'c'.
 */
mxVmlCanvas2D.prototype.curveOp = 'c';

/**
 * Variable: closeOp
 * 
 * Holds the operator for closing curves. Default is 'x e'.
 */
mxVmlCanvas2D.prototype.closeOp = 'x';

/**
 * Variable: rotatedHtmlBackground
 * 
 * Background color for rotated HTML. Default is ''. This can be set to eg.
 * white to improve rendering of rotated text in VML for IE9.
 */
mxVmlCanvas2D.prototype.rotatedHtmlBackground = '';

/**
 * Variable: vmlScale
 * 
 * Specifies the scale used to draw VML shapes.
 */
mxVmlCanvas2D.prototype.vmlScale = 1;

/**
 * Function: createElement
 * 
 * Creates the given element using the document.
 */
mxVmlCanvas2D.prototype.createElement = function(name)
{
	return document.createElement(name);
};

/**
 * Function: createVmlElement
 * 
 * Creates a new element using <createElement> and prefixes the given name with
 * <mxClient.VML_PREFIX>.
 */
mxVmlCanvas2D.prototype.createVmlElement = function(name)
{
	return this.createElement(mxClient.VML_PREFIX + ':' + name);
};

/**
 * Function: addNode
 * 
 * Adds the current node to the <root>.
 */
mxVmlCanvas2D.prototype.addNode = function(filled, stroked)
{
	var node = this.node;
	var s = this.state;
	
	if (node != null)
	{
		if (node.nodeName == 'shape')
		{
			// Checks if the path is not empty
			if (this.path != null && this.path.length > 0)
			{
				node.path = this.path.join(' ') + ' e';
				node.style.width = this.root.style.width;
				node.style.height = this.root.style.height;
				node.coordsize = parseInt(node.style.width) + ' ' + parseInt(node.style.height);
			}
			else
			{
				return;
			}
		}

		node.strokeweight = this.format(Math.max(1, s.strokeWidth * s.scale / this.vmlScale)) + 'px';
		
		if (s.shadow)
		{
			this.root.appendChild(this.createShadow(node,
				filled && s.fillColor != null,
				stroked && s.strokeColor != null));
		}
		
		if (stroked && s.strokeColor != null)
		{
			node.stroked = 'true';
			node.strokecolor = s.strokeColor;
		}
		else
		{
			node.stroked = 'false';
		}

		node.appendChild(this.createStroke());

		if (filled && s.fillColor != null)
		{
			node.appendChild(this.createFill());
		}
		else if (this.pointerEvents && (node.nodeName != 'shape' ||
			this.path[this.path.length - 1] == this.closeOp))
		{
			node.appendChild(this.createTransparentFill());
		}
		else
		{
			node.filled = 'false';
		}

		// LATER: Update existing DOM for performance
		this.root.appendChild(node);
	}
};

/**
 * Function: createTransparentFill
 * 
 * Creates a transparent fill.
 */
mxVmlCanvas2D.prototype.createTransparentFill = function()
{
	var fill = this.createVmlElement('fill');
	fill.src = mxClient.imageBasePath + '/transparent.gif';
	fill.type = 'tile';
	
	return fill;
};

/**
 * Function: createFill
 * 
 * Creates a fill for the current state.
 */
mxVmlCanvas2D.prototype.createFill = function()
{
	var s = this.state;
	
	// Gradients in foregrounds not supported because special gradients
	// with bounds must be created for each element in graphics-canvases
	var fill = this.createVmlElement('fill');
	fill.color = s.fillColor;

	if (s.gradientColor != null)
	{
		fill.type = 'gradient';
		fill.method = 'none';
		fill.color2 = s.gradientColor;
		var angle = 180 - s.rotation;
		
		if (s.gradientDirection == mxConstants.DIRECTION_WEST)
		{
			angle -= 90 + ((this.root.style.flip == 'x') ? 180 : 0);
		}
		else if (s.gradientDirection == mxConstants.DIRECTION_EAST)
		{
			angle += 90 + ((this.root.style.flip == 'x') ? 180 : 0);
		}
		else if (s.gradientDirection == mxConstants.DIRECTION_NORTH)
		{
			angle -= 180 + ((this.root.style.flip == 'y') ? -180 : 0);
		}
		else
		{
			 angle += ((this.root.style.flip == 'y') ? -180 : 0);
		}
		
		if (this.root.style.flip == 'x' || this.root.style.flip == 'y')
		{
			angle *= -1;
		}

		// LATER: Fix outer bounding box for rotated shapes used in VML.
		fill.angle = mxUtils.mod(angle, 360);
		fill.opacity = (s.alpha * s.gradientFillAlpha * 100) + '%';
		fill.setAttribute(mxClient.OFFICE_PREFIX + ':opacity2', (s.alpha * s.gradientAlpha * 100) + '%');
	}
	else if (s.alpha < 1 || s.fillAlpha < 1)
	{
		fill.opacity = (s.alpha * s.fillAlpha * 100) + '%';			
	}
	
	return fill;
};
/**
 * Function: createStroke
 * 
 * Creates a fill for the current state.
 */
mxVmlCanvas2D.prototype.createStroke = function()
{
	var s = this.state;
	var stroke = this.createVmlElement('stroke');
	stroke.endcap = s.lineCap || 'flat';
	stroke.joinstyle = s.lineJoin || 'miter';
	stroke.miterlimit = s.miterLimit || '10';
	
	if (s.alpha < 1 || s.strokeAlpha < 1)
	{
		stroke.opacity = (s.alpha * s.strokeAlpha * 100) + '%';
	}
	
	if (s.dashed)
	{
		stroke.dashstyle = this.getVmlDashStyle();
	}
	
	return stroke;
};

/**
 * Function: getVmlDashPattern
 * 
 * Returns a VML dash pattern for the current dashPattern.
 * See http://msdn.microsoft.com/en-us/library/bb264085(v=vs.85).aspx
 */
mxVmlCanvas2D.prototype.getVmlDashStyle = function()
{
	var result = 'dash';
	
	if (typeof(this.state.dashPattern) === 'string')
	{
		var tok = this.state.dashPattern.split(' ');
		
		if (tok.length > 0 && tok[0] == 1)
		{
			result = '0 2';
		}
	}
	
	return result;
};

/**
 * Function: createShadow
 * 
 * Creates a shadow for the given node.
 */
mxVmlCanvas2D.prototype.createShadow = function(node, filled, stroked)
{
	var s = this.state;
	var rad = -s.rotation * (Math.PI / 180);
	var cos = Math.cos(rad);
	var sin = Math.sin(rad);

	var dx = s.shadowDx * s.scale;
	var dy = s.shadowDy * s.scale;

	if (this.root.style.flip == 'x')
	{
		dx *= -1;
	}
	else if (this.root.style.flip == 'y')
	{
		dy *= -1;
	}
	
	var shadow = node.cloneNode(true);
	shadow.style.marginLeft = Math.round(dx * cos - dy * sin) + 'px';
	shadow.style.marginTop = Math.round(dx * sin + dy * cos) + 'px';

	// Workaround for wrong cloning in IE8 standards mode
	if (document.documentMode == 8)
	{
		shadow.strokeweight = node.strokeweight;
		
		if (node.nodeName == 'shape')
		{
			shadow.path = this.path.join(' ') + ' e';
			shadow.style.width = this.root.style.width;
			shadow.style.height = this.root.style.height;
			shadow.coordsize = parseInt(node.style.width) + ' ' + parseInt(node.style.height);
		}
	}
	
	if (stroked)
	{
		shadow.strokecolor = s.shadowColor;
		shadow.appendChild(this.createShadowStroke());
	}
	else
	{
		shadow.stroked = 'false';
	}
	
	if (filled)
	{
		shadow.appendChild(this.createShadowFill());
	}
	else
	{
		shadow.filled = 'false';
	}
	
	return shadow;
};

/**
 * Function: createShadowFill
 * 
 * Creates the fill for the shadow.
 */
mxVmlCanvas2D.prototype.createShadowFill = function()
{
	var fill = this.createVmlElement('fill');
	fill.color = this.state.shadowColor;
	fill.opacity = (this.state.alpha * this.state.shadowAlpha * 100) + '%';
	
	return fill;
};

/**
 * Function: createShadowStroke
 * 
 * Creates the stroke for the shadow.
 */
mxVmlCanvas2D.prototype.createShadowStroke = function()
{
	var stroke = this.createStroke();
	stroke.opacity = (this.state.alpha * this.state.shadowAlpha * 100) + '%';
	
	return stroke;
};

/**
 * Function: rotate
 * 
 * Sets the rotation of the canvas. Note that rotation cannot be concatenated.
 */
mxVmlCanvas2D.prototype.rotate = function(theta, flipH, flipV, cx, cy)
{
	if (flipH && flipV)
	{
		theta += 180;
	}
	else if (flipH)
	{
		this.root.style.flip = 'x';
	}
	else if (flipV)
	{
		this.root.style.flip = 'y';
	}

	if (flipH ? !flipV : flipV)
	{
		theta *= -1;
	}

	this.root.style.rotation = theta;
	this.state.rotation = this.state.rotation + theta;
	this.state.rotationCx = cx;
	this.state.rotationCy = cy;
};

/**
 * Function: begin
 * 
 * Extends superclass to create path.
 */
mxVmlCanvas2D.prototype.begin = function()
{
	mxAbstractCanvas2D.prototype.begin.apply(this, arguments);
	this.node = this.createVmlElement('shape');
	this.node.style.position = 'absolute';
};

/**
 * Function: quadTo
 * 
 * Replaces quadratic curve with bezier curve in VML.
 */
mxVmlCanvas2D.prototype.quadTo = function(x1, y1, x2, y2)
{
	var s = this.state;

	var cpx0 = (this.lastX + s.dx) * s.scale;
	var cpy0 = (this.lastY + s.dy) * s.scale;
	var qpx1 = (x1 + s.dx) * s.scale;
	var qpy1 = (y1 + s.dy) * s.scale;
	var cpx3 = (x2 + s.dx) * s.scale;
	var cpy3 = (y2 + s.dy) * s.scale;
	
	var cpx1 = cpx0 + 2/3 * (qpx1 - cpx0);
	var cpy1 = cpy0 + 2/3 * (qpy1 - cpy0);
	
	var cpx2 = cpx3 + 2/3 * (qpx1 - cpx3);
	var cpy2 = cpy3 + 2/3 * (qpy1 - cpy3);
	
	this.path.push('c ' + this.format(cpx1) + ' ' + this.format(cpy1) +
			' ' + this.format(cpx2) + ' ' + this.format(cpy2) +
			' ' + this.format(cpx3) + ' ' + this.format(cpy3));
	this.lastX = (cpx3 / s.scale) - s.dx;
	this.lastY = (cpy3 / s.scale) - s.dy;
	
};

/**
 * Function: createRect
 * 
 * Sets the glass gradient.
 */
mxVmlCanvas2D.prototype.createRect = function(nodeName, x, y, w, h)
{
	var s = this.state;
	var n = this.createVmlElement(nodeName);
	n.style.position = 'absolute';
	n.style.left = this.format((x + s.dx) * s.scale) + 'px';
	n.style.top = this.format((y + s.dy) * s.scale) + 'px';
	n.style.width = this.format(w * s.scale) + 'px';
	n.style.height = this.format(h * s.scale) + 'px';
	
	return n;
};

/**
 * Function: rect
 * 
 * Sets the current path to a rectangle.
 */
mxVmlCanvas2D.prototype.rect = function(x, y, w, h)
{
	this.node = this.createRect('rect', x, y, w, h);
};

/**
 * Function: roundrect
 * 
 * Sets the current path to a rounded rectangle.
 */
mxVmlCanvas2D.prototype.roundrect = function(x, y, w, h, dx, dy)
{
	this.node = this.createRect('roundrect', x, y, w, h);
	// SetAttribute needed here for IE8
	this.node.setAttribute('arcsize', Math.max(dx * 100 / w, dy * 100 / h) + '%');
};

/**
 * Function: ellipse
 * 
 * Sets the current path to an ellipse.
 */
mxVmlCanvas2D.prototype.ellipse = function(x, y, w, h)
{
	this.node = this.createRect('oval', x, y, w, h);
};

/**
 * Function: image
 * 
 * Paints an image.
 */
mxVmlCanvas2D.prototype.image = function(x, y, w, h, src, aspect, flipH, flipV)
{
	var node = null;
	
	if (!aspect)
	{
		node = this.createRect('image', x, y, w, h);
		node.src = src;
	}
	else
	{
		// Uses fill with aspect to avoid asynchronous update of size
		node = this.createRect('rect', x, y, w, h);
		node.stroked = 'false';
		
		// Handles image aspect via fill
		var fill = this.createVmlElement('fill');
		fill.aspect = (aspect) ? 'atmost' : 'ignore';
		fill.rotate = 'true';
		fill.type = 'frame';
		fill.src = src;

		node.appendChild(fill);
	}
	
	if (flipH && flipV)
	{
		node.style.rotation = '180';
	}
	else if (flipH)
	{
		node.style.flip = 'x';
	}
	else if (flipV)
	{
		node.style.flip = 'y';
	}
	
	if (this.state.alpha < 1 || this.state.fillAlpha < 1)
	{
		// KNOWN: Borders around transparent images in IE<9. Using fill.opacity
		// fixes this problem by adding a white background in all IE versions.
		node.style.filter += 'alpha(opacity=' + (this.state.alpha * this.state.fillAlpha * 100) + ')';
	}

	this.root.appendChild(node);
};

/**
 * Function: createText
 * 
 * Creates the innermost element that contains the HTML text.
 */
mxVmlCanvas2D.prototype.createDiv = function(str, align, valign, overflow)
{
	var div = this.createElement('div');
	var state = this.state;

	var css = '';
	
	if (state.fontBackgroundColor != null)
	{
		css += 'background-color:' + state.fontBackgroundColor + ';';
	}
	
	if (state.fontBorderColor != null)
	{
		css += 'border:1px solid ' + state.fontBorderColor + ';';
	}
	
	if (mxUtils.isNode(str))
	{
		div.appendChild(str);
	}
	else
	{
		if (overflow != 'fill' && overflow != 'width')
		{
			var div2 = this.createElement('div');
			div2.style.cssText = css;
			div2.style.display = (mxClient.IS_QUIRKS) ? 'inline' : 'inline-block';
			div2.style.zoom = '1';
			div2.style.textDecoration = 'inherit';
			div2.innerHTML = str;
			div.appendChild(div2);
		}
		else
		{
			div.style.cssText = css;
			div.innerHTML = str;
		}
	}
	
	var style = div.style;

	style.fontSize = (state.fontSize / this.vmlScale) + 'px';
	style.fontFamily = state.fontFamily;
	style.color = state.fontColor;
	style.verticalAlign = 'top';
	style.textAlign = align || 'left';
	style.lineHeight = (mxConstants.ABSOLUTE_LINE_HEIGHT) ? (state.fontSize * mxConstants.LINE_HEIGHT / this.vmlScale) + 'px' : mxConstants.LINE_HEIGHT;

	if ((state.fontStyle & mxConstants.FONT_BOLD) == mxConstants.FONT_BOLD)
	{
		style.fontWeight = 'bold';
	}

	if ((state.fontStyle & mxConstants.FONT_ITALIC) == mxConstants.FONT_ITALIC)
	{
		style.fontStyle = 'italic';
	}
	
	if ((state.fontStyle & mxConstants.FONT_UNDERLINE) == mxConstants.FONT_UNDERLINE)
	{
		style.textDecoration = 'underline';
	}
	
	return div;
};

/**
 * Function: text
 * 
 * Paints the given text. Possible values for format are empty string for plain
 * text and html for HTML markup. Clipping, text background and border are not
 * supported for plain text in VML.
 */
mxVmlCanvas2D.prototype.text = function(x, y, w, h, str, align, valign, wrap, format, overflow, clip, rotation, dir)
{
	if (this.textEnabled && str != null)
	{
		var s = this.state;
		
		if (format == 'html')
		{
			if (s.rotation != null)
			{
				var pt = this.rotatePoint(x, y, s.rotation, s.rotationCx, s.rotationCy);
				
				x = pt.x;
				y = pt.y;
			}

			if (document.documentMode == 8 && !mxClient.IS_EM)
			{
				x += s.dx;
				y += s.dy;
				
				// Workaround for rendering offsets
				if (overflow != 'fill' && valign == mxConstants.ALIGN_TOP)
				{
					y -= 1;
				}
			}
			else
			{
				x *= s.scale;
				y *= s.scale;
			}

			// Adds event transparency in IE8 standards without the transparent background
			// filter which cannot be used due to bugs in the zoomed bounding box (too slow)
			// FIXME: No event transparency if inside v:rect (ie part of shape)
			// KNOWN: Offset wrong for rotated text with word that are longer than the wrapping
			// width in IE8 because real width of text cannot be determined here.
			// This should be fixed in mxText.updateBoundingBox by calling before this and
			// passing the real width to this method if not clipped and wrapped.
			var abs = (document.documentMode == 8 && !mxClient.IS_EM) ? this.createVmlElement('group') : this.createElement('div');
			abs.style.position = 'absolute';
			abs.style.display = 'inline';
			abs.style.left = this.format(x) + 'px';
			abs.style.top = this.format(y) + 'px';
			abs.style.zoom = s.scale;

			var box = this.createElement('div');
			box.style.position = 'relative';
			box.style.display = 'inline';
			
			var margin = mxUtils.getAlignmentAsPoint(align, valign);
			var dx = margin.x;
			var dy = margin.y;

			var div = this.createDiv(str, align, valign, overflow);
			var inner = this.createElement('div');
			
			if (dir != null)
			{
				div.setAttribute('dir', dir);
			}

			if (wrap && w > 0)
			{
				if (!clip)
				{
					div.style.width = Math.round(w) + 'px';
				}
				
				div.style.wordWrap = mxConstants.WORD_WRAP;
				div.style.whiteSpace = 'normal';
				
				// LATER: Check if other cases need to be handled
				if (div.style.wordWrap == 'break-word')
				{
					var tmp = div;
					
					if (tmp.firstChild != null && tmp.firstChild.nodeName == 'DIV')
					{
						tmp.firstChild.style.width = '100%';
					}
				}
			}
			else
			{
				div.style.whiteSpace = 'nowrap';
			}
			
			var rot = s.rotation + (rotation || 0);
			
			if (this.rotateHtml && rot != 0)
			{
				inner.style.display = 'inline';
				inner.style.zoom = '1';
				inner.appendChild(div);

				// Box not needed for rendering in IE8 standards
				if (document.documentMode == 8 && !mxClient.IS_EM && this.root.nodeName != 'DIV')
				{
					box.appendChild(inner);
					abs.appendChild(box);
				}
				else
				{
					abs.appendChild(inner);
				}
			}
			else if (document.documentMode == 8 && !mxClient.IS_EM)
			{
				box.appendChild(div);
				abs.appendChild(box);
			}
			else
			{
				div.style.display = 'inline';
				abs.appendChild(div);
			}
			
			// Inserts the node into the DOM
			if (this.root.nodeName != 'DIV')
			{
				// Rectangle to fix position in group
				var rect = this.createVmlElement('rect');
				rect.stroked = 'false';
				rect.filled = 'false';

				rect.appendChild(abs);
				this.root.appendChild(rect);
			}
			else
			{
				this.root.appendChild(abs);
			}
			
			if (clip)
			{
				div.style.overflow = 'hidden';
				div.style.width = Math.round(w) + 'px';
				
				if (!mxClient.IS_QUIRKS)
				{
					div.style.maxHeight = Math.round(h) + 'px';
				}
			}
			else if (overflow == 'fill')
			{
				// KNOWN: Affects horizontal alignment in quirks
				// but fill should only be used with align=left
				div.style.overflow = 'hidden';
				div.style.width = (Math.max(0, w) + 1) + 'px';
				div.style.height = (Math.max(0, h) + 1) + 'px';
			}
			else if (overflow == 'width')
			{
				// KNOWN: Affects horizontal alignment in quirks
				// but fill should only be used with align=left
				div.style.overflow = 'hidden';
				div.style.width = (Math.max(0, w) + 1) + 'px';
				div.style.maxHeight = (Math.max(0, h) + 1) + 'px';
			}
			
			if (this.rotateHtml && rot != 0)
			{
				var rad = rot * (Math.PI / 180);
				
				// Precalculate cos and sin for the rotation
				var real_cos = parseFloat(parseFloat(Math.cos(rad)).toFixed(8));
				var real_sin = parseFloat(parseFloat(Math.sin(-rad)).toFixed(8));

				rad %= 2 * Math.PI;
				if (rad < 0) rad += 2 * Math.PI;
				rad %= Math.PI;
				if (rad > Math.PI / 2) rad = Math.PI - rad;
				
				var cos = Math.cos(rad);
				var sin = Math.sin(rad);

				// Adds div to document to measure size
				if (document.documentMode == 8 && !mxClient.IS_EM)
				{
					div.style.display = 'inline-block';
					inner.style.display = 'inline-block';
					box.style.display = 'inline-block';
				}
				
				div.style.visibility = 'hidden';
				div.style.position = 'absolute';
				document.body.appendChild(div);
				
				var sizeDiv = div;
				
				if (sizeDiv.firstChild != null && sizeDiv.firstChild.nodeName == 'DIV')
				{
					sizeDiv = sizeDiv.firstChild;
				}
				
				var tmp = sizeDiv.offsetWidth + 3;
				var oh = sizeDiv.offsetHeight;
				
				if (clip)
				{
					w = Math.min(w, tmp);
					oh = Math.min(oh, h);
				}
				else
				{
					w = tmp;
				}

				// Handles words that are longer than the given wrapping width
				if (wrap)
				{
					div.style.width = w + 'px';
				}
				
				// Simulates max-height in quirks
				if (mxClient.IS_QUIRKS && (clip || overflow == 'width') && oh > h)
				{
					oh = h;
					
					// Quirks does not support maxHeight
					div.style.height = oh + 'px';
				}
				
				h = oh;

				var top_fix = (h - h * cos + w * -sin) / 2 - real_sin * w * (dx + 0.5) + real_cos * h * (dy + 0.5);
				var left_fix = (w - w * cos + h * -sin) / 2 + real_cos * w * (dx + 0.5) + real_sin * h * (dy + 0.5);

				if (abs.nodeName == 'group' && this.root.nodeName == 'DIV')
				{
					// Workaround for bug where group gets moved away if left and top are non-zero in IE8 standards
					var pos = this.createElement('div');
					pos.style.display = 'inline-block';
					pos.style.position = 'absolute';
					pos.style.left = this.format(x + (left_fix - w / 2) * s.scale) + 'px';
					pos.style.top = this.format(y + (top_fix - h / 2) * s.scale) + 'px';
					
					abs.parentNode.appendChild(pos);
					pos.appendChild(abs);
				}
				else
				{
					var sc = (document.documentMode == 8 && !mxClient.IS_EM) ? 1 : s.scale;
					
					abs.style.left = this.format(x + (left_fix - w / 2) * sc) + 'px';
					abs.style.top = this.format(y + (top_fix - h / 2) * sc) + 'px';
				}
				
				// KNOWN: Rotated text rendering quality is bad for IE9 quirks
				inner.style.filter = "progid:DXImageTransform.Microsoft.Matrix(M11="+real_cos+", M12="+
					real_sin+", M21="+(-real_sin)+", M22="+real_cos+", sizingMethod='auto expand')";
				inner.style.backgroundColor = this.rotatedHtmlBackground;
				
				if (this.state.alpha < 1)
				{
					inner.style.filter += 'alpha(opacity=' + (this.state.alpha * 100) + ')';
				}

				// Restore parent node for DIV
				inner.appendChild(div);
				div.style.position = '';
				div.style.visibility = '';
			}
			else if (document.documentMode != 8 || mxClient.IS_EM)
			{
				div.style.verticalAlign = 'top';
				
				if (this.state.alpha < 1)
				{
					abs.style.filter = 'alpha(opacity=' + (this.state.alpha * 100) + ')';
				}
				
				// Adds div to document to measure size
				var divParent = div.parentNode;
				div.style.visibility = 'hidden';
				document.body.appendChild(div);
				
				w = div.offsetWidth;
				var oh = div.offsetHeight;
				
				// Simulates max-height in quirks
				if (mxClient.IS_QUIRKS && clip && oh > h)
				{
					oh = h;
					
					// Quirks does not support maxHeight
					div.style.height = oh + 'px';
				}
				
				h = oh;
				
				div.style.visibility = '';
				divParent.appendChild(div);
				
				abs.style.left = this.format(x + w * dx * this.state.scale) + 'px';
				abs.style.top = this.format(y + h * dy * this.state.scale) + 'px';
			}
			else
			{
				if (this.state.alpha < 1)
				{
					div.style.filter = 'alpha(opacity=' + (this.state.alpha * 100) + ')';
				}
				
				// Faster rendering in IE8 without offsetWidth/Height
				box.style.left = (dx * 100) + '%';
				box.style.top = (dy * 100) + '%';
			}
		}
		else
		{
			this.plainText(x, y, w, h, mxUtils.htmlEntities(str, false), align, valign, wrap, format, overflow, clip, rotation, dir);
		}
	}
};

/**
 * Function: plainText
 * 
 * Paints the outline of the current path.
 */
mxVmlCanvas2D.prototype.plainText = function(x, y, w, h, str, align, valign, wrap, format, overflow, clip, rotation, dir)
{
	// TextDirection is ignored since this code is not used (format is always HTML in the text function)
	var s = this.state;
	x = (x + s.dx) * s.scale;
	y = (y + s.dy) * s.scale;
	
	var node = this.createVmlElement('shape');
	node.style.width = '1px';
	node.style.height = '1px';
	node.stroked = 'false';

	var fill = this.createVmlElement('fill');
	fill.color = s.fontColor;
	fill.opacity = (s.alpha * 100) + '%';
	node.appendChild(fill);
	
	var path = this.createVmlElement('path');
	path.textpathok = 'true';
	path.v = 'm ' + this.format(0) + ' ' + this.format(0) + ' l ' + this.format(1) + ' ' + this.format(0);
	
	node.appendChild(path);
	
	// KNOWN: Font family and text decoration ignored
	var tp = this.createVmlElement('textpath');
	tp.style.cssText = 'v-text-align:' + align;
	tp.style.align = align;
	tp.style.fontFamily = s.fontFamily;
	tp.string = str;
	tp.on = 'true';
	
	// Scale via fontsize instead of node.style.zoom for correct offsets in IE8
	var size = s.fontSize * s.scale / this.vmlScale;
	tp.style.fontSize = size + 'px';
	
	// Bold
	if ((s.fontStyle & mxConstants.FONT_BOLD) == mxConstants.FONT_BOLD)
	{
		tp.style.fontWeight = 'bold';
	}
	
	// Italic
	if ((s.fontStyle & mxConstants.FONT_ITALIC) == mxConstants.FONT_ITALIC)
	{
		tp.style.fontStyle = 'italic';
	}

	// Underline
	if ((s.fontStyle & mxConstants.FONT_UNDERLINE) == mxConstants.FONT_UNDERLINE)
	{
		tp.style.textDecoration = 'underline';
	}

	var lines = str.split('\n');
	var textHeight = size + (lines.length - 1) * size * mxConstants.LINE_HEIGHT;
	var dx = 0;
	var dy = 0;

	if (valign == mxConstants.ALIGN_BOTTOM)
	{
		dy = - textHeight / 2;
	}
	else if (valign != mxConstants.ALIGN_MIDDLE) // top
	{
		dy = textHeight / 2;
	}

	if (rotation != null)
	{
		node.style.rotation = rotation;
		var rad = rotation * (Math.PI / 180);
		dx = Math.sin(rad) * dy;
		dy = Math.cos(rad) * dy;
	}

	// FIXME: Clipping is relative to bounding box
	/*if (clip)
	{
		node.style.clip = 'rect(0px ' + this.format(w) + 'px ' + this.format(h) + 'px 0px)';
	}*/
	
	node.appendChild(tp);
	node.style.left = this.format(x - dx) + 'px';
	node.style.top = this.format(y + dy) + 'px';
	
	this.root.appendChild(node);
};

/**
 * Function: stroke
 * 
 * Paints the outline of the current path.
 */
mxVmlCanvas2D.prototype.stroke = function()
{
	this.addNode(false, true);
};

/**
 * Function: fill
 * 
 * Fills the current path.
 */
mxVmlCanvas2D.prototype.fill = function()
{
	this.addNode(true, false);
};

/**
 * Function: fillAndStroke
 * 
 * Fills and paints the outline of the current path.
 */
mxVmlCanvas2D.prototype.fillAndStroke = function()
{
	this.addNode(true, true);
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxGuide
 *
 * Implements the alignment of selection cells to other cells in the graph.
 * 
 * Constructor: mxGuide
 * 
 * Constructs a new guide object.
 */
function mxGuide(graph, states)
{
	this.graph = graph;
	this.setStates(states);
};

/**
 * Variable: graph
 *
 * Reference to the enclosing <mxGraph> instance.
 */
mxGuide.prototype.graph = null;

/**
 * Variable: states
 * 
 * Contains the <mxCellStates> that are used for alignment.
 */
mxGuide.prototype.states = null;

/**
 * Variable: horizontal
 *
 * Specifies if horizontal guides are enabled. Default is true.
 */
mxGuide.prototype.horizontal = true;

/**
 * Variable: vertical
 *
 * Specifies if vertical guides are enabled. Default is true.
 */
mxGuide.prototype.vertical = true;

/**
 * Variable: vertical
 *
 * Holds the <mxShape> for the horizontal guide.
 */
mxGuide.prototype.guideX = null;

/**
 * Variable: vertical
 *
 * Holds the <mxShape> for the vertical guide.
 */
mxGuide.prototype.guideY = null;

/**
 * Function: setStates
 * 
 * Sets the <mxCellStates> that should be used for alignment.
 */
mxGuide.prototype.setStates = function(states)
{
	this.states = states;
};

/**
 * Function: isEnabledForEvent
 * 
 * Returns true if the guide should be enabled for the given native event. This
 * implementation always returns true.
 */
mxGuide.prototype.isEnabledForEvent = function(evt)
{
	return true;
};

/**
 * Function: getGuideTolerance
 * 
 * Returns the tolerance for the guides. Default value is gridSize / 2.
 */
mxGuide.prototype.getGuideTolerance = function()
{
	return this.graph.gridSize / 2;
};

/**
 * Function: createGuideShape
 * 
 * Returns the mxShape to be used for painting the respective guide. This
 * implementation returns a new, dashed and crisp <mxPolyline> using
 * <mxConstants.GUIDE_COLOR> and <mxConstants.GUIDE_STROKEWIDTH> as the format.
 * 
 * Parameters:
 * 
 * horizontal - Boolean that specifies which guide should be created.
 */
mxGuide.prototype.createGuideShape = function(horizontal)
{
	var guide = new mxPolyline([], mxConstants.GUIDE_COLOR, mxConstants.GUIDE_STROKEWIDTH);
	guide.isDashed = true;
	
	return guide;
};

/**
 * Function: move
 * 
 * Moves the <bounds> by the given <mxPoint> and returnt the snapped point.
 */
mxGuide.prototype.move = function(bounds, delta, gridEnabled)
{
	if (this.states != null && (this.horizontal || this.vertical) && bounds != null && delta != null)
	{
		var trx = this.graph.getView().translate;
		var scale = this.graph.getView().scale;
		var dx = delta.x;
		var dy = delta.y;
		
		var overrideX = false;
		var stateX = null;
		var valueX = null;
		var overrideY = false;
		var stateY = null;
		var valueY = null;
		
		var tt = this.getGuideTolerance();
		var ttX = tt;
		var ttY = tt;
		
		var b = bounds.clone();
		b.x += delta.x;
		b.y += delta.y;
		
		var left = b.x;
		var right = b.x + b.width;
		var center = b.getCenterX();
		var top = b.y;
		var bottom = b.y + b.height;
		var middle = b.getCenterY();
	
		// Snaps the left, center and right to the given x-coordinate
		function snapX(x, state)
		{
			x += this.graph.panDx;
			var override = false;
			
			if (Math.abs(x - center) < ttX)
			{
				dx = x - bounds.getCenterX();
				ttX = Math.abs(x - center);
				override = true;
			}
			else if (Math.abs(x - left) < ttX)
			{
				dx = x - bounds.x;
				ttX = Math.abs(x - left);
				override = true;
			}
			else if (Math.abs(x - right) < ttX)
			{
				dx = x - bounds.x - bounds.width;
				ttX = Math.abs(x - right);
				override = true;
			}
			
			if (override)
			{
				stateX = state;
				valueX = Math.round(x - this.graph.panDx);
				
				if (this.guideX == null)
				{
					this.guideX = this.createGuideShape(true);
					
					// Makes sure to use either VML or SVG shapes in order to implement
					// event-transparency on the background area of the rectangle since
					// HTML shapes do not let mouseevents through even when transparent
					this.guideX.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
						mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
					this.guideX.pointerEvents = false;
					this.guideX.init(this.graph.getView().getOverlayPane());
				}
			}
			
			overrideX = overrideX || override;
		};
		
		// Snaps the top, middle or bottom to the given y-coordinate
		function snapY(y)
		{
			y += this.graph.panDy;
			var override = false;
			
			if (Math.abs(y - middle) < ttY)
			{
				dy = y - bounds.getCenterY();
				ttY = Math.abs(y -  middle);
				override = true;
			}
			else if (Math.abs(y - top) < ttY)
			{
				dy = y - bounds.y;
				ttY = Math.abs(y - top);
				override = true;
			}
			else if (Math.abs(y - bottom) < ttY)
			{
				dy = y - bounds.y - bounds.height;
				ttY = Math.abs(y - bottom);
				override = true;
			}
			
			if (override)
			{
				stateY = state;
				valueY = Math.round(y - this.graph.panDy);
				
				if (this.guideY == null)
				{
					this.guideY = this.createGuideShape(false);
					
					// Makes sure to use either VML or SVG shapes in order to implement
					// event-transparency on the background area of the rectangle since
					// HTML shapes do not let mouseevents through even when transparent
					this.guideY.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
						mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
					this.guideY.pointerEvents = false;
					this.guideY.init(this.graph.getView().getOverlayPane());
				}
			}
			
			overrideY = overrideY || override;
		};
		
		for (var i = 0; i < this.states.length; i++)
		{
			var state =  this.states[i];
			
			if (state != null)
			{
				// Align x
				if (this.horizontal)
				{
					snapX.call(this, state.getCenterX(), state);
					snapX.call(this, state.x, state);
					snapX.call(this, state.x + state.width, state);
				}
	
				// Align y
				if (this.vertical)
				{
					snapY.call(this, state.getCenterY(), state);
					snapY.call(this, state.y, state);
					snapY.call(this, state.y + state.height, state);
				}
			}
		}

		// Moves cells that are off-grid back to the grid on move
		if (gridEnabled)
		{
			if (!overrideX)
			{
				var tx = bounds.x - (this.graph.snap(bounds.x /
					scale - trx.x) + trx.x) * scale;
				dx = this.graph.snap(dx / scale) * scale - tx;
			}
			
			if (!overrideY)
			{
				var ty = bounds.y - (this.graph.snap(bounds.y /
					scale - trx.y) + trx.y) * scale;
				dy = this.graph.snap(dy / scale) * scale - ty;
			}
		}
		
		// Redraws the guides
		var c = this.graph.container;
		
		if (!overrideX && this.guideX != null)
		{
			this.guideX.node.style.visibility = 'hidden';
		}
		else if (this.guideX != null)
		{
			if (stateX != null && bounds != null)
			{
				minY = Math.min(bounds.y + dy - this.graph.panDy, stateX.y);
				maxY = Math.max(bounds.y + bounds.height + dy - this.graph.panDy, stateX.y + stateX.height);
			}
			
			if (minY != null && maxY != null)
			{
				this.guideX.points = [new mxPoint(valueX, minY), new mxPoint(valueX, maxY)];
			}
			else
			{
				this.guideX.points = [new mxPoint(valueX, -this.graph.panDy), new mxPoint(valueX, c.scrollHeight - 3 - this.graph.panDy)];
			}
			
			this.guideX.stroke = this.getGuideColor(stateX, true);
			this.guideX.node.style.visibility = 'visible';
			this.guideX.redraw();
		}
		
		if (!overrideY && this.guideY != null)
		{
			this.guideY.node.style.visibility = 'hidden';
		}
		else if (this.guideY != null)
		{
			if (stateY != null && bounds != null)
			{
				minX = Math.min(bounds.x + dx - this.graph.panDx, stateY.x);
				maxX = Math.max(bounds.x + bounds.width + dx - this.graph.panDx, stateY.x + stateY.width);
			}
			
			if (minX != null && maxX != null)
			{
				this.guideY.points = [new mxPoint(minX, valueY), new mxPoint(maxX, valueY)];
			}
			else
			{
				this.guideY.points = [new mxPoint(-this.graph.panDx, valueY), new mxPoint(c.scrollWidth - 3 - this.graph.panDx, valueY)];
			}
			
			this.guideY.stroke = this.getGuideColor(stateY, false);
			this.guideY.node.style.visibility = 'visible';
			this.guideY.redraw();
		}
		
		delta = new mxPoint(dx, dy);
	}
	
	return delta;
};

/**
 * Function: hide
 * 
 * Hides all current guides.
 */
mxGuide.prototype.getGuideColor = function(state, horizontal)
{
	return mxConstants.GUIDE_COLOR;
};

/**
 * Function: hide
 * 
 * Hides all current guides.
 */
mxGuide.prototype.hide = function()
{
	this.setVisible(false);
};

/**
 * Function: setVisible
 * 
 * Shows or hides the current guides.
 */
mxGuide.prototype.setVisible = function(visible)
{
	if (this.guideX != null)
	{
		this.guideX.node.style.visibility = (visible) ? 'visible' : 'hidden';
	}
	
	if (this.guideY != null)
	{
		this.guideY.node.style.visibility = (visible) ? 'visible' : 'hidden';
	}
};

/**
 * Function: destroy
 * 
 * Destroys all resources that this object uses.
 */
mxGuide.prototype.destroy = function()
{
	if (this.guideX != null)
	{
		this.guideX.destroy();
		this.guideX = null;
	}
	
	if (this.guideY != null)
	{
		this.guideY.destroy();
		this.guideY = null;
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxStencil
 *
 * Implements a generic shape which is based on a XML node as a description.
 * 
 * shape:
 * 
 * The outer element is *shape*, that has attributes:
 * 
 * - "name", string, required. The stencil name that uniquely identifies the shape.
 * - "w" and "h" are optional decimal view bounds. This defines your co-ordinate
 * system for the graphics operations in the shape. The default is 100,100.
 * - "aspect", optional string. Either "variable", the default, or "fixed". Fixed
 * means always render the shape with the aspect ratio defined by the ratio w/h.
 * Variable causes the ratio to match that of the geometry of the current vertex.
 * - "strokewidth", optional string. Either an integer or the string "inherit".
 * "inherit" indicates that the strokeWidth of the cell is only changed on scaling,
 * not on resizing. Default is "1".
 * If numeric values are used, the strokeWidth of the cell is changed on both
 * scaling and resizing and the value defines the multiple that is applied to
 * the width.
 * 
 * connections:
 * 
 * If you want to define specific fixed connection points on the shape use the
 * *connections* element. Each *constraint* element within connections defines
 * a fixed connection point on the shape. Constraints have attributes:
 * 
 * - "perimeter", required. 1 or 0. 0 sets the connection point where specified
 * by x,y. 1 Causes the position of the connection point to be extrapolated from
 * the center of the shape, through x,y to the point of intersection with the
 * perimeter of the shape.
 * - "x" and "y" are the position of the fixed point relative to the bounds of
 * the shape. They can be automatically adjusted if perimeter=1. So, (0,0) is top
 * left, (0.5,0.5) the center, (1,0.5) the center of the right hand edge of the
 * bounds, etc. Values may be less than 0 or greater than 1 to be positioned
 * outside of the shape.
 * - "name", optional string. A unique identifier for the port on the shape.
 * 
 * background and foreground:
 * 
 * The path of the graphics drawing is split into two elements, *foreground* and
 * *background*. The split is to define which part any shadow applied to the shape
 * is derived from (the background). This, generally, means the background is the
 * line tracing of the outside of the shape, but not always.
 * 
 * Any stroke, fill or fillstroke of a background must be the first element of the
 * foreground element, they must not be used within *background*. If the background
 * is empty, this is not required.
 * 
 * Because the background cannot have any fill or stroke, it can contain only one
 * *path*, *rect*, *roundrect* or *ellipse* element (or none). It can also not
 * include *image*, *text* or *include-shape*.
 * 
 * Note that the state, styling and drawing in mxGraph stencils is very close in
 * design to that of HTML 5 canvas. Tutorials on this subject, if you're not
 * familiar with the topic, will give a good high-level introduction to the
 * concepts used.
 * 
 * State:
 * 
 * Rendering within the foreground and background elements has the concept of
 * state. There are two types of operations other than state save/load, styling
 * and drawing. The styling operations change the current state, so you can save
 * the current state with <save/> and pull the last saved state from the state
 * stack using <restore/>.
 * 
 * Styling:
 * 
 * The elements that change colors within the current state all take a hash
 * prefixed hex color code ("#FFEA80").
 * 
 * - *strokecolor*, this sets the color that drawing paths will be rendered in
 * when a stroke or fillstroke command is issued.
 * - *fillcolor*, this sets the color that the inside of closed paths will be
 * rendered in when a fill or fillstroke command is issued.
 * - *fontcolor*, this sets the color that fonts are rendered in when text is drawn.
 * 
 * *alpha* defines the degree of transparency used between 1.0 for fully opaque
 * and 0.0 for fully transparent.
 * 
 * *strokewidth* defines the integer thickness of drawing elements rendered by
 * stroking. Use fixed="1" to apply the value as-is, without scaling.
 * 
 * *dashed* is "1" for dashing enabled and "0" for disabled.
 * 
 * When *dashed* is enabled the current dash pattern, defined by *dashpattern*,
 * is used on strokes. dashpattern is a sequence of space separated "on, off"
 * lengths that define what distance to paint the stroke for, then what distance
 * to paint nothing for, repeat... The default is "3 3". You could define a more
 * complex pattern with "5 3 2 6", for example. Generally, it makes sense to have
 * an even number of elements in the dashpattern, but that's not required.
 * 
 * *linejoin*, *linecap* and *miterlimit* are best explained by the Mozilla page
 * on Canvas styling (about halfway down). The values are all the same except we
 * use "flat" for linecap, instead of Canvas' "butt".
 * 
 * For font styling there are.
 * 
 * - *fontsize*, an integer,
 * - *fontstyle*, an ORed bit pattern of bold (1), italic (2) and underline (4),
 * i.e bold underline is "5".
 * - *fontfamily*, is a string defining the typeface to be used.
 * 
 * Drawing:
 * 
 * Most drawing is contained within a *path* element. Again, the graphic
 * primitives are very similar to that of HTML 5 canvas.
 * 
 * - *move* to attributes required decimals (x,y).
 * - *line* to attributes required decimals (x,y).
 * - *quad* to required decimals (x2,y2) via control point required decimals
 * (x1,y1).
 * - *curve* to required decimals (x3,y3), via control points required decimals
 * (x1,y1) and (x2,y2).
 * - *arc*, this doesn't follow the HTML Canvas signatures, instead it's a copy
 * of the SVG arc command. The SVG specification documentation gives the best
 * description of its behaviors. The attributes are named identically, they are
 * decimals and all required.
 * - *close* ends the current subpath and causes an automatic straight line to
 * be drawn from the current point to the initial point of the current subpath.
 * 
 * Complex drawing:
 * 
 * In addition to the graphics primitive operations there are non-primitive
 * operations. These provide an easy method to draw some basic shapes.
 * 
 * - *rect*, attributes "x", "y", "w", "h", all required decimals
 * - *roundrect*, attributes "x", "y", "w", "h", all required decimals. Also
 * "arcsize" an optional decimal attribute defining how large, the corner curves
 * are.
 * - *ellipse*, attributes "x", "y", "w", "h", all required decimals.
 * 
 * Note that these 3 shapes and all paths must be followed by either a fill,
 * stroke, or fillstroke.
 * 
 * Text:
 * 
 * *text* elements have the following attributes.
 * 
 * - "str", the text string to display, required.
 * - "x" and "y", the decimal location (x,y) of the text element, required.
 * - "align", the horizontal alignment of the text element, either "left",
 * "center" or "right". Optional, default is "left".
 * - "valign", the vertical alignment of the text element, either "top", "middle"
 * or "bottom". Optional, default is "top".
 * - "localized", 0 or 1, if 1 then the "str" actually contains a key to use to
 * fetch the value out of mxResources. Optional, default is
 * <mxStencil.defaultLocalized>.
 * - "vertical", 0 or 1, if 1 the label is rendered vertically (rotated by 90
 * degrees). Optional, default is 0.
 * - "rotation", angle in degrees (0 to 360). The angle to rotate the text by.
 * Optional, default is 0.
 * - "align-shape", 0 or 1, if 0 ignore the rotation of the shape when setting
 * the text rotation. Optional, default is 1.
 * 
 * If <allowEval> is true, then the text content of the this element can define
 * a function which is invoked with the shape as the only argument and returns
 * the value for the text element (ignored if the str attribute is not null).
 * 
 * Images:
 * 
 * *image* elements can either be external URLs, or data URIs, where supported
 * (not in IE 7-). Attributes are:
 * 
 * - "src", required string. Either a data URI or URL.
 * - "x", "y", required decimals. The (x,y) position of the image.
 * - "w", "h", required decimals. The width and height of the image.
 * - "flipH" and "flipV", optional 0 or 1. Whether to flip the image along the
 * horizontal/vertical axis. Default is 0 for both.
 * 
 * If <allowEval> is true, then the text content of the this element can define
 * a function which is invoked with the shape as the only argument and returns
 * the value for the image source (ignored if the src attribute is not null).
 * 
 * Sub-shapes:
 * 
 * *include-shape* allow stencils to be rendered within the current stencil by
 * referencing the sub-stencil by name. Attributes are:
 * 
 * - "name", required string. The unique shape name of the stencil.
 * - "x", "y", "w", "h", required decimals. The (x,y) position of the sub-shape
 * and its width and height.
 * 
 * Constructor: mxStencil
 * 
 * Constructs a new generic shape by setting <desc> to the given XML node and
 * invoking <parseDescription> and <parseConstraints>.
 * 
 * Parameters:
 * 
 * desc - XML node that contains the stencil description.
 */
function mxStencil(desc)
{
	this.desc = desc;
	this.parseDescription();
	this.parseConstraints();
};

/**
 * Variable: defaultLocalized
 * 
 * Static global variable that specifies the default value for the localized
 * attribute of the text element. Default is false.
 */
mxStencil.defaultLocalized = false;

/**
 * Function: allowEval
 * 
 * Static global switch that specifies if the use of eval is allowed for
 * evaluating text content and images. Default is false. Set this to true
 * if stencils can not contain user input.
 */
mxStencil.allowEval = false;

/**
 * Variable: desc
 *
 * Holds the XML node with the stencil description.
 */
mxStencil.prototype.desc = null;

/**
 * Variable: constraints
 * 
 * Holds an array of <mxConnectionConstraints> as defined in the shape.
 */
mxStencil.prototype.constraints = null;

/**
 * Variable: aspect
 *
 * Holds the aspect of the shape. Default is 'auto'.
 */
mxStencil.prototype.aspect = null;

/**
 * Variable: w0
 *
 * Holds the width of the shape. Default is 100.
 */
mxStencil.prototype.w0 = null;

/**
 * Variable: h0
 *
 * Holds the height of the shape. Default is 100.
 */
mxStencil.prototype.h0 = null;

/**
 * Variable: bgNodes
 *
 * Holds the XML node with the stencil description.
 */
mxStencil.prototype.bgNode = null;

/**
 * Variable: fgNodes
 *
 * Holds the XML node with the stencil description.
 */
mxStencil.prototype.fgNode = null;

/**
 * Variable: strokewidth
 *
 * Holds the strokewidth direction from the description.
 */
mxStencil.prototype.strokewidth = null;

/**
 * Function: parseDescription
 *
 * Reads <w0>, <h0>, <aspect>, <bgNodes> and <fgNodes> from <desc>.
 */
mxStencil.prototype.parseDescription = function()
{
	// LATER: Preprocess nodes for faster painting
	this.fgNode = this.desc.getElementsByTagName('foreground')[0];
	this.bgNode = this.desc.getElementsByTagName('background')[0];
	this.w0 = Number(this.desc.getAttribute('w') || 100);
	this.h0 = Number(this.desc.getAttribute('h') || 100);
	
	// Possible values for aspect are: variable and fixed where
	// variable means fill the available space and fixed means
	// use w0 and h0 to compute the aspect.
	var aspect = this.desc.getAttribute('aspect');
	this.aspect = (aspect != null) ? aspect : 'variable';
	
	// Possible values for strokewidth are all numbers and "inherit"
	// where the inherit means take the value from the style (ie. the
	// user-defined stroke-width). Note that the strokewidth is scaled
	// by the minimum scaling that is used to draw the shape (sx, sy).
	var sw = this.desc.getAttribute('strokewidth');
	this.strokewidth = (sw != null) ? sw : '1';
};

/**
 * Function: parseConstraints
 *
 * Reads the constraints from <desc> into <constraints> using
 * <parseConstraint>.
 */
mxStencil.prototype.parseConstraints = function()
{
	var conns = this.desc.getElementsByTagName('connections')[0];
	
	if (conns != null)
	{
		var tmp = mxUtils.getChildNodes(conns);
		
		if (tmp != null && tmp.length > 0)
		{
			this.constraints = [];
			
			for (var i = 0; i < tmp.length; i++)
			{
				this.constraints.push(this.parseConstraint(tmp[i]));
			}
		}
	}
};

/**
 * Function: parseConstraint
 *
 * Parses the given XML node and returns its <mxConnectionConstraint>.
 */
mxStencil.prototype.parseConstraint = function(node)
{
	var x = Number(node.getAttribute('x'));
	var y = Number(node.getAttribute('y'));
	var perimeter = node.getAttribute('perimeter') == '1';
	var name = node.getAttribute('name');
	
	return new mxConnectionConstraint(new mxPoint(x, y), perimeter, name);
};

/**
 * Function: evaluateTextAttribute
 * 
 * Gets the given attribute as a text. The return value from <evaluateAttribute>
 * is used as a key to <mxResources.get> if the localized attribute in the text
 * node is 1 or if <defaultLocalized> is true.
 */
mxStencil.prototype.evaluateTextAttribute = function(node, attribute, shape)
{
	var result = this.evaluateAttribute(node, attribute, shape);
	var loc = node.getAttribute('localized');
	
	if ((mxStencil.defaultLocalized && loc == null) || loc == '1')
	{
		result = mxResources.get(result);
	}

	return result;
};

/**
 * Function: evaluateAttribute
 *
 * Gets the attribute for the given name from the given node. If the attribute
 * does not exist then the text content of the node is evaluated and if it is
 * a function it is invoked with <shape> as the only argument and the return
 * value is used as the attribute value to be returned.
 */
mxStencil.prototype.evaluateAttribute = function(node, attribute, shape)
{
	var result = node.getAttribute(attribute);
	
	if (result == null)
	{
		var text = mxUtils.getTextContent(node);
		
		if (text != null && mxStencil.allowEval)
		{
			var funct = mxUtils.eval(text);
			
			if (typeof(funct) == 'function')
			{
				result = funct(shape);
			}
		}
	}
	
	return result;
};

/**
 * Function: drawShape
 *
 * Draws this stencil inside the given bounds.
 */
mxStencil.prototype.drawShape = function(canvas, shape, x, y, w, h)
{
	// TODO: Internal structure (array of special structs?), relative and absolute
	// coordinates (eg. note shape, process vs star, actor etc.), text rendering
	// and non-proportional scaling, how to implement pluggable edge shapes
	// (start, segment, end blocks), pluggable markers, how to implement
	// swimlanes (title area) with this API, add icon, horizontal/vertical
	// label, indicator for all shapes, rotation
	var direction = mxUtils.getValue(shape.style, mxConstants.STYLE_DIRECTION, null);
	var aspect = this.computeAspect(shape.style, x, y, w, h, direction);
	var minScale = Math.min(aspect.width, aspect.height);
	var sw = (this.strokewidth == 'inherit') ?
			Number(mxUtils.getNumber(shape.style, mxConstants.STYLE_STROKEWIDTH, 1)) :
			Number(this.strokewidth) * minScale;
	canvas.setStrokeWidth(sw);

	this.drawChildren(canvas, shape, x, y, w, h, this.bgNode, aspect, false);
	this.drawChildren(canvas, shape, x, y, w, h, this.fgNode, aspect, true);
};

/**
 * Function: drawChildren
 *
 * Draws this stencil inside the given bounds.
 */
mxStencil.prototype.drawChildren = function(canvas, shape, x, y, w, h, node, aspect, disableShadow)
{
	if (node != null && w > 0 && h > 0)
	{
		var tmp = node.firstChild;
		
		while (tmp != null)
		{
			if (tmp.nodeType == mxConstants.NODETYPE_ELEMENT)
			{
				this.drawNode(canvas, shape, tmp, aspect, disableShadow);
			}
			
			tmp = tmp.nextSibling;
		}
	}
};

/**
 * Function: computeAspect
 *
 * Returns a rectangle that contains the offset in x and y and the horizontal
 * and vertical scale in width and height used to draw this shape inside the
 * given <mxRectangle>.
 * 
 * Parameters:
 * 
 * shape - <mxShape> to be drawn.
 * bounds - <mxRectangle> that should contain the stencil.
 * direction - Optional direction of the shape to be darwn.
 */
mxStencil.prototype.computeAspect = function(shape, x, y, w, h, direction)
{
	var x0 = x;
	var y0 = y;
	var sx = w / this.w0;
	var sy = h / this.h0;
	
	var inverse = (direction == mxConstants.DIRECTION_NORTH || direction == mxConstants.DIRECTION_SOUTH);

	if (inverse)
	{
		sy = w / this.h0;
		sx = h / this.w0;
		
		var delta = (w - h) / 2;

		x0 += delta;
		y0 -= delta;
	}

	if (this.aspect == 'fixed')
	{
		sy = Math.min(sx, sy);
		sx = sy;
		
		// Centers the shape inside the available space
		if (inverse)
		{
			x0 += (h - this.w0 * sx) / 2;
			y0 += (w - this.h0 * sy) / 2;
		}
		else
		{
			x0 += (w - this.w0 * sx) / 2;
			y0 += (h - this.h0 * sy) / 2;
		}
	}

	return new mxRectangle(x0, y0, sx, sy);
};

/**
 * Function: drawNode
 *
 * Draws this stencil inside the given bounds.
 */
mxStencil.prototype.drawNode = function(canvas, shape, node, aspect, disableShadow)
{
	var name = node.nodeName;
	var x0 = aspect.x;
	var y0 = aspect.y;
	var sx = aspect.width;
	var sy = aspect.height;
	var minScale = Math.min(sx, sy);

	if (name == 'save')
	{
		canvas.save();
	}
	else if (name == 'restore')
	{
		canvas.restore();
	}
	else if (name == 'path')
	{
		canvas.begin();

		// Renders the elements inside the given path
		var childNode = node.firstChild;
		
		while (childNode != null)
		{
			if (childNode.nodeType == mxConstants.NODETYPE_ELEMENT)
			{
				this.drawNode(canvas, shape, childNode, aspect, disableShadow);
			}
			
			childNode = childNode.nextSibling;
		}
	}
	else if (name == 'close')
	{
		canvas.close();
	}
	else if (name == 'move')
	{
		canvas.moveTo(x0 + Number(node.getAttribute('x')) * sx, y0 + Number(node.getAttribute('y')) * sy);
	}
	else if (name == 'line')
	{
		canvas.lineTo(x0 + Number(node.getAttribute('x')) * sx, y0 + Number(node.getAttribute('y')) * sy);
	}
	else if (name == 'quad')
	{
		canvas.quadTo(x0 + Number(node.getAttribute('x1')) * sx,
				y0 + Number(node.getAttribute('y1')) * sy,
				x0 + Number(node.getAttribute('x2')) * sx,
				y0 + Number(node.getAttribute('y2')) * sy);
	}
	else if (name == 'curve')
	{
		canvas.curveTo(x0 + Number(node.getAttribute('x1')) * sx,
				y0 + Number(node.getAttribute('y1')) * sy,
				x0 + Number(node.getAttribute('x2')) * sx,
				y0 + Number(node.getAttribute('y2')) * sy,
				x0 + Number(node.getAttribute('x3')) * sx,
				y0 + Number(node.getAttribute('y3')) * sy);
	}
	else if (name == 'arc')
	{
		canvas.arcTo(Number(node.getAttribute('rx')) * sx,
				Number(node.getAttribute('ry')) * sy,
				Number(node.getAttribute('x-axis-rotation')),
				Number(node.getAttribute('large-arc-flag')),
				Number(node.getAttribute('sweep-flag')),
				x0 + Number(node.getAttribute('x')) * sx,
				y0 + Number(node.getAttribute('y')) * sy);
	}
	else if (name == 'rect')
	{
		canvas.rect(x0 + Number(node.getAttribute('x')) * sx,
				y0 + Number(node.getAttribute('y')) * sy,
				Number(node.getAttribute('w')) * sx,
				Number(node.getAttribute('h')) * sy);
	}
	else if (name == 'roundrect')
	{
		var arcsize = Number(node.getAttribute('arcsize'));

		if (arcsize == 0)
		{
			arcsize = mxConstants.RECTANGLE_ROUNDING_FACTOR * 100;
		}
		
		var w = Number(node.getAttribute('w')) * sx;
		var h = Number(node.getAttribute('h')) * sy;
		var factor = Number(arcsize) / 100;
		var r = Math.min(w * factor, h * factor);
		
		canvas.roundrect(x0 + Number(node.getAttribute('x')) * sx,
				y0 + Number(node.getAttribute('y')) * sy,
				w, h, r, r);
	}
	else if (name == 'ellipse')
	{
		canvas.ellipse(x0 + Number(node.getAttribute('x')) * sx,
			y0 + Number(node.getAttribute('y')) * sy,
			Number(node.getAttribute('w')) * sx,
			Number(node.getAttribute('h')) * sy);
	}
	else if (name == 'image')
	{
		if (!shape.outline)
		{
			var src = this.evaluateAttribute(node, 'src', shape);
			
			canvas.image(x0 + Number(node.getAttribute('x')) * sx,
				y0 + Number(node.getAttribute('y')) * sy,
				Number(node.getAttribute('w')) * sx,
				Number(node.getAttribute('h')) * sy,
				src, false, node.getAttribute('flipH') == '1',
				node.getAttribute('flipV') == '1');
		}
	}
	else if (name == 'text')
	{
		if (!shape.outline)
		{
			var str = this.evaluateTextAttribute(node, 'str', shape);
			var rotation = node.getAttribute('vertical') == '1' ? -90 : 0;
			
			if (node.getAttribute('align-shape') == '0')
			{
				var dr = shape.rotation;
	
				// Depends on flipping
				var flipH = mxUtils.getValue(shape.style, mxConstants.STYLE_FLIPH, 0) == 1;
				var flipV = mxUtils.getValue(shape.style, mxConstants.STYLE_FLIPV, 0) == 1;
				
				if (flipH && flipV)
				{
					rotation -= dr;
				}
				else if (flipH || flipV)
				{
					rotation += dr;
				}
				else
				{
					rotation -= dr;
				}
			}
	
			rotation -= node.getAttribute('rotation');
	
			canvas.text(x0 + Number(node.getAttribute('x')) * sx,
					y0 + Number(node.getAttribute('y')) * sy,
					0, 0, str, node.getAttribute('align') || 'left',
					node.getAttribute('valign') || 'top', false, '',
					null, false, rotation);
		}
	}
	else if (name == 'include-shape')
	{
		var stencil = mxStencilRegistry.getStencil(node.getAttribute('name'));
		
		if (stencil != null)
		{
			var x = x0 + Number(node.getAttribute('x')) * sx;
			var y = y0 + Number(node.getAttribute('y')) * sy;
			var w = Number(node.getAttribute('w')) * sx;
			var h = Number(node.getAttribute('h')) * sy;
			
			stencil.drawShape(canvas, shape, x, y, w, h);
		}
	}
	else if (name == 'fillstroke')
	{
		canvas.fillAndStroke();
	}
	else if (name == 'fill')
	{
		canvas.fill();
	}
	else if (name == 'stroke')
	{
		canvas.stroke();
	}
	else if (name == 'strokewidth')
	{
		var s = (node.getAttribute('fixed') == '1') ? 1 : minScale;
		canvas.setStrokeWidth(Number(node.getAttribute('width')) * s);
	}
	else if (name == 'dashed')
	{
		canvas.setDashed(node.getAttribute('dashed') == '1');
	}
	else if (name == 'dashpattern')
	{
		var value = node.getAttribute('pattern');
		
		if (value != null)
		{
			var tmp = value.split(' ');
			var pat = [];
			
			for (var i = 0; i < tmp.length; i++)
			{
				if (tmp[i].length > 0)
				{
					pat.push(Number(tmp[i]) * minScale);
				}
			}
			
			value = pat.join(' ');
			canvas.setDashPattern(value);
		}
	}
	else if (name == 'strokecolor')
	{
		canvas.setStrokeColor(node.getAttribute('color'));
	}
	else if (name == 'linecap')
	{
		canvas.setLineCap(node.getAttribute('cap'));
	}
	else if (name == 'linejoin')
	{
		canvas.setLineJoin(node.getAttribute('join'));
	}
	else if (name == 'miterlimit')
	{
		canvas.setMiterLimit(Number(node.getAttribute('limit')));
	}
	else if (name == 'fillcolor')
	{
		canvas.setFillColor(node.getAttribute('color'));
	}
	else if (name == 'alpha')
	{
		canvas.setAlpha(node.getAttribute('alpha'));
	}
	else if (name == 'fontcolor')
	{
		canvas.setFontColor(node.getAttribute('color'));
	}
	else if (name == 'fontstyle')
	{
		canvas.setFontStyle(node.getAttribute('style'));
	}
	else if (name == 'fontfamily')
	{
		canvas.setFontFamily(node.getAttribute('family'));
	}
	else if (name == 'fontsize')
	{
		canvas.setFontSize(Number(node.getAttribute('size')) * minScale);
	}
	
	if (disableShadow && (name == 'fillstroke' || name == 'fill' || name == 'stroke'))
	{
		disableShadow = false;
		canvas.setShadow(false);
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxShape
 *
 * Base class for all shapes. A shape in mxGraph is a
 * separate implementation for SVG, VML and HTML. Which
 * implementation to use is controlled by the <dialect>
 * property which is assigned from within the <mxCellRenderer>
 * when the shape is created. The dialect must be assigned
 * for a shape, and it does normally depend on the browser and
 * the confiuration of the graph (see <mxGraph> rendering hint).
 *
 * For each supported shape in SVG and VML, a corresponding
 * shape exists in mxGraph, namely for text, image, rectangle,
 * rhombus, ellipse and polyline. The other shapes are a
 * combination of these shapes (eg. label and swimlane)
 * or they consist of one or more (filled) path objects
 * (eg. actor and cylinder). The HTML implementation is
 * optional but may be required for a HTML-only view of
 * the graph.
 *
 * Custom Shapes:
 *
 * To extend from this class, the basic code looks as follows.
 * In the special case where the custom shape consists only of
 * one filled region or one filled region and an additional stroke
 * the <mxActor> and <mxCylinder> should be subclassed,
 * respectively.
 *
 * (code)
 * function CustomShape() { }
 * 
 * CustomShape.prototype = new mxShape();
 * CustomShape.prototype.constructor = CustomShape; 
 * (end)
 *
 * To register a custom shape in an existing graph instance,
 * one must register the shape under a new name in the graph's
 * cell renderer as follows:
 *
 * (code)
 * mxCellRenderer.registerShape('customShape', CustomShape);
 * (end)
 *
 * The second argument is the name of the constructor.
 *
 * In order to use the shape you can refer to the given name above
 * in a stylesheet. For example, to change the shape for the default
 * vertex style, the following code is used:
 *
 * (code)
 * var style = graph.getStylesheet().getDefaultVertexStyle();
 * style[mxConstants.STYLE_SHAPE] = 'customShape';
 * (end)
 * 
 * Constructor: mxShape
 *
 * Constructs a new shape.
 */
function mxShape(stencil)
{
	this.stencil = stencil;
	this.initStyles();
};

/**
 * Variable: dialect
 *
 * Holds the dialect in which the shape is to be painted.
 * This can be one of the DIALECT constants in <mxConstants>.
 */
mxShape.prototype.dialect = null;

/**
 * Variable: scale
 *
 * Holds the scale in which the shape is being painted.
 */
mxShape.prototype.scale = 1;

/**
 * Variable: antiAlias
 * 
 * Rendering hint for configuring the canvas.
 */
mxShape.prototype.antiAlias = true;

/**
 * Variable: bounds
 *
 * Holds the <mxRectangle> that specifies the bounds of this shape.
 */
mxShape.prototype.bounds = null;

/**
 * Variable: points
 *
 * Holds the array of <mxPoints> that specify the points of this shape.
 */
mxShape.prototype.points = null;

/**
 * Variable: node
 *
 * Holds the outermost DOM node that represents this shape.
 */
mxShape.prototype.node = null;
 
/**
 * Variable: state
 * 
 * Optional reference to the corresponding <mxCellState>.
 */
mxShape.prototype.state = null;

/**
 * Variable: style
 *
 * Optional reference to the style of the corresponding <mxCellState>.
 */
mxShape.prototype.style = null;

/**
 * Variable: boundingBox
 *
 * Contains the bounding box of the shape, that is, the smallest rectangle
 * that includes all pixels of the shape.
 */
mxShape.prototype.boundingBox = null;

/**
 * Variable: stencil
 *
 * Holds the <mxStencil> that defines the shape.
 */
mxShape.prototype.stencil = null;

/**
 * Variable: svgStrokeTolerance
 *
 * Event-tolerance for SVG strokes (in px). Default is 8. This is only passed
 * to the canvas in <createSvgCanvas> if <pointerEvents> is true.
 */
mxShape.prototype.svgStrokeTolerance = 8;

/**
 * Variable: pointerEvents
 * 
 * Specifies if pointer events should be handled. Default is true.
 */
mxShape.prototype.pointerEvents = true;

/**
 * Variable: svgPointerEvents
 * 
 * Specifies if pointer events should be handled. Default is true.
 */
mxShape.prototype.svgPointerEvents = 'all';

/**
 * Variable: shapePointerEvents
 * 
 * Specifies if pointer events outside of shape should be handled. Default
 * is false.
 */
mxShape.prototype.shapePointerEvents = false;

/**
 * Variable: stencilPointerEvents
 * 
 * Specifies if pointer events outside of stencils should be handled. Default
 * is false. Set this to true for backwards compatibility with the 1.x branch.
 */
mxShape.prototype.stencilPointerEvents = false;

/**
 * Variable: vmlScale
 * 
 * Scale for improving the precision of VML rendering. Default is 1.
 */
mxShape.prototype.vmlScale = 1;

/**
 * Variable: outline
 * 
 * Specifies if the shape should be drawn as an outline. This disables all
 * fill colors and can be used to disable other drawing states that should
 * not be painted for outlines. Default is false. This should be set before
 * calling <apply>.
 */
mxShape.prototype.outline = false;

/**
 * Variable: visible
 * 
 * Specifies if the shape is visible. Default is true.
 */
mxShape.prototype.visible = true;

/**
 * Variable: useSvgBoundingBox
 * 
 * Allows to use the SVG bounding box in SVG. Default is false for performance
 * reasons.
 */
mxShape.prototype.useSvgBoundingBox = false;

/**
 * Function: init
 *
 * Initializes the shape by creaing the DOM node using <create>
 * and adding it into the given container.
 *
 * Parameters:
 *
 * container - DOM node that will contain the shape.
 */
mxShape.prototype.init = function(container)
{
	if (this.node == null)
	{
		this.node = this.create(container);
		
		if (container != null)
		{
			container.appendChild(this.node);
		}
	}
};

/**
 * Function: initStyles
 *
 * Sets the styles to their default values.
 */
mxShape.prototype.initStyles = function(container)
{
	this.strokewidth = 1;
	this.rotation = 0;
	this.opacity = 100;
	this.fillOpacity = 100;
	this.strokeOpacity = 100;
	this.flipH = false;
	this.flipV = false;
};

/**
 * Function: isParseVml
 * 
 * Specifies if any VML should be added via insertAdjacentHtml to the DOM. This
 * is only needed in IE8 and only if the shape contains VML markup. This method
 * returns true.
 */
mxShape.prototype.isParseVml = function()
{
	return true;
};

/**
 * Function: isHtmlAllowed
 * 
 * Returns true if HTML is allowed for this shape. This implementation always
 * returns false.
 */
mxShape.prototype.isHtmlAllowed = function()
{
	return false;
};

/**
 * Function: getSvgScreenOffset
 * 
 * Returns 0, or 0.5 if <strokewidth> % 2 == 1.
 */
mxShape.prototype.getSvgScreenOffset = function()
{
	var sw = this.stencil && this.stencil.strokewidth != 'inherit' ? Number(this.stencil.strokewidth) : this.strokewidth;
	
	return (mxUtils.mod(Math.max(1, Math.round(sw * this.scale)), 2) == 1) ? 0.5 : 0;
};

/**
 * Function: create
 *
 * Creates and returns the DOM node(s) for the shape in
 * the given container. This implementation invokes
 * <createSvg>, <createHtml> or <createVml> depending
 * on the <dialect> and style settings.
 *
 * Parameters:
 *
 * container - DOM node that will contain the shape.
 */
mxShape.prototype.create = function(container)
{
	var node = null;
	
	if (container != null && container.ownerSVGElement != null)
	{
		node = this.createSvg(container);
	}
	else if (document.documentMode == 8 || !mxClient.IS_VML ||
		(this.dialect != mxConstants.DIALECT_VML && this.isHtmlAllowed()))
	{
		node = this.createHtml(container);
	}
	else
	{
		node = this.createVml(container);
	}
	
	return node;
};

/**
 * Function: createSvg
 *
 * Creates and returns the SVG node(s) to represent this shape.
 */
mxShape.prototype.createSvg = function()
{
	return document.createElementNS(mxConstants.NS_SVG, 'g');
};

/**
 * Function: createVml
 *
 * Creates and returns the VML node to represent this shape.
 */
mxShape.prototype.createVml = function()
{
	var node = document.createElement(mxClient.VML_PREFIX + ':group');
	node.style.position = 'absolute';
	
	return node;
};

/**
 * Function: createHtml
 *
 * Creates and returns the HTML DOM node(s) to represent
 * this shape. This implementation falls back to <createVml>
 * so that the HTML creation is optional.
 */
mxShape.prototype.createHtml = function()
{
	var node = document.createElement('div');
	node.style.position = 'absolute';
	
	return node;
};

/**
 * Function: reconfigure
 *
 * Reconfigures this shape. This will update the colors etc in
 * addition to the bounds or points.
 */
mxShape.prototype.reconfigure = function()
{
	this.redraw();
};

/**
 * Function: redraw
 *
 * Creates and returns the SVG node(s) to represent this shape.
 */
mxShape.prototype.redraw = function()
{
	this.updateBoundsFromPoints();
	
	if (this.visible && this.checkBounds())
	{
		this.node.style.visibility = 'visible';
		this.clear();
		
		if (this.node.nodeName == 'DIV' && (this.isHtmlAllowed() || !mxClient.IS_VML))
		{
			this.redrawHtmlShape();
		}
		else
		{	
			this.redrawShape();
		}

		this.updateBoundingBox();
	}
	else
	{
		this.node.style.visibility = 'hidden';
		this.boundingBox = null;
	}
};

/**
 * Function: clear
 * 
 * Removes all child nodes and resets all CSS.
 */
mxShape.prototype.clear = function()
{
	if (this.node.ownerSVGElement != null)
	{
		while (this.node.lastChild != null)
		{
			this.node.removeChild(this.node.lastChild);
		}
	}
	else
	{
		this.node.style.cssText = 'position:absolute;' + ((this.cursor != null) ?
			('cursor:' + this.cursor + ';') : '');
		this.node.innerHTML = '';
	}
};

/**
 * Function: updateBoundsFromPoints
 * 
 * Updates the bounds based on the points.
 */
mxShape.prototype.updateBoundsFromPoints = function()
{
	var pts = this.points;
	
	if (pts != null && pts.length > 0 && pts[0] != null)
	{
		this.bounds = new mxRectangle(Number(pts[0].x), Number(pts[0].y), 1, 1);
		
		for (var i = 1; i < this.points.length; i++)
		{
			if (pts[i] != null)
			{
				this.bounds.add(new mxRectangle(Number(pts[i].x), Number(pts[i].y), 1, 1));
			}
		}
	}
};

/**
 * Function: getLabelBounds
 * 
 * Returns the <mxRectangle> for the label bounds of this shape, based on the
 * given scaled and translated bounds of the shape. This method should not
 * change the rectangle in-place. This implementation returns the given rect.
 */
mxShape.prototype.getLabelBounds = function(rect)
{
	var d = mxUtils.getValue(this.style, mxConstants.STYLE_DIRECTION, mxConstants.DIRECTION_EAST);
	var bounds = rect;
	
	// Normalizes argument for getLabelMargins hook
	if (d != mxConstants.DIRECTION_SOUTH && d != mxConstants.DIRECTION_NORTH &&
		this.state != null && this.state.text != null &&
		this.state.text.isPaintBoundsInverted())
	{
		bounds = bounds.clone();
		var tmp = bounds.width;
		bounds.width = bounds.height;
		bounds.height = tmp;
	}
		
	var m = this.getLabelMargins(bounds);
	
	if (m != null)
	{
		var flipH = mxUtils.getValue(this.style, mxConstants.STYLE_FLIPH, false) == '1';
		var flipV = mxUtils.getValue(this.style, mxConstants.STYLE_FLIPV, false) == '1';
		
		// Handles special case for vertical labels
		if (this.state != null && this.state.text != null &&
			this.state.text.isPaintBoundsInverted())
		{
			var tmp = m.x;
			m.x = m.height;
			m.height = m.width;
			m.width = m.y;
			m.y = tmp;

			tmp = flipH;
			flipH = flipV;
			flipV = tmp;
		}
		
		return mxUtils.getDirectedBounds(rect, m, this.style, flipH, flipV);
	}
	
	return rect;
};

/**
 * Function: getLabelMargins
 * 
 * Returns the scaled top, left, bottom and right margin to be used for
 * computing the label bounds as an <mxRectangle>, where the bottom and right
 * margin are defined in the width and height of the rectangle, respectively.
 */
mxShape.prototype.getLabelMargins= function(rect)
{
	return null;
};

/**
 * Function: checkBounds
 * 
 * Returns true if the bounds are not null and all of its variables are numeric.
 */
mxShape.prototype.checkBounds = function()
{
	return (!isNaN(this.scale) && isFinite(this.scale) && this.scale > 0 &&
			this.bounds != null && !isNaN(this.bounds.x) && !isNaN(this.bounds.y) &&
			!isNaN(this.bounds.width) && !isNaN(this.bounds.height) &&
			this.bounds.width > 0 && this.bounds.height > 0);
};

/**
 * Function: createVmlGroup
 *
 * Returns the temporary element used for rendering in IE8 standards mode.
 */
mxShape.prototype.createVmlGroup = function()
{
	var node = document.createElement(mxClient.VML_PREFIX + ':group');
	node.style.position = 'absolute';
	node.style.width = this.node.style.width;
	node.style.height = this.node.style.height;
	
	return node;
};

/**
 * Function: redrawShape
 *
 * Updates the SVG or VML shape.
 */
mxShape.prototype.redrawShape = function()
{
	var canvas = this.createCanvas();
	
	if (canvas != null)
	{
		// Specifies if events should be handled
		canvas.pointerEvents = this.pointerEvents;
	
		this.paint(canvas);
	
		if (this.node != canvas.root)
		{
			// Forces parsing in IE8 standards mode - slow! avoid
			this.node.insertAdjacentHTML('beforeend', canvas.root.outerHTML);
		}
	
		if (this.node.nodeName == 'DIV' && document.documentMode == 8)
		{
			// Makes DIV transparent to events for IE8 in IE8 standards
			// mode (Note: Does not work for IE9 in IE8 standards mode
			// and not for IE11 in enterprise mode)
			this.node.style.filter = '';
			
			// Adds event transparency in IE8 standards
			mxUtils.addTransparentBackgroundFilter(this.node);
		}
		
		this.destroyCanvas(canvas);
	}
};

/**
 * Function: createCanvas
 * 
 * Creates a new canvas for drawing this shape. May return null.
 */
mxShape.prototype.createCanvas = function()
{
	var canvas = null;
	
	// LATER: Check if reusing existing DOM nodes improves performance
	if (this.node.ownerSVGElement != null)
	{
		canvas = this.createSvgCanvas();
	}
	else if (mxClient.IS_VML)
	{
		this.updateVmlContainer();
		canvas = this.createVmlCanvas();
	}
	
	if (canvas != null && this.outline)
	{
		canvas.setStrokeWidth(this.strokewidth);
		canvas.setStrokeColor(this.stroke);
		
		if (this.isDashed != null)
		{
			canvas.setDashed(this.isDashed);
		}
		
		canvas.setStrokeWidth = function() {};
		canvas.setStrokeColor = function() {};
		canvas.setFillColor = function() {};
		canvas.setGradient = function() {};
		canvas.setDashed = function() {};
	}

	return canvas;
};

/**
 * Function: createSvgCanvas
 * 
 * Creates and returns an <mxSvgCanvas2D> for rendering this shape.
 */
mxShape.prototype.createSvgCanvas = function()
{
	var canvas = new mxSvgCanvas2D(this.node, false);
	canvas.strokeTolerance = (this.pointerEvents) ? this.svgStrokeTolerance : 0;
	canvas.pointerEventsValue = this.svgPointerEvents;
	canvas.blockImagePointerEvents = mxClient.IS_FF;
	var off = this.getSvgScreenOffset();

	if (off != 0)
	{
		this.node.setAttribute('transform', 'translate(' + off + ',' + off + ')');
	}
	else
	{
		this.node.removeAttribute('transform');
	}
	
	if (!this.antiAlias)
	{
		// Rounds all numbers in the SVG output to integers
		canvas.format = function(value)
		{
			return Math.round(parseFloat(value));
		};
	}
	
	return canvas;
};

/**
 * Function: createVmlCanvas
 * 
 * Creates and returns an <mxVmlCanvas2D> for rendering this shape.
 */
mxShape.prototype.createVmlCanvas = function()
{
	// Workaround for VML rendering bug in IE8 standards mode
	var node = (document.documentMode == 8 && this.isParseVml()) ? this.createVmlGroup() : this.node;
	var canvas = new mxVmlCanvas2D(node, false);
	
	if (node.tagUrn != '')
	{
		var w = Math.max(1, Math.round(this.bounds.width));
		var h = Math.max(1, Math.round(this.bounds.height));
		node.coordsize = (w * this.vmlScale) + ',' + (h * this.vmlScale);
		canvas.scale(this.vmlScale);
		canvas.vmlScale = this.vmlScale;
	}

	// Painting relative to top, left shape corner
	var s = this.scale;
	canvas.translate(-Math.round(this.bounds.x / s), -Math.round(this.bounds.y / s));
	
	return canvas;
};

/**
 * Function: updateVmlContainer
 * 
 * Updates the bounds of the VML container.
 */
mxShape.prototype.updateVmlContainer = function()
{
	this.node.style.left = Math.round(this.bounds.x) + 'px';
	this.node.style.top = Math.round(this.bounds.y) + 'px';
	var w = Math.max(1, Math.round(this.bounds.width));
	var h = Math.max(1, Math.round(this.bounds.height));
	this.node.style.width = w + 'px';
	this.node.style.height = h + 'px';
	this.node.style.overflow = 'visible';
};

/**
 * Function: redrawHtml
 *
 * Allow optimization by replacing VML with HTML.
 */
mxShape.prototype.redrawHtmlShape = function()
{
	// LATER: Refactor methods
	this.updateHtmlBounds(this.node);
	this.updateHtmlFilters(this.node);
	this.updateHtmlColors(this.node);
};

/**
 * Function: updateHtmlFilters
 *
 * Allow optimization by replacing VML with HTML.
 */
mxShape.prototype.updateHtmlFilters = function(node)
{
	var f = '';
	
	if (this.opacity < 100)
	{
		f += 'alpha(opacity=' + (this.opacity) + ')';
	}
	
	if (this.isShadow)
	{
		// FIXME: Cannot implement shadow transparency with filter
		f += 'progid:DXImageTransform.Microsoft.dropShadow (' +
			'OffX=\'' + Math.round(mxConstants.SHADOW_OFFSET_X * this.scale) + '\', ' +
			'OffY=\'' + Math.round(mxConstants.SHADOW_OFFSET_Y * this.scale) + '\', ' +
			'Color=\'' + mxConstants.VML_SHADOWCOLOR + '\')';
	}
	
	if (this.fill != null && this.fill != mxConstants.NONE && this.gradient && this.gradient != mxConstants.NONE)
	{
		var start = this.fill;
		var end = this.gradient;
		var type = '0';
		
		var lookup = {east:0,south:1,west:2,north:3};
		var dir = (this.direction != null) ? lookup[this.direction] : 0;
		
		if (this.gradientDirection != null)
		{
			dir = mxUtils.mod(dir + lookup[this.gradientDirection] - 1, 4);
		}

		if (dir == 1)
		{
			type = '1';
			var tmp = start;
			start = end;
			end = tmp;
		}
		else if (dir == 2)
		{
			var tmp = start;
			start = end;
			end = tmp;
		}
		else if (dir == 3)
		{
			type = '1';
		}
		
		f += 'progid:DXImageTransform.Microsoft.gradient(' +
			'startColorStr=\'' + start + '\', endColorStr=\'' + end +
			'\', gradientType=\'' + type + '\')';
	}

	node.style.filter = f;
};

/**
 * Function: mixedModeHtml
 *
 * Allow optimization by replacing VML with HTML.
 */
mxShape.prototype.updateHtmlColors = function(node)
{
	var color = this.stroke;
	
	if (color != null && color != mxConstants.NONE)
	{
		node.style.borderColor = color;

		if (this.isDashed)
		{
			node.style.borderStyle = 'dashed';
		}
		else if (this.strokewidth > 0)
		{
			node.style.borderStyle = 'solid';
		}

		node.style.borderWidth = Math.max(1, Math.ceil(this.strokewidth * this.scale)) + 'px';
	}
	else
	{
		node.style.borderWidth = '0px';
	}

	color = (this.outline) ? null : this.fill;
	
	if (color != null && color != mxConstants.NONE)
	{
		node.style.backgroundColor = color;
		node.style.backgroundImage = 'none';
	}
	else if (this.pointerEvents)
	{
		 node.style.backgroundColor = 'transparent';
	}
	else if (document.documentMode == 8)
	{
		mxUtils.addTransparentBackgroundFilter(node);
	}
	else
	{
		this.setTransparentBackgroundImage(node);
	}
};

/**
 * Function: mixedModeHtml
 *
 * Allow optimization by replacing VML with HTML.
 */
mxShape.prototype.updateHtmlBounds = function(node)
{
	var sw = (document.documentMode >= 9) ? 0 : Math.ceil(this.strokewidth * this.scale);
	node.style.borderWidth = Math.max(1, sw) + 'px';
	node.style.overflow = 'hidden';
	
	node.style.left = Math.round(this.bounds.x - sw / 2) + 'px';
	node.style.top = Math.round(this.bounds.y - sw / 2) + 'px';

	if (document.compatMode == 'CSS1Compat')
	{
		sw = -sw;
	}
	
	node.style.width = Math.round(Math.max(0, this.bounds.width + sw)) + 'px';
	node.style.height = Math.round(Math.max(0, this.bounds.height + sw)) + 'px';
};

/**
 * Function: destroyCanvas
 * 
 * Destroys the given canvas which was used for drawing. This implementation
 * increments the reference counts on all shared gradients used in the canvas.
 */
mxShape.prototype.destroyCanvas = function(canvas)
{
	// Manages reference counts
	if (canvas instanceof mxSvgCanvas2D)
	{
		// Increments ref counts
		for (var key in canvas.gradients)
		{
			var gradient = canvas.gradients[key];
			
			if (gradient != null)
			{
				gradient.mxRefCount = (gradient.mxRefCount || 0) + 1;
			}
		}
		
		this.releaseSvgGradients(this.oldGradients);
		this.oldGradients = canvas.gradients;
	}
};

/**
 * Function: paint
 * 
 * Generic rendering code.
 */
mxShape.prototype.paint = function(c)
{
	// Scale is passed-through to canvas
	var s = this.scale;
	var x = this.bounds.x / s;
	var y = this.bounds.y / s;
	var w = this.bounds.width / s;
	var h = this.bounds.height / s;

	if (this.isPaintBoundsInverted())
	{
		var t = (w - h) / 2;
		x += t;
		y -= t;
		var tmp = w;
		w = h;
		h = tmp;
	}
	
	this.updateTransform(c, x, y, w, h);
	this.configureCanvas(c, x, y, w, h);

	// Adds background rectangle to capture events
	var bg = null;
	
	if ((this.stencil == null && this.points == null && this.shapePointerEvents) ||
		(this.stencil != null && this.stencilPointerEvents))
	{
		var bb = this.createBoundingBox();
		
		if (this.dialect == mxConstants.DIALECT_SVG)
		{
			bg = this.createTransparentSvgRectangle(bb.x, bb.y, bb.width, bb.height);
			this.node.appendChild(bg);
		}
		else
		{
			var rect = c.createRect('rect', bb.x / s, bb.y / s, bb.width / s, bb.height / s);
			rect.appendChild(c.createTransparentFill());
			rect.stroked = 'false';
			c.root.appendChild(rect);
		}
	}

	if (this.stencil != null)
	{
		this.stencil.drawShape(c, this, x, y, w, h);
	}
	else
	{
		// Stencils have separate strokewidth
		c.setStrokeWidth(this.strokewidth);
		
		if (this.points != null)
		{
			// Paints edge shape
			var pts = [];
			
			for (var i = 0; i < this.points.length; i++)
			{
				if (this.points[i] != null)
				{
					pts.push(new mxPoint(this.points[i].x / s, this.points[i].y / s));
				}
			}

			this.paintEdgeShape(c, pts);
		}
		else
		{
			// Paints vertex shape
			this.paintVertexShape(c, x, y, w, h);
		}
	}
	
	if (bg != null && c.state != null && c.state.transform != null)
	{
		bg.setAttribute('transform', c.state.transform);
	}
};

/**
 * Function: configureCanvas
 * 
 * Sets the state of the canvas for drawing the shape.
 */
mxShape.prototype.configureCanvas = function(c, x, y, w, h)
{
	var dash = null;
	
	if (this.style != null)
	{
		dash = this.style['dashPattern'];		
	}

	c.setAlpha(this.opacity / 100);
	c.setFillAlpha(this.fillOpacity / 100);
	c.setStrokeAlpha(this.strokeOpacity / 100);

	// Sets alpha, colors and gradients
	if (this.isShadow != null)
	{
		c.setShadow(this.isShadow);
	}
	
	// Dash pattern
	if (this.isDashed != null)
	{
		c.setDashed(this.isDashed, (this.style != null) ?
			mxUtils.getValue(this.style, mxConstants.STYLE_FIX_DASH, false) == 1 : false);
	}

	if (dash != null)
	{
		c.setDashPattern(dash);
	}

	if (this.fill != null && this.fill != mxConstants.NONE && this.gradient && this.gradient != mxConstants.NONE)
	{
		var b = this.getGradientBounds(c, x, y, w, h);
		c.setGradient(this.fill, this.gradient, b.x, b.y, b.width, b.height, this.gradientDirection);
	}
	else
	{
		c.setFillColor(this.fill);
	}

	c.setStrokeColor(this.stroke);
};

/**
 * Function: getGradientBounds
 * 
 * Returns the bounding box for the gradient box for this shape.
 */
mxShape.prototype.getGradientBounds = function(c, x, y, w, h)
{
	return new mxRectangle(x, y, w, h);
};

/**
 * Function: updateTransform
 * 
 * Sets the scale and rotation on the given canvas.
 */
mxShape.prototype.updateTransform = function(c, x, y, w, h)
{
	// NOTE: Currently, scale is implemented in state and canvas. This will
	// move to canvas in a later version, so that the states are unscaled
	// and untranslated and do not need an update after zooming or panning.
	c.scale(this.scale);
	c.rotate(this.getShapeRotation(), this.flipH, this.flipV, x + w / 2, y + h / 2);
};

/**
 * Function: paintVertexShape
 * 
 * Paints the vertex shape.
 */
mxShape.prototype.paintVertexShape = function(c, x, y, w, h)
{
	this.paintBackground(c, x, y, w, h);
	c.setShadow(false);
	this.paintForeground(c, x, y, w, h);
};

/**
 * Function: paintBackground
 * 
 * Hook for subclassers. This implementation is empty.
 */
mxShape.prototype.paintBackground = function(c, x, y, w, h) { };

/**
 * Function: paintForeground
 * 
 * Hook for subclassers. This implementation is empty.
 */
mxShape.prototype.paintForeground = function(c, x, y, w, h) { };

/**
 * Function: paintEdgeShape
 * 
 * Hook for subclassers. This implementation is empty.
 */
mxShape.prototype.paintEdgeShape = function(c, pts) { };

/**
 * Function: getArcSize
 * 
 * Returns the arc size for the given dimension.
 */
mxShape.prototype.getArcSize = function(w, h)
{
	var r = 0;
	
	if (mxUtils.getValue(this.style, mxConstants.STYLE_ABSOLUTE_ARCSIZE, 0) == '1')
	{
		r = Math.min(w / 2, Math.min(h / 2, mxUtils.getValue(this.style,
			mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2));
	}
	else
	{
		var f = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE,
			mxConstants.RECTANGLE_ROUNDING_FACTOR * 100) / 100;
		r = Math.min(w * f, h * f);
	}
	
	return r;
};

/**
 * Function: paintGlassEffect
 * 
 * Paints the glass gradient effect.
 */
mxShape.prototype.paintGlassEffect = function(c, x, y, w, h, arc)
{
	var sw = Math.ceil(this.strokewidth / 2);
	var size = 0.4;
	
	c.setGradient('#ffffff', '#ffffff', x, y, w, h * 0.6, 'south', 0.9, 0.1);
	c.begin();
	arc += 2 * sw;
		
	if (this.isRounded)
	{
		c.moveTo(x - sw + arc, y - sw);
		c.quadTo(x - sw, y - sw, x - sw, y - sw + arc);
		c.lineTo(x - sw, y + h * size);
		c.quadTo(x + w * 0.5, y + h * 0.7, x + w + sw, y + h * size);
		c.lineTo(x + w + sw, y - sw + arc);
		c.quadTo(x + w + sw, y - sw, x + w + sw - arc, y - sw);
	}
	else
	{
		c.moveTo(x - sw, y - sw);
		c.lineTo(x - sw, y + h * size);
		c.quadTo(x + w * 0.5, y + h * 0.7, x + w + sw, y + h * size);
		c.lineTo(x + w + sw, y - sw);
	}
	
	c.close();
	c.fill();
};

/**
 * Function: addPoints
 * 
 * Paints the given points with rounded corners.
 */
mxShape.prototype.addPoints = function(c, pts, rounded, arcSize, close, exclude, initialMove)
{
	if (pts != null && pts.length > 0)
	{
		initialMove = (initialMove != null) ? initialMove : true;
		var pe = pts[pts.length - 1];
		
		// Adds virtual waypoint in the center between start and end point
		if (close && rounded)
		{
			pts = pts.slice();
			var p0 = pts[0];
			var wp = new mxPoint(pe.x + (p0.x - pe.x) / 2, pe.y + (p0.y - pe.y) / 2);
			pts.splice(0, 0, wp);
		}
	
		var pt = pts[0];
		var i = 1;
	
		// Draws the line segments
		if (initialMove)
		{
			c.moveTo(pt.x, pt.y);
		}
		else
		{
			c.lineTo(pt.x, pt.y);
		}
		
		while (i < ((close) ? pts.length : pts.length - 1))
		{
			var tmp = pts[mxUtils.mod(i, pts.length)];
			var dx = pt.x - tmp.x;
			var dy = pt.y - tmp.y;
	
			if (rounded && (dx != 0 || dy != 0) && (exclude == null || mxUtils.indexOf(exclude, i - 1) < 0))
			{
				// Draws a line from the last point to the current
				// point with a spacing of size off the current point
				// into direction of the last point
				var dist = Math.sqrt(dx * dx + dy * dy);
				var nx1 = dx * Math.min(arcSize, dist / 2) / dist;
				var ny1 = dy * Math.min(arcSize, dist / 2) / dist;
	
				var x1 = tmp.x + nx1;
				var y1 = tmp.y + ny1;
				c.lineTo(x1, y1);
	
				// Draws a curve from the last point to the current
				// point with a spacing of size off the current point
				// into direction of the next point
				var next = pts[mxUtils.mod(i + 1, pts.length)];
				
				// Uses next non-overlapping point
				while (i < pts.length - 2 && Math.round(next.x - tmp.x) == 0 && Math.round(next.y - tmp.y) == 0)
				{
					next = pts[mxUtils.mod(i + 2, pts.length)];
					i++;
				}
				
				dx = next.x - tmp.x;
				dy = next.y - tmp.y;
	
				dist = Math.max(1, Math.sqrt(dx * dx + dy * dy));
				var nx2 = dx * Math.min(arcSize, dist / 2) / dist;
				var ny2 = dy * Math.min(arcSize, dist / 2) / dist;
	
				var x2 = tmp.x + nx2;
				var y2 = tmp.y + ny2;
	
				c.quadTo(tmp.x, tmp.y, x2, y2);
				tmp = new mxPoint(x2, y2);
			}
			else
			{
				c.lineTo(tmp.x, tmp.y);
			}
	
			pt = tmp;
			i++;
		}
	
		if (close)
		{
			c.close();
		}
		else
		{
			c.lineTo(pe.x, pe.y);
		}
	}
};

/**
 * Function: resetStyles
 * 
 * Resets all styles.
 */
mxShape.prototype.resetStyles = function()
{
	this.initStyles();

	this.spacing = 0;
	
	delete this.fill;
	delete this.gradient;
	delete this.gradientDirection;
	delete this.stroke;
	delete this.startSize;
	delete this.endSize;
	delete this.startArrow;
	delete this.endArrow;
	delete this.direction;
	delete this.isShadow;
	delete this.isDashed;
	delete this.isRounded;
	delete this.glass;
};

/**
 * Function: apply
 * 
 * Applies the style of the given <mxCellState> to the shape. This
 * implementation assigns the following styles to local fields:
 * 
 * - <mxConstants.STYLE_FILLCOLOR> => fill
 * - <mxConstants.STYLE_GRADIENTCOLOR> => gradient
 * - <mxConstants.STYLE_GRADIENT_DIRECTION> => gradientDirection
 * - <mxConstants.STYLE_OPACITY> => opacity
 * - <mxConstants.STYLE_FILL_OPACITY> => fillOpacity
 * - <mxConstants.STYLE_STROKE_OPACITY> => strokeOpacity
 * - <mxConstants.STYLE_STROKECOLOR> => stroke
 * - <mxConstants.STYLE_STROKEWIDTH> => strokewidth
 * - <mxConstants.STYLE_SHADOW> => isShadow
 * - <mxConstants.STYLE_DASHED> => isDashed
 * - <mxConstants.STYLE_SPACING> => spacing
 * - <mxConstants.STYLE_STARTSIZE> => startSize
 * - <mxConstants.STYLE_ENDSIZE> => endSize
 * - <mxConstants.STYLE_ROUNDED> => isRounded
 * - <mxConstants.STYLE_STARTARROW> => startArrow
 * - <mxConstants.STYLE_ENDARROW> => endArrow
 * - <mxConstants.STYLE_ROTATION> => rotation
 * - <mxConstants.STYLE_DIRECTION> => direction
 * - <mxConstants.STYLE_GLASS> => glass
 *
 * This keeps a reference to the <style>. If you need to keep a reference to
 * the cell, you can override this method and store a local reference to
 * state.cell or the <mxCellState> itself. If <outline> should be true, make
 * sure to set it before calling this method.
 *
 * Parameters:
 *
 * state - <mxCellState> of the corresponding cell.
 */
mxShape.prototype.apply = function(state)
{
	this.state = state;
	this.style = state.style;

	if (this.style != null)
	{
		this.fill = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, this.fill);
		this.gradient = mxUtils.getValue(this.style, mxConstants.STYLE_GRADIENTCOLOR, this.gradient);
		this.gradientDirection = mxUtils.getValue(this.style, mxConstants.STYLE_GRADIENT_DIRECTION, this.gradientDirection);
		this.opacity = mxUtils.getValue(this.style, mxConstants.STYLE_OPACITY, this.opacity);
		this.fillOpacity = mxUtils.getValue(this.style, mxConstants.STYLE_FILL_OPACITY, this.fillOpacity);
		this.strokeOpacity = mxUtils.getValue(this.style, mxConstants.STYLE_STROKE_OPACITY, this.strokeOpacity);
		this.stroke = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, this.stroke);
		this.strokewidth = mxUtils.getNumber(this.style, mxConstants.STYLE_STROKEWIDTH, this.strokewidth);
		this.spacing = mxUtils.getValue(this.style, mxConstants.STYLE_SPACING, this.spacing);
		this.startSize = mxUtils.getNumber(this.style, mxConstants.STYLE_STARTSIZE, this.startSize);
		this.endSize = mxUtils.getNumber(this.style, mxConstants.STYLE_ENDSIZE, this.endSize);
		this.startArrow = mxUtils.getValue(this.style, mxConstants.STYLE_STARTARROW, this.startArrow);
		this.endArrow = mxUtils.getValue(this.style, mxConstants.STYLE_ENDARROW, this.endArrow);
		this.rotation = mxUtils.getValue(this.style, mxConstants.STYLE_ROTATION, this.rotation);
		this.direction = mxUtils.getValue(this.style, mxConstants.STYLE_DIRECTION, this.direction);
		this.flipH = mxUtils.getValue(this.style, mxConstants.STYLE_FLIPH, 0) == 1;
		this.flipV = mxUtils.getValue(this.style, mxConstants.STYLE_FLIPV, 0) == 1;	
		
		// Legacy support for stencilFlipH/V
		if (this.stencil != null)
		{
			this.flipH = mxUtils.getValue(this.style, 'stencilFlipH', 0) == 1 || this.flipH;
			this.flipV = mxUtils.getValue(this.style, 'stencilFlipV', 0) == 1 || this.flipV;
		}
		
		if (this.direction == mxConstants.DIRECTION_NORTH || this.direction == mxConstants.DIRECTION_SOUTH)
		{
			var tmp = this.flipH;
			this.flipH = this.flipV;
			this.flipV = tmp;
		}

		this.isShadow = mxUtils.getValue(this.style, mxConstants.STYLE_SHADOW, this.isShadow) == 1;
		this.isDashed = mxUtils.getValue(this.style, mxConstants.STYLE_DASHED, this.isDashed) == 1;
		this.isRounded = mxUtils.getValue(this.style, mxConstants.STYLE_ROUNDED, this.isRounded) == 1;
		this.glass = mxUtils.getValue(this.style, mxConstants.STYLE_GLASS, this.glass) == 1;
		
		if (this.fill == mxConstants.NONE)
		{
			this.fill = null;
		}

		if (this.gradient == mxConstants.NONE)
		{
			this.gradient = null;
		}

		if (this.stroke == mxConstants.NONE)
		{
			this.stroke = null;
		}
	}
};

/**
 * Function: setCursor
 * 
 * Sets the cursor on the given shape.
 *
 * Parameters:
 *
 * cursor - The cursor to be used.
 */
mxShape.prototype.setCursor = function(cursor)
{
	if (cursor == null)
	{
		cursor = '';
	}
	
	this.cursor = cursor;

	if (this.node != null)
	{
		this.node.style.cursor = cursor;
	}
};

/**
 * Function: getCursor
 * 
 * Returns the current cursor.
 */
mxShape.prototype.getCursor = function()
{
	return this.cursor;
};

/**
 * Function: updateBoundingBox
 *
 * Updates the <boundingBox> for this shape using <createBoundingBox> and
 * <augmentBoundingBox> and stores the result in <boundingBox>.
 */
mxShape.prototype.updateBoundingBox = function()
{
	// Tries to get bounding box from SVG subsystem
	// LATER: Use getBoundingClientRect for fallback in VML
	if (this.useSvgBoundingBox && this.node != null && this.node.ownerSVGElement != null)
	{
		try
		{
			var b = this.node.getBBox();
	
			if (b.width > 0 && b.height > 0)
			{
				this.boundingBox = new mxRectangle(b.x, b.y, b.width, b.height);
				
				// Adds strokeWidth
				this.boundingBox.grow(this.strokewidth * this.scale / 2);
				
				return;
			}
		}
		catch(e)
		{
			// fallback to code below
		}
	}

	if (this.bounds != null)
	{
		var bbox = this.createBoundingBox();
		
		if (bbox != null)
		{
			this.augmentBoundingBox(bbox);
			var rot = this.getShapeRotation();
			
			if (rot != 0)
			{
				bbox = mxUtils.getBoundingBox(bbox, rot);
			}
		}

		this.boundingBox = bbox;
	}
};

/**
 * Function: createBoundingBox
 *
 * Returns a new rectangle that represents the bounding box of the bare shape
 * with no shadows or strokewidths.
 */
mxShape.prototype.createBoundingBox = function()
{
	var bb = this.bounds.clone();

	if ((this.stencil != null && (this.direction == mxConstants.DIRECTION_NORTH ||
		this.direction == mxConstants.DIRECTION_SOUTH)) || this.isPaintBoundsInverted())
	{
		bb.rotate90();
	}
	
	return bb;
};

/**
 * Function: augmentBoundingBox
 *
 * Augments the bounding box with the strokewidth and shadow offsets.
 */
mxShape.prototype.augmentBoundingBox = function(bbox)
{
	if (this.isShadow)
	{
		bbox.width += Math.ceil(mxConstants.SHADOW_OFFSET_X * this.scale);
		bbox.height += Math.ceil(mxConstants.SHADOW_OFFSET_Y * this.scale);
	}
	
	// Adds strokeWidth
	bbox.grow(this.strokewidth * this.scale / 2);
};

/**
 * Function: isPaintBoundsInverted
 * 
 * Returns true if the bounds should be inverted.
 */
mxShape.prototype.isPaintBoundsInverted = function()
{
	// Stencil implements inversion via aspect
	return this.stencil == null && (this.direction == mxConstants.DIRECTION_NORTH ||
			this.direction == mxConstants.DIRECTION_SOUTH);
};

/**
 * Function: getRotation
 * 
 * Returns the rotation from the style.
 */
mxShape.prototype.getRotation = function()
{
	return (this.rotation != null) ? this.rotation : 0;
};

/**
 * Function: getTextRotation
 * 
 * Returns the rotation for the text label.
 */
mxShape.prototype.getTextRotation = function()
{
	var rot = this.getRotation();
	
	if (mxUtils.getValue(this.style, mxConstants.STYLE_HORIZONTAL, 1) != 1)
	{
		rot += mxText.prototype.verticalTextRotation;
	}
	
	return rot;
};

/**
 * Function: getShapeRotation
 * 
 * Returns the actual rotation of the shape.
 */
mxShape.prototype.getShapeRotation = function()
{
	var rot = this.getRotation();
	
	if (this.direction != null)
	{
		if (this.direction == mxConstants.DIRECTION_NORTH)
		{
			rot += 270;
		}
		else if (this.direction == mxConstants.DIRECTION_WEST)
		{
			rot += 180;
		}
		else if (this.direction == mxConstants.DIRECTION_SOUTH)
		{
			rot += 90;
		}
	}
	
	return rot;
};

/**
 * Function: createTransparentSvgRectangle
 * 
 * Adds a transparent rectangle that catches all events.
 */
mxShape.prototype.createTransparentSvgRectangle = function(x, y, w, h)
{
	var rect = document.createElementNS(mxConstants.NS_SVG, 'rect');
	rect.setAttribute('x', x);
	rect.setAttribute('y', y);
	rect.setAttribute('width', w);
	rect.setAttribute('height', h);
	rect.setAttribute('fill', 'none');
	rect.setAttribute('stroke', 'none');
	rect.setAttribute('pointer-events', 'all');
	
	return rect;
};

/**
 * Function: setTransparentBackgroundImage
 * 
 * Sets a transparent background CSS style to catch all events.
 * 
 * Paints the line shape.
 */
mxShape.prototype.setTransparentBackgroundImage = function(node)
{
	node.style.backgroundImage = 'url(\'' + mxClient.imageBasePath + '/transparent.gif\')';
};

/**
 * Function: releaseSvgGradients
 * 
 * Paints the line shape.
 */
mxShape.prototype.releaseSvgGradients = function(grads)
{
	if (grads != null)
	{
		for (var key in grads)
		{
			var gradient = grads[key];
			
			if (gradient != null)
			{
				gradient.mxRefCount = (gradient.mxRefCount || 0) - 1;
				
				if (gradient.mxRefCount == 0 && gradient.parentNode != null)
				{
					gradient.parentNode.removeChild(gradient);
				}
			}
		}
	}
};

/**
 * Function: destroy
 *
 * Destroys the shape by removing it from the DOM and releasing the DOM
 * node associated with the shape using <mxEvent.release>.
 */
mxShape.prototype.destroy = function()
{
	if (this.node != null)
	{
		mxEvent.release(this.node);
		
		if (this.node.parentNode != null)
		{
			this.node.parentNode.removeChild(this.node);
		}
		
		this.node = null;
	}
	
	// Decrements refCount and removes unused
	this.releaseSvgGradients(this.oldGradients);
	this.oldGradients = null;
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 * 
 * Code to add stencils.
 * 
 * (code)
 * var req = mxUtils.load('test/stencils.xml');
 * var root = req.getDocumentElement();
 * var shape = root.firstChild;
 * 
 * while (shape != null)
 * {
 * 	 if (shape.nodeType == mxConstants.NODETYPE_ELEMENT)
 *   {
 *     mxStencilRegistry.addStencil(shape.getAttribute('name'), new mxStencil(shape));
 *   }
 *   
 *   shape = shape.nextSibling;
 * }
 * (end)
 */
var mxStencilRegistry =
{
	/**
	 * Class: mxStencilRegistry
	 * 
	 * A singleton class that provides a registry for stencils and the methods
	 * for painting those stencils onto a canvas or into a DOM.
	 */
	stencils: {},
	
	/**
	 * Function: addStencil
	 * 
	 * Adds the given <mxStencil>.
	 */
	addStencil: function(name, stencil)
	{
		mxStencilRegistry.stencils[name] = stencil;
	},
	
	/**
	 * Function: getStencil
	 * 
	 * Returns the <mxStencil> for the given name.
	 */
	getStencil: function(name)
	{
		return mxStencilRegistry.stencils[name];
	}

};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
var mxMarker =
{
	/**
	 * Class: mxMarker
	 * 
	 * A static class that implements all markers for VML and SVG using a
	 * registry. NOTE: The signatures in this class will change.
	 * 
	 * Variable: markers
	 * 
	 * Maps from markers names to functions to paint the markers.
	 */
	markers: [],
	
	/**
	 * Function: addMarker
	 * 
	 * Adds a factory method that updates a given endpoint and returns a
	 * function to paint the marker onto the given canvas.
	 */
	addMarker: function(type, funct)
	{
		mxMarker.markers[type] = funct;
	},
	
	/**
	 * Function: createMarker
	 * 
	 * Returns a function to paint the given marker.
	 */
	createMarker: function(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled)
	{
		var funct = mxMarker.markers[type];
		
		return (funct != null) ? funct(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled) : null;
	}

};

/**
 * Adds the classic and block marker factory method.
 */
(function()
{
	function createArrow(widthFactor)
	{
		widthFactor = (widthFactor != null) ? widthFactor : 2;
		
		return function(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled)
		{
			// The angle of the forward facing arrow sides against the x axis is
			// 26.565 degrees, 1/sin(26.565) = 2.236 / 2 = 1.118 ( / 2 allows for
			// only half the strokewidth is processed ).
			var endOffsetX = unitX * sw * 1.118;
			var endOffsetY = unitY * sw * 1.118;
			
			unitX = unitX * (size + sw);
			unitY = unitY * (size + sw);
	
			var pt = pe.clone();
			pt.x -= endOffsetX;
			pt.y -= endOffsetY;
			
			var f = (type != mxConstants.ARROW_CLASSIC && type != mxConstants.ARROW_CLASSIC_THIN) ? 1 : 3 / 4;
			pe.x += -unitX * f - endOffsetX;
			pe.y += -unitY * f - endOffsetY;
			
			return function()
			{
				canvas.begin();
				canvas.moveTo(pt.x, pt.y);
				canvas.lineTo(pt.x - unitX - unitY / widthFactor, pt.y - unitY + unitX / widthFactor);
			
				if (type == mxConstants.ARROW_CLASSIC || type == mxConstants.ARROW_CLASSIC_THIN)
				{
					canvas.lineTo(pt.x - unitX * 3 / 4, pt.y - unitY * 3 / 4);
				}
			
				canvas.lineTo(pt.x + unitY / widthFactor - unitX, pt.y - unitY - unitX / widthFactor);
				canvas.close();
	
				if (filled)
				{
					canvas.fillAndStroke();
				}
				else
				{
					canvas.stroke();
				}
			};
		}
	};
	
	mxMarker.addMarker('classic', createArrow(2));
	mxMarker.addMarker('classicThin', createArrow(3));
	mxMarker.addMarker('block', createArrow(2));
	mxMarker.addMarker('blockThin', createArrow(3));
	
	function createOpenArrow(widthFactor)
	{
		widthFactor = (widthFactor != null) ? widthFactor : 2;
		
		return function(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled)
		{
			// The angle of the forward facing arrow sides against the x axis is
			// 26.565 degrees, 1/sin(26.565) = 2.236 / 2 = 1.118 ( / 2 allows for
			// only half the strokewidth is processed ).
			var endOffsetX = unitX * sw * 1.118;
			var endOffsetY = unitY * sw * 1.118;
			
			unitX = unitX * (size + sw);
			unitY = unitY * (size + sw);
			
			var pt = pe.clone();
			pt.x -= endOffsetX;
			pt.y -= endOffsetY;
			
			pe.x += -endOffsetX * 2;
			pe.y += -endOffsetY * 2;

			return function()
			{
				canvas.begin();
				canvas.moveTo(pt.x - unitX - unitY / widthFactor, pt.y - unitY + unitX / widthFactor);
				canvas.lineTo(pt.x, pt.y);
				canvas.lineTo(pt.x + unitY / widthFactor - unitX, pt.y - unitY - unitX / widthFactor);
				canvas.stroke();
			};
		}
	};
	
	mxMarker.addMarker('open', createOpenArrow(2));
	mxMarker.addMarker('openThin', createOpenArrow(3));
	
	mxMarker.addMarker('oval', function(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled)
	{
		var a = size / 2;
		
		var pt = pe.clone();
		pe.x -= unitX * a;
		pe.y -= unitY * a;

		return function()
		{
			canvas.ellipse(pt.x - a, pt.y - a, size, size);
						
			if (filled)
			{
				canvas.fillAndStroke();
			}
			else
			{
				canvas.stroke();
			}
		};
	});

	function diamond(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled)
	{
		// The angle of the forward facing arrow sides against the x axis is
		// 45 degrees, 1/sin(45) = 1.4142 / 2 = 0.7071 ( / 2 allows for
		// only half the strokewidth is processed ). Or 0.9862 for thin diamond.
		// Note these values and the tk variable below are dependent, update
		// both together (saves trig hard coding it).
		var swFactor = (type == mxConstants.ARROW_DIAMOND) ?  0.7071 : 0.9862;
		var endOffsetX = unitX * sw * swFactor;
		var endOffsetY = unitY * sw * swFactor;
		
		unitX = unitX * (size + sw);
		unitY = unitY * (size + sw);
		
		var pt = pe.clone();
		pt.x -= endOffsetX;
		pt.y -= endOffsetY;
		
		pe.x += -unitX - endOffsetX;
		pe.y += -unitY - endOffsetY;
		
		// thickness factor for diamond
		var tk = ((type == mxConstants.ARROW_DIAMOND) ?  2 : 3.4);
		
		return function()
		{
			canvas.begin();
			canvas.moveTo(pt.x, pt.y);
			canvas.lineTo(pt.x - unitX / 2 - unitY / tk, pt.y + unitX / tk - unitY / 2);
			canvas.lineTo(pt.x - unitX, pt.y - unitY);
			canvas.lineTo(pt.x - unitX / 2 + unitY / tk, pt.y - unitY / 2 - unitX / tk);
			canvas.close();
			
			if (filled)
			{
				canvas.fillAndStroke();
			}
			else
			{
				canvas.stroke();
			}
		};
	};

	mxMarker.addMarker('diamond', diamond);
	mxMarker.addMarker('diamondThin', diamond);
})();
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxActor
 *
 * Extends <mxShape> to implement an actor shape. If a custom shape with one
 * filled area is needed, then this shape's <redrawPath> should be overridden.
 * 
 * Example:
 * 
 * (code)
 * function SampleShape() { }
 * 
 * SampleShape.prototype = new mxActor();
 * SampleShape.prototype.constructor = vsAseShape;
 * 
 * mxCellRenderer.prototype.defaultShapes['sample'] = SampleShape;
 * SampleShape.prototype.redrawPath = function(path, x, y, w, h)
 * {
 *   path.moveTo(0, 0);
 *   path.lineTo(w, h);
 *   // ...
 *   path.close();
 * }
 * (end)
 * 
 * This shape is registered under <mxConstants.SHAPE_ACTOR> in
 * <mxCellRenderer>.
 * 
 * Constructor: mxActor
 *
 * Constructs a new actor shape.
 * 
 * Parameters:
 * 
 * bounds - <mxRectangle> that defines the bounds. This is stored in
 * <mxShape.bounds>.
 * fill - String that defines the fill color. This is stored in <fill>.
 * stroke - String that defines the stroke color. This is stored in <stroke>.
 * strokewidth - Optional integer that defines the stroke width. Default is
 * 1. This is stored in <strokewidth>.
 */
function mxActor(bounds, fill, stroke, strokewidth)
{
	mxShape.call(this);
	this.bounds = bounds;
	this.fill = fill;
	this.stroke = stroke;
	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
};

/**
 * Extends mxShape.
 */
mxUtils.extend(mxActor, mxShape);

/**
 * Function: paintVertexShape
 * 
 * Redirects to redrawPath for subclasses to work.
 */
mxActor.prototype.paintVertexShape = function(c, x, y, w, h)
{
	c.translate(x, y);
	c.begin();
	this.redrawPath(c, x, y, w, h);
	c.fillAndStroke();
};

/**
 * Function: redrawPath
 *
 * Draws the path for this shape.
 */
mxActor.prototype.redrawPath = function(c, x, y, w, h)
{
	var width = w/3;
	c.moveTo(0, h);
	c.curveTo(0, 3 * h / 5, 0, 2 * h / 5, w / 2, 2 * h / 5);
	c.curveTo(w / 2 - width, 2 * h / 5, w / 2 - width, 0, w / 2, 0);
	c.curveTo(w / 2 + width, 0, w / 2 + width, 2 * h / 5, w / 2, 2 * h / 5);
	c.curveTo(w, 2 * h / 5, w, 3 * h / 5, w, h);
	c.close();
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxCloud
 *
 * Extends <mxActor> to implement a cloud shape.
 * 
 * This shape is registered under <mxConstants.SHAPE_CLOUD> in
 * <mxCellRenderer>.
 * 
 * Constructor: mxCloud
 *
 * Constructs a new cloud shape.
 * 
 * Parameters:
 * 
 * bounds - <mxRectangle> that defines the bounds. This is stored in
 * <mxShape.bounds>.
 * fill - String that defines the fill color. This is stored in <fill>.
 * stroke - String that defines the stroke color. This is stored in <stroke>.
 * strokewidth - Optional integer that defines the stroke width. Default is
 * 1. This is stored in <strokewidth>.
 */
function mxCloud(bounds, fill, stroke, strokewidth)
{
	mxActor.call(this);
	this.bounds = bounds;
	this.fill = fill;
	this.stroke = stroke;
	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
};

/**
 * Extends mxActor.
 */
mxUtils.extend(mxCloud, mxActor);

/**
 * Function: redrawPath
 *
 * Draws the path for this shape.
 */
mxCloud.prototype.redrawPath = function(c, x, y, w, h)
{
	c.moveTo(0.25 * w, 0.25 * h);
	c.curveTo(0.05 * w, 0.25 * h, 0, 0.5 * h, 0.16 * w, 0.55 * h);
	c.curveTo(0, 0.66 * h, 0.18 * w, 0.9 * h, 0.31 * w, 0.8 * h);
	c.curveTo(0.4 * w, h, 0.7 * w, h, 0.8 * w, 0.8 * h);
	c.curveTo(w, 0.8 * h, w, 0.6 * h, 0.875 * w, 0.5 * h);
	c.curveTo(w, 0.3 * h, 0.8 * w, 0.1 * h, 0.625 * w, 0.2 * h);
	c.curveTo(0.5 * w, 0.05 * h, 0.3 * w, 0.05 * h, 0.25 * w, 0.25 * h);
	c.close();
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxRectangleShape
 *
 * Extends <mxShape> to implement a rectangle shape.
 * This shape is registered under <mxConstants.SHAPE_RECTANGLE>
 * in <mxCellRenderer>.
 * 
 * Constructor: mxRectangleShape
 *
 * Constructs a new rectangle shape.
 * 
 * Parameters:
 * 
 * bounds - <mxRectangle> that defines the bounds. This is stored in
 * <mxShape.bounds>.
 * fill - String that defines the fill color. This is stored in <fill>.
 * stroke - String that defines the stroke color. This is stored in <stroke>.
 * strokewidth - Optional integer that defines the stroke width. Default is
 * 1. This is stored in <strokewidth>.
 */
function mxRectangleShape(bounds, fill, stroke, strokewidth)
{
	mxShape.call(this);
	this.bounds = bounds;
	this.fill = fill;
	this.stroke = stroke;
	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
};

/**
 * Extends mxShape.
 */
mxUtils.extend(mxRectangleShape, mxShape);

/**
 * Function: isHtmlAllowed
 *
 * Returns true for non-rounded, non-rotated shapes with no glass gradient.
 */
mxRectangleShape.prototype.isHtmlAllowed = function()
{
	var events = true;
	
	if (this.style != null)
	{
		events = mxUtils.getValue(this.style, mxConstants.STYLE_POINTER_EVENTS, '1') == '1';		
	}
	
	return !this.isRounded && !this.glass && this.rotation == 0 && (events ||
		(this.fill != null && this.fill != mxConstants.NONE));
};

/**
 * Function: paintBackground
 * 
 * Generic background painting implementation.
 */
mxRectangleShape.prototype.paintBackground = function(c, x, y, w, h)
{
	var events = true;
	
	if (this.style != null)
	{
		events = mxUtils.getValue(this.style, mxConstants.STYLE_POINTER_EVENTS, '1') == '1';		
	}
	
	if (events || (this.fill != null && this.fill != mxConstants.NONE) ||
		(this.stroke != null && this.stroke != mxConstants.NONE))
	{
		if (!events && (this.fill == null || this.fill == mxConstants.NONE))
		{
			c.pointerEvents = false;
		}
		
		if (this.isRounded)
		{
			var r = 0;
			
			if (mxUtils.getValue(this.style, mxConstants.STYLE_ABSOLUTE_ARCSIZE, 0) == '1')
			{
				r = Math.min(w / 2, Math.min(h / 2, mxUtils.getValue(this.style,
					mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2));
			}
			else
			{
				var f = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE,
					mxConstants.RECTANGLE_ROUNDING_FACTOR * 100) / 100;
				r = Math.min(w * f, h * f);
			}
			
			c.roundrect(x, y, w, h, r, r);
		}
		else
		{
			c.rect(x, y, w, h);
		}
			
		c.fillAndStroke();
	}
};

/**
 * Function: paintForeground
 * 
 * Generic background painting implementation.
 */
mxRectangleShape.prototype.paintForeground = function(c, x, y, w, h)
{
	if (this.glass && !this.outline && this.fill != null && this.fill != mxConstants.NONE)
	{
		this.paintGlassEffect(c, x, y, w, h, this.getArcSize(w + this.strokewidth, h + this.strokewidth));
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxEllipse
 *
 * Extends <mxShape> to implement an ellipse shape.
 * This shape is registered under <mxConstants.SHAPE_ELLIPSE>
 * in <mxCellRenderer>.
 * 
 * Constructor: mxEllipse
 *
 * Constructs a new ellipse shape.
 * 
 * Parameters:
 * 
 * bounds - <mxRectangle> that defines the bounds. This is stored in
 * <mxShape.bounds>.
 * fill - String that defines the fill color. This is stored in <fill>.
 * stroke - String that defines the stroke color. This is stored in <stroke>.
 * strokewidth - Optional integer that defines the stroke width. Default is
 * 1. This is stored in <strokewidth>.
 */
function mxEllipse(bounds, fill, stroke, strokewidth)
{
	mxShape.call(this);
	this.bounds = bounds;
	this.fill = fill;
	this.stroke = stroke;
	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
};

/**
 * Extends mxShape.
 */
mxUtils.extend(mxEllipse, mxShape);

/**
 * Function: paintVertexShape
 * 
 * Paints the ellipse shape.
 */
mxEllipse.prototype.paintVertexShape = function(c, x, y, w, h)
{
	c.ellipse(x, y, w, h);
	c.fillAndStroke();
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxDoubleEllipse
 *
 * Extends <mxShape> to implement a double ellipse shape. This shape is
 * registered under <mxConstants.SHAPE_DOUBLE_ELLIPSE> in <mxCellRenderer>.
 * Use the following override to only fill the inner ellipse in this shape:
 * 
 * (code)
 * mxDoubleEllipse.prototype.paintVertexShape = function(c, x, y, w, h)
 * {
 *   c.ellipse(x, y, w, h);
 *   c.stroke();
 *   
 *   var inset = mxUtils.getValue(this.style, mxConstants.STYLE_MARGIN, Math.min(3 + this.strokewidth, Math.min(w / 5, h / 5)));
 *   x += inset;
 *   y += inset;
 *   w -= 2 * inset;
 *   h -= 2 * inset;
 *   
 *   if (w > 0 && h > 0)
 *   {
 *     c.ellipse(x, y, w, h);
 *   }
 *   
 *   c.fillAndStroke();
 * };
 * (end)
 * 
 * Constructor: mxDoubleEllipse
 *
 * Constructs a new ellipse shape.
 *
 * Parameters:
 *
 * bounds - <mxRectangle> that defines the bounds. This is stored in
 * <mxShape.bounds>.
 * fill - String that defines the fill color. This is stored in <fill>.
 * stroke - String that defines the stroke color. This is stored in <stroke>.
 * strokewidth - Optional integer that defines the stroke width. Default is
 * 1. This is stored in <strokewidth>.
 */
function mxDoubleEllipse(bounds, fill, stroke, strokewidth)
{
	mxShape.call(this);
	this.bounds = bounds;
	this.fill = fill;
	this.stroke = stroke;
	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
};

/**
 * Extends mxShape.
 */
mxUtils.extend(mxDoubleEllipse, mxShape);

/**
 * Variable: vmlScale
 * 
 * Scale for improving the precision of VML rendering. Default is 10.
 */
mxDoubleEllipse.prototype.vmlScale = 10;

/**
 * Function: paintBackground
 * 
 * Paints the background.
 */
mxDoubleEllipse.prototype.paintBackground = function(c, x, y, w, h)
{
	c.ellipse(x, y, w, h);
	c.fillAndStroke();
};

/**
 * Function: paintForeground
 * 
 * Paints the foreground.
 */
mxDoubleEllipse.prototype.paintForeground = function(c, x, y, w, h)
{
	if (!this.outline)
	{
		var margin = mxUtils.getValue(this.style, mxConstants.STYLE_MARGIN, Math.min(3 + this.strokewidth, Math.min(w / 5, h / 5)));
		x += margin;
		y += margin;
		w -= 2 * margin;
		h -= 2 * margin;
		
		// FIXME: Rounding issues in IE8 standards mode (not in 1.x)
		if (w > 0 && h > 0)
		{
			c.ellipse(x, y, w, h);
		}
		
		c.stroke();
	}
};

/**
 * Function: getLabelBounds
 * 
 * Returns the bounds for the label.
 */
mxDoubleEllipse.prototype.getLabelBounds = function(rect)
{
	var margin = (mxUtils.getValue(this.style, mxConstants.STYLE_MARGIN, Math.min(3 + this.strokewidth,
			Math.min(rect.width / 5 / this.scale, rect.height / 5 / this.scale)))) * this.scale;

	return new mxRectangle(rect.x + margin, rect.y + margin, rect.width - 2 * margin, rect.height - 2 * margin);
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxRhombus
 *
 * Extends <mxShape> to implement a rhombus (aka diamond) shape.
 * This shape is registered under <mxConstants.SHAPE_RHOMBUS>
 * in <mxCellRenderer>.
 * 
 * Constructor: mxRhombus
 *
 * Constructs a new rhombus shape.
 * 
 * Parameters:
 * 
 * bounds - <mxRectangle> that defines the bounds. This is stored in
 * <mxShape.bounds>.
 * fill - String that defines the fill color. This is stored in <fill>.
 * stroke - String that defines the stroke color. This is stored in <stroke>.
 * strokewidth - Optional integer that defines the stroke width. Default is
 * 1. This is stored in <strokewidth>.
 */
function mxRhombus(bounds, fill, stroke, strokewidth)
{
	mxShape.call(this);
	this.bounds = bounds;
	this.fill = fill;
	this.stroke = stroke;
	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
};

/**
 * Extends mxShape.
 */
mxUtils.extend(mxRhombus, mxShape);

/**
 * Function: paintVertexShape
 * 
 * Generic painting implementation.
 */
mxRhombus.prototype.paintVertexShape = function(c, x, y, w, h)
{
	var hw = w / 2;
	var hh = h / 2;
	
	var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
	c.begin();
	this.addPoints(c, [new mxPoint(x + hw, y), new mxPoint(x + w, y + hh), new mxPoint(x + hw, y + h),
	     new mxPoint(x, y + hh)], this.isRounded, arcSize, true);
	c.fillAndStroke();
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxPolyline
 *
 * Extends <mxShape> to implement a polyline (a line with multiple points).
 * This shape is registered under <mxConstants.SHAPE_POLYLINE> in
 * <mxCellRenderer>.
 * 
 * Constructor: mxPolyline
 *
 * Constructs a new polyline shape.
 * 
 * Parameters:
 * 
 * points - Array of <mxPoints> that define the points. This is stored in
 * <mxShape.points>.
 * stroke - String that defines the stroke color. Default is 'black'. This is
 * stored in <stroke>.
 * strokewidth - Optional integer that defines the stroke width. Default is
 * 1. This is stored in <strokewidth>.
 */
function mxPolyline(points, stroke, strokewidth)
{
	mxShape.call(this);
	this.points = points;
	this.stroke = stroke;
	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
};

/**
 * Extends mxShape.
 */
mxUtils.extend(mxPolyline, mxShape);

/**
 * Function: getRotation
 * 
 * Returns 0.
 */
mxPolyline.prototype.getRotation = function()
{
	return 0;
};

/**
 * Function: getShapeRotation
 * 
 * Returns 0.
 */
mxPolyline.prototype.getShapeRotation = function()
{
	return 0;
};

/**
 * Function: isPaintBoundsInverted
 * 
 * Returns false.
 */
mxPolyline.prototype.isPaintBoundsInverted = function()
{
	return false;
};

/**
 * Function: paintEdgeShape
 * 
 * Paints the line shape.
 */
mxPolyline.prototype.paintEdgeShape = function(c, pts)
{
	if (this.style == null || this.style[mxConstants.STYLE_CURVED] != 1)
	{
		this.paintLine(c, pts, this.isRounded);
	}
	else
	{
		this.paintCurvedLine(c, pts);
	}
};

/**
 * Function: paintLine
 * 
 * Paints the line shape.
 */
mxPolyline.prototype.paintLine = function(c, pts, rounded)
{
	var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
	c.begin();
	this.addPoints(c, pts, rounded, arcSize, false);
	c.stroke();
};

/**
 * Function: paintLine
 * 
 * Paints the line shape.
 */
mxPolyline.prototype.paintCurvedLine = function(c, pts)
{
	c.begin();
	
	var pt = pts[0];
	var n = pts.length;
	
	c.moveTo(pt.x, pt.y);
	
	for (var i = 1; i < n - 2; i++)
	{
		var p0 = pts[i];
		var p1 = pts[i + 1];
		var ix = (p0.x + p1.x) / 2;
		var iy = (p0.y + p1.y) / 2;
		
		c.quadTo(p0.x, p0.y, ix, iy);
	}
	
	var p0 = pts[n - 2];
	var p1 = pts[n - 1];
	
	c.quadTo(p0.x, p0.y, p1.x, p1.y);
	c.stroke();
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxArrow
 *
 * Extends <mxShape> to implement an arrow shape. (The shape
 * is used to represent edges, not vertices.)
 * This shape is registered under <mxConstants.SHAPE_ARROW>
 * in <mxCellRenderer>.
 * 
 * Constructor: mxArrow
 *
 * Constructs a new arrow shape.
 * 
 * Parameters:
 * 
 * points - Array of <mxPoints> that define the points. This is stored in
 * <mxShape.points>.
 * fill - String that defines the fill color. This is stored in <fill>.
 * stroke - String that defines the stroke color. This is stored in <stroke>.
 * strokewidth - Optional integer that defines the stroke width. Default is
 * 1. This is stored in <strokewidth>.
 * arrowWidth - Optional integer that defines the arrow width. Default is
 * <mxConstants.ARROW_WIDTH>. This is stored in <arrowWidth>.
 * spacing - Optional integer that defines the spacing between the arrow shape
 * and its endpoints. Default is <mxConstants.ARROW_SPACING>. This is stored in
 * <spacing>.
 * endSize - Optional integer that defines the size of the arrowhead. Default
 * is <mxConstants.ARROW_SIZE>. This is stored in <endSize>.
 */
function mxArrow(points, fill, stroke, strokewidth, arrowWidth, spacing, endSize)
{
	mxShape.call(this);
	this.points = points;
	this.fill = fill;
	this.stroke = stroke;
	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
	this.arrowWidth = (arrowWidth != null) ? arrowWidth : mxConstants.ARROW_WIDTH;
	this.spacing = (spacing != null) ? spacing : mxConstants.ARROW_SPACING;
	this.endSize = (endSize != null) ? endSize : mxConstants.ARROW_SIZE;
};

/**
 * Extends mxShape.
 */
mxUtils.extend(mxArrow, mxShape);

/**
 * Function: augmentBoundingBox
 *
 * Augments the bounding box with the edge width and markers.
 */
mxArrow.prototype.augmentBoundingBox = function(bbox)
{
	mxShape.prototype.augmentBoundingBox.apply(this, arguments);
	
	var w = Math.max(this.arrowWidth, this.endSize);
	bbox.grow((w / 2 + this.strokewidth) * this.scale);
};

/**
 * Function: paintEdgeShape
 * 
 * Paints the line shape.
 */
mxArrow.prototype.paintEdgeShape = function(c, pts)
{
	// Geometry of arrow
	var spacing =  mxConstants.ARROW_SPACING;
	var width = mxConstants.ARROW_WIDTH;
	var arrow = mxConstants.ARROW_SIZE;

	// Base vector (between end points)
	var p0 = pts[0];
	var pe = pts[pts.length - 1];
	var dx = pe.x - p0.x;
	var dy = pe.y - p0.y;
	var dist = Math.sqrt(dx * dx + dy * dy);
	var length = dist - 2 * spacing - arrow;
	
	// Computes the norm and the inverse norm
	var nx = dx / dist;
	var ny = dy / dist;
	var basex = length * nx;
	var basey = length * ny;
	var floorx = width * ny/3;
	var floory = -width * nx/3;
	
	// Computes points
	var p0x = p0.x - floorx / 2 + spacing * nx;
	var p0y = p0.y - floory / 2 + spacing * ny;
	var p1x = p0x + floorx;
	var p1y = p0y + floory;
	var p2x = p1x + basex;
	var p2y = p1y + basey;
	var p3x = p2x + floorx;
	var p3y = p2y + floory;
	// p4 not necessary
	var p5x = p3x - 3 * floorx;
	var p5y = p3y - 3 * floory;
	
	c.begin();
	c.moveTo(p0x, p0y);
	c.lineTo(p1x, p1y);
	c.lineTo(p2x, p2y);
	c.lineTo(p3x, p3y);
	c.lineTo(pe.x - spacing * nx, pe.y - spacing * ny);
	c.lineTo(p5x, p5y);
	c.lineTo(p5x + floorx, p5y + floory);
	c.close();

	c.fillAndStroke();
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxArrowConnector
 *
 * Extends <mxShape> to implement an new rounded arrow shape with support for
 * waypoints and double arrows. (The shape is used to represent edges, not
 * vertices.) This shape is registered under <mxConstants.SHAPE_ARROW_CONNECTOR>
 * in <mxCellRenderer>.
 * 
 * Constructor: mxArrowConnector
 *
 * Constructs a new arrow shape.
 * 
 * Parameters:
 * 
 * points - Array of <mxPoints> that define the points. This is stored in
 * <mxShape.points>.
 * fill - String that defines the fill color. This is stored in <fill>.
 * stroke - String that defines the stroke color. This is stored in <stroke>.
 * strokewidth - Optional integer that defines the stroke width. Default is
 * 1. This is stored in <strokewidth>.
 * arrowWidth - Optional integer that defines the arrow width. Default is
 * <mxConstants.ARROW_WIDTH>. This is stored in <arrowWidth>.
 * spacing - Optional integer that defines the spacing between the arrow shape
 * and its endpoints. Default is <mxConstants.ARROW_SPACING>. This is stored in
 * <spacing>.
 * endSize - Optional integer that defines the size of the arrowhead. Default
 * is <mxConstants.ARROW_SIZE>. This is stored in <endSize>.
 */
function mxArrowConnector(points, fill, stroke, strokewidth, arrowWidth, spacing, endSize)
{
	mxShape.call(this);
	this.points = points;
	this.fill = fill;
	this.stroke = stroke;
	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
	this.arrowWidth = (arrowWidth != null) ? arrowWidth : mxConstants.ARROW_WIDTH;
	this.arrowSpacing = (spacing != null) ? spacing : mxConstants.ARROW_SPACING;
	this.startSize = mxConstants.ARROW_SIZE / 5;
	this.endSize = mxConstants.ARROW_SIZE / 5;
};

/**
 * Extends mxShape.
 */
mxUtils.extend(mxArrowConnector, mxShape);

/**
 * Variable: useSvgBoundingBox
 * 
 * Allows to use the SVG bounding box in SVG. Default is false for performance
 * reasons.
 */
mxArrowConnector.prototype.useSvgBoundingBox = true;

/**
 * Variable: resetStyles
 * 
 * Overrides mxShape to reset spacing.
 */
mxArrowConnector.prototype.resetStyles = function()
{
	mxShape.prototype.resetStyles.apply(this, arguments);
	
	this.arrowSpacing = mxConstants.ARROW_SPACING;
};

/**
 * Overrides apply to get smooth transition from default start- and endsize.
 */
mxArrowConnector.prototype.apply = function(state)
{
	mxShape.prototype.apply.apply(this, arguments);

	if (this.style != null)
	{
		this.startSize = mxUtils.getNumber(this.style, mxConstants.STYLE_STARTSIZE, mxConstants.ARROW_SIZE / 5) * 3;
		this.endSize = mxUtils.getNumber(this.style, mxConstants.STYLE_ENDSIZE, mxConstants.ARROW_SIZE / 5) * 3;
	}
};

/**
 * Function: augmentBoundingBox
 *
 * Augments the bounding box with the edge width and markers.
 */
mxArrowConnector.prototype.augmentBoundingBox = function(bbox)
{
	mxShape.prototype.augmentBoundingBox.apply(this, arguments);
	
	var w = this.getEdgeWidth();
	
	if (this.isMarkerStart())
	{
		w = Math.max(w, this.getStartArrowWidth());
	}
	
	if (this.isMarkerEnd())
	{
		w = Math.max(w, this.getEndArrowWidth());
	}
	
	bbox.grow((w / 2 + this.strokewidth) * this.scale);
};

/**
 * Function: paintEdgeShape
 * 
 * Paints the line shape.
 */
mxArrowConnector.prototype.paintEdgeShape = function(c, pts)
{
	// Geometry of arrow
	var strokeWidth = this.strokewidth;
	
	if (this.outline)
	{
		strokeWidth = Math.max(1, mxUtils.getNumber(this.style, mxConstants.STYLE_STROKEWIDTH, this.strokewidth));
	}
	
	var startWidth = this.getStartArrowWidth() + strokeWidth;
	var endWidth = this.getEndArrowWidth() + strokeWidth;
	var edgeWidth = this.outline ? this.getEdgeWidth() + strokeWidth : this.getEdgeWidth();
	var openEnded = this.isOpenEnded();
	var markerStart = this.isMarkerStart();
	var markerEnd = this.isMarkerEnd();
	var spacing = (openEnded) ? 0 : this.arrowSpacing + strokeWidth / 2;
	var startSize = this.startSize + strokeWidth;
	var endSize = this.endSize + strokeWidth;
	var isRounded = this.isArrowRounded();
	
	// Base vector (between first points)
	var pe = pts[pts.length - 1];

	// Finds first non-overlapping point
	var i0 = 1;
	
	while (i0 < pts.length - 1 && pts[i0].x == pts[0].x && pts[i0].y == pts[0].y)
	{
		i0++;
	}
	
	var dx = pts[i0].x - pts[0].x;
	var dy = pts[i0].y - pts[0].y;
	var dist = Math.sqrt(dx * dx + dy * dy);
	
	if (dist == 0)
	{
		return;
	}
	
	// Computes the norm and the inverse norm
	var nx = dx / dist;
	var nx2, nx1 = nx;
	var ny = dy / dist;
	var ny2, ny1 = ny;
	var orthx = edgeWidth * ny;
	var orthy = -edgeWidth * nx;
	
	// Stores the inbound function calls in reverse order in fns
	var fns = [];
	
	if (isRounded)
	{
		c.setLineJoin('round');
	}
	else if (pts.length > 2)
	{
		// Only mitre if there are waypoints
		c.setMiterLimit(1.42);
	}

	c.begin();

	var startNx = nx;
	var startNy = ny;

	if (markerStart && !openEnded)
	{
		this.paintMarker(c, pts[0].x, pts[0].y, nx, ny, startSize, startWidth, edgeWidth, spacing, true);
	}
	else
	{
		var outStartX = pts[0].x + orthx / 2 + spacing * nx;
		var outStartY = pts[0].y + orthy / 2 + spacing * ny;
		var inEndX = pts[0].x - orthx / 2 + spacing * nx;
		var inEndY = pts[0].y - orthy / 2 + spacing * ny;
		
		if (openEnded)
		{
			c.moveTo(outStartX, outStartY);
			
			fns.push(function()
			{
				c.lineTo(inEndX, inEndY);
			});
		}
		else
		{
			c.moveTo(inEndX, inEndY);
			c.lineTo(outStartX, outStartY);
		}
	}
	
	var dx1 = 0;
	var dy1 = 0;
	var dist1 = 0;

	for (var i = 0; i < pts.length - 2; i++)
	{
		// Work out in which direction the line is bending
		var pos = mxUtils.relativeCcw(pts[i].x, pts[i].y, pts[i+1].x, pts[i+1].y, pts[i+2].x, pts[i+2].y);

		dx1 = pts[i+2].x - pts[i+1].x;
		dy1 = pts[i+2].y - pts[i+1].y;

		dist1 = Math.sqrt(dx1 * dx1 + dy1 * dy1);
		
		if (dist1 != 0)
		{
			nx1 = dx1 / dist1;
			ny1 = dy1 / dist1;
			
			var tmp1 = nx * nx1 + ny * ny1;
			tmp = Math.max(Math.sqrt((tmp1 + 1) / 2), 0.04);
			
			// Work out the normal orthogonal to the line through the control point and the edge sides intersection
			nx2 = (nx + nx1);
			ny2 = (ny + ny1);
	
			var dist2 = Math.sqrt(nx2 * nx2 + ny2 * ny2);
			
			if (dist2 != 0)
			{
				nx2 = nx2 / dist2;
				ny2 = ny2 / dist2;
				
				// Higher strokewidths require a larger minimum bend, 0.35 covers all but the most extreme cases
				var strokeWidthFactor = Math.max(tmp, Math.min(this.strokewidth / 200 + 0.04, 0.35));
				var angleFactor = (pos != 0 && isRounded) ? Math.max(0.1, strokeWidthFactor) : Math.max(tmp, 0.06);

				var outX = pts[i+1].x + ny2 * edgeWidth / 2 / angleFactor;
				var outY = pts[i+1].y - nx2 * edgeWidth / 2 / angleFactor;
				var inX = pts[i+1].x - ny2 * edgeWidth / 2 / angleFactor;
				var inY = pts[i+1].y + nx2 * edgeWidth / 2 / angleFactor;
				
				if (pos == 0 || !isRounded)
				{
					// If the two segments are aligned, or if we're not drawing curved sections between segments
					// just draw straight to the intersection point
					c.lineTo(outX, outY);
					
					(function(x, y)
					{
						fns.push(function()
						{
							c.lineTo(x, y);
						});
					})(inX, inY);
				}
				else if (pos == -1)
				{
					var c1x = inX + ny * edgeWidth;
					var c1y = inY - nx * edgeWidth;
					var c2x = inX + ny1 * edgeWidth;
					var c2y = inY - nx1 * edgeWidth;
					c.lineTo(c1x, c1y);
					c.quadTo(outX, outY, c2x, c2y);
					
					(function(x, y)
					{
						fns.push(function()
						{
							c.lineTo(x, y);
						});
					})(inX, inY);
				}
				else
				{
					c.lineTo(outX, outY);
					
					(function(x, y)
					{
						var c1x = outX - ny * edgeWidth;
						var c1y = outY + nx * edgeWidth;
						var c2x = outX - ny1 * edgeWidth;
						var c2y = outY + nx1 * edgeWidth;
						
						fns.push(function()
						{
							c.quadTo(x, y, c1x, c1y);
						});
						fns.push(function()
						{
							c.lineTo(c2x, c2y);
						});
					})(inX, inY);
				}
				
				nx = nx1;
				ny = ny1;
			}
		}
	}
	
	orthx = edgeWidth * ny1;
	orthy = - edgeWidth * nx1;

	if (markerEnd && !openEnded)
	{
		this.paintMarker(c, pe.x, pe.y, -nx, -ny, endSize, endWidth, edgeWidth, spacing, false);
	}
	else
	{
		c.lineTo(pe.x - spacing * nx1 + orthx / 2, pe.y - spacing * ny1 + orthy / 2);
		
		var inStartX = pe.x - spacing * nx1 - orthx / 2;
		var inStartY = pe.y - spacing * ny1 - orthy / 2;

		if (!openEnded)
		{
			c.lineTo(inStartX, inStartY);
		}
		else
		{
			c.moveTo(inStartX, inStartY);
			
			fns.splice(0, 0, function()
			{
				c.moveTo(inStartX, inStartY);
			});
		}
	}
	
	for (var i = fns.length - 1; i >= 0; i--)
	{
		fns[i]();
	}

	if (openEnded)
	{
		c.end();
		c.stroke();
	}
	else
	{
		c.close();
		c.fillAndStroke();
	}
	
	// Workaround for shadow on top of base arrow
	c.setShadow(false);
	
	// Need to redraw the markers without the low miter limit
	c.setMiterLimit(4);
	
	if (isRounded)
	{
		c.setLineJoin('flat');
	}

	if (pts.length > 2)
	{
		// Only to repaint markers if no waypoints
		// Need to redraw the markers without the low miter limit
		c.setMiterLimit(4);
		if (markerStart && !openEnded)
		{
			c.begin();
			this.paintMarker(c, pts[0].x, pts[0].y, startNx, startNy, startSize, startWidth, edgeWidth, spacing, true);
			c.stroke();
			c.end();
		}
		
		if (markerEnd && !openEnded)
		{
			c.begin();
			this.paintMarker(c, pe.x, pe.y, -nx, -ny, endSize, endWidth, edgeWidth, spacing, true);
			c.stroke();
			c.end();
		}
	}
};

/**
 * Function: paintEdgeShape
 * 
 * Paints the line shape.
 */
mxArrowConnector.prototype.paintMarker = function(c, ptX, ptY, nx, ny, size, arrowWidth, edgeWidth, spacing, initialMove)
{
	var widthArrowRatio = edgeWidth / arrowWidth;
	var orthx = edgeWidth * ny / 2;
	var orthy = -edgeWidth * nx / 2;

	var spaceX = (spacing + size) * nx;
	var spaceY = (spacing + size) * ny;

	if (initialMove)
	{
		c.moveTo(ptX - orthx + spaceX, ptY - orthy + spaceY);
	}
	else
	{
		c.lineTo(ptX - orthx + spaceX, ptY - orthy + spaceY);
	}

	c.lineTo(ptX - orthx / widthArrowRatio + spaceX, ptY - orthy / widthArrowRatio + spaceY);
	c.lineTo(ptX + spacing * nx, ptY + spacing * ny);
	c.lineTo(ptX + orthx / widthArrowRatio + spaceX, ptY + orthy / widthArrowRatio + spaceY);
	c.lineTo(ptX + orthx + spaceX, ptY + orthy + spaceY);
}

/**
 * Function: isArrowRounded
 * 
 * Returns wether the arrow is rounded
 */
mxArrowConnector.prototype.isArrowRounded = function()
{
	return this.isRounded;
};

/**
 * Function: getStartArrowWidth
 * 
 * Returns the width of the start arrow
 */
mxArrowConnector.prototype.getStartArrowWidth = function()
{
	return mxConstants.ARROW_WIDTH;
};

/**
 * Function: getEndArrowWidth
 * 
 * Returns the width of the end arrow
 */
mxArrowConnector.prototype.getEndArrowWidth = function()
{
	return mxConstants.ARROW_WIDTH;
};

/**
 * Function: getEdgeWidth
 * 
 * Returns the width of the body of the edge
 */
mxArrowConnector.prototype.getEdgeWidth = function()
{
	return mxConstants.ARROW_WIDTH / 3;
};

/**
 * Function: isOpenEnded
 * 
 * Returns whether the ends of the shape are drawn
 */
mxArrowConnector.prototype.isOpenEnded = function()
{
	return false;
};

/**
 * Function: isMarkerStart
 * 
 * Returns whether the start marker is drawn
 */
mxArrowConnector.prototype.isMarkerStart = function()
{
	return (mxUtils.getValue(this.style, mxConstants.STYLE_STARTARROW, mxConstants.NONE) != mxConstants.NONE);
};

/**
 * Function: isMarkerEnd
 * 
 * Returns whether the end marker is drawn
 */
mxArrowConnector.prototype.isMarkerEnd = function()
{
	return (mxUtils.getValue(this.style, mxConstants.STYLE_ENDARROW, mxConstants.NONE) != mxConstants.NONE);
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxText
 *
 * Extends <mxShape> to implement a text shape. To change vertical text from
 * bottom to top to top to bottom, the following code can be used:
 * 
 * (code)
 * mxText.prototype.verticalTextRotation = 90;
 * (end)
 * 
 * Constructor: mxText
 *
 * Constructs a new text shape.
 * 
 * Parameters:
 * 
 * value - String that represents the text to be displayed. This is stored in
 * <value>.
 * bounds - <mxRectangle> that defines the bounds. This is stored in
 * <mxShape.bounds>.
 * align - Specifies the horizontal alignment. Default is ''. This is stored in
 * <align>.
 * valign - Specifies the vertical alignment. Default is ''. This is stored in
 * <valign>.
 * color - String that specifies the text color. Default is 'black'. This is
 * stored in <color>.
 * family - String that specifies the font family. Default is
 * <mxConstants.DEFAULT_FONTFAMILY>. This is stored in <family>.
 * size - Integer that specifies the font size. Default is
 * <mxConstants.DEFAULT_FONTSIZE>. This is stored in <size>.
 * fontStyle - Specifies the font style. Default is 0. This is stored in
 * <fontStyle>.
 * spacing - Integer that specifies the global spacing. Default is 2. This is
 * stored in <spacing>.
 * spacingTop - Integer that specifies the top spacing. Default is 0. The
 * sum of the spacing and this is stored in <spacingTop>.
 * spacingRight - Integer that specifies the right spacing. Default is 0. The
 * sum of the spacing and this is stored in <spacingRight>.
 * spacingBottom - Integer that specifies the bottom spacing. Default is 0.The
 * sum of the spacing and this is stored in <spacingBottom>.
 * spacingLeft - Integer that specifies the left spacing. Default is 0. The
 * sum of the spacing and this is stored in <spacingLeft>.
 * horizontal - Boolean that specifies if the label is horizontal. Default is
 * true. This is stored in <horizontal>.
 * background - String that specifies the background color. Default is null.
 * This is stored in <background>.
 * border - String that specifies the label border color. Default is null.
 * This is stored in <border>.
 * wrap - Specifies if word-wrapping should be enabled. Default is false.
 * This is stored in <wrap>.
 * clipped - Specifies if the label should be clipped. Default is false.
 * This is stored in <clipped>.
 * overflow - Value of the overflow style. Default is 'visible'.
 */
function mxText(value, bounds, align, valign, color,
	family,	size, fontStyle, spacing, spacingTop, spacingRight,
	spacingBottom, spacingLeft, horizontal, background, border,
	wrap, clipped, overflow, labelPadding, textDirection)
{
	mxShape.call(this);
	this.value = value;
	this.bounds = bounds;
	this.color = (color != null) ? color : 'black';
	this.align = (align != null) ? align : mxConstants.ALIGN_CENTER;
	this.valign = (valign != null) ? valign : mxConstants.ALIGN_MIDDLE;
	this.family = (family != null) ? family : mxConstants.DEFAULT_FONTFAMILY;
	this.size = (size != null) ? size : mxConstants.DEFAULT_FONTSIZE;
	this.fontStyle = (fontStyle != null) ? fontStyle : mxConstants.DEFAULT_FONTSTYLE;
	this.spacing = parseInt(spacing || 2);
	this.spacingTop = this.spacing + parseInt(spacingTop || 0);
	this.spacingRight = this.spacing + parseInt(spacingRight || 0);
	this.spacingBottom = this.spacing + parseInt(spacingBottom || 0);
	this.spacingLeft = this.spacing + parseInt(spacingLeft || 0);
	this.horizontal = (horizontal != null) ? horizontal : true;
	this.background = background;
	this.border = border;
	this.wrap = (wrap != null) ? wrap : false;
	this.clipped = (clipped != null) ? clipped : false;
	this.overflow = (overflow != null) ? overflow : 'visible';
	this.labelPadding = (labelPadding != null) ? labelPadding : 0;
	this.textDirection = textDirection;
	this.rotation = 0;
	this.updateMargin();
};

/**
 * Extends mxShape.
 */
mxUtils.extend(mxText, mxShape);

/**
 * Variable: baseSpacingTop
 * 
 * Specifies the spacing to be added to the top spacing. Default is 0. Use the
 * value 5 here to get the same label positions as in mxGraph 1.x.
 */
mxText.prototype.baseSpacingTop = 0;

/**
 * Variable: baseSpacingBottom
 * 
 * Specifies the spacing to be added to the bottom spacing. Default is 0. Use the
 * value 1 here to get the same label positions as in mxGraph 1.x.
 */
mxText.prototype.baseSpacingBottom = 0;

/**
 * Variable: baseSpacingLeft
 * 
 * Specifies the spacing to be added to the left spacing. Default is 0.
 */
mxText.prototype.baseSpacingLeft = 0;

/**
 * Variable: baseSpacingRight
 * 
 * Specifies the spacing to be added to the right spacing. Default is 0.
 */
mxText.prototype.baseSpacingRight = 0;

/**
 * Variable: replaceLinefeeds
 * 
 * Specifies if linefeeds in HTML labels should be replaced with BR tags.
 * Default is true.
 */
mxText.prototype.replaceLinefeeds = true;

/**
 * Variable: verticalTextRotation
 * 
 * Rotation for vertical text. Default is -90 (bottom to top).
 */
mxText.prototype.verticalTextRotation = -90;

/**
 * Variable: ignoreClippedStringSize
 * 
 * Specifies if the string size should be measured in <updateBoundingBox> if
 * the label is clipped and the label position is center and middle. If this is
 * true, then the bounding box will be set to <bounds>. Default is true.
 * <ignoreStringSize> has precedence over this switch.
 */
mxText.prototype.ignoreClippedStringSize = true;

/**
 * Variable: ignoreStringSize
 * 
 * Specifies if the actual string size should be measured. If disabled the
 * boundingBox will not ignore the actual size of the string, otherwise
 * <bounds> will be used instead. Default is false.
 */
mxText.prototype.ignoreStringSize = false;

/**
 * Variable: textWidthPadding
 * 
 * Specifies the padding to be added to the text width for the bounding box.
 * This is needed to make sure no clipping is applied to borders. Default is 4
 * for IE 8 standards mode and 3 for all others.
 */
mxText.prototype.textWidthPadding = (document.documentMode == 8 && !mxClient.IS_EM) ? 4 : 3;

/**
 * Variable: lastValue
 * 
 * Contains the last rendered text value. Used for caching.
 */
mxText.prototype.lastValue = null;

/**
 * Variable: cacheEnabled
 * 
 * Specifies if caching for HTML labels should be enabled. Default is true.
 */
mxText.prototype.cacheEnabled = true;

/**
 * Function: isParseVml
 * 
 * Text shapes do not contain VML markup and do not need to be parsed. This
 * method returns false to speed up rendering in IE8.
 */
mxText.prototype.isParseVml = function()
{
	return false;
};

/**
 * Function: isHtmlAllowed
 * 
 * Returns true if HTML is allowed for this shape. This implementation returns
 * true if the browser is not in IE8 standards mode.
 */
mxText.prototype.isHtmlAllowed = function()
{
	return document.documentMode != 8 || mxClient.IS_EM;
};

/**
 * Function: getSvgScreenOffset
 * 
 * Disables offset in IE9 for crisper image output.
 */
mxText.prototype.getSvgScreenOffset = function()
{
	return 0;
};

/**
 * Function: checkBounds
 * 
 * Returns true if the bounds are not null and all of its variables are numeric.
 */
mxText.prototype.checkBounds = function()
{
	return (!isNaN(this.scale) && isFinite(this.scale) && this.scale > 0 &&
			this.bounds != null && !isNaN(this.bounds.x) && !isNaN(this.bounds.y) &&
			!isNaN(this.bounds.width) && !isNaN(this.bounds.height));
};

/**
 * Function: paint
 * 
 * Generic rendering code.
 */
mxText.prototype.paint = function(c, update)
{
	// Scale is passed-through to canvas
	var s = this.scale;
	var x = this.bounds.x / s;
	var y = this.bounds.y / s;
	var w = this.bounds.width / s;
	var h = this.bounds.height / s;
	
	this.updateTransform(c, x, y, w, h);
	this.configureCanvas(c, x, y, w, h);

	var unscaledWidth = (this.state != null) ? this.state.unscaledWidth : null;

	if (update)
	{
		if (this.node.firstChild != null && (unscaledWidth == null ||
			this.lastUnscaledWidth != unscaledWidth))
		{
			c.invalidateCachedOffsetSize(this.node);
		}

		c.updateText(x, y, w, h, this.align, this.valign, this.wrap, this.overflow,
				this.clipped, this.getTextRotation(), this.node);
	}
	else
	{
		// Checks if text contains HTML markup
		var realHtml = mxUtils.isNode(this.value) || this.dialect == mxConstants.DIALECT_STRICTHTML;
		
		// Always renders labels as HTML in VML
		var fmt = (realHtml || c instanceof mxVmlCanvas2D) ? 'html' : '';
		var val = this.value;
		
		if (!realHtml && fmt == 'html')
		{
			val =  mxUtils.htmlEntities(val, false);
		}
		
		if (fmt == 'html' && !mxUtils.isNode(this.value))
		{
			val = mxUtils.replaceTrailingNewlines(val, '<div><br></div>');			
		}
		
		// Handles trailing newlines to make sure they are visible in rendering output
		val = (!mxUtils.isNode(this.value) && this.replaceLinefeeds && fmt == 'html') ?
			val.replace(/\n/g, '<br/>') : val;
			
		var dir = this.textDirection;
	
		if (dir == mxConstants.TEXT_DIRECTION_AUTO && !realHtml)
		{
			dir = this.getAutoDirection();
		}
		
		if (dir != mxConstants.TEXT_DIRECTION_LTR && dir != mxConstants.TEXT_DIRECTION_RTL)
		{
			dir = null;
		}
	
		c.text(x, y, w, h, val, this.align, this.valign, this.wrap, fmt, this.overflow,
			this.clipped, this.getTextRotation(), dir);
	}
	
	// Needs to invalidate the cached offset widths if the geometry changes
	this.lastUnscaledWidth = unscaledWidth;
};

/**
 * Function: redraw
 * 
 * Renders the text using the given DOM nodes.
 */
mxText.prototype.redraw = function()
{
	if (this.visible && this.checkBounds() && this.cacheEnabled && this.lastValue == this.value &&
		(mxUtils.isNode(this.value) || this.dialect == mxConstants.DIALECT_STRICTHTML))
	{
		if (this.node.nodeName == 'DIV' && (this.isHtmlAllowed() || !mxClient.IS_VML))
		{
			this.updateSize(this.node, (this.state == null || this.state.view.textDiv == null));

			if (mxClient.IS_IE && (document.documentMode == null || document.documentMode <= 8))
			{
				this.updateHtmlFilter();
			}
			else
			{
				this.updateHtmlTransform();
			}
			
			this.updateBoundingBox();
		}
		else
		{
			var canvas = this.createCanvas();

			if (canvas != null && canvas.updateText != null &&
				canvas.invalidateCachedOffsetSize != null)
			{
				this.paint(canvas, true);
				this.destroyCanvas(canvas);
				this.updateBoundingBox();
			}
			else
			{
				// Fallback if canvas does not support updateText (VML)
				mxShape.prototype.redraw.apply(this, arguments);
			}
		}
	}
	else
	{
		mxShape.prototype.redraw.apply(this, arguments);
		
		if (mxUtils.isNode(this.value) || this.dialect == mxConstants.DIALECT_STRICTHTML)
		{
			this.lastValue = this.value;
		}
		else
		{
			this.lastValue = null;
		}
	}
};

/**
 * Function: resetStyles
 * 
 * Resets all styles.
 */
mxText.prototype.resetStyles = function()
{
	mxShape.prototype.resetStyles.apply(this, arguments);
	
	this.color = 'black';
	this.align = mxConstants.ALIGN_CENTER;
	this.valign = mxConstants.ALIGN_MIDDLE;
	this.family = mxConstants.DEFAULT_FONTFAMILY;
	this.size = mxConstants.DEFAULT_FONTSIZE;
	this.fontStyle = mxConstants.DEFAULT_FONTSTYLE;
	this.spacing = 2;
	this.spacingTop = 2;
	this.spacingRight = 2;
	this.spacingBottom = 2;
	this.spacingLeft = 2;
	this.horizontal = true;
	delete this.background;
	delete this.border;
	this.textDirection = mxConstants.DEFAULT_TEXT_DIRECTION;
	delete this.margin;
};

/**
 * Function: apply
 * 
 * Extends mxShape to update the text styles.
 *
 * Parameters:
 *
 * state - <mxCellState> of the corresponding cell.
 */
mxText.prototype.apply = function(state)
{
	var old = this.spacing;
	mxShape.prototype.apply.apply(this, arguments);
	
	if (this.style != null)
	{
		this.fontStyle = mxUtils.getValue(this.style, mxConstants.STYLE_FONTSTYLE, this.fontStyle);
		this.family = mxUtils.getValue(this.style, mxConstants.STYLE_FONTFAMILY, this.family);
		this.size = mxUtils.getValue(this.style, mxConstants.STYLE_FONTSIZE, this.size);
		this.color = mxUtils.getValue(this.style, mxConstants.STYLE_FONTCOLOR, this.color);
		this.align = mxUtils.getValue(this.style, mxConstants.STYLE_ALIGN, this.align);
		this.valign = mxUtils.getValue(this.style, mxConstants.STYLE_VERTICAL_ALIGN, this.valign);
		this.spacing = parseInt(mxUtils.getValue(this.style, mxConstants.STYLE_SPACING, this.spacing));
		this.spacingTop = parseInt(mxUtils.getValue(this.style, mxConstants.STYLE_SPACING_TOP, this.spacingTop - old)) + this.spacing;
		this.spacingRight = parseInt(mxUtils.getValue(this.style, mxConstants.STYLE_SPACING_RIGHT, this.spacingRight - old)) + this.spacing;
		this.spacingBottom = parseInt(mxUtils.getValue(this.style, mxConstants.STYLE_SPACING_BOTTOM, this.spacingBottom - old)) + this.spacing;
		this.spacingLeft = parseInt(mxUtils.getValue(this.style, mxConstants.STYLE_SPACING_LEFT, this.spacingLeft - old)) + this.spacing;
		this.horizontal = mxUtils.getValue(this.style, mxConstants.STYLE_HORIZONTAL, this.horizontal);
		this.background = mxUtils.getValue(this.style, mxConstants.STYLE_LABEL_BACKGROUNDCOLOR, this.background);
		this.border = mxUtils.getValue(this.style, mxConstants.STYLE_LABEL_BORDERCOLOR, this.border);
		this.textDirection = mxUtils.getValue(this.style, mxConstants.STYLE_TEXT_DIRECTION, mxConstants.DEFAULT_TEXT_DIRECTION);
		this.opacity = mxUtils.getValue(this.style, mxConstants.STYLE_TEXT_OPACITY, 100);
		this.updateMargin();
	}
	
	this.flipV = null;
	this.flipH = null;
};

/**
 * Function: getAutoDirection
 * 
 * Used to determine the automatic text direction. Returns
 * <mxConstants.TEXT_DIRECTION_LTR> or <mxConstants.TEXT_DIRECTION_RTL>
 * depending on the contents of <value>. This is not invoked for HTML, wrapped
 * content or if <value> is a DOM node.
 */
mxText.prototype.getAutoDirection = function()
{
	// Looks for strong (directional) characters
	var tmp = /[A-Za-z\u05d0-\u065f\u066a-\u06ef\u06fa-\u07ff\ufb1d-\ufdff\ufe70-\ufefc]/.exec(this.value);
	
	// Returns the direction defined by the character
	return (tmp != null && tmp.length > 0 && tmp[0] > 'z') ?
		mxConstants.TEXT_DIRECTION_RTL : mxConstants.TEXT_DIRECTION_LTR;
};

/**
 * Function: updateBoundingBox
 *
 * Updates the <boundingBox> for this shape using the given node and position.
 */
mxText.prototype.updateBoundingBox = function()
{
	var node = this.node;
	this.boundingBox = this.bounds.clone();
	var rot = this.getTextRotation();
	
	var h = (this.style != null) ? mxUtils.getValue(this.style, mxConstants.STYLE_LABEL_POSITION, mxConstants.ALIGN_CENTER) : null;
	var v = (this.style != null) ? mxUtils.getValue(this.style, mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE) : null;

	if (!this.ignoreStringSize && node != null && this.overflow != 'fill' && (!this.clipped ||
		!this.ignoreClippedStringSize || h != mxConstants.ALIGN_CENTER || v != mxConstants.ALIGN_MIDDLE))
	{
		var ow = null;
		var oh = null;
		
		if (node.ownerSVGElement != null)
		{
			if (node.firstChild != null && node.firstChild.firstChild != null &&
				node.firstChild.firstChild.nodeName == 'foreignObject')
			{
				node = node.firstChild.firstChild;
				ow = parseInt(node.getAttribute('width')) * this.scale;
				oh = parseInt(node.getAttribute('height')) * this.scale;
			}
			else
			{
				try
				{
					var b = node.getBBox();
					
					// Workaround for bounding box of empty string
					if (typeof(this.value) == 'string' && mxUtils.trim(this.value) == 0)
					{
						this.boundingBox = null;
					}
					else if (b.width == 0 && b.height == 0)
					{
						this.boundingBox = null;
					}
					else
					{
						this.boundingBox = new mxRectangle(b.x, b.y, b.width, b.height);
					}
					
					return;
				}
				catch (e)
				{
					// Ignores NS_ERROR_FAILURE in FF if container display is none.
				}
			}
		}
		else
		{
			var td = (this.state != null) ? this.state.view.textDiv : null;

			// Use cached offset size
			if (this.offsetWidth != null && this.offsetHeight != null)
			{
				ow = this.offsetWidth * this.scale;
				oh = this.offsetHeight * this.scale;
			}
			else
			{
				// Cannot get node size while container hidden so a
				// shared temporary DIV is used for text measuring
				if (td != null)
				{
					this.updateFont(td);
					this.updateSize(td, false);
					this.updateInnerHtml(td);

					node = td;
				}
				
				var sizeDiv = node;

				if (document.documentMode == 8 && !mxClient.IS_EM)
				{
					var w = Math.round(this.bounds.width / this.scale);
	
					if (this.wrap && w > 0)
					{
						node.style.wordWrap = mxConstants.WORD_WRAP;
						node.style.whiteSpace = 'normal';

						if (node.style.wordWrap != 'break-word')
						{
							// Innermost DIV is used for measuring text
							var divs = sizeDiv.getElementsByTagName('div');
							
							if (divs.length > 0)
							{
								sizeDiv = divs[divs.length - 1];
							}
							
							ow = sizeDiv.offsetWidth + 2;
							divs = this.node.getElementsByTagName('div');
							
							if (this.clipped)
							{
								ow = Math.min(w, ow);
							}
							
							// Second last DIV width must be updated in DOM tree
							if (divs.length > 1)
							{
								divs[divs.length - 2].style.width = ow + 'px';
							}
						}
					}
					else
					{
						node.style.whiteSpace = 'nowrap';
					}
				}
				else if (sizeDiv.firstChild != null && sizeDiv.firstChild.nodeName == 'DIV')
				{
					sizeDiv = sizeDiv.firstChild;
				}

				this.offsetWidth = sizeDiv.offsetWidth + this.textWidthPadding;
				this.offsetHeight = sizeDiv.offsetHeight;
				
				ow = this.offsetWidth * this.scale;
				oh = this.offsetHeight * this.scale;
			}
		}

		if (ow != null && oh != null)
		{	
			this.boundingBox = new mxRectangle(this.bounds.x,
				this.bounds.y, ow, oh);
		}
	}

	if (this.boundingBox != null)
	{
		if (rot != 0)
		{
			// Accounts for pre-rotated x and y
			var bbox = mxUtils.getBoundingBox(new mxRectangle(
				this.margin.x * this.boundingBox.width,
				this.margin.y * this.boundingBox.height,
				this.boundingBox.width, this.boundingBox.height),
				rot, new mxPoint(0, 0));
			
			this.unrotatedBoundingBox = mxRectangle.fromRectangle(this.boundingBox);
			this.unrotatedBoundingBox.x += this.margin.x * this.unrotatedBoundingBox.width;
			this.unrotatedBoundingBox.y += this.margin.y * this.unrotatedBoundingBox.height;
			
			this.boundingBox.x += bbox.x;
			this.boundingBox.y += bbox.y;
			this.boundingBox.width = bbox.width;
			this.boundingBox.height = bbox.height;
		}
		else
		{
			this.boundingBox.x += this.margin.x * this.boundingBox.width;
			this.boundingBox.y += this.margin.y * this.boundingBox.height;
			this.unrotatedBoundingBox = null;
		}
	}
};

/**
 * Function: getShapeRotation
 * 
 * Returns 0 to avoid using rotation in the canvas via updateTransform.
 */
mxText.prototype.getShapeRotation = function()
{
	return 0;
};

/**
 * Function: getTextRotation
 * 
 * Returns the rotation for the text label of the corresponding shape.
 */
mxText.prototype.getTextRotation = function()
{
	return (this.state != null && this.state.shape != null) ? this.state.shape.getTextRotation() : 0;
};

/**
 * Function: isPaintBoundsInverted
 * 
 * Inverts the bounds if <mxShape.isBoundsInverted> returns true or if the
 * horizontal style is false.
 */
mxText.prototype.isPaintBoundsInverted = function()
{
	return !this.horizontal && this.state != null && this.state.view.graph.model.isVertex(this.state.cell);
};

/**
 * Function: configureCanvas
 * 
 * Sets the state of the canvas for drawing the shape.
 */
mxText.prototype.configureCanvas = function(c, x, y, w, h)
{
	mxShape.prototype.configureCanvas.apply(this, arguments);
	
	c.setFontColor(this.color);
	c.setFontBackgroundColor(this.background);
	c.setFontBorderColor(this.border);
	c.setFontFamily(this.family);
	c.setFontSize(this.size);
	c.setFontStyle(this.fontStyle);
};

/**
 * Function: updateVmlContainer
 * 
 * Sets the width and height of the container to 1px.
 */
mxText.prototype.updateVmlContainer = function()
{
	this.node.style.left = Math.round(this.bounds.x) + 'px';
	this.node.style.top = Math.round(this.bounds.y) + 'px';
	this.node.style.width = '1px';
	this.node.style.height = '1px';
	this.node.style.overflow = 'visible';
};

/**
 * Function: redrawHtmlShape
 *
 * Updates the HTML node(s) to reflect the latest bounds and scale.
 */
mxText.prototype.redrawHtmlShape = function()
{
	var style = this.node.style;

	// Resets CSS styles
	style.whiteSpace = 'normal';
	style.overflow = '';
	style.width = '';
	style.height = '';
	
	this.updateValue();
	this.updateFont(this.node);
	this.updateSize(this.node, (this.state == null || this.state.view.textDiv == null));
	
	this.offsetWidth = null;
	this.offsetHeight = null;

	if (mxClient.IS_IE && (document.documentMode == null || document.documentMode <= 8))
	{
		this.updateHtmlFilter();
	}
	else
	{
		this.updateHtmlTransform();
	}
};

/**
 * Function: updateHtmlTransform
 *
 * Returns the spacing as an <mxPoint>.
 */
mxText.prototype.updateHtmlTransform = function()
{
	var theta = this.getTextRotation();
	var style = this.node.style;
	var dx = this.margin.x;
	var dy = this.margin.y;
	
	if (theta != 0)
	{
		mxUtils.setPrefixedStyle(style, 'transformOrigin', (-dx * 100) + '%' + ' ' + (-dy * 100) + '%');
		mxUtils.setPrefixedStyle(style, 'transform', 'translate(' + (dx * 100) + '%' + ',' + (dy * 100) + '%)' +
			'scale(' + this.scale + ') rotate(' + theta + 'deg)');
	}
	else
	{
		mxUtils.setPrefixedStyle(style, 'transformOrigin', '0% 0%');
		mxUtils.setPrefixedStyle(style, 'transform', 'scale(' + this.scale + ')' +
			'translate(' + (dx * 100) + '%' + ',' + (dy * 100) + '%)');
	}

	style.left = Math.round(this.bounds.x - Math.ceil(dx * ((this.overflow != 'fill' &&
		this.overflow != 'width') ? 3 : 1))) + 'px';
	style.top = Math.round(this.bounds.y - dy * ((this.overflow != 'fill') ? 3 : 1)) + 'px';
	
	if (this.opacity < 100)
	{
		style.opacity = this.opacity / 100;
	}
	else
	{
		style.opacity = '';
	}
};

/**
 * Function: setInnerHtml
 * 
 * Sets the inner HTML of the given element to the <value>.
 */
mxText.prototype.updateInnerHtml = function(elt)
{
	if (mxUtils.isNode(this.value))
	{
		elt.innerHTML = this.value.outerHTML;
	}
	else
	{
		var val = this.value;
		
		if (this.dialect != mxConstants.DIALECT_STRICTHTML)
		{
			// LATER: Can be cached in updateValue
			val = mxUtils.htmlEntities(val, false);
		}
		
		// Handles trailing newlines to make sure they are visible in rendering output
		val = mxUtils.replaceTrailingNewlines(val, '<div>&nbsp;</div>');
		val = (this.replaceLinefeeds) ? val.replace(/\n/g, '<br/>') : val;
		val = '<div style="display:inline-block;_display:inline;">' + val + '</div>';
		
		elt.innerHTML = val;
	}
};

/**
 * Function: updateHtmlFilter
 *
 * Rotated text rendering quality is bad for IE9 quirks/IE8 standards
 */
mxText.prototype.updateHtmlFilter = function()
{
	var style = this.node.style;
	var dx = this.margin.x;
	var dy = this.margin.y;
	var s = this.scale;
	
	// Resets filter before getting offsetWidth
	mxUtils.setOpacity(this.node, this.opacity);
	
	// Adds 1 to match table height in 1.x
	var ow = 0;
	var oh = 0;
	var td = (this.state != null) ? this.state.view.textDiv : null;
	var sizeDiv = this.node;
	
	// Fallback for hidden text rendering in IE quirks mode
	if (td != null)
	{
		td.style.overflow = '';
		td.style.height = '';
		td.style.width = '';
		
		this.updateFont(td);
		this.updateSize(td, false);
		this.updateInnerHtml(td);
		
		var w = Math.round(this.bounds.width / this.scale);

		if (this.wrap && w > 0)
		{
			td.style.whiteSpace = 'normal';
			td.style.wordWrap = mxConstants.WORD_WRAP;
			ow = w;
			
			if (this.clipped)
			{
				ow = Math.min(ow, this.bounds.width);
			}

			td.style.width = ow + 'px';
		}
		else
		{
			td.style.whiteSpace = 'nowrap';
		}
		
		sizeDiv = td;
		
		if (sizeDiv.firstChild != null && sizeDiv.firstChild.nodeName == 'DIV')
		{
			sizeDiv = sizeDiv.firstChild;
			
			if (this.wrap && td.style.wordWrap == 'break-word')
			{
				sizeDiv.style.width = '100%';
			}
		}

		// Required to update the height of the text box after wrapping width is known 
		if (!this.clipped && this.wrap && w > 0)
		{
			ow = sizeDiv.offsetWidth + this.textWidthPadding;
			td.style.width = ow + 'px';
		}
		
		oh = sizeDiv.offsetHeight + 2;
		
		if (mxClient.IS_QUIRKS && this.border != null && this.border != mxConstants.NONE)
		{
			oh += 3;
		}
	}
	else if (sizeDiv.firstChild != null && sizeDiv.firstChild.nodeName == 'DIV')
	{
		sizeDiv = sizeDiv.firstChild;
		oh = sizeDiv.offsetHeight;
	}

	ow = sizeDiv.offsetWidth + this.textWidthPadding;
	
	if (this.clipped)
	{
		oh = Math.min(oh, this.bounds.height);
	}

	var w = this.bounds.width / s;
	var h = this.bounds.height / s;

	// Handles special case for live preview with no wrapper DIV and no textDiv
	if (this.overflow == 'fill')
	{
		oh = h;
		ow = w;
	}
	else if (this.overflow == 'width')
	{
		oh = sizeDiv.scrollHeight;
		ow = w;
	}
	
	// Stores for later use
	this.offsetWidth = ow;
	this.offsetHeight = oh;
	
	// Simulates max-height CSS in quirks mode
	if (mxClient.IS_QUIRKS && (this.clipped || (this.overflow == 'width' && h > 0)))
	{
		h = Math.min(h, oh);
		style.height = Math.round(h) + 'px';
	}
	else
	{
		h = oh;
	}

	if (this.overflow != 'fill' && this.overflow != 'width')
	{
		if (this.clipped)
		{
			ow = Math.min(w, ow);
		}
		
		w = ow;

		// Simulates max-width CSS in quirks mode
		if ((mxClient.IS_QUIRKS && this.clipped) || this.wrap)
		{
			style.width = Math.round(w) + 'px';
		}
	}

	h *= s;
	w *= s;
	
	// Rotation case is handled via VML canvas
	var rad = this.getTextRotation() * (Math.PI / 180);
	
	// Precalculate cos and sin for the rotation
	var real_cos = parseFloat(parseFloat(Math.cos(rad)).toFixed(8));
	var real_sin = parseFloat(parseFloat(Math.sin(-rad)).toFixed(8));

	rad %= 2 * Math.PI;
	
	if (rad < 0)
	{
		rad += 2 * Math.PI;
	}
	
	rad %= Math.PI;
	
	if (rad > Math.PI / 2)
	{
		rad = Math.PI - rad;
	}
	
	var cos = Math.cos(rad);
	var sin = Math.sin(-rad);

	var tx = w * -(dx + 0.5);
	var ty = h * -(dy + 0.5);

	var top_fix = (h - h * cos + w * sin) / 2 + real_sin * tx - real_cos * ty;
	var left_fix = (w - w * cos + h * sin) / 2 - real_cos * tx - real_sin * ty;
	
	if (rad != 0)
	{
		var f = 'progid:DXImageTransform.Microsoft.Matrix(M11=' + real_cos + ', M12='+
			real_sin + ', M21=' + (-real_sin) + ', M22=' + real_cos + ', sizingMethod=\'auto expand\')';
		
		if (style.filter != null && style.filter.length > 0)
		{
			style.filter += ' ' + f;
		}
		else
		{
			style.filter = f;
		}
	}
	
	// Workaround for rendering offsets
	var dy = 0;
	
	if (this.overflow != 'fill' && mxClient.IS_QUIRKS)
	{
		if (this.valign == mxConstants.ALIGN_TOP)
		{
			dy -= 1;
		}
		else if (this.valign == mxConstants.ALIGN_BOTTOM)
		{
			dy += 2;
		}
		else
		{
			dy += 1;
		}
	}

	style.zoom = s;
	style.left = Math.round(this.bounds.x + left_fix - w / 2) + 'px';
	style.top = Math.round(this.bounds.y + top_fix - h / 2 + dy) + 'px';
};

/**
 * Function: updateValue
 *
 * Updates the HTML node(s) to reflect the latest bounds and scale.
 */
mxText.prototype.updateValue = function()
{
	if (mxUtils.isNode(this.value))
	{
		this.node.innerHTML = '';
		this.node.appendChild(this.value);
	}
	else
	{
		var val = this.value;
		
		if (this.dialect != mxConstants.DIALECT_STRICTHTML)
		{
			val = mxUtils.htmlEntities(val, false);
		}
		
		// Handles trailing newlines to make sure they are visible in rendering output
		val = mxUtils.replaceTrailingNewlines(val, '<div><br></div>');
		val = (this.replaceLinefeeds) ? val.replace(/\n/g, '<br/>') : val;
		var bg = (this.background != null && this.background != mxConstants.NONE) ? this.background : null;
		var bd = (this.border != null && this.border != mxConstants.NONE) ? this.border : null;

		if (this.overflow == 'fill' || this.overflow == 'width')
		{
			if (bg != null)
			{
				this.node.style.backgroundColor = bg;
			}
			
			if (bd != null)
			{
				this.node.style.border = '1px solid ' + bd;
			}
		}
		else
		{
			var css = '';
			
			if (bg != null)
			{
				css += 'background-color:' + bg + ';';
			}
			
			if (bd != null)
			{
				css += 'border:1px solid ' + bd + ';';
			}
			
			// Wrapper DIV for background, zoom needed for inline in quirks
			// and to measure wrapped font sizes in all browsers
			// FIXME: Background size in quirks mode for wrapped text
			var lh = (mxConstants.ABSOLUTE_LINE_HEIGHT) ? (this.size * mxConstants.LINE_HEIGHT) + 'px' :
				mxConstants.LINE_HEIGHT;
			val = '<div style="zoom:1;' + css + 'display:inline-block;_display:inline;text-decoration:inherit;' +
				'padding-bottom:1px;padding-right:1px;line-height:' + lh + '">' + val + '</div>';
		}

		this.node.innerHTML = val;
		
		// Sets text direction
		var divs = this.node.getElementsByTagName('div');
		
		if (divs.length > 0)
		{
			var dir = this.textDirection;

			if (dir == mxConstants.TEXT_DIRECTION_AUTO && this.dialect != mxConstants.DIALECT_STRICTHTML)
			{
				dir = this.getAutoDirection();
			}
			
			if (dir == mxConstants.TEXT_DIRECTION_LTR || dir == mxConstants.TEXT_DIRECTION_RTL)
			{
				divs[divs.length - 1].setAttribute('dir', dir);
			}
			else
			{
				divs[divs.length - 1].removeAttribute('dir');
			}
		}
	}
};

/**
 * Function: updateFont
 *
 * Updates the HTML node(s) to reflect the latest bounds and scale.
 */
mxText.prototype.updateFont = function(node)
{
	var style = node.style;
	
	style.lineHeight = (mxConstants.ABSOLUTE_LINE_HEIGHT) ? (this.size * mxConstants.LINE_HEIGHT) + 'px' : mxConstants.LINE_HEIGHT;
	style.fontSize = this.size + 'px';
	style.fontFamily = this.family;
	style.verticalAlign = 'top';
	style.color = this.color;
	
	if ((this.fontStyle & mxConstants.FONT_BOLD) == mxConstants.FONT_BOLD)
	{
		style.fontWeight = 'bold';
	}
	else
	{
		style.fontWeight = '';
	}

	if ((this.fontStyle & mxConstants.FONT_ITALIC) == mxConstants.FONT_ITALIC)
	{
		style.fontStyle = 'italic';
	}
	else
	{
		style.fontStyle = '';
	}
	
	if ((this.fontStyle & mxConstants.FONT_UNDERLINE) == mxConstants.FONT_UNDERLINE)
	{
		style.textDecoration = 'underline';
	}
	else
	{
		style.textDecoration = '';
	}
	
	if (this.align == mxConstants.ALIGN_CENTER)
	{
		style.textAlign = 'center';
	}
	else if (this.align == mxConstants.ALIGN_RIGHT)
	{
		style.textAlign = 'right';
	}
	else
	{
		style.textAlign = 'left';
	}
};

/**
 * Function: updateSize
 *
 * Updates the HTML node(s) to reflect the latest bounds and scale.
 */
mxText.prototype.updateSize = function(node, enableWrap)
{
	var w = Math.max(0, Math.round(this.bounds.width / this.scale));
	var h = Math.max(0, Math.round(this.bounds.height / this.scale));
	var style = node.style;
	
	// NOTE: Do not use maxWidth here because wrapping will
	// go wrong if the cell is outside of the viewable area
	if (this.clipped)
	{
		style.overflow = 'hidden';
		
		if (!mxClient.IS_QUIRKS)
		{
			style.maxHeight = h + 'px';
			style.maxWidth = w + 'px';
		}
		else
		{
			style.width = w + 'px';
		}
	}
	else if (this.overflow == 'fill')
	{
		style.width = (w + 1) + 'px';
		style.height = (h + 1) + 'px';
		style.overflow = 'hidden';
	}
	else if (this.overflow == 'width')
	{
		style.width = (w + 1) + 'px';
		style.maxHeight = (h + 1) + 'px';
		style.overflow = 'hidden';
	}
	
	if (this.wrap && w > 0)
	{
		style.wordWrap = mxConstants.WORD_WRAP;
		style.whiteSpace = 'normal';
		style.width = w + 'px';

		if (enableWrap && this.overflow != 'fill' && this.overflow != 'width')
		{
			var sizeDiv = node;
			
			if (sizeDiv.firstChild != null && sizeDiv.firstChild.nodeName == 'DIV')
			{
				sizeDiv = sizeDiv.firstChild;
				
				if (node.style.wordWrap == 'break-word')
				{
					sizeDiv.style.width = '100%';
				}
			}
			
			var tmp = sizeDiv.offsetWidth;
			
			// Workaround for text measuring in hidden containers
			if (tmp == 0)
			{
				var prev = node.parentNode;
				node.style.visibility = 'hidden';
				document.body.appendChild(node);
				tmp = sizeDiv.offsetWidth;
				node.style.visibility = '';
				prev.appendChild(node);
			}

			tmp += 3;
			
			if (this.clipped)
			{
				tmp = Math.min(tmp, w);
			}
			
			style.width = tmp + 'px';
		}
	}
	else
	{
		style.whiteSpace = 'nowrap';
	}
};

/**
 * Function: getMargin
 *
 * Returns the spacing as an <mxPoint>.
 */
mxText.prototype.updateMargin = function()
{
	this.margin = mxUtils.getAlignmentAsPoint(this.align, this.valign);
};

/**
 * Function: getSpacing
 *
 * Returns the spacing as an <mxPoint>.
 */
mxText.prototype.getSpacing = function()
{
	var dx = 0;
	var dy = 0;

	if (this.align == mxConstants.ALIGN_CENTER)
	{
		dx = (this.spacingLeft - this.spacingRight) / 2;
	}
	else if (this.align == mxConstants.ALIGN_RIGHT)
	{
		dx = -this.spacingRight - this.baseSpacingRight;
	}
	else
	{
		dx = this.spacingLeft + this.baseSpacingLeft;
	}

	if (this.valign == mxConstants.ALIGN_MIDDLE)
	{
		dy = (this.spacingTop - this.spacingBottom) / 2;
	}
	else if (this.valign == mxConstants.ALIGN_BOTTOM)
	{
		dy = -this.spacingBottom - this.baseSpacingBottom;;
	}
	else
	{
		dy = this.spacingTop + this.baseSpacingTop;
	}
	
	return new mxPoint(dx, dy);
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxTriangle
 * 
 * Implementation of the triangle shape.
 * 
 * Constructor: mxTriangle
 *
 * Constructs a new triangle shape.
 */
function mxTriangle()
{
	mxActor.call(this);
};

/**
 * Extends mxActor.
 */
mxUtils.extend(mxTriangle, mxActor);

/**
 * Function: redrawPath
 *
 * Draws the path for this shape.
 */
mxTriangle.prototype.redrawPath = function(c, x, y, w, h)
{
	var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
	this.addPoints(c, [new mxPoint(0, 0), new mxPoint(w, 0.5 * h), new mxPoint(0, h)], this.isRounded, arcSize, true);
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxHexagon
 * 
 * Implementation of the hexagon shape.
 * 
 * Constructor: mxHexagon
 *
 * Constructs a new hexagon shape.
 */
function mxHexagon()
{
	mxActor.call(this);
};

/**
 * Extends mxActor.
 */
mxUtils.extend(mxHexagon, mxActor);

/**
 * Function: redrawPath
 *
 * Draws the path for this shape.
 */
mxHexagon.prototype.redrawPath = function(c, x, y, w, h)
{
	var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
	this.addPoints(c, [new mxPoint(0.25 * w, 0), new mxPoint(0.75 * w, 0), new mxPoint(w, 0.5 * h), new mxPoint(0.75 * w, h),
	                   new mxPoint(0.25 * w, h), new mxPoint(0, 0.5 * h)], this.isRounded, arcSize, true);
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxLine
 *
 * Extends <mxShape> to implement a horizontal line shape.
 * This shape is registered under <mxConstants.SHAPE_LINE> in
 * <mxCellRenderer>.
 * 
 * Constructor: mxLine
 *
 * Constructs a new line shape.
 * 
 * Parameters:
 * 
 * bounds - <mxRectangle> that defines the bounds. This is stored in
 * <mxShape.bounds>.
 * stroke - String that defines the stroke color. Default is 'black'. This is
 * stored in <stroke>.
 * strokewidth - Optional integer that defines the stroke width. Default is
 * 1. This is stored in <strokewidth>.
 */
function mxLine(bounds, stroke, strokewidth)
{
	mxShape.call(this);
	this.bounds = bounds;
	this.stroke = stroke;
	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
};

/**
 * Extends mxShape.
 */
mxUtils.extend(mxLine, mxShape);

/**
 * Function: paintVertexShape
 * 
 * Redirects to redrawPath for subclasses to work.
 */
mxLine.prototype.paintVertexShape = function(c, x, y, w, h)
{
	var mid = y + h / 2;

	c.begin();
	c.moveTo(x, mid);
	c.lineTo(x + w, mid);
	c.stroke();
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxImageShape
 *
 * Extends <mxShape> to implement an image shape. This shape is registered
 * under <mxConstants.SHAPE_IMAGE> in <mxCellRenderer>.
 * 
 * Constructor: mxImageShape
 * 
 * Constructs a new image shape.
 * 
 * Parameters:
 * 
 * bounds - <mxRectangle> that defines the bounds. This is stored in
 * <mxShape.bounds>.
 * image - String that specifies the URL of the image. This is stored in
 * <image>.
 * fill - String that defines the fill color. This is stored in <fill>.
 * stroke - String that defines the stroke color. This is stored in <stroke>.
 * strokewidth - Optional integer that defines the stroke width. Default is
 * 0. This is stored in <strokewidth>.
 */
function mxImageShape(bounds, image, fill, stroke, strokewidth)
{
	mxShape.call(this);
	this.bounds = bounds;
	this.image = image;
	this.fill = fill;
	this.stroke = stroke;
	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
	this.shadow = false;
};

/**
 * Extends mxShape.
 */
mxUtils.extend(mxImageShape, mxRectangleShape);

/**
 * Variable: preserveImageAspect
 *
 * Switch to preserve image aspect. Default is true.
 */
mxImageShape.prototype.preserveImageAspect = true;

/**
 * Function: getSvgScreenOffset
 * 
 * Disables offset in IE9 for crisper image output.
 */
mxImageShape.prototype.getSvgScreenOffset = function()
{
	return 0;
};

/**
 * Function: apply
 * 
 * Overrides <mxShape.apply> to replace the fill and stroke colors with the
 * respective values from <mxConstants.STYLE_IMAGE_BACKGROUND> and
 * <mxConstants.STYLE_IMAGE_BORDER>.
 * 
 * Applies the style of the given <mxCellState> to the shape. This
 * implementation assigns the following styles to local fields:
 * 
 * - <mxConstants.STYLE_IMAGE_BACKGROUND> => fill
 * - <mxConstants.STYLE_IMAGE_BORDER> => stroke
 *
 * Parameters:
 *
 * state - <mxCellState> of the corresponding cell.
 */
mxImageShape.prototype.apply = function(state)
{
	mxShape.prototype.apply.apply(this, arguments);
	
	this.fill = null;
	this.stroke = null;
	this.gradient = null;
	
	if (this.style != null)
	{
		this.preserveImageAspect = mxUtils.getNumber(this.style, mxConstants.STYLE_IMAGE_ASPECT, 1) == 1;
		
		// Legacy support for imageFlipH/V
		this.flipH = this.flipH || mxUtils.getValue(this.style, 'imageFlipH', 0) == 1;
		this.flipV = this.flipV || mxUtils.getValue(this.style, 'imageFlipV', 0) == 1;
	}
};

/**
 * Function: isHtmlAllowed
 * 
 * Returns true if HTML is allowed for this shape. This implementation always
 * returns false.
 */
mxImageShape.prototype.isHtmlAllowed = function()
{
	return !this.preserveImageAspect;
};

/**
 * Function: createHtml
 *
 * Creates and returns the HTML DOM node(s) to represent
 * this shape. This implementation falls back to <createVml>
 * so that the HTML creation is optional.
 */
mxImageShape.prototype.createHtml = function()
{
	var node = document.createElement('div');
	node.style.position = 'absolute';

	return node;
};

/**
 * Function: paintVertexShape
 * 
 * Generic background painting implementation.
 */
mxImageShape.prototype.paintVertexShape = function(c, x, y, w, h)
{
	if (this.image != null)
	{
		var fill = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_BACKGROUND, null);
		var stroke = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_BORDER, null);
		
		if (fill != null)
		{
			// Stroke rendering required for shadow
			c.setFillColor(fill);
			c.setStrokeColor(stroke);
			c.rect(x, y, w, h);
			c.fillAndStroke();
		}

		// FlipH/V are implicit via mxShape.updateTransform
		c.image(x, y, w, h, this.image, this.preserveImageAspect, false, false);
		
		var stroke = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_BORDER, null);
		
		if (stroke != null)
		{
			c.setShadow(false);
			c.setStrokeColor(stroke);
			c.rect(x, y, w, h);
			c.stroke();
		}
	}
	else
	{
		mxRectangleShape.prototype.paintBackground.apply(this, arguments);
	}
};

/**
 * Function: redraw
 * 
 * Overrides <mxShape.redraw> to preserve the aspect ratio of images.
 */
mxImageShape.prototype.redrawHtmlShape = function()
{
	this.node.style.left = Math.round(this.bounds.x) + 'px';
	this.node.style.top = Math.round(this.bounds.y) + 'px';
	this.node.style.width = Math.max(0, Math.round(this.bounds.width)) + 'px';
	this.node.style.height = Math.max(0, Math.round(this.bounds.height)) + 'px';
	this.node.innerHTML = '';

	if (this.image != null)
	{
		var fill = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_BACKGROUND, '');
		var stroke = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_BORDER, '');
		this.node.style.backgroundColor = fill;
		this.node.style.borderColor = stroke;
		
		// VML image supports PNG in IE6
		var useVml = mxClient.IS_IE6 || ((document.documentMode == null || document.documentMode <= 8) && this.rotation != 0);
		var img = document.createElement((useVml) ? mxClient.VML_PREFIX + ':image' : 'img');
		img.setAttribute('border', '0');
		img.style.position = 'absolute';
		img.src = this.image;

		var filter = (this.opacity < 100) ? 'alpha(opacity=' + this.opacity + ')' : '';
		this.node.style.filter = filter;
		
		if (this.flipH && this.flipV)
		{
			filter += 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2)';
		}
		else if (this.flipH)
		{
			filter += 'progid:DXImageTransform.Microsoft.BasicImage(mirror=1)';
		}
		else if (this.flipV)
		{
			filter += 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)';
		}

		if (img.style.filter != filter)
		{
			img.style.filter = filter;
		}

		if (img.nodeName == 'image')
		{
			img.style.rotation = this.rotation;
		}
		else if (this.rotation != 0)
		{
			// LATER: Add flipV/H support
			mxUtils.setPrefixedStyle(img.style, 'transform', 'rotate(' + this.rotation + 'deg)');
		}
		else
		{
			mxUtils.setPrefixedStyle(img.style, 'transform', '');
		}

		// Known problem: IE clips top line of image for certain angles
		img.style.width = this.node.style.width;
		img.style.height = this.node.style.height;
		
		this.node.style.backgroundImage = '';
		this.node.appendChild(img);
	}
	else
	{
		this.setTransparentBackgroundImage(this.node);
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxLabel
 *
 * Extends <mxShape> to implement an image shape with a label.
 * This shape is registered under <mxConstants.SHAPE_LABEL> in
 * <mxCellRenderer>.
 * 
 * Constructor: mxLabel
 *
 * Constructs a new label shape.
 * 
 * Parameters:
 * 
 * bounds - <mxRectangle> that defines the bounds. This is stored in
 * <mxShape.bounds>.
 * fill - String that defines the fill color. This is stored in <fill>.
 * stroke - String that defines the stroke color. This is stored in <stroke>.
 * strokewidth - Optional integer that defines the stroke width. Default is
 * 1. This is stored in <strokewidth>.
 */
function mxLabel(bounds, fill, stroke, strokewidth)
{
	mxRectangleShape.call(this, bounds, fill, stroke, strokewidth);
};

/**
 * Extends mxShape.
 */
mxUtils.extend(mxLabel, mxRectangleShape);

/**
 * Variable: imageSize
 *
 * Default width and height for the image. Default is
 * <mxConstants.DEFAULT_IMAGESIZE>.
 */
mxLabel.prototype.imageSize = mxConstants.DEFAULT_IMAGESIZE;

/**
 * Variable: spacing
 *
 * Default value for image spacing. Default is 2.
 */
mxLabel.prototype.spacing = 2;

/**
 * Variable: indicatorSize
 *
 * Default width and height for the indicicator. Default is 10.
 */
mxLabel.prototype.indicatorSize = 10;

/**
 * Variable: indicatorSpacing
 *
 * Default spacing between image and indicator. Default is 2.
 */
mxLabel.prototype.indicatorSpacing = 2;

/**
 * Function: init
 *
 * Initializes the shape and the <indicator>.
 */
mxLabel.prototype.init = function(container)
{
	mxShape.prototype.init.apply(this, arguments);

	if (this.indicatorShape != null)
	{
		this.indicator = new this.indicatorShape();
		this.indicator.dialect = this.dialect;
		this.indicator.init(this.node);
	}
};

/**
 * Function: redraw
 *
 * Reconfigures this shape. This will update the colors of the indicator
 * and reconfigure it if required.
 */
mxLabel.prototype.redraw = function()
{
	if (this.indicator != null)
	{
		this.indicator.fill = this.indicatorColor;
		this.indicator.stroke = this.indicatorStrokeColor;
		this.indicator.gradient = this.indicatorGradientColor;
		this.indicator.direction = this.indicatorDirection;
	}
	
	mxShape.prototype.redraw.apply(this, arguments);
};

/**
 * Function: isHtmlAllowed
 *
 * Returns true for non-rounded, non-rotated shapes with no glass gradient and
 * no indicator shape.
 */
mxLabel.prototype.isHtmlAllowed = function()
{
	return mxRectangleShape.prototype.isHtmlAllowed.apply(this, arguments) &&
		this.indicatorColor == null && this.indicatorShape == null;
};

/**
 * Function: paintForeground
 * 
 * Generic background painting implementation.
 */
mxLabel.prototype.paintForeground = function(c, x, y, w, h)
{
	this.paintImage(c, x, y, w, h);
	this.paintIndicator(c, x, y, w, h);
	
	mxRectangleShape.prototype.paintForeground.apply(this, arguments);
};

/**
 * Function: paintImage
 * 
 * Generic background painting implementation.
 */
mxLabel.prototype.paintImage = function(c, x, y, w, h)
{
	if (this.image != null)
	{
		var bounds = this.getImageBounds(x, y, w, h);
		c.image(bounds.x, bounds.y, bounds.width, bounds.height, this.image, false, false, false);
	}
};

/**
 * Function: getImageBounds
 * 
 * Generic background painting implementation.
 */
mxLabel.prototype.getImageBounds = function(x, y, w, h)
{
	var align = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_ALIGN, mxConstants.ALIGN_LEFT);
	var valign = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_VERTICAL_ALIGN, mxConstants.ALIGN_MIDDLE);
	var width = mxUtils.getNumber(this.style, mxConstants.STYLE_IMAGE_WIDTH, mxConstants.DEFAULT_IMAGESIZE);
	var height = mxUtils.getNumber(this.style, mxConstants.STYLE_IMAGE_HEIGHT, mxConstants.DEFAULT_IMAGESIZE);
	var spacing = mxUtils.getNumber(this.style, mxConstants.STYLE_SPACING, this.spacing) + 5;

	if (align == mxConstants.ALIGN_CENTER)
	{
		x += (w - width) / 2;
	}
	else if (align == mxConstants.ALIGN_RIGHT)
	{
		x += w - width - spacing;
	}
	else // default is left
	{
		x += spacing;
	}

	if (valign == mxConstants.ALIGN_TOP)
	{
		y += spacing;
	}
	else if (valign == mxConstants.ALIGN_BOTTOM)
	{
		y += h - height - spacing;
	}
	else // default is middle
	{
		y += (h - height) / 2;
	}
	
	return new mxRectangle(x, y, width, height);
};

/**
 * Function: paintIndicator
 * 
 * Generic background painting implementation.
 */
mxLabel.prototype.paintIndicator = function(c, x, y, w, h)
{
	if (this.indicator != null)
	{
		this.indicator.bounds = this.getIndicatorBounds(x, y, w, h);
		this.indicator.paint(c);
	}
	else if (this.indicatorImage != null)
	{
		var bounds = this.getIndicatorBounds(x, y, w, h);
		c.image(bounds.x, bounds.y, bounds.width, bounds.height, this.indicatorImage, false, false, false);
	}
};

/**
 * Function: getIndicatorBounds
 * 
 * Generic background painting implementation.
 */
mxLabel.prototype.getIndicatorBounds = function(x, y, w, h)
{
	var align = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_ALIGN, mxConstants.ALIGN_LEFT);
	var valign = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_VERTICAL_ALIGN, mxConstants.ALIGN_MIDDLE);
	var width = mxUtils.getNumber(this.style, mxConstants.STYLE_INDICATOR_WIDTH, this.indicatorSize);
	var height = mxUtils.getNumber(this.style, mxConstants.STYLE_INDICATOR_HEIGHT, this.indicatorSize);
	var spacing = this.spacing + 5;		
	
	if (align == mxConstants.ALIGN_RIGHT)
	{
		x += w - width - spacing;
	}
	else if (align == mxConstants.ALIGN_CENTER)
	{
		x += (w - width) / 2;
	}
	else // default is left
	{
		x += spacing;
	}
	
	if (valign == mxConstants.ALIGN_BOTTOM)
	{
		y += h - height - spacing;
	}
	else if (valign == mxConstants.ALIGN_TOP)
	{
		y += spacing;
	}
	else // default is middle
	{
		y += (h - height) / 2;
	}
	
	return new mxRectangle(x, y, width, height);
};
/**
 * Function: redrawHtmlShape
 * 
 * Generic background painting implementation.
 */
mxLabel.prototype.redrawHtmlShape = function()
{
	mxRectangleShape.prototype.redrawHtmlShape.apply(this, arguments);
	
	// Removes all children
	while(this.node.hasChildNodes())
	{
		this.node.removeChild(this.node.lastChild);
	}
	
	if (this.image != null)
	{
		var node = document.createElement('img');
		node.style.position = 'relative';
		node.setAttribute('border', '0');
		
		var bounds = this.getImageBounds(this.bounds.x, this.bounds.y, this.bounds.width, this.bounds.height);
		bounds.x -= this.bounds.x;
		bounds.y -= this.bounds.y;

		node.style.left = Math.round(bounds.x) + 'px';
		node.style.top = Math.round(bounds.y) + 'px';
		node.style.width = Math.round(bounds.width) + 'px';
		node.style.height = Math.round(bounds.height) + 'px';
		
		node.src = this.image;
		
		this.node.appendChild(node);
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxCylinder
 *
 * Extends <mxShape> to implement an cylinder shape. If a
 * custom shape with one filled area and an overlay path is
 * needed, then this shape's <redrawPath> should be overridden.
 * This shape is registered under <mxConstants.SHAPE_CYLINDER>
 * in <mxCellRenderer>.
 * 
 * Constructor: mxCylinder
 *
 * Constructs a new cylinder shape.
 * 
 * Parameters:
 * 
 * bounds - <mxRectangle> that defines the bounds. This is stored in
 * <mxShape.bounds>.
 * fill - String that defines the fill color. This is stored in <fill>.
 * stroke - String that defines the stroke color. This is stored in <stroke>.
 * strokewidth - Optional integer that defines the stroke width. Default is
 * 1. This is stored in <strokewidth>.
 */
function mxCylinder(bounds, fill, stroke, strokewidth)
{
	mxShape.call(this);
	this.bounds = bounds;
	this.fill = fill;
	this.stroke = stroke;
	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
};

/**
 * Extends mxShape.
 */
mxUtils.extend(mxCylinder, mxShape);

/**
 * Variable: maxHeight
 *
 * Defines the maximum height of the top and bottom part
 * of the cylinder shape.
 */
mxCylinder.prototype.maxHeight = 40;

/**
 * Variable: svgStrokeTolerance
 *
 * Sets stroke tolerance to 0 for SVG.
 */
mxCylinder.prototype.svgStrokeTolerance = 0;

/**
 * Function: paintVertexShape
 * 
 * Redirects to redrawPath for subclasses to work.
 */
mxCylinder.prototype.paintVertexShape = function(c, x, y, w, h)
{
	c.translate(x, y);
	c.begin();
	this.redrawPath(c, x, y, w, h, false);
	c.fillAndStroke();
	
	c.setShadow(false);
	
	c.begin();
	this.redrawPath(c, x, y, w, h, true);
	c.stroke();
};

/**
 * Function: redrawPath
 *
 * Draws the path for this shape.
 */
mxCylinder.prototype.redrawPath = function(c, x, y, w, h, isForeground)
{
	var dy = Math.min(this.maxHeight, Math.round(h / 5));
	
	if ((isForeground && this.fill != null) || (!isForeground && this.fill == null))
	{
		c.moveTo(0, dy);
		c.curveTo(0, 2 * dy, w, 2 * dy, w, dy);
		
		// Needs separate shapes for correct hit-detection
		if (!isForeground)
		{
			c.stroke();
			c.begin();
		}
	}
	
	if (!isForeground)
	{
		c.moveTo(0, dy);
		c.curveTo(0, -dy / 3, w, -dy / 3, w, dy);
		c.lineTo(w, h - dy);
		c.curveTo(w, h + dy / 3, 0, h + dy / 3, 0, h - dy);
		c.close();
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxConnector
 * 
 * Extends <mxShape> to implement a connector shape. The connector
 * shape allows for arrow heads on either side.
 * 
 * This shape is registered under <mxConstants.SHAPE_CONNECTOR> in
 * <mxCellRenderer>.
 * 
 * Constructor: mxConnector
 * 
 * Constructs a new connector shape.
 * 
 * Parameters:
 * 
 * points - Array of <mxPoints> that define the points. This is stored in
 * <mxShape.points>.
 * stroke - String that defines the stroke color. This is stored in <stroke>.
 * Default is 'black'.
 * strokewidth - Optional integer that defines the stroke width. Default is
 * 1. This is stored in <strokewidth>.
 */
function mxConnector(points, stroke, strokewidth)
{
	mxPolyline.call(this, points, stroke, strokewidth);
};

/**
 * Extends mxPolyline.
 */
mxUtils.extend(mxConnector, mxPolyline);

/**
 * Function: updateBoundingBox
 *
 * Updates the <boundingBox> for this shape using <createBoundingBox> and
 * <augmentBoundingBox> and stores the result in <boundingBox>.
 */
mxConnector.prototype.updateBoundingBox = function()
{
	this.useSvgBoundingBox = this.style != null && this.style[mxConstants.STYLE_CURVED] == 1;
	mxShape.prototype.updateBoundingBox.apply(this, arguments);
};

/**
 * Function: paintEdgeShape
 * 
 * Paints the line shape.
 */
mxConnector.prototype.paintEdgeShape = function(c, pts)
{
	// The indirection via functions for markers is needed in
	// order to apply the offsets before painting the line and
	// paint the markers after painting the line.
	var sourceMarker = this.createMarker(c, pts, true);
	var targetMarker = this.createMarker(c, pts, false);

	mxPolyline.prototype.paintEdgeShape.apply(this, arguments);
	
	// Disables shadows, dashed styles and fixes fill color for markers
	c.setFillColor(this.stroke);
	c.setShadow(false);
	c.setDashed(false);
	
	if (sourceMarker != null)
	{
		sourceMarker();
	}
	
	if (targetMarker != null)
	{
		targetMarker();
	}
};

/**
 * Function: createMarker
 * 
 * Prepares the marker by adding offsets in pts and returning a function to
 * paint the marker.
 */
mxConnector.prototype.createMarker = function(c, pts, source)
{
	var result = null;
	var n = pts.length;
	var type = mxUtils.getValue(this.style, (source) ? mxConstants.STYLE_STARTARROW : mxConstants.STYLE_ENDARROW);
	var p0 = (source) ? pts[1] : pts[n - 2];
	var pe = (source) ? pts[0] : pts[n - 1];
	
	if (type != null && p0 != null && pe != null)
	{
		var count = 1;
		
		// Uses next non-overlapping point
		while (count < n - 1 && Math.round(p0.x - pe.x) == 0 && Math.round(p0.y - pe.y) == 0)
		{
			p0 = (source) ? pts[1 + count] : pts[n - 2 - count];
			count++;
		}
	
		// Computes the norm and the inverse norm
		var dx = pe.x - p0.x;
		var dy = pe.y - p0.y;
	
		var dist = Math.max(1, Math.sqrt(dx * dx + dy * dy));
		
		var unitX = dx / dist;
		var unitY = dy / dist;
	
		var size = mxUtils.getNumber(this.style, (source) ? mxConstants.STYLE_STARTSIZE : mxConstants.STYLE_ENDSIZE, mxConstants.DEFAULT_MARKERSIZE);
		
		// Allow for stroke width in the end point used and the 
		// orthogonal vectors describing the direction of the marker
		var filled = this.style[(source) ? mxConstants.STYLE_STARTFILL : mxConstants.STYLE_ENDFILL] != 0;
		
		result = mxMarker.createMarker(c, this, type, pe, unitX, unitY, size, source, this.strokewidth, filled);
	}
	
	return result;
};

/**
 * Function: augmentBoundingBox
 *
 * Augments the bounding box with the strokewidth and shadow offsets.
 */
mxConnector.prototype.augmentBoundingBox = function(bbox)
{
	mxShape.prototype.augmentBoundingBox.apply(this, arguments);
	
	// Adds marker sizes
	var size = 0;
	
	if (mxUtils.getValue(this.style, mxConstants.STYLE_STARTARROW, mxConstants.NONE) != mxConstants.NONE)
	{
		size = mxUtils.getNumber(this.style, mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_MARKERSIZE) + 1;
	}
	
	if (mxUtils.getValue(this.style, mxConstants.STYLE_ENDARROW, mxConstants.NONE) != mxConstants.NONE)
	{
		size = Math.max(size, mxUtils.getNumber(this.style, mxConstants.STYLE_ENDSIZE, mxConstants.DEFAULT_MARKERSIZE)) + 1;
	}
	
	bbox.grow(size * this.scale);
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxSwimlane
 *
 * Extends <mxShape> to implement a swimlane shape. This shape is registered
 * under <mxConstants.SHAPE_SWIMLANE> in <mxCellRenderer>. Use the
 * <mxConstants.STYLE_STYLE_STARTSIZE> to define the size of the title
 * region, <mxConstants.STYLE_SWIMLANE_FILLCOLOR> for the content area fill,
 * <mxConstants.STYLE_SEPARATORCOLOR> to draw an additional vertical separator
 * and <mxConstants.STYLE_SWIMLANE_LINE> to hide the line between the title
 * region and the content area. The <mxConstants.STYLE_HORIZONTAL> affects
 * the orientation of this shape, not only its label.
 * 
 * Constructor: mxSwimlane
 *
 * Constructs a new swimlane shape.
 * 
 * Parameters:
 * 
 * bounds - <mxRectangle> that defines the bounds. This is stored in
 * <mxShape.bounds>.
 * fill - String that defines the fill color. This is stored in <fill>.
 * stroke - String that defines the stroke color. This is stored in <stroke>.
 * strokewidth - Optional integer that defines the stroke width. Default is
 * 1. This is stored in <strokewidth>.
 */
function mxSwimlane(bounds, fill, stroke, strokewidth)
{
	mxShape.call(this);
	this.bounds = bounds;
	this.fill = fill;
	this.stroke = stroke;
	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
};

/**
 * Extends mxShape.
 */
mxUtils.extend(mxSwimlane, mxShape);

/**
 * Variable: imageSize
 *
 * Default imagewidth and imageheight if an image but no imagewidth
 * and imageheight are defined in the style. Value is 16.
 */
mxSwimlane.prototype.imageSize = 16;

/**
 * Function: getGradientBounds
 * 
 * Returns the bounding box for the gradient box for this shape.
 */
mxSwimlane.prototype.getTitleSize = function()
{
	return Math.max(0, mxUtils.getValue(this.style, mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_STARTSIZE));
};

/**
 * Function: getGradientBounds
 * 
 * Returns the bounding box for the gradient box for this shape.
 */
mxSwimlane.prototype.getLabelBounds = function(rect)
{
	var start = this.getTitleSize();
	var bounds = new mxRectangle(rect.x, rect.y, rect.width, rect.height);
	var horizontal = this.isHorizontal();
	
	var flipH = mxUtils.getValue(this.style, mxConstants.STYLE_FLIPH, 0) == 1;
	var flipV = mxUtils.getValue(this.style, mxConstants.STYLE_FLIPV, 0) == 1;	
	
	// East is default
	var shapeVertical = (this.direction == mxConstants.DIRECTION_NORTH ||
			this.direction == mxConstants.DIRECTION_SOUTH);
	var realHorizontal = horizontal == !shapeVertical;
	
	var realFlipH = !realHorizontal && flipH != (this.direction == mxConstants.DIRECTION_SOUTH ||
			this.direction == mxConstants.DIRECTION_WEST);
	var realFlipV = realHorizontal && flipV != (this.direction == mxConstants.DIRECTION_SOUTH ||
			this.direction == mxConstants.DIRECTION_WEST);

	// Shape is horizontal
	if (!shapeVertical)
	{
		var tmp = Math.min(bounds.height, start * this.scale);

		if (realFlipH || realFlipV)
		{
			bounds.y += bounds.height - tmp;
		}

		bounds.height = tmp;
	}
	else
	{
		var tmp = Math.min(bounds.width, start * this.scale);
		
		if (realFlipH || realFlipV)
		{
			bounds.x += bounds.width - tmp;	
		}

		bounds.width = tmp;
	}
	
	return bounds;
};

/**
 * Function: getGradientBounds
 * 
 * Returns the bounding box for the gradient box for this shape.
 */
mxSwimlane.prototype.getGradientBounds = function(c, x, y, w, h)
{
	var start = this.getTitleSize();
	
	if (this.isHorizontal())
	{
		start = Math.min(start, h);
		return new mxRectangle(x, y, w, start);
	}
	else
	{
		start = Math.min(start, w);
		return new mxRectangle(x, y, start, h);
	}
};

/**
 * Function: getArcSize
 * 
 * Returns the arcsize for the swimlane.
 */
mxSwimlane.prototype.getArcSize = function(w, h, start)
{
	var f = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.RECTANGLE_ROUNDING_FACTOR * 100) / 100;

	return start * f * 3; 
};

/**
 * Function: paintVertexShape
 *
 * Paints the swimlane vertex shape.
 */
mxSwimlane.prototype.isHorizontal = function()
{
	return mxUtils.getValue(this.style, mxConstants.STYLE_HORIZONTAL, 1) == 1;
};

/**
 * Function: paintVertexShape
 *
 * Paints the swimlane vertex shape.
 */
mxSwimlane.prototype.paintVertexShape = function(c, x, y, w, h)
{
	var start = this.getTitleSize();
	var fill = mxUtils.getValue(this.style, mxConstants.STYLE_SWIMLANE_FILLCOLOR, mxConstants.NONE);
	var swimlaneLine = mxUtils.getValue(this.style, mxConstants.STYLE_SWIMLANE_LINE, 1) == 1;
	var r = 0;
	
	if (this.isHorizontal())
	{
		start = Math.min(start, h);
	}
	else
	{
		start = Math.min(start, w);
	}
	
	c.translate(x, y);
	
	if (!this.isRounded)
	{
		this.paintSwimlane(c, x, y, w, h, start, fill, swimlaneLine);
	}
	else
	{
		r = this.getArcSize(w, h, start);
		this.paintRoundedSwimlane(c, x, y, w, h, start, r, fill, swimlaneLine);
	}
	
	var sep = mxUtils.getValue(this.style, mxConstants.STYLE_SEPARATORCOLOR, mxConstants.NONE);
	this.paintSeparator(c, x, y, w, h, start, sep);

	if (this.image != null)
	{
		var bounds = this.getImageBounds(x, y, w, h);
		c.image(bounds.x - x, bounds.y - y, bounds.width, bounds.height,
				this.image, false, false, false);
	}
	
	if (this.glass)
	{
		c.setShadow(false);
		this.paintGlassEffect(c, 0, 0, w, start, r);
	}
};

/**
 * Function: paintSwimlane
 *
 * Paints the swimlane vertex shape.
 */
mxSwimlane.prototype.paintSwimlane = function(c, x, y, w, h, start, fill, swimlaneLine)
{
	if (fill != mxConstants.NONE)
	{
		c.save();
		c.setFillColor(fill);
		c.rect(0, 0, w, h);
		c.fillAndStroke();
		c.restore();
		c.setShadow(false);
	}

	c.begin();
	
	if (this.isHorizontal())
	{
		c.moveTo(0, start);
		c.lineTo(0, 0);
		c.lineTo(w, 0);
		c.lineTo(w, start);
		
		if (swimlaneLine || start >= h)
		{
			c.close();
		}
		
		c.fillAndStroke();
		
		// Transparent content area
		if (start < h && fill == mxConstants.NONE)
		{
			c.pointerEvents = false;
			
			c.begin();
			c.moveTo(0, start);
			c.lineTo(0, h);
			c.lineTo(w, h);
			c.lineTo(w, start);
			c.stroke();
		}
	}
	else
	{
		c.moveTo(start, 0);
		c.lineTo(0, 0);
		c.lineTo(0, h);
		c.lineTo(start, h);
		
		if (swimlaneLine || start >= w)
		{
			c.close();
		}
		
		c.fillAndStroke();
		
		// Transparent content area
		if (start < w && fill == mxConstants.NONE)
		{
			c.pointerEvents = false;
			
			c.begin();
			c.moveTo(start, 0);
			c.lineTo(w, 0);
			c.lineTo(w, h);
			c.lineTo(start, h);
			c.stroke();
		}
	}
};

/**
 * Function: paintRoundedSwimlane
 *
 * Paints the swimlane vertex shape.
 */
mxSwimlane.prototype.paintRoundedSwimlane = function(c, x, y, w, h, start, r, fill, swimlaneLine)
{
	r = Math.min(h - start, Math.min(start, r));
	
	if (fill != mxConstants.NONE)
	{
		c.save();
		c.setFillColor(fill);
		c.roundrect(0, 0, w, h, r, r);
		c.fillAndStroke();
		c.restore();
		c.setShadow(false);
	}
	
	c.begin();
	
	if (this.isHorizontal())
	{
		c.moveTo(w, start);
		c.lineTo(w, r);
		c.quadTo(w, 0, w - Math.min(w / 2, r), 0);
		c.lineTo(Math.min(w / 2, r), 0);
		c.quadTo(0, 0, 0, r);
		c.lineTo(0, start);
		
		if (swimlaneLine || start >= h)
		{
			c.close();
		}
	
		c.fillAndStroke();
		
		// Transparent content area
		if (start < h && fill == mxConstants.NONE)
		{
			c.pointerEvents = false;
			
			c.begin();
			c.moveTo(0, start);
			c.lineTo(0, h - r);
			c.quadTo(0, h, Math.min(w / 2, r), h);
			c.lineTo(w - Math.min(w / 2, r), h);
			c.quadTo(w, h, w, h - r);
			c.lineTo(w, start);
			c.stroke();
		}
	}
	else
	{
		c.moveTo(start, 0);
		c.lineTo(r, 0);
		c.quadTo(0, 0, 0, Math.min(h / 2, r));
		c.lineTo(0, h - Math.min(h / 2, r));
		c.quadTo(0, h, r, h);
		c.lineTo(start, h);
		
		if (swimlaneLine || start >= w)
		{
			c.close();
		}
	
		c.fillAndStroke();
		
		// Transparent content area
		if (start < w && fill == mxConstants.NONE)
		{
			c.pointerEvents = false;
			
			c.begin();
			c.moveTo(start, h);
			c.lineTo(w - r, h);
			c.quadTo(w, h, w, h - Math.min(h / 2, r));
			c.lineTo(w, Math.min(h / 2, r));
			c.quadTo(w, 0, w - r, 0);
			c.lineTo(start, 0);
			c.stroke();
		}
	}
};

/**
 * Function: paintSwimlane
 *
 * Paints the swimlane vertex shape.
 */
mxSwimlane.prototype.paintSeparator = function(c, x, y, w, h, start, color)
{
	if (color != mxConstants.NONE)
	{
		c.setStrokeColor(color);
		c.setDashed(true);
		c.begin();
		
		if (this.isHorizontal())
		{
			c.moveTo(w, start);
			c.lineTo(w, h);
		}
		else
		{
			c.moveTo(start, 0);
			c.lineTo(w, 0);
		}
		
		c.stroke();
		c.setDashed(false);
	}
};

/**
 * Function: getImageBounds
 *
 * Paints the swimlane vertex shape.
 */
mxSwimlane.prototype.getImageBounds = function(x, y, w, h)
{
	if (this.isHorizontal())
	{
		return new mxRectangle(x + w - this.imageSize, y, this.imageSize, this.imageSize);
	}
	else
	{
		return new mxRectangle(x, y, this.imageSize, this.imageSize);
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxGraphLayout
 * 
 * Base class for all layout algorithms in mxGraph. Main public functions are
 * <move> for handling a moved cell within a layouted parent, and <execute> for
 * running the layout on a given parent cell.
 *
 * Known Subclasses:
 *
 * <mxCircleLayout>, <mxCompactTreeLayout>, <mxCompositeLayout>,
 * <mxFastOrganicLayout>, <mxParallelEdgeLayout>, <mxPartitionLayout>,
 * <mxStackLayout>
 * 
 * Constructor: mxGraphLayout
 *
 * Constructs a new layout using the given layouts.
 *
 * Arguments:
 * 
 * graph - Enclosing 
 */
function mxGraphLayout(graph)
{
	this.graph = graph;
};

/**
 * Variable: graph
 * 
 * Reference to the enclosing <mxGraph>.
 */
mxGraphLayout.prototype.graph = null;

/**
 * Variable: useBoundingBox
 *
 * Boolean indicating if the bounding box of the label should be used if
 * its available. Default is true.
 */
mxGraphLayout.prototype.useBoundingBox = true;

/**
 * Variable: parent
 *
 * The parent cell of the layout, if any
 */
mxGraphLayout.prototype.parent = null;

/**
 * Function: moveCell
 * 
 * Notified when a cell is being moved in a parent that has automatic
 * layout to update the cell state (eg. index) so that the outcome of the
 * layout will position the vertex as close to the point (x, y) as
 * possible.
 * 
 * Empty implementation.
 * 
 * Parameters:
 * 
 * cell - <mxCell> which has been moved.
 * x - X-coordinate of the new cell location.
 * y - Y-coordinate of the new cell location.
 */
mxGraphLayout.prototype.moveCell = function(cell, x, y) { };

/**
 * Function: execute
 * 
 * Executes the layout algorithm for the children of the given parent.
 * 
 * Parameters:
 * 
 * parent - <mxCell> whose children should be layed out.
 */
mxGraphLayout.prototype.execute = function(parent) { };

/**
 * Function: getGraph
 * 
 * Returns the graph that this layout operates on.
 */
mxGraphLayout.prototype.getGraph = function()
{
	return this.graph;
};

/**
 * Function: getConstraint
 * 
 * Returns the constraint for the given key and cell. The optional edge and
 * source arguments are used to return inbound and outgoing routing-
 * constraints for the given edge and vertex. This implementation always
 * returns the value for the given key in the style of the given cell.
 * 
 * Parameters:
 * 
 * key - Key of the constraint to be returned.
 * cell - <mxCell> whose constraint should be returned.
 * edge - Optional <mxCell> that represents the connection whose constraint
 * should be returned. Default is null.
 * source - Optional boolean that specifies if the connection is incoming
 * or outgoing. Default is null.
 */
mxGraphLayout.prototype.getConstraint = function(key, cell, edge, source)
{
	var state = this.graph.view.getState(cell);
	var style = (state != null) ? state.style : this.graph.getCellStyle(cell);
	
	return (style != null) ? style[key] : null;
};

/**
 * Function: traverse
 * 
 * Traverses the (directed) graph invoking the given function for each
 * visited vertex and edge. The function is invoked with the current vertex
 * and the incoming edge as a parameter. This implementation makes sure
 * each vertex is only visited once. The function may return false if the
 * traversal should stop at the given vertex.
 * 
 * Example:
 * 
 * (code)
 * mxLog.show();
 * var cell = graph.getSelectionCell();
 * graph.traverse(cell, false, function(vertex, edge)
 * {
 *   mxLog.debug(graph.getLabel(vertex));
 * });
 * (end)
 * 
 * Parameters:
 * 
 * vertex - <mxCell> that represents the vertex where the traversal starts.
 * directed - Optional boolean indicating if edges should only be traversed
 * from source to target. Default is true.
 * func - Visitor function that takes the current vertex and the incoming
 * edge as arguments. The traversal stops if the function returns false.
 * edge - Optional <mxCell> that represents the incoming edge. This is
 * null for the first step of the traversal.
 * visited - Optional <mxDictionary> of cell paths for the visited cells.
 */
mxGraphLayout.traverse = function(vertex, directed, func, edge, visited)
{
	if (func != null && vertex != null)
	{
		directed = (directed != null) ? directed : true;
		visited = visited || new mxDictionary();
		
		if (!visited.get(vertex))
		{
			visited.put(vertex, true);
			var result = func(vertex, edge);
			
			if (result == null || result)
			{
				var edgeCount = this.graph.model.getEdgeCount(vertex);
				
				if (edgeCount > 0)
				{
					for (var i = 0; i < edgeCount; i++)
					{
						var e = this.graph.model.getEdgeAt(vertex, i);
						var isSource = this.graph.model.getTerminal(e, true) == vertex;
												
						if (!directed || isSource)
						{
							var next = this.graph.view.getVisibleTerminal(e, !isSource);
							this.traverse(next, directed, func, e, visited);
						}
					}
				}
			}
		}
	}
};

/**
 * Function: isVertexMovable
 * 
 * Returns a boolean indicating if the given <mxCell> is movable or
 * bendable by the algorithm. This implementation returns true if the given
 * cell is movable in the graph.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose movable state should be returned.
 */
mxGraphLayout.prototype.isVertexMovable = function(cell)
{
	return this.graph.isCellMovable(cell);
};

/**
 * Function: isVertexIgnored
 * 
 * Returns a boolean indicating if the given <mxCell> should be ignored by
 * the algorithm. This implementation returns false for all vertices.
 * 
 * Parameters:
 * 
 * vertex - <mxCell> whose ignored state should be returned.
 */
mxGraphLayout.prototype.isVertexIgnored = function(vertex)
{
	return !this.graph.getModel().isVertex(vertex) ||
		!this.graph.isCellVisible(vertex);
};

/**
 * Function: isEdgeIgnored
 * 
 * Returns a boolean indicating if the given <mxCell> should be ignored by
 * the algorithm. This implementation returns false for all vertices.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose ignored state should be returned.
 */
mxGraphLayout.prototype.isEdgeIgnored = function(edge)
{
	var model = this.graph.getModel();
	
	return !model.isEdge(edge) ||
		!this.graph.isCellVisible(edge) ||
		model.getTerminal(edge, true) == null ||
		model.getTerminal(edge, false) == null;
};

/**
 * Function: setEdgeStyleEnabled
 * 
 * Disables or enables the edge style of the given edge.
 */
mxGraphLayout.prototype.setEdgeStyleEnabled = function(edge, value)
{
	this.graph.setCellStyles(mxConstants.STYLE_NOEDGESTYLE,
			(value) ? '0' : '1', [edge]);
};

/**
 * Function: setOrthogonalEdge
 * 
 * Disables or enables orthogonal end segments of the given edge.
 */
mxGraphLayout.prototype.setOrthogonalEdge = function(edge, value)
{
	this.graph.setCellStyles(mxConstants.STYLE_ORTHOGONAL,
			(value) ? '1' : '0', [edge]);
};

/**
 * Function: getParentOffset
 * 
 * Determines the offset of the given parent to the parent
 * of the layout
 */
mxGraphLayout.prototype.getParentOffset = function(parent)
{
	var result = new mxPoint();

	if (parent != null && parent != this.parent)
	{
		var model = this.graph.getModel();

		if (model.isAncestor(this.parent, parent))
		{
			var parentGeo = model.getGeometry(parent);

			while (parent != this.parent)
			{
				result.x = result.x + parentGeo.x;
				result.y = result.y + parentGeo.y;

				parent = model.getParent(parent);;
				parentGeo = model.getGeometry(parent);
			}
		}
	}

	return result;
};

/**
 * Function: setEdgePoints
 * 
 * Replaces the array of mxPoints in the geometry of the given edge
 * with the given array of mxPoints.
 */
mxGraphLayout.prototype.setEdgePoints = function(edge, points)
{
	if (edge != null)
	{
		var model = this.graph.model;
		var geometry = model.getGeometry(edge);

		if (geometry == null)
		{
			geometry = new mxGeometry();
			geometry.setRelative(true);
		}
		else
		{
			geometry = geometry.clone();
		}

		if (this.parent != null && points != null)
		{
			var parent = model.getParent(edge);

			var parentOffset = this.getParentOffset(parent);

			for (var i = 0; i < points.length; i++)
			{
				points[i].x = points[i].x - parentOffset.x;
				points[i].y = points[i].y - parentOffset.y;
			}
		}

		geometry.points = points;
		model.setGeometry(edge, geometry);
	}
};

/**
 * Function: setVertexLocation
 * 
 * Sets the new position of the given cell taking into account the size of
 * the bounding box if <useBoundingBox> is true. The change is only carried
 * out if the new location is not equal to the existing location, otherwise
 * the geometry is not replaced with an updated instance. The new or old
 * bounds are returned (including overlapping labels).
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose geometry is to be set.
 * x - Integer that defines the x-coordinate of the new location.
 * y - Integer that defines the y-coordinate of the new location.
 */
mxGraphLayout.prototype.setVertexLocation = function(cell, x, y)
{
	var model = this.graph.getModel();
	var geometry = model.getGeometry(cell);
	var result = null;
	
	if (geometry != null)
	{
		result = new mxRectangle(x, y, geometry.width, geometry.height);
		
		// Checks for oversize labels and shifts the result
		// TODO: Use mxUtils.getStringSize for label bounds
		if (this.useBoundingBox)
		{
			var state = this.graph.getView().getState(cell);
			
			if (state != null && state.text != null && state.text.boundingBox != null)
			{
				var scale = this.graph.getView().scale;
				var box = state.text.boundingBox;
				
				if (state.text.boundingBox.x < state.x)
				{
					x += (state.x - box.x) / scale;
					result.width = box.width;
				}
				
				if (state.text.boundingBox.y < state.y)
				{
					y += (state.y - box.y) / scale;
					result.height = box.height;
				}
			}
		}

		if (this.parent != null)
		{
			var parent = model.getParent(cell);

			if (parent != null && parent != this.parent)
			{
				var parentOffset = this.getParentOffset(parent);

				x = x - parentOffset.x;
				y = y - parentOffset.y;
			}
		}

		if (geometry.x != x || geometry.y != y)
		{
			geometry = geometry.clone();
			geometry.x = x;
			geometry.y = y;
			
			model.setGeometry(cell, geometry);
		}
	}
	
	return result;
};

/**
 * Function: getVertexBounds
 * 
 * Returns an <mxRectangle> that defines the bounds of the given cell or
 * the bounding box if <useBoundingBox> is true.
 */
mxGraphLayout.prototype.getVertexBounds = function(cell)
{
	var geo = this.graph.getModel().getGeometry(cell);

	// Checks for oversize label bounding box and corrects
	// the return value accordingly
	// TODO: Use mxUtils.getStringSize for label bounds
	if (this.useBoundingBox)
	{
		var state = this.graph.getView().getState(cell);

		if (state != null && state.text != null && state.text.boundingBox != null)
		{
			var scale = this.graph.getView().scale;
			var tmp = state.text.boundingBox;

			var dx0 = Math.max(state.x - tmp.x, 0) / scale;
			var dy0 = Math.max(state.y - tmp.y, 0) / scale;
			var dx1 = Math.max((tmp.x + tmp.width) - (state.x + state.width), 0) / scale;
  			var dy1 = Math.max((tmp.y + tmp.height) - (state.y + state.height), 0) / scale;

			geo = new mxRectangle(geo.x - dx0, geo.y - dy0, geo.width + dx0 + dx1, geo.height + dy0 + dy1);
		}
	}

	if (this.parent != null)
	{
		var parent = this.graph.getModel().getParent(cell);
		geo = geo.clone();

		if (parent != null && parent != this.parent)
		{
			var parentOffset = this.getParentOffset(parent);
			geo.x = geo.x + parentOffset.x;
			geo.y = geo.y + parentOffset.y;
		}
	}

	return new mxRectangle(geo.x, geo.y, geo.width, geo.height);
};

/**
 * Function: arrangeGroups
 * 
 * Shortcut to <mxGraph.updateGroupBounds> with moveGroup set to true.
 */
mxGraphLayout.prototype.arrangeGroups = function(cells, border, topBorder, rightBorder, bottomBorder, leftBorder)
{
	return this.graph.updateGroupBounds(cells, border, true, topBorder, rightBorder, bottomBorder, leftBorder);
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxStackLayout
 * 
 * Extends <mxGraphLayout> to create a horizontal or vertical stack of the
 * child vertices. The children do not need to be connected for this layout
 * to work.
 * 
 * Example:
 * 
 * (code)
 * var layout = new mxStackLayout(graph, true);
 * layout.execute(graph.getDefaultParent());
 * (end)
 * 
 * Constructor: mxStackLayout
 * 
 * Constructs a new stack layout layout for the specified graph,
 * spacing, orientation and offset.
 */
function mxStackLayout(graph, horizontal, spacing, x0, y0, border)
{
	mxGraphLayout.call(this, graph);
	this.horizontal = (horizontal != null) ? horizontal : true;
	this.spacing = (spacing != null) ? spacing : 0;
	this.x0 = (x0 != null) ? x0 : 0;
	this.y0 = (y0 != null) ? y0 : 0;
	this.border = (border != null) ? border : 0;
};

/**
 * Extends mxGraphLayout.
 */
mxStackLayout.prototype = new mxGraphLayout();
mxStackLayout.prototype.constructor = mxStackLayout;

/**
 * Variable: horizontal
 *
 * Specifies the orientation of the layout. Default is true.
 */
mxStackLayout.prototype.horizontal = null;

/**
 * Variable: spacing
 *
 * Specifies the spacing between the cells. Default is 0.
 */
mxStackLayout.prototype.spacing = null;

/**
 * Variable: x0
 *
 * Specifies the horizontal origin of the layout. Default is 0.
 */
mxStackLayout.prototype.x0 = null;

/**
 * Variable: y0
 *
 * Specifies the vertical origin of the layout. Default is 0.
 */
mxStackLayout.prototype.y0 = null;

/**
 * Variable: border
 *
 * Border to be added if fill is true. Default is 0.
 */
mxStackLayout.prototype.border = 0;

/**
 * Variable: marginTop
 * 
 * Top margin for the child area. Default is 0.
 */
mxStackLayout.prototype.marginTop = 0;

/**
 * Variable: marginLeft
 * 
 * Top margin for the child area. Default is 0.
 */
mxStackLayout.prototype.marginLeft = 0;

/**
 * Variable: marginRight
 * 
 * Top margin for the child area. Default is 0.
 */
mxStackLayout.prototype.marginRight = 0;

/**
 * Variable: marginBottom
 * 
 * Top margin for the child area. Default is 0.
 */
mxStackLayout.prototype.marginBottom = 0;

/**
 * Variable: keepFirstLocation
 * 
 * Boolean indicating if the location of the first cell should be
 * kept, that is, it will not be moved to x0 or y0.
 */
mxStackLayout.prototype.keepFirstLocation = false;

/**
 * Variable: fill
 * 
 * Boolean indicating if dimension should be changed to fill out the parent
 * cell. Default is false.
 */
mxStackLayout.prototype.fill = false;
	
/**
 * Variable: resizeParent
 * 
 * If the parent should be resized to match the width/height of the
 * stack. Default is false.
 */
mxStackLayout.prototype.resizeParent = false;

/**
 * Variable: resizeParentMax
 * 
 * Use maximum of existing value and new value for resize of parent.
 * Default is false.
 */
mxStackLayout.prototype.resizeParentMax = false;

/**
 * Variable: resizeLast
 * 
 * If the last element should be resized to fill out the parent. Default is
 * false. If <resizeParent> is true then this is ignored.
 */
mxStackLayout.prototype.resizeLast = false;

/**
 * Variable: wrap
 * 
 * Value at which a new column or row should be created. Default is null.
 */
mxStackLayout.prototype.wrap = null;

/**
 * Variable: borderCollapse
 * 
 * If the strokeWidth should be ignored. Default is true.
 */
mxStackLayout.prototype.borderCollapse = true;

/**
 * Function: isHorizontal
 * 
 * Returns <horizontal>.
 */
mxStackLayout.prototype.isHorizontal = function()
{
	return this.horizontal;
};

/**
 * Function: moveCell
 * 
 * Implements <mxGraphLayout.moveCell>.
 */
mxStackLayout.prototype.moveCell = function(cell, x, y)
{
	var model = this.graph.getModel();
	var parent = model.getParent(cell);
	var horizontal = this.isHorizontal();
	
	if (cell != null && parent != null)
	{
		var i = 0;
		var last = 0;
		var childCount = model.getChildCount(parent);
		var value = (horizontal) ? x : y;
		var pstate = this.graph.getView().getState(parent);

		if (pstate != null)
		{
			value -= (horizontal) ? pstate.x : pstate.y;
		}
		
		value /= this.graph.view.scale;
		
		for (i = 0; i < childCount; i++)
		{
			var child = model.getChildAt(parent, i);
			
			if (child != cell)
			{
				var bounds = model.getGeometry(child);
				
				if (bounds != null)
				{
					var tmp = (horizontal) ?
						bounds.x + bounds.width / 2 :
						bounds.y + bounds.height / 2;
					
					if (last <= value && tmp > value)
					{
						break;
					}
					
					last = tmp;
				}
			}
		}

		// Changes child order in parent
		var idx = parent.getIndex(cell);
		idx = Math.max(0, i - ((i > idx) ? 1 : 0));

		model.add(parent, cell, idx);
	}
};

/**
 * Function: getParentSize
 * 
 * Returns the size for the parent container or the size of the graph
 * container if the parent is a layer or the root of the model.
 */
mxStackLayout.prototype.getParentSize = function(parent)
{
	var model = this.graph.getModel();			
	var pgeo = model.getGeometry(parent);
	
	// Handles special case where the parent is either a layer with no
	// geometry or the current root of the view in which case the size
	// of the graph's container will be used.
	if (this.graph.container != null && ((pgeo == null &&
		model.isLayer(parent)) || parent == this.graph.getView().currentRoot))
	{
		var width = this.graph.container.offsetWidth - 1;
		var height = this.graph.container.offsetHeight - 1;
		pgeo = new mxRectangle(0, 0, width, height);
	}
	
	return pgeo;
};

/**
 * Function: execute
 * 
 * Implements <mxGraphLayout.execute>.
 * 
 * Only children where <isVertexIgnored> returns false are taken into
 * account.
 */
mxStackLayout.prototype.execute = function(parent)
{
	if (parent != null)
	{
		var pgeo = this.getParentSize(parent);
		var horizontal = this.isHorizontal();
		var model = this.graph.getModel();	
		var fillValue = null;
		
		if (pgeo != null)
		{
			fillValue = (horizontal) ? pgeo.height - this.marginTop - this.marginBottom :
				pgeo.width - this.marginLeft - this.marginRight;
		}
		
		fillValue -= 2 * this.spacing + 2 * this.border;
		var x0 = this.x0 + this.border + this.marginLeft;
		var y0 = this.y0 + this.border + this.marginTop;
		
		// Handles swimlane start size
		if (this.graph.isSwimlane(parent))
		{
			// Uses computed style to get latest 
			var style = this.graph.getCellStyle(parent);
			var start = mxUtils.getNumber(style, mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_STARTSIZE);
			var horz = mxUtils.getValue(style, mxConstants.STYLE_HORIZONTAL, true) == 1;

			if (pgeo != null)
			{
				if (horz)
				{
					start = Math.min(start, pgeo.height);
				}
				else
				{
					start = Math.min(start, pgeo.width);
				}
			}
			
			if (horizontal == horz)
			{
				fillValue -= start;
			}

			if (horz)
			{
				y0 += start;
			}
			else
			{
				x0 += start;
			}
		}

		model.beginUpdate();
		try
		{
			var tmp = 0;
			var last = null;
			var lastValue = 0;
			var lastChild = null;
			var childCount = model.getChildCount(parent);
			
			for (var i = 0; i < childCount; i++)
			{
				var child = model.getChildAt(parent, i);
				
				if (!this.isVertexIgnored(child) && this.isVertexMovable(child))
				{
					var geo = model.getGeometry(child);
					
					if (geo != null)
					{
						geo = geo.clone();
						
						if (this.wrap != null && last != null)
						{
							if ((horizontal && last.x + last.width +
								geo.width + 2 * this.spacing > this.wrap) ||
								(!horizontal && last.y + last.height +
								geo.height + 2 * this.spacing > this.wrap))
							{
								last = null;
								
								if (horizontal)
								{
									y0 += tmp + this.spacing;
								}
								else
								{
									x0 += tmp + this.spacing;
								}
								
								tmp = 0;
							}	
						}
						
						tmp = Math.max(tmp, (horizontal) ? geo.height : geo.width);
						var sw = 0;
						
						if (!this.borderCollapse)
						{
							var childStyle = this.graph.getCellStyle(child);
							sw = mxUtils.getNumber(childStyle, mxConstants.STYLE_STROKEWIDTH, 1);
						}
						
						if (last != null)
						{
							if (horizontal)
							{
								geo.x = lastValue + this.spacing + Math.floor(sw / 2);
							}
							else
							{
								geo.y = lastValue + this.spacing + Math.floor(sw / 2);
							}
						}
						else if (!this.keepFirstLocation)
						{
							if (horizontal)
							{
								geo.x = x0;
							}
							else
							{
								geo.y = y0;
							}
						}
						
						if (horizontal)
						{
							geo.y = y0;
						}
						else
						{
							geo.x = x0;
						}
						
						if (this.fill && fillValue != null)
						{
							if (horizontal)
							{
								geo.height = fillValue;
							}
							else
							{
								geo.width = fillValue;									
							}
						}
						
						this.setChildGeometry(child, geo);
						lastChild = child;
						last = geo;
						
						if (horizontal)
						{
							lastValue = last.x + last.width + Math.floor(sw / 2);
						}
						else
						{
							lastValue = last.y + last.height + Math.floor(sw / 2);
						}
					}
				}
			}

			if (this.resizeParent && pgeo != null && last != null && !this.graph.isCellCollapsed(parent))
			{
				this.updateParentGeometry(parent, pgeo, last);
			}
			else if (this.resizeLast && pgeo != null && last != null && lastChild != null)
			{
				if (horizontal)
				{
					last.width = pgeo.width - last.x - this.spacing - this.marginRight - this.marginLeft;
				}
				else
				{
					last.height = pgeo.height - last.y - this.spacing - this.marginBottom;
				}
				
				this.setChildGeometry(lastChild, last);
			}
		}
		finally
		{
			model.endUpdate();
		}
	}
};

/**
 * Function: execute
 * 
 * Implements <mxGraphLayout.execute>.
 * 
 * Only children where <isVertexIgnored> returns false are taken into
 * account.
 */
mxStackLayout.prototype.setChildGeometry = function(child, geo)
{
	var geo2 = this.graph.getCellGeometry(child);
	
	if (geo2 == null || geo.x != geo2.x || geo.y != geo2.y ||
		geo.width != geo2.width || geo.height != geo2.height)
	{
		this.graph.getModel().setGeometry(child, geo);
	}
};

/**
 * Function: execute
 * 
 * Implements <mxGraphLayout.execute>.
 * 
 * Only children where <isVertexIgnored> returns false are taken into
 * account.
 */
mxStackLayout.prototype.updateParentGeometry = function(parent, pgeo, last)
{
	var horizontal = this.isHorizontal();
	var model = this.graph.getModel();	

	var pgeo2 = pgeo.clone();
	
	if (horizontal)
	{
		var tmp = last.x + last.width + this.spacing + this.marginRight;
		
		if (this.resizeParentMax)
		{
			pgeo2.width = Math.max(pgeo2.width, tmp);
		}
		else
		{
			pgeo2.width = tmp;
		}
	}
	else
	{
		var tmp = last.y + last.height + this.spacing + this.marginBottom;
		
		if (this.resizeParentMax)
		{
			pgeo2.height = Math.max(pgeo2.height, tmp);
		}
		else
		{
			pgeo2.height = tmp;
		}
	}
	
	if (pgeo.x != pgeo2.x || pgeo.y != pgeo2.y ||
		pgeo.width != pgeo2.width || pgeo.height != pgeo2.height)
	{
		model.setGeometry(parent, pgeo2);
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxPartitionLayout
 * 
 * Extends <mxGraphLayout> for partitioning the parent cell vertically or
 * horizontally by filling the complete area with the child cells. A horizontal
 * layout partitions the height of the given parent whereas a a non-horizontal
 * layout partitions the width. If the parent is a layer (that is, a child of
 * the root node), then the current graph size is partitioned. The children do
 * not need to be connected for this layout to work.
 * 
 * Example:
 * 
 * (code)
 * var layout = new mxPartitionLayout(graph, true, 10, 20);
 * layout.execute(graph.getDefaultParent());
 * (end)
 * 
 * Constructor: mxPartitionLayout
 * 
 * Constructs a new stack layout layout for the specified graph,
 * spacing, orientation and offset.
 */
function mxPartitionLayout(graph, horizontal, spacing, border)
{
	mxGraphLayout.call(this, graph);
	this.horizontal = (horizontal != null) ? horizontal : true;
	this.spacing = spacing || 0;
	this.border = border || 0;
};

/**
 * Extends mxGraphLayout.
 */
mxPartitionLayout.prototype = new mxGraphLayout();
mxPartitionLayout.prototype.constructor = mxPartitionLayout;

/**
 * Variable: horizontal
 * 
 * Boolean indicating the direction in which the space is partitioned.
 * Default is true.
 */
mxPartitionLayout.prototype.horizontal = null;

/**
 * Variable: spacing
 * 
 * Integer that specifies the absolute spacing in pixels between the
 * children. Default is 0.
 */
mxPartitionLayout.prototype.spacing = null;

/**
 * Variable: border
 * 
 * Integer that specifies the absolute inset in pixels for the parent that
 * contains the children. Default is 0.
 */
mxPartitionLayout.prototype.border = null;

/**
 * Variable: resizeVertices
 * 
 * Boolean that specifies if vertices should be resized. Default is true.
 */
mxPartitionLayout.prototype.resizeVertices = true;

/**
 * Function: isHorizontal
 * 
 * Returns <horizontal>.
 */
mxPartitionLayout.prototype.isHorizontal = function()
{
	return this.horizontal;
};

/**
 * Function: moveCell
 * 
 * Implements <mxGraphLayout.moveCell>.
 */
mxPartitionLayout.prototype.moveCell = function(cell, x, y)
{
	var model = this.graph.getModel();
	var parent = model.getParent(cell);
	
	if (cell != null &&
		parent != null)
	{
		var i = 0;
		var last = 0;
		var childCount = model.getChildCount(parent);
		
		// Finds index of the closest swimlane
		// TODO: Take into account the orientation
		for (i = 0; i < childCount; i++)
		{
			var child = model.getChildAt(parent, i);
			var bounds = this.getVertexBounds(child);
			
			if (bounds != null)
			{
				var tmp = bounds.x + bounds.width / 2;
				
				if (last < x && tmp > x)
				{
					break;
				}
				
				last = tmp;
			}
		}
		
		// Changes child order in parent
		var idx = parent.getIndex(cell);
		idx = Math.max(0, i - ((i > idx) ? 1 : 0));
		
		model.add(parent, cell, idx);
	}
};

/**
 * Function: execute
 * 
 * Implements <mxGraphLayout.execute>. All children where <isVertexIgnored>
 * returns false and <isVertexMovable> returns true are modified.
 */
mxPartitionLayout.prototype.execute = function(parent)
{
	var horizontal = this.isHorizontal();
	var model = this.graph.getModel();
	var pgeo = model.getGeometry(parent);
	
	// Handles special case where the parent is either a layer with no
	// geometry or the current root of the view in which case the size
	// of the graph's container will be used.
	if (this.graph.container != null &&
		((pgeo == null &&
		model.isLayer(parent)) ||
		parent == this.graph.getView().currentRoot))
	{
		var width = this.graph.container.offsetWidth - 1;
		var height = this.graph.container.offsetHeight - 1;
		pgeo = new mxRectangle(0, 0, width, height);
	}

	if (pgeo != null)
	{
		var children = [];
		var childCount = model.getChildCount(parent);
		
		for (var i = 0; i < childCount; i++)
		{
			var child = model.getChildAt(parent, i);
			
			if (!this.isVertexIgnored(child) &&
				this.isVertexMovable(child))
			{
				children.push(child);
			}
		}
		
		var n = children.length;

		if (n > 0)
		{
			var x0 = this.border;
			var y0 = this.border;
			var other = (horizontal) ? pgeo.height : pgeo.width;
			other -= 2 * this.border;

			var size = (this.graph.isSwimlane(parent)) ?
				this.graph.getStartSize(parent) :
				new mxRectangle();

			other -= (horizontal) ? size.height : size.width;
			x0 = x0 + size.width;
			y0 = y0 + size.height;

			var tmp = this.border + (n - 1) * this.spacing;
			var value = (horizontal) ?
				((pgeo.width - x0 - tmp) / n) :
				((pgeo.height - y0 - tmp) / n);
			
			// Avoids negative values, that is values where the sum of the
			// spacing plus the border is larger then the available space
			if (value > 0)
			{
				model.beginUpdate();
				try
				{
					for (var i = 0; i < n; i++)
					{
						var child = children[i];
						var geo = model.getGeometry(child);
					
						if (geo != null)
						{
							geo = geo.clone();
							geo.x = x0;
							geo.y = y0;

							if (horizontal)
							{
								if (this.resizeVertices)
								{
									geo.width = value;
									geo.height = other;
								}
								
								x0 += value + this.spacing;
							}
							else
							{
								if (this.resizeVertices)
								{
									geo.height = value;
									geo.width = other;
								}
								
								y0 += value + this.spacing;
							}

							model.setGeometry(child, geo);
						}
					}
				}
				finally
				{
					model.endUpdate();
				}
			}
		}
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxCompactTreeLayout
 * 
 * Extends <mxGraphLayout> to implement a compact tree (Moen) algorithm. This
 * layout is suitable for graphs that have no cycles (trees). Vertices that are
 * not connected to the tree will be ignored by this layout.
 * 
 * Example:
 * 
 * (code)
 * var layout = new mxCompactTreeLayout(graph);
 * layout.execute(graph.getDefaultParent());
 * (end)
 * 
 * Constructor: mxCompactTreeLayout
 * 
 * Constructs a new compact tree layout for the specified graph
 * and orientation.
 */
function mxCompactTreeLayout(graph, horizontal, invert)
{
	mxGraphLayout.call(this, graph);
	this.horizontal = (horizontal != null) ? horizontal : true;
	this.invert = (invert != null) ? invert : false;
};

/**
 * Extends mxGraphLayout.
 */
mxCompactTreeLayout.prototype = new mxGraphLayout();
mxCompactTreeLayout.prototype.constructor = mxCompactTreeLayout;

/**
 * Variable: horizontal
 *
 * Specifies the orientation of the layout. Default is true.
 */
mxCompactTreeLayout.prototype.horizontal = null;	 

/**
 * Variable: invert
 *
 * Specifies if edge directions should be inverted. Default is false.
 */
mxCompactTreeLayout.prototype.invert = null;	 

/**
 * Variable: resizeParent
 * 
 * If the parents should be resized to match the width/height of the
 * children. Default is true.
 */
mxCompactTreeLayout.prototype.resizeParent = true;

/**
 * Variable: maintainParentLocation
 * 
 * Specifies if the parent location should be maintained, so that the
 * top, left corner stays the same before and after execution of
 * the layout. Default is false for backwards compatibility.
 */
mxCompactTreeLayout.prototype.maintainParentLocation = false;

/**
 * Variable: groupPadding
 * 
 * Padding added to resized parents. Default is 10.
 */
mxCompactTreeLayout.prototype.groupPadding = 10;

/**
 * Variable: groupPaddingTop
 * 
 * Top padding added to resized parents. Default is 0.
 */
mxCompactTreeLayout.prototype.groupPaddingTop = 0;

/**
 * Variable: groupPaddingRight
 * 
 * Right padding added to resized parents. Default is 0.
 */
mxCompactTreeLayout.prototype.groupPaddingRight = 0;

/**
 * Variable: groupPaddingBottom
 * 
 * Bottom padding added to resized parents. Default is 0.
 */
mxCompactTreeLayout.prototype.groupPaddingBottom = 0;

/**
 * Variable: groupPaddingLeft
 * 
 * Left padding added to resized parents. Default is 0.
 */
mxCompactTreeLayout.prototype.groupPaddingLeft = 0;

/**
 * Variable: parentsChanged
 *
 * A set of the parents that need updating based on children
 * process as part of the layout.
 */
mxCompactTreeLayout.prototype.parentsChanged = null;

/**
 * Variable: moveTree
 * 
 * Specifies if the tree should be moved to the top, left corner
 * if it is inside a top-level layer. Default is false.
 */
mxCompactTreeLayout.prototype.moveTree = false;

/**
 * Variable: visited
 * 
 * Specifies if the tree should be moved to the top, left corner
 * if it is inside a top-level layer. Default is false.
 */
mxCompactTreeLayout.prototype.visited = null;

/**
 * Variable: levelDistance
 *
 * Holds the levelDistance. Default is 10.
 */
mxCompactTreeLayout.prototype.levelDistance = 10;

/**
 * Variable: nodeDistance
 *
 * Holds the nodeDistance. Default is 20.
 */
mxCompactTreeLayout.prototype.nodeDistance = 20;

/**
 * Variable: resetEdges
 * 
 * Specifies if all edge points of traversed edges should be removed.
 * Default is true.
 */
mxCompactTreeLayout.prototype.resetEdges = true;

/**
 * Variable: prefHozEdgeSep
 * 
 * The preferred horizontal distance between edges exiting a vertex.
 */
mxCompactTreeLayout.prototype.prefHozEdgeSep = 5;

/**
 * Variable: prefVertEdgeOff
 * 
 * The preferred vertical offset between edges exiting a vertex.
 */
mxCompactTreeLayout.prototype.prefVertEdgeOff = 4;

/**
 * Variable: minEdgeJetty
 * 
 * The minimum distance for an edge jetty from a vertex.
 */
mxCompactTreeLayout.prototype.minEdgeJetty = 8;

/**
 * Variable: channelBuffer
 * 
 * The size of the vertical buffer in the center of inter-rank channels
 * where edge control points should not be placed.
 */
mxCompactTreeLayout.prototype.channelBuffer = 4;

/**
 * Variable: edgeRouting
 * 
 * Whether or not to apply the internal tree edge routing.
 */
mxCompactTreeLayout.prototype.edgeRouting = true;

/**
 * Variable: sortEdges
 * 
 * Specifies if edges should be sorted according to the order of their
 * opposite terminal cell in the model.
 */
mxCompactTreeLayout.prototype.sortEdges = false;

/**
 * Variable: alignRanks
 * 
 * Whether or not the tops of cells in each rank should be aligned
 * across the rank
 */
mxCompactTreeLayout.prototype.alignRanks = false;

/**
 * Variable: maxRankHeight
 * 
 * An array of the maximum height of cells (relative to the layout direction)
 * per rank
 */
mxCompactTreeLayout.prototype.maxRankHeight = null;

/**
 * Variable: root
 * 
 * The cell to use as the root of the tree
 */
mxCompactTreeLayout.prototype.root = null;

/**
 * Variable: node
 * 
 * The internal node representation of the root cell. Do not set directly
 * , this value is only exposed to assist with post-processing functionality
 */
mxCompactTreeLayout.prototype.node = null;

/**
 * Function: isVertexIgnored
 * 
 * Returns a boolean indicating if the given <mxCell> should be ignored as a
 * vertex. This returns true if the cell has no connections.
 * 
 * Parameters:
 * 
 * vertex - <mxCell> whose ignored state should be returned.
 */
mxCompactTreeLayout.prototype.isVertexIgnored = function(vertex)
{
	return mxGraphLayout.prototype.isVertexIgnored.apply(this, arguments) ||
		this.graph.getConnections(vertex).length == 0;
};

/**
 * Function: isHorizontal
 * 
 * Returns <horizontal>.
 */
mxCompactTreeLayout.prototype.isHorizontal = function()
{
	return this.horizontal;
};

/**
 * Function: execute
 * 
 * Implements <mxGraphLayout.execute>.
 * 
 * If the parent has any connected edges, then it is used as the root of
 * the tree. Else, <mxGraph.findTreeRoots> will be used to find a suitable
 * root node within the set of children of the given parent.
 * 
 * Parameters:
 * 
 * parent - <mxCell> whose children should be laid out.
 * root - Optional <mxCell> that will be used as the root of the tree.
 * Overrides <root> if specified.
 */
mxCompactTreeLayout.prototype.execute = function(parent, root)
{
	this.parent = parent;
	var model = this.graph.getModel();

	if (root == null)
	{
		// Takes the parent as the root if it has outgoing edges
		if (this.graph.getEdges(parent, model.getParent(parent),
			this.invert, !this.invert, false).length > 0)
		{
			this.root = parent;
		}
		
		// Tries to find a suitable root in the parent's
		// children
		else
		{
			var roots = this.graph.findTreeRoots(parent, true, this.invert);
			
			if (roots.length > 0)
			{
				for (var i = 0; i < roots.length; i++)
				{
					if (!this.isVertexIgnored(roots[i]) &&
						this.graph.getEdges(roots[i], null,
							this.invert, !this.invert, false).length > 0)
					{
						this.root = roots[i];
						break;
					}
				}
			}
		}
	}
	else
	{
		this.root = root;
	}
	
	if (this.root != null)
	{
		if (this.resizeParent)
		{
			this.parentsChanged = new Object();
		}
		else
		{
			this.parentsChanged = null;
		}

		//  Maintaining parent location
		this.parentX = null;
		this.parentY = null;
		
		if (parent != this.root && model.isVertex(parent) != null && this.maintainParentLocation)
		{
			var geo = this.graph.getCellGeometry(parent);
			
			if (geo != null)
			{
				this.parentX = geo.x;
				this.parentY = geo.y;
			}
		}
		
		model.beginUpdate();
		
		try
		{
			this.visited = new Object();
			this.node = this.dfs(this.root, parent);
			
			if (this.alignRanks)
			{
				this.maxRankHeight = [];
				this.findRankHeights(this.node, 0);
				this.setCellHeights(this.node, 0);
			}
			
			if (this.node != null)
			{
				this.layout(this.node);
				var x0 = this.graph.gridSize;
				var y0 = x0;
				
				if (!this.moveTree)
				{
					var g = this.getVertexBounds(this.root);
					
					if (g != null)
					{
						x0 = g.x;
						y0 = g.y;
					}
				}
				
				var bounds = null;
				
				if (this.isHorizontal())
				{
					bounds = this.horizontalLayout(this.node, x0, y0);
				}
				else
				{
					bounds = this.verticalLayout(this.node, null, x0, y0);
				}

				if (bounds != null)
				{
					var dx = 0;
					var dy = 0;

					if (bounds.x < 0)
					{
						dx = Math.abs(x0 - bounds.x);
					}

					if (bounds.y < 0)
					{
						dy = Math.abs(y0 - bounds.y);	
					}

					if (dx != 0 || dy != 0)
					{
						this.moveNode(this.node, dx, dy);
					}
					
					if (this.resizeParent)
					{
						this.adjustParents();
					}

					if (this.edgeRouting)
					{
						// Iterate through all edges setting their positions
						this.localEdgeProcessing(this.node);
					}
				}
				
				// Maintaining parent location
				if (this.parentX != null && this.parentY != null)
				{
					var geo = this.graph.getCellGeometry(parent);
					
					if (geo != null)
					{
						geo = geo.clone();
						geo.x = this.parentX;
						geo.y = this.parentY;
						model.setGeometry(parent, geo);
					}
				}
			}
		}
		finally
		{
			model.endUpdate();
		}
	}
};

/**
 * Function: moveNode
 * 
 * Moves the specified node and all of its children by the given amount.
 */
mxCompactTreeLayout.prototype.moveNode = function(node, dx, dy)
{
	node.x += dx;
	node.y += dy;
	this.apply(node);
	
	var child = node.child;
	
	while (child != null)
	{
		this.moveNode(child, dx, dy);
		child = child.next;
	}
};


/**
 * Function: sortOutgoingEdges
 * 
 * Called if <sortEdges> is true to sort the array of outgoing edges in place.
 */
mxCompactTreeLayout.prototype.sortOutgoingEdges = function(source, edges)
{
	var lookup = new mxDictionary();
	
	edges.sort(function(e1, e2)
	{
		var end1 = e1.getTerminal(e1.getTerminal(false) == source);
		var p1 = lookup.get(end1);
		
		if (p1 == null)
		{
			p1 = mxCellPath.create(end1).split(mxCellPath.PATH_SEPARATOR);
			lookup.put(end1, p1);
		}

		var end2 = e2.getTerminal(e2.getTerminal(false) == source);
		var p2 = lookup.get(end2);
		
		if (p2 == null)
		{
			p2 = mxCellPath.create(end2).split(mxCellPath.PATH_SEPARATOR);
			lookup.put(end2, p2);
		}

		return mxCellPath.compare(p1, p2);
	});
};

/**
 * Function: findRankHeights
 * 
 * Stores the maximum height (relative to the layout
 * direction) of cells in each rank
 */
mxCompactTreeLayout.prototype.findRankHeights = function(node, rank)
{
	if (this.maxRankHeight[rank] == null || this.maxRankHeight[rank] < node.height)
	{
		this.maxRankHeight[rank] = node.height;
	}

	var child = node.child;
	
	while (child != null)
	{
		this.findRankHeights(child, rank + 1);
		child = child.next;
	}
};

/**
 * Function: setCellHeights
 * 
 * Set the cells heights (relative to the layout
 * direction) when the tops of each rank are to be aligned
 */
mxCompactTreeLayout.prototype.setCellHeights = function(node, rank)
{
	if (this.maxRankHeight[rank] != null && this.maxRankHeight[rank] > node.height)
	{
		node.height = this.maxRankHeight[rank];
	}

	var child = node.child;
	
	while (child != null)
	{
		this.setCellHeights(child, rank + 1);
		child = child.next;
	}
};

/**
 * Function: dfs
 * 
 * Does a depth first search starting at the specified cell.
 * Makes sure the specified parent is never left by the
 * algorithm.
 */
mxCompactTreeLayout.prototype.dfs = function(cell, parent)
{
	var id = mxCellPath.create(cell);
	var node = null;
	
	if (cell != null && this.visited[id] == null && !this.isVertexIgnored(cell))
	{
		this.visited[id] = cell;
		node = this.createNode(cell);

		var model = this.graph.getModel();
		var prev = null;
		var out = this.graph.getEdges(cell, parent, this.invert, !this.invert, false, true);
		var view = this.graph.getView();
		
		if (this.sortEdges)
		{
			this.sortOutgoingEdges(cell, out);
		}

		for (var i = 0; i < out.length; i++)
		{
			var edge = out[i];
			
			if (!this.isEdgeIgnored(edge))
			{
				// Resets the points on the traversed edge
				if (this.resetEdges)
				{
					this.setEdgePoints(edge, null);
				}
				
				if (this.edgeRouting)
				{
					this.setEdgeStyleEnabled(edge, false);
					this.setEdgePoints(edge, null);
				}
				
				// Checks if terminal in same swimlane
				var state = view.getState(edge);
				var target = (state != null) ? state.getVisibleTerminal(this.invert) : view.getVisibleTerminal(edge, this.invert);
				var tmp = this.dfs(target, parent);
				
				if (tmp != null && model.getGeometry(target) != null)
				{
					if (prev == null)
					{
						node.child = tmp;
					}
					else
					{
						prev.next = tmp;
					}
					
					prev = tmp;
				}
			}
		}
	}
	
	return node;
};

/**
 * Function: layout
 * 
 * Starts the actual compact tree layout algorithm
 * at the given node.
 */
mxCompactTreeLayout.prototype.layout = function(node)
{
	if (node != null)
	{
		var child = node.child;
		
		while (child != null)
		{
			this.layout(child);
			child = child.next;
		}
		
		if (node.child != null)
		{
			this.attachParent(node, this.join(node));
		}
		else
		{
			this.layoutLeaf(node);
		}
	}
};

/**
 * Function: horizontalLayout
 */
mxCompactTreeLayout.prototype.horizontalLayout = function(node, x0, y0, bounds)
{
	node.x += x0 + node.offsetX;
	node.y += y0 + node.offsetY;
	bounds = this.apply(node, bounds);
	var child = node.child;
	
	if (child != null)
	{
		bounds = this.horizontalLayout(child, node.x, node.y, bounds);
		var siblingOffset = node.y + child.offsetY;
		var s = child.next;
		
		while (s != null)
		{
			bounds = this.horizontalLayout(s, node.x + child.offsetX, siblingOffset, bounds);
			siblingOffset += s.offsetY;
			s = s.next;
		}
	}
	
	return bounds;
};
	
/**
 * Function: verticalLayout
 */
mxCompactTreeLayout.prototype.verticalLayout = function(node, parent, x0, y0, bounds)
{
	node.x += x0 + node.offsetY;
	node.y += y0 + node.offsetX;
	bounds = this.apply(node, bounds);
	var child = node.child;
	
	if (child != null)
	{
		bounds = this.verticalLayout(child, node, node.x, node.y, bounds);
		var siblingOffset = node.x + child.offsetY;
		var s = child.next;
		
		while (s != null)
		{
			bounds = this.verticalLayout(s, node, siblingOffset, node.y + child.offsetX, bounds);
			siblingOffset += s.offsetY;
			s = s.next;
		}
	}
	
	return bounds;
};

/**
 * Function: attachParent
 */
mxCompactTreeLayout.prototype.attachParent = function(node, height)
{
	var x = this.nodeDistance + this.levelDistance;
	var y2 = (height - node.width) / 2 - this.nodeDistance;
	var y1 = y2 + node.width + 2 * this.nodeDistance - height;
	
	node.child.offsetX = x + node.height;
	node.child.offsetY = y1;
	
	node.contour.upperHead = this.createLine(node.height, 0,
		this.createLine(x, y1, node.contour.upperHead));
	node.contour.lowerHead = this.createLine(node.height, 0,
		this.createLine(x, y2, node.contour.lowerHead));
};

/**
 * Function: layoutLeaf
 */
mxCompactTreeLayout.prototype.layoutLeaf = function(node)
{
	var dist = 2 * this.nodeDistance;
	
	node.contour.upperTail = this.createLine(
		node.height + dist, 0);
	node.contour.upperHead = node.contour.upperTail;
	node.contour.lowerTail = this.createLine(
		0, -node.width - dist);
	node.contour.lowerHead = this.createLine(
		node.height + dist, 0, node.contour.lowerTail);
};

/**
 * Function: join
 */
mxCompactTreeLayout.prototype.join = function(node)
{
	var dist = 2 * this.nodeDistance;
	
	var child = node.child;
	node.contour = child.contour;
	var h = child.width + dist;
	var sum = h;
	child = child.next;
	
	while (child != null)
	{
		var d = this.merge(node.contour, child.contour);
		child.offsetY = d + h;
		child.offsetX = 0;
		h = child.width + dist;
		sum += d + h;
		child = child.next;
	}
	
	return sum;
};

/**
 * Function: merge
 */
mxCompactTreeLayout.prototype.merge = function(p1, p2)
{
	var x = 0;
	var y = 0;
	var total = 0;
	
	var upper = p1.lowerHead;
	var lower = p2.upperHead;
	
	while (lower != null && upper != null)
	{
		var d = this.offset(x, y, lower.dx, lower.dy,
			upper.dx, upper.dy);
		y += d;
		total += d;
		
		if (x + lower.dx <= upper.dx)
		{
			x += lower.dx;
			y += lower.dy;
			lower = lower.next;
		}
		else
		{				
			x -= upper.dx;
			y -= upper.dy;
			upper = upper.next;
		}
	}
	
	if (lower != null)
	{
		var b = this.bridge(p1.upperTail, 0, 0, lower, x, y);
		p1.upperTail = (b.next != null) ? p2.upperTail : b;
		p1.lowerTail = p2.lowerTail;
	}
	else
	{
		var b = this.bridge(p2.lowerTail, x, y, upper, 0, 0);
		
		if (b.next == null)
		{
			p1.lowerTail = b;
		}
	}
	
	p1.lowerHead = p2.lowerHead;
	
	return total;
};

/**
 * Function: offset
 */
mxCompactTreeLayout.prototype.offset = function(p1, p2, a1, a2, b1, b2)
{
	var d = 0;
	
	if (b1 <= p1 || p1 + a1 <= 0)
	{
		return 0;
	}

	var t = b1 * a2 - a1 * b2;
	
	if (t > 0)
	{
		if (p1 < 0)
		{
			var s = p1 * a2;
			d = s / a1 - p2;
		}
		else if (p1 > 0)
		{
			var s = p1 * b2;
			d = s / b1 - p2;
		}
		else
		{
			d = -p2;
		}
	}
	else if (b1 < p1 + a1)
	{
		var s = (b1 - p1) * a2;
		d = b2 - (p2 + s / a1);
	}
	else if (b1 > p1 + a1)
	{
		var s = (a1 + p1) * b2;
		d = s / b1 - (p2 + a2);
	}
	else
	{
		d = b2 - (p2 + a2);
	}

	if (d > 0)
	{
		return d;
	}
	else
	{
		return 0;
	}
};

/**
 * Function: bridge
 */
mxCompactTreeLayout.prototype.bridge = function(line1, x1, y1, line2, x2, y2)
{
	var dx = x2 + line2.dx - x1;
	var dy = 0;
	var s = 0;
	
	if (line2.dx == 0)
	{
		dy = line2.dy;
	}
	else
	{
		s = dx * line2.dy;
		dy = s / line2.dx;
	}
	
	var r = this.createLine(dx, dy, line2.next);
	line1.next = this.createLine(0, y2 + line2.dy - dy - y1, r);
	
	return r;
};

/**
 * Function: createNode
 */
mxCompactTreeLayout.prototype.createNode = function(cell)
{
	var node = new Object();
	node.cell = cell;
	node.x = 0;
	node.y = 0;
	node.width = 0;
	node.height = 0;
	
	var geo = this.getVertexBounds(cell);
	
	if (geo != null)
	{
		if (this.isHorizontal())
		{
			node.width = geo.height;
			node.height = geo.width;			
		}
		else
		{
			node.width = geo.width;
			node.height = geo.height;
		}
	}
	
	node.offsetX = 0;
	node.offsetY = 0;
	node.contour = new Object();
	
	return node;
};

/**
 * Function: apply
 */
mxCompactTreeLayout.prototype.apply = function(node, bounds)
{
	var model = this.graph.getModel();
	var cell = node.cell;
	var g = model.getGeometry(cell);

	if (cell != null && g != null)
	{
		if (this.isVertexMovable(cell))
		{
			g = this.setVertexLocation(cell, node.x, node.y);
			
			if (this.resizeParent)
			{
				var parent = model.getParent(cell);
				var id = mxCellPath.create(parent);
				
				// Implements set semantic
				if (this.parentsChanged[id] == null)
				{
					this.parentsChanged[id] = parent;					
				}
			}
		}
		
		if (bounds == null)
		{
			bounds = new mxRectangle(g.x, g.y, g.width, g.height);
		}
		else
		{
			bounds = new mxRectangle(Math.min(bounds.x, g.x),
				Math.min(bounds.y, g.y),
				Math.max(bounds.x + bounds.width, g.x + g.width),
				Math.max(bounds.y + bounds.height, g.y + g.height));
		}
	}
	
	return bounds;
};

/**
 * Function: createLine
 */
mxCompactTreeLayout.prototype.createLine = function(dx, dy, next)
{
	var line = new Object();
	line.dx = dx;
	line.dy = dy;
	line.next = next;
	
	return line;
};

/**
 * Function: adjustParents
 * 
 * Adjust parent cells whose child geometries have changed. The default 
 * implementation adjusts the group to just fit around the children with 
 * a padding.
 */
mxCompactTreeLayout.prototype.adjustParents = function()
{
	var tmp = [];
	
	for (var id in this.parentsChanged)
	{
		tmp.push(this.parentsChanged[id]);
	}
	
	this.arrangeGroups(mxUtils.sortCells(tmp, true), this.groupPadding, this.groupPaddingTop,
		this.groupPaddingRight, this.groupPaddingBottom, this.groupPaddingLeft);
};

/**
 * Function: localEdgeProcessing
 *
 * Moves the specified node and all of its children by the given amount.
 */
mxCompactTreeLayout.prototype.localEdgeProcessing = function(node)
{
	this.processNodeOutgoing(node);
	var child = node.child;

	while (child != null)
	{
		this.localEdgeProcessing(child);
		child = child.next;
	}
};

/**
 * Function: localEdgeProcessing
 *
 * Separates the x position of edges as they connect to vertices
 */
mxCompactTreeLayout.prototype.processNodeOutgoing = function(node)
{
	var child = node.child;
	var parentCell = node.cell;

	var childCount = 0;
	var sortedCells = [];

	while (child != null)
	{
		childCount++;

		var sortingCriterion = child.x;

		if (this.horizontal)
		{
			sortingCriterion = child.y;
		}

		sortedCells.push(new WeightedCellSorter(child, sortingCriterion));
		child = child.next;
	}

	sortedCells.sort(WeightedCellSorter.prototype.compare);

	var availableWidth = node.width;

	var requiredWidth = (childCount + 1) * this.prefHozEdgeSep;

	// Add a buffer on the edges of the vertex if the edge count allows
	if (availableWidth > requiredWidth + (2 * this.prefHozEdgeSep))
	{
		availableWidth -= 2 * this.prefHozEdgeSep;
	}

	var edgeSpacing = availableWidth / childCount;

	var currentXOffset = edgeSpacing / 2.0;

	if (availableWidth > requiredWidth + (2 * this.prefHozEdgeSep))
	{
		currentXOffset += this.prefHozEdgeSep;
	}

	var currentYOffset = this.minEdgeJetty - this.prefVertEdgeOff;
	var maxYOffset = 0;

	var parentBounds = this.getVertexBounds(parentCell);
	child = node.child;

	for (var j = 0; j < sortedCells.length; j++)
	{
		var childCell = sortedCells[j].cell.cell;
		var childBounds = this.getVertexBounds(childCell);

		var edges = this.graph.getEdgesBetween(parentCell,
				childCell, false);
		
		var newPoints = [];
		var x = 0;
		var y = 0;

		for (var i = 0; i < edges.length; i++)
		{
			if (this.horizontal)
			{
				// Use opposite co-ords, calculation was done for 
				// 
				x = parentBounds.x + parentBounds.width;
				y = parentBounds.y + currentXOffset;
				newPoints.push(new mxPoint(x, y));
				x = parentBounds.x + parentBounds.width
						+ currentYOffset;
				newPoints.push(new mxPoint(x, y));
				y = childBounds.y + childBounds.height / 2.0;
				newPoints.push(new mxPoint(x, y));
				this.setEdgePoints(edges[i], newPoints);
			}
			else
			{
				x = parentBounds.x + currentXOffset;
				y = parentBounds.y + parentBounds.height;
				newPoints.push(new mxPoint(x, y));
				y = parentBounds.y + parentBounds.height
						+ currentYOffset;
				newPoints.push(new mxPoint(x, y));
				x = childBounds.x + childBounds.width / 2.0;
				newPoints.push(new mxPoint(x, y));
				this.setEdgePoints(edges[i], newPoints);
			}
		}

		if (j < childCount / 2)
		{
			currentYOffset += this.prefVertEdgeOff;
		}
		else if (j > childCount / 2)
		{
			currentYOffset -= this.prefVertEdgeOff;
		}
		// Ignore the case if equals, this means the second of 2
		// jettys with the same y (even number of edges)

		//								pos[k * 2] = currentX;
		currentXOffset += edgeSpacing;
		//								pos[k * 2 + 1] = currentYOffset;

		maxYOffset = Math.max(maxYOffset, currentYOffset);
	}
};

/**
 * Class: WeightedCellSorter
 * 
 * A utility class used to track cells whilst sorting occurs on the weighted
 * sum of their connected edges. Does not violate (x.compareTo(y)==0) ==
 * (x.equals(y))
 *
 * Constructor: WeightedCellSorter
 * 
 * Constructs a new weighted cell sorted for the given cell and weight.
 */
function WeightedCellSorter(cell, weightedValue)
{
	this.cell = cell;
	this.weightedValue = weightedValue;
};

/**
 * Variable: weightedValue
 * 
 * The weighted value of the cell stored.
 */
WeightedCellSorter.prototype.weightedValue = 0;

/**
 * Variable: nudge
 * 
 * Whether or not to flip equal weight values.
 */
WeightedCellSorter.prototype.nudge = false;

/**
 * Variable: visited
 * 
 * Whether or not this cell has been visited in the current assignment.
 */
WeightedCellSorter.prototype.visited = false;

/**
 * Variable: rankIndex
 * 
 * The index this cell is in the model rank.
 */
WeightedCellSorter.prototype.rankIndex = null;

/**
 * Variable: cell
 * 
 * The cell whose median value is being calculated.
 */
WeightedCellSorter.prototype.cell = null;

/**
 * Function: compare
 * 
 * Compares two WeightedCellSorters.
 */
WeightedCellSorter.prototype.compare = function(a, b)
{
	if (a != null && b != null)
	{
		if (b.weightedValue > a.weightedValue)
		{
			return 1;
		}
		else if (b.weightedValue < a.weightedValue)
		{
			return -1;
		}
		else
		{
			if (b.nudge)
			{
				return 1;
			}
			else
			{
				return -1;
			}
		}
	}
	else
	{
		return 0;
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxRadialTreeLayout
 * 
 * Extends <mxGraphLayout> to implement a radial tree algorithm. This
 * layout is suitable for graphs that have no cycles (trees). Vertices that are
 * not connected to the tree will be ignored by this layout.
 * 
 * Example:
 * 
 * (code)
 * var layout = new mxRadialTreeLayout(graph);
 * layout.execute(graph.getDefaultParent());
 * (end)
 * 
 * Constructor: mxRadialTreeLayout
 * 
 * Constructs a new radial tree layout for the specified graph
 */
function mxRadialTreeLayout(graph)
{
	mxCompactTreeLayout.call(this, graph , false);
};

/**
 * Extends mxGraphLayout.
 */
mxUtils.extend(mxRadialTreeLayout, mxCompactTreeLayout);

/**
 * Variable: angleOffset
 *
 * The initial offset to compute the angle position.
 */
mxRadialTreeLayout.prototype.angleOffset = 0.5;

/**
 * Variable: rootx
 *
 * The X co-ordinate of the root cell
 */
mxRadialTreeLayout.prototype.rootx = 0;

/**
 * Variable: rooty
 *
 * The Y co-ordinate of the root cell
 */
mxRadialTreeLayout.prototype.rooty = 0;

/**
 * Variable: levelDistance
 *
 * Holds the levelDistance. Default is 120.
 */
mxRadialTreeLayout.prototype.levelDistance = 120;

/**
 * Variable: nodeDistance
 *
 * Holds the nodeDistance. Default is 10.
 */
mxRadialTreeLayout.prototype.nodeDistance = 10;

/**
 * Variable: autoRadius
 * 
 * Specifies if the radios should be computed automatically
 */
mxRadialTreeLayout.prototype.autoRadius = false;

/**
 * Variable: sortEdges
 * 
 * Specifies if edges should be sorted according to the order of their
 * opposite terminal cell in the model.
 */
mxRadialTreeLayout.prototype.sortEdges = false;

/**
 * Variable: rowMinX
 * 
 * Array of leftmost x coordinate of each row
 */
mxRadialTreeLayout.prototype.rowMinX = [];

/**
 * Variable: rowMaxX
 * 
 * Array of rightmost x coordinate of each row
 */
mxRadialTreeLayout.prototype.rowMaxX = [];

/**
 * Variable: rowMinCenX
 * 
 * Array of x coordinate of leftmost vertex of each row
 */
mxRadialTreeLayout.prototype.rowMinCenX = [];

/**
 * Variable: rowMaxCenX
 * 
 * Array of x coordinate of rightmost vertex of each row
 */
mxRadialTreeLayout.prototype.rowMaxCenX = [];

/**
 * Variable: rowRadi
 * 
 * Array of y deltas of each row behind root vertex, also the radius in the tree
 */
mxRadialTreeLayout.prototype.rowRadi = [];

/**
 * Variable: row
 * 
 * Array of vertices on each row
 */
mxRadialTreeLayout.prototype.row = [];

/**
 * Function: isVertexIgnored
 * 
 * Returns a boolean indicating if the given <mxCell> should be ignored as a
 * vertex. This returns true if the cell has no connections.
 * 
 * Parameters:
 * 
 * vertex - <mxCell> whose ignored state should be returned.
 */
mxRadialTreeLayout.prototype.isVertexIgnored = function(vertex)
{
	return mxGraphLayout.prototype.isVertexIgnored.apply(this, arguments) ||
		this.graph.getConnections(vertex).length == 0;
};

/**
 * Function: execute
 * 
 * Implements <mxGraphLayout.execute>.
 * 
 * If the parent has any connected edges, then it is used as the root of
 * the tree. Else, <mxGraph.findTreeRoots> will be used to find a suitable
 * root node within the set of children of the given parent.
 * 
 * Parameters:
 * 
 * parent - <mxCell> whose children should be laid out.
 * root - Optional <mxCell> that will be used as the root of the tree.
 */
mxRadialTreeLayout.prototype.execute = function(parent, root)
{
	this.parent = parent;
	
	this.useBoundingBox = false;
	this.edgeRouting = false;
	//this.horizontal = false;

	mxCompactTreeLayout.prototype.execute.apply(this, arguments);
	
	var bounds = null;
	var rootBounds = this.getVertexBounds(this.root);
	this.centerX = rootBounds.x + rootBounds.width / 2;
	this.centerY = rootBounds.y + rootBounds.height / 2;

	// Calculate the bounds of the involved vertices directly from the values set in the compact tree
	for (var vertex in this.visited)
	{
		var vertexBounds = this.getVertexBounds(this.visited[vertex]);
		bounds = (bounds != null) ? bounds : vertexBounds.clone();
		bounds.add(vertexBounds);
	}
	
	this.calcRowDims([this.node], 0);
	
	var maxLeftGrad = 0;
	var maxRightGrad = 0;

	// Find the steepest left and right gradients
	for (var i = 0; i < this.row.length; i++)
	{
		var leftGrad = (this.centerX - this.rowMinX[i] - this.nodeDistance) / this.rowRadi[i];
		var rightGrad = (this.rowMaxX[i] - this.centerX - this.nodeDistance) / this.rowRadi[i];
		
		maxLeftGrad = Math.max (maxLeftGrad, leftGrad);
		maxRightGrad = Math.max (maxRightGrad, rightGrad);
	}
	
	// Extend out row so they meet the maximum gradient and convert to polar co-ords
	for (var i = 0; i < this.row.length; i++)
	{
		var xLeftLimit = this.centerX - this.nodeDistance - maxLeftGrad * this.rowRadi[i];
		var xRightLimit = this.centerX + this.nodeDistance + maxRightGrad * this.rowRadi[i];
		var fullWidth = xRightLimit - xLeftLimit;
		
		for (var j = 0; j < this.row[i].length; j ++)
		{
			var row = this.row[i];
			var node = row[j];
			var vertexBounds = this.getVertexBounds(node.cell);
			var xProportion = (vertexBounds.x + vertexBounds.width / 2 - xLeftLimit) / (fullWidth);
			var theta =  2 * Math.PI * xProportion;
			node.theta = theta;
		}
	}

	// Post-process from outside inwards to try to align parents with children
	for (var i = this.row.length - 2; i >= 0; i--)
	{
		var row = this.row[i];
		
		for (var j = 0; j < row.length; j++)
		{
			var node = row[j];
			var child = node.child;
			var counter = 0;
			var totalTheta = 0;
			
			while (child != null)
			{
				totalTheta += child.theta;
				counter++;
				child = child.next;
			}
			
			if (counter > 0)
			{
				var averTheta = totalTheta / counter;
				
				if (averTheta > node.theta && j < row.length - 1)
				{
					var nextTheta = row[j+1].theta;
					node.theta = Math.min (averTheta, nextTheta - Math.PI/10);
				}
				else if (averTheta < node.theta && j > 0 )
				{
					var lastTheta = row[j-1].theta;
					node.theta = Math.max (averTheta, lastTheta + Math.PI/10);
				}
			}
		}
	}
	
	// Set locations
	for (var i = 0; i < this.row.length; i++)
	{
		for (var j = 0; j < this.row[i].length; j ++)
		{
			var row = this.row[i];
			var node = row[j];
			var vertexBounds = this.getVertexBounds(node.cell);
			this.setVertexLocation(node.cell,
									this.centerX - vertexBounds.width / 2 + this.rowRadi[i] * Math.cos(node.theta),
									this.centerY - vertexBounds.height / 2 + this.rowRadi[i] * Math.sin(node.theta));
		}
	}
};

/**
 * Function: calcRowDims
 * 
 * Recursive function to calculate the dimensions of each row
 * 
 * Parameters:
 * 
 * row - Array of internal nodes, the children of which are to be processed.
 * rowNum - Integer indicating which row is being processed.
 */
mxRadialTreeLayout.prototype.calcRowDims = function(row, rowNum)
{
	if (row == null || row.length == 0)
	{
		return;
	}

	// Place root's children proportionally around the first level
	this.rowMinX[rowNum] = this.centerX;
	this.rowMaxX[rowNum] = this.centerX;
	this.rowMinCenX[rowNum] = this.centerX;
	this.rowMaxCenX[rowNum] = this.centerX;
	this.row[rowNum] = [];

	var rowHasChildren = false;

	for (var i = 0; i < row.length; i++)
	{
		var child = row[i] != null ? row[i].child : null;

		while (child != null)
		{
			var cell = child.cell;
			vertexBounds = this.getVertexBounds(cell);
			
			this.rowMinX[rowNum] = Math.min(vertexBounds.x, this.rowMinX[rowNum]);
			this.rowMaxX[rowNum] = Math.max(vertexBounds.x + vertexBounds.width, this.rowMaxX[rowNum]);
			this.rowMinCenX[rowNum] = Math.min(vertexBounds.x + vertexBounds.width / 2, this.rowMinCenX[rowNum]);
			this.rowMaxCenX[rowNum] = Math.max(vertexBounds.x + vertexBounds.width / 2, this.rowMaxCenX[rowNum]);
			this.rowRadi[rowNum] = vertexBounds.y - this.getVertexBounds(this.root).y;
	
			if (child.child != null)
			{
				rowHasChildren = true;
			}
			this.row[rowNum].push(child);
			child = child.next;
		}
	}
	
	if (rowHasChildren)
	{
		this.calcRowDims(this.row[rowNum], rowNum + 1);
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxFastOrganicLayout
 * 
 * Extends <mxGraphLayout> to implement a fast organic layout algorithm.
 * The vertices need to be connected for this layout to work, vertices
 * with no connections are ignored.
 * 
 * Example:
 * 
 * (code)
 * var layout = new mxFastOrganicLayout(graph);
 * layout.execute(graph.getDefaultParent());
 * (end)
 * 
 * Constructor: mxCompactTreeLayout
 * 
 * Constructs a new fast organic layout for the specified graph.
 */
function mxFastOrganicLayout(graph)
{
	mxGraphLayout.call(this, graph);
};

/**
 * Extends mxGraphLayout.
 */
mxFastOrganicLayout.prototype = new mxGraphLayout();
mxFastOrganicLayout.prototype.constructor = mxFastOrganicLayout;

/**
 * Variable: useInputOrigin
 * 
 * Specifies if the top left corner of the input cells should be the origin
 * of the layout result. Default is true.
 */
mxFastOrganicLayout.prototype.useInputOrigin = true;

/**
 * Variable: resetEdges
 * 
 * Specifies if all edge points of traversed edges should be removed.
 * Default is true.
 */
mxFastOrganicLayout.prototype.resetEdges = true;

/**
 * Variable: disableEdgeStyle
 * 
 * Specifies if the STYLE_NOEDGESTYLE flag should be set on edges that are
 * modified by the result. Default is true.
 */
mxFastOrganicLayout.prototype.disableEdgeStyle = true;

/**
 * Variable: forceConstant
 * 
 * The force constant by which the attractive forces are divided and the
 * replusive forces are multiple by the square of. The value equates to the
 * average radius there is of free space around each node. Default is 50.
 */
mxFastOrganicLayout.prototype.forceConstant = 50;

/**
 * Variable: forceConstantSquared
 * 
 * Cache of <forceConstant>^2 for performance.
 */
mxFastOrganicLayout.prototype.forceConstantSquared = 0;

/**
 * Variable: minDistanceLimit
 * 
 * Minimal distance limit. Default is 2. Prevents of
 * dividing by zero.
 */
mxFastOrganicLayout.prototype.minDistanceLimit = 2;

/**
 * Variable: minDistanceLimit
 * 
 * Minimal distance limit. Default is 2. Prevents of
 * dividing by zero.
 */
mxFastOrganicLayout.prototype.maxDistanceLimit = 500;

/**
 * Variable: minDistanceLimitSquared
 * 
 * Cached version of <minDistanceLimit> squared.
 */
mxFastOrganicLayout.prototype.minDistanceLimitSquared = 4;

/**
 * Variable: initialTemp
 * 
 * Start value of temperature. Default is 200.
 */
mxFastOrganicLayout.prototype.initialTemp = 200;

/**
 * Variable: temperature
 * 
 * Temperature to limit displacement at later stages of layout.
 */
mxFastOrganicLayout.prototype.temperature = 0;

/**
 * Variable: maxIterations
 * 
 * Total number of iterations to run the layout though.
 */
mxFastOrganicLayout.prototype.maxIterations = 0;

/**
 * Variable: iteration
 * 
 * Current iteration count.
 */
mxFastOrganicLayout.prototype.iteration = 0;

/**
 * Variable: vertexArray
 * 
 * An array of all vertices to be laid out.
 */
mxFastOrganicLayout.prototype.vertexArray;

/**
 * Variable: dispX
 * 
 * An array of locally stored X co-ordinate displacements for the vertices.
 */
mxFastOrganicLayout.prototype.dispX;

/**
 * Variable: dispY
 * 
 * An array of locally stored Y co-ordinate displacements for the vertices.
 */
mxFastOrganicLayout.prototype.dispY;

/**
 * Variable: cellLocation
 * 
 * An array of locally stored co-ordinate positions for the vertices.
 */
mxFastOrganicLayout.prototype.cellLocation;

/**
 * Variable: radius
 * 
 * The approximate radius of each cell, nodes only.
 */
mxFastOrganicLayout.prototype.radius;

/**
 * Variable: radiusSquared
 * 
 * The approximate radius squared of each cell, nodes only.
 */
mxFastOrganicLayout.prototype.radiusSquared;

/**
 * Variable: isMoveable
 * 
 * Array of booleans representing the movable states of the vertices.
 */
mxFastOrganicLayout.prototype.isMoveable;

/**
 * Variable: neighbours
 * 
 * Local copy of cell neighbours.
 */
mxFastOrganicLayout.prototype.neighbours;

/**
 * Variable: indices
 * 
 * Hashtable from cells to local indices.
 */
mxFastOrganicLayout.prototype.indices;

/**
 * Variable: allowedToRun
 * 
 * Boolean flag that specifies if the layout is allowed to run. If this is
 * set to false, then the layout exits in the following iteration.
 */
mxFastOrganicLayout.prototype.allowedToRun = true;

/**
 * Function: isVertexIgnored
 * 
 * Returns a boolean indicating if the given <mxCell> should be ignored as a
 * vertex. This returns true if the cell has no connections.
 * 
 * Parameters:
 * 
 * vertex - <mxCell> whose ignored state should be returned.
 */
mxFastOrganicLayout.prototype.isVertexIgnored = function(vertex)
{
	return mxGraphLayout.prototype.isVertexIgnored.apply(this, arguments) ||
		this.graph.getConnections(vertex).length == 0;
};

/**
 * Function: execute
 * 
 * Implements <mxGraphLayout.execute>. This operates on all children of the
 * given parent where <isVertexIgnored> returns false.
 */
mxFastOrganicLayout.prototype.execute = function(parent)
{
	var model = this.graph.getModel();
	this.vertexArray = [];
	var cells = this.graph.getChildVertices(parent);
	
	for (var i = 0; i < cells.length; i++)
	{
		if (!this.isVertexIgnored(cells[i]))
		{
			this.vertexArray.push(cells[i]);
		}
	}
	
	var initialBounds = (this.useInputOrigin) ?
			this.graph.getBoundingBoxFromGeometry(this.vertexArray) :
				null;
	var n = this.vertexArray.length;

	this.indices = [];
	this.dispX = [];
	this.dispY = [];
	this.cellLocation = [];
	this.isMoveable = [];
	this.neighbours = [];
	this.radius = [];
	this.radiusSquared = [];

	if (this.forceConstant < 0.001)
	{
		this.forceConstant = 0.001;
	}

	this.forceConstantSquared = this.forceConstant * this.forceConstant;

	// Create a map of vertices first. This is required for the array of
	// arrays called neighbours which holds, for each vertex, a list of
	// ints which represents the neighbours cells to that vertex as
	// the indices into vertexArray
	for (var i = 0; i < this.vertexArray.length; i++)
	{
		var vertex = this.vertexArray[i];
		this.cellLocation[i] = [];
		
		// Set up the mapping from array indices to cells
		var id = mxObjectIdentity.get(vertex);
		this.indices[id] = i;
		var bounds = this.getVertexBounds(vertex);

		// Set the X,Y value of the internal version of the cell to
		// the center point of the vertex for better positioning
		var width = bounds.width;
		var height = bounds.height;
		
		// Randomize (0, 0) locations
		var x = bounds.x;
		var y = bounds.y;
		
		this.cellLocation[i][0] = x + width / 2.0;
		this.cellLocation[i][1] = y + height / 2.0;
		this.radius[i] = Math.min(width, height);
		this.radiusSquared[i] = this.radius[i] * this.radius[i];
	}

	// Moves cell location back to top-left from center locations used in
	// algorithm, resetting the edge points is part of the transaction
	model.beginUpdate();
	try
	{
		for (var i = 0; i < n; i++)
		{
			this.dispX[i] = 0;
			this.dispY[i] = 0;
			this.isMoveable[i] = this.isVertexMovable(this.vertexArray[i]);

			// Get lists of neighbours to all vertices, translate the cells
			// obtained in indices into vertexArray and store as an array
			// against the orginial cell index
			var edges = this.graph.getConnections(this.vertexArray[i], parent);
			var cells = this.graph.getOpposites(edges, this.vertexArray[i]);
			this.neighbours[i] = [];

			for (var j = 0; j < cells.length; j++)
			{
				// Resets the points on the traversed edge
				if (this.resetEdges)
				{
					this.graph.resetEdge(edges[j]);
				}

			    if (this.disableEdgeStyle)
			    {
			    	this.setEdgeStyleEnabled(edges[j], false);
			    }

				// Looks the cell up in the indices dictionary
				var id = mxObjectIdentity.get(cells[j]);
				var index = this.indices[id];

				// Check the connected cell in part of the vertex list to be
				// acted on by this layout
				if (index != null)
				{
					this.neighbours[i][j] = index;
				}

				// Else if index of the other cell doesn't correspond to
				// any cell listed to be acted upon in this layout. Set
				// the index to the value of this vertex (a dummy self-loop)
				// so the attraction force of the edge is not calculated
				else
				{
					this.neighbours[i][j] = i;
				}
			}
		}
		this.temperature = this.initialTemp;

		// If max number of iterations has not been set, guess it
		if (this.maxIterations == 0)
		{
			this.maxIterations = 20 * Math.sqrt(n);
		}
		
		// Main iteration loop
		for (this.iteration = 0; this.iteration < this.maxIterations; this.iteration++)
		{
			if (!this.allowedToRun)
			{
				return;
			}
			
			// Calculate repulsive forces on all vertices
			this.calcRepulsion();

			// Calculate attractive forces through edges
			this.calcAttraction();

			this.calcPositions();
			this.reduceTemperature();
		}

		var minx = null;
		var miny = null;
		
		for (var i = 0; i < this.vertexArray.length; i++)
		{
			var vertex = this.vertexArray[i];
			
			if (this.isVertexMovable(vertex))
			{
				var bounds = this.getVertexBounds(vertex);
				
				if (bounds != null)
				{
					this.cellLocation[i][0] -= bounds.width / 2.0;
					this.cellLocation[i][1] -= bounds.height / 2.0;
					
					var x = this.graph.snap(this.cellLocation[i][0]);
					var y = this.graph.snap(this.cellLocation[i][1]);
					
					this.setVertexLocation(vertex, x, y);
					
					if (minx == null)
					{
						minx = x;
					}
					else
					{
						minx = Math.min(minx, x);
					}
					
					if (miny == null)
					{
						miny = y;
					}
					else
					{
						miny = Math.min(miny, y);
					}
				}
			}
		}
		
		// Modifies the cloned geometries in-place. Not needed
		// to clone the geometries again as we're in the same
		// undoable change.
		var dx = -(minx || 0) + 1;
		var dy = -(miny || 0) + 1;
		
		if (initialBounds != null)
		{
			dx += initialBounds.x;
			dy += initialBounds.y;
		}
		
		this.graph.moveCells(this.vertexArray, dx, dy);
	}
	finally
	{
		model.endUpdate();
	}
};

/**
 * Function: calcPositions
 * 
 * Takes the displacements calculated for each cell and applies them to the
 * local cache of cell positions. Limits the displacement to the current
 * temperature.
 */
mxFastOrganicLayout.prototype.calcPositions = function()
{
	for (var index = 0; index < this.vertexArray.length; index++)
	{
		if (this.isMoveable[index])
		{
			// Get the distance of displacement for this node for this
			// iteration
			var deltaLength = Math.sqrt(this.dispX[index] * this.dispX[index] +
				this.dispY[index] * this.dispY[index]);

			if (deltaLength < 0.001)
			{
				deltaLength = 0.001;
			}

			// Scale down by the current temperature if less than the
			// displacement distance
			var newXDisp = this.dispX[index] / deltaLength
				* Math.min(deltaLength, this.temperature);

			var newYDisp = this.dispY[index] / deltaLength
				* Math.min(deltaLength, this.temperature);

			// reset displacements
			this.dispX[index] = 0;
			this.dispY[index] = 0;

			// Update the cached cell locations
			this.cellLocation[index][0] += newXDisp;
			this.cellLocation[index][1] += newYDisp;
		}
	}
};

/**
 * Function: calcAttraction
 * 
 * Calculates the attractive forces between all laid out nodes linked by
 * edges
 */
mxFastOrganicLayout.prototype.calcAttraction = function()
{
	// Check the neighbours of each vertex and calculate the attractive
	// force of the edge connecting them
	for (var i = 0; i < this.vertexArray.length; i++)
	{
		for (var k = 0; k < this.neighbours[i].length; k++)
		{
			// Get the index of the othe cell in the vertex array
			var j = this.neighbours[i][k];
			
			// Do not proceed self-loops
			if (i != j &&
				this.isMoveable[i] &&
				this.isMoveable[j])
			{
				var xDelta = this.cellLocation[i][0] - this.cellLocation[j][0];
				var yDelta = this.cellLocation[i][1] - this.cellLocation[j][1];

				// The distance between the nodes
				var deltaLengthSquared = xDelta * xDelta + yDelta
						* yDelta - this.radiusSquared[i] - this.radiusSquared[j];

				if (deltaLengthSquared < this.minDistanceLimitSquared)
				{
					deltaLengthSquared = this.minDistanceLimitSquared;
				}
				
				var deltaLength = Math.sqrt(deltaLengthSquared);
				var force = (deltaLengthSquared) / this.forceConstant;

				var displacementX = (xDelta / deltaLength) * force;
				var displacementY = (yDelta / deltaLength) * force;
				
				this.dispX[i] -= displacementX;
				this.dispY[i] -= displacementY;
				
				this.dispX[j] += displacementX;
				this.dispY[j] += displacementY;
			}
		}
	}
};

/**
 * Function: calcRepulsion
 * 
 * Calculates the repulsive forces between all laid out nodes
 */
mxFastOrganicLayout.prototype.calcRepulsion = function()
{
	var vertexCount = this.vertexArray.length;

	for (var i = 0; i < vertexCount; i++)
	{
		for (var j = i; j < vertexCount; j++)
		{
			// Exits if the layout is no longer allowed to run
			if (!this.allowedToRun)
			{
				return;
			}

			if (j != i &&
				this.isMoveable[i] &&
				this.isMoveable[j])
			{
				var xDelta = this.cellLocation[i][0] - this.cellLocation[j][0];
				var yDelta = this.cellLocation[i][1] - this.cellLocation[j][1];

				if (xDelta == 0)
				{
					xDelta = 0.01 + Math.random();
				}
				
				if (yDelta == 0)
				{
					yDelta = 0.01 + Math.random();
				}
				
				// Distance between nodes
				var deltaLength = Math.sqrt((xDelta * xDelta)
						+ (yDelta * yDelta));
				var deltaLengthWithRadius = deltaLength - this.radius[i]
						- this.radius[j];

				if (deltaLengthWithRadius > this.maxDistanceLimit)
				{
					// Ignore vertices too far apart
					continue;
				}

				if (deltaLengthWithRadius < this.minDistanceLimit)
				{
					deltaLengthWithRadius = this.minDistanceLimit;
				}

				var force = this.forceConstantSquared / deltaLengthWithRadius;

				var displacementX = (xDelta / deltaLength) * force;
				var displacementY = (yDelta / deltaLength) * force;
				
				this.dispX[i] += displacementX;
				this.dispY[i] += displacementY;

				this.dispX[j] -= displacementX;
				this.dispY[j] -= displacementY;
			}
		}
	}
};

/**
 * Function: reduceTemperature
 * 
 * Reduces the temperature of the layout from an initial setting in a linear
 * fashion to zero.
 */
mxFastOrganicLayout.prototype.reduceTemperature = function()
{
	this.temperature = this.initialTemp * (1.0 - this.iteration / this.maxIterations);
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxCircleLayout
 * 
 * Extends <mxGraphLayout> to implement a circluar layout for a given radius.
 * The vertices do not need to be connected for this layout to work and all
 * connections between vertices are not taken into account.
 * 
 * Example:
 * 
 * (code)
 * var layout = new mxCircleLayout(graph);
 * layout.execute(graph.getDefaultParent());
 * (end)
 * 
 * Constructor: mxCircleLayout
 *
 * Constructs a new circular layout for the specified radius.
 *
 * Arguments:
 * 
 * graph - <mxGraph> that contains the cells.
 * radius - Optional radius as an int. Default is 100.
 */
function mxCircleLayout(graph, radius)
{
	mxGraphLayout.call(this, graph);
	this.radius = (radius != null) ? radius : 100;
};

/**
 * Extends mxGraphLayout.
 */
mxCircleLayout.prototype = new mxGraphLayout();
mxCircleLayout.prototype.constructor = mxCircleLayout;

/**
 * Variable: radius
 * 
 * Integer specifying the size of the radius. Default is 100.
 */
mxCircleLayout.prototype.radius = null;

/**
 * Variable: moveCircle
 * 
 * Boolean specifying if the circle should be moved to the top,
 * left corner specified by <x0> and <y0>. Default is false.
 */
mxCircleLayout.prototype.moveCircle = false;

/**
 * Variable: x0
 * 
 * Integer specifying the left coordinate of the circle.
 * Default is 0.
 */
mxCircleLayout.prototype.x0 = 0;

/**
 * Variable: y0
 * 
 * Integer specifying the top coordinate of the circle.
 * Default is 0.
 */
mxCircleLayout.prototype.y0 = 0;

/**
 * Variable: resetEdges
 * 
 * Specifies if all edge points of traversed edges should be removed.
 * Default is true.
 */
mxCircleLayout.prototype.resetEdges = true;

/**
 * Variable: disableEdgeStyle
 * 
 * Specifies if the STYLE_NOEDGESTYLE flag should be set on edges that are
 * modified by the result. Default is true.
 */
mxCircleLayout.prototype.disableEdgeStyle = true;

/**
 * Function: execute
 * 
 * Implements <mxGraphLayout.execute>.
 */
mxCircleLayout.prototype.execute = function(parent)
{
	var model = this.graph.getModel();

	// Moves the vertices to build a circle. Makes sure the
	// radius is large enough for the vertices to not
	// overlap
	model.beginUpdate();
	try
	{
		// Gets all vertices inside the parent and finds
		// the maximum dimension of the largest vertex
		var max = 0;
		var top = null;
		var left = null;
		var vertices = [];
		var childCount = model.getChildCount(parent);
		
		for (var i = 0; i < childCount; i++)
		{
			var cell = model.getChildAt(parent, i);
			
			if (!this.isVertexIgnored(cell))
			{
				vertices.push(cell);
				var bounds = this.getVertexBounds(cell);
				
				if (top == null)
				{
					top = bounds.y;
				}
				else
				{
					top = Math.min(top, bounds.y);
				}
				
				if (left == null)
				{
					left = bounds.x;
				}
				else
				{
					left = Math.min(left, bounds.x);
				}
				
				max = Math.max(max, Math.max(bounds.width, bounds.height));
			}
			else if (!this.isEdgeIgnored(cell))
			{
				// Resets the points on the traversed edge
				if (this.resetEdges)
				{
					this.graph.resetEdge(cell);
				}

			    if (this.disableEdgeStyle)
			    {
			    	this.setEdgeStyleEnabled(cell, false);
			    }
			}
		}
		
		var r = this.getRadius(vertices.length, max);

		// Moves the circle to the specified origin
		if (this.moveCircle)
		{
			left = this.x0;
			top = this.y0;
		}
		
		this.circle(vertices, r, left, top);
	}
	finally
	{
		model.endUpdate();
	}
};

/**
 * Function: getRadius
 * 
 * Returns the radius to be used for the given vertex count. Max is the maximum
 * width or height of all vertices in the layout.
 */
mxCircleLayout.prototype.getRadius = function(count, max)
{
	return Math.max(count * max / Math.PI, this.radius);
};

/**
 * Function: circle
 * 
 * Executes the circular layout for the specified array
 * of vertices and the given radius. This is called from
 * <execute>.
 */
mxCircleLayout.prototype.circle = function(vertices, r, left, top)
{
	var vertexCount = vertices.length;
	var phi = 2 * Math.PI / vertexCount;
	
	for (var i = 0; i < vertexCount; i++)
	{
		if (this.isVertexMovable(vertices[i]))
		{
			this.setVertexLocation(vertices[i],
				left + r + r * Math.sin(i*phi),
				top + r + r * Math.cos(i*phi));
		}
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxParallelEdgeLayout
 * 
 * Extends <mxGraphLayout> for arranging parallel edges. This layout works
 * on edges for all pairs of vertices where there is more than one edge
 * connecting the latter.
 * 
 * Example:
 * 
 * (code)
 * var layout = new mxParallelEdgeLayout(graph);
 * layout.execute(graph.getDefaultParent());
 * (end)
 * 
 * To run the layout for the parallel edges of a changed edge only, the
 * following code can be used.
 * 
 * (code)
 * var layout = new mxParallelEdgeLayout(graph);
 * 
 * graph.addListener(mxEvent.CELL_CONNECTED, function(sender, evt)
 * {
 *   var model = graph.getModel();
 *   var edge = evt.getProperty('edge');
 *   var src = model.getTerminal(edge, true);
 *   var trg = model.getTerminal(edge, false);
 *   
 *   layout.isEdgeIgnored = function(edge2)
 *   {
 *     var src2 = model.getTerminal(edge2, true);
 *     var trg2 = model.getTerminal(edge2, false);
 *     
 *     return !(model.isEdge(edge2) && ((src == src2 && trg == trg2) || (src == trg2 && trg == src2)));
 *   };
 *   
 *   layout.execute(graph.getDefaultParent());
 * });
 * (end)
 * 
 * Constructor: mxCompactTreeLayout
 * 
 * Constructs a new fast organic layout for the specified graph.
 */
function mxParallelEdgeLayout(graph)
{
	mxGraphLayout.call(this, graph);
};

/**
 * Extends mxGraphLayout.
 */
mxParallelEdgeLayout.prototype = new mxGraphLayout();
mxParallelEdgeLayout.prototype.constructor = mxParallelEdgeLayout;

/**
 * Variable: spacing
 * 
 * Defines the spacing between the parallels. Default is 20.
 */
mxParallelEdgeLayout.prototype.spacing = 20;

/**
 * Function: execute
 * 
 * Implements <mxGraphLayout.execute>.
 */
mxParallelEdgeLayout.prototype.execute = function(parent)
{
	var lookup = this.findParallels(parent);
	
	this.graph.model.beginUpdate();	
	try
	{
		for (var i in lookup)
		{
			var parallels = lookup[i];

			if (parallels.length > 1)
			{
				this.layout(parallels);
			}
		}
	}
	finally
	{
		this.graph.model.endUpdate();
	}
};

/**
 * Function: findParallels
 * 
 * Finds the parallel edges in the given parent.
 */
mxParallelEdgeLayout.prototype.findParallels = function(parent)
{
	var model = this.graph.getModel();
	var lookup = [];
	var childCount = model.getChildCount(parent);
	
	for (var i = 0; i < childCount; i++)
	{
		var child = model.getChildAt(parent, i);
		
		if (!this.isEdgeIgnored(child))
		{
			var id = this.getEdgeId(child);
			
			if (id != null)
			{
				if (lookup[id] == null)
				{
					lookup[id] = [];
				}
				
				lookup[id].push(child);
			}
		}
	}
	
	return lookup;
};

/**
 * Function: getEdgeId
 * 
 * Returns a unique ID for the given edge. The id is independent of the
 * edge direction and is built using the visible terminal of the given
 * edge.
 */
mxParallelEdgeLayout.prototype.getEdgeId = function(edge)
{
	var view = this.graph.getView();
	
	// Cannot used cached visible terminal because this could be triggered in BEFORE_UNDO
	var src = view.getVisibleTerminal(edge, true);
	var trg = view.getVisibleTerminal(edge, false);

	if (src != null && trg != null)
	{
		src = mxObjectIdentity.get(src);
		trg = mxObjectIdentity.get(trg);
		
		return (src > trg) ? trg + '-' + src : src + '-' + trg;
	}
	
	return null;
};

/**
 * Function: layout
 * 
 * Lays out the parallel edges in the given array.
 */
mxParallelEdgeLayout.prototype.layout = function(parallels)
{
	var edge = parallels[0];
	var view = this.graph.getView();
	var model = this.graph.getModel();
	var src = model.getGeometry(view.getVisibleTerminal(edge, true));
	var trg = model.getGeometry(view.getVisibleTerminal(edge, false));
	
	// Routes multiple loops
	if (src == trg)
	{
		var x0 = src.x + src.width + this.spacing;
		var y0 = src.y + src.height / 2;

		for (var i = 0; i < parallels.length; i++)
		{
			this.route(parallels[i], x0, y0);
			x0 += this.spacing;
		}
	}
	else if (src != null && trg != null)
	{
		// Routes parallel edges
		var scx = src.x + src.width / 2;
		var scy = src.y + src.height / 2;
		
		var tcx = trg.x + trg.width / 2;
		var tcy = trg.y + trg.height / 2;
		
		var dx = tcx - scx;
		var dy = tcy - scy;

		var len = Math.sqrt(dx * dx + dy * dy);
		
		if (len > 0)
		{
			var x0 = scx + dx / 2;
			var y0 = scy + dy / 2;
			
			var nx = dy * this.spacing / len;
			var ny = dx * this.spacing / len;
			
			x0 += nx * (parallels.length - 1) / 2;
			y0 -= ny * (parallels.length - 1) / 2;
	
			for (var i = 0; i < parallels.length; i++)
			{
				this.route(parallels[i], x0, y0);
				x0 -= nx;
				y0 += ny;
			}
		}
	}
};

/**
 * Function: route
 * 
 * Routes the given edge via the given point.
 */
mxParallelEdgeLayout.prototype.route = function(edge, x, y)
{
	if (this.graph.isCellMovable(edge))
	{
		this.setEdgePoints(edge, [new mxPoint(x, y)]);
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxCompositeLayout
 * 
 * Allows to compose multiple layouts into a single layout. The master layout
 * is the layout that handles move operations if another layout than the first
 * element in <layouts> should be used. The <master> layout is not executed as
 * the code assumes that it is part of <layouts>.
 * 
 * Example:
 * (code)
 * var first = new mxFastOrganicLayout(graph);
 * var second = new mxParallelEdgeLayout(graph);
 * var layout = new mxCompositeLayout(graph, [first, second], first);
 * layout.execute(graph.getDefaultParent());
 * (end)
 * 
 * Constructor: mxCompositeLayout
 *
 * Constructs a new layout using the given layouts. The graph instance is
 * required for creating the transaction that contains all layouts.
 *
 * Arguments:
 * 
 * graph - Reference to the enclosing <mxGraph>.
 * layouts - Array of <mxGraphLayouts>.
 * master - Optional layout that handles moves. If no layout is given then
 * the first layout of the above array is used to handle moves.
 */
function mxCompositeLayout(graph, layouts, master)
{
	mxGraphLayout.call(this, graph);
	this.layouts = layouts;
	this.master = master;
};

/**
 * Extends mxGraphLayout.
 */
mxCompositeLayout.prototype = new mxGraphLayout();
mxCompositeLayout.prototype.constructor = mxCompositeLayout;
	
/**
 * Variable: layouts
 * 
 * Holds the array of <mxGraphLayouts> that this layout contains.
 */
mxCompositeLayout.prototype.layouts = null;

/**
 * Variable: layouts
 * 
 * Reference to the <mxGraphLayouts> that handles moves. If this is null
 * then the first layout in <layouts> is used.
 */
mxCompositeLayout.prototype.master = null;

/**
 * Function: moveCell
 * 
 * Implements <mxGraphLayout.moveCell> by calling move on <master> or the first
 * layout in <layouts>.
 */
mxCompositeLayout.prototype.moveCell = function(cell, x, y)
{
	if (this.master != null)
	{
		this.master.move.apply(this.master, arguments);
	}
	else
	{
		this.layouts[0].move.apply(this.layouts[0], arguments);
	}
};

/**
 * Function: execute
 * 
 * Implements <mxGraphLayout.execute> by executing all <layouts> in a
 * single transaction.
 */
mxCompositeLayout.prototype.execute = function(parent)
{
	var model = this.graph.getModel();
	
	model.beginUpdate();
	try
	{
		for (var i = 0; i < this.layouts.length; i++)
		{
			this.layouts[i].execute.apply(this.layouts[i], arguments);
		}
	}
	finally
	{
		model.endUpdate();
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxEdgeLabelLayout
 * 
 * Extends <mxGraphLayout> to implement an edge label layout. This layout
 * makes use of cell states, which means the graph must be validated in
 * a graph view (so that the label bounds are available) before this layout
 * can be executed.
 * 
 * Example:
 * 
 * (code)
 * var layout = new mxEdgeLabelLayout(graph);
 * layout.execute(graph.getDefaultParent());
 * (end)
 * 
 * Constructor: mxEdgeLabelLayout
 *
 * Constructs a new edge label layout.
 *
 * Arguments:
 * 
 * graph - <mxGraph> that contains the cells.
 */
function mxEdgeLabelLayout(graph, radius)
{
	mxGraphLayout.call(this, graph);
};

/**
 * Extends mxGraphLayout.
 */
mxEdgeLabelLayout.prototype = new mxGraphLayout();
mxEdgeLabelLayout.prototype.constructor = mxEdgeLabelLayout;

/**
 * Function: execute
 * 
 * Implements <mxGraphLayout.execute>.
 */
mxEdgeLabelLayout.prototype.execute = function(parent)
{
	var view = this.graph.view;
	var model = this.graph.getModel();
	
	// Gets all vertices and edges inside the parent
	var edges = [];
	var vertices = [];
	var childCount = model.getChildCount(parent);
	
	for (var i = 0; i < childCount; i++)
	{
		var cell = model.getChildAt(parent, i);
		var state = view.getState(cell);
		
		if (state != null)
		{
			if (!this.isVertexIgnored(cell))
			{
				vertices.push(state);
			}
			else if (!this.isEdgeIgnored(cell))
			{
				edges.push(state);
			}
		}
	}
	
	this.placeLabels(vertices, edges);
};

/**
 * Function: placeLabels
 * 
 * Places the labels of the given edges.
 */
mxEdgeLabelLayout.prototype.placeLabels = function(v, e)
{
	var model = this.graph.getModel();
	
	// Moves the vertices to build a circle. Makes sure the
	// radius is large enough for the vertices to not
	// overlap
	model.beginUpdate();
	try
	{
		for (var i = 0; i < e.length; i++)
		{
			var edge = e[i];
			
			if (edge != null && edge.text != null &&
				edge.text.boundingBox != null)
			{
				for (var j = 0; j < v.length; j++)
				{
					var vertex = v[j];
					
					if (vertex != null)
					{
						this.avoid(edge, vertex);
					}
				}
			}
		}
	}
	finally
	{
		model.endUpdate();
	}
};

/**
 * Function: avoid
 * 
 * Places the labels of the given edges.
 */
mxEdgeLabelLayout.prototype.avoid = function(edge, vertex)
{
	var model = this.graph.getModel();
	var labRect = edge.text.boundingBox;
	
	if (mxUtils.intersects(labRect, vertex))
	{
		var dy1 = -labRect.y - labRect.height + vertex.y;
		var dy2 = -labRect.y + vertex.y + vertex.height;
		
		var dy = (Math.abs(dy1) < Math.abs(dy2)) ? dy1 : dy2;
		
		var dx1 = -labRect.x - labRect.width + vertex.x;
		var dx2 = -labRect.x + vertex.x + vertex.width;
	
		var dx = (Math.abs(dx1) < Math.abs(dx2)) ? dx1 : dx2;
		
		if (Math.abs(dx) < Math.abs(dy))
		{
			dy = 0;
		}
		else
		{
			dx = 0;
		}
	
		var g = model.getGeometry(edge.cell);
		
		if (g != null)
		{
			g = g.clone();
			
			if (g.offset != null)
			{
				g.offset.x += dx;
				g.offset.y += dy;
			}
			else
			{
				g.offset = new mxPoint(dx, dy);
			}
			
			model.setGeometry(edge.cell, g);
		}
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxGraphAbstractHierarchyCell
 * 
 * An abstraction of an internal hierarchy node or edge
 * 
 * Constructor: mxGraphAbstractHierarchyCell
 *
 * Constructs a new hierarchical layout algorithm.
 *
 * Arguments:
 * 
 * graph - Reference to the enclosing <mxGraph>.
 * deterministic - Optional boolean that specifies if this layout should be
 * deterministic. Default is true.
 */
function mxGraphAbstractHierarchyCell()
{
	this.x = [];
	this.y = [];
	this.temp = [];
};

/**
 * Variable: maxRank
 * 
 * The maximum rank this cell occupies. Default is -1.
 */
mxGraphAbstractHierarchyCell.prototype.maxRank = -1;

/**
 * Variable: minRank
 * 
 * The minimum rank this cell occupies. Default is -1.
 */
mxGraphAbstractHierarchyCell.prototype.minRank = -1;

/**
 * Variable: x
 * 
 * The x position of this cell for each layer it occupies
 */
mxGraphAbstractHierarchyCell.prototype.x = null;

/**
 * Variable: y
 * 
 * The y position of this cell for each layer it occupies
 */
mxGraphAbstractHierarchyCell.prototype.y = null;

/**
 * Variable: width
 * 
 * The width of this cell
 */
mxGraphAbstractHierarchyCell.prototype.width = 0;

/**
 * Variable: height
 * 
 * The height of this cell
 */
mxGraphAbstractHierarchyCell.prototype.height = 0;

/**
 * Variable: nextLayerConnectedCells
 * 
 * A cached version of the cells this cell connects to on the next layer up
 */
mxGraphAbstractHierarchyCell.prototype.nextLayerConnectedCells = null;

/**
 * Variable: previousLayerConnectedCells
 * 
 * A cached version of the cells this cell connects to on the next layer down
 */
mxGraphAbstractHierarchyCell.prototype.previousLayerConnectedCells = null;

/**
 * Variable: temp
 * 
 * Temporary variable for general use. Generally, try to avoid
 * carrying information between stages. Currently, the longest
 * path layering sets temp to the rank position in fixRanks()
 * and the crossing reduction uses this. This meant temp couldn't
 * be used for hashing the nodes in the model dfs and so hashCode
 * was created
 */
mxGraphAbstractHierarchyCell.prototype.temp = null;

/**
 * Function: getNextLayerConnectedCells
 * 
 * Returns the cells this cell connects to on the next layer up
 */
mxGraphAbstractHierarchyCell.prototype.getNextLayerConnectedCells = function(layer)
{
	return null;
};

/**
 * Function: getPreviousLayerConnectedCells
 * 
 * Returns the cells this cell connects to on the next layer down
 */
mxGraphAbstractHierarchyCell.prototype.getPreviousLayerConnectedCells = function(layer)
{
	return null;
};

/**
 * Function: isEdge
 * 
 * Returns whether or not this cell is an edge
 */
mxGraphAbstractHierarchyCell.prototype.isEdge = function()
{
	return false;
};

/**
 * Function: isVertex
 * 
 * Returns whether or not this cell is a node
 */
mxGraphAbstractHierarchyCell.prototype.isVertex = function()
{
	return false;
};

/**
 * Function: getGeneralPurposeVariable
 * 
 * Gets the value of temp for the specified layer
 */
mxGraphAbstractHierarchyCell.prototype.getGeneralPurposeVariable = function(layer)
{
	return null;
};

/**
 * Function: setGeneralPurposeVariable
 * 
 * Set the value of temp for the specified layer
 */
mxGraphAbstractHierarchyCell.prototype.setGeneralPurposeVariable = function(layer, value)
{
	return null;
};

/**
 * Function: setX
 * 
 * Set the value of x for the specified layer
 */
mxGraphAbstractHierarchyCell.prototype.setX = function(layer, value)
{
	if (this.isVertex())
	{
		this.x[0] = value;
	}
	else if (this.isEdge())
	{
		this.x[layer - this.minRank - 1] = value;
	}
};

/**
 * Function: getX
 * 
 * Gets the value of x on the specified layer
 */
mxGraphAbstractHierarchyCell.prototype.getX = function(layer)
{
	if (this.isVertex())
	{
		return this.x[0];
	}
	else if (this.isEdge())
	{
		return this.x[layer - this.minRank - 1];
	}

	return 0.0;
};

/**
 * Function: setY
 * 
 * Set the value of y for the specified layer
 */
mxGraphAbstractHierarchyCell.prototype.setY = function(layer, value)
{
	if (this.isVertex())
	{
		this.y[0] = value;
	}
	else if (this.isEdge())
	{
		this.y[layer -this. minRank - 1] = value;
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxGraphHierarchyNode
 * 
 * An abstraction of a hierarchical edge for the hierarchy layout
 * 
 * Constructor: mxGraphHierarchyNode
 *
 * Constructs an internal node to represent the specified real graph cell
 *
 * Arguments:
 * 
 * cell - the real graph cell this node represents
 */
function mxGraphHierarchyNode(cell)
{
	mxGraphAbstractHierarchyCell.apply(this, arguments);
	this.cell = cell;
	this.id = mxObjectIdentity.get(cell);
	this.connectsAsTarget = [];
	this.connectsAsSource = [];
};

/**
 * Extends mxGraphAbstractHierarchyCell.
 */
mxGraphHierarchyNode.prototype = new mxGraphAbstractHierarchyCell();
mxGraphHierarchyNode.prototype.constructor = mxGraphHierarchyNode;

/**
 * Variable: cell
 * 
 * The graph cell this object represents.
 */
mxGraphHierarchyNode.prototype.cell = null;

/**
 * Variable: id
 * 
 * The object identity of the wrapped cell
 */
mxGraphHierarchyNode.prototype.id = null;

/**
 * Variable: connectsAsTarget
 * 
 * Collection of hierarchy edges that have this node as a target
 */
mxGraphHierarchyNode.prototype.connectsAsTarget = null;

/**
 * Variable: connectsAsSource
 * 
 * Collection of hierarchy edges that have this node as a source
 */
mxGraphHierarchyNode.prototype.connectsAsSource = null;

/**
 * Variable: hashCode
 * 
 * Assigns a unique hashcode for each node. Used by the model dfs instead
 * of copying HashSets
 */
mxGraphHierarchyNode.prototype.hashCode = false;

/**
 * Function: getRankValue
 * 
 * Returns the integer value of the layer that this node resides in
 */
mxGraphHierarchyNode.prototype.getRankValue = function(layer)
{
	return this.maxRank;
};

/**
 * Function: getNextLayerConnectedCells
 * 
 * Returns the cells this cell connects to on the next layer up
 */
mxGraphHierarchyNode.prototype.getNextLayerConnectedCells = function(layer)
{
	if (this.nextLayerConnectedCells == null)
	{
		this.nextLayerConnectedCells = [];
		this.nextLayerConnectedCells[0] = [];
		
		for (var i = 0; i < this.connectsAsTarget.length; i++)
		{
			var edge = this.connectsAsTarget[i];

			if (edge.maxRank == -1 || edge.maxRank == layer + 1)
			{
				// Either edge is not in any rank or
				// no dummy nodes in edge, add node of other side of edge
				this.nextLayerConnectedCells[0].push(edge.source);
			}
			else
			{
				// Edge spans at least two layers, add edge
				this.nextLayerConnectedCells[0].push(edge);
			}
		}
	}

	return this.nextLayerConnectedCells[0];
};

/**
 * Function: getPreviousLayerConnectedCells
 * 
 * Returns the cells this cell connects to on the next layer down
 */
mxGraphHierarchyNode.prototype.getPreviousLayerConnectedCells = function(layer)
{
	if (this.previousLayerConnectedCells == null)
	{
		this.previousLayerConnectedCells = [];
		this.previousLayerConnectedCells[0] = [];
		
		for (var i = 0; i < this.connectsAsSource.length; i++)
		{
			var edge = this.connectsAsSource[i];

			if (edge.minRank == -1 || edge.minRank == layer - 1)
			{
				// No dummy nodes in edge, add node of other side of edge
				this.previousLayerConnectedCells[0].push(edge.target);
			}
			else
			{
				// Edge spans at least two layers, add edge
				this.previousLayerConnectedCells[0].push(edge);
			}
		}
	}

	return this.previousLayerConnectedCells[0];
};

/**
 * Function: isVertex
 * 
 * Returns true.
 */
mxGraphHierarchyNode.prototype.isVertex = function()
{
	return true;
};

/**
 * Function: getGeneralPurposeVariable
 * 
 * Gets the value of temp for the specified layer
 */
mxGraphHierarchyNode.prototype.getGeneralPurposeVariable = function(layer)
{
	return this.temp[0];
};

/**
 * Function: setGeneralPurposeVariable
 * 
 * Set the value of temp for the specified layer
 */
mxGraphHierarchyNode.prototype.setGeneralPurposeVariable = function(layer, value)
{
	this.temp[0] = value;
};

/**
 * Function: isAncestor
 */
mxGraphHierarchyNode.prototype.isAncestor = function(otherNode)
{
	// Firstly, the hash code of this node needs to be shorter than the
	// other node
	if (otherNode != null && this.hashCode != null && otherNode.hashCode != null
			&& this.hashCode.length < otherNode.hashCode.length)
	{
		if (this.hashCode == otherNode.hashCode)
		{
			return true;
		}
		
		if (this.hashCode == null || this.hashCode == null)
		{
			return false;
		}
		
		// Secondly, this hash code must match the start of the other
		// node's hash code. Arrays.equals cannot be used here since
		// the arrays are different length, and we do not want to
		// perform another array copy.
		for (var i = 0; i < this.hashCode.length; i++)
		{
			if (this.hashCode[i] != otherNode.hashCode[i])
			{
				return false;
			}
		}

		return true;
	}

	return false;
};

/**
 * Function: getCoreCell
 * 
 * Gets the core vertex associated with this wrapper
 */
mxGraphHierarchyNode.prototype.getCoreCell = function()
{
	return this.cell;
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxGraphHierarchyEdge
 * 
 * An abstraction of a hierarchical edge for the hierarchy layout
 * 
 * Constructor: mxGraphHierarchyEdge
 *
 * Constructs a hierarchy edge
 *
 * Arguments:
 * 
 * edges - a list of real graph edges this abstraction represents
 */
function mxGraphHierarchyEdge(edges)
{
	mxGraphAbstractHierarchyCell.apply(this, arguments);
	this.edges = edges;
	this.ids = [];
	
	for (var i = 0; i < edges.length; i++)
	{
		this.ids.push(mxObjectIdentity.get(edges[i]));
	}
};

/**
 * Extends mxGraphAbstractHierarchyCell.
 */
mxGraphHierarchyEdge.prototype = new mxGraphAbstractHierarchyCell();
mxGraphHierarchyEdge.prototype.constructor = mxGraphHierarchyEdge;

/**
 * Variable: edges
 * 
 * The graph edge(s) this object represents. Parallel edges are all grouped
 * together within one hierarchy edge.
 */
mxGraphHierarchyEdge.prototype.edges = null;

/**
 * Variable: ids
 * 
 * The object identities of the wrapped cells
 */
mxGraphHierarchyEdge.prototype.ids = null;

/**
 * Variable: source
 * 
 * The node this edge is sourced at
 */
mxGraphHierarchyEdge.prototype.source = null;

/**
 * Variable: target
 * 
 * The node this edge targets
 */
mxGraphHierarchyEdge.prototype.target = null;

/**
 * Variable: isReversed
 * 
 * Whether or not the direction of this edge has been reversed
 * internally to create a DAG for the hierarchical layout
 */
mxGraphHierarchyEdge.prototype.isReversed = false;

/**
 * Function: invert
 * 
 * Inverts the direction of this internal edge(s)
 */
mxGraphHierarchyEdge.prototype.invert = function(layer)
{
	var temp = this.source;
	this.source = this.target;
	this.target = temp;
	this.isReversed = !this.isReversed;
};

/**
 * Function: getNextLayerConnectedCells
 * 
 * Returns the cells this cell connects to on the next layer up
 */
mxGraphHierarchyEdge.prototype.getNextLayerConnectedCells = function(layer)
{
	if (this.nextLayerConnectedCells == null)
	{
		this.nextLayerConnectedCells = [];
		
		for (var i = 0; i < this.temp.length; i++)
		{
			this.nextLayerConnectedCells[i] = [];
			
			if (i == this.temp.length - 1)
			{
				this.nextLayerConnectedCells[i].push(this.source);
			}
			else
			{
				this.nextLayerConnectedCells[i].push(this);
			}
		}
	}
	
	return this.nextLayerConnectedCells[layer - this.minRank - 1];
};

/**
 * Function: getPreviousLayerConnectedCells
 * 
 * Returns the cells this cell connects to on the next layer down
 */
mxGraphHierarchyEdge.prototype.getPreviousLayerConnectedCells = function(layer)
{
	if (this.previousLayerConnectedCells == null)
	{
		this.previousLayerConnectedCells = [];

		for (var i = 0; i < this.temp.length; i++)
		{
			this.previousLayerConnectedCells[i] = [];
			
			if (i == 0)
			{
				this.previousLayerConnectedCells[i].push(this.target);
			}
			else
			{
				this.previousLayerConnectedCells[i].push(this);
			}
		}
	}

	return this.previousLayerConnectedCells[layer - this.minRank - 1];
};

/**
 * Function: isEdge
 * 
 * Returns true.
 */
mxGraphHierarchyEdge.prototype.isEdge = function()
{
	return true;
};

/**
 * Function: getGeneralPurposeVariable
 * 
 * Gets the value of temp for the specified layer
 */
mxGraphHierarchyEdge.prototype.getGeneralPurposeVariable = function(layer)
{
	return this.temp[layer - this.minRank - 1];
};

/**
 * Function: setGeneralPurposeVariable
 * 
 * Set the value of temp for the specified layer
 */
mxGraphHierarchyEdge.prototype.setGeneralPurposeVariable = function(layer, value)
{
	this.temp[layer - this.minRank - 1] = value;
};

/**
 * Function: getCoreCell
 * 
 * Gets the first core edge associated with this wrapper
 */
mxGraphHierarchyEdge.prototype.getCoreCell = function()
{
	if (this.edges != null && this.edges.length > 0)
	{
		return this.edges[0];
	}
	
	return null;
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxGraphHierarchyModel
 *
 * Internal model of a hierarchical graph. This model stores nodes and edges
 * equivalent to the real graph nodes and edges, but also stores the rank of the
 * cells, the order within the ranks and the new candidate locations of cells.
 * The internal model also reverses edge direction were appropriate , ignores
 * self-loop and groups parallels together under one edge object.
 *
 * Constructor: mxGraphHierarchyModel
 *
 * Creates an internal ordered graph model using the vertices passed in. If
 * there are any, leftward edge need to be inverted in the internal model
 *
 * Arguments:
 *
 * graph - the facade describing the graph to be operated on
 * vertices - the vertices for this hierarchy
 * ordered - whether or not the vertices are already ordered
 * deterministic - whether or not this layout should be deterministic on each
 * tightenToSource - whether or not to tighten vertices towards the sources
 * scanRanksFromSinks - Whether rank assignment is from the sinks or sources.
 * usage
 */
function mxGraphHierarchyModel(layout, vertices, roots, parent, tightenToSource)
{
	var graph = layout.getGraph();
	this.tightenToSource = tightenToSource;
	this.roots = roots;
	this.parent = parent;

	// map of cells to internal cell needed for second run through
	// to setup the sink of edges correctly
	this.vertexMapper = new mxDictionary();
	this.edgeMapper = new mxDictionary();
	this.maxRank = 0;
	var internalVertices = [];

	if (vertices == null)
	{
		vertices = this.graph.getChildVertices(parent);
	}

	this.maxRank = this.SOURCESCANSTARTRANK;
	// map of cells to internal cell needed for second run through
	// to setup the sink of edges correctly. Guess size by number
	// of edges is roughly same as number of vertices.
	this.createInternalCells(layout, vertices, internalVertices);

	// Go through edges set their sink values. Also check the
	// ordering if and invert edges if necessary
	for (var i = 0; i < vertices.length; i++)
	{
		var edges = internalVertices[i].connectsAsSource;

		for (var j = 0; j < edges.length; j++)
		{
			var internalEdge = edges[j];
			var realEdges = internalEdge.edges;

			// Only need to process the first real edge, since
			// all the edges connect to the same other vertex
			if (realEdges != null && realEdges.length > 0)
			{
				var realEdge = realEdges[0];
				var targetCell = layout.getVisibleTerminal(
						realEdge, false);
				var internalTargetCell = this.vertexMapper.get(targetCell);

				if (internalVertices[i] == internalTargetCell)
				{
					// If there are parallel edges going between two vertices and not all are in the same direction
					// you can have navigated across one direction when doing the cycle reversal that isn't the same
					// direction as the first real edge in the array above. When that happens the if above catches
					// that and we correct the target cell before continuing.
					// This branch only detects this single case
					targetCell = layout.getVisibleTerminal(
							realEdge, true);
					internalTargetCell = this.vertexMapper.get(targetCell);
				}
				
				if (internalTargetCell != null
						&& internalVertices[i] != internalTargetCell)
				{
					internalEdge.target = internalTargetCell;

					if (internalTargetCell.connectsAsTarget.length == 0)
					{
						internalTargetCell.connectsAsTarget = [];
					}

					if (mxUtils.indexOf(internalTargetCell.connectsAsTarget, internalEdge) < 0)
					{
						internalTargetCell.connectsAsTarget.push(internalEdge);
					}
				}
			}
		}

		// Use the temp variable in the internal nodes to mark this
		// internal vertex as having been visited.
		internalVertices[i].temp[0] = 1;
	}
};

/**
 * Variable: maxRank
 *
 * Stores the largest rank number allocated
 */
mxGraphHierarchyModel.prototype.maxRank = null;

/**
 * Variable: vertexMapper
 *
 * Map from graph vertices to internal model nodes.
 */
mxGraphHierarchyModel.prototype.vertexMapper = null;

/**
 * Variable: edgeMapper
 *
 * Map from graph edges to internal model edges
 */
mxGraphHierarchyModel.prototype.edgeMapper = null;

/**
 * Variable: ranks
 *
 * Mapping from rank number to actual rank
 */
mxGraphHierarchyModel.prototype.ranks = null;

/**
 * Variable: roots
 *
 * Store of roots of this hierarchy model, these are real graph cells, not
 * internal cells
 */
mxGraphHierarchyModel.prototype.roots = null;

/**
 * Variable: parent
 *
 * The parent cell whose children are being laid out
 */
mxGraphHierarchyModel.prototype.parent = null;

/**
 * Variable: dfsCount
 *
 * Count of the number of times the ancestor dfs has been used.
 */
mxGraphHierarchyModel.prototype.dfsCount = 0;

/**
 * Variable: SOURCESCANSTARTRANK
 *
 * High value to start source layering scan rank value from.
 */
mxGraphHierarchyModel.prototype.SOURCESCANSTARTRANK = 100000000;

/**
 * Variable: tightenToSource
 *
 * Whether or not to tighten the assigned ranks of vertices up towards
 * the source cells.
 */
mxGraphHierarchyModel.prototype.tightenToSource = false;

/**
 * Function: createInternalCells
 *
 * Creates all edges in the internal model
 *
 * Parameters:
 *
 * layout - Reference to the <mxHierarchicalLayout> algorithm.
 * vertices - Array of <mxCells> that represent the vertices whom are to
 * have an internal representation created.
 * internalVertices - The array of <mxGraphHierarchyNodes> to have their
 * information filled in using the real vertices.
 */
mxGraphHierarchyModel.prototype.createInternalCells = function(layout, vertices, internalVertices)
{
	var graph = layout.getGraph();

	// Create internal edges
	for (var i = 0; i < vertices.length; i++)
	{
		internalVertices[i] = new mxGraphHierarchyNode(vertices[i]);
		this.vertexMapper.put(vertices[i], internalVertices[i]);

		// If the layout is deterministic, order the cells
		//List outgoingCells = graph.getNeighbours(vertices[i], deterministic);
		var conns = layout.getEdges(vertices[i]);
		internalVertices[i].connectsAsSource = [];

		// Create internal edges, but don't do any rank assignment yet
		// First use the information from the greedy cycle remover to
		// invert the leftward edges internally
		for (var j = 0; j < conns.length; j++)
		{
			var cell = layout.getVisibleTerminal(conns[j], false);

			// Looking for outgoing edges only
			if (cell != vertices[i] && layout.graph.model.isVertex(cell) &&
					!layout.isVertexIgnored(cell))
			{
				// We process all edge between this source and its targets
				// If there are edges going both ways, we need to collect
				// them all into one internal edges to avoid looping problems
				// later. We assume this direction (source -> target) is the 
				// natural direction if at least half the edges are going in
				// that direction.

				// The check below for edges[0] being in the vertex mapper is
				// in case we've processed this the other way around
				// (target -> source) and the number of edges in each direction
				// are the same. All the graph edges will have been assigned to
				// an internal edge going the other way, so we don't want to 
				// process them again
				var undirectedEdges = layout.getEdgesBetween(vertices[i],
						cell, false);
				var directedEdges = layout.getEdgesBetween(vertices[i],
						cell, true);
				
				if (undirectedEdges != null &&
						undirectedEdges.length > 0 &&
						this.edgeMapper.get(undirectedEdges[0]) == null &&
						directedEdges.length * 2 >= undirectedEdges.length)
				{
					var internalEdge = new mxGraphHierarchyEdge(undirectedEdges);

					for (var k = 0; k < undirectedEdges.length; k++)
					{
						var edge = undirectedEdges[k];
						this.edgeMapper.put(edge, internalEdge);

						// Resets all point on the edge and disables the edge style
						// without deleting it from the cell style
						graph.resetEdge(edge);

					    if (layout.disableEdgeStyle)
					    {
					    	layout.setEdgeStyleEnabled(edge, false);
					    	layout.setOrthogonalEdge(edge,true);
					    }
					}

					internalEdge.source = internalVertices[i];

					if (mxUtils.indexOf(internalVertices[i].connectsAsSource, internalEdge) < 0)
					{
						internalVertices[i].connectsAsSource.push(internalEdge);
					}
				}
			}
		}

		// Ensure temp variable is cleared from any previous use
		internalVertices[i].temp[0] = 0;
	}
};

/**
 * Function: initialRank
 *
 * Basic determination of minimum layer ranking by working from from sources
 * or sinks and working through each node in the relevant edge direction.
 * Starting at the sinks is basically a longest path layering algorithm.
*/
mxGraphHierarchyModel.prototype.initialRank = function()
{
	var startNodes = [];

	if (this.roots != null)
	{
		for (var i = 0; i < this.roots.length; i++)
		{
			var internalNode = this.vertexMapper.get(this.roots[i]);

			if (internalNode != null)
			{
				startNodes.push(internalNode);
			}
		}
	}

	var internalNodes = this.vertexMapper.getValues();
	
	for (var i=0; i < internalNodes.length; i++)
	{
		// Mark the node as not having had a layer assigned
		internalNodes[i].temp[0] = -1;
	}

	var startNodesCopy = startNodes.slice();

	while (startNodes.length > 0)
	{
		var internalNode = startNodes[0];
		var layerDeterminingEdges;
		var edgesToBeMarked;

		layerDeterminingEdges = internalNode.connectsAsTarget;
		edgesToBeMarked = internalNode.connectsAsSource;

		// flag to keep track of whether or not all layer determining
		// edges have been scanned
		var allEdgesScanned = true;

		// Work out the layer of this node from the layer determining
		// edges. The minimum layer number of any node connected by one of
		// the layer determining edges variable
		var minimumLayer = this.SOURCESCANSTARTRANK;

		for (var i = 0; i < layerDeterminingEdges.length; i++)
		{
			var internalEdge = layerDeterminingEdges[i];

			if (internalEdge.temp[0] == 5270620)
			{
				// This edge has been scanned, get the layer of the
				// node on the other end
				var otherNode = internalEdge.source;
				minimumLayer = Math.min(minimumLayer, otherNode.temp[0] - 1);
			}
			else
			{
				allEdgesScanned = false;

				break;
			}
		}

		// If all edge have been scanned, assign the layer, mark all
		// edges in the other direction and remove from the nodes list
		if (allEdgesScanned)
		{
			internalNode.temp[0] = minimumLayer;
			this.maxRank = Math.min(this.maxRank, minimumLayer);

			if (edgesToBeMarked != null)
			{
				for (var i = 0; i < edgesToBeMarked.length; i++)
				{
					var internalEdge = edgesToBeMarked[i];

					// Assign unique stamp ( y/m/d/h )
					internalEdge.temp[0] = 5270620;

					// Add node on other end of edge to LinkedList of
					// nodes to be analysed
					var otherNode = internalEdge.target;

					// Only add node if it hasn't been assigned a layer
					if (otherNode.temp[0] == -1)
					{
						startNodes.push(otherNode);

						// Mark this other node as neither being
						// unassigned nor assigned so it isn't
						// added to this list again, but it's
						// layer isn't used in any calculation.
						otherNode.temp[0] = -2;
					}
				}
			}

			startNodes.shift();
		}
		else
		{
			// Not all the edges have been scanned, get to the back of
			// the class and put the dunces cap on
			var removedCell = startNodes.shift();
			startNodes.push(internalNode);

			if (removedCell == internalNode && startNodes.length == 1)
			{
				// This is an error condition, we can't get out of
				// this loop. It could happen for more than one node
				// but that's a lot harder to detect. Log the error
				// TODO make log comment
				break;
			}
		}
	}

	// Normalize the ranks down from their large starting value to place
	// at least 1 sink on layer 0
	for (var i=0; i < internalNodes.length; i++)
	{
		// Mark the node as not having had a layer assigned
		internalNodes[i].temp[0] -= this.maxRank;
	}
	
	// Tighten the rank 0 nodes as far as possible
	for ( var i = 0; i < startNodesCopy.length; i++)
	{
		var internalNode = startNodesCopy[i];
		var currentMaxLayer = 0;
		var layerDeterminingEdges = internalNode.connectsAsSource;

		for ( var j = 0; j < layerDeterminingEdges.length; j++)
		{
			var internalEdge = layerDeterminingEdges[j];
			var otherNode = internalEdge.target;
			internalNode.temp[0] = Math.max(currentMaxLayer,
					otherNode.temp[0] + 1);
			currentMaxLayer = internalNode.temp[0];
		}
	}
	
	// Reset the maxRank to that which would be expected for a from-sink
	// scan
	this.maxRank = this.SOURCESCANSTARTRANK - this.maxRank;
};

/**
 * Function: fixRanks
 *
 * Fixes the layer assignments to the values stored in the nodes. Also needs
 * to create dummy nodes for edges that cross layers.
 */
mxGraphHierarchyModel.prototype.fixRanks = function()
{
	var rankList = [];
	this.ranks = [];

	for (var i = 0; i < this.maxRank + 1; i++)
	{
		rankList[i] = [];
		this.ranks[i] = rankList[i];
	}

	// Perform a DFS to obtain an initial ordering for each rank.
	// Without doing this you would end up having to process
	// crossings for a standard tree.
	var rootsArray = null;

	if (this.roots != null)
	{
		var oldRootsArray = this.roots;
		rootsArray = [];

		for (var i = 0; i < oldRootsArray.length; i++)
		{
			var cell = oldRootsArray[i];
			var internalNode = this.vertexMapper.get(cell);
			rootsArray[i] = internalNode;
		}
	}

	this.visit(function(parent, node, edge, layer, seen)
	{
		if (seen == 0 && node.maxRank < 0 && node.minRank < 0)
		{
			rankList[node.temp[0]].push(node);
			node.maxRank = node.temp[0];
			node.minRank = node.temp[0];

			// Set temp[0] to the nodes position in the rank
			node.temp[0] = rankList[node.maxRank].length - 1;
		}

		if (parent != null && edge != null)
		{
			var parentToCellRankDifference = parent.maxRank - node.maxRank;

			if (parentToCellRankDifference > 1)
			{
				// There are ranks in between the parent and current cell
				edge.maxRank = parent.maxRank;
				edge.minRank = node.maxRank;
				edge.temp = [];
				edge.x = [];
				edge.y = [];

				for (var i = edge.minRank + 1; i < edge.maxRank; i++)
				{
					// The connecting edge must be added to the
					// appropriate ranks
					rankList[i].push(edge);
					edge.setGeneralPurposeVariable(i, rankList[i]
							.length - 1);
				}
			}
		}
	}, rootsArray, false, null);
};

/**
 * Function: visit
 *
 * A depth first search through the internal heirarchy model.
 *
 * Parameters:
 *
 * visitor - The visitor function pattern to be called for each node.
 * trackAncestors - Whether or not the search is to keep track all nodes
 * directly above this one in the search path.
 */
mxGraphHierarchyModel.prototype.visit = function(visitor, dfsRoots, trackAncestors, seenNodes)
{
	// Run dfs through on all roots
	if (dfsRoots != null)
	{
		for (var i = 0; i < dfsRoots.length; i++)
		{
			var internalNode = dfsRoots[i];

			if (internalNode != null)
			{
				if (seenNodes == null)
				{
					seenNodes = new Object();
				}

				if (trackAncestors)
				{
					// Set up hash code for root
					internalNode.hashCode = [];
					internalNode.hashCode[0] = this.dfsCount;
					internalNode.hashCode[1] = i;
					this.extendedDfs(null, internalNode, null, visitor, seenNodes,
							internalNode.hashCode, i, 0);
				}
				else
				{
					this.dfs(null, internalNode, null, visitor, seenNodes, 0);
				}
			}
		}

		this.dfsCount++;
	}
};

/**
 * Function: dfs
 *
 * Performs a depth first search on the internal hierarchy model
 *
 * Parameters:
 *
 * parent - the parent internal node of the current internal node
 * root - the current internal node
 * connectingEdge - the internal edge connecting the internal node and the parent
 * internal node, if any
 * visitor - the visitor pattern to be called for each node
 * seen - a set of all nodes seen by this dfs a set of all of the
 * ancestor node of the current node
 * layer - the layer on the dfs tree ( not the same as the model ranks )
 */
mxGraphHierarchyModel.prototype.dfs = function(parent, root, connectingEdge, visitor, seen, layer)
{
	if (root != null)
	{
		var rootId = root.id;

		if (seen[rootId] == null)
		{
			seen[rootId] = root;
			visitor(parent, root, connectingEdge, layer, 0);

			// Copy the connects as source list so that visitors
			// can change the original for edge direction inversions
			var outgoingEdges = root.connectsAsSource.slice();
			
			for (var i = 0; i< outgoingEdges.length; i++)
			{
				var internalEdge = outgoingEdges[i];
				var targetNode = internalEdge.target;

				// Root check is O(|roots|)
				this.dfs(root, targetNode, internalEdge, visitor, seen,
						layer + 1);
			}
		}
		else
		{
			// Use the int field to indicate this node has been seen
			visitor(parent, root, connectingEdge, layer, 1);
		}
	}
};

/**
 * Function: extendedDfs
 *
 * Performs a depth first search on the internal hierarchy model. This dfs
 * extends the default version by keeping track of cells ancestors, but it
 * should be only used when necessary because of it can be computationally
 * intensive for deep searches.
 *
 * Parameters:
 *
 * parent - the parent internal node of the current internal node
 * root - the current internal node
 * connectingEdge - the internal edge connecting the internal node and the parent
 * internal node, if any
 * visitor - the visitor pattern to be called for each node
 * seen - a set of all nodes seen by this dfs
 * ancestors - the parent hash code
 * childHash - the new hash code for this node
 * layer - the layer on the dfs tree ( not the same as the model ranks )
 */
mxGraphHierarchyModel.prototype.extendedDfs = function(parent, root, connectingEdge, visitor, seen, ancestors, childHash, layer)
{
	// Explanation of custom hash set. Previously, the ancestors variable
	// was passed through the dfs as a HashSet. The ancestors were copied
	// into a new HashSet and when the new child was processed it was also
	// added to the set. If the current node was in its ancestor list it
	// meant there is a cycle in the graph and this information is passed
	// to the visitor.visit() in the seen parameter. The HashSet clone was
	// very expensive on CPU so a custom hash was developed using primitive
	// types. temp[] couldn't be used so hashCode[] was added to each node.
	// Each new child adds another int to the array, copying the prefix
	// from its parent. Child of the same parent add different ints (the
	// limit is therefore 2^32 children per parent...). If a node has a
	// child with the hashCode already set then the child code is compared
	// to the same portion of the current nodes array. If they match there
	// is a loop.
	// Note that the basic mechanism would only allow for 1 use of this
	// functionality, so the root nodes have two ints. The second int is
	// incremented through each node root and the first is incremented
	// through each run of the dfs algorithm (therefore the dfs is not
	// thread safe). The hash code of each node is set if not already set,
	// or if the first int does not match that of the current run.
	if (root != null)
	{
		if (parent != null)
		{
			// Form this nodes hash code if necessary, that is, if the
			// hashCode variable has not been initialized or if the
			// start of the parent hash code does not equal the start of
			// this nodes hash code, indicating the code was set on a
			// previous run of this dfs.
			if (root.hashCode == null ||
				root.hashCode[0] != parent.hashCode[0])
			{
				var hashCodeLength = parent.hashCode.length + 1;
				root.hashCode = parent.hashCode.slice();
				root.hashCode[hashCodeLength - 1] = childHash;
			}
		}

		var rootId = root.id;

		if (seen[rootId] == null)
		{
			seen[rootId] = root;
			visitor(parent, root, connectingEdge, layer, 0);

			// Copy the connects as source list so that visitors
			// can change the original for edge direction inversions
			var outgoingEdges = root.connectsAsSource.slice();

			for (var i = 0; i < outgoingEdges.length; i++)
			{
				var internalEdge = outgoingEdges[i];
				var targetNode = internalEdge.target;

				// Root check is O(|roots|)
				this.extendedDfs(root, targetNode, internalEdge, visitor, seen,
						root.hashCode, i, layer + 1);
			}
		}
		else
		{
			// Use the int field to indicate this node has been seen
			visitor(parent, root, connectingEdge, layer, 1);
		}
	}
};
/**
 * Copyright (c) 2006-2016, JGraph Ltd
 * Copyright (c) 2006-2016, Gaudenz Alder
 */
/**
 * Class: mxSwimlaneModel
 *
 * Internal model of a hierarchical graph. This model stores nodes and edges
 * equivalent to the real graph nodes and edges, but also stores the rank of the
 * cells, the order within the ranks and the new candidate locations of cells.
 * The internal model also reverses edge direction were appropriate , ignores
 * self-loop and groups parallels together under one edge object.
 *
 * Constructor: mxSwimlaneModel
 *
 * Creates an internal ordered graph model using the vertices passed in. If
 * there are any, leftward edge need to be inverted in the internal model
 *
 * Arguments:
 *
 * graph - the facade describing the graph to be operated on
 * vertices - the vertices for this hierarchy
 * ordered - whether or not the vertices are already ordered
 * deterministic - whether or not this layout should be deterministic on each
 * tightenToSource - whether or not to tighten vertices towards the sources
 * scanRanksFromSinks - Whether rank assignment is from the sinks or sources.
 * usage
 */
function mxSwimlaneModel(layout, vertices, roots, parent, tightenToSource)
{
	var graph = layout.getGraph();
	this.tightenToSource = tightenToSource;
	this.roots = roots;
	this.parent = parent;

	// map of cells to internal cell needed for second run through
	// to setup the sink of edges correctly
	this.vertexMapper = new mxDictionary();
	this.edgeMapper = new mxDictionary();
	this.maxRank = 0;
	var internalVertices = [];

	if (vertices == null)
	{
		vertices = this.graph.getChildVertices(parent);
	}

	this.maxRank = this.SOURCESCANSTARTRANK;
	// map of cells to internal cell needed for second run through
	// to setup the sink of edges correctly. Guess size by number
	// of edges is roughly same as number of vertices.
	this.createInternalCells(layout, vertices, internalVertices);

	// Go through edges set their sink values. Also check the
	// ordering if and invert edges if necessary
	for (var i = 0; i < vertices.length; i++)
	{
		var edges = internalVertices[i].connectsAsSource;

		for (var j = 0; j < edges.length; j++)
		{
			var internalEdge = edges[j];
			var realEdges = internalEdge.edges;

			// Only need to process the first real edge, since
			// all the edges connect to the same other vertex
			if (realEdges != null && realEdges.length > 0)
			{
				var realEdge = realEdges[0];
				var targetCell = layout.getVisibleTerminal(
						realEdge, false);
				var internalTargetCell = this.vertexMapper.get(targetCell);

				if (internalVertices[i] == internalTargetCell)
				{
					// If there are parallel edges going between two vertices and not all are in the same direction
					// you can have navigated across one direction when doing the cycle reversal that isn't the same
					// direction as the first real edge in the array above. When that happens the if above catches
					// that and we correct the target cell before continuing.
					// This branch only detects this single case
					targetCell = layout.getVisibleTerminal(
							realEdge, true);
					internalTargetCell = this.vertexMapper.get(targetCell);
				}

				if (internalTargetCell != null
						&& internalVertices[i] != internalTargetCell)
				{
					internalEdge.target = internalTargetCell;

					if (internalTargetCell.connectsAsTarget.length == 0)
					{
						internalTargetCell.connectsAsTarget = [];
					}

					if (mxUtils.indexOf(internalTargetCell.connectsAsTarget, internalEdge) < 0)
					{
						internalTargetCell.connectsAsTarget.push(internalEdge);
					}
				}
			}
		}

		// Use the temp variable in the internal nodes to mark this
		// internal vertex as having been visited.
		internalVertices[i].temp[0] = 1;
	}
};

/**
 * Variable: maxRank
 *
 * Stores the largest rank number allocated
 */
mxSwimlaneModel.prototype.maxRank = null;

/**
 * Variable: vertexMapper
 *
 * Map from graph vertices to internal model nodes.
 */
mxSwimlaneModel.prototype.vertexMapper = null;

/**
 * Variable: edgeMapper
 *
 * Map from graph edges to internal model edges
 */
mxSwimlaneModel.prototype.edgeMapper = null;

/**
 * Variable: ranks
 *
 * Mapping from rank number to actual rank
 */
mxSwimlaneModel.prototype.ranks = null;

/**
 * Variable: roots
 *
 * Store of roots of this hierarchy model, these are real graph cells, not
 * internal cells
 */
mxSwimlaneModel.prototype.roots = null;

/**
 * Variable: parent
 *
 * The parent cell whose children are being laid out
 */
mxSwimlaneModel.prototype.parent = null;

/**
 * Variable: dfsCount
 *
 * Count of the number of times the ancestor dfs has been used.
 */
mxSwimlaneModel.prototype.dfsCount = 0;

/**
 * Variable: SOURCESCANSTARTRANK
 *
 * High value to start source layering scan rank value from.
 */
mxSwimlaneModel.prototype.SOURCESCANSTARTRANK = 100000000;

/**
 * Variable: tightenToSource
 *
 * Whether or not to tighten the assigned ranks of vertices up towards
 * the source cells.
 */
mxGraphHierarchyModel.prototype.tightenToSource = false;

/**
 * Variable: ranksPerGroup
 *
 * An array of the number of ranks within each swimlane
 */
mxSwimlaneModel.prototype.ranksPerGroup = null;

/**
 * Function: createInternalCells
 *
 * Creates all edges in the internal model
 *
 * Parameters:
 *
 * layout - Reference to the <mxHierarchicalLayout> algorithm.
 * vertices - Array of <mxCells> that represent the vertices whom are to
 * have an internal representation created.
 * internalVertices - The array of <mxGraphHierarchyNodes> to have their
 * information filled in using the real vertices.
 */
mxSwimlaneModel.prototype.createInternalCells = function(layout, vertices, internalVertices)
{
	var graph = layout.getGraph();
	var swimlanes = layout.swimlanes;

	// Create internal edges
	for (var i = 0; i < vertices.length; i++)
	{
		internalVertices[i] = new mxGraphHierarchyNode(vertices[i]);
		this.vertexMapper.put(vertices[i], internalVertices[i]);
		internalVertices[i].swimlaneIndex = -1;

		for (var ii = 0; ii < swimlanes.length; ii++)
		{
			if (graph.model.getParent(vertices[i]) == swimlanes[ii])
			{
				internalVertices[i].swimlaneIndex = ii;
				break;
			}
		}

		// If the layout is deterministic, order the cells
		//List outgoingCells = graph.getNeighbours(vertices[i], deterministic);
		var conns = layout.getEdges(vertices[i]);
		internalVertices[i].connectsAsSource = [];

		// Create internal edges, but don't do any rank assignment yet
		// First use the information from the greedy cycle remover to
		// invert the leftward edges internally
		for (var j = 0; j < conns.length; j++)
		{
			var cell = layout.getVisibleTerminal(conns[j], false);

			// Looking for outgoing edges only
			if (cell != vertices[i] && layout.graph.model.isVertex(cell) &&
					!layout.isVertexIgnored(cell))
			{
				// We process all edge between this source and its targets
				// If there are edges going both ways, we need to collect
				// them all into one internal edges to avoid looping problems
				// later. We assume this direction (source -> target) is the 
				// natural direction if at least half the edges are going in
				// that direction.

				// The check below for edges[0] being in the vertex mapper is
				// in case we've processed this the other way around
				// (target -> source) and the number of edges in each direction
				// are the same. All the graph edges will have been assigned to
				// an internal edge going the other way, so we don't want to 
				// process them again
				var undirectedEdges = layout.getEdgesBetween(vertices[i],
						cell, false);
				var directedEdges = layout.getEdgesBetween(vertices[i],
						cell, true);
				
				if (undirectedEdges != null &&
						undirectedEdges.length > 0 &&
						this.edgeMapper.get(undirectedEdges[0]) == null &&
						directedEdges.length * 2 >= undirectedEdges.length)
				{
					var internalEdge = new mxGraphHierarchyEdge(undirectedEdges);

					for (var k = 0; k < undirectedEdges.length; k++)
					{
						var edge = undirectedEdges[k];
						this.edgeMapper.put(edge, internalEdge);

						// Resets all point on the edge and disables the edge style
						// without deleting it from the cell style
						graph.resetEdge(edge);

					    if (layout.disableEdgeStyle)
					    {
					    	layout.setEdgeStyleEnabled(edge, false);
					    	layout.setOrthogonalEdge(edge,true);
					    }
					}

					internalEdge.source = internalVertices[i];

					if (mxUtils.indexOf(internalVertices[i].connectsAsSource, internalEdge) < 0)
					{
						internalVertices[i].connectsAsSource.push(internalEdge);
					}
				}
			}
		}

		// Ensure temp variable is cleared from any previous use
		internalVertices[i].temp[0] = 0;
	}
};

/**
 * Function: initialRank
 *
 * Basic determination of minimum layer ranking by working from from sources
 * or sinks and working through each node in the relevant edge direction.
 * Starting at the sinks is basically a longest path layering algorithm.
*/
mxSwimlaneModel.prototype.initialRank = function()
{
	this.ranksPerGroup = [];
	
	var startNodes = [];
	var seen = new Object();

	if (this.roots != null)
	{
		for (var i = 0; i < this.roots.length; i++)
		{
			var internalNode = this.vertexMapper.get(this.roots[i]);
			this.maxChainDfs(null, internalNode, null, seen, 0);

			if (internalNode != null)
			{
				startNodes.push(internalNode);
			}
		}
	}

	// Calculate the lower and upper rank bounds of each swimlane
	var lowerRank = [];
	var upperRank = [];
	
	for (var i = this.ranksPerGroup.length - 1; i >= 0; i--)
	{
		if (i == this.ranksPerGroup.length - 1)
		{
			lowerRank[i] = 0;
		}
		else
		{
			lowerRank[i] = upperRank[i+1] + 1;
		}
		
		upperRank[i] = lowerRank[i] + this.ranksPerGroup[i];
	}
	
	this.maxRank = upperRank[0];

	var internalNodes = this.vertexMapper.getValues();
	
	for (var i=0; i < internalNodes.length; i++)
	{
		// Mark the node as not having had a layer assigned
		internalNodes[i].temp[0] = -1;
	}

	var startNodesCopy = startNodes.slice();
	
	while (startNodes.length > 0)
	{
		var internalNode = startNodes[0];
		var layerDeterminingEdges;
		var edgesToBeMarked;

		layerDeterminingEdges = internalNode.connectsAsTarget;
		edgesToBeMarked = internalNode.connectsAsSource;

		// flag to keep track of whether or not all layer determining
		// edges have been scanned
		var allEdgesScanned = true;

		// Work out the layer of this node from the layer determining
		// edges. The minimum layer number of any node connected by one of
		// the layer determining edges variable
		var minimumLayer = upperRank[0];

		for (var i = 0; i < layerDeterminingEdges.length; i++)
		{
			var internalEdge = layerDeterminingEdges[i];

			if (internalEdge.temp[0] == 5270620)
			{
				// This edge has been scanned, get the layer of the
				// node on the other end
				var otherNode = internalEdge.source;
				minimumLayer = Math.min(minimumLayer, otherNode.temp[0] - 1);
			}
			else
			{
				allEdgesScanned = false;

				break;
			}
		}

		// If all edge have been scanned, assign the layer, mark all
		// edges in the other direction and remove from the nodes list
		if (allEdgesScanned)
		{
			if (minimumLayer > upperRank[internalNode.swimlaneIndex])
			{
				minimumLayer = upperRank[internalNode.swimlaneIndex];
			}

			internalNode.temp[0] = minimumLayer;

			if (edgesToBeMarked != null)
			{
				for (var i = 0; i < edgesToBeMarked.length; i++)
				{
					var internalEdge = edgesToBeMarked[i];

					// Assign unique stamp ( y/m/d/h )
					internalEdge.temp[0] = 5270620;

					// Add node on other end of edge to LinkedList of
					// nodes to be analysed
					var otherNode = internalEdge.target;

					// Only add node if it hasn't been assigned a layer
					if (otherNode.temp[0] == -1)
					{
						startNodes.push(otherNode);

						// Mark this other node as neither being
						// unassigned nor assigned so it isn't
						// added to this list again, but it's
						// layer isn't used in any calculation.
						otherNode.temp[0] = -2;
					}
				}
			}

			startNodes.shift();
		}
		else
		{
			// Not all the edges have been scanned, get to the back of
			// the class and put the dunces cap on
			var removedCell = startNodes.shift();
			startNodes.push(internalNode);

			if (removedCell == internalNode && startNodes.length == 1)
			{
				// This is an error condition, we can't get out of
				// this loop. It could happen for more than one node
				// but that's a lot harder to detect. Log the error
				// TODO make log comment
				break;
			}
		}
	}

	// Normalize the ranks down from their large starting value to place
	// at least 1 sink on layer 0
//	for (var key in this.vertexMapper)
//	{
//		var internalNode = this.vertexMapper[key];
//		// Mark the node as not having had a layer assigned
//		internalNode.temp[0] -= this.maxRank;
//	}
	
	// Tighten the rank 0 nodes as far as possible
//	for ( var i = 0; i < startNodesCopy.length; i++)
//	{
//		var internalNode = startNodesCopy[i];
//		var currentMaxLayer = 0;
//		var layerDeterminingEdges = internalNode.connectsAsSource;
//
//		for ( var j = 0; j < layerDeterminingEdges.length; j++)
//		{
//			var internalEdge = layerDeterminingEdges[j];
//			var otherNode = internalEdge.target;
//			internalNode.temp[0] = Math.max(currentMaxLayer,
//					otherNode.temp[0] + 1);
//			currentMaxLayer = internalNode.temp[0];
//		}
//	}
};

/**
 * Function: maxChainDfs
 *
 * Performs a depth first search on the internal hierarchy model. This dfs
 * extends the default version by keeping track of chains within groups.
 * Any cycles should be removed prior to running, but previously seen cells
 * are ignored.
 *
 * Parameters:
 *
 * parent - the parent internal node of the current internal node
 * root - the current internal node
 * connectingEdge - the internal edge connecting the internal node and the parent
 * internal node, if any
 * seen - a set of all nodes seen by this dfs
 * chainCount - the number of edges in the chain of vertices going through
 * the current swimlane
 */
mxSwimlaneModel.prototype.maxChainDfs = function(parent, root, connectingEdge, seen, chainCount)
{
	if (root != null)
	{
		var rootId = mxCellPath.create(root.cell);

		if (seen[rootId] == null)
		{
			seen[rootId] = root;
			var slIndex = root.swimlaneIndex;
			
			if (this.ranksPerGroup[slIndex] == null || this.ranksPerGroup[slIndex] < chainCount)
			{
				this.ranksPerGroup[slIndex] = chainCount;
			}

			// Copy the connects as source list so that visitors
			// can change the original for edge direction inversions
			var outgoingEdges = root.connectsAsSource.slice();

			for (var i = 0; i < outgoingEdges.length; i++)
			{
				var internalEdge = outgoingEdges[i];
				var targetNode = internalEdge.target;

				// Only navigate in source->target direction within the same
				// swimlane, or from a lower index swimlane to a higher one
				if (root.swimlaneIndex < targetNode.swimlaneIndex)
				{
					this.maxChainDfs(root, targetNode, internalEdge, mxUtils.clone(seen, null , true), 0);
				}
				else if (root.swimlaneIndex == targetNode.swimlaneIndex)
				{
					this.maxChainDfs(root, targetNode, internalEdge, mxUtils.clone(seen, null , true), chainCount + 1);
				}
			}
		}
	}
};

/**
 * Function: fixRanks
 *
 * Fixes the layer assignments to the values stored in the nodes. Also needs
 * to create dummy nodes for edges that cross layers.
 */
mxSwimlaneModel.prototype.fixRanks = function()
{
	var rankList = [];
	this.ranks = [];

	for (var i = 0; i < this.maxRank + 1; i++)
	{
		rankList[i] = [];
		this.ranks[i] = rankList[i];
	}

	// Perform a DFS to obtain an initial ordering for each rank.
	// Without doing this you would end up having to process
	// crossings for a standard tree.
	var rootsArray = null;

	if (this.roots != null)
	{
		var oldRootsArray = this.roots;
		rootsArray = [];

		for (var i = 0; i < oldRootsArray.length; i++)
		{
			var cell = oldRootsArray[i];
			var internalNode = this.vertexMapper.get(cell);
			rootsArray[i] = internalNode;
		}
	}

	this.visit(function(parent, node, edge, layer, seen)
	{
		if (seen == 0 && node.maxRank < 0 && node.minRank < 0)
		{
			rankList[node.temp[0]].push(node);
			node.maxRank = node.temp[0];
			node.minRank = node.temp[0];

			// Set temp[0] to the nodes position in the rank
			node.temp[0] = rankList[node.maxRank].length - 1;
		}

		if (parent != null && edge != null)
		{
			var parentToCellRankDifference = parent.maxRank - node.maxRank;

			if (parentToCellRankDifference > 1)
			{
				// There are ranks in between the parent and current cell
				edge.maxRank = parent.maxRank;
				edge.minRank = node.maxRank;
				edge.temp = [];
				edge.x = [];
				edge.y = [];

				for (var i = edge.minRank + 1; i < edge.maxRank; i++)
				{
					// The connecting edge must be added to the
					// appropriate ranks
					rankList[i].push(edge);
					edge.setGeneralPurposeVariable(i, rankList[i]
							.length - 1);
				}
			}
		}
	}, rootsArray, false, null);
};

/**
 * Function: visit
 *
 * A depth first search through the internal heirarchy model.
 *
 * Parameters:
 *
 * visitor - The visitor function pattern to be called for each node.
 * trackAncestors - Whether or not the search is to keep track all nodes
 * directly above this one in the search path.
 */
mxSwimlaneModel.prototype.visit = function(visitor, dfsRoots, trackAncestors, seenNodes)
{
	// Run dfs through on all roots
	if (dfsRoots != null)
	{
		for (var i = 0; i < dfsRoots.length; i++)
		{
			var internalNode = dfsRoots[i];

			if (internalNode != null)
			{
				if (seenNodes == null)
				{
					seenNodes = new Object();
				}

				if (trackAncestors)
				{
					// Set up hash code for root
					internalNode.hashCode = [];
					internalNode.hashCode[0] = this.dfsCount;
					internalNode.hashCode[1] = i;
					this.extendedDfs(null, internalNode, null, visitor, seenNodes,
							internalNode.hashCode, i, 0);
				}
				else
				{
					this.dfs(null, internalNode, null, visitor, seenNodes, 0);
				}
			}
		}

		this.dfsCount++;
	}
};

/**
 * Function: dfs
 *
 * Performs a depth first search on the internal hierarchy model
 *
 * Parameters:
 *
 * parent - the parent internal node of the current internal node
 * root - the current internal node
 * connectingEdge - the internal edge connecting the internal node and the parent
 * internal node, if any
 * visitor - the visitor pattern to be called for each node
 * seen - a set of all nodes seen by this dfs a set of all of the
 * ancestor node of the current node
 * layer - the layer on the dfs tree ( not the same as the model ranks )
 */
mxSwimlaneModel.prototype.dfs = function(parent, root, connectingEdge, visitor, seen, layer)
{
	if (root != null)
	{
		var rootId = root.id;

		if (seen[rootId] == null)
		{
			seen[rootId] = root;
			visitor(parent, root, connectingEdge, layer, 0);

			// Copy the connects as source list so that visitors
			// can change the original for edge direction inversions
			var outgoingEdges = root.connectsAsSource.slice();
			
			for (var i = 0; i< outgoingEdges.length; i++)
			{
				var internalEdge = outgoingEdges[i];
				var targetNode = internalEdge.target;

				// Root check is O(|roots|)
				this.dfs(root, targetNode, internalEdge, visitor, seen,
						layer + 1);
			}
		}
		else
		{
			// Use the int field to indicate this node has been seen
			visitor(parent, root, connectingEdge, layer, 1);
		}
	}
};

/**
 * Function: extendedDfs
 *
 * Performs a depth first search on the internal hierarchy model. This dfs
 * extends the default version by keeping track of cells ancestors, but it
 * should be only used when necessary because of it can be computationally
 * intensive for deep searches.
 *
 * Parameters:
 *
 * parent - the parent internal node of the current internal node
 * root - the current internal node
 * connectingEdge - the internal edge connecting the internal node and the parent
 * internal node, if any
 * visitor - the visitor pattern to be called for each node
 * seen - a set of all nodes seen by this dfs
 * ancestors - the parent hash code
 * childHash - the new hash code for this node
 * layer - the layer on the dfs tree ( not the same as the model ranks )
 */
mxSwimlaneModel.prototype.extendedDfs = function(parent, root, connectingEdge, visitor, seen, ancestors, childHash, layer)
{
	// Explanation of custom hash set. Previously, the ancestors variable
	// was passed through the dfs as a HashSet. The ancestors were copied
	// into a new HashSet and when the new child was processed it was also
	// added to the set. If the current node was in its ancestor list it
	// meant there is a cycle in the graph and this information is passed
	// to the visitor.visit() in the seen parameter. The HashSet clone was
	// very expensive on CPU so a custom hash was developed using primitive
	// types. temp[] couldn't be used so hashCode[] was added to each node.
	// Each new child adds another int to the array, copying the prefix
	// from its parent. Child of the same parent add different ints (the
	// limit is therefore 2^32 children per parent...). If a node has a
	// child with the hashCode already set then the child code is compared
	// to the same portion of the current nodes array. If they match there
	// is a loop.
	// Note that the basic mechanism would only allow for 1 use of this
	// functionality, so the root nodes have two ints. The second int is
	// incremented through each node root and the first is incremented
	// through each run of the dfs algorithm (therefore the dfs is not
	// thread safe). The hash code of each node is set if not already set,
	// or if the first int does not match that of the current run.
	if (root != null)
	{
		if (parent != null)
		{
			// Form this nodes hash code if necessary, that is, if the
			// hashCode variable has not been initialized or if the
			// start of the parent hash code does not equal the start of
			// this nodes hash code, indicating the code was set on a
			// previous run of this dfs.
			if (root.hashCode == null ||
				root.hashCode[0] != parent.hashCode[0])
			{
				var hashCodeLength = parent.hashCode.length + 1;
				root.hashCode = parent.hashCode.slice();
				root.hashCode[hashCodeLength - 1] = childHash;
			}
		}

		var rootId = root.id;

		if (seen[rootId] == null)
		{
			seen[rootId] = root;
			visitor(parent, root, connectingEdge, layer, 0);

			// Copy the connects as source list so that visitors
			// can change the original for edge direction inversions
			var outgoingEdges = root.connectsAsSource.slice();
			var incomingEdges = root.connectsAsTarget.slice();

			for (var i = 0; i < outgoingEdges.length; i++)
			{
				var internalEdge = outgoingEdges[i];
				var targetNode = internalEdge.target;
				
				// Only navigate in source->target direction within the same
				// swimlane, or from a lower index swimlane to a higher one
				if (root.swimlaneIndex <= targetNode.swimlaneIndex)
				{
					this.extendedDfs(root, targetNode, internalEdge, visitor, seen,
							root.hashCode, i, layer + 1);
				}
			}
			
			for (var i = 0; i < incomingEdges.length; i++)
			{
				var internalEdge = incomingEdges[i];
				var targetNode = internalEdge.source;

				// Only navigate in target->source direction from a lower index 
				// swimlane to a higher one
				if (root.swimlaneIndex < targetNode.swimlaneIndex)
				{
					this.extendedDfs(root, targetNode, internalEdge, visitor, seen,
							root.hashCode, i, layer + 1);
				}
			}
		}
		else
		{
			// Use the int field to indicate this node has been seen
			visitor(parent, root, connectingEdge, layer, 1);
		}
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxHierarchicalLayoutStage
 * 
 * The specific layout interface for hierarchical layouts. It adds a
 * <code>run</code> method with a parameter for the hierarchical layout model
 * that is shared between the layout stages.
 * 
 * Constructor: mxHierarchicalLayoutStage
 *
 * Constructs a new hierarchical layout stage.
 */
function mxHierarchicalLayoutStage() { };

/**
 * Function: execute
 * 
 * Takes the graph detail and configuration information within the facade
 * and creates the resulting laid out graph within that facade for further
 * use.
 */
mxHierarchicalLayoutStage.prototype.execute = function(parent) { };
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxMedianHybridCrossingReduction
 * 
 * Sets the horizontal locations of node and edge dummy nodes on each layer.
 * Uses median down and up weighings as well heuristic to straighten edges as
 * far as possible.
 * 
 * Constructor: mxMedianHybridCrossingReduction
 *
 * Creates a coordinate assignment.
 * 
 * Arguments:
 * 
 * intraCellSpacing - the minimum buffer between cells on the same rank
 * interRankCellSpacing - the minimum distance between cells on adjacent ranks
 * orientation - the position of the root node(s) relative to the graph
 * initialX - the leftmost coordinate node placement starts at
 */
function mxMedianHybridCrossingReduction(layout)
{
	this.layout = layout;
};

/**
 * Extends mxMedianHybridCrossingReduction.
 */
mxMedianHybridCrossingReduction.prototype = new mxHierarchicalLayoutStage();
mxMedianHybridCrossingReduction.prototype.constructor = mxMedianHybridCrossingReduction;

/**
 * Variable: layout
 * 
 * Reference to the enclosing <mxHierarchicalLayout>.
 */
mxMedianHybridCrossingReduction.prototype.layout = null;

/**
 * Variable: maxIterations
 * 
 * The maximum number of iterations to perform whilst reducing edge
 * crossings. Default is 24.
 */
mxMedianHybridCrossingReduction.prototype.maxIterations = 24;

/**
 * Variable: nestedBestRanks
 * 
 * Stores each rank as a collection of cells in the best order found for
 * each layer so far
 */
mxMedianHybridCrossingReduction.prototype.nestedBestRanks = null;

/**
 * Variable: currentBestCrossings
 * 
 * The total number of crossings found in the best configuration so far
 */
mxMedianHybridCrossingReduction.prototype.currentBestCrossings = 0;

/**
 * Variable: iterationsWithoutImprovement
 * 
 * The total number of crossings found in the best configuration so far
 */
mxMedianHybridCrossingReduction.prototype.iterationsWithoutImprovement = 0;

/**
 * Variable: maxNoImprovementIterations
 * 
 * The total number of crossings found in the best configuration so far
 */
mxMedianHybridCrossingReduction.prototype.maxNoImprovementIterations = 2;

/**
 * Function: execute
 * 
 * Performs a vertex ordering within ranks as described by Gansner et al
 * 1993
 */
mxMedianHybridCrossingReduction.prototype.execute = function(parent)
{
	var model = this.layout.getModel();

	// Stores initial ordering as being the best one found so far
	this.nestedBestRanks = [];
	
	for (var i = 0; i < model.ranks.length; i++)
	{
		this.nestedBestRanks[i] = model.ranks[i].slice();
	}

	var iterationsWithoutImprovement = 0;
	var currentBestCrossings = this.calculateCrossings(model);

	for (var i = 0; i < this.maxIterations &&
		iterationsWithoutImprovement < this.maxNoImprovementIterations; i++)
	{
		this.weightedMedian(i, model);
		this.transpose(i, model);
		var candidateCrossings = this.calculateCrossings(model);

		if (candidateCrossings < currentBestCrossings)
		{
			currentBestCrossings = candidateCrossings;
			iterationsWithoutImprovement = 0;

			// Store the current rankings as the best ones
			for (var j = 0; j < this.nestedBestRanks.length; j++)
			{
				var rank = model.ranks[j];

				for (var k = 0; k < rank.length; k++)
				{
					var cell = rank[k];
					this.nestedBestRanks[j][cell.getGeneralPurposeVariable(j)] = cell;
				}
			}
		}
		else
		{
			// Increase count of iterations where we haven't improved the
			// layout
			iterationsWithoutImprovement++;

			// Restore the best values to the cells
			for (var j = 0; j < this.nestedBestRanks.length; j++)
			{
				var rank = model.ranks[j];
				
				for (var k = 0; k < rank.length; k++)
				{
					var cell = rank[k];
					cell.setGeneralPurposeVariable(j, k);
				}
			}
		}
		
		if (currentBestCrossings == 0)
		{
			// Do nothing further
			break;
		}
	}

	// Store the best rankings but in the model
	var ranks = [];
	var rankList = [];

	for (var i = 0; i < model.maxRank + 1; i++)
	{
		rankList[i] = [];
		ranks[i] = rankList[i];
	}

	for (var i = 0; i < this.nestedBestRanks.length; i++)
	{
		for (var j = 0; j < this.nestedBestRanks[i].length; j++)
		{
			rankList[i].push(this.nestedBestRanks[i][j]);
		}
	}

	model.ranks = ranks;
};


/**
 * Function: calculateCrossings
 * 
 * Calculates the total number of edge crossing in the current graph.
 * Returns the current number of edge crossings in the hierarchy graph
 * model in the current candidate layout
 * 
 * Parameters:
 * 
 * model - the internal model describing the hierarchy
 */
mxMedianHybridCrossingReduction.prototype.calculateCrossings = function(model)
{
	var numRanks = model.ranks.length;
	var totalCrossings = 0;

	for (var i = 1; i < numRanks; i++)
	{
		totalCrossings += this.calculateRankCrossing(i, model);
	}
	
	return totalCrossings;
};

/**
 * Function: calculateRankCrossing
 * 
 * Calculates the number of edges crossings between the specified rank and
 * the rank below it. Returns the number of edges crossings with the rank
 * beneath
 * 
 * Parameters:
 * 
 * i -  the topmost rank of the pair ( higher rank value )
 * model - the internal model describing the hierarchy
 */
mxMedianHybridCrossingReduction.prototype.calculateRankCrossing = function(i, model)
{
	var totalCrossings = 0;
	var rank = model.ranks[i];
	var previousRank = model.ranks[i - 1];

	var tmpIndices = [];

	// Iterate over the top rank and fill in the connection information
	for (var j = 0; j < rank.length; j++)
	{
		var node = rank[j];
		var rankPosition = node.getGeneralPurposeVariable(i);
		var connectedCells = node.getPreviousLayerConnectedCells(i);
		var nodeIndices = [];

		for (var k = 0; k < connectedCells.length; k++)
		{
			var connectedNode = connectedCells[k];
			var otherCellRankPosition = connectedNode.getGeneralPurposeVariable(i - 1);
			nodeIndices.push(otherCellRankPosition);
		}
		
		nodeIndices.sort(function(x, y) { return x - y; });
		tmpIndices[rankPosition] = nodeIndices;
	}
	
	var indices = [];

	for (var j = 0; j < tmpIndices.length; j++)
	{
		indices = indices.concat(tmpIndices[j]);
	}

	var firstIndex = 1;
	
	while (firstIndex < previousRank.length)
	{
		firstIndex <<= 1;
	}

	var treeSize = 2 * firstIndex - 1;
	firstIndex -= 1;

	var tree = [];
	
	for (var j = 0; j < treeSize; ++j)
	{
		tree[j] = 0;
	}

	for (var j = 0; j < indices.length; j++)
	{
		var index = indices[j];
	    var treeIndex = index + firstIndex;
	    ++tree[treeIndex];
	    
	    while (treeIndex > 0)
	    {
	    	if (treeIndex % 2)
	    	{
	    		totalCrossings += tree[treeIndex + 1];
	    	}
	      
	    	treeIndex = (treeIndex - 1) >> 1;
	    	++tree[treeIndex];
	    }
	}

	return totalCrossings;
};

/**
 * Function: transpose
 * 
 * Takes each possible adjacent cell pair on each rank and checks if
 * swapping them around reduces the number of crossing
 * 
 * Parameters:
 * 
 * mainLoopIteration - the iteration number of the main loop
 * model - the internal model describing the hierarchy
 */
mxMedianHybridCrossingReduction.prototype.transpose = function(mainLoopIteration, model)
{
	var improved = true;

	// Track the number of iterations in case of looping
	var count = 0;
	var maxCount = 10;
	while (improved && count++ < maxCount)
	{
		// On certain iterations allow allow swapping of cell pairs with
		// equal edge crossings switched or not switched. This help to
		// nudge a stuck layout into a lower crossing total.
		var nudge = mainLoopIteration % 2 == 1 && count % 2 == 1;
		improved = false;
		
		for (var i = 0; i < model.ranks.length; i++)
		{
			var rank = model.ranks[i];
			var orderedCells = [];
			
			for (var j = 0; j < rank.length; j++)
			{
				var cell = rank[j];
				var tempRank = cell.getGeneralPurposeVariable(i);
				
				// FIXME: Workaround to avoid negative tempRanks
				if (tempRank < 0)
				{
					tempRank = j;
				}
				orderedCells[tempRank] = cell;
			}
			
			var leftCellAboveConnections = null;
			var leftCellBelowConnections = null;
			var rightCellAboveConnections = null;
			var rightCellBelowConnections = null;
			
			var leftAbovePositions = null;
			var leftBelowPositions = null;
			var rightAbovePositions = null;
			var rightBelowPositions = null;
			
			var leftCell = null;
			var rightCell = null;

			for (var j = 0; j < (rank.length - 1); j++)
			{
				// For each intra-rank adjacent pair of cells
				// see if swapping them around would reduce the
				// number of edges crossing they cause in total
				// On every cell pair except the first on each rank, we
				// can save processing using the previous values for the
				// right cell on the new left cell
				if (j == 0)
				{
					leftCell = orderedCells[j];
					leftCellAboveConnections = leftCell
							.getNextLayerConnectedCells(i);
					leftCellBelowConnections = leftCell
							.getPreviousLayerConnectedCells(i);
					leftAbovePositions = [];
					leftBelowPositions = [];
					
					for (var k = 0; k < leftCellAboveConnections.length; k++)
					{
						leftAbovePositions[k] = leftCellAboveConnections[k].getGeneralPurposeVariable(i + 1);
					}
					
					for (var k = 0; k < leftCellBelowConnections.length; k++)
					{
						leftBelowPositions[k] = leftCellBelowConnections[k].getGeneralPurposeVariable(i - 1);
					}
				}
				else
				{
					leftCellAboveConnections = rightCellAboveConnections;
					leftCellBelowConnections = rightCellBelowConnections;
					leftAbovePositions = rightAbovePositions;
					leftBelowPositions = rightBelowPositions;
					leftCell = rightCell;
				}
				
				rightCell = orderedCells[j + 1];
				rightCellAboveConnections = rightCell
						.getNextLayerConnectedCells(i);
				rightCellBelowConnections = rightCell
						.getPreviousLayerConnectedCells(i);

				rightAbovePositions = [];
				rightBelowPositions = [];

				for (var k = 0; k < rightCellAboveConnections.length; k++)
				{
					rightAbovePositions[k] = rightCellAboveConnections[k].getGeneralPurposeVariable(i + 1);
				}
				
				for (var k = 0; k < rightCellBelowConnections.length; k++)
				{
					rightBelowPositions[k] = rightCellBelowConnections[k].getGeneralPurposeVariable(i - 1);
				}

				var totalCurrentCrossings = 0;
				var totalSwitchedCrossings = 0;
				
				for (var k = 0; k < leftAbovePositions.length; k++)
				{
					for (var ik = 0; ik < rightAbovePositions.length; ik++)
					{
						if (leftAbovePositions[k] > rightAbovePositions[ik])
						{
							totalCurrentCrossings++;
						}

						if (leftAbovePositions[k] < rightAbovePositions[ik])
						{
							totalSwitchedCrossings++;
						}
					}
				}
				
				for (var k = 0; k < leftBelowPositions.length; k++)
				{
					for (var ik = 0; ik < rightBelowPositions.length; ik++)
					{
						if (leftBelowPositions[k] > rightBelowPositions[ik])
						{
							totalCurrentCrossings++;
						}

						if (leftBelowPositions[k] < rightBelowPositions[ik])
						{
							totalSwitchedCrossings++;
						}
					}
				}
				
				if ((totalSwitchedCrossings < totalCurrentCrossings) ||
					(totalSwitchedCrossings == totalCurrentCrossings &&
					nudge))
				{
					var temp = leftCell.getGeneralPurposeVariable(i);
					leftCell.setGeneralPurposeVariable(i, rightCell
							.getGeneralPurposeVariable(i));
					rightCell.setGeneralPurposeVariable(i, temp);

					// With this pair exchanged we have to switch all of
					// values for the left cell to the right cell so the
					// next iteration for this rank uses it as the left
					// cell again
					rightCellAboveConnections = leftCellAboveConnections;
					rightCellBelowConnections = leftCellBelowConnections;
					rightAbovePositions = leftAbovePositions;
					rightBelowPositions = leftBelowPositions;
					rightCell = leftCell;
					
					if (!nudge)
					{
						// Don't count nudges as improvement or we'll end
						// up stuck in two combinations and not finishing
						// as early as we should
						improved = true;
					}
				}
			}
		}
	}
};

/**
 * Function: weightedMedian
 * 
 * Sweeps up or down the layout attempting to minimise the median placement
 * of connected cells on adjacent ranks
 * 
 * Parameters:
 * 
 * iteration - the iteration number of the main loop
 * model - the internal model describing the hierarchy
 */
mxMedianHybridCrossingReduction.prototype.weightedMedian = function(iteration, model)
{
	// Reverse sweep direction each time through this method
	var downwardSweep = (iteration % 2 == 0);
	if (downwardSweep)
	{
		for (var j = model.maxRank - 1; j >= 0; j--)
		{
			this.medianRank(j, downwardSweep);
		}
	}
	else
	{
		for (var j = 1; j < model.maxRank; j++)
		{
			this.medianRank(j, downwardSweep);
		}
	}
};

/**
 * Function: medianRank
 * 
 * Attempts to minimise the median placement of connected cells on this rank
 * and one of the adjacent ranks
 * 
 * Parameters:
 * 
 * rankValue - the layer number of this rank
 * downwardSweep - whether or not this is a downward sweep through the graph
 */
mxMedianHybridCrossingReduction.prototype.medianRank = function(rankValue, downwardSweep)
{
	var numCellsForRank = this.nestedBestRanks[rankValue].length;
	var medianValues = [];
	var reservedPositions = [];

	for (var i = 0; i < numCellsForRank; i++)
	{
		var cell = this.nestedBestRanks[rankValue][i];
		var sorterEntry = new MedianCellSorter();
		sorterEntry.cell = cell;

		// Flip whether or not equal medians are flipped on up and down
		// sweeps
		// TODO re-implement some kind of nudge
		// medianValues[i].nudge = !downwardSweep;
		var nextLevelConnectedCells;
		
		if (downwardSweep)
		{
			nextLevelConnectedCells = cell
					.getNextLayerConnectedCells(rankValue);
		}
		else
		{
			nextLevelConnectedCells = cell
					.getPreviousLayerConnectedCells(rankValue);
		}
		
		var nextRankValue;
		
		if (downwardSweep)
		{
			nextRankValue = rankValue + 1;
		}
		else
		{
			nextRankValue = rankValue - 1;
		}

		if (nextLevelConnectedCells != null
				&& nextLevelConnectedCells.length != 0)
		{
			sorterEntry.medianValue = this.medianValue(
					nextLevelConnectedCells, nextRankValue);
			medianValues.push(sorterEntry);
		}
		else
		{
			// Nodes with no adjacent vertices are flagged in the reserved array
			// to indicate they should be left in their current position.
			reservedPositions[cell.getGeneralPurposeVariable(rankValue)] = true;
		}
	}
	
	medianValues.sort(MedianCellSorter.prototype.compare);
	
	// Set the new position of each node within the rank using
	// its temp variable
	for (var i = 0; i < numCellsForRank; i++)
	{
		if (reservedPositions[i] == null)
		{
			var cell = medianValues.shift().cell;
			cell.setGeneralPurposeVariable(rankValue, i);
		}
	}
};

/**
 * Function: medianValue
 * 
 * Calculates the median rank order positioning for the specified cell using
 * the connected cells on the specified rank. Returns the median rank
 * ordering value of the connected cells
 * 
 * Parameters:
 * 
 * connectedCells - the cells on the specified rank connected to the
 * specified cell
 * rankValue - the rank that the connected cell lie upon
 */
mxMedianHybridCrossingReduction.prototype.medianValue = function(connectedCells, rankValue)
{
	var medianValues = [];
	var arrayCount = 0;
	
	for (var i = 0; i < connectedCells.length; i++)
	{
		var cell = connectedCells[i];
		medianValues[arrayCount++] = cell.getGeneralPurposeVariable(rankValue);
	}

	// Sort() sorts lexicographically by default (i.e. 11 before 9) so force
	// numerical order sort
	medianValues.sort(function(a,b){return a - b;});
	
	if (arrayCount % 2 == 1)
	{
		// For odd numbers of adjacent vertices return the median
		return medianValues[Math.floor(arrayCount / 2)];
	}
	else if (arrayCount == 2)
	{
		return ((medianValues[0] + medianValues[1]) / 2.0);
	}
	else
	{
		var medianPoint = arrayCount / 2;
		var leftMedian = medianValues[medianPoint - 1] - medianValues[0];
		var rightMedian = medianValues[arrayCount - 1]
				- medianValues[medianPoint];

		return (medianValues[medianPoint - 1] * rightMedian + medianValues[medianPoint]
				* leftMedian)
				/ (leftMedian + rightMedian);
	}
};

/**
 * Class: MedianCellSorter
 * 
 * A utility class used to track cells whilst sorting occurs on the median
 * values. Does not violate (x.compareTo(y)==0) == (x.equals(y))
 *
 * Constructor: MedianCellSorter
 * 
 * Constructs a new median cell sorter.
 */
function MedianCellSorter()
{
	// empty
};

/**
 * Variable: medianValue
 * 
 * The weighted value of the cell stored.
 */
MedianCellSorter.prototype.medianValue = 0;

/**
 * Variable: cell
 * 
 * The cell whose median value is being calculated
 */
MedianCellSorter.prototype.cell = false;

/**
 * Function: compare
 * 
 * Compares two MedianCellSorters.
 */
MedianCellSorter.prototype.compare = function(a, b)
{
	if (a != null && b != null)
	{
		if (b.medianValue > a.medianValue)
		{
			return -1;
		}
		else if (b.medianValue < a.medianValue)
		{
			return 1;
		}
		else
		{
			return 0;
		}
	}
	else
	{
		return 0;
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxMinimumCycleRemover
 * 
 * An implementation of the first stage of the Sugiyama layout. Straightforward
 * longest path calculation of layer assignment
 * 
 * Constructor: mxMinimumCycleRemover
 *
 * Creates a cycle remover for the given internal model.
 */
function mxMinimumCycleRemover(layout)
{
	this.layout = layout;
};

/**
 * Extends mxHierarchicalLayoutStage.
 */
mxMinimumCycleRemover.prototype = new mxHierarchicalLayoutStage();
mxMinimumCycleRemover.prototype.constructor = mxMinimumCycleRemover;

/**
 * Variable: layout
 * 
 * Reference to the enclosing <mxHierarchicalLayout>.
 */
mxMinimumCycleRemover.prototype.layout = null;

/**
 * Function: execute
 * 
 * Takes the graph detail and configuration information within the facade
 * and creates the resulting laid out graph within that facade for further
 * use.
 */
mxMinimumCycleRemover.prototype.execute = function(parent)
{
	var model = this.layout.getModel();
	var seenNodes = new Object();
	var unseenNodesArray = model.vertexMapper.getValues();
	var unseenNodes = new Object();
	
	for (var i = 0; i < unseenNodesArray.length; i++)
	{
		unseenNodes[unseenNodesArray[i].id] = unseenNodesArray[i];
	}
	
	// Perform a dfs through the internal model. If a cycle is found,
	// reverse it.
	var rootsArray = null;
	
	if (model.roots != null)
	{
		var modelRoots = model.roots;
		rootsArray = [];
		
		for (var i = 0; i < modelRoots.length; i++)
		{
			rootsArray[i] = model.vertexMapper.get(modelRoots[i]);
		}
	}

	model.visit(function(parent, node, connectingEdge, layer, seen)
	{
		// Check if the cell is in it's own ancestor list, if so
		// invert the connecting edge and reverse the target/source
		// relationship to that edge in the parent and the cell
		if (node.isAncestor(parent))
		{
			connectingEdge.invert();
			mxUtils.remove(connectingEdge, parent.connectsAsSource);
			parent.connectsAsTarget.push(connectingEdge);
			mxUtils.remove(connectingEdge, node.connectsAsTarget);
			node.connectsAsSource.push(connectingEdge);
		}
		
		seenNodes[node.id] = node;
		delete unseenNodes[node.id];
	}, rootsArray, true, null);

	// If there are any nodes that should be nodes that the dfs can miss
	// these need to be processed with the dfs and the roots assigned
	// correctly to form a correct internal model
	var seenNodesCopy = mxUtils.clone(seenNodes, null, true);

	// Pick a random cell and dfs from it
	model.visit(function(parent, node, connectingEdge, layer, seen)
	{
		// Check if the cell is in it's own ancestor list, if so
		// invert the connecting edge and reverse the target/source
		// relationship to that edge in the parent and the cell
		if (node.isAncestor(parent))
		{
			connectingEdge.invert();
			mxUtils.remove(connectingEdge, parent.connectsAsSource);
			node.connectsAsSource.push(connectingEdge);
			parent.connectsAsTarget.push(connectingEdge);
			mxUtils.remove(connectingEdge, node.connectsAsTarget);
		}
		
		seenNodes[node.id] = node;
		delete unseenNodes[node.id];
	}, unseenNodes, true, seenNodesCopy);
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxCoordinateAssignment
 * 
 * Sets the horizontal locations of node and edge dummy nodes on each layer.
 * Uses median down and up weighings as well as heuristics to straighten edges as
 * far as possible.
 * 
 * Constructor: mxCoordinateAssignment
 *
 * Creates a coordinate assignment.
 * 
 * Arguments:
 * 
 * intraCellSpacing - the minimum buffer between cells on the same rank
 * interRankCellSpacing - the minimum distance between cells on adjacent ranks
 * orientation - the position of the root node(s) relative to the graph
 * initialX - the leftmost coordinate node placement starts at
 */
function mxCoordinateAssignment(layout, intraCellSpacing, interRankCellSpacing,
	orientation, initialX, parallelEdgeSpacing)
{
	this.layout = layout;
	this.intraCellSpacing = intraCellSpacing;
	this.interRankCellSpacing = interRankCellSpacing;
	this.orientation = orientation;
	this.initialX = initialX;
	this.parallelEdgeSpacing = parallelEdgeSpacing;
};

/**
 * Extends mxHierarchicalLayoutStage.
 */
mxCoordinateAssignment.prototype = new mxHierarchicalLayoutStage();
mxCoordinateAssignment.prototype.constructor = mxCoordinateAssignment;

/**
 * Variable: layout
 * 
 * Reference to the enclosing <mxHierarchicalLayout>.
 */
mxCoordinateAssignment.prototype.layout = null;

/**
 * Variable: intraCellSpacing
 * 
 * The minimum buffer between cells on the same rank. Default is 30.
 */
mxCoordinateAssignment.prototype.intraCellSpacing = 30;

/**
 * Variable: interRankCellSpacing
 * 
 * The minimum distance between cells on adjacent ranks. Default is 10.
 */
mxCoordinateAssignment.prototype.interRankCellSpacing = 100;

/**
 * Variable: parallelEdgeSpacing
 * 
 * The distance between each parallel edge on each ranks for long edges.
 * Default is 10.
 */
mxCoordinateAssignment.prototype.parallelEdgeSpacing = 10;

/**
 * Variable: maxIterations
 * 
 * The number of heuristic iterations to run. Default is 8.
 */
mxCoordinateAssignment.prototype.maxIterations = 8;

/**
 * Variable: prefHozEdgeSep
 * 
 * The preferred horizontal distance between edges exiting a vertex
 */
mxCoordinateAssignment.prototype.prefHozEdgeSep = 5;

/**
 * Variable: prefVertEdgeOff
 * 
 * The preferred vertical offset between edges exiting a vertex
 */
mxCoordinateAssignment.prototype.prefVertEdgeOff = 2;

/**
 * Variable: minEdgeJetty
 * 
 * The minimum distance for an edge jetty from a vertex
 */
mxCoordinateAssignment.prototype.minEdgeJetty = 12;

/**
 * Variable: channelBuffer
 * 
 * The size of the vertical buffer in the center of inter-rank channels
 * where edge control points should not be placed
 */
mxCoordinateAssignment.prototype.channelBuffer = 4;

/**
 * Variable: jettyPositions
 * 
 * Map of internal edges and (x,y) pair of positions of the start and end jetty
 * for that edge where it connects to the source and target vertices.
 * Note this should technically be a WeakHashMap, but since JS does not
 * have an equivalent, housekeeping must be performed before using.
 * i.e. check all edges are still in the model and clear the values.
 * Note that the y co-ord is the offset of the jetty, not the
 * absolute point
 */
mxCoordinateAssignment.prototype.jettyPositions = null;

/**
 * Variable: orientation
 * 
 * The position of the root ( start ) node(s) relative to the rest of the
 * laid out graph. Default is <mxConstants.DIRECTION_NORTH>.
 */
mxCoordinateAssignment.prototype.orientation = mxConstants.DIRECTION_NORTH;

/**
 * Variable: initialX
 * 
 * The minimum x position node placement starts at
 */
mxCoordinateAssignment.prototype.initialX = null;

/**
 * Variable: limitX
 * 
 * The maximum x value this positioning lays up to
 */
mxCoordinateAssignment.prototype.limitX = null;

/**
 * Variable: currentXDelta
 * 
 * The sum of x-displacements for the current iteration
 */
mxCoordinateAssignment.prototype.currentXDelta = null;

/**
 * Variable: widestRank
 * 
 * The rank that has the widest x position
 */
mxCoordinateAssignment.prototype.widestRank = null;

/**
 * Variable: rankTopY
 * 
 * Internal cache of top-most values of Y for each rank
 */
mxCoordinateAssignment.prototype.rankTopY = null;

/**
 * Variable: rankBottomY
 * 
 * Internal cache of bottom-most value of Y for each rank
 */
mxCoordinateAssignment.prototype.rankBottomY = null;

/**
 * Variable: widestRankValue
 * 
 * The X-coordinate of the edge of the widest rank
 */
mxCoordinateAssignment.prototype.widestRankValue = null;

/**
 * Variable: rankWidths
 * 
 * The width of all the ranks
 */
mxCoordinateAssignment.prototype.rankWidths = null;

/**
 * Variable: rankY
 * 
 * The Y-coordinate of all the ranks
 */
mxCoordinateAssignment.prototype.rankY = null;

/**
 * Variable: fineTuning
 * 
 * Whether or not to perform local optimisations and iterate multiple times
 * through the algorithm. Default is true.
 */
mxCoordinateAssignment.prototype.fineTuning = true;

/**
 * Variable: nextLayerConnectedCache
 * 
 * A store of connections to the layer above for speed
 */
mxCoordinateAssignment.prototype.nextLayerConnectedCache = null;

/**
 * Variable: previousLayerConnectedCache
 * 
 * A store of connections to the layer below for speed
 */
mxCoordinateAssignment.prototype.previousLayerConnectedCache = null;

/**
 * Variable: groupPadding
 * 
 * Padding added to resized parents
 */
mxCoordinateAssignment.prototype.groupPadding = 10;

/**
 * Utility method to display current positions
 */
mxCoordinateAssignment.prototype.printStatus = function()
{
	var model = this.layout.getModel();
	mxLog.show();

	mxLog.writeln('======Coord assignment debug=======');

	for (var j = 0; j < model.ranks.length; j++)
	{
		mxLog.write('Rank ', j, ' : ' );
		var rank = model.ranks[j];
		
		for (var k = 0; k < rank.length; k++)
		{
			var cell = rank[k];
			
			mxLog.write(cell.getGeneralPurposeVariable(j), '  ');
		}
		mxLog.writeln();
	}
	
	mxLog.writeln('====================================');
};

/**
 * Function: execute
 * 
 * A basic horizontal coordinate assignment algorithm
 */
mxCoordinateAssignment.prototype.execute = function(parent)
{
	this.jettyPositions = Object();
	var model = this.layout.getModel();
	this.currentXDelta = 0.0;

	this.initialCoords(this.layout.getGraph(), model);
	
//	this.printStatus();
	
	if (this.fineTuning)
	{
		this.minNode(model);
	}
	
	var bestXDelta = 100000000.0;
	
	if (this.fineTuning)
	{
		for (var i = 0; i < this.maxIterations; i++)
		{
//			this.printStatus();
		
			// Median Heuristic
			if (i != 0)
			{
				this.medianPos(i, model);
				this.minNode(model);
			}
			
			// if the total offset is less for the current positioning,
			// there are less heavily angled edges and so the current
			// positioning is used
			if (this.currentXDelta < bestXDelta)
			{
				for (var j = 0; j < model.ranks.length; j++)
				{
					var rank = model.ranks[j];
					
					for (var k = 0; k < rank.length; k++)
					{
						var cell = rank[k];
						cell.setX(j, cell.getGeneralPurposeVariable(j));
					}
				}
				
				bestXDelta = this.currentXDelta;
			}
			else
			{
				// Restore the best positions
				for (var j = 0; j < model.ranks.length; j++)
				{
					var rank = model.ranks[j];
					
					for (var k = 0; k < rank.length; k++)
					{
						var cell = rank[k];
						cell.setGeneralPurposeVariable(j, cell.getX(j));
					}
				}
			}
			
			this.minPath(this.layout.getGraph(), model);
			
			this.currentXDelta = 0;
		}
	}
	
	this.setCellLocations(this.layout.getGraph(), model);
};

/**
 * Function: minNode
 * 
 * Performs one median positioning sweep in both directions
 */
mxCoordinateAssignment.prototype.minNode = function(model)
{
	// Queue all nodes
	var nodeList = [];
	
	// Need to be able to map from cell to cellWrapper
	var map = new mxDictionary();
	var rank = [];
	
	for (var i = 0; i <= model.maxRank; i++)
	{
		rank[i] = model.ranks[i];
		
		for (var j = 0; j < rank[i].length; j++)
		{
			// Use the weight to store the rank and visited to store whether
			// or not the cell is in the list
			var node = rank[i][j];
			var nodeWrapper = new WeightedCellSorter(node, i);
			nodeWrapper.rankIndex = j;
			nodeWrapper.visited = true;
			nodeList.push(nodeWrapper);
			
			map.put(node, nodeWrapper);
		}
	}
	
	// Set a limit of the maximum number of times we will access the queue
	// in case a loop appears
	var maxTries = nodeList.length * 10;
	var count = 0;
	
	// Don't move cell within this value of their median
	var tolerance = 1;
	
	while (nodeList.length > 0 && count <= maxTries)
	{
		var cellWrapper = nodeList.shift();
		var cell = cellWrapper.cell;
		
		var rankValue = cellWrapper.weightedValue;
		var rankIndex = parseInt(cellWrapper.rankIndex);
		
		var nextLayerConnectedCells = cell.getNextLayerConnectedCells(rankValue);
		var previousLayerConnectedCells = cell.getPreviousLayerConnectedCells(rankValue);
		
		var numNextLayerConnected = nextLayerConnectedCells.length;
		var numPreviousLayerConnected = previousLayerConnectedCells.length;

		var medianNextLevel = this.medianXValue(nextLayerConnectedCells,
				rankValue + 1);
		var medianPreviousLevel = this.medianXValue(previousLayerConnectedCells,
				rankValue - 1);

		var numConnectedNeighbours = numNextLayerConnected
				+ numPreviousLayerConnected;
		var currentPosition = cell.getGeneralPurposeVariable(rankValue);
		var cellMedian = currentPosition;
		
		if (numConnectedNeighbours > 0)
		{
			cellMedian = (medianNextLevel * numNextLayerConnected + medianPreviousLevel
					* numPreviousLayerConnected)
					/ numConnectedNeighbours;
		}

		// Flag storing whether or not position has changed
		var positionChanged = false;
		
		if (cellMedian < currentPosition - tolerance)
		{
			if (rankIndex == 0)
			{
				cell.setGeneralPurposeVariable(rankValue, cellMedian);
				positionChanged = true;
			}
			else
			{
				var leftCell = rank[rankValue][rankIndex - 1];
				var leftLimit = leftCell
						.getGeneralPurposeVariable(rankValue);
				leftLimit = leftLimit + leftCell.width / 2
						+ this.intraCellSpacing + cell.width / 2;

				if (leftLimit < cellMedian)
				{
					cell.setGeneralPurposeVariable(rankValue, cellMedian);
					positionChanged = true;
				}
				else if (leftLimit < cell
						.getGeneralPurposeVariable(rankValue)
						- tolerance)
				{
					cell.setGeneralPurposeVariable(rankValue, leftLimit);
					positionChanged = true;
				}
			}
		}
		else if (cellMedian > currentPosition + tolerance)
		{
			var rankSize = rank[rankValue].length;
			
			if (rankIndex == rankSize - 1)
			{
				cell.setGeneralPurposeVariable(rankValue, cellMedian);
				positionChanged = true;
			}
			else
			{
				var rightCell = rank[rankValue][rankIndex + 1];
				var rightLimit = rightCell
						.getGeneralPurposeVariable(rankValue);
				rightLimit = rightLimit - rightCell.width / 2
						- this.intraCellSpacing - cell.width / 2;
				
				if (rightLimit > cellMedian)
				{
					cell.setGeneralPurposeVariable(rankValue, cellMedian);
					positionChanged = true;
				}
				else if (rightLimit > cell
						.getGeneralPurposeVariable(rankValue)
						+ tolerance)
				{
					cell.setGeneralPurposeVariable(rankValue, rightLimit);
					positionChanged = true;
				}
			}
		}
		
		if (positionChanged)
		{
			// Add connected nodes to map and list
			for (var i = 0; i < nextLayerConnectedCells.length; i++)
			{
				var connectedCell = nextLayerConnectedCells[i];
				var connectedCellWrapper = map.get(connectedCell);
				
				if (connectedCellWrapper != null)
				{
					if (connectedCellWrapper.visited == false)
					{
						connectedCellWrapper.visited = true;
						nodeList.push(connectedCellWrapper);
					}
				}
			}

			// Add connected nodes to map and list
			for (var i = 0; i < previousLayerConnectedCells.length; i++)
			{
				var connectedCell = previousLayerConnectedCells[i];
				var connectedCellWrapper = map.get(connectedCell);

				if (connectedCellWrapper != null)
				{
					if (connectedCellWrapper.visited == false)
					{
						connectedCellWrapper.visited = true;
						nodeList.push(connectedCellWrapper);
					}
				}
			}
		}
		
		cellWrapper.visited = false;
		count++;
	}
};

/**
 * Function: medianPos
 * 
 * Performs one median positioning sweep in one direction
 * 
 * Parameters:
 * 
 * i - the iteration of the whole process
 * model - an internal model of the hierarchical layout
 */
mxCoordinateAssignment.prototype.medianPos = function(i, model)
{
	// Reverse sweep direction each time through this method
	var downwardSweep = (i % 2 == 0);
	
	if (downwardSweep)
	{
		for (var j = model.maxRank; j > 0; j--)
		{
			this.rankMedianPosition(j - 1, model, j);
		}
	}
	else
	{
		for (var j = 0; j < model.maxRank - 1; j++)
		{
			this.rankMedianPosition(j + 1, model, j);
		}
	}
};

/**
 * Function: rankMedianPosition
 * 
 * Performs median minimisation over one rank.
 * 
 * Parameters:
 * 
 * rankValue - the layer number of this rank
 * model - an internal model of the hierarchical layout
 * nextRankValue - the layer number whose connected cels are to be laid out
 * relative to
 */
mxCoordinateAssignment.prototype.rankMedianPosition = function(rankValue, model, nextRankValue)
{
	var rank = model.ranks[rankValue];

	// Form an array of the order in which the cell are to be processed
	// , the order is given by the weighted sum of the in or out edges,
	// depending on whether we're traveling up or down the hierarchy.
	var weightedValues = [];
	var cellMap = new Object();

	for (var i = 0; i < rank.length; i++)
	{
		var currentCell = rank[i];
		weightedValues[i] = new WeightedCellSorter();
		weightedValues[i].cell = currentCell;
		weightedValues[i].rankIndex = i;
		cellMap[currentCell.id] = weightedValues[i];
		var nextLayerConnectedCells = null;
		
		if (nextRankValue < rankValue)
		{
			nextLayerConnectedCells = currentCell
					.getPreviousLayerConnectedCells(rankValue);
		}
		else
		{
			nextLayerConnectedCells = currentCell
					.getNextLayerConnectedCells(rankValue);
		}

		// Calculate the weighing based on this node type and those this
		// node is connected to on the next layer
		weightedValues[i].weightedValue = this.calculatedWeightedValue(
				currentCell, nextLayerConnectedCells);
	}

	weightedValues.sort(WeightedCellSorter.prototype.compare);

	// Set the new position of each node within the rank using
	// its temp variable
	
	for (var i = 0; i < weightedValues.length; i++)
	{
		var numConnectionsNextLevel = 0;
		var cell = weightedValues[i].cell;
		var nextLayerConnectedCells = null;
		var medianNextLevel = 0;

		if (nextRankValue < rankValue)
		{
			nextLayerConnectedCells = cell.getPreviousLayerConnectedCells(
					rankValue).slice();
		}
		else
		{
			nextLayerConnectedCells = cell.getNextLayerConnectedCells(
					rankValue).slice();
		}

		if (nextLayerConnectedCells != null)
		{
			numConnectionsNextLevel = nextLayerConnectedCells.length;
			
			if (numConnectionsNextLevel > 0)
			{
				medianNextLevel = this.medianXValue(nextLayerConnectedCells,
						nextRankValue);
			}
			else
			{
				// For case of no connections on the next level set the
				// median to be the current position and try to be
				// positioned there
				medianNextLevel = cell.getGeneralPurposeVariable(rankValue);
			}
		}

		var leftBuffer = 0.0;
		var leftLimit = -100000000.0;
		
		for (var j = weightedValues[i].rankIndex - 1; j >= 0;)
		{
			var weightedValue = cellMap[rank[j].id];
			
			if (weightedValue != null)
			{
				var leftCell = weightedValue.cell;
				
				if (weightedValue.visited)
				{
					// The left limit is the right hand limit of that
					// cell plus any allowance for unallocated cells
					// in-between
					leftLimit = leftCell
							.getGeneralPurposeVariable(rankValue)
							+ leftCell.width
							/ 2.0
							+ this.intraCellSpacing
							+ leftBuffer + cell.width / 2.0;
					j = -1;
				}
				else
				{
					leftBuffer += leftCell.width + this.intraCellSpacing;
					j--;
				}
			}
		}

		var rightBuffer = 0.0;
		var rightLimit = 100000000.0;
		
		for (var j = weightedValues[i].rankIndex + 1; j < weightedValues.length;)
		{
			var weightedValue = cellMap[rank[j].id];
			
			if (weightedValue != null)
			{
				var rightCell = weightedValue.cell;
				
				if (weightedValue.visited)
				{
					// The left limit is the right hand limit of that
					// cell plus any allowance for unallocated cells
					// in-between
					rightLimit = rightCell
							.getGeneralPurposeVariable(rankValue)
							- rightCell.width
							/ 2.0
							- this.intraCellSpacing
							- rightBuffer - cell.width / 2.0;
					j = weightedValues.length;
				}
				else
				{
					rightBuffer += rightCell.width + this.intraCellSpacing;
					j++;
				}
			}
		}
		
		if (medianNextLevel >= leftLimit && medianNextLevel <= rightLimit)
		{
			cell.setGeneralPurposeVariable(rankValue, medianNextLevel);
		}
		else if (medianNextLevel < leftLimit)
		{
			// Couldn't place at median value, place as close to that
			// value as possible
			cell.setGeneralPurposeVariable(rankValue, leftLimit);
			this.currentXDelta += leftLimit - medianNextLevel;
		}
		else if (medianNextLevel > rightLimit)
		{
			// Couldn't place at median value, place as close to that
			// value as possible
			cell.setGeneralPurposeVariable(rankValue, rightLimit);
			this.currentXDelta += medianNextLevel - rightLimit;
		}

		weightedValues[i].visited = true;
	}
};

/**
 * Function: calculatedWeightedValue
 * 
 * Calculates the priority the specified cell has based on the type of its
 * cell and the cells it is connected to on the next layer
 * 
 * Parameters:
 * 
 * currentCell - the cell whose weight is to be calculated
 * collection - the cells the specified cell is connected to
 */
mxCoordinateAssignment.prototype.calculatedWeightedValue = function(currentCell, collection)
{
	var totalWeight = 0;
	
	for (var i = 0; i < collection.length; i++)
	{
		var cell = collection[i];

		if (currentCell.isVertex() && cell.isVertex())
		{
			totalWeight++;
		}
		else if (currentCell.isEdge() && cell.isEdge())
		{
			totalWeight += 8;
		}
		else
		{
			totalWeight += 2;
		}
	}

	return totalWeight;
};

/**
 * Function: medianXValue
 * 
 * Calculates the median position of the connected cell on the specified
 * rank
 * 
 * Parameters:
 * 
 * connectedCells - the cells the candidate connects to on this level
 * rankValue - the layer number of this rank
 */
mxCoordinateAssignment.prototype.medianXValue = function(connectedCells, rankValue)
{
	if (connectedCells.length == 0)
	{
		return 0;
	}

	var medianValues = [];

	for (var i = 0; i < connectedCells.length; i++)
	{
		medianValues[i] = connectedCells[i].getGeneralPurposeVariable(rankValue);
	}

	medianValues.sort(function(a,b){return a - b;});
	
	if (connectedCells.length % 2 == 1)
	{
		// For odd numbers of adjacent vertices return the median
		return medianValues[Math.floor(connectedCells.length / 2)];
	}
	else
	{
		var medianPoint = connectedCells.length / 2;
		var leftMedian = medianValues[medianPoint - 1];
		var rightMedian = medianValues[medianPoint];

		return ((leftMedian + rightMedian) / 2);
	}
};

/**
 * Function: initialCoords
 * 
 * Sets up the layout in an initial positioning. The ranks are all centered
 * as much as possible along the middle vertex in each rank. The other cells
 * are then placed as close as possible on either side.
 * 
 * Parameters:
 * 
 * facade - the facade describing the input graph
 * model - an internal model of the hierarchical layout
 */
mxCoordinateAssignment.prototype.initialCoords = function(facade, model)
{
	this.calculateWidestRank(facade, model);

	// Sweep up and down from the widest rank
	for (var i = this.widestRank; i >= 0; i--)
	{
		if (i < model.maxRank)
		{
			this.rankCoordinates(i, facade, model);
		}
	}

	for (var i = this.widestRank+1; i <= model.maxRank; i++)
	{
		if (i > 0)
		{
			this.rankCoordinates(i, facade, model);
		}
	}
};

/**
 * Function: rankCoordinates
 * 
 * Sets up the layout in an initial positioning. All the first cells in each
 * rank are moved to the left and the rest of the rank inserted as close
 * together as their size and buffering permits. This method works on just
 * the specified rank.
 * 
 * Parameters:
 * 
 * rankValue - the current rank being processed
 * graph - the facade describing the input graph
 * model - an internal model of the hierarchical layout
 */
mxCoordinateAssignment.prototype.rankCoordinates = function(rankValue, graph, model)
{
	var rank = model.ranks[rankValue];
	var maxY = 0.0;
	var localX = this.initialX + (this.widestRankValue - this.rankWidths[rankValue])
			/ 2;

	// Store whether or not any of the cells' bounds were unavailable so
	// to only issue the warning once for all cells
	var boundsWarning = false;
	
	for (var i = 0; i < rank.length; i++)
	{
		var node = rank[i];
		
		if (node.isVertex())
		{
			var bounds = this.layout.getVertexBounds(node.cell);

			if (bounds != null)
			{
				if (this.orientation == mxConstants.DIRECTION_NORTH ||
					this.orientation == mxConstants.DIRECTION_SOUTH)
				{
					node.width = bounds.width;
					node.height = bounds.height;
				}
				else
				{
					node.width = bounds.height;
					node.height = bounds.width;
				}
			}
			else
			{
				boundsWarning = true;
			}

			maxY = Math.max(maxY, node.height);
		}
		else if (node.isEdge())
		{
			// The width is the number of additional parallel edges
			// time the parallel edge spacing
			var numEdges = 1;

			if (node.edges != null)
			{
				numEdges = node.edges.length;
			}
			else
			{
				mxLog.warn('edge.edges is null');
			}

			node.width = (numEdges - 1) * this.parallelEdgeSpacing;
		}

		// Set the initial x-value as being the best result so far
		localX += node.width / 2.0;
		node.setX(rankValue, localX);
		node.setGeneralPurposeVariable(rankValue, localX);
		localX += node.width / 2.0;
		localX += this.intraCellSpacing;
	}

	if (boundsWarning == true)
	{
		mxLog.warn('At least one cell has no bounds');
	}
};

/**
 * Function: calculateWidestRank
 * 
 * Calculates the width rank in the hierarchy. Also set the y value of each
 * rank whilst performing the calculation
 * 
 * Parameters:
 * 
 * graph - the facade describing the input graph
 * model - an internal model of the hierarchical layout
 */
mxCoordinateAssignment.prototype.calculateWidestRank = function(graph, model)
{
	// Starting y co-ordinate
	var y = -this.interRankCellSpacing;
	
	// Track the widest cell on the last rank since the y
	// difference depends on it
	var lastRankMaxCellHeight = 0.0;
	this.rankWidths = [];
	this.rankY = [];

	for (var rankValue = model.maxRank; rankValue >= 0; rankValue--)
	{
		// Keep track of the widest cell on this rank
		var maxCellHeight = 0.0;
		var rank = model.ranks[rankValue];
		var localX = this.initialX;

		// Store whether or not any of the cells' bounds were unavailable so
		// to only issue the warning once for all cells
		var boundsWarning = false;
		
		for (var i = 0; i < rank.length; i++)
		{
			var node = rank[i];

			if (node.isVertex())
			{
				var bounds = this.layout.getVertexBounds(node.cell);

				if (bounds != null)
				{
					if (this.orientation == mxConstants.DIRECTION_NORTH ||
						this.orientation == mxConstants.DIRECTION_SOUTH)
					{
						node.width = bounds.width;
						node.height = bounds.height;
					}
					else
					{
						node.width = bounds.height;
						node.height = bounds.width;
					}
				}
				else
				{
					boundsWarning = true;
				}

				maxCellHeight = Math.max(maxCellHeight, node.height);
			}
			else if (node.isEdge())
			{
				// The width is the number of additional parallel edges
				// time the parallel edge spacing
				var numEdges = 1;

				if (node.edges != null)
				{
					numEdges = node.edges.length;
				}
				else
				{
					mxLog.warn('edge.edges is null');
				}

				node.width = (numEdges - 1) * this.parallelEdgeSpacing;
			}

			// Set the initial x-value as being the best result so far
			localX += node.width / 2.0;
			node.setX(rankValue, localX);
			node.setGeneralPurposeVariable(rankValue, localX);
			localX += node.width / 2.0;
			localX += this.intraCellSpacing;

			if (localX > this.widestRankValue)
			{
				this.widestRankValue = localX;
				this.widestRank = rankValue;
			}

			this.rankWidths[rankValue] = localX;
		}

		if (boundsWarning == true)
		{
			mxLog.warn('At least one cell has no bounds');
		}

		this.rankY[rankValue] = y;
		var distanceToNextRank = maxCellHeight / 2.0
				+ lastRankMaxCellHeight / 2.0 + this.interRankCellSpacing;
		lastRankMaxCellHeight = maxCellHeight;

		if (this.orientation == mxConstants.DIRECTION_NORTH ||
			this.orientation == mxConstants.DIRECTION_WEST)
		{
			y += distanceToNextRank;
		}
		else
		{
			y -= distanceToNextRank;
		}

		for (var i = 0; i < rank.length; i++)
		{
			var cell = rank[i];
			cell.setY(rankValue, y);
		}
	}
};

/**
 * Function: minPath
 * 
 * Straightens out chains of virtual nodes where possibleacade to those stored after this layout
 * processing step has completed.
 * 
 * Parameters:
 *
 * graph - the facade describing the input graph
 * model - an internal model of the hierarchical layout
 */
mxCoordinateAssignment.prototype.minPath = function(graph, model)
{
	// Work down and up each edge with at least 2 control points
	// trying to straighten each one out. If the same number of
	// straight segments are formed in both directions, the 
	// preferred direction used is the one where the final
	// control points have the least offset from the connectable 
	// region of the terminating vertices
	var edges = model.edgeMapper.getValues();
	
	for (var j = 0; j < edges.length; j++)
	{
		var cell = edges[j];
		
		if (cell.maxRank - cell.minRank - 1 < 1)
		{
			continue;
		}

		// At least two virtual nodes in the edge
		// Check first whether the edge is already straight
		var referenceX = cell
				.getGeneralPurposeVariable(cell.minRank + 1);
		var edgeStraight = true;
		var refSegCount = 0;
		
		for (var i = cell.minRank + 2; i < cell.maxRank; i++)
		{
			var x = cell.getGeneralPurposeVariable(i);

			if (referenceX != x)
			{
				edgeStraight = false;
				referenceX = x;
			}
			else
			{
				refSegCount++;
			}
		}

		if (!edgeStraight)
		{
			var upSegCount = 0;
			var downSegCount = 0;
			var upXPositions = [];
			var downXPositions = [];

			var currentX = cell.getGeneralPurposeVariable(cell.minRank + 1);

			for (var i = cell.minRank + 1; i < cell.maxRank - 1; i++)
			{
				// Attempt to straight out the control point on the
				// next segment up with the current control point.
				var nextX = cell.getX(i + 1);

				if (currentX == nextX)
				{
					upXPositions[i - cell.minRank - 1] = currentX;
					upSegCount++;
				}
				else if (this.repositionValid(model, cell, i + 1, currentX))
				{
					upXPositions[i - cell.minRank - 1] = currentX;
					upSegCount++;
					// Leave currentX at same value
				}
				else
				{
					upXPositions[i - cell.minRank - 1] = nextX;
					currentX = nextX;
				}				
			}

			currentX = cell.getX(i);

			for (var i = cell.maxRank - 1; i > cell.minRank + 1; i--)
			{
				// Attempt to straight out the control point on the
				// next segment down with the current control point.
				var nextX = cell.getX(i - 1);

				if (currentX == nextX)
				{
					downXPositions[i - cell.minRank - 2] = currentX;
					downSegCount++;
				}
				else if (this.repositionValid(model, cell, i - 1, currentX))
				{
					downXPositions[i - cell.minRank - 2] = currentX;
					downSegCount++;
					// Leave currentX at same value
				}
				else
				{
					downXPositions[i - cell.minRank - 2] = cell.getX(i-1);
					currentX = nextX;
				}
			}

			if (downSegCount > refSegCount || upSegCount > refSegCount)
			{
				if (downSegCount >= upSegCount)
				{
					// Apply down calculation values
					for (var i = cell.maxRank - 2; i > cell.minRank; i--)
					{
						cell.setX(i, downXPositions[i - cell.minRank - 1]);
					}
				}
				else if (upSegCount > downSegCount)
				{
					// Apply up calculation values
					for (var i = cell.minRank + 2; i < cell.maxRank; i++)
					{
						cell.setX(i, upXPositions[i - cell.minRank - 2]);
					}
				}
				else
				{
					// Neither direction provided a favourable result
					// But both calculations are better than the
					// existing solution, so apply the one with minimal
					// offset to attached vertices at either end.
				}
			}
		}
	}
};

/**
 * Function: repositionValid
 * 
 * Determines whether or not a node may be moved to the specified x 
 * position on the specified rank
 * 
 * Parameters:
 *
 * model - the layout model
 * cell - the cell being analysed
 * rank - the layer of the cell
 * position - the x position being sought
 */
mxCoordinateAssignment.prototype.repositionValid = function(model, cell, rank, position)
{
	var rankArray = model.ranks[rank];
	var rankIndex = -1;

	for (var i = 0; i < rankArray.length; i++)
	{
		if (cell == rankArray[i])
		{
			rankIndex = i;
			break;
		}
	}

	if (rankIndex < 0)
	{
		return false;
	}

	var currentX = cell.getGeneralPurposeVariable(rank);

	if (position < currentX)
	{
		// Trying to move node to the left.
		if (rankIndex == 0)
		{
			// Left-most node, can move anywhere
			return true;
		}

		var leftCell = rankArray[rankIndex - 1];
		var leftLimit = leftCell.getGeneralPurposeVariable(rank);
		leftLimit = leftLimit + leftCell.width / 2
				+ this.intraCellSpacing + cell.width / 2;

		if (leftLimit <= position)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	else if (position > currentX)
	{
		// Trying to move node to the right.
		if (rankIndex == rankArray.length - 1)
		{
			// Right-most node, can move anywhere
			return true;
		}

		var rightCell = rankArray[rankIndex + 1];
		var rightLimit = rightCell.getGeneralPurposeVariable(rank);
		rightLimit = rightLimit - rightCell.width / 2
				- this.intraCellSpacing - cell.width / 2;

		if (rightLimit >= position)
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	return true;
};

/**
 * Function: setCellLocations
 * 
 * Sets the cell locations in the facade to those stored after this layout
 * processing step has completed.
 * 
 * Parameters:
 *
 * graph - the input graph
 * model - the layout model
 */
mxCoordinateAssignment.prototype.setCellLocations = function(graph, model)
{
	this.rankTopY = [];
	this.rankBottomY = [];

	for (var i = 0; i < model.ranks.length; i++)
	{
		this.rankTopY[i] = Number.MAX_VALUE;
		this.rankBottomY[i] = -Number.MAX_VALUE;
	}
	
	var vertices = model.vertexMapper.getValues();

	// Process vertices all first, since they define the lower and 
	// limits of each rank. Between these limits lie the channels
	// where the edges can be routed across the graph

	for (var i = 0; i < vertices.length; i++)
	{
		this.setVertexLocation(vertices[i]);
	}
	
	// Post process edge styles. Needs the vertex locations set for initial
	// values of the top and bottoms of each rank
	if (this.layout.edgeStyle == mxHierarchicalEdgeStyle.ORTHOGONAL
			|| this.layout.edgeStyle == mxHierarchicalEdgeStyle.POLYLINE
			|| this.layout.edgeStyle == mxHierarchicalEdgeStyle.CURVE)
	{
		this.localEdgeProcessing(model);
	}

	var edges = model.edgeMapper.getValues();

	for (var i = 0; i < edges.length; i++)
	{
		this.setEdgePosition(edges[i]);
	}
};

/**
 * Function: localEdgeProcessing
 * 
 * Separates the x position of edges as they connect to vertices
 * 
 * Parameters:
 *
 * model - the layout model
 */
mxCoordinateAssignment.prototype.localEdgeProcessing = function(model)
{
	// Iterate through each vertex, look at the edges connected in
	// both directions.
	for (var rankIndex = 0; rankIndex < model.ranks.length; rankIndex++)
	{
		var rank = model.ranks[rankIndex];

		for (var cellIndex = 0; cellIndex < rank.length; cellIndex++)
		{
			var cell = rank[cellIndex];

			if (cell.isVertex())
			{
				var currentCells = cell.getPreviousLayerConnectedCells(rankIndex);

				var currentRank = rankIndex - 1;

				// Two loops, last connected cells, and next
				for (var k = 0; k < 2; k++)
				{
					if (currentRank > -1
							&& currentRank < model.ranks.length
							&& currentCells != null
							&& currentCells.length > 0)
					{
						var sortedCells = [];

						for (var j = 0; j < currentCells.length; j++)
						{
							var sorter = new WeightedCellSorter(
									currentCells[j], currentCells[j].getX(currentRank));
							sortedCells.push(sorter);
						}

						sortedCells.sort(WeightedCellSorter.prototype.compare);

						var leftLimit = cell.x[0] - cell.width / 2;
						var rightLimit = leftLimit + cell.width;

						// Connected edge count starts at 1 to allow for buffer
						// with edge of vertex
						var connectedEdgeCount = 0;
						var connectedEdgeGroupCount = 0;
						var connectedEdges = [];
						// Calculate width requirements for all connected edges
						for (var j = 0; j < sortedCells.length; j++)
						{
							var innerCell = sortedCells[j].cell;
							var connections;

							if (innerCell.isVertex())
							{
								// Get the connecting edge
								if (k == 0)
								{
									connections = cell.connectsAsSource;

								}
								else
								{
									connections = cell.connectsAsTarget;
								}

								for (var connIndex = 0; connIndex < connections.length; connIndex++)
								{
									if (connections[connIndex].source == innerCell
											|| connections[connIndex].target == innerCell)
									{
										connectedEdgeCount += connections[connIndex].edges
												.length;
										connectedEdgeGroupCount++;

										connectedEdges.push(connections[connIndex]);
									}
								}
							}
							else
							{
								connectedEdgeCount += innerCell.edges.length;
								connectedEdgeGroupCount++;
								connectedEdges.push(innerCell);
							}
						}

						var requiredWidth = (connectedEdgeCount + 1)
								* this.prefHozEdgeSep;

						// Add a buffer on the edges of the vertex if the edge count allows
						if (cell.width > requiredWidth
								+ (2 * this.prefHozEdgeSep))
						{
							leftLimit += this.prefHozEdgeSep;
							rightLimit -= this.prefHozEdgeSep;
						}

						var availableWidth = rightLimit - leftLimit;
						var edgeSpacing = availableWidth / connectedEdgeCount;

						var currentX = leftLimit + edgeSpacing / 2.0;
						var currentYOffset = this.minEdgeJetty - this.prefVertEdgeOff;
						var maxYOffset = 0;

						for (var j = 0; j < connectedEdges.length; j++)
						{
							var numActualEdges = connectedEdges[j].edges
									.length;
							var pos = this.jettyPositions[connectedEdges[j].ids[0]];
							
							if (pos == null)
							{
								pos = [];
								this.jettyPositions[connectedEdges[j].ids[0]] = pos;
							}

							if (j < connectedEdgeCount / 2)
							{
								currentYOffset += this.prefVertEdgeOff;
							}
							else if (j > connectedEdgeCount / 2)
							{
								currentYOffset -= this.prefVertEdgeOff;
							}
							// Ignore the case if equals, this means the second of 2
							// jettys with the same y (even number of edges)

							for (var m = 0; m < numActualEdges; m++)
							{
								pos[m * 4 + k * 2] = currentX;
								currentX += edgeSpacing;
								pos[m * 4 + k * 2 + 1] = currentYOffset;
							}
							
							maxYOffset = Math.max(maxYOffset,
									currentYOffset);
						}
					}

					currentCells = cell.getNextLayerConnectedCells(rankIndex);

					currentRank = rankIndex + 1;
				}
			}
		}
	}
};

/**
 * Function: setEdgePosition
 * 
 * Fixes the control points
 */
mxCoordinateAssignment.prototype.setEdgePosition = function(cell)
{
	// For parallel edges we need to seperate out the points a
	// little
	var offsetX = 0;
	// Only set the edge control points once

	if (cell.temp[0] != 101207)
	{
		var maxRank = cell.maxRank;
		var minRank = cell.minRank;
		
		if (maxRank == minRank)
		{
			maxRank = cell.source.maxRank;
			minRank = cell.target.minRank;
		}
		
		var parallelEdgeCount = 0;
		var jettys = this.jettyPositions[cell.ids[0]];

		var source = cell.isReversed ? cell.target.cell : cell.source.cell;
		var graph = this.layout.graph;
		var layoutReversed = this.orientation == mxConstants.DIRECTION_EAST
				|| this.orientation == mxConstants.DIRECTION_SOUTH;

		for (var i = 0; i < cell.edges.length; i++)
		{
			var realEdge = cell.edges[i];
			var realSource = this.layout.getVisibleTerminal(realEdge, true);

			//List oldPoints = graph.getPoints(realEdge);
			var newPoints = [];

			// Single length reversed edges end up with the jettys in the wrong
			// places. Since single length edges only have jettys, not segment
			// control points, we just say the edge isn't reversed in this section
			var reversed = cell.isReversed;
			
			if (realSource != source)
			{
				// The real edges include all core model edges and these can go
				// in both directions. If the source of the hierarchical model edge
				// isn't the source of the specific real edge in this iteration
				// treat if as reversed
				reversed = !reversed;
			}

			// First jetty of edge
			if (jettys != null)
			{
				var arrayOffset = reversed ? 2 : 0;
				var y = reversed ?
						(layoutReversed ? this.rankBottomY[minRank] : this.rankTopY[minRank]) :
							(layoutReversed ? this.rankTopY[maxRank] : this.rankBottomY[maxRank]);
				var jetty = jettys[parallelEdgeCount * 4 + 1 + arrayOffset];
				
				if (reversed != layoutReversed)
				{
					jetty = -jetty;
				}
				
				y += jetty;
				var x = jettys[parallelEdgeCount * 4 + arrayOffset];
				
				var modelSource = graph.model.getTerminal(realEdge, true);

				if (this.layout.isPort(modelSource) && graph.model.getParent(modelSource) == realSource)
				{
					var state = graph.view.getState(modelSource);
					
					if (state != null)
					{
						x = state.x;
					}
					else
					{
						x = realSource.geometry.x + cell.source.width * modelSource.geometry.x;
					}
				}

				if (this.orientation == mxConstants.DIRECTION_NORTH
						|| this.orientation == mxConstants.DIRECTION_SOUTH)
				{
					newPoints.push(new mxPoint(x, y));
					
					if (this.layout.edgeStyle == mxHierarchicalEdgeStyle.CURVE)
					{
						newPoints.push(new mxPoint(x, y + jetty));
					}
				}
				else
				{
					newPoints.push(new mxPoint(y, x));
					
					if (this.layout.edgeStyle == mxHierarchicalEdgeStyle.CURVE)
					{
						newPoints.push(new mxPoint(y + jetty, x));
					}
				}
			}

			// Declare variables to define loop through edge points and 
			// change direction if edge is reversed

			var loopStart = cell.x.length - 1;
			var loopLimit = -1;
			var loopDelta = -1;
			var currentRank = cell.maxRank - 1;

			if (reversed)
			{
				loopStart = 0;
				loopLimit = cell.x.length;
				loopDelta = 1;
				currentRank = cell.minRank + 1;
			}
			// Reversed edges need the points inserted in
			// reverse order
			for (var j = loopStart; (cell.maxRank != cell.minRank) && j != loopLimit; j += loopDelta)
			{
				// The horizontal position in a vertical layout
				var positionX = cell.x[j] + offsetX;

				// Work out the vertical positions in a vertical layout
				// in the edge buffer channels above and below this rank
				var topChannelY = (this.rankTopY[currentRank] + this.rankBottomY[currentRank + 1]) / 2.0;
				var bottomChannelY = (this.rankTopY[currentRank - 1] + this.rankBottomY[currentRank]) / 2.0;

				if (reversed)
				{
					var tmp = topChannelY;
					topChannelY = bottomChannelY;
					bottomChannelY = tmp;
				}

				if (this.orientation == mxConstants.DIRECTION_NORTH ||
					this.orientation == mxConstants.DIRECTION_SOUTH)
				{
					newPoints.push(new mxPoint(positionX, topChannelY));
					newPoints.push(new mxPoint(positionX, bottomChannelY));
				}
				else
				{
					newPoints.push(new mxPoint(topChannelY, positionX));
					newPoints.push(new mxPoint(bottomChannelY, positionX));
				}

				this.limitX = Math.max(this.limitX, positionX);
				currentRank += loopDelta;
			}

			// Second jetty of edge
			if (jettys != null)
			{
				var arrayOffset = reversed ? 2 : 0;
				var rankY = reversed ?
						(layoutReversed ? this.rankTopY[maxRank] : this.rankBottomY[maxRank]) :
							(layoutReversed ? this.rankBottomY[minRank] : this.rankTopY[minRank]);
				var jetty = jettys[parallelEdgeCount * 4 + 3 - arrayOffset];
				
				if (reversed != layoutReversed)
				{
					jetty = -jetty;
				}
				var y = rankY - jetty;
				var x = jettys[parallelEdgeCount * 4 + 2 - arrayOffset];
				
				var modelTarget = graph.model.getTerminal(realEdge, false);
				var realTarget = this.layout.getVisibleTerminal(realEdge, false);

				if (this.layout.isPort(modelTarget) && graph.model.getParent(modelTarget) == realTarget)
				{
					var state = graph.view.getState(modelTarget);
					
					if (state != null)
					{
						x = state.x;
					}
					else
					{
						x = realTarget.geometry.x + cell.target.width * modelTarget.geometry.x;
					}
				}

				if (this.orientation == mxConstants.DIRECTION_NORTH ||
						this.orientation == mxConstants.DIRECTION_SOUTH)
				{
					if (this.layout.edgeStyle == mxHierarchicalEdgeStyle.CURVE)
					{
						newPoints.push(new mxPoint(x, y - jetty));
					}

					newPoints.push(new mxPoint(x, y));
				}
				else
				{
					if (this.layout.edgeStyle == mxHierarchicalEdgeStyle.CURVE)
					{
						newPoints.push(new mxPoint(y - jetty, x));
					}

					newPoints.push(new mxPoint(y, x));
				}
			}

			if (cell.isReversed)
			{
				this.processReversedEdge(cell, realEdge);
			}

			this.layout.setEdgePoints(realEdge, newPoints);

			// Increase offset so next edge is drawn next to
			// this one
			if (offsetX == 0.0)
			{
				offsetX = this.parallelEdgeSpacing;
			}
			else if (offsetX > 0)
			{
				offsetX = -offsetX;
			}
			else
			{
				offsetX = -offsetX + this.parallelEdgeSpacing;
			}
			
			parallelEdgeCount++;
		}

		cell.temp[0] = 101207;
	}
};


/**
 * Function: setVertexLocation
 * 
 * Fixes the position of the specified vertex.
 * 
 * Parameters:
 * 
 * cell - the vertex to position
 */
mxCoordinateAssignment.prototype.setVertexLocation = function(cell)
{
	var realCell = cell.cell;
	var positionX = cell.x[0] - cell.width / 2;
	var positionY = cell.y[0] - cell.height / 2;

	this.rankTopY[cell.minRank] = Math.min(this.rankTopY[cell.minRank], positionY);
	this.rankBottomY[cell.minRank] = Math.max(this.rankBottomY[cell.minRank],
			positionY + cell.height);

	if (this.orientation == mxConstants.DIRECTION_NORTH ||
		this.orientation == mxConstants.DIRECTION_SOUTH)
	{
		this.layout.setVertexLocation(realCell, positionX, positionY);
	}
	else
	{
		this.layout.setVertexLocation(realCell, positionY, positionX);
	}

	this.limitX = Math.max(this.limitX, positionX + cell.width);
};

/**
 * Function: processReversedEdge
 * 
 * Hook to add additional processing
 * 
 * Parameters:
 * 
 * edge - the hierarchical model edge
 * realEdge - the real edge in the graph
 */
mxCoordinateAssignment.prototype.processReversedEdge = function(graph, model)
{
	// hook for subclassers
};

/**
 * Class: WeightedCellSorter
 * 
 * A utility class used to track cells whilst sorting occurs on the weighted
 * sum of their connected edges. Does not violate (x.compareTo(y)==0) ==
 * (x.equals(y))
 *
 * Constructor: WeightedCellSorter
 * 
 * Constructs a new weighted cell sorted for the given cell and weight.
 */
function WeightedCellSorter(cell, weightedValue)
{
	this.cell = cell;
	this.weightedValue = weightedValue;
};

/**
 * Variable: weightedValue
 * 
 * The weighted value of the cell stored.
 */
WeightedCellSorter.prototype.weightedValue = 0;

/**
 * Variable: nudge
 * 
 * Whether or not to flip equal weight values.
 */
WeightedCellSorter.prototype.nudge = false;

/**
 * Variable: visited
 * 
 * Whether or not this cell has been visited in the current assignment.
 */
WeightedCellSorter.prototype.visited = false;

/**
 * Variable: rankIndex
 * 
 * The index this cell is in the model rank.
 */
WeightedCellSorter.prototype.rankIndex = null;

/**
 * Variable: cell
 * 
 * The cell whose median value is being calculated.
 */
WeightedCellSorter.prototype.cell = null;

/**
 * Function: compare
 * 
 * Compares two WeightedCellSorters.
 */
WeightedCellSorter.prototype.compare = function(a, b)
{
	if (a != null && b != null)
	{
		if (b.weightedValue > a.weightedValue)
		{
			return -1;
		}
		else if (b.weightedValue < a.weightedValue)
		{
			return 1;
		}
		else
		{
			if (b.nudge)
			{
				return -1;
			}
			else
			{
				return 1;
			}
		}
	}
	else
	{
		return 0;
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxSwimlaneOrdering
 * 
 * An implementation of the first stage of the Sugiyama layout. Straightforward
 * longest path calculation of layer assignment
 * 
 * Constructor: mxSwimlaneOrdering
 *
 * Creates a cycle remover for the given internal model.
 */
function mxSwimlaneOrdering(layout)
{
	this.layout = layout;
};

/**
 * Extends mxHierarchicalLayoutStage.
 */
mxSwimlaneOrdering.prototype = new mxHierarchicalLayoutStage();
mxSwimlaneOrdering.prototype.constructor = mxSwimlaneOrdering;

/**
 * Variable: layout
 * 
 * Reference to the enclosing <mxHierarchicalLayout>.
 */
mxSwimlaneOrdering.prototype.layout = null;

/**
 * Function: execute
 * 
 * Takes the graph detail and configuration information within the facade
 * and creates the resulting laid out graph within that facade for further
 * use.
 */
mxSwimlaneOrdering.prototype.execute = function(parent)
{
	var model = this.layout.getModel();
	var seenNodes = new Object();
	var unseenNodes = mxUtils.clone(model.vertexMapper, null, true);
	
	// Perform a dfs through the internal model. If a cycle is found,
	// reverse it.
	var rootsArray = null;
	
	if (model.roots != null)
	{
		var modelRoots = model.roots;
		rootsArray = [];
		
		for (var i = 0; i < modelRoots.length; i++)
		{
			var nodeId = mxCellPath.create(modelRoots[i]);
			rootsArray[i] = model.vertexMapper.get(modelRoots[i]);
		}
	}

	model.visit(function(parent, node, connectingEdge, layer, seen)
	{
		// Check if the cell is in it's own ancestor list, if so
		// invert the connecting edge and reverse the target/source
		// relationship to that edge in the parent and the cell
		// Ancestor hashes only line up within a swimlane
		var isAncestor = parent != null && parent.swimlaneIndex == node.swimlaneIndex && node.isAncestor(parent);

		// If the source->target swimlane indices go from higher to
		// lower, the edge is reverse
		var reversedOverSwimlane = parent != null && connectingEdge != null &&
						parent.swimlaneIndex < node.swimlaneIndex && connectingEdge.source == node;

		if (isAncestor)
		{
			connectingEdge.invert();
			mxUtils.remove(connectingEdge, parent.connectsAsSource);
			node.connectsAsSource.push(connectingEdge);
			parent.connectsAsTarget.push(connectingEdge);
			mxUtils.remove(connectingEdge, node.connectsAsTarget);
		}
		else if (reversedOverSwimlane)
		{
			connectingEdge.invert();
			mxUtils.remove(connectingEdge, parent.connectsAsTarget);
			node.connectsAsTarget.push(connectingEdge);
			parent.connectsAsSource.push(connectingEdge);
			mxUtils.remove(connectingEdge, node.connectsAsSource);
		}
		
		var cellId = mxCellPath.create(node.cell);
		seenNodes[cellId] = node;
		delete unseenNodes[cellId];
	}, rootsArray, true, null);
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxHierarchicalLayout
 * 
 * A hierarchical layout algorithm.
 * 
 * Constructor: mxHierarchicalLayout
 *
 * Constructs a new hierarchical layout algorithm.
 *
 * Arguments:
 * 
 * graph - Reference to the enclosing <mxGraph>.
 * orientation - Optional constant that defines the orientation of this
 * layout.
 * deterministic - Optional boolean that specifies if this layout should be
 * deterministic. Default is true.
 */
function mxHierarchicalLayout(graph, orientation, deterministic)
{
	mxGraphLayout.call(this, graph);
	this.orientation = (orientation != null) ? orientation : mxConstants.DIRECTION_NORTH;
	this.deterministic = (deterministic != null) ? deterministic : true;
};

var mxHierarchicalEdgeStyle =
{
	ORTHOGONAL: 1,
	POLYLINE: 2,
	STRAIGHT: 3,
	CURVE: 4
};

/**
 * Extends mxGraphLayout.
 */
mxHierarchicalLayout.prototype = new mxGraphLayout();
mxHierarchicalLayout.prototype.constructor = mxHierarchicalLayout;

/**
 * Variable: roots
 * 
 * Holds the array of <mxCell> that this layout contains.
 */
mxHierarchicalLayout.prototype.roots = null;

/**
 * Variable: resizeParent
 * 
 * Specifies if the parent should be resized after the layout so that it
 * contains all the child cells. Default is false. See also <parentBorder>.
 */
mxHierarchicalLayout.prototype.resizeParent = false;

/**
 * Variable: maintainParentLocation
 * 
 * Specifies if the parent location should be maintained, so that the
 * top, left corner stays the same before and after execution of
 * the layout. Default is false for backwards compatibility.
 */
mxHierarchicalLayout.prototype.maintainParentLocation = false;

/**
 * Variable: moveParent
 * 
 * Specifies if the parent should be moved if <resizeParent> is enabled.
 * Default is false.
 */
mxHierarchicalLayout.prototype.moveParent = false;

/**
 * Variable: parentBorder
 * 
 * The border to be added around the children if the parent is to be
 * resized using <resizeParent>. Default is 0.
 */
mxHierarchicalLayout.prototype.parentBorder = 0;

/**
 * Variable: intraCellSpacing
 * 
 * The spacing buffer added between cells on the same layer. Default is 30.
 */
mxHierarchicalLayout.prototype.intraCellSpacing = 30;

/**
 * Variable: interRankCellSpacing
 * 
 * The spacing buffer added between cell on adjacent layers. Default is 50.
 */
mxHierarchicalLayout.prototype.interRankCellSpacing = 100;

/**
 * Variable: interHierarchySpacing
 * 
 * The spacing buffer between unconnected hierarchies. Default is 60.
 */
mxHierarchicalLayout.prototype.interHierarchySpacing = 60;

/**
 * Variable: parallelEdgeSpacing
 * 
 * The distance between each parallel edge on each ranks for long edges
 */
mxHierarchicalLayout.prototype.parallelEdgeSpacing = 10;

/**
 * Variable: orientation
 * 
 * The position of the root node(s) relative to the laid out graph in.
 * Default is <mxConstants.DIRECTION_NORTH>.
 */
mxHierarchicalLayout.prototype.orientation = mxConstants.DIRECTION_NORTH;

/**
 * Variable: fineTuning
 * 
 * Whether or not to perform local optimisations and iterate multiple times
 * through the algorithm. Default is true.
 */
mxHierarchicalLayout.prototype.fineTuning = true;

/**
 * 
 * Variable: tightenToSource
 * 
 * Whether or not to tighten the assigned ranks of vertices up towards
 * the source cells.
 */
mxHierarchicalLayout.prototype.tightenToSource = true;

/**
 * Variable: disableEdgeStyle
 * 
 * Specifies if the STYLE_NOEDGESTYLE flag should be set on edges that are
 * modified by the result. Default is true.
 */
mxHierarchicalLayout.prototype.disableEdgeStyle = true;

/**
 * Variable: traverseAncestors
 * 
 * Whether or not to drill into child cells and layout in reverse
 * group order. This also cause the layout to navigate edges whose 
 * terminal vertices  * have different parents but are in the same 
 * ancestry chain
 */
mxHierarchicalLayout.prototype.traverseAncestors = true;

/**
 * Variable: model
 * 
 * The internal <mxGraphHierarchyModel> formed of the layout.
 */
mxHierarchicalLayout.prototype.model = null;

/**
 * Variable: edgesSet
 * 
 * A cache of edges whose source terminal is the key
 */
mxHierarchicalLayout.prototype.edgesCache = null;

/**
 * Variable: edgesSet
 * 
 * A cache of edges whose source terminal is the key
 */
mxHierarchicalLayout.prototype.edgeSourceTermCache = null;

/**
 * Variable: edgesSet
 * 
 * A cache of edges whose source terminal is the key
 */
mxHierarchicalLayout.prototype.edgesTargetTermCache = null;

/**
 * Variable: edgeStyle
 * 
 * The style to apply between cell layers to edge segments
 */
mxHierarchicalLayout.prototype.edgeStyle = mxHierarchicalEdgeStyle.POLYLINE;

/**
 * Function: getModel
 * 
 * Returns the internal <mxGraphHierarchyModel> for this layout algorithm.
 */
mxHierarchicalLayout.prototype.getModel = function()
{
	return this.model;
};

/**
 * Function: execute
 * 
 * Executes the layout for the children of the specified parent.
 * 
 * Parameters:
 * 
 * parent - Parent <mxCell> that contains the children to be laid out.
 * roots - Optional starting roots of the layout.
 */
mxHierarchicalLayout.prototype.execute = function(parent, roots)
{
	this.parent = parent;
	var model = this.graph.model;
	this.edgesCache = new mxDictionary();
	this.edgeSourceTermCache = new mxDictionary();
	this.edgesTargetTermCache = new mxDictionary();

	if (roots != null && !(roots instanceof Array))
	{
		roots = [roots];
	}
	
	// If the roots are set and the parent is set, only
	// use the roots that are some dependent of the that
	// parent.
	// If just the root are set, use them as-is
	// If just the parent is set use it's immediate
	// children as the initial set

	if (roots == null && parent == null)
	{
		// TODO indicate the problem
		return;
	}
	
	//  Maintaining parent location
	this.parentX = null;
	this.parentY = null;
	
	if (parent != this.root && model.isVertex(parent) != null && this.maintainParentLocation)
	{
		var geo = this.graph.getCellGeometry(parent);
		
		if (geo != null)
		{
			this.parentX = geo.x;
			this.parentY = geo.y;
		}
	}
	
	if (roots != null)
	{
		var rootsCopy = [];

		for (var i = 0; i < roots.length; i++)
		{
			var ancestor = parent != null ? model.isAncestor(parent, roots[i]) : true;
			
			if (ancestor && model.isVertex(roots[i]))
			{
				rootsCopy.push(roots[i]);
			}
		}

		this.roots = rootsCopy;
	}
	
	model.beginUpdate();
	try
	{
		this.run(parent);
		
		if (this.resizeParent && !this.graph.isCellCollapsed(parent))
		{
			this.graph.updateGroupBounds([parent], this.parentBorder, this.moveParent);
		}
		
		// Maintaining parent location
		if (this.parentX != null && this.parentY != null)
		{
			var geo = this.graph.getCellGeometry(parent);
			
			if (geo != null)
			{
				geo = geo.clone();
				geo.x = this.parentX;
				geo.y = this.parentY;
				model.setGeometry(parent, geo);
			}
		}
	}
	finally
	{
		model.endUpdate();
	}
};

/**
 * Function: findRoots
 * 
 * Returns all visible children in the given parent which do not have
 * incoming edges. If the result is empty then the children with the
 * maximum difference between incoming and outgoing edges are returned.
 * This takes into account edges that are being promoted to the given
 * root due to invisible children or collapsed cells.
 * 
 * Parameters:
 * 
 * parent - <mxCell> whose children should be checked.
 * vertices - array of vertices to limit search to
 */
mxHierarchicalLayout.prototype.findRoots = function(parent, vertices)
{
	var roots = [];
	
	if (parent != null && vertices != null)
	{
		var model = this.graph.model;
		var best = null;
		var maxDiff = -100000;
		
		for (var i in vertices)
		{
			var cell = vertices[i];

			if (model.isVertex(cell) && this.graph.isCellVisible(cell))
			{
				var conns = this.getEdges(cell);
				var fanOut = 0;
				var fanIn = 0;

				for (var k = 0; k < conns.length; k++)
				{
					var src = this.getVisibleTerminal(conns[k], true);

					if (src == cell)
					{
						fanOut++;
					}
					else
					{
						fanIn++;
					}
				}

				if (fanIn == 0 && fanOut > 0)
				{
					roots.push(cell);
				}

				var diff = fanOut - fanIn;

				if (diff > maxDiff)
				{
					maxDiff = diff;
					best = cell;
				}
			}
		}
		
		if (roots.length == 0 && best != null)
		{
			roots.push(best);
		}
	}
	
	return roots;
};

/**
 * Function: getEdges
 * 
 * Returns the connected edges for the given cell.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose edges should be returned.
 */
mxHierarchicalLayout.prototype.getEdges = function(cell)
{
	var cachedEdges = this.edgesCache.get(cell);
	
	if (cachedEdges != null)
	{
		return cachedEdges;
	}

	var model = this.graph.model;
	var edges = [];
	var isCollapsed = this.graph.isCellCollapsed(cell);
	var childCount = model.getChildCount(cell);

	for (var i = 0; i < childCount; i++)
	{
		var child = model.getChildAt(cell, i);

		if (this.isPort(child))
		{
			edges = edges.concat(model.getEdges(child, true, true));
		}
		else if (isCollapsed || !this.graph.isCellVisible(child))
		{
			edges = edges.concat(model.getEdges(child, true, true));
		}
	}

	edges = edges.concat(model.getEdges(cell, true, true));
	var result = [];
	
	for (var i = 0; i < edges.length; i++)
	{
		var source = this.getVisibleTerminal(edges[i], true);
		var target = this.getVisibleTerminal(edges[i], false);
		
		if ((source == target) || ((source != target) && ((target == cell && (this.parent == null || this.graph.isValidAncestor(source, this.parent, this.traverseAncestors))) ||
			(source == cell && (this.parent == null ||
					this.graph.isValidAncestor(target, this.parent, this.traverseAncestors))))))
		{
			result.push(edges[i]);
		}
	}

	this.edgesCache.put(cell, result);

	return result;
};

/**
 * Function: getVisibleTerminal
 * 
 * Helper function to return visible terminal for edge allowing for ports
 * 
 * Parameters:
 * 
 * edge - <mxCell> whose edges should be returned.
 * source - Boolean that specifies whether the source or target terminal is to be returned
 */
mxHierarchicalLayout.prototype.getVisibleTerminal = function(edge, source)
{
	var terminalCache = this.edgesTargetTermCache;
	
	if (source)
	{
		terminalCache = this.edgeSourceTermCache;
	}

	var term = terminalCache.get(edge);

	if (term != null)
	{
		return term;
	}

	var state = this.graph.view.getState(edge);
	
	var terminal = (state != null) ? state.getVisibleTerminal(source) : this.graph.view.getVisibleTerminal(edge, source);
	
	if (terminal == null)
	{
		terminal = (state != null) ? state.getVisibleTerminal(source) : this.graph.view.getVisibleTerminal(edge, source);
	}

	if (terminal != null)
	{
		if (this.isPort(terminal))
		{
			terminal = this.graph.model.getParent(terminal);
		}
		
		terminalCache.put(edge, terminal);
	}

	return terminal;
};

/**
 * Function: run
 * 
 * The API method used to exercise the layout upon the graph description
 * and produce a separate description of the vertex position and edge
 * routing changes made. It runs each stage of the layout that has been
 * created.
 */
mxHierarchicalLayout.prototype.run = function(parent)
{
	// Separate out unconnected hierarchies
	var hierarchyVertices = [];
	var allVertexSet = [];

	if (this.roots == null && parent != null)
	{
		var filledVertexSet = Object();
		this.filterDescendants(parent, filledVertexSet);

		this.roots = [];
		var filledVertexSetEmpty = true;

		// Poor man's isSetEmpty
		for (var key in filledVertexSet)
		{
			if (filledVertexSet[key] != null)
			{
				filledVertexSetEmpty = false;
				break;
			}
		}

		while (!filledVertexSetEmpty)
		{
			var candidateRoots = this.findRoots(parent, filledVertexSet);
			
			// If the candidate root is an unconnected group cell, remove it from
			// the layout. We may need a custom set that holds such groups and forces
			// them to be processed for resizing and/or moving.
			

			for (var i = 0; i < candidateRoots.length; i++)
			{
				var vertexSet = Object();
				hierarchyVertices.push(vertexSet);

				this.traverse(candidateRoots[i], true, null, allVertexSet, vertexSet,
						hierarchyVertices, filledVertexSet);
			}

			for (var i = 0; i < candidateRoots.length; i++)
			{
				this.roots.push(candidateRoots[i]);
			}
			
			filledVertexSetEmpty = true;
			
			// Poor man's isSetEmpty
			for (var key in filledVertexSet)
			{
				if (filledVertexSet[key] != null)
				{
					filledVertexSetEmpty = false;
					break;
				}
			}
		}
	}
	else
	{
		// Find vertex set as directed traversal from roots

		for (var i = 0; i < this.roots.length; i++)
		{
			var vertexSet = Object();
			hierarchyVertices.push(vertexSet);

			this.traverse(this.roots[i], true, null, allVertexSet, vertexSet,
					hierarchyVertices, null);
		}
	}

	// Iterate through the result removing parents who have children in this layout
	
	// Perform a layout for each seperate hierarchy
	// Track initial coordinate x-positioning
	var initialX = 0;

	for (var i = 0; i < hierarchyVertices.length; i++)
	{
		var vertexSet = hierarchyVertices[i];
		var tmp = [];
		
		for (var key in vertexSet)
		{
			tmp.push(vertexSet[key]);
		}
		
		this.model = new mxGraphHierarchyModel(this, tmp, this.roots,
			parent, this.tightenToSource);

		this.cycleStage(parent);
		this.layeringStage();
		
		this.crossingStage(parent);
		initialX = this.placementStage(initialX, parent);
	}
};

/**
 * Function: filterDescendants
 * 
 * Creates an array of descendant cells
 */
mxHierarchicalLayout.prototype.filterDescendants = function(cell, result)
{
	var model = this.graph.model;

	if (model.isVertex(cell) && cell != this.parent && this.graph.isCellVisible(cell))
	{
		result[mxObjectIdentity.get(cell)] = cell;
	}

	if (this.traverseAncestors || cell == this.parent
			&& this.graph.isCellVisible(cell))
	{
		var childCount = model.getChildCount(cell);

		for (var i = 0; i < childCount; i++)
		{
			var child = model.getChildAt(cell, i);
			
			// Ignore ports in the layout vertex list, they are dealt with
			// in the traversal mechanisms
			if (!this.isPort(child))
			{
				this.filterDescendants(child, result);
			}
		}
	}
};

/**
 * Function: isPort
 * 
 * Returns true if the given cell is a "port", that is, when connecting to
 * it, its parent is the connecting vertex in terms of graph traversal
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents the port.
 */
mxHierarchicalLayout.prototype.isPort = function(cell)
{
	if (cell.geometry.relative)
	{
		return true;
	}
	
	return false;
};

/**
 * Function: getEdgesBetween
 * 
 * Returns the edges between the given source and target. This takes into
 * account collapsed and invisible cells and ports.
 * 
 * Parameters:
 * 
 * source -
 * target -
 * directed -
 */
mxHierarchicalLayout.prototype.getEdgesBetween = function(source, target, directed)
{
	directed = (directed != null) ? directed : false;
	var edges = this.getEdges(source);
	var result = [];

	// Checks if the edge is connected to the correct
	// cell and returns the first match
	for (var i = 0; i < edges.length; i++)
	{
		var src = this.getVisibleTerminal(edges[i], true);
		var trg = this.getVisibleTerminal(edges[i], false);

		if ((src == source && trg == target) || (!directed && src == target && trg == source))
		{
			result.push(edges[i]);
		}
	}

	return result;
};

/**
 * Traverses the (directed) graph invoking the given function for each
 * visited vertex and edge. The function is invoked with the current vertex
 * and the incoming edge as a parameter. This implementation makes sure
 * each vertex is only visited once. The function may return false if the
 * traversal should stop at the given vertex.
 * 
 * Parameters:
 * 
 * vertex - <mxCell> that represents the vertex where the traversal starts.
 * directed - boolean indicating if edges should only be traversed
 * from source to target. Default is true.
 * edge - Optional <mxCell> that represents the incoming edge. This is
 * null for the first step of the traversal.
 * allVertices - Array of cell paths for the visited cells.
 */
mxHierarchicalLayout.prototype.traverse = function(vertex, directed, edge, allVertices, currentComp,
											hierarchyVertices, filledVertexSet)
{
	if (vertex != null && allVertices != null)
	{
		// Has this vertex been seen before in any traversal
		// And if the filled vertex set is populated, only 
		// process vertices in that it contains
		var vertexID = mxObjectIdentity.get(vertex);
		
		if ((allVertices[vertexID] == null)
				&& (filledVertexSet == null ? true : filledVertexSet[vertexID] != null))
		{
			if (currentComp[vertexID] == null)
			{
				currentComp[vertexID] = vertex;
			}
			if (allVertices[vertexID] == null)
			{
				allVertices[vertexID] = vertex;
			}

			if (filledVertexSet !== null)
			{
				delete filledVertexSet[vertexID];
			}

			var edges = this.getEdges(vertex);
			var edgeIsSource = [];

			for (var i = 0; i < edges.length; i++)
			{
				edgeIsSource[i] = (this.getVisibleTerminal(edges[i], true) == vertex);
			}

			for (var i = 0; i < edges.length; i++)
			{
				if (!directed || edgeIsSource[i])
				{
					var next = this.getVisibleTerminal(edges[i], !edgeIsSource[i]);
					
					// Check whether there are more edges incoming from the target vertex than outgoing
					// The hierarchical model treats bi-directional parallel edges as being sourced
					// from the more "sourced" terminal. If the directions are equal in number, the direction
					// is that of the natural direction from the roots of the layout.
					// The checks below are slightly more verbose than need be for performance reasons
					var netCount = 1;

					for (var j = 0; j < edges.length; j++)
					{
						if (j == i)
						{
							continue;
						}
						else
						{
							var isSource2 = edgeIsSource[j];
							var otherTerm = this.getVisibleTerminal(edges[j], !isSource2);
							
							if (otherTerm == next)
							{
								if (isSource2)
								{
									netCount++;
								}
								else
								{
									netCount--;
								}
							}
						}
					}

					if (netCount >= 0)
					{
						currentComp = this.traverse(next, directed, edges[i], allVertices,
							currentComp, hierarchyVertices,
							filledVertexSet);
					}
				}
			}
		}
		else
		{
			if (currentComp[vertexID] == null)
			{
				// We've seen this vertex before, but not in the current component
				// This component and the one it's in need to be merged

				for (var i = 0; i < hierarchyVertices.length; i++)
				{
					var comp = hierarchyVertices[i];

					if (comp[vertexID] != null)
					{
						for (var key in comp)
						{
							currentComp[key] = comp[key];
						}
						
						// Remove the current component from the hierarchy set
						hierarchyVertices.splice(i, 1);
						return currentComp;
					}
				}
			}
		}
	}
	
	return currentComp;
};

/**
 * Function: cycleStage
 * 
 * Executes the cycle stage using mxMinimumCycleRemover.
 */
mxHierarchicalLayout.prototype.cycleStage = function(parent)
{
	var cycleStage = new mxMinimumCycleRemover(this);
	cycleStage.execute(parent);
};

/**
 * Function: layeringStage
 * 
 * Implements first stage of a Sugiyama layout.
 */
mxHierarchicalLayout.prototype.layeringStage = function()
{
	this.model.initialRank();
	this.model.fixRanks();
};

/**
 * Function: crossingStage
 * 
 * Executes the crossing stage using mxMedianHybridCrossingReduction.
 */
mxHierarchicalLayout.prototype.crossingStage = function(parent)
{
	var crossingStage = new mxMedianHybridCrossingReduction(this);
	crossingStage.execute(parent);
};

/**
 * Function: placementStage
 * 
 * Executes the placement stage using mxCoordinateAssignment.
 */
mxHierarchicalLayout.prototype.placementStage = function(initialX, parent)
{
	var placementStage = new mxCoordinateAssignment(this, this.intraCellSpacing,
			this.interRankCellSpacing, this.orientation, initialX,
			this.parallelEdgeSpacing);
	placementStage.fineTuning = this.fineTuning;
	placementStage.execute(parent);
	
	return placementStage.limitX + this.interHierarchySpacing;
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxSwimlaneLayout
 * 
 * A hierarchical layout algorithm.
 * 
 * Constructor: mxSwimlaneLayout
 *
 * Constructs a new hierarchical layout algorithm.
 *
 * Arguments:
 * 
 * graph - Reference to the enclosing <mxGraph>.
 * orientation - Optional constant that defines the orientation of this
 * layout.
 * deterministic - Optional boolean that specifies if this layout should be
 * deterministic. Default is true.
 */
function mxSwimlaneLayout(graph, orientation, deterministic)
{
	mxGraphLayout.call(this, graph);
	this.orientation = (orientation != null) ? orientation : mxConstants.DIRECTION_NORTH;
	this.deterministic = (deterministic != null) ? deterministic : true;
};

/**
 * Extends mxGraphLayout.
 */
mxSwimlaneLayout.prototype = new mxGraphLayout();
mxSwimlaneLayout.prototype.constructor = mxSwimlaneLayout;

/**
 * Variable: roots
 * 
 * Holds the array of <mxCell> that this layout contains.
 */
mxSwimlaneLayout.prototype.roots = null;

/**
 * Variable: swimlanes
 * 
 * Holds the array of <mxCell> of the ordered swimlanes to lay out
 */
mxSwimlaneLayout.prototype.swimlanes = null;

/**
 * Variable: dummyVertices
 * 
 * Holds an array of <mxCell> of dummy vertices inserted during the layout
 * to pad out empty swimlanes
 */
mxSwimlaneLayout.prototype.dummyVertices = null;

/**
 * Variable: dummyVertexWidth
 * 
 * The cell width of any dummy vertices inserted
 */
mxSwimlaneLayout.prototype.dummyVertexWidth = 50;

/**
 * Variable: resizeParent
 * 
 * Specifies if the parent should be resized after the layout so that it
 * contains all the child cells. Default is false. See also <parentBorder>.
 */
mxSwimlaneLayout.prototype.resizeParent = false;

/**
 * Variable: maintainParentLocation
 * 
 * Specifies if the parent location should be maintained, so that the
 * top, left corner stays the same before and after execution of
 * the layout. Default is false for backwards compatibility.
 */
mxSwimlaneLayout.prototype.maintainParentLocation = false;

/**
 * Variable: moveParent
 * 
 * Specifies if the parent should be moved if <resizeParent> is enabled.
 * Default is false.
 */
mxSwimlaneLayout.prototype.moveParent = false;

/**
 * Variable: parentBorder
 * 
 * The border to be added around the children if the parent is to be
 * resized using <resizeParent>. Default is 0.
 */
mxSwimlaneLayout.prototype.parentBorder = 30;

/**
 * Variable: intraCellSpacing
 * 
 * The spacing buffer added between cells on the same layer. Default is 30.
 */
mxSwimlaneLayout.prototype.intraCellSpacing = 30;

/**
 * Variable: interRankCellSpacing
 * 
 * The spacing buffer added between cell on adjacent layers. Default is 50.
 */
mxSwimlaneLayout.prototype.interRankCellSpacing = 100;

/**
 * Variable: interHierarchySpacing
 * 
 * The spacing buffer between unconnected hierarchies. Default is 60.
 */
mxSwimlaneLayout.prototype.interHierarchySpacing = 60;

/**
 * Variable: parallelEdgeSpacing
 * 
 * The distance between each parallel edge on each ranks for long edges
 */
mxSwimlaneLayout.prototype.parallelEdgeSpacing = 10;

/**
 * Variable: orientation
 * 
 * The position of the root node(s) relative to the laid out graph in.
 * Default is <mxConstants.DIRECTION_NORTH>.
 */
mxSwimlaneLayout.prototype.orientation = mxConstants.DIRECTION_NORTH;

/**
 * Variable: fineTuning
 * 
 * Whether or not to perform local optimisations and iterate multiple times
 * through the algorithm. Default is true.
 */
mxSwimlaneLayout.prototype.fineTuning = true;

/**
 * 
 * Variable: tightenToSource
 * 
 * Whether or not to tighten the assigned ranks of vertices up towards
 * the source cells.
 */
mxSwimlaneLayout.prototype.tightenToSource = true;

/**
 * Variable: disableEdgeStyle
 * 
 * Specifies if the STYLE_NOEDGESTYLE flag should be set on edges that are
 * modified by the result. Default is true.
 */
mxSwimlaneLayout.prototype.disableEdgeStyle = true;

/**
 * Variable: traverseAncestors
 * 
 * Whether or not to drill into child cells and layout in reverse
 * group order. This also cause the layout to navigate edges whose 
 * terminal vertices  * have different parents but are in the same 
 * ancestry chain
 */
mxSwimlaneLayout.prototype.traverseAncestors = true;

/**
 * Variable: model
 * 
 * The internal <mxSwimlaneModel> formed of the layout.
 */
mxSwimlaneLayout.prototype.model = null;

/**
 * Variable: edgesSet
 * 
 * A cache of edges whose source terminal is the key
 */
mxSwimlaneLayout.prototype.edgesCache = null;

/**
 * Variable: edgesSet
 * 
 * A cache of edges whose source terminal is the key
 */
mxHierarchicalLayout.prototype.edgeSourceTermCache = null;

/**
 * Variable: edgesSet
 * 
 * A cache of edges whose source terminal is the key
 */
mxHierarchicalLayout.prototype.edgesTargetTermCache = null;

/**
 * Variable: edgeStyle
 * 
 * The style to apply between cell layers to edge segments
 */
mxHierarchicalLayout.prototype.edgeStyle = mxHierarchicalEdgeStyle.POLYLINE;

/**
 * Function: getModel
 * 
 * Returns the internal <mxSwimlaneModel> for this layout algorithm.
 */
mxSwimlaneLayout.prototype.getModel = function()
{
	return this.model;
};

/**
 * Function: execute
 * 
 * Executes the layout for the children of the specified parent.
 * 
 * Parameters:
 * 
 * parent - Parent <mxCell> that contains the children to be laid out.
 * swimlanes - Ordered array of swimlanes to be laid out
 */
mxSwimlaneLayout.prototype.execute = function(parent, swimlanes)
{
	this.parent = parent;
	var model = this.graph.model;
	this.edgesCache = new mxDictionary();
	this.edgeSourceTermCache = new mxDictionary();
	this.edgesTargetTermCache = new mxDictionary();

	// If the roots are set and the parent is set, only
	// use the roots that are some dependent of the that
	// parent.
	// If just the root are set, use them as-is
	// If just the parent is set use it's immediate
	// children as the initial set

	if (swimlanes == null || swimlanes.length < 1)
	{
		// TODO indicate the problem
		return;
	}

	if (parent == null)
	{
		parent = model.getParent(swimlanes[0]);
	}

	//  Maintaining parent location
	this.parentX = null;
	this.parentY = null;
	
	if (parent != this.root && model.isVertex(parent) != null && this.maintainParentLocation)
	{
		var geo = this.graph.getCellGeometry(parent);
		
		if (geo != null)
		{
			this.parentX = geo.x;
			this.parentY = geo.y;
		}
	}

	this.swimlanes = swimlanes;
	this.dummyVertices = [];
	// Check the swimlanes all have vertices
	// in them
	for (var i = 0; i < swimlanes.length; i++)
	{
		var children = this.graph.getChildCells(swimlanes[i]);
		
		if (children == null || children.length == 0)
		{
			var vertex = this.graph.insertVertex(swimlanes[i], null, null, 0, 0, this.dummyVertexWidth, 0);
			this.dummyVertices.push(vertex);
		}
	}
	
	model.beginUpdate();
	try
	{
		this.run(parent);
		
		if (this.resizeParent && !this.graph.isCellCollapsed(parent))
		{
			this.graph.updateGroupBounds([parent], this.parentBorder, this.moveParent);
		}
		
		// Maintaining parent location
		if (this.parentX != null && this.parentY != null)
		{
			var geo = this.graph.getCellGeometry(parent);
			
			if (geo != null)
			{
				geo = geo.clone();
				geo.x = this.parentX;
				geo.y = this.parentY;
				model.setGeometry(parent, geo);
			}
		}

		this.graph.removeCells(this.dummyVertices);
	}
	finally
	{
		model.endUpdate();
	}
};

/**
 * Function: updateGroupBounds
 * 
 * Updates the bounds of the given array of groups so that it includes
 * all child vertices.
 * 
 */
mxSwimlaneLayout.prototype.updateGroupBounds = function()
{
	// Get all vertices and edge in the layout
	var cells = [];
	var model = this.model;
	
	for (var key in model.edgeMapper)
	{
		var edge = model.edgeMapper[key];
		
		for (var i = 0; i < edge.edges.length; i++)
		{
			cells.push(edge.edges[i]);
		}
	}
	
	var layoutBounds = this.graph.getBoundingBoxFromGeometry(cells, true);
	var childBounds = [];

	for (var i = 0; i < this.swimlanes.length; i++)
	{
		var lane = this.swimlanes[i];
		var geo = this.graph.getCellGeometry(lane);
		
		if (geo != null)
		{
			var children = this.graph.getChildCells(lane);
			
			var size = (this.graph.isSwimlane(lane)) ?
					this.graph.getStartSize(lane) : new mxRectangle();

			var bounds = this.graph.getBoundingBoxFromGeometry(children);
			childBounds[i] = bounds;
			var childrenY = bounds.y + geo.y - size.height - this.parentBorder;
			var maxChildrenY = bounds.y + geo.y + bounds.height;

			if (layoutBounds == null)
			{
				layoutBounds = new mxRectangle(0, childrenY, 0, maxChildrenY - childrenY);
			}
			else
			{
				layoutBounds.y = Math.min(layoutBounds.y, childrenY);
				var maxY = Math.max(layoutBounds.y + layoutBounds.height, maxChildrenY);
				layoutBounds.height = maxY - layoutBounds.y;
			}
		}
	}

	
	for (var i = 0; i < this.swimlanes.length; i++)
	{
		var lane = this.swimlanes[i];
		var geo = this.graph.getCellGeometry(lane);
		
		if (geo != null)
		{
			var children = this.graph.getChildCells(lane);
			
			var size = (this.graph.isSwimlane(lane)) ?
					this.graph.getStartSize(lane) : new mxRectangle();

			var newGeo = geo.clone();
			
			var leftGroupBorder = (i == 0) ? this.parentBorder : this.interRankCellSpacing/2;
			newGeo.x += childBounds[i].x - size.width - leftGroupBorder;
			newGeo.y = newGeo.y + layoutBounds.y - geo.y - this.parentBorder;
			
			newGeo.width = childBounds[i].width + size.width + this.interRankCellSpacing/2 + leftGroupBorder;
			newGeo.height = layoutBounds.height + size.height + 2 * this.parentBorder;
			
			this.graph.model.setGeometry(lane, newGeo);
			this.graph.moveCells(children, -childBounds[i].x + size.width + leftGroupBorder, 
					geo.y - layoutBounds.y + this.parentBorder);
		}
	}
};

/**
 * Function: findRoots
 * 
 * Returns all visible children in the given parent which do not have
 * incoming edges. If the result is empty then the children with the
 * maximum difference between incoming and outgoing edges are returned.
 * This takes into account edges that are being promoted to the given
 * root due to invisible children or collapsed cells.
 * 
 * Parameters:
 * 
 * parent - <mxCell> whose children should be checked.
 * vertices - array of vertices to limit search to
 */
mxSwimlaneLayout.prototype.findRoots = function(parent, vertices)
{
	var roots = [];
	
	if (parent != null && vertices != null)
	{
		var model = this.graph.model;
		var best = null;
		var maxDiff = -100000;
		
		for (var i in vertices)
		{
			var cell = vertices[i];

			if (cell != null && model.isVertex(cell) && this.graph.isCellVisible(cell) && model.isAncestor(parent, cell))
			{
				var conns = this.getEdges(cell);
				var fanOut = 0;
				var fanIn = 0;

				for (var k = 0; k < conns.length; k++)
				{
					var src = this.getVisibleTerminal(conns[k], true);

					if (src == cell)
					{
						// Only count connection within this swimlane
						var other = this.getVisibleTerminal(conns[k], false);
						
						if (model.isAncestor(parent, other))
						{
							fanOut++;
						}
					}
					else if (model.isAncestor(parent, src))
					{
						fanIn++;
					}
				}

				if (fanIn == 0 && fanOut > 0)
				{
					roots.push(cell);
				}

				var diff = fanOut - fanIn;

				if (diff > maxDiff)
				{
					maxDiff = diff;
					best = cell;
				}
			}
		}
		
		if (roots.length == 0 && best != null)
		{
			roots.push(best);
		}
	}
	
	return roots;
};

/**
 * Function: getEdges
 * 
 * Returns the connected edges for the given cell.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose edges should be returned.
 */
mxSwimlaneLayout.prototype.getEdges = function(cell)
{
	var cachedEdges = this.edgesCache.get(cell);
	
	if (cachedEdges != null)
	{
		return cachedEdges;
	}

	var model = this.graph.model;
	var edges = [];
	var isCollapsed = this.graph.isCellCollapsed(cell);
	var childCount = model.getChildCount(cell);

	for (var i = 0; i < childCount; i++)
	{
		var child = model.getChildAt(cell, i);

		if (this.isPort(child))
		{
			edges = edges.concat(model.getEdges(child, true, true));
		}
		else if (isCollapsed || !this.graph.isCellVisible(child))
		{
			edges = edges.concat(model.getEdges(child, true, true));
		}
	}

	edges = edges.concat(model.getEdges(cell, true, true));
	var result = [];
	
	for (var i = 0; i < edges.length; i++)
	{
		var source = this.getVisibleTerminal(edges[i], true);
		var target = this.getVisibleTerminal(edges[i], false);
		
		if ((source == target) || ((source != target) && ((target == cell && (this.parent == null || this.graph.isValidAncestor(source, this.parent, this.traverseAncestors))) ||
			(source == cell && (this.parent == null ||
					this.graph.isValidAncestor(target, this.parent, this.traverseAncestors))))))
		{
			result.push(edges[i]);
		}
	}

	this.edgesCache.put(cell, result);

	return result;
};

/**
 * Function: getVisibleTerminal
 * 
 * Helper function to return visible terminal for edge allowing for ports
 * 
 * Parameters:
 * 
 * edge - <mxCell> whose edges should be returned.
 * source - Boolean that specifies whether the source or target terminal is to be returned
 */
mxSwimlaneLayout.prototype.getVisibleTerminal = function(edge, source)
{
	var terminalCache = this.edgesTargetTermCache;
	
	if (source)
	{
		terminalCache = this.edgeSourceTermCache;
	}

	var term = terminalCache.get(edge);

	if (term != null)
	{
		return term;
	}

	var state = this.graph.view.getState(edge);
	
	var terminal = (state != null) ? state.getVisibleTerminal(source) : this.graph.view.getVisibleTerminal(edge, source);
	
	if (terminal == null)
	{
		terminal = (state != null) ? state.getVisibleTerminal(source) : this.graph.view.getVisibleTerminal(edge, source);
	}

	if (terminal != null)
	{
		if (this.isPort(terminal))
		{
			terminal = this.graph.model.getParent(terminal);
		}
		
		terminalCache.put(edge, terminal);
	}

	return terminal;
};

/**
 * Function: run
 * 
 * The API method used to exercise the layout upon the graph description
 * and produce a separate description of the vertex position and edge
 * routing changes made. It runs each stage of the layout that has been
 * created.
 */
mxSwimlaneLayout.prototype.run = function(parent)
{
	// Separate out unconnected hierarchies
	var hierarchyVertices = [];
	var allVertexSet = [];

	if (this.swimlanes != null && this.swimlanes.length > 0 && parent != null)
	{
		var filledVertexSet = Object();
		
		for (var i = 0; i < this.swimlanes.length; i++)
		{
			this.filterDescendants(this.swimlanes[i], filledVertexSet);
		}

		this.roots = [];
		var filledVertexSetEmpty = true;

		// Poor man's isSetEmpty
		for (var key in filledVertexSet)
		{
			if (filledVertexSet[key] != null)
			{
				filledVertexSetEmpty = false;
				break;
			}
		}

		// Only test for candidates in each swimlane in order
		var laneCounter = 0;

		while (!filledVertexSetEmpty && laneCounter < this.swimlanes.length)
		{
			var candidateRoots = this.findRoots(this.swimlanes[laneCounter], filledVertexSet);
			
			if (candidateRoots.length == 0)
			{
				laneCounter++;
				continue;
			}
			
			// If the candidate root is an unconnected group cell, remove it from
			// the layout. We may need a custom set that holds such groups and forces
			// them to be processed for resizing and/or moving.
			for (var i = 0; i < candidateRoots.length; i++)
			{
				var vertexSet = Object();
				hierarchyVertices.push(vertexSet);

				this.traverse(candidateRoots[i], true, null, allVertexSet, vertexSet,
						hierarchyVertices, filledVertexSet, laneCounter);
			}

			for (var i = 0; i < candidateRoots.length; i++)
			{
				this.roots.push(candidateRoots[i]);
			}
			
			filledVertexSetEmpty = true;
			
			// Poor man's isSetEmpty
			for (var key in filledVertexSet)
			{
				if (filledVertexSet[key] != null)
				{
					filledVertexSetEmpty = false;
					break;
				}
			}
		}
	}
	else
	{
		// Find vertex set as directed traversal from roots

		for (var i = 0; i < this.roots.length; i++)
		{
			var vertexSet = Object();
			hierarchyVertices.push(vertexSet);

			this.traverse(this.roots[i], true, null, allVertexSet, vertexSet,
					hierarchyVertices, null);
		}
	}

	var tmp = [];
	
	for (var key in allVertexSet)
	{
		tmp.push(allVertexSet[key]);
	}
	
	this.model = new mxSwimlaneModel(this, tmp, this.roots,
		parent, this.tightenToSource);

	this.cycleStage(parent);
	this.layeringStage();
	
	this.crossingStage(parent);
	initialX = this.placementStage(0, parent);
};

/**
 * Function: filterDescendants
 * 
 * Creates an array of descendant cells
 */
mxSwimlaneLayout.prototype.filterDescendants = function(cell, result)
{
	var model = this.graph.model;

	if (model.isVertex(cell) && cell != this.parent && model.getParent(cell) != this.parent && this.graph.isCellVisible(cell))
	{
		result[mxObjectIdentity.get(cell)] = cell;
	}

	if (this.traverseAncestors || cell == this.parent
			&& this.graph.isCellVisible(cell))
	{
		var childCount = model.getChildCount(cell);

		for (var i = 0; i < childCount; i++)
		{
			var child = model.getChildAt(cell, i);
			
			// Ignore ports in the layout vertex list, they are dealt with
			// in the traversal mechanisms
			if (!this.isPort(child))
			{
				this.filterDescendants(child, result);
			}
		}
	}
};

/**
 * Function: isPort
 * 
 * Returns true if the given cell is a "port", that is, when connecting to
 * it, its parent is the connecting vertex in terms of graph traversal
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents the port.
 */
mxSwimlaneLayout.prototype.isPort = function(cell)
{
	if (cell.geometry.relative)
	{
		return true;
	}
	
	return false;
};

/**
 * Function: getEdgesBetween
 * 
 * Returns the edges between the given source and target. This takes into
 * account collapsed and invisible cells and ports.
 * 
 * Parameters:
 * 
 * source -
 * target -
 * directed -
 */
mxSwimlaneLayout.prototype.getEdgesBetween = function(source, target, directed)
{
	directed = (directed != null) ? directed : false;
	var edges = this.getEdges(source);
	var result = [];

	// Checks if the edge is connected to the correct
	// cell and returns the first match
	for (var i = 0; i < edges.length; i++)
	{
		var src = this.getVisibleTerminal(edges[i], true);
		var trg = this.getVisibleTerminal(edges[i], false);

		if ((src == source && trg == target) || (!directed && src == target && trg == source))
		{
			result.push(edges[i]);
		}
	}

	return result;
};

/**
 * Traverses the (directed) graph invoking the given function for each
 * visited vertex and edge. The function is invoked with the current vertex
 * and the incoming edge as a parameter. This implementation makes sure
 * each vertex is only visited once. The function may return false if the
 * traversal should stop at the given vertex.
 * 
 * Parameters:
 * 
 * vertex - <mxCell> that represents the vertex where the traversal starts.
 * directed - boolean indicating if edges should only be traversed
 * from source to target. Default is true.
 * edge - Optional <mxCell> that represents the incoming edge. This is
 * null for the first step of the traversal.
 * allVertices - Array of cell paths for the visited cells.
 * swimlaneIndex - the laid out order index of the swimlane vertex is contained in
 */
mxSwimlaneLayout.prototype.traverse = function(vertex, directed, edge, allVertices, currentComp,
											hierarchyVertices, filledVertexSet, swimlaneIndex)
{
	if (vertex != null && allVertices != null)
	{
		// Has this vertex been seen before in any traversal
		// And if the filled vertex set is populated, only 
		// process vertices in that it contains
		var vertexID = mxObjectIdentity.get(vertex);
		
		if ((allVertices[vertexID] == null)
				&& (filledVertexSet == null ? true : filledVertexSet[vertexID] != null))
		{
			if (currentComp[vertexID] == null)
			{
				currentComp[vertexID] = vertex;
			}
			if (allVertices[vertexID] == null)
			{
				allVertices[vertexID] = vertex;
			}

			if (filledVertexSet !== null)
			{
				delete filledVertexSet[vertexID];
			}

			var edges = this.getEdges(vertex);
			var model = this.graph.model;

			for (var i = 0; i < edges.length; i++)
			{
				var otherVertex = this.getVisibleTerminal(edges[i], true);
				var isSource = otherVertex == vertex;
				
				if (isSource)
				{
					otherVertex = this.getVisibleTerminal(edges[i], false);
				}

				var otherIndex = 0;
				// Get the swimlane index of the other terminal
				for (otherIndex = 0; otherIndex < this.swimlanes.length; otherIndex++)
				{
					if (model.isAncestor(this.swimlanes[otherIndex], otherVertex))
					{
						break;
					}
				}
				
				if (otherIndex >= this.swimlanes.length)
				{
					continue;
				}

				// Traverse if the other vertex is within the same swimlane as
				// as the current vertex, or if the swimlane index of the other
				// vertex is greater than that of this vertex
				if ((otherIndex > swimlaneIndex) ||
						((!directed || isSource) && otherIndex == swimlaneIndex))
				{
					currentComp = this.traverse(otherVertex, directed, edges[i], allVertices,
							currentComp, hierarchyVertices,
							filledVertexSet, otherIndex);
				}
			}
		}
		else
		{
			if (currentComp[vertexID] == null)
			{
				// We've seen this vertex before, but not in the current component
				// This component and the one it's in need to be merged
				for (var i = 0; i < hierarchyVertices.length; i++)
				{
					var comp = hierarchyVertices[i];

					if (comp[vertexID] != null)
					{
						for (var key in comp)
						{
							currentComp[key] = comp[key];
						}
						
						// Remove the current component from the hierarchy set
						hierarchyVertices.splice(i, 1);
						return currentComp;
					}
				}
			}
		}
	}
	
	return currentComp;
};

/**
 * Function: cycleStage
 * 
 * Executes the cycle stage using mxMinimumCycleRemover.
 */
mxSwimlaneLayout.prototype.cycleStage = function(parent)
{
	var cycleStage = new mxSwimlaneOrdering(this);
	cycleStage.execute(parent);
};

/**
 * Function: layeringStage
 * 
 * Implements first stage of a Sugiyama layout.
 */
mxSwimlaneLayout.prototype.layeringStage = function()
{
	this.model.initialRank();
	this.model.fixRanks();
};

/**
 * Function: crossingStage
 * 
 * Executes the crossing stage using mxMedianHybridCrossingReduction.
 */
mxSwimlaneLayout.prototype.crossingStage = function(parent)
{
	var crossingStage = new mxMedianHybridCrossingReduction(this);
	crossingStage.execute(parent);
};

/**
 * Function: placementStage
 * 
 * Executes the placement stage using mxCoordinateAssignment.
 */
mxSwimlaneLayout.prototype.placementStage = function(initialX, parent)
{
	var placementStage = new mxCoordinateAssignment(this, this.intraCellSpacing,
			this.interRankCellSpacing, this.orientation, initialX,
			this.parallelEdgeSpacing);
	placementStage.fineTuning = this.fineTuning;
	placementStage.execute(parent);
	
	return placementStage.limitX + this.interHierarchySpacing;
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxGraphModel
 * 
 * Extends <mxEventSource> to implement a graph model. The graph model acts as
 * a wrapper around the cells which are in charge of storing the actual graph
 * datastructure. The model acts as a transactional wrapper with event
 * notification for all changes, whereas the cells contain the atomic
 * operations for updating the actual datastructure.
 * 
 * Layers:
 * 
 * The cell hierarchy in the model must have a top-level root cell which
 * contains the layers (typically one default layer), which in turn contain the
 * top-level cells of the layers. This means each cell is contained in a layer.
 * If no layers are required, then all new cells should be added to the default
 * layer.
 * 
 * Layers are useful for hiding and showing groups of cells, or for placing
 * groups of cells on top of other cells in the display. To identify a layer,
 * the <isLayer> function is used. It returns true if the parent of the given
 * cell is the root of the model.
 * 
 * Events:
 * 
 * See events section for more details. There is a new set of events for
 * tracking transactional changes as they happen. The events are called
 * startEdit for the initial beginUpdate, executed for each executed change
 * and endEdit for the terminal endUpdate. The executed event contains a
 * property called change which represents the change after execution.
 * 
 * Encoding the model:
 * 
 * To encode a graph model, use the following code:
 * 
 * (code)
 * var enc = new mxCodec();
 * var node = enc.encode(graph.getModel());
 * (end)
 * 
 * This will create an XML node that contains all the model information.
 * 
 * Encoding and decoding changes:
 * 
 * For the encoding of changes, a graph model listener is required that encodes
 * each change from the given array of changes.
 * 
 * (code)
 * model.addListener(mxEvent.CHANGE, function(sender, evt)
 * {
 *   var changes = evt.getProperty('edit').changes;
 *   var nodes = [];
 *   var codec = new mxCodec();
 * 
 *   for (var i = 0; i < changes.length; i++)
 *   {
 *     nodes.push(codec.encode(changes[i]));
 *   }
 *   // do something with the nodes
 * });
 * (end)
 * 
 * For the decoding and execution of changes, the codec needs a lookup function
 * that allows it to resolve cell IDs as follows:
 * 
 * (code)
 * var codec = new mxCodec();
 * codec.lookup = function(id)
 * {
 *   return model.getCell(id);
 * }
 * (end)
 * 
 * For each encoded change (represented by a node), the following code can be
 * used to carry out the decoding and create a change object.
 * 
 * (code)
 * var changes = [];
 * var change = codec.decode(node);
 * change.model = model;
 * change.execute();
 * changes.push(change);
 * (end)
 * 
 * The changes can then be dispatched using the model as follows.
 * 
 * (code)
 * var edit = new mxUndoableEdit(model, false);
 * edit.changes = changes;
 * 
 * edit.notify = function()
 * {
 *   edit.source.fireEvent(new mxEventObject(mxEvent.CHANGE,
 *   	'edit', edit, 'changes', edit.changes));
 *   edit.source.fireEvent(new mxEventObject(mxEvent.NOTIFY,
 *   	'edit', edit, 'changes', edit.changes));
 * }
 * 
 * model.fireEvent(new mxEventObject(mxEvent.UNDO, 'edit', edit));
 * model.fireEvent(new mxEventObject(mxEvent.CHANGE,
 * 		'edit', edit, 'changes', changes));
 * (end)
 *
 * Event: mxEvent.CHANGE
 *
 * Fires when an undoable edit is dispatched. The <code>edit</code> property
 * contains the <mxUndoableEdit>. The <code>changes</code> property contains
 * the array of atomic changes inside the undoable edit. The changes property
 * is <strong>deprecated</strong>, please use edit.changes instead.
 *
 * Example:
 * 
 * For finding newly inserted cells, the following code can be used:
 * 
 * (code)
 * graph.model.addListener(mxEvent.CHANGE, function(sender, evt)
 * {
 *   var changes = evt.getProperty('edit').changes;
 * 
 *   for (var i = 0; i < changes.length; i++)
 *   {
 *     var change = changes[i];
 *     
 *     if (change instanceof mxChildChange &&
 *       change.change.previous == null)
 *     {
 *       graph.startEditingAtCell(change.child);
 *       break;
 *     }
 *   }
 * });
 * (end)
 * 
 * 
 * Event: mxEvent.NOTIFY
 *
 * Same as <mxEvent.CHANGE>, this event can be used for classes that need to
 * implement a sync mechanism between this model and, say, a remote model. In
 * such a setup, only local changes should trigger a notify event and all
 * changes should trigger a change event.
 * 
 * Event: mxEvent.EXECUTE
 * 
 * Fires between begin- and endUpdate and after an atomic change was executed
 * in the model. The <code>change</code> property contains the atomic change
 * that was executed.
 * 
 * Event: mxEvent.EXECUTED
 * 
 * Fires between START_EDIT and END_EDIT after an atomic change was executed.
 * The <code>change</code> property contains the change that was executed.
 *
 * Event: mxEvent.BEGIN_UPDATE
 *
 * Fires after the <updateLevel> was incremented in <beginUpdate>. This event
 * contains no properties.
 * 
 * Event: mxEvent.START_EDIT
 *
 * Fires after the <updateLevel> was changed from 0 to 1. This event
 * contains no properties.
 * 
 * Event: mxEvent.END_UPDATE
 * 
 * Fires after the <updateLevel> was decreased in <endUpdate> but before any
 * notification or change dispatching. The <code>edit</code> property contains
 * the <currentEdit>.
 * 
 * Event: mxEvent.END_EDIT
 *
 * Fires after the <updateLevel> was changed from 1 to 0. This event
 * contains no properties.
 * 
 * Event: mxEvent.BEFORE_UNDO
 * 
 * Fires before the change is dispatched after the update level has reached 0
 * in <endUpdate>. The <code>edit</code> property contains the <curreneEdit>.
 * 
 * Event: mxEvent.UNDO
 * 
 * Fires after the change was dispatched in <endUpdate>. The <code>edit</code>
 * property contains the <currentEdit>.
 * 
 * Constructor: mxGraphModel
 * 
 * Constructs a new graph model. If no root is specified then a new root
 * <mxCell> with a default layer is created.
 * 
 * Parameters:
 * 
 * root - <mxCell> that represents the root cell.
 */
function mxGraphModel(root)
{
	this.currentEdit = this.createUndoableEdit();
	
	if (root != null)
	{
		this.setRoot(root);
	}
	else
	{
		this.clear();
	}
};

/**
 * Extends mxEventSource.
 */
mxGraphModel.prototype = new mxEventSource();
mxGraphModel.prototype.constructor = mxGraphModel;

/**
 * Variable: root
 * 
 * Holds the root cell, which in turn contains the cells that represent the
 * layers of the diagram as child cells. That is, the actual elements of the
 * diagram are supposed to live in the third generation of cells and below.
 */
mxGraphModel.prototype.root = null;

/**
 * Variable: cells
 * 
 * Maps from Ids to cells.
 */
mxGraphModel.prototype.cells = null;

/**
 * Variable: maintainEdgeParent
 * 
 * Specifies if edges should automatically be moved into the nearest common
 * ancestor of their terminals. Default is true.
 */
mxGraphModel.prototype.maintainEdgeParent = true;

/**
 * Variable: ignoreRelativeEdgeParent
 * 
 * Specifies if relative edge parents should be ignored for finding the nearest
 * common ancestors of an edge's terminals. Default is true.
 */
mxGraphModel.prototype.ignoreRelativeEdgeParent = true;

/**
 * Variable: createIds
 * 
 * Specifies if the model should automatically create Ids for new cells.
 * Default is true.
 */
mxGraphModel.prototype.createIds = true;

/**
 * Variable: prefix
 * 
 * Defines the prefix of new Ids. Default is an empty string.
 */
mxGraphModel.prototype.prefix = '';

/**
 * Variable: postfix
 * 
 * Defines the postfix of new Ids. Default is an empty string.
 */
mxGraphModel.prototype.postfix = '';

/**
 * Variable: nextId
 * 
 * Specifies the next Id to be created. Initial value is 0.
 */
mxGraphModel.prototype.nextId = 0;

/**
 * Variable: currentEdit
 * 
 * Holds the changes for the current transaction. If the transaction is
 * closed then a new object is created for this variable using
 * <createUndoableEdit>.
 */
mxGraphModel.prototype.currentEdit = null;

/**
 * Variable: updateLevel
 * 
 * Counter for the depth of nested transactions. Each call to <beginUpdate>
 * will increment this number and each call to <endUpdate> will decrement
 * it. When the counter reaches 0, the transaction is closed and the
 * respective events are fired. Initial value is 0.
 */
mxGraphModel.prototype.updateLevel = 0;

/**
 * Variable: endingUpdate
 * 
 * True if the program flow is currently inside endUpdate.
 */
mxGraphModel.prototype.endingUpdate = false;

/**
 * Function: clear
 *
 * Sets a new root using <createRoot>.
 */
mxGraphModel.prototype.clear = function()
{
	this.setRoot(this.createRoot());
};

/**
 * Function: isCreateIds
 *
 * Returns <createIds>.
 */
mxGraphModel.prototype.isCreateIds = function()
{
	return this.createIds;
};

/**
 * Function: setCreateIds
 *
 * Sets <createIds>.
 */
mxGraphModel.prototype.setCreateIds = function(value)
{
	this.createIds = value;
};

/**
 * Function: createRoot
 *
 * Creates a new root cell with a default layer (child 0).
 */
mxGraphModel.prototype.createRoot = function()
{
	var cell = new mxCell();
	cell.insert(new mxCell());
	
	return cell;
};

/**
 * Function: getCell
 *
 * Returns the <mxCell> for the specified Id or null if no cell can be
 * found for the given Id.
 *
 * Parameters:
 * 
 * id - A string representing the Id of the cell.
 */
mxGraphModel.prototype.getCell = function(id)
{
	return (this.cells != null) ? this.cells[id] : null;
};

/**
 * Function: filterCells
 * 
 * Returns the cells from the given array where the given filter function
 * returns true.
 */
mxGraphModel.prototype.filterCells = function(cells, filter)
{
	var result = null;
	
	if (cells != null)
	{
		result = [];
		
		for (var i = 0; i < cells.length; i++)
		{
			if (filter(cells[i]))
			{
				result.push(cells[i]);
			}
		}
	}
	
	return result;
};

/**
 * Function: getDescendants
 * 
 * Returns all descendants of the given cell and the cell itself in an array.
 * 
 * Parameters:
 * 
 * parent - <mxCell> whose descendants should be returned.
 */
mxGraphModel.prototype.getDescendants = function(parent)
{
	return this.filterDescendants(null, parent);
};

/**
 * Function: filterDescendants
 * 
 * Visits all cells recursively and applies the specified filter function
 * to each cell. If the function returns true then the cell is added
 * to the resulting array. The parent and result paramters are optional.
 * If parent is not specified then the recursion starts at <root>.
 * 
 * Example:
 * The following example extracts all vertices from a given model:
 * (code)
 * var filter = function(cell)
 * {
 * 	return model.isVertex(cell);
 * }
 * var vertices = model.filterDescendants(filter);
 * (end)
 * 
 * Parameters:
 * 
 * filter - JavaScript function that takes an <mxCell> as an argument
 * and returns a boolean.
 * parent - Optional <mxCell> that is used as the root of the recursion.
 */
mxGraphModel.prototype.filterDescendants = function(filter, parent)
{
	// Creates a new array for storing the result
	var result = [];

	// Recursion starts at the root of the model
	parent = parent || this.getRoot();
	
	// Checks if the filter returns true for the cell
	// and adds it to the result array
	if (filter == null || filter(parent))
	{
		result.push(parent);
	}
	
	// Visits the children of the cell
	var childCount = this.getChildCount(parent);
	
	for (var i = 0; i < childCount; i++)
	{
		var child = this.getChildAt(parent, i);
		result = result.concat(this.filterDescendants(filter, child));
	}

	return result;
};

/**
 * Function: getRoot
 * 
 * Returns the root of the model or the topmost parent of the given cell.
 *
 * Parameters:
 * 
 * cell - Optional <mxCell> that specifies the child.
 */
mxGraphModel.prototype.getRoot = function(cell)
{
	var root = cell || this.root;
	
	if (cell != null)
	{
		while (cell != null)
		{
			root = cell;
			cell = this.getParent(cell);
		}
	}
	
	return root;
};

/**
 * Function: setRoot
 * 
 * Sets the <root> of the model using <mxRootChange> and adds the change to
 * the current transaction. This resets all datastructures in the model and
 * is the preferred way of clearing an existing model. Returns the new
 * root.
 * 
 * Example:
 * 
 * (code)
 * var root = new mxCell();
 * root.insert(new mxCell());
 * model.setRoot(root);
 * (end)
 *
 * Parameters:
 * 
 * root - <mxCell> that specifies the new root.
 */
mxGraphModel.prototype.setRoot = function(root)
{
	this.execute(new mxRootChange(this, root));
	
	return root;
};

/**
 * Function: rootChanged
 * 
 * Inner callback to change the root of the model and update the internal
 * datastructures, such as <cells> and <nextId>. Returns the previous root.
 *
 * Parameters:
 * 
 * root - <mxCell> that specifies the new root.
 */
mxGraphModel.prototype.rootChanged = function(root)
{
	var oldRoot = this.root;
	this.root = root;
	
	// Resets counters and datastructures
	this.nextId = 0;
	this.cells = null;
	this.cellAdded(root);
	
	return oldRoot;
};

/**
 * Function: isRoot
 * 
 * Returns true if the given cell is the root of the model and a non-null
 * value.
 *
 * Parameters:
 * 
 * cell - <mxCell> that represents the possible root.
 */
mxGraphModel.prototype.isRoot = function(cell)
{
	return cell != null && this.root == cell;
};

/**
 * Function: isLayer
 * 
 * Returns true if <isRoot> returns true for the parent of the given cell.
 *
 * Parameters:
 * 
 * cell - <mxCell> that represents the possible layer.
 */
mxGraphModel.prototype.isLayer = function(cell)
{
	return this.isRoot(this.getParent(cell));
};

/**
 * Function: isAncestor
 * 
 * Returns true if the given parent is an ancestor of the given child.
 *
 * Parameters:
 * 
 * parent - <mxCell> that specifies the parent.
 * child - <mxCell> that specifies the child.
 */
mxGraphModel.prototype.isAncestor = function(parent, child)
{
	while (child != null && child != parent)
	{
		child = this.getParent(child);
	}
	
	return child == parent;
};

/**
 * Function: contains
 * 
 * Returns true if the model contains the given <mxCell>.
 *
 * Parameters:
 * 
 * cell - <mxCell> that specifies the cell.
 */
mxGraphModel.prototype.contains = function(cell)
{
	return this.isAncestor(this.root, cell);
};

/**
 * Function: getParent
 * 
 * Returns the parent of the given cell.
 *
 * Parameters:
 * 
 * cell - <mxCell> whose parent should be returned.
 */
mxGraphModel.prototype.getParent = function(cell)
{
	return (cell != null) ? cell.getParent() : null;
};

/**
 * Function: add
 * 
 * Adds the specified child to the parent at the given index using
 * <mxChildChange> and adds the change to the current transaction. If no
 * index is specified then the child is appended to the parent's array of
 * children. Returns the inserted child.
 * 
 * Parameters:
 * 
 * parent - <mxCell> that specifies the parent to contain the child.
 * child - <mxCell> that specifies the child to be inserted.
 * index - Optional integer that specifies the index of the child.
 */
mxGraphModel.prototype.add = function(parent, child, index)
{
	if (child != parent && parent != null && child != null)
	{	
		// Appends the child if no index was specified
		if (index == null)
		{
			index = this.getChildCount(parent);
		}
		
		var parentChanged = parent != this.getParent(child);
		this.execute(new mxChildChange(this, parent, child, index));

		// Maintains the edges parents by moving the edges
		// into the nearest common ancestor of its
		// terminals
		if (this.maintainEdgeParent && parentChanged)
		{
			this.updateEdgeParents(child);
		}
	}
	
	return child;
};

/**
 * Function: cellAdded
 * 
 * Inner callback to update <cells> when a cell has been added. This
 * implementation resolves collisions by creating new Ids. To change the
 * ID of a cell after it was inserted into the model, use the following
 * code:
 * 
 * (code
 * delete model.cells[cell.getId()];
 * cell.setId(newId);
 * model.cells[cell.getId()] = cell;
 * (end)
 *
 * If the change of the ID should be part of the command history, then the
 * cell should be removed from the model and a clone with the new ID should
 * be reinserted into the model instead.
 *
 * Parameters:
 * 
 * cell - <mxCell> that specifies the cell that has been added.
 */
mxGraphModel.prototype.cellAdded = function(cell)
{
	if (cell != null)
	{
		// Creates an Id for the cell if not Id exists
		if (cell.getId() == null && this.createIds)
		{
			cell.setId(this.createId(cell));
		}
		
		if (cell.getId() != null)
		{
			var collision = this.getCell(cell.getId());
			
			if (collision != cell)
			{	
				// Creates new Id for the cell
				// as long as there is a collision
				while (collision != null)
				{
					cell.setId(this.createId(cell));
					collision = this.getCell(cell.getId());
				}
				
				// Lazily creates the cells dictionary
				if (this.cells == null)
				{
					this.cells = new Object();
				}
				
				this.cells[cell.getId()] = cell;
			}
		}
		
		// Makes sure IDs of deleted cells are not reused
		if (mxUtils.isNumeric(cell.getId()))
		{
			this.nextId = Math.max(this.nextId, cell.getId());
		}
		
		// Recursively processes child cells
		var childCount = this.getChildCount(cell);
		
		for (var i=0; i<childCount; i++)
		{
			this.cellAdded(this.getChildAt(cell, i));
		}
	}
};

/**
 * Function: createId
 * 
 * Hook method to create an Id for the specified cell. This implementation
 * concatenates <prefix>, id and <postfix> to create the Id and increments
 * <nextId>. The cell is ignored by this implementation, but can be used in
 * overridden methods to prefix the Ids with eg. the cell type.
 *
 * Parameters:
 *
 * cell - <mxCell> to create the Id for.
 */
mxGraphModel.prototype.createId = function(cell)
{
	var id = this.nextId;
	this.nextId++;
	
	return this.prefix + id + this.postfix;
};

/**
 * Function: updateEdgeParents
 * 
 * Updates the parent for all edges that are connected to cell or one of
 * its descendants using <updateEdgeParent>.
 */
mxGraphModel.prototype.updateEdgeParents = function(cell, root)
{
	// Gets the topmost node of the hierarchy
	root = root || this.getRoot(cell);
	
	// Updates edges on children first
	var childCount = this.getChildCount(cell);
	
	for (var i = 0; i < childCount; i++)
	{
		var child = this.getChildAt(cell, i);
		this.updateEdgeParents(child, root);
	}
	
	// Updates the parents of all connected edges
	var edgeCount = this.getEdgeCount(cell);
	var edges = [];

	for (var i = 0; i < edgeCount; i++)
	{
		edges.push(this.getEdgeAt(cell, i));
	}
	
	for (var i = 0; i < edges.length; i++)
	{
		var edge = edges[i];
		
		// Updates edge parent if edge and child have
		// a common root node (does not need to be the
		// model root node)
		if (this.isAncestor(root, edge))
		{
			this.updateEdgeParent(edge, root);
		}
	}
};

/**
 * Function: updateEdgeParent
 *
 * Inner callback to update the parent of the specified <mxCell> to the
 * nearest-common-ancestor of its two terminals.
 *
 * Parameters:
 * 
 * edge - <mxCell> that specifies the edge.
 * root - <mxCell> that represents the current root of the model.
 */
mxGraphModel.prototype.updateEdgeParent = function(edge, root)
{
	var source = this.getTerminal(edge, true);
	var target = this.getTerminal(edge, false);
	var cell = null;
	
	// Uses the first non-relative descendants of the source terminal
	while (source != null && !this.isEdge(source) &&
		source.geometry != null && source.geometry.relative)
	{
		source = this.getParent(source);
	}
	
	// Uses the first non-relative descendants of the target terminal
	while (target != null && this.ignoreRelativeEdgeParent &&
		!this.isEdge(target) && target.geometry != null && 
		target.geometry.relative)
	{
		target = this.getParent(target);
	}
	
	if (this.isAncestor(root, source) && this.isAncestor(root, target))
	{
		if (source == target)
		{
			cell = this.getParent(source);
		}
		else
		{
			cell = this.getNearestCommonAncestor(source, target);
		}

		if (cell != null && (this.getParent(cell) != this.root ||
			this.isAncestor(cell, edge)) && this.getParent(edge) != cell)
		{
			var geo = this.getGeometry(edge);
			
			if (geo != null)
			{
				var origin1 = this.getOrigin(this.getParent(edge));
				var origin2 = this.getOrigin(cell);
				
				var dx = origin2.x - origin1.x;
				var dy = origin2.y - origin1.y;
				
				geo = geo.clone();
				geo.translate(-dx, -dy);
				this.setGeometry(edge, geo);
			}

			this.add(cell, edge, this.getChildCount(cell));
		}
	}
};

/**
 * Function: getOrigin
 * 
 * Returns the absolute, accumulated origin for the children inside the
 * given parent as an <mxPoint>.
 */
mxGraphModel.prototype.getOrigin = function(cell)
{
	var result = null;
	
	if (cell != null)
	{
		result = this.getOrigin(this.getParent(cell));
		
		if (!this.isEdge(cell))
		{
			var geo = this.getGeometry(cell);
			
			if (geo != null)
			{
				result.x += geo.x;
				result.y += geo.y;
			}
		}
	}
	else
	{
		result = new mxPoint();
	}
	
	return result;
};

/**
 * Function: getNearestCommonAncestor
 * 
 * Returns the nearest common ancestor for the specified cells.
 *
 * Parameters:
 * 
 * cell1 - <mxCell> that specifies the first cell in the tree.
 * cell2 - <mxCell> that specifies the second cell in the tree.
 */
mxGraphModel.prototype.getNearestCommonAncestor = function(cell1, cell2)
{
	if (cell1 != null && cell2 != null)
	{		
		// Creates the cell path for the second cell
		var path = mxCellPath.create(cell2);

		if (path != null && path.length > 0)
		{
			// Bubbles through the ancestors of the first
			// cell to find the nearest common ancestor.
			var cell = cell1;
			var current = mxCellPath.create(cell);
			
			// Inverts arguments
			if (path.length < current.length)
			{
				cell = cell2;
				var tmp = current;
				current = path;
				path = tmp;
			}
			
			while (cell != null)
			{
				var parent = this.getParent(cell);
				
				// Checks if the cell path is equal to the beginning of the given cell path
				if (path.indexOf(current + mxCellPath.PATH_SEPARATOR) == 0 && parent != null)
				{
					return cell;
				}
				
				current = mxCellPath.getParentPath(current);
				cell = parent;
			}
		}
	}
	
	return null;
};

/**
 * Function: remove
 * 
 * Removes the specified cell from the model using <mxChildChange> and adds
 * the change to the current transaction. This operation will remove the
 * cell and all of its children from the model. Returns the removed cell.
 *
 * Parameters:
 * 
 * cell - <mxCell> that should be removed.
 */
mxGraphModel.prototype.remove = function(cell)
{
	if (cell == this.root)
	{
		this.setRoot(null);
	}
	else if (this.getParent(cell) != null)
	{
		this.execute(new mxChildChange(this, null, cell));
	}
	
	return cell;
};

/**
 * Function: cellRemoved
 * 
 * Inner callback to update <cells> when a cell has been removed.
 *
 * Parameters:
 * 
 * cell - <mxCell> that specifies the cell that has been removed.
 */
mxGraphModel.prototype.cellRemoved = function(cell)
{
	if (cell != null && this.cells != null)
	{
		// Recursively processes child cells
		var childCount = this.getChildCount(cell);
		
		for (var i = childCount - 1; i >= 0; i--)
		{
			this.cellRemoved(this.getChildAt(cell, i));
		}
		
		// Removes the dictionary entry for the cell
		if (this.cells != null && cell.getId() != null)
		{
			delete this.cells[cell.getId()];
		}
	}
};

/**
 * Function: parentForCellChanged
 * 
 * Inner callback to update the parent of a cell using <mxCell.insert>
 * on the parent and return the previous parent.
 *
 * Parameters:
 * 
 * cell - <mxCell> to update the parent for.
 * parent - <mxCell> that specifies the new parent of the cell.
 * index - Optional integer that defines the index of the child
 * in the parent's child array.
 */
mxGraphModel.prototype.parentForCellChanged = function(cell, parent, index)
{
	var previous = this.getParent(cell);
	
	if (parent != null)
	{
		if (parent != previous || previous.getIndex(cell) != index)
		{
			parent.insert(cell, index);
		}
	}
	else if (previous != null)
	{
		var oldIndex = previous.getIndex(cell);
		previous.remove(oldIndex);
	}
	
	// Checks if the previous parent was already in the
	// model and avoids calling cellAdded if it was.
	if (!this.contains(previous) && parent != null)
	{
		this.cellAdded(cell);
	}
	else if (parent == null)
	{
		this.cellRemoved(cell);
	}
	
	return previous;
};

/**
 * Function: getChildCount
 *
 * Returns the number of children in the given cell.
 *
 * Parameters:
 * 
 * cell - <mxCell> whose number of children should be returned.
 */
mxGraphModel.prototype.getChildCount = function(cell)
{
	return (cell != null) ? cell.getChildCount() : 0;
};

/**
 * Function: getChildAt
 *
 * Returns the child of the given <mxCell> at the given index.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents the parent.
 * index - Integer that specifies the index of the child to be returned.
 */
mxGraphModel.prototype.getChildAt = function(cell, index)
{
	return (cell != null) ? cell.getChildAt(index) : null;
};

/**
 * Function: getChildren
 * 
 * Returns all children of the given <mxCell> as an array of <mxCells>. The
 * return value should be only be read.
 *
 * Parameters:
 * 
 * cell - <mxCell> the represents the parent.
 */
mxGraphModel.prototype.getChildren = function(cell)
{
	return (cell != null) ? cell.children : null;
};
	
/**
 * Function: getChildVertices
 * 
 * Returns the child vertices of the given parent.
 *
 * Parameters:
 * 
 * cell - <mxCell> whose child vertices should be returned.
 */
mxGraphModel.prototype.getChildVertices = function(parent)
{
	return this.getChildCells(parent, true, false);
};
		
/**
 * Function: getChildEdges
 * 
 * Returns the child edges of the given parent.
 *
 * Parameters:
 * 
 * cell - <mxCell> whose child edges should be returned.
 */
mxGraphModel.prototype.getChildEdges = function(parent)
{
	return this.getChildCells(parent, false, true);
};

/**
 * Function: getChildCells
 * 
 * Returns the children of the given cell that are vertices and/or edges
 * depending on the arguments.
 *
 * Parameters:
 * 
 * cell - <mxCell> the represents the parent.
 * vertices - Boolean indicating if child vertices should be returned.
 * Default is false.
 * edges - Boolean indicating if child edges should be returned.
 * Default is false.
 */
mxGraphModel.prototype.getChildCells = function(parent, vertices, edges)
{
	vertices = (vertices != null) ? vertices : false;
	edges = (edges != null) ? edges : false;
	
	var childCount = this.getChildCount(parent);
	var result = [];

	for (var i = 0; i < childCount; i++)
	{
		var child = this.getChildAt(parent, i);

		if ((!edges && !vertices) || (edges && this.isEdge(child)) ||
			(vertices && this.isVertex(child)))
		{
			result.push(child);
		}
	}

	return result;
};
		
/**
 * Function: getTerminal
 * 
 * Returns the source or target <mxCell> of the given edge depending on the
 * value of the boolean parameter.
 *
 * Parameters:
 * 
 * edge - <mxCell> that specifies the edge.
 * isSource - Boolean indicating which end of the edge should be returned.
 */
mxGraphModel.prototype.getTerminal = function(edge, isSource)
{
	return (edge != null) ? edge.getTerminal(isSource) : null;
};

/**
 * Function: setTerminal
 * 
 * Sets the source or target terminal of the given <mxCell> using
 * <mxTerminalChange> and adds the change to the current transaction.
 * This implementation updates the parent of the edge using <updateEdgeParent>
 * if required.
 *
 * Parameters:
 * 
 * edge - <mxCell> that specifies the edge.
 * terminal - <mxCell> that specifies the new terminal.
 * isSource - Boolean indicating if the terminal is the new source or
 * target terminal of the edge.
 */
mxGraphModel.prototype.setTerminal = function(edge, terminal, isSource)
{
	var terminalChanged = terminal != this.getTerminal(edge, isSource);
	this.execute(new mxTerminalChange(this, edge, terminal, isSource));
	
	if (this.maintainEdgeParent && terminalChanged)
	{
		this.updateEdgeParent(edge, this.getRoot());
	}
	
	return terminal;
};
	
/**
 * Function: setTerminals
 * 
 * Sets the source and target <mxCell> of the given <mxCell> in a single
 * transaction using <setTerminal> for each end of the edge.
 *
 * Parameters:
 * 
 * edge - <mxCell> that specifies the edge.
 * source - <mxCell> that specifies the new source terminal.
 * target - <mxCell> that specifies the new target terminal.
 */
mxGraphModel.prototype.setTerminals = function(edge, source, target)
{
	this.beginUpdate();
	try
	{
		this.setTerminal(edge, source, true);
		this.setTerminal(edge, target, false);
	}
	finally
	{
		this.endUpdate();
	}
};

/**
 * Function: terminalForCellChanged
 * 
 * Inner helper function to update the terminal of the edge using
 * <mxCell.insertEdge> and return the previous terminal.
 * 
 * Parameters:
 * 
 * edge - <mxCell> that specifies the edge to be updated.
 * terminal - <mxCell> that specifies the new terminal.
 * isSource - Boolean indicating if the terminal is the new source or
 * target terminal of the edge.
 */
mxGraphModel.prototype.terminalForCellChanged = function(edge, terminal, isSource)
{
	var previous = this.getTerminal(edge, isSource);
	
	if (terminal != null)
	{
		terminal.insertEdge(edge, isSource);
	}
	else if (previous != null)
	{
		previous.removeEdge(edge, isSource);
	}
	
	return previous;
};

/**
 * Function: getEdgeCount
 * 
 * Returns the number of distinct edges connected to the given cell.
 *
 * Parameters:
 * 
 * cell - <mxCell> that represents the vertex.
 */
mxGraphModel.prototype.getEdgeCount = function(cell)
{
	return (cell != null) ? cell.getEdgeCount() : 0;
};

/**
 * Function: getEdgeAt
 * 
 * Returns the edge of cell at the given index.
 *
 * Parameters:
 * 
 * cell - <mxCell> that specifies the vertex.
 * index - Integer that specifies the index of the edge
 * to return.
 */
mxGraphModel.prototype.getEdgeAt = function(cell, index)
{
	return (cell != null) ? cell.getEdgeAt(index) : null;
};
	
/**
 * Function: getDirectedEdgeCount
 * 
 * Returns the number of incoming or outgoing edges, ignoring the given
 * edge.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose edge count should be returned.
 * outgoing - Boolean that specifies if the number of outgoing or
 * incoming edges should be returned.
 * ignoredEdge - <mxCell> that represents an edge to be ignored.
 */
mxGraphModel.prototype.getDirectedEdgeCount = function(cell, outgoing, ignoredEdge)
{
	var count = 0;
	var edgeCount = this.getEdgeCount(cell);

	for (var i = 0; i < edgeCount; i++)
	{
		var edge = this.getEdgeAt(cell, i);

		if (edge != ignoredEdge && this.getTerminal(edge, outgoing) == cell)
		{
			count++;
		}
	}

	return count;
};

/**
 * Function: getConnections
 * 
 * Returns all edges of the given cell without loops.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose edges should be returned.
 * 
 */
mxGraphModel.prototype.getConnections = function(cell)
{
	return this.getEdges(cell, true, true, false);
};

/**
 * Function: getIncomingEdges
 * 
 * Returns the incoming edges of the given cell without loops.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose incoming edges should be returned.
 * 
 */
mxGraphModel.prototype.getIncomingEdges = function(cell)
{
	return this.getEdges(cell, true, false, false);
};

/**
 * Function: getOutgoingEdges
 * 
 * Returns the outgoing edges of the given cell without loops.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose outgoing edges should be returned.
 * 
 */
mxGraphModel.prototype.getOutgoingEdges = function(cell)
{
	return this.getEdges(cell, false, true, false);
};

/**
 * Function: getEdges
 * 
 * Returns all distinct edges connected to this cell as a new array of
 * <mxCells>. If at least one of incoming or outgoing is true, then loops
 * are ignored, otherwise if both are false, then all edges connected to
 * the given cell are returned including loops.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that specifies the cell.
 * incoming - Optional boolean that specifies if incoming edges should be
 * returned. Default is true.
 * outgoing - Optional boolean that specifies if outgoing edges should be
 * returned. Default is true.
 * includeLoops - Optional boolean that specifies if loops should be returned.
 * Default is true. 
 */
mxGraphModel.prototype.getEdges = function(cell, incoming, outgoing, includeLoops)
{
	incoming = (incoming != null) ? incoming : true;
	outgoing = (outgoing != null) ? outgoing : true;
	includeLoops = (includeLoops != null) ? includeLoops : true;
	
	var edgeCount = this.getEdgeCount(cell);
	var result = [];

	for (var i = 0; i < edgeCount; i++)
	{
		var edge = this.getEdgeAt(cell, i);
		var source = this.getTerminal(edge, true);
		var target = this.getTerminal(edge, false);

		if ((includeLoops && source == target) || ((source != target) && ((incoming && target == cell) ||
			(outgoing && source == cell))))
		{
			result.push(edge);
		}
	}

	return result;
};

/**
 * Function: getEdgesBetween
 * 
 * Returns all edges between the given source and target pair. If directed
 * is true, then only edges from the source to the target are returned,
 * otherwise, all edges between the two cells are returned.
 * 
 * Parameters:
 * 
 * source - <mxCell> that defines the source terminal of the edge to be
 * returned.
 * target - <mxCell> that defines the target terminal of the edge to be
 * returned.
 * directed - Optional boolean that specifies if the direction of the
 * edge should be taken into account. Default is false.
 */
mxGraphModel.prototype.getEdgesBetween = function(source, target, directed)
{
	directed = (directed != null) ? directed : false;
	
	var tmp1 = this.getEdgeCount(source);
	var tmp2 = this.getEdgeCount(target);
	
	// Assumes the source has less connected edges
	var terminal = source;
	var edgeCount = tmp1;
	
	// Uses the smaller array of connected edges
	// for searching the edge
	if (tmp2 < tmp1)
	{
		edgeCount = tmp2;
		terminal = target;
	}
	
	var result = [];
	
	// Checks if the edge is connected to the correct
	// cell and returns the first match
	for (var i = 0; i < edgeCount; i++)
	{
		var edge = this.getEdgeAt(terminal, i);
		var src = this.getTerminal(edge, true);
		var trg = this.getTerminal(edge, false);
		var directedMatch = (src == source) && (trg == target);
		var oppositeMatch = (trg == source) && (src == target);

		if (directedMatch || (!directed && oppositeMatch))
		{
			result.push(edge);
		}
	}
	
	return result;
};

/**
 * Function: getOpposites
 * 
 * Returns all opposite vertices wrt terminal for the given edges, only
 * returning sources and/or targets as specified. The result is returned
 * as an array of <mxCells>.
 * 
 * Parameters:
 * 
 * edges - Array of <mxCells> that contain the edges to be examined.
 * terminal - <mxCell> that specifies the known end of the edges.
 * sources - Boolean that specifies if source terminals should be contained
 * in the result. Default is true.
 * targets - Boolean that specifies if target terminals should be contained
 * in the result. Default is true.
 */
mxGraphModel.prototype.getOpposites = function(edges, terminal, sources, targets)
{
	sources = (sources != null) ? sources : true;
	targets = (targets != null) ? targets : true;
	
	var terminals = [];
	
	if (edges != null)
	{
		for (var i = 0; i < edges.length; i++)
		{
			var source = this.getTerminal(edges[i], true);
			var target = this.getTerminal(edges[i], false);
			
			// Checks if the terminal is the source of
			// the edge and if the target should be
			// stored in the result
			if (source == terminal && target != null && target != terminal && targets)
			{
				terminals.push(target);
			}
			
			// Checks if the terminal is the taget of
			// the edge and if the source should be
			// stored in the result
			else if (target == terminal && source != null && source != terminal && sources)
			{
				terminals.push(source);
			}
		}
	}
	
	return terminals;
};

/**
 * Function: getTopmostCells
 * 
 * Returns the topmost cells of the hierarchy in an array that contains no
 * descendants for each <mxCell> that it contains. Duplicates should be
 * removed in the cells array to improve performance.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> whose topmost ancestors should be returned.
 */
mxGraphModel.prototype.getTopmostCells = function(cells)
{
	var dict = new mxDictionary();
	var tmp = [];
	
	for (var i = 0; i < cells.length; i++)
	{
		dict.put(cells[i], true);
	}
	
	for (var i = 0; i < cells.length; i++)
	{
		var cell = cells[i];
		var topmost = true;
		var parent = this.getParent(cell);
		
		while (parent != null)
		{
			if (dict.get(parent))
			{
				topmost = false;
				break;
			}
			
			parent = this.getParent(parent);
		}
		
		if (topmost)
		{
			tmp.push(cell);
		}
	}
	
	return tmp;
};

/**
 * Function: isVertex
 * 
 * Returns true if the given cell is a vertex.
 *
 * Parameters:
 * 
 * cell - <mxCell> that represents the possible vertex.
 */
mxGraphModel.prototype.isVertex = function(cell)
{
	return (cell != null) ? cell.isVertex() : false;
};

/**
 * Function: isEdge
 * 
 * Returns true if the given cell is an edge.
 *
 * Parameters:
 * 
 * cell - <mxCell> that represents the possible edge.
 */
mxGraphModel.prototype.isEdge = function(cell)
{
	return (cell != null) ? cell.isEdge() : false;
};

/**
 * Function: isConnectable
 * 
 * Returns true if the given <mxCell> is connectable. If <edgesConnectable>
 * is false, then this function returns false for all edges else it returns
 * the return value of <mxCell.isConnectable>.
 *
 * Parameters:
 * 
 * cell - <mxCell> whose connectable state should be returned.
 */
mxGraphModel.prototype.isConnectable = function(cell)
{
	return (cell != null) ? cell.isConnectable() : false;
};

/**
 * Function: getValue
 * 
 * Returns the user object of the given <mxCell> using <mxCell.getValue>.
 *
 * Parameters:
 * 
 * cell - <mxCell> whose user object should be returned.
 */
mxGraphModel.prototype.getValue = function(cell)
{
	return (cell != null) ? cell.getValue() : null;
};

/**
 * Function: setValue
 * 
 * Sets the user object of then given <mxCell> using <mxValueChange>
 * and adds the change to the current transaction.
 *
 * Parameters:
 * 
 * cell - <mxCell> whose user object should be changed.
 * value - Object that defines the new user object.
 */
mxGraphModel.prototype.setValue = function(cell, value)
{
	this.execute(new mxValueChange(this, cell, value));
	
	return value;
};

/**
 * Function: valueForCellChanged
 * 
 * Inner callback to update the user object of the given <mxCell>
 * using <mxCell.valueChanged> and return the previous value,
 * that is, the return value of <mxCell.valueChanged>.
 * 
 * To change a specific attribute in an XML node, the following code can be
 * used.
 * 
 * (code)
 * graph.getModel().valueForCellChanged = function(cell, value)
 * {
 *   var previous = cell.value.getAttribute('label');
 *   cell.value.setAttribute('label', value);
 *   
 *   return previous;
 * };
 * (end) 
 */
mxGraphModel.prototype.valueForCellChanged = function(cell, value)
{
	return cell.valueChanged(value);
};

/**
 * Function: getGeometry
 * 
 * Returns the <mxGeometry> of the given <mxCell>.
 *
 * Parameters:
 * 
 * cell - <mxCell> whose geometry should be returned.
 */
mxGraphModel.prototype.getGeometry = function(cell)
{
	return (cell != null) ? cell.getGeometry() : null;
};

/**
 * Function: setGeometry
 * 
 * Sets the <mxGeometry> of the given <mxCell>. The actual update
 * of the cell is carried out in <geometryForCellChanged>. The
 * <mxGeometryChange> action is used to encapsulate the change.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose geometry should be changed.
 * geometry - <mxGeometry> that defines the new geometry.
 */
mxGraphModel.prototype.setGeometry = function(cell, geometry)
{
	if (geometry != this.getGeometry(cell))
	{
		this.execute(new mxGeometryChange(this, cell, geometry));
	}
	
	return geometry;
};

/**
 * Function: geometryForCellChanged
 * 
 * Inner callback to update the <mxGeometry> of the given <mxCell> using
 * <mxCell.setGeometry> and return the previous <mxGeometry>.
 */
mxGraphModel.prototype.geometryForCellChanged = function(cell, geometry)
{
	var previous = this.getGeometry(cell);
	cell.setGeometry(geometry);
	
	return previous;
};

/**
 * Function: getStyle
 * 
 * Returns the style of the given <mxCell>.
 *
 * Parameters:
 * 
 * cell - <mxCell> whose style should be returned.
 */
mxGraphModel.prototype.getStyle = function(cell)
{
	return (cell != null) ? cell.getStyle() : null;
};

/**
 * Function: setStyle
 * 
 * Sets the style of the given <mxCell> using <mxStyleChange> and
 * adds the change to the current transaction.
 *
 * Parameters:
 * 
 * cell - <mxCell> whose style should be changed.
 * style - String of the form [stylename;|key=value;] to specify
 * the new cell style.
 */
mxGraphModel.prototype.setStyle = function(cell, style)
{
	if (style != this.getStyle(cell))
	{
		this.execute(new mxStyleChange(this, cell, style));
	}
	
	return style;
};

/**
 * Function: styleForCellChanged
 * 
 * Inner callback to update the style of the given <mxCell>
 * using <mxCell.setStyle> and return the previous style.
 *
 * Parameters:
 * 
 * cell - <mxCell> that specifies the cell to be updated.
 * style - String of the form [stylename;|key=value;] to specify
 * the new cell style.
 */
mxGraphModel.prototype.styleForCellChanged = function(cell, style)
{
	var previous = this.getStyle(cell);
	cell.setStyle(style);
	
	return previous;
};

/**
 * Function: isCollapsed
 * 
 * Returns true if the given <mxCell> is collapsed.
 *
 * Parameters:
 * 
 * cell - <mxCell> whose collapsed state should be returned.
 */
mxGraphModel.prototype.isCollapsed = function(cell)
{
	return (cell != null) ? cell.isCollapsed() : false;
};

/**
 * Function: setCollapsed
 * 
 * Sets the collapsed state of the given <mxCell> using <mxCollapseChange>
 * and adds the change to the current transaction.
 *
 * Parameters:
 * 
 * cell - <mxCell> whose collapsed state should be changed.
 * collapsed - Boolean that specifies the new collpased state.
 */
mxGraphModel.prototype.setCollapsed = function(cell, collapsed)
{
	if (collapsed != this.isCollapsed(cell))
	{
		this.execute(new mxCollapseChange(this, cell, collapsed));
	}
	
	return collapsed;
};
	
/**
 * Function: collapsedStateForCellChanged
 *
 * Inner callback to update the collapsed state of the
 * given <mxCell> using <mxCell.setCollapsed> and return
 * the previous collapsed state.
 *
 * Parameters:
 * 
 * cell - <mxCell> that specifies the cell to be updated.
 * collapsed - Boolean that specifies the new collpased state.
 */
mxGraphModel.prototype.collapsedStateForCellChanged = function(cell, collapsed)
{
	var previous = this.isCollapsed(cell);
	cell.setCollapsed(collapsed);
	
	return previous;
};

/**
 * Function: isVisible
 * 
 * Returns true if the given <mxCell> is visible.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose visible state should be returned.
 */
mxGraphModel.prototype.isVisible = function(cell)
{
	return (cell != null) ? cell.isVisible() : false;
};

/**
 * Function: setVisible
 * 
 * Sets the visible state of the given <mxCell> using <mxVisibleChange> and
 * adds the change to the current transaction.
 *
 * Parameters:
 * 
 * cell - <mxCell> whose visible state should be changed.
 * visible - Boolean that specifies the new visible state.
 */
mxGraphModel.prototype.setVisible = function(cell, visible)
{
	if (visible != this.isVisible(cell))
	{
		this.execute(new mxVisibleChange(this, cell, visible));
	}
	
	return visible;
};
	
/**
 * Function: visibleStateForCellChanged
 *
 * Inner callback to update the visible state of the
 * given <mxCell> using <mxCell.setCollapsed> and return
 * the previous visible state.
 *
 * Parameters:
 * 
 * cell - <mxCell> that specifies the cell to be updated.
 * visible - Boolean that specifies the new visible state.
 */
mxGraphModel.prototype.visibleStateForCellChanged = function(cell, visible)
{
	var previous = this.isVisible(cell);
	cell.setVisible(visible);
	
	return previous;
};

/**
 * Function: execute
 * 
 * Executes the given edit and fires events if required. The edit object
 * requires an execute function which is invoked. The edit is added to the
 * <currentEdit> between <beginUpdate> and <endUpdate> calls, so that
 * events will be fired if this execute is an individual transaction, that
 * is, if no previous <beginUpdate> calls have been made without calling
 * <endUpdate>. This implementation fires an <execute> event before
 * executing the given change.
 * 
 * Parameters:
 * 
 * change - Object that described the change.
 */
mxGraphModel.prototype.execute = function(change)
{
	change.execute();
	this.beginUpdate();
	this.currentEdit.add(change);
	this.fireEvent(new mxEventObject(mxEvent.EXECUTE, 'change', change));
	// New global executed event
	this.fireEvent(new mxEventObject(mxEvent.EXECUTED, 'change', change));
	this.endUpdate();
};

/**
 * Function: beginUpdate
 * 
 * Increments the <updateLevel> by one. The event notification
 * is queued until <updateLevel> reaches 0 by use of
 * <endUpdate>.
 *
 * All changes on <mxGraphModel> are transactional,
 * that is, they are executed in a single undoable change
 * on the model (without transaction isolation).
 * Therefore, if you want to combine any
 * number of changes into a single undoable change,
 * you should group any two or more API calls that
 * modify the graph model between <beginUpdate>
 * and <endUpdate> calls as shown here:
 * 
 * (code)
 * var model = graph.getModel();
 * var parent = graph.getDefaultParent();
 * var index = model.getChildCount(parent);
 * model.beginUpdate();
 * try
 * {
 *   model.add(parent, v1, index);
 *   model.add(parent, v2, index+1);
 * }
 * finally
 * {
 *   model.endUpdate();
 * }
 * (end)
 * 
 * Of course there is a shortcut for appending a
 * sequence of cells into the default parent:
 * 
 * (code)
 * graph.addCells([v1, v2]).
 * (end)
 */
mxGraphModel.prototype.beginUpdate = function()
{
	this.updateLevel++;
	this.fireEvent(new mxEventObject(mxEvent.BEGIN_UPDATE));
	
	if (this.updateLevel == 1)
	{
		this.fireEvent(new mxEventObject(mxEvent.START_EDIT));
	}
};

/**
 * Function: endUpdate
 * 
 * Decrements the <updateLevel> by one and fires an <undo>
 * event if the <updateLevel> reaches 0. This function
 * indirectly fires a <change> event by invoking the notify
 * function on the <currentEdit> und then creates a new
 * <currentEdit> using <createUndoableEdit>.
 *
 * The <undo> event is fired only once per edit, whereas
 * the <change> event is fired whenever the notify
 * function is invoked, that is, on undo and redo of
 * the edit.
 */
mxGraphModel.prototype.endUpdate = function()
{
	this.updateLevel--;
	
	if (this.updateLevel == 0)
	{
		this.fireEvent(new mxEventObject(mxEvent.END_EDIT));
	}
	
	if (!this.endingUpdate)
	{
		this.endingUpdate = this.updateLevel == 0;
		this.fireEvent(new mxEventObject(mxEvent.END_UPDATE, 'edit', this.currentEdit));

		try
		{		
			if (this.endingUpdate && !this.currentEdit.isEmpty())
			{
				this.fireEvent(new mxEventObject(mxEvent.BEFORE_UNDO, 'edit', this.currentEdit));
				var tmp = this.currentEdit;
				this.currentEdit = this.createUndoableEdit();
				tmp.notify();
				this.fireEvent(new mxEventObject(mxEvent.UNDO, 'edit', tmp));
			}
		}
		finally
		{
			this.endingUpdate = false;
		}
	}
};

/**
 * Function: createUndoableEdit
 * 
 * Creates a new <mxUndoableEdit> that implements the
 * notify function to fire a <change> and <notify> event
 * through the <mxUndoableEdit>'s source.
 */
mxGraphModel.prototype.createUndoableEdit = function()
{
	var edit = new mxUndoableEdit(this, true);
	
	edit.notify = function()
	{
		// LATER: Remove changes property (deprecated)
		edit.source.fireEvent(new mxEventObject(mxEvent.CHANGE,
			'edit', edit, 'changes', edit.changes));
		edit.source.fireEvent(new mxEventObject(mxEvent.NOTIFY,
			'edit', edit, 'changes', edit.changes));
	};
	
	return edit;
};

/**
 * Function: mergeChildren
 * 
 * Merges the children of the given cell into the given target cell inside
 * this model. All cells are cloned unless there is a corresponding cell in
 * the model with the same id, in which case the source cell is ignored and
 * all edges are connected to the corresponding cell in this model. Edges
 * are considered to have no identity and are always cloned unless the
 * cloneAllEdges flag is set to false, in which case edges with the same
 * id in the target model are reconnected to reflect the terminals of the
 * source edges.
 */
mxGraphModel.prototype.mergeChildren = function(from, to, cloneAllEdges)
{
	cloneAllEdges = (cloneAllEdges != null) ? cloneAllEdges : true;
	
	this.beginUpdate();
	try
	{
		var mapping = new Object();
		this.mergeChildrenImpl(from, to, cloneAllEdges, mapping);
		
		// Post-processes all edges in the mapping and
		// reconnects the terminals to the corresponding
		// cells in the target model
		for (var key in mapping)
		{
			var cell = mapping[key];
			var terminal = this.getTerminal(cell, true);

			if (terminal != null)
			{
				terminal = mapping[mxCellPath.create(terminal)];
				this.setTerminal(cell, terminal, true);
			}
			
			terminal = this.getTerminal(cell, false);
			
			if (terminal != null)
			{
				terminal = mapping[mxCellPath.create(terminal)];
				this.setTerminal(cell, terminal, false);
			}
		}
	}
	finally
	{
		this.endUpdate();
	}
};

/**
 * Function: mergeChildren
 * 
 * Clones the children of the source cell into the given target cell in
 * this model and adds an entry to the mapping that maps from the source
 * cell to the target cell with the same id or the clone of the source cell
 * that was inserted into this model.
 */
mxGraphModel.prototype.mergeChildrenImpl = function(from, to, cloneAllEdges, mapping)
{
	this.beginUpdate();
	try
	{
		var childCount = from.getChildCount();
		
		for (var i = 0; i < childCount; i++)
		{
			var cell = from.getChildAt(i);
			
			if (typeof(cell.getId) == 'function')
			{
				var id = cell.getId();
				var target = (id != null && (!this.isEdge(cell) || !cloneAllEdges)) ?
						this.getCell(id) : null;
				
				// Clones and adds the child if no cell exists for the id
				if (target == null)
				{
					var clone = cell.clone();
					clone.setId(id);
					
					// Sets the terminals from the original cell to the clone
					// because the lookup uses strings not cells in JS
					clone.setTerminal(cell.getTerminal(true), true);
					clone.setTerminal(cell.getTerminal(false), false);
					
					// Do *NOT* use model.add as this will move the edge away
					// from the parent in updateEdgeParent if maintainEdgeParent
					// is enabled in the target model
					target = to.insert(clone);
					this.cellAdded(target);
				}
				
				// Stores the mapping for later reconnecting edges
				mapping[mxCellPath.create(cell)] = target;
				
				// Recurses
				this.mergeChildrenImpl(cell, target, cloneAllEdges, mapping);
			}
		}
	}
	finally
	{
		this.endUpdate();
	}
};

/**
 * Function: getParents
 * 
 * Returns an array that represents the set (no duplicates) of all parents
 * for the given array of cells.
 * 
 * Parameters:
 * 
 * cells - Array of cells whose parents should be returned.
 */
mxGraphModel.prototype.getParents = function(cells)
{
	var parents = [];
	
	if (cells != null)
	{
		var dict = new mxDictionary();
		
		for (var i = 0; i < cells.length; i++)
		{
			var parent = this.getParent(cells[i]);
			
			if (parent != null && !dict.get(parent))
			{
				dict.put(parent, true);
				parents.push(parent);
			}
		}
	}
	
	return parents;
};

//
// Cell Cloning
//

/**
 * Function: cloneCell
 * 
 * Returns a deep clone of the given <mxCell> (including
 * the children) which is created using <cloneCells>.
 *
 * Parameters:
 * 
 * cell - <mxCell> to be cloned.
 */
mxGraphModel.prototype.cloneCell = function(cell)
{
	if (cell != null)
	{
		return this.cloneCells([cell], true)[0];
	}
	
	return null;
};

/**
 * Function: cloneCells
 * 
 * Returns an array of clones for the given array of <mxCells>.
 * Depending on the value of includeChildren, a deep clone is created for
 * each cell. Connections are restored based if the corresponding
 * cell is contained in the passed in array.
 *
 * Parameters:
 * 
 * cells - Array of <mxCell> to be cloned.
 * includeChildren - Boolean indicating if the cells should be cloned
 * with all descendants.
 * mapping - Optional mapping for existing clones.
 */
mxGraphModel.prototype.cloneCells = function(cells, includeChildren, mapping)
{
	mapping = (mapping != null) ? mapping : new Object();
	var clones = [];
	
	for (var i = 0; i < cells.length; i++)
	{
		if (cells[i] != null)
		{
			clones.push(this.cloneCellImpl(cells[i], mapping, includeChildren));
		}
		else
		{
			clones.push(null);
		}
	}
	
	for (var i = 0; i < clones.length; i++)
	{
		if (clones[i] != null)
		{
			this.restoreClone(clones[i], cells[i], mapping);
		}
	}
	
	return clones;
};
			
/**
 * Function: cloneCellImpl
 * 
 * Inner helper method for cloning cells recursively.
 */
mxGraphModel.prototype.cloneCellImpl = function(cell, mapping, includeChildren)
{
	var clone = this.cellCloned(cell);
	
	// Stores the clone in the lookup table
	mapping[mxObjectIdentity.get(cell)] = clone;
	
	if (includeChildren)
	{
		var childCount = this.getChildCount(cell);
		
		for (var i = 0; i < childCount; i++)
		{
			var cloneChild = this.cloneCellImpl(
				this.getChildAt(cell, i), mapping, true);
			clone.insert(cloneChild);
		}
	}
	
	return clone;
};

/**
 * Function: cellCloned
 * 
 * Hook for cloning the cell. This returns cell.clone() or
 * any possible exceptions.
 */
mxGraphModel.prototype.cellCloned = function(cell)
{
	return cell.clone();
};

/**
 * Function: restoreClone
 * 
 * Inner helper method for restoring the connections in
 * a network of cloned cells.
 */
mxGraphModel.prototype.restoreClone = function(clone, cell, mapping)
{
	var source = this.getTerminal(cell, true);
	
	if (source != null)
	{
		var tmp = mapping[mxObjectIdentity.get(source)];
		
		if (tmp != null)
		{
			tmp.insertEdge(clone, true);
		}
	}
	
	var target = this.getTerminal(cell, false);
	
	if (target != null)
	{
		var tmp = mapping[mxObjectIdentity.get(target)];
		
		if (tmp != null)
		{	
			tmp.insertEdge(clone, false);
		}
	}
	
	var childCount = this.getChildCount(clone);
	
	for (var i = 0; i < childCount; i++)
	{
		this.restoreClone(this.getChildAt(clone, i),
			this.getChildAt(cell, i), mapping);
	}
};

//
// Atomic changes
//

/**
 * Class: mxRootChange
 * 
 * Action to change the root in a model.
 *
 * Constructor: mxRootChange
 * 
 * Constructs a change of the root in the
 * specified model.
 */
function mxRootChange(model, root)
{
	this.model = model;
	this.root = root;
	this.previous = root;
};

/**
 * Function: execute
 * 
 * Carries out a change of the root using
 * <mxGraphModel.rootChanged>.
 */
mxRootChange.prototype.execute = function()
{
	this.root = this.previous;
	this.previous = this.model.rootChanged(this.previous);
};

/**
 * Class: mxChildChange
 * 
 * Action to add or remove a child in a model.
 *
 * Constructor: mxChildChange
 * 
 * Constructs a change of a child in the
 * specified model.
 */
function mxChildChange(model, parent, child, index)
{
	this.model = model;
	this.parent = parent;
	this.previous = parent;
	this.child = child;
	this.index = index;
	this.previousIndex = index;
};

/**
 * Function: execute
 * 
 * Changes the parent of <child> using
 * <mxGraphModel.parentForCellChanged> and
 * removes or restores the cell's
 * connections.
 */
mxChildChange.prototype.execute = function()
{
	var tmp = this.model.getParent(this.child);
	var tmp2 = (tmp != null) ? tmp.getIndex(this.child) : 0;
	
	if (this.previous == null)
	{
		this.connect(this.child, false);
	}
	
	tmp = this.model.parentForCellChanged(
		this.child, this.previous, this.previousIndex);
		
	if (this.previous != null)
	{
		this.connect(this.child, true);
	}
	
	this.parent = this.previous;
	this.previous = tmp;
	this.index = this.previousIndex;
	this.previousIndex = tmp2;
};

/**
 * Function: disconnect
 * 
 * Disconnects the given cell recursively from its
 * terminals and stores the previous terminal in the
 * cell's terminals.
 */
mxChildChange.prototype.connect = function(cell, isConnect)
{
	isConnect = (isConnect != null) ? isConnect : true;
	
	var source = cell.getTerminal(true);
	var target = cell.getTerminal(false);
	
	if (source != null)
	{
		if (isConnect)
		{
			this.model.terminalForCellChanged(cell, source, true);
		}
		else
		{
			this.model.terminalForCellChanged(cell, null, true);
		}
	}
	
	if (target != null)
	{
		if (isConnect)
		{
			this.model.terminalForCellChanged(cell, target, false);
		}
		else
		{
			this.model.terminalForCellChanged(cell, null, false);
		}
	}
	
	cell.setTerminal(source, true);
	cell.setTerminal(target, false);
	
	var childCount = this.model.getChildCount(cell);
	
	for (var i=0; i<childCount; i++)
	{
		this.connect(this.model.getChildAt(cell, i), isConnect);
	}
};

/**
 * Class: mxTerminalChange
 * 
 * Action to change a terminal in a model.
 *
 * Constructor: mxTerminalChange
 * 
 * Constructs a change of a terminal in the 
 * specified model.
 */
function mxTerminalChange(model, cell, terminal, source)
{
	this.model = model;
	this.cell = cell;
	this.terminal = terminal;
	this.previous = terminal;
	this.source = source;
};

/**
 * Function: execute
 * 
 * Changes the terminal of <cell> to <previous> using
 * <mxGraphModel.terminalForCellChanged>.
 */
mxTerminalChange.prototype.execute = function()
{
	this.terminal = this.previous;
	this.previous = this.model.terminalForCellChanged(
		this.cell, this.previous, this.source);
};

/**
 * Class: mxValueChange
 * 
 * Action to change a user object in a model.
 *
 * Constructor: mxValueChange
 * 
 * Constructs a change of a user object in the 
 * specified model.
 */
function mxValueChange(model, cell, value)
{
	this.model = model;
	this.cell = cell;
	this.value = value;
	this.previous = value;
};

/**
 * Function: execute
 * 
 * Changes the value of <cell> to <previous> using
 * <mxGraphModel.valueForCellChanged>.
 */
mxValueChange.prototype.execute = function()
{
	this.value = this.previous;
	this.previous = this.model.valueForCellChanged(
		this.cell, this.previous);
};

/**
 * Class: mxStyleChange
 * 
 * Action to change a cell's style in a model.
 *
 * Constructor: mxStyleChange
 * 
 * Constructs a change of a style in the
 * specified model.
 */
function mxStyleChange(model, cell, style)
{
	this.model = model;
	this.cell = cell;
	this.style = style;
	this.previous = style;
};

/**
 * Function: execute
 * 
 * Changes the style of <cell> to <previous> using
 * <mxGraphModel.styleForCellChanged>.
 */
mxStyleChange.prototype.execute = function()
{
	this.style = this.previous;
	this.previous = this.model.styleForCellChanged(
		this.cell, this.previous);
};

/**
 * Class: mxGeometryChange
 * 
 * Action to change a cell's geometry in a model.
 *
 * Constructor: mxGeometryChange
 * 
 * Constructs a change of a geometry in the
 * specified model.
 */
function mxGeometryChange(model, cell, geometry)
{
	this.model = model;
	this.cell = cell;
	this.geometry = geometry;
	this.previous = geometry;
};

/**
 * Function: execute
 * 
 * Changes the geometry of <cell> ro <previous> using
 * <mxGraphModel.geometryForCellChanged>.
 */
mxGeometryChange.prototype.execute = function()
{
	this.geometry = this.previous;
	this.previous = this.model.geometryForCellChanged(
		this.cell, this.previous);
};

/**
 * Class: mxCollapseChange
 * 
 * Action to change a cell's collapsed state in a model.
 *
 * Constructor: mxCollapseChange
 * 
 * Constructs a change of a collapsed state in the
 * specified model.
 */
function mxCollapseChange(model, cell, collapsed)
{
	this.model = model;
	this.cell = cell;
	this.collapsed = collapsed;
	this.previous = collapsed;
};

/**
 * Function: execute
 * 
 * Changes the collapsed state of <cell> to <previous> using
 * <mxGraphModel.collapsedStateForCellChanged>.
 */
mxCollapseChange.prototype.execute = function()
{
	this.collapsed = this.previous;
	this.previous = this.model.collapsedStateForCellChanged(
		this.cell, this.previous);
};

/**
 * Class: mxVisibleChange
 * 
 * Action to change a cell's visible state in a model.
 *
 * Constructor: mxVisibleChange
 * 
 * Constructs a change of a visible state in the
 * specified model.
 */
function mxVisibleChange(model, cell, visible)
{
	this.model = model;
	this.cell = cell;
	this.visible = visible;
	this.previous = visible;
};

/**
 * Function: execute
 * 
 * Changes the visible state of <cell> to <previous> using
 * <mxGraphModel.visibleStateForCellChanged>.
 */
mxVisibleChange.prototype.execute = function()
{
	this.visible = this.previous;
	this.previous = this.model.visibleStateForCellChanged(
		this.cell, this.previous);
};

/**
 * Class: mxCellAttributeChange
 * 
 * Action to change the attribute of a cell's user object.
 * There is no method on the graph model that uses this
 * action. To use the action, you can use the code shown
 * in the example below.
 * 
 * Example:
 * 
 * To change the attributeName in the cell's user object
 * to attributeValue, use the following code:
 * 
 * (code)
 * model.beginUpdate();
 * try
 * {
 *   var edit = new mxCellAttributeChange(
 *     cell, attributeName, attributeValue);
 *   model.execute(edit);
 * }
 * finally
 * {
 *   model.endUpdate();
 * } 
 * (end)
 *
 * Constructor: mxCellAttributeChange
 * 
 * Constructs a change of a attribute of the DOM node
 * stored as the value of the given <mxCell>.
 */
function mxCellAttributeChange(cell, attribute, value)
{
	this.cell = cell;
	this.attribute = attribute;
	this.value = value;
	this.previous = value;
};

/**
 * Function: execute
 * 
 * Changes the attribute of the cell's user object by
 * using <mxCell.setAttribute>.
 */
mxCellAttributeChange.prototype.execute = function()
{
	var tmp = this.cell.getAttribute(this.attribute);
	
	if (this.previous == null)
	{
		this.cell.value.removeAttribute(this.attribute);
	}
	else
	{
		this.cell.setAttribute(this.attribute, this.previous);
	}
	
	this.previous = tmp;
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxCell
 *
 * Cells are the elements of the graph model. They represent the state
 * of the groups, vertices and edges in a graph.
 * 
 * Custom attributes:
 * 
 * For custom attributes we recommend using an XML node as the value of a cell.
 * The following code can be used to create a cell with an XML node as the
 * value:
 * 
 * (code)
 * var doc = mxUtils.createXmlDocument();
 * var node = doc.createElement('MyNode')
 * node.setAttribute('label', 'MyLabel');
 * node.setAttribute('attribute1', 'value1');
 * graph.insertVertex(graph.getDefaultParent(), null, node, 40, 40, 80, 30);
 * (end)
 * 
 * For the label to work, <mxGraph.convertValueToString> and
 * <mxGraph.cellLabelChanged> should be overridden as follows:
 * 
 * (code)
 * graph.convertValueToString = function(cell)
 * {
 *   if (mxUtils.isNode(cell.value))
 *   {
 *     return cell.getAttribute('label', '')
 *   }
 * };
 * 
 * var cellLabelChanged = graph.cellLabelChanged;
 * graph.cellLabelChanged = function(cell, newValue, autoSize)
 * {
 *   if (mxUtils.isNode(cell.value))
 *   {
 *     // Clones the value for correct undo/redo
 *     var elt = cell.value.cloneNode(true);
 *     elt.setAttribute('label', newValue);
 *     newValue = elt;
 *   }
 *   
 *   cellLabelChanged.apply(this, arguments);
 * };
 * (end)
 * 
 * Callback: onInit
 *
 * Called from within the constructor.
 * 
 * Constructor: mxCell
 *
 * Constructs a new cell to be used in a graph model.
 * This method invokes <onInit> upon completion.
 * 
 * Parameters:
 * 
 * value - Optional object that represents the cell value.
 * geometry - Optional <mxGeometry> that specifies the geometry.
 * style - Optional formatted string that defines the style.
 */
function mxCell(value, geometry, style)
{
	this.value = value;
	this.setGeometry(geometry);
	this.setStyle(style);
	
	if (this.onInit != null)
	{
		this.onInit();
	}
};

/**
 * Variable: id
 *
 * Holds the Id. Default is null.
 */
mxCell.prototype.id = null;

/**
 * Variable: value
 *
 * Holds the user object. Default is null.
 */
mxCell.prototype.value = null;

/**
 * Variable: geometry
 *
 * Holds the <mxGeometry>. Default is null.
 */
mxCell.prototype.geometry = null;

/**
 * Variable: style
 *
 * Holds the style as a string of the form [(stylename|key=value);]. Default is
 * null.
 */
mxCell.prototype.style = null;

/**
 * Variable: vertex
 *
 * Specifies whether the cell is a vertex. Default is false.
 */
mxCell.prototype.vertex = false;

/**
 * Variable: edge
 *
 * Specifies whether the cell is an edge. Default is false.
 */
mxCell.prototype.edge = false;

/**
 * Variable: connectable
 *
 * Specifies whether the cell is connectable. Default is true.
 */
mxCell.prototype.connectable = true;

/**
 * Variable: visible
 *
 * Specifies whether the cell is visible. Default is true.
 */
mxCell.prototype.visible = true;

/**
 * Variable: collapsed
 *
 * Specifies whether the cell is collapsed. Default is false.
 */
mxCell.prototype.collapsed = false;

/**
 * Variable: parent
 *
 * Reference to the parent cell.
 */
mxCell.prototype.parent = null;

/**
 * Variable: source
 *
 * Reference to the source terminal.
 */
mxCell.prototype.source = null;

/**
 * Variable: target
 *
 * Reference to the target terminal.
 */
mxCell.prototype.target = null;

/**
 * Variable: children
 *
 * Holds the child cells.
 */
mxCell.prototype.children = null;

/**
 * Variable: edges
 *
 * Holds the edges.
 */
mxCell.prototype.edges = null;

/**
 * Variable: mxTransient
 *
 * List of members that should not be cloned inside <clone>. This field is
 * passed to <mxUtils.clone> and is not made persistent in <mxCellCodec>.
 * This is not a convention for all classes, it is only used in this class
 * to mark transient fields since transient modifiers are not supported by
 * the language.
 */
mxCell.prototype.mxTransient = ['id', 'value', 'parent', 'source',
                                'target', 'children', 'edges'];

/**
 * Function: getId
 *
 * Returns the Id of the cell as a string.
 */
mxCell.prototype.getId = function()
{
	return this.id;
};
		
/**
 * Function: setId
 *
 * Sets the Id of the cell to the given string.
 */
mxCell.prototype.setId = function(id)
{
	this.id = id;
};

/**
 * Function: getValue
 *
 * Returns the user object of the cell. The user
 * object is stored in <value>.
 */
mxCell.prototype.getValue = function()
{
	return this.value;
};
		
/**
 * Function: setValue
 *
 * Sets the user object of the cell. The user object
 * is stored in <value>.
 */
mxCell.prototype.setValue = function(value)
{
	this.value = value;
};

/**
 * Function: valueChanged
 *
 * Changes the user object after an in-place edit
 * and returns the previous value. This implementation
 * replaces the user object with the given value and
 * returns the old user object.
 */
mxCell.prototype.valueChanged = function(newValue)
{
	var previous = this.getValue();
	this.setValue(newValue);
	
	return previous;
};

/**
 * Function: getGeometry
 *
 * Returns the <mxGeometry> that describes the <geometry>.
 */
mxCell.prototype.getGeometry = function()
{
	return this.geometry;
};

/**
 * Function: setGeometry
 *
 * Sets the <mxGeometry> to be used as the <geometry>.
 */
mxCell.prototype.setGeometry = function(geometry)
{
	this.geometry = geometry;
};

/**
 * Function: getStyle
 *
 * Returns a string that describes the <style>.
 */
mxCell.prototype.getStyle = function()
{
	return this.style;
};

/**
 * Function: setStyle
 *
 * Sets the string to be used as the <style>.
 */
mxCell.prototype.setStyle = function(style)
{
	this.style = style;
};

/**
 * Function: isVertex
 *
 * Returns true if the cell is a vertex.
 */
mxCell.prototype.isVertex = function()
{
	return this.vertex != 0;
};

/**
 * Function: setVertex
 *
 * Specifies if the cell is a vertex. This should only be assigned at
 * construction of the cell and not be changed during its lifecycle.
 * 
 * Parameters:
 * 
 * vertex - Boolean that specifies if the cell is a vertex.
 */
mxCell.prototype.setVertex = function(vertex)
{
	this.vertex = vertex;
};

/**
 * Function: isEdge
 *
 * Returns true if the cell is an edge.
 */
mxCell.prototype.isEdge = function()
{
	return this.edge != 0;
};
	
/**
 * Function: setEdge
 * 
 * Specifies if the cell is an edge. This should only be assigned at
 * construction of the cell and not be changed during its lifecycle.
 * 
 * Parameters:
 * 
 * edge - Boolean that specifies if the cell is an edge.
 */
mxCell.prototype.setEdge = function(edge)
{
	this.edge = edge;
};

/**
 * Function: isConnectable
 *
 * Returns true if the cell is connectable.
 */
mxCell.prototype.isConnectable = function()
{
	return this.connectable != 0;
};

/**
 * Function: setConnectable
 *
 * Sets the connectable state.
 * 
 * Parameters:
 * 
 * connectable - Boolean that specifies the new connectable state.
 */
mxCell.prototype.setConnectable = function(connectable)
{
	this.connectable = connectable;
};

/**
 * Function: isVisible
 *
 * Returns true if the cell is visibile.
 */
mxCell.prototype.isVisible = function()
{
	return this.visible != 0;
};

/**
 * Function: setVisible
 *
 * Specifies if the cell is visible.
 * 
 * Parameters:
 * 
 * visible - Boolean that specifies the new visible state.
 */
mxCell.prototype.setVisible = function(visible)
{
	this.visible = visible;
};

/**
 * Function: isCollapsed
 *
 * Returns true if the cell is collapsed.
 */
mxCell.prototype.isCollapsed = function()
{
	return this.collapsed != 0;
};

/**
 * Function: setCollapsed
 *
 * Sets the collapsed state.
 * 
 * Parameters:
 * 
 * collapsed - Boolean that specifies the new collapsed state.
 */
mxCell.prototype.setCollapsed = function(collapsed)
{
	this.collapsed = collapsed;
};

/**
 * Function: getParent
 *
 * Returns the cell's parent.
 */
mxCell.prototype.getParent = function()
{
	return this.parent;
};

/**
 * Function: setParent
 *
 * Sets the parent cell.
 * 
 * Parameters:
 * 
 * parent - <mxCell> that represents the new parent.
 */
mxCell.prototype.setParent = function(parent)
{
	this.parent = parent;
};

/**
 * Function: getTerminal
 *
 * Returns the source or target terminal.
 * 
 * Parameters:
 * 
 * source - Boolean that specifies if the source terminal should be
 * returned.
 */
mxCell.prototype.getTerminal = function(source)
{
	return (source) ? this.source : this.target;
};

/**
 * Function: setTerminal
 *
 * Sets the source or target terminal and returns the new terminal.
 * 
 * Parameters:
 * 
 * terminal - <mxCell> that represents the new source or target terminal.
 * isSource - Boolean that specifies if the source or target terminal
 * should be set.
 */
mxCell.prototype.setTerminal = function(terminal, isSource)
{
	if (isSource)
	{
		this.source = terminal;
	}
	else
	{
		this.target = terminal;
	}
	
	return terminal;
};

/**
 * Function: getChildCount
 *
 * Returns the number of child cells.
 */
mxCell.prototype.getChildCount = function()
{
	return (this.children == null) ? 0 : this.children.length;
};

/**
 * Function: getIndex
 *
 * Returns the index of the specified child in the child array.
 * 
 * Parameters:
 * 
 * child - Child whose index should be returned.
 */
mxCell.prototype.getIndex = function(child)
{
	return mxUtils.indexOf(this.children, child);
};

/**
 * Function: getChildAt
 *
 * Returns the child at the specified index.
 * 
 * Parameters:
 * 
 * index - Integer that specifies the child to be returned.
 */
mxCell.prototype.getChildAt = function(index)
{
	return (this.children == null) ? null : this.children[index];
};

/**
 * Function: insert
 *
 * Inserts the specified child into the child array at the specified index
 * and updates the parent reference of the child. If not childIndex is
 * specified then the child is appended to the child array. Returns the
 * inserted child.
 * 
 * Parameters:
 * 
 * child - <mxCell> to be inserted or appended to the child array.
 * index - Optional integer that specifies the index at which the child
 * should be inserted into the child array.
 */
mxCell.prototype.insert = function(child, index)
{
	if (child != null)
	{
		if (index == null)
		{
			index = this.getChildCount();
			
			if (child.getParent() == this)
			{
				index--;
			}
		}

		child.removeFromParent();
		child.setParent(this);
		
		if (this.children == null)
		{
			this.children = [];
			this.children.push(child);
		}
		else
		{
			this.children.splice(index, 0, child);
		}
	}
	
	return child;
};

/**
 * Function: remove
 *
 * Removes the child at the specified index from the child array and
 * returns the child that was removed. Will remove the parent reference of
 * the child.
 * 
 * Parameters:
 * 
 * index - Integer that specifies the index of the child to be
 * removed.
 */
mxCell.prototype.remove = function(index)
{
	var child = null;
	
	if (this.children != null && index >= 0)
	{
		child = this.getChildAt(index);
		
		if (child != null)
		{
			this.children.splice(index, 1);
			child.setParent(null);
		}
	}
	
	return child;
};

/**
 * Function: removeFromParent
 *
 * Removes the cell from its parent.
 */
mxCell.prototype.removeFromParent = function()
{
	if (this.parent != null)
	{
		var index = this.parent.getIndex(this);
		this.parent.remove(index);
	}
};

/**
 * Function: getEdgeCount
 *
 * Returns the number of edges in the edge array.
 */
mxCell.prototype.getEdgeCount = function()
{
	return (this.edges == null) ? 0 : this.edges.length;
};

/**
 * Function: getEdgeIndex
 *
 * Returns the index of the specified edge in <edges>.
 * 
 * Parameters:
 * 
 * edge - <mxCell> whose index in <edges> should be returned.
 */
mxCell.prototype.getEdgeIndex = function(edge)
{
	return mxUtils.indexOf(this.edges, edge);
};

/**
 * Function: getEdgeAt
 *
 * Returns the edge at the specified index in <edges>.
 * 
 * Parameters:
 * 
 * index - Integer that specifies the index of the edge to be returned.
 */
mxCell.prototype.getEdgeAt = function(index)
{
	return (this.edges == null) ? null : this.edges[index];
};

/**
 * Function: insertEdge
 *
 * Inserts the specified edge into the edge array and returns the edge.
 * Will update the respective terminal reference of the edge.
 * 
 * Parameters:
 * 
 * edge - <mxCell> to be inserted into the edge array.
 * isOutgoing - Boolean that specifies if the edge is outgoing.
 */
mxCell.prototype.insertEdge = function(edge, isOutgoing)
{
	if (edge != null)
	{
		edge.removeFromTerminal(isOutgoing);
		edge.setTerminal(this, isOutgoing);
		
		if (this.edges == null ||
			edge.getTerminal(!isOutgoing) != this ||
			mxUtils.indexOf(this.edges, edge) < 0)
		{
			if (this.edges == null)
			{
				this.edges = [];
			}
			
			this.edges.push(edge);
		}
	}
	
	return edge;
};

/**
 * Function: removeEdge
 *
 * Removes the specified edge from the edge array and returns the edge.
 * Will remove the respective terminal reference from the edge.
 * 
 * Parameters:
 * 
 * edge - <mxCell> to be removed from the edge array.
 * isOutgoing - Boolean that specifies if the edge is outgoing.
 */
mxCell.prototype.removeEdge = function(edge, isOutgoing)
{
	if (edge != null)
	{
		if (edge.getTerminal(!isOutgoing) != this &&
			this.edges != null)
		{
			var index = this.getEdgeIndex(edge);
			
			if (index >= 0)
			{
				this.edges.splice(index, 1);
			}
		}
		
		edge.setTerminal(null, isOutgoing);
	}
	
	return edge;
};

/**
 * Function: removeFromTerminal
 *
 * Removes the edge from its source or target terminal.
 * 
 * Parameters:
 * 
 * isSource - Boolean that specifies if the edge should be removed from its
 * source or target terminal.
 */
mxCell.prototype.removeFromTerminal = function(isSource)
{
	var terminal = this.getTerminal(isSource);
	
	if (terminal != null)
	{
		terminal.removeEdge(this, isSource);
	}
};

/**
 * Function: hasAttribute
 * 
 * Returns true if the user object is an XML node that contains the given
 * attribute.
 * 
 * Parameters:
 * 
 * name - Name of the attribute.
 */
mxCell.prototype.hasAttribute = function(name)
{
	var userObject = this.getValue();
	
	return (userObject != null &&
		userObject.nodeType == mxConstants.NODETYPE_ELEMENT && userObject.hasAttribute) ?
		userObject.hasAttribute(name) : userObject.getAttribute(name) != null;
};

/**
 * Function: getAttribute
 *
 * Returns the specified attribute from the user object if it is an XML
 * node.
 * 
 * Parameters:
 * 
 * name - Name of the attribute whose value should be returned.
 * defaultValue - Optional default value to use if the attribute has no
 * value.
 */
mxCell.prototype.getAttribute = function(name, defaultValue)
{
	var userObject = this.getValue();
	
	var val = (userObject != null &&
		userObject.nodeType == mxConstants.NODETYPE_ELEMENT) ?
		userObject.getAttribute(name) : null;
		
	return val || defaultValue;
};

/**
 * Function: setAttribute
 *
 * Sets the specified attribute on the user object if it is an XML node.
 * 
 * Parameters:
 * 
 * name - Name of the attribute whose value should be set.
 * value - New value of the attribute.
 */
mxCell.prototype.setAttribute = function(name, value)
{
	var userObject = this.getValue();
	
	if (userObject != null &&
		userObject.nodeType == mxConstants.NODETYPE_ELEMENT)
	{
		userObject.setAttribute(name, value);
	}
};

/**
 * Function: clone
 *
 * Returns a clone of the cell. Uses <cloneValue> to clone
 * the user object. All fields in <mxTransient> are ignored
 * during the cloning.
 */
mxCell.prototype.clone = function()
{
	var clone = mxUtils.clone(this, this.mxTransient);
	clone.setValue(this.cloneValue());
	
	return clone;
};

/**
 * Function: cloneValue
 *
 * Returns a clone of the cell's user object.
 */
mxCell.prototype.cloneValue = function()
{
	var value = this.getValue();
	
	if (value != null)
	{
		if (typeof(value.clone) == 'function')
		{
			value = value.clone();
		}
		else if (!isNaN(value.nodeType))
		{
			value = value.cloneNode(true);
		}
	}
	
	return value;
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxGeometry
 * 
 * Extends <mxRectangle> to represent the geometry of a cell.
 * 
 * For vertices, the geometry consists of the x- and y-location, and the width
 * and height. For edges, the geometry consists of the optional terminal- and
 * control points. The terminal points are only required if an edge is
 * unconnected, and are stored in the sourcePoint> and <targetPoint>
 * variables, respectively.
 * 
 * Example:
 * 
 * If an edge is unconnected, that is, it has no source or target terminal,
 * then a geometry with terminal points for a new edge can be defined as
 * follows.
 * 
 * (code)
 * geometry.setTerminalPoint(new mxPoint(x1, y1), true);
 * geometry.points = [new mxPoint(x2, y2)];
 * geometry.setTerminalPoint(new mxPoint(x3, y3), false);
 * (end)
 * 
 * Control points are used regardless of the connected state of an edge and may
 * be ignored or interpreted differently depending on the edge's <mxEdgeStyle>.
 * 
 * To disable automatic reset of control points after a cell has been moved or
 * resized, the the <mxGraph.resizeEdgesOnMove> and
 * <mxGraph.resetEdgesOnResize> may be used.
 *
 * Edge Labels:
 * 
 * Using the x- and y-coordinates of a cell's geometry, it is possible to
 * position the label on edges on a specific location on the actual edge shape
 * as it appears on the screen. The x-coordinate of an edge's geometry is used
 * to describe the distance from the center of the edge from -1 to 1 with 0
 * being the center of the edge and the default value. The y-coordinate of an
 * edge's geometry is used to describe the absolute, orthogonal distance in
 * pixels from that point. In addition, the <mxGeometry.offset> is used as an
 * absolute offset vector from the resulting point.
 * 
 * This coordinate system is applied if <relative> is true, otherwise the
 * offset defines the absolute vector from the edge's center point to the
 * label and the values for <x> and <y> are ignored.
 * 
 * The width and height parameter for edge geometries can be used to set the
 * label width and height (eg. for word wrapping).
 * 
 * Ports:
 * 
 * The term "port" refers to a relatively positioned, connectable child cell,
 * which is used to specify the connection between the parent and another cell
 * in the graph. Ports are typically modeled as vertices with relative
 * geometries.
 * 
 * Offsets:
 * 
 * The <offset> field is interpreted in 3 different ways, depending on the cell
 * and the geometry. For edges, the offset defines the absolute offset for the
 * edge label. For relative geometries, the offset defines the absolute offset
 * for the origin (top, left corner) of the vertex, otherwise the offset
 * defines the absolute offset for the label inside the vertex or group.
 * 
 * Constructor: mxGeometry
 *
 * Constructs a new object to describe the size and location of a vertex or
 * the control points of an edge.
 */
function mxGeometry(x, y, width, height)
{
	mxRectangle.call(this, x, y, width, height);
};

/**
 * Extends mxRectangle.
 */
mxGeometry.prototype = new mxRectangle();
mxGeometry.prototype.constructor = mxGeometry;

/**
 * Variable: TRANSLATE_CONTROL_POINTS
 * 
 * Global switch to translate the points in translate. Default is true.
 */
mxGeometry.prototype.TRANSLATE_CONTROL_POINTS = true;

/**
 * Variable: alternateBounds
 *
 * Stores alternate values for x, y, width and height in a rectangle. See
 * <swap> to exchange the values. Default is null.
 */
mxGeometry.prototype.alternateBounds = null;

/**
 * Variable: sourcePoint
 *
 * Defines the source <mxPoint> of the edge. This is used if the
 * corresponding edge does not have a source vertex. Otherwise it is
 * ignored. Default is  null.
 */
mxGeometry.prototype.sourcePoint = null;

/**
 * Variable: targetPoint
 *
 * Defines the target <mxPoint> of the edge. This is used if the
 * corresponding edge does not have a target vertex. Otherwise it is
 * ignored. Default is null.
 */
mxGeometry.prototype.targetPoint = null;

/**
 * Variable: points
 *
 * Array of <mxPoints> which specifies the control points along the edge.
 * These points are the intermediate points on the edge, for the endpoints
 * use <targetPoint> and <sourcePoint> or set the terminals of the edge to
 * a non-null value. Default is null.
 */
mxGeometry.prototype.points = null;

/**
 * Variable: offset
 *
 * For edges, this holds the offset (in pixels) from the position defined
 * by <x> and <y> on the edge. For relative geometries (for vertices), this
 * defines the absolute offset from the point defined by the relative
 * coordinates. For absolute geometries (for vertices), this defines the
 * offset for the label. Default is null.
 */
mxGeometry.prototype.offset = null;

/**
 * Variable: relative
 *
 * Specifies if the coordinates in the geometry are to be interpreted as
 * relative coordinates. For edges, this is used to define the location of
 * the edge label relative to the edge as rendered on the display. For
 * vertices, this specifies the relative location inside the bounds of the
 * parent cell.
 * 
 * If this is false, then the coordinates are relative to the origin of the
 * parent cell or, for edges, the edge label position is relative to the
 * center of the edge as rendered on screen.
 * 
 * Default is false.
 */
mxGeometry.prototype.relative = false;

/**
 * Function: swap
 * 
 * Swaps the x, y, width and height with the values stored in
 * <alternateBounds> and puts the previous values into <alternateBounds> as
 * a rectangle. This operation is carried-out in-place, that is, using the
 * existing geometry instance. If this operation is called during a graph
 * model transactional change, then the geometry should be cloned before
 * calling this method and setting the geometry of the cell using
 * <mxGraphModel.setGeometry>.
 */
mxGeometry.prototype.swap = function()
{
	if (this.alternateBounds != null)
	{
		var old = new mxRectangle(
			this.x, this.y, this.width, this.height);

		this.x = this.alternateBounds.x;
		this.y = this.alternateBounds.y;
		this.width = this.alternateBounds.width;
		this.height = this.alternateBounds.height;

		this.alternateBounds = old;
	}
};

/**
 * Function: getTerminalPoint
 * 
 * Returns the <mxPoint> representing the source or target point of this
 * edge. This is only used if the edge has no source or target vertex.
 * 
 * Parameters:
 * 
 * isSource - Boolean that specifies if the source or target point
 * should be returned.
 */
mxGeometry.prototype.getTerminalPoint = function(isSource)
{
	return (isSource) ? this.sourcePoint : this.targetPoint;
};

/**
 * Function: setTerminalPoint
 * 
 * Sets the <sourcePoint> or <targetPoint> to the given <mxPoint> and
 * returns the new point.
 * 
 * Parameters:
 * 
 * point - Point to be used as the new source or target point.
 * isSource - Boolean that specifies if the source or target point
 * should be set.
 */
mxGeometry.prototype.setTerminalPoint = function(point, isSource)
{
	if (isSource)
	{
		this.sourcePoint = point;
	}
	else
	{
		this.targetPoint = point;
	}
	
	return point;
};

/**
 * Function: rotate
 * 
 * Rotates the geometry by the given angle around the given center. That is,
 * <x> and <y> of the geometry, the <sourcePoint>, <targetPoint> and all
 * <points> are translated by the given amount. <x> and <y> are only
 * translated if <relative> is false.
 * 
 * Parameters:
 * 
 * angle - Number that specifies the rotation angle in degrees.
 * cx - <mxPoint> that specifies the center of the rotation.
 */
mxGeometry.prototype.rotate = function(angle, cx)
{
	var rad = mxUtils.toRadians(angle);
	var cos = Math.cos(rad);
	var sin = Math.sin(rad);
	
	// Rotates the geometry
	if (!this.relative)
	{
		var ct = new mxPoint(this.getCenterX(), this.getCenterY());
		var pt = mxUtils.getRotatedPoint(ct, cos, sin, cx);
		
		this.x = Math.round(pt.x - this.width / 2);
		this.y = Math.round(pt.y - this.height / 2);
	}

	// Rotates the source point
	if (this.sourcePoint != null)
	{
		var pt = mxUtils.getRotatedPoint(this.sourcePoint, cos, sin, cx);
		this.sourcePoint.x = Math.round(pt.x);
		this.sourcePoint.y = Math.round(pt.y);
	}
	
	// Translates the target point
	if (this.targetPoint != null)
	{
		var pt = mxUtils.getRotatedPoint(this.targetPoint, cos, sin, cx);
		this.targetPoint.x = Math.round(pt.x);
		this.targetPoint.y = Math.round(pt.y);	
	}
	
	// Translate the control points
	if (this.points != null)
	{
		for (var i = 0; i < this.points.length; i++)
		{
			if (this.points[i] != null)
			{
				var pt = mxUtils.getRotatedPoint(this.points[i], cos, sin, cx);
				this.points[i].x = Math.round(pt.x);
				this.points[i].y = Math.round(pt.y);
			}
		}
	}
};

/**
 * Function: translate
 * 
 * Translates the geometry by the specified amount. That is, <x> and <y> of the
 * geometry, the <sourcePoint>, <targetPoint> and all <points> are translated
 * by the given amount. <x> and <y> are only translated if <relative> is false.
 * If <TRANSLATE_CONTROL_POINTS> is false, then <points> are not modified by
 * this function.
 * 
 * Parameters:
 * 
 * dx - Number that specifies the x-coordinate of the translation.
 * dy - Number that specifies the y-coordinate of the translation.
 */
mxGeometry.prototype.translate = function(dx, dy)
{
	dx = parseFloat(dx);
	dy = parseFloat(dy);
	
	// Translates the geometry
	if (!this.relative)
	{
		this.x = parseFloat(this.x) + dx;
		this.y = parseFloat(this.y) + dy;
	}

	// Translates the source point
	if (this.sourcePoint != null)
	{
		this.sourcePoint.x = parseFloat(this.sourcePoint.x) + dx;
		this.sourcePoint.y = parseFloat(this.sourcePoint.y) + dy;
	}
	
	// Translates the target point
	if (this.targetPoint != null)
	{
		this.targetPoint.x = parseFloat(this.targetPoint.x) + dx;
		this.targetPoint.y = parseFloat(this.targetPoint.y) + dy;		
	}

	// Translate the control points
	if (this.TRANSLATE_CONTROL_POINTS && this.points != null)
	{
		for (var i = 0; i < this.points.length; i++)
		{
			if (this.points[i] != null)
			{
				this.points[i].x = parseFloat(this.points[i].x) + dx;
				this.points[i].y = parseFloat(this.points[i].y) + dy;
			}
		}
	}
};

/**
 * Function: scale
 * 
 * Scales the geometry by the given amount. That is, <x> and <y> of the
 * geometry, the <sourcePoint>, <targetPoint> and all <points> are scaled
 * by the given amount. <x>, <y>, <width> and <height> are only scaled if
 * <relative> is false. If <fixedAspect> is true, then the smaller value
 * is used to scale the width and the height.
 * 
 * Parameters:
 * 
 * sx - Number that specifies the horizontal scale factor.
 * sy - Number that specifies the vertical scale factor.
 * fixedAspect - Optional boolean to keep the aspect ratio fixed.
 */
mxGeometry.prototype.scale = function(sx, sy, fixedAspect)
{
	sx = parseFloat(sx);
	sy = parseFloat(sy);

	// Translates the source point
	if (this.sourcePoint != null)
	{
		this.sourcePoint.x = parseFloat(this.sourcePoint.x) * sx;
		this.sourcePoint.y = parseFloat(this.sourcePoint.y) * sy;
	}
	
	// Translates the target point
	if (this.targetPoint != null)
	{
		this.targetPoint.x = parseFloat(this.targetPoint.x) * sx;
		this.targetPoint.y = parseFloat(this.targetPoint.y) * sy;		
	}

	// Translate the control points
	if (this.points != null)
	{
		for (var i = 0; i < this.points.length; i++)
		{
			if (this.points[i] != null)
			{
				this.points[i].x = parseFloat(this.points[i].x) * sx;
				this.points[i].y = parseFloat(this.points[i].y) * sy;
			}
		}
	}
	
	// Translates the geometry
	if (!this.relative)
	{
		this.x = parseFloat(this.x) * sx;
		this.y = parseFloat(this.y) * sy;

		if (fixedAspect)
		{
			sy = sx = Math.min(sx, sy);
		}
		
		this.width = parseFloat(this.width) * sx;
		this.height = parseFloat(this.height) * sy;
	}
};

/**
 * Function: equals
 * 
 * Returns true if the given object equals this geometry.
 */
mxGeometry.prototype.equals = function(obj)
{
	return mxRectangle.prototype.equals.apply(this, arguments) &&
		this.relative == obj.relative &&
		((this.sourcePoint == null && obj.sourcePoint == null) || (this.sourcePoint != null && this.sourcePoint.equals(obj.sourcePoint))) &&
		((this.targetPoint == null && obj.targetPoint == null) || (this.targetPoint != null && this.targetPoint.equals(obj.targetPoint))) &&
		((this.points == null && obj.points == null) || (this.points != null && mxUtils.equalPoints(this.points, obj.points))) &&
		((this.alternateBounds == null && obj.alternateBounds == null) || (this.alternateBounds != null && this.alternateBounds.equals(obj.alternateBounds))) &&
		((this.offset == null && obj.offset == null) || (this.offset != null && this.offset.equals(obj.offset)));
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
var mxCellPath =
{

	/**
	 * Class: mxCellPath
	 * 
	 * Implements a mechanism for temporary cell Ids.
	 * 
	 * Variable: PATH_SEPARATOR
	 * 
	 * Defines the separator between the path components. Default is ".".
	 */
	PATH_SEPARATOR: '.',
	
	/**
	 * Function: create
	 * 
	 * Creates the cell path for the given cell. The cell path is a
	 * concatenation of the indices of all ancestors on the (finite) path to
	 * the root, eg. "0.0.0.1".
	 * 
	 * Parameters:
	 * 
	 * cell - Cell whose path should be returned.
	 */
	create: function(cell)
	{
		var result = '';
		
		if (cell != null)
		{
			var parent = cell.getParent();
			
			while (parent != null)
			{
				var index = parent.getIndex(cell);
				result = index + mxCellPath.PATH_SEPARATOR + result;
				
				cell = parent;
				parent = cell.getParent();
			}
		}
		
		// Removes trailing separator
		var n = result.length;
		
		if (n > 1)
		{
			result = result.substring(0, n - 1);
		}
		
		return result;
	},
	
	/**
	 * Function: getParentPath
	 * 
	 * Returns the path for the parent of the cell represented by the given
	 * path. Returns null if the given path has no parent.
	 * 
	 * Parameters:
	 * 
	 * path - Path whose parent path should be returned.
	 */
	getParentPath: function(path)
	{
		if (path != null)
		{
			var index = path.lastIndexOf(mxCellPath.PATH_SEPARATOR);

			if (index >= 0)
			{
				return path.substring(0, index);
			}
			else if (path.length > 0)
			{
				return '';
			}
		}

		return null;
	},

	/**
	 * Function: resolve
	 * 
	 * Returns the cell for the specified cell path using the given root as the
	 * root of the path.
	 * 
	 * Parameters:
	 * 
	 * root - Root cell of the path to be resolved.
	 * path - String that defines the path.
	 */
	resolve: function(root, path)
	{
		var parent = root;
		
		if (path != null)
		{
			var tokens = path.split(mxCellPath.PATH_SEPARATOR);
			
			for (var i=0; i<tokens.length; i++)
			{
				parent = parent.getChildAt(parseInt(tokens[i]));
			}
		}
		
		return parent;
	},
	
	/**
	 * Function: compare
	 * 
	 * Compares the given cell paths and returns -1 if p1 is smaller, 0 if
	 * p1 is equal and 1 if p1 is greater than p2.
	 */
	compare: function(p1, p2)
	{
		var min = Math.min(p1.length, p2.length);
		var comp = 0;
		
		for (var i = 0; i < min; i++)
		{
			if (p1[i] != p2[i])
			{
				if (p1[i].length == 0 ||
					p2[i].length == 0)
				{
					comp = (p1[i] == p2[i]) ? 0 : ((p1[i] > p2[i]) ? 1 : -1);
				}
				else
				{
					var t1 = parseInt(p1[i]);
					var t2 = parseInt(p2[i]);
					
					comp = (t1 == t2) ? 0 : ((t1 > t2) ? 1 : -1);
				}
				
				break;
			}
		}
		
		// Compares path length if both paths are equal to this point
		if (comp == 0)
		{
			var t1 = p1.length;
			var t2 = p2.length;
			
			if (t1 != t2)
			{
				comp = (t1 > t2) ? 1 : -1;
			}
		}
		
		return comp;
	}

};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
var mxPerimeter =
{
	/**
	 * Class: mxPerimeter
	 * 
	 * Provides various perimeter functions to be used in a style
	 * as the value of <mxConstants.STYLE_PERIMETER>. Perimeters for
	 * rectangle, circle, rhombus and triangle are available.
	 *
	 * Example:
	 * 
	 * (code)
	 * <add as="perimeter">mxPerimeter.RectanglePerimeter</add>
	 * (end)
	 * 
	 * Or programmatically:
	 * 
	 * (code)
	 * style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter;
	 * (end)
	 * 
	 * When adding new perimeter functions, it is recommended to use the 
	 * mxPerimeter-namespace as follows:
	 * 
	 * (code)
	 * mxPerimeter.CustomPerimeter = function (bounds, vertex, next, orthogonal)
	 * {
	 *   var x = 0; // Calculate x-coordinate
	 *   var y = 0; // Calculate y-coordainte
	 *   
	 *   return new mxPoint(x, y);
	 * }
	 * (end)
	 * 
	 * The new perimeter should then be registered in the <mxStyleRegistry> as follows:
	 * (code)
	 * mxStyleRegistry.putValue('customPerimeter', mxPerimeter.CustomPerimeter);
	 * (end)
	 * 
	 * The custom perimeter above can now be used in a specific vertex as follows:
	 * 
	 * (code)
	 * model.setStyle(vertex, 'perimeter=customPerimeter');
	 * (end)
	 * 
	 * Note that the key of the <mxStyleRegistry> entry for the function should
	 * be used in string values, unless <mxGraphView.allowEval> is true, in
	 * which case you can also use mxPerimeter.CustomPerimeter for the value in
	 * the cell style above.
	 * 
	 * Or it can be used for all vertices in the graph as follows:
	 * 
	 * (code)
	 * var style = graph.getStylesheet().getDefaultVertexStyle();
	 * style[mxConstants.STYLE_PERIMETER] = mxPerimeter.CustomPerimeter;
	 * (end)
	 * 
	 * Note that the object can be used directly when programmatically setting
	 * the value, but the key in the <mxStyleRegistry> should be used when
	 * setting the value via a key, value pair in a cell style.
	 * 
	 * The parameters are explained in <RectanglePerimeter>.
	 * 
	 * Function: RectanglePerimeter
	 * 
	 * Describes a rectangular perimeter for the given bounds.
	 *
	 * Parameters:
	 * 
	 * bounds - <mxRectangle> that represents the absolute bounds of the
	 * vertex.
	 * vertex - <mxCellState> that represents the vertex.
	 * next - <mxPoint> that represents the nearest neighbour point on the
	 * given edge.
	 * orthogonal - Boolean that specifies if the orthogonal projection onto
	 * the perimeter should be returned. If this is false then the intersection
	 * of the perimeter and the line between the next and the center point is
	 * returned.
	 */
	RectanglePerimeter: function (bounds, vertex, next, orthogonal)
	{
		var cx = bounds.getCenterX();
		var cy = bounds.getCenterY();
		var dx = next.x - cx;
		var dy = next.y - cy;
		var alpha = Math.atan2(dy, dx);
		var p = new mxPoint(0, 0);
		var pi = Math.PI;
		var pi2 = Math.PI/2;
		var beta = pi2 - alpha;
		var t = Math.atan2(bounds.height, bounds.width);
		
		if (alpha < -pi + t || alpha > pi - t)
		{
			// Left edge
			p.x = bounds.x;
			p.y = cy - bounds.width * Math.tan(alpha) / 2;
		}
		else if (alpha < -t)
		{
			// Top Edge
			p.y = bounds.y;
			p.x = cx - bounds.height * Math.tan(beta) / 2;
		}
		else if (alpha < t)
		{
			// Right Edge
			p.x = bounds.x + bounds.width;
			p.y = cy + bounds.width * Math.tan(alpha) / 2;
		}
		else
		{
			// Bottom Edge
			p.y = bounds.y + bounds.height;
			p.x = cx + bounds.height * Math.tan(beta) / 2;
		}
		
		if (orthogonal)
		{
			if (next.x >= bounds.x &&
				next.x <= bounds.x + bounds.width)
			{
				p.x = next.x;
			}
			else if (next.y >= bounds.y &&
					   next.y <= bounds.y + bounds.height)
			{
				p.y = next.y;
			}
			if (next.x < bounds.x)
			{
				p.x = bounds.x;
			}
			else if (next.x > bounds.x + bounds.width)
			{
				p.x = bounds.x + bounds.width;
			}
			if (next.y < bounds.y)
			{
				p.y = bounds.y;
			}
			else if (next.y > bounds.y + bounds.height)
			{
				p.y = bounds.y + bounds.height;
			}
		}
		
		return p;
	},

	/**
	 * Function: EllipsePerimeter
	 * 
	 * Describes an elliptic perimeter. See <RectanglePerimeter>
	 * for a description of the parameters.
	 */
	EllipsePerimeter: function (bounds, vertex, next, orthogonal)
	{
		var x = bounds.x;
		var y = bounds.y;
		var a = bounds.width / 2;
		var b = bounds.height / 2;
		var cx = x + a;
		var cy = y + b;
		var px = next.x;
		var py = next.y;
		
		// Calculates straight line equation through
		// point and ellipse center y = d * x + h
		var dx = parseInt(px - cx);
		var dy = parseInt(py - cy);
		
		if (dx == 0 && dy != 0)
		{
			return new mxPoint(cx, cy + b * dy / Math.abs(dy));
		}
		else if (dx == 0 && dy == 0)
		{
			return new mxPoint(px, py);
		}

		if (orthogonal)
		{
			if (py >= y && py <= y + bounds.height)
			{
				var ty = py - cy;
				var tx = Math.sqrt(a*a*(1-(ty*ty)/(b*b))) || 0;
				
				if (px <= x)
				{
					tx = -tx;
				}
				
				return new mxPoint(cx+tx, py);
			}
			
			if (px >= x && px <= x + bounds.width)
			{
				var tx = px - cx;
				var ty = Math.sqrt(b*b*(1-(tx*tx)/(a*a))) || 0;
				
				if (py <= y)
				{
					ty = -ty;	
				}
				
				return new mxPoint(px, cy+ty);
			}
		}
		
		// Calculates intersection
		var d = dy / dx;
		var h = cy - d * cx;
		var e = a * a * d * d + b * b;
		var f = -2 * cx * e;
		var g = a * a * d * d * cx * cx +
				b * b * cx * cx -
				a * a * b * b;
		var det = Math.sqrt(f * f - 4 * e * g);
		
		// Two solutions (perimeter points)
		var xout1 = (-f + det) / (2 * e);
		var xout2 = (-f - det) / (2 * e);
		var yout1 = d * xout1 + h;
		var yout2 = d * xout2 + h;
		var dist1 = Math.sqrt(Math.pow((xout1 - px), 2)
					+ Math.pow((yout1 - py), 2));
		var dist2 = Math.sqrt(Math.pow((xout2 - px), 2)
					+ Math.pow((yout2 - py), 2));
					
		// Correct solution
		var xout = 0;
		var yout = 0;
		
		if (dist1 < dist2)
		{
			xout = xout1;
			yout = yout1;
		}
		else
		{
			xout = xout2;
			yout = yout2;
		}
		
		return new mxPoint(xout, yout);
	},

	/**
	 * Function: RhombusPerimeter
	 * 
	 * Describes a rhombus (aka diamond) perimeter. See <RectanglePerimeter>
	 * for a description of the parameters.
	 */
	RhombusPerimeter: function (bounds, vertex, next, orthogonal)
	{
		var x = bounds.x;
		var y = bounds.y;
		var w = bounds.width;
		var h = bounds.height;
		
		var cx = x + w / 2;
		var cy = y + h / 2;

		var px = next.x;
		var py = next.y;

		// Special case for intersecting the diamond's corners
		if (cx == px)
		{
			if (cy > py)
			{
				return new mxPoint(cx, y); // top
			}
			else
			{
				return new mxPoint(cx, y + h); // bottom
			}
		}
		else if (cy == py)
		{
			if (cx > px)
			{
				return new mxPoint(x, cy); // left
			}
			else
			{
				return new mxPoint(x + w, cy); // right
			}
		}
		
		var tx = cx;
		var ty = cy;
		
		if (orthogonal)
		{
			if (px >= x && px <= x + w)
			{
				tx = px;
			}
			else if (py >= y && py <= y + h)
			{
				ty = py;
			}
		}
		
		// In which quadrant will the intersection be?
		// set the slope and offset of the border line accordingly
		if (px < cx)
		{
			if (py < cy)
			{
				return mxUtils.intersection(px, py, tx, ty, cx, y, x, cy);
			}
			else
			{
				return mxUtils.intersection(px, py, tx, ty, cx, y + h, x, cy);
			}
		}
		else if (py < cy)
		{
			return mxUtils.intersection(px, py, tx, ty, cx, y, x + w, cy);
		}
		else
		{
			return mxUtils.intersection(px, py, tx, ty, cx, y + h, x + w, cy);
		}
	},
	
	/**
	 * Function: TrianglePerimeter
	 * 
	 * Describes a triangle perimeter. See <RectanglePerimeter>
	 * for a description of the parameters.
	 */
	TrianglePerimeter: function (bounds, vertex, next, orthogonal)
	{
		var direction = (vertex != null) ?
			vertex.style[mxConstants.STYLE_DIRECTION] : null;
		var vertical = direction == mxConstants.DIRECTION_NORTH ||
			direction == mxConstants.DIRECTION_SOUTH;

		var x = bounds.x;
		var y = bounds.y;
		var w = bounds.width;
		var h = bounds.height;
		
		var cx = x + w / 2;
		var cy = y + h / 2;
		
		var start = new mxPoint(x, y);
		var corner = new mxPoint(x + w, cy);
		var end = new mxPoint(x, y + h);
		
		if (direction == mxConstants.DIRECTION_NORTH)
		{
			start = end;
			corner = new mxPoint(cx, y);
			end = new mxPoint(x + w, y + h);
		}
		else if (direction == mxConstants.DIRECTION_SOUTH)
		{
			corner = new mxPoint(cx, y + h);
			end = new mxPoint(x + w, y);
		}
		else if (direction == mxConstants.DIRECTION_WEST)
		{
			start = new mxPoint(x + w, y);
			corner = new mxPoint(x, cy);
			end = new mxPoint(x + w, y + h);
		}

		var dx = next.x - cx;
		var dy = next.y - cy;

		var alpha = (vertical) ? Math.atan2(dx, dy) : Math.atan2(dy, dx);
		var t = (vertical) ? Math.atan2(w, h) : Math.atan2(h, w);
		
		var base = false;
		
		if (direction == mxConstants.DIRECTION_NORTH ||
			direction == mxConstants.DIRECTION_WEST)
		{
			base = alpha > -t && alpha < t;
		}
		else
		{
			base = alpha < -Math.PI + t || alpha > Math.PI - t;	
		}

		var result = null;			

		if (base)
		{
			if (orthogonal && ((vertical && next.x >= start.x && next.x <= end.x) ||
				(!vertical && next.y >= start.y && next.y <= end.y)))
			{
				if (vertical)
				{
					result = new mxPoint(next.x, start.y);
				}
				else
				{
					result = new mxPoint(start.x, next.y);
				}
			}
			else
			{
				if (direction == mxConstants.DIRECTION_NORTH)
				{
					result = new mxPoint(x + w / 2 + h * Math.tan(alpha) / 2,
						y + h);
				}
				else if (direction == mxConstants.DIRECTION_SOUTH)
				{
					result = new mxPoint(x + w / 2 - h * Math.tan(alpha) / 2,
						y);
				}
				else if (direction == mxConstants.DIRECTION_WEST)
				{
					result = new mxPoint(x + w, y + h / 2 +
						w * Math.tan(alpha) / 2);
				}
				else
				{
					result = new mxPoint(x, y + h / 2 -
						w * Math.tan(alpha) / 2);
				}
			}
		}
		else
		{
			if (orthogonal)
			{
				var pt = new mxPoint(cx, cy);
		
				if (next.y >= y && next.y <= y + h)
				{
					pt.x = (vertical) ? cx : (
						(direction == mxConstants.DIRECTION_WEST) ?
							x + w : x);
					pt.y = next.y;
				}
				else if (next.x >= x && next.x <= x + w)
				{
					pt.x = next.x;
					pt.y = (!vertical) ? cy : (
						(direction == mxConstants.DIRECTION_NORTH) ?
							y + h : y);
				}
				
				// Compute angle
				dx = next.x - pt.x;
				dy = next.y - pt.y;
				
				cx = pt.x;
				cy = pt.y;
			}

			if ((vertical && next.x <= x + w / 2) ||
				(!vertical && next.y <= y + h / 2))
			{
				result = mxUtils.intersection(next.x, next.y, cx, cy,
					start.x, start.y, corner.x, corner.y);
			}
			else
			{
				result = mxUtils.intersection(next.x, next.y, cx, cy,
					corner.x, corner.y, end.x, end.y);
			}
		}
		
		if (result == null)
		{
			result = new mxPoint(cx, cy);
		}
		
		return result;
	},
	
	/**
	 * Function: HexagonPerimeter
	 * 
	 * Describes a hexagon perimeter. See <RectanglePerimeter>
	 * for a description of the parameters.
	 */
	HexagonPerimeter: function (bounds, vertex, next, orthogonal)
	{
		var x = bounds.x;
		var y = bounds.y;
		var w = bounds.width;
		var h = bounds.height;

		var cx = bounds.getCenterX();
		var cy = bounds.getCenterY();
		var px = next.x;
		var py = next.y;
		var dx = px - cx;
		var dy = py - cy;
		var alpha = -Math.atan2(dy, dx);
		var pi = Math.PI;
		var pi2 = Math.PI / 2;

		var result = new mxPoint(cx, cy);

		var direction = (vertex != null) ? mxUtils.getValue(
				vertex.style, mxConstants.STYLE_DIRECTION,
				mxConstants.DIRECTION_EAST) : mxConstants.DIRECTION_EAST;
		var vertical = direction == mxConstants.DIRECTION_NORTH
				|| direction == mxConstants.DIRECTION_SOUTH;
		var a = new mxPoint();
		var b = new mxPoint();

		//Only consider corrects quadrants for the orthogonal case.
		if ((px < x) && (py < y) || (px < x) && (py > y + h)
				|| (px > x + w) && (py < y) || (px > x + w) && (py > y + h))
		{
			orthogonal = false;
		}

		if (orthogonal)
		{
			if (vertical)
			{
				//Special cases where intersects with hexagon corners
				if (px == cx)
				{
					if (py <= y)
					{
						return new mxPoint(cx, y);
					}
					else if (py >= y + h)
					{
						return new mxPoint(cx, y + h);
					}
				}
				else if (px < x)
				{
					if (py == y + h / 4)
					{
						return new mxPoint(x, y + h / 4);
					}
					else if (py == y + 3 * h / 4)
					{
						return new mxPoint(x, y + 3 * h / 4);
					}
				}
				else if (px > x + w)
				{
					if (py == y + h / 4)
					{
						return new mxPoint(x + w, y + h / 4);
					}
					else if (py == y + 3 * h / 4)
					{
						return new mxPoint(x + w, y + 3 * h / 4);
					}
				}
				else if (px == x)
				{
					if (py < cy)
					{
						return new mxPoint(x, y + h / 4);
					}
					else if (py > cy)
					{
						return new mxPoint(x, y + 3 * h / 4);
					}
				}
				else if (px == x + w)
				{
					if (py < cy)
					{
						return new mxPoint(x + w, y + h / 4);
					}
					else if (py > cy)
					{
						return new mxPoint(x + w, y + 3 * h / 4);
					}
				}
				if (py == y)
				{
					return new mxPoint(cx, y);
				}
				else if (py == y + h)
				{
					return new mxPoint(cx, y + h);
				}

				if (px < cx)
				{
					if ((py > y + h / 4) && (py < y + 3 * h / 4))
					{
						a = new mxPoint(x, y);
						b = new mxPoint(x, y + h);
					}
					else if (py < y + h / 4)
					{
						a = new mxPoint(x - Math.floor(0.5 * w), y
								+ Math.floor(0.5 * h));
						b = new mxPoint(x + w, y - Math.floor(0.25 * h));
					}
					else if (py > y + 3 * h / 4)
					{
						a = new mxPoint(x - Math.floor(0.5 * w), y
								+ Math.floor(0.5 * h));
						b = new mxPoint(x + w, y + Math.floor(1.25 * h));
					}
				}
				else if (px > cx)
				{
					if ((py > y + h / 4) && (py < y + 3 * h / 4))
					{
						a = new mxPoint(x + w, y);
						b = new mxPoint(x + w, y + h);
					}
					else if (py < y + h / 4)
					{
						a = new mxPoint(x, y - Math.floor(0.25 * h));
						b = new mxPoint(x + Math.floor(1.5 * w), y
								+ Math.floor(0.5 * h));
					}
					else if (py > y + 3 * h / 4)
					{
						a = new mxPoint(x + Math.floor(1.5 * w), y
								+ Math.floor(0.5 * h));
						b = new mxPoint(x, y + Math.floor(1.25 * h));
					}
				}

			}
			else
			{
				//Special cases where intersects with hexagon corners
				if (py == cy)
				{
					if (px <= x)
					{
						return new mxPoint(x, y + h / 2);
					}
					else if (px >= x + w)
					{
						return new mxPoint(x + w, y + h / 2);
					}
				}
				else if (py < y)
				{
					if (px == x + w / 4)
					{
						return new mxPoint(x + w / 4, y);
					}
					else if (px == x + 3 * w / 4)
					{
						return new mxPoint(x + 3 * w / 4, y);
					}
				}
				else if (py > y + h)
				{
					if (px == x + w / 4)
					{
						return new mxPoint(x + w / 4, y + h);
					}
					else if (px == x + 3 * w / 4)
					{
						return new mxPoint(x + 3 * w / 4, y + h);
					}
				}
				else if (py == y)
				{
					if (px < cx)
					{
						return new mxPoint(x + w / 4, y);
					}
					else if (px > cx)
					{
						return new mxPoint(x + 3 * w / 4, y);
					}
				}
				else if (py == y + h)
				{
					if (px < cx)
					{
						return new mxPoint(x + w / 4, y + h);
					}
					else if (py > cy)
					{
						return new mxPoint(x + 3 * w / 4, y + h);
					}
				}
				if (px == x)
				{
					return new mxPoint(x, cy);
				}
				else if (px == x + w)
				{
					return new mxPoint(x + w, cy);
				}

				if (py < cy)
				{
					if ((px > x + w / 4) && (px < x + 3 * w / 4))
					{
						a = new mxPoint(x, y);
						b = new mxPoint(x + w, y);
					}
					else if (px < x + w / 4)
					{
						a = new mxPoint(x - Math.floor(0.25 * w), y + h);
						b = new mxPoint(x + Math.floor(0.5 * w), y
								- Math.floor(0.5 * h));
					}
					else if (px > x + 3 * w / 4)
					{
						a = new mxPoint(x + Math.floor(0.5 * w), y
								- Math.floor(0.5 * h));
						b = new mxPoint(x + Math.floor(1.25 * w), y + h);
					}
				}
				else if (py > cy)
				{
					if ((px > x + w / 4) && (px < x + 3 * w / 4))
					{
						a = new mxPoint(x, y + h);
						b = new mxPoint(x + w, y + h);
					}
					else if (px < x + w / 4)
					{
						a = new mxPoint(x - Math.floor(0.25 * w), y);
						b = new mxPoint(x + Math.floor(0.5 * w), y
								+ Math.floor(1.5 * h));
					}
					else if (px > x + 3 * w / 4)
					{
						a = new mxPoint(x + Math.floor(0.5 * w), y
								+ Math.floor(1.5 * h));
						b = new mxPoint(x + Math.floor(1.25 * w), y);
					}
				}
			}

			var tx = cx;
			var ty = cy;

			if (px >= x && px <= x + w)
			{
				tx = px;
				
				if (py < cy)
				{
					ty = y + h;
				}
				else
				{
					ty = y;
				}
			}
			else if (py >= y && py <= y + h)
			{
				ty = py;
				
				if (px < cx)
				{
					tx = x + w;
				}
				else
				{
					tx = x;
				}
			}

			result = mxUtils.intersection(tx, ty, next.x, next.y, a.x, a.y, b.x, b.y);
		}
		else
		{
			if (vertical)
			{
				var beta = Math.atan2(h / 4, w / 2);

				//Special cases where intersects with hexagon corners
				if (alpha == beta)
				{
					return new mxPoint(x + w, y + Math.floor(0.25 * h));
				}
				else if (alpha == pi2)
				{
					return new mxPoint(x + Math.floor(0.5 * w), y);
				}
				else if (alpha == (pi - beta))
				{
					return new mxPoint(x, y + Math.floor(0.25 * h));
				}
				else if (alpha == -beta)
				{
					return new mxPoint(x + w, y + Math.floor(0.75 * h));
				}
				else if (alpha == (-pi2))
				{
					return new mxPoint(x + Math.floor(0.5 * w), y + h);
				}
				else if (alpha == (-pi + beta))
				{
					return new mxPoint(x, y + Math.floor(0.75 * h));
				}

				if ((alpha < beta) && (alpha > -beta))
				{
					a = new mxPoint(x + w, y);
					b = new mxPoint(x + w, y + h);
				}
				else if ((alpha > beta) && (alpha < pi2))
				{
					a = new mxPoint(x, y - Math.floor(0.25 * h));
					b = new mxPoint(x + Math.floor(1.5 * w), y
							+ Math.floor(0.5 * h));
				}
				else if ((alpha > pi2) && (alpha < (pi - beta)))
				{
					a = new mxPoint(x - Math.floor(0.5 * w), y
							+ Math.floor(0.5 * h));
					b = new mxPoint(x + w, y - Math.floor(0.25 * h));
				}
				else if (((alpha > (pi - beta)) && (alpha <= pi))
						|| ((alpha < (-pi + beta)) && (alpha >= -pi)))
				{
					a = new mxPoint(x, y);
					b = new mxPoint(x, y + h);
				}
				else if ((alpha < -beta) && (alpha > -pi2))
				{
					a = new mxPoint(x + Math.floor(1.5 * w), y
							+ Math.floor(0.5 * h));
					b = new mxPoint(x, y + Math.floor(1.25 * h));
				}
				else if ((alpha < -pi2) && (alpha > (-pi + beta)))
				{
					a = new mxPoint(x - Math.floor(0.5 * w), y
							+ Math.floor(0.5 * h));
					b = new mxPoint(x + w, y + Math.floor(1.25 * h));
				}
			}
			else
			{
				var beta = Math.atan2(h / 2, w / 4);

				//Special cases where intersects with hexagon corners
				if (alpha == beta)
				{
					return new mxPoint(x + Math.floor(0.75 * w), y);
				}
				else if (alpha == (pi - beta))
				{
					return new mxPoint(x + Math.floor(0.25 * w), y);
				}
				else if ((alpha == pi) || (alpha == -pi))
				{
					return new mxPoint(x, y + Math.floor(0.5 * h));
				}
				else if (alpha == 0)
				{
					return new mxPoint(x + w, y + Math.floor(0.5 * h));
				}
				else if (alpha == -beta)
				{
					return new mxPoint(x + Math.floor(0.75 * w), y + h);
				}
				else if (alpha == (-pi + beta))
				{
					return new mxPoint(x + Math.floor(0.25 * w), y + h);
				}

				if ((alpha > 0) && (alpha < beta))
				{
					a = new mxPoint(x + Math.floor(0.5 * w), y
							- Math.floor(0.5 * h));
					b = new mxPoint(x + Math.floor(1.25 * w), y + h);
				}
				else if ((alpha > beta) && (alpha < (pi - beta)))
				{
					a = new mxPoint(x, y);
					b = new mxPoint(x + w, y);
				}
				else if ((alpha > (pi - beta)) && (alpha < pi))
				{
					a = new mxPoint(x - Math.floor(0.25 * w), y + h);
					b = new mxPoint(x + Math.floor(0.5 * w), y
							- Math.floor(0.5 * h));
				}
				else if ((alpha < 0) && (alpha > -beta))
				{
					a = new mxPoint(x + Math.floor(0.5 * w), y
							+ Math.floor(1.5 * h));
					b = new mxPoint(x + Math.floor(1.25 * w), y);
				}
				else if ((alpha < -beta) && (alpha > (-pi + beta)))
				{
					a = new mxPoint(x, y + h);
					b = new mxPoint(x + w, y + h);
				}
				else if ((alpha < (-pi + beta)) && (alpha > -pi))
				{
					a = new mxPoint(x - Math.floor(0.25 * w), y);
					b = new mxPoint(x + Math.floor(0.5 * w), y
							+ Math.floor(1.5 * h));
				}
			}

			result = mxUtils.intersection(cx, cy, next.x, next.y, a.x, a.y, b.x, b.y);
		}
		
		if (result == null)
		{
			return new mxPoint(cx, cy);
		}
		
		return result;
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxPrintPreview
 * 
 * Implements printing of a diagram across multiple pages. The following opens
 * a print preview for an existing graph:
 * 
 * (code)
 * var preview = new mxPrintPreview(graph);
 * preview.open();
 * (end)
 * 
 * Use <mxUtils.getScaleForPageCount> as follows in order to print the graph
 * across a given number of pages:
 * 
 * (code)
 * var pageCount = mxUtils.prompt('Enter page count', '1');
 * 
 * if (pageCount != null)
 * {
 *   var scale = mxUtils.getScaleForPageCount(pageCount, graph);
 *   var preview = new mxPrintPreview(graph, scale);
 *   preview.open();
 * }
 * (end)
 * 
 * Additional pages:
 * 
 * To add additional pages before and after the output, <getCoverPages> and
 * <getAppendices> can be used, respectively.
 * 
 * (code)
 * var preview = new mxPrintPreview(graph, 1);
 * 
 * preview.getCoverPages = function(w, h)
 * {
 *   return [this.renderPage(w, h, 0, 0, mxUtils.bind(this, function(div)
 *   {
 *     div.innerHTML = '<div style="position:relative;margin:4px;">Cover Page</p>'
 *   }))];
 * };
 * 
 * preview.getAppendices = function(w, h)
 * {
 *   return [this.renderPage(w, h, 0, 0, mxUtils.bind(this, function(div)
 *   {
 *     div.innerHTML = '<div style="position:relative;margin:4px;">Appendix</p>'
 *   }))];
 * };
 * 
 * preview.open();
 * (end)
 * 
 * CSS:
 * 
 * The CSS from the original page is not carried over to the print preview.
 * To add CSS to the page, use the css argument in the <open> function or
 * override <writeHead> to add the respective link tags as follows:
 * 
 * (code)
 * var writeHead = preview.writeHead;
 * preview.writeHead = function(doc, css)
 * {
 *   writeHead.apply(this, arguments);
 *   doc.writeln('<link rel="stylesheet" type="text/css" href="style.css">');
 * };
 * (end)
 * 
 * Padding:
 * 
 * To add a padding to the page in the preview (but not the print output), use
 * the following code:
 * 
 * (code)
 * preview.writeHead = function(doc)
 * {
 *   writeHead.apply(this, arguments);
 *   
 *   doc.writeln('<style type="text/css">');
 *   doc.writeln('@media screen {');
 *   doc.writeln('  body > div { padding-top:30px;padding-left:40px;box-sizing:content-box; }');
 *   doc.writeln('}');
 *   doc.writeln('</style>');
 * };
 * (end)
 * 
 * Headers:
 * 
 * Apart from setting the title argument in the mxPrintPreview constructor you
 * can override <renderPage> as follows to add a header to any page:
 * 
 * (code)
 * var oldRenderPage = mxPrintPreview.prototype.renderPage;
 * mxPrintPreview.prototype.renderPage = function(w, h, x, y, content, pageNumber)
 * {
 *   var div = oldRenderPage.apply(this, arguments);
 *   
 *   var header = document.createElement('div');
 *   header.style.position = 'absolute';
 *   header.style.top = '0px';
 *   header.style.width = '100%';
 *   header.style.textAlign = 'right';
 *   mxUtils.write(header, 'Your header here');
 *   div.firstChild.appendChild(header);
 *   
 *   return div;
 * };
 * (end)
 * 
 * The pageNumber argument contains the number of the current page, starting at
 * 1. To display a header on the first page only, check pageNumber and add a
 * vertical offset in the constructor call for the height of the header.
 * 
 * Page Format:
 * 
 * For landscape printing, use <mxConstants.PAGE_FORMAT_A4_LANDSCAPE> as
 * the pageFormat in <mxUtils.getScaleForPageCount> and <mxPrintPreview>.
 * Keep in mind that one can not set the defaults for the print dialog
 * of the operating system from JavaScript so the user must manually choose
 * a page format that matches this setting.
 * 
 * You can try passing the following CSS directive to <open> to set the
 * page format in the print dialog to landscape. However, this CSS
 * directive seems to be ignored in most major browsers, including IE.
 * 
 * (code)
 * @page {
 *   size: landscape;
 * }
 * (end)
 * 
 * Note that the print preview behaves differently in IE when used from the
 * filesystem or via HTTP so printing should always be tested via HTTP.
 * 
 * If you are using a DOCTYPE in the source page you can override <getDoctype>
 * and provide the same DOCTYPE for the print preview if required. Here is
 * an example for IE8 standards mode.
 * 
 * (code)
 * var preview = new mxPrintPreview(graph);
 * preview.getDoctype = function()
 * {
 *   return '<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=5,IE=8" ><![endif]-->';
 * };
 * preview.open();
 * (end)
 * 
 * Constructor: mxPrintPreview
 *
 * Constructs a new print preview for the given parameters.
 * 
 * Parameters:
 * 
 * graph - <mxGraph> to be previewed.
 * scale - Optional scale of the output. Default is 1 / <mxGraph.pageScale>.
 * border - Border in pixels along each side of every page. Note that the
 * actual print function in the browser will add another border for
 * printing.
 * pageFormat - <mxRectangle> that specifies the page format (in pixels).
 * This should match the page format of the printer. Default uses the
 * <mxGraph.pageFormat> of the given graph.
 * x0 - Optional left offset of the output. Default is 0.
 * y0 - Optional top offset of the output. Default is 0.
 * borderColor - Optional color of the page border. Default is no border.
 * Note that a border is sometimes useful to highlight the printed page
 * border in the print preview of the browser.
 * title - Optional string that is used for the window title. Default
 * is 'Printer-friendly version'.
 * pageSelector - Optional boolean that specifies if the page selector
 * should appear in the window with the print preview. Default is true.
 */
function mxPrintPreview(graph, scale, pageFormat, border, x0, y0, borderColor, title, pageSelector)
{
	this.graph = graph;
	this.scale = (scale != null) ? scale : 1 / graph.pageScale;
	this.border = (border != null) ? border : 0;
	this.pageFormat = mxRectangle.fromRectangle((pageFormat != null) ? pageFormat : graph.pageFormat);
	this.title = (title != null) ? title : 'Printer-friendly version';
	this.x0 = (x0 != null) ? x0 : 0;
	this.y0 = (y0 != null) ? y0 : 0;
	this.borderColor = borderColor;
	this.pageSelector = (pageSelector != null) ? pageSelector : true;
};

/**
 * Variable: graph
 * 
 * Reference to the <mxGraph> that should be previewed.
 */
mxPrintPreview.prototype.graph = null;

/**
 * Variable: pageFormat
 *
 * Holds the <mxRectangle> that defines the page format.
 */
mxPrintPreview.prototype.pageFormat = null;

/**
 * Variable: scale
 * 
 * Holds the scale of the print preview.
 */
mxPrintPreview.prototype.scale = null;

/**
 * Variable: border
 * 
 * The border inset around each side of every page in the preview. This is set
 * to 0 if autoOrigin is false.
 */
mxPrintPreview.prototype.border = 0;

/**
 * Variable: marginTop
 * 
 * The margin at the top of the page (number). Default is 0.
 */
mxPrintPreview.prototype.marginTop = 0;

/**
 * Variable: marginBottom
 * 
 * The margin at the bottom of the page (number). Default is 0.
 */
mxPrintPreview.prototype.marginBottom = 0;

/**
 * Variable: x0
 * 
 * Holds the horizontal offset of the output.
 */
mxPrintPreview.prototype.x0 = 0;

/**
 * Variable: y0
 *
 * Holds the vertical offset of the output.
 */
mxPrintPreview.prototype.y0 = 0;

/**
 * Variable: autoOrigin
 * 
 * Specifies if the origin should be automatically computed based on the top,
 * left corner of the actual diagram contents. The required offset will be added
 * to <x0> and <y0> in <open>. Default is true.
 */
mxPrintPreview.prototype.autoOrigin = true;

/**
 * Variable: printOverlays
 * 
 * Specifies if overlays should be printed. Default is false.
 */
mxPrintPreview.prototype.printOverlays = false;

/**
 * Variable: printControls
 * 
 * Specifies if controls (such as folding icons) should be printed. Default is
 * false.
 */
mxPrintPreview.prototype.printControls = false;

/**
 * Variable: printBackgroundImage
 * 
 * Specifies if the background image should be printed. Default is false.
 */
mxPrintPreview.prototype.printBackgroundImage = false;

/**
 * Variable: backgroundColor
 * 
 * Holds the color value for the page background color. Default is #ffffff.
 */
mxPrintPreview.prototype.backgroundColor = '#ffffff';

/**
 * Variable: borderColor
 * 
 * Holds the color value for the page border.
 */
mxPrintPreview.prototype.borderColor = null;

/**
 * Variable: title
 * 
 * Holds the title of the preview window.
 */
mxPrintPreview.prototype.title = null;

/**
 * Variable: pageSelector
 * 
 * Boolean that specifies if the page selector should be
 * displayed. Default is true.
 */
mxPrintPreview.prototype.pageSelector = null;

/**
 * Variable: wnd
 * 
 * Reference to the preview window.
 */
mxPrintPreview.prototype.wnd = null;

/**
 * Variable: targetWindow
 * 
 * Assign any window here to redirect the rendering in <open>.
 */
mxPrintPreview.prototype.targetWindow = null;

/**
 * Variable: pageCount
 * 
 * Holds the actual number of pages in the preview.
 */
mxPrintPreview.prototype.pageCount = 0;

/**
 * Variable: clipping
 * 
 * Specifies is clipping should be used to avoid creating too many cell states
 * in large diagrams. The bounding box of the cells in the original diagram is
 * used if this is enabled. Default is true.
 */
mxPrintPreview.prototype.clipping = true;

/**
 * Function: getWindow
 * 
 * Returns <wnd>.
 */
mxPrintPreview.prototype.getWindow = function()
{
	return this.wnd;
};

/**
 * Function: getDocType
 * 
 * Returns the string that should go before the HTML tag in the print preview
 * page. This implementation returns an X-UA meta tag for IE5 in quirks mode,
 * IE8 in IE8 standards mode and edge in IE9 standards mode.
 */
mxPrintPreview.prototype.getDoctype = function()
{
	var dt = '';
	
	if (document.documentMode == 5)
	{
		dt = '<meta http-equiv="X-UA-Compatible" content="IE=5">';
	}
	else if (document.documentMode == 8)
	{
		dt = '<meta http-equiv="X-UA-Compatible" content="IE=8">';
	}
	else if (document.documentMode > 8)
	{
		// Comment needed to make standards doctype apply in IE
		dt = '<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->';
	}
	
	return dt;
};

/**
 * Function: appendGraph
 * 
 * Adds the given graph to the existing print preview.
 * 
 * Parameters:
 * 
 * css - Optional CSS string to be used in the head section.
 * targetWindow - Optional window that should be used for rendering. If
 * this is specified then no HEAD tag, CSS and BODY tag will be written.
 */
mxPrintPreview.prototype.appendGraph = function(graph, scale, x0, y0, forcePageBreaks, keepOpen)
{
	this.graph = graph;
	this.scale = (scale != null) ? scale : 1 / graph.pageScale;
	this.x0 = x0;
	this.y0 = y0;
	this.open(null, null, forcePageBreaks, keepOpen);
};

/**
 * Function: open
 * 
 * Shows the print preview window. The window is created here if it does
 * not exist.
 * 
 * Parameters:
 * 
 * css - Optional CSS string to be used in the head section.
 * targetWindow - Optional window that should be used for rendering. If
 * this is specified then no HEAD tag, CSS and BODY tag will be written.
 */
mxPrintPreview.prototype.open = function(css, targetWindow, forcePageBreaks, keepOpen)
{
	// Closing the window while the page is being rendered may cause an
	// exception in IE. This and any other exceptions are simply ignored.
	var previousInitializeOverlay = this.graph.cellRenderer.initializeOverlay;
	var div = null;
	
	try
	{
		// Temporarily overrides the method to redirect rendering of overlays
		// to the draw pane so that they are visible in the printout
		if (this.printOverlays)
		{
			this.graph.cellRenderer.initializeOverlay = function(state, overlay)
			{
				overlay.init(state.view.getDrawPane());
			};
		}
		
		if (this.printControls)
		{
			this.graph.cellRenderer.initControl = function(state, control, handleEvents, clickHandler)
			{
				control.dialect = state.view.graph.dialect;
				control.init(state.view.getDrawPane());
			};
		}
		
		this.wnd = (targetWindow != null) ? targetWindow : this.wnd;
		var isNewWindow = false;
		
		if (this.wnd == null)
		{
			isNewWindow = true;
			this.wnd = window.open();
		}
		
		var doc = this.wnd.document;
		
		if (isNewWindow)
		{
			var dt = this.getDoctype();
			
			if (dt != null && dt.length > 0)
			{
				doc.writeln(dt);
			}
			
			if (mxClient.IS_VML)
			{
				doc.writeln('<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">');
			}
			else
			{
				if (document.compatMode === 'CSS1Compat')
				{
					doc.writeln('<!DOCTYPE html>');
				}
				
				doc.writeln('<html>');
			}
			
			doc.writeln('<head>');
			this.writeHead(doc, css);
			doc.writeln('</head>');
			doc.writeln('<body class="mxPage">');
		}

		// Computes the horizontal and vertical page count
		var bounds = this.graph.getGraphBounds().clone();
		var currentScale = this.graph.getView().getScale();
		var sc = currentScale / this.scale;
		var tr = this.graph.getView().getTranslate();
		
		// Uses the absolute origin with no offset for all printing
		if (!this.autoOrigin)
		{
			this.x0 -= tr.x * this.scale;
			this.y0 -= tr.y * this.scale;
			bounds.width += bounds.x;
			bounds.height += bounds.y;
			bounds.x = 0;
			bounds.y = 0;
			this.border = 0;
		}
		
		// Store the available page area
		var availableWidth = this.pageFormat.width - (this.border * 2);
		var availableHeight = this.pageFormat.height - (this.border * 2);
	
		// Adds margins to page format
		this.pageFormat.height += this.marginTop + this.marginBottom;

		// Compute the unscaled, untranslated bounds to find
		// the number of vertical and horizontal pages
		bounds.width /= sc;
		bounds.height /= sc;

		var hpages = Math.max(1, Math.ceil((bounds.width + this.x0) / availableWidth));
		var vpages = Math.max(1, Math.ceil((bounds.height + this.y0) / availableHeight));
		this.pageCount = hpages * vpages;
		
		var writePageSelector = mxUtils.bind(this, function()
		{
			if (this.pageSelector && (vpages > 1 || hpages > 1))
			{
				var table = this.createPageSelector(vpages, hpages);
				doc.body.appendChild(table);
				
				// Implements position: fixed in IE quirks mode
				if (mxClient.IS_IE && doc.documentMode == null || doc.documentMode == 5 || doc.documentMode == 8 || doc.documentMode == 7)
				{
					table.style.position = 'absolute';
					
					var update = function()
					{
						table.style.top = ((doc.body.scrollTop || doc.documentElement.scrollTop) + 10) + 'px';
					};
					
					mxEvent.addListener(this.wnd, 'scroll', function(evt)
					{
						update();
					});
					
					mxEvent.addListener(this.wnd, 'resize', function(evt)
					{
						update();
					});
				}
			}
		});
		
		var addPage = mxUtils.bind(this, function(div, addBreak)
		{
			// Border of the DIV (aka page) inside the document
			if (this.borderColor != null)
			{
				div.style.borderColor = this.borderColor;
				div.style.borderStyle = 'solid';
				div.style.borderWidth = '1px';
			}
			
			// Needs to be assigned directly because IE doesn't support
			// child selectors, eg. body > div { background: white; }
			div.style.background = this.backgroundColor;
			
			if (forcePageBreaks || addBreak)
			{
				div.style.pageBreakAfter = 'always';
			}

			// NOTE: We are dealing with cross-window DOM here, which
			// is a problem in IE, so we copy the HTML markup instead.
			// The underlying problem is that the graph display markup
			// creation (in mxShape, mxGraphView) is hardwired to using
			// document.createElement and hence we must use this document
			// to create the complete page and then copy it over to the
			// new window.document. This can be fixed later by using the
			// ownerDocument of the container in mxShape and mxGraphView.
			if (isNewWindow && (mxClient.IS_IE || document.documentMode >= 11 || mxClient.IS_EDGE))
			{
				// For some obscure reason, removing the DIV from the
				// parent before fetching its outerHTML has missing
				// fillcolor properties and fill children, so the div
				// must be removed afterwards to keep the fillcolors.
				doc.writeln(div.outerHTML);
				div.parentNode.removeChild(div);
			}
			else
			{
				div.parentNode.removeChild(div);
				doc.body.appendChild(div);
			}

			if (forcePageBreaks || addBreak)
			{
				this.addPageBreak(doc);
			}
		});
		
		var cov = this.getCoverPages(this.pageFormat.width, this.pageFormat.height);
		
		if (cov != null)
		{
			for (var i = 0; i < cov.length; i++)
			{
				addPage(cov[i], true);
			}
		}
		
		var apx = this.getAppendices(this.pageFormat.width, this.pageFormat.height);
		
		// Appends each page to the page output for printing, making
		// sure there will be a page break after each page (ie. div)
		for (var i = 0; i < vpages; i++)
		{
			var dy = i * availableHeight / this.scale - this.y0 / this.scale +
					(bounds.y - tr.y * currentScale) / currentScale;
			
			for (var j = 0; j < hpages; j++)
			{
				if (this.wnd == null)
				{
					return null;
				}
				
				var dx = j * availableWidth / this.scale - this.x0 / this.scale +
						(bounds.x - tr.x * currentScale) / currentScale;
				var pageNum = i * hpages + j + 1;
				var clip = new mxRectangle(dx, dy, availableWidth, availableHeight);
				div = this.renderPage(this.pageFormat.width, this.pageFormat.height, 0, 0, mxUtils.bind(this, function(div)
				{
					this.addGraphFragment(-dx, -dy, this.scale, pageNum, div, clip);
					
					if (this.printBackgroundImage)
					{
						this.insertBackgroundImage(div, -dx, -dy);
					}
				}), pageNum);

				// Gives the page a unique ID for later accessing the page
				div.setAttribute('id', 'mxPage-'+pageNum);

				addPage(div, apx != null || i < vpages - 1 || j < hpages - 1);
			}
		}

		if (apx != null)
		{
			for (var i = 0; i < apx.length; i++)
			{
				addPage(apx[i], i < apx.length - 1);
			}
		}

		if (isNewWindow && !keepOpen)
		{
			this.closeDocument();
			writePageSelector();
		}
		
		this.wnd.focus();
	}
	catch (e)
	{
		// Removes the DIV from the document in case of an error
		if (div != null && div.parentNode != null)
		{
			div.parentNode.removeChild(div);
		}
	}
	finally
	{
		this.graph.cellRenderer.initializeOverlay = previousInitializeOverlay;
	}

	return this.wnd;
};

/**
 * Function: addPageBreak
 * 
 * Adds a page break to the given document.
 */
mxPrintPreview.prototype.addPageBreak = function(doc)
{
	var hr = doc.createElement('hr');
	hr.className = 'mxPageBreak';
	doc.body.appendChild(hr);
};

/**
 * Function: closeDocument
 * 
 * Writes the closing tags for body and page after calling <writePostfix>.
 */
mxPrintPreview.prototype.closeDocument = function()
{
	if (this.wnd != null && this.wnd.document != null)
	{
		var doc = this.wnd.document;
		
		this.writePostfix(doc);
		doc.writeln('</body>');
		doc.writeln('</html>');
		doc.close();
		
		// Removes all event handlers in the print output
		mxEvent.release(doc.body);
	}
};

/**
 * Function: writeHead
 * 
 * Writes the HEAD section into the given document, without the opening
 * and closing HEAD tags.
 */
mxPrintPreview.prototype.writeHead = function(doc, css)
{
	if (this.title != null)
	{
		doc.writeln('<title>' + this.title + '</title>');
	}
	
	// Adds required namespaces
	if (mxClient.IS_VML)
	{
		doc.writeln('<style type="text/css">v\\:*{behavior:url(#default#VML)}o\\:*{behavior:url(#default#VML)}</style>');
	}

	// Adds all required stylesheets
	mxClient.link('stylesheet', mxClient.basePath + '/css/common.css', doc);

	// Removes horizontal rules and page selector from print output
	doc.writeln('<style type="text/css">');
	doc.writeln('@media print {');
	doc.writeln('  table.mxPageSelector { display: none; }');
	doc.writeln('  hr.mxPageBreak { display: none; }');
	doc.writeln('}');
	doc.writeln('@media screen {');
	
	// NOTE: position: fixed is not supported in IE, so the page selector
	// position (absolute) needs to be updated in IE (see below)
	doc.writeln('  table.mxPageSelector { position: fixed; right: 10px; top: 10px;' +
			'font-family: Arial; font-size:10pt; border: solid 1px darkgray;' +
			'background: white; border-collapse:collapse; }');
	doc.writeln('  table.mxPageSelector td { border: solid 1px gray; padding:4px; }');
	doc.writeln('  body.mxPage { background: gray; }');
	doc.writeln('}');
	
	if (css != null)
	{
		doc.writeln(css);
	}
	
	doc.writeln('</style>');
};

/**
 * Function: writePostfix
 * 
 * Called before closing the body of the page. This implementation is empty.
 */
mxPrintPreview.prototype.writePostfix = function(doc)
{
	// empty
};

/**
 * Function: createPageSelector
 * 
 * Creates the page selector table.
 */
mxPrintPreview.prototype.createPageSelector = function(vpages, hpages)
{
	var doc = this.wnd.document;
	var table = doc.createElement('table');
	table.className = 'mxPageSelector';
	table.setAttribute('border', '0');

	var tbody = doc.createElement('tbody');
	
	for (var i = 0; i < vpages; i++)
	{
		var row = doc.createElement('tr');
		
		for (var j = 0; j < hpages; j++)
		{
			var pageNum = i * hpages + j + 1;
			var cell = doc.createElement('td');
			var a = doc.createElement('a');
			a.setAttribute('href', '#mxPage-' + pageNum);

			// Workaround for FF where the anchor is appended to the URL of the original document
			if (mxClient.IS_NS && !mxClient.IS_SF && !mxClient.IS_GC)
			{
				var js = 'var page = document.getElementById(\'mxPage-' + pageNum + '\');page.scrollIntoView(true);event.preventDefault();';
				a.setAttribute('onclick', js);
			}
			
			mxUtils.write(a, pageNum, doc);
			cell.appendChild(a);
			row.appendChild(cell);
		}
		
		tbody.appendChild(row);
	}
	
	table.appendChild(tbody);
	
	return table;
};

/**
 * Function: renderPage
 * 
 * Creates a DIV that prints a single page of the given
 * graph using the given scale and returns the DIV that
 * represents the page.
 * 
 * Parameters:
 * 
 * w - Width of the page in pixels.
 * h - Height of the page in pixels.
 * dx - Optional horizontal page offset in pixels (used internally).
 * dy - Optional vertical page offset in pixels (used internally).
 * content - Callback that adds the HTML content to the inner div of a page.
 * Takes the inner div as the argument.
 * pageNumber - Integer representing the page number.
 */
mxPrintPreview.prototype.renderPage = function(w, h, dx, dy, content, pageNumber)
{
	var doc = this.wnd.document;
	var div = document.createElement('div');
	var arg = null;

	try
	{
		// Workaround for ignored clipping in IE 9 standards
		// when printing with page breaks and HTML labels.
		if (dx != 0 || dy != 0)
		{
			div.style.position = 'relative';
			div.style.width = w + 'px';
			div.style.height = h + 'px';
			div.style.pageBreakInside = 'avoid';
			
			var innerDiv = document.createElement('div');
			innerDiv.style.position = 'relative';
			innerDiv.style.top = this.border + 'px';
			innerDiv.style.left = this.border + 'px';
			innerDiv.style.width = (w - 2 * this.border) + 'px';
			innerDiv.style.height = (h - 2 * this.border) + 'px';
			innerDiv.style.overflow = 'hidden';
			
			var viewport = document.createElement('div');
			viewport.style.position = 'relative';
			viewport.style.marginLeft = dx + 'px';
			viewport.style.marginTop = dy + 'px';

			// FIXME: IE8 standards output problems
			if (doc.documentMode == 8)
			{
				innerDiv.style.position = 'absolute';
				viewport.style.position = 'absolute';
			}
		
			if (doc.documentMode == 10)
			{
				viewport.style.width = '100%';
				viewport.style.height = '100%';
			}
			
			innerDiv.appendChild(viewport);
			div.appendChild(innerDiv);
			document.body.appendChild(div);
			arg = viewport;
		}
		// FIXME: IE10/11 too many pages
		else
		{
			div.style.width = w + 'px';
			div.style.height = h + 'px';
			div.style.overflow = 'hidden';
			div.style.pageBreakInside = 'avoid';
			
			// IE8 uses above branch currently
			if (doc.documentMode == 8)
			{
				div.style.position = 'relative';
			}
			
			var innerDiv = document.createElement('div');
			innerDiv.style.width = (w - 2 * this.border) + 'px';
			innerDiv.style.height = (h - 2 * this.border) + 'px';
			innerDiv.style.overflow = 'hidden';

			if (mxClient.IS_IE && (doc.documentMode == null || doc.documentMode == 5 || doc.documentMode == 8 || doc.documentMode == 7))
			{
				innerDiv.style.marginTop = this.border + 'px';
				innerDiv.style.marginLeft = this.border + 'px';	
			}
			else
			{
				innerDiv.style.top = this.border + 'px';
				innerDiv.style.left = this.border + 'px';
			}
	
			if (this.graph.dialect == mxConstants.DIALECT_VML)
			{
				innerDiv.style.position = 'absolute';
			}

			div.appendChild(innerDiv);
			document.body.appendChild(div);
			arg = innerDiv;
		}
	}
	catch (e)
	{
		div.parentNode.removeChild(div);
		div = null;
		
		throw e;
	}

	content(arg);
	 
	return div;
};

/**
 * Function: getRoot
 * 
 * Returns the root cell for painting the graph.
 */
mxPrintPreview.prototype.getRoot = function()
{
	var root = this.graph.view.currentRoot;
	
	if (root == null)
	{
		root = this.graph.getModel().getRoot();
	}
	
	return root;
};

/**
 * Function: addGraphFragment
 * 
 * Adds a graph fragment to the given div.
 * 
 * Parameters:
 * 
 * dx - Horizontal translation for the diagram.
 * dy - Vertical translation for the diagram.
 * scale - Scale for the diagram.
 * pageNumber - Number of the page to be rendered.
 * div - Div that contains the output.
 * clip - Contains the clipping rectangle as an <mxRectangle>.
 */
mxPrintPreview.prototype.addGraphFragment = function(dx, dy, scale, pageNumber, div, clip)
{
	var view = this.graph.getView();
	var previousContainer = this.graph.container;
	this.graph.container = div;
	
	var canvas = view.getCanvas();
	var backgroundPane = view.getBackgroundPane();
	var drawPane = view.getDrawPane();
	var overlayPane = view.getOverlayPane();

	if (this.graph.dialect == mxConstants.DIALECT_SVG)
	{
		view.createSvg();
	}
	else if (this.graph.dialect == mxConstants.DIALECT_VML)
	{
		view.createVml();
	}
	else
	{
		view.createHtml();
	}
	
	// Disables events on the view
	var eventsEnabled = view.isEventsEnabled();
	view.setEventsEnabled(false);
	
	// Disables the graph to avoid cursors
	var graphEnabled = this.graph.isEnabled();
	this.graph.setEnabled(false);

	// Resets the translation
	var translate = view.getTranslate();
	view.translate = new mxPoint(dx, dy);
	
	// Redraws only states that intersect the clip
	var redraw = this.graph.cellRenderer.redraw;
	var states = view.states;
	var s = view.scale;
	
	// Gets the transformed clip for intersection check below
	if (this.clipping)
	{
		var tempClip = new mxRectangle((clip.x + translate.x) * s, (clip.y + translate.y) * s,
				clip.width * s / scale, clip.height * s / scale);
		
		// Checks clipping rectangle for speedup
		// Must create terminal states for edge clipping even if terminal outside of clip
		this.graph.cellRenderer.redraw = function(state, force, rendering)
		{
			if (state != null)
			{
				// Gets original state from graph to find bounding box
				var orig = states.get(state.cell);
				
				if (orig != null)
				{
					var bbox = view.getBoundingBox(orig, false);
					
					// Stops rendering if outside clip for speedup
					if (bbox != null && !mxUtils.intersects(tempClip, bbox))
					{
						return;
					}
				}
			}
			
			redraw.apply(this, arguments);
		};
	}
	
	var temp = null;
	
	try
	{
		// Creates the temporary cell states in the view and
		// draws them onto the temporary DOM nodes in the view
		var cells = [this.getRoot()];
		temp = new mxTemporaryCellStates(view, scale, cells);
	}
	finally
	{
		// Removes overlay pane with selection handles
		// controls and icons from the print output
		if (mxClient.IS_IE)
		{
			view.overlayPane.innerHTML = '';
			view.canvas.style.overflow = 'hidden';
			view.canvas.style.position = 'relative';
			view.canvas.style.top = this.marginTop + 'px';
			view.canvas.style.width = clip.width + 'px';
			view.canvas.style.height = clip.height + 'px';
		}
		else
		{
			// Removes everything but the SVG node
			var tmp = div.firstChild;

			while (tmp != null)
			{
				var next = tmp.nextSibling;
				var name = tmp.nodeName.toLowerCase();

				// Note: Width and height are required in FF 11
				if (name == 'svg')
				{
					tmp.style.overflow = 'hidden';
					tmp.style.position = 'relative';
					tmp.style.top = this.marginTop + 'px';
					tmp.setAttribute('width', clip.width);
					tmp.setAttribute('height', clip.height);
					tmp.style.width = '';
					tmp.style.height = '';
				}
				// Tries to fetch all text labels and only text labels
				else if (tmp.style.cursor != 'default' && name != 'div')
				{
					tmp.parentNode.removeChild(tmp);
				}
				
				tmp = next;
			}
		}
		
		// Puts background image behind SVG output
		if (this.printBackgroundImage)
		{
			var svgs = div.getElementsByTagName('svg');
			
			if (svgs.length > 0)
			{
				svgs[0].style.position = 'absolute';
			}
		}
		
		// Completely removes the overlay pane to remove more handles
		view.overlayPane.parentNode.removeChild(view.overlayPane);

		// Restores the state of the view
		this.graph.setEnabled(graphEnabled);
		this.graph.container = previousContainer;
		this.graph.cellRenderer.redraw = redraw;
		view.canvas = canvas;
		view.backgroundPane = backgroundPane;
		view.drawPane = drawPane;
		view.overlayPane = overlayPane;
		view.translate = translate;
		temp.destroy();
		view.setEventsEnabled(eventsEnabled);
	}
};

/**
 * Function: insertBackgroundImage
 * 
 * Inserts the background image into the given div.
 */
mxPrintPreview.prototype.insertBackgroundImage = function(div, dx, dy)
{
	var bg = this.graph.backgroundImage;
	
	if (bg != null)
	{
		var img = document.createElement('img');
		img.style.position = 'absolute';
		img.style.marginLeft = Math.round(dx * this.scale) + 'px';
		img.style.marginTop = Math.round(dy * this.scale) + 'px';
		img.setAttribute('width', Math.round(this.scale * bg.width));
		img.setAttribute('height', Math.round(this.scale * bg.height));
		img.src = bg.src;
		
		div.insertBefore(img, div.firstChild);
	}
};

/**
 * Function: getCoverPages
 * 
 * Returns the pages to be added before the print output. This returns null.
 */
mxPrintPreview.prototype.getCoverPages = function()
{
	return null;
};

/**
 * Function: getAppendices
 * 
 * Returns the pages to be added after the print output. This returns null.
 */
mxPrintPreview.prototype.getAppendices = function()
{
	return null;
};

/**
 * Function: print
 * 
 * Opens the print preview and shows the print dialog.
 * 
 * Parameters:
 * 
 * css - Optional CSS string to be used in the head section.
 */
mxPrintPreview.prototype.print = function(css)
{
	var wnd = this.open(css);
	
	if (wnd != null)
	{
		wnd.print();
	}
};

/**
 * Function: close
 * 
 * Closes the print preview window.
 */
mxPrintPreview.prototype.close = function()
{
	if (this.wnd != null)
	{
		this.wnd.close();
		this.wnd = null;
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxStylesheet
 * 
 * Defines the appearance of the cells in a graph. See <putCellStyle> for an
 * example of creating a new cell style. It is recommended to use objects, not
 * arrays for holding cell styles. Existing styles can be cloned using
 * <mxUtils.clone> and turned into a string for debugging using
 * <mxUtils.toString>.
 *
 * Default Styles:
 * 
 * The stylesheet contains two built-in styles, which are used if no style is
 * defined for a cell:
 *
 *   defaultVertex - Default style for vertices
 *   defaultEdge - Default style for edges
 * 
 * Example:
 * 
 * (code)
 * var vertexStyle = stylesheet.getDefaultVertexStyle();
 * vertexStyle[mxConstants.ROUNDED] = true;
 * var edgeStyle = stylesheet.getDefaultEdgeStyle();
 * edgeStyle[mxConstants.STYLE_EDGE] = mxEdgeStyle.EntityRelation;
 * (end)
 * 
 * Modifies the built-in default styles.
 * 
 * To avoid the default style for a cell, add a leading semicolon
 * to the style definition, eg.
 * 
 * (code)
 * ;shadow=1
 * (end)
 * 
 * Removing keys:
 * 
 * For removing a key in a cell style of the form [stylename;|key=value;] the
 * special value none can be used, eg. highlight;fillColor=none
 * 
 * See also the helper methods in mxUtils to modify strings of this format,
 * namely <mxUtils.setStyle>, <mxUtils.indexOfStylename>,
 * <mxUtils.addStylename>, <mxUtils.removeStylename>,
 * <mxUtils.removeAllStylenames> and <mxUtils.setStyleFlag>.
 * 
 * Constructor: mxStylesheet
 * 
 * Constructs a new stylesheet and assigns default styles.
 */
function mxStylesheet()
{
	this.styles = new Object();
	
	this.putDefaultVertexStyle(this.createDefaultVertexStyle());
	this.putDefaultEdgeStyle(this.createDefaultEdgeStyle());
};

/**
 * Function: styles
 * 
 * Maps from names to cell styles. Each cell style is a map of key,
 * value pairs.
 */
mxStylesheet.prototype.styles;

/**
 * Function: createDefaultVertexStyle
 * 
 * Creates and returns the default vertex style.
 */
mxStylesheet.prototype.createDefaultVertexStyle = function()
{
	var style = new Object();
	
	style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_RECTANGLE;
	style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter;
	style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE;
	style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER;
	style[mxConstants.STYLE_FILLCOLOR] = '#C3D9FF';
	style[mxConstants.STYLE_STROKECOLOR] = '#6482B9';
	style[mxConstants.STYLE_FONTCOLOR] = '#774400';
	
	return style;
};

/**
 * Function: createDefaultEdgeStyle
 * 
 * Creates and returns the default edge style.
 */
mxStylesheet.prototype.createDefaultEdgeStyle = function()
{
	var style = new Object();
	
	style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_CONNECTOR;
	style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_CLASSIC;
	style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE;
	style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER;
	style[mxConstants.STYLE_STROKECOLOR] = '#6482B9';
	style[mxConstants.STYLE_FONTCOLOR] = '#446299';
	
	return style;
};

/**
 * Function: putDefaultVertexStyle
 * 
 * Sets the default style for vertices using defaultVertex as the
 * stylename.
 * 
 * Parameters:
 * style - Key, value pairs that define the style.
 */
mxStylesheet.prototype.putDefaultVertexStyle = function(style)
{
	this.putCellStyle('defaultVertex', style);
};

/**
 * Function: putDefaultEdgeStyle
 * 
 * Sets the default style for edges using defaultEdge as the stylename.
 */
mxStylesheet.prototype.putDefaultEdgeStyle = function(style)
{
	this.putCellStyle('defaultEdge', style);
};

/**
 * Function: getDefaultVertexStyle
 * 
 * Returns the default style for vertices.
 */
mxStylesheet.prototype.getDefaultVertexStyle = function()
{
	return this.styles['defaultVertex'];
};

/**
 * Function: getDefaultEdgeStyle
 * 
 * Sets the default style for edges.
 */
mxStylesheet.prototype.getDefaultEdgeStyle = function()
{
	return this.styles['defaultEdge'];
};

/**
 * Function: putCellStyle
 * 
 * Stores the given map of key, value pairs under the given name in
 * <styles>.
 *
 * Example:
 * 
 * The following example adds a new style called 'rounded' into an
 * existing stylesheet:
 * 
 * (code)
 * var style = new Object();
 * style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_RECTANGLE;
 * style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter;
 * style[mxConstants.STYLE_ROUNDED] = true;
 * graph.getStylesheet().putCellStyle('rounded', style);
 * (end)
 * 
 * In the above example, the new style is an object. The possible keys of
 * the object are all the constants in <mxConstants> that start with STYLE
 * and the values are either JavaScript objects, such as
 * <mxPerimeter.RightAngleRectanglePerimeter> (which is in fact a function)
 * or expressions, such as true. Note that not all keys will be
 * interpreted by all shapes (eg. the line shape ignores the fill color).
 * The final call to this method associates the style with a name in the
 * stylesheet. The style is used in a cell with the following code:
 * 
 * (code)
 * model.setStyle(cell, 'rounded');
 * (end)
 * 
 * Parameters:
 * 
 * name - Name for the style to be stored.
 * style - Key, value pairs that define the style.
 */
mxStylesheet.prototype.putCellStyle = function(name, style)
{
	this.styles[name] = style;
};

/**
 * Function: getCellStyle
 * 
 * Returns the cell style for the specified stylename or the given
 * defaultStyle if no style can be found for the given stylename.
 * 
 * Parameters:
 * 
 * name - String of the form [(stylename|key=value);] that represents the
 * style.
 * defaultStyle - Default style to be returned if no style can be found.
 */
mxStylesheet.prototype.getCellStyle = function(name, defaultStyle)
{
	var style = defaultStyle;
	
	if (name != null && name.length > 0)
	{
		var pairs = name.split(';');

		if (style != null &&
			name.charAt(0) != ';')
		{
			style = mxUtils.clone(style);
		}
		else
		{
			style = new Object();
		}

		// Parses each key, value pair into the existing style
	 	for (var i = 0; i < pairs.length; i++)
	 	{
	 		var tmp = pairs[i];
	 		var pos = tmp.indexOf('=');
	 		
	 		if (pos >= 0)
	 		{
		 		var key = tmp.substring(0, pos);
		 		var value = tmp.substring(pos + 1);

		 		if (value == mxConstants.NONE)
		 		{
		 			delete style[key];
		 		}
		 		else if (mxUtils.isNumeric(value))
		 		{
		 			style[key] = parseFloat(value);
		 		}
		 		else
		 		{
			 		style[key] = value;
		 		}
			}
	 		else
	 		{
	 			// Merges the entries from a named style
				var tmpStyle = this.styles[tmp];
				
				if (tmpStyle != null)
				{
					for (var key in tmpStyle)
					{
						style[key] = tmpStyle[key];
					}
				}
	 		}
		}
	}
	
	return style;
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxCellState
 * 
 * Represents the current state of a cell in a given <mxGraphView>.
 * 
 * For edges, the edge label position is stored in <absoluteOffset>.
 * 
 * The size for oversize labels can be retrieved using the boundingBox property
 * of the <text> field as shown below.
 * 
 * (code)
 * var bbox = (state.text != null) ? state.text.boundingBox : null;
 * (end)
 * 
 * Constructor: mxCellState
 * 
 * Constructs a new object that represents the current state of the given
 * cell in the specified view.
 * 
 * Parameters:
 * 
 * view - <mxGraphView> that contains the state.
 * cell - <mxCell> that this state represents.
 * style - Array of key, value pairs that constitute the style.
 */
function mxCellState(view, cell, style)
{
	this.view = view;
	this.cell = cell;
	this.style = style;
	
	this.origin = new mxPoint();
	this.absoluteOffset = new mxPoint();
};

/**
 * Extends mxRectangle.
 */
mxCellState.prototype = new mxRectangle();
mxCellState.prototype.constructor = mxCellState;

/**
 * Variable: view
 * 
 * Reference to the enclosing <mxGraphView>.
 */
mxCellState.prototype.view = null;

/**
 * Variable: cell
 *
 * Reference to the <mxCell> that is represented by this state.
 */
mxCellState.prototype.cell = null;

/**
 * Variable: style
 * 
 * Contains an array of key, value pairs that represent the style of the
 * cell.
 */
mxCellState.prototype.style = null;

/**
 * Variable: invalid
 * 
 * Specifies if the state is invalid. Default is true.
 */
mxCellState.prototype.invalid = true;

/**
 * Variable: origin
 *
 * <mxPoint> that holds the origin for all child cells. Default is a new
 * empty <mxPoint>.
 */
mxCellState.prototype.origin = null;

/**
 * Variable: absolutePoints
 * 
 * Holds an array of <mxPoints> that represent the absolute points of an
 * edge.
 */
mxCellState.prototype.absolutePoints = null;

/**
 * Variable: absoluteOffset
 *
 * <mxPoint> that holds the absolute offset. For edges, this is the
 * absolute coordinates of the label position. For vertices, this is the
 * offset of the label relative to the top, left corner of the vertex. 
 */
mxCellState.prototype.absoluteOffset = null;

/**
 * Variable: visibleSourceState
 * 
 * Caches the visible source terminal state.
 */
mxCellState.prototype.visibleSourceState = null;

/**
 * Variable: visibleTargetState
 * 
 * Caches the visible target terminal state.
 */
mxCellState.prototype.visibleTargetState = null;

/**
 * Variable: terminalDistance
 * 
 * Caches the distance between the end points for an edge.
 */
mxCellState.prototype.terminalDistance = 0;

/**
 * Variable: length
 *
 * Caches the length of an edge.
 */
mxCellState.prototype.length = 0;

/**
 * Variable: segments
 * 
 * Array of numbers that represent the cached length of each segment of the
 * edge.
 */
mxCellState.prototype.segments = null;

/**
 * Variable: shape
 * 
 * Holds the <mxShape> that represents the cell graphically.
 */
mxCellState.prototype.shape = null;

/**
 * Variable: text
 * 
 * Holds the <mxText> that represents the label of the cell. Thi smay be
 * null if the cell has no label.
 */
mxCellState.prototype.text = null;

/**
 * Variable: unscaledWidth
 * 
 * Holds the unscaled width of the state.
 */
mxCellState.prototype.unscaledWidth = null;

/**
 * Function: getPerimeterBounds
 * 
 * Returns the <mxRectangle> that should be used as the perimeter of the
 * cell.
 * 
 * Parameters:
 * 
 * border - Optional border to be added around the perimeter bounds.
 * bounds - Optional <mxRectangle> to be used as the initial bounds.
 */
mxCellState.prototype.getPerimeterBounds = function(border, bounds)
{
	border = border || 0;
	bounds = (bounds != null) ? bounds : new mxRectangle(this.x, this.y, this.width, this.height);
	
	if (this.shape != null && this.shape.stencil != null && this.shape.stencil.aspect == 'fixed')
	{
		var aspect = this.shape.stencil.computeAspect(this.style, bounds.x, bounds.y, bounds.width, bounds.height);
		
		bounds.x = aspect.x;
		bounds.y = aspect.y;
		bounds.width = this.shape.stencil.w0 * aspect.width;
		bounds.height = this.shape.stencil.h0 * aspect.height;
	}
	
	if (border != 0)
	{
		bounds.grow(border);
	}
	
	return bounds;
};

/**
 * Function: setAbsoluteTerminalPoint
 * 
 * Sets the first or last point in <absolutePoints> depending on isSource.
 * 
 * Parameters:
 * 
 * point - <mxPoint> that represents the terminal point.
 * isSource - Boolean that specifies if the first or last point should
 * be assigned.
 */
mxCellState.prototype.setAbsoluteTerminalPoint = function(point, isSource)
{
	if (isSource)
	{
		if (this.absolutePoints == null)
		{
			this.absolutePoints = [];
		}
		
		if (this.absolutePoints.length == 0)
		{
			this.absolutePoints.push(point);
		}
		else
		{
			this.absolutePoints[0] = point;
		}
	}
	else
	{
		if (this.absolutePoints == null)
		{
			this.absolutePoints = [];
			this.absolutePoints.push(null);
			this.absolutePoints.push(point);
		}
		else if (this.absolutePoints.length == 1)
		{
			this.absolutePoints.push(point);
		}
		else
		{
			this.absolutePoints[this.absolutePoints.length - 1] = point;
		}
	}
};

/**
 * Function: setCursor
 * 
 * Sets the given cursor on the shape and text shape.
 */
mxCellState.prototype.setCursor = function(cursor)
{
	if (this.shape != null)
	{
		this.shape.setCursor(cursor);
	}
	
	if (this.text != null)
	{
		this.text.setCursor(cursor);
	}
};

/**
 * Function: getVisibleTerminal
 * 
 * Returns the visible source or target terminal cell.
 * 
 * Parameters:
 * 
 * source - Boolean that specifies if the source or target cell should be
 * returned.
 */
mxCellState.prototype.getVisibleTerminal = function(source)
{
	var tmp = this.getVisibleTerminalState(source);
	
	return (tmp != null) ? tmp.cell : null;
};

/**
 * Function: getVisibleTerminalState
 * 
 * Returns the visible source or target terminal state.
 * 
 * Parameters:
 * 
 * source - Boolean that specifies if the source or target state should be
 * returned.
 */
mxCellState.prototype.getVisibleTerminalState = function(source)
{
	return (source) ? this.visibleSourceState : this.visibleTargetState;
};

/**
 * Function: setVisibleTerminalState
 * 
 * Sets the visible source or target terminal state.
 * 
 * Parameters:
 * 
 * terminalState - <mxCellState> that represents the terminal.
 * source - Boolean that specifies if the source or target state should be set.
 */
mxCellState.prototype.setVisibleTerminalState = function(terminalState, source)
{
	if (source)
	{
		this.visibleSourceState = terminalState;
	}
	else
	{
		this.visibleTargetState = terminalState;
	}
};

/**
 * Function: getCellBounds
 * 
 * Returns the unscaled, untranslated bounds.
 */
mxCellState.prototype.getCellBounds = function()
{
	return this.cellBounds;
};

/**
 * Function: getPaintBounds
 * 
 * Returns the unscaled, untranslated paint bounds. This is the same as
 * <getCellBounds> but with a 90 degree rotation if the shape's
 * isPaintBoundsInverted returns true.
 */
mxCellState.prototype.getPaintBounds = function()
{
	return this.paintBounds;
};

/**
 * Function: updateCachedBounds
 * 
 * Updates the cellBounds and paintBounds.
 */
mxCellState.prototype.updateCachedBounds = function()
{
	var tr = this.view.translate;
	var s = this.view.scale;
	this.cellBounds = new mxRectangle(this.x / s - tr.x, this.y / s - tr.y, this.width / s, this.height / s);
	this.paintBounds = mxRectangle.fromRectangle(this.cellBounds);
	
	if (this.shape != null && this.shape.isPaintBoundsInverted())
	{
		this.paintBounds.rotate90();
	}
};

/**
 * Destructor: setState
 * 
 * Copies all fields from the given state to this state.
 */
mxCellState.prototype.setState = function(state)
{
	this.view = state.view;
	this.cell = state.cell;
	this.style = state.style;
	this.absolutePoints = state.absolutePoints;
	this.origin = state.origin;
	this.absoluteOffset = state.absoluteOffset;
	this.boundingBox = state.boundingBox;
	this.terminalDistance = state.terminalDistance;
	this.segments = state.segments;
	this.length = state.length;
	this.x = state.x;
	this.y = state.y;
	this.width = state.width;
	this.height = state.height;
	this.unscaledWidth = state.unscaledWidth;
};

/**
 * Function: clone
 *
 * Returns a clone of this <mxPoint>.
 */
mxCellState.prototype.clone = function()
{
 	var clone = new mxCellState(this.view, this.cell, this.style);

	// Clones the absolute points
	if (this.absolutePoints != null)
	{
		clone.absolutePoints = [];
		
		for (var i = 0; i < this.absolutePoints.length; i++)
		{
			clone.absolutePoints[i] = this.absolutePoints[i].clone();
		}
	}

	if (this.origin != null)
	{
		clone.origin = this.origin.clone();
	}

	if (this.absoluteOffset != null)
	{
		clone.absoluteOffset = this.absoluteOffset.clone();
	}

	if (this.boundingBox != null)
	{
		clone.boundingBox = this.boundingBox.clone();
	}

	clone.terminalDistance = this.terminalDistance;
	clone.segments = this.segments;
	clone.length = this.length;
	clone.x = this.x;
	clone.y = this.y;
	clone.width = this.width;
	clone.height = this.height;
	clone.unscaledWidth = this.unscaledWidth;
	
	return clone;
};

/**
 * Destructor: destroy
 * 
 * Destroys the state and all associated resources.
 */
mxCellState.prototype.destroy = function()
{
	this.view.graph.cellRenderer.destroy(this);
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxGraphSelectionModel
 *
 * Implements the selection model for a graph. Here is a listener that handles
 * all removed selection cells.
 * 
 * (code)
 * graph.getSelectionModel().addListener(mxEvent.CHANGE, function(sender, evt)
 * {
 *   var cells = evt.getProperty('added');
 *   
 *   for (var i = 0; i < cells.length; i++)
 *   {
 *     // Handle cells[i]...
 *   }
 * });
 * (end)
 * 
 * Event: mxEvent.UNDO
 * 
 * Fires after the selection was changed in <changeSelection>. The
 * <code>edit</code> property contains the <mxUndoableEdit> which contains the
 * <mxSelectionChange>.
 * 
 * Event: mxEvent.CHANGE
 * 
 * Fires after the selection changes by executing an <mxSelectionChange>. The
 * <code>added</code> and <code>removed</code> properties contain arrays of
 * cells that have been added to or removed from the selection, respectively.
 * The names are inverted due to historic reasons. This cannot be changed.
 * 
 * Constructor: mxGraphSelectionModel
 *
 * Constructs a new graph selection model for the given <mxGraph>.
 * 
 * Parameters:
 * 
 * graph - Reference to the enclosing <mxGraph>.
 */
function mxGraphSelectionModel(graph)
{
	this.graph = graph;
	this.cells = [];
};

/**
 * Extends mxEventSource.
 */
mxGraphSelectionModel.prototype = new mxEventSource();
mxGraphSelectionModel.prototype.constructor = mxGraphSelectionModel;

/**
 * Variable: doneResource
 * 
 * Specifies the resource key for the status message after a long operation.
 * If the resource for this key does not exist then the value is used as
 * the status message. Default is 'done'.
 */
mxGraphSelectionModel.prototype.doneResource = (mxClient.language != 'none') ? 'done' : '';

/**
 * Variable: updatingSelectionResource
 *
 * Specifies the resource key for the status message while the selection is
 * being updated. If the resource for this key does not exist then the
 * value is used as the status message. Default is 'updatingSelection'.
 */
mxGraphSelectionModel.prototype.updatingSelectionResource = (mxClient.language != 'none') ? 'updatingSelection' : '';

/**
 * Variable: graph
 * 
 * Reference to the enclosing <mxGraph>.
 */
mxGraphSelectionModel.prototype.graph = null;

/**
 * Variable: singleSelection
 *
 * Specifies if only one selected item at a time is allowed.
 * Default is false.
 */
mxGraphSelectionModel.prototype.singleSelection = false;

/**
 * Function: isSingleSelection
 *
 * Returns <singleSelection> as a boolean.
 */
mxGraphSelectionModel.prototype.isSingleSelection = function()
{
	return this.singleSelection;
};

/**
 * Function: setSingleSelection
 *
 * Sets the <singleSelection> flag.
 * 
 * Parameters:
 * 
 * singleSelection - Boolean that specifies the new value for
 * <singleSelection>.
 */
mxGraphSelectionModel.prototype.setSingleSelection = function(singleSelection)
{
	this.singleSelection = singleSelection;
};

/**
 * Function: isSelected
 *
 * Returns true if the given <mxCell> is selected.
 */
mxGraphSelectionModel.prototype.isSelected = function(cell)
{
	if (cell != null)
	{
		return mxUtils.indexOf(this.cells, cell) >= 0;
	}
	
	return false;
};

/**
 * Function: isEmpty
 *
 * Returns true if no cells are currently selected.
 */
mxGraphSelectionModel.prototype.isEmpty = function()
{
	return this.cells.length == 0;
};

/**
 * Function: clear
 *
 * Clears the selection and fires a <change> event if the selection was not
 * empty.
 */
mxGraphSelectionModel.prototype.clear = function()
{
	this.changeSelection(null, this.cells);
};

/**
 * Function: setCell
 *
 * Selects the specified <mxCell> using <setCells>.
 * 
 * Parameters:
 * 
 * cell - <mxCell> to be selected.
 */
mxGraphSelectionModel.prototype.setCell = function(cell)
{
	if (cell != null)
	{
		this.setCells([cell]);
	}
};

/**
 * Function: setCells
 *
 * Selects the given array of <mxCells> and fires a <change> event.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to be selected.
 */
mxGraphSelectionModel.prototype.setCells = function(cells)
{
	if (cells != null)
	{
		if (this.singleSelection)
		{
			cells = [this.getFirstSelectableCell(cells)];
		}
	
		var tmp = [];
		
		for (var i = 0; i < cells.length; i++)
		{
			if (this.graph.isCellSelectable(cells[i]))
			{
				tmp.push(cells[i]);
			}	
		}

		this.changeSelection(tmp, this.cells);
	}
};

/**
 * Function: getFirstSelectableCell
 *
 * Returns the first selectable cell in the given array of cells.
 */
mxGraphSelectionModel.prototype.getFirstSelectableCell = function(cells)
{
	if (cells != null)
	{
		for (var i = 0; i < cells.length; i++)
		{
			if (this.graph.isCellSelectable(cells[i]))
			{
				return cells[i];
			}
		}
	}
	
	return null;
};

/**
 * Function: addCell
 * 
 * Adds the given <mxCell> to the selection and fires a <select> event.
 * 
 * Parameters:
 * 
 * cell - <mxCell> to add to the selection.
 */
mxGraphSelectionModel.prototype.addCell = function(cell)
{
	if (cell != null)
	{
		this.addCells([cell]);
	}
};

/**
 * Function: addCells
 * 
 * Adds the given array of <mxCells> to the selection and fires a <select>
 * event.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to add to the selection.
 */
mxGraphSelectionModel.prototype.addCells = function(cells)
{
	if (cells != null)
	{
		var remove = null;
		
		if (this.singleSelection)
		{
			remove = this.cells;
			cells = [this.getFirstSelectableCell(cells)];
		}

		var tmp = [];
		
		for (var i = 0; i < cells.length; i++)
		{
			if (!this.isSelected(cells[i]) &&
				this.graph.isCellSelectable(cells[i]))
			{
				tmp.push(cells[i]);
			}	
		}

		this.changeSelection(tmp, remove);
	}
};

/**
 * Function: removeCell
 *
 * Removes the specified <mxCell> from the selection and fires a <select>
 * event for the remaining cells.
 * 
 * Parameters:
 * 
 * cell - <mxCell> to remove from the selection.
 */
mxGraphSelectionModel.prototype.removeCell = function(cell)
{
	if (cell != null)
	{
		this.removeCells([cell]);
	}
};

/**
 * Function: removeCells
 */
mxGraphSelectionModel.prototype.removeCells = function(cells)
{
	if (cells != null)
	{
		var tmp = [];
		
		for (var i = 0; i < cells.length; i++)
		{
			if (this.isSelected(cells[i]))
			{
				tmp.push(cells[i]);
			}
		}
		
		this.changeSelection(null, tmp);	
	}
};

/**
 * Function: changeSelection
 *
 * Inner callback to add the specified <mxCell> to the selection. No event
 * is fired in this implementation.
 * 
 * Paramters:
 * 
 * cell - <mxCell> to add to the selection.
 */
mxGraphSelectionModel.prototype.changeSelection = function(added, removed)
{
	if ((added != null &&
		added.length > 0 &&
		added[0] != null) ||
		(removed != null &&
		removed.length > 0 &&
		removed[0] != null))
	{
		var change = new mxSelectionChange(this, added, removed);
		change.execute();
		var edit = new mxUndoableEdit(this, false);
		edit.add(change);
		this.fireEvent(new mxEventObject(mxEvent.UNDO, 'edit', edit));
	}
};

/**
 * Function: cellAdded
 *
 * Inner callback to add the specified <mxCell> to the selection. No event
 * is fired in this implementation.
 * 
 * Paramters:
 * 
 * cell - <mxCell> to add to the selection.
 */
mxGraphSelectionModel.prototype.cellAdded = function(cell)
{
	if (cell != null &&
		!this.isSelected(cell))
	{
		this.cells.push(cell);
	}
};

/**
 * Function: cellRemoved
 *
 * Inner callback to remove the specified <mxCell> from the selection. No
 * event is fired in this implementation.
 * 
 * Parameters:
 * 
 * cell - <mxCell> to remove from the selection.
 */
mxGraphSelectionModel.prototype.cellRemoved = function(cell)
{
	if (cell != null)
	{
		var index = mxUtils.indexOf(this.cells, cell);
		
		if (index >= 0)
		{
			this.cells.splice(index, 1);
		}
	}
};

/**
 * Class: mxSelectionChange
 *
 * Action to change the current root in a view.
 *
 * Constructor: mxCurrentRootChange
 *
 * Constructs a change of the current root in the given view.
 */
function mxSelectionChange(selectionModel, added, removed)
{
	this.selectionModel = selectionModel;
	this.added = (added != null) ? added.slice() : null;
	this.removed = (removed != null) ? removed.slice() : null;
};

/**
 * Function: execute
 *
 * Changes the current root of the view.
 */
mxSelectionChange.prototype.execute = function()
{
	var t0 = mxLog.enter('mxSelectionChange.execute');
	window.status = mxResources.get(
		this.selectionModel.updatingSelectionResource) ||
		this.selectionModel.updatingSelectionResource;

	if (this.removed != null)
	{
		for (var i = 0; i < this.removed.length; i++)
		{
			this.selectionModel.cellRemoved(this.removed[i]);
		}
	}

	if (this.added != null)
	{
		for (var i = 0; i < this.added.length; i++)
		{
			this.selectionModel.cellAdded(this.added[i]);
		}
	}
	
	var tmp = this.added;
	this.added = this.removed;
	this.removed = tmp;

	window.status = mxResources.get(this.selectionModel.doneResource) ||
		this.selectionModel.doneResource;
	mxLog.leave('mxSelectionChange.execute', t0);
	
	this.selectionModel.fireEvent(new mxEventObject(mxEvent.CHANGE,
			'added', this.added, 'removed', this.removed));
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxCellEditor
 *
 * In-place editor for the graph. To control this editor, use
 * <mxGraph.invokesStopCellEditing>, <mxGraph.enterStopsCellEditing> and
 * <mxGraph.escapeEnabled>. If <mxGraph.enterStopsCellEditing> is true then
 * ctrl-enter or shift-enter can be used to create a linefeed. The F2 and
 * escape keys can always be used to stop editing.
 * 
 * To customize the location of the textbox in the graph, override
 * <getEditorBounds> as follows:
 * 
 * (code)
 * graph.cellEditor.getEditorBounds = function(state)
 * {
 *   var result = mxCellEditor.prototype.getEditorBounds.apply(this, arguments);
 *   
 *   if (this.graph.getModel().isEdge(state.cell))
 *   {
 *     result.x = state.getCenterX() - result.width / 2;
 *     result.y = state.getCenterY() - result.height / 2;
 *   }
 *   
 *   return result;
 * };
 * (end)
 * 
 * Note that this hook is only called if <autoSize> is false. If <autoSize> is true,
 * then <mxShape.getLabelBounds> is used to compute the current bounds of the textbox.
 * 
 * The textarea uses the mxCellEditor CSS class. You can modify this class in
 * your custom CSS. Note: You should modify the CSS after loading the client
 * in the page.
 *
 * Example:
 * 
 * To only allow numeric input in the in-place editor, use the following code.
 *
 * (code)
 * var text = graph.cellEditor.textarea;
 * 
 * mxEvent.addListener(text, 'keydown', function (evt)
 * {
 *   if (!(evt.keyCode >= 48 && evt.keyCode <= 57) &&
 *       !(evt.keyCode >= 96 && evt.keyCode <= 105))
 *   {
 *     mxEvent.consume(evt);
 *   }
 * }); 
 * (end)
 * 
 * Placeholder:
 * 
 * To implement a placeholder for cells without a label, use the
 * <emptyLabelText> variable.
 * 
 * Resize in Chrome:
 * 
 * Resize of the textarea is disabled by default. If you want to enable
 * this feature extend <init> and set this.textarea.style.resize = ''.
 * 
 * To start editing on a key press event, the container of the graph
 * should have focus or a focusable parent should be used to add the
 * key press handler as follows.
 * 
 * (code)
 * mxEvent.addListener(graph.container, 'keypress', mxUtils.bind(this, function(evt)
 * {
 *   if (!graph.isEditing() && !graph.isSelectionEmpty() && evt.which !== 0 &&
 *       !mxEvent.isAltDown(evt) && !mxEvent.isControlDown(evt) && !mxEvent.isMetaDown(evt))
 *   {
 *     graph.startEditing();
 *     
 *     if (mxClient.IS_FF)
 *     {
 *       graph.cellEditor.textarea.value = String.fromCharCode(evt.which);
 *     }
 *   }
 * }));
 * (end)
 * 
 * To allow focus for a DIV, and hence to receive key press events, some browsers
 * require it to have a valid tabindex attribute. In this case the following
 * code may be used to keep the container focused.
 * 
 * (code)
 * var graphFireMouseEvent = graph.fireMouseEvent;
 * graph.fireMouseEvent = function(evtName, me, sender)
 * {
 *   if (evtName == mxEvent.MOUSE_DOWN)
 *   {
 *     this.container.focus();
 *   }
 *   
 *   graphFireMouseEvent.apply(this, arguments);
 * };
 * (end)
 *
 * Constructor: mxCellEditor
 *
 * Constructs a new in-place editor for the specified graph.
 * 
 * Parameters:
 * 
 * graph - Reference to the enclosing <mxGraph>.
 */
function mxCellEditor(graph)
{
	this.graph = graph;
	
	// Stops editing after zoom changes
	this.zoomHandler = mxUtils.bind(this, function()
	{
		if (this.graph.isEditing())
		{
			this.resize();
		}
	});
	
	this.graph.view.addListener(mxEvent.SCALE, this.zoomHandler);
	this.graph.view.addListener(mxEvent.SCALE_AND_TRANSLATE, this.zoomHandler);
	
	// Adds handling of deleted cells while editing
	this.changeHandler = mxUtils.bind(this, function(sender)
	{
		if (this.editingCell != null && this.graph.getView().getState(this.editingCell) == null)
		{
			this.stopEditing(true);
		}
	});

	this.graph.getModel().addListener(mxEvent.CHANGE, this.changeHandler);
};

/**
 * Variable: graph
 * 
 * Reference to the enclosing <mxGraph>.
 */
mxCellEditor.prototype.graph = null;

/**
 * Variable: textarea
 *
 * Holds the DIV that is used for text editing. Note that this may be null before the first
 * edit. Instantiated in <init>.
 */
mxCellEditor.prototype.textarea = null;

/**
 * Variable: editingCell
 * 
 * Reference to the <mxCell> that is currently being edited.
 */
mxCellEditor.prototype.editingCell = null;

/**
 * Variable: trigger
 * 
 * Reference to the event that was used to start editing.
 */
mxCellEditor.prototype.trigger = null;

/**
 * Variable: modified
 * 
 * Specifies if the label has been modified.
 */
mxCellEditor.prototype.modified = false;

/**
 * Variable: autoSize
 * 
 * Specifies if the textarea should be resized while the text is being edited.
 * Default is true.
 */
mxCellEditor.prototype.autoSize = true;

/**
 * Variable: selectText
 * 
 * Specifies if the text should be selected when editing starts. Default is
 * true.
 */
mxCellEditor.prototype.selectText = true;

/**
 * Variable: emptyLabelText
 * 
 * Text to be displayed for empty labels. Default is '' or '<br>' in Firefox as
 * a workaround for the missing cursor bug for empty content editable. This can
 * be set to eg. "[Type Here]" to easier visualize editing of empty labels. The
 * value is only displayed before the first keystroke and is never used as the
 * actual editing value.
 */
mxCellEditor.prototype.emptyLabelText = (mxClient.IS_FF) ? '<br>' : '';

/**
 * Variable: escapeCancelsEditing
 * 
 * If true, pressing the escape key will stop editing and not accept the new
 * value. Change this to false to accept the new value on escape, and cancel
 * editing on Shift+Escape instead. Default is true.
 */
mxCellEditor.prototype.escapeCancelsEditing = true;

/**
 * Variable: textNode
 * 
 * Reference to the label DOM node that has been hidden.
 */
mxCellEditor.prototype.textNode = '';

/**
 * Variable: zIndex
 * 
 * Specifies the zIndex for the textarea. Default is 5.
 */
mxCellEditor.prototype.zIndex = 5;

/**
 * Variable: minResize
 * 
 * Defines the minimum width and height to be used in <resize>. Default is 0x20px.
 */
mxCellEditor.prototype.minResize = new mxRectangle(0, 20);

/**
 * Variable: wordWrapPadding
 * 
 * Correction factor for word wrapping width. Default is 2 in quirks, 0 in IE
 * 11 and 1 in all other browsers and modes.
 */
mxCellEditor.prototype.wordWrapPadding = (mxClient.IS_QUIRKS) ? 2 : (!mxClient.IS_IE11) ? 1 : 0;

/**
 * Variable: blurEnabled
 *
 * If <focusLost> should be called if <textarea> loses the focus. Default is false.
 */
mxCellEditor.prototype.blurEnabled = false;

/**
 * Variable: initialValue
 * 
 * Holds the initial editing value to check if the current value was modified.
 */
mxCellEditor.prototype.initialValue = null;

/**
 * Function: init
 *
 * Creates the <textarea> and installs the event listeners. The key handler
 * updates the <modified> state.
 */
mxCellEditor.prototype.init = function ()
{
	this.textarea = document.createElement('div');
	this.textarea.className = 'mxCellEditor mxPlainTextEditor';
	this.textarea.contentEditable = true;
	
	// Workaround for selection outside of DIV if height is 0
	if (mxClient.IS_GC)
	{
		this.textarea.style.minHeight = '1em';
	}
	
	this.installListeners(this.textarea);
};

/**
 * Function: applyValue
 * 
 * Called in <stopEditing> if cancel is false to invoke <mxGraph.labelChanged>.
 */
mxCellEditor.prototype.applyValue = function(state, value)
{
	this.graph.labelChanged(state.cell, value, this.trigger);
};

/**
 * Function: getInitialValue
 * 
 * Gets the initial editing value for the given cell.
 */
mxCellEditor.prototype.getInitialValue = function(state, trigger)
{
	var result = mxUtils.htmlEntities(this.graph.getEditingValue(state.cell, trigger), false);
	
    // Workaround for trailing line breaks being ignored in the editor
	if (!mxClient.IS_QUIRKS && document.documentMode != 8 && document.documentMode != 9 &&
		document.documentMode != 10)
	{
		result = mxUtils.replaceTrailingNewlines(result, '<div><br></div>');
	}
    
    return result.replace(/\n/g, '<br>');
};

/**
 * Function: getCurrentValue
 * 
 * Returns the current editing value.
 */
mxCellEditor.prototype.getCurrentValue = function(state)
{
	return mxUtils.extractTextWithWhitespace(this.textarea.childNodes);
};

/**
 * Function: installListeners
 * 
 * Installs listeners for focus, change and standard key event handling.
 */
mxCellEditor.prototype.installListeners = function(elt)
{
	// Applies value if focus is lost
	mxEvent.addListener(elt, 'blur', mxUtils.bind(this, function(evt)
	{
		if (this.blurEnabled)
		{
			this.focusLost(evt);
		}
	}));

	// Updates modified state and handles placeholder text
	mxEvent.addListener(elt, 'keydown', mxUtils.bind(this, function(evt)
	{
		if (!mxEvent.isConsumed(evt))
		{
			if (this.isStopEditingEvent(evt))
			{
				this.graph.stopEditing(false);
				mxEvent.consume(evt);
			}
			else if (evt.keyCode == 27 /* Escape */)
			{
				this.graph.stopEditing(this.escapeCancelsEditing || mxEvent.isShiftDown(evt));
				mxEvent.consume(evt);
			}
		}
	}));

	// Keypress only fires if printable key was pressed and handles removing the empty placeholder
	var keypressHandler = mxUtils.bind(this, function(evt)
	{
		if (this.editingCell != null)
		{
			// Clears the initial empty label on the first keystroke
			// and workaround for FF which fires keypress for delete and backspace
			if (this.clearOnChange && elt.innerHTML == this.getEmptyLabelText() &&
				(!mxClient.IS_FF || (evt.keyCode != 8 /* Backspace */ && evt.keyCode != 46 /* Delete */)))
			{
				this.clearOnChange = false;
				elt.innerHTML = '';
			}
		}
	});

	mxEvent.addListener(elt, 'keypress', keypressHandler);
	mxEvent.addListener(elt, 'paste', keypressHandler);
	
	// Handler for updating the empty label text value after a change
	var keyupHandler = mxUtils.bind(this, function(evt)
	{
		if (this.editingCell != null)
		{
			// Uses an optional text value for sempty labels which is cleared
			// when the first keystroke appears. This makes it easier to see
			// that a label is being edited even if the label is empty.
			// In Safari and FF, an empty text is represented by <BR> which isn't enough to force a valid size
			if (this.textarea.innerHTML.length == 0 || this.textarea.innerHTML == '<br>')
			{
				this.textarea.innerHTML = this.getEmptyLabelText();
				this.clearOnChange = this.textarea.innerHTML.length > 0;
			}
			else
			{
				this.clearOnChange = false;
			}
		}
	});

	mxEvent.addListener(elt, (!mxClient.IS_IE11 && !mxClient.IS_IE) ? 'input' : 'keyup', keyupHandler);
	mxEvent.addListener(elt, 'cut', keyupHandler);
	mxEvent.addListener(elt, 'paste', keyupHandler);

	// Adds automatic resizing of the textbox while typing using input, keyup and/or DOM change events
	var evtName = (!mxClient.IS_IE11 && !mxClient.IS_IE) ? 'input' : 'keydown';
	
	var resizeHandler = mxUtils.bind(this, function(evt)
	{
		if (this.editingCell != null && this.autoSize && !mxEvent.isConsumed(evt))
		{
			// Asynchronous is needed for keydown and shows better results for input events overall
			// (ie non-blocking and cases where the offsetWidth/-Height was wrong at this time)
			if (this.resizeThread != null)
			{
				window.clearTimeout(this.resizeThread);
			}
			
			this.resizeThread = window.setTimeout(mxUtils.bind(this, function()
			{
				this.resizeThread = null;
				this.resize();
			}), 0);
		}
	});
	
	mxEvent.addListener(elt, evtName, resizeHandler);

	if (document.documentMode >= 9)
	{
		mxEvent.addListener(elt, 'DOMNodeRemoved', resizeHandler);
		mxEvent.addListener(elt, 'DOMNodeInserted', resizeHandler);
	}
	else
	{
		mxEvent.addListener(elt, 'cut', resizeHandler);
		mxEvent.addListener(elt, 'paste', resizeHandler);
	}
};

/**
 * Function: isStopEditingEvent
 * 
 * Returns true if the given keydown event should stop cell editing. This
 * returns true if F2 is pressed of if <mxGraph.enterStopsCellEditing> is true
 * and enter is pressed without control or shift.
 */
mxCellEditor.prototype.isStopEditingEvent = function(evt)
{
	return evt.keyCode == 113 /* F2 */ || (this.graph.isEnterStopsCellEditing() &&
		evt.keyCode == 13 /* Enter */ && !mxEvent.isControlDown(evt) &&
		!mxEvent.isShiftDown(evt));
};

/**
 * Function: isEventSource
 * 
 * Returns true if this editor is the source for the given native event.
 */
mxCellEditor.prototype.isEventSource = function(evt)
{
	return mxEvent.getSource(evt) == this.textarea;
};

/**
 * Function: resize
 * 
 * Returns <modified>.
 */
mxCellEditor.prototype.resize = function()
{
	var state = this.graph.getView().getState(this.editingCell);
	
	if (state == null)
	{
		this.stopEditing(true);
	}
	else if (this.textarea != null)
	{
		var isEdge = this.graph.getModel().isEdge(state.cell);
 		var scale = this.graph.getView().scale;
 		var m = null;
		
		if (!this.autoSize || (state.style[mxConstants.STYLE_OVERFLOW] == 'fill'))
		{
			// Specifies the bounds of the editor box
			this.bounds = this.getEditorBounds(state);
			this.textarea.style.width = Math.round(this.bounds.width / scale) + 'px';
			this.textarea.style.height = Math.round(this.bounds.height / scale) + 'px';
			
			// FIXME: Offset when scaled
			if (document.documentMode == 8 || mxClient.IS_QUIRKS)
			{
				this.textarea.style.left = Math.round(this.bounds.x) + 'px';
				this.textarea.style.top = Math.round(this.bounds.y) + 'px';
			}
			else
			{
				this.textarea.style.left = Math.max(0, Math.round(this.bounds.x + 1)) + 'px';
				this.textarea.style.top = Math.max(0, Math.round(this.bounds.y + 1)) + 'px';
			}
			
			// Installs native word wrapping and avoids word wrap for empty label placeholder
			if (this.graph.isWrapping(state.cell) && (this.bounds.width >= 2 || this.bounds.height >= 2) &&
				this.textarea.innerHTML != this.getEmptyLabelText())
			{
				this.textarea.style.wordWrap = mxConstants.WORD_WRAP;
				this.textarea.style.whiteSpace = 'normal';
				
				if (state.style[mxConstants.STYLE_OVERFLOW] != 'fill')
				{
					this.textarea.style.width = Math.round(this.bounds.width / scale) + this.wordWrapPadding + 'px';
				}
			}
			else
			{
				this.textarea.style.whiteSpace = 'nowrap';
				
				if (state.style[mxConstants.STYLE_OVERFLOW] != 'fill')
				{
					this.textarea.style.width = '';
				}
			}
		}
		else
	 	{
	 		var lw = mxUtils.getValue(state.style, mxConstants.STYLE_LABEL_WIDTH, null);
			m = (state.text != null) ? state.text.margin : null;
			
			if (m == null)
			{
				m = mxUtils.getAlignmentAsPoint(mxUtils.getValue(state.style, mxConstants.STYLE_ALIGN, mxConstants.ALIGN_CENTER),
						mxUtils.getValue(state.style, mxConstants.STYLE_VERTICAL_ALIGN, mxConstants.ALIGN_MIDDLE));
			}
			
	 		if (isEdge)
			{
				this.bounds = new mxRectangle(state.absoluteOffset.x, state.absoluteOffset.y, 0, 0);
				
				if (lw != null)
			 	{
					var tmp = (parseFloat(lw) + 2) * scale;
					this.bounds.width = tmp;
					this.bounds.x += m.x * tmp;
			 	}
			}
			else
			{
				var bds = mxRectangle.fromRectangle(state);
				var hpos = mxUtils.getValue(state.style, mxConstants.STYLE_LABEL_POSITION, mxConstants.ALIGN_CENTER);
				var vpos = mxUtils.getValue(state.style, mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE);

				bds = (state.shape != null && hpos == mxConstants.ALIGN_CENTER && vpos == mxConstants.ALIGN_MIDDLE) ? state.shape.getLabelBounds(bds) : bds;
			 	
			 	if (lw != null)
			 	{
			 		bds.width = parseFloat(lw) * scale;
			 	}
			 	
			 	if (!state.view.graph.cellRenderer.legacySpacing || state.style[mxConstants.STYLE_OVERFLOW] != 'width')
			 	{
					var spacing = parseInt(state.style[mxConstants.STYLE_SPACING] || 2) * scale;
					var spacingTop = (parseInt(state.style[mxConstants.STYLE_SPACING_TOP] || 0) + mxText.prototype.baseSpacingTop) * scale + spacing;
					var spacingRight = (parseInt(state.style[mxConstants.STYLE_SPACING_RIGHT] || 0) + mxText.prototype.baseSpacingRight) * scale + spacing;
					var spacingBottom = (parseInt(state.style[mxConstants.STYLE_SPACING_BOTTOM] || 0) + mxText.prototype.baseSpacingBottom) * scale + spacing;
					var spacingLeft = (parseInt(state.style[mxConstants.STYLE_SPACING_LEFT] || 0) + mxText.prototype.baseSpacingLeft) * scale + spacing;
					
					var hpos = mxUtils.getValue(state.style, mxConstants.STYLE_LABEL_POSITION, mxConstants.ALIGN_CENTER);
					var vpos = mxUtils.getValue(state.style, mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE);

					bds = new mxRectangle(bds.x + spacingLeft, bds.y + spacingTop,
						bds.width - ((hpos == mxConstants.ALIGN_CENTER && lw == null) ? (spacingLeft + spacingRight) : 0),
						bds.height - ((vpos == mxConstants.ALIGN_MIDDLE) ? (spacingTop + spacingBottom) : 0));
			 	}

				this.bounds = new mxRectangle(bds.x + state.absoluteOffset.x, bds.y + state.absoluteOffset.y, bds.width, bds.height);
			}

			// Needed for word wrap inside text blocks with oversize lines to match the final result where
	 		// the width of the longest line is used as the reference for text alignment in the cell
	 		// TODO: Fix word wrapping preview for edge labels in helloworld.html
			if (this.graph.isWrapping(state.cell) && (this.bounds.width >= 2 || this.bounds.height >= 2) &&
				this.textarea.innerHTML != this.getEmptyLabelText())
			{
				this.textarea.style.wordWrap = mxConstants.WORD_WRAP;
				this.textarea.style.whiteSpace = 'normal';
				
		 		// Forces automatic reflow if text is removed from an oversize label and normal word wrap
				var tmp = Math.round(this.bounds.width / ((document.documentMode == 8) ? scale : scale)) + this.wordWrapPadding;
				this.textarea.style.width = tmp + 'px';
				
				if (this.textarea.scrollWidth > tmp)
				{
					this.textarea.style.width = this.textarea.scrollWidth + 'px';
				}
			}
			else
			{
				// KNOWN: Trailing cursor in IE9 quirks mode is not visible
				this.textarea.style.whiteSpace = 'nowrap';
				this.textarea.style.width = '';
			}
			
			// LATER: Keep in visible area, add fine tuning for pixel precision
			// Workaround for wrong measuring in IE8 standards
			if (document.documentMode == 8)
			{
				this.textarea.style.zoom = '1';
				this.textarea.style.height = 'auto';
			}
			
			var ow = this.textarea.scrollWidth;
			var oh = this.textarea.scrollHeight;
			
			// TODO: Update CSS width and height if smaller than minResize or remove minResize
			//if (this.minResize != null)
			//{
			//	ow = Math.max(ow, this.minResize.width);
			//	oh = Math.max(oh, this.minResize.height);
			//}
			
			// LATER: Keep in visible area, add fine tuning for pixel precision
			if (document.documentMode == 8)
			{
				// LATER: Scaled wrapping and position is wrong in IE8
				this.textarea.style.left = Math.max(0, Math.ceil((this.bounds.x - m.x * (this.bounds.width - (ow + 1) * scale) + ow * (scale - 1) * 0 + (m.x + 0.5) * 2) / scale)) + 'px';
				this.textarea.style.top = Math.max(0, Math.ceil((this.bounds.y - m.y * (this.bounds.height - (oh + 0.5) * scale) + oh * (scale - 1) * 0 + Math.abs(m.y + 0.5) * 1) / scale)) + 'px';
				// Workaround for wrong event handling width and height
				this.textarea.style.width = Math.round(ow * scale) + 'px';
				this.textarea.style.height = Math.round(oh * scale) + 'px';
			}
			else if (mxClient.IS_QUIRKS)
			{			
				this.textarea.style.left = Math.max(0, Math.ceil(this.bounds.x - m.x * (this.bounds.width - (ow + 1) * scale) + ow * (scale - 1) * 0 + (m.x + 0.5) * 2)) + 'px';
				this.textarea.style.top = Math.max(0, Math.ceil(this.bounds.y - m.y * (this.bounds.height - (oh + 0.5) * scale) + oh * (scale - 1) * 0 + Math.abs(m.y + 0.5) * 1)) + 'px';
			}
			else
			{
				this.textarea.style.left = Math.max(0, Math.round(this.bounds.x - m.x * (this.bounds.width - 2)) + 1) + 'px';
				this.textarea.style.top = Math.max(0, Math.round(this.bounds.y - m.y * (this.bounds.height - 4) + ((m.y == -1) ? 3 : 0)) + 1) + 'px';
			}
	 	}

		if (mxClient.IS_VML)
		{
			this.textarea.style.zoom = scale;
		}
		else
		{
			mxUtils.setPrefixedStyle(this.textarea.style, 'transformOrigin', '0px 0px');
			mxUtils.setPrefixedStyle(this.textarea.style, 'transform',
				'scale(' + scale + ',' + scale + ')' + ((m == null) ? '' :
				' translate(' + (m.x * 100) + '%,' + (m.y * 100) + '%)'));
		}
	}
};

/**
 * Function: focusLost
 *
 * Called if the textarea has lost focus.
 */
mxCellEditor.prototype.focusLost = function()
{
	this.stopEditing(!this.graph.isInvokesStopCellEditing());
};

/**
 * Function: getBackgroundColor
 * 
 * Returns the background color for the in-place editor. This implementation
 * always returns null.
 */
mxCellEditor.prototype.getBackgroundColor = function(state)
{
	return null;
};

/**
 * Function: startEditing
 *
 * Starts the editor for the given cell.
 * 
 * Parameters:
 * 
 * cell - <mxCell> to start editing.
 * trigger - Optional mouse event that triggered the editor.
 */
mxCellEditor.prototype.startEditing = function(cell, trigger)
{
	this.stopEditing(true);
	
	// Creates new textarea instance
	if (this.textarea == null)
	{
		this.init();
	}
	
	if (this.graph.tooltipHandler != null)
	{
		this.graph.tooltipHandler.hideTooltip();
	}
	
	var state = this.graph.getView().getState(cell);
	
	if (state != null)
	{
		// Configures the style of the in-place editor
		var scale = this.graph.getView().scale;
		var size = mxUtils.getValue(state.style, mxConstants.STYLE_FONTSIZE, mxConstants.DEFAULT_FONTSIZE);
		var family = mxUtils.getValue(state.style, mxConstants.STYLE_FONTFAMILY, mxConstants.DEFAULT_FONTFAMILY);
		var color = mxUtils.getValue(state.style, mxConstants.STYLE_FONTCOLOR, 'black');
		var align = mxUtils.getValue(state.style, mxConstants.STYLE_ALIGN, mxConstants.ALIGN_LEFT);
		var bold = (mxUtils.getValue(state.style, mxConstants.STYLE_FONTSTYLE, 0) &
				mxConstants.FONT_BOLD) == mxConstants.FONT_BOLD;
		var italic = (mxUtils.getValue(state.style, mxConstants.STYLE_FONTSTYLE, 0) &
				mxConstants.FONT_ITALIC) == mxConstants.FONT_ITALIC;
		var uline = (mxUtils.getValue(state.style, mxConstants.STYLE_FONTSTYLE, 0) &
				mxConstants.FONT_UNDERLINE) == mxConstants.FONT_UNDERLINE;
		
		this.textarea.style.lineHeight = (mxConstants.ABSOLUTE_LINE_HEIGHT) ? Math.round(size * mxConstants.LINE_HEIGHT) + 'px' : mxConstants.LINE_HEIGHT;
		this.textarea.style.backgroundColor = this.getBackgroundColor(state);
		this.textarea.style.textDecoration = (uline) ? 'underline' : '';
		this.textarea.style.fontWeight = (bold) ? 'bold' : 'normal';
		this.textarea.style.fontStyle = (italic) ? 'italic' : '';
		this.textarea.style.fontSize = Math.round(size) + 'px';
		this.textarea.style.zIndex = this.zIndex;
		this.textarea.style.fontFamily = family;
		this.textarea.style.textAlign = align;
		this.textarea.style.outline = 'none';
		this.textarea.style.color = color;
		
		var dir = this.textDirection = mxUtils.getValue(state.style, mxConstants.STYLE_TEXT_DIRECTION, mxConstants.DEFAULT_TEXT_DIRECTION);
		
		if (dir == mxConstants.TEXT_DIRECTION_AUTO)
		{
			if (state != null && state.text != null && state.text.dialect != mxConstants.DIALECT_STRICTHTML &&
				!mxUtils.isNode(state.text.value))
			{
				dir = state.text.getAutoDirection();
			}
		}
		
		if (dir == mxConstants.TEXT_DIRECTION_LTR || dir == mxConstants.TEXT_DIRECTION_RTL)
		{
			this.textarea.setAttribute('dir', dir);
		}
		else
		{
			this.textarea.removeAttribute('dir');
		}

		// Sets the initial editing value
		this.textarea.innerHTML = this.getInitialValue(state, trigger) || '';
		this.initialValue = this.textarea.innerHTML;

		// Uses an optional text value for empty labels which is cleared
		// when the first keystroke appears. This makes it easier to see
		// that a label is being edited even if the label is empty.
		if (this.textarea.innerHTML.length == 0 || this.textarea.innerHTML == '<br>')
		{
			this.textarea.innerHTML = this.getEmptyLabelText();
			this.clearOnChange = true;
		}
		else
		{
			this.clearOnChange = this.textarea.innerHTML == this.getEmptyLabelText();
		}

		this.graph.container.appendChild(this.textarea);
		
		// Update this after firing all potential events that could update the cleanOnChange flag
		this.editingCell = cell;
		this.trigger = trigger;
		this.textNode = null;

		if (state.text != null && this.isHideLabel(state))
		{
			this.textNode = state.text.node;
			this.textNode.style.visibility = 'hidden';
		}

		// Workaround for initial offsetHeight not ready for heading in markup
		if (this.autoSize && (this.graph.model.isEdge(state.cell) || state.style[mxConstants.STYLE_OVERFLOW] != 'fill'))
		{
			window.setTimeout(mxUtils.bind(this, function()
			{
				this.resize();
			}), 0);
		}
		
		this.resize();
		
		// Workaround for NS_ERROR_FAILURE in FF
		try
		{
			// Prefers blinking cursor over no selected text if empty
			this.textarea.focus();
			
			if (this.isSelectText() && this.textarea.innerHTML.length > 0 &&
				(this.textarea.innerHTML != this.getEmptyLabelText() || !this.clearOnChange))
			{
				document.execCommand('selectAll', false, null);
			}
		}
		catch (e)
		{
			// ignore
		}
	}
};

/**
 * Function: isSelectText
 * 
 * Returns <selectText>.
 */
mxCellEditor.prototype.isSelectText = function()
{
	return this.selectText;
};

/**
 * Function: stopEditing
 *
 * Stops the editor and applies the value if cancel is false.
 */
mxCellEditor.prototype.stopEditing = function(cancel)
{
	cancel = cancel || false;
	
	if (this.editingCell != null)
	{
		if (this.textNode != null)
		{
			this.textNode.style.visibility = 'visible';
			this.textNode = null;
		}

		var state = (!cancel) ? this.graph.view.getState(this.editingCell) : null;

		var initial = this.initialValue;
		this.initialValue = null;
		this.editingCell = null;
		this.trigger = null;
		this.bounds = null;
		this.textarea.blur();
		
		if (this.textarea.parentNode != null)
		{
			this.textarea.parentNode.removeChild(this.textarea);
		}
		
		if (this.clearOnChange && this.textarea.innerHTML == this.getEmptyLabelText())
		{
			this.textarea.innerHTML = '';
			this.clearOnChange = false;
		}
		
		if (state != null && this.textarea.innerHTML != initial)
		{
			this.prepareTextarea();
			var value = this.getCurrentValue(state);
			
			if (value != null)
			{
				this.applyValue(state, value);
			}
		}
		
		// Forces new instance on next edit for undo history reset
		mxEvent.release(this.textarea);
		this.textarea = null;
	}
};

/**
 * Function: prepareTextarea
 * 
 * Prepares the textarea for getting its value in <stopEditing>.
 * This implementation removes the extra trailing linefeed in Firefox.
 */
mxCellEditor.prototype.prepareTextarea = function()
{
	if (mxClient.IS_FF && this.textarea.lastChild != null &&
		this.textarea.lastChild.nodeName == 'BR')
	{
		this.textarea.removeChild(this.textarea.lastChild);
	}
};

/**
 * Function: isHideLabel
 * 
 * Returns true if the label should be hidden while the cell is being
 * edited.
 */
mxCellEditor.prototype.isHideLabel = function(state)
{
	return true;
};

/**
 * Function: getMinimumSize
 * 
 * Returns the minimum width and height for editing the given state.
 */
mxCellEditor.prototype.getMinimumSize = function(state)
{
	var scale = this.graph.getView().scale;
	
	return new mxRectangle(0, 0, (state.text == null) ? 30 : state.text.size * scale + 20,
			(this.textarea.style.textAlign == 'left') ? 120 : 40);
};

/**
 * Function: getEditorBounds
 * 
 * Returns the <mxRectangle> that defines the bounds of the editor.
 */
mxCellEditor.prototype.getEditorBounds = function(state)
{
	var isEdge = this.graph.getModel().isEdge(state.cell);
	var scale = this.graph.getView().scale;
	var minSize = this.getMinimumSize(state);
	var minWidth = minSize.width;
 	var minHeight = minSize.height;
 	var result = null;
 	
 	if (!isEdge && state.view.graph.cellRenderer.legacySpacing && state.style[mxConstants.STYLE_OVERFLOW] == 'fill')
 	{
 		result = state.shape.getLabelBounds(mxRectangle.fromRectangle(state));
 	}
 	else
 	{
		var spacing = parseInt(state.style[mxConstants.STYLE_SPACING] || 0) * scale;
		var spacingTop = (parseInt(state.style[mxConstants.STYLE_SPACING_TOP] || 0) + mxText.prototype.baseSpacingTop) * scale + spacing;
		var spacingRight = (parseInt(state.style[mxConstants.STYLE_SPACING_RIGHT] || 0) + mxText.prototype.baseSpacingRight) * scale + spacing;
		var spacingBottom = (parseInt(state.style[mxConstants.STYLE_SPACING_BOTTOM] || 0) + mxText.prototype.baseSpacingBottom) * scale + spacing;
		var spacingLeft = (parseInt(state.style[mxConstants.STYLE_SPACING_LEFT] || 0) + mxText.prototype.baseSpacingLeft) * scale + spacing;
	
	 	result = new mxRectangle(state.x, state.y,
	 		 Math.max(minWidth, state.width - spacingLeft - spacingRight),
	 		 Math.max(minHeight, state.height - spacingTop - spacingBottom));
		var hpos = mxUtils.getValue(state.style, mxConstants.STYLE_LABEL_POSITION, mxConstants.ALIGN_CENTER);
		var vpos = mxUtils.getValue(state.style, mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE);
		
		result = (state.shape != null && hpos == mxConstants.ALIGN_CENTER && vpos == mxConstants.ALIGN_MIDDLE) ? state.shape.getLabelBounds(result) : result;
	
		if (isEdge)
		{
			result.x = state.absoluteOffset.x;
			result.y = state.absoluteOffset.y;
	
			if (state.text != null && state.text.boundingBox != null)
			{
				// Workaround for label containing just spaces in which case
				// the bounding box location contains negative numbers 
				if (state.text.boundingBox.x > 0)
				{
					result.x = state.text.boundingBox.x;
				}
				
				if (state.text.boundingBox.y > 0)
				{
					result.y = state.text.boundingBox.y;
				}
			}
		}
		else if (state.text != null && state.text.boundingBox != null)
		{
			result.x = Math.min(result.x, state.text.boundingBox.x);
			result.y = Math.min(result.y, state.text.boundingBox.y);
		}
	
		result.x += spacingLeft;
		result.y += spacingTop;
	
		if (state.text != null && state.text.boundingBox != null)
		{
			if (!isEdge)
			{
				result.width = Math.max(result.width, state.text.boundingBox.width);
				result.height = Math.max(result.height, state.text.boundingBox.height);
			}
			else
			{
				result.width = Math.max(minWidth, state.text.boundingBox.width);
				result.height = Math.max(minHeight, state.text.boundingBox.height);
			}
		}
		
		// Applies the horizontal and vertical label positions
		if (this.graph.getModel().isVertex(state.cell))
		{
			var horizontal = mxUtils.getValue(state.style, mxConstants.STYLE_LABEL_POSITION, mxConstants.ALIGN_CENTER);
	
			if (horizontal == mxConstants.ALIGN_LEFT)
			{
				result.x -= state.width;
			}
			else if (horizontal == mxConstants.ALIGN_RIGHT)
			{
				result.x += state.width;
			}
	
			var vertical = mxUtils.getValue(state.style, mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE);
	
			if (vertical == mxConstants.ALIGN_TOP)
			{
				result.y -= state.height;
			}
			else if (vertical == mxConstants.ALIGN_BOTTOM)
			{
				result.y += state.height;
			}
		}
 	}
 	
 	return new mxRectangle(Math.round(result.x), Math.round(result.y), Math.round(result.width), Math.round(result.height));
};

/**
 * Function: getEmptyLabelText
 *
 * Returns the initial label value to be used of the label of the given
 * cell is empty. This label is displayed and cleared on the first keystroke.
 * This implementation returns <emptyLabelText>.
 * 
 * Parameters:
 * 
 * cell - <mxCell> for which a text for an empty editing box should be
 * returned.
 */
mxCellEditor.prototype.getEmptyLabelText = function (cell)
{
	return this.emptyLabelText;
};

/**
 * Function: getEditingCell
 *
 * Returns the cell that is currently being edited or null if no cell is
 * being edited.
 */
mxCellEditor.prototype.getEditingCell = function ()
{
	return this.editingCell;
};

/**
 * Function: destroy
 *
 * Destroys the editor and removes all associated resources.
 */
mxCellEditor.prototype.destroy = function ()
{
	if (this.textarea != null)
	{
		mxEvent.release(this.textarea);
		
		if (this.textarea.parentNode != null)
		{
			this.textarea.parentNode.removeChild(this.textarea);
		}
		
		this.textarea = null;

	}
			
	if (this.changeHandler != null)
	{
		this.graph.getModel().removeListener(this.changeHandler);
		this.changeHandler = null;
	}

	if (this.zoomHandler)
	{
		this.graph.view.removeListener(this.zoomHandler);
		this.zoomHandler = null;
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxCellRenderer
 * 
 * Renders cells into a document object model. The <defaultShapes> is a global
 * map of shapename, constructor pairs that is used in all instances. You can
 * get a list of all available shape names using the following code.
 * 
 * In general the cell renderer is in charge of creating, redrawing and
 * destroying the shape and label associated with a cell state, as well as
 * some other graphical objects, namely controls and overlays. The shape
 * hieararchy in the display (ie. the hierarchy in which the DOM nodes
 * appear in the document) does not reflect the cell hierarchy. The shapes
 * are a (flat) sequence of shapes and labels inside the draw pane of the
 * graph view, with some exceptions, namely the HTML labels being placed
 * directly inside the graph container for certain browsers.
 * 
 * (code)
 * mxLog.show();
 * for (var i in mxCellRenderer.prototype.defaultShapes)
 * {
 *   mxLog.debug(i);
 * }
 * (end)
 *
 * Constructor: mxCellRenderer
 * 
 * Constructs a new cell renderer with the following built-in shapes:
 * arrow, rectangle, ellipse, rhombus, image, line, label, cylinder,
 * swimlane, connector, actor and cloud.
 */
function mxCellRenderer() { };

/**
 * Variable: defaultEdgeShape
 * 
 * Defines the default shape for edges. Default is <mxConnector>.
 */
mxCellRenderer.prototype.defaultEdgeShape = mxConnector;

/**
 * Variable: defaultVertexShape
 * 
 * Defines the default shape for vertices. Default is <mxRectangleShape>.
 */
mxCellRenderer.prototype.defaultVertexShape = mxRectangleShape;

/**
 * Variable: defaultTextShape
 * 
 * Defines the default shape for labels. Default is <mxText>.
 */
mxCellRenderer.prototype.defaultTextShape = mxText;

/**
 * Variable: legacyControlPosition
 * 
 * Specifies if the folding icon should ignore the horizontal
 * orientation of a swimlane. Default is true.
 */
mxCellRenderer.prototype.legacyControlPosition = true;

/**
 * Variable: legacySpacing
 * 
 * Specifies if spacing and label position should be ignored if overflow is
 * fill or width. Default is true for backwards compatiblity.
 */
mxCellRenderer.prototype.legacySpacing = true;

/**
 * Variable: defaultShapes
 * 
 * Static array that contains the globally registered shapes which are
 * known to all instances of this class. For adding new shapes you should
 * use the static <mxCellRenderer.registerShape> function.
 */
mxCellRenderer.prototype.defaultShapes = new Object();

/**
 * Variable: antiAlias
 * 
 * Anti-aliasing option for new shapes. Default is true.
 */
mxCellRenderer.prototype.antiAlias = true;

/**
 * Variable: forceControlClickHandler
 * 
 * Specifies if the enabled state of the graph should be ignored in the control
 * click handler (to allow folding in disabled graphs). Default is false.
 */
mxCellRenderer.prototype.forceControlClickHandler = false;

/**
 * Function: registerShape
 * 
 * Registers the given constructor under the specified key in this instance
 * of the renderer.
 * 
 * Example:
 * 
 * (code)
 * mxCellRenderer.registerShape(mxConstants.SHAPE_RECTANGLE, mxRectangleShape);
 * (end)
 * 
 * Parameters:
 * 
 * key - String representing the shape name.
 * shape - Constructor of the <mxShape> subclass.
 */
mxCellRenderer.registerShape = function(key, shape)
{
	mxCellRenderer.prototype.defaultShapes[key] = shape;
};

// Adds default shapes into the default shapes array
mxCellRenderer.registerShape(mxConstants.SHAPE_RECTANGLE, mxRectangleShape);
mxCellRenderer.registerShape(mxConstants.SHAPE_ELLIPSE, mxEllipse);
mxCellRenderer.registerShape(mxConstants.SHAPE_RHOMBUS, mxRhombus);
mxCellRenderer.registerShape(mxConstants.SHAPE_CYLINDER, mxCylinder);
mxCellRenderer.registerShape(mxConstants.SHAPE_CONNECTOR, mxConnector);
mxCellRenderer.registerShape(mxConstants.SHAPE_ACTOR, mxActor);
mxCellRenderer.registerShape(mxConstants.SHAPE_TRIANGLE, mxTriangle);
mxCellRenderer.registerShape(mxConstants.SHAPE_HEXAGON, mxHexagon);
mxCellRenderer.registerShape(mxConstants.SHAPE_CLOUD, mxCloud);
mxCellRenderer.registerShape(mxConstants.SHAPE_LINE, mxLine);
mxCellRenderer.registerShape(mxConstants.SHAPE_ARROW, mxArrow);
mxCellRenderer.registerShape(mxConstants.SHAPE_ARROW_CONNECTOR, mxArrowConnector);
mxCellRenderer.registerShape(mxConstants.SHAPE_DOUBLE_ELLIPSE, mxDoubleEllipse);
mxCellRenderer.registerShape(mxConstants.SHAPE_SWIMLANE, mxSwimlane);
mxCellRenderer.registerShape(mxConstants.SHAPE_IMAGE, mxImageShape);
mxCellRenderer.registerShape(mxConstants.SHAPE_LABEL, mxLabel);

/**
 * Function: initializeShape
 * 
 * Initializes the shape in the given state by calling its init method with
 * the correct container after configuring it using <configureShape>.
 * 
 * Parameters:
 * 
 * state - <mxCellState> for which the shape should be initialized.
 */
mxCellRenderer.prototype.initializeShape = function(state)
{
	state.shape.dialect = state.view.graph.dialect;
	this.configureShape(state);
	state.shape.init(state.view.getDrawPane());
};

/**
 * Function: createShape
 * 
 * Creates and returns the shape for the given cell state.
 * 
 * Parameters:
 * 
 * state - <mxCellState> for which the shape should be created.
 */
mxCellRenderer.prototype.createShape = function(state)
{
	var shape = null;
	
	if (state.style != null)
	{
		// Checks if there is a stencil for the name and creates
		// a shape instance for the stencil if one exists
		var stencil = mxStencilRegistry.getStencil(state.style[mxConstants.STYLE_SHAPE]);
		
		if (stencil != null)
		{
			shape = new mxShape(stencil);
		}
		else
		{
			var ctor = this.getShapeConstructor(state);
			shape = new ctor();
		}
	}
	
	return shape;
};

/**
 * Function: createIndicatorShape
 * 
 * Creates the indicator shape for the given cell state.
 * 
 * Parameters:
 * 
 * state - <mxCellState> for which the indicator shape should be created.
 */
mxCellRenderer.prototype.createIndicatorShape = function(state)
{
	state.shape.indicatorShape = this.getShape(state.view.graph.getIndicatorShape(state));
};

/**
 * Function: getShape
 * 
 * Returns the shape for the given name from <defaultShapes>.
 */
mxCellRenderer.prototype.getShape = function(name)
{
	return (name != null) ? mxCellRenderer.prototype.defaultShapes[name] : null;
};

/**
 * Function: getShapeConstructor
 * 
 * Returns the constructor to be used for creating the shape.
 */
mxCellRenderer.prototype.getShapeConstructor = function(state)
{
	var ctor = this.getShape(state.style[mxConstants.STYLE_SHAPE]);
	
	if (ctor == null)
	{
		ctor = (state.view.graph.getModel().isEdge(state.cell)) ?
			this.defaultEdgeShape : this.defaultVertexShape;
	}
	
	return ctor;
};

/**
 * Function: configureShape
 * 
 * Configures the shape for the given cell state.
 * 
 * Parameters:
 * 
 * state - <mxCellState> for which the shape should be configured.
 */
mxCellRenderer.prototype.configureShape = function(state)
{
	state.shape.apply(state);
	state.shape.image = state.view.graph.getImage(state);
	state.shape.indicatorColor = state.view.graph.getIndicatorColor(state);
	state.shape.indicatorStrokeColor = state.style[mxConstants.STYLE_INDICATOR_STROKECOLOR];
	state.shape.indicatorGradientColor = state.view.graph.getIndicatorGradientColor(state);
	state.shape.indicatorDirection = state.style[mxConstants.STYLE_INDICATOR_DIRECTION];
	state.shape.indicatorImage = state.view.graph.getIndicatorImage(state);

	this.postConfigureShape(state);
};

/**
 * Function: postConfigureShape
 * 
 * Replaces any reserved words used for attributes, eg. inherit,
 * indicated or swimlane for colors in the shape for the given state.
 * This implementation resolves these keywords on the fill, stroke
 * and gradient color keys.
 */
mxCellRenderer.prototype.postConfigureShape = function(state)
{
	if (state.shape != null)
	{
		this.resolveColor(state, 'indicatorColor', mxConstants.STYLE_FILLCOLOR);
		this.resolveColor(state, 'indicatorGradientColor', mxConstants.STYLE_GRADIENTCOLOR);
		this.resolveColor(state, 'fill', mxConstants.STYLE_FILLCOLOR);
		this.resolveColor(state, 'stroke', mxConstants.STYLE_STROKECOLOR);
		this.resolveColor(state, 'gradient', mxConstants.STYLE_GRADIENTCOLOR);
	}
};

/**
 * Function: resolveColor
 * 
 * Resolves special keywords 'inherit', 'indicated' and 'swimlane' and sets
 * the respective color on the shape.
 */
mxCellRenderer.prototype.resolveColor = function(state, field, key)
{
	var value = state.shape[field];
	var graph = state.view.graph;
	var referenced = null;
	
	if (value == 'inherit')
	{
		referenced = graph.model.getParent(state.cell);
	}
	else if (value == 'swimlane')
	{
		if (graph.model.getTerminal(state.cell, false) != null)
		{
			referenced = graph.model.getTerminal(state.cell, false);
		}
		else
		{
			referenced = state.cell;
		}
		
		referenced = graph.getSwimlane(referenced);
		key = graph.swimlaneIndicatorColorAttribute;
	}
	else if (value == 'indicated')
	{
		state.shape[field] = state.shape.indicatorColor;
	}
	
	if (referenced != null)
	{
		var rstate = graph.getView().getState(referenced);
		state.shape[field] = null;

		if (rstate != null)
		{
			if (rstate.shape != null && field != 'indicatorColor')
			{
				state.shape[field] = rstate.shape[field];
			}
			else
			{
				state.shape[field] = rstate.style[key];
			}
		}
	}
};

/**
 * Function: getLabelValue
 * 
 * Returns the value to be used for the label.
 * 
 * Parameters:
 * 
 * state - <mxCellState> for which the label should be created.
 */
mxCellRenderer.prototype.getLabelValue = function(state)
{
	return state.view.graph.getLabel(state.cell);
};

/**
 * Function: createLabel
 * 
 * Creates the label for the given cell state.
 * 
 * Parameters:
 * 
 * state - <mxCellState> for which the label should be created.
 */
mxCellRenderer.prototype.createLabel = function(state, value)
{
	var graph = state.view.graph;
	var isEdge = graph.getModel().isEdge(state.cell);
	
	if (state.style[mxConstants.STYLE_FONTSIZE] > 0 || state.style[mxConstants.STYLE_FONTSIZE] == null)
	{
		// Avoids using DOM node for empty labels
		var isForceHtml = (graph.isHtmlLabel(state.cell) || (value != null && mxUtils.isNode(value)));

		state.text = new this.defaultTextShape(value, new mxRectangle(),
				(state.style[mxConstants.STYLE_ALIGN] || mxConstants.ALIGN_CENTER),
				graph.getVerticalAlign(state),
				state.style[mxConstants.STYLE_FONTCOLOR],
				state.style[mxConstants.STYLE_FONTFAMILY],
				state.style[mxConstants.STYLE_FONTSIZE],
				state.style[mxConstants.STYLE_FONTSTYLE],
				state.style[mxConstants.STYLE_SPACING],
				state.style[mxConstants.STYLE_SPACING_TOP],
				state.style[mxConstants.STYLE_SPACING_RIGHT],
				state.style[mxConstants.STYLE_SPACING_BOTTOM],
				state.style[mxConstants.STYLE_SPACING_LEFT],
				state.style[mxConstants.STYLE_HORIZONTAL],
				state.style[mxConstants.STYLE_LABEL_BACKGROUNDCOLOR],
				state.style[mxConstants.STYLE_LABEL_BORDERCOLOR],
				graph.isWrapping(state.cell) && graph.isHtmlLabel(state.cell),
				graph.isLabelClipped(state.cell),
				state.style[mxConstants.STYLE_OVERFLOW],
				state.style[mxConstants.STYLE_LABEL_PADDING],
				mxUtils.getValue(state.style, mxConstants.STYLE_TEXT_DIRECTION, mxConstants.DEFAULT_TEXT_DIRECTION));
		state.text.opacity = mxUtils.getValue(state.style, mxConstants.STYLE_TEXT_OPACITY, 100);
		state.text.dialect = (isForceHtml) ? mxConstants.DIALECT_STRICTHTML : state.view.graph.dialect;
		state.text.style = state.style;
		state.text.state = state;
		this.initializeLabel(state, state.text);
		
		// Workaround for touch devices routing all events for a mouse gesture
		// (down, move, up) via the initial DOM node. IE additionally redirects
		// the event via the initial DOM node but the event source is the node
		// under the mouse, so we need to check if this is the case and force
		// getCellAt for the subsequent mouseMoves and the final mouseUp.
		var forceGetCell = false;
		
		var getState = function(evt)
		{
			var result = state;

			if (mxClient.IS_TOUCH || forceGetCell)
			{
				var x = mxEvent.getClientX(evt);
				var y = mxEvent.getClientY(evt);
				
				// Dispatches the drop event to the graph which
				// consumes and executes the source function
				var pt = mxUtils.convertPoint(graph.container, x, y);
				result = graph.view.getState(graph.getCellAt(pt.x, pt.y));
			}
			
			return result;
		};
		
		// TODO: Add handling for special touch device gestures
		mxEvent.addGestureListeners(state.text.node,
			mxUtils.bind(this, function(evt)
			{
				if (this.isLabelEvent(state, evt))
				{
					graph.fireMouseEvent(mxEvent.MOUSE_DOWN, new mxMouseEvent(evt, state));
					forceGetCell = graph.dialect != mxConstants.DIALECT_SVG &&
						mxEvent.getSource(evt).nodeName == 'IMG';
				}
			}),
			mxUtils.bind(this, function(evt)
			{
				if (this.isLabelEvent(state, evt))
				{
					graph.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt, getState(evt)));
				}
			}),
			mxUtils.bind(this, function(evt)
			{
				if (this.isLabelEvent(state, evt))
				{
					graph.fireMouseEvent(mxEvent.MOUSE_UP, new mxMouseEvent(evt, getState(evt)));
					forceGetCell = false;
				}
			})
		);

		// Uses double click timeout in mxGraph for quirks mode
		if (graph.nativeDblClickEnabled)
		{
			mxEvent.addListener(state.text.node, 'dblclick',
				mxUtils.bind(this, function(evt)
				{
					if (this.isLabelEvent(state, evt))
					{
						graph.dblClick(evt, state.cell);
						mxEvent.consume(evt);
					}
				})
			);
		}
	}
};

/**
 * Function: initializeLabel
 * 
 * Initiailzes the label with a suitable container.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose label should be initialized.
 */
mxCellRenderer.prototype.initializeLabel = function(state, shape)
{
	if (mxClient.IS_SVG && mxClient.NO_FO && shape.dialect != mxConstants.DIALECT_SVG)
	{
		shape.init(state.view.graph.container);
	}
	else
	{
		shape.init(state.view.getDrawPane());
	}
};

/**
 * Function: createCellOverlays
 * 
 * Creates the actual shape for showing the overlay for the given cell state.
 * 
 * Parameters:
 * 
 * state - <mxCellState> for which the overlay should be created.
 */
mxCellRenderer.prototype.createCellOverlays = function(state)
{
	var graph = state.view.graph;
	var overlays = graph.getCellOverlays(state.cell);
	var dict = null;
	
	if (overlays != null)
	{
		dict = new mxDictionary();
		
		for (var i = 0; i < overlays.length; i++)
		{
			var shape = (state.overlays != null) ? state.overlays.remove(overlays[i]) : null;
			
			if (shape == null)
			{
				var tmp = new mxImageShape(new mxRectangle(), overlays[i].image.src);
				tmp.dialect = state.view.graph.dialect;
				tmp.preserveImageAspect = false;
				tmp.overlay = overlays[i];
				this.initializeOverlay(state, tmp);
				this.installCellOverlayListeners(state, overlays[i], tmp);
	
				if (overlays[i].cursor != null)
				{
					tmp.node.style.cursor = overlays[i].cursor;
				}
				
				dict.put(overlays[i], tmp);
			}
			else
			{
				dict.put(overlays[i], shape);
			}
		}
	}
	
	// Removes unused
	if (state.overlays != null)
	{
		state.overlays.visit(function(id, shape)
		{
			shape.destroy();
		});
	}
	
	state.overlays = dict;
};

/**
 * Function: initializeOverlay
 * 
 * Initializes the given overlay.
 * 
 * Parameters:
 * 
 * state - <mxCellState> for which the overlay should be created.
 * overlay - <mxImageShape> that represents the overlay.
 */
mxCellRenderer.prototype.initializeOverlay = function(state, overlay)
{
	overlay.init(state.view.getOverlayPane());
};

/**
 * Function: installOverlayListeners
 * 
 * Installs the listeners for the given <mxCellState>, <mxCellOverlay> and
 * <mxShape> that represents the overlay.
 */
mxCellRenderer.prototype.installCellOverlayListeners = function(state, overlay, shape)
{
	var graph  = state.view.graph;
	
	mxEvent.addListener(shape.node, 'click', function (evt)
	{
		if (graph.isEditing())
		{
			graph.stopEditing(!graph.isInvokesStopCellEditing());
		}
		
		overlay.fireEvent(new mxEventObject(mxEvent.CLICK,
				'event', evt, 'cell', state.cell));
	});
	
	mxEvent.addGestureListeners(shape.node,
		function (evt)
		{
			mxEvent.consume(evt);
		},
		function (evt)
		{
			graph.fireMouseEvent(mxEvent.MOUSE_MOVE,
				new mxMouseEvent(evt, state));
		});
	
	if (mxClient.IS_TOUCH)
	{
		mxEvent.addListener(shape.node, 'touchend', function (evt)
		{
			overlay.fireEvent(new mxEventObject(mxEvent.CLICK,
					'event', evt, 'cell', state.cell));
		});
	}
};

/**
 * Function: createControl
 * 
 * Creates the control for the given cell state.
 * 
 * Parameters:
 * 
 * state - <mxCellState> for which the control should be created.
 */
mxCellRenderer.prototype.createControl = function(state)
{
	var graph = state.view.graph;
	var image = graph.getFoldingImage(state);
	
	if (graph.foldingEnabled && image != null)
	{
		if (state.control == null)
		{
			var b = new mxRectangle(0, 0, image.width, image.height);
			state.control = new mxImageShape(b, image.src);
			state.control.preserveImageAspect = false;
			state.control.dialect = graph.dialect;

			this.initControl(state, state.control, true, this.createControlClickHandler(state));
		}
	}
	else if (state.control != null)
	{
		state.control.destroy();
		state.control = null;
	}
};

/**
 * Function: createControlClickHandler
 * 
 * Hook for creating the click handler for the folding icon.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose control click handler should be returned.
 */
mxCellRenderer.prototype.createControlClickHandler = function(state)
{
	var graph = state.view.graph;
	
	return mxUtils.bind(this, function (evt)
	{
		if (this.forceControlClickHandler || graph.isEnabled())
		{
			var collapse = !graph.isCellCollapsed(state.cell);
			graph.foldCells(collapse, false, [state.cell], null, evt);
			mxEvent.consume(evt);
		}
	});
};

/**
 * Function: initControl
 * 
 * Initializes the given control and returns the corresponding DOM node.
 * 
 * Parameters:
 * 
 * state - <mxCellState> for which the control should be initialized.
 * control - <mxShape> to be initialized.
 * handleEvents - Boolean indicating if mousedown and mousemove should fire events via the graph.
 * clickHandler - Optional function to implement clicks on the control.
 */
mxCellRenderer.prototype.initControl = function(state, control, handleEvents, clickHandler)
{
	var graph = state.view.graph;
	
	// In the special case where the label is in HTML and the display is SVG the image
	// should go into the graph container directly in order to be clickable. Otherwise
	// it is obscured by the HTML label that overlaps the cell.
	var isForceHtml = graph.isHtmlLabel(state.cell) && mxClient.NO_FO &&
		graph.dialect == mxConstants.DIALECT_SVG;

	if (isForceHtml)
	{
		control.dialect = mxConstants.DIALECT_PREFERHTML;
		control.init(graph.container);
		control.node.style.zIndex = 1;
	}
	else
	{
		control.init(state.view.getOverlayPane());
	}

	var node = control.innerNode || control.node;
	
	// Workaround for missing click event on iOS is to check tolerance below
	if (clickHandler != null && !mxClient.IS_IOS)
	{
		if (graph.isEnabled())
		{
			node.style.cursor = 'pointer';
		}
		
		mxEvent.addListener(node, 'click', clickHandler);
	}
	
	if (handleEvents)
	{
		var first = null;

		mxEvent.addGestureListeners(node,
			function (evt)
			{
				first = new mxPoint(mxEvent.getClientX(evt), mxEvent.getClientY(evt));
				graph.fireMouseEvent(mxEvent.MOUSE_DOWN, new mxMouseEvent(evt, state));
				mxEvent.consume(evt);
			},
			function (evt)
			{
				graph.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt, state));
			},
			function (evt)
			{
				graph.fireMouseEvent(mxEvent.MOUSE_UP, new mxMouseEvent(evt, state));
				mxEvent.consume(evt);
			});
		
		// Uses capture phase for event interception to stop bubble phase
		if (clickHandler != null && mxClient.IS_IOS)
		{
			node.addEventListener('touchend', function(evt)
			{
				if (first != null)
				{
					var tol = graph.tolerance;
					
					if (Math.abs(first.x - mxEvent.getClientX(evt)) < tol &&
						Math.abs(first.y - mxEvent.getClientY(evt)) < tol)
					{
						clickHandler.call(clickHandler, evt);
						mxEvent.consume(evt);
					}
				}
			}, true);
		}
	}
	
	return node;
};

/**
 * Function: isShapeEvent
 * 
 * Returns true if the event is for the shape of the given state. This
 * implementation always returns true.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose shape fired the event.
 * evt - Mouse event which was fired.
 */
mxCellRenderer.prototype.isShapeEvent = function(state, evt)
{
	return true;
};

/**
 * Function: isLabelEvent
 * 
 * Returns true if the event is for the label of the given state. This
 * implementation always returns true.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose label fired the event.
 * evt - Mouse event which was fired.
 */
mxCellRenderer.prototype.isLabelEvent = function(state, evt)
{
	return true;
};

/**
 * Function: installListeners
 * 
 * Installs the event listeners for the given cell state.
 * 
 * Parameters:
 * 
 * state - <mxCellState> for which the event listeners should be isntalled.
 */
mxCellRenderer.prototype.installListeners = function(state)
{
	var graph = state.view.graph;

	// Workaround for touch devices routing all events for a mouse
	// gesture (down, move, up) via the initial DOM node. Same for
	// HTML images in all IE versions (VML images are working).
	var getState = function(evt)
	{
		var result = state;
		
		if ((graph.dialect != mxConstants.DIALECT_SVG && mxEvent.getSource(evt).nodeName == 'IMG') || mxClient.IS_TOUCH)
		{
			var x = mxEvent.getClientX(evt);
			var y = mxEvent.getClientY(evt);
			
			// Dispatches the drop event to the graph which
			// consumes and executes the source function
			var pt = mxUtils.convertPoint(graph.container, x, y);
			result = graph.view.getState(graph.getCellAt(pt.x, pt.y));
		}
		
		return result;
	};

	mxEvent.addGestureListeners(state.shape.node,
		mxUtils.bind(this, function(evt)
		{
			if (this.isShapeEvent(state, evt))
			{
				graph.fireMouseEvent(mxEvent.MOUSE_DOWN, new mxMouseEvent(evt, state));
			}
		}),
		mxUtils.bind(this, function(evt)
		{
			if (this.isShapeEvent(state, evt))
			{
				graph.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt, getState(evt)));
			}
		}),
		mxUtils.bind(this, function(evt)
		{
			if (this.isShapeEvent(state, evt))
			{
				graph.fireMouseEvent(mxEvent.MOUSE_UP, new mxMouseEvent(evt, getState(evt)));
			}
		})
	);
	
	// Uses double click timeout in mxGraph for quirks mode
	if (graph.nativeDblClickEnabled)
	{
		mxEvent.addListener(state.shape.node, 'dblclick',
			mxUtils.bind(this, function(evt)
			{
				if (this.isShapeEvent(state, evt))
				{
					graph.dblClick(evt, state.cell);
					mxEvent.consume(evt);
				}
			})
		);
	}
};

/**
 * Function: redrawLabel
 * 
 * Redraws the label for the given cell state.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose label should be redrawn.
 */
mxCellRenderer.prototype.redrawLabel = function(state, forced)
{
	var value = this.getLabelValue(state);
	
	if (state.text == null && value != null && (mxUtils.isNode(value) || value.length > 0))
	{
		this.createLabel(state, value);
	}
	else if (state.text != null && (value == null || value.length == 0))
	{
		state.text.destroy();
		state.text = null;
	}

	if (state.text != null)
	{
		var graph = state.view.graph;

		// Forced is true if the style has changed, so to get the updated
		// result in getLabelBounds we apply the new style to the shape
		if (forced)
		{

			// Checks if a full repaint is needed
			if (state.text.lastValue != null && this.isTextShapeInvalid(state, state.text))
			{
				// Forces a full repaint
				state.text.lastValue = null;
			}
			
			state.text.resetStyles();
			state.text.apply(state);
			
			// Special case where value is obtained via hook in graph
			state.text.valign = graph.getVerticalAlign(state);
		}
		
		var bounds = this.getLabelBounds(state);
		var wrapping = graph.isWrapping(state.cell);
		var clipping = graph.isLabelClipped(state.cell);
		var isForceHtml = (state.view.graph.isHtmlLabel(state.cell) || (value != null && mxUtils.isNode(value)));
		var dialect = (isForceHtml) ? mxConstants.DIALECT_STRICTHTML : state.view.graph.dialect;

		// Text is a special case where change of dialect is possible at runtime
		var overflow = state.style[mxConstants.STYLE_OVERFLOW] || 'visible';
		
		if (forced || state.text.value != value || state.text.isWrapping != wrapping ||
			state.text.overflow != overflow || state.text.isClipping != clipping ||
			state.text.scale != this.getTextScale(state) || state.text.dialect != dialect ||
			!state.text.bounds.equals(bounds))
		{
			state.text.dialect = dialect;
			state.text.value = value;
			state.text.bounds = bounds;
			state.text.scale = this.getTextScale(state);
			state.text.wrap = wrapping;
			state.text.clipped = clipping;
			state.text.overflow = overflow;
			
			// Preserves visible state
			var vis = state.text.node.style.visibility;
			this.redrawLabelShape(state.text);
			state.text.node.style.visibility = vis;
		}
	}
};

/**
 * Function: isTextShapeInvalid
 * 
 * Returns true if the style for the text shape has changed.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose label should be checked.
 * shape - <mxText> shape to be checked.
 */
mxCellRenderer.prototype.isTextShapeInvalid = function(state, shape)
{
	function check(property, stylename, defaultValue)
	{
		// Workaround for spacing added to directional spacing
		if (stylename == 'spacingTop' || stylename == 'spacingRight' ||
			stylename == 'spacingBottom' || stylename == 'spacingLeft')
		{
			result = parseFloat(shape[property]) - parseFloat(shape.spacing) !=
				(state.style[stylename] || defaultValue);
		}
		else
		{
			result = shape[property] != (state.style[stylename] || defaultValue);
		}
		
		return result;
	};

	return check('fontStyle', mxConstants.STYLE_FONTSTYLE, mxConstants.DEFAULT_FONTSTYLE) ||
		check('family', mxConstants.STYLE_FONTFAMILY, mxConstants.DEFAULT_FONTFAMILY) ||
		check('size', mxConstants.STYLE_FONTSIZE, mxConstants.DEFAULT_FONTSIZE) ||
		check('color', mxConstants.STYLE_FONTCOLOR, 'black') ||
		check('align', mxConstants.STYLE_ALIGN, '') ||
		check('valign', mxConstants.STYLE_VERTICAL_ALIGN, '') ||
		check('spacing', mxConstants.STYLE_SPACING, 2) ||
		check('spacingTop', mxConstants.STYLE_SPACING_TOP, 0) ||
		check('spacingRight', mxConstants.STYLE_SPACING_RIGHT, 0) ||
		check('spacingBottom', mxConstants.STYLE_SPACING_BOTTOM, 0) ||
		check('spacingLeft', mxConstants.STYLE_SPACING_LEFT, 0) ||
		check('horizontal', mxConstants.STYLE_HORIZONTAL, true) ||
		check('background', mxConstants.STYLE_LABEL_BACKGROUNDCOLOR) ||
		check('border', mxConstants.STYLE_LABEL_BORDERCOLOR) ||
		check('opacity', mxConstants.STYLE_TEXT_OPACITY, 100) ||
		check('textDirection', mxConstants.STYLE_TEXT_DIRECTION, mxConstants.DEFAULT_TEXT_DIRECTION);
};

/**
 * Function: redrawLabelShape
 * 
 * Called to invoked redraw on the given text shape.
 * 
 * Parameters:
 * 
 * shape - <mxText> shape to be redrawn.
 */
mxCellRenderer.prototype.redrawLabelShape = function(shape)
{
	shape.redraw();
};

/**
 * Function: getTextScale
 * 
 * Returns the scaling used for the label of the given state
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose label scale should be returned.
 */
mxCellRenderer.prototype.getTextScale = function(state)
{
	return state.view.scale;
};

/**
 * Function: getLabelBounds
 * 
 * Returns the bounds to be used to draw the label of the given state.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose label bounds should be returned.
 */
mxCellRenderer.prototype.getLabelBounds = function(state)
{
	var graph = state.view.graph;
	var scale = state.view.scale;
	var isEdge = graph.getModel().isEdge(state.cell);
	var bounds = new mxRectangle(state.absoluteOffset.x, state.absoluteOffset.y);

	if (isEdge)
	{
		var spacing = state.text.getSpacing();
		bounds.x += spacing.x * scale;
		bounds.y += spacing.y * scale;
		
		var geo = graph.getCellGeometry(state.cell);
		
		if (geo != null)
		{
			bounds.width = Math.max(0, geo.width * scale);
			bounds.height = Math.max(0, geo.height * scale);
		}
	}
	else
	{
		// Inverts label position
		if (state.text.isPaintBoundsInverted())
		{
			var tmp = bounds.x;
			bounds.x = bounds.y;
			bounds.y = tmp;
		}
		
		bounds.x += state.x;
		bounds.y += state.y;
		
		// Minimum of 1 fixes alignment bug in HTML labels
		bounds.width = Math.max(1, state.width);
		bounds.height = Math.max(1, state.height);

		var sc = mxUtils.getValue(state.style, mxConstants.STYLE_STROKECOLOR, mxConstants.NONE);
		
		if (sc != mxConstants.NONE && sc != '')
		{
			var s = parseFloat(mxUtils.getValue(state.style, mxConstants.STYLE_STROKEWIDTH, 1)) * scale;
			var dx = 1 + Math.floor((s - 1) / 2);
			var dh = Math.floor(s + 1);
			
			bounds.x += dx;
			bounds.y += dx;
			bounds.width -= dh;
			bounds.height -= dh;
		}
	}

	if (state.text.isPaintBoundsInverted())
	{
		// Rotates around center of state
		var t = (state.width - state.height) / 2;
		bounds.x += t;
		bounds.y -= t;
		var tmp = bounds.width;
		bounds.width = bounds.height;
		bounds.height = tmp;
	}
	
	// Shape can modify its label bounds
	if (state.shape != null)
	{
		var hpos = mxUtils.getValue(state.style, mxConstants.STYLE_LABEL_POSITION, mxConstants.ALIGN_CENTER);
		var vpos = mxUtils.getValue(state.style, mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE);
		
		if (hpos == mxConstants.ALIGN_CENTER && vpos == mxConstants.ALIGN_MIDDLE)
		{
			bounds = state.shape.getLabelBounds(bounds);
		}
	}
	
	// Label width style overrides actual label width
	var lw = mxUtils.getValue(state.style, mxConstants.STYLE_LABEL_WIDTH, null);
	
	if (lw != null)
	{
		bounds.width = parseFloat(lw) * scale;
	}
	
	if (!isEdge)
	{
		this.rotateLabelBounds(state, bounds);
	}
	
	return bounds;
};

/**
 * Function: rotateLabelBounds
 * 
 * Adds the shape rotation to the given label bounds and
 * applies the alignment and offsets.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose label bounds should be rotated.
 * bounds - <mxRectangle> the rectangle to be rotated.
 */
mxCellRenderer.prototype.rotateLabelBounds = function(state, bounds)
{
	bounds.y -= state.text.margin.y * bounds.height;
	bounds.x -= state.text.margin.x * bounds.width;
	
	if (!this.legacySpacing || (state.style[mxConstants.STYLE_OVERFLOW] != 'fill' && state.style[mxConstants.STYLE_OVERFLOW] != 'width'))
	{
		var s = state.view.scale;
		var spacing = state.text.getSpacing();
		bounds.x += spacing.x * s;
		bounds.y += spacing.y * s;
		
		var hpos = mxUtils.getValue(state.style, mxConstants.STYLE_LABEL_POSITION, mxConstants.ALIGN_CENTER);
		var vpos = mxUtils.getValue(state.style, mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE);
		var lw = mxUtils.getValue(state.style, mxConstants.STYLE_LABEL_WIDTH, null);
		
		bounds.width = Math.max(0, bounds.width - ((hpos == mxConstants.ALIGN_CENTER && lw == null) ? (state.text.spacingLeft * s + state.text.spacingRight * s) : 0));
		bounds.height = Math.max(0, bounds.height - ((vpos == mxConstants.ALIGN_MIDDLE) ? (state.text.spacingTop * s + state.text.spacingBottom * s) : 0));
	}

	var theta = state.text.getTextRotation();

	// Only needed if rotated around another center
	if (theta != 0 && state != null && state.view.graph.model.isVertex(state.cell))
	{
		var cx = state.getCenterX();
		var cy = state.getCenterY();
		
		if (bounds.x != cx || bounds.y != cy)
		{
			var rad = theta * (Math.PI / 180);
			pt = mxUtils.getRotatedPoint(new mxPoint(bounds.x, bounds.y),
					Math.cos(rad), Math.sin(rad), new mxPoint(cx, cy));
			
			bounds.x = pt.x;
			bounds.y = pt.y;
		}
	}
};

/**
 * Function: redrawCellOverlays
 * 
 * Redraws the overlays for the given cell state.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose overlays should be redrawn.
 */
mxCellRenderer.prototype.redrawCellOverlays = function(state, forced)
{
	this.createCellOverlays(state);

	if (state.overlays != null)
	{
		var rot = mxUtils.mod(mxUtils.getValue(state.style, mxConstants.STYLE_ROTATION, 0), 90);
        var rad = mxUtils.toRadians(rot);
        var cos = Math.cos(rad);
        var sin = Math.sin(rad);
		
		state.overlays.visit(function(id, shape)
		{
			var bounds = shape.overlay.getBounds(state);
		
			if (!state.view.graph.getModel().isEdge(state.cell))
			{
				if (state.shape != null && rot != 0)
				{
					var cx = bounds.getCenterX();
					var cy = bounds.getCenterY();

					var point = mxUtils.getRotatedPoint(new mxPoint(cx, cy), cos, sin,
			        		new mxPoint(state.getCenterX(), state.getCenterY()));

			        cx = point.x;
			        cy = point.y;
			        bounds.x = Math.round(cx - bounds.width / 2);
			        bounds.y = Math.round(cy - bounds.height / 2);
				}
			}
			
			if (forced || shape.bounds == null || shape.scale != state.view.scale ||
				!shape.bounds.equals(bounds))
			{
				shape.bounds = bounds;
				shape.scale = state.view.scale;
				shape.redraw();
			}
		});
	}
};

/**
 * Function: redrawControl
 * 
 * Redraws the control for the given cell state.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose control should be redrawn.
 */
mxCellRenderer.prototype.redrawControl = function(state, forced)
{
	var image = state.view.graph.getFoldingImage(state);
	
	if (state.control != null && image != null)
	{
		var bounds = this.getControlBounds(state, image.width, image.height);
		var r = (this.legacyControlPosition) ?
				mxUtils.getValue(state.style, mxConstants.STYLE_ROTATION, 0) :
				state.shape.getTextRotation();
		var s = state.view.scale;
		
		if (forced || state.control.scale != s || !state.control.bounds.equals(bounds) ||
			state.control.rotation != r)
		{
			state.control.rotation = r;
			state.control.bounds = bounds;
			state.control.scale = s;
			
			state.control.redraw();
		}
	}
};

/**
 * Function: getControlBounds
 * 
 * Returns the bounds to be used to draw the control (folding icon) of the
 * given state.
 */
mxCellRenderer.prototype.getControlBounds = function(state, w, h)
{
	if (state.control != null)
	{
		var s = state.view.scale;
		var cx = state.getCenterX();
		var cy = state.getCenterY();
	
		if (!state.view.graph.getModel().isEdge(state.cell))
		{
			cx = state.x + w * s;
			cy = state.y + h * s;
			
			if (state.shape != null)
			{
				// TODO: Factor out common code
				var rot = state.shape.getShapeRotation();
				
				if (this.legacyControlPosition)
				{
					rot = mxUtils.getValue(state.style, mxConstants.STYLE_ROTATION, 0);
				}
				else
				{
					if (state.shape.isPaintBoundsInverted())
					{
						var t = (state.width - state.height) / 2;
						cx += t;
						cy -= t;
					}
				}
				
				if (rot != 0)
				{
			        var rad = mxUtils.toRadians(rot);
			        var cos = Math.cos(rad);
			        var sin = Math.sin(rad);
			        
			        var point = mxUtils.getRotatedPoint(new mxPoint(cx, cy), cos, sin,
			        		new mxPoint(state.getCenterX(), state.getCenterY()));
			        cx = point.x;
			        cy = point.y;
				}
			}
		}
		
		return (state.view.graph.getModel().isEdge(state.cell)) ? 
			new mxRectangle(Math.round(cx - w / 2 * s), Math.round(cy - h / 2 * s), Math.round(w * s), Math.round(h * s))
			: new mxRectangle(Math.round(cx - w / 2 * s), Math.round(cy - h / 2 * s), Math.round(w * s), Math.round(h * s));
	}
	
	return null;
};

/**
 * Function: insertStateAfter
 * 
 * Inserts the given array of <mxShapes> after the given nodes in the DOM.
 * 
 * Parameters:
 * 
 * shapes - Array of <mxShapes> to be inserted.
 * node - Node in <drawPane> after which the shapes should be inserted.
 * htmlNode - Node in the graph container after which the shapes should be inserted that
 * will not go into the <drawPane> (eg. HTML labels without foreignObjects).
 */
mxCellRenderer.prototype.insertStateAfter = function(state, node, htmlNode)
{
	var shapes = this.getShapesForState(state);
	
	for (var i = 0; i < shapes.length; i++)
	{
		if (shapes[i] != null && shapes[i].node != null)
		{
			var html = shapes[i].node.parentNode != state.view.getDrawPane() &&
				shapes[i].node.parentNode != state.view.getOverlayPane();
			var temp = (html) ? htmlNode : node;
			
			if (temp != null && temp.nextSibling != shapes[i].node)
			{
				if (temp.nextSibling == null)
				{
					temp.parentNode.appendChild(shapes[i].node);
				}
				else
				{
					temp.parentNode.insertBefore(shapes[i].node, temp.nextSibling);
				}
			}
			else if (temp == null)
			{
				// Special case: First HTML node should be first sibling after canvas
				if (shapes[i].node.parentNode == state.view.graph.container)
				{
					var canvas = state.view.canvas;
					
					while (canvas != null && canvas.parentNode != state.view.graph.container)
					{
						canvas = canvas.parentNode;
					}
					
					if (canvas != null && canvas.nextSibling != null)
					{
						if (canvas.nextSibling != shapes[i].node)
						{
							shapes[i].node.parentNode.insertBefore(shapes[i].node, canvas.nextSibling);
						}
					}
					else
					{
						shapes[i].node.parentNode.appendChild(shapes[i].node);
					}
				}
				else if (shapes[i].node.parentNode.firstChild != null && shapes[i].node.parentNode.firstChild != shapes[i].node)
				{
					// Inserts the node as the first child of the parent to implement the order
					shapes[i].node.parentNode.insertBefore(shapes[i].node, shapes[i].node.parentNode.firstChild);
				}
			}
			
			if (html)
			{
				htmlNode = shapes[i].node;
			}
			else
			{
				node = shapes[i].node;
			}
		}
	}

	return [node, htmlNode];
};

/**
 * Function: getShapesForState
 * 
 * Returns the <mxShapes> for the given cell state in the order in which they should
 * appear in the DOM.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose shapes should be returned.
 */
mxCellRenderer.prototype.getShapesForState = function(state)
{
	return [state.shape, state.text, state.control];
};

/**
 * Function: redraw
 * 
 * Updates the bounds or points and scale of the shapes for the given cell
 * state. This is called in mxGraphView.validatePoints as the last step of
 * updating all cells.
 * 
 * Parameters:
 * 
 * state - <mxCellState> for which the shapes should be updated.
 * force - Optional boolean that specifies if the cell should be reconfiured
 * and redrawn without any additional checks.
 * rendering - Optional boolean that specifies if the cell should actually
 * be drawn into the DOM. If this is false then redraw and/or reconfigure
 * will not be called on the shape.
 */
mxCellRenderer.prototype.redraw = function(state, force, rendering)
{
	var shapeChanged = this.redrawShape(state, force, rendering);
	
	if (state.shape != null && (rendering == null || rendering))
	{
		this.redrawLabel(state, shapeChanged);
		this.redrawCellOverlays(state, shapeChanged);
		this.redrawControl(state, shapeChanged);
	}
};

/**
 * Function: redrawShape
 * 
 * Redraws the shape for the given cell state.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose label should be redrawn.
 */
mxCellRenderer.prototype.redrawShape = function(state, force, rendering)
{
	var model = state.view.graph.model;
	var shapeChanged = false;

	// Forces creation of new shape if shape style has changed
	if (state.shape != null && state.shape.style != null && state.style != null &&
		state.shape.style[mxConstants.STYLE_SHAPE] != state.style[mxConstants.STYLE_SHAPE])
	{
		state.shape.destroy();
		state.shape = null;
	}
	
	if (state.shape == null && state.view.graph.container != null &&
		state.cell != state.view.currentRoot &&
		(model.isVertex(state.cell) || model.isEdge(state.cell)))
	{
		state.shape = this.createShape(state);
		
		if (state.shape != null)
		{
			state.shape.antiAlias = this.antiAlias;
	
			this.createIndicatorShape(state);
			this.initializeShape(state);
			this.createCellOverlays(state);
			this.installListeners(state);
			
			// Forces a refresh of the handler of one exists
			state.view.graph.selectionCellsHandler.updateHandler(state);
		}
	}
	else if (state.shape != null && !mxUtils.equalEntries(state.shape.style, state.style))
	{
		state.shape.resetStyles();
		this.configureShape(state);
		// LATER: Ignore update for realtime to fix reset of current gesture
		state.view.graph.selectionCellsHandler.updateHandler(state);
		force = true;
	}

	if (state.shape != null)
	{
		// Handles changes of the collapse icon
		this.createControl(state);
		
		// Redraws the cell if required, ignores changes to bounds if points are
		// defined as the bounds are updated for the given points inside the shape
		if (force || this.isShapeInvalid(state, state.shape))
		{
			if (state.absolutePoints != null)
			{
				state.shape.points = state.absolutePoints.slice();
				state.shape.bounds = null;
			}
			else
			{
				state.shape.points = null;
				state.shape.bounds = new mxRectangle(state.x, state.y, state.width, state.height);
			}

			state.shape.scale = state.view.scale;
			
			if (rendering == null || rendering)
			{
				state.shape.redraw();
			}
			else
			{
				state.shape.updateBoundingBox();
			}
			
			shapeChanged = true;
		}
	}

	return shapeChanged;
};

/**
 * Function: isShapeInvalid
 * 
 * Returns true if the given shape must be repainted.
 */
mxCellRenderer.prototype.isShapeInvalid = function(state, shape)
{
	return shape.bounds == null || shape.scale != state.view.scale ||
		(state.absolutePoints == null && !shape.bounds.equals(state)) ||
		(state.absolutePoints != null && !mxUtils.equalPoints(shape.points, state.absolutePoints))
};

/**
 * Function: destroy
 * 
 * Destroys the shapes associated with the given cell state.
 * 
 * Parameters:
 * 
 * state - <mxCellState> for which the shapes should be destroyed.
 */
mxCellRenderer.prototype.destroy = function(state)
{
	if (state.shape != null)
	{
		if (state.text != null)
		{		
			state.text.destroy();
			state.text = null;
		}
		
		if (state.overlays != null)
		{
			state.overlays.visit(function(id, shape)
			{
				shape.destroy();
			});
			
			state.overlays = null;
		}

		if (state.control != null)
		{
			state.control.destroy();
			state.control = null;
		}
		
		state.shape.destroy();
		state.shape = null;
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
var mxEdgeStyle =
{
	/**
	 * Class: mxEdgeStyle
	 * 
	 * Provides various edge styles to be used as the values for
	 * <mxConstants.STYLE_EDGE> in a cell style.
	 *
	 * Example:
	 * 
	 * (code)
	 * var style = stylesheet.getDefaultEdgeStyle();
	 * style[mxConstants.STYLE_EDGE] = mxEdgeStyle.ElbowConnector;
	 * (end)
	 * 
	 * Sets the default edge style to <ElbowConnector>.
	 * 
	 * Custom edge style:
	 * 
	 * To write a custom edge style, a function must be added to the mxEdgeStyle
	 * object as follows:
	 * 
	 * (code)
	 * mxEdgeStyle.MyStyle = function(state, source, target, points, result)
	 * {
	 *   if (source != null && target != null)
	 *   {
	 *     var pt = new mxPoint(target.getCenterX(), source.getCenterY());
	 * 
	 *     if (mxUtils.contains(source, pt.x, pt.y))
	 *     {
	 *       pt.y = source.y + source.height;
	 *     }
	 * 
	 *     result.push(pt);
	 *   }
	 * };
	 * (end)
	 * 
	 * In the above example, a right angle is created using a point on the
	 * horizontal center of the target vertex and the vertical center of the source
	 * vertex. The code checks if that point intersects the source vertex and makes
	 * the edge straight if it does. The point is then added into the result array,
	 * which acts as the return value of the function.
	 *
	 * The new edge style should then be registered in the <mxStyleRegistry> as follows:
	 * (code)
	 * mxStyleRegistry.putValue('myEdgeStyle', mxEdgeStyle.MyStyle);
	 * (end)
	 * 
	 * The custom edge style above can now be used in a specific edge as follows:
	 * 
	 * (code)
	 * model.setStyle(edge, 'edgeStyle=myEdgeStyle');
	 * (end)
	 * 
	 * Note that the key of the <mxStyleRegistry> entry for the function should
	 * be used in string values, unless <mxGraphView.allowEval> is true, in
	 * which case you can also use mxEdgeStyle.MyStyle for the value in the
	 * cell style above.
	 * 
	 * Or it can be used for all edges in the graph as follows:
	 * 
	 * (code)
	 * var style = graph.getStylesheet().getDefaultEdgeStyle();
	 * style[mxConstants.STYLE_EDGE] = mxEdgeStyle.MyStyle;
	 * (end)
	 * 
	 * Note that the object can be used directly when programmatically setting
	 * the value, but the key in the <mxStyleRegistry> should be used when
	 * setting the value via a key, value pair in a cell style.
	 * 
	 * Function: EntityRelation
	 * 
	 * Implements an entity relation style for edges (as used in database
	 * schema diagrams). At the time the function is called, the result
	 * array contains a placeholder (null) for the first absolute point,
	 * that is, the point where the edge and source terminal are connected.
	 * The implementation of the style then adds all intermediate waypoints
	 * except for the last point, that is, the connection point between the
	 * edge and the target terminal. The first ant the last point in the
	 * result array are then replaced with mxPoints that take into account
	 * the terminal's perimeter and next point on the edge.
	 *
	 * Parameters:
	 * 
	 * state - <mxCellState> that represents the edge to be updated.
	 * source - <mxCellState> that represents the source terminal.
	 * target - <mxCellState> that represents the target terminal.
	 * points - List of relative control points.
	 * result - Array of <mxPoints> that represent the actual points of the
	 * edge.
	 */
	 EntityRelation: function (state, source, target, points, result)
	 {
		var view = state.view;
	 	var graph = view.graph;
	 	var segment = mxUtils.getValue(state.style,
	 			mxConstants.STYLE_SEGMENT,
	 			mxConstants.ENTITY_SEGMENT) * view.scale;
	 	
		var pts = state.absolutePoints;
		var p0 = pts[0];
		var pe = pts[pts.length-1];

	 	var isSourceLeft = false;

		if (p0 != null)
		{
			source = new mxCellState();
			source.x = p0.x;
			source.y = p0.y;
		}
		else if (source != null)
		{
			var constraint = mxUtils.getPortConstraints(source, state, true, mxConstants.DIRECTION_MASK_NONE);
			
			if (constraint != mxConstants.DIRECTION_MASK_NONE && constraint != mxConstants.DIRECTION_MASK_WEST +
				mxConstants.DIRECTION_MASK_EAST)
			{
				isSourceLeft = constraint == mxConstants.DIRECTION_MASK_WEST;
			}
			else
			{
			 	var sourceGeometry = graph.getCellGeometry(source.cell);
		
			 	if (sourceGeometry.relative)
			 	{
			 		isSourceLeft = sourceGeometry.x <= 0.5;
			 	}
			 	else if (target != null)
			 	{
			 		isSourceLeft = target.x + target.width < source.x;
			 	}
			}
		}
		else
		{
			return;
		}
	 	
	 	var isTargetLeft = true;

		if (pe != null)
		{
			target = new mxCellState();
			target.x = pe.x;
			target.y = pe.y;
		}
		else if (target != null)
	 	{
			var constraint = mxUtils.getPortConstraints(target, state, false, mxConstants.DIRECTION_MASK_NONE);

			if (constraint != mxConstants.DIRECTION_MASK_NONE && constraint != mxConstants.DIRECTION_MASK_WEST +
				mxConstants.DIRECTION_MASK_EAST)
			{
				isTargetLeft = constraint == mxConstants.DIRECTION_MASK_WEST;
			}
			else
			{
			 	var targetGeometry = graph.getCellGeometry(target.cell);
	
			 	if (targetGeometry.relative)
			 	{
			 		isTargetLeft = targetGeometry.x <= 0.5;
			 	}
			 	else if (source != null)
			 	{
			 		isTargetLeft = source.x + source.width < target.x;
			 	}
			}
	 	}
		
		if (source != null && target != null)
		{
			var x0 = (isSourceLeft) ? source.x : source.x + source.width;
			var y0 = view.getRoutingCenterY(source);
			
			var xe = (isTargetLeft) ? target.x : target.x + target.width;
			var ye = view.getRoutingCenterY(target);
	
			var seg = segment;
	
			var dx = (isSourceLeft) ? -seg : seg;
			var dep = new mxPoint(x0 + dx, y0);
					
			dx = (isTargetLeft) ? -seg : seg;
			var arr = new mxPoint(xe + dx, ye);
	
			// Adds intermediate points if both go out on same side
			if (isSourceLeft == isTargetLeft)
			{
				var x = (isSourceLeft) ?
					Math.min(x0, xe)-segment :
					Math.max(x0, xe)+segment;
	
				result.push(new mxPoint(x, y0));
				result.push(new mxPoint(x, ye));
			}
			else if ((dep.x < arr.x) == isSourceLeft)
			{
				var midY = y0 + (ye - y0) / 2;
	
				result.push(dep);
				result.push(new mxPoint(dep.x, midY));
				result.push(new mxPoint(arr.x, midY));
				result.push(arr);
			}
			else
			{
				result.push(dep);
				result.push(arr);
			}
		}
	 },

	 /**
	 * Function: Loop
	 * 
	 * Implements a self-reference, aka. loop.
	 */
	Loop: function (state, source, target, points, result)
	{
		var pts = state.absolutePoints;
		
		var p0 = pts[0];
		var pe = pts[pts.length-1];

		if (p0 != null && pe != null)
		{
			if (points != null && points.length > 0)
			{
				for (var i = 0; i < points.length; i++)
				{
					var pt = points[i];
					pt = state.view.transformControlPoint(state, pt);
					result.push(new mxPoint(pt.x, pt.y));
				}
			}

			return;
		}
		
		if (source != null)
		{
			var view = state.view;
			var graph = view.graph;
			var pt = (points != null && points.length > 0) ? points[0] : null;

			if (pt != null)
			{
				pt = view.transformControlPoint(state, pt);
					
				if (mxUtils.contains(source, pt.x, pt.y))
				{
					pt = null;
				}
			}
			
			var x = 0;
			var dx = 0;
			var y = 0;
			var dy = 0;
			
		 	var seg = mxUtils.getValue(state.style, mxConstants.STYLE_SEGMENT,
		 		graph.gridSize) * view.scale;
			var dir = mxUtils.getValue(state.style, mxConstants.STYLE_DIRECTION,
				mxConstants.DIRECTION_WEST);
			
			if (dir == mxConstants.DIRECTION_NORTH ||
				dir == mxConstants.DIRECTION_SOUTH)
			{
				x = view.getRoutingCenterX(source);
				dx = seg;
			}
			else
			{
				y = view.getRoutingCenterY(source);
				dy = seg;
			}
			
			if (pt == null ||
				pt.x < source.x ||
				pt.x > source.x + source.width)
			{
				if (pt != null)
				{
					x = pt.x;
					dy = Math.max(Math.abs(y - pt.y), dy);
				}
				else
				{
					if (dir == mxConstants.DIRECTION_NORTH)
					{
						y = source.y - 2 * dx;
					}
					else if (dir == mxConstants.DIRECTION_SOUTH)
					{
						y = source.y + source.height + 2 * dx;
					}
					else if (dir == mxConstants.DIRECTION_EAST)
					{
						x = source.x - 2 * dy;
					}
					else
					{
						x = source.x + source.width + 2 * dy;
					}
				}
			}
			else if (pt != null)
			{
				x = view.getRoutingCenterX(source);
				dx = Math.max(Math.abs(x - pt.x), dy);
				y = pt.y;
				dy = 0;
			}
			
			result.push(new mxPoint(x - dx, y - dy));
			result.push(new mxPoint(x + dx, y + dy));
		}
	},
	
	/**
	 * Function: ElbowConnector
	 * 
	 * Uses either <SideToSide> or <TopToBottom> depending on the horizontal
	 * flag in the cell style. <SideToSide> is used if horizontal is true or
	 * unspecified. See <EntityRelation> for a description of the
	 * parameters.
	 */
	ElbowConnector: function (state, source, target, points, result)
	{
		var pt = (points != null && points.length > 0) ? points[0] : null;

		var vertical = false;
		var horizontal = false;
		
		if (source != null && target != null)
		{
			if (pt != null)
			{
				var left = Math.min(source.x, target.x);
				var right = Math.max(source.x + source.width,
					target.x + target.width);
	
				var top = Math.min(source.y, target.y);
				var bottom = Math.max(source.y + source.height,
					target.y + target.height);

				pt = state.view.transformControlPoint(state, pt);
					
				vertical = pt.y < top || pt.y > bottom;
				horizontal = pt.x < left || pt.x > right;
			}
			else
			{
				var left = Math.max(source.x, target.x);
				var right = Math.min(source.x + source.width,
					target.x + target.width);
					
				vertical = left == right;
				
				if (!vertical)
				{
					var top = Math.max(source.y, target.y);
					var bottom = Math.min(source.y + source.height,
						target.y + target.height);
						
					horizontal = top == bottom;
				}
			}
		}

		if (!horizontal && (vertical ||
			state.style[mxConstants.STYLE_ELBOW] == mxConstants.ELBOW_VERTICAL))
		{
			mxEdgeStyle.TopToBottom(state, source, target, points, result);
		}
		else
		{
			mxEdgeStyle.SideToSide(state, source, target, points, result);
		}
	},

	/**
	 * Function: SideToSide
	 * 
	 * Implements a vertical elbow edge. See <EntityRelation> for a description
	 * of the parameters.
	 */
	SideToSide: function (state, source, target, points, result)
	{
		var view = state.view;
		var pt = (points != null && points.length > 0) ? points[0] : null;
		var pts = state.absolutePoints;
		var p0 = pts[0];
		var pe = pts[pts.length-1];
		
		if (pt != null)
		{
			pt = view.transformControlPoint(state, pt);
		}
		
		if (p0 != null)
		{
			source = new mxCellState();
			source.x = p0.x;
			source.y = p0.y;
		}
		
		if (pe != null)
		{
			target = new mxCellState();
			target.x = pe.x;
			target.y = pe.y;
		}
		
		if (source != null && target != null)
		{
			var l = Math.max(source.x, target.x);
			var r = Math.min(source.x + source.width,
							 target.x + target.width);
	
			var x = (pt != null) ? pt.x : Math.round(r + (l - r) / 2);
	
			var y1 = view.getRoutingCenterY(source);
			var y2 = view.getRoutingCenterY(target);
	
			if (pt != null)
			{
				if (pt.y >= source.y && pt.y <= source.y + source.height)
				{
					y1 = pt.y;
				}
				
				if (pt.y >= target.y && pt.y <= target.y + target.height)
				{
					y2 = pt.y;
				}
			}
			
			if (!mxUtils.contains(target, x, y1) &&
				!mxUtils.contains(source, x, y1))
			{
				result.push(new mxPoint(x,  y1));
			}
	
			if (!mxUtils.contains(target, x, y2) &&
				!mxUtils.contains(source, x, y2))
			{
				result.push(new mxPoint(x, y2));
			}
	
			if (result.length == 1)
			{
				if (pt != null)
				{
					if (!mxUtils.contains(target, x, pt.y) &&
						!mxUtils.contains(source, x, pt.y))
					{
						result.push(new mxPoint(x, pt.y));
					}
				}
				else
				{	
					var t = Math.max(source.y, target.y);
					var b = Math.min(source.y + source.height,
							 target.y + target.height);
						 
					result.push(new mxPoint(x, t + (b - t) / 2));
				}
			}
		}
	},

	/**
	 * Function: TopToBottom
	 * 
	 * Implements a horizontal elbow edge. See <EntityRelation> for a
	 * description of the parameters.
	 */
	TopToBottom: function(state, source, target, points, result)
	{
		var view = state.view;
		var pt = (points != null && points.length > 0) ? points[0] : null;
		var pts = state.absolutePoints;
		var p0 = pts[0];
		var pe = pts[pts.length-1];
		
		if (pt != null)
		{
			pt = view.transformControlPoint(state, pt);
		}
		
		if (p0 != null)
		{
			source = new mxCellState();
			source.x = p0.x;
			source.y = p0.y;
		}
		
		if (pe != null)
		{
			target = new mxCellState();
			target.x = pe.x;
			target.y = pe.y;
		}

		if (source != null && target != null)
		{
			var t = Math.max(source.y, target.y);
			var b = Math.min(source.y + source.height,
							 target.y + target.height);
	
			var x = view.getRoutingCenterX(source);
			
			if (pt != null &&
				pt.x >= source.x &&
				pt.x <= source.x + source.width)
			{
				x = pt.x;
			}
			
			var y = (pt != null) ? pt.y : Math.round(b + (t - b) / 2);
			
			if (!mxUtils.contains(target, x, y) &&
				!mxUtils.contains(source, x, y))
			{
				result.push(new mxPoint(x, y));						
			}
			
			if (pt != null &&
				pt.x >= target.x &&
				pt.x <= target.x + target.width)
			{
				x = pt.x;
			}
			else
			{
				x = view.getRoutingCenterX(target);
			}
			
			if (!mxUtils.contains(target, x, y) &&
				!mxUtils.contains(source, x, y))
			{
				result.push(new mxPoint(x, y));						
			}
			
			if (result.length == 1)
			{
				if (pt != null && result.length == 1)
				{
					if (!mxUtils.contains(target, pt.x, y) &&
						!mxUtils.contains(source, pt.x, y))
					{
						result.push(new mxPoint(pt.x, y));
					}
				}
				else
				{
					var l = Math.max(source.x, target.x);
					var r = Math.min(source.x + source.width,
							 target.x + target.width);
						 
					result.push(new mxPoint(l + (r - l) / 2, y));
				}
			}
		}
	},

	/**
	 * Function: SegmentConnector
	 * 
	 * Implements an orthogonal edge style. Use <mxEdgeSegmentHandler>
	 * as an interactive handler for this style.
	 */
	SegmentConnector: function(state, source, target, hints, result)
	{
		// Creates array of all way- and terminalpoints
		var pts = state.absolutePoints;
		var tol = Math.max(1, state.view.scale);
		
		// Whether the first segment outgoing from the source end is horizontal
		var lastPushed = (result.length > 0) ? result[0] : null;
		var horizontal = true;
		var hint = null;
		
		// Adds waypoints only if outside of tolerance
		function pushPoint(pt)
		{
			if (lastPushed == null || Math.abs(lastPushed.x - pt.x) >= tol || Math.abs(lastPushed.y - pt.y) >= tol)
			{
				result.push(pt);
				lastPushed = pt;
			}
			
			return lastPushed;
		};

		// Adds the first point
		var pt = pts[0];
		
		if (pt == null && source != null)
		{
			pt = new mxPoint(state.view.getRoutingCenterX(source), state.view.getRoutingCenterY(source));
		}
		else if (pt != null)
		{
			pt = pt.clone();
		}
		
		pt.x = Math.round(pt.x);
		pt.y = Math.round(pt.y);
		
		var lastInx = pts.length - 1;

		// Adds the waypoints
		if (hints != null && hints.length > 0)
		{
			// Converts all hints and removes nulls
			var newHints = [];
			
			for (var i = 0; i < hints.length; i++)
			{
				var tmp = state.view.transformControlPoint(state, hints[i]);
				
				if (tmp != null)
				{
					tmp.x = Math.round(tmp.x);
					tmp.y = Math.round(tmp.y);
					newHints.push(tmp);
				}
			}
			
			if (newHints.length == 0)
			{
				return;
			}
			
			hints = newHints;
			
			// Aligns source and target hint to fixed points
			if (pt != null && hints[0] != null)
			{
				if (Math.abs(hints[0].x - pt.x) < tol)
				{
					hints[0].x = pt.x;
				}
				
				if (Math.abs(hints[0].y - pt.y) < tol)
				{
					hints[0].y = pt.y;
				}
			}
			
			var pe = pts[lastInx];
			
			if (pe != null && hints[hints.length - 1] != null)
			{
				if (Math.abs(hints[hints.length - 1].x - pe.x) < tol)
				{
					hints[hints.length - 1].x = pe.x;
				}
				
				if (Math.abs(hints[hints.length - 1].y - pe.y) < tol)
				{
					hints[hints.length - 1].y = pe.y;
				}
			}
			
			hint = hints[0];

			var currentTerm = source;
			var currentPt = pts[0];
			var hozChan = false;
			var vertChan = false;
			var currentHint = hint;
			
			if (currentPt != null)
			{
				currentPt.x = Math.round(currentPt.x);
				currentPt.y = Math.round(currentPt.y);
				currentTerm = null;
			}
			
			// Check for alignment with fixed points and with channels
			// at source and target segments only
			for (var i = 0; i < 2; i++)
			{
				var fixedVertAlign = currentPt != null && currentPt.x == currentHint.x;
				var fixedHozAlign = currentPt != null && currentPt.y == currentHint.y;
				
				var inHozChan = currentTerm != null && (currentHint.y >= currentTerm.y &&
						currentHint.y <= currentTerm.y + currentTerm.height);
				var inVertChan = currentTerm != null && (currentHint.x >= currentTerm.x &&
						currentHint.x <= currentTerm.x + currentTerm.width);

				hozChan = fixedHozAlign || (currentPt == null && inHozChan);
				vertChan = fixedVertAlign || (currentPt == null && inVertChan);
				
				// If the current hint falls in both the hor and vert channels in the case
				// of a floating port, or if the hint is exactly co-incident with a 
				// fixed point, ignore the source and try to work out the orientation
				// from the target end
				if (i==0 && ((hozChan && vertChan) || (fixedVertAlign && fixedHozAlign)))
				{
				}
				else
				{
					if (currentPt != null && (!fixedHozAlign && !fixedVertAlign) && (inHozChan || inVertChan)) 
					{
						horizontal = inHozChan ? false : true;
						break;
					}
			
					if (vertChan || hozChan)
					{
						horizontal = hozChan;
						
						if (i == 1)
						{
							// Work back from target end
							horizontal = hints.length % 2 == 0 ? hozChan : vertChan;
						}
	
						break;
					}
				}
				
				currentTerm = target;
				currentPt = pts[lastInx];
				
				if (currentPt != null)
				{
					currentPt.x = Math.round(currentPt.x);
					currentPt.y = Math.round(currentPt.y);
					currentTerm = null;
				}
				
				currentHint = hints[hints.length - 1];
				
				if (fixedVertAlign && fixedHozAlign)
				{
					hints = hints.slice(1);
				}
			}

			if (horizontal && ((pts[0] != null && pts[0].y != hint.y) ||
				(pts[0] == null && source != null &&
				(hint.y < source.y || hint.y > source.y + source.height))))
			{
				pushPoint(new mxPoint(pt.x, hint.y));
			}
			else if (!horizontal && ((pts[0] != null && pts[0].x != hint.x) ||
					(pts[0] == null && source != null &&
					(hint.x < source.x || hint.x > source.x + source.width))))
			{
				pushPoint(new mxPoint(hint.x, pt.y));
			}
			
			if (horizontal)
			{
				pt.y = hint.y;
			}
			else
			{
				pt.x = hint.x;
			}
		
			for (var i = 0; i < hints.length; i++)
			{
				horizontal = !horizontal;
				hint = hints[i];
				
//				mxLog.show();
//				mxLog.debug('hint', i, hint.x, hint.y);
				
				if (horizontal)
				{
					pt.y = hint.y;
				}
				else
				{
					pt.x = hint.x;
				}
		
				pushPoint(pt.clone());
			}
		}
		else
		{
			hint = pt;
			// FIXME: First click in connect preview toggles orientation
			horizontal = true;
		}

		// Adds the last point
		pt = pts[lastInx];

		if (pt == null && target != null)
		{
			pt = new mxPoint(state.view.getRoutingCenterX(target), state.view.getRoutingCenterY(target));
		}
		
		if (pt != null)
		{
			pt.x = Math.round(pt.x);
			pt.y = Math.round(pt.y);
			
			if (hint != null)
			{
				if (horizontal && ((pts[lastInx] != null && pts[lastInx].y != hint.y) ||
					(pts[lastInx] == null && target != null &&
					(hint.y < target.y || hint.y > target.y + target.height))))
				{
					pushPoint(new mxPoint(pt.x, hint.y));
				}
				else if (!horizontal && ((pts[lastInx] != null && pts[lastInx].x != hint.x) ||
						(pts[lastInx] == null && target != null &&
						(hint.x < target.x || hint.x > target.x + target.width))))
				{
					pushPoint(new mxPoint(hint.x, pt.y));
				}
			}
		}
		
		// Removes bends inside the source terminal for floating ports
		if (pts[0] == null && source != null)
		{
			while (result.length > 1 && result[1] != null &&
				mxUtils.contains(source, result[1].x, result[1].y))
			{
				result.splice(1, 1);
			}
		}
		
		// Removes bends inside the target terminal
		if (pts[lastInx] == null && target != null)
		{
			while (result.length > 1 && result[result.length - 1] != null &&
				mxUtils.contains(target, result[result.length - 1].x, result[result.length - 1].y))
			{
				result.splice(result.length - 1, 1);
			}
		}
		
		// Removes last point if inside tolerance with end point
		if (pe != null && result[result.length - 1] != null &&
			Math.abs(pe.x - result[result.length - 1].x) < tol &&
			Math.abs(pe.y - result[result.length - 1].y) < tol)
		{
			result.splice(result.length - 1, 1);
			
			// Lines up second last point in result with end point
			if (result[result.length - 1] != null)
			{
				if (Math.abs(result[result.length - 1].x - pe.x) < tol)
				{
					result[result.length - 1].x = pe.x;
				}
				
				if (Math.abs(result[result.length - 1].y - pe.y) < tol)
				{
					result[result.length - 1].y = pe.y;
				}
			}
		}
	},
	
	orthBuffer: 10,
	
	orthPointsFallback: true,

	dirVectors: [ [ -1, 0 ],
			[ 0, -1 ], [ 1, 0 ], [ 0, 1 ], [ -1, 0 ], [ 0, -1 ], [ 1, 0 ] ],

	wayPoints1: [ [ 0, 0], [ 0, 0],  [ 0, 0], [ 0, 0], [ 0, 0],  [ 0, 0],
	              [ 0, 0],  [ 0, 0], [ 0, 0],  [ 0, 0], [ 0, 0],  [ 0, 0] ],

	routePatterns: [
		[ [ 513, 2308, 2081, 2562 ], [ 513, 1090, 514, 2184, 2114, 2561 ],
			[ 513, 1090, 514, 2564, 2184, 2562 ],
			[ 513, 2308, 2561, 1090, 514, 2568, 2308 ] ],
	[ [ 514, 1057, 513, 2308, 2081, 2562 ], [ 514, 2184, 2114, 2561 ],
			[ 514, 2184, 2562, 1057, 513, 2564, 2184 ],
			[ 514, 1057, 513, 2568, 2308, 2561 ] ],
	[ [ 1090, 514, 1057, 513, 2308, 2081, 2562 ], [ 2114, 2561 ],
			[ 1090, 2562, 1057, 513, 2564, 2184 ],
			[ 1090, 514, 1057, 513, 2308, 2561, 2568 ] ],
	[ [ 2081, 2562 ], [ 1057, 513, 1090, 514, 2184, 2114, 2561 ],
			[ 1057, 513, 1090, 514, 2184, 2562, 2564 ],
			[ 1057, 2561, 1090, 514, 2568, 2308 ] ] ],
	
	inlineRoutePatterns: [
			[ null, [ 2114, 2568 ], null, null ],
			[ null, [ 514, 2081, 2114, 2568 ] , null, null ],
			[ null, [ 2114, 2561 ], null, null ],
			[ [ 2081, 2562 ], [ 1057, 2114, 2568 ],
					[ 2184, 2562 ],
					null ] ],
	vertexSeperations: [],

	limits: [
	       [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
	       [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ] ],

	LEFT_MASK: 32,

	TOP_MASK: 64,

	RIGHT_MASK: 128,

	BOTTOM_MASK: 256,

	LEFT: 1,

	TOP: 2,

	RIGHT: 4,

	BOTTOM: 8,

	// TODO remove magic numbers
	SIDE_MASK: 480,
	//mxEdgeStyle.LEFT_MASK | mxEdgeStyle.TOP_MASK | mxEdgeStyle.RIGHT_MASK
	//| mxEdgeStyle.BOTTOM_MASK,

	CENTER_MASK: 512,

	SOURCE_MASK: 1024,

	TARGET_MASK: 2048,

	VERTEX_MASK: 3072,
	// mxEdgeStyle.SOURCE_MASK | mxEdgeStyle.TARGET_MASK,
	
	getJettySize: function(state, source, target, points, isSource)
	{
		var value = mxUtils.getValue(state.style, (isSource) ? mxConstants.STYLE_SOURCE_JETTY_SIZE :
			mxConstants.STYLE_TARGET_JETTY_SIZE, mxUtils.getValue(state.style,
					mxConstants.STYLE_JETTY_SIZE, mxEdgeStyle.orthBuffer));
		
		if (value == 'auto')
		{
			// Computes the automatic jetty size
			var type = mxUtils.getValue(state.style, (isSource) ? mxConstants.STYLE_STARTARROW : mxConstants.STYLE_ENDARROW, mxConstants.NONE);
			
			if (type != mxConstants.NONE)
			{
				var size = mxUtils.getNumber(state.style, (isSource) ? mxConstants.STYLE_STARTSIZE : mxConstants.STYLE_ENDSIZE, mxConstants.DEFAULT_MARKERSIZE);
				value = Math.max(2, Math.ceil((size + mxEdgeStyle.orthBuffer) / mxEdgeStyle.orthBuffer)) * mxEdgeStyle.orthBuffer;
			}
			else
			{
				value = 2 * mxEdgeStyle.orthBuffer;
			}
		}
		
		return value;
	},

	/**
	 * Function: OrthConnector
	 * 
	 * Implements a local orthogonal router between the given
	 * cells.
	 * 
	 * Parameters:
	 * 
	 * state - <mxCellState> that represents the edge to be updated.
	 * source - <mxCellState> that represents the source terminal.
	 * target - <mxCellState> that represents the target terminal.
	 * points - List of relative control points.
	 * result - Array of <mxPoints> that represent the actual points of the
	 * edge.
	 * 
	 */
	OrthConnector: function(state, source, target, points, result)
	{
		var graph = state.view.graph;
		var sourceEdge = source == null ? false : graph.getModel().isEdge(source.cell);
		var targetEdge = target == null ? false : graph.getModel().isEdge(target.cell);

		var pts = state.absolutePoints;
		var p0 = pts[0];
		var pe = pts[pts.length-1];

		var sourceX = source != null ? source.x : p0.x;
		var sourceY = source != null ? source.y : p0.y;
		var sourceWidth = source != null ? source.width : 0;
		var sourceHeight = source != null ? source.height : 0;
		
		var targetX = target != null ? target.x : pe.x;
		var targetY = target != null ? target.y : pe.y;
		var targetWidth = target != null ? target.width : 0;
		var targetHeight = target != null ? target.height : 0;

		var scaledSourceBuffer = state.view.scale * mxEdgeStyle.getJettySize(state, source, target, points, true);
		var scaledTargetBuffer = state.view.scale * mxEdgeStyle.getJettySize(state, source, target, points, false);
		
		// Workaround for loop routing within buffer zone
		if (source != null && target == source)
		{
			scaledTargetBuffer = Math.max(scaledSourceBuffer, scaledTargetBuffer);
			scaledSourceBuffer = scaledTargetBuffer;
		}
		
		var totalBuffer = scaledTargetBuffer + scaledSourceBuffer;
		var tooShort = false;
		
		// Checks minimum distance for fixed points and falls back to segment connector
		if (p0 != null && pe != null)
		{
			var dx = pe.x - p0.x;
			var dy = pe.y - p0.y;
			
			tooShort = dx * dx + dy * dy < totalBuffer * totalBuffer;
		}

		if (tooShort || (mxEdgeStyle.orthPointsFallback && (points != null &&
			points.length > 0)) || sourceEdge || targetEdge)
		{
			mxEdgeStyle.SegmentConnector(state, source, target, points, result);
			
			return;
		}

		// Determine the side(s) of the source and target vertices
		// that the edge may connect to
		// portConstraint [source, target]
		var portConstraint = [mxConstants.DIRECTION_MASK_ALL, mxConstants.DIRECTION_MASK_ALL];
		var rotation = 0;
		
		if (source != null)
		{
			portConstraint[0] = mxUtils.getPortConstraints(source, state, true, 
					mxConstants.DIRECTION_MASK_ALL);
			rotation = mxUtils.getValue(source.style, mxConstants.STYLE_ROTATION, 0);
			
			if (rotation != 0)
			{
				var newRect = mxUtils.getBoundingBox(new mxRectangle(sourceX, sourceY, sourceWidth, sourceHeight), rotation);
				sourceX = newRect.x; 
				sourceY = newRect.y;
				sourceWidth = newRect.width;
				sourceHeight = newRect.height;
			}
		}

		if (target != null)
		{
			portConstraint[1] = mxUtils.getPortConstraints(target, state, false,
				mxConstants.DIRECTION_MASK_ALL);
			rotation = mxUtils.getValue(target.style, mxConstants.STYLE_ROTATION, 0);

			if (rotation != 0)
			{
				var newRect = mxUtils.getBoundingBox(new mxRectangle(targetX, targetY, targetWidth, targetHeight), rotation);
				targetX = newRect.x;
				targetY = newRect.y;
				targetWidth = newRect.width;
				targetHeight = newRect.height;
			}
		}

		// Avoids floating point number errors
		sourceX = Math.round(sourceX * 10) / 10;
		sourceY = Math.round(sourceY * 10) / 10;
		sourceWidth = Math.round(sourceWidth * 10) / 10;
		sourceHeight = Math.round(sourceHeight * 10) / 10;
		
		targetX = Math.round(targetX * 10) / 10;
		targetY = Math.round(targetY * 10) / 10;
		targetWidth = Math.round(targetWidth * 10) / 10;
		targetHeight = Math.round(targetHeight * 10) / 10;
		
		var dir = [0, 0];

		// Work out which faces of the vertices present against each other
		// in a way that would allow a 3-segment connection if port constraints
		// permitted.
		// geo -> [source, target] [x, y, width, height]
		var geo = [ [sourceX, sourceY, sourceWidth, sourceHeight] ,
		            [targetX, targetY, targetWidth, targetHeight] ];
		var buffer = [scaledSourceBuffer, scaledTargetBuffer];

		for (var i = 0; i < 2; i++)
		{
			mxEdgeStyle.limits[i][1] = geo[i][0] - buffer[i];
			mxEdgeStyle.limits[i][2] = geo[i][1] - buffer[i];
			mxEdgeStyle.limits[i][4] = geo[i][0] + geo[i][2] + buffer[i];
			mxEdgeStyle.limits[i][8] = geo[i][1] + geo[i][3] + buffer[i];
		}
		
		// Work out which quad the target is in
		var sourceCenX = geo[0][0] + geo[0][2] / 2.0;
		var sourceCenY = geo[0][1] + geo[0][3] / 2.0;
		var targetCenX = geo[1][0] + geo[1][2] / 2.0;
		var targetCenY = geo[1][1] + geo[1][3] / 2.0;
		
		var dx = sourceCenX - targetCenX;
		var dy = sourceCenY - targetCenY;

		var quad = 0;

		if (dx < 0)
		{
			if (dy < 0)
			{
				quad = 2;
			}
			else
			{
				quad = 1;
			}
		}
		else
		{
			if (dy <= 0)
			{
				quad = 3;
				
				// Special case on x = 0 and negative y
				if (dx == 0)
				{
					quad = 2;
				}
			}
		}

		// Check for connection constraints
		var currentTerm = null;
		
		if (source != null)
		{
			currentTerm = p0;
		}

		var constraint = [ [0.5, 0.5] , [0.5, 0.5] ];

		for (var i = 0; i < 2; i++)
		{
			if (currentTerm != null)
			{
				constraint[i][0] = (currentTerm.x - geo[i][0]) / geo[i][2];
				
				if (Math.abs(currentTerm.x - geo[i][0]) <= 1)
				{
					dir[i] = mxConstants.DIRECTION_MASK_WEST;
				}
				else if (Math.abs(currentTerm.x - geo[i][0] - geo[i][2]) <= 1)
				{
					dir[i] = mxConstants.DIRECTION_MASK_EAST;
				}

				constraint[i][1] = (currentTerm.y - geo[i][1]) / geo[i][3];

				if (Math.abs(currentTerm.y - geo[i][1]) <= 1)
				{
					dir[i] = mxConstants.DIRECTION_MASK_NORTH;
				}
				else if (Math.abs(currentTerm.y - geo[i][1] - geo[i][3]) <= 1)
				{
					dir[i] = mxConstants.DIRECTION_MASK_SOUTH;
				}
			}

			currentTerm = null;
			
			if (target != null)
			{
				currentTerm = pe;
			}
		}

		var sourceTopDist = geo[0][1] - (geo[1][1] + geo[1][3]);
		var sourceLeftDist = geo[0][0] - (geo[1][0] + geo[1][2]);
		var sourceBottomDist = geo[1][1] - (geo[0][1] + geo[0][3]);
		var sourceRightDist = geo[1][0] - (geo[0][0] + geo[0][2]);

		mxEdgeStyle.vertexSeperations[1] = Math.max(sourceLeftDist - totalBuffer, 0);
		mxEdgeStyle.vertexSeperations[2] = Math.max(sourceTopDist - totalBuffer, 0);
		mxEdgeStyle.vertexSeperations[4] = Math.max(sourceBottomDist - totalBuffer, 0);
		mxEdgeStyle.vertexSeperations[3] = Math.max(sourceRightDist - totalBuffer, 0);
				
		//==============================================================
		// Start of source and target direction determination

		// Work through the preferred orientations by relative positioning
		// of the vertices and list them in preferred and available order
		
		var dirPref = [];
		var horPref = [];
		var vertPref = [];

		horPref[0] = (sourceLeftDist >= sourceRightDist) ? mxConstants.DIRECTION_MASK_WEST
				: mxConstants.DIRECTION_MASK_EAST;
		vertPref[0] = (sourceTopDist >= sourceBottomDist) ? mxConstants.DIRECTION_MASK_NORTH
				: mxConstants.DIRECTION_MASK_SOUTH;

		horPref[1] = mxUtils.reversePortConstraints(horPref[0]);
		vertPref[1] = mxUtils.reversePortConstraints(vertPref[0]);
		
		var preferredHorizDist = sourceLeftDist >= sourceRightDist ? sourceLeftDist
				: sourceRightDist;
		var preferredVertDist = sourceTopDist >= sourceBottomDist ? sourceTopDist
				: sourceBottomDist;

		var prefOrdering = [ [0, 0] , [0, 0] ];
		var preferredOrderSet = false;

		// If the preferred port isn't available, switch it
		for (var i = 0; i < 2; i++)
		{
			if (dir[i] != 0x0)
			{
				continue;
			}

			if ((horPref[i] & portConstraint[i]) == 0)
			{
				horPref[i] = mxUtils.reversePortConstraints(horPref[i]);
			}

			if ((vertPref[i] & portConstraint[i]) == 0)
			{
				vertPref[i] = mxUtils
						.reversePortConstraints(vertPref[i]);
			}

			prefOrdering[i][0] = vertPref[i];
			prefOrdering[i][1] = horPref[i];
		}

		if (preferredVertDist > 0
				&& preferredHorizDist > 0)
		{
			// Possibility of two segment edge connection
			if (((horPref[0] & portConstraint[0]) > 0)
					&& ((vertPref[1] & portConstraint[1]) > 0))
			{
				prefOrdering[0][0] = horPref[0];
				prefOrdering[0][1] = vertPref[0];
				prefOrdering[1][0] = vertPref[1];
				prefOrdering[1][1] = horPref[1];
				preferredOrderSet = true;
			}
			else if (((vertPref[0] & portConstraint[0]) > 0)
					&& ((horPref[1] & portConstraint[1]) > 0))
			{
				prefOrdering[0][0] = vertPref[0];
				prefOrdering[0][1] = horPref[0];
				prefOrdering[1][0] = horPref[1];
				prefOrdering[1][1] = vertPref[1];
				preferredOrderSet = true;
			}
		}
		
		if (preferredVertDist > 0 && !preferredOrderSet)
		{
			prefOrdering[0][0] = vertPref[0];
			prefOrdering[0][1] = horPref[0];
			prefOrdering[1][0] = vertPref[1];
			prefOrdering[1][1] = horPref[1];
			preferredOrderSet = true;

		}
		
		if (preferredHorizDist > 0 && !preferredOrderSet)
		{
			prefOrdering[0][0] = horPref[0];
			prefOrdering[0][1] = vertPref[0];
			prefOrdering[1][0] = horPref[1];
			prefOrdering[1][1] = vertPref[1];
			preferredOrderSet = true;
		}

		// The source and target prefs are now an ordered list of
		// the preferred port selections
		// It the list can contain gaps, compact it

		for (var i = 0; i < 2; i++)
		{
			if (dir[i] != 0x0)
			{
				continue;
			}

			if ((prefOrdering[i][0] & portConstraint[i]) == 0)
			{
				prefOrdering[i][0] = prefOrdering[i][1];
			}

			dirPref[i] = prefOrdering[i][0] & portConstraint[i];
			dirPref[i] |= (prefOrdering[i][1] & portConstraint[i]) << 8;
			dirPref[i] |= (prefOrdering[1 - i][i] & portConstraint[i]) << 16;
			dirPref[i] |= (prefOrdering[1 - i][1 - i] & portConstraint[i]) << 24;

			if ((dirPref[i] & 0xF) == 0)
			{
				dirPref[i] = dirPref[i] << 8;
			}
			
			if ((dirPref[i] & 0xF00) == 0)
			{
				dirPref[i] = (dirPref[i] & 0xF) | dirPref[i] >> 8;
			}
			
			if ((dirPref[i] & 0xF0000) == 0)
			{
				dirPref[i] = (dirPref[i] & 0xFFFF)
						| ((dirPref[i] & 0xF000000) >> 8);
			}

			dir[i] = dirPref[i] & 0xF;

			if (portConstraint[i] == mxConstants.DIRECTION_MASK_WEST
					|| portConstraint[i] == mxConstants.DIRECTION_MASK_NORTH
					|| portConstraint[i] == mxConstants.DIRECTION_MASK_EAST
					|| portConstraint[i] == mxConstants.DIRECTION_MASK_SOUTH)
			{
				dir[i] = portConstraint[i];
			}
		}

		//==============================================================
		// End of source and target direction determination

		var sourceIndex = dir[0] == mxConstants.DIRECTION_MASK_EAST ? 3
				: dir[0];
		var targetIndex = dir[1] == mxConstants.DIRECTION_MASK_EAST ? 3
				: dir[1];

		sourceIndex -= quad;
		targetIndex -= quad;

		if (sourceIndex < 1)
		{
			sourceIndex += 4;
		}
		
		if (targetIndex < 1)
		{
			targetIndex += 4;
		}

		var routePattern = mxEdgeStyle.routePatterns[sourceIndex - 1][targetIndex - 1];

		mxEdgeStyle.wayPoints1[0][0] = geo[0][0];
		mxEdgeStyle.wayPoints1[0][1] = geo[0][1];

		switch (dir[0])
		{
			case mxConstants.DIRECTION_MASK_WEST:
				mxEdgeStyle.wayPoints1[0][0] -= scaledSourceBuffer;
				mxEdgeStyle.wayPoints1[0][1] += constraint[0][1] * geo[0][3];
				break;
			case mxConstants.DIRECTION_MASK_SOUTH:
				mxEdgeStyle.wayPoints1[0][0] += constraint[0][0] * geo[0][2];
				mxEdgeStyle.wayPoints1[0][1] += geo[0][3] + scaledSourceBuffer;
				break;
			case mxConstants.DIRECTION_MASK_EAST:
				mxEdgeStyle.wayPoints1[0][0] += geo[0][2] + scaledSourceBuffer;
				mxEdgeStyle.wayPoints1[0][1] += constraint[0][1] * geo[0][3];
				break;
			case mxConstants.DIRECTION_MASK_NORTH:
				mxEdgeStyle.wayPoints1[0][0] += constraint[0][0] * geo[0][2];
				mxEdgeStyle.wayPoints1[0][1] -= scaledSourceBuffer;
				break;
		}

		var currentIndex = 0;

		// Orientation, 0 horizontal, 1 vertical
		var lastOrientation = (dir[0] & (mxConstants.DIRECTION_MASK_EAST | mxConstants.DIRECTION_MASK_WEST)) > 0 ? 0
				: 1;
		var initialOrientation = lastOrientation;
		var currentOrientation = 0;

		for (var i = 0; i < routePattern.length; i++)
		{
			var nextDirection = routePattern[i] & 0xF;

			// Rotate the index of this direction by the quad
			// to get the real direction
			var directionIndex = nextDirection == mxConstants.DIRECTION_MASK_EAST ? 3
					: nextDirection;

			directionIndex += quad;

			if (directionIndex > 4)
			{
				directionIndex -= 4;
			}

			var direction = mxEdgeStyle.dirVectors[directionIndex - 1];

			currentOrientation = (directionIndex % 2 > 0) ? 0 : 1;
			// Only update the current index if the point moved
			// in the direction of the current segment move,
			// otherwise the same point is moved until there is 
			// a segment direction change
			if (currentOrientation != lastOrientation)
			{
				currentIndex++;
				// Copy the previous way point into the new one
				// We can't base the new position on index - 1
				// because sometime elbows turn out not to exist,
				// then we'd have to rewind.
				mxEdgeStyle.wayPoints1[currentIndex][0] = mxEdgeStyle.wayPoints1[currentIndex - 1][0];
				mxEdgeStyle.wayPoints1[currentIndex][1] = mxEdgeStyle.wayPoints1[currentIndex - 1][1];
			}

			var tar = (routePattern[i] & mxEdgeStyle.TARGET_MASK) > 0;
			var sou = (routePattern[i] & mxEdgeStyle.SOURCE_MASK) > 0;
			var side = (routePattern[i] & mxEdgeStyle.SIDE_MASK) >> 5;
			side = side << quad;

			if (side > 0xF)
			{
				side = side >> 4;
			}

			var center = (routePattern[i] & mxEdgeStyle.CENTER_MASK) > 0;

			if ((sou || tar) && side < 9)
			{
				var limit = 0;
				var souTar = sou ? 0 : 1;

				if (center && currentOrientation == 0)
				{
					limit = geo[souTar][0] + constraint[souTar][0] * geo[souTar][2];
				}
				else if (center)
				{
					limit = geo[souTar][1] + constraint[souTar][1] * geo[souTar][3];
				}
				else
				{
					limit = mxEdgeStyle.limits[souTar][side];
				}
				
				if (currentOrientation == 0)
				{
					var lastX = mxEdgeStyle.wayPoints1[currentIndex][0];
					var deltaX = (limit - lastX) * direction[0];

					if (deltaX > 0)
					{
						mxEdgeStyle.wayPoints1[currentIndex][0] += direction[0]
								* deltaX;
					}
				}
				else
				{
					var lastY = mxEdgeStyle.wayPoints1[currentIndex][1];
					var deltaY = (limit - lastY) * direction[1];

					if (deltaY > 0)
					{
						mxEdgeStyle.wayPoints1[currentIndex][1] += direction[1]
								* deltaY;
					}
				}
			}

			else if (center)
			{
				// Which center we're travelling to depend on the current direction
				mxEdgeStyle.wayPoints1[currentIndex][0] += direction[0]
						* Math.abs(mxEdgeStyle.vertexSeperations[directionIndex] / 2);
				mxEdgeStyle.wayPoints1[currentIndex][1] += direction[1]
						* Math.abs(mxEdgeStyle.vertexSeperations[directionIndex] / 2);
			}

			if (currentIndex > 0
					&& mxEdgeStyle.wayPoints1[currentIndex][currentOrientation] == mxEdgeStyle.wayPoints1[currentIndex - 1][currentOrientation])
			{
				currentIndex--;
			}
			else
			{
				lastOrientation = currentOrientation;
			}
		}

		for (var i = 0; i <= currentIndex; i++)
		{
			if (i == currentIndex)
			{
				// Last point can cause last segment to be in
				// same direction as jetty/approach. If so,
				// check the number of points is consistent
				// with the relative orientation of source and target
				// jx. Same orientation requires an even
				// number of turns (points), different requires
				// odd.
				var targetOrientation = (dir[1] & (mxConstants.DIRECTION_MASK_EAST | mxConstants.DIRECTION_MASK_WEST)) > 0 ? 0
						: 1;
				var sameOrient = targetOrientation == initialOrientation ? 0 : 1;

				// (currentIndex + 1) % 2 is 0 for even number of points,
				// 1 for odd
				if (sameOrient != (currentIndex + 1) % 2)
				{
					// The last point isn't required
					break;
				}
			}
			
			result.push(new mxPoint(Math.round(mxEdgeStyle.wayPoints1[i][0]), Math.round(mxEdgeStyle.wayPoints1[i][1])));
		}
		
		// Removes duplicates
		var index = 1;
		
		while (index < result.length)
		{
			if (result[index - 1] == null || result[index] == null ||
				result[index - 1].x != result[index].x ||
				result[index - 1].y != result[index].y)
			{
				index++;
			}
			else
			{
				result.splice(index, 1);
			}
		}
	},
	
	getRoutePattern: function(dir, quad, dx, dy)
	{
		var sourceIndex = dir[0] == mxConstants.DIRECTION_MASK_EAST ? 3
				: dir[0];
		var targetIndex = dir[1] == mxConstants.DIRECTION_MASK_EAST ? 3
				: dir[1];

		sourceIndex -= quad;
		targetIndex -= quad;

		if (sourceIndex < 1)
		{
			sourceIndex += 4;
		}
		if (targetIndex < 1)
		{
			targetIndex += 4;
		}

		var result = routePatterns[sourceIndex - 1][targetIndex - 1];

		if (dx == 0 || dy == 0)
		{
			if (inlineRoutePatterns[sourceIndex - 1][targetIndex - 1] != null)
			{
				result = inlineRoutePatterns[sourceIndex - 1][targetIndex - 1];
			}
		}

		return result;
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
var mxStyleRegistry =
{
	/**
	 * Class: mxStyleRegistry
	 *
	 * Singleton class that acts as a global converter from string to object values
	 * in a style. This is currently only used to perimeters and edge styles.
	 * 
	 * Variable: values
	 *
	 * Maps from strings to objects.
	 */
	values: [],

	/**
	 * Function: putValue
	 *
	 * Puts the given object into the registry under the given name.
	 */
	putValue: function(name, obj)
	{
		mxStyleRegistry.values[name] = obj;
	},

	/**
	 * Function: getValue
	 *
	 * Returns the value associated with the given name.
	 */
	getValue: function(name)
	{
		return mxStyleRegistry.values[name];
	},
	
	/**
	 * Function: getName
	 * 
	 * Returns the name for the given value.
	 */
	getName: function(value)
	{
		for (var key in mxStyleRegistry.values)
		{
			if (mxStyleRegistry.values[key] == value)
			{
				return key;
			}
		}
		
		return null;
	}

};

mxStyleRegistry.putValue(mxConstants.EDGESTYLE_ELBOW, mxEdgeStyle.ElbowConnector);
mxStyleRegistry.putValue(mxConstants.EDGESTYLE_ENTITY_RELATION, mxEdgeStyle.EntityRelation);
mxStyleRegistry.putValue(mxConstants.EDGESTYLE_LOOP, mxEdgeStyle.Loop);
mxStyleRegistry.putValue(mxConstants.EDGESTYLE_SIDETOSIDE, mxEdgeStyle.SideToSide);
mxStyleRegistry.putValue(mxConstants.EDGESTYLE_TOPTOBOTTOM, mxEdgeStyle.TopToBottom);
mxStyleRegistry.putValue(mxConstants.EDGESTYLE_ORTHOGONAL, mxEdgeStyle.OrthConnector);
mxStyleRegistry.putValue(mxConstants.EDGESTYLE_SEGMENT, mxEdgeStyle.SegmentConnector);

mxStyleRegistry.putValue(mxConstants.PERIMETER_ELLIPSE, mxPerimeter.EllipsePerimeter);
mxStyleRegistry.putValue(mxConstants.PERIMETER_RECTANGLE, mxPerimeter.RectanglePerimeter);
mxStyleRegistry.putValue(mxConstants.PERIMETER_RHOMBUS, mxPerimeter.RhombusPerimeter);
mxStyleRegistry.putValue(mxConstants.PERIMETER_TRIANGLE, mxPerimeter.TrianglePerimeter);
mxStyleRegistry.putValue(mxConstants.PERIMETER_HEXAGON, mxPerimeter.HexagonPerimeter);
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxGraphView
 *
 * Extends <mxEventSource> to implement a view for a graph. This class is in
 * charge of computing the absolute coordinates for the relative child
 * geometries, the points for perimeters and edge styles and keeping them
 * cached in <mxCellStates> for faster retrieval. The states are updated
 * whenever the model or the view state (translate, scale) changes. The scale
 * and translate are honoured in the bounds.
 * 
 * Event: mxEvent.UNDO
 * 
 * Fires after the root was changed in <setCurrentRoot>. The <code>edit</code>
 * property contains the <mxUndoableEdit> which contains the
 * <mxCurrentRootChange>.
 * 
 * Event: mxEvent.SCALE_AND_TRANSLATE
 * 
 * Fires after the scale and translate have been changed in <scaleAndTranslate>.
 * The <code>scale</code>, <code>previousScale</code>, <code>translate</code>
 * and <code>previousTranslate</code> properties contain the new and previous
 * scale and translate, respectively.
 * 
 * Event: mxEvent.SCALE
 * 
 * Fires after the scale was changed in <setScale>. The <code>scale</code> and
 * <code>previousScale</code> properties contain the new and previous scale.
 * 
 * Event: mxEvent.TRANSLATE
 * 
 * Fires after the translate was changed in <setTranslate>. The
 * <code>translate</code> and <code>previousTranslate</code> properties contain
 * the new and previous value for translate.
 * 
 * Event: mxEvent.DOWN and mxEvent.UP
 * 
 * Fire if the current root is changed by executing an <mxCurrentRootChange>.
 * The event name depends on the location of the root in the cell hierarchy
 * with respect to the current root. The <code>root</code> and
 * <code>previous</code> properties contain the new and previous root,
 * respectively.
 * 
 * Constructor: mxGraphView
 *
 * Constructs a new view for the given <mxGraph>.
 * 
 * Parameters:
 * 
 * graph - Reference to the enclosing <mxGraph>.
 */
function mxGraphView(graph)
{
	this.graph = graph;
	this.translate = new mxPoint();
	this.graphBounds = new mxRectangle();
	this.states = new mxDictionary();
};

/**
 * Extends mxEventSource.
 */
mxGraphView.prototype = new mxEventSource();
mxGraphView.prototype.constructor = mxGraphView;

/**
 *
 */
mxGraphView.prototype.EMPTY_POINT = new mxPoint();

/**
 * Variable: doneResource
 * 
 * Specifies the resource key for the status message after a long operation.
 * If the resource for this key does not exist then the value is used as
 * the status message. Default is 'done'.
 */
mxGraphView.prototype.doneResource = (mxClient.language != 'none') ? 'done' : '';

/**
 * Function: updatingDocumentResource
 *
 * Specifies the resource key for the status message while the document is
 * being updated. If the resource for this key does not exist then the
 * value is used as the status message. Default is 'updatingDocument'.
 */
mxGraphView.prototype.updatingDocumentResource = (mxClient.language != 'none') ? 'updatingDocument' : '';

/**
 * Variable: allowEval
 * 
 * Specifies if string values in cell styles should be evaluated using
 * <mxUtils.eval>. This will only be used if the string values can't be mapped
 * to objects using <mxStyleRegistry>. Default is false. NOTE: Enabling this
 * switch carries a possible security risk.
 */
mxGraphView.prototype.allowEval = false;

/**
 * Variable: captureDocumentGesture
 * 
 * Specifies if a gesture should be captured when it goes outside of the
 * graph container. Default is true.
 */
mxGraphView.prototype.captureDocumentGesture = true;

/**
 * Variable: optimizeVmlReflows
 * 
 * Specifies if the <canvas> should be hidden while rendering in IE8 standards
 * mode and quirks mode. This will significantly improve rendering performance.
 * Default is true.
 */
mxGraphView.prototype.optimizeVmlReflows = true;

/**
 * Variable: rendering
 * 
 * Specifies if shapes should be created, updated and destroyed using the
 * methods of <mxCellRenderer> in <graph>. Default is true.
 */
mxGraphView.prototype.rendering = true;

/**
 * Variable: graph
 *
 * Reference to the enclosing <mxGraph>.
 */
mxGraphView.prototype.graph = null;

/**
 * Variable: currentRoot
 *
 * <mxCell> that acts as the root of the displayed cell hierarchy.
 */
mxGraphView.prototype.currentRoot = null;

/**
 * Variable: graphBounds
 *
 * <mxRectangle> that caches the scales, translated bounds of the current view.
 */
mxGraphView.prototype.graphBounds = null;

/**
 * Variable: scale
 * 
 * Specifies the scale. Default is 1 (100%).
 */
mxGraphView.prototype.scale = 1;
	
/**
 * Variable: translate
 *
 * <mxPoint> that specifies the current translation. Default is a new
 * empty <mxPoint>.
 */
mxGraphView.prototype.translate = null;

/**
 * Variable: states
 * 
 * <mxDictionary> that maps from cell IDs to <mxCellStates>.
 */
mxGraphView.prototype.states = null;

/**
 * Variable: updateStyle
 * 
 * Specifies if the style should be updated in each validation step. If this
 * is false then the style is only updated if the state is created or if the
 * style of the cell was changed. Default is false.
 */
mxGraphView.prototype.updateStyle = false;

/**
 * Variable: lastNode
 * 
 * During validation, this contains the last DOM node that was processed.
 */
mxGraphView.prototype.lastNode = null;

/**
 * Variable: lastHtmlNode
 * 
 * During validation, this contains the last HTML DOM node that was processed.
 */
mxGraphView.prototype.lastHtmlNode = null;

/**
 * Variable: lastForegroundNode
 * 
 * During validation, this contains the last edge's DOM node that was processed.
 */
mxGraphView.prototype.lastForegroundNode = null;

/**
 * Variable: lastForegroundHtmlNode
 * 
 * During validation, this contains the last edge HTML DOM node that was processed.
 */
mxGraphView.prototype.lastForegroundHtmlNode = null;

/**
 * Function: getGraphBounds
 *
 * Returns <graphBounds>.
 */
mxGraphView.prototype.getGraphBounds = function()
{
	return this.graphBounds;
};

/**
 * Function: setGraphBounds
 *
 * Sets <graphBounds>.
 */
mxGraphView.prototype.setGraphBounds = function(value)
{
	this.graphBounds = value;
};

/**
 * Function: getBounds
 * 
 * Returns the union of all <mxCellStates> for the given array of <mxCells>.
 *
 * Parameters:
 *
 * cells - Array of <mxCells> whose bounds should be returned.
 */
mxGraphView.prototype.getBounds = function(cells)
{
	var result = null;
	
	if (cells != null && cells.length > 0)
	{
		var model = this.graph.getModel();
		
		for (var i = 0; i < cells.length; i++)
		{
			if (model.isVertex(cells[i]) || model.isEdge(cells[i]))
			{
				var state = this.getState(cells[i]);
			
				if (state != null)
				{
					if (result == null)
					{
						result = mxRectangle.fromRectangle(state);
					}
					else
					{
						result.add(state);
					}
				}
			}
		}
	}
	
	return result;
};

/**
 * Function: setCurrentRoot
 *
 * Sets and returns the current root and fires an <undo> event before
 * calling <mxGraph.sizeDidChange>.
 *
 * Parameters:
 *
 * root - <mxCell> that specifies the root of the displayed cell hierarchy.
 */
mxGraphView.prototype.setCurrentRoot = function(root)
{
	if (this.currentRoot != root)
	{
		var change = new mxCurrentRootChange(this, root);
		change.execute();
		var edit = new mxUndoableEdit(this, false);
		edit.add(change);
		this.fireEvent(new mxEventObject(mxEvent.UNDO, 'edit', edit));
		this.graph.sizeDidChange();
	}
	
	return root;
};

/**
 * Function: scaleAndTranslate
 *
 * Sets the scale and translation and fires a <scale> and <translate> event
 * before calling <revalidate> followed by <mxGraph.sizeDidChange>.
 *
 * Parameters:
 *
 * scale - Decimal value that specifies the new scale (1 is 100%).
 * dx - X-coordinate of the translation.
 * dy - Y-coordinate of the translation.
 */
mxGraphView.prototype.scaleAndTranslate = function(scale, dx, dy)
{
	var previousScale = this.scale;
	var previousTranslate = new mxPoint(this.translate.x, this.translate.y);
	
	if (this.scale != scale || this.translate.x != dx || this.translate.y != dy)
	{
		this.scale = scale;
		
		this.translate.x = dx;
		this.translate.y = dy;

		if (this.isEventsEnabled())
		{
			this.revalidate();
			this.graph.sizeDidChange();
		}
	}
	
	this.fireEvent(new mxEventObject(mxEvent.SCALE_AND_TRANSLATE,
		'scale', scale, 'previousScale', previousScale,
		'translate', this.translate, 'previousTranslate', previousTranslate));
};

/**
 * Function: getScale
 * 
 * Returns the <scale>.
 */
mxGraphView.prototype.getScale = function()
{
	return this.scale;
};

/**
 * Function: setScale
 *
 * Sets the scale and fires a <scale> event before calling <revalidate> followed
 * by <mxGraph.sizeDidChange>.
 *
 * Parameters:
 *
 * value - Decimal value that specifies the new scale (1 is 100%).
 */
mxGraphView.prototype.setScale = function(value)
{
	var previousScale = this.scale;
	
	if (this.scale != value)
	{
		this.scale = value;

		if (this.isEventsEnabled())
		{
			this.revalidate();
			this.graph.sizeDidChange();
		}
	}
	
	this.fireEvent(new mxEventObject(mxEvent.SCALE,
		'scale', value, 'previousScale', previousScale));
};

/**
 * Function: getTranslate
 * 
 * Returns the <translate>.
 */
mxGraphView.prototype.getTranslate = function()
{
	return this.translate;
};

/**
 * Function: setTranslate
 *
 * Sets the translation and fires a <translate> event before calling
 * <revalidate> followed by <mxGraph.sizeDidChange>. The translation is the
 * negative of the origin.
 *
 * Parameters:
 *
 * dx - X-coordinate of the translation.
 * dy - Y-coordinate of the translation.
 */
mxGraphView.prototype.setTranslate = function(dx, dy)
{
	var previousTranslate = new mxPoint(this.translate.x, this.translate.y);
	
	if (this.translate.x != dx || this.translate.y != dy)
	{
		this.translate.x = dx;
		this.translate.y = dy;

		if (this.isEventsEnabled())
		{
			this.revalidate();
			this.graph.sizeDidChange();
		}
	}
	
	this.fireEvent(new mxEventObject(mxEvent.TRANSLATE,
		'translate', this.translate, 'previousTranslate', previousTranslate));
};

/**
 * Function: refresh
 *
 * Clears the view if <currentRoot> is not null and revalidates.
 */
mxGraphView.prototype.refresh = function()
{
	if (this.currentRoot != null)
	{
		this.clear();
	}
	
	this.revalidate();
};

/**
 * Function: revalidate
 *
 * Revalidates the complete view with all cell states.
 */
mxGraphView.prototype.revalidate = function()
{
	this.invalidate();
	this.validate();
};

/**
 * Function: clear
 *
 * Removes the state of the given cell and all descendants if the given
 * cell is not the current root.
 * 
 * Parameters:
 * 
 * cell - Optional <mxCell> for which the state should be removed. Default
 * is the root of the model.
 * force - Boolean indicating if the current root should be ignored for
 * recursion.
 */
mxGraphView.prototype.clear = function(cell, force, recurse)
{
	var model = this.graph.getModel();
	cell = cell || model.getRoot();
	force = (force != null) ? force : false;
	recurse = (recurse != null) ? recurse : true;
	
	this.removeState(cell);
	
	if (recurse && (force || cell != this.currentRoot))
	{
		var childCount = model.getChildCount(cell);
		
		for (var i = 0; i < childCount; i++)
		{
			this.clear(model.getChildAt(cell, i), force);
		}
	}
	else
	{
		this.invalidate(cell);
	}
};

/**
 * Function: invalidate
 * 
 * Invalidates the state of the given cell, all its descendants and
 * connected edges.
 * 
 * Parameters:
 * 
 * cell - Optional <mxCell> to be invalidated. Default is the root of the
 * model.
 */
mxGraphView.prototype.invalidate = function(cell, recurse, includeEdges)
{
	var model = this.graph.getModel();
	cell = cell || model.getRoot();
	recurse = (recurse != null) ? recurse : true;
	includeEdges = (includeEdges != null) ? includeEdges : true;
	
	var state = this.getState(cell);
	
	if (state != null)
	{
		state.invalid = true;
	}
	
	// Avoids infinite loops for invalid graphs
	if (!cell.invalidating)
	{
		cell.invalidating = true;
		
		// Recursively invalidates all descendants
		if (recurse)
		{
			var childCount = model.getChildCount(cell);
			
			for (var i = 0; i < childCount; i++)
			{
				var child = model.getChildAt(cell, i);
				this.invalidate(child, recurse, includeEdges);
			}
		}
		
		// Propagates invalidation to all connected edges
		if (includeEdges)
		{
			var edgeCount = model.getEdgeCount(cell);
			
			for (var i = 0; i < edgeCount; i++)
			{
				this.invalidate(model.getEdgeAt(cell, i), recurse, includeEdges);
			}
		}
		
		delete cell.invalidating;
	}
};

/**
 * Function: validate
 * 
 * Calls <validateCell> and <validateCellState> and updates the <graphBounds>
 * using <getBoundingBox>. Finally the background is validated using
 * <validateBackground>.
 * 
 * Parameters:
 * 
 * cell - Optional <mxCell> to be used as the root of the validation.
 * Default is <currentRoot> or the root of the model.
 */
mxGraphView.prototype.validate = function(cell)
{
	var t0 = mxLog.enter('mxGraphView.validate');
	window.status = mxResources.get(this.updatingDocumentResource) ||
		this.updatingDocumentResource;
	
	this.resetValidationState();
	
	// Improves IE rendering speed by minimizing reflows
	var prevDisplay = null;
	
	if (this.optimizeVmlReflows && this.canvas != null && this.textDiv == null &&
		((document.documentMode == 8 && !mxClient.IS_EM) || mxClient.IS_QUIRKS))
	{
		// Placeholder keeps scrollbar positions when canvas is hidden
		this.placeholder = document.createElement('div');
		this.placeholder.style.position = 'absolute';
		this.placeholder.style.width = this.canvas.clientWidth + 'px';
		this.placeholder.style.height = this.canvas.clientHeight + 'px';
		this.canvas.parentNode.appendChild(this.placeholder);

		prevDisplay = this.drawPane.style.display;
		this.canvas.style.display = 'none';
		
		// Creates temporary DIV used for text measuring in mxText.updateBoundingBox
		this.textDiv = document.createElement('div');
		this.textDiv.style.position = 'absolute';
		this.textDiv.style.whiteSpace = 'nowrap';
		this.textDiv.style.visibility = 'hidden';
		this.textDiv.style.display = (mxClient.IS_QUIRKS) ? 'inline' : 'inline-block';
		this.textDiv.style.zoom = '1';
		
		document.body.appendChild(this.textDiv);
	}
	
	var graphBounds = this.getBoundingBox(this.validateCellState(
		this.validateCell(cell || ((this.currentRoot != null) ?
			this.currentRoot : this.graph.getModel().getRoot()))));
	this.setGraphBounds((graphBounds != null) ? graphBounds : this.getEmptyBounds());
	this.validateBackground();
	
	if (prevDisplay != null)
	{
		this.canvas.style.display = prevDisplay;
		this.textDiv.parentNode.removeChild(this.textDiv);
		
		if (this.placeholder != null)
		{
			this.placeholder.parentNode.removeChild(this.placeholder);
		}
				
		// Textdiv cannot be reused
		this.textDiv = null;
	}
	
	this.resetValidationState();
	
	window.status = mxResources.get(this.doneResource) ||
		this.doneResource;
	mxLog.leave('mxGraphView.validate', t0);
};

/**
 * Function: getEmptyBounds
 * 
 * Returns the bounds for an empty graph. This returns a rectangle at
 * <translate> with the size of 0 x 0.
 */
mxGraphView.prototype.getEmptyBounds = function()
{
	return new mxRectangle(this.translate.x * this.scale, this.translate.y * this.scale);
};

/**
 * Function: getBoundingBox
 * 
 * Returns the bounding box of the shape and the label for the given
 * <mxCellState> and its children if recurse is true.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose bounding box should be returned.
 * recurse - Optional boolean indicating if the children should be included.
 * Default is true.
 */
mxGraphView.prototype.getBoundingBox = function(state, recurse)
{
	recurse = (recurse != null) ? recurse : true;
	var bbox = null;
	
	if (state != null)
	{
		if (state.shape != null && state.shape.boundingBox != null)
		{
			bbox = state.shape.boundingBox.clone();
		}
		
		// Adds label bounding box to graph bounds
		if (state.text != null && state.text.boundingBox != null)
		{
			if (bbox != null)
			{
				bbox.add(state.text.boundingBox);
			}
			else
			{
				bbox = state.text.boundingBox.clone();
			}
		}
		
		if (recurse)
		{
			var model = this.graph.getModel();
			var childCount = model.getChildCount(state.cell);
			
			for (var i = 0; i < childCount; i++)
			{
				var bounds = this.getBoundingBox(this.getState(model.getChildAt(state.cell, i)));
				
				if (bounds != null)
				{
					if (bbox == null)
					{
						bbox = bounds;
					}
					else
					{
						bbox.add(bounds);
					}
				}
			}
		}
	}
	
	return bbox;
};

/**
 * Function: createBackgroundPageShape
 *
 * Creates and returns the shape used as the background page.
 * 
 * Parameters:
 * 
 * bounds - <mxRectangle> that represents the bounds of the shape.
 */
mxGraphView.prototype.createBackgroundPageShape = function(bounds)
{
	return new mxRectangleShape(bounds, 'white', 'black');
};

/**
 * Function: validateBackground
 *
 * Calls <validateBackgroundImage> and <validateBackgroundPage>.
 */
mxGraphView.prototype.validateBackground = function()
{
	this.validateBackgroundImage();
	this.validateBackgroundPage();
};

/**
 * Function: validateBackgroundImage
 * 
 * Validates the background image.
 */
mxGraphView.prototype.validateBackgroundImage = function()
{
	var bg = this.graph.getBackgroundImage();
	
	if (bg != null)
	{
		if (this.backgroundImage == null || this.backgroundImage.image != bg.src)
		{
			if (this.backgroundImage != null)
			{
				this.backgroundImage.destroy();
			}
			
			var bounds = new mxRectangle(0, 0, 1, 1);
			
			this.backgroundImage = new mxImageShape(bounds, bg.src);
			this.backgroundImage.dialect = this.graph.dialect;
			this.backgroundImage.init(this.backgroundPane);
			this.backgroundImage.redraw();

			// Workaround for ignored event on background in IE8 standards mode
			if (document.documentMode == 8 && !mxClient.IS_EM)
			{
				mxEvent.addGestureListeners(this.backgroundImage.node,
					mxUtils.bind(this, function(evt)
					{
						this.graph.fireMouseEvent(mxEvent.MOUSE_DOWN, new mxMouseEvent(evt));
					}),
					mxUtils.bind(this, function(evt)
					{
						this.graph.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt));
					}),
					mxUtils.bind(this, function(evt)
					{
						this.graph.fireMouseEvent(mxEvent.MOUSE_UP, new mxMouseEvent(evt));
					})
				);
			}
		}
		
		this.redrawBackgroundImage(this.backgroundImage, bg);
	}
	else if (this.backgroundImage != null)
	{
		this.backgroundImage.destroy();
		this.backgroundImage = null;
	}
};

/**
 * Function: validateBackgroundPage
 * 
 * Validates the background page.
 */
mxGraphView.prototype.validateBackgroundPage = function()
{
	if (this.graph.pageVisible)
	{
		var bounds = this.getBackgroundPageBounds();
		
		if (this.backgroundPageShape == null)
		{
			this.backgroundPageShape = this.createBackgroundPageShape(bounds);
			this.backgroundPageShape.scale = this.scale;
			this.backgroundPageShape.isShadow = true;
			this.backgroundPageShape.dialect = this.graph.dialect;
			this.backgroundPageShape.init(this.backgroundPane);
			this.backgroundPageShape.redraw();
			
			// Adds listener for double click handling on background
			if (this.graph.nativeDblClickEnabled)
			{
				mxEvent.addListener(this.backgroundPageShape.node, 'dblclick', mxUtils.bind(this, function(evt)
				{
					this.graph.dblClick(evt);
				}));
			}

			// Adds basic listeners for graph event dispatching outside of the
			// container and finishing the handling of a single gesture
			mxEvent.addGestureListeners(this.backgroundPageShape.node,
				mxUtils.bind(this, function(evt)
				{
					this.graph.fireMouseEvent(mxEvent.MOUSE_DOWN, new mxMouseEvent(evt));
				}),
				mxUtils.bind(this, function(evt)
				{
					// Hides the tooltip if mouse is outside container
					if (this.graph.tooltipHandler != null && this.graph.tooltipHandler.isHideOnHover())
					{
						this.graph.tooltipHandler.hide();
					}
					
					if (this.graph.isMouseDown && !mxEvent.isConsumed(evt))
					{
						this.graph.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt));
					}
				}),
				mxUtils.bind(this, function(evt)
				{
					this.graph.fireMouseEvent(mxEvent.MOUSE_UP, new mxMouseEvent(evt));
				})
			);
		}
		else
		{
			this.backgroundPageShape.scale = this.scale;
			this.backgroundPageShape.bounds = bounds;
			this.backgroundPageShape.redraw();
		}
	}
	else if (this.backgroundPageShape != null)
	{
		this.backgroundPageShape.destroy();
		this.backgroundPageShape = null;
	}
};

/**
 * Function: getBackgroundPageBounds
 * 
 * Returns the bounds for the background page.
 */
mxGraphView.prototype.getBackgroundPageBounds = function()
{
	var fmt = this.graph.pageFormat;
	var ps = this.scale * this.graph.pageScale;
	var bounds = new mxRectangle(this.scale * this.translate.x, this.scale * this.translate.y,
			fmt.width * ps, fmt.height * ps);
	
	return bounds;
};

/**
 * Function: redrawBackgroundImage
 *
 * Updates the bounds and redraws the background image.
 * 
 * Example:
 * 
 * If the background image should not be scaled, this can be replaced with
 * the following.
 * 
 * (code)
 * mxGraphView.prototype.redrawBackground = function(backgroundImage, bg)
 * {
 *   backgroundImage.bounds.x = this.translate.x;
 *   backgroundImage.bounds.y = this.translate.y;
 *   backgroundImage.bounds.width = bg.width;
 *   backgroundImage.bounds.height = bg.height;
 *
 *   backgroundImage.redraw();
 * };
 * (end)
 * 
 * Parameters:
 * 
 * backgroundImage - <mxImageShape> that represents the background image.
 * bg - <mxImage> that specifies the image and its dimensions.
 */
mxGraphView.prototype.redrawBackgroundImage = function(backgroundImage, bg)
{
	backgroundImage.scale = this.scale;
	backgroundImage.bounds.x = this.scale * this.translate.x;
	backgroundImage.bounds.y = this.scale * this.translate.y;
	backgroundImage.bounds.width = this.scale * bg.width;
	backgroundImage.bounds.height = this.scale * bg.height;

	backgroundImage.redraw();
};

/**
 * Function: validateCell
 * 
 * Recursively creates the cell state for the given cell if visible is true and
 * the given cell is visible. If the cell is not visible but the state exists
 * then it is removed using <removeState>.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose <mxCellState> should be created.
 * visible - Optional boolean indicating if the cell should be visible. Default
 * is true.
 */
mxGraphView.prototype.validateCell = function(cell, visible)
{
	visible = (visible != null) ? visible : true;
	
	if (cell != null)
	{
		visible = visible && this.graph.isCellVisible(cell);
		var state = this.getState(cell, visible);
		
		if (state != null && !visible)
		{
			this.removeState(cell);
		}
		else
		{
			var model = this.graph.getModel();
			var childCount = model.getChildCount(cell);
			
			for (var i = 0; i < childCount; i++)
			{
				this.validateCell(model.getChildAt(cell, i), visible &&
					(!this.isCellCollapsed(cell) || cell == this.currentRoot));
			}
		}
	}
	
	return cell;
};

/**
 * Function: validateCellState
 * 
 * Validates and repaints the <mxCellState> for the given <mxCell>.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose <mxCellState> should be validated.
 * recurse - Optional boolean indicating if the children of the cell should be
 * validated. Default is true.
 */
mxGraphView.prototype.validateCellState = function(cell, recurse)
{
	recurse = (recurse != null) ? recurse : true;
	var state = null;
	
	if (cell != null)
	{
		state = this.getState(cell);
		
		if (state != null)
		{
			var model = this.graph.getModel();
			
			if (state.invalid)
			{
				state.invalid = false;
				
				if (state.style == null)
				{
					state.style = this.graph.getCellStyle(state.cell);
				}
				
				if (cell != this.currentRoot)
				{
					this.validateCellState(model.getParent(cell), false);
				}

				state.setVisibleTerminalState(this.validateCellState(this.getVisibleTerminal(cell, true), false), true);
				state.setVisibleTerminalState(this.validateCellState(this.getVisibleTerminal(cell, false), false), false);
				
				this.updateCellState(state);
				
				// Repaint happens immediately after the cell is validated
				if (cell != this.currentRoot && !state.invalid)
				{
					this.graph.cellRenderer.redraw(state, false, this.isRendering());

					// Handles changes to invertex paintbounds after update of rendering shape
					state.updateCachedBounds();
				}
			}

			if (recurse && !state.invalid)
			{
				// Updates order in DOM if recursively traversing
				if (state.shape != null)
				{
					this.stateValidated(state);
				}
			
				var childCount = model.getChildCount(cell);
				
				for (var i = 0; i < childCount; i++)
				{
					this.validateCellState(model.getChildAt(cell, i));
				}
			}
		}
	}
	
	return state;
};

/**
 * Function: updateCellState
 * 
 * Updates the given <mxCellState>.
 * 
 * Parameters:
 * 
 * state - <mxCellState> to be updated.
 */
mxGraphView.prototype.updateCellState = function(state)
{
	state.absoluteOffset.x = 0;
	state.absoluteOffset.y = 0;
	state.origin.x = 0;
	state.origin.y = 0;
	state.length = 0;
	
	if (state.cell != this.currentRoot)
	{
		var model = this.graph.getModel();
		var pState = this.getState(model.getParent(state.cell)); 
		
		if (pState != null && pState.cell != this.currentRoot)
		{
			state.origin.x += pState.origin.x;
			state.origin.y += pState.origin.y;
		}
		
		var offset = this.graph.getChildOffsetForCell(state.cell);
		
		if (offset != null)
		{
			state.origin.x += offset.x;
			state.origin.y += offset.y;
		}
		
		var geo = this.graph.getCellGeometry(state.cell);				
	
		if (geo != null)
		{
			if (!model.isEdge(state.cell))
			{
				offset = geo.offset || this.EMPTY_POINT;
	
				if (geo.relative && pState != null)
				{
					if (model.isEdge(pState.cell))
					{
						var origin = this.getPoint(pState, geo);

						if (origin != null)
						{
							state.origin.x += (origin.x / this.scale) - pState.origin.x - this.translate.x;
							state.origin.y += (origin.y / this.scale) - pState.origin.y - this.translate.y;
						}
					}
					else
					{
						state.origin.x += geo.x * pState.width / this.scale + offset.x;
						state.origin.y += geo.y * pState.height / this.scale + offset.y;
					}
				}
				else
				{
					state.absoluteOffset.x = this.scale * offset.x;
					state.absoluteOffset.y = this.scale * offset.y;
					state.origin.x += geo.x;
					state.origin.y += geo.y;
				}
			}
	
			state.x = this.scale * (this.translate.x + state.origin.x);
			state.y = this.scale * (this.translate.y + state.origin.y);
			state.width = this.scale * geo.width;
			state.unscaledWidth = geo.width;
			state.height = this.scale * geo.height;
			
			if (model.isVertex(state.cell))
			{
				this.updateVertexState(state, geo);
			}
			
			if (model.isEdge(state.cell))
			{
				this.updateEdgeState(state, geo);
			}
		}
	}

	state.updateCachedBounds();
};

/**
 * Function: isCellCollapsed
 * 
 * Returns true if the children of the given cell should not be visible in the
 * view. This implementation uses <mxGraph.isCellVisible> but it can be
 * overidden to use a separate condition.
 */
mxGraphView.prototype.isCellCollapsed = function(cell)
{
	return this.graph.isCellCollapsed(cell);
};

/**
 * Function: updateVertexState
 * 
 * Validates the given cell state.
 */
mxGraphView.prototype.updateVertexState = function(state, geo)
{
	var model = this.graph.getModel();
	var pState = this.getState(model.getParent(state.cell));
	
	if (geo.relative && pState != null && !model.isEdge(pState.cell))
	{
		var alpha = mxUtils.toRadians(pState.style[mxConstants.STYLE_ROTATION] || '0');
		
		if (alpha != 0)
		{
			var cos = Math.cos(alpha);
			var sin = Math.sin(alpha);

			var ct = new mxPoint(state.getCenterX(), state.getCenterY());
			var cx = new mxPoint(pState.getCenterX(), pState.getCenterY());
			var pt = mxUtils.getRotatedPoint(ct, cos, sin, cx);
			state.x = pt.x - state.width / 2;
			state.y = pt.y - state.height / 2;
		}
	}
	
	this.updateVertexLabelOffset(state);
};

/**
 * Function: updateEdgeState
 * 
 * Validates the given cell state.
 */
mxGraphView.prototype.updateEdgeState = function(state, geo)
{
	var source = state.getVisibleTerminalState(true);
	var target = state.getVisibleTerminalState(false);
	
	// This will remove edges with no terminals and no terminal points
	// as such edges are invalid and produce NPEs in the edge styles.
	// Also removes connected edges that have no visible terminals.
	if ((this.graph.model.getTerminal(state.cell, true) != null && source == null) ||
		(source == null && geo.getTerminalPoint(true) == null) ||
		(this.graph.model.getTerminal(state.cell, false) != null && target == null) ||
		(target == null && geo.getTerminalPoint(false) == null))
	{
		this.clear(state.cell, true);
	}
	else
	{
		this.updateFixedTerminalPoints(state, source, target);
		this.updatePoints(state, geo.points, source, target);
		this.updateFloatingTerminalPoints(state, source, target);
		
		var pts = state.absolutePoints;
		
		if (state.cell != this.currentRoot && (pts == null || pts.length < 2 ||
			pts[0] == null || pts[pts.length - 1] == null))
		{
			// This will remove edges with invalid points from the list of states in the view.
			// Happens if the one of the terminals and the corresponding terminal point is null.
			this.clear(state.cell, true);
		}
		else
		{
			this.updateEdgeBounds(state);
			this.updateEdgeLabelOffset(state);
		}
	}
};

/**
 * Function: updateVertexLabelOffset
 * 
 * Updates the absoluteOffset of the given vertex cell state. This takes
 * into account the label position styles.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose absolute offset should be updated.
 */
mxGraphView.prototype.updateVertexLabelOffset = function(state)
{
	var h = mxUtils.getValue(state.style, mxConstants.STYLE_LABEL_POSITION, mxConstants.ALIGN_CENTER);

	if (h == mxConstants.ALIGN_LEFT)
	{
		var lw = mxUtils.getValue(state.style, mxConstants.STYLE_LABEL_WIDTH, null);
		
		if (lw != null)
		{
			lw *= this.scale;
		}
		else
		{
			lw = state.width;
		}
		
		state.absoluteOffset.x -= lw;
	}
	else if (h == mxConstants.ALIGN_RIGHT)
	{
		state.absoluteOffset.x += state.width;
	}
	else if (h == mxConstants.ALIGN_CENTER)
	{
		var lw = mxUtils.getValue(state.style, mxConstants.STYLE_LABEL_WIDTH, null);
		
		if (lw != null)
		{
			// Aligns text block with given width inside the vertex width
			var align = mxUtils.getValue(state.style, mxConstants.STYLE_ALIGN, mxConstants.ALIGN_CENTER);
			var dx = 0;
			
			if (align == mxConstants.ALIGN_CENTER)
			{
				dx = 0.5;
			}
			else if (align == mxConstants.ALIGN_RIGHT)
			{
				dx = 1;
			}
			
			if (dx != 0)
			{
				state.absoluteOffset.x -= (lw * this.scale - state.width) * dx;
			}
		}
	}
	
	var v = mxUtils.getValue(state.style, mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE);
	
	if (v == mxConstants.ALIGN_TOP)
	{
		state.absoluteOffset.y -= state.height;
	}
	else if (v == mxConstants.ALIGN_BOTTOM)
	{
		state.absoluteOffset.y += state.height;
	}
};

/**
 * Function: resetValidationState
 *
 * Resets the current validation state.
 */
mxGraphView.prototype.resetValidationState = function()
{
	this.lastNode = null;
	this.lastHtmlNode = null;
	this.lastForegroundNode = null;
	this.lastForegroundHtmlNode = null;
};

/**
 * Function: stateValidated
 * 
 * Invoked when a state has been processed in <validatePoints>. This is used
 * to update the order of the DOM nodes of the shape.
 * 
 * Parameters:
 * 
 * state - <mxCellState> that represents the cell state.
 */
mxGraphView.prototype.stateValidated = function(state)
{
	var fg = (this.graph.getModel().isEdge(state.cell) && this.graph.keepEdgesInForeground) ||
		(this.graph.getModel().isVertex(state.cell) && this.graph.keepEdgesInBackground);
	var htmlNode = (fg) ? this.lastForegroundHtmlNode || this.lastHtmlNode : this.lastHtmlNode;
	var node = (fg) ? this.lastForegroundNode || this.lastNode : this.lastNode;
	var result = this.graph.cellRenderer.insertStateAfter(state, node, htmlNode);

	if (fg)
	{
		this.lastForegroundHtmlNode = result[1];
		this.lastForegroundNode = result[0];
	}
	else
	{
		this.lastHtmlNode = result[1];
		this.lastNode = result[0];
	}
};

/**
 * Function: updateFixedTerminalPoints
 *
 * Sets the initial absolute terminal points in the given state before the edge
 * style is computed.
 * 
 * Parameters:
 * 
 * edge - <mxCellState> whose initial terminal points should be updated.
 * source - <mxCellState> which represents the source terminal.
 * target - <mxCellState> which represents the target terminal.
 */
mxGraphView.prototype.updateFixedTerminalPoints = function(edge, source, target)
{
	this.updateFixedTerminalPoint(edge, source, true,
		this.graph.getConnectionConstraint(edge, source, true));
	this.updateFixedTerminalPoint(edge, target, false,
		this.graph.getConnectionConstraint(edge, target, false));
};

/**
 * Function: updateFixedTerminalPoint
 *
 * Sets the fixed source or target terminal point on the given edge.
 * 
 * Parameters:
 * 
 * edge - <mxCellState> whose terminal point should be updated.
 * terminal - <mxCellState> which represents the actual terminal.
 * source - Boolean that specifies if the terminal is the source.
 * constraint - <mxConnectionConstraint> that specifies the connection.
 */
mxGraphView.prototype.updateFixedTerminalPoint = function(edge, terminal, source, constraint)
{
	edge.setAbsoluteTerminalPoint(this.getFixedTerminalPoint(edge, terminal, source, constraint), source);
};

/**
 * Function: getFixedTerminalPoint
 *
 * Returns the fixed source or target terminal point for the given edge.
 * 
 * Parameters:
 * 
 * edge - <mxCellState> whose terminal point should be returned.
 * terminal - <mxCellState> which represents the actual terminal.
 * source - Boolean that specifies if the terminal is the source.
 * constraint - <mxConnectionConstraint> that specifies the connection.
 */
mxGraphView.prototype.getFixedTerminalPoint = function(edge, terminal, source, constraint)
{
	var pt = null;
	
	if (constraint != null)
	{
		pt = this.graph.getConnectionPoint(terminal, constraint);
	}
	
	if (pt == null && terminal == null)
	{
		var s = this.scale;
		var tr = this.translate;
		var orig = edge.origin;
		var geo = this.graph.getCellGeometry(edge.cell);
		pt = geo.getTerminalPoint(source);
		
		if (pt != null)
		{
			pt = new mxPoint(s * (tr.x + pt.x + orig.x),
							 s * (tr.y + pt.y + orig.y));
		}
	}
	
	return pt;
};

/**
 * Function: updateBoundsFromStencil
 * 
 * Updates the bounds of the given cell state to reflect the bounds of the stencil
 * if it has a fixed aspect and returns the previous bounds as an <mxRectangle> if
 * the bounds have been modified or null otherwise.
 * 
 * Parameters:
 * 
 * edge - <mxCellState> whose bounds should be updated.
 */
mxGraphView.prototype.updateBoundsFromStencil = function(state)
{
	var previous = null;
	
	if (state != null && state.shape != null && state.shape.stencil != null && state.shape.stencil.aspect == 'fixed')
	{
		previous = mxRectangle.fromRectangle(state);
		var asp = state.shape.stencil.computeAspect(state.style, state.x, state.y, state.width, state.height);
		state.setRect(asp.x, asp.y, state.shape.stencil.w0 * asp.width, state.shape.stencil.h0 * asp.height);
	}
	
	return previous;
};

/**
 * Function: updatePoints
 *
 * Updates the absolute points in the given state using the specified array
 * of <mxPoints> as the relative points.
 * 
 * Parameters:
 * 
 * edge - <mxCellState> whose absolute points should be updated.
 * points - Array of <mxPoints> that constitute the relative points.
 * source - <mxCellState> that represents the source terminal.
 * target - <mxCellState> that represents the target terminal.
 */
mxGraphView.prototype.updatePoints = function(edge, points, source, target)
{
	if (edge != null)
	{
		var pts = [];
		pts.push(edge.absolutePoints[0]);
		var edgeStyle = this.getEdgeStyle(edge, points, source, target);
		
		if (edgeStyle != null)
		{
			var src = this.getTerminalPort(edge, source, true);
			var trg = this.getTerminalPort(edge, target, false);
			
			// Uses the stencil bounds for routing and restores after routing
			var srcBounds = this.updateBoundsFromStencil(src);
			var trgBounds = this.updateBoundsFromStencil(trg);

			edgeStyle(edge, src, trg, points, pts);
			
			// Restores previous bounds
			if (srcBounds != null)
			{
				src.setRect(srcBounds.x, srcBounds.y, srcBounds.width, srcBounds.height);
			}
			
			if (trgBounds != null)
			{
				trg.setRect(trgBounds.x, trgBounds.y, trgBounds.width, trgBounds.height);
			}
		}
		else if (points != null)
		{
			for (var i = 0; i < points.length; i++)
			{
				if (points[i] != null)
				{
					var pt = mxUtils.clone(points[i]);
					pts.push(this.transformControlPoint(edge, pt));
				}
			}
		}
		
		var tmp = edge.absolutePoints;
		pts.push(tmp[tmp.length-1]);

		edge.absolutePoints = pts;
	}
};

/**
 * Function: transformControlPoint
 *
 * Transforms the given control point to an absolute point.
 */
mxGraphView.prototype.transformControlPoint = function(state, pt)
{
	if (state != null && pt != null)
	{
		var orig = state.origin;
		
	    return new mxPoint(this.scale * (pt.x + this.translate.x + orig.x),
	    	this.scale * (pt.y + this.translate.y + orig.y));
	}
	
	return null;
};

/**
 * Function: isLoopStyleEnabled
 * 
 * Returns true if the given edge should be routed with <mxGraph.defaultLoopStyle>
 * or the <mxConstants.STYLE_LOOP> defined for the given edge. This implementation
 * returns true if the given edge is a loop and does not 
 */
mxGraphView.prototype.isLoopStyleEnabled = function(edge, points, source, target)
{
	var sc = this.graph.getConnectionConstraint(edge, source, true);
	var tc = this.graph.getConnectionConstraint(edge, target, false);
	
	if (!mxUtils.getValue(edge.style, mxConstants.STYLE_ORTHOGONAL_LOOP, false) ||
		((sc == null || sc.point == null) && (tc == null || tc.point == null)))
	{
		return source != null && source == target;
	}
	
	return false;
};

/**
 * Function: getEdgeStyle
 * 
 * Returns the edge style function to be used to render the given edge state.
 */
mxGraphView.prototype.getEdgeStyle = function(edge, points, source, target)
{
	var edgeStyle = this.isLoopStyleEnabled(edge, points, source, target) ?
		mxUtils.getValue(edge.style, mxConstants.STYLE_LOOP, this.graph.defaultLoopStyle) :
		(!mxUtils.getValue(edge.style, mxConstants.STYLE_NOEDGESTYLE, false) ?
		edge.style[mxConstants.STYLE_EDGE] : null);

	// Converts string values to objects
	if (typeof(edgeStyle) == "string")
	{
		var tmp = mxStyleRegistry.getValue(edgeStyle);
		
		if (tmp == null && this.isAllowEval())
		{
 			tmp = mxUtils.eval(edgeStyle);
		}
		
		edgeStyle = tmp;
	}
	
	if (typeof(edgeStyle) == "function")
	{
		return edgeStyle;
	}
	
	return null;
};

/**
 * Function: updateFloatingTerminalPoints
 *
 * Updates the terminal points in the given state after the edge style was
 * computed for the edge.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose terminal points should be updated.
 * source - <mxCellState> that represents the source terminal.
 * target - <mxCellState> that represents the target terminal.
 */
mxGraphView.prototype.updateFloatingTerminalPoints = function(state, source, target)
{
	var pts = state.absolutePoints;
	var p0 = pts[0];
	var pe = pts[pts.length - 1];

	if (pe == null && target != null)
	{
		this.updateFloatingTerminalPoint(state, target, source, false);
	}
	
	if (p0 == null && source != null)
	{
		this.updateFloatingTerminalPoint(state, source, target, true);
	}
};

/**
 * Function: updateFloatingTerminalPoint
 *
 * Updates the absolute terminal point in the given state for the given
 * start and end state, where start is the source if source is true.
 * 
 * Parameters:
 * 
 * edge - <mxCellState> whose terminal point should be updated.
 * start - <mxCellState> for the terminal on "this" side of the edge.
 * end - <mxCellState> for the terminal on the other side of the edge.
 * source - Boolean indicating if start is the source terminal state.
 */
mxGraphView.prototype.updateFloatingTerminalPoint = function(edge, start, end, source)
{
	edge.setAbsoluteTerminalPoint(this.getFloatingTerminalPoint(edge, start, end, source), source);
};

/**
 * Function: getFloatingTerminalPoint
 * 
 * Returns the floating terminal point for the given edge, start and end
 * state, where start is the source if source is true.
 * 
 * Parameters:
 * 
 * edge - <mxCellState> whose terminal point should be returned.
 * start - <mxCellState> for the terminal on "this" side of the edge.
 * end - <mxCellState> for the terminal on the other side of the edge.
 * source - Boolean indicating if start is the source terminal state.
 */
mxGraphView.prototype.getFloatingTerminalPoint = function(edge, start, end, source)
{
	start = this.getTerminalPort(edge, start, source);
	var next = this.getNextPoint(edge, end, source);
	
	var orth = this.graph.isOrthogonal(edge);
	var alpha = mxUtils.toRadians(Number(start.style[mxConstants.STYLE_ROTATION] || '0'));
	var center = new mxPoint(start.getCenterX(), start.getCenterY());
	
	if (alpha != 0)
	{
		var cos = Math.cos(-alpha);
		var sin = Math.sin(-alpha);
		next = mxUtils.getRotatedPoint(next, cos, sin, center);
	}
	
	var border = parseFloat(edge.style[mxConstants.STYLE_PERIMETER_SPACING] || 0);
	border += parseFloat(edge.style[(source) ?
		mxConstants.STYLE_SOURCE_PERIMETER_SPACING :
		mxConstants.STYLE_TARGET_PERIMETER_SPACING] || 0);
	var pt = this.getPerimeterPoint(start, next, alpha == 0 && orth, border);

	if (alpha != 0)
	{
		var cos = Math.cos(alpha);
		var sin = Math.sin(alpha);
		pt = mxUtils.getRotatedPoint(pt, cos, sin, center);
	}
	
	return pt;
};

/**
 * Function: getTerminalPort
 * 
 * Returns an <mxCellState> that represents the source or target terminal or
 * port for the given edge.
 * 
 * Parameters:
 * 
 * state - <mxCellState> that represents the state of the edge.
 * terminal - <mxCellState> that represents the terminal.
 * source - Boolean indicating if the given terminal is the source terminal.
 */
mxGraphView.prototype.getTerminalPort = function(state, terminal, source)
{
	var key = (source) ? mxConstants.STYLE_SOURCE_PORT :
		mxConstants.STYLE_TARGET_PORT;
	var id = mxUtils.getValue(state.style, key);
	
	if (id != null)
	{
		var tmp = this.getState(this.graph.getModel().getCell(id));
		
		// Only uses ports where a cell state exists
		if (tmp != null)
		{
			terminal = tmp;
		}
	}
	
	return terminal;
};

/**
 * Function: getPerimeterPoint
 *
 * Returns an <mxPoint> that defines the location of the intersection point between
 * the perimeter and the line between the center of the shape and the given point.
 * 
 * Parameters:
 * 
 * terminal - <mxCellState> for the source or target terminal.
 * next - <mxPoint> that lies outside of the given terminal.
 * orthogonal - Boolean that specifies if the orthogonal projection onto
 * the perimeter should be returned. If this is false then the intersection
 * of the perimeter and the line between the next and the center point is
 * returned.
 * border - Optional border between the perimeter and the shape.
 */
mxGraphView.prototype.getPerimeterPoint = function(terminal, next, orthogonal, border)
{
	var point = null;
	
	if (terminal != null)
	{
		var perimeter = this.getPerimeterFunction(terminal);
		
		if (perimeter != null && next != null)
		{
			var bounds = this.getPerimeterBounds(terminal, border);

			if (bounds.width > 0 || bounds.height > 0)
			{
				point = new mxPoint(next.x, next.y);
				var flipH = false;
				var flipV = false;	
				
				if (this.graph.model.isVertex(terminal.cell))
				{
					flipH = mxUtils.getValue(terminal.style, mxConstants.STYLE_FLIPH, 0) == 1;
					flipV = mxUtils.getValue(terminal.style, mxConstants.STYLE_FLIPV, 0) == 1;	
	
					// Legacy support for stencilFlipH/V
					if (terminal.shape != null && terminal.shape.stencil != null)
					{
						flipH = (mxUtils.getValue(terminal.style, 'stencilFlipH', 0) == 1) || flipH;
						flipV = (mxUtils.getValue(terminal.style, 'stencilFlipV', 0) == 1) || flipV;
					}
	
					if (flipH)
					{
						point.x = 2 * bounds.getCenterX() - point.x;
					}
					
					if (flipV)
					{
						point.y = 2 * bounds.getCenterY() - point.y;
					}
				}
				
				point = perimeter(bounds, terminal, point, orthogonal);

				if (point != null)
				{
					if (flipH)
					{
						point.x = 2 * bounds.getCenterX() - point.x;
					}
					
					if (flipV)
					{
						point.y = 2 * bounds.getCenterY() - point.y;
					}
				}
			}
		}
		
		if (point == null)
		{
			point = this.getPoint(terminal);
		}
	}
	
	return point;
};

/**
 * Function: getRoutingCenterX
 * 
 * Returns the x-coordinate of the center point for automatic routing.
 */
mxGraphView.prototype.getRoutingCenterX = function (state)
{
	var f = (state.style != null) ? parseFloat(state.style
		[mxConstants.STYLE_ROUTING_CENTER_X]) || 0 : 0;

	return state.getCenterX() + f * state.width;
};

/**
 * Function: getRoutingCenterY
 * 
 * Returns the y-coordinate of the center point for automatic routing.
 */
mxGraphView.prototype.getRoutingCenterY = function (state)
{
	var f = (state.style != null) ? parseFloat(state.style
		[mxConstants.STYLE_ROUTING_CENTER_Y]) || 0 : 0;

	return state.getCenterY() + f * state.height;
};

/**
 * Function: getPerimeterBounds
 *
 * Returns the perimeter bounds for the given terminal, edge pair as an
 * <mxRectangle>.
 * 
 * If you have a model where each terminal has a relative child that should
 * act as the graphical endpoint for a connection from/to the terminal, then
 * this method can be replaced as follows:
 * 
 * (code)
 * var oldGetPerimeterBounds = mxGraphView.prototype.getPerimeterBounds;
 * mxGraphView.prototype.getPerimeterBounds = function(terminal, edge, isSource)
 * {
 *   var model = this.graph.getModel();
 *   var childCount = model.getChildCount(terminal.cell);
 * 
 *   if (childCount > 0)
 *   {
 *     var child = model.getChildAt(terminal.cell, 0);
 *     var geo = model.getGeometry(child);
 *
 *     if (geo != null &&
 *         geo.relative)
 *     {
 *       var state = this.getState(child);
 *       
 *       if (state != null)
 *       {
 *         terminal = state;
 *       }
 *     }
 *   }
 *   
 *   return oldGetPerimeterBounds.apply(this, arguments);
 * };
 * (end)
 * 
 * Parameters:
 * 
 * terminal - <mxCellState> that represents the terminal.
 * border - Number that adds a border between the shape and the perimeter.
 */
mxGraphView.prototype.getPerimeterBounds = function(terminal, border)
{
	border = (border != null) ? border : 0;

	if (terminal != null)
	{
		border += parseFloat(terminal.style[mxConstants.STYLE_PERIMETER_SPACING] || 0);
	}

	return terminal.getPerimeterBounds(border * this.scale);
};

/**
 * Function: getPerimeterFunction
 *
 * Returns the perimeter function for the given state.
 */
mxGraphView.prototype.getPerimeterFunction = function(state)
{
	var perimeter = state.style[mxConstants.STYLE_PERIMETER];

	// Converts string values to objects
	if (typeof(perimeter) == "string")
	{
		var tmp = mxStyleRegistry.getValue(perimeter);
		
		if (tmp == null && this.isAllowEval())
		{
 			tmp = mxUtils.eval(perimeter);
		}

		perimeter = tmp;
	}
	
	if (typeof(perimeter) == "function")
	{
		return perimeter;
	}
	
	return null;
};

/**
 * Function: getNextPoint
 *
 * Returns the nearest point in the list of absolute points or the center
 * of the opposite terminal.
 * 
 * Parameters:
 * 
 * edge - <mxCellState> that represents the edge.
 * opposite - <mxCellState> that represents the opposite terminal.
 * source - Boolean indicating if the next point for the source or target
 * should be returned.
 */
mxGraphView.prototype.getNextPoint = function(edge, opposite, source)
{
	var pts = edge.absolutePoints;
	var point = null;
	
	if (pts != null && pts.length >= 2)
	{
		var count = pts.length;
		point = pts[(source) ? Math.min(1, count - 1) : Math.max(0, count - 2)];
	}
	
	if (point == null && opposite != null)
	{
		point = new mxPoint(opposite.getCenterX(), opposite.getCenterY());
	}
	
	return point;
};

/**
 * Function: getVisibleTerminal
 *
 * Returns the nearest ancestor terminal that is visible. The edge appears
 * to be connected to this terminal on the display. The result of this method
 * is cached in <mxCellState.getVisibleTerminalState>.
 * 
 * Parameters:
 * 
 * edge - <mxCell> whose visible terminal should be returned.
 * source - Boolean that specifies if the source or target terminal
 * should be returned.
 */
mxGraphView.prototype.getVisibleTerminal = function(edge, source)
{
	var model = this.graph.getModel();
	var result = model.getTerminal(edge, source);
	var best = result;
	
	while (result != null && result != this.currentRoot)
	{
		if (!this.graph.isCellVisible(best) || this.isCellCollapsed(result))
		{
			best = result;
		}
		
		result = model.getParent(result);
	}

	// Checks if the result is not a layer
	if (model.getParent(best) == model.getRoot())
	{
		best = null;
	}
	
	return best;
};

/**
 * Function: updateEdgeBounds
 *
 * Updates the given state using the bounding box of t
 * he absolute points.
 * Also updates <mxCellState.terminalDistance>, <mxCellState.length> and
 * <mxCellState.segments>.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose bounds should be updated.
 */
mxGraphView.prototype.updateEdgeBounds = function(state)
{
	var points = state.absolutePoints;
	var p0 = points[0];
	var pe = points[points.length - 1];
	
	if (p0.x != pe.x || p0.y != pe.y)
	{
		var dx = pe.x - p0.x;
		var dy = pe.y - p0.y;
		state.terminalDistance = Math.sqrt(dx * dx + dy * dy);
	}
	else
	{
		state.terminalDistance = 0;
	}
	
	var length = 0;
	var segments = [];
	var pt = p0;
	
	if (pt != null)
	{
		var minX = pt.x;
		var minY = pt.y;
		var maxX = minX;
		var maxY = minY;
		
		for (var i = 1; i < points.length; i++)
		{
			var tmp = points[i];
			
			if (tmp != null)
			{
				var dx = pt.x - tmp.x;
				var dy = pt.y - tmp.y;
				
				var segment = Math.sqrt(dx * dx + dy * dy);
				segments.push(segment);
				length += segment;
				
				pt = tmp;
				
				minX = Math.min(pt.x, minX);
				minY = Math.min(pt.y, minY);
				maxX = Math.max(pt.x, maxX);
				maxY = Math.max(pt.y, maxY);
			}
		}
		
		state.length = length;
		state.segments = segments;
		
		var markerSize = 1; // TODO: include marker size
		
		state.x = minX;
		state.y = minY;
		state.width = Math.max(markerSize, maxX - minX);
		state.height = Math.max(markerSize, maxY - minY);
	}
};

/**
 * Function: getPoint
 *
 * Returns the absolute point on the edge for the given relative
 * <mxGeometry> as an <mxPoint>. The edge is represented by the given
 * <mxCellState>.
 * 
 * Parameters:
 * 
 * state - <mxCellState> that represents the state of the parent edge.
 * geometry - <mxGeometry> that represents the relative location.
 */
mxGraphView.prototype.getPoint = function(state, geometry)
{
	var x = state.getCenterX();
	var y = state.getCenterY();
	
	if (state.segments != null && (geometry == null || geometry.relative))
	{
		var gx = (geometry != null) ? geometry.x / 2 : 0;
		var pointCount = state.absolutePoints.length;
		var dist = Math.round((gx + 0.5) * state.length);
		var segment = state.segments[0];
		var length = 0;				
		var index = 1;

		while (dist >= Math.round(length + segment) && index < pointCount - 1)
		{
			length += segment;
			segment = state.segments[index++];
		}

		var factor = (segment == 0) ? 0 : (dist - length) / segment;
		var p0 = state.absolutePoints[index-1];
		var pe = state.absolutePoints[index];

		if (p0 != null && pe != null)
		{
			var gy = 0;
			var offsetX = 0;
			var offsetY = 0;

			if (geometry != null)
			{
				gy = geometry.y;
				var offset = geometry.offset;
				
				if (offset != null)
				{
					offsetX = offset.x;
					offsetY = offset.y;
				}
			}

			var dx = pe.x - p0.x;
			var dy = pe.y - p0.y;
			var nx = (segment == 0) ? 0 : dy / segment;
			var ny = (segment == 0) ? 0 : dx / segment;
			
			x = p0.x + dx * factor + (nx * gy + offsetX) * this.scale;
			y = p0.y + dy * factor - (ny * gy - offsetY) * this.scale;
		}
	}
	else if (geometry != null)
	{
		var offset = geometry.offset;
		
		if (offset != null)
		{
			x += offset.x;
			y += offset.y;
		}
	}
	
	return new mxPoint(x, y);		
};

/**
 * Function: getRelativePoint
 *
 * Gets the relative point that describes the given, absolute label
 * position for the given edge state.
 * 
 * Parameters:
 * 
 * state - <mxCellState> that represents the state of the parent edge.
 * x - Specifies the x-coordinate of the absolute label location.
 * y - Specifies the y-coordinate of the absolute label location.
 */
mxGraphView.prototype.getRelativePoint = function(edgeState, x, y)
{
	var model = this.graph.getModel();
	var geometry = model.getGeometry(edgeState.cell);
	
	if (geometry != null)
	{
		var pointCount = edgeState.absolutePoints.length;
		
		if (geometry.relative && pointCount > 1)
		{
			var totalLength = edgeState.length;
			var segments = edgeState.segments;

			// Works which line segment the point of the label is closest to
			var p0 = edgeState.absolutePoints[0];
			var pe = edgeState.absolutePoints[1];
			var minDist = mxUtils.ptSegDistSq(p0.x, p0.y, pe.x, pe.y, x, y);

			var index = 0;
			var tmp = 0;
			var length = 0;
			
			for (var i = 2; i < pointCount; i++)
			{
				tmp += segments[i - 2];
				pe = edgeState.absolutePoints[i];
				var dist = mxUtils.ptSegDistSq(p0.x, p0.y, pe.x, pe.y, x, y);

				if (dist <= minDist)
				{
					minDist = dist;
					index = i - 1;
					length = tmp;
				}
				
				p0 = pe;
			}
			
			var seg = segments[index];
			p0 = edgeState.absolutePoints[index];
			pe = edgeState.absolutePoints[index + 1];
			
			var x2 = p0.x;
			var y2 = p0.y;
			
			var x1 = pe.x;
			var y1 = pe.y;
			
			var px = x;
			var py = y;
			
			var xSegment = x2 - x1;
			var ySegment = y2 - y1;
			
			px -= x1;
			py -= y1;
			var projlenSq = 0;
			
			px = xSegment - px;
			py = ySegment - py;
			var dotprod = px * xSegment + py * ySegment;

			if (dotprod <= 0.0)
			{
				projlenSq = 0;
			}
			else
			{
				projlenSq = dotprod * dotprod
						/ (xSegment * xSegment + ySegment * ySegment);
			}

			var projlen = Math.sqrt(projlenSq);

			if (projlen > seg)
			{
				projlen = seg;
			}

			var yDistance = Math.sqrt(mxUtils.ptSegDistSq(p0.x, p0.y, pe
					.x, pe.y, x, y));
			var direction = mxUtils.relativeCcw(p0.x, p0.y, pe.x, pe.y, x, y);

			if (direction == -1)
			{
				yDistance = -yDistance;
			}

			// Constructs the relative point for the label
			return new mxPoint(((totalLength / 2 - length - projlen) / totalLength) * -2,
						yDistance / this.scale);
		}
	}
	
	return new mxPoint();
};

/**
 * Function: updateEdgeLabelOffset
 *
 * Updates <mxCellState.absoluteOffset> for the given state. The absolute
 * offset is normally used for the position of the edge label. Is is
 * calculated from the geometry as an absolute offset from the center
 * between the two endpoints if the geometry is absolute, or as the
 * relative distance between the center along the line and the absolute
 * orthogonal distance if the geometry is relative.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose absolute offset should be updated.
 */
mxGraphView.prototype.updateEdgeLabelOffset = function(state)
{
	var points = state.absolutePoints;
	
	state.absoluteOffset.x = state.getCenterX();
	state.absoluteOffset.y = state.getCenterY();

	if (points != null && points.length > 0 && state.segments != null)
	{
		var geometry = this.graph.getCellGeometry(state.cell);
		
		if (geometry.relative)
		{
			var offset = this.getPoint(state, geometry);
			
			if (offset != null)
			{
				state.absoluteOffset = offset;
			}
		}
		else
		{
			var p0 = points[0];
			var pe = points[points.length - 1];
			
			if (p0 != null && pe != null)
			{
				var dx = pe.x - p0.x;
				var dy = pe.y - p0.y;
				var x0 = 0;
				var y0 = 0;

				var off = geometry.offset;
				
				if (off != null)
				{
					x0 = off.x;
					y0 = off.y;
				}
				
				var x = p0.x + dx / 2 + x0 * this.scale;
				var y = p0.y + dy / 2 + y0 * this.scale;
				
				state.absoluteOffset.x = x;
				state.absoluteOffset.y = y;
			}
		}
	}
};

/**
 * Function: getState
 *
 * Returns the <mxCellState> for the given cell. If create is true, then
 * the state is created if it does not yet exist.
 * 
 * Parameters:
 * 
 * cell - <mxCell> for which the <mxCellState> should be returned.
 * create - Optional boolean indicating if a new state should be created
 * if it does not yet exist. Default is false.
 */
mxGraphView.prototype.getState = function(cell, create)
{
	create = create || false;
	var state = null;
	
	if (cell != null)
	{
		state = this.states.get(cell);
		
		if (create && (state == null || this.updateStyle) && this.graph.isCellVisible(cell))
		{
			if (state == null)
			{
				state = this.createState(cell);
				this.states.put(cell, state);
			}
			else
			{
				state.style = this.graph.getCellStyle(cell);
			}
		}
	}

	return state;
};

/**
 * Function: isRendering
 *
 * Returns <rendering>.
 */
mxGraphView.prototype.isRendering = function()
{
	return this.rendering;
};

/**
 * Function: setRendering
 *
 * Sets <rendering>.
 */
mxGraphView.prototype.setRendering = function(value)
{
	this.rendering = value;
};

/**
 * Function: isAllowEval
 *
 * Returns <allowEval>.
 */
mxGraphView.prototype.isAllowEval = function()
{
	return this.allowEval;
};

/**
 * Function: setAllowEval
 *
 * Sets <allowEval>.
 */
mxGraphView.prototype.setAllowEval = function(value)
{
	this.allowEval = value;
};

/**
 * Function: getStates
 *
 * Returns <states>.
 */
mxGraphView.prototype.getStates = function()
{
	return this.states;
};

/**
 * Function: setStates
 *
 * Sets <states>.
 */
mxGraphView.prototype.setStates = function(value)
{
	this.states = value;
};

/**
 * Function: getCellStates
 *
 * Returns the <mxCellStates> for the given array of <mxCells>. The array
 * contains all states that are not null, that is, the returned array may
 * have less elements than the given array. If no argument is given, then
 * this returns <states>.
 */
mxGraphView.prototype.getCellStates = function(cells)
{
	if (cells == null)
	{
		return this.states;
	}
	else
	{
		var result = [];
		
		for (var i = 0; i < cells.length; i++)
		{
			var state = this.getState(cells[i]);
			
			if (state != null)
			{
				result.push(state);
			}
		}
		
		return result;
	}
};

/**
 * Function: removeState
 *
 * Removes and returns the <mxCellState> for the given cell.
 * 
 * Parameters:
 * 
 * cell - <mxCell> for which the <mxCellState> should be removed.
 */
mxGraphView.prototype.removeState = function(cell)
{
	var state = null;
	
	if (cell != null)
	{
		state = this.states.remove(cell);
		
		if (state != null)
		{
			this.graph.cellRenderer.destroy(state);
			state.invalid = true;
			state.destroy();
		}
	}
	
	return state;
};

/**
 * Function: createState
 *
 * Creates and returns an <mxCellState> for the given cell and initializes
 * it using <mxCellRenderer.initialize>.
 * 
 * Parameters:
 * 
 * cell - <mxCell> for which a new <mxCellState> should be created.
 */
mxGraphView.prototype.createState = function(cell)
{
	return new mxCellState(this, cell, this.graph.getCellStyle(cell));
};

/**
 * Function: getCanvas
 *
 * Returns the DOM node that contains the background-, draw- and
 * overlay- and decoratorpanes.
 */
mxGraphView.prototype.getCanvas = function()
{
	return this.canvas;
};

/**
 * Function: getBackgroundPane
 *
 * Returns the DOM node that represents the background layer.
 */
mxGraphView.prototype.getBackgroundPane = function()
{
	return this.backgroundPane;
};

/**
 * Function: getDrawPane
 *
 * Returns the DOM node that represents the main drawing layer.
 */
mxGraphView.prototype.getDrawPane = function()
{
	return this.drawPane;
};

/**
 * Function: getOverlayPane
 *
 * Returns the DOM node that represents the layer above the drawing layer.
 */
mxGraphView.prototype.getOverlayPane = function()
{
	return this.overlayPane;
};

/**
 * Function: getDecoratorPane
 *
 * Returns the DOM node that represents the topmost drawing layer.
 */
mxGraphView.prototype.getDecoratorPane = function()
{
	return this.decoratorPane;
};

/**
 * Function: isContainerEvent
 * 
 * Returns true if the event origin is one of the drawing panes or
 * containers of the view.
 */
mxGraphView.prototype.isContainerEvent = function(evt)
{
	var source = mxEvent.getSource(evt);

	return (source == this.graph.container ||
		source.parentNode == this.backgroundPane ||
		(source.parentNode != null &&
		source.parentNode.parentNode == this.backgroundPane) ||
		source == this.canvas.parentNode ||
		source == this.canvas ||
		source == this.backgroundPane ||
		source == this.drawPane ||
		source == this.overlayPane ||
		source == this.decoratorPane);
};

/**
 * Function: isScrollEvent
 * 
 * Returns true if the event origin is one of the scrollbars of the
 * container in IE. Such events are ignored.
 */
 mxGraphView.prototype.isScrollEvent = function(evt)
{
	var offset = mxUtils.getOffset(this.graph.container);
	var pt = new mxPoint(evt.clientX - offset.x, evt.clientY - offset.y);

	var outWidth = this.graph.container.offsetWidth;
	var inWidth = this.graph.container.clientWidth;

	if (outWidth > inWidth && pt.x > inWidth + 2 && pt.x <= outWidth)
	{
		return true;
	}

	var outHeight = this.graph.container.offsetHeight;
	var inHeight = this.graph.container.clientHeight;
	
	if (outHeight > inHeight && pt.y > inHeight + 2 && pt.y <= outHeight)
	{
		return true;
	}
	
	return false;
};

/**
 * Function: init
 *
 * Initializes the graph event dispatch loop for the specified container
 * and invokes <create> to create the required DOM nodes for the display.
 */
mxGraphView.prototype.init = function()
{
	this.installListeners();
	
	// Creates the DOM nodes for the respective display dialect
	var graph = this.graph;
	
	if (graph.dialect == mxConstants.DIALECT_SVG)
	{
		this.createSvg();
	}
	else if (graph.dialect == mxConstants.DIALECT_VML)
	{
		this.createVml();
	}
	else
	{
		this.createHtml();
	}
};

/**
 * Function: installListeners
 *
 * Installs the required listeners in the container.
 */
mxGraphView.prototype.installListeners = function()
{
	var graph = this.graph;
	var container = graph.container;
	
	if (container != null)
	{
		// Support for touch device gestures (eg. pinch to zoom)
		// Double-tap handling is implemented in mxGraph.fireMouseEvent
		if (mxClient.IS_TOUCH)
		{
			mxEvent.addListener(container, 'gesturestart', mxUtils.bind(this, function(evt)
			{
				graph.fireGestureEvent(evt);
				mxEvent.consume(evt);
			}));
			
			mxEvent.addListener(container, 'gesturechange', mxUtils.bind(this, function(evt)
			{
				graph.fireGestureEvent(evt);
				mxEvent.consume(evt);
			}));

			mxEvent.addListener(container, 'gestureend', mxUtils.bind(this, function(evt)
			{
				graph.fireGestureEvent(evt);
				mxEvent.consume(evt);
			}));
		}
		
		// Adds basic listeners for graph event dispatching
		mxEvent.addGestureListeners(container, mxUtils.bind(this, function(evt)
		{
			// Condition to avoid scrollbar events starting a rubberband selection
			if (this.isContainerEvent(evt) && ((!mxClient.IS_IE && !mxClient.IS_IE11 && !mxClient.IS_GC &&
				!mxClient.IS_OP && !mxClient.IS_SF) || !this.isScrollEvent(evt)))
			{
				graph.fireMouseEvent(mxEvent.MOUSE_DOWN, new mxMouseEvent(evt));
			}
		}),
		mxUtils.bind(this, function(evt)
		{
			if (this.isContainerEvent(evt))
			{
				graph.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt));
			}
		}),
		mxUtils.bind(this, function(evt)
		{
			if (this.isContainerEvent(evt))
			{
				graph.fireMouseEvent(mxEvent.MOUSE_UP, new mxMouseEvent(evt));
			}
		}));
		
		// Adds listener for double click handling on background, this does always
		// use native event handler, we assume that the DOM of the background
		// does not change during the double click
		mxEvent.addListener(container, 'dblclick', mxUtils.bind(this, function(evt)
		{
			if (this.isContainerEvent(evt))
			{
				graph.dblClick(evt);
			}
		}));

		// Workaround for touch events which started on some DOM node
		// on top of the container, in which case the cells under the
		// mouse for the move and up events are not detected.
		var getState = function(evt)
		{
			var state = null;
			
			// Workaround for touch events which started on some DOM node
			// on top of the container, in which case the cells under the
			// mouse for the move and up events are not detected.
			if (mxClient.IS_TOUCH)
			{
				var x = mxEvent.getClientX(evt);
				var y = mxEvent.getClientY(evt);
				
				// Dispatches the drop event to the graph which
				// consumes and executes the source function
				var pt = mxUtils.convertPoint(container, x, y);
				state = graph.view.getState(graph.getCellAt(pt.x, pt.y));
			}
			
			return state;
		};
		
		// Adds basic listeners for graph event dispatching outside of the
		// container and finishing the handling of a single gesture
		// Implemented via graph event dispatch loop to avoid duplicate events
		// in Firefox and Chrome
		graph.addMouseListener(
		{
			mouseDown: function(sender, me)
			{
				graph.popupMenuHandler.hideMenu();
			},
			mouseMove: function() { },
			mouseUp: function() { }
		});
		
		this.moveHandler = mxUtils.bind(this, function(evt)
		{
			// Hides the tooltip if mouse is outside container
			if (graph.tooltipHandler != null && graph.tooltipHandler.isHideOnHover())
			{
				graph.tooltipHandler.hide();
			}

			if (this.captureDocumentGesture && graph.isMouseDown && graph.container != null &&
				!this.isContainerEvent(evt) && graph.container.style.display != 'none' &&
				graph.container.style.visibility != 'hidden' && !mxEvent.isConsumed(evt))
			{
				graph.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt, getState(evt)));
			}
		});
		
		this.endHandler = mxUtils.bind(this, function(evt)
		{
			if (this.captureDocumentGesture && graph.isMouseDown && graph.container != null &&
				!this.isContainerEvent(evt) && graph.container.style.display != 'none' &&
				graph.container.style.visibility != 'hidden')
			{
				graph.fireMouseEvent(mxEvent.MOUSE_UP, new mxMouseEvent(evt));
			}
		});
		
		mxEvent.addGestureListeners(document, null, this.moveHandler, this.endHandler);
	}
};

/**
 * Function: create
 *
 * Creates the DOM nodes for the HTML display.
 */
mxGraphView.prototype.createHtml = function()
{
	var container = this.graph.container;
	
	if (container != null)
	{
		this.canvas = this.createHtmlPane('100%', '100%');
		this.canvas.style.overflow = 'hidden';
	
		// Uses minimal size for inner DIVs on Canvas. This is required
		// for correct event processing in IE. If we have an overlapping
		// DIV then the events on the cells are only fired for labels.
		this.backgroundPane = this.createHtmlPane('1px', '1px');
		this.drawPane = this.createHtmlPane('1px', '1px');
		this.overlayPane = this.createHtmlPane('1px', '1px');
		this.decoratorPane = this.createHtmlPane('1px', '1px');
		
		this.canvas.appendChild(this.backgroundPane);
		this.canvas.appendChild(this.drawPane);
		this.canvas.appendChild(this.overlayPane);
		this.canvas.appendChild(this.decoratorPane);

		container.appendChild(this.canvas);
		this.updateContainerStyle(container);
		
		// Implements minWidth/minHeight in quirks mode
		if (mxClient.IS_QUIRKS)
		{
			var onResize = mxUtils.bind(this, function(evt)
			{
				var bounds = this.getGraphBounds();
				var width = bounds.x + bounds.width + this.graph.border;
				var height = bounds.y + bounds.height + this.graph.border;
				
				this.updateHtmlCanvasSize(width, height);
			});
			
			mxEvent.addListener(window, 'resize', onResize);
		}
	}
};

/**
 * Function: updateHtmlCanvasSize
 * 
 * Updates the size of the HTML canvas.
 */
mxGraphView.prototype.updateHtmlCanvasSize = function(width, height)
{
	if (this.graph.container != null)
	{
		var ow = this.graph.container.offsetWidth;
		var oh = this.graph.container.offsetHeight;

		if (ow < width)
		{
			this.canvas.style.width = width + 'px';
		}
		else
		{
			this.canvas.style.width = '100%';
		}

		if (oh < height)
		{
			this.canvas.style.height = height + 'px';
		}
		else
		{
			this.canvas.style.height = '100%';
		}
	}
};

/**
 * Function: createHtmlPane
 * 
 * Creates and returns a drawing pane in HTML (DIV).
 */
mxGraphView.prototype.createHtmlPane = function(width, height)
{
	var pane = document.createElement('DIV');
	
	if (width != null && height != null)
	{
		pane.style.position = 'absolute';
		pane.style.left = '0px';
		pane.style.top = '0px';

		pane.style.width = width;
		pane.style.height = height;
	}
	else
	{
		pane.style.position = 'relative';
	}
	
	return pane;
};

/**
 * Function: create
 *
 * Creates the DOM nodes for the VML display.
 */
mxGraphView.prototype.createVml = function()
{
	var container = this.graph.container;

	if (container != null)
	{
		var width = container.offsetWidth;
		var height = container.offsetHeight;
		this.canvas = this.createVmlPane(width, height);
		this.canvas.style.overflow = 'hidden';
		
		this.backgroundPane = this.createVmlPane(width, height);
		this.drawPane = this.createVmlPane(width, height);
		this.overlayPane = this.createVmlPane(width, height);
		this.decoratorPane = this.createVmlPane(width, height);
		
		this.canvas.appendChild(this.backgroundPane);
		this.canvas.appendChild(this.drawPane);
		this.canvas.appendChild(this.overlayPane);
		this.canvas.appendChild(this.decoratorPane);
		
		container.appendChild(this.canvas);
	}
};

/**
 * Function: createVmlPane
 * 
 * Creates a drawing pane in VML (group).
 */
mxGraphView.prototype.createVmlPane = function(width, height)
{
	var pane = document.createElement(mxClient.VML_PREFIX + ':group');
	
	// At this point the width and height are potentially
	// uninitialized. That's OK.
	pane.style.position = 'absolute';
	pane.style.left = '0px';
	pane.style.top = '0px';

	pane.style.width = width + 'px';
	pane.style.height = height + 'px';

	pane.setAttribute('coordsize', width + ',' + height);
	pane.setAttribute('coordorigin', '0,0');
	
	return pane;
};

/**
 * Function: create
 *
 * Creates and returns the DOM nodes for the SVG display.
 */
mxGraphView.prototype.createSvg = function()
{
	var container = this.graph.container;
	this.canvas = document.createElementNS(mxConstants.NS_SVG, 'g');
	
	// For background image
	this.backgroundPane = document.createElementNS(mxConstants.NS_SVG, 'g');
	this.canvas.appendChild(this.backgroundPane);

	// Adds two layers (background is early feature)
	this.drawPane = document.createElementNS(mxConstants.NS_SVG, 'g');
	this.canvas.appendChild(this.drawPane);

	this.overlayPane = document.createElementNS(mxConstants.NS_SVG, 'g');
	this.canvas.appendChild(this.overlayPane);
	
	this.decoratorPane = document.createElementNS(mxConstants.NS_SVG, 'g');
	this.canvas.appendChild(this.decoratorPane);
	
	var root = document.createElementNS(mxConstants.NS_SVG, 'svg');
	root.style.width = '100%';
	root.style.height = '100%';
	
	// NOTE: In standards mode, the SVG must have block layout
	// in order for the container DIV to not show scrollbars.
	root.style.display = 'block';
	root.appendChild(this.canvas);
	
	// Workaround for scrollbars in IE11 and below
	if (mxClient.IS_IE || mxClient.IS_IE11)
	{
		root.style.overflow = 'hidden';
	}

	if (container != null)
	{
		container.appendChild(root);
		this.updateContainerStyle(container);
	}
};

/**
 * Function: updateContainerStyle
 * 
 * Updates the style of the container after installing the SVG DOM elements.
 */
mxGraphView.prototype.updateContainerStyle = function(container)
{
	// Workaround for offset of container
	var style = mxUtils.getCurrentStyle(container);
	
	if (style != null && style.position == 'static')
	{
		container.style.position = 'relative';
	}
	
	// Disables built-in pan and zoom in IE10 and later
	if (mxClient.IS_POINTER)
	{
		container.style.touchAction = 'none';
	}
};

/**
 * Function: destroy
 * 
 * Destroys the view and all its resources.
 */
mxGraphView.prototype.destroy = function()
{
	var root = (this.canvas != null) ? this.canvas.ownerSVGElement : null;
	
	if (root == null)
	{
		root = this.canvas;
	}
	
	if (root != null && root.parentNode != null)
	{
		this.clear(this.currentRoot, true);
		mxEvent.removeGestureListeners(document, null, this.moveHandler, this.endHandler);
		mxEvent.release(this.graph.container);
		root.parentNode.removeChild(root);
		
		this.moveHandler = null;
		this.endHandler = null;
		this.canvas = null;
		this.backgroundPane = null;
		this.drawPane = null;
		this.overlayPane = null;
		this.decoratorPane = null;
	}
};

/**
 * Class: mxCurrentRootChange
 *
 * Action to change the current root in a view.
 *
 * Constructor: mxCurrentRootChange
 *
 * Constructs a change of the current root in the given view.
 */
function mxCurrentRootChange(view, root)
{
	this.view = view;
	this.root = root;
	this.previous = root;
	this.isUp = root == null;
	
	if (!this.isUp)
	{
		var tmp = this.view.currentRoot;
		var model = this.view.graph.getModel();
		
		while (tmp != null)
		{
			if (tmp == root)
			{
				this.isUp = true;
				break;
			}
			
			tmp = model.getParent(tmp);
		}
	}
};

/**
 * Function: execute
 *
 * Changes the current root of the view.
 */
mxCurrentRootChange.prototype.execute = function()
{
	var tmp = this.view.currentRoot;
	this.view.currentRoot = this.previous;
	this.previous = tmp;

	var translate = this.view.graph.getTranslateForRoot(this.view.currentRoot);
	
	if (translate != null)
	{
		this.view.translate = new mxPoint(-translate.x, -translate.y);
	}

	if (this.isUp)
	{
		this.view.clear(this.view.currentRoot, true);
		this.view.validate();
	}
	else
	{
		this.view.refresh();
	}
	
	var name = (this.isUp) ? mxEvent.UP : mxEvent.DOWN;
	this.view.fireEvent(new mxEventObject(name,
		'root', this.view.currentRoot, 'previous', this.previous));
	this.isUp = !this.isUp;
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxGraph
 *
 * Extends <mxEventSource> to implement a graph component for
 * the browser. This is the main class of the package. To activate
 * panning and connections use <setPanning> and <setConnectable>.
 * For rubberband selection you must create a new instance of
 * <mxRubberband>. The following listeners are added to
 * <mouseListeners> by default:
 * 
 * - <tooltipHandler>: <mxTooltipHandler> that displays tooltips
 * - <panningHandler>: <mxPanningHandler> for panning and popup menus
 * - <connectionHandler>: <mxConnectionHandler> for creating connections
 * - <graphHandler>: <mxGraphHandler> for moving and cloning cells
 * 
 * These listeners will be called in the above order if they are enabled.
 *
 * Background Images:
 * 
 * To display a background image, set the image, image width and
 * image height using <setBackgroundImage>. If one of the
 * above values has changed then the <view>'s <mxGraphView.validate>
 * should be invoked.
 * 
 * Cell Images:
 * 
 * To use images in cells, a shape must be specified in the default
 * vertex style (or any named style). Possible shapes are
 * <mxConstants.SHAPE_IMAGE> and <mxConstants.SHAPE_LABEL>.
 * The code to change the shape used in the default vertex style,
 * the following code is used:
 * 
 * (code)
 * var style = graph.getStylesheet().getDefaultVertexStyle();
 * style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_IMAGE;
 * (end)
 * 
 * For the default vertex style, the image to be displayed can be
 * specified in a cell's style using the <mxConstants.STYLE_IMAGE>
 * key and the image URL as a value, for example:
 * 
 * (code)
 * image=http://www.example.com/image.gif
 * (end)
 * 
 * For a named style, the the stylename must be the first element
 * of the cell style:
 * 
 * (code)
 * stylename;image=http://www.example.com/image.gif
 * (end)
 * 
 * A cell style can have any number of key=value pairs added, divided
 * by a semicolon as follows:
 * 
 * (code)
 * [stylename;|key=value;]
 * (end)
 *
 * Labels:
 * 
 * The cell labels are defined by <getLabel> which uses <convertValueToString>
 * if <labelsVisible> is true. If a label must be rendered as HTML markup, then
 * <isHtmlLabel> should return true for the respective cell. If all labels
 * contain HTML markup, <htmlLabels> can be set to true. NOTE: Enabling HTML
 * labels carries a possible security risk (see the section on security in
 * the manual).
 * 
 * If wrapping is needed for a label, then <isHtmlLabel> and <isWrapping> must
 * return true for the cell whose label should be wrapped. See <isWrapping> for
 * an example.
 * 
 * If clipping is needed to keep the rendering of a HTML label inside the
 * bounds of its vertex, then <isClipping> should return true for the
 * respective cell.
 * 
 * By default, edge labels are movable and vertex labels are fixed. This can be
 * changed by setting <edgeLabelsMovable> and <vertexLabelsMovable>, or by
 * overriding <isLabelMovable>.
 *
 * In-place Editing:
 * 
 * In-place editing is started with a doubleclick or by typing F2.
 * Programmatically, <edit> is used to check if the cell is editable
 * (<isCellEditable>) and call <startEditingAtCell>, which invokes
 * <mxCellEditor.startEditing>. The editor uses the value returned
 * by <getEditingValue> as the editing value.
 * 
 * After in-place editing, <labelChanged> is called, which invokes
 * <mxGraphModel.setValue>, which in turn calls
 * <mxGraphModel.valueForCellChanged> via <mxValueChange>.
 * 
 * The event that triggers in-place editing is passed through to the
 * <cellEditor>, which may take special actions depending on the type of the
 * event or mouse location, and is also passed to <getEditingValue>. The event
 * is then passed back to the event processing functions which can perform
 * specific actions based on the trigger event.
 * 
 * Tooltips:
 * 
 * Tooltips are implemented by <getTooltip>, which calls <getTooltipForCell>
 * if a cell is under the mousepointer. The default implementation checks if
 * the cell has a getTooltip function and calls it if it exists. Hence, in order
 * to provide custom tooltips, the cell must provide a getTooltip function, or 
 * one of the two above functions must be overridden.
 * 
 * Typically, for custom cell tooltips, the latter function is overridden as
 * follows:
 * 
 * (code)
 * graph.getTooltipForCell = function(cell)
 * {
 *   var label = this.convertValueToString(cell);
 *   return 'Tooltip for '+label;
 * }
 * (end)
 * 
 * When using a config file, the function is overridden in the mxGraph section
 * using the following entry:
 * 
 * (code)
 * <add as="getTooltipForCell"><![CDATA[
 *   function(cell)
 *   {
 *     var label = this.convertValueToString(cell);
 *     return 'Tooltip for '+label;
 *   }
 * ]]></add>
 * (end)
 * 
 * "this" refers to the graph in the implementation, so for example to check if 
 * a cell is an edge, you use this.getModel().isEdge(cell)
 *
 * For replacing the default implementation of <getTooltipForCell> (rather than 
 * replacing the function on a specific instance), the following code should be 
 * used after loading the JavaScript files, but before creating a new mxGraph 
 * instance using <mxGraph>:
 * 
 * (code)
 * mxGraph.prototype.getTooltipForCell = function(cell)
 * {
 *   var label = this.convertValueToString(cell);
 *   return 'Tooltip for '+label;
 * }
 * (end)
 * 
 * Shapes & Styles:
 * 
 * The implementation of new shapes is demonstrated in the examples. We'll assume
 * that we have implemented a custom shape with the name BoxShape which we want
 * to use for drawing vertices. To use this shape, it must first be registered in
 * the cell renderer as follows:
 * 
 * (code)
 * mxCellRenderer.registerShape('box', BoxShape);
 * (end)
 * 
 * The code registers the BoxShape constructor under the name box in the cell
 * renderer of the graph. The shape can now be referenced using the shape-key in
 * a style definition. (The cell renderer contains a set of additional shapes,
 * namely one for each constant with a SHAPE-prefix in <mxConstants>.)
 *
 * Styles are a collection of key, value pairs and a stylesheet is a collection
 * of named styles. The names are referenced by the cellstyle, which is stored
 * in <mxCell.style> with the following format: [stylename;|key=value;]. The
 * string is resolved to a collection of key, value pairs, where the keys are
 * overridden with the values in the string.
 *
 * When introducing a new shape, the name under which the shape is registered
 * must be used in the stylesheet. There are three ways of doing this:
 * 
 *   - By changing the default style, so that all vertices will use the new
 * 		shape
 *   - By defining a new style, so that only vertices with the respective
 * 		cellstyle will use the new shape
 *   - By using shape=box in the cellstyle's optional list of key, value pairs
 * 		to be overridden
 *
 * In the first case, the code to fetch and modify the default style for
 * vertices is as follows:
 * 
 * (code)
 * var style = graph.getStylesheet().getDefaultVertexStyle();
 * style[mxConstants.STYLE_SHAPE] = 'box';
 * (end)
 * 
 * The code takes the default vertex style, which is used for all vertices that
 * do not have a specific cellstyle, and modifies the value for the shape-key
 * in-place to use the new BoxShape for drawing vertices. This is done by
 * assigning the box value in the second line, which refers to the name of the
 * BoxShape in the cell renderer.
 * 
 * In the second case, a collection of key, value pairs is created and then
 * added to the stylesheet under a new name. In order to distinguish the
 * shapename and the stylename we'll use boxstyle for the stylename:
 * 
 * (code)
 * var style = new Object();
 * style[mxConstants.STYLE_SHAPE] = 'box';
 * style[mxConstants.STYLE_STROKECOLOR] = '#000000';
 * style[mxConstants.STYLE_FONTCOLOR] = '#000000';
 * graph.getStylesheet().putCellStyle('boxstyle', style);
 * (end)
 * 
 * The code adds a new style with the name boxstyle to the stylesheet. To use
 * this style with a cell, it must be referenced from the cellstyle as follows:
 * 
 * (code)
 * var vertex = graph.insertVertex(parent, null, 'Hello, World!', 20, 20, 80, 20,
 * 				'boxstyle');
 * (end)
 * 
 * To summarize, each new shape must be registered in the <mxCellRenderer> with
 * a unique name. That name is then used as the value of the shape-key in a
 * default or custom style. If there are multiple custom shapes, then there
 * should be a separate style for each shape.
 * 
 * Inheriting Styles:
 * 
 * For fill-, stroke-, gradient- and indicatorColors special keywords can be
 * used. The inherit keyword for one of these colors will inherit the color
 * for the same key from the parent cell. The swimlane keyword does the same,
 * but inherits from the nearest swimlane in the ancestor hierarchy. Finally,
 * the indicated keyword will use the color of the indicator as the color for
 * the given key.
 * 
 * Scrollbars:
 * 
 * The <containers> overflow CSS property defines if scrollbars are used to
 * display the graph. For values of 'auto' or 'scroll', the scrollbars will
 * be shown. Note that the <resizeContainer> flag is normally not used
 * together with scrollbars, as it will resize the container to match the
 * size of the graph after each change.
 * 
 * Multiplicities and Validation:
 * 
 * To control the possible connections in mxGraph, <getEdgeValidationError> is
 * used. The default implementation of the function uses <multiplicities>,
 * which is an array of <mxMultiplicity>. Using this class allows to establish
 * simple multiplicities, which are enforced by the graph.
 * 
 * The <mxMultiplicity> uses <mxCell.is> to determine for which terminals it
 * applies. The default implementation of <mxCell.is> works with DOM nodes (XML
 * nodes) and checks if the given type parameter matches the nodeName of the
 * node (case insensitive). Optionally, an attributename and value can be
 * specified which are also checked.
 * 
 * <getEdgeValidationError> is called whenever the connectivity of an edge
 * changes. It returns an empty string or an error message if the edge is
 * invalid or null if the edge is valid. If the returned string is not empty
 * then it is displayed as an error message.
 * 
 * <mxMultiplicity> allows to specify the multiplicity between a terminal and
 * its possible neighbors. For example, if any rectangle may only be connected
 * to, say, a maximum of two circles you can add the following rule to
 * <multiplicities>:
 * 
 * (code)
 * graph.multiplicities.push(new mxMultiplicity(
 *   true, 'rectangle', null, null, 0, 2, ['circle'],
 *   'Only 2 targets allowed',
 *   'Only shape targets allowed'));
 * (end)
 * 
 * This will display the first error message whenever a rectangle is connected
 * to more than two circles and the second error message if a rectangle is
 * connected to anything but a circle.
 * 
 * For certain multiplicities, such as a minimum of 1 connection, which cannot
 * be enforced at cell creation time (unless the cell is created together with
 * the connection), mxGraph offers <validate> which checks all multiplicities
 * for all cells and displays the respective error messages in an overlay icon
 * on the cells.
 * 
 * If a cell is collapsed and contains validation errors, a respective warning
 * icon is attached to the collapsed cell.
 * 
 * Auto-Layout:
 * 
 * For automatic layout, the <getLayout> hook is provided in <mxLayoutManager>.
 * It can be overridden to return a layout algorithm for the children of a
 * given cell.
 * 
 * Unconnected edges:
 * 
 * The default values for all switches are designed to meet the requirements of
 * general diagram drawing applications. A very typical set of settings to
 * avoid edges that are not connected is the following:
 * 
 * (code)
 * graph.setAllowDanglingEdges(false);
 * graph.setDisconnectOnMove(false);
 * (end)
 * 
 * Setting the <cloneInvalidEdges> switch to true is optional. This switch
 * controls if edges are inserted after a copy, paste or clone-drag if they are
 * invalid. For example, edges are invalid if copied or control-dragged without 
 * having selected the corresponding terminals and allowDanglingEdges is
 * false, in which case the edges will not be cloned if the switch is false.
 * 
 * Output:
 * 
 * To produce an XML representation for a diagram, the following code can be
 * used.
 * 
 * (code)
 * var enc = new mxCodec(mxUtils.createXmlDocument());
 * var node = enc.encode(graph.getModel());
 * (end)
 * 
 * This will produce an XML node than can be handled using the DOM API or
 * turned into a string representation using the following code:
 * 
 * (code)
 * var xml = mxUtils.getXml(node);
 * (end)
 * 
 * To obtain a formatted string, mxUtils.getPrettyXml can be used instead.
 * 
 * This string can now be stored in a local persistent storage (for example
 * using Google Gears) or it can be passed to a backend using mxUtils.post as
 * follows. The url variable is the URL of the Java servlet, PHP page or HTTP
 * handler, depending on the server.
 * 
 * (code)
 * var xmlString = encodeURIComponent(mxUtils.getXml(node));
 * mxUtils.post(url, 'xml='+xmlString, function(req)
 * {
 *   // Process server response using req of type mxXmlRequest
 * });
 * (end)
 * 
 * Input:
 * 
 * To load an XML representation of a diagram into an existing graph object
 * mxUtils.load can be used as follows. The url variable is the URL of the Java
 * servlet, PHP page or HTTP handler that produces the XML string.
 * 
 * (code)
 * var xmlDoc = mxUtils.load(url).getXml();
 * var node = xmlDoc.documentElement;
 * var dec = new mxCodec(node.ownerDocument);
 * dec.decode(node, graph.getModel());
 * (end)
 * 
 * For creating a page that loads the client and a diagram using a single
 * request please refer to the deployment examples in the backends.
 * 
 * Functional dependencies:
 * 
 * (see images/callgraph.png)
 * 
 * Resources:
 *
 * resources/graph - Language resources for mxGraph
 *
 * Group: Events
 * 
 * Event: mxEvent.ROOT
 * 
 * Fires if the root in the model has changed. This event has no properties.
 * 
 * Event: mxEvent.ALIGN_CELLS
 * 
 * Fires between begin- and endUpdate in <alignCells>. The <code>cells</code>
 * and <code>align</code> properties contain the respective arguments that were
 * passed to <alignCells>.
 *
 * Event: mxEvent.FLIP_EDGE
 *
 * Fires between begin- and endUpdate in <flipEdge>. The <code>edge</code>
 * property contains the edge passed to <flipEdge>.
 * 
 * Event: mxEvent.ORDER_CELLS
 * 
 * Fires between begin- and endUpdate in <orderCells>. The <code>cells</code>
 * and <code>back</code> properties contain the respective arguments that were
 * passed to <orderCells>.
 *
 * Event: mxEvent.CELLS_ORDERED
 *
 * Fires between begin- and endUpdate in <cellsOrdered>. The <code>cells</code>
 * and <code>back</code> arguments contain the respective arguments that were
 * passed to <cellsOrdered>.
 * 
 * Event: mxEvent.GROUP_CELLS
 * 
 * Fires between begin- and endUpdate in <groupCells>. The <code>group</code>,
 * <code>cells</code> and <code>border</code> arguments contain the respective
 * arguments that were passed to <groupCells>.
 * 
 * Event: mxEvent.UNGROUP_CELLS
 * 
 * Fires between begin- and endUpdate in <ungroupCells>. The <code>cells</code>
 * property contains the array of cells that was passed to <ungroupCells>.
 * 
 * Event: mxEvent.REMOVE_CELLS_FROM_PARENT
 * 
 * Fires between begin- and endUpdate in <removeCellsFromParent>. The
 * <code>cells</code> property contains the array of cells that was passed to
 * <removeCellsFromParent>.
 * 
 * Event: mxEvent.ADD_CELLS
 * 
 * Fires between begin- and endUpdate in <addCells>. The <code>cells</code>,
 * <code>parent</code>, <code>index</code>, <code>source</code> and
 * <code>target</code> properties contain the respective arguments that were
 * passed to <addCells>.
 * 
 * Event: mxEvent.CELLS_ADDED
 * 
 * Fires between begin- and endUpdate in <cellsAdded>. The <code>cells</code>,
 * <code>parent</code>, <code>index</code>, <code>source</code>,
 * <code>target</code> and <code>absolute</code> properties contain the
 * respective arguments that were passed to <cellsAdded>.
 * 
 * Event: mxEvent.REMOVE_CELLS
 * 
 * Fires between begin- and endUpdate in <removeCells>. The <code>cells</code>
 * and <code>includeEdges</code> arguments contain the respective arguments
 * that were passed to <removeCells>.
 * 
 * Event: mxEvent.CELLS_REMOVED
 * 
 * Fires between begin- and endUpdate in <cellsRemoved>. The <code>cells</code>
 * argument contains the array of cells that was removed.
 * 
 * Event: mxEvent.SPLIT_EDGE
 * 
 * Fires between begin- and endUpdate in <splitEdge>. The <code>edge</code>
 * property contains the edge to be splitted, the <code>cells</code>,
 * <code>newEdge</code>, <code>dx</code> and <code>dy</code> properties contain
 * the respective arguments that were passed to <splitEdge>.
 * 
 * Event: mxEvent.TOGGLE_CELLS
 * 
 * Fires between begin- and endUpdate in <toggleCells>. The <code>show</code>,
 * <code>cells</code> and <code>includeEdges</code> properties contain the
 * respective arguments that were passed to <toggleCells>.
 * 
 * Event: mxEvent.FOLD_CELLS
 * 
 * Fires between begin- and endUpdate in <foldCells>. The
 * <code>collapse</code>, <code>cells</code> and <code>recurse</code>
 * properties contain the respective arguments that were passed to <foldCells>.
 * 
 * Event: mxEvent.CELLS_FOLDED
 * 
 * Fires between begin- and endUpdate in cellsFolded. The
 * <code>collapse</code>, <code>cells</code> and <code>recurse</code>
 * properties contain the respective arguments that were passed to
 * <cellsFolded>.
 * 
 * Event: mxEvent.UPDATE_CELL_SIZE
 * 
 * Fires between begin- and endUpdate in <updateCellSize>. The
 * <code>cell</code> and <code>ignoreChildren</code> properties contain the
 * respective arguments that were passed to <updateCellSize>.
 * 
 * Event: mxEvent.RESIZE_CELLS
 * 
 * Fires between begin- and endUpdate in <resizeCells>. The <code>cells</code>
 * and <code>bounds</code> properties contain the respective arguments that
 * were passed to <resizeCells>.
 * 
 * Event: mxEvent.CELLS_RESIZED
 * 
 * Fires between begin- and endUpdate in <cellsResized>. The <code>cells</code>
 * and <code>bounds</code> properties contain the respective arguments that
 * were passed to <cellsResized>.
 * 
 * Event: mxEvent.MOVE_CELLS
 * 
 * Fires between begin- and endUpdate in <moveCells>. The <code>cells</code>,
 * <code>dx</code>, <code>dy</code>, <code>clone</code>, <code>target</code>
 * and <code>event</code> properties contain the respective arguments that
 * were passed to <moveCells>.
 * 
 * Event: mxEvent.CELLS_MOVED
 * 
 * Fires between begin- and endUpdate in <cellsMoved>. The <code>cells</code>,
 * <code>dx</code>, <code>dy</code> and <code>disconnect</code> properties
 * contain the respective arguments that were passed to <cellsMoved>.
 * 
 * Event: mxEvent.CONNECT_CELL
 * 
 * Fires between begin- and endUpdate in <connectCell>. The <code>edge</code>,
 * <code>terminal</code> and <code>source</code> properties contain the
 * respective arguments that were passed to <connectCell>.
 * 
 * Event: mxEvent.CELL_CONNECTED
 * 
 * Fires between begin- and endUpdate in <cellConnected>. The
 * <code>edge</code>, <code>terminal</code> and <code>source</code> properties
 * contain the respective arguments that were passed to <cellConnected>.
 * 
 * Event: mxEvent.REFRESH
 * 
 * Fires after <refresh> was executed. This event has no properties.
 *
 * Event: mxEvent.CLICK
 * 
 * Fires in <click> after a click event. The <code>event</code> property
 * contains the original mouse event and <code>cell</code> property contains
 * the cell under the mouse or null if the background was clicked.
 * 
 * Event: mxEvent.DOUBLE_CLICK
 *
 * Fires in <dblClick> after a double click. The <code>event</code> property
 * contains the original mouse event and the <code>cell</code> property
 * contains the cell under the mouse or null if the background was clicked.
 * 
 * Event: mxEvent.GESTURE
 *
 * Fires in <fireGestureEvent> after a touch gesture. The <code>event</code>
 * property contains the original gesture end event and the <code>cell</code>
 * property contains the optional cell associated with the gesture.
 *
 * Event: mxEvent.TAP_AND_HOLD
 *
 * Fires in <tapAndHold> if a tap and hold event was detected. The <code>event</code>
 * property contains the initial touch event and the <code>cell</code> property
 * contains the cell under the mouse or null if the background was clicked.
 *
 * Event: mxEvent.FIRE_MOUSE_EVENT
 *
 * Fires in <fireMouseEvent> before the mouse listeners are invoked. The
 * <code>eventName</code> property contains the event name and the
 * <code>event</code> property contains the <mxMouseEvent>.
 *
 * Event: mxEvent.SIZE
 *
 * Fires after <sizeDidChange> was executed. The <code>bounds</code> property
 * contains the new graph bounds.
 *
 * Event: mxEvent.START_EDITING
 *
 * Fires before the in-place editor starts in <startEditingAtCell>. The
 * <code>cell</code> property contains the cell that is being edited and the
 * <code>event</code> property contains the optional event argument that was
 * passed to <startEditingAtCell>.
 * 
 * Event: mxEvent.EDITING_STARTED
 *
 * Fires after the in-place editor starts in <startEditingAtCell>. The
 * <code>cell</code> property contains the cell that is being edited and the
 * <code>event</code> property contains the optional event argument that was
 * passed to <startEditingAtCell>.
 * 
 * Event: mxEvent.EDITING_STOPPED
 *
 * Fires after the in-place editor stops in <stopEditing>.
 *
 * Event: mxEvent.LABEL_CHANGED
 *
 * Fires between begin- and endUpdate in <cellLabelChanged>. The
 * <code>cell</code> property contains the cell, the <code>value</code>
 * property contains the new value for the cell, the <code>old</code> property
 * contains the old value and the optional <code>event</code> property contains
 * the mouse event that started the edit.
 * 
 * Event: mxEvent.ADD_OVERLAY
 *
 * Fires after an overlay is added in <addCellOverlay>. The <code>cell</code>
 * property contains the cell and the <code>overlay</code> property contains
 * the <mxCellOverlay> that was added.
 *
 * Event: mxEvent.REMOVE_OVERLAY
 *
 * Fires after an overlay is removed in <removeCellOverlay> and
 * <removeCellOverlays>. The <code>cell</code> property contains the cell and
 * the <code>overlay</code> property contains the <mxCellOverlay> that was
 * removed.
 * 
 * Constructor: mxGraph
 * 
 * Constructs a new mxGraph in the specified container. Model is an optional
 * mxGraphModel. If no model is provided, a new mxGraphModel instance is 
 * used as the model. The container must have a valid owner document prior 
 * to calling this function in Internet Explorer. RenderHint is a string to
 * affect the display performance and rendering in IE, but not in SVG-based 
 * browsers. The parameter is mapped to <dialect>, which may 
 * be one of <mxConstants.DIALECT_SVG> for SVG-based browsers, 
 * <mxConstants.DIALECT_STRICTHTML> for fastest display mode,
 * <mxConstants.DIALECT_PREFERHTML> for faster display mode,
 * <mxConstants.DIALECT_MIXEDHTML> for fast and <mxConstants.DIALECT_VML> 
 * for exact display mode (slowest). The dialects are defined in mxConstants.
 * The default values are DIALECT_SVG for SVG-based browsers and
 * DIALECT_MIXED for IE.
 *
 * The possible values for the renderingHint parameter are explained below:
 * 
 * fast - The parameter is based on the fact that the display performance is 
 * highly improved in IE if the VML is not contained within a VML group 
 * element. The lack of a group element only slightly affects the display while 
 * panning, but improves the performance by almost a factor of 2, while keeping 
 * the display sufficiently accurate. This also allows to render certain shapes as HTML 
 * if the display accuracy is not affected, which is implemented by 
 * <mxShape.isMixedModeHtml>. This is the default setting and is mapped to
 * DIALECT_MIXEDHTML.
 * faster - Same as fast, but more expensive shapes are avoided. This is 
 * controlled by <mxShape.preferModeHtml>. The default implementation will 
 * avoid gradients and rounded rectangles, but more significant shapes, such 
 * as rhombus, ellipse, actor and cylinder will be rendered accurately. This 
 * setting is mapped to DIALECT_PREFERHTML.
 * fastest - Almost anything will be rendered in Html. This allows for 
 * rectangles, labels and images. This setting is mapped to
 * DIALECT_STRICTHTML.
 * exact - If accurate panning is required and if the diagram is small (up
 * to 100 cells), then this value should be used. In this mode, a group is 
 * created that contains the VML. This allows for accurate panning and is 
 * mapped to DIALECT_VML.
 *
 * Example:
 * 
 * To create a graph inside a DOM node with an id of graph:
 * (code)
 * var container = document.getElementById('graph');
 * var graph = new mxGraph(container);
 * (end)
 * 
 * Parameters:
 * 
 * container - Optional DOM node that acts as a container for the graph.
 * If this is null then the container can be initialized later using
 * <init>.
 * model - Optional <mxGraphModel> that constitutes the graph data.
 * renderHint - Optional string that specifies the display accuracy and
 * performance. Default is mxConstants.DIALECT_MIXEDHTML (for IE).
 * stylesheet - Optional <mxStylesheet> to be used in the graph.
 */
function mxGraph(container, model, renderHint, stylesheet)
{
	// Initializes the variable in case the prototype has been
	// modified to hold some listeners (which is possible because
	// the createHandlers call is executed regardless of the
	// arguments passed into the ctor).
	this.mouseListeners = null;
	
	// Converts the renderHint into a dialect
	this.renderHint = renderHint;

	if (mxClient.IS_SVG)
	{
		this.dialect = mxConstants.DIALECT_SVG;
	}
	else if (renderHint == mxConstants.RENDERING_HINT_EXACT && mxClient.IS_VML)
	{
		this.dialect = mxConstants.DIALECT_VML;
	}
	else if (renderHint == mxConstants.RENDERING_HINT_FASTEST)
	{
		this.dialect = mxConstants.DIALECT_STRICTHTML;
	}
	else if (renderHint == mxConstants.RENDERING_HINT_FASTER)
	{
		this.dialect = mxConstants.DIALECT_PREFERHTML;
	}
	else // default for VML
	{
		this.dialect = mxConstants.DIALECT_MIXEDHTML;
	}
	
	// Initializes the main members that do not require a container
	this.model = (model != null) ? model : new mxGraphModel();
	this.multiplicities = [];
	this.imageBundles = [];
	this.cellRenderer = this.createCellRenderer();
	this.setSelectionModel(this.createSelectionModel());
	this.setStylesheet((stylesheet != null) ? stylesheet : this.createStylesheet());
	this.view = this.createGraphView();
	
	// Adds a graph model listener to update the view
	this.graphModelChangeListener = mxUtils.bind(this, function(sender, evt)
	{
		this.graphModelChanged(evt.getProperty('edit').changes);
	});
	
	this.model.addListener(mxEvent.CHANGE, this.graphModelChangeListener);

	// Installs basic event handlers with disabled default settings.
	this.createHandlers();
	
	// Initializes the display if a container was specified
	if (container != null)
	{
		this.init(container);
	}
	
	this.view.revalidate();
};

/**
 * Installs the required language resources at class
 * loading time.
 */
if (mxLoadResources)
{
	mxResources.add(mxClient.basePath+'/resources/graph');
}

/**
 * Extends mxEventSource.
 */
mxGraph.prototype = new mxEventSource();
mxGraph.prototype.constructor = mxGraph;

/**
 * Variable: EMPTY_ARRAY
 *
 * Immutable empty array instance.
 */
mxGraph.prototype.EMPTY_ARRAY = [];

/**
 * Group: Variables
 */

/**
 * Variable: mouseListeners
 * 
 * Holds the mouse event listeners. See <fireMouseEvent>.
 */
mxGraph.prototype.mouseListeners = null;

/**
 * Variable: isMouseDown
 * 
 * Holds the state of the mouse button.
 */
mxGraph.prototype.isMouseDown = false;

/**
 * Variable: model
 * 
 * Holds the <mxGraphModel> that contains the cells to be displayed.
 */
mxGraph.prototype.model = null;

/**
 * Variable: view
 * 
 * Holds the <mxGraphView> that caches the <mxCellStates> for the cells.
 */
mxGraph.prototype.view = null;

/**
 * Variable: stylesheet
 * 
 * Holds the <mxStylesheet> that defines the appearance of the cells.
 * 
 * 
 * Example:
 * 
 * Use the following code to read a stylesheet into an existing graph.
 * 
 * (code)
 * var req = mxUtils.load('stylesheet.xml');
 * var root = req.getDocumentElement();
 * var dec = new mxCodec(root.ownerDocument);
 * dec.decode(root, graph.stylesheet);
 * (end)
 */
mxGraph.prototype.stylesheet = null;
	
/**
 * Variable: selectionModel
 * 
 * Holds the <mxGraphSelectionModel> that models the current selection.
 */
mxGraph.prototype.selectionModel = null;

/**
 * Variable: cellEditor
 * 
 * Holds the <mxCellEditor> that is used as the in-place editing.
 */
mxGraph.prototype.cellEditor = null;

/**
 * Variable: cellRenderer
 * 
 * Holds the <mxCellRenderer> for rendering the cells in the graph.
 */
mxGraph.prototype.cellRenderer = null;

/**
 * Variable: multiplicities
 * 
 * An array of <mxMultiplicities> describing the allowed
 * connections in a graph.
 */
mxGraph.prototype.multiplicities = null;

/**
 * Variable: renderHint
 * 
 * RenderHint as it was passed to the constructor.
 */
mxGraph.prototype.renderHint = null;

/**
 * Variable: dialect
 * 
 * Dialect to be used for drawing the graph. Possible values are all
 * constants in <mxConstants> with a DIALECT-prefix.
 */
mxGraph.prototype.dialect = null;

/**
 * Variable: gridSize
 * 
 * Specifies the grid size. Default is 10.
 */
mxGraph.prototype.gridSize = 10;
	
/**
 * Variable: gridEnabled
 * 
 * Specifies if the grid is enabled. This is used in <snap>. Default is
 * true.
 */
mxGraph.prototype.gridEnabled = true;

/**
 * Variable: portsEnabled
 * 
 * Specifies if ports are enabled. This is used in <cellConnected> to update
 * the respective style. Default is true.
 */
mxGraph.prototype.portsEnabled = true;

/**
 * Variable: nativeDoubleClickEnabled
 * 
 * Specifies if native double click events should be detected. Default is true.
 */
mxGraph.prototype.nativeDblClickEnabled = true;

/**
 * Variable: doubleTapEnabled
 * 
 * Specifies if double taps on touch-based devices should be handled as a
 * double click. Default is true.
 */
mxGraph.prototype.doubleTapEnabled = true;

/**
 * Variable: doubleTapTimeout
 * 
 * Specifies the timeout for double taps and non-native double clicks. Default
 * is 500 ms.
 */
mxGraph.prototype.doubleTapTimeout = 500;

/**
 * Variable: doubleTapTolerance
 * 
 * Specifies the tolerance for double taps and double clicks in quirks mode.
 * Default is 25 pixels.
 */
mxGraph.prototype.doubleTapTolerance = 25;

/**
 * Variable: lastTouchX
 * 
 * Holds the x-coordinate of the last touch event for double tap detection.
 */
mxGraph.prototype.lastTouchY = 0;

/**
 * Variable: lastTouchX
 * 
 * Holds the y-coordinate of the last touch event for double tap detection.
 */
mxGraph.prototype.lastTouchY = 0;

/**
 * Variable: lastTouchTime
 * 
 * Holds the time of the last touch event for double click detection.
 */
mxGraph.prototype.lastTouchTime = 0;

/**
 * Variable: tapAndHoldEnabled
 * 
 * Specifies if tap and hold should be used for starting connections on touch-based
 * devices. Default is true.
 */
mxGraph.prototype.tapAndHoldEnabled = true;

/**
 * Variable: tapAndHoldDelay
 * 
 * Specifies the time for a tap and hold. Default is 500 ms.
 */
mxGraph.prototype.tapAndHoldDelay = 500;

/**
 * Variable: tapAndHoldInProgress
 * 
 * True if the timer for tap and hold events is running.
 */
mxGraph.prototype.tapAndHoldInProgress = false;

/**
 * Variable: tapAndHoldValid
 * 
 * True as long as the timer is running and the touch events
 * stay within the given <tapAndHoldTolerance>.
 */
mxGraph.prototype.tapAndHoldValid = false;

/**
 * Variable: initialTouchX
 * 
 * Holds the x-coordinate of the intial touch event for tap and hold.
 */
mxGraph.prototype.initialTouchX = 0;

/**
 * Variable: initialTouchY
 * 
 * Holds the y-coordinate of the intial touch event for tap and hold.
 */
mxGraph.prototype.initialTouchY = 0;

/**
 * Variable: tolerance
 * 
 * Tolerance for a move to be handled as a single click.
 * Default is 4 pixels.
 */
mxGraph.prototype.tolerance = 4;

/**
 * Variable: defaultOverlap
 * 
 * Value returned by <getOverlap> if <isAllowOverlapParent> returns
 * true for the given cell. <getOverlap> is used in <constrainChild> if
 * <isConstrainChild> returns true. The value specifies the
 * portion of the child which is allowed to overlap the parent.
 */
mxGraph.prototype.defaultOverlap = 0.5;

/**
 * Variable: defaultParent
 * 
 * Specifies the default parent to be used to insert new cells.
 * This is used in <getDefaultParent>. Default is null.
 */
mxGraph.prototype.defaultParent = null;

/**
 * Variable: alternateEdgeStyle
 * 
 * Specifies the alternate edge style to be used if the main control point
 * on an edge is being doubleclicked. Default is null.
 */
mxGraph.prototype.alternateEdgeStyle = null;

/**
 * Variable: backgroundImage
 *
 * Specifies the <mxImage> to be returned by <getBackgroundImage>. Default
 * is null.
 * 
 * Example:
 *
 * (code)
 * var img = new mxImage('http://www.example.com/maps/examplemap.jpg', 1024, 768);
 * graph.setBackgroundImage(img);
 * graph.view.validate();
 * (end)
 */
mxGraph.prototype.backgroundImage = null;

/**
 * Variable: pageVisible
 *
 * Specifies if the background page should be visible. Default is false.
 * Not yet implemented.
 */
mxGraph.prototype.pageVisible = false;

/**
 * Variable: pageBreaksVisible
 * 
 * Specifies if a dashed line should be drawn between multiple pages. Default
 * is false. If you change this value while a graph is being displayed then you
 * should call <sizeDidChange> to force an update of the display.
 */
mxGraph.prototype.pageBreaksVisible = false;

/**
 * Variable: pageBreakColor
 * 
 * Specifies the color for page breaks. Default is 'gray'.
 */
mxGraph.prototype.pageBreakColor = 'gray';

/**
 * Variable: pageBreakDashed
 * 
 * Specifies the page breaks should be dashed. Default is true.
 */
mxGraph.prototype.pageBreakDashed = true;

/**
 * Variable: minPageBreakDist
 * 
 * Specifies the minimum distance for page breaks to be visible. Default is
 * 20 (in pixels).
 */
mxGraph.prototype.minPageBreakDist = 20;

/**
 * Variable: preferPageSize
 * 
 * Specifies if the graph size should be rounded to the next page number in
 * <sizeDidChange>. This is only used if the graph container has scrollbars.
 * Default is false.
 */
mxGraph.prototype.preferPageSize = false;

/**
 * Variable: pageFormat
 *
 * Specifies the page format for the background page. Default is
 * <mxConstants.PAGE_FORMAT_A4_PORTRAIT>. This is used as the default in
 * <mxPrintPreview> and for painting the background page if <pageVisible> is
 * true and the pagebreaks if <pageBreaksVisible> is true.
 */
mxGraph.prototype.pageFormat = mxConstants.PAGE_FORMAT_A4_PORTRAIT;

/**
 * Variable: pageScale
 *
 * Specifies the scale of the background page. Default is 1.5.
 * Not yet implemented.
 */
mxGraph.prototype.pageScale = 1.5;

/**
 * Variable: enabled
 * 
 * Specifies the return value for <isEnabled>. Default is true.
 */
mxGraph.prototype.enabled = true;

/**
 * Variable: escapeEnabled
 * 
 * Specifies if <mxKeyHandler> should invoke <escape> when the escape key
 * is pressed. Default is true.
 */
mxGraph.prototype.escapeEnabled = true;

/**
 * Variable: invokesStopCellEditing
 * 
 * If true, when editing is to be stopped by way of selection changing,
 * data in diagram changing or other means stopCellEditing is invoked, and
 * changes are saved. This is implemented in a focus handler in
 * <mxCellEditor>. Default is true.
 */
mxGraph.prototype.invokesStopCellEditing = true;

/**
 * Variable: enterStopsCellEditing
 * 
 * If true, pressing the enter key without pressing control or shift will stop
 * editing and accept the new value. This is used in <mxCellEditor> to stop
 * cell editing. Note: You can always use F2 and escape to stop editing.
 * Default is false.
 */
mxGraph.prototype.enterStopsCellEditing = false;

/**
 * Variable: useScrollbarsForPanning
 * 
 * Specifies if scrollbars should be used for panning in <panGraph> if
 * any scrollbars are available. If scrollbars are enabled in CSS, but no
 * scrollbars appear because the graph is smaller than the container size,
 * then no panning occurs if this is true. Default is true.
 */
mxGraph.prototype.useScrollbarsForPanning = true;

/**
 * Variable: exportEnabled
 * 
 * Specifies the return value for <canExportCell>. Default is true.
 */
mxGraph.prototype.exportEnabled = true;

/**
 * Variable: importEnabled
 * 
 * Specifies the return value for <canImportCell>. Default is true.
 */
mxGraph.prototype.importEnabled = true;

/**
 * Variable: cellsLocked
 * 
 * Specifies the return value for <isCellLocked>. Default is false.
 */
mxGraph.prototype.cellsLocked = false;

/**
 * Variable: cellsCloneable
 * 
 * Specifies the return value for <isCellCloneable>. Default is true.
 */
mxGraph.prototype.cellsCloneable = true;

/**
 * Variable: foldingEnabled
 * 
 * Specifies if folding (collapse and expand via an image icon in the graph
 * should be enabled). Default is true.
 */
mxGraph.prototype.foldingEnabled = true;

/**
 * Variable: cellsEditable
 * 
 * Specifies the return value for <isCellEditable>. Default is true.
 */
mxGraph.prototype.cellsEditable = true;
		
/**
 * Variable: cellsDeletable
 * 
 * Specifies the return value for <isCellDeletable>. Default is true.
 */
mxGraph.prototype.cellsDeletable = true;

/**
 * Variable: cellsMovable
 * 
 * Specifies the return value for <isCellMovable>. Default is true.
 */
mxGraph.prototype.cellsMovable = true;
	
/**
 * Variable: edgeLabelsMovable
 * 
 * Specifies the return value for edges in <isLabelMovable>. Default is true.
 */
mxGraph.prototype.edgeLabelsMovable = true;
	
/**
 * Variable: vertexLabelsMovable
 * 
 * Specifies the return value for vertices in <isLabelMovable>. Default is false.
 */
mxGraph.prototype.vertexLabelsMovable = false;

/**
 * Variable: dropEnabled
 * 
 * Specifies the return value for <isDropEnabled>. Default is false.
 */
mxGraph.prototype.dropEnabled = false;

/**
 * Variable: splitEnabled
 * 
 * Specifies if dropping onto edges should be enabled. This is ignored if
 * <dropEnabled> is false. If enabled, it will call <splitEdge> to carry
 * out the drop operation. Default is true.
 */
mxGraph.prototype.splitEnabled = true;

/**
 * Variable: cellsResizable
 * 
 * Specifies the return value for <isCellResizable>. Default is true.
 */
mxGraph.prototype.cellsResizable = true;

/**
 * Variable: cellsBendable
 * 
 * Specifies the return value for <isCellsBendable>. Default is true.
 */
mxGraph.prototype.cellsBendable = true;

/**
 * Variable: cellsSelectable
 * 
 * Specifies the return value for <isCellSelectable>. Default is true.
 */
mxGraph.prototype.cellsSelectable = true;

/**
 * Variable: cellsDisconnectable
 * 
 * Specifies the return value for <isCellDisconntable>. Default is true.
 */
mxGraph.prototype.cellsDisconnectable = true;

/**
 * Variable: autoSizeCells
 * 
 * Specifies if the graph should automatically update the cell size after an
 * edit. This is used in <isAutoSizeCell>. Default is false.
 */
mxGraph.prototype.autoSizeCells = false;

/**
 * Variable: autoSizeCellsOnAdd
 * 
 * Specifies if autoSize style should be applied when cells are added. Default is false.
 */
mxGraph.prototype.autoSizeCellsOnAdd = false;

/**
 * Variable: autoScroll
 * 
 * Specifies if the graph should automatically scroll if the mouse goes near
 * the container edge while dragging. This is only taken into account if the
 * container has scrollbars. Default is true.
 * 
 * If you need this to work without scrollbars then set <ignoreScrollbars> to
 * true. Please consult the <ignoreScrollbars> for details. In general, with
 * no scrollbars, the use of <allowAutoPanning> is recommended.
 */
mxGraph.prototype.autoScroll = true;

/**
 * Variable: ignoreScrollbars
 * 
 * Specifies if the graph should automatically scroll regardless of the
 * scrollbars. This will scroll the container using positive values for
 * scroll positions (ie usually only rightwards and downwards). To avoid
 * possible conflicts with panning, set <translateToScrollPosition> to true.
 */
mxGraph.prototype.ignoreScrollbars = false;

/**
 * Variable: translateToScrollPosition
 * 
 * Specifies if the graph should automatically convert the current scroll
 * position to a translate in the graph view when a mouseUp event is received.
 * This can be used to avoid conflicts when using <autoScroll> and
 * <ignoreScrollbars> with no scrollbars in the container.
 */
mxGraph.prototype.translateToScrollPosition = false;

/**
 * Variable: timerAutoScroll
 * 
 * Specifies if autoscrolling should be carried out via mxPanningManager even
 * if the container has scrollbars. This disables <scrollPointToVisible> and
 * uses <mxPanningManager> instead. If this is true then <autoExtend> is
 * disabled. It should only be used with a scroll buffer or when scollbars
 * are visible and scrollable in all directions. Default is false.
 */
mxGraph.prototype.timerAutoScroll = false;

/**
 * Variable: allowAutoPanning
 * 
 * Specifies if panning via <panGraph> should be allowed to implement autoscroll
 * if no scrollbars are available in <scrollPointToVisible>. To enable panning
 * inside the container, near the edge, set <mxPanningManager.border> to a
 * positive value. Default is false.
 */
mxGraph.prototype.allowAutoPanning = false;

/**
 * Variable: autoExtend
 * 
 * Specifies if the size of the graph should be automatically extended if the
 * mouse goes near the container edge while dragging. This is only taken into
 * account if the container has scrollbars. Default is true. See <autoScroll>.
 */
mxGraph.prototype.autoExtend = true;

/**
 * Variable: maximumGraphBounds
 * 
 * <mxRectangle> that specifies the area in which all cells in the diagram
 * should be placed. Uses in <getMaximumGraphBounds>. Use a width or height of
 * 0 if you only want to give a upper, left corner.
 */
mxGraph.prototype.maximumGraphBounds = null;

/**
 * Variable: minimumGraphSize
 * 
 * <mxRectangle> that specifies the minimum size of the graph. This is ignored
 * if the graph container has no scrollbars. Default is null.
 */
mxGraph.prototype.minimumGraphSize = null;

/**
 * Variable: minimumContainerSize
 * 
 * <mxRectangle> that specifies the minimum size of the <container> if
 * <resizeContainer> is true.
 */
mxGraph.prototype.minimumContainerSize = null;
		
/**
 * Variable: maximumContainerSize
 * 
 * <mxRectangle> that specifies the maximum size of the container if
 * <resizeContainer> is true.
 */
mxGraph.prototype.maximumContainerSize = null;

/**
 * Variable: resizeContainer
 * 
 * Specifies if the container should be resized to the graph size when
 * the graph size has changed. Default is false.
 */
mxGraph.prototype.resizeContainer = false;

/**
 * Variable: border
 * 
 * Border to be added to the bottom and right side when the container is
 * being resized after the graph has been changed. Default is 0.
 */
mxGraph.prototype.border = 0;
		
/**
 * Variable: keepEdgesInForeground
 * 
 * Specifies if edges should appear in the foreground regardless of their order
 * in the model. If <keepEdgesInForeground> and <keepEdgesInBackground> are
 * both true then the normal order is applied. Default is false.
 */
mxGraph.prototype.keepEdgesInForeground = false;

/**
 * Variable: keepEdgesInBackground
 * 
 * Specifies if edges should appear in the background regardless of their order
 * in the model. If <keepEdgesInForeground> and <keepEdgesInBackground> are
 * both true then the normal order is applied. Default is false.
 */
mxGraph.prototype.keepEdgesInBackground = false;

/**
 * Variable: allowNegativeCoordinates
 * 
 * Specifies if negative coordinates for vertices are allowed. Default is true.
 */
mxGraph.prototype.allowNegativeCoordinates = true;

/**
 * Variable: constrainChildren
 * 
 * Specifies if a child should be constrained inside the parent bounds after a
 * move or resize of the child. Default is true.
 */
mxGraph.prototype.constrainChildren = true;

/**
 * Variable: constrainRelativeChildren
 * 
 * Specifies if child cells with relative geometries should be constrained
 * inside the parent bounds, if <constrainChildren> is true, and/or the
 * <maximumGraphBounds>. Default is false.
 */
mxGraph.prototype.constrainRelativeChildren = false;

/**
 * Variable: extendParents
 * 
 * Specifies if a parent should contain the child bounds after a resize of
 * the child. Default is true. This has precedence over <constrainChildren>.
 */
mxGraph.prototype.extendParents = true;

/**
 * Variable: extendParentsOnAdd
 * 
 * Specifies if parents should be extended according to the <extendParents>
 * switch if cells are added. Default is true.
 */
mxGraph.prototype.extendParentsOnAdd = true;

/**
 * Variable: extendParentsOnAdd
 * 
 * Specifies if parents should be extended according to the <extendParents>
 * switch if cells are added. Default is false for backwards compatiblity.
 */
mxGraph.prototype.extendParentsOnMove = false;

/**
 * Variable: recursiveResize
 * 
 * Specifies the return value for <isRecursiveResize>. Default is
 * false for backwards compatiblity.
 */
mxGraph.prototype.recursiveResize = false;

/**
 * Variable: collapseToPreferredSize
 * 
 * Specifies if the cell size should be changed to the preferred size when
 * a cell is first collapsed. Default is true.
 */
mxGraph.prototype.collapseToPreferredSize = true;

/**
 * Variable: zoomFactor
 * 
 * Specifies the factor used for <zoomIn> and <zoomOut>. Default is 1.2
 * (120%).
 */
mxGraph.prototype.zoomFactor = 1.2;

/**
 * Variable: keepSelectionVisibleOnZoom
 * 
 * Specifies if the viewport should automatically contain the selection cells
 * after a zoom operation. Default is false.
 */
mxGraph.prototype.keepSelectionVisibleOnZoom = false;

/**
 * Variable: centerZoom
 * 
 * Specifies if the zoom operations should go into the center of the actual
 * diagram rather than going from top, left. Default is true.
 */
mxGraph.prototype.centerZoom = true;

/**
 * Variable: resetViewOnRootChange
 * 
 * Specifies if the scale and translate should be reset if the root changes in
 * the model. Default is true.
 */
mxGraph.prototype.resetViewOnRootChange = true;

/**
 * Variable: resetEdgesOnResize
 * 
 * Specifies if edge control points should be reset after the resize of a
 * connected cell. Default is false.
 */
mxGraph.prototype.resetEdgesOnResize = false;

/**
 * Variable: resetEdgesOnMove
 * 
 * Specifies if edge control points should be reset after the move of a
 * connected cell. Default is false.
 */
mxGraph.prototype.resetEdgesOnMove = false;

/**
 * Variable: resetEdgesOnConnect
 * 
 * Specifies if edge control points should be reset after the the edge has been
 * reconnected. Default is true.
 */
mxGraph.prototype.resetEdgesOnConnect = true;

/**
 * Variable: allowLoops
 * 
 * Specifies if loops (aka self-references) are allowed. Default is false.
 */
mxGraph.prototype.allowLoops = false;
	
/**
 * Variable: defaultLoopStyle
 * 
 * <mxEdgeStyle> to be used for loops. This is a fallback for loops if the
 * <mxConstants.STYLE_LOOP> is undefined. Default is <mxEdgeStyle.Loop>.
 */
mxGraph.prototype.defaultLoopStyle = mxEdgeStyle.Loop;

/**
 * Variable: multigraph
 * 
 * Specifies if multiple edges in the same direction between the same pair of
 * vertices are allowed. Default is true.
 */
mxGraph.prototype.multigraph = true;

/**
 * Variable: connectableEdges
 * 
 * Specifies if edges are connectable. Default is false. This overrides the
 * connectable field in edges.
 */
mxGraph.prototype.connectableEdges = false;

/**
 * Variable: allowDanglingEdges
 * 
 * Specifies if edges with disconnected terminals are allowed in the graph.
 * Default is true.
 */
mxGraph.prototype.allowDanglingEdges = true;

/**
 * Variable: cloneInvalidEdges
 * 
 * Specifies if edges that are cloned should be validated and only inserted
 * if they are valid. Default is true.
 */
mxGraph.prototype.cloneInvalidEdges = false;

/**
 * Variable: disconnectOnMove
 * 
 * Specifies if edges should be disconnected from their terminals when they
 * are moved. Default is true.
 */
mxGraph.prototype.disconnectOnMove = true;

/**
 * Variable: labelsVisible
 * 
 * Specifies if labels should be visible. This is used in <getLabel>. Default
 * is true.
 */
mxGraph.prototype.labelsVisible = true;
	
/**
 * Variable: htmlLabels
 * 
 * Specifies the return value for <isHtmlLabel>. Default is false.
 */
mxGraph.prototype.htmlLabels = false;

/**
 * Variable: swimlaneSelectionEnabled
 * 
 * Specifies if swimlanes should be selectable via the content if the
 * mouse is released. Default is true.
 */
mxGraph.prototype.swimlaneSelectionEnabled = true;

/**
 * Variable: swimlaneNesting
 * 
 * Specifies if nesting of swimlanes is allowed. Default is true.
 */
mxGraph.prototype.swimlaneNesting = true;
	
/**
 * Variable: swimlaneIndicatorColorAttribute
 * 
 * The attribute used to find the color for the indicator if the indicator
 * color is set to 'swimlane'. Default is <mxConstants.STYLE_FILLCOLOR>.
 */
mxGraph.prototype.swimlaneIndicatorColorAttribute = mxConstants.STYLE_FILLCOLOR;

/**
 * Variable: imageBundles
 * 
 * Holds the list of image bundles.
 */
mxGraph.prototype.imageBundles = null;

/**
 * Variable: minFitScale
 * 
 * Specifies the minimum scale to be applied in <fit>. Default is 0.1. Set this
 * to null to allow any value.
 */
mxGraph.prototype.minFitScale = 0.1;

/**
 * Variable: maxFitScale
 * 
 * Specifies the maximum scale to be applied in <fit>. Default is 8. Set this
 * to null to allow any value.
 */
mxGraph.prototype.maxFitScale = 8;

/**
 * Variable: panDx
 * 
 * Current horizontal panning value. Default is 0.
 */
mxGraph.prototype.panDx = 0;

/**
 * Variable: panDy
 * 
 * Current vertical panning value. Default is 0.
 */
mxGraph.prototype.panDy = 0;

/**
 * Variable: collapsedImage
 * 
 * Specifies the <mxImage> to indicate a collapsed state.
 * Default value is mxClient.imageBasePath + '/collapsed.gif'
 */
mxGraph.prototype.collapsedImage = new mxImage(mxClient.imageBasePath + '/collapsed.gif', 9, 9);

/**
 * Variable: expandedImage
 * 
 * Specifies the <mxImage> to indicate a expanded state.
 * Default value is mxClient.imageBasePath + '/expanded.gif'
 */
mxGraph.prototype.expandedImage = new mxImage(mxClient.imageBasePath + '/expanded.gif', 9, 9);

/**
 * Variable: warningImage
 * 
 * Specifies the <mxImage> for the image to be used to display a warning
 * overlay. See <setCellWarning>. Default value is mxClient.imageBasePath +
 * '/warning'.  The extension for the image depends on the platform. It is
 * '.png' on the Mac and '.gif' on all other platforms.
 */
mxGraph.prototype.warningImage = new mxImage(mxClient.imageBasePath + '/warning'+
	((mxClient.IS_MAC) ? '.png' : '.gif'), 16, 16);

/**
 * Variable: alreadyConnectedResource
 * 
 * Specifies the resource key for the error message to be displayed in
 * non-multigraphs when two vertices are already connected. If the resource
 * for this key does not exist then the value is used as the error message.
 * Default is 'alreadyConnected'.
 */
mxGraph.prototype.alreadyConnectedResource = (mxClient.language != 'none') ? 'alreadyConnected' : '';

/**
 * Variable: containsValidationErrorsResource
 * 
 * Specifies the resource key for the warning message to be displayed when
 * a collapsed cell contains validation errors. If the resource for this
 * key does not exist then the value is used as the warning message.
 * Default is 'containsValidationErrors'.
 */
mxGraph.prototype.containsValidationErrorsResource = (mxClient.language != 'none') ? 'containsValidationErrors' : '';

/**
 * Variable: collapseExpandResource
 * 
 * Specifies the resource key for the tooltip on the collapse/expand icon.
 * If the resource for this key does not exist then the value is used as
 * the tooltip. Default is 'collapse-expand'.
 */
mxGraph.prototype.collapseExpandResource = (mxClient.language != 'none') ? 'collapse-expand' : '';

/**
 * Function: init
 * 
 * Initializes the <container> and creates the respective datastructures.
 * 
 * Parameters:
 * 
 * container - DOM node that will contain the graph display.
 */
mxGraph.prototype.init = function(container)
{
	this.container = container;
	
	// Initializes the in-place editor
	this.cellEditor = this.createCellEditor();	

	// Initializes the container using the view
	this.view.init();
	
	// Updates the size of the container for the current graph
	this.sizeDidChange();
	
	// Hides tooltips and resets tooltip timer if mouse leaves container
	mxEvent.addListener(container, 'mouseleave', mxUtils.bind(this, function()
	{
		if (this.tooltipHandler != null)
		{
			this.tooltipHandler.hide();
		}
	}));

	// Automatic deallocation of memory
	if (mxClient.IS_IE)
	{
		mxEvent.addListener(window, 'unload', mxUtils.bind(this, function()
		{
			this.destroy();
		}));
		
		// Disable shift-click for text
		mxEvent.addListener(container, 'selectstart',
			mxUtils.bind(this, function(evt)
			{
				return this.isEditing() || (!this.isMouseDown && !mxEvent.isShiftDown(evt));
			})
		);
	}
	
	// Workaround for missing last shape and connect preview in IE8 standards
	// mode if no initial graph displayed or no label for shape defined
	if (document.documentMode == 8)
	{
		container.insertAdjacentHTML('beforeend', '<' + mxClient.VML_PREFIX + ':group' +
			' style="DISPLAY: none;"></' + mxClient.VML_PREFIX + ':group>');
	}
};

/**
 * Function: createHandlers
 * 
 * Creates the tooltip-, panning-, connection- and graph-handler (in this
 * order). This is called in the constructor before <init> is called.
 */
mxGraph.prototype.createHandlers = function()
{
	this.tooltipHandler = this.createTooltipHandler();
	this.tooltipHandler.setEnabled(false);
	this.selectionCellsHandler = this.createSelectionCellsHandler();
	this.connectionHandler = this.createConnectionHandler();
	this.connectionHandler.setEnabled(false);
	this.graphHandler = this.createGraphHandler();
	this.panningHandler = this.createPanningHandler();
	this.panningHandler.panningEnabled = false;
	this.popupMenuHandler = this.createPopupMenuHandler();
};

/**
 * Function: createTooltipHandler
 * 
 * Creates and returns a new <mxTooltipHandler> to be used in this graph.
 */
mxGraph.prototype.createTooltipHandler = function()
{
	return new mxTooltipHandler(this);
};

/**
 * Function: createSelectionCellsHandler
 * 
 * Creates and returns a new <mxTooltipHandler> to be used in this graph.
 */
mxGraph.prototype.createSelectionCellsHandler = function()
{
	return new mxSelectionCellsHandler(this);
};

/**
 * Function: createConnectionHandler
 * 
 * Creates and returns a new <mxConnectionHandler> to be used in this graph.
 */
mxGraph.prototype.createConnectionHandler = function()
{
	return new mxConnectionHandler(this);
};

/**
 * Function: createGraphHandler
 * 
 * Creates and returns a new <mxGraphHandler> to be used in this graph.
 */
mxGraph.prototype.createGraphHandler = function()
{
	return new mxGraphHandler(this);
};

/**
 * Function: createPanningHandler
 * 
 * Creates and returns a new <mxPanningHandler> to be used in this graph.
 */
mxGraph.prototype.createPanningHandler = function()
{
	return new mxPanningHandler(this);
};

/**
 * Function: createPopupMenuHandler
 * 
 * Creates and returns a new <mxPopupMenuHandler> to be used in this graph.
 */
mxGraph.prototype.createPopupMenuHandler = function()
{
	return new mxPopupMenuHandler(this);
};

/**
 * Function: createSelectionModel
 * 
 * Creates a new <mxGraphSelectionModel> to be used in this graph.
 */
mxGraph.prototype.createSelectionModel = function()
{
	return new mxGraphSelectionModel(this);
};

/**
 * Function: createStylesheet
 * 
 * Creates a new <mxGraphSelectionModel> to be used in this graph.
 */
mxGraph.prototype.createStylesheet = function()
{
	return new mxStylesheet();
};

/**
 * Function: createGraphView
 * 
 * Creates a new <mxGraphView> to be used in this graph.
 */
mxGraph.prototype.createGraphView = function()
{
	return new mxGraphView(this);
};
 
/**
 * Function: createCellRenderer
 * 
 * Creates a new <mxCellRenderer> to be used in this graph.
 */
mxGraph.prototype.createCellRenderer = function()
{
	return new mxCellRenderer();
};

/**
 * Function: createCellEditor
 * 
 * Creates a new <mxCellEditor> to be used in this graph.
 */
mxGraph.prototype.createCellEditor = function()
{
	return new mxCellEditor(this);
};

/**
 * Function: getModel
 * 
 * Returns the <mxGraphModel> that contains the cells.
 */
mxGraph.prototype.getModel = function()
{
	return this.model;
};

/**
 * Function: getView
 * 
 * Returns the <mxGraphView> that contains the <mxCellStates>.
 */
mxGraph.prototype.getView = function()
{
	return this.view;
};

/**
 * Function: getStylesheet
 * 
 * Returns the <mxStylesheet> that defines the style.
 */
mxGraph.prototype.getStylesheet = function()
{
	return this.stylesheet;
};

/**
 * Function: setStylesheet
 * 
 * Sets the <mxStylesheet> that defines the style.
 */
mxGraph.prototype.setStylesheet = function(stylesheet)
{
	this.stylesheet = stylesheet;
};

/**
 * Function: getSelectionModel
 * 
 * Returns the <mxGraphSelectionModel> that contains the selection.
 */
mxGraph.prototype.getSelectionModel = function()
{
	return this.selectionModel;
};

/**
 * Function: setSelectionModel
 * 
 * Sets the <mxSelectionModel> that contains the selection.
 */
mxGraph.prototype.setSelectionModel = function(selectionModel)
{
	this.selectionModel = selectionModel;
};

/**
 * Function: getSelectionCellsForChanges
 * 
 * Returns the cells to be selected for the given array of changes.
 */
mxGraph.prototype.getSelectionCellsForChanges = function(changes)
{
	var cells = [];
	
	for (var i = 0; i < changes.length; i++)
	{
		var change = changes[i];
		
		if (change.constructor != mxRootChange)
		{
			var cell = null;

			if (change instanceof mxChildChange && change.previous == null)
			{
				cell = change.child;
			}
			else if (change.cell != null && change.cell instanceof mxCell)
			{
				cell = change.cell;
			}
			
			if (cell != null && mxUtils.indexOf(cells, cell) < 0)
			{
				cells.push(cell);
			}
		}
	}
	
	return this.getModel().getTopmostCells(cells);
};

/**
 * Function: graphModelChanged
 * 
 * Called when the graph model changes. Invokes <processChange> on each
 * item of the given array to update the view accordingly.
 * 
 * Parameters:
 * 
 * changes - Array that contains the individual changes.
 */
mxGraph.prototype.graphModelChanged = function(changes)
{
	for (var i = 0; i < changes.length; i++)
	{
		this.processChange(changes[i]);
	}
	
	this.removeSelectionCells(this.getRemovedCellsForChanges(changes));
	
	this.view.validate();
	this.sizeDidChange();
};

/**
 * Function: getRemovedCellsForChanges
 * 
 * Returns the cells that have been removed from the model.
 */
mxGraph.prototype.getRemovedCellsForChanges = function(changes)
{
	var result = [];
	
	for (var i = 0; i < changes.length; i++)
	{
		var change = changes[i];
		
		// Resets the view settings, removes all cells and clears
		// the selection if the root changes.
		if (change instanceof mxRootChange)
		{
			break;
		}
		else if (change instanceof mxChildChange)
		{
			if (change.previous != null && change.parent == null)
			{
				result = result.concat(this.model.getDescendants(change.child));
			}
		}
		else if (change instanceof mxVisibleChange)
		{
			result = result.concat(this.model.getDescendants(change.cell));
		}
	}
	
	return result;
};

/**
 * Function: processChange
 * 
 * Processes the given change and invalidates the respective cached data
 * in <view>. This fires a <root> event if the root has changed in the
 * model.
 * 
 * Parameters:
 * 
 * change - Object that represents the change on the model.
 */
mxGraph.prototype.processChange = function(change)
{
	// Resets the view settings, removes all cells and clears
	// the selection if the root changes.
	if (change instanceof mxRootChange)
	{
		this.clearSelection();
		this.setDefaultParent(null);
		this.removeStateForCell(change.previous);
		
		if (this.resetViewOnRootChange)
		{
			this.view.scale = 1;
			this.view.translate.x = 0;
			this.view.translate.y = 0;
		}

		this.fireEvent(new mxEventObject(mxEvent.ROOT));
	}
	
	// Adds or removes a child to the view by online invaliding
	// the minimal required portions of the cache, namely, the
	// old and new parent and the child.
	else if (change instanceof mxChildChange)
	{
		var newParent = this.model.getParent(change.child);
		this.view.invalidate(change.child, true, true);

		if (newParent == null || this.isCellCollapsed(newParent))
		{
			this.view.invalidate(change.child, true, true);
			this.removeStateForCell(change.child);
			
			// Handles special case of current root of view being removed
			if (this.view.currentRoot == change.child)
			{
				this.home();
			}
		}
 
		if (newParent != change.previous)
		{
			// Refreshes the collapse/expand icons on the parents
			if (newParent != null)
			{
				this.view.invalidate(newParent, false, false);
			}
			
			if (change.previous != null)
			{
				this.view.invalidate(change.previous, false, false);
			}
		}
	}

	// Handles two special cases where the shape does not need to be
	// recreated from scratch, it only needs to be invalidated.
	else if (change instanceof mxTerminalChange || change instanceof mxGeometryChange)
	{
		// Checks if the geometry has changed to avoid unnessecary revalidation
		if (change instanceof mxTerminalChange || ((change.previous == null && change.geometry != null) ||
			(change.previous != null && !change.previous.equals(change.geometry))))
		{
			this.view.invalidate(change.cell);
		}
	}

	// Handles two special cases where only the shape, but no
	// descendants need to be recreated
	else if (change instanceof mxValueChange)
	{
		this.view.invalidate(change.cell, false, false);
	}
	
	// Requires a new mxShape in JavaScript
	else if (change instanceof mxStyleChange)
	{
		this.view.invalidate(change.cell, true, true);
		var state = this.view.getState(change.cell);
		
		if (state != null)
		{
			state.style = null;
		}
	}
	
	// Removes the state from the cache by default
	else if (change.cell != null && change.cell instanceof mxCell)
	{
		this.removeStateForCell(change.cell);
	}
};

/**
 * Function: removeStateForCell
 * 
 * Removes all cached information for the given cell and its descendants.
 * This is called when a cell was removed from the model.
 * 
 * Paramters:
 * 
 * cell - <mxCell> that was removed from the model.
 */
mxGraph.prototype.removeStateForCell = function(cell)
{
	var childCount = this.model.getChildCount(cell);
	
	for (var i = 0; i < childCount; i++)
	{
		this.removeStateForCell(this.model.getChildAt(cell, i));
	}

	this.view.invalidate(cell, false, true);
	this.view.removeState(cell);
};

/**
 * Group: Overlays
 */

/**
 * Function: addCellOverlay
 * 
 * Adds an <mxCellOverlay> for the specified cell. This method fires an
 * <addoverlay> event and returns the new <mxCellOverlay>.
 * 
 * Parameters:
 * 
 * cell - <mxCell> to add the overlay for.
 * overlay - <mxCellOverlay> to be added for the cell.
 */
mxGraph.prototype.addCellOverlay = function(cell, overlay)
{
	if (cell.overlays == null)
	{
		cell.overlays = [];
	}
	
	cell.overlays.push(overlay);

	var state = this.view.getState(cell);

	// Immediately updates the cell display if the state exists
	if (state != null)
	{
		this.cellRenderer.redraw(state);
	}
	
	this.fireEvent(new mxEventObject(mxEvent.ADD_OVERLAY,
			'cell', cell, 'overlay', overlay));
	
	return overlay;
};

/**
 * Function: getCellOverlays
 * 
 * Returns the array of <mxCellOverlays> for the given cell or null, if
 * no overlays are defined.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose overlays should be returned.
 */
mxGraph.prototype.getCellOverlays = function(cell)
{
	return cell.overlays;
};

/**
 * Function: removeCellOverlay
 * 
 * Removes and returns the given <mxCellOverlay> from the given cell. This
 * method fires a <removeoverlay> event. If no overlay is given, then all
 * overlays are removed using <removeOverlays>.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose overlay should be removed.
 * overlay - Optional <mxCellOverlay> to be removed.
 */
mxGraph.prototype.removeCellOverlay = function(cell, overlay)
{
	if (overlay == null)
	{
		this.removeCellOverlays(cell);
	}
	else
	{
		var index = mxUtils.indexOf(cell.overlays, overlay);
		
		if (index >= 0)
		{
			cell.overlays.splice(index, 1);
			
			if (cell.overlays.length == 0)
			{
				cell.overlays = null;
			}
			
			// Immediately updates the cell display if the state exists
			var state = this.view.getState(cell);
			
			if (state != null)
			{
				this.cellRenderer.redraw(state);
			}
			
			this.fireEvent(new mxEventObject(mxEvent.REMOVE_OVERLAY,
					'cell', cell, 'overlay', overlay));	
		}
		else
		{
			overlay = null;
		}
	}
	
	return overlay;
};

/**
 * Function: removeCellOverlays
 * 
 * Removes all <mxCellOverlays> from the given cell. This method
 * fires a <removeoverlay> event for each <mxCellOverlay> and returns
 * the array of <mxCellOverlays> that was removed from the cell.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose overlays should be removed
 */
mxGraph.prototype.removeCellOverlays = function(cell)
{
	var overlays = cell.overlays;
	
	if (overlays != null)
	{
		cell.overlays = null;
		
		// Immediately updates the cell display if the state exists
		var state = this.view.getState(cell);
		
		if (state != null)
		{
			this.cellRenderer.redraw(state);
		}
		
		for (var i = 0; i < overlays.length; i++)
		{
			this.fireEvent(new mxEventObject(mxEvent.REMOVE_OVERLAY,
					'cell', cell, 'overlay', overlays[i]));
		}
	}
	
	return overlays;
};

/**
 * Function: clearCellOverlays
 * 
 * Removes all <mxCellOverlays> in the graph for the given cell and all its
 * descendants. If no cell is specified then all overlays are removed from
 * the graph. This implementation uses <removeCellOverlays> to remove the
 * overlays from the individual cells.
 * 
 * Parameters:
 * 
 * cell - Optional <mxCell> that represents the root of the subtree to
 * remove the overlays from. Default is the root in the model.
 */
mxGraph.prototype.clearCellOverlays = function(cell)
{
	cell = (cell != null) ? cell : this.model.getRoot();
	this.removeCellOverlays(cell);
	
	// Recursively removes all overlays from the children
	var childCount = this.model.getChildCount(cell);
	
	for (var i = 0; i < childCount; i++)
	{
		var child = this.model.getChildAt(cell, i);
		this.clearCellOverlays(child); // recurse
	}
};

/**
 * Function: setCellWarning
 * 
 * Creates an overlay for the given cell using the warning and image or
 * <warningImage> and returns the new <mxCellOverlay>. The warning is
 * displayed as a tooltip in a red font and may contain HTML markup. If
 * the warning is null or a zero length string, then all overlays are
 * removed from the cell.
 * 
 * Example:
 * 
 * (code)
 * graph.setCellWarning(cell, '<b>Warning:</b>: Hello, World!');
 * (end)
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose warning should be set.
 * warning - String that represents the warning to be displayed.
 * img - Optional <mxImage> to be used for the overlay. Default is
 * <warningImage>.
 * isSelect - Optional boolean indicating if a click on the overlay
 * should select the corresponding cell. Default is false.
 */
mxGraph.prototype.setCellWarning = function(cell, warning, img, isSelect)
{
	if (warning != null && warning.length > 0)
	{
		img = (img != null) ? img : this.warningImage;
		
		// Creates the overlay with the image and warning
		var overlay = new mxCellOverlay(img,
			'<font color=red>'+warning+'</font>');
		
		// Adds a handler for single mouseclicks to select the cell
		if (isSelect)
		{
			overlay.addListener(mxEvent.CLICK,
				mxUtils.bind(this, function(sender, evt)
				{
					if (this.isEnabled())
					{
						this.setSelectionCell(cell);
					}
				})
			);
		}
		
		// Sets and returns the overlay in the graph
		return this.addCellOverlay(cell, overlay);
	}
	else
	{
		this.removeCellOverlays(cell);
	}
	
	return null;
};

/**
 * Group: In-place editing
 */

/**
 * Function: startEditing
 * 
 * Calls <startEditingAtCell> using the given cell or the first selection
 * cell.
 * 
 * Parameters:
 * 
 * evt - Optional mouse event that triggered the editing.
 */
mxGraph.prototype.startEditing = function(evt)
{
	this.startEditingAtCell(null, evt);
};

/**
 * Function: startEditingAtCell
 * 
 * Fires a <startEditing> event and invokes <mxCellEditor.startEditing>
 * on <editor>. After editing was started, a <editingStarted> event is
 * fired.
 * 
 * Parameters:
 * 
 * cell - <mxCell> to start the in-place editor for.
 * evt - Optional mouse event that triggered the editing.
 */
mxGraph.prototype.startEditingAtCell = function(cell, evt)
{
	if (evt == null || !mxEvent.isMultiTouchEvent(evt))
	{
		if (cell == null)
		{
			cell = this.getSelectionCell();
			
			if (cell != null && !this.isCellEditable(cell))
			{
				cell = null;
			}
		}
	
		if (cell != null)
		{
			this.fireEvent(new mxEventObject(mxEvent.START_EDITING,
					'cell', cell, 'event', evt));
			this.cellEditor.startEditing(cell, evt);
			this.fireEvent(new mxEventObject(mxEvent.EDITING_STARTED,
					'cell', cell, 'event', evt));
		}
	}
};

/**
 * Function: getEditingValue
 * 
 * Returns the initial value for in-place editing. This implementation
 * returns <convertValueToString> for the given cell. If this function is
 * overridden, then <mxGraphModel.valueForCellChanged> should take care
 * of correctly storing the actual new value inside the user object.
 * 
 * Parameters:
 * 
 * cell - <mxCell> for which the initial editing value should be returned.
 * evt - Optional mouse event that triggered the editor.
 */
mxGraph.prototype.getEditingValue = function(cell, evt)
{
	return this.convertValueToString(cell);
};

/**
 * Function: stopEditing
 * 
 * Stops the current editing  and fires a <editingStopped> event.
 * 
 * Parameters:
 * 
 * cancel - Boolean that specifies if the current editing value
 * should be stored.
 */
mxGraph.prototype.stopEditing = function(cancel)
{
	this.cellEditor.stopEditing(cancel);
	this.fireEvent(new mxEventObject(mxEvent.EDITING_STOPPED, 'cancel', cancel));
};

/**
 * Function: labelChanged
 * 
 * Sets the label of the specified cell to the given value using
 * <cellLabelChanged> and fires <mxEvent.LABEL_CHANGED> while the
 * transaction is in progress. Returns the cell whose label was changed.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose label should be changed.
 * value - New label to be assigned.
 * evt - Optional event that triggered the change.
 */
mxGraph.prototype.labelChanged = function(cell, value, evt)
{
	this.model.beginUpdate();
	try
	{
		var old = cell.value;
		this.cellLabelChanged(cell, value, this.isAutoSizeCell(cell));
		this.fireEvent(new mxEventObject(mxEvent.LABEL_CHANGED,
			'cell', cell, 'value', value, 'old', old, 'event', evt));
	}
	finally
	{
		this.model.endUpdate();
	}
	
	return cell;
};

/**
 * Function: cellLabelChanged
 * 
 * Sets the new label for a cell. If autoSize is true then
 * <cellSizeUpdated> will be called.
 * 
 * In the following example, the function is extended to map changes to
 * attributes in an XML node, as shown in <convertValueToString>.
 * Alternatively, the handling of this can be implemented as shown in
 * <mxGraphModel.valueForCellChanged> without the need to clone the
 * user object.
 * 
 * (code)
 * var graphCellLabelChanged = graph.cellLabelChanged;
 * graph.cellLabelChanged = function(cell, newValue, autoSize)
 * {
 * 	// Cloned for correct undo/redo
 * 	var elt = cell.value.cloneNode(true);
 *  elt.setAttribute('label', newValue);
 *  
 *  newValue = elt;
 *  graphCellLabelChanged.apply(this, arguments);
 * };
 * (end) 
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose label should be changed.
 * value - New label to be assigned.
 * autoSize - Boolean that specifies if <cellSizeUpdated> should be called.
 */
mxGraph.prototype.cellLabelChanged = function(cell, value, autoSize)
{
	this.model.beginUpdate();
	try
	{
		this.model.setValue(cell, value);
		
		if (autoSize)
		{
			this.cellSizeUpdated(cell, false);
		}
	}
	finally
	{
		this.model.endUpdate();
	}
};

/**
 * Group: Event processing
 */

/**
 * Function: escape
 * 
 * Processes an escape keystroke.
 * 
 * Parameters:
 * 
 * evt - Mouseevent that represents the keystroke.
 */
mxGraph.prototype.escape = function(evt)
{
	this.fireEvent(new mxEventObject(mxEvent.ESCAPE, 'event', evt));
};

/**
 * Function: click
 * 
 * Processes a singleclick on an optional cell and fires a <click> event.
 * The click event is fired initially. If the graph is enabled and the
 * event has not been consumed, then the cell is selected using
 * <selectCellForEvent> or the selection is cleared using
 * <clearSelection>. The events consumed state is set to true if the
 * corresponding <mxMouseEvent> has been consumed.
 *
 * To handle a click event, use the following code.
 * 
 * (code)
 * graph.addListener(mxEvent.CLICK, function(sender, evt)
 * {
 *   var e = evt.getProperty('event'); // mouse event
 *   var cell = evt.getProperty('cell'); // cell may be null
 *   
 *   if (cell != null)
 *   {
 *     // Do something useful with cell and consume the event
 *     evt.consume();
 *   }
 * });
 * (end)
 * 
 * Parameters:
 * 
 * me - <mxMouseEvent> that represents the single click.
 */
mxGraph.prototype.click = function(me)
{
	var evt = me.getEvent();
	var cell = me.getCell();
	var mxe = new mxEventObject(mxEvent.CLICK, 'event', evt, 'cell', cell);
	
	if (me.isConsumed())
	{
		mxe.consume();
	}
	
	this.fireEvent(mxe);
	
	// Handles the event if it has not been consumed
	if (this.isEnabled() && !mxEvent.isConsumed(evt) && !mxe.isConsumed())
	{
		if (cell != null)
		{
			if (this.isTransparentClickEvent(evt))
			{
				var active = false;
				
				var tmp = this.getCellAt(me.graphX, me.graphY, null, null, null, mxUtils.bind(this, function(state)
				{
					var selected = this.isCellSelected(state.cell);
					active = active || selected;
					
					return !active || selected;
				}));
				
				if (tmp != null)
				{
					cell = tmp;
				}
			}
			
			this.selectCellForEvent(cell, evt);
		}
		else
		{
			var swimlane = null;
			
			if (this.isSwimlaneSelectionEnabled())
			{
				// Gets the swimlane at the location (includes
				// content area of swimlanes)
				swimlane = this.getSwimlaneAt(me.getGraphX(), me.getGraphY());
			}

			// Selects the swimlane and consumes the event
			if (swimlane != null)
			{
				this.selectCellForEvent(swimlane, evt);
			}
			
			// Ignores the event if the control key is pressed
			else if (!this.isToggleEvent(evt))
			{
				this.clearSelection();
			}
		}
	}
};

/**
 * Function: dblClick
 * 
 * Processes a doubleclick on an optional cell and fires a <dblclick>
 * event. The event is fired initially. If the graph is enabled and the
 * event has not been consumed, then <edit> is called with the given
 * cell. The event is ignored if no cell was specified.
 *
 * Example for overriding this method.
 *
 * (code)
 * graph.dblClick = function(evt, cell)
 * {
 *   var mxe = new mxEventObject(mxEvent.DOUBLE_CLICK, 'event', evt, 'cell', cell);
 *   this.fireEvent(mxe);
 *   
 *   if (this.isEnabled() && !mxEvent.isConsumed(evt) && !mxe.isConsumed())
 *   {
 * 	   mxUtils.alert('Hello, World!');
 *     mxe.consume();
 *   }
 * }
 * (end)
 * 
 * Example listener for this event.
 * 
 * (code)
 * graph.addListener(mxEvent.DOUBLE_CLICK, function(sender, evt)
 * {
 *   var cell = evt.getProperty('cell');
 *   // do something with the cell and consume the
 *   // event to prevent in-place editing from start
 * });
 * (end) 
 * 
 * Parameters:
 * 
 * evt - Mouseevent that represents the doubleclick.
 * cell - Optional <mxCell> under the mousepointer.
 */
mxGraph.prototype.dblClick = function(evt, cell)
{
	var mxe = new mxEventObject(mxEvent.DOUBLE_CLICK, 'event', evt, 'cell', cell);
	this.fireEvent(mxe);
	
	// Handles the event if it has not been consumed
	if (this.isEnabled() && !mxEvent.isConsumed(evt) && !mxe.isConsumed() &&
		cell != null && this.isCellEditable(cell) && !this.isEditing(cell))
	{
		this.startEditingAtCell(cell, evt);
		mxEvent.consume(evt);
	}
};

/**
 * Function: tapAndHold
 * 
 * Handles the <mxMouseEvent> by highlighting the <mxCellState>.
 * 
 * Parameters:
 * 
 * me - <mxMouseEvent> that represents the touch event.
 * state - Optional <mxCellState> that is associated with the event.
 */
mxGraph.prototype.tapAndHold = function(me)
{
	var evt = me.getEvent();
	var mxe = new mxEventObject(mxEvent.TAP_AND_HOLD, 'event', evt, 'cell', me.getCell());

	// LATER: Check if event should be consumed if me is consumed
	this.fireEvent(mxe);

	if (mxe.isConsumed())
	{
		// Resets the state of the panning handler
		this.panningHandler.panningTrigger = false;
	}
	
	// Handles the event if it has not been consumed
	if (this.isEnabled() && !mxEvent.isConsumed(evt) && !mxe.isConsumed() && this.connectionHandler.isEnabled())
	{
		var state = this.view.getState(this.connectionHandler.marker.getCell(me));

		if (state != null)
		{
			this.connectionHandler.marker.currentColor = this.connectionHandler.marker.validColor;
			this.connectionHandler.marker.markedState = state;
			this.connectionHandler.marker.mark();
			
			this.connectionHandler.first = new mxPoint(me.getGraphX(), me.getGraphY());
			this.connectionHandler.edgeState = this.connectionHandler.createEdgeState(me);
			this.connectionHandler.previous = state;
			this.connectionHandler.fireEvent(new mxEventObject(mxEvent.START, 'state', this.connectionHandler.previous));
		}
	}
};

/**
 * Function: scrollPointToVisible
 * 
 * Scrolls the graph to the given point, extending the graph container if
 * specified.
 */
mxGraph.prototype.scrollPointToVisible = function(x, y, extend, border)
{
	if (!this.timerAutoScroll && (this.ignoreScrollbars || mxUtils.hasScrollbars(this.container)))
	{
		var c = this.container;
		border = (border != null) ? border : 20;
		
		if (x >= c.scrollLeft && y >= c.scrollTop && x <= c.scrollLeft + c.clientWidth &&
			y <= c.scrollTop + c.clientHeight)
		{
			var dx = c.scrollLeft + c.clientWidth - x;
			
			if (dx < border)
			{
				var old = c.scrollLeft;
				c.scrollLeft += border - dx;

				// Automatically extends the canvas size to the bottom, right
				// if the event is outside of the canvas and the edge of the
				// canvas has been reached. Notes: Needs fix for IE.
				if (extend && old == c.scrollLeft)
				{
					if (this.dialect == mxConstants.DIALECT_SVG)
					{
						var root = this.view.getDrawPane().ownerSVGElement;
						var width = this.container.scrollWidth + border - dx;
						
						// Updates the clipping region. This is an expensive
						// operation that should not be executed too often.
						root.style.width = width + 'px';
					}
					else
					{
						var width = Math.max(c.clientWidth, c.scrollWidth) + border - dx;
						var canvas = this.view.getCanvas();
						canvas.style.width = width + 'px';
					}
					
					c.scrollLeft += border - dx;
				}
			}
			else
			{
				dx = x - c.scrollLeft;
				
				if (dx < border)
				{
					c.scrollLeft -= border - dx;
				}
			}
			
			var dy = c.scrollTop + c.clientHeight - y;
			
			if (dy < border)
			{
				var old = c.scrollTop;
				c.scrollTop += border - dy;

				if (old == c.scrollTop && extend)
				{
					if (this.dialect == mxConstants.DIALECT_SVG)
					{
						var root = this.view.getDrawPane().ownerSVGElement;
						var height = this.container.scrollHeight + border - dy;
						
						// Updates the clipping region. This is an expensive
						// operation that should not be executed too often.
						root.style.height = height + 'px';
					}
					else
					{
						var height = Math.max(c.clientHeight, c.scrollHeight) + border - dy;
						var canvas = this.view.getCanvas();
						canvas.style.height = height + 'px';
					}
					
					c.scrollTop += border - dy;
				}
			}
			else
			{
				dy = y - c.scrollTop;
				
				if (dy < border)
				{
					c.scrollTop -= border - dy;
				}
			}
		}
	}
	else if (this.allowAutoPanning && !this.panningHandler.isActive())
	{
		if (this.panningManager == null)
		{
			this.panningManager = this.createPanningManager();
		}

		this.panningManager.panTo(x + this.panDx, y + this.panDy);
	}
};


/**
 * Function: createPanningManager
 * 
 * Creates and returns an <mxPanningManager>.
 */
mxGraph.prototype.createPanningManager = function()
{
	return new mxPanningManager(this);
};

/**
 * Function: getBorderSizes
 * 
 * Returns the size of the border and padding on all four sides of the
 * container. The left, top, right and bottom borders are stored in the x, y,
 * width and height of the returned <mxRectangle>, respectively.
 */
mxGraph.prototype.getBorderSizes = function()
{
	var css = mxUtils.getCurrentStyle(this.container);
	
	return new mxRectangle(mxUtils.parseCssNumber(css.paddingLeft) +
			((css.borderLeftStyle != 'none') ? mxUtils.parseCssNumber(css.borderLeftWidth) : 0),
		mxUtils.parseCssNumber(css.paddingTop) +
			((css.borderTopStyle != 'none') ? mxUtils.parseCssNumber(css.borderTopWidth) : 0),
		mxUtils.parseCssNumber(css.paddingRight) +
			((css.borderRightStyle != 'none') ? mxUtils.parseCssNumber(css.borderRightWidth) : 0),
		mxUtils.parseCssNumber(css.paddingBottom) +
			((css.borderBottomStyle != 'none') ? mxUtils.parseCssNumber(css.borderBottomWidth) : 0));
};

/**
 * Function: getPreferredPageSize
 * 
 * Returns the preferred size of the background page if <preferPageSize> is true.
 */
mxGraph.prototype.getPreferredPageSize = function(bounds, width, height)
{
	var scale = this.view.scale;
	var tr = this.view.translate;
	var fmt = this.pageFormat;
	var ps = this.pageScale;
	var page = new mxRectangle(0, 0, Math.ceil(fmt.width * ps), Math.ceil(fmt.height * ps));
	
	var hCount = (this.pageBreaksVisible) ? Math.ceil(width / page.width) : 1;
	var vCount = (this.pageBreaksVisible) ? Math.ceil(height / page.height) : 1;
	
	return new mxRectangle(0, 0, hCount * page.width + 2 + tr.x, vCount * page.height + 2 + tr.y);
};

/**
 * Function: fit
 *
 * Scales the graph such that the complete diagram fits into <container> and
 * returns the current scale in the view. To fit an initial graph prior to
 * rendering, set <mxGraphView.rendering> to false prior to changing the model
 * and execute the following after changing the model.
 * 
 * (code)
 * graph.fit();
 * graph.view.rendering = true;
 * graph.refresh();
 * (end)
 * 
 * To fit and center the graph, the following code can be used.
 * 
 * (code)
 * var margin = 2;
 * var max = 3;
 * 
 * var bounds = graph.getGraphBounds();
 * var cw = graph.container.clientWidth - margin;
 * var ch = graph.container.clientHeight - margin;
 * var w = bounds.width / graph.view.scale;
 * var h = bounds.height / graph.view.scale;
 * var s = Math.min(max, Math.min(cw / w, ch / h));
 * 
 * graph.view.scaleAndTranslate(s,
 *   (margin + cw - w * s) / (2 * s) - bounds.x / graph.view.scale,
 *   (margin + ch - h * s) / (2 * s) - bounds.y / graph.view.scale);
 * (end)
 * 
 * Parameters:
 * 
 * border - Optional number that specifies the border. Default is <border>.
 * keepOrigin - Optional boolean that specifies if the translate should be
 * changed. Default is false.
 * margin - Optional margin in pixels. Default is 0.
 * enabled - Optional boolean that specifies if the scale should be set or
 * just returned. Default is true.
 * ignoreWidth - Optional boolean that specifies if the width should be
 * ignored. Default is false.
 * ignoreHeight - Optional boolean that specifies if the height should be
 * ignored. Default is false.
 */
mxGraph.prototype.fit = function(border, keepOrigin, margin, enabled, ignoreWidth, ignoreHeight)
{
	if (this.container != null)
	{
		border = (border != null) ? border : this.getBorder();
		keepOrigin = (keepOrigin != null) ? keepOrigin : false;
		margin = (margin != null) ? margin : 0;
		enabled = (enabled != null) ? enabled : true;
		ignoreWidth = (ignoreWidth != null) ? ignoreWidth : false;
		ignoreHeight = (ignoreHeight != null) ? ignoreHeight : false;
		
		// Adds spacing and border from css
		var cssBorder = this.getBorderSizes();
		var w1 = this.container.offsetWidth - cssBorder.x - cssBorder.width - 1;
		var h1 = this.container.offsetHeight - cssBorder.y - cssBorder.height - 1;
		var bounds = this.view.getGraphBounds();
		
		if (bounds.width > 0 && bounds.height > 0)
		{
			if (keepOrigin && bounds.x != null && bounds.y != null)
			{
				bounds = bounds.clone();
				bounds.width += bounds.x;
				bounds.height += bounds.y;
				bounds.x = 0;
				bounds.y = 0;
			}
			
			// LATER: Use unscaled bounding boxes to fix rounding errors
			var s = this.view.scale;
			var w2 = bounds.width / s;
			var h2 = bounds.height / s;
			
			// Fits to the size of the background image if required
			if (this.backgroundImage != null)
			{
				w2 = Math.max(w2, this.backgroundImage.width - bounds.x / s);
				h2 = Math.max(h2, this.backgroundImage.height - bounds.y / s);
			}
			
			var b = ((keepOrigin) ? border : 2 * border) + margin;

			w1 -= b;
			h1 -= b;
			
			var s2 = (((ignoreWidth) ? h1 / h2 : (ignoreHeight) ? w1 / w2 :
				Math.min(w1 / w2, h1 / h2)));
			
			if (this.minFitScale != null)
			{
				s2 = Math.max(s2, this.minFitScale);
			}
			
			if (this.maxFitScale != null)
			{
				s2 = Math.min(s2, this.maxFitScale);
			}
	
			if (enabled)
			{
				if (!keepOrigin)
				{
					if (!mxUtils.hasScrollbars(this.container))
					{
						var x0 = (bounds.x != null) ? Math.floor(this.view.translate.x - bounds.x / s + border / s2 + margin / 2) : border;
						var y0 = (bounds.y != null) ? Math.floor(this.view.translate.y - bounds.y / s + border / s2 + margin / 2) : border;

						this.view.scaleAndTranslate(s2, x0, y0);
					}
					else
					{
						this.view.setScale(s2);
						var b2 = this.getGraphBounds();
						
						if (b2.x != null)
						{
							this.container.scrollLeft = b2.x;
						}
						
						if (b2.y != null)
						{
							this.container.scrollTop = b2.y;
						}
					}
				}
				else if (this.view.scale != s2)
				{
					this.view.setScale(s2);
				}
			}
			else
			{
				return s2;
			}
		}
	}

	return this.view.scale;
};

/**
 * Function: sizeDidChange
 * 
 * Called when the size of the graph has changed. This implementation fires
 * a <size> event after updating the clipping region of the SVG element in
 * SVG-bases browsers.
 */
mxGraph.prototype.sizeDidChange = function()
{
	var bounds = this.getGraphBounds();
	
	if (this.container != null)
	{
		var border = this.getBorder();
		
		var width = Math.max(0, bounds.x + bounds.width + border);
		var height = Math.max(0, bounds.y + bounds.height + border);
		
		if (this.minimumContainerSize != null)
		{
			width = Math.max(width, this.minimumContainerSize.width);
			height = Math.max(height, this.minimumContainerSize.height);
		}

		if (this.resizeContainer)
		{
			this.doResizeContainer(width, height);
		}

		if (this.preferPageSize || (!mxClient.IS_IE && this.pageVisible))
		{
			var size = this.getPreferredPageSize(bounds, Math.max(1, width), Math.max(1, height));
			
			if (size != null)
			{
				width = size.width * this.view.scale;
				height = size.height * this.view.scale;
			}
		}
		
		if (this.minimumGraphSize != null)
		{
			width = Math.max(width, this.minimumGraphSize.width * this.view.scale);
			height = Math.max(height, this.minimumGraphSize.height * this.view.scale);
		}

		width = Math.ceil(width);
		height = Math.ceil(height);

		if (this.dialect == mxConstants.DIALECT_SVG)
		{
			var root = this.view.getDrawPane().ownerSVGElement;
			
			root.style.minWidth = Math.max(1, width) + 'px';
			root.style.minHeight = Math.max(1, height) + 'px';
			root.style.width = '100%';
			root.style.height = '100%';
		}
		else
		{
			if (mxClient.IS_QUIRKS)
			{
				// Quirks mode does not support minWidth/-Height
				this.view.updateHtmlCanvasSize(Math.max(1, width), Math.max(1, height));
			}
			else
			{
				this.view.canvas.style.minWidth = Math.max(1, width) + 'px';
				this.view.canvas.style.minHeight = Math.max(1, height) + 'px';
			}
		}
		
		this.updatePageBreaks(this.pageBreaksVisible, width, height);
	}

	this.fireEvent(new mxEventObject(mxEvent.SIZE, 'bounds', bounds));
};

/**
 * Function: doResizeContainer
 * 
 * Resizes the container for the given graph width and height.
 */
mxGraph.prototype.doResizeContainer = function(width, height)
{
	if (this.maximumContainerSize != null)
	{
		width = Math.min(this.maximumContainerSize.width, width);
		height = Math.min(this.maximumContainerSize.height, height);
	}

	this.container.style.width = Math.ceil(width) + 'px';
	this.container.style.height = Math.ceil(height) + 'px';
};

/**
 * Function: updatePageBreaks
 * 
 * Invokes from <sizeDidChange> to redraw the page breaks.
 * 
 * Parameters:
 * 
 * visible - Boolean that specifies if page breaks should be shown.
 * width - Specifies the width of the container in pixels.
 * height - Specifies the height of the container in pixels.
 */
mxGraph.prototype.updatePageBreaks = function(visible, width, height)
{
	var scale = this.view.scale;
	var tr = this.view.translate;
	var fmt = this.pageFormat;
	var ps = scale * this.pageScale;
	var bounds = new mxRectangle(0, 0, fmt.width * ps, fmt.height * ps);

	var gb = mxRectangle.fromRectangle(this.getGraphBounds());
	gb.width = Math.max(1, gb.width);
	gb.height = Math.max(1, gb.height);
	
	bounds.x = Math.floor((gb.x - tr.x * scale) / bounds.width) * bounds.width + tr.x * scale;
	bounds.y = Math.floor((gb.y - tr.y * scale) / bounds.height) * bounds.height + tr.y * scale;
	
	gb.width = Math.ceil((gb.width + (gb.x - bounds.x)) / bounds.width) * bounds.width;
	gb.height = Math.ceil((gb.height + (gb.y - bounds.y)) / bounds.height) * bounds.height;
	
	// Does not show page breaks if the scale is too small
	visible = visible && Math.min(bounds.width, bounds.height) > this.minPageBreakDist;

	var horizontalCount = (visible) ? Math.ceil(gb.height / bounds.height) + 1 : 0;
	var verticalCount = (visible) ? Math.ceil(gb.width / bounds.width) + 1 : 0;
	var right = (verticalCount - 1) * bounds.width;
	var bottom = (horizontalCount - 1) * bounds.height;
	
	if (this.horizontalPageBreaks == null && horizontalCount > 0)
	{
		this.horizontalPageBreaks = [];
	}

	if (this.verticalPageBreaks == null && verticalCount > 0)
	{
		this.verticalPageBreaks = [];
	}
	
	var drawPageBreaks = mxUtils.bind(this, function(breaks)
	{
		if (breaks != null)
		{
			var count = (breaks == this.horizontalPageBreaks) ? horizontalCount : verticalCount; 
			
			for (var i = 0; i <= count; i++)
			{
				var pts = (breaks == this.horizontalPageBreaks) ?
					[new mxPoint(Math.round(bounds.x), Math.round(bounds.y + i * bounds.height)),
			         new mxPoint(Math.round(bounds.x + right), Math.round(bounds.y + i * bounds.height))] :
			        [new mxPoint(Math.round(bounds.x + i * bounds.width), Math.round(bounds.y)),
			         new mxPoint(Math.round(bounds.x + i * bounds.width), Math.round(bounds.y + bottom))];

				if (breaks[i] != null)
				{
					breaks[i].points = pts;
					breaks[i].redraw();
				}
				else
				{
					var pageBreak = new mxPolyline(pts, this.pageBreakColor);
					pageBreak.dialect = this.dialect;
					pageBreak.pointerEvents = false;
					pageBreak.isDashed = this.pageBreakDashed;
					pageBreak.init(this.view.backgroundPane);
					pageBreak.redraw();
					
					breaks[i] = pageBreak;
				}
			}
			
			for (var i = count; i < breaks.length; i++)
			{
				breaks[i].destroy();
			}
			
			breaks.splice(count, breaks.length - count);
		}
	});
	
	drawPageBreaks(this.horizontalPageBreaks);
	drawPageBreaks(this.verticalPageBreaks);
};

/**
 * Group: Cell styles
 */

/**
 * Function: getCellStyle
 * 
 * Returns an array of key, value pairs representing the cell style for the
 * given cell. If no string is defined in the model that specifies the
 * style, then the default style for the cell is returned or <EMPTY_ARRAY>,
 * if not style can be found. Note: You should try and get the cell state
 * for the given cell and use the cached style in the state before using
 * this method.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose style should be returned as an array.
 */
mxGraph.prototype.getCellStyle = function(cell)
{
	var stylename = this.model.getStyle(cell);
	var style = null;
	
	// Gets the default style for the cell
	if (this.model.isEdge(cell))
	{
		style = this.stylesheet.getDefaultEdgeStyle();
	}
	else
	{
		style = this.stylesheet.getDefaultVertexStyle();
	}
	
	// Resolves the stylename using the above as the default
	if (stylename != null)
	{
		style = this.postProcessCellStyle(this.stylesheet.getCellStyle(stylename, style));
	}
	
	// Returns a non-null value if no style can be found
	if (style == null)
	{
		style = mxGraph.prototype.EMPTY_ARRAY;
	}
	
	return style;
};

/**
 * Function: postProcessCellStyle
 * 
 * Tries to resolve the value for the image style in the image bundles and
 * turns short data URIs as defined in mxImageBundle to data URIs as
 * defined in RFC 2397 of the IETF.
 */
mxGraph.prototype.postProcessCellStyle = function(style)
{
	if (style != null)
	{
		var key = style[mxConstants.STYLE_IMAGE];
		var image = this.getImageFromBundles(key);

		if (image != null)
		{
			style[mxConstants.STYLE_IMAGE] = image;
		}
		else
		{
			image = key;
		}
		
		// Converts short data uris to normal data uris
		if (image != null && image.substring(0, 11) == 'data:image/')
		{
			if (image.substring(0, 20) == 'data:image/svg+xml,<')
			{
				// Required for FF and IE11
				image = image.substring(0, 19) + encodeURIComponent(image.substring(19));
			}
			else if (image.substring(0, 22) != 'data:image/svg+xml,%3C')
			{
				var comma = image.indexOf(',');
				
				// Adds base64 encoding prefix if needed
				if (comma > 0 && image.substring(comma - 7, comma + 1) != ';base64,')
				{
					image = image.substring(0, comma) + ';base64,'
						+ image.substring(comma + 1);
				}
			}
			
			style[mxConstants.STYLE_IMAGE] = image;
		}
	}

	return style;
};

/**
 * Function: setCellStyle
 * 
 * Sets the style of the specified cells. If no cells are given, then the
 * selection cells are changed.
 * 
 * Parameters:
 * 
 * style - String representing the new style of the cells.
 * cells - Optional array of <mxCells> to set the style for. Default is the
 * selection cells.
 */
mxGraph.prototype.setCellStyle = function(style, cells)
{
	cells = cells || this.getSelectionCells();
	
	if (cells != null)
	{
		this.model.beginUpdate();
		try
		{
			for (var i = 0; i < cells.length; i++)
			{
				this.model.setStyle(cells[i], style);
			}
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Function: toggleCellStyle
 * 
 * Toggles the boolean value for the given key in the style of the given cell
 * and returns the new value as 0 or 1. If no cell is specified then the
 * selection cell is used.
 * 
 * Parameter:
 * 
 * key - String representing the key for the boolean value to be toggled.
 * defaultValue - Optional boolean default value if no value is defined.
 * Default is false.
 * cell - Optional <mxCell> whose style should be modified. Default is
 * the selection cell.
 */
mxGraph.prototype.toggleCellStyle = function(key, defaultValue, cell)
{
	cell = cell || this.getSelectionCell();
	
	return this.toggleCellStyles(key, defaultValue, [cell]);
};

/**
 * Function: toggleCellStyles
 * 
 * Toggles the boolean value for the given key in the style of the given cells
 * and returns the new value as 0 or 1. If no cells are specified, then the
 * selection cells are used. For example, this can be used to toggle
 * <mxConstants.STYLE_ROUNDED> or any other style with a boolean value.
 * 
 * Parameter:
 * 
 * key - String representing the key for the boolean value to be toggled.
 * defaultValue - Optional boolean default value if no value is defined.
 * Default is false.
 * cells - Optional array of <mxCells> whose styles should be modified.
 * Default is the selection cells.
 */
mxGraph.prototype.toggleCellStyles = function(key, defaultValue, cells)
{
	defaultValue = (defaultValue != null) ? defaultValue : false;
	cells = cells || this.getSelectionCells();
	var value = null;
	
	if (cells != null && cells.length > 0)
	{
		var state = this.view.getState(cells[0]);
		var style = (state != null) ? state.style : this.getCellStyle(cells[0]);
		
		if (style != null)
		{
			value = (mxUtils.getValue(style, key, defaultValue)) ? 0 : 1;
			this.setCellStyles(key, value, cells);
		}
	}
	
	return value;
};

/**
 * Function: setCellStyles
 * 
 * Sets the key to value in the styles of the given cells. This will modify
 * the existing cell styles in-place and override any existing assignment
 * for the given key. If no cells are specified, then the selection cells
 * are changed. If no value is specified, then the respective key is
 * removed from the styles.
 * 
 * Parameters:
 * 
 * key - String representing the key to be assigned.
 * value - String representing the new value for the key.
 * cells - Optional array of <mxCells> to change the style for. Default is
 * the selection cells.
 */
mxGraph.prototype.setCellStyles = function(key, value, cells)
{
	cells = cells || this.getSelectionCells();
	mxUtils.setCellStyles(this.model, cells, key, value);
};

/**
 * Function: toggleCellStyleFlags
 * 
 * Toggles the given bit for the given key in the styles of the specified
 * cells.
 * 
 * Parameters:
 * 
 * key - String representing the key to toggle the flag in.
 * flag - Integer that represents the bit to be toggled.
 * cells - Optional array of <mxCells> to change the style for. Default is
 * the selection cells.
 */
mxGraph.prototype.toggleCellStyleFlags = function(key, flag, cells)
{
	this.setCellStyleFlags(key, flag, null, cells);
};

/**
 * Function: setCellStyleFlags
 * 
 * Sets or toggles the given bit for the given key in the styles of the
 * specified cells.
 * 
 * Parameters:
 * 
 * key - String representing the key to toggle the flag in.
 * flag - Integer that represents the bit to be toggled.
 * value - Boolean value to be used or null if the value should be toggled.
 * cells - Optional array of <mxCells> to change the style for. Default is
 * the selection cells.
 */
mxGraph.prototype.setCellStyleFlags = function(key, flag, value, cells)
{
	cells = cells || this.getSelectionCells();
	
	if (cells != null && cells.length > 0)
	{
		if (value == null)
		{
			var state = this.view.getState(cells[0]);
			var style = (state != null) ? state.style : this.getCellStyle(cells[0]);
			
			if (style != null)
			{
				var current = parseInt(style[key] || 0);
				value = !((current & flag) == flag);
			}
		}

		mxUtils.setCellStyleFlags(this.model, cells, key, flag, value);
	}
};

/**
 * Group: Cell alignment and orientation
 */

/**
 * Function: alignCells
 * 
 * Aligns the given cells vertically or horizontally according to the given
 * alignment using the optional parameter as the coordinate.
 * 
 * Parameters:
 * 
 * align - Specifies the alignment. Possible values are all constants in
 * mxConstants with an ALIGN prefix.
 * cells - Array of <mxCells> to be aligned.
 * param - Optional coordinate for the alignment.
 */
mxGraph.prototype.alignCells = function(align, cells, param)
{
	if (cells == null)
	{
		cells = this.getSelectionCells();
	}
	
	if (cells != null && cells.length > 1)
	{
		// Finds the required coordinate for the alignment
		if (param == null)
		{
			for (var i = 0; i < cells.length; i++)
			{
				var state = this.view.getState(cells[i]);
				
				if (state != null && !this.model.isEdge(cells[i]))
				{
					if (param == null)
					{
						if (align == mxConstants.ALIGN_CENTER)
						{
							param = state.x + state.width / 2;
							break;
						}
						else if (align == mxConstants.ALIGN_RIGHT)
						{
							param = state.x + state.width;
						}
						else if (align == mxConstants.ALIGN_TOP)
						{
							param = state.y;
						}
						else if (align == mxConstants.ALIGN_MIDDLE)
						{
							param = state.y + state.height / 2;
							break;
						}
						else if (align == mxConstants.ALIGN_BOTTOM)
						{
							param = state.y + state.height;
						}
						else
						{
							param = state.x;
						}
					}
					else
					{
						if (align == mxConstants.ALIGN_RIGHT)
						{
							param = Math.max(param, state.x + state.width);
						}
						else if (align == mxConstants.ALIGN_TOP)
						{
							param = Math.min(param, state.y);
						}
						else if (align == mxConstants.ALIGN_BOTTOM)
						{
							param = Math.max(param, state.y + state.height);
						}
						else
						{
							param = Math.min(param, state.x);
						}
					}
				}
			}
		}

		// Aligns the cells to the coordinate
		if (param != null)
		{
			var s = this.view.scale;

			this.model.beginUpdate();
			try
			{
				for (var i = 0; i < cells.length; i++)
				{
					var state = this.view.getState(cells[i]);
					
					if (state != null)
					{
						var geo = this.getCellGeometry(cells[i]);
						
						if (geo != null && !this.model.isEdge(cells[i]))
						{
							geo = geo.clone();
							
							if (align == mxConstants.ALIGN_CENTER)
							{
								geo.x += (param - state.x - state.width / 2) / s;
							}
							else if (align == mxConstants.ALIGN_RIGHT)
							{
								geo.x += (param - state.x - state.width) / s;
							}
							else if (align == mxConstants.ALIGN_TOP)
							{
								geo.y += (param - state.y) / s;
							}
							else if (align == mxConstants.ALIGN_MIDDLE)
							{
								geo.y += (param - state.y - state.height / 2) / s;
							}
							else if (align == mxConstants.ALIGN_BOTTOM)
							{
								geo.y += (param - state.y - state.height) / s;
							}
							else
							{
								geo.x += (param - state.x) / s;
							}
							
							this.resizeCell(cells[i], geo);
						}
					}
				}
				
				this.fireEvent(new mxEventObject(mxEvent.ALIGN_CELLS,
						'align', align, 'cells', cells));
			}
			finally
			{
				this.model.endUpdate();
			}
		}
	}
	
	return cells;
};

/**
 * Function: flipEdge
 * 
 * Toggles the style of the given edge between null (or empty) and
 * <alternateEdgeStyle>. This method fires <mxEvent.FLIP_EDGE> while the
 * transaction is in progress. Returns the edge that was flipped.
 * 
 * Here is an example that overrides this implementation to invert the
 * value of <mxConstants.STYLE_ELBOW> without removing any existing styles.
 * 
 * (code)
 * graph.flipEdge = function(edge)
 * {
 *   if (edge != null)
 *   {
 *     var state = this.view.getState(edge);
 *     var style = (state != null) ? state.style : this.getCellStyle(edge);
 *     
 *     if (style != null)
 *     {
 *       var elbow = mxUtils.getValue(style, mxConstants.STYLE_ELBOW,
 *           mxConstants.ELBOW_HORIZONTAL);
 *       var value = (elbow == mxConstants.ELBOW_HORIZONTAL) ?
 *           mxConstants.ELBOW_VERTICAL : mxConstants.ELBOW_HORIZONTAL;
 *       this.setCellStyles(mxConstants.STYLE_ELBOW, value, [edge]);
 *     }
 *   }
 * };
 * (end)
 * 
 * Parameters:
 * 
 * edge - <mxCell> whose style should be changed.
 */
mxGraph.prototype.flipEdge = function(edge)
{
	if (edge != null &&
		this.alternateEdgeStyle != null)
	{
		this.model.beginUpdate();
		try
		{
			var style = this.model.getStyle(edge);

			if (style == null || style.length == 0)
			{
				this.model.setStyle(edge, this.alternateEdgeStyle);
			}
			else
			{
				this.model.setStyle(edge, null);
			}

			// Removes all existing control points
			this.resetEdge(edge);
			this.fireEvent(new mxEventObject(mxEvent.FLIP_EDGE, 'edge', edge));
		}
		finally
		{
			this.model.endUpdate();
		}
	}

	return edge;
};

/**
 * Function: addImageBundle
 *
 * Adds the specified <mxImageBundle>.
 */
mxGraph.prototype.addImageBundle = function(bundle)
{
	this.imageBundles.push(bundle);
};

/**
 * Function: removeImageBundle
 * 
 * Removes the specified <mxImageBundle>.
 */
mxGraph.prototype.removeImageBundle = function(bundle)
{
	var tmp = [];
	
	for (var i = 0; i < this.imageBundles.length; i++)
	{
		if (this.imageBundles[i] != bundle)
		{
			tmp.push(this.imageBundles[i]);
		}
	}
	
	this.imageBundles = tmp;
};

/**
 * Function: getImageFromBundles
 *
 * Searches all <imageBundles> for the specified key and returns the value
 * for the first match or null if the key is not found.
 */
mxGraph.prototype.getImageFromBundles = function(key)
{
	if (key != null)
	{
		for (var i = 0; i < this.imageBundles.length; i++)
		{
			var image = this.imageBundles[i].getImage(key);
			
			if (image != null)
			{
				return image;
			}
		}
	}
	
	return null;
};

/**
 * Group: Order
 */

/**
 * Function: orderCells
 * 
 * Moves the given cells to the front or back. The change is carried out
 * using <cellsOrdered>. This method fires <mxEvent.ORDER_CELLS> while the
 * transaction is in progress.
 * 
 * Parameters:
 * 
 * back - Boolean that specifies if the cells should be moved to back.
 * cells - Array of <mxCells> to move to the background. If null is
 * specified then the selection cells are used.
 */
mxGraph.prototype.orderCells = function(back, cells)
{
	if (cells == null)
	{
		cells = mxUtils.sortCells(this.getSelectionCells(), true);
	}

	this.model.beginUpdate();
	try
	{
		this.cellsOrdered(cells, back);
		this.fireEvent(new mxEventObject(mxEvent.ORDER_CELLS,
				'back', back, 'cells', cells));
	}
	finally
	{
		this.model.endUpdate();
	}

	return cells;
};

/**
 * Function: cellsOrdered
 * 
 * Moves the given cells to the front or back. This method fires
 * <mxEvent.CELLS_ORDERED> while the transaction is in progress.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> whose order should be changed.
 * back - Boolean that specifies if the cells should be moved to back.
 */
mxGraph.prototype.cellsOrdered = function(cells, back)
{
	if (cells != null)
	{
		this.model.beginUpdate();
		try
		{
			for (var i = 0; i < cells.length; i++)
			{
				var parent = this.model.getParent(cells[i]);

				if (back)
				{
					this.model.add(parent, cells[i], i);
				}
				else
				{
					this.model.add(parent, cells[i],
							this.model.getChildCount(parent) - 1);
				}
			}
			
			this.fireEvent(new mxEventObject(mxEvent.CELLS_ORDERED,
					'back', back, 'cells', cells));
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Group: Grouping
 */

/**
 * Function: groupCells
 * 
 * Adds the cells into the given group. The change is carried out using
 * <cellsAdded>, <cellsMoved> and <cellsResized>. This method fires
 * <mxEvent.GROUP_CELLS> while the transaction is in progress. Returns the
 * new group. A group is only created if there is at least one entry in the
 * given array of cells.
 * 
 * Parameters:
 * 
 * group - <mxCell> that represents the target group. If null is specified
 * then a new group is created using <createGroupCell>.
 * border - Optional integer that specifies the border between the child
 * area and the group bounds. Default is 0.
 * cells - Optional array of <mxCells> to be grouped. If null is specified
 * then the selection cells are used.
 */
mxGraph.prototype.groupCells = function(group, border, cells)
{
	if (cells == null)
	{
		cells = mxUtils.sortCells(this.getSelectionCells(), true);
	}

	cells = this.getCellsForGroup(cells);

	if (group == null)
	{
		group = this.createGroupCell(cells);
	}

	var bounds = this.getBoundsForGroup(group, cells, border);

	if (cells.length > 0 && bounds != null)
	{
		// Uses parent of group or previous parent of first child
		var parent = this.model.getParent(group);
		
		if (parent == null)
		{
			parent = this.model.getParent(cells[0]);
		}

		this.model.beginUpdate();
		try
		{
			// Checks if the group has a geometry and
			// creates one if one does not exist
			if (this.getCellGeometry(group) == null)
			{
				this.model.setGeometry(group, new mxGeometry());
			}

			// Adds the group into the parent
			var index = this.model.getChildCount(parent);
			this.cellsAdded([group], parent, index, null, null, false, false, false);

			// Adds the children into the group and moves
			index = this.model.getChildCount(group);
			this.cellsAdded(cells, group, index, null, null, false, false, false);
			this.cellsMoved(cells, -bounds.x, -bounds.y, false, false, false);

			// Resizes the group
			this.cellsResized([group], [bounds], false);

			this.fireEvent(new mxEventObject(mxEvent.GROUP_CELLS,
					'group', group, 'border', border, 'cells', cells));
		}
		finally
		{
			this.model.endUpdate();
		}
	}

	return group;
};

/**
 * Function: getCellsForGroup
 * 
 * Returns the cells with the same parent as the first cell
 * in the given array.
 */
mxGraph.prototype.getCellsForGroup = function(cells)
{
	var result = [];

	if (cells != null && cells.length > 0)
	{
		var parent = this.model.getParent(cells[0]);
		result.push(cells[0]);

		// Filters selection cells with the same parent
		for (var i = 1; i < cells.length; i++)
		{
			if (this.model.getParent(cells[i]) == parent)
			{
				result.push(cells[i]);
			}
		}
	}

	return result;
};

/**
 * Function: getBoundsForGroup
 * 
 * Returns the bounds to be used for the given group and children.
 */
mxGraph.prototype.getBoundsForGroup = function(group, children, border)
{
	var result = this.getBoundingBoxFromGeometry(children, true);
	
	if (result != null)
	{
		if (this.isSwimlane(group))
		{
			var size = this.getStartSize(group);
			
			result.x -= size.width;
			result.y -= size.height;
			result.width += size.width;
			result.height += size.height;
		}
		
		// Adds the border
		if (border != null)
		{
			result.x -= border;
			result.y -= border;
			result.width += 2 * border;
			result.height += 2 * border;
		}
	}			
	
	return result;
};

/**
 * Function: createGroupCell
 * 
 * Hook for creating the group cell to hold the given array of <mxCells> if
 * no group cell was given to the <group> function.
 * 
 * The following code can be used to set the style of new group cells.
 * 
 * (code)
 * var graphCreateGroupCell = graph.createGroupCell;
 * graph.createGroupCell = function(cells)
 * {
 *   var group = graphCreateGroupCell.apply(this, arguments);
 *   group.setStyle('group');
 *   
 *   return group;
 * };
 */
mxGraph.prototype.createGroupCell = function(cells)
{
	var group = new mxCell('');
	group.setVertex(true);
	group.setConnectable(false);
	
	return group;
};

/**
 * Function: ungroupCells
 * 
 * Ungroups the given cells by moving the children the children to their
 * parents parent and removing the empty groups. Returns the children that
 * have been removed from the groups.
 * 
 * Parameters:
 * 
 * cells - Array of cells to be ungrouped. If null is specified then the
 * selection cells are used.
 */
mxGraph.prototype.ungroupCells = function(cells)
{
	var result = [];
	
	if (cells == null)
	{
		cells = this.getSelectionCells();

		// Finds the cells with children
		var tmp = [];
		
		for (var i = 0; i < cells.length; i++)
		{
			if (this.model.getChildCount(cells[i]) > 0)
			{
				tmp.push(cells[i]);
			}
		}

		cells = tmp;
	}
	
	if (cells != null && cells.length > 0)
	{
		this.model.beginUpdate();
		try
		{
			for (var i = 0; i < cells.length; i++)
			{
				var children = this.model.getChildren(cells[i]);
				
				if (children != null && children.length > 0)
				{
					children = children.slice();
					var parent = this.model.getParent(cells[i]);
					var index = this.model.getChildCount(parent);

					this.cellsAdded(children, parent, index, null, null, true);
					result = result.concat(children);
				}
			}

			this.removeCellsAfterUngroup(cells);
			this.fireEvent(new mxEventObject(mxEvent.UNGROUP_CELLS, 'cells', cells));
		}
		finally
		{
			this.model.endUpdate();
		}
	}
	
	return result;
};

/**
 * Function: removeCellsAfterUngroup
 * 
 * Hook to remove the groups after <ungroupCells>.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> that were ungrouped.
 */
mxGraph.prototype.removeCellsAfterUngroup = function(cells)
{
	this.cellsRemoved(this.addAllEdges(cells));
};

/**
 * Function: removeCellsFromParent
 * 
 * Removes the specified cells from their parents and adds them to the
 * default parent. Returns the cells that were removed from their parents.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to be removed from their parents.
 */
mxGraph.prototype.removeCellsFromParent = function(cells)
{
	if (cells == null)
	{
		cells = this.getSelectionCells();
	}
	
	this.model.beginUpdate();
	try
	{
		var parent = this.getDefaultParent();
		var index = this.model.getChildCount(parent);

		this.cellsAdded(cells, parent, index, null, null, true);
		this.fireEvent(new mxEventObject(mxEvent.REMOVE_CELLS_FROM_PARENT, 'cells', cells));
	}
	finally
	{
		this.model.endUpdate();
	}

	return cells;
};

/**
 * Function: updateGroupBounds
 * 
 * Updates the bounds of the given groups to include all children and returns
 * the passed-in cells. Call this with the groups in parent to child order,
 * top-most group first, the cells are processed in reverse order and cells
 * with no children are ignored.
 * 
 * Parameters:
 * 
 * cells - The groups whose bounds should be updated. If this is null, then
 * the selection cells are used.
 * border - Optional border to be added in the group. Default is 0.
 * moveGroup - Optional boolean that allows the group to be moved. Default
 * is false.
 * topBorder - Optional top border to be added in the group. Default is 0.
 * rightBorder - Optional top border to be added in the group. Default is 0.
 * bottomBorder - Optional top border to be added in the group. Default is 0.
 * leftBorder - Optional top border to be added in the group. Default is 0.
 */
mxGraph.prototype.updateGroupBounds = function(cells, border, moveGroup, topBorder, rightBorder, bottomBorder, leftBorder)
{
	if (cells == null)
	{
		cells = this.getSelectionCells();
	}
	
	border = (border != null) ? border : 0;
	moveGroup = (moveGroup != null) ? moveGroup : false;
	topBorder = (topBorder != null) ? topBorder : 0;
	rightBorder = (rightBorder != null) ? rightBorder : 0;
	bottomBorder = (bottomBorder != null) ? bottomBorder : 0;
	leftBorder = (leftBorder != null) ? leftBorder : 0;

	this.model.beginUpdate();
	try
	{
		for (var i = cells.length - 1; i >= 0; i--)
		{
			var geo = this.getCellGeometry(cells[i]);
			
			if (geo != null)
			{
				var children = this.getChildCells(cells[i]);
				
				if (children != null && children.length > 0)
				{
					var bounds = this.getBoundingBoxFromGeometry(children, true);
					
					if (bounds != null && bounds.width > 0 && bounds.height > 0)
					{
						var left = 0;
						var top = 0;
						
						// Adds the size of the title area for swimlanes
						if (this.isSwimlane(cells[i]))
						{
							var size = this.getStartSize(cells[i]);
							left = size.width;
							top = size.height;
						}
						
						geo = geo.clone();
						
						if (moveGroup)
						{
							geo.x = Math.round(geo.x + bounds.x - border - left - leftBorder);
							geo.y = Math.round(geo.y + bounds.y - border - top - topBorder);
						}
						
						geo.width = Math.round(bounds.width + 2 * border + left + leftBorder + rightBorder);
						geo.height = Math.round(bounds.height + 2 * border + top + topBorder + bottomBorder);
						
						this.model.setGeometry(cells[i], geo);
						this.moveCells(children, border + left - bounds.x + leftBorder,
								border + top - bounds.y + topBorder);
					}
				}
			}
		}
	}
	finally
	{
		this.model.endUpdate();
	}

	return cells;
};

/**
 * Function: getBoundingBox
 * 
 * Returns the bounding box for the given array of <mxCells>. The bounding box for
 * each cell and its descendants is computed using <mxGraphView.getBoundingBox>.
 *
 * Parameters:
 *
 * cells - Array of <mxCells> whose bounding box should be returned.
 */
mxGraph.prototype.getBoundingBox = function(cells)
{
	var result = null;
	
	if (cells != null && cells.length > 0)
	{
		for (var i = 0; i < cells.length; i++)
		{
			if (this.model.isVertex(cells[i]) || this.model.isEdge(cells[i]))
			{
				var bbox = this.view.getBoundingBox(this.view.getState(cells[i]), true);
			
				if (bbox != null)
				{
					if (result == null)
					{
						result = mxRectangle.fromRectangle(bbox);
					}
					else
					{
						result.add(bbox);
					}
				}
			}
		}
	}
	
	return result;
};

/**
 * Group: Cell cloning, insertion and removal
 */

/**
 * Function: cloneCells
 * 
 * Returns the clones for the given cells. The clones are created recursively
 * using <mxGraphModel.cloneCells>. If the terminal of an edge is not in the
 * given array, then the respective end is assigned a terminal point and the
 * terminal is removed.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to be cloned.
 * allowInvalidEdges - Optional boolean that specifies if invalid edges
 * should be cloned. Default is true.
 * mapping - Optional mapping for existing clones.
 */
mxGraph.prototype.cloneCells = function(cells, allowInvalidEdges, mapping)
{
	allowInvalidEdges = (allowInvalidEdges != null) ? allowInvalidEdges : true;
	var clones = null;
	
	if (cells != null)
	{
		// Creates a dictionary for fast lookups
		var dict = new mxDictionary();
		var tmp = [];
		
		for (var i = 0; i < cells.length; i++)
		{
			dict.put(cells[i], true);
			tmp.push(cells[i]);
		}
		
		if (tmp.length > 0)
		{
			var scale = this.view.scale;
			var trans = this.view.translate;
			clones = this.model.cloneCells(cells, true, mapping);
		
			for (var i = 0; i < cells.length; i++)
			{
				if (!allowInvalidEdges && this.model.isEdge(clones[i]) &&
					this.getEdgeValidationError(clones[i],
						this.model.getTerminal(clones[i], true),
						this.model.getTerminal(clones[i], false)) != null)
				{
					clones[i] = null;
				}
				else
				{
					var g = this.model.getGeometry(clones[i]);
					
					if (g != null)
					{
						var state = this.view.getState(cells[i]);
						var pstate = this.view.getState(this.model.getParent(cells[i]));
						
						if (state != null && pstate != null)
						{
							var dx = pstate.origin.x;
							var dy = pstate.origin.y;
							
							if (this.model.isEdge(clones[i]))
							{
								var pts = state.absolutePoints;
								
								// Checks if the source is cloned or sets the terminal point
								var src = this.model.getTerminal(cells[i], true);
								
								while (src != null && !dict.get(src))
								{
									src = this.model.getParent(src);
								}
								
								if (src == null)
								{
									g.setTerminalPoint(
										new mxPoint(pts[0].x / scale - trans.x,
											pts[0].y / scale - trans.y), true);
								}
								
								// Checks if the target is cloned or sets the terminal point
								var trg = this.model.getTerminal(cells[i], false);
								
								while (trg != null && !dict.get(trg))
								{
									trg = this.model.getParent(trg);
								}
								
								if (trg == null)
								{
									var n = pts.length - 1;
									g.setTerminalPoint(
										new mxPoint(pts[n].x / scale - trans.x,
											pts[n].y / scale - trans.y), false);
								}
								
								// Translates the control points
								var points = g.points;
								
								if (points != null)
								{
									for (var j = 0; j < points.length; j++)
									{
										points[j].x += dx;
										points[j].y += dy;
									}
								}
							}
							else
							{
								g.translate(dx, dy);
							}
						}
					}
				}
			}
		}
		else
		{
			clones = [];
		}
	}
	
	return clones;
};

/**
 * Function: insertVertex
 * 
 * Adds a new vertex into the given parent <mxCell> using value as the user
 * object and the given coordinates as the <mxGeometry> of the new vertex.
 * The id and style are used for the respective properties of the new
 * <mxCell>, which is returned.
 *
 * When adding new vertices from a mouse event, one should take into
 * account the offset of the graph container and the scale and translation
 * of the view in order to find the correct unscaled, untranslated
 * coordinates using <mxGraph.getPointForEvent> as follows:
 * 
 * (code)
 * var pt = graph.getPointForEvent(evt);
 * var parent = graph.getDefaultParent();
 * graph.insertVertex(parent, null,
 * 			'Hello, World!', x, y, 220, 30);
 * (end)
 * 
 * For adding image cells, the style parameter can be assigned as
 * 
 * (code)
 * stylename;image=imageUrl
 * (end)
 * 
 * See <mxGraph> for more information on using images.
 *
 * Parameters:
 * 
 * parent - <mxCell> that specifies the parent of the new vertex.
 * id - Optional string that defines the Id of the new vertex.
 * value - Object to be used as the user object.
 * x - Integer that defines the x coordinate of the vertex.
 * y - Integer that defines the y coordinate of the vertex.
 * width - Integer that defines the width of the vertex.
 * height - Integer that defines the height of the vertex.
 * style - Optional string that defines the cell style.
 * relative - Optional boolean that specifies if the geometry is relative.
 * Default is false.
 */
mxGraph.prototype.insertVertex = function(parent, id, value,
	x, y, width, height, style, relative)
{
	var vertex = this.createVertex(parent, id, value, x, y, width, height, style, relative);

	return this.addCell(vertex, parent);
};

/**
 * Function: createVertex
 * 
 * Hook method that creates the new vertex for <insertVertex>.
 */
mxGraph.prototype.createVertex = function(parent, id, value,
		x, y, width, height, style, relative)
{
	// Creates the geometry for the vertex
	var geometry = new mxGeometry(x, y, width, height);
	geometry.relative = (relative != null) ? relative : false;
	
	// Creates the vertex
	var vertex = new mxCell(value, geometry, style);
	vertex.setId(id);
	vertex.setVertex(true);
	vertex.setConnectable(true);
	
	return vertex;
};
	
/**
 * Function: insertEdge
 * 
 * Adds a new edge into the given parent <mxCell> using value as the user
 * object and the given source and target as the terminals of the new edge.
 * The id and style are used for the respective properties of the new
 * <mxCell>, which is returned.
 *
 * Parameters:
 * 
 * parent - <mxCell> that specifies the parent of the new edge.
 * id - Optional string that defines the Id of the new edge.
 * value - JavaScript object to be used as the user object.
 * source - <mxCell> that defines the source of the edge.
 * target - <mxCell> that defines the target of the edge.
 * style - Optional string that defines the cell style.
 */
mxGraph.prototype.insertEdge = function(parent, id, value, source, target, style)
{
	var edge = this.createEdge(parent, id, value, source, target, style);
	
	return this.addEdge(edge, parent, source, target);
};

/**
 * Function: createEdge
 * 
 * Hook method that creates the new edge for <insertEdge>. This
 * implementation does not set the source and target of the edge, these
 * are set when the edge is added to the model.
 * 
 */
mxGraph.prototype.createEdge = function(parent, id, value, source, target, style)
{
	// Creates the edge
	var edge = new mxCell(value, new mxGeometry(), style);
	edge.setId(id);
	edge.setEdge(true);
	edge.geometry.relative = true;
	
	return edge;
};

/**
 * Function: addEdge
 * 
 * Adds the edge to the parent and connects it to the given source and
 * target terminals. This is a shortcut method. Returns the edge that was
 * added.
 * 
 * Parameters:
 * 
 * edge - <mxCell> to be inserted into the given parent.
 * parent - <mxCell> that represents the new parent. If no parent is
 * given then the default parent is used.
 * source - Optional <mxCell> that represents the source terminal.
 * target - Optional <mxCell> that represents the target terminal.
 * index - Optional index to insert the cells at. Default is to append.
 */
mxGraph.prototype.addEdge = function(edge, parent, source, target, index)
{
	return this.addCell(edge, parent, index, source, target);
};

/**
 * Function: addCell
 * 
 * Adds the cell to the parent and connects it to the given source and
 * target terminals. This is a shortcut method. Returns the cell that was
 * added.
 * 
 * Parameters:
 * 
 * cell - <mxCell> to be inserted into the given parent.
 * parent - <mxCell> that represents the new parent. If no parent is
 * given then the default parent is used.
 * index - Optional index to insert the cells at. Default is to append.
 * source - Optional <mxCell> that represents the source terminal.
 * target - Optional <mxCell> that represents the target terminal.
 */
mxGraph.prototype.addCell = function(cell, parent, index, source, target)
{
	return this.addCells([cell], parent, index, source, target)[0];
};

/**
 * Function: addCells
 * 
 * Adds the cells to the parent at the given index, connecting each cell to
 * the optional source and target terminal. The change is carried out using
 * <cellsAdded>. This method fires <mxEvent.ADD_CELLS> while the
 * transaction is in progress. Returns the cells that were added.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to be inserted.
 * parent - <mxCell> that represents the new parent. If no parent is
 * given then the default parent is used.
 * index - Optional index to insert the cells at. Default is to append.
 * source - Optional source <mxCell> for all inserted cells.
 * target - Optional target <mxCell> for all inserted cells.
 */
mxGraph.prototype.addCells = function(cells, parent, index, source, target)
{
	if (parent == null)
	{
		parent = this.getDefaultParent();
	}
	
	if (index == null)
	{
		index = this.model.getChildCount(parent);
	}
	
	this.model.beginUpdate();
	try
	{
		this.cellsAdded(cells, parent, index, source, target, false, true);
		this.fireEvent(new mxEventObject(mxEvent.ADD_CELLS, 'cells', cells,
				'parent', parent, 'index', index, 'source', source, 'target', target));
	}
	finally
	{
		this.model.endUpdate();
	}

	return cells;
};

/**
 * Function: cellsAdded
 * 
 * Adds the specified cells to the given parent. This method fires
 * <mxEvent.CELLS_ADDED> while the transaction is in progress.
 */
mxGraph.prototype.cellsAdded = function(cells, parent, index, source, target, absolute, constrain, extend)
{
	if (cells != null && parent != null && index != null)
	{
		this.model.beginUpdate();
		try
		{
			var parentState = (absolute) ? this.view.getState(parent) : null;
			var o1 = (parentState != null) ? parentState.origin : null;
			var zero = new mxPoint(0, 0);

			for (var i = 0; i < cells.length; i++)
			{
				if (cells[i] == null)
				{
					index--;
				}
				else
				{
					var previous = this.model.getParent(cells[i]);
	
					// Keeps the cell at its absolute location
					if (o1 != null && cells[i] != parent && parent != previous)
					{
						var oldState = this.view.getState(previous);
						var o2 = (oldState != null) ? oldState.origin : zero;
						var geo = this.model.getGeometry(cells[i]);
	
						if (geo != null)
						{
							var dx = o2.x - o1.x;
							var dy = o2.y - o1.y;
	
							// FIXME: Cells should always be inserted first before any other edit
							// to avoid forward references in sessions.
							geo = geo.clone();
							geo.translate(dx, dy);
							
							if (!geo.relative && this.model.isVertex(cells[i]) &&
								!this.isAllowNegativeCoordinates())
							{
								geo.x = Math.max(0, geo.x);
								geo.y = Math.max(0, geo.y);
							}
							
							this.model.setGeometry(cells[i], geo);
						}
					}
	
					// Decrements all following indices
					// if cell is already in parent
					if (parent == previous && index + i > this.model.getChildCount(parent))
					{
						index--;
					}

					this.model.add(parent, cells[i], index + i);
					
					if (this.autoSizeCellsOnAdd)
					{
						this.autoSizeCell(cells[i], true);
					}

					// Extends the parent or constrains the child
					if ((extend == null || extend) &&
						this.isExtendParentsOnAdd(cells[i]) && this.isExtendParent(cells[i]))
					{
						this.extendParent(cells[i]);
					}
					
					// Additionally constrains the child after extending the parent
					if (constrain == null || constrain)
					{
						this.constrainChild(cells[i]);
					}
					
					// Sets the source terminal
					if (source != null)
					{
						this.cellConnected(cells[i], source, true);
					}
					
					// Sets the target terminal
					if (target != null)
					{
						this.cellConnected(cells[i], target, false);
					}
				}
			}
			
			this.fireEvent(new mxEventObject(mxEvent.CELLS_ADDED, 'cells', cells,
				'parent', parent, 'index', index, 'source', source, 'target', target,
				'absolute', absolute));
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Function: autoSizeCell
 * 
 * Resizes the specified cell to just fit around the its label and/or children
 * 
 * Parameters:
 * 
 * cell - <mxCells> to be resized.
 * recurse - Optional boolean which specifies if all descendants should be
 * autosized. Default is true.
 */
mxGraph.prototype.autoSizeCell = function(cell, recurse)
{
	recurse = (recurse != null) ? recurse : true;
	
	if (recurse)
	{
		var childCount = this.model.getChildCount(cell);
		
		for (var i = 0; i < childCount; i++)
		{
			this.autoSizeCell(this.model.getChildAt(cell, i));
		}
	}

	if (this.getModel().isVertex(cell) && this.isAutoSizeCell(cell))
	{
		this.updateCellSize(cell);
	}
};

/**
 * Function: removeCells
 * 
 * Removes the given cells from the graph including all connected edges if
 * includeEdges is true. The change is carried out using <cellsRemoved>.
 * This method fires <mxEvent.REMOVE_CELLS> while the transaction is in
 * progress. The removed cells are returned as an array.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to remove. If null is specified then the
 * selection cells which are deletable are used.
 * includeEdges - Optional boolean which specifies if all connected edges
 * should be removed as well. Default is true.
 */
mxGraph.prototype.removeCells = function(cells, includeEdges)
{
	includeEdges = (includeEdges != null) ? includeEdges : true;
	
	if (cells == null)
	{
		cells = this.getDeletableCells(this.getSelectionCells());
	}

	// Adds all edges to the cells
	if (includeEdges)
	{
		// FIXME: Remove duplicate cells in result or do not add if
		// in cells or descendant of cells
		cells = this.getDeletableCells(this.addAllEdges(cells));
	}

	this.model.beginUpdate();
	try
	{
		this.cellsRemoved(cells);
		this.fireEvent(new mxEventObject(mxEvent.REMOVE_CELLS, 
				'cells', cells, 'includeEdges', includeEdges));
	}
	finally
	{
		this.model.endUpdate();
	}
	
	return cells;
};

/**
 * Function: cellsRemoved
 * 
 * Removes the given cells from the model. This method fires
 * <mxEvent.CELLS_REMOVED> while the transaction is in progress.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to remove.
 */
mxGraph.prototype.cellsRemoved = function(cells)
{
	if (cells != null && cells.length > 0)
	{
		var scale = this.view.scale;
		var tr = this.view.translate;
		
		this.model.beginUpdate();
		try
		{
			// Creates hashtable for faster lookup
			var dict = new mxDictionary();
			
			for (var i = 0; i < cells.length; i++)
			{
				dict.put(cells[i], true);
			}
			
			for (var i = 0; i < cells.length; i++)
			{
				// Disconnects edges which are not in cells
				var edges = this.getAllEdges([cells[i]]);
				
				var disconnectTerminal = mxUtils.bind(this, function(edge, source)
				{
					var geo = this.model.getGeometry(edge);

					if (geo != null)
					{
						var state = this.view.getState(edge);
								
						if (state != null)
						{
							// Checks which side of the edge is being disconnected
							var tmp = state.getVisibleTerminal(source);
							var connected = false;
							
							while (tmp != null)
							{
								if (cells[i] == tmp)
								{
									connected = true;
									break;
								}
								
								tmp = this.model.getParent(tmp);
							}
							
							if (connected)
							{
								var dx = tr.x;
								var dy = tr.y;
								var parentState = this.view.getState(this.model.getParent(edge));
								
								if (parentState != null && this.model.isVertex(parentState.cell))
								{
									dx = parentState.x / scale;
									dy = parentState.y / scale;
								}
								
								geo = geo.clone();
								var pts = state.absolutePoints;
								var n = (source) ? 0 : pts.length - 1;
								geo.setTerminalPoint(new mxPoint(pts[n].x / scale - dx, pts[n].y / scale - dy), source);
								this.model.setTerminal(edges[j], null, source);
								this.model.setGeometry(edges[j], geo);
							}
						}
					}
				});
				
				for (var j = 0; j < edges.length; j++)
				{
					if (!dict.get(edges[j]))
					{
						disconnectTerminal(edges[j], true);
						disconnectTerminal(edges[j], false);
					}
				}

				this.model.remove(cells[i]);
			}
			
			this.fireEvent(new mxEventObject(mxEvent.CELLS_REMOVED, 'cells', cells));
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Function: splitEdge
 * 
 * Splits the given edge by adding the newEdge between the previous source
 * and the given cell and reconnecting the source of the given edge to the
 * given cell. This method fires <mxEvent.SPLIT_EDGE> while the transaction
 * is in progress. Returns the new edge that was inserted.
 * 
 * Parameters:
 * 
 * edge - <mxCell> that represents the edge to be splitted.
 * cells - <mxCells> that represents the cells to insert into the edge.
 * newEdge - <mxCell> that represents the edge to be inserted.
 * dx - Optional integer that specifies the vector to move the cells.
 * dy - Optional integer that specifies the vector to move the cells.
 */
mxGraph.prototype.splitEdge = function(edge, cells, newEdge, dx, dy)
{
	dx = dx || 0;
	dy = dy || 0;

	var parent = this.model.getParent(edge);
	var source = this.model.getTerminal(edge, true);

	this.model.beginUpdate();
	try
	{
		if (newEdge == null)
		{
			newEdge = this.cloneCells([edge])[0];
			
			// Removes waypoints before/after new cell
			var state = this.view.getState(edge);
			var geo = this.getCellGeometry(newEdge);
			
			if (geo != null && geo.points != null && state != null)
			{
				var t = this.view.translate;
				var s = this.view.scale;
				var idx = mxUtils.findNearestSegment(state, (dx + t.x) * s, (dy + t.y) * s);
				geo.points = geo.points.slice(0, idx);
								
				geo = this.getCellGeometry(edge);
				
				if (geo != null && geo.points != null)
				{
					geo = geo.clone();
					geo.points = geo.points.slice(idx);
					this.model.setGeometry(edge, geo);
				}
			}
		}
		
		this.cellsMoved(cells, dx, dy, false, false);
		this.cellsAdded(cells, parent, this.model.getChildCount(parent), null, null,
				true);
		this.cellsAdded([newEdge], parent, this.model.getChildCount(parent),
				source, cells[0], false);
		this.cellConnected(edge, cells[0], true);
		this.fireEvent(new mxEventObject(mxEvent.SPLIT_EDGE, 'edge', edge,
				'cells', cells, 'newEdge', newEdge, 'dx', dx, 'dy', dy));
	}
	finally
	{
		this.model.endUpdate();
	}

	return newEdge;
};

/**
 * Group: Cell visibility
 */

/**
 * Function: toggleCells
 * 
 * Sets the visible state of the specified cells and all connected edges
 * if includeEdges is true. The change is carried out using <cellsToggled>.
 * This method fires <mxEvent.TOGGLE_CELLS> while the transaction is in
 * progress. Returns the cells whose visible state was changed.
 * 
 * Parameters:
 * 
 * show - Boolean that specifies the visible state to be assigned.
 * cells - Array of <mxCells> whose visible state should be changed. If
 * null is specified then the selection cells are used.
 * includeEdges - Optional boolean indicating if the visible state of all
 * connected edges should be changed as well. Default is true.
 */
mxGraph.prototype.toggleCells = function(show, cells, includeEdges)
{
	if (cells == null)
	{
		cells = this.getSelectionCells();
	}

	// Adds all connected edges recursively
	if (includeEdges)
	{
		cells = this.addAllEdges(cells);
	}

	this.model.beginUpdate();
	try
	{
		this.cellsToggled(cells, show);
		this.fireEvent(new mxEventObject(mxEvent.TOGGLE_CELLS,
			'show', show, 'cells', cells, 'includeEdges', includeEdges));
	}
	finally
	{
		this.model.endUpdate();
	}

	return cells;
};

/**
 * Function: cellsToggled
 * 
 * Sets the visible state of the specified cells.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> whose visible state should be changed.
 * show - Boolean that specifies the visible state to be assigned.
 */
mxGraph.prototype.cellsToggled = function(cells, show)
{
	if (cells != null && cells.length > 0)
	{
		this.model.beginUpdate();
		try
		{
			for (var i = 0; i < cells.length; i++)
			{
				this.model.setVisible(cells[i], show);
			}
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Group: Folding
 */

/**
 * Function: foldCells
 * 
 * Sets the collapsed state of the specified cells and all descendants
 * if recurse is true. The change is carried out using <cellsFolded>.
 * This method fires <mxEvent.FOLD_CELLS> while the transaction is in
 * progress. Returns the cells whose collapsed state was changed.
 * 
 * Parameters:
 * 
 * collapsed - Boolean indicating the collapsed state to be assigned.
 * recurse - Optional boolean indicating if the collapsed state of all
 * descendants should be set. Default is false.
 * cells - Array of <mxCells> whose collapsed state should be set. If
 * null is specified then the foldable selection cells are used.
 * checkFoldable - Optional boolean indicating of isCellFoldable should be
 * checked. Default is false.
 * evt - Optional native event that triggered the invocation.
 */
mxGraph.prototype.foldCells = function(collapse, recurse, cells, checkFoldable, evt)
{
	recurse = (recurse != null) ? recurse : false;
	
	if (cells == null)
	{
		cells = this.getFoldableCells(this.getSelectionCells(), collapse);
	}

	this.stopEditing(false);

	this.model.beginUpdate();
	try
	{
		this.cellsFolded(cells, collapse, recurse, checkFoldable);
		this.fireEvent(new mxEventObject(mxEvent.FOLD_CELLS,
			'collapse', collapse, 'recurse', recurse, 'cells', cells));
	}
	finally
	{
		this.model.endUpdate();
	}

	return cells;
};

/**
 * Function: cellsFolded
 * 
 * Sets the collapsed state of the specified cells. This method fires
 * <mxEvent.CELLS_FOLDED> while the transaction is in progress. Returns the
 * cells whose collapsed state was changed.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> whose collapsed state should be set.
 * collapsed - Boolean indicating the collapsed state to be assigned.
 * recurse - Boolean indicating if the collapsed state of all descendants
 * should be set.
 * checkFoldable - Optional boolean indicating of isCellFoldable should be
 * checked. Default is false.
 */
mxGraph.prototype.cellsFolded = function(cells, collapse, recurse, checkFoldable)
{
	if (cells != null && cells.length > 0)
	{
		this.model.beginUpdate();
		try
		{
			for (var i = 0; i < cells.length; i++)
			{
				if ((!checkFoldable || this.isCellFoldable(cells[i], collapse)) &&
					collapse != this.isCellCollapsed(cells[i]))
				{
					this.model.setCollapsed(cells[i], collapse);
					this.swapBounds(cells[i], collapse);

					if (this.isExtendParent(cells[i]))
					{
						this.extendParent(cells[i]);
					}

					if (recurse)
					{
						var children = this.model.getChildren(cells[i]);
						this.foldCells(children, collapse, recurse);
					}
					
					this.constrainChild(cells[i]);
				}
			}
			
			this.fireEvent(new mxEventObject(mxEvent.CELLS_FOLDED,
				'cells', cells, 'collapse', collapse, 'recurse', recurse));
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Function: swapBounds
 * 
 * Swaps the alternate and the actual bounds in the geometry of the given
 * cell invoking <updateAlternateBounds> before carrying out the swap.
 * 
 * Parameters:
 * 
 * cell - <mxCell> for which the bounds should be swapped.
 * willCollapse - Boolean indicating if the cell is going to be collapsed.
 */
mxGraph.prototype.swapBounds = function(cell, willCollapse)
{
	if (cell != null)
	{
		var geo = this.model.getGeometry(cell);
		
		if (geo != null)
		{
			geo = geo.clone();
			
			this.updateAlternateBounds(cell, geo, willCollapse);
			geo.swap();
			
			this.model.setGeometry(cell, geo);
		}
	}
};

/**
 * Function: updateAlternateBounds
 * 
 * Updates or sets the alternate bounds in the given geometry for the given
 * cell depending on whether the cell is going to be collapsed. If no
 * alternate bounds are defined in the geometry and
 * <collapseToPreferredSize> is true, then the preferred size is used for
 * the alternate bounds. The top, left corner is always kept at the same
 * location.
 * 
 * Parameters:
 * 
 * cell - <mxCell> for which the geometry is being udpated.
 * g - <mxGeometry> for which the alternate bounds should be updated.
 * willCollapse - Boolean indicating if the cell is going to be collapsed.
 */
mxGraph.prototype.updateAlternateBounds = function(cell, geo, willCollapse)
{
	if (cell != null && geo != null)
	{
		var state = this.view.getState(cell);
		var style = (state != null) ? state.style : this.getCellStyle(cell);

		if (geo.alternateBounds == null)
		{
			var bounds = geo;
			
			if (this.collapseToPreferredSize)
			{
				var tmp = this.getPreferredSizeForCell(cell);
				
				if (tmp != null)
				{
					bounds = tmp;

					var startSize = mxUtils.getValue(style, mxConstants.STYLE_STARTSIZE);

					if (startSize > 0)
					{
						bounds.height = Math.max(bounds.height, startSize);
					}
				}
			}
			
			geo.alternateBounds = new mxRectangle(0, 0, bounds.width, bounds.height);
		}
		
		if (geo.alternateBounds != null)
		{
			geo.alternateBounds.x = geo.x;
			geo.alternateBounds.y = geo.y;
			
			var alpha = mxUtils.toRadians(style[mxConstants.STYLE_ROTATION] || 0);
			
			if (alpha != 0)
			{
				var dx = geo.alternateBounds.getCenterX() - geo.getCenterX();
				var dy = geo.alternateBounds.getCenterY() - geo.getCenterY();
	
				var cos = Math.cos(alpha);
				var sin = Math.sin(alpha);
	
				var dx2 = cos * dx - sin * dy;
				var dy2 = sin * dx + cos * dy;
				
				geo.alternateBounds.x += dx2 - dx;
				geo.alternateBounds.y += dy2 - dy;
			}
		}
	}
};

/**
 * Function: addAllEdges
 * 
 * Returns an array with the given cells and all edges that are connected
 * to a cell or one of its descendants.
 */
mxGraph.prototype.addAllEdges = function(cells)
{
	var allCells = cells.slice();
	
	return mxUtils.removeDuplicates(allCells.concat(this.getAllEdges(cells)));
};

/**
 * Function: getAllEdges
 * 
 * Returns all edges connected to the given cells or its descendants.
 */
mxGraph.prototype.getAllEdges = function(cells)
{
	var edges = [];
	
	if (cells != null)
	{
		for (var i = 0; i < cells.length; i++)
		{
			var edgeCount = this.model.getEdgeCount(cells[i]);
			
			for (var j = 0; j < edgeCount; j++)
			{
				edges.push(this.model.getEdgeAt(cells[i], j));
			}

			// Recurses
			var children = this.model.getChildren(cells[i]);
			edges = edges.concat(this.getAllEdges(children));
		}
	}
	
	return edges;
};

/**
 * Group: Cell sizing
 */

/**
 * Function: updateCellSize
 * 
 * Updates the size of the given cell in the model using <cellSizeUpdated>.
 * This method fires <mxEvent.UPDATE_CELL_SIZE> while the transaction is in
 * progress. Returns the cell whose size was updated.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose size should be updated.
 */
mxGraph.prototype.updateCellSize = function(cell, ignoreChildren)
{
	ignoreChildren = (ignoreChildren != null) ? ignoreChildren : false;
	
	this.model.beginUpdate();				
	try
	{
		this.cellSizeUpdated(cell, ignoreChildren);
		this.fireEvent(new mxEventObject(mxEvent.UPDATE_CELL_SIZE,
				'cell', cell, 'ignoreChildren', ignoreChildren));
	}
	finally
	{
		this.model.endUpdate();
	}
	
	return cell;
};

/**
 * Function: cellSizeUpdated
 * 
 * Updates the size of the given cell in the model using
 * <getPreferredSizeForCell> to get the new size.
 * 
 * Parameters:
 * 
 * cell - <mxCell> for which the size should be changed.
 */
mxGraph.prototype.cellSizeUpdated = function(cell, ignoreChildren)
{
	if (cell != null)
	{
		this.model.beginUpdate();				
		try
		{
			var size = this.getPreferredSizeForCell(cell);
			var geo = this.model.getGeometry(cell);
			
			if (size != null && geo != null)
			{
				var collapsed = this.isCellCollapsed(cell);
				geo = geo.clone();

				if (this.isSwimlane(cell))
				{
					var state = this.view.getState(cell);
					var style = (state != null) ? state.style : this.getCellStyle(cell);
					var cellStyle = this.model.getStyle(cell);

					if (cellStyle == null)
					{
						cellStyle = '';
					}

					if (mxUtils.getValue(style, mxConstants.STYLE_HORIZONTAL, true))
					{
						cellStyle = mxUtils.setStyle(cellStyle,
								mxConstants.STYLE_STARTSIZE, size.height + 8);

						if (collapsed)
						{
							geo.height = size.height + 8;
						}

						geo.width = size.width;
					}
					else
					{
						cellStyle = mxUtils.setStyle(cellStyle,
								mxConstants.STYLE_STARTSIZE, size.width + 8);

						if (collapsed)
						{
							geo.width = size.width + 8;
						}

						geo.height = size.height;
					}

					this.model.setStyle(cell, cellStyle);
				}
				else
				{
					geo.width = size.width;
					geo.height = size.height;
				}

				if (!ignoreChildren && !collapsed)
				{
					var bounds = this.view.getBounds(this.model.getChildren(cell));

					if (bounds != null)
					{
						var tr = this.view.translate;
						var scale = this.view.scale;

						var width = (bounds.x + bounds.width) / scale - geo.x - tr.x;
						var height = (bounds.y + bounds.height) / scale - geo.y - tr.y;

						geo.width = Math.max(geo.width, width);
						geo.height = Math.max(geo.height, height);
					}
				}

				this.cellsResized([cell], [geo], false);
			}
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Function: getPreferredSizeForCell
 * 
 * Returns the preferred width and height of the given <mxCell> as an
 * <mxRectangle>. To implement a minimum width, add a new style eg.
 * minWidth in the vertex and override this method as follows.
 * 
 * (code)
 * var graphGetPreferredSizeForCell = graph.getPreferredSizeForCell;
 * graph.getPreferredSizeForCell = function(cell)
 * {
 *   var result = graphGetPreferredSizeForCell.apply(this, arguments);
 *   var style = this.getCellStyle(cell);
 *   
 *   if (style['minWidth'] > 0)
 *   {
 *     result.width = Math.max(style['minWidth'], result.width);
 *   }
 * 
 *   return result;
 * };
 * (end)
 * 
 * Parameters:
 * 
 * cell - <mxCell> for which the preferred size should be returned.
 */
mxGraph.prototype.getPreferredSizeForCell = function(cell)
{
	var result = null;
	
	if (cell != null)
	{
		var state = this.view.getState(cell) || this.view.createState(cell);
		var style = state.style;

		if (!this.model.isEdge(cell))
		{
			var fontSize = style[mxConstants.STYLE_FONTSIZE] || mxConstants.DEFAULT_FONTSIZE;
			var dx = 0;
			var dy = 0;
			
			// Adds dimension of image if shape is a label
			if (this.getImage(state) != null || style[mxConstants.STYLE_IMAGE] != null)
			{
				if (style[mxConstants.STYLE_SHAPE] == mxConstants.SHAPE_LABEL)
				{
					if (style[mxConstants.STYLE_VERTICAL_ALIGN] == mxConstants.ALIGN_MIDDLE)
					{
						dx += parseFloat(style[mxConstants.STYLE_IMAGE_WIDTH]) || mxLabel.prototype.imageSize;
					}
					
					if (style[mxConstants.STYLE_ALIGN] != mxConstants.ALIGN_CENTER)
					{
						dy += parseFloat(style[mxConstants.STYLE_IMAGE_HEIGHT]) || mxLabel.prototype.imageSize;
					}
				}
			}

			// Adds spacings
			dx += 2 * (style[mxConstants.STYLE_SPACING] || 0);
			dx += style[mxConstants.STYLE_SPACING_LEFT] || 0;
			dx += style[mxConstants.STYLE_SPACING_RIGHT] || 0;

			dy += 2 * (style[mxConstants.STYLE_SPACING] || 0);
			dy += style[mxConstants.STYLE_SPACING_TOP] || 0;
			dy += style[mxConstants.STYLE_SPACING_BOTTOM] || 0;
			
			// Add spacing for collapse/expand icon
			// LATER: Check alignment and use constants
			// for image spacing
			var image = this.getFoldingImage(state);
			
			if (image != null)
			{
				dx += image.width + 8;
			}

			// Adds space for label
			var value = this.cellRenderer.getLabelValue(state);

			if (value != null && value.length > 0)
			{
				if (!this.isHtmlLabel(state.cell))
				{
					value = mxUtils.htmlEntities(value);
				}
				
				value = value.replace(/\n/g, '<br>');
				
				var size = mxUtils.getSizeForString(value, fontSize, style[mxConstants.STYLE_FONTFAMILY]);
				var width = size.width + dx;
				var height = size.height + dy;
				
				if (!mxUtils.getValue(style, mxConstants.STYLE_HORIZONTAL, true))
				{
					var tmp = height;
					
					height = width;
					width = tmp;
				}
			
				if (this.gridEnabled)
				{
					width = this.snap(width + this.gridSize / 2);
					height = this.snap(height + this.gridSize / 2);
				}

				result = new mxRectangle(0, 0, width, height);
			}
			else
			{
				var gs2 = 4 * this.gridSize;
				result = new mxRectangle(0, 0, gs2, gs2);
			}
		}
	}
	
	return result;
};

/**
 * Function: resizeCell
 * 
 * Sets the bounds of the given cell using <resizeCells>. Returns the
 * cell which was passed to the function.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose bounds should be changed.
 * bounds - <mxRectangle> that represents the new bounds.
 */
mxGraph.prototype.resizeCell = function(cell, bounds, recurse)
{
	return this.resizeCells([cell], [bounds], recurse)[0];
};

/**
 * Function: resizeCells
 * 
 * Sets the bounds of the given cells and fires a <mxEvent.RESIZE_CELLS>
 * event while the transaction is in progress. Returns the cells which
 * have been passed to the function.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> whose bounds should be changed.
 * bounds - Array of <mxRectangles> that represent the new bounds.
 */
mxGraph.prototype.resizeCells = function(cells, bounds, recurse)
{
	recurse = (recurse != null) ? recurse : this.isRecursiveResize();
	
	this.model.beginUpdate();
	try
	{
		this.cellsResized(cells, bounds, recurse);
		this.fireEvent(new mxEventObject(mxEvent.RESIZE_CELLS,
				'cells', cells, 'bounds', bounds));
	}
	finally
	{
		this.model.endUpdate();
	}

	return cells;
};

/**
 * Function: cellsResized
 * 
 * Sets the bounds of the given cells and fires a <mxEvent.CELLS_RESIZED>
 * event. If <extendParents> is true, then the parent is extended if a
 * child size is changed so that it overlaps with the parent.
 * 
 * The following example shows how to control group resizes to make sure
 * that all child cells stay within the group.
 * 
 * (code)
 * graph.addListener(mxEvent.CELLS_RESIZED, function(sender, evt)
 * {
 *   var cells = evt.getProperty('cells');
 *   
 *   if (cells != null)
 *   {
 *     for (var i = 0; i < cells.length; i++)
 *     {
 *       if (graph.getModel().getChildCount(cells[i]) > 0)
 *       {
 *         var geo = graph.getCellGeometry(cells[i]);
 *         
 *         if (geo != null)
 *         {
 *           var children = graph.getChildCells(cells[i], true, true);
 *           var bounds = graph.getBoundingBoxFromGeometry(children, true);
 *           
 *           geo = geo.clone();
 *           geo.width = Math.max(geo.width, bounds.width);
 *           geo.height = Math.max(geo.height, bounds.height);
 *           
 *           graph.getModel().setGeometry(cells[i], geo);
 *         }
 *       }
 *     }
 *   }
 * });
 * (end)
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> whose bounds should be changed.
 * bounds - Array of <mxRectangles> that represent the new bounds.
 * recurse - Optional boolean that specifies if the children should be resized.
 */
mxGraph.prototype.cellsResized = function(cells, bounds, recurse)
{
	recurse = (recurse != null) ? recurse : false;
	
	if (cells != null && bounds != null && cells.length == bounds.length)
	{
		this.model.beginUpdate();
		try
		{
			for (var i = 0; i < cells.length; i++)
			{
				this.cellResized(cells[i], bounds[i], false, recurse);

				if (this.isExtendParent(cells[i]))
				{
					this.extendParent(cells[i]);
				}
				
				this.constrainChild(cells[i]);
			}

			if (this.resetEdgesOnResize)
			{
				this.resetEdges(cells);
			}
			
			this.fireEvent(new mxEventObject(mxEvent.CELLS_RESIZED,
					'cells', cells, 'bounds', bounds));
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Function: cellResized
 * 
 * Resizes the parents recursively so that they contain the complete area
 * of the resized child cell.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose bounds should be changed.
 * bounds - <mxRectangles> that represent the new bounds.
 * ignoreRelative - Boolean that indicates if relative cells should be ignored.
 * recurse - Optional boolean that specifies if the children should be resized.
 */
mxGraph.prototype.cellResized = function(cell, bounds, ignoreRelative, recurse)
{
	var geo = this.model.getGeometry(cell);

	if (geo != null && (geo.x != bounds.x || geo.y != bounds.y ||
		geo.width != bounds.width || geo.height != bounds.height))
	{
		geo = geo.clone();

		if (!ignoreRelative && geo.relative)
		{
			var offset = geo.offset;

			if (offset != null)
			{
				offset.x += bounds.x - geo.x;
				offset.y += bounds.y - geo.y;
			}
		}
		else
		{
			geo.x = bounds.x;
			geo.y = bounds.y;
		}

		geo.width = bounds.width;
		geo.height = bounds.height;

		if (!geo.relative && this.model.isVertex(cell) && !this.isAllowNegativeCoordinates())
		{
			geo.x = Math.max(0, geo.x);
			geo.y = Math.max(0, geo.y);
		}

		this.model.beginUpdate();
		try
		{
			if (recurse)
			{
				this.resizeChildCells(cell, geo);
			}
						
			this.model.setGeometry(cell, geo);
			this.constrainChildCells(cell);
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Function: resizeChildCells
 * 
 * Resizes the child cells of the given cell for the given new geometry with
 * respect to the current geometry of the cell.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that has been resized.
 * newGeo - <mxGeometry> that represents the new bounds.
 */
mxGraph.prototype.resizeChildCells = function(cell, newGeo)
{
	var geo = this.model.getGeometry(cell);
	var dx = newGeo.width / geo.width;
	var dy = newGeo.height / geo.height;
	var childCount = this.model.getChildCount(cell);
	
	for (var i = 0; i < childCount; i++)
	{
		this.scaleCell(this.model.getChildAt(cell, i), dx, dy, true);
	}
};

/**
 * Function: constrainChildCells
 * 
 * Constrains the children of the given cell using <constrainChild>.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that has been resized.
 */
mxGraph.prototype.constrainChildCells = function(cell)
{
	var childCount = this.model.getChildCount(cell);
	
	for (var i = 0; i < childCount; i++)
	{
		this.constrainChild(this.model.getChildAt(cell, i));
	}
};

/**
 * Function: scaleCell
 * 
 * Scales the points, position and size of the given cell according to the
 * given vertical and horizontal scaling factors.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose geometry should be scaled.
 * dx - Horizontal scaling factor.
 * dy - Vertical scaling factor.
 * recurse - Boolean indicating if the child cells should be scaled.
 */
mxGraph.prototype.scaleCell = function(cell, dx, dy, recurse)
{
	var geo = this.model.getGeometry(cell);
	
	if (geo != null)
	{
		var state = this.view.getState(cell);
		var style = (state != null) ? state.style : this.getCellStyle(cell);
		
		geo = geo.clone();
		
		// Stores values for restoring based on style
		var x = geo.x;
		var y = geo.y
		var w = geo.width;
		var h = geo.height;
		
		geo.scale(dx, dy, style[mxConstants.STYLE_ASPECT] == 'fixed');
		
		if (style[mxConstants.STYLE_RESIZE_WIDTH] == '1')
		{
			geo.width = w * dx;
		}
		else if (style[mxConstants.STYLE_RESIZE_WIDTH] == '0')
		{
			geo.width = w;
		}
		
		if (style[mxConstants.STYLE_RESIZE_HEIGHT] == '1')
		{
			geo.height = h * dy;
		}
		else if (style[mxConstants.STYLE_RESIZE_HEIGHT] == '0')
		{
			geo.height = h;
		}
		
		if (!this.isCellMovable(cell))
		{
			geo.x = x;
			geo.y = y;
		}
		
		if (!this.isCellResizable(cell))
		{
			geo.width = w;
			geo.height = h;
		}

		if (this.model.isVertex(cell))
		{
			this.cellResized(cell, geo, true, recurse);
		}
		else
		{
			this.model.setGeometry(cell, geo);
		}
	}
};

/**
 * Function: extendParent
 * 
 * Resizes the parents recursively so that they contain the complete area
 * of the resized child cell.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that has been resized.
 */
mxGraph.prototype.extendParent = function(cell)
{
	if (cell != null)
	{
		var parent = this.model.getParent(cell);
		var p = this.getCellGeometry(parent);
		
		if (parent != null && p != null && !this.isCellCollapsed(parent))
		{
			var geo = this.getCellGeometry(cell);
			
			if (geo != null && !geo.relative &&
				(p.width < geo.x + geo.width ||
				p.height < geo.y + geo.height))
			{
				p = p.clone();
				
				p.width = Math.max(p.width, geo.x + geo.width);
				p.height = Math.max(p.height, geo.y + geo.height);
				
				this.cellsResized([parent], [p], false);
			}
		}
	}
};

/**
 * Group: Cell moving
 */

/**
 * Function: importCells
 * 
 * Clones and inserts the given cells into the graph using the move
 * method and returns the inserted cells. This shortcut is used if
 * cells are inserted via datatransfer.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to be imported.
 * dx - Integer that specifies the x-coordinate of the vector. Default is 0.
 * dy - Integer that specifies the y-coordinate of the vector. Default is 0.
 * target - <mxCell> that represents the new parent of the cells.
 * evt - Mouseevent that triggered the invocation.
 * mapping - Optional mapping for existing clones.
 */
mxGraph.prototype.importCells = function(cells, dx, dy, target, evt, mapping)
{	
	return this.moveCells(cells, dx, dy, true, target, evt, mapping);
};

/**
 * Function: moveCells
 * 
 * Moves or clones the specified cells and moves the cells or clones by the
 * given amount, adding them to the optional target cell. The evt is the
 * mouse event as the mouse was released. The change is carried out using
 * <cellsMoved>. This method fires <mxEvent.MOVE_CELLS> while the
 * transaction is in progress. Returns the cells that were moved.
 * 
 * Use the following code to move all cells in the graph.
 * 
 * (code)
 * graph.moveCells(graph.getChildCells(null, true, true), 10, 10);
 * (end)
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to be moved, cloned or added to the target.
 * dx - Integer that specifies the x-coordinate of the vector. Default is 0.
 * dy - Integer that specifies the y-coordinate of the vector. Default is 0.
 * clone - Boolean indicating if the cells should be cloned. Default is false.
 * target - <mxCell> that represents the new parent of the cells.
 * evt - Mouseevent that triggered the invocation.
 * mapping - Optional mapping for existing clones.
 */
mxGraph.prototype.moveCells = function(cells, dx, dy, clone, target, evt, mapping)
{
	dx = (dx != null) ? dx : 0;
	dy = (dy != null) ? dy : 0;
	clone = (clone != null) ? clone : false;
	
	if (cells != null && (dx != 0 || dy != 0 || clone || target != null))
	{
		// Removes descandants with ancestors in cells to avoid multiple moving
		cells = this.model.getTopmostCells(cells);

		this.model.beginUpdate();
		try
		{
			// Faster cell lookups to remove relative edge labels with selected
			// terminals to avoid explicit and implicit move at same time
			var dict = new mxDictionary();
			
			for (var i = 0; i < cells.length; i++)
			{
				dict.put(cells[i], true);
			}
			
			var isSelected = mxUtils.bind(this, function(cell)
			{
				while (cell != null)
				{
					if (dict.get(cell))
					{
						return true;
					}
					
					cell = this.model.getParent(cell);
				}
				
				return false;
			});
			
			// Removes relative edge labels with selected terminals
			var checked = [];
			
			for (var i = 0; i < cells.length; i++)
			{
				var geo = this.getCellGeometry(cells[i]);
				var parent = this.model.getParent(cells[i]);
		
				if ((geo == null || !geo.relative) || !this.model.isEdge(parent) ||
					(!isSelected(this.model.getTerminal(parent, true)) &&
					!isSelected(this.model.getTerminal(parent, false))))
				{
					checked.push(cells[i]);
				}
			}

			cells = checked;
			
			if (clone)
			{
				cells = this.cloneCells(cells, this.isCloneInvalidEdges(), mapping);

				if (target == null)
				{
					target = this.getDefaultParent();
				}
			}

			// FIXME: Cells should always be inserted first before any other edit
			// to avoid forward references in sessions.
			// Need to disable allowNegativeCoordinates if target not null to
			// allow for temporary negative numbers until cellsAdded is called.
			var previous = this.isAllowNegativeCoordinates();
			
			if (target != null)
			{
				this.setAllowNegativeCoordinates(true);
			}
			
			this.cellsMoved(cells, dx, dy, !clone && this.isDisconnectOnMove()
					&& this.isAllowDanglingEdges(), target == null,
					this.isExtendParentsOnMove() && target == null);
			
			this.setAllowNegativeCoordinates(previous);

			if (target != null)
			{
				var index = this.model.getChildCount(target);
				this.cellsAdded(cells, target, index, null, null, true);
			}

			// Dispatches a move event
			this.fireEvent(new mxEventObject(mxEvent.MOVE_CELLS, 'cells', cells,
				'dx', dx, 'dy', dy, 'clone', clone, 'target', target, 'event', evt));
		}
		finally
		{
			this.model.endUpdate();
		}
	}

	return cells;
};

/**
 * Function: cellsMoved
 * 
 * Moves the specified cells by the given vector, disconnecting the cells
 * using disconnectGraph is disconnect is true. This method fires
 * <mxEvent.CELLS_MOVED> while the transaction is in progress.
 */
mxGraph.prototype.cellsMoved = function(cells, dx, dy, disconnect, constrain, extend)
{
	if (cells != null && (dx != 0 || dy != 0))
	{
		extend = (extend != null) ? extend : false;

		this.model.beginUpdate();
		try
		{
			if (disconnect)
			{
				this.disconnectGraph(cells);
			}

			for (var i = 0; i < cells.length; i++)
			{
				this.translateCell(cells[i], dx, dy);
				
				if (extend && this.isExtendParent(cells[i]))
				{
					this.extendParent(cells[i]);
				}
				else if (constrain)
				{
					this.constrainChild(cells[i]);
				}
			}

			if (this.resetEdgesOnMove)
			{
				this.resetEdges(cells);
			}
			
			this.fireEvent(new mxEventObject(mxEvent.CELLS_MOVED,
				'cells', cells, 'dx', dx, 'dy', dy, 'disconnect', disconnect));
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Function: translateCell
 * 
 * Translates the geometry of the given cell and stores the new,
 * translated geometry in the model as an atomic change.
 */
mxGraph.prototype.translateCell = function(cell, dx, dy)
{
	var geo = this.model.getGeometry(cell);

	if (geo != null)
	{
		dx = parseFloat(dx);
		dy = parseFloat(dy);
		geo = geo.clone();
		geo.translate(dx, dy);

		if (!geo.relative && this.model.isVertex(cell) && !this.isAllowNegativeCoordinates())
		{
			geo.x = Math.max(0, parseFloat(geo.x));
			geo.y = Math.max(0, parseFloat(geo.y));
		}
		
		if (geo.relative && !this.model.isEdge(cell))
		{
			var parent = this.model.getParent(cell);
			var angle = 0;
			
			if (this.model.isVertex(parent))
			{
				var state = this.view.getState(parent);
				var style = (state != null) ? state.style : this.getCellStyle(parent);
				
				angle = mxUtils.getValue(style, mxConstants.STYLE_ROTATION, 0);
			}
			
			if (angle != 0)
			{
				var rad = mxUtils.toRadians(-angle);
				var cos = Math.cos(rad);
				var sin = Math.sin(rad);
				var pt = mxUtils.getRotatedPoint(new mxPoint(dx, dy), cos, sin, new mxPoint(0, 0));
				dx = pt.x;
				dy = pt.y;
			}
			
			if (geo.offset == null)
			{
				geo.offset = new mxPoint(dx, dy);
			}
			else
			{
				geo.offset.x = parseFloat(geo.offset.x) + dx;
				geo.offset.y = parseFloat(geo.offset.y) + dy;
			}
		}

		this.model.setGeometry(cell, geo);
	}
};

/**
 * Function: getCellContainmentArea
 * 
 * Returns the <mxRectangle> inside which a cell is to be kept.
 * 
 * Parameters:
 * 
 * cell - <mxCell> for which the area should be returned.
 */
mxGraph.prototype.getCellContainmentArea = function(cell)
{
	if (cell != null && !this.model.isEdge(cell))
	{
		var parent = this.model.getParent(cell);
		
		if (parent != null && parent != this.getDefaultParent())
		{
			var g = this.model.getGeometry(parent);
			
			if (g != null)
			{
				var x = 0;
				var y = 0;
				var w = g.width;
				var h = g.height;
				
				if (this.isSwimlane(parent))
				{
					var size = this.getStartSize(parent);
					
					var state = this.view.getState(parent);
					var style = (state != null) ? state.style : this.getCellStyle(parent);
					var dir = mxUtils.getValue(style, mxConstants.STYLE_DIRECTION, mxConstants.DIRECTION_EAST);
					var flipH = mxUtils.getValue(style, mxConstants.STYLE_FLIPH, 0) == 1;
					var flipV = mxUtils.getValue(style, mxConstants.STYLE_FLIPV, 0) == 1;
					
					if (dir == mxConstants.DIRECTION_SOUTH || dir == mxConstants.DIRECTION_NORTH)
					{
						var tmp = size.width;
						size.width = size.height;
						size.height = tmp;
					}
					
					if ((dir == mxConstants.DIRECTION_EAST && !flipV) || (dir == mxConstants.DIRECTION_NORTH && !flipH) ||
						(dir == mxConstants.DIRECTION_WEST && flipV) || (dir == mxConstants.DIRECTION_SOUTH && flipH))
					{
						x = size.width;
						y = size.height;
					}

					w -= size.width;
					h -= size.height;
				}
				
				return new mxRectangle(x, y, w, h);
			}
		}
	}
	
	return null;
};

/**
 * Function: getMaximumGraphBounds
 * 
 * Returns the bounds inside which the diagram should be kept as an
 * <mxRectangle>.
 */
mxGraph.prototype.getMaximumGraphBounds = function()
{
	return this.maximumGraphBounds;
};

/**
 * Function: constrainChild
 * 
 * Keeps the given cell inside the bounds returned by
 * <getCellContainmentArea> for its parent, according to the rules defined by
 * <getOverlap> and <isConstrainChild>. This modifies the cell's geometry
 * in-place and does not clone it.
 * 
 * Parameters:
 * 
 * cells - <mxCell> which should be constrained.
 * sizeFirst - Specifies if the size should be changed first. Default is true.
 */
mxGraph.prototype.constrainChild = function(cell, sizeFirst)
{
	sizeFirst = (sizeFirst != null) ? sizeFirst : true;
	
	if (cell != null)
	{
		var geo = this.getCellGeometry(cell);
		
		if (geo != null && (this.isConstrainRelativeChildren() || !geo.relative))
		{
			var parent = this.model.getParent(cell);
			var pgeo = this.getCellGeometry(parent);
			var max = this.getMaximumGraphBounds();
			
			// Finds parent offset
			if (max != null)
			{
				var off = this.getBoundingBoxFromGeometry([parent], false);
				
				if (off != null)
				{
					max = mxRectangle.fromRectangle(max);
					
					max.x -= off.x;
					max.y -= off.y;
				}
			}
			
			if (this.isConstrainChild(cell))
			{
				var tmp = this.getCellContainmentArea(cell);
				
				if (tmp != null)
				{
					var overlap = this.getOverlap(cell);
	
					if (overlap > 0)
					{
						tmp = mxRectangle.fromRectangle(tmp);
						
						tmp.x -= tmp.width * overlap;
						tmp.y -= tmp.height * overlap;
						tmp.width += 2 * tmp.width * overlap;
						tmp.height += 2 * tmp.height * overlap;
					}
					
					// Find the intersection between max and tmp
					if (max == null)
					{
						max = tmp;
					}
					else
					{
						max = mxRectangle.fromRectangle(max);
						max.intersect(tmp);
					}
				}
			}
			
			if (max != null)
			{
				var cells = [cell];
				
				if (!this.isCellCollapsed(cell))
				{
					var desc = this.model.getDescendants(cell);
					
					for (var i = 0; i < desc.length; i++)
					{
						if (this.isCellVisible(desc[i]))
						{
							cells.push(desc[i]);
						}
					}
				}
				
				var bbox = this.getBoundingBoxFromGeometry(cells, false);
				
				if (bbox != null)
				{
					geo = geo.clone();
					
					// Cumulative horizontal movement
					var dx = 0;
					
					if (geo.width > max.width)
					{
						dx = geo.width - max.width;
						geo.width -= dx;
					}
					
					if (bbox.x + bbox.width > max.x + max.width)
					{
						dx -= bbox.x + bbox.width - max.x - max.width - dx;
					}
					
					// Cumulative vertical movement
					var dy = 0;
					
					if (geo.height > max.height)
					{
						dy = geo.height - max.height;
						geo.height -= dy;
					}
					
					if (bbox.y + bbox.height > max.y + max.height)
					{
						dy -= bbox.y + bbox.height - max.y - max.height - dy;
					}
					
					if (bbox.x < max.x)
					{
						dx -= bbox.x - max.x;
					}
					
					if (bbox.y < max.y)
					{
						dy -= bbox.y - max.y;
					}
					
					if (dx != 0 || dy != 0)
					{
						if (geo.relative)
						{
							// Relative geometries are moved via absolute offset
							if (geo.offset == null)
							{
								geo.offset = new mxPoint();
							}
						
							geo.offset.x += dx;
							geo.offset.y += dy;
						}
						else
						{
							geo.x += dx;
							geo.y += dy;
						}
					}
					
					this.model.setGeometry(cell, geo);
				}
			}
		}
	}
};

/**
 * Function: resetEdges
 * 
 * Resets the control points of the edges that are connected to the given
 * cells if not both ends of the edge are in the given cells array.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> for which the connected edges should be
 * reset.
 */
mxGraph.prototype.resetEdges = function(cells)
{
	if (cells != null)
	{
		// Prepares faster cells lookup
		var dict = new mxDictionary();
		
		for (var i = 0; i < cells.length; i++)
		{
			dict.put(cells[i], true);
		}
		
		this.model.beginUpdate();
		try
		{
			for (var i = 0; i < cells.length; i++)
			{
				var edges = this.model.getEdges(cells[i]);
				
				if (edges != null)
				{
					for (var j = 0; j < edges.length; j++)
					{
						var state = this.view.getState(edges[j]);
						
						var source = (state != null) ? state.getVisibleTerminal(true) : this.view.getVisibleTerminal(edges[j], true);
						var target = (state != null) ? state.getVisibleTerminal(false) : this.view.getVisibleTerminal(edges[j], false);
						
						// Checks if one of the terminals is not in the given array
						if (!dict.get(source) || !dict.get(target))
						{
							this.resetEdge(edges[j]);
						}
					}
				}
				
				this.resetEdges(this.model.getChildren(cells[i]));
			}
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Function: resetEdge
 * 
 * Resets the control points of the given edge.
 * 
 * Parameters:
 * 
 * edge - <mxCell> whose points should be reset.
 */
mxGraph.prototype.resetEdge = function(edge)
{
	var geo = this.model.getGeometry(edge);
	
	// Resets the control points
	if (geo != null && geo.points != null && geo.points.length > 0)
	{
		geo = geo.clone();
		geo.points = [];
		this.model.setGeometry(edge, geo);
	}
	
	return edge;
};

/**
 * Group: Cell connecting and connection constraints
 */

/**
 * Function: getOutlineConstraint
 * 
 * Returns the constraint used to connect to the outline of the given state.
 */
mxGraph.prototype.getOutlineConstraint = function(point, terminalState, me)
{
	if (terminalState.shape != null)
	{
		var bounds = this.view.getPerimeterBounds(terminalState);
		var direction = terminalState.style[mxConstants.STYLE_DIRECTION];
		
		if (direction == mxConstants.DIRECTION_NORTH || direction == mxConstants.DIRECTION_SOUTH)
		{
			bounds.x += bounds.width / 2 - bounds.height / 2;
			bounds.y += bounds.height / 2 - bounds.width / 2;
			var tmp = bounds.width;
			bounds.width = bounds.height;
			bounds.height = tmp;
		}
	
		var alpha = mxUtils.toRadians(terminalState.shape.getShapeRotation());
		
		if (alpha != 0)
		{
			var cos = Math.cos(-alpha);
			var sin = Math.sin(-alpha);
	
			var ct = new mxPoint(bounds.getCenterX(), bounds.getCenterY());
			point = mxUtils.getRotatedPoint(point, cos, sin, ct);
		}

		var sx = 1;
		var sy = 1;
		var dx = 0;
		var dy = 0;
		
		// LATER: Add flipping support for image shapes
		if (this.getModel().isVertex(terminalState.cell))
		{
			var flipH = terminalState.style[mxConstants.STYLE_FLIPH];
			var flipV = terminalState.style[mxConstants.STYLE_FLIPV];
			
			// Legacy support for stencilFlipH/V
			if (terminalState.shape != null && terminalState.shape.stencil != null)
			{
				flipH = mxUtils.getValue(terminalState.style, 'stencilFlipH', 0) == 1 || flipH;
				flipV = mxUtils.getValue(terminalState.style, 'stencilFlipV', 0) == 1 || flipV;
			}
			
			if (direction == mxConstants.DIRECTION_NORTH || direction == mxConstants.DIRECTION_SOUTH)
			{
				var tmp = flipH;
				flipH = flipV;
				flipV = tmp;
			}
			
			if (flipH)
			{
				sx = -1;
				dx = -bounds.width;
			}
			
			if (flipV)
			{
				sy = -1;
				dy = -bounds.height ;
			}
		}
		
		point = new mxPoint((point.x - bounds.x) * sx - dx + bounds.x, (point.y - bounds.y) * sy - dy + bounds.y);
		
		var x = Math.round((point.x - bounds.x) * 1000 / bounds.width) / 1000;
		var y = Math.round((point.y - bounds.y) * 1000 / bounds.height) / 1000;
		
		return new mxConnectionConstraint(new mxPoint(x, y), false);
	}
	
	return null;
};

/**
 * Function: getAllConnectionConstraints
 * 
 * Returns an array of all <mxConnectionConstraints> for the given terminal. If
 * the shape of the given terminal is a <mxStencilShape> then the constraints
 * of the corresponding <mxStencil> are returned.
 * 
 * Parameters:
 * 
 * terminal - <mxCellState> that represents the terminal.
 * source - Boolean that specifies if the terminal is the source or target.
 */
mxGraph.prototype.getAllConnectionConstraints = function(terminal, source)
{
	if (terminal != null && terminal.shape != null && terminal.shape.stencil != null)
	{
		return terminal.shape.stencil.constraints;
	}

	return null;
};

/**
 * Function: getConnectionConstraint
 * 
 * Returns an <mxConnectionConstraint> that describes the given connection
 * point. This result can then be passed to <getConnectionPoint>.
 * 
 * Parameters:
 * 
 * edge - <mxCellState> that represents the edge.
 * terminal - <mxCellState> that represents the terminal.
 * source - Boolean indicating if the terminal is the source or target.
 */
mxGraph.prototype.getConnectionConstraint = function(edge, terminal, source)
{
	var point = null;
	var x = edge.style[(source) ? mxConstants.STYLE_EXIT_X : mxConstants.STYLE_ENTRY_X];

	if (x != null)
	{
		var y = edge.style[(source) ? mxConstants.STYLE_EXIT_Y : mxConstants.STYLE_ENTRY_Y];
		
		if (y != null)
		{
			point = new mxPoint(parseFloat(x), parseFloat(y));
		}
	}
	
	var perimeter = false;
	
	if (point != null)
	{
		perimeter = mxUtils.getValue(edge.style, (source) ? mxConstants.STYLE_EXIT_PERIMETER :
			mxConstants.STYLE_ENTRY_PERIMETER, true);
	}
	
	return new mxConnectionConstraint(point, perimeter);
};

/**
 * Function: setConnectionConstraint
 * 
 * Sets the <mxConnectionConstraint> that describes the given connection point.
 * If no constraint is given then nothing is changed. To remove an existing
 * constraint from the given edge, use an empty constraint instead.
 * 
 * Parameters:
 * 
 * edge - <mxCell> that represents the edge.
 * terminal - <mxCell> that represents the terminal.
 * source - Boolean indicating if the terminal is the source or target.
 * constraint - Optional <mxConnectionConstraint> to be used for this
 * connection.
 */
mxGraph.prototype.setConnectionConstraint = function(edge, terminal, source, constraint)
{
	if (constraint != null)
	{
		this.model.beginUpdate();
		
		try
		{
			if (constraint == null || constraint.point == null)
			{
				this.setCellStyles((source) ? mxConstants.STYLE_EXIT_X :
					mxConstants.STYLE_ENTRY_X, null, [edge]);
				this.setCellStyles((source) ? mxConstants.STYLE_EXIT_Y :
					mxConstants.STYLE_ENTRY_Y, null, [edge]);
				this.setCellStyles((source) ? mxConstants.STYLE_EXIT_PERIMETER :
					mxConstants.STYLE_ENTRY_PERIMETER, null, [edge]);
			}
			else if (constraint.point != null)
			{
				this.setCellStyles((source) ? mxConstants.STYLE_EXIT_X :
					mxConstants.STYLE_ENTRY_X, constraint.point.x, [edge]);
				this.setCellStyles((source) ? mxConstants.STYLE_EXIT_Y :
					mxConstants.STYLE_ENTRY_Y, constraint.point.y, [edge]);
				
				// Only writes 0 since 1 is default
				if (!constraint.perimeter)
				{
					this.setCellStyles((source) ? mxConstants.STYLE_EXIT_PERIMETER :
						mxConstants.STYLE_ENTRY_PERIMETER, '0', [edge]);
				}
				else
				{
					this.setCellStyles((source) ? mxConstants.STYLE_EXIT_PERIMETER :
						mxConstants.STYLE_ENTRY_PERIMETER, null, [edge]);
				}
			}
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Function: getConnectionPoint
 *
 * Returns the nearest point in the list of absolute points or the center
 * of the opposite terminal.
 * 
 * Parameters:
 * 
 * vertex - <mxCellState> that represents the vertex.
 * constraint - <mxConnectionConstraint> that represents the connection point
 * constraint as returned by <getConnectionConstraint>.
 */
mxGraph.prototype.getConnectionPoint = function(vertex, constraint)
{
	var point = null;
	
	if (vertex != null && constraint.point != null)
	{
		var bounds = this.view.getPerimeterBounds(vertex);
        var cx = new mxPoint(bounds.getCenterX(), bounds.getCenterY());
		var direction = vertex.style[mxConstants.STYLE_DIRECTION];
		var r1 = 0;
		
		// Bounds need to be rotated by 90 degrees for further computation
		if (direction != null)
		{
			if (direction == mxConstants.DIRECTION_NORTH)
			{
				r1 += 270;
			}
			else if (direction == mxConstants.DIRECTION_WEST)
			{
				r1 += 180;
			}
			else if (direction == mxConstants.DIRECTION_SOUTH)
			{
				r1 += 90;
			}

			// Bounds need to be rotated by 90 degrees for further computation
			if (direction == mxConstants.DIRECTION_NORTH || direction == mxConstants.DIRECTION_SOUTH)
			{
				bounds.rotate90();
			}
		}

		point = new mxPoint(bounds.x + constraint.point.x * bounds.width,
				bounds.y + constraint.point.y * bounds.height);
		
		// Rotation for direction before projection on perimeter
		var r2 = vertex.style[mxConstants.STYLE_ROTATION] || 0;
		
		if (constraint.perimeter)
		{
			if (r1 != 0)
			{
				// Only 90 degrees steps possible here so no trig needed
				var cos = 0;
				var sin = 0;
				
				if (r1 == 90)
				{
					sin = 1;
				}
				else if (r1 == 180)
				{
					cos = -1;
				}
				else if (r1 == 270)
				{
					sin = -1;
				}
				
		        point = mxUtils.getRotatedPoint(point, cos, sin, cx);
			}
	
			point = this.view.getPerimeterPoint(vertex, point, false);
		}
		else
		{
			r2 += r1;
			
			if (this.getModel().isVertex(vertex.cell))
			{
				var flipH = vertex.style[mxConstants.STYLE_FLIPH] == 1;
				var flipV = vertex.style[mxConstants.STYLE_FLIPV] == 1;
				
				// Legacy support for stencilFlipH/V
				if (vertex.shape != null && vertex.shape.stencil != null)
				{
					flipH = (mxUtils.getValue(vertex.style, 'stencilFlipH', 0) == 1) || flipH;
					flipV = (mxUtils.getValue(vertex.style, 'stencilFlipV', 0) == 1) || flipV;
				}
				
				if (flipH)
				{
					point.x = 2 * bounds.getCenterX() - point.x;
				}
				
				if (flipV)
				{
					point.y = 2 * bounds.getCenterY() - point.y;
				}
			}
		}

		// Generic rotation after projection on perimeter
		if (r2 != 0 && point != null)
		{
	        var rad = mxUtils.toRadians(r2);
	        var cos = Math.cos(rad);
	        var sin = Math.sin(rad);
	        
	        point = mxUtils.getRotatedPoint(point, cos, sin, cx);
		}
	}
	
	if (point != null)
	{
		point.x = Math.round(point.x);
		point.y = Math.round(point.y);
	}

	return point;
};

/**
 * Function: connectCell
 * 
 * Connects the specified end of the given edge to the given terminal
 * using <cellConnected> and fires <mxEvent.CONNECT_CELL> while the
 * transaction is in progress. Returns the updated edge.
 * 
 * Parameters:
 * 
 * edge - <mxCell> whose terminal should be updated.
 * terminal - <mxCell> that represents the new terminal to be used.
 * source - Boolean indicating if the new terminal is the source or target.
 * constraint - Optional <mxConnectionConstraint> to be used for this
 * connection.
 */
mxGraph.prototype.connectCell = function(edge, terminal, source, constraint)
{
	this.model.beginUpdate();
	try
	{
		var previous = this.model.getTerminal(edge, source);
		this.cellConnected(edge, terminal, source, constraint);
		this.fireEvent(new mxEventObject(mxEvent.CONNECT_CELL,
			'edge', edge, 'terminal', terminal, 'source', source,
			'previous', previous));
	}
	finally
	{
		this.model.endUpdate();
	}

	return edge;
};

/**
 * Function: cellConnected
 * 
 * Sets the new terminal for the given edge and resets the edge points if
 * <resetEdgesOnConnect> is true. This method fires
 * <mxEvent.CELL_CONNECTED> while the transaction is in progress.
 * 
 * Parameters:
 * 
 * edge - <mxCell> whose terminal should be updated.
 * terminal - <mxCell> that represents the new terminal to be used.
 * source - Boolean indicating if the new terminal is the source or target.
 * constraint - <mxConnectionConstraint> to be used for this connection.
 */
mxGraph.prototype.cellConnected = function(edge, terminal, source, constraint)
{
	if (edge != null)
	{
		this.model.beginUpdate();
		try
		{
			var previous = this.model.getTerminal(edge, source);

			// Updates the constraint
			this.setConnectionConstraint(edge, terminal, source, constraint);
			
			// Checks if the new terminal is a port, uses the ID of the port in the
			// style and the parent of the port as the actual terminal of the edge.
			if (this.isPortsEnabled())
			{
				var id = null;
	
				if (this.isPort(terminal))
				{
					id = terminal.getId();
					terminal = this.getTerminalForPort(terminal, source);
				}
				
				// Sets or resets all previous information for connecting to a child port
				var key = (source) ? mxConstants.STYLE_SOURCE_PORT :
					mxConstants.STYLE_TARGET_PORT;
				this.setCellStyles(key, id, [edge]);
			}
			
			this.model.setTerminal(edge, terminal, source);
			
			if (this.resetEdgesOnConnect)
			{
				this.resetEdge(edge);
			}

			this.fireEvent(new mxEventObject(mxEvent.CELL_CONNECTED,
				'edge', edge, 'terminal', terminal, 'source', source,
				'previous', previous));
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Function: disconnectGraph
 * 
 * Disconnects the given edges from the terminals which are not in the
 * given array.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to be disconnected.
 */
mxGraph.prototype.disconnectGraph = function(cells)
{
	if (cells != null)
	{
		this.model.beginUpdate();
		try
		{							
			var scale = this.view.scale;
			var tr = this.view.translate;
			
			// Fast lookup for finding cells in array
			var dict = new mxDictionary();
			
			for (var i = 0; i < cells.length; i++)
			{
				dict.put(cells[i], true);
			}
			
			for (var i = 0; i < cells.length; i++)
			{
				if (this.model.isEdge(cells[i]))
				{
					var geo = this.model.getGeometry(cells[i]);
					
					if (geo != null)
					{
						var state = this.view.getState(cells[i]);
						var pstate = this.view.getState(
							this.model.getParent(cells[i]));
						
						if (state != null &&
							pstate != null)
						{
							geo = geo.clone();
							
							var dx = -pstate.origin.x;
							var dy = -pstate.origin.y;
							var pts = state.absolutePoints;

							var src = this.model.getTerminal(cells[i], true);
							
							if (src != null && this.isCellDisconnectable(cells[i], src, true))
							{
								while (src != null && !dict.get(src))
								{
									src = this.model.getParent(src);
								}
								
								if (src == null)
								{
									geo.setTerminalPoint(
										new mxPoint(pts[0].x / scale - tr.x + dx,
											pts[0].y / scale - tr.y + dy), true);
									this.model.setTerminal(cells[i], null, true);
								}
							}
							
							var trg = this.model.getTerminal(cells[i], false);
							
							if (trg != null && this.isCellDisconnectable(cells[i], trg, false))
							{
								while (trg != null && !dict.get(trg))
								{
									trg = this.model.getParent(trg);
								}
								
								if (trg == null)
								{
									var n = pts.length - 1;
									geo.setTerminalPoint(
										new mxPoint(pts[n].x / scale - tr.x + dx,
											pts[n].y / scale - tr.y + dy), false);
									this.model.setTerminal(cells[i], null, false);
								}
							}

							this.model.setGeometry(cells[i], geo);
						}
					}
				}
			}
		}
		finally
		{
			this.model.endUpdate();
		}
	}
};

/**
 * Group: Drilldown
 */

/**
 * Function: getCurrentRoot
 * 
 * Returns the current root of the displayed cell hierarchy. This is a
 * shortcut to <mxGraphView.currentRoot> in <view>.
 */
mxGraph.prototype.getCurrentRoot = function()
{
	return this.view.currentRoot;
};
 
/**
 * Function: getTranslateForRoot
 * 
 * Returns the translation to be used if the given cell is the root cell as
 * an <mxPoint>. This implementation returns null.
 * 
 * Example:
 * 
 * To keep the children at their absolute position while stepping into groups,
 * this function can be overridden as follows.
 * 
 * (code)
 * var offset = new mxPoint(0, 0);
 * 
 * while (cell != null)
 * {
 *   var geo = this.model.getGeometry(cell);
 * 
 *   if (geo != null)
 *   {
 *     offset.x -= geo.x;
 *     offset.y -= geo.y;
 *   }
 * 
 *   cell = this.model.getParent(cell);
 * }
 * 
 * return offset;
 * (end)
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents the root.
 */
mxGraph.prototype.getTranslateForRoot = function(cell)
{
	return null;
};

/**
 * Function: isPort
 * 
 * Returns true if the given cell is a "port", that is, when connecting to
 * it, the cell returned by getTerminalForPort should be used as the
 * terminal and the port should be referenced by the ID in either the
 * mxConstants.STYLE_SOURCE_PORT or the or the
 * mxConstants.STYLE_TARGET_PORT. Note that a port should not be movable.
 * This implementation always returns false.
 * 
 * A typical implementation is the following:
 * 
 * (code)
 * graph.isPort = function(cell)
 * {
 *   var geo = this.getCellGeometry(cell);
 *   
 *   return (geo != null) ? geo.relative : false;
 * };
 * (end)
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents the port.
 */
mxGraph.prototype.isPort = function(cell)
{
	return false;
};

/**
 * Function: getTerminalForPort
 * 
 * Returns the terminal to be used for a given port. This implementation
 * always returns the parent cell.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents the port.
 * source - If the cell is the source or target port.
 */
mxGraph.prototype.getTerminalForPort = function(cell, source)
{
	return this.model.getParent(cell);
};

/**
 * Function: getChildOffsetForCell
 * 
 * Returns the offset to be used for the cells inside the given cell. The
 * root and layer cells may be identified using <mxGraphModel.isRoot> and
 * <mxGraphModel.isLayer>. For all other current roots, the
 * <mxGraphView.currentRoot> field points to the respective cell, so that
 * the following holds: cell == this.view.currentRoot. This implementation
 * returns null.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose offset should be returned.
 */
mxGraph.prototype.getChildOffsetForCell = function(cell)
{
	return null;
};

/**
 * Function: enterGroup
 * 
 * Uses the given cell as the root of the displayed cell hierarchy. If no
 * cell is specified then the selection cell is used. The cell is only used
 * if <isValidRoot> returns true.
 * 
 * Parameters:
 * 
 * cell - Optional <mxCell> to be used as the new root. Default is the
 * selection cell.
 */
mxGraph.prototype.enterGroup = function(cell)
{
	cell = cell || this.getSelectionCell();
	
	if (cell != null && this.isValidRoot(cell))
	{
		this.view.setCurrentRoot(cell);
		this.clearSelection();
	}
};

/**
 * Function: exitGroup
 * 
 * Changes the current root to the next valid root in the displayed cell
 * hierarchy.
 */
mxGraph.prototype.exitGroup = function()
{
	var root = this.model.getRoot();
	var current = this.getCurrentRoot();
	
	if (current != null)
	{
		var next = this.model.getParent(current);
		
		// Finds the next valid root in the hierarchy
		while (next != root && !this.isValidRoot(next) &&
				this.model.getParent(next) != root)
		{
			next = this.model.getParent(next);
		}
		
		// Clears the current root if the new root is
		// the model's root or one of the layers.
		if (next == root || this.model.getParent(next) == root)
		{
			this.view.setCurrentRoot(null);
		}
		else
		{
			this.view.setCurrentRoot(next);
		}
		
		var state = this.view.getState(current);
		
		// Selects the previous root in the graph
		if (state != null)
		{
			this.setSelectionCell(current);
		}
	}
};

/**
 * Function: home
 * 
 * Uses the root of the model as the root of the displayed cell hierarchy
 * and selects the previous root.
 */
mxGraph.prototype.home = function()
{
	var current = this.getCurrentRoot();
	
	if (current != null)
	{
		this.view.setCurrentRoot(null);
		var state = this.view.getState(current);
		
		if (state != null)
		{
			this.setSelectionCell(current);
		}
	}
};

/**
 * Function: isValidRoot
 * 
 * Returns true if the given cell is a valid root for the cell display
 * hierarchy. This implementation returns true for all non-null values.
 * 
 * Parameters:
 * 
 * cell - <mxCell> which should be checked as a possible root.
 */
mxGraph.prototype.isValidRoot = function(cell)
{
	return (cell != null);
};

/**
 * Group: Graph display
 */
 
/**
 * Function: getGraphBounds
 * 
 * Returns the bounds of the visible graph. Shortcut to
 * <mxGraphView.getGraphBounds>. See also: <getBoundingBoxFromGeometry>.
 */
 mxGraph.prototype.getGraphBounds = function()
 {
 	return this.view.getGraphBounds();
 };

/**
 * Function: getCellBounds
 * 
 * Returns the scaled, translated bounds for the given cell. See
 * <mxGraphView.getBounds> for arrays.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose bounds should be returned.
 * includeEdge - Optional boolean that specifies if the bounds of
 * the connected edges should be included. Default is false.
 * includeDescendants - Optional boolean that specifies if the bounds
 * of all descendants should be included. Default is false.
 */
mxGraph.prototype.getCellBounds = function(cell, includeEdges, includeDescendants)
{
	var cells = [cell];
	
	// Includes all connected edges
	if (includeEdges)
	{
		cells = cells.concat(this.model.getEdges(cell));
	}
	
	var result = this.view.getBounds(cells);
	
	// Recursively includes the bounds of the children
	if (includeDescendants)
	{
		var childCount = this.model.getChildCount(cell);
		
		for (var i = 0; i < childCount; i++)
		{
			var tmp = this.getCellBounds(this.model.getChildAt(cell, i),
				includeEdges, true);

			if (result != null)
			{
				result.add(tmp);
			}
			else
			{
				result = tmp;
			}
		}
	}
	
	return result;
};

/**
 * Function: getBoundingBoxFromGeometry
 * 
 * Returns the bounding box for the geometries of the vertices in the
 * given array of cells. This can be used to find the graph bounds during
 * a layout operation (ie. before the last endUpdate) as follows:
 * 
 * (code)
 * var cells = graph.getChildCells(graph.getDefaultParent(), true, true);
 * var bounds = graph.getBoundingBoxFromGeometry(cells, true);
 * (end)
 * 
 * This can then be used to move cells to the origin:
 * 
 * (code)
 * if (bounds.x < 0 || bounds.y < 0)
 * {
 *   graph.moveCells(cells, -Math.min(bounds.x, 0), -Math.min(bounds.y, 0))
 * }
 * (end)
 * 
 * Or to translate the graph view:
 * 
 * (code)
 * if (bounds.x < 0 || bounds.y < 0)
 * {
 *   graph.view.setTranslate(-Math.min(bounds.x, 0), -Math.min(bounds.y, 0));
 * }
 * (end)
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> whose bounds should be returned.
 * includeEdges - Specifies if edge bounds should be included by computing
 * the bounding box for all points in geometry. Default is false.
 */
mxGraph.prototype.getBoundingBoxFromGeometry = function(cells, includeEdges)
{
	includeEdges = (includeEdges != null) ? includeEdges : false;
	var result = null;
	
	if (cells != null)
	{
		for (var i = 0; i < cells.length; i++)
		{
			if (includeEdges || this.model.isVertex(cells[i]))
			{
				// Computes the bounding box for the points in the geometry
				var geo = this.getCellGeometry(cells[i]);
				
				if (geo != null)
				{
					var bbox = null;
					
					if (this.model.isEdge(cells[i]))
					{
						var addPoint = function(pt)
						{
							if (pt != null)
							{
								if (tmp == null)
								{
									tmp = new mxRectangle(pt.x, pt.y, 0, 0);
								}
								else
								{
									tmp.add(new mxRectangle(pt.x, pt.y, 0, 0));
								}
							}
						};
						
						if (this.model.getTerminal(cells[i], true) == null)
						{
							addPoint(geo.getTerminalPoint(true));
						}
						
						if (this.model.getTerminal(cells[i], false) == null)
						{
							addPoint(geo.getTerminalPoint(false));
						}
												
						var pts = geo.points;
						
						if (pts != null && pts.length > 0)
						{
							var tmp = new mxRectangle(pts[0].x, pts[0].y, 0, 0);

							for (var j = 1; j < pts.length; j++)
							{
								addPoint(pts[j]);
							}
						}
						
						bbox = tmp;
					}
					else
					{
						var parent = this.model.getParent(cells[i]);
						
						if (geo.relative)
						{
							if (this.model.isVertex(parent) && parent != this.view.currentRoot)
							{
								var tmp = this.getBoundingBoxFromGeometry([parent], false);
								
								if (tmp != null)
								{
									bbox = new mxRectangle(geo.x * tmp.width, geo.y * tmp.height, geo.width, geo.height);
									
									if (mxUtils.indexOf(cells, parent) >= 0)
									{
										bbox.x += tmp.x;
										bbox.y += tmp.y;
									}
								}
							}
						}
						else
						{
							bbox = mxRectangle.fromRectangle(geo);
							
							if (this.model.isVertex(parent) && mxUtils.indexOf(cells, parent) >= 0)
							{
								var tmp = this.getBoundingBoxFromGeometry([parent], false);

								if (tmp != null)
								{
									bbox.x += tmp.x;
									bbox.y += tmp.y;
								}
							}
						}
						
						if (bbox != null && geo.offset != null)
						{
							bbox.x += geo.offset.x;
							bbox.y += geo.offset.y;
						}
					}
					
					if (bbox != null)
					{
						if (result == null)
						{
							result = mxRectangle.fromRectangle(bbox);
						}
						else
						{
							result.add(bbox);
						}
					}
				}
			}
		}
	}
	
	return result;
};

/**
 * Function: refresh
 * 
 * Clears all cell states or the states for the hierarchy starting at the
 * given cell and validates the graph. This fires a refresh event as the
 * last step.
 * 
 * Parameters:
 * 
 * cell - Optional <mxCell> for which the cell states should be cleared.
 */
mxGraph.prototype.refresh = function(cell)
{
	this.view.clear(cell, cell == null);
	this.view.validate();
	this.sizeDidChange();
	this.fireEvent(new mxEventObject(mxEvent.REFRESH));
};

/**
 * Function: snap
 * 
 * Snaps the given numeric value to the grid if <gridEnabled> is true.
 * 
 * Parameters:
 * 
 * value - Numeric value to be snapped to the grid.
 */
mxGraph.prototype.snap = function(value)
{
	if (this.gridEnabled)
	{
		value = Math.round(value / this.gridSize ) * this.gridSize;
	}
	
	return value;
};

/**
 * Function: panGraph
 * 
 * Shifts the graph display by the given amount. This is used to preview
 * panning operations, use <mxGraphView.setTranslate> to set a persistent
 * translation of the view. Fires <mxEvent.PAN>.
 * 
 * Parameters:
 * 
 * dx - Amount to shift the graph along the x-axis.
 * dy - Amount to shift the graph along the y-axis.
 */
mxGraph.prototype.panGraph = function(dx, dy)
{
	if (this.useScrollbarsForPanning && mxUtils.hasScrollbars(this.container))
	{
		this.container.scrollLeft = -dx;
		this.container.scrollTop = -dy;
	}
	else
	{
		var canvas = this.view.getCanvas();
		
		if (this.dialect == mxConstants.DIALECT_SVG)
		{
			// Puts everything inside the container in a DIV so that it
			// can be moved without changing the state of the container
			if (dx == 0 && dy == 0)
			{
				// Workaround for ignored removeAttribute on SVG element in IE9 standards
				if (mxClient.IS_IE)
				{
					canvas.setAttribute('transform', 'translate(' + dx + ',' + dy + ')');
				}
				else
				{
					canvas.removeAttribute('transform');
				}
				
				if (this.shiftPreview1 != null)
				{
					var child = this.shiftPreview1.firstChild;
					
					while (child != null)
					{
						var next = child.nextSibling;
						this.container.appendChild(child);
						child = next;
					}

					if (this.shiftPreview1.parentNode != null)
					{
						this.shiftPreview1.parentNode.removeChild(this.shiftPreview1);
					}
					
					this.shiftPreview1 = null;
					
					this.container.appendChild(canvas.parentNode);
					
					child = this.shiftPreview2.firstChild;
					
					while (child != null)
					{
						var next = child.nextSibling;
						this.container.appendChild(child);
						child = next;
					}

					if (this.shiftPreview2.parentNode != null)
					{
						this.shiftPreview2.parentNode.removeChild(this.shiftPreview2);
					}
					
					this.shiftPreview2 = null;
				}
			}
			else
			{
				canvas.setAttribute('transform', 'translate(' + dx + ',' + dy + ')');
				
				if (this.shiftPreview1 == null)
				{
					// Needs two divs for stuff before and after the SVG element
					this.shiftPreview1 = document.createElement('div');
					this.shiftPreview1.style.position = 'absolute';
					this.shiftPreview1.style.overflow = 'visible';
					
					this.shiftPreview2 = document.createElement('div');
					this.shiftPreview2.style.position = 'absolute';
					this.shiftPreview2.style.overflow = 'visible';

					var current = this.shiftPreview1;
					var child = this.container.firstChild;
					
					while (child != null)
					{
						var next = child.nextSibling;
						
						// SVG element is moved via transform attribute
						if (child != canvas.parentNode)
						{
							current.appendChild(child);
						}
						else
						{
							current = this.shiftPreview2;
						}
						
						child = next;
					}
					
					// Inserts elements only if not empty
					if (this.shiftPreview1.firstChild != null)
					{
						this.container.insertBefore(this.shiftPreview1, canvas.parentNode);
					}
					
					if (this.shiftPreview2.firstChild != null)
					{
						this.container.appendChild(this.shiftPreview2);
					}
				}
				
				this.shiftPreview1.style.left = dx + 'px';
				this.shiftPreview1.style.top = dy + 'px';
				this.shiftPreview2.style.left = dx + 'px';
				this.shiftPreview2.style.top = dy + 'px';
			}
		}
		else
		{
			canvas.style.left = dx + 'px';
			canvas.style.top = dy + 'px';
		}
		
		this.panDx = dx;
		this.panDy = dy;

		this.fireEvent(new mxEventObject(mxEvent.PAN));
	}
};

/**
 * Function: zoomIn
 * 
 * Zooms into the graph by <zoomFactor>.
 */
mxGraph.prototype.zoomIn = function()
{
	this.zoom(this.zoomFactor);
};

/**
 * Function: zoomOut
 * 
 * Zooms out of the graph by <zoomFactor>.
 */
mxGraph.prototype.zoomOut = function()
{
	this.zoom(1 / this.zoomFactor);
};

/**
 * Function: zoomActual
 * 
 * Resets the zoom and panning in the view.
 */
mxGraph.prototype.zoomActual = function()
{
	if (this.view.scale == 1)
	{
		this.view.setTranslate(0, 0);
	}
	else
	{
		this.view.translate.x = 0;
		this.view.translate.y = 0;

		this.view.setScale(1);
	}
};

/**
 * Function: zoomTo
 * 
 * Zooms the graph to the given scale with an optional boolean center
 * argument, which is passd to <zoom>.
 */
mxGraph.prototype.zoomTo = function(scale, center)
{
	this.zoom(scale / this.view.scale, center);
};

/**
 * Function: center
 * 
 * Centers the graph in the container.
 * 
 * Parameters:
 * 
 * horizontal - Optional boolean that specifies if the graph should be centered
 * horizontally. Default is true.
 * vertical - Optional boolean that specifies if the graph should be centered
 * vertically. Default is true.
 * cx - Optional float that specifies the horizontal center. Default is 0.5.
 * cy - Optional float that specifies the vertical center. Default is 0.5.
 */
mxGraph.prototype.center = function(horizontal, vertical, cx, cy)
{
	horizontal = (horizontal != null) ? horizontal : true;
	vertical = (vertical != null) ? vertical : true;
	cx = (cx != null) ? cx : 0.5;
	cy = (cy != null) ? cy : 0.5;
	
	var hasScrollbars = mxUtils.hasScrollbars(this.container);
	var cw = this.container.clientWidth;
	var ch = this.container.clientHeight;
	var bounds = this.getGraphBounds();

	var t = this.view.translate;
	var s = this.view.scale;

	var dx = (horizontal) ? cw - bounds.width : 0;
	var dy = (vertical) ? ch - bounds.height : 0;
	
	if (!hasScrollbars)
	{
		this.view.setTranslate((horizontal) ? Math.floor(t.x - bounds.x * s + dx * cx / s) : t.x,
			(vertical) ? Math.floor(t.y - bounds.y * s + dy * cy / s) : t.y);
	}
	else
	{
		bounds.x -= t.x;
		bounds.y -= t.y;
	
		var sw = this.container.scrollWidth;
		var sh = this.container.scrollHeight;
		
		if (sw > cw)
		{
			dx = 0;
		}
		
		if (sh > ch)
		{
			dy = 0;
		}

		this.view.setTranslate(Math.floor(dx / 2 - bounds.x), Math.floor(dy / 2 - bounds.y));
		this.container.scrollLeft = (sw - cw) / 2;
		this.container.scrollTop = (sh - ch) / 2;
	}
};

/**
 * Function: zoom
 * 
 * Zooms the graph using the given factor. Center is an optional boolean
 * argument that keeps the graph scrolled to the center. If the center argument
 * is omitted, then <centerZoom> will be used as its value.
 */
mxGraph.prototype.zoom = function(factor, center)
{
	center = (center != null) ? center : this.centerZoom;
	var scale = Math.round(this.view.scale * factor * 100) / 100;
	var state = this.view.getState(this.getSelectionCell());
	factor = scale / this.view.scale;
	
	if (this.keepSelectionVisibleOnZoom && state != null)
	{
		var rect = new mxRectangle(state.x * factor, state.y * factor,
			state.width * factor, state.height * factor);
		
		// Refreshes the display only once if a scroll is carried out
		this.view.scale = scale;
		
		if (!this.scrollRectToVisible(rect))
		{
			this.view.revalidate();
			
			// Forces an event to be fired but does not revalidate again
			this.view.setScale(scale);
		}
	}
	else
	{
		var hasScrollbars = mxUtils.hasScrollbars(this.container);
		
		if (center && !hasScrollbars)
		{
			var dx = this.container.offsetWidth;
			var dy = this.container.offsetHeight;
			
			if (factor > 1)
			{
				var f = (factor - 1) / (scale * 2);
				dx *= -f;
				dy *= -f;
			}
			else
			{
				var f = (1 / factor - 1) / (this.view.scale * 2);
				dx *= f;
				dy *= f;
			}

			this.view.scaleAndTranslate(scale,
				this.view.translate.x + dx,
				this.view.translate.y + dy);
		}
		else
		{
			// Allows for changes of translate and scrollbars during setscale
			var tx = this.view.translate.x;
			var ty = this.view.translate.y;
			var sl = this.container.scrollLeft;
			var st = this.container.scrollTop;
			
			this.view.setScale(scale);
			
			if (hasScrollbars)
			{
				var dx = 0;
				var dy = 0;
				
				if (center)
				{
					dx = this.container.offsetWidth * (factor - 1) / 2;
					dy = this.container.offsetHeight * (factor - 1) / 2;
				}
				
				this.container.scrollLeft = (this.view.translate.x - tx) * this.view.scale + Math.round(sl * factor + dx);
				this.container.scrollTop = (this.view.translate.y - ty) * this.view.scale + Math.round(st * factor + dy);
			}
		}
	}
};

/**
 * Function: zoomToRect
 * 
 * Zooms the graph to the specified rectangle. If the rectangle does not have same aspect
 * ratio as the display container, it is increased in the smaller relative dimension only
 * until the aspect match. The original rectangle is centralised within this expanded one.
 * 
 * Note that the input rectangular must be un-scaled and un-translated.
 * 
 * Parameters:
 * 
 * rect - The un-scaled and un-translated rectangluar region that should be just visible 
 * after the operation
 */
mxGraph.prototype.zoomToRect = function(rect)
{
	var scaleX = this.container.clientWidth / rect.width;
	var scaleY = this.container.clientHeight / rect.height;
	var aspectFactor = scaleX / scaleY;

	// Remove any overlap of the rect outside the client area
	rect.x = Math.max(0, rect.x);
	rect.y = Math.max(0, rect.y);
	var rectRight = Math.min(this.container.scrollWidth, rect.x + rect.width);
	var rectBottom = Math.min(this.container.scrollHeight, rect.y + rect.height);
	rect.width = rectRight - rect.x;
	rect.height = rectBottom - rect.y;

	// The selection area has to be increased to the same aspect
	// ratio as the container, centred around the centre point of the 
	// original rect passed in.
	if (aspectFactor < 1.0)
	{
		// Height needs increasing
		var newHeight = rect.height / aspectFactor;
		var deltaHeightBuffer = (newHeight - rect.height) / 2.0;
		rect.height = newHeight;
		
		// Assign up to half the buffer to the upper part of the rect, not crossing 0
		// put the rest on the bottom
		var upperBuffer = Math.min(rect.y , deltaHeightBuffer);
		rect.y = rect.y - upperBuffer;
		
		// Check if the bottom has extended too far
		rectBottom = Math.min(this.container.scrollHeight, rect.y + rect.height);
		rect.height = rectBottom - rect.y;
	}
	else
	{
		// Width needs increasing
		var newWidth = rect.width * aspectFactor;
		var deltaWidthBuffer = (newWidth - rect.width) / 2.0;
		rect.width = newWidth;
		
		// Assign up to half the buffer to the upper part of the rect, not crossing 0
		// put the rest on the bottom
		var leftBuffer = Math.min(rect.x , deltaWidthBuffer);
		rect.x = rect.x - leftBuffer;
		
		// Check if the right hand side has extended too far
		rectRight = Math.min(this.container.scrollWidth, rect.x + rect.width);
		rect.width = rectRight - rect.x;
	}

	var scale = this.container.clientWidth / rect.width;
	var newScale = this.view.scale * scale;

	if (!mxUtils.hasScrollbars(this.container))
	{
		this.view.scaleAndTranslate(newScale, (this.view.translate.x - rect.x / this.view.scale), (this.view.translate.y - rect.y / this.view.scale));
	}
	else
	{
		this.view.setScale(newScale);
		this.container.scrollLeft = Math.round(rect.x * scale);
		this.container.scrollTop = Math.round(rect.y * scale);
	}
};

/**
 * Function: scrollCellToVisible
 * 
 * Pans the graph so that it shows the given cell. Optionally the cell may
 * be centered in the container.
 * 
 * To center a given graph if the <container> has no scrollbars, use the following code.
 * 
 * [code]
 * var bounds = graph.getGraphBounds();
 * graph.view.setTranslate(-bounds.x - (bounds.width - container.clientWidth) / 2,
 * 						   -bounds.y - (bounds.height - container.clientHeight) / 2);
 * [/code]
 * 
 * Parameters:
 * 
 * cell - <mxCell> to be made visible.
 * center - Optional boolean flag. Default is false.
 */
mxGraph.prototype.scrollCellToVisible = function(cell, center)
{
	var x = -this.view.translate.x;
	var y = -this.view.translate.y;

	var state = this.view.getState(cell);

	if (state != null)
	{
		var bounds = new mxRectangle(x + state.x, y + state.y, state.width,
			state.height);

		if (center && this.container != null)
		{
			var w = this.container.clientWidth;
			var h = this.container.clientHeight;

			bounds.x = bounds.getCenterX() - w / 2;
			bounds.width = w;
			bounds.y = bounds.getCenterY() - h / 2;
			bounds.height = h;
		}
		
		var tr = new mxPoint(this.view.translate.x, this.view.translate.y);

		if (this.scrollRectToVisible(bounds))
		{
			// Triggers an update via the view's event source
			var tr2 = new mxPoint(this.view.translate.x, this.view.translate.y);
			this.view.translate.x = tr.x;
			this.view.translate.y = tr.y;
			this.view.setTranslate(tr2.x, tr2.y);
		}
	}
};

/**
 * Function: scrollRectToVisible
 * 
 * Pans the graph so that it shows the given rectangle.
 * 
 * Parameters:
 * 
 * rect - <mxRectangle> to be made visible.
 */
mxGraph.prototype.scrollRectToVisible = function(rect)
{
	var isChanged = false;
	
	if (rect != null)
	{
		var w = this.container.offsetWidth;
		var h = this.container.offsetHeight;

        var widthLimit = Math.min(w, rect.width);
        var heightLimit = Math.min(h, rect.height);

		if (mxUtils.hasScrollbars(this.container))
		{
			var c = this.container;
			rect.x += this.view.translate.x;
			rect.y += this.view.translate.y;
			var dx = c.scrollLeft - rect.x;
			var ddx = Math.max(dx - c.scrollLeft, 0);

			if (dx > 0)
			{
				c.scrollLeft -= dx + 2;
			}
			else
			{
				dx = rect.x + widthLimit - c.scrollLeft - c.clientWidth;

				if (dx > 0)
				{
					c.scrollLeft += dx + 2;
				}
			}

			var dy = c.scrollTop - rect.y;
			var ddy = Math.max(0, dy - c.scrollTop);

			if (dy > 0)
			{
				c.scrollTop -= dy + 2;
			}
			else
			{
				dy = rect.y + heightLimit - c.scrollTop - c.clientHeight;

				if (dy > 0)
				{
					c.scrollTop += dy + 2;
				}
			}

			if (!this.useScrollbarsForPanning && (ddx != 0 || ddy != 0))
			{
				this.view.setTranslate(ddx, ddy);
			}
		}
		else
		{
			var x = -this.view.translate.x;
			var y = -this.view.translate.y;

			var s = this.view.scale;

			if (rect.x + widthLimit > x + w)
			{
				this.view.translate.x -= (rect.x + widthLimit - w - x) / s;
				isChanged = true;
			}

			if (rect.y + heightLimit > y + h)
			{
				this.view.translate.y -= (rect.y + heightLimit - h - y) / s;
				isChanged = true;
			}

			if (rect.x < x)
			{
				this.view.translate.x += (x - rect.x) / s;
				isChanged = true;
			}

			if (rect.y  < y)
			{
				this.view.translate.y += (y - rect.y) / s;
				isChanged = true;
			}

			if (isChanged)
			{
				this.view.refresh();
				
				// Repaints selection marker (ticket 18)
				if (this.selectionCellsHandler != null)
				{
					this.selectionCellsHandler.refresh();
				}
			}
		}
	}

	return isChanged;
};

/**
 * Function: getCellGeometry
 * 
 * Returns the <mxGeometry> for the given cell. This implementation uses
 * <mxGraphModel.getGeometry>. Subclasses can override this to implement
 * specific geometries for cells in only one graph, that is, it can return
 * geometries that depend on the current state of the view.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose geometry should be returned.
 */
mxGraph.prototype.getCellGeometry = function(cell)
{
	return this.model.getGeometry(cell);
};

/**
 * Function: isCellVisible
 * 
 * Returns true if the given cell is visible in this graph. This
 * implementation uses <mxGraphModel.isVisible>. Subclassers can override
 * this to implement specific visibility for cells in only one graph, that
 * is, without affecting the visible state of the cell.
 * 
 * When using dynamic filter expressions for cell visibility, then the
 * graph should be revalidated after the filter expression has changed.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose visible state should be returned.
 */
mxGraph.prototype.isCellVisible = function(cell)
{
	return this.model.isVisible(cell);
};

/**
 * Function: isCellCollapsed
 * 
 * Returns true if the given cell is collapsed in this graph. This
 * implementation uses <mxGraphModel.isCollapsed>. Subclassers can override
 * this to implement specific collapsed states for cells in only one graph,
 * that is, without affecting the collapsed state of the cell.
 * 
 * When using dynamic filter expressions for the collapsed state, then the
 * graph should be revalidated after the filter expression has changed.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose collapsed state should be returned.
 */
mxGraph.prototype.isCellCollapsed = function(cell)
{
	return this.model.isCollapsed(cell);
};

/**
 * Function: isCellConnectable
 * 
 * Returns true if the given cell is connectable in this graph. This
 * implementation uses <mxGraphModel.isConnectable>. Subclassers can override
 * this to implement specific connectable states for cells in only one graph,
 * that is, without affecting the connectable state of the cell in the model.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose connectable state should be returned.
 */
mxGraph.prototype.isCellConnectable = function(cell)
{
	return this.model.isConnectable(cell);
};

/**
 * Function: isOrthogonal
 * 
 * Returns true if perimeter points should be computed such that the
 * resulting edge has only horizontal or vertical segments.
 * 
 * Parameters:
 * 
 * edge - <mxCellState> that represents the edge.
 */
mxGraph.prototype.isOrthogonal = function(edge)
{
	var orthogonal = edge.style[mxConstants.STYLE_ORTHOGONAL];
	
	if (orthogonal != null)
	{
		return orthogonal;
	}
	
	var tmp = this.view.getEdgeStyle(edge);
	
	return tmp == mxEdgeStyle.SegmentConnector ||
		tmp == mxEdgeStyle.ElbowConnector ||
		tmp == mxEdgeStyle.SideToSide ||
		tmp == mxEdgeStyle.TopToBottom ||
		tmp == mxEdgeStyle.EntityRelation ||
		tmp == mxEdgeStyle.OrthConnector;
};

/**
 * Function: isLoop
 * 
 * Returns true if the given cell state is a loop.
 * 
 * Parameters:
 * 
 * state - <mxCellState> that represents a potential loop.
 */
mxGraph.prototype.isLoop = function(state)
{
	var src = state.getVisibleTerminalState(true);
	var trg = state.getVisibleTerminalState(false);
	
	return (src != null && src == trg);
};

/**
 * Function: isCloneEvent
 * 
 * Returns true if the given event is a clone event. This implementation
 * returns true if control is pressed.
 */
mxGraph.prototype.isCloneEvent = function(evt)
{
	return mxEvent.isControlDown(evt);
};

/**
 * Function: isTransparentClickEvent
 * 
 * Hook for implementing click-through behaviour on selected cells. If this
 * returns true the cell behind the selected cell will be selected. This
 * implementation returns false;
 */
mxGraph.prototype.isTransparentClickEvent = function(evt)
{
	return false;
};

/**
 * Function: isToggleEvent
 * 
 * Returns true if the given event is a toggle event. This implementation
 * returns true if the meta key (Cmd) is pressed on Macs or if control is
 * pressed on any other platform.
 */
mxGraph.prototype.isToggleEvent = function(evt)
{
	return (mxClient.IS_MAC) ? mxEvent.isMetaDown(evt) : mxEvent.isControlDown(evt);
};

/**
 * Function: isGridEnabledEvent
 * 
 * Returns true if the given mouse event should be aligned to the grid.
 */
mxGraph.prototype.isGridEnabledEvent = function(evt)
{
	return evt != null && !mxEvent.isAltDown(evt);
};

/**
 * Function: isConstrainedEvent
 * 
 * Returns true if the given mouse event should be aligned to the grid.
 */
mxGraph.prototype.isConstrainedEvent = function(evt)
{
	return mxEvent.isShiftDown(evt);
};

/**
 * Function: isIgnoreTerminalEvent
 * 
 * Returns true if the given mouse event should not allow any connections to be
 * made. This implementation returns false.
 */
mxGraph.prototype.isIgnoreTerminalEvent = function(evt)
{
	return false;
};

/**
 * Group: Validation
 */

/**
 * Function: validationAlert
 * 
 * Displays the given validation error in a dialog. This implementation uses
 * mxUtils.alert.
 */
mxGraph.prototype.validationAlert = function(message)
{
	mxUtils.alert(message);
};

/**
 * Function: isEdgeValid
 * 
 * Checks if the return value of <getEdgeValidationError> for the given
 * arguments is null.
 *  
 * Parameters:
 * 
 * edge - <mxCell> that represents the edge to validate.
 * source - <mxCell> that represents the source terminal.
 * target - <mxCell> that represents the target terminal.
 */
mxGraph.prototype.isEdgeValid = function(edge, source, target)
{
	return this.getEdgeValidationError(edge, source, target) == null;
};

/**
 * Function: getEdgeValidationError
 * 
 * Returns the validation error message to be displayed when inserting or
 * changing an edges' connectivity. A return value of null means the edge
 * is valid, a return value of '' means it's not valid, but do not display
 * an error message. Any other (non-empty) string returned from this method
 * is displayed as an error message when trying to connect an edge to a
 * source and target. This implementation uses the <multiplicities>, and
 * checks <multigraph>, <allowDanglingEdges> and <allowLoops> to generate
 * validation errors.
 * 
 * For extending this method with specific checks for source/target cells,
 * the method can be extended as follows. Returning an empty string means
 * the edge is invalid with no error message, a non-null string specifies
 * the error message, and null means the edge is valid.
 * 
 * (code)
 * graph.getEdgeValidationError = function(edge, source, target)
 * {
 *   if (source != null && target != null &&
 *     this.model.getValue(source) != null &&
 *     this.model.getValue(target) != null)
 *   {
 *     if (target is not valid for source)
 *     {
 *       return 'Invalid Target';
 *     }
 *   }
 *   
 *   // "Supercall"
 *   return mxGraph.prototype.getEdgeValidationError.apply(this, arguments);
 * }
 * (end)
 *  
 * Parameters:
 * 
 * edge - <mxCell> that represents the edge to validate.
 * source - <mxCell> that represents the source terminal.
 * target - <mxCell> that represents the target terminal.
 */
mxGraph.prototype.getEdgeValidationError = function(edge, source, target)
{
	if (edge != null && !this.isAllowDanglingEdges() && (source == null || target == null))
	{
		return '';
	}
	
	if (edge != null && this.model.getTerminal(edge, true) == null &&
		this.model.getTerminal(edge, false) == null)	
	{
		return null;
	}
	
	// Checks if we're dealing with a loop
	if (!this.allowLoops && source == target && source != null)
	{
		return '';
	}
	
	// Checks if the connection is generally allowed
	if (!this.isValidConnection(source, target))
	{
		return '';
	}

	if (source != null && target != null)
	{
		var error = '';

		// Checks if the cells are already connected
		// and adds an error message if required			
		if (!this.multigraph)
		{
			var tmp = this.model.getEdgesBetween(source, target, true);
			
			// Checks if the source and target are not connected by another edge
			if (tmp.length > 1 || (tmp.length == 1 && tmp[0] != edge))
			{
				error += (mxResources.get(this.alreadyConnectedResource) ||
					this.alreadyConnectedResource)+'\n';
			}
		}

		// Gets the number of outgoing edges from the source
		// and the number of incoming edges from the target
		// without counting the edge being currently changed.
		var sourceOut = this.model.getDirectedEdgeCount(source, true, edge);
		var targetIn = this.model.getDirectedEdgeCount(target, false, edge);

		// Checks the change against each multiplicity rule
		if (this.multiplicities != null)
		{
			for (var i = 0; i < this.multiplicities.length; i++)
			{
				var err = this.multiplicities[i].check(this, edge, source,
					target, sourceOut, targetIn);
				
				if (err != null)
				{
					error += err;
				}
			}
		}

		// Validates the source and target terminals independently
		var err = this.validateEdge(edge, source, target);
		
		if (err != null)
		{
			error += err;
		}
		
		return (error.length > 0) ? error : null;
	}
	
	return (this.allowDanglingEdges) ? null : '';
};

/**
 * Function: validateEdge
 * 
 * Hook method for subclassers to return an error message for the given
 * edge and terminals. This implementation returns null.
 * 
 * Parameters:
 * 
 * edge - <mxCell> that represents the edge to validate.
 * source - <mxCell> that represents the source terminal.
 * target - <mxCell> that represents the target terminal.
 */
mxGraph.prototype.validateEdge = function(edge, source, target)
{
	return null;
};

/**
 * Function: validateGraph
 * 
 * Validates the graph by validating each descendant of the given cell or
 * the root of the model. Context is an object that contains the validation
 * state for the complete validation run. The validation errors are
 * attached to their cells using <setCellWarning>. Returns null in the case of
 * successful validation or an array of strings (warnings) in the case of
 * failed validations.
 * 
 * Paramters:
 * 
 * cell - Optional <mxCell> to start the validation recursion. Default is
 * the graph root.
 * context - Object that represents the global validation state.
 */
mxGraph.prototype.validateGraph = function(cell, context)
{
	cell = (cell != null) ? cell : this.model.getRoot();
	context = (context != null) ? context : new Object();
	
	var isValid = true;
	var childCount = this.model.getChildCount(cell);
	
	for (var i = 0; i < childCount; i++)
	{
		var tmp = this.model.getChildAt(cell, i);
		var ctx = context;
		
		if (this.isValidRoot(tmp))
		{
			ctx = new Object();
		}
		
		var warn = this.validateGraph(tmp, ctx);
		
		if (warn != null)
		{
			this.setCellWarning(tmp, warn.replace(/\n/g, '<br>'));
		}
		else
		{
			this.setCellWarning(tmp, null);
		}
		
		isValid = isValid && warn == null;
	}
	
	var warning = '';
	
	// Adds error for invalid children if collapsed (children invisible)
	if (this.isCellCollapsed(cell) && !isValid)
	{
		warning += (mxResources.get(this.containsValidationErrorsResource) ||
			this.containsValidationErrorsResource) + '\n';
	}
	
	// Checks edges and cells using the defined multiplicities
	if (this.model.isEdge(cell))
	{
		warning += this.getEdgeValidationError(cell,
		this.model.getTerminal(cell, true),
		this.model.getTerminal(cell, false)) || '';
	}
	else
	{
		warning += this.getCellValidationError(cell) || '';
	}
	
	// Checks custom validation rules
	var err = this.validateCell(cell, context);
	
	if (err != null)
	{
		warning += err;
	}
	
	// Updates the display with the warning icons
	// before any potential alerts are displayed.
	// LATER: Move this into addCellOverlay. Redraw
	// should check if overlay was added or removed.
	if (this.model.getParent(cell) == null)
	{
		this.view.validate();
	}

	return (warning.length > 0 || !isValid) ? warning : null;
};

/**
 * Function: getCellValidationError
 * 
 * Checks all <multiplicities> that cannot be enforced while the graph is
 * being modified, namely, all multiplicities that require a minimum of
 * 1 edge.
 * 
 * Parameters:
 * 
 * cell - <mxCell> for which the multiplicities should be checked.
 */
mxGraph.prototype.getCellValidationError = function(cell)
{
	var outCount = this.model.getDirectedEdgeCount(cell, true);
	var inCount = this.model.getDirectedEdgeCount(cell, false);
	var value = this.model.getValue(cell);
	var error = '';

	if (this.multiplicities != null)
	{
		for (var i = 0; i < this.multiplicities.length; i++)
		{
			var rule = this.multiplicities[i];
			
			if (rule.source && mxUtils.isNode(value, rule.type,
				rule.attr, rule.value) && (outCount > rule.max ||
				outCount < rule.min))
			{
				error += rule.countError + '\n';
			}
			else if (!rule.source && mxUtils.isNode(value, rule.type,
					rule.attr, rule.value) && (inCount > rule.max ||
					inCount < rule.min))
			{
				error += rule.countError + '\n';
			}
		}
	}

	return (error.length > 0) ? error : null;
};

/**
 * Function: validateCell
 * 
 * Hook method for subclassers to return an error message for the given
 * cell and validation context. This implementation returns null. Any HTML
 * breaks will be converted to linefeeds in the calling method.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents the cell to validate.
 * context - Object that represents the global validation state.
 */
mxGraph.prototype.validateCell = function(cell, context)
{
	return null;
};

/**
 * Group: Graph appearance
 */

/**
 * Function: getBackgroundImage
 * 
 * Returns the <backgroundImage> as an <mxImage>.
 */
mxGraph.prototype.getBackgroundImage = function()
{
	return this.backgroundImage;
};

/**
 * Function: setBackgroundImage
 * 
 * Sets the new <backgroundImage>.
 * 
 * Parameters:
 * 
 * image - New <mxImage> to be used for the background.
 */
mxGraph.prototype.setBackgroundImage = function(image)
{
	this.backgroundImage = image;
};

/**
 * Function: getFoldingImage
 * 
 * Returns the <mxImage> used to display the collapsed state of
 * the specified cell state. This returns null for all edges.
 */
mxGraph.prototype.getFoldingImage = function(state)
{
	if (state != null && this.foldingEnabled && !this.getModel().isEdge(state.cell))
	{
		var tmp = this.isCellCollapsed(state.cell);
		
		if (this.isCellFoldable(state.cell, !tmp))
		{
			return (tmp) ? this.collapsedImage : this.expandedImage;
		}
	}
	
	return null;
};

/**
 * Function: convertValueToString
 * 
 * Returns the textual representation for the given cell. This
 * implementation returns the nodename or string-representation of the user
 * object.
 *
 * Example:
 * 
 * The following returns the label attribute from the cells user
 * object if it is an XML node.
 * 
 * (code)
 * graph.convertValueToString = function(cell)
 * {
 * 	return cell.getAttribute('label');
 * }
 * (end)
 * 
 * See also: <cellLabelChanged>.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose textual representation should be returned.
 */
mxGraph.prototype.convertValueToString = function(cell)
{
	var value = this.model.getValue(cell);
	
	if (value != null)
	{
		if (mxUtils.isNode(value))
		{
			return value.nodeName;
		}
		else if (typeof(value.toString) == 'function')
		{
			return value.toString();
		}
	}
	
	return '';
};

/**
 * Function: getLabel
 * 
 * Returns a string or DOM node that represents the label for the given
 * cell. This implementation uses <convertValueToString> if <labelsVisible>
 * is true. Otherwise it returns an empty string.
 * 
 * To truncate a label to match the size of the cell, the following code
 * can be used.
 * 
 * (code)
 * graph.getLabel = function(cell)
 * {
 *   var label = mxGraph.prototype.getLabel.apply(this, arguments);
 * 
 *   if (label != null && this.model.isVertex(cell))
 *   {
 *     var geo = this.getCellGeometry(cell);
 * 
 *     if (geo != null)
 *     {
 *       var max = parseInt(geo.width / 8);
 * 
 *       if (label.length > max)
 *       {
 *         label = label.substring(0, max)+'...';
 *       }
 *     }
 *   } 
 *   return mxUtils.htmlEntities(label);
 * }
 * (end)
 * 
 * A resize listener is needed in the graph to force a repaint of the label
 * after a resize.
 * 
 * (code)
 * graph.addListener(mxEvent.RESIZE_CELLS, function(sender, evt)
 * {
 *   var cells = evt.getProperty('cells');
 * 
 *   for (var i = 0; i < cells.length; i++)
 *   {
 *     this.view.removeState(cells[i]);
 *   }
 * });
 * (end)
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose label should be returned.
 */
mxGraph.prototype.getLabel = function(cell)
{
	var result = '';
	
	if (this.labelsVisible && cell != null)
	{
		var state = this.view.getState(cell);
		var style = (state != null) ? state.style : this.getCellStyle(cell);
		
		if (!mxUtils.getValue(style, mxConstants.STYLE_NOLABEL, false))
		{
			result = this.convertValueToString(cell);
		}
	}
	
	return result;
};

/**
 * Function: isHtmlLabel
 * 
 * Returns true if the label must be rendered as HTML markup. The default
 * implementation returns <htmlLabels>.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose label should be displayed as HTML markup.
 */
mxGraph.prototype.isHtmlLabel = function(cell)
{
	return this.isHtmlLabels();
};
 
/**
 * Function: isHtmlLabels
 * 
 * Returns <htmlLabels>.
 */
mxGraph.prototype.isHtmlLabels = function()
{
	return this.htmlLabels;
};
 
/**
 * Function: setHtmlLabels
 * 
 * Sets <htmlLabels>.
 */
mxGraph.prototype.setHtmlLabels = function(value)
{
	this.htmlLabels = value;
};

/**
 * Function: isWrapping
 * 
 * This enables wrapping for HTML labels.
 * 
 * Returns true if no white-space CSS style directive should be used for
 * displaying the given cells label. This implementation returns true if
 * <mxConstants.STYLE_WHITE_SPACE> in the style of the given cell is 'wrap'.
 * 
 * This is used as a workaround for IE ignoring the white-space directive
 * of child elements if the directive appears in a parent element. It
 * should be overridden to return true if a white-space directive is used
 * in the HTML markup that represents the given cells label. In order for
 * HTML markup to work in labels, <isHtmlLabel> must also return true
 * for the given cell.
 * 
 * Example:
 * 
 * (code)
 * graph.getLabel = function(cell)
 * {
 *   var tmp = mxGraph.prototype.getLabel.apply(this, arguments); // "supercall"
 *   
 *   if (this.model.isEdge(cell))
 *   {
 *     tmp = '<div style="width: 150px; white-space:normal;">'+tmp+'</div>';
 *   }
 *   
 *   return tmp;
 * }
 * 
 * graph.isWrapping = function(state)
 * {
 * 	 return this.model.isEdge(state.cell);
 * }
 * (end)
 * 
 * Makes sure no edge label is wider than 150 pixels, otherwise the content
 * is wrapped. Note: No width must be specified for wrapped vertex labels as
 * the vertex defines the width in its geometry.
 * 
 * Parameters:
 * 
 * state - <mxCell> whose label should be wrapped.
 */
mxGraph.prototype.isWrapping = function(cell)
{
	var state = this.view.getState(cell);
	var style = (state != null) ? state.style : this.getCellStyle(cell);

	return (style != null) ? style[mxConstants.STYLE_WHITE_SPACE] == 'wrap' : false;
};

/**
 * Function: isLabelClipped
 * 
 * Returns true if the overflow portion of labels should be hidden. If this
 * returns true then vertex labels will be clipped to the size of the vertices.
 * This implementation returns true if <mxConstants.STYLE_OVERFLOW> in the
 * style of the given cell is 'hidden'.
 * 
 * Parameters:
 * 
 * state - <mxCell> whose label should be clipped.
 */
mxGraph.prototype.isLabelClipped = function(cell)
{
	var state = this.view.getState(cell);
	var style = (state != null) ? state.style : this.getCellStyle(cell);

	return (style != null) ? style[mxConstants.STYLE_OVERFLOW] == 'hidden' : false;
};

/**
 * Function: getTooltip
 * 
 * Returns the string or DOM node that represents the tooltip for the given
 * state, node and coordinate pair. This implementation checks if the given
 * node is a folding icon or overlay and returns the respective tooltip. If
 * this does not result in a tooltip, the handler for the cell is retrieved
 * from <selectionCellsHandler> and the optional getTooltipForNode method is
 * called. If no special tooltip exists here then <getTooltipForCell> is used
 * with the cell in the given state as the argument to return a tooltip for the
 * given state.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose tooltip should be returned.
 * node - DOM node that is currently under the mouse.
 * x - X-coordinate of the mouse.
 * y - Y-coordinate of the mouse.
 */
mxGraph.prototype.getTooltip = function(state, node, x, y)
{
	var tip = null;
	
	if (state != null)
	{
		// Checks if the mouse is over the folding icon
		if (state.control != null && (node == state.control.node ||
			node.parentNode == state.control.node))
		{
			tip = this.collapseExpandResource;
			tip = mxUtils.htmlEntities(mxResources.get(tip) || tip).replace(/\\n/g, '<br>');
		}

		if (tip == null && state.overlays != null)
		{
			state.overlays.visit(function(id, shape)
			{
				// LATER: Exit loop if tip is not null
				if (tip == null && (node == shape.node || node.parentNode == shape.node))
				{
					tip = shape.overlay.toString();
				}
			});
		}
		
		if (tip == null)
		{
			var handler = this.selectionCellsHandler.getHandler(state.cell);
			
			if (handler != null && typeof(handler.getTooltipForNode) == 'function')
			{
				tip = handler.getTooltipForNode(node);
			}
		}
		
		if (tip == null)
		{
			tip = this.getTooltipForCell(state.cell);
		}
	}
	
	return tip;
};

/**
 * Function: getTooltipForCell
 * 
 * Returns the string or DOM node to be used as the tooltip for the given
 * cell. This implementation uses the cells getTooltip function if it
 * exists, or else it returns <convertValueToString> for the cell.
 * 
 * Example:
 * 
 * (code)
 * graph.getTooltipForCell = function(cell)
 * {
 *   return 'Hello, World!';
 * }
 * (end)
 * 
 * Replaces all tooltips with the string Hello, World!
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose tooltip should be returned.
 */
mxGraph.prototype.getTooltipForCell = function(cell)
{
	var tip = null;
	
	if (cell != null && cell.getTooltip != null)
	{
		tip = cell.getTooltip();
	}
	else
	{
		tip = this.convertValueToString(cell);
	}
	
	return tip;
};

/**
 * Function: getCursorForMouseEvent
 * 
 * Returns the cursor value to be used for the CSS of the shape for the
 * given event. This implementation calls <getCursorForCell>.
 * 
 * Parameters:
 * 
 * me - <mxMouseEvent> whose cursor should be returned.
 */
mxGraph.prototype.getCursorForMouseEvent = function(me)
{
	return this.getCursorForCell(me.getCell());
};

/**
 * Function: getCursorForCell
 * 
 * Returns the cursor value to be used for the CSS of the shape for the
 * given cell. This implementation returns null.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose cursor should be returned.
 */
mxGraph.prototype.getCursorForCell = function(cell)
{
	return null;
};

/**
 * Function: getStartSize
 * 
 * Returns the start size of the given swimlane, that is, the width or
 * height of the part that contains the title, depending on the
 * horizontal style. The return value is an <mxRectangle> with either
 * width or height set as appropriate.
 * 
 * Parameters:
 * 
 * swimlane - <mxCell> whose start size should be returned.
 */
mxGraph.prototype.getStartSize = function(swimlane)
{
	var result = new mxRectangle();
	var state = this.view.getState(swimlane);
	var style = (state != null) ? state.style : this.getCellStyle(swimlane);
	
	if (style != null)
	{
		var size = parseInt(mxUtils.getValue(style,
			mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_STARTSIZE));
		
		if (mxUtils.getValue(style, mxConstants.STYLE_HORIZONTAL, true))
		{
			result.height = size;
		}
		else
		{
			result.width = size;
		}
	}
	
	return result;
};

/**
 * Function: getImage
 * 
 * Returns the image URL for the given cell state. This implementation
 * returns the value stored under <mxConstants.STYLE_IMAGE> in the cell
 * style.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose image URL should be returned.
 */
mxGraph.prototype.getImage = function(state)
{
	return (state != null && state.style != null) ? state.style[mxConstants.STYLE_IMAGE] : null;
};

/**
 * Function: getVerticalAlign
 * 
 * Returns the vertical alignment for the given cell state. This
 * implementation returns the value stored under
 * <mxConstants.STYLE_VERTICAL_ALIGN> in the cell style.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose vertical alignment should be
 * returned.
 */
mxGraph.prototype.getVerticalAlign = function(state)
{
	return (state != null && state.style != null) ?
		(state.style[mxConstants.STYLE_VERTICAL_ALIGN] ||
		mxConstants.ALIGN_MIDDLE) : null;
};

/**
 * Function: getIndicatorColor
 * 
 * Returns the indicator color for the given cell state. This
 * implementation returns the value stored under
 * <mxConstants.STYLE_INDICATOR_COLOR> in the cell style.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose indicator color should be
 * returned.
 */
mxGraph.prototype.getIndicatorColor = function(state)
{
	return (state != null && state.style != null) ? state.style[mxConstants.STYLE_INDICATOR_COLOR] : null;
};

/**
 * Function: getIndicatorGradientColor
 * 
 * Returns the indicator gradient color for the given cell state. This
 * implementation returns the value stored under
 * <mxConstants.STYLE_INDICATOR_GRADIENTCOLOR> in the cell style.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose indicator gradient color should be
 * returned.
 */
mxGraph.prototype.getIndicatorGradientColor = function(state)
{
	return (state != null && state.style != null) ? state.style[mxConstants.STYLE_INDICATOR_GRADIENTCOLOR] : null;
};

/**
 * Function: getIndicatorShape
 * 
 * Returns the indicator shape for the given cell state. This
 * implementation returns the value stored under
 * <mxConstants.STYLE_INDICATOR_SHAPE> in the cell style.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose indicator shape should be returned.
 */
mxGraph.prototype.getIndicatorShape = function(state)
{
	return (state != null && state.style != null) ? state.style[mxConstants.STYLE_INDICATOR_SHAPE] : null;
};

/**
 * Function: getIndicatorImage
 * 
 * Returns the indicator image for the given cell state. This
 * implementation returns the value stored under
 * <mxConstants.STYLE_INDICATOR_IMAGE> in the cell style.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose indicator image should be returned.
 */
mxGraph.prototype.getIndicatorImage = function(state)
{
	return (state != null && state.style != null) ? state.style[mxConstants.STYLE_INDICATOR_IMAGE] : null;
};

/**
 * Function: getBorder
 * 
 * Returns the value of <border>.
 */
mxGraph.prototype.getBorder = function()
{
	return this.border;
};

/**
 * Function: setBorder
 * 
 * Sets the value of <border>.
 * 
 * Parameters:
 * 
 * value - Positive integer that represents the border to be used.
 */
mxGraph.prototype.setBorder = function(value)
{
	this.border = value;
};

/**
 * Function: isSwimlane
 * 
 * Returns true if the given cell is a swimlane in the graph. A swimlane is
 * a container cell with some specific behaviour. This implementation
 * checks if the shape associated with the given cell is a <mxSwimlane>.
 * 
 * Parameters:
 * 
 * cell - <mxCell> to be checked.
 */
mxGraph.prototype.isSwimlane = function (cell)
{
	if (cell != null)
	{
		if (this.model.getParent(cell) != this.model.getRoot())
		{
			var state = this.view.getState(cell);
			var style = (state != null) ? state.style : this.getCellStyle(cell);

			if (style != null && !this.model.isEdge(cell))
			{
				return style[mxConstants.STYLE_SHAPE] == mxConstants.SHAPE_SWIMLANE;
			}
		}
	}
	
	return false;
};

/**
 * Group: Graph behaviour
 */

/**
 * Function: isResizeContainer
 * 
 * Returns <resizeContainer>.
 */
mxGraph.prototype.isResizeContainer = function()
{
	return this.resizeContainer;
};

/**
 * Function: setResizeContainer
 * 
 * Sets <resizeContainer>.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if the container should be resized.
 */
mxGraph.prototype.setResizeContainer = function(value)
{
	this.resizeContainer = value;
};

/**
 * Function: isEnabled
 * 
 * Returns true if the graph is <enabled>.
 */
mxGraph.prototype.isEnabled = function()
{
	return this.enabled;
};

/**
 * Function: setEnabled
 * 
 * Specifies if the graph should allow any interactions. This
 * implementation updates <enabled>.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if the graph should be enabled.
 */
mxGraph.prototype.setEnabled = function(value)
{
	this.enabled = value;
};

/**
 * Function: isEscapeEnabled
 * 
 * Returns <escapeEnabled>.
 */
mxGraph.prototype.isEscapeEnabled = function()
{
	return this.escapeEnabled;
};

/**
 * Function: setEscapeEnabled
 * 
 * Sets <escapeEnabled>.
 * 
 * Parameters:
 * 
 * enabled - Boolean indicating if escape should be enabled.
 */
mxGraph.prototype.setEscapeEnabled = function(value)
{
	this.escapeEnabled = value;
};

/**
 * Function: isInvokesStopCellEditing
 * 
 * Returns <invokesStopCellEditing>.
 */
mxGraph.prototype.isInvokesStopCellEditing = function()
{
	return this.invokesStopCellEditing;
};

/**
 * Function: setInvokesStopCellEditing
 * 
 * Sets <invokesStopCellEditing>.
 */
mxGraph.prototype.setInvokesStopCellEditing = function(value)
{
	this.invokesStopCellEditing = value;
};

/**
 * Function: isEnterStopsCellEditing
 * 
 * Returns <enterStopsCellEditing>.
 */
mxGraph.prototype.isEnterStopsCellEditing = function()
{
	return this.enterStopsCellEditing;
};

/**
 * Function: setEnterStopsCellEditing
 * 
 * Sets <enterStopsCellEditing>.
 */
mxGraph.prototype.setEnterStopsCellEditing = function(value)
{
	this.enterStopsCellEditing = value;
};

/**
 * Function: isCellLocked
 * 
 * Returns true if the given cell may not be moved, sized, bended,
 * disconnected, edited or selected. This implementation returns true for
 * all vertices with a relative geometry if <locked> is false.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose locked state should be returned.
 */
mxGraph.prototype.isCellLocked = function(cell)
{
	var geometry = this.model.getGeometry(cell);
	
	return this.isCellsLocked() || (geometry != null && this.model.isVertex(cell) && geometry.relative);
};

/**
 * Function: isCellsLocked
 * 
 * Returns true if the given cell may not be moved, sized, bended,
 * disconnected, edited or selected. This implementation returns true for
 * all vertices with a relative geometry if <locked> is false.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose locked state should be returned.
 */
mxGraph.prototype.isCellsLocked = function()
{
	return this.cellsLocked;
};

/**
 * Function: setLocked
 * 
 * Sets if any cell may be moved, sized, bended, disconnected, edited or
 * selected.
 * 
 * Parameters:
 * 
 * value - Boolean that defines the new value for <cellsLocked>.
 */
mxGraph.prototype.setCellsLocked = function(value)
{
	this.cellsLocked = value;
};

/**
 * Function: getCloneableCells
 * 
 * Returns the cells which may be exported in the given array of cells.
 */
mxGraph.prototype.getCloneableCells = function(cells)
{
	return this.model.filterCells(cells, mxUtils.bind(this, function(cell)
	{
		return this.isCellCloneable(cell);
	}));
};

/**
 * Function: isCellCloneable
 * 
 * Returns true if the given cell is cloneable. This implementation returns
 * <isCellsCloneable> for all cells unless a cell style specifies
 * <mxConstants.STYLE_CLONEABLE> to be 0. 
 * 
 * Parameters:
 * 
 * cell - Optional <mxCell> whose cloneable state should be returned.
 */
mxGraph.prototype.isCellCloneable = function(cell)
{
	var state = this.view.getState(cell);
	var style = (state != null) ? state.style : this.getCellStyle(cell);

	return this.isCellsCloneable() && style[mxConstants.STYLE_CLONEABLE] != 0;
};

/**
 * Function: isCellsCloneable
 * 
 * Returns <cellsCloneable>, that is, if the graph allows cloning of cells
 * by using control-drag.
 */
mxGraph.prototype.isCellsCloneable = function()
{
	return this.cellsCloneable;
};

/**
 * Function: setCellsCloneable
 * 
 * Specifies if the graph should allow cloning of cells by holding down the
 * control key while cells are being moved. This implementation updates
 * <cellsCloneable>.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if the graph should be cloneable.
 */
mxGraph.prototype.setCellsCloneable = function(value)
{
	this.cellsCloneable = value;
};

/**
 * Function: getExportableCells
 * 
 * Returns the cells which may be exported in the given array of cells.
 */
mxGraph.prototype.getExportableCells = function(cells)
{
	return this.model.filterCells(cells, mxUtils.bind(this, function(cell)
	{
		return this.canExportCell(cell);
	}));
};

/**
 * Function: canExportCell
 * 
 * Returns true if the given cell may be exported to the clipboard. This
 * implementation returns <exportEnabled> for all cells.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents the cell to be exported.
 */
mxGraph.prototype.canExportCell = function(cell)
{
	return this.exportEnabled;
};

/**
 * Function: getImportableCells
 * 
 * Returns the cells which may be imported in the given array of cells.
 */
mxGraph.prototype.getImportableCells = function(cells)
{
	return this.model.filterCells(cells, mxUtils.bind(this, function(cell)
	{
		return this.canImportCell(cell);
	}));
};

/**
 * Function: canImportCell
 * 
 * Returns true if the given cell may be imported from the clipboard.
 * This implementation returns <importEnabled> for all cells.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents the cell to be imported.
 */
mxGraph.prototype.canImportCell = function(cell)
{
	return this.importEnabled;
};

/**
 * Function: isCellSelectable
 *
 * Returns true if the given cell is selectable. This implementation
 * returns <cellsSelectable>.
 * 
 * To add a new style for making cells (un)selectable, use the following code.
 * 
 * (code)
 * mxGraph.prototype.isCellSelectable = function(cell)
 * {
 *   var state = this.view.getState(cell);
 *   var style = (state != null) ? state.style : this.getCellStyle(cell);
 *   
 *   return this.isCellsSelectable() && !this.isCellLocked(cell) && style['selectable'] != 0;
 * };
 * (end)
 * 
 * You can then use the new style as shown in this example.
 * 
 * (code)
 * graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30, 'selectable=0');
 * (end)
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose selectable state should be returned.
 */
mxGraph.prototype.isCellSelectable = function(cell)
{
	return this.isCellsSelectable();
};

/**
 * Function: isCellsSelectable
 *
 * Returns <cellsSelectable>.
 */
mxGraph.prototype.isCellsSelectable = function()
{
	return this.cellsSelectable;
};

/**
 * Function: setCellsSelectable
 *
 * Sets <cellsSelectable>.
 */
mxGraph.prototype.setCellsSelectable = function(value)
{
	this.cellsSelectable = value;
};

/**
 * Function: getDeletableCells
 * 
 * Returns the cells which may be exported in the given array of cells.
 */
mxGraph.prototype.getDeletableCells = function(cells)
{
	return this.model.filterCells(cells, mxUtils.bind(this, function(cell)
	{
		return this.isCellDeletable(cell);
	}));
};

/**
 * Function: isCellDeletable
 *
 * Returns true if the given cell is moveable. This returns
 * <cellsDeletable> for all given cells if a cells style does not specify
 * <mxConstants.STYLE_DELETABLE> to be 0.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose deletable state should be returned.
 */
mxGraph.prototype.isCellDeletable = function(cell)
{
	var state = this.view.getState(cell);
	var style = (state != null) ? state.style : this.getCellStyle(cell);
	
	return this.isCellsDeletable() && style[mxConstants.STYLE_DELETABLE] != 0;
};

/**
 * Function: isCellsDeletable
 *
 * Returns <cellsDeletable>.
 */
mxGraph.prototype.isCellsDeletable = function()
{
	return this.cellsDeletable;
};

/**
 * Function: setCellsDeletable
 * 
 * Sets <cellsDeletable>.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if the graph should allow deletion of cells.
 */
mxGraph.prototype.setCellsDeletable = function(value)
{
	this.cellsDeletable = value;
};

/**
 * Function: isLabelMovable
 *
 * Returns true if the given edges's label is moveable. This returns
 * <movable> for all given cells if <isLocked> does not return true
 * for the given cell.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose label should be moved.
 */
mxGraph.prototype.isLabelMovable = function(cell)
{
	return !this.isCellLocked(cell) &&
		((this.model.isEdge(cell) && this.edgeLabelsMovable) ||
		(this.model.isVertex(cell) && this.vertexLabelsMovable));
};

/**
 * Function: isCellRotatable
 *
 * Returns true if the given cell is rotatable. This returns true for the given
 * cell if its style does not specify <mxConstants.STYLE_ROTATABLE> to be 0.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose rotatable state should be returned.
 */
mxGraph.prototype.isCellRotatable = function(cell)
{
	var state = this.view.getState(cell);
	var style = (state != null) ? state.style : this.getCellStyle(cell);
	
	return style[mxConstants.STYLE_ROTATABLE] != 0;
};

/**
 * Function: getMovableCells
 * 
 * Returns the cells which are movable in the given array of cells.
 */
mxGraph.prototype.getMovableCells = function(cells)
{
	return this.model.filterCells(cells, mxUtils.bind(this, function(cell)
	{
		return this.isCellMovable(cell);
	}));
};

/**
 * Function: isCellMovable
 *
 * Returns true if the given cell is moveable. This returns <cellsMovable>
 * for all given cells if <isCellLocked> does not return true for the given
 * cell and its style does not specify <mxConstants.STYLE_MOVABLE> to be 0.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose movable state should be returned.
 */
mxGraph.prototype.isCellMovable = function(cell)
{
	var state = this.view.getState(cell);
	var style = (state != null) ? state.style : this.getCellStyle(cell);
	
	return this.isCellsMovable() && !this.isCellLocked(cell) && style[mxConstants.STYLE_MOVABLE] != 0;
};

/**
 * Function: isCellsMovable
 *
 * Returns <cellsMovable>.
 */
mxGraph.prototype.isCellsMovable = function()
{
	return this.cellsMovable;
};

/**
 * Function: setCellsMovable
 * 
 * Specifies if the graph should allow moving of cells. This implementation
 * updates <cellsMsovable>.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if the graph should allow moving of cells.
 */
mxGraph.prototype.setCellsMovable = function(value)
{
	this.cellsMovable = value;
};

/**
 * Function: isGridEnabled
 *
 * Returns <gridEnabled> as a boolean.
 */
mxGraph.prototype.isGridEnabled = function()
{
	return this.gridEnabled;
};

/**
 * Function: setGridEnabled
 * 
 * Specifies if the grid should be enabled.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if the grid should be enabled.
 */
mxGraph.prototype.setGridEnabled = function(value)
{
	this.gridEnabled = value;
};

/**
 * Function: isPortsEnabled
 *
 * Returns <portsEnabled> as a boolean.
 */
mxGraph.prototype.isPortsEnabled = function()
{
	return this.portsEnabled;
};

/**
 * Function: setPortsEnabled
 * 
 * Specifies if the ports should be enabled.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if the ports should be enabled.
 */
mxGraph.prototype.setPortsEnabled = function(value)
{
	this.portsEnabled = value;
};

/**
 * Function: getGridSize
 *
 * Returns <gridSize>.
 */
mxGraph.prototype.getGridSize = function()
{
	return this.gridSize;
};

/**
 * Function: setGridSize
 * 
 * Sets <gridSize>.
 */
mxGraph.prototype.setGridSize = function(value)
{
	this.gridSize = value;
};

/**
 * Function: getTolerance
 *
 * Returns <tolerance>.
 */
mxGraph.prototype.getTolerance = function()
{
	return this.tolerance;
};

/**
 * Function: setTolerance
 * 
 * Sets <tolerance>.
 */
mxGraph.prototype.setTolerance = function(value)
{
	this.tolerance = value;
};

/**
 * Function: isVertexLabelsMovable
 *
 * Returns <vertexLabelsMovable>.
 */
mxGraph.prototype.isVertexLabelsMovable = function()
{
	return this.vertexLabelsMovable;
};

/**
 * Function: setVertexLabelsMovable
 * 
 * Sets <vertexLabelsMovable>.
 */
mxGraph.prototype.setVertexLabelsMovable = function(value)
{
	this.vertexLabelsMovable = value;
};

/**
 * Function: isEdgeLabelsMovable
 *
 * Returns <edgeLabelsMovable>.
 */
mxGraph.prototype.isEdgeLabelsMovable = function()
{
	return this.edgeLabelsMovable;
};

/**
 * Function: isEdgeLabelsMovable
 * 
 * Sets <edgeLabelsMovable>.
 */
mxGraph.prototype.setEdgeLabelsMovable = function(value)
{
	this.edgeLabelsMovable = value;
};

/**
 * Function: isSwimlaneNesting
 *
 * Returns <swimlaneNesting> as a boolean.
 */
mxGraph.prototype.isSwimlaneNesting = function()
{
	return this.swimlaneNesting;
};

/**
 * Function: setSwimlaneNesting
 * 
 * Specifies if swimlanes can be nested by drag and drop. This is only
 * taken into account if dropEnabled is true.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if swimlanes can be nested.
 */
mxGraph.prototype.setSwimlaneNesting = function(value)
{
	this.swimlaneNesting = value;
};

/**
 * Function: isSwimlaneSelectionEnabled
 *
 * Returns <swimlaneSelectionEnabled> as a boolean.
 */
mxGraph.prototype.isSwimlaneSelectionEnabled = function()
{
	return this.swimlaneSelectionEnabled;
};

/**
 * Function: setSwimlaneSelectionEnabled
 * 
 * Specifies if swimlanes should be selected if the mouse is released
 * over their content area.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if swimlanes content areas
 * should be selected when the mouse is released over them.
 */
mxGraph.prototype.setSwimlaneSelectionEnabled = function(value)
{
	this.swimlaneSelectionEnabled = value;
};

/**
 * Function: isMultigraph
 *
 * Returns <multigraph> as a boolean.
 */
mxGraph.prototype.isMultigraph = function()
{
	return this.multigraph;
};

/**
 * Function: setMultigraph
 * 
 * Specifies if the graph should allow multiple connections between the
 * same pair of vertices.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if the graph allows multiple connections
 * between the same pair of vertices.
 */
mxGraph.prototype.setMultigraph = function(value)
{
	this.multigraph = value;
};

/**
 * Function: isAllowLoops
 *
 * Returns <allowLoops> as a boolean.
 */
mxGraph.prototype.isAllowLoops = function()
{
	return this.allowLoops;
};

/**
 * Function: setAllowDanglingEdges
 * 
 * Specifies if dangling edges are allowed, that is, if edges are allowed
 * that do not have a source and/or target terminal defined.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if dangling edges are allowed.
 */
mxGraph.prototype.setAllowDanglingEdges = function(value)
{
	this.allowDanglingEdges = value;
};

/**
 * Function: isAllowDanglingEdges
 *
 * Returns <allowDanglingEdges> as a boolean.
 */
mxGraph.prototype.isAllowDanglingEdges = function()
{
	return this.allowDanglingEdges;
};

/**
 * Function: setConnectableEdges
 * 
 * Specifies if edges should be connectable.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if edges should be connectable.
 */
mxGraph.prototype.setConnectableEdges = function(value)
{
	this.connectableEdges = value;
};

/**
 * Function: isConnectableEdges
 *
 * Returns <connectableEdges> as a boolean.
 */
mxGraph.prototype.isConnectableEdges = function()
{
	return this.connectableEdges;
};

/**
 * Function: setCloneInvalidEdges
 * 
 * Specifies if edges should be inserted when cloned but not valid wrt.
 * <getEdgeValidationError>. If false such edges will be silently ignored.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if cloned invalid edges should be
 * inserted into the graph or ignored.
 */
mxGraph.prototype.setCloneInvalidEdges = function(value)
{
	this.cloneInvalidEdges = value;
};

/**
 * Function: isCloneInvalidEdges
 *
 * Returns <cloneInvalidEdges> as a boolean.
 */
mxGraph.prototype.isCloneInvalidEdges = function()
{
	return this.cloneInvalidEdges;
};

/**
 * Function: setAllowLoops
 * 
 * Specifies if loops are allowed.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if loops are allowed.
 */
mxGraph.prototype.setAllowLoops = function(value)
{
	this.allowLoops = value;
};

/**
 * Function: isDisconnectOnMove
 *
 * Returns <disconnectOnMove> as a boolean.
 */
mxGraph.prototype.isDisconnectOnMove = function()
{
	return this.disconnectOnMove;
};

/**
 * Function: setDisconnectOnMove
 * 
 * Specifies if edges should be disconnected when moved. (Note: Cloned
 * edges are always disconnected.)
 * 
 * Parameters:
 * 
 * value - Boolean indicating if edges should be disconnected
 * when moved.
 */
mxGraph.prototype.setDisconnectOnMove = function(value)
{
	this.disconnectOnMove = value;
};

/**
 * Function: isDropEnabled
 *
 * Returns <dropEnabled> as a boolean.
 */
mxGraph.prototype.isDropEnabled = function()
{
	return this.dropEnabled;
};

/**
 * Function: setDropEnabled
 * 
 * Specifies if the graph should allow dropping of cells onto or into other
 * cells.
 * 
 * Parameters:
 * 
 * dropEnabled - Boolean indicating if the graph should allow dropping
 * of cells into other cells.
 */
mxGraph.prototype.setDropEnabled = function(value)
{
	this.dropEnabled = value;
};

/**
 * Function: isSplitEnabled
 *
 * Returns <splitEnabled> as a boolean.
 */
mxGraph.prototype.isSplitEnabled = function()
{
	return this.splitEnabled;
};

/**
 * Function: setSplitEnabled
 * 
 * Specifies if the graph should allow dropping of cells onto or into other
 * cells.
 * 
 * Parameters:
 * 
 * dropEnabled - Boolean indicating if the graph should allow dropping
 * of cells into other cells.
 */
mxGraph.prototype.setSplitEnabled = function(value)
{
	this.splitEnabled = value;
};

/**
 * Function: isCellResizable
 *
 * Returns true if the given cell is resizable. This returns
 * <cellsResizable> for all given cells if <isCellLocked> does not return
 * true for the given cell and its style does not specify
 * <mxConstants.STYLE_RESIZABLE> to be 0.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose resizable state should be returned.
 */
mxGraph.prototype.isCellResizable = function(cell)
{
	var state = this.view.getState(cell);
	var style = (state != null) ? state.style : this.getCellStyle(cell);

	return this.isCellsResizable() && !this.isCellLocked(cell) &&
		mxUtils.getValue(style, mxConstants.STYLE_RESIZABLE, '1') != '0';
};

/**
 * Function: isCellsResizable
 *
 * Returns <cellsResizable>.
 */
mxGraph.prototype.isCellsResizable = function()
{
	return this.cellsResizable;
};

/**
 * Function: setCellsResizable
 * 
 * Specifies if the graph should allow resizing of cells. This
 * implementation updates <cellsResizable>.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if the graph should allow resizing of
 * cells.
 */
mxGraph.prototype.setCellsResizable = function(value)
{
	this.cellsResizable = value;
};

/**
 * Function: isTerminalPointMovable
 *
 * Returns true if the given terminal point is movable. This is independent
 * from <isCellConnectable> and <isCellDisconnectable> and controls if terminal
 * points can be moved in the graph if the edge is not connected. Note that it
 * is required for this to return true to connect unconnected edges. This
 * implementation returns true.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose terminal point should be moved.
 * source - Boolean indicating if the source or target terminal should be moved.
 */
mxGraph.prototype.isTerminalPointMovable = function(cell, source)
{
	return true;
};

/**
 * Function: isCellBendable
 *
 * Returns true if the given cell is bendable. This returns <cellsBendable>
 * for all given cells if <isLocked> does not return true for the given
 * cell and its style does not specify <mxConstants.STYLE_BENDABLE> to be 0.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose bendable state should be returned.
 */
mxGraph.prototype.isCellBendable = function(cell)
{
	var state = this.view.getState(cell);
	var style = (state != null) ? state.style : this.getCellStyle(cell);
	
	return this.isCellsBendable() && !this.isCellLocked(cell) && style[mxConstants.STYLE_BENDABLE] != 0;
};

/**
 * Function: isCellsBendable
 *
 * Returns <cellsBenadable>.
 */
mxGraph.prototype.isCellsBendable = function()
{
	return this.cellsBendable;
};

/**
 * Function: setCellsBendable
 * 
 * Specifies if the graph should allow bending of edges. This
 * implementation updates <bendable>.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if the graph should allow bending of
 * edges.
 */
mxGraph.prototype.setCellsBendable = function(value)
{
	this.cellsBendable = value;
};

/**
 * Function: isCellEditable
 *
 * Returns true if the given cell is editable. This returns <cellsEditable> for
 * all given cells if <isCellLocked> does not return true for the given cell
 * and its style does not specify <mxConstants.STYLE_EDITABLE> to be 0.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose editable state should be returned.
 */
mxGraph.prototype.isCellEditable = function(cell)
{
	var state = this.view.getState(cell);
	var style = (state != null) ? state.style : this.getCellStyle(cell);
	
	return this.isCellsEditable() && !this.isCellLocked(cell) && style[mxConstants.STYLE_EDITABLE] != 0;
};

/**
 * Function: isCellsEditable
 *
 * Returns <cellsEditable>.
 */
mxGraph.prototype.isCellsEditable = function()
{
	return this.cellsEditable;
};

/**
 * Function: setCellsEditable
 * 
 * Specifies if the graph should allow in-place editing for cell labels.
 * This implementation updates <cellsEditable>.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if the graph should allow in-place
 * editing.
 */
mxGraph.prototype.setCellsEditable = function(value)
{
	this.cellsEditable = value;
};

/**
 * Function: isCellDisconnectable
 *
 * Returns true if the given cell is disconnectable from the source or
 * target terminal. This returns <isCellsDisconnectable> for all given
 * cells if <isCellLocked> does not return true for the given cell.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose disconnectable state should be returned.
 * terminal - <mxCell> that represents the source or target terminal.
 * source - Boolean indicating if the source or target terminal is to be
 * disconnected.
 */
mxGraph.prototype.isCellDisconnectable = function(cell, terminal, source)
{
	return this.isCellsDisconnectable() && !this.isCellLocked(cell);
};

/**
 * Function: isCellsDisconnectable
 *
 * Returns <cellsDisconnectable>.
 */
mxGraph.prototype.isCellsDisconnectable = function()
{
	return this.cellsDisconnectable;
};

/**
 * Function: setCellsDisconnectable
 *
 * Sets <cellsDisconnectable>.
 */
mxGraph.prototype.setCellsDisconnectable = function(value)
{
	this.cellsDisconnectable = value;
};

/**
 * Function: isValidSource
 * 
 * Returns true if the given cell is a valid source for new connections.
 * This implementation returns true for all non-null values and is
 * called by is called by <isValidConnection>.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents a possible source or null.
 */
mxGraph.prototype.isValidSource = function(cell)
{
	return (cell == null && this.allowDanglingEdges) ||
		(cell != null && (!this.model.isEdge(cell) ||
		this.connectableEdges) && this.isCellConnectable(cell));
};
	
/**
 * Function: isValidTarget
 * 
 * Returns <isValidSource> for the given cell. This is called by
 * <isValidConnection>.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents a possible target or null.
 */
mxGraph.prototype.isValidTarget = function(cell)
{
	return this.isValidSource(cell);
};

/**
 * Function: isValidConnection
 * 
 * Returns true if the given target cell is a valid target for source.
 * This is a boolean implementation for not allowing connections between
 * certain pairs of vertices and is called by <getEdgeValidationError>.
 * This implementation returns true if <isValidSource> returns true for
 * the source and <isValidTarget> returns true for the target.
 * 
 * Parameters:
 * 
 * source - <mxCell> that represents the source cell.
 * target - <mxCell> that represents the target cell.
 */
mxGraph.prototype.isValidConnection = function(source, target)
{
	return this.isValidSource(source) && this.isValidTarget(target);
};

/**
 * Function: setConnectable
 * 
 * Specifies if the graph should allow new connections. This implementation
 * updates <mxConnectionHandler.enabled> in <connectionHandler>.
 * 
 * Parameters:
 * 
 * connectable - Boolean indicating if new connections should be allowed.
 */
mxGraph.prototype.setConnectable = function(connectable)
{
	this.connectionHandler.setEnabled(connectable);
};
	
/**
 * Function: isConnectable
 * 
 * Returns true if the <connectionHandler> is enabled.
 */
mxGraph.prototype.isConnectable = function(connectable)
{
	return this.connectionHandler.isEnabled();
};

/**
 * Function: setTooltips
 * 
 * Specifies if tooltips should be enabled. This implementation updates
 * <mxTooltipHandler.enabled> in <tooltipHandler>.
 * 
 * Parameters:
 * 
 * enabled - Boolean indicating if tooltips should be enabled.
 */
mxGraph.prototype.setTooltips = function (enabled)
{
	this.tooltipHandler.setEnabled(enabled);
};

/**
 * Function: setPanning
 * 
 * Specifies if panning should be enabled. This implementation updates
 * <mxPanningHandler.panningEnabled> in <panningHandler>.
 * 
 * Parameters:
 * 
 * enabled - Boolean indicating if panning should be enabled.
 */
mxGraph.prototype.setPanning = function(enabled)
{
	this.panningHandler.panningEnabled = enabled;
};

/**
 * Function: isEditing
 * 
 * Returns true if the given cell is currently being edited.
 * If no cell is specified then this returns true if any
 * cell is currently being edited.
 *
 * Parameters:
 * 
 * cell - <mxCell> that should be checked.
 */
mxGraph.prototype.isEditing = function(cell)
{
	if (this.cellEditor != null)
	{
		var editingCell = this.cellEditor.getEditingCell();
		
		return (cell == null) ? editingCell != null : cell == editingCell;
	}
	
	return false;
};

/**
 * Function: isAutoSizeCell
 * 
 * Returns true if the size of the given cell should automatically be
 * updated after a change of the label. This implementation returns
 * <autoSizeCells> or checks if the cell style does specify
 * <mxConstants.STYLE_AUTOSIZE> to be 1.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that should be resized.
 */
mxGraph.prototype.isAutoSizeCell = function(cell)
{
	var state = this.view.getState(cell);
	var style = (state != null) ? state.style : this.getCellStyle(cell);
	
	return this.isAutoSizeCells() || style[mxConstants.STYLE_AUTOSIZE] == 1;
};

/**
 * Function: isAutoSizeCells
 * 
 * Returns <autoSizeCells>.
 */
mxGraph.prototype.isAutoSizeCells = function()
{
	return this.autoSizeCells;
};

/**
 * Function: setAutoSizeCells
 * 
 * Specifies if cell sizes should be automatically updated after a label
 * change. This implementation sets <autoSizeCells> to the given parameter.
 * To update the size of cells when the cells are added, set
 * <autoSizeCellsOnAdd> to true.
 * 
 * Parameters:
 * 
 * value - Boolean indicating if cells should be resized
 * automatically.
 */
mxGraph.prototype.setAutoSizeCells = function(value)
{
	this.autoSizeCells = value;
};

/**
 * Function: isExtendParent
 * 
 * Returns true if the parent of the given cell should be extended if the
 * child has been resized so that it overlaps the parent. This
 * implementation returns <isExtendParents> if the cell is not an edge.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that has been resized.
 */
mxGraph.prototype.isExtendParent = function(cell)
{
	return !this.getModel().isEdge(cell) && this.isExtendParents();
};

/**
 * Function: isExtendParents
 * 
 * Returns <extendParents>.
 */
mxGraph.prototype.isExtendParents = function()
{
	return this.extendParents;
};

/**
 * Function: setExtendParents
 * 
 * Sets <extendParents>.
 * 
 * Parameters:
 * 
 * value - New boolean value for <extendParents>.
 */
mxGraph.prototype.setExtendParents = function(value)
{
	this.extendParents = value;
};

/**
 * Function: isExtendParentsOnAdd
 * 
 * Returns <extendParentsOnAdd>.
 */
mxGraph.prototype.isExtendParentsOnAdd = function(cell)
{
	return this.extendParentsOnAdd;
};

/**
 * Function: setExtendParentsOnAdd
 * 
 * Sets <extendParentsOnAdd>.
 * 
 * Parameters:
 * 
 * value - New boolean value for <extendParentsOnAdd>.
 */
mxGraph.prototype.setExtendParentsOnAdd = function(value)
{
	this.extendParentsOnAdd = value;
};

/**
 * Function: isExtendParentsOnMove
 * 
 * Returns <extendParentsOnMove>.
 */
mxGraph.prototype.isExtendParentsOnMove = function()
{
	return this.extendParentsOnMove;
};

/**
 * Function: setExtendParentsOnMove
 * 
 * Sets <extendParentsOnMove>.
 * 
 * Parameters:
 * 
 * value - New boolean value for <extendParentsOnAdd>.
 */
mxGraph.prototype.setExtendParentsOnMove = function(value)
{
	this.extendParentsOnMove = value;
};

/**
 * Function: isRecursiveResize
 * 
 * Returns <recursiveResize>.
 * 
 * Parameters:
 * 
 * state - <mxCellState> that is being resized.
 */
mxGraph.prototype.isRecursiveResize = function(state)
{
	return this.recursiveResize;
};

/**
 * Function: setRecursiveResize
 * 
 * Sets <recursiveResize>.
 * 
 * Parameters:
 * 
 * value - New boolean value for <recursiveResize>.
 */
mxGraph.prototype.setRecursiveResize = function(value)
{
	this.recursiveResize = value;
};

/**
 * Function: isConstrainChild
 * 
 * Returns true if the given cell should be kept inside the bounds of its
 * parent according to the rules defined by <getOverlap> and
 * <isAllowOverlapParent>. This implementation returns false for all children
 * of edges and <isConstrainChildren> otherwise.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that should be constrained.
 */
mxGraph.prototype.isConstrainChild = function(cell)
{
	return this.isConstrainChildren() && !this.getModel().isEdge(this.getModel().getParent(cell));
};

/**
 * Function: isConstrainChildren
 * 
 * Returns <constrainChildren>.
 */
mxGraph.prototype.isConstrainChildren = function()
{
	return this.constrainChildren;
};

/**
 * Function: setConstrainChildren
 * 
 * Sets <constrainChildren>.
 */
mxGraph.prototype.setConstrainChildren = function(value)
{
	this.constrainChildren = value;
};

/**
 * Function: isConstrainRelativeChildren
 * 
 * Returns <constrainRelativeChildren>.
 */
mxGraph.prototype.isConstrainRelativeChildren = function()
{
	return this.constrainRelativeChildren;
};

/**
 * Function: setConstrainRelativeChildren
 * 
 * Sets <constrainRelativeChildren>.
 */
mxGraph.prototype.setConstrainRelativeChildren = function(value)
{
	this.constrainRelativeChildren = value;
};

/**
 * Function: isConstrainChildren
 * 
 * Returns <allowNegativeCoordinates>.
 */
mxGraph.prototype.isAllowNegativeCoordinates = function()
{
	return this.allowNegativeCoordinates;
};

/**
 * Function: setConstrainChildren
 * 
 * Sets <allowNegativeCoordinates>.
 */
mxGraph.prototype.setAllowNegativeCoordinates = function(value)
{
	this.allowNegativeCoordinates = value;
};

/**
 * Function: getOverlap
 * 
 * Returns a decimal number representing the amount of the width and height
 * of the given cell that is allowed to overlap its parent. A value of 0
 * means all children must stay inside the parent, 1 means the child is
 * allowed to be placed outside of the parent such that it touches one of
 * the parents sides. If <isAllowOverlapParent> returns false for the given
 * cell, then this method returns 0.
 * 
 * Parameters:
 * 
 * cell - <mxCell> for which the overlap ratio should be returned.
 */
mxGraph.prototype.getOverlap = function(cell)
{
	return (this.isAllowOverlapParent(cell)) ? this.defaultOverlap : 0;
};
	
/**
 * Function: isAllowOverlapParent
 * 
 * Returns true if the given cell is allowed to be placed outside of the
 * parents area.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents the child to be checked.
 */
mxGraph.prototype.isAllowOverlapParent = function(cell)
{
	return false;
};

/**
 * Function: getFoldableCells
 * 
 * Returns the cells which are movable in the given array of cells.
 */
mxGraph.prototype.getFoldableCells = function(cells, collapse)
{
	return this.model.filterCells(cells, mxUtils.bind(this, function(cell)
	{
		return this.isCellFoldable(cell, collapse);
	}));
};

/**
 * Function: isCellFoldable
 * 
 * Returns true if the given cell is foldable. This implementation
 * returns true if the cell has at least one child and its style
 * does not specify <mxConstants.STYLE_FOLDABLE> to be 0.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose foldable state should be returned.
 */
mxGraph.prototype.isCellFoldable = function(cell, collapse)
{
	var state = this.view.getState(cell);
	var style = (state != null) ? state.style : this.getCellStyle(cell);
	
	return this.model.getChildCount(cell) > 0 && style[mxConstants.STYLE_FOLDABLE] != 0;
};

/**
 * Function: isValidDropTarget
 *
 * Returns true if the given cell is a valid drop target for the specified
 * cells. If <splitEnabled> is true then this returns <isSplitTarget> for
 * the given arguments else it returns true if the cell is not collapsed
 * and its child count is greater than 0.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents the possible drop target.
 * cells - <mxCells> that should be dropped into the target.
 * evt - Mouseevent that triggered the invocation.
 */
mxGraph.prototype.isValidDropTarget = function(cell, cells, evt)
{
	return cell != null && ((this.isSplitEnabled() &&
		this.isSplitTarget(cell, cells, evt)) || (!this.model.isEdge(cell) &&
		(this.isSwimlane(cell) || (this.model.getChildCount(cell) > 0 &&
		!this.isCellCollapsed(cell)))));
};

/**
 * Function: isSplitTarget
 *
 * Returns true if the given edge may be splitted into two edges with the
 * given cell as a new terminal between the two.
 * 
 * Parameters:
 * 
 * target - <mxCell> that represents the edge to be splitted.
 * cells - <mxCells> that should split the edge.
 * evt - Mouseevent that triggered the invocation.
 */
mxGraph.prototype.isSplitTarget = function(target, cells, evt)
{
	if (this.model.isEdge(target) && cells != null && cells.length == 1 &&
		this.isCellConnectable(cells[0]) && this.getEdgeValidationError(target,
			this.model.getTerminal(target, true), cells[0]) == null)
	{
		var src = this.model.getTerminal(target, true);
		var trg = this.model.getTerminal(target, false);

		return (!this.model.isAncestor(cells[0], src) &&
				!this.model.isAncestor(cells[0], trg));
	}

	return false;
};

/**
 * Function: getDropTarget
 * 
 * Returns the given cell if it is a drop target for the given cells or the
 * nearest ancestor that may be used as a drop target for the given cells.
 * If the given array contains a swimlane and <swimlaneNesting> is false
 * then this always returns null. If no cell is given, then the bottommost
 * swimlane at the location of the given event is returned.
 * 
 * This function should only be used if <isDropEnabled> returns true.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> which are to be dropped onto the target.
 * evt - Mouseevent for the drag and drop.
 * cell - <mxCell> that is under the mousepointer.
 * clone - Optional boolean to indicate of cells will be cloned.
 */
mxGraph.prototype.getDropTarget = function(cells, evt, cell, clone)
{
	if (!this.isSwimlaneNesting())
	{
		for (var i = 0; i < cells.length; i++)
		{
			if (this.isSwimlane(cells[i]))
			{
				return null;
			}
		}
	}

	var pt = mxUtils.convertPoint(this.container,
		mxEvent.getClientX(evt), mxEvent.getClientY(evt));
	pt.x -= this.panDx;
	pt.y -= this.panDy;
	var swimlane = this.getSwimlaneAt(pt.x, pt.y);
	
	if (cell == null)
	{
		cell = swimlane;
	}
	else if (swimlane != null)
	{
		// Checks if the cell is an ancestor of the swimlane
		// under the mouse and uses the swimlane in that case
		var tmp = this.model.getParent(swimlane);
		
		while (tmp != null && this.isSwimlane(tmp) && tmp != cell)
		{
			tmp = this.model.getParent(tmp);
		}
		
		if (tmp == cell)
		{
			cell = swimlane;
		}
	}
	
	while (cell != null && !this.isValidDropTarget(cell, cells, evt) &&
		!this.model.isLayer(cell))
	{
		cell = this.model.getParent(cell);
	}
	
	// Checks if parent is dropped into child if not cloning
	if (clone == null || !clone)
	{
		var parent = cell;
		
		while (parent != null && mxUtils.indexOf(cells, parent) < 0)
		{
			parent = this.model.getParent(parent);
		}
	}

	return (!this.model.isLayer(cell) && parent == null) ? cell : null;
};

/**
 * Group: Cell retrieval
 */

/**
 * Function: getDefaultParent
 * 
 * Returns <defaultParent> or <mxGraphView.currentRoot> or the first child
 * child of <mxGraphModel.root> if both are null. The value returned by
 * this function should be used as the parent for new cells (aka default
 * layer).
 */
mxGraph.prototype.getDefaultParent = function()
{
	var parent = this.getCurrentRoot();
	
	if (parent == null)
	{
		parent = this.defaultParent;
		
		if (parent == null)
		{
			var root = this.model.getRoot();
			parent = this.model.getChildAt(root, 0);
		}
	}
	
	return parent;
};

/**
 * Function: setDefaultParent
 * 
 * Sets the <defaultParent> to the given cell. Set this to null to return
 * the first child of the root in getDefaultParent.
 */
mxGraph.prototype.setDefaultParent = function(cell)
{
	this.defaultParent = cell;
};

/**
 * Function: getSwimlane
 * 
 * Returns the nearest ancestor of the given cell which is a swimlane, or
 * the given cell, if it is itself a swimlane.
 * 
 * Parameters:
 * 
 * cell - <mxCell> for which the ancestor swimlane should be returned.
 */
mxGraph.prototype.getSwimlane = function(cell)
{
	while (cell != null && !this.isSwimlane(cell))
	{
		cell = this.model.getParent(cell);
	}
	
	return cell;
};

/**
 * Function: getSwimlaneAt
 * 
 * Returns the bottom-most swimlane that intersects the given point (x, y)
 * in the cell hierarchy that starts at the given parent.
 * 
 * Parameters:
 * 
 * x - X-coordinate of the location to be checked.
 * y - Y-coordinate of the location to be checked.
 * parent - <mxCell> that should be used as the root of the recursion.
 * Default is <defaultParent>.
 */
mxGraph.prototype.getSwimlaneAt = function (x, y, parent)
{
	parent = parent || this.getDefaultParent();
	
	if (parent != null)
	{
		var childCount = this.model.getChildCount(parent);
		
		for (var i = 0; i < childCount; i++)
		{
			var child = this.model.getChildAt(parent, i);
			var result = this.getSwimlaneAt(x, y, child);
			
			if (result != null)
			{
				return result;
			}
			else if (this.isSwimlane(child))
			{
				var state = this.view.getState(child);
				
				if (this.intersects(state, x, y))
				{
					return child;
				}
			}
		}
	}
	
	return null;
};

/**
 * Function: getCellAt
 * 
 * Returns the bottom-most cell that intersects the given point (x, y) in
 * the cell hierarchy starting at the given parent. This will also return
 * swimlanes if the given location intersects the content area of the
 * swimlane. If this is not desired, then the <hitsSwimlaneContent> may be
 * used if the returned cell is a swimlane to determine if the location
 * is inside the content area or on the actual title of the swimlane.
 * 
 * Parameters:
 * 
 * x - X-coordinate of the location to be checked.
 * y - Y-coordinate of the location to be checked.
 * parent - <mxCell> that should be used as the root of the recursion.
 * Default is current root of the view or the root of the model.
 * vertices - Optional boolean indicating if vertices should be returned.
 * Default is true.
 * edges - Optional boolean indicating if edges should be returned. Default
 * is true.
 * ignoreFn - Optional function that returns true if cell should be ignored.
 * The function is passed the cell state and the x and y parameter.
 */
mxGraph.prototype.getCellAt = function(x, y, parent, vertices, edges, ignoreFn)
{
	vertices = (vertices != null) ? vertices : true;
	edges = (edges != null) ? edges : true;

	if (parent == null)
	{
		parent = this.getCurrentRoot();
		
		if (parent == null)
		{
			parent = this.getModel().getRoot();
		}
	}

	if (parent != null)
	{
		var childCount = this.model.getChildCount(parent);
		
		for (var i = childCount - 1; i >= 0; i--)
		{
			var cell = this.model.getChildAt(parent, i);
			var result = this.getCellAt(x, y, cell, vertices, edges, ignoreFn);
			
			if (result != null)
			{
				return result;
			}
			else if (this.isCellVisible(cell) && (edges && this.model.isEdge(cell) ||
				vertices && this.model.isVertex(cell)))
			{
				var state = this.view.getState(cell);

				if (state != null && (ignoreFn == null || !ignoreFn(state, x, y)) &&
					this.intersects(state, x, y))
				{
					return cell;
				}
			}
		}
	}
	
	return null;
};

/**
 * Function: intersects
 * 
 * Returns the bottom-most cell that intersects the given point (x, y) in
 * the cell hierarchy that starts at the given parent.
 * 
 * Parameters:
 * 
 * state - <mxCellState> that represents the cell state.
 * x - X-coordinate of the location to be checked.
 * y - Y-coordinate of the location to be checked.
 */
mxGraph.prototype.intersects = function(state, x, y)
{
	if (state != null)
	{
		var pts = state.absolutePoints;

		if (pts != null)
		{
			var t2 = this.tolerance * this.tolerance;
			var pt = pts[0];
			
			for (var i = 1; i < pts.length; i++)
			{
				var next = pts[i];
				var dist = mxUtils.ptSegDistSq(pt.x, pt.y, next.x, next.y, x, y);
				
				if (dist <= t2)
				{
					return true;
				}
				
				pt = next;
			}
		}
		else
		{
			var alpha = mxUtils.toRadians(mxUtils.getValue(state.style, mxConstants.STYLE_ROTATION) || 0);
			
			if (alpha != 0)
			{
				var cos = Math.cos(-alpha);
				var sin = Math.sin(-alpha);
				var cx = new mxPoint(state.getCenterX(), state.getCenterY());
				var pt = mxUtils.getRotatedPoint(new mxPoint(x, y), cos, sin, cx);
				x = pt.x;
				y = pt.y;
			}
			
			if (mxUtils.contains(state, x, y))
			{
				return true;
			}
		}
	}
	
	return false;
};

/**
 * Function: hitsSwimlaneContent
 * 
 * Returns true if the given coordinate pair is inside the content
 * are of the given swimlane.
 * 
 * Parameters:
 * 
 * swimlane - <mxCell> that specifies the swimlane.
 * x - X-coordinate of the mouse event.
 * y - Y-coordinate of the mouse event.
 */
mxGraph.prototype.hitsSwimlaneContent = function(swimlane, x, y)
{
	var state = this.getView().getState(swimlane);
	var size = this.getStartSize(swimlane);
	
	if (state != null)
	{
		var scale = this.getView().getScale();
		x -= state.x;
		y -= state.y;
		
		if (size.width > 0 && x > 0 && x > size.width * scale)
		{
			return true;
		}
		else if (size.height > 0 && y > 0 && y > size.height * scale)
		{
			return true;
		}
	}
	
	return false;
};

/**
 * Function: getChildVertices
 * 
 * Returns the visible child vertices of the given parent.
 * 
 * Parameters:
 * 
 * parent - <mxCell> whose children should be returned.
 */
mxGraph.prototype.getChildVertices = function(parent)
{
	return this.getChildCells(parent, true, false);
};
	
/**
 * Function: getChildEdges
 * 
 * Returns the visible child edges of the given parent.
 * 
 * Parameters:
 * 
 * parent - <mxCell> whose child vertices should be returned.
 */
mxGraph.prototype.getChildEdges = function(parent)
{
	return this.getChildCells(parent, false, true);
};

/**
 * Function: getChildCells
 * 
 * Returns the visible child vertices or edges in the given parent. If
 * vertices and edges is false, then all children are returned.
 * 
 * Parameters:
 * 
 * parent - <mxCell> whose children should be returned.
 * vertices - Optional boolean that specifies if child vertices should
 * be returned. Default is false.
 * edges - Optional boolean that specifies if child edges should
 * be returned. Default is false.
 */
mxGraph.prototype.getChildCells = function(parent, vertices, edges)
{
	parent = (parent != null) ? parent : this.getDefaultParent();
	vertices = (vertices != null) ? vertices : false;
	edges = (edges != null) ? edges : false;

	var cells = this.model.getChildCells(parent, vertices, edges);
	var result = [];

	// Filters out the non-visible child cells
	for (var i = 0; i < cells.length; i++)
	{
		if (this.isCellVisible(cells[i]))
		{
			result.push(cells[i]);
		}
	}

	return result;
};
	
/**
 * Function: getConnections
 * 
 * Returns all visible edges connected to the given cell without loops.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose connections should be returned.
 * parent - Optional parent of the opposite end for a connection to be
 * returned.
 */
mxGraph.prototype.getConnections = function(cell, parent)
{
	return this.getEdges(cell, parent, true, true, false);
};
	
/**
 * Function: getIncomingEdges
 * 
 * Returns the visible incoming edges for the given cell. If the optional
 * parent argument is specified, then only child edges of the given parent
 * are returned.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose incoming edges should be returned.
 * parent - Optional parent of the opposite end for an edge to be
 * returned.
 */
mxGraph.prototype.getIncomingEdges = function(cell, parent)
{
	return this.getEdges(cell, parent, true, false, false);
};
	
/**
 * Function: getOutgoingEdges
 * 
 * Returns the visible outgoing edges for the given cell. If the optional
 * parent argument is specified, then only child edges of the given parent
 * are returned.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose outgoing edges should be returned.
 * parent - Optional parent of the opposite end for an edge to be
 * returned.
 */
mxGraph.prototype.getOutgoingEdges = function(cell, parent)
{
	return this.getEdges(cell, parent, false, true, false);
};
	
/**
 * Function: getEdges
 * 
 * Returns the incoming and/or outgoing edges for the given cell.
 * If the optional parent argument is specified, then only edges are returned
 * where the opposite is in the given parent cell. If at least one of incoming
 * or outgoing is true, then loops are ignored, if both are false, then all
 * edges connected to the given cell are returned including loops.
 * 
 * Parameters:
 * 
 * cell - <mxCell> whose edges should be returned.
 * parent - Optional parent of the opposite end for an edge to be
 * returned.
 * incoming - Optional boolean that specifies if incoming edges should
 * be included in the result. Default is true.
 * outgoing - Optional boolean that specifies if outgoing edges should
 * be included in the result. Default is true.
 * includeLoops - Optional boolean that specifies if loops should be
 * included in the result. Default is true.
 * recurse - Optional boolean the specifies if the parent specified only 
 * need be an ancestral parent, true, or the direct parent, false.
 * Default is false
 */
mxGraph.prototype.getEdges = function(cell, parent, incoming, outgoing, includeLoops, recurse)
{
	incoming = (incoming != null) ? incoming : true;
	outgoing = (outgoing != null) ? outgoing : true;
	includeLoops = (includeLoops != null) ? includeLoops : true;
	recurse = (recurse != null) ? recurse : false;
	
	var edges = [];
	var isCollapsed = this.isCellCollapsed(cell);
	var childCount = this.model.getChildCount(cell);

	for (var i = 0; i < childCount; i++)
	{
		var child = this.model.getChildAt(cell, i);

		if (isCollapsed || !this.isCellVisible(child))
		{
			edges = edges.concat(this.model.getEdges(child, incoming, outgoing));
		}
	}

	edges = edges.concat(this.model.getEdges(cell, incoming, outgoing));
	var result = [];
	
	for (var i = 0; i < edges.length; i++)
	{
		var state = this.view.getState(edges[i]);
		
		var source = (state != null) ? state.getVisibleTerminal(true) : this.view.getVisibleTerminal(edges[i], true);
		var target = (state != null) ? state.getVisibleTerminal(false) : this.view.getVisibleTerminal(edges[i], false);

		if ((includeLoops && source == target) || ((source != target) && ((incoming &&
			target == cell && (parent == null || this.isValidAncestor(source, parent, recurse))) ||
			(outgoing && source == cell && (parent == null ||
					this.isValidAncestor(target, parent, recurse))))))
		{
			result.push(edges[i]);
		}
	}

	return result;
};

/**
 * Function: isValidAncestor
 * 
 * Returns whether or not the specified parent is a valid
 * ancestor of the specified cell, either direct or indirectly
 * based on whether ancestor recursion is enabled.
 * 
 * Parameters:
 * 
 * cell - <mxCell> the possible child cell
 * parent - <mxCell> the possible parent cell
 * recurse - boolean whether or not to recurse the child ancestors
 */
mxGraph.prototype.isValidAncestor = function(cell, parent, recurse)
{
	return (recurse ? this.model.isAncestor(parent, cell) : this.model
			.getParent(cell) == parent);
};

/**
 * Function: getOpposites
 * 
 * Returns all distinct visible opposite cells for the specified terminal
 * on the given edges.
 * 
 * Parameters:
 * 
 * edges - Array of <mxCells> that contains the edges whose opposite
 * terminals should be returned.
 * terminal - Terminal that specifies the end whose opposite should be
 * returned.
 * source - Optional boolean that specifies if source terminals should be
 * included in the result. Default is true.
 * targets - Optional boolean that specifies if targer terminals should be
 * included in the result. Default is true.
 */
mxGraph.prototype.getOpposites = function(edges, terminal, sources, targets)
{
	sources = (sources != null) ? sources : true;
	targets = (targets != null) ? targets : true;
	
	var terminals = [];
	
	// Fast lookup to avoid duplicates in terminals array
	var dict = new mxDictionary();
	
	if (edges != null)
	{
		for (var i = 0; i < edges.length; i++)
		{
			var state = this.view.getState(edges[i]);
			
			var source = (state != null) ? state.getVisibleTerminal(true) : this.view.getVisibleTerminal(edges[i], true);
			var target = (state != null) ? state.getVisibleTerminal(false) : this.view.getVisibleTerminal(edges[i], false);
			
			// Checks if the terminal is the source of the edge and if the
			// target should be stored in the result
			if (source == terminal && target != null && target != terminal && targets)
			{
				if (!dict.get(target))
				{
					dict.put(target, true);
					terminals.push(target);
				}
			}
			
			// Checks if the terminal is the taget of the edge and if the
			// source should be stored in the result
			else if (target == terminal && source != null && source != terminal && sources)
			{
				if (!dict.get(source))
				{
					dict.put(source, true);
					terminals.push(source);
				}
			}
		}
	}
	
	return terminals;
};

/**
 * Function: getEdgesBetween
 * 
 * Returns the edges between the given source and target. This takes into
 * account collapsed and invisible cells and returns the connected edges
 * as displayed on the screen.
 * 
 * Parameters:
 * 
 * source -
 * target -
 * directed -
 */
mxGraph.prototype.getEdgesBetween = function(source, target, directed)
{
	directed = (directed != null) ? directed : false;
	var edges = this.getEdges(source);
	var result = [];

	// Checks if the edge is connected to the correct
	// cell and returns the first match
	for (var i = 0; i < edges.length; i++)
	{
		var state = this.view.getState(edges[i]);
		
		var src = (state != null) ? state.getVisibleTerminal(true) : this.view.getVisibleTerminal(edges[i], true);
		var trg = (state != null) ? state.getVisibleTerminal(false) : this.view.getVisibleTerminal(edges[i], false);

		if ((src == source && trg == target) || (!directed && src == target && trg == source))
		{
			result.push(edges[i]);
		}
	}

	return result;
};

/**
 * Function: getPointForEvent
 * 
 * Returns an <mxPoint> representing the given event in the unscaled,
 * non-translated coordinate space of <container> and applies the grid.
 * 
 * Parameters:
 * 
 * evt - Mousevent that contains the mouse pointer location.
 * addOffset - Optional boolean that specifies if the position should be
 * offset by half of the <gridSize>. Default is true.
 */
 mxGraph.prototype.getPointForEvent = function(evt, addOffset)
 {
	var p = mxUtils.convertPoint(this.container,
		mxEvent.getClientX(evt), mxEvent.getClientY(evt));
	
	var s = this.view.scale;
	var tr = this.view.translate;
	var off = (addOffset != false) ? this.gridSize / 2 : 0;
	
	p.x = this.snap(p.x / s - tr.x - off);
	p.y = this.snap(p.y / s - tr.y - off);
	
	return p;
 };

/**
 * Function: getCells
 * 
 * Returns the child vertices and edges of the given parent that are contained
 * in the given rectangle. The result is added to the optional result array,
 * which is returned. If no result array is specified then a new array is
 * created and returned.
 * 
 * Parameters:
 * 
 * x - X-coordinate of the rectangle.
 * y - Y-coordinate of the rectangle.
 * width - Width of the rectangle.
 * height - Height of the rectangle.
 * parent - <mxCell> that should be used as the root of the recursion.
 * Default is current root of the view or the root of the model.
 * result - Optional array to store the result in.
 */
mxGraph.prototype.getCells = function(x, y, width, height, parent, result)
{
	result = (result != null) ? result : [];
	
	if (width > 0 || height > 0)
	{
		var model = this.getModel();
		var right = x + width;
		var bottom = y + height;

		if (parent == null)
		{
			parent = this.getCurrentRoot();
			
			if (parent == null)
			{
				parent = model.getRoot();
			}
		}
		
		if (parent != null)
		{
			var childCount = model.getChildCount(parent);
			
			for (var i = 0; i < childCount; i++)
			{
				var cell = model.getChildAt(parent, i);
				var state = this.view.getState(cell);
				
				if (state != null && this.isCellVisible(cell))
				{
					var deg = mxUtils.getValue(state.style, mxConstants.STYLE_ROTATION) || 0;
					var box = state;
					
					if (deg != 0)
					{
						box = mxUtils.getBoundingBox(box, deg);
					}
					
					if ((model.isEdge(cell) || model.isVertex(cell)) &&
						box.x >= x && box.y + box.height <= bottom &&
						box.y >= y && box.x + box.width <= right)
					{
						result.push(cell);
					}
					else
					{
						this.getCells(x, y, width, height, cell, result);
					}
				}
			}
		}
	}
	
	return result;
};

/**
 * Function: getCellsBeyond
 * 
 * Returns the children of the given parent that are contained in the
 * halfpane from the given point (x0, y0) rightwards or downwards
 * depending on rightHalfpane and bottomHalfpane.
 * 
 * Parameters:
 * 
 * x0 - X-coordinate of the origin.
 * y0 - Y-coordinate of the origin.
 * parent - Optional <mxCell> whose children should be checked. Default is
 * <defaultParent>.
 * rightHalfpane - Boolean indicating if the cells in the right halfpane
 * from the origin should be returned.
 * bottomHalfpane - Boolean indicating if the cells in the bottom halfpane
 * from the origin should be returned.
 */
mxGraph.prototype.getCellsBeyond = function(x0, y0, parent, rightHalfpane, bottomHalfpane)
{
	var result = [];
	
	if (rightHalfpane || bottomHalfpane)
	{
		if (parent == null)
		{
			parent = this.getDefaultParent();
		}
		
		if (parent != null)
		{
			var childCount = this.model.getChildCount(parent);
			
			for (var i = 0; i < childCount; i++)
			{
				var child = this.model.getChildAt(parent, i);
				var state = this.view.getState(child);
				
				if (this.isCellVisible(child) && state != null)
				{
					if ((!rightHalfpane || state.x >= x0) &&
						(!bottomHalfpane || state.y >= y0))
					{
						result.push(child);
					}
				}
			}
		}
	}
	
	return result;
};

/**
 * Function: findTreeRoots
 * 
 * Returns all children in the given parent which do not have incoming
 * edges. If the result is empty then the with the greatest difference
 * between incoming and outgoing edges is returned.
 * 
 * Parameters:
 * 
 * parent - <mxCell> whose children should be checked.
 * isolate - Optional boolean that specifies if edges should be ignored if
 * the opposite end is not a child of the given parent cell. Default is
 * false.
 * invert - Optional boolean that specifies if outgoing or incoming edges
 * should be counted for a tree root. If false then outgoing edges will be
 * counted. Default is false.
 */
mxGraph.prototype.findTreeRoots = function(parent, isolate, invert)
{
	isolate = (isolate != null) ? isolate : false;
	invert = (invert != null) ? invert : false;
	var roots = [];
	
	if (parent != null)
	{
		var model = this.getModel();
		var childCount = model.getChildCount(parent);
		var best = null;
		var maxDiff = 0;
		
		for (var i=0; i<childCount; i++)
		{
			var cell = model.getChildAt(parent, i);
			
			if (this.model.isVertex(cell) && this.isCellVisible(cell))
			{
				var conns = this.getConnections(cell, (isolate) ? parent : null);
				var fanOut = 0;
				var fanIn = 0;
				
				for (var j = 0; j < conns.length; j++)
				{
					var src = this.view.getVisibleTerminal(conns[j], true);

                    if (src == cell)
                    {
                        fanOut++;
                    }
                    else
                    {
                        fanIn++;
                    }
				}
				
				if ((invert && fanOut == 0 && fanIn > 0) ||
					(!invert && fanIn == 0 && fanOut > 0))
				{
					roots.push(cell);
				}
				
				var diff = (invert) ? fanIn - fanOut : fanOut - fanIn;
				
				if (diff > maxDiff)
				{
					maxDiff = diff;
					best = cell;
				}
			}
		}
		
		if (roots.length == 0 && best != null)
		{
			roots.push(best);
		}
	}
	
	return roots;
};

/**
 * Function: traverse
 * 
 * Traverses the (directed) graph invoking the given function for each
 * visited vertex and edge. The function is invoked with the current vertex
 * and the incoming edge as a parameter. This implementation makes sure
 * each vertex is only visited once. The function may return false if the
 * traversal should stop at the given vertex.
 * 
 * Example:
 * 
 * (code)
 * mxLog.show();
 * var cell = graph.getSelectionCell();
 * graph.traverse(cell, false, function(vertex, edge)
 * {
 *   mxLog.debug(graph.getLabel(vertex));
 * });
 * (end)
 * 
 * Parameters:
 * 
 * vertex - <mxCell> that represents the vertex where the traversal starts.
 * directed - Optional boolean indicating if edges should only be traversed
 * from source to target. Default is true.
 * func - Visitor function that takes the current vertex and the incoming
 * edge as arguments. The traversal stops if the function returns false.
 * edge - Optional <mxCell> that represents the incoming edge. This is
 * null for the first step of the traversal.
 * visited - Optional <mxDictionary> from cells to true for the visited cells.
 * inverse - Optional boolean to traverse in inverse direction. Default is false.
 * This is ignored if directed is false.
 */
mxGraph.prototype.traverse = function(vertex, directed, func, edge, visited, inverse)
{
	if (func != null && vertex != null)
	{
		directed = (directed != null) ? directed : true;
		inverse = (inverse != null) ? inverse : false;
		visited = visited || new mxDictionary();
		
		if (!visited.get(vertex))
		{
			visited.put(vertex, true);
			var result = func(vertex, edge);
			
			if (result == null || result)
			{
				var edgeCount = this.model.getEdgeCount(vertex);
				
				if (edgeCount > 0)
				{
					for (var i = 0; i < edgeCount; i++)
					{
						var e = this.model.getEdgeAt(vertex, i);
						var isSource = this.model.getTerminal(e, true) == vertex;
						
						if (!directed || (!inverse == isSource))
						{
							var next = this.model.getTerminal(e, !isSource);
							this.traverse(next, directed, func, e, visited, inverse);
						}
					}
				}
			}
		}
	}
};

/**
 * Group: Selection
 */

/**
 * Function: isCellSelected
 * 
 * Returns true if the given cell is selected.
 * 
 * Parameters:
 * 
 * cell - <mxCell> for which the selection state should be returned.
 */
mxGraph.prototype.isCellSelected = function(cell)
{
	return this.getSelectionModel().isSelected(cell);
};

/**
 * Function: isSelectionEmpty
 * 
 * Returns true if the selection is empty.
 */
mxGraph.prototype.isSelectionEmpty = function()
{
	return this.getSelectionModel().isEmpty();
};

/**
 * Function: clearSelection
 * 
 * Clears the selection using <mxGraphSelectionModel.clear>.
 */
mxGraph.prototype.clearSelection = function()
{
	return this.getSelectionModel().clear();
};

/**
 * Function: getSelectionCount
 * 
 * Returns the number of selected cells.
 */
mxGraph.prototype.getSelectionCount = function()
{
	return this.getSelectionModel().cells.length;
};
	
/**
 * Function: getSelectionCell
 * 
 * Returns the first cell from the array of selected <mxCells>.
 */
mxGraph.prototype.getSelectionCell = function()
{
	return this.getSelectionModel().cells[0];
};

/**
 * Function: getSelectionCells
 * 
 * Returns the array of selected <mxCells>.
 */
mxGraph.prototype.getSelectionCells = function()
{
	return this.getSelectionModel().cells.slice();
};

/**
 * Function: setSelectionCell
 * 
 * Sets the selection cell.
 * 
 * Parameters:
 * 
 * cell - <mxCell> to be selected.
 */
mxGraph.prototype.setSelectionCell = function(cell)
{
	this.getSelectionModel().setCell(cell);
};

/**
 * Function: setSelectionCells
 * 
 * Sets the selection cell.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to be selected.
 */
mxGraph.prototype.setSelectionCells = function(cells)
{
	this.getSelectionModel().setCells(cells);
};

/**
 * Function: addSelectionCell
 * 
 * Adds the given cell to the selection.
 * 
 * Parameters:
 * 
 * cell - <mxCell> to be add to the selection.
 */
mxGraph.prototype.addSelectionCell = function(cell)
{
	this.getSelectionModel().addCell(cell);
};

/**
 * Function: addSelectionCells
 * 
 * Adds the given cells to the selection.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to be added to the selection.
 */
mxGraph.prototype.addSelectionCells = function(cells)
{
	this.getSelectionModel().addCells(cells);
};

/**
 * Function: removeSelectionCell
 * 
 * Removes the given cell from the selection.
 * 
 * Parameters:
 * 
 * cell - <mxCell> to be removed from the selection.
 */
mxGraph.prototype.removeSelectionCell = function(cell)
{
	this.getSelectionModel().removeCell(cell);
};

/**
 * Function: removeSelectionCells
 * 
 * Removes the given cells from the selection.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to be removed from the selection.
 */
mxGraph.prototype.removeSelectionCells = function(cells)
{
	this.getSelectionModel().removeCells(cells);
};

/**
 * Function: selectRegion
 * 
 * Selects and returns the cells inside the given rectangle for the
 * specified event.
 * 
 * Parameters:
 * 
 * rect - <mxRectangle> that represents the region to be selected.
 * evt - Mouseevent that triggered the selection.
 */
mxGraph.prototype.selectRegion = function(rect, evt)
{
	var cells = this.getCells(rect.x, rect.y, rect.width, rect.height);
	this.selectCellsForEvent(cells, evt);
	
	return cells;
};

/**
 * Function: selectNextCell
 * 
 * Selects the next cell.
 */
mxGraph.prototype.selectNextCell = function()
{
	this.selectCell(true);
};

/**
 * Function: selectPreviousCell
 * 
 * Selects the previous cell.
 */
mxGraph.prototype.selectPreviousCell = function()
{
	this.selectCell();
};

/**
 * Function: selectParentCell
 * 
 * Selects the parent cell.
 */
mxGraph.prototype.selectParentCell = function()
{
	this.selectCell(false, true);
};

/**
 * Function: selectChildCell
 * 
 * Selects the first child cell.
 */
mxGraph.prototype.selectChildCell = function()
{
	this.selectCell(false, false, true);
};

/**
 * Function: selectCell
 * 
 * Selects the next, parent, first child or previous cell, if all arguments
 * are false.
 * 
 * Parameters:
 * 
 * isNext - Boolean indicating if the next cell should be selected.
 * isParent - Boolean indicating if the parent cell should be selected.
 * isChild - Boolean indicating if the first child cell should be selected.
 */
mxGraph.prototype.selectCell = function(isNext, isParent, isChild)
{
	var sel = this.selectionModel;
	var cell = (sel.cells.length > 0) ? sel.cells[0] : null;
	
	if (sel.cells.length > 1)
	{
		sel.clear();
	}
	
	var parent = (cell != null) ?
		this.model.getParent(cell) :
		this.getDefaultParent();
	
	var childCount = this.model.getChildCount(parent);
	
	if (cell == null && childCount > 0)
	{
		var child = this.model.getChildAt(parent, 0);
		this.setSelectionCell(child);
	}
	else if ((cell == null || isParent) &&
		this.view.getState(parent) != null &&
		this.model.getGeometry(parent) != null)
	{
		if (this.getCurrentRoot() != parent)
		{
			this.setSelectionCell(parent);
		}
	}
	else if (cell != null && isChild)
	{
		var tmp = this.model.getChildCount(cell);
		
		if (tmp > 0)
		{
			var child = this.model.getChildAt(cell, 0);
			this.setSelectionCell(child);
		}
	}
	else if (childCount > 0)
	{
		var i = parent.getIndex(cell);
		
		if (isNext)
		{
			i++;
			var child = this.model.getChildAt(parent, i % childCount);
			this.setSelectionCell(child);
		}
		else
		{
			i--;
			var index =  (i < 0) ? childCount - 1 : i;
			var child = this.model.getChildAt(parent, index);
			this.setSelectionCell(child);
		}
	}
};

/**
 * Function: selectAll
 * 
 * Selects all children of the given parent cell or the children of the
 * default parent if no parent is specified. To select leaf vertices and/or
 * edges use <selectCells>.
 * 
 * Parameters:
 * 
 * parent - Optional <mxCell> whose children should be selected.
 * Default is <defaultParent>.
 * descendants - Optional boolean specifying whether all descendants should be
 * selected. Default is false.
 */
mxGraph.prototype.selectAll = function(parent, descendants)
{
	parent = parent || this.getDefaultParent();
	
	var cells = (descendants) ? this.model.filterDescendants(function(cell)
	{
		return cell != parent;
	}, parent) : this.model.getChildren(parent);
	
	if (cells != null)
	{
		this.setSelectionCells(cells);
	}
};

/**
 * Function: selectVertices
 * 
 * Select all vertices inside the given parent or the default parent.
 */
mxGraph.prototype.selectVertices = function(parent)
{
	this.selectCells(true, false, parent);
};

/**
 * Function: selectVertices
 * 
 * Select all vertices inside the given parent or the default parent.
 */
mxGraph.prototype.selectEdges = function(parent)
{
	this.selectCells(false, true, parent);
};

/**
 * Function: selectCells
 * 
 * Selects all vertices and/or edges depending on the given boolean
 * arguments recursively, starting at the given parent or the default
 * parent if no parent is specified. Use <selectAll> to select all cells.
 * For vertices, only cells with no children are selected.
 * 
 * Parameters:
 * 
 * vertices - Boolean indicating if vertices should be selected.
 * edges - Boolean indicating if edges should be selected.
 * parent - Optional <mxCell> that acts as the root of the recursion.
 * Default is <defaultParent>.
 */
mxGraph.prototype.selectCells = function(vertices, edges, parent)
{
	parent = parent || this.getDefaultParent();
	
	var filter = mxUtils.bind(this, function(cell)
	{
		return this.view.getState(cell) != null &&
			((this.model.getChildCount(cell) == 0 && this.model.isVertex(cell) && vertices
			&& !this.model.isEdge(this.model.getParent(cell))) ||
			(this.model.isEdge(cell) && edges));
	});
	
	var cells = this.model.filterDescendants(filter, parent);
	this.setSelectionCells(cells);
};

/**
 * Function: selectCellForEvent
 * 
 * Selects the given cell by either adding it to the selection or
 * replacing the selection depending on whether the given mouse event is a
 * toggle event.
 * 
 * Parameters:
 * 
 * cell - <mxCell> to be selected.
 * evt - Optional mouseevent that triggered the selection.
 */
mxGraph.prototype.selectCellForEvent = function(cell, evt)
{
	var isSelected = this.isCellSelected(cell);
	
	if (this.isToggleEvent(evt))
	{
		if (isSelected)
		{
			this.removeSelectionCell(cell);
		}
		else
		{
			this.addSelectionCell(cell);
		}
	}
	else if (!isSelected || this.getSelectionCount() != 1)
	{
		this.setSelectionCell(cell);
	}
};

/**
 * Function: selectCellsForEvent
 * 
 * Selects the given cells by either adding them to the selection or
 * replacing the selection depending on whether the given mouse event is a
 * toggle event.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> to be selected.
 * evt - Optional mouseevent that triggered the selection.
 */
mxGraph.prototype.selectCellsForEvent = function(cells, evt)
{
	if (this.isToggleEvent(evt))
	{
		this.addSelectionCells(cells);
	}
	else
	{
		this.setSelectionCells(cells);
	}
};

/**
 * Group: Selection state
 */

/**
 * Function: createHandler
 * 
 * Creates a new handler for the given cell state. This implementation
 * returns a new <mxEdgeHandler> of the corresponding cell is an edge,
 * otherwise it returns an <mxVertexHandler>.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose handler should be created.
 */
mxGraph.prototype.createHandler = function(state)
{
	var result = null;
	
	if (state != null)
	{
		if (this.model.isEdge(state.cell))
		{
			var source = state.getVisibleTerminalState(true);
			var target = state.getVisibleTerminalState(false);
			var geo = this.getCellGeometry(state.cell);
			
			var edgeStyle = this.view.getEdgeStyle(state, (geo != null) ? geo.points : null, source, target);
			result = this.createEdgeHandler(state, edgeStyle);
		}
		else
		{
			result = this.createVertexHandler(state);
		}
	}
	
	return result;
};

/**
 * Function: createVertexHandler
 * 
 * Hooks to create a new <mxVertexHandler> for the given <mxCellState>.
 * 
 * Parameters:
 * 
 * state - <mxCellState> to create the handler for.
 */
mxGraph.prototype.createVertexHandler = function(state)
{
	return new mxVertexHandler(state);
};

/**
 * Function: createEdgeHandler
 * 
 * Hooks to create a new <mxEdgeHandler> for the given <mxCellState>.
 * 
 * Parameters:
 * 
 * state - <mxCellState> to create the handler for.
 */
mxGraph.prototype.createEdgeHandler = function(state, edgeStyle)
{
	var result = null;
	
	if (edgeStyle == mxEdgeStyle.Loop ||
		edgeStyle == mxEdgeStyle.ElbowConnector ||
		edgeStyle == mxEdgeStyle.SideToSide ||
		edgeStyle == mxEdgeStyle.TopToBottom)
	{
		result = this.createElbowEdgeHandler(state);
	}
	else if (edgeStyle == mxEdgeStyle.SegmentConnector || 
			edgeStyle == mxEdgeStyle.OrthConnector)
	{
		result = this.createEdgeSegmentHandler(state);
	}
	else
	{
		result = new mxEdgeHandler(state);
	}
	
	return result;
};

/**
 * Function: createEdgeSegmentHandler
 * 
 * Hooks to create a new <mxEdgeSegmentHandler> for the given <mxCellState>.
 * 
 * Parameters:
 * 
 * state - <mxCellState> to create the handler for.
 */
mxGraph.prototype.createEdgeSegmentHandler = function(state)
{
	return new mxEdgeSegmentHandler(state);
};

/**
 * Function: createElbowEdgeHandler
 * 
 * Hooks to create a new <mxElbowEdgeHandler> for the given <mxCellState>.
 * 
 * Parameters:
 * 
 * state - <mxCellState> to create the handler for.
 */
mxGraph.prototype.createElbowEdgeHandler = function(state)
{
	return new mxElbowEdgeHandler(state);
};

/**
 * Group: Graph events
 */

/**
 * Function: addMouseListener
 * 
 * Adds a listener to the graph event dispatch loop. The listener
 * must implement the mouseDown, mouseMove and mouseUp methods
 * as shown in the <mxMouseEvent> class.
 * 
 * Parameters:
 * 
 * listener - Listener to be added to the graph event listeners.
 */
mxGraph.prototype.addMouseListener = function(listener)
{
	if (this.mouseListeners == null)
	{
		this.mouseListeners = [];
	}
	
	this.mouseListeners.push(listener);
};

/**
 * Function: removeMouseListener
 * 
 * Removes the specified graph listener.
 * 
 * Parameters:
 * 
 * listener - Listener to be removed from the graph event listeners.
 */
mxGraph.prototype.removeMouseListener = function(listener)
{
	if (this.mouseListeners != null)
	{
		for (var i = 0; i < this.mouseListeners.length; i++)
		{
			if (this.mouseListeners[i] == listener)
			{
				this.mouseListeners.splice(i, 1);
				break;
			}
		}
	}
};

/**
 * Function: updateMouseEvent
 * 
 * Sets the graphX and graphY properties if the given <mxMouseEvent> if
 * required and returned the event.
 * 
 * Parameters:
 * 
 * me - <mxMouseEvent> to be updated.
 * evtName - Name of the mouse event.
 */
mxGraph.prototype.updateMouseEvent = function(me, evtName)
{
	if (me.graphX == null || me.graphY == null)
	{
		var pt = mxUtils.convertPoint(this.container, me.getX(), me.getY());
		
		me.graphX = pt.x - this.panDx;
		me.graphY = pt.y - this.panDy;
		
		// Searches for rectangles using method if native hit detection is disabled on shape
		if (me.getCell() == null && this.isMouseDown && evtName == mxEvent.MOUSE_MOVE)
		{
			me.state = this.view.getState(this.getCellAt(pt.x, pt.y, null, null, null, function(state)
			{
				return state.shape == null || state.shape.paintBackground != mxRectangleShape.prototype.paintBackground ||
					mxUtils.getValue(state.style, mxConstants.STYLE_POINTER_EVENTS, '1') == '1' ||
					(state.shape.fill != null && state.shape.fill != mxConstants.NONE);
			}));
		}
	}
	
	return me;
};

/**
 * Function: getStateForEvent
 * 
 * Returns the state for the given touch event.
 */
mxGraph.prototype.getStateForTouchEvent = function(evt)
{
	var x = mxEvent.getClientX(evt);
	var y = mxEvent.getClientY(evt);
	
	// Dispatches the drop event to the graph which
	// consumes and executes the source function
	var pt = mxUtils.convertPoint(this.container, x, y);

	return this.view.getState(this.getCellAt(pt.x, pt.y));
};

/**
 * Function: isEventIgnored
 * 
 * Returns true if the event should be ignored in <fireMouseEvent>.
 */
mxGraph.prototype.isEventIgnored = function(evtName, me, sender)
{
	var mouseEvent = mxEvent.isMouseEvent(me.getEvent());
	var result = false;

	// Drops events that are fired more than once
	if (me.getEvent() == this.lastEvent)
	{
		result = true;
	}
	else
	{
		this.lastEvent = me.getEvent();
	}

	// Installs event listeners to capture the complete gesture from the event source
	// for non-MS touch events as a workaround for all events for the same geture being
	// fired from the event source even if that was removed from the DOM.
	if (this.eventSource != null && evtName != mxEvent.MOUSE_MOVE)
	{
		mxEvent.removeGestureListeners(this.eventSource, null, this.mouseMoveRedirect, this.mouseUpRedirect);
		this.mouseMoveRedirect = null;
		this.mouseUpRedirect = null;
		this.eventSource = null;
	}
	else if (this.eventSource != null && me.getSource() != this.eventSource)
	{
		result = true;
	}
	else if (mxClient.IS_TOUCH && evtName == mxEvent.MOUSE_DOWN && !mouseEvent && !mxEvent.isPenEvent(me.getEvent()))
	{
		this.eventSource = me.getSource();

		this.mouseMoveRedirect = mxUtils.bind(this, function(evt)
		{
			this.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt, this.getStateForTouchEvent(evt)));
		});
		this.mouseUpRedirect = mxUtils.bind(this, function(evt)
		{
			this.fireMouseEvent(mxEvent.MOUSE_UP, new mxMouseEvent(evt, this.getStateForTouchEvent(evt)));
		});
		
		mxEvent.addGestureListeners(this.eventSource, null, this.mouseMoveRedirect, this.mouseUpRedirect);
	}

	// Factored out the workarounds for FF to make it easier to override/remove
	// Note this method has side-effects!
	if (this.isSyntheticEventIgnored(evtName, me, sender))
	{
		result = true;
	}

	// Never fires mouseUp/-Down for double clicks
	if (!mxEvent.isPopupTrigger(this.lastEvent) && evtName != mxEvent.MOUSE_MOVE && this.lastEvent.detail == 2)
	{
		return true;
	}
	
	// Filters out of sequence events or mixed event types during a gesture
	if (evtName == mxEvent.MOUSE_UP && this.isMouseDown)
	{
		this.isMouseDown = false;
	}
	else if (evtName == mxEvent.MOUSE_DOWN && !this.isMouseDown)
	{
		this.isMouseDown = true;
		this.isMouseTrigger = mouseEvent;
	}
	// Drops mouse events that are fired during touch gestures as a workaround for Webkit
	// and mouse events that are not in sync with the current internal button state
	else if (!result && (((!mxClient.IS_FF || evtName != mxEvent.MOUSE_MOVE) &&
		this.isMouseDown && this.isMouseTrigger != mouseEvent) ||
		(evtName == mxEvent.MOUSE_DOWN && this.isMouseDown) ||
		(evtName == mxEvent.MOUSE_UP && !this.isMouseDown)))
	{
		result = true;
	}
	
	if (!result && evtName == mxEvent.MOUSE_DOWN)
	{
		this.lastMouseX = me.getX();
		this.lastMouseY = me.getY();
	}

	return result;
};

/**
 * Function: isSyntheticEventIgnored
 * 
 * Hook for ignoring synthetic mouse events after touchend in Firefox.
 */
mxGraph.prototype.isSyntheticEventIgnored = function(evtName, me, sender)
{
	var result = false;
	var mouseEvent = mxEvent.isMouseEvent(me.getEvent());
	
	// LATER: This does not cover all possible cases that can go wrong in FF
	if (this.ignoreMouseEvents && mouseEvent && evtName != mxEvent.MOUSE_MOVE)
	{
		this.ignoreMouseEvents = evtName != mxEvent.MOUSE_UP;
		result = true;
	}
	else if (mxClient.IS_FF && !mouseEvent && evtName == mxEvent.MOUSE_UP)
	{
		this.ignoreMouseEvents = true;
	}
	
	return result;
};

/**
 * Function: isEventSourceIgnored
 * 
 * Returns true if the event should be ignored in <fireMouseEvent>. This
 * implementation returns true for select, option and input (if not of type
 * checkbox, radio, button, submit or file) event sources if the event is not
 * a mouse event or a left mouse button press event.
 * 
 * Parameters:
 * 
 * evtName - The name of the event.
 * me - <mxMouseEvent> that should be ignored.
 */
mxGraph.prototype.isEventSourceIgnored = function(evtName, me)
{
	var source = me.getSource();
	var name = (source.nodeName != null) ? source.nodeName.toLowerCase() : '';
	var candidate = !mxEvent.isMouseEvent(me.getEvent()) || mxEvent.isLeftMouseButton(me.getEvent());
	
	return evtName == mxEvent.MOUSE_DOWN && candidate && (name == 'select' || name == 'option' ||
		(name == 'input' && source.type != 'checkbox' && source.type != 'radio' &&
		source.type != 'button' && source.type != 'submit' && source.type != 'file'));
};

/**
 * Function: getEventState
 * 
 * Returns the <mxCellState> to be used when firing the mouse event for the
 * given state. This implementation returns the given state.
 * 
 * Parameters:
 * 
 * <mxCellState> - State whose event source should be returned.
 */
mxGraph.prototype.getEventState = function(state)
{
	return state;
};

/**
 * Function: fireMouseEvent
 * 
 * Dispatches the given event in the graph event dispatch loop. Possible
 * event names are <mxEvent.MOUSE_DOWN>, <mxEvent.MOUSE_MOVE> and
 * <mxEvent.MOUSE_UP>. All listeners are invoked for all events regardless
 * of the consumed state of the event.
 * 
 * Parameters:
 * 
 * evtName - String that specifies the type of event to be dispatched.
 * me - <mxMouseEvent> to be fired.
 * sender - Optional sender argument. Default is this.
 */
mxGraph.prototype.fireMouseEvent = function(evtName, me, sender)
{
	if (this.isEventSourceIgnored(evtName, me))
	{
		if (this.tooltipHandler != null)
		{
			this.tooltipHandler.hide();
		}
		
		return;
	}
	
	if (sender == null)
	{
		sender = this;
	}

	// Updates the graph coordinates in the event
	me = this.updateMouseEvent(me, evtName);

	// Detects and processes double taps for touch-based devices which do not have native double click events
	// or where detection of double click is not always possible (quirks, IE10+). Note that this can only handle
	// double clicks on cells because the sequence of events in IE prevents detection on the background, it fires
	// two mouse ups, one of which without a cell but no mousedown for the second click which means we cannot
	// detect which mouseup(s) are part of the first click, ie we do not know when the first click ends.
	if ((!this.nativeDblClickEnabled && !mxEvent.isPopupTrigger(me.getEvent())) || (this.doubleTapEnabled &&
		mxClient.IS_TOUCH && (mxEvent.isTouchEvent(me.getEvent()) || mxEvent.isPenEvent(me.getEvent()))))
	{
		var currentTime = new Date().getTime();
		
		// NOTE: Second mouseDown for double click missing in quirks mode
		if ((!mxClient.IS_QUIRKS && evtName == mxEvent.MOUSE_DOWN) || (mxClient.IS_QUIRKS && evtName == mxEvent.MOUSE_UP && !this.fireDoubleClick))
		{
			if (this.lastTouchEvent != null && this.lastTouchEvent != me.getEvent() &&
				currentTime - this.lastTouchTime < this.doubleTapTimeout &&
				Math.abs(this.lastTouchX - me.getX()) < this.doubleTapTolerance &&
				Math.abs(this.lastTouchY - me.getY()) < this.doubleTapTolerance &&
				this.doubleClickCounter < 2)
			{
				this.doubleClickCounter++;
				var doubleClickFired = false;
				
				if (evtName == mxEvent.MOUSE_UP)
				{
					if (me.getCell() == this.lastTouchCell && this.lastTouchCell != null)
					{
						this.lastTouchTime = 0;
						var cell = this.lastTouchCell;
						this.lastTouchCell = null;

						// Fires native dblclick event via event source
						// NOTE: This fires two double click events on edges in quirks mode. While
						// trying to fix this, we realized that nativeDoubleClick can be disabled for
						// quirks and IE10+ (or we didn't find the case mentioned above where it
						// would not work), ie. all double clicks seem to be working without this.
						if (mxClient.IS_QUIRKS)
						{
							me.getSource().fireEvent('ondblclick');
						}
						
						this.dblClick(me.getEvent(), cell);
						doubleClickFired = true;
					}
				}
				else
				{
					this.fireDoubleClick = true;
					this.lastTouchTime = 0;
				}

				// Do not ignore mouse up in quirks in this case
				if (!mxClient.IS_QUIRKS || doubleClickFired)
				{
					mxEvent.consume(me.getEvent());
					return;
				}
			}
			else if (this.lastTouchEvent == null || this.lastTouchEvent != me.getEvent())
			{
				this.lastTouchCell = me.getCell();
				this.lastTouchX = me.getX();
				this.lastTouchY = me.getY();
				this.lastTouchTime = currentTime;
				this.lastTouchEvent = me.getEvent();
				this.doubleClickCounter = 0;
			}
		}
		else if ((this.isMouseDown || evtName == mxEvent.MOUSE_UP) && this.fireDoubleClick)
		{
			this.fireDoubleClick = false;
			var cell = this.lastTouchCell;
			this.lastTouchCell = null;
			this.isMouseDown = false;
			
			// Workaround for Chrome/Safari not firing native double click events for double touch on background
			var valid = (cell != null) || ((mxEvent.isTouchEvent(me.getEvent()) || mxEvent.isPenEvent(me.getEvent())) &&
				(mxClient.IS_GC || mxClient.IS_SF));
			
			if (valid && Math.abs(this.lastTouchX - me.getX()) < this.doubleTapTolerance &&
				Math.abs(this.lastTouchY - me.getY()) < this.doubleTapTolerance)
			{
				this.dblClick(me.getEvent(), cell);
			}
			else
			{
				mxEvent.consume(me.getEvent());
			}
			
			return;
		}
	}

	if (!this.isEventIgnored(evtName, me, sender))
	{
		// Updates the event state via getEventState
		me.state = this.getEventState(me.getState());
		this.fireEvent(new mxEventObject(mxEvent.FIRE_MOUSE_EVENT, 'eventName', evtName, 'event', me));
		
		if ((mxClient.IS_OP || mxClient.IS_SF || mxClient.IS_GC || mxClient.IS_IE11 ||
			(mxClient.IS_IE && mxClient.IS_SVG) || me.getEvent().target != this.container))
		{
			if (evtName == mxEvent.MOUSE_MOVE && this.isMouseDown && this.autoScroll && !mxEvent.isMultiTouchEvent(me.getEvent))
			{
				this.scrollPointToVisible(me.getGraphX(), me.getGraphY(), this.autoExtend);
			}
			else if (evtName == mxEvent.MOUSE_UP && this.ignoreScrollbars && this.translateToScrollPosition &&
					(this.container.scrollLeft != 0 || this.container.scrollTop != 0))
			{
				var s = this.view.scale;
				var tr = this.view.translate;
				this.view.setTranslate(tr.x - this.container.scrollLeft / s, tr.y - this.container.scrollTop / s);
				this.container.scrollLeft = 0;
				this.container.scrollTop = 0;
			}
			
			if (this.mouseListeners != null)
			{
				var args = [sender, me];
	
				// Does not change returnValue in Opera
				if (!me.getEvent().preventDefault)
				{
					me.getEvent().returnValue = true;
				}
				
				for (var i = 0; i < this.mouseListeners.length; i++)
				{
					var l = this.mouseListeners[i];
					
					if (evtName == mxEvent.MOUSE_DOWN)
					{
						l.mouseDown.apply(l, args);
					}
					else if (evtName == mxEvent.MOUSE_MOVE)
					{
						l.mouseMove.apply(l, args);
					}
					else if (evtName == mxEvent.MOUSE_UP)
					{
						l.mouseUp.apply(l, args);
					}
				}
			}
			
			// Invokes the click handler
			if (evtName == mxEvent.MOUSE_UP)
			{
				this.click(me);
			}
		}
		
		// Detects tapAndHold events using a timer
		if ((mxEvent.isTouchEvent(me.getEvent()) || mxEvent.isPenEvent(me.getEvent())) &&
			evtName == mxEvent.MOUSE_DOWN && this.tapAndHoldEnabled && !this.tapAndHoldInProgress)
		{
			this.tapAndHoldInProgress = true;
			this.initialTouchX = me.getGraphX();
			this.initialTouchY = me.getGraphY();
			
			var handler = function()
			{
				if (this.tapAndHoldValid)
				{
					this.tapAndHold(me);
				}
				
				this.tapAndHoldInProgress = false;
				this.tapAndHoldValid = false;
			};
			
			if (this.tapAndHoldThread)
			{
				window.clearTimeout(this.tapAndHoldThread);
			}
	
			this.tapAndHoldThread = window.setTimeout(mxUtils.bind(this, handler), this.tapAndHoldDelay);
			this.tapAndHoldValid = true;
		}
		else if (evtName == mxEvent.MOUSE_UP)
		{
			this.tapAndHoldInProgress = false;
			this.tapAndHoldValid = false;
		}
		else if (this.tapAndHoldValid)
		{
			this.tapAndHoldValid =
				Math.abs(this.initialTouchX - me.getGraphX()) < this.tolerance &&
				Math.abs(this.initialTouchY - me.getGraphY()) < this.tolerance;
		}

		// Stops editing for all events other than from cellEditor
		if (evtName == mxEvent.MOUSE_DOWN && this.isEditing() && !this.cellEditor.isEventSource(me.getEvent()))
		{
			this.stopEditing(!this.isInvokesStopCellEditing());
		}

		this.consumeMouseEvent(evtName, me, sender);
	}
};

/**
 * Function: consumeMouseEvent
 * 
 * Consumes the given <mxMouseEvent> if it's a touchStart event.
 */
mxGraph.prototype.consumeMouseEvent = function(evtName, me, sender)
{
	// Workaround for duplicate click in Windows 8 with Chrome/FF/Opera with touch
	if (evtName == mxEvent.MOUSE_DOWN && mxEvent.isTouchEvent(me.getEvent()))
	{
		me.consume(false);
	}
};

/**
 * Function: fireGestureEvent
 * 
 * Dispatches a <mxEvent.GESTURE> event. The following example will resize the
 * cell under the mouse based on the scale property of the native touch event.
 * 
 * (code)
 * graph.addListener(mxEvent.GESTURE, function(sender, eo)
 * {
 *   var evt = eo.getProperty('event');
 *   var state = graph.view.getState(eo.getProperty('cell'));
 *   
 *   if (graph.isEnabled() && graph.isCellResizable(state.cell) && Math.abs(1 - evt.scale) > 0.2)
 *   {
 *     var scale = graph.view.scale;
 *     var tr = graph.view.translate;
 *     
 *     var w = state.width * evt.scale;
 *     var h = state.height * evt.scale;
 *     var x = state.x - (w - state.width) / 2;
 *     var y = state.y - (h - state.height) / 2;
 *     
 *     var bounds = new mxRectangle(graph.snap(x / scale) - tr.x,
 *     		graph.snap(y / scale) - tr.y, graph.snap(w / scale), graph.snap(h / scale));
 *     graph.resizeCell(state.cell, bounds);
 *     eo.consume();
 *   }
 * });
 * (end)
 * 
 * Parameters:
 * 
 * evt - Gestureend event that represents the gesture.
 * cell - Optional <mxCell> associated with the gesture.
 */
mxGraph.prototype.fireGestureEvent = function(evt, cell)
{
	// Resets double tap event handling when gestures take place
	this.lastTouchTime = 0;
	this.fireEvent(new mxEventObject(mxEvent.GESTURE, 'event', evt, 'cell', cell));
};

/**
 * Function: destroy
 * 
 * Destroys the graph and all its resources.
 */
mxGraph.prototype.destroy = function()
{
	if (!this.destroyed)
	{
		this.destroyed = true;
		
		if (this.tooltipHandler != null)
		{
			this.tooltipHandler.destroy();
		}
		
		if (this.selectionCellsHandler != null)
		{
			this.selectionCellsHandler.destroy();
		}

		if (this.panningHandler != null)
		{
			this.panningHandler.destroy();
		}

		if (this.popupMenuHandler != null)
		{
			this.popupMenuHandler.destroy();
		}
		
		if (this.connectionHandler != null)
		{
			this.connectionHandler.destroy();
		}
		
		if (this.graphHandler != null)
		{
			this.graphHandler.destroy();
		}
		
		if (this.cellEditor != null)
		{
			this.cellEditor.destroy();
		}
		
		if (this.view != null)
		{
			this.view.destroy();
		}

		if (this.model != null && this.graphModelChangeListener != null)
		{
			this.model.removeListener(this.graphModelChangeListener);
			this.graphModelChangeListener = null;
		}

		this.container = null;
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxCellOverlay
 *
 * Extends <mxEventSource> to implement a graph overlay, represented by an icon
 * and a tooltip. Overlays can handle and fire <click> events and are added to
 * the graph using <mxGraph.addCellOverlay>, and removed using
 * <mxGraph.removeCellOverlay>, or <mxGraph.removeCellOverlays> to remove all overlays.
 * The <mxGraph.getCellOverlays> function returns the array of overlays for a given
 * cell in a graph. If multiple overlays exist for the same cell, then
 * <getBounds> should be overridden in at least one of the overlays.
 * 
 * Overlays appear on top of all cells in a special layer. If this is not
 * desirable, then the image must be rendered as part of the shape or label of
 * the cell instead.
 *
 * Example:
 * 
 * The following adds a new overlays for a given vertex and selects the cell
 * if the overlay is clicked.
 *
 * (code)
 * var overlay = new mxCellOverlay(img, html);
 * graph.addCellOverlay(vertex, overlay);
 * overlay.addListener(mxEvent.CLICK, function(sender, evt)
 * {
 *   var cell = evt.getProperty('cell');
 *   graph.setSelectionCell(cell);
 * });
 * (end)
 * 
 * For cell overlays to be printed use <mxPrintPreview.printOverlays>.
 *
 * Event: mxEvent.CLICK
 *
 * Fires when the user clicks on the overlay. The <code>event</code> property
 * contains the corresponding mouse event and the <code>cell</code> property
 * contains the cell. For touch devices this is fired if the element receives
 * a touchend event.
 * 
 * Constructor: mxCellOverlay
 *
 * Constructs a new overlay using the given image and tooltip.
 * 
 * Parameters:
 * 
 * image - <mxImage> that represents the icon to be displayed.
 * tooltip - Optional string that specifies the tooltip.
 * align - Optional horizontal alignment for the overlay. Possible
 * values are <ALIGN_LEFT>, <ALIGN_CENTER> and <ALIGN_RIGHT>
 * (default).
 * verticalAlign - Vertical alignment for the overlay. Possible
 * values are <ALIGN_TOP>, <ALIGN_MIDDLE> and <ALIGN_BOTTOM>
 * (default).
 */
function mxCellOverlay(image, tooltip, align, verticalAlign, offset, cursor)
{
	this.image = image;
	this.tooltip = tooltip;
	this.align = (align != null) ? align : this.align;
	this.verticalAlign = (verticalAlign != null) ? verticalAlign : this.verticalAlign;
	this.offset = (offset != null) ? offset : new mxPoint();
	this.cursor = (cursor != null) ? cursor : 'help';
};

/**
 * Extends mxEventSource.
 */
mxCellOverlay.prototype = new mxEventSource();
mxCellOverlay.prototype.constructor = mxCellOverlay;

/**
 * Variable: image
 *
 * Holds the <mxImage> to be used as the icon.
 */
mxCellOverlay.prototype.image = null;

/**
 * Variable: tooltip
 * 
 * Holds the optional string to be used as the tooltip.
 */
mxCellOverlay.prototype.tooltip = null;

/**
 * Variable: align
 * 
 * Holds the horizontal alignment for the overlay. Default is
 * <mxConstants.ALIGN_RIGHT>. For edges, the overlay always appears in the
 * center of the edge.
 */
mxCellOverlay.prototype.align = mxConstants.ALIGN_RIGHT;

/**
 * Variable: verticalAlign
 * 
 * Holds the vertical alignment for the overlay. Default is
 * <mxConstants.ALIGN_BOTTOM>. For edges, the overlay always appears in the
 * center of the edge.
 */
mxCellOverlay.prototype.verticalAlign = mxConstants.ALIGN_BOTTOM;

/**
 * Variable: offset
 * 
 * Holds the offset as an <mxPoint>. The offset will be scaled according to the
 * current scale.
 */
mxCellOverlay.prototype.offset = null;

/**
 * Variable: cursor
 * 
 * Holds the cursor for the overlay. Default is 'help'.
 */
mxCellOverlay.prototype.cursor = null;

/**
 * Variable: defaultOverlap
 * 
 * Defines the overlapping for the overlay, that is, the proportional distance
 * from the origin to the point defined by the alignment. Default is 0.5.
 */
mxCellOverlay.prototype.defaultOverlap = 0.5;

/**
 * Function: getBounds
 * 
 * Returns the bounds of the overlay for the given <mxCellState> as an
 * <mxRectangle>. This should be overridden when using multiple overlays
 * per cell so that the overlays do not overlap.
 * 
 * The following example will place the overlay along an edge (where
 * x=[-1..1] from the start to the end of the edge and y is the
 * orthogonal offset in px).
 * 
 * (code)
 * overlay.getBounds = function(state)
 * {
 *   var bounds = mxCellOverlay.prototype.getBounds.apply(this, arguments);
 *   
 *   if (state.view.graph.getModel().isEdge(state.cell))
 *   {
 *     var pt = state.view.getPoint(state, {x: 0, y: 0, relative: true});
 *     
 *     bounds.x = pt.x - bounds.width / 2;
 *     bounds.y = pt.y - bounds.height / 2;
 *   }
 *   
 *   return bounds;
 * };
 * (end)
 * 
 * Parameters:
 * 
 * state - <mxCellState> that represents the current state of the
 * associated cell.
 */
mxCellOverlay.prototype.getBounds = function(state)
{
	var isEdge = state.view.graph.getModel().isEdge(state.cell);
	var s = state.view.scale;
	var pt = null;

	var w = this.image.width;
	var h = this.image.height;
	
	if (isEdge)
	{
		var pts = state.absolutePoints;
		
		if (pts.length % 2 == 1)
		{
			pt = pts[Math.floor(pts.length / 2)];
		}
		else
		{
			var idx = pts.length / 2;
			var p0 = pts[idx-1];
			var p1 = pts[idx];
			pt = new mxPoint(p0.x + (p1.x - p0.x) / 2,
				p0.y + (p1.y - p0.y) / 2);
		}
	}
	else
	{
		pt = new mxPoint();
		
		if (this.align == mxConstants.ALIGN_LEFT)
		{
			pt.x = state.x;
		}
		else if (this.align == mxConstants.ALIGN_CENTER)
		{
			pt.x = state.x + state.width / 2;
		}
		else
		{
			pt.x = state.x + state.width;
		}
		
		if (this.verticalAlign == mxConstants.ALIGN_TOP)
		{
			pt.y = state.y;
		}
		else if (this.verticalAlign == mxConstants.ALIGN_MIDDLE)
		{
			pt.y = state.y + state.height / 2;
		}
		else
		{
			pt.y = state.y + state.height;
		}
	}

	return new mxRectangle(Math.round(pt.x - (w * this.defaultOverlap - this.offset.x) * s),
		Math.round(pt.y - (h * this.defaultOverlap - this.offset.y) * s), w * s, h * s);
};

/**
 * Function: toString
 * 
 * Returns the textual representation of the overlay to be used as the
 * tooltip. This implementation returns <tooltip>.
 */
mxCellOverlay.prototype.toString = function()
{
	return this.tooltip;
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxOutline
 *
 * Implements an outline (aka overview) for a graph. Set <updateOnPan> to true
 * to enable updates while the source graph is panning.
 * 
 * Example:
 * 
 * (code)
 * var outline = new mxOutline(graph, div);
 * (end)
 * 
 * If an outline is used in an <mxWindow> in IE8 standards mode, the following
 * code makes sure that the shadow filter is not inherited and that any
 * transparent elements in the graph do not show the page background, but the
 * background of the graph container.
 * 
 * (code)
 * if (document.documentMode == 8)
 * {
 *   container.style.filter = 'progid:DXImageTransform.Microsoft.alpha(opacity=100)';
 * }
 * (end)
 * 
 * To move the graph to the top, left corner the following code can be used.
 * 
 * (code)
 * var scale = graph.view.scale;
 * var bounds = graph.getGraphBounds();
 * graph.view.setTranslate(-bounds.x / scale, -bounds.y / scale);
 * (end)
 * 
 * To toggle the suspended mode, the following can be used.
 * 
 * (code)
 * outline.suspended = !outln.suspended;
 * if (!outline.suspended)
 * {
 *   outline.update(true);
 * }
 * (end)
 * 
 * Constructor: mxOutline
 *
 * Constructs a new outline for the specified graph inside the given
 * container.
 * 
 * Parameters:
 * 
 * source - <mxGraph> to create the outline for.
 * container - DOM node that will contain the outline.
 */
function mxOutline(source, container)
{
	this.source = source;

	if (container != null)
	{
		this.init(container);
	}
};

/**
 * Function: source
 * 
 * Reference to the source <mxGraph>.
 */
mxOutline.prototype.source = null;

/**
 * Function: outline
 * 
 * Reference to the <mxGraph> that renders the outline.
 */
mxOutline.prototype.outline = null;

/**
 * Function: graphRenderHint
 * 
 * Renderhint to be used for the outline graph. Default is faster.
 */
mxOutline.prototype.graphRenderHint = mxConstants.RENDERING_HINT_FASTER;

/**
 * Variable: enabled
 * 
 * Specifies if events are handled. Default is true.
 */
mxOutline.prototype.enabled = true;

/**
 * Variable: showViewport
 * 
 * Specifies a viewport rectangle should be shown. Default is true.
 */
mxOutline.prototype.showViewport = true;

/**
 * Variable: border
 * 
 * Border to be added at the bottom and right. Default is 10.
 */
mxOutline.prototype.border = 10;

/**
 * Variable: enabled
 * 
 * Specifies the size of the sizer handler. Default is 8.
 */
mxOutline.prototype.sizerSize = 8;

/**
 * Variable: labelsVisible
 * 
 * Specifies if labels should be visible in the outline. Default is false.
 */
mxOutline.prototype.labelsVisible = false;

/**
 * Variable: updateOnPan
 * 
 * Specifies if <update> should be called for <mxEvent.PAN> in the source
 * graph. Default is false.
 */
mxOutline.prototype.updateOnPan = false;

/**
 * Variable: sizerImage
 * 
 * Optional <mxImage> to be used for the sizer. Default is null.
 */
mxOutline.prototype.sizerImage = null;

/**
 * Variable: minScale
 * 
 * Minimum scale to be used. Default is 0.001.
 */
mxOutline.prototype.minScale = 0.0001;

/**
 * Variable: suspended
 * 
 * Optional boolean flag to suspend updates. Default is false. This flag will
 * also suspend repaints of the outline. To toggle this switch, use the
 * following code.
 * 
 * (code)
 * nav.suspended = !nav.suspended;
 * 
 * if (!nav.suspended)
 * {
 *   nav.update(true);
 * }
 * (end)
 */
mxOutline.prototype.suspended = false;

/**
 * Variable: forceVmlHandles
 * 
 * Specifies if VML should be used to render the handles in this control. This
 * is true for IE8 standards mode and false for all other browsers and modes.
 * This is a workaround for rendering issues of HTML elements over elements
 * with filters in IE 8 standards mode.
 */
mxOutline.prototype.forceVmlHandles = document.documentMode == 8;

/**
 * Function: createGraph
 * 
 * Creates the <mxGraph> used in the outline.
 */
mxOutline.prototype.createGraph = function(container)
{
	var graph = new mxGraph(container, this.source.getModel(), this.graphRenderHint, this.source.getStylesheet());
	graph.foldingEnabled = false;
	graph.autoScroll = false;
	
	return graph;
};

/**
 * Function: init
 * 
 * Initializes the outline inside the given container.
 */
mxOutline.prototype.init = function(container)
{
	this.outline = this.createGraph(container);
	
	// Do not repaint when suspended
	var outlineGraphModelChanged = this.outline.graphModelChanged;
	this.outline.graphModelChanged = mxUtils.bind(this, function(changes)
	{
		if (!this.suspended && this.outline != null)
		{
			outlineGraphModelChanged.apply(this.outline, arguments);
		}
	});

	// Enables faster painting in SVG
	if (mxClient.IS_SVG)
	{
		var node = this.outline.getView().getCanvas().parentNode;
		node.setAttribute('shape-rendering', 'optimizeSpeed');
		node.setAttribute('image-rendering', 'optimizeSpeed');
	}
	
	// Hides cursors and labels
	this.outline.labelsVisible = this.labelsVisible;
	this.outline.setEnabled(false);
	
	this.updateHandler = mxUtils.bind(this, function(sender, evt)
	{
		if (!this.suspended && !this.active)
		{
			this.update();
		}
	});
	
	// Updates the scale of the outline after a change of the main graph
	this.source.getModel().addListener(mxEvent.CHANGE, this.updateHandler);
	this.outline.addMouseListener(this);
	
	// Adds listeners to keep the outline in sync with the source graph
	var view = this.source.getView();
	view.addListener(mxEvent.SCALE, this.updateHandler);
	view.addListener(mxEvent.TRANSLATE, this.updateHandler);
	view.addListener(mxEvent.SCALE_AND_TRANSLATE, this.updateHandler);
	view.addListener(mxEvent.DOWN, this.updateHandler);
	view.addListener(mxEvent.UP, this.updateHandler);

	// Updates blue rectangle on scroll
	mxEvent.addListener(this.source.container, 'scroll', this.updateHandler);
	
	this.panHandler = mxUtils.bind(this, function(sender)
	{
		if (this.updateOnPan)
		{
			this.updateHandler.apply(this, arguments);
		}
	});
	this.source.addListener(mxEvent.PAN, this.panHandler);
	
	// Refreshes the graph in the outline after a refresh of the main graph
	this.refreshHandler = mxUtils.bind(this, function(sender)
	{
		this.outline.setStylesheet(this.source.getStylesheet());
		this.outline.refresh();
	});
	this.source.addListener(mxEvent.REFRESH, this.refreshHandler);

	// Creates the blue rectangle for the viewport
	this.bounds = new mxRectangle(0, 0, 0, 0);
	this.selectionBorder = new mxRectangleShape(this.bounds, null,
		mxConstants.OUTLINE_COLOR, mxConstants.OUTLINE_STROKEWIDTH);
	this.selectionBorder.dialect = this.outline.dialect;

	if (this.forceVmlHandles)
	{
		this.selectionBorder.isHtmlAllowed = function()
		{
			return false;
		};
	}
	
	this.selectionBorder.init(this.outline.getView().getOverlayPane());

	// Handles event by catching the initial pointer start and then listening to the
	// complete gesture on the event target. This is needed because all the events
	// are routed via the initial element even if that element is removed from the
	// DOM, which happens when we repaint the selection border and zoom handles.
	var handler = mxUtils.bind(this, function(evt)
	{
		var t = mxEvent.getSource(evt);
		
		var redirect = mxUtils.bind(this, function(evt)
		{
			this.outline.fireMouseEvent(mxEvent.MOUSE_MOVE, new mxMouseEvent(evt));
		});
		
		var redirect2 = mxUtils.bind(this, function(evt)
		{
			mxEvent.removeGestureListeners(t, null, redirect, redirect2);
			this.outline.fireMouseEvent(mxEvent.MOUSE_UP, new mxMouseEvent(evt));
		});
		
		mxEvent.addGestureListeners(t, null, redirect, redirect2);
		this.outline.fireMouseEvent(mxEvent.MOUSE_DOWN, new mxMouseEvent(evt));
	});
	
	mxEvent.addGestureListeners(this.selectionBorder.node, handler);

	// Creates a small blue rectangle for sizing (sizer handle)
	this.sizer = this.createSizer();
	
	if (this.forceVmlHandles)
	{
		this.sizer.isHtmlAllowed = function()
		{
			return false;
		};
	}
	
	this.sizer.init(this.outline.getView().getOverlayPane());
	
	if (this.enabled)
	{
		this.sizer.node.style.cursor = 'nwse-resize';
	}
	
	mxEvent.addGestureListeners(this.sizer.node, handler);

	this.selectionBorder.node.style.display = (this.showViewport) ? '' : 'none';
	this.sizer.node.style.display = this.selectionBorder.node.style.display;
	this.selectionBorder.node.style.cursor = 'move';

	this.update(false);
};

/**
 * Function: isEnabled
 * 
 * Returns true if events are handled. This implementation
 * returns <enabled>.
 */
mxOutline.prototype.isEnabled = function()
{
	return this.enabled;
};

/**
 * Function: setEnabled
 * 
 * Enables or disables event handling. This implementation
 * updates <enabled>.
 * 
 * Parameters:
 * 
 * value - Boolean that specifies the new enabled state.
 */
mxOutline.prototype.setEnabled = function(value)
{
	this.enabled = value;
};

/**
 * Function: setZoomEnabled
 * 
 * Enables or disables the zoom handling by showing or hiding the respective
 * handle.
 * 
 * Parameters:
 * 
 * value - Boolean that specifies the new enabled state.
 */
mxOutline.prototype.setZoomEnabled = function(value)
{
	this.sizer.node.style.visibility = (value) ? 'visible' : 'hidden';
};

/**
 * Function: refresh
 * 
 * Invokes <update> and revalidate the outline. This method is deprecated.
 */
mxOutline.prototype.refresh = function()
{
	this.update(true);
};

/**
 * Function: createSizer
 * 
 * Creates the shape used as the sizer.
 */
mxOutline.prototype.createSizer = function()
{
	if (this.sizerImage != null)
	{
		var sizer = new mxImageShape(new mxRectangle(0, 0, this.sizerImage.width, this.sizerImage.height), this.sizerImage.src);
		sizer.dialect = this.outline.dialect;
		
		return sizer;
	}
	else
	{
		var sizer = new mxRectangleShape(new mxRectangle(0, 0, this.sizerSize, this.sizerSize),
			mxConstants.OUTLINE_HANDLE_FILLCOLOR, mxConstants.OUTLINE_HANDLE_STROKECOLOR);
		sizer.dialect = this.outline.dialect;
	
		return sizer;
	}
};

/**
 * Function: getSourceContainerSize
 * 
 * Returns the size of the source container.
 */
mxOutline.prototype.getSourceContainerSize = function()
{
	return new mxRectangle(0, 0, this.source.container.scrollWidth, this.source.container.scrollHeight);
};

/**
 * Function: getOutlineOffset
 * 
 * Returns the offset for drawing the outline graph.
 */
mxOutline.prototype.getOutlineOffset = function(scale)
{
	return null;
};

/**
 * Function: getOutlineOffset
 * 
 * Returns the offset for drawing the outline graph.
 */
mxOutline.prototype.getSourceGraphBounds = function()
{
	return this.source.getGraphBounds();
};

/**
 * Function: update
 * 
 * Updates the outline.
 */
mxOutline.prototype.update = function(revalidate)
{
	if (this.source != null && this.outline != null)
	{
		var sourceScale = this.source.view.scale;
		var scaledGraphBounds = this.getSourceGraphBounds();
		var unscaledGraphBounds = new mxRectangle(scaledGraphBounds.x / sourceScale + this.source.panDx,
				scaledGraphBounds.y / sourceScale + this.source.panDy, scaledGraphBounds.width / sourceScale,
				scaledGraphBounds.height / sourceScale);

		var unscaledFinderBounds = new mxRectangle(0, 0,
			this.source.container.clientWidth / sourceScale,
			this.source.container.clientHeight / sourceScale);
		
		var union = unscaledGraphBounds.clone();
		union.add(unscaledFinderBounds);
	
		// Zooms to the scrollable area if that is bigger than the graph
		var size = this.getSourceContainerSize();
		var completeWidth = Math.max(size.width / sourceScale, union.width);
		var completeHeight = Math.max(size.height / sourceScale, union.height);
	
		var availableWidth = Math.max(0, this.outline.container.clientWidth - this.border);
		var availableHeight = Math.max(0, this.outline.container.clientHeight - this.border);
		
		var outlineScale = Math.min(availableWidth / completeWidth, availableHeight / completeHeight);
		var scale = (isNaN(outlineScale)) ? this.minScale : Math.max(this.minScale, outlineScale);

		if (scale > 0)
		{
			if (this.outline.getView().scale != scale)
			{
				this.outline.getView().scale = scale;
				revalidate = true;
			}
		
			var navView = this.outline.getView();
			
			if (navView.currentRoot != this.source.getView().currentRoot)
			{
				navView.setCurrentRoot(this.source.getView().currentRoot);
			}

			var t = this.source.view.translate;
			var tx = t.x + this.source.panDx;
			var ty = t.y + this.source.panDy;
			
			var off = this.getOutlineOffset(scale);
			
			if (off != null)
			{
				tx += off.x;
				ty += off.y;
			}
			
			if (unscaledGraphBounds.x < 0)
			{
				tx = tx - unscaledGraphBounds.x;
			}
			if (unscaledGraphBounds.y < 0)
			{
				ty = ty - unscaledGraphBounds.y;
			}
			
			if (navView.translate.x != tx || navView.translate.y != ty)
			{
				navView.translate.x = tx;
				navView.translate.y = ty;
				revalidate = true;
			}
		
			// Prepares local variables for computations
			var t2 = navView.translate;
			scale = this.source.getView().scale;
			var scale2 = scale / navView.scale;
			var scale3 = 1.0 / navView.scale;
			var container = this.source.container;
			
			// Updates the bounds of the viewrect in the navigation
			this.bounds = new mxRectangle(
				(t2.x - t.x - this.source.panDx) / scale3,
				(t2.y - t.y - this.source.panDy) / scale3,
				(container.clientWidth / scale2),
				(container.clientHeight / scale2));
			
			// Adds the scrollbar offset to the finder
			this.bounds.x += this.source.container.scrollLeft * navView.scale / scale;
			this.bounds.y += this.source.container.scrollTop * navView.scale / scale;
			
			var b = this.selectionBorder.bounds;
			
			if (b.x != this.bounds.x || b.y != this.bounds.y || b.width != this.bounds.width || b.height != this.bounds.height)
			{
				this.selectionBorder.bounds = this.bounds;
				this.selectionBorder.redraw();
			}
		
			// Updates the bounds of the zoom handle at the bottom right
			var b = this.sizer.bounds;
			var b2 = new mxRectangle(this.bounds.x + this.bounds.width - b.width / 2,
					this.bounds.y + this.bounds.height - b.height / 2, b.width, b.height);

			if (b.x != b2.x || b.y != b2.y || b.width != b2.width || b.height != b2.height)
			{
				this.sizer.bounds = b2;
				
				// Avoids update of visibility in redraw for VML
				if (this.sizer.node.style.visibility != 'hidden')
				{
					this.sizer.redraw();
				}
			}

			if (revalidate)
			{
				this.outline.view.revalidate();
			}
		}
	}
};

/**
 * Function: mouseDown
 * 
 * Handles the event by starting a translation or zoom.
 */
mxOutline.prototype.mouseDown = function(sender, me)
{
	if (this.enabled && this.showViewport)
	{
		var tol = (!mxEvent.isMouseEvent(me.getEvent())) ? this.source.tolerance : 0;
		var hit = (this.source.allowHandleBoundsCheck && (mxClient.IS_IE || tol > 0)) ?
				new mxRectangle(me.getGraphX() - tol, me.getGraphY() - tol, 2 * tol, 2 * tol) : null;
		this.zoom = me.isSource(this.sizer) || (hit != null && mxUtils.intersects(shape.bounds, hit));
		this.startX = me.getX();
		this.startY = me.getY();
		this.active = true;

		if (this.source.useScrollbarsForPanning && mxUtils.hasScrollbars(this.source.container))
		{
			this.dx0 = this.source.container.scrollLeft;
			this.dy0 = this.source.container.scrollTop;
		}
		else
		{
			this.dx0 = 0;
			this.dy0 = 0;
		}
	}

	me.consume();
};

/**
 * Function: mouseMove
 * 
 * Handles the event by previewing the viewrect in <graph> and updating the
 * rectangle that represents the viewrect in the outline.
 */
mxOutline.prototype.mouseMove = function(sender, me)
{
	if (this.active)
	{
		this.selectionBorder.node.style.display = (this.showViewport) ? '' : 'none';
		this.sizer.node.style.display = this.selectionBorder.node.style.display; 

		var delta = this.getTranslateForEvent(me);
		var dx = delta.x;
		var dy = delta.y;
		var bounds = null;
		
		if (!this.zoom)
		{
			// Previews the panning on the source graph
			var scale = this.outline.getView().scale;
			bounds = new mxRectangle(this.bounds.x + dx,
				this.bounds.y + dy, this.bounds.width, this.bounds.height);
			this.selectionBorder.bounds = bounds;
			this.selectionBorder.redraw();
			dx /= scale;
			dx *= this.source.getView().scale;
			dy /= scale;
			dy *= this.source.getView().scale;
			this.source.panGraph(-dx - this.dx0, -dy - this.dy0);
		}
		else
		{
			// Does *not* preview zooming on the source graph
			var container = this.source.container;
			var viewRatio = container.clientWidth / container.clientHeight;
			dy = dx / viewRatio;
			bounds = new mxRectangle(this.bounds.x,
				this.bounds.y,
				Math.max(1, this.bounds.width + dx),
				Math.max(1, this.bounds.height + dy));
			this.selectionBorder.bounds = bounds;
			this.selectionBorder.redraw();
		}
		
		// Updates the zoom handle
		var b = this.sizer.bounds;
		this.sizer.bounds = new mxRectangle(
			bounds.x + bounds.width - b.width / 2,
			bounds.y + bounds.height - b.height / 2,
			b.width, b.height);
		
		// Avoids update of visibility in redraw for VML
		if (this.sizer.node.style.visibility != 'hidden')
		{
			this.sizer.redraw();
		}
		
		me.consume();
	}
};

/**
 * Function: getTranslateForEvent
 * 
 * Gets the translate for the given mouse event. Here is an example to limit
 * the outline to stay within positive coordinates:
 * 
 * (code)
 * outline.getTranslateForEvent = function(me)
 * {
 *   var pt = new mxPoint(me.getX() - this.startX, me.getY() - this.startY);
 *   
 *   if (!this.zoom)
 *   {
 *     var tr = this.source.view.translate;
 *     pt.x = Math.max(tr.x * this.outline.view.scale, pt.x);
 *     pt.y = Math.max(tr.y * this.outline.view.scale, pt.y);
 *   }
 *   
 *   return pt;
 * };
 * (end)
 */
mxOutline.prototype.getTranslateForEvent = function(me)
{
	return new mxPoint(me.getX() - this.startX, me.getY() - this.startY);
};

/**
 * Function: mouseUp
 * 
 * Handles the event by applying the translation or zoom to <graph>.
 */
mxOutline.prototype.mouseUp = function(sender, me)
{
	if (this.active)
	{
		var delta = this.getTranslateForEvent(me);
		var dx = delta.x;
		var dy = delta.y;
		
		if (Math.abs(dx) > 0 || Math.abs(dy) > 0)
		{
			if (!this.zoom)
			{
				// Applies the new translation if the source
				// has no scrollbars
				if (!this.source.useScrollbarsForPanning ||
					!mxUtils.hasScrollbars(this.source.container))
				{
					this.source.panGraph(0, 0);
					dx /= this.outline.getView().scale;
					dy /= this.outline.getView().scale;
					var t = this.source.getView().translate;
					this.source.getView().setTranslate(t.x - dx, t.y - dy);
				}
			}
			else
			{
				// Applies the new zoom
				var w = this.selectionBorder.bounds.width;
				var scale = this.source.getView().scale;
				this.source.zoomTo(Math.max(this.minScale, scale - (dx * scale) / w), false);
			}

			this.update();
			me.consume();
		}
			
		// Resets the state of the handler
		this.index = null;
		this.active = false;
	}
};

/**
 * Function: destroy
 * 
 * Destroy this outline and removes all listeners from <source>.
 */
mxOutline.prototype.destroy = function()
{
	if (this.source != null)
	{
		this.source.removeListener(this.panHandler);
		this.source.removeListener(this.refreshHandler);
		this.source.getModel().removeListener(this.updateHandler);
		this.source.getView().removeListener(this.updateHandler);
		mxEvent.addListener(this.source.container, 'scroll', this.updateHandler);
		this.source = null;
	}
	
	if (this.outline != null)
	{
		this.outline.removeMouseListener(this);
		this.outline.destroy();
		this.outline = null;
	}

	if (this.selectionBorder != null)
	{
		this.selectionBorder.destroy();
		this.selectionBorder = null;
	}
	
	if (this.sizer != null)
	{
		this.sizer.destroy();
		this.sizer = null;
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxMultiplicity
 * 
 * Defines invalid connections along with the error messages that they produce.
 * To add or remove rules on a graph, you must add/remove instances of this
 * class to <mxGraph.multiplicities>.
 * 
 * Example:
 * 
 * (code)
 * graph.multiplicities.push(new mxMultiplicity(
 *   true, 'rectangle', null, null, 0, 2, ['circle'],
 *   'Only 2 targets allowed',
 *   'Only circle targets allowed'));
 * (end)
 * 
 * Defines a rule where each rectangle must be connected to no more than 2
 * circles and no other types of targets are allowed.
 * 
 * Constructor: mxMultiplicity
 * 
 * Instantiate class mxMultiplicity in order to describe allowed
 * connections in a graph. Not all constraints can be enforced while
 * editing, some must be checked at validation time. The <countError> and
 * <typeError> are treated as resource keys in <mxResources>.
 * 
 * Parameters:
 * 
 * source - Boolean indicating if this rule applies to the source or target
 * terminal.
 * type - Type of the source or target terminal that this rule applies to.
 * See <type> for more information.
 * attr - Optional attribute name to match the source or target terminal.
 * value - Optional attribute value to match the source or target terminal.
 * min - Minimum number of edges for this rule. Default is 1.
 * max - Maximum number of edges for this rule. n means infinite. Default
 * is n.
 * validNeighbors - Array of types of the opposite terminal for which this
 * rule applies.
 * countError - Error to be displayed for invalid number of edges.
 * typeError - Error to be displayed for invalid opposite terminals.
 * validNeighborsAllowed - Optional boolean indicating if the array of
 * opposite types should be valid or invalid.
 */
function mxMultiplicity(source, type, attr, value, min, max,
	validNeighbors, countError, typeError, validNeighborsAllowed)
{
	this.source = source;
	this.type = type;
	this.attr = attr;
	this.value = value;
	this.min = (min != null) ? min : 0;
	this.max = (max != null) ? max : 'n';
	this.validNeighbors = validNeighbors;
	this.countError = mxResources.get(countError) || countError;
	this.typeError = mxResources.get(typeError) || typeError;
	this.validNeighborsAllowed = (validNeighborsAllowed != null) ?
		validNeighborsAllowed : true;
};

/**
 * Variable: type
 * 
 * Defines the type of the source or target terminal. The type is a string
 * passed to <mxUtils.isNode> together with the source or target vertex
 * value as the first argument.
 */
mxMultiplicity.prototype.type = null;

/**
 * Variable: attr
 * 
 * Optional string that specifies the attributename to be passed to
 * <mxUtils.isNode> to check if the rule applies to a cell.
 */
mxMultiplicity.prototype.attr = null;

/**
 * Variable: value
 * 
 * Optional string that specifies the value of the attribute to be passed
 * to <mxUtils.isNode> to check if the rule applies to a cell.
 */
mxMultiplicity.prototype.value = null;

/**
 * Variable: source
 * 
 * Boolean that specifies if the rule is applied to the source or target
 * terminal of an edge.
 */
mxMultiplicity.prototype.source = null;

/**
 * Variable: min
 * 
 * Defines the minimum number of connections for which this rule applies.
 * Default is 0.
 */
mxMultiplicity.prototype.min = null;

/**
 * Variable: max
 * 
 * Defines the maximum number of connections for which this rule applies.
 * A value of 'n' means unlimited times. Default is 'n'. 
 */
mxMultiplicity.prototype.max = null;

/**
 * Variable: validNeighbors
 * 
 * Holds an array of strings that specify the type of neighbor for which
 * this rule applies. The strings are used in <mxCell.is> on the opposite
 * terminal to check if the rule applies to the connection.
 */
mxMultiplicity.prototype.validNeighbors = null;

/**
 * Variable: validNeighborsAllowed
 * 
 * Boolean indicating if the list of validNeighbors are those that are allowed
 * for this rule or those that are not allowed for this rule.
 */
mxMultiplicity.prototype.validNeighborsAllowed = true;

/**
 * Variable: countError
 * 
 * Holds the localized error message to be displayed if the number of
 * connections for which the rule applies is smaller than <min> or greater
 * than <max>.
 */
mxMultiplicity.prototype.countError = null;

/**
 * Variable: typeError
 * 
 * Holds the localized error message to be displayed if the type of the
 * neighbor for a connection does not match the rule.
 */
mxMultiplicity.prototype.typeError = null;

/**
 * Function: check
 * 
 * Checks the multiplicity for the given arguments and returns the error
 * for the given connection or null if the multiplicity does not apply.
 *  
 * Parameters:
 * 
 * graph - Reference to the enclosing <mxGraph> instance.
 * edge - <mxCell> that represents the edge to validate.
 * source - <mxCell> that represents the source terminal.
 * target - <mxCell> that represents the target terminal.
 * sourceOut - Number of outgoing edges from the source terminal.
 * targetIn - Number of incoming edges for the target terminal.
 */
mxMultiplicity.prototype.check = function(graph, edge, source, target, sourceOut, targetIn)
{
	var error = '';

	if ((this.source && this.checkTerminal(graph, source, edge)) ||
		(!this.source && this.checkTerminal(graph, target, edge)))
	{
		if (this.countError != null && 
			((this.source && (this.max == 0 || (sourceOut >= this.max))) ||
			(!this.source && (this.max == 0 || (targetIn >= this.max)))))
		{
			error += this.countError + '\n';
		}

		if (this.validNeighbors != null && this.typeError != null && this.validNeighbors.length > 0)
		{
			var isValid = this.checkNeighbors(graph, edge, source, target);

			if (!isValid)
			{
				error += this.typeError + '\n';
			}
		}
	}
	
	return (error.length > 0) ? error : null;
};

/**
 * Function: checkNeighbors
 * 
 * Checks if there are any valid neighbours in <validNeighbors>. This is only
 * called if <validNeighbors> is a non-empty array.
 */
mxMultiplicity.prototype.checkNeighbors = function(graph, edge, source, target)
{
	var sourceValue = graph.model.getValue(source);
	var targetValue = graph.model.getValue(target);
	var isValid = !this.validNeighborsAllowed;
	var valid = this.validNeighbors;
	
	for (var j = 0; j < valid.length; j++)
	{
		if (this.source &&
			this.checkType(graph, targetValue, valid[j]))
		{
			isValid = this.validNeighborsAllowed;
			break;
		}
		else if (!this.source && 
			this.checkType(graph, sourceValue, valid[j]))
		{
			isValid = this.validNeighborsAllowed;
			break;
		}
	}
	
	return isValid;
};

/**
 * Function: checkTerminal
 * 
 * Checks the given terminal cell and returns true if this rule applies. The
 * given cell is the source or target of the given edge, depending on
 * <source>. This implementation uses <checkType> on the terminal's value.
 */
mxMultiplicity.prototype.checkTerminal = function(graph, terminal, edge)
{
	var value = graph.model.getValue(terminal);
	
	return this.checkType(graph, value, this.type, this.attr, this.value);
};

/**
 * Function: checkType
 * 
 * Checks the type of the given value.
 */
mxMultiplicity.prototype.checkType = function(graph, value, type, attr, attrValue)
{
	if (value != null)
	{
		if (!isNaN(value.nodeType)) // Checks if value is a DOM node
		{
			return mxUtils.isNode(value, type, attr, attrValue);
		}
		else
		{
			return value == type;
		}
	}
	
	return false;
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxLayoutManager
 * 
 * Implements a layout manager that runs a given layout after any changes to the graph:
 * 
 * Example:
 * 
 * (code)
 * var layoutMgr = new mxLayoutManager(graph);
 * layoutMgr.getLayout = function(cell)
 * {
 *   return layout;
 * };
 * (end)
 * 
 * Event: mxEvent.LAYOUT_CELLS
 * 
 * Fires between begin- and endUpdate after all cells have been layouted in
 * <layoutCells>. The <code>cells</code> property contains all cells that have
 * been passed to <layoutCells>.
 * 
 * Constructor: mxLayoutManager
 *
 * Constructs a new automatic layout for the given graph.
 *
 * Arguments:
 * 
 * graph - Reference to the enclosing graph. 
 */
function mxLayoutManager(graph)
{
	// Executes the layout before the changes are dispatched
	this.undoHandler = mxUtils.bind(this, function(sender, evt)
	{
		if (this.isEnabled())
		{
			this.beforeUndo(evt.getProperty('edit'));
		}
	});
	
	// Notifies the layout of a move operation inside a parent
	this.moveHandler = mxUtils.bind(this, function(sender, evt)
	{
		if (this.isEnabled())
		{
			this.cellsMoved(evt.getProperty('cells'), evt.getProperty('event'));
		}
	});
	
	this.setGraph(graph);
};

/**
 * Extends mxEventSource.
 */
mxLayoutManager.prototype = new mxEventSource();
mxLayoutManager.prototype.constructor = mxLayoutManager;

/**
 * Variable: graph
 * 
 * Reference to the enclosing <mxGraph>.
 */
mxLayoutManager.prototype.graph = null;

/**
 * Variable: bubbling
 * 
 * Specifies if the layout should bubble along
 * the cell hierarchy. Default is true.
 */
mxLayoutManager.prototype.bubbling = true;

/**
 * Variable: enabled
 * 
 * Specifies if event handling is enabled. Default is true.
 */
mxLayoutManager.prototype.enabled = true;

/**
 * Variable: updateHandler
 * 
 * Holds the function that handles the endUpdate event.
 */
mxLayoutManager.prototype.updateHandler = null;

/**
 * Variable: moveHandler
 * 
 * Holds the function that handles the move event.
 */
mxLayoutManager.prototype.moveHandler = null;

/**
 * Function: isEnabled
 * 
 * Returns true if events are handled. This implementation
 * returns <enabled>.
 */
mxLayoutManager.prototype.isEnabled = function()
{
	return this.enabled;
};

/**
 * Function: setEnabled
 * 
 * Enables or disables event handling. This implementation
 * updates <enabled>.
 * 
 * Parameters:
 * 
 * enabled - Boolean that specifies the new enabled state.
 */
mxLayoutManager.prototype.setEnabled = function(enabled)
{
	this.enabled = enabled;
};

/**
 * Function: isBubbling
 * 
 * Returns true if a layout should bubble, that is, if the parent layout
 * should be executed whenever a cell layout (layout of the children of
 * a cell) has been executed. This implementation returns <bubbling>.
 */
mxLayoutManager.prototype.isBubbling = function()
{
	return this.bubbling;
};

/**
 * Function: setBubbling
 * 
 * Sets <bubbling>.
 */
mxLayoutManager.prototype.setBubbling = function(value)
{
	this.bubbling = value;
};

/**
 * Function: getGraph
 * 
 * Returns the graph that this layout operates on.
 */
mxLayoutManager.prototype.getGraph = function()
{
	return this.graph;
};

/**
 * Function: setGraph
 * 
 * Sets the graph that the layouts operate on.
 */
mxLayoutManager.prototype.setGraph = function(graph)
{
	if (this.graph != null)
	{
		var model = this.graph.getModel();		
		model.removeListener(this.undoHandler);
		this.graph.removeListener(this.moveHandler);
	}
	
	this.graph = graph;
	
	if (this.graph != null)
	{
		var model = this.graph.getModel();	
		model.addListener(mxEvent.BEFORE_UNDO, this.undoHandler);
		this.graph.addListener(mxEvent.MOVE_CELLS, this.moveHandler);
	}
};

/**
 * Function: getLayout
 * 
 * Returns the layout to be executed for the given graph and parent.
 */
mxLayoutManager.prototype.getLayout = function(parent)
{
	return null;
};

/**
 * Function: beforeUndo
 * 
 * Called from the undoHandler.
 *
 * Parameters:
 * 
 * cell - Array of <mxCells> that have been moved.
 * evt - Mouse event that represents the mousedown.
 */
mxLayoutManager.prototype.beforeUndo = function(undoableEdit)
{
	var cells = this.getCellsForChanges(undoableEdit.changes);
	var model = this.getGraph().getModel();

	// Adds all descendants
	var tmp = [];
	
	for (var i = 0; i < cells.length; i++)
	{
		tmp = tmp.concat(model.getDescendants(cells[i]));
	}
	
	cells = tmp;
	
	// Adds all parent ancestors
	if (this.isBubbling())
	{
		tmp = model.getParents(cells);
		
		while (tmp.length > 0)
		{
			cells = cells.concat(tmp);
			tmp = model.getParents(tmp);
		}
	}
	
	this.executeLayoutForCells(cells);
};

/**
 * Function: executeLayout
 * 
 * Executes the given layout on the given parent.
 */
mxLayoutManager.prototype.executeLayoutForCells = function(cells)
{
	// Adds reverse to this array to avoid duplicate execution of leafes
	// Works like capture/bubble for events, first executes all layout
	// from top to bottom and in reverse order and removes duplicates.
	var sorted = mxUtils.sortCells(cells, true);
	sorted = sorted.concat(sorted.slice().reverse());
	this.layoutCells(sorted);
};

/**
 * Function: cellsMoved
 * 
 * Called from the moveHandler.
 *
 * Parameters:
 * 
 * cell - Array of <mxCells> that have been moved.
 * evt - Mouse event that represents the mousedown.
 */
mxLayoutManager.prototype.cellsMoved = function(cells, evt)
{
	if (cells != null && evt != null)
	{
		var point = mxUtils.convertPoint(this.getGraph().container,
			mxEvent.getClientX(evt), mxEvent.getClientY(evt));
		var model = this.getGraph().getModel();
		
		// Checks if a layout exists to take care of the moving if the
		// parent itself is not being moved
		for (var i = 0; i < cells.length; i++)
		{
			var parent = model.getParent(cells[i]);
			
			if (mxUtils.indexOf(cells, parent) < 0)
			{
				var layout = this.getLayout(parent);
	
				if (layout != null)
				{
					layout.moveCell(cells[i], point.x, point.y);
				}
			}
		}
	}
};

/**
 * Function: getCellsForEdit
 * 
 * Returns the cells to be layouted for the given sequence of changes.
 */
mxLayoutManager.prototype.getCellsForChanges = function(changes)
{
	var dict = new mxDictionary();
	var result = [];
	
	for (var i = 0; i < changes.length; i++)
	{
		var change = changes[i];
		
		if (change instanceof mxRootChange)
		{
			return [];
		}
		else
		{
			var cells = this.getCellsForChange(change);
			
			for (var j = 0; j < cells.length; j++)
			{
				if (cells[j] != null && !dict.get(cells[j]))
				{
					dict.put(cells[j], true);
					result.push(cells[j]);
				}
			}
		}
	}
	
	return result;
};

/**
 * Function: getCellsForChange
 * 
 * Executes all layouts which have been scheduled during the
 * changes.
 */
mxLayoutManager.prototype.getCellsForChange = function(change)
{
	var model = this.getGraph().getModel();
	
	if (change instanceof mxChildChange)
	{
		return [change.child, change.previous, model.getParent(change.child)];
	}
	else if (change instanceof mxTerminalChange || change instanceof mxGeometryChange)
	{
		return [change.cell, model.getParent(change.cell)];
	}
	else if (change instanceof mxVisibleChange || change instanceof mxStyleChange)
	{
		return [change.cell];
	}
	
	return [];
};

/**
 * Function: layoutCells
 * 
 * Executes all layouts which have been scheduled during the
 * changes.
 */
mxLayoutManager.prototype.layoutCells = function(cells)
{
	if (cells.length > 0)
	{
		// Invokes the layouts while removing duplicates
		var model = this.getGraph().getModel();
		
		model.beginUpdate();
		try 
		{
			var last = null;
			
			for (var i = 0; i < cells.length; i++)
			{
				if (cells[i] != model.getRoot() && cells[i] != last)
				{
					if (this.executeLayout(this.getLayout(cells[i]), cells[i]))
					{
						last = cells[i];
					}
				}
			}
			
			this.fireEvent(new mxEventObject(mxEvent.LAYOUT_CELLS, 'cells', cells));
		}
		finally
		{
			model.endUpdate();
		}
	}
};

/**
 * Function: executeLayout
 * 
 * Executes the given layout on the given parent.
 */
mxLayoutManager.prototype.executeLayout = function(layout, parent)
{
	var result = false;
	
	if (layout != null && parent != null)
	{
		layout.execute(parent);
		result = true;
	}
	
	return result;
};

/**
 * Function: destroy
 * 
 * Removes all handlers from the <graph> and deletes the reference to it.
 */
mxLayoutManager.prototype.destroy = function()
{
	this.setGraph(null);
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxSwimlaneManager
 * 
 * Manager for swimlanes and nested swimlanes that sets the size of newly added
 * swimlanes to that of their siblings, and propagates changes to the size of a
 * swimlane to its siblings, if <siblings> is true, and its ancestors, if
 * <bubbling> is true.
 * 
 * Constructor: mxSwimlaneManager
 *
 * Constructs a new swimlane manager for the given graph.
 *
 * Arguments:
 * 
 * graph - Reference to the enclosing graph. 
 */
function mxSwimlaneManager(graph, horizontal, addEnabled, resizeEnabled)
{
	this.horizontal = (horizontal != null) ? horizontal : true;
	this.addEnabled = (addEnabled != null) ? addEnabled : true;
	this.resizeEnabled = (resizeEnabled != null) ? resizeEnabled : true;

	this.addHandler = mxUtils.bind(this, function(sender, evt)
	{
		if (this.isEnabled() && this.isAddEnabled())
		{
			this.cellsAdded(evt.getProperty('cells'));
		}
	});
	
	this.resizeHandler = mxUtils.bind(this, function(sender, evt)
	{
		if (this.isEnabled() && this.isResizeEnabled())
		{
			this.cellsResized(evt.getProperty('cells'));
		}
	});
	
	this.setGraph(graph);
};

/**
 * Extends mxEventSource.
 */
mxSwimlaneManager.prototype = new mxEventSource();
mxSwimlaneManager.prototype.constructor = mxSwimlaneManager;

/**
 * Variable: graph
 * 
 * Reference to the enclosing <mxGraph>.
 */
mxSwimlaneManager.prototype.graph = null;

/**
 * Variable: enabled
 * 
 * Specifies if event handling is enabled. Default is true.
 */
mxSwimlaneManager.prototype.enabled = true;

/**
 * Variable: horizontal
 * 
 * Specifies the orientation of the swimlanes. Default is true.
 */
mxSwimlaneManager.prototype.horizontal = true;

/**
 * Variable: addEnabled
 * 
 * Specifies if newly added cells should be resized to match the size of their
 * existing siblings. Default is true.
 */
mxSwimlaneManager.prototype.addEnabled = true;

/**
 * Variable: resizeEnabled
 * 
 * Specifies if resizing of swimlanes should be handled. Default is true.
 */
mxSwimlaneManager.prototype.resizeEnabled = true;

/**
 * Variable: moveHandler
 * 
 * Holds the function that handles the move event.
 */
mxSwimlaneManager.prototype.addHandler = null;

/**
 * Variable: moveHandler
 * 
 * Holds the function that handles the move event.
 */
mxSwimlaneManager.prototype.resizeHandler = null;

/**
 * Function: isEnabled
 * 
 * Returns true if events are handled. This implementation
 * returns <enabled>.
 */
mxSwimlaneManager.prototype.isEnabled = function()
{
	return this.enabled;
};

/**
 * Function: setEnabled
 * 
 * Enables or disables event handling. This implementation
 * updates <enabled>.
 * 
 * Parameters:
 * 
 * enabled - Boolean that specifies the new enabled state.
 */
mxSwimlaneManager.prototype.setEnabled = function(value)
{
	this.enabled = value;
};

/**
 * Function: isHorizontal
 * 
 * Returns <horizontal>.
 */
mxSwimlaneManager.prototype.isHorizontal = function()
{
	return this.horizontal;
};

/**
 * Function: setHorizontal
 * 
 * Sets <horizontal>.
 */
mxSwimlaneManager.prototype.setHorizontal = function(value)
{
	this.horizontal = value;
};

/**
 * Function: isAddEnabled
 * 
 * Returns <addEnabled>.
 */
mxSwimlaneManager.prototype.isAddEnabled = function()
{
	return this.addEnabled;
};

/**
 * Function: setAddEnabled
 * 
 * Sets <addEnabled>.
 */
mxSwimlaneManager.prototype.setAddEnabled = function(value)
{
	this.addEnabled = value;
};

/**
 * Function: isResizeEnabled
 * 
 * Returns <resizeEnabled>.
 */
mxSwimlaneManager.prototype.isResizeEnabled = function()
{
	return this.resizeEnabled;
};

/**
 * Function: setResizeEnabled
 * 
 * Sets <resizeEnabled>.
 */
mxSwimlaneManager.prototype.setResizeEnabled = function(value)
{
	this.resizeEnabled = value;
};

/**
 * Function: getGraph
 * 
 * Returns the graph that this manager operates on.
 */
mxSwimlaneManager.prototype.getGraph = function()
{
	return this.graph;
};

/**
 * Function: setGraph
 * 
 * Sets the graph that the manager operates on.
 */
mxSwimlaneManager.prototype.setGraph = function(graph)
{
	if (this.graph != null)
	{
		this.graph.removeListener(this.addHandler);
		this.graph.removeListener(this.resizeHandler);
	}
	
	this.graph = graph;
	
	if (this.graph != null)
	{
		this.graph.addListener(mxEvent.ADD_CELLS, this.addHandler);
		this.graph.addListener(mxEvent.CELLS_RESIZED, this.resizeHandler);
	}
};

/**
 * Function: isSwimlaneIgnored
 * 
 * Returns true if the given swimlane should be ignored.
 */
mxSwimlaneManager.prototype.isSwimlaneIgnored = function(swimlane)
{
	return !this.getGraph().isSwimlane(swimlane);
};

/**
 * Function: isCellHorizontal
 * 
 * Returns true if the given cell is horizontal. If the given cell is not a
 * swimlane, then the global orientation is returned.
 */
mxSwimlaneManager.prototype.isCellHorizontal = function(cell)
{
	if (this.graph.isSwimlane(cell))
	{
		var style = this.graph.getCellStyle(cell);
		
		return mxUtils.getValue(style, mxConstants.STYLE_HORIZONTAL, 1) == 1;
	}
	
	return !this.isHorizontal();
};

/**
 * Function: cellsAdded
 * 
 * Called if any cells have been added.
 * 
 * Parameters:
 * 
 * cell - Array of <mxCells> that have been added.
 */
mxSwimlaneManager.prototype.cellsAdded = function(cells)
{
	if (cells != null)
	{
		var model = this.getGraph().getModel();

		model.beginUpdate();
		try
		{
			for (var i = 0; i < cells.length; i++)
			{
				if (!this.isSwimlaneIgnored(cells[i]))
				{
					this.swimlaneAdded(cells[i]);
				}
			}
		}
		finally
		{
			model.endUpdate();
		}
	}
};

/**
 * Function: swimlaneAdded
 * 
 * Updates the size of the given swimlane to match that of any existing
 * siblings swimlanes.
 * 
 * Parameters:
 * 
 * swimlane - <mxCell> that represents the new swimlane.
 */
mxSwimlaneManager.prototype.swimlaneAdded = function(swimlane)
{
	var model = this.getGraph().getModel();
	var parent = model.getParent(swimlane);
	var childCount = model.getChildCount(parent);
	var geo = null;
	
	// Finds the first valid sibling swimlane as reference
	for (var i = 0; i < childCount; i++)
	{
		var child = model.getChildAt(parent, i);
		
		if (child != swimlane && !this.isSwimlaneIgnored(child))
		{
			geo = model.getGeometry(child);
			
			if (geo != null)
			{	
				break;
			}
		}
	}
	
	// Applies the size of the refernece to the newly added swimlane
	if (geo != null)
	{
		var parentHorizontal = (parent != null) ? this.isCellHorizontal(parent) : this.horizontal;
		this.resizeSwimlane(swimlane, geo.width, geo.height, parentHorizontal);
	}
};

/**
 * Function: cellsResized
 * 
 * Called if any cells have been resizes. Calls <swimlaneResized> for all
 * swimlanes where <isSwimlaneIgnored> returns false.
 * 
 * Parameters:
 * 
 * cells - Array of <mxCells> whose size was changed.
 */
mxSwimlaneManager.prototype.cellsResized = function(cells)
{
	if (cells != null)
	{
		var model = this.getGraph().getModel();
		
		model.beginUpdate();
		try
		{
			// Finds the top-level swimlanes and adds offsets
			for (var i = 0; i < cells.length; i++)
			{
				if (!this.isSwimlaneIgnored(cells[i]))
				{
					var geo = model.getGeometry(cells[i]);

					if (geo != null)
					{
						var size = new mxRectangle(0, 0, geo.width, geo.height);
						var top = cells[i];
						var current = top;
						
						while (current != null)
						{
							top = current;
							current = model.getParent(current);
							var tmp = (this.graph.isSwimlane(current)) ?
									this.graph.getStartSize(current) :
									new mxRectangle();
							size.width += tmp.width;
							size.height += tmp.height;
						}
						
						var parentHorizontal = (current != null) ? this.isCellHorizontal(current) : this.horizontal;
						this.resizeSwimlane(top, size.width, size.height, parentHorizontal);
					}
				}
			}
		}
		finally
		{
			model.endUpdate();
		}
	}
};

/**
 * Function: resizeSwimlane
 * 
 * Called from <cellsResized> for all swimlanes that are not ignored to update
 * the size of the siblings and the size of the parent swimlanes, recursively,
 * if <bubbling> is true.
 * 
 * Parameters:
 * 
 * swimlane - <mxCell> whose size has changed.
 */
mxSwimlaneManager.prototype.resizeSwimlane = function(swimlane, w, h, parentHorizontal)
{
	var model = this.getGraph().getModel();
	
	model.beginUpdate();
	try
	{
		var horizontal = this.isCellHorizontal(swimlane);
		
		if (!this.isSwimlaneIgnored(swimlane))
		{
			var geo = model.getGeometry(swimlane);
			
			if (geo != null)
			{
				if ((parentHorizontal && geo.height != h) || (!parentHorizontal && geo.width != w))
				{
					geo = geo.clone();
					
					if (parentHorizontal)
					{
						geo.height = h;
					}
					else
					{
						geo.width = w;
					}

					model.setGeometry(swimlane, geo);
				}
			}
		}

		var tmp = (this.graph.isSwimlane(swimlane)) ?
				this.graph.getStartSize(swimlane) :
				new mxRectangle();
		w -= tmp.width;
		h -= tmp.height;
		
		var childCount = model.getChildCount(swimlane);
		
		for (var i = 0; i < childCount; i++)
		{
			var child = model.getChildAt(swimlane, i);
			this.resizeSwimlane(child, w, h, horizontal);
		}
	}
	finally
	{
		model.endUpdate();
	}
};

/**
 * Function: destroy
 * 
 * Removes all handlers from the <graph> and deletes the reference to it.
 */
mxSwimlaneManager.prototype.destroy = function()
{
	this.setGraph(null);
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxTemporaryCellStates
 *
 * Extends <mxPoint> to implement a 2-dimensional rectangle with double
 * precision coordinates.
 * 
 * Constructor: mxRectangle
 *
 * Constructs a new rectangle for the optional parameters. If no parameters
 * are given then the respective default values are used.
 */
function mxTemporaryCellStates(view, scale, cells, isCellVisibleFn)
{
	scale = (scale != null) ? scale : 1;
	this.view = view;
	
	// Stores the previous state
	this.oldValidateCellState = view.validateCellState;
	this.oldBounds = view.getGraphBounds();
	this.oldStates = view.getStates();
	this.oldScale = view.getScale();
	
	// Overrides validateCellState to ignore invisible cells
	var self = this;
	
	view.validateCellState = function(cell, resurse)
	{
		if (cell == null || isCellVisibleFn == null || isCellVisibleFn(cell))
		{
			return self.oldValidateCellState.apply(view, arguments);
		}
		
		return null;
	};
	
	// Creates space for new states
	view.setStates(new mxDictionary());
	view.setScale(scale);
	
	if (cells != null)
	{
		view.resetValidationState();
		var bbox = null;

		// Validates the vertices and edges without adding them to
		// the model so that the original cells are not modified
		for (var i = 0; i < cells.length; i++)
		{
			var bounds = view.getBoundingBox(view.validateCellState(view.validateCell(cells[i])));
			
			if (bbox == null)
			{
				bbox = bounds;
			}
			else
			{
				bbox.add(bounds);
			}
		}

		view.setGraphBounds(bbox || new mxRectangle());
	}
};

/**
 * Variable: view
 *
 * Holds the width of the rectangle. Default is 0.
 */
mxTemporaryCellStates.prototype.view = null;

/**
 * Variable: oldStates
 *
 * Holds the height of the rectangle. Default is 0.
 */
mxTemporaryCellStates.prototype.oldStates = null;

/**
 * Variable: oldBounds
 *
 * Holds the height of the rectangle. Default is 0.
 */
mxTemporaryCellStates.prototype.oldBounds = null;

/**
 * Variable: oldScale
 *
 * Holds the height of the rectangle. Default is 0.
 */
mxTemporaryCellStates.prototype.oldScale = null;

/**
 * Function: destroy
 * 
 * Returns the top, left corner as a new <mxPoint>.
 */
mxTemporaryCellStates.prototype.destroy = function()
{
	this.view.setScale(this.oldScale);
	this.view.setStates(this.oldStates);
	this.view.setGraphBounds(this.oldBounds);
	this.view.validateCellState = this.oldValidateCellState;
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 *
 * Class: mxCellStatePreview
 * 
 * Implements a live preview for moving cells.
 * 
 * Constructor: mxCellStatePreview
 * 
 * Constructs a move preview for the given graph.
 * 
 * Parameters:
 * 
 * graph - Reference to the enclosing <mxGraph>.
 */
function mxCellStatePreview(graph)
{
	this.deltas = new mxDictionary();
	this.graph = graph;
};

/**
 * Variable: graph
 * 
 * Reference to the enclosing <mxGraph>.
 */
mxCellStatePreview.prototype.graph = null;

/**
 * Variable: deltas
 * 
 * Reference to the enclosing <mxGraph>.
 */
mxCellStatePreview.prototype.deltas = null;

/**
 * Variable: count
 * 
 * Contains the number of entries in the map.
 */
mxCellStatePreview.prototype.count = 0;

/**
 * Function: isEmpty
 * 
 * Returns true if this contains no entries.
 */
mxCellStatePreview.prototype.isEmpty = function()
{
	return this.count == 0;
};

/**
 * Function: moveState
 */
mxCellStatePreview.prototype.moveState = function(state, dx, dy, add, includeEdges)
{
	add = (add != null) ? add : true;
	includeEdges = (includeEdges != null) ? includeEdges : true;
	
	var delta = this.deltas.get(state.cell);

	if (delta == null)
	{
		// Note: Deltas stores the point and the state since the key is a string.
		delta = {point: new mxPoint(dx, dy), state: state};
		this.deltas.put(state.cell, delta);
		this.count++;
	}
	else if (add)
	{
		delta.point.x += dx;
		delta.point.y += dy;
	}
	else
	{
		delta.point.x = dx;
		delta.point.y = dy;
	}
	
	if (includeEdges)
	{
		this.addEdges(state);
	}
	
	return delta.point;
};

/**
 * Function: show
 */
mxCellStatePreview.prototype.show = function(visitor)
{
	this.deltas.visit(mxUtils.bind(this, function(key, delta)
	{
		this.translateState(delta.state, delta.point.x, delta.point.y);
	}));
	
	this.deltas.visit(mxUtils.bind(this, function(key, delta)
	{
		this.revalidateState(delta.state, delta.point.x, delta.point.y, visitor);
	}));
};

/**
 * Function: translateState
 */
mxCellStatePreview.prototype.translateState = function(state, dx, dy)
{
	if (state != null)
	{
		var model = this.graph.getModel();
		
		if (model.isVertex(state.cell))
		{
			state.view.updateCellState(state);
			var geo = model.getGeometry(state.cell);
			
			// Moves selection cells and non-relative vertices in
			// the first phase so that edge terminal points will
			// be updated in the second phase
			if ((dx != 0 || dy != 0) && geo != null && (!geo.relative || this.deltas.get(state.cell) != null))
			{
				state.x += dx;
				state.y += dy;
			}
		}
	    
	    var childCount = model.getChildCount(state.cell);
	    
	    for (var i = 0; i < childCount; i++)
	    {
	    	this.translateState(state.view.getState(model.getChildAt(state.cell, i)), dx, dy);
	    }
	}
};

/**
 * Function: revalidateState
 */
mxCellStatePreview.prototype.revalidateState = function(state, dx, dy, visitor)
{
	if (state != null)
	{
		var model = this.graph.getModel();
		
		// Updates the edge terminal points and restores the
		// (relative) positions of any (relative) children
		if (model.isEdge(state.cell))
		{
			state.view.updateCellState(state);
		}

		var geo = this.graph.getCellGeometry(state.cell);
		var pState = state.view.getState(model.getParent(state.cell));
		
		// Moves selection vertices which are relative
		if ((dx != 0 || dy != 0) && geo != null && geo.relative &&
			model.isVertex(state.cell) && (pState == null ||
			model.isVertex(pState.cell) || this.deltas.get(state.cell) != null))
		{
			state.x += dx;
			state.y += dy;
		}
		
		this.graph.cellRenderer.redraw(state);
	
		// Invokes the visitor on the given state
		if (visitor != null)
		{
			visitor(state);
		}
						
	    var childCount = model.getChildCount(state.cell);
	    
	    for (var i = 0; i < childCount; i++)
	    {
	    	this.revalidateState(this.graph.view.getState(model.getChildAt(state.cell, i)), dx, dy, visitor);
	    }
	}
};

/**
 * Function: addEdges
 */
mxCellStatePreview.prototype.addEdges = function(state)
{
	var model = this.graph.getModel();
	var edgeCount = model.getEdgeCount(state.cell);

	for (var i = 0; i < edgeCount; i++)
	{
		var s = state.view.getState(model.getEdgeAt(state.cell, i));

		if (s != null)
		{
			this.moveState(s, 0, 0);
		}
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxConnectionConstraint
 * 
 * Defines an object that contains the constraints about how to connect one
 * side of an edge to its terminal.
 * 
 * Constructor: mxConnectionConstraint
 * 
 * Constructs a new connection constraint for the given point and boolean
 * arguments.
 * 
 * Parameters:
 * 
 * point - Optional <mxPoint> that specifies the fixed location of the point
 * in relative coordinates. Default is null.
 * perimeter - Optional boolean that specifies if the fixed point should be
 * projected onto the perimeter of the terminal. Default is true.
 */
function mxConnectionConstraint(point, perimeter, name)
{
	this.point = point;
	this.perimeter = (perimeter != null) ? perimeter : true;
	this.name = name;
};

/**
 * Variable: point
 * 
 * <mxPoint> that specifies the fixed location of the connection point.
 */
mxConnectionConstraint.prototype.point = null;

/**
 * Variable: perimeter
 * 
 * Boolean that specifies if the point should be projected onto the perimeter
 * of the terminal.
 */
mxConnectionConstraint.prototype.perimeter = null;

/**
 * Variable: name
 * 
 * Optional string that specifies the name of the constraint.
 */
mxConnectionConstraint.prototype.name = null;
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxGraphHandler
 * 
 * Graph event handler that handles selection. Individual cells are handled
 * separately using <mxVertexHandler> or one of the edge handlers. These
 * handlers are created using <mxGraph.createHandler> in
 * <mxGraphSelectionModel.cellAdded>.
 * 
 * To avoid the container to scroll a moved cell into view, set
 * <scrollAfterMove> to false.
 * 
 * Constructor: mxGraphHandler
 * 
 * Constructs an event handler that creates handles for the
 * selection cells.
 * 
 * Parameters:
 * 
 * graph - Reference to the enclosing <mxGraph>.
 */
function mxGraphHandler(graph)
{
	this.graph = graph;
	this.graph.addMouseListener(this);
	
	// Repaints the handler after autoscroll
	this.panHandler = mxUtils.bind(this, function()
	{
		this.updatePreviewShape();
		this.updateHint();
	});
	
	this.graph.addListener(mxEvent.PAN, this.panHandler);
	
	// Handles escape keystrokes
	this.escapeHandler = mxUtils.bind(this, function(sender, evt)
	{
		this.reset();
	});
	
	this.graph.addListener(mxEvent.ESCAPE, this.escapeHandler);
};

/**
 * Variable: graph
 * 
 * Reference to the enclosing <mxGraph>.
 */
mxGraphHandler.prototype.graph = null;

/**
 * Variable: maxCells
 * 
 * Defines the maximum number of cells to paint subhandles
 * for. Default is 50 for Firefox and 20 for IE. Set this
 * to 0 if you want an unlimited number of handles to be
 * displayed. This is only recommended if the number of
 * cells in the graph is limited to a small number, eg.
 * 500.
 */
mxGraphHandler.prototype.maxCells = (mxClient.IS_IE) ? 20 : 50;

/**
 * Variable: enabled
 * 
 * Specifies if events are handled. Default is true.
 */
mxGraphHandler.prototype.enabled = true;

/**
 * Variable: highlightEnabled
 * 
 * Specifies if drop targets under the mouse should be enabled. Default is
 * true.
 */
mxGraphHandler.prototype.highlightEnabled = true;

/**
 * Variable: cloneEnabled
 * 
 * Specifies if cloning by control-drag is enabled. Default is true.
 */
mxGraphHandler.prototype.cloneEnabled = true;

/**
 * Variable: moveEnabled
 * 
 * Specifies if moving is enabled. Default is true.
 */
mxGraphHandler.prototype.moveEnabled = true;

/**
 * Variable: guidesEnabled
 * 
 * Specifies if other cells should be used for snapping the right, center or
 * left side of the current selection. Default is false.
 */
mxGraphHandler.prototype.guidesEnabled = false;

/**
 * Variable: guide
 * 
 * Holds the <mxGuide> instance that is used for alignment.
 */
mxGraphHandler.prototype.guide = null;

/**
 * Variable: currentDx
 * 
 * Stores the x-coordinate of the current mouse move.
 */
mxGraphHandler.prototype.currentDx = null;

/**
 * Variable: currentDy
 * 
 * Stores the y-coordinate of the current mouse move.
 */
mxGraphHandler.prototype.currentDy = null;

/**
 * Variable: updateCursor
 * 
 * Specifies if a move cursor should be shown if the mouse is over a movable
 * cell. Default is true.
 */
mxGraphHandler.prototype.updateCursor = true;

/**
 * Variable: selectEnabled
 * 
 * Specifies if selecting is enabled. Default is true.
 */
mxGraphHandler.prototype.selectEnabled = true;

/**
 * Variable: removeCellsFromParent
 * 
 * Specifies if cells may be moved out of their parents. Default is true.
 */
mxGraphHandler.prototype.removeCellsFromParent = true;

/**
 * Variable: connectOnDrop
 * 
 * Specifies if drop events are interpreted as new connections if no other
 * drop action is defined. Default is false.
 */
mxGraphHandler.prototype.connectOnDrop = false;

/**
 * Variable: scrollOnMove
 * 
 * Specifies if the view should be scrolled so that a moved cell is
 * visible. Default is true.
 */
mxGraphHandler.prototype.scrollOnMove = true;

/**
 * Variable: minimumSize
 * 
 * Specifies the minimum number of pixels for the width and height of a
 * selection border. Default is 6.
 */
mxGraphHandler.prototype.minimumSize = 6;

/**
 * Variable: previewColor
 * 
 * Specifies the color of the preview shape. Default is black.
 */
mxGraphHandler.prototype.previewColor = 'black';

/**
 * Variable: htmlPreview
 * 
 * Specifies if the graph container should be used for preview. If this is used
 * then drop target detection relies entirely on <mxGraph.getCellAt> because
 * the HTML preview does not "let events through". Default is false.
 */
mxGraphHandler.prototype.htmlPreview = false;

/**
 * Variable: shape
 * 
 * Reference to the <mxShape> that represents the preview.
 */
mxGraphHandler.prototype.shape = null;

/**
 * Variable: scaleGrid
 * 
 * Specifies if the grid should be scaled. Default is false.
 */
mxGraphHandler.prototype.scaleGrid = false;

/**
 * Variable: rotationEnabled
 * 
 * Specifies if the bounding box should allow for rotation. Default is true.
 */
mxGraphHandler.prototype.rotationEnabled = true;

/**
 * Function: isEnabled
 * 
 * Returns <enabled>.
 */
mxGraphHandler.prototype.isEnabled = function()
{
	return this.enabled;
};

/**
 * Function: setEnabled
 * 
 * Sets <enabled>.
 */
mxGraphHandler.prototype.setEnabled = function(value)
{
	this.enabled = value;
};

/**
 * Function: isCloneEnabled
 * 
 * Returns <cloneEnabled>.
 */
mxGraphHandler.prototype.isCloneEnabled = function()
{
	return this.cloneEnabled;
};

/**
 * Function: setCloneEnabled
 * 
 * Sets <cloneEnabled>.
 * 
 * Parameters:
 * 
 * value - Boolean that specifies the new clone enabled state.
 */
mxGraphHandler.prototype.setCloneEnabled = function(value)
{
	this.cloneEnabled = value;
};

/**
 * Function: isMoveEnabled
 * 
 * Returns <moveEnabled>.
 */
mxGraphHandler.prototype.isMoveEnabled = function()
{
	return this.moveEnabled;
};

/**
 * Function: setMoveEnabled
 * 
 * Sets <moveEnabled>.
 */
mxGraphHandler.prototype.setMoveEnabled = function(value)
{
	this.moveEnabled = value;
};

/**
 * Function: isSelectEnabled
 * 
 * Returns <selectEnabled>.
 */
mxGraphHandler.prototype.isSelectEnabled = function()
{
	return this.selectEnabled;
};

/**
 * Function: setSelectEnabled
 * 
 * Sets <selectEnabled>.
 */
mxGraphHandler.prototype.setSelectEnabled = function(value)
{
	this.selectEnabled = value;
};

/**
 * Function: isRemoveCellsFromParent
 * 
 * Returns <removeCellsFromParent>.
 */
mxGraphHandler.prototype.isRemoveCellsFromParent = function()
{
	return this.removeCellsFromParent;
};

/**
 * Function: setRemoveCellsFromParent
 * 
 * Sets <removeCellsFromParent>.
 */
mxGraphHandler.prototype.setRemoveCellsFromParent = function(value)
{
	this.removeCellsFromParent = value;
};

/**
 * Function: getInitialCellForEvent
 * 
 * Hook to return initial cell for the given event.
 */
mxGraphHandler.prototype.getInitialCellForEvent = function(me)
{
	return me.getCell();
};

/**
 * Function: isDelayedSelection
 * 
 * Hook to return true for delayed selections.
 */
mxGraphHandler.prototype.isDelayedSelection = function(cell, me)
{
	return this.graph.isCellSelected(cell);
};

/**
 * Function: consumeMouseEvent
 * 
 * Consumes the given mouse event. NOTE: This may be used to enable click
 * events for links in labels on iOS as follows as consuming the initial
 * touchStart disables firing the subsequent click evnent on the link.
 * 
 * <code>
 * mxGraphHandler.prototype.consumeMouseEvent = function(evtName, me)
 * {
 *   var source = mxEvent.getSource(me.getEvent());
 *   
 *   if (!mxEvent.isTouchEvent(me.getEvent()) || source.nodeName != 'A')
 *   {
 *     me.consume();
 *   }
 * }
 * </code>
 */
mxGraphHandler.prototype.consumeMouseEvent = function(evtName, me)
{
	me.consume();
};

/**
 * Function: mouseDown
 * 
 * Handles the event by selecing the given cell and creating a handle for
 * it. By consuming the event all subsequent events of the gesture are
 * redirected to this handler.
 */
mxGraphHandler.prototype.mouseDown = function(sender, me)
{
	if (!me.isConsumed() && this.isEnabled() && this.graph.isEnabled() &&
		me.getState() != null && !mxEvent.isMultiTouchEvent(me.getEvent()))
	{
		var cell = this.getInitialCellForEvent(me);
		this.delayedSelection = this.isDelayedSelection(cell, me);
		this.cell = null;
		
		if (this.isSelectEnabled() && !this.delayedSelection)
		{
			this.graph.selectCellForEvent(cell, me.getEvent());
		}

		if (this.isMoveEnabled())
		{
			var model = this.graph.model;
			var geo = model.getGeometry(cell);

			if (this.graph.isCellMovable(cell) && ((!model.isEdge(cell) || this.graph.getSelectionCount() > 1 ||
				(geo.points != null && geo.points.length > 0) || model.getTerminal(cell, true) == null ||
				model.getTerminal(cell, false) == null) || this.graph.allowDanglingEdges || 
				(this.graph.isCloneEvent(me.getEvent()) && this.graph.isCellsCloneable())))
			{
				this.start(cell, me.getX(), me.getY());
			}
			else if (this.delayedSelection)
			{
				this.cell = cell;
			}

			this.cellWasClicked = true;
			this.consumeMouseEvent(mxEvent.MOUSE_DOWN, me);
		}
	}
};

/**
 * Function: getGuideStates
 * 
 * Creates an array of cell states which should be used as guides.
 */
mxGraphHandler.prototype.getGuideStates = function()
{
	var parent = this.graph.getDefaultParent();
	var model = this.graph.getModel();
	
	var filter = mxUtils.bind(this, function(cell)
	{
		return this.graph.view.getState(cell) != null &&
			model.isVertex(cell) &&
			model.getGeometry(cell) != null &&
			!model.getGeometry(cell).relative;
	});
	
	return this.graph.view.getCellStates(model.filterDescendants(filter, parent));
};

/**
 * Function: getCells
 * 
 * Returns the cells to be modified by this handler. This implementation
 * returns all selection cells that are movable, or the given initial cell if
 * the given cell is not selected and movable. This handles the case of moving
 * unselectable or unselected cells.
 * 
 * Parameters:
 * 
 * initialCell - <mxCell> that triggered this handler.
 */
mxGraphHandler.prototype.getCells = function(initialCell)
{
	if (!this.delayedSelection && this.graph.isCellMovable(initialCell))
	{
		return [initialCell];
	}
	else
	{
		return this.graph.getMovableCells(this.graph.getSelectionCells());
	}
};

/**
 * Function: getPreviewBounds
 * 
 * Returns the <mxRectangle> used as the preview bounds for
 * moving the given cells.
 */
mxGraphHandler.prototype.getPreviewBounds = function(cells)
{
	var bounds = this.getBoundingBox(cells);
	
	if (bounds != null)
	{
		// Corrects width and height
		bounds.width = Math.max(0, bounds.width - 1);
		bounds.height = Math.max(0, bounds.height - 1);
		
		if (bounds.width < this.minimumSize)
		{
			var dx = this.minimumSize - bounds.width;
			bounds.x -= dx / 2;
			bounds.width = this.minimumSize;
		}
		else
		{
			bounds.x = Math.round(bounds.x);
			bounds.width = Math.ceil(bounds.width);
		}
		
		var tr = this.graph.view.translate;
		var s = this.graph.view.scale;
		
		if (bounds.height < this.minimumSize)
		{
			var dy = this.minimumSize - bounds.height;
			bounds.y -= dy / 2;
			bounds.height = this.minimumSize;
		}
		else
		{
			bounds.y = Math.round(bounds.y);
			bounds.height = Math.ceil(bounds.height);
		}
	}
	
	return bounds;
};

/**
 * Function: getBoundingBox
 * 
 * Returns the union of the <mxCellStates> for the given array of <mxCells>.
 * For vertices, this method uses the bounding box of the corresponding shape
 * if one exists. The bounding box of the corresponding text label and all
 * controls and overlays are ignored. See also: <mxGraphView.getBounds> and
 * <mxGraph.getBoundingBox>.
 *
 * Parameters:
 *
 * cells - Array of <mxCells> whose bounding box should be returned.
 */
mxGraphHandler.prototype.getBoundingBox = function(cells)
{
	var result = null;
	
	if (cells != null && cells.length > 0)
	{
		var model = this.graph.getModel();
		
		for (var i = 0; i < cells.length; i++)
		{
			if (model.isVertex(cells[i]) || model.isEdge(cells[i]))
			{
				var state = this.graph.view.getState(cells[i]);
			
				if (state != null)
				{
					var bbox = state;
					
					if (model.isVertex(cells[i]) && state.shape != null && state.shape.boundingBox != null)
					{
						bbox = state.shape.boundingBox;
					}
					
					if (result == null)
					{
						result = mxRectangle.fromRectangle(bbox);
					}
					else
					{
						result.add(bbox);
					}
				}
			}
		}
	}
	
	return result;
};

/**
 * Function: createPreviewShape
 * 
 * Creates the shape used to draw the preview for the given bounds.
 */
mxGraphHandler.prototype.createPreviewShape = function(bounds)
{
	var shape = new mxRectangleShape(bounds, null, this.previewColor);
	shape.isDashed = true;
	
	if (this.htmlPreview)
	{
		shape.dialect = mxConstants.DIALECT_STRICTHTML;
		shape.init(this.graph.container);
	}
	else
	{
		// Makes sure to use either VML or SVG shapes in order to implement
		// event-transparency on the background area of the rectangle since
		// HTML shapes do not let mouseevents through even when transparent
		shape.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
			mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
		shape.init(this.graph.getView().getOverlayPane());
		shape.pointerEvents = false;
		
		// Workaround for artifacts on iOS
		if (mxClient.IS_IOS)
		{
			shape.getSvgScreenOffset = function()
			{
				return 0;
			};
		}
	}
	
	return shape;
};

/**
 * Function: start
 * 
 * Starts the handling of the mouse gesture.
 */
mxGraphHandler.prototype.start = function(cell, x, y)
{
	this.cell = cell;
	this.first = mxUtils.convertPoint(this.graph.container, x, y);
	this.cells = this.getCells(this.cell);
	this.bounds = this.graph.getView().getBounds(this.cells);
	this.pBounds = this.getPreviewBounds(this.cells);

	if (this.guidesEnabled)
	{
		this.guide = new mxGuide(this.graph, this.getGuideStates());
	}
};

/**
 * Function: useGuidesForEvent
 * 
 * Returns true if the guides should be used for the given <mxMouseEvent>.
 * This implementation returns <mxGuide.isEnabledForEvent>.
 */
mxGraphHandler.prototype.useGuidesForEvent = function(me)
{
	return (this.guide != null) ? this.guide.isEnabledForEvent(me.getEvent()) : true;
};


/**
 * Function: snap
 * 
 * Snaps the given vector to the grid and returns the given mxPoint instance.
 */
mxGraphHandler.prototype.snap = function(vector)
{
	var scale = (this.scaleGrid) ? this.graph.view.scale : 1;
	
	vector.x = this.graph.snap(vector.x / scale) * scale;
	vector.y = this.graph.snap(vector.y / scale) * scale;
	
	return vector;
};

/**
 * Function: getDelta
 * 
 * Returns an <mxPoint> that represents the vector for moving the cells
 * for the given <mxMouseEvent>.
 */
mxGraphHandler.prototype.getDelta = function(me)
{
	var point = mxUtils.convertPoint(this.graph.container, me.getX(), me.getY());
	var s = this.graph.view.scale;
	
	return new mxPoint(this.roundLength((point.x - this.first.x) / s) * s,
		this.roundLength((point.y - this.first.y) / s) * s);
};

/**
 * Function: updateHint
 * 
 * Hook for subclassers do show details while the handler is active.
 */
mxGraphHandler.prototype.updateHint = function(me) { };

/**
 * Function: removeHint
 * 
 * Hooks for subclassers to hide details when the handler gets inactive.
 */
mxGraphHandler.prototype.removeHint = function() { };

/**
 * Function: roundLength
 * 
 * Hook for rounding the unscaled vector. This uses Math.round.
 */
mxGraphHandler.prototype.roundLength = function(length)
{
	return Math.round(length);
};

/**
 * Function: mouseMove
 * 
 * Handles the event by highlighting possible drop targets and updating the
 * preview.
 */
mxGraphHandler.prototype.mouseMove = function(sender, me)
{
	var graph = this.graph;

	if (!me.isConsumed() && graph.isMouseDown && this.cell != null &&
		this.first != null && this.bounds != null)
	{
		// Stops moving if a multi touch event is received
		if (mxEvent.isMultiTouchEvent(me.getEvent()))
		{
			this.reset();
			return;
		}
		
		var delta = this.getDelta(me);
		var dx = delta.x;
		var dy = delta.y;
		var tol = graph.tolerance;

		if (this.shape != null || Math.abs(dx) > tol || Math.abs(dy) > tol)
		{
			// Highlight is used for highlighting drop targets
			if (this.highlight == null)
			{
				this.highlight = new mxCellHighlight(this.graph,
					mxConstants.DROP_TARGET_COLOR, 3);
			}
			
			if (this.shape == null)
			{
				this.shape = this.createPreviewShape(this.bounds);
			}
			
			var gridEnabled = graph.isGridEnabledEvent(me.getEvent());
			var hideGuide = true;
			
			if (this.guide != null && this.useGuidesForEvent(me))
			{
				delta = this.guide.move(this.bounds, new mxPoint(dx, dy), gridEnabled);
				hideGuide = false;
				dx = delta.x;
				dy = delta.y;
			}
			else if (gridEnabled)
			{
				var trx = graph.getView().translate;
				var scale = graph.getView().scale;				
				
				var tx = this.bounds.x - (graph.snap(this.bounds.x / scale - trx.x) + trx.x) * scale;
				var ty = this.bounds.y - (graph.snap(this.bounds.y / scale - trx.y) + trx.y) * scale;
				var v = this.snap(new mxPoint(dx, dy));
			
				dx = v.x - tx;
				dy = v.y - ty;
			}
			
			if (this.guide != null && hideGuide)
			{
				this.guide.hide();
			}

			// Constrained movement if shift key is pressed
			if (graph.isConstrainedEvent(me.getEvent()))
			{
				if (Math.abs(dx) > Math.abs(dy))
				{
					dy = 0;
				}
				else
				{
					dx = 0;
				}
			}

			this.currentDx = dx;
			this.currentDy = dy;
			this.updatePreviewShape();

			var target = null;
			var cell = me.getCell();

			var clone = graph.isCloneEvent(me.getEvent()) && graph.isCellsCloneable() && this.isCloneEnabled();
			
			if (graph.isDropEnabled() && this.highlightEnabled)
			{
				// Contains a call to getCellAt to find the cell under the mouse
				target = graph.getDropTarget(this.cells, me.getEvent(), cell, clone);
			}

			var state = graph.getView().getState(target);
			var highlight = false;
			
			if (state != null && (graph.model.getParent(this.cell) != target || clone))
			{
			    if (this.target != target)
			    {
				    this.target = target;
				    this.setHighlightColor(mxConstants.DROP_TARGET_COLOR);
				}
			    
			    highlight = true;
			}
			else
			{
				this.target = null;

				if (this.connectOnDrop && cell != null && this.cells.length == 1 &&
					graph.getModel().isVertex(cell) && graph.isCellConnectable(cell))
				{
					state = graph.getView().getState(cell);
					
					if (state != null)
					{
						var error = graph.getEdgeValidationError(null, this.cell, cell);
						var color = (error == null) ?
							mxConstants.VALID_COLOR :
							mxConstants.INVALID_CONNECT_TARGET_COLOR;
						this.setHighlightColor(color);
						highlight = true;
					}
				}
			}
			
			if (state != null && highlight)
			{
				this.highlight.highlight(state);
			}
			else
			{
				this.highlight.hide();
			}
		}

		this.updateHint(me);
		this.consumeMouseEvent(mxEvent.MOUSE_MOVE, me);
		
		// Cancels the bubbling of events to the container so
		// that the droptarget is not reset due to an mouseMove
		// fired on the container with no associated state.
		mxEvent.consume(me.getEvent());
	}
	else if ((this.isMoveEnabled() || this.isCloneEnabled()) && this.updateCursor &&
		!me.isConsumed() && me.getState() != null && !graph.isMouseDown)
	{
		var cursor = graph.getCursorForMouseEvent(me);
		
		if (cursor == null && graph.isEnabled() && graph.isCellMovable(me.getCell()))
		{
			if (graph.getModel().isEdge(me.getCell()))
			{
				cursor = mxConstants.CURSOR_MOVABLE_EDGE;
			}
			else
			{
				cursor = mxConstants.CURSOR_MOVABLE_VERTEX;
			}
		}

		// Sets the cursor on the original source state under the mouse
		// instead of the event source state which can be the parent
		if (me.sourceState != null)
		{
			me.sourceState.setCursor(cursor);
		}
	}
};

/**
 * Function: updatePreviewShape
 * 
 * Updates the bounds of the preview shape.
 */
mxGraphHandler.prototype.updatePreviewShape = function()
{
	if (this.shape != null)
	{
		this.shape.bounds = new mxRectangle(Math.round(this.pBounds.x + this.currentDx - this.graph.panDx),
				Math.round(this.pBounds.y + this.currentDy - this.graph.panDy), this.pBounds.width, this.pBounds.height);
		this.shape.redraw();
	}
};

/**
 * Function: setHighlightColor
 * 
 * Sets the color of the rectangle used to highlight drop targets.
 * 
 * Parameters:
 * 
 * color - String that represents the new highlight color.
 */
mxGraphHandler.prototype.setHighlightColor = function(color)
{
	if (this.highlight != null)
	{
		this.highlight.setHighlightColor(color);
	}
};

/**
 * Function: mouseUp
 * 
 * Handles the event by applying the changes to the selection cells.
 */
mxGraphHandler.prototype.mouseUp = function(sender, me)
{
	if (!me.isConsumed())
	{
		var graph = this.graph;
		
		if (this.cell != null && this.first != null && this.shape != null &&
			this.currentDx != null && this.currentDy != null)
		{
			var cell = me.getCell();
			
			if (this.connectOnDrop && this.target == null && cell != null && graph.getModel().isVertex(cell) &&
				graph.isCellConnectable(cell) && graph.isEdgeValid(null, this.cell, cell))
			{
				graph.connectionHandler.connect(this.cell, cell, me.getEvent());
			}
			else
			{
				var clone = graph.isCloneEvent(me.getEvent()) && graph.isCellsCloneable() && this.isCloneEnabled();
				var scale = graph.getView().scale;
				var dx = this.roundLength(this.currentDx / scale);
				var dy = this.roundLength(this.currentDy / scale);
				var target = this.target;
				
				if (graph.isSplitEnabled() && graph.isSplitTarget(target, this.cells, me.getEvent()))
				{
					graph.splitEdge(target, this.cells, null, dx, dy);
				}
				else
				{
					this.moveCells(this.cells, dx, dy, clone, this.target, me.getEvent());
				}
			}
		}
		else if (this.isSelectEnabled() && this.delayedSelection && this.cell != null)
		{
			this.selectDelayed(me);
		}
	}

	// Consumes the event if a cell was initially clicked
	if (this.cellWasClicked)
	{
		this.consumeMouseEvent(mxEvent.MOUSE_UP, me);
	}

	this.reset();
};

/**
 * Function: selectDelayed
 * 
 * Implements the delayed selection for the given mouse event.
 */
mxGraphHandler.prototype.selectDelayed = function(me)
{
	if (!this.graph.isCellSelected(this.cell) || !this.graph.popupMenuHandler.isPopupTrigger(me))
	{
		this.graph.selectCellForEvent(this.cell, me.getEvent());
	}
};

/**
 * Function: reset
 * 
 * Resets the state of this handler.
 */
mxGraphHandler.prototype.reset = function()
{
	this.destroyShapes();
	this.removeHint();
	
	this.cellWasClicked = false;
	this.delayedSelection = false;
	this.currentDx = null;
	this.currentDy = null;
	this.guides = null;
	this.first = null;
	this.cell = null;
	this.target = null;
};

/**
 * Function: shouldRemoveCellsFromParent
 * 
 * Returns true if the given cells should be removed from the parent for the specified
 * mousereleased event.
 */
mxGraphHandler.prototype.shouldRemoveCellsFromParent = function(parent, cells, evt)
{
	if (this.graph.getModel().isVertex(parent))
	{
		var pState = this.graph.getView().getState(parent);
		
		if (pState != null)
		{
			var pt = mxUtils.convertPoint(this.graph.container,
				mxEvent.getClientX(evt), mxEvent.getClientY(evt));
			var alpha = mxUtils.toRadians(mxUtils.getValue(pState.style, mxConstants.STYLE_ROTATION) || 0);
			
			if (alpha != 0)
			{
				var cos = Math.cos(-alpha);
				var sin = Math.sin(-alpha);
				var cx = new mxPoint(pState.getCenterX(), pState.getCenterY());
				pt = mxUtils.getRotatedPoint(pt, cos, sin, cx);
			}
		
			return !mxUtils.contains(pState, pt.x, pt.y);
		}
	}
	
	return false;
};

/**
 * Function: moveCells
 * 
 * Moves the given cells by the specified amount.
 */
mxGraphHandler.prototype.moveCells = function(cells, dx, dy, clone, target, evt)
{
	if (clone)
	{
		cells = this.graph.getCloneableCells(cells);
	}
	
	// Removes cells from parent
	if (target == null && this.isRemoveCellsFromParent() &&
		this.shouldRemoveCellsFromParent(this.graph.getModel().getParent(this.cell), cells, evt))
	{
		target = this.graph.getDefaultParent();
	}
	
	// Passes all selected cells in order to correctly clone or move into
	// the target cell. The method checks for each cell if its movable.
	cells = this.graph.moveCells(cells, dx - this.graph.panDx / this.graph.view.scale,
			dy - this.graph.panDy / this.graph.view.scale, clone, target, evt);
	
	if (this.isSelectEnabled() && this.scrollOnMove)
	{
		this.graph.scrollCellToVisible(cells[0]);
	}
			
	// Selects the new cells if cells have been cloned
	if (clone)
	{
		this.graph.setSelectionCells(cells);
	}
};

/**
 * Function: destroyShapes
 * 
 * Destroy the preview and highlight shapes.
 */
mxGraphHandler.prototype.destroyShapes = function()
{
	// Destroys the preview dashed rectangle
	if (this.shape != null)
	{
		this.shape.destroy();
		this.shape = null;
	}
	
	if (this.guide != null)
	{
		this.guide.destroy();
		this.guide = null;
	}
	
	// Destroys the drop target highlight
	if (this.highlight != null)
	{
		this.highlight.destroy();
		this.highlight = null;
	}
};

/**
 * Function: destroy
 * 
 * Destroys the handler and all its resources and DOM nodes.
 */
mxGraphHandler.prototype.destroy = function()
{
	this.graph.removeMouseListener(this);
	this.graph.removeListener(this.panHandler);
	
	if (this.escapeHandler != null)
	{
		this.graph.removeListener(this.escapeHandler);
		this.escapeHandler = null;
	}
	
	this.destroyShapes();
	this.removeHint();
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxPanningHandler
 * 
 * Event handler that pans and creates popupmenus. To use the left
 * mousebutton for panning without interfering with cell moving and
 * resizing, use <isUseLeftButton> and <isIgnoreCell>. For grid size
 * steps while panning, use <useGrid>. This handler is built-into
 * <mxGraph.panningHandler> and enabled using <mxGraph.setPanning>.
 * 
 * Constructor: mxPanningHandler
 * 
 * Constructs an event handler that creates a <mxPopupMenu>
 * and pans the graph.
 *
 * Event: mxEvent.PAN_START
 *
 * Fires when the panning handler changes its <active> state to true. The
 * <code>event</code> property contains the corresponding <mxMouseEvent>.
 *
 * Event: mxEvent.PAN
 *
 * Fires while handle is processing events. The <code>event</code> property contains
 * the corresponding <mxMouseEvent>.
 *
 * Event: mxEvent.PAN_END
 *
 * Fires when the panning handler changes its <active> state to false. The
 * <code>event</code> property contains the corresponding <mxMouseEvent>.
 */
function mxPanningHandler(graph)
{
	if (graph != null)
	{
		this.graph = graph;
		this.graph.addMouseListener(this);

		// Handles force panning event
		this.forcePanningHandler = mxUtils.bind(this, function(sender, evt)
		{
			var evtName = evt.getProperty('eventName');
			var me = evt.getProperty('event');
			
			if (evtName == mxEvent.MOUSE_DOWN && this.isForcePanningEvent(me))
			{
				this.start(me);
				this.active = true;
				this.fireEvent(new mxEventObject(mxEvent.PAN_START, 'event', me));
				me.consume();
			}
		});

		this.graph.addListener(mxEvent.FIRE_MOUSE_EVENT, this.forcePanningHandler);
		
		// Handles pinch gestures
		this.gestureHandler = mxUtils.bind(this, function(sender, eo)
		{
			if (this.isPinchEnabled())
			{
				var evt = eo.getProperty('event');
				
				if (!mxEvent.isConsumed(evt) && evt.type == 'gesturestart')
				{
					this.initialScale = this.graph.view.scale;
				
					// Forces start of panning when pinch gesture starts
					if (!this.active && this.mouseDownEvent != null)
					{
						this.start(this.mouseDownEvent);
						this.mouseDownEvent = null;
					}
				}
				else if (evt.type == 'gestureend' && this.initialScale != null)
				{
					this.initialScale = null;
				}
				
				if (this.initialScale != null)
				{
					var value = Math.round(this.initialScale * evt.scale * 100) / 100;
					
					if (this.minScale != null)
					{
						value = Math.max(this.minScale, value);
					}
					
					if (this.maxScale != null)
					{
						value = Math.min(this.maxScale, value);
					}
	
					if (this.graph.view.scale != value)
					{
						this.graph.zoomTo(value);
						mxEvent.consume(evt);
					}
				}
			}
		});
		
		this.graph.addListener(mxEvent.GESTURE, this.gestureHandler);
	}
};

/**
 * Extends mxEventSource.
 */
mxPanningHandler.prototype = new mxEventSource();
mxPanningHandler.prototype.constructor = mxPanningHandler;

/**
 * Variable: graph
 * 
 * Reference to the enclosing <mxGraph>.
 */
mxPanningHandler.prototype.graph = null;

/**
 * Variable: useLeftButtonForPanning
 * 
 * Specifies if panning should be active for the left mouse button.
 * Setting this to true may conflict with <mxRubberband>. Default is false.
 */
mxPanningHandler.prototype.useLeftButtonForPanning = false;

/**
 * Variable: usePopupTrigger
 * 
 * Specifies if <mxEvent.isPopupTrigger> should also be used for panning.
 */
mxPanningHandler.prototype.usePopupTrigger = true;

/**
 * Variable: ignoreCell
 * 
 * Specifies if panning should be active even if there is a cell under the
 * mousepointer. Default is false.
 */
mxPanningHandler.prototype.ignoreCell = false;

/**
 * Variable: previewEnabled
 * 
 * Specifies if the panning should be previewed. Default is true.
 */
mxPanningHandler.prototype.previewEnabled = true;

/**
 * Variable: useGrid
 * 
 * Specifies if the panning steps should be aligned to the grid size.
 * Default is false.
 */
mxPanningHandler.prototype.useGrid = false;

/**
 * Variable: panningEnabled
 * 
 * Specifies if panning should be enabled. Default is true.
 */
mxPanningHandler.prototype.panningEnabled = true;

/**
 * Variable: pinchEnabled
 * 
 * Specifies if pinch gestures should be handled as zoom. Default is true.
 */
mxPanningHandler.prototype.pinchEnabled = true;

/**
 * Variable: maxScale
 * 
 * Specifies the maximum scale. Default is 8.
 */
mxPanningHandler.prototype.maxScale = 8;

/**
 * Variable: minScale
 * 
 * Specifies the minimum scale. Default is 0.01.
 */
mxPanningHandler.prototype.minScale = 0.01;

/**
 * Variable: dx
 * 
 * Holds the current horizontal offset.
 */
mxPanningHandler.prototype.dx = null;

/**
 * Variable: dy
 * 
 * Holds the current vertical offset.
 */
mxPanningHandler.prototype.dy = null;

/**
 * Variable: startX
 * 
 * Holds the x-coordinate of the start point.
 */
mxPanningHandler.prototype.startX = 0;

/**
 * Variable: startY
 * 
 * Holds the y-coordinate of the start point.
 */
mxPanningHandler.prototype.startY = 0;

/**
 * Function: isActive
 * 
 * Returns true if the handler is currently active.
 */
mxPanningHandler.prototype.isActive = function()
{
	return this.active || this.initialScale != null;
};

/**
 * Function: isPanningEnabled
 * 
 * Returns <panningEnabled>.
 */
mxPanningHandler.prototype.isPanningEnabled = function()
{
	return this.panningEnabled;
};

/**
 * Function: setPanningEnabled
 * 
 * Sets <panningEnabled>.
 */
mxPanningHandler.prototype.setPanningEnabled = function(value)
{
	this.panningEnabled = value;
};

/**
 * Function: isPinchEnabled
 * 
 * Returns <pinchEnabled>.
 */
mxPanningHandler.prototype.isPinchEnabled = function()
{
	return this.pinchEnabled;
};

/**
 * Function: setPinchEnabled
 * 
 * Sets <pinchEnabled>.
 */
mxPanningHandler.prototype.setPinchEnabled = function(value)
{
	this.pinchEnabled = value;
};

/**
 * Function: isPanningTrigger
 * 
 * Returns true if the given event is a panning trigger for the optional
 * given cell. This returns true if control-shift is pressed or if
 * <usePopupTrigger> is true and the event is a popup trigger.
 */
mxPanningHandler.prototype.isPanningTrigger = function(me)
{
	var evt = me.getEvent();
	
	return (this.useLeftButtonForPanning && me.getState() == null &&
			mxEvent.isLeftMouseButton(evt)) || (mxEvent.isControlDown(evt) &&
			mxEvent.isShiftDown(evt)) || (this.usePopupTrigger && mxEvent.isPopupTrigger(evt));
};

/**
 * Function: isForcePanningEvent
 * 
 * Returns true if the given <mxMouseEvent> should start panning. This
 * implementation always returns true if <ignoreCell> is true or for
 * multi touch events.
 */
mxPanningHandler.prototype.isForcePanningEvent = function(me)
{
	return this.ignoreCell || mxEvent.isMultiTouchEvent(me.getEvent());
};

/**
 * Function: mouseDown
 * 
 * Handles the event by initiating the panning. By consuming the event all
 * subsequent events of the gesture are redirected to this handler.
 */
mxPanningHandler.prototype.mouseDown = function(sender, me)
{
	this.mouseDownEvent = me;
	
	if (!me.isConsumed() && this.isPanningEnabled() && !this.active && this.isPanningTrigger(me))
	{
		this.start(me);
		this.consumePanningTrigger(me);
	}
};

/**
 * Function: start
 * 
 * Starts panning at the given event.
 */
mxPanningHandler.prototype.start = function(me)
{
	this.dx0 = -this.graph.container.scrollLeft;
	this.dy0 = -this.graph.container.scrollTop;

	// Stores the location of the trigger event
	this.startX = me.getX();
	this.startY = me.getY();
	this.dx = null;
	this.dy = null;
	
	this.panningTrigger = true;
};

/**
 * Function: consumePanningTrigger
 * 
 * Consumes the given <mxMouseEvent> if it was a panning trigger in
 * <mouseDown>. The default is to invoke <mxMouseEvent.consume>. Note that this
 * will block any further event processing. If you haven't disabled built-in
 * context menus and require immediate selection of the cell on mouseDown in
 * Safari and/or on the Mac, then use the following code:
 * 
 * (code)
 * mxPanningHandler.prototype.consumePanningTrigger = function(me)
 * {
 *   if (me.evt.preventDefault)
 *   {
 *     me.evt.preventDefault();
 *   }
 *   
 *   // Stops event processing in IE
 *   me.evt.returnValue = false;
 *   
 *   // Sets local consumed state
 *   if (!mxClient.IS_SF && !mxClient.IS_MAC)
 *   {
 *     me.consumed = true;
 *   }
 * };
 * (end)
 */
mxPanningHandler.prototype.consumePanningTrigger = function(me)
{
	me.consume();
};

/**
 * Function: mouseMove
 * 
 * Handles the event by updating the panning on the graph.
 */
mxPanningHandler.prototype.mouseMove = function(sender, me)
{
	this.dx = me.getX() - this.startX;
	this.dy = me.getY() - this.startY;
	
	if (this.active)
	{
		if (this.previewEnabled)
		{
			// Applies the grid to the panning steps
			if (this.useGrid)
			{
				this.dx = this.graph.snap(this.dx);
				this.dy = this.graph.snap(this.dy);
			}
			
			this.graph.panGraph(this.dx + this.dx0, this.dy + this.dy0);
		}

		this.fireEvent(new mxEventObject(mxEvent.PAN, 'event', me));
	}
	else if (this.panningTrigger)
	{
		var tmp = this.active;

		// Panning is activated only if the mouse is moved
		// beyond the graph tolerance
		this.active = Math.abs(this.dx) > this.graph.tolerance || Math.abs(this.dy) > this.graph.tolerance;

		if (!tmp && this.active)
		{
			this.fireEvent(new mxEventObject(mxEvent.PAN_START, 'event', me));
		}
	}
	
	if (this.active || this.panningTrigger)
	{
		me.consume();
	}
};

/**
 * Function: mouseUp
 * 
 * Handles the event by setting the translation on the view or showing the
 * popupmenu.
 */
mxPanningHandler.prototype.mouseUp = function(sender, me)
{
	if (this.active)
	{
		if (this.dx != null && this.dy != null)
		{
			// Ignores if scrollbars have been used for panning
			if (!this.graph.useScrollbarsForPanning || !mxUtils.hasScrollbars(this.graph.container))
			{
				var scale = this.graph.getView().scale;
				var t = this.graph.getView().translate;
				this.graph.panGraph(0, 0);
				this.panGraph(t.x + this.dx / scale, t.y + this.dy / scale);
			}
			
			me.consume();
		}
		
		this.fireEvent(new mxEventObject(mxEvent.PAN_END, 'event', me));
	}
	
	this.panningTrigger = false;
	this.mouseDownEvent = null;
	this.active = false;
	this.dx = null;
	this.dy = null;
};

/**
 * Function: panGraph
 * 
 * Pans <graph> by the given amount.
 */
mxPanningHandler.prototype.panGraph = function(dx, dy)
{
	this.graph.getView().setTranslate(dx, dy);
};

/**
 * Function: destroy
 * 
 * Destroys the handler and all its resources and DOM nodes.
 */
mxPanningHandler.prototype.destroy = function()
{
	this.graph.removeMouseListener(this);
	this.graph.removeListener(this.forcePanningHandler);
	this.graph.removeListener(this.gestureHandler);
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxPopupMenuHandler
 * 
 * Event handler that creates popupmenus.
 * 
 * Constructor: mxPopupMenuHandler
 * 
 * Constructs an event handler that creates a <mxPopupMenu>.
 */
function mxPopupMenuHandler(graph, factoryMethod)
{
	if (graph != null)
	{
		this.graph = graph;
		this.factoryMethod = factoryMethod;
		this.graph.addMouseListener(this);
		
		// Does not show menu if any touch gestures take place after the trigger
		this.gestureHandler = mxUtils.bind(this, function(sender, eo)
		{
			this.inTolerance = false;
		});
		
		this.graph.addListener(mxEvent.GESTURE, this.gestureHandler);
		
		this.init();
	}
};

/**
 * Extends mxPopupMenu.
 */
mxPopupMenuHandler.prototype = new mxPopupMenu();
mxPopupMenuHandler.prototype.constructor = mxPopupMenuHandler;

/**
 * Variable: graph
 * 
 * Reference to the enclosing <mxGraph>.
 */
mxPopupMenuHandler.prototype.graph = null;

/**
 * Variable: selectOnPopup
 * 
 * Specifies if cells should be selected if a popupmenu is displayed for
 * them. Default is true.
 */
mxPopupMenuHandler.prototype.selectOnPopup = true;

/**
 * Variable: clearSelectionOnBackground
 * 
 * Specifies if cells should be deselected if a popupmenu is displayed for
 * the diagram background. Default is true.
 */
mxPopupMenuHandler.prototype.clearSelectionOnBackground = true;

/**
 * Variable: triggerX
 * 
 * X-coordinate of the mouse down event.
 */
mxPopupMenuHandler.prototype.triggerX = null;

/**
 * Variable: triggerY
 * 
 * Y-coordinate of the mouse down event.
 */
mxPopupMenuHandler.prototype.triggerY = null;

/**
 * Variable: screenX
 * 
 * Screen X-coordinate of the mouse down event.
 */
mxPopupMenuHandler.prototype.screenX = null;

/**
 * Variable: screenY
 * 
 * Screen Y-coordinate of the mouse down event.
 */
mxPopupMenuHandler.prototype.screenY = null;

/**
 * Function: init
 * 
 * Initializes the shapes required for this vertex handler.
 */
mxPopupMenuHandler.prototype.init = function()
{
	// Supercall
	mxPopupMenu.prototype.init.apply(this);

	// Hides the tooltip if the mouse is over
	// the context menu
	mxEvent.addGestureListeners(this.div, mxUtils.bind(this, function(evt)
	{
		this.graph.tooltipHandler.hide();
	}));
};

/**
 * Function: isSelectOnPopup
 * 
 * Hook for returning if a cell should be selected for a given <mxMouseEvent>.
 * This implementation returns <selectOnPopup>.
 */
mxPopupMenuHandler.prototype.isSelectOnPopup = function(me)
{
	return this.selectOnPopup;
};

/**
 * Function: mouseDown
 * 
 * Handles the event by initiating the panning. By consuming the event all
 * subsequent events of the gesture are redirected to this handler.
 */
mxPopupMenuHandler.prototype.mouseDown = function(sender, me)
{
	if (this.isEnabled() && !mxEvent.isMultiTouchEvent(me.getEvent()))
	{
		// Hides the popupmenu if is is being displayed
		this.hideMenu();
		this.triggerX = me.getGraphX();
		this.triggerY = me.getGraphY();
		this.screenX = mxEvent.getMainEvent(me.getEvent()).screenX;
		this.screenY = mxEvent.getMainEvent(me.getEvent()).screenY;
		this.popupTrigger = this.isPopupTrigger(me);
		this.inTolerance = true;
	}
};

/**
 * Function: mouseMove
 * 
 * Handles the event by updating the panning on the graph.
 */
mxPopupMenuHandler.prototype.mouseMove = function(sender, me)
{
	// Popup trigger may change on mouseUp so ignore it
	if (this.inTolerance && this.screenX != null && this.screenY != null)
	{
		if (Math.abs(mxEvent.getMainEvent(me.getEvent()).screenX - this.screenX) > this.graph.tolerance ||
			Math.abs(mxEvent.getMainEvent(me.getEvent()).screenY - this.screenY) > this.graph.tolerance)
		{
			this.inTolerance = false;
		}
	}
};

/**
 * Function: mouseUp
 * 
 * Handles the event by setting the translation on the view or showing the
 * popupmenu.
 */
mxPopupMenuHandler.prototype.mouseUp = function(sender, me)
{
	if (this.popupTrigger && this.inTolerance && this.triggerX != null && this.triggerY != null)
	{
		var cell = this.getCellForPopupEvent(me);

		// Selects the cell for which the context menu is being displayed
		if (this.graph.isEnabled() && this.isSelectOnPopup(me) &&
			cell != null && !this.graph.isCellSelected(cell))
		{
			this.graph.setSelectionCell(cell);
		}
		else if (this.clearSelectionOnBackground && cell == null)
		{
			this.graph.clearSelection();
		}
		
		// Hides the tooltip if there is one
		this.graph.tooltipHandler.hide();

		// Menu is shifted by 1 pixel so that the mouse up event
		// is routed via the underlying shape instead of the DIV
		var origin = mxUtils.getScrollOrigin();
		this.popup(me.getX() + origin.x + 1, me.getY() + origin.y + 1, cell, me.getEvent());
		me.consume();
	}
	
	this.popupTrigger = false;
	this.inTolerance = false;
};

/**
 * Function: getCellForPopupEvent
 * 
 * Hook to return the cell for the mouse up popup trigger handling.
 */
mxPopupMenuHandler.prototype.getCellForPopupEvent = function(me)
{
	return me.getCell();
};

/**
 * Function: destroy
 * 
 * Destroys the handler and all its resources and DOM nodes.
 */
mxPopupMenuHandler.prototype.destroy = function()
{
	this.graph.removeMouseListener(this);
	this.graph.removeListener(this.gestureHandler);
	
	// Supercall
	mxPopupMenu.prototype.destroy.apply(this);
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxCellMarker
 * 
 * A helper class to process mouse locations and highlight cells.
 * 
 * Helper class to highlight cells. To add a cell marker to an existing graph
 * for highlighting all cells, the following code is used:
 * 
 * (code)
 * var marker = new mxCellMarker(graph);
 * graph.addMouseListener({
 *   mouseDown: function() {},
 *   mouseMove: function(sender, me)
 *   {
 *     marker.process(me);
 *   },
 *   mouseUp: function() {}
 * });
 * (end)
 *
 * Event: mxEvent.MARK
 * 
 * Fires after a cell has been marked or unmarked. The <code>state</code>
 * property contains the marked <mxCellState> or null if no state is marked.
 * 
 * Constructor: mxCellMarker
 * 
 * Constructs a new cell marker.
 * 
 * Parameters:
 * 
 * graph - Reference to the enclosing <mxGraph>.
 * validColor - Optional marker color for valid states. Default is
 * <mxConstants.DEFAULT_VALID_COLOR>.
 * invalidColor - Optional marker color for invalid states. Default is
 * <mxConstants.DEFAULT_INVALID_COLOR>.
 * hotspot - Portion of the width and hight where a state intersects a
 * given coordinate pair. A value of 0 means always highlight. Default is
 * <mxConstants.DEFAULT_HOTSPOT>.
 */
function mxCellMarker(graph, validColor, invalidColor, hotspot)
{
	mxEventSource.call(this);
	
	if (graph != null)
	{
		this.graph = graph;
		this.validColor = (validColor != null) ? validColor : mxConstants.DEFAULT_VALID_COLOR;
		this.invalidColor = (validColor != null) ? invalidColor : mxConstants.DEFAULT_INVALID_COLOR;
		this.hotspot = (hotspot != null) ? hotspot : mxConstants.DEFAULT_HOTSPOT;
		
		this.highlight = new mxCellHighlight(graph);
	}
};

/**
 * Extends mxEventSource.
 */
mxUtils.extend(mxCellMarker, mxEventSource);

/**
 * Variable: graph
 * 
 * Reference to the enclosing <mxGraph>.
 */
mxCellMarker.prototype.graph = null;

/**
 * Variable: enabled
 * 
 * Specifies if the marker is enabled. Default is true.
 */
mxCellMarker.prototype.enabled = true;

/**
 * Variable: hotspot
 * 
 * Specifies the portion of the width and height that should trigger
 * a highlight. The area around the center of the cell to be marked is used
 * as the hotspot. Possible values are between 0 and 1. Default is
 * mxConstants.DEFAULT_HOTSPOT.
 */
mxCellMarker.prototype.hotspot = mxConstants.DEFAULT_HOTSPOT; 

/**
 * Variable: hotspotEnabled
 * 
 * Specifies if the hotspot is enabled. Default is false.
 */
mxCellMarker.prototype.hotspotEnabled = false;

/**
 * Variable: validColor
 * 
 * Holds the valid marker color.
 */
mxCellMarker.prototype.validColor = null;

/**
 * Variable: invalidColor
 * 
 * Holds the invalid marker color.
 */
mxCellMarker.prototype.invalidColor = null;

/**
 * Variable: currentColor
 * 
 * Holds the current marker color.
 */
mxCellMarker.prototype.currentColor = null;

/**
 * Variable: validState
 * 
 * Holds the marked <mxCellState> if it is valid.
 */
mxCellMarker.prototype.validState = null; 

/**
 * Variable: markedState
 * 
 * Holds the marked <mxCellState>.
 */
mxCellMarker.prototype.markedState = null;

/**
 * Function: setEnabled
 * 
 * Enables or disables event handling. This implementation
 * updates <enabled>.
 * 
 * Parameters:
 * 
 * enabled - Boolean that specifies the new enabled state.
 */
mxCellMarker.prototype.setEnabled = function(enabled)
{
	this.enabled = enabled;
};

/**
 * Function: isEnabled
 * 
 * Returns true if events are handled. This implementation
 * returns <enabled>.
 */
mxCellMarker.prototype.isEnabled = function()
{
	return this.enabled;
};

/**
 * Function: setHotspot
 * 
 * Sets the <hotspot>.
 */
mxCellMarker.prototype.setHotspot = function(hotspot)
{
	this.hotspot = hotspot;
};

/**
 * Function: getHotspot
 * 
 * Returns the <hotspot>.
 */
mxCellMarker.prototype.getHotspot = function()
{
	return this.hotspot;
};

/**
 * Function: setHotspotEnabled
 * 
 * Specifies whether the hotspot should be used in <intersects>.
 */
mxCellMarker.prototype.setHotspotEnabled = function(enabled)
{
	this.hotspotEnabled = enabled;
};

/**
 * Function: isHotspotEnabled
 * 
 * Returns true if hotspot is used in <intersects>.
 */
mxCellMarker.prototype.isHotspotEnabled = function()
{
	return this.hotspotEnabled;
};

/**
 * Function: hasValidState
 * 
 * Returns true if <validState> is not null.
 */
mxCellMarker.prototype.hasValidState = function()
{
	return this.validState != null;
};

/**
 * Function: getValidState
 * 
 * Returns the <validState>.
 */
mxCellMarker.prototype.getValidState = function()
{
	return this.validState;
};

/**
 * Function: getMarkedState
 * 
 * Returns the <markedState>.
 */
mxCellMarker.prototype.getMarkedState = function()
{
	return this.markedState;
};

/**
 * Function: reset
 * 
 * Resets the state of the cell marker.
 */
mxCellMarker.prototype.reset = function()
{
	this.validState = null;
	
	if (this.markedState != null)
	{
		this.markedState = null;
		this.unmark();
	}
};

/**
 * Function: process
 * 
 * Processes the given event and cell and marks the state returned by
 * <getState> with the color returned by <getMarkerColor>. If the
 * markerColor is not null, then the state is stored in <markedState>. If
 * <isValidState> returns true, then the state is stored in <validState>
 * regardless of the marker color. The state is returned regardless of the
 * marker color and valid state. 
 */
mxCellMarker.prototype.process = function(me)
{
	var state = null;
	
	if (this.isEnabled())
	{
		state = this.getState(me);
		this.setCurrentState(state, me);
	}
	
	return state;
};

/**
 * Function: setCurrentState
 * 
 * Sets and marks the current valid state.
 */
mxCellMarker.prototype.setCurrentState = function(state, me, color)
{
	var isValid = (state != null) ? this.isValidState(state) : false;
	color = (color != null) ? color : this.getMarkerColor(me.getEvent(), state, isValid);
	
	if (isValid)
	{
		this.validState = state;
	}
	else
	{
		this.validState = null;
	}
	
	if (state != this.markedState || color != this.currentColor)
	{
		this.currentColor = color;
		
		if (state != null && this.currentColor != null)
		{
			this.markedState = state;
			this.mark();		
		}
		else if (this.markedState != null)
		{
			this.markedState = null;
			this.unmark();
		}
	}
};

/**
 * Function: markCell
 * 
 * Marks the given cell using the given color, or <validColor> if no color is specified.
 */
mxCellMarker.prototype.markCell = function(cell, color)
{
	var state = this.graph.getView().getState(cell);
	
	if (state != null)
	{
		this.currentColor = (color != null) ? color : this.validColor;
		this.markedState = state;
		this.mark();
	}
};

/**
 * Function: mark
 * 
 * Marks the <markedState> and fires a <mark> event.
 */
mxCellMarker.prototype.mark = function()
{
	this.highlight.setHighlightColor(this.currentColor);
	this.highlight.highlight(this.markedState);
	this.fireEvent(new mxEventObject(mxEvent.MARK, 'state', this.markedState));
};

/**
 * Function: unmark
 * 
 * Hides the marker and fires a <mark> event.
 */
mxCellMarker.prototype.unmark = function()
{
	this.mark();
};

/**
 * Function: isValidState
 * 
 * Returns true if the given <mxCellState> is a valid state. If this
 * returns true, then the state is stored in <validState>. The return value
 * of this method is used as the argument for <getMarkerColor>.
 */
mxCellMarker.prototype.isValidState = function(state)
{
	return true;
};

/**
 * Function: getMarkerColor
 * 
 * Returns the valid- or invalidColor depending on the value of isValid.
 * The given <mxCellState> is ignored by this implementation.
 */
mxCellMarker.prototype.getMarkerColor = function(evt, state, isValid)
{
	return (isValid) ? this.validColor : this.invalidColor;
};

/**
 * Function: getState
 * 
 * Uses <getCell>, <getStateToMark> and <intersects> to return the
 * <mxCellState> for the given <mxMouseEvent>.
 */
mxCellMarker.prototype.getState = function(me)
{
	var view = this.graph.getView();
	var cell = this.getCell(me);
	var state = this.getStateToMark(view.getState(cell));

	return (state != null && this.intersects(state, me)) ? state : null;
};

/**
 * Function: getCell
 * 
 * Returns the <mxCell> for the given event and cell. This returns the
 * given cell.
 */
mxCellMarker.prototype.getCell = function(me)
{
	return me.getCell();
};

/**
 * Function: getStateToMark
 * 
 * Returns the <mxCellState> to be marked for the given <mxCellState> under
 * the mouse. This returns the given state.
 */
mxCellMarker.prototype.getStateToMark = function(state)
{
	return state;
};

/**
 * Function: intersects
 * 
 * Returns true if the given coordinate pair intersects the given state.
 * This returns true if the <hotspot> is 0 or the coordinates are inside
 * the hotspot for the given cell state.
 */
mxCellMarker.prototype.intersects = function(state, me)
{
	if (this.hotspotEnabled)
	{
		return mxUtils.intersectsHotspot(state, me.getGraphX(), me.getGraphY(),
			this.hotspot, mxConstants.MIN_HOTSPOT_SIZE,
			mxConstants.MAX_HOTSPOT_SIZE);
	}
	
	return true;
};

/**
 * Function: destroy
 * 
 * Destroys the handler and all its resources and DOM nodes.
 */
mxCellMarker.prototype.destroy = function()
{
	this.graph.getView().removeListener(this.resetHandler);
	this.graph.getModel().removeListener(this.resetHandler);
	this.highlight.destroy();
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxSelectionCellsHandler
 * 
 * An event handler that manages cell handlers and invokes their mouse event
 * processing functions.
 * 
 * Group: Events
 * 
 * Event: mxEvent.ADD
 * 
 * Fires if a cell has been added to the selection. The <code>state</code>
 * property contains the <mxCellState> that has been added.
 * 
 * Event: mxEvent.REMOVE
 * 
 * Fires if a cell has been remove from the selection. The <code>state</code>
 * property contains the <mxCellState> that has been removed.
 * 
 * Parameters:
 * 
 * graph - Reference to the enclosing <mxGraph>.
 */
function mxSelectionCellsHandler(graph)
{
	mxEventSource.call(this);
	
	this.graph = graph;
	this.handlers = new mxDictionary();
	this.graph.addMouseListener(this);
	
	this.refreshHandler = mxUtils.bind(this, function(sender, evt)
	{
		if (this.isEnabled())
		{
			this.refresh();
		}
	});
	
	this.graph.getSelectionModel().addListener(mxEvent.CHANGE, this.refreshHandler);
	this.graph.getModel().addListener(mxEvent.CHANGE, this.refreshHandler);
	this.graph.getView().addListener(mxEvent.SCALE, this.refreshHandler);
	this.graph.getView().addListener(mxEvent.TRANSLATE, this.refreshHandler);
	this.graph.getView().addListener(mxEvent.SCALE_AND_TRANSLATE, this.refreshHandler);
	this.graph.getView().addListener(mxEvent.DOWN, this.refreshHandler);
	this.graph.getView().addListener(mxEvent.UP, this.refreshHandler);
};

/**
 * Extends mxEventSource.
 */
mxUtils.extend(mxSelectionCellsHandler, mxEventSource);

/**
 * Variable: graph
 * 
 * Reference to the enclosing <mxGraph>.
 */
mxSelectionCellsHandler.prototype.graph = null;

/**
 * Variable: enabled
 * 
 * Specifies if events are handled. Default is true.
 */
mxSelectionCellsHandler.prototype.enabled = true;

/**
 * Variable: refreshHandler
 * 
 * Keeps a reference to an event listener for later removal.
 */
mxSelectionCellsHandler.prototype.refreshHandler = null;

/**
 * Variable: maxHandlers
 * 
 * Defines the maximum number of handlers to paint individually. Default is 100.
 */
mxSelectionCellsHandler.prototype.maxHandlers = 100;

/**
 * Variable: handlers
 * 
 * <mxDictionary> that maps from cells to handlers.
 */
mxSelectionCellsHandler.prototype.handlers = null;

/**
 * Function: isEnabled
 * 
 * Returns <enabled>.
 */
mxSelectionCellsHandler.prototype.isEnabled = function()
{
	return this.enabled;
};

/**
 * Function: setEnabled
 * 
 * Sets <enabled>.
 */
mxSelectionCellsHandler.prototype.setEnabled = function(value)
{
	this.enabled = value;
};

/**
 * Function: getHandler
 * 
 * Returns the handler for the given cell.
 */
mxSelectionCellsHandler.prototype.getHandler = function(cell)
{
	return this.handlers.get(cell);
};

/**
 * Function: reset
 * 
 * Resets all handlers.
 */
mxSelectionCellsHandler.prototype.reset = function()
{
	this.handlers.visit(function(key, handler)
	{
		handler.reset.apply(handler);
	});
};

/**
 * Function: refresh
 * 
 * Reloads or updates all handlers.
 */
mxSelectionCellsHandler.prototype.refresh = function()
{
	// Removes all existing handlers
	var oldHandlers = this.handlers;
	this.handlers = new mxDictionary();
	
	// Creates handles for all selection cells
	var tmp = this.graph.getSelectionCells();

	for (var i = 0; i < tmp.length; i++)
	{
		var state = this.graph.view.getState(tmp[i]);

		if (state != null)
		{
			var handler = oldHandlers.remove(tmp[i]);

			if (handler != null)
			{
				if (handler.state != state)
				{
					handler.destroy();
					handler = null;
				}
				else
				{
					if (handler.refresh != null)
					{
						handler.refresh();
					}
					
					handler.redraw();
				}
			}
			
			if (handler == null)
			{
				handler = this.graph.createHandler(state);
				this.fireEvent(new mxEventObject(mxEvent.ADD, 'state', state));
			}
			
			if (handler != null)
			{
				this.handlers.put(tmp[i], handler);
			}
		}
	}
	
	// Destroys all unused handlers
	oldHandlers.visit(mxUtils.bind(this, function(key, handler)
	{
		this.fireEvent(new mxEventObject(mxEvent.REMOVE, 'state', handler.state));
		handler.destroy();
	}));
};

/**
 * Function: updateHandler
 * 
 * Updates the handler for the given shape if one exists.
 */
mxSelectionCellsHandler.prototype.updateHandler = function(state)
{
	var handler = this.handlers.remove(state.cell);
	
	if (handler != null)
	{
		handler.destroy();
		handler = this.graph.createHandler(state);
		
		if (handler != null)
		{
			this.handlers.put(state.cell, handler);
		}
	}
};

/**
 * Function: mouseDown
 * 
 * Redirects the given event to the handlers.
 */
mxSelectionCellsHandler.prototype.mouseDown = function(sender, me)
{
	if (this.graph.isEnabled() && this.isEnabled())
	{
		var args = [sender, me];

		this.handlers.visit(function(key, handler)
		{
			handler.mouseDown.apply(handler, args);
		});
	}
};

/**
 * Function: mouseMove
 * 
 * Redirects the given event to the handlers.
 */
mxSelectionCellsHandler.prototype.mouseMove = function(sender, me)
{
	if (this.graph.isEnabled() && this.isEnabled())
	{
		var args = [sender, me];

		this.handlers.visit(function(key, handler)
		{
			handler.mouseMove.apply(handler, args);
		});
	}
};

/**
 * Function: mouseUp
 * 
 * Redirects the given event to the handlers.
 */
mxSelectionCellsHandler.prototype.mouseUp = function(sender, me)
{
	if (this.graph.isEnabled() && this.isEnabled())
	{
		var args = [sender, me];

		this.handlers.visit(function(key, handler)
		{
			handler.mouseUp.apply(handler, args);
		});
	}
};

/**
 * Function: destroy
 * 
 * Destroys the handler and all its resources and DOM nodes.
 */
mxSelectionCellsHandler.prototype.destroy = function()
{
	this.graph.removeMouseListener(this);
	
	if (this.refreshHandler != null)
	{
		this.graph.getSelectionModel().removeListener(this.refreshHandler);
		this.graph.getModel().removeListener(this.refreshHandler);
		this.graph.getView().removeListener(this.refreshHandler);
		this.refreshHandler = null;
	}
};
/**
 * Copyright (c) 2006-2016, JGraph Ltd
 * Copyright (c) 2006-2016, Gaudenz Alder
 */
/**
 * Class: mxConnectionHandler
 *
 * Graph event handler that creates new connections. Uses <mxTerminalMarker>
 * for finding and highlighting the source and target vertices and
 * <factoryMethod> to create the edge instance. This handler is built-into
 * <mxGraph.connectionHandler> and enabled using <mxGraph.setConnectable>.
 *
 * Example:
 * 
 * (code)
 * new mxConnectionHandler(graph, function(source, target, style)
 * {
 *   edge = new mxCell('', new mxGeometry());
 *   edge.setEdge(true);
 *   edge.setStyle(style);
 *   edge.geometry.relative = true;
 *   return edge;
 * });
 * (end)
 * 
 * Here is an alternative solution that just sets a specific user object for
 * new edges by overriding <insertEdge>.
 *
 * (code)
 * mxConnectionHandlerInsertEdge = mxConnectionHandler.prototype.insertEdge;
 * mxConnectionHandler.prototype.insertEdge = function(parent, id, value, source, target, style)
 * {
 *   value = 'Test';
 * 
 *   return mxConnectionHandlerInsertEdge.apply(this, arguments);
 * };
 * (end)
 * 
 * Using images to trigger connections:
 * 
 * This handler uses mxTerminalMarker to find the source and target cell for
 * the new connection and creates a new edge using <connect>. The new edge is
 * created using <createEdge> which in turn uses <factoryMethod> or creates a
 * new default edge.
 * 
 * The handler uses a "highlight-paradigm" for indicating if a cell is being
 * used as a source or target terminal, as seen in other diagramming products.
 * In order to allow both, moving and connecting cells at the same time,
 * <mxConstants.DEFAULT_HOTSPOT> is used in the handler to determine the hotspot
 * of a cell, that is, the region of the cell which is used to trigger a new
 * connection. The constant is a value between 0 and 1 that specifies the
 * amount of the width and height around the center to be used for the hotspot
 * of a cell and its default value is 0.5. In addition,
 * <mxConstants.MIN_HOTSPOT_SIZE> defines the minimum number of pixels for the
 * width and height of the hotspot.
 * 
 * This solution, while standards compliant, may be somewhat confusing because
 * there is no visual indicator for the hotspot and the highlight is seen to
 * switch on and off while the mouse is being moved in and out. Furthermore,
 * this paradigm does not allow to create different connections depending on
 * the highlighted hotspot as there is only one hotspot per cell and it
 * normally does not allow cells to be moved and connected at the same time as
 * there is no clear indication of the connectable area of the cell.
 * 
 * To come across these issues, the handle has an additional <createIcons> hook
 * with a default implementation that allows to create one icon to be used to
 * trigger new connections. If this icon is specified, then new connections can
 * only be created if the image is clicked while the cell is being highlighted.
 * The <createIcons> hook may be overridden to create more than one
 * <mxImageShape> for creating new connections, but the default implementation
 * supports one image and is used as follows:
 * 
 * In order to display the "connect image" whenever the mouse is over the cell,
 * an DEFAULT_HOTSPOT of 1 should be used:
 * 
 * (code)
 * mxConstants.DEFAULT_HOTSPOT = 1;
 * (end)
 * 
 * In order to avoid confusion with the highlighting, the highlight color
 * should not be used with a connect image:
 * 
 * (code)
 * mxConstants.HIGHLIGHT_COLOR = null;
 * (end)
 * 
 * To install the image, the connectImage field of the mxConnectionHandler must
 * be assigned a new <mxImage> instance:
 * 
 * (code)
 * mxConnectionHandler.prototype.connectImage = new mxImage('images/green-dot.gif', 14, 14);
 * (end)
 * 
 * This will use the green-dot.gif with a width and height of 14 pixels as the
 * image to trigger new connections. In createIcons the icon field of the
 * handler will be set in order to remember the icon that has been clicked for
 * creating the new connection. This field will be available under selectedIcon
 * in the connect method, which may be overridden to take the icon that
 * triggered the new connection into account. This is useful if more than one
 * icon may be used to create a connection.
 *
 * Group: Events
 * 
 * Event: mxEvent.START
 * 
 * Fires when a new connection is being created by the user. The <code>state</code>
 * property contains the state of the source cell.
 * 
 * Event: mxEvent.CONNECT
 * 
 * Fires between begin- and endUpdate in <connect>. The <code>cell</code>
 * property contains the inserted edge, the <code>event</code> and <code>target</code> 
 * properties contain the respective arguments that were passed to <connect> (where
 * target corresponds to the dropTarget argument). Finally, the <code>terminal</code>
 * property corresponds to the target argument in <connect> or the clone of the source
 * terminal if <createTarget> is enabled.
 * 
 * Note that the target is the cell under the mouse where the mouse button was released.
 * Depending on the logic in the handler, this doesn't necessarily have to be the target
 * of the inserted edge. To print the source, target or any optional ports IDs that the
 * edge is connected to, the following code can be used. To get more details about the
 * actual connection point, <mxGraph.getConnectionConstraint> can be used. To resolve
 * the port IDs, use <mxGraphModel.getCell>.
 * 
 * (code)
 * graph.connectionHandler.addListener(mxEvent.CONNECT, function(sender, evt)
 * {
 *   var edge = evt.getProperty('cell');
 *   var source = graph.getModel().getTerminal(edge, true);
 *   var target = graph.getModel().getTerminal(edge, false);
 *   
 *   var style = graph.getCellStyle(edge);
 *   var sourcePortId = style[mxConstants.STYLE_SOURCE_PORT];
 *   var targetPortId = style[mxConstants.STYLE_TARGET_PORT];
 *   
 *   mxLog.show();
 *   mxLog.debug('connect', edge, source.id, target.id, sourcePortId, targetPortId);
 * });
 * (end)
 *
 * Event: mxEvent.RESET
 * 
 * Fires when the <reset> method is invoked.
 *
 * Constructor: mxConnectionHandler
 *
 * Constructs an event handler that connects vertices using the specified
 * factory method to create the new edges. Modify
 * <mxConstants.ACTIVE_REGION> to setup the region on a cell which triggers
 * the creation of a new connection or use connect icons as explained
 * above.
 * 
 * Parameters:
 * 
 * graph - Reference to the enclosing <mxGraph>.
 * factoryMethod - Optional function to create the edge. The function takes
 * the source and target <mxCell> as the first and second argument and an
 * optional cell style from the preview as the third argument. It returns
 * the <mxCell> that represents the new edge.
 */
function mxConnectionHandler(graph, factoryMethod)
{
	mxEventSource.call(this);
	
	if (graph != null)
	{
		this.graph = graph;
		this.factoryMethod = factoryMethod;
		this.init();
		
		// Handles escape keystrokes
		this.escapeHandler = mxUtils.bind(this, function(sender, evt)
		{
			this.reset();
		});
		
		this.graph.addListener(mxEvent.ESCAPE, this.escapeHandler);
	}
};

/**
 * Extends mxEventSource.
 */
mxUtils.extend(mxConnectionHandler, mxEventSource);

/**
 * Variable: graph
 * 
 * Reference to the enclosing <mxGraph>.
 */
mxConnectionHandler.prototype.graph = null;

/**
 * Variable: factoryMethod
 * 
 * Function that is used for creating new edges. The function takes the
 * source and target <mxCell> as the first and second argument and returns
 * a new <mxCell> that represents the edge. This is used in <createEdge>.
 */
mxConnectionHandler.prototype.factoryMethod = true;

/**
 * Variable: moveIconFront
 * 
 * Specifies if icons should be displayed inside the graph container instead
 * of the overlay pane. This is used for HTML labels on vertices which hide
 * the connect icon. This has precendence over <moveIconBack> when set
 * to true. Default is false.
 */
mxConnectionHandler.prototype.moveIconFront = false;

/**
 * Variable: moveIconBack
 * 
 * Specifies if icons should be moved to the back of the overlay pane. This can
 * be set to true if the icons of the connection handler conflict with other
 * handles, such as the vertex label move handle. Default is false.
 */
mxConnectionHandler.prototype.moveIconBack = false;

/**
 * Variable: connectImage
 * 
 * <mxImage> that is used to trigger the creation of a new connection. This
 * is used in <createIcons>. Default is null.
 */
mxConnectionHandler.prototype.connectImage = null;

/**
 * Variable: targetConnectImage
 * 
 * Specifies if the connect icon should be centered on the target state
 * while connections are being previewed. Default is false.
 */
mxConnectionHandler.prototype.targetConnectImage = false;

/**
 * Variable: enabled
 * 
 * Specifies if events are handled. Default is true.
 */
mxConnectionHandler.prototype.enabled = true;

/**
 * Variable: select
 * 
 * Specifies if new edges should be selected. Default is true.
 */
mxConnectionHandler.prototype.select = true;

/**
 * Variable: createTarget
 * 
 * Specifies if <createTargetVertex> should be called if no target was under the
 * mouse for the new connection. Setting this to true means the connection
 * will be drawn as valid if no target is under the mouse, and
 * <createTargetVertex> will be called before the connection is created between
 * the source cell and the newly created vertex in <createTargetVertex>, which
 * can be overridden to create a new target. Default is false.
 */
mxConnectionHandler.prototype.createTarget = false;

/**
 * Variable: marker
 * 
 * Holds the <mxTerminalMarker> used for finding source and target cells.
 */
mxConnectionHandler.prototype.marker = null;

/**
 * Variable: constraintHandler
 * 
 * Holds the <mxConstraintHandler> used for drawing and highlighting
 * constraints.
 */
mxConnectionHandler.prototype.constraintHandler = null;

/**
 * Variable: error
 * 
 * Holds the current validation error while connections are being created.
 */
mxConnectionHandler.prototype.error = null;

/**
 * Variable: waypointsEnabled
 * 
 * Specifies if single clicks should add waypoints on the new edge. Default is
 * false.
 */
mxConnectionHandler.prototype.waypointsEnabled = false;

/**
 * Variable: ignoreMouseDown
 * 
 * Specifies if the connection handler should ignore the state of the mouse
 * button when highlighting the source. Default is false, that is, the
 * handler only highlights the source if no button is being pressed.
 */
mxConnectionHandler.prototype.ignoreMouseDown = false;

/**
 * Variable: first
 * 
 * Holds the <mxPoint> where the mouseDown took place while the handler is
 * active.
 */
mxConnectionHandler.prototype.first = null;

/**
 * Variable: connectIconOffset
 * 
 * Holds the offset for connect icons during connection preview.
 * Default is mxPoint(0, <mxConstants.TOOLTIP_VERTICAL_OFFSET>).
 * Note that placing the icon under the mouse pointer with an
 * offset of (0,0) will affect hit detection.
 */
mxConnectionHandler.prototype.connectIconOffset = new mxPoint(0, mxConstants.TOOLTIP_VERTICAL_OFFSET);

/**
 * Variable: edgeState
 * 
 * Optional <mxCellState> that represents the preview edge while the
 * handler is active. This is created in <createEdgeState>.
 */
mxConnectionHandler.prototype.edgeState = null;

/**
 * Variable: changeHandler
 * 
 * Holds the change event listener for later removal.
 */
mxConnectionHandler.prototype.changeHandler = null;

/**
 * Variable: drillHandler
 * 
 * Holds the drill event listener for later removal.
 */
mxConnectionHandler.prototype.drillHandler = null;

/**
 * Variable: mouseDownCounter
 * 
 * Counts the number of mouseDown events since the start. The initial mouse
 * down event counts as 1.
 */
mxConnectionHandler.prototype.mouseDownCounter = 0;

/**
 * Variable: movePreviewAway
 * 
 * Switch to enable moving the preview away from the mousepointer. This is required in browsers
 * where the preview cannot be made transparent to events and if the built-in hit detection on
 * the HTML elements in the page should be used. Default is the value of <mxClient.IS_VML>.
 */
mxConnectionHandler.prototype.movePreviewAway = mxClient.IS_VML;

/**
 * Variable: outlineConnect
 * 
 * Specifies if connections to the outline of a highlighted target should be
 * enabled. This will allow to place the connection point along the outline of
 * the highlighted target. Default is false.
 */
mxConnectionHandler.prototype.outlineConnect = false;

/**
 * Variable: livePreview
 * 
 * Specifies if the actual shape of the edge state should be used for the preview.
 * Default is false. (Ignored if no edge state is created in <createEdgeState>.)
 */
mxConnectionHandler.prototype.livePreview = false;

/**
 * Variable: cursor
 * 
 * Specifies the cursor to be used while the handler is active. Default is null.
 */
mxConnectionHandler.prototype.cursor = null;

/**
 * Variable: insertBeforeSource
 * 
 * Specifies if new edges should be inserted before the source vertex in the
 * cell hierarchy. Default is false for backwards compatibility.
 */
mxConnectionHandler.prototype.insertBeforeSource = false;

/**
 * Function: isEnabled
 * 
 * Returns true if events are handled. This implementation
 * returns <enabled>.
 */
mxConnectionHandler.prototype.isEnabled = function()
{
	return this.enabled;
};
	
/**
 * Function: setEnabled
 * 
 * Enables or disables event handling. This implementation
 * updates <enabled>.
 * 
 * Parameters:
 * 
 * enabled - Boolean that specifies the new enabled state.
 */
mxConnectionHandler.prototype.setEnabled = function(enabled)
{
	this.enabled = enabled;
};

/**
 * Function: isInsertBefore
 * 
 * Returns <insertBeforeSource> for non-loops and false for loops.
 *
 * Parameters:
 * 
 * edge - <mxCell> that represents the edge to be inserted.
 * source - <mxCell> that represents the source terminal.
 * target - <mxCell> that represents the target terminal.
 * evt - Mousedown event of the connect gesture.
 * dropTarget - <mxCell> that represents the cell under the mouse when it was
 * released.
 */
mxConnectionHandler.prototype.isInsertBefore = function(edge, source, target, evt, dropTarget)
{
	return this.insertBeforeSource && source != target;
};

/**
 * Function: isCreateTarget
 * 
 * Returns <createTarget>.
 *
 * Parameters:
 *
 * evt - Current active native pointer event.
 */
mxConnectionHandler.prototype.isCreateTarget = function(evt)
{
	return this.createTarget;
};

/**
 * Function: setCreateTarget
 * 
 * Sets <createTarget>.
 */
mxConnectionHandler.prototype.setCreateTarget = function(value)
{
	this.createTarget = value;
};

/**
 * Function: createShape
 * 
 * Creates the preview shape for new connections.
 */
mxConnectionHandler.prototype.createShape = function()
{
	// Creates the edge preview
	var shape = (this.livePreview && this.edgeState != null) ?
		this.graph.cellRenderer.createShape(this.edgeState) :
		new mxPolyline([], mxConstants.INVALID_COLOR);
	shape.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
		mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
	shape.scale = this.graph.view.scale;
	shape.pointerEvents = false;
	shape.isDashed = true;
	shape.init(this.graph.getView().getOverlayPane());
	mxEvent.redirectMouseEvents(shape.node, this.graph, null);

	return shape;
};

/**
 * Function: init
 * 
 * Initializes the shapes required for this connection handler. This should
 * be invoked if <mxGraph.container> is assigned after the connection
 * handler has been created.
 */
mxConnectionHandler.prototype.init = function()
{
	this.graph.addMouseListener(this);
	this.marker = this.createMarker();
	this.constraintHandler = new mxConstraintHandler(this.graph);

	// Redraws the icons if the graph changes
	this.changeHandler = mxUtils.bind(this, function(sender)
	{
		if (this.iconState != null)
		{
			this.iconState = this.graph.getView().getState(this.iconState.cell);
		}
		
		if (this.iconState != null)
		{
			this.redrawIcons(this.icons, this.iconState);
			this.constraintHandler.reset();
		}
		else if (this.previous != null && this.graph.view.getState(this.previous.cell) == null)
		{
			this.reset();
		}
	});
	
	this.graph.getModel().addListener(mxEvent.CHANGE, this.changeHandler);
	this.graph.getView().addListener(mxEvent.SCALE, this.changeHandler);
	this.graph.getView().addListener(mxEvent.TRANSLATE, this.changeHandler);
	this.graph.getView().addListener(mxEvent.SCALE_AND_TRANSLATE, this.changeHandler);
	
	// Removes the icon if we step into/up or start editing
	this.drillHandler = mxUtils.bind(this, function(sender)
	{
		this.reset();
	});
	
	this.graph.addListener(mxEvent.START_EDITING, this.drillHandler);
	this.graph.getView().addListener(mxEvent.DOWN, this.drillHandler);
	this.graph.getView().addListener(mxEvent.UP, this.drillHandler);
};

/**
 * Function: isConnectableCell
 * 
 * Returns true if the given cell is connectable. This is a hook to
 * disable floating connections. This implementation returns true.
 */
mxConnectionHandler.prototype.isConnectableCell = function(cell)
{
	return true;
};

/**
 * Function: createMarker
 * 
 * Creates and returns the <mxCellMarker> used in <marker>.
 */
mxConnectionHandler.prototype.createMarker = function()
{
	var marker = new mxCellMarker(this.graph);
	marker.hotspotEnabled = true;

	// Overrides to return cell at location only if valid (so that
	// there is no highlight for invalid cells)
	marker.getCell = mxUtils.bind(this, function(me)
	{
		var cell = mxCellMarker.prototype.getCell.apply(marker, arguments);
		this.error = null;
		
		// Checks for cell at preview point (with grid)
		if (cell == null && this.currentPoint != null)
		{
			cell = this.graph.getCellAt(this.currentPoint.x, this.currentPoint.y);
		}
		
		// Uses connectable parent vertex if one exists
		if (cell != null && !this.graph.isCellConnectable(cell))
		{
			var parent = this.graph.getModel().getParent(cell);
			
			if (this.graph.getModel().isVertex(parent) && this.graph.isCellConnectable(parent))
			{
				cell = parent;
			}
		}
		
		if ((this.graph.isSwimlane(cell) && this.currentPoint != null &&
			this.graph.hitsSwimlaneContent(cell, this.currentPoint.x, this.currentPoint.y)) ||
			!this.isConnectableCell(cell))
		{
			cell = null;
		}
		
		if (cell != null)
		{
			if (this.isConnecting())
			{
				if (this.previous != null)
				{
					this.error = this.validateConnection(this.previous.cell, cell);
					
					if (this.error != null && this.error.length == 0)
					{
						cell = null;
						
						// Enables create target inside groups
						if (this.isCreateTarget(me.getEvent()))
						{
							this.error = null;
						}
					}
				}
			}
			else if (!this.isValidSource(cell, me))
			{
				cell = null;
			}
		}
		else if (this.isConnecting() && !this.isCreateTarget(me.getEvent()) &&
				!this.graph.allowDanglingEdges)
		{
			this.error = '';
		}

		return cell;
	});

	// Sets the highlight color according to validateConnection
	marker.isValidState = mxUtils.bind(this, function(state)
	{
		if (this.isConnecting())
		{
			return this.error == null;
		}
		else
		{
			return mxCellMarker.prototype.isValidState.apply(marker, arguments);
		}
	});

	// Overrides to use marker color only in highlight mode or for
	// target selection
	marker.getMarkerColor = mxUtils.bind(this, function(evt, state, isValid)
	{
		return (this.connectImage == null || this.isConnecting()) ?
			mxCellMarker.prototype.getMarkerColor.apply(marker, arguments) :
			null;
	});

	// Overrides to use hotspot only for source selection otherwise
	// intersects always returns true when over a cell
	marker.intersects = mxUtils.bind(this, function(state, evt)
	{
		if (this.connectImage != null || this.isConnecting())
		{
			return true;
		}
		
		return mxCellMarker.prototype.intersects.apply(marker, arguments);
	});

	return marker;
};

/**
 * Function: start
 * 
 * Starts a new connection for the given state and coordinates.
 */
mxConnectionHandler.prototype.start = function(state, x, y, edgeState)
{
	this.previous = state;
	this.first = new mxPoint(x, y);
	this.edgeState = (edgeState != null) ? edgeState : this.createEdgeState(null);
	
	// Marks the source state
	this.marker.currentColor = this.marker.validColor;
	this.marker.markedState = state;
	this.marker.mark();

	this.fireEvent(new mxEventObject(mxEvent.START, 'state', this.previous));
};

/**
 * Function: isConnecting
 * 
 * Returns true if the source terminal has been clicked and a new
 * connection is currently being previewed.
 */
mxConnectionHandler.prototype.isConnecting = function()
{
	return this.first != null && this.shape != null;
};

/**
 * Function: isValidSource
 * 
 * Returns <mxGraph.isValidSource> for the given source terminal.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents the source terminal.
 * me - <mxMouseEvent> that is associated with this call.
 */
mxConnectionHandler.prototype.isValidSource = function(cell, me)
{
	return this.graph.isValidSource(cell);
};

/**
 * Function: isValidTarget
 * 
 * Returns true. The call to <mxGraph.isValidTarget> is implicit by calling
 * <mxGraph.getEdgeValidationError> in <validateConnection>. This is an
 * additional hook for disabling certain targets in this specific handler.
 * 
 * Parameters:
 * 
 * cell - <mxCell> that represents the target terminal.
 */
mxConnectionHandler.prototype.isValidTarget = function(cell)
{
	return true;
};

/**
 * Function: validateConnection
 * 
 * Returns the error message or an empty string if the connection for the
 * given source target pair is not valid. Otherwise it returns null. This
 * implementation uses <mxGraph.getEdgeValidationError>.
 * 
 * Parameters:
 * 
 * source - <mxCell> that represents the source terminal.
 * target - <mxCell> that represents the target terminal.
 */
mxConnectionHandler.prototype.validateConnection = function(source, target)
{
	if (!this.isValidTarget(target))
	{
		return '';
	}
	
	return this.graph.getEdgeValidationError(null, source, target);
};

/**
 * Function: getConnectImage
 * 
 * Hook to return the <mxImage> used for the connection icon of the given
 * <mxCellState>. This implementation returns <connectImage>.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose connect image should be returned.
 */
mxConnectionHandler.prototype.getConnectImage = function(state)
{
	return this.connectImage;
};

/**
 * Function: isMoveIconToFrontForState
 * 
 * Returns true if the state has a HTML label in the graph's container, otherwise
 * it returns <moveIconFront>.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose connect icons should be returned.
 */
mxConnectionHandler.prototype.isMoveIconToFrontForState = function(state)
{
	if (state.text != null && state.text.node.parentNode == this.graph.container)
	{
		return true;
	}
	
	return this.moveIconFront;
};

/**
 * Function: createIcons
 * 
 * Creates the array <mxImageShapes> that represent the connect icons for
 * the given <mxCellState>.
 * 
 * Parameters:
 * 
 * state - <mxCellState> whose connect icons should be returned.
 */
mxConnectionHandler.prototype.createIcons = function(state)
{
	var image = this.getConnectImage(state);
	
	if (image != null && state != null)
	{
		this.iconState = state;
		var icons = [];

		// Cannot use HTML for the connect icons because the icon receives all
		// mouse move events in IE, must use VML and SVG instead even if the
		// connect-icon appears behind the selection border and the selection
		// border consumes the events before the icon gets a chance
		var bounds = new mxRectangle(0, 0, image.width, image.height);
		var icon = new mxImageShape(bounds, image.src, null, null, 0);
		icon.preserveImageAspect = false;
		
		if (this.isMoveIconToFrontForState(state))
		{
			icon.dialect = mxConstants.DIALECT_STRICTHTML;
			icon.init(this.graph.container);
		}
		else
		{
			icon.dialect = (this.graph.dialect == mxConstants.DIALECT_SVG) ?
				mxConstants.DIALECT_SVG : mxConstants.DIALECT_VML;
			icon.init(this.graph.getView().getOverlayPane());

			// Move the icon back in the overlay pane
			if (this.moveIconBack && icon.node.previousSibling != null)
			{
				icon.node.parentNode.insertBefore(icon.node, icon.node.parentNode.firstChild);
			}
		}

		icon.node.style.cursor = mxConstants.CURSOR_CONNECT;

		// Events transparency
		var getState = mxUtils.bind(this, function()
		{
			return (this.currentState != null) ? this.currentState : state;
		});
		
		// Updates the local icon before firing the mouse down event.
		var mouseDown = mxUtils.bind(this, function(evt)
		{
			if (!mxEvent.isConsumed(evt))
			{
				this.icon = icon;
				this.graph.fireMouseEvent(mxEvent.MOUSE_DOWN,
					new mxMouseEvent(evt, getState()));
			}
		});

		mxEvent.redirectMouseEvents(icon.node, this.graph, getState, mouseDown);
		
		icons.push(icon);
		this.redrawIcons(icons, this.iconState);
		
		return icons;
	}
	
	return null;
};

/**
 * Function: redrawIcons
 * 
 * Redraws the given array of <mxImageShapes>.
 * 
 * Parameters:
 * 
 * icons - Optional array of <mxImageShapes> to be redrawn.
 */
mxConnectionHandler.prototype.redrawIcons = function(icons, state)
{
	if (icons != null && icons[0] != null && state != null)
	{
		var pos = this.getIconPosition(icons[0], state);
		icons[0].bounds.x = pos.x;
		icons[0].bounds.y = pos.y;
		icons[0].redraw();
	}
};

/**
 * Function: redrawIcons
 * 
 * Redraws the given array of <mxImageShapes>.
 * 
 * Parameters:
 * 
 * icons - Optional array of <mxImageShapes> to be redrawn.
 */
mxConnectionHandler.prototype.getIconPosition = function(icon, state)
{
	var scale = this.graph.getView().scale;
	var cx = state.getCenterX();
	var cy = state.getCenterY();
	
	if (this.graph.isSwimlane(state.cell))
	{
		var size = this.graph.getStartSize(state.cell);
		
		cx = (size.width != 0) ? state.x + size.width * scale / 2 : cx;
		cy = (size.height != 0) ? state.y + size.height * scale / 2 : cy;
		
		var alpha = mxUtils.toRadians(mxUtils.getValue(state.style, mxConstants.STYLE_ROTATION) || 0);
		
		if (alpha != 0)
		{
			var cos = Math.cos(alpha);
			var sin = Math.sin(alpha);
			var ct = new mxPoint(state.getCenterX(), state.getCenterY());
			var pt = mxUtils.getRotatedPoint(new mxPoint(cx, cy), cos, sin, ct);
			cx = pt.x;
			cy = pt.y;
		}
	}

	return new mxPoint(cx - icon.bounds.width / 2,
			cy - icon.bounds.height / 2);
};

/**
 * Function: destroyIcons
 * 
 * Destroys the connect icons and resets the respective state.
 */
mxConnectionHandler.prototype.destroyIcons = function()
{
	if (this.icons != null)
	{
		for (var i = 0; i < this.icons.length; i++)
		{
			this.icons[i].destroy();
		}
		
		this.icons = null;
		this.icon = null;
		this.selectedIcon = null;
		this.iconState = null;
	}
};

/**
 * Function: isStartEvent
 * 
 * Returns true if the given mouse down event should start this handler. The
 * This implementation returns true if the event does not force marquee
 * selection, and the currentConstraint and currentFocus of the
 * <constraintHandler> are not null, or <previous> and <error> are not null and
 * <icons> is null or <icons> and <icon> are not null.
 */
mxConnectionHandler.prototype.isStartEvent = function(me)
{
	return ((this.constraintHandler.currentFocus != null && this.constraintHandler.currentConstraint != null) ||
		(this.previous != null && this.error == null && (this.icons == null || (this.icons != null &&
		this.icon != null))));
};

/**
 * Function: mouseDown
 * 
 * Handles the event by initiating a new connection.
 */
mxConnectionHandler.prototype.mouseDown = function(sender, me)
{
	this.mouseDownCounter++;
	
	if (this.isEnabled() && this.graph.isEnabled() && !me.isConsumed() &&
		!this.isConnecting() && this.isStartEvent(me))
	{
		if (this.constraintHandler.currentConstraint != null &&
			this.constraintHandler.currentFocus != null &&
			this.constraintHandler.currentPoint != null)
		{
			this.sourceConstraint = this.constraintHandler.currentConstraint;
			this.previous = this.constraintHandler.currentFocus;
			this.first = this.constraintHandler.currentPoint.clone();
		}
		else
		{
			// Stores the location of the initial mousedown
			this.first = new mxPoint(me.getGraphX(), me.getGraphY());
		}
	
		this.edgeState = this.createEdgeState(me);
		this.mouseDownCounter = 1;
		
		if (this.waypointsEnabled && this.shape == null)
		{
			this.waypoints = null;
			this.shape = this.createShape();
			
			if (this.edgeState != null)
			{
				this.shape.apply(this.edgeState);
			}
		}

		// Stores the starting point in the geometry of the preview
		if (this.previous == null && this.edgeState != null)
		{
			var pt = this.graph.getPointForEvent(me.getEvent());
			this.edgeState.cell.geometry.setTerminalPoint(pt, true);
		}
		
		this.fireEvent(new mxEventObject(mxEvent.START, 'state', this.previous));

		me.consume();
	}

	this.selectedIcon = this.icon;
	this.icon = null;
};

/**
 * Function: isImmediateConnectSource
 * 
 * Returns true if a tap on the given source state should immediately start
 * connecting. This implementation returns true if the state is not movable
 * in the graph. 
 */
mxConnectionHandler.prototype.isImmediateConnectSource = function(state)
{
	return !this.graph.isCellMovable(state.cell);
};

/**
 * Function: createEdgeState
 * 
 * Hook to return an <mxCellState> which may be used during the preview.
 * This implementation returns null.
 * 
 * Use the following code to create a preview for an existing edge style:
 * 
 * (code)
 * graph.connectionHandler.createEdgeState = function(me)
 * {
 *   var edge = graph.createEdge(null, null, null, null, null, 'edgeStyle=elbowEdgeStyle');
 *   
 *   return new mxCellState(this.graph.view, edge, this.graph.getCellStyle(edge));
 * };
 * (end)
 */
mxConnectionHandler.prototype.createEdgeState = function(me)
{
	return null;
};

/**
 * Function: isOutlineConnectEvent
 * 
 * Returns true if <outlineConnect> is true and the source of the event is the outline shape
 * or shift is pressed.
 */
mxConnectionHandler.prototype.isOutlineConnectEvent = function(me)
{
	var offset = mxUtils.getOffset(this.graph.container);
	var evt = me.getEvent();
	
	var clientX = mxEvent.getClientX(evt);
	var clientY = mxEvent.getClientY(evt);
	
	var doc = document.documentElement;
	var left = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
	var top = (window.pageYOffset || doc.scrollTop)  - (doc.clientTop || 0);
	
	var gridX = this.currentPoint.x - this.graph.container.scrollLeft + offset.x - left;
	var gridY = this.currentPoint.y - this.graph.container.scrollTop + offset.y - top;

	return this.outlineConnect && !mxEvent.isShiftDown(me.getEvent()) &&
		(me.isSource(this.marker.highlight.shape) ||
		(mxEvent.isAltDown(me.getEvent()) && me.getState() != null) ||
		this.marker.highlight.isHighlightAt(clientX, clientY) ||
		((gridX != clientX || gridY != clientY) && me.getState() == null &&
		this.marker.highlight.isHighlightAt(gridX, gridY)));
};

/**
 * Function: updateCurrentState
 * 
 * Updates the current state for a given mouse move event by using
 * the <marker>.
 */
mxConnectionHandler.prototype.updateCurrentState = function(me, point)
{
	this.constraintHandler.update(me, this.first == null, false, (this.first == null ||
		me.isSource(this.marker.highlight.shape)) ? null : point);
	
	if (this.constraintHandler.currentFocus != null && this.constraintHandler.currentConstraint != null)
	{
		// Handles special case where grid is large and connection point is at actual point in which
		// case the outline is not followed as long as we're < gridSize / 2 away from that point
		if (this.marker.highlight != null && this.marker.highlight.state != null &&
			this.marker.highlight.state.cell == this.constraintHandler.currentFocus.cell)
		{
			// Direct repaint needed if cell already highlighted
			if (this.marker.highlight.shape.stroke != 'transparent')
			{
				this.marker.highlight.shape.stroke = 'transparent';
				this.marker.highlight.repaint();
			}
		}
		else
		{
			this.marker.markCell(this.constraintHandler.currentFocus.cell, 'transparent');
		}

		// Updates validation state
		if (this.previous != null)
		{
			this.error = this.validateConnection(this.previous.cell, this.constraintHandler.currentFocus.cell);
			
			if (this.error == null)
			{
				this.currentState = this.constraintHandler.currentFocus;
			}
			else
			{
				this.constraintHandler.reset();
			}
		}
	}
	else
	{
		if (this.graph.isIgnoreTerminalEvent(me.getEvent()))
		{
			this.marker.reset();
			this.currentState = null;
		}
		else
		{
			this.marker.process(me);
			this.currentState = this.marker.getValidState();
		}

		var outline = this.isOutlineConnectEvent(me);
		
		if (this.currentState != null && outline)
		{
			// Handles special case where mouse is on outline away from actual end point
			// in which case the grid is ignored and mouse point is used instead
			if (me.isSource(this.marker.highlight.shape))
			{
				point = new mxPoint(me.getGraphX(), me.getGraphY());
			}
			
			var constraint = this.graph.getOutlineConstraint(point, this.currentState, me);
			this.constraintHandler.setFocus(me, this.currentState, false);
			this.constraintHandler.currentConstraint = constraint;
			this.constraintHandler.currentPoint = point;
		}

		if (this.outlineConnect)
		{
			if (this.marker.highlight != null && this.marker.highlight.shape != null)
			{
				var s = this.graph.view.scale;
				
				if (this.constraintHandler.currentConstraint != null &&
					this.constraintHandler.currentFocus != null)
				{
					this.marker.highlight.shape.stroke = mxConstants.OUTLINE_HIGHLIGHT_COLOR;
					this.marker.highlight.shape.strokewidth = mxConstants.OUTLINE_HIGHLIGHT_STROKEWIDTH / s / s;
					this.marker.highlight.repaint();
				} 
				else if (this.marker.hasValidState())
				{
					// Handles special case where actual end point of edge and current mouse point
					// are not equal (due to grid snapping) and there is no hit on shape or highlight
					if (this.marker.getValidState() != me.getState())
					{
						this.marker.highlight.shape.stroke = 'transparent';
						this.currentState = null;
					}
					else
					{
						this.marker.highlight.shape.stroke = mxConstants.DEFAULT_VALID_COLOR;
					}
	
					this.marker.highlight.shape.strokewidth = mxConstants.HIGHLIGHT_STROKEWIDTH / s / s;
					this.marker.highlight.repaint();
				}
			}
		}
	}
};

/**
 * Function: convertWaypoint
 * 
 * Converts the given point from screen coordinates to model coordinates.
 */
mxConnectionHandler.prototype.convertWaypoint = function(point)
{
	var scale = this.graph.getView().getScale();
	var tr = this.graph.getView().getTranslate();
	
	point.x = point.x / scale - tr.x;
	point.y = point.y / scale - tr.y;
};

/**
 * Function: snapToPreview
 * 
 * Called to snap the given point to the current preview. This snaps to the
 * first point of the preview if alt is not pressed.
 */
mxConnectionHandler.prototype.snapToPreview = function(me, point)
{
	if (!mxEvent.isAltDown(me.getEvent()) && this.previous != null)
	{
		var tol = this.graph.gridSize * this.graph.view.scale / 2;	
		var tmp = (this.sourceConstraint != null) ? this.first :
			new mxPoint(this.previous.getCenterX(), this.previous.getCenterY());

		if (Math.abs(tmp.x - me.getGraphX()) < tol)
		{
			point.x = tmp.x;
		}
		
		if (Math.abs(tmp.y - me.getGraphY()) < tol)
		{
			point.y = tmp.y;
		}
	}	
};

/**
 * Function: mouseMove
 * 
 * Handles the event by updating the preview edge or by highlighting
 * a possible source or target terminal.
 */
mxConnectionHandler.prototype.mouseMove = function(sender, me)
{
	if (!me.isConsumed() && (this.ignoreMouseDown || this.first != null || !this.graph.isMouseDown))
	{
		// Handles special case when handler is disabled during highlight
		if (!this.isEnabled() && this.currentState != null)
		{
			this.destroyIcons();
			this.currentState = null;
		}

		var view = this.graph.getView();
		var scale = view.scale;
		var tr = view.translate;
		var point = new mxPoint(me.getGraphX(), me.getGraphY());
		this.error = null;

		if (this.graph.isGridEnabledEvent(me.getEvent()))
		{
			point = new mxPoint((this.graph.snap(point.x / scale - tr.x) + tr.x) * scale,
				(this.graph.snap(point.y / scale - tr.y) + tr.y) * scale);
		}
		
		this.snapToPreview(me, point);
		this.currentPoint = point;
		
		if (this.first != null || (this.isEnabled() && this.graph.isEnabled()))
		{
			this.updateCurrentState(me, point);
		}

		if (this.first != null)
		{
			var constraint = null;
			var current = point;
			
			// Uses the current point from the constraint handler if available
			if (this.constraintHandler.currentConstraint != null &&
				this.constraintHandler.currentFocus != null &&
				this.constraintHandler.currentPoint != null)
			{
				constraint = this.constraintHandler.currentConstraint;
				current = this.constraintHandler.currentPoint.clone();
			}
			else if (this.previous != null && !this.graph.isIgnoreTerminalEvent(me.getEvent()) && mxEvent.isShiftDown(me.getEvent()))
			{
				if (Math.abs(this.previous.getCenterX() - point.x) < Math.abs(this.previous.getCenterY() - point.y))
				{
					point.x = this.previous.getCenterX();
				}
				else
				{
					point.y = this.previous.getCenterY();
				}
			}
			
			var pt2 = this.first;
			
			// Moves the connect icon with the mouse
			if (this.selectedIcon != null)
			{
				var w = this.selectedIcon.bounds.width;
				var h = this.selectedIcon.bounds.height;
				
				if (this.currentState != null && this.targetConnectImage)
				{
					var pos = this.getIconPosition(this.selectedIcon, this.currentState);
					this.selectedIcon.bounds.x = pos.x;
					this.selectedIcon.bounds.y = pos.y;
				}
				else
				{
					var bounds = new mxRectangle(me.getGraphX() + this.connectIconOffset.x,
						me.getGraphY() + this.connectIconOffset.y, w, h);
					this.selectedIcon.bounds = bounds;
				}
				
				this.selectedIcon.redraw();
			}

			// Uses edge state to compute the terminal points
			if (this.edgeState != null)
			{
				this.updateEdgeState(current, constraint);
				current = this.edgeState.absolutePoints[this.edgeState.absolutePoints.length - 1];
				pt2 = this.edgeState.absolutePoints[0];
			}
			else
			{
				if (this.currentState != null)
				{
					if (this.constraintHandler.currentConstraint == null)
					{
						var tmp = this.getTargetPerimeterPoint(this.currentState, me);
						
						if (tmp != null)
						{
							current = tmp;
						}
					}
				}
				
				// Computes the source perimeter point
				if (this.sourceConstraint == null && this.previous != null)
				{
					var next = (this.waypoints != null && this.waypoints.length > 0) ?
							this.waypoints[0] : current;
					var tmp = this.getSourcePerimeterPoint(this.previous, next, me);
					
					if (tmp != null)
					{
						pt2 = tmp;
					}
				}
			}

			// Makes sure the cell under the mousepointer can be detected
			// by moving the preview shape away from the mouse. This
			// makes sure the preview shape does not prevent the detection
			// of the cell under the mousepointer even for slow gestures.
			if (this.currentState == null && this.movePreviewAway)
			{
				var tmp = pt2; 
				
				if (this.edgeState != null && this.edgeState.absolutePoints.length >= 2)
				{
					var tmp2 = this.edgeState.absolutePoints[this.edgeState.absolutePoints.length - 2];
					
					if (tmp2 != null)
					{
						tmp = tmp2;
					}
				}
				
				var dx = current.x - tmp.x;
				var dy = current.y - tmp.y;
				
				var len = Math.sqrt(dx * dx + dy * dy);
				
				if (len == 0)
				{
					return;
				}

				// Stores old point to reuse when creating edge
				this.originalPoint = current.clone();
				current.x -= dx * 4 / len;
				current.y -= dy * 4 / len;
			}
			else
			{
				this.originalPoint = null;
			}
			
			// Creates the preview shape (lazy)
			if (this.shape == null)
			{
				var dx = Math.abs(point.x - this.first.x);
				var dy = Math.abs(point.y - this.first.y);

				if (dx > this.graph.tolerance || dy > this.graph.tolerance)
				{
					this.shape = this.createShape();

					if (this.edgeState != null)
					{
						this.shape.apply(this.edgeState);
					}
					
					// Revalidates current connection
					this.updateCurrentState(me, point);
				}
			}

			// Updates the points in the preview edge
			if (this.shape != null)
			{
				if (this.edgeState != null)
				{
					this.shape.points = this.edgeState.absolutePoints;
				}
				else
				{
					var pts = [pt2];
					
					if (this.waypoints != null)
					{
						pts = pts.concat(this.waypoints);
					}

					pts.push(current);
					this.shape.points = pts;
				}
				
				this.drawPreview();
			}
			
			// Makes sure endpoint of edge is visible during connect
			if (this.cursor != null)
			{
				this.graph.container.style.cursor = this.cursor;
			}
			
			mxEvent.consume(me.getEvent());
			me.consume();
		}
		else if (!this.isEnabled() || !this.graph.isEnabled())
		{
			this.constraintHandler.reset();
		}
		else if (this.previous != this.currentState && this.edgeState == null)
		{
			this.destroyIcons();
			
			// Sets the cursor on the current shape				
			if (this.currentState != null && this.error == null && this.constraintHandler.currentConstraint == null)
			{
				this.icons = this.createIcons(this.currentState);

				if (this.icons == null)
				{
					this.currentState.setCursor(mxConstants.CURSOR_CONNECT);
					me.consume();
				}
			}

			this.previous = this.currentState;
		}
		else if (this.previous == this.currentState && this.currentState != null && this.icons == null &&
			!this.graph.isMouseDown)
		{
			// Makes sure that no cursors are changed
			me.consume();
		}

		if (!this.graph.isMouseDown && this.currentState != null && this.icons != null)
		{
			var hitsIcon = false;
			var target = me.getSource();
			
			for (var i = 0; i < this.icons.length && !hitsIcon; i++)
			{
				hitsIcon = target == this.icons[i].node || target.parentNode == this.icons[i].node;
			}

			if (!hitsIcon)
			{
				this.updateIcons(this.currentState, this.icons, me);
			}
		}
	}
	else
	{
		this.constraintHandler.reset();
	}
};

/**
 * Function: updateEdgeState
 * 
 * Updates <edgeState>.
 */
mxConnectionHandler.prototype.updateEdgeState = function(current, constraint)
{
	// TODO: Use generic method for writing constraint to style
	if (this.sourceConstraint != null && this.sourceConstraint.point != null)
	{
		this.edgeState.style[mxConstants.STYLE_EXIT_X] = this.sourceConstraint.point.x;
		this.edgeState.style[mxConstants.STYLE_EXIT_Y] = this.sourceConstraint.point.y;
	}

	if (constraint != null && constraint.point != null)
	{
		this.edgeState.style[mxConstants.STYLE_ENTRY_X] = constraint.point.x;
		this.edgeState.style[mxConstants.STYLE_ENTRY_Y] = constraint.point.y;
	}
	else
	{
		delete this.edgeState.style[mxConstants.STYLE_ENTRY_X];
		delete this.edgeState.style[mxConstants.STYLE_ENTRY_Y];
	}
	
	this.edgeState.absolutePoints = [null, (this.currentState != null) ? null : current];
	this.graph.view.updateFixedTerminalPoint(this.edgeState, this.previous, true, this.sourceConstraint);
	
	if (this.currentState != null)
	{
		if (constraint == null)
		{
			constraint = this.graph.getConnectionConstraint(this.edgeState, this.previous, false);
		}
		
		this.edgeState.setAbsoluteTerminalPoint(null, false);
		this.graph.view.updateFixedTerminalPoint(this.edgeState, this.currentState, false, constraint);
	}
	
	// Scales and translates the waypoints to the model
	var realPoints = null;
	
	if (this.waypoints != null)
	{
		realPoints = [];
		
		for (var i = 0; i < this.waypoints.length; i++)
		{
			var pt = this.waypoints[i].clone();
			this.convertWaypoint(pt);
			realPoints[i] = pt;
		}
	}
	
	this.graph.view.updatePoints(this.edgeState, realPoints, this.previous, this.currentState);
	this.graph.view.updateFloatingTerminalPoints(this.edgeState, this.previous, this.currentState);
};

/**
 * Function: getTargetPerimeterPoint
 * 
 * Returns the perimeter point for the given target state.
 * 
 * Parameters:
 * 
 * state - <mxCellState> that represents the target cell state.
 * me - <mxMouseEvent> that represents the mouse move.
 */
mxConnectionHandler.prototype.getTargetPerimeterPoint = function(state, me)
{
	var result = null;
	var view = state.view;
	var targetPerimeter = view.getPerimeterFunction(state);
	
	if (targetPerimeter != null)
	{
		var next = (this.waypoints != null && this.waypoints.length > 0) ?
				this.waypoints[this.waypoints.length - 1] :
				new mxPoint(this.previous.getCenterX(), this.previous.getCenterY());
		var tmp = targetPerimeter(view.getPerimeterBounds(state),
			this.edgeState, next, false);
			
		if (tmp != null)
		{
			result = tmp;
		}
	}
	else
	{
		result = new mxPoint(state.getCenterX(), state.getCenterY());
	}
	
	return result;
};

/**
 * Function: getSourcePerimeterPoint
 * 
 * Hook to update the icon position(s) based on a mouseOver event. This is
 * an empty implementation.
 * 
 * Parameters:
 * 
 * state - <mxCellState> that represents the target cell state.
 * next - <mxPoint> that represents the next point along the previewed edge.
 * me - <mxMouseEvent> that represents the mouse move.
 */
mxConnectionHandler.prototype.getSourcePerimeterPoint = function(state, next, me)
{
	var result = null;
	var view = state.view;
	var sourcePerimeter = view.getPerimeterFunction(state);
	var c = new mxPoint(state.getCenterX(), state.getCenterY());
	
	if (sourcePerimeter != null)
	{
		var theta = mxUtils.getValue(state.style, mxConstants.STYLE_ROTATION, 0);
		var rad = -theta * (Math.PI / 180);
		
		if (theta != 0)
		{
			next = mxUtils.getRotatedPoint(new mxPoint(next.x, next.y), Math.cos(rad), Math.sin(rad), c);
		}
		
		var tmp = sourcePerimeter(view.getPerimeterBounds(state), state, next, false);
			
		if (tmp != null)
		{
			if (theta != 0)
			{
				tmp = mxUtils.getRotatedPoint(new mxPoint(tmp.x, tmp.y), Math.cos(-rad), Math.sin(-rad), c);
			}
			
			result = tmp;
		}
	}
	else
	{
		result = c;
	}
	
	return result;
};


/**
 * Function: updateIcons
 * 
 * Hook to update the icon position(s) based on a mouseOver event. This is
 * an empty implementation.
 * 
 * Parameters:
 * 
 * state - <mxCellState> under the mouse.
 * icons - Array of currently displayed icons.
 * me - <mxMouseEvent> that contains the mouse event.
 */
mxConnectionHandler.prototype.updateIcons = function(state, icons, me)
{
	// empty
};

/**
 * Function: isStopEvent
 * 
 * Returns true if the given mouse up event should stop this handler. The
 * connection will be created if <error> is null. Note that this is only
 * called if <waypointsEnabled> is true. This implemtation returns true
 * if there is a cell state in the given event.
 */
mxConnectionHandler.prototype.isStopEvent = function(me)
{
	return me.getState() != null;
};

/**
 * Function: addWaypoint
 * 
 * Adds the waypoint for the given event to <waypoints>.
 */
mxConnectionHandler.prototype.addWaypointForEvent = function(me)
{
	var point = mxUtils.convertPoint(this.graph.container, me.getX(), me.getY());
	var dx = Math.abs(point.x - this.first.x);
	var dy = Math.abs(point.y - this.first.y);
	var addPoint = this.waypoints != null || (this.mouseDownCounter > 1 &&
			(dx > this.graph.tolerance || dy > this.graph.tolerance));

	if (addPoint)
	{
		if (this.waypoints == null)
		{
			this.waypoints = [];
		}
		
		var scale = this.graph.view.scale;
		var point = new mxPoint(this.graph.snap(me.getGraphX() / scale) * scale,
				this.graph.snap(me.getGraphY() / scale) * scale);
		this.waypoints.push(point);
	}
};

/**
 * Function: mouseUp
 * 
 * Handles the event by inserting the new connection.
 */
mxConnectionHandler.prototype.mouseUp = function(sender, me)
{
	if (!me.isConsumed() && this.isConnecting())
	{
		if (this.waypointsEnabled && !this.isStopEvent(me))
		{
			this.addWaypointForEvent(me);
			me.consume();
			
			return;
		}
		
		// Inserts the edge if no validation error exists
		if (this.error == null)
		{
			var source = (this.previous != null) ? this.previous.cell : null;
			var target = null;
			
			if (this.constraintHandler.currentConstraint != null &&
				this.constraintHandler.currentFocus != null)
			{
				target = this.constraintHandler.currentFocus.cell;
			}
			
			if (target == null && this.currentState != null)
			{
				target = this.currentState.cell;
			}
			
			this.connect(source, target, me.getEvent(), me.getCell());
		}
		else
		{
			// Selects the source terminal for self-references
			if (this.previous != null && this.marker.validState != null &&
				this.previous.cell == this.marker.validState.cell)
			{
				this.graph.selectCellForEvent(this.marker.source, evt);
			}
			
			// Displays the error message if it is not an empty string,
			// for empty error messages, the event is silently dropped
			if (this.error.length > 0)
			{
				this.graph.validationAlert(this.error);
			}
		}
		
		// Redraws the connect icons and resets the handler state
		this.destroyIcons();
		me.consume();
	}

	if (this.first != null)
	{
		this.reset();
	}
};

/**
 * Function: reset
 * 
 * Resets the state of this handler.
 */
mxConnectionHandler.prototype.reset = function()
{
	if (this.shape != null)
	{
		this.shape.destroy();
		this.shape = null;
	}
	
	// Resets the cursor on the container
	if (this.cursor != null && this.graph.container != null)
	{
		this.graph.container.style.cursor = '';
	}
	
	this.destroyIcons();
	this.marker.reset();
	this.constraintHandler.reset();
	this.originalPoint = null;
	this.currentPoint = null;
	this.edgeState = null;
	this.previous = null;
	this.error = null;
	this.sourceConstraint = null;
	this.mouseDownCounter = 0;
	this.first = null;

	this.fireEvent(new mxEventObject(mxEvent.RESET));
};

/**
 * Function: drawPreview
 * 
 * Redraws the preview edge using the color and width returned by
 * <getEdgeColor> and <getEdgeWidth>.
 */
mxConnectionHandler.prototype.drawPreview = function()
{
	this.updatePreview(this.error == null);
	this.shape.redraw();
};

/**
 * Function: getEdgeColor
 * 
 * Returns the color used to draw the preview edge. This returns green if
 * there is no edge validation error and red otherwise.
 * 
 * Parameters:
 * 
 * valid - Boolean indicating if the color for a valid edge should be
 * returned.
 */
mxConnectionHandler.prototype.updatePreview = function(valid)
{
	this.shape.strokewidth = this.getEdgeWidth(valid);
	this.shape.stroke = this.getEdgeColor(valid);
};

/**
 * Function: getEdgeColor
 * 
 * Returns the color used to draw the preview edge. This returns green if
 * there is no edge validation error and red otherwise.
 * 
 * Parameters:
 * 
 * valid - Boolean indicating if the color for a valid edge should be
 * returned.
 */
mxConnectionHandler.prototype.getEdgeColor = function(valid)
{
	return (valid) ? mxConstants.VALID_COLOR : mxConstants.INVALID_COLOR;
};
	
/**
 * Function: getEdgeWidth
 * 
 * Returns the width used to draw the preview edge. This returns 3 if
 * there is no edge validation error and 1 otherwise.
 * 
 * Parameters:
 * 
 * valid - Boolean indicating if the width for a valid edge should be
 * returned.
 */
mxConnectionHandler.prototype.getEdgeWidth = function(valid)
{
	return (valid) ? 3 : 1;
};

/**
 * Function: connect
 * 
 * Connects the given source and target using a new edge. This
 * implementation uses <createEdge> to create the edge.
 * 
 * Parameters:
 * 
 * source - <mxCell> that represents the source terminal.
 * target - <mxCell> that represents the target terminal.
 * evt - Mousedown event of the connect gesture.
 * dropTarget - <mxCell> that represents the cell under the mouse when it was
 * released.
 */
mxConnectionHandler.prototype.connect = function(source, target, evt, dropTarget)
{
	if (target != null || this.isCreateTarget(evt) || this.graph.allowDanglingEdges)
	{
		// Uses the common parent of source and target or
		// the default parent to insert the edge
		var model = this.graph.getModel();
		var terminalInserted = false;
		var edge = null;

		model.beginUpdate();
		try
		{
			if (source != null && target == null && !this.graph.isIgnoreTerminalEvent(evt) && this.isCreateTarget(evt))
			{
				target = this.createTargetVertex(evt, source);
				
				if (target != null)
				{
					dropTarget = this.graph.getDropTarget([target], evt, dropTarget);
					terminalInserted = true;
					
					// Disables edges as drop targets if the target cell was created
					// FIXME: Should not shift if vertex was aligned (same in Java)
					if (dropTarget == null || !this.graph.getModel().isEdge(dropTarget))
					{
						var pstate = this.graph.getView().getState(dropTarget);
						
						if (pstate != null)
						{
							var tmp = model.getGeometry(target);
							tmp.x -= pstate.origin.x;
							tmp.y -= pstate.origin.y;
						}
					}
					else
					{
						dropTarget = this.graph.getDefaultParent();
					}
						
					this.graph.addCell(target, dropTarget);
				}
			}

			var parent = this.graph.getDefaultParent();

			if (source != null && target != null &&
				model.getParent(source) == model.getParent(target) &&
				model.getParent(model.getParent(source)) != model.getRoot())
			{
				parent = model.getParent(source);

				if ((source.geometry != null && source.geometry.relative) &&
					(target.geometry != null && target.geometry.relative))
				{
					parent = model.getParent(parent);
				}
			}
			
			// Uses the value of the preview edge state for inserting
			// the new edge into the graph
			var value = null;
			var style = null;
			
			if (this.edgeState != null)
			{
				value = this.edgeState.cell.value;
				style = this.edgeState.cell.style;
			}

			edge = this.insertEdge(parent, null, value, source, target, style);
			
			if (edge != null)
			{
				// Updates the connection constraints
				this.graph.setConnectionConstraint(edge, source, true, this.sourceConstraint);
				this.graph.setConnectionConstraint(edge, target, false, this.constraintHandler.currentConstraint);
				
				// Uses geometry of the preview edge state
				if (this.edgeState != null)
				{
					model.setGeometry(edge, this.edgeState.cell.geometry);
				}
				
				var parent = model.getParent(source);
				
				// Inserts edge before source
				if (this.isInsertBefore(edge, source, target, evt, dropTarget))
				{
					var index = null;
					var tmp = source;

					while (tmp.parent != null && tmp.geometry != null &&
						tmp.geometry.relative && tmp.parent != edge.parent)
					{
						tmp = this.graph.model.getParent(tmp);
					}

					if (tmp != null && tmp.parent != null && tmp.parent == edge.parent)
					{
						var index = tmp.parent.getIndex(tmp);
						tmp.parent.insert(edge, index);
					}
				}
				
				// Makes sure the edge has a non-null, relative geometry
				var geo = model.getGeometry(edge);

				if (geo == null)
				{
					geo = new mxGeometry();
					geo.relative = true;
					
					model.setGeometry(edge, geo);
				}
				
				// Uses scaled waypoints in geometry
				if (this.waypoints != null && this.waypoints.length > 0)
				{
					var s = this.graph.view.scale;
					var tr = this.graph.view.translate;
					geo.points = [];
					
					for (var i = 0; i < this.waypoints.length; i++)
					{
						var pt = this.waypoints[i];
						geo.points.push(new mxPoint(pt.x / s - tr.x, pt.y / s - tr.y));
					}
				}

				if (target == null)
				{
					var t = this.graph.view.translate;
					var s = this.graph.view.scale;
					var pt = (this.originalPoint != null) ?
							new mxPoint(this.originalPoint.x / s - t.x, this.originalPoint.y / s - t.y) :
						new mxPoint(this.currentPoint.x / s - t.x, this.currentPoint.y / s - t.y);
					pt.x -= this.graph.panDx / this.graph.view.scale;
					pt.y -= this.graph.panDy / this.graph.view.scale;
					geo.setTerminalPoint(pt, false);
				}
				
				this.fireEvent(new mxEventObject(mxEvent.CONNECT, 'cell', edge, 'terminal', target,
					'event', evt, 'target', dropTarget, 'terminalInserted', terminalInserted));
			}
		}
		catch (e)
		{
			mxLog.show();
			mxLog.debug(e.message);
		}
		finally
		{
			model.endUpdate();
		}
		
		if (this.select)
		{
			this.selectCells(edge, (terminalInserted) ? target : null);
		}
	}
};

/**
 * Function: selectCells
 * 
 * Selects the given edge after adding a new connection. The target argument
 * contains the target vertex if one has been inserted.
 */
mxConnectionHandler.prototype.selectCells = function(edge, target)
{
	this.graph.setSelectionCell(edge);
};

/**
 * Function: insertEdge
 * 
 * Creates, inserts and returns the new edge for the given parameters. This
 * implementation does only use <createEdge> if <factoryMethod> is defined,
 * otherwise <mxGraph.insertEdge> will be used.
 */
mxConnectionHandler.prototype.insertEdge = function(parent, id, value, source, target, style)
{
	if (this.factoryMethod == null)
	{
		return this.graph.insertEdge(parent, id, value, source, target, style);
	}
	else
	{
		var edge = this.createEdge(value, source, target, style);
		edge = this.graph.addEdge(edge, parent, source, target);
		
		return edge;
	}
};

/**
 * Function: createTargetVertex
 * 
 * Hook method for creating new vertices on the fly if no target was
 * under the mouse. This is only called if <createTarget> is true and
 * returns null.
 * 
 * Parameters:
 * 
 * evt - Mousedown event of the connect gesture.
 * source - <mxCell> that represents the source terminal.
 */
mxConnectionHandler.prototype.createTargetVertex = function(evt, source)
{
	// Uses the first non-relative source
	var geo = this.graph.getCellGeometry(source);
	
	while (geo != null && geo.relative)
	{
		source = this.graph.getModel().getParent(source);
		geo = this.graph.getCellGeometry(source);
	}
	
	var clone = this.graph.cloneCells([source])[0];
	var geo = this.graph.getModel().getGeometry(clone);
	
	if (geo != null)
	{
		var t = this.graph.view.translate;
		var s = this.graph.view.scale;
		var point = new mxPoint(this.currentPoint.x / s - t.x, this.currentPoint.y / s - t.y);
		geo.x = Math.round(point.x - geo.width / 2 - this.graph.panDx / s);
		geo.y = Math.round(point.y - geo.height / 2 - this.graph.panDy / s);

		// Aligns with source if within certain tolerance
		var tol = this.getAlignmentTolerance();
		
		if (tol > 0)
		{
			var sourceState = this.graph.view.getState(source);
			
			if (sourceState != null)
			{
				var x = sourceState.x / s - t.x;
				var y = sourceState.y / s - t.y;
				
				if (Math.abs(x - geo.x) <= tol)
				{
					geo.x = Math.round(x);
				}
				
				if (Math.abs(y - geo.y) <= tol)
				{
					geo.y = Math.round(y);
				}
			}
		}
	}

	return clone;		
};

/**
 * Function: getAlignmentTolerance
 * 
 * Returns the tolerance for aligning new targets to sources. This returns the grid size / 2.
 */
mxConnectionHandler.prototype.getAlignmentTolerance = function(evt)
{
	return (this.graph.isGridEnabled()) ? this.graph.gridSize / 2 : this.graph.tolerance;
};

/**
 * Function: createEdge
 * 
 * Creates and returns a new edge using <factoryMethod> if one exists. If
 * no factory method is defined, then a new default edge is returned. The
 * source and target arguments are informal, the actual connection is
 * setup later by the caller of this function.
 * 
 * Parameters:
 * 
 * value - Value to be used for creating the edge.
 * source - <mxCell> that represents the source terminal.
 * target - <mxCell> that represents the target terminal.
 * style - Optional style from the preview edge.
 */
mxConnectionHandler.prototype.createEdge = function(value, source, target, style)
{
	var edge = null;
	
	// Creates a new edge using the factoryMethod
	if (this.factoryMethod != null)
	{
		edge = this.factoryMethod(source, target, style);
	}
	
	if (edge == null)
	{
		edge = new mxCell(value || '');
		edge.setEdge(true);
		edge.setStyle(style);
		
		var geo = new mxGeometry();
		geo.relative = true;
		edge.setGeometry(geo);
	}

	return edge;
};

/**
 * Function: destroy
 * 
 * Destroys the handler and all its resources and DOM nodes. This should be
 * called on all instances. It is called automatically for the built-in
 * instance created for each <mxGraph>.
 */
mxConnectionHandler.prototype.destroy = function()
{
	this.graph.removeMouseListener(this);
	
	if (this.shape != null)
	{
		this.shape.destroy();
		this.shape = null;
	}
	
	if (this.marker != null)
	{
		this.marker.destroy();
		this.marker = null;
	}

	if (this.constraintHandler != null)
	{
		this.constraintHandler.destroy();
		this.constraintHandler = null;
	}

	if (this.changeHandler != null)
	{
		this.graph.getModel().removeListener(this.changeHandler);
		this.graph.getView().removeListener(this.changeHandler);
		this.changeHandler = null;
	}
	
	if (this.drillHandler != null)
	{
		this.graph.removeListener(this.drillHandler);
		this.graph.getView().removeListener(this.drillHandler);
		this.drillHandler = null;
	}
	
	if (this.escapeHandler != null)
	{
		this.graph.removeListener(this.escapeHandler);
		this.escapeHandler = null;
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxConstraintHandler
 *
 * Handles constraints on connection targets. This class is in charge of
 * showing fixed points when the mouse is over a vertex and handles constraints
 * to establish new connections.
 *
 * Constructor: mxConstraintHandler
 *
 * Constructs an new constraint handler.
 * 
 * Parameters:
 * 
 * graph - Reference to the enclosing <mxGraph>.
 * factoryMethod - Optional function to create the edge. The function takes
 * the source and target <mxCell> as the first and second argument and
 * returns the <mxCell> that represents the new edge.
 */
function mxConstraintHandler(graph)
{
	this.graph = graph;
	
	// Adds a graph model listener to update the current focus on changes
	this.resetHandler = mxUtils.bind(this, function(sender, evt)
	{
		if (this.currentFocus != null && this.graph.view.getState(this.currentFocus.cell) == null)
		{
			this.reset();
		}
		else
		{
			this.redraw();
		}
	});
	
	this.graph.model.addListener(mxEvent.CHANGE, this.resetHandler);
	this.graph.view.addListener(mxEvent.SCALE, this.resetHandler);
	this.graph.addListener(mxEvent.ROOT, this.resetHandler);
};

/**
 * Variable: pointImage
 * 
 * <mxImage> to be used as the image for fixed connection points.
 */
mxConstraintHandler.prototype.pointImage = new mxImage(mxClient.imageBasePath + '/point.gif', 5, 5);

/**
 * Variable: graph
 * 
 * Reference to the enclosing <mxGraph>.
 */
mxConstraintHandler.prototype.graph = null;

/**
 * Variable: enabled
 * 
 * Specifies if events are handled. Default is true.
 */
mxConstraintHandler.prototype.enabled = true;

/**
 * Variable: highlightColor
 * 
 * Specifies the color for the highlight. Default is <mxConstants.DEFAULT_VALID_COLOR>.
 */
mxConstraintHandler.prototype.highlightColor = mxConstants.DEFAULT_VALID_COLOR;

/**
 * Function: isEnabled
 * 
 * Returns true if events are handled. This implementation
 * returns <enabled>.
 */
mxConstraintHandler.prototype.isEnabled = function()
{
	return this.enabled;
};
	
/**
 * Function: setEnabled
 * 
 * Enables or disables event handling. This implementation
 * updates <enabled>.
 * 
 * Parameters:
 * 
 * enabled - Boolean that specifies the new enabled state.
 */
mxConstraintHandler.prototype.setEnabled = function(enabled)
{
	this.enabled = enabled;
};

/**
 * Function: reset
 * 
 * Resets the state of this handler.
 */
mxConstraintHandler.prototype.reset = function()
{
	if (this.focusIcons != null)
	{
		for (var i = 0; i < this.focusIcons.length; i++)
		{
			this.focusIcons[i].destroy();
		}
		
		this.focusIcons = null;
	}
	
	if (this.focusHighlight != null)
	{
		this.focusHighlight.destroy();
		this.focusHighlight = null;
	}
	
	this.currentConstraint = null;
	this.currentFocusArea = null;
	this.currentPoint = null;
	this.currentFocus = null;
	this.focusPoints = null;
};

/**
 * Function: getTolerance
 * 
 * Returns the tolerance to be used for intersecting connection points. This
 * implementation returns <mxGraph.tolerance>.
 * 
 * Parameters:
 * 
 * me - <mxMouseEvent> whose tolerance should be returned.
 */
mxConstraintHandler.prototype.getTolerance = function(me)
{
	return this.graph.getTolerance();
};

/**
 * Function: getImageForConstraint
 * 
 * Returns the tolerance to be used for intersecting connection points.
 */
mxConstraintHandler.prototype.getImageForConstraint = function(state, constraint, point)
{
	return this.pointImage;
};

/**
 * Function: isEventIgnored
 * 
 * Returns true if the given <mxMouseEvent> should be ignored in <update>. This
 * implementation always returns false.
 */
mxConstraintHandler.prototype.isEventIgnored = function(me, source)
{
	return false;
};

/**
 * Function: isStateIgnored
 * 
 * Returns true if the given state should be ignored. This always returns false.
 */
mxConstraintHandler.prototype.isStateIgnored = function(state, source)
{
	return false;
};

/**
 * Function: destroyIcons
 * 
 * Destroys the <focusIcons> if they exist.
 */
mxConstraintHandler.prototype.destroyIcons = function()
{
	if (this.focusIcons != null)
	{
		for (var i = 0; i < this.focusIcons.length; i++)
		{
			this.focusIcons[i].destroy();
		}
		
		this.focusIcons = null;
		this.focusPoints = null;
	}
};

/**
 * Function: destroyFocusHighlight
 * 
 * Destroys the <focusHighlight> if one exists.
 */
mxConstraintHandler.prototype.destroyFocusHighlight = function()
{
	if (this.focusHighlight != null)
	{
		this.focusHighlight.destroy();
		this.focusHighlight = null;
	}
};

/**
 * Function: isKeepFocusEvent
 * 
 * Returns true if the current focused state should not be changed for the given event.
 * This returns true if shift and alt are pressed.
 */
mxConstraintHandler.prototype.isKeepFocusEvent = function(me)
{
	return mxEvent.isShiftDown(me.getEvent());
};

/**
 * Function: getCellForEvent
 * 
 * Returns the cell for the given event.
 */
mxConstraintHandler.prototype.getCellForEvent = function(me, point)
{
	var cell = me.getCell();
	
	// Gets cell under actual point if different from event location
	if (cell == null && point != null && (me.getGraphX() != point.x || me.getGraphY() != point.y))
	{
		cell = this.graph.getCellAt(point.x, point.y);
	}
	
	// Uses connectable parent vertex if one exists
	if (cell != null && !this.graph.isCellConnectable(cell))
	{
		var parent = this.graph.getModel().getParent(cell);
		
		if (this.graph.getModel().isVertex(parent) && this.graph.isCellConnectable(parent))
		{
			cell = parent;
		}
	}
	
	return cell;
};

/**
 * Function: update
 * 
 * Updates the state of this handler based on the given <mxMouseEvent>.
 * Source is a boolean indicating if the cell is a source or target.
 */
mxConstraintHandler.prototype.update = function(me, source, existingEdge, point)
{
	if (this.isEnabled() && !this.isEventIgnored(me))
	{
		// Lazy installation of mouseleave handler
		if (this.mouseleaveHandler == null && this.graph.container != null)
		{
			this.mouseleaveHandler = mxUtils.bind(this, function()
			{
				this.reset();
			});

			mxEvent.addListener(this.graph.container, 'mouseleave', this.resetHandler);	
		}
		
		var tol = this.getTolerance(me);
		var x = (point != null) ? point.x : me.getGraphX();
		var y = (point != null) ? point.y : me.getGraphY();
		var grid = new mxRectangle(x - tol, y - tol, 2 * tol, 2 * tol);
		var mouse = new mxRectangle(me.getGraphX() - tol, me.getGraphY() - tol, 2 * tol, 2 * tol);
		var state = this.graph.view.getState(this.getCellForEvent(me, point));

		// Keeps focus icons visible while over vertex bounds and no other cell under mouse or shift is pressed
		if (!this.isKeepFocusEvent(me) && (this.currentFocusArea == null || this.currentFocus == null ||
			(state != null) || !this.graph.getModel().isVertex(this.currentFocus.cell) ||
			!mxUtils.intersects(this.currentFocusArea, mouse)) && (state != this.currentFocus))
		{
			this.currentFocusArea = null;
			this.currentFocus = null;
			this.setFocus(me, state, source);
		}

		this.currentConstraint = null;
		this.currentPoint = null;
		var minDistSq = null;
		
		if (this.focusIcons != null && this.constraints != null &&
			(state == null || this.currentFocus == state))
		{
			var cx = mouse.getCenterX();
			var cy = mouse.getCenterY();
			
			for (var i = 0; i < this.focusIcons.length; i++)
			{
				var dx = cx - this.focusIcons[i].bounds.getCenterX();
				var dy = cy - this.focusIcons[i].bounds.getCenterY();
				var tmp = dx * dx + dy * dy;
				
				if ((this.intersects(this.focusIcons[i], mouse, source, existingEdge) || (point != null &&
					this.intersects(this.focusIcons[i], grid, source, existingEdge))) &&
					(minDistSq == null || tmp < minDistSq))
				{
					this.currentConstraint = this.constraints[i];
					this.currentPoint = this.focusPoints[i];
					minDistSq = tmp;
					
					var tmp = this.focusIcons[i].bounds.clone();
					tmp.grow(mxConstants.HIGHLIGHT_SIZE);
					
					if (mxClient.IS_IE)
					{
						tmp.grow(1);
						tmp.width -= 1;
						tmp.height -= 1;
					}
					
					if (this.focusHighlight == null)
					{
						var hl = this.createHighlightShape();
						hl.dialect = (this.graph.dialect == mxConstants.DIALECT_SVG) ?
								mxConstants.DIALECT_SVG : mxConstants.DIALECT_VML;
						hl.pointerEvents = false;

						hl.init(this.graph.getView().getOverlayPane());
						this.focusHighlight = hl;
						
						var getState = mxUtils.bind(this, function()
						{
							return (this.currentFocus != null) ? this.currentFocus : state;
						});
	
						mxEvent.redirectMouseEvents(hl.node, this.graph, getState);
					}

					this.focusHighlight.bounds = tmp;
					this.focusHighlight.redraw();
				}
			}
		}
		
		if (this.currentConstraint == null)
		{
			this.destroyFocusHighlight();
		}
	}
	else
	{
		this.currentConstraint = null;
		this.currentFocus = null;
		this.currentPoint = null;
	}
};

/**
 * Function: redraw
 * 
 * Transfers the focus to the given state as a source or target terminal. If
 * the handler is not enabled then the outline is painted, but the constraints
 * are ignored.
 */
mxConstraintHandler.prototype.redraw = function()
{
	if (this.currentFocus != null && this.constraints != null && this.focusIcons != null)
	{
		var state = this.graph.view.getState(this.currentFocus.cell);
		this.currentFocus = state;
		this.currentFocusArea = new mxRectangle(state.x, state.y, state.width, state.height);
		
		for (var i = 0; i < this.constraints.length; i++)
		{
			var cp = this.graph.getConnectionPoint(state, this.constraints[i]);
			var img = this.getImageForConstraint(state, this.constraints[i], cp);

			var bounds = new mxRectangle(Math.round(cp.x - img.width / 2),
				Math.round(cp.y - img.height / 2), img.width, img.height);
			this.focusIcons[i].bounds = bounds;
			this.focusIcons[i].redraw();
			this.currentFocusArea.add(this.focusIcons[i].bounds);
			this.focusPoints[i] = cp;
		}
	}	
};

/**
 * Function: setFocus
 * 
 * Transfers the focus to the given state as a source or target terminal. If
 * the handler is not enabled then the outline is painted, but the constraints
 * are ignored.
 */
mxConstraintHandler.prototype.setFocus = function(me, state, source)
{
	this.constraints = (state != null && !this.isStateIgnored(state, source) &&
		this.graph.isCellConnectable(state.cell)) ? ((this.isEnabled()) ?
		(this.graph.getAllConnectionConstraints(state, source) || []) : []) : null;

	// Only uses cells which have constraints
	if (this.constraints != null)
	{
		this.currentFocus = state;
		this.currentFocusArea = new mxRectangle(state.x, state.y, state.width, state.height);
		
		if (this.focusIcons != null)
		{
			for (var i = 0; i < this.focusIcons.length; i++)
			{
				this.focusIcons[i].destroy();
			}
			
			this.focusIcons = null;
			this.focusPoints = null;
		}
		
		this.focusPoints = [];
		this.focusIcons = [];
		
		for (var i = 0; i < this.constraints.length; i++)
		{
			var cp = this.graph.getConnectionPoint(state, this.constraints[i]);
			var img = this.getImageForConstraint(state, this.constraints[i], cp);

			var src = img.src;
			var bounds = new mxRectangle(Math.round(cp.x - img.width / 2),
				Math.round(cp.y - img.height / 2), img.width, img.height);
			var icon = new mxImageShape(bounds, src);
			icon.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
					mxConstants.DIALECT_MIXEDHTML : mxConstants.DIALECT_SVG;
			icon.preserveImageAspect = false;
			icon.init(this.graph.getView().getDecoratorPane());
			
			// Fixes lost event tracking for images in quirks / IE8 standards
			if (mxClient.IS_QUIRKS || document.documentMode == 8)
			{
				mxEvent.addListener(icon.node, 'dragstart', function(evt)
				{
					mxEvent.consume(evt);
					
					return false;
				});
			}
			
			// Move the icon behind all other overlays
			if (icon.node.previousSibling != null)
			{
				icon.node.parentNode.insertBefore(icon.node, icon.node.parentNode.firstChild);
			}

			var getState = mxUtils.bind(this, function()
			{
				return (this.currentFocus != null) ? this.currentFocus : state;
			});
			
			icon.redraw();

			mxEvent.redirectMouseEvents(icon.node, this.graph, getState);
			this.currentFocusArea.add(icon.bounds);
			this.focusIcons.push(icon);
			this.focusPoints.push(cp);
		}
		
		this.currentFocusArea.grow(this.getTolerance(me));
	}
	else
	{
		this.destroyIcons();
		this.destroyFocusHighlight();
	}
};

/**
 * Function: createHighlightShape
 * 
 * Create the shape used to paint the highlight.
 * 
 * Returns true if the given icon intersects the given point.
 */
mxConstraintHandler.prototype.createHighlightShape = function()
{
	var hl = new mxRectangleShape(null, this.highlightColor, this.highlightColor, mxConstants.HIGHLIGHT_STROKEWIDTH);
	hl.opacity = mxConstants.HIGHLIGHT_OPACITY;
	
	return hl;
};

/**
 * Function: intersects
 * 
 * Returns true if the given icon intersects the given rectangle.
 */
mxConstraintHandler.prototype.intersects = function(icon, mouse, source, existingEdge)
{
	return mxUtils.intersects(icon.bounds, mouse);
};

/**
 * Function: destroy
 * 
 * Destroy this handler.
 */
mxConstraintHandler.prototype.destroy = function()
{
	this.reset();
	
	if (this.resetHandler != null)
	{
		this.graph.model.removeListener(this.resetHandler);
		this.graph.view.removeListener(this.resetHandler);
		this.graph.removeListener(this.resetHandler);
		this.resetHandler = null;
	}
	
	if (this.mouseleaveHandler != null && this.graph.container != null)
	{
		mxEvent.removeListener(this.graph.container, 'mouseleave', this.mouseleaveHandler);
		this.mouseleaveHandler = null;
	}
};
/**
 * Copyright (c) 2006-2016, JGraph Ltd
 * Copyright (c) 2006-2016, Gaudenz Alder
 */
/**
 * Class: mxRubberband
 * 
 * Event handler that selects rectangular regions. This is not built-into
 * <mxGraph>. To enable rubberband selection in a graph, use the following code.
 * 
 * Example:
 * 
 * (code)
 * var rubberband = new mxRubberband(graph);
 * (end)
 * 
 * Constructor: mxRubberband
 * 
 * Constructs an event handler that selects rectangular regions in the graph
 * using rubberband selection.
 */
function mxRubberband(graph)
{
	if (graph != null)
	{
		this.graph = graph;
		this.graph.addMouseListener(this);

		// Handles force rubberband event
		this.forceRubberbandHandler = mxUtils.bind(this, function(sender, evt)
		{
			var evtName = evt.getProperty('eventName');
			var me = evt.getProperty('event');
			
			if (evtName == mxEvent.MOUSE_DOWN && this.isForceRubberbandEvent(me))
			{
				var offset = mxUtils.getOffset(this.graph.container);
				var origin = mxUtils.getScrollOrigin(this.graph.container);
				origin.x -= offset.x;
				origin.y -= offset.y;
				this.start(me.getX() + origin.x, me.getY() + origin.y);
				me.consume(false);
			}
		});
		
		this.graph.addListener(mxEvent.FIRE_MOUSE_EVENT, this.forceRubberbandHandler);
		
		// Repaints the marquee after autoscroll
		this.panHandler = mxUtils.bind(this, function()
		{
			this.repaint();
		});
		
		this.graph.addListener(mxEvent.PAN, this.panHandler);
		
		// Does not show menu if any touch gestures take place after the trigger
		this.gestureHandler = mxUtils.bind(this, function(sender, eo)
		{
			if (this.first != null)
			{
				this.reset();
			}
		});
		
		this.graph.addListener(mxEvent.GESTURE, this.gestureHandler);
		
		// Automatic deallocation of memory
		if (mxClient.IS_IE)
		{
			mxEvent.addListener(window, 'unload',
				mxUtils.bind(this, function()
				{
					this.destroy();
				})
			);
		}
	}
};

/**
 * Variable: defaultOpacity
 * 
 * Specifies the default opacity to be used for the rubberband div. Default
 * is 20.
 */
mxRubberband.prototype.defaultOpacity = 20;

/**
 * Variable: enabled
 * 
 * Specifies if events are handled. Default is true.
 */
mxRubberband.prototype.enabled = true;

/**
 * Variable: div
 * 
 * Holds the DIV element which is currently visible.
 */
mxRubberband.prototype.div = null;

/**
 * Variable: sharedDiv
 * 
 * Holds the DIV element which is used to display the rubberband.
 */
mxRubberband.prototype.sharedDiv = null;

/**
 * Variable: currentX
 * 
 * Holds the value of the x argument in the last call to <update>.
 */
mxRubberband.prototype.currentX = 0;

/**
 * Variable: currentY
 * 
 * Holds the value of the y argument in the last call to <update>.
 */
mxRubberband.prototype.currentY = 0;

/**
 * Function: isEnabled
 * 
 * Returns true if events are handled. This implementation returns
 * <enabled>.
 */
mxRubberband.prototype.isEnabled = function()
{
	return this.enabled;
};
		
/**
 * Function: setEnabled
 * 
 * Enables or disables event handling. This implementation updates
 * <enabled>.
 */
mxRubberband.prototype.setEnabled = function(enabled)
{
	this.enabled = enabled;
};

/**
 * Function: isForceRubberbandEvent
 * 
 * Returns true if the given <mxMouseEvent> should start rubberband selection.
 * This implementation returns true if the alt key is pressed.
 */
mxRubberband.prototype.isForceRubberbandEvent = function(me)
{
	return mxEvent.isAltDown(me.getEvent());
};

/**
 * Function: mouseDown
 * 
 * Handles the event by initiating a rubberband selection. By consuming the
 * event all subsequent events of the gesture are redirected to this
 * handler.
 */
mxRubberband.prototype.mouseDown = function(sender, me)
{
	if (!me.isConsumed() && this.isEnabled() && this.graph.isEnabled() &&
		me.getState() == null && !mxEvent.isMultiTouchEvent(me.getEvent()))
	{
		var offset = mxUtils.getOffset(this.graph.container);
		var origin = mxUtils.getScrollOrigin(this.graph.container);
		origin.x -= offset.x;
		origin.y -= offset.y;
		this.start(me.getX() + origin.x, me.getY() + origin.y);

		// Does not prevent the default for this event so that the
		// event processing chain is still executed even if we start
		// rubberbanding. This is required eg. in ExtJs to hide the
		// current context menu. In mouseMove we'll make sure we're
		// not selecting anything while we're rubberbanding.
		me.consume(false);
	}
};

/**
 * Function: start
 * 
 * Sets the start point for the rubberband selection.
 */
mxRubberband.prototype.start = function(x, y)
{
	this.first = new mxPoint(x, y);

	var container = this.graph.container;
	
	function createMouseEvent(evt)
	{
		var me = new mxMouseEvent(evt);
		var pt = mxUtils.convertPoint(container, me.getX(), me.getY());
		
		me.graphX = pt.x;
		me.graphY = pt.y;
		
		return me;
	};

	this.dragHandler = mxUtils.bind(this, function(evt)
	{
		this.mouseMove(this.graph, createMouseEvent(evt));
	});

	this.dropHandler = mxUtils.bind(this, function(evt)
	{
		this.mouseUp(this.graph, createMouseEvent(evt));
	});

	// Workaround for rubberband stopping if the mouse leaves the container in Firefox
	if (mxClient.IS_FF)
	{
		mxEvent.addGestureListeners(document, null, this.dragHandler, this.dropHandler);
	}
};

/**
 * Function: mouseMove
 * 
 * Handles the event by updating therubberband selection.
 */
mxRubberband.prototype.mouseMove = function(sender, me)
{
	if (!me.isConsumed() && this.first != null)
	{
		var origin = mxUtils.getScrollOrigin(this.graph.container);
		var offset = mxUtils.getOffset(this.graph.container);
		origin.x -= offset.x;
		origin.y -= offset.y;
		var x = me.getX() + origin.x;
		var y = me.getY() + origin.y;
		var dx = this.first.x - x;
		var dy = this.first.y - y;
		var tol = this.graph.tolerance;
		
		if (this.div != null || Math.abs(dx) > tol ||  Math.abs(dy) > tol)
		{
			if (this.div == null)
			{
				this.div = this.createShape();
			}
			
			// Clears selection while rubberbanding. This is required because
			// the event is not consumed in mouseDown.
			mxUtils.clearSelection();
			
			this.update(x, y);
			me.consume();
		}
	}
};

/**
 * Function: createShape
 * 
 * Creates the rubberband selection shape.
 */
mxRubberband.prototype.createShape = function()
{
	if (this.sharedDiv == null)
	{
		this.sharedDiv = document.createElement('div');
		this.sharedDiv.className = 'mxRubberband';
		mxUtils.setOpacity(this.sharedDiv, this.defaultOpacity);
	}

	this.graph.container.appendChild(this.sharedDiv);
		
	return this.sharedDiv;
};

/**
 * Function: isActive
 * 
 * Returns true if this handler is active.
 */
mxRubberband.prototype.isActive = function(sender, me)
{
	return this.div != null && this.div.style.display != 'none';
};

/**
 * Function: mouseUp
 * 
 * Handles the event by selecting the region of the rubberband using
 * <mxGraph.selectRegion>.
 */
mxRubberband.prototype.mouseUp = function(sender, me)
{
	var active = this.isActive();
	this.reset();
	
	if (active)
	{
		this.execute(me.getEvent());
		me.consume();
	}
};

/**
 * Function: execute
 * 
 * Resets the state of this handler and selects the current region
 * for the given event.
 */
mxRubberband.prototype.execute = function(evt)
{
	var rect = new mxRectangle(this.x, this.y, this.width, this.height);
	this.graph.selectRegion(rect, evt);
};

/**
 * Function: reset
 * 
 * Resets the state of the rubberband selection.
 */
mxRubberband.prototype.reset = function()
{
	if (this.div != null)
	{
		this.div.parentNode.removeChild(this.div);
	}

	mxEvent.removeGestureListeners(document, null, this.dragHandler, this.dropHandler);
	this.dragHandler = null;
	this.dropHandler = null;
	
	this.currentX = 0;
	this.currentY = 0;
	this.first = null;
	this.div = null;
};

/**
 * Function: update
 * 
 * Sets <currentX> and <currentY> and calls <repaint>.
 */
mxRubberband.prototype.update = function(x, y)
{
	this.currentX = x;
	this.currentY = y;
	
	this.repaint();
};

/**
 * Function: repaint
 * 
 * Computes the bounding box and updates the style of the <div>.
 */
mxRubberband.prototype.repaint = function()
{
	if (this.div != null)
	{
		var x = this.currentX - this.graph.panDx;
		var y = this.currentY - this.graph.panDy;
		
		this.x = Math.min(this.first.x, x);
		this.y = Math.min(this.first.y, y);
		this.width = Math.max(this.first.x, x) - this.x;
		this.height =  Math.max(this.first.y, y) - this.y;

		var dx = (mxClient.IS_VML) ? this.graph.panDx : 0;
		var dy = (mxClient.IS_VML) ? this.graph.panDy : 0;
		
		this.div.style.left = (this.x + dx) + 'px';
		this.div.style.top = (this.y + dy) + 'px';
		this.div.style.width = Math.max(1, this.width) + 'px';
		this.div.style.height = Math.max(1, this.height) + 'px';
	}
};

/**
 * Function: destroy
 * 
 * Destroys the handler and all its resources and DOM nodes. This does
 * normally not need to be called, it is called automatically when the
 * window unloads.
 */
mxRubberband.prototype.destroy = function()
{
	if (!this.destroyed)
	{
		this.destroyed = true;
		this.graph.removeMouseListener(this);
		this.graph.removeListener(this.forceRubberbandHandler);
		this.graph.removeListener(this.panHandler);
		this.reset();
		
		if (this.sharedDiv != null)
		{
			this.sharedDiv = null;
		}
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxHandle
 * 
 * Implements a single custom handle for vertices.
 * 
 * Constructor: mxHandle
 * 
 * Constructs a new handle for the given state.
 * 
 * Parameters:
 * 
 * state - <mxCellState> of the cell to be handled.
 */
function mxHandle(state, cursor, image)
{
	this.graph = state.view.graph;
	this.state = state;
	this.cursor = (cursor != null) ? cursor : this.cursor;
	this.image = (image != null) ? image : this.image;
	this.init();
};

/**
 * Variable: cursor
 * 
 * Specifies the cursor to be used for this handle. Default is 'default'.
 */
mxHandle.prototype.cursor = 'default';

/**
 * Variable: image
 * 
 * Specifies the <mxImage> to be used to render the handle. Default is null.
 */
mxHandle.prototype.image = null;

/**
 * Variable: image
 * 
 * Specifies the <mxImage> to be used to render the handle. Default is null.
 */
mxHandle.prototype.ignoreGrid = false;

/**
 * Function: getPosition
 * 
 * Hook for subclassers to return the current position of the handle.
 */
mxHandle.prototype.getPosition = function(bounds) { };

/**
 * Function: setPosition
 * 
 * Hooks for subclassers to update the style in the <state>.
 */
mxHandle.prototype.setPosition = function(bounds, pt, me) { };

/**
 * Function: execute
 * 
 * Hook for subclassers to execute the handle.
 */
mxHandle.prototype.execute = function() { };

/**
 * Function: copyStyle
 * 
 * Sets the cell style with the given name to the corresponding value in <state>.
 */
mxHandle.prototype.copyStyle = function(key)
{
	this.graph.setCellStyles(key, this.state.style[key], [this.state.cell]);
};

/**
 * Function: processEvent
 * 
 * Processes the given <mxMouseEvent> and invokes <setPosition>.
 */
mxHandle.prototype.processEvent = function(me)
{
	var scale = this.graph.view.scale;
	var tr = this.graph.view.translate;
	var pt = new mxPoint(me.getGraphX() / scale - tr.x, me.getGraphY() / scale - tr.y);
	
	// Center shape on mouse cursor
	if (this.shape != null && this.shape.bounds != null)
	{
		pt.x -= this.shape.bounds.width / scale / 4;
		pt.y -= this.shape.bounds.height / scale / 4;
	}

	// Snaps to grid for the rotated position then applies the rotation for the direction after that
	var alpha1 = -mxUtils.toRadians(this.getRotation());
	var alpha2 = -mxUtils.toRadians(this.getTotalRotation()) - alpha1;
	pt = this.flipPoint(this.rotatePoint(this.snapPoint(this.rotatePoint(pt, alpha1),
			this.ignoreGrid || !this.graph.isGridEnabledEvent(me.getEvent())), alpha2));
	this.setPosition(this.state.getPaintBounds(), pt, me);
	this.positionChanged();
	this.redraw();
};

/**
 * Function: positionChanged
 * 
 * Called after <setPosition> has been called in <processEvent>. This repaints
 * the state using <mxCellRenderer>.
 */
mxHandle.prototype.positionChanged = function()
{
	if (this.state.text != null)
	{
		this.state.text.apply(this.state);
	}
	
	if (this.state.shape != null)
	{
		this.state.shape.apply(this.state);
	}
	
	// Needed to force update of text bounds
	this.state.unscaledWidth = null;
	this.graph.cellRenderer.redraw(this.state, true);
};

/**
 * Function: getRotation
 * 
 * Returns the rotation defined in the style of the cell.
 */
mxHandle.prototype.getRotation = function()
{
	if (this.state.shape != null)
	{
		return this.state.shape.getRotation();
	}
	
	return 0;
};

/**
 * Function: getTotalRotation
 * 
 * Returns the rotation from the style and the rotation from the direction of
 * the cell.
 */
mxHandle.prototype.getTotalRotation = function()
{
	if (this.state.shape != null)
	{
		return this.state.shape.getShapeRotation();
	}
	
	return 0;
};

/**
 * Function: init
 * 
 * Creates and initializes the shapes required for this handle.
 */
mxHandle.prototype.init = function()
{
	var html = this.isHtmlRequired();
	
	if (this.image != null)
	{
		this.shape = new mxImageShape(new mxRectangle(0, 0, this.image.width, this.image.height), this.image.src);
		this.shape.preserveImageAspect = false;
	}
	else
	{
		this.shape = this.createShape(html);
	}
	
	this.initShape(html);
};

/**
 * Function: createShape
 * 
 * Creates and returns the shape for this handle.
 */
mxHandle.prototype.createShape = function(html)
{
	var bounds = new mxRectangle(0, 0, mxConstants.HANDLE_SIZE, mxConstants.HANDLE_SIZE);
	
	return new mxRectangleShape(bounds, mxConstants.HANDLE_FILLCOLOR, mxConstants.HANDLE_STROKECOLOR);
};

/**
 * Function: initShape
 * 
 * Initializes <shape> and sets its cursor.
 */
mxHandle.prototype.initShape = function(html)
{
	if (html && this.shape.isHtmlAllowed())
	{
		this.shape.dialect = mxConstants.DIALECT_STRICTHTML;
		this.shape.init(this.graph.container);
	}
	else
	{
		this.shape.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ? mxConstants.DIALECT_MIXEDHTML : mxConstants.DIALECT_SVG;
		
		if (this.cursor != null)
		{
			this.shape.init(this.graph.getView().getOverlayPane());
		}
	}

	mxEvent.redirectMouseEvents(this.shape.node, this.graph, this.state);
	this.shape.node.style.cursor = this.cursor;
};

/**
 * Function: redraw
 * 
 * Renders the shape for this handle.
 */
mxHandle.prototype.redraw = function()
{
	if (this.shape != null && this.state.shape != null)
	{
		var pt = this.getPosition(this.state.getPaintBounds());
		
		if (pt != null)
		{
			var alpha = mxUtils.toRadians(this.getTotalRotation());
			pt = this.rotatePoint(this.flipPoint(pt), alpha);
	
			var scale = this.graph.view.scale;
			var tr = this.graph.view.translate;
			this.shape.bounds.x = Math.floor((pt.x + tr.x) * scale - this.shape.bounds.width / 2);
			this.shape.bounds.y = Math.floor((pt.y + tr.y) * scale - this.shape.bounds.height / 2);
			
			// Needed to force update of text bounds
			this.shape.redraw();
		}
	}
};

/**
 * Function: isHtmlRequired
 * 
 * Returns true if this handle should be rendered in HTML. This returns true if
 * the text node is in the graph container.
 */
mxHandle.prototype.isHtmlRequired = function()
{
	return this.state.text != null && this.state.text.node.parentNode == this.graph.container;
};

/**
 * Function: rotatePoint
 * 
 * Rotates the point by the given angle.
 */
mxHandle.prototype.rotatePoint = function(pt, alpha)
{
	var bounds = this.state.getCellBounds();
	var cx = new mxPoint(bounds.getCenterX(), bounds.getCenterY());
	var cos = Math.cos(alpha);
	var sin = Math.sin(alpha); 

	return mxUtils.getRotatedPoint(pt, cos, sin, cx);
};

/**
 * Function: flipPoint
 * 
 * Flips the given point vertically and/or horizontally.
 */
mxHandle.prototype.flipPoint = function(pt)
{
	if (this.state.shape != null)
	{
		var bounds = this.state.getCellBounds();
		
		if (this.state.shape.flipH)
		{
			pt.x = 2 * bounds.x + bounds.width - pt.x;
		}
		
		if (this.state.shape.flipV)
		{
			pt.y = 2 * bounds.y + bounds.height - pt.y;
		}
	}
	
	return pt;
};

/**
 * Function: snapPoint
 * 
 * Snaps the given point to the grid if ignore is false. This modifies
 * the given point in-place and also returns it.
 */
mxHandle.prototype.snapPoint = function(pt, ignore)
{
	if (!ignore)
	{
		pt.x = this.graph.snap(pt.x);
		pt.y = this.graph.snap(pt.y);
	}
	
	return pt;
};

/**
 * Function: setVisible
 * 
 * Shows or hides this handle.
 */
mxHandle.prototype.setVisible = function(visible)
{
	if (this.shape != null && this.shape.node != null)
	{
		this.shape.node.style.display = (visible) ? '' : 'none';
	}
};

/**
 * Function: reset
 * 
 * Resets the state of this handle by setting its visibility to true.
 */
mxHandle.prototype.reset = function()
{
	this.setVisible(true);
	this.state.style = this.graph.getCellStyle(this.state.cell);
	this.positionChanged();
};

/**
 * Function: destroy
 * 
 * Destroys this handle.
 */
mxHandle.prototype.destroy = function()
{
	if (this.shape != null)
	{
		this.shape.destroy();
		this.shape = null;
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxVertexHandler
 * 
 * Event handler for resizing cells. This handler is automatically created in
 * <mxGraph.createHandler>.
 * 
 * Constructor: mxVertexHandler
 * 
 * Constructs an event handler that allows to resize vertices
 * and groups.
 * 
 * Parameters:
 * 
 * state - <mxCellState> of the cell to be resized.
 */
function mxVertexHandler(state)
{
	if (state != null)
	{
		this.state = state;
		this.init();
		
		// Handles escape keystrokes
		this.escapeHandler = mxUtils.bind(this, function(sender, evt)
		{
			if (this.livePreview && this.index != null)
			{
				// Redraws the live preview
				this.state.view.graph.cellRenderer.redraw(this.state, true);
				
				// Redraws connected edges
				this.state.view.invalidate(this.state.cell);
				this.state.invalid = false;
				this.state.view.validate();
			}
			
			this.reset();
		});
		
		this.state.view.graph.addListener(mxEvent.ESCAPE, this.escapeHandler);
	}
};

/**
 * Variable: graph
 * 
 * Reference to the enclosing <mxGraph>.
 */
mxVertexHandler.prototype.graph = null;

/**
 * Variable: state
 * 
 * Reference to the <mxCellState> being modified.
 */
mxVertexHandler.prototype.state = null;

/**
 * Variable: singleSizer
 * 
 * Specifies if only one sizer handle at the bottom, right corner should be
 * used. Default is false.
 */
mxVertexHandler.prototype.singleSizer = false;

/**
 * Variable: index
 * 
 * Holds the index of the current handle.
 */
mxVertexHandler.prototype.index = null;

/**
 * Variable: allowHandleBoundsCheck
 * 
 * Specifies if the bounds of handles should be used for hit-detection in IE or
 * if <tolerance> > 0. Default is true.
 */
mxVertexHandler.prototype.allowHandleBoundsCheck = true;

/**
 * Variable: handleImage
 * 
 * Optional <mxImage> to be used as handles. Default is null.
 */
mxVertexHandler.prototype.handleImage = null;

/**
 * Variable: tolerance
 * 
 * Optional tolerance for hit-detection in <getHandleForEvent>. Default is 0.
 */
mxVertexHandler.prototype.tolerance = 0;

/**
 * Variable: rotationEnabled
 * 
 * Specifies if a rotation handle should be visible. Default is false.
 */
mxVertexHandler.prototype.rotationEnabled = false;

/**
 * Variable: parentHighlightEnabled
 * 
 * Specifies if the parent should be highlighted if a child cell is selected.
 * Default is false.
 */
mxVertexHandler.prototype.parentHighlightEnabled = false;

/**
 * Variable: rotationRaster
 * 
 * Specifies if rotation steps should be "rasterized" depening on the distance
 * to the handle. Default is true.
 */
mxVertexHandler.prototype.rotationRaster = true;

/**
 * Variable: rotationCursor
 * 
 * Specifies the cursor for the rotation handle. Default is 'crosshair'.
 */
mxVertexHandler.prototype.rotationCursor = 'crosshair';

/**
 * Variable: livePreview
 * 
 * Specifies if resize should change the cell in-place. This is an experimental
 * feature for non-touch devices. Default is false.
 */
mxVertexHandler.prototype.livePreview = false;

/**
 * Variable: manageSizers
 * 
 * Specifies if sizers should be hidden and spaced if the vertex is small.
 * Default is false.
 */
mxVertexHandler.prototype.manageSizers = false;

/**
 * Variable: constrainGroupByChildren
 * 
 * Specifies if the size of groups should be constrained by the children.
 * Default is false.
 */
mxVertexHandler.prototype.constrainGroupByChildren = false;

/**
 * Variable: rotationHandleVSpacing
 * 
 * Vertical spacing for rotation icon. Default is -16.
 */
mxVertexHandler.prototype.rotationHandleVSpacing = -16;

/**
 * Variable: horizontalOffset
 * 
 * The horizontal offset for the handles. This is updated in <redrawHandles>
 * if <manageSizers> is true and the sizers are offset horizontally.
 */
mxVertexHandler.prototype.horizontalOffset = 0;

/**
 * Variable: verticalOffset
 * 
 * The horizontal offset for the handles. This is updated in <redrawHandles>
 * if <manageSizers> is true and the sizers are offset vertically.
 */
mxVertexHandler.prototype.verticalOffset = 0;

/**
 * Function: init
 * 
 * Initializes the shapes required for this vertex handler.
 */
mxVertexHandler.prototype.init = function()
{
	this.graph = this.state.view.graph;
	this.selectionBounds = this.getSelectionBounds(this.state);
	this.bounds = new mxRectangle(this.selectionBounds.x, this.selectionBounds.y, this.selectionBounds.width, this.selectionBounds.height);
	this.selectionBorder = this.createSelectionShape(this.bounds);
	// VML dialect required here for event transparency in IE
	this.selectionBorder.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ? mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
	this.selectionBorder.pointerEvents = false;
	this.selectionBorder.rotation = Number(this.state.style[mxConstants.STYLE_ROTATION] || '0');
	this.selectionBorder.init(this.graph.getView().getOverlayPane());
	mxEvent.redirectMouseEvents(this.selectionBorder.node, this.graph, this.state);
	
	if (this.graph.isCellMovable(this.state.cell))
	{
		this.selectionBorder.setCursor(mxConstants.CURSOR_MOVABLE_VERTEX);
	}

	// Adds the sizer handles
	if (mxGraphHandler.prototype.maxCells <= 0 || this.graph.getSelectionCount() < mxGraphHandler.prototype.maxCells)
	{
		var resizable = this.graph.isCellResizable(this.state.cell);
		this.sizers = [];

		if (resizable || (this.graph.isLabelMovable(this.state.cell) &&
			this.state.width >= 2 && this.state.height >= 2))
		{
			var i = 0;

			if (resizable)
			{
				if (!this.singleSizer)
				{
					this.sizers.push(this.createSizer('nw-resize', i++));
					this.sizers.push(this.createSizer('n-resize', i++));
					this.sizers.push(this.createSizer('ne-resize', i++));
					this.sizers.push(this.createSizer('w-resize', i++));
					this.sizers.push(this.createSizer('e-resize', i++));
					this.sizers.push(this.createSizer('sw-resize', i++));
					this.sizers.push(this.createSizer('s-resize', i++));
				}
				
				this.sizers.push(this.createSizer('se-resize', i++));
			}
			
			var geo = this.graph.model.getGeometry(this.state.cell);
			
			if (geo != null && !geo.relative && !this.graph.isSwimlane(this.state.cell) &&
				this.graph.isLabelMovable(this.state.cell))
			{
				// Marks this as the label handle for getHandleForEvent
				this.labelShape = this.createSizer(mxConstants.CURSOR_LABEL_HANDLE, mxEvent.LABEL_HANDLE, mxConstants.LABEL_HANDLE_SIZE, mxConstants.LABEL_HANDLE_FILLCOLOR);
				this.sizers.push(this.labelShape);
			}
		}
		else if (this.graph.isCellMovable(this.state.cell) && !this.graph.isCellResizable(this.state.cell) &&
			this.state.width < 2 && this.state.height < 2)
		{
			this.labelShape = this.createSizer(mxConstants.CURSOR_MOVABLE_VERTEX,
				mxEvent.LABEL_HANDLE, null, mxConstants.LABEL_HANDLE_FILLCOLOR);
			this.sizers.push(this.labelShape);
		}
	}
	
	// Adds the rotation handler
	if (this.isRotationHandleVisible())
	{
		this.rotationShape = this.createSizer(this.rotationCursor, mxEvent.ROTATION_HANDLE,
			mxConstants.HANDLE_SIZE + 3, mxConstants.HANDLE_FILLCOLOR);
		this.sizers.push(this.rotationShape);
	}

	this.customHandles = this.createCustomHandles();
	this.redraw();
	
	if (this.constrainGroupByChildren)
	{
		this.updateMinBounds();
	}
};

/**
 * Function: isRotationHandleVisible
 * 
 * Returns true if the rotation handle should be showing.
 */
mxVertexHandler.prototype.isRotationHandleVisible = function()
{
	return this.graph.isEnabled() && this.rotationEnabled && this.graph.isCellRotatable(this.state.cell) &&
		(mxGraphHandler.prototype.maxCells <= 0 || this.graph.getSelectionCount() < mxGraphHandler.prototype.maxCells) &&
		this.state.width >= 2 && this.state.height >= 2;
};

/**
 * Function: isConstrainedEvent
 * 
 * Returns true if the aspect ratio if the cell should be maintained.
 */
mxVertexHandler.prototype.isConstrainedEvent = function(me)
{
	return mxEvent.isShiftDown(me.getEvent()) || this.state.style[mxConstants.STYLE_ASPECT] == 'fixed';
};

/**
 * Function: isCenteredEvent
 * 
 * Returns true if the center of the vertex should be maintained during the resize.
 */
mxVertexHandler.prototype.isCenteredEvent = function(state, me)
{
	return false;
};

/**
 * Function: createCustomHandles
 * 
 * Returns an array of custom handles. This implementation returns null.
 */
mxVertexHandler.prototype.createCustomHandles = function()
{
	return null;
};

/**
 * Function: updateMinBounds
 * 
 * Initializes the shapes required for this vertex handler.
 */
mxVertexHandler.prototype.updateMinBounds = function()
{
	var children = this.graph.getChildCells(this.state.cell);
	
	if (children.length > 0)
	{
		this.minBounds = this.graph.view.getBounds(children);
		
		if (this.minBounds != null)
		{
			var s = this.state.view.scale;
			var t = this.state.view.translate;

			this.minBounds.x -= this.state.x;
			this.minBounds.y -= this.state.y;
			this.minBounds.x /= s;
			this.minBounds.y /= s;
			this.minBounds.width /= s;
			this.minBounds.height /= s;
			this.x0 = this.state.x / s - t.x;
			this.y0 = this.state.y / s - t.y;
		}
	}
};

/**
 * Function: getSelectionBounds
 * 
 * Returns the mxRectangle that defines the bounds of the selection
 * border.
 */
mxVertexHandler.prototype.getSelectionBounds = function(state)
{
	return new mxRectangle(Math.round(state.x), Math.round(state.y), Math.round(state.width), Math.round(state.height));
};

/**
 * Function: createParentHighlightShape
 * 
 * Creates the shape used to draw the selection border.
 */
mxVertexHandler.prototype.createParentHighlightShape = function(bounds)
{
	return this.createSelectionShape(bounds);
};

/**
 * Function: createSelectionShape
 * 
 * Creates the shape used to draw the selection border.
 */
mxVertexHandler.prototype.createSelectionShape = function(bounds)
{
	var shape = new mxRectangleShape(bounds, null, this.getSelectionColor());
	shape.strokewidth = this.getSelectionStrokeWidth();
	shape.isDashed = this.isSelectionDashed();
	
	return shape;
};

/**
 * Function: getSelectionColor
 * 
 * Returns <mxConstants.VERTEX_SELECTION_COLOR>.
 */
mxVertexHandler.prototype.getSelectionColor = function()
{
	return mxConstants.VERTEX_SELECTION_COLOR;
};

/**
 * Function: getSelectionStrokeWidth
 * 
 * Returns <mxConstants.VERTEX_SELECTION_STROKEWIDTH>.
 */
mxVertexHandler.prototype.getSelectionStrokeWidth = function()
{
	return mxConstants.VERTEX_SELECTION_STROKEWIDTH;
};

/**
 * Function: isSelectionDashed
 * 
 * Returns <mxConstants.VERTEX_SELECTION_DASHED>.
 */
mxVertexHandler.prototype.isSelectionDashed = function()
{
	return mxConstants.VERTEX_SELECTION_DASHED;
};

/**
 * Function: createSizer
 * 
 * Creates a sizer handle for the specified cursor and index and returns
 * the new <mxRectangleShape> that represents the handle.
 */
mxVertexHandler.prototype.createSizer = function(cursor, index, size, fillColor)
{
	size = size || mxConstants.HANDLE_SIZE;
	
	var bounds = new mxRectangle(0, 0, size, size);
	var sizer = this.createSizerShape(bounds, index, fillColor);

	if (sizer.isHtmlAllowed() && this.state.text != null && this.state.text.node.parentNode == this.graph.container)
	{
		sizer.bounds.height -= 1;
		sizer.bounds.width -= 1;
		sizer.dialect = mxConstants.DIALECT_STRICTHTML;
		sizer.init(this.graph.container);
	}
	else
	{
		sizer.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
				mxConstants.DIALECT_MIXEDHTML : mxConstants.DIALECT_SVG;
		sizer.init(this.graph.getView().getOverlayPane());
	}

	mxEvent.redirectMouseEvents(sizer.node, this.graph, this.state);
	
	if (this.graph.isEnabled())
	{
		sizer.setCursor(cursor);
	}
	
	if (!this.isSizerVisible(index))
	{
		sizer.visible = false;
	}
	
	return sizer;
};

/**
 * Function: isSizerVisible
 * 
 * Returns true if the sizer for the given index is visible.
 * This returns true for all given indices.
 */
mxVertexHandler.prototype.isSizerVisible = function(index)
{
	return true;
};

/**
 * Function: createSizerShape
 * 
 * Creates the shape used for the sizer handle for the specified bounds an
 * index. Only images and rectangles should be returned if support for HTML
 * labels with not foreign objects is required.
 */
mxVertexHandler.prototype.createSizerShape = function(bounds, index, fillColor)
{
	if (this.handleImage != null)
	{
		bounds = new mxRectangle(bounds.x, bounds.y, this.handleImage.width, this.handleImage.height);
		var shape = new mxImageShape(bounds, this.handleImage.src);
		
		// Allows HTML rendering of the images
		shape.preserveImageAspect = false;

		return shape;
	}
	else if (index == mxEvent.ROTATION_HANDLE)
	{
		return new mxEllipse(bounds, fillColor || mxConstants.HANDLE_FILLCOLOR, mxConstants.HANDLE_STROKECOLOR);
	}
	else
	{
		return new mxRectangleShape(bounds, fillColor || mxConstants.HANDLE_FILLCOLOR, mxConstants.HANDLE_STROKECOLOR);
	}
};

/**
 * Function: createBounds
 * 
 * Helper method to create an <mxRectangle> around the given centerpoint
 * with a width and height of 2*s or 6, if no s is given.
 */
mxVertexHandler.prototype.moveSizerTo = function(shape, x, y)
{
	if (shape != null)
	{
		shape.bounds.x = Math.floor(x - shape.bounds.width / 2);
		shape.bounds.y = Math.floor(y - shape.bounds.height / 2);
		
		// Fixes visible inactive handles in VML
		if (shape.node != null && shape.node.style.display != 'none')
		{
			shape.redraw();
		}
	}
};

/**
 * Function: getHandleForEvent
 * 
 * Returns the index of the handle for the given event. This returns the index
 * of the sizer from where the event originated or <mxEvent.LABEL_INDEX>.
 */
mxVertexHandler.prototype.getHandleForEvent = function(me)
{
	// Connection highlight may consume events before they reach sizer handle
	var tol = (!mxEvent.isMouseEvent(me.getEvent())) ? this.tolerance : 1;
	var hit = (this.allowHandleBoundsCheck && (mxClient.IS_IE || tol > 0)) ?
		new mxRectangle(me.getGraphX() - tol, me.getGraphY() - tol, 2 * tol, 2 * tol) : null;
	
	function checkShape(shape)
	{
		return shape != null && (me.isSource(shape) || (hit != null && mxUtils.intersects(shape.bounds, hit) &&
			shape.node.style.display != 'none' && shape.node.style.visibility != 'hidden'));
	}

	if (this.customHandles != null && this.isCustomHandleEvent(me))
	{
		// Inverse loop order to match display order
		for (var i = this.customHandles.length - 1; i >= 0; i--)
		{
			if (checkShape(this.customHandles[i].shape))
			{
				// LATER: Return reference to active shape
				return mxEvent.CUSTOM_HANDLE - i;
			}
		}
	}

	if (checkShape(this.rotationShape))
	{
		return mxEvent.ROTATION_HANDLE;
	}
	else if (checkShape(this.labelShape))
	{
		return mxEvent.LABEL_HANDLE;
	}
	
	if (this.sizers != null)
	{
		for (var i = 0; i < this.sizers.length; i++)
		{
			if (checkShape(this.sizers[i]))
			{
				return i;
			}
		}
	}

	return null;
};

/**
 * Function: isCustomHandleEvent
 * 
 * Returns true if the given event allows custom handles to be changed. This
 * implementation returns true.
 */
mxVertexHandler.prototype.isCustomHandleEvent = function(me)
{
	return true;
};

/**
 * Function: mouseDown
 * 
 * Handles the event if a handle has been clicked. By consuming the
 * event all subsequent events of the gesture are redirected to this
 * handler.
 */
mxVertexHandler.prototype.mouseDown = function(sender, me)
{
	var tol = (!mxEvent.isMouseEvent(me.getEvent())) ? this.tolerance : 0;
	
	if (!me.isConsumed() && this.graph.isEnabled() && (tol > 0 || me.getState() == this.state))
	{
		var handle = this.getHandleForEvent(me);

		if (handle != null)
		{
			this.start(me.getGraphX(), me.getGraphY(), handle);
			me.consume();
		}
	}
};

/**
 * Function: isLivePreviewBorder
 * 
 * Called if <livePreview> is enabled to check if a border should be painted.
 * This implementation returns true if the shape is transparent.
 */
mxVertexHandler.prototype.isLivePreviewBorder = function()
{
	return this.state.shape != null && this.state.shape.fill == null && this.state.shape.stroke == null;
};

/**
 * Function: start
 * 
 * Starts the handling of the mouse gesture.
 */
mxVertexHandler.prototype.start = function(x, y, index)
{
	this.inTolerance = true;
	this.childOffsetX = 0;
	this.childOffsetY = 0;
	this.index = index;
	this.startX = x;
	this.startY = y;
	
	// Saves reference to parent state
	var model = this.state.view.graph.model;
	var parent = model.getParent(this.state.cell);
	
	if (this.state.view.currentRoot != parent && (model.isVertex(parent) || model.isEdge(parent)))
	{
		this.parentState = this.state.view.graph.view.getState(parent);
	}
	
	// Creates a preview that can be on top of any HTML label
	this.selectionBorder.node.style.display = (index == mxEvent.ROTATION_HANDLE) ? 'inline' : 'none';
	
	// Creates the border that represents the new bounds
	if (!this.livePreview || this.isLivePreviewBorder())
	{
		this.preview = this.createSelectionShape(this.bounds);
		
		if (!(mxClient.IS_SVG && Number(this.state.style[mxConstants.STYLE_ROTATION] || '0') != 0) &&
			this.state.text != null && this.state.text.node.parentNode == this.graph.container)
		{
			this.preview.dialect = mxConstants.DIALECT_STRICTHTML;
			this.preview.init(this.graph.container);
		}
		else
		{
			this.preview.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
					mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
			this.preview.init(this.graph.view.getOverlayPane());
		}
	}
	
	// Prepares the handles for live preview
	if (this.livePreview)
	{
		this.hideSizers();
		
		if (index == mxEvent.ROTATION_HANDLE)
		{
			this.rotationShape.node.style.display = '';
		}
		else if (index == mxEvent.LABEL_HANDLE)
		{
			this.labelShape.node.style.display = '';
		}
		else if (this.sizers != null && this.sizers[index] != null)
		{
			this.sizers[index].node.style.display = '';
		}
		else if (index <= mxEvent.CUSTOM_HANDLE && this.customHandles != null)
		{
			this.customHandles[mxEvent.CUSTOM_HANDLE - index].setVisible(true);
		}
		
		// Gets the array of connected edge handlers for redrawing
		var edges = this.graph.getEdges(this.state.cell);
		this.edgeHandlers = [];
		
		for (var i = 0; i < edges.length; i++)
		{
			var handler = this.graph.selectionCellsHandler.getHandler(edges[i]);
			
			if (handler != null)
			{
				this.edgeHandlers.push(handler);
			}
		}
	}
};

/**
 * Function: hideHandles
 * 
 * Shortcut to <hideSizers>.
 */
mxVertexHandler.prototype.setHandlesVisible = function(visible)
{
	if (this.sizers != null)
	{
		for (var i = 0; i < this.sizers.length; i++)
		{
			this.sizers[i].node.style.display = (visible) ? '' : 'none';
		}
	}

	if (this.customHandles != null)
	{
		for (var i = 0; i < this.customHandles.length; i++)
		{
			this.customHandles[i].setVisible(visible);
		}
	}
};

/**
 * Function: hideSizers
 * 
 * Hides all sizers except.
 * 
 * Starts the handling of the mouse gesture.
 */
mxVertexHandler.prototype.hideSizers = function()
{
	this.setHandlesVisible(false);
};

/**
 * Function: checkTolerance
 * 
 * Checks if the coordinates for the given event are within the
 * <mxGraph.tolerance>. If the event is a mouse event then the tolerance is
 * ignored.
 */
mxVertexHandler.prototype.checkTolerance = function(me)
{
	if (this.inTolerance && this.startX != null && this.startY != null)
	{
		if (mxEvent.isMouseEvent(me.getEvent()) ||
			Math.abs(me.getGraphX() - this.startX) > this.graph.tolerance ||
			Math.abs(me.getGraphY() - this.startY) > this.graph.tolerance)
		{
			this.inTolerance = false;
		}
	}
};

/**
 * Function: updateHint
 * 
 * Hook for subclassers do show details while the handler is active.
 */
mxVertexHandler.prototype.updateHint = function(me) { };

/**
 * Function: removeHint
 * 
 * Hooks for subclassers to hide details when the handler gets inactive.
 */
mxVertexHandler.prototype.removeHint = function() { };

/**
 * Function: roundAngle
 * 
 * Hook for rounding the angle. This uses Math.round.
 */
mxVertexHandler.prototype.roundAngle = function(angle)
{
	return Math.round(angle * 10) / 10;
};

/**
 * Function: roundLength
 * 
 * Hook for rounding the unscaled width or height. This uses Math.round.
 */
mxVertexHandler.prototype.roundLength = function(length)
{
	return Math.round(length);
};

/**
 * Function: mouseMove
 * 
 * Handles the event by updating the preview.
 */
mxVertexHandler.prototype.mouseMove = function(sender, me)
{
	if (!me.isConsumed() && this.index != null)
	{
		// Checks tolerance for ignoring single clicks
		this.checkTolerance(me);

		if (!this.inTolerance)
		{
			if (this.index <= mxEvent.CUSTOM_HANDLE)
			{
				if (this.customHandles != null)
				{
					this.customHandles[mxEvent.CUSTOM_HANDLE - this.index].processEvent(me);
					this.customHandles[mxEvent.CUSTOM_HANDLE - this.index].active = true;
				}
			}
			else if (this.index == mxEvent.LABEL_HANDLE)
			{
				this.moveLabel(me);
			}
			else if (this.index == mxEvent.ROTATION_HANDLE)
			{
				this.rotateVertex(me);
			}
			else
			{
				this.resizeVertex(me);
			}

			this.updateHint(me);
		}
		
		me.consume();
	}
	// Workaround for disabling the connect highlight when over handle
	else if (!this.graph.isMouseDown && this.getHandleForEvent(me) != null)
	{
		me.consume(false);
	}
};

/**
 * Function: rotateVertex
 * 
 * Rotates the vertex.
 */
mxVertexHandler.prototype.moveLabel = function(me)
{
	var point = new mxPoint(me.getGraphX(), me.getGraphY());
	var tr = this.graph.view.translate;
	var scale = this.graph.view.scale;
	
	if (this.graph.isGridEnabledEvent(me.getEvent()))
	{
		point.x = (this.graph.snap(point.x / scale - tr.x) + tr.x) * scale;
		point.y = (this.graph.snap(point.y / scale - tr.y) + tr.y) * scale;
	}

	var index = (this.rotationShape != null) ? this.sizers.length - 2 : this.sizers.length - 1;
	this.moveSizerTo(this.sizers[index], point.x, point.y);
};

/**
 * Function: rotateVertex
 * 
 * Rotates the vertex.
 */
mxVertexHandler.prototype.rotateVertex = function(me)
{
	var point = new mxPoint(me.getGraphX(), me.getGraphY());
	var dx = this.state.x + this.state.width / 2 - point.x;
	var dy = this.state.y + this.state.height / 2 - point.y;
	this.currentAlpha = (dx != 0) ? Math.atan(dy / dx) * 180 / Math.PI + 90 : ((dy < 0) ? 180 : 0);
	
	if (dx > 0)
	{
		this.currentAlpha -= 180;
	}

	// Rotation raster
	if (this.rotationRaster && this.graph.isGridEnabledEvent(me.getEvent()))
	{
		var dx = point.x - this.state.getCenterX();
		var dy = point.y - this.state.getCenterY();
		var dist = Math.abs(Math.sqrt(dx * dx + dy * dy) - 20) * 3;
		var raster = Math.max(1, 5 * Math.min(3, Math.max(0, Math.round(80 / Math.abs(dist)))));
		
		this.currentAlpha = Math.round(this.currentAlpha / raster) * raster;
	}
	else
	{
		this.currentAlpha = this.roundAngle(this.currentAlpha);
	}

	this.selectionBorder.rotation = this.currentAlpha;
	this.selectionBorder.redraw();
					
	if (this.livePreview)
	{
		this.redrawHandles();
	}
};

/**
 * Function: rotateVertex
 * 
 * Rotates the vertex.
 */
mxVertexHandler.prototype.resizeVertex = function(me)
{
	var ct = new mxPoint(this.state.getCenterX(), this.state.getCenterY());
	var alpha = mxUtils.toRadians(this.state.style[mxConstants.STYLE_ROTATION] || '0');
	var point = new mxPoint(me.getGraphX(), me.getGraphY());
	var tr = this.graph.view.translate;
	var scale = this.graph.view.scale;
	var cos = Math.cos(-alpha);
	var sin = Math.sin(-alpha);
	
	var dx = point.x - this.startX;
	var dy = point.y - this.startY;

	// Rotates vector for mouse gesture
	var tx = cos * dx - sin * dy;
	var ty = sin * dx + cos * dy;
	
	dx = tx;
	dy = ty;

	var geo = this.graph.getCellGeometry(this.state.cell);
	this.unscaledBounds = this.union(geo, dx / scale, dy / scale, this.index,
		this.graph.isGridEnabledEvent(me.getEvent()), 1,
		new mxPoint(0, 0), this.isConstrainedEvent(me),
		this.isCenteredEvent(this.state, me));
	
	// Keeps vertex within maximum graph or parent bounds
	if (!geo.relative)
	{
		var max = this.graph.getMaximumGraphBounds();
		
		// Handles child cells
		if (max != null && this.parentState != null)
		{
			max = mxRectangle.fromRectangle(max);
			
			max.x -= (this.parentState.x - tr.x * scale) / scale;
			max.y -= (this.parentState.y - tr.y * scale) / scale;
		}
		
		if (this.graph.isConstrainChild(this.state.cell))
		{
			var tmp = this.graph.getCellContainmentArea(this.state.cell);
			
			if (tmp != null)
			{
				var overlap = this.graph.getOverlap(this.state.cell);
				
				if (overlap > 0)
				{
					tmp = mxRectangle.fromRectangle(tmp);
					
					tmp.x -= tmp.width * overlap;
					tmp.y -= tmp.height * overlap;
					tmp.width += 2 * tmp.width * overlap;
					tmp.height += 2 * tmp.height * overlap;
				}
				
				if (max == null)
				{
					max = tmp;
				}
				else
				{
					max = mxRectangle.fromRectangle(max);
					max.intersect(tmp);
				}
			}
		}
	
		if (max != null)
		{
			if (this.unscaledBounds.x < max.x)
			{
				this.unscaledBounds.width -= max.x - this.unscaledBounds.x;
				this.unscaledBounds.x = max.x;
			}
			
			if (this.unscaledBounds.y < max.y)
			{
				this.unscaledBounds.height -= max.y - this.unscaledBounds.y;
				this.unscaledBounds.y = max.y;
			}
			
			if (this.unscaledBounds.x + this.unscaledBounds.width > max.x + max.width)
			{
				this.unscaledBounds.width -= this.unscaledBounds.x +
					this.unscaledBounds.width - max.x - max.width;
			}
			
			if (this.unscaledBounds.y + this.unscaledBounds.height > max.y + max.height)
			{
				this.unscaledBounds.height -= this.unscaledBounds.y +
					this.unscaledBounds.height - max.y - max.height;
			}
		}
	}
	
	this.bounds = new mxRectangle(((this.parentState != null) ? this.parentState.x : tr.x * scale) +
		(this.unscaledBounds.x) * scale, ((this.parentState != null) ? this.parentState.y : tr.y * scale) +
		(this.unscaledBounds.y) * scale, this.unscaledBounds.width * scale, this.unscaledBounds.height * scale);

	if (geo.relative && this.parentState != null)
	{
		this.bounds.x += this.state.x - this.parentState.x;
		this.bounds.y += this.state.y - this.parentState.y;
	}

	cos = Math.cos(alpha);
	sin = Math.sin(alpha);
	
	var c2 = new mxPoint(this.bounds.getCenterX(), this.bounds.getCenterY());

	var dx = c2.x - ct.x;
	var dy = c2.y - ct.y;
	
	var dx2 = cos * dx - sin * dy;
	var dy2 = sin * dx + cos * dy;
	
	var dx3 = dx2 - dx;
	var dy3 = dy2 - dy;
	
	var dx4 = this.bounds.x - this.state.x;
	var dy4 = this.bounds.y - this.state.y;
	
	var dx5 = cos * dx4 - sin * dy4;
	var dy5 = sin * dx4 + cos * dy4;
	
	this.bounds.x += dx3;
	this.bounds.y += dy3;
	
	// Rounds unscaled bounds to int
	this.unscaledBounds.x = this.roundLength(this.unscaledBounds.x + dx3 / scale);
	this.unscaledBounds.y = this.roundLength(this.unscaledBounds.y + dy3 / scale);
	this.unscaledBounds.width = this.roundLength(this.unscaledBounds.width);
	this.unscaledBounds.height = this.roundLength(this.unscaledBounds.height);
	
	// Shifts the children according to parent offset
	if (!this.graph.isCellCollapsed(this.state.cell) && (dx3 != 0 || dy3 != 0))
	{
		this.childOffsetX = this.state.x - this.bounds.x + dx5;
		this.childOffsetY = this.state.y - this.bounds.y + dy5;
	}
	else
	{
		this.childOffsetX = 0;
		this.childOffsetY = 0;
	}
	
	if (this.livePreview)
	{
		this.updateLivePreview(me);
	}
	
	if (this.preview != null)
	{
		this.drawPreview();
	}
};

/**
 * Function: updateLivePreview
 * 
 * Repaints the live preview.
 */
mxVertexHandler.prototype.updateLivePreview = function(me)
{
	// TODO: Apply child offset to children in live preview
	var scale = this.graph.view.scale;
	var tr = this.graph.view.translate;
	
	// Saves current state
	var tempState = this.state.clone();

	// Temporarily changes size and origin
	this.state.x = this.bounds.x;
	this.state.y = this.bounds.y;
	this.state.origin = new mxPoint(this.state.x / scale - tr.x, this.state.y / scale - tr.y);
	this.state.width = this.bounds.width;
	this.state.height = this.bounds.height;
	
	// Needed to force update of text bounds
	this.state.unscaledWidth = null;
	
	// Redraws cell and handles
	var off = this.state.absoluteOffset;
	off = new mxPoint(off.x, off.y);

	// Required to store and reset absolute offset for updating label position
	this.state.absoluteOffset.x = 0;
	this.state.absoluteOffset.y = 0;
	var geo = this.graph.getCellGeometry(this.state.cell);				

	if (geo != null)
	{
		var offset = geo.offset || this.EMPTY_POINT;

		if (offset != null && !geo.relative)
		{
			this.state.absoluteOffset.x = this.state.view.scale * offset.x;
			this.state.absoluteOffset.y = this.state.view.scale * offset.y;
		}
		
		this.state.view.updateVertexLabelOffset(this.state);
	}
	
	// Draws the live preview
	this.state.view.graph.cellRenderer.redraw(this.state, true);
	
	// Redraws connected edges TODO: Include child edges
	this.state.view.invalidate(this.state.cell);
	this.state.invalid = false;
	this.state.view.validate();
	this.redrawHandles();
	
	// Restores current state
	this.state.setState(tempState);
};

/**
 * Function: mouseUp
 * 
 * Handles the event by applying the changes to the geometry.
 */
mxVertexHandler.prototype.mouseUp = function(sender, me)
{
	if (this.index != null && this.state != null)
	{
		var point = new mxPoint(me.getGraphX(), me.getGraphY());

		this.graph.getModel().beginUpdate();
		try
		{
			if (this.index <= mxEvent.CUSTOM_HANDLE)
			{
				if (this.customHandles != null)
				{
					this.customHandles[mxEvent.CUSTOM_HANDLE - this.index].active = false;
					this.customHandles[mxEvent.CUSTOM_HANDLE - this.index].execute();
				}
			}
			else if (this.index == mxEvent.ROTATION_HANDLE)
			{
				if (this.currentAlpha != null)
				{
					var delta = this.currentAlpha - (this.state.style[mxConstants.STYLE_ROTATION] || 0);
					
					if (delta != 0)
					{
						this.rotateCell(this.state.cell, delta);
					}
				}
				else
				{
					this.rotateClick();
				}
			}
			else
			{
				var gridEnabled = this.graph.isGridEnabledEvent(me.getEvent());
				var alpha = mxUtils.toRadians(this.state.style[mxConstants.STYLE_ROTATION] || '0');
				var cos = Math.cos(-alpha);
				var sin = Math.sin(-alpha);
				
				var dx = point.x - this.startX;
				var dy = point.y - this.startY;
				
				// Rotates vector for mouse gesture
				var tx = cos * dx - sin * dy;
				var ty = sin * dx + cos * dy;
				
				dx = tx;
				dy = ty;
				
				var s = this.graph.view.scale;
				var recurse = this.isRecursiveResize(this.state, me);
				this.resizeCell(this.state.cell, this.roundLength(dx / s), this.roundLength(dy / s),
					this.index, gridEnabled, this.isConstrainedEvent(me), recurse);
			}
		}
		finally
		{
			this.graph.getModel().endUpdate();
		}

		me.consume();
		this.reset();
	}
};

/**
 * Function: rotateCell
 * 
 * Rotates the given cell to the given rotation.
 */
mxVertexHandler.prototype.isRecursiveResize = function(state, me)
{
	return this.graph.isRecursiveResize(this.state);
};

/**
 * Function: rotateClick
 * 
 * Hook for subclassers to implement a single click on the rotation handle.
 * This code is executed as part of the model transaction. This implementation
 * is empty.
 */
mxVertexHandler.prototype.rotateClick = function() { };

/**
 * Function: rotateCell
 * 
 * Rotates the given cell and its children by the given angle in degrees.
 * 
 * Parameters:
 * 
 * cell - <mxCell> to be rotated.
 * angle - Angle in degrees.
 */
mxVertexHandler.prototype.rotateCell = function(cell, angle, parent)
{
	if (angle != 0)
	{
		var model = this.graph.getModel();

		if (model.isVertex(cell) || model.isEdge(cell))
		{
			if (!model.isEdge(cell))
			{
				var state = this.graph.view.getState(cell);
				var style = (state != null) ? state.style : this.graph.getCellStyle(cell);
		
				if (style != null)
				{
					var total = (style[mxConstants.STYLE_ROTATION] || 0) + angle;
					this.graph.setCellStyles(mxConstants.STYLE_ROTATION, total, [cell]);
				}
			}
			
			var geo = this.graph.getCellGeometry(cell);
			
			if (geo != null)
			{
				var pgeo = this.graph.getCellGeometry(parent);
				
				if (pgeo != null && !model.isEdge(parent))
				{
					geo = geo.clone();
					geo.rotate(angle, new mxPoint(pgeo.width / 2, pgeo.height / 2));
					model.setGeometry(cell, geo);
				}
				
				if ((model.isVertex(cell) && !geo.relative) || model.isEdge(cell))
				{
					// Recursive rotation
					var childCount = model.getChildCount(cell);
					
					for (var i = 0; i < childCount; i++)
					{
						this.rotateCell(model.getChildAt(cell, i), angle, cell);
					}
				}
			}
		}
	}
};

/**
 * Function: reset
 * 
 * Resets the state of this handler.
 */
mxVertexHandler.prototype.reset = function()
{
	if (this.sizers != null && this.index != null && this.sizers[this.index] != null &&
		this.sizers[this.index].node.style.display == 'none')
	{
		this.sizers[this.index].node.style.display = '';
	}

	this.currentAlpha = null;
	this.inTolerance = null;
	this.index = null;

	// TODO: Reset and redraw cell states for live preview
	if (this.preview != null)
	{
		this.preview.destroy();
		this.preview = null;
	}

	if (this.livePreview && this.sizers != null)
	{
		for (var i = 0; i < this.sizers.length; i++)
		{
			if (this.sizers[i] != null)
			{
				this.sizers[i].node.style.display = '';
			}
		}
	}

	if (this.customHandles != null)
	{
		for (var i = 0; i < this.customHandles.length; i++)
		{
			if (this.customHandles[i].active)
			{
				this.customHandles[i].active = false;
				this.customHandles[i].reset();
			}
			else
			{
				this.customHandles[i].setVisible(true);
			}
		}
	}
	
	// Checks if handler has been destroyed
	if (this.selectionBorder != null)
	{
		this.selectionBorder.node.style.display = 'inline';
		this.selectionBounds = this.getSelectionBounds(this.state);
		this.bounds = new mxRectangle(this.selectionBounds.x, this.selectionBounds.y,
			this.selectionBounds.width, this.selectionBounds.height);
		this.drawPreview();
	}

	this.removeHint();
	this.redrawHandles();
	this.edgeHandlers = null;
	this.unscaledBounds = null;
};

/**
 * Function: resizeCell
 * 
 * Uses the given vector to change the bounds of the given cell
 * in the graph using <mxGraph.resizeCell>.
 */
mxVertexHandler.prototype.resizeCell = function(cell, dx, dy, index, gridEnabled, constrained, recurse)
{
	var geo = this.graph.model.getGeometry(cell);
	
	if (geo != null)
	{
		if (index == mxEvent.LABEL_HANDLE)
		{
			var scale = this.graph.view.scale;
			dx = Math.round((this.labelShape.bounds.getCenterX() - this.startX) / scale);
			dy = Math.round((this.labelShape.bounds.getCenterY() - this.startY) / scale);
			
			geo = geo.clone();
			
			if (geo.offset == null)
			{
				geo.offset = new mxPoint(dx, dy);
			}
			else
			{
				geo.offset.x += dx;
				geo.offset.y += dy;
			}
			
			this.graph.model.setGeometry(cell, geo);
		}
		else if (this.unscaledBounds != null)
		{
			var scale = this.graph.view.scale;

			if (this.childOffsetX != 0 || this.childOffsetY != 0)
			{
				this.moveChildren(cell, Math.round(this.childOffsetX / scale), Math.round(this.childOffsetY / scale));
			}

			this.graph.resizeCell(cell, this.unscaledBounds, recurse);
		}
	}
};

/**
 * Function: moveChildren
 * 
 * Moves the children of the given cell by the given vector.
 */
mxVertexHandler.prototype.moveChildren = function(cell, dx, dy)
{
	var model = this.graph.getModel();
	var childCount = model.getChildCount(cell);
	
	for (var i = 0; i < childCount; i++)
	{
		var child = model.getChildAt(cell, i);
		var geo = this.graph.getCellGeometry(child);
		
		if (geo != null)
		{
			geo = geo.clone();
			geo.translate(dx, dy);
			model.setGeometry(child, geo);
		}
	}
};
/**
 * Function: union
 * 
 * Returns the union of the given bounds and location for the specified
 * handle index.
 * 
 * To override this to limit the size of vertex via a minWidth/-Height style,
 * the following code can be used.
 * 
 * (code)
 * var vertexHandlerUnion = mxVertexHandler.prototype.union;
 * mxVertexHandler.prototype.union = function(bounds, dx, dy, index, gridEnabled, scale, tr, constrained)
 * {
 *   var result = vertexHandlerUnion.apply(this, arguments);
 *   
 *   result.width = Math.max(result.width, mxUtils.getNumber(this.state.style, 'minWidth', 0));
 *   result.height = Math.max(result.height, mxUtils.getNumber(this.state.style, 'minHeight', 0));
 *   
 *   return result;
 * };
 * (end)
 * 
 * The minWidth/-Height style can then be used as follows:
 * 
 * (code)
 * graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30, 'minWidth=100;minHeight=100;');
 * (end)
 * 
 * To override this to update the height for a wrapped text if the width of a vertex is
 * changed, the following can be used.
 * 
 * (code)
 * var mxVertexHandlerUnion = mxVertexHandler.prototype.union;
 * mxVertexHandler.prototype.union = function(bounds, dx, dy, index, gridEnabled, scale, tr, constrained)
 * {
 *   var result = mxVertexHandlerUnion.apply(this, arguments);
 *   var s = this.state;
 *   
 *   if (this.graph.isHtmlLabel(s.cell) && (index == 3 || index == 4) &&
 *       s.text != null && s.style[mxConstants.STYLE_WHITE_SPACE] == 'wrap')
 *   {
 *     var label = this.graph.getLabel(s.cell);
 *     var fontSize = mxUtils.getNumber(s.style, mxConstants.STYLE_FONTSIZE, mxConstants.DEFAULT_FONTSIZE);
 *     var ww = result.width / s.view.scale - s.text.spacingRight - s.text.spacingLeft
 *     
 *     result.height = mxUtils.getSizeForString(label, fontSize, s.style[mxConstants.STYLE_FONTFAMILY], ww).height;
 *   }
 *   
 *   return result;
 * };
 * (end)
 */
mxVertexHandler.prototype.union = function(bounds, dx, dy, index, gridEnabled, scale, tr, constrained, centered)
{
	if (this.singleSizer)
	{
		var x = bounds.x + bounds.width + dx;
		var y = bounds.y + bounds.height + dy;
		
		if (gridEnabled)
		{
			x = this.graph.snap(x / scale) * scale;
			y = this.graph.snap(y / scale) * scale;
		}
		
		var rect = new mxRectangle(bounds.x, bounds.y, 0, 0);
		rect.add(new mxRectangle(x, y, 0, 0));
		
		return rect;
	}
	else
	{
		var w0 = bounds.width;
		var h0 = bounds.height;
		var left = bounds.x - tr.x * scale;
		var right = left + w0;
		var top = bounds.y - tr.y * scale;
		var bottom = top + h0;
		
		var cx = left + w0 / 2;
		var cy = top + h0 / 2;
		
		if (index > 4 /* Bottom Row */)
		{
			bottom = bottom + dy;
			
			if (gridEnabled)
			{
				bottom = this.graph.snap(bottom / scale) * scale;
			}
		}
		else if (index < 3 /* Top Row */)
		{
			top = top + dy;
			
			if (gridEnabled)
			{
				top = this.graph.snap(top / scale) * scale;
			}
		}
		
		if (index == 0 || index == 3 || index == 5 /* Left */)
		{
			left += dx;
			
			if (gridEnabled)
			{
				left = this.graph.snap(left / scale) * scale;
			}
		}
		else if (index == 2 || index == 4 || index == 7 /* Right */)
		{
			right += dx;
			
			if (gridEnabled)
			{
				right = this.graph.snap(right / scale) * scale;
			}
		}
		
		var width = right - left;
		var height = bottom - top;

		if (constrained)
		{
			var geo = this.graph.getCellGeometry(this.state.cell);

			if (geo != null)
			{
				var aspect = geo.width / geo.height;
				
				if (index== 1 || index== 2 || index == 7 || index == 6)
				{
					width = height * aspect;
				}
				else
				{
					height = width / aspect;
				}
				
				if (index == 0)
				{
					left = right - width;
					top = bottom - height;
				}
			}
		}

		if (centered)
		{
			width += (width - w0);
			height += (height - h0);
			
			var cdx = cx - (left + width / 2);
			var cdy = cy - (top + height / 2);

			left += cdx;
			top += cdy;
			right += cdx;
			bottom += cdy;
		}

		// Flips over left side
		if (width < 0)
		{
			left += width;
			width = Math.abs(width);
		}
		
		// Flips over top side
		if (height < 0)
		{
			top += height;
			height = Math.abs(height);
		}

		var result = new mxRectangle(left + tr.x * scale, top + tr.y * scale, width, height);
		
		if (this.minBounds != null)
		{
			result.width = Math.max(result.width, this.minBounds.x * scale + this.minBounds.width * scale +
				Math.max(0, this.x0 * scale - result.x));
			result.height = Math.max(result.height, this.minBounds.y * scale + this.minBounds.height * scale +
				Math.max(0, this.y0 * scale - result.y));
		}
		
		return result;
	}
};

/**
 * Function: redraw
 * 
 * Redraws the handles and the preview.
 */
mxVertexHandler.prototype.redraw = function()
{
	this.selectionBounds = this.getSelectionBounds(this.state);
	this.bounds = new mxRectangle(this.selectionBounds.x, this.selectionBounds.y, this.selectionBounds.width, this.selectionBounds.height);
	
	this.redrawHandles();
	this.drawPreview();
};

/**
 * Returns the padding to be used for drawing handles for the current <bounds>.
 */
mxVertexHandler.prototype.getHandlePadding = function()
{
	// KNOWN: Tolerance depends on event type (eg. 0 for mouse events)
	var result = new mxPoint(0, 0);
	var tol = this.tolerance;

	if (this.sizers != null && this.sizers.length > 0 && this.sizers[0] != null &&
		(this.bounds.width < 2 * this.sizers[0].bounds.width + 2 * tol ||
		this.bounds.height < 2 * this.sizers[0].bounds.height + 2 * tol))
	{
		tol /= 2;
		
		result.x = this.sizers[0].bounds.width + tol;
		result.y = this.sizers[0].bounds.height + tol;
	}
	
	return result;
};

/**
 * Function: redrawHandles
 * 
 * Redraws the handles. To hide certain handles the following code can be used.
 * 
 * (code)
 * mxVertexHandler.prototype.redrawHandles = function()
 * {
 *   mxVertexHandlerRedrawHandles.apply(this, arguments);
 *   
 *   if (this.sizers != null && this.sizers.length > 7)
 *   {
 *     this.sizers[1].node.style.display = 'none';
 *     this.sizers[6].node.style.display = 'none';
 *   }
 * };
 * (end)
 */
mxVertexHandler.prototype.redrawHandles = function()
{
	var tol = this.tolerance;
	this.horizontalOffset = 0;
	this.verticalOffset = 0;
	var s = this.bounds;

	if (this.sizers != null && this.sizers.length > 0 && this.sizers[0] != null)
	{
		if (this.index == null && this.manageSizers && this.sizers.length >= 8)
		{
			// KNOWN: Tolerance depends on event type (eg. 0 for mouse events)
			var padding = this.getHandlePadding();
			this.horizontalOffset = padding.x;
			this.verticalOffset = padding.y;
			
			if (this.horizontalOffset != 0 || this.verticalOffset != 0)
			{
				s = new mxRectangle(s.x, s.y, s.width, s.height);

				s.x -= this.horizontalOffset / 2;
				s.width += this.horizontalOffset;
				s.y -= this.verticalOffset / 2;
				s.height += this.verticalOffset;
			}
			
			if (this.sizers.length >= 8)
			{
				if ((s.width < 2 * this.sizers[0].bounds.width + 2 * tol) ||
					(s.height < 2 * this.sizers[0].bounds.height + 2 * tol))
				{
					this.sizers[0].node.style.display = 'none';
					this.sizers[2].node.style.display = 'none';
					this.sizers[5].node.style.display = 'none';
					this.sizers[7].node.style.display = 'none';
				}
				else
				{
					this.sizers[0].node.style.display = '';
					this.sizers[2].node.style.display = '';
					this.sizers[5].node.style.display = '';
					this.sizers[7].node.style.display = '';
				}
			}
		}

		var r = s.x + s.width;
		var b = s.y + s.height;
		
		if (this.singleSizer)
		{
			this.moveSizerTo(this.sizers[0], r, b);
		}
		else
		{
			var cx = s.x + s.width / 2;
			var cy = s.y + s.height / 2;
			
			if (this.sizers.length >= 8)
			{
				var crs = ['nw-resize', 'n-resize', 'ne-resize', 'e-resize', 'se-resize', 's-resize', 'sw-resize', 'w-resize'];
				
				var alpha = mxUtils.toRadians(this.state.style[mxConstants.STYLE_ROTATION] || '0');
				var cos = Math.cos(alpha);
				var sin = Math.sin(alpha);
				
				var da = Math.round(alpha * 4 / Math.PI);
				
				var ct = new mxPoint(s.getCenterX(), s.getCenterY());
				var pt = mxUtils.getRotatedPoint(new mxPoint(s.x, s.y), cos, sin, ct);
				
				this.moveSizerTo(this.sizers[0], pt.x, pt.y);
				this.sizers[0].setCursor(crs[mxUtils.mod(0 + da, crs.length)]);
				
				pt.x = cx;
				pt.y = s.y;
				pt = mxUtils.getRotatedPoint(pt, cos, sin, ct);
				
				this.moveSizerTo(this.sizers[1], pt.x, pt.y);
				this.sizers[1].setCursor(crs[mxUtils.mod(1 + da, crs.length)]);
				
				pt.x = r;
				pt.y = s.y;
				pt = mxUtils.getRotatedPoint(pt, cos, sin, ct);
				
				this.moveSizerTo(this.sizers[2], pt.x, pt.y);
				this.sizers[2].setCursor(crs[mxUtils.mod(2 + da, crs.length)]);
				
				pt.x = s.x;
				pt.y = cy;
				pt = mxUtils.getRotatedPoint(pt, cos, sin, ct);
				
				this.moveSizerTo(this.sizers[3], pt.x, pt.y);
				this.sizers[3].setCursor(crs[mxUtils.mod(7 + da, crs.length)]);

				pt.x = r;
				pt.y = cy;
				pt = mxUtils.getRotatedPoint(pt, cos, sin, ct);
				
				this.moveSizerTo(this.sizers[4], pt.x, pt.y);
				this.sizers[4].setCursor(crs[mxUtils.mod(3 + da, crs.length)]);

				pt.x = s.x;
				pt.y = b;
				pt = mxUtils.getRotatedPoint(pt, cos, sin, ct);
				
				this.moveSizerTo(this.sizers[5], pt.x, pt.y);
				this.sizers[5].setCursor(crs[mxUtils.mod(6 + da, crs.length)]);

				pt.x = cx;
				pt.y = b;
				pt = mxUtils.getRotatedPoint(pt, cos, sin, ct);
				
				this.moveSizerTo(this.sizers[6], pt.x, pt.y);
				this.sizers[6].setCursor(crs[mxUtils.mod(5 + da, crs.length)]);

				pt.x = r;
				pt.y = b;
				pt = mxUtils.getRotatedPoint(pt, cos, sin, ct);
				
				this.moveSizerTo(this.sizers[7], pt.x, pt.y);
				this.sizers[7].setCursor(crs[mxUtils.mod(4 + da, crs.length)]);
				
				this.moveSizerTo(this.sizers[8], cx + this.state.absoluteOffset.x, cy + this.state.absoluteOffset.y);
			}
			else if (this.state.width >= 2 && this.state.height >= 2)
			{
				this.moveSizerTo(this.sizers[0], cx + this.state.absoluteOffset.x, cy + this.state.absoluteOffset.y);
			}
			else
			{
				this.moveSizerTo(this.sizers[0], this.state.x, this.state.y);
			}
		}
	}

	if (this.rotationShape != null)
	{
		var alpha = mxUtils.toRadians((this.currentAlpha != null) ? this.currentAlpha : this.state.style[mxConstants.STYLE_ROTATION] || '0');
		var cos = Math.cos(alpha);
		var sin = Math.sin(alpha);
		
		var ct = new mxPoint(this.state.getCenterX(), this.state.getCenterY());
		var pt = mxUtils.getRotatedPoint(new mxPoint(s.x + s.width / 2, s.y + this.rotationHandleVSpacing), cos, sin, ct);

		if (this.rotationShape.node != null)
		{
			this.moveSizerTo(this.rotationShape, pt.x, pt.y);
		}
	}
	
	if (this.selectionBorder != null)
	{
		this.selectionBorder.rotation = Number(this.state.style[mxConstants.STYLE_ROTATION] || '0');
	}
	
	if (this.edgeHandlers != null)
	{		
		for (var i = 0; i < this.edgeHandlers.length; i++)
		{
			this.edgeHandlers[i].redraw();
		}
	}

	if (this.customHandles != null)
	{
		for (var i = 0; i < this.customHandles.length; i++)
		{
			var temp = this.customHandles[i].shape.node.style.display;
			this.customHandles[i].redraw();
			this.customHandles[i].shape.node.style.display = temp;
		}
	}

	this.updateParentHighlight();
};

/**
 * Function: updateParentHighlight
 * 
 * Updates the highlight of the parent if <parentHighlightEnabled> is true.
 */
mxVertexHandler.prototype.updateParentHighlight = function()
{
	// If not destroyed
	if (this.selectionBorder != null)
	{
		if (this.parentHighlight != null)
		{
			var parent = this.graph.model.getParent(this.state.cell);
	
			if (this.graph.model.isVertex(parent))
			{
				var pstate = this.graph.view.getState(parent);
				var b = this.parentHighlight.bounds;
				
				if (pstate != null && (b.x != pstate.x || b.y != pstate.y ||
					b.width != pstate.width || b.height != pstate.height))
				{
					this.parentHighlight.bounds = pstate;
					this.parentHighlight.redraw();
				}
			}
			else
			{
				this.parentHighlight.destroy();
				this.parentHighlight = null;
			}
		}
		else if (this.parentHighlightEnabled)
		{
			var parent = this.graph.model.getParent(this.state.cell);
			
			if (this.graph.model.isVertex(parent))
			{
				var pstate = this.graph.view.getState(parent);
				
				if (pstate != null)
				{
					this.parentHighlight = this.createParentHighlightShape(pstate);
					// VML dialect required here for event transparency in IE
					this.parentHighlight.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ? mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
					this.parentHighlight.pointerEvents = false;
					this.parentHighlight.rotation = Number(pstate.style[mxConstants.STYLE_ROTATION] || '0');
					this.parentHighlight.init(this.graph.getView().getOverlayPane());
				}
			}
		}
	}
};

/**
 * Function: drawPreview
 * 
 * Redraws the preview.
 */
mxVertexHandler.prototype.drawPreview = function()
{
	if (this.preview != null)
	{
		this.preview.bounds = this.bounds;
		
		if (this.preview.node.parentNode == this.graph.container)
		{
			this.preview.bounds.width = Math.max(0, this.preview.bounds.width - 1);
			this.preview.bounds.height = Math.max(0, this.preview.bounds.height - 1);
		}
	
		this.preview.rotation = Number(this.state.style[mxConstants.STYLE_ROTATION] || '0');
		this.preview.redraw();
	}
	
	this.selectionBorder.bounds = this.bounds;
	this.selectionBorder.redraw();
	
	if (this.parentHighlight != null)
	{
		this.parentHighlight.redraw();
	}
};

/**
 * Function: destroy
 * 
 * Destroys the handler and all its resources and DOM nodes.
 */
mxVertexHandler.prototype.destroy = function()
{
	if (this.escapeHandler != null)
	{
		this.state.view.graph.removeListener(this.escapeHandler);
		this.escapeHandler = null;
	}
	
	if (this.preview != null)
	{
		this.preview.destroy();
		this.preview = null;
	}
	
	if (this.parentHighlight != null)
	{
		this.parentHighlight.destroy();
		this.parentHighlight = null;
	}
	
	if (this.selectionBorder != null)
	{
		this.selectionBorder.destroy();
		this.selectionBorder = null;
	}
	
	this.labelShape = null;
	this.removeHint();

	if (this.sizers != null)
	{
		for (var i = 0; i < this.sizers.length; i++)
		{
			this.sizers[i].destroy();
		}
		
		this.sizers = null;
	}

	if (this.customHandles != null)
	{
		for (var i = 0; i < this.customHandles.length; i++)
		{
			this.customHandles[i].destroy();
		}
		
		this.customHandles = null;
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxEdgeHandler
 *
 * Graph event handler that reconnects edges and modifies control points and
 * the edge label location. Uses <mxTerminalMarker> for finding and
 * highlighting new source and target vertices. This handler is automatically
 * created in <mxGraph.createHandler> for each selected edge.
 * 
 * To enable adding/removing control points, the following code can be used:
 * 
 * (code)
 * mxEdgeHandler.prototype.addEnabled = true;
 * mxEdgeHandler.prototype.removeEnabled = true;
 * (end)
 * 
 * Note: This experimental feature is not recommended for production use.
 * 
 * Constructor: mxEdgeHandler
 *
 * Constructs an edge handler for the specified <mxCellState>.
 * 
 * Parameters:
 * 
 * state - <mxCellState> of the cell to be handled.
 */
function mxEdgeHandler(state)
{
	if (state != null)
	{
		this.state = state;
		this.init();
		
		// Handles escape keystrokes
		this.escapeHandler = mxUtils.bind(this, function(sender, evt)
		{
			this.reset();
		});
		
		this.state.view.graph.addListener(mxEvent.ESCAPE, this.escapeHandler);
	}
};

/**
 * Variable: graph
 * 
 * Reference to the enclosing <mxGraph>.
 */
mxEdgeHandler.prototype.graph = null;

/**
 * Variable: state
 * 
 * Reference to the <mxCellState> being modified.
 */
mxEdgeHandler.prototype.state = null;

/**
 * Variable: marker
 * 
 * Holds the <mxTerminalMarker> which is used for highlighting terminals.
 */
mxEdgeHandler.prototype.marker = null;

/**
 * Variable: constraintHandler
 * 
 * Holds the <mxConstraintHandler> used for drawing and highlighting
 * constraints.
 */
mxEdgeHandler.prototype.constraintHandler = null;

/**
 * Variable: error
 * 
 * Holds the current validation error while a connection is being changed.
 */
mxEdgeHandler.prototype.error = null;

/**
 * Variable: shape
 * 
 * Holds the <mxShape> that represents the preview edge.
 */
mxEdgeHandler.prototype.shape = null;

/**
 * Variable: bends
 * 
 * Holds the <mxShapes> that represent the points.
 */
mxEdgeHandler.prototype.bends = null;

/**
 * Variable: labelShape
 * 
 * Holds the <mxShape> that represents the label position.
 */
mxEdgeHandler.prototype.labelShape = null;

/**
 * Variable: cloneEnabled
 * 
 * Specifies if cloning by control-drag is enabled. Default is true.
 */
mxEdgeHandler.prototype.cloneEnabled = true;

/**
 * Variable: addEnabled
 * 
 * Specifies if adding bends by shift-click is enabled. Default is false.
 * Note: This experimental feature is not recommended for production use.
 */
mxEdgeHandler.prototype.addEnabled = false;

/**
 * Variable: removeEnabled
 * 
 * Specifies if removing bends by shift-click is enabled. Default is false.
 * Note: This experimental feature is not recommended for production use.
 */
mxEdgeHandler.prototype.removeEnabled = false;

/**
 * Variable: dblClickRemoveEnabled
 * 
 * Specifies if removing bends by double click is enabled. Default is false.
 */
mxEdgeHandler.prototype.dblClickRemoveEnabled = false;

/**
 * Variable: mergeRemoveEnabled
 * 
 * Specifies if removing bends by dropping them on other bends is enabled.
 * Default is false.
 */
mxEdgeHandler.prototype.mergeRemoveEnabled = false;

/**
 * Variable: straightRemoveEnabled
 * 
 * Specifies if removing bends by creating straight segments should be enabled.
 * If enabled, this can be overridden by holding down the alt key while moving.
 * Default is false.
 */
mxEdgeHandler.prototype.straightRemoveEnabled = false;

/**
 * Variable: virtualBendsEnabled
 * 
 * Specifies if virtual bends should be added in the center of each
 * segments. These bends can then be used to add new waypoints.
 * Default is false.
 */
mxEdgeHandler.prototype.virtualBendsEnabled = false;

/**
 * Variable: virtualBendOpacity
 * 
 * Opacity to be used for virtual bends (see <virtualBendsEnabled>).
 * Default is 20.
 */
mxEdgeHandler.prototype.virtualBendOpacity = 20;

/**
 * Variable: parentHighlightEnabled
 * 
 * Specifies if the parent should be highlighted if a child cell is selected.
 * Default is false.
 */
mxEdgeHandler.prototype.parentHighlightEnabled = false;

/**
 * Variable: preferHtml
 * 
 * Specifies if bends should be added to the graph container. This is updated
 * in <init> based on whether the edge or one of its terminals has an HTML
 * label in the container.
 */
mxEdgeHandler.prototype.preferHtml = false;

/**
 * Variable: allowHandleBoundsCheck
 * 
 * Specifies if the bounds of handles should be used for hit-detection in IE
 * Default is true.
 */
mxEdgeHandler.prototype.allowHandleBoundsCheck = true;

/**
 * Variable: snapToTerminals
 * 
 * Specifies if waypoints should snap to the routing centers of terminals.
 * Default is false.
 */
mxEdgeHandler.prototype.snapToTerminals = false;

/**
 * Variable: handleImage
 * 
 * Optional <mxImage> to be used as handles. Default is null.
 */
mxEdgeHandler.prototype.handleImage = null;

/**
 * Variable: tolerance
 * 
 * Optional tolerance for hit-detection in <getHandleForEvent>. Default is 0.
 */
mxEdgeHandler.prototype.tolerance = 0;

/**
 * Variable: outlineConnect
 * 
 * Specifies if connections to the outline of a highlighted target should be
 * enabled. This will allow to place the connection point along the outline of
 * the highlighted target. Default is false.
 */
mxEdgeHandler.prototype.outlineConnect = false;

/**
 * Variable: manageLabelHandle
 * 
 * Specifies if the label handle should be moved if it intersects with another
 * handle. Uses <checkLabelHandle> for checking and moving. Default is false.
 */
mxEdgeHandler.prototype.manageLabelHandle = false;

/**
 * Function: init
 * 
 * Initializes the shapes required for this edge handler.
 */
mxEdgeHandler.prototype.init = function()
{
	this.graph = this.state.view.graph;
	this.marker = this.createMarker();
	this.constraintHandler = new mxConstraintHandler(this.graph);
	
	// Clones the original points from the cell
	// and makes sure at least one point exists
	this.points = [];
	
	// Uses the absolute points of the state
	// for the initial configuration and preview
	this.abspoints = this.getSelectionPoints(this.state);
	this.shape = this.createSelectionShape(this.abspoints);
	this.shape.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
		mxConstants.DIALECT_MIXEDHTML : mxConstants.DIALECT_SVG;
	this.shape.init(this.graph.getView().getOverlayPane());
	this.shape.pointerEvents = false;
	this.shape.setCursor(mxConstants.CURSOR_MOVABLE_EDGE);
	mxEvent.redirectMouseEvents(this.shape.node, this.graph, this.state);

	// Updates preferHtml
	this.preferHtml = this.state.text != null &&
		this.state.text.node.parentNode == this.graph.container;
	
	if (!this.preferHtml)
	{
		// Checks source terminal
		var sourceState = this.state.getVisibleTerminalState(true);
		
		if (sourceState != null)
		{
			this.preferHtml = sourceState.text != null &&
				sourceState.text.node.parentNode == this.graph.container;
		}
		
		if (!this.preferHtml)
		{
			// Checks target terminal
			var targetState = this.state.getVisibleTerminalState(false);
			
			if (targetState != null)
			{
				this.preferHtml = targetState.text != null &&
				targetState.text.node.parentNode == this.graph.container;
			}
		}
	}
	
	// Adds highlight for parent group
	if (this.parentHighlightEnabled)
	{
		var parent = this.graph.model.getParent(this.state.cell);
		
		if (this.graph.model.isVertex(parent))
		{
			var pstate = this.graph.view.getState(parent);
			
			if (pstate != null)
			{
				this.parentHighlight = this.createParentHighlightShape(pstate);
				// VML dialect required here for event transparency in IE
				this.parentHighlight.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ? mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
				this.parentHighlight.pointerEvents = false;
				this.parentHighlight.rotation = Number(pstate.style[mxConstants.STYLE_ROTATION] || '0');
				this.parentHighlight.init(this.graph.getView().getOverlayPane());
			}
		}
	}
	
	// Creates bends for the non-routed absolute points
	// or bends that don't correspond to points
	if (this.graph.getSelectionCount() < mxGraphHandler.prototype.maxCells ||
		mxGraphHandler.prototype.maxCells <= 0)
	{
		this.bends = this.createBends();

		if (this.isVirtualBendsEnabled())
		{
			this.virtualBends = this.createVirtualBends();
		}
	}

	// Adds a rectangular handle for the label position
	this.label = new mxPoint(this.state.absoluteOffset.x, this.state.absoluteOffset.y);
	this.labelShape = this.createLabelHandleShape();
	this.initBend(this.labelShape);
	this.labelShape.setCursor(mxConstants.CURSOR_LABEL_HANDLE);
	
	this.customHandles = this.createCustomHandles();
	
	this.redraw();
};

/**
 * Function: createCustomHandles
 * 
 * Returns an array of custom handles. This implementation returns null.
 */
mxEdgeHandler.prototype.createCustomHandles = function()
{
	return null;
};

/**
 * Function: isVirtualBendsEnabled
 * 
 * Returns true if virtual bends should be added. This returns true if
 * <virtualBendsEnabled> is true and the current style allows and
 * renders custom waypoints.
 */
mxEdgeHandler.prototype.isVirtualBendsEnabled = function(evt)
{
	return this.virtualBendsEnabled && (this.state.style[mxConstants.STYLE_EDGE] == null ||
			this.state.style[mxConstants.STYLE_EDGE] == mxConstants.NONE ||
			this.state.style[mxConstants.STYLE_NOEDGESTYLE] == 1)  &&
			mxUtils.getValue(this.state.style, mxConstants.STYLE_SHAPE, null) != 'arrow';
};

/**
 * Function: isAddPointEvent
 * 
 * Returns true if the given event is a trigger to add a new point. This
 * implementation returns true if shift is pressed.
 */
mxEdgeHandler.prototype.isAddPointEvent = function(evt)
{
	return mxEvent.isShiftDown(evt);
};

/**
 * Function: isRemovePointEvent
 * 
 * Returns true if the given event is a trigger to remove a point. This
 * implementation returns true if shift is pressed.
 */
mxEdgeHandler.prototype.isRemovePointEvent = function(evt)
{
	return mxEvent.isShiftDown(evt);
};

/**
 * Function: getSelectionPoints
 * 
 * Returns the list of points that defines the selection stroke.
 */
mxEdgeHandler.prototype.getSelectionPoints = function(state)
{
	return state.absolutePoints;
};

/**
 * Function: createSelectionShape
 * 
 * Creates the shape used to draw the selection border.
 */
mxEdgeHandler.prototype.createParentHighlightShape = function(bounds)
{
	var shape = new mxRectangleShape(bounds, null, this.getSelectionColor());
	shape.strokewidth = this.getSelectionStrokeWidth();
	shape.isDashed = this.isSelectionDashed();
	
	return shape;
};

/**
 * Function: createSelectionShape
 * 
 * Creates the shape used to draw the selection border.
 */
mxEdgeHandler.prototype.createSelectionShape = function(points)
{
	var shape = new this.state.shape.constructor();
	shape.outline = true;
	shape.apply(this.state);
	
	shape.isDashed = this.isSelectionDashed();
	shape.stroke = this.getSelectionColor();
	shape.isShadow = false;
	
	return shape;
};

/**
 * Function: getSelectionColor
 * 
 * Returns <mxConstants.EDGE_SELECTION_COLOR>.
 */
mxEdgeHandler.prototype.getSelectionColor = function()
{
	return mxConstants.EDGE_SELECTION_COLOR;
};

/**
 * Function: getSelectionStrokeWidth
 * 
 * Returns <mxConstants.EDGE_SELECTION_STROKEWIDTH>.
 */
mxEdgeHandler.prototype.getSelectionStrokeWidth = function()
{
	return mxConstants.EDGE_SELECTION_STROKEWIDTH;
};

/**
 * Function: isSelectionDashed
 * 
 * Returns <mxConstants.EDGE_SELECTION_DASHED>.
 */
mxEdgeHandler.prototype.isSelectionDashed = function()
{
	return mxConstants.EDGE_SELECTION_DASHED;
};

/**
 * Function: isConnectableCell
 * 
 * Returns true if the given cell is connectable. This is a hook to
 * disable floating connections. This implementation returns true.
 */
mxEdgeHandler.prototype.isConnectableCell = function(cell)
{
	return true;
};

/**
 * Function: getCellAt
 * 
 * Creates and returns the <mxCellMarker> used in <marker>.
 */
mxEdgeHandler.prototype.getCellAt = function(x, y)
{
	return (!this.outlineConnect) ? this.graph.getCellAt(x, y) : null;
};

/**
 * Function: createMarker
 * 
 * Creates and returns the <mxCellMarker> used in <marker>.
 */
mxEdgeHandler.prototype.createMarker = function()
{
	var marker = new mxCellMarker(this.graph);
	var self = this; // closure

	// Only returns edges if they are connectable and never returns
	// the edge that is currently being modified
	marker.getCell = function(me)
	{
		var cell = mxCellMarker.prototype.getCell.apply(this, arguments);

		// Checks for cell at preview point (with grid)
		if ((cell == self.state.cell || cell == null) && self.currentPoint != null)
		{
			cell = self.graph.getCellAt(self.currentPoint.x, self.currentPoint.y);
		}
		
		// Uses connectable parent vertex if one exists
		if (cell != null && !this.graph.isCellConnectable(cell))
		{
			var parent = this.graph.getModel().getParent(cell);
			
			if (this.graph.getModel().isVertex(parent) && this.graph.isCellConnectable(parent))
			{
				cell = parent;
			}
		}
		
		var model = self.graph.getModel();
		
		if ((this.graph.isSwimlane(cell) && self.currentPoint != null &&
			this.graph.hitsSwimlaneContent(cell, self.currentPoint.x, self.currentPoint.y)) ||
			(!self.isConnectableCell(cell)) || (cell == self.state.cell ||
			(cell != null && !self.graph.connectableEdges && model.isEdge(cell))) ||
			model.isAncestor(self.state.cell, cell))
		{
			cell = null;
		}
		
		if (!this.graph.isCellConnectable(cell))
		{
			cell = null;
		}
		
		return cell;
	};

	// Sets the highlight color according to validateConnection
	marker.isValidState = function(state)
	{
		var model = self.graph.getModel();
		var other = self.graph.view.getTerminalPort(state,
			self.graph.view.getState(model.getTerminal(self.state.cell,
			!self.isSource)), !self.isSource);
		var otherCell = (other != null) ? other.cell : null;
		var source = (self.isSource) ? state.cell : otherCell;
		var target = (self.isSource) ? otherCell : state.cell;
		
		// Updates the error message of the handler
		self.error = self.validateConnection(source, target);

		return self.error == null;
	};
	
	return marker;
};

/**
 * Function: validateConnection
 * 
 * Returns the error message or an empty string if the connection for the
 * given source, target pair is not valid. Otherwise it returns null. This
 * implementation uses <mxGraph.getEdgeValidationError>.
 * 
 * Parameters:
 * 
 * source - <mxCell> that represents the source terminal.
 * target - <mxCell> that represents the target terminal.
 */
mxEdgeHandler.prototype.validateConnection = function(source, target)
{
	return this.graph.getEdgeValidationError(this.state.cell, source, target);
};

/**
 * Function: createBends
 * 
 * Creates and returns the bends used for modifying the edge. This is
 * typically an array of <mxRectangleShapes>.
 */
 mxEdgeHandler.prototype.createBends = function()
 {
	var cell = this.state.cell;
	var bends = [];

	for (var i = 0; i < this.abspoints.length; i++)
	{
		if (this.isHandleVisible(i))
		{
			var source = i == 0;
			var target = i == this.abspoints.length - 1;
			var terminal = source || target;

			if (terminal || this.graph.isCellBendable(cell))
			{
				(mxUtils.bind(this, function(index)
				{
					var bend = this.createHandleShape(index);
					this.initBend(bend, mxUtils.bind(this, mxUtils.bind(this, function()
					{
						if (this.dblClickRemoveEnabled)
						{
							this.removePoint(this.state, index);
						}
					})));
	
					if (this.isHandleEnabled(i))
					{
						bend.setCursor((terminal) ? mxConstants.CURSOR_TERMINAL_HANDLE : mxConstants.CURSOR_BEND_HANDLE);
					}
					
					bends.push(bend);
				
					if (!terminal)
					{
						this.points.push(new mxPoint(0,0));
						bend.node.style.visibility = 'hidden';
					}
				}))(i);
			}
		}
	}

	return bends;
};

/**
 * Function: createVirtualBends
 * 
 * Creates and returns the bends used for modifying the edge. This is
 * typically an array of <mxRectangleShapes>.
 */
 mxEdgeHandler.prototype.createVirtualBends = function()
 {
	var cell = this.state.cell;
	var last = this.abspoints[0];
	var bends = [];

	if (this.graph.isCellBendable(cell))
	{
		for (var i = 1; i < this.abspoints.length; i++)
		{
			(mxUtils.bind(this, function(bend)
			{
				this.initBend(bend);
				bend.setCursor(mxConstants.CURSOR_VIRTUAL_BEND_HANDLE);
				bends.push(bend);
			}))(this.createHandleShape());
		}
	}

	return bends;
};

/**
 * Function: isHandleEnabled
 * 
 * Creates the shape used to display the given bend.
 */
mxEdgeHandler.prototype.isHandleEnabled = function(index)
{
	return true;
};

/**
 * Function: isHandleVisible
 * 
 * Returns true if the handle at the given index is visible.
 */
mxEdgeHandler.prototype.isHandleVisible = function(index)
{
	var source = this.state.getVisibleTerminalState(true);
	var target = this.state.getVisibleTerminalState(false);
	var geo = this.graph.getCellGeometry(this.state.cell);
	var edgeStyle = (geo != null) ? this.graph.view.getEdgeStyle(this.state, geo.points, source, target) : null;

	return edgeStyle != mxEdgeStyle.EntityRelation || index == 0 || index == this.abspoints.length - 1;
};

/**
 * Function: createHandleShape
 * 
 * Creates the shape used to display the given bend. Note that the index may be
 * null for special cases, such as when called from
 * <mxElbowEdgeHandler.createVirtualBend>. Only images and rectangles should be
 * returned if support for HTML labels with not foreign objects is required.
 * Index if null for virtual handles.
 */
mxEdgeHandler.prototype.createHandleShape = function(index)
{
	if (this.handleImage != null)
	{
		var shape = new mxImageShape(new mxRectangle(0, 0, this.handleImage.width, this.handleImage.height), this.handleImage.src);
		
		// Allows HTML rendering of the images
		shape.preserveImageAspect = false;

		return shape;
	}
	else
	{
		var s = mxConstants.HANDLE_SIZE;
		
		if (this.preferHtml)
		{
			s -= 1;
		}
		
		return new mxRectangleShape(new mxRectangle(0, 0, s, s), mxConstants.HANDLE_FILLCOLOR, mxConstants.HANDLE_STROKECOLOR);
	}
};

/**
 * Function: createLabelHandleShape
 * 
 * Creates the shape used to display the the label handle.
 */
mxEdgeHandler.prototype.createLabelHandleShape = function()
{
	if (this.labelHandleImage != null)
	{
		var shape = new mxImageShape(new mxRectangle(0, 0, this.labelHandleImage.width, this.labelHandleImage.height), this.labelHandleImage.src);
		
		// Allows HTML rendering of the images
		shape.preserveImageAspect = false;

		return shape;
	}
	else
	{
		var s = mxConstants.LABEL_HANDLE_SIZE;
		return new mxRectangleShape(new mxRectangle(0, 0, s, s), mxConstants.LABEL_HANDLE_FILLCOLOR, mxConstants.HANDLE_STROKECOLOR);
	}
};

/**
 * Function: initBend
 * 
 * Helper method to initialize the given bend.
 * 
 * Parameters:
 * 
 * bend - <mxShape> that represents the bend to be initialized.
 */
mxEdgeHandler.prototype.initBend = function(bend, dblClick)
{
	if (this.preferHtml)
	{
		bend.dialect = mxConstants.DIALECT_STRICTHTML;
		bend.init(this.graph.container);
	}
	else
	{
		bend.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ?
			mxConstants.DIALECT_MIXEDHTML : mxConstants.DIALECT_SVG;
		bend.init(this.graph.getView().getOverlayPane());
	}

	mxEvent.redirectMouseEvents(bend.node, this.graph, this.state,
			null, null, null, dblClick);
	
	// Fixes lost event tracking for images in quirks / IE8 standards
	if (mxClient.IS_QUIRKS || document.documentMode == 8)
	{
		mxEvent.addListener(bend.node, 'dragstart', function(evt)
		{
			mxEvent.consume(evt);
			
			return false;
		});
	}
	
	if (mxClient.IS_TOUCH)
	{
		bend.node.setAttribute('pointer-events', 'none');
	}
};

/**
 * Function: getHandleForEvent
 * 
 * Returns the index of the handle for the given event.
 */
mxEdgeHandler.prototype.getHandleForEvent = function(me)
{
	// Connection highlight may consume events before they reach sizer handle
	var tol = (!mxEvent.isMouseEvent(me.getEvent())) ? this.tolerance : 1;
	var hit = (this.allowHandleBoundsCheck && (mxClient.IS_IE || tol > 0)) ?
		new mxRectangle(me.getGraphX() - tol, me.getGraphY() - tol, 2 * tol, 2 * tol) : null;
	var minDistSq = null;
	var result = null;

	function checkShape(shape)
	{
		if (shape != null && shape.node.style.display != 'none' && shape.node.style.visibility != 'hidden' &&
			(me.isSource(shape) || (hit != null && mxUtils.intersects(shape.bounds, hit))))
		{
			var dx = me.getGraphX() - shape.bounds.getCenterX();
			var dy = me.getGraphY() - shape.bounds.getCenterY();
			var tmp = dx * dx + dy * dy;
			
			if (minDistSq == null || tmp <= minDistSq)
			{
				minDistSq = tmp;
			
				return true;
			}
		}
		
		return false;
	}
	
	if (this.customHandles != null && this.isCustomHandleEvent(me))
	{
		// Inverse loop order to match display order
		for (var i = this.customHandles.length - 1; i >= 0; i--)
		{
			if (checkShape(this.customHandles[i].shape))
			{
				// LATER: Return reference to active shape
				return mxEvent.CUSTOM_HANDLE - i;
			}
		}
	}

	if (me.isSource(this.state.text) || checkShape(this.labelShape))
	{
		result = mxEvent.LABEL_HANDLE;
	}
	
	if (this.bends != null)
	{
		for (var i = 0; i < this.bends.length; i++)
		{
			if (checkShape(this.bends[i]))
			{
				result = i;
			}
		}
	}
	
	if (this.virtualBends != null && this.isAddVirtualBendEvent(me))
	{
		for (var i = 0; i < this.virtualBends.length; i++)
		{
			if (checkShape(this.virtualBends[i]))
			{
				result = mxEvent.VIRTUAL_HANDLE - i;
			}
		}
	}

	return result;
};

/**
 * Function: isAddVirtualBendEvent
 * 
 * Returns true if the given event allows virtual bends to be added. This
 * implementation returns true.
 */
mxEdgeHandler.prototype.isAddVirtualBendEvent = function(me)
{
	return true;
};

/**
 * Function: isCustomHandleEvent
 * 
 * Returns true if the given event allows custom handles to be changed. This
 * implementation returns true.
 */
mxEdgeHandler.prototype.isCustomHandleEvent = function(me)
{
	return true;
};

/**
 * Function: mouseDown
 * 
 * Handles the event by checking if a special element of the handler
 * was clicked, in which case the index parameter is non-null. The
 * indices may be one of <LABEL_HANDLE> or the number of the respective
 * control point. The source and target points are used for reconnecting
 * the edge.
 */
mxEdgeHandler.prototype.mouseDown = function(sender, me)
{
	var handle = this.getHandleForEvent(me);
	
	if (this.bends != null && this.bends[handle] != null)
	{
		var b = this.bends[handle].bounds;
		this.snapPoint = new mxPoint(b.getCenterX(), b.getCenterY());
	}
	
	if (this.addEnabled && handle == null && this.isAddPointEvent(me.getEvent()))
	{
		this.addPoint(this.state, me.getEvent());
		me.consume();
	}
	else if (handle != null && !me.isConsumed() && this.graph.isEnabled())
	{
		if (this.removeEnabled && this.isRemovePointEvent(me.getEvent()))
		{
			this.removePoint(this.state, handle);
		}
		else if (handle != mxEvent.LABEL_HANDLE || this.graph.isLabelMovable(me.getCell()))
		{
			if (handle <= mxEvent.VIRTUAL_HANDLE)
			{
				mxUtils.setOpacity(this.virtualBends[mxEvent.VIRTUAL_HANDLE - handle].node, 100);
			}
			
			this.start(me.getX(), me.getY(), handle);
		}
		
		me.consume();
	}
};

/**
 * Function: start
 * 
 * Starts the handling of the mouse gesture.
 */
mxEdgeHandler.prototype.start = function(x, y, index)
{
	this.startX = x;
	this.startY = y;

	this.isSource = (this.bends == null) ? false : index == 0;
	this.isTarget = (this.bends == null) ? false : index == this.bends.length - 1;
	this.isLabel = index == mxEvent.LABEL_HANDLE;

	if (this.isSource || this.isTarget)
	{
		var cell = this.state.cell;
		var terminal = this.graph.model.getTerminal(cell, this.isSource);

		if ((terminal == null && this.graph.isTerminalPointMovable(cell, this.isSource)) ||
			(terminal != null && this.graph.isCellDisconnectable(cell, terminal, this.isSource)))
		{
			this.index = index;
		}
	}
	else
	{
		this.index = index;
	}
	
	// Hides other custom handles
	if (this.index <= mxEvent.CUSTOM_HANDLE && this.index > mxEvent.VIRTUAL_HANDLE)
	{
		if (this.customHandles != null)
		{
			for (var i = 0; i < this.customHandles.length; i++)
			{
				if (i != mxEvent.CUSTOM_HANDLE - this.index)
				{
					this.customHandles[i].setVisible(false);
				}
			}
		}
	}
};

/**
 * Function: clonePreviewState
 * 
 * Returns a clone of the current preview state for the given point and terminal.
 */
mxEdgeHandler.prototype.clonePreviewState = function(point, terminal)
{
	return this.state.clone();
};

/**
 * Function: getSnapToTerminalTolerance
 * 
 * Returns the tolerance for the guides. Default value is
 * gridSize * scale / 2.
 */
mxEdgeHandler.prototype.getSnapToTerminalTolerance = function()
{
	return this.graph.gridSize * this.graph.view.scale / 2;
};

/**
 * Function: updateHint
 * 
 * Hook for subclassers do show details while the handler is active.
 */
mxEdgeHandler.prototype.updateHint = function(me, point) { };

/**
 * Function: removeHint
 * 
 * Hooks for subclassers to hide details when the handler gets inactive.
 */
mxEdgeHandler.prototype.removeHint = function() { };

/**
 * Function: roundLength
 * 
 * Hook for rounding the unscaled width or height. This uses Math.round.
 */
mxEdgeHandler.prototype.roundLength = function(length)
{
	return Math.round(length);
};

/**
 * Function: isSnapToTerminalsEvent
 * 
 * Returns true if <snapToTerminals> is true and if alt is not pressed.
 */
mxEdgeHandler.prototype.isSnapToTerminalsEvent = function(me)
{
	return this.snapToTerminals && !mxEvent.isAltDown(me.getEvent());
};

/**
 * Function: getPointForEvent
 * 
 * Returns the point for the given event.
 */
mxEdgeHandler.prototype.getPointForEvent = function(me)
{
	var view = this.graph.getView();
	var scale = view.scale;
	var point = new mxPoint(this.roundLength(me.getGraphX() / scale) * scale,
		this.roundLength(me.getGraphY() / scale) * scale);
	
	var tt = this.getSnapToTerminalTolerance();
	var overrideX = false;
	var overrideY = false;		
	
	if (tt > 0 && this.isSnapToTerminalsEvent(me))
	{
		function snapToPoint(pt)
		{
			if (pt != null)
			{
				var x = pt.x;

				if (Math.abs(point.x - x) < tt)
				{
					point.x = x;
					overrideX = true;
				}
				
				var y = pt.y;

				if (Math.abs(point.y - y) < tt)
				{
					point.y = y;
					overrideY = true;
				}
			}
		}
		
		// Temporary function
		function snapToTerminal(terminal)
		{
			if (terminal != null)
			{
				snapToPoint.call(this, new mxPoint(view.getRoutingCenterX(terminal),
						view.getRoutingCenterY(terminal)));
			}
		};

		snapToTerminal.call(this, this.state.getVisibleTerminalState(true));
		snapToTerminal.call(this, this.state.getVisibleTerminalState(false));

		if (this.state.absolutePoints != null)
		{
			for (var i = 0; i < this.state.absolutePoints.length; i++)
			{
				snapToPoint.call(this, this.state.absolutePoints[i]);
			}
		}
	}

	if (this.graph.isGridEnabledEvent(me.getEvent()))
	{
		var tr = view.translate;
		
		if (!overrideX)
		{
			point.x = (this.graph.snap(point.x / scale - tr.x) + tr.x) * scale;
		}
		
		if (!overrideY)
		{
			point.y = (this.graph.snap(point.y / scale - tr.y) + tr.y) * scale;
		}
	}
	
	return point;
};

/**
 * Function: getPreviewTerminalState
 * 
 * Updates the given preview state taking into account the state of the constraint handler.
 */
mxEdgeHandler.prototype.getPreviewTerminalState = function(me)
{
	this.constraintHandler.update(me, this.isSource, true, me.isSource(this.marker.highlight.shape) ? null : this.currentPoint);
	
	if (this.constraintHandler.currentFocus != null && this.constraintHandler.currentConstraint != null)
	{
		// Handles special case where grid is large and connection point is at actual point in which
		// case the outline is not followed as long as we're < gridSize / 2 away from that point
		if (this.marker.highlight != null && this.marker.highlight.state != null &&
			this.marker.highlight.state.cell == this.constraintHandler.currentFocus.cell)
		{
			// Direct repaint needed if cell already highlighted
			if (this.marker.highlight.shape.stroke != 'transparent')
			{
				this.marker.highlight.shape.stroke = 'transparent';
				this.marker.highlight.repaint();
			}
		}
		else
		{
			this.marker.markCell(this.constraintHandler.currentFocus.cell, 'transparent');
		}
		
		var model = this.graph.getModel();
		var other = this.graph.view.getTerminalPort(this.state,
				this.graph.view.getState(model.getTerminal(this.state.cell,
			!this.isSource)), !this.isSource);
		var otherCell = (other != null) ? other.cell : null;
		var source = (this.isSource) ? this.constraintHandler.currentFocus.cell : otherCell;
		var target = (this.isSource) ? otherCell : this.constraintHandler.currentFocus.cell;
		
		// Updates the error message of the handler
		this.error = this.validateConnection(source, target);
		var result = null;
		
		if (this.error == null)
		{
			result = this.constraintHandler.currentFocus;
		}
		else
		{
			this.constraintHandler.reset();
		}
		
		return result;
	}
	else if (!this.graph.isIgnoreTerminalEvent(me.getEvent()))
	{
		this.marker.process(me);

		return this.marker.getValidState();
	}
	else
	{
		this.marker.reset();
		
		return null;
	}
};

/**
 * Function: getPreviewPoints
 * 
 * Updates the given preview state taking into account the state of the constraint handler.
 * 
 * Parameters:
 * 
 * pt - <mxPoint> that contains the current pointer position.
 * me - Optional <mxMouseEvent> that contains the current event.
 */
mxEdgeHandler.prototype.getPreviewPoints = function(pt, me)
{
	var geometry = this.graph.getCellGeometry(this.state.cell);
	var points = (geometry.points != null) ? geometry.points.slice() : null;
	var point = new mxPoint(pt.x, pt.y);
	var result = null;
	
	if (!this.isSource && !this.isTarget)
	{
		this.convertPoint(point, false);
		
		if (points == null)
		{
			points = [point];
		}
		else
		{
			// Adds point from virtual bend
			if (this.index <= mxEvent.VIRTUAL_HANDLE)
			{
				points.splice(mxEvent.VIRTUAL_HANDLE - this.index, 0, point);
			}

			// Removes point if dragged on terminal point
			if (!this.isSource && !this.isTarget)
			{
				for (var i = 0; i < this.bends.length; i++)
				{
					if (i != this.index)
					{
						var bend = this.bends[i];
						
						if (bend != null && mxUtils.contains(bend.bounds, pt.x, pt.y))
						{
							if (this.index <= mxEvent.VIRTUAL_HANDLE)
							{
								points.splice(mxEvent.VIRTUAL_HANDLE - this.index, 1);
							}
							else
							{
								points.splice(this.index - 1, 1);
							}
							
							result = points;
						}
					}
				}
				
				// Removes point if user tries to straighten a segment
				if (result == null && this.straightRemoveEnabled && (me == null || !mxEvent.isAltDown(me.getEvent())))
				{
					var tol = this.graph.tolerance * this.graph.tolerance;
					var abs = this.state.absolutePoints.slice();
					abs[this.index] = pt;
					
					// Handes special case where removing waypoint affects tolerance (flickering)
					var src = this.state.getVisibleTerminalState(true);
					
					if (src != null)
					{
						var c = this.graph.getConnectionConstraint(this.state, src, true);
						
						// Checks if point is not fixed
						if (c == null || this.graph.getConnectionPoint(src, c) == null)
						{
							abs[0] = new mxPoint(src.view.getRoutingCenterX(src), src.view.getRoutingCenterY(src));
						}
					}
					
					var trg = this.state.getVisibleTerminalState(false);
					
					if (trg != null)
					{
						var c = this.graph.getConnectionConstraint(this.state, trg, false);
						
						// Checks if point is not fixed
						if (c == null || this.graph.getConnectionPoint(trg, c) == null)
						{
							abs[abs.length - 1] = new mxPoint(trg.view.getRoutingCenterX(trg), trg.view.getRoutingCenterY(trg));
						}
					}

					function checkRemove(idx, tmp)
					{
						if (idx > 0 && idx < abs.length - 1 &&
							mxUtils.ptSegDistSq(abs[idx - 1].x, abs[idx - 1].y,
								abs[idx + 1].x, abs[idx + 1].y, tmp.x, tmp.y) < tol)
						{
							points.splice(idx - 1, 1);
							result = points;
						}
					};
					
					// LATER: Check if other points can be removed if a segment is made straight
					checkRemove(this.index, pt);
				}
			}
			
			// Updates existing point
			if (result == null && this.index > mxEvent.VIRTUAL_HANDLE)
			{
				points[this.index - 1] = point;
			}
		}
	}
	else if (this.graph.resetEdgesOnConnect)
	{
		points = null;
	}
	
	return (result != null) ? result : points;
};

/**
 * Function: isOutlineConnectEvent
 * 
 * Returns true if <outlineConnect> is true and the source of the event is the outline shape
 * or shift is pressed.
 */
mxEdgeHandler.prototype.isOutlineConnectEvent = function(me)
{
	var offset = mxUtils.getOffset(this.graph.container);
	var evt = me.getEvent();
	
	var clientX = mxEvent.getClientX(evt);
	var clientY = mxEvent.getClientY(evt);
	
	var doc = document.documentElement;
	var left = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
	var top = (window.pageYOffset || doc.scrollTop)  - (doc.clientTop || 0);
	
	var gridX = this.currentPoint.x - this.graph.container.scrollLeft + offset.x - left;
	var gridY = this.currentPoint.y - this.graph.container.scrollTop + offset.y - top;

	return this.outlineConnect && !mxEvent.isShiftDown(me.getEvent()) &&
		(me.isSource(this.marker.highlight.shape) ||
		(mxEvent.isAltDown(me.getEvent()) && me.getState() != null) ||
		this.marker.highlight.isHighlightAt(clientX, clientY) ||
		((gridX != clientX || gridY != clientY) && me.getState() == null &&
		this.marker.highlight.isHighlightAt(gridX, gridY)));
};

/**
 * Function: updatePreviewState
 * 
 * Updates the given preview state taking into account the state of the constraint handler.
 */
mxEdgeHandler.prototype.updatePreviewState = function(edge, point, terminalState, me, outline)
{
	// Computes the points for the edge style and terminals
	var sourceState = (this.isSource) ? terminalState : this.state.getVisibleTerminalState(true);
	var targetState = (this.isTarget) ? terminalState : this.state.getVisibleTerminalState(false);
	
	var sourceConstraint = this.graph.getConnectionConstraint(edge, sourceState, true);
	var targetConstraint = this.graph.getConnectionConstraint(edge, targetState, false);

	var constraint = this.constraintHandler.currentConstraint;

	if (constraint == null && outline)
	{
		if (terminalState != null)
		{
			// Handles special case where mouse is on outline away from actual end point
			// in which case the grid is ignored and mouse point is used instead
			if (me.isSource(this.marker.highlight.shape))
			{
				point = new mxPoint(me.getGraphX(), me.getGraphY());
			}
			
			constraint = this.graph.getOutlineConstraint(point, terminalState, me);
			this.constraintHandler.setFocus(me, terminalState, this.isSource);
			this.constraintHandler.currentConstraint = constraint;
			this.constraintHandler.currentPoint = point;
		}
		else
		{
			constraint = new mxConnectionConstraint();
		}
	}
	
	if (this.outlineConnect && this.marker.highlight != null && this.marker.highlight.shape != null)
	{
		var s = this.graph.view.scale;
		
		if (this.constraintHandler.currentConstraint != null &&
			this.constraintHandler.currentFocus != null)
		{
			this.marker.highlight.shape.stroke = (outline) ? mxConstants.OUTLINE_HIGHLIGHT_COLOR : 'transparent';
			this.marker.highlight.shape.strokewidth = mxConstants.OUTLINE_HIGHLIGHT_STROKEWIDTH / s / s;
			this.marker.highlight.repaint();
		}
		else if (this.marker.hasValidState())
		{
			this.marker.highlight.shape.stroke = (this.marker.getValidState() == me.getState()) ?
				mxConstants.DEFAULT_VALID_COLOR : 'transparent';
			this.marker.highlight.shape.strokewidth = mxConstants.HIGHLIGHT_STROKEWIDTH / s / s;
			this.marker.highlight.repaint();
		}
	}
	
	if (this.isSource)
	{
		sourceConstraint = constraint;
	}
	else if (this.isTarget)
	{
		targetConstraint = constraint;
	}
	
	if (this.isSource || this.isTarget)
	{
		if (constraint != null && constraint.point != null)
		{
			edge.style[(this.isSource) ? mxConstants.STYLE_EXIT_X : mxConstants.STYLE_ENTRY_X] = constraint.point.x;
			edge.style[(this.isSource) ? mxConstants.STYLE_EXIT_Y : mxConstants.STYLE_ENTRY_Y] = constraint.point.y;
		}
		else
		{
			delete edge.style[(this.isSource) ? mxConstants.STYLE_EXIT_X : mxConstants.STYLE_ENTRY_X];
			delete edge.style[(this.isSource) ? mxConstants.STYLE_EXIT_Y : mxConstants.STYLE_ENTRY_Y];
		}
	}
	
	edge.setVisibleTerminalState(sourceState, true);
	edge.setVisibleTerminalState(targetState, false);
	
	if (!this.isSource || sourceState != null)
	{
		edge.view.updateFixedTerminalPoint(edge, sourceState, true, sourceConstraint);
	}
	
	if (!this.isTarget || targetState != null)
	{
		edge.view.updateFixedTerminalPoint(edge, targetState, false, targetConstraint);
	}
	
	if ((this.isSource || this.isTarget) && terminalState == null)
	{
		edge.setAbsoluteTerminalPoint(point, this.isSource);

		if (this.marker.getMarkedState() == null)
		{
			this.error = (this.graph.allowDanglingEdges) ? null : '';
		}
	}
	
	edge.view.updatePoints(edge, this.points, sourceState, targetState);
	edge.view.updateFloatingTerminalPoints(edge, sourceState, targetState);
};

/**
 * Function: mouseMove
 * 
 * Handles the event by updating the preview.
 */
mxEdgeHandler.prototype.mouseMove = function(sender, me)
{
	if (this.index != null && this.marker != null)
	{
		this.currentPoint = this.getPointForEvent(me);
		this.error = null;
		
		// Uses the current point from the constraint handler if available
		if (!this.graph.isIgnoreTerminalEvent(me.getEvent()) && mxEvent.isShiftDown(me.getEvent()) && this.snapPoint != null)
		{
			if (Math.abs(this.snapPoint.x - this.currentPoint.x) < Math.abs(this.snapPoint.y - this.currentPoint.y))
			{
				this.currentPoint.x = this.snapPoint.x;
			}
			else
			{
				this.currentPoint.y = this.snapPoint.y;
			}
		}
		
		if (this.index <= mxEvent.CUSTOM_HANDLE && this.index > mxEvent.VIRTUAL_HANDLE)
		{
			if (this.customHandles != null)
			{
				this.customHandles[mxEvent.CUSTOM_HANDLE - this.index].processEvent(me);
			}
		}
		else if (this.isLabel)
		{
			this.label.x = this.currentPoint.x;
			this.label.y = this.currentPoint.y;
		}
		else
		{
			this.points = this.getPreviewPoints(this.currentPoint, me);
			var terminalState = (this.isSource || this.isTarget) ? this.getPreviewTerminalState(me) : null;

			if (this.constraintHandler.currentConstraint != null &&
				this.constraintHandler.currentFocus != null &&
				this.constraintHandler.currentPoint != null)
			{
				this.currentPoint = this.constraintHandler.currentPoint.clone();
			}
			else if (this.outlineConnect)
			{
				// Need to check outline before cloning terminal state
				var outline = (this.isSource || this.isTarget) ? this.isOutlineConnectEvent(me) : false
						
				if (outline)
				{
					terminalState = this.marker.highlight.state;
				}
				else if (terminalState != null && terminalState != me.getState() && this.marker.highlight.shape != null)
				{
					this.marker.highlight.shape.stroke = 'transparent';
					this.marker.highlight.repaint();
					terminalState = null;
				}
			}
			
			var clone = this.clonePreviewState(this.currentPoint, (terminalState != null) ? terminalState.cell : null);
			this.updatePreviewState(clone, this.currentPoint, terminalState, me, outline);

			// Sets the color of the preview to valid or invalid, updates the
			// points of the preview and redraws
			var color = (this.error == null) ? this.marker.validColor : this.marker.invalidColor;
			this.setPreviewColor(color);
			this.abspoints = clone.absolutePoints;
			this.active = true;
		}

		// This should go before calling isOutlineConnectEvent above. As a workaround
		// we add an offset of gridSize to the hint to avoid problem with hit detection
		// in highlight.isHighlightAt (which uses comonentFromPoint)
		this.updateHint(me, this.currentPoint);
		this.drawPreview();
		mxEvent.consume(me.getEvent());
		me.consume();
	}
	// Workaround for disabling the connect highlight when over handle
	else if (mxClient.IS_IE && this.getHandleForEvent(me) != null)
	{
		me.consume(false);
	}
};

/**
 * Function: mouseUp
 * 
 * Handles the event to applying the previewed changes on the edge by
 * using <moveLabel>, <connect> or <changePoints>.
 */
mxEdgeHandler.prototype.mouseUp = function(sender, me)
{
	// Workaround for wrong event source in Webkit
	if (this.index != null && this.marker != null)
	{
		var edge = this.state.cell;
		
		// Ignores event if mouse has not been moved
		if (me.getX() != this.startX || me.getY() != this.startY)
		{
			var clone = !this.graph.isIgnoreTerminalEvent(me.getEvent()) && this.graph.isCloneEvent(me.getEvent()) &&
				this.cloneEnabled && this.graph.isCellsCloneable();
			
			// Displays the reason for not carriying out the change
			// if there is an error message with non-zero length
			if (this.error != null)
			{
				if (this.error.length > 0)
				{
					this.graph.validationAlert(this.error);
				}
			}
			else if (this.index <= mxEvent.CUSTOM_HANDLE && this.index > mxEvent.VIRTUAL_HANDLE)
			{
				if (this.customHandles != null)
				{
					var model = this.graph.getModel();
					
					model.beginUpdate();
					try
					{
						this.customHandles[mxEvent.CUSTOM_HANDLE - this.index].execute();
					}
					finally
					{
						model.endUpdate();
					}
				}
			}
			else if (this.isLabel)
			{
				this.moveLabel(this.state, this.label.x, this.label.y);
			}
			else if (this.isSource || this.isTarget)
			{
				var terminal = null;
				
				if (this.constraintHandler.currentConstraint != null &&
					this.constraintHandler.currentFocus != null)
				{
					terminal = this.constraintHandler.currentFocus.cell;
				}
				
				if (terminal == null && this.marker.hasValidState() && this.marker.highlight != null &&
					this.marker.highlight.shape != null &&
					this.marker.highlight.shape.stroke != 'transparent' &&
					this.marker.highlight.shape.stroke != 'white')
				{
					terminal = this.marker.validState.cell;
				}
				
				if (terminal != null)
				{
					edge = this.connect(edge, terminal, this.isSource, clone, me);
				}
				else if (this.graph.isAllowDanglingEdges())
				{
					var pt = this.abspoints[(this.isSource) ? 0 : this.abspoints.length - 1];
					pt.x = this.roundLength(pt.x / this.graph.view.scale - this.graph.view.translate.x);
					pt.y = this.roundLength(pt.y / this.graph.view.scale - this.graph.view.translate.y);

					var pstate = this.graph.getView().getState(
							this.graph.getModel().getParent(edge));
							
					if (pstate != null)
					{
						pt.x -= pstate.origin.x;
						pt.y -= pstate.origin.y;
					}
					
					pt.x -= this.graph.panDx / this.graph.view.scale;
					pt.y -= this.graph.panDy / this.graph.view.scale;
										
					// Destroys and recreates this handler
					edge = this.changeTerminalPoint(edge, pt, this.isSource, clone);
				}
			}
			else if (this.active)
			{
				edge = this.changePoints(edge, this.points, clone);
			}
			else
			{
				this.graph.getView().invalidate(this.state.cell);
				this.graph.getView().validate(this.state.cell);						
			}
		}
		
		// Resets the preview color the state of the handler if this
		// handler has not been recreated
		if (this.marker != null)
		{
			this.reset();

			// Updates the selection if the edge has been cloned
			if (edge != this.state.cell)
			{
				this.graph.setSelectionCell(edge);
			}
		}

		me.consume();
	}
};

/**
 * Function: reset
 * 
 * Resets the state of this handler.
 */
mxEdgeHandler.prototype.reset = function()
{
	this.error = null;
	this.index = null;
	this.label = null;
	this.points = null;
	this.snapPoint = null;
	this.active = false;
	this.isLabel = false;
	this.isSource = false;
	this.isTarget = false;
	
	if (this.livePreview && this.sizers != null)
	{
		for (var i = 0; i < this.sizers.length; i++)
		{
			if (this.sizers[i] != null)
			{
				this.sizers[i].node.style.display = '';
			}
		}
	}

	if (this.marker != null)
	{
		this.marker.reset();
	}
	
	if (this.constraintHandler != null)
	{
		this.constraintHandler.reset();
	}
	
	if (this.customHandles != null)
	{
		for (var i = 0; i < this.customHandles.length; i++)
		{
			this.customHandles[i].reset();
		}
	}

	this.setPreviewColor(mxConstants.EDGE_SELECTION_COLOR);
	this.removeHint();
	this.redraw();
};

/**
 * Function: setPreviewColor
 * 
 * Sets the color of the preview to the given value.
 */
mxEdgeHandler.prototype.setPreviewColor = function(color)
{
	if (this.shape != null)
	{
		this.shape.stroke = color;
	}
};


/**
 * Function: convertPoint
 * 
 * Converts the given point in-place from screen to unscaled, untranslated
 * graph coordinates and applies the grid. Returns the given, modified
 * point instance.
 * 
 * Parameters:
 * 
 * point - <mxPoint> to be converted.
 * gridEnabled - Boolean that specifies if the grid should be applied.
 */
mxEdgeHandler.prototype.convertPoint = function(point, gridEnabled)
{
	var scale = this.graph.getView().getScale();
	var tr = this.graph.getView().getTranslate();
		
	if (gridEnabled)
	{
		point.x = this.graph.snap(point.x);
		point.y = this.graph.snap(point.y);
	}
	
	point.x = Math.round(point.x / scale - tr.x);
	point.y = Math.round(point.y / scale - tr.y);

	var pstate = this.graph.getView().getState(
		this.graph.getModel().getParent(this.state.cell));

	if (pstate != null)
	{
		point.x -= pstate.origin.x;
		point.y -= pstate.origin.y;
	}

	return point;
};

/**
 * Function: moveLabel
 * 
 * Changes the coordinates for the label of the given edge.
 * 
 * Parameters:
 * 
 * edge - <mxCell> that represents the edge.
 * x - Integer that specifies the x-coordinate of the new location.
 * y - Integer that specifies the y-coordinate of the new location.
 */
mxEdgeHandler.prototype.moveLabel = function(edgeState, x, y)
{
	var model = this.graph.getModel();
	var geometry = model.getGeometry(edgeState.cell);
	
	if (geometry != null)
	{
		var scale = this.graph.getView().scale;
		geometry = geometry.clone();
		
		if (geometry.relative)
		{
			// Resets the relative location stored inside the geometry
			var pt = this.graph.getView().getRelativePoint(edgeState, x, y);
			geometry.x = Math.round(pt.x * 10000) / 10000;
			geometry.y = Math.round(pt.y);
			
			// Resets the offset inside the geometry to find the offset
			// from the resulting point
			geometry.offset = new mxPoint(0, 0);
			var pt = this.graph.view.getPoint(edgeState, geometry);
			geometry.offset = new mxPoint(Math.round((x - pt.x) / scale), Math.round((y - pt.y) / scale));
		}
		else
		{
			var points = edgeState.absolutePoints;
			var p0 = points[0];
			var pe = points[points.length - 1];
			
			if (p0 != null && pe != null)
			{
				var cx = p0.x + (pe.x - p0.x) / 2;
				var cy = p0.y + (pe.y - p0.y) / 2;
				
				geometry.offset = new mxPoint(Math.round((x - cx) / scale), Math.round((y - cy) / scale));
				geometry.x = 0;
				geometry.y = 0;
			}
		}

		model.setGeometry(edgeState.cell, geometry);
	}
};

/**
 * Function: connect
 * 
 * Changes the terminal or terminal point of the given edge in the graph
 * model.
 * 
 * Parameters:
 * 
 * edge - <mxCell> that represents the edge to be reconnected.
 * terminal - <mxCell> that represents the new terminal.
 * isSource - Boolean indicating if the new terminal is the source or
 * target terminal.
 * isClone - Boolean indicating if the new connection should be a clone of
 * the old edge.
 * me - <mxMouseEvent> that contains the mouse up event.
 */
mxEdgeHandler.prototype.connect = function(edge, terminal, isSource, isClone, me)
{
	var model = this.graph.getModel();
	var parent = model.getParent(edge);
	
	model.beginUpdate();
	try
	{
		// Clones and adds the cell
		if (isClone)
		{
			var clone = this.graph.cloneCells([edge])[0];
			model.add(parent, clone, model.getChildCount(parent));
			
			var other = model.getTerminal(edge, !isSource);
			this.graph.connectCell(clone, other, !isSource);
			
			edge = clone;
		}

		var constraint = this.constraintHandler.currentConstraint;
		
		if (constraint == null)
		{
			constraint = new mxConnectionConstraint();
		}

		this.graph.connectCell(edge, terminal, isSource, constraint);
	}
	finally
	{
		model.endUpdate();
	}
	
	return edge;
};

/**
 * Function: changeTerminalPoint
 * 
 * Changes the terminal point of the given edge.
 */
mxEdgeHandler.prototype.changeTerminalPoint = function(edge, point, isSource, clone)
{
	var model = this.graph.getModel();

	model.beginUpdate();
	try
	{
		if (clone)
		{
			var parent = model.getParent(edge);
			var terminal = model.getTerminal(edge, !isSource);
			edge = this.graph.cloneCells([edge])[0];
			model.add(parent, edge, model.getChildCount(parent));
			model.setTerminal(edge, terminal, !isSource);
		}

		var geo = model.getGeometry(edge);
		
		if (geo != null)
		{
			geo = geo.clone();
			geo.setTerminalPoint(point, isSource);
			model.setGeometry(edge, geo);
			this.graph.connectCell(edge, null, isSource, new mxConnectionConstraint());
		}
	}
	finally
	{
		model.endUpdate();
	}
	
	return edge;
};

/**
 * Function: changePoints
 * 
 * Changes the control points of the given edge in the graph model.
 */
mxEdgeHandler.prototype.changePoints = function(edge, points, clone)
{
	var model = this.graph.getModel();
	model.beginUpdate();
	try
	{
		if (clone)
		{
			var parent = model.getParent(edge);
			var source = model.getTerminal(edge, true);
			var target = model.getTerminal(edge, false);
			edge = this.graph.cloneCells([edge])[0];
			model.add(parent, edge, model.getChildCount(parent));
			model.setTerminal(edge, source, true);
			model.setTerminal(edge, target, false);
		}
		
		var geo = model.getGeometry(edge);
		
		if (geo != null)
		{
			geo = geo.clone();
			geo.points = points;
			
			model.setGeometry(edge, geo);
		}
	}
	finally
	{
		model.endUpdate();
	}
	
	return edge;
};

/**
 * Function: addPoint
 * 
 * Adds a control point for the given state and event.
 */
mxEdgeHandler.prototype.addPoint = function(state, evt)
{
	var pt = mxUtils.convertPoint(this.graph.container, mxEvent.getClientX(evt),
			mxEvent.getClientY(evt));
	var gridEnabled = this.graph.isGridEnabledEvent(evt);
	this.convertPoint(pt, gridEnabled);
	this.addPointAt(state, pt.x, pt.y);
	mxEvent.consume(evt);
};

/**
 * Function: addPointAt
 * 
 * Adds a control point at the given point.
 */
mxEdgeHandler.prototype.addPointAt = function(state, x, y)
{
	var geo = this.graph.getCellGeometry(state.cell);
	var pt = new mxPoint(x, y);
	
	if (geo != null)
	{
		geo = geo.clone();
		var t = this.graph.view.translate;
		var s = this.graph.view.scale;
		var offset = new mxPoint(t.x * s, t.y * s);
		
		var parent = this.graph.model.getParent(this.state.cell);
		
		if (this.graph.model.isVertex(parent))
		{
			var pState = this.graph.view.getState(parent);
			offset = new mxPoint(pState.x, pState.y);
		}
		
		var index = mxUtils.findNearestSegment(state, pt.x * s + offset.x, pt.y * s + offset.y);

		if (geo.points == null)
		{
			geo.points = [pt];
		}
		else
		{
			geo.points.splice(index, 0, pt);
		}
		
		this.graph.getModel().setGeometry(state.cell, geo);
		this.refresh();	
		this.redraw();
	}
};

/**
 * Function: removePoint
 * 
 * Removes the control point at the given index from the given state.
 */
mxEdgeHandler.prototype.removePoint = function(state, index)
{
	if (index > 0 && index < this.abspoints.length - 1)
	{
		var geo = this.graph.getCellGeometry(this.state.cell);
		
		if (geo != null && geo.points != null)
		{
			geo = geo.clone();
			geo.points.splice(index - 1, 1);
			this.graph.getModel().setGeometry(state.cell, geo);
			this.refresh();
			this.redraw();
		}
	}
};

/**
 * Function: getHandleFillColor
 * 
 * Returns the fillcolor for the handle at the given index.
 */
mxEdgeHandler.prototype.getHandleFillColor = function(index)
{
	var isSource = index == 0;
	var cell = this.state.cell;
	var terminal = this.graph.getModel().getTerminal(cell, isSource);
	var color = mxConstants.HANDLE_FILLCOLOR;
	
	if ((terminal != null && !this.graph.isCellDisconnectable(cell, terminal, isSource)) ||
		(terminal == null && !this.graph.isTerminalPointMovable(cell, isSource)))
	{
		color = mxConstants.LOCKED_HANDLE_FILLCOLOR;
	}
	else if (terminal != null && this.graph.isCellDisconnectable(cell, terminal, isSource))
	{
		color = mxConstants.CONNECT_HANDLE_FILLCOLOR;
	}
	
	return color;
};

/**
 * Function: redraw
 * 
 * Redraws the preview, and the bends- and label control points.
 */
mxEdgeHandler.prototype.redraw = function()
{
	this.abspoints = this.state.absolutePoints.slice();
	this.redrawHandles();
	
	var g = this.graph.getModel().getGeometry(this.state.cell);
	var pts = g.points;

	if (this.bends != null && this.bends.length > 0)
	{
		if (pts != null)
		{
			if (this.points == null)
			{
				this.points = [];
			}
			
			for (var i = 1; i < this.bends.length - 1; i++)
			{
				if (this.bends[i] != null && this.abspoints[i] != null)
				{
					this.points[i - 1] = pts[i - 1];
				}
			}
		}
	}

	this.drawPreview();
};

/**
 * Function: redrawHandles
 * 
 * Redraws the handles.
 */
mxEdgeHandler.prototype.redrawHandles = function()
{
	var cell = this.state.cell;

	// Updates the handle for the label position
	var b = this.labelShape.bounds;
	this.label = new mxPoint(this.state.absoluteOffset.x, this.state.absoluteOffset.y);
	this.labelShape.bounds = new mxRectangle(Math.round(this.label.x - b.width / 2),
		Math.round(this.label.y - b.height / 2), b.width, b.height);

	// Shows or hides the label handle depending on the label
	var lab = this.graph.getLabel(cell);
	this.labelShape.visible = (lab != null && lab.length > 0 && this.graph.isLabelMovable(cell));
	
	if (this.bends != null && this.bends.length > 0)
	{
		var n = this.abspoints.length - 1;
		
		var p0 = this.abspoints[0];
		var x0 = p0.x;
		var y0 = p0.y;
		
		b = this.bends[0].bounds;
		this.bends[0].bounds = new mxRectangle(Math.floor(x0 - b.width / 2),
				Math.floor(y0 - b.height / 2), b.width, b.height);
		this.bends[0].fill = this.getHandleFillColor(0);
		this.bends[0].redraw();
		
		if (this.manageLabelHandle)
		{
			this.checkLabelHandle(this.bends[0].bounds);
		}
				
		var pe = this.abspoints[n];
		var xn = pe.x;
		var yn = pe.y;
		
		var bn = this.bends.length - 1;
		b = this.bends[bn].bounds;
		this.bends[bn].bounds = new mxRectangle(Math.floor(xn - b.width / 2),
				Math.floor(yn - b.height / 2), b.width, b.height);
		this.bends[bn].fill = this.getHandleFillColor(bn);
		this.bends[bn].redraw();
				
		if (this.manageLabelHandle)
		{
			this.checkLabelHandle(this.bends[bn].bounds);
		}
		
		this.redrawInnerBends(p0, pe);
	}

	if (this.abspoints != null && this.virtualBends != null && this.virtualBends.length > 0)
	{
		var last = this.abspoints[0];
		
		for (var i = 0; i < this.virtualBends.length; i++)
		{
			if (this.virtualBends[i] != null && this.abspoints[i + 1] != null)
			{
				var pt = this.abspoints[i + 1];
				var b = this.virtualBends[i];
				var x = last.x + (pt.x - last.x) / 2;
				var y = last.y + (pt.y - last.y) / 2;
				b.bounds = new mxRectangle(Math.floor(x - b.bounds.width / 2),
						Math.floor(y - b.bounds.height / 2), b.bounds.width, b.bounds.height);
				b.redraw();
				mxUtils.setOpacity(b.node, this.virtualBendOpacity);
				last = pt;
				
				if (this.manageLabelHandle)
				{
					this.checkLabelHandle(b.bounds);
				}
			}
		}
	}
	
	if (this.labelShape != null)
	{
		this.labelShape.redraw();
	}
	
	if (this.customHandles != null)
	{
		for (var i = 0; i < this.customHandles.length; i++)
		{
			this.customHandles[i].redraw();
		}
	}
};

/**
 * Function: hideHandles
 * 
 * Shortcut to <hideSizers>.
 */
mxEdgeHandler.prototype.setHandlesVisible = function(visible)
{
	if (this.bends != null)
	{
		for (var i = 0; i < this.bends.length; i++)
		{
			this.bends[i].node.style.display = (visible) ? '' : 'none';
		}
	}
	
	if (this.virtualBends != null)
	{
		for (var i = 0; i < this.virtualBends.length; i++)
		{
			this.virtualBends[i].node.style.display = (visible) ? '' : 'none';
		}
	}

	if (this.labelShape != null)
	{
		this.labelShape.node.style.display = (visible) ? '' : 'none';
	}
	
	if (this.customHandles != null)
	{
		for (var i = 0; i < this.customHandles.length; i++)
		{
			this.customHandles[i].setVisible(visible);
		}
	}
};

/**
 * Function: redrawInnerBends
 * 
 * Updates and redraws the inner bends.
 * 
 * Parameters:
 * 
 * p0 - <mxPoint> that represents the location of the first point.
 * pe - <mxPoint> that represents the location of the last point.
 */
mxEdgeHandler.prototype.redrawInnerBends = function(p0, pe)
{
	for (var i = 1; i < this.bends.length - 1; i++)
	{
		if (this.bends[i] != null)
		{
			if (this.abspoints[i] != null)
			{
				var x = this.abspoints[i].x;
				var y = this.abspoints[i].y;
				
				var b = this.bends[i].bounds;
				this.bends[i].node.style.visibility = 'visible';
				this.bends[i].bounds = new mxRectangle(Math.round(x - b.width / 2),
						Math.round(y - b.height / 2), b.width, b.height);
				
				if (this.manageLabelHandle)
				{
					this.checkLabelHandle(this.bends[i].bounds);
				}
				else if (this.handleImage == null && this.labelShape.visible && mxUtils.intersects(this.bends[i].bounds, this.labelShape.bounds))
				{
					w = mxConstants.HANDLE_SIZE + 3;
					h = mxConstants.HANDLE_SIZE + 3;
					this.bends[i].bounds = new mxRectangle(Math.round(x - w / 2), Math.round(y - h / 2), w, h);
				}
				
				this.bends[i].redraw();
			}
			else
			{
				this.bends[i].destroy();
				this.bends[i] = null;
			}
		}
	}
};

/**
 * Function: checkLabelHandle
 * 
 * Checks if the label handle intersects the given bounds and moves it if it
 * intersects.
 */
mxEdgeHandler.prototype.checkLabelHandle = function(b)
{
	if (this.labelShape != null)
	{
		var b2 = this.labelShape.bounds;
		
		if (mxUtils.intersects(b, b2))
		{
			if (b.getCenterY() < b2.getCenterY())
			{
				b2.y = b.y + b.height;
			}
			else
			{
				b2.y = b.y - b2.height;
			}
		}
	}
};

/**
 * Function: drawPreview
 * 
 * Redraws the preview.
 */
mxEdgeHandler.prototype.drawPreview = function()
{
	if (this.isLabel)
	{
		var b = this.labelShape.bounds;
		var bounds = new mxRectangle(Math.round(this.label.x - b.width / 2),
				Math.round(this.label.y - b.height / 2), b.width, b.height);
		this.labelShape.bounds = bounds;
		this.labelShape.redraw();
	}
	else if (this.shape != null)
	{
		this.shape.apply(this.state);
		this.shape.points = this.abspoints;
		this.shape.scale = this.state.view.scale;
		this.shape.isDashed = this.isSelectionDashed();
		this.shape.stroke = this.getSelectionColor();
		this.shape.strokewidth = this.getSelectionStrokeWidth() / this.shape.scale / this.shape.scale;
		this.shape.isShadow = false;
		this.shape.redraw();
	}
	
	if (this.parentHighlight != null)
	{
		this.parentHighlight.redraw();
	}
};

/**
 * Function: refresh
 * 
 * Refreshes the bends of this handler.
 */
mxEdgeHandler.prototype.refresh = function()
{
	this.abspoints = this.getSelectionPoints(this.state);
	this.points = [];

	if (this.shape != null)
	{
		this.shape.points = this.abspoints;
	}
	
	if (this.bends != null)
	{
		this.destroyBends(this.bends);
		this.bends = this.createBends();
	}
	
	if (this.virtualBends != null)
	{
		this.destroyBends(this.virtualBends);
		this.virtualBends = this.createVirtualBends();
	}
	
	if (this.customHandles != null)
	{
		this.destroyBends(this.customHandles);
		this.customHandles = this.createCustomHandles();
	}
	
	// Puts label node on top of bends
	if (this.labelShape != null && this.labelShape.node != null && this.labelShape.node.parentNode != null)
	{
		this.labelShape.node.parentNode.appendChild(this.labelShape.node);
	}
};

/**
 * Function: destroyBends
 * 
 * Destroys all elements in <bends>.
 */
mxEdgeHandler.prototype.destroyBends = function(bends)
{
	if (bends != null)
	{
		for (var i = 0; i < bends.length; i++)
		{
			if (bends[i] != null)
			{
				bends[i].destroy();
			}
		}
	}
};

/**
 * Function: destroy
 * 
 * Destroys the handler and all its resources and DOM nodes. This does
 * normally not need to be called as handlers are destroyed automatically
 * when the corresponding cell is deselected.
 */
mxEdgeHandler.prototype.destroy = function()
{
	if (this.escapeHandler != null)
	{
		this.state.view.graph.removeListener(this.escapeHandler);
		this.escapeHandler = null;
	}
	
	if (this.marker != null)
	{
		this.marker.destroy();
		this.marker = null;
	}
	
	if (this.shape != null)
	{
		this.shape.destroy();
		this.shape = null;
	}
	
	if (this.parentHighlight != null)
	{
		this.parentHighlight.destroy();
		this.parentHighlight = null;
	}
	
	if (this.labelShape != null)
	{
		this.labelShape.destroy();
		this.labelShape = null;
	}

	if (this.constraintHandler != null)
	{
		this.constraintHandler.destroy();
		this.constraintHandler = null;
	}
	
	this.destroyBends(this.virtualBends);
	this.virtualBends = null;
	
	this.destroyBends(this.customHandles);
	this.customHandles = null;

	this.destroyBends(this.bends);
	this.bends = null;
	
	this.removeHint();
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxElbowEdgeHandler
 *
 * Graph event handler that reconnects edges and modifies control points and
 * the edge label location. Uses <mxTerminalMarker> for finding and
 * highlighting new source and target vertices. This handler is automatically
 * created in <mxGraph.createHandler>. It extends <mxEdgeHandler>.
 * 
 * Constructor: mxEdgeHandler
 *
 * Constructs an edge handler for the specified <mxCellState>.
 * 
 * Parameters:
 * 
 * state - <mxCellState> of the cell to be modified.
 */
function mxElbowEdgeHandler(state)
{
	mxEdgeHandler.call(this, state);
};

/**
 * Extends mxEdgeHandler.
 */
mxUtils.extend(mxElbowEdgeHandler, mxEdgeHandler);

/**
 * Specifies if a double click on the middle handle should call
 * <mxGraph.flipEdge>. Default is true.
 */
mxElbowEdgeHandler.prototype.flipEnabled = true;

/**
 * Variable: doubleClickOrientationResource
 * 
 * Specifies the resource key for the tooltip to be displayed on the single
 * control point for routed edges. If the resource for this key does not
 * exist then the value is used as the error message. Default is
 * 'doubleClickOrientation'.
 */
mxElbowEdgeHandler.prototype.doubleClickOrientationResource =
	(mxClient.language != 'none') ? 'doubleClickOrientation' : '';

/**
 * Function: createBends
 * 
 * Overrides <mxEdgeHandler.createBends> to create custom bends.
 */
 mxElbowEdgeHandler.prototype.createBends = function()
 {
	var bends = [];
	
	// Source
	var bend = this.createHandleShape(0);
	this.initBend(bend);
	bend.setCursor(mxConstants.CURSOR_TERMINAL_HANDLE);
	bends.push(bend);

	// Virtual
	bends.push(this.createVirtualBend(mxUtils.bind(this, function(evt)
	{
		if (!mxEvent.isConsumed(evt) && this.flipEnabled)
		{
			this.graph.flipEdge(this.state.cell, evt);
			mxEvent.consume(evt);
		}
	})));
	this.points.push(new mxPoint(0,0));

	// Target
	bend = this.createHandleShape(2);
	this.initBend(bend);
	bend.setCursor(mxConstants.CURSOR_TERMINAL_HANDLE);
	bends.push(bend);
	
	return bends;
 };

/**
 * Function: createVirtualBend
 * 
 * Creates a virtual bend that supports double clicking and calls
 * <mxGraph.flipEdge>.
 */
mxElbowEdgeHandler.prototype.createVirtualBend = function(dblClickHandler)
{
	var bend = this.createHandleShape();
	this.initBend(bend, dblClickHandler);

	bend.setCursor(this.getCursorForBend());

	if (!this.graph.isCellBendable(this.state.cell))
	{
		bend.node.style.display = 'none';
	}

	return bend;
};

/**
 * Function: getCursorForBend
 * 
 * Returns the cursor to be used for the bend.
 */
mxElbowEdgeHandler.prototype.getCursorForBend = function()
{
	return (this.state.style[mxConstants.STYLE_EDGE] == mxEdgeStyle.TopToBottom ||
		this.state.style[mxConstants.STYLE_EDGE] == mxConstants.EDGESTYLE_TOPTOBOTTOM ||
		((this.state.style[mxConstants.STYLE_EDGE] == mxEdgeStyle.ElbowConnector ||
		this.state.style[mxConstants.STYLE_EDGE] == mxConstants.EDGESTYLE_ELBOW)&&
		this.state.style[mxConstants.STYLE_ELBOW] == mxConstants.ELBOW_VERTICAL)) ? 
		'row-resize' : 'col-resize';
};

/**
 * Function: getTooltipForNode
 * 
 * Returns the tooltip for the given node.
 */
mxElbowEdgeHandler.prototype.getTooltipForNode = function(node)
{
	var tip = null;
	
	if (this.bends != null && this.bends[1] != null && (node == this.bends[1].node ||
		node.parentNode == this.bends[1].node))
	{
		tip = this.doubleClickOrientationResource;
		tip = mxResources.get(tip) || tip; // translate
	}

	return tip;
};

/**
 * Function: convertPoint
 * 
 * Converts the given point in-place from screen to unscaled, untranslated
 * graph coordinates and applies the grid.
 * 
 * Parameters:
 * 
 * point - <mxPoint> to be converted.
 * gridEnabled - Boolean that specifies if the grid should be applied.
 */
mxElbowEdgeHandler.prototype.convertPoint = function(point, gridEnabled)
{
	var scale = this.graph.getView().getScale();
	var tr = this.graph.getView().getTranslate();
	var origin = this.state.origin;
	
	if (gridEnabled)
	{
		point.x = this.graph.snap(point.x);
		point.y = this.graph.snap(point.y);
	}
	
	point.x = Math.round(point.x / scale - tr.x - origin.x);
	point.y = Math.round(point.y / scale - tr.y - origin.y);
	
	return point;
};

/**
 * Function: redrawInnerBends
 * 
 * Updates and redraws the inner bends.
 * 
 * Parameters:
 * 
 * p0 - <mxPoint> that represents the location of the first point.
 * pe - <mxPoint> that represents the location of the last point.
 */
mxElbowEdgeHandler.prototype.redrawInnerBends = function(p0, pe)
{
	var g = this.graph.getModel().getGeometry(this.state.cell);
	var pts = this.state.absolutePoints;
	var pt = null;

	// Keeps the virtual bend on the edge shape
	if (pts.length > 1)
	{
		p0 = pts[1];
		pe = pts[pts.length - 2];
	}
	else if (g.points != null && g.points.length > 0)
	{
		pt = pts[0];
	}
	
	if (pt == null)
	{
		pt = new mxPoint(p0.x + (pe.x - p0.x) / 2, p0.y + (pe.y - p0.y) / 2);
	}
	else
	{
		pt = new mxPoint(this.graph.getView().scale * (pt.x + this.graph.getView().translate.x + this.state.origin.x),
				this.graph.getView().scale * (pt.y + this.graph.getView().translate.y + this.state.origin.y));
	}

	// Makes handle slightly bigger if the yellow  label handle
	// exists and intersects this green handle
	var b = this.bends[1].bounds;
	var w = b.width;
	var h = b.height;
	var bounds = new mxRectangle(Math.round(pt.x - w / 2), Math.round(pt.y - h / 2), w, h);

	if (this.manageLabelHandle)
	{
		this.checkLabelHandle(bounds);
	}
	else if (this.handleImage == null && this.labelShape.visible && mxUtils.intersects(bounds, this.labelShape.bounds))
	{
		w = mxConstants.HANDLE_SIZE + 3;
		h = mxConstants.HANDLE_SIZE + 3;
		bounds = new mxRectangle(Math.floor(pt.x - w / 2), Math.floor(pt.y - h / 2), w, h);
	}

	this.bends[1].bounds = bounds;
	this.bends[1].redraw();
	
	if (this.manageLabelHandle)
	{
		this.checkLabelHandle(this.bends[1].bounds);
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
function mxEdgeSegmentHandler(state)
{
	mxEdgeHandler.call(this, state);
};

/**
 * Extends mxEdgeHandler.
 */
mxUtils.extend(mxEdgeSegmentHandler, mxElbowEdgeHandler);

/**
 * Function: getCurrentPoints
 * 
 * Returns the current absolute points.
 */
mxEdgeSegmentHandler.prototype.getCurrentPoints = function()
{
	var pts = this.state.absolutePoints;
	
	if (pts != null)
	{
		// Special case for straight edges where we add a virtual middle handle for moving the edge
		if (pts.length == 2 || (pts.length == 3 && (pts[0].x == pts[1].x && pts[1].x == pts[2].x ||
				pts[0].y == pts[1].y && pts[1].y == pts[2].y)))
		{
			var cx = pts[0].x + (pts[pts.length - 1].x - pts[0].x) / 2;
			var cy = pts[0].y + (pts[pts.length - 1].y - pts[0].y) / 2;
			
			pts = [pts[0], new mxPoint(cx, cy), new mxPoint(cx, cy), pts[pts.length - 1]];	
		}
	}

	return pts;
};

/**
 * Function: getPreviewPoints
 * 
 * Updates the given preview state taking into account the state of the constraint handler.
 */
mxEdgeSegmentHandler.prototype.getPreviewPoints = function(point)
{
	if (this.isSource || this.isTarget)
	{
		return mxElbowEdgeHandler.prototype.getPreviewPoints.apply(this, arguments);
	}
	else
	{
		var pts = this.getCurrentPoints();
		var last = this.convertPoint(pts[0].clone(), false);
		point = this.convertPoint(point.clone(), false);
		var result = [];

		for (var i = 1; i < pts.length; i++)
		{
			var pt = this.convertPoint(pts[i].clone(), false);
			
			if (i == this.index)
			{
				if (Math.round(last.x - pt.x) == 0)
		 		{
					last.x = point.x;
					pt.x = point.x;
		 		}
		 		
				if (Math.round(last.y - pt.y) == 0)
		 		{
		 			last.y = point.y;
		 			pt.y = point.y;
		 		}
			}

			if (i < pts.length - 1)
			{
				result.push(pt);
			}

			last = pt;
		}
		
		// Replaces single point that intersects with source or target
		if (result.length == 1)
		{
			var source = this.state.getVisibleTerminalState(true);
			var target = this.state.getVisibleTerminalState(false);
			var scale = this.state.view.getScale();
			var tr = this.state.view.getTranslate();
			
			var x = result[0].x * scale + tr.x;
			var y = result[0].y * scale + tr.y;
			
			if ((source != null && mxUtils.contains(source, x, y)) ||
				(target != null && mxUtils.contains(target, x, y)))
			{
				result = [point, point];
			}
		}

		return result;
	}
};

/**
 * Function: updatePreviewState
 * 
 * Overridden to perform optimization of the edge style result.
 */
mxEdgeSegmentHandler.prototype.updatePreviewState = function(edge, point, terminalState, me)
{
	mxEdgeHandler.prototype.updatePreviewState.apply(this, arguments);

	// Checks and corrects preview by running edge style again
	if (!this.isSource && !this.isTarget)
	{
		point = this.convertPoint(point.clone(), false);
		var pts = edge.absolutePoints;
		var pt0 = pts[0];
		var pt1 = pts[1];

		var result = [];
		
		for (var i = 2; i < pts.length; i++)
		{
			var pt2 = pts[i];
		
			// Merges adjacent segments only if more than 2 to allow for straight edges
			if ((Math.round(pt0.x - pt1.x) != 0 || Math.round(pt1.x - pt2.x) != 0) &&
				(Math.round(pt0.y - pt1.y) != 0 || Math.round(pt1.y - pt2.y) != 0))
			{
				result.push(this.convertPoint(pt1.clone(), false));
			}

			pt0 = pt1;
			pt1 = pt2;
		}
		
		var source = this.state.getVisibleTerminalState(true);
		var target = this.state.getVisibleTerminalState(false);
		var rpts = this.state.absolutePoints;
		
		// A straight line is represented by 3 handles
		if (result.length == 0 && (Math.round(pts[0].x - pts[pts.length - 1].x) == 0 ||
			Math.round(pts[0].y - pts[pts.length - 1].y) == 0))
		{
			result = [point, point];
		}
		// Handles special case of transitions from straight vertical to routed
		else if (pts.length == 5 && result.length == 2 && source != null && target != null &&
				rpts != null && Math.round(rpts[0].x - rpts[rpts.length - 1].x) == 0)
		{
			var view = this.graph.getView();
			var scale = view.getScale();
			var tr = view.getTranslate();
			
			var y0 = view.getRoutingCenterY(source) / scale - tr.y;
			
			// Use fixed connection point y-coordinate if one exists
			var sc = this.graph.getConnectionConstraint(edge, source, true);
			
			if (sc != null)
			{
				var pt = this.graph.getConnectionPoint(source, sc);
				
				if (pt != null)
				{
					this.convertPoint(pt, false);
					y0 = pt.y;
				}
			}
			
			var ye = view.getRoutingCenterY(target) / scale - tr.y;
			
			// Use fixed connection point y-coordinate if one exists
			var tc = this.graph.getConnectionConstraint(edge, target, false);
			
			if (tc)
			{
				var pt = this.graph.getConnectionPoint(target, tc);
				
				if (pt != null)
				{
					this.convertPoint(pt, false);
					ye = pt.y;
				}
			}
			
			result = [new mxPoint(point.x, y0), new mxPoint(point.x, ye)];
		}

		this.points = result;

		// LATER: Check if points and result are different
		edge.view.updateFixedTerminalPoints(edge, source, target);
		edge.view.updatePoints(edge, this.points, source, target);
		edge.view.updateFloatingTerminalPoints(edge, source, target);
	}
};

/**
 * Overriden to merge edge segments.
 */
mxEdgeSegmentHandler.prototype.connect = function(edge, terminal, isSource, isClone, me)
{
	// Merges adjacent edge segments
	var pts = this.abspoints;
	var pt0 = pts[0];
	var pt1 = pts[1];
	var result = [];
	
	for (var i = 2; i < pts.length; i++)
	{
		var pt2 = pts[i];
	
		// Merges adjacent segments only if more than 2 to allow for straight edges
		if ((Math.round(pt0.x - pt1.x) != 0 || Math.round(pt1.x - pt2.x) != 0) &&
			(Math.round(pt0.y - pt1.y) != 0 || Math.round(pt1.y - pt2.y) != 0))
		{
			result.push(this.convertPoint(pt1.clone(), false));
		}

		pt0 = pt1;
		pt1 = pt2;
	}
	
	var model = this.graph.getModel();
	
	model.beginUpdate();
	try
	{
		var geo = model.getGeometry(edge);
		
		if (geo != null)
		{
			geo = geo.clone();
			geo.points = result;
			
			model.setGeometry(edge, geo);
		}
		
		edge = mxEdgeHandler.prototype.connect.apply(this, arguments);
	}
	finally
	{
		model.endUpdate();
	}
	
	return edge;
};

/**
 * Function: getTooltipForNode
 * 
 * Returns no tooltips.
 */
mxEdgeSegmentHandler.prototype.getTooltipForNode = function(node)
{
	return null;
};

/**
 * Function: createBends
 * 
 * Adds custom bends for the center of each segment.
 */
mxEdgeSegmentHandler.prototype.start = function(x, y, index)
{
	mxEdgeHandler.prototype.start.apply(this, arguments);
	
	if (this.bends[index] != null && !this.isSource && !this.isTarget)
	{
		mxUtils.setOpacity(this.bends[index].node, 100);
	}
};

/**
 * Function: createBends
 * 
 * Adds custom bends for the center of each segment.
 */
mxEdgeSegmentHandler.prototype.createBends = function()
{
	var bends = [];
	
	// Source
	var bend = this.createHandleShape(0);
	this.initBend(bend);
	bend.setCursor(mxConstants.CURSOR_TERMINAL_HANDLE);
	bends.push(bend);

	var pts = this.getCurrentPoints();

	// Waypoints (segment handles)
	if (this.graph.isCellBendable(this.state.cell))
	{
		if (this.points == null)
		{
			this.points = [];
		}

		for (var i = 0; i < pts.length - 1; i++)
		{
			bend = this.createVirtualBend();
			bends.push(bend);
			var horizontal = Math.round(pts[i].x - pts[i + 1].x) == 0;
			
			// Special case where dy is 0 as well
			if (Math.round(pts[i].y - pts[i + 1].y) == 0 && i < pts.length - 2)
			{
				horizontal = Math.round(pts[i].x - pts[i + 2].x) == 0;
			}
			
			bend.setCursor((horizontal) ? 'col-resize' : 'row-resize');
			this.points.push(new mxPoint(0,0));
		}
	}

	// Target
	var bend = this.createHandleShape(pts.length);
	this.initBend(bend);
	bend.setCursor(mxConstants.CURSOR_TERMINAL_HANDLE);
	bends.push(bend);

	return bends;
};

/**
 * Function: redraw
 * 
 * Overridden to invoke <refresh> before the redraw.
 */
mxEdgeSegmentHandler.prototype.redraw = function()
{
	this.refresh();
	mxEdgeHandler.prototype.redraw.apply(this, arguments);
};

/**
 * Function: redrawInnerBends
 * 
 * Updates the position of the custom bends.
 */
mxEdgeSegmentHandler.prototype.redrawInnerBends = function(p0, pe)
{
	if (this.graph.isCellBendable(this.state.cell))
	{
		var pts = this.getCurrentPoints();
		
		if (pts != null && pts.length > 1)
		{
			var straight = false;
			
			// Puts handle in the center of straight edges
			if (pts.length == 4 && Math.round(pts[1].x - pts[2].x) == 0 && Math.round(pts[1].y - pts[2].y) == 0)
			{
				straight = true;
				
				if (Math.round(pts[0].y - pts[pts.length - 1].y) == 0)
				{
					var cx = pts[0].x + (pts[pts.length - 1].x - pts[0].x) / 2;
					pts[1] = new mxPoint(cx, pts[1].y);
					pts[2] = new mxPoint(cx, pts[2].y);
				}
				else
				{
					var cy = pts[0].y + (pts[pts.length - 1].y - pts[0].y) / 2;
					pts[1] = new mxPoint(pts[1].x, cy);
					pts[2] = new mxPoint(pts[2].x, cy);
				}
			}
			
			for (var i = 0; i < pts.length - 1; i++)
			{
				if (this.bends[i + 1] != null)
				{
		 			var p0 = pts[i];
	 				var pe = pts[i + 1];
			 		var pt = new mxPoint(p0.x + (pe.x - p0.x) / 2, p0.y + (pe.y - p0.y) / 2);
			 		var b = this.bends[i + 1].bounds;
			 		this.bends[i + 1].bounds = new mxRectangle(Math.floor(pt.x - b.width / 2),
			 				Math.floor(pt.y - b.height / 2), b.width, b.height);
				 	this.bends[i + 1].redraw();
				 	
				 	if (this.manageLabelHandle)
					{
						this.checkLabelHandle(this.bends[i + 1].bounds);
					}
				}
			}
			
			if (straight)
			{
				mxUtils.setOpacity(this.bends[1].node, this.virtualBendOpacity);
				mxUtils.setOpacity(this.bends[3].node, this.virtualBendOpacity);
			}
		}
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxKeyHandler
 *
 * Event handler that listens to keystroke events. This is not a singleton,
 * however, it is normally only required once if the target is the document
 * element (default).
 * 
 * This handler installs a key event listener in the topmost DOM node and
 * processes all events that originate from descandants of <mxGraph.container>
 * or from the topmost DOM node. The latter means that all unhandled keystrokes
 * are handled by this object regardless of the focused state of the <graph>.
 * 
 * Example:
 * 
 * The following example creates a key handler that listens to the delete key
 * (46) and deletes the selection cells if the graph is enabled.
 * 
 * (code)
 * var keyHandler = new mxKeyHandler(graph);
 * keyHandler.bindKey(46, function(evt)
 * {
 *   if (graph.isEnabled())
 *   {
 *     graph.removeCells();
 *   }
 * });
 * (end)
 * 
 * Keycodes:
 * 
 * See http://tinyurl.com/yp8jgl or http://tinyurl.com/229yqw for a list of
 * keycodes or install a key event listener into the document element and print
 * the key codes of the respective events to the console.
 * 
 * To support the Command key and the Control key on the Mac, the following
 * code can be used.
 *
 * (code)
 * keyHandler.getFunction = function(evt)
 * {
 *   if (evt != null)
 *   {
 *     return (mxEvent.isControlDown(evt) || (mxClient.IS_MAC && evt.metaKey)) ? this.controlKeys[evt.keyCode] : this.normalKeys[evt.keyCode];
 *   }
 *   
 *   return null;
 * };
 * (end)
 * 
 * Constructor: mxKeyHandler
 *
 * Constructs an event handler that executes functions bound to specific
 * keystrokes.
 * 
 * Parameters:
 * 
 * graph - Reference to the associated <mxGraph>.
 * target - Optional reference to the event target. If null, the document
 * element is used as the event target, that is, the object where the key
 * event listener is installed.
 */
function mxKeyHandler(graph, target)
{
	if (graph != null)
	{
		this.graph = graph;
		this.target = target || document.documentElement;
		
		// Creates the arrays to map from keycodes to functions
		this.normalKeys = [];
		this.shiftKeys = [];
		this.controlKeys = [];
		this.controlShiftKeys = [];
		
		this.keydownHandler = mxUtils.bind(this, function(evt)
		{
			this.keyDown(evt);
		});

		// Installs the keystroke listener in the target
		mxEvent.addListener(this.target, 'keydown', this.keydownHandler);
		
		// Automatically deallocates memory in IE
		if (mxClient.IS_IE)
		{
			mxEvent.addListener(window, 'unload',
				mxUtils.bind(this, function()
				{
					this.destroy();
				})
			);
		}
	}
};

/**
 * Variable: graph
 * 
 * Reference to the <mxGraph> associated with this handler.
 */
mxKeyHandler.prototype.graph = null;

/**
 * Variable: target
 * 
 * Reference to the target DOM, that is, the DOM node where the key event
 * listeners are installed.
 */
mxKeyHandler.prototype.target = null;

/**
 * Variable: normalKeys
 * 
 * Maps from keycodes to functions for non-pressed control keys.
 */
mxKeyHandler.prototype.normalKeys = null;

/**
 * Variable: shiftKeys
 * 
 * Maps from keycodes to functions for pressed shift keys.
 */
mxKeyHandler.prototype.shiftKeys = null;

/**
 * Variable: controlKeys
 * 
 * Maps from keycodes to functions for pressed control keys.
 */
mxKeyHandler.prototype.controlKeys = null;

/**
 * Variable: controlShiftKeys
 * 
 * Maps from keycodes to functions for pressed control and shift keys.
 */
mxKeyHandler.prototype.controlShiftKeys = null;

/**
 * Variable: enabled
 * 
 * Specifies if events are handled. Default is true.
 */
mxKeyHandler.prototype.enabled = true;

/**
 * Function: isEnabled
 * 
 * Returns true if events are handled. This implementation returns
 * <enabled>.
 */
mxKeyHandler.prototype.isEnabled = function()
{
	return this.enabled;
};

/**
 * Function: setEnabled
 * 
 * Enables or disables event handling by updating <enabled>.
 * 
 * Parameters:
 * 
 * enabled - Boolean that specifies the new enabled state.
 */
mxKeyHandler.prototype.setEnabled = function(enabled)
{
	this.enabled = enabled;
};

/**
 * Function: bindKey
 * 
 * Binds the specified keycode to the given function. This binding is used
 * if the control key is not pressed.
 * 
 * Parameters:
 *
 * code - Integer that specifies the keycode.
 * funct - JavaScript function that takes the key event as an argument.
 */
mxKeyHandler.prototype.bindKey = function(code, funct)
{
	this.normalKeys[code] = funct;
};

/**
 * Function: bindShiftKey
 * 
 * Binds the specified keycode to the given function. This binding is used
 * if the shift key is pressed.
 * 
 * Parameters:
 *
 * code - Integer that specifies the keycode.
 * funct - JavaScript function that takes the key event as an argument.
 */
mxKeyHandler.prototype.bindShiftKey = function(code, funct)
{
	this.shiftKeys[code] = funct;
};

/**
 * Function: bindControlKey
 * 
 * Binds the specified keycode to the given function. This binding is used
 * if the control key is pressed.
 * 
 * Parameters:
 *
 * code - Integer that specifies the keycode.
 * funct - JavaScript function that takes the key event as an argument.
 */
mxKeyHandler.prototype.bindControlKey = function(code, funct)
{
	this.controlKeys[code] = funct;
};

/**
 * Function: bindControlShiftKey
 * 
 * Binds the specified keycode to the given function. This binding is used
 * if the control and shift key are pressed.
 * 
 * Parameters:
 *
 * code - Integer that specifies the keycode.
 * funct - JavaScript function that takes the key event as an argument.
 */
mxKeyHandler.prototype.bindControlShiftKey = function(code, funct)
{
	this.controlShiftKeys[code] = funct;
};

/**
 * Function: isControlDown
 * 
 * Returns true if the control key is pressed. This uses <mxEvent.isControlDown>.
 * 
 * Parameters:
 * 
 * evt - Key event whose control key pressed state should be returned.
 */
mxKeyHandler.prototype.isControlDown = function(evt)
{
	return mxEvent.isControlDown(evt);
};

/**
 * Function: getFunction
 * 
 * Returns the function associated with the given key event or null if no
 * function is associated with the given event.
 * 
 * Parameters:
 * 
 * evt - Key event whose associated function should be returned.
 */
mxKeyHandler.prototype.getFunction = function(evt)
{
	if (evt != null && !mxEvent.isAltDown(evt))
	{
		if (this.isControlDown(evt))
		{
			if (mxEvent.isShiftDown(evt))
			{
				return this.controlShiftKeys[evt.keyCode];
			}
			else
			{
				return this.controlKeys[evt.keyCode];
			}
		}
		else
		{
			if (mxEvent.isShiftDown(evt))
			{
				return this.shiftKeys[evt.keyCode];
			}
			else
			{
				return this.normalKeys[evt.keyCode];
			}
		}
	}
	
	return null;
};
	
/**
 * Function: isGraphEvent
 * 
 * Returns true if the event should be processed by this handler, that is,
 * if the event source is either the target, one of its direct children, a
 * descendant of the <mxGraph.container>, or the <mxGraph.cellEditor> of the
 * <graph>.
 * 
 * Parameters:
 * 
 * evt - Key event that represents the keystroke.
 */
mxKeyHandler.prototype.isGraphEvent = function(evt)
{
	var source = mxEvent.getSource(evt);
	
	// Accepts events from the target object or
	// in-place editing inside graph
	if ((source == this.target || source.parentNode == this.target) ||
		(this.graph.cellEditor != null && this.graph.cellEditor.isEventSource(evt)))
	{
		return true;
	}
	
	// Accepts events from inside the container
	return mxUtils.isAncestorNode(this.graph.container, source);
};

/**
 * Function: keyDown
 * 
 * Handles the event by invoking the function bound to the respective keystroke
 * if <isEnabledForEvent> returns true for the given event and if
 * <isEventIgnored> returns false, except for escape for which
 * <isEventIgnored> is not invoked.
 * 
 * Parameters:
 * 
 * evt - Key event that represents the keystroke.
 */
mxKeyHandler.prototype.keyDown = function(evt)
{
	if (this.isEnabledForEvent(evt))
	{
		// Cancels the editing if escape is pressed
		if (evt.keyCode == 27 /* Escape */)
		{
			this.escape(evt);
		}
		
		// Invokes the function for the keystroke
		else if (!this.isEventIgnored(evt))
		{
			var boundFunction = this.getFunction(evt);
			
			if (boundFunction != null)
			{
				boundFunction(evt);
				mxEvent.consume(evt);
			}
		}
	}
};

/**
 * Function: isEnabledForEvent
 * 
 * Returns true if the given event should be handled. <isEventIgnored> is
 * called later if the event is not an escape key stroke, in which case
 * <escape> is called. This implementation returns true if <isEnabled>
 * returns true for both, this handler and <graph>, if the event is not
 * consumed and if <isGraphEvent> returns true.
 * 
 * Parameters:
 * 
 * evt - Key event that represents the keystroke.
 */
mxKeyHandler.prototype.isEnabledForEvent = function(evt)
{
	return (this.graph.isEnabled() && !mxEvent.isConsumed(evt) &&
		this.isGraphEvent(evt) && this.isEnabled());
};

/**
 * Function: isEventIgnored
 * 
 * Returns true if the given keystroke should be ignored. This returns
 * graph.isEditing().
 * 
 * Parameters:
 * 
 * evt - Key event that represents the keystroke.
 */
mxKeyHandler.prototype.isEventIgnored = function(evt)
{
	return this.graph.isEditing();
};

/**
 * Function: escape
 * 
 * Hook to process ESCAPE keystrokes. This implementation invokes
 * <mxGraph.stopEditing> to cancel the current editing, connecting
 * and/or other ongoing modifications.
 * 
 * Parameters:
 * 
 * evt - Key event that represents the keystroke. Possible keycode in this
 * case is 27 (ESCAPE).
 */
mxKeyHandler.prototype.escape = function(evt)
{
	if (this.graph.isEscapeEnabled())
	{
		this.graph.escape(evt);
	}
};

/**
 * Function: destroy
 * 
 * Destroys the handler and all its references into the DOM. This does
 * normally not need to be called, it is called automatically when the
 * window unloads (in IE).
 */
mxKeyHandler.prototype.destroy = function()
{
	if (this.target != null && this.keydownHandler != null)
	{
		mxEvent.removeListener(this.target, 'keydown', this.keydownHandler);
		this.keydownHandler = null;
	}
	
	this.target = null;
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxTooltipHandler
 * 
 * Graph event handler that displays tooltips. <mxGraph.getTooltip> is used to
 * get the tooltip for a cell or handle. This handler is built-into
 * <mxGraph.tooltipHandler> and enabled using <mxGraph.setTooltips>.
 *
 * Example:
 * 
 * (code>
 * new mxTooltipHandler(graph);
 * (end)
 * 
 * Constructor: mxTooltipHandler
 * 
 * Constructs an event handler that displays tooltips with the specified
 * delay (in milliseconds). If no delay is specified then a default delay
 * of 500 ms (0.5 sec) is used.
 * 
 * Parameters:
 * 
 * graph - Reference to the enclosing <mxGraph>.
 * delay - Optional delay in milliseconds.
 */
function mxTooltipHandler(graph, delay)
{
	if (graph != null)
	{
		this.graph = graph;
		this.delay = delay || 500;
		this.graph.addMouseListener(this);
	}
};

/**
 * Variable: zIndex
 * 
 * Specifies the zIndex for the tooltip and its shadow. Default is 10005.
 */
mxTooltipHandler.prototype.zIndex = 10005;

/**
 * Variable: graph
 * 
 * Reference to the enclosing <mxGraph>.
 */
mxTooltipHandler.prototype.graph = null;

/**
 * Variable: delay
 * 
 * Delay to show the tooltip in milliseconds. Default is 500.
 */
mxTooltipHandler.prototype.delay = null;

/**
 * Variable: ignoreTouchEvents
 * 
 * Specifies if touch and pen events should be ignored. Default is true.
 */
mxTooltipHandler.prototype.ignoreTouchEvents = true;

/**
 * Variable: hideOnHover
 * 
 * Specifies if the tooltip should be hidden if the mouse is moved over the
 * current cell. Default is false.
 */
mxTooltipHandler.prototype.hideOnHover = false;

/**
 * Variable: destroyed
 * 
 * True if this handler was destroyed using <destroy>.
 */
mxTooltipHandler.prototype.destroyed = false;

/**
 * Variable: enabled
 * 
 * Specifies if events are handled. Default is true.
 */
mxTooltipHandler.prototype.enabled = true;

/**
 * Function: isEnabled
 * 
 * Returns true if events are handled. This implementation
 * returns <enabled>.
 */
mxTooltipHandler.prototype.isEnabled = function()
{
	return this.enabled;
};

/**
 * Function: setEnabled
 * 
 * Enables or disables event handling. This implementation
 * updates <enabled>.
 */
mxTooltipHandler.prototype.setEnabled = function(enabled)
{
	this.enabled = enabled;
};

/**
 * Function: isHideOnHover
 * 
 * Returns <hideOnHover>.
 */
mxTooltipHandler.prototype.isHideOnHover = function()
{
	return this.hideOnHover;
};

/**
 * Function: setHideOnHover
 * 
 * Sets <hideOnHover>.
 */
mxTooltipHandler.prototype.setHideOnHover = function(value)
{
	this.hideOnHover = value;
};

/**
 * Function: init
 * 
 * Initializes the DOM nodes required for this tooltip handler.
 */
mxTooltipHandler.prototype.init = function()
{
	if (document.body != null)
	{
		this.div = document.createElement('div');
		this.div.className = 'mxTooltip';
		this.div.style.visibility = 'hidden';

		document.body.appendChild(this.div);

		mxEvent.addGestureListeners(this.div, mxUtils.bind(this, function(evt)
		{
			this.hideTooltip();
		}));
	}
};

/**
 * Function: mouseDown
 * 
 * Handles the event by initiating a rubberband selection. By consuming the
 * event all subsequent events of the gesture are redirected to this
 * handler.
 */
mxTooltipHandler.prototype.mouseDown = function(sender, me)
{
	this.reset(me, false);
	this.hideTooltip();
};

/**
 * Function: mouseMove
 * 
 * Handles the event by updating the rubberband selection.
 */
mxTooltipHandler.prototype.mouseMove = function(sender, me)
{
	if (me.getX() != this.lastX || me.getY() != this.lastY)
	{
		this.reset(me, true);
		
		if (this.isHideOnHover() || me.getState() != this.state || (me.getSource() != this.node &&
			(!this.stateSource || (me.getState() != null && this.stateSource ==
			(me.isSource(me.getState().shape) || !me.isSource(me.getState().text))))))
		{
			this.hideTooltip();
		}
	}
	
	this.lastX = me.getX();
	this.lastY = me.getY();
};

/**
 * Function: mouseUp
 * 
 * Handles the event by resetting the tooltip timer or hiding the existing
 * tooltip.
 */
mxTooltipHandler.prototype.mouseUp = function(sender, me)
{
	this.reset(me, true);
	this.hideTooltip();
};


/**
 * Function: resetTimer
 * 
 * Resets the timer.
 */
mxTooltipHandler.prototype.resetTimer = function()
{
	if (this.thread != null)
	{
		window.clearTimeout(this.thread);
		this.thread = null;
	}
};

/**
 * Function: reset
 * 
 * Resets and/or restarts the timer to trigger the display of the tooltip.
 */
mxTooltipHandler.prototype.reset = function(me, restart)
{
	if (!this.ignoreTouchEvents || mxEvent.isMouseEvent(me.getEvent()))
	{
		this.resetTimer();
		
		if (restart && this.isEnabled() && me.getState() != null && (this.div == null ||
			this.div.style.visibility == 'hidden'))
		{
			var state = me.getState();
			var node = me.getSource();
			var x = me.getX();
			var y = me.getY();
			var stateSource = me.isSource(state.shape) || me.isSource(state.text);
	
			this.thread = window.setTimeout(mxUtils.bind(this, function()
			{
				if (!this.graph.isEditing() && !this.graph.popupMenuHandler.isMenuShowing() && !this.graph.isMouseDown)
				{
					// Uses information from inside event cause using the event at
					// this (delayed) point in time is not possible in IE as it no
					// longer contains the required information (member not found)
					var tip = this.graph.getTooltip(state, node, x, y);
					this.show(tip, x, y);
					this.state = state;
					this.node = node;
					this.stateSource = stateSource;
				}
			}), this.delay);
		}
	}
};

/**
 * Function: hide
 * 
 * Hides the tooltip and resets the timer.
 */
mxTooltipHandler.prototype.hide = function()
{
	this.resetTimer();
	this.hideTooltip();
};

/**
 * Function: hideTooltip
 * 
 * Hides the tooltip.
 */
mxTooltipHandler.prototype.hideTooltip = function()
{
	if (this.div != null)
	{
		this.div.style.visibility = 'hidden';
		this.div.innerHTML = '';
	}
};

/**
 * Function: show
 * 
 * Shows the tooltip for the specified cell and optional index at the
 * specified location (with a vertical offset of 10 pixels).
 */
mxTooltipHandler.prototype.show = function(tip, x, y)
{
	if (!this.destroyed && tip != null && tip.length > 0)
	{
		// Initializes the DOM nodes if required
		if (this.div == null)
		{
			this.init();
		}
		
		var origin = mxUtils.getScrollOrigin();

		this.div.style.zIndex = this.zIndex;
		this.div.style.left = (x + origin.x) + 'px';
		this.div.style.top = (y + mxConstants.TOOLTIP_VERTICAL_OFFSET +
			origin.y) + 'px';

		if (!mxUtils.isNode(tip))
		{	
			this.div.innerHTML = tip.replace(/\n/g, '<br>');
		}
		else
		{
			this.div.innerHTML = '';
			this.div.appendChild(tip);
		}
		
		this.div.style.visibility = '';
		mxUtils.fit(this.div);
	}
};

/**
 * Function: destroy
 * 
 * Destroys the handler and all its resources and DOM nodes.
 */
mxTooltipHandler.prototype.destroy = function()
{
	if (!this.destroyed)
	{
		this.graph.removeMouseListener(this);
		mxEvent.release(this.div);
		
		if (this.div != null && this.div.parentNode != null)
		{
			this.div.parentNode.removeChild(this.div);
		}
		
		this.destroyed = true;
		this.div = null;
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxCellTracker
 * 
 * Event handler that highlights cells. Inherits from <mxCellMarker>.
 * 
 * Example:
 * 
 * (code)
 * new mxCellTracker(graph, '#00FF00');
 * (end)
 * 
 * For detecting dragEnter, dragOver and dragLeave on cells, the following
 * code can be used:
 * 
 * (code)
 * graph.addMouseListener(
 * {
 *   cell: null,
 *   mouseDown: function(sender, me) { },
 *   mouseMove: function(sender, me)
 *   {
 *     var tmp = me.getCell();
 *     
 *     if (tmp != this.cell)
 *     {
 *       if (this.cell != null)
 *       {
 *         this.dragLeave(me.getEvent(), this.cell);
 *       }
 *       
 *       this.cell = tmp;
 *       
 *       if (this.cell != null)
 *       {
 *         this.dragEnter(me.getEvent(), this.cell);
 *       }
 *     }
 *     
 *     if (this.cell != null)
 *     {
 *       this.dragOver(me.getEvent(), this.cell);
 *     }
 *   },
 *   mouseUp: function(sender, me) { },
 *   dragEnter: function(evt, cell)
 *   {
 *     mxLog.debug('dragEnter', cell.value);
 *   },
 *   dragOver: function(evt, cell)
 *   {
 *     mxLog.debug('dragOver', cell.value);
 *   },
 *   dragLeave: function(evt, cell)
 *   {
 *     mxLog.debug('dragLeave', cell.value);
 *   }
 * });
 * (end)
 * 
 * Constructor: mxCellTracker
 * 
 * Constructs an event handler that highlights cells.
 * 
 * Parameters:
 * 
 * graph - Reference to the enclosing <mxGraph>.
 * color - Color of the highlight. Default is blue.
 * funct - Optional JavaScript function that is used to override
 * <mxCellMarker.getCell>.
 */
function mxCellTracker(graph, color, funct)
{
	mxCellMarker.call(this, graph, color);

	this.graph.addMouseListener(this);
	
	if (funct != null)
	{
		this.getCell = funct;
	}
	
	// Automatic deallocation of memory
	if (mxClient.IS_IE)
	{
		mxEvent.addListener(window, 'unload', mxUtils.bind(this, function()
		{
			this.destroy();
		}));
	}
};

/**
 * Extends mxCellMarker.
 */
mxUtils.extend(mxCellTracker, mxCellMarker);

/**
 * Function: mouseDown
 * 
 * Ignores the event. The event is not consumed.
 */
mxCellTracker.prototype.mouseDown = function(sender, me) { };

/**
 * Function: mouseMove
 * 
 * Handles the event by highlighting the cell under the mousepointer if it
 * is over the hotspot region of the cell.
 */
mxCellTracker.prototype.mouseMove = function(sender, me)
{
	if (this.isEnabled())
	{
		this.process(me);
	}
};

/**
 * Function: mouseUp
 * 
 * Handles the event by reseting the highlight.
 */
mxCellTracker.prototype.mouseUp = function(sender, me) { };

/**
 * Function: destroy
 * 
 * Destroys the object and all its resources and DOM nodes. This doesn't
 * normally need to be called. It is called automatically when the window
 * unloads.
 */
mxCellTracker.prototype.destroy = function()
{
	if (!this.destroyed)
	{
		this.destroyed = true;

		this.graph.removeMouseListener(this);
		mxCellMarker.prototype.destroy.apply(this);
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxCellHighlight
 * 
 * A helper class to highlight cells. Here is an example for a given cell.
 * 
 * (code)
 * var highlight = new mxCellHighlight(graph, '#ff0000', 2);
 * highlight.highlight(graph.view.getState(cell)));
 * (end)
 * 
 * Constructor: mxCellHighlight
 * 
 * Constructs a cell highlight.
 */
function mxCellHighlight(graph, highlightColor, strokeWidth, dashed)
{
	if (graph != null)
	{
		this.graph = graph;
		this.highlightColor = (highlightColor != null) ? highlightColor : mxConstants.DEFAULT_VALID_COLOR;
		this.strokeWidth = (strokeWidth != null) ? strokeWidth : mxConstants.HIGHLIGHT_STROKEWIDTH;
		this.dashed = (dashed != null) ? dashed : false;
		this.opacity = mxConstants.HIGHLIGHT_OPACITY;

		// Updates the marker if the graph changes
		this.repaintHandler = mxUtils.bind(this, function()
		{
			// Updates reference to state
			if (this.state != null)
			{
				var tmp = this.graph.view.getState(this.state.cell);
				
				if (tmp == null)
				{
					this.hide();
				}
				else
				{
					this.state = tmp;
					this.repaint();
				}
			}
		});

		this.graph.getView().addListener(mxEvent.SCALE, this.repaintHandler);
		this.graph.getView().addListener(mxEvent.TRANSLATE, this.repaintHandler);
		this.graph.getView().addListener(mxEvent.SCALE_AND_TRANSLATE, this.repaintHandler);
		this.graph.getModel().addListener(mxEvent.CHANGE, this.repaintHandler);
		
		// Hides the marker if the current root changes
		this.resetHandler = mxUtils.bind(this, function()
		{
			this.hide();
		});

		this.graph.getView().addListener(mxEvent.DOWN, this.resetHandler);
		this.graph.getView().addListener(mxEvent.UP, this.resetHandler);
	}
};

/**
 * Variable: keepOnTop
 * 
 * Specifies if the highlights should appear on top of everything
 * else in the overlay pane. Default is false.
 */
mxCellHighlight.prototype.keepOnTop = false;

/**
 * Variable: graph
 * 
 * Reference to the enclosing <mxGraph>.
 */
mxCellHighlight.prototype.graph = true;

/**
 * Variable: state
 * 
 * Reference to the <mxCellState>.
 */
mxCellHighlight.prototype.state = null;

/**
 * Variable: spacing
 * 
 * Specifies the spacing between the highlight for vertices and the vertex.
 * Default is 2.
 */
mxCellHighlight.prototype.spacing = 2;

/**
 * Variable: resetHandler
 * 
 * Holds the handler that automatically invokes reset if the highlight
 * should be hidden.
 */
mxCellHighlight.prototype.resetHandler = null;

/**
 * Function: setHighlightColor
 * 
 * Sets the color of the rectangle used to highlight drop targets.
 * 
 * Parameters:
 * 
 * color - String that represents the new highlight color.
 */
mxCellHighlight.prototype.setHighlightColor = function(color)
{
	this.highlightColor = color;
	
	if (this.shape != null)
	{
		this.shape.stroke = color;
	}
};

/**
 * Function: drawHighlight
 * 
 * Creates and returns the highlight shape for the given state.
 */
mxCellHighlight.prototype.drawHighlight = function()
{
	this.shape = this.createShape();
	this.repaint();

	if (!this.keepOnTop && this.shape.node.parentNode.firstChild != this.shape.node)
	{
		this.shape.node.parentNode.insertBefore(this.shape.node, this.shape.node.parentNode.firstChild);
	}
};

/**
 * Function: createShape
 * 
 * Creates and returns the highlight shape for the given state.
 */
mxCellHighlight.prototype.createShape = function()
{
	var shape = this.graph.cellRenderer.createShape(this.state);
	
	shape.svgStrokeTolerance = this.graph.tolerance;
	shape.points = this.state.absolutePoints;
	shape.apply(this.state);
	shape.stroke = this.highlightColor;
	shape.opacity = this.opacity;
	shape.isDashed = this.dashed;
	shape.isShadow = false;
	
	shape.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ? mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
	shape.init(this.graph.getView().getOverlayPane());
	mxEvent.redirectMouseEvents(shape.node, this.graph, this.state);
	
	if (this.graph.dialect != mxConstants.DIALECT_SVG)
	{
		shape.pointerEvents = false;
	}
	else
	{
		shape.svgPointerEvents = 'stroke';
	}
	
	return shape;
};

/**
 * Function: repaint
 * 
 * Updates the highlight after a change of the model or view.
 */
mxCellHighlight.prototype.getStrokeWidth = function(state)
{
	return this.strokeWidth;
};

/**
 * Function: repaint
 * 
 * Updates the highlight after a change of the model or view.
 */
mxCellHighlight.prototype.repaint = function()
{
	if (this.state != null && this.shape != null)
	{
		this.shape.scale = this.state.view.scale;
		
		if (this.graph.model.isEdge(this.state.cell))
		{
			this.shape.strokewidth = this.getStrokeWidth();
			this.shape.points = this.state.absolutePoints;
			this.shape.outline = false;
		}
		else
		{
			this.shape.bounds = new mxRectangle(this.state.x - this.spacing, this.state.y - this.spacing,
					this.state.width + 2 * this.spacing, this.state.height + 2 * this.spacing);
			this.shape.rotation = Number(this.state.style[mxConstants.STYLE_ROTATION] || '0');
			this.shape.strokewidth = this.getStrokeWidth() / this.state.view.scale;
			this.shape.outline = true;
		}

		// Uses cursor from shape in highlight
		if (this.state.shape != null)
		{
			this.shape.setCursor(this.state.shape.getCursor());
		}
		
		// Workaround for event transparency in VML with transparent color
		// is to use a non-transparent color with near zero opacity
		if (mxClient.IS_QUIRKS || document.documentMode == 8)
		{
			if (this.shape.stroke == 'transparent')
			{
				// KNOWN: Quirks mode does not seem to catch events if
				// we do not force an update of the DOM via a change such
				// as mxLog.debug. Since IE6 is EOL we do not add a fix.
				this.shape.stroke = 'white';
				this.shape.opacity = 1;
			}
			else
			{
				this.shape.opacity = this.opacity;
			}
		}
		
		this.shape.redraw();
	}
};

/**
 * Function: hide
 * 
 * Resets the state of the cell marker.
 */
mxCellHighlight.prototype.hide = function()
{
	this.highlight(null);
};

/**
 * Function: mark
 * 
 * Marks the <markedState> and fires a <mark> event.
 */
mxCellHighlight.prototype.highlight = function(state)
{
	if (this.state != state)
	{
		if (this.shape != null)
		{
			this.shape.destroy();
			this.shape = null;
		}

		this.state = state;
		
		if (this.state != null)
		{
			this.drawHighlight();
		}
	}
};

/**
 * Function: isHighlightAt
 * 
 * Returns true if this highlight is at the given position.
 */
mxCellHighlight.prototype.isHighlightAt = function(x, y)
{
	var hit = false;
	
	// Quirks mode is currently not supported as it used a different coordinate system
	if (this.shape != null && document.elementFromPoint != null && !mxClient.IS_QUIRKS)
	{
		var elt = document.elementFromPoint(x, y);

		while (elt != null)
		{
			if (elt == this.shape.node)
			{
				hit = true;
				break;
			}
			
			elt = elt.parentNode;
		}
	}
	
	return hit;
};

/**
 * Function: destroy
 * 
 * Destroys the handler and all its resources and DOM nodes.
 */
mxCellHighlight.prototype.destroy = function()
{
	this.graph.getView().removeListener(this.resetHandler);
	this.graph.getView().removeListener(this.repaintHandler);
	this.graph.getModel().removeListener(this.repaintHandler);
	
	if (this.shape != null)
	{
		this.shape.destroy();
		this.shape = null;
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxDefaultKeyHandler
 *
 * Binds keycodes to actionnames in an editor. This aggregates an internal
 * <handler> and extends the implementation of <mxKeyHandler.escape> to not
 * only cancel the editing, but also hide the properties dialog and fire an
 * <mxEditor.escape> event via <editor>. An instance of this class is created
 * by <mxEditor> and stored in <mxEditor.keyHandler>.
 * 
 * Example:
 * 
 * Bind the delete key to the delete action in an existing editor.
 * 
 * (code)
 * var keyHandler = new mxDefaultKeyHandler(editor);
 * keyHandler.bindAction(46, 'delete');
 * (end)
 *
 * Codec:
 * 
 * This class uses the <mxDefaultKeyHandlerCodec> to read configuration
 * data into an existing instance. See <mxDefaultKeyHandlerCodec> for a
 * description of the configuration format.
 * 
 * Keycodes:
 * 
 * See <mxKeyHandler>.
 * 
 * An <mxEvent.ESCAPE> event is fired via the editor if the escape key is
 * pressed.
 * 
 * Constructor: mxDefaultKeyHandler
 *
 * Constructs a new default key handler for the <mxEditor.graph> in the
 * given <mxEditor>. (The editor may be null if a prototypical instance for
 * a <mxDefaultKeyHandlerCodec> is created.)
 * 
 * Parameters:
 * 
 * editor - Reference to the enclosing <mxEditor>.
 */
function mxDefaultKeyHandler(editor)
{
	if (editor != null)
	{
		this.editor = editor;
		this.handler = new mxKeyHandler(editor.graph);
		
		// Extends the escape function of the internal key
		// handle to hide the properties dialog and fire
		// the escape event via the editor instance
		var old = this.handler.escape;
		
		this.handler.escape = function(evt)
		{
			old.apply(this, arguments);
			editor.hideProperties();
			editor.fireEvent(new mxEventObject(mxEvent.ESCAPE, 'event', evt));
		};
	}
};
	
/**
 * Variable: editor
 *
 * Reference to the enclosing <mxEditor>.
 */
mxDefaultKeyHandler.prototype.editor = null;

/**
 * Variable: handler
 *
 * Holds the <mxKeyHandler> for key event handling.
 */
mxDefaultKeyHandler.prototype.handler = null;

/**
 * Function: bindAction
 *
 * Binds the specified keycode to the given action in <editor>. The
 * optional control flag specifies if the control key must be pressed
 * to trigger the action.
 *
 * Parameters:
 *
 * code - Integer that specifies the keycode.
 * action - Name of the action to execute in <editor>.
 * control - Optional boolean that specifies if control must be pressed.
 * Default is false.
 */
mxDefaultKeyHandler.prototype.bindAction = function (code, action, control)
{
	var keyHandler = mxUtils.bind(this, function()
	{
		this.editor.execute(action);
	});

	// Binds the function to control-down keycode
	if (control)
	{
		this.handler.bindControlKey(code, keyHandler);
	}

	// Binds the function to the normal keycode
	else
	{
		this.handler.bindKey(code, keyHandler);				
	}
};

/**
 * Function: destroy
 *
 * Destroys the <handler> associated with this object. This does normally
 * not need to be called, the <handler> is destroyed automatically when the
 * window unloads (in IE) by <mxEditor>.
 */
mxDefaultKeyHandler.prototype.destroy = function ()
{
	this.handler.destroy();
	this.handler = null;
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxDefaultPopupMenu
 *
 * Creates popupmenus for mouse events. This object holds an XML node
 * which is a description of the popup menu to be created. In
 * <createMenu>, the configuration is applied to the context and
 * the resulting menu items are added to the menu dynamically. See
 * <createMenu> for a description of the configuration format.
 * 
 * This class does not create the DOM nodes required for the popup menu, it
 * only parses an XML description to invoke the respective methods on an
 * <mxPopupMenu> each time the menu is displayed.
 *
 * Codec:
 * 
 * This class uses the <mxDefaultPopupMenuCodec> to read configuration
 * data into an existing instance, however, the actual parsing is done
 * by this class during program execution, so the format is described
 * below.
 * 
 * Constructor: mxDefaultPopupMenu
 *
 * Constructs a new popupmenu-factory based on given configuration.
 *
 * Paramaters:
 *
 * config - XML node that contains the configuration data.
 */
function mxDefaultPopupMenu(config)
{
	this.config = config;
};

/**
 * Variable: imageBasePath
 *
 * Base path for all icon attributes in the config. Default is null.
 */
mxDefaultPopupMenu.prototype.imageBasePath = null;

/**
 * Variable: config
 *
 * XML node used as the description of new menu items. This node is
 * used in <createMenu> to dynamically create the menu items if their
 * respective conditions evaluate to true for the given arguments.
 */
mxDefaultPopupMenu.prototype.config = null;

/**
 * Function: createMenu
 *
 * This function is called from <mxEditor> to add items to the
 * given menu based on <config>. The config is a sequence of
 * the following nodes and attributes.
 *
 * Child Nodes: 
 *
 * add - Adds a new menu item. See below for attributes.
 * separator - Adds a separator. No attributes.
 * condition - Adds a custom condition. Name attribute.
 * 
 * The add-node may have a child node that defines a function to be invoked
 * before the action is executed (or instead of an action to be executed).
 *
 * Attributes:
 *
 * as - Resource key for the label (needs entry in property file).
 * action - Name of the action to execute in enclosing editor.
 * icon - Optional icon (relative/absolute URL).
 * iconCls - Optional CSS class for the icon.
 * if - Optional name of condition that must be true (see below).
 * enabled-if - Optional name of condition that specifies if the menu item
 * should be enabled.
 * name - Name of custom condition. Only for condition nodes.
 *
 * Conditions:
 *
 * nocell - No cell under the mouse.
 * ncells - More than one cell selected.
 * notRoot - Drilling position is other than home.
 * cell - Cell under the mouse.
 * notEmpty - Exactly one cell with children under mouse.
 * expandable - Exactly one expandable cell under mouse.
 * collapsable - Exactly one collapsable cell under mouse.
 * validRoot - Exactly one cell which is a possible root under mouse.
 * swimlane - Exactly one cell which is a swimlane under mouse.
 *
 * Example:
 *
 * To add a new item for a given action to the popupmenu:
 * 
 * (code)
 * <mxDefaultPopupMenu as="popupHandler">
 *   <add as="delete" action="delete" icon="images/delete.gif" if="cell"/>
 * </mxDefaultPopupMenu>
 * (end)
 * 
 * To add a new item for a custom function:
 * 
 * (code)
 * <mxDefaultPopupMenu as="popupHandler">
 *   <add as="action1"><![CDATA[
 *		function (editor, cell, evt)
 *		{
 *			editor.execute('action1', cell, 'myArg');
 *		}
 *   ]]></add>
 * </mxDefaultPopupMenu>
 * (end)
 * 
 * The above example invokes action1 with an additional third argument via
 * the editor instance. The third argument is passed to the function that
 * defines action1. If the add-node has no action-attribute, then only the
 * function defined in the text content is executed, otherwise first the
 * function and then the action defined in the action-attribute is
 * executed. The function in the text content has 3 arguments, namely the
 * <mxEditor> instance, the <mxCell> instance under the mouse, and the
 * native mouse event.
 *
 * Custom Conditions:
 *
 * To add a new condition for popupmenu items:
 *  
 * (code)
 * <condition name="condition1"><![CDATA[
 *   function (editor, cell, evt)
 *   {
 *     return cell != null;
 *   }
 * ]]></condition>
 * (end)
 * 
 * The new condition can then be used in any item as follows:
 * 
 * (code)
 * <add as="action1" action="action1" icon="action1.gif" if="condition1"/>
 * (end)
 * 
 * The order in which the items and conditions appear is not significant as
 * all connditions are evaluated before any items are created.
 * 
 * Parameters:
 *
 * editor - Enclosing <mxEditor> instance.
 * menu - <mxPopupMenu> that is used for adding items and separators.
 * cell - Optional <mxCell> which is under the mousepointer.
 * evt - Optional mouse event which triggered the menu. 
 */
mxDefaultPopupMenu.prototype.createMenu = function(editor, menu, cell, evt)
{
	if (this.config != null)
	{
		var conditions = this.createConditions(editor, cell, evt);
		var item = this.config.firstChild;

		this.addItems(editor, menu, cell, evt, conditions, item, null);
	}
};

/**
 * Function: addItems
 * 
 * Recursively adds the given items and all of its children into the given menu.
 * 
 * Parameters:
 *
 * editor - Enclosing <mxEditor> instance.
 * menu - <mxPopupMenu> that is used for adding items and separators.
 * cell - Optional <mxCell> which is under the mousepointer.
 * evt - Optional mouse event which triggered the menu.
 * conditions - Array of names boolean conditions.
 * item - XML node that represents the current menu item.
 * parent - DOM node that represents the parent menu item.
 */
mxDefaultPopupMenu.prototype.addItems = function(editor, menu, cell, evt, conditions, item, parent)
{
	var addSeparator = false;
	
	while (item != null)
	{
		if (item.nodeName == 'add')
		{
			var condition = item.getAttribute('if');
			
			if (condition == null || conditions[condition])
			{
				var as = item.getAttribute('as');
				as = mxResources.get(as) || as;
				var funct = mxUtils.eval(mxUtils.getTextContent(item));
				var action = item.getAttribute('action');
				var icon = item.getAttribute('icon');
				var iconCls = item.getAttribute('iconCls');
				var enabledCond = item.getAttribute('enabled-if');
				var enabled = enabledCond == null || conditions[enabledCond];
				
				if (addSeparator)
				{
					menu.addSeparator(parent);
					addSeparator = false;
				}
				
				if (icon != null && this.imageBasePath)
				{
					icon = this.imageBasePath + icon;
				}
				
				var row = this.addAction(menu, editor, as, icon, funct, action, cell, parent, iconCls, enabled);
				this.addItems(editor, menu, cell, evt, conditions, item.firstChild, row);
			}
		}
		else if (item.nodeName == 'separator')
		{
			addSeparator = true;
		}
		
		item = item.nextSibling;
	}
};

/**
 * Function: addAction
 *
 * Helper method to bind an action to a new menu item.
 * 
 * Parameters:
 *
 * menu - <mxPopupMenu> that is used for adding items and separators.
 * editor - Enclosing <mxEditor> instance.
 * lab - String that represents the label of the menu item.
 * icon - Optional URL that represents the icon of the menu item.
 * action - Optional name of the action to execute in the given editor.
 * funct - Optional function to execute before the optional action. The
 * function takes an <mxEditor>, the <mxCell> under the mouse and the
 * mouse event that triggered the call.
 * cell - Optional <mxCell> to use as an argument for the action.
 * parent - DOM node that represents the parent menu item.
 * iconCls - Optional CSS class for the menu icon.
 * enabled - Optional boolean that specifies if the menu item is enabled.
 * Default is true.
 */
mxDefaultPopupMenu.prototype.addAction = function(menu, editor, lab, icon, funct, action, cell, parent, iconCls, enabled)
{
	var clickHandler = function(evt)
	{
		if (typeof(funct) == 'function')
		{
			funct.call(editor, editor, cell, evt);
		}
		
		if (action != null)
		{
			editor.execute(action, cell, evt);
		}
	};
	
	return menu.addItem(lab, icon, clickHandler, parent, iconCls, enabled);
};

/**
 * Function: createConditions
 * 
 * Evaluates the default conditions for the given context.
 */
mxDefaultPopupMenu.prototype.createConditions = function(editor, cell, evt)
{
	// Creates array with conditions
	var model = editor.graph.getModel();
	var childCount = model.getChildCount(cell);
	
	// Adds some frequently used conditions
	var conditions = [];
	conditions['nocell'] = cell == null;
	conditions['ncells'] = editor.graph.getSelectionCount() > 1;
	conditions['notRoot'] = model.getRoot() !=
		model.getParent(editor.graph.getDefaultParent());
	conditions['cell'] = cell != null;
	
	var isCell = cell != null && editor.graph.getSelectionCount() == 1;
	conditions['nonEmpty'] = isCell && childCount > 0;
	conditions['expandable'] = isCell && editor.graph.isCellFoldable(cell, false);
	conditions['collapsable'] = isCell && editor.graph.isCellFoldable(cell, true);
	conditions['validRoot'] = isCell && editor.graph.isValidRoot(cell);
	conditions['emptyValidRoot'] = conditions['validRoot'] && childCount == 0;
	conditions['swimlane'] = isCell && editor.graph.isSwimlane(cell);

	// Evaluates dynamic conditions from config file
	var condNodes = this.config.getElementsByTagName('condition');
	
	for (var i=0; i<condNodes.length; i++)
	{
		var funct = mxUtils.eval(mxUtils.getTextContent(condNodes[i]));
		var name = condNodes[i].getAttribute('name');
		
		if (name != null && typeof(funct) == 'function')
		{
			conditions[name] = funct(editor, cell, evt);
		}
	}
	
	return conditions;
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxDefaultToolbar
 *
 * Toolbar for the editor. This modifies the state of the graph
 * or inserts new cells upon mouse clicks.
 * 
 * Example:
 * 
 * Create a toolbar with a button to copy the selection into the clipboard,
 * and a combo box with one action to paste the selection from the clipboard
 * into the graph.
 * 
 * (code)
 * var toolbar = new mxDefaultToolbar(container, editor);
 * toolbar.addItem('Copy', null, 'copy');
 * 
 * var combo = toolbar.addActionCombo('More actions...');
 * toolbar.addActionOption(combo, 'Paste', 'paste');
 * (end) 
 *
 * Codec:
 * 
 * This class uses the <mxDefaultToolbarCodec> to read configuration
 * data into an existing instance. See <mxDefaultToolbarCodec> for a
 * description of the configuration format.
 * 
 * Constructor: mxDefaultToolbar
 *
 * Constructs a new toolbar for the given container and editor. The
 * container and editor may be null if a prototypical instance for a
 * <mxDefaultKeyHandlerCodec> is created.
 *
 * Parameters:
 *
 * container - DOM node that contains the toolbar.
 * editor - Reference to the enclosing <mxEditor>. 
 */
function mxDefaultToolbar(container, editor)
{
	this.editor = editor;

	if (container != null && editor != null)
	{
		this.init(container);
	}
};
	
/**
 * Variable: editor
 *
 * Reference to the enclosing <mxEditor>.
 */
mxDefaultToolbar.prototype.editor = null;

/**
 * Variable: toolbar
 *
 * Holds the internal <mxToolbar>.
 */
mxDefaultToolbar.prototype.toolbar = null;

/**
 * Variable: resetHandler
 *
 * Reference to the function used to reset the <toolbar>.
 */
mxDefaultToolbar.prototype.resetHandler = null;

/**
 * Variable: spacing
 *
 * Defines the spacing between existing and new vertices in
 * gridSize units when a new vertex is dropped on an existing
 * cell. Default is 4 (40 pixels).
 */
mxDefaultToolbar.prototype.spacing = 4;

/**
 * Variable: connectOnDrop
 * 
 * Specifies if elements should be connected if new cells are dropped onto
 * connectable elements. Default is false.
 */
mxDefaultToolbar.prototype.connectOnDrop = false;

/**
 * Variable: init
 * 
 * Constructs the <toolbar> for the given container and installs a listener
 * that updates the <mxEditor.insertFunction> on <editor> if an item is
 * selected in the toolbar. This assumes that <editor> is not null.
 *
 * Parameters:
 *
 * container - DOM node that contains the toolbar.
 */
mxDefaultToolbar.prototype.init = function(container)
{
	if (container != null)
	{
		this.toolbar = new mxToolbar(container);
		
		// Installs the insert function in the editor if an item is
		// selected in the toolbar
		this.toolbar.addListener(mxEvent.SELECT, mxUtils.bind(this, function(sender, evt)
		{
			var funct = evt.getProperty('function');
			
			if (funct != null)
			{
				this.editor.insertFunction = mxUtils.bind(this, function()
				{
					funct.apply(this, arguments);
					this.toolbar.resetMode();
				});
			}
			else
			{
				this.editor.insertFunction = null;
			}
		}));
		
		// Resets the selected tool after a doubleclick or escape keystroke
		this.resetHandler = mxUtils.bind(this, function()
		{
			if (this.toolbar != null)
			{
				this.toolbar.resetMode(true);
			}
		});

		this.editor.graph.addListener(mxEvent.DOUBLE_CLICK, this.resetHandler);
		this.editor.addListener(mxEvent.ESCAPE, this.resetHandler);
	}
};

/**
 * Function: addItem
 *
 * Adds a new item that executes the given action in <editor>. The title,
 * icon and pressedIcon are used to display the toolbar item.
 * 
 * Parameters:
 *
 * title - String that represents the title (tooltip) for the item.
 * icon - URL of the icon to be used for displaying the item.
 * action - Name of the action to execute when the item is clicked.
 * pressed - Optional URL of the icon for the pressed state.
 */
mxDefaultToolbar.prototype.addItem = function(title, icon, action, pressed)
{
	var clickHandler = mxUtils.bind(this, function()
	{
		if (action != null && action.length > 0)
		{
			this.editor.execute(action);
		}
	});
	
	return this.toolbar.addItem(title, icon, clickHandler, pressed);
};

/**
 * Function: addSeparator
 *
 * Adds a vertical separator using the optional icon.
 * 
 * Parameters:
 * 
 * icon - Optional URL of the icon that represents the vertical separator.
 * Default is <mxClient.imageBasePath> + '/separator.gif'.
 */
mxDefaultToolbar.prototype.addSeparator = function(icon)
{
	icon = icon || mxClient.imageBasePath + '/separator.gif';
	this.toolbar.addSeparator(icon);
};
	
/**
 * Function: addCombo
 *
 * Helper method to invoke <mxToolbar.addCombo> on <toolbar> and return the
 * resulting DOM node.
 */
mxDefaultToolbar.prototype.addCombo = function()
{
	return this.toolbar.addCombo();
};
		
/**
 * Function: addActionCombo
 *
 * Helper method to invoke <mxToolbar.addActionCombo> on <toolbar> using
 * the given title and return the resulting DOM node.
 * 
 * Parameters:
 * 
 * title - String that represents the title of the combo.
 */
mxDefaultToolbar.prototype.addActionCombo = function(title)
{
	return this.toolbar.addActionCombo(title);
};

/**
 * Function: addActionOption
 *
 * Binds the given action to a option with the specified label in the
 * given combo. Combo is an object returned from an earlier call to
 * <addCombo> or <addActionCombo>.
 * 
 * Parameters:
 * 
 * combo - DOM node that represents the combo box.
 * title - String that represents the title of the combo.
 * action - Name of the action to execute in <editor>.
 */
mxDefaultToolbar.prototype.addActionOption = function(combo, title, action)
{
	var clickHandler = mxUtils.bind(this, function()
	{
		this.editor.execute(action);
	});
	
	this.addOption(combo, title, clickHandler);
};

/**
 * Function: addOption
 *
 * Helper method to invoke <mxToolbar.addOption> on <toolbar> and return
 * the resulting DOM node that represents the option.
 * 
 * Parameters:
 * 
 * combo - DOM node that represents the combo box.
 * title - String that represents the title of the combo.
 * value - Object that represents the value of the option.
 */
mxDefaultToolbar.prototype.addOption = function(combo, title, value)
{
	return this.toolbar.addOption(combo, title, value);
};
	
/**
 * Function: addMode
 *
 * Creates an item for selecting the given mode in the <editor>'s graph.
 * Supported modenames are select, connect and pan.
 * 
 * Parameters:
 * 
 * title - String that represents the title of the item.
 * icon - URL of the icon that represents the item.
 * mode - String that represents the mode name to be used in
 * <mxEditor.setMode>.
 * pressed - Optional URL of the icon that represents the pressed state.
 * funct - Optional JavaScript function that takes the <mxEditor> as the
 * first and only argument that is executed after the mode has been
 * selected.
 */
mxDefaultToolbar.prototype.addMode = function(title, icon, mode, pressed, funct)
{
	var clickHandler = mxUtils.bind(this, function()
	{
		this.editor.setMode(mode);
		
		if (funct != null)
		{
			funct(this.editor);
		}
	});
	
	return this.toolbar.addSwitchMode(title, icon, clickHandler, pressed);
};

/**
 * Function: addPrototype
 *
 * Creates an item for inserting a clone of the specified prototype cell into
 * the <editor>'s graph. The ptype may either be a cell or a function that
 * returns a cell.
 * 
 * Parameters:
 * 
 * title - String that represents the title of the item.
 * icon - URL of the icon that represents the item.
 * ptype - Function or object that represents the prototype cell. If ptype
 * is a function then it is invoked with no arguments to create new
 * instances.
 * pressed - Optional URL of the icon that represents the pressed state.
 * insert - Optional JavaScript function that handles an insert of the new
 * cell. This function takes the <mxEditor>, new cell to be inserted, mouse
 * event and optional <mxCell> under the mouse pointer as arguments.
 * toggle - Optional boolean that specifies if the item can be toggled.
 * Default is true.
 */
mxDefaultToolbar.prototype.addPrototype = function(title, icon, ptype, pressed, insert, toggle)
{
	// Creates a wrapper function that is in charge of constructing
	// the new cell instance to be inserted into the graph
	var factory = mxUtils.bind(this, function()
	{
		if (typeof(ptype) == 'function')
		{
			return ptype();
		}
		else if (ptype != null)
		{
			return this.editor.graph.cloneCells([ptype])[0];
		}
		
		return null;
	});
	
	// Defines the function for a click event on the graph
	// after this item has been selected in the toolbar
	var clickHandler = mxUtils.bind(this, function(evt, cell)
	{
		if (typeof(insert) == 'function')
		{
			insert(this.editor, factory(), evt, cell);
		}
		else
		{
			this.drop(factory(), evt, cell);
		}
		
		this.toolbar.resetMode();
		mxEvent.consume(evt);
	});
	
	var img = this.toolbar.addMode(title, icon, clickHandler, pressed, null, toggle);
				
	// Creates a wrapper function that calls the click handler without
	// the graph argument
	var dropHandler = function(graph, evt, cell)
	{
		clickHandler(evt, cell);
	};
	
	this.installDropHandler(img, dropHandler);
	
	return img;
};

/**
 * Function: drop
 * 
 * Handles a drop from a toolbar item to the graph. The given vertex
 * represents the new cell to be inserted. This invokes <insert> or
 * <connect> depending on the given target cell.
 * 
 * Parameters:
 * 
 * vertex - <mxCell> to be inserted.
 * evt - Mouse event that represents the drop.
 * target - Optional <mxCell> that represents the drop target.
 */
mxDefaultToolbar.prototype.drop = function(vertex, evt, target)
{
	var graph = this.editor.graph;
	var model = graph.getModel();
	
	if (target == null ||
		model.isEdge(target) ||
		!this.connectOnDrop ||
		!graph.isCellConnectable(target))
	{
		while (target != null &&
			!graph.isValidDropTarget(target, [vertex], evt))
		{
			target = model.getParent(target);
		}
		
		this.insert(vertex, evt, target);
	}
	else
	{
		this.connect(vertex, evt, target);
	}
};

/**
 * Function: insert
 *
 * Handles a drop by inserting the given vertex into the given parent cell
 * or the default parent if no parent is specified.
 * 
 * Parameters:
 * 
 * vertex - <mxCell> to be inserted.
 * evt - Mouse event that represents the drop.
 * parent - Optional <mxCell> that represents the parent.
 */
mxDefaultToolbar.prototype.insert = function(vertex, evt, target)
{
	var graph = this.editor.graph;
	
	if (graph.canImportCell(vertex))
	{
		var x = mxEvent.getClientX(evt);
		var y = mxEvent.getClientY(evt);
		var pt = mxUtils.convertPoint(graph.container, x, y);
		
		// Splits the target edge or inserts into target group
		if (graph.isSplitEnabled() &&
			graph.isSplitTarget(target, [vertex], evt))
		{
			return graph.splitEdge(target, [vertex], null, pt.x, pt.y);
		}
		else
		{
			return this.editor.addVertex(target, vertex, pt.x, pt.y);
		}
	}
	
	return null;
};

/**
 * Function: connect
 * 
 * Handles a drop by connecting the given vertex to the given source cell.
 * 
 * vertex - <mxCell> to be inserted.
 * evt - Mouse event that represents the drop.
 * source - Optional <mxCell> that represents the source terminal.
 */
mxDefaultToolbar.prototype.connect = function(vertex, evt, source)
{
	var graph = this.editor.graph;
	var model = graph.getModel();
	
	if (source != null &&
		graph.isCellConnectable(vertex) &&
		graph.isEdgeValid(null, source, vertex))
	{
		var edge = null;

		model.beginUpdate();
		try
		{
			var geo = model.getGeometry(source);
			var g = model.getGeometry(vertex).clone();
			
			// Moves the vertex away from the drop target that will
			// be used as the source for the new connection
			g.x = geo.x + (geo.width - g.width) / 2;
			g.y = geo.y + (geo.height - g.height) / 2;
			
			var step = this.spacing * graph.gridSize;
			var dist = model.getDirectedEdgeCount(source, true) * 20;
			
			if (this.editor.horizontalFlow)
			{
				g.x += (g.width + geo.width) / 2 + step + dist;
			}
			else
			{
				g.y += (g.height + geo.height) / 2 + step + dist;
			}
			
			vertex.setGeometry(g);
			
			// Fires two add-events with the code below - should be fixed
			// to only fire one add event for both inserts
			var parent = model.getParent(source);
			graph.addCell(vertex, parent);
			graph.constrainChild(vertex);

			// Creates the edge using the editor instance and calls
			// the second function that fires an add event
			edge = this.editor.createEdge(source, vertex);
			
			if (model.getGeometry(edge) == null)
			{
				var edgeGeometry = new mxGeometry();
				edgeGeometry.relative = true;
				
				model.setGeometry(edge, edgeGeometry);
			}
			
			graph.addEdge(edge, parent, source, vertex);
		}
		finally
		{
			model.endUpdate();
		}
		
		graph.setSelectionCells([vertex, edge]);
		graph.scrollCellToVisible(vertex);
	}
};

/**
 * Function: installDropHandler
 * 
 * Makes the given img draggable using the given function for handling a
 * drop event.
 * 
 * Parameters:
 * 
 * img - DOM node that represents the image.
 * dropHandler - Function that handles a drop of the image.
 */
mxDefaultToolbar.prototype.installDropHandler = function (img, dropHandler)
{
	var sprite = document.createElement('img');
	sprite.setAttribute('src', img.getAttribute('src'));

	// Handles delayed loading of the images
	var loader = mxUtils.bind(this, function(evt)
	{
		// Preview uses the image node with double size. Later this can be
		// changed to use a separate preview and guides, but for this the
		// dropHandler must use the additional x- and y-arguments and the
		// dragsource which makeDraggable returns much be configured to
		// use guides via mxDragSource.isGuidesEnabled.
		sprite.style.width = (2 * img.offsetWidth) + 'px';
		sprite.style.height = (2 * img.offsetHeight) + 'px';

		mxUtils.makeDraggable(img, this.editor.graph, dropHandler,
			sprite);
		mxEvent.removeListener(sprite, 'load', loader);
	});

	if (mxClient.IS_IE)
	{
		loader();
	}
	else
	{
		mxEvent.addListener(sprite, 'load', loader);
	}	
};

/**
 * Function: destroy
 * 
 * Destroys the <toolbar> associated with this object and removes all
 * installed listeners. This does normally not need to be called, the
 * <toolbar> is destroyed automatically when the window unloads (in IE) by
 * <mxEditor>.
 */
mxDefaultToolbar.prototype.destroy = function ()
{
	if (this.resetHandler != null)
	{
		this.editor.graph.removeListener('dblclick', this.resetHandler);
		this.editor.removeListener('escape', this.resetHandler);
		this.resetHandler = null;
	}
	
	if (this.toolbar != null)
	{
		this.toolbar.destroy();
		this.toolbar = null;
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxEditor
 *
 * Extends <mxEventSource> to implement a application wrapper for a graph that
 * adds <actions>, I/O using <mxCodec>, auto-layout using <mxLayoutManager>,
 * command history using <undoManager>, and standard dialogs and widgets, eg.
 * properties, help, outline, toolbar, and popupmenu. It also adds <templates>
 * to be used as cells in toolbars, auto-validation using the <validation>
 * flag, attribute cycling using <cycleAttributeValues>, higher-level events
 * such as <root>, and backend integration using <urlPost> and <urlImage>. 
 * 
 * Actions:
 * 
 * Actions are functions stored in the <actions> array under their names. The
 * functions take the <mxEditor> as the first, and an optional <mxCell> as the
 * second argument and are invoked using <execute>. Any additional arguments
 * passed to execute are passed on to the action as-is.
 * 
 * A list of built-in actions is available in the <addActions> description.
 * 
 * Read/write Diagrams:
 * 
 * To read a diagram from an XML string, for example from a textfield within the 
 * page, the following code is used:
 * 
 * (code)
 * var doc = mxUtils.parseXML(xmlString);
 * var node = doc.documentElement;
 * editor.readGraphModel(node);
 * (end)
 * 
 * For reading a diagram from a remote location, use the <open> method.
 * 
 * To save diagrams in XML on a server, you can set the <urlPost> variable. 
 * This variable will be used in <getUrlPost> to construct a URL for the post 
 * request that is issued in the <save> method. The post request contains the 
 * XML representation of the diagram as returned by <writeGraphModel> in the 
 * xml parameter.
 * 
 * On the server side, the post request is processed using standard
 * technologies such as Java Servlets, CGI, .NET or ASP.
 * 
 * Here are some examples of processing a post request in various languages.
 * 
 * - Java: URLDecoder.decode(request.getParameter("xml"), "UTF-8").replace("\n", "&#xa;")
 * 
 * Note that the linefeeds should only be replaced if the XML is
 * processed in Java, for example when creating an image, but not
 * if the XML is passed back to the client-side.
 * 
 * - .NET: HttpUtility.UrlDecode(context.Request.Params["xml"])
 * - PHP: urldecode($_POST["xml"])
 * 
 * Creating images:
 * 
 * A backend (Java, PHP or C#) is required for creating images. The
 * distribution contains an example for each backend (ImageHandler.java,
 * ImageHandler.cs and graph.php). More information about using a backend
 * to create images can be found in the readme.html files. Note that the
 * preview is implemented using VML/SVG in the browser and does not require
 * a backend. The backend is only required to creates images (bitmaps).
 * 
 * Special characters:
 * 
 * Note There are five characters that should always appear in XML content as
 * escapes, so that they do not interact with the syntax of the markup. These
 * are part of the language for all documents based on XML and for HTML.
 * 
 * - &lt; (<)
 * - &gt; (>)
 * - &amp; (&)
 * - &quot; (")
 * - &apos; (')
 * 
 * Although it is part of the XML language, &apos; is not defined in HTML.
 * For this reason the XHTML specification recommends instead the use of
 * &#39; if text may be passed to a HTML user agent.
 * 
 * If you are having problems with special characters on the server-side then
 * you may want to try the <escapePostData> flag.
 * 
 * For converting decimal escape sequences inside strings, a user has provided
 * us with the following function:
 * 
 * (code)
 * function html2js(text)
 * {
 *   var entitySearch = /&#[0-9]+;/;
 *   var entity;
 *   
 *   while (entity = entitySearch.exec(text))
 *   {
 *     var charCode = entity[0].substring(2, entity[0].length -1);
 *     text = text.substring(0, entity.index)
 *            + String.fromCharCode(charCode)
 *            + text.substring(entity.index + entity[0].length);
 *   }
 *   
 *   return text;
 * }
 * (end)
 * 
 * Otherwise try using hex escape sequences and the built-in unescape function
 * for converting such strings.
 * 
 * Local Files:
 * 
 * For saving and opening local files, no standardized method exists that
 * works across all browsers. The recommended way of dealing with local files
 * is to create a backend that streams the XML data back to the browser (echo)
 * as an attachment so that a Save-dialog is displayed on the client-side and
 * the file can be saved to the local disk.
 * 
 * For example, in PHP the code that does this looks as follows.
 * 
 * (code)
 * $xml = stripslashes($_POST["xml"]);
 * header("Content-Disposition: attachment; filename=\"diagram.xml\"");
 * echo($xml);
 * (end)
 * 
 * To open a local file, the file should be uploaded via a form in the browser
 * and then opened from the server in the editor.
 * 
 * Cell Properties:
 * 
 * The properties displayed in the properties dialog are the attributes and 
 * values of the cell's user object, which is an XML node. The XML node is 
 * defined in the templates section of the config file.
 * 
 * The templates are stored in <mxEditor.templates> and contain cells which
 * are cloned at insertion time to create new vertices by use of drag and
 * drop from the toolbar. Each entry in the toolbar for adding a new vertex
 * must refer to an existing template.
 * 
 * In the following example, the task node is a business object and only the 
 * mxCell node and its mxGeometry child contain graph information:
 * 
 * (code)
 * <Task label="Task" description="">
 *   <mxCell vertex="true">
 *     <mxGeometry as="geometry" width="72" height="32"/>
 *   </mxCell>
 * </Task> 
 * (end)
 * 
 * The idea is that the XML representation is inverse from the in-memory 
 * representation: The outer XML node is the user object and the inner node is 
 * the cell. This means the user object of the cell is the Task node with no 
 * children for the above example:
 * 
 * (code)
 * <Task label="Task" description=""/>
 * (end)
 * 
 * The Task node can have any tag name, attributes and child nodes. The 
 * <mxCodec> will use the XML hierarchy as the user object, while removing the 
 * "known annotations", such as the mxCell node. At save-time the cell data 
 * will be "merged" back into the user object. The user object is only modified 
 * via the properties dialog during the lifecycle of the cell.
 * 
 * In the default implementation of <createProperties>, the user object's
 * attributes are put into a form for editing. Attributes are changed using
 * the <mxCellAttributeChange> action in the model. The dialog can be replaced 
 * by overriding the <createProperties> hook or by replacing the showProperties
 * action in <actions>. Alternatively, the entry in the config file's popupmenu
 * section can be modified to invoke a different action.
 * 
 * If you want to displey the properties dialog on a doubleclick, you can set
 * <mxEditor.dblClickAction> to showProperties as follows:
 * 
 * (code)
 * editor.dblClickAction = 'showProperties';
 * (end)
 * 
 * Popupmenu and Toolbar:
 * 
 * The toolbar and popupmenu are typically configured using the respective
 * sections in the config file, that is, the popupmenu is defined as follows:
 * 
 * (code)
 * <mxEditor>
 *   <mxDefaultPopupMenu as="popupHandler">
 * 		<add as="cut" action="cut" icon="images/cut.gif"/>
 *      ...
 * (end)
 * 
 * New entries can be added to the toolbar by inserting an add-node into the
 * above configuration. Existing entries may be removed and changed by
 * modifying or removing the respective entries in the configuration.
 * The configuration is read by the <mxDefaultPopupMenuCodec>, the format of the
 * configuration is explained in <mxDefaultPopupMenu.decode>.
 * 
 * The toolbar is defined in the mxDefaultToolbar section. Items can be added
 * and removed in this section.
 * 
 * (code)
 * <mxEditor>
 *   <mxDefaultToolbar>
 *     <add as="save" action="save" icon="images/save.gif"/>
 *     <add as="Swimlane" template="swimlane" icon="images/swimlane.gif"/>
 *     ...
 * (end)
 * 
 * The format of the configuration is described in
 * <mxDefaultToolbarCodec.decode>.
 * 
 * Ids:
 * 
 * For the IDs, there is an implicit behaviour in <mxCodec>: It moves the Id
 * from the cell to the user object at encoding time and vice versa at decoding
 * time. For example, if the Task node from above has an id attribute, then
 * the <mxCell.id> of the corresponding cell will have this value. If there
 * is no Id collision in the model, then the cell may be retrieved using this
 * Id with the <mxGraphModel.getCell> function. If there is a collision, a new
 * Id will be created for the cell using <mxGraphModel.createId>. At encoding
 * time, this new Id will replace the value previously stored under the id
 * attribute in the Task node.
 * 
 * See <mxEditorCodec>, <mxDefaultToolbarCodec> and <mxDefaultPopupMenuCodec>
 * for information about configuring the editor and user interface.
 * 
 * Programmatically inserting cells:
 * 
 * For inserting a new cell, say, by clicking a button in the document,
 * the following code can be used. This requires an reference to the editor.
 * 
 * (code)
 * var userObject = new Object();
 * var parent = editor.graph.getDefaultParent();
 * var model = editor.graph.model;
 * model.beginUpdate();
 * try
 * {
 *   editor.graph.insertVertex(parent, null, userObject, 20, 20, 80, 30);
 * }
 * finally
 * {
 *   model.endUpdate();
 * }
 * (end)
 * 
 * If a template cell from the config file should be inserted, then a clone
 * of the template can be created as follows. The clone is then inserted using
 * the add function instead of addVertex.
 * 
 * (code)
 * var template = editor.templates['task'];
 * var clone = editor.graph.model.cloneCell(template);
 * (end)
 * 
 * Resources:
 *
 * resources/editor - Language resources for mxEditor
 *
 * Callback: onInit
 *
 * Called from within the constructor. In the callback,
 * "this" refers to the editor instance.
 *
 * Cookie: mxgraph=seen
 *
 * Set when the editor is started. Never expires. Use
 * <resetFirstTime> to reset this cookie. This cookie
 * only exists if <onInit> is implemented.
 *
 * Event: mxEvent.OPEN
 *
 * Fires after a file was opened in <open>. The <code>filename</code> property
 * contains the filename that was used. The same value is also available in
 * <filename>.
 *
 * Event: mxEvent.SAVE
 *
 * Fires after the current file was saved in <save>. The <code>url</code>
 * property contains the URL that was used for saving.
 *
 * Event: mxEvent.POST
 * 
 * Fires if a successful response was received in <postDiagram>. The
 * <code>request</code> property contains the <mxXmlRequest>, the
 * <code>url</code> and <code>data</code> properties contain the URL and the
 * data that were used in the post request. 
 *
 * Event: mxEvent.ROOT
 *
 * Fires when the current root has changed, or when the title of the current
 * root has changed. This event has no properties.
 *
 * Event: mxEvent.BEFORE_ADD_VERTEX
 * 
 * Fires before a vertex is added in <addVertex>. The <code>vertex</code>
 * property contains the new vertex and the <code>parent</code> property
 * contains its parent.
 * 
 * Event: mxEvent.ADD_VERTEX
 * 
 * Fires between begin- and endUpdate in <addVertex>. The <code>vertex</code>
 * property contains the vertex that is being inserted.
 * 
 * Event: mxEvent.AFTER_ADD_VERTEX
 * 
 * Fires after a vertex was inserted and selected in <addVertex>. The
 * <code>vertex</code> property contains the new vertex.
 * 
 * Example:
 * 
 * For starting an in-place edit after a new vertex has been added to the
 * graph, the following code can be used.
 * 
 * (code)
 * editor.addListener(mxEvent.AFTER_ADD_VERTEX, function(sender, evt)
 * {
 *   var vertex = evt.getProperty('vertex');
 * 
 *   if (editor.graph.isCellEditable(vertex))
 *   {
 *   	editor.graph.startEditingAtCell(vertex);
 *   }
 * });
 * (end)
 * 
 * Event: mxEvent.ESCAPE
 * 
 * Fires when the escape key is pressed. The <code>event</code> property
 * contains the key event.
 * 
 * Constructor: mxEditor
 *
 * Constructs a new editor. This function invokes the <onInit> callback
 * upon completion.
 *
 * Example:
 *
 * (code)
 * var config = mxUtils.load('config/diagrameditor.xml').getDocumentElement();
 * var editor = new mxEditor(config);
 * (end)
 * 
 * Parameters:
 * 
 * config - Optional XML node that contains the configuration.
 */
function mxEditor(config)
{
	this.actions = [];
	this.addActions();

	// Executes the following only if a document has been instanciated.
	// That is, don't execute when the editorcodec is setup.
	if (document.body != null)
	{
		// Defines instance fields
		this.cycleAttributeValues = [];
		this.popupHandler = new mxDefaultPopupMenu();
		this.undoManager = new mxUndoManager();

		// Creates the graph and toolbar without the containers
		this.graph = this.createGraph();
		this.toolbar = this.createToolbar();

		// Creates the global keyhandler (requires graph instance)
		this.keyHandler = new mxDefaultKeyHandler(this);

		// Configures the editor using the URI
		// which was passed to the ctor
		this.configure(config);
		
		// Assigns the swimlaneIndicatorColorAttribute on the graph
		this.graph.swimlaneIndicatorColorAttribute = this.cycleAttributeName;

		// Checks if the <onInit> hook has been set
		if (this.onInit != null)
		{
			// Invokes the <onInit> hook
			this.onInit();
		}
		
		// Automatic deallocation of memory
		if (mxClient.IS_IE)
		{
			mxEvent.addListener(window, 'unload', mxUtils.bind(this, function()
			{
				this.destroy();
			}));
		}
	}
};

/**
 * Installs the required language resources at class
 * loading time.
 */
if (mxLoadResources)
{
	mxResources.add(mxClient.basePath+'/resources/editor');
}

/**
 * Extends mxEventSource.
 */
mxEditor.prototype = new mxEventSource();
mxEditor.prototype.constructor = mxEditor;

/**
 * Group: Controls and Handlers
 */
	
/**
 * Variable: askZoomResource
 * 
 * Specifies the resource key for the zoom dialog. If the resource for this
 * key does not exist then the value is used as the error message. Default
 * is 'askZoom'.
 */
mxEditor.prototype.askZoomResource = (mxClient.language != 'none') ? 'askZoom' : '';
	
/**
 * Variable: lastSavedResource
 * 
 * Specifies the resource key for the last saved info. If the resource for
 * this key does not exist then the value is used as the error message.
 * Default is 'lastSaved'.
 */
mxEditor.prototype.lastSavedResource = (mxClient.language != 'none') ? 'lastSaved' : '';
	
/**
 * Variable: currentFileResource
 * 
 * Specifies the resource key for the current file info. If the resource for
 * this key does not exist then the value is used as the error message.
 * Default is 'lastSaved'.
 */
mxEditor.prototype.currentFileResource = (mxClient.language != 'none') ? 'currentFile' : '';
	
/**
 * Variable: propertiesResource
 * 
 * Specifies the resource key for the properties window title. If the
 * resource for this key does not exist then the value is used as the
 * error message. Default is 'properties'.
 */
mxEditor.prototype.propertiesResource = (mxClient.language != 'none') ? 'properties' : '';
	
/**
 * Variable: tasksResource
 * 
 * Specifies the resource key for the tasks window title. If the
 * resource for this key does not exist then the value is used as the
 * error message. Default is 'tasks'.
 */
mxEditor.prototype.tasksResource = (mxClient.language != 'none') ? 'tasks' : '';
	
/**
 * Variable: helpResource
 * 
 * Specifies the resource key for the help window title. If the
 * resource for this key does not exist then the value is used as the
 * error message. Default is 'help'.
 */
mxEditor.prototype.helpResource = (mxClient.language != 'none') ? 'help' : '';
	
/**
 * Variable: outlineResource
 * 
 * Specifies the resource key for the outline window title. If the
 * resource for this key does not exist then the value is used as the
 * error message. Default is 'outline'.
 */
mxEditor.prototype.outlineResource = (mxClient.language != 'none') ? 'outline' : '';
	
/**
 * Variable: outline
 * 
 * Reference to the <mxWindow> that contains the outline. The <mxOutline>
 * is stored in outline.outline.
 */
mxEditor.prototype.outline = null;

/**
 * Variable: graph
 *
 * Holds a <mxGraph> for displaying the diagram. The graph
 * is created in <setGraphContainer>.
 */
mxEditor.prototype.graph = null;

/**
 * Variable: graphRenderHint
 *
 * Holds the render hint used for creating the
 * graph in <setGraphContainer>. See <mxGraph>.
 * Default is null.
 */
mxEditor.prototype.graphRenderHint = null;

/**
 * Variable: toolbar
 *
 * Holds a <mxDefaultToolbar> for displaying the toolbar. The
 * toolbar is created in <setToolbarContainer>.
 */
mxEditor.prototype.toolbar = null;

/**
 * Variable: status
 *
 * DOM container that holds the statusbar. Default is null.
 * Use <setStatusContainer> to set this value.
 */
mxEditor.prototype.status = null;

/**
 * Variable: popupHandler
 *
 * Holds a <mxDefaultPopupMenu> for displaying
 * popupmenus.
 */
mxEditor.prototype.popupHandler = null;

/**
 * Variable: undoManager
 *
 * Holds an <mxUndoManager> for the command history.
 */
mxEditor.prototype.undoManager = null;

/**
 * Variable: keyHandler
 *
 * Holds a <mxDefaultKeyHandler> for handling keyboard events.
 * The handler is created in <setGraphContainer>.
 */
mxEditor.prototype.keyHandler = null;

/**
 * Group: Actions and Options
 */

/**
 * Variable: actions
 *
 * Maps from actionnames to actions, which are functions taking
 * the editor and the cell as arguments. Use <addAction>
 * to add or replace an action and <execute> to execute an action
 * by name, passing the cell to be operated upon as the second
 * argument.
 */
mxEditor.prototype.actions = null;

/**
 * Variable: dblClickAction
 *
 * Specifies the name of the action to be executed
 * when a cell is double clicked. Default is edit.
 * 
 * To handle a singleclick, use the following code.
 * 
 * (code)
 * editor.graph.addListener(mxEvent.CLICK, function(sender, evt)
 * {
 *   var e = evt.getProperty('event');
 *   var cell = evt.getProperty('cell');
 * 
 *   if (cell != null && !e.isConsumed())
 *   {
 *     // Do something useful with cell...
 *     e.consume();
 *   }
 * });
 * (end)
 */
mxEditor.prototype.dblClickAction = 'edit';

/**
 * Variable: swimlaneRequired
 * 
 * Specifies if new cells must be inserted
 * into an existing swimlane. Otherwise, cells
 * that are not swimlanes can be inserted as
 * top-level cells. Default is false.
 */
mxEditor.prototype.swimlaneRequired = false;

/**
 * Variable: disableContextMenu
 *
 * Specifies if the context menu should be disabled in the graph container.
 * Default is true.
 */
mxEditor.prototype.disableContextMenu = true;

/**
 * Group: Templates
 */

/**
 * Variable: insertFunction
 *
 * Specifies the function to be used for inserting new
 * cells into the graph. This is assigned from the
 * <mxDefaultToolbar> if a vertex-tool is clicked.
 */
mxEditor.prototype.insertFunction = null;

/**
 * Variable: forcedInserting
 *
 * Specifies if a new cell should be inserted on a single
 * click even using <insertFunction> if there is a cell 
 * under the mousepointer, otherwise the cell under the 
 * mousepointer is selected. Default is false.
 */
mxEditor.prototype.forcedInserting = false;

/**
 * Variable: templates
 * 
 * Maps from names to protoype cells to be used
 * in the toolbar for inserting new cells into
 * the diagram.
 */
mxEditor.prototype.templates = null;

/**
 * Variable: defaultEdge
 * 
 * Prototype edge cell that is used for creating
 * new edges.
 */
mxEditor.prototype.defaultEdge = null;

/**
 * Variable: defaultEdgeStyle
 * 
 * Specifies the edge style to be returned in <getEdgeStyle>.
 * Default is null.
 */
mxEditor.prototype.defaultEdgeStyle = null;

/**
 * Variable: defaultGroup
 * 
 * Prototype group cell that is used for creating
 * new groups.
 */
mxEditor.prototype.defaultGroup = null;

/**
 * Variable: graphRenderHint
 *
 * Default size for the border of new groups. If null,
 * then then <mxGraph.gridSize> is used. Default is
 * null.
 */
mxEditor.prototype.groupBorderSize = null;

/**
 * Group: Backend Integration
 */

/**
 * Variable: filename
 *
 * Contains the URL of the last opened file as a string.
 * Default is null.
 */
mxEditor.prototype.filename = null;

/**
 * Variable: lineFeed
 *
 * Character to be used for encoding linefeeds in <save>. Default is '&#xa;'.
 */
mxEditor.prototype.linefeed = '&#xa;';

/**
 * Variable: postParameterName
 *
 * Specifies if the name of the post parameter that contains the diagram
 * data in a post request to the server. Default is xml.
 */
mxEditor.prototype.postParameterName = 'xml';

/**
 * Variable: escapePostData
 *
 * Specifies if the data in the post request for saving a diagram
 * should be converted using encodeURIComponent. Default is true.
 */
mxEditor.prototype.escapePostData = true;

/**
 * Variable: urlPost
 *
 * Specifies the URL to be used for posting the diagram
 * to a backend in <save>.
 */
mxEditor.prototype.urlPost = null;

/**
 * Variable: urlImage
 *
 * Specifies the URL to be used for creating a bitmap of
 * the graph in the image action.
 */
mxEditor.prototype.urlImage = null;

/**
 * Group: Autolayout
 */

/**
 * Variable: horizontalFlow
 *
 * Specifies the direction of the flow
 * in the diagram. This is used in the
 * layout algorithms. Default is false,
 * ie. vertical flow.
 */
mxEditor.prototype.horizontalFlow = false;

/**
 * Variable: layoutDiagram
 *
 * Specifies if the top-level elements in the
 * diagram should be layed out using a vertical
 * or horizontal stack depending on the setting
 * of <horizontalFlow>. The spacing between the
 * swimlanes is specified by <swimlaneSpacing>.
 * Default is false.
 * 
 * If the top-level elements are swimlanes, then
 * the intra-swimlane layout is activated by
 * the <layoutSwimlanes> switch.
 */
mxEditor.prototype.layoutDiagram = false;

/**
 * Variable: swimlaneSpacing
 *
 * Specifies the spacing between swimlanes if
 * automatic layout is turned on in
 * <layoutDiagram>. Default is 0.
 */
mxEditor.prototype.swimlaneSpacing = 0;

/**
 * Variable: maintainSwimlanes
 * 
 * Specifies if the swimlanes should be kept at the same
 * width or height depending on the setting of
 * <horizontalFlow>.  Default is false.
 * 
 * For horizontal flows, all swimlanes
 * have the same height and for vertical flows, all swimlanes
 * have the same width. Furthermore, the swimlanes are
 * automatically "stacked" if <layoutDiagram> is true.
 */
mxEditor.prototype.maintainSwimlanes = false;

/**
 * Variable: layoutSwimlanes
 *
 * Specifies if the children of swimlanes should
 * be layed out, either vertically or horizontally
 * depending on <horizontalFlow>.
 * Default is false.
 */
mxEditor.prototype.layoutSwimlanes = false;

/**
 * Group: Attribute Cycling
 */
 
/**
 * Variable: cycleAttributeValues
 * 
 * Specifies the attribute values to be cycled when
 * inserting new swimlanes. Default is an empty
 * array.
 */
mxEditor.prototype.cycleAttributeValues = null;

/**
 * Variable: cycleAttributeIndex
 * 
 * Index of the last consumed attribute index. If a new
 * swimlane is inserted, then the <cycleAttributeValues>
 * at this index will be used as the value for
 * <cycleAttributeName>. Default is 0.
 */
mxEditor.prototype.cycleAttributeIndex = 0;

/**
 * Variable: cycleAttributeName
 * 
 * Name of the attribute to be assigned a <cycleAttributeValues>
 * when inserting new swimlanes. Default is fillColor.
 */
mxEditor.prototype.cycleAttributeName = 'fillColor';

/**
 * Group: Windows
 */

/**
 * Variable: tasks
 * 
 * Holds the <mxWindow> created in <showTasks>.
 */
mxEditor.prototype.tasks = null;

/**
 * Variable: tasksWindowImage
 *
 * Icon for the tasks window.
 */
mxEditor.prototype.tasksWindowImage = null;

/**
 * Variable: tasksTop
 * 
 * Specifies the top coordinate of the tasks window in pixels.
 * Default is 20.
 */
mxEditor.prototype.tasksTop = 20;

/**
 * Variable: help
 * 
 * Holds the <mxWindow> created in <showHelp>.
 */
mxEditor.prototype.help = null;

/**
 * Variable: helpWindowImage
 *
 * Icon for the help window.
 */
mxEditor.prototype.helpWindowImage = null;

/**
 * Variable: urlHelp
 *
 * Specifies the URL to be used for the contents of the
 * Online Help window. This is usually specified in the
 * resources file under urlHelp for language-specific
 * online help support.
 */
mxEditor.prototype.urlHelp = null;

/**
 * Variable: helpWidth
 * 
 * Specifies the width of the help window in pixels.
 * Default is 300.
 */
mxEditor.prototype.helpWidth = 300;
	
/**
 * Variable: helpWidth
 * 
 * Specifies the width of the help window in pixels.
 * Default is 260.
 */
mxEditor.prototype.helpHeight = 260;

/**
 * Variable: propertiesWidth
 * 
 * Specifies the width of the properties window in pixels.
 * Default is 240.
 */
mxEditor.prototype.propertiesWidth = 240;
		
/**
 * Variable: propertiesHeight
 * 
 * Specifies the height of the properties window in pixels.
 * If no height is specified then the window will be automatically
 * sized to fit its contents. Default is null.
 */
mxEditor.prototype.propertiesHeight = null;
		
/**
 * Variable: movePropertiesDialog
 *
 * Specifies if the properties dialog should be automatically
 * moved near the cell it is displayed for, otherwise the
 * dialog is not moved. This value is only taken into 
 * account if the dialog is already visible. Default is false.
 */
mxEditor.prototype.movePropertiesDialog = false;

/**
 * Variable: validating
 *
 * Specifies if <mxGraph.validateGraph> should automatically be invoked after
 * each change. Default is false.
 */
mxEditor.prototype.validating = false;

/**
 * Variable: modified
 *
 * True if the graph has been modified since it was last saved.
 */
mxEditor.prototype.modified = false;

/**
 * Function: isModified
 * 
 * Returns <modified>.
 */
mxEditor.prototype.isModified = function ()
{
	return this.modified;
};

/**
 * Function: setModified
 * 
 * Sets <modified> to the specified boolean value.
 */
mxEditor.prototype.setModified = function (value)
{
	this.modified = value;
};

/**
 * Function: addActions
 *
 * Adds the built-in actions to the editor instance.
 *
 * save - Saves the graph using <urlPost>.
 * print - Shows the graph in a new print preview window.
 * show - Shows the graph in a new window.
 * exportImage - Shows the graph as a bitmap image using <getUrlImage>.
 * refresh - Refreshes the graph's display.
 * cut - Copies the current selection into the clipboard
 * and removes it from the graph.
 * copy - Copies the current selection into the clipboard.
 * paste - Pastes the clipboard into the graph.
 * delete - Removes the current selection from the graph.
 * group - Puts the current selection into a new group.
 * ungroup - Removes the selected groups and selects the children.
 * undo - Undoes the last change on the graph model.
 * redo - Redoes the last change on the graph model.
 * zoom - Sets the zoom via a dialog.
 * zoomIn - Zooms into the graph.
 * zoomOut - Zooms out of the graph
 * actualSize - Resets the scale and translation on the graph.
 * fit - Changes the scale so that the graph fits into the window.
 * showProperties - Shows the properties dialog.
 * selectAll - Selects all cells.
 * selectNone - Clears the selection.
 * selectVertices - Selects all vertices.
 * selectEdges = Selects all edges.
 * edit - Starts editing the current selection cell.
 * enterGroup - Drills down into the current selection cell.
 * exitGroup - Moves up in the drilling hierachy
 * home - Moves to the topmost parent in the drilling hierarchy
 * selectPrevious - Selects the previous cell.
 * selectNext - Selects the next cell.
 * selectParent - Selects the parent of the selection cell.
 * selectChild - Selects the first child of the selection cell.
 * collapse - Collapses the currently selected cells.
 * expand - Expands the currently selected cells.
 * bold - Toggle bold text style.
 * italic - Toggle italic text style.
 * underline - Toggle underline text style.
 * alignCellsLeft - Aligns the selection cells at the left.
 * alignCellsCenter - Aligns the selection cells in the center.
 * alignCellsRight - Aligns the selection cells at the right.
 * alignCellsTop - Aligns the selection cells at the top.
 * alignCellsMiddle - Aligns the selection cells in the middle.
 * alignCellsBottom - Aligns the selection cells at the bottom.
 * alignFontLeft - Sets the horizontal text alignment to left.
 * alignFontCenter - Sets the horizontal text alignment to center.
 * alignFontRight - Sets the horizontal text alignment to right.
 * alignFontTop - Sets the vertical text alignment to top.
 * alignFontMiddle - Sets the vertical text alignment to middle.
 * alignFontBottom - Sets the vertical text alignment to bottom.
 * toggleTasks - Shows or hides the tasks window.
 * toggleHelp - Shows or hides the help window.
 * toggleOutline - Shows or hides the outline window.
 * toggleConsole - Shows or hides the console window.
 */
mxEditor.prototype.addActions = function ()
{
	this.addAction('save', function(editor)
	{
		editor.save();
	});
	
	this.addAction('print', function(editor)
	{
		var preview = new mxPrintPreview(editor.graph, 1);
		preview.open();
	});
	
	this.addAction('show', function(editor)
	{
		mxUtils.show(editor.graph, null, 10, 10);
	});

	this.addAction('exportImage', function(editor)
	{
		var url = editor.getUrlImage();
		
		if (url == null || mxClient.IS_LOCAL)
		{
			editor.execute('show');
		}
		else
		{
			var node = mxUtils.getViewXml(editor.graph, 1);
			var xml = mxUtils.getXml(node, '\n');

			mxUtils.submit(url, editor.postParameterName + '=' +
				encodeURIComponent(xml), document, '_blank');
		}
	});
	
	this.addAction('refresh', function(editor)
	{
		editor.graph.refresh();
	});
	
	this.addAction('cut', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			mxClipboard.cut(editor.graph);
		}
	});
	
	this.addAction('copy', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			mxClipboard.copy(editor.graph);
		}
	});
	
	this.addAction('paste', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			mxClipboard.paste(editor.graph);
		}
	});
	
	this.addAction('delete', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.removeCells();
		}
	});
	
	this.addAction('group', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.setSelectionCell(editor.groupCells());
		}
	});
	
	this.addAction('ungroup', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.setSelectionCells(editor.graph.ungroupCells());
		}
	});
	
	this.addAction('removeFromParent', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.removeCellsFromParent();
		}
	});
	
	this.addAction('undo', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.undo();
		}
	});
	
	this.addAction('redo', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.redo();
		}
	});
	
	this.addAction('zoomIn', function(editor)
	{
		editor.graph.zoomIn();
	});
	
	this.addAction('zoomOut', function(editor)
	{
		editor.graph.zoomOut();
	});
	
	this.addAction('actualSize', function(editor)
	{
		editor.graph.zoomActual();
	});
	
	this.addAction('fit', function(editor)
	{
		editor.graph.fit();
	});
	
	this.addAction('showProperties', function(editor, cell)
	{
		editor.showProperties(cell);
	});
	
	this.addAction('selectAll', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.selectAll();
		}
	});
	
	this.addAction('selectNone', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.clearSelection();
		}
	});
	
	this.addAction('selectVertices', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.selectVertices();
		}
	});
	
	this.addAction('selectEdges', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.selectEdges();
		}
	});
	
	this.addAction('edit', function(editor, cell)
	{
		if (editor.graph.isEnabled() &&
			editor.graph.isCellEditable(cell))
		{
			editor.graph.startEditingAtCell(cell);
		}
	});
	
	this.addAction('toBack', function(editor, cell)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.orderCells(true);
		}
	});
	
	this.addAction('toFront', function(editor, cell)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.orderCells(false);
		}
	});
	
	this.addAction('enterGroup', function(editor, cell)
	{
		editor.graph.enterGroup(cell);
	});
	
	this.addAction('exitGroup', function(editor)
	{
		editor.graph.exitGroup();
	});
	
	this.addAction('home', function(editor)
	{
		editor.graph.home();
	});
	
	this.addAction('selectPrevious', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.selectPreviousCell();
		}
	});
	
	this.addAction('selectNext', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.selectNextCell();
		}
	});
	
	this.addAction('selectParent', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.selectParentCell();
		}
	});
	
	this.addAction('selectChild', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.selectChildCell();
		}
	});
	
	this.addAction('collapse', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.foldCells(true);
		}
	});
	
	this.addAction('collapseAll', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			var cells = editor.graph.getChildVertices();
			editor.graph.foldCells(true, false, cells);
		}
	});
	
	this.addAction('expand', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.foldCells(false);
		}
	});
	
	this.addAction('expandAll', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			var cells = editor.graph.getChildVertices();
			editor.graph.foldCells(false, false, cells);
		}
	});
	
	this.addAction('bold', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.toggleCellStyleFlags(
				mxConstants.STYLE_FONTSTYLE,
				mxConstants.FONT_BOLD);
		}
	});
	
	this.addAction('italic', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.toggleCellStyleFlags(
				mxConstants.STYLE_FONTSTYLE,
				mxConstants.FONT_ITALIC);
		}
	});
	
	this.addAction('underline', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.toggleCellStyleFlags(
				mxConstants.STYLE_FONTSTYLE,
				mxConstants.FONT_UNDERLINE);
		}
	});

	this.addAction('alignCellsLeft', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.alignCells(mxConstants.ALIGN_LEFT);
		}
	});
	
	this.addAction('alignCellsCenter', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.alignCells(mxConstants.ALIGN_CENTER);
		}
	});
	
	this.addAction('alignCellsRight', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.alignCells(mxConstants.ALIGN_RIGHT);
		}
	});
	
	this.addAction('alignCellsTop', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.alignCells(mxConstants.ALIGN_TOP);
		}
	});
	
	this.addAction('alignCellsMiddle', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.alignCells(mxConstants.ALIGN_MIDDLE);
		}
	});
	
	this.addAction('alignCellsBottom', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.alignCells(mxConstants.ALIGN_BOTTOM);
		}
	});
	
	this.addAction('alignFontLeft', function(editor)
	{
		
		editor.graph.setCellStyles(
			mxConstants.STYLE_ALIGN,
			mxConstants.ALIGN_LEFT);
	});
	
	this.addAction('alignFontCenter', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.setCellStyles(
				mxConstants.STYLE_ALIGN,
				mxConstants.ALIGN_CENTER);
		}
	});
	
	this.addAction('alignFontRight', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.setCellStyles(
				mxConstants.STYLE_ALIGN,
				mxConstants.ALIGN_RIGHT);
		}
	});
	
	this.addAction('alignFontTop', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.setCellStyles(
				mxConstants.STYLE_VERTICAL_ALIGN,
				mxConstants.ALIGN_TOP);
		}
	});
	
	this.addAction('alignFontMiddle', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.setCellStyles(
				mxConstants.STYLE_VERTICAL_ALIGN,
				mxConstants.ALIGN_MIDDLE);
		}
	});
	
	this.addAction('alignFontBottom', function(editor)
	{
		if (editor.graph.isEnabled())
		{
			editor.graph.setCellStyles(
				mxConstants.STYLE_VERTICAL_ALIGN,
				mxConstants.ALIGN_BOTTOM);
		}
	});
	
	this.addAction('zoom', function(editor)
	{
		var current = editor.graph.getView().scale*100;
		var scale = parseFloat(mxUtils.prompt(
			mxResources.get(editor.askZoomResource) ||
			editor.askZoomResource,
			current))/100;

		if (!isNaN(scale))
		{
			editor.graph.getView().setScale(scale);
		}
	});
	
	this.addAction('toggleTasks', function(editor)
	{
		if (editor.tasks != null)
		{
			editor.tasks.setVisible(!editor.tasks.isVisible());
		}
		else
		{
			editor.showTasks();
		}
	});
	
	this.addAction('toggleHelp', function(editor)
	{
		if (editor.help != null)
		{
			editor.help.setVisible(!editor.help.isVisible());
		}
		else
		{
			editor.showHelp();
		}
	});
	
	this.addAction('toggleOutline', function(editor)
	{
		if (editor.outline == null)
		{
			editor.showOutline();
		}
		else
		{
			editor.outline.setVisible(!editor.outline.isVisible());
		}
	});
	
	this.addAction('toggleConsole', function(editor)
	{
		mxLog.setVisible(!mxLog.isVisible());
	});
};

/**
 * Function: configure
 *
 * Configures the editor using the specified node. To load the
 * configuration from a given URL the following code can be used to obtain
 * the XML node.
 * 
 * (code)
 * var node = mxUtils.load(url).getDocumentElement();
 * (end)
 * 
 * Parameters:
 * 
 * node - XML node that contains the configuration.
 */
mxEditor.prototype.configure = function (node)
{
	if (node != null)
	{
		// Creates a decoder for the XML data
		// and uses it to configure the editor
		var dec = new mxCodec(node.ownerDocument);
		dec.decode(node, this);
		
		// Resets the counters, modified state and
		// command history
		this.resetHistory();
	}
};

/**
 * Function: resetFirstTime
 * 
 * Resets the cookie that is used to remember if the editor has already
 * been used.
 */
mxEditor.prototype.resetFirstTime = function ()
{
	document.cookie =
		'mxgraph=seen; expires=Fri, 27 Jul 2001 02:47:11 UTC; path=/';
};

/**
 * Function: resetHistory
 * 
 * Resets the command history, modified state and counters.
 */
mxEditor.prototype.resetHistory = function ()
{
	this.lastSnapshot = new Date().getTime();
	this.undoManager.clear();
	this.ignoredChanges = 0;
	this.setModified(false);
};

/**
 * Function: addAction
 * 
 * Binds the specified actionname to the specified function.
 * 
 * Parameters:
 * 
 * actionname - String that specifies the name of the action
 * to be added.
 * funct - Function that implements the new action. The first
 * argument of the function is the editor it is used
 * with, the second argument is the cell it operates
 * upon.
 * 
 * Example:
 * (code)
 * editor.addAction('test', function(editor, cell)
 * {
 * 		mxUtils.alert("test "+cell);
 * });
 * (end)
 */
mxEditor.prototype.addAction = function (actionname, funct)
{
	this.actions[actionname] = funct;
};

/**
 * Function: execute
 * 
 * Executes the function with the given name in <actions> passing the
 * editor instance and given cell as the first and second argument. All
 * additional arguments are passed to the action as well. This method
 * contains a try-catch block and displays an error message if an action
 * causes an exception. The exception is re-thrown after the error
 * message was displayed.
 * 
 * Example:
 * 
 * (code)
 * editor.execute("showProperties", cell);
 * (end)
 */
mxEditor.prototype.execute = function (actionname, cell, evt)
{
	var action = this.actions[actionname];
	
	if (action != null)
	{
		try
		{
			// Creates the array of arguments by replacing the actionname
			// with the editor instance in the args of this function
			var args = arguments;
			args[0] = this;
			
			// Invokes the function on the editor using the args
			action.apply(this, args);
		}
		catch (e)
		{
			mxUtils.error('Cannot execute ' + actionname +
				': ' + e.message, 280, true);
			
			throw e;
		}
	}
	else
	{
		mxUtils.error('Cannot find action '+actionname, 280, true);
	}
};

/**
 * Function: addTemplate
 * 
 * Adds the specified template under the given name in <templates>.
 */
mxEditor.prototype.addTemplate = function (name, template)
{
	this.templates[name] = template;
};

/**
 * Function: getTemplate
 * 
 * Returns the template for the given name.
 */
mxEditor.prototype.getTemplate = function (name)
{
	return this.templates[name];
};

/**
 * Function: createGraph
 * 
 * Creates the <graph> for the editor. The graph is created with no
 * container and is initialized from <setGraphContainer>.
 */
mxEditor.prototype.createGraph = function ()
{
	var graph = new mxGraph(null, null, this.graphRenderHint);
	
	// Enables rubberband, tooltips, panning
	graph.setTooltips(true);
	graph.setPanning(true);

	// Overrides the dblclick method on the graph to
	// invoke the dblClickAction for a cell and reset
	// the selection tool in the toolbar
	this.installDblClickHandler(graph);
	
	// Installs the command history
	this.installUndoHandler(graph);

	// Installs the handlers for the root event
	this.installDrillHandler(graph);
	
	// Installs the handler for validation
	this.installChangeHandler(graph);

	// Installs the handler for calling the
	// insert function and consume the
	// event if an insert function is defined
	this.installInsertHandler(graph);

	// Redirects the function for creating the
	// popupmenu items
	graph.popupMenuHandler.factoryMethod =
		mxUtils.bind(this, function(menu, cell, evt)
		{
			return this.createPopupMenu(menu, cell, evt);
		});

	// Redirects the function for creating
	// new connections in the diagram
	graph.connectionHandler.factoryMethod =
		mxUtils.bind(this, function(source, target)
		{
			return this.createEdge(source, target);
		});
	
	// Maintains swimlanes and installs autolayout
	this.createSwimlaneManager(graph);
	this.createLayoutManager(graph);
	
	return graph;
};

/**
 * Function: createSwimlaneManager
 * 
 * Sets the graph's container using <mxGraph.init>.
 */
mxEditor.prototype.createSwimlaneManager = function (graph)
{
	var swimlaneMgr = new mxSwimlaneManager(graph, false);

	swimlaneMgr.isHorizontal = mxUtils.bind(this, function()
	{
		return this.horizontalFlow;
	});
	
	swimlaneMgr.isEnabled = mxUtils.bind(this, function()
	{
		return this.maintainSwimlanes;
	});
	
	return swimlaneMgr;
};

/**
 * Function: createLayoutManager
 * 
 * Creates a layout manager for the swimlane and diagram layouts, that
 * is, the locally defined inter- and intraswimlane layouts.
 */
mxEditor.prototype.createLayoutManager = function (graph)
{
	var layoutMgr = new mxLayoutManager(graph);
	
	var self = this; // closure
	layoutMgr.getLayout = function(cell)
	{
		var layout = null;
		var model = self.graph.getModel();
		
		if (model.getParent(cell) != null)
		{
			// Executes the swimlane layout if a child of
			// a swimlane has been changed. The layout is
			// lazy created in createSwimlaneLayout.
			if (self.layoutSwimlanes &&
				graph.isSwimlane(cell))
			{
				if (self.swimlaneLayout == null)
				{
					self.swimlaneLayout = self.createSwimlaneLayout();
				}
				
				layout = self.swimlaneLayout;
			}
			
			// Executes the diagram layout if the modified
			// cell is a top-level cell. The layout is
			// lazy created in createDiagramLayout.
			else if (self.layoutDiagram &&
				(graph.isValidRoot(cell) ||
				model.getParent(model.getParent(cell)) == null))
			{
				if (self.diagramLayout == null)
				{
					self.diagramLayout = self.createDiagramLayout();
				}
				
				layout = self.diagramLayout;
			}
		}
			
		return layout;
	};
	
	return layoutMgr;
};

/**
 * Function: setGraphContainer
 * 
 * Sets the graph's container using <mxGraph.init>.
 */
mxEditor.prototype.setGraphContainer = function (container)
{
	if (this.graph.container == null)
	{
		// Creates the graph instance inside the given container and render hint
		//this.graph = new mxGraph(container, null, this.graphRenderHint);
		this.graph.init(container);

		// Install rubberband selection as the last
		// action handler in the chain
		this.rubberband = new mxRubberband(this.graph);

		// Disables the context menu
		if (this.disableContextMenu)
		{
			mxEvent.disableContextMenu(container);
		}

		// Workaround for stylesheet directives in IE
		if (mxClient.IS_QUIRKS)
		{
			new mxDivResizer(container);
		}
	}
};

/**
 * Function: installDblClickHandler
 * 
 * Overrides <mxGraph.dblClick> to invoke <dblClickAction>
 * on a cell and reset the selection tool in the toolbar.
 */
mxEditor.prototype.installDblClickHandler = function (graph)
{
	// Installs a listener for double click events
	graph.addListener(mxEvent.DOUBLE_CLICK,
		mxUtils.bind(this, function(sender, evt)
		{
			var cell = evt.getProperty('cell');
			
			if (cell != null &&
				graph.isEnabled() &&
				this.dblClickAction != null)
			{
				this.execute(this.dblClickAction, cell);
				evt.consume();
			}
		})
	);
};
		
/**
 * Function: installUndoHandler
 * 
 * Adds the <undoManager> to the graph model and the view.
 */
mxEditor.prototype.installUndoHandler = function (graph)
{				
	var listener = mxUtils.bind(this, function(sender, evt)
	{
		var edit = evt.getProperty('edit');
		this.undoManager.undoableEditHappened(edit);
	});
	
	graph.getModel().addListener(mxEvent.UNDO, listener);
	graph.getView().addListener(mxEvent.UNDO, listener);

	// Keeps the selection state in sync
	var undoHandler = function(sender, evt)
	{
		var changes = evt.getProperty('edit').changes;
		graph.setSelectionCells(graph.getSelectionCellsForChanges(changes));
	};
	
	this.undoManager.addListener(mxEvent.UNDO, undoHandler);
	this.undoManager.addListener(mxEvent.REDO, undoHandler);
};
		
/**
 * Function: installDrillHandler
 * 
 * Installs listeners for dispatching the <root> event.
 */
mxEditor.prototype.installDrillHandler = function (graph)
{				
	var listener = mxUtils.bind(this, function(sender)
	{
		this.fireEvent(new mxEventObject(mxEvent.ROOT));
	});
	
	graph.getView().addListener(mxEvent.DOWN, listener);
	graph.getView().addListener(mxEvent.UP, listener);
};

/**
 * Function: installChangeHandler
 * 
 * Installs the listeners required to automatically validate
 * the graph. On each change of the root, this implementation
 * fires a <root> event.
 */
mxEditor.prototype.installChangeHandler = function (graph)
{
	var listener = mxUtils.bind(this, function(sender, evt)
	{
		// Updates the modified state
		this.setModified(true);

		// Automatically validates the graph
		// after each change
		if (this.validating == true)
		{
			graph.validateGraph();
		}

		// Checks if the root has been changed
		var changes = evt.getProperty('edit').changes;
		
		for (var i = 0; i < changes.length; i++)
		{
			var change = changes[i];
			
			if (change instanceof mxRootChange ||
				(change instanceof mxValueChange &&
				change.cell == this.graph.model.root) ||
				(change instanceof mxCellAttributeChange &&
				change.cell == this.graph.model.root))
			{
				this.fireEvent(new mxEventObject(mxEvent.ROOT));
				break;
			}
		}
	});
	
	graph.getModel().addListener(mxEvent.CHANGE, listener);
};

/**
 * Function: installInsertHandler
 * 
 * Installs the handler for invoking <insertFunction> if
 * one is defined.
 */
mxEditor.prototype.installInsertHandler = function (graph)
{
	var self = this; // closure
	var insertHandler =
	{
		mouseDown: function(sender, me)
		{
			if (self.insertFunction != null &&
				!me.isPopupTrigger() &&
				(self.forcedInserting ||
				me.getState() == null))
			{
				self.graph.clearSelection();
				self.insertFunction(me.getEvent(), me.getCell());

				// Consumes the rest of the events
				// for this gesture (down, move, up)
				this.isActive = true;
				me.consume();
			}
		},
		
		mouseMove: function(sender, me)
		{
			if (this.isActive)
			{
				me.consume();
			}
		},
		
		mouseUp: function(sender, me)
		{
			if (this.isActive)
			{
				this.isActive = false;
				me.consume();
			}
		}
	};
	
	graph.addMouseListener(insertHandler);
};

/**
 * Function: createDiagramLayout
 * 
 * Creates the layout instance used to layout the
 * swimlanes in the diagram.
 */
mxEditor.prototype.createDiagramLayout = function ()
{
	var gs = this.graph.gridSize;
	var layout = new mxStackLayout(this.graph, !this.horizontalFlow,
		 this.swimlaneSpacing, 2*gs, 2*gs);
	
	// Overrides isIgnored to only take into account swimlanes
	layout.isVertexIgnored = function(cell)
	{
		return !layout.graph.isSwimlane(cell);
	};
	
	return layout;
};

/**
 * Function: createSwimlaneLayout
 * 
 * Creates the layout instance used to layout the
 * children of each swimlane.
 */
mxEditor.prototype.createSwimlaneLayout = function ()
{
	return new mxCompactTreeLayout(this.graph, this.horizontalFlow);
};

/**
 * Function: createToolbar
 * 
 * Creates the <toolbar> with no container.
 */
mxEditor.prototype.createToolbar = function ()
{
	return new mxDefaultToolbar(null, this);
};

/**
 * Function: setToolbarContainer
 * 
 * Initializes the toolbar for the given container.
 */
mxEditor.prototype.setToolbarContainer = function (container)
{
	this.toolbar.init(container);
	
	// Workaround for stylesheet directives in IE
	if (mxClient.IS_QUIRKS)
	{
		new mxDivResizer(container);
	}
};

/**
 * Function: setStatusContainer
 * 
 * Creates the <status> using the specified container.
 * 
 * This implementation adds listeners in the editor to 
 * display the last saved time and the current filename 
 * in the status bar.
 * 
 * Parameters:
 * 
 * container - DOM node that will contain the statusbar.
 */
mxEditor.prototype.setStatusContainer = function (container)
{
	if (this.status == null)
	{
		this.status = container;
		
		// Prints the last saved time in the status bar
		// when files are saved
		this.addListener(mxEvent.SAVE, mxUtils.bind(this, function()
		{
			var tstamp = new Date().toLocaleString();
			this.setStatus((mxResources.get(this.lastSavedResource) ||
				this.lastSavedResource)+': '+tstamp);
		}));
		
		// Updates the statusbar to display the filename
		// when new files are opened
		this.addListener(mxEvent.OPEN, mxUtils.bind(this, function()
		{
			this.setStatus((mxResources.get(this.currentFileResource) ||
				this.currentFileResource)+': '+this.filename);
		}));
		
		// Workaround for stylesheet directives in IE
		if (mxClient.IS_QUIRKS)
		{
			new mxDivResizer(container);
		}
	}
};

/**
 * Function: setStatus
 * 
 * Display the specified message in the status bar.
 * 
 * Parameters:
 * 
 * message - String the specified the message to
 * be displayed.
 */
mxEditor.prototype.setStatus = function (message)
{
	if (this.status != null && message != null)
	{
		this.status.innerHTML = message;
	}
};

/**
 * Function: setTitleContainer
 * 
 * Creates a listener to update the inner HTML of the
 * specified DOM node with the value of <getTitle>.
 * 
 * Parameters:
 * 
 * container - DOM node that will contain the title.
 */
mxEditor.prototype.setTitleContainer = function (container)
{
	this.addListener(mxEvent.ROOT, mxUtils.bind(this, function(sender)
	{
		container.innerHTML = this.getTitle();
	}));

	// Workaround for stylesheet directives in IE
	if (mxClient.IS_QUIRKS)
	{
		new mxDivResizer(container);
	}
};

/**
 * Function: treeLayout
 * 
 * Executes a vertical or horizontal compact tree layout
 * using the specified cell as an argument. The cell may
 * either be a group or the root of a tree.
 * 
 * Parameters:
 * 
 * cell - <mxCell> to use in the compact tree layout.
 * horizontal - Optional boolean to specify the tree's
 * orientation. Default is true.
 */
mxEditor.prototype.treeLayout = function (cell, horizontal)
{
	if (cell != null)
	{
		var layout = new mxCompactTreeLayout(this.graph, horizontal);
		layout.execute(cell);
	}
};

/**
 * Function: getTitle
 * 
 * Returns the string value for the current root of the
 * diagram.
 */
mxEditor.prototype.getTitle = function ()
{
	var title = '';
	var graph = this.graph;
	var cell = graph.getCurrentRoot();
	
	while (cell != null &&
		   graph.getModel().getParent(
				graph.getModel().getParent(cell)) != null)
	{
		// Append each label of a valid root
		if (graph.isValidRoot(cell))
		{
			title = ' > ' +
			graph.convertValueToString(cell) + title;
		}
		
		cell = graph.getModel().getParent(cell);
	}
	
	var prefix = this.getRootTitle();
	
	return prefix + title;
};

/**
 * Function: getRootTitle
 * 
 * Returns the string value of the root cell in
 * <mxGraph.model>.
 */
mxEditor.prototype.getRootTitle = function ()
{
	var root = this.graph.getModel().getRoot();
	return this.graph.convertValueToString(root);
};

/**
 * Function: undo
 * 
 * Undo the last change in <graph>.
 */
mxEditor.prototype.undo = function ()
{
	this.undoManager.undo();
};

/**
 * Function: redo
 * 
 * Redo the last change in <graph>.
 */
mxEditor.prototype.redo = function ()
{
	this.undoManager.redo();
};

/**
 * Function: groupCells
 * 
 * Invokes <createGroup> to create a new group cell and the invokes
 * <mxGraph.groupCells>, using the grid size of the graph as the spacing
 * in the group's content area.
 */
mxEditor.prototype.groupCells = function ()
{
	var border = (this.groupBorderSize != null) ?
		this.groupBorderSize :
		this.graph.gridSize;
	return this.graph.groupCells(this.createGroup(), border);
};

/**
 * Function: createGroup
 * 
 * Creates and returns a clone of <defaultGroup> to be used
 * as a new group cell in <group>.
 */
mxEditor.prototype.createGroup = function ()
{
	var model = this.graph.getModel();
	
	return model.cloneCell(this.defaultGroup);
};

/**
 * Function: open
 * 
 * Opens the specified file synchronously and parses it using
 * <readGraphModel>. It updates <filename> and fires an <open>-event after
 * the file has been opened. Exceptions should be handled as follows:
 * 
 * (code)
 * try
 * {
 *   editor.open(filename);
 * }
 * catch (e)
 * {
 *   mxUtils.error('Cannot open ' + filename +
 *     ': ' + e.message, 280, true);
 * }
 * (end)
 *
 * Parameters:
 * 
 * filename - URL of the file to be opened.
 */
mxEditor.prototype.open = function (filename)
{
	if (filename != null)
	{
		var xml = mxUtils.load(filename).getXml();
		this.readGraphModel(xml.documentElement);
		this.filename = filename;
		
		this.fireEvent(new mxEventObject(mxEvent.OPEN, 'filename', filename));
	}
};

/**
 * Function: readGraphModel
 * 
 * Reads the specified XML node into the existing graph model and resets
 * the command history and modified state.
 */
mxEditor.prototype.readGraphModel = function (node)
{
	var dec = new mxCodec(node.ownerDocument);
	dec.decode(node, this.graph.getModel());
	this.resetHistory();
};

/**
 * Function: save
 * 
 * Posts the string returned by <writeGraphModel> to the given URL or the
 * URL returned by <getUrlPost>. The actual posting is carried out by
 * <postDiagram>. If the URL is null then the resulting XML will be
 * displayed using <mxUtils.popup>. Exceptions should be handled as
 * follows:
 * 
 * (code)
 * try
 * {
 *   editor.save();
 * }
 * catch (e)
 * {
 *   mxUtils.error('Cannot save : ' + e.message, 280, true);
 * }
 * (end)
 */
mxEditor.prototype.save = function (url, linefeed)
{
	// Gets the URL to post the data to
	url = url || this.getUrlPost();

	// Posts the data if the URL is not empty
	if (url != null && url.length > 0)
	{
		var data = this.writeGraphModel(linefeed);
		this.postDiagram(url, data);
		
		// Resets the modified flag
		this.setModified(false);
	}
	
	// Dispatches a save event
	this.fireEvent(new mxEventObject(mxEvent.SAVE, 'url', url));
};

/**
 * Function: postDiagram
 * 
 * Hook for subclassers to override the posting of a diagram
 * represented by the given node to the given URL. This fires
 * an asynchronous <post> event if the diagram has been posted.
 * 
 * Example:
 * 
 * To replace the diagram with the diagram in the response, use the
 * following code.
 * 
 * (code)
 * editor.addListener(mxEvent.POST, function(sender, evt)
 * {
 *   // Process response (replace diagram)
 *   var req = evt.getProperty('request');
 *   var root = req.getDocumentElement();
 *   editor.graph.readGraphModel(root)
 * });
 * (end)
 */
mxEditor.prototype.postDiagram = function (url, data)
{
	if (this.escapePostData)
	{
		data = encodeURIComponent(data);
	}

	mxUtils.post(url, this.postParameterName+'='+data,
		mxUtils.bind(this, function(req)
		{
			this.fireEvent(new mxEventObject(mxEvent.POST,
				'request', req, 'url', url, 'data', data));
		})
	);
};

/**
 * Function: writeGraphModel
 * 
 * Hook to create the string representation of the diagram. The default
 * implementation uses an <mxCodec> to encode the graph model as
 * follows:
 * 
 * (code)
 * var enc = new mxCodec();
 * var node = enc.encode(this.graph.getModel());
 * return mxUtils.getXml(node, this.linefeed);
 * (end)
 * 
 * Parameters:
 * 
 * linefeed - Optional character to be used as the linefeed. Default is
 * <linefeed>.
 */
mxEditor.prototype.writeGraphModel = function (linefeed)
{
	linefeed = (linefeed != null) ? linefeed : this.linefeed;
	var enc = new mxCodec();
	var node = enc.encode(this.graph.getModel());

	return mxUtils.getXml(node, linefeed);
};

/**
 * Function: getUrlPost
 * 
 * Returns the URL to post the diagram to. This is used
 * in <save>. The default implementation returns <urlPost>,
 * adding <code>?draft=true</code>.
 */
mxEditor.prototype.getUrlPost = function ()
{
	return this.urlPost;
};

/**
 * Function: getUrlImage
 * 
 * Returns the URL to create the image with. This is typically
 * the URL of a backend which accepts an XML representation
 * of a graph view to create an image. The function is used
 * in the image action to create an image. This implementation
 * returns <urlImage>.
 */
mxEditor.prototype.getUrlImage = function ()
{
	return this.urlImage;
};

/**
 * Function: swapStyles
 * 
 * Swaps the styles for the given names in the graph's
 * stylesheet and refreshes the graph.
 */
mxEditor.prototype.swapStyles = function (first, second)
{
	var style = this.graph.getStylesheet().styles[second];
	this.graph.getView().getStylesheet().putCellStyle(
		second, this.graph.getStylesheet().styles[first]);
	this.graph.getStylesheet().putCellStyle(first, style);
	this.graph.refresh();
};

/**
 * Function: showProperties
 * 
 * Creates and shows the properties dialog for the given
 * cell. The content area of the dialog is created using
 * <createProperties>.
 */
mxEditor.prototype.showProperties = function (cell)
{
	cell = cell || this.graph.getSelectionCell();
	
	// Uses the root node for the properties dialog
	// if not cell was passed in and no cell is
	// selected
	if (cell == null)
	{
		cell = this.graph.getCurrentRoot();
		
		if (cell == null)
		{
			cell = this.graph.getModel().getRoot();
		}
	}
	
	if (cell != null)
	{
		// Makes sure there is no in-place editor in the
		// graph and computes the location of the dialog
		this.graph.stopEditing(true);

		var offset = mxUtils.getOffset(this.graph.container);
		var x = offset.x+10;
		var y = offset.y;
		
		// Avoids moving the dialog if it is alredy open
		if (this.properties != null && !this.movePropertiesDialog)
		{
			x = this.properties.getX();
			y = this.properties.getY();
		}
		
		// Places the dialog near the cell for which it
		// displays the properties
		else
		{
			var bounds = this.graph.getCellBounds(cell);
			
			if (bounds != null)
			{
				x += bounds.x+Math.min(200, bounds.width);
				y += bounds.y;				
			}			
		}
		
		// Hides the existing properties dialog and creates a new one with the
		// contents created in the hook method
		this.hideProperties();
		var node = this.createProperties(cell);
		
		if (node != null)
		{
			// Displays the contents in a window and stores a reference to the
			// window for later hiding of the window
			this.properties = new mxWindow(mxResources.get(this.propertiesResource) ||
				this.propertiesResource, node, x, y, this.propertiesWidth, this.propertiesHeight, false);
			this.properties.setVisible(true);
		}
	}
};

/**
 * Function: isPropertiesVisible
 * 
 * Returns true if the properties dialog is currently visible.
 */
mxEditor.prototype.isPropertiesVisible = function ()
{
	return this.properties != null;
};

/**
 * Function: createProperties
 * 
 * Creates and returns the DOM node that represents the contents
 * of the properties dialog for the given cell. This implementation
 * works for user objects that are XML nodes and display all the
 * node attributes in a form.
 */
mxEditor.prototype.createProperties = function (cell)
{
	var model = this.graph.getModel();
	var value = model.getValue(cell);
	
	if (mxUtils.isNode(value))
	{
		// Creates a form for the user object inside
		// the cell
		var form = new mxForm('properties');
		
		// Adds a readonly field for the cell id
		var id = form.addText('ID', cell.getId());
		id.setAttribute('readonly', 'true');

		var geo = null;
		var yField = null;
		var xField = null;
		var widthField = null;
		var heightField = null;

		// Adds fields for the location and size
		if (model.isVertex(cell))
		{
			geo = model.getGeometry(cell);
			
			if (geo != null)
			{
				yField = form.addText('top', geo.y);
				xField = form.addText('left', geo.x);
				widthField = form.addText('width', geo.width);
				heightField = form.addText('height', geo.height);
			}
		}
		
		// Adds a field for the cell style			
		var tmp = model.getStyle(cell);
		var style = form.addText('Style', tmp || '');
		
		// Creates textareas for each attribute of the
		// user object within the cell
		var attrs = value.attributes;
		var texts = [];
		
		for (var i = 0; i < attrs.length; i++)
		{
			// Creates a textarea with more lines for
			// the cell label
			var val = attrs[i].value;
			texts[i] = form.addTextarea(attrs[i].nodeName, val,
				(attrs[i].nodeName == 'label') ? 4 : 2);
		}
		
		// Adds an OK and Cancel button to the dialog
		// contents and implements the respective
		// actions below
		
		// Defines the function to be executed when the
		// OK button is pressed in the dialog
		var okFunction = mxUtils.bind(this, function()
		{
			// Hides the dialog
			this.hideProperties();
			
			// Supports undo for the changes on the underlying
			// XML structure / XML node attribute changes.
			model.beginUpdate();
			try
			{
				if (geo != null)
				{
					geo = geo.clone();
					
					geo.x = parseFloat(xField.value);
					geo.y = parseFloat(yField.value);
					geo.width = parseFloat(widthField.value);
					geo.height = parseFloat(heightField.value);
					
					model.setGeometry(cell, geo);
				}
				
				// Applies the style
				if (style.value.length > 0)
				{
					model.setStyle(cell, style.value);
				}
				else
				{
					model.setStyle(cell, null);
				}
				
				// Creates an undoable change for each
				// attribute and executes it using the
				// model, which will also make the change
				// part of the current transaction
				for (var i=0; i<attrs.length; i++)
				{
					var edit = new mxCellAttributeChange(
						cell, attrs[i].nodeName,
						texts[i].value);
					model.execute(edit);
				}
				
				// Checks if the graph wants cells to 
				// be automatically sized and updates
				// the size as an undoable step if
				// the feature is enabled
				if (this.graph.isAutoSizeCell(cell))
				{
					this.graph.updateCellSize(cell);
				}
			}
			finally
			{
				model.endUpdate();
			}
		});
		
		// Defines the function to be executed when the
		// Cancel button is pressed in the dialog
		var cancelFunction = mxUtils.bind(this, function()
		{
			// Hides the dialog
			this.hideProperties();
		});
		
		form.addButtons(okFunction, cancelFunction);
		
		return form.table;
	}

	return null;
};

/**
 * Function: hideProperties
 * 
 * Hides the properties dialog.
 */
mxEditor.prototype.hideProperties = function ()
{
	if (this.properties != null)
	{
		this.properties.destroy();
		this.properties = null;
	}
};

/**
 * Function: showTasks
 * 
 * Shows the tasks window. The tasks window is created using <createTasks>. The
 * default width of the window is 200 pixels, the y-coordinate of the location
 * can be specifies in <tasksTop> and the x-coordinate is right aligned with a
 * 20 pixel offset from the right border. To change the location of the tasks
 * window, the following code can be used:
 * 
 * (code)
 * var oldShowTasks = mxEditor.prototype.showTasks;
 * mxEditor.prototype.showTasks = function()
 * {
 *   oldShowTasks.apply(this, arguments); // "supercall"
 *   
 *   if (this.tasks != null)
 *   {
 *     this.tasks.setLocation(10, 10);
 *   }
 * };
 * (end)
 */
mxEditor.prototype.showTasks = function ()
{
	if (this.tasks == null)
	{
		var div = document.createElement('div');
		div.style.padding = '4px';
		div.style.paddingLeft = '20px';
		var w = document.body.clientWidth;
		var wnd = new mxWindow(
			mxResources.get(this.tasksResource) ||
			this.tasksResource,
			div, w - 220, this.tasksTop, 200);
		wnd.setClosable(true);
		wnd.destroyOnClose = false;
		
		// Installs a function to update the contents
		// of the tasks window on every change of the
		// model, selection or root.
		var funct = mxUtils.bind(this, function(sender)
		{
			mxEvent.release(div);
			div.innerHTML = '';
			this.createTasks(div);
		});
		
		this.graph.getModel().addListener(mxEvent.CHANGE, funct);
		this.graph.getSelectionModel().addListener(mxEvent.CHANGE, funct);
		this.graph.addListener(mxEvent.ROOT, funct);
		
		// Assigns the icon to the tasks window
		if (this.tasksWindowImage != null)
		{
			wnd.setImage(this.tasksWindowImage);
		}
		
		this.tasks = wnd;
		this.createTasks(div);
	}
	
	this.tasks.setVisible(true);
};
		
/**
 * Function: refreshTasks
 * 
 * Updates the contents of the tasks window using <createTasks>.
 */
mxEditor.prototype.refreshTasks = function (div)
{
	if (this.tasks != null)
	{
		var div = this.tasks.content;
		mxEvent.release(div);
		div.innerHTML = '';
		this.createTasks(div);
	}
};
		
/**
 * Function: createTasks
 * 
 * Updates the contents of the given DOM node to
 * display the tasks associated with the current
 * editor state. This is invoked whenever there
 * is a possible change of state in the editor.
 * Default implementation is empty.
 */
mxEditor.prototype.createTasks = function (div)
{
	// override
};
	
/**
 * Function: showHelp
 * 
 * Shows the help window. If the help window does not exist
 * then it is created using an iframe pointing to the resource
 * for the <code>urlHelp</code> key or <urlHelp> if the resource
 * is undefined.
 */
mxEditor.prototype.showHelp = function (tasks)
{
	if (this.help == null)
	{
		var frame = document.createElement('iframe');
		frame.setAttribute('src', mxResources.get('urlHelp') || this.urlHelp);
		frame.setAttribute('height', '100%');
		frame.setAttribute('width', '100%');
		frame.setAttribute('frameBorder', '0');
		frame.style.backgroundColor = 'white';
	
		var w = document.body.clientWidth;
		var h = (document.body.clientHeight || document.documentElement.clientHeight);
		
		var wnd = new mxWindow(mxResources.get(this.helpResource) || this.helpResource,
			frame, (w-this.helpWidth)/2, (h-this.helpHeight)/3, this.helpWidth, this.helpHeight);
		wnd.setMaximizable(true);
		wnd.setClosable(true);
		wnd.destroyOnClose = false;
		wnd.setResizable(true);

		// Assigns the icon to the help window
		if (this.helpWindowImage != null)
		{
			wnd.setImage(this.helpWindowImage);
		}
		
		// Workaround for ignored iframe height 100% in FF
		if (mxClient.IS_NS)
		{
			var handler = function(sender)
			{
				var h = wnd.div.offsetHeight;
				frame.setAttribute('height', (h-26)+'px');
			};
			
			wnd.addListener(mxEvent.RESIZE_END, handler);
			wnd.addListener(mxEvent.MAXIMIZE, handler);
			wnd.addListener(mxEvent.NORMALIZE, handler);
			wnd.addListener(mxEvent.SHOW, handler);
		}
		
		this.help = wnd;
	}
	
	this.help.setVisible(true);
};

/**
 * Function: showOutline
 * 
 * Shows the outline window. If the window does not exist, then it is
 * created using an <mxOutline>.
 */
mxEditor.prototype.showOutline = function ()
{
	var create = this.outline == null;
	
	if (create)
	{
		var div = document.createElement('div');
		
		div.style.overflow = 'hidden';
		div.style.position = 'relative';
		div.style.width = '100%';
		div.style.height = '100%';
		div.style.background = 'white';
		div.style.cursor = 'move';
		
		if (document.documentMode == 8)
		{
			div.style.filter = 'progid:DXImageTransform.Microsoft.alpha(opacity=100)';
		}
		
		var wnd = new mxWindow(
			mxResources.get(this.outlineResource) ||
			this.outlineResource,
			div, 600, 480, 200, 200, false);
				
		// Creates the outline in the specified div
		// and links it to the existing graph
		var outline = new mxOutline(this.graph, div);			
		wnd.setClosable(true);
		wnd.setResizable(true);
		wnd.destroyOnClose = false;
		
		wnd.addListener(mxEvent.RESIZE_END, function()
		{
			outline.update();
		});
		
		this.outline = wnd;
		this.outline.outline = outline;
	}
	
	// Finally shows the outline
	this.outline.setVisible(true);
	this.outline.outline.update(true);
};
		
/**
 * Function: setMode
 *
 * Puts the graph into the specified mode. The following modenames are
 * supported:
 * 
 * select - Selects using the left mouse button, new connections
 * are disabled.
 * connect - Selects using the left mouse button or creates new
 * connections if mouse over cell hotspot. See <mxConnectionHandler>.
 * pan - Pans using the left mouse button, new connections are disabled.
 */
mxEditor.prototype.setMode = function(modename)
{
	if (modename == 'select')
	{
		this.graph.panningHandler.useLeftButtonForPanning = false;
		this.graph.setConnectable(false);
	}
	else if (modename == 'connect')
	{
		this.graph.panningHandler.useLeftButtonForPanning = false;
		this.graph.setConnectable(true);
	}
	else if (modename == 'pan')
	{
		this.graph.panningHandler.useLeftButtonForPanning = true;
		this.graph.setConnectable(false);
	}
};

/**
 * Function: createPopupMenu
 * 
 * Uses <popupHandler> to create the menu in the graph's
 * panning handler. The redirection is setup in
 * <setToolbarContainer>.
 */
mxEditor.prototype.createPopupMenu = function (menu, cell, evt)
{
	this.popupHandler.createMenu(this, menu, cell, evt);
};

/**
 * Function: createEdge
 * 
 * Uses <defaultEdge> as the prototype for creating new edges
 * in the connection handler of the graph. The style of the
 * edge will be overridden with the value returned by
 * <getEdgeStyle>.
 */
mxEditor.prototype.createEdge = function (source, target)
{
	// Clones the defaultedge prototype
	var e = null;
	
	if (this.defaultEdge != null)
	{
		var model = this.graph.getModel();
		e = model.cloneCell(this.defaultEdge);
	}
	else
	{
		e = new mxCell('');
		e.setEdge(true);
		
		var geo = new mxGeometry();
		geo.relative = true;
		e.setGeometry(geo);
	}
	
	// Overrides the edge style
	var style = this.getEdgeStyle();
	
	if (style != null)
	{
		e.setStyle(style);
	}
	
	return e;
};

/**
 * Function: getEdgeStyle
 * 
 * Returns a string identifying the style of new edges.
 * The function is used in <createEdge> when new edges
 * are created in the graph.
 */
mxEditor.prototype.getEdgeStyle = function ()
{
	return this.defaultEdgeStyle;
};

/**
 * Function: consumeCycleAttribute
 * 
 * Returns the next attribute in <cycleAttributeValues>
 * or null, if not attribute should be used in the
 * specified cell.
 */
mxEditor.prototype.consumeCycleAttribute = function (cell)
{
	return (this.cycleAttributeValues != null &&
		this.cycleAttributeValues.length > 0 &&
		this.graph.isSwimlane(cell)) ?
		this.cycleAttributeValues[this.cycleAttributeIndex++ %
			this.cycleAttributeValues.length] : null;
};

/**
 * Function: cycleAttribute
 * 
 * Uses the returned value from <consumeCycleAttribute>
 * as the value for the <cycleAttributeName> key in
 * the given cell's style.
 */
mxEditor.prototype.cycleAttribute = function (cell)
{
	if (this.cycleAttributeName != null)
	{
		var value = this.consumeCycleAttribute(cell);
		
		if (value != null)
		{
			cell.setStyle(cell.getStyle()+';'+
				this.cycleAttributeName+'='+value);
		}
	}
};

/**
 * Function: addVertex
 * 
 * Adds the given vertex as a child of parent at the specified
 * x and y coordinate and fires an <addVertex> event.
 */
mxEditor.prototype.addVertex = function (parent, vertex, x, y)
{
	var model = this.graph.getModel();
	
	while (parent != null && !this.graph.isValidDropTarget(parent))
	{
		parent = model.getParent(parent);
	}
	
	parent = (parent != null) ? parent : this.graph.getSwimlaneAt(x, y);
	var scale = this.graph.getView().scale;
	
	var geo = model.getGeometry(vertex);
	var pgeo = model.getGeometry(parent);
	
	if (this.graph.isSwimlane(vertex) &&
		!this.graph.swimlaneNesting)
	{
		parent = null;
	}
	else if (parent == null && this.swimlaneRequired)
	{
		return null;
	}
	else if (parent != null && pgeo != null)
	{
		// Keeps vertex inside parent
		var state = this.graph.getView().getState(parent);
		
		if (state != null)
		{			
			x -= state.origin.x * scale;
			y -= state.origin.y * scale;
			
			if (this.graph.isConstrainedMoving)
			{
				var width = geo.width;
				var height = geo.height;				
				var tmp = state.x+state.width;
				
				if (x+width > tmp)
				{
					x -= x+width - tmp;
				}
				
				tmp = state.y+state.height;
				
				if (y+height > tmp)
				{
					y -= y+height - tmp;
				}
			}
		}
		else if (pgeo != null)
		{
			x -= pgeo.x*scale;
			y -= pgeo.y*scale;
		}
	}
	
	geo = geo.clone();
	geo.x = this.graph.snap(x / scale -
		this.graph.getView().translate.x -
		this.graph.gridSize/2);
	geo.y = this.graph.snap(y / scale -
		this.graph.getView().translate.y -
		this.graph.gridSize/2);
	vertex.setGeometry(geo);
	
	if (parent == null)
	{
		parent = this.graph.getDefaultParent();
	}

	this.cycleAttribute(vertex);
	this.fireEvent(new mxEventObject(mxEvent.BEFORE_ADD_VERTEX,
			'vertex', vertex, 'parent', parent));

	model.beginUpdate();
	try
	{
		vertex = this.graph.addCell(vertex, parent);
		
		if (vertex != null)
		{
			this.graph.constrainChild(vertex);
			
			this.fireEvent(new mxEventObject(mxEvent.ADD_VERTEX, 'vertex', vertex));
		}
	}
	finally
	{
		model.endUpdate();
	}
	
	if (vertex != null)
	{
		this.graph.setSelectionCell(vertex);
		this.graph.scrollCellToVisible(vertex);
		this.fireEvent(new mxEventObject(mxEvent.AFTER_ADD_VERTEX, 'vertex', vertex));
	}
	
	return vertex;
};

/**
 * Function: destroy
 * 
 * Removes the editor and all its associated resources. This does not
 * normally need to be called, it is called automatically when the window
 * unloads.
 */
mxEditor.prototype.destroy = function ()
{
	if (!this.destroyed)
	{
		this.destroyed = true;

		if (this.tasks != null)
		{
			this.tasks.destroy();
		}
		
		if (this.outline != null)
		{
			this.outline.destroy();
		}
		
		if (this.properties != null)
		{
			this.properties.destroy();
		}
		
		if (this.keyHandler != null)
		{
			this.keyHandler.destroy();
		}
		
		if (this.rubberband != null)
		{
			this.rubberband.destroy();
		}
		
		if (this.toolbar != null)
		{
			this.toolbar.destroy();
		}
		
		if (this.graph != null)
		{
			this.graph.destroy();
		}
	
		this.status = null;
		this.templates = null;
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
var mxCodecRegistry =
{
	/**
	 * Class: mxCodecRegistry
	 *
	 * Singleton class that acts as a global registry for codecs.
	 *
	 * Adding an <mxCodec>:
	 *
	 * 1. Define a default codec with a new instance of the 
	 * object to be handled.
	 *
	 * (code)
	 * var codec = new mxObjectCodec(new mxGraphModel());
	 * (end)
	 *
	 * 2. Define the functions required for encoding and decoding
	 * objects.
	 *
	 * (code)
	 * codec.encode = function(enc, obj) { ... }
	 * codec.decode = function(dec, node, into) { ... }
	 * (end)
	 *
	 * 3. Register the codec in the <mxCodecRegistry>.
	 *
	 * (code)
	 * mxCodecRegistry.register(codec);
	 * (end)
	 *
	 * <mxObjectCodec.decode> may be used to either create a new 
	 * instance of an object or to configure an existing instance, 
	 * in which case the into argument points to the existing
	 * object. In this case, we say the codec "configures" the
	 * object.
	 * 
	 * Variable: codecs
	 *
	 * Maps from constructor names to codecs.
	 */
	codecs: [],
	
	/**
	 * Variable: aliases
	 *
	 * Maps from classnames to codecnames.
	 */
	aliases: [],

	/**
	 * Function: register
	 *
	 * Registers a new codec and associates the name of the template
	 * constructor in the codec with the codec object.
	 *
	 * Parameters:
	 *
	 * codec - <mxObjectCodec> to be registered.
	 */
	register: function(codec)
	{
		if (codec != null)
		{
			var name = codec.getName();
			mxCodecRegistry.codecs[name] = codec;
			
			var classname = mxUtils.getFunctionName(codec.template.constructor);

			if (classname != name)
			{
				mxCodecRegistry.addAlias(classname, name);
			}
		}

		return codec;
	},

	/**
	 * Function: addAlias
	 *
	 * Adds an alias for mapping a classname to a codecname.
	 */
	addAlias: function(classname, codecname)
	{
		mxCodecRegistry.aliases[classname] = codecname;
	},

	/**
	 * Function: getCodec
	 *
	 * Returns a codec that handles objects that are constructed
	 * using the given constructor.
	 *
	 * Parameters:
	 *
	 * ctor - JavaScript constructor function. 
	 */
	getCodec: function(ctor)
	{
		var codec = null;
		
		if (ctor != null)
		{
			var name = mxUtils.getFunctionName(ctor);
			var tmp = mxCodecRegistry.aliases[name];
			
			if (tmp != null)
			{
				name = tmp;
			}
			
			codec = mxCodecRegistry.codecs[name];
			
			// Registers a new default codec for the given constructor
			// if no codec has been previously defined.
			if (codec == null)
			{
				try
				{
					codec = new mxObjectCodec(new ctor());
					mxCodecRegistry.register(codec);
				}
				catch (e)
				{
					// ignore
				}
			}
		}
		
		return codec;
	}

};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxCodec
 *
 * XML codec for JavaScript object graphs. See <mxObjectCodec> for a
 * description of the general encoding/decoding scheme. This class uses the
 * codecs registered in <mxCodecRegistry> for encoding/decoding each object.
 * 
 * References:
 * 
 * In order to resolve references, especially forward references, the mxCodec
 * constructor must be given the document that contains the referenced
 * elements.
 *
 * Examples:
 *
 * The following code is used to encode a graph model.
 *
 * (code)
 * var encoder = new mxCodec();
 * var result = encoder.encode(graph.getModel());
 * var xml = mxUtils.getXml(result);
 * (end)
 * 
 * Example:
 * 
 * Using the code below, an XML document is decoded into an existing model. The
 * document may be obtained using one of the functions in mxUtils for loading
 * an XML file, eg. <mxUtils.get>, or using <mxUtils.parseXml> for parsing an
 * XML string.
 * 
 * (code)
 * var doc = mxUtils.parseXml(xmlString);
 * var codec = new mxCodec(doc);
 * codec.decode(doc.documentElement, graph.getModel());
 * (end)
 * 
 * Example:
 * 
 * This example demonstrates parsing a list of isolated cells into an existing
 * graph model. Note that the cells do not have a parent reference so they can
 * be added anywhere in the cell hierarchy after parsing.
 * 
 * (code)
 * var xml = '<root><mxCell id="2" value="Hello," vertex="1"><mxGeometry x="20" y="20" width="80" height="30" as="geometry"/></mxCell><mxCell id="3" value="World!" vertex="1"><mxGeometry x="200" y="150" width="80" height="30" as="geometry"/></mxCell><mxCell id="4" value="" edge="1" source="2" target="3"><mxGeometry relative="1" as="geometry"/></mxCell></root>';
 * var doc = mxUtils.parseXml(xml);
 * var codec = new mxCodec(doc);
 * var elt = doc.documentElement.firstChild;
 * var cells = [];
 * 
 * while (elt != null)
 * {
 *   cells.push(codec.decode(elt));
 *   elt = elt.nextSibling;
 * }
 * 
 * graph.addCells(cells);
 * (end)
 * 
 * Example:
 * 
 * Using the following code, the selection cells of a graph are encoded and the
 * output is displayed in a dialog box.
 * 
 * (code)
 * var enc = new mxCodec();
 * var cells = graph.getSelectionCells();
 * mxUtils.alert(mxUtils.getPrettyXml(enc.encode(cells)));
 * (end)
 * 
 * Newlines in the XML can be converted to <br>, in which case a '<br>' argument
 * must be passed to <mxUtils.getXml> as the second argument.
 * 
 * Debugging:
 * 
 * For debugging I/O you can use the following code to get the sequence of
 * encoded objects:
 * 
 * (code)
 * var oldEncode = mxCodec.prototype.encode;
 * mxCodec.prototype.encode = function(obj)
 * {
 *   mxLog.show();
 *   mxLog.debug('mxCodec.encode: obj='+mxUtils.getFunctionName(obj.constructor));
 *   
 *   return oldEncode.apply(this, arguments);
 * };
 * (end)
 * 
 * Note that the I/O system adds object codecs for new object automatically. For
 * decoding those objects, the constructor should be written as follows:
 * 
 * (code)
 * var MyObj = function(name)
 * {
 *   // ...
 * };
 * (end)
 * 
 * Constructor: mxCodec
 *
 * Constructs an XML encoder/decoder for the specified
 * owner document.
 *
 * Parameters:
 *
 * document - Optional XML document that contains the data.
 * If no document is specified then a new document is created
 * using <mxUtils.createXmlDocument>.
 */
function mxCodec(document)
{
	this.document = document || mxUtils.createXmlDocument();
	this.objects = [];
};

/**
 * Variable: document
 *
 * The owner document of the codec.
 */
mxCodec.prototype.document = null;

/**
 * Variable: objects
 *
 * Maps from IDs to objects.
 */
mxCodec.prototype.objects = null;

/**
 * Variable: elements
 * 
 * Lookup table for resolving IDs to elements.
 */
mxCodec.prototype.elements = null;

/**
 * Variable: encodeDefaults
 *
 * Specifies if default values should be encoded. Default is false.
 */
mxCodec.prototype.encodeDefaults = false;


/**
 * Function: putObject
 * 
 * Assoiates the given object with the given ID and returns the given object.
 * 
 * Parameters
 * 
 * id - ID for the object to be associated with.
 * obj - Object to be associated with the ID.
 */
mxCodec.prototype.putObject = function(id, obj)
{
	this.objects[id] = obj;
	
	return obj;
};

/**
 * Function: getObject
 *
 * Returns the decoded object for the element with the specified ID in
 * <document>. If the object is not known then <lookup> is used to find an
 * object. If no object is found, then the element with the respective ID
 * from the document is parsed using <decode>.
 */
mxCodec.prototype.getObject = function(id)
{
	var obj = null;

	if (id != null)
	{
		obj = this.objects[id];
		
		if (obj == null)
		{
			obj = this.lookup(id);
			
			if (obj == null)
			{
				var node = this.getElementById(id);
				
				if (node != null)
				{
					obj = this.decode(node);
				}
			}
		}
	}
	
	return obj;
};

/**
 * Function: lookup
 *
 * Hook for subclassers to implement a custom lookup mechanism for cell IDs.
 * This implementation always returns null.
 *
 * Example:
 *
 * (code)
 * var codec = new mxCodec();
 * codec.lookup = function(id)
 * {
 *   return model.getCell(id);
 * };
 * (end)
 *
 * Parameters:
 *
 * id - ID of the object to be returned.
 */
mxCodec.prototype.lookup = function(id)
{
	return null;
};

/**
 * Function: getElementById
 *
 * Returns the element with the given ID from <document>.
 *
 * Parameters:
 *
 * id - String that contains the ID.
 */
mxCodec.prototype.getElementById = function(id)
{
	if (this.elements == null)
	{
		// Throws custom error for cases where a reference should be resolved
		// in an empty document. This happens if an XML node is decoded without
		// passing the owner document to the codec constructor.
		if (this.document.documentElement == null)
		{
			throw new Error('mxCodec constructor needs document parameter');
		}
		
		this.elements = new Object();
		this.addElement(this.document.documentElement);
	}
	
	return this.elements[id];
};

/**
 * Function: addElement
 *
 * Adds the given element to <elements> if it has an ID.
 */
mxCodec.prototype.addElement = function(node)
{
	if (node.nodeType == mxConstants.NODETYPE_ELEMENT)
	{
		var id = node.getAttribute('id');
		
		if (id != null && this.elements[id] == null)
		{
			this.elements[id] = node;
		}
	}
	
	node = node.firstChild;
	
	while (node != null)
	{
		this.addElement(node);
		node = node.nextSibling;
	}
};

/**
 * Function: getId
 *
 * Returns the ID of the specified object. This implementation
 * calls <reference> first and if that returns null handles
 * the object as an <mxCell> by returning their IDs using
 * <mxCell.getId>. If no ID exists for the given cell, then
 * an on-the-fly ID is generated using <mxCellPath.create>.
 *
 * Parameters:
 *
 * obj - Object to return the ID for.
 */
mxCodec.prototype.getId = function(obj)
{
	var id = null;
	
	if (obj != null)
	{
		id = this.reference(obj);
		
		if (id == null && obj instanceof mxCell)
		{
			id = obj.getId();
			
			if (id == null)
			{
				// Uses an on-the-fly Id
				id = mxCellPath.create(obj);
				
				if (id.length == 0)
				{
					id = 'root';
				}
			}
		}
	}
	
	return id;
};

/**
 * Function: reference
 *
 * Hook for subclassers to implement a custom method
 * for retrieving IDs from objects. This implementation
 * always returns null.
 *
 * Example:
 *
 * (code)
 * var codec = new mxCodec();
 * codec.reference = function(obj)
 * {
 *   return obj.getCustomId();
 * };
 * (end)
 *
 * Parameters:
 *
 * obj - Object whose ID should be returned.
 */
mxCodec.prototype.reference = function(obj)
{
	return null;
};

/**
 * Function: encode
 *
 * Encodes the specified object and returns the resulting
 * XML node.
 *
 * Parameters:
 *
 * obj - Object to be encoded. 
 */
mxCodec.prototype.encode = function(obj)
{
	var node = null;
	
	if (obj != null && obj.constructor != null)
	{
		var enc = mxCodecRegistry.getCodec(obj.constructor);
		
		if (enc != null)
		{
			node = enc.encode(this, obj);
		}
		else
		{
			if (mxUtils.isNode(obj))
			{
				node = mxUtils.importNode(this.document, obj, true);
			}
			else
			{
	    		mxLog.warn('mxCodec.encode: No codec for ' + mxUtils.getFunctionName(obj.constructor));
			}
		}
	}
	
	return node;
};

/**
 * Function: decode
 *
 * Decodes the given XML node. The optional "into"
 * argument specifies an existing object to be
 * used. If no object is given, then a new instance
 * is created using the constructor from the codec.
 *
 * The function returns the passed in object or
 * the new instance if no object was given.
 *
 * Parameters:
 *
 * node - XML node to be decoded.
 * into - Optional object to be decodec into.
 */
mxCodec.prototype.decode = function(node, into)
{
	var obj = null;
	
	if (node != null && node.nodeType == mxConstants.NODETYPE_ELEMENT)
	{
		var ctor = null;
		
		try
		{
			ctor = window[node.nodeName];
		}
		catch (err)
		{
			// ignore
		}
		
		var dec = mxCodecRegistry.getCodec(ctor);
		
		if (dec != null)
		{
			obj = dec.decode(this, node, into);
		}
		else
		{
			obj = node.cloneNode(true);
			obj.removeAttribute('as');
		}
	}
	
	return obj;
};

/**
 * Function: encodeCell
 *
 * Encoding of cell hierarchies is built-into the core, but
 * is a higher-level function that needs to be explicitely
 * used by the respective object encoders (eg. <mxModelCodec>,
 * <mxChildChangeCodec> and <mxRootChangeCodec>). This
 * implementation writes the given cell and its children as a
 * (flat) sequence into the given node. The children are not
 * encoded if the optional includeChildren is false. The
 * function is in charge of adding the result into the
 * given node and has no return value.
 *
 * Parameters:
 *
 * cell - <mxCell> to be encoded.
 * node - Parent XML node to add the encoded cell into.
 * includeChildren - Optional boolean indicating if the
 * function should include all descendents. Default is true. 
 */
mxCodec.prototype.encodeCell = function(cell, node, includeChildren)
{
	node.appendChild(this.encode(cell));
	
	if (includeChildren == null || includeChildren)
	{
		var childCount = cell.getChildCount();
		
		for (var i = 0; i < childCount; i++)
		{
			this.encodeCell(cell.getChildAt(i), node);
		}
	}
};

/**
 * Function: isCellCodec
 * 
 * Returns true if the given codec is a cell codec. This uses
 * <mxCellCodec.isCellCodec> to check if the codec is of the
 * given type.
 */
mxCodec.prototype.isCellCodec = function(codec)
{
	if (codec != null && typeof(codec.isCellCodec) == 'function')
	{
		return codec.isCellCodec();
	}
	
	return false;
};

/**
 * Function: decodeCell
 *
 * Decodes cells that have been encoded using inversion, ie.
 * where the user object is the enclosing node in the XML,
 * and restores the group and graph structure in the cells.
 * Returns a new <mxCell> instance that represents the
 * given node.
 *
 * Parameters:
 *
 * node - XML node that contains the cell data.
 * restoreStructures - Optional boolean indicating whether
 * the graph structure should be restored by calling insert
 * and insertEdge on the parent and terminals, respectively.
 * Default is true.
 */
mxCodec.prototype.decodeCell = function(node, restoreStructures)
{
	restoreStructures = (restoreStructures != null) ? restoreStructures : true;
	var cell = null;
	
	if (node != null && node.nodeType == mxConstants.NODETYPE_ELEMENT)
	{
		// Tries to find a codec for the given node name. If that does
		// not return a codec then the node is the user object (an XML node
		// that contains the mxCell, aka inversion).
		var decoder = mxCodecRegistry.getCodec(node.nodeName);
		
		// Tries to find the codec for the cell inside the user object.
		// This assumes all node names inside the user object are either
		// not registered or they correspond to a class for cells.
		if (!this.isCellCodec(decoder))
		{
			var child = node.firstChild;
			
			while (child != null && !this.isCellCodec(decoder))
			{
				decoder = mxCodecRegistry.getCodec(child.nodeName);
				child = child.nextSibling;
			}
		}
		
		if (!this.isCellCodec(decoder))
		{
			decoder = mxCodecRegistry.getCodec(mxCell);
		}

		cell = decoder.decode(this, node);
		
		if (restoreStructures)
		{
			this.insertIntoGraph(cell);
		}
	}
	
	return cell;
};

/**
 * Function: insertIntoGraph
 *
 * Inserts the given cell into its parent and terminal cells.
 */
mxCodec.prototype.insertIntoGraph = function(cell)
{
	var parent = cell.parent;
	var source = cell.getTerminal(true);
	var target = cell.getTerminal(false);

	// Fixes possible inconsistencies during insert into graph
	cell.setTerminal(null, false);
	cell.setTerminal(null, true);
	cell.parent = null;
	
	if (parent != null)
	{
		parent.insert(cell);
	}

	if (source != null)
	{
		source.insertEdge(cell, true);
	}

	if (target != null)
	{
		target.insertEdge(cell, false);
	}
};

/**
 * Function: setAttribute
 *
 * Sets the attribute on the specified node to value. This is a
 * helper method that makes sure the attribute and value arguments
 * are not null.
 *
 * Parameters:
 *
 * node - XML node to set the attribute for.
 * attributes - Attributename to be set.
 * value - New value of the attribute.
 */
mxCodec.prototype.setAttribute = function(node, attribute, value)
{
	if (attribute != null && value != null)
	{
		node.setAttribute(attribute, value);
	}
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxObjectCodec
 *
 * Generic codec for JavaScript objects that implements a mapping between
 * JavaScript objects and XML nodes that maps each field or element to an
 * attribute or child node, and vice versa.
 * 
 * Atomic Values:
 * 
 * Consider the following example.
 * 
 * (code)
 * var obj = new Object();
 * obj.foo = "Foo";
 * obj.bar = "Bar";
 * (end)
 * 
 * This object is encoded into an XML node using the following.
 * 
 * (code)
 * var enc = new mxCodec();
 * var node = enc.encode(obj);
 * (end)
 * 
 * The output of the encoding may be viewed using <mxLog> as follows.
 * 
 * (code)
 * mxLog.show();
 * mxLog.debug(mxUtils.getPrettyXml(node));
 * (end)
 * 
 * Finally, the result of the encoding looks as follows.
 * 
 * (code)
 * <Object foo="Foo" bar="Bar"/>
 * (end)
 * 
 * In the above output, the foo and bar fields have been mapped to attributes
 * with the same names, and the name of the constructor was used for the
 * nodename.
 * 
 * Booleans:
 *
 * Since booleans are numbers in JavaScript, all boolean values are encoded
 * into 1 for true and 0 for false. The decoder also accepts the string true
 * and false for boolean values.
 * 
 * Objects:
 * 
 * The above scheme is applied to all atomic fields, that is, to all non-object
 * fields of an object. For object fields, a child node is created with a
 * special attribute that contains the fieldname. This special attribute is
 * called "as" and hence, as is a reserved word that should not be used for a
 * fieldname.
 * 
 * Consider the following example where foo is an object and bar is an atomic
 * property of foo.
 * 
 * (code)
 * var obj = {foo: {bar: "Bar"}};
 * (end)
 * 
 * This will be mapped to the following XML structure by mxObjectCodec.
 * 
 * (code)
 * <Object>
 *   <Object bar="Bar" as="foo"/>
 * </Object>
 * (end)
 * 
 * In the above output, the inner Object node contains the as-attribute that
 * specifies the fieldname in the enclosing object. That is, the field foo was
 * mapped to a child node with an as-attribute that has the value foo.
 * 
 * Arrays:
 * 
 * Arrays are special objects that are either associative, in which case each
 * key, value pair is treated like a field where the key is the fieldname, or
 * they are a sequence of atomic values and objects, which is mapped to a
 * sequence of child nodes. For object elements, the above scheme is applied
 * without the use of the special as-attribute for creating each child. For
 * atomic elements, a special add-node is created with the value stored in the
 * value-attribute.
 * 
 * For example, the following array contains one atomic value and one object
 * with a field called bar. Furthermore it contains two associative entries
 * called bar with an atomic value, and foo with an object value.
 * 
 * (code)
 * var obj = ["Bar", {bar: "Bar"}];
 * obj["bar"] = "Bar";
 * obj["foo"] = {bar: "Bar"};
 * (end)
 * 
 * This array is represented by the following XML nodes.
 * 
 * (code)
 * <Array bar="Bar">
 *   <add value="Bar"/>
 *   <Object bar="Bar"/>
 *   <Object bar="Bar" as="foo"/>
 * </Array>
 * (end)
 * 
 * The Array node name is the name of the constructor. The additional
 * as-attribute in the last child contains the key of the associative entry,
 * whereas the second last child is part of the array sequence and does not
 * have an as-attribute.
 * 
 * References:
 * 
 * Objects may be represented as child nodes or attributes with ID values,
 * which are used to lookup the object in a table within <mxCodec>. The
 * <isReference> function is in charge of deciding if a specific field should
 * be encoded as a reference or not. Its default implementation returns true if
 * the fieldname is in <idrefs>, an array of strings that is used to configure
 * the <mxObjectCodec>.
 * 
 * Using this approach, the mapping does not guarantee that the referenced
 * object itself exists in the document. The fields that are encoded as
 * references must be carefully chosen to make sure all referenced objects
 * exist in the document, or may be resolved by some other means if necessary.
 * 
 * For example, in the case of the graph model all cells are stored in a tree
 * whose root is referenced by the model's root field. A tree is a structure
 * that is well suited for an XML representation, however, the additional edges
 * in the graph model have a reference to a source and target cell, which are
 * also contained in the tree. To handle this case, the source and target cell
 * of an edge are treated as references, whereas the children are treated as
 * objects. Since all cells are contained in the tree and no edge references a
 * source or target outside the tree, this setup makes sure all referenced
 * objects are contained in the document.
 * 
 * In the case of a tree structure we must further avoid infinite recursion by
 * ignoring the parent reference of each child. This is done by returning true
 * in <isExcluded>, whose default implementation uses the array of excluded
 * fieldnames passed to the mxObjectCodec constructor.
 * 
 * References are only used for cells in mxGraph. For defining other
 * referencable object types, the codec must be able to work out the ID of an
 * object. This is done by implementing <mxCodec.reference>. For decoding a
 * reference, the XML node with the respective id-attribute is fetched from the
 * document, decoded, and stored in a lookup table for later reference. For
 * looking up external objects, <mxCodec.lookup> may be implemented.
 * 
 * Expressions:
 * 
 * For decoding JavaScript expressions, the add-node may be used with a text
 * content that contains the JavaScript expression. For example, the following
 * creates a field called foo in the enclosing object and assigns it the value
 * of <mxConstants.ALIGN_LEFT>.
 * 
 * (code)
 * <Object>
 *   <add as="foo">mxConstants.ALIGN_LEFT</add>
 * </Object>
 * (end)
 * 
 * The resulting object has a field called foo with the value "left". Its XML
 * representation looks as follows.
 * 
 * (code)
 * <Object foo="left"/>
 * (end)
 * 
 * This means the expression is evaluated at decoding time and the result of
 * the evaluation is stored in the respective field. Valid expressions are all
 * JavaScript expressions, including function definitions, which are mapped to
 * functions on the resulting object.
 * 
 * Expressions are only evaluated if <allowEval> is true.
 * 
 * Constructor: mxObjectCodec
 *
 * Constructs a new codec for the specified template object.
 * The variables in the optional exclude array are ignored by
 * the codec. Variables in the optional idrefs array are
 * turned into references in the XML. The optional mapping
 * may be used to map from variable names to XML attributes.
 * The argument is created as follows:
 *
 * (code)
 * var mapping = new Object();
 * mapping['variableName'] = 'attribute-name';
 * (end)
 *
 * Parameters:
 *
 * template - Prototypical instance of the object to be
 * encoded/decoded.
 * exclude - Optional array of fieldnames to be ignored.
 * idrefs - Optional array of fieldnames to be converted to/from
 * references.
 * mapping - Optional mapping from field- to attributenames.
 */
function mxObjectCodec(template, exclude, idrefs, mapping)
{
	this.template = template;
	
	this.exclude = (exclude != null) ? exclude : [];
	this.idrefs = (idrefs != null) ? idrefs : [];
	this.mapping = (mapping != null) ? mapping : [];
	
	this.reverse = new Object();
	
	for (var i in this.mapping)
	{
		this.reverse[this.mapping[i]] = i;
	}
};

/**
 * Variable: allowEval
 *
 * Static global switch that specifies if expressions in arrays are allowed.
 * Default is false. NOTE: Enabling this carries a possible security risk.
 */
mxObjectCodec.allowEval = false;

/**
 * Variable: template
 *
 * Holds the template object associated with this codec.
 */
mxObjectCodec.prototype.template = null;

/**
 * Variable: exclude
 *
 * Array containing the variable names that should be
 * ignored by the codec.
 */
mxObjectCodec.prototype.exclude = null;

/**
 * Variable: idrefs
 *
 * Array containing the variable names that should be
 * turned into or converted from references. See
 * <mxCodec.getId> and <mxCodec.getObject>.
 */
mxObjectCodec.prototype.idrefs = null;

/**
 * Variable: mapping
 *
 * Maps from from fieldnames to XML attribute names.
 */
mxObjectCodec.prototype.mapping = null;

/**
 * Variable: reverse
 *
 * Maps from from XML attribute names to fieldnames.
 */
mxObjectCodec.prototype.reverse = null;

/**
 * Function: getName
 * 
 * Returns the name used for the nodenames and lookup of the codec when
 * classes are encoded and nodes are decoded. For classes to work with
 * this the codec registry automatically adds an alias for the classname
 * if that is different than what this returns. The default implementation
 * returns the classname of the template class.
 */
mxObjectCodec.prototype.getName = function()
{
	return mxUtils.getFunctionName(this.template.constructor);
};

/**
 * Function: cloneTemplate
 * 
 * Returns a new instance of the template for this codec.
 */
mxObjectCodec.prototype.cloneTemplate = function()
{
	return new this.template.constructor();
};

/**
 * Function: getFieldName
 * 
 * Returns the fieldname for the given attributename.
 * Looks up the value in the <reverse> mapping or returns
 * the input if there is no reverse mapping for the
 * given name.
 */
mxObjectCodec.prototype.getFieldName = function(attributename)
{
	if (attributename != null)
	{
		var mapped = this.reverse[attributename];
		
		if (mapped != null)
		{
			attributename = mapped;
		}
	}
	
	return attributename;
};

/**
 * Function: getAttributeName
 * 
 * Returns the attributename for the given fieldname.
 * Looks up the value in the <mapping> or returns
 * the input if there is no mapping for the
 * given name.
 */
mxObjectCodec.prototype.getAttributeName = function(fieldname)
{
	if (fieldname != null)
	{
		var mapped = this.mapping[fieldname];
		
		if (mapped != null)
		{
			fieldname = mapped;
		}
	}
	
	return fieldname;
};

/**
 * Function: isExcluded
 *
 * Returns true if the given attribute is to be ignored by the codec. This
 * implementation returns true if the given fieldname is in <exclude> or
 * if the fieldname equals <mxObjectIdentity.FIELD_NAME>.
 *
 * Parameters:
 *
 * obj - Object instance that contains the field.
 * attr - Fieldname of the field.
 * value - Value of the field.
 * write - Boolean indicating if the field is being encoded or decoded.
 * Write is true if the field is being encoded, else it is being decoded.
 */
mxObjectCodec.prototype.isExcluded = function(obj, attr, value, write)
{
	return attr == mxObjectIdentity.FIELD_NAME ||
		mxUtils.indexOf(this.exclude, attr) >= 0;
};

/**
 * Function: isReference
 *
 * Returns true if the given fieldname is to be treated
 * as a textual reference (ID). This implementation returns
 * true if the given fieldname is in <idrefs>.
 *
 * Parameters:
 *
 * obj - Object instance that contains the field.
 * attr - Fieldname of the field.
 * value - Value of the field. 
 * write - Boolean indicating if the field is being encoded or decoded.
 * Write is true if the field is being encoded, else it is being decoded.
 */
mxObjectCodec.prototype.isReference = function(obj, attr, value, write)
{
	return mxUtils.indexOf(this.idrefs, attr) >= 0;
};

/**
 * Function: encode
 *
 * Encodes the specified object and returns a node
 * representing then given object. Calls <beforeEncode>
 * after creating the node and <afterEncode> with the 
 * resulting node after processing.
 *
 * Enc is a reference to the calling encoder. It is used
 * to encode complex objects and create references.
 *
 * This implementation encodes all variables of an
 * object according to the following rules:
 *
 * - If the variable name is in <exclude> then it is ignored.
 * - If the variable name is in <idrefs> then <mxCodec.getId>
 * is used to replace the object with its ID.
 * - The variable name is mapped using <mapping>.
 * - If obj is an array and the variable name is numeric
 * (ie. an index) then it is not encoded.
 * - If the value is an object, then the codec is used to
 * create a child node with the variable name encoded into
 * the "as" attribute.
 * - Else, if <encodeDefaults> is true or the value differs
 * from the template value, then ...
 * - ... if obj is not an array, then the value is mapped to
 * an attribute.
 * - ... else if obj is an array, the value is mapped to an
 * add child with a value attribute or a text child node,
 * if the value is a function.
 *
 * If no ID exists for a variable in <idrefs> or if an object
 * cannot be encoded, a warning is issued using <mxLog.warn>.
 *
 * Returns the resulting XML node that represents the given
 * object.
 *
 * Parameters:
 *
 * enc - <mxCodec> that controls the encoding process.
 * obj - Object to be encoded.
 */
mxObjectCodec.prototype.encode = function(enc, obj)
{
	var node = enc.document.createElement(this.getName());
	
	obj = this.beforeEncode(enc, obj, node);
	this.encodeObject(enc, obj, node);
	
	return this.afterEncode(enc, obj, node);
};
	
/**
 * Function: encodeObject
 *
 * Encodes the value of each member in then given obj into the given node using
 * <encodeValue>.
 * 
 * Parameters:
 *
 * enc - <mxCodec> that controls the encoding process.
 * obj - Object to be encoded.
 * node - XML node that contains the encoded object.
 */
mxObjectCodec.prototype.encodeObject = function(enc, obj, node)
{
	enc.setAttribute(node, 'id', enc.getId(obj));
	
    for (var i in obj)
    {
		var name = i;
		var value = obj[name];
		
    	if (value != null && !this.isExcluded(obj, name, value, true))
    	{
    		if (mxUtils.isInteger(name))
    		{
    			name = null;
    		}
    		
    		this.encodeValue(enc, obj, name, value, node);
    	}
    }
};

/**
 * Function: encodeValue
 * 
 * Converts the given value according to the mappings
 * and id-refs in this codec and uses <writeAttribute>
 * to write the attribute into the given node.
 * 
 * Parameters:
 *
 * enc - <mxCodec> that controls the encoding process.
 * obj - Object whose property is going to be encoded.
 * name - XML node that contains the encoded object.
 * value - Value of the property to be encoded.
 * node - XML node that contains the encoded object.
 */
mxObjectCodec.prototype.encodeValue = function(enc, obj, name, value, node)
{
	if (value != null)
	{
		if (this.isReference(obj, name, value, true))
		{
			var tmp = enc.getId(value);
			
			if (tmp == null)
			{
		    	mxLog.warn('mxObjectCodec.encode: No ID for ' +
		    		this.getName() + '.' + name + '=' + value);
		    	return; // exit
		    }
		    
		    value = tmp;
		}

		var defaultValue = this.template[name];
		
		// Checks if the value is a default value and
		// the name is correct
		if (name == null || enc.encodeDefaults || defaultValue != value)
		{
			name = this.getAttributeName(name);
			this.writeAttribute(enc, obj, name, value, node);	
		}
	}
};

/**
 * Function: writeAttribute
 * 
 * Writes the given value into node using <writePrimitiveAttribute>
 * or <writeComplexAttribute> depending on the type of the value.
 */
mxObjectCodec.prototype.writeAttribute = function(enc, obj, name, value, node)
{
	if (typeof(value) != 'object' /* primitive type */)
	{
		this.writePrimitiveAttribute(enc, obj, name, value, node);
	}
	else /* complex type */
	{
		this.writeComplexAttribute(enc, obj, name, value, node);
	}
};

/**
 * Function: writePrimitiveAttribute
 * 
 * Writes the given value as an attribute of the given node.
 */
mxObjectCodec.prototype.writePrimitiveAttribute = function(enc, obj, name, value, node)
{
	value = this.convertAttributeToXml(enc, obj, name, value, node);
	
	if (name == null)
	{
		var child = enc.document.createElement('add');
		
		if (typeof(value) == 'function')
		{
    		child.appendChild(enc.document.createTextNode(value));
    	}
    	else
    	{
    		enc.setAttribute(child, 'value', value);
    	}
    	
		node.appendChild(child);
	}
	else if (typeof(value) != 'function')
	{
    	enc.setAttribute(node, name, value);
	}		
};
	
/**
 * Function: writeComplexAttribute
 * 
 * Writes the given value as a child node of the given node.
 */
mxObjectCodec.prototype.writeComplexAttribute = function(enc, obj, name, value, node)
{
	var child = enc.encode(value);
	
	if (child != null)
	{
		if (name != null)
		{
    		child.setAttribute('as', name);
    	}
    	
    	node.appendChild(child);
	}
	else
	{
		mxLog.warn('mxObjectCodec.encode: No node for ' + this.getName() + '.' + name + ': ' + value);
	}
};

/**
 * Function: convertAttributeToXml
 * 
 * Converts true to "1" and false to "0" is <isBooleanAttribute> returns true.
 * All other values are not converted.
 * 
 * Parameters:
 *
 * enc - <mxCodec> that controls the encoding process.
 * obj - Objec to convert the attribute for.
 * name - Name of the attribute to be converted.
 * value - Value to be converted.
 */
mxObjectCodec.prototype.convertAttributeToXml = function(enc, obj, name, value)
{
	// Makes sure to encode boolean values as numeric values
	if (this.isBooleanAttribute(enc, obj, name, value))
	{	
		// Checks if the value is true (do not use the value as is, because
		// this would check if the value is not null, so 0 would be true)
		value = (value == true) ? '1' : '0';
	}
	
	return value;
};

/**
 * Function: isBooleanAttribute
 * 
 * Returns true if the given object attribute is a boolean value.
 * 
 * Parameters:
 *
 * enc - <mxCodec> that controls the encoding process.
 * obj - Objec to convert the attribute for.
 * name - Name of the attribute to be converted.
 * value - Value of the attribute to be converted.
 */
mxObjectCodec.prototype.isBooleanAttribute = function(enc, obj, name, value)
{
	return (typeof(value.length) == 'undefined' && (value == true || value == false));
};

/**
 * Function: convertAttributeFromXml
 * 
 * Converts booleans and numeric values to the respective types. Values are
 * numeric if <isNumericAttribute> returns true.
 * 
 * Parameters:
 *
 * dec - <mxCodec> that controls the decoding process.
 * attr - XML attribute to be converted.
 * obj - Objec to convert the attribute for.
 */
mxObjectCodec.prototype.convertAttributeFromXml = function(dec, attr, obj)
{
	var value = attr.value;
	
	if (this.isNumericAttribute(dec, attr, obj))
	{
		value = parseFloat(value);
	}
	
	return value;
};

/**
 * Function: isNumericAttribute
 * 
 * Returns true if the given XML attribute is a numeric value.
 * 
 * Parameters:
 *
 * dec - <mxCodec> that controls the decoding process.
 * attr - XML attribute to be converted.
 * obj - Objec to convert the attribute for.
 */
mxObjectCodec.prototype.isNumericAttribute = function(dec, attr, obj)
{
	return mxUtils.isNumeric(attr.value);
};

/**
 * Function: beforeEncode
 *
 * Hook for subclassers to pre-process the object before
 * encoding. This returns the input object. The return
 * value of this function is used in <encode> to perform
 * the default encoding into the given node.
 *
 * Parameters:
 *
 * enc - <mxCodec> that controls the encoding process.
 * obj - Object to be encoded.
 * node - XML node to encode the object into.
 */
mxObjectCodec.prototype.beforeEncode = function(enc, obj, node)
{
	return obj;
};

/**
 * Function: afterEncode
 *
 * Hook for subclassers to post-process the node
 * for the given object after encoding and return the
 * post-processed node. This implementation returns 
 * the input node. The return value of this method
 * is returned to the encoder from <encode>.
 *
 * Parameters:
 *
 * enc - <mxCodec> that controls the encoding process.
 * obj - Object to be encoded.
 * node - XML node that represents the default encoding.
 */
mxObjectCodec.prototype.afterEncode = function(enc, obj, node)
{
	return node;
};

/**
 * Function: decode
 *
 * Parses the given node into the object or returns a new object
 * representing the given node.
 *
 * Dec is a reference to the calling decoder. It is used to decode
 * complex objects and resolve references.
 *
 * If a node has an id attribute then the object cache is checked for the
 * object. If the object is not yet in the cache then it is constructed
 * using the constructor of <template> and cached in <mxCodec.objects>.
 *
 * This implementation decodes all attributes and childs of a node
 * according to the following rules:
 *
 * - If the variable name is in <exclude> or if the attribute name is "id"
 * or "as" then it is ignored.
 * - If the variable name is in <idrefs> then <mxCodec.getObject> is used
 * to replace the reference with an object.
 * - The variable name is mapped using a reverse <mapping>.
 * - If the value has a child node, then the codec is used to create a
 * child object with the variable name taken from the "as" attribute.
 * - If the object is an array and the variable name is empty then the
 * value or child object is appended to the array.
 * - If an add child has no value or the object is not an array then
 * the child text content is evaluated using <mxUtils.eval>.
 *
 * For add nodes where the object is not an array and the variable name
 * is defined, the default mechanism is used, allowing to override/add
 * methods as follows:
 *
 * (code)
 * <Object>
 *   <add as="hello"><![CDATA[
 *     function(arg1) {
 *       mxUtils.alert('Hello '+arg1);
 *     }
 *   ]]></add>
 * </Object>
 * (end) 
 *
 * If no object exists for an ID in <idrefs> a warning is issued
 * using <mxLog.warn>.
 *
 * Returns the resulting object that represents the given XML node
 * or the object given to the method as the into parameter.
 *
 * Parameters:
 *
 * dec - <mxCodec> that controls the decoding process.
 * node - XML node to be decoded.
 * into - Optional objec to encode the node into.
 */
mxObjectCodec.prototype.decode = function(dec, node, into)
{
	var id = node.getAttribute('id');
	var obj = dec.objects[id];
	
	if (obj == null)
	{
		obj = into || this.cloneTemplate();
		
		if (id != null)
		{
			dec.putObject(id, obj);
		}
	}
	
	node = this.beforeDecode(dec, node, obj);
	this.decodeNode(dec, node, obj);
	
    return this.afterDecode(dec, node, obj);
};	

/**
 * Function: decodeNode
 * 
 * Calls <decodeAttributes> and <decodeChildren> for the given node.
 * 
 * Parameters:
 *
 * dec - <mxCodec> that controls the decoding process.
 * node - XML node to be decoded.
 * obj - Objec to encode the node into.
 */	
mxObjectCodec.prototype.decodeNode = function(dec, node, obj)
{
	if (node != null)
	{
		this.decodeAttributes(dec, node, obj);
		this.decodeChildren(dec, node, obj);
	}
};

/**
 * Function: decodeAttributes
 * 
 * Decodes all attributes of the given node using <decodeAttribute>.
 * 
 * Parameters:
 *
 * dec - <mxCodec> that controls the decoding process.
 * node - XML node to be decoded.
 * obj - Objec to encode the node into.
 */	
mxObjectCodec.prototype.decodeAttributes = function(dec, node, obj)
{
	var attrs = node.attributes;
	
	if (attrs != null)
	{
		for (var i = 0; i < attrs.length; i++)
		{
			this.decodeAttribute(dec, attrs[i], obj);
		}
	}
};

/**
 * Function: isIgnoredAttribute
 * 
 * Returns true if the given attribute should be ignored. This implementation
 * returns true if the attribute name is "as" or "id".
 * 
 * Parameters:
 *
 * dec - <mxCodec> that controls the decoding process.
 * attr - XML attribute to be decoded.
 * obj - Objec to encode the attribute into.
 */	
mxObjectCodec.prototype.isIgnoredAttribute = function(dec, attr, obj)
{
	return attr.nodeName == 'as' || attr.nodeName == 'id';
};

/**
 * Function: decodeAttribute
 * 
 * Reads the given attribute into the specified object.
 * 
 * Parameters:
 *
 * dec - <mxCodec> that controls the decoding process.
 * attr - XML attribute to be decoded.
 * obj - Objec to encode the attribute into.
 */	
mxObjectCodec.prototype.decodeAttribute = function(dec, attr, obj)
{
	if (!this.isIgnoredAttribute(dec, attr, obj))
	{
		var name = attr.nodeName;
		
		// Converts the string true and false to their boolean values.
		// This may require an additional check on the obj to see if
		// the existing field is a boolean value or uninitialized, in
		// which case we may want to convert true and false to a string.
		var value = this.convertAttributeFromXml(dec, attr, obj);
		var fieldname = this.getFieldName(name);
		
		if (this.isReference(obj, fieldname, value, false))
		{
			var tmp = dec.getObject(value);
			
			if (tmp == null)
			{
		    	mxLog.warn('mxObjectCodec.decode: No object for ' +
		    		this.getName() + '.' + name + '=' + value);
		    	return; // exit
		    }
		    
		    value = tmp;
		}

		if (!this.isExcluded(obj, name, value, false))
		{
			//mxLog.debug(mxUtils.getFunctionName(obj.constructor)+'.'+name+'='+value);
			obj[name] = value;
		}
	}
};

/**
 * Function: decodeChildren
 * 
 * Decodes all children of the given node using <decodeChild>.
 * 
 * Parameters:
 *
 * dec - <mxCodec> that controls the decoding process.
 * node - XML node to be decoded.
 * obj - Objec to encode the node into.
 */	
mxObjectCodec.prototype.decodeChildren = function(dec, node, obj)
{
	var child = node.firstChild;
	
	while (child != null)
	{
		var tmp = child.nextSibling;
		
		if (child.nodeType == mxConstants.NODETYPE_ELEMENT &&
			!this.processInclude(dec, child, obj))
		{
			this.decodeChild(dec, child, obj);
		}
		
		child = tmp;
	}
};

/**
 * Function: decodeChild
 * 
 * Reads the specified child into the given object.
 * 
 * Parameters:
 *
 * dec - <mxCodec> that controls the decoding process.
 * child - XML child element to be decoded.
 * obj - Objec to encode the node into.
 */	
mxObjectCodec.prototype.decodeChild = function(dec, child, obj)
{
	var fieldname = this.getFieldName(child.getAttribute('as'));
	
	if (fieldname == null || !this.isExcluded(obj, fieldname, child, false))
	{
		var template = this.getFieldTemplate(obj, fieldname, child);
		var value = null;
		
		if (child.nodeName == 'add')
		{
			value = child.getAttribute('value');
			
			if (value == null && mxObjectCodec.allowEval)
			{
				value = mxUtils.eval(mxUtils.getTextContent(child));
			}
		}
		else
		{
			value = dec.decode(child, template);
		}

		this.addObjectValue(obj, fieldname, value, template);
	}
};

/**
 * Function: getFieldTemplate
 * 
 * Returns the template instance for the given field. This returns the
 * value of the field, null if the value is an array or an empty collection
 * if the value is a collection. The value is then used to populate the
 * field for a new instance. For strongly typed languages it may be
 * required to override this to return the correct collection instance
 * based on the encoded child.
 */	
mxObjectCodec.prototype.getFieldTemplate = function(obj, fieldname, child)
{
	var template = obj[fieldname];
	
	// Non-empty arrays are replaced completely
    if (template instanceof Array && template.length > 0)
    {
        template = null;
    }
    
    return template;
};

/**
 * Function: addObjectValue
 * 
 * Sets the decoded child node as a value of the given object. If the
 * object is a map, then the value is added with the given fieldname as a
 * key. If the fieldname is not empty, then setFieldValue is called or
 * else, if the object is a collection, the value is added to the
 * collection. For strongly typed languages it may be required to
 * override this with the correct code to add an entry to an object.
 */	
mxObjectCodec.prototype.addObjectValue = function(obj, fieldname, value, template)
{
	if (value != null && value != template)
	{
		if (fieldname != null && fieldname.length > 0)
		{
			obj[fieldname] = value;
		}
		else
		{
			obj.push(value);
		}
		//mxLog.debug('Decoded '+mxUtils.getFunctionName(obj.constructor)+'.'+fieldname+': '+value);
	}
};

/**
 * Function: processInclude
 *
 * Returns true if the given node is an include directive and
 * executes the include by decoding the XML document. Returns
 * false if the given node is not an include directive.
 *
 * Parameters:
 *
 * dec - <mxCodec> that controls the encoding/decoding process.
 * node - XML node to be checked.
 * into - Optional object to pass-thru to the codec.
 */
mxObjectCodec.prototype.processInclude = function(dec, node, into)
{
	if (node.nodeName == 'include')
	{
		var name = node.getAttribute('name');
		
		if (name != null)
		{
			try
			{
				var xml = mxUtils.load(name).getDocumentElement();
				
				if (xml != null)
				{
					dec.decode(xml, into);
				}
			}
			catch (e)
			{
				// ignore
			}
		}
		
		return true;
	}
	
	return false;
};

/**
 * Function: beforeDecode
 *
 * Hook for subclassers to pre-process the node for
 * the specified object and return the node to be
 * used for further processing by <decode>.
 * The object is created based on the template in the 
 * calling method and is never null. This implementation
 * returns the input node. The return value of this
 * function is used in <decode> to perform
 * the default decoding into the given object.
 *
 * Parameters:
 *
 * dec - <mxCodec> that controls the decoding process.
 * node - XML node to be decoded.
 * obj - Object to encode the node into.
 */
mxObjectCodec.prototype.beforeDecode = function(dec, node, obj)
{
	return node;
};

/**
 * Function: afterDecode
 *
 * Hook for subclassers to post-process the object after
 * decoding. This implementation returns the given object
 * without any changes. The return value of this method
 * is returned to the decoder from <decode>.
 *
 * Parameters:
 *
 * enc - <mxCodec> that controls the encoding process.
 * node - XML node to be decoded.
 * obj - Object that represents the default decoding.
 */
mxObjectCodec.prototype.afterDecode = function(dec, node, obj)
{
	return obj;
};
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
mxCodecRegistry.register(function()
{
	/**
	 * Class: mxCellCodec
	 *
	 * Codec for <mxCell>s. This class is created and registered
	 * dynamically at load time and used implicitely via <mxCodec>
	 * and the <mxCodecRegistry>.
	 *
	 * Transient Fields:
	 *
	 * - children
	 * - edges
	 * - overlays
	 * - mxTransient
	 *
	 * Reference Fields:
	 *
	 * - parent
	 * - source
	 * - target
	 * 
	 * Transient fields can be added using the following code:
	 * 
	 * mxCodecRegistry.getCodec(mxCell).exclude.push('name_of_field');
	 * 
	 * To subclass <mxCell>, replace the template and add an alias as
	 * follows.
	 * 
	 * (code)
	 * function CustomCell(value, geometry, style)
	 * {
	 *   mxCell.apply(this, arguments);
	 * }
	 * 
	 * mxUtils.extend(CustomCell, mxCell);
	 * 
	 * mxCodecRegistry.getCodec(mxCell).template = new CustomCell();
	 * mxCodecRegistry.addAlias('CustomCell', 'mxCell');
	 * (end)
	 */
	var codec = new mxObjectCodec(new mxCell(),
		['children', 'edges', 'overlays', 'mxTransient'],
		['parent', 'source', 'target']);

	/**
	 * Function: isCellCodec
	 *
	 * Returns true since this is a cell codec.
	 */
	codec.isCellCodec = function()
	{
		return true;
	};

	/**
	 * Overidden to disable conversion of value to number.
	 */
	codec.isNumericAttribute = function(dec, attr, obj)
	{
		return attr.nodeName !== 'value' && mxObjectCodec.prototype.isNumericAttribute.apply(this, arguments);
	};
	
	/**
	 * Function: isExcluded
	 *
	 * Excludes user objects that are XML nodes.
	 */ 
	codec.isExcluded = function(obj, attr, value, isWrite)
	{
		return mxObjectCodec.prototype.isExcluded.apply(this, arguments) ||
			(isWrite && attr == 'value' &&
			value.nodeType == mxConstants.NODETYPE_ELEMENT);
	};
	
	/**
	 * Function: afterEncode
	 *
	 * Encodes an <mxCell> and wraps the XML up inside the
	 * XML of the user object (inversion).
	 */
	codec.afterEncode = function(enc, obj, node)
	{
		if (obj.value != null && obj.value.nodeType == mxConstants.NODETYPE_ELEMENT)
		{
			// Wraps the graphical annotation up in the user object (inversion)
			// by putting the result of the default encoding into a clone of the
			// user object (node type 1) and returning this cloned user object.
			var tmp = node;
			node = mxUtils.importNode(enc.document, obj.value, true);
			node.appendChild(tmp);
			
			// Moves the id attribute to the outermost XML node, namely the
			// node which denotes the object boundaries in the file.
			var id = tmp.getAttribute('id');
			node.setAttribute('id', id);
			tmp.removeAttribute('id');
		}

		return node;
	};

	/**
	 * Function: beforeDecode
	 *
	 * Decodes an <mxCell> and uses the enclosing XML node as
	 * the user object for the cell (inversion).
	 */
	codec.beforeDecode = function(dec, node, obj)
	{
		var inner = node.cloneNode(true);
		var classname = this.getName();
		
		if (node.nodeName != classname)
		{
			// Passes the inner graphical annotation node to the
			// object codec for further processing of the cell.
			var tmp = node.getElementsByTagName(classname)[0];
			
			if (tmp != null && tmp.parentNode == node)
			{
				mxUtils.removeWhitespace(tmp, true);
				mxUtils.removeWhitespace(tmp, false);
				tmp.parentNode.removeChild(tmp);
				inner = tmp;
			}
			else
			{
				inner = null;
			}
			
			// Creates the user object out of the XML node
			obj.value = node.cloneNode(true);
			var id = obj.value.getAttribute('id');
			
			if (id != null)
			{
				obj.setId(id);
				obj.value.removeAttribute('id');
			}
		}
		else
		{
			// Uses ID from XML file as ID for cell in model
			obj.setId(node.getAttribute('id'));
		}
			
		// Preprocesses and removes all Id-references in order to use the
		// correct encoder (this) for the known references to cells (all).
		if (inner != null)
		{
			for (var i = 0; i < this.idrefs.length; i++)
			{
				var attr = this.idrefs[i];
				var ref = inner.getAttribute(attr);
				
				if (ref != null)
				{
					inner.removeAttribute(attr);
					var object = dec.objects[ref] || dec.lookup(ref);
					
					if (object == null)
					{
						// Needs to decode forward reference
						var element = dec.getElementById(ref);
						
						if (element != null)
						{
							var decoder = mxCodecRegistry.codecs[element.nodeName] || this;
							object = decoder.decode(dec, element);
						}
					}
					
					obj[attr] = object;
				}
			}
		}
		
		return inner;
	};

	// Returns the codec into the registry
	return codec;

}());
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
mxCodecRegistry.register(function()
{
	/**
	 * Class: mxModelCodec
	 *
	 * Codec for <mxGraphModel>s. This class is created and registered
	 * dynamically at load time and used implicitely via <mxCodec>
	 * and the <mxCodecRegistry>.
	 */
	var codec = new mxObjectCodec(new mxGraphModel());

	/**
	 * Function: encodeObject
	 *
	 * Encodes the given <mxGraphModel> by writing a (flat) XML sequence of
	 * cell nodes as produced by the <mxCellCodec>. The sequence is
	 * wrapped-up in a node with the name root.
	 */
	codec.encodeObject = function(enc, obj, node)
	{
		var rootNode = enc.document.createElement('root');
		enc.encodeCell(obj.getRoot(), rootNode);
		node.appendChild(rootNode);
	};

	/**
	 * Function: decodeChild
	 * 
	 * Overrides decode child to handle special child nodes.
	 */	
	codec.decodeChild = function(dec, child, obj)
	{
		if (child.nodeName == 'root')
		{
			this.decodeRoot(dec, child, obj);
		}
		else
		{
			mxObjectCodec.prototype.decodeChild.apply(this, arguments);
		}
	};

	/**
	 * Function: decodeRoot
	 *
	 * Reads the cells into the graph model. All cells
	 * are children of the root element in the node.
	 */
	codec.decodeRoot = function(dec, root, model)
	{
		var rootCell = null;
		var tmp = root.firstChild;
		
		while (tmp != null)
		{
			var cell = dec.decodeCell(tmp);
			
			if (cell != null && cell.getParent() == null)
			{
				rootCell = cell;
			}
			
			tmp = tmp.nextSibling;
		}

		// Sets the root on the model if one has been decoded
		if (rootCell != null)
		{
			model.setRoot(rootCell);
		}
	};

	// Returns the codec into the registry
	return codec;

}());
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
mxCodecRegistry.register(function()
{
	/**
	 * Class: mxRootChangeCodec
	 *
	 * Codec for <mxRootChange>s. This class is created and registered
	 * dynamically at load time and used implicitely via <mxCodec> and
	 * the <mxCodecRegistry>.
	 *
	 * Transient Fields:
	 *
	 * - model
	 * - previous
	 * - root
	 */
	var codec = new mxObjectCodec(new mxRootChange(),
		['model', 'previous', 'root']);

	/**
	 * Function: onEncode
	 *
	 * Encodes the child recursively.
	 */
	codec.afterEncode = function(enc, obj, node)
	{
		enc.encodeCell(obj.root, node);
		
		return node;
	};

	/**
	 * Function: beforeDecode
	 *
	 * Decodes the optional children as cells
	 * using the respective decoder.
	 */
	codec.beforeDecode = function(dec, node, obj)
	{
		if (node.firstChild != null &&
			node.firstChild.nodeType == mxConstants.NODETYPE_ELEMENT)
		{
			// Makes sure the original node isn't modified
			node = node.cloneNode(true);
			
			var tmp = node.firstChild;
			obj.root = dec.decodeCell(tmp, false);

			var tmp2 = tmp.nextSibling;
			tmp.parentNode.removeChild(tmp);
			tmp = tmp2;
		
			while (tmp != null)
			{
				tmp2 = tmp.nextSibling;
				dec.decodeCell(tmp);
				tmp.parentNode.removeChild(tmp);
				tmp = tmp2;
			}
		}
		
		return node;
	};
	
	/**
	 * Function: afterDecode
	 *
	 * Restores the state by assigning the previous value.
	 */
	codec.afterDecode = function(dec, node, obj)
	{
		obj.previous = obj.root;
		
		return obj;
	};

	// Returns the codec into the registry
	return codec;

}());
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
mxCodecRegistry.register(function()
{
	/**
	 * Class: mxChildChangeCodec
	 *
	 * Codec for <mxChildChange>s. This class is created and registered
	 * dynamically at load time and used implicitely via <mxCodec> and
	 * the <mxCodecRegistry>.
	 *
	 * Transient Fields:
	 *
	 * - model
	 * - previous
	 * - previousIndex
	 * - child
	 *
	 * Reference Fields:
	 *
	 * - parent
	 */
	var codec = new mxObjectCodec(new mxChildChange(),
		['model', 'child', 'previousIndex'],
		['parent', 'previous']);

	/**
	 * Function: isReference
	 *
	 * Returns true for the child attribute if the child
	 * cell had a previous parent or if we're reading the
	 * child as an attribute rather than a child node, in
	 * which case it's always a reference.
	 */
	codec.isReference = function(obj, attr, value, isWrite)
	{
		if (attr == 'child' &&
			(obj.previous != null ||
			!isWrite))
		{
			return true;
		}
		
		return mxUtils.indexOf(this.idrefs, attr) >= 0;
	};

	/**
	 * Function: afterEncode
	 *
	 * Encodes the child recusively and adds the result
	 * to the given node.
	 */
	codec.afterEncode = function(enc, obj, node)
	{
		if (this.isReference(obj, 'child',  obj.child, true))
		{
			// Encodes as reference (id)
			node.setAttribute('child', enc.getId(obj.child));
		}
		else
		{
			// At this point, the encoder is no longer able to know which cells
			// are new, so we have to encode the complete cell hierarchy and
			// ignore the ones that are already there at decoding time. Note:
			// This can only be resolved by moving the notify event into the
			// execute of the edit.
			enc.encodeCell(obj.child, node);
		}
		
		return node;
	};

	/**
	 * Function: beforeDecode
	 *
	 * Decodes the any child nodes as using the respective
	 * codec from the registry.
	 */
	codec.beforeDecode = function(dec, node, obj)
	{
		if (node.firstChild != null &&
			node.firstChild.nodeType == mxConstants.NODETYPE_ELEMENT)
		{
			// Makes sure the original node isn't modified
			node = node.cloneNode(true);
			
			var tmp = node.firstChild;
			obj.child = dec.decodeCell(tmp, false);

			var tmp2 = tmp.nextSibling;
			tmp.parentNode.removeChild(tmp);
			tmp = tmp2;
			
			while (tmp != null)
			{
				tmp2 = tmp.nextSibling;
				
				if (tmp.nodeType == mxConstants.NODETYPE_ELEMENT)
				{
					// Ignores all existing cells because those do not need to
					// be re-inserted into the model. Since the encoded version
					// of these cells contains the new parent, this would leave
					// to an inconsistent state on the model (ie. a parent
					// change without a call to parentForCellChanged).
					var id = tmp.getAttribute('id');
					
					if (dec.lookup(id) == null)
					{
						dec.decodeCell(tmp);
					}
				}
				
				tmp.parentNode.removeChild(tmp);
				tmp = tmp2;
			}
		}
		else
		{
			var childRef = node.getAttribute('child');
			obj.child = dec.getObject(childRef);
		}
		
		return node;
	};
	
	/**
	 * Function: afterDecode
	 *
	 * Restores object state in the child change.
	 */
	codec.afterDecode = function(dec, node, obj)
	{
		// Cells are encoded here after a complete transaction so the previous
		// parent must be restored on the cell for the case where the cell was
		// added. This is needed for the local model to identify the cell as a
		// new cell and register the ID.
		obj.child.parent = obj.previous;
		obj.previous = obj.parent;
		obj.previousIndex = obj.index;

		return obj;
	};

	// Returns the codec into the registry
	return codec;

}());
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
mxCodecRegistry.register(function()
{
	/**
	 * Class: mxTerminalChangeCodec
	 *
	 * Codec for <mxTerminalChange>s. This class is created and registered
	 * dynamically at load time and used implicitely via <mxCodec> and
	 * the <mxCodecRegistry>.
	 *
	 * Transient Fields:
	 *
	 * - model
	 * - previous
	 *
	 * Reference Fields:
	 *
	 * - cell
	 * - terminal
	 */
	var codec = new mxObjectCodec(new mxTerminalChange(),
		['model', 'previous'], ['cell', 'terminal']);

	/**
	 * Function: afterDecode
	 *
	 * Restores the state by assigning the previous value.
	 */
	codec.afterDecode = function(dec, node, obj)
	{
		obj.previous = obj.terminal;
		
		return obj;
	};

	// Returns the codec into the registry
	return codec;

}());
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxGenericChangeCodec
 *
 * Codec for <mxValueChange>s, <mxStyleChange>s, <mxGeometryChange>s,
 * <mxCollapseChange>s and <mxVisibleChange>s. This class is created
 * and registered dynamically at load time and used implicitely
 * via <mxCodec> and the <mxCodecRegistry>.
 *
 * Transient Fields:
 *
 * - model
 * - previous
 *
 * Reference Fields:
 *
 * - cell
 * 
 * Constructor: mxGenericChangeCodec
 *
 * Factory function that creates a <mxObjectCodec> for
 * the specified change and fieldname.
 *
 * Parameters:
 *
 * obj - An instance of the change object.
 * variable - The fieldname for the change data.
 */
var mxGenericChangeCodec = function(obj, variable)
{
	var codec = new mxObjectCodec(obj,  ['model', 'previous'], ['cell']);

	/**
	 * Function: afterDecode
	 *
	 * Restores the state by assigning the previous value.
	 */
	codec.afterDecode = function(dec, node, obj)
	{
		// Allows forward references in sessions. This is a workaround
		// for the sequence of edits in mxGraph.moveCells and cellsAdded.
		if (mxUtils.isNode(obj.cell))
		{
			obj.cell = dec.decodeCell(obj.cell, false);
		}

		obj.previous = obj[variable];

		return obj;
	};
	
	return codec;
};

// Registers the codecs
mxCodecRegistry.register(mxGenericChangeCodec(new mxValueChange(), 'value'));
mxCodecRegistry.register(mxGenericChangeCodec(new mxStyleChange(), 'style'));
mxCodecRegistry.register(mxGenericChangeCodec(new mxGeometryChange(), 'geometry'));
mxCodecRegistry.register(mxGenericChangeCodec(new mxCollapseChange(), 'collapsed'));
mxCodecRegistry.register(mxGenericChangeCodec(new mxVisibleChange(), 'visible'));
mxCodecRegistry.register(mxGenericChangeCodec(new mxCellAttributeChange(), 'value'));
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
mxCodecRegistry.register(function()
{
	/**
	 * Class: mxGraphCodec
	 *
	 * Codec for <mxGraph>s. This class is created and registered
	 * dynamically at load time and used implicitely via <mxCodec>
	 * and the <mxCodecRegistry>.
	 *
	 * Transient Fields:
	 *
	 * - graphListeners
	 * - eventListeners
	 * - view
	 * - container
	 * - cellRenderer
	 * - editor
	 * - selection
	 */
	return new mxObjectCodec(new mxGraph(),
		['graphListeners', 'eventListeners', 'view', 'container',
		'cellRenderer', 'editor', 'selection']);

}());
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
mxCodecRegistry.register(function()
{
	/**
	 * Class: mxGraphViewCodec
	 *
	 * Custom encoder for <mxGraphView>s. This class is created
	 * and registered dynamically at load time and used implicitely via
	 * <mxCodec> and the <mxCodecRegistry>. This codec only writes views
	 * into a XML format that can be used to create an image for
	 * the graph, that is, it contains absolute coordinates with
	 * computed perimeters, edge styles and cell styles.
	 */
	var codec = new mxObjectCodec(new mxGraphView());

	/**
	 * Function: encode
	 *
	 * Encodes the given <mxGraphView> using <encodeCell>
	 * starting at the model's root. This returns the
	 * top-level graph node of the recursive encoding.
	 */
	codec.encode = function(enc, view)
	{
		return this.encodeCell(enc, view,
			view.graph.getModel().getRoot());
	};

	/**
	 * Function: encodeCell
	 *
	 * Recursively encodes the specifed cell. Uses layer
	 * as the default nodename. If the cell's parent is
	 * null, then graph is used for the nodename. If
	 * <mxGraphModel.isEdge> returns true for the cell,
	 * then edge is used for the nodename, else if
	 * <mxGraphModel.isVertex> returns true for the cell,
	 * then vertex is used for the nodename.
	 *
	 * <mxGraph.getLabel> is used to create the label
	 * attribute for the cell. For graph nodes and vertices
	 * the bounds are encoded into x, y, width and height.
	 * For edges the points are encoded into a points
	 * attribute as a space-separated list of comma-separated
	 * coordinate pairs (eg. x0,y0 x1,y1 ... xn,yn). All
	 * values from the cell style are added as attribute
	 * values to the node. 
	 */
	codec.encodeCell = function(enc, view, cell)
	{
		var model = view.graph.getModel();
		var state = view.getState(cell);
		var parent = model.getParent(cell);
		
		if (parent == null || state != null)
		{
			var childCount = model.getChildCount(cell);
			var geo = view.graph.getCellGeometry(cell);
			var name = null;
			
			if (parent == model.getRoot())
			{
				name = 'layer';
			}
			else if (parent == null)
			{
				name = 'graph';
			}
			else if (model.isEdge(cell))
			{
				name = 'edge';
			}
			else if (childCount > 0 && geo != null)
			{
				name = 'group';
			}
			else if (model.isVertex(cell))
			{
				name = 'vertex';
			}
			
			if (name != null)
			{
				var node = enc.document.createElement(name);
				var lab = view.graph.getLabel(cell);
				
				if (lab != null)
				{
					node.setAttribute('label', view.graph.getLabel(cell));
					
					if (view.graph.isHtmlLabel(cell))
					{
						node.setAttribute('html', true);
					}
				}
		
				if (parent == null)
				{
					var bounds = view.getGraphBounds();
					
					if (bounds != null)
					{
						node.setAttribute('x', Math.round(bounds.x));
						node.setAttribute('y', Math.round(bounds.y));
						node.setAttribute('width', Math.round(bounds.width));
						node.setAttribute('height', Math.round(bounds.height));
					}
					
					node.setAttribute('scale', view.scale);
				}
				else if (state != null && geo != null)
				{
					// Writes each key, value in the style pair to an attribute
				    for (var i in state.style)
				    {
				    	var value = state.style[i];
		
				    	// Tries to turn objects and functions into strings
					    if (typeof(value) == 'function' &&
							typeof(value) == 'object')
						{
					    	value = mxStyleRegistry.getName(value);
				        }
				    	
				    	if (value != null &&
				    		typeof(value) != 'function' &&
							typeof(value) != 'object')
						{
							node.setAttribute(i, value);
				        }
				    }
				    
					var abs = state.absolutePoints;
					
					// Writes the list of points into one attribute
					if (abs != null && abs.length > 0)
					{
						var pts = Math.round(abs[0].x) + ',' + Math.round(abs[0].y);
		
						for (var i=1; i<abs.length; i++)
						{
							pts += ' ' + Math.round(abs[i].x) + ',' +
								Math.round(abs[i].y);
						}
		
						node.setAttribute('points', pts);
					}
					
					// Writes the bounds into 4 attributes
					else
					{
						node.setAttribute('x', Math.round(state.x));
						node.setAttribute('y', Math.round(state.y));
						node.setAttribute('width', Math.round(state.width));
						node.setAttribute('height', Math.round(state.height));				
					}
		
					var offset = state.absoluteOffset;
					
					// Writes the offset into 2 attributes
					if (offset != null)
					{
						if (offset.x != 0)
						{
							node.setAttribute('dx', Math.round(offset.x));
						}
						
						if (offset.y != 0)
						{
							node.setAttribute('dy', Math.round(offset.y));
						}
					}
				}
		
				for (var i=0; i<childCount; i++)
				{
					var childNode = this.encodeCell(enc,
							view, model.getChildAt(cell, i));
					
					if (childNode != null)
					{
						node.appendChild(childNode);
					}
				}
			}
		}
		
		return node;
	};

	// Returns the codec into the registry
	return codec;

}());
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxStylesheetCodec
 *
 * Codec for <mxStylesheet>s. This class is created and registered
 * dynamically at load time and used implicitely via <mxCodec>
 * and the <mxCodecRegistry>.
 */
var mxStylesheetCodec = mxCodecRegistry.register(function()
{
	var codec = new mxObjectCodec(new mxStylesheet());

	/**
	 * Function: encode
	 *
	 * Encodes a stylesheet. See <decode> for a description of the
	 * format.
	 */
	codec.encode = function(enc, obj)
	{
		var node = enc.document.createElement(this.getName());
		
		for (var i in obj.styles)
		{
			var style = obj.styles[i];
			var styleNode = enc.document.createElement('add');
			
			if (i != null)
			{
				styleNode.setAttribute('as', i);
				
				for (var j in style)
				{
					var value = this.getStringValue(j, style[j]);
					
					if (value != null)
					{
						var entry = enc.document.createElement('add');
						entry.setAttribute('value', value);
						entry.setAttribute('as', j);
						styleNode.appendChild(entry);
					}
				}
				
				if (styleNode.childNodes.length > 0)
				{
					node.appendChild(styleNode);
				}
			}
		}
		
	    return node;
	};

	/**
	 * Function: getStringValue
	 *
	 * Returns the string for encoding the given value.
	 */
	codec.getStringValue = function(key, value)
	{
		var type = typeof(value);
		
		if (type == 'function')
		{
			value = mxStyleRegistry.getName(style[j]);
		}
		else if (type == 'object')
		{
			value = null;
		}
		
		return value;
	};
	
	/**
	 * Function: decode
	 *
	 * Reads a sequence of the following child nodes
	 * and attributes:
	 *
	 * Child Nodes:
	 *
	 * add - Adds a new style.
	 *
	 * Attributes:
	 *
	 * as - Name of the style.
	 * extend - Name of the style to inherit from.
	 *
	 * Each node contains another sequence of add and remove nodes with the following
	 * attributes:
	 *
	 * as - Name of the style (see <mxConstants>).
	 * value - Value for the style.
	 *
	 * Instead of the value-attribute, one can put Javascript expressions into
	 * the node as follows if <mxStylesheetCodec.allowEval> is true:
	 * <add as="perimeter">mxPerimeter.RectanglePerimeter</add>
	 *
	 * A remove node will remove the entry with the name given in the as-attribute
	 * from the style.
	 * 
	 * Example:
	 *
	 * (code)
	 * <mxStylesheet as="stylesheet">
	 *   <add as="text">
	 *     <add as="fontSize" value="12"/>
	 *   </add>
	 *   <add as="defaultVertex" extend="text">
	 *     <add as="shape" value="rectangle"/>
	 *   </add>
	 * </mxStylesheet>
	 * (end)
	 */
	codec.decode = function(dec, node, into)
	{
		var obj = into || new this.template.constructor();
		var id = node.getAttribute('id');
		
		if (id != null)
		{
			dec.objects[id] = obj;
		}
		
		node = node.firstChild;
		
		while (node != null)
		{
			if (!this.processInclude(dec, node, obj) && node.nodeName == 'add')
			{
				var as = node.getAttribute('as');
				
				if (as != null)
				{
					var extend = node.getAttribute('extend');
					var style = (extend != null) ? mxUtils.clone(obj.styles[extend]) : null;
					
					if (style == null)
					{
						if (extend != null)
						{
							mxLog.warn('mxStylesheetCodec.decode: stylesheet ' +
								extend + ' not found to extend');
						}
						
						style = new Object();
					}
					
					var entry = node.firstChild;
					
					while (entry != null)
					{
						if (entry.nodeType == mxConstants.NODETYPE_ELEMENT)
						{
						 	var key = entry.getAttribute('as');
						 	
						 	if (entry.nodeName == 'add')
						 	{
							 	var text = mxUtils.getTextContent(entry);
							 	var value = null;
							 	
							 	if (text != null && text.length > 0 && mxStylesheetCodec.allowEval)
							 	{
							 		value = mxUtils.eval(text);
							 	}
							 	else
							 	{
							 		value = entry.getAttribute('value');
							 		
							 		if (mxUtils.isNumeric(value))
							 		{
										value = parseFloat(value);
									}
							 	}

							 	if (value != null)
							 	{
							 		style[key] = value;
							 	}
						 	}
						 	else if (entry.nodeName == 'remove')
						 	{
						 		delete style[key];
						 	}
						}
						
						entry = entry.nextSibling;
					}
					
					obj.putCellStyle(as, style);
				}
			}
			
			node = node.nextSibling;
		}
		
		return obj;
	};

	// Returns the codec into the registry
	return codec;

}());

/**
 * Variable: allowEval
 * 
 * Static global switch that specifies if the use of eval is allowed for
 * evaluating text content. Default is true. Set this to false if stylesheets
 * may contain user input.
 */
mxStylesheetCodec.allowEval = true;
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
mxCodecRegistry.register(function()
{
	/**
	 * Class: mxDefaultKeyHandlerCodec
	 *
	 * Custom codec for configuring <mxDefaultKeyHandler>s. This class is created
	 * and registered dynamically at load time and used implicitely via
	 * <mxCodec> and the <mxCodecRegistry>. This codec only reads configuration
	 * data for existing key handlers, it does not encode or create key handlers.
	 */
	var codec = new mxObjectCodec(new mxDefaultKeyHandler());

	/**
	 * Function: encode
	 *
	 * Returns null.
	 */
	codec.encode = function(enc, obj)
	{
		return null;
	};
	
	/**
	 * Function: decode
	 *
	 * Reads a sequence of the following child nodes
	 * and attributes:
	 *
	 * Child Nodes:
	 *
	 * add - Binds a keystroke to an actionname.
	 *
	 * Attributes:
	 *
	 * as - Keycode.
	 * action - Actionname to execute in editor.
	 * control - Optional boolean indicating if
	 * 		the control key must be pressed.
	 *
	 * Example:
	 *
	 * (code)
	 * <mxDefaultKeyHandler as="keyHandler">
	 *   <add as="88" control="true" action="cut"/>
	 *   <add as="67" control="true" action="copy"/>
	 *   <add as="86" control="true" action="paste"/>
	 * </mxDefaultKeyHandler>
	 * (end)
	 *
	 * The keycodes are for the x, c and v keys.
	 *
	 * See also: <mxDefaultKeyHandler.bindAction>,
	 * http://www.js-examples.com/page/tutorials__key_codes.html
	 */
	codec.decode = function(dec, node, into)
	{
		if (into != null)
		{
			var editor = into.editor;
			node = node.firstChild;
			
			while (node != null)
			{
				if (!this.processInclude(dec, node, into) &&
					node.nodeName == 'add')
				{
					var as = node.getAttribute('as');
					var action = node.getAttribute('action');
					var control = node.getAttribute('control');
					
					into.bindAction(as, action, control);
				}
				
				node = node.nextSibling;
			}
		}
		
		return into;
	};

	// Returns the codec into the registry
	return codec;

}());
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxDefaultToolbarCodec
 *
 * Custom codec for configuring <mxDefaultToolbar>s. This class is created
 * and registered dynamically at load time and used implicitely via
 * <mxCodec> and the <mxCodecRegistry>. This codec only reads configuration
 * data for existing toolbars handlers, it does not encode or create toolbars.
 */
var mxDefaultToolbarCodec = mxCodecRegistry.register(function()
{
	var codec = new mxObjectCodec(new mxDefaultToolbar());

	/**
	 * Function: encode
	 *
	 * Returns null.
	 */
	codec.encode = function(enc, obj)
	{
		return null;
	};
	
	/**
	 * Function: decode
	 *
	 * Reads a sequence of the following child nodes
	 * and attributes:
	 *
	 * Child Nodes:
	 *
	 * add - Adds a new item to the toolbar. See below for attributes.
	 * separator - Adds a vertical separator. No attributes.
	 * hr - Adds a horizontal separator. No attributes.
	 * br - Adds a linefeed. No attributes. 
	 *
	 * Attributes:
	 *
	 * as - Resource key for the label.
	 * action - Name of the action to execute in enclosing editor.
	 * mode - Modename (see below).
	 * template - Template name for cell insertion.
	 * style - Optional style to override the template style.
	 * icon - Icon (relative/absolute URL).
	 * pressedIcon - Optional icon for pressed state (relative/absolute URL).
	 * id - Optional ID to be used for the created DOM element.
	 * toggle - Optional 0 or 1 to disable toggling of the element. Default is
	 * 1 (true).
	 *
	 * The action, mode and template attributes are mutually exclusive. The
	 * style can only be used with the template attribute. The add node may
	 * contain another sequence of add nodes with as and action attributes
	 * to create a combo box in the toolbar. If the icon is specified then
	 * a list of the child node is expected to have its template attribute
	 * set and the action is ignored instead.
	 * 
	 * Nodes with a specified template may define a function to be used for
	 * inserting the cloned template into the graph. Here is an example of such
	 * a node:
	 * 
	 * (code)
	 * <add as="Swimlane" template="swimlane" icon="images/swimlane.gif"><![CDATA[
	 *   function (editor, cell, evt, targetCell)
	 *   {
	 *     var pt = mxUtils.convertPoint(
	 *       editor.graph.container, mxEvent.getClientX(evt),
	 *         mxEvent.getClientY(evt));
	 *     return editor.addVertex(targetCell, cell, pt.x, pt.y);
	 *   }
	 * ]]></add>
	 * (end)
	 * 
	 * In the above function, editor is the enclosing <mxEditor> instance, cell
	 * is the clone of the template, evt is the mouse event that represents the
	 * drop and targetCell is the cell under the mousepointer where the drop
	 * occurred. The targetCell is retrieved using <mxGraph.getCellAt>.
	 *
	 * Futhermore, nodes with the mode attribute may define a function to
	 * be executed upon selection of the respective toolbar icon. In the
	 * example below, the default edge style is set when this specific
	 * connect-mode is activated:
	 *
	 * (code)
	 * <add as="connect" mode="connect"><![CDATA[
	 *   function (editor)
	 *   {
	 *     if (editor.defaultEdge != null)
	 *     {
	 *       editor.defaultEdge.style = 'straightEdge';
	 *     }
	 *   }
	 * ]]></add>
	 * (end)
	 * 
	 * Both functions require <mxDefaultToolbarCodec.allowEval> to be set to true.
	 *
	 * Modes:
	 *
	 * select - Left mouse button used for rubberband- & cell-selection.
	 * connect - Allows connecting vertices by inserting new edges.
	 * pan - Disables selection and switches to panning on the left button.
	 *
	 * Example:
	 *
	 * To add items to the toolbar:
	 * 
	 * (code)
	 * <mxDefaultToolbar as="toolbar">
	 *   <add as="save" action="save" icon="images/save.gif"/>
	 *   <br/><hr/>
	 *   <add as="select" mode="select" icon="images/select.gif"/>
	 *   <add as="connect" mode="connect" icon="images/connect.gif"/>
	 * </mxDefaultToolbar>
	 * (end)
	 */
	codec.decode = function(dec, node, into)
	{
		if (into != null)
		{
			var editor = into.editor;
			node = node.firstChild;
			
			while (node != null)
			{
				if (node.nodeType == mxConstants.NODETYPE_ELEMENT)
				{
					if (!this.processInclude(dec, node, into))
					{
						if (node.nodeName == 'separator')
						{
							into.addSeparator();
						}
						else if (node.nodeName == 'br')
						{
							into.toolbar.addBreak();
						}
						else if (node.nodeName == 'hr')
						{
							into.toolbar.addLine();
						}
						else if (node.nodeName == 'add')
						{
							var as = node.getAttribute('as');
							as = mxResources.get(as) || as;
							var icon = node.getAttribute('icon');
							var pressedIcon = node.getAttribute('pressedIcon');
							var action = node.getAttribute('action');
							var mode = node.getAttribute('mode');
							var template = node.getAttribute('template');
							var toggle = node.getAttribute('toggle') != '0';
							var text = mxUtils.getTextContent(node);
							var elt = null;

							if (action != null)
							{
								elt = into.addItem(as, icon, action, pressedIcon);
							}
							else if (mode != null)
							{
								var funct = (mxDefaultToolbarCodec.allowEval) ? mxUtils.eval(text) : null;
								elt = into.addMode(as, icon, mode, pressedIcon, funct);
							}
							else if (template != null || (text != null && text.length > 0))
							{
								var cell = editor.templates[template];
								var style = node.getAttribute('style');
								
								if (cell != null && style != null)
								{
									cell = editor.graph.cloneCells([cell])[0];
									cell.setStyle(style);
								}
								
								var insertFunction = null;
								
								if (text != null && text.length > 0 && mxDefaultToolbarCodec.allowEval)
								{
									insertFunction = mxUtils.eval(text);
								}
								
								elt = into.addPrototype(as, icon, cell, pressedIcon, insertFunction, toggle);
							}
							else
							{
								var children = mxUtils.getChildNodes(node);
								
								if (children.length > 0)
								{
									if (icon == null)
									{
										var combo = into.addActionCombo(as);
										
										for (var i=0; i<children.length; i++)
										{
											var child = children[i];
											
											if (child.nodeName == 'separator')
											{
												into.addOption(combo, '---');
											}
											else if (child.nodeName == 'add')
											{
												var lab = child.getAttribute('as');
												var act = child.getAttribute('action');
												into.addActionOption(combo, lab, act);
											}
										}
									}
									else
									{
										var select = null;
										var create = function()
										{
											var template = editor.templates[select.value];
											
											if (template != null)
											{
												var clone = template.clone();
												var style = select.options[select.selectedIndex].cellStyle;
												
												if (style != null)
												{
													clone.setStyle(style);
												}
												
												return clone;
											}
											else
											{
												mxLog.warn('Template '+template+' not found');
											}
											
											return null;
										};
										
										var img = into.addPrototype(as, icon, create, null, null, toggle);
										select = into.addCombo();
										
										// Selects the toolbar icon if a selection change
										// is made in the corresponding combobox.
										mxEvent.addListener(select, 'change', function()
										{
											into.toolbar.selectMode(img, function(evt)
											{
												var pt = mxUtils.convertPoint(editor.graph.container,
													mxEvent.getClientX(evt), mxEvent.getClientY(evt));
												
												return editor.addVertex(null, funct(), pt.x, pt.y);
											});
											
											into.toolbar.noReset = false;
										});
										
										// Adds the entries to the combobox
										for (var i=0; i<children.length; i++)
										{
											var child = children[i];
											
											if (child.nodeName == 'separator')
											{
												into.addOption(select, '---');
											}
											else if (child.nodeName == 'add')
											{
												var lab = child.getAttribute('as');
												var tmp = child.getAttribute('template');
												var option = into.addOption(select, lab, tmp || template);
												option.cellStyle = child.getAttribute('style');
											}
										}
										
									}
								}
							}
							
							// Assigns an ID to the created element to access it later.
							if (elt != null)
							{
								var id = node.getAttribute('id');
								
								if (id != null && id.length > 0)
								{
									elt.setAttribute('id', id);
								}
							}
						}
					}
				}
				
				node = node.nextSibling;
			}
		}
		
		return into;
	};
	
	// Returns the codec into the registry
	return codec;

}());

/**
 * Variable: allowEval
 * 
 * Static global switch that specifies if the use of eval is allowed for
 * evaluating text content. Default is true. Set this to false if stylesheets
 * may contain user input
 */
mxDefaultToolbarCodec.allowEval = true;
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
mxCodecRegistry.register(function()
{
	/**
	 * Class: mxDefaultPopupMenuCodec
	 *
	 * Custom codec for configuring <mxDefaultPopupMenu>s. This class is created
	 * and registered dynamically at load time and used implicitely via
	 * <mxCodec> and the <mxCodecRegistry>. This codec only reads configuration
	 * data for existing popup menus, it does not encode or create menus. Note
	 * that this codec only passes the configuration node to the popup menu,
	 * which uses the config to dynamically create menus. See
	 * <mxDefaultPopupMenu.createMenu>.
	 */
	var codec = new mxObjectCodec(new mxDefaultPopupMenu());

	/**
	 * Function: encode
	 *
	 * Returns null.
	 */
	codec.encode = function(enc, obj)
	{
		return null;
	};
	
	/**
	 * Function: decode
	 *
	 * Uses the given node as the config for <mxDefaultPopupMenu>.
	 */
	codec.decode = function(dec, node, into)
	{
		var inc = node.getElementsByTagName('include')[0];
		
		if (inc != null)
		{
			this.processInclude(dec, inc, into);
		}
		else if (into != null)
		{
			into.config = node;
		}
		
		return into;
	};
	
	// Returns the codec into the registry
	return codec;

}());
/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
mxCodecRegistry.register(function()
{
	/**
	 * Class: mxEditorCodec
	 *
	 * Codec for <mxEditor>s. This class is created and registered
	 * dynamically at load time and used implicitely via <mxCodec>
	 * and the <mxCodecRegistry>.
	 *
	 * Transient Fields:
	 *
	 * - modified
	 * - lastSnapshot
	 * - ignoredChanges
	 * - undoManager
	 * - graphContainer
	 * - toolbarContainer
	 */
	var codec = new mxObjectCodec(new mxEditor(),
		['modified', 'lastSnapshot', 'ignoredChanges',
		'undoManager', 'graphContainer', 'toolbarContainer']);

	/**
	 * Function: beforeDecode
	 *
	 * Decodes the ui-part of the configuration node by reading
	 * a sequence of the following child nodes and attributes
	 * and passes the control to the default decoding mechanism:
	 *
	 * Child Nodes:
	 *
	 * stylesheet - Adds a CSS stylesheet to the document.
	 * resource - Adds the basename of a resource bundle.
	 * add - Creates or configures a known UI element.
	 *
	 * These elements may appear in any order given that the
	 * graph UI element is added before the toolbar element
	 * (see Known Keys).
	 *
	 * Attributes:
	 *
	 * as - Key for the UI element (see below).
	 * element - ID for the element in the document.
	 * style - CSS style to be used for the element or window.
	 * x - X coordinate for the new window.
	 * y - Y coordinate for the new window.
	 * width - Width for the new window.
	 * height - Optional height for the new window.
	 * name - Name of the stylesheet (absolute/relative URL).
	 * basename - Basename of the resource bundle (see <mxResources>).
	 *
	 * The x, y, width and height attributes are used to create a new
	 * <mxWindow> if the element attribute is not specified in an add
	 * node. The name and basename are only used in the stylesheet and
	 * resource nodes, respectively.
	 *
	 * Known Keys:
	 *
	 * graph - Main graph element (see <mxEditor.setGraphContainer>).
	 * title - Title element (see <mxEditor.setTitleContainer>).
	 * toolbar - Toolbar element (see <mxEditor.setToolbarContainer>).
	 * status - Status bar element (see <mxEditor.setStatusContainer>).
	 *
	 * Example:
	 *
	 * (code)
	 * <ui>
	 *   <stylesheet name="css/process.css"/>
	 *   <resource basename="resources/app"/>
	 *   <add as="graph" element="graph"
	 *     style="left:70px;right:20px;top:20px;bottom:40px"/>
	 *   <add as="status" element="status"/>
	 *   <add as="toolbar" x="10" y="20" width="54"/>
	 * </ui>
	 * (end)
	 */
	codec.afterDecode = function(dec, node, obj)
	{
		// Assigns the specified templates for edges
		var defaultEdge = node.getAttribute('defaultEdge');
		
		if (defaultEdge != null)
		{
			node.removeAttribute('defaultEdge');
			obj.defaultEdge = obj.templates[defaultEdge];
		}

		// Assigns the specified templates for groups
		var defaultGroup = node.getAttribute('defaultGroup');
		
		if (defaultGroup != null)
		{
			node.removeAttribute('defaultGroup');
			obj.defaultGroup = obj.templates[defaultGroup];
		}

		return obj;
	};
	
	/**
	 * Function: decodeChild
	 * 
	 * Overrides decode child to handle special child nodes.
	 */	
	codec.decodeChild = function(dec, child, obj)
	{
		if (child.nodeName == 'Array')
		{
			var role = child.getAttribute('as');
			
			if (role == 'templates')
			{
				this.decodeTemplates(dec, child, obj);
				return;
			}
		}
		else if (child.nodeName == 'ui')
		{
			this.decodeUi(dec, child, obj);
			return;
		}
		
		mxObjectCodec.prototype.decodeChild.apply(this, arguments);
	};
		
	/**
	 * Function: decodeTemplates
	 *
	 * Decodes the cells from the given node as templates.
	 */
	codec.decodeUi = function(dec, node, editor)
	{
		var tmp = node.firstChild;
		while (tmp != null)
		{
			if (tmp.nodeName == 'add')
			{
				var as = tmp.getAttribute('as');
				var elt = tmp.getAttribute('element');
				var style = tmp.getAttribute('style');
				var element = null;

				if (elt != null)
				{
					element = document.getElementById(elt);
					
					if (element != null && style != null)
					{
						element.style.cssText += ';' + style;
					}
				}
				else
				{
					var x = parseInt(tmp.getAttribute('x'));
					var y = parseInt(tmp.getAttribute('y'));
					var width = tmp.getAttribute('width');
					var height = tmp.getAttribute('height');

					// Creates a new window around the element
					element = document.createElement('div');
					element.style.cssText = style;
					
					var wnd = new mxWindow(mxResources.get(as) || as,
						element, x, y, width, height, false, true);
					wnd.setVisible(true);
				}
				
				// TODO: Make more generic
				if (as == 'graph')
				{
					editor.setGraphContainer(element);
				}
				else if (as == 'toolbar')
				{
					editor.setToolbarContainer(element);
				}
				else if (as == 'title')
				{
					editor.setTitleContainer(element);
				}
				else if (as == 'status')
				{
					editor.setStatusContainer(element);
				}
				else if (as == 'map')
				{
					editor.setMapContainer(element);
				}
			}
			else if (tmp.nodeName == 'resource')
			{
				mxResources.add(tmp.getAttribute('basename'));
			}
			else if (tmp.nodeName == 'stylesheet')
			{
				mxClient.link('stylesheet', tmp.getAttribute('name'));
			}
			
			tmp = tmp.nextSibling;
		}	
	};
	
	/**
	 * Function: decodeTemplates
	 *
	 * Decodes the cells from the given node as templates.
	 */
	codec.decodeTemplates = function(dec, node, editor)
	{
		if (editor.templates == null)
		{
			editor.templates = [];
		}
		
		var children = mxUtils.getChildNodes(node);
		for (var j=0; j<children.length; j++)
		{
			var name = children[j].getAttribute('as');
			var child = children[j].firstChild;
			
			while (child != null && child.nodeType != 1)
			{
				child = child.nextSibling;
			}
			
			if (child != null)
			{
				// LATER: Only single cells means you need
				// to group multiple cells within another
				// cell. This should be changed to support
				// arrays of cells, or the wrapper must
				// be automatically handled in this class.
				editor.templates[name] = dec.decodeCell(child);
			}
		}
	};
	
	// Returns the codec into the registry
	return codec;

}());
