Bladeren bron

8.6.9 release

Former-commit-id: dd3ab4e4d482b9f3fdd354469481c8b5434cc6ea
Gaudenz Alder 7 jaren geleden
bovenliggende
commit
636273370b
41 gewijzigde bestanden met toevoegingen van 3688 en 3438 verwijderingen
  1. 7 0
      ChangeLog
  2. 1 1
      VERSION
  3. 4 4
      etc/mxgraph/mxClient.js
  4. 1 3
      src/main/webapp/cache.manifest
  5. 2 2
      src/main/webapp/connect/confluence/admin.js
  6. 1 1
      src/main/webapp/connect/confluence/connect.json
  7. 52 12
      src/main/webapp/connect/confluence/connectUtils-1-4-8.js
  8. 8 3
      src/main/webapp/connect/confluence/macroEditor.html
  9. 12 10
      src/main/webapp/connect/confluence/viewer-1-4-8.html
  10. BIN
      src/main/webapp/images/facebook.png
  11. BIN
      src/main/webapp/images/favicon-16x16.png
  12. BIN
      src/main/webapp/images/favicon-32x32.png
  13. BIN
      src/main/webapp/images/tweet.png
  14. 622 623
      src/main/webapp/js/app.min.js
  15. 528 529
      src/main/webapp/js/atlas-viewer.min.js
  16. 1144 1144
      src/main/webapp/js/atlas.min.js
  17. 103 108
      src/main/webapp/js/diagramly/App.js
  18. 19 3
      src/main/webapp/js/diagramly/Editor.js
  19. 32 8
      src/main/webapp/js/diagramly/EditorUi.js
  20. 11 2
      src/main/webapp/js/diagramly/Embed.js
  21. 199 192
      src/main/webapp/js/diagramly/Menus.js
  22. 4 20
      src/main/webapp/js/diagramly/Minimal.js
  23. 4 15
      src/main/webapp/js/diagramly/Pages.js
  24. 6 8
      src/main/webapp/js/diagramly/sidebar/Sidebar-WebIcons.js
  25. 62 13
      src/main/webapp/js/diagramly/vsdx/importer.js
  26. 27 26
      src/main/webapp/js/embed-static.min.js
  27. 11 2
      src/main/webapp/js/embed.dev.js
  28. 21 20
      src/main/webapp/js/embed.min.js
  29. 29 28
      src/main/webapp/js/extensions.min.js
  30. 2 2
      src/main/webapp/js/mxgraph/Actions.js
  31. 5 0
      src/main/webapp/js/mxgraph/Editor.js
  32. 3 2
      src/main/webapp/js/mxgraph/EditorUi.js
  33. 1 1
      src/main/webapp/js/mxgraph/Graph.js
  34. 10 5
      src/main/webapp/js/mxgraph/Menus.js
  35. 6 6
      src/main/webapp/js/reader.min.js
  36. 2 2
      src/main/webapp/js/stencils.min.js
  37. 528 529
      src/main/webapp/js/viewer.min.js
  38. 2 1
      src/main/webapp/mxgraph/css/common.css
  39. 61 2
      src/main/webapp/plugins/cConf-1-4-8.js
  40. 47 57
      src/main/webapp/stencils/webicons.xml
  41. 111 54
      src/main/webapp/stencils/weblogos.xml

+ 7 - 0
ChangeLog

@@ -1,3 +1,10 @@
+29-MAY-2018: 8.6.9
+
+- Adds enableCustomLibraries switch
+- Fixes math rendering timing bug
+- Uses mxGraph 3.9.6 beta 1
+- Uses MathJax 2.7.4
+
 24-MAY-2018: 8.6.8
 
 - Fixes math typesetting in PDF export

+ 1 - 1
VERSION

@@ -1 +1 @@
-8.6.8
+8.6.9

File diff suppressed because it is too large
+ 4 - 4
etc/mxgraph/mxClient.js


+ 1 - 3
src/main/webapp/cache.manifest

@@ -1,7 +1,7 @@
 CACHE MANIFEST
 
 # THIS FILE WAS GENERATED. DO NOT MODIFY!
-# 05/24/2018 11:31 AM
+# 05/29/2018 06:47 PM
 
 app.html
 index.html?offline=1
@@ -26,11 +26,9 @@ mxgraph/images/window.gif
 mxgraph/images/window-title.gif
 mxgraph/images/button.gif
 mxgraph/images/point.gif
-mxgraph/images/transparent.gif
 resources/dia.txt
 images/delete.png
 images/droptarget.png
-images/edit.gif
 images/help.png
 images/download.png
 images/drawlogo-text-bottom.svg

+ 2 - 2
src/main/webapp/connect/confluence/admin.js

@@ -320,7 +320,7 @@ var GliffyMassImporter = function(logDiv)
 			 						};
 				 					
 				 					//Add custom content
