diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 8ec874d9bbd407363e6264ae30611a3d358a684e..ffe1b195d489bf56fa2477e22389cd95a18bfb41 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -9,12 +9,10 @@ include:
     - apt-get update && apt-get install -y git default-jre
     - npm install
     - npm run build
-    - echo "@metabohub:registry=https://forgemia.inra.fr/api/v4/packages/npm/">.npmrc
-    - echo "//forgemia.inra.fr/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=${CI_JOB_TOKEN}">>.npmrc
 
 
 test:
-  image: node:latest
+  image: node:18
   stage: test
   before_script:
     - npm install
diff --git a/.npmrc b/.npmrc
index f4c5e3ac00e2deb26b41d8c24d9d6a0548a754cb..9c9fc8246cf71c9b77fa234dd584e516bc037699 100644
--- a/.npmrc
+++ b/.npmrc
@@ -1,2 +1,2 @@
-@metabohub:registry=https://forgemia.inra.fr/api/v4/packages/npm/
-//forgemia.inra.fr/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=${CI_JOB_TOKEN}
\ No newline at end of file
+@metabohub:registry=https://forgemia.inra.fr/api/v4/projects/${CI_PROJECT_ID}/packages/npm/
+//forgemia.inra.fr/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=${CI_JOB_TOKEN}
diff --git a/src/composables/LayoutMainChain.ts b/src/composables/LayoutMainChain.ts
index 9af059454f7de0cf2c48524fb1c8340d6bff001e..92cf43f3666e219fca07c9ed1f7cb86d820b4cbf 100644
--- a/src/composables/LayoutMainChain.ts
+++ b/src/composables/LayoutMainChain.ts
@@ -267,61 +267,80 @@ function findMaxKeys(obj: { [key: string]: number }): {key:string[],max:number}
 
 /**
  * Merge a new path in the object with all paths. If a common node is find between the new path and the other : the two paths are merged into one.
- * Else the path is added as a new one.
+ * Else the path is added as a new one. If merge is false, one of the path with highest height is keeped.
  * @param source source node use to get the longest path from a source DAG
  * @param newPath path to add in the object with all paths
  * @param pathsFromSources object with all paths (array of node id with an path id)
  * @param [merge=true] if true, merge the path with an existing one if a common node is found
  * @returns all paths including the new one
  */
