camunda-bpmn-js 0.13.0-alpha.8 → 0.13.1

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 (66) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/assets/base-navigated-viewer.css +2 -0
  3. package/dist/assets/base-viewer.css +2 -0
  4. package/dist/assets/camunda-cloud-navigated-viewer.css +1 -0
  5. package/dist/assets/camunda-cloud-viewer.css +1 -0
  6. package/dist/assets/camunda-platform-navigated-viewer.css +1 -0
  7. package/dist/assets/camunda-platform-viewer.css +1 -0
  8. package/dist/assets/properties-panel.css +900 -901
  9. package/dist/base-navigated-viewer.development.js +22218 -0
  10. package/dist/base-navigated-viewer.production.min.js +2 -0
  11. package/dist/base-viewer.development.js +21227 -0
  12. package/dist/base-viewer.production.min.js +2 -0
  13. package/dist/camunda-cloud-modeler.development.js +1249 -944
  14. package/dist/camunda-cloud-modeler.production.min.js +4 -4
  15. package/dist/camunda-cloud-navigated-viewer.development.js +23041 -0
  16. package/dist/camunda-cloud-navigated-viewer.production.min.js +2 -0
  17. package/dist/camunda-cloud-viewer.development.js +22050 -0
  18. package/dist/camunda-cloud-viewer.production.min.js +2 -0
  19. package/dist/camunda-platform-modeler.development.js +1464 -1381
  20. package/dist/camunda-platform-modeler.production.min.js +4 -4
  21. package/dist/camunda-platform-navigated-viewer.development.js +23413 -0
  22. package/dist/camunda-platform-navigated-viewer.production.min.js +2 -0
  23. package/dist/camunda-platform-viewer.development.js +22422 -0
  24. package/dist/camunda-platform-viewer.production.min.js +2 -0
  25. package/lib/base/NavigatedViewer.js +3 -0
  26. package/lib/base/Viewer.js +3 -0
  27. package/lib/camunda-cloud/Modeler.js +7 -11
  28. package/lib/camunda-cloud/NavigatedViewer.js +34 -0
  29. package/lib/camunda-cloud/Viewer.js +34 -0
  30. package/lib/camunda-cloud/util/commonModules.js +14 -0
  31. package/lib/camunda-platform/Modeler.js +5 -5
  32. package/lib/camunda-platform/NavigatedViewer.js +25 -0
  33. package/lib/camunda-platform/Viewer.js +24 -0
  34. package/lib/camunda-platform/util/commonModules.js +7 -0
  35. package/package.json +9 -4
  36. package/styles/base-navigated-viewer.css +2 -0
  37. package/styles/base-viewer.css +2 -0
  38. package/styles/camunda-cloud-navigated-viewer.css +1 -0
  39. package/styles/camunda-cloud-viewer.css +1 -0
  40. package/styles/camunda-platform-navigated-viewer.css +1 -0
  41. package/styles/camunda-platform-viewer.css +1 -0
  42. package/util/index.js +39 -0
  43. package/lib/camunda-cloud/features/modeling/behavior/CleanUpBusinessRuleTaskBehavior.js +0 -115
  44. package/lib/camunda-cloud/features/modeling/behavior/CreateZeebeBoundaryEventBehavior.js +0 -76
  45. package/lib/camunda-cloud/features/modeling/behavior/CreateZeebeCallActivityBehavior.js +0 -86
  46. package/lib/camunda-cloud/features/modeling/behavior/FormDefinitionBehavior.js +0 -138
  47. package/lib/camunda-cloud/features/modeling/behavior/RemoveAssignmentDefinitionBehavior.js +0 -51
  48. package/lib/camunda-cloud/features/modeling/behavior/UpdatePropagateAllChildVariablesBehavior.js +0 -136
  49. package/lib/camunda-cloud/features/modeling/behavior/index.js +0 -24
  50. package/lib/camunda-cloud/features/modeling/index.js +0 -7
  51. package/lib/camunda-cloud/helper/CalledElementHelper.js +0 -72
  52. package/lib/camunda-cloud/helper/ElementHelper.js +0 -18
  53. package/lib/camunda-cloud/helper/FormsHelper.js +0 -84
  54. package/lib/camunda-cloud/helper/InputOutputHelper.js +0 -138
  55. package/lib/camunda-cloud/helper/Utils.js +0 -10
  56. package/lib/camunda-cloud/helper/ZeebeServiceTaskHelper.js +0 -41
  57. package/lib/camunda-platform/features/modeling/behavior/DeleteErrorEventDefinitionBehavior.js +0 -54
  58. package/lib/camunda-platform/features/modeling/behavior/DeleteRetryTimeCycleBehavior.js +0 -96
  59. package/lib/camunda-platform/features/modeling/behavior/UpdateCamundaExclusiveBehavior.js +0 -68
  60. package/lib/camunda-platform/features/modeling/behavior/UpdateInputOutputBehavior.js +0 -44
  61. package/lib/camunda-platform/features/modeling/behavior/UpdateResultVariableBehavior.js +0 -54
  62. package/lib/camunda-platform/features/modeling/behavior/UserTaskFormsBehavior.js +0 -71
  63. package/lib/camunda-platform/features/modeling/behavior/UserTaskGeneratedFormsBehavior.js +0 -116
  64. package/lib/camunda-platform/features/modeling/behavior/index.js +0 -26
  65. package/lib/camunda-platform/features/modeling/index.js +0 -7
  66. package/lib/camunda-platform/helper/InputOutputHelper.js +0 -29