-				 					AC.saveCustomContent(spaceKey, pageId, pageType, attName + ".drawio.xml", attInfo.revision, null, null, 
+				 					AC.saveCustomContent(spaceKey, pageId, pageType, attName + ".drawio.xml", attName + ".drawio.xml", attInfo.revision, null, null, 
 				 							function(responseText)
 				 							{
 				 								logDiv.append($('<div>Gliffy diagram "'+ AC.htmlEntities(attName) +'" imported successfully.</div>'));
@@ -403,7 +403,7 @@ var DrawIoDiagramsIndexer = function(logDiv)
 		
 		function addNewCustomContent()
 		{
-			AC.saveCustomContent(spaceKey, pageId, pageType, attName, revision, null, null, 
+			AC.saveCustomContent(spaceKey, pageId, pageType, attName, attName, revision, null, null, 
 					function(responseText)
 					{
 						logDiv.append($('<div>Diagram "'+ AC.htmlEntities(attName) +'" indexed successfully.</div>'));

+ 1 - 1
src/main/webapp/connect/confluence/connect.json

@@ -76,7 +76,7 @@
                     "i18n": "drawioMacro",
                     "value": "Draw.io Diagram"
                 },
-                "url": "/connect/confluence/viewer-1-4-8.html?ceoId=${page.id}&diagramName=${diagramName}&revision=${revision}&width=${width}&height=${height}&tbstyle=${tbstyle}&lbox=${lbox}&zoom=${zoom}&links=${links}&owningPageId=${pageId}",
+                "url": "/connect/confluence/viewer-1-4-8.html?ceoId=${page.id}&diagramName=${diagramName}&revision=${revision}&width=${width}&height=${height}&tbstyle=${tbstyle}&lbox=${lbox}&zoom=${zoom}&links=${links}&owningPageId=${pageId}&displayName=${diagramDisplayName}",
                 "width": "100%",
                 "description": 
                 {

+ 52 - 12
src/main/webapp/connect/confluence/connectUtils-1-4-8.js

@@ -431,6 +431,8 @@ AC.init = function(baseUrl, location, pageId, editor, diagramName, initialXml, d
 	var user = AC.getUrlParam('user_id', true);
 	var draftExists = false;
 	
+	var diagramDisplayName = macroData != null? (macroData.diagramDisplayName || diagramName) : diagramName;
+	
 	AP.require(['messages', 'confluence', 'request'], function(messages, confluence, request)
 	{
 		var newPage = location.indexOf('createpage.action') > -1 ? true : false;
@@ -613,7 +615,7 @@ AC.init = function(baseUrl, location, pageId, editor, diagramName, initialXml, d
 		if (initialXml != '')
 		{
 			editor.contentWindow.postMessage(JSON.stringify({action: 'load',
-				autosave: 1, xml: initialXml, title: diagramName,
+				autosave: 1, xml: initialXml, title: diagramDisplayName,
 				macroData: macroData}), '*');
 		}
 
@@ -621,7 +623,7 @@ AC.init = function(baseUrl, location, pageId, editor, diagramName, initialXml, d
 		{
 			// Keeps ignore option even for existing files
 			editor.contentWindow.postMessage(JSON.stringify({action: 'draft', xml: draftXml,
-				name: diagramName, discardKey: 'discardChanges', ignore: true}), '*');
+				name: diagramDisplayName, discardKey: 'discardChanges', ignore: true}), '*');
 		}
 		else if (initialXml == '')
 		{
@@ -654,7 +656,7 @@ AC.init = function(baseUrl, location, pageId, editor, diagramName, initialXml, d
 						//console.trace('DRAFT: Using', draftName);
 
 						editor.contentWindow.postMessage(JSON.stringify({action: 'load',
-							autosave: 1, xml: drawMsg.message.xml, title: diagramName}), '*');
+							autosave: 1, xml: drawMsg.message.xml, title: diagramDisplayName}), '*');
 						editor.contentWindow.postMessage(JSON.stringify({action: 'status',
 							messageKey: 'unsavedChanges', modified: true}), '*');
 						draftExists = true;
@@ -666,7 +668,7 @@ AC.init = function(baseUrl, location, pageId, editor, diagramName, initialXml, d
 							if (initialXml != '')
 							{
 								editor.contentWindow.postMessage(JSON.stringify({action: 'load',
-									autosave: 1, xml: initialXml, title: diagramName,
+									autosave: 1, xml: initialXml, title: diagramDisplayName,
 									macroData: macroData}), '*');
 							}
 							else
@@ -843,6 +845,7 @@ AC.init = function(baseUrl, location, pageId, editor, diagramName, initialXml, d
 						checkName(drawMsg.name, function(name)
 						{
 							diagramName = name;
+							diagramDisplayName = name;
 							
 							AP.require('request', function(request) {
 								
@@ -853,7 +856,7 @@ AC.init = function(baseUrl, location, pageId, editor, diagramName, initialXml, d
 										success: function(xml) 
 										{
 											editor.contentWindow.postMessage(JSON.stringify({action: 'load',
-												autosave: 1, xml: xml, title: diagramName}), '*');
+												autosave: 1, xml: xml, title: diagramDisplayName}), '*');
 											editor.contentWindow.postMessage(JSON.stringify({action: 'spinner',
 												show: false}), '*');
 										},
@@ -906,6 +909,7 @@ AC.init = function(baseUrl, location, pageId, editor, diagramName, initialXml, d
 							editor.contentWindow.postMessage(JSON.stringify({action: 'spinner',
 								show: false}), '*');
 							diagramName = name;
+							diagramDisplayName = name;
 	
 							if (AC.draftEnabled)
 							{
@@ -917,7 +921,7 @@ AC.init = function(baseUrl, location, pageId, editor, diagramName, initialXml, d
 								{
 									editor.contentWindow.postMessage(JSON.stringify({action: 'spinner', show: false}), '*');
 									editor.contentWindow.postMessage(JSON.stringify({action: 'load',
-										autosave: 1, xml: drawMsg.xml, title: diagramName}), '*');
+										autosave: 1, xml: drawMsg.xml, title: diagramDisplayName}), '*');
 								},
 								function()
 								{
@@ -933,7 +937,7 @@ AC.init = function(baseUrl, location, pageId, editor, diagramName, initialXml, d
 							else
 							{
 								editor.contentWindow.postMessage(JSON.stringify({action: 'load',
-									autosave: 1, xml: drawMsg.xml, title: diagramName}), '*');
+									autosave: 1, xml: drawMsg.xml, title: diagramDisplayName}), '*');
 							}
 						},
 						function(name, err, errKey)
@@ -996,6 +1000,7 @@ AC.init = function(baseUrl, location, pageId, editor, diagramName, initialXml, d
 						editor.contentWindow.postMessage(JSON.stringify({action: 'spinner',
 							show: false}), '*');
 						diagramName = name;
+						diagramDisplayName = name;
 						editor.contentWindow.postMessage(JSON.stringify({action: 'export',
 							format: 'png', spinKey: 'saving'}), '*');
 					},
@@ -1006,6 +1011,39 @@ AC.init = function(baseUrl, location, pageId, editor, diagramName, initialXml, d
 						promptName(name, err, errKey);
 					});
 				}
+				else if (drawMsg.event == 'rename')
+				{
+					//If diagram name is not set yet, use the new name for both file and diagram
+					//TODO should we disable renaming if diagramName is null?
+					if (diagramName == null) 
+					{
+						editor.contentWindow.postMessage(JSON.stringify({action: 'spinner',
+							show: true}), '*');
+
+						checkName(drawMsg.name, function(name)
+						{
+							editor.contentWindow.postMessage(JSON.stringify({action: 'spinner',
+								show: false}), '*');
+							diagramName = name;
+							diagramDisplayName = name;
+						},
+						function(name, err, errKey)
+						{
+							editor.contentWindow.postMessage(JSON.stringify({action: 'spinner',
+								show: false}), '*');
+							editor.contentWindow.postMessage(JSON.stringify({action: 'dialog',
+								titleKey: 'error', message: err, messageKey: errKey,
+								buttonKey: 'ok'}), '*');
+						});	
+					}
+					else
+					{
+						diagramDisplayName = drawMsg.name;
+					}
+					
+					editor.contentWindow.postMessage(JSON.stringify({action: 'status',
+						messageKey: 'unsavedChanges', modified: true}), '*');
+				}
 				else if (drawMsg.event == 'export')
 				{
 					// Proceeds from sending the export message by saving the exported files
@@ -1078,7 +1116,7 @@ AC.init = function(baseUrl, location, pageId, editor, diagramName, initialXml, d
 							var spaceKey = AC.getSpaceKey(attObj._expandable.space);
 							var pageType = attObj.container.type;
 
-							AC.saveCustomContent(spaceKey, pageId, pageType, diagramName, revision, 
+							AC.saveCustomContent(spaceKey, pageId, pageType, diagramName, diagramDisplayName, revision, 
 									(drawMsg.macroData != null) ? drawMsg.macroData.contentId  : null,
 									(drawMsg.macroData != null) ? drawMsg.macroData.contentVer : null,
 									function(responseText) 
@@ -1121,6 +1159,7 @@ AC.init = function(baseUrl, location, pageId, editor, diagramName, initialXml, d
 								confluence.saveMacro(
 								{
 									diagramName: diagramName,
+									diagramDisplayName: diagramDisplayName,
 									revision: revision,
 									pageId: newPage ? null : pageId,
 									contentId: contentId,
@@ -1200,6 +1239,7 @@ AC.loadDiagram = function (pageId, diagramName, revision, success, error, owning
 						confluence.saveMacro(
 						{
 							diagramName: macroData.diagramName,
+							diagramDisplayName: macroData.diagramDisplayName != null ? macroData.diagramDisplayName : macroData.diagramName,
 							revision: attInfo.version.number,
 							pageId: macroData.pageId,
 							contentId: macroData.contentId,
@@ -1309,7 +1349,7 @@ AC.loadDiagram = function (pageId, diagramName, revision, success, error, owning
 	});
 };
 
-AC.saveCustomContent = function(spaceKey, pageId, pageType, diagramName, revision, contentId, contentVer, success, error)
+AC.saveCustomContent = function(spaceKey, pageId, pageType, diagramName, diagramDisplayName, revision, contentId, contentVer, success, error)
 {
     var customObj = {
         "type": "ac:com.mxgraph.confluence.plugins.diagramly:drawio-diagram",
@@ -1320,7 +1360,7 @@ AC.saveCustomContent = function(spaceKey, pageId, pageType, diagramName, revisio
                "type": pageType,
                "id": pageId
             },
-         "title": diagramName,
+         "title": diagramDisplayName,
          "body": {
            "storage": {
              "value": encodeURIComponent(JSON.stringify({
@@ -1356,7 +1396,7 @@ AC.saveCustomContent = function(spaceKey, pageId, pageType, diagramName, revisio
                
                if (contentId && err.statusCode == 403 && err.message.indexOf(contentId) > 0)
                {
-                   AC.saveCustomContent(spaceKey, pageId, pageType, diagramName, revision, null, null, success, error);
+                   AC.saveCustomContent(spaceKey, pageId, pageType, diagramName, diagramDisplayName, revision, null, null, success, error);
                }
                //Sometimes the macro is not updated such that the version is not correct. The same happens when a page version is restored
                else if (err.statusCode == 409 && err.message.indexOf("Current version is:") > 0)
@@ -1367,7 +1407,7 @@ AC.saveCustomContent = function(spaceKey, pageId, pageType, diagramName, revisio
             	   
             	   if (curContentVer != null)
         		   {
-            		   AC.saveCustomContent(spaceKey, pageId, pageType, diagramName, revision, contentId, curContentVer[0], success, error);
+            		   AC.saveCustomContent(spaceKey, pageId, pageType, diagramName, diagramDisplayName, revision, contentId, curContentVer[0], success, error);
         		   }
         	   }
                else

+ 8 - 3
src/main/webapp/connect/confluence/macroEditor.html

@@ -34,14 +34,19 @@
 	var script = document.createElement('script');
 	script.setAttribute('data-options', 'resize:false;margin:false');
 	
-	alert("Unsupported draw.io version, please upgrade.");
-	
 	// Main
 	script.onload = function()
 	{
 		AP.sizeToParent(true);
-		AC.initAsync(baseUrl);
+		
+		alert("Unsupported draw.io version, please upgrade.");
+		
+		AP.require(['confluence'], function (confluence)
+		{
+			confluence.closeMacroEditor();
+		});
 	};
+
 	script.src = connectUrl + '/all.js';
 	head.appendChild(script);
 	

+ 12 - 10
src/main/webapp/connect/confluence/viewer-1-4-8.html

@@ -78,6 +78,7 @@ if (lang != null)
 	var diagramWidth = parseFloat(getUrlParam('width'));
 	var diagramHeight = parseFloat(getUrlParam('height'));
 	var diagramName = getUrlParam('diagramName');
+	var displayName = getUrlParam('displayName');
 	
 	//ceoId and owningPageId are IDs of the page that potentially hold the attachment
 	//they will differ when page history is shown, ceoId will be historical version ID,
@@ -128,8 +129,9 @@ if (lang != null)
 				}
 				
 				// Loads the given XML into the viewer
-				function showDiagram(id, backupId, name, revision, page, links, retryParams)
+				function showDiagram(id, backupId, name, revision, page, links, retryParams, displayName)
 				{
+					displayName = displayName || name;
 					id = id.toString();
 					
 					retryParams = retryParams || {}; //so we can use it without NPE check
@@ -260,7 +262,7 @@ if (lang != null)
 											
 											if (tbStyle == 'top')
 											{
-												config.title = name;
+												config.title = displayName;
 											}
 	
 											if (links != 'auto')
@@ -325,10 +327,10 @@ if (lang != null)
 											{
 								                dialog.create(
 								                {
-								                    header: name,
+								                    header: displayName,
 								                		key: 'lightbox',
 								                    size: 'fullscreen',
-								                    customData: {id: id, name: name, revision: revision, page: viewer.currentPage, links: links},
+								                    customData: {id: id, name: name, revision: revision, page: viewer.currentPage, links: links, displayName: displayName},
 								                    chrome: true
 								                });
 											};
@@ -350,7 +352,7 @@ if (lang != null)
 											if (attInfo.version.number > loadedVer 
 													&& (pageInfo.version.message == null || pageInfo.version.message.indexOf("Reverted") < 0)) 
 											{
-												showDiagram(id, backupId, name, attInfo.version.number + '', page, links, {dontCheckVer: true});
+												showDiagram(id, backupId, name, attInfo.version.number + '', page, links, {dontCheckVer: true}, displayName);
 												//I think updating macro here is too risky since calling confluence.getMacroData returns null
 											}
 										}
@@ -440,12 +442,12 @@ if (lang != null)
 							 			//So, try revision 1 first
 							 			if (revision > 1)
 							 			{
-								 			showDiagram(id, backupId, name, null, page, links, {revision: revision});
+								 			showDiagram(id, backupId, name, null, page, links, {revision: revision}, displayName);
 							 			}
 							 			else if (backupId != null)
 						 				{
 								 			//Since attachment wasn't found in this page, it is better to save it to this page
-								 			showDiagram(backupId, null, name, revision || retryParams.revision, page, links, {saveIt: true, pageId: id});
+								 			showDiagram(backupId, null, name, revision || retryParams.revision, page, links, {saveIt: true, pageId: id}, displayName);
 						 				}
 							 		}
 							 		else if (acceptResponse)
@@ -477,7 +479,7 @@ if (lang != null)
                             
                             var info = JSON.parse(decodeURIComponent(resp.body.storage.value));
                             
-                            showDiagram(info.pageId, info.pageId, info.diagramName, info.version, null, links, {dontCheckVer: true}); //custom content can load old versions which will be overridden by version check
+                            showDiagram(info.pageId, info.pageId, info.diagramName, info.version, null, links, {dontCheckVer: true}, resp.title); //custom content can load old versions which will be overridden by version check
                         },
                         error: function (resp) 
                         {
@@ -489,12 +491,12 @@ if (lang != null)
 				{
 					// Gets the paramters from the customData object in lightbox mode
 					// LATER: Add XML to custom data (does not seem to work)
-					showDiagram(dialog.customData.id, dialog.customData.id, dialog.customData.name, dialog.customData.revision, dialog.customData.page, dialog.customData.links);
+					showDiagram(dialog.customData.id, dialog.customData.id, dialog.customData.name, dialog.customData.revision, dialog.customData.page, dialog.customData.links, null, dialog.customData.displayName);
 				}
 				else
 				{
 					var myPageId = (owningPageId != null && owningPageId.length > 0) ? owningPageId : ceoId;
-					showDiagram(candidateId, (owningPageId != null && owningPageId.length > 0) ? owningPageId : ceoId, diagramName, revision, null, links);
+					showDiagram(candidateId, (owningPageId != null && owningPageId.length > 0) ? owningPageId : ceoId, diagramName, revision, null, links, null, displayName);
 				}
 		    });
 		});

BIN
src/main/webapp/images/facebook.png


BIN
src/main/webapp/images/favicon-16x16.png


BIN
src/main/webapp/images/favicon-32x32.png


BIN
src/main/webapp/images/tweet.png


File diff suppressed because it is too large
+ 622 - 623
src/main/webapp/js/app.min.js


File diff suppressed because it is too large
+ 528 - 529
src/main/webapp/js/atlas-viewer.min.js


File diff suppressed because it is too large
+ 1144 - 1144
src/main/webapp/js/atlas.min.js


+ 103 - 108
src/main/webapp/js/diagramly/App.js

@@ -551,111 +551,122 @@ App.main = function(callback, createUi)
 		Editor.initMath();
 	}
 
-	// Adds required resources (disables loading of fallback properties, this can only
-	// be used if we know that all keys are defined in the language specific file)
-	mxResources.loadDefaultBundle = false;
-	var bundle = mxResources.getDefaultBundle(RESOURCE_BASE, mxLanguage) ||
-		mxResources.getSpecialBundle(RESOURCE_BASE, mxLanguage);
-
-	// Prefetches asynchronous requests so that below code runs synchronous
-	// Loading the correct bundle (one file) via the fallback system in mxResources. The stylesheet
-	// is compiled into JS in the build process and is only needed for local development.
-	mxUtils.getAll((urlParams['dev'] != '1') ? [bundle] : [bundle, (uiTheme == 'dark') ? STYLE_PATH + '/dark-default.xml' : STYLE_PATH + '/default.xml'], function(xhr)
+	function doLoad(bundle)
 	{
-		// Adds bundle text to resources
-		mxResources.parse(xhr[0].getText());
-		
-		// Prepares themes with mapping from old default-style to old XML file
-		if (xhr.length > 1)
+		// Prefetches asynchronous requests so that below code runs synchronous
+		// Loading the correct bundle (one file) via the fallback system in mxResources. The stylesheet
+		// is compiled into JS in the build process and is only needed for local development.
+		mxUtils.getAll((urlParams['dev'] != '1') ? [bundle] : [bundle, (uiTheme == 'dark') ? STYLE_PATH + '/dark-default.xml' : STYLE_PATH + '/default.xml'], function(xhr)
 		{
- 			Graph.prototype.defaultThemes[Graph.prototype.defaultThemeName] = xhr[1].getDocumentElement();
-		}
-
-		// Main
-		var ui = (createUi != null) ? createUi() : new App(new Editor(urlParams['chrome'] == '0' || uiTheme == 'min', null, null, null, urlParams['chrome'] != '0'));
-		
-		if (window.mxscript != null)
-		{
-			// Loads dropbox for all browsers but IE8 and below (no CORS) if not disabled or if enabled and in embed mode
-			// KNOWN: Picker does not work in IE11 (https://dropbox.zendesk.com/requests/1650781)
-			if (typeof window.DropboxClient === 'function' &&
-				(window.Dropbox == null && window.DrawDropboxClientCallback != null &&
-				(((urlParams['embed'] != '1' && urlParams['db'] != '0') ||
-				(urlParams['embed'] == '1' && urlParams['db'] == '1')) &&
-				isSvgBrowser && (document.documentMode == null || document.documentMode > 9))))
-			{
-				mxscript(App.DROPBOX_URL, function()
-				{
-					// Must load this after the dropbox SDK since they use the same namespace
-					mxscript(App.DROPINS_URL, function()
-					{
-						DrawDropboxClientCallback();
-					}, 'dropboxjs', App.DROPBOX_APPKEY);
-				});
-			}
-			// Disables client
-			else if (typeof window.Dropbox === 'undefined' || typeof window.Dropbox.choose === 'undefined')
-			{
-				window.DropboxClient = null;
-			}
-				
-			// Loads OneDrive for all browsers but IE6/IOS if not disabled or if enabled and in embed mode
-			if (typeof window.OneDriveClient === 'function' &&
-				(typeof OneDrive === 'undefined' && window.DrawOneDriveClientCallback != null &&
-				(((urlParams['embed'] != '1' && urlParams['od'] != '0') || (urlParams['embed'] == '1' &&
-				urlParams['od'] == '1')) && (navigator.userAgent.indexOf('MSIE') < 0 || document.documentMode >= 10))))
-			{
-				mxscript(App.ONEDRIVE_URL, window.DrawOneDriveClientCallback);
-			}
-			// Disables client
-			else if (typeof window.OneDrive === 'undefined')
+			// Adds bundle text to resources
+			mxResources.parse(xhr[0].getText());
+			
+			// Prepares themes with mapping from old default-style to old XML file
+			if (xhr.length > 1)
 			{
-				window.OneDriveClient = null;
+	 			Graph.prototype.defaultThemes[Graph.prototype.defaultThemeName] = xhr[1].getDocumentElement();
 			}
+	
+			// Main
+			var ui = (createUi != null) ? createUi() : new App(new Editor(urlParams['chrome'] == '0' || uiTheme == 'min', null, null, null, urlParams['chrome'] != '0'));
 			
-			// Loads Trello for all browsers but < IE10 if not disabled or if enabled and in embed mode
-			if (typeof window.TrelloClient === 'function' &&
-				(typeof window.Trello === 'undefined' && window.DrawTrelloClientCallback != null &&
-				(((urlParams['embed'] != '1' && urlParams['tr'] != '0') || (urlParams['embed'] == '1' &&
-				urlParams['tr'] == '1')) && (navigator.userAgent.indexOf('MSIE') < 0 || document.documentMode >= 10))))
+			if (window.mxscript != null)
 			{
-				mxscript(App.TRELLO_JQUERY_URL, function()
+				// Loads dropbox for all browsers but IE8 and below (no CORS) if not disabled or if enabled and in embed mode
+				// KNOWN: Picker does not work in IE11 (https://dropbox.zendesk.com/requests/1650781)
+				if (typeof window.DropboxClient === 'function' &&
+					(window.Dropbox == null && window.DrawDropboxClientCallback != null &&
+					(((urlParams['embed'] != '1' && urlParams['db'] != '0') ||
+					(urlParams['embed'] == '1' && urlParams['db'] == '1')) &&
+					isSvgBrowser && (document.documentMode == null || document.documentMode > 9))))
 				{
-					// Must load this after the dropbox SDK since they use the same namespace
-					mxscript(App.TRELLO_URL, function()
+					mxscript(App.DROPBOX_URL, function()
 					{
-						DrawTrelloClientCallback();
+						// Must load this after the dropbox SDK since they use the same namespace
+						mxscript(App.DROPINS_URL, function()
+						{
+							DrawDropboxClientCallback();
+						}, 'dropboxjs', App.DROPBOX_APPKEY);
 					});
-				});
+				}
+				// Disables client
+				else if (typeof window.Dropbox === 'undefined' || typeof window.Dropbox.choose === 'undefined')
+				{
+					window.DropboxClient = null;
+				}
+					
+				// Loads OneDrive for all browsers but IE6/IOS if not disabled or if enabled and in embed mode
+				if (typeof window.OneDriveClient === 'function' &&
+					(typeof OneDrive === 'undefined' && window.DrawOneDriveClientCallback != null &&
+					(((urlParams['embed'] != '1' && urlParams['od'] != '0') || (urlParams['embed'] == '1' &&
+					urlParams['od'] == '1')) && (navigator.userAgent.indexOf('MSIE') < 0 || document.documentMode >= 10))))
+				{
+					mxscript(App.ONEDRIVE_URL, window.DrawOneDriveClientCallback);
+				}
+				// Disables client
+				else if (typeof window.OneDrive === 'undefined')
+				{
+					window.OneDriveClient = null;
+				}
+				
+				// Loads Trello for all browsers but < IE10 if not disabled or if enabled and in embed mode
+				if (typeof window.TrelloClient === 'function' &&
+					(typeof window.Trello === 'undefined' && window.DrawTrelloClientCallback != null &&
+					(((urlParams['embed'] != '1' && urlParams['tr'] != '0') || (urlParams['embed'] == '1' &&
+					urlParams['tr'] == '1')) && (navigator.userAgent.indexOf('MSIE') < 0 || document.documentMode >= 10))))
+				{
+					mxscript(App.TRELLO_JQUERY_URL, function()
+					{
+						// Must load this after the dropbox SDK since they use the same namespace
+						mxscript(App.TRELLO_URL, function()
+						{
+							DrawTrelloClientCallback();
+						});
+					});
+				}
+				// Disables client
+				else if (typeof window.Trello === 'undefined')
+				{
+					window.TrelloClient = null;
+				}
+	
 			}
-			// Disables client
-			else if (typeof window.Trello === 'undefined')
+			
+			if (callback != null)
 			{
-				window.TrelloClient = null;
+				callback(ui);
 			}
-
-		}
-		
-		if (callback != null)
-		{
-			callback(ui);
-		}
-		
-		/**
-		 * For developers only
-		 */
-		if (urlParams['chrome'] != '0' && urlParams['test'] == '1')
+			
+			/**
+			 * For developers only
+			 */
+			if (urlParams['chrome'] != '0' && urlParams['test'] == '1')
+			{
+				mxLog.show();
+				mxLog.debug('Started in ' + (new Date().getTime() - t0.getTime()) + 'ms');
+				mxLog.debug('Export:', EXPORT_URL);
+				mxLog.debug('Development mode:', (urlParams['dev'] == '1') ? 'active' : 'inactive');
+				mxLog.debug('Test mode:', (urlParams['test'] == '1') ? 'active' : 'inactive');
+			}
+		}, function(xhr)
 		{
-			mxLog.show();
-			mxLog.debug('Started in ' + (new Date().getTime() - t0.getTime()) + 'ms');
-			mxLog.debug('Export:', EXPORT_URL);
-			mxLog.debug('Development mode:', (urlParams['dev'] == '1') ? 'active' : 'inactive');
-			mxLog.debug('Test mode:', (urlParams['test'] == '1') ? 'active' : 'inactive');
-		}
-	}, function()
-	{
-		document.getElementById('geStatus').innerHTML = 'Error loading page. <a href="javascript:void(0);" onclick="location.reload();">Please try refreshing.</a>';
-	});
+			document.getElementById('geStatus').innerHTML = 'Error loading page. <a href="javascript:void(0);">Please try refreshing.</a>';
+			
+			// Tries reload with default resources in case any language resources were not available
+			document.getElementById('geStatus').getElementsByTagName('a')[0].onclick = function()
+			{
+				mxLanguage = 'en';
+				doLoad(mxResources.getDefaultBundle(RESOURCE_BASE, mxLanguage) ||
+						mxResources.getSpecialBundle(RESOURCE_BASE, mxLanguage));
+			};
+		});
+	};
+	
+	// Adds required resources (disables loading of fallback properties, this can only
+	// be used if we know that all keys are defined in the language specific file)
+	mxResources.loadDefaultBundle = false;
+	doLoad(mxResources.getDefaultBundle(RESOURCE_BASE, mxLanguage) ||
+		mxResources.getSpecialBundle(RESOURCE_BASE, mxLanguage));
 };
 
 //Extends EditorUi
@@ -1416,22 +1427,6 @@ App.prototype.createCrcTable = function()
     return crcTable;
 };
 
-/**
- * Authorizes the client, gets the userId and calls <open>.
- */
-App.prototype.crc32 = function(str)
-{
-	this.crcTable = this.crcTable || this.createCrcTable();
-    var crc = 0 ^ (-1);
-
-    for (var i = 0; i < str.length; i++ )
-    {
-        crc = (crc >>> 8) ^ this.crcTable[(crc ^ str.charCodeAt(i)) & 0xFF];
-    }
-
-    return (crc ^ (-1)) >>> 0;
-};
-
 /**
  * Returns a thumbnail of the current file.
  */

+ 19 - 3
src/main/webapp/js/diagramly/Editor.js

@@ -58,6 +58,11 @@
 	 * Default value for custom libraries in mxSettings.
 	 */
 	Editor.defaultCustomLibraries = [];
+	
+	/**
+	 * Default value for custom libraries in mxSettings.
+	 */
+	Editor.enableCustomLibraries = true;
 
 	/**
 	 * Default value for the CSV import dialog.
@@ -200,6 +205,12 @@
 				Editor.defaultCustomLibraries = config.defaultCustomLibraries;
 			}
 			
+			// Disables custom libraries
+			if (config.enableCustomLibraries != null)
+			{
+				Editor.enableCustomLibraries = config.enableCustomLibraries;
+			}
+			
 			// Overrides default vertex style
 			if (config.defaultVertexStyle != null)
 			{
@@ -565,7 +576,7 @@
 	 */
 	Editor.initMath = function(src, config)
 	{
-		src = (src != null) ? src : 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-MML-AM_HTMLorMML';
+		src = (src != null) ? src : 'https://math.draw.io/current/MathJax.js?config=TeX-MML-AM_HTMLorMML';
 		Editor.mathJaxQueue = [];
 		
 		Editor.doMathJaxRender = function(container)
@@ -593,6 +604,9 @@
 				MathJax.Hub.Config(config || {
 					jax: ['input/TeX', 'input/MathML', 'input/AsciiMath', 'output/HTML-CSS'],
 					extensions: ['tex2jax.js', 'mml2jax.js', 'asciimath2jax.js'],
+					'HTML-CSS': {
+						imageFont: null
+					},
 					TeX: {
 					  extensions: ['AMSmath.js', 'AMSsymbols.js', 'noErrors.js', 'noUndefined.js']
 					},
@@ -2120,10 +2134,12 @@
 				doc.writeln('messageStyle: "none",');
 				doc.writeln('jax: ["input/TeX", "input/MathML", "input/AsciiMath", "output/HTML-CSS"],');
 				doc.writeln('extensions: ["tex2jax.js", "mml2jax.js", "asciimath2jax.js"],');
+				doc.writeln('"HTML-CSS": {');
+				doc.writeln('imageFont: null');
+				doc.writeln('},');
 				doc.writeln('TeX: {');
 				doc.writeln('extensions: ["AMSmath.js", "AMSsymbols.js", "noErrors.js", "noUndefined.js"]');
 				doc.writeln('},');
-							// Ignores math in in-place editor
 				doc.writeln('tex2jax: {');
 				doc.writeln('	ignoreClass: "geDisableMathJax"');
 			  	doc.writeln('},');
@@ -2141,7 +2157,7 @@
 				}
 				
 				doc.writeln('</script>');
-				doc.writeln('<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js"></script>');
+				doc.writeln('<script type="text/javascript" src="https://math.draw.io/current/MathJax.js"></script>');
 			}
 			
 			pv.closeDocument();

+ 32 - 8
src/main/webapp/js/diagramly/EditorUi.js

@@ -1040,7 +1040,7 @@
 	 * @param {number} dx X-coordinate of the translation.
 	 * @param {number} dy Y-coordinate of the translation.
 	 */
-	EditorUi.prototype.getBaseFilename = function()
+	EditorUi.prototype.getBaseFilename = function(ignorePageName)
 	{
 		var file = this.getCurrentFile();
 		var basename = (file != null && file.getTitle() != null) ? file.getTitle() : this.defaultFilename;
@@ -1050,6 +1050,13 @@
 		{
 			basename = basename.substring(0, basename.lastIndexOf('.'));
 		}
+
+		if (!ignorePageName && this.pages != null && this.pages.length > 1 &&
+			this.currentPage != null && this.currentPage.node.getAttribute('name') != null &&
+			this.currentPage.getName().length > 0)
+		{
+			basename = basename + '-' + this.currentPage.getName();
+		}
 		
 		return basename;
 	};
@@ -1065,7 +1072,7 @@
 		try
 		{
 			ignoreSelection = (ignoreSelection != null) ? ignoreSelection : this.editor.graph.isSelectionEmpty();
-			var basename = this.getBaseFilename();
+			var basename = this.getBaseFilename(!currentPage);
 			var filename = basename + '.' + format;
 			
 			if (format == 'xml')
@@ -2572,8 +2579,8 @@
 											else
 											{
 												this.handleError({message: mxResources.get((xhr.status == 413) ?
-					            						'drawingTooLarge' : 'invalidOrMissingFile')},
-					            						mxResources.get('errorLoadingFile'));
+				            						'drawingTooLarge' : 'invalidOrMissingFile')},
+				            						mxResources.get('errorLoadingFile'));
 											}
 										}
 									}));
@@ -2608,7 +2615,7 @@
 			}
 	
 			btn = btn.cloneNode(false);
-			btn.setAttribute('src', IMAGE_PATH + '/edit.gif');
+			btn.setAttribute('src', Editor.editImage);
 			btn.setAttribute('title', mxResources.get('edit'));
 			buttons.insertBefore(btn, buttons.firstChild);
 			
@@ -6956,6 +6963,19 @@
 		return c;
 	};
 
+	EditorUi.prototype.crc32 = function(str)
+	{
+		this.crcTable = this.crcTable || this.createCrcTable();
+	    var crc = 0 ^ (-1);
+
+	    for (var i = 0; i < str.length; i++ )
+	    {
+	        crc = (crc >>> 8) ^ this.crcTable[(crc ^ str.charCodeAt(i)) & 0xFF];
+	    }
+
+	    return (crc ^ (-1)) >>> 0;
+	};
+
 	/**
 	 * Adds the given text to the compressed or non-compressed text chunk.
 	 */
@@ -10362,10 +10382,14 @@
 		// while waiting for file data
 		var libsEnabled = urlParams['embed'] != '1' ||
 				this.editor.graph.isEnabled();
-		this.menus.get('openLibraryFrom').setEnabled(libsEnabled);
-		this.menus.get('newLibrary').setEnabled(libsEnabled);
 		this.menus.get('extras').setEnabled(libsEnabled);
 		
+		if (Editor.enableCustomLibraries)
+		{
+			this.menus.get('openLibraryFrom').setEnabled(libsEnabled);
+			this.menus.get('newLibrary').setEnabled(libsEnabled);
+		}
+		
 		// Disables actions in the toolbar
 		var editable = (urlParams['embed'] == '1' &&
 			this.editor.graph.isEnabled()) ||
@@ -10546,7 +10570,7 @@
 		this.actions.get('find').setEnabled(enabled);
 		this.actions.get('layers').setEnabled(enabled);
 		this.actions.get('outline').setEnabled(enabled);
-		this.actions.get('rename').setEnabled(file != null && file.isRenamable());
+		this.actions.get('rename').setEnabled((file != null && file.isRenamable()) || urlParams['embed'] == '1');
 		this.actions.get('close').setEnabled(file != null);
 		this.menus.get('publish').setEnabled(file != null && !file.isRestricted());
 		

+ 11 - 2
src/main/webapp/js/diagramly/Embed.js

@@ -50,7 +50,16 @@
 				messageStyle: 'none',
 				AuthorInit: function ()
 				{
-					MathJax.Hub.Config({"HTML-CSS":{availableFonts:[],webFont:"STIX-Web",imageFont:null}});
+					MathJax.Hub.Config({
+						jax: ['input/TeX', 'input/MathML', 'input/AsciiMath', 'output/HTML-CSS'],
+						extensions: ['tex2jax.js', 'mml2jax.js', 'asciimath2jax.js'],
+						'HTML-CSS': {
+							imageFont: null
+						},
+						TeX: {
+						  extensions: ['AMSmath.js', 'AMSsymbols.js', 'noErrors.js', 'noUndefined.js']
+						}
+					});
 					
 					MathJax.Hub.Register.StartupHook('Begin', function()
 					{
@@ -64,7 +73,7 @@
 
 			var script = document.createElement('script');
 			script.type = 'text/javascript';
-			script.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-MML-AM_HTMLorMML';
+			script.src = 'https://math.draw.io/current/MathJax.js?config=TeX-MML-AM_HTMLorMML';
 			document.getElementsByTagName('head')[0].appendChild(script);
 		}
 	};

+ 199 - 192
src/main/webapp/js/diagramly/Menus.js

@@ -172,7 +172,7 @@
 						editorUi.createHtml(publicUrl, zoomEnabled, initialZoom, linkTarget, linkColor,
 							fit, allPages, layers, lightbox, editLink, mxUtils.bind(this, function(html, scriptTag)
 							{
-								var basename = editorUi.getBaseFilename();
+								var basename = editorUi.getBaseFilename(allPages);
 								var result = '<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=5,IE=9" ><![endif]-->\n' +
 									'<!DOCTYPE html>\n<html>\n<head>\n<title>' + mxUtils.htmlEntities(basename) + '</title>\n' +
 									'<meta charset="utf-8"/>\n</head>\n<body>' + html + '\n' + scriptTag + '\n</body>\n</html>';
@@ -1830,7 +1830,7 @@
 			}
 		})));
 
-		this.editorUi.actions.addAction('rename...', mxUtils.bind(this, function()
+		var renameAction = this.editorUi.actions.addAction('rename...', mxUtils.bind(this, function()
 		{
 			var file = this.editorUi.getCurrentFile();
 			
@@ -1867,11 +1867,15 @@
 				this.editorUi.showDialog(dlg.container, 300, 80, true, true);
 				dlg.init();
 			}
-		})).isEnabled = function()
+		}));
+		
+		renameAction.isEnabled = function()
 		{
 			return this.enabled && isGraphEnabled.apply(this, arguments);
 		}
 		
+		renameAction.visible = urlParams['embed'] != '1';
+		
 		editorUi.actions.addAction('makeCopy...', mxUtils.bind(this, function()
 		{
 			var file = editorUi.getCurrentFile();
@@ -2279,240 +2283,243 @@
 			}
 		}));
 		
-		this.put('newLibrary', new Menu(function(menu, parent)
+		if (Editor.enableCustomLibraries)
 		{
-			if (typeof(google) != 'undefined' && typeof(google.picker) != 'undefined')
+			this.put('newLibrary', new Menu(function(menu, parent)
 			{
-				if (editorUi.drive != null)
+				if (typeof(google) != 'undefined' && typeof(google.picker) != 'undefined')
 				{
-					menu.addItem(mxResources.get('googleDrive') + '...', null, function()
+					if (editorUi.drive != null)
 					{
-						editorUi.showLibraryDialog(null, null, null, null, App.MODE_GOOGLE);
+						menu.addItem(mxResources.get('googleDrive') + '...', null, function()
+						{
+							editorUi.showLibraryDialog(null, null, null, null, App.MODE_GOOGLE);
+						}, parent);
+					}
+					else if (googleEnabled)
+					{
+						menu.addItem(mxResources.get('googleDrive') + ' (' + mxResources.get('loading') + '...)', null, function()
+						{
+							// do nothing
+						}, parent, null, false);
+					}
+				}
+				
+				if (editorUi.gitHub != null)
+				{
+					menu.addItem(mxResources.get('github') + '...', null, function()
+					{
+						editorUi.showLibraryDialog(null, null, null, null, App.MODE_GITHUB);
 					}, parent);
 				}
-				else if (googleEnabled)
+				
+				if (editorUi.dropbox != null)
 				{
-					menu.addItem(mxResources.get('googleDrive') + ' (' + mxResources.get('loading') + '...)', null, function()
+					menu.addItem(mxResources.get('dropbox') + '...', null, function()
+					{
+						editorUi.showLibraryDialog(null, null, null, null, App.MODE_DROPBOX);
+					}, parent);
+				}
+				else if (dropboxEnabled)
+				{
+					menu.addItem(mxResources.get('dropbox') + ' (' + mxResources.get('loading') + '...)', null, function()
 					{
 						// do nothing
 					}, parent, null, false);
 				}
-			}
-			
-			if (editorUi.gitHub != null)
-			{
-				menu.addItem(mxResources.get('github') + '...', null, function()
-				{
-					editorUi.showLibraryDialog(null, null, null, null, App.MODE_GITHUB);
-				}, parent);
-			}
-			
-			if (editorUi.dropbox != null)
-			{
-				menu.addItem(mxResources.get('dropbox') + '...', null, function()
+				
+				if (editorUi.oneDrive != null)
 				{
-					editorUi.showLibraryDialog(null, null, null, null, App.MODE_DROPBOX);
-				}, parent);
-			}
-			else if (dropboxEnabled)
-			{
-				menu.addItem(mxResources.get('dropbox') + ' (' + mxResources.get('loading') + '...)', null, function()
+					menu.addItem(mxResources.get('oneDrive') + '...', null, function()
+					{
+						editorUi.showLibraryDialog(null, null, null, null, App.MODE_ONEDRIVE);
+					}, parent);
+				}
+				else if (oneDriveEnabled)
 				{
-					// do nothing
-				}, parent, null, false);
-			}
-			
-			if (editorUi.oneDrive != null)
-			{
-				menu.addItem(mxResources.get('oneDrive') + '...', null, function()
+					menu.addItem(mxResources.get('oneDrive') + ' (' + mxResources.get('loading') + '...)', null, function()
+					{
+						// do nothing
+					}, parent, null, false);
+				}
+				
+				if (editorUi.trello != null)
 				{
-					editorUi.showLibraryDialog(null, null, null, null, App.MODE_ONEDRIVE);
-				}, parent);
-			}
-			else if (oneDriveEnabled)
-			{
-				menu.addItem(mxResources.get('oneDrive') + ' (' + mxResources.get('loading') + '...)', null, function()
+					menu.addItem(mxResources.get('trello') + '...', null, function()
+					{
+						editorUi.showLibraryDialog(null, null, null, null, App.MODE_TRELLO);
+					}, parent);
+				}
+				else if (trelloEnabled)
 				{
-					// do nothing
-				}, parent, null, false);
-			}
-			
-			if (editorUi.trello != null)
-			{
-				menu.addItem(mxResources.get('trello') + '...', null, function()
+					menu.addItem(mxResources.get('trello') + ' (' + mxResources.get('loading') + '...)', null, function()
+					{
+						// do nothing
+					}, parent, null, false);
+				}
+				
+				menu.addSeparator(parent);
+	
+				if (isLocalStorage && urlParams['browser'] != '0')
 				{
-					editorUi.showLibraryDialog(null, null, null, null, App.MODE_TRELLO);
-				}, parent);
-			}
-			else if (trelloEnabled)
-			{
-				menu.addItem(mxResources.get('trello') + ' (' + mxResources.get('loading') + '...)', null, function()
+					menu.addItem(mxResources.get('browser') + '...', null, function()
+					{
+						editorUi.showLibraryDialog(null, null, null, null, App.MODE_BROWSER);
+					}, parent);
+				}
+				
+				if (!mxClient.IS_IOS)
 				{
-					// do nothing
-				}, parent, null, false);
-			}
-			
-			menu.addSeparator(parent);
-
-			if (isLocalStorage && urlParams['browser'] != '0')
+					menu.addItem(mxResources.get('device') + '...', null, function()
+					{
+						editorUi.showLibraryDialog(null, null, null, null, App.MODE_DEVICE);
+					}, parent);
+				}
+			}));
+	
+			this.put('openLibraryFrom', new Menu(function(menu, parent)
 			{
-				menu.addItem(mxResources.get('browser') + '...', null, function()
+				if (typeof(google) != 'undefined' && typeof(google.picker) != 'undefined')
 				{
-					editorUi.showLibraryDialog(null, null, null, null, App.MODE_BROWSER);
-				}, parent);
-			}
-			
-			if (!mxClient.IS_IOS)
-			{
-				menu.addItem(mxResources.get('device') + '...', null, function()
+					if (editorUi.drive != null)
+					{
+						menu.addItem(mxResources.get('googleDrive') + '...', null, function()
+						{
+							editorUi.pickLibrary(App.MODE_GOOGLE);
+						}, parent);
+					}
+					else if (googleEnabled)
+					{
+						menu.addItem(mxResources.get('googleDrive') + ' (' + mxResources.get('loading') + '...)', null, function()
+						{
+							// do nothing
+						}, parent, null, false);
+					}
+				}
+				
+				if (editorUi.gitHub != null)
 				{
-					editorUi.showLibraryDialog(null, null, null, null, App.MODE_DEVICE);
-				}, parent);
-			}
-		}));
-		
-		this.put('openLibraryFrom', new Menu(function(menu, parent)
-		{
-			if (typeof(google) != 'undefined' && typeof(google.picker) != 'undefined')
-			{
-				if (editorUi.drive != null)
+					menu.addItem(mxResources.get('github') + '...', null, function()
+					{
+						editorUi.pickLibrary(App.MODE_GITHUB);
+					}, parent);
+				}
+				
+				if (editorUi.dropbox != null)
 				{
-					menu.addItem(mxResources.get('googleDrive') + '...', null, function()
+					menu.addItem(mxResources.get('dropbox') + '...', null, function()
 					{
-						editorUi.pickLibrary(App.MODE_GOOGLE);
+						editorUi.pickLibrary(App.MODE_DROPBOX);
 					}, parent);
 				}
-				else if (googleEnabled)
+				else if (dropboxEnabled)
 				{
-					menu.addItem(mxResources.get('googleDrive') + ' (' + mxResources.get('loading') + '...)', null, function()
+					menu.addItem(mxResources.get('dropbox') + ' (' + mxResources.get('loading') + '...)', null, function()
 					{
 						// do nothing
 					}, parent, null, false);
 				}
-			}
-			
-			if (editorUi.gitHub != null)
-			{
-				menu.addItem(mxResources.get('github') + '...', null, function()
-				{
-					editorUi.pickLibrary(App.MODE_GITHUB);
-				}, parent);
-			}
-			
-			if (editorUi.dropbox != null)
-			{
-				menu.addItem(mxResources.get('dropbox') + '...', null, function()
-				{
-					editorUi.pickLibrary(App.MODE_DROPBOX);
-				}, parent);
-			}
-			else if (dropboxEnabled)
-			{
-				menu.addItem(mxResources.get('dropbox') + ' (' + mxResources.get('loading') + '...)', null, function()
-				{
-					// do nothing
-				}, parent, null, false);
-			}
-			
-			if (editorUi.oneDrive != null)
-			{
-				menu.addItem(mxResources.get('oneDrive') + '...', null, function()
-				{
-					editorUi.pickLibrary(App.MODE_ONEDRIVE);
-				}, parent);
-			}
-			else if (oneDriveEnabled)
-			{
-				menu.addItem(mxResources.get('oneDrive') + ' (' + mxResources.get('loading') + '...)', null, function()
-				{
-					// do nothing
-				}, parent, null, false);
-			}
-			
-			if (editorUi.trello != null)
-			{
-				menu.addItem(mxResources.get('trello') + '...', null, function()
+				
+				if (editorUi.oneDrive != null)
 				{
-					editorUi.pickLibrary(App.MODE_TRELLO);
-				}, parent);
-			}
-			else if (trelloEnabled)
-			{
-				menu.addItem(mxResources.get('trello') + ' (' + mxResources.get('loading') + '...)', null, function()
+					menu.addItem(mxResources.get('oneDrive') + '...', null, function()
+					{
+						editorUi.pickLibrary(App.MODE_ONEDRIVE);
+					}, parent);
+				}
+				else if (oneDriveEnabled)
 				{
-					// do nothing
-				}, parent, null, false);
-			}
-			
-			menu.addSeparator(parent);
-
-			if (isLocalStorage && urlParams['browser'] != '0')
-			{
-				menu.addItem(mxResources.get('browser') + '...', null, function()
+					menu.addItem(mxResources.get('oneDrive') + ' (' + mxResources.get('loading') + '...)', null, function()
+					{
+						// do nothing
+					}, parent, null, false);
+				}
+				
+				if (editorUi.trello != null)
 				{
-					editorUi.pickLibrary(App.MODE_BROWSER);
-				}, parent);
-			}
-			
-			if (!mxClient.IS_IOS)
-			{
-				menu.addItem(mxResources.get('device') + '...', null, function()
+					menu.addItem(mxResources.get('trello') + '...', null, function()
+					{
+						editorUi.pickLibrary(App.MODE_TRELLO);
+					}, parent);
+				}
+				else if (trelloEnabled)
 				{
-					editorUi.pickLibrary(App.MODE_DEVICE);
-				}, parent);
-			}
-
-			if (!editorUi.isOffline())
-			{
+					menu.addItem(mxResources.get('trello') + ' (' + mxResources.get('loading') + '...)', null, function()
+					{
+						// do nothing
+					}, parent, null, false);
+				}
+				
 				menu.addSeparator(parent);
+	
+				if (isLocalStorage && urlParams['browser'] != '0')
+				{
+					menu.addItem(mxResources.get('browser') + '...', null, function()
+					{
+						editorUi.pickLibrary(App.MODE_BROWSER);
+					}, parent);
+				}
 				
-				menu.addItem(mxResources.get('url') + '...', null, function()
+				if (!mxClient.IS_IOS)
 				{
-					var dlg = new FilenameDialog(editorUi, '', mxResources.get('open'), function(fileUrl)
+					menu.addItem(mxResources.get('device') + '...', null, function()
 					{
-						if (fileUrl != null && fileUrl.length > 0 && editorUi.spinner.spin(document.body, mxResources.get('loading')))
+						editorUi.pickLibrary(App.MODE_DEVICE);
+					}, parent);
+				}
+	
+				if (!editorUi.isOffline())
+				{
+					menu.addSeparator(parent);
+					
+					menu.addItem(mxResources.get('url') + '...', null, function()
+					{
+						var dlg = new FilenameDialog(editorUi, '', mxResources.get('open'), function(fileUrl)
 						{
-							var realUrl = fileUrl;
-							
-							if (!editorUi.isCorsEnabledForUrl(fileUrl))
+							if (fileUrl != null && fileUrl.length > 0 && editorUi.spinner.spin(document.body, mxResources.get('loading')))
 							{
-								realUrl = PROXY_URL + '?url=' + encodeURIComponent(fileUrl);
-							}
-							
-							// Uses proxy to avoid CORS issues
-							mxUtils.get(realUrl, function(req)
-							{
-								if (req.getStatus() >= 200 && req.getStatus() <= 299)
+								var realUrl = fileUrl;
+								
+								if (!editorUi.isCorsEnabledForUrl(fileUrl))
 								{
-									editorUi.spinner.stop();
-									
-									try
+									realUrl = PROXY_URL + '?url=' + encodeURIComponent(fileUrl);
+								}
+								
+								// Uses proxy to avoid CORS issues
+								mxUtils.get(realUrl, function(req)
+								{
+									if (req.getStatus() >= 200 && req.getStatus() <= 299)
 									{
-										editorUi.loadLibrary(new UrlLibrary(this, req.getText(), fileUrl));
+										editorUi.spinner.stop();
+										
+										try
+										{
+											editorUi.loadLibrary(new UrlLibrary(this, req.getText(), fileUrl));
+										}
+										catch (e)
+										{
+											editorUi.handleError(e, mxResources.get('errorLoadingFile'));
+										}
 									}
-									catch (e)
+									else
 									{
-										editorUi.handleError(e, mxResources.get('errorLoadingFile'));
+										editorUi.spinner.stop();
+										editorUi.handleError(null, mxResources.get('errorLoadingFile'));
 									}
-								}
-								else
+								}, function()
 								{
 									editorUi.spinner.stop();
 									editorUi.handleError(null, mxResources.get('errorLoadingFile'));
-								}
-							}, function()
-							{
-								editorUi.spinner.stop();
-								editorUi.handleError(null, mxResources.get('errorLoadingFile'));
-							});
-						}
-					}, mxResources.get('url'));
-					editorUi.showDialog(dlg.container, 300, 80, true, true);
-					dlg.init();
-				}, parent);
-			}
-		}));
-		
+								});
+							}
+						}, mxResources.get('url'));
+						editorUi.showDialog(dlg.container, 300, 80, true, true);
+						dlg.init();
+					}, parent);
+				}
+			}));
+		}
+			
 		// Overrides edit menu to add find
 		this.put('edit', new Menu(mxUtils.bind(this, function(menu, parent)
 		{
@@ -2586,7 +2593,7 @@
 			{
 				this.addMenuItem(menu, 'plugins', parent);
 			}
-				
+
 			menu.addSeparator(parent);
 			this.addMenuItem(menu, 'tags', parent);
 		})));
