@umbraci/jsmind 0.10.12 → 0.10.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/LICENSE +24 -24
  2. package/README.md +116 -116
  3. package/dist/jsmind.draggable-node.js +1 -1
  4. package/dist/jsmind.draggable-node.js.map +1 -1
  5. package/dist/jsmind.history.js +1 -1
  6. package/dist/jsmind.history.js.map +1 -1
  7. package/dist/jsmind.js +1 -1
  8. package/dist/jsmind.js.map +1 -1
  9. package/dist/jsmind.multi-select.js +9 -0
  10. package/dist/jsmind.multi-select.js.map +1 -0
  11. package/dist/jsmind.multiline-text.js +1 -1
  12. package/dist/jsmind.multiline-text.js.map +1 -1
  13. package/dist/jsmind.screenshot.js +1 -1
  14. package/dist/jsmind.screenshot.js.map +1 -1
  15. package/es/jsmind.draggable-node.js +1 -1
  16. package/es/jsmind.draggable-node.js.map +1 -1
  17. package/es/jsmind.history.js +1 -1
  18. package/es/jsmind.history.js.map +1 -1
  19. package/es/jsmind.js +1 -1
  20. package/es/jsmind.js.map +1 -1
  21. package/es/jsmind.multi-select.js +9 -0
  22. package/es/jsmind.multi-select.js.map +1 -0
  23. package/es/jsmind.multiline-text.js +1 -1
  24. package/es/jsmind.multiline-text.js.map +1 -1
  25. package/es/jsmind.screenshot.js +1 -1
  26. package/es/jsmind.screenshot.js.map +1 -1
  27. package/lib/jsmind.draggable-node.js +1 -1
  28. package/lib/jsmind.draggable-node.js.map +1 -1
  29. package/lib/jsmind.history.js +1 -1
  30. package/lib/jsmind.history.js.map +1 -1
  31. package/lib/jsmind.js +1 -1
  32. package/lib/jsmind.js.map +1 -1
  33. package/lib/jsmind.multi-select.js +9 -0
  34. package/lib/jsmind.multi-select.js.map +1 -0
  35. package/lib/jsmind.multiline-text.js +1 -1
  36. package/lib/jsmind.multiline-text.js.map +1 -1
  37. package/lib/jsmind.screenshot.js +1 -1
  38. package/lib/jsmind.screenshot.js.map +1 -1
  39. package/package.json +115 -111
  40. package/style/jsmind.css +408 -408
  41. package/types/tsconfig.declaration.json +19 -19
  42. package/dist/jsmind.copy-paste.js +0 -9
  43. package/dist/jsmind.copy-paste.js.map +0 -1
  44. package/es/jsmind.copy-paste.js +0 -9
  45. package/es/jsmind.copy-paste.js.map +0 -1
  46. package/lib/jsmind.copy-paste.js +0 -9
  47. package/lib/jsmind.copy-paste.js.map +0 -1
  48. package/types/generated/index.d.ts +0 -8
  49. package/types/generated/jsmind.common.d.ts +0 -68
  50. package/types/generated/jsmind.d.ts +0 -632
  51. package/types/generated/jsmind.data_provider.d.ts +0 -56
  52. package/types/generated/jsmind.dom.d.ts +0 -59
  53. package/types/generated/jsmind.enhanced-plugin.d.ts +0 -103
  54. package/types/generated/jsmind.format.d.ts +0 -113
  55. package/types/generated/jsmind.graph.d.ts +0 -180
  56. package/types/generated/jsmind.layout_provider.d.ts +0 -182
  57. package/types/generated/jsmind.mind.d.ts +0 -129
  58. package/types/generated/jsmind.node.d.ts +0 -69
  59. package/types/generated/jsmind.option.d.ts +0 -78
  60. package/types/generated/jsmind.plugin.d.ts +0 -21
  61. package/types/generated/jsmind.shortcut_provider.d.ts +0 -52
  62. package/types/generated/jsmind.util.d.ts +0 -26
  63. package/types/generated/jsmind.view_provider.d.ts +0 -374
  64. package/types/generated/plugins/history/history-diff.d.ts +0 -310
  65. package/types/generated/plugins/history/jsmind.history.d.ts +0 -87
  66. package/types/generated/plugins/jsmind.draggable-node.d.ts +0 -262
  67. package/types/generated/plugins/jsmind.multiline-text-v2.d.ts +0 -58
  68. package/types/generated/plugins/jsmind.multiline-text.d.ts +0 -43
  69. package/types/generated/plugins/jsmind.screenshot.d.ts +0 -83