@@ -0,0 +1,34 @@
1
+ import inherits from 'inherits';
2
+
3
+ import BaseViewer from '../base/NavigatedViewer';
4
+
5
+ import { commonModdleExtensions, commonModules } from './util/commonModules';
6
+
7
+
8
+ /**
9
+ *
10
+ * @param {Object} options
11
+ */
12
+ export default function NavigatedViewer(options = {}) {
13
+
14
+ options = {
15
+ ...options,
16
+ moddleExtensions: {
17
+ ...commonModdleExtensions,
18
+ ...options.moddleExtensions
19
+ }
20
+ };
21
+
22
+ BaseViewer.call(this, options);
23
+ }
24
+
25
+ inherits(NavigatedViewer, BaseViewer);
26
+
27
+ NavigatedViewer.prototype._camundaCloudModules = [
28
+ ...commonModules
29
+ ];
30
+
31
+ NavigatedViewer.prototype._modules = [].concat(
32
+ BaseViewer.prototype._modules,
33
+ NavigatedViewer.prototype._camundaCloudModules
34
+ );
@@ -0,0 +1,34 @@
1
+ import inherits from 'inherits';
2
+
3
+ import BaseViewer from '../base/Viewer';
4
+
5
+ import { commonModdleExtensions, commonModules } from './util/commonModules';
6
+
7
+
8
+ /**
9
+ *
10
+ * @param {Object} options
11
+ */
12
+ export default function Viewer(options = {}) {
13
+
14
+ options = {
15
+ ...options,
16
+ moddleExtensions: {
17
+ ...commonModdleExtensions,
18
+ ...options.moddleExtensions
19
+ }
20
+ };
21
+
22
+ BaseViewer.call(this, options);
23
+ }
24
+
25
+ inherits(Viewer, BaseViewer);
26
+
27
+ Viewer.prototype._camundaCloudModules = [
28
+ ...commonModules
29
+ ];
30
+
31
+ Viewer.prototype._modules = [].concat(
32
+ BaseViewer.prototype._modules,
33
+ Viewer.prototype._camundaCloudModules
34
+ );
@@ -0,0 +1,14 @@
1
+ import iconRendererModule from '@bpmn-io/element-templates-icons-renderer';
2
+
3
+ import drilldownModule from '../features/drilldown';
4
+
5
+ import zeebeModdle from 'zeebe-bpmn-moddle/resources/zeebe.json';
6
+
7
+ export const commonModules = [
8
+ drilldownModule,
9
+ iconRendererModule
10
+ ];
11
+
12
+ export const commonModdleExtensions = {
13
+ zeebe: zeebeModdle
14
+ };
@@ -2,9 +2,7 @@ import inherits from 'inherits';
2
2
 
3
3
  import BaseModeler from '../base/Modeler';
4
4
 
