├── .eslintignore ├── .eslintrc ├── .gitattributes ├── .github └── FUNDING.yml ├── .gitignore ├── .npmrc ├── CHANGELOG.md ├── LICENSE ├── README.md ├── archimate-font ├── LICENSE ├── README.md ├── lib │ ├── LICENSE.txt │ ├── README.txt │ ├── config.json │ ├── css │ │ ├── animation.css │ │ ├── archimate-font-codes.css │ │ ├── archimate-font-embedded.css │ │ ├── archimate-font-ie7-codes.css │ │ ├── archimate-font-ie7.css │ │ └── archimate-font.css │ ├── demo.html │ └── font │ │ ├── archimate-font.eot │ │ ├── archimate-font.svg │ │ ├── archimate-font.ttf │ │ ├── archimate-font.woff │ │ └── archimate-font.woff2 ├── package.json └── src │ ├── relations │ ├── relation-access-read.svg │ ├── relation-access-readwrite.svg │ ├── relation-access-write.svg │ ├── relation-access.svg │ ├── relation-aggregation.svg │ ├── relation-assignment.old.svg │ ├── relation-assignment.svg │ ├── relation-association-direct.svg │ ├── relation-association.svg │ ├── relation-composition.svg │ ├── relation-flow.old.svg │ ├── relation-flow.svg │ ├── relation-influence.svg │ ├── relation-junction-2.svg │ ├── relation-junction.svg │ ├── relation-line.svg │ ├── relation-multi.svg │ ├── relation-realization.svg │ ├── relation-serving.old.svg │ ├── relation-serving.svg │ ├── relation-specialization.svg │ ├── relation-triggering.old.svg │ └── relation-triggering.svg │ ├── tool-gear-thin.svg │ ├── tool-gear.svg │ ├── tool-note-2.svg │ ├── tool-note-3.svg │ └── tool-note.svg ├── assets ├── archimate-js.css ├── font-awesome-5 │ ├── 29f589f173dcc69ef6c805b711894998.eot │ ├── 29f589f173dcc69ef6c805b711894998.svg │ ├── 29f589f173dcc69ef6c805b711894998.ttf │ ├── 29f589f173dcc69ef6c805b711894998.woff │ └── 29f589f173dcc69ef6c805b711894998.woff2 ├── ibm-plex-font │ ├── IBMPlexSans-Bold.ttf │ ├── IBMPlexSans-BoldItalic.ttf │ ├── IBMPlexSans-ExtraLight.ttf │ ├── IBMPlexSans-ExtraLightItalic.ttf │ ├── IBMPlexSans-Italic.ttf │ ├── IBMPlexSans-Light.ttf │ ├── IBMPlexSans-LightItalic.ttf │ ├── IBMPlexSans-Medium.ttf │ ├── IBMPlexSans-MediumItalic.ttf │ ├── IBMPlexSans-Regular.ttf │ ├── IBMPlexSans-SemiBold.ttf │ ├── IBMPlexSans-SemiBoldItalic.ttf │ ├── IBMPlexSans-Thin.ttf │ ├── IBMPlexSans-ThinItalic.ttf │ └── OFL.txt ├── icons │ ├── application_collaboration.svg │ ├── application_component.svg │ ├── application_data_object.svg │ ├── application_event.svg │ ├── application_function.svg │ ├── application_interaction.svg │ ├── application_interface.svg │ ├── application_process.svg │ ├── application_service.svg │ ├── archive │ │ ├── application_function.svg │ │ ├── application_interface.svg │ │ ├── application_process.svg │ │ ├── business_actor.old.svg │ │ ├── business_actor_1px.svg │ │ ├── business_actor_nc.svg │ │ ├── business_collaboration.old.svg │ │ ├── business_collaboration_nc.svg │ │ ├── business_function.old.svg │ │ ├── business_function_nc.svg │ │ ├── business_interaction.old.svg │ │ ├── business_interaction_nc.svg │ │ ├── business_interface.old.svg │ │ ├── business_interface_nc.svg │ │ ├── business_process.old.svg │ │ └── business_process_nc.svg │ ├── business_actor.svg │ ├── business_collaboration.svg │ ├── business_contract.svg │ ├── business_event.svg │ ├── business_function.svg │ ├── business_interaction.svg │ ├── business_interface.svg │ ├── business_object.svg │ ├── business_process.svg │ ├── business_product.svg │ ├── business_representation.svg │ ├── business_role.svg │ ├── business_service.svg │ ├── group.svg │ ├── image.svg │ ├── note-ok.svg │ ├── note.svg │ ├── note_old.svg │ ├── relation-aggregation.svg │ ├── strategy_capability.svg │ ├── strategy_course_of_action.svg │ ├── strategy_resource.svg │ ├── strategy_value_stream.svg │ ├── technology_artifact.svg │ ├── technology_collaboration.svg │ ├── technology_communication_network.svg │ ├── technology_device.svg │ ├── technology_event.svg │ ├── technology_function.svg │ ├── technology_interaction.svg │ ├── technology_interface.svg │ ├── technology_node.svg │ ├── technology_path.svg │ ├── technology_process.svg │ ├── technology_service.svg │ ├── technology_system_software.svg │ ├── tool_hand.svg │ ├── tool_hand_r.svg │ ├── tool_select.svg │ ├── tool_select_r.svg │ └── tool_space.svg └── palette-icons.css ├── index.js ├── lib ├── .eslintrc ├── BaseModeler.js ├── BaseViewer.js ├── Modeler.js ├── NavigatedViewer.js ├── Viewer.js ├── core │ └── index.js ├── draw │ ├── ArchimateRenderer.js │ ├── ArchimateRendererUtil.js │ ├── PathMap.js │ ├── TextRenderer.js │ └── index.js ├── features │ ├── auto-place │ │ ├── ArchimateAutoPlace.js │ │ ├── ArchimateAutoPlaceUtil.js │ │ └── index.js │ ├── canvas-create │ │ ├── CanvasCreate.js │ │ └── index.js │ ├── context-pad │ │ ├── ContextPadProvider.js │ │ └── index.js │ ├── copy-paste │ │ ├── ArchimateCopyPaste.js │ │ ├── ModdleCopy.js │ │ └── index.js │ ├── editor-actions │ │ ├── ArchimateEditorActions.js │ │ └── index.js │ ├── keyboard │ │ ├── ArchimateKeyboardBindings.js │ │ └── index.js │ ├── label-editing │ │ ├── LabelEditingPreview.js │ │ ├── LabelEditingProvider.js │ │ ├── LabelUtil.js │ │ ├── cmd │ │ │ └── UpdateLabelHandler.js │ │ └── index.js │ ├── modeling │ │ ├── ArchimateFactory.js │ │ ├── ArchimateLayouter.js │ │ ├── ConnectionUpdater.js │ │ ├── ElementFactory.js │ │ ├── Modeling.js │ │ ├── NodeUpdater.js │ │ ├── behavior │ │ │ ├── AdaptiveLabelPositioningBehavior.js │ │ │ ├── AppendBehavior.js │ │ │ ├── AttachmentBehavior.js │ │ │ ├── ConnectionToConnectionBehavior.js │ │ │ ├── FixHoverBehavior.js │ │ │ ├── ImportDockingFix.js │ │ │ ├── LabelBehavior.js │ │ │ ├── ReplaceElementBehaviour.js │ │ │ ├── UnclaimIdBehavior.js │ │ │ ├── index.js │ │ │ └── util │ │ │ │ ├── ConnectionLayoutUtil.js │ │ │ │ ├── GeometricUtil.js │ │ │ │ ├── LabelLayoutUtil.js │ │ │ │ ├── LayoutUtil.js │ │ │ │ ├── LineAttachmentUtil.js │ │ │ │ └── LineIntersect.js │ │ ├── cmd │ │ │ ├── IdClaimHandler.js │ │ │ ├── ReplaceElementRefHandler.js │ │ │ ├── ReplaceRelationshipRefHandler.js │ │ │ ├── SetColorHandler.js │ │ │ ├── UpdateCanvasRootHandler.js │ │ │ ├── UpdateModdlePropertiesHandler.js │ │ │ ├── UpdatePropertiesHandler.js │ │ │ └── UpdateStyleHandler.js │ │ └── index.js │ ├── ordering │ │ ├── ArchimateOrdering.js │ │ ├── ArchimateOrderingProvider.js │ │ └── index.js │ ├── palette │ │ ├── PaletteProvider.js │ │ └── index.js │ ├── popup-menu │ │ ├── ConnectionMenuProvider.js │ │ ├── ConnectionOptions.js │ │ ├── ElementRefMenuProvider.js │ │ ├── TextMenuProvider.js │ │ └── index.js │ ├── replace-preview │ │ ├── ArchimateReplacePreview.js │ │ └── index.js │ ├── replace │ │ ├── ArchimateReplace.js │ │ ├── ReplaceOptions.js │ │ └── index.js │ ├── rules │ │ ├── ArchimateRules.js │ │ └── index.js │ └── snapping │ │ ├── ArchimateCreateMoveSnapping.js │ │ ├── SnappingUtil.js │ │ └── index.js ├── import │ ├── ArchimateImporter.js │ ├── Importer.js │ ├── Util.js │ └── index.js ├── metamodel │ ├── ApplicationRelationshipMap.js │ ├── BusinessRelationshipMap.js │ ├── Concept.js │ ├── ImpMigRelationshipMap.js │ ├── MotivationRelationshipMap.js │ ├── OtherRelationshipMap.js │ ├── PhysicalRelationshipMap.js │ ├── RelationshipRelationshipMap.js │ ├── StrategyRelationshipMap.js │ └── TechnologyRelationshipMap.js ├── moddle │ ├── Moddle.js │ ├── index.js │ └── resources │ │ └── archimate.json └── util │ ├── ColorUtil.js │ ├── ElementUtil.js │ ├── FileUtil.js │ ├── LabelUtil.js │ ├── Logger.js │ ├── ModelUtil.js │ ├── RelationshipUtil.js │ └── ScreenUtil.js └── package.json /.eslintignore: -------------------------------------------------------------------------------- 1 | coverage 2 | dist 3 | example 4 | node_modules 5 | *.json 6 | assets 7 | extension-experiments -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "plugin:bpmn-io/es6", 3 | "env": { 4 | "browser": true 5 | }, 6 | "globals": { 7 | "Promise": true, 8 | "Sentry": true 9 | } 10 | } -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | *.{cmd,[cC][mM][dD]} text eol=crlf 3 | *.{bat,[bB][aA][tT]} text eol=crlf -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: vbo75 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | coverage/ 4 | .idea 5 | *.iml 6 | .DS_Store -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## 0.0.4 8 | 9 | * `FEAT`: text properties supported 10 | * Vertical alignment 11 | * Horizontal alignment 12 | * Bold 13 | * `CORE`: all ArchiMate elements from Strategy, Business, Application and Technolgy layers supported 14 | * `CORE`: all ArchiMate relationships supported except Junction 15 | 16 | ## 0.0.3 17 | 18 | Initial release 19 | 20 | * `FEAT`: create Note 21 | * `CORE`: ArchiMate elements supported 22 | * Bussiness layer : Actor, Interface, Function, Process 23 | * Application layer : Interface, Function, Process 24 | * Technology layer : Interface, Function, Process 25 | * `CORE`: ArchiMate relationships supported 26 | * Association 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Vincent Boulet 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # archimate-js 2 | 3 | Create an ArchiMate® diagrams modeler builds on [diagram-js](https://github.com/bpmn-io/diagram-js) modeler engine from [bpmn.io](https://bpmn.io/) project. 4 | 5 | ArchiMate® is a registered trademark of [The Open Group](https://www.opengroup.org/archimate-forum/archimate-overview). 6 | 7 | ## Features 8 | 9 | * Create/modify ArchiMate® models and views 10 | * Import/export ArchiMate® model in XML format 11 | -------------------------------------------------------------------------------- /archimate-font/LICENSE: -------------------------------------------------------------------------------- 1 | SIL OPEN FONT LICENSE 2 | Version 1.1 - 26 February 2007 3 | 4 | PREAMBLE 5 | The goals of the Open Font License (OFL) are to stimulate worldwide 6 | development of collaborative font projects, to support the font creation 7 | efforts of academic and linguistic communities, and to provide a free and 8 | open framework in which fonts may be shared and improved in partnership 9 | with others. 10 | 11 | The OFL allows the licensed fonts to be used, studied, modified and 12 | redistributed freely as long as they are not sold by themselves. The 13 | fonts, including any derivative works, can be bundled, embedded, 14 | redistributed and/or sold with any software provided that any reserved 15 | names are not used by derivative works. The fonts and derivatives, 16 | however, cannot be released under any other type of license. The 17 | requirement for fonts to remain under this license does not apply 18 | to any document created using the fonts or their derivatives. 19 | 20 | DEFINITIONS 21 | "Font Software" refers to the set of files released by the Copyright 22 | Holder(s) under this license and clearly marked as such. This may 23 | include source files, build scripts and documentation. 24 | 25 | "Reserved Font Name" refers to any names specified as such after the 26 | copyright statement(s). 27 | 28 | "Original Version" refers to the collection of Font Software components as 29 | distributed by the Copyright Holder(s). 30 | 31 | "Modified Version" refers to any derivative made by adding to, deleting, 32 | or substituting — in part or in whole — any of the components of the 33 | Original Version, by changing formats or by porting the Font Software to a 34 | new environment. 35 | 36 | "Author" refers to any designer, engineer, programmer, technical 37 | writer or other person who contributed to the Font Software. 38 | 39 | PERMISSION & CONDITIONS 40 | Permission is hereby granted, free of charge, to any person obtaining 41 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 42 | redistribute, and sell modified and unmodified copies of the Font 43 | Software, subject to the following conditions: 44 | 45 | 1) Neither the Font Software nor any of its individual components, 46 | in Original or Modified Versions, may be sold by itself. 47 | 48 | 2) Original or Modified Versions of the Font Software may be bundled, 49 | redistributed and/or sold with any software, provided that each copy 50 | contains the above copyright notice and this license. These can be 51 | included either as stand-alone text files, human-readable headers or 52 | in the appropriate machine-readable metadata fields within text or 53 | binary files as long as those fields can be easily viewed by the user. 54 | 55 | 3) No Modified Version of the Font Software may use the Reserved Font 56 | Name(s) unless explicit written permission is granted by the corresponding 57 | Copyright Holder. This restriction only applies to the primary font name as 58 | presented to the users. 59 | 60 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 61 | Software shall not be used to promote, endorse or advertise any 62 | Modified Version, except to acknowledge the contribution(s) of the 63 | Copyright Holder(s) and the Author(s) or with their explicit written 64 | permission. 65 | 66 | 5) The Font Software, modified or unmodified, in part or in whole, 67 | must be distributed entirely under this license, and must not be 68 | distributed under any other license. The requirement for fonts to 69 | remain under this license does not apply to any document created 70 | using the Font Software. 71 | 72 | TERMINATION 73 | This license becomes null and void if any of the above conditions are 74 | not met. 75 | 76 | DISCLAIMER 77 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 78 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 79 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 80 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 81 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 82 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 83 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 84 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 85 | OTHER DEALINGS IN THE FONT SOFTWARE. 86 | 87 | -------------------------------------------------------------------------------- /archimate-font/README.md: -------------------------------------------------------------------------------- 1 | # archimate-font 2 | An ArchiMate symbol font for archimate-js. 3 | 4 | ## How-to 5 | - SVG graphics drawn with [SVG Path Editor](https://yqnn.github.io/svg-path-editor/). SVG graphics are in 2048x2048 pixel. 6 | - Archimate font powered by [fontello](https://fontello.com/) project. Baseline is 15%. 7 | 8 | ### Delete horizontal margin 9 | Comment 'margin-left: .2em;' and 'margin-right: .2em;' lines in archimate-font.css and archimate-font-embedded.css files. 10 | 11 | ## License 12 | SIL License: [OFL-1.1](https://scripts.sil.org/OFL) 13 | -------------------------------------------------------------------------------- /archimate-font/lib/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Font license info 2 | 3 | 4 | ## Font Awesome 5 | 6 | Copyright (C) 2016 by Dave Gandy 7 | 8 | Author: Dave Gandy 9 | License: SIL () 10 | Homepage: http://fortawesome.github.com/Font-Awesome/ 11 | 12 | 13 | -------------------------------------------------------------------------------- /archimate-font/lib/README.txt: -------------------------------------------------------------------------------- 1 | This webfont is generated by https://fontello.com open source project. 2 | 3 | 4 | ================================================================================ 5 | Please, note, that you should obey original font licenses, used to make this 6 | webfont pack. Details available in LICENSE.txt file. 7 | 8 | - Usually, it's enough to publish content of LICENSE.txt file somewhere on your 9 | site in "About" section. 10 | 11 | - If your project is open-source, usually, it will be ok to make LICENSE.txt 12 | file publicly available in your repository. 13 | 14 | - Fonts, used in Fontello, don't require a clickable link on your site. 15 | But any kind of additional authors crediting is welcome. 16 | ================================================================================ 17 | 18 | 19 | Comments on archive content 20 | --------------------------- 21 | 22 | - /font/* - fonts in different formats 23 | 24 | - /css/* - different kinds of css, for all situations. Should be ok with 25 | twitter bootstrap. Also, you can skip style and assign icon classes 26 | directly to text elements, if you don't mind about IE7. 27 | 28 | - demo.html - demo file, to show your webfont content 29 | 30 | - LICENSE.txt - license info about source fonts, used to build your one. 31 | 32 | - config.json - keeps your settings. You can import it back into fontello 33 | anytime, to continue your work 34 | 35 | 36 | Why so many CSS files ? 37 | ----------------------- 38 | 39 | Because we like to fit all your needs :) 40 | 41 | - basic file, .css - is usually enough, it contains @font-face 42 | and character code definitions 43 | 44 | - *-ie7.css - if you need IE7 support, but still don't wish to put char codes 45 | directly into html 46 | 47 | - *-codes.css and *-ie7-codes.css - if you like to use your own @font-face 48 | rules, but still wish to benefit from css generation. That can be very 49 | convenient for automated asset build systems. When you need to update font - 50 | no need to manually edit files, just override old version with archive 51 | content. See fontello source code for examples. 52 | 53 | - *-embedded.css - basic css file, but with embedded WOFF font, to avoid 54 | CORS issues in Firefox and IE9+, when fonts are hosted on the separate domain. 55 | We strongly recommend to resolve this issue by `Access-Control-Allow-Origin` 56 | server headers. But if you ok with dirty hack - this file is for you. Note, 57 | that data url moved to separate @font-face to avoid problems with 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/relations/relation-access-readwrite.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/relations/relation-access-write.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/relations/relation-access.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/relations/relation-aggregation.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/relations/relation-assignment.old.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/relations/relation-assignment.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/relations/relation-association-direct.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/relations/relation-association.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/relations/relation-composition.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/relations/relation-flow.old.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/relations/relation-flow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/relations/relation-influence.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/relations/relation-junction-2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/relations/relation-junction.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/relations/relation-line.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/relations/relation-multi.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/relations/relation-realization.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/relations/relation-serving.old.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/relations/relation-serving.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/relations/relation-specialization.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/relations/relation-triggering.old.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/relations/relation-triggering.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/tool-gear-thin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/tool-gear.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/tool-note-2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/tool-note-3.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /archimate-font/src/tool-note.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 15 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /assets/font-awesome-5/29f589f173dcc69ef6c805b711894998.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archimodel/archimate-js/9c73897140199e0071dafcc6cd5e513ffb2dfc2a/assets/font-awesome-5/29f589f173dcc69ef6c805b711894998.eot -------------------------------------------------------------------------------- /assets/font-awesome-5/29f589f173dcc69ef6c805b711894998.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archimodel/archimate-js/9c73897140199e0071dafcc6cd5e513ffb2dfc2a/assets/font-awesome-5/29f589f173dcc69ef6c805b711894998.ttf -------------------------------------------------------------------------------- /assets/font-awesome-5/29f589f173dcc69ef6c805b711894998.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archimodel/archimate-js/9c73897140199e0071dafcc6cd5e513ffb2dfc2a/assets/font-awesome-5/29f589f173dcc69ef6c805b711894998.woff -------------------------------------------------------------------------------- /assets/font-awesome-5/29f589f173dcc69ef6c805b711894998.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archimodel/archimate-js/9c73897140199e0071dafcc6cd5e513ffb2dfc2a/assets/font-awesome-5/29f589f173dcc69ef6c805b711894998.woff2 -------------------------------------------------------------------------------- /assets/ibm-plex-font/IBMPlexSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archimodel/archimate-js/9c73897140199e0071dafcc6cd5e513ffb2dfc2a/assets/ibm-plex-font/IBMPlexSans-Bold.ttf -------------------------------------------------------------------------------- /assets/ibm-plex-font/IBMPlexSans-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archimodel/archimate-js/9c73897140199e0071dafcc6cd5e513ffb2dfc2a/assets/ibm-plex-font/IBMPlexSans-BoldItalic.ttf -------------------------------------------------------------------------------- /assets/ibm-plex-font/IBMPlexSans-ExtraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archimodel/archimate-js/9c73897140199e0071dafcc6cd5e513ffb2dfc2a/assets/ibm-plex-font/IBMPlexSans-ExtraLight.ttf -------------------------------------------------------------------------------- /assets/ibm-plex-font/IBMPlexSans-ExtraLightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archimodel/archimate-js/9c73897140199e0071dafcc6cd5e513ffb2dfc2a/assets/ibm-plex-font/IBMPlexSans-ExtraLightItalic.ttf -------------------------------------------------------------------------------- /assets/ibm-plex-font/IBMPlexSans-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archimodel/archimate-js/9c73897140199e0071dafcc6cd5e513ffb2dfc2a/assets/ibm-plex-font/IBMPlexSans-Italic.ttf -------------------------------------------------------------------------------- /assets/ibm-plex-font/IBMPlexSans-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archimodel/archimate-js/9c73897140199e0071dafcc6cd5e513ffb2dfc2a/assets/ibm-plex-font/IBMPlexSans-Light.ttf -------------------------------------------------------------------------------- /assets/ibm-plex-font/IBMPlexSans-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archimodel/archimate-js/9c73897140199e0071dafcc6cd5e513ffb2dfc2a/assets/ibm-plex-font/IBMPlexSans-LightItalic.ttf -------------------------------------------------------------------------------- /assets/ibm-plex-font/IBMPlexSans-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archimodel/archimate-js/9c73897140199e0071dafcc6cd5e513ffb2dfc2a/assets/ibm-plex-font/IBMPlexSans-Medium.ttf -------------------------------------------------------------------------------- /assets/ibm-plex-font/IBMPlexSans-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archimodel/archimate-js/9c73897140199e0071dafcc6cd5e513ffb2dfc2a/assets/ibm-plex-font/IBMPlexSans-MediumItalic.ttf -------------------------------------------------------------------------------- /assets/ibm-plex-font/IBMPlexSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archimodel/archimate-js/9c73897140199e0071dafcc6cd5e513ffb2dfc2a/assets/ibm-plex-font/IBMPlexSans-Regular.ttf -------------------------------------------------------------------------------- /assets/ibm-plex-font/IBMPlexSans-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archimodel/archimate-js/9c73897140199e0071dafcc6cd5e513ffb2dfc2a/assets/ibm-plex-font/IBMPlexSans-SemiBold.ttf -------------------------------------------------------------------------------- /assets/ibm-plex-font/IBMPlexSans-SemiBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archimodel/archimate-js/9c73897140199e0071dafcc6cd5e513ffb2dfc2a/assets/ibm-plex-font/IBMPlexSans-SemiBoldItalic.ttf -------------------------------------------------------------------------------- /assets/ibm-plex-font/IBMPlexSans-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archimodel/archimate-js/9c73897140199e0071dafcc6cd5e513ffb2dfc2a/assets/ibm-plex-font/IBMPlexSans-Thin.ttf -------------------------------------------------------------------------------- /assets/ibm-plex-font/IBMPlexSans-ThinItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archimodel/archimate-js/9c73897140199e0071dafcc6cd5e513ffb2dfc2a/assets/ibm-plex-font/IBMPlexSans-ThinItalic.ttf -------------------------------------------------------------------------------- /assets/icons/application_collaboration.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/application_component.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/application_data_object.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/application_event.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/application_function.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/application_interaction.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/application_interface.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/application_process.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/application_service.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/archive/application_function.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 41 | 43 | 46 | 49 | 50 | 51 | 56 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /assets/icons/archive/application_interface.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 41 | 43 | 46 | 49 | 50 | 53 | 56 | 57 | 58 | 63 | 67 | 76 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /assets/icons/archive/application_process.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 41 | 43 | 46 | 49 | 50 | 51 | 56 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /assets/icons/archive/business_actor.old.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 39 | 41 | 44 | 47 | 48 | 51 | 54 | 55 | 58 | 61 | 62 | 65 | 68 | 69 | 72 | 75 | 76 | 77 | 82 | 84 | 88 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /assets/icons/archive/business_function.old.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 41 | 43 | 46 | 49 | 50 | 51 | 56 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /assets/icons/archive/business_function_nc.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 39 | 41 | 44 | 47 | 48 | 49 | 54 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /assets/icons/archive/business_interaction.old.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 41 | 43 | 46 | 49 | 50 | 53 | 56 | 57 | 58 | 63 | 67 | 75 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /assets/icons/archive/business_interaction_nc.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 39 | 41 | 44 | 47 | 48 | 51 | 54 | 55 | 56 | 61 | 65 | 73 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /assets/icons/archive/business_interface.old.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 41 | 43 | 46 | 49 | 50 | 53 | 56 | 57 | 58 | 63 | 67 | 76 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /assets/icons/archive/business_interface_nc.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 39 | 41 | 44 | 47 | 48 | 51 | 54 | 55 | 56 | 61 | 65 | 74 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /assets/icons/archive/business_process.old.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 41 | 43 | 46 | 49 | 50 | 51 | 56 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /assets/icons/archive/business_process_nc.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 39 | 41 | 44 | 47 | 48 | 49 | 54 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /assets/icons/business_actor.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/business_collaboration.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/business_contract.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/business_event.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/business_function.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/business_interaction.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/business_interface.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/business_object.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/business_process.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/business_product.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/business_representation.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/business_role.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/business_service.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/group.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/image.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/note-ok.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/note.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/icons/note_old.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/relation-aggregation.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/strategy_capability.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/strategy_course_of_action.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | -------------------------------------------------------------------------------- /assets/icons/strategy_resource.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /assets/icons/strategy_value_stream.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/technology_artifact.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/technology_collaboration.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/technology_communication_network.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/technology_device.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/technology_event.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/technology_function.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/technology_interaction.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/technology_interface.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/technology_node.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/technology_path.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/technology_process.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/technology_service.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/technology_system_software.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/tool_hand.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/tool_hand_r.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /assets/icons/tool_select.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/tool_select_r.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/icons/tool_space.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | export { 2 | default 3 | } from './lib/Viewer'; -------------------------------------------------------------------------------- /lib/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "import" 4 | ], 5 | "rules": { 6 | "import/no-unresolved": "error" 7 | } 8 | } -------------------------------------------------------------------------------- /lib/BaseModeler.js: -------------------------------------------------------------------------------- 1 | import inherits from 'inherits-browser'; 2 | 3 | //import Ids from 'ids'; 4 | 5 | import BaseViewer from './BaseViewer'; 6 | 7 | /** 8 | * A base modeler for Archimate views. 9 | * 10 | * Have a look at {@link Modeler} for a bundle that includes actual features. 11 | * 12 | * @param {Object} [options] configuration options to pass to the viewer 13 | * @param {DOMElement} [options.container] the container to render the viewer in, defaults to body. 14 | * @param {String|Number} [options.width] the width of the viewer 15 | * @param {String|Number} [options.height] the height of the viewer 16 | * @param {Object} [options.moddleExtensions] extension packages to provide 17 | * @param {Array} [options.modules] a list of modules to override the default modules 18 | * @param {Array} [options.additionalModules] a list of modules to use with the default modules 19 | */ 20 | export default function BaseModeler(options) { 21 | BaseViewer.call(this, options); 22 | 23 | // hook ID collection into the modeler 24 | this.on('import.parse.complete', function(event) { 25 | if (!event.error) { 26 | this._collectIds(event.model, event.context); 27 | } 28 | }, this); 29 | 30 | this.on('diagram.destroy', function() { // never call by a hook in other js !!! 31 | this.get('moddle').ids.clear(); 32 | }, this); 33 | } 34 | 35 | inherits(BaseModeler, BaseViewer); 36 | 37 | 38 | /** 39 | * Create a moddle instance, attaching ids to it. 40 | * 41 | * @param {Object} options 42 | */ 43 | BaseModeler.prototype._createModdle = function(options) { 44 | var moddle = BaseViewer.prototype._createModdle.call(this, options); 45 | 46 | // attach ids to moddle to be able to track 47 | // and validated ids in the XML document tree 48 | //moddle.ids = new Ids([ 32, 36, 1 ]); 49 | //moddle.ids = new Ids(); 50 | 51 | return moddle; 52 | }; 53 | 54 | /** 55 | * Collect ids processed during parsing of the 56 | * definitions object. 57 | * 58 | * @param {ModdleElement} definitions 59 | * @param {Context} context 60 | */ 61 | BaseModeler.prototype._collectIds = function(model, context) { 62 | 63 | var moddle = model.$model, 64 | ids = moddle.ids, 65 | id; 66 | 67 | // remove references from previous import 68 | ids.clear(); 69 | 70 | for (id in context.elementsById) { 71 | ids.claim(id, context.elementsById[id]); 72 | } 73 | }; -------------------------------------------------------------------------------- /lib/NavigatedViewer.js: -------------------------------------------------------------------------------- 1 | import inherits from 'inherits-browser'; 2 | 3 | import Viewer from './Viewer'; 4 | 5 | import KeyboardMoveModule from 'diagram-js/lib/navigation/keyboard-move'; 6 | import MoveCanvasModule from 'diagram-js/lib/navigation/movecanvas'; 7 | import ZoomScrollModule from 'diagram-js/lib/navigation/zoomscroll'; 8 | 9 | 10 | /** 11 | * A viewer that includes mouse navigation facilities 12 | * 13 | * @param {Object} options 14 | */ 15 | export default function NavigatedViewer(options) { 16 | Viewer.call(this, options); 17 | } 18 | 19 | inherits(NavigatedViewer, Viewer); 20 | 21 | 22 | NavigatedViewer.prototype._navigationModules = [ 23 | KeyboardMoveModule, 24 | MoveCanvasModule, 25 | ZoomScrollModule 26 | ]; 27 | 28 | NavigatedViewer.prototype._modules = [].concat( 29 | Viewer.prototype._modules, 30 | NavigatedViewer.prototype._navigationModules 31 | ); -------------------------------------------------------------------------------- /lib/Viewer.js: -------------------------------------------------------------------------------- 1 | import inherits from 'inherits-browser'; 2 | 3 | import CoreModule from './core'; 4 | import TranslateModule from 'diagram-js/lib/i18n/translate'; 5 | import SelectionModule from 'diagram-js/lib/features/selection'; 6 | import OverlaysModule from 'diagram-js/lib/features/overlays'; 7 | import ModelingModule from './features/modeling'; 8 | import KeyboardMoveModule from 'diagram-js/lib/navigation/keyboard-move'; 9 | import MoveCanvasModule from 'diagram-js/lib/navigation/movecanvas'; 10 | import TouchModule from 'diagram-js/lib/navigation/touch'; 11 | import ZoomScrollModule from 'diagram-js/lib/navigation/zoomscroll'; 12 | 13 | 14 | import BaseViewer from './BaseViewer'; 15 | 16 | export default function Viewer(options) { 17 | BaseViewer.call(this, options); 18 | } 19 | 20 | inherits(Viewer, BaseViewer); 21 | 22 | 23 | Viewer.prototype._interactionModules = [ 24 | // non-modeling components 25 | KeyboardMoveModule, 26 | //PropertiesPanelModule, 27 | MoveCanvasModule, 28 | TouchModule, 29 | ZoomScrollModule 30 | ]; 31 | 32 | Viewer.prototype._coreModules = [ 33 | CoreModule, 34 | TranslateModule, 35 | SelectionModule, 36 | OverlaysModule, 37 | ModelingModule // need to be able to create figures 38 | ] 39 | 40 | // modules the viewer is composed of 41 | Viewer.prototype._modules = [].concat( 42 | Viewer.prototype._coreModules, 43 | Viewer.prototype._interactionModules 44 | ); 45 | 46 | // default moddle extensions the viewer is composed of 47 | Viewer.prototype._moddleExtensions = {}; -------------------------------------------------------------------------------- /lib/core/index.js: -------------------------------------------------------------------------------- 1 | import DrawModule from '../draw'; 2 | import ImportModule from '../import'; 3 | 4 | export default { 5 | __depends__: [ 6 | DrawModule, 7 | ImportModule 8 | ] 9 | }; -------------------------------------------------------------------------------- /lib/draw/TextRenderer.js: -------------------------------------------------------------------------------- 1 | import { assign } from 'min-dash'; 2 | 3 | import TextUtil from 'diagram-js/lib/util/Text'; 4 | 5 | export const FONTSIZE_DEFAULT = 13, 6 | FONTNAME_DEFAULT = 'Quicksand'; 7 | 8 | 9 | const LINE_HEIGHT_RATIO = 1.4; 10 | 11 | export default function TextRenderer(config) { 12 | 13 | var defaultStyle = assign({ 14 | fontFamily: 'Quicksand', //'IBM Plex, sans-serif', 15 | fontSize: FONTSIZE_DEFAULT, 16 | fontWeight: '500', 17 | lineHeight: LINE_HEIGHT_RATIO 18 | }, config && config.defaultStyle || {}); 19 | 20 | var externalFontSize = parseInt(defaultStyle.fontSize, 10) - 1; 21 | 22 | var externalStyle = assign({}, defaultStyle, { 23 | fontSize: externalFontSize 24 | }, config && config.externalStyle || {}); 25 | 26 | var textUtil = new TextUtil({ 27 | style: defaultStyle 28 | }); 29 | 30 | /** 31 | * Get the new bounds of an externally rendered, 32 | * layouted label. 33 | * 34 | * @param {Bounds} bounds 35 | * @param {String} text 36 | * 37 | * @return {Bounds} 38 | */ 39 | this.getExternalLabelBounds = function(bounds, text) { 40 | 41 | var layoutedDimensions = textUtil.getDimensions(text, { 42 | box: { 43 | width: 90, 44 | height: 30, 45 | x: bounds.width / 2 + bounds.x, 46 | y: bounds.height / 2 + bounds.y 47 | }, 48 | style: externalStyle 49 | }); 50 | 51 | // resize label shape to fit label text 52 | return { 53 | x: Math.round(bounds.x + bounds.width / 2 - layoutedDimensions.width / 2), 54 | y: Math.round(bounds.y), 55 | width: Math.ceil(layoutedDimensions.width), 56 | height: Math.ceil(layoutedDimensions.height) 57 | }; 58 | 59 | }; 60 | 61 | /** 62 | * Create a layouted text element. 63 | * 64 | * @param {String} text 65 | * @param {Object} [options] 66 | * 67 | * @return {SVGElement} rendered text 68 | */ 69 | this.createText = function(text, options) { 70 | return textUtil.createText(text, options || {}); 71 | }; 72 | 73 | /** 74 | * Get default text style. 75 | */ 76 | this.getDefaultStyle = function() { 77 | return defaultStyle; 78 | }; 79 | 80 | /** 81 | * Get the external text style. 82 | */ 83 | this.getExternalStyle = function() { 84 | return externalStyle; 85 | }; 86 | 87 | } 88 | 89 | TextRenderer.$inject = [ 90 | 'config.textRenderer' 91 | ]; -------------------------------------------------------------------------------- /lib/draw/index.js: -------------------------------------------------------------------------------- 1 | import ArchimateRenderer from './ArchimateRenderer'; 2 | import TextRenderer from './TextRenderer'; 3 | 4 | import PathMap from './PathMap'; 5 | 6 | export default { 7 | __init__: [ 'ArchimateRenderer' ], 8 | ArchimateRenderer: [ 'type', ArchimateRenderer ], 9 | textRenderer: [ 'type', TextRenderer ], 10 | pathMap: [ 'type', PathMap ] 11 | }; 12 | -------------------------------------------------------------------------------- /lib/features/auto-place/ArchimateAutoPlace.js: -------------------------------------------------------------------------------- 1 | import { logger } from '../../util/Logger'; 2 | import { getNewShapePosition } from './ArchimateAutoPlaceUtil'; 3 | 4 | 5 | /** 6 | * Archimate auto-place behavior. 7 | * 8 | * @param {EventBus} eventBus 9 | */ 10 | export default function AutoPlace(eventBus) { 11 | eventBus.on('autoPlace', function(context) { 12 | logger.log(context); 13 | var shape = context.shape, 14 | source = context.source; 15 | 16 | return getNewShapePosition(source, shape); 17 | }); 18 | } 19 | 20 | AutoPlace.$inject = [ 'eventBus' ]; -------------------------------------------------------------------------------- /lib/features/auto-place/ArchimateAutoPlaceUtil.js: -------------------------------------------------------------------------------- 1 | import { is, isAny, NOTE } from '../../util/ModelUtil'; 2 | 3 | import { 4 | getMid, 5 | asTRBL, 6 | getOrientation 7 | } from 'diagram-js/lib/layout/LayoutUtil'; 8 | 9 | import { 10 | findFreePosition, 11 | generateGetNextPosition, 12 | getConnectedDistance 13 | } from 'diagram-js/lib/features/auto-place/AutoPlaceUtil'; 14 | import { logger } from '../../util/Logger'; 15 | 16 | 17 | 18 | 19 | /** 20 | * Find the new position for the target element to 21 | * connect to source. 22 | * 23 | * @param {djs.model.Shape} source 24 | * @param {djs.model.Shape} element 25 | * 26 | * @return {Point} 27 | */ 28 | export function getNewShapePosition(source, element) { 29 | 30 | if (element.type === NOTE) { 31 | return getNotePosition(source, element); 32 | } 33 | 34 | if (isAny(element, [ 'bpmn:DataObjectReference', 'bpmn:DataStoreReference' ])) { 35 | return getDataElementPosition(source, element); 36 | } 37 | 38 | if (is(element, 'bpmn:FlowNode')) { 39 | return getFlowNodePosition(source, element); 40 | } 41 | } 42 | 43 | /** 44 | * Always try to place element right of source; 45 | * compute actual distance from previous nodes in flow. 46 | */ 47 | export function getFlowNodePosition(source, element) { 48 | 49 | var sourceTrbl = asTRBL(source); 50 | var sourceMid = getMid(source); 51 | 52 | var horizontalDistance = getConnectedDistance(source, { 53 | filter: function(connection) { 54 | return is(connection, 'bpmn:SequenceFlow'); 55 | } 56 | }); 57 | 58 | var margin = 30, 59 | minDistance = 80, 60 | orientation = 'left'; 61 | 62 | if (is(source, 'bpmn:BoundaryEvent')) { 63 | orientation = getOrientation(source, source.host, -25); 64 | 65 | if (orientation.indexOf('top') !== -1) { 66 | margin *= -1; 67 | } 68 | } 69 | 70 | var position = { 71 | x: sourceTrbl.right + horizontalDistance + element.width / 2, 72 | y: sourceMid.y + getVerticalDistance(orientation, minDistance) 73 | }; 74 | 75 | var nextPositionDirection = { 76 | y: { 77 | margin: margin, 78 | minDistance: minDistance 79 | } 80 | }; 81 | 82 | return findFreePosition(source, element, position, generateGetNextPosition(nextPositionDirection)); 83 | } 84 | 85 | 86 | function getVerticalDistance(orientation, minDistance) { 87 | if (orientation.indexOf('top') != -1) { 88 | return -1 * minDistance; 89 | } else if (orientation.indexOf('bottom') != -1) { 90 | return minDistance; 91 | } else { 92 | return 0; 93 | } 94 | } 95 | 96 | 97 | /** 98 | * Always try to place NOTE top right of source. 99 | */ 100 | export function getNotePosition(source, element) { 101 | 102 | logger.log(element); 103 | 104 | var sourceTrbl = asTRBL(source); 105 | 106 | var position = { 107 | x: sourceTrbl.right + element.width / 2, 108 | y: sourceTrbl.top - 50 - element.height / 2 109 | }; 110 | 111 | if (isConnection(source)) { 112 | position = getMid(source); 113 | position.x += 100; 114 | position.y -= 50; 115 | } 116 | 117 | var nextPositionDirection = { 118 | y: { 119 | margin: -30, 120 | minDistance: 20 121 | } 122 | }; 123 | 124 | return findFreePosition(source, element, position, generateGetNextPosition(nextPositionDirection)); 125 | } 126 | 127 | 128 | /** 129 | * Always put element bottom right of source. 130 | */ 131 | export function getDataElementPosition(source, element) { 132 | 133 | var sourceTrbl = asTRBL(source); 134 | 135 | var position = { 136 | x: sourceTrbl.right - 10 + element.width / 2, 137 | y: sourceTrbl.bottom + 40 + element.width / 2 138 | }; 139 | 140 | var nextPositionDirection = { 141 | x: { 142 | margin: 30, 143 | minDistance: 30 144 | } 145 | }; 146 | 147 | return findFreePosition(source, element, position, generateGetNextPosition(nextPositionDirection)); 148 | } 149 | 150 | function isConnection(element) { 151 | return !!element.waypoints; 152 | } -------------------------------------------------------------------------------- /lib/features/auto-place/index.js: -------------------------------------------------------------------------------- 1 | import AutoPlaceModule from 'diagram-js/lib/features/auto-place'; 2 | 3 | import ArchimateAutoPlace from './ArchimateAutoPlace'; 4 | 5 | export default { 6 | __depends__: [ AutoPlaceModule ], 7 | __init__: [ 'archimateAutoPlace' ], 8 | archimateAutoPlace: [ 'type', ArchimateAutoPlace ] 9 | }; -------------------------------------------------------------------------------- /lib/features/canvas-create/CanvasCreate.js: -------------------------------------------------------------------------------- 1 | import { 2 | delegate as domDelegate 3 | } from 'min-dom'; 4 | 5 | import { 6 | assign 7 | } from 'min-dash'; 8 | 9 | import { 10 | isAny 11 | } from '../../util/ModelUtil'; 12 | 13 | import { 14 | toPoint 15 | } from 'diagram-js/lib/util/Event'; 16 | 17 | import { logger } from "../../util/Logger"; 18 | 19 | var DEFAULT_SHAPE = { 20 | type: 'archimate:', 21 | $instanceOf: function() { return true; } 22 | }; 23 | 24 | export default function CanvasCreate(eventBus, elementFactory, canvas, directEditing, modeling) { 25 | 26 | var lastCreatedShape = DEFAULT_SHAPE; 27 | 28 | function _getNewShapePosition(event) { 29 | var eventPoint = toPoint(event); 30 | 31 | return { 32 | x: eventPoint.x, 33 | y: eventPoint.y 34 | }; 35 | } 36 | 37 | function _activateDirectEdit(element) { 38 | if (isAny(element.businessObject, [ ARCHIMATE_NODE ])) { 39 | directEditing.activate(element); 40 | } 41 | } 42 | 43 | function _createShapeOnCanvas(event) { 44 | var position = _getNewShapePosition(event); 45 | 46 | var newShape = elementFactory.create( 47 | 'shape', assign(lastCreatedShape, position)); 48 | 49 | logger.log('_createShapeOnCanvas(event)'); 50 | logger.log(newShape); 51 | 52 | var root = canvas.getRootElement(); 53 | 54 | var createdShape = modeling.createShape(newShape, position, root); 55 | 56 | _activateDirectEdit(createdShape); 57 | } 58 | 59 | function _saveLastCreatedShape(shape) { 60 | if (!shape) { 61 | lastCreatedShape = DEFAULT_SHAPE; 62 | return; 63 | } 64 | 65 | var viewElement = shape.businessObject; 66 | 67 | lastCreatedShape = { 68 | type: shape.type, 69 | $instanceOf: function(type) { 70 | return (typeof viewElement.$instanceOf === 'function') && viewElement.$instanceOf(type); 71 | } 72 | }; 73 | } 74 | 75 | eventBus.on('canvas.init', function(context) { 76 | var svg = context.svg; 77 | 78 | domDelegate.bind(svg, 'svg', 'dblclick', function(event) { 79 | if (event.target !== svg) { 80 | return; 81 | } 82 | 83 | _createShapeOnCanvas(event); 84 | }); 85 | 86 | eventBus.on('create.end', function(context) { 87 | var shape = context.shape; 88 | _saveLastCreatedShape(shape); 89 | }); 90 | }); 91 | } 92 | 93 | CanvasCreate.$inject = ['eventBus', 'elementFactory', 'canvas', 'directEditing', 'modeling']; 94 | -------------------------------------------------------------------------------- /lib/features/canvas-create/index.js: -------------------------------------------------------------------------------- 1 | import CanvasCreate from './CanvasCreate'; 2 | import DirectEditingModule from 'diagram-js-direct-editing'; 3 | 4 | export default { 5 | __depends__: [ 6 | DirectEditingModule 7 | ], 8 | __init__: [ 'canvasCreate' ], 9 | canvasCreate: [ 'type', CanvasCreate ] 10 | }; -------------------------------------------------------------------------------- /lib/features/context-pad/index.js: -------------------------------------------------------------------------------- 1 | import DirectEditingModule from 'diagram-js-direct-editing'; 2 | import ContextPadModule from 'diagram-js/lib/features/context-pad'; 3 | import SelectionModule from 'diagram-js/lib/features/selection'; 4 | import ConnectModule from 'diagram-js/lib/features/connect'; 5 | import CreateModule from 'diagram-js/lib/features/create'; 6 | import PopupMenuModule from '../popup-menu'; 7 | import AutoPlaceModule from '../auto-place' 8 | 9 | import ContextPadProvider from './ContextPadProvider'; 10 | 11 | export default { 12 | __depends__: [ 13 | DirectEditingModule, 14 | ContextPadModule, 15 | SelectionModule, 16 | ConnectModule, 17 | CreateModule, 18 | PopupMenuModule, 19 | AutoPlaceModule 20 | ], 21 | __init__: [ 'contextPadProvider' ], 22 | contextPadProvider: [ 'type', ContextPadProvider ] 23 | }; -------------------------------------------------------------------------------- /lib/features/copy-paste/ArchimateCopyPaste.js: -------------------------------------------------------------------------------- 1 | import { 2 | getViewElement, 3 | getElementRef 4 | } from '../../util/ModelUtil'; 5 | 6 | import { 7 | forEach, 8 | isArray, 9 | isUndefined, 10 | omit, 11 | reduce 12 | } from 'min-dash'; 13 | 14 | import { logger } from "../../util/Logger"; 15 | 16 | function copyProperties(source, target, properties) { 17 | if (!isArray(properties)) { 18 | properties = [ properties ]; 19 | } 20 | 21 | forEach(properties, function(property) { 22 | if (!isUndefined(source[property])) { 23 | target[property] = source[property]; 24 | } 25 | }); 26 | } 27 | 28 | function removeProperties(element, properties) { 29 | if (!isArray(properties)) { 30 | properties = [ properties ]; 31 | } 32 | 33 | forEach(properties, function(property) { 34 | if (element[property]) { 35 | delete element[property]; 36 | } 37 | }); 38 | } 39 | 40 | var LOW_PRIORITY = 750; 41 | 42 | 43 | export default function ArchimateCopyPaste(archimateFactory, eventBus, moddleCopy) { 44 | 45 | eventBus.on('copyPaste.copyElement', LOW_PRIORITY, function(context) { 46 | var descriptor = context.descriptor, 47 | element = context.element; 48 | 49 | logger.log('copyPaste.copyElement(context):'); 50 | logger.log({context}); 51 | 52 | var elementRef = descriptor.oldElementRef = getElementRef(element); 53 | 54 | descriptor.type = element.type; 55 | 56 | // TODO(vbo) bug on copy element, root cause is on copyProperties 57 | copyProperties(elementRef, descriptor, ['name', 'documentation']); 58 | 59 | // TODO(vbo) 60 | // create new property viewElement in shape element, possible confusion with businessObject [getViewElement()] 61 | // this property is never used after, check copyProperties() code 62 | descriptor.viewElement = {}; 63 | 64 | copyProperties(getViewElement(element), descriptor.viewElement, ['style', 'label', 'fillColor', 'lineColor']); 65 | 66 | if (isLabel(descriptor)) { 67 | return descriptor; 68 | } 69 | 70 | 71 | 72 | }); 73 | 74 | var references; 75 | 76 | function resolveReferences(descriptor, cache) { 77 | var elementRef = descriptor.oldElementRef; 78 | 79 | // default sequence flows 80 | if (descriptor.default) { 81 | 82 | // relationship cannot be resolved immediately 83 | references[ descriptor.default ] = { 84 | element: elementRef, 85 | property: 'default' 86 | }; 87 | } 88 | 89 | references = omit(references, reduce(references, function(array, reference, key) { 90 | var element = reference.element, 91 | property = reference.property; 92 | 93 | if (key === descriptor.id) { 94 | element[ property ] = elementRef; 95 | 96 | array.push(descriptor.id); 97 | } 98 | 99 | return array; 100 | }, [])); 101 | } 102 | 103 | eventBus.on('copyPaste.pasteElements', function() { 104 | references = {}; 105 | }); 106 | 107 | eventBus.on('copyPaste.pasteElement', function(context) { 108 | var cache = context.cache, 109 | descriptor = context.descriptor, 110 | oldElementRef = descriptor.oldElementRef, 111 | newElementRef; 112 | 113 | logger.log('copyPaste.pasteElement(context):'); 114 | logger.log({context}); 115 | 116 | newElementRef = archimateFactory.create(oldElementRef.$type); 117 | 118 | descriptor.businessObject = moddleCopy.copyElement( 119 | oldElementRef, 120 | newElementRef 121 | ); 122 | 123 | // resolve references e.g. default sequence flow 124 | resolveReferences(descriptor, cache); 125 | 126 | copyProperties(descriptor, newElementRef, [ 'name', 'documentation' ]); 127 | 128 | removeProperties(descriptor, 'oldElementRef'); 129 | }); 130 | 131 | } 132 | 133 | 134 | ArchimateCopyPaste.$inject = [ 135 | 'archimateFactory', 136 | 'eventBus', 137 | 'moddleCopy' 138 | ]; 139 | 140 | // helpers ////////// 141 | 142 | function isLabel(element) { 143 | return !!element.labelTarget; 144 | } 145 | -------------------------------------------------------------------------------- /lib/features/copy-paste/index.js: -------------------------------------------------------------------------------- 1 | import CopyPasteModule from 'diagram-js/lib/features/copy-paste'; 2 | 3 | import ArchimateCopyPaste from './ArchimateCopyPaste'; 4 | import ModdleCopy from './ModdleCopy'; 5 | 6 | export default { 7 | __depends__: [ 8 | CopyPasteModule 9 | ], 10 | __init__: [ 'archimateCopyPaste', 'moddleCopy' ], 11 | archimateCopyPaste: [ 'type', ArchimateCopyPaste ], 12 | moddleCopy: [ 'type', ModdleCopy ] 13 | }; 14 | -------------------------------------------------------------------------------- /lib/features/editor-actions/index.js: -------------------------------------------------------------------------------- 1 | import EditorActionsModule from 'diagram-js/lib/features/editor-actions'; 2 | 3 | import ArchimateEditorActions from './ArchimateEditorActions'; 4 | 5 | export default { 6 | __depends__: [ 7 | EditorActionsModule 8 | ], 9 | editorActions: [ 'type', ArchimateEditorActions ] 10 | }; 11 | -------------------------------------------------------------------------------- /lib/features/keyboard/ArchimateKeyboardBindings.js: -------------------------------------------------------------------------------- 1 | import inherits from 'inherits-browser'; 2 | 3 | import KeyboardBindings from 'diagram-js/lib/features/keyboard/KeyboardBindings'; 4 | 5 | 6 | /** 7 | * Archimate specific keyboard bindings. 8 | * 9 | * @param {Injector} injector 10 | */ 11 | export default function ArchimateKeyboardBindings(injector) { 12 | injector.invoke(KeyboardBindings, this); 13 | } 14 | 15 | inherits(ArchimateKeyboardBindings, KeyboardBindings); 16 | 17 | ArchimateKeyboardBindings.$inject = [ 18 | 'injector' 19 | ]; 20 | 21 | 22 | /** 23 | * Register available keyboard bindings. 24 | * 25 | * @param {Keyboard} keyboard 26 | * @param {EditorActions} editorActions 27 | */ 28 | ArchimateKeyboardBindings.prototype.registerBindings = function(keyboard, editorActions) { 29 | 30 | // inherit default bindings 31 | KeyboardBindings.prototype.registerBindings.call(this, keyboard, editorActions); 32 | 33 | /** 34 | * Add keyboard binding if respective editor action 35 | * is registered. 36 | * 37 | * @param {String} action name 38 | * @param {Function} fn that implements the key binding 39 | */ 40 | function addListener(action, fn) { 41 | 42 | if (editorActions.isRegistered(action)) { 43 | keyboard.addListener(fn); 44 | } 45 | } 46 | 47 | // select all elements 48 | // CTRL + A 49 | addListener('selectElements', function(context) { 50 | 51 | var event = context.keyEvent; 52 | 53 | if (keyboard.isKey(['a', 'A'], event) && keyboard.isCmd(event)) { 54 | editorActions.trigger('selectElements'); 55 | 56 | return true; 57 | } 58 | }); 59 | 60 | // search labels 61 | // CTRL + F 62 | addListener('find', function(context) { 63 | 64 | var event = context.keyEvent; 65 | 66 | if (keyboard.isKey(['f', 'F'], event) && keyboard.isCmd(event)) { 67 | editorActions.trigger('find'); 68 | 69 | return true; 70 | } 71 | }); 72 | 73 | // activate space tool 74 | // S 75 | addListener('spaceTool', function(context) { 76 | 77 | var event = context.keyEvent; 78 | 79 | if (keyboard.hasModifier(event)) { 80 | return; 81 | } 82 | 83 | if (keyboard.isKey(['s', 'S'], event)) { 84 | editorActions.trigger('spaceTool'); 85 | 86 | return true; 87 | } 88 | }); 89 | 90 | // activate lasso tool 91 | // L 92 | addListener('lassoTool', function(context) { 93 | 94 | var event = context.keyEvent; 95 | 96 | if (keyboard.hasModifier(event)) { 97 | return; 98 | } 99 | 100 | if (keyboard.isKey(['l', 'L'], event)) { 101 | editorActions.trigger('lassoTool'); 102 | 103 | return true; 104 | } 105 | }); 106 | 107 | // activate hand tool 108 | // H 109 | addListener('handTool', function(context) { 110 | 111 | var event = context.keyEvent; 112 | 113 | if (keyboard.hasModifier(event)) { 114 | return; 115 | } 116 | 117 | if (keyboard.isKey(['h', 'H'], event)) { 118 | editorActions.trigger('handTool'); 119 | 120 | return true; 121 | } 122 | }); 123 | 124 | // activate direct editing 125 | // E 126 | addListener('directEditing', function(context) { 127 | 128 | var event = context.keyEvent; 129 | 130 | if (keyboard.hasModifier(event)) { 131 | return; 132 | } 133 | 134 | if (keyboard.isKey(['e', 'E'], event)) { 135 | editorActions.trigger('directEditing'); 136 | 137 | return true; 138 | } 139 | }); 140 | 141 | }; -------------------------------------------------------------------------------- /lib/features/keyboard/index.js: -------------------------------------------------------------------------------- 1 | import KeyboardModule from 'diagram-js/lib/features/keyboard'; 2 | 3 | import ArchimateKeyboardBindings from './ArchimateKeyboardBindings'; 4 | 5 | export default { 6 | __depends__: [ 7 | KeyboardModule 8 | ], 9 | __init__: [ 'keyboardBindings' ], 10 | keyboardBindings: [ 'type', ArchimateKeyboardBindings ] 11 | }; 12 | -------------------------------------------------------------------------------- /lib/features/label-editing/LabelEditingPreview.js: -------------------------------------------------------------------------------- 1 | import { 2 | remove as svgRemove 3 | } from 'tiny-svg'; 4 | 5 | import { isAny } from '../../util/ModelUtil'; 6 | import { ARCHIMATE_NODE } from '../../metamodel/Concept'; 7 | 8 | var MARKER_HIDDEN = 'djs-element-hidden', 9 | MARKER_LABEL_HIDDEN = 'djs-label-hidden'; 10 | 11 | 12 | export default function LabelEditingPreview( 13 | eventBus, canvas, elementRegistry, 14 | pathMap) { 15 | 16 | 17 | var element, gfx; 18 | 19 | eventBus.on('directEditing.activate', function(context) { 20 | var activeProvider = context.active; 21 | 22 | element = activeProvider.element.label || activeProvider.element; 23 | 24 | 25 | if (element.labelTarget) { 26 | canvas.addMarker(element, MARKER_HIDDEN); 27 | } else if (isAny(element.businessObject, [ ARCHIMATE_NODE ])) { 28 | canvas.addMarker(element, MARKER_LABEL_HIDDEN); 29 | } 30 | }); 31 | 32 | 33 | eventBus.on([ 'directEditing.complete', 'directEditing.cancel' ], function(context) { 34 | var activeProvider = context.active; 35 | 36 | if (activeProvider) { 37 | canvas.removeMarker(activeProvider.element.label || activeProvider.element, MARKER_HIDDEN); 38 | canvas.removeMarker(element, MARKER_LABEL_HIDDEN); 39 | } 40 | 41 | element = undefined; 42 | 43 | if (gfx) { 44 | svgRemove(gfx); 45 | 46 | gfx = undefined; 47 | } 48 | }); 49 | } 50 | 51 | LabelEditingPreview.$inject = [ 52 | 'eventBus', 53 | 'canvas', 54 | 'elementRegistry', 55 | 'pathMap' 56 | ]; -------------------------------------------------------------------------------- /lib/features/label-editing/LabelUtil.js: -------------------------------------------------------------------------------- 1 | import { ARCHIMATE_CONNECTION, ARCHIMATE_NODE } from '../../metamodel/Concept'; 2 | import { isAny, NOTE } from '../../util/ModelUtil'; 3 | 4 | function getLabelAttr(element) { 5 | if (isAny(element, [ ARCHIMATE_NODE, ARCHIMATE_CONNECTION ])) { 6 | if (element.type === NOTE) { 7 | return 'text'; 8 | } else { 9 | return 'name'; 10 | } 11 | } 12 | } 13 | 14 | export function getLabel(element) { 15 | var attr = getLabelAttr(element.businessObject); 16 | 17 | if (attr) { 18 | return element[attr] || ''; 19 | } 20 | 21 | } 22 | 23 | export function setLabel(element, text) { 24 | 25 | if (isAny(element.businessObject, [ ARCHIMATE_NODE ])) { 26 | if (element.businessObject.type === NOTE) { 27 | element.text = text; 28 | element.businessObject.label = text; 29 | } else { 30 | element.name = text; 31 | element.businessObject.elementRef.name = text; 32 | 33 | } 34 | } 35 | 36 | if (isAny(element.businessObject, [ ARCHIMATE_CONNECTION ])) { 37 | element.name = text; 38 | element.businessObject.relationshipRef.name = text; 39 | 40 | } 41 | 42 | return element; 43 | } -------------------------------------------------------------------------------- /lib/features/label-editing/cmd/UpdateLabelHandler.js: -------------------------------------------------------------------------------- 1 | import { 2 | setLabel, 3 | getLabel 4 | } from '../LabelUtil'; 5 | 6 | import { 7 | getExternalLabelMid, 8 | isLabelExternal, 9 | hasExternalLabel, 10 | isLabel 11 | } from '../../../util/LabelUtil'; 12 | 13 | import { logger } from "../../../util/Logger"; 14 | 15 | var NULL_DIMENSIONS = { 16 | width: 0, 17 | height: 0 18 | }; 19 | 20 | /** 21 | * A handler that updates the text of an element. 22 | */ 23 | export default function UpdateLabelHandler(modeling, textRenderer) { 24 | 25 | /** 26 | * Set the label and return the changed elements. 27 | * 28 | * Element parameter can be label itself or connection (i.e. sequence flow). 29 | * 30 | * @param {djs.model.Base} element 31 | * @param {String} text 32 | */ 33 | function setText(element, text) { 34 | 35 | // external label if present 36 | var label = element.label || element; 37 | 38 | var labelTarget = element.labelTarget || element; 39 | 40 | setLabel(label, text, labelTarget !== label); 41 | 42 | return [ label, labelTarget ]; 43 | } 44 | 45 | function preExecute(ctx) { 46 | 47 | logger.log('preExecute'); 48 | 49 | var element = ctx.element, 50 | businessObject = element.businessObject, 51 | newLabel = ctx.newLabel; 52 | 53 | if (!isLabel(element) 54 | && isLabelExternal(element) 55 | && !hasExternalLabel(element) 56 | && !isEmptyText(newLabel)) { 57 | 58 | // create label 59 | var paddingTop = 7; 60 | 61 | var labelCenter = getExternalLabelMid(element); 62 | 63 | labelCenter = { 64 | x: labelCenter.x, 65 | y: labelCenter.y + paddingTop 66 | }; 67 | 68 | modeling.createLabel(element, labelCenter, { 69 | id: businessObject.id + '_label', 70 | businessObject: businessObject 71 | }); 72 | } 73 | } 74 | 75 | function execute(ctx) { 76 | logger.log('execute'); 77 | ctx.oldLabel = getLabel(ctx.element); 78 | return setText(ctx.element, ctx.newLabel); 79 | } 80 | 81 | function revert(ctx) { 82 | logger.log('revert'); 83 | return setText(ctx.element, ctx.oldLabel); 84 | } 85 | 86 | function postExecute(ctx) { 87 | logger.log('revert'); 88 | var element = ctx.element, 89 | label = element.label || element, 90 | newLabel = ctx.newLabel, 91 | newBounds = ctx.newBounds, 92 | hints = ctx.hints || {}; 93 | 94 | // ignore internal labels for elements 95 | if (!isLabel(label)) { 96 | return; 97 | } 98 | 99 | if (isLabel(label) && isEmptyText(newLabel)) { 100 | 101 | if (hints.removeShape !== false) { 102 | modeling.removeShape(label, { unsetLabel: false }); 103 | } 104 | 105 | return; 106 | } 107 | 108 | var text = getLabel(label); 109 | 110 | // resize element based on label _or_ pre-defined bounds 111 | if (typeof newBounds === 'undefined') { 112 | newBounds = textRenderer.getExternalLabelBounds(label, text); 113 | } 114 | 115 | // setting newBounds to false or _null_ will 116 | // disable the postExecute resize operation 117 | if (newBounds) { 118 | modeling.resizeShape(label, newBounds, NULL_DIMENSIONS); 119 | } 120 | } 121 | 122 | // API 123 | 124 | this.preExecute = preExecute; 125 | this.execute = execute; 126 | this.revert = revert; 127 | this.postExecute = postExecute; 128 | } 129 | 130 | UpdateLabelHandler.$inject = [ 131 | 'modeling', 132 | 'textRenderer' 133 | ]; 134 | 135 | 136 | // helpers /////////////////////// 137 | 138 | function isEmptyText(label) { 139 | return !label || !label.trim(); 140 | } -------------------------------------------------------------------------------- /lib/features/label-editing/index.js: -------------------------------------------------------------------------------- 1 | import ChangeSupportModule from 'diagram-js/lib/features/change-support'; 2 | import ResizeModule from 'diagram-js/lib/features/resize'; 3 | import DirectEditingModule from 'diagram-js-direct-editing'; 4 | 5 | import LabelEditingProvider from './LabelEditingProvider'; 6 | import LabelEditingPreview from './LabelEditingPreview'; 7 | 8 | 9 | export default { 10 | __depends__: [ 11 | ChangeSupportModule, 12 | ResizeModule, 13 | DirectEditingModule 14 | ], 15 | __init__: [ 16 | 'labelEditingProvider', 17 | 'labelEditingPreview' 18 | ], 19 | labelEditingProvider: [ 'type', LabelEditingProvider ], 20 | labelEditingPreview: [ 'type', LabelEditingPreview ] 21 | }; 22 | -------------------------------------------------------------------------------- /lib/features/modeling/ArchimateFactory.js: -------------------------------------------------------------------------------- 1 | import { 2 | assign, 3 | pick 4 | } from 'min-dash'; 5 | 6 | import { 7 | is 8 | } from '../../util/ModelUtil'; 9 | 10 | import { logger } from "../../util/Logger"; 11 | import { ARCHIMATE_CONNECTION, ARCHIMATE_ELEMENT, ARCHIMATE_FILLCOLOR, ARCHIMATE_IDOBJECT, ARCHIMATE_LINECOLOR, ARCHIMATE_RELATIONSHIP, ARCHIMATE_STYLE, ARCHIMATE_VIEW, ARCHIMATE_WAYPOINT, ARCHIMATE_WAYPOINTS } from '../../metamodel/Concept'; 12 | 13 | export default function ArchimateFactory(moddle) { 14 | this._moddle = moddle; 15 | } 16 | 17 | ArchimateFactory.$inject = [ 'moddle' ]; 18 | 19 | ArchimateFactory.prototype._needsId = function(element) { 20 | return is(element, ARCHIMATE_IDOBJECT); 21 | }; 22 | 23 | ArchimateFactory.prototype._ensureId = function(element) { 24 | var prefix = 'id-'; 25 | 26 | if (!element.id && this._needsId(element)) { 27 | element.id = this._moddle.ids.nextPrefixed(prefix, element); 28 | } 29 | 30 | }; 31 | 32 | ArchimateFactory.prototype.create = function(type, attrs) { 33 | logger.log('create(type, attrs)'); 34 | logger.log({type, attrs}); 35 | 36 | var element = this._moddle.create(type, attrs || {}); 37 | 38 | this._ensureId(element); 39 | 40 | return element; 41 | }; 42 | 43 | /* 44 | ArchimateFactory.prototype.createBaseElement = function(xsiType) { 45 | return this.create(ARCHIMATE_ELEMENT, { 46 | type: xsiType 47 | }); 48 | }; 49 | 50 | ArchimateFactory.prototype.createRelationship = function(xsiType) { 51 | return this.create(ARCHIMATE_RELATIONSHIP, { 52 | type: xsiType 53 | }); 54 | }; 55 | 56 | ArchimateFactory.prototype.createViewElement = function(elementRef, attrs) { 57 | return this.create(ARCHIMATE_NODE, assign({ 58 | elementRef: elementRef//, 59 | // style: this.createStyle(attrs) 60 | }, attrs)); 61 | }; 62 | 63 | ArchimateFactory.prototype.createConnection = function(relationshipRef, attrs) { 64 | return this.create(ARCHIMATE_CONNECTION, assign({ 65 | relationshipRef: relationshipRef 66 | }, attrs)); 67 | }; 68 | */ 69 | 70 | ArchimateFactory.prototype.createWaypoints = function(waypoints) { 71 | var self = this; 72 | 73 | var waypointsArray = waypoints.map(function(waypoint) { 74 | return self.createWaypoint(waypoint); 75 | }); 76 | 77 | return this.create(ARCHIMATE_WAYPOINTS, { 78 | waypoints: waypointsArray 79 | }); 80 | 81 | }; 82 | 83 | ArchimateFactory.prototype.createWaypoint = function(waypoint) { 84 | return this.create(ARCHIMATE_WAYPOINT, pick(waypoint, [ 'x', 'y' ])); 85 | }; 86 | 87 | 88 | /// NEXT no more used 89 | 90 | ArchimateFactory.prototype.createStyle = function(attrs) { 91 | logger.log('createStyle(attrs)'); 92 | logger.log(attrs); 93 | 94 | return this.create(ARCHIMATE_STYLE, assign({ 95 | fillColor: this.create(ARCHIMATE_FILLCOLOR, attrs), 96 | lineColor: this.create(ARCHIMATE_LINECOLOR, attrs) 97 | }, attrs)); 98 | }; 99 | 100 | ArchimateFactory.prototype.createView = function(elementRef) { 101 | return this.create(ARCHIMATE_VIEW, { 102 | elementRef: elementRef 103 | }); 104 | }; 105 | -------------------------------------------------------------------------------- /lib/features/modeling/behavior/AppendBehavior.js: -------------------------------------------------------------------------------- 1 | import inherits from 'inherits-browser'; 2 | 3 | import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor'; 4 | import { logger } from '../../../util/Logger'; 5 | import { NOTE } from '../../../util/ModelUtil'; 6 | 7 | 8 | export default function AppendBehavior(eventBus) { 9 | 10 | CommandInterceptor.call(this, eventBus); 11 | 12 | // assign correct shape position unless already set 13 | 14 | this.preExecute('shape.append', function(context) { 15 | logger.log({context}); 16 | 17 | var source = context.source, 18 | shape = context.shape; 19 | 20 | if (!context.connection) { 21 | if (shape.type === NOTE) { 22 | context.connection = {type : 'Line'} 23 | } 24 | } 25 | 26 | if (!context.position) { 27 | 28 | context.position = { 29 | x: source.x + source.width + 80 + shape.width / 2, 30 | y: source.y + source.height / 2 31 | }; 32 | 33 | } 34 | }, true); 35 | } 36 | 37 | inherits(AppendBehavior, CommandInterceptor); 38 | 39 | AppendBehavior.$inject = [ 40 | 'eventBus' 41 | ]; -------------------------------------------------------------------------------- /lib/features/modeling/behavior/FixHoverBehavior.js: -------------------------------------------------------------------------------- 1 | import { logger } from '../../../util/Logger'; 2 | import { is } from '../../../util/ModelUtil'; 3 | 4 | var HIGH_PRIORITY = 1500; 5 | 6 | 7 | /** 8 | * Correct hover targets in certain situations to improve diagram interaction. 9 | * 10 | * @param {ElementRegistry} elementRegistry 11 | * @param {EventBus} eventBus 12 | * @param {Canvas} canvas 13 | */ 14 | export default function FixHoverBehavior(elementRegistry, eventBus, canvas) { 15 | 16 | eventBus.on([ 17 | 'create.hover', 18 | 'create.move', 19 | 'create.end', 20 | 'shape.move.hover', 21 | 'shape.move.move', 22 | 'shape.move.end' 23 | ], HIGH_PRIORITY, function(event) { 24 | logger.log({event}); 25 | var context = event.context, 26 | shape = context.shape || event.shape, 27 | hover = event.hover; 28 | 29 | var rootElement = canvas.getRootElement(); 30 | 31 | //var elementRef = shape.businessObject.elementRef; 32 | 33 | if (hover !== rootElement) { // && (shape.labelTarget || (elementRef && is(elementRef, 'archimate:Group')))) { 34 | event.hover = rootElement; 35 | event.hoverGfx = elementRegistry.getGraphics(event.hover); 36 | } 37 | }); 38 | 39 | } 40 | 41 | FixHoverBehavior.$inject = [ 42 | 'elementRegistry', 43 | 'eventBus', 44 | 'canvas' 45 | ]; -------------------------------------------------------------------------------- /lib/features/modeling/behavior/ImportDockingFix.js: -------------------------------------------------------------------------------- 1 | import { 2 | getMid 3 | } from 'diagram-js/lib/layout/LayoutUtil'; 4 | 5 | import lineIntersect from './util/LineIntersect'; 6 | 7 | import { logger } from '../../../util/Logger'; 8 | 9 | 10 | /** 11 | * Fix broken dockings after DI imports. 12 | * 13 | * @param {EventBus} eventBus 14 | */ 15 | export default function ImportDockingFix(eventBus) { 16 | 17 | function adjustDocking(startPoint, nextPoint, elementMid) { 18 | 19 | var elementTop = { 20 | x: elementMid.x, 21 | y: elementMid.y - 50 22 | }; 23 | 24 | var elementLeft = { 25 | x: elementMid.x - 50, 26 | y: elementMid.y 27 | }; 28 | 29 | var verticalIntersect = lineIntersect(startPoint, nextPoint, elementMid, elementTop), 30 | horizontalIntersect = lineIntersect(startPoint, nextPoint, elementMid, elementLeft); 31 | 32 | // original is horizontal or vertical center cross intersection 33 | var centerIntersect; 34 | 35 | if (verticalIntersect && horizontalIntersect) { 36 | if (getDistance(verticalIntersect, elementMid) > getDistance(horizontalIntersect, elementMid)) { 37 | centerIntersect = horizontalIntersect; 38 | } else { 39 | centerIntersect = verticalIntersect; 40 | } 41 | } else { 42 | centerIntersect = verticalIntersect || horizontalIntersect; 43 | } 44 | 45 | startPoint.original = centerIntersect; 46 | } 47 | 48 | function fixDockings(connection) { 49 | var waypoints = connection.waypoints; 50 | 51 | adjustDocking( 52 | waypoints[0], 53 | waypoints[1], 54 | getMid(connection.source) 55 | ); 56 | 57 | adjustDocking( 58 | waypoints[waypoints.length - 1], 59 | waypoints[waypoints.length - 2], 60 | getMid(connection.target) 61 | ); 62 | } 63 | 64 | eventBus.on('elementRef.added', function(event) { 65 | logger.log({event}); 66 | var element = event.element; 67 | 68 | if (element.waypoints) { 69 | fixDockings(element); 70 | } 71 | }); 72 | } 73 | 74 | ImportDockingFix.$inject = [ 75 | 'eventBus' 76 | ]; 77 | 78 | 79 | // helpers ////////////////////// 80 | 81 | function getDistance(p1, p2) { 82 | return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2)); 83 | } -------------------------------------------------------------------------------- /lib/features/modeling/behavior/ReplaceElementBehaviour.js: -------------------------------------------------------------------------------- 1 | import inherits from 'inherits-browser'; 2 | 3 | import { forEach } from 'min-dash'; 4 | 5 | import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor'; 6 | 7 | import { getViewElement } from '../../../util/ModelUtil'; 8 | import { logger } from '../../../util/Logger'; 9 | 10 | /** 11 | * Archimate-specific replace behavior. 12 | */ 13 | export default function ReplaceElementBehaviour( 14 | archimateReplace, 15 | archimateRules, 16 | elementRegistry, 17 | injector, 18 | modeling, 19 | selection 20 | ) { 21 | injector.invoke(CommandInterceptor, this); 22 | 23 | this._archimateReplace = archimateReplace; 24 | this._elementRegistry = elementRegistry; 25 | this._selection = selection; 26 | 27 | 28 | // replace elements on move 29 | this.postExecuted([ 'elements.move' ], 500, function(event) { 30 | logger.log({event}); 31 | /* var context = event.context, 32 | target = context.newParent, 33 | newHost = context.newHost, 34 | elements = []; 35 | 36 | forEach(context.closure.topLevel, function(topLevelElements) { 37 | elements = elements.concat(topLevelElements); 38 | }); 39 | 40 | // set target to host if attaching 41 | if (elements.length === 1 && newHost) { 42 | target = newHost; 43 | } 44 | 45 | var canReplace = archimateRules.canReplace(elements, target); 46 | 47 | if (canReplace) { 48 | this.replaceElements(elements, canReplace.replacements, newHost); 49 | */ 50 | }, this); 51 | 52 | // update attachments on host replace 53 | this.postExecute([ 'shape.replace' ], 1500, function(event) { 54 | logger.log({event}); 55 | var context = event.context, 56 | oldShape = context.oldShape, 57 | newShape = context.newShape, 58 | attachers = oldShape.attachers, 59 | canReplace; 60 | 61 | if (attachers && attachers.length) { 62 | canReplace = archimateRules.canReplace(attachers, newShape); 63 | 64 | this.replaceElements(attachers, canReplace.replacements); 65 | } 66 | 67 | }, this); 68 | 69 | // keep ID on shape replace 70 | this.postExecuted([ 'shape.replace' ], 1500, function(event) { 71 | logger.log({event}); 72 | var context = event.context, 73 | oldShape = context.oldShape, 74 | newShape = context.newShape; 75 | 76 | oldViewElement = getViewElement(oldShape); 77 | 78 | modeling.unclaimId(oldViewElement.id, oldViewElement); 79 | modeling.updateProperties(newShape, { id: oldShape.id }); 80 | }); 81 | } 82 | 83 | inherits(ReplaceElementBehaviour, CommandInterceptor); 84 | 85 | ReplaceElementBehaviour.prototype.replaceElements = function(elements, newElements) { 86 | var elementRegistry = this._elementRegistry, 87 | archimateReplace = this._archimateReplace, 88 | selection = this._selection; 89 | 90 | forEach(newElements, function(replacement) { 91 | var newElement = { 92 | type: replacement.newElementType 93 | }; 94 | 95 | var oldElement = elementRegistry.get(replacement.oldElementId); 96 | 97 | var idx = elements.indexOf(oldElement); 98 | 99 | elements[idx] = archimateReplace.replaceElement(oldElement, newElement, { select: false }); 100 | }); 101 | 102 | if (newElements) { 103 | selection.select(elements); 104 | } 105 | }; 106 | 107 | ReplaceElementBehaviour.$inject = [ 108 | 'archimateReplace', 109 | 'archimateRules', 110 | 'elementRegistry', 111 | 'injector', 112 | 'modeling', 113 | 'selection' 114 | ]; 115 | -------------------------------------------------------------------------------- /lib/features/modeling/behavior/UnclaimIdBehavior.js: -------------------------------------------------------------------------------- 1 | import inherits from 'inherits-browser'; 2 | 3 | import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor'; 4 | 5 | import { isLabel } from '../../../util/LabelUtil'; 6 | 7 | import { getElementRef, NOTE } from '../../../util/ModelUtil'; 8 | 9 | import { logger } from "../../../util/Logger"; 10 | 11 | /** 12 | * Unclaims model IDs on element deletion. 13 | * 14 | * @param {Canvas} canvas 15 | * @param {Injector} injector 16 | * @param {Moddle} moddle 17 | * @param {Modeling} modeling 18 | */ 19 | export default function UnclaimIdBehavior(canvas, injector, moddle, modeling) { 20 | injector.invoke(CommandInterceptor, this); 21 | 22 | this.preExecute('shape.delete', function(event) { 23 | logger.log({event}); 24 | var context = event.context, 25 | shape = context.shape, 26 | elementRef = getElementRef(shape); 27 | 28 | logger.log('shape.delete in UnclaimIdBehavior'); 29 | logger.log(shape); 30 | 31 | if (isLabel(shape)) { 32 | return; 33 | } 34 | 35 | if (shape.type === NOTE) { 36 | return; 37 | } 38 | 39 | //modeling.unclaimId(elementRef.id, elementRef); 40 | }); 41 | 42 | this.preExecute('canvas.updateRoot', function(event) { 43 | logger.log({event}); 44 | var rootElement = canvas.getRootElement(), 45 | rootElementRef = getElementRef(rootElement); 46 | 47 | logger.log('canvas.updateRoot in UnclaimIdBehavior'); 48 | logger.log(rootElement); 49 | 50 | moddle.ids.unclaim(rootElementRef.id); 51 | }); 52 | } 53 | 54 | inherits(UnclaimIdBehavior, CommandInterceptor); 55 | 56 | UnclaimIdBehavior.$inject = [ 'canvas', 'injector', 'moddle', 'modeling' ]; -------------------------------------------------------------------------------- /lib/features/modeling/behavior/index.js: -------------------------------------------------------------------------------- 1 | import AdaptiveLabelPositioningBehavior from './AdaptiveLabelPositioningBehavior'; 2 | import AppendBehavior from './AppendBehavior'; 3 | import FixHoverBehavior from './FixHoverBehavior'; 4 | import ImportDockingFix from './ImportDockingFix'; 5 | import LabelBehavior from './LabelBehavior'; 6 | import ReplaceElementBehaviour from './ReplaceElementBehaviour'; 7 | import UnclaimIdBehavior from './UnclaimIdBehavior'; 8 | import ConnectionToConnectionBehavior from './ConnectionToConnectionBehavior'; 9 | import AttachmentBehavior from './AttachmentBehavior'; 10 | 11 | export default { 12 | 13 | __depends__: [ 14 | // PopupMenuModule 15 | ], 16 | 17 | __init__: [ 18 | 'adaptiveLabelPositioningBehavior', 19 | 'appendBehavior', 20 | 'fixHoverBehavior', 21 | 'importDockingFix', 22 | 'labelBehavior', 23 | 'replaceElementBehaviour', 24 | 'unclaimIdBehavior', 25 | 'connectionToConnectionBehavior', 26 | 'attachmentBehavior', 27 | ], 28 | adaptiveLabelPositioningBehavior: [ 'type', AdaptiveLabelPositioningBehavior ], 29 | appendBehavior: [ 'type', AppendBehavior ], 30 | fixHoverBehavior: [ 'type', FixHoverBehavior ], 31 | importDockingFix: [ 'type', ImportDockingFix ], 32 | labelBehavior: [ 'type', LabelBehavior ], 33 | replaceElementBehaviour: [ 'type', ReplaceElementBehaviour ], 34 | unclaimIdBehavior: [ 'type', UnclaimIdBehavior ], 35 | connectionToConnectionBehavior: [ 'type', ConnectionToConnectionBehavior ], 36 | attachmentBehavior: [ 'type', AttachmentBehavior ], 37 | }; 38 | -------------------------------------------------------------------------------- /lib/features/modeling/behavior/util/ConnectionLayoutUtil.js: -------------------------------------------------------------------------------- 1 | import { getAnchorPointAdjustment } from './LayoutUtil'; 2 | 3 | /** 4 | * @typedef {import('diagram-js/lib/util/Types').Point} Point 5 | * 6 | * @typedef {import('./LayoutUtil').FindNewLineStartIndexHints} FindNewLineStartIndexHints 7 | */ 8 | 9 | /** 10 | * Calculate the new point after the connection waypoints got updated. 11 | * 12 | * @param {Point} position 13 | * @param {Point[]} newWaypoints 14 | * @param {Point[]} oldWaypoints 15 | * @param {FindNewLineStartIndexHints} hints 16 | * 17 | * @return {Point} 18 | */ 19 | export function getConnectionAdjustment(position, newWaypoints, oldWaypoints, hints) { 20 | return getAnchorPointAdjustment(position, newWaypoints, oldWaypoints, hints).point; 21 | } 22 | -------------------------------------------------------------------------------- /lib/features/modeling/behavior/util/GeometricUtil.js: -------------------------------------------------------------------------------- 1 | export * from 'diagram-js/lib/features/bendpoints/GeometricUtil'; -------------------------------------------------------------------------------- /lib/features/modeling/behavior/util/LineIntersect.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @typedef {import('diagram-js/lib/util/Types').Point} Point 3 | */ 4 | 5 | /** 6 | * Returns the intersection between two line segments a and b. 7 | * 8 | * @param {Point} l1s 9 | * @param {Point} l1e 10 | * @param {Point} l2s 11 | * @param {Point} l2e 12 | * 13 | * @return {Point} 14 | */ 15 | export default function lineIntersect(l1s, l1e, l2s, l2e) { 16 | 17 | // if the lines intersect, the result contains the x and y of the 18 | // intersection (treating the lines as infinite) and booleans for 19 | // whether line segment 1 or line segment 2 contain the point 20 | var denominator, a, b, c, numerator; 21 | 22 | denominator = ((l2e.y - l2s.y) * (l1e.x - l1s.x)) - ((l2e.x - l2s.x) * (l1e.y - l1s.y)); 23 | 24 | if (denominator == 0) { 25 | return null; 26 | } 27 | 28 | a = l1s.y - l2s.y; 29 | b = l1s.x - l2s.x; 30 | numerator = ((l2e.x - l2s.x) * a) - ((l2e.y - l2s.y) * b); 31 | 32 | c = numerator / denominator; 33 | 34 | // if we cast these lines infinitely in 35 | // both directions, they intersect here 36 | return { 37 | x: Math.round(l1s.x + (c * (l1e.x - l1s.x))), 38 | y: Math.round(l1s.y + (c * (l1e.y - l1s.y))) 39 | }; 40 | } -------------------------------------------------------------------------------- /lib/features/modeling/cmd/IdClaimHandler.js: -------------------------------------------------------------------------------- 1 | export default function IdClaimHandler(moddle) { 2 | this._moddle = moddle; 3 | } 4 | 5 | IdClaimHandler.$inject = [ 'moddle' ]; 6 | 7 | 8 | IdClaimHandler.prototype.execute = function(context) { 9 | var ids = this._moddle.ids, 10 | id = context.id, 11 | element = context.element, 12 | claiming = context.claiming; 13 | 14 | if (claiming) { 15 | ids.claim(id, element); 16 | } else { 17 | ids.unclaim(id); 18 | } 19 | }; 20 | 21 | /** 22 | * Command revert implementation. 23 | */ 24 | IdClaimHandler.prototype.revert = function(context) { 25 | var ids = this._moddle.ids, 26 | id = context.id, 27 | element = context.element, 28 | claiming = context.claiming; 29 | 30 | if (claiming) { 31 | ids.unclaim(id); 32 | } else { 33 | ids.claim(id, element); 34 | } 35 | }; 36 | 37 | -------------------------------------------------------------------------------- /lib/features/modeling/cmd/SetColorHandler.js: -------------------------------------------------------------------------------- 1 | import { forEach, assign } from 'min-dash'; 2 | 3 | import { toRgba } from '../../../util/ColorUtil'; 4 | 5 | export default function SetColorHandler(commandStack, eventBus, archimateFactory) { 6 | this._commandStack = commandStack; 7 | this._eventBus = eventBus; 8 | this._archimateFactory = archimateFactory; 9 | } 10 | 11 | SetColorHandler.$inject = [ 12 | 'commandStack', 13 | 'eventBus', 14 | 'archimateFactory' 15 | ]; 16 | 17 | SetColorHandler.prototype.postExecute = function(context) { 18 | var elements = context.elements, 19 | changed = [ elements ], 20 | property = context.property; 21 | 22 | var self = this; 23 | 24 | forEach(elements, function(element) { 25 | 26 | var style = element.businessObject.style; 27 | 28 | switch(property.name) { 29 | case 'fillColor': 30 | element.fillColor = property.value; 31 | assign(style.fillColor, toRgba(property.value)); 32 | break; 33 | 34 | case 'lineColor': 35 | element.lineColor = property.value; 36 | assign(style.lineColor, toRgba(property.value)); 37 | break; 38 | 39 | default: 40 | // code block 41 | } 42 | }); 43 | 44 | self._eventBus.fire('elements.changed', { elements }); 45 | 46 | return changed; 47 | }; -------------------------------------------------------------------------------- /lib/features/modeling/cmd/UpdateCanvasRootHandler.js: -------------------------------------------------------------------------------- 1 | import { 2 | add as collectionAdd, 3 | remove as collectionRemove 4 | } from 'diagram-js/lib/util/Collections'; 5 | 6 | export default function UpdateCanvasRootHandler(canvas, modeling) { 7 | this._canvas = canvas; 8 | this._modeling = modeling; 9 | } 10 | 11 | UpdateCanvasRootHandler.$inject = [ 12 | 'canvas', 13 | 'modeling' 14 | ]; 15 | 16 | 17 | UpdateCanvasRootHandler.prototype.execute = function(context) { 18 | 19 | var canvas = this._canvas; 20 | 21 | // TODO(vbo) businessObject for root element is ARCHIMATE_VIEW 22 | // as business target must so no need to change when diObject delete 23 | 24 | var newRoot = context.newRoot, 25 | newRootBusinessObject = newRoot.businessObject, 26 | oldRoot = canvas.getRootElement(), 27 | oldRootBusinessObject = oldRoot.businessObject, 28 | oldRootBusinessObjectParent = oldRootBusinessObject.$parent; 29 | 30 | 31 | // (1) replace process old <> new root 32 | canvas.setRootElement(newRoot, true); 33 | 34 | // (2) update root elements 35 | collectionAdd(oldRootBusinessObjectParent.rootElements, newRootBusinessObject); 36 | newRootBusinessObject.$parent = oldRootBusinessObjectParent; 37 | 38 | collectionRemove(oldRootBusinessObjectParent.rootElements, oldRootBusinessObject); 39 | oldRootBusinessObject.$parent = null; 40 | 41 | context.oldRoot = oldRoot; 42 | 43 | // TODO(nikku): return changed elements? 44 | // return [ newRoot, oldRoot ]; 45 | }; 46 | 47 | 48 | UpdateCanvasRootHandler.prototype.revert = function(context) { 49 | 50 | var canvas = this._canvas; 51 | 52 | var newRoot = context.newRoot, 53 | newRootBusinessObject = newRoot.businessObject, 54 | oldRoot = context.oldRoot, 55 | oldRootBusinessObject = oldRoot.businessObject, 56 | oldRootBusinessObjectParent = newRootBusinessObject.$parent; 57 | 58 | // (1) replace process old <> new root 59 | canvas.setRootElement(oldRoot, true); 60 | 61 | // (2) update root elements 62 | collectionRemove(oldRootBusinessObjectParent.rootElements, newRootBusinessObject); 63 | newRootBusinessObject.$parent = null; 64 | 65 | collectionAdd(oldRootBusinessObjectParent.rootElements, oldRootBusinessObject); 66 | oldRootBusinessObject.$parent = oldRootBusinessObjectParent; 67 | 68 | // TODO(nikku): return changed elements? 69 | // return [ newRoot, oldRoot ]; 70 | }; -------------------------------------------------------------------------------- /lib/features/modeling/cmd/UpdateModdlePropertiesHandler.js: -------------------------------------------------------------------------------- 1 | import { 2 | reduce, 3 | keys, 4 | forEach 5 | } from 'min-dash'; 6 | 7 | import { 8 | is, 9 | getBusinessObject 10 | } from '../../../util/ModelUtil'; 11 | 12 | /** 13 | * @typedef {import('diagram-js/lib/command/CommandHandler').default} CommandHandler 14 | * 15 | * @typedef {import('diagram-js/lib/core/ElementRegistry').default} ElementRegistry 16 | * 17 | * @typedef {import('../../../model/Types').Shape} Shape 18 | * @typedef {import('../../../model/Types').ModdleElement} ModdleElement 19 | */ 20 | 21 | /** 22 | * @implements {CommandHandler} 23 | * 24 | * @param {ElementRegistry} elementRegistry 25 | */ 26 | export default function UpdateModdlePropertiesHandler(elementRegistry) { 27 | this._elementRegistry = elementRegistry; 28 | } 29 | 30 | UpdateModdlePropertiesHandler.$inject = [ 'elementRegistry' ]; 31 | 32 | UpdateModdlePropertiesHandler.prototype.execute = function(context) { 33 | 34 | var element = context.element, 35 | moddleElement = context.moddleElement, 36 | properties = context.properties; 37 | 38 | if (!moddleElement) { 39 | throw new Error(' required'); 40 | } 41 | 42 | // TODO(nikku): we need to ensure that ID properties 43 | // are properly registered / unregistered via 44 | // this._moddle.ids.assigned(id) 45 | var changed = context.changed || this._getVisualReferences(moddleElement).concat(element); 46 | var oldProperties = context.oldProperties || getModdleProperties(moddleElement, keys(properties)); 47 | 48 | setModdleProperties(moddleElement, properties); 49 | 50 | context.oldProperties = oldProperties; 51 | context.changed = changed; 52 | 53 | return changed; 54 | }; 55 | 56 | UpdateModdlePropertiesHandler.prototype.revert = function(context) { 57 | var oldProperties = context.oldProperties, 58 | moddleElement = context.moddleElement, 59 | changed = context.changed; 60 | 61 | setModdleProperties(moddleElement, oldProperties); 62 | 63 | return changed; 64 | }; 65 | 66 | /** 67 | * Return visual references of given moddle element within the diagram. 68 | * 69 | * @param {ModdleElement} moddleElement 70 | * 71 | * @return {Shape[]} 72 | */ 73 | UpdateModdlePropertiesHandler.prototype._getVisualReferences = function(moddleElement) { 74 | 75 | var elementRegistry = this._elementRegistry; 76 | 77 | if (is(moddleElement, 'bpmn:DataObject')) { 78 | return getAllDataObjectReferences(moddleElement, elementRegistry); 79 | } 80 | 81 | return []; 82 | }; 83 | 84 | 85 | // helpers ///////////////// 86 | 87 | function getModdleProperties(moddleElement, propertyNames) { 88 | return reduce(propertyNames, function(result, key) { 89 | result[key] = moddleElement.get(key); 90 | return result; 91 | }, {}); 92 | } 93 | 94 | function setModdleProperties(moddleElement, properties) { 95 | forEach(properties, function(value, key) { 96 | moddleElement.set(key, value); 97 | }); 98 | } 99 | 100 | function getAllDataObjectReferences(dataObject, elementRegistry) { 101 | return elementRegistry.filter(function(element) { 102 | return ( 103 | is(element, 'bpmn:DataObjectReference') && 104 | getBusinessObject(element).dataObjectRef === dataObject 105 | ); 106 | }); 107 | } -------------------------------------------------------------------------------- /lib/features/modeling/index.js: -------------------------------------------------------------------------------- 1 | import BehaviorModule from './behavior'; 2 | import RulesModule from '../rules'; 3 | import OrderingModule from '../ordering'; 4 | import ReplaceModule from '../replace'; 5 | 6 | import CommandModule from 'diagram-js/lib/command'; 7 | import TooltipsModule from 'diagram-js/lib/features/tooltips'; 8 | import LabelSupportModule from 'diagram-js/lib/features/label-support'; 9 | import AttachSupportModule from 'diagram-js/lib/features/attach-support'; 10 | import SelectionModule from 'diagram-js/lib/features/selection'; 11 | import ChangeSupportModule from 'diagram-js/lib/features/change-support'; 12 | import SpaceToolModule from 'diagram-js/lib/features/space-tool'; 13 | import CreateModule from 'diagram-js/lib/features/create' 14 | // import Layouter from 'diagram-js/lib/layout/BaseLayouter'; 15 | 16 | import ArchimateFactory from './ArchimateFactory'; 17 | import NodeUpdater from './NodeUpdater'; 18 | import ConnectionUpdater from './ConnectionUpdater'; 19 | import ElementFactory from './ElementFactory'; 20 | import Modeling from './Modeling'; 21 | import ArchimateLayouter from './ArchimateLayouter'; 22 | import CroppingConnectionDocking from 'diagram-js/lib/layout/CroppingConnectionDocking'; 23 | 24 | 25 | export default { 26 | __init__: [ 27 | 'modeling', 28 | 'nodeUpdater', 29 | 'connectionUpdater' 30 | ], 31 | __depends__: [ 32 | BehaviorModule, 33 | RulesModule, 34 | CreateModule, 35 | OrderingModule, 36 | ReplaceModule, 37 | CommandModule, 38 | TooltipsModule, 39 | LabelSupportModule, 40 | AttachSupportModule, 41 | SelectionModule, 42 | ChangeSupportModule, 43 | SpaceToolModule 44 | ], 45 | archimateFactory: [ 'type', ArchimateFactory ], 46 | nodeUpdater: [ 'type', NodeUpdater ], 47 | connectionUpdater: [ 'type', ConnectionUpdater ], 48 | elementFactory: [ 'type', ElementFactory ], 49 | modeling: [ 'type', Modeling ], 50 | layouter: [ 'type', ArchimateLayouter ], 51 | connectionDocking: [ 'type', CroppingConnectionDocking ] 52 | }; -------------------------------------------------------------------------------- /lib/features/ordering/ArchimateOrdering.js: -------------------------------------------------------------------------------- 1 | // import { getDi } from '../../util/ModelUtil'; 2 | 3 | import { 4 | filter, 5 | forEach, 6 | map 7 | } from 'min-dash'; 8 | 9 | import { selfAndAllChildren } from 'diagram-js/lib/util/Elements'; 10 | 11 | import { logger } from "../../util/Logger"; 12 | 13 | /** 14 | * @typedef {import('diagram-js/lib/core/EventBus').default} EventBus 15 | * @typedef {import('diagram-js/lib/core/Canvas').default} Canvas 16 | */ 17 | 18 | var HIGH_PRIORITY = 2000; 19 | 20 | /** 21 | * @param {EventBus} eventBus 22 | * @param {Canvas} canvas 23 | */ 24 | export default function ArchimateOrdering(eventBus, canvas) { 25 | 26 | eventBus.on('saveXML.start', HIGH_PRIORITY, orderDi); 27 | 28 | function orderDi() { 29 | 30 | var rootElements = canvas.getRootElements(); 31 | 32 | logger.log(rootElements); 33 | 34 | forEach(rootElements, function(root) { 35 | var rootDi = root, 36 | elements, 37 | diElements; 38 | 39 | elements = selfAndAllChildren([ root ], false); 40 | 41 | // only bpmndi:Shape and bpmndi:Edge can be direct children of bpmndi:Plane 42 | elements = filter(elements, function(element) { 43 | return element !== root && !element.labelTarget; 44 | }); 45 | 46 | //diElements = map(elements, getDi); 47 | 48 | rootDi.set('planeElement', elements); //diElements); 49 | }); 50 | } 51 | } 52 | 53 | ArchimateOrdering.$inject = [ 'eventBus', 'canvas' ]; -------------------------------------------------------------------------------- /lib/features/ordering/index.js: -------------------------------------------------------------------------------- 1 | import translate from 'diagram-js/lib/i18n/translate'; 2 | 3 | import ArchimateOrderingProvider from './ArchimateOrderingProvider'; 4 | import ArchimateOrdering from './ArchimateOrdering'; 5 | 6 | export default { 7 | __depends__: [ 8 | translate 9 | ], 10 | __init__: [ 11 | 'archimateOrderingProvider', 12 | 'archimateOrdering' 13 | ], 14 | archimateOrderingProvider: [ 'type', ArchimateOrderingProvider ], 15 | archimateOrdering: ['type', ArchimateOrdering] 16 | }; -------------------------------------------------------------------------------- /lib/features/palette/index.js: -------------------------------------------------------------------------------- 1 | import PaletteModule from 'diagram-js/lib/features/palette'; 2 | import CreateModule from 'diagram-js/lib/features/create'; 3 | import SpaceToolModule from 'diagram-js/lib/features/space-tool'; 4 | import LassoToolModule from 'diagram-js/lib/features/lasso-tool'; 5 | import HandToolModule from 'diagram-js/lib/features/hand-tool'; 6 | import TranslateModule from 'diagram-js/lib/i18n/translate'; 7 | 8 | import PopupMenuModule from '../popup-menu'; 9 | import PaletteProvider from './PaletteProvider'; 10 | 11 | export default { 12 | __depends__: [ 13 | PaletteModule, 14 | CreateModule, 15 | SpaceToolModule, 16 | LassoToolModule, 17 | HandToolModule, 18 | TranslateModule, 19 | PopupMenuModule 20 | ], 21 | __init__: [ 'paletteProvider' ], 22 | paletteProvider: [ 'type', PaletteProvider ] 23 | }; 24 | -------------------------------------------------------------------------------- /lib/features/popup-menu/index.js: -------------------------------------------------------------------------------- 1 | import PopupMenuModule from 'diagram-js/lib/features/popup-menu'; 2 | import CreateModule from 'diagram-js/lib/features/create' 3 | //import ReplaceModule from '../replace'; 4 | 5 | import ConnectionMenuProvider from './ConnectionMenuProvider'; 6 | import ElementRefMenuProvider from './ElementRefMenuProvider'; 7 | import TextMenuProvider from './TextMenuProvider'; 8 | 9 | export default { 10 | __depends__: [ 11 | PopupMenuModule, 12 | CreateModule, 13 | // ReplaceModule 14 | ], 15 | __init__: [ 16 | 'connectionMenuProvider', 17 | 'elementRefMenuProvider', 18 | 'textMenuProvider' 19 | ], 20 | connectionMenuProvider: [ 'type', ConnectionMenuProvider ], 21 | elementRefMenuProvider : [ 'type', ElementRefMenuProvider ], 22 | textMenuProvider: [ 'type', TextMenuProvider] 23 | }; -------------------------------------------------------------------------------- /lib/features/replace-preview/ArchimateReplacePreview.js: -------------------------------------------------------------------------------- 1 | import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor'; 2 | 3 | import inherits from 'inherits-browser'; 4 | 5 | import cssEscape from 'css.escape'; 6 | 7 | import { 8 | assign, 9 | forEach 10 | } from 'min-dash'; 11 | 12 | import { 13 | query as domQuery 14 | } from 'min-dom'; 15 | 16 | import { 17 | attr as svgAttr 18 | } from 'tiny-svg'; 19 | 20 | var LOW_PRIORITY = 250; 21 | 22 | 23 | export default function ArchimateReplacePreview( 24 | eventBus, elementRegistry, elementFactory, 25 | canvas, previewSupport) { 26 | 27 | CommandInterceptor.call(this, eventBus); 28 | 29 | /** 30 | * Replace the visuals of all elements in the context which can be replaced 31 | * 32 | * @param {Object} context 33 | */ 34 | function replaceVisual(context) { 35 | 36 | var replacements = context.canExecute.replacements; 37 | 38 | forEach(replacements, function(replacement) { 39 | 40 | var id = replacement.oldElementId; 41 | 42 | var newElement = { 43 | type: replacement.newElementType 44 | }; 45 | 46 | // if the visual of the element is already replaced 47 | if (context.visualReplacements[id]) { 48 | return; 49 | } 50 | 51 | var element = elementRegistry.get(id); 52 | 53 | assign(newElement, { x: element.x, y: element.y }); 54 | 55 | // create a temporary shape 56 | var tempShape = elementFactory.createShape(newElement); 57 | 58 | canvas.addShape(tempShape, element.parent); 59 | 60 | // select the original SVG element related to the element and hide it 61 | var gfx = domQuery('[data-element-id="' + cssEscape(element.id) + '"]', context.dragGroup); 62 | 63 | if (gfx) { 64 | svgAttr(gfx, { display: 'none' }); 65 | } 66 | 67 | // clone the gfx of the temporary shape and add it to the drag group 68 | var dragger = previewSupport.addDragger(tempShape, context.dragGroup); 69 | 70 | context.visualReplacements[id] = dragger; 71 | 72 | canvas.removeShape(tempShape); 73 | }); 74 | } 75 | 76 | /** 77 | * Restore the original visuals of the previously replaced elements 78 | * 79 | * @param {Object} context 80 | */ 81 | function restoreVisual(context) { 82 | 83 | var visualReplacements = context.visualReplacements; 84 | 85 | forEach(visualReplacements, function(dragger, id) { 86 | 87 | var originalGfx = domQuery('[data-element-id="' + cssEscape(id) + '"]', context.dragGroup); 88 | 89 | if (originalGfx) { 90 | svgAttr(originalGfx, { display: 'inline' }); 91 | } 92 | 93 | dragger.remove(); 94 | 95 | if (visualReplacements[id]) { 96 | delete visualReplacements[id]; 97 | } 98 | }); 99 | } 100 | 101 | eventBus.on('shape.move.move', LOW_PRIORITY, function(event) { 102 | 103 | var context = event.context, 104 | canExecute = context.canExecute; 105 | 106 | if (!context.visualReplacements) { 107 | context.visualReplacements = {}; 108 | } 109 | 110 | if (canExecute && canExecute.replacements) { 111 | replaceVisual(context); 112 | } else { 113 | restoreVisual(context); 114 | } 115 | }); 116 | } 117 | 118 | ArchimateReplacePreview.$inject = [ 119 | 'eventBus', 120 | 'elementRegistry', 121 | 'elementFactory', 122 | 'canvas', 123 | 'previewSupport' 124 | ]; 125 | 126 | inherits(ArchimateReplacePreview, CommandInterceptor); -------------------------------------------------------------------------------- /lib/features/replace-preview/index.js: -------------------------------------------------------------------------------- 1 | import PreviewSupportModule from 'diagram-js/lib/features/preview-support'; 2 | 3 | import ArchimateReplacePreview from './ArchimateReplacePreview'; 4 | 5 | export default { 6 | __depends__: [ 7 | PreviewSupportModule 8 | ], 9 | __init__: [ 'archimateReplacePreview' ], 10 | archimateReplacePreview: [ 'type', ArchimateReplacePreview ] 11 | }; 12 | -------------------------------------------------------------------------------- /lib/features/replace/ArchimateReplace.js: -------------------------------------------------------------------------------- 1 | import { 2 | pick, 3 | assign, 4 | forEach, 5 | isArray, 6 | isUndefined 7 | } from 'min-dash'; 8 | import { logger } from '../../util/Logger'; 9 | 10 | import { getPropertyNames } from '../copy-paste/ModdleCopy'; 11 | 12 | function copyProperties(source, target, properties) { 13 | if (!isArray(properties)) { 14 | properties = [ properties ]; 15 | } 16 | 17 | forEach(properties, function(property) { 18 | if (!isUndefined(source[property])) { 19 | target[property] = source[property]; 20 | } 21 | }); 22 | } 23 | 24 | var CUSTOM_PROPERTIES = [ 25 | 'cancelActivity', 26 | 'instantiate', 27 | 'eventGatewayType', 28 | 'triggeredByEvent', 29 | 'isInterrupting' 30 | ]; 31 | 32 | 33 | 34 | /** 35 | * TODO(vbo) TO REWRITE 36 | * 37 | * business object links to viewElement which links to elementRef 38 | * In a replace function, we need to : 39 | * - create a new elementRef with the target type and links to existing viewElement 40 | * - delete old elementRef 41 | * - redraw new shape 42 | * 43 | * This module takes care of replacing elements 44 | */ 45 | export default function ArchimateReplace( 46 | archimateFactory, 47 | elementFactory, 48 | moddleCopy, 49 | modeling, 50 | replace, 51 | selection 52 | ) { 53 | 54 | /** 55 | * Prepares a new business object for the replacement element 56 | * and triggers the replace operation. 57 | * 58 | * @param {djs.model.Base} element 59 | * @param {Object} target 60 | * @param {Object} [hints] 61 | * 62 | * @return {djs.model.Base} the newly created element 63 | */ 64 | function replaceElement(element, target, hints) { 65 | 66 | hints = hints || {}; 67 | 68 | logger.log('replaceElement'); 69 | logger.log(element); 70 | logger.log(target); 71 | /* 72 | var type = target.type, 73 | oldBusinessObject = element.businessObject; 74 | 75 | var newBusinessObject = archimateFactory.create(type); 76 | 77 | var newElement = { 78 | type: type, 79 | businessObject: newBusinessObject 80 | }; 81 | 82 | var elementProps = getPropertyNames(oldBusinessObject.$descriptor), 83 | newElementProps = getPropertyNames(newBusinessObject.$descriptor, true), 84 | copyProps = intersection(elementProps, newElementProps); 85 | 86 | // initialize special properties defined in target definition 87 | assign(newBusinessObject, pick(target, CUSTOM_PROPERTIES)); 88 | 89 | var properties = copyProps; 90 | 91 | newBusinessObject = moddleCopy.copyElement( 92 | oldBusinessObject, 93 | newBusinessObject, 94 | properties 95 | ); 96 | 97 | newBusinessObject.name = oldBusinessObject.name; 98 | 99 | newElement.di = {}; 100 | 101 | // fill and stroke will be set to DI 102 | copyProperties(oldBusinessObject.di, newElement.di, [ 103 | 'fill', 104 | 'stroke' 105 | ]); 106 | 107 | newElement = replace.replaceElement(element, newElement, hints); 108 | 109 | if (hints.select !== false) { 110 | selection.select(newElement); 111 | } 112 | 113 | return newElement; 114 | */ 115 | 116 | element.businessObject.relationshipRef.type = 'Aggregation'; 117 | 118 | var newElement = { 119 | type: 'Aggregation', 120 | businessObject: element.businessObject 121 | }; 122 | 123 | // TODO VBO diagram.js do not replace connections, yet 124 | newElement = replace.replaceElement(element, newElement, hints); 125 | 126 | if (hints.select !== false) { 127 | selection.select(newElement); 128 | } 129 | 130 | return newElement; 131 | } 132 | 133 | this.replaceElement = replaceElement; 134 | } 135 | 136 | ArchimateReplace.$inject = [ 137 | 'archimateFactory', 138 | 'elementFactory', 139 | 'moddleCopy', 140 | 'modeling', 141 | 'replace', 142 | 'selection' 143 | ]; 144 | 145 | /** 146 | * Compute intersection between two arrays. 147 | */ 148 | function intersection(a1, a2) { 149 | return a1.filter(function(el) { 150 | return a2.indexOf(el) !== -1; 151 | }); 152 | } 153 | -------------------------------------------------------------------------------- /lib/features/replace/ReplaceOptions.js: -------------------------------------------------------------------------------- 1 | export var POST_IT = [ 2 | 3 | ]; 4 | -------------------------------------------------------------------------------- /lib/features/replace/index.js: -------------------------------------------------------------------------------- 1 | import CopyPasteModule from '../copy-paste'; 2 | import ReplaceModule from 'diagram-js/lib/features/replace'; 3 | import SelectionModule from 'diagram-js/lib/features/selection'; 4 | 5 | import ArchimateReplace from './ArchimateReplace'; 6 | 7 | export default { 8 | __depends__: [ 9 | CopyPasteModule, 10 | ReplaceModule, 11 | SelectionModule 12 | ], 13 | archimateReplace: [ 'type', ArchimateReplace ] 14 | }; 15 | -------------------------------------------------------------------------------- /lib/features/rules/index.js: -------------------------------------------------------------------------------- 1 | import RulesModule from 'diagram-js/lib/features/rules'; 2 | 3 | import ArchimateRules from './ArchimateRules'; 4 | 5 | export default { 6 | __depends__: [ 7 | RulesModule 8 | ], 9 | __init__: [ 'archimateRules' ], 10 | archimateRules: [ 'type', ArchimateRules ] 11 | }; 12 | -------------------------------------------------------------------------------- /lib/features/snapping/ArchimateCreateMoveSnapping.js: -------------------------------------------------------------------------------- 1 | import inherits from 'inherits-browser'; 2 | 3 | import CreateMoveSnapping from 'diagram-js/lib/features/snapping/CreateMoveSnapping'; 4 | 5 | /** 6 | * Snap during create and move. 7 | * 8 | * @param {EventBus} eventBus 9 | * @param {Injector} injector 10 | */ 11 | export default function ArchimateCreateMoveSnapping(injector) { 12 | injector.invoke(CreateMoveSnapping, this); 13 | } 14 | 15 | inherits(ArchimateCreateMoveSnapping, CreateMoveSnapping); 16 | 17 | ArchimateCreateMoveSnapping.$inject = [ 18 | 'injector' 19 | ]; 20 | 21 | ArchimateCreateMoveSnapping.prototype.initSnap = function(event) { 22 | return CreateMoveSnapping.prototype.initSnap.call(this, event); 23 | }; 24 | 25 | ArchimateCreateMoveSnapping.prototype.addSnapTargetPoints = function(snapPoints, shape, target) { 26 | return CreateMoveSnapping.prototype.addSnapTargetPoints.call(this, snapPoints, shape, target); 27 | }; 28 | 29 | ArchimateCreateMoveSnapping.prototype.getSnapTargets = function(shape, target) { 30 | return CreateMoveSnapping.prototype.getSnapTargets.call(this, shape, target); 31 | }; 32 | -------------------------------------------------------------------------------- /lib/features/snapping/SnappingUtil.js: -------------------------------------------------------------------------------- 1 | import { getOrientation } from 'diagram-js/lib/layout/LayoutUtil'; 2 | 3 | export function getBoundaryAttachment(position, targetBounds) { 4 | 5 | var orientation = getOrientation(position, targetBounds, -15); 6 | 7 | if (orientation !== 'intersect') { 8 | return orientation; 9 | } else { 10 | return null; 11 | } 12 | } -------------------------------------------------------------------------------- /lib/features/snapping/index.js: -------------------------------------------------------------------------------- 1 | import ArchimateCreateMoveSnapping from './ArchimateCreateMoveSnapping'; 2 | import SnappingModule from 'diagram-js/lib/features/snapping'; 3 | 4 | export default { 5 | __depends__: [ SnappingModule ], 6 | __init__: [ 7 | 'createMoveSnapping' 8 | ], 9 | createMoveSnapping: [ 'type', ArchimateCreateMoveSnapping ] 10 | }; -------------------------------------------------------------------------------- /lib/import/Util.js: -------------------------------------------------------------------------------- 1 | export function elementToString(e) { 2 | if (!e) { 3 | return ''; 4 | } 5 | 6 | return '<' + e.$type + (e.id ? ' id="' + e.id : '') + '" />'; 7 | } -------------------------------------------------------------------------------- /lib/import/index.js: -------------------------------------------------------------------------------- 1 | import translate from 'diagram-js/lib/i18n/translate'; 2 | 3 | import ArchimateImporter from './ArchimateImporter'; 4 | 5 | export default { 6 | __depends__: [ 7 | translate 8 | ], 9 | ArchimateImporter: [ 'type', ArchimateImporter ] 10 | }; -------------------------------------------------------------------------------- /lib/moddle/Moddle.js: -------------------------------------------------------------------------------- 1 | import { isString, assign } from 'min-dash'; 2 | 3 | import { Moddle } from 'moddle'; 4 | 5 | import { Reader, Writer } from 'moddle-xml'; 6 | import { ARCHIMATE_MODEL } from '../metamodel/Concept'; 7 | 8 | /** 9 | * A sub class of {@link Moddle} with support for import and export of archimate-js xml files. 10 | * 11 | * @class ArchimateModdle 12 | * 13 | * @extends Moddle 14 | * 15 | * @param {Object|Array} packages to use for instantiating the model 16 | * @param {Object} [options] additional options to pass over 17 | */ 18 | export default function ArchimateModdle(packages, options) { 19 | Moddle.call(this, packages, options); 20 | } 21 | 22 | ArchimateModdle.prototype = Object.create(Moddle.prototype); 23 | 24 | /** 25 | * The fromXML result. 26 | * 27 | * @typedef {Object} ParseResult 28 | * 29 | * @property {ModdleElement} rootElement 30 | * @property {Array} references 31 | * @property {Array} warnings 32 | * @property {Object} elementsById - a mapping containing each ID -> ModdleElement 33 | */ 34 | 35 | /** 36 | * The fromXML error. 37 | * 38 | * @typedef {Error} ParseError 39 | * 40 | * @property {Array} warnings 41 | */ 42 | 43 | /** 44 | * Instantiates an Archimate model tree from a given xml string. 45 | * 46 | * @param {String} xmlStr 47 | * @param {String} [typeName=ARCHIMATE_MODEL] name of the root element, typically 'Model' 48 | * @param {Object} [options] options to pass to the underlying reader 49 | * 50 | * @returns {Promise} 51 | */ 52 | ArchimateModdle.prototype.fromXML = function(xmlStr, typeName, options) { 53 | if (!isString(typeName)) { 54 | options = typeName; 55 | typeName = ARCHIMATE_MODEL; 56 | 57 | } 58 | 59 | var reader = new Reader(assign({ model: this, lax: true }, options)); 60 | var rootHandler = reader.handler(typeName); 61 | 62 | return reader.fromXML(xmlStr, rootHandler); 63 | }; 64 | 65 | /** 66 | * The toXML result. 67 | * 68 | * @typedef {Object} SerializationResult 69 | * 70 | * @property {String} xml 71 | */ 72 | 73 | /** 74 | * Serializes a Archimate object tree to XML. 75 | * 76 | * @param {String} element the root element, typically an instance of 'Model' 77 | * @param {Object} [options] to pass to the underlying writer 78 | * 79 | * @returns {Promise} 80 | */ 81 | ArchimateModdle.prototype.toXML = function(element, options) { 82 | var writer = new Writer(options); 83 | 84 | return new Promise(function(resolve, reject) { 85 | try { 86 | var result = writer.toXML(element); 87 | 88 | return resolve({ 89 | xml: result 90 | }); 91 | } catch (err) { 92 | return reject(err); 93 | } 94 | }); 95 | }; 96 | -------------------------------------------------------------------------------- /lib/moddle/index.js: -------------------------------------------------------------------------------- 1 | import { 2 | assign 3 | } from 'min-dash'; 4 | 5 | import Moddle from './Moddle'; 6 | 7 | import ArchimateDescriptors from './resources/archimate.json'; 8 | 9 | var packages = { 10 | archimate: ArchimateDescriptors, 11 | }; 12 | 13 | export default function(additionalPackages, options) { 14 | var pks = assign({}, packages, additionalPackages); 15 | 16 | return new Moddle(pks, options); 17 | } -------------------------------------------------------------------------------- /lib/util/ColorUtil.js: -------------------------------------------------------------------------------- 1 | import { rgbaToHex, hexToRgba } from 'hex-and-rgba/esm'; 2 | 3 | 4 | import { 5 | LAYER_APPLICATION, LAYER_BUSINESS, LAYER_MOTIVATION, 6 | LAYER_STRATEGY, LAYER_IMP_MIG, 7 | LAYER_PHYSICAL, LAYER_TECHNOLOGY 8 | } from '../metamodel/Concept'; 9 | 10 | export const COLOR_LAYER_STRATEGY = '#F5DEAA', // 'rgba(245, 222, 170, 1)' 11 | COLOR_LAYER_BUSINESS = '#FFFFB5', // 'rgba(255, 255, 181, 1)' 12 | COLOR_LAYER_APPLICATION = '#B5FFFF', // 'rgba(181, 255, 255, 1)' 13 | COLOR_LAYER_TECHNOLOGY = '#C9E7B7', // 'rgba(201, 231, 183, 1)' 14 | COLOR_LAYER_PHYSICAL = '#C9E7B7', // 'rgba(201, 231, 183, 1)' 15 | COLOR_LAYER_IMP_MIG = '#FFE0E0', // 'rgba(255, 224, 224,1)' 16 | COLOR_LAYER_MOTIVATION = '#CCCCFF'; // 'rgba(204, 204, 255, 1)' 17 | 18 | export const COLOR_LAYER_MAP = new Map([ 19 | [LAYER_STRATEGY, COLOR_LAYER_STRATEGY], 20 | [LAYER_BUSINESS, COLOR_LAYER_BUSINESS], 21 | [LAYER_APPLICATION, COLOR_LAYER_APPLICATION], 22 | [LAYER_TECHNOLOGY, COLOR_LAYER_TECHNOLOGY], 23 | [LAYER_PHYSICAL, COLOR_LAYER_PHYSICAL], 24 | [LAYER_IMP_MIG, COLOR_LAYER_IMP_MIG], 25 | [LAYER_MOTIVATION, COLOR_LAYER_MOTIVATION] 26 | ]) 27 | 28 | export const BLACK_SHADOW = '#00000066', // 'rgba(0, 0, 0, 0.40)' 29 | DEFAULT_NOTE_COLOR = '#FFFFFF', 30 | DEFAULT_CONNECTION_COLOR = '#000000'; 31 | 32 | export function toHex(rgbaColor) { 33 | return rgbaColor && rgbaToHex(rgbaColor.r, rgbaColor.g, rgbaColor.b, rgbaColor.a/100 ); 34 | } 35 | 36 | export function toRgba(hexColor) { 37 | var color = hexToRgba(hexColor); 38 | if (color) { 39 | return {r: color[0], g: color[1], b: color[2], a: color[3]*100}; 40 | } else { 41 | return false 42 | } 43 | } -------------------------------------------------------------------------------- /lib/util/ElementUtil.js: -------------------------------------------------------------------------------- 1 | import { logger } from "./Logger"; 2 | 3 | export function getExistingElements(elementType, elementsNode, excludedElementId) { 4 | 5 | function filterNode(array, elementType, excludedElementId) { 6 | return array.filter((element) => { 7 | //logger.log(element); 8 | return element.type === elementType && element.id !== excludedElementId; 9 | }); 10 | } 11 | 12 | var existingElements = []; 13 | 14 | if (elementsNode) { 15 | var elements = elementsNode.baseElements || []; 16 | existingElements = filterNode(elements, elementType, excludedElementId); 17 | } 18 | 19 | return existingElements.sort(function(a,b){ 20 | return a.name.localeCompare(b.name); 21 | }); 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /lib/util/FileUtil.js: -------------------------------------------------------------------------------- 1 | export function fileToDataURL(file) { 2 | return new Promise((resolve, reject) => { 3 | try { 4 | var reader = new FileReader(); 5 | reader.onloadend = function() { 6 | resolve(reader.result); 7 | }; 8 | reader.readAsDataURL(file); 9 | } catch (e) { 10 | reject(e); 11 | } 12 | }); 13 | } 14 | 15 | 16 | export async function imageProcessor(ev, file) { 17 | const base64file = await fileToDataURL(file); 18 | 19 | // createImage(ev, base64file); 20 | return base64file; // passing any errors through 21 | } 22 | 23 | export async function fileReader(ev, files) { 24 | let uploadResult = []; 25 | let errors; 26 | let fileItems = files; 27 | if (ev && (ev.dataTransfer.items || ev.dataTransfer.files)) { 28 | fileItems = ev.dataTransfer.items || ev.dataTransfer.files; 29 | } 30 | try { 31 | if (fileItems) { 32 | for (var i = 0; i < fileItems.length; i++) { 33 | if (ev && ev.dataTransfer.items) { 34 | if (fileItems[i].kind === 'file') { 35 | var file = fileItems[i].getAsFile(); 36 | uploadResult.push(await imageProcessor(ev, file)); 37 | } 38 | } else { 39 | uploadResult.push(await imageProcessor(ev, fileItems[i])); 40 | } 41 | } 42 | } 43 | } catch (e) { 44 | errors = e; 45 | uploadResult = null; 46 | } 47 | return { uploadResult, errors }; 48 | } 49 | 50 | -------------------------------------------------------------------------------- /lib/util/LabelUtil.js: -------------------------------------------------------------------------------- 1 | import { 2 | assign 3 | } from 'min-dash'; 4 | 5 | import { is, getViewElement, getElementRef } from './ModelUtil'; 6 | 7 | 8 | export var DEFAULT_LABEL_SIZE = { 9 | width: 90, 10 | height: 20 11 | }; 12 | 13 | export var FLOW_LABEL_INDENT = 15; 14 | 15 | /** 16 | * Returns true if the given element has an external label 17 | * 18 | * @param {Shape} element 19 | * @return {Boolean} true if has label 20 | */ 21 | export function isLabelExternal(element) { 22 | var elementRef = getElementRef(element); 23 | // return is(semantic, 'archimate:Group'); 24 | return is(elementRef, 'archimate:Group'); 25 | } 26 | 27 | /** 28 | * Returns true if the given element has an external label 29 | * 30 | * @param {djs.model.shape} element 31 | * @return {Boolean} true if has label 32 | */ 33 | export function hasExternalLabel(element) { 34 | return isLabel(element.label); 35 | } 36 | 37 | 38 | /** 39 | * Get the middle of a number of waypoints 40 | * 41 | * @param {Array} waypoints 42 | * @return {Point} the mid point 43 | */ 44 | export function getWaypointsMid(waypoints) { 45 | 46 | var mid = waypoints.length / 2 - 1; 47 | 48 | var first = waypoints[Math.floor(mid)]; 49 | var second = waypoints[Math.ceil(mid + 0.01)]; 50 | 51 | return { 52 | x: first.x + (second.x - first.x) / 2, 53 | y: first.y + (second.y - first.y) / 2 54 | }; 55 | } 56 | 57 | 58 | export function getExternalLabelMid(element) { 59 | 60 | var elementRef = getElementRef(element); 61 | 62 | logger.log('getExternalLabelMid(element)'); 63 | logger.log({element}); 64 | 65 | if (is(elementRef, 'archimate:Group')) { 66 | 67 | return { 68 | x: element.x + element.width / 2, 69 | y: element.y + DEFAULT_LABEL_SIZE.height / 2 70 | }; 71 | } else { 72 | return { 73 | x: element.x + element.width / 2, 74 | y: element.y + element.height + DEFAULT_LABEL_SIZE.height / 2 75 | }; 76 | } 77 | } 78 | 79 | 80 | /** 81 | * Returns the bounds of an elements label, parsed from the elements or 82 | * generated from its bounds. 83 | * 84 | * @param {djs.model.Base} element 85 | */ 86 | export function getExternalLabelBounds(element) { 87 | 88 | var mid, 89 | size, 90 | bounds, 91 | di = getViewElement(element), 92 | label = di.label; 93 | 94 | if (label && label.bounds) { 95 | bounds = label.bounds; 96 | 97 | size = { 98 | width: Math.max(DEFAULT_LABEL_SIZE.width, bounds.width), 99 | height: bounds.height 100 | }; 101 | 102 | mid = { 103 | x: bounds.x + bounds.width / 2, 104 | y: bounds.y + bounds.height / 2 105 | }; 106 | } else { 107 | 108 | mid = getExternalLabelMid(element); 109 | 110 | size = DEFAULT_LABEL_SIZE; 111 | } 112 | 113 | return assign({ 114 | x: mid.x - size.width / 2, 115 | y: mid.y - size.height / 2 116 | }, size); 117 | } 118 | 119 | export function isLabel(element) { 120 | return element && !!element.labelTarget; 121 | } 122 | -------------------------------------------------------------------------------- /lib/util/Logger.js: -------------------------------------------------------------------------------- 1 | const APP_ENV = process.env.NODE_ENV === 'production' ? 'production' : 'development'; 2 | 3 | const LOG_LEVEL = APP_ENV === 'production' ? 'warn' : 'log'; 4 | 5 | const NO_OP = (message, ...optionalParams) => {}; 6 | 7 | export class ConsoleLogger { 8 | 9 | constructor(options) { 10 | const { level } = options || {}; 11 | 12 | this.error = console.error.bind(console); 13 | 14 | if (level === 'error') { 15 | this.warn = NO_OP; 16 | this.log = NO_OP; 17 | 18 | return; 19 | } 20 | 21 | this.warn = console.warn.bind(console); 22 | 23 | if (level === 'warn') { 24 | this.log = NO_OP; 25 | 26 | return; 27 | } 28 | 29 | this.log = console.log.bind(console); 30 | 31 | } 32 | 33 | } 34 | 35 | export const logger = new ConsoleLogger({ level: LOG_LEVEL }); -------------------------------------------------------------------------------- /lib/util/ScreenUtil.js: -------------------------------------------------------------------------------- 1 | export function getMousePosition(event) { 2 | event = event || window.event; 3 | 4 | var pageX = event.pageX; 5 | var pageY = event.pageY; 6 | 7 | // IE 8 8 | if (pageX === undefined) { 9 | pageX = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; 10 | pageY = event.clientY + document.body.scrollTop + document.documentElement.scrollTop; 11 | } 12 | 13 | return { pageX, pageY }; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "archimate-js", 3 | "version": "0.0.4", 4 | "description": "An ArchiMate diagrams modeler builds on diagram-js modeler engine from bpmn.io project", 5 | "author": { 6 | "name": "Vincent Boulet" 7 | }, 8 | "license": "MIT", 9 | "keywords": [ 10 | "archimate", 11 | "architecture", 12 | "modeler", 13 | "modeling" 14 | ], 15 | "scripts": { 16 | "all": "run-s lint test", 17 | "lint": "eslint ." 18 | }, 19 | "repository": { 20 | "type": "git", 21 | "url": "https://github.com/archimodel/archimate-js" 22 | }, 23 | "files": [ 24 | "index.js", 25 | "assets", 26 | "dist", 27 | "lib", 28 | "!.eslintrc" 29 | ], 30 | "sideEffects": [ 31 | "*.css" 32 | ], 33 | "devDependencies": { 34 | "eslint": "^7.32.0", 35 | "eslint-plugin-bpmn-io": "^0.12.0", 36 | "eslint-plugin-import": "^2.25.2", 37 | "file-loader": "^6.2.0", 38 | "npm-run-all": "^4.1.5", 39 | "puppeteer": "^10.4.0", 40 | "raw-loader": "^4.0.2", 41 | "webpack": "^5.61.0" 42 | }, 43 | "dependencies": { 44 | "archimate-font": "file:./archimate-font", 45 | "bpmn-font": "^0.10.0", 46 | "css.escape": "^1.5.1", 47 | "diagram-js": "^12.1.0", 48 | "diagram-js-direct-editing": "^2.0.0", 49 | "hex-and-rgba": "^2.0.0", 50 | "ids": "^1.0.0", 51 | "inherits": "^2.0.4", 52 | "inherits-browser": "^0.1.0", 53 | "mathjs": "^13.2.0", 54 | "min-dash": "^3.8.0", 55 | "min-dom": "^3.1.3", 56 | "moddle": "^5.0.2", 57 | "moddle-xml": "^9.0.5", 58 | "object-refs": "^0.3.0", 59 | "tiny-svg": "^2.2.2" 60 | } 61 | } 62 | --------------------------------------------------------------------------------