@@ -2606,7 +2613,7 @@
 					this.addSubmenu('openLibraryFrom', menu, parent);
 				}
 				
-				this.addMenuItems(menu, ['-', 'pageSetup', 'print', '-', 'save'], parent);
+				this.addMenuItems(menu, ['-', 'pageSetup', 'print', '-', 'rename', 'save'], parent);
 				
 				if (urlParams['saveAndExit'] == '1')
 				{

+ 4 - 20
src/main/webapp/js/diagramly/Minimal.js

@@ -123,17 +123,9 @@ EditorUi.initMinimalTheme = function()
 	            
 	            return format;
 	        });
-	        ui.formatWindow.window.addListener('show', function()
-	        {
-	            ui.fireEvent(new mxEventObject('format'));
-	        });
-	        ui.formatWindow.window.addListener('format', function()
-	        {
-	            ui.fireEvent(new mxEventObject('format'));
-	        });
+	        
 	        ui.formatWindow.window.minimumSize = new mxRectangle(0, 0, 240, 80);
 	        ui.formatWindow.window.setVisible(true);
-	        ui.fireEvent(new mxEventObject('sidebar'));
 	    }
 	    else
 	    {
@@ -192,7 +184,7 @@ EditorUi.initMinimalTheme = function()
 	                return elt;
 	            }
 	            