5
- import modelingModule from './features/modeling';
6
-
7
- import camundaModdle from 'camunda-bpmn-moddle/resources/camunda.json';
5
+ import behaviorsModule from 'camunda-bpmn-js-behaviors/lib/camunda-platform';
8
6
 
9
7
  import camundaModdleExtension from 'camunda-bpmn-moddle/lib';
10
8
 
@@ -13,6 +11,8 @@ import {
13
11
  ElementTemplatesPropertiesProviderModule
14
12
  } from 'bpmn-js-properties-panel';
15
13
 
14
+ import { commonModdleExtensions } from './util/commonModules';
15
+
16
16
 
17
17
  /**
18
18
  *
@@ -23,7 +23,7 @@ export default function Modeler(options = {}) {
23
23
  options = {
24
24
  ...options,
25
25
  moddleExtensions: {
26
- camunda: camundaModdle,
26
+ ...commonModdleExtensions,
27
27
  ...options.moddleExtensions
28
28
  }
29
29
  };
@@ -35,7 +35,7 @@ inherits(Modeler, BaseModeler);
35
35
 
36
36
  Modeler.prototype._camundaPlatformModules = [
37
37
  camundaModdleExtension,
38
- modelingModule,
38
+ behaviorsModule,
39
39
  CamundaPlatformPropertiesProviderModule,
40
40
  ElementTemplatesPropertiesProviderModule
41
41
  ];
@@ -0,0 +1,25 @@
1
+ import inherits from 'inherits';
2
+
3
+ import BaseViewer from '../base/NavigatedViewer';
4
+
5
+ import { commonModdleExtensions } from './util/commonModules';
6
+
7
+
8
+ /**
9
+ *
10
+ * @param {Object} options
11
+ */
12
+ export default function NavigatedViewer(options = {}) {
13
+
14
+ options = {
15
+ ...options,
16
+ moddleExtensions: {
17
+ ...commonModdleExtensions,
18
+ ...options.moddleExtensions
19
+ }
20
+ };
21
+
22
+ BaseViewer.call(this, options);
23
+ }
24
+
25
+ inherits(NavigatedViewer, BaseViewer);
@@ -0,0 +1,24 @@
1
+ import inherits from 'inherits';
2
+
3
+ import BaseViewer from '../base/Viewer';
4
+
5
+ import { commonModdleExtensions } from './util/commonModules';
6
+
7
+ /**
8
+ *
9
+ * @param {Object} options
10
+ */
11
+ export default function Viewer(options = {}) {
12
+
13
+ options = {
14
+ ...options,
15
+ moddleExtensions: {
16
+ ...commonModdleExtensions,
17
+ ...options.moddleExtensions
18
+ }
19
+ };
20
+
21
+ BaseViewer.call(this, options);
22
+ }
23
+
24
+ inherits(Viewer, BaseViewer);
@@ -0,0 +1,7 @@
1
+ import camundaModdle from 'camunda-bpmn-moddle/resources/camunda.json';
2
+
3
+ export const commonModules = [];
4
+
5
+ export const commonModdleExtensions = {
6
+ camunda: camundaModdle
7
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "camunda-bpmn-js",
3
- "version": "0.13.0-alpha.8",
3
+ "version": "0.13.1",
4
4
  "description": "Embeddable Camunda modeling distributions based on bpmn-js",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -14,6 +14,10 @@
14
14
  "start:base": "cross-env SINGLE_START=base-modeler npm run dev",
15
15
  "start:platform": "cross-env SINGLE_START=camunda-platform-modeler npm run dev",
16
16
  "start:cloud": "cross-env SINGLE_START=camunda-cloud-modeler npm run dev",
17
+ "start:platform-viewer": "cross-env SINGLE_START=camunda-platform-viewer npm run dev",
18
+ "start:cloud-viewer": "cross-env SINGLE_START=camunda-cloud-viewer npm run dev",
19
+ "start:platform-navigated-viewer": "cross-env SINGLE_START=camunda-platform-navigated-viewer npm run dev",
20
+ "start:cloud-navigated-viewer": "cross-env SINGLE_START=camunda-cloud-navigated-viewer npm run dev",
17
21
  "prepublishOnly": "run-s test:distro",
18
22
  "prepare": "run-s clean distro"
19
23
  },
