From d1ac435abadbb993aaf7d721315ce0cd5fa80b68 Mon Sep 17 00:00:00 2001 From: gigamaster <1905497+gigamaster@users.noreply.github.com> Date: Wed, 24 Jul 2024 07:57:25 +0200 Subject: [PATCH] cloud --- .../drawio/mxgraph/src/shape/mxActor.js | 86 + .../drawio/mxgraph/src/shape/mxArrow.js | 115 + .../mxgraph/src/shape/mxArrowConnector.js | 488 + .../drawio/mxgraph/src/shape/mxCloud.js | 55 + .../drawio/mxgraph/src/shape/mxConnector.js | 145 + .../drawio/mxgraph/src/shape/mxCylinder.js | 111 + .../mxgraph/src/shape/mxDoubleEllipse.js | 107 + .../drawio/mxgraph/src/shape/mxEllipse.js | 48 + .../drawio/mxgraph/src/shape/mxHexagon.js | 34 + .../drawio/mxgraph/src/shape/mxImageShape.js | 258 + .../drawio/mxgraph/src/shape/mxLabel.js | 277 + .../drawio/mxgraph/src/shape/mxLine.js | 69 + .../drawio/mxgraph/src/shape/mxMarker.js | 293 + .../drawio/mxgraph/src/shape/mxPolyline.js | 132 + .../mxgraph/src/shape/mxRectangleShape.js | 111 + .../drawio/mxgraph/src/shape/mxRhombus.js | 64 + .../drawio/mxgraph/src/shape/mxShape.js | 1790 + .../drawio/mxgraph/src/shape/mxStencil.js | 887 + .../mxgraph/src/shape/mxStencilRegistry.js | 53 + .../drawio/mxgraph/src/shape/mxSwimlane.js | 620 + .../drawio/mxgraph/src/shape/mxText.js | 1463 + .../drawio/mxgraph/src/shape/mxTriangle.js | 43 + .../mxgraph/src/util/mxAbstractCanvas2D.js | 671 + .../drawio/mxgraph/src/util/mxAnimation.js | 92 + .../mxgraph/src/util/mxAutoSaveManager.js | 213 + .../drawio/mxgraph/src/util/mxClipboard.js | 223 + .../drawio/mxgraph/src/util/mxConstants.js | 2489 + .../drawio/mxgraph/src/util/mxDictionary.js | 147 + .../drawio/mxgraph/src/util/mxDivResizer.js | 151 + .../drawio/mxgraph/src/util/mxDragSource.js | 726 + .../drawio/mxgraph/src/util/mxEffects.js | 211 + .../drawio/mxgraph/src/util/mxEvent.js | 1501 + .../drawio/mxgraph/src/util/mxEventObject.js | 111 + .../drawio/mxgraph/src/util/mxEventSource.js | 189 + .../drawio/mxgraph/src/util/mxForm.js | 202 + .../drawio/mxgraph/src/util/mxGuide.js | 446 + .../drawio/mxgraph/src/util/mxImage.js | 57 + .../drawio/mxgraph/src/util/mxImageBundle.js | 103 + .../drawio/mxgraph/src/util/mxImageExport.js | 228 + .../drawio/mxgraph/src/util/mxLog.js | 414 + .../drawio/mxgraph/src/util/mxMorphing.js | 249 + .../drawio/mxgraph/src/util/mxMouseEvent.js | 245 + .../mxgraph/src/util/mxObjectIdentity.js | 72 + .../mxgraph/src/util/mxPanningManager.js | 265 + .../drawio/mxgraph/src/util/mxPoint.js | 54 + .../drawio/mxgraph/src/util/mxPopupMenu.js | 626 + .../drawio/mxgraph/src/util/mxRectangle.js | 191 + .../drawio/mxgraph/src/util/mxResources.js | 450 + .../drawio/mxgraph/src/util/mxSvgCanvas2D.js | 2657 + .../drawio/mxgraph/src/util/mxToolbar.js | 527 + .../drawio/mxgraph/src/util/mxUndoManager.js | 229 + .../drawio/mxgraph/src/util/mxUndoableEdit.js | 213 + .../drawio/mxgraph/src/util/mxUrlConverter.js | 153 + .../drawio/mxgraph/src/util/mxUtils.js | 4839 + .../drawio/mxgraph/src/util/mxWindow.js | 1115 + .../drawio/mxgraph/src/util/mxXmlCanvas2D.js | 1216 + .../drawio/mxgraph/src/util/mxXmlRequest.js | 475 + .../drawio/mxgraph/src/view/mxCellEditor.js | 1076 + .../drawio/mxgraph/src/view/mxCellOverlay.js | 233 + .../drawio/mxgraph/src/view/mxCellRenderer.js | 1663 + .../drawio/mxgraph/src/view/mxCellState.js | 473 + .../mxgraph/src/view/mxCellStatePreview.js | 203 + .../src/view/mxConnectionConstraint.js | 67 + .../drawio/mxgraph/src/view/mxEdgeStyle.js | 1672 + .../drawio/mxgraph/src/view/mxGraph.js | 13573 ++ .../mxgraph/src/view/mxGraphSelectionModel.js | 436 + .../drawio/mxgraph/src/view/mxGraphView.js | 2978 + .../mxgraph/src/view/mxLayoutManager.js | 506 + .../drawio/mxgraph/src/view/mxMultiplicity.js | 257 + .../drawio/mxgraph/src/view/mxOutline.js | 525 + .../drawio/mxgraph/src/view/mxPerimeter.js | 921 + .../drawio/mxgraph/src/view/mxPrintPreview.js | 1248 + .../mxgraph/src/view/mxStyleRegistry.js | 71 + .../drawio/mxgraph/src/view/mxStylesheet.js | 266 + .../mxgraph/src/view/mxSwimlaneManager.js | 450 + .../mxgraph/src/view/mxTemporaryCellStates.js | 134 + app/web-tools/drawio/onedrive3.html | 58 + app/web-tools/drawio/open.html | 33 + app/web-tools/drawio/plugins/animation.js | 421 + app/web-tools/drawio/plugins/anonymize.js | 96 + .../drawio/plugins/edgeConnection.js | 52 + app/web-tools/drawio/plugins/explore.js | 41 + app/web-tools/drawio/plugins/flow.js | 108 + app/web-tools/drawio/plugins/googledrive.js | 17 + app/web-tools/drawio/plugins/import.js | 210 + app/web-tools/drawio/plugins/nextcloud.js | 577 + app/web-tools/drawio/plugins/number.js | 130 + app/web-tools/drawio/plugins/page.js | 152 + app/web-tools/drawio/plugins/props.js | 182 + app/web-tools/drawio/plugins/rackF5.js | 1675 + app/web-tools/drawio/plugins/random.js | 502 + app/web-tools/drawio/plugins/replay.js | 296 + app/web-tools/drawio/plugins/sql.js | 656 + app/web-tools/drawio/plugins/svgdata.js | 55 + app/web-tools/drawio/plugins/tags.js | 369 + app/web-tools/drawio/plugins/text.js | 31 + app/web-tools/drawio/plugins/tooltips.js | 45 + .../drawio/plugins/trees/handle-move.gif | Bin 0 -> 2287 bytes app/web-tools/drawio/plugins/trees/trees.js | 1449 + app/web-tools/drawio/plugins/trello.js | 99 + app/web-tools/drawio/plugins/update.js | 304 + .../drawio/plugins/webcola/cola.min.js | 3 + .../plugins/webcola/mxWebColaAdaptor.js | 908 + .../drawio/plugins/webcola/mxWebColaLayout.js | 410 + .../drawio/plugins/webcola/webcola.js | 40 + app/web-tools/drawio/resources/README.md | 5 + app/web-tools/drawio/resources/dia.txt | 1291 + app/web-tools/drawio/resources/dia_am.txt | 1291 + app/web-tools/drawio/resources/dia_ar.txt | 1291 + app/web-tools/drawio/resources/dia_bg.txt | 1291 + app/web-tools/drawio/resources/dia_bn.txt | 1291 + app/web-tools/drawio/resources/dia_bs.txt | 1291 + app/web-tools/drawio/resources/dia_ca.txt | 1291 + app/web-tools/drawio/resources/dia_cs.txt | 1291 + app/web-tools/drawio/resources/dia_da.txt | 1291 + app/web-tools/drawio/resources/dia_de.txt | 1291 + app/web-tools/drawio/resources/dia_el.txt | 1291 + app/web-tools/drawio/resources/dia_eo.txt | 1291 + app/web-tools/drawio/resources/dia_es.txt | 1291 + app/web-tools/drawio/resources/dia_et.txt | 1291 + app/web-tools/drawio/resources/dia_eu.txt | 1291 + app/web-tools/drawio/resources/dia_fa.txt | 1291 + app/web-tools/drawio/resources/dia_fi.txt | 1291 + app/web-tools/drawio/resources/dia_fil.txt | 1291 + app/web-tools/drawio/resources/dia_fr.txt | 1291 + app/web-tools/drawio/resources/dia_gl.txt | 1291 + app/web-tools/drawio/resources/dia_gu.txt | 1291 + app/web-tools/drawio/resources/dia_he.txt | 1291 + app/web-tools/drawio/resources/dia_hi.txt | 1291 + app/web-tools/drawio/resources/dia_hr.txt | 1291 + app/web-tools/drawio/resources/dia_hu.txt | 1291 + app/web-tools/drawio/resources/dia_i18n.txt | 1291 + app/web-tools/drawio/resources/dia_id.txt | 1291 + app/web-tools/drawio/resources/dia_it.txt | 1291 + app/web-tools/drawio/resources/dia_ja.txt | 1291 + app/web-tools/drawio/resources/dia_kn.txt | 1291 + app/web-tools/drawio/resources/dia_ko.txt | 1291 + app/web-tools/drawio/resources/dia_lt.txt | 1291 + app/web-tools/drawio/resources/dia_lv.txt | 1291 + app/web-tools/drawio/resources/dia_ml.txt | 1291 + app/web-tools/drawio/resources/dia_mr.txt | 1291 + app/web-tools/drawio/resources/dia_ms.txt | 1291 + app/web-tools/drawio/resources/dia_my.txt | 1291 + app/web-tools/drawio/resources/dia_nl.txt | 1291 + app/web-tools/drawio/resources/dia_no.txt | 1291 + app/web-tools/drawio/resources/dia_pl.txt | 1291 + app/web-tools/drawio/resources/dia_pt-br.txt | 1291 + app/web-tools/drawio/resources/dia_pt.txt | 1291 + app/web-tools/drawio/resources/dia_ro.txt | 1291 + app/web-tools/drawio/resources/dia_ru.txt | 1291 + app/web-tools/drawio/resources/dia_si.txt | 1291 + app/web-tools/drawio/resources/dia_sk.txt | 1291 + app/web-tools/drawio/resources/dia_sl.txt | 1291 + app/web-tools/drawio/resources/dia_sr.txt | 1291 + app/web-tools/drawio/resources/dia_sv.txt | 1291 + app/web-tools/drawio/resources/dia_sw.txt | 1291 + app/web-tools/drawio/resources/dia_ta.txt | 1291 + app/web-tools/drawio/resources/dia_te.txt | 1291 + app/web-tools/drawio/resources/dia_th.txt | 1291 + app/web-tools/drawio/resources/dia_tr.txt | 1291 + app/web-tools/drawio/resources/dia_uk.txt | 1291 + app/web-tools/drawio/resources/dia_vi.txt | 1291 + app/web-tools/drawio/resources/dia_zh-tw.txt | 1291 + app/web-tools/drawio/resources/dia_zh.txt | 1291 + app/web-tools/drawio/service-worker.js | 2 + .../drawio/shapes/bpmn/mxBpmnShape2.js | 2066 + app/web-tools/drawio/shapes/emoji/mxEmoji.js | 1968 + app/web-tools/drawio/shapes/er/mxER.js | 1498 + app/web-tools/drawio/shapes/ios7/mxIOS7Ui.js | 1719 + .../drawio/shapes/mockup/mxMockupButtons.js | 1028 + .../shapes/mockup/mxMockupContainers.js | 2119 + .../drawio/shapes/mockup/mxMockupForms.js | 2503 + .../drawio/shapes/mockup/mxMockupGraphics.js | 1235 + .../drawio/shapes/mockup/mxMockupMarkup.js | 200 + .../drawio/shapes/mockup/mxMockupMisc.js | 1680 + .../shapes/mockup/mxMockupNavigation.js | 845 + .../drawio/shapes/mockup/mxMockupText.js | 932 + .../drawio/shapes/mockup/mxMockupiOS.js | 6694 + app/web-tools/drawio/shapes/mxAWS3D.js | 9438 ++ app/web-tools/drawio/shapes/mxAWS4.js | 427 + app/web-tools/drawio/shapes/mxAndroid.js | 1510 + app/web-tools/drawio/shapes/mxArchiMate.js | 1220 + app/web-tools/drawio/shapes/mxArchiMate3.js | 4354 + app/web-tools/drawio/shapes/mxArrows.js | 2883 + app/web-tools/drawio/shapes/mxAtlassian.js | 291 + app/web-tools/drawio/shapes/mxBasic.js | 3500 + app/web-tools/drawio/shapes/mxBootstrap.js | 1503 + app/web-tools/drawio/shapes/mxC4.js | 367 + app/web-tools/drawio/shapes/mxCabinets.js | 257 + app/web-tools/drawio/shapes/mxCisco19.js | 149 + app/web-tools/drawio/shapes/mxCiscoSafe.js | 177 + app/web-tools/drawio/shapes/mxDFD.js | 447 + app/web-tools/drawio/shapes/mxEip.js | 570 + app/web-tools/drawio/shapes/mxElectrical.js | 5687 + app/web-tools/drawio/shapes/mxFloorplan.js | 1780 + app/web-tools/drawio/shapes/mxFlowchart.js | 86 + app/web-tools/drawio/shapes/mxGCP2.js | 370 + app/web-tools/drawio/shapes/mxGmdl.js | 967 + app/web-tools/drawio/shapes/mxIBM.js | 100 + app/web-tools/drawio/shapes/mxInfographic.js | 2668 + app/web-tools/drawio/shapes/mxKubernetes.js | 586 + app/web-tools/drawio/shapes/mxLeanMap.js | 2229 + app/web-tools/drawio/shapes/mxNetworks.js | 120 + app/web-tools/drawio/shapes/mxSAP.js | 74 + app/web-tools/drawio/shapes/mxSysML.js | 3269 + app/web-tools/drawio/shapes/mxUML25.js | 261 + .../drawio/shapes/pid2/mxPidInstruments.js | 685 + app/web-tools/drawio/shapes/pid2/mxPidMisc.js | 498 + .../drawio/shapes/pid2/mxPidValves.js | 1149 + app/web-tools/drawio/shapes/rack/mxRack.js | 1585 + app/web-tools/drawio/shortcuts.svg | 4 + app/web-tools/drawio/stencils/LICENSE | 95 + .../drawio/stencils/android/android.xml | 1905 + app/web-tools/drawio/stencils/arrows.xml | 846 + app/web-tools/drawio/stencils/atlassian.xml | 713 + app/web-tools/drawio/stencils/aws/compute.xml | 720 + .../drawio/stencils/aws/content_delivery.xml | 445 + .../drawio/stencils/aws/database.xml | 1358 + .../stencils/aws/deployment_management.xml | 306 + app/web-tools/drawio/stencils/aws/groups.xml | 1798 + .../drawio/stencils/aws/messaging.xml | 670 + app/web-tools/drawio/stencils/aws/misc.xml | 274 + .../drawio/stencils/aws/networking.xml | 872 + .../stencils/aws/non_service_specific.xml | 734 + .../stencils/aws/on_demand_workforce.xml | 422 + app/web-tools/drawio/stencils/aws/storage.xml | 376 + .../aws2/administration_and_security.xml | 358 + .../drawio/stencils/aws2/analytics.xml | 1318 + .../drawio/stencils/aws2/app_services.xml | 2362 + .../stencils/aws2/compute_and_networking.xml | 6215 + .../drawio/stencils/aws2/database.xml | 6832 + .../aws2/deployment_and_management.xml | 2785 + .../drawio/stencils/aws2/developer_tools.xml | 294 + .../stencils/aws2/enterprise_applications.xml | 235 + .../drawio/stencils/aws2/game_development.xml | 126 + .../stencils/aws2/internet_of_things.xml | 4799 + .../drawio/stencils/aws2/management_tools.xml | 208 + .../drawio/stencils/aws2/mobile_services.xml | 1141 + .../drawio/stencils/aws2/networking.xml | 277 + .../stencils/aws2/non-service_specific.xml | 2641 + .../stencils/aws2/on-demand_workforce.xml | 886 + app/web-tools/drawio/stencils/aws2/sdks.xml | 1351 + .../stencils/aws2/security_and_identity.xml | 715 + .../aws2/storage_and_content_delivery.xml | 2780 + app/web-tools/drawio/stencils/aws3.xml | 34201 +++++ app/web-tools/drawio/stencils/aws3d.xml | 625 + app/web-tools/drawio/stencils/aws4.xml | 116413 +++++++++++++++ app/web-tools/drawio/stencils/azure.xml | 5541 + app/web-tools/drawio/stencils/basic.xml | 1027 + app/web-tools/drawio/stencils/bootstrap.xml | 123 + app/web-tools/drawio/stencils/bpmn.xml | 1162 + app/web-tools/drawio/stencils/cabinets.xml | 2359 + .../drawio/stencils/cisco/buildings.xml | 1449 + .../cisco/computers_and_peripherals.xml | 2438 + .../cisco/controllers_and_modules.xml | 1207 + .../drawio/stencils/cisco/directors.xml | 533 + .../stencils/cisco/hubs_and_gateways.xml | 812 + app/web-tools/drawio/stencils/cisco/misc.xml | 15882 ++ .../stencils/cisco/modems_and_phones.xml | 1871 + .../drawio/stencils/cisco/people.xml | 2192 + .../drawio/stencils/cisco/routers.xml | 3145 + .../drawio/stencils/cisco/security.xml | 942 + .../drawio/stencils/cisco/servers.xml | 1634 + .../drawio/stencils/cisco/storage.xml | 1648 + .../drawio/stencils/cisco/switches.xml | 3320 + .../drawio/stencils/cisco/wireless.xml | 1135 + app/web-tools/drawio/stencils/cisco19.xml | 25930 ++++ .../stencils/cisco_safe/architecture.xml | 9672 ++ .../stencils/cisco_safe/business_icons.xml | 1947 + .../drawio/stencils/cisco_safe/capability.xml | 12634 ++ .../drawio/stencils/cisco_safe/design.xml | 17309 +++ .../stencils/cisco_safe/iot_things_icons.xml | 3592 + .../cisco_safe/people_places_things_icons.xml | 897 + .../stencils/cisco_safe/security_icons.xml | 9089 ++ .../stencils/cisco_safe/technology_icons.xml | 2231 + .../drawio/stencils/cisco_safe/threat.xml | 9524 ++ app/web-tools/drawio/stencils/citrix.xml | 20213 +++ .../drawio/stencils/clipart/Gear_128x128.png | Bin 0 -> 10678 bytes app/web-tools/drawio/stencils/eip.xml | 2003 + .../drawio/stencils/electrical/abstract.xml | 667 + .../drawio/stencils/electrical/capacitors.xml | 439 + .../drawio/stencils/electrical/diodes.xml | 352 + .../electrical/electro-mechanical.xml | 1816 + .../drawio/stencils/electrical/iec417.xml | 1143 + .../stencils/electrical/iec_logic_gates.xml | 240 + .../drawio/stencils/electrical/inductors.xml | 993 + .../stencils/electrical/instruments.xml | 146 + .../stencils/electrical/logic_gates.xml | 829 + .../stencils/electrical/miscellaneous.xml | 1792 + .../drawio/stencils/electrical/mosfets1.xml | 821 + .../drawio/stencils/electrical/mosfets2.xml | 560 + .../drawio/stencils/electrical/op_amps.xml | 438 + .../stencils/electrical/opto_electronics.xml | 654 + .../drawio/stencils/electrical/plc_ladder.xml | 122 + .../electrical/power_semiconductors.xml | 743 + .../drawio/stencils/electrical/radio.xml | 268 + .../drawio/stencils/electrical/resistors.xml | 618 + .../drawio/stencils/electrical/rot_mech.xml | 367 + .../stencils/electrical/signal_sources.xml | 413 + .../electrical/thermionic_devices.xml | 295 + .../stencils/electrical/transistors.xml | 1103 + .../stencils/electrical/transmission.xml | 335 + .../drawio/stencils/electrical/waveforms.xml | 361 + app/web-tools/drawio/stencils/floorplan.xml | 1910 + app/web-tools/drawio/stencils/flowchart.xml | 921 + app/web-tools/drawio/stencils/fluid_power.xml | 18349 +++ .../drawio/stencils/gcp/big_data.xml | 777 + app/web-tools/drawio/stencils/gcp/compute.xml | 708 + .../drawio/stencils/gcp/developer_tools.xml | 289 + app/web-tools/drawio/stencils/gcp/extras.xml | 748 + .../stencils/gcp/identity_and_security.xml | 681 + .../drawio/stencils/gcp/machine_learning.xml | 632 + .../drawio/stencils/gcp/management_tools.xml | 761 + .../drawio/stencils/gcp/networking.xml | 951 + .../drawio/stencils/gcp/product_cards.xml | 106 + .../drawio/stencils/gcp/storage_databases.xml | 593 + app/web-tools/drawio/stencils/gcp2.xml | 23206 +++ app/web-tools/drawio/stencils/gmdl.xml | 2952 + app/web-tools/drawio/stencils/ibm.xml | 578 + app/web-tools/drawio/stencils/ios7/icons.xml | 2481 + app/web-tools/drawio/stencils/ios7/misc.xml | 2184 + app/web-tools/drawio/stencils/kubernetes.xml | 3850 + app/web-tools/drawio/stencils/kubernetes2.xml | 3817 + .../drawio/stencils/lean_mapping.xml | 462 + .../drawio/stencils/mockup/advertising.xml | 223 + .../drawio/stencils/mockup/calendars.xml | 1595 + .../drawio/stencils/mockup/carousel.xml | 599 + .../stencils/mockup/charts_and_tables.xml | 626 + .../drawio/stencils/mockup/controls.xml | 648 + .../drawio/stencils/mockup/form_elements.xml | 433 + .../stencils/mockup/menus_and_buttons.xml | 848 + app/web-tools/drawio/stencils/mockup/misc.xml | 2183 + app/web-tools/drawio/stencils/mockup/tabs.xml | 193 + app/web-tools/drawio/stencils/mscae/cloud.xml | 10257 ++ .../drawio/stencils/mscae/deprecated.xml | 946 + .../drawio/stencils/mscae/enterprise.xml | 5289 + .../drawio/stencils/mscae/general.xml | 1412 + .../drawio/stencils/mscae/general_symbols.xml | 587 + .../drawio/stencils/mscae/intune.xml | 3517 + app/web-tools/drawio/stencils/mscae/oms.xml | 1458 + .../drawio/stencils/mscae/opsmanager.xml | 2900 + app/web-tools/drawio/stencils/mscae/other.xml | 1292 + .../drawio/stencils/mscae/system_center.xml | 675 + app/web-tools/drawio/stencils/mscae/vm.xml | 1949 + app/web-tools/drawio/stencils/networks.xml | 4976 + .../drawio/stencils/office/clouds.xml | 847 + .../drawio/stencils/office/communications.xml | 7570 + .../drawio/stencils/office/concepts.xml | 6700 + .../drawio/stencils/office/databases.xml | 1748 + .../drawio/stencils/office/devices.xml | 3171 + .../drawio/stencils/office/security.xml | 2258 + .../drawio/stencils/office/servers.xml | 8510 ++ .../drawio/stencils/office/services.xml | 3232 + .../drawio/stencils/office/sites.xml | 1731 + .../drawio/stencils/office/users.xml | 2307 + .../drawio/stencils/pid/agitators.xml | 190 + .../stencils/pid/apparatus_elements.xml | 94 + .../drawio/stencils/pid/centrifuges.xml | 240 + .../drawio/stencils/pid/compressors.xml | 373 + .../drawio/stencils/pid/compressors_iso.xml | 283 + .../drawio/stencils/pid/crushers_grinding.xml | 431 + app/web-tools/drawio/stencils/pid/driers.xml | 235 + app/web-tools/drawio/stencils/pid/engines.xml | 142 + app/web-tools/drawio/stencils/pid/feeders.xml | 105 + app/web-tools/drawio/stencils/pid/filters.xml | 429 + .../drawio/stencils/pid/fittings.xml | 770 + .../drawio/stencils/pid/flow_sensors.xml | 328 + .../drawio/stencils/pid/heat_exchangers.xml | 809 + .../drawio/stencils/pid/instruments.xml | 571 + app/web-tools/drawio/stencils/pid/misc.xml | 2320 + app/web-tools/drawio/stencils/pid/mixers.xml | 97 + app/web-tools/drawio/stencils/pid/piping.xml | 882 + app/web-tools/drawio/stencils/pid/pumps.xml | 600 + .../drawio/stencils/pid/pumps_din.xml | 221 + .../drawio/stencils/pid/pumps_iso.xml | 199 + .../drawio/stencils/pid/separators.xml | 594 + .../drawio/stencils/pid/shaping_machines.xml | 188 + app/web-tools/drawio/stencils/pid/valves.xml | 846 + app/web-tools/drawio/stencils/pid/vessels.xml | 1847 + app/web-tools/drawio/stencils/rack/apc.xml | 277 + app/web-tools/drawio/stencils/rack/cisco.xml | 16373 ++ app/web-tools/drawio/stencils/rack/dell.xml | 5617 + app/web-tools/drawio/stencils/rack/f5.xml | 7923 + .../drawio/stencils/rack/general.xml | 3477 + app/web-tools/drawio/stencils/rack/hp.xml | 2057 + .../rack/hpe_aruba/gateways_controllers.xml | 7238 + .../stencils/rack/hpe_aruba/security.xml | 2184 + .../stencils/rack/hpe_aruba/switches.xml | 88731 +++++++++++ app/web-tools/drawio/stencils/rack/ibm.xml | 2657 + app/web-tools/drawio/stencils/rack/oracle.xml | 5140 + app/web-tools/drawio/stencils/salesforce.xml | 8360 ++ .../drawio/stencils/signs/animals.xml | 1515 + app/web-tools/drawio/stencils/signs/food.xml | 615 + .../drawio/stencils/signs/healthcare.xml | 5753 + .../drawio/stencils/signs/nature.xml | 1049 + .../drawio/stencils/signs/people.xml | 1603 + .../drawio/stencils/signs/safety.xml | 1644 + .../drawio/stencils/signs/science.xml | 434 + .../drawio/stencils/signs/sports.xml | 6035 + app/web-tools/drawio/stencils/signs/tech.xml | 1295 + .../drawio/stencils/signs/transportation.xml | 6297 + .../drawio/stencils/signs/travel.xml | 3450 + app/web-tools/drawio/stencils/sitemap.xml | 4221 + app/web-tools/drawio/stencils/veeam/2d.xml | 11861 ++ app/web-tools/drawio/stencils/veeam/3d.xml | 11155 ++ app/web-tools/drawio/stencils/veeam/veeam.xml | 12363 ++ .../drawio/stencils/veeam/veeam2.xml | 21868 +++ app/web-tools/drawio/stencils/vvd.xml | 11419 ++ app/web-tools/drawio/stencils/webicons.xml | 15274 ++ app/web-tools/drawio/stencils/weblogos.xml | 12222 ++ app/web-tools/drawio/styles/atlas.css | 221 + app/web-tools/drawio/styles/dark-default.xml | 109 + app/web-tools/drawio/styles/dark.css | 298 + app/web-tools/drawio/styles/default-old.xml | 109 + app/web-tools/drawio/styles/default.xml | 203 + .../fonts/ArchitectsDaughter-Regular.ttf | Bin 0 -> 37632 bytes app/web-tools/drawio/styles/grapheditor.css | 2169 + app/web-tools/drawio/styles/high-contrast.css | 78 + app/web-tools/drawio/styles/thumb_horz.png | Bin 0 -> 113 bytes .../drawio/styles/thumb_vertical.png | Bin 0 -> 122 bytes app/web-tools/drawio/teams.html | 463 + .../drawio/templates/basic/classes.png | Bin 0 -> 4213 bytes .../drawio/templates/basic/classes.xml | 2 + .../drawio/templates/basic/cross.png | Bin 0 -> 4577 bytes .../drawio/templates/basic/cross.xml | 1 + app/web-tools/drawio/templates/basic/erd.png | Bin 0 -> 3237 bytes app/web-tools/drawio/templates/basic/erd.xml | 1 + .../drawio/templates/basic/flowchart.png | Bin 0 -> 3946 bytes .../drawio/templates/basic/flowchart.xml | 2 + .../drawio/templates/basic/kanban.png | Bin 0 -> 3670 bytes .../drawio/templates/basic/kanban.xml | 1 + .../drawio/templates/basic/mindmap.png | Bin 0 -> 8147 bytes .../drawio/templates/basic/mindmap.xml | 329 + .../drawio/templates/basic/orgchart.png | Bin 0 -> 2763 bytes .../drawio/templates/basic/orgchart.xml | 2 + .../drawio/templates/basic/placeholder.png | Bin 0 -> 8034 bytes .../drawio/templates/basic/placeholder.xml | 64 + .../drawio/templates/basic/sequence.png | Bin 0 -> 3245 bytes .../drawio/templates/basic/sequence.xml | 1 + .../drawio/templates/basic/swimlanes.png | Bin 0 -> 3715 bytes .../drawio/templates/basic/swimlanes.xml | 2 + .../drawio/templates/business/accd.png | Bin 0 -> 3670 bytes .../drawio/templates/business/accd.xml | 1 + .../drawio/templates/business/archimate.png | Bin 0 -> 2981 bytes .../drawio/templates/business/archimate.xml | 1 + .../drawio/templates/business/bpmn.png | Bin 0 -> 3560 bytes .../drawio/templates/business/bpmn.xml | 1 + .../templates/business/business_model_1.png | Bin 0 -> 7133 bytes .../templates/business/business_model_1.xml | 1 + .../templates/business/business_model_2.png | Bin 0 -> 3725 bytes .../templates/business/business_model_2.xml | 1 + .../business/business_model_canvas_1.png | Bin 0 -> 2438 bytes .../business/business_model_canvas_1.xml | 1 + .../drawio/templates/business/ishikawa_1.png | Bin 0 -> 3486 bytes .../drawio/templates/business/ishikawa_1.xml | 1 + .../drawio/templates/business/ishikawa_2.png | Bin 0 -> 4472 bytes .../drawio/templates/business/ishikawa_2.xml | 1 + .../drawio/templates/business/pert_1.png | Bin 0 -> 4684 bytes .../drawio/templates/business/pert_1.xml | 1 + .../drawio/templates/business/pert_2.png | Bin 0 -> 2950 bytes .../drawio/templates/business/pert_2.xml | 1 + .../drawio/templates/business/swimlane.png | Bin 0 -> 6794 bytes .../drawio/templates/business/swimlane.xml | 1 + .../drawio/templates/business/timeline_1.png | Bin 0 -> 7370 bytes .../drawio/templates/business/timeline_1.xml | 1 + .../drawio/templates/business/timeline_2.png | Bin 0 -> 3547 bytes .../drawio/templates/business/timeline_2.xml | 1 + .../drawio/templates/business/timeline_3.png | Bin 0 -> 3556 bytes .../drawio/templates/business/timeline_3.xml | 1 + .../drawio/templates/business/timeline_4.png | Bin 0 -> 3967 bytes .../drawio/templates/business/timeline_4.xml | 1 + .../drawio/templates/charts/bar_chart_1.png | Bin 0 -> 2156 bytes .../drawio/templates/charts/bar_chart_1.xml | 1 + app/web-tools/drawio/templates/charts/coc.png | Bin 0 -> 4964 bytes app/web-tools/drawio/templates/charts/coc.xml | 1 + .../drawio/templates/charts/org_chart_1.png | Bin 0 -> 5456 bytes .../drawio/templates/charts/org_chart_1.xml | 1 + .../drawio/templates/charts/org_chart_2.png | Bin 0 -> 1954 bytes .../drawio/templates/charts/org_chart_2.xml | 1 + .../drawio/templates/charts/processbar.png | Bin 0 -> 14501 bytes .../drawio/templates/charts/processbar.xml | 25 + .../charts/work_breakdown_structure.png | Bin 0 -> 4501 bytes .../charts/work_breakdown_structure.xml | 1 + .../drawio/templates/cloud/aws/aws_1.png | Bin 0 -> 19740 bytes .../drawio/templates/cloud/aws/aws_1.xml | 1 + .../drawio/templates/cloud/aws/aws_10.png | Bin 0 -> 16280 bytes .../drawio/templates/cloud/aws/aws_10.xml | 1 + .../drawio/templates/cloud/aws/aws_2.png | Bin 0 -> 16697 bytes .../drawio/templates/cloud/aws/aws_2.xml | 1 + .../drawio/templates/cloud/aws/aws_3.png | Bin 0 -> 9149 bytes .../drawio/templates/cloud/aws/aws_3.xml | 1 + .../drawio/templates/cloud/aws/aws_3d.png | Bin 0 -> 13117 bytes .../drawio/templates/cloud/aws/aws_3d.xml | 1 + .../drawio/templates/cloud/aws/aws_4.png | Bin 0 -> 15604 bytes .../drawio/templates/cloud/aws/aws_4.xml | 1 + .../drawio/templates/cloud/aws/aws_5.png | Bin 0 -> 13657 bytes .../drawio/templates/cloud/aws/aws_5.xml | 1 + .../drawio/templates/cloud/aws/aws_6.png | Bin 0 -> 20300 bytes .../drawio/templates/cloud/aws/aws_6.xml | 1 + .../drawio/templates/cloud/aws/aws_7.png | Bin 0 -> 11967 bytes .../drawio/templates/cloud/aws/aws_7.xml | 1 + .../drawio/templates/cloud/aws/aws_8.png | Bin 0 -> 15531 bytes .../drawio/templates/cloud/aws/aws_8.xml | 1 + .../drawio/templates/cloud/aws/aws_9.png | Bin 0 -> 17650 bytes .../drawio/templates/cloud/aws/aws_9.xml | 1 + .../drawio/templates/cloud/azure/azure_1.png | Bin 0 -> 2683 bytes .../drawio/templates/cloud/azure/azure_1.xml | 2 + .../drawio/templates/cloud/azure/azure_2.png | Bin 0 -> 5316 bytes .../drawio/templates/cloud/azure/azure_2.xml | 1 + .../drawio/templates/cloud/azure/azure_3.png | Bin 0 -> 14477 bytes .../drawio/templates/cloud/azure/azure_3.xml | 1 + .../drawio/templates/cloud/azure/azure_4.png | Bin 0 -> 14572 bytes .../drawio/templates/cloud/azure/azure_4.xml | 1 + .../drawio/templates/cloud/azure/azure_5.png | Bin 0 -> 12937 bytes .../drawio/templates/cloud/azure/azure_5.xml | 1 + .../drawio/templates/cloud/azure/azure_6.png | Bin 0 -> 9033 bytes .../drawio/templates/cloud/azure/azure_6.xml | 1 + .../drawio/templates/cloud/azure/azure_7.png | Bin 0 -> 8939 bytes .../drawio/templates/cloud/azure/azure_7.xml | 1 + .../drawio/templates/cloud/azure/azure_8.png | Bin 0 -> 11353 bytes .../drawio/templates/cloud/azure/azure_8.xml | 1 + .../drawio/templates/cloud/azure/azure_9.png | Bin 0 -> 5748 bytes .../drawio/templates/cloud/azure/azure_9.xml | 1 + 523 files changed, 1034983 insertions(+) create mode 100644 app/web-tools/drawio/mxgraph/src/shape/mxActor.js create mode 100644 app/web-tools/drawio/mxgraph/src/shape/mxArrow.js create mode 100644 app/web-tools/drawio/mxgraph/src/shape/mxArrowConnector.js create mode 100644 app/web-tools/drawio/mxgraph/src/shape/mxCloud.js create mode 100644 app/web-tools/drawio/mxgraph/src/shape/mxConnector.js create mode 100644 app/web-tools/drawio/mxgraph/src/shape/mxCylinder.js create mode 100644 app/web-tools/drawio/mxgraph/src/shape/mxDoubleEllipse.js create mode 100644 app/web-tools/drawio/mxgraph/src/shape/mxEllipse.js create mode 100644 app/web-tools/drawio/mxgraph/src/shape/mxHexagon.js create mode 100644 app/web-tools/drawio/mxgraph/src/shape/mxImageShape.js create mode 100644 app/web-tools/drawio/mxgraph/src/shape/mxLabel.js create mode 100644 app/web-tools/drawio/mxgraph/src/shape/mxLine.js create mode 100644 app/web-tools/drawio/mxgraph/src/shape/mxMarker.js create mode 100644 app/web-tools/drawio/mxgraph/src/shape/mxPolyline.js create mode 100644 app/web-tools/drawio/mxgraph/src/shape/mxRectangleShape.js create mode 100644 app/web-tools/drawio/mxgraph/src/shape/mxRhombus.js create mode 100644 app/web-tools/drawio/mxgraph/src/shape/mxShape.js create mode 100644 app/web-tools/drawio/mxgraph/src/shape/mxStencil.js create mode 100644 app/web-tools/drawio/mxgraph/src/shape/mxStencilRegistry.js create mode 100644 app/web-tools/drawio/mxgraph/src/shape/mxSwimlane.js create mode 100644 app/web-tools/drawio/mxgraph/src/shape/mxText.js create mode 100644 app/web-tools/drawio/mxgraph/src/shape/mxTriangle.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxAbstractCanvas2D.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxAnimation.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxAutoSaveManager.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxClipboard.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxConstants.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxDictionary.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxDivResizer.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxDragSource.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxEffects.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxEvent.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxEventObject.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxEventSource.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxForm.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxGuide.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxImage.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxImageBundle.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxImageExport.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxLog.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxMorphing.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxMouseEvent.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxObjectIdentity.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxPanningManager.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxPoint.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxPopupMenu.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxRectangle.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxResources.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxSvgCanvas2D.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxToolbar.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxUndoManager.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxUndoableEdit.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxUrlConverter.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxUtils.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxWindow.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxXmlCanvas2D.js create mode 100644 app/web-tools/drawio/mxgraph/src/util/mxXmlRequest.js create mode 100644 app/web-tools/drawio/mxgraph/src/view/mxCellEditor.js create mode 100644 app/web-tools/drawio/mxgraph/src/view/mxCellOverlay.js create mode 100644 app/web-tools/drawio/mxgraph/src/view/mxCellRenderer.js create mode 100644 app/web-tools/drawio/mxgraph/src/view/mxCellState.js create mode 100644 app/web-tools/drawio/mxgraph/src/view/mxCellStatePreview.js create mode 100644 app/web-tools/drawio/mxgraph/src/view/mxConnectionConstraint.js create mode 100644 app/web-tools/drawio/mxgraph/src/view/mxEdgeStyle.js create mode 100644 app/web-tools/drawio/mxgraph/src/view/mxGraph.js create mode 100644 app/web-tools/drawio/mxgraph/src/view/mxGraphSelectionModel.js create mode 100644 app/web-tools/drawio/mxgraph/src/view/mxGraphView.js create mode 100644 app/web-tools/drawio/mxgraph/src/view/mxLayoutManager.js create mode 100644 app/web-tools/drawio/mxgraph/src/view/mxMultiplicity.js create mode 100644 app/web-tools/drawio/mxgraph/src/view/mxOutline.js create mode 100644 app/web-tools/drawio/mxgraph/src/view/mxPerimeter.js create mode 100644 app/web-tools/drawio/mxgraph/src/view/mxPrintPreview.js create mode 100644 app/web-tools/drawio/mxgraph/src/view/mxStyleRegistry.js create mode 100644 app/web-tools/drawio/mxgraph/src/view/mxStylesheet.js create mode 100644 app/web-tools/drawio/mxgraph/src/view/mxSwimlaneManager.js create mode 100644 app/web-tools/drawio/mxgraph/src/view/mxTemporaryCellStates.js create mode 100644 app/web-tools/drawio/onedrive3.html create mode 100644 app/web-tools/drawio/open.html create mode 100644 app/web-tools/drawio/plugins/animation.js create mode 100644 app/web-tools/drawio/plugins/anonymize.js create mode 100644 app/web-tools/drawio/plugins/edgeConnection.js create mode 100644 app/web-tools/drawio/plugins/explore.js create mode 100644 app/web-tools/drawio/plugins/flow.js create mode 100644 app/web-tools/drawio/plugins/googledrive.js create mode 100644 app/web-tools/drawio/plugins/import.js create mode 100644 app/web-tools/drawio/plugins/nextcloud.js create mode 100644 app/web-tools/drawio/plugins/number.js create mode 100644 app/web-tools/drawio/plugins/page.js create mode 100644 app/web-tools/drawio/plugins/props.js create mode 100644 app/web-tools/drawio/plugins/rackF5.js create mode 100644 app/web-tools/drawio/plugins/random.js create mode 100644 app/web-tools/drawio/plugins/replay.js create mode 100644 app/web-tools/drawio/plugins/sql.js create mode 100644 app/web-tools/drawio/plugins/svgdata.js create mode 100644 app/web-tools/drawio/plugins/tags.js create mode 100644 app/web-tools/drawio/plugins/text.js create mode 100644 app/web-tools/drawio/plugins/tooltips.js create mode 100644 app/web-tools/drawio/plugins/trees/handle-move.gif create mode 100644 app/web-tools/drawio/plugins/trees/trees.js create mode 100644 app/web-tools/drawio/plugins/trello.js create mode 100644 app/web-tools/drawio/plugins/update.js create mode 100644 app/web-tools/drawio/plugins/webcola/cola.min.js create mode 100644 app/web-tools/drawio/plugins/webcola/mxWebColaAdaptor.js create mode 100644 app/web-tools/drawio/plugins/webcola/mxWebColaLayout.js create mode 100644 app/web-tools/drawio/plugins/webcola/webcola.js create mode 100644 app/web-tools/drawio/resources/README.md create mode 100644 app/web-tools/drawio/resources/dia.txt create mode 100644 app/web-tools/drawio/resources/dia_am.txt create mode 100644 app/web-tools/drawio/resources/dia_ar.txt create mode 100644 app/web-tools/drawio/resources/dia_bg.txt create mode 100644 app/web-tools/drawio/resources/dia_bn.txt create mode 100644 app/web-tools/drawio/resources/dia_bs.txt create mode 100644 app/web-tools/drawio/resources/dia_ca.txt create mode 100644 app/web-tools/drawio/resources/dia_cs.txt create mode 100644 app/web-tools/drawio/resources/dia_da.txt create mode 100644 app/web-tools/drawio/resources/dia_de.txt create mode 100644 app/web-tools/drawio/resources/dia_el.txt create mode 100644 app/web-tools/drawio/resources/dia_eo.txt create mode 100644 app/web-tools/drawio/resources/dia_es.txt create mode 100644 app/web-tools/drawio/resources/dia_et.txt create mode 100644 app/web-tools/drawio/resources/dia_eu.txt create mode 100644 app/web-tools/drawio/resources/dia_fa.txt create mode 100644 app/web-tools/drawio/resources/dia_fi.txt create mode 100644 app/web-tools/drawio/resources/dia_fil.txt create mode 100644 app/web-tools/drawio/resources/dia_fr.txt create mode 100644 app/web-tools/drawio/resources/dia_gl.txt create mode 100644 app/web-tools/drawio/resources/dia_gu.txt create mode 100644 app/web-tools/drawio/resources/dia_he.txt create mode 100644 app/web-tools/drawio/resources/dia_hi.txt create mode 100644 app/web-tools/drawio/resources/dia_hr.txt create mode 100644 app/web-tools/drawio/resources/dia_hu.txt create mode 100644 app/web-tools/drawio/resources/dia_i18n.txt create mode 100644 app/web-tools/drawio/resources/dia_id.txt create mode 100644 app/web-tools/drawio/resources/dia_it.txt create mode 100644 app/web-tools/drawio/resources/dia_ja.txt create mode 100644 app/web-tools/drawio/resources/dia_kn.txt create mode 100644 app/web-tools/drawio/resources/dia_ko.txt create mode 100644 app/web-tools/drawio/resources/dia_lt.txt create mode 100644 app/web-tools/drawio/resources/dia_lv.txt create mode 100644 app/web-tools/drawio/resources/dia_ml.txt create mode 100644 app/web-tools/drawio/resources/dia_mr.txt create mode 100644 app/web-tools/drawio/resources/dia_ms.txt create mode 100644 app/web-tools/drawio/resources/dia_my.txt create mode 100644 app/web-tools/drawio/resources/dia_nl.txt create mode 100644 app/web-tools/drawio/resources/dia_no.txt create mode 100644 app/web-tools/drawio/resources/dia_pl.txt create mode 100644 app/web-tools/drawio/resources/dia_pt-br.txt create mode 100644 app/web-tools/drawio/resources/dia_pt.txt create mode 100644 app/web-tools/drawio/resources/dia_ro.txt create mode 100644 app/web-tools/drawio/resources/dia_ru.txt create mode 100644 app/web-tools/drawio/resources/dia_si.txt create mode 100644 app/web-tools/drawio/resources/dia_sk.txt create mode 100644 app/web-tools/drawio/resources/dia_sl.txt create mode 100644 app/web-tools/drawio/resources/dia_sr.txt create mode 100644 app/web-tools/drawio/resources/dia_sv.txt create mode 100644 app/web-tools/drawio/resources/dia_sw.txt create mode 100644 app/web-tools/drawio/resources/dia_ta.txt create mode 100644 app/web-tools/drawio/resources/dia_te.txt create mode 100644 app/web-tools/drawio/resources/dia_th.txt create mode 100644 app/web-tools/drawio/resources/dia_tr.txt create mode 100644 app/web-tools/drawio/resources/dia_uk.txt create mode 100644 app/web-tools/drawio/resources/dia_vi.txt create mode 100644 app/web-tools/drawio/resources/dia_zh-tw.txt create mode 100644 app/web-tools/drawio/resources/dia_zh.txt create mode 100644 app/web-tools/drawio/service-worker.js create mode 100644 app/web-tools/drawio/shapes/bpmn/mxBpmnShape2.js create mode 100644 app/web-tools/drawio/shapes/emoji/mxEmoji.js create mode 100644 app/web-tools/drawio/shapes/er/mxER.js create mode 100644 app/web-tools/drawio/shapes/ios7/mxIOS7Ui.js create mode 100644 app/web-tools/drawio/shapes/mockup/mxMockupButtons.js create mode 100644 app/web-tools/drawio/shapes/mockup/mxMockupContainers.js create mode 100644 app/web-tools/drawio/shapes/mockup/mxMockupForms.js create mode 100644 app/web-tools/drawio/shapes/mockup/mxMockupGraphics.js create mode 100644 app/web-tools/drawio/shapes/mockup/mxMockupMarkup.js create mode 100644 app/web-tools/drawio/shapes/mockup/mxMockupMisc.js create mode 100644 app/web-tools/drawio/shapes/mockup/mxMockupNavigation.js create mode 100644 app/web-tools/drawio/shapes/mockup/mxMockupText.js create mode 100644 app/web-tools/drawio/shapes/mockup/mxMockupiOS.js create mode 100644 app/web-tools/drawio/shapes/mxAWS3D.js create mode 100644 app/web-tools/drawio/shapes/mxAWS4.js create mode 100644 app/web-tools/drawio/shapes/mxAndroid.js create mode 100644 app/web-tools/drawio/shapes/mxArchiMate.js create mode 100644 app/web-tools/drawio/shapes/mxArchiMate3.js create mode 100644 app/web-tools/drawio/shapes/mxArrows.js create mode 100644 app/web-tools/drawio/shapes/mxAtlassian.js create mode 100644 app/web-tools/drawio/shapes/mxBasic.js create mode 100644 app/web-tools/drawio/shapes/mxBootstrap.js create mode 100644 app/web-tools/drawio/shapes/mxC4.js create mode 100644 app/web-tools/drawio/shapes/mxCabinets.js create mode 100644 app/web-tools/drawio/shapes/mxCisco19.js create mode 100644 app/web-tools/drawio/shapes/mxCiscoSafe.js create mode 100644 app/web-tools/drawio/shapes/mxDFD.js create mode 100644 app/web-tools/drawio/shapes/mxEip.js create mode 100644 app/web-tools/drawio/shapes/mxElectrical.js create mode 100644 app/web-tools/drawio/shapes/mxFloorplan.js create mode 100644 app/web-tools/drawio/shapes/mxFlowchart.js create mode 100644 app/web-tools/drawio/shapes/mxGCP2.js create mode 100644 app/web-tools/drawio/shapes/mxGmdl.js create mode 100644 app/web-tools/drawio/shapes/mxIBM.js create mode 100644 app/web-tools/drawio/shapes/mxInfographic.js create mode 100644 app/web-tools/drawio/shapes/mxKubernetes.js create mode 100644 app/web-tools/drawio/shapes/mxLeanMap.js create mode 100644 app/web-tools/drawio/shapes/mxNetworks.js create mode 100644 app/web-tools/drawio/shapes/mxSAP.js create mode 100644 app/web-tools/drawio/shapes/mxSysML.js create mode 100644 app/web-tools/drawio/shapes/mxUML25.js create mode 100644 app/web-tools/drawio/shapes/pid2/mxPidInstruments.js create mode 100644 app/web-tools/drawio/shapes/pid2/mxPidMisc.js create mode 100644 app/web-tools/drawio/shapes/pid2/mxPidValves.js create mode 100644 app/web-tools/drawio/shapes/rack/mxRack.js create mode 100644 app/web-tools/drawio/shortcuts.svg create mode 100644 app/web-tools/drawio/stencils/LICENSE create mode 100644 app/web-tools/drawio/stencils/android/android.xml create mode 100644 app/web-tools/drawio/stencils/arrows.xml create mode 100644 app/web-tools/drawio/stencils/atlassian.xml create mode 100644 app/web-tools/drawio/stencils/aws/compute.xml create mode 100644 app/web-tools/drawio/stencils/aws/content_delivery.xml create mode 100644 app/web-tools/drawio/stencils/aws/database.xml create mode 100644 app/web-tools/drawio/stencils/aws/deployment_management.xml create mode 100644 app/web-tools/drawio/stencils/aws/groups.xml create mode 100644 app/web-tools/drawio/stencils/aws/messaging.xml create mode 100644 app/web-tools/drawio/stencils/aws/misc.xml create mode 100644 app/web-tools/drawio/stencils/aws/networking.xml create mode 100644 app/web-tools/drawio/stencils/aws/non_service_specific.xml create mode 100644 app/web-tools/drawio/stencils/aws/on_demand_workforce.xml create mode 100644 app/web-tools/drawio/stencils/aws/storage.xml create mode 100644 app/web-tools/drawio/stencils/aws2/administration_and_security.xml create mode 100644 app/web-tools/drawio/stencils/aws2/analytics.xml create mode 100644 app/web-tools/drawio/stencils/aws2/app_services.xml create mode 100644 app/web-tools/drawio/stencils/aws2/compute_and_networking.xml create mode 100644 app/web-tools/drawio/stencils/aws2/database.xml create mode 100644 app/web-tools/drawio/stencils/aws2/deployment_and_management.xml create mode 100644 app/web-tools/drawio/stencils/aws2/developer_tools.xml create mode 100644 app/web-tools/drawio/stencils/aws2/enterprise_applications.xml create mode 100644 app/web-tools/drawio/stencils/aws2/game_development.xml create mode 100644 app/web-tools/drawio/stencils/aws2/internet_of_things.xml create mode 100644 app/web-tools/drawio/stencils/aws2/management_tools.xml create mode 100644 app/web-tools/drawio/stencils/aws2/mobile_services.xml create mode 100644 app/web-tools/drawio/stencils/aws2/networking.xml create mode 100644 app/web-tools/drawio/stencils/aws2/non-service_specific.xml create mode 100644 app/web-tools/drawio/stencils/aws2/on-demand_workforce.xml create mode 100644 app/web-tools/drawio/stencils/aws2/sdks.xml create mode 100644 app/web-tools/drawio/stencils/aws2/security_and_identity.xml create mode 100644 app/web-tools/drawio/stencils/aws2/storage_and_content_delivery.xml create mode 100644 app/web-tools/drawio/stencils/aws3.xml create mode 100644 app/web-tools/drawio/stencils/aws3d.xml create mode 100644 app/web-tools/drawio/stencils/aws4.xml create mode 100644 app/web-tools/drawio/stencils/azure.xml create mode 100644 app/web-tools/drawio/stencils/basic.xml create mode 100644 app/web-tools/drawio/stencils/bootstrap.xml create mode 100644 app/web-tools/drawio/stencils/bpmn.xml create mode 100644 app/web-tools/drawio/stencils/cabinets.xml create mode 100644 app/web-tools/drawio/stencils/cisco/buildings.xml create mode 100644 app/web-tools/drawio/stencils/cisco/computers_and_peripherals.xml create mode 100644 app/web-tools/drawio/stencils/cisco/controllers_and_modules.xml create mode 100644 app/web-tools/drawio/stencils/cisco/directors.xml create mode 100644 app/web-tools/drawio/stencils/cisco/hubs_and_gateways.xml create mode 100644 app/web-tools/drawio/stencils/cisco/misc.xml create mode 100644 app/web-tools/drawio/stencils/cisco/modems_and_phones.xml create mode 100644 app/web-tools/drawio/stencils/cisco/people.xml create mode 100644 app/web-tools/drawio/stencils/cisco/routers.xml create mode 100644 app/web-tools/drawio/stencils/cisco/security.xml create mode 100644 app/web-tools/drawio/stencils/cisco/servers.xml create mode 100644 app/web-tools/drawio/stencils/cisco/storage.xml create mode 100644 app/web-tools/drawio/stencils/cisco/switches.xml create mode 100644 app/web-tools/drawio/stencils/cisco/wireless.xml create mode 100644 app/web-tools/drawio/stencils/cisco19.xml create mode 100644 app/web-tools/drawio/stencils/cisco_safe/architecture.xml create mode 100644 app/web-tools/drawio/stencils/cisco_safe/business_icons.xml create mode 100644 app/web-tools/drawio/stencils/cisco_safe/capability.xml create mode 100644 app/web-tools/drawio/stencils/cisco_safe/design.xml create mode 100644 app/web-tools/drawio/stencils/cisco_safe/iot_things_icons.xml create mode 100644 app/web-tools/drawio/stencils/cisco_safe/people_places_things_icons.xml create mode 100644 app/web-tools/drawio/stencils/cisco_safe/security_icons.xml create mode 100644 app/web-tools/drawio/stencils/cisco_safe/technology_icons.xml create mode 100644 app/web-tools/drawio/stencils/cisco_safe/threat.xml create mode 100644 app/web-tools/drawio/stencils/citrix.xml create mode 100644 app/web-tools/drawio/stencils/clipart/Gear_128x128.png create mode 100644 app/web-tools/drawio/stencils/eip.xml create mode 100644 app/web-tools/drawio/stencils/electrical/abstract.xml create mode 100644 app/web-tools/drawio/stencils/electrical/capacitors.xml create mode 100644 app/web-tools/drawio/stencils/electrical/diodes.xml create mode 100644 app/web-tools/drawio/stencils/electrical/electro-mechanical.xml create mode 100644 app/web-tools/drawio/stencils/electrical/iec417.xml create mode 100644 app/web-tools/drawio/stencils/electrical/iec_logic_gates.xml create mode 100644 app/web-tools/drawio/stencils/electrical/inductors.xml create mode 100644 app/web-tools/drawio/stencils/electrical/instruments.xml create mode 100644 app/web-tools/drawio/stencils/electrical/logic_gates.xml create mode 100644 app/web-tools/drawio/stencils/electrical/miscellaneous.xml create mode 100644 app/web-tools/drawio/stencils/electrical/mosfets1.xml create mode 100644 app/web-tools/drawio/stencils/electrical/mosfets2.xml create mode 100644 app/web-tools/drawio/stencils/electrical/op_amps.xml create mode 100644 app/web-tools/drawio/stencils/electrical/opto_electronics.xml create mode 100644 app/web-tools/drawio/stencils/electrical/plc_ladder.xml create mode 100644 app/web-tools/drawio/stencils/electrical/power_semiconductors.xml create mode 100644 app/web-tools/drawio/stencils/electrical/radio.xml create mode 100644 app/web-tools/drawio/stencils/electrical/resistors.xml create mode 100644 app/web-tools/drawio/stencils/electrical/rot_mech.xml create mode 100644 app/web-tools/drawio/stencils/electrical/signal_sources.xml create mode 100644 app/web-tools/drawio/stencils/electrical/thermionic_devices.xml create mode 100644 app/web-tools/drawio/stencils/electrical/transistors.xml create mode 100644 app/web-tools/drawio/stencils/electrical/transmission.xml create mode 100644 app/web-tools/drawio/stencils/electrical/waveforms.xml create mode 100644 app/web-tools/drawio/stencils/floorplan.xml create mode 100644 app/web-tools/drawio/stencils/flowchart.xml create mode 100644 app/web-tools/drawio/stencils/fluid_power.xml create mode 100644 app/web-tools/drawio/stencils/gcp/big_data.xml create mode 100644 app/web-tools/drawio/stencils/gcp/compute.xml create mode 100644 app/web-tools/drawio/stencils/gcp/developer_tools.xml create mode 100644 app/web-tools/drawio/stencils/gcp/extras.xml create mode 100644 app/web-tools/drawio/stencils/gcp/identity_and_security.xml create mode 100644 app/web-tools/drawio/stencils/gcp/machine_learning.xml create mode 100644 app/web-tools/drawio/stencils/gcp/management_tools.xml create mode 100644 app/web-tools/drawio/stencils/gcp/networking.xml create mode 100644 app/web-tools/drawio/stencils/gcp/product_cards.xml create mode 100644 app/web-tools/drawio/stencils/gcp/storage_databases.xml create mode 100644 app/web-tools/drawio/stencils/gcp2.xml create mode 100644 app/web-tools/drawio/stencils/gmdl.xml create mode 100644 app/web-tools/drawio/stencils/ibm.xml create mode 100644 app/web-tools/drawio/stencils/ios7/icons.xml create mode 100644 app/web-tools/drawio/stencils/ios7/misc.xml create mode 100644 app/web-tools/drawio/stencils/kubernetes.xml create mode 100644 app/web-tools/drawio/stencils/kubernetes2.xml create mode 100644 app/web-tools/drawio/stencils/lean_mapping.xml create mode 100644 app/web-tools/drawio/stencils/mockup/advertising.xml create mode 100644 app/web-tools/drawio/stencils/mockup/calendars.xml create mode 100644 app/web-tools/drawio/stencils/mockup/carousel.xml create mode 100644 app/web-tools/drawio/stencils/mockup/charts_and_tables.xml create mode 100644 app/web-tools/drawio/stencils/mockup/controls.xml create mode 100644 app/web-tools/drawio/stencils/mockup/form_elements.xml create mode 100644 app/web-tools/drawio/stencils/mockup/menus_and_buttons.xml create mode 100644 app/web-tools/drawio/stencils/mockup/misc.xml create mode 100644 app/web-tools/drawio/stencils/mockup/tabs.xml create mode 100644 app/web-tools/drawio/stencils/mscae/cloud.xml create mode 100644 app/web-tools/drawio/stencils/mscae/deprecated.xml create mode 100644 app/web-tools/drawio/stencils/mscae/enterprise.xml create mode 100644 app/web-tools/drawio/stencils/mscae/general.xml create mode 100644 app/web-tools/drawio/stencils/mscae/general_symbols.xml create mode 100644 app/web-tools/drawio/stencils/mscae/intune.xml create mode 100644 app/web-tools/drawio/stencils/mscae/oms.xml create mode 100644 app/web-tools/drawio/stencils/mscae/opsmanager.xml create mode 100644 app/web-tools/drawio/stencils/mscae/other.xml create mode 100644 app/web-tools/drawio/stencils/mscae/system_center.xml create mode 100644 app/web-tools/drawio/stencils/mscae/vm.xml create mode 100644 app/web-tools/drawio/stencils/networks.xml create mode 100644 app/web-tools/drawio/stencils/office/clouds.xml create mode 100644 app/web-tools/drawio/stencils/office/communications.xml create mode 100644 app/web-tools/drawio/stencils/office/concepts.xml create mode 100644 app/web-tools/drawio/stencils/office/databases.xml create mode 100644 app/web-tools/drawio/stencils/office/devices.xml create mode 100644 app/web-tools/drawio/stencils/office/security.xml create mode 100644 app/web-tools/drawio/stencils/office/servers.xml create mode 100644 app/web-tools/drawio/stencils/office/services.xml create mode 100644 app/web-tools/drawio/stencils/office/sites.xml create mode 100644 app/web-tools/drawio/stencils/office/users.xml create mode 100644 app/web-tools/drawio/stencils/pid/agitators.xml create mode 100644 app/web-tools/drawio/stencils/pid/apparatus_elements.xml create mode 100644 app/web-tools/drawio/stencils/pid/centrifuges.xml create mode 100644 app/web-tools/drawio/stencils/pid/compressors.xml create mode 100644 app/web-tools/drawio/stencils/pid/compressors_iso.xml create mode 100644 app/web-tools/drawio/stencils/pid/crushers_grinding.xml create mode 100644 app/web-tools/drawio/stencils/pid/driers.xml create mode 100644 app/web-tools/drawio/stencils/pid/engines.xml create mode 100644 app/web-tools/drawio/stencils/pid/feeders.xml create mode 100644 app/web-tools/drawio/stencils/pid/filters.xml create mode 100644 app/web-tools/drawio/stencils/pid/fittings.xml create mode 100644 app/web-tools/drawio/stencils/pid/flow_sensors.xml create mode 100644 app/web-tools/drawio/stencils/pid/heat_exchangers.xml create mode 100644 app/web-tools/drawio/stencils/pid/instruments.xml create mode 100644 app/web-tools/drawio/stencils/pid/misc.xml create mode 100644 app/web-tools/drawio/stencils/pid/mixers.xml create mode 100644 app/web-tools/drawio/stencils/pid/piping.xml create mode 100644 app/web-tools/drawio/stencils/pid/pumps.xml create mode 100644 app/web-tools/drawio/stencils/pid/pumps_din.xml create mode 100644 app/web-tools/drawio/stencils/pid/pumps_iso.xml create mode 100644 app/web-tools/drawio/stencils/pid/separators.xml create mode 100644 app/web-tools/drawio/stencils/pid/shaping_machines.xml create mode 100644 app/web-tools/drawio/stencils/pid/valves.xml create mode 100644 app/web-tools/drawio/stencils/pid/vessels.xml create mode 100644 app/web-tools/drawio/stencils/rack/apc.xml create mode 100644 app/web-tools/drawio/stencils/rack/cisco.xml create mode 100644 app/web-tools/drawio/stencils/rack/dell.xml create mode 100644 app/web-tools/drawio/stencils/rack/f5.xml create mode 100644 app/web-tools/drawio/stencils/rack/general.xml create mode 100644 app/web-tools/drawio/stencils/rack/hp.xml create mode 100644 app/web-tools/drawio/stencils/rack/hpe_aruba/gateways_controllers.xml create mode 100644 app/web-tools/drawio/stencils/rack/hpe_aruba/security.xml create mode 100644 app/web-tools/drawio/stencils/rack/hpe_aruba/switches.xml create mode 100644 app/web-tools/drawio/stencils/rack/ibm.xml create mode 100644 app/web-tools/drawio/stencils/rack/oracle.xml create mode 100644 app/web-tools/drawio/stencils/salesforce.xml create mode 100644 app/web-tools/drawio/stencils/signs/animals.xml create mode 100644 app/web-tools/drawio/stencils/signs/food.xml create mode 100644 app/web-tools/drawio/stencils/signs/healthcare.xml create mode 100644 app/web-tools/drawio/stencils/signs/nature.xml create mode 100644 app/web-tools/drawio/stencils/signs/people.xml create mode 100644 app/web-tools/drawio/stencils/signs/safety.xml create mode 100644 app/web-tools/drawio/stencils/signs/science.xml create mode 100644 app/web-tools/drawio/stencils/signs/sports.xml create mode 100644 app/web-tools/drawio/stencils/signs/tech.xml create mode 100644 app/web-tools/drawio/stencils/signs/transportation.xml create mode 100644 app/web-tools/drawio/stencils/signs/travel.xml create mode 100644 app/web-tools/drawio/stencils/sitemap.xml create mode 100644 app/web-tools/drawio/stencils/veeam/2d.xml create mode 100644 app/web-tools/drawio/stencils/veeam/3d.xml create mode 100644 app/web-tools/drawio/stencils/veeam/veeam.xml create mode 100644 app/web-tools/drawio/stencils/veeam/veeam2.xml create mode 100644 app/web-tools/drawio/stencils/vvd.xml create mode 100644 app/web-tools/drawio/stencils/webicons.xml create mode 100644 app/web-tools/drawio/stencils/weblogos.xml create mode 100644 app/web-tools/drawio/styles/atlas.css create mode 100644 app/web-tools/drawio/styles/dark-default.xml create mode 100644 app/web-tools/drawio/styles/dark.css create mode 100644 app/web-tools/drawio/styles/default-old.xml create mode 100644 app/web-tools/drawio/styles/default.xml create mode 100644 app/web-tools/drawio/styles/fonts/ArchitectsDaughter-Regular.ttf create mode 100644 app/web-tools/drawio/styles/grapheditor.css create mode 100644 app/web-tools/drawio/styles/high-contrast.css create mode 100644 app/web-tools/drawio/styles/thumb_horz.png create mode 100644 app/web-tools/drawio/styles/thumb_vertical.png create mode 100644 app/web-tools/drawio/teams.html create mode 100644 app/web-tools/drawio/templates/basic/classes.png create mode 100644 app/web-tools/drawio/templates/basic/classes.xml create mode 100644 app/web-tools/drawio/templates/basic/cross.png create mode 100644 app/web-tools/drawio/templates/basic/cross.xml create mode 100644 app/web-tools/drawio/templates/basic/erd.png create mode 100644 app/web-tools/drawio/templates/basic/erd.xml create mode 100644 app/web-tools/drawio/templates/basic/flowchart.png create mode 100644 app/web-tools/drawio/templates/basic/flowchart.xml create mode 100644 app/web-tools/drawio/templates/basic/kanban.png create mode 100644 app/web-tools/drawio/templates/basic/kanban.xml create mode 100644 app/web-tools/drawio/templates/basic/mindmap.png create mode 100644 app/web-tools/drawio/templates/basic/mindmap.xml create mode 100644 app/web-tools/drawio/templates/basic/orgchart.png create mode 100644 app/web-tools/drawio/templates/basic/orgchart.xml create mode 100644 app/web-tools/drawio/templates/basic/placeholder.png create mode 100644 app/web-tools/drawio/templates/basic/placeholder.xml create mode 100644 app/web-tools/drawio/templates/basic/sequence.png create mode 100644 app/web-tools/drawio/templates/basic/sequence.xml create mode 100644 app/web-tools/drawio/templates/basic/swimlanes.png create mode 100644 app/web-tools/drawio/templates/basic/swimlanes.xml create mode 100644 app/web-tools/drawio/templates/business/accd.png create mode 100644 app/web-tools/drawio/templates/business/accd.xml create mode 100644 app/web-tools/drawio/templates/business/archimate.png create mode 100644 app/web-tools/drawio/templates/business/archimate.xml create mode 100644 app/web-tools/drawio/templates/business/bpmn.png create mode 100644 app/web-tools/drawio/templates/business/bpmn.xml create mode 100644 app/web-tools/drawio/templates/business/business_model_1.png create mode 100644 app/web-tools/drawio/templates/business/business_model_1.xml create mode 100644 app/web-tools/drawio/templates/business/business_model_2.png create mode 100644 app/web-tools/drawio/templates/business/business_model_2.xml create mode 100644 app/web-tools/drawio/templates/business/business_model_canvas_1.png create mode 100644 app/web-tools/drawio/templates/business/business_model_canvas_1.xml create mode 100644 app/web-tools/drawio/templates/business/ishikawa_1.png create mode 100644 app/web-tools/drawio/templates/business/ishikawa_1.xml create mode 100644 app/web-tools/drawio/templates/business/ishikawa_2.png create mode 100644 app/web-tools/drawio/templates/business/ishikawa_2.xml create mode 100644 app/web-tools/drawio/templates/business/pert_1.png create mode 100644 app/web-tools/drawio/templates/business/pert_1.xml create mode 100644 app/web-tools/drawio/templates/business/pert_2.png create mode 100644 app/web-tools/drawio/templates/business/pert_2.xml create mode 100644 app/web-tools/drawio/templates/business/swimlane.png create mode 100644 app/web-tools/drawio/templates/business/swimlane.xml create mode 100644 app/web-tools/drawio/templates/business/timeline_1.png create mode 100644 app/web-tools/drawio/templates/business/timeline_1.xml create mode 100644 app/web-tools/drawio/templates/business/timeline_2.png create mode 100644 app/web-tools/drawio/templates/business/timeline_2.xml create mode 100644 app/web-tools/drawio/templates/business/timeline_3.png create mode 100644 app/web-tools/drawio/templates/business/timeline_3.xml create mode 100644 app/web-tools/drawio/templates/business/timeline_4.png create mode 100644 app/web-tools/drawio/templates/business/timeline_4.xml create mode 100644 app/web-tools/drawio/templates/charts/bar_chart_1.png create mode 100644 app/web-tools/drawio/templates/charts/bar_chart_1.xml create mode 100644 app/web-tools/drawio/templates/charts/coc.png create mode 100644 app/web-tools/drawio/templates/charts/coc.xml create mode 100644 app/web-tools/drawio/templates/charts/org_chart_1.png create mode 100644 app/web-tools/drawio/templates/charts/org_chart_1.xml create mode 100644 app/web-tools/drawio/templates/charts/org_chart_2.png create mode 100644 app/web-tools/drawio/templates/charts/org_chart_2.xml create mode 100644 app/web-tools/drawio/templates/charts/processbar.png create mode 100644 app/web-tools/drawio/templates/charts/processbar.xml create mode 100644 app/web-tools/drawio/templates/charts/work_breakdown_structure.png create mode 100644 app/web-tools/drawio/templates/charts/work_breakdown_structure.xml create mode 100644 app/web-tools/drawio/templates/cloud/aws/aws_1.png create mode 100644 app/web-tools/drawio/templates/cloud/aws/aws_1.xml create mode 100644 app/web-tools/drawio/templates/cloud/aws/aws_10.png create mode 100644 app/web-tools/drawio/templates/cloud/aws/aws_10.xml create mode 100644 app/web-tools/drawio/templates/cloud/aws/aws_2.png create mode 100644 app/web-tools/drawio/templates/cloud/aws/aws_2.xml create mode 100644 app/web-tools/drawio/templates/cloud/aws/aws_3.png create mode 100644 app/web-tools/drawio/templates/cloud/aws/aws_3.xml create mode 100644 app/web-tools/drawio/templates/cloud/aws/aws_3d.png create mode 100644 app/web-tools/drawio/templates/cloud/aws/aws_3d.xml create mode 100644 app/web-tools/drawio/templates/cloud/aws/aws_4.png create mode 100644 app/web-tools/drawio/templates/cloud/aws/aws_4.xml create mode 100644 app/web-tools/drawio/templates/cloud/aws/aws_5.png create mode 100644 app/web-tools/drawio/templates/cloud/aws/aws_5.xml create mode 100644 app/web-tools/drawio/templates/cloud/aws/aws_6.png create mode 100644 app/web-tools/drawio/templates/cloud/aws/aws_6.xml create mode 100644 app/web-tools/drawio/templates/cloud/aws/aws_7.png create mode 100644 app/web-tools/drawio/templates/cloud/aws/aws_7.xml create mode 100644 app/web-tools/drawio/templates/cloud/aws/aws_8.png create mode 100644 app/web-tools/drawio/templates/cloud/aws/aws_8.xml create mode 100644 app/web-tools/drawio/templates/cloud/aws/aws_9.png create mode 100644 app/web-tools/drawio/templates/cloud/aws/aws_9.xml create mode 100644 app/web-tools/drawio/templates/cloud/azure/azure_1.png create mode 100644 app/web-tools/drawio/templates/cloud/azure/azure_1.xml create mode 100644 app/web-tools/drawio/templates/cloud/azure/azure_2.png create mode 100644 app/web-tools/drawio/templates/cloud/azure/azure_2.xml create mode 100644 app/web-tools/drawio/templates/cloud/azure/azure_3.png create mode 100644 app/web-tools/drawio/templates/cloud/azure/azure_3.xml create mode 100644 app/web-tools/drawio/templates/cloud/azure/azure_4.png create mode 100644 app/web-tools/drawio/templates/cloud/azure/azure_4.xml create mode 100644 app/web-tools/drawio/templates/cloud/azure/azure_5.png create mode 100644 app/web-tools/drawio/templates/cloud/azure/azure_5.xml create mode 100644 app/web-tools/drawio/templates/cloud/azure/azure_6.png create mode 100644 app/web-tools/drawio/templates/cloud/azure/azure_6.xml create mode 100644 app/web-tools/drawio/templates/cloud/azure/azure_7.png create mode 100644 app/web-tools/drawio/templates/cloud/azure/azure_7.xml create mode 100644 app/web-tools/drawio/templates/cloud/azure/azure_8.png create mode 100644 app/web-tools/drawio/templates/cloud/azure/azure_8.xml create mode 100644 app/web-tools/drawio/templates/cloud/azure/azure_9.png create mode 100644 app/web-tools/drawio/templates/cloud/azure/azure_9.xml diff --git a/app/web-tools/drawio/mxgraph/src/shape/mxActor.js b/app/web-tools/drawio/mxgraph/src/shape/mxActor.js new file mode 100644 index 00000000..204201cf --- /dev/null +++ b/app/web-tools/drawio/mxgraph/src/shape/mxActor.js @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2006-2015, JGraph Ltd + * Copyright (c) 2006-2015, Gaudenz Alder + */ +/** + * Class: mxActor + * + * Extends to implement an actor shape. If a custom shape with one + * filled area is needed, then this shape's should be overridden. + * + * Example: + * + * (code) + * function SampleShape() { } + * + * SampleShape.prototype = new mxActor(); + * SampleShape.prototype.constructor = vsAseShape; + * + * mxCellRenderer.registerShape('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 in + * . + * + * Constructor: mxActor + * + * Constructs a new actor shape. + * + * Parameters: + * + * bounds - that defines the bounds. This is stored in + * . + * fill - String that defines the fill color. This is stored in . + * stroke - String that defines the stroke color. This is stored in . + * strokewidth - Optional integer that defines the stroke width. Default is + * 1. This is stored in . + */ +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(); +}; diff --git a/app/web-tools/drawio/mxgraph/src/shape/mxArrow.js b/app/web-tools/drawio/mxgraph/src/shape/mxArrow.js new file mode 100644 index 00000000..c5c44020 --- /dev/null +++ b/app/web-tools/drawio/mxgraph/src/shape/mxArrow.js @@ -0,0 +1,115 @@ +/** + * Copyright (c) 2006-2015, JGraph Ltd + * Copyright (c) 2006-2015, Gaudenz Alder + */ +/** + * Class: mxArrow + * + * Extends to implement an arrow shape. (The shape + * is used to represent edges, not vertices.) + * This shape is registered under + * in . + * + * Constructor: mxArrow + * + * Constructs a new arrow shape. + * + * Parameters: + * + * points - Array of that define the points. This is stored in + * . + * fill - String that defines the fill color. This is stored in . + * stroke - String that defines the stroke color. This is stored in . + * strokewidth - Optional integer that defines the stroke width. Default is + * 1. This is stored in . + * arrowWidth - Optional integer that defines the arrow width. Default is + * . This is stored in . + * spacing - Optional integer that defines the spacing between the arrow shape + * and its endpoints. Default is . This is stored in + * . + * endSize - Optional integer that defines the size of the arrowhead. Default + * is . This is stored in . + */ +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(); +}; diff --git a/app/web-tools/drawio/mxgraph/src/shape/mxArrowConnector.js b/app/web-tools/drawio/mxgraph/src/shape/mxArrowConnector.js new file mode 100644 index 00000000..96d516fc --- /dev/null +++ b/app/web-tools/drawio/mxgraph/src/shape/mxArrowConnector.js @@ -0,0 +1,488 @@ +/** + * Copyright (c) 2006-2015, JGraph Ltd + * Copyright (c) 2006-2015, Gaudenz Alder + */ +/** + * Class: mxArrowConnector + * + * Extends 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 + * in . + * + * Constructor: mxArrowConnector + * + * Constructs a new arrow shape. + * + * Parameters: + * + * points - Array of that define the points. This is stored in + * . + * fill - String that defines the fill color. This is stored in . + * stroke - String that defines the stroke color. This is stored in . + * strokewidth - Optional integer that defines the stroke width. Default is + * 1. This is stored in . + * arrowWidth - Optional integer that defines the arrow width. Default is + * . This is stored in . + * spacing - Optional integer that defines the spacing between the arrow shape + * and its endpoints. Default is . This is stored in + * . + * endSize - Optional integer that defines the size of the arrowhead. Default + * is . This is stored in . + */ +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; + +/** + * Function: isRoundable + * + * Hook for subclassers. + */ +mxArrowConnector.prototype.isRoundable = function() +{ + return 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]; + var dx = pts[1].x - pts[0].x; + var dy = pts[1].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; + var 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: paintMarker + * + * Paints the marker. + */ +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); +}; \ No newline at end of file diff --git a/app/web-tools/drawio/mxgraph/src/shape/mxCloud.js b/app/web-tools/drawio/mxgraph/src/shape/mxCloud.js new file mode 100644 index 00000000..fb1f931b --- /dev/null +++ b/app/web-tools/drawio/mxgraph/src/shape/mxCloud.js @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2006-2015, JGraph Ltd + * Copyright (c) 2006-2015, Gaudenz Alder + */ +/** + * Class: mxCloud + * + * Extends to implement a cloud shape. + * + * This shape is registered under in + * . + * + * Constructor: mxCloud + * + * Constructs a new cloud shape. + * + * Parameters: + * + * bounds - that defines the bounds. This is stored in + * . + * fill - String that defines the fill color. This is stored in . + * stroke - String that defines the stroke color. This is stored in . + * strokewidth - Optional integer that defines the stroke width. Default is + * 1. This is stored in . + */ +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(); +}; diff --git a/app/web-tools/drawio/mxgraph/src/shape/mxConnector.js b/app/web-tools/drawio/mxgraph/src/shape/mxConnector.js new file mode 100644 index 00000000..6d7e9f5e --- /dev/null +++ b/app/web-tools/drawio/mxgraph/src/shape/mxConnector.js @@ -0,0 +1,145 @@ +/** + * Copyright (c) 2006-2015, JGraph Ltd + * Copyright (c) 2006-2015, Gaudenz Alder + */ +/** + * Class: mxConnector + * + * Extends to implement a connector shape. The connector + * shape allows for arrow heads on either side. + * + * This shape is registered under in + * . + * + * Constructor: mxConnector + * + * Constructs a new connector shape. + * + * Parameters: + * + * points - Array of that define the points. This is stored in + * . + * stroke - String that defines the stroke color. This is stored in . + * Default is 'black'. + * strokewidth - Optional integer that defines the stroke width. Default is + * 1. This is stored in . + */ +function mxConnector(points, stroke, strokewidth) +{ + mxPolyline.call(this, points, stroke, strokewidth); +}; + +/** + * Extends mxPolyline. + */ +mxUtils.extend(mxConnector, mxPolyline); + +/** + * Function: updateBoundingBox + * + * Updates the for this shape using and + * and stores the result in . + */ +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.setShadow(false); + c.setDashed(false); + + if (sourceMarker != null) + { + c.setFillColor(mxUtils.getValue(this.style, + mxConstants.STYLE_STARTFILLCOLOR, this.stroke)); + sourceMarker(); + } + + if (targetMarker != null) + { + c.setFillColor(mxUtils.getValue(this.style, + mxConstants.STYLE_ENDFILLCOLOR, this.stroke)); + 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) + { + // Computes the norm and the inverse norm + var dx = pe.x - p0.x; + var dy = pe.y - p0.y; + var dist = 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); +}; diff --git a/app/web-tools/drawio/mxgraph/src/shape/mxCylinder.js b/app/web-tools/drawio/mxgraph/src/shape/mxCylinder.js new file mode 100644 index 00000000..aae12d99 --- /dev/null +++ b/app/web-tools/drawio/mxgraph/src/shape/mxCylinder.js @@ -0,0 +1,111 @@ +/** + * Copyright (c) 2006-2015, JGraph Ltd + * Copyright (c) 2006-2015, Gaudenz Alder + */ +/** + * Class: mxCylinder + * + * Extends to implement an cylinder shape. If a + * custom shape with one filled area and an overlay path is + * needed, then this shape's should be overridden. + * This shape is registered under + * in . + * + * Constructor: mxCylinder + * + * Constructs a new cylinder shape. + * + * Parameters: + * + * bounds - that defines the bounds. This is stored in + * . + * fill - String that defines the fill color. This is stored in . + * stroke - String that defines the stroke color. This is stored in . + * strokewidth - Optional integer that defines the stroke width. Default is + * 1. This is stored in . + */ +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; + +/** + * 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(); + + if (!this.outline || this.style == null || mxUtils.getValue( + this.style, mxConstants.STYLE_BACKGROUND_OUTLINE, 0) == 0) + { + c.setShadow(false); + c.begin(); + this.redrawPath(c, x, y, w, h, true); + c.stroke(); + } +}; + +/** + * Function: getCylinderSize + * + * Returns the cylinder size. + */ +mxCylinder.prototype.getCylinderSize = function(x, y, w, h) +{ + return Math.min(this.maxHeight, Math.round(h / 5)); +}; + +/** + * Function: redrawPath + * + * Draws the path for this shape. + */ +mxCylinder.prototype.redrawPath = function(c, x, y, w, h, isForeground) +{ + var dy = this.getCylinderSize(x, y, w, h); + + 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(); + } +}; diff --git a/app/web-tools/drawio/mxgraph/src/shape/mxDoubleEllipse.js b/app/web-tools/drawio/mxgraph/src/shape/mxDoubleEllipse.js new file mode 100644 index 00000000..ff528d57 --- /dev/null +++ b/app/web-tools/drawio/mxgraph/src/shape/mxDoubleEllipse.js @@ -0,0 +1,107 @@ +/** + * Copyright (c) 2006-2015, JGraph Ltd + * Copyright (c) 2006-2015, Gaudenz Alder + */ +/** + * Class: mxDoubleEllipse + * + * Extends to implement a double ellipse shape. This shape is + * registered under in . + * 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 - that defines the bounds. This is stored in + * . + * fill - String that defines the fill color. This is stored in . + * stroke - String that defines the stroke color. This is stored in . + * strokewidth - Optional integer that defines the stroke width. Default is + * 1. This is stored in . + */ +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); + +/** + * 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); +}; diff --git a/app/web-tools/drawio/mxgraph/src/shape/mxEllipse.js b/app/web-tools/drawio/mxgraph/src/shape/mxEllipse.js new file mode 100644 index 00000000..aef8df72 --- /dev/null +++ b/app/web-tools/drawio/mxgraph/src/shape/mxEllipse.js @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2006-2015, JGraph Ltd + * Copyright (c) 2006-2015, Gaudenz Alder + */ +/** + * Class: mxEllipse + * + * Extends to implement an ellipse shape. + * This shape is registered under + * in . + * + * Constructor: mxEllipse + * + * Constructs a new ellipse shape. + * + * Parameters: + * + * bounds - that defines the bounds. This is stored in + * . + * fill - String that defines the fill color. This is stored in . + * stroke - String that defines the stroke color. This is stored in . + * strokewidth - Optional integer that defines the stroke width. Default is + * 1. This is stored in . + */ +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(); +}; diff --git a/app/web-tools/drawio/mxgraph/src/shape/mxHexagon.js b/app/web-tools/drawio/mxgraph/src/shape/mxHexagon.js new file mode 100644 index 00000000..83f4fd69 --- /dev/null +++ b/app/web-tools/drawio/mxgraph/src/shape/mxHexagon.js @@ -0,0 +1,34 @@ +/** + * 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); +}; diff --git a/app/web-tools/drawio/mxgraph/src/shape/mxImageShape.js b/app/web-tools/drawio/mxgraph/src/shape/mxImageShape.js new file mode 100644 index 00000000..694c26e1 --- /dev/null +++ b/app/web-tools/drawio/mxgraph/src/shape/mxImageShape.js @@ -0,0 +1,258 @@ +/** + * Copyright (c) 2006-2015, JGraph Ltd + * Copyright (c) 2006-2015, Gaudenz Alder + */ +/** + * Class: mxImageShape + * + * Extends to implement an image shape. This shape is registered + * under in . + * + * Constructor: mxImageShape + * + * Constructs a new image shape. + * + * Parameters: + * + * bounds - that defines the bounds. This is stored in + * . + * image - String that specifies the URL of the image. This is stored in + * . + * fill - String that defines the fill color. This is stored in . + * stroke - String that defines the stroke color. This is stored in . + * strokewidth - Optional integer that defines the stroke width. Default is + * 0. This is stored in . + */ +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; +}; + +/** + * 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 to replace the fill and stroke colors with the + * respective values from and + * . + * + * Applies the style of the given to the shape. This + * implementation assigns the following styles to local fields: + * + * - => fill + * - => stroke + * + * Parameters: + * + * state - 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; + this.imageBackground = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_BACKGROUND, null); + this.imageBorder = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_BORDER, null); + + // 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; + + this.clipPath = mxUtils.getValue(this.style, mxConstants.STYLE_CLIP_PATH, null); + } +}; + +/** + * 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. + */ +mxImageShape.prototype.createHtml = function() +{ + var node = document.createElement('div'); + node.style.position = 'absolute'; + + return node; +}; + +/** + * Function: isRoundable + * + * Disables inherited roundable support. + */ +mxImageShape.prototype.isRoundable = function() +{ + return false; +}; + +/** + * Function: getImageDataUri + * + * Returns the image to be rendered. + */ +mxImageShape.prototype.getImageDataUri = function() +{ + return this.image; +}; + +/** + * Function: configurePointerEvents + * + * Configures the pointer events for the given canvas. + */ +mxImageShape.prototype.configurePointerEvents = function(c) +{ + // do nothing +}; + +/** + * Function: paintVertexShape + * + * Generic background painting implementation. + */ +mxImageShape.prototype.paintVertexShape = function(c, x, y, w, h) +{ + if (this.image != null) + { + if (this.imageBackground != null) + { + // Stroke rendering required for shadow + c.setFillColor(this.imageBackground); + c.setStrokeColor(this.imageBorder); + c.rect(x, y, w, h); + c.fillAndStroke(); + } + + // FlipH/V are implicit via mxShape.updateTransform + c.image(x, y, w, h, this.getImageDataUri(), this.preserveImageAspect, false, false, this.clipPath); + + if (this.imageBorder != null) + { + c.setShadow(false); + c.setStrokeColor(this.imageBorder); + c.rect(x, y, w, h); + c.stroke(); + } + } + else + { + mxRectangleShape.prototype.paintBackground.apply(this, arguments); + } +}; + +/** + * Function: redraw + * + * Overrides 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.innerText = ''; + + 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; + + var img = document.createElement('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); + } +}; diff --git a/app/web-tools/drawio/mxgraph/src/shape/mxLabel.js b/app/web-tools/drawio/mxgraph/src/shape/mxLabel.js new file mode 100644 index 00000000..a77dec10 --- /dev/null +++ b/app/web-tools/drawio/mxgraph/src/shape/mxLabel.js @@ -0,0 +1,277 @@ +/** + * Copyright (c) 2006-2015, JGraph Ltd + * Copyright (c) 2006-2015, Gaudenz Alder + */ +/** + * Class: mxLabel + * + * Extends to implement an image shape with a label. + * This shape is registered under in + * . + * + * Constructor: mxLabel + * + * Constructs a new label shape. + * + * Parameters: + * + * bounds - that defines the bounds. This is stored in + * . + * fill - String that defines the fill color. This is stored in . + * stroke - String that defines the stroke color. This is stored in . + * strokewidth - Optional integer that defines the stroke width. Default is + * 1. This is stored in . + */ +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 + * . + */ +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 . + */ +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; + this.indicator.redraw(); + } + + 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); + var clipPath = mxUtils.getValue(this.style, mxConstants.STYLE_CLIP_PATH, null); + c.image(bounds.x, bounds.y, bounds.width, bounds.height, this.image, false, false, false, clipPath); + } +}; + +/** + * 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); + } +}; diff --git a/app/web-tools/drawio/mxgraph/src/shape/mxLine.js b/app/web-tools/drawio/mxgraph/src/shape/mxLine.js new file mode 100644 index 00000000..7486a3cb --- /dev/null +++ b/app/web-tools/drawio/mxgraph/src/shape/mxLine.js @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2006-2015, JGraph Ltd + * Copyright (c) 2006-2015, Gaudenz Alder + */ +/** + * Class: mxLine + * + * Extends to implement a horizontal line shape. + * This shape is registered under in + * . + * + * Constructor: mxLine + * + * Constructs a new line shape. + * + * Parameters: + * + * bounds - that defines the bounds. This is stored in + * . + * stroke - String that defines the stroke color. Default is 'black'. This is + * stored in . + * strokewidth - Optional integer that defines the stroke width. Default is + * 1. This is stored in . + */ +function mxLine(bounds, stroke, strokewidth, vertical) +{ + mxShape.call(this); + this.bounds = bounds; + this.stroke = stroke; + this.strokewidth = (strokewidth != null) ? strokewidth : 1; + this.vertical = (vertical != null) ? vertical : this.vertical; +}; + +/** + * Extends mxShape. + */ +mxUtils.extend(mxLine, mxShape); + +/** + * Function: vertical + * + * Whether to paint a vertical line. + */ +mxLine.prototype.vertical = false; + +/** + * Function: paintVertexShape + * + * Redirects to redrawPath for subclasses to work. + */ +mxLine.prototype.paintVertexShape = function(c, x, y, w, h) +{ + c.begin(); + + if (this.vertical) + { + var mid = x + w / 2; + c.moveTo(mid, y); + c.lineTo(mid, y + h); + } + else + { + var mid = y + h / 2; + c.moveTo(x, mid); + c.lineTo(x + w, mid); + } + + c.stroke(); +}; diff --git a/app/web-tools/drawio/mxgraph/src/shape/mxMarker.js b/app/web-tools/drawio/mxgraph/src/shape/mxMarker.js new file mode 100644 index 00000000..9a585e64 --- /dev/null +++ b/app/web-tools/drawio/mxgraph/src/shape/mxMarker.js @@ -0,0 +1,293 @@ +/** + * Copyright (c) 2006-2015, JGraph Ltd + * Copyright (c) 2006-2015, Gaudenz Alder + */ +var mxMarker = +{ + /** + * Class: mxMarker + * + * A static class that implements all markers for 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(); + } + }; + }); + + mxMarker.addMarker('baseDash', function(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled) + { + var nx = unitX * (size + sw + 1); + var ny = unitY * (size + sw + 1); + + return function() + { + canvas.begin(); + canvas.moveTo(pe.x - ny / 2, pe.y + nx / 2); + canvas.lineTo(pe.x + ny / 2, pe.y - nx / 2); + canvas.stroke(); + }; + + }); + + mxMarker.addMarker('doubleBlock', function(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled) + { + var widthFactor = 2; + + 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 * 2 - endOffsetX; + pe.y += -unitY * f * 2 - endOffsetY; + + return function() + { + canvas.begin(); + canvas.moveTo(pt.x, pt.y); + canvas.lineTo(pt.x - unitX - unitY / widthFactor, pt.y - unitY + unitX / widthFactor); + canvas.lineTo(pt.x + unitY / widthFactor - unitX, pt.y - unitY - unitX / widthFactor); + canvas.close(); + canvas.moveTo(pt.x - unitX, pt.y - unitY); + canvas.lineTo(pt.x - 2 * unitX - 0.5 * unitY, pt.y + 0.5 * unitX - 2 * unitY); + canvas.lineTo(pt.x - 2 * unitX + 0.5 * unitY, pt.y - 0.5 * unitX - 2 * unitY); + canvas.close(); + + 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); + + mxMarker.addMarker('manyOptional', function(c, shape, type, pe, unitX, unitY, size, source, sw, filled) + { + var nx = unitX * (size + sw + 1); + var ny = unitY * (size + sw + 1); + var a = size / 2; + var px = pe.x; + var py = pe.y; + + pe.x -= 2 * nx - unitX * sw / 2; + pe.y -= 2 * ny - unitY * sw / 2; + + return function() + { + c.begin(); + c.ellipse(px - 1.5 * nx - a, py - 1.5 * ny - a, 2 * a, 2 * a); + filled ? c.fillAndStroke() : c.stroke(); + + c.begin(); + c.moveTo(px, py); + c.lineTo(px - nx, py - ny); + + c.moveTo(px + ny / 2, py - nx / 2); + c.lineTo(px - nx, py - ny); + c.lineTo(px - ny / 2, py + nx / 2); + + c.stroke(); + }; + }); +})(); diff --git a/app/web-tools/drawio/mxgraph/src/shape/mxPolyline.js b/app/web-tools/drawio/mxgraph/src/shape/mxPolyline.js new file mode 100644 index 00000000..72ddc244 --- /dev/null +++ b/app/web-tools/drawio/mxgraph/src/shape/mxPolyline.js @@ -0,0 +1,132 @@ +/** + * Copyright (c) 2006-2015, JGraph Ltd + * Copyright (c) 2006-2015, Gaudenz Alder + */ +/** + * Class: mxPolyline + * + * Extends to implement a polyline (a line with multiple points). + * This shape is registered under in + * . + * + * Constructor: mxPolyline + * + * Constructs a new polyline shape. + * + * Parameters: + * + * points - Array of that define the points. This is stored in + * . + * stroke - String that defines the stroke color. Default is 'black'. This is + * stored in . + * strokewidth - Optional integer that defines the stroke width. Default is + * 1. This is stored in . + */ +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) +{ + var prev = c.pointerEventsValue; + c.pointerEventsValue = 'stroke'; + + if (this.style == null || this.style[mxConstants.STYLE_CURVED] != 1) + { + this.paintLine(c, pts, this.isRounded); + } + else + { + this.paintCurvedLine(c, pts); + } + + c.pointerEventsValue = prev; +}; + +/** + * 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: paintCurvedLine + * + * Paints a curved line. + */ +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(); +}; diff --git a/app/web-tools/drawio/mxgraph/src/shape/mxRectangleShape.js b/app/web-tools/drawio/mxgraph/src/shape/mxRectangleShape.js new file mode 100644 index 00000000..333bd936 --- /dev/null +++ b/app/web-tools/drawio/mxgraph/src/shape/mxRectangleShape.js @@ -0,0 +1,111 @@ +/** + * Copyright (c) 2006-2015, JGraph Ltd + * Copyright (c) 2006-2015, Gaudenz Alder + */ +/** + * Class: mxRectangleShape + * + * Extends to implement a rectangle shape. + * This shape is registered under + * in . + * + * Constructor: mxRectangleShape + * + * Constructs a new rectangle shape. + * + * Parameters: + * + * bounds - that defines the bounds. This is stored in + * . + * fill - String that defines the fill color. This is stored in . + * stroke - String that defines the stroke color. This is stored in . + * strokewidth - Optional integer that defines the stroke width. Default is + * 1. This is stored in . + */ +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) +{ + 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: isRoundable + * + * Adds roundable support. + */ +mxRectangleShape.prototype.isRoundable = function() +{ + return true; +}; + +/** + * 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)); + } +}; diff --git a/app/web-tools/drawio/mxgraph/src/shape/mxRhombus.js b/app/web-tools/drawio/mxgraph/src/shape/mxRhombus.js new file mode 100644 index 00000000..1bb299d5 --- /dev/null +++ b/app/web-tools/drawio/mxgraph/src/shape/mxRhombus.js @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2006-2015, JGraph Ltd + * Copyright (c) 2006-2015, Gaudenz Alder + */ +/** + * Class: mxRhombus + * + * Extends to implement a rhombus (aka diamond) shape. + * This shape is registered under + * in . + * + * Constructor: mxRhombus + * + * Constructs a new rhombus shape. + * + * Parameters: + * + * bounds - that defines the bounds. This is stored in + * . + * fill - String that defines the fill color. This is stored in . + * stroke - String that defines the stroke color. This is stored in . + * strokewidth - Optional integer that defines the stroke width. Default is + * 1. This is stored in . + */ +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: isRoundable + * + * Adds roundable support. + */ +mxRhombus.prototype.isRoundable = function() +{ + return true; +}; + +/** + * 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(); +}; diff --git a/app/web-tools/drawio/mxgraph/src/shape/mxShape.js b/app/web-tools/drawio/mxgraph/src/shape/mxShape.js new file mode 100644 index 00000000..15bbf836 --- /dev/null +++ b/app/web-tools/drawio/mxgraph/src/shape/mxShape.js @@ -0,0 +1,1790 @@ +/** + * 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 and HTML. Which + * implementation to use is controlled by the + * property which is assigned from within the + * 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 rendering hint). + * + * For each supported shape in SVG, 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 and 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: forceFilledPointerEvents + * + * Specifies if pointerEvents should be forced for filled shapes. Default is + * false. + */ +mxShape.forceFilledPointerEvents = true; + +/** + * Variable: dialect + * + * Holds the dialect in which the shape is to be painted. + * This can be one of the DIALECT constants in . + */ +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: minSvgStrokeWidth + * + * Minimum stroke width for SVG output. + */ +mxShape.prototype.minSvgStrokeWidth = 1; + +/** + * Variable: bounds + * + * Holds the that specifies the bounds of this shape. + */ +mxShape.prototype.bounds = null; + +/** + * Variable: points + * + * Holds the array of 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 . + */ +mxShape.prototype.state = null; + +/** + * Variable: style + * + * Optional reference to the style of the corresponding . + */ +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 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 if 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: 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 . + */ +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 + * 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: 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 % 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 + * or depending container + * type. + * + * 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 + { + node = this.createHtml(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: createHtml + * + * Creates and returns the HTML DOM node(s) to represent + * this shape. + */ +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.redrawHtmlShape(); + } + else + { + this.redrawShape(); + } + } + 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.innerText = ''; + } +}; + +/** + * 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), this.scale, this.scale); + + 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), this.scale, this.scale)); + } + } + } +}; + +/** + * Function: getLabelBounds + * + * Returns the 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 , 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: getShadowStyle + * + * Removes all child nodes and resets all CSS. + */ +mxShape.prototype.getShadowStyle = function() +{ + var s = { + dx: mxConstants.SHADOW_OFFSET_X, + dy: mxConstants.SHADOW_OFFSET_Y, + blur: mxConstants.SHADOW_BLUR, + color: mxConstants.SHADOWCOLOR, + opacity: mxConstants.SHADOW_OPACITY * 100 + }; + + if (this.style != null) + { + s.dx = mxUtils.getValue(this.style, + mxConstants.STYLE_SHADOW_OFFSET_X, s.dx); + s.dy = mxUtils.getValue(this.style, + mxConstants.STYLE_SHADOW_OFFSET_Y, s.dy); + s.blur = mxUtils.getValue(this.style, + mxConstants.STYLE_SHADOW_BLUR, s.blur); + s.color = mxUtils.getValue(this.style, + mxConstants.STYLE_SHADOWCOLOR, s.color); + s.opacity = mxUtils.getValue(this.style, + mxConstants.STYLE_SHADOW_OPACITY, s.opacity); + } + + return s; +}; + +/** + * Function: createDropShadow + * + * Removes all child nodes and resets all CSS. + */ +mxShape.prototype.createDropShadow = function(style, scale) +{ + return 'drop-shadow(' + Math.round(style.dx * scale * 100) / 100 + 'px ' + + Math.round(style.dy * scale * 100) / 100 + 'px ' + + Math.round(style.blur * scale * 100) / 100 + 'px ' + + mxUtils.hex2rgba(style.color, style.opacity / 100) + ')'; +}; + +/** + * Function: updateSvgFilters + * + * Removes all child nodes and resets all CSS. + */ +mxShape.prototype.updateSvgFilters = function(scale) +{ + this.node.style.filter = (this.isShadowEnabled()) ? + this.createDropShadow(this.getShadowStyle(), scale) : ''; +}; + +/** + * Function: isShadowEnabled + * + * Removes all child nodes and resets all CSS. + */ +mxShape.prototype.isShadowEnabled = function() +{ + return this.isShadow; +}; + +/** + * Function: redrawShape + * + * Updates the SVG shape. + */ +mxShape.prototype.redrawShape = function() +{ + var canvas = this.createCanvas(); + + if (canvas != null) + { + // Specifies if events should be handled + canvas.pointerEvents = this.pointerEvents; + this.beforePaint(canvas); + this.paint(canvas); + this.afterPaint(canvas); + 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(); + } + + 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() {}; + canvas.text = function() {}; + } + + return canvas; +}; + +/** + * Function: createSvgCanvas + * + * Creates and returns an for rendering this shape. + */ +mxShape.prototype.createSvgCanvas = function() +{ + var canvas = new mxSvgCanvas2D(this.node, false); + canvas.strokeTolerance = this.svgStrokeTolerance; + canvas.pointerEventsValue = this.svgPointerEvents; + var off = this.getSvgScreenOffset(); + + if (off != 0) + { + this.node.setAttribute('transform', 'translate(' + off + ',' + off + ')'); + } + else + { + this.node.removeAttribute('transform'); + } + + canvas.minStrokeWidth = this.minSvgStrokeWidth; + + if (!this.antiAlias) + { + // Rounds all numbers in the SVG output to integers + canvas.format = function(value) + { + return Math.round(parseFloat(value)); + }; + } + + return canvas; +}; + +/** + * Function: redrawHtml + * + * Redraw HTML + */ +mxShape.prototype.redrawHtmlShape = function() +{ + // LATER: Refactor methods + this.updateHtmlBounds(this.node); + this.updateHtmlFilters(this.node); + this.updateHtmlColors(this.node); +}; + +/** + * Function: updateHtmlFilters + * + * Update HTML filters + */ +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: updateHtmlColors + * + * 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 + { + this.setTransparentBackgroundImage(node); + } +}; + +/** + * Function: updateHtmlBounds + * + * Allow optimization by replacing VML with HTML. + */ +mxShape.prototype.updateHtmlBounds = function(node) +{ + var sw = 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; + } + } + + for (var key in canvas.fillPatterns) + { + var pattern = canvas.fillPatterns[key]; + + if (pattern != null) + { + pattern.mxRefCount = (pattern.mxRefCount || 0) + 1; + } + } + + this.releaseSvgGradients(this.oldGradients); + this.releaseSvgFillPatterns(this.oldFillPatterns); + this.oldGradients = canvas.gradients; + this.oldFillPatterns = canvas.fillPatterns; + } +}; + +/** + * Function: beforePaint + * + * Invoked before paint is called. + */ +mxShape.prototype.beforePaint = function(c) { }; + +/** + * Function: afterPaint + * + * Invokes after paint was called. + */ +mxShape.prototype.afterPaint = function(c) { }; + +/** + * Function: paint + * + * Generic rendering code. + */ +mxShape.prototype.paint = function(c) +{ + var pointerEvents = c.pointerEvents; + var strokeDrawn = false; + + if (c != null && this.outline) + { + var stroke = c.stroke; + + c.stroke = function() + { + strokeDrawn = true; + stroke.apply(this, arguments); + }; + + var fillAndStroke = c.fillAndStroke; + + c.fillAndStroke = function() + { + strokeDrawn = true; + fillAndStroke.apply(this, arguments); + }; + } + + // 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); + this.updateSvgFilters((c != null) ? c.state.scale : s); + + // 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); + var pts = this.getWaypoints(); + + if (pts != null) + { + // Paints edge shape + if (pts.length > 1) + { + 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); + } + + // Draws highlight rectangle if no stroke was used + if (c != null && this.outline && !strokeDrawn) + { + c.rect(x, y, w, h); + c.stroke(); + } + + c.pointerEvents = pointerEvents; +}; + +/** + * Function: getWaypoints + * + * Returns the array of non-overlapping, unscaled points. + */ +mxShape.prototype.getWaypoints = function() +{ + var pts = this.points; + var result = null; + + if (pts != null) + { + result = []; + + if (pts.length > 0) + { + var s = this.scale; + var t = Math.max(s, 1); + var p0 = pts[0]; + result.push(new mxPoint(p0.x / s, p0.y / s)); + + for (var i = 1; i < pts.length; i++) + { + var pe = pts[i]; + + if (Math.abs(p0.x - pe.x) >= t || + Math.abs(p0.y - pe.y) >= t) + { + result.push(new mxPoint(pe.x / s, pe.y / s)); + } + + p0 = pe; + } + } + } + + return result; +}; + +/** + * 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, this.shadowStyle); + } + + // 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.setFillStyle(this.fillStyle); + } + + if (this.style != null) + { + if (this.style['linecap'] != null) + { + c.setLineCap(this.style['linecap']); + } + + if (this.style['linejoin'] != null) + { + c.setLineJoin(this.style['linejoin']); + } + } + + c.setStrokeColor(this.stroke); + this.configurePointerEvents(c); +}; + +/** + * Function: configurePointerEvents + * + * Configures the pointer events for the given canvas. + */ +mxShape.prototype.configurePointerEvents = function(c) +{ + if (this.style != null && (!mxShape.forceFilledPointerEvents || + (this.fill == null || this.fill == mxConstants.NONE || + this.opacity == 0 || this.fillOpacity == 0)) && + mxUtils.getValue(this.style, mxConstants.STYLE_POINTER_EVENTS, '1') == '0') + { + c.pointerEvents = false; + } +}; + +/** + * 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); + + if (!this.outline || this.style == null || mxUtils.getValue( + this.style, mxConstants.STYLE_BACKGROUND_OUTLINE, 0) == 0) + { + 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 to the shape. This + * implementation assigns the following styles to local fields: + * + * - => fill + * - => gradient + * - => gradientDirection + * - => opacity + * - => fillOpacity + * - => strokeOpacity + * - => stroke + * - => strokewidth + * - => isShadow + * - => isDashed + * - => spacing + * - => startSize + * - => endSize + * - => isRounded + * - => startArrow + * - => endArrow + * - => rotation + * - => direction + * - => glass + * + * This keeps a reference to the '; + + // Copies the contents of the graph container + html += '
'; + html += graph.container.innerHTML; + html += '
'; + + doc.writeln(html); + doc.close(); + } + else + { + doc.writeln(''); + + 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(''); + 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 - to be printed. + */ + printScreen: function(graph) + { + var wnd = window.open(); + 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 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,'
').replace(/ /g, ' '); + + 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('
'+mxUtils.htmlEntities(content)+'').replace(/ /g, ' ');
+			   	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  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 .
+	 * 
+	 * 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')); //  
+		div.appendChild(document.createTextNode('\u00a0')); //  
+		div.appendChild(document.createTextNode('\u00a0')); //  
+		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 . If
+	 *  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 -  that acts as the drop target or a function that takes a
+	 * mouse event and returns the current .
+	 * 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;
+	},
+
+	/**
+	 * Function: format
+	 * 
+	 * Rounds all numbers to 2 decimal points.
+	 */
+	format: function(value)
+	{
+		return parseFloat(parseFloat(value).toFixed(2));
+	}
+};
diff --git a/app/web-tools/drawio/mxgraph/src/util/mxWindow.js b/app/web-tools/drawio/mxgraph/src/util/mxWindow.js
new file mode 100644
index 00000000..4b46bf92
--- /dev/null
+++ b/app/web-tools/drawio/mxgraph/src/util/mxWindow.js
@@ -0,0 +1,1115 @@
+/**
+ * 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 event property contains
+ * the corresponding mouse event.
+ *
+ * Event: mxEvent.MOVE
+ *
+ * Fires while the window is being moved. The event property
+ * contains the corresponding mouse event.
+ *
+ * Event: mxEvent.MOVE_END
+ *
+ * Fires after the window is moved. The event property contains
+ * the corresponding mouse event.
+ *
+ * Event: mxEvent.RESIZE_START
+ *
+ * Fires before the window is resized. The event property contains
+ * the corresponding mouse event.
+ *
+ * Event: mxEvent.RESIZE
+ *
+ * Fires while the window is being resized. The event property
+ * contains the corresponding mouse event.
+ *
+ * Event: mxEvent.RESIZE_END
+ *
+ * Fires after the window is resized. The event property contains
+ * the corresponding mouse event.
+ *
+ * Event: mxEvent.MAXIMIZE
+ * 
+ * Fires after the window is maximized. The event property
+ * contains the corresponding mouse event.
+ * 
+ * Event: mxEvent.MINIMIZE
+ * 
+ * Fires after the window is minimized. The event 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 event property contains the
+ * corresponding mouse event.
+ *  
+ * Event: mxEvent.ACTIVATE
+ * 
+ * Fires after a window is activated. The previousWindow 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 event 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: resizeImage
+ * 
+ * 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
+ * 
+ *  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 . 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)
+	{
+		this.div.style.width = width + 'px'; 
+		this.table.style.width = width + 'px';
+	} 
+	
+	if (height != null)
+	{
+		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 (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 == null ||
+		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 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 = '0px';
+			this.resize.style.right = '0px';
+			this.resize.style.zIndex = '2';
+
+			this.resize.setAttribute('src', this.resizeImage);
+			this.resize.style.cursor = 'nwse-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
+	this.div.style.width =  width + 'px';
+	this.div.style.height = height + 'px';
+	
+	this.table.style.width =  width + 'px';
+	this.table.style.height = height + 'px';
+
+	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.minimizeImg.style.display = (minimizable) ? '' : 'none';
+};
+
+/**
+ * Function: getMinimumSize
+ * 
+ * Returns an  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: toggleMinimized
+ * 
+ * Minimizes the window.
+ */
+mxWindow.prototype.toggleMinimized = function(evt)
+{
+	this.activate();
+	
+	if (!this.minimized)
+	{
+		this.minimized = true;
+		
+		this.minimizeImg.setAttribute('src', this.normalizeImage);
+		this.minimizeImg.setAttribute('title', 'Normalize');
+		this.contentWrapper.style.display = 'none';
+		this.maxDisplay = this.maximize.style.display;
+		
+		this.maximize.style.display = 'none';
+		this.height = this.table.style.height;
+		
+		var minSize = this.getMinimumSize();
+		
+		if (minSize.height > 0)
+		{
+			this.div.style.height = minSize.height + 'px';
+			this.table.style.height = minSize.height + 'px';
+		}
+		
+		if (minSize.width > 0)
+		{
+			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
+	{
+		this.minimized = false;
+		
+		this.minimizeImg.setAttribute('src', this.minimizeImage);
+		this.minimizeImg.setAttribute('title', 'Minimize');
+		this.contentWrapper.style.display = ''; // default
+		this.maximize.style.display = this.maxDisplay;
+		
+		this.div.style.height = this.height;
+		this.table.style.height = this.height;
+
+		if (this.resize != null)
+		{
+			this.resize.style.visibility = '';
+		}
+		
+		this.fireEvent(new mxEventObject(mxEvent.NORMALIZE, 'event', evt));
+	}
+};
+
+/**
+ * Function: installMinimizeHandler
+ * 
+ * Installs the event listeners required for minimizing the window.
+ */
+mxWindow.prototype.installMinimizeHandler = function()
+{
+	this.minimizeImg = document.createElement('img');
+	
+	this.minimizeImg.setAttribute('src', this.minimizeImage);
+	this.minimizeImg.setAttribute('title', 'Minimize');
+	this.minimizeImg.style.cursor = 'pointer';
+	this.minimizeImg.style.marginLeft = '2px';
+	this.minimizeImg.style.display = 'none';
+	
+	this.buttons.appendChild(this.minimizeImg);
+	
+	this.minimized = false;
+	this.maxDisplay = null;
+	this.height = null;
+
+	var funct = mxUtils.bind(this, function(evt)
+	{
+		this.toggleMinimized(evt);
+		mxEvent.consume(evt);
+	});
+	
+	mxEvent.addGestureListeners(this.minimizeImg, 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.minimizeImg.style.display;
+				this.minimizeImg.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);
+
+				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';
+				}
+
+				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.minimizeImg.style.display = minDisplay;
+
+				// Restores window state
+				this.div.style.left = x+'px';
+				this.div.style.top = y+'px';
+
+				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  as a new image node in  and installs the
+ *  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)
+	{
+		if (this.isVisible() != visible)
+		{
+			if (visible)
+			{
+				this.show();
+			}
+			else
+			{
+				this.hide();
+			}
+		}
+		else
+		{
+			this.fireEvent(new mxEventObject((visible) ?
+				mxEvent.SHOW : mxEvent.HIDE));
+		}
+	}
+};
+
+/**
+ * Function: show
+ *
+ * Shows the window.
+ */
+mxWindow.prototype.show = function()
+{
+	this.div.style.display = '';
+	this.activate();
+	
+	var style = mxUtils.getCurrentStyle(this.contentWrapper);
+	
+	if ((style.overflow == 'auto' || this.resize != null) &&
+		this.contentWrapper.style.display != 'none')
+	{
+		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
+ *  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;
+};
diff --git a/app/web-tools/drawio/mxgraph/src/util/mxXmlCanvas2D.js b/app/web-tools/drawio/mxgraph/src/util/mxXmlCanvas2D.js
new file mode 100644
index 00000000..e335a137
--- /dev/null
+++ b/app/web-tools/drawio/mxgraph/src/util/mxXmlCanvas2D.js
@@ -0,0 +1,1216 @@
+/**
+ * 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:
+ * 
+ * - , 
+ * - , , 
+ * - , , , , ,
+ *   , , , , , 
+ *   , 
+ * - , , , ,
+ *   , 
+ * - , , , 
+ * - , , , , 
+ * - , , , , 
+ * - , , 
+ * 
+ *  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 :
+ */
+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 .
+ */
+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.) // TODO, no longer a limit
+ * 
+ * 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 , ,
+ *  or .
+ * 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 .
+ * 
+ * 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 .
+ * 
+ * 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 .
+ */
+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 .
+ * 
+ * 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 .
+ * 
+ * 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. 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'));
+};
diff --git a/app/web-tools/drawio/mxgraph/src/util/mxXmlRequest.js b/app/web-tools/drawio/mxgraph/src/util/mxXmlRequest.js
new file mode 100644
index 00000000..62bc49d4
--- /dev/null
+++ b/app/web-tools/drawio/mxgraph/src/util/mxXmlRequest.js
@@ -0,0 +1,475 @@
+/**
+ * Copyright (c) 2006-2020, JGraph Ltd
+ * Copyright (c) 2006-2020, draw.io AG
+ */
+/**
+ * Class: mxXmlRequest
+ * 
+ * XML HTTP request wrapper. See also: ,  and
+ * . 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  the
+ *  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.
+ * 
+ * 
+ * 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", "
");
+ * (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 . Defaults to false for backwards compatibility,
+ * to avoid another decode on the server this should be set to true.
+ */
+mxXmlRequest.prototype.decodeSimulateValues = false;
+
+/**
+ * Variable: acceptResponse
+ * 
+ * Specifies if the response has been processed with onload or onerror.
+ */
+mxXmlRequest.prototype.acceptResponse = true;
+
+/**
+ * Function: isBinary
+ * 
+ * Returns .
+ */
+mxXmlRequest.prototype.isBinary = function()
+{
+	return this.binary;
+};
+
+/**
+ * Function: setBinary
+ * 
+ * Sets .
+ */
+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  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: 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 != null) ? this.request.status : null;
+};
+
+/**
+ * Function: create
+ * 
+ * Creates and returns the inner  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  to the target URL using the specified functions to
+ * process the response asychronously.
+ * 
+ * Note: Due to technical limitations, onerror is currently ignored.
+ * 
+ * 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() && this.acceptResponse)
+				{
+					this.acceptResponse = false;
+					onload(this);
+					this.request.onreadystatechange = 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 (onerror != null)
+		{
+			this.request.onerror = mxUtils.bind(this, function(e)
+			{
+				if (this.acceptResponse)
+				{
+					this.acceptResponse = false;
+					onerror(this, e);
+				}
+			});
+		}
+		
+		if ((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  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 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;
+	}
+};
diff --git a/app/web-tools/drawio/mxgraph/src/view/mxCellEditor.js b/app/web-tools/drawio/mxgraph/src/view/mxCellEditor.js
new file mode 100644
index 00000000..e29a6460
--- /dev/null
+++ b/app/web-tools/drawio/mxgraph/src/view/mxCellEditor.js
@@ -0,0 +1,1076 @@
+/**
+ * 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
+ * ,  and
+ * . If  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.
+ * 
+ * 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
+ *  variable.
+ * 
+ * Resize in Chrome:
+ * 
+ * Resize of the textarea is disabled by default. If you want to enable
+ * this feature extend  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 .
+ */
+function mxCellEditor(graph)
+{
+	this.graph = graph;
+	
+	// Stops editing after zoom changes
+	this.zoomHandler = mxUtils.bind(this, function()
+	{
+		if (this.graph.isEditing())
+		{
+			this.resize();
+		}
+	});
+	
+	// Reposition after scrolling
+	if (this.graph.container != null)
+	{
+		mxEvent.addListener(this.graph.container, 'scroll', this.zoomHandler);
+	}
+
+	this.graph.view.addListener(mxEvent.SCALE_AND_TRANSLATE, this.zoomHandler);
+	this.graph.view.addListener(mxEvent.SCALE, this.zoomHandler);
+
+	// Adds handling of deleted cells while editing
+	this.changeHandler = mxUtils.bind(this, function(sender)
+	{
+		if (this.editingCell != null)
+		{
+			var state = this.graph.getView().getState(this.editingCell);
+
+			if (state == null)
+			{
+				this.stopEditing(true);
+			}
+			else
+			{
+				this.updateTextAreaStyle(state);
+			}
+		}
+	});
+
+	this.graph.getModel().addListener(mxEvent.CHANGE, this.changeHandler);
+};
+
+/**
+ * Variable: graph
+ * 
+ * Reference to the enclosing .
+ */
+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 .
+ */
+mxCellEditor.prototype.textarea = null;
+
+/**
+ * Variable: editingCell
+ * 
+ * Reference to the  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: rotateText
+ * 
+ * Specifies if text editing should allow rotated text. Default is true.
+ */
+mxCellEditor.prototype.rotateText = true;
+
+/**
+ * Variable: emptyLabelText
+ * 
+ * Text to be displayed for empty labels. Default is '' or '
' 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) ? '
' : ''; + +/** + * 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 = null; + +/** + * Variable: zIndex + * + * Specifies the zIndex for the textarea. Default is 1. + */ +mxCellEditor.prototype.zIndex = 1; + +/** + * Variable: minResize + * + * Defines the minimum width and height to be used in . Default is 0x20px. + */ +mxCellEditor.prototype.minResize = new mxRectangle(0, 20); + +/** + * Variable: blurEnabled + * + * If should be called if