-				if (urlParams['embed'] != '1' || urlParams['libraries'] == '1')
+				if (Editor.enableCustomLibraries && (urlParams['embed'] != '1' || urlParams['libraries'] == '1'))
 	            {
 					// Defined in native apps together with openLibrary
 					if (ui.actions.get('newLibrary') != null)
@@ -241,17 +233,9 @@ EditorUi.initMinimalTheme = function()
 	            
 	            return container;
 	        });
-	        ui.sidebarWindow.window.addListener('show', function()
-	        {
-	            ui.fireEvent(new mxEventObject('sidebar'));
-	        });
-	        ui.sidebarWindow.window.addListener('sidebar', function()
-	        {
-	            ui.fireEvent(new mxEventObject('sidebar'));
-	        });
+	        
 	        ui.sidebarWindow.window.minimumSize = new mxRectangle(0, 0, 90, 90);
 	        ui.sidebarWindow.window.setVisible(true);
-	        ui.fireEvent(new mxEventObject('sidebar'));
 	        
 	        ui.getLocalData('sidebar', function(value)
 	        {
@@ -569,7 +553,7 @@ EditorUi.initMinimalTheme = function()
         }
     };
 
-    DiagramFormatPanel.prototype.isMathOptionVisible = function(div)
+    DiagramFormatPanel.prototype.isMathOptionVisible = function()
     {
         return true;
     };