@@ -44,8 +48,9 @@
44
48
  "@bpmn-io/align-to-origin": "^0.7.0",
45
49
  "@bpmn-io/element-templates-icons-renderer": "^0.1.2",
46
50
  "bpmn-js": "^9.0.3",
47
- "bpmn-js-disable-collapsed-subprocess": "^0.1.3",
51
+ "bpmn-js-disable-collapsed-subprocess": "^0.1.4",
48
52
  "bpmn-js-executable-fix": "^0.1.3",
53
+ "camunda-bpmn-js-behaviors": "^0.1.0",
49
54
  "camunda-bpmn-moddle": "^6.1.2",
50
55
  "diagram-js": "^8.2.1",
51
56
  "diagram-js-minimap": "^2.1.0",
@@ -59,7 +64,7 @@
59
64
  "@rollup/plugin-commonjs": "^17.1.0",
60
65
  "@rollup/plugin-json": "^4.1.0",
61
66
  "@rollup/plugin-node-resolve": "^11.1.1",
62
- "bpmn-js-properties-panel": "^1.0.0-alpha.12",
67
+ "bpmn-js-properties-panel": "^1.1.0",
63
68
  "chai": "^4.2.0",
64
69
  "cross-env": "^7.0.3",
65
70
  "del-cli": "^4.0.1",
@@ -93,6 +98,6 @@
93
98
  },
94
99
  "peerDependencies": {
95
100
  "@bpmn-io/properties-panel": "0.13.x",
96
- "bpmn-js-properties-panel": "1.0.0-alpha.10"
101
+ "bpmn-js-properties-panel": "1.x"
97
102
  }
98
103
  }
