@eturnity/eturnity_3d 0.0.4

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 (78) hide show
  1. package/.babelrc +3 -0
  2. package/.env +0 -0
  3. package/.eslintrc +18 -0
  4. package/.eslintrc.json +18 -0
  5. package/.prettierrc +7 -0
  6. package/Dockerfile +17 -0
  7. package/README.md +18 -0
  8. package/bitbucket-pipelines.yml +681 -0
  9. package/dist/assets/images/panels/longiSolarLR4_60HPH_350M.png +0 -0
  10. package/dist/assets/images/panels/longiSolarLR4_60HPH_370M.png +0 -0
  11. package/dist/assets/images/panels/reneSola_Virtus_2_JC320S_24_Bbw copy.png +0 -0
  12. package/dist/assets/images/panels/reneSola_Virtus_2_JC320S_24_Bbw.png +0 -0
  13. package/dist/assets/images/panels/uv.png +0 -0
  14. package/dist/assets/panels/longiSolarLR4_60HPH_350M.png +0 -0
  15. package/dist/assets/panels/longiSolarLR4_60HPH_370M.png +0 -0
  16. package/dist/assets/panels/reneSola_Virtus_2_JC320S_24_Bbw.png +0 -0
  17. package/dist/assets/panels/uv.png +0 -0
  18. package/dist/assets/theme.js +43 -0
  19. package/dist/assets/vue.svg +1 -0
  20. package/dist/css/main.1f8fe45d.css +1 -0
  21. package/dist/img/longiSolarLR4_60HPH_350M.85a84b2e.png +0 -0
  22. package/dist/img/longiSolarLR4_60HPH_370M.bf6b1f4e.png +0 -0
  23. package/dist/img/reneSola_Virtus_2_JC320S_24_Bbw.8b1892e0.png +0 -0
  24. package/dist/index.html +26 -0
  25. package/dist/main.js +60230 -0
  26. package/dist/main.js.map +1 -0
  27. package/dist/vite.svg +1 -0
  28. package/docker_conf/nginx/nginx.conf +16 -0
  29. package/index.html +26 -0
  30. package/package.json +71 -0
  31. package/postcss.config.js +1 -0
  32. package/preview.html +55 -0
  33. package/public/assets/images/panels/longiSolarLR4_60HPH_350M.png +0 -0
  34. package/public/assets/images/panels/longiSolarLR4_60HPH_370M.png +0 -0
  35. package/public/assets/images/panels/reneSola_Virtus_2_JC320S_24_Bbw copy.png +0 -0
  36. package/public/assets/images/panels/reneSola_Virtus_2_JC320S_24_Bbw.png +0 -0
  37. package/public/assets/images/panels/uv.png +0 -0
  38. package/public/assets/panels/longiSolarLR4_60HPH_350M.png +0 -0
  39. package/public/assets/panels/longiSolarLR4_60HPH_370M.png +0 -0
  40. package/public/assets/panels/reneSola_Virtus_2_JC320S_24_Bbw.png +0 -0
  41. package/public/assets/panels/uv.png +0 -0
  42. package/public/assets/theme.js +43 -0
  43. package/public/assets/vue.svg +1 -0
  44. package/public/vite.svg +1 -0
  45. package/server.js +17 -0
  46. package/src/App.vue +28 -0
  47. package/src/assets/images/panels/longiSolarLR4_60HPH_350M.png +0 -0
  48. package/src/assets/images/panels/longiSolarLR4_60HPH_370M.png +0 -0
  49. package/src/assets/images/panels/reneSola_Virtus_2_JC320S_24_Bbw copy.png +0 -0
  50. package/src/assets/images/panels/reneSola_Virtus_2_JC320S_24_Bbw.png +0 -0
  51. package/src/assets/images/panels/uv.png +0 -0
  52. package/src/assets/images/white_tile.png +0 -0
  53. package/src/assets/theme.js +43 -0
  54. package/src/components/ThreeCanvasViewer.vue +247 -0
  55. package/src/config.js +104 -0
  56. package/src/functions.js +2 -0
  57. package/src/helper/DFS.js +80 -0
  58. package/src/helper/MapView.js +253 -0
  59. package/src/helper/UpdateRoofModuleFieldRelations.js +119 -0
  60. package/src/helper/UpdateRoofObstacleRelations.js +86 -0
  61. package/src/helper/clearThreeObjects.js +21 -0
  62. package/src/helper/customProvider.js +57 -0
  63. package/src/helper/geometryHandler.js +606 -0
  64. package/src/helper/graphCreation.js +43 -0
  65. package/src/helper/materials.js +55 -0
  66. package/src/helper/projectedMaterial.js +502 -0
  67. package/src/helper/renderMixin.js +1132 -0
  68. package/src/helper/threeMixin.js +171 -0
  69. package/src/main.js +28 -0
  70. package/src/store/AddMargin.js +107 -0
  71. package/src/store/hydrateData.js +209 -0
  72. package/src/store/nodesEdgesCreation.js +216 -0
  73. package/src/store/store.js +10 -0
  74. package/src/store/three-d-module.js +142 -0
  75. package/src/style.css +96 -0
  76. package/src/utils/layers.js +265 -0
  77. package/src/utils/leaflet-config.service.js +67 -0
  78. package/vue.config.js +46 -0