+ 4 - 15
src/main/webapp/js/diagramly/Pages.js

@@ -328,8 +328,6 @@ EditorUi.prototype.initPages = function()
 		graphViewValidateBackground.apply(graph.view, arguments);
 	});
 
-	// Math workaround is only needed for initial rendering
-	var ignorePendingMath = false;
 	var lastPage = null;
 	
 	var updateTabs = mxUtils.bind(this, function()
@@ -376,28 +374,19 @@ EditorUi.prototype.initPages = function()
 		if (typeof(MathJax) !== 'undefined' && typeof(MathJax.Hub) !== 'undefined')
 		{
 			// Pending math should not be rendered if the graph has no math enabled
-			if (!ignorePendingMath && this.editor != null)
+			if (MathJax.Hub.queue.pending == 1 && this.editor != null && !this.editor.graph.mathEnabled)
 			{
-				if (MathJax.Hub.queue.pending == 1 && !this.editor.graph.mathEnabled)
-				{
-					// Since there is no way to stop/undo mathjax or
-					// clear the queue, we do a refresh after typeset
-					MathJax.Hub.Queue(mxUtils.bind(this, function()
-					{
-						this.editor.graph.refresh();
-					}));
-				}
-				
+				// Since there is no way to stop/undo mathjax or
+				// clear the queue we have to refresh after typeset
 				MathJax.Hub.Queue(mxUtils.bind(this, function()
 				{
-					ignorePendingMath = true;
+					this.editor.graph.refresh();
 				}));
 			}
 		}
 		else if (typeof(Editor.MathJaxClear) !== 'undefined' && (this.editor == null || !this.editor.graph.mathEnabled))
 		{
 			// Clears our own queue for async loading
-			ignorePendingMath = true;
 			Editor.MathJaxClear();
 		}
 	});

+ 6 - 8
src/main/webapp/js/diagramly/sidebar/Sidebar-WebIcons.js