@@ -0,0 +1,2 @@
1
+ @import './diagram-js.css';
2
+ @import './bpmn-js.css';
@@ -0,0 +1,2 @@
1
+ @import './diagram-js.css';
2
+ @import './bpmn-js.css';
@@ -0,0 +1 @@
1
+ @import './base-navigated-viewer.css';
@@ -0,0 +1 @@
1
+ @import './base-viewer.css';
@@ -0,0 +1 @@
1
+ @import './base-navigated-viewer.css';
@@ -0,0 +1 @@
1
+ @import './base-viewer.css';
package/util/index.js ADDED
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Generates all possible combinations of the items in the given arrays.
3
+ *
4
+ * @param {...Array} - arrays with options to combine
5
+ * @returns {Array<Array>} array with all posible combinations of items
6
+ */
7
+ function getAllCombinations() {
8
+ const [ first, ...rest ] = arguments;
9
+
10
+ if (!first) {
11
+ return;
12
+ }
13
+
14
+ const combinations = getAllCombinations(...rest);
15
+
16
+ return first.reduce((acc, cur) => {
17
+
18
+ const newCombination = combinations ? combinations.map(combination => [ cur, ...combination ]) : [ [ cur ] ];
19
+
20
+ return acc.concat(
21
+ newCombination
22
+ );
23
+ }, []);
24
+ }
25
+
26
+ function capitalize(string) {
27
+ return string.charAt(0).toUpperCase() + string.slice(1);
28
+ }
29
+
30
+ function toKebabCase(string) {
31
+ return string.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
32
+ }
33
+
34
+
35
+ module.exports = {
36
+ getAllCombinations,
37
+ capitalize,
38
+ toKebabCase
39
+ };
@@ -1,115 +0,0 @@
1
- import {
2
- getBusinessObject,
3
- is
4
- } from 'bpmn-js/lib/util/ModelUtil';
5
-
6
- import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
7
-
8
- import { without } from 'min-dash';
9
-
10
- import { getExtensionElementsList } from '../../../../util/ExtensionElementsUtil';
11
-
12
- const HIGH_PRIORITY = 5000;
13
-
14
-
15
- /**
16
- * Zeebe BPMN behavior ensuring that bpmn:BusinessRuleTask only has one of the following:
17
- *
18
- * (1) zeebe:CalledDecision
19
- * (2) zeebe:TaskDefinition and zeebe:TaskHeaders
20
- */
21
- export default class CleanUpBusinessRuleTaskBehavior extends CommandInterceptor {
22
- constructor(commandStack, eventBus) {
23
- super(eventBus);
24
-
25
- /**
26
- * Remove zeebe:CalledDecision if zeebe:TaskDefinition is about to be added.
27
- */
28
- this.preExecute('element.updateModdleProperties' , HIGH_PRIORITY, function(context) {
29
- const {
30
- element,
31
- moddleElement,
32
- properties
33
- } = context;
34
-
35
- if (
36
- !is(element, 'bpmn:BusinessRuleTask')
37
- || !is(moddleElement, 'bpmn:ExtensionElements')
38
- || !properties.values
39
- ) {
40
- return;
41
- }
42
-
43
- const calledDecision = getCalledDecision(element),
44
- taskDefinition = getTaskDefinition(element);
45
-
46
- if (
47
- calledDecision
48
- && !taskDefinition
49
- && properties.values.find(value => is(value, 'zeebe:CalledDecision'))
50
- && properties.values.find(value => is(value, 'zeebe:TaskDefinition'))
51
- ) {
52
- properties.values = without(properties.values, calledDecision);
53
- }
54
- }, true);
55
-
56
- /**
57
- * Remove zeebe:TaskDefinition and zeebe:TaskHeaders if zeebe:CalledDecision is about to be added.
58
- */
59
- this.preExecute('element.updateModdleProperties', HIGH_PRIORITY, function(context) {
60
- const {
61
- element,
62
- moddleElement,
63
- properties
64
- } = context;
65
-
66
- if (
67
- !is(element, 'bpmn:BusinessRuleTask')
68
- || !is(moddleElement, 'bpmn:ExtensionElements')
69
- || !properties.values
70
- ) {
71
- return;
72
- }
73
-
74
- const calledDecision = getCalledDecision(element),
75
- taskDefinition = getTaskDefinition(element),
76
- taskHeaders = getTaskHeaders(element);
77
-
78
- if (
79
- !calledDecision
80
- && (taskDefinition || taskHeaders)
81
- && properties.values.find(value => is(value, 'zeebe:CalledDecision'))
82
- && properties.values.find(value => is(value, 'zeebe:TaskDefinition') || is(value, 'zeebe:TaskHeaders'))
83
- ) {
84
- properties.values = without(properties.values, (value) => value === taskDefinition || value === taskHeaders);
85
- }
86
- }, true);
87
-
88
- }
89
- }
90
-
91
- CleanUpBusinessRuleTaskBehavior.$inject = [
92
- 'commandStack',
93
- 'eventBus'
94
- ];
95
-
96
-
97
- // helpers //////////
98
-
99
- function getCalledDecision(element) {
100
- const businessObject = getBusinessObject(element);
101
-
102
- return getExtensionElementsList(businessObject, 'zeebe:CalledDecision')[ 0 ];
103
- }
104
-
105
- function getTaskDefinition(element) {
106
- const businessObject = getBusinessObject(element);
107
-
108
- return getExtensionElementsList(businessObject, 'zeebe:TaskDefinition')[ 0 ];
109
- }
110
-
111
- function getTaskHeaders(element) {
112
- const businessObject = getBusinessObject(element);
113
-
114
- return getExtensionElementsList(businessObject, 'zeebe:TaskHeaders')[ 0 ];
115
- }
@@ -1,76 +0,0 @@
1
- import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
2
-
3
- import {
4
- getBusinessObject,
5
- is
6
- } from 'bpmn-js/lib/util/ModelUtil';
7
-
8
- const HIGH_PRIORITY = 5000;
9
-
10
-
11
- /**
12
- * Zeebe BPMN specific behavior for creating boundary events.
13
- */
14
- export default class CreateZeebeBoundaryEventBehavior extends CommandInterceptor {
15
- constructor(bpmnFactory, elementFactory, eventBus) {
16
- super(eventBus);
17
-
18
- /**
19
- * Replace intermediate catch event with boundary event when attaching it to a shape.
20
- */
21
- this.preExecute('shape.create', HIGH_PRIORITY, function(context) {
22
- const {
23
- shape,
24
- host
25
- } = context;
26
-
27
- const businessObject = getBusinessObject(shape);
28
-
29
- let attrs = {
30
- cancelActivity: true
31
- };
32
-
33
- let newBusinessObject,
34
- hostBusinessObject,
35
- boundaryEvent,
36
- eventDefinitions;
37
-
38
- if (!host || !is(shape, 'bpmn:IntermediateCatchEvent')) {
39
- return;
40
- }
41
-
42
- hostBusinessObject = getBusinessObject(host);
43
-
44
- attrs = {
45
- ...attrs,
46
- attachedToRef: hostBusinessObject
47
- };
48
-
49
- eventDefinitions = businessObject.eventDefinitions;
50
-
51
- newBusinessObject = bpmnFactory.create('bpmn:BoundaryEvent', attrs);
52
-
53
- boundaryEvent = {
54
- type: 'bpmn:BoundaryEvent',
55
- businessObject: newBusinessObject,
56
- };
57
-
58
- if (eventDefinitions && eventDefinitions[0]) {
59
- boundaryEvent = {
60
- ...boundaryEvent,
61
- eventDefinitionType: eventDefinitions[0].$type
62
- };
63
- }
64
-
65
- context.shape = elementFactory.createShape(boundaryEvent);
66
-
67
- }, true);
68
-
69
- }
70
- }
71
-
72
- CreateZeebeBoundaryEventBehavior.$inject = [
73
- 'bpmnFactory',
74
- 'elementFactory',
75
- 'eventBus'
76
- ];
@@ -1,86 +0,0 @@
1
- import { has } from 'min-dash';
2
-
3
- import { createElement } from '../../../helper/ElementHelper';
4
-
5
- import { getCalledElement } from '../../../helper/CalledElementHelper';
6
-
7
- import {
8
- getBusinessObject,
9
- is
10
- } from 'bpmn-js/lib/util/ModelUtil';
11
-
12
- import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
13
-
14
- const HIGH_PRIORITY = 5000;
15
-
16
-
17
- /**
18
- * Zeebe BPMN specific behavior for creating call activities.
19
- */
20
- export default class CreateZeebeCallActivityBehavior extends CommandInterceptor {
21
- constructor(bpmnFactory, eventBus, modeling) {
22
- super(eventBus);
23
-
24
- /**
25
- * Add zeebe:CalledElement extension element with zeebe:propagateAllChildVariables attribute = false
26
- * when creating bpmn:CallActivity.
27
- */
28
- this.postExecuted('shape.create', HIGH_PRIORITY, function(context) {
29
- const { shape } = context;
30
-
31
- if (!is(shape, 'bpmn:CallActivity')) {
32
- return;
33
- }
34
-
35
- const businessObject = getBusinessObject(shape);
36
-
37
- let calledElement = getCalledElement(businessObject);
38
-
39
- if (!calledElement) {
40
- let extensionElements = businessObject.get('extensionElements');
41
-
42
- if (!extensionElements) {
43
- extensionElements = createElement(
44
- 'bpmn:ExtensionElements',
45
- {
46
- values: []
47
- },
48
- businessObject,
49
- bpmnFactory
50
- );
51
-
52
- modeling.updateProperties(shape, { extensionElements });
53
- }
54
-
55
- calledElement = createElement(
56
- 'zeebe:CalledElement',
57
- {
58
- propagateAllChildVariables: false
59
- },
60
- extensionElements,
61
- bpmnFactory
62
- );
63
-
64
- modeling.updateModdleProperties(shape, extensionElements, {
65
- values: [
66
- ...(extensionElements.values || []),
67
- calledElement
68
- ]
69
- });
70
- } else if (!has(calledElement, 'propagateAllChildVariables')) {
71
-
72
- // set zeebe:propagateAllChildVariables to false if zeebe:CalledElement exists
73
- modeling.updateModdleProperties(shape, calledElement, {
74
- propagateAllChildVariables: false
75
- });
76
- }
77
- }, true);
78
-
79
- }
80
- }
81
-
82
- CreateZeebeCallActivityBehavior.$inject = [
83
- 'bpmnFactory',
84
- 'eventBus',
85
- 'modeling'
86
- ];