package/LICENSE CHANGED
@@ -1,24 +1,24 @@
1
- Copyright (c) 2014-2025, ZHANG ZHIGANG <hizzgdev@163.com>
2
- All rights reserved.
3
-
4
- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5
-
6
- * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7
- * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8
- * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9
-
10
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11
-
12
-
13
-
14
- 版权所有 (c) 2014-2025, 张志刚 <hizzgdev@163.com>
15
- 保留一切权利。
16
-
17
- 在满足下列条件的前提下,授予使用者使用及再发布本软件的源代码或二进制形式的权利,无论是否修改皆然:
18
-
19
- * 对于本软件源代码的再发布,必须保留上述的版权声明、此三条许可条件,以及下述的免责声明。
20
- * 对于本软件二进制形式的再发布,必须在随同提供的文档和/或其它媒介中,包含上述的版权声明、此三条许可条件,以及下述的免责声明。
21
- * 未获得事前书面许可,不得使用版权所有人的名称和贡献者的名字,来为本软件的衍生物做任何支持、认可或推广、促销的行为。
22
-
23
- 此软件由版权所有者及贡献者以现状("as is")方式提供,本软件不负任何明示或暗示的担保责任,包括但不限于就适销性以及特定目的的适用性的暗示性担保。任何因使用本软件造成的,直接、间接、连带、特别、惩戒或任何结果的损害(包括但不限于替代商品及服务的采购,无法使用,数据丢失,盈利损失或业务中断等),无论任何条件、无论任何原因或任何责任推断、无论是否属于合同范畴、无论是否为严格赔偿责任或民事侵权行为(包括过失或其他原因)而起,即使在使用前已获告知可能会造成此类损害的情形下,版权所有者及贡献者均不负任何责任。
24
-
1
+ Copyright (c) 2014-2025, ZHANG ZHIGANG <hizzgdev@163.com>
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5
+
6
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8
+ * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9
+
10
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11
+
12
+
13
+
14
+ 版权所有 (c) 2014-2025, 张志刚 <hizzgdev@163.com>
15
+ 保留一切权利。
16
+
17
+ 在满足下列条件的前提下,授予使用者使用及再发布本软件的源代码或二进制形式的权利,无论是否修改皆然:
18
+
19
+ * 对于本软件源代码的再发布,必须保留上述的版权声明、此三条许可条件,以及下述的免责声明。
20
+ * 对于本软件二进制形式的再发布,必须在随同提供的文档和/或其它媒介中,包含上述的版权声明、此三条许可条件,以及下述的免责声明。
21
+ * 未获得事前书面许可,不得使用版权所有人的名称和贡献者的名字,来为本软件的衍生物做任何支持、认可或推广、促销的行为。
22
+
23
+ 此软件由版权所有者及贡献者以现状("as is")方式提供,本软件不负任何明示或暗示的担保责任,包括但不限于就适销性以及特定目的的适用性的暗示性担保。任何因使用本软件造成的,直接、间接、连带、特别、惩戒或任何结果的损害(包括但不限于替代商品及服务的采购,无法使用,数据丢失,盈利损失或业务中断等),无论任何条件、无论任何原因或任何责任推断、无论是否属于合同范畴、无论是否为严格赔偿责任或民事侵权行为(包括过失或其他原因)而起,即使在使用前已获告知可能会造成此类损害的情形下,版权所有者及贡献者均不负任何责任。
24
+
package/README.md CHANGED
@@ -1,116 +1,116 @@
1
- # jsMind
2
-
3
- [![npm version](https://badge.fury.io/js/jsmind.svg)](https://www.npmjs.com/package/jsmind)
4
- ![build-test](https://github.com/hizzgdev/jsmind/actions/workflows/node.js.yml/badge.svg)
5
-
6
- jsMind 是一个显示/编辑思维导图的纯 javascript 类库,其基于 html5 canvas 和 svg 进行设计。jsMind 以 [BSD 协议开源](LICENSE),在此基础上你可以在你的项目上任意使用。
7
-
8
- jsMind is mind map library built by javascript, it base on html5 canvas and svg. jsMind is released under [the BSD license](LICENSE), you can embed it in any project as long as you abide by the license.
9
-
10
- ## ✨ New Feature: Enhanced Plugin System
11
-
12
- jsMind now supports a new enhanced plugin system with:
13
-
14
- - **Synchronous Initialization**: Plugins initialize before rendering, allowing them to affect the initial render
15
- - **Preload Support**: Control plugin initialization order (before or after core modules)
16
- - **Lifecycle Management**: Proper cleanup with `beforePluginRemove()` and `beforePluginDestroy()` hooks
17
- - **Dynamic Plugin Management**: Add or remove plugins at runtime
18
- - **Backward Compatibility**: Works alongside the existing plugin system
19
-
20
- See [Enhanced Plugin System Documentation](docs/enhanced-plugin-system.md) for more information.
21
-
22
- ### Quick Example
23
-
24
- ```javascript
25
- import jsMind from './jsmind.js';
26
- import MultilineTextV2 from './plugins/jsmind.multiline-text-v2.js';
27
-
28
- // Register plugin (before creating instance)
29
- jsMind.usePlugin(MultilineTextV2, {
30
- text_width: 250,
31
- min_height: 40,
32
- });
33
-
34
- // Create jsMind instance
35
- const jm = new jsMind({
36
- container: 'jsmind_container',
37
- editable: true,
38
- });
39
-
40
- // Show mind map with multiline text
41
- jm.show({
42
- meta: { name: 'demo' },
43
- format: 'node_tree',
44
- data: {
45
- id: 'root',
46
- topic: 'Root Node',
47
- children: [{ id: 'node1', topic: 'Line 1\nLine 2\nLine 3' }],
48
- },
49
- });
50
- ```
51
-
52
- ## Project Home
53
-
54
- - [jsMind on Github](https://github.com/hizzgdev/jsmind)
55
- - [国内镜像 - Gitee](https://gitee.com/hizzgdev/jsmind)
56
-
57
- ## Get Started
58
-
59
- ```html
60
- <html>
61
- <head>
62
- <link
63
- type="text/css"
64
- rel="stylesheet"
65
- href="//cdn.jsdelivr.net/npm/jsmind@0.9.0/style/jsmind.css"
66
- />
67
- <script
68
- type="text/javascript"
69
- src="//cdn.jsdelivr.net/npm/jsmind@0.9.0/es6/jsmind.js"
70
- ></script>
71
- </head>
72
- <body>
73
- <div id="jsmind_container"></div>
74
-
75
- <script type="text/javascript">
76
- var mind = {
77
- // 3 data formats were supported ...
78
- // see documents for more information
79
- };
80
- var options = {
81
- container: 'jsmind_container',
82
- theme: 'orange',
83
- editable: true,
84
- };
85
- var jm = new jsMind(options);
86
- jm.show(mind);
87
- </script>
88
- </body>
89
- </html>
90
- ```
91
-
92
- ## Links
93
-
94
- - Resources:
95
- - [文档 - Documents](https://hizzgdev.github.io/jsmind/docs)
96
- - [NPM - jsmind](https://www.npmjs.com/package/jsmind)
97
- - CDN - [用法](docs/zh/1.usage.md) [Usage](docs/en/1.usage.md)
98
- - [UNPKG](https://unpkg.com/browse/jsmind/)
99
- - [jsDelivr](https://www.jsdelivr.com/package/npm/jsmind/)
100
- - [jsDelivr 国内镜像](https://jsd.onmicrosoft.cn/npm/jsmind/)
101
- - Apps :
102
- - <https://jsmind.online>
103
- - Demo :
104
- - [显示一个脑图 Render a mindmap](https://hizzgdev.github.io/jsmind/example/1_basic.html) [[国内版](https://hizzgdev.github.io/jsmind/example/1_basic_cn.html)]
105
- - [试用所有功能 Try all features](https://hizzgdev.github.io/jsmind/example/2_features.html) [[国内版](https://hizzgdev.github.io/jsmind/example/2_features_cn.html)]
106
- - [requirejs + jsMind](https://hizzgdev.github.io/jsmind/example/3_requirejs.html)
107
- - [更多示例 - More samples](https://github.com/hizzgdev/jsmind-samples) [[国内版](https://gitee.com/hizzgdev/jsmind-samples)]
108
-
109
- ## Funding
110
-
111
- - [致谢 - Acknowledgement](https://hizzgdev.github.io/acknowledgement.html)
112
- - [资助 - Sponsor](https://hizzgdev.github.io/sponsor.html)
113
-
114
- ## Maintainer
115
-
116
- - [张志刚 - Zhigang Zhang](https://hizzgdev.github.io)
1
+ # jsMind
2
+
3
+ [![npm version](https://badge.fury.io/js/jsmind.svg)](https://www.npmjs.com/package/jsmind)
4
+ ![build-test](https://github.com/hizzgdev/jsmind/actions/workflows/node.js.yml/badge.svg)
5
+
6
+ jsMind 是一个显示/编辑思维导图的纯 javascript 类库,其基于 html5 canvas 和 svg 进行设计。jsMind 以 [BSD 协议开源](LICENSE),在此基础上你可以在你的项目上任意使用。
7
+
8
+ jsMind is mind map library built by javascript, it base on html5 canvas and svg. jsMind is released under [the BSD license](LICENSE), you can embed it in any project as long as you abide by the license.
9
+
10
+ ## ✨ New Feature: Enhanced Plugin System
11
+
12
+ jsMind now supports a new enhanced plugin system with:
13
+
14
+ - **Synchronous Initialization**: Plugins initialize before rendering, allowing them to affect the initial render
15
+ - **Preload Support**: Control plugin initialization order (before or after core modules)
16
+ - **Lifecycle Management**: Proper cleanup with `beforePluginRemove()` and `beforePluginDestroy()` hooks
17
+ - **Dynamic Plugin Management**: Add or remove plugins at runtime
18
+ - **Backward Compatibility**: Works alongside the existing plugin system
19
+
20
+ See [Enhanced Plugin System Documentation](docs/enhanced-plugin-system.md) for more information.
21
+
22
+ ### Quick Example
23
+
24
+ ```javascript
25
+ import jsMind from './jsmind.js';
26
+ import MultilineTextV2 from './plugins/jsmind.multiline-text-v2.js';
27
+
28
+ // Register plugin (before creating instance)
29
+ jsMind.usePlugin(MultilineTextV2, {
30
+ text_width: 250,
31
+ min_height: 40,
32
+ });
33
+
34
+ // Create jsMind instance
35
+ const jm = new jsMind({
36
+ container: 'jsmind_container',
37
+ editable: true,
38
+ });
39
+
40
+ // Show mind map with multiline text
41
+ jm.show({
42
+ meta: { name: 'demo' },
43
+ format: 'node_tree',
44
+ data: {
45
+ id: 'root',
46
+ topic: 'Root Node',
47
+ children: [{ id: 'node1', topic: 'Line 1\nLine 2\nLine 3' }],
48
+ },
49
+ });
50
+ ```
51
+
52
+ ## Project Home
53
+
54
+ - [jsMind on Github](https://github.com/hizzgdev/jsmind)
55
+ - [国内镜像 - Gitee](https://gitee.com/hizzgdev/jsmind)
56
+
57
+ ## Get Started
58
+
59
+ ```html
60
+ <html>
61
+ <head>
62
+ <link
63
+ type="text/css"
64
+ rel="stylesheet"
65
+ href="//cdn.jsdelivr.net/npm/jsmind@0.9.0/style/jsmind.css"
66
+ />
67
+ <script
68
+ type="text/javascript"
69
+ src="//cdn.jsdelivr.net/npm/jsmind@0.9.0/es6/jsmind.js"
70
+ ></script>
71
+ </head>
72
+ <body>
73
+ <div id="jsmind_container"></div>
74
+
75
+ <script type="text/javascript">
76
+ var mind = {
77
+ // 3 data formats were supported ...
78
+ // see documents for more information
79
+ };
80
+ var options = {
81
+ container: 'jsmind_container',
82
+ theme: 'orange',
83
+ editable: true,
84
+ };
85
+ var jm = new jsMind(options);
86
+ jm.show(mind);
87
+ </script>
88
+ </body>
89
+ </html>
90
+ ```
91
+
92
+ ## Links
93
+
94
+ - Resources:
95
+ - [文档 - Documents](https://hizzgdev.github.io/jsmind/docs)
96
+ - [NPM - jsmind](https://www.npmjs.com/package/jsmind)
97
+ - CDN - [用法](docs/zh/1.usage.md) [Usage](docs/en/1.usage.md)
98
+ - [UNPKG](https://unpkg.com/browse/jsmind/)
99
+ - [jsDelivr](https://www.jsdelivr.com/package/npm/jsmind/)
100
+ - [jsDelivr 国内镜像](https://jsd.onmicrosoft.cn/npm/jsmind/)
101
+ - Apps :
102
+ - <https://jsmind.online>
103
+ - Demo :
104
+ - [显示一个脑图 Render a mindmap](https://hizzgdev.github.io/jsmind/example/1_basic.html) [[国内版](https://hizzgdev.github.io/jsmind/example/1_basic_cn.html)]
105
+ - [试用所有功能 Try all features](https://hizzgdev.github.io/jsmind/example/2_features.html) [[国内版](https://hizzgdev.github.io/jsmind/example/2_features_cn.html)]
106
+ - [requirejs + jsMind](https://hizzgdev.github.io/jsmind/example/3_requirejs.html)
107
+ - [更多示例 - More samples](https://github.com/hizzgdev/jsmind-samples) [[国内版](https://gitee.com/hizzgdev/jsmind-samples)]
108
+
109
+ ## Funding
110
+
111
+ - [致谢 - Acknowledgement](https://hizzgdev.github.io/acknowledgement.html)
112
+ - [资助 - Sponsor](https://hizzgdev.github.io/sponsor.html)
113
+
114
+ ## Maintainer
115
+
116
+ - [张志刚 - Zhigang Zhang](https://hizzgdev.github.io)
@@ -5,5 +5,5 @@
5
5
  * Project Home:
6
6
  * https://github.com/hizzgdev/jsmind/
7
7
  */
8
- !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@umbraci/jsmind")):"function"==typeof define&&define.amd?define(["exports","@umbraci/jsmind"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).jsMindDraggableNode={},t.jsMind)}(this,function(t,e){"use strict";function i(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var s=i(e);if(!s.default)throw new Error("jsMind is not defined");const o=s.default.$,n="getSelection"in o.w?function(){o.w.getSelection().removeAllRanges()}:function(){o.d.selection.empty()},h={line_width:5,line_color:"rgba(0,0,0,0.3)",line_color_invalid:"rgba(255,51,51,0.6)",lookup_delay:200,lookup_interval:100,scrolling_trigger_width:20,scrolling_step_length:10,shadow_node_class_name:"jsmind-draggable-shadow-node"};class l{constructor(t,e){var i={};s.default.util.json.merge(i,h),s.default.util.json.merge(i,e),this.version="0.4.0",this.jm=t,this.options=i,this.is_svg_engine="svg"===t.view.opts.engine,this.e_canvas=null,this.canvas_ctx=null,this.helper_line=null,this.shadow=null,this.shadow_p_x=0,this.shadow_p_y=0,this.shadow_w=0,this.shadow_h=0,this.active_node=null,this.target_node=null,this.target_direct=null,this.client_w=0,this.client_h=0,this.offset_x=0,this.offset_y=0,this.hlookup_delay=0,this.hlookup_timer=0,this.capture=!1,this.moved=!1,this.canvas_draggable=t.get_view_draggable(),this.view_panel=t.view.e_panel,this.view_panel_rect=null}init(){this.create_canvas(),this.create_shadow(),this.event_bind()}resize(){this.jm.view.e_nodes.appendChild(this.shadow),this.is_svg_engine?(this.e_canvas.setAttribute("width",this.jm.view.size.w),this.e_canvas.setAttribute("height",this.jm.view.size.h)):(this.e_canvas.width=this.jm.view.size.w,this.e_canvas.height=this.jm.view.size.h)}create_canvas(){if(this.is_svg_engine){var t=this._create_svg_element("svg");t.setAttribute("class","jsmind-draggable-helper"),t.setAttribute("style","position: absolute; top: 0; left: 0; pointer-events: none;"),this.jm.view.e_panel.appendChild(t),this.e_canvas=t}else{var e=o.c("canvas");this.jm.view.e_panel.appendChild(e);var i=e.getContext("2d");this.e_canvas=e,this.canvas_ctx=i}}_create_svg_element(t){return o.d.createElementNS("http://www.w3.org/2000/svg",t)}create_shadow(){var t=o.c("jmnode");t.style.visibility="hidden",t.style.zIndex="3",t.style.cursor="move",t.style.opacity="0.7",t.className=this.options.shadow_node_class_name,this.shadow=t}reset_shadow(t){var e=this.shadow.style;this.shadow.innerHTML=t.innerHTML,e.left=t.style.left,e.top=t.style.top,e.width=t.style.width,e.height=t.style.height,e.backgroundImage=t.style.backgroundImage,e.backgroundSize=t.style.backgroundSize,e.transform=t.style.transform,this.shadow_w=this.shadow.clientWidth,this.shadow_h=this.shadow.clientHeight}show_shadow(){this.moved||(this.shadow.style.visibility="visible")}hide_shadow(){this.shadow.style.visibility="hidden"}magnet_shadow(t,e,i){this.clear_lines();var s=i?this.options.line_color_invalid:this.options.line_color;this.is_svg_engine?this.svg_draw_line(t.x,t.y,e.x,e.y,s):(this.canvas_ctx.lineWidth=this.options.line_width,this.canvas_ctx.strokeStyle=s,this.canvas_ctx.lineCap="round",this.canvas_lineto(t.x,t.y,e.x,e.y))}clear_lines(){this.is_svg_engine?this.helper_line&&this.helper_line.parentNode&&(this.e_canvas.removeChild(this.helper_line),this.helper_line=null):this.canvas_ctx.clearRect(0,0,this.jm.view.size.w,this.jm.view.size.h)}canvas_lineto(t,e,i,s){this.canvas_ctx.beginPath(),this.canvas_ctx.moveTo(t,e),this.canvas_ctx.lineTo(i,s),this.canvas_ctx.stroke()}svg_draw_line(t,e,i,s,o){this.helper_line=this._create_svg_element("path"),this.helper_line.setAttribute("stroke",o),this.helper_line.setAttribute("stroke-width",this.options.line_width),this.helper_line.setAttribute("fill","transparent"),this.helper_line.setAttribute("stroke-linecap","round"),this._svg_bezier_to(this.helper_line,t,e,i,s),this.e_canvas.appendChild(this.helper_line)}_svg_bezier_to(t,e,i,s,o){t.setAttribute("d","M "+e+" "+i+" C "+(e+2*(s-e)/3)+" "+i+", "+e+" "+o+", "+s+" "+o)}event_bind(){var t=this,e=this.jm.view.container;o.on(e,"mousedown",function(e){0===e.button&&t.dragstart.call(t,e)}),o.on(e,"mousemove",function(e){0===e.movementX&&0===e.movementY||t.drag.call(t,e)}),o.on(e,"mouseup",function(e){t.dragend.call(t,e)}),o.on(e,"touchstart",function(e){t.dragstart.call(t,e)}),o.on(e,"touchmove",function(e){t.drag.call(t,e)}),o.on(e,"touchend",function(e){t.dragend.call(t,e)})}dragstart(t){if(this.jm.get_editable()&&!this.capture){var e=this.jm.view;if(!e.is_editing()){this.active_node=null,this.view_draggable=this.jm.get_view_draggable();var i=this.find_node_element(t.target);if(i){this.view_draggable&&this.jm.disable_view_draggable();var s=e.get_binded_nodeid(i);if(s){var n=this.jm.get_node(s);if(!n.isroot){if(n.data&&!1===n.data.draggable)return;this.reset_shadow(i),this.view_panel_rect=this.view_panel.getBoundingClientRect(),this.active_node=n,this.offset_x=(t.clientX||t.touches[0].clientX)/e.zoom_current-i.offsetLeft,this.offset_y=(t.clientY||t.touches[0].clientY)/e.zoom_current-i.offsetTop,this.client_hw=Math.floor(i.clientWidth/2),this.client_hh=Math.floor(i.clientHeight/2),0!=this.hlookup_delay&&o.w.clearTimeout(this.hlookup_delay),0!=this.hlookup_timer&&o.w.clearInterval(this.hlookup_timer);var h=this;this.hlookup_delay=o.w.setTimeout(function(){h.hlookup_delay=0,h.hlookup_timer=o.w.setInterval(function(){h.lookup_target_node.call(h)},h.options.lookup_interval)},this.options.lookup_delay),h.capture=!0}}}}}}drag(t){if(this.jm.get_editable()&&this.capture){t.preventDefault(),this.show_shadow(),this.moved=!0,n();var e=this.jm.view,i=(t.clientX||t.touches[0].clientX)/e.zoom_current-this.offset_x,s=(t.clientY||t.touches[0].clientY)/e.zoom_current-this.offset_y;t.clientY-this.view_panel_rect.top<this.options.scrolling_trigger_width&&this.view_panel.scrollTop>this.options.scrolling_step_length?(this.view_panel.scrollBy(0,-this.options.scrolling_step_length),this.offset_y+=this.options.scrolling_step_length/e.zoom_current):this.view_panel_rect.bottom-t.clientY<this.options.scrolling_trigger_width&&this.view_panel.scrollTop<this.view_panel.scrollHeight-this.view_panel_rect.height-this.options.scrolling_step_length&&(this.view_panel.scrollBy(0,this.options.scrolling_step_length),this.offset_y-=this.options.scrolling_step_length/e.zoom_current),t.clientX-this.view_panel_rect.left<this.options.scrolling_trigger_width&&this.view_panel.scrollLeft>this.options.scrolling_step_length?(this.view_panel.scrollBy(-this.options.scrolling_step_length,0),this.offset_x+=this.options.scrolling_step_length/e.zoom_current):this.view_panel_rect.right-t.clientX<this.options.scrolling_trigger_width&&this.view_panel.scrollLeft<this.view_panel.scrollWidth-this.view_panel_rect.width-this.options.scrolling_step_length&&(this.view_panel.scrollBy(this.options.scrolling_step_length,0),this.offset_x-=this.options.scrolling_step_length/e.zoom_current),this.shadow.style.left=i+"px",this.shadow.style.top=s+"px",n()}}dragend(t){if(this.jm.get_editable()){if(this.view_draggable&&this.jm.enable_view_draggable(),this.capture){if(0!=this.hlookup_delay&&(o.w.clearTimeout(this.hlookup_delay),this.hlookup_delay=0,this.clear_lines()),0!=this.hlookup_timer&&(o.w.clearInterval(this.hlookup_timer),this.hlookup_timer=0,this.clear_lines()),this.moved){var e=this.active_node,i=this.target_node,s=this.target_direct;this.move_node(e,i,s)}this.hide_shadow()}this.view_panel_rect=null,this.moved=!1,this.capture=!1}}find_node_element(t){return t===this.jm.view.e_nodes||t===this.jm.view.e_panel||t===this.jm.view.container?null:"jmnode"===t.tagName.toLowerCase()?t:this.find_node_element(t.parentNode)}lookup_target_node(){let t=this.shadow.offsetLeft,e=this.shadow.offsetTop;if(t===this.shadow_p_x&&e===this.shadow_p_y)return;this.shadow_p_x=t,this.shadow_p_y=e;let i=this.shadow_p_x+this.shadow_w/2>=this.get_root_x()?s.default.direction.right:s.default.direction.left,o=this.lookup_overlapping_node_parent(i)||this.lookup_close_node(i);if(o){let t=this.calc_point_of_node(o,i),e=s.default.node.inherited(this.active_node,o);this.magnet_shadow(t.sp,t.np,e),this.target_node=o,this.target_direct=i}}get_root_x(){let t=this.jm.get_root(),e=t.get_location(),i=t.get_size();return e.x+i.w/2}lookup_overlapping_node_parent(t){let e=this.shadow.getBoundingClientRect(),i=e.x+e.width*(1-t)/2,s=(this.jm.options.layout.hspace+this.jm.options.layout.pspace)*t,o=e.height,n=[[i,e.y],[i,e.y+o/2],[i,e.y+o],[i+s/2,e.y],[i+s/2,e.y+o/2],[i+s/2,e.y+o],[i+s,e.y],[i+s,e.y+o/2],[i+s,e.y+o]];for(const t of n){let e=this.lookup_node_parent_by_location(t[0],t[1]);if(e)return e}}lookup_node_parent_by_location(t,e){return o.d.elementsFromPoint(t,e).filter(t=>"JMNODE"===t.tagName&&t.className!==this.options.shadow_node_class_name).map(t=>this.jm.view.get_binded_nodeid(t)).map(t=>t&&this.jm.mind.nodes[t]).map(t=>t&&t.parent).find(t=>t)}lookup_close_node(t){return Object.values(this.jm.mind.nodes).filter(e=>e.direction==t||e.isroot).filter(t=>this.jm.layout.is_visible(t)).filter(e=>this.shadow_on_target_side(e,t)).map(e=>({node:e,distance:this.shadow_to_node(e,t)})).reduce((t,e)=>t.distance<e.distance?t:e,{node:this.jm.get_root(),distance:Number.MAX_VALUE}).node}shadow_on_target_side(t,e){return e==s.default.direction.right&&this.shadow_to_right_of_node(t)>0||e==s.default.direction.left&&this.shadow_to_left_of_node(t)>0}shadow_to_right_of_node(t){return this.shadow_p_x-t.get_location().x-t.get_size().w}shadow_to_left_of_node(t){return t.get_location().x-this.shadow_p_x-this.shadow_w}shadow_to_base_line_of_node(t){return this.shadow_p_y+this.shadow_h/2-t.get_location().y-t.get_size().h/2}shadow_to_node(t,e){return(e===s.default.direction.right?Math.abs(this.shadow_to_right_of_node(t)):Math.abs(this.shadow_to_left_of_node(t)))+Math.abs(this.shadow_to_base_line_of_node(t))}calc_point_of_node(t,e){let i=t.get_size(),s=t.get_location(),o=t.isroot?s.x+i.w/2:s.x+i.w*(1+e)/2+this.options.line_width*e,n=s.y+i.h/2;return{sp:{x:this.shadow_p_x+this.shadow_w*(1-e)/2-this.options.line_width*e,y:this.shadow_p_y+this.shadow_h/2},np:{x:o,y:n}}}move_node(t,e,i){var o=this.shadow.offsetTop;if(e&&t&&!s.default.node.inherited(t,e)){if(this.options.validate_drag&&"function"==typeof this.options.validate_drag){if(!this.options.validate_drag(t,e))return this.active_node=null,this.target_node=null,void(this.target_direct=null)}for(var n=e.children,h=n.length,l=null,a=Number.MAX_VALUE,_=null,r="_last_";h--;)if((l=n[h]).direction==i&&l.id!=t.id){var d=l.get_location().y-o;d>0&&d<a&&(a=d,_=l,r="_first_")}_&&(r=_.id),this.jm.move_node(t.id,r,e.id,i)}this.active_node=null,this.target_node=null,this.target_direct=null}jm_event_handle(t,e){t===s.default.event_type.resize&&this.resize()}}const a=new s.default.plugin("draggable_node",function(t,e){var i=new l(t,e);i.init(),t.add_event_listener(function(t,e){i.jm_event_handle.call(i,t,e)})});s.default.register_plugin(a),t.DraggableNode=l,t.default=l,t.draggable_plugin=a,Object.defineProperty(t,"__esModule",{value:!0})});
8
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@umbraci/jsmind")):"function"==typeof define&&define.amd?define(["exports","@umbraci/jsmind"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).jsMindDraggableNode={},t.jsMind)}(this,(function(t,e){"use strict";function i(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var s=i(e);if(!s.default)throw new Error("jsMind is not defined");const o=s.default.$,n="getSelection"in o.w?function(){o.w.getSelection().removeAllRanges()}:function(){o.d.selection.empty()},h={line_width:5,line_color:"rgba(0,0,0,0.3)",line_color_invalid:"rgba(255,51,51,0.6)",lookup_delay:200,lookup_interval:100,scrolling_trigger_width:20,scrolling_step_length:10,shadow_node_class_name:"jsmind-draggable-shadow-node"};class l{constructor(t,e){var i={};s.default.util.json.merge(i,h),s.default.util.json.merge(i,e),this.version="0.4.0",this.jm=t,this.options=i,this.is_svg_engine="svg"===t.view.opts.engine,this.e_canvas=null,this.canvas_ctx=null,this.helper_line=null,this.shadow=null,this.shadow_p_x=0,this.shadow_p_y=0,this.shadow_w=0,this.shadow_h=0,this.active_node=null,this.target_node=null,this.target_direct=null,this.client_w=0,this.client_h=0,this.offset_x=0,this.offset_y=0,this.hlookup_delay=0,this.hlookup_timer=0,this.capture=!1,this.moved=!1,this.canvas_draggable=t.get_view_draggable(),this.view_panel=t.view.e_panel,this.view_panel_rect=null}init(){this.create_canvas(),this.create_shadow(),this.event_bind()}resize(){this.jm.view.e_nodes.appendChild(this.shadow),this.is_svg_engine?(this.e_canvas.setAttribute("width",this.jm.view.size.w),this.e_canvas.setAttribute("height",this.jm.view.size.h)):(this.e_canvas.width=this.jm.view.size.w,this.e_canvas.height=this.jm.view.size.h)}create_canvas(){if(this.is_svg_engine){var t=this._create_svg_element("svg");t.setAttribute("class","jsmind-draggable-helper"),t.setAttribute("style","position: absolute; top: 0; left: 0; pointer-events: none;"),this.jm.view.e_panel.appendChild(t),this.e_canvas=t}else{var e=o.c("canvas");this.jm.view.e_panel.appendChild(e);var i=e.getContext("2d");this.e_canvas=e,this.canvas_ctx=i}}_create_svg_element(t){return o.d.createElementNS("http://www.w3.org/2000/svg",t)}create_shadow(){var t=o.c("jmnode");t.style.visibility="hidden",t.style.zIndex="3",t.style.cursor="move",t.style.opacity="0.7",t.className=this.options.shadow_node_class_name,this.shadow=t}reset_shadow(t){var e=this.shadow.style;this.shadow.innerHTML=t.innerHTML,e.left=t.style.left,e.top=t.style.top,e.width=t.style.width,e.height=t.style.height,e.backgroundImage=t.style.backgroundImage,e.backgroundSize=t.style.backgroundSize,e.transform=t.style.transform,this.shadow_w=this.shadow.clientWidth,this.shadow_h=this.shadow.clientHeight}show_shadow(){this.moved||(this.shadow.style.visibility="visible")}hide_shadow(){this.shadow.style.visibility="hidden"}magnet_shadow(t,e,i){this.clear_lines();var s=i?this.options.line_color_invalid:this.options.line_color;this.is_svg_engine?this.svg_draw_line(t.x,t.y,e.x,e.y,s):(this.canvas_ctx.lineWidth=this.options.line_width,this.canvas_ctx.strokeStyle=s,this.canvas_ctx.lineCap="round",this.canvas_lineto(t.x,t.y,e.x,e.y))}clear_lines(){this.is_svg_engine?this.helper_line&&this.helper_line.parentNode&&(this.e_canvas.removeChild(this.helper_line),this.helper_line=null):this.canvas_ctx.clearRect(0,0,this.jm.view.size.w,this.jm.view.size.h)}canvas_lineto(t,e,i,s){this.canvas_ctx.beginPath(),this.canvas_ctx.moveTo(t,e),this.canvas_ctx.lineTo(i,s),this.canvas_ctx.stroke()}svg_draw_line(t,e,i,s,o){this.helper_line=this._create_svg_element("path"),this.helper_line.setAttribute("stroke",o),this.helper_line.setAttribute("stroke-width",this.options.line_width),this.helper_line.setAttribute("fill","transparent"),this.helper_line.setAttribute("stroke-linecap","round"),this._svg_bezier_to(this.helper_line,t,e,i,s),this.e_canvas.appendChild(this.helper_line)}_svg_bezier_to(t,e,i,s,o){t.setAttribute("d","M "+e+" "+i+" C "+(e+2*(s-e)/3)+" "+i+", "+e+" "+o+", "+s+" "+o)}event_bind(){var t=this,e=this.jm.view.container;o.on(e,"mousedown",(function(e){0===e.button&&t.dragstart.call(t,e)})),o.on(e,"mousemove",(function(e){0===e.movementX&&0===e.movementY||t.drag.call(t,e)})),o.on(e,"mouseup",(function(e){t.dragend.call(t,e)})),o.on(e,"touchstart",(function(e){t.dragstart.call(t,e)})),o.on(e,"touchmove",(function(e){t.drag.call(t,e)})),o.on(e,"touchend",(function(e){t.dragend.call(t,e)}))}dragstart(t){if(this.jm.get_editable()&&!this.capture){var e=this.jm.view;if(!e.is_editing()){this.active_node=null,this.view_draggable=this.jm.get_view_draggable();var i=this.find_node_element(t.target);if(i){this.view_draggable&&this.jm.disable_view_draggable();var s=e.get_binded_nodeid(i);if(s){var n=this.jm.get_node(s);if(!n.isroot){if(n.data&&!1===n.data.draggable)return;this.reset_shadow(i),this.view_panel_rect=this.view_panel.getBoundingClientRect(),this.active_node=n,this.offset_x=(t.clientX||t.touches[0].clientX)/e.zoom_current-i.offsetLeft,this.offset_y=(t.clientY||t.touches[0].clientY)/e.zoom_current-i.offsetTop,this.client_hw=Math.floor(i.clientWidth/2),this.client_hh=Math.floor(i.clientHeight/2),0!=this.hlookup_delay&&o.w.clearTimeout(this.hlookup_delay),0!=this.hlookup_timer&&o.w.clearInterval(this.hlookup_timer);var h=this;this.hlookup_delay=o.w.setTimeout((function(){h.hlookup_delay=0,h.hlookup_timer=o.w.setInterval((function(){h.lookup_target_node.call(h)}),h.options.lookup_interval)}),this.options.lookup_delay),h.capture=!0}}}}}}drag(t){if(this.jm.get_editable()&&this.capture){t.preventDefault(),this.show_shadow(),this.moved=!0,n();var e=this.jm.view,i=(t.clientX||t.touches[0].clientX)/e.zoom_current-this.offset_x,s=(t.clientY||t.touches[0].clientY)/e.zoom_current-this.offset_y;t.clientY-this.view_panel_rect.top<this.options.scrolling_trigger_width&&this.view_panel.scrollTop>this.options.scrolling_step_length?(this.view_panel.scrollBy(0,-this.options.scrolling_step_length),this.offset_y+=this.options.scrolling_step_length/e.zoom_current):this.view_panel_rect.bottom-t.clientY<this.options.scrolling_trigger_width&&this.view_panel.scrollTop<this.view_panel.scrollHeight-this.view_panel_rect.height-this.options.scrolling_step_length&&(this.view_panel.scrollBy(0,this.options.scrolling_step_length),this.offset_y-=this.options.scrolling_step_length/e.zoom_current),t.clientX-this.view_panel_rect.left<this.options.scrolling_trigger_width&&this.view_panel.scrollLeft>this.options.scrolling_step_length?(this.view_panel.scrollBy(-this.options.scrolling_step_length,0),this.offset_x+=this.options.scrolling_step_length/e.zoom_current):this.view_panel_rect.right-t.clientX<this.options.scrolling_trigger_width&&this.view_panel.scrollLeft<this.view_panel.scrollWidth-this.view_panel_rect.width-this.options.scrolling_step_length&&(this.view_panel.scrollBy(this.options.scrolling_step_length,0),this.offset_x-=this.options.scrolling_step_length/e.zoom_current),this.shadow.style.left=i+"px",this.shadow.style.top=s+"px",n()}}dragend(t){if(this.jm.get_editable()){if(this.view_draggable&&this.jm.enable_view_draggable(),this.capture){if(0!=this.hlookup_delay&&(o.w.clearTimeout(this.hlookup_delay),this.hlookup_delay=0,this.clear_lines()),0!=this.hlookup_timer&&(o.w.clearInterval(this.hlookup_timer),this.hlookup_timer=0,this.clear_lines()),this.moved){var e=this.active_node,i=this.target_node,s=this.target_direct;this.move_node(e,i,s)}this.hide_shadow()}this.view_panel_rect=null,this.moved=!1,this.capture=!1}}find_node_element(t){return t===this.jm.view.e_nodes||t===this.jm.view.e_panel||t===this.jm.view.container?null:"jmnode"===t.tagName.toLowerCase()?t:this.find_node_element(t.parentNode)}lookup_target_node(){let t=this.shadow.offsetLeft,e=this.shadow.offsetTop;if(t===this.shadow_p_x&&e===this.shadow_p_y)return;this.shadow_p_x=t,this.shadow_p_y=e;let i=this.shadow_p_x+this.shadow_w/2>=this.get_root_x()?s.default.direction.right:s.default.direction.left,o=this.lookup_overlapping_node_parent(i)||this.lookup_close_node(i);if(o){let t=this.calc_point_of_node(o,i),e=s.default.node.inherited(this.active_node,o);this.magnet_shadow(t.sp,t.np,e),this.target_node=o,this.target_direct=i}}get_root_x(){let t=this.jm.get_root(),e=t.get_location(),i=t.get_size();return e.x+i.w/2}lookup_overlapping_node_parent(t){let e=this.shadow.getBoundingClientRect(),i=e.x+e.width*(1-t)/2,s=(this.jm.options.layout.hspace+this.jm.options.layout.pspace)*t,o=e.height,n=[[i,e.y],[i,e.y+o/2],[i,e.y+o],[i+s/2,e.y],[i+s/2,e.y+o/2],[i+s/2,e.y+o],[i+s,e.y],[i+s,e.y+o/2],[i+s,e.y+o]];for(const t of n){let e=this.lookup_node_parent_by_location(t[0],t[1]);if(e)return e}}lookup_node_parent_by_location(t,e){return o.d.elementsFromPoint(t,e).filter((t=>"JMNODE"===t.tagName&&t.className!==this.options.shadow_node_class_name)).map((t=>this.jm.view.get_binded_nodeid(t))).map((t=>t&&this.jm.mind.nodes[t])).map((t=>t&&t.parent)).find((t=>t))}lookup_close_node(t){return Object.values(this.jm.mind.nodes).filter((e=>e.direction==t||e.isroot)).filter((t=>this.jm.layout.is_visible(t))).filter((e=>this.shadow_on_target_side(e,t))).map((e=>({node:e,distance:this.shadow_to_node(e,t)}))).reduce(((t,e)=>t.distance<e.distance?t:e),{node:this.jm.get_root(),distance:Number.MAX_VALUE}).node}shadow_on_target_side(t,e){return e==s.default.direction.right&&this.shadow_to_right_of_node(t)>0||e==s.default.direction.left&&this.shadow_to_left_of_node(t)>0}shadow_to_right_of_node(t){return this.shadow_p_x-t.get_location().x-t.get_size().w}shadow_to_left_of_node(t){return t.get_location().x-this.shadow_p_x-this.shadow_w}shadow_to_base_line_of_node(t){return this.shadow_p_y+this.shadow_h/2-t.get_location().y-t.get_size().h/2}shadow_to_node(t,e){return(e===s.default.direction.right?Math.abs(this.shadow_to_right_of_node(t)):Math.abs(this.shadow_to_left_of_node(t)))+Math.abs(this.shadow_to_base_line_of_node(t))}calc_point_of_node(t,e){let i=t.get_size(),s=t.get_location(),o=t.isroot?s.x+i.w/2:s.x+i.w*(1+e)/2+this.options.line_width*e,n=s.y+i.h/2;return{sp:{x:this.shadow_p_x+this.shadow_w*(1-e)/2-this.options.line_width*e,y:this.shadow_p_y+this.shadow_h/2},np:{x:o,y:n}}}move_node(t,e,i){var o=this.shadow.offsetTop;if(e&&t&&!s.default.node.inherited(t,e)){if(this.options.validate_drag&&"function"==typeof this.options.validate_drag){if(!this.options.validate_drag(t,e))return this.active_node=null,this.target_node=null,void(this.target_direct=null)}for(var n=e.children,h=n.length,l=null,a=Number.MAX_VALUE,_=null,r="_last_";h--;)if((l=n[h]).direction==i&&l.id!=t.id){var d=l.get_location().y-o;d>0&&d<a&&(a=d,_=l,r="_first_")}_&&(r=_.id),this.jm.move_node(t.id,r,e.id,i)}this.active_node=null,this.target_node=null,this.target_direct=null}jm_event_handle(t,e){t===s.default.event_type.resize&&this.resize()}}const a=new s.default.plugin("draggable_node",(function(t,e){var i=new l(t,e);i.init(),t.add_event_listener((function(t,e){i.jm_event_handle.call(i,t,e)}))}));s.default.register_plugin(a),t.DraggableNode=l,t.default=l,t.draggable_plugin=a,Object.defineProperty(t,"__esModule",{value:!0})}));
9
9
  //# sourceMappingURL=jsmind.draggable-node.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"jsmind.draggable-node.js","sources":["../src/plugins/jsmind.draggable-node.js"],"sourcesContent":["/**\n * @license BSD\n * @copyright 2014-2025 UmbraCi\n *\n * Project Home:\n * https://github.com/UmbraCi/jsmind/\n */\n\nimport jsMind from '@umbraci/jsmind';\n\nif (!jsMind) {\n throw new Error('jsMind is not defined');\n}\n\nconst $ = jsMind.$;\n\nconst clear_selection =\n 'getSelection' in $.w\n ? function () {\n $.w.getSelection().removeAllRanges();\n }\n : function () {\n $.d.selection.empty();\n };\n\n/**\n * Default options for draggable node plugin.\n * @typedef {Object} DraggableNodeOptions\n * @property {number} [line_width]\n * @property {string} [line_color]\n * @property {string} [line_color_invalid]\n * @property {number} [lookup_delay]\n * @property {number} [lookup_interval]\n * @property {number} [scrolling_trigger_width]\n * @property {number} [scrolling_step_length]\n * @property {string} [shadow_node_class_name]\n * @property {(draggedNode:import('../jsmind.node.js').Node, targetNode:import('../jsmind.node.js').Node|null)=>boolean} [validate_drag]\n */\nconst DEFAULT_OPTIONS = {\n line_width: 5,\n line_color: 'rgba(0,0,0,0.3)',\n line_color_invalid: 'rgba(255,51,51,0.6)',\n lookup_delay: 200,\n lookup_interval: 100,\n scrolling_trigger_width: 20,\n scrolling_step_length: 10,\n shadow_node_class_name: 'jsmind-draggable-shadow-node',\n};\n\n/**\n * Draggable node plugin for jsMind.\n */\nexport class DraggableNode {\n /**\n * Create draggable node plugin instance.\n * @param {import('../jsmind.js').default} jm - jsMind instance\n * @param {Partial<DraggableNodeOptions>} options - Plugin options\n */\n constructor(jm, options) {\n var opts = {};\n jsMind.util.json.merge(opts, DEFAULT_OPTIONS);\n jsMind.util.json.merge(opts, options);\n\n this.version = '0.4.0';\n /** @type {import('../jsmind.js').default} */\n this.jm = jm;\n /** @type {DraggableNodeOptions} */\n this.options = opts;\n /** @type {boolean} */\n this.is_svg_engine = jm.view.opts.engine === 'svg';\n /** @type {HTMLCanvasElement|SVGSVGElement|null} */\n this.e_canvas = null;\n /** @type {CanvasRenderingContext2D|null} */\n this.canvas_ctx = null;\n /** @type {SVGPathElement|null} */\n this.helper_line = null;\n /** @type {HTMLElement|null} */\n this.shadow = null;\n /** @type {number} */\n this.shadow_p_x = 0;\n /** @type {number} */\n this.shadow_p_y = 0;\n /** @type {number} */\n this.shadow_w = 0;\n /** @type {number} */\n this.shadow_h = 0;\n /** @type {import('../jsmind.node.js').Node|null} */\n this.active_node = null;\n /** @type {import('../jsmind.node.js').Node|null} */\n this.target_node = null;\n /** @type {number|null} */\n this.target_direct = null;\n /** @type {number} */\n this.client_w = 0;\n /** @type {number} */\n this.client_h = 0;\n /** @type {number} */\n this.offset_x = 0;\n /** @type {number} */\n this.offset_y = 0;\n /** @type {number} */\n this.hlookup_delay = 0;\n /** @type {number} */\n this.hlookup_timer = 0;\n /** @type {boolean} */\n this.capture = false;\n /** @type {boolean} */\n this.moved = false;\n /** @type {boolean} */\n this.canvas_draggable = jm.get_view_draggable();\n /** @type {HTMLElement} */\n this.view_panel = jm.view.e_panel;\n /** @type {DOMRect|null} */\n this.view_panel_rect = null;\n }\n /** Initialize the draggable node plugin. */\n init() {\n this.create_canvas();\n this.create_shadow();\n this.event_bind();\n }\n /** Resize canvas/SVG and shadow elements. */\n resize() {\n this.jm.view.e_nodes.appendChild(this.shadow);\n if (this.is_svg_engine) {\n this.e_canvas.setAttribute('width', this.jm.view.size.w);\n this.e_canvas.setAttribute('height', this.jm.view.size.h);\n } else {\n this.e_canvas.width = this.jm.view.size.w;\n this.e_canvas.height = this.jm.view.size.h;\n }\n }\n /** Create canvas or SVG for drawing drag lines. */\n create_canvas() {\n if (this.is_svg_engine) {\n // Create SVG element for helper lines\n var svg = this._create_svg_element('svg');\n svg.setAttribute('class', 'jsmind-draggable-helper');\n svg.setAttribute('style', 'position: absolute; top: 0; left: 0; pointer-events: none;');\n this.jm.view.e_panel.appendChild(svg);\n this.e_canvas = svg;\n } else {\n // Create Canvas element for helper lines\n var c = $.c('canvas');\n this.jm.view.e_panel.appendChild(c);\n var ctx = c.getContext('2d');\n this.e_canvas = c;\n this.canvas_ctx = ctx;\n }\n }\n /**\n * Create SVG element with proper namespace.\n * @param {string} tag - SVG tag name\n * @returns {SVGElement}\n * @private\n */\n _create_svg_element(tag) {\n return $.d.createElementNS('http://www.w3.org/2000/svg', tag);\n }\n create_shadow() {\n var s = $.c('jmnode');\n s.style.visibility = 'hidden';\n s.style.zIndex = '3';\n s.style.cursor = 'move';\n s.style.opacity = '0.7';\n s.className = this.options.shadow_node_class_name;\n this.shadow = s;\n }\n /**\n * Reset shadow element style and cache its size.\n * @param {HTMLElement} el - The node element to mirror as shadow\n */\n reset_shadow(el) {\n var s = this.shadow.style;\n this.shadow.innerHTML = el.innerHTML;\n s.left = el.style.left;\n s.top = el.style.top;\n s.width = el.style.width;\n s.height = el.style.height;\n s.backgroundImage = el.style.backgroundImage;\n s.backgroundSize = el.style.backgroundSize;\n s.transform = el.style.transform;\n this.shadow_w = this.shadow.clientWidth;\n this.shadow_h = this.shadow.clientHeight;\n }\n /** Show the shadow element. */\n show_shadow() {\n if (!this.moved) {\n this.shadow.style.visibility = 'visible';\n }\n }\n /** Hide the shadow element. */\n hide_shadow() {\n this.shadow.style.visibility = 'hidden';\n }\n /**\n * Draw a helper line between the shadow and target node.\n * @param {{x:number,y:number}} shadow_p - Shadow anchor point\n * @param {{x:number,y:number}} node_p - Target node anchor point\n * @param {boolean} invalid - Whether current target is invalid\n */\n magnet_shadow(shadow_p, node_p, invalid) {\n this.clear_lines();\n var color = invalid ? this.options.line_color_invalid : this.options.line_color;\n\n if (this.is_svg_engine) {\n this.svg_draw_line(shadow_p.x, shadow_p.y, node_p.x, node_p.y, color);\n } else {\n this.canvas_ctx.lineWidth = this.options.line_width;\n this.canvas_ctx.strokeStyle = color;\n this.canvas_ctx.lineCap = 'round';\n this.canvas_lineto(shadow_p.x, shadow_p.y, node_p.x, node_p.y);\n }\n }\n /** Clear helper lines from canvas or SVG. */\n clear_lines() {\n if (this.is_svg_engine) {\n if (this.helper_line && this.helper_line.parentNode) {\n this.e_canvas.removeChild(this.helper_line);\n this.helper_line = null;\n }\n } else {\n this.canvas_ctx.clearRect(0, 0, this.jm.view.size.w, this.jm.view.size.h);\n }\n }\n /**\n * Draw a straight helper line on canvas.\n * @param {number} x1\n * @param {number} y1\n * @param {number} x2\n * @param {number} y2\n */\n canvas_lineto(x1, y1, x2, y2) {\n this.canvas_ctx.beginPath();\n this.canvas_ctx.moveTo(x1, y1);\n this.canvas_ctx.lineTo(x2, y2);\n this.canvas_ctx.stroke();\n }\n /**\n * Draw a helper line on SVG using bezier curve.\n * Reuses the line drawing logic from SvgGraph.\n * @param {number} x1 - Start x coordinate\n * @param {number} y1 - Start y coordinate\n * @param {number} x2 - End x coordinate\n * @param {number} y2 - End y coordinate\n * @param {string} color - Line color\n */\n svg_draw_line(x1, y1, x2, y2, color) {\n // Create SVG path element for helper line\n this.helper_line = this._create_svg_element('path');\n this.helper_line.setAttribute('stroke', color);\n this.helper_line.setAttribute('stroke-width', this.options.line_width);\n this.helper_line.setAttribute('fill', 'transparent');\n this.helper_line.setAttribute('stroke-linecap', 'round');\n\n // Draw bezier curve (same as SvgGraph._bezier_to)\n this._svg_bezier_to(this.helper_line, x1, y1, x2, y2);\n\n // Add to SVG container\n this.e_canvas.appendChild(this.helper_line);\n }\n /**\n * Draw bezier curve to SVG path element.\n * Reuses logic from SvgGraph._bezier_to.\n * @param {SVGPathElement} path - SVG path element\n * @param {number} x1 - Start x coordinate\n * @param {number} y1 - Start y coordinate\n * @param {number} x2 - End x coordinate\n * @param {number} y2 - End y coordinate\n * @private\n */\n _svg_bezier_to(path, x1, y1, x2, y2) {\n path.setAttribute(\n 'd',\n 'M ' +\n x1 +\n ' ' +\n y1 +\n ' C ' +\n (x1 + ((x2 - x1) * 2) / 3) +\n ' ' +\n y1 +\n ', ' +\n x1 +\n ' ' +\n y2 +\n ', ' +\n x2 +\n ' ' +\n y2\n );\n }\n /** Bind mouse/touch events for dragging. */\n event_bind() {\n var jd = this;\n var container = this.jm.view.container;\n $.on(container, 'mousedown', function (e) {\n if (e.button === 0) {\n jd.dragstart.call(jd, e);\n }\n });\n $.on(container, 'mousemove', function (e) {\n if (e.movementX !== 0 || e.movementY !== 0) {\n jd.drag.call(jd, e);\n }\n });\n $.on(container, 'mouseup', function (e) {\n jd.dragend.call(jd, e);\n });\n $.on(container, 'touchstart', function (e) {\n jd.dragstart.call(jd, e);\n });\n $.on(container, 'touchmove', function (e) {\n jd.drag.call(jd, e);\n });\n $.on(container, 'touchend', function (e) {\n jd.dragend.call(jd, e);\n });\n }\n /**\n * Begin dragging interaction.\n * @param {MouseEvent|TouchEvent} e - Pointer down event\n */\n dragstart(e) {\n if (!this.jm.get_editable()) {\n return;\n }\n if (this.capture) {\n return;\n }\n var jview = this.jm.view;\n if (jview.is_editing()) {\n return;\n }\n this.active_node = null;\n this.view_draggable = this.jm.get_view_draggable();\n\n var el = this.find_node_element(e.target);\n if (!el) {\n return;\n }\n if (this.view_draggable) {\n this.jm.disable_view_draggable();\n }\n var nodeid = jview.get_binded_nodeid(el);\n if (!!nodeid) {\n var node = this.jm.get_node(nodeid);\n if (!node.isroot) {\n // 检查节点是否允许拖拽\n if (node.data && node.data.draggable === false) {\n return;\n }\n this.reset_shadow(el);\n this.view_panel_rect = this.view_panel.getBoundingClientRect();\n this.active_node = node;\n this.offset_x =\n (e.clientX || e.touches[0].clientX) / jview.zoom_current - el.offsetLeft;\n this.offset_y =\n (e.clientY || e.touches[0].clientY) / jview.zoom_current - el.offsetTop;\n this.client_hw = Math.floor(el.clientWidth / 2);\n this.client_hh = Math.floor(el.clientHeight / 2);\n if (this.hlookup_delay != 0) {\n $.w.clearTimeout(this.hlookup_delay);\n }\n if (this.hlookup_timer != 0) {\n $.w.clearInterval(this.hlookup_timer);\n }\n var jd = this;\n this.hlookup_delay = $.w.setTimeout(function () {\n jd.hlookup_delay = 0;\n jd.hlookup_timer = $.w.setInterval(function () {\n jd.lookup_target_node.call(jd);\n }, jd.options.lookup_interval);\n }, this.options.lookup_delay);\n jd.capture = true;\n }\n }\n }\n /**\n * Drag handler to move shadow and auto-scroll container.\n * @param {MouseEvent|TouchEvent} e - Pointer move event\n */\n drag(e) {\n if (!this.jm.get_editable()) {\n return;\n }\n if (this.capture) {\n e.preventDefault();\n this.show_shadow();\n this.moved = true;\n clear_selection();\n var jview = this.jm.view;\n var px = (e.clientX || e.touches[0].clientX) / jview.zoom_current - this.offset_x;\n var py = (e.clientY || e.touches[0].clientY) / jview.zoom_current - this.offset_y;\n // scrolling container axisY if drag nodes exceeding container\n if (\n e.clientY - this.view_panel_rect.top < this.options.scrolling_trigger_width &&\n this.view_panel.scrollTop > this.options.scrolling_step_length\n ) {\n this.view_panel.scrollBy(0, -this.options.scrolling_step_length);\n this.offset_y += this.options.scrolling_step_length / jview.zoom_current;\n } else if (\n this.view_panel_rect.bottom - e.clientY < this.options.scrolling_trigger_width &&\n this.view_panel.scrollTop <\n this.view_panel.scrollHeight -\n this.view_panel_rect.height -\n this.options.scrolling_step_length\n ) {\n this.view_panel.scrollBy(0, this.options.scrolling_step_length);\n this.offset_y -= this.options.scrolling_step_length / jview.zoom_current;\n }\n // scrolling container axisX if drag nodes exceeding container\n if (\n e.clientX - this.view_panel_rect.left < this.options.scrolling_trigger_width &&\n this.view_panel.scrollLeft > this.options.scrolling_step_length\n ) {\n this.view_panel.scrollBy(-this.options.scrolling_step_length, 0);\n this.offset_x += this.options.scrolling_step_length / jview.zoom_current;\n } else if (\n this.view_panel_rect.right - e.clientX < this.options.scrolling_trigger_width &&\n this.view_panel.scrollLeft <\n this.view_panel.scrollWidth -\n this.view_panel_rect.width -\n this.options.scrolling_step_length\n ) {\n this.view_panel.scrollBy(this.options.scrolling_step_length, 0);\n this.offset_x -= this.options.scrolling_step_length / jview.zoom_current;\n }\n this.shadow.style.left = px + 'px';\n this.shadow.style.top = py + 'px';\n clear_selection();\n }\n }\n /**\n * Finish dragging, move the node if applicable.\n * @param {MouseEvent|TouchEvent} e - Pointer up event\n */\n dragend(e) {\n if (!this.jm.get_editable()) {\n return;\n }\n if (this.view_draggable) {\n this.jm.enable_view_draggable();\n }\n if (this.capture) {\n if (this.hlookup_delay != 0) {\n $.w.clearTimeout(this.hlookup_delay);\n this.hlookup_delay = 0;\n this.clear_lines();\n }\n if (this.hlookup_timer != 0) {\n $.w.clearInterval(this.hlookup_timer);\n this.hlookup_timer = 0;\n this.clear_lines();\n }\n if (this.moved) {\n var src_node = this.active_node;\n var target_node = this.target_node;\n var target_direct = this.target_direct;\n this.move_node(src_node, target_node, target_direct);\n }\n this.hide_shadow();\n }\n this.view_panel_rect = null;\n this.moved = false;\n this.capture = false;\n }\n /**\n * Find the closest node element from an event target.\n * @param {HTMLElement} el - Current DOM element\n * @returns {HTMLElement|null} Matched node element or null\n */\n find_node_element(el) {\n if (\n el === this.jm.view.e_nodes ||\n el === this.jm.view.e_panel ||\n el === this.jm.view.container\n ) {\n return null;\n }\n if (el.tagName.toLowerCase() === 'jmnode') {\n return el;\n }\n return this.find_node_element(el.parentNode);\n }\n /** Recompute target node under the shadow and draw helper. */\n lookup_target_node() {\n let sx = this.shadow.offsetLeft;\n let sy = this.shadow.offsetTop;\n if (sx === this.shadow_p_x && sy === this.shadow_p_y) {\n return;\n }\n this.shadow_p_x = sx;\n this.shadow_p_y = sy;\n\n let target_direction =\n this.shadow_p_x + this.shadow_w / 2 >= this.get_root_x()\n ? jsMind.direction.right\n : jsMind.direction.left;\n let overlapping_node = this.lookup_overlapping_node_parent(target_direction);\n let target_node = overlapping_node || this.lookup_close_node(target_direction);\n if (!!target_node) {\n let points = this.calc_point_of_node(target_node, target_direction);\n let invalid = jsMind.node.inherited(this.active_node, target_node);\n this.magnet_shadow(points.sp, points.np, invalid);\n this.target_node = target_node;\n this.target_direct = target_direction;\n }\n }\n /**\n * Get X coordinate of root node center.\n * @returns {number}\n */\n get_root_x() {\n let root = this.jm.get_root();\n let root_location = root.get_location();\n let root_size = root.get_size();\n return root_location.x + root_size.w / 2;\n }\n\n /**\n * Lookup overlapping node's parent near the shadow position.\n * @param {number} direction - Direction constant\n * @returns {import('../jsmind.node.js').Node|null}\n */\n lookup_overlapping_node_parent(direction) {\n let shadowRect = this.shadow.getBoundingClientRect();\n let x = shadowRect.x + (shadowRect.width * (1 - direction)) / 2;\n let deltaX = (this.jm.options.layout.hspace + this.jm.options.layout.pspace) * direction;\n let deltaY = shadowRect.height;\n let points = [\n [x, shadowRect.y],\n [x, shadowRect.y + deltaY / 2],\n [x, shadowRect.y + deltaY],\n [x + deltaX / 2, shadowRect.y],\n [x + deltaX / 2, shadowRect.y + deltaY / 2],\n [x + deltaX / 2, shadowRect.y + deltaY],\n [x + deltaX, shadowRect.y],\n [x + deltaX, shadowRect.y + deltaY / 2],\n [x + deltaX, shadowRect.y + deltaY],\n ];\n for (const p of points) {\n let n = this.lookup_node_parent_by_location(p[0], p[1]);\n if (!!n) {\n return n;\n }\n }\n }\n\n /**\n * Find node's parent by a screen location.\n * @param {number} x - Client X\n * @param {number} y - Client Y\n * @returns {import('../jsmind.node.js').Node|null}\n */\n lookup_node_parent_by_location(x, y) {\n return $.d\n .elementsFromPoint(x, y)\n .filter(\n x => x.tagName === 'JMNODE' && x.className !== this.options.shadow_node_class_name\n )\n .map(el => this.jm.view.get_binded_nodeid(el))\n .map(id => id && this.jm.mind.nodes[id])\n .map(n => n && n.parent)\n .find(n => n);\n }\n\n /**\n * Lookup the closest node along a direction.\n * @param {number} direction\n * @returns {import('../jsmind.node.js').Node}\n */\n lookup_close_node(direction) {\n return Object.values(this.jm.mind.nodes)\n .filter(n => n.direction == direction || n.isroot)\n .filter(n => this.jm.layout.is_visible(n))\n .filter(n => this.shadow_on_target_side(n, direction))\n .map(n => ({ node: n, distance: this.shadow_to_node(n, direction) }))\n .reduce(\n (prev, curr) => {\n return prev.distance < curr.distance ? prev : curr;\n },\n { node: this.jm.get_root(), distance: Number.MAX_VALUE }\n ).node;\n }\n\n /**\n * Check if shadow is on the target side of a node.\n * @param {import('../jsmind.node.js').Node} node\n * @param {number} dir\n * @returns {boolean}\n */\n shadow_on_target_side(node, dir) {\n return (\n (dir == jsMind.direction.right && this.shadow_to_right_of_node(node) > 0) ||\n (dir == jsMind.direction.left && this.shadow_to_left_of_node(node) > 0)\n );\n }\n\n /**\n * Distance from shadow to the right side of a node.\n * @param {import('../jsmind.node.js').Node} node\n * @returns {number}\n */\n shadow_to_right_of_node(node) {\n return this.shadow_p_x - node.get_location().x - node.get_size().w;\n }\n\n /**\n * Distance from shadow to the left side of a node.\n * @param {import('../jsmind.node.js').Node} node\n * @returns {number}\n */\n shadow_to_left_of_node(node) {\n return node.get_location().x - this.shadow_p_x - this.shadow_w;\n }\n\n /**\n * Vertical distance between shadow centerline and node centerline.\n * @param {import('../jsmind.node.js').Node} node\n * @returns {number}\n */\n shadow_to_base_line_of_node(node) {\n return this.shadow_p_y + this.shadow_h / 2 - node.get_location().y - node.get_size().h / 2;\n }\n\n /**\n * Manhattan distance to a node along a direction.\n * @param {import('../jsmind.node.js').Node} node\n * @param {number} dir\n * @returns {number}\n */\n shadow_to_node(node, dir) {\n let distance_x =\n dir === jsMind.direction.right\n ? Math.abs(this.shadow_to_right_of_node(node))\n : Math.abs(this.shadow_to_left_of_node(node));\n let distance_y = Math.abs(this.shadow_to_base_line_of_node(node));\n return distance_x + distance_y;\n }\n\n /**\n * Calculate connection points of a node and the shadow.\n * @param {import('../jsmind.node.js').Node} node\n * @param {number} dir\n * @returns {{sp:{x:number,y:number}, np:{x:number,y:number}}}\n */\n calc_point_of_node(node, dir) {\n let ns = node.get_size();\n let nl = node.get_location();\n let node_x = node.isroot\n ? nl.x + ns.w / 2\n : nl.x + (ns.w * (1 + dir)) / 2 + this.options.line_width * dir;\n let node_y = nl.y + ns.h / 2;\n let shadow_x =\n this.shadow_p_x + (this.shadow_w * (1 - dir)) / 2 - this.options.line_width * dir;\n let shadow_y = this.shadow_p_y + this.shadow_h / 2;\n return {\n sp: { x: shadow_x, y: shadow_y },\n np: { x: node_x, y: node_y },\n };\n }\n\n /**\n * Move a node to a new parent/position.\n * @param {import('../jsmind.node.js').Node} src_node\n * @param {import('../jsmind.node.js').Node|null} target_node\n * @param {number|null} target_direct\n */\n move_node(src_node, target_node, target_direct) {\n var shadow_h = this.shadow.offsetTop;\n if (!!target_node && !!src_node && !jsMind.node.inherited(src_node, target_node)) {\n // Call validate_drag function if provided, to validate the drag operation\n if (this.options.validate_drag && typeof this.options.validate_drag === 'function') {\n const isValid = this.options.validate_drag(src_node, target_node);\n if (!isValid) {\n // Drag operation is not allowed, cleanup and return\n this.active_node = null;\n this.target_node = null;\n this.target_direct = null;\n return;\n }\n }\n\n // lookup before_node\n var sibling_nodes = target_node.children;\n var sc = sibling_nodes.length;\n var node = null;\n var delta_y = Number.MAX_VALUE;\n var node_before = null;\n var beforeid = '_last_';\n while (sc--) {\n node = sibling_nodes[sc];\n if (node.direction == target_direct && node.id != src_node.id) {\n var dy = node.get_location().y - shadow_h;\n if (dy > 0 && dy < delta_y) {\n delta_y = dy;\n node_before = node;\n beforeid = '_first_';\n }\n }\n }\n if (!!node_before) {\n beforeid = node_before.id;\n }\n this.jm.move_node(src_node.id, beforeid, target_node.id, target_direct);\n }\n this.active_node = null;\n this.target_node = null;\n this.target_direct = null;\n }\n /**\n * Handle jsMind events.\n * @param {number|string} type - Event type\n * @param {object} [data] - Event data\n */\n jm_event_handle(type, data) {\n if (type === jsMind.event_type.resize) {\n this.resize();\n }\n }\n}\n\n/**\n * Draggable node plugin registration.\n * @type {import('../jsmind.plugin.js').Plugin<Partial<DraggableNodeOptions>>}\n */\nexport const draggable_plugin = new jsMind.plugin('draggable_node', function (jm, options) {\n var jd = new DraggableNode(jm, options);\n jd.init();\n jm.add_event_listener(function (type, data) {\n jd.jm_event_handle.call(jd, type, data);\n });\n});\n\njsMind.register_plugin(draggable_plugin);\n\nexport default DraggableNode;\n"],"names":["jsMind","Error","$","clear_selection","w","getSelection","removeAllRanges","d","selection","empty","DEFAULT_OPTIONS","line_width","line_color","line_color_invalid","lookup_delay","lookup_interval","scrolling_trigger_width","scrolling_step_length","shadow_node_class_name","DraggableNode","constructor","jm","options","opts","util","json","merge","this","version","is_svg_engine","view","engine","e_canvas","canvas_ctx","helper_line","shadow","shadow_p_x","shadow_p_y","shadow_w","shadow_h","active_node","target_node","target_direct","client_w","client_h","offset_x","offset_y","hlookup_delay","hlookup_timer","capture","moved","canvas_draggable","get_view_draggable","view_panel","e_panel","view_panel_rect","init","create_canvas","create_shadow","event_bind","resize","e_nodes","appendChild","setAttribute","size","h","width","height","svg","_create_svg_element","c","ctx","getContext","tag","createElementNS","s","style","visibility","zIndex","cursor","opacity","className","reset_shadow","el","innerHTML","left","top","backgroundImage","backgroundSize","transform","clientWidth","clientHeight","show_shadow","hide_shadow","magnet_shadow","shadow_p","node_p","invalid","clear_lines","color","svg_draw_line","x","y","lineWidth","strokeStyle","lineCap","canvas_lineto","parentNode","removeChild","clearRect","x1","y1","x2","y2","beginPath","moveTo","lineTo","stroke","_svg_bezier_to","path","jd","container","on","e","button","dragstart","call","movementX","movementY","drag","dragend","get_editable","jview","is_editing","view_draggable","find_node_element","target","disable_view_draggable","nodeid","get_binded_nodeid","node","get_node","isroot","data","draggable","getBoundingClientRect","clientX","touches","zoom_current","offsetLeft","clientY","offsetTop","client_hw","Math","floor","client_hh","clearTimeout","clearInterval","setTimeout","setInterval","lookup_target_node","preventDefault","px","py","scrollTop","scrollBy","bottom","scrollHeight","scrollLeft","right","scrollWidth","enable_view_draggable","src_node","move_node","tagName","toLowerCase","sx","sy","target_direction","get_root_x","direction","lookup_overlapping_node_parent","lookup_close_node","points","calc_point_of_node","inherited","sp","np","root","get_root","root_location","get_location","root_size","get_size","shadowRect","deltaX","layout","hspace","pspace","deltaY","p","n","lookup_node_parent_by_location","elementsFromPoint","filter","map","id","mind","nodes","parent","find","Object","values","is_visible","shadow_on_target_side","distance","shadow_to_node","reduce","prev","curr","Number","MAX_VALUE","dir","shadow_to_right_of_node","shadow_to_left_of_node","shadow_to_base_line_of_node","abs","ns","nl","node_x","node_y","validate_drag","sibling_nodes","children","sc","length","delta_y","node_before","beforeid","dy","jm_event_handle","type","event_type","draggable_plugin","plugin","add_event_listener","register_plugin"],"mappings":"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"}
1
+ {"version":3,"file":"jsmind.draggable-node.js","sources":["../src/plugins/jsmind.draggable-node.js"],"sourcesContent":["/**\r\n * @license BSD\r\n * @copyright 2014-2025 UmbraCi\r\n *\r\n * Project Home:\r\n * https://github.com/UmbraCi/jsmind/\r\n */\r\n\r\nimport jsMind from '@umbraci/jsmind';\r\n\r\nif (!jsMind) {\r\n throw new Error('jsMind is not defined');\r\n}\r\n\r\nconst $ = jsMind.$;\r\n\r\nconst clear_selection =\r\n 'getSelection' in $.w\r\n ? function () {\r\n $.w.getSelection().removeAllRanges();\r\n }\r\n : function () {\r\n $.d.selection.empty();\r\n };\r\n\r\n/**\r\n * Default options for draggable node plugin.\r\n * @typedef {Object} DraggableNodeOptions\r\n * @property {number} [line_width]\r\n * @property {string} [line_color]\r\n * @property {string} [line_color_invalid]\r\n * @property {number} [lookup_delay]\r\n * @property {number} [lookup_interval]\r\n * @property {number} [scrolling_trigger_width]\r\n * @property {number} [scrolling_step_length]\r\n * @property {string} [shadow_node_class_name]\r\n * @property {(draggedNode:import('../jsmind.node.js').Node, targetNode:import('../jsmind.node.js').Node|null)=>boolean} [validate_drag]\r\n */\r\nconst DEFAULT_OPTIONS = {\r\n line_width: 5,\r\n line_color: 'rgba(0,0,0,0.3)',\r\n line_color_invalid: 'rgba(255,51,51,0.6)',\r\n lookup_delay: 200,\r\n lookup_interval: 100,\r\n scrolling_trigger_width: 20,\r\n scrolling_step_length: 10,\r\n shadow_node_class_name: 'jsmind-draggable-shadow-node',\r\n};\r\n\r\n/**\r\n * Draggable node plugin for jsMind.\r\n */\r\nexport class DraggableNode {\r\n /**\r\n * Create draggable node plugin instance.\r\n * @param {import('../jsmind.js').default} jm - jsMind instance\r\n * @param {Partial<DraggableNodeOptions>} options - Plugin options\r\n */\r\n constructor(jm, options) {\r\n var opts = {};\r\n jsMind.util.json.merge(opts, DEFAULT_OPTIONS);\r\n jsMind.util.json.merge(opts, options);\r\n\r\n this.version = '0.4.0';\r\n /** @type {import('../jsmind.js').default} */\r\n this.jm = jm;\r\n /** @type {DraggableNodeOptions} */\r\n this.options = opts;\r\n /** @type {boolean} */\r\n this.is_svg_engine = jm.view.opts.engine === 'svg';\r\n /** @type {HTMLCanvasElement|SVGSVGElement|null} */\r\n this.e_canvas = null;\r\n /** @type {CanvasRenderingContext2D|null} */\r\n this.canvas_ctx = null;\r\n /** @type {SVGPathElement|null} */\r\n this.helper_line = null;\r\n /** @type {HTMLElement|null} */\r\n this.shadow = null;\r\n /** @type {number} */\r\n this.shadow_p_x = 0;\r\n /** @type {number} */\r\n this.shadow_p_y = 0;\r\n /** @type {number} */\r\n this.shadow_w = 0;\r\n /** @type {number} */\r\n this.shadow_h = 0;\r\n /** @type {import('../jsmind.node.js').Node|null} */\r\n this.active_node = null;\r\n /** @type {import('../jsmind.node.js').Node|null} */\r\n this.target_node = null;\r\n /** @type {number|null} */\r\n this.target_direct = null;\r\n /** @type {number} */\r\n this.client_w = 0;\r\n /** @type {number} */\r\n this.client_h = 0;\r\n /** @type {number} */\r\n this.offset_x = 0;\r\n /** @type {number} */\r\n this.offset_y = 0;\r\n /** @type {number} */\r\n this.hlookup_delay = 0;\r\n /** @type {number} */\r\n this.hlookup_timer = 0;\r\n /** @type {boolean} */\r\n this.capture = false;\r\n /** @type {boolean} */\r\n this.moved = false;\r\n /** @type {boolean} */\r\n this.canvas_draggable = jm.get_view_draggable();\r\n /** @type {HTMLElement} */\r\n this.view_panel = jm.view.e_panel;\r\n /** @type {DOMRect|null} */\r\n this.view_panel_rect = null;\r\n }\r\n /** Initialize the draggable node plugin. */\r\n init() {\r\n this.create_canvas();\r\n this.create_shadow();\r\n this.event_bind();\r\n }\r\n /** Resize canvas/SVG and shadow elements. */\r\n resize() {\r\n this.jm.view.e_nodes.appendChild(this.shadow);\r\n if (this.is_svg_engine) {\r\n this.e_canvas.setAttribute('width', this.jm.view.size.w);\r\n this.e_canvas.setAttribute('height', this.jm.view.size.h);\r\n } else {\r\n this.e_canvas.width = this.jm.view.size.w;\r\n this.e_canvas.height = this.jm.view.size.h;\r\n }\r\n }\r\n /** Create canvas or SVG for drawing drag lines. */\r\n create_canvas() {\r\n if (this.is_svg_engine) {\r\n // Create SVG element for helper lines\r\n var svg = this._create_svg_element('svg');\r\n svg.setAttribute('class', 'jsmind-draggable-helper');\r\n svg.setAttribute('style', 'position: absolute; top: 0; left: 0; pointer-events: none;');\r\n this.jm.view.e_panel.appendChild(svg);\r\n this.e_canvas = svg;\r\n } else {\r\n // Create Canvas element for helper lines\r\n var c = $.c('canvas');\r\n this.jm.view.e_panel.appendChild(c);\r\n var ctx = c.getContext('2d');\r\n this.e_canvas = c;\r\n this.canvas_ctx = ctx;\r\n }\r\n }\r\n /**\r\n * Create SVG element with proper namespace.\r\n * @param {string} tag - SVG tag name\r\n * @returns {SVGElement}\r\n * @private\r\n */\r\n _create_svg_element(tag) {\r\n return $.d.createElementNS('http://www.w3.org/2000/svg', tag);\r\n }\r\n create_shadow() {\r\n var s = $.c('jmnode');\r\n s.style.visibility = 'hidden';\r\n s.style.zIndex = '3';\r\n s.style.cursor = 'move';\r\n s.style.opacity = '0.7';\r\n s.className = this.options.shadow_node_class_name;\r\n this.shadow = s;\r\n }\r\n /**\r\n * Reset shadow element style and cache its size.\r\n * @param {HTMLElement} el - The node element to mirror as shadow\r\n */\r\n reset_shadow(el) {\r\n var s = this.shadow.style;\r\n this.shadow.innerHTML = el.innerHTML;\r\n s.left = el.style.left;\r\n s.top = el.style.top;\r\n s.width = el.style.width;\r\n s.height = el.style.height;\r\n s.backgroundImage = el.style.backgroundImage;\r\n s.backgroundSize = el.style.backgroundSize;\r\n s.transform = el.style.transform;\r\n this.shadow_w = this.shadow.clientWidth;\r\n this.shadow_h = this.shadow.clientHeight;\r\n }\r\n /** Show the shadow element. */\r\n show_shadow() {\r\n if (!this.moved) {\r\n this.shadow.style.visibility = 'visible';\r\n }\r\n }\r\n /** Hide the shadow element. */\r\n hide_shadow() {\r\n this.shadow.style.visibility = 'hidden';\r\n }\r\n /**\r\n * Draw a helper line between the shadow and target node.\r\n * @param {{x:number,y:number}} shadow_p - Shadow anchor point\r\n * @param {{x:number,y:number}} node_p - Target node anchor point\r\n * @param {boolean} invalid - Whether current target is invalid\r\n */\r\n magnet_shadow(shadow_p, node_p, invalid) {\r\n this.clear_lines();\r\n var color = invalid ? this.options.line_color_invalid : this.options.line_color;\r\n\r\n if (this.is_svg_engine) {\r\n this.svg_draw_line(shadow_p.x, shadow_p.y, node_p.x, node_p.y, color);\r\n } else {\r\n this.canvas_ctx.lineWidth = this.options.line_width;\r\n this.canvas_ctx.strokeStyle = color;\r\n this.canvas_ctx.lineCap = 'round';\r\n this.canvas_lineto(shadow_p.x, shadow_p.y, node_p.x, node_p.y);\r\n }\r\n }\r\n /** Clear helper lines from canvas or SVG. */\r\n clear_lines() {\r\n if (this.is_svg_engine) {\r\n if (this.helper_line && this.helper_line.parentNode) {\r\n this.e_canvas.removeChild(this.helper_line);\r\n this.helper_line = null;\r\n }\r\n } else {\r\n this.canvas_ctx.clearRect(0, 0, this.jm.view.size.w, this.jm.view.size.h);\r\n }\r\n }\r\n /**\r\n * Draw a straight helper line on canvas.\r\n * @param {number} x1\r\n * @param {number} y1\r\n * @param {number} x2\r\n * @param {number} y2\r\n */\r\n canvas_lineto(x1, y1, x2, y2) {\r\n this.canvas_ctx.beginPath();\r\n this.canvas_ctx.moveTo(x1, y1);\r\n this.canvas_ctx.lineTo(x2, y2);\r\n this.canvas_ctx.stroke();\r\n }\r\n /**\r\n * Draw a helper line on SVG using bezier curve.\r\n * Reuses the line drawing logic from SvgGraph.\r\n * @param {number} x1 - Start x coordinate\r\n * @param {number} y1 - Start y coordinate\r\n * @param {number} x2 - End x coordinate\r\n * @param {number} y2 - End y coordinate\r\n * @param {string} color - Line color\r\n */\r\n svg_draw_line(x1, y1, x2, y2, color) {\r\n // Create SVG path element for helper line\r\n this.helper_line = this._create_svg_element('path');\r\n this.helper_line.setAttribute('stroke', color);\r\n this.helper_line.setAttribute('stroke-width', this.options.line_width);\r\n this.helper_line.setAttribute('fill', 'transparent');\r\n this.helper_line.setAttribute('stroke-linecap', 'round');\r\n\r\n // Draw bezier curve (same as SvgGraph._bezier_to)\r\n this._svg_bezier_to(this.helper_line, x1, y1, x2, y2);\r\n\r\n // Add to SVG container\r\n this.e_canvas.appendChild(this.helper_line);\r\n }\r\n /**\r\n * Draw bezier curve to SVG path element.\r\n * Reuses logic from SvgGraph._bezier_to.\r\n * @param {SVGPathElement} path - SVG path element\r\n * @param {number} x1 - Start x coordinate\r\n * @param {number} y1 - Start y coordinate\r\n * @param {number} x2 - End x coordinate\r\n * @param {number} y2 - End y coordinate\r\n * @private\r\n */\r\n _svg_bezier_to(path, x1, y1, x2, y2) {\r\n path.setAttribute(\r\n 'd',\r\n 'M ' +\r\n x1 +\r\n ' ' +\r\n y1 +\r\n ' C ' +\r\n (x1 + ((x2 - x1) * 2) / 3) +\r\n ' ' +\r\n y1 +\r\n ', ' +\r\n x1 +\r\n ' ' +\r\n y2 +\r\n ', ' +\r\n x2 +\r\n ' ' +\r\n y2\r\n );\r\n }\r\n /** Bind mouse/touch events for dragging. */\r\n event_bind() {\r\n var jd = this;\r\n var container = this.jm.view.container;\r\n $.on(container, 'mousedown', function (e) {\r\n if (e.button === 0) {\r\n jd.dragstart.call(jd, e);\r\n }\r\n });\r\n $.on(container, 'mousemove', function (e) {\r\n if (e.movementX !== 0 || e.movementY !== 0) {\r\n jd.drag.call(jd, e);\r\n }\r\n });\r\n $.on(container, 'mouseup', function (e) {\r\n jd.dragend.call(jd, e);\r\n });\r\n $.on(container, 'touchstart', function (e) {\r\n jd.dragstart.call(jd, e);\r\n });\r\n $.on(container, 'touchmove', function (e) {\r\n jd.drag.call(jd, e);\r\n });\r\n $.on(container, 'touchend', function (e) {\r\n jd.dragend.call(jd, e);\r\n });\r\n }\r\n /**\r\n * Begin dragging interaction.\r\n * @param {MouseEvent|TouchEvent} e - Pointer down event\r\n */\r\n dragstart(e) {\r\n if (!this.jm.get_editable()) {\r\n return;\r\n }\r\n if (this.capture) {\r\n return;\r\n }\r\n var jview = this.jm.view;\r\n if (jview.is_editing()) {\r\n return;\r\n }\r\n this.active_node = null;\r\n this.view_draggable = this.jm.get_view_draggable();\r\n\r\n var el = this.find_node_element(e.target);\r\n if (!el) {\r\n return;\r\n }\r\n if (this.view_draggable) {\r\n this.jm.disable_view_draggable();\r\n }\r\n var nodeid = jview.get_binded_nodeid(el);\r\n if (!!nodeid) {\r\n var node = this.jm.get_node(nodeid);\r\n if (!node.isroot) {\r\n // 检查节点是否允许拖拽\r\n if (node.data && node.data.draggable === false) {\r\n return;\r\n }\r\n this.reset_shadow(el);\r\n this.view_panel_rect = this.view_panel.getBoundingClientRect();\r\n this.active_node = node;\r\n this.offset_x =\r\n (e.clientX || e.touches[0].clientX) / jview.zoom_current - el.offsetLeft;\r\n this.offset_y =\r\n (e.clientY || e.touches[0].clientY) / jview.zoom_current - el.offsetTop;\r\n this.client_hw = Math.floor(el.clientWidth / 2);\r\n this.client_hh = Math.floor(el.clientHeight / 2);\r\n if (this.hlookup_delay != 0) {\r\n $.w.clearTimeout(this.hlookup_delay);\r\n }\r\n if (this.hlookup_timer != 0) {\r\n $.w.clearInterval(this.hlookup_timer);\r\n }\r\n var jd = this;\r\n this.hlookup_delay = $.w.setTimeout(function () {\r\n jd.hlookup_delay = 0;\r\n jd.hlookup_timer = $.w.setInterval(function () {\r\n jd.lookup_target_node.call(jd);\r\n }, jd.options.lookup_interval);\r\n }, this.options.lookup_delay);\r\n jd.capture = true;\r\n }\r\n }\r\n }\r\n /**\r\n * Drag handler to move shadow and auto-scroll container.\r\n * @param {MouseEvent|TouchEvent} e - Pointer move event\r\n */\r\n drag(e) {\r\n if (!this.jm.get_editable()) {\r\n return;\r\n }\r\n if (this.capture) {\r\n e.preventDefault();\r\n this.show_shadow();\r\n this.moved = true;\r\n clear_selection();\r\n var jview = this.jm.view;\r\n var px = (e.clientX || e.touches[0].clientX) / jview.zoom_current - this.offset_x;\r\n var py = (e.clientY || e.touches[0].clientY) / jview.zoom_current - this.offset_y;\r\n // scrolling container axisY if drag nodes exceeding container\r\n if (\r\n e.clientY - this.view_panel_rect.top < this.options.scrolling_trigger_width &&\r\n this.view_panel.scrollTop > this.options.scrolling_step_length\r\n ) {\r\n this.view_panel.scrollBy(0, -this.options.scrolling_step_length);\r\n this.offset_y += this.options.scrolling_step_length / jview.zoom_current;\r\n } else if (\r\n this.view_panel_rect.bottom - e.clientY < this.options.scrolling_trigger_width &&\r\n this.view_panel.scrollTop <\r\n this.view_panel.scrollHeight -\r\n this.view_panel_rect.height -\r\n this.options.scrolling_step_length\r\n ) {\r\n this.view_panel.scrollBy(0, this.options.scrolling_step_length);\r\n this.offset_y -= this.options.scrolling_step_length / jview.zoom_current;\r\n }\r\n // scrolling container axisX if drag nodes exceeding container\r\n if (\r\n e.clientX - this.view_panel_rect.left < this.options.scrolling_trigger_width &&\r\n this.view_panel.scrollLeft > this.options.scrolling_step_length\r\n ) {\r\n this.view_panel.scrollBy(-this.options.scrolling_step_length, 0);\r\n this.offset_x += this.options.scrolling_step_length / jview.zoom_current;\r\n } else if (\r\n this.view_panel_rect.right - e.clientX < this.options.scrolling_trigger_width &&\r\n this.view_panel.scrollLeft <\r\n this.view_panel.scrollWidth -\r\n this.view_panel_rect.width -\r\n this.options.scrolling_step_length\r\n ) {\r\n this.view_panel.scrollBy(this.options.scrolling_step_length, 0);\r\n this.offset_x -= this.options.scrolling_step_length / jview.zoom_current;\r\n }\r\n this.shadow.style.left = px + 'px';\r\n this.shadow.style.top = py + 'px';\r\n clear_selection();\r\n }\r\n }\r\n /**\r\n * Finish dragging, move the node if applicable.\r\n * @param {MouseEvent|TouchEvent} e - Pointer up event\r\n */\r\n dragend(e) {\r\n if (!this.jm.get_editable()) {\r\n return;\r\n }\r\n if (this.view_draggable) {\r\n this.jm.enable_view_draggable();\r\n }\r\n if (this.capture) {\r\n if (this.hlookup_delay != 0) {\r\n $.w.clearTimeout(this.hlookup_delay);\r\n this.hlookup_delay = 0;\r\n this.clear_lines();\r\n }\r\n if (this.hlookup_timer != 0) {\r\n $.w.clearInterval(this.hlookup_timer);\r\n this.hlookup_timer = 0;\r\n this.clear_lines();\r\n }\r\n if (this.moved) {\r\n var src_node = this.active_node;\r\n var target_node = this.target_node;\r\n var target_direct = this.target_direct;\r\n this.move_node(src_node, target_node, target_direct);\r\n }\r\n this.hide_shadow();\r\n }\r\n this.view_panel_rect = null;\r\n this.moved = false;\r\n this.capture = false;\r\n }\r\n /**\r\n * Find the closest node element from an event target.\r\n * @param {HTMLElement} el - Current DOM element\r\n * @returns {HTMLElement|null} Matched node element or null\r\n */\r\n find_node_element(el) {\r\n if (\r\n el === this.jm.view.e_nodes ||\r\n el === this.jm.view.e_panel ||\r\n el === this.jm.view.container\r\n ) {\r\n return null;\r\n }\r\n if (el.tagName.toLowerCase() === 'jmnode') {\r\n return el;\r\n }\r\n return this.find_node_element(el.parentNode);\r\n }\r\n /** Recompute target node under the shadow and draw helper. */\r\n lookup_target_node() {\r\n let sx = this.shadow.offsetLeft;\r\n let sy = this.shadow.offsetTop;\r\n if (sx === this.shadow_p_x && sy === this.shadow_p_y) {\r\n return;\r\n }\r\n this.shadow_p_x = sx;\r\n this.shadow_p_y = sy;\r\n\r\n let target_direction =\r\n this.shadow_p_x + this.shadow_w / 2 >= this.get_root_x()\r\n ? jsMind.direction.right\r\n : jsMind.direction.left;\r\n let overlapping_node = this.lookup_overlapping_node_parent(target_direction);\r\n let target_node = overlapping_node || this.lookup_close_node(target_direction);\r\n if (!!target_node) {\r\n let points = this.calc_point_of_node(target_node, target_direction);\r\n let invalid = jsMind.node.inherited(this.active_node, target_node);\r\n this.magnet_shadow(points.sp, points.np, invalid);\r\n this.target_node = target_node;\r\n this.target_direct = target_direction;\r\n }\r\n }\r\n /**\r\n * Get X coordinate of root node center.\r\n * @returns {number}\r\n */\r\n get_root_x() {\r\n let root = this.jm.get_root();\r\n let root_location = root.get_location();\r\n let root_size = root.get_size();\r\n return root_location.x + root_size.w / 2;\r\n }\r\n\r\n /**\r\n * Lookup overlapping node's parent near the shadow position.\r\n * @param {number} direction - Direction constant\r\n * @returns {import('../jsmind.node.js').Node|null}\r\n */\r\n lookup_overlapping_node_parent(direction) {\r\n let shadowRect = this.shadow.getBoundingClientRect();\r\n let x = shadowRect.x + (shadowRect.width * (1 - direction)) / 2;\r\n let deltaX = (this.jm.options.layout.hspace + this.jm.options.layout.pspace) * direction;\r\n let deltaY = shadowRect.height;\r\n let points = [\r\n [x, shadowRect.y],\r\n [x, shadowRect.y + deltaY / 2],\r\n [x, shadowRect.y + deltaY],\r\n [x + deltaX / 2, shadowRect.y],\r\n [x + deltaX / 2, shadowRect.y + deltaY / 2],\r\n [x + deltaX / 2, shadowRect.y + deltaY],\r\n [x + deltaX, shadowRect.y],\r\n [x + deltaX, shadowRect.y + deltaY / 2],\r\n [x + deltaX, shadowRect.y + deltaY],\r\n ];\r\n for (const p of points) {\r\n let n = this.lookup_node_parent_by_location(p[0], p[1]);\r\n if (!!n) {\r\n return n;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Find node's parent by a screen location.\r\n * @param {number} x - Client X\r\n * @param {number} y - Client Y\r\n * @returns {import('../jsmind.node.js').Node|null}\r\n */\r\n lookup_node_parent_by_location(x, y) {\r\n return $.d\r\n .elementsFromPoint(x, y)\r\n .filter(\r\n x => x.tagName === 'JMNODE' && x.className !== this.options.shadow_node_class_name\r\n )\r\n .map(el => this.jm.view.get_binded_nodeid(el))\r\n .map(id => id && this.jm.mind.nodes[id])\r\n .map(n => n && n.parent)\r\n .find(n => n);\r\n }\r\n\r\n /**\r\n * Lookup the closest node along a direction.\r\n * @param {number} direction\r\n * @returns {import('../jsmind.node.js').Node}\r\n */\r\n lookup_close_node(direction) {\r\n return Object.values(this.jm.mind.nodes)\r\n .filter(n => n.direction == direction || n.isroot)\r\n .filter(n => this.jm.layout.is_visible(n))\r\n .filter(n => this.shadow_on_target_side(n, direction))\r\n .map(n => ({ node: n, distance: this.shadow_to_node(n, direction) }))\r\n .reduce(\r\n (prev, curr) => {\r\n return prev.distance < curr.distance ? prev : curr;\r\n },\r\n { node: this.jm.get_root(), distance: Number.MAX_VALUE }\r\n ).node;\r\n }\r\n\r\n /**\r\n * Check if shadow is on the target side of a node.\r\n * @param {import('../jsmind.node.js').Node} node\r\n * @param {number} dir\r\n * @returns {boolean}\r\n */\r\n shadow_on_target_side(node, dir) {\r\n return (\r\n (dir == jsMind.direction.right && this.shadow_to_right_of_node(node) > 0) ||\r\n (dir == jsMind.direction.left && this.shadow_to_left_of_node(node) > 0)\r\n );\r\n }\r\n\r\n /**\r\n * Distance from shadow to the right side of a node.\r\n * @param {import('../jsmind.node.js').Node} node\r\n * @returns {number}\r\n */\r\n shadow_to_right_of_node(node) {\r\n return this.shadow_p_x - node.get_location().x - node.get_size().w;\r\n }\r\n\r\n /**\r\n * Distance from shadow to the left side of a node.\r\n * @param {import('../jsmind.node.js').Node} node\r\n * @returns {number}\r\n */\r\n shadow_to_left_of_node(node) {\r\n return node.get_location().x - this.shadow_p_x - this.shadow_w;\r\n }\r\n\r\n /**\r\n * Vertical distance between shadow centerline and node centerline.\r\n * @param {import('../jsmind.node.js').Node} node\r\n * @returns {number}\r\n */\r\n shadow_to_base_line_of_node(node) {\r\n return this.shadow_p_y + this.shadow_h / 2 - node.get_location().y - node.get_size().h / 2;\r\n }\r\n\r\n /**\r\n * Manhattan distance to a node along a direction.\r\n * @param {import('../jsmind.node.js').Node} node\r\n * @param {number} dir\r\n * @returns {number}\r\n */\r\n shadow_to_node(node, dir) {\r\n let distance_x =\r\n dir === jsMind.direction.right\r\n ? Math.abs(this.shadow_to_right_of_node(node))\r\n : Math.abs(this.shadow_to_left_of_node(node));\r\n let distance_y = Math.abs(this.shadow_to_base_line_of_node(node));\r\n return distance_x + distance_y;\r\n }\r\n\r\n /**\r\n * Calculate connection points of a node and the shadow.\r\n * @param {import('../jsmind.node.js').Node} node\r\n * @param {number} dir\r\n * @returns {{sp:{x:number,y:number}, np:{x:number,y:number}}}\r\n */\r\n calc_point_of_node(node, dir) {\r\n let ns = node.get_size();\r\n let nl = node.get_location();\r\n let node_x = node.isroot\r\n ? nl.x + ns.w / 2\r\n : nl.x + (ns.w * (1 + dir)) / 2 + this.options.line_width * dir;\r\n let node_y = nl.y + ns.h / 2;\r\n let shadow_x =\r\n this.shadow_p_x + (this.shadow_w * (1 - dir)) / 2 - this.options.line_width * dir;\r\n let shadow_y = this.shadow_p_y + this.shadow_h / 2;\r\n return {\r\n sp: { x: shadow_x, y: shadow_y },\r\n np: { x: node_x, y: node_y },\r\n };\r\n }\r\n\r\n /**\r\n * Move a node to a new parent/position.\r\n * @param {import('../jsmind.node.js').Node} src_node\r\n * @param {import('../jsmind.node.js').Node|null} target_node\r\n * @param {number|null} target_direct\r\n */\r\n move_node(src_node, target_node, target_direct) {\r\n var shadow_h = this.shadow.offsetTop;\r\n if (!!target_node && !!src_node && !jsMind.node.inherited(src_node, target_node)) {\r\n // Call validate_drag function if provided, to validate the drag operation\r\n if (this.options.validate_drag && typeof this.options.validate_drag === 'function') {\r\n const isValid = this.options.validate_drag(src_node, target_node);\r\n if (!isValid) {\r\n // Drag operation is not allowed, cleanup and return\r\n this.active_node = null;\r\n this.target_node = null;\r\n this.target_direct = null;\r\n return;\r\n }\r\n }\r\n\r\n // lookup before_node\r\n var sibling_nodes = target_node.children;\r\n var sc = sibling_nodes.length;\r\n var node = null;\r\n var delta_y = Number.MAX_VALUE;\r\n var node_before = null;\r\n var beforeid = '_last_';\r\n while (sc--) {\r\n node = sibling_nodes[sc];\r\n if (node.direction == target_direct && node.id != src_node.id) {\r\n var dy = node.get_location().y - shadow_h;\r\n if (dy > 0 && dy < delta_y) {\r\n delta_y = dy;\r\n node_before = node;\r\n beforeid = '_first_';\r\n }\r\n }\r\n }\r\n if (!!node_before) {\r\n beforeid = node_before.id;\r\n }\r\n this.jm.move_node(src_node.id, beforeid, target_node.id, target_direct);\r\n }\r\n this.active_node = null;\r\n this.target_node = null;\r\n this.target_direct = null;\r\n }\r\n /**\r\n * Handle jsMind events.\r\n * @param {number|string} type - Event type\r\n * @param {object} [data] - Event data\r\n */\r\n jm_event_handle(type, data) {\r\n if (type === jsMind.event_type.resize) {\r\n this.resize();\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Draggable node plugin registration.\r\n * @type {import('../jsmind.plugin.js').Plugin<Partial<DraggableNodeOptions>>}\r\n */\r\nexport const draggable_plugin = new jsMind.plugin('draggable_node', function (jm, options) {\r\n var jd = new DraggableNode(jm, options);\r\n jd.init();\r\n jm.add_event_listener(function (type, data) {\r\n jd.jm_event_handle.call(jd, type, data);\r\n });\r\n});\r\n\r\njsMind.register_plugin(draggable_plugin);\r\n\r\nexport default DraggableNode;\r\n"],"names":["jsMind","Error","$","clear_selection","w","getSelection","removeAllRanges","d","selection","empty","DEFAULT_OPTIONS","line_width","line_color","line_color_invalid","lookup_delay","lookup_interval","scrolling_trigger_width","scrolling_step_length","shadow_node_class_name","DraggableNode","constructor","jm","options","opts","util","json","merge","this","version","is_svg_engine","view","engine","e_canvas","canvas_ctx","helper_line","shadow","shadow_p_x","shadow_p_y","shadow_w","shadow_h","active_node","target_node","target_direct","client_w","client_h","offset_x","offset_y","hlookup_delay","hlookup_timer","capture","moved","canvas_draggable","get_view_draggable","view_panel","e_panel","view_panel_rect","init","create_canvas","create_shadow","event_bind","resize","e_nodes","appendChild","setAttribute","size","h","width","height","svg","_create_svg_element","c","ctx","getContext","tag","createElementNS","s","style","visibility","zIndex","cursor","opacity","className","reset_shadow","el","innerHTML","left","top","backgroundImage","backgroundSize","transform","clientWidth","clientHeight","show_shadow","hide_shadow","magnet_shadow","shadow_p","node_p","invalid","clear_lines","color","svg_draw_line","x","y","lineWidth","strokeStyle","lineCap","canvas_lineto","parentNode","removeChild","clearRect","x1","y1","x2","y2","beginPath","moveTo","lineTo","stroke","_svg_bezier_to","path","jd","container","on","e","button","dragstart","call","movementX","movementY","drag","dragend","get_editable","jview","is_editing","view_draggable","find_node_element","target","disable_view_draggable","nodeid","get_binded_nodeid","node","get_node","isroot","data","draggable","getBoundingClientRect","clientX","touches","zoom_current","offsetLeft","clientY","offsetTop","client_hw","Math","floor","client_hh","clearTimeout","clearInterval","setTimeout","setInterval","lookup_target_node","preventDefault","px","py","scrollTop","scrollBy","bottom","scrollHeight","scrollLeft","right","scrollWidth","enable_view_draggable","src_node","move_node","tagName","toLowerCase","sx","sy","target_direction","get_root_x","direction","lookup_overlapping_node_parent","lookup_close_node","points","calc_point_of_node","inherited","sp","np","root","get_root","root_location","get_location","root_size","get_size","shadowRect","deltaX","layout","hspace","pspace","deltaY","p","n","lookup_node_parent_by_location","elementsFromPoint","filter","map","id","mind","nodes","parent","find","Object","values","is_visible","shadow_on_target_side","distance","shadow_to_node","reduce","prev","curr","Number","MAX_VALUE","dir","shadow_to_right_of_node","shadow_to_left_of_node","shadow_to_base_line_of_node","abs","ns","nl","node_x","node_y","validate_drag","sibling_nodes","children","sc","length","delta_y","node_before","beforeid","dy","jm_event_handle","type","event_type","draggable_plugin","plugin","add_event_listener","register_plugin"],"mappings":";;;;;;;sYAUA,IAAKA,UACD,MAAM,IAAIC,MAAM,yBAGpB,MAAMC,EAAIF,EAAM,QAACE,EAEXC,EACF,iBAAkBD,EAAEE,EACd,WACIF,EAAEE,EAAEC,eAAeC,iBACtB,EACD,WACIJ,EAAEK,EAAEC,UAAUC,OAC5B,EAeMC,EAAkB,CACpBC,WAAY,EACZC,WAAY,kBACZC,mBAAoB,sBACpBC,aAAc,IACdC,gBAAiB,IACjBC,wBAAyB,GACzBC,sBAAuB,GACvBC,uBAAwB,gCAMrB,MAAMC,EAMT,WAAAC,CAAYC,EAAIC,GACZ,IAAIC,EAAO,CAAA,EACXvB,EAAM,QAACwB,KAAKC,KAAKC,MAAMH,EAAMb,GAC7BV,EAAM,QAACwB,KAAKC,KAAKC,MAAMH,EAAMD,GAE7BK,KAAKC,QAAU,QAEfD,KAAKN,GAAKA,EAEVM,KAAKL,QAAUC,EAEfI,KAAKE,cAAwC,QAAxBR,EAAGS,KAAKP,KAAKQ,OAElCJ,KAAKK,SAAW,KAEhBL,KAAKM,WAAa,KAElBN,KAAKO,YAAc,KAEnBP,KAAKQ,OAAS,KAEdR,KAAKS,WAAa,EAElBT,KAAKU,WAAa,EAElBV,KAAKW,SAAW,EAEhBX,KAAKY,SAAW,EAEhBZ,KAAKa,YAAc,KAEnBb,KAAKc,YAAc,KAEnBd,KAAKe,cAAgB,KAErBf,KAAKgB,SAAW,EAEhBhB,KAAKiB,SAAW,EAEhBjB,KAAKkB,SAAW,EAEhBlB,KAAKmB,SAAW,EAEhBnB,KAAKoB,cAAgB,EAErBpB,KAAKqB,cAAgB,EAErBrB,KAAKsB,SAAU,EAEftB,KAAKuB,OAAQ,EAEbvB,KAAKwB,iBAAmB9B,EAAG+B,qBAE3BzB,KAAK0B,WAAahC,EAAGS,KAAKwB,QAE1B3B,KAAK4B,gBAAkB,IAC1B,CAED,IAAAC,GACI7B,KAAK8B,gBACL9B,KAAK+B,gBACL/B,KAAKgC,YACR,CAED,MAAAC,GACIjC,KAAKN,GAAGS,KAAK+B,QAAQC,YAAYnC,KAAKQ,QAClCR,KAAKE,eACLF,KAAKK,SAAS+B,aAAa,QAASpC,KAAKN,GAAGS,KAAKkC,KAAK5D,GACtDuB,KAAKK,SAAS+B,aAAa,SAAUpC,KAAKN,GAAGS,KAAKkC,KAAKC,KAEvDtC,KAAKK,SAASkC,MAAQvC,KAAKN,GAAGS,KAAKkC,KAAK5D,EACxCuB,KAAKK,SAASmC,OAASxC,KAAKN,GAAGS,KAAKkC,KAAKC,EAEhD,CAED,aAAAR,GACI,GAAI9B,KAAKE,cAAe,CAEpB,IAAIuC,EAAMzC,KAAK0C,oBAAoB,OACnCD,EAAIL,aAAa,QAAS,2BAC1BK,EAAIL,aAAa,QAAS,8DAC1BpC,KAAKN,GAAGS,KAAKwB,QAAQQ,YAAYM,GACjCzC,KAAKK,SAAWoC,CAC5B,KAAe,CAEH,IAAIE,EAAIpE,EAAEoE,EAAE,UACZ3C,KAAKN,GAAGS,KAAKwB,QAAQQ,YAAYQ,GACjC,IAAIC,EAAMD,EAAEE,WAAW,MACvB7C,KAAKK,SAAWsC,EAChB3C,KAAKM,WAAasC,CACrB,CACJ,CAOD,mBAAAF,CAAoBI,GAChB,OAAOvE,EAAEK,EAAEmE,gBAAgB,6BAA8BD,EAC5D,CACD,aAAAf,GACI,IAAIiB,EAAIzE,EAAEoE,EAAE,UACZK,EAAEC,MAAMC,WAAa,SACrBF,EAAEC,MAAME,OAAS,IACjBH,EAAEC,MAAMG,OAAS,OACjBJ,EAAEC,MAAMI,QAAU,MAClBL,EAAEM,UAAYtD,KAAKL,QAAQJ,uBAC3BS,KAAKQ,OAASwC,CACjB,CAKD,YAAAO,CAAaC,GACT,IAAIR,EAAIhD,KAAKQ,OAAOyC,MACpBjD,KAAKQ,OAAOiD,UAAYD,EAAGC,UAC3BT,EAAEU,KAAOF,EAAGP,MAAMS,KAClBV,EAAEW,IAAMH,EAAGP,MAAMU,IACjBX,EAAET,MAAQiB,EAAGP,MAAMV,MACnBS,EAAER,OAASgB,EAAGP,MAAMT,OACpBQ,EAAEY,gBAAkBJ,EAAGP,MAAMW,gBAC7BZ,EAAEa,eAAiBL,EAAGP,MAAMY,eAC5Bb,EAAEc,UAAYN,EAAGP,MAAMa,UACvB9D,KAAKW,SAAWX,KAAKQ,OAAOuD,YAC5B/D,KAAKY,SAAWZ,KAAKQ,OAAOwD,YAC/B,CAED,WAAAC,GACSjE,KAAKuB,QACNvB,KAAKQ,OAAOyC,MAAMC,WAAa,UAEtC,CAED,WAAAgB,GACIlE,KAAKQ,OAAOyC,MAAMC,WAAa,QAClC,CAOD,aAAAiB,CAAcC,EAAUC,EAAQC,GAC5BtE,KAAKuE,cACL,IAAIC,EAAQF,EAAUtE,KAAKL,QAAQT,mBAAqBc,KAAKL,QAAQV,WAEjEe,KAAKE,cACLF,KAAKyE,cAAcL,EAASM,EAAGN,EAASO,EAAGN,EAAOK,EAAGL,EAAOM,EAAGH,IAE/DxE,KAAKM,WAAWsE,UAAY5E,KAAKL,QAAQX,WACzCgB,KAAKM,WAAWuE,YAAcL,EAC9BxE,KAAKM,WAAWwE,QAAU,QAC1B9E,KAAK+E,cAAcX,EAASM,EAAGN,EAASO,EAAGN,EAAOK,EAAGL,EAAOM,GAEnE,CAED,WAAAJ,GACQvE,KAAKE,cACDF,KAAKO,aAAeP,KAAKO,YAAYyE,aACrChF,KAAKK,SAAS4E,YAAYjF,KAAKO,aAC/BP,KAAKO,YAAc,MAGvBP,KAAKM,WAAW4E,UAAU,EAAG,EAAGlF,KAAKN,GAAGS,KAAKkC,KAAK5D,EAAGuB,KAAKN,GAAGS,KAAKkC,KAAKC,EAE9E,CAQD,aAAAyC,CAAcI,EAAIC,EAAIC,EAAIC,GACtBtF,KAAKM,WAAWiF,YAChBvF,KAAKM,WAAWkF,OAAOL,EAAIC,GAC3BpF,KAAKM,WAAWmF,OAAOJ,EAAIC,GAC3BtF,KAAKM,WAAWoF,QACnB,CAUD,aAAAjB,CAAcU,EAAIC,EAAIC,EAAIC,EAAId,GAE1BxE,KAAKO,YAAcP,KAAK0C,oBAAoB,QAC5C1C,KAAKO,YAAY6B,aAAa,SAAUoC,GACxCxE,KAAKO,YAAY6B,aAAa,eAAgBpC,KAAKL,QAAQX,YAC3DgB,KAAKO,YAAY6B,aAAa,OAAQ,eACtCpC,KAAKO,YAAY6B,aAAa,iBAAkB,SAGhDpC,KAAK2F,eAAe3F,KAAKO,YAAa4E,EAAIC,EAAIC,EAAIC,GAGlDtF,KAAKK,SAAS8B,YAAYnC,KAAKO,YAClC,CAWD,cAAAoF,CAAeC,EAAMT,EAAIC,EAAIC,EAAIC,GAC7BM,EAAKxD,aACD,IACA,KACI+C,EACA,IACAC,EACA,OACCD,EAAkB,GAAXE,EAAKF,GAAW,GACxB,IACAC,EACA,KACAD,EACA,IACAG,EACA,KACAD,EACA,IACAC,EAEX,CAED,UAAAtD,GACI,IAAI6D,EAAK7F,KACL8F,EAAY9F,KAAKN,GAAGS,KAAK2F,UAC7BvH,EAAEwH,GAAGD,EAAW,aAAa,SAAUE,GAClB,IAAbA,EAAEC,QACFJ,EAAGK,UAAUC,KAAKN,EAAIG,EAEtC,IACQzH,EAAEwH,GAAGD,EAAW,aAAa,SAAUE,GACf,IAAhBA,EAAEI,WAAmC,IAAhBJ,EAAEK,WACvBR,EAAGS,KAAKH,KAAKN,EAAIG,EAEjC,IACQzH,EAAEwH,GAAGD,EAAW,WAAW,SAAUE,GACjCH,EAAGU,QAAQJ,KAAKN,EAAIG,EAChC,IACQzH,EAAEwH,GAAGD,EAAW,cAAc,SAAUE,GACpCH,EAAGK,UAAUC,KAAKN,EAAIG,EAClC,IACQzH,EAAEwH,GAAGD,EAAW,aAAa,SAAUE,GACnCH,EAAGS,KAAKH,KAAKN,EAAIG,EAC7B,IACQzH,EAAEwH,GAAGD,EAAW,YAAY,SAAUE,GAClCH,EAAGU,QAAQJ,KAAKN,EAAIG,EAChC,GACK,CAKD,SAAAE,CAAUF,GACN,GAAKhG,KAAKN,GAAG8G,iBAGTxG,KAAKsB,QAAT,CAGA,IAAImF,EAAQzG,KAAKN,GAAGS,KACpB,IAAIsG,EAAMC,aAAV,CAGA1G,KAAKa,YAAc,KACnBb,KAAK2G,eAAiB3G,KAAKN,GAAG+B,qBAE9B,IAAI+B,EAAKxD,KAAK4G,kBAAkBZ,EAAEa,QAClC,GAAKrD,EAAL,CAGIxD,KAAK2G,gBACL3G,KAAKN,GAAGoH,yBAEZ,IAAIC,EAASN,EAAMO,kBAAkBxD,GACrC,GAAMuD,EAAQ,CACV,IAAIE,EAAOjH,KAAKN,GAAGwH,SAASH,GAC5B,IAAKE,EAAKE,OAAQ,CAEd,GAAIF,EAAKG,OAAgC,IAAxBH,EAAKG,KAAKC,UACvB,OAEJrH,KAAKuD,aAAaC,GAClBxD,KAAK4B,gBAAkB5B,KAAK0B,WAAW4F,wBACvCtH,KAAKa,YAAcoG,EACnBjH,KAAKkB,UACA8E,EAAEuB,SAAWvB,EAAEwB,QAAQ,GAAGD,SAAWd,EAAMgB,aAAejE,EAAGkE,WAClE1H,KAAKmB,UACA6E,EAAE2B,SAAW3B,EAAEwB,QAAQ,GAAGG,SAAWlB,EAAMgB,aAAejE,EAAGoE,UAClE5H,KAAK6H,UAAYC,KAAKC,MAAMvE,EAAGO,YAAc,GAC7C/D,KAAKgI,UAAYF,KAAKC,MAAMvE,EAAGQ,aAAe,GACpB,GAAtBhE,KAAKoB,eACL7C,EAAEE,EAAEwJ,aAAajI,KAAKoB,eAEA,GAAtBpB,KAAKqB,eACL9C,EAAEE,EAAEyJ,cAAclI,KAAKqB,eAE3B,IAAIwE,EAAK7F,KACTA,KAAKoB,cAAgB7C,EAAEE,EAAE0J,YAAW,WAChCtC,EAAGzE,cAAgB,EACnByE,EAAGxE,cAAgB9C,EAAEE,EAAE2J,aAAY,WAC/BvC,EAAGwC,mBAAmBlC,KAAKN,EACnD,GAAuBA,EAAGlG,QAAQP,gBAClC,GAAmBY,KAAKL,QAAQR,cAChB0G,EAAGvE,SAAU,CAChB,CACJ,CApCA,CAPA,CAJA,CAgDJ,CAKD,IAAAgF,CAAKN,GACD,GAAKhG,KAAKN,GAAG8G,gBAGTxG,KAAKsB,QAAS,CACd0E,EAAEsC,iBACFtI,KAAKiE,cACLjE,KAAKuB,OAAQ,EACb/C,IACA,IAAIiI,EAAQzG,KAAKN,GAAGS,KAChBoI,GAAMvC,EAAEuB,SAAWvB,EAAEwB,QAAQ,GAAGD,SAAWd,EAAMgB,aAAezH,KAAKkB,SACrEsH,GAAMxC,EAAE2B,SAAW3B,EAAEwB,QAAQ,GAAGG,SAAWlB,EAAMgB,aAAezH,KAAKmB,SAGrE6E,EAAE2B,QAAU3H,KAAK4B,gBAAgB+B,IAAM3D,KAAKL,QAAQN,yBACpDW,KAAK0B,WAAW+G,UAAYzI,KAAKL,QAAQL,uBAEzCU,KAAK0B,WAAWgH,SAAS,GAAI1I,KAAKL,QAAQL,uBAC1CU,KAAKmB,UAAYnB,KAAKL,QAAQL,sBAAwBmH,EAAMgB,cAE5DzH,KAAK4B,gBAAgB+G,OAAS3C,EAAE2B,QAAU3H,KAAKL,QAAQN,yBACvDW,KAAK0B,WAAW+G,UACZzI,KAAK0B,WAAWkH,aACZ5I,KAAK4B,gBAAgBY,OACrBxC,KAAKL,QAAQL,wBAErBU,KAAK0B,WAAWgH,SAAS,EAAG1I,KAAKL,QAAQL,uBACzCU,KAAKmB,UAAYnB,KAAKL,QAAQL,sBAAwBmH,EAAMgB,cAI5DzB,EAAEuB,QAAUvH,KAAK4B,gBAAgB8B,KAAO1D,KAAKL,QAAQN,yBACrDW,KAAK0B,WAAWmH,WAAa7I,KAAKL,QAAQL,uBAE1CU,KAAK0B,WAAWgH,UAAU1I,KAAKL,QAAQL,sBAAuB,GAC9DU,KAAKkB,UAAYlB,KAAKL,QAAQL,sBAAwBmH,EAAMgB,cAE5DzH,KAAK4B,gBAAgBkH,MAAQ9C,EAAEuB,QAAUvH,KAAKL,QAAQN,yBACtDW,KAAK0B,WAAWmH,WACZ7I,KAAK0B,WAAWqH,YACZ/I,KAAK4B,gBAAgBW,MACrBvC,KAAKL,QAAQL,wBAErBU,KAAK0B,WAAWgH,SAAS1I,KAAKL,QAAQL,sBAAuB,GAC7DU,KAAKkB,UAAYlB,KAAKL,QAAQL,sBAAwBmH,EAAMgB,cAEhEzH,KAAKQ,OAAOyC,MAAMS,KAAO6E,EAAK,KAC9BvI,KAAKQ,OAAOyC,MAAMU,IAAM6E,EAAK,KAC7BhK,GACH,CACJ,CAKD,OAAA+H,CAAQP,GACJ,GAAKhG,KAAKN,GAAG8G,eAAb,CAMA,GAHIxG,KAAK2G,gBACL3G,KAAKN,GAAGsJ,wBAERhJ,KAAKsB,QAAS,CAWd,GAV0B,GAAtBtB,KAAKoB,gBACL7C,EAAEE,EAAEwJ,aAAajI,KAAKoB,eACtBpB,KAAKoB,cAAgB,EACrBpB,KAAKuE,eAEiB,GAAtBvE,KAAKqB,gBACL9C,EAAEE,EAAEyJ,cAAclI,KAAKqB,eACvBrB,KAAKqB,cAAgB,EACrBrB,KAAKuE,eAELvE,KAAKuB,MAAO,CACZ,IAAI0H,EAAWjJ,KAAKa,YAChBC,EAAcd,KAAKc,YACnBC,EAAgBf,KAAKe,cACzBf,KAAKkJ,UAAUD,EAAUnI,EAAaC,EACzC,CACDf,KAAKkE,aACR,CACDlE,KAAK4B,gBAAkB,KACvB5B,KAAKuB,OAAQ,EACbvB,KAAKsB,SAAU,CAzBd,CA0BJ,CAMD,iBAAAsF,CAAkBpD,GACd,OACIA,IAAOxD,KAAKN,GAAGS,KAAK+B,SACpBsB,IAAOxD,KAAKN,GAAGS,KAAKwB,SACpB6B,IAAOxD,KAAKN,GAAGS,KAAK2F,UAEb,KAEsB,WAA7BtC,EAAG2F,QAAQC,cACJ5F,EAEJxD,KAAK4G,kBAAkBpD,EAAGwB,WACpC,CAED,kBAAAqD,GACI,IAAIgB,EAAKrJ,KAAKQ,OAAOkH,WACjB4B,EAAKtJ,KAAKQ,OAAOoH,UACrB,GAAIyB,IAAOrJ,KAAKS,YAAc6I,IAAOtJ,KAAKU,WACtC,OAEJV,KAAKS,WAAa4I,EAClBrJ,KAAKU,WAAa4I,EAElB,IAAIC,EACAvJ,KAAKS,WAAaT,KAAKW,SAAW,GAAKX,KAAKwJ,aACtCnL,EAAM,QAACoL,UAAUX,MACjBzK,EAAM,QAACoL,UAAU/F,KAEvB5C,EADmBd,KAAK0J,+BAA+BH,IACrBvJ,KAAK2J,kBAAkBJ,GAC7D,GAAMzI,EAAa,CACf,IAAI8I,EAAS5J,KAAK6J,mBAAmB/I,EAAayI,GAC9CjF,EAAUjG,EAAAA,QAAO4I,KAAK6C,UAAU9J,KAAKa,YAAaC,GACtDd,KAAKmE,cAAcyF,EAAOG,GAAIH,EAAOI,GAAI1F,GACzCtE,KAAKc,YAAcA,EACnBd,KAAKe,cAAgBwI,CACxB,CACJ,CAKD,UAAAC,GACI,IAAIS,EAAOjK,KAAKN,GAAGwK,WACfC,EAAgBF,EAAKG,eACrBC,EAAYJ,EAAKK,WACrB,OAAOH,EAAczF,EAAI2F,EAAU5L,EAAI,CAC1C,CAOD,8BAAAiL,CAA+BD,GAC3B,IAAIc,EAAavK,KAAKQ,OAAO8G,wBACzB5C,EAAI6F,EAAW7F,EAAK6F,EAAWhI,OAAS,EAAIkH,GAAc,EAC1De,GAAUxK,KAAKN,GAAGC,QAAQ8K,OAAOC,OAAS1K,KAAKN,GAAGC,QAAQ8K,OAAOE,QAAUlB,EAC3EmB,EAASL,EAAW/H,OACpBoH,EAAS,CACT,CAAClF,EAAG6F,EAAW5F,GACf,CAACD,EAAG6F,EAAW5F,EAAIiG,EAAS,GAC5B,CAAClG,EAAG6F,EAAW5F,EAAIiG,GACnB,CAAClG,EAAI8F,EAAS,EAAGD,EAAW5F,GAC5B,CAACD,EAAI8F,EAAS,EAAGD,EAAW5F,EAAIiG,EAAS,GACzC,CAAClG,EAAI8F,EAAS,EAAGD,EAAW5F,EAAIiG,GAChC,CAAClG,EAAI8F,EAAQD,EAAW5F,GACxB,CAACD,EAAI8F,EAAQD,EAAW5F,EAAIiG,EAAS,GACrC,CAAClG,EAAI8F,EAAQD,EAAW5F,EAAIiG,IAEhC,IAAK,MAAMC,KAAKjB,EAAQ,CACpB,IAAIkB,EAAI9K,KAAK+K,+BAA+BF,EAAE,GAAIA,EAAE,IACpD,GAAMC,EACF,OAAOA,CAEd,CACJ,CAQD,8BAAAC,CAA+BrG,EAAGC,GAC9B,OAAOpG,EAAEK,EACJoM,kBAAkBtG,EAAGC,GACrBsG,QACGvG,GAAmB,WAAdA,EAAEyE,SAAwBzE,EAAEpB,YAActD,KAAKL,QAAQJ,yBAE/D2L,KAAI1H,GAAMxD,KAAKN,GAAGS,KAAK6G,kBAAkBxD,KACzC0H,KAAIC,GAAMA,GAAMnL,KAAKN,GAAG0L,KAAKC,MAAMF,KACnCD,KAAIJ,GAAKA,GAAKA,EAAEQ,SAChBC,MAAKT,GAAKA,GAClB,CAOD,iBAAAnB,CAAkBF,GACd,OAAO+B,OAAOC,OAAOzL,KAAKN,GAAG0L,KAAKC,OAC7BJ,QAAOH,GAAKA,EAAErB,WAAaA,GAAaqB,EAAE3D,SAC1C8D,QAAOH,GAAK9K,KAAKN,GAAG+K,OAAOiB,WAAWZ,KACtCG,QAAOH,GAAK9K,KAAK2L,sBAAsBb,EAAGrB,KAC1CyB,KAAIJ,IAAC,CAAO7D,KAAM6D,EAAGc,SAAU5L,KAAK6L,eAAef,EAAGrB,OACtDqC,QACG,CAACC,EAAMC,IACID,EAAKH,SAAWI,EAAKJ,SAAWG,EAAOC,GAElD,CAAE/E,KAAMjH,KAAKN,GAAGwK,WAAY0B,SAAUK,OAAOC,YAC/CjF,IACT,CAQD,qBAAA0E,CAAsB1E,EAAMkF,GACxB,OACKA,GAAO9N,EAAM,QAACoL,UAAUX,OAAS9I,KAAKoM,wBAAwBnF,GAAQ,GACtEkF,GAAO9N,EAAAA,QAAOoL,UAAU/F,MAAQ1D,KAAKqM,uBAAuBpF,GAAQ,CAE5E,CAOD,uBAAAmF,CAAwBnF,GACpB,OAAOjH,KAAKS,WAAawG,EAAKmD,eAAe1F,EAAIuC,EAAKqD,WAAW7L,CACpE,CAOD,sBAAA4N,CAAuBpF,GACnB,OAAOA,EAAKmD,eAAe1F,EAAI1E,KAAKS,WAAaT,KAAKW,QACzD,CAOD,2BAAA2L,CAA4BrF,GACxB,OAAOjH,KAAKU,WAAaV,KAAKY,SAAW,EAAIqG,EAAKmD,eAAezF,EAAIsC,EAAKqD,WAAWhI,EAAI,CAC5F,CAQD,cAAAuJ,CAAe5E,EAAMkF,GAMjB,OAJIA,IAAQ9N,EAAAA,QAAOoL,UAAUX,MACnBhB,KAAKyE,IAAIvM,KAAKoM,wBAAwBnF,IACtCa,KAAKyE,IAAIvM,KAAKqM,uBAAuBpF,KAC9Ba,KAAKyE,IAAIvM,KAAKsM,4BAA4BrF,GAE9D,CAQD,kBAAA4C,CAAmB5C,EAAMkF,GACrB,IAAIK,EAAKvF,EAAKqD,WACVmC,EAAKxF,EAAKmD,eACVsC,EAASzF,EAAKE,OACZsF,EAAG/H,EAAI8H,EAAG/N,EAAI,EACdgO,EAAG/H,EAAK8H,EAAG/N,GAAK,EAAI0N,GAAQ,EAAInM,KAAKL,QAAQX,WAAamN,EAC5DQ,EAASF,EAAG9H,EAAI6H,EAAGlK,EAAI,EAI3B,MAAO,CACHyH,GAAI,CAAErF,EAHN1E,KAAKS,WAAcT,KAAKW,UAAY,EAAIwL,GAAQ,EAAInM,KAAKL,QAAQX,WAAamN,EAG3DxH,EAFR3E,KAAKU,WAAaV,KAAKY,SAAW,GAG7CoJ,GAAI,CAAEtF,EAAGgI,EAAQ/H,EAAGgI,GAE3B,CAQD,SAAAzD,CAAUD,EAAUnI,EAAaC,GAC7B,IAAIH,EAAWZ,KAAKQ,OAAOoH,UAC3B,GAAM9G,GAAiBmI,IAAa5K,UAAO4I,KAAK6C,UAAUb,EAAUnI,GAAc,CAE9E,GAAId,KAAKL,QAAQiN,eAAuD,mBAA/B5M,KAAKL,QAAQiN,cAA8B,CAEhF,IADgB5M,KAAKL,QAAQiN,cAAc3D,EAAUnI,GAMjD,OAHAd,KAAKa,YAAc,KACnBb,KAAKc,YAAc,UACnBd,KAAKe,cAAgB,KAG5B,CASD,IANA,IAAI8L,EAAgB/L,EAAYgM,SAC5BC,EAAKF,EAAcG,OACnB/F,EAAO,KACPgG,EAAUhB,OAAOC,UACjBgB,EAAc,KACdC,EAAW,SACRJ,KAEH,IADA9F,EAAO4F,EAAcE,IACZtD,WAAa1I,GAAiBkG,EAAKkE,IAAMlC,EAASkC,GAAI,CAC3D,IAAIiC,EAAKnG,EAAKmD,eAAezF,EAAI/D,EAC7BwM,EAAK,GAAKA,EAAKH,IACfA,EAAUG,EACVF,EAAcjG,EACdkG,EAAW,UAElB,CAECD,IACFC,EAAWD,EAAY/B,IAE3BnL,KAAKN,GAAGwJ,UAAUD,EAASkC,GAAIgC,EAAUrM,EAAYqK,GAAIpK,EAC5D,CACDf,KAAKa,YAAc,KACnBb,KAAKc,YAAc,KACnBd,KAAKe,cAAgB,IACxB,CAMD,eAAAsM,CAAgBC,EAAMlG,GACdkG,IAASjP,EAAAA,QAAOkP,WAAWtL,QAC3BjC,KAAKiC,QAEZ,EAOO,MAACuL,EAAmB,IAAInP,EAAAA,QAAOoP,OAAO,kBAAkB,SAAU/N,EAAIC,GAC9E,IAAIkG,EAAK,IAAIrG,EAAcE,EAAIC,GAC/BkG,EAAGhE,OACHnC,EAAGgO,oBAAmB,SAAUJ,EAAMlG,GAClCvB,EAAGwH,gBAAgBlH,KAAKN,EAAIyH,EAAMlG,EAC1C,GACA,IAEA/I,EAAAA,QAAOsP,gBAAgBH"}