@@ -4,7 +4,7 @@
 	Sidebar.prototype.addWebIconsPalette = function()
 	{
 		var sb = this;
-		var s = 'dashed=0;html=1;' + mxConstants.STYLE_SHAPE + "=mxgraph.webicons.";
+		var s = 'dashed=0;html=1;align=center;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;' + mxConstants.STYLE_SHAPE + "=mxgraph.webicons.";
 		var gn = 'mxgraph.webicons';
 		var dt = 'web icons icon';
 		var w = 0.2;
@@ -92,10 +92,8 @@
 				 w * 512, h * 512, '', 'Diigo', null, null, this.getTagsForStencil(gn, 'diiigo', dt).join(' ')),
 		 this.createVertexTemplateEntry(s + 'dopplr;fillColor=#FFFFFF;gradientColor=#DFDEDE',
 				 w * 512, h * 512, '', 'Dopplr', null, null, this.getTagsForStencil(gn, 'dopplr', dt).join(' ')),
-		 this.createVertexTemplateEntry(s + 'drawio1;fillColor=#2174CE;gradientColor=#134277',
-				 w * 512, h * 512, '', 'Draw.io', null, null, this.getTagsForStencil(gn, 'drawio draw io', dt).join(' ')),
 		 this.createVertexTemplateEntry(s + 'drawio2;fillColor=#2174CE;gradientColor=#134277',
-				 w * 512, h * 512, '', 'Draw.io', null, null, this.getTagsForStencil(gn, 'drawio draw io', dt).join(' ')),
+				 w * 512, h * 512, '', 'Draw.io', null, null, this.getTagsForStencil(gn, 'drawio draw io draw.io', dt).join(' ')),
 		 this.createVertexTemplateEntry(s + 'dribbble;fillColor=#FFFFFF;gradientColor=#DFDEDE',
 				 w * 512, h * 512, '', 'Dribbble', null, null, this.getTagsForStencil(gn, 'dribbble', dt).join(' ')),
 		 this.createVertexTemplateEntry(s + 'dropbox;fillColor=#0BAAFE;gradientColor=#0080E6',
@@ -371,7 +369,7 @@
 	Sidebar.prototype.addWebLogosPalette = function()
 	{
 		var sb = this;
-		var s = 'dashed=0;html=1;' + mxConstants.STYLE_SHAPE + "=mxgraph.weblogos.";
+		var s = 'dashed=0;html=1;align=center;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;' + mxConstants.STYLE_SHAPE + "=mxgraph.weblogos.";
 		var gn = 'mxgraph.weblogos';
 		var dt = 'web logos logo';
 		var w = 0.2;
@@ -467,10 +465,10 @@
 				 w * 306, h * 344, '', 'Diigo', null, null, this.getTagsForStencil(gn, 'diiigo', dt).join(' ')),
 		 this.createVertexTemplateEntry(s + 'dopplr;fillColor=#F9634D;strokeColor=none',
 				 w * 512, h * 512, '', 'Dopplr', null, null, this.getTagsForStencil(gn, 'dopplr', dt).join(' ')),
-		 this.createVertexTemplateEntry(s + 'drawio1;fillColor=#1A5BA3',
-				 w * 248, h * 341, '', 'Draw.io', null, null, this.getTagsForStencil(gn, 'drawio draw io', dt).join(' ')),
 		 this.createVertexTemplateEntry(s + 'drawio2;fillColor=#1A5BA3',
-				 w * 261, h * 354, '', 'Draw.io', null, null, this.getTagsForStencil(gn, 'drawio draw io', dt).join(' ')),
+				 w * 261, h * 354, '', 'Draw.io', null, null, this.getTagsForStencil(gn, 'drawio draw io draw.io', dt).join(' ')),
+		 this.createVertexTemplateEntry(s + 'drawio3;fillColor=#1A5BA3;fontSize=15;fontColor=#1A5BA3;fontStyle=1',
+				 w * 261, h * 261, 'draw<font color="#f08707">.io</font>', 'Draw.io', null, null, this.getTagsForStencil(gn, 'drawio draw io draw.io', dt).join(' ')),
 		 this.createVertexTemplateEntry(s + 'dribbble;fillColor=#EB548D',
 				 w * 337, h * 336, '', 'Dribbble', null, null, this.getTagsForStencil(gn, 'dribbble', dt).join(' ')),
 		 this.createVertexTemplateEntry(s + 'dropbox;fillColor=#0287EA',

+ 62 - 13
src/main/webapp/js/diagramly/vsdx/importer.js

@@ -54,6 +54,36 @@ var com;
                 		return mxVsdxCodec.vsdxPlaceholder;
                 };
                 
+                mxVsdxCodec.parsererrorNS_$LI$ = function ()
+                {
+            		if (mxVsdxCodec.parsererrorNS == null)
+            		{
+            			var parser = new DOMParser();
+            			mxVsdxCodec.parsererrorNS = parser.parseFromString('<', 'text/xml').getElementsByTagName("parsererror")[0].namespaceURI;
+        			}
+
+            		return mxVsdxCodec.parsererrorNS;
+                };
+                
+                mxVsdxCodec.isParseError = function (doc) 
+                {
+                    return doc.getElementsByTagNameNS(mxVsdxCodec.parsererrorNS, 'parsererror').length > 0;
+                };
+                
+                //TODO Optimize this function
+                mxVsdxCodec.decodeUTF16LE = function ( binaryStr ) 
+                {
+                    var cp = "";
+                    for( var i = 0; i < binaryStr.length; i+=2) 
+                    {
+                        cp += String.fromCharCode( 
+                             binaryStr.charCodeAt(i) |
+                            ( binaryStr.charCodeAt(i+1) << 8 )
+                        );
+                    }
+
+                    return cp ;
+                }
                 /**
                  * Parses the input VSDX format and uses the information to populate
                  * the specified graph.
@@ -170,7 +200,24 @@ var com;
 	                    	{
 	                    		var dateAfter = new Date();
 		                         //console.log(processedFiles + " File extracted in " + (dateAfter - dateBefore) + "ms");
-		                         allDone();
+		                     	try
+		                    	{
+		                     		allDone();
+		                    	}
+		                    	catch(e)
+		                    	{
+		                    		console.log(e);
+		                    		
+		                    		if (onerror != null) 
+		                    		{
+		                    			onerror();
+		                    		}
+		                    		else
+		                    		{
+		                    			callback("");
+		                    		}
+		                    	}
+
 	                    	}
                     };
                     
@@ -199,21 +246,22 @@ var com;
 	                            	filesCount++;
 	        	                    zipEntry.async("string").then(function (str) 
 	        	                  	{
-	        	                    		if (!(str.length === 0)) {
+        	                    		if (!(str.length === 0)) {
 	        	    						//UTF-8 BOM causes exception while parsing, so remove it
 	        	    						//TODO is the text encoding will be correct or string must be re-read as UTF-8?
-	                                        if ((function (str, searchString, position) {
-	                                            if (position === void 0) { position = 0; }
-	                                            return str.substr(position, searchString.length) === searchString;
-	                                        })(str, "\u00ef\u00bb\u00bf"))
-	                                            str = str.substring(3);
+	                                        if (str.charCodeAt(0) == 65279)
+                                        	{
+	                                            str = str.substring(1);
+                                        	}
+	                                        
 	                                        var doc = mxUtils.parseXml(str);
-	                                        if (doc == null) { //FIXME TODO find a way to change encoding in javascript
-	//                                            var outBytes = out.toByteArray();
-	//                                            if (outBytes[1] === 0 && outBytes[3] === 0 && outBytes[5] === 0) {
-	//                                                str = out.toString("UTF-16LE");
-	//                                                doc = mxUtils.parseXml(str);
-	//                                            }
+	                                        
+	                                        if ( mxVsdxCodec.isParseError(doc)) 
+	                                        {
+	                                        	if (str.charCodeAt(1) === 0 && str.charCodeAt(3) === 0 && str.charCodeAt(5) === 0)
+                                        		{
+	                                        		doc = mxUtils.parseXml(mxVsdxCodec.decodeUTF16LE(str));
+                                        		}
 	                                        	//TODO add any other non-standard encoding that may be needed 
 	                                        }
 	                                        doc.vsdxFileName = filename;
@@ -11687,6 +11735,7 @@ com.mxgraph.io.vsdx.mxVsdxConstants.SET_VALUES_$LI$();
 com.mxgraph.io.vsdx.mxPropertiesManager.defaultColors_$LI$();
 com.mxgraph.io.vsdx.mxPropertiesManager.__static_initialize();
 com.mxgraph.io.mxVsdxCodec.vsdxPlaceholder_$LI$();
+com.mxgraph.io.mxVsdxCodec.parsererrorNS_$LI$();
 
 EditorUi.prototype.doImportVisio = function(file, done, onerror)
 {

File diff suppressed because it is too large
+ 27 - 26
src/main/webapp/js/embed-static.min.js


+ 11 - 2
src/main/webapp/js/embed.dev.js

@@ -50,7 +50,16 @@
 				messageStyle: 'none',
 				AuthorInit: function ()
 				{
-					MathJax.Hub.Config({"HTML-CSS":{availableFonts:[],webFont:"STIX-Web",imageFont:null}});
+					MathJax.Hub.Config({
+						jax: ['input/TeX', 'input/MathML', 'input/AsciiMath', 'output/HTML-CSS'],
+						extensions: ['tex2jax.js', 'mml2jax.js', 'asciimath2jax.js'],
+						'HTML-CSS': {
+							imageFont: null
+						},
+						TeX: {
+						  extensions: ['AMSmath.js', 'AMSsymbols.js', 'noErrors.js', 'noUndefined.js']
+						}
+					});
 					
 					MathJax.Hub.Register.StartupHook('Begin', function()
 					{
@@ -64,7 +73,7 @@
 
 			var script = document.createElement('script');
 			script.type = 'text/javascript';
-			script.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-MML-AM_HTMLorMML';
+			script.src = 'https://math.draw.io/current/MathJax.js?config=TeX-MML-AM_HTMLorMML';
 			document.getElementsByTagName('head')[0].appendChild(script);
 		}
 	};

File diff suppressed because it is too large
+ 21 - 20
src/main/webapp/js/embed.min.js


File diff suppressed because it is too large
+ 29 - 28
src/main/webapp/js/extensions.min.js


+ 2 - 2
src/main/webapp/js/mxgraph/Actions.js

@@ -587,8 +587,8 @@ Actions.prototype.init = function()
 		if (mxUtils.hasScrollbars(graph.container))
 		{
 			var pad = graph.getPagePadding();
-			graph.container.scrollTop = pad.y * graph.view.scale;
-			graph.container.scrollLeft = Math.min(pad.x * graph.view.scale, (graph.container.scrollWidth - graph.container.clientWidth) / 2);
+			graph.container.scrollTop = pad.y * graph.view.scale - 1;
+			graph.container.scrollLeft = Math.min(pad.x * graph.view.scale, (graph.container.scrollWidth - graph.container.clientWidth) / 2) - 1;
 		}
 	}), null, null, Editor.ctrlKey + '+J');
 	this.addAction('fitTwoPages', mxUtils.bind(this, function()

+ 5 - 0
src/main/webapp/js/mxgraph/Editor.js

@@ -144,6 +144,11 @@ Editor.previousImage = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCA
  */
 Editor.nextImage = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAAi0lEQVQ4jeXUIQ7CUAwA0MeGxWI2yylwnALJUdBcgYvM7QYLmjOQIAkIPmJZghiIvypoUtX0tfnJL38X5ZfaEgUeUcManFBHgS0SLlhHggk3bCPBhCf2keCQR8wjwYTDp6YiZxJmOU1jGw7vGALescuBxsArNlOwd/CM1VSM/ut1qCIw+uOwiMJ+OF4CQzBCXm3hyAAAAABJRU5ErkJggg==';
 
+/**
+ * Specifies the image URL to be used for the transparent background.
+ */
+Editor.editImage = (mxClient.IS_SVG) ? 'data:image/gif;base64,R0lGODlhCwALAIABAFdXV////yH5BAEAAAEALAAAAAALAAsAAAIZjB8AiKuc4jvLOGqzrjX6zmkWyChXaUJBAQA7' : IMAGE_PATH + '/edit.gif';
+
 /**
  * Specifies the image URL to be used for the transparent background.
  */

+ 3 - 2
src/main/webapp/js/mxgraph/EditorUi.js

