camunda-bpmn-js 0.24.0 → 1.0.0
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.
- package/dist/assets/color-picker.css +10 -0
- package/dist/assets/diagram-js.css +26 -24
- package/dist/base-modeler.development.js +144 -48
- package/dist/base-modeler.production.min.js +39 -25
- package/dist/base-navigated-viewer.development.js +3 -0
- package/dist/base-navigated-viewer.production.min.js +1 -1
- package/dist/base-viewer.development.js +3 -0
- package/dist/base-viewer.production.min.js +1 -1
- package/dist/camunda-cloud-modeler.development.js +480 -144
- package/dist/camunda-cloud-modeler.production.min.js +50 -36
- package/dist/camunda-cloud-navigated-viewer.development.js +3 -0
- package/dist/camunda-cloud-navigated-viewer.production.min.js +1 -1
- package/dist/camunda-cloud-viewer.development.js +3 -0
- package/dist/camunda-cloud-viewer.production.min.js +1 -1
- package/dist/camunda-platform-modeler.development.js +534 -49
- package/dist/camunda-platform-modeler.production.min.js +41 -27
- package/dist/camunda-platform-navigated-viewer.development.js +3 -0
- package/dist/camunda-platform-navigated-viewer.production.min.js +1 -1
- package/dist/camunda-platform-viewer.development.js +3 -0
- package/dist/camunda-platform-viewer.production.min.js +1 -1
- package/lib/camunda-cloud/Modeler.js +5 -1
- package/lib/camunda-cloud/features/replace/ElementTemplatesReplaceProvider.js +4 -135
- package/lib/camunda-platform/Modeler.js +6 -1
- package/lib/shared/features/replace/UnlinkTemplateReplaceProvider.js +178 -0
- package/lib/shared/features/replace/index.js +8 -0
- package/lib/{camunda-cloud/features/replace → shared/features/replace/util}/ReplaceOptionsUtil.js +0 -0
- package/package.json +8 -6
|
@@ -13,6 +13,8 @@ import {
|
|
|
13
13
|
} from 'bpmn-js-properties-panel';
|
|
14
14
|
|
|
15
15
|
import replaceModule from './features/replace';
|
|
16
|
+
import sharedReplaceModule from '../shared/features/replace';
|
|
17
|
+
import colorPickerModule from 'bpmn-js-color-picker';
|
|
16
18
|
|
|
17
19
|
import { commonModdleExtensions, commonModules } from './util/commonModules';
|
|
18
20
|
|
|
@@ -46,7 +48,9 @@ Modeler.prototype._camundaCloudModules = [
|
|
|
46
48
|
rulesModule,
|
|
47
49
|
zeebePropertiesProviderModule,
|
|
48
50
|
cloudElementTemplatesPropertiesProvider,
|
|
49
|
-
replaceModule
|
|
51
|
+
replaceModule,
|
|
52
|
+
sharedReplaceModule,
|
|
53
|
+
colorPickerModule
|
|
50
54
|
];
|
|
51
55
|
|
|
52
56
|
Modeler.prototype._modules = [].concat(
|
|
@@ -1,35 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
isDifferentType
|
|
3
|
-
} from 'bpmn-js/lib/features/popup-menu/util/TypeUtil';
|
|
4
|
-
|
|
5
1
|
import {
|
|
6
2
|
getBusinessObject,
|
|
7
3
|
isAny
|
|
8
4
|
} from 'bpmn-js/lib/util/ModelUtil';
|
|
9
5
|
|
|
10
|
-
import {
|
|
11
|
-
getReplaceOptionGroups
|
|
12
|
-
} from './ReplaceOptionsUtil';
|
|
13
6
|
|
|
14
7
|
/**
|
|
15
8
|
* A replace menu provider that allows to replace elements with
|
|
16
9
|
* element templates.
|
|
17
10
|
*/
|
|
18
|
-
export default function ElementTemplatesReplaceProvider(
|
|
11
|
+
export default function ElementTemplatesReplaceProvider(popupMenu, translate, elementTemplates) {
|
|
19
12
|
|
|
20
13
|
this._popupMenu = popupMenu;
|
|
21
14
|
this._translate = translate;
|
|
22
15
|
this._elementTemplates = elementTemplates;
|
|
23
16
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (enabled) {
|
|
27
|
-
this.register();
|
|
28
|
-
}
|
|
17
|
+
this.register();
|
|
29
18
|
}
|
|
30
19
|
|
|
31
20
|
ElementTemplatesReplaceProvider.$inject = [
|
|
32
|
-
'config.elementTemplatesReplaceProvider',
|
|
33
21
|
'popupMenu',
|
|
34
22
|
'translate',
|
|
35
23
|
'elementTemplates'
|
|
@@ -55,9 +43,6 @@ ElementTemplatesReplaceProvider.prototype.getPopupMenuEntries = function(element
|
|
|
55
43
|
// convert our entries into something sortable
|
|
56
44
|
let entrySet = Object.entries(entries);
|
|
57
45
|
|
|
58
|
-
// add unlink template option
|
|
59
|
-
this._addPlainElementEntry(element, entrySet);
|
|
60
|
-
|
|
61
46
|
// add template entries
|
|
62
47
|
entrySet = [ ...entrySet, ...this.getTemplateEntries(element) ];
|
|
63
48
|
|
|
@@ -70,81 +55,6 @@ ElementTemplatesReplaceProvider.prototype.getPopupMenuEntries = function(element
|
|
|
70
55
|
};
|
|
71
56
|
};
|
|
72
57
|
|
|
73
|
-
/**
|
|
74
|
-
* Adds the option to replace with plain element (unlink template).
|
|
75
|
-
*
|
|
76
|
-
* @param {djs.model.Base} element
|
|
77
|
-
* @param {Array<Object>} entries
|
|
78
|
-
*/
|
|
79
|
-
ElementTemplatesReplaceProvider.prototype._addPlainElementEntry = function(element, entries) {
|
|
80
|
-
|
|
81
|
-
const replaceOption = this._getPlainEntry(element, entries);
|
|
82
|
-
|
|
83
|
-
const [
|
|
84
|
-
insertIndex,
|
|
85
|
-
entry
|
|
86
|
-
] = replaceOption;
|
|
87
|
-
|
|
88
|
-
// insert unlink entry
|
|
89
|
-
entries.splice(insertIndex, 0, [ entry.id, entry ]);
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Returns the option to replace with plain element and the index where it should be inserted.
|
|
94
|
-
*
|
|
95
|
-
* @param {djs.model.Base} element
|
|
96
|
-
* @param {Array<Object>} entries
|
|
97
|
-
*
|
|
98
|
-
* @returns {Array<Object, number>}
|
|
99
|
-
*/
|
|
100
|
-
ElementTemplatesReplaceProvider.prototype._getPlainEntry = function(element, entries) {
|
|
101
|
-
|
|
102
|
-
const {
|
|
103
|
-
options,
|
|
104
|
-
option,
|
|
105
|
-
optionIndex
|
|
106
|
-
} = findReplaceOptions(element) || { };
|
|
107
|
-
|
|
108
|
-
if (!options) {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const entry = {
|
|
113
|
-
id: option.actionName,
|
|
114
|
-
action: () => {
|
|
115
|
-
this._elementTemplates.applyTemplate(element, null);
|
|
116
|
-
},
|
|
117
|
-
label: this._translate(option.label),
|
|
118
|
-
className: option.className
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
// insert after previous option, if it exists
|
|
122
|
-
const previousIndex = getOptionIndex(options, optionIndex - 1, entries);
|
|
123
|
-
|
|
124
|
-
if (previousIndex) {
|
|
125
|
-
return [
|
|
126
|
-
previousIndex + 1,
|
|
127
|
-
entry
|
|
128
|
-
];
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// insert before next option, if it exists
|
|
132
|
-
const nextIndex = getOptionIndex(options, optionIndex + 1, entries);
|
|
133
|
-
|
|
134
|
-
if (nextIndex) {
|
|
135
|
-
return [
|
|
136
|
-
nextIndex,
|
|
137
|
-
entry
|
|
138
|
-
];
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// fallback to insert at start
|
|
142
|
-
return [
|
|
143
|
-
0,
|
|
144
|
-
entry
|
|
145
|
-
];
|
|
146
|
-
};
|
|
147
|
-
|
|
148
58
|
/**
|
|
149
59
|
* Get all element templates that can be used to replace the given element.
|
|
150
60
|
*
|
|
@@ -162,7 +72,7 @@ ElementTemplatesReplaceProvider.prototype.getTemplateEntries = function(element)
|
|
|
162
72
|
category,
|
|
163
73
|
} = template;
|
|
164
74
|
|
|
165
|
-
const entryId = `replace
|
|
75
|
+
const entryId = `replace.template-${template.id}`;
|
|
166
76
|
|
|
167
77
|
const defaultGroup = {
|
|
168
78
|
id: 'templates',
|
|
@@ -170,7 +80,7 @@ ElementTemplatesReplaceProvider.prototype.getTemplateEntries = function(element)
|
|
|
170
80
|
};
|
|
171
81
|
|
|
172
82
|
return [ entryId, {
|
|
173
|
-
|
|
83
|
+
label: template.name,
|
|
174
84
|
description: template.description,
|
|
175
85
|
documentationRef: template.documentationRef,
|
|
176
86
|
imageUrl: icon.contents,
|
|
@@ -205,45 +115,4 @@ export function isTemplateApplied(element, template) {
|
|
|
205
115
|
}
|
|
206
116
|
|
|
207
117
|
return false;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
function getOptionIndex(options, index, entries) {
|
|
211
|
-
const option = options[index];
|
|
212
|
-
|
|
213
|
-
if (!option) {
|
|
214
|
-
return false;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
return entries.findIndex(
|
|
218
|
-
([ key ]) => key === option.actionName
|
|
219
|
-
);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* @param {ModdleElement} element
|
|
224
|
-
*
|
|
225
|
-
* @return { { options: Array<any>, option: any, optionIndex: number } | null }
|
|
226
|
-
*/
|
|
227
|
-
function findReplaceOptions(element) {
|
|
228
|
-
|
|
229
|
-
const isSameType = (element, option) => option.target && !isDifferentType(element)(option);
|
|
230
|
-
|
|
231
|
-
return getReplaceOptionGroups().reduce((result, options) => {
|
|
232
|
-
|
|
233
|
-
if (result) {
|
|
234
|
-
return result;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
const optionIndex = options.findIndex(option => isSameType(element, option));
|
|
238
|
-
|
|
239
|
-
if (optionIndex === -1) {
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
return {
|
|
244
|
-
options,
|
|
245
|
-
option: options[optionIndex],
|
|
246
|
-
optionIndex
|
|
247
|
-
};
|
|
248
|
-
}, null);
|
|
249
118
|
}
|
|
@@ -11,6 +11,9 @@ import {
|
|
|
11
11
|
|
|
12
12
|
import { commonModdleExtensions } from './util/commonModules';
|
|
13
13
|
|
|
14
|
+
import sharedReplaceModule from '../shared/features/replace';
|
|
15
|
+
import colorPickerModule from 'bpmn-js-color-picker';
|
|
16
|
+
|
|
14
17
|
|
|
15
18
|
/**
|
|
16
19
|
*
|
|
@@ -34,7 +37,9 @@ inherits(Modeler, BaseModeler);
|
|
|
34
37
|
Modeler.prototype._camundaPlatformModules = [
|
|
35
38
|
behaviorsModule,
|
|
36
39
|
CamundaPlatformPropertiesProviderModule,
|
|
37
|
-
ElementTemplatesPropertiesProviderModule
|
|
40
|
+
ElementTemplatesPropertiesProviderModule,
|
|
41
|
+
sharedReplaceModule,
|
|
42
|
+
colorPickerModule
|
|
38
43
|
];
|
|
39
44
|
|
|
40
45
|
Modeler.prototype._modules = [].concat(
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { isDifferentType } from 'bpmn-js/lib/features/popup-menu/util/TypeUtil';
|
|
2
|
+
import { getReplaceOptionGroups } from './util/ReplaceOptionsUtil';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A replace menu provider that allows to replace elements with
|
|
6
|
+
* templates applied with the correspondent plain element.
|
|
7
|
+
*/
|
|
8
|
+
export default function UnlinkTemplateReplaceProvider(popupMenu, translate, elementTemplates) {
|
|
9
|
+
|
|
10
|
+
this._popupMenu = popupMenu;
|
|
11
|
+
this._translate = translate;
|
|
12
|
+
this._elementTemplates = elementTemplates;
|
|
13
|
+
|
|
14
|
+
this.register();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
UnlinkTemplateReplaceProvider.$inject = [
|
|
18
|
+
'popupMenu',
|
|
19
|
+
'translate',
|
|
20
|
+
'elementTemplates'
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Register replace menu provider in the popup menu
|
|
25
|
+
*/
|
|
26
|
+
UnlinkTemplateReplaceProvider.prototype.register = function() {
|
|
27
|
+
this._popupMenu.registerProvider('bpmn-replace', this);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Adds the element templates to the replace menu.
|
|
32
|
+
* @param {djs.model.Base} element
|
|
33
|
+
*
|
|
34
|
+
* @returns {Object}
|
|
35
|
+
*/
|
|
36
|
+
UnlinkTemplateReplaceProvider.prototype.getPopupMenuEntries = function(element) {
|
|
37
|
+
|
|
38
|
+
return (entries) => {
|
|
39
|
+
|
|
40
|
+
// convert our entries into something sortable
|
|
41
|
+
let entrySet = Object.entries(entries);
|
|
42
|
+
|
|
43
|
+
if (this._elementTemplates.get(element)) {
|
|
44
|
+
|
|
45
|
+
// add unlink template option
|
|
46
|
+
this.addPlainElementEntry(element, entrySet, this._translate, this._elementTemplates);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// convert back to object
|
|
50
|
+
return entrySet.reduce((entries, [ key, value ]) => {
|
|
51
|
+
entries[key] = value;
|
|
52
|
+
|
|
53
|
+
return entries;
|
|
54
|
+
}, {});
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Adds the option to replace with plain element (unlink template).
|
|
61
|
+
*
|
|
62
|
+
* @param {djs.model.Base} element
|
|
63
|
+
* @param {Array<Object>} entries
|
|
64
|
+
*/
|
|
65
|
+
UnlinkTemplateReplaceProvider.prototype.addPlainElementEntry = function(element, entries, translate, elementTemplates) {
|
|
66
|
+
|
|
67
|
+
const replaceOption = this.getPlainEntry(element, entries, translate, elementTemplates);
|
|
68
|
+
|
|
69
|
+
if (!replaceOption) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const [
|
|
74
|
+
insertIndex,
|
|
75
|
+
entry
|
|
76
|
+
] = replaceOption;
|
|
77
|
+
|
|
78
|
+
// insert unlink entry
|
|
79
|
+
entries.splice(insertIndex, 0, [ entry.id, entry ]);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Returns the option to replace with plain element and the index where it should be inserted.
|
|
84
|
+
*
|
|
85
|
+
* @param {djs.model.Base} element
|
|
86
|
+
* @param {Array<Object>} entries
|
|
87
|
+
*
|
|
88
|
+
* @returns {Array<Object, number>}
|
|
89
|
+
*/
|
|
90
|
+
UnlinkTemplateReplaceProvider.prototype.getPlainEntry = function(element, entries, translate, elementTemplates) {
|
|
91
|
+
|
|
92
|
+
const {
|
|
93
|
+
options,
|
|
94
|
+
option,
|
|
95
|
+
optionIndex
|
|
96
|
+
} = findReplaceOptions(element) || { };
|
|
97
|
+
|
|
98
|
+
if (!options) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const entry = {
|
|
103
|
+
id: 'replace-unlink-element-template',
|
|
104
|
+
action: () => {
|
|
105
|
+
elementTemplates.applyTemplate(element, null);
|
|
106
|
+
},
|
|
107
|
+
label: translate(option.label),
|
|
108
|
+
className: option.className
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
// insert after previous option, if it exists
|
|
112
|
+
const previousIndex = getOptionIndex(options, optionIndex - 1, entries);
|
|
113
|
+
|
|
114
|
+
if (previousIndex) {
|
|
115
|
+
return [
|
|
116
|
+
previousIndex + 1,
|
|
117
|
+
entry
|
|
118
|
+
];
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// insert before next option, if it exists
|
|
122
|
+
const nextIndex = getOptionIndex(options, optionIndex + 1, entries);
|
|
123
|
+
|
|
124
|
+
if (nextIndex) {
|
|
125
|
+
return [
|
|
126
|
+
nextIndex,
|
|
127
|
+
entry
|
|
128
|
+
];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// fallback to insert at start
|
|
132
|
+
return [
|
|
133
|
+
0,
|
|
134
|
+
entry
|
|
135
|
+
];
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* @param {ModdleElement} element
|
|
141
|
+
*
|
|
142
|
+
* @return { { options: Array<any>, option: any, optionIndex: number } | null }
|
|
143
|
+
*/
|
|
144
|
+
function findReplaceOptions(element) {
|
|
145
|
+
|
|
146
|
+
const isSameType = (element, option) => option.target && !isDifferentType(element)(option);
|
|
147
|
+
|
|
148
|
+
return getReplaceOptionGroups().reduce((result, options) => {
|
|
149
|
+
|
|
150
|
+
if (result) {
|
|
151
|
+
return result;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const optionIndex = options.findIndex(option => isSameType(element, option));
|
|
155
|
+
|
|
156
|
+
if (optionIndex === -1) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
options,
|
|
162
|
+
option: options[optionIndex],
|
|
163
|
+
optionIndex
|
|
164
|
+
};
|
|
165
|
+
}, null);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function getOptionIndex(options, index, entries) {
|
|
169
|
+
const option = options[index];
|
|
170
|
+
|
|
171
|
+
if (!option) {
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return entries.findIndex(
|
|
176
|
+
([ key ]) => key === option.actionName
|
|
177
|
+
);
|
|
178
|
+
}
|
package/lib/{camunda-cloud/features/replace → shared/features/replace/util}/ReplaceOptionsUtil.js
RENAMED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "camunda-bpmn-js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Embeddable Camunda modeling distributions based on bpmn-js",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"start:cloud-viewer": "cross-env SINGLE_START=camunda-cloud-viewer npm run dev",
|
|
19
19
|
"start:platform-navigated-viewer": "cross-env SINGLE_START=camunda-platform-navigated-viewer npm run dev",
|
|
20
20
|
"start:cloud-navigated-viewer": "cross-env SINGLE_START=camunda-cloud-navigated-viewer npm run dev",
|
|
21
|
+
"start:cloud-connectors-extension": "cross-env SINGLE_START=camunda-cloud-connectors-extension npm run dev",
|
|
21
22
|
"prepublishOnly": "run-s test:distro",
|
|
22
23
|
"prepare": "run-s clean distro"
|
|
23
24
|
},
|
|
@@ -47,11 +48,12 @@
|
|
|
47
48
|
"dependencies": {
|
|
48
49
|
"@bpmn-io/align-to-origin": "^0.7.0",
|
|
49
50
|
"@bpmn-io/element-templates-icons-renderer": "^0.3.0",
|
|
50
|
-
"bpmn-js": "^11.0
|
|
51
|
+
"bpmn-js": "^11.1.0",
|
|
52
|
+
"bpmn-js-color-picker": "^0.5.0",
|
|
51
53
|
"bpmn-js-executable-fix": "^0.2.0",
|
|
52
54
|
"camunda-bpmn-js-behaviors": "^0.4.0",
|
|
53
55
|
"camunda-bpmn-moddle": "^7.0.1",
|
|
54
|
-
"diagram-js": "^11.
|
|
56
|
+
"diagram-js": "^11.4.1",
|
|
55
57
|
"diagram-js-minimap": "^3.0.0",
|
|
56
58
|
"diagram-js-origin": "^1.4.0",
|
|
57
59
|
"inherits": "^2.0.4",
|
|
@@ -60,14 +62,14 @@
|
|
|
60
62
|
},
|
|
61
63
|
"devDependencies": {
|
|
62
64
|
"@babel/core": "^7.18.13",
|
|
63
|
-
"@bpmn-io/element-template-chooser": "^
|
|
65
|
+
"@bpmn-io/element-template-chooser": "^1.0.0",
|
|
64
66
|
"@bpmn-io/properties-panel": "^1.0.1",
|
|
65
67
|
"@rollup/plugin-commonjs": "^23.0.0",
|
|
66
68
|
"@rollup/plugin-json": "^4.1.0",
|
|
67
69
|
"@rollup/plugin-node-resolve": "^14.0.0",
|
|
68
70
|
"babel-loader": "^9.0.0",
|
|
69
71
|
"babel-plugin-istanbul": "^6.1.1",
|
|
70
|
-
"bpmn-js-connectors-extension": "^0.4.
|
|
72
|
+
"bpmn-js-connectors-extension": "^0.4.5",
|
|
71
73
|
"bpmn-js-properties-panel": "^1.12.0",
|
|
72
74
|
"chai": "^4.3.7",
|
|
73
75
|
"cross-env": "^7.0.3",
|
|
@@ -92,7 +94,7 @@
|
|
|
92
94
|
"mocha": "^10.1.0",
|
|
93
95
|
"mocha-test-container-support": "^0.2.0",
|
|
94
96
|
"npm-run-all": "^4.1.5",
|
|
95
|
-
"puppeteer": "^19.
|
|
97
|
+
"puppeteer": "^19.4.0",
|
|
96
98
|
"raw-loader": "^4.0.2",
|
|
97
99
|
"rollup": "^2.38.4",
|
|
98
100
|
"rollup-plugin-copy": "^3.3.0",
|