@@ -0,0 +1,43 @@
1
+ const theme = {
2
+ colors: {
3
+ primary: '#282387',
4
+ secondary: '#818181',
5
+ tertiary: '#d5d5d5',
6
+ black: '#263238',
7
+ yellow: '#fdb813',
8
+ darkGray: '#818181',
9
+ mediumGray: '#d5d5d5',
10
+ lightGray: '#f2f2f2',
11
+ white: '#fff',
12
+ blue: '#48a2d0',
13
+ red: '#FF5656',
14
+ blue1: '#e4efff',
15
+ blue2: '#F6FAFF',
16
+ grey1: '#666',
17
+ grey2: '#c4c4c4',
18
+ grey3: '#b2b9c5',
19
+ grey4: '#dee2eb',
20
+ grey5: '#fafafa',
21
+ grey6: '#555d61',
22
+ turquoise:'#20A4CA',
23
+ green: '#99db0c',
24
+ purple: '#505ca6',
25
+ disabled: '#dfe1e1',
26
+ transparentWhite1: '#ffffff32',
27
+ transparentBlack1: '#263238e6',
28
+ transparentBlue1:'#20a4cae6',
29
+ blueElectric:'#66dffa',
30
+ eturnityGrey: '#263238'
31
+ },
32
+
33
+ screen: {
34
+ mobileSmall: '345px',
35
+ mobile: '425px',
36
+ mobileLarge: '530px',
37
+ tablet: '768px',
38
+ tabletLarge: '950px'
39
+ },
40
+ borderRadius: '4px'
41
+ }
42
+
43
+ export default theme
@@ -0,0 +1,247 @@
1
+ <template>
2
+ <div id="canvas3DContainer" ref="canvas3DContainer" crossorigin />
3
+ </template>
4
+
5
+ <script>
6
+ import { mapActions, mapState, mapGetters,mapMutations } from 'vuex'
7
+ import * as THREE from 'three'
8
+ import { addVector, multiplyVector } from '@eturnity/eturnity_maths'
9
+ import { updateComputedGeometryPolygon } from '@eturnity/eturnity_maths'
10
+
11
+ import threeMixin from '../helper/threeMixin'
12
+ import { material } from '../helper/materials'
13
+ import renderMixin from '../helper/renderMixin'
14
+ export default {
15
+ name: 'ThreeCanvas',
16
+ data() {
17
+ return {
18
+ scene: new THREE.Scene(),
19
+ camera: new THREE.PerspectiveCamera(50, 300 / 300, 0.1, 100000),
20
+ orthographicCamera: new THREE.OrthographicCamera(
21
+ 10 / -2,
22
+ 10 / 2,
23
+ 10 / 2,
24
+ 10 / -2,
25
+ 1,
26
+ 1000
27
+ ),
28
+ provider:null,
29
+ cameraprojection: null,
30
+ texture: null,
31
+ material: material,
32
+ renderer: new THREE.WebGLRenderer({
33
+ antialias: true,
34
+ preserveDrawingBuffer: true
35
+ }),
36
+ orbitControl:null,
37
+ raycaster: new THREE.Raycaster(),
38
+ loader: new THREE.TextureLoader(),
39
+ pointer: { x: 0, y: 0 },
40
+ canvasHeight: null,
41
+ canvasWidth: null,
42
+ canvasOffset: { x: 0, y: 0 },
43
+ tweenCamera: null,
44
+ tweenOrbit: null,
45
+ three_map: null,
46
+ backgroundImagesizeInMm: null,
47
+ textureLoader: new THREE.TextureLoader(),
48
+ isReady: {
49
+ texturesLoaded: 0,
50
+ texturesToLoad: 0,
51
+ backgroundImage: false,
52
+ threeMap: false,
53
+ geometry: false,
54
+ camera: false
55
+ },
56
+ screenshotable: false
57
+ }
58
+ },
59
+ mixins: [renderMixin,threeMixin],
60
+ async mounted() {
61
+ await this.hydrateData(this.geometryData)
62
+ this.renderer.domElement.style.width = '100%'
63
+ this.renderer.domElement.style.height = '100%'
64
+
65
+ this.initialiseThree()
66
+ this.loadProjectionMaterial()
67
+ this.initialiseThreeMap()
68
+ await this.loadTextureFromModuleFields()
69
+ this.renderGeometry()
70
+ this.onWindowResize()
71
+ this.animate()
72
+ this.$root.$on('on-roofSelected',(polygon)=>this.setCameraOrthogonalTo(polygon))
73
+ this.updateProjectionMaterial()
74
+
75
+ console.log('uuid to focus on:', this.uuid)
76
+ const polygon = this.polygons.find((p) => p.id == this.uuid)
77
+ this.setCamera(polygon, this.view_mode)
78
+ this.isReady.geometry = true
79
+ },
80
+ computed: {
81
+ ...mapState({
82
+ geometryData: (state) => state.threeDModule.geometryData,
83
+ uuid: (state) => state.threeDModule.uuid,
84
+ view_mode: (state) => state.threeDModule.view_mode
85
+ }),
86
+ ...mapGetters({
87
+ polygons: 'getPolygons',
88
+ edges: 'getEdges3D',
89
+ nodes: 'getNodes3D',
90
+ mapConfig: 'getMapConfig',
91
+ roofsBounds: 'getRoofsBounds',
92
+ layoutSettings: 'getLayoutSettings',
93
+
94
+ roofs: 'getRoofs',
95
+ obstacles: 'getObstacles',
96
+ moduleFields: 'getModuleFields',
97
+ panels: 'getPanels',
98
+ userDeactivatedPanels: 'getUserDeactivatedPanels'
99
+ })
100
+ },
101
+ methods: {
102
+ ...mapActions({
103
+ hydrateData: 'hydrateData'
104
+ }),
105
+ ...mapMutations({
106
+ set_module_texture_version_id: 'mutate_module_texture_version_id'
107
+ }),
108
+ setCamera(polygon, view_mode) {
109
+ console.log('viewmode', view_mode)
110
+ if (!polygon || view_mode == 'global') {
111
+ let roofsBounds = this.roofsBounds()
112
+ //let distance = 5 + objectRadius / Math.sin(((this.orthographicCamera.fov / 2) * Math.PI) / 180)
113
+ //console.log('distance:',distance)
114
+ const position = [0, 0, 100]
115
+ const target = [0, 0, 0]
116
+ this.orthographicCamera.position.set(...position)
117
+ this.orthographicCamera.lookAt(...target)
118
+ this.isReady.camera = true
119
+ this.orthographicCamera.left = roofsBounds.xMin / 1000
120
+ this.orthographicCamera.right = roofsBounds.xMax / 1000
121
+ this.orthographicCamera.top = roofsBounds.yMax / 1000
122
+ this.orthographicCamera.bottom = roofsBounds.yMin / 1000
123
+ this.orthographicCamera.updateProjectionMatrix()
124
+ } else if (polygon) {
125
+ let polygonRef = polygon
126
+
127
+ //get polygonMesh
128
+ let mesh
129
+ let target
130
+ let distance = 45
131
+ if (polygonRef.layer == 'roof') {
132
+ mesh = this.meshes.roofMeshes[polygonRef.id]
133
+ } else if (polygonRef.layer == 'moduleField') {
134
+ mesh = this.meshes.moduleFieldsMeshes[polygonRef.id]
135
+ }
136
+ if (mesh) {
137
+ const geometry = mesh.geometry
138
+
139
+ if (geometry.boundingSphere === null) geometry.computeBoundingSphere()
140
+ console.log('geometry.boundingSphere', geometry.boundingSphere)
141
+ target = [
142
+ geometry.boundingSphere.center.x,
143
+ geometry.boundingSphere.center.y,
144
+ geometry.boundingSphere.center.z
145
+ ]
146
+ let objectRadius = geometry.boundingSphere.radius
147
+ distance =
148
+ 5 + objectRadius / Math.sin(((this.camera.fov / 2) * Math.PI) / 180)
149
+ //_sphere.copy( geometry.boundingSphere ).applyMatrix4( object.matrixWorld );
150
+ }
151
+
152
+ polygonRef = updateComputedGeometryPolygon(polygonRef)
153
+ const targetVector = polygonRef.meanPoint
154
+ //const target=[targetVector.x/1000,targetVector.y/1000,targetVector.z/1000]
155
+ let cameraMoveVector = { x: 0, y: 0, z: 0 }
156
+ console.log('normalVector:', polygonRef.normalVector)
157
+ if (view_mode == 'ortho') {
158
+ cameraMoveVector = multiplyVector(
159
+ distance * 1000,
160
+ polygonRef.normalVector
161
+ )
162
+ } else if (view_mode == 'top') {
163
+ let polygonBounds = polygonRef.getBounds()
164
+ polygonBounds.xMin-=1000
165
+ polygonBounds.xMax+=1000
166
+ polygonBounds.yMin-=1000
167
+ polygonBounds.yMax+=1000
168
+ const position = [0,0, 100]
169
+ const target = [0, 0, 0]
170
+
171
+ console.log('top POS TARGET', position, target)
172
+ this.orthographicCamera.position.set(...position)
173
+ this.orthographicCamera.lookAt(...target)
174
+ this.orthographicCamera.left = polygonBounds.xMin / 1000
175
+ this.orthographicCamera.right = polygonBounds.xMax / 1000
176
+ this.orthographicCamera.top = polygonBounds.yMax / 1000
177
+ this.orthographicCamera.bottom = polygonBounds.yMin / 1000
178
+ this.orthographicCamera.updateProjectionMatrix()
179
+ } else {
180
+ //street view
181
+ const horizontalVector = { ...polygonRef.normalVector, z: 0 }
182
+ if (horizontalVector.x == 0 && horizontalVector.y == 0) {
183
+ horizontalVector.y = 1
184
+ }
185
+ cameraMoveVector = multiplyVector(distance * 1000, horizontalVector)
186
+ }
187
+
188
+ const positionVector = addVector(polygonRef.meanPoint, cameraMoveVector)
189
+ const position = [
190
+ positionVector.x / 1000,
191
+ positionVector.y / 1000 - 1,
192
+ positionVector.z / 1000
193
+ ]
194
+
195
+ this.camera.position.set(...position)
196
+ this.camera.lookAt(...target)
197
+ this.camera.updateProjectionMatrix()
198
+
199
+ this.isReady.camera = true
200
+ }
201
+ },
202
+ animate() {
203
+ this.render()
204
+ requestAnimationFrame(this.animate)
205
+ },
206
+ render() {
207
+ this.renderer.clear()
208
+ if (['top', 'global'].includes(this.view_mode)) {
209
+ this.renderer.render(this.scene, this.orthographicCamera)
210
+ } else {
211
+ this.renderer.render(this.scene, this.camera)
212
+ }
213
+ }
214
+ },
215
+ watch: {
216
+ isReady: {
217
+ handler() {
218
+ if (
219
+ this.isReady.texturesToLoad == this.isReady.texturesLoaded &&
220
+ this.isReady.backgroundImage &&
221
+ this.isReady.geometry &&
222
+ this.isReady.threeMap &&
223
+ this.isReady.camera
224
+ ) {
225
+ var event = new CustomEvent('screenshotable')
226
+ // dispatch the custom event
227
+ document.dispatchEvent(event)
228
+ this.screenshotable = true
229
+ console.log('screenshotable')
230
+ }
231
+ },
232
+ deep: true
233
+ }
234
+ }
235
+ }
236
+ </script>
237
+
238
+ <style>
239
+ #canvas3DContainer {
240
+ width: 100%;
241
+ height: 100%;
242
+ }
243
+ #canvas3DContainer > canvas {
244
+ width: 100%;
245
+ height: 100%;
246
+ }
247
+ </style>
package/src/config.js ADDED
@@ -0,0 +1,104 @@
1
+ import theme from './assets/theme'
2
+ export const polygonCloseTolerance=15
3
+ export const snapToPointTolerance = 15
4
+ export const snapToIntersectionPointTolerance = 15
5
+ export const snapToLineTolerance = 10
6
+ export const distanceToCloseNode = 70
7
+ export const mmTolerance=50
8
+ export const earthRadius=6371008
9
+
10
+ export const layerColors = {
11
+ construction: { fillColor: 'transparent', strokeColor: theme.colors.blueElectric ,strokeWidth:3 },
12
+ roof: { fillColor: 'rgba(255, 255, 255, 0.1)', strokeColor: 'white' ,strokeWidth:0 },
13
+ roofInside: { fillColor: 'rgba(255, 255, 255, 0.1)', strokeColor: 'white' ,strokeWidth:1},
14
+ obstacle: { fillColor: theme.colors.red, strokeColor: 'red' ,strokeWidth:1 },
15
+ panel: { fillColor: 'rgba(115, 115, 229, 0.1)', strokeColor: '#ffffff' ,strokeWidth:1},
16
+ user_deactivated_panel: { fillColor: 'rgba(115, 115, 229, 0.1)', strokeColor: 'white' ,strokeWidth:4},
17
+ selectedPanel: { fillColor: '#0068DE80', strokeColor: theme.colors.blue ,strokeWidth:1},
18
+ snap: { fillColor: 'transparent', strokeColor: 'white' },
19
+ moduleField: { fillColor: 'rgba(255, 255, 255, 0.1)', strokeColor: 'white' ,strokeWidth:3 },
20
+ hoveredModuleFieldEdge: { strokeColor: theme.colors.blue ,strokeWidth:6 },
21
+ tmpModuleField: { fillColor: 'rgba(115, 115, 229, 0.4)', strokeColor: theme.colors.blue ,strokeWidth:2 },
22
+ selectedModuleField: {fillColor: '#0068DE80', strokeColor: theme.colors.blue ,strokeWidth:3},
23
+ highlight: { fillColor: 'rgba(255, 255, 255, 0.2)', strokeColor: 'white' ,strokeWidth:1 },
24
+ selectedRoof: { fillColor: '#0068DE80', strokeColor: 'white' ,strokeWidth:3 },
25
+ selectedObstacle: { fillColor: '#0068DE80', strokeColor: theme.colors.blue ,strokeWidth:2 },
26
+ selectedAndHighlighted: {fillColor: '#0068DEA0', strokeColor: theme.colors.blue ,strokeWidth:3},
27
+ flatWarning: {fillColor: '#ffff0090', strokeColor: 'yellow' ,strokeWidth:1},
28
+ customLength: { fillColor: 'transparent', strokeColor: theme.colors.blueElectric ,strokeWidth:1 },
29
+ snapDirectionIncline: { fillColor: 'transparent', strokeColor: theme.colors.blue ,strokeWidth:1 },
30
+ inclineDirectionArrow: { fillColor: 'transparent', strokeColor: "#FF5656" ,strokeWidth:5 },
31
+ inclineLabel: { fillColor: theme.colors.transparentBlack1, textColor: "white"},
32
+ directionLabel: { fillColor: theme.colors.transparentBlack1, textColor: "white"},
33
+ }
34
+
35
+ export const snapInclineTolerance=5
36
+ export const snapDirectionTolerance=15
37
+ export const radiusPadding=20
38
+ export const InclineDirectionCircleRadius=250
39
+ export const inclineDirectionMinRadius=50
40
+ export const baseEdgeOfModuleField=theme.colors.blueElectric
41
+ export const maximumGapLimit=500
42
+ export const defaultBaseHeight=3000
43
+ export const colorArrayBase=[
44
+ "#FF5656",
45
+ "#FDB813",
46
+ "#505CA6",
47
+ "#8392EE",
48
+ "#6CD5D5",
49
+ "#C84E4E",
50
+ "#90A650",
51
+ "#D27CCA",
52
+ "#6276DF",
53
+ ]
54
+ export const colorArray=colorArrayBase.map(c=>c+"c0")
55
+ export const layerTools={
56
+ map:[],
57
+ roof:["drawRoof","selectRoof"],
58
+ obstacle:["drawObstacle"],
59
+ margin:["selectMargin"],
60
+ panel:["selectModuleField"],
61
+ }
62
+ //3D visualisation:
63
+ export const beamRadius=0.05
64
+ export const maxMargin=2500
65
+ export const node3DRadius=0.05
66
+ export const beamColor="#ffffff"
67
+ export const node3DColor="white"
68
+ export const beamOpacity=0.3
69
+ export const node3dOpacity=0.3
70
+ export const dimMarginColor='#ff000020'
71
+ export const defaultTextureUrl=require('./assets/images/panels/reneSola_Virtus_2_JC320S_24_Bbw.png')
72
+ export const defaultTextureUrls=[
73
+ require('./assets/images/panels/reneSola_Virtus_2_JC320S_24_Bbw.png'),
74
+ require('./assets/images/panels/longiSolarLR4_60HPH_370M.png'),
75
+ require('./assets/images/panels/longiSolarLR4_60HPH_350M.png'),
76
+ ]
77
+ export const hitOption = {
78
+ segments: true,
79
+ stroke: true,
80
+ fill: true,
81
+ tolerance: 10
82
+ }
83
+ export const zoomFactor=Math.exp(Math.log(2)/10)
84
+ export const hitOptionPolygonStrict = {
85
+ segments: false,
86
+ stroke: false,
87
+ fill: true,
88
+ tolerance: 0
89
+ }
90
+ export const hitOptionStrokeStrict = {
91
+ segments: false,
92
+ stroke: true,
93
+ fill: false,
94
+ tolerance: 0
95
+ }
96
+ export const hitOptionStroke = {
97
+ segments: false,
98
+ stroke: true,
99
+ fill: false,
100
+ tolerance: 2
101
+ }
102
+
103
+ export const dragHeightSensitivity=20
104
+ export const snapLimit=100
@@ -0,0 +1,2 @@
1
+ export * from './helper/UpdateRoofModuleFieldRelations'
2
+ export * from './helper/UpdateRoofObstacleRelations'
@@ -0,0 +1,80 @@
1
+
2
+ // Javascript program to print DFS
3
+ // traversal from a given
4
+ // graph
5
+
6
+ // This class represents a
7
+ // directed graph using adjacency
8
+ // list representation
9
+ export class Graph
10
+ {
11
+
12
+ // Constructor
13
+ //v=number of vertices
14
+ constructor()
15
+ {
16
+ this.visited=[]
17
+ this.dict= []
18
+ this.adj = []
19
+
20
+ }
21
+
22
+ // Function to add an edge into the graph
23
+ addEdge(uuid1, uuid2)
24
+ {
25
+ let v=this.dict.indexOf(uuid1)
26
+ let length
27
+ if(v==-1){
28
+ length=this.dict.length
29
+ this.dict[length]=uuid1
30
+ this.adj[length]=[]
31
+ v=length
32
+ }
33
+ let w=this.dict.indexOf(uuid2)
34
+ if(w==-1){
35
+ length=this.dict.length
36
+ this.dict[length]=uuid2
37
+ this.adj[length]=[]
38
+ w=length
39
+ }
40
+ // Add w to v's list.
41
+ if(!this.adj[v]){this.adj[v]=[]}
42
+ this.adj[v].push(w);
43
+ if(!this.adj[w]){this.adj[w]=[]}
44
+ this.adj[w].push(v);
45
+ }
46
+
47
+ // A function used by DFS
48
+ DFSUtil(v, visited)
49
+ {
50
+
51
+ // Mark the current node as visited and print it
52
+ visited[v] = true;
53
+ this.visited.push(v)
54
+
55
+ // Recur for all the vertices adjacent to this
56
+ // vertex
57
+ for(let i in this.adj[v])
58
+ {
59
+ let n = this.adj[v][i]
60
+ if (!visited[n])
61
+ this.DFSUtil(n, visited);
62
+ }
63
+ }
64
+
65
+ // The function to do DFS traversal.
66
+ // It uses recursive
67
+ // DFSUtil()
68
+ DFS(uuidStart){
69
+ let v=this.dict.indexOf(uuidStart)
70
+ // Mark all the vertices as
71
+ // not visited(set as
72
+ // false by default in java)
73
+ let visited = [];
74
+ // Call the recursive helper
75
+ // function to print DFS
76
+ // traversal
77
+ this.DFSUtil(v, visited);
78
+ return [...new Set(this.visited.map((i)=>{return this.dict[i]}))]
79
+ }
80
+ }