@@ -2449,8 +2449,9 @@ EditorUi.prototype.resetScrollbars = function()
 			if (graph.pageVisible)
 			{
 				var pad = graph.getPagePadding();
-				graph.container.scrollTop = Math.floor(pad.y - this.editor.initialTopSpacing);
-				graph.container.scrollLeft = Math.floor(Math.min(pad.x, (graph.container.scrollWidth - graph.container.clientWidth) / 2));
+				graph.container.scrollTop = Math.floor(pad.y - this.editor.initialTopSpacing) - 1;
+				graph.container.scrollLeft = Math.floor(Math.min(pad.x,
+					(graph.container.scrollWidth - graph.container.clientWidth) / 2)) - 1;
 
 				// Scrolls graph to visible area
 				var bounds = graph.getGraphBounds();

+ 1 - 1
src/main/webapp/js/mxgraph/Graph.js

@@ -7690,7 +7690,7 @@ if (typeof mxVertexHandler != 'undefined')
 					if (this.graph.isEnabled() && typeof this.graph.editLink === 'function')
 					{
 						var changeLink = document.createElement('img');
-						changeLink.setAttribute('src', IMAGE_PATH + '/edit.gif');
+						changeLink.setAttribute('src', Editor.editImage);
 						changeLink.setAttribute('title', mxResources.get('editLink'));
 						changeLink.setAttribute('width', '11');
 						changeLink.setAttribute('height', '11');

+ 10 - 5
src/main/webapp/js/mxgraph/Menus.js

@@ -512,12 +512,17 @@ Menus.prototype.get = function(name)
  */
 Menus.prototype.addSubmenu = function(name, menu, parent, label)
 {
-	var enabled = this.get(name).isEnabled();
-
-	if (menu.showDisabled || enabled)
+	var entry = this.get(name);
+	
+	if (entry != null)
 	{
-		var submenu = menu.addItem(label || mxResources.get(name), null, null, parent, null, enabled);
-		this.addMenu(name, menu, submenu);
+		var enabled = entry.isEnabled();
+	
+		if (menu.showDisabled || enabled)
+		{
+			var submenu = menu.addItem(label || mxResources.get(name), null, null, parent, null, enabled);
+			this.addMenu(name, menu, submenu);
+		}
 	}
 };
 

File diff suppressed because it is too large
+ 6 - 6
src/main/webapp/js/reader.min.js


File diff suppressed because it is too large
+ 2 - 2
src/main/webapp/js/stencils.min.js


File diff suppressed because it is too large
+ 528 - 529
src/main/webapp/js/viewer.min.js


+ 2 - 1
src/main/webapp/mxgraph/css/common.css

@@ -7,7 +7,8 @@ div.mxRubberband {
 	background: #0077FF;
 }
 .mxCellEditor {
-	background: url('../images/transparent.gif');
+	background: url(data:image/gif;base64,R0lGODlhMAAwAIAAAP///wAAACH5BAEAAAAALAAAAAAwADAAAAIxhI+py+0Po5y02ouz3rz7D4biSJbmiabqyrbuC8fyTNf2jef6zvf+DwwKh8Si8egpAAA7);
+	_background: url('../images/transparent.gif');
 	border-color: transparent;
 	border-style: solid;
 	display: inline-block;

+ 61 - 2
src/main/webapp/plugins/cConf-1-4-8.js

@@ -14,9 +14,14 @@ Draw.loadPlugin(function(ui)
 		{
 			data = JSON.parse(data);
 			
-			if (data.action == 'load' && data.macroData != null)
+			if (data.action == 'load')
 			{
-				macroData = data.macroData;
+				if (data.macroData != null) 
+				{
+					macroData = data.macroData;
+				}
+				
+				macroData.diagramDisplayName = data.title;
 			}
 		}
 		catch (e)
@@ -118,6 +123,60 @@ Draw.loadPlugin(function(ui)
 		ui.menus.addMenuItems(menu, ['linksAuto', 'linksBlank', 'linksSelf'], parent);
 	})));
 
+	var renameAction = ui.actions.get("rename"); 
+
+	renameAction.visible = true;
+	
+	renameAction.isEnabled = function()
+	{
+		return macroData.diagramDisplayName != null;
+	}
+	
+	renameAction.funct = function()
+	{
+		var dlg = new FilenameDialog(ui, macroData.diagramDisplayName || "",
+				mxResources.get('rename'), function(newName)
+		{
+			if (newName != null && newName.length > 0)
+			{
+				macroData.diagramDisplayName = newName;
+				var parent = window.opener || window.parent;
+				parent.postMessage(JSON.stringify({event: 'rename', name: newName}), '*'); 
+				//Update file name in the UI
+				var tmp = document.createElement('span');
+				mxUtils.write(tmp, mxUtils.htmlEntities(newName));
+				
+				if (ui.embedFilenameSpan != null)
+				{
+					ui.embedFilenameSpan.parentNode.removeChild(ui.embedFilenameSpan);
+				}
+
+				ui.buttonContainer.appendChild(tmp);
+				ui.embedFilenameSpan = tmp;
+			}
+		}, mxResources.get('rename'), function(name)
+		{
+			var err = "";
+			if (name == null || name.length == 0)
+			{
+				err = 'Filename too short';
+			}
+			else if (/[&\*+=\\;/{}|\":<>\?~]/g.test(name))
+			{        
+				err = 'Invalid characters \\ / | : { } < > & + ? = ; * " ~';
+			}
+			else
+			{
+				return true;
+			}
+			
+			ui.showError(mxResources.get('error'), err, mxResources.get('ok'));
+			return false;
+		});
+		ui.showDialog(dlg.container, 300, 80, true, true);
+		dlg.init();
+	}
+	
 	// Adds Viewer menu at bottom of Extras menu
 	var menu = ui.menus.get('extras');
 	var oldFunct = menu.funct;

+ 47 - 57
src/main/webapp/stencils/webicons.xml

@@ -3574,13 +3574,14 @@
         <fill/>
         <fillcolor color="#f08707"/>
         <path>
-            <move x="124.2" y="327.5"/>
-            <line x="124.2" y="112.96"/>
-            <line x="384.19" y="112.96"/>
-            <line x="384.19" y="326.48"/>
+            <move x="384.19" y="326.48"/>
             <curve x1="384.19" x2="379.76" x3="376.54" y1="330.6" y2="334.45" y3="334.45"/>
             <line x="131.13" y="334.45"/>
             <curve x1="127.7" x2="124.2" x3="124.2" y1="334.45" y2="330.61" y3="327.5"/>
+            <line x="124.2" y="83.06"/>
+            <curve x1="124.2" x2="126.66" x3="131.77" y1="78.49" y2="74.52" y3="74.52"/>
+            <line x="378.04" y="74.71"/>
+            <curve x1="381.74" x2="384.14" x3="384.19" y1="74.71" y2="78.1" y3="82.51"/>
             <close/>
         </path>
         <fill/>
@@ -3690,60 +3691,49 @@
         <fillcolor color="#db6112"/>
         <path>
             <move x="220.31" y="334.45"/>
-            <line x="180.23" y="294.23"/>
-            <line x="273.23" y="155.67"/>
-            <line x="283.89" y="153.75"/>
-            <line x="384.17" y="256.19"/>
+            <line x="180.23" y="274.23"/>
+            <line x="273.23" y="135.67"/>
+            <line x="283.89" y="133.75"/>
+            <line x="384.17" y="236.19"/>
             <line x="384.17" y="326.74"/>
-            <curve x1="384.17" x2="380.03" x3="376.73" y1="330.02" y2="334.45" y3="334.45"/>
-            <close/>
-        </path>
-        <fill/>
-        <fillcolor color="#333333"/>
-        <path>
-            <move x="124.2" y="112.96"/>
-            <line x="124.2" y="83.06"/>
-            <curve x1="124.2" x2="126.66" x3="131.77" y1="78.49" y2="74.52" y3="74.52"/>
-            <line x="378.04" y="74.71"/>
-            <curve x1="381.74" x2="384.14" x3="384.19" y1="74.71" y2="78.1" y3="82.51"/>
-            <line x="384.19" y="112.96"/>
-            <close/>
-        </path>
-        <fill/>
-        <fillcolor color="#ffffff"/>
-        <path>
-            <move x="184.57" y="294.92"/>
-            <curve x1="178.24" x2="175.27" x3="175.27" y1="294.92" y2="289.74" y3="285.45"/>
-            <line x="175.27" y="251.34"/>
-            <curve x1="175.27" x2="178.4" x3="182.8" y1="247.26" y2="242.15" y3="242.15"/>
-            <line x="209.62" y="242.15"/>
-            <line x="233.53" y="202.5"/>
-            <line x="230.35" y="202.5"/>
-            <curve x1="228.5" x2="222.81" x3="222.81" y1="202.5" y2="198.85" y3="194.88"/>
-            <line x="222.81" y="158.43"/>
-            <curve x1="222.81" x2="227.9" x3="231.72" y1="154.34" y2="149.14" y3="149.14"/>
-            <line x="275.05" y="149.14"/>
-            <curve x1="279" x2="285.41" x3="285.41" y1="149.14" y2="151.33" y3="158.82"/>
-            <line x="285.41" y="193.83"/>
-            <curve x1="285.41" x2="281.72" x3="277.97" y1="197.92" y2="202.5" y3="202.5"/>
-            <line x="274.86" y="202.5"/>
-            <line x="298.84" y="242.15"/>
-            <line x="324.35" y="242.15"/>
-            <curve x1="330.42" x2="333.36" x3="333.36" y1="242.15" y2="245.49" y3="250.42"/>
-            <line x="333.36" y="285.5"/>
-            <curve x1="333.36" x2="328.8" x3="324.27" y1="290.8" y2="294.92" y3="294.92"/>
-            <line x="281.22" y="294.92"/>
-            <curve x1="275.71" x2="270.95" x3="270.95" y1="294.92" y2="291.36" y3="285.92"/>
-            <line x="270.95" y="249.11"/>
-            <curve x1="271.59" x2="275.1" x3="279.24" y1="245.35" y2="242.15" y3="242.15"/>
-            <line x="287.32" y="242.15"/>
-            <line x="264.27" y="202.5"/>
-            <line x="244.42" y="202.5"/>
-            <line x="221.53" y="242.15"/>
-            <line x="230.33" y="242.15"/>
-            <curve x1="234.18" x2="237.52" x3="237.52" y1="242.15" y2="245.93" y3="250.3"/>
-            <line x="237.52" y="287.61"/>
-            <curve x1="237.52" x2="233.95" x3="229.91" y1="290.71" y2="294.92" y3="294.92"/>
+            <curve x1="384.17" x2="380" x3="376.73" y1="330.02" y2="334.87" y3="334.45"/>
+            <close/>
+        </path>
+        <fill/>
+        <fillcolor color="#ffffff"/>
+        <path>
+            <move x="184.57" y="274.92"/>
+            <curve x1="178.24" x2="175.27" x3="175.27" y1="274.92" y2="269.74" y3="265.45"/>
+            <line x="175.27" y="231.34"/>
+            <curve x1="175.27" x2="178.4" x3="182.8" y1="227.26" y2="222.15" y3="222.15"/>
+            <line x="209.62" y="222.15"/>
+            <line x="233.53" y="182.5"/>
+            <line x="230.35" y="182.5"/>
+            <curve x1="228.5" x2="222.81" x3="222.81" y1="182.5" y2="178.85" y3="174.88"/>
+            <line x="222.81" y="138.43"/>
+            <curve x1="222.81" x2="227.9" x3="231.72" y1="134.34" y2="129.14" y3="129.14"/>
+            <line x="275.05" y="129.14"/>
+            <curve x1="279" x2="285.41" x3="285.41" y1="129.14" y2="131.33" y3="138.82"/>
+            <line x="285.41" y="173.83"/>
+            <curve x1="285.41" x2="281.72" x3="277.97" y1="177.92" y2="182.5" y3="182.5"/>
+            <line x="274.86" y="182.5"/>
+            <line x="298.84" y="222.15"/>
+            <line x="324.35" y="222.15"/>
+            <curve x1="330.42" x2="333.36" x3="333.36" y1="222.15" y2="225.49" y3="230.42"/>
+            <line x="333.36" y="265.5"/>
+            <curve x1="333.36" x2="328.8" x3="324.27" y1="270.8" y2="274.92" y3="274.92"/>
+            <line x="281.22" y="274.92"/>
+            <curve x1="275.71" x2="270.95" x3="270.95" y1="274.92" y2="271.36" y3="265.92"/>
+            <line x="270.95" y="229.11"/>
+            <curve x1="271.59" x2="275.1" x3="279.24" y1="225.35" y2="222.15" y3="222.15"/>
+            <line x="287.32" y="222.15"/>
+            <line x="264.27" y="182.5"/>
+            <line x="244.42" y="182.5"/>
+            <line x="221.53" y="222.15"/>
+            <line x="230.33" y="222.15"/>
+            <curve x1="234.18" x2="237.52" x3="237.52" y1="222.15" y2="225.93" y3="230.3"/>
+            <line x="237.52" y="267.61"/>
+            <curve x1="237.52" x2="233.95" x3="229.91" y1="270.71" y2="274.92" y3="274.92"/>
             <close/>
         </path>
         <fill/>

+ 111 - 54
src/main/webapp/stencils/weblogos.xml

@@ -3266,13 +3266,63 @@
         <save/>
         <fillcolor color="#f08707"/>
         <path>
-            <move x="0.79" y="252.98"/>
-            <line x="0.79" y="38.44"/>
-            <line x="260.78" y="38.44"/>
-            <line x="260.78" y="251.96"/>
+            <move x="260.78" y="251.96"/>
             <curve x1="260.78" x2="256.35" x3="253.13" y1="256.08" y2="259.93" y3="259.93"/>
             <line x="7.72" y="259.93"/>
             <curve x1="4.3" x2="0.79" x3="0.79" y1="259.93" y2="256.09" y3="252.98"/>
+            <line x="0.79" y="8.54"/>
+            <curve x1="0.79" x2="3.25" x3="8.36" y1="3.97" y2="0" y3="0"/>
+            <line x="254.64" y="0.19"/>
+            <curve x1="258.33" x2="260.73" x3="260.78" y1="0.19" y2="3.58" y3="7.99"/>
+            <close/>
+        </path>
+        <fill/>
+        <fillcolor color="#db6112"/>
+        <path>
+            <move x="96.9" y="259.93"/>
+            <line x="56.82" y="199.71"/>
+            <line x="149.82" y="61.15"/>
+            <line x="160.49" y="59.23"/>
+            <line x="260.77" y="161.67"/>
+            <line x="260.77" y="252.22"/>
+            <curve x1="260.77" x2="256.6" x3="253.33" y1="255.5" y2="260.35" y3="259.93"/>
+            <close/>
+        </path>
+        <fill/>
+        <fillcolor color="#ffffff"/>
+        <path>
+            <move x="61.16" y="200.4"/>
+            <curve x1="54.84" x2="51.86" x3="51.86" y1="200.4" y2="195.22" y3="190.93"/>
+            <line x="51.86" y="156.82"/>
+            <curve x1="51.86" x2="54.99" x3="59.39" y1="152.73" y2="147.63" y3="147.63"/>
+            <line x="86.22" y="147.63"/>
+            <line x="110.12" y="107.98"/>
+            <line x="106.94" y="107.98"/>
+            <curve x1="105.09" x2="99.4" x3="99.4" y1="107.98" y2="104.32" y3="100.36"/>
+            <line x="99.4" y="63.91"/>
+            <curve x1="99.4" x2="104.49" x3="108.32" y1="59.82" y2="54.62" y3="54.62"/>
+            <line x="151.65" y="54.62"/>
+            <curve x1="155.59" x2="162.01" x3="162.01" y1="54.62" y2="56.81" y3="64.3"/>
+            <line x="162.01" y="99.31"/>
+            <curve x1="162.01" x2="158.31" x3="154.56" y1="103.4" y2="107.98" y3="107.98"/>
+            <line x="151.46" y="107.98"/>
+            <line x="175.43" y="147.63"/>
+            <line x="200.95" y="147.63"/>
+            <curve x1="207.01" x2="209.95" x3="209.95" y1="147.63" y2="150.97" y3="155.9"/>
+            <line x="209.95" y="190.98"/>
+            <curve x1="209.95" x2="205.4" x3="200.87" y1="196.28" y2="200.4" y3="200.4"/>
+            <line x="157.82" y="200.4"/>
+            <curve x1="152.3" x2="147.55" x3="147.55" y1="200.4" y2="196.84" y3="191.4"/>
+            <line x="147.55" y="154.59"/>
+            <curve x1="148.18" x2="151.69" x3="155.83" y1="150.83" y2="147.63" y3="147.63"/>
+            <line x="163.91" y="147.63"/>
+            <line x="140.87" y="107.98"/>
+            <line x="121.02" y="107.98"/>
+            <line x="98.13" y="147.63"/>
+            <line x="106.92" y="147.63"/>
+            <curve x1="110.78" x2="114.11" x3="114.11" y1="147.63" y2="151.41" y3="155.78"/>
+            <line x="114.11" y="193.09"/>
+            <curve x1="114.11" x2="110.55" x3="106.51" y1="196.19" y2="200.4" y3="200.4"/>
             <close/>
         </path>
         <fill/>
@@ -3373,71 +3423,78 @@
             <line x="213.14" y="312.97"/>
             <line x="213.14" y="352.9"/>
             <close/>
-            <move x="200.97" y="302.12"/>
+            <move x="200.97" y="302.13"/>
             <curve x1="200.97" x2="204.21" x3="207.19" y1="298.87" y2="296" y3="296"/>
-            <curve x1="211.29" x2="213.2" x3="213.2" y1="296" y2="299.05" y3="302.12"/>
+            <curve x1="211.29" x2="213.2" x3="213.2" y1="296" y2="299.05" y3="302.13"/>
             <curve x1="213.2" x2="210.66" x3="207.3" y1="305.86" y2="308" y3="308"/>
-            <curve x1="203.92" x2="200.97" x3="200.97" y1="308" y2="304.94" y3="302.12"/>
+            <curve x1="203.92" x2="200.97" x3="200.97" y1="308" y2="304.94" y3="302.13"/>
             <close/>
         </path>
         <fill/>
-        <fillcolor color="#db6112"/>
+    </foreground>
+</shape>
+<shape aspect="variable" h="260.35" name="Drawio3" strokewidth="inherit" w="259.99">
+    <connections/>
+    <foreground>
+        <fillcolor color="#f08707"/>
         <path>
-            <move x="96.9" y="259.93"/>
-            <line x="56.82" y="219.71"/>
-            <line x="149.82" y="81.15"/>
-            <line x="160.49" y="79.23"/>
-            <line x="260.77" y="181.67"/>
-            <line x="260.77" y="252.22"/>
-            <curve x1="260.77" x2="256.62" x3="253.33" y1="255.5" y2="259.93" y3="259.93"/>
+            <move x="259.99" y="251.96"/>
+            <curve x1="259.99" x2="255.56" x3="252.34" y1="256.08" y2="259.93" y3="259.93"/>
+            <line x="6.93" y="259.93"/>
+            <curve x1="3.51" x2="0" x3="0" y1="259.93" y2="256.09" y3="252.98"/>
+            <line x="0" y="8.54"/>
+            <curve x1="0" x2="2.46" x3="7.57" y1="3.97" y2="0" y3="0"/>
+            <line x="253.85" y="0.19"/>
+            <curve x1="257.54" x2="259.94" x3="259.99" y1="0.19" y2="3.58" y3="7.99"/>
             <close/>
         </path>
         <fill/>
-        <fillcolor color="#333333"/>
+        <fillcolor color="#db6112"/>
         <path>
-            <move x="0.79" y="38.44"/>
-            <line x="0.79" y="8.54"/>
-            <curve x1="0.79" x2="3.25" x3="8.36" y1="3.97" y2="0" y3="0"/>
-            <line x="254.64" y="0.19"/>
-            <curve x1="258.33" x2="260.73" x3="260.78" y1="0.19" y2="3.58" y3="7.99"/>
-            <line x="260.78" y="38.44"/>
+            <move x="96.11" y="259.93"/>
+            <line x="56.03" y="199.71"/>
+            <line x="149.03" y="61.15"/>
+            <line x="159.7" y="59.23"/>
+            <line x="259.98" y="161.67"/>
+            <line x="259.98" y="252.22"/>
+            <curve x1="259.98" x2="255.81" x3="252.53" y1="255.5" y2="260.35" y3="259.93"/>
             <close/>
         </path>
         <fill/>
         <fillcolor color="#ffffff"/>
         <path>
-            <move x="61.16" y="220.4"/>
-            <curve x1="54.84" x2="51.86" x3="51.86" y1="220.4" y2="215.22" y3="210.93"/>
-            <line x="51.86" y="176.82"/>
-            <curve x1="51.86" x2="54.99" x3="59.39" y1="172.73" y2="167.63" y3="167.63"/>
-            <line x="86.22" y="167.63"/>
-            <line x="110.12" y="127.98"/>
-            <line x="106.94" y="127.98"/>
-            <curve x1="105.09" x2="99.4" x3="99.4" y1="127.98" y2="124.32" y3="120.36"/>
-            <line x="99.4" y="83.91"/>
-            <curve x1="99.4" x2="104.49" x3="108.32" y1="79.82" y2="74.62" y3="74.62"/>
-            <line x="151.65" y="74.62"/>
-            <curve x1="155.59" x2="162.01" x3="162.01" y1="74.62" y2="76.81" y3="84.3"/>
-            <line x="162.01" y="119.31"/>
-            <curve x1="162.01" x2="158.31" x3="154.56" y1="123.4" y2="127.98" y3="127.98"/>
-            <line x="151.46" y="127.98"/>
-            <line x="175.43" y="167.63"/>
-            <line x="200.95" y="167.63"/>
-            <curve x1="207.01" x2="209.95" x3="209.95" y1="167.63" y2="170.97" y3="175.9"/>
-            <line x="209.95" y="210.98"/>
-            <curve x1="209.95" x2="205.4" x3="200.87" y1="216.28" y2="220.4" y3="220.4"/>
-            <line x="157.82" y="220.4"/>
-            <curve x1="152.3" x2="147.55" x3="147.55" y1="220.4" y2="216.84" y3="211.4"/>
-            <line x="147.55" y="174.59"/>
-            <curve x1="148.18" x2="151.69" x3="155.83" y1="170.83" y2="167.63" y3="167.63"/>
-            <line x="163.91" y="167.63"/>
-            <line x="140.87" y="127.98"/>
-            <line x="121.02" y="127.98"/>
-            <line x="98.13" y="167.63"/>
-            <line x="106.92" y="167.63"/>
-            <curve x1="110.78" x2="114.11" x3="114.11" y1="167.63" y2="171.41" y3="175.78"/>
-            <line x="114.11" y="213.09"/>
-            <curve x1="114.11" x2="110.55" x3="106.51" y1="216.19" y2="220.4" y3="220.4"/>
+            <move x="60.37" y="200.4"/>
+            <curve x1="54.05" x2="51.07" x3="51.07" y1="200.4" y2="195.22" y3="190.93"/>
+            <line x="51.07" y="156.82"/>
+            <curve x1="51.07" x2="54.2" x3="58.6" y1="152.73" y2="147.63" y3="147.63"/>
+            <line x="85.43" y="147.63"/>
+            <line x="109.33" y="107.98"/>
+            <line x="106.15" y="107.98"/>
+            <curve x1="104.3" x2="98.61" x3="98.61" y1="107.98" y2="104.32" y3="100.36"/>
+            <line x="98.61" y="63.91"/>
+            <curve x1="98.61" x2="103.7" x3="107.53" y1="59.82" y2="54.62" y3="54.62"/>
+            <line x="150.86" y="54.62"/>
+            <curve x1="154.8" x2="161.22" x3="161.22" y1="54.62" y2="56.81" y3="64.3"/>
+            <line x="161.22" y="99.31"/>
+            <curve x1="161.22" x2="157.52" x3="153.77" y1="103.4" y2="107.98" y3="107.98"/>
+            <line x="150.67" y="107.98"/>
+            <line x="174.64" y="147.63"/>
+            <line x="200.16" y="147.63"/>
+            <curve x1="206.22" x2="209.16" x3="209.16" y1="147.63" y2="150.97" y3="155.9"/>
+            <line x="209.16" y="190.98"/>
+            <curve x1="209.16" x2="204.61" x3="200.07" y1="196.28" y2="200.4" y3="200.4"/>
+            <line x="157.03" y="200.4"/>
+            <curve x1="151.51" x2="146.75" x3="146.75" y1="200.4" y2="196.84" y3="191.4"/>
+            <line x="146.75" y="154.59"/>
+            <curve x1="147.39" x2="150.9" x3="155.04" y1="150.83" y2="147.63" y3="147.63"/>
+            <line x="163.12" y="147.63"/>
+            <line x="140.08" y="107.98"/>
+            <line x="120.23" y="107.98"/>
+            <line x="97.34" y="147.63"/>
+            <line x="106.13" y="147.63"/>
+            <curve x1="109.98" x2="113.32" x3="113.32" y1="147.63" y2="151.41" y3="155.78"/>
+            <line x="113.32" y="193.09"/>
+            <curve x1="113.32" x2="109.76" x3="105.72" y1="196.19" y2="200.4" y3="200.4"/>
             <close/>
         </path>
         <fill/>