-async function mergeNewPath(source:string,newPath:{nodes:Array<string>, height:number},pathsFromSources:{[key:string]:{nodes:Array<string>, height:number}}, merge:boolean=true):Promise<{[key:string]:{nodes:Array<string>, height:number}}>{
-    const keys=Object.keys(pathsFromSources).sort();
-    let processed:boolean=false;
-
-    // if no path in the object : add the new path
-    if (keys.length===0){
-        pathsFromSources[source]=newPath;
-        return pathsFromSources;
-    }
+async function mergeNewPath( source: string, newPath: { nodes: Array<string>, height: number }, pathsFromSources: { [key: string]: { nodes: Array<string>, height: number } }, merge: boolean = true ): Promise<{ [key: string]: { nodes: Array<string>, height: number } }> {
+    const keys = Object.keys(pathsFromSources).sort();
+    let keysCommonNodes: string[] = [];
 
-    // for each path in the object
-    keys.forEach(key=>{
+    // Searching paths with common nodes : keep their keys
+    keys.forEach(key => {
         const pathNodes = pathsFromSources[key].nodes;
-        // Check for common nodes
+        // common nodes ?
         const commonNodes = pathNodes.find(node => newPath.nodes.includes(node));
-        if (commonNodes && commonNodes.length>0){
-            processed=true;
-            if(merge){
-                // Merge paths
-                const mergedPath = Array.from(new Set(pathNodes.concat(newPath.nodes)));
-                // Create new key if necessary
-                let newKey:string = key;
-                const sourceAlreadyInKey=key.split('__').includes(source);
-                if(!sourceAlreadyInKey){ 
-                    newKey= `${key}__${source}`;
-                }
-                // Update pathsFromSources object
-                const newheight=newPath.height>pathsFromSources[key].height?newPath.height:pathsFromSources[key].height;
-                pathsFromSources[newKey] = {nodes:mergedPath,height:newheight};
-                
-                // Remove old key if the name has changed
-                if(!sourceAlreadyInKey){
-                    delete pathsFromSources[key];
+        if (commonNodes) {
+            keysCommonNodes.push(key);
+        }
+    });
+
+    // if independant path
+    if (keysCommonNodes.length === 0) {
+        if (pathsFromSources[source]) throw new Error('source already in pathsFromSources, but supposed to have no common nodes');
+        pathsFromSources[source] = newPath;
+    } else {
+        // if common nodes
+        if (merge) {
+            // if merge
+            let mergedPath = newPath.nodes;
+            let newHeight = newPath.height;
+
+            keysCommonNodes.forEach(key => {
+                mergedPath = Array.from(new Set(mergedPath.concat(pathsFromSources[key].nodes)));
+                newHeight = Math.max(newHeight, pathsFromSources[key].height);
+            });
+
+            // suppression of keys with common nodes
+            keysCommonNodes.forEach(key => {
+                delete pathsFromSources[key];
+            });
+
+            // adding new path (merged)
+            if (pathsFromSources[source]) throw new Error('newKey already exists in pathsFromSources : there is another path with same source but no common nodes');
+                pathsFromSources[source] = { nodes: mergedPath, height: newHeight };
+        } else {
+            // if no merge : keeping the path with the highest height
+            let maxHeight = newPath.height;
+            let maxHeightKey = source;
+            let maxPath = newPath.nodes;
+
+            keysCommonNodes.forEach(key => {
+                if (pathsFromSources[key].height >= maxHeight) {
+                    maxHeight = pathsFromSources[key].height;
+                    maxPath = pathsFromSources[key].nodes;
+                    maxHeightKey = key;
                 }
-            }else{
-                // Highest path is kept
-                if(newPath.height>pathsFromSources[key].height){
+            });
+
+            // suppression of keys with common nodes, but the one that is keeped
+            keysCommonNodes.forEach(key => {
+                if (key !== maxHeightKey) {
                     delete pathsFromSources[key];
-                    pathsFromSources[source]=newPath;
                 }
+            });
+
+            // if the highest path is a path with the source node as key,
+            // either a previous one or the new one, do the update in case of the new one
+            if (maxHeightKey === source) {
+                pathsFromSources[source] = { nodes: maxPath, height: maxHeight };
             }
         }
-    });
-    if (!processed){
-        // If no common nodes : path added on it's own
-        if(pathsFromSources[source]) throw new Error('source already in pathsFromSources, but supposed to have no common nodes');
-        pathsFromSources[source]=newPath;
     }
+
     return pathsFromSources;
 }
 
diff --git a/src/composables/__tests__/LayoutMainChain.test.ts b/src/composables/__tests__/LayoutMainChain.test.ts
index 44d2ffb0fd32cf7ca05fcfaa5b77181445c39c07..ba6b3722f5a528c8527fa821f7af597f5e88922b 100644
--- a/src/composables/__tests__/LayoutMainChain.test.ts
+++ b/src/composables/__tests__/LayoutMainChain.test.ts
@@ -460,7 +460,7 @@ describe('LayoutMainChain', () => {
                
                 // DATA
                 const pathExpected = {
-                    A: { nodes: [  'C','B','A','E','D'  ], height: 3 }
+                    A: { nodes: [ 'E','D','A','C','B'  ], height: 3 }
                 };
 
                 // TEST
@@ -487,7 +487,7 @@ describe('LayoutMainChain', () => {
 
                 // TEST
                 const result = await LayoutMainChain.getPathSourcesToTargetNode(network, sources, false ,PathType.ALL_LONGEST);
-                
+
                 // EXPECT
                 expect(DFSsourceDAGMock).toHaveBeenCalledTimes(1);
                 expect(BFSMock).toHaveBeenCalledTimes(2);
@@ -624,7 +624,7 @@ describe('LayoutMainChain', () => {
                 // BFS start : H (DFS with D)
                 BFSMock.mockReturnValueOnce([ 'H','F','E','G','D' ]);
 
-                const pathExpected = { A__D: { nodes: [ 'H','F','B','A','E','G','D' ], height: 5 } };
+                const pathExpected = { D: { nodes: [ 'H','F','E','G','D','B','A' ], height: 5 } };
 
                 // TEST
                 const result = await LayoutMainChain.getPathSourcesToTargetNode(network, sources, true ,PathType.ALL);
@@ -687,33 +687,31 @@ describe('LayoutMainChain', () => {
                 // DATA
                 sources=["A","C"];
 
-               // MOCK 
-               graphGDS={
-               adjacent:jest.fn((id: string) => {
-                   switch (id) {
-                       case 'A':
-                           return ['B'];
-                       case 'D':
-                           return ['E','F'];
-                       case 'C':
-                           return ['D'];
-                       default:
-                           return [];
-                   }
-
-               }),
-               getEdgeWeight:jest.fn(() => (1)),
-               nodes: jest.fn(() => (['A', 'B', 'C', 'D', 'E', 'F']))
-           }
-
-           networkToGDSGraphMock.mockImplementation(async ()=>{
-               return graphGDS;
-           });
-
            });
 
             test ('case with one start nodes associated with 2 targets, and one start with one target, merge = true', async () => {
-                // MOCK
+                // MOCK 
+               graphGDS={
+                adjacent:jest.fn((id: string) => {
+                    switch (id) {
+                        case 'A':
+                            return ['B'];
+                        case 'D':
+                            return ['E','F'];
+                        case 'C':
+                            return ['D'];
+                        default:
+                            return [];
+                    }
+ 
+                }),
+                getEdgeWeight:jest.fn(() => (1)),
+                nodes: jest.fn(() => (['A', 'B', 'C', 'D', 'E', 'F']))
+            }
+ 
+            networkToGDSGraphMock.mockImplementation(async ()=>{
+                return graphGDS;
+            });
                 // DFS start : A
                 DFSsourceDAGMock.mockReturnValueOnce(Promise.resolve(
                     {dfs:[
@@ -737,7 +735,7 @@ describe('LayoutMainChain', () => {
                 // BFS start : F (DFS with C)
                 BFSMock.mockReturnValueOnce([ 'F','D','C' ]);
 
-                const pathExpected =  {"A":{"nodes":["B","A"],"height":2},"C":{"nodes":["E","D","C","F"],"height":3}};
+                const pathExpected =  {"A":{"nodes":["B","A"],"height":2},"C":{"nodes":["F","D","C","E"],"height":3}};
 
                 // TEST
                 const result = await LayoutMainChain.getPathSourcesToTargetNode(network, sources, true ,PathType.ALL);
@@ -754,6 +752,128 @@ describe('LayoutMainChain', () => {
 
             });
 
+            test ('case with one start nodes associated with 2 targets, and one start with one target of the first, merge = true', async () => {
+                // MOCK 
+               graphGDS={
+                adjacent:jest.fn((id: string) => {
+                    switch (id) {
+                        case 'A':
+                            return ['D'];
+                        case 'C':
+                            return ['D','B'];
+                        default:
+                            return [];
+                    }
+ 
+                }),
+                getEdgeWeight:jest.fn(() => (1)),
+                nodes: jest.fn(() => (['A', 'B', 'C', 'D']))
+            }
+ 
+            networkToGDSGraphMock.mockImplementation(async ()=>{
+                return graphGDS;
+            });
+                // DFS start : A
+                DFSsourceDAGMock.mockReturnValueOnce(Promise.resolve(
+                    {dfs:[
+                            'A', 'D',
+                        ], 
+                        graph:graphGDS}
+                ));
+
+                // DFS start : C
+                DFSsourceDAGMock.mockReturnValueOnce(Promise.resolve(
+                    {dfs:[
+                            'C', 'D','B',
+                        ], 
+                        graph:graphGDS}
+                ));
+
+                // BFS start : D (DFS with A)
+                BFSMock.mockReturnValueOnce(['D','A' ]);
+                // BFS start : B (DFS with C)
+                BFSMock.mockReturnValueOnce([ 'B','C' ]);
+                // BFS start : D (DFS with C)
+                BFSMock.mockReturnValueOnce([ 'D','C' ]);
+
+                const pathExpected =  {"C":{"nodes":["D","C","A","B"],"height":2}};
+
+                // TEST
+                const result = await LayoutMainChain.getPathSourcesToTargetNode(network, sources, true ,PathType.ALL);
+
+                // EXPECT
+                expect(DFSsourceDAGMock).toHaveBeenCalledTimes(2);
+                expect(DFSsourceDAGMock).toHaveBeenCalledWith(expect.anything(),['A']);
+                expect(DFSsourceDAGMock).toHaveBeenLastCalledWith(expect.anything(),['C']);
+                expect(BFSMock).toHaveBeenCalledTimes(3);
+                expect(BFSMock).toHaveBeenCalledWith({"A":[],"D":["A"]}, 'D');
+                expect(BFSMock).toHaveBeenCalledWith({"C":[],"D":["C"],"B":["C"]}, 'B');
+                expect(BFSMock).toHaveBeenLastCalledWith({"C":[],"D":["C"],"B":["C"]}, 'D');
+                expect(result).toEqual(pathExpected);
+
+            });
+
+            test ('case with one start nodes associated with 2 targets, and one start with one target of the first, merge = false', async () => {
+                // MOCK 
+               graphGDS={
+                adjacent:jest.fn((id: string) => {
+                    switch (id) {
+                        case 'A':
+                            return ['D'];
+                        case 'C':
+                            return ['D','B'];
+                        default:
+                            return [];
+                    }
+ 
+                }),
+                getEdgeWeight:jest.fn(() => (1)),
+                nodes: jest.fn(() => (['A', 'B', 'C', 'D']))
+            }
+ 
+            networkToGDSGraphMock.mockImplementation(async ()=>{
+                return graphGDS;
+            });
+                // DFS start : A
+                DFSsourceDAGMock.mockReturnValueOnce(Promise.resolve(
+                    {dfs:[
+                            'A', 'D',
+                        ], 
+                        graph:graphGDS}
+                ));
+
+                // DFS start : C
+                DFSsourceDAGMock.mockReturnValueOnce(Promise.resolve(
+                    {dfs:[
+                            'C', 'D','B',
+                        ], 
+                        graph:graphGDS}
+                ));
+
+                // BFS start : D (DFS with A)
+                BFSMock.mockReturnValueOnce(['D','A' ]);
+                // BFS start : B (DFS with C)
+                BFSMock.mockReturnValueOnce([ 'B','C' ]);
+                // BFS start : D (DFS with C)
+                BFSMock.mockReturnValueOnce([ 'D','C' ]);
+
+                const pathExpected =  {"C":{"nodes":["B","C"],"height":2}};
+
+                // TEST
+                const result = await LayoutMainChain.getPathSourcesToTargetNode(network, sources, false ,PathType.ALL);
+
+                // EXPECT
+                expect(DFSsourceDAGMock).toHaveBeenCalledTimes(2);
+                expect(DFSsourceDAGMock).toHaveBeenCalledWith(expect.anything(),['A']);
+                expect(DFSsourceDAGMock).toHaveBeenLastCalledWith(expect.anything(),['C']);
+                expect(BFSMock).toHaveBeenCalledTimes(3);
+                expect(BFSMock).toHaveBeenCalledWith({"A":[],"D":["A"]}, 'D');
+                expect(BFSMock).toHaveBeenCalledWith({"C":[],"D":["C"],"B":["C"]}, 'B');
+                expect(BFSMock).toHaveBeenLastCalledWith({"C":[],"D":["C"],"B":["C"]}, 'D');
+                expect(result).toEqual(pathExpected);
+
+            });
+
 
         });