diff --git a/.github/workflows/indigo-ci.yaml b/.github/workflows/indigo-ci.yaml
index e17a2b321d..3a817238b0 100644
--- a/.github/workflows/indigo-ci.yaml
+++ b/.github/workflows/indigo-ci.yaml
@@ -19,7 +19,7 @@ jobs:
container: epmlsop/indigo-tester:latest
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -41,7 +41,7 @@ jobs:
needs: static_analysis
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -78,7 +78,7 @@ jobs:
cmake --build . --config Release --target ALL_BUILD
ctest --verbose -C Release
- name: Upload artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: indigo-libs-${{ fromJSON(env.OS_NAME_MAPPING_JSON)[matrix.os] }}-x86_64
path: dist
@@ -92,7 +92,7 @@ jobs:
needs: static_analysis
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -109,7 +109,7 @@ jobs:
cmake --build . --config Release --target ALL_BUILD
ctest --verbose -C Release
- name: Upload artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: indigo-libs-${{ fromJSON(env.OS_NAME_MAPPING_JSON)[matrix.os] }}-i386
path: dist
@@ -123,7 +123,7 @@ jobs:
needs: static_analysis
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -152,7 +152,7 @@ jobs:
cmake --build . --config Release --target all -- -j $(sysctl -n hw.logicalcpu)
# ctest --verbose # NOTE: We can't run tests until we have native ARM64 node
- name: Upload artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: indigo-libs-${{ fromJSON(env.OS_NAME_MAPPING_JSON)[matrix.os] }}-aarch64
path: dist
@@ -167,7 +167,7 @@ jobs:
container: epmlsop/indigo-tester:latest
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -178,32 +178,32 @@ jobs:
- name: Create folder for native libs
run: mkdir dist
- name: Download Linux native libs x86_64
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-libs-linux-x86_64
path: dist/
- name: Download Linux native libs aarch64
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-libs-linux-aarch64
path: dist/
- name: Download Windows native libs x86_64
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-libs-windows-x86_64
path: dist/
- name: Download Windows native libs i386
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-libs-windows-i386
path: dist/
- name: Download macOS native libs x86_64
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-libs-macos-x86_64
path: dist/
- name: Download macOS native libs aarch64
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-libs-macos-aarch64
path: dist/
@@ -216,31 +216,41 @@ jobs:
cmake .. -DBUILD_INDIGO=OFF -DBUILD_INDIGO_UTILS=OFF -DBUILD_BINGO=OFF -DBUILD_BINGO_ELASTIC=OFF
cmake --build . --config Release --target indigo-${{ matrix.wrapper }}
- name: Upload native shared libs
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
- name: indigo-native-shared-libs
+ name: indigo-native-shared-libs-${{ matrix.wrapper }}
path: |
dist/lib
- name: Upload Python wrappers
if: ${{ matrix.wrapper == 'python' }}
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: indigo-python
path: |
dist/*.whl
- name: Upload Java wrappers
if: ${{ matrix.wrapper == 'java' }}
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: indigo-java
path: dist/*.jar
- name: Upload .NET wrappers
if: ${{ matrix.wrapper == 'dotnet' }}
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: indigo-dotnet
path: dist/*.nupkg
+ merge_indigo_wrappers:
+ runs-on: ubuntu-latest
+ needs: build_indigo_wrappers
+ steps:
+ - name: Merge native shared libs
+ uses: actions/upload-artifact/merge@v4
+ with:
+ name: indigo-native-shared-libs
+ pattern: indigo-native-shared-libs-*
+
test_indigo_python_x86_64:
timeout-minutes: 60
strategy:
@@ -248,10 +258,10 @@ jobs:
matrix:
os: [ macos-13, ubuntu-latest, windows-latest ]
runs-on: ${{ matrix.os }}
- needs: build_indigo_wrappers
+ needs: merge_indigo_wrappers
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -262,7 +272,7 @@ jobs:
- name: Create folder for native libs
run: mkdir dist
- name: Download wrappers
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-python
path: dist/
@@ -281,7 +291,7 @@ jobs:
run: python3 -Wignore api/tests/integration/test.py -t 1 -j junit_report.xml
- name: Publish Test Report
if: always()
- uses: mikepenz/action-junit-report@v3
+ uses: mikepenz/action-junit-report@v4
with:
report_paths: 'junit_report.xml'
github_token: ${{ secrets.GITHUB_TOKEN }}
@@ -294,10 +304,10 @@ jobs:
matrix:
os: [ ubuntu-latest ]
runs-on: ${{ matrix.os }}
- needs: build_indigo_wrappers
+ needs: merge_indigo_wrappers
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -308,7 +318,7 @@ jobs:
- name: Create folder for native libs
run: mkdir dist
- name: Download wrappers
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-python
path: dist/
@@ -327,7 +337,7 @@ jobs:
python3 api/tests/integration/test.py -p basic/basic.py -t 1 -j junit_report.xml
- name: Publish Test Report
if: always()
- uses: mikepenz/action-junit-report@v3
+ uses: mikepenz/action-junit-report@v4
with:
report_paths: 'junit_report.xml'
github_token: ${{ secrets.GITHUB_TOKEN }}
@@ -340,10 +350,10 @@ jobs:
matrix:
os: [ windows-latest ]
runs-on: ${{ matrix.os }}
- needs: build_indigo_wrappers
+ needs: merge_indigo_wrappers
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -354,7 +364,7 @@ jobs:
- name: Create folder for native libs
run: mkdir dist
- name: Download wrappers
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-python
path: dist/
@@ -372,7 +382,7 @@ jobs:
run: python api/tests/integration/test.py -t 1 -p basic/basic.py -j junit_report.xml
- name: Publish Test Report
if: always()
- uses: mikepenz/action-junit-report@v3
+ uses: mikepenz/action-junit-report@v4
with:
report_paths: 'junit_report.xml'
github_token: ${{ secrets.GITHUB_TOKEN }}
@@ -385,10 +395,10 @@ jobs:
matrix:
os: [ macos-13, ubuntu-latest, windows-latest ]
runs-on: ${{ matrix.os }}
- needs: build_indigo_wrappers
+ needs: merge_indigo_wrappers
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -399,7 +409,7 @@ jobs:
- name: Create folder for native libs
run: mkdir dist
- name: Download wrappers
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-java
path: dist/
@@ -413,7 +423,7 @@ jobs:
java -Xss4m -jar jython.jar api/tests/integration/test.py -t 1 -j junit_report.xml
- name: Publish Test Report
if: always()
- uses: mikepenz/action-junit-report@v3
+ uses: mikepenz/action-junit-report@v4
with:
report_paths: 'junit_report.xml'
github_token: ${{ secrets.GITHUB_TOKEN }}
@@ -426,10 +436,10 @@ jobs:
matrix:
os: [ ubuntu-latest ]
runs-on: ${{ matrix.os }}
- needs: build_indigo_wrappers
+ needs: merge_indigo_wrappers
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -440,7 +450,7 @@ jobs:
- name: Create folder for native libs
run: mkdir dist
- name: Download wrappers
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-java
path: dist/
@@ -459,7 +469,7 @@ jobs:
java -Xss4m -jar jython.jar api/tests/integration/test.py -p basic/basic.py -t 1 -j junit_report.xml
- name: Publish Test Report
if: always()
- uses: mikepenz/action-junit-report@v3
+ uses: mikepenz/action-junit-report@v4
with:
report_paths: 'junit_report.xml'
github_token: ${{ secrets.GITHUB_TOKEN }}
@@ -472,10 +482,10 @@ jobs:
matrix:
os: [ windows-latest ]
runs-on: ${{ matrix.os }}
- needs: build_indigo_wrappers
+ needs: merge_indigo_wrappers
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -486,7 +496,7 @@ jobs:
- name: Create folder for native libs
run: mkdir dist
- name: Download wrappers
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-java
path: dist/
@@ -505,7 +515,7 @@ jobs:
java -Xss4m -jar jython.jar api/tests/integration/test.py -t 1 -p basic/basic.py -j junit_report.xml
- name: Publish Test Report
if: always()
- uses: mikepenz/action-junit-report@v3
+ uses: mikepenz/action-junit-report@v4
with:
report_paths: 'junit_report.xml'
github_token: ${{ secrets.GITHUB_TOKEN }}
@@ -519,10 +529,10 @@ jobs:
# os: [ macos-13, ubuntu-latest, windows-latest ]
os: [ macos-13, windows-latest ]
runs-on: ${{ matrix.os }}
- needs: build_indigo_wrappers
+ needs: merge_indigo_wrappers
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -533,7 +543,7 @@ jobs:
- name: Create folder for native libs
run: mkdir dist
- name: Download wrappers
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-dotnet
path: dist/
@@ -592,7 +602,7 @@ jobs:
run: ./IronPython/net462/ipy.exe api/tests/integration/test.py -t 1 -j junit_report.xml
- name: Publish Test Report
if: always()
- uses: mikepenz/action-junit-report@v3
+ uses: mikepenz/action-junit-report@v4
with:
report_paths: 'junit_report.xml'
github_token: ${{ secrets.GITHUB_TOKEN }}
@@ -605,10 +615,10 @@ jobs:
matrix:
os: [ windows-latest ]
runs-on: ${{ matrix.os }}
- needs: build_indigo_wrappers
+ needs: merge_indigo_wrappers
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -619,7 +629,7 @@ jobs:
- name: Create folder for native libs
run: mkdir dist
- name: Download wrappers
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-dotnet
path: dist/
@@ -644,7 +654,7 @@ jobs:
run: ./IronPython/net462/ipy32.exe api/tests/integration/test.py -t 1 -p basic/basic.py -j junit_report.xml
- name: Publish Test Report
if: always()
- uses: mikepenz/action-junit-report@v3
+ uses: mikepenz/action-junit-report@v4
with:
report_paths: 'junit_report.xml'
github_token: ${{ secrets.GITHUB_TOKEN }}
@@ -656,9 +666,9 @@ jobs:
fail-fast: false
matrix:
python-version: [ '3.9', '3.10' ]
- needs: build_indigo_wrappers
+ needs: merge_indigo_wrappers
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
@@ -668,7 +678,7 @@ jobs:
- name: Create folder for native libs
run: mkdir dist
- name: Download wrappers
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-python
path: dist/
@@ -695,21 +705,31 @@ jobs:
run: pytest tests
working-directory: bingo/bingo-elastic/python
- name: Upload artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
- name: bingo-elastic-python
+ name: bingo-elastic-python-${{ matrix.python-version }}
path: dist
+ merge_bingo_elastic_python_linux_x86_64:
+ runs-on: ubuntu-latest
+ needs: [ test_bingo_elastic_python_linux_x86_64 ]
+ steps:
+ - name: Merge artifacts
+ uses: actions/upload-artifact/merge@v4
+ with:
+ name: bingo-elastic-python
+ pattern: bingo-elastic-python-*
+
test_bingo_elastic_java_linux_x86_64:
strategy:
fail-fast: false
matrix:
java-version: [ 1.8, 1.11 ]
runs-on: ubuntu-latest
- needs: build_indigo_wrappers
+ needs: merge_indigo_wrappers
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -724,7 +744,7 @@ jobs:
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2
- name: Download wrappers
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-java
path: dist/
@@ -743,7 +763,7 @@ jobs:
shell: msys2 {0}
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -777,13 +797,13 @@ jobs:
# python api/tests/integration/test.py -t 1 -j junit_report.xml -platform mingw
# - name: Publish Test Report
# if: always()
-# uses: mikepenz/action-junit-report@v3
+# uses: mikepenz/action-junit-report@v4
# with:
# report_paths: 'junit_report.xml'
# github_token: ${{ secrets.GITHUB_TOKEN }}
# check_name: "windows-mingw_python_test_report"
- name: Upload artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: indigo-libs-windows-mingw-x86_64
path: dist
@@ -794,7 +814,7 @@ jobs:
container: emscripten/emsdk:3.1.60
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -815,7 +835,7 @@ jobs:
emcmake cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build . --config Release --target indigo-ketcher-package -- -j $(nproc)
- name: Upload artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: indigo-ketcher
path: dist/indigo-ketcher*.tgz
@@ -826,7 +846,7 @@ jobs:
container: emscripten/emsdk:3.1.60
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -847,7 +867,7 @@ jobs:
emcmake cmake .. -DCMAKE_BUILD_TYPE=Release -DRENDER_ENABLE_CJK=ON
cmake --build . --config Release --target indigo-ketcher-package -- -j $(nproc)
- name: Upload artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: indigo-ketcher-cjk
path: dist/indigo-ketcher*.tgz
@@ -861,7 +881,7 @@ jobs:
needs: static_analysis
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -898,7 +918,7 @@ jobs:
cmake --build . --config Release --target ALL_BUILD
ctest --verbose -C Release
- name: Upload artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: indigo-utils-${{ fromJSON(env.OS_NAME_MAPPING_JSON)[matrix.os] }}-x86_64
path: dist/utils
@@ -908,7 +928,7 @@ jobs:
needs: static_analysis
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -928,7 +948,7 @@ jobs:
cmake --build . --config Release --target package-bingo-oracle -- -j $(nproc)
"
- name: Upload artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: bingo-oracle-linux-x86_64
path: dist/bingo-oracle*.tgz
@@ -941,7 +961,7 @@ jobs:
shell: msys2 {0}
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -960,7 +980,7 @@ jobs:
cmake .. -G "MinGW Makefiles" -DBUILD_BINGO_ORACLE=ON -DBUILD_BINGO_SQLSERVER=OFF -DBUILD_BINGO_POSTGRES=OFF -DBUILD_INDIGO=OFF -DBUILD_INDIGO_WRAPPERS=OFF -DBUILD_INDIGO_UTILS=OFF -DBUILD_BINGO_ELASTIC=OFF
cmake --build . --config Release --target package-bingo-oracle -- -j $(nproc)
- name: Upload artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: bingo-oracle-windows-mingw-x86_64
path: dist/bingo-oracle*.zip
@@ -970,7 +990,7 @@ jobs:
needs: static_analysis
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -985,7 +1005,7 @@ jobs:
cmake .. -DBUILD_BINGO_ORACLE=ON -DBUILD_BINGO_SQLSERVER=OFF -DBUILD_BINGO_POSTGRES=OFF -DBUILD_INDIGO=OFF -DBUILD_INDIGO_WRAPPERS=OFF -DBUILD_INDIGO_UTILS=OFF -DBUILD_BINGO_ELASTIC=OFF
cmake --build . --config Release --target package-bingo-oracle
- name: Upload artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: bingo-oracle-windows-msvc-x86_64
path: dist/bingo-oracle*.zip
@@ -999,7 +1019,7 @@ jobs:
needs: static_analysis
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -1030,7 +1050,7 @@ jobs:
cmake --build . --config Release --target package-bingo-postgres -- -j $(nproc)
"
- name: Upload artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: bingo-postgres-${{ matrix.postgres_major_version }}-linux-x86_64
path: dist/bingo-postgres*.tgz
@@ -1059,7 +1079,7 @@ jobs:
run: docker push epmlsop/bingo-postgres:${{ matrix.postgres_major_version }}-latest
- name: Publish Test Report
if: always()
- uses: mikepenz/action-junit-report@v3
+ uses: mikepenz/action-junit-report@v4
with:
report_paths: 'bingo/tests/junit_report.xml'
github_token: ${{ secrets.GITHUB_TOKEN }}
@@ -1074,7 +1094,7 @@ jobs:
needs: static_analysis
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -1096,7 +1116,7 @@ jobs:
cmake .. -DBUILD_BINGO_POSTGRES=ON -DBUILD_BINGO_SQLSERVER=OFF -DBUILD_BINGO_ORACLE=OFF -DBUILD_INDIGO=OFF -DBUILD_INDIGO_WRAPPERS=OFF -DBUILD_INDIGO_UTILS=OFF -DBUILD_BINGO_ELASTIC=OFF -DPostgreSQL_ROOT="$(resolve-path $pwd/../pgsql)"
cmake --build . --config Release --target package-bingo-postgres
- name: Upload artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: bingo-postgres-${{ matrix.postgres_major_version }}-windows-x86_64
path: dist/bingo-postgres*.zip
@@ -1110,7 +1130,7 @@ jobs:
needs: static_analysis
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -1131,7 +1151,7 @@ jobs:
cmake .. -DBUILD_BINGO_POSTGRES=ON -DBUILD_BINGO_SQLSERVER=OFF -DBUILD_BINGO_ORACLE=OFF -DBUILD_INDIGO=OFF -DBUILD_INDIGO_WRAPPERS=OFF -DBUILD_INDIGO_UTILS=OFF -DBUILD_BINGO_ELASTIC=OFF -DPostgreSQL_ROOT="$(dirname $PWD)/pgsql" -DPostgreSQL_ADDITIONAL_VERSIONS=${{ matrix.postgres_major_version }}
cmake --build . --config Release --target package-bingo-postgres
- name: Upload artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: bingo-postgres-${{ matrix.postgres_major_version }}-macos-x86_64
path: dist/bingo-postgres*.tgz
@@ -1145,7 +1165,7 @@ jobs:
needs: static_analysis
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -1160,7 +1180,7 @@ jobs:
cmake .. -DBUILD_BINGO_SQLSERVER=ON -DBUILD_BINGO_POSTGRES=OFF -DBUILD_BINGO_ORACLE=OFF -DBUILD_INDIGO=OFF -DBUILD_INDIGO_WRAPPERS=OFF -DBUILD_INDIGO_UTILS=OFF -DBUILD_BINGO_ELASTIC=OFF
cmake --build . --config Release --target package-bingo-sqlserver
- name: Upload artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: bingo-sqlserver-${{ matrix.os }}-x86_64
path: dist/bingo-sqlserver*.zip
@@ -1168,11 +1188,11 @@ jobs:
publish_indigo_to_pypi:
if: startsWith(github.ref, 'refs/tags/indigo-')
runs-on: ubuntu-latest
- needs: [test_indigo_python_x86_64, test_indigo_java_x86_64, test_indigo_dotnet_x86_64, test_indigo_python_i386, test_indigo_java_i386, test_indigo_dotnet_i386, test_indigo_python_aarch64, test_indigo_java_aarch64, test_bingo_elastic_python_linux_x86_64, test_bingo_elastic_java_linux_x86_64, build_indigo_ketcher]
+ needs: [test_indigo_python_x86_64, test_indigo_java_x86_64, test_indigo_dotnet_x86_64, test_indigo_python_i386, test_indigo_java_i386, test_indigo_dotnet_i386, test_indigo_python_aarch64, test_indigo_java_aarch64, merge_bingo_elastic_python_linux_x86_64, test_bingo_elastic_java_linux_x86_64, build_indigo_ketcher]
container: epmlsop/indigo-tester:latest
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -1183,17 +1203,17 @@ jobs:
- name: Create folder for native libs
run: mkdir -p dist/lib
- name: Download native shared libraries
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-native-shared-libs
path: dist/lib
- name: Download Python wheels
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-python
path: dist/
- name: Download bingo-elastic-python
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: bingo-elastic-python
path: dist/
@@ -1206,11 +1226,11 @@ jobs:
publish_indigo_to_nuget:
if: startsWith(github.ref, 'refs/tags/indigo-')
runs-on: ubuntu-latest
- needs: [test_indigo_python_x86_64, test_indigo_java_x86_64, test_indigo_dotnet_x86_64, test_indigo_python_i386, test_indigo_java_i386, test_indigo_dotnet_i386, test_indigo_python_aarch64, test_indigo_java_aarch64, test_bingo_elastic_python_linux_x86_64, test_bingo_elastic_java_linux_x86_64, build_indigo_ketcher]
+ needs: [test_indigo_python_x86_64, test_indigo_java_x86_64, test_indigo_dotnet_x86_64, test_indigo_python_i386, test_indigo_java_i386, test_indigo_dotnet_i386, test_indigo_python_aarch64, test_indigo_java_aarch64, merge_bingo_elastic_python_linux_x86_64, test_bingo_elastic_java_linux_x86_64, build_indigo_ketcher]
container: epmlsop/indigo-tester:latest
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -1221,12 +1241,12 @@ jobs:
- name: Create folder for native libs
run: mkdir -p dist/lib
- name: Download native shared libraries
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-native-shared-libs
path: dist/lib
- name: Download .NET nupkg
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-dotnet
path: dist/
@@ -1238,11 +1258,11 @@ jobs:
publish_indigo_to_npm:
if: startsWith(github.ref, 'refs/tags/indigo-')
runs-on: ubuntu-latest
- needs: [test_indigo_python_x86_64, test_indigo_java_x86_64, test_indigo_dotnet_x86_64, test_indigo_python_i386, test_indigo_java_i386, test_indigo_dotnet_i386, test_indigo_python_aarch64, test_indigo_java_aarch64, test_bingo_elastic_python_linux_x86_64, test_bingo_elastic_java_linux_x86_64, build_indigo_ketcher]
+ needs: [test_indigo_python_x86_64, test_indigo_java_x86_64, test_indigo_dotnet_x86_64, test_indigo_python_i386, test_indigo_java_i386, test_indigo_dotnet_i386, test_indigo_python_aarch64, test_indigo_java_aarch64, merge_bingo_elastic_python_linux_x86_64, test_bingo_elastic_java_linux_x86_64, build_indigo_ketcher]
container: epmlsop/indigo-tester:latest
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -1253,12 +1273,12 @@ jobs:
- name: Create folder for native libs
run: mkdir -p dist/lib
- name: Download native shared libraries
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-native-shared-libs
path: dist/lib
- name: Download indigo-ketcher NPM package
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-ketcher
path: dist/
@@ -1275,11 +1295,11 @@ jobs:
publish_indigo_to_maven:
if: startsWith(github.ref, 'refs/tags/indigo-')
runs-on: ubuntu-latest
- needs: [test_indigo_python_x86_64, test_indigo_java_x86_64, test_indigo_dotnet_x86_64, test_indigo_python_i386, test_indigo_java_i386, test_indigo_dotnet_i386, test_indigo_python_aarch64, test_indigo_java_aarch64, test_bingo_elastic_python_linux_x86_64, test_bingo_elastic_java_linux_x86_64, build_indigo_ketcher]
+ needs: [test_indigo_python_x86_64, test_indigo_java_x86_64, test_indigo_dotnet_x86_64, test_indigo_python_i386, test_indigo_java_i386, test_indigo_dotnet_i386, test_indigo_python_aarch64, test_indigo_java_aarch64, merge_bingo_elastic_python_linux_x86_64, test_bingo_elastic_java_linux_x86_64, build_indigo_ketcher]
container: epmlsop/indigo-tester:latest
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -1290,7 +1310,7 @@ jobs:
- name: Create folder for native libs
run: mkdir -p dist/lib
- name: Download native shared libraries
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-native-shared-libs
path: dist/lib
@@ -1318,10 +1338,10 @@ jobs:
build_test_publish_indigo_service_old:
timeout-minutes: 60
runs-on: ubuntu-latest
- needs: build_indigo_wrappers
+ needs: merge_indigo_wrappers
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -1330,7 +1350,7 @@ jobs:
git config --global --add safe.directory '*'
git fetch --tags -f
- name: Download wrappers
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-python
path: utils/indigo-service/backend/lib/
@@ -1375,10 +1395,10 @@ jobs:
build_test_publish_indigo_service_new:
timeout-minutes: 60
runs-on: ubuntu-latest
- needs: build_indigo_wrappers
+ needs: merge_indigo_wrappers
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 500
@@ -1387,7 +1407,7 @@ jobs:
git config --global --add safe.directory '*'
git fetch --tags -f
- name: Download wrappers
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: indigo-python
path: api/http/
diff --git a/api/tests/integration/ref/formats/ket_to_ket.py.out b/api/tests/integration/ref/formats/ket_to_ket.py.out
index 6cc65d74c2..0296b821cd 100644
--- a/api/tests/integration/ref/formats/ket_to_ket.py.out
+++ b/api/tests/integration/ref/formats/ket_to_ket.py.out
@@ -6,3 +6,4 @@ ambiguous_monomer.ket mol loadQueryMolecule: SUCCEED
monomer_shape.ket doc loadKetDocument: SUCCEED
monomer_shape.ket mol loadMolecule: SUCCEED
monomer_shape.ket mol loadQueryMolecule: SUCCEED
+multi_merge4.ket:SUCCEED
diff --git a/api/tests/integration/ref/formats/ket_to_rdf.py.out b/api/tests/integration/ref/formats/ket_to_rdf.py.out
index 9ad5628411..a7714364ce 100644
--- a/api/tests/integration/ref/formats/ket_to_rdf.py.out
+++ b/api/tests/integration/ref/formats/ket_to_rdf.py.out
@@ -1,6 +1,12 @@
*** KET to RDF ***
2404-metadata_detect.rdf:SUCCEED
multi.rdf:SUCCEED
+multi_merge1.rdf:SUCCEED
+multi_merge2.rdf:SUCCEED
+multi_merge3.rdf:SUCCEED
+multi_merge4.rdf:SUCCEED
+multi_merge5.rdf:SUCCEED
+multi_merge6.rdf:SUCCEED
pathway1.rdf:SUCCEED
pathway10.rdf:SUCCEED
pathway11.rdf:SUCCEED
@@ -13,3 +19,5 @@ pathway6.rdf:SUCCEED
pathway7.rdf:SUCCEED
pathway8.rdf:SUCCEED
pathway9.rdf:SUCCEED
+pathway_merge1.rdf:SUCCEED
+pathway_merge2.rdf:SUCCEED
diff --git a/api/tests/integration/ref/formats/ket_to_rxn.py.out b/api/tests/integration/ref/formats/ket_to_rxn.py.out
new file mode 100644
index 0000000000..eb132d964d
--- /dev/null
+++ b/api/tests/integration/ref/formats/ket_to_rxn.py.out
@@ -0,0 +1,11 @@
+*** KET to RXN ***
+merge_test1.rxn:SUCCEED
+merge_test1a.rxn:SUCCEED
+merge_test2.rxn:SUCCEED
+merge_test2a.rxn:SUCCEED
+merge_test3.rxn:SUCCEED
+merge_test3a.rxn:SUCCEED
+merge_test4.rxn:SUCCEED
+merge_test5.rxn:SUCCEED
+merge_test6.rxn:SUCCEED
+merge_test7.rxn:SUCCEED
diff --git a/api/tests/integration/tests/formats/ket_cdxml.py b/api/tests/integration/tests/formats/ket_cdxml.py
index 25eca0c543..a12beca075 100644
--- a/api/tests/integration/tests/formats/ket_cdxml.py
+++ b/api/tests/integration/tests/formats/ket_cdxml.py
@@ -98,8 +98,8 @@ def find_diff(a, b):
print(getIndigoExceptionText(e))
raise SystemExit
cdxml_text = ket.cdxml()
- with open(os.path.join(ref_path, filename) + ".cdxml", "w") as file:
- file.write(cdxml_text)
+ # with open(os.path.join(ref_path, filename) + ".cdxml", "w") as file:
+ # file.write(cdxml_text)
indigo.loadMolecule(
cdxml_text
diff --git a/api/tests/integration/tests/formats/ket_to_ket.py b/api/tests/integration/tests/formats/ket_to_ket.py
index a3bd406ee4..b7307984c6 100644
--- a/api/tests/integration/tests/formats/ket_to_ket.py
+++ b/api/tests/integration/tests/formats/ket_to_ket.py
@@ -22,6 +22,7 @@ def find_diff(a, b):
root = joinPathPy("molecules/", __file__)
ref_path = joinPathPy("ref/", __file__)
+root_rea = joinPathPy("reactions/", __file__)
files = [
"images",
@@ -73,3 +74,25 @@ def check_res(filename, format, ket_ref, ket):
# file.write(mol.json())
ket = mol.json()
check_res(filename, format + " " + loader.__name__, ket_ref, ket)
+
+files = [
+ "multi_merge4",
+]
+
+files.sort()
+for filename in files:
+ rea = indigo.loadReactionFromFile(
+ os.path.join(root_rea, filename + ".ket")
+ )
+
+ # with open(os.path.join(ref_path, filename) + ".ket", "w") as file:
+ # file.write(rea.json())
+ with open(os.path.join(ref_path, filename) + ".ket", "r") as file:
+ ket_ref = file.read()
+ ket = rea.json()
+ diff = find_diff(ket_ref, ket)
+ if not diff:
+ print(filename + ".ket:SUCCEED")
+ else:
+ print(filename + ".ket:FAILED")
+ print(diff)
diff --git a/api/tests/integration/tests/formats/ket_to_rdf.py b/api/tests/integration/tests/formats/ket_to_rdf.py
index 7c3f8aec7b..b1a53d441d 100644
--- a/api/tests/integration/tests/formats/ket_to_rdf.py
+++ b/api/tests/integration/tests/formats/ket_to_rdf.py
@@ -39,6 +39,14 @@ def find_diff(a, b):
"pathway10",
"pathway11",
"pathway12",
+ "pathway_merge1",
+ "pathway_merge2",
+ "multi_merge1",
+ "multi_merge2",
+ "multi_merge3",
+ "multi_merge4",
+ "multi_merge5",
+ "multi_merge6",
]
files.sort()
@@ -64,7 +72,7 @@ def find_diff(a, b):
rdf = buffer.toString()
# with open(os.path.join(ref_path, filename) + ".rdf", "w") as file:
- # file.write(rdf)
+ # file.write(rdf)
with open(os.path.join(ref_path, filename) + ".rdf", "r") as file:
rdf_ref = file.read()
diff --git a/api/tests/integration/tests/formats/ket_to_rxn.py b/api/tests/integration/tests/formats/ket_to_rxn.py
new file mode 100644
index 0000000000..b17d50a7bb
--- /dev/null
+++ b/api/tests/integration/tests/formats/ket_to_rxn.py
@@ -0,0 +1,54 @@
+import difflib
+import os
+import sys
+
+
+def find_diff(a, b):
+ return "\n".join(difflib.unified_diff(a.splitlines(), b.splitlines()))
+
+
+sys.path.append(
+ os.path.normpath(
+ os.path.join(os.path.abspath(__file__), "..", "..", "..", "common")
+ )
+)
+from env_indigo import Indigo, joinPathPy # noqa
+
+indigo = Indigo()
+indigo.setOption("json-saving-pretty", True)
+indigo.setOption("ignore-stereochemistry-errors", True)
+indigo.setOption("molfile-saving-skip-date", True)
+
+print("*** KET to RXN ***")
+
+root = joinPathPy("reactions/", __file__)
+ref_path = joinPathPy("ref/", __file__)
+
+files = [
+ "merge_test1",
+ "merge_test1a",
+ "merge_test2",
+ "merge_test2a",
+ "merge_test3",
+ "merge_test3a",
+ "merge_test4",
+ "merge_test5",
+ "merge_test6",
+ "merge_test7",
+]
+
+files.sort()
+for filename in files:
+ rea = indigo.loadReactionFromFile(os.path.join(root, filename + ".ket"))
+
+ # with open(os.path.join(ref_path, filename) + ".rxn", "w") as file:
+ # file.write(rea.rxnfile())
+ with open(os.path.join(ref_path, filename) + ".rxn", "r") as file:
+ rxn_ref = file.read()
+ rxn = rea.rxnfile()
+ diff = find_diff(rxn_ref, rxn)
+ if not diff:
+ print(filename + ".rxn:SUCCEED")
+ else:
+ print(filename + ".rxn:FAILED")
+ print(diff)
diff --git a/api/tests/integration/tests/formats/reactions/ket_retro_arrow.ket b/api/tests/integration/tests/formats/reactions/ket_retro_arrow.ket
index 20893f3cee..f0d8784d07 100644
--- a/api/tests/integration/tests/formats/reactions/ket_retro_arrow.ket
+++ b/api/tests/integration/tests/formats/reactions/ket_retro_arrow.ket
@@ -31,17 +31,9 @@
"type": "molecule",
"atoms": [
{
- "label": "C",
- "location": [
- 1.366025,
- -0.75,
- 0.0
- ]
- },
- {
- "label": "C",
+ "label": "O",
"location": [
- 1.366025,
+ 5.232051,
0.25,
0.0
]
@@ -49,16 +41,16 @@
{
"label": "C",
"location": [
- 0.5,
- 0.75,
+ 6.098076,
+ -0.25,
0.0
]
},
{
- "label": "N",
+ "label": "O",
"location": [
- 2.232051,
- 0.75,
+ 6.964102,
+ 0.25,
0.0
]
}
@@ -77,13 +69,6 @@
1,
2
]
- },
- {
- "type": 1,
- "atoms": [
- 1,
- 3
- ]
}
]
},
@@ -91,9 +76,17 @@
"type": "molecule",
"atoms": [
{
- "label": "O",
+ "label": "C",
"location": [
- 5.232051,
+ 1.366025,
+ -0.75,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 1.366025,
0.25,
0.0
]
@@ -101,16 +94,16 @@
{
"label": "C",
"location": [
- 6.098076,
- -0.25,
+ 0.5,
+ 0.75,
0.0
]
},
{
- "label": "O",
+ "label": "N",
"location": [
- 6.964102,
- 0.25,
+ 2.232051,
+ 0.75,
0.0
]
}
@@ -129,6 +122,13 @@
1,
2
]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
}
]
}
diff --git a/api/tests/integration/tests/formats/reactions/merge_test1.ket b/api/tests/integration/tests/formats/reactions/merge_test1.ket
new file mode 100644
index 0000000000..d37bfdf3c5
--- /dev/null
+++ b/api/tests/integration/tests/formats/reactions/merge_test1.ket
@@ -0,0 +1,182 @@
+{
+ "root": {
+ "nodes": [
+ {
+ "$ref": "mol0"
+ },
+ {
+ "$ref": "mol1"
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 13.975000000000001,
+ "y": -9.850000000000001,
+ "z": 0
+ },
+ {
+ "x": 16.62511792190461,
+ "y": -9.850000000000001,
+ "z": 0
+ }
+ ]
+ }
+ }
+ ],
+ "connections": [],
+ "templates": []
+ },
+ "mol0": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "N",
+ "location": [
+ 9.9,
+ -10,
+ 0
+ ],
+ "charge": 1
+ },
+ {
+ "label": "C",
+ "location": [
+ 9.9,
+ -9,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 10.76602540378444,
+ -8.5,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 8.9,
+ -10,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 8.033974596215561,
+ -9.5,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 9.9,
+ -11,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 9.033974596215561,
+ -11.5,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 10.9,
+ -10,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 11.607106781186548,
+ -10.707106781186548,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 5
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 5,
+ 6
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 7
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 7,
+ 8
+ ]
+ }
+ ]
+ },
+ "mol1": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 12.525,
+ -9.9,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/api/tests/integration/tests/formats/reactions/merge_test1a.ket b/api/tests/integration/tests/formats/reactions/merge_test1a.ket
new file mode 100644
index 0000000000..e6c734e9aa
--- /dev/null
+++ b/api/tests/integration/tests/formats/reactions/merge_test1a.ket
@@ -0,0 +1,182 @@
+{
+ "root": {
+ "nodes": [
+ {
+ "$ref": "mol0"
+ },
+ {
+ "$ref": "mol1"
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 13.72051270189222,
+ "y": -9.650000000000004,
+ "z": 0
+ },
+ {
+ "x": 16.370630623796828,
+ "y": -9.650000000000004,
+ "z": 0
+ }
+ ]
+ }
+ }
+ ],
+ "connections": [],
+ "templates": []
+ },
+ "mol0": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "N",
+ "location": [
+ 20.095512701892222,
+ -9.850000000000001,
+ 0
+ ],
+ "charge": 1
+ },
+ {
+ "label": "C",
+ "location": [
+ 20.095512701892222,
+ -8.850000000000001,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 20.96153810567666,
+ -8.350000000000001,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 19.095512701892222,
+ -9.850000000000001,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 18.229487298107784,
+ -9.350000000000001,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 20.095512701892222,
+ -10.850000000000001,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 19.229487298107784,
+ -11.350000000000001,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 21.095512701892222,
+ -9.850000000000001,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 21.80261948307877,
+ -10.55710678118655,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 5
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 5,
+ 6
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 7
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 7,
+ 8
+ ]
+ }
+ ]
+ },
+ "mol1": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 22.72051270189222,
+ -9.750000000000002,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/api/tests/integration/tests/formats/reactions/merge_test2.ket b/api/tests/integration/tests/formats/reactions/merge_test2.ket
new file mode 100644
index 0000000000..952cb5bd37
--- /dev/null
+++ b/api/tests/integration/tests/formats/reactions/merge_test2.ket
@@ -0,0 +1,236 @@
+{
+ "root": {
+ "nodes": [
+ {
+ "$ref": "mol0"
+ },
+ {
+ "$ref": "mol1"
+ },
+ {
+ "$ref": "mol2"
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 9.375,
+ "y": -8.55,
+ "z": 0
+ },
+ {
+ "x": 11.825127547700324,
+ "y": -8.55,
+ "z": 0
+ }
+ ]
+ }
+ }
+ ],
+ "connections": [],
+ "templates": []
+ },
+ "mol0": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 8.45720745473898,
+ -9.02254874346472,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 8.45350411466491,
+ -8.027451256535281,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 7.445294802067824,
+ -9.009637098341615,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 7.442792545261021,
+ -8.027451256535281,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol1": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 13.532207454738979,
+ -9.12254874346472,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 13.52850411466491,
+ -8.12745125653528,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.520294802067824,
+ -9.109637098341615,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.517792545261022,
+ -8.12745125653528,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol2": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 13.507207454738978,
+ -7.647548743464719,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 13.50350411466491,
+ -6.652451256535281,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.495294802067825,
+ -7.634637098341615,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.492792545261022,
+ -6.652451256535281,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/api/tests/integration/tests/formats/reactions/merge_test2a.ket b/api/tests/integration/tests/formats/reactions/merge_test2a.ket
new file mode 100644
index 0000000000..02ad1c3262
--- /dev/null
+++ b/api/tests/integration/tests/formats/reactions/merge_test2a.ket
@@ -0,0 +1,251 @@
+{
+ "root": {
+ "nodes": [
+ {
+ "$ref": "mol0"
+ },
+ {
+ "$ref": "mol1"
+ },
+ {
+ "$ref": "mol2"
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 17.8375,
+ "y": -11.137500000000003,
+ "z": 0
+ },
+ {
+ "x": 20.287627547700325,
+ "y": -11.137500000000003,
+ "z": 0
+ }
+ ]
+ }
+ }
+ ],
+ "connections": [],
+ "templates": []
+ },
+ "mol0": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 21.96970745473898,
+ -11.66004874346472,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 21.96600411466491,
+ -10.664951256535282,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 20.957794802067827,
+ -11.647137098341616,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 20.95529254526102,
+ -10.664951256535282,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ],
+ "stereoFlagPosition": {
+ "x": 21.96970745473898,
+ "y": 9.664951256535282,
+ "z": 0
+ }
+ },
+ "mol1": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 16.969707454738984,
+ -11.410048743464719,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 16.966004114664916,
+ -10.41495125653528,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 15.957794802067825,
+ -11.397137098341615,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 15.955292545261026,
+ -10.41495125653528,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ],
+ "stereoFlagPosition": {
+ "x": 16.969707454738984,
+ "y": 9.41495125653528,
+ "z": 0
+ }
+ },
+ "mol2": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 16.944707454738978,
+ -9.935048743464717,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 16.94100411466491,
+ -8.93995125653528,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 15.932794802067827,
+ -9.922137098341613,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 15.930292545261024,
+ -8.93995125653528,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ],
+ "stereoFlagPosition": {
+ "x": 16.944707454738978,
+ "y": 7.939951256535281,
+ "z": 0
+ }
+ }
+}
\ No newline at end of file
diff --git a/api/tests/integration/tests/formats/reactions/merge_test3.ket b/api/tests/integration/tests/formats/reactions/merge_test3.ket
new file mode 100644
index 0000000000..03320530c0
--- /dev/null
+++ b/api/tests/integration/tests/formats/reactions/merge_test3.ket
@@ -0,0 +1,344 @@
+{
+ "root": {
+ "nodes": [
+ {
+ "$ref": "mol0"
+ },
+ {
+ "$ref": "mol1"
+ },
+ {
+ "$ref": "mol2"
+ },
+ {
+ "$ref": "mol3"
+ },
+ {
+ "$ref": "mol4"
+ },
+ {
+ "$ref": "mol5"
+ },
+ {
+ "$ref": "mol6"
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 13.575000000000001,
+ "y": -7.800000000000001,
+ "z": 0
+ },
+ {
+ "x": 16.150000000000006,
+ "y": -7.800000000000001,
+ "z": 0
+ }
+ ]
+ }
+ },
+ {
+ "type": "plus",
+ "location": [
+ 10.5,
+ -7.8500000000000005,
+ 0
+ ],
+ "prop": {}
+ }
+ ],
+ "connections": [],
+ "templates": []
+ },
+ "mol0": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 9.532207454738979,
+ -8.347548743464719,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 9.52850411466491,
+ -7.352451256535282,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 8.520294802067824,
+ -8.334637098341616,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 8.517792545261022,
+ -7.352451256535282,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol1": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 11.47437421436393,
+ -8.307470415521406,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.47562578563607,
+ -8.307470415521406,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 11.975050188048687,
+ -7.442529584478595,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol2": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 13.05,
+ -7.4,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ },
+ "mol3": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Br",
+ "location": [
+ 14.75,
+ -7.25,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol4": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 14.224374214363932,
+ -6.8324704155214055,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 15.22562578563607,
+ -6.8324704155214055,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 14.725050188048687,
+ -5.967529584478595,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol5": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 16.725,
+ -8.35,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 17.59102540378444,
+ -7.85,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 17.59102540378444,
+ -6.85,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ }
+ ]
+ },
+ "mol6": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 18.675,
+ -6.9750000000000005,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 18.675,
+ -7.9750000000000005,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 19.541025403784438,
+ -8.475000000000001,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/api/tests/integration/tests/formats/reactions/merge_test3a.ket b/api/tests/integration/tests/formats/reactions/merge_test3a.ket
new file mode 100644
index 0000000000..95303415ae
--- /dev/null
+++ b/api/tests/integration/tests/formats/reactions/merge_test3a.ket
@@ -0,0 +1,354 @@
+{
+ "root": {
+ "nodes": [
+ {
+ "$ref": "mol0"
+ },
+ {
+ "$ref": "mol1"
+ },
+ {
+ "$ref": "mol2"
+ },
+ {
+ "$ref": "mol3"
+ },
+ {
+ "$ref": "mol4"
+ },
+ {
+ "$ref": "mol5"
+ },
+ {
+ "$ref": "mol6"
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 13.575000000000001,
+ "y": -7.800000000000001,
+ "z": 0
+ },
+ {
+ "x": 16.150000000000006,
+ "y": -7.800000000000001,
+ "z": 0
+ }
+ ]
+ }
+ },
+ {
+ "type": "plus",
+ "location": [
+ 10.5,
+ -7.8500000000000005,
+ 0
+ ],
+ "prop": {}
+ }
+ ],
+ "connections": [],
+ "templates": []
+ },
+ "mol0": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 9.532207454738979,
+ -8.347548743464719,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 9.52850411466491,
+ -7.352451256535282,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 8.520294802067824,
+ -8.334637098341616,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 8.517792545261022,
+ -7.352451256535282,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol1": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 11.47437421436393,
+ -8.307470415521406,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.47562578563607,
+ -8.307470415521406,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 11.975050188048687,
+ -7.442529584478595,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol2": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 13.05,
+ -7.4,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ },
+ "mol3": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Br",
+ "location": [
+ 14.75,
+ -8.350000000000001,
+ 0
+ ]
+ }
+ ],
+ "stereoFlagPosition": {
+ "x": 14.75,
+ "y": 7.350000000000002,
+ "z": 0
+ }
+ },
+ "mol4": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 14.149374214363933,
+ -9.832470415521406,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 15.150625785636072,
+ -9.832470415521406,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 14.650050188048688,
+ -8.967529584478596,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ],
+ "stereoFlagPosition": {
+ "x": 15.150625785636072,
+ "y": 7.967529584478596,
+ "z": 0
+ }
+ },
+ "mol5": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 16.725,
+ -8.35,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 17.59102540378444,
+ -7.85,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 17.59102540378444,
+ -6.85,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ }
+ ]
+ },
+ "mol6": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 18.675,
+ -6.9750000000000005,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 18.675,
+ -7.9750000000000005,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 19.541025403784438,
+ -8.475000000000001,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/api/tests/integration/tests/formats/reactions/merge_test4.ket b/api/tests/integration/tests/formats/reactions/merge_test4.ket
new file mode 100644
index 0000000000..9358518c73
--- /dev/null
+++ b/api/tests/integration/tests/formats/reactions/merge_test4.ket
@@ -0,0 +1,350 @@
+{
+ "root": {
+ "nodes": [
+ {
+ "$ref": "mol0"
+ },
+ {
+ "$ref": "mol1"
+ },
+ {
+ "$ref": "mol2"
+ },
+ {
+ "$ref": "mol3"
+ },
+ {
+ "$ref": "mol4"
+ },
+ {
+ "$ref": "mol5"
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 15.725000000000001,
+ "y": -7.8500000000000005,
+ "z": 0
+ },
+ {
+ "x": 20.30006830550103,
+ "y": -7.8500000000000005,
+ "z": 0
+ }
+ ]
+ }
+ },
+ {
+ "type": "plus",
+ "location": [
+ 9.750000000000002,
+ -7.875000000000001,
+ 0
+ ],
+ "prop": {}
+ },
+ {
+ "type": "plus",
+ "location": [
+ 11.4,
+ -7.9,
+ 0
+ ],
+ "prop": {}
+ }
+ ],
+ "connections": [],
+ "templates": []
+ },
+ "mol0": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 8.324374214363932,
+ -8.307470415521404,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 9.32562578563607,
+ -8.307470415521404,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 8.825050188048685,
+ -7.442529584478594,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol1": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 10.55,
+ -7.8500000000000005,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ },
+ "mol2": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 11.4,
+ -7.1000000000000005,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ },
+ "mol3": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "I",
+ "location": [
+ 8.075000000000001,
+ -7.125,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ },
+ "mol4": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 12.554476379955526,
+ -7.418603270895517,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 13.338409765774513,
+ -6.801031626975767,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 14.311440664360363,
+ -7.023581771768126,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 14.745523620044471,
+ -7.919391175468781,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.559985046905828,
+ -8.425787904573266,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 14.312141767426768,
+ -8.826418228231876,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 13.338409765774513,
+ -9.048968373024234,
+ 0
+ ]
+ },
+ {
+ "label": "Br",
+ "location": [
+ 15.177466068144803,
+ -6.523581771768126,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 4,
+ 6
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 6,
+ 5
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 5,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 7
+ ]
+ }
+ ]
+ },
+ "mol5": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 22.05720745473898,
+ -8.37254874346472,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 22.05350411466491,
+ -7.377451256535281,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 21.045294802067826,
+ -8.359637098341615,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 21.042792545261022,
+ -7.377451256535281,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/api/tests/integration/tests/formats/reactions/merge_test5.ket b/api/tests/integration/tests/formats/reactions/merge_test5.ket
new file mode 100644
index 0000000000..952d183583
--- /dev/null
+++ b/api/tests/integration/tests/formats/reactions/merge_test5.ket
@@ -0,0 +1,113 @@
+{
+ "root": {
+ "nodes": [
+ {
+ "$ref": "mol0"
+ },
+ {
+ "$ref": "mol1"
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 15.725000000000001,
+ "y": -7.8500000000000005,
+ "z": 0
+ },
+ {
+ "x": 20.30006830550103,
+ "y": -7.8500000000000005,
+ "z": 0
+ }
+ ]
+ }
+ }
+ ],
+ "connections": [],
+ "templates": []
+ },
+ "mol0": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 18.332207454738978,
+ -7.472548743464719,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 18.32850411466491,
+ -6.477451256535282,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 17.320294802067824,
+ -7.459637098341616,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 17.31779254526102,
+ -6.477451256535282,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol1": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 18.95,
+ -6.95,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/api/tests/integration/tests/formats/reactions/merge_test6.ket b/api/tests/integration/tests/formats/reactions/merge_test6.ket
new file mode 100644
index 0000000000..594a7bf7aa
--- /dev/null
+++ b/api/tests/integration/tests/formats/reactions/merge_test6.ket
@@ -0,0 +1,554 @@
+{
+ "root": {
+ "nodes": [
+ {
+ "$ref": "mol0"
+ },
+ {
+ "$ref": "mol1"
+ },
+ {
+ "$ref": "mol2"
+ },
+ {
+ "$ref": "mol3"
+ },
+ {
+ "$ref": "mol4"
+ },
+ {
+ "$ref": "mol5"
+ },
+ {
+ "$ref": "mol6"
+ },
+ {
+ "$ref": "mol7"
+ },
+ {
+ "$ref": "mol8"
+ },
+ {
+ "$ref": "mol9"
+ },
+ {
+ "$ref": "mol10"
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 23.041103727369492,
+ "y": -8.025000000000002,
+ "z": 0
+ },
+ {
+ "x": 27.616172032870523,
+ "y": -8.025000000000002,
+ "z": 0
+ }
+ ]
+ }
+ },
+ {
+ "type": "plus",
+ "location": [
+ 30.55,
+ -8.1,
+ 0
+ ],
+ "prop": {}
+ },
+ {
+ "type": "plus",
+ "location": [
+ 19.6,
+ -7.925000000000001,
+ 0
+ ],
+ "prop": {}
+ }
+ ],
+ "connections": [],
+ "templates": []
+ },
+ "mol0": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 25.64831118210847,
+ -7.64754874346472,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 25.6446078420344,
+ -6.652451256535282,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 24.636398529437315,
+ -7.634637098341616,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 24.633896272630512,
+ -6.652451256535282,
+ 0
+ ]
+ },
+ {
+ "label": "P",
+ "location": [
+ 23.926789491443966,
+ -5.945344475348734,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 4
+ ]
+ }
+ ]
+ },
+ "mol1": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 26.266103727369494,
+ -7.125,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ },
+ "mol2": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 29.18220745473898,
+ -8.472548743464719,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 29.17850411466491,
+ -7.477451256535282,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 28.170294802067826,
+ -8.459637098341616,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 28.167792545261022,
+ -7.477451256535282,
+ 0
+ ]
+ },
+ {
+ "label": "Cl",
+ "location": [
+ 29.889314235925525,
+ -9.179655524651267,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 4
+ ]
+ }
+ ]
+ },
+ "mol3": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 22.65720745473898,
+ -8.49754874346472,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 22.653504114664912,
+ -7.502451256535281,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 21.645294802067827,
+ -8.484637098341615,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 21.642792545261024,
+ -7.502451256535281,
+ 0
+ ]
+ },
+ {
+ "label": "S",
+ "location": [
+ 20.676866718971954,
+ -7.24363221143276,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 4
+ ]
+ }
+ ]
+ },
+ "mol4": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "N",
+ "location": [
+ 31.525000000000002,
+ -8.15,
+ 0
+ ],
+ "charge": -1
+ }
+ ],
+ "stereoFlagPosition": {
+ "x": 31.525000000000002,
+ "y": 7.15,
+ "z": 0
+ }
+ },
+ "mol5": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Br",
+ "location": [
+ 31.825000000000003,
+ -9.025,
+ 0
+ ],
+ "charge": -1
+ }
+ ],
+ "stereoFlagPosition": {
+ "x": 31.825000000000003,
+ "y": 8.025,
+ "z": 0
+ }
+ },
+ "mol6": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "I",
+ "location": [
+ 29.725,
+ -8.05,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ },
+ "mol7": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 21.5,
+ -9.575000000000001,
+ 0
+ ],
+ "charge": -1
+ },
+ {
+ "label": "C",
+ "location": [
+ 22.5,
+ -9.575000000000001,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ }
+ ]
+ },
+ "mol8": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 18.225,
+ -7.25,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 17.725,
+ -8.11602540378444,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 18.225,
+ -8.982050807568877,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ }
+ ]
+ },
+ "mol9": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 16.075,
+ -7.1000000000000005,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 16.075,
+ -8.100000000000001,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 16.941025403784437,
+ -8.600000000000001,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 16.941025403784437,
+ -9.600000000000001,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 17.807050807568878,
+ -10.100000000000001,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 4
+ ]
+ }
+ ]
+ },
+ "mol10": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 17.225,
+ -6.175000000000001,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/api/tests/integration/tests/formats/reactions/merge_test7.ket b/api/tests/integration/tests/formats/reactions/merge_test7.ket
new file mode 100644
index 0000000000..cc0816b080
--- /dev/null
+++ b/api/tests/integration/tests/formats/reactions/merge_test7.ket
@@ -0,0 +1,331 @@
+{
+ "root": {
+ "nodes": [
+ {
+ "$ref": "mol0"
+ },
+ {
+ "$ref": "mol1"
+ },
+ {
+ "$ref": "mol2"
+ },
+ {
+ "$ref": "mol3"
+ },
+ {
+ "$ref": "mol4"
+ },
+ {
+ "$ref": "mol5"
+ },
+ {
+ "$ref": "mol6"
+ },
+ {
+ "$ref": "mol7"
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 11.975000000000001,
+ "y": -9.450000000000001,
+ "z": 0
+ },
+ {
+ "x": 16.7500654445777,
+ "y": -9.450000000000001,
+ "z": 0
+ }
+ ]
+ }
+ },
+ {
+ "type": "plus",
+ "location": [
+ 21.275000000000002,
+ -9.475,
+ 0
+ ],
+ "prop": {}
+ }
+ ],
+ "connections": [],
+ "templates": []
+ },
+ "mol0": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 9.52499266647844,
+ -10.291012701659344,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 10.525007333521561,
+ -10.291012701659344,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 11.025014667043123,
+ -9.425,
+ 0
+ ]
+ },
+ {
+ "label": "O",
+ "location": [
+ 10.525007333521561,
+ -8.558987298340657,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 9.52499266647844,
+ -8.558987298340657,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 9.024985332956877,
+ -9.425,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 5,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 4,
+ 5
+ ]
+ }
+ ]
+ },
+ "mol1": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 18.29999266647844,
+ -10.341012701659343,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 19.300007333521563,
+ -10.341012701659343,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 19.800014667043122,
+ -9.475,
+ 0
+ ]
+ },
+ {
+ "label": "N",
+ "location": [
+ 19.300007333521563,
+ -8.608987298340654,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 18.29999266647844,
+ -8.608987298340654,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 17.79998533295688,
+ -9.475,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 5,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 4,
+ 5
+ ]
+ }
+ ]
+ },
+ "mol2": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 23.400000000000002,
+ -7.075,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol3": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 24.75,
+ -6.2250000000000005,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol4": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 26.425,
+ -6.300000000000001,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol5": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 27.650000000000002,
+ -6.75,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol6": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 25.425,
+ -6.775,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol7": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 23.575000000000003,
+ -6.275,
+ 0
+ ]
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/api/tests/integration/tests/formats/reactions/multi_merge1.ket b/api/tests/integration/tests/formats/reactions/multi_merge1.ket
new file mode 100644
index 0000000000..7dbb43bcc4
--- /dev/null
+++ b/api/tests/integration/tests/formats/reactions/multi_merge1.ket
@@ -0,0 +1,369 @@
+{
+ "root": {
+ "nodes": [
+ {
+ "$ref": "mol0"
+ },
+ {
+ "$ref": "mol1"
+ },
+ {
+ "$ref": "mol2"
+ },
+ {
+ "$ref": "mol3"
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 12.275,
+ "y": -8.525,
+ "z": 0
+ },
+ {
+ "x": 16.874999999999996,
+ "y": -8.525,
+ "z": 0
+ }
+ ]
+ }
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 18.625,
+ "y": -13.475000000000001,
+ "z": 0
+ },
+ {
+ "x": 18.625,
+ "y": -9.77364889533565,
+ "z": 0
+ }
+ ]
+ }
+ }
+ ],
+ "connections": [],
+ "templates": []
+ },
+ "mol0": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 11.782207454738979,
+ -9.02254874346472,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 11.77850411466491,
+ -8.027451256535281,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 10.770294802067824,
+ -9.009637098341615,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 10.767792545261022,
+ -8.027451256535281,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol1": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 17.324374214363928,
+ -8.932470415521406,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 18.32562578563607,
+ -8.932470415521406,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 17.825050188048685,
+ -8.067529584478596,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol2": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 19.83220745473898,
+ -9.07254874346472,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 19.828504114664913,
+ -8.077451256535282,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 18.820294802067828,
+ -9.059637098341616,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 18.817792545261025,
+ -8.077451256535282,
+ 0
+ ]
+ },
+ {
+ "label": "Cl",
+ "location": [
+ 20.69452951844935,
+ -7.577451256535282,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 4
+ ]
+ }
+ ]
+ },
+ "mol3": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 17.55447637995553,
+ -14.893603270895516,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 18.338409765774518,
+ -14.276031626975767,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 19.31144066436037,
+ -14.498581771768126,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 19.745523620044477,
+ -15.39439117546878,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 17.559985046905833,
+ -15.900787904573264,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 19.312141767426773,
+ -16.301418228231874,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 18.338409765774518,
+ -16.523968373024235,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 4,
+ 6
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 6,
+ 5
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 5,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 1
+ ]
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/api/tests/integration/tests/formats/reactions/multi_merge2.ket b/api/tests/integration/tests/formats/reactions/multi_merge2.ket
new file mode 100644
index 0000000000..a1bc1658f1
--- /dev/null
+++ b/api/tests/integration/tests/formats/reactions/multi_merge2.ket
@@ -0,0 +1,545 @@
+{
+ "root": {
+ "nodes": [
+ {
+ "$ref": "mol0"
+ },
+ {
+ "$ref": "mol1"
+ },
+ {
+ "$ref": "mol2"
+ },
+ {
+ "$ref": "mol3"
+ },
+ {
+ "$ref": "mol4"
+ },
+ {
+ "$ref": "mol5"
+ },
+ {
+ "$ref": "mol6"
+ },
+ {
+ "$ref": "mol7"
+ },
+ {
+ "$ref": "mol8"
+ },
+ {
+ "$ref": "mol9"
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 9.875,
+ "y": -7.825,
+ "z": 0
+ },
+ {
+ "x": 12.252104330903464,
+ "y": -7.825,
+ "z": 0
+ }
+ ]
+ }
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 26.343486238962686,
+ "y": -7.9,
+ "z": 0
+ },
+ {
+ "x": 23.900000000000002,
+ "y": -7.9,
+ "z": 0
+ }
+ ]
+ }
+ },
+ {
+ "type": "plus",
+ "location": [
+ 14.375,
+ -7.825,
+ 0
+ ],
+ "prop": {}
+ },
+ {
+ "type": "plus",
+ "location": [
+ 21.599999999999998,
+ -7.87622562826764,
+ 0
+ ],
+ "prop": {}
+ }
+ ],
+ "connections": [],
+ "templates": []
+ },
+ "mol0": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 8.257207454738978,
+ -8.37254874346472,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 8.25350411466491,
+ -7.377451256535281,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 7.245294802067824,
+ -8.359637098341615,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 7.242792545261022,
+ -7.377451256535281,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol1": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 8.925,
+ -7.825,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ },
+ "mol2": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 12.774374214363931,
+ -8.257470415521405,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 13.77562578563607,
+ -8.257470415521405,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 13.275050188048684,
+ -7.392529584478595,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol3": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 16.20720745473898,
+ -8.347548743464719,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 16.20350411466491,
+ -7.352451256535282,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 15.195294802067824,
+ -8.334637098341616,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 15.192792545261023,
+ -7.352451256535282,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol4": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 12.850000000000001,
+ -6.9750000000000005,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ },
+ "mol5": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 27.957207454738974,
+ -8.42377437173236,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 27.953504114664906,
+ -7.428676884802921,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 26.94529480206782,
+ -8.410862726609256,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 26.942792545261018,
+ -7.428676884802921,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ],
+ "stereoFlagPosition": {
+ "x": 27.957207454738974,
+ "y": 6.428676884802921,
+ "z": 0
+ }
+ },
+ "mol6": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 28.624999999999996,
+ -7.87622562826764,
+ 0
+ ],
+ "charge": -1
+ }
+ ],
+ "stereoFlagPosition": {
+ "x": 28.624999999999996,
+ "y": 6.87622562826764,
+ "z": 0
+ }
+ },
+ "mol7": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 19.99937421436393,
+ -8.308696043789043,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 21.000625785636068,
+ -8.308696043789043,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 20.500050188048682,
+ -7.443755212746234,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ],
+ "stereoFlagPosition": {
+ "x": 21.000625785636068,
+ "y": 6.443755212746234,
+ "z": 0
+ }
+ },
+ "mol8": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 23.43220745473898,
+ -8.398774371732358,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 23.428504114664907,
+ -7.4036768848029215,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 22.420294802067822,
+ -8.385862726609258,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 22.41779254526102,
+ -7.4036768848029215,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ],
+ "stereoFlagPosition": {
+ "x": 23.43220745473898,
+ "y": 6.4036768848029215,
+ "z": 0
+ }
+ },
+ "mol9": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 20.075,
+ -7.02622562826764,
+ 0
+ ],
+ "charge": -1
+ }
+ ],
+ "stereoFlagPosition": {
+ "x": 20.075,
+ "y": 6.02622562826764,
+ "z": 0
+ }
+ }
+}
\ No newline at end of file
diff --git a/api/tests/integration/tests/formats/reactions/multi_merge3.ket b/api/tests/integration/tests/formats/reactions/multi_merge3.ket
new file mode 100644
index 0000000000..0122dfa82f
--- /dev/null
+++ b/api/tests/integration/tests/formats/reactions/multi_merge3.ket
@@ -0,0 +1,421 @@
+{
+ "root": {
+ "nodes": [
+ {
+ "$ref": "mol0"
+ },
+ {
+ "$ref": "mol1"
+ },
+ {
+ "$ref": "mol2"
+ },
+ {
+ "$ref": "mol3"
+ },
+ {
+ "$ref": "mol4"
+ },
+ {
+ "$ref": "mol5"
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 19.25,
+ "y": -7.2,
+ "z": 0
+ },
+ {
+ "x": 21.82512135636362,
+ "y": -7.2,
+ "z": 0
+ }
+ ]
+ }
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 19.85,
+ "y": -10.450000000000001,
+ "z": 0
+ },
+ {
+ "x": 22.57545867699366,
+ "y": -10.450000000000001,
+ "z": 0
+ }
+ ]
+ }
+ }
+ ],
+ "connections": [],
+ "templates": []
+ },
+ "mol0": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 18.30720745473898,
+ -7.747548743464718,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 18.30350411466491,
+ -6.752451256535281,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 17.295294802067826,
+ -7.734637098341615,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 17.292792545261022,
+ -6.752451256535281,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol1": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 22.59937421436393,
+ -7.657470415521406,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 23.600625785636073,
+ -7.657470415521406,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 23.100050188048687,
+ -6.792529584478595,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol2": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 17.104476379955532,
+ -10.118603270895518,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 17.88840976577452,
+ -9.501031626975768,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 18.86144066436037,
+ -9.723581771768126,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 19.295523620044477,
+ -10.619391175468783,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 17.109985046905834,
+ -11.125787904573267,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 18.862141767426774,
+ -11.526418228231877,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 17.88840976577452,
+ -11.748968373024235,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 4,
+ 6
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 6,
+ 5
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 5,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 1
+ ]
+ }
+ ],
+ "stereoFlagPosition": {
+ "x": 19.295523620044477,
+ "y": 8.501031626975768,
+ "z": 0
+ }
+ },
+ "mol3": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 24.175000000000004,
+ -9.630559548551435,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 24.983989960649676,
+ -10.218352254200232,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 24.674993795209936,
+ -11.169440451448565,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 23.675006204790073,
+ -11.169440451448565,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 23.366010039350332,
+ -10.218352254200232,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 4,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 0
+ ]
+ }
+ ],
+ "stereoFlagPosition": {
+ "x": 24.983989960649676,
+ "y": 8.630559548551435,
+ "z": 0
+ }
+ },
+ "mol4": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 18.000000000000004,
+ -8.975000000000001,
+ 0
+ ]
+ }
+ ],
+ "stereoFlagPosition": {
+ "x": 18.000000000000004,
+ "y": 7.975000000000001,
+ "z": 0
+ }
+ },
+ "mol5": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 17.875000000000004,
+ -8.425,
+ 0
+ ]
+ }
+ ],
+ "stereoFlagPosition": {
+ "x": 17.875000000000004,
+ "y": 7.425000000000001,
+ "z": 0
+ }
+ }
+}
\ No newline at end of file
diff --git a/api/tests/integration/tests/formats/reactions/multi_merge4.ket b/api/tests/integration/tests/formats/reactions/multi_merge4.ket
new file mode 100644
index 0000000000..ccf99dc95b
--- /dev/null
+++ b/api/tests/integration/tests/formats/reactions/multi_merge4.ket
@@ -0,0 +1,1017 @@
+{
+ "root": {
+ "nodes": [
+ {
+ "$ref": "mol0"
+ },
+ {
+ "$ref": "mol1"
+ },
+ {
+ "$ref": "mol2"
+ },
+ {
+ "$ref": "mol3"
+ },
+ {
+ "$ref": "mol4"
+ },
+ {
+ "$ref": "mol5"
+ },
+ {
+ "$ref": "mol6"
+ },
+ {
+ "$ref": "mol7"
+ },
+ {
+ "$ref": "mol8"
+ },
+ {
+ "$ref": "mol9"
+ },
+ {
+ "$ref": "mol10"
+ },
+ {
+ "$ref": "mol11"
+ },
+ {
+ "$ref": "mol12"
+ },
+ {
+ "$ref": "mol13"
+ },
+ {
+ "$ref": "mol14"
+ },
+ {
+ "$ref": "mol15"
+ },
+ {
+ "$ref": "mol16"
+ },
+ {
+ "$ref": "mol17"
+ },
+ {
+ "$ref": "mol18"
+ },
+ {
+ "$ref": "mol19"
+ },
+ {
+ "$ref": "mol20"
+ },
+ {
+ "$ref": "mol21"
+ },
+ {
+ "$ref": "mol22"
+ },
+ {
+ "$ref": "mol23"
+ },
+ {
+ "$ref": "mol24"
+ },
+ {
+ "$ref": "mol25"
+ },
+ {
+ "$ref": "mol26"
+ },
+ {
+ "$ref": "mol27"
+ },
+ {
+ "$ref": "mol28"
+ },
+ {
+ "$ref": "mol29"
+ },
+ {
+ "$ref": "mol30"
+ },
+ {
+ "$ref": "mol31"
+ },
+ {
+ "$ref": "mol32"
+ },
+ {
+ "$ref": "mol33"
+ },
+ {
+ "$ref": "mol34"
+ },
+ {
+ "$ref": "mol35"
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 17.41289017840029,
+ "y": -15.460500755414808,
+ "z": 0
+ },
+ {
+ "x": 19.53789017840029,
+ "y": -17.210500755414806,
+ "z": 0
+ }
+ ]
+ }
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 8.16289017840029,
+ "y": -15.485500755414806,
+ "z": 0
+ },
+ {
+ "x": 6.537890178400287,
+ "y": -17.460500755414806,
+ "z": 0
+ }
+ ]
+ }
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 12.662890178400293,
+ "y": -9.785500755414805,
+ "z": 0
+ },
+ {
+ "x": 12.662890178400293,
+ "y": -7.758033123120764,
+ "z": 0
+ }
+ ]
+ }
+ }
+ ],
+ "connections": [],
+ "templates": []
+ },
+ "mol0": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 13.12009763313927,
+ -11.558049498879527,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 13.116394293065202,
+ -10.562952011950086,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.108184980468113,
+ -11.545137853756422,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.10568272366131,
+ -10.562952011950086,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol1": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 8.312264392764217,
+ -14.742971170936213,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 9.313515964036359,
+ -14.742971170936213,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 8.812940366448974,
+ -13.878030339893401,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol2": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 16.11289017840029,
+ -13.491060303966242,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 16.92188013904996,
+ -14.078853009615038,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 16.61288397361022,
+ -15.02994120686337,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 15.612896383190357,
+ -15.02994120686337,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 15.303900217750616,
+ -14.078853009615038,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 4,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol3": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 5.237264392764217,
+ -18.517971170936214,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 6.238515964036358,
+ -18.517971170936214,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 5.737940366448971,
+ -17.653030339893405,
+ 0
+ ]
+ },
+ {
+ "label": "Br",
+ "location": [
+ 6.945622745222906,
+ -19.22507795212276,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ }
+ ]
+ },
+ "mol4": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 20.61289017840029,
+ -17.566060303966246,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 21.421880139049964,
+ -18.15385300961504,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 21.112883973610224,
+ -19.104941206863373,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 20.112896383190357,
+ -19.104941206863373,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 19.803900217750616,
+ -18.15385300961504,
+ 0
+ ]
+ },
+ {
+ "label": "I",
+ "location": [
+ 21.819990754796773,
+ -19.81204798804992,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 4,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 5
+ ]
+ }
+ ]
+ },
+ "mol5": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 13.19509763313927,
+ -7.133049498879523,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 13.191394293065201,
+ -6.137952011950086,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.183184980468113,
+ -7.12013785375642,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.18068272366131,
+ -6.137952011950086,
+ 0
+ ]
+ },
+ {
+ "label": "S",
+ "location": [
+ 14.057419696849635,
+ -5.637952011950086,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 4
+ ]
+ }
+ ]
+ },
+ "mol6": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 9.862890178400292,
+ -14.935500755414804,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol7": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 10.38789017840029,
+ -15.460500755414806,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol8": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 10.83789017840029,
+ -15.860500755414806,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol9": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 11.312890178400288,
+ -16.185500755414807,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol10": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 11.91289017840029,
+ -16.385500755414807,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol11": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 12.787890178400293,
+ -16.385500755414807,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol12": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 13.56289017840029,
+ -16.310500755414807,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol13": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 14.287890178400293,
+ -16.185500755414807,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol14": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 14.812890178400291,
+ -15.760500755414805,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol15": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 14.937890178400288,
+ -15.310500755414806,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol16": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 15.112890178400292,
+ -14.810500755414806,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol17": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Br",
+ "location": [
+ 12.628627573780491,
+ -15.775000000000006,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol18": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "I",
+ "location": [
+ 12.653627573780497,
+ -15.250000000000004,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol19": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "P",
+ "location": [
+ 11.928627573780492,
+ -14.300000000000004,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol20": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 11.403627573780494,
+ -12.150000000000004,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol21": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Br",
+ "location": [
+ 11.453627573780494,
+ -11.600000000000005,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol22": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Br",
+ "location": [
+ 11.57862757378049,
+ -11.100000000000001,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol23": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 11.278627573780494,
+ -12.775000000000004,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol24": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 11.228627573780493,
+ -13.375000000000004,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol25": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 11.603627573780493,
+ -13.875000000000004,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol26": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "P",
+ "location": [
+ 10.278627573780497,
+ -16.450000000000003,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol27": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "O",
+ "location": [
+ 10.353627573780496,
+ -16.975000000000005,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol28": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "S",
+ "location": [
+ 9.978627573780496,
+ -17.650000000000002,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol29": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "N",
+ "location": [
+ 9.678627573780497,
+ -18.400000000000002,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol30": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 14.028627573780497,
+ -16.775000000000006,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol31": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "S",
+ "location": [
+ 14.178627573780496,
+ -17.425000000000004,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol32": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 14.003627573780497,
+ -18.050000000000004,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol33": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "O",
+ "location": [
+ 10.503627573780497,
+ -12.150000000000002,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol34": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "H",
+ "location": [
+ 9.628627573780498,
+ -11.650000000000004,
+ 0
+ ]
+ }
+ ],
+ "stereoFlagPosition": {
+ "x": 9.628627573780498,
+ "y": 10.650000000000004,
+ "z": 0
+ }
+ },
+ "mol35": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "N",
+ "location": [
+ 9.153627573780497,
+ -11.100000000000005,
+ 0
+ ]
+ }
+ ],
+ "stereoFlagPosition": {
+ "x": 9.153627573780497,
+ "y": 10.100000000000005,
+ "z": 0
+ }
+ }
+}
\ No newline at end of file
diff --git a/api/tests/integration/tests/formats/reactions/multi_merge5.ket b/api/tests/integration/tests/formats/reactions/multi_merge5.ket
new file mode 100644
index 0000000000..cfa6647e26
--- /dev/null
+++ b/api/tests/integration/tests/formats/reactions/multi_merge5.ket
@@ -0,0 +1,975 @@
+{
+ "root": {
+ "nodes": [
+ {
+ "$ref": "mol0"
+ },
+ {
+ "$ref": "mol1"
+ },
+ {
+ "$ref": "mol2"
+ },
+ {
+ "$ref": "mol3"
+ },
+ {
+ "$ref": "mol4"
+ },
+ {
+ "$ref": "mol5"
+ },
+ {
+ "$ref": "mol6"
+ },
+ {
+ "$ref": "mol7"
+ },
+ {
+ "$ref": "mol8"
+ },
+ {
+ "$ref": "mol9"
+ },
+ {
+ "$ref": "mol10"
+ },
+ {
+ "$ref": "mol11"
+ },
+ {
+ "$ref": "mol12"
+ },
+ {
+ "$ref": "mol13"
+ },
+ {
+ "$ref": "mol14"
+ },
+ {
+ "$ref": "mol15"
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 13.125,
+ "y": -14.3,
+ "z": 0
+ },
+ {
+ "x": 17.8,
+ "y": -10.475000000000001,
+ "z": 0
+ }
+ ]
+ }
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 26.975,
+ "y": -10.425,
+ "z": 0
+ },
+ {
+ "x": 30.150000000000002,
+ "y": -13.8,
+ "z": 0
+ }
+ ]
+ }
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 29.275000000000002,
+ "y": -19.175,
+ "z": 0
+ },
+ {
+ "x": 13.431034271685638,
+ "y": -19.175,
+ "z": 0
+ }
+ ]
+ }
+ },
+ {
+ "type": "plus",
+ "location": [
+ 21.875,
+ -9.25,
+ 0
+ ],
+ "prop": {}
+ },
+ {
+ "type": "plus",
+ "location": [
+ 24.575000000000003,
+ -9.275,
+ 0
+ ],
+ "prop": {}
+ },
+ {
+ "type": "plus",
+ "location": [
+ 31.074999999999996,
+ -18.325,
+ 0
+ ],
+ "prop": {}
+ },
+ {
+ "type": "plus",
+ "location": [
+ 31.1,
+ -21.250000000000004,
+ 0
+ ],
+ "prop": {}
+ },
+ {
+ "type": "plus",
+ "location": [
+ 11.700000000000001,
+ -17.325,
+ 0
+ ],
+ "prop": {}
+ }
+ ],
+ "connections": [],
+ "templates": []
+ },
+ "mol0": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 18.57947637995553,
+ -8.793603270895517,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 19.363409765774517,
+ -8.176031626975767,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 20.336440664360367,
+ -8.398581771768125,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 20.770523620044475,
+ -9.294391175468782,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 18.58498504690583,
+ -9.800787904573266,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 20.337141767426772,
+ -10.201418228231876,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 19.363409765774517,
+ -10.423968373024234,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 19.104590720671997,
+ -7.210105800686699,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 4,
+ 6
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 6,
+ 5
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 5,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 7
+ ]
+ }
+ ]
+ },
+ "mol1": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 22.67437421436393,
+ -9.707470415521406,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 23.675625785636072,
+ -9.707470415521406,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 23.175050188048687,
+ -8.842529584478594,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 21.967267433177383,
+ -10.414577196707954,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 3
+ ]
+ }
+ ]
+ },
+ "mol2": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 26.55720745473898,
+ -9.79754874346472,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 26.55350411466491,
+ -8.802451256535281,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 25.545294802067826,
+ -9.784637098341616,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 25.542792545261022,
+ -8.802451256535281,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 27.260610895851457,
+ -8.095344475348734,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 4
+ ]
+ }
+ ]
+ },
+ "mol3": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 30.054476379955528,
+ -14.793603270895517,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 30.838409765774514,
+ -14.176031626975767,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 31.811440664360365,
+ -14.398581771768125,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 32.24552362004447,
+ -15.294391175468782,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 30.05998504690583,
+ -15.800787904573266,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 31.81214176742677,
+ -16.201418228231876,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 30.838409765774514,
+ -16.423968373024234,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 32.6774660681448,
+ -13.898581771768125,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 32.67816717121121,
+ -16.701418228231876,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 4,
+ 6
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 6,
+ 5
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 5,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 7
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 5,
+ 8
+ ]
+ }
+ ]
+ },
+ "mol4": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 33,
+ -15.25,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ },
+ "mol5": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "O",
+ "location": [
+ 23.150000000000002,
+ -8.200000000000001,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ },
+ "mol6": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "S",
+ "location": [
+ 23.575000000000003,
+ -10.375,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ },
+ "mol7": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Br",
+ "location": [
+ 30.975,
+ -17.075,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ },
+ "mol8": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 30.64937421436393,
+ -20.157470415521406,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 31.650625785636073,
+ -20.157470415521406,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 31.150050188048688,
+ -19.292529584478597,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol9": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Br",
+ "location": [
+ 31.125,
+ -22.400000000000002,
+ 0
+ ],
+ "charge": -2
+ }
+ ]
+ },
+ "mol10": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 10.50447637995553,
+ -18.768603270895518,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 11.288409765774517,
+ -18.15103162697577,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.261440664360368,
+ -18.37358177176813,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.695523620044476,
+ -19.269391175468783,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 10.509985046905832,
+ -19.775787904573267,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.262141767426773,
+ -20.176418228231878,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 11.288409765774517,
+ -20.398968373024235,
+ 0
+ ]
+ },
+ {
+ "label": "N",
+ "location": [
+ 10.788409765774517,
+ -21.264993776808673,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 4,
+ 6
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 6,
+ 5
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 5,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 6,
+ 7
+ ]
+ }
+ ]
+ },
+ "mol11": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 11.700000000000001,
+ -15.080559548551436,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.508989960649673,
+ -15.668352254200233,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.199993795209934,
+ -16.61944045144857,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 11.200006204790068,
+ -16.61944045144857,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 10.891010039350329,
+ -15.668352254200233,
+ 0
+ ]
+ },
+ {
+ "label": "P",
+ "location": [
+ 11.200000000000001,
+ -14.214534144766997,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 4,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 5
+ ]
+ }
+ ]
+ },
+ "mol12": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 10.100000000000001,
+ -15.65,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ },
+ "mol13": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 9.125,
+ -15.625,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ },
+ "mol14": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 8.125,
+ -15.625,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ },
+ "mol15": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "I",
+ "location": [
+ 11.450000000000001,
+ -22.075000000000003,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/api/tests/integration/tests/formats/reactions/multi_merge6.ket b/api/tests/integration/tests/formats/reactions/multi_merge6.ket
new file mode 100644
index 0000000000..97a30267e8
--- /dev/null
+++ b/api/tests/integration/tests/formats/reactions/multi_merge6.ket
@@ -0,0 +1,1406 @@
+{
+ "root": {
+ "nodes": [
+ {
+ "$ref": "mol0"
+ },
+ {
+ "$ref": "mol1"
+ },
+ {
+ "$ref": "mol2"
+ },
+ {
+ "$ref": "mol3"
+ },
+ {
+ "$ref": "mol4"
+ },
+ {
+ "$ref": "mol5"
+ },
+ {
+ "$ref": "mol6"
+ },
+ {
+ "$ref": "mol7"
+ },
+ {
+ "$ref": "mol8"
+ },
+ {
+ "$ref": "mol9"
+ },
+ {
+ "$ref": "mol10"
+ },
+ {
+ "$ref": "mol11"
+ },
+ {
+ "$ref": "mol12"
+ },
+ {
+ "$ref": "mol13"
+ },
+ {
+ "$ref": "mol14"
+ },
+ {
+ "$ref": "mol15"
+ },
+ {
+ "$ref": "mol16"
+ },
+ {
+ "$ref": "mol17"
+ },
+ {
+ "$ref": "mol18"
+ },
+ {
+ "$ref": "mol19"
+ },
+ {
+ "$ref": "mol20"
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 23.041103727369492,
+ "y": -8.025000000000002,
+ "z": 0
+ },
+ {
+ "x": 27.616172032870523,
+ "y": -8.025000000000002,
+ "z": 0
+ }
+ ]
+ }
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 17.325,
+ "y": -11.700000000000001,
+ "z": 0
+ },
+ {
+ "x": 17.325,
+ "y": -15.25008802707764,
+ "z": 0
+ }
+ ]
+ }
+ },
+ {
+ "type": "plus",
+ "location": [
+ 30.55,
+ -8.1,
+ 0
+ ],
+ "prop": {}
+ },
+ {
+ "type": "plus",
+ "location": [
+ 19.6,
+ -7.925000000000001,
+ 0
+ ],
+ "prop": {}
+ },
+ {
+ "type": "plus",
+ "location": [
+ 17.275000000000002,
+ -17.975,
+ 0
+ ],
+ "prop": {}
+ },
+ {
+ "type": "plus",
+ "location": [
+ 18.95,
+ -16.375,
+ 0
+ ],
+ "prop": {}
+ },
+ {
+ "type": "plus",
+ "location": [
+ 14.675,
+ -16.325,
+ 0
+ ],
+ "prop": {}
+ },
+ {
+ "type": "text",
+ "data": {
+ "content": "{\"blocks\":[{\"key\":\"uskp\",\"text\":\"not a reaction\",\"type\":\"unstyled\",\"depth\":0,\"inlineStyleRanges\":[],\"entityRanges\":[],\"data\":{}}],\"entityMap\":{}}",
+ "position": {
+ "x": 34.3,
+ "y": -15.250000000000002,
+ "z": 0
+ },
+ "pos": [
+ {
+ "x": 34.3,
+ "y": -15.250000000000002,
+ "z": 0
+ },
+ {
+ "x": 34.3,
+ "y": -15.625000000000002,
+ "z": 0
+ },
+ {
+ "x": 36.26953125,
+ "y": -15.625000000000002,
+ "z": 0
+ },
+ {
+ "x": 36.26953125,
+ "y": -15.250000000000002,
+ "z": 0
+ }
+ ]
+ }
+ }
+ ],
+ "connections": [],
+ "templates": []
+ },
+ "mol0": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 25.64831118210847,
+ -7.64754874346472,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 25.6446078420344,
+ -6.652451256535282,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 24.636398529437315,
+ -7.634637098341616,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 24.633896272630512,
+ -6.652451256535282,
+ 0
+ ]
+ },
+ {
+ "label": "P",
+ "location": [
+ 23.926789491443966,
+ -5.945344475348734,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 4
+ ]
+ }
+ ]
+ },
+ "mol1": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 26.266103727369494,
+ -7.125,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ },
+ "mol2": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 29.18220745473898,
+ -8.472548743464719,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 29.17850411466491,
+ -7.477451256535282,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 28.170294802067826,
+ -8.459637098341616,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 28.167792545261022,
+ -7.477451256535282,
+ 0
+ ]
+ },
+ {
+ "label": "Cl",
+ "location": [
+ 29.889314235925525,
+ -9.179655524651267,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 4
+ ]
+ }
+ ]
+ },
+ "mol3": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 22.65720745473898,
+ -8.49754874346472,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 22.653504114664912,
+ -7.502451256535281,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 21.645294802067827,
+ -8.484637098341615,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 21.642792545261024,
+ -7.502451256535281,
+ 0
+ ]
+ },
+ {
+ "label": "S",
+ "location": [
+ 20.676866718971954,
+ -7.24363221143276,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 4
+ ]
+ }
+ ]
+ },
+ "mol4": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "N",
+ "location": [
+ 31.525000000000002,
+ -8.15,
+ 0
+ ],
+ "charge": -1
+ }
+ ],
+ "stereoFlagPosition": {
+ "x": 31.525000000000002,
+ "y": 7.15,
+ "z": 0
+ }
+ },
+ "mol5": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Br",
+ "location": [
+ 31.825000000000003,
+ -9.025,
+ 0
+ ],
+ "charge": -1
+ }
+ ],
+ "stereoFlagPosition": {
+ "x": 31.825000000000003,
+ "y": 8.025,
+ "z": 0
+ }
+ },
+ "mol6": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "I",
+ "location": [
+ 29.725,
+ -8.05,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ },
+ "mol7": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 21.5,
+ -9.575000000000001,
+ 0
+ ],
+ "charge": -1
+ },
+ {
+ "label": "C",
+ "location": [
+ 22.5,
+ -9.575000000000001,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ }
+ ]
+ },
+ "mol8": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 18.225,
+ -7.25,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 17.725,
+ -8.11602540378444,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 18.225,
+ -8.982050807568877,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ }
+ ]
+ },
+ "mol9": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 16.075,
+ -7.1000000000000005,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 16.075,
+ -8.100000000000001,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 16.941025403784437,
+ -8.600000000000001,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 16.941025403784437,
+ -9.600000000000001,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 17.807050807568878,
+ -10.100000000000001,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 4
+ ]
+ }
+ ]
+ },
+ "mol10": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 17.225,
+ -6.175000000000001,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ },
+ "mol11": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 17.85720745473898,
+ -16.87254874346472,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 17.85350411466491,
+ -15.87745125653528,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 16.845294802067826,
+ -16.859637098341615,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 16.842792545261023,
+ -15.87745125653528,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol12": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 16.87437421436393,
+ -19.807470415521404,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 17.87562578563607,
+ -19.807470415521404,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 17.375050188048686,
+ -18.942529584478596,
+ 0
+ ]
+ },
+ {
+ "label": "P",
+ "location": [
+ 18.87562578563607,
+ -19.807470415521404,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ }
+ ]
+ },
+ "mol13": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 20.775000000000002,
+ -15.630559548551437,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 21.583989960649674,
+ -16.218352254200234,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 21.274993795209934,
+ -17.16944045144857,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 20.27500620479007,
+ -17.16944045144857,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 19.96601003935033,
+ -16.218352254200234,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 4,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol14": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Br",
+ "location": [
+ 15.9,
+ -16.3,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ },
+ "mol15": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 11.343333689669972,
+ -16.901245306776698,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 11.343534650001445,
+ -15.898754693223307,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.048704453140436,
+ -15.193484409918579,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.048905413471909,
+ -17.606616070247163,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 13.051295546859565,
+ -17.606616070247163,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 13.75666631033003,
+ -16.901245306776698,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 13.756565830164293,
+ -15.898754693223307,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 13.051295546859565,
+ -15.19338392975284,
+ 0
+ ]
+ },
+ {
+ "label": "Cl",
+ "location": [
+ 11.341597671953888,
+ -14.486377628732031,
+ 0
+ ]
+ },
+ {
+ "label": "Cl",
+ "location": [
+ 10.477308285885533,
+ -17.401245306776698,
+ 0
+ ]
+ },
+ {
+ "label": "Cl",
+ "location": [
+ 13.310114591962087,
+ -18.572541896536233,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 4,
+ 5
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 5,
+ 6
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 6,
+ 7
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 7,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 8
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 9
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 4,
+ 10
+ ]
+ }
+ ]
+ },
+ "mol16": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 34.50720745473898,
+ -17.29754874346472,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 34.503504114664906,
+ -16.30245125653528,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 33.495294802067825,
+ -17.284637098341616,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 33.49279254526102,
+ -16.30245125653528,
+ 0
+ ]
+ },
+ {
+ "label": "Br",
+ "location": [
+ 32.62676714147658,
+ -15.802451256535281,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 4
+ ]
+ }
+ ]
+ },
+ "mol17": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 33.59279254526102,
+ -18.25245125653528,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 33.596495885335095,
+ -19.24754874346472,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 34.60470519793218,
+ -18.265362901658385,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 34.60720745473898,
+ -19.24754874346472,
+ 0
+ ]
+ },
+ {
+ "label": "Br",
+ "location": [
+ 33.096495885335095,
+ -20.113574147249157,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 4
+ ]
+ }
+ ]
+ },
+ "mol18": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 36.957207454738985,
+ -17.27254874346472,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 36.95350411466491,
+ -16.277451256535283,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 35.94529480206783,
+ -17.259637098341617,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 35.94279254526102,
+ -16.277451256535283,
+ 0
+ ]
+ },
+ {
+ "label": "Br",
+ "location": [
+ 37.81952951844935,
+ -15.777451256535283,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 4
+ ]
+ }
+ ]
+ },
+ "mol19": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 37.15720745473898,
+ -19.24754874346472,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 37.15350411466491,
+ -18.25245125653528,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 36.14529480206782,
+ -19.234637098341615,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 36.14279254526102,
+ -18.25245125653528,
+ 0
+ ]
+ },
+ {
+ "label": "Br",
+ "location": [
+ 37.86431423592553,
+ -19.954655524651265,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 4
+ ]
+ }
+ ]
+ },
+ "mol20": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "I",
+ "location": [
+ 37.875,
+ -18.725,
+ 0
+ ],
+ "charge": -1
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/api/tests/integration/tests/formats/reactions/pathway_merge1.ket b/api/tests/integration/tests/formats/reactions/pathway_merge1.ket
new file mode 100644
index 0000000000..46f8944b43
--- /dev/null
+++ b/api/tests/integration/tests/formats/reactions/pathway_merge1.ket
@@ -0,0 +1,1538 @@
+{
+ "root": {
+ "nodes": [
+ {
+ "$ref": "mol0"
+ },
+ {
+ "$ref": "mol1"
+ },
+ {
+ "$ref": "mol2"
+ },
+ {
+ "$ref": "mol3"
+ },
+ {
+ "$ref": "mol4"
+ },
+ {
+ "$ref": "mol5"
+ },
+ {
+ "type": "multi-tailed-arrow",
+ "data": {
+ "head": {
+ "position": {
+ "x": 14.0,
+ "y": -8.774066925048829,
+ "z": 0.0
+ }
+ },
+ "spine": {
+ "pos": [
+ {
+ "x": 7.5,
+ "y": -3.2660446166992189,
+ "z": 0.0
+ },
+ {
+ "x": 7.5,
+ "y": -14.282089233398438,
+ "z": 0.0
+ }
+ ]
+ },
+ "tails": {
+ "pos": [
+ {
+ "x": 7.0,
+ "y": -3.2660446166992189,
+ "z": 0.0
+ },
+ {
+ "x": 7.0,
+ "y": -9.032089233398438,
+ "z": 0.0
+ },
+ {
+ "x": 7.0,
+ "y": -14.282089233398438,
+ "z": 0.0
+ }
+ ]
+ },
+ "zOrder": 0
+ }
+ }
+ ]
+ },
+ "mol0": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 2.291954278945923,
+ -4.705737113952637,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 4.708045482635498,
+ -1.8263521194458008,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 2.8572123050689699,
+ -5.0320892333984379,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 2.291954278945923,
+ -1.8263518810272217,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 4.142787933349609,
+ -1.500000238418579,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 1.6491668224334717,
+ -3.5923962593078615,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 2.633974552154541,
+ -3.7660446166992189,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 4.366025447845459,
+ -2.7660446166992189,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 5.350832939147949,
+ -2.939692497253418,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 4.70804500579834,
+ -4.705737590789795,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 4.142787456512451,
+ -5.0320892333984379,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 3.5,
+ -4.266044616699219,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 3.5,
+ -2.2660446166992189,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 2.8572120666503908,
+ -1.500000238418579,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 2.633974552154541,
+ -2.7660446166992189,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 1.6491668224334717,
+ -2.939692974090576,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 5.350832939147949,
+ -3.5923964977264406,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 4.366024971008301,
+ -3.7660446166992189,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 6,
+ 14
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 14,
+ 12
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 12,
+ 7
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 7,
+ 17
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 17,
+ 11
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 11,
+ 6
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 6
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 7,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 11,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 14,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 4,
+ 12
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 5,
+ 6
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 7,
+ 8
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 9,
+ 17
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 10,
+ 11
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 12,
+ 13
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 14,
+ 15
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 16,
+ 17
+ ]
+ }
+ ]
+ },
+ "mol1": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 2.633974552154541,
+ -10.532089233398438,
+ 0.0
+ ]
+ },
+ {
+ "label": "N",
+ "location": [
+ 3.5,
+ -10.032089233398438,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 4.366025447845459,
+ -10.532089233398438,
+ 0.0
+ ]
+ },
+ {
+ "label": "P",
+ "location": [
+ 3.5,
+ -9.032089233398438,
+ 0.0
+ ]
+ },
+ {
+ "label": "N",
+ "location": [
+ 2.633974552154541,
+ -8.532089233398438,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 1.767949104309082,
+ -9.032089233398438,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 2.633974075317383,
+ -7.5320892333984379,
+ 0.0
+ ]
+ },
+ {
+ "label": "N",
+ "location": [
+ 4.366025447845459,
+ -8.532089233398438,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 5.232050895690918,
+ -9.032089233398438,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 4.366024971008301,
+ -7.5320892333984379,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 4,
+ 5
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 4,
+ 6
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 7
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 7,
+ 8
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 7,
+ 9
+ ]
+ }
+ ]
+ },
+ "mol2": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Si",
+ "location": [
+ 3.5,
+ -14.032089233398438,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 3.500000476837158,
+ -15.032089233398438,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 3.5,
+ -13.032089233398438,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 4.366025924682617,
+ -15.532089233398438,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 2.633975028991699,
+ -15.532089233398438,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 2.5,
+ -14.032089233398438,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 2.0,
+ -13.166064262390137,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 1.0,
+ -13.166064262390137,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 1.9999998807907105,
+ -14.898115158081055,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 1.0,
+ -14.898115158081055,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 0.5,
+ -14.032089233398438,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 4.5,
+ -14.032089233398438,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 5.0,
+ -14.898115158081055,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 6.0,
+ -14.898114204406739,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 5.0,
+ -13.16606330871582,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 6.0,
+ -13.16606330871582,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 6.5,
+ -14.032089233398438,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 5
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 6,
+ 5
+ ]
+ },
+ {
+ "type": 2,
+ "atoms": [
+ 6,
+ 7
+ ]
+ },
+ {
+ "type": 2,
+ "atoms": [
+ 5,
+ 8
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 8,
+ 9
+ ]
+ },
+ {
+ "type": 2,
+ "atoms": [
+ 9,
+ 10
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 10,
+ 7
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 11
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 12,
+ 11
+ ]
+ },
+ {
+ "type": 2,
+ "atoms": [
+ 12,
+ 13
+ ]
+ },
+ {
+ "type": 2,
+ "atoms": [
+ 11,
+ 14
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 14,
+ 15
+ ]
+ },
+ {
+ "type": 2,
+ "atoms": [
+ 15,
+ 16
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 16,
+ 13
+ ]
+ }
+ ],
+ "sgroups": [
+ {
+ "type": "SUP",
+ "atoms": [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 10,
+ 11,
+ 12,
+ 13,
+ 14,
+ 15,
+ 16
+ ],
+ "name": "TBDPS",
+ "expanded": true,
+ "attachmentPoints": [
+ {
+ "attachmentAtom": 0,
+ "attachmentId": " 1"
+ }
+ ]
+ }
+ ]
+ },
+ "mol3": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 14.500000953674317,
+ -9.524066925048829,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 15.366025924682618,
+ -9.024066925048829,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 15.366025924682618,
+ -8.024066925048829,
+ 0.0
+ ]
+ },
+ {
+ "label": "N",
+ "location": [
+ 16.232051849365236,
+ -9.524066925048829,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 17.09807586669922,
+ -9.024066925048829,
+ 0.0
+ ]
+ },
+ {
+ "label": "S",
+ "location": [
+ 17.964101791381837,
+ -8.524066925048829,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 2,
+ "atoms": [
+ 3,
+ 4
+ ]
+ },
+ {
+ "type": 2,
+ "atoms": [
+ 4,
+ 5
+ ]
+ }
+ ]
+ },
+ "mol4": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 20.248552322387697,
+ -9.84934139251709,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 19.941761016845704,
+ -8.897564888000489,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 18.964101791381837,
+ -8.687366485595704,
+ 0.0
+ ]
+ },
+ {
+ "label": "N",
+ "location": [
+ 20.612627029418947,
+ -8.155986785888672,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 21.590286254882814,
+ -8.36618423461914,
+ 0.0
+ ]
+ },
+ {
+ "label": "N",
+ "location": [
+ 22.334991455078126,
+ -7.698792457580566,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 23.199846267700197,
+ -8.20081615447998,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 24.151622772216798,
+ -7.894023895263672,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 24.89320182800293,
+ -8.564889907836914,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 24.683002471923829,
+ -9.542549133300782,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 23.731225967407228,
+ -9.84934139251709,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 22.989648818969728,
+ -9.178475379943848,
+ 0.0
+ ]
+ },
+ {
+ "label": "O",
+ "location": [
+ 21.994884490966798,
+ -9.280677795410157,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 4
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 4,
+ 5
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 5,
+ 6
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 6,
+ 7
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 7,
+ 8
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 8,
+ 9
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 9,
+ 10
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 10,
+ 11
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 11,
+ 12
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 12,
+ 4
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 11,
+ 6
+ ]
+ }
+ ]
+ },
+ "mol5": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 35.228172302246097,
+ -6.782937049865723,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 34.38882827758789,
+ -7.326540946960449,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 33.498382568359378,
+ -6.8714518547058109,
+ 0.0
+ ]
+ },
+ {
+ "label": "N",
+ "location": [
+ 34.43993377685547,
+ -8.325234413146973,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 33.60059356689453,
+ -8.868839263916016,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 32.71014404296875,
+ -8.413749694824219,
+ 0.0
+ ]
+ },
+ {
+ "label": "O",
+ "location": [
+ 32.65904235839844,
+ -7.415056228637695,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 31.870803833007814,
+ -8.957353591918946,
+ 0.0
+ ]
+ },
+ {
+ "label": "O",
+ "location": [
+ 30.980358123779298,
+ -8.502264976501465,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 30.141016006469728,
+ -9.045869827270508,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 30.192119598388673,
+ -10.044562339782715,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 29.352779388427736,
+ -10.588167190551758,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 28.46233367919922,
+ -10.133077621459961,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 27.62299156188965,
+ -10.676682472229004,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 26.7325439453125,
+ -10.221592903137207,
+ 0.0
+ ]
+ },
+ {
+ "label": "N",
+ "location": [
+ 26.681442260742189,
+ -9.222900390625,
+ 0.0
+ ]
+ },
+ {
+ "label": "O",
+ "location": [
+ 25.893203735351564,
+ -10.76519775390625,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 28.41122817993164,
+ -9.134384155273438,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 29.25057029724121,
+ -8.590780258178711,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 35.330379486083987,
+ -8.780323028564454,
+ 0.0
+ ]
+ },
+ {
+ "label": "N",
+ "location": [
+ 36.221946716308597,
+ -8.327431678771973,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 36.92818069458008,
+ -9.035409927368164,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 37.92687225341797,
+ -8.984305381774903,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 38.47047805786133,
+ -9.823647499084473,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 38.01538848876953,
+ -10.714093208312989,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 37.016693115234378,
+ -10.76519775390625,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 36.47309112548828,
+ -9.92585563659668,
+ 0.0
+ ]
+ },
+ {
+ "label": "O",
+ "location": [
+ 35.485595703125,
+ -9.768203735351563,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 4,
+ 5
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 5,
+ 6
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 5,
+ 7
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 7,
+ 8
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 8,
+ 9
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 9,
+ 10
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 10,
+ 11
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 11,
+ 12
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 12,
+ 13
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 13,
+ 14
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 14,
+ 15
+ ]
+ },
+ {
+ "type": 2,
+ "atoms": [
+ 14,
+ 16
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 12,
+ 17
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 17,
+ 18
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 19
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 19,
+ 20
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 20,
+ 21
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 21,
+ 22
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 22,
+ 23
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 23,
+ 24
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 24,
+ 25
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 25,
+ 26
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 26,
+ 27
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 18,
+ 9
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 27,
+ 19
+ ]
+ },
+ {
+ "type": 4,
+ "atoms": [
+ 26,
+ 21
+ ]
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/api/tests/integration/tests/formats/reactions/pathway_merge2.ket b/api/tests/integration/tests/formats/reactions/pathway_merge2.ket
new file mode 100644
index 0000000000..f02658cd39
--- /dev/null
+++ b/api/tests/integration/tests/formats/reactions/pathway_merge2.ket
@@ -0,0 +1,861 @@
+{
+ "root": {
+ "nodes": [
+ {
+ "$ref": "mol0"
+ },
+ {
+ "$ref": "mol1"
+ },
+ {
+ "$ref": "mol2"
+ },
+ {
+ "$ref": "mol3"
+ },
+ {
+ "$ref": "mol4"
+ },
+ {
+ "$ref": "mol5"
+ },
+ {
+ "$ref": "mol6"
+ },
+ {
+ "$ref": "mol7"
+ },
+ {
+ "$ref": "mol8"
+ },
+ {
+ "$ref": "mol9"
+ },
+ {
+ "$ref": "mol10"
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 15.700000000000001,
+ "y": -0.9428649902343751,
+ "z": 0
+ },
+ {
+ "x": 18.125515409145038,
+ "y": -0.9428649902343751,
+ "z": 0
+ }
+ ]
+ }
+ },
+ {
+ "type": "plus",
+ "location": [
+ 13.175000000000002,
+ -0.8928649902343748,
+ 0
+ ],
+ "prop": {}
+ },
+ {
+ "type": "plus",
+ "location": [
+ 20.55,
+ -0.992864990234375,
+ 0
+ ],
+ "prop": {}
+ },
+ {
+ "type": "multi-tailed-arrow",
+ "data": {
+ "head": {
+ "position": {
+ "x": 19.8,
+ "y": -7.77722,
+ "z": 0
+ }
+ },
+ "spine": {
+ "pos": [
+ {
+ "x": 15.6,
+ "y": -5.30222,
+ "z": 0
+ },
+ {
+ "x": 15.6,
+ "y": -10.52722,
+ "z": 0
+ }
+ ]
+ },
+ "tails": {
+ "pos": [
+ {
+ "x": 15.2,
+ "y": -5.30222,
+ "z": 0
+ },
+ {
+ "x": 15.2,
+ "y": -10.52722,
+ "z": 0
+ }
+ ]
+ },
+ "zOrder": 0
+ }
+ }
+ ],
+ "connections": [],
+ "templates": []
+ },
+ "mol0": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 10.88220745473898,
+ -1.3904137336990934,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 10.878504114664912,
+ -0.3953162467696558,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 9.870294802067827,
+ -1.37750208857599,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 9.867792545261024,
+ -0.3953162467696558,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol1": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 12.282207454738979,
+ -1.3904137336990934,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.27850411466491,
+ -0.3953162467696558,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 11.270294802067825,
+ -1.37750208857599,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 11.267792545261022,
+ -0.3953162467696558,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol2": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 13.97437421436393,
+ -1.3753354057557805,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 14.97562578563607,
+ -1.3753354057557805,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 14.475050188048687,
+ -0.5103945747129699,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol3": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 18.94937421436393,
+ -1.3503354057557804,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 19.950625785636074,
+ -1.3503354057557804,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 19.45005018804869,
+ -0.4853945747129699,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol4": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 21.50447637995553,
+ -0.5614682611298911,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 22.288409765774517,
+ 0.05610338278985827,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 23.261440664360368,
+ -0.1664467620025003,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 23.695523620044476,
+ -1.0622561657031553,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 21.509985046905832,
+ -1.5686528948076393,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 23.262141767426773,
+ -1.9692832184662508,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 22.288409765774517,
+ -2.1918333632586093,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 4,
+ 6
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 6,
+ 5
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 5,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 1
+ ]
+ }
+ ]
+ },
+ "mol5": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 25.125,
+ -0.2734245387858093,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 25.933989960649672,
+ -0.8612172444346063,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 25.62499379520993,
+ -1.8123054416829407,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 24.62500620479007,
+ -1.8123054416829407,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 24.316010039350328,
+ -0.8612172444346063,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 4,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol6": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 13.574374214363932,
+ -5.584692095208905,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 14.57562578563607,
+ -5.584692095208905,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 14.075050188048685,
+ -4.719751264166094,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol7": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 13.20720745473898,
+ -5.699770423152219,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 13.203504114664911,
+ -4.7046729362227815,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.195294802067824,
+ -5.686858778029116,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.192792545261023,
+ -4.7046729362227815,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol8": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 12.858987298340658,
+ -10.00221434616594,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.858987298340658,
+ -11.002229013209064,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 13.725000000000001,
+ -11.502236346730625,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 14.591012701659345,
+ -11.002229013209064,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 14.591012701659345,
+ -10.00221434616594,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 13.725000000000001,
+ -9.50220701264438,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 5,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 4,
+ 5
+ ]
+ }
+ ]
+ },
+ "mol9": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 21.27505003874321,
+ -6.907175460437001,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 21.77543747083789,
+ -8.447267898937998,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 22.0846769038724,
+ -7.501035264846965,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 20.774662606648533,
+ -8.447267898937998,
+ 0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 20.465323096127605,
+ -7.501035264846965,
+ 0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 4
+ ]
+ },
+ {
+ "type": 2,
+ "atoms": [
+ 4,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 1
+ ]
+ },
+ {
+ "type": 2,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol10": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Br",
+ "location": [
+ 23.150000000000002,
+ -7.7522216796875005,
+ 0
+ ]
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/api/tests/integration/tests/formats/ref/2558-missed.cdxml b/api/tests/integration/tests/formats/ref/2558-missed.cdxml
index 39825ecc85..ede0b80df3 100644
--- a/api/tests/integration/tests/formats/ref/2558-missed.cdxml
+++ b/api/tests/integration/tests/formats/ref/2558-missed.cdxml
@@ -34,178 +34,178 @@
-
+
+
+ F
+
+
+
+
+
+ SH
+
+
+
+
+
+
+
+ SH
+
+
+
+
+
+
+
+ SH
+
+
+
+
+
+
+
+ SH
+
+
+
+
+ F
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
NH
2
-
-
-
-
-
-
+
+
+
+
+
+
O
-
-
-
+
+
+
F
-
-
-
+
+
+
F
-
-
-
-
-
-
+
+
+
+
+
+
NH
2
-
-
-
+
+
+
Cl
-
-
+
+
Cl
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- F
-
-
-
-
-
- SH
-
-
-
-
-
-
-
- SH
-
-
-
-
-
-
-
- SH
-
-
-
-
-
-
-
- SH
-
-
-
-
- F
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -297,7 +297,7 @@
-
+
diff --git a/api/tests/integration/tests/formats/ref/963-super.cdxml b/api/tests/integration/tests/formats/ref/963-super.cdxml
index 3749bc258b..beb08f55fa 100644
--- a/api/tests/integration/tests/formats/ref/963-super.cdxml
+++ b/api/tests/integration/tests/formats/ref/963-super.cdxml
@@ -1,127 +1,127 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- O
-
-
-
-
- O
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- CO2tBu
-
-
-
-
-
-
- S
-
-
-
-
-
-
- O
-
-
-
-
- O
-
-
-
-
-
-
-
-
- Ms
-
-
-
-
-
-
- S
-
-
-
-
- O
-
-
-
-
- O
-
-
-
-
- OH
-
-
-
-
-
-
-
-
-
- methane sulphonic acid
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ O
+
+
+
+
+ O
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CO2tBu
+
+
+
+
+
+
+ S
+
+
+
+
+
+
+ O
+
+
+
+
+ O
+
+
+
+
+
+
+
+
+ Ms
+
+
+
+
+
+
+ S
+
+
+
+
+ O
+
+
+
+
+ O
+
+
+
+
+ OH
+
+
+
+
+
+
+
+
+
+ methane sulphonic acid
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/api/tests/integration/tests/formats/ref/agents.b64cdx b/api/tests/integration/tests/formats/ref/agents.b64cdx
index 2c4c248754..ab89eace8b 100644
--- a/api/tests/integration/tests/formats/ref/agents.b64cdx
+++ b/api/tests/integration/tests/formats/ref/agents.b64cdx
@@ -1 +1 @@
-VmpDRDAxMDAEAwIBAAAAAAAAAAAAAAAAAAAAAAUIBAAAAB4AGggCAAMAGwgCAAQAAAEkAAAAAgACAOn9BQBBcmlhbAMA6f0PAFRpbWVzIE5ldyBSb21hbgADMgAIAP///////wAAAAAAAP//AAAAAP////8AAAAA//8AAAAA/////wAAAAD/////AAD//wGAAAAAABAIAgABAA8IAgABAAOABAAAAASABQAAAAACCAB0wJ8Ax53DAAAABIAGAAAAAAIIAGjAvQDHncMAAAAEgAcAAAAAAggAYcDMAHqiqQAAAASACAAAAAACCAB6v70AGqiPAAAABIAJAAAAAAIIAIa/nwAaqI8AAAAEgAoAAAAAAggAjL+QAHqiqQAAAASACwAAAAACCACYv3IAeqKpAAAABIAMAAAAAgQCAAgAKwQCAAAAAAIIAJ+/YwAaqI8ABoAAAAAAAAIIAJ+/YwAaqI8AIwgBAAAABw0AAQAAAAMAYADIAAAATwAAAAAEgA0AAAAAAggAn79jAMedwwAAAAWAIgAAAAQGBAAFAAAABQYEAAYAAAAAAAWAIwAAAAQGBAAGAAAABQYEAAcAAAAABgIAAgAAAAWAJAAAAAQGBAAHAAAABQYEAAgAAAAAAAWAJQAAAAQGBAAIAAAABQYEAAkAAAAABgIAAgAAAAWAJgAAAAQGBAAJAAAABQYEAAoAAAAAAAWAJwAAAAQGBAAFAAAABQYEAAoAAAAABgIAAgAAAAWAKAAAAAQGBAAKAAAABQYEAAsAAAAAAAWAKQAAAAQGBAALAAAABQYEAAwAAAAABgIAAgAAAAWAKgAAAAQGBAALAAAABQYEAA0AAAAAAAAAA4AOAAAABIAPAAAAAAIIAKS9rADk1wUCAAAEgBAAAAAAAggAl73KAOTXBQIAAASAEQAAAAACCACQvdkAmNzrAQAABIASAAAAAAIIAJe9ygBM4dEBAAAEgBMAAAAAAggApL2sAEzh0QEAAASAFAAAAAACCACqvZ0AmNzrAQAABIAVAAAAAAIIALe9fwCY3OsBAAAEgBYAAAAAAggAvb1wAEzh0QEAAASAFwAAAAACCADDvWEA6ua3AQAABIAYAAAAAgQCAAgAKwQCAAEAAAIIAG/CVgBE4eABBoAAAAAAAAIIAG/CVgBE4eABIwgBAAAABw4AAQAAAAMAYADIAAAAT0gAAAAABIAZAAAAAAIIAAu5igBQ4cIBAAAFgCsAAAAEBgQADwAAAAUGBAAQAAAAAAAFgCwAAAAEBgQAEAAAAAUGBAARAAAAAAYCAAIAAAAFgC0AAAAEBgQAEQAAAAUGBAASAAAAAAAFgC4AAAAEBgQAEgAAAAUGBAATAAAAAAYCAAIAAAAFgC8AAAAEBgQAEwAAAAUGBAAUAAAAAAAFgDAAAAAEBgQADwAAAAUGBAAUAAAAAAYCAAIAAAAFgDEAAAAEBgQAFAAAAAUGBAAVAAAAAAAFgDIAAAAEBgQAFQAAAAUGBAAWAAAAAAAFgDMAAAAEBgQAFgAAAAUGBAAXAAAAAAAFgDQAAAAEBgQAFgAAAAUGBAAYAAAAAAAFgDUAAAAEBgQAFgAAAAUGBAAZAAAAAAAAAAOAGgAAAASAGwAAAAIEAgARACsEAgABAAACCAAAAIcAAEA6AQaAAAAAAAACCAAAAIcAAEA6ASMIAQAAAAcPAAEAAAADAGAAyAAAAENsSAAAAAAAACGAHAAAAAQCEAAAwJYAAACAAQBAmAAAAP8ANwoCAAAALwoCAAEAIAoCAMoIMQoCADMCNQoCAAIAMAoCABkABwIMAAAAgAEAwJYAAAAAAAgCDAAAAP8AAECYAAAAAAAAAAaAHwAAAAACCAAAQKcAAIAwAQEHAQAACAcBAAAABxAAAQAAAAQAAACtAAAAdGVzdAAADYAAAAAADoAAAAAAAQwEAAQAAAACDAQADgAAAAUMBAAaAAAABAwEABwAAAAAAAAAAAAAAAAA
\ No newline at end of file
+VmpDRDAxMDAEAwIBAAAAAAAAAAAAAAAAAAAAAAUIBAAAAB4AGggCAAMAGwgCAAQAAAEkAAAAAgACAOn9BQBBcmlhbAMA6f0PAFRpbWVzIE5ldyBSb21hbgADMgAIAP///////wAAAAAAAP//AAAAAP////8AAAAA//8AAAAA/////wAAAAD/////AAD//wGAAAAAABAIAgABAA8IAgABAAOABAAAAASABQAAAAACCAB0wJ8Ax53DAAAABIAGAAAAAAIIAGjAvQDHncMAAAAEgAcAAAAAAggAYcDMAHqiqQAAAASACAAAAAACCAB6v70AGqiPAAAABIAJAAAAAAIIAIa/nwAaqI8AAAAEgAoAAAAAAggAjL+QAHqiqQAAAASACwAAAAACCACYv3IAeqKpAAAABIAMAAAAAgQCAAgAKwQCAAAAAAIIAJ+/YwAaqI8ABoAAAAAAAAIIAJ+/YwAaqI8AIwgBAAAABw0AAQAAAAMAYADIAAAATwAAAAAEgA0AAAAAAggAn79jAMedwwAAAAWAIgAAAAQGBAAFAAAABQYEAAYAAAAAAAWAIwAAAAQGBAAGAAAABQYEAAcAAAAABgIAAgAAAAWAJAAAAAQGBAAHAAAABQYEAAgAAAAAAAWAJQAAAAQGBAAIAAAABQYEAAkAAAAABgIAAgAAAAWAJgAAAAQGBAAJAAAABQYEAAoAAAAAAAWAJwAAAAQGBAAFAAAABQYEAAoAAAAABgIAAgAAAAWAKAAAAAQGBAAKAAAABQYEAAsAAAAAAAWAKQAAAAQGBAALAAAABQYEAAwAAAAABgIAAgAAAAWAKgAAAAQGBAALAAAABQYEAA0AAAAAAAAAA4AOAAAABIAPAAAAAgQCABEAKwQCAAEAAAIIAAAAhwAAQDoBBoAAAAAAAAIIAAAAhwAAQDoBIwgBAAAABw8AAQAAAAMAYADIAAAAQ2xIAAAAAAAAA4AQAAAABIARAAAAAAIIAKS9rADk1wUCAAAEgBIAAAAAAggAl73KAOTXBQIAAASAEwAAAAACCACQvdkAmNzrAQAABIAUAAAAAAIIAJe9ygBM4dEBAAAEgBUAAAAAAggApL2sAEzh0QEAAASAFgAAAAACCACqvZ0AmNzrAQAABIAXAAAAAAIIALe9fwCY3OsBAAAEgBgAAAAAAggAvb1wAEzh0QEAAASAGQAAAAACCADDvWEA6ua3AQAABIAaAAAAAgQCAAgAKwQCAAEAAAIIAG/CVgBE4eABBoAAAAAAAAIIAG/CVgBE4eABIwgBAAAABw4AAQAAAAMAYADIAAAAT0gAAAAABIAbAAAAAAIIAAu5igBQ4cIBAAAFgCsAAAAEBgQAEQAAAAUGBAASAAAAAAAFgCwAAAAEBgQAEgAAAAUGBAATAAAAAAYCAAIAAAAFgC0AAAAEBgQAEwAAAAUGBAAUAAAAAAAFgC4AAAAEBgQAFAAAAAUGBAAVAAAAAAYCAAIAAAAFgC8AAAAEBgQAFQAAAAUGBAAWAAAAAAAFgDAAAAAEBgQAEQAAAAUGBAAWAAAAAAYCAAIAAAAFgDEAAAAEBgQAFgAAAAUGBAAXAAAAAAAFgDIAAAAEBgQAFwAAAAUGBAAYAAAAAAAFgDMAAAAEBgQAGAAAAAUGBAAZAAAAAAAFgDQAAAAEBgQAGAAAAAUGBAAaAAAAAAAFgDUAAAAEBgQAGAAAAAUGBAAbAAAAAAAAACGAHAAAAAQCEAAAwJYAAACAAQBAmAAAAP8ANwoCAAAALwoCAAEAIAoCAMoIMQoCADMCNQoCAAIAMAoCABkABwIMAAAAgAEAwJYAAAAAAAgCDAAAAP8AAECYAAAAAAAAAAaAHwAAAAACCAAAQKcAAIAwAQEHAQAACAcBAAAABxAAAQAAAAQAAACtAAAAdGVzdAAADYAAAAAADoAAAAAAAQwEAAQAAAACDAQAEAAAAAUMBAAOAAAABAwEABwAAAAAAAAAAAAAAAAA
\ No newline at end of file
diff --git a/api/tests/integration/tests/formats/ref/agents.cdxml b/api/tests/integration/tests/formats/ref/agents.cdxml
index 7ff1942b8a..d9796cca00 100644
--- a/api/tests/integration/tests/formats/ref/agents.cdxml
+++ b/api/tests/integration/tests/formats/ref/agents.cdxml
@@ -42,46 +42,46 @@
-
-
-
-
-
-
-
-
-
-
-
- OH
+
+
+ ClH
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ClH
+
+
+
+
+
+
+
+
+
+
+
+
+ OH
+
+
+
+
+
+
+
+
+
+
+
+
test
-
+
diff --git a/api/tests/integration/tests/formats/ref/images.cdxml b/api/tests/integration/tests/formats/ref/images.cdxml
index 5321b6fa97..826e226ec4 100644
--- a/api/tests/integration/tests/formats/ref/images.cdxml
+++ b/api/tests/integration/tests/formats/ref/images.cdxml
@@ -1,39 +1,39 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/api/tests/integration/tests/formats/ref/ket_retro_arrow.b64cdx b/api/tests/integration/tests/formats/ref/ket_retro_arrow.b64cdx
index b5914075f9..32ec92b4bb 100644
--- a/api/tests/integration/tests/formats/ref/ket_retro_arrow.b64cdx
+++ b/api/tests/integration/tests/formats/ref/ket_retro_arrow.b64cdx
@@ -1 +1 @@
-VmpDRDAxMDAEAwIBAAAAAAAAAAAAAAAAAAAAAAUIBAAAAB4AGggCAAMAGwgCAAQAAAEkAAAAAgACAOn9BQBBcmlhbAMA6f0PAFRpbWVzIE5ldyBSb21hbgADMgAIAP///////wAAAAAAAP//AAAAAP////8AAAAA//8AAAAA/////wAAAAD/////AAD//wGAAAAAABAIAgABAA8IAgABAAOABAAAAASABQAAAAACCAAAgBYAEvsoAAAABIAGAAAAAAIIAACA+P8S+ygAAAAEgAcAAAAAAggAAIDp/wAADwAAAASACAAAAAIEAgAHACsEAgACAAACCAAAgOn/JvZCAAaAAAAAAAACCAAAgOn/JvZCACMIAQAAAAcZAAIAAAADAGAAyAAAAAIAAwAgAMgAAABOSDIAAAAABYAQAAAABAYEAAUAAAAFBgQABgAAAAAABYARAAAABAYEAAYAAAAFBgQABwAAAAAABYASAAAABAYEAAYAAAAFBgQACAAAAAAAAAADgAkAAAAEgAoAAAACBAIACAArBAIAAQAAAggAAID4/yf2nAAGgAAAAAAAAggAAID4/yf2nAAjCAEAAAAHDgABAAAAAwBgAMgAAABPSAAAAAAEgAsAAAAAAggAAIAHADnxtgAAAASADAAAAAIEAgAIACsEAgABAAACCAAAgPj/TezQAAaAAAAAAAACCAAAgPj/TezQACMIAQAAAAcOAAEAAAADAGAAyAAAAE9IAAAAAAWAEwAAAAQGBAAKAAAABQYEAAsAAAAAAAWAFAAAAAQGBAALAAAABQYEAAwAAAAAAAAAIYANAAAABAIQAAAAAAAm9n4AAAAAACb2YAA3CgIAAAA1CgIAAgAvCgIAAwAgCgIAWAIwCgIAWAIxCgIAlgAzCgIAWAIHAgwAJvZ+AAAAAAAAAAAACAIMACb2YAAAAAAAAAAAAAAAB4AVAAAAEwAEAA0AAAAACgIAAQACCgIAIAAgCgIAWAIEAhAAAAAAACb2fgAAAAAAJvZgAAAADYAAAAAADoAAAAAAAQwEAAQAAAACDAQACQAAAAQMBAAVAAAAAAAAAAAAAAAAAA==
\ No newline at end of file
+VmpDRDAxMDAEAwIBAAAAAAAAAAAAAAAAAAAAAAUIBAAAAB4AGggCAAMAGwgCAAQAAAEkAAAAAgACAOn9BQBBcmlhbAMA6f0PAFRpbWVzIE5ldyBSb21hbgADMgAIAP///////wAAAAAAAP//AAAAAP////8AAAAA//8AAAAA/////wAAAAD/////AAD//wGAAAAAABAIAgABAA8IAgABAAOABAAAAASABQAAAAIEAgAIACsEAgABAAACCAAAgPj/J/acAAaAAAAAAAACCAAAgPj/J/acACMIAQAAAAcOAAEAAAADAGAAyAAAAE9IAAAAAASABgAAAAACCAAAgAcAOfG2AAAABIAHAAAAAgQCAAgAKwQCAAEAAAIIAACA+P9N7NAABoAAAAAAAAIIAACA+P9N7NAAIwgBAAAABw4AAQAAAAMAYADIAAAAT0gAAAAABYAQAAAABAYEAAUAAAAFBgQABgAAAAAABYARAAAABAYEAAYAAAAFBgQABwAAAAAAAAADgAgAAAAEgAkAAAAAAggAAIAWABL7KAAAAASACgAAAAACCAAAgPj/EvsoAAAABIALAAAAAAIIAACA6f8AAA8AAAAEgAwAAAACBAIABwArBAIAAgAAAggAAIDp/yb2QgAGgAAAAAAAAggAAIDp/yb2QgAjCAEAAAAHGQACAAAAAwBgAMgAAAACAAMAIADIAAAATkgyAAAAAAWAEgAAAAQGBAAJAAAABQYEAAoAAAAAAAWAEwAAAAQGBAAKAAAABQYEAAsAAAAAAAWAFAAAAAQGBAAKAAAABQYEAAwAAAAAAAAAIYANAAAABAIQAAAAAAAm9n4AAAAAACb2YAA3CgIAAAA1CgIAAgAvCgIAAwAgCgIAWAIwCgIAWAIxCgIAlgAzCgIAWAIHAgwAJvZ+AAAAAAAAAAAACAIMACb2YAAAAAAAAAAAAAAAB4AVAAAAEwAEAA0AAAAACgIAAQACCgIAIAAgCgIAWAIEAhAAAAAAACb2fgAAAAAAJvZgAAAADYAAAAAADoAAAAAAAQwEAAgAAAACDAQABAAAAAQMBAAVAAAAAAAAAAAAAAAAAA==
\ No newline at end of file
diff --git a/api/tests/integration/tests/formats/ref/ket_retro_arrow.cdxml b/api/tests/integration/tests/formats/ref/ket_retro_arrow.cdxml
index c394758f9d..c3dd2bfac0 100644
--- a/api/tests/integration/tests/formats/ref/ket_retro_arrow.cdxml
+++ b/api/tests/integration/tests/formats/ref/ket_retro_arrow.cdxml
@@ -18,38 +18,38 @@
-
-
-
-
-
- NH
- 2
-
-
-
-
-
-
-
-
+
OH
-
-
+
+
OH
+
+
+
+
+
+
+
+
+
+ NH
+ 2
+
+
+
-
+
-
+
diff --git a/api/tests/integration/tests/formats/ref/ket_retro_arrow_sum_of_reactants.b64cdx b/api/tests/integration/tests/formats/ref/ket_retro_arrow_sum_of_reactants.b64cdx
index 8a5c078957..02eb0b61ee 100644
--- a/api/tests/integration/tests/formats/ref/ket_retro_arrow_sum_of_reactants.b64cdx
+++ b/api/tests/integration/tests/formats/ref/ket_retro_arrow_sum_of_reactants.b64cdx
@@ -1 +1 @@
-VmpDRDAxMDAEAwIBAAAAAAAAAAAAAAAAAAAAAAUIBAAAAB4AGggCAAMAGwgCAAQAAAEkAAAAAgACAOn9BQBBcmlhbAMA6f0PAFRpbWVzIE5ldyBSb21hbgADMgAIAP///////wAAAAAAAP//AAAAAP////8AAAAA//8AAAAA/////wAAAAD/////AAD//wGAAAAAABAIAgABAA8IAgABAAOABAAAAASABQAAAAACCABaawgBsN2NAQAABIAGAAAAAAIIAFlr6gCw3Y0BAAAEgAcAAAAAAggAWWvbAJzicwEAAASACAAAAAIEAgAHACsEAgACAAACCABZa9sAxNinAQaAAAAAAAACCABZa9sAxNinASMIAQAAAAcZAAIAAAADAGAAyAAAAAIAAwAgAMgAAABOSDIAAAAABYAZAAAABAYEAAUAAAAFBgQABgAAAAAABYAaAAAABAYEAAYAAAAFBgQABwAAAAAABYAbAAAABAYEAAYAAAAFBgQACAAAAAAAAAADgAkAAAAEgAoAAAAAAggAM9baAACeAwIAAASACwAAAAACCACAAAkBAp70AQAABIAMAAAAAAIIAGN47ADCWOsBAAAEgA0AAAAAAggAgAAJAQCeEgIAAASADgAAAAACCABkeOwAROMbAgAABYAcAAAABAYEAAoAAAAFBgQADgAAAAAABYAdAAAABAYEAA4AAAAFBgQADQAAAAAGAgACAAAABYAeAAAABAYEAA0AAAAFBgQACwAAAAAABYAfAAAABAYEAAsAAAAFBgQADAAAAAAGAgACAAAABYAgAAAABAYEAAwAAAAFBgQACgAAAAAAAAADgA8AAAAEgBAAAAACBAIACAArBAIAAQAAAggAWWvqAEQjkAIGgAAAAAAAAggAWWvqAEQjkAIjCAEAAAAHDgABAAAAAwBgAMgAAABPSAAAAAAEgBEAAAAAAggAWmv5AFgeqgIAAASAEgAAAAIEAgAIACsEAgABAAACCABZa+oAbBnEAgaAAAAAAAACCABZa+oAbBnEAiMIAQAAAAcOAAEAAAADAGAAyAAAAE9IAAAAAAWAIQAAAAQGBAAQAAAABQYEABEAAAAAAAWAIgAAAAQGBAARAAAABQYEABIAAAAAAAAAIYATAAAABAIQAFrr8QBEY30CWuvxAESjLgI3CgIAAAA1CgIAAgAvCgIAAwAgCgIAWAIwCgIAWAIxCgIAlgAzCgIAWAIHAgwARGN9Alrr8QAAAAAACAIMAESjLgJa6/EAAAAAAAAAB4AjAAAAEwAEABMAAAAACgIAAQACCgIAIAAgCgIAWAIEAhAAWuvxAERjfQJa6/EARKMuAgAAB4AWAAAABAIQAFqr9QDEmMkBWivuAMSYyQEACgIABwAHCgIACAAAAA2AAAAAAA6AAAAAAAEMCAAEAAAACQAAAAIMBAAPAAAABAwEACMAAAAAAAAAAAAAAAAA
\ No newline at end of file
+VmpDRDAxMDAEAwIBAAAAAAAAAAAAAAAAAAAAAAUIBAAAAB4AGggCAAMAGwgCAAQAAAEkAAAAAgACAOn9BQBBcmlhbAMA6f0PAFRpbWVzIE5ldyBSb21hbgADMgAIAP///////wAAAAAAAP//AAAAAP////8AAAAA//8AAAAA/////wAAAAD/////AAD//wGAAAAAABAIAgABAA8IAgABAAOABAAAAASABQAAAAIEAgAIACsEAgABAAACCABZa+oARCOQAgaAAAAAAAACCABZa+oARCOQAiMIAQAAAAcOAAEAAAADAGAAyAAAAE9IAAAAAASABgAAAAACCABaa/kAWB6qAgAABIAHAAAAAgQCAAgAKwQCAAEAAAIIAFlr6gBsGcQCBoAAAAAAAAIIAFlr6gBsGcQCIwgBAAAABw4AAQAAAAMAYADIAAAAT0gAAAAABYAZAAAABAYEAAUAAAAFBgQABgAAAAAABYAaAAAABAYEAAYAAAAFBgQABwAAAAAAAAADgAgAAAAEgAkAAAAAAggAWmsIAbDdjQEAAASACgAAAAACCABZa+oAsN2NAQAABIALAAAAAAIIAFlr2wCc4nMBAAAEgAwAAAACBAIABwArBAIAAgAAAggAWWvbAMTYpwEGgAAAAAAAAggAWWvbAMTYpwEjCAEAAAAHGQACAAAAAwBgAMgAAAACAAMAIADIAAAATkgyAAAAAAWAGwAAAAQGBAAJAAAABQYEAAoAAAAAAAWAHAAAAAQGBAAKAAAABQYEAAsAAAAAAAWAHQAAAAQGBAAKAAAABQYEAAwAAAAAAAAAA4ANAAAABIAOAAAAAAIIADPW2gAAngMCAAAEgA8AAAAAAggAgAAJAQKe9AEAAASAEAAAAAACCABjeOwAwljrAQAABIARAAAAAAIIAIAACQEAnhICAAAEgBIAAAAAAggAZHjsAETjGwIAAAWAHgAAAAQGBAAOAAAABQYEABIAAAAAAAWAHwAAAAQGBAASAAAABQYEABEAAAAABgIAAgAAAAWAIAAAAAQGBAARAAAABQYEAA8AAAAAAAWAIQAAAAQGBAAPAAAABQYEABAAAAAABgIAAgAAAAWAIgAAAAQGBAAQAAAABQYEAA4AAAAAAAAAIYATAAAABAIQAFrr8QBEY30CWuvxAESjLgI3CgIAAAA1CgIAAgAvCgIAAwAgCgIAWAIwCgIAWAIxCgIAlgAzCgIAWAIHAgwARGN9Alrr8QAAAAAACAIMAESjLgJa6/EAAAAAAAAAB4AjAAAAEwAEABMAAAAACgIAAQACCgIAIAAgCgIAWAIEAhAAWuvxAERjfQJa6/EARKMuAgAAB4AWAAAABAIQAFqr9QDEmMkBWivuAMSYyQEACgIABwAHCgIACAAAAA2AAAAAAA6AAAAAAAEMCAAIAAAADQAAAAIMBAAEAAAABAwEACMAAAAAAAAAAAAAAAAA
\ No newline at end of file
diff --git a/api/tests/integration/tests/formats/ref/ket_retro_arrow_sum_of_reactants.cdxml b/api/tests/integration/tests/formats/ref/ket_retro_arrow_sum_of_reactants.cdxml
index d4c5b89413..dd76f4395b 100644
--- a/api/tests/integration/tests/formats/ref/ket_retro_arrow_sum_of_reactants.cdxml
+++ b/api/tests/integration/tests/formats/ref/ket_retro_arrow_sum_of_reactants.cdxml
@@ -18,51 +18,51 @@
-
-
-
-
-
- NH
- 2
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
OH
-
-
+
+
OH
-
-
+
+
+
+
+
+
+
+
+
+ NH
+ 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/api/tests/integration/tests/formats/ref/macro/sa-mono.cdxml b/api/tests/integration/tests/formats/ref/macro/sa-mono.cdxml
index f355ac90c2..3618a3c544 100644
--- a/api/tests/integration/tests/formats/ref/macro/sa-mono.cdxml
+++ b/api/tests/integration/tests/formats/ref/macro/sa-mono.cdxml
@@ -1,84 +1,84 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- OH
-
-
-
-
-
-
- OH
-
-
-
-
-
-
- NH
-
-
-
-
-
-
-
-
-
- O
-
-
-
-
-
-
-
-
-
-
- A
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Chiral
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ OH
+
+
+
+
+
+
+ OH
+
+
+
+
+
+
+ NH
+
+
+
+
+
+
+
+
+
+ O
+
+
+
+
+
+
+
+
+
+
+ A
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Chiral
+
+
+
+
+
diff --git a/api/tests/integration/tests/formats/ref/merge_test1.rxn b/api/tests/integration/tests/formats/ref/merge_test1.rxn
new file mode 100644
index 0000000000..e8258b82cb
--- /dev/null
+++ b/api/tests/integration/tests/formats/ref/merge_test1.rxn
@@ -0,0 +1,30 @@
+$RXN
+
+ -INDIGO- 0100000000
+
+ 1 0
+$MOL
+
+ -INDIGO-01000000002D
+
+ 10 8 0 0 0 0 0 0 0 0999 V2000
+ 12.5250 -9.9000 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.9000 -10.0000 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.9000 -9.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.7660 -8.5000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 8.9000 -10.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 8.0340 -9.5000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.9000 -11.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.0340 -11.5000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.9000 -10.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.6071 -10.7071 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 4 1 0 0 0 0
+ 2 5 1 0 0 0 0
+ 5 6 1 0 0 0 0
+ 2 7 1 0 0 0 0
+ 7 8 1 0 0 0 0
+ 2 9 1 0 0 0 0
+ 9 10 1 0 0 0 0
+M CHG 2 1 -1 2 1
+M END
diff --git a/api/tests/integration/tests/formats/ref/merge_test1a.rxn b/api/tests/integration/tests/formats/ref/merge_test1a.rxn
new file mode 100644
index 0000000000..d2865fbb68
--- /dev/null
+++ b/api/tests/integration/tests/formats/ref/merge_test1a.rxn
@@ -0,0 +1,30 @@
+$RXN
+
+ -INDIGO- 0100000000
+
+ 0 1
+$MOL
+
+ -INDIGO-01000000002D
+
+ 10 8 0 0 0 0 0 0 0 0999 V2000
+ 20.0955 -9.8500 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
+ 20.0955 -8.8500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 20.9615 -8.3500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.0955 -9.8500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.2295 -9.3500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 20.0955 -10.8500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.2295 -11.3500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.0955 -9.8500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.8026 -10.5571 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 22.7205 -9.7500 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 1 4 1 0 0 0 0
+ 4 5 1 0 0 0 0
+ 1 6 1 0 0 0 0
+ 6 7 1 0 0 0 0
+ 1 8 1 0 0 0 0
+ 8 9 1 0 0 0 0
+M CHG 2 1 1 10 -1
+M END
diff --git a/api/tests/integration/tests/formats/ref/merge_test2.rxn b/api/tests/integration/tests/formats/ref/merge_test2.rxn
new file mode 100644
index 0000000000..a7a067ed01
--- /dev/null
+++ b/api/tests/integration/tests/formats/ref/merge_test2.rxn
@@ -0,0 +1,41 @@
+$RXN
+
+ -INDIGO- 0100000000
+
+ 1 1
+$MOL
+
+ -INDIGO-01000000002D
+
+ 4 4 0 0 0 0 0 0 0 0999 V2000
+ 8.4572 -9.0225 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 8.4535 -8.0275 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 7.4453 -9.0096 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 7.4428 -8.0275 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 8 8 0 0 0 0 0 0 0 0999 V2000
+ 13.5322 -9.1225 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 13.5285 -8.1275 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.5203 -9.1096 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.5178 -8.1275 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 13.5072 -7.6475 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 13.5035 -6.6525 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.4953 -7.6346 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.4928 -6.6525 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+ 5 6 1 0 0 0 0
+ 6 8 1 0 0 0 0
+ 8 7 1 0 0 0 0
+ 7 5 1 0 0 0 0
+M END
diff --git a/api/tests/integration/tests/formats/ref/merge_test2a.rxn b/api/tests/integration/tests/formats/ref/merge_test2a.rxn
new file mode 100644
index 0000000000..dc63926482
--- /dev/null
+++ b/api/tests/integration/tests/formats/ref/merge_test2a.rxn
@@ -0,0 +1,41 @@
+$RXN
+
+ -INDIGO- 0100000000
+
+ 1 1
+$MOL
+
+ -INDIGO-01000000002D
+
+ 8 8 0 0 0 0 0 0 0 0999 V2000
+ 16.9697 -11.4100 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 16.9660 -10.4150 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 15.9578 -11.3971 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 15.9553 -10.4150 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 16.9447 -9.9350 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 16.9410 -8.9400 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 15.9328 -9.9221 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 15.9303 -8.9400 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+ 5 6 1 0 0 0 0
+ 6 8 1 0 0 0 0
+ 8 7 1 0 0 0 0
+ 7 5 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 4 4 0 0 0 0 0 0 0 0999 V2000
+ 21.9697 -11.6600 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.9660 -10.6650 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 20.9578 -11.6471 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 20.9553 -10.6650 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+M END
diff --git a/api/tests/integration/tests/formats/ref/merge_test3.rxn b/api/tests/integration/tests/formats/ref/merge_test3.rxn
new file mode 100644
index 0000000000..2da71decab
--- /dev/null
+++ b/api/tests/integration/tests/formats/ref/merge_test3.rxn
@@ -0,0 +1,68 @@
+$RXN
+
+ -INDIGO- 0100000000
+
+ 2 1 2
+$MOL
+
+ -INDIGO-01000000002D
+
+ 4 4 0 0 0 0 0 0 0 0999 V2000
+ 9.5322 -8.3475 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.5285 -7.3525 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 8.5203 -8.3346 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 8.5178 -7.3525 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 4 3 0 0 0 0 0 0 0 0999 V2000
+ 11.4744 -8.3075 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.4756 -8.3075 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.9750 -7.4425 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 13.0500 -7.4000 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+M CHG 1 4 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 6 4 0 0 0 0 0 0 0 0999 V2000
+ 16.7250 -8.3500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.5910 -7.8500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.5910 -6.8500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.6750 -6.9750 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.6750 -7.9750 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.5410 -8.4750 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 4 5 1 0 0 0 0
+ 5 6 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 1 0 0 0 0 0 0 0 0 0999 V2000
+ 14.7500 -7.2500 0.0000 Br 0 0 0 0 0 0 0 0 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 3 3 0 0 0 0 0 0 0 0999 V2000
+ 14.2244 -6.8325 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 15.2256 -6.8325 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 14.7250 -5.9675 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+M END
diff --git a/api/tests/integration/tests/formats/ref/merge_test3a.rxn b/api/tests/integration/tests/formats/ref/merge_test3a.rxn
new file mode 100644
index 0000000000..174f8fd486
--- /dev/null
+++ b/api/tests/integration/tests/formats/ref/merge_test3a.rxn
@@ -0,0 +1,68 @@
+$RXN
+
+ -INDIGO- 0100000000
+
+ 2 1 2
+$MOL
+
+ -INDIGO-01000000002D
+
+ 4 4 0 0 0 0 0 0 0 0999 V2000
+ 9.5322 -8.3475 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.5285 -7.3525 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 8.5203 -8.3346 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 8.5178 -7.3525 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 4 3 0 0 0 0 0 0 0 0999 V2000
+ 11.4744 -8.3075 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.4756 -8.3075 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.9750 -7.4425 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 13.0500 -7.4000 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+M CHG 1 4 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 6 4 0 0 0 0 0 0 0 0999 V2000
+ 16.7250 -8.3500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.5910 -7.8500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.5910 -6.8500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.6750 -6.9750 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.6750 -7.9750 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.5410 -8.4750 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 4 5 1 0 0 0 0
+ 5 6 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 1 0 0 0 0 0 0 0 0 0999 V2000
+ 14.7500 -8.3500 0.0000 Br 0 0 0 0 0 0 0 0 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 3 3 0 0 0 0 0 0 0 0999 V2000
+ 14.1494 -9.8325 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 15.1506 -9.8325 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 14.6501 -8.9675 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+M END
diff --git a/api/tests/integration/tests/formats/ref/merge_test4.rxn b/api/tests/integration/tests/formats/ref/merge_test4.rxn
new file mode 100644
index 0000000000..2e3b33477a
--- /dev/null
+++ b/api/tests/integration/tests/formats/ref/merge_test4.rxn
@@ -0,0 +1,64 @@
+$RXN
+
+ -INDIGO- 0100000000
+
+ 3 1
+$MOL
+
+ -INDIGO-01000000002D
+
+ 4 3 0 0 0 0 0 0 0 0999 V2000
+ 8.3244 -8.3075 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.3256 -8.3075 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 8.8251 -7.4425 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 8.0750 -7.1250 0.0000 I 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+M CHG 1 4 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 2 0 0 0 0 0 0 0 0 0999 V2000
+ 10.5500 -7.8500 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.4000 -7.1000 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
+M CHG 2 1 -1 2 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 8 8 0 0 0 0 0 0 0 0999 V2000
+ 12.5545 -7.4186 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 13.3384 -6.8010 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 14.3114 -7.0236 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 14.7455 -7.9194 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.5600 -8.4258 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 14.3121 -8.8264 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 13.3384 -9.0490 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 15.1775 -6.5236 0.0000 Br 0 0 0 0 0 0 0 0 0 0 0 0
+ 2 1 1 0 0 0 0
+ 1 5 1 0 0 0 0
+ 5 7 1 0 0 0 0
+ 7 6 1 0 0 0 0
+ 6 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 2 1 0 0 0 0
+ 3 8 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 4 4 0 0 0 0 0 0 0 0999 V2000
+ 22.0572 -8.3725 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 22.0535 -7.3775 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.0453 -8.3596 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.0428 -7.3775 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+M END
diff --git a/api/tests/integration/tests/formats/ref/merge_test5.rxn b/api/tests/integration/tests/formats/ref/merge_test5.rxn
new file mode 100644
index 0000000000..3a173d2be4
--- /dev/null
+++ b/api/tests/integration/tests/formats/ref/merge_test5.rxn
@@ -0,0 +1,27 @@
+$RXN
+
+ -INDIGO- 0100000000
+
+ 0 0 2
+$MOL
+
+ -INDIGO-01000000002D
+
+ 4 4 0 0 0 0 0 0 0 0999 V2000
+ 18.3322 -7.4725 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.3285 -6.4775 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.3203 -7.4596 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.3178 -6.4775 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 1 0 0 0 0 0 0 0 0 0999 V2000
+ 18.9500 -6.9500 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+M CHG 1 1 -1
+M END
diff --git a/api/tests/integration/tests/formats/ref/merge_test6.rxn b/api/tests/integration/tests/formats/ref/merge_test6.rxn
new file mode 100644
index 0000000000..acb6c1dd9e
--- /dev/null
+++ b/api/tests/integration/tests/formats/ref/merge_test6.rxn
@@ -0,0 +1,98 @@
+$RXN
+
+ -INDIGO- 0100000000
+
+ 2 2 2
+$MOL
+
+ -INDIGO-01000000002D
+
+ 9 6 0 0 0 0 0 0 0 0999 V2000
+ 18.2250 -7.2500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.7250 -8.1160 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.2250 -8.9821 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 16.0750 -7.1000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 16.0750 -8.1000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 16.9410 -8.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 16.9410 -9.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.8071 -10.1000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.2250 -6.1750 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 4 5 1 0 0 0 0
+ 5 6 1 0 0 0 0
+ 6 7 1 0 0 0 0
+ 7 8 1 0 0 0 0
+M CHG 1 9 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 7 6 0 0 0 0 0 0 0 0999 V2000
+ 22.6572 -8.4975 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 22.6535 -7.5025 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.6453 -8.4846 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.6428 -7.5025 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 20.6769 -7.2436 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.5000 -9.5750 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 22.5000 -9.5750 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+ 4 5 1 0 0 0 0
+ 6 7 1 0 0 0 0
+M CHG 1 6 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 6 5 0 0 0 0 0 0 0 0999 V2000
+ 29.1822 -8.4725 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 29.1785 -7.4775 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 28.1703 -8.4596 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 28.1678 -7.4775 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 29.8893 -9.1797 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 29.7250 -8.0500 0.0000 I 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+ 1 5 1 0 0 0 0
+M CHG 1 6 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 2 0 0 0 0 0 0 0 0 0999 V2000
+ 31.5250 -8.1500 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
+ 31.8250 -9.0250 0.0000 Br 0 0 0 0 0 0 0 0 0 0 0 0
+M CHG 2 1 -1 2 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 5 5 0 0 0 0 0 0 0 0999 V2000
+ 25.6483 -7.6475 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 25.6446 -6.6525 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 24.6364 -7.6346 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 24.6339 -6.6525 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 23.9268 -5.9453 0.0000 P 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+ 4 5 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 1 0 0 0 0 0 0 0 0 0999 V2000
+ 26.2661 -7.1250 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+M CHG 1 1 -1
+M END
diff --git a/api/tests/integration/tests/formats/ref/merge_test7.rxn b/api/tests/integration/tests/formats/ref/merge_test7.rxn
new file mode 100644
index 0000000000..f9733a467a
--- /dev/null
+++ b/api/tests/integration/tests/formats/ref/merge_test7.rxn
@@ -0,0 +1,83 @@
+$RXN
+
+ -INDIGO- 0100000000
+
+ 1 1 6
+$MOL
+
+ -INDIGO-01000000002D
+
+ 6 6 0 0 0 0 0 0 0 0999 V2000
+ 9.5250 -10.2910 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.5250 -10.2910 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.0250 -9.4250 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.5250 -8.5590 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.5250 -8.5590 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.0250 -9.4250 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 6 1 1 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 4 1 0 0 0 0
+ 4 5 1 0 0 0 0
+ 5 6 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 6 6 0 0 0 0 0 0 0 0999 V2000
+ 18.3000 -10.3410 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.3000 -10.3410 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.8000 -9.4750 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.3000 -8.6090 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.3000 -8.6090 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.8000 -9.4750 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 6 1 1 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 4 1 0 0 0 0
+ 4 5 1 0 0 0 0
+ 5 6 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 1 0 0 0 0 0 0 0 0 0999 V2000
+ 23.4000 -7.0750 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 1 0 0 0 0 0 0 0 0 0999 V2000
+ 24.7500 -6.2250 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 1 0 0 0 0 0 0 0 0 0999 V2000
+ 26.4250 -6.3000 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 1 0 0 0 0 0 0 0 0 0999 V2000
+ 27.6500 -6.7500 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 1 0 0 0 0 0 0 0 0 0999 V2000
+ 25.4250 -6.7750 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 1 0 0 0 0 0 0 0 0 0999 V2000
+ 23.5750 -6.2750 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+M END
diff --git a/api/tests/integration/tests/formats/ref/multi_merge1.rdf b/api/tests/integration/tests/formats/ref/multi_merge1.rdf
new file mode 100644
index 0000000000..73c0292a80
--- /dev/null
+++ b/api/tests/integration/tests/formats/ref/multi_merge1.rdf
@@ -0,0 +1,94 @@
+$RDFILE 1
+$DATM 01/00/00 00:00
+$RDFILE 1
+$DATM 01/00/00 00:00
+$RFMT
+$RXN
+
+ -INDIGO- 0100000000
+
+ 1 1
+$MOL
+
+ -INDIGO-01000000002D
+
+ 4 4 0 0 0 0 0 0 0 0999 V2000
+ 11.7822 -9.0225 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.7785 -8.0275 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.7703 -9.0096 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.7678 -8.0275 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 8 8 0 0 0 0 0 0 0 0999 V2000
+ 17.3244 -8.9325 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.3256 -8.9325 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.8251 -8.0675 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.8322 -9.0725 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.8285 -8.0775 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.8203 -9.0596 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.8178 -8.0775 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 20.6945 -7.5775 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+ 4 5 1 0 0 0 0
+ 5 7 1 0 0 0 0
+ 7 6 1 0 0 0 0
+ 6 4 1 0 0 0 0
+ 5 8 1 0 0 0 0
+M END
+$RFMT
+$RXN
+
+ -INDIGO- 0100000000
+
+ 1 1
+$MOL
+
+ -INDIGO-01000000002D
+
+ 7 7 0 0 0 0 0 0 0 0999 V2000
+ 17.5545 -14.8936 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.3384 -14.2760 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.3114 -14.4986 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.7455 -15.3944 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.5600 -15.9008 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.3121 -16.3014 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.3384 -16.5240 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 2 1 1 0 0 0 0
+ 1 5 1 0 0 0 0
+ 5 7 1 0 0 0 0
+ 7 6 1 0 0 0 0
+ 6 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 2 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 8 8 0 0 0 0 0 0 0 0999 V2000
+ 17.3244 -8.9325 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.3256 -8.9325 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.8251 -8.0675 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.8322 -9.0725 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.8285 -8.0775 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.8203 -9.0596 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.8178 -8.0775 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 20.6945 -7.5775 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+ 4 5 1 0 0 0 0
+ 5 7 1 0 0 0 0
+ 7 6 1 0 0 0 0
+ 6 4 1 0 0 0 0
+ 5 8 1 0 0 0 0
+M END
diff --git a/api/tests/integration/tests/formats/ref/multi_merge2.rdf b/api/tests/integration/tests/formats/ref/multi_merge2.rdf
new file mode 100644
index 0000000000..21326c12f2
--- /dev/null
+++ b/api/tests/integration/tests/formats/ref/multi_merge2.rdf
@@ -0,0 +1,104 @@
+$RDFILE 1
+$DATM 01/00/00 00:00
+$RDFILE 1
+$DATM 01/00/00 00:00
+$RFMT
+$RXN
+
+ -INDIGO- 0100000000
+
+ 1 2
+$MOL
+
+ -INDIGO-01000000002D
+
+ 5 4 0 0 0 0 0 0 0 0999 V2000
+ 8.2572 -8.3725 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 8.2535 -7.3775 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 7.2453 -8.3596 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 7.2428 -7.3775 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 8.9250 -7.8250 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+M CHG 1 5 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 4 3 0 0 0 0 0 0 0 0999 V2000
+ 12.7744 -8.2575 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 13.7756 -8.2575 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 13.2751 -7.3925 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.8500 -6.9750 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+M CHG 1 4 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 4 4 0 0 0 0 0 0 0 0999 V2000
+ 16.2072 -8.3475 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 16.2035 -7.3525 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 15.1953 -8.3346 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 15.1928 -7.3525 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+M END
+$RFMT
+$RXN
+
+ -INDIGO- 0100000000
+
+ 1 2
+$MOL
+
+ -INDIGO-01000000002D
+
+ 5 4 0 0 0 0 0 0 0 0999 V2000
+ 27.9572 -8.4238 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 27.9535 -7.4287 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 26.9453 -8.4109 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 26.9428 -7.4287 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 28.6250 -7.8762 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+M CHG 1 5 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 4 3 0 0 0 0 0 0 0 0999 V2000
+ 19.9994 -8.3087 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.0006 -8.3087 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 20.5000 -7.4438 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 20.0750 -7.0262 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+M CHG 1 4 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 4 4 0 0 0 0 0 0 0 0999 V2000
+ 23.4322 -8.3988 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 23.4285 -7.4037 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 22.4203 -8.3859 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 22.4178 -7.4037 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+M END
diff --git a/api/tests/integration/tests/formats/ref/multi_merge3.rdf b/api/tests/integration/tests/formats/ref/multi_merge3.rdf
new file mode 100644
index 0000000000..25a8628a78
--- /dev/null
+++ b/api/tests/integration/tests/formats/ref/multi_merge3.rdf
@@ -0,0 +1,80 @@
+$RDFILE 1
+$DATM 01/00/00 00:00
+$RDFILE 1
+$DATM 01/00/00 00:00
+$RFMT
+$RXN
+
+ -INDIGO- 0100000000
+
+ 1 1
+$MOL
+
+ -INDIGO-01000000002D
+
+ 5 4 0 0 0 0 0 0 0 0999 V2000
+ 18.3072 -7.7475 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.3035 -6.7525 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.2953 -7.7346 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.2928 -6.7525 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.8750 -8.4250 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 3 3 0 0 0 0 0 0 0 0999 V2000
+ 22.5994 -7.6575 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 23.6006 -7.6575 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 23.1000 -6.7925 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+M END
+$RFMT
+$RXN
+
+ -INDIGO- 0100000000
+
+ 1 1
+$MOL
+
+ -INDIGO-01000000002D
+
+ 8 7 0 0 0 0 0 0 0 0999 V2000
+ 17.1045 -10.1186 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.8884 -9.5010 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.8614 -9.7236 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.2955 -10.6194 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.1100 -11.1258 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.8621 -11.5264 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.8884 -11.7490 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.0000 -8.9750 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 2 1 1 0 0 0 0
+ 1 5 1 0 0 0 0
+ 5 7 1 0 0 0 0
+ 7 6 1 0 0 0 0
+ 6 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 2 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 5 5 0 0 0 0 0 0 0 0999 V2000
+ 24.1750 -9.6306 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 24.9840 -10.2184 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 24.6750 -11.1694 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 23.6750 -11.1694 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 23.3660 -10.2184 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 5 1 0 0 0 0
+ 5 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 2 1 0 0 0 0
+ 2 1 1 0 0 0 0
+M END
diff --git a/api/tests/integration/tests/formats/ref/multi_merge4.ket b/api/tests/integration/tests/formats/ref/multi_merge4.ket
new file mode 100644
index 0000000000..b8f0d53d73
--- /dev/null
+++ b/api/tests/integration/tests/formats/ref/multi_merge4.ket
@@ -0,0 +1,1035 @@
+{
+ "root": {
+ "nodes": [
+ {
+ "$ref": "mol0"
+ },
+ {
+ "$ref": "mol1"
+ },
+ {
+ "$ref": "mol2"
+ },
+ {
+ "$ref": "mol3"
+ },
+ {
+ "$ref": "mol4"
+ },
+ {
+ "$ref": "mol5"
+ },
+ {
+ "$ref": "mol6"
+ },
+ {
+ "$ref": "mol7"
+ },
+ {
+ "$ref": "mol8"
+ },
+ {
+ "$ref": "mol9"
+ },
+ {
+ "$ref": "mol10"
+ },
+ {
+ "$ref": "mol11"
+ },
+ {
+ "$ref": "mol12"
+ },
+ {
+ "$ref": "mol13"
+ },
+ {
+ "$ref": "mol14"
+ },
+ {
+ "$ref": "mol15"
+ },
+ {
+ "$ref": "mol16"
+ },
+ {
+ "$ref": "mol17"
+ },
+ {
+ "$ref": "mol18"
+ },
+ {
+ "$ref": "mol19"
+ },
+ {
+ "$ref": "mol20"
+ },
+ {
+ "$ref": "mol21"
+ },
+ {
+ "$ref": "mol22"
+ },
+ {
+ "$ref": "mol23"
+ },
+ {
+ "$ref": "mol24"
+ },
+ {
+ "$ref": "mol25"
+ },
+ {
+ "$ref": "mol26"
+ },
+ {
+ "$ref": "mol27"
+ },
+ {
+ "$ref": "mol28"
+ },
+ {
+ "$ref": "mol29"
+ },
+ {
+ "$ref": "mol30"
+ },
+ {
+ "$ref": "mol31"
+ },
+ {
+ "$ref": "mol32"
+ },
+ {
+ "$ref": "mol33"
+ },
+ {
+ "$ref": "mol34"
+ },
+ {
+ "$ref": "mol35"
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 17.412889,
+ "y": -15.460501,
+ "z": 0.0
+ },
+ {
+ "x": 19.537889,
+ "y": -17.210501,
+ "z": 0.0
+ }
+ ]
+ }
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 8.16289,
+ "y": -15.4855,
+ "z": 0.0
+ },
+ {
+ "x": 6.53789,
+ "y": -17.460501,
+ "z": 0.0
+ }
+ ]
+ }
+ },
+ {
+ "type": "arrow",
+ "data": {
+ "mode": "open-angle",
+ "pos": [
+ {
+ "x": 12.66289,
+ "y": -9.785501,
+ "z": 0.0
+ },
+ {
+ "x": 12.66289,
+ "y": -7.758033,
+ "z": 0.0
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "mol0": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 8.312264,
+ -14.742971,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 9.313516,
+ -14.742971,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 8.812941,
+ -13.878031,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol1": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "O",
+ "location": [
+ 10.503628,
+ -12.15,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol2": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 11.278627,
+ -12.775,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol3": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 11.403627,
+ -12.15,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol4": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Br",
+ "location": [
+ 11.453628,
+ -11.6,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol5": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Br",
+ "location": [
+ 11.578628,
+ -11.1,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol6": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 13.120097,
+ -11.558049,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 13.116394,
+ -10.562952,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.108185,
+ -11.545137,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.105682,
+ -10.562952,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol7": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 9.86289,
+ -14.935501,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol8": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 10.837891,
+ -15.8605,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol9": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 10.38789,
+ -15.460501,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol10": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "P",
+ "location": [
+ 10.278627,
+ -16.450001,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol11": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 11.31289,
+ -16.185501,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol12": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 11.228627,
+ -13.375,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol13": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Cl",
+ "location": [
+ 11.603627,
+ -13.875,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol14": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "O",
+ "location": [
+ 10.353627,
+ -16.975,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol15": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "P",
+ "location": [
+ 11.928628,
+ -14.3,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol16": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 11.91289,
+ -16.3855,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol17": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "S",
+ "location": [
+ 9.978627,
+ -17.65,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol18": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "N",
+ "location": [
+ 9.678628,
+ -18.4,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol19": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "H",
+ "location": [
+ 9.628628,
+ -11.65,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol20": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "N",
+ "location": [
+ 9.153627,
+ -11.1,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol21": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 16.11289,
+ -13.49106,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 16.921881,
+ -14.078853,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 16.612885,
+ -15.029942,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 15.612896,
+ -15.029942,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 15.3039,
+ -14.078853,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 4,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 0
+ ]
+ }
+ ]
+ },
+ "mol22": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "Br",
+ "location": [
+ 12.628628,
+ -15.775,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol23": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "I",
+ "location": [
+ 12.653627,
+ -15.25,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol24": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 12.78789,
+ -16.3855,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol25": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 13.56289,
+ -16.310501,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol26": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 14.028627,
+ -16.775,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol27": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "S",
+ "location": [
+ 14.178628,
+ -17.424999,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol28": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 14.003628,
+ -18.049999,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol29": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 14.28789,
+ -16.185501,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol30": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 14.81289,
+ -15.760501,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol31": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 14.93789,
+ -15.310501,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol32": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "F",
+ "location": [
+ 15.11289,
+ -14.810501,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol33": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 20.61289,
+ -17.566061,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 21.421881,
+ -18.153852,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 21.112885,
+ -19.10494,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 20.112896,
+ -19.10494,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 19.8039,
+ -18.153852,
+ 0.0
+ ]
+ },
+ {
+ "label": "I",
+ "location": [
+ 21.81999,
+ -19.812048,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 4,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 5
+ ]
+ }
+ ]
+ },
+ "mol34": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 5.237264,
+ -18.517971,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 6.238516,
+ -18.517971,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 5.73794,
+ -17.65303,
+ 0.0
+ ]
+ },
+ {
+ "label": "Br",
+ "location": [
+ 6.945623,
+ -19.225079,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ }
+ ]
+ },
+ "mol35": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 13.195098,
+ -7.133049,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 13.191394,
+ -6.137952,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.183185,
+ -7.120138,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 12.180683,
+ -6.137952,
+ 0.0
+ ]
+ },
+ {
+ "label": "S",
+ "location": [
+ 14.05742,
+ -5.637952,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 2,
+ 0
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 4
+ ]
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/api/tests/integration/tests/formats/ref/multi_merge4.rdf b/api/tests/integration/tests/formats/ref/multi_merge4.rdf
new file mode 100644
index 0000000000..2523b02d8a
--- /dev/null
+++ b/api/tests/integration/tests/formats/ref/multi_merge4.rdf
@@ -0,0 +1,175 @@
+$RDFILE 1
+$DATM 01/00/00 00:00
+$RDFILE 1
+$DATM 01/00/00 00:00
+$RFMT
+$RXN
+
+ -INDIGO- 0100000000
+
+ 1 1
+$MOL
+
+ -INDIGO-01000000002D
+
+ 26 7 0 0 0 0 0 0 0 0999 V2000
+ 8.3123 -14.7430 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.3135 -14.7430 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 8.8129 -13.8780 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.5036 -12.1500 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.2786 -12.7750 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.4036 -12.1500 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.4536 -11.6000 0.0000 Br 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.5786 -11.1000 0.0000 Br 0 0 0 0 0 0 0 0 0 0 0 0
+ 13.1201 -11.5580 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 13.1164 -10.5630 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.1082 -11.5451 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.1057 -10.5630 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.8629 -14.9355 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.8379 -15.8605 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.3879 -15.4605 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.2786 -16.4500 0.0000 P 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.3129 -16.1855 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.2286 -13.3750 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.6036 -13.8750 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.3536 -16.9750 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.9286 -14.3000 0.0000 P 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.9129 -16.3855 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.9786 -17.6500 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.6786 -18.4000 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.6286 -11.6500 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.1536 -11.1000 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+ 9 10 1 0 0 0 0
+ 10 12 1 0 0 0 0
+ 12 11 1 0 0 0 0
+ 11 9 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 4 4 0 0 0 0 0 0 0 0999 V2000
+ 5.2373 -18.5180 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 6.2385 -18.5180 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 5.7379 -17.6530 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 6.9456 -19.2251 0.0000 Br 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+ 2 4 1 0 0 0 0
+M END
+$RFMT
+$RXN
+
+ -INDIGO- 0100000000
+
+ 1 1
+$MOL
+
+ -INDIGO-01000000002D
+
+ 26 7 0 0 0 0 0 0 0 0999 V2000
+ 8.3123 -14.7430 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.3135 -14.7430 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 8.8129 -13.8780 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.5036 -12.1500 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.2786 -12.7750 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.4036 -12.1500 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.4536 -11.6000 0.0000 Br 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.5786 -11.1000 0.0000 Br 0 0 0 0 0 0 0 0 0 0 0 0
+ 13.1201 -11.5580 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 13.1164 -10.5630 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.1082 -11.5451 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.1057 -10.5630 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.8629 -14.9355 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.8379 -15.8605 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.3879 -15.4605 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.2786 -16.4500 0.0000 P 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.3129 -16.1855 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.2286 -13.3750 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.6036 -13.8750 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.3536 -16.9750 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.9286 -14.3000 0.0000 P 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.9129 -16.3855 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.9786 -17.6500 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.6786 -18.4000 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.6286 -11.6500 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.1536 -11.1000 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+ 9 10 1 0 0 0 0
+ 10 12 1 0 0 0 0
+ 12 11 1 0 0 0 0
+ 11 9 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 5 5 0 0 0 0 0 0 0 0999 V2000
+ 13.1951 -7.1330 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 13.1914 -6.1380 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.1832 -7.1201 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.1807 -6.1380 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 14.0574 -5.6380 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+ 2 5 1 0 0 0 0
+M END
+$RFMT
+$RXN
+
+ -INDIGO- 0100000000
+
+ 1 1
+$MOL
+
+ -INDIGO-01000000002D
+
+ 16 5 0 0 0 0 0 0 0 0999 V2000
+ 16.1129 -13.4911 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 16.9219 -14.0789 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 16.6129 -15.0299 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 15.6129 -15.0299 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 15.3039 -14.0789 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.6286 -15.7750 0.0000 Br 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.6536 -15.2500 0.0000 I 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.7879 -16.3855 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
+ 13.5629 -16.3105 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
+ 14.0286 -16.7750 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 14.1786 -17.4250 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0
+ 14.0036 -18.0500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 14.2879 -16.1855 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
+ 14.8129 -15.7605 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
+ 14.9379 -15.3105 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
+ 15.1129 -14.8105 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 5 1 0 0 0 0
+ 5 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 2 1 0 0 0 0
+ 2 1 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 6 6 0 0 0 0 0 0 0 0999 V2000
+ 20.6129 -17.5661 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.4219 -18.1539 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.1129 -19.1049 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 20.1129 -19.1049 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.8039 -18.1539 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.8200 -19.8120 0.0000 I 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 5 1 0 0 0 0
+ 5 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 2 1 0 0 0 0
+ 2 1 1 0 0 0 0
+ 3 6 1 0 0 0 0
+M END
diff --git a/api/tests/integration/tests/formats/ref/multi_merge5.rdf b/api/tests/integration/tests/formats/ref/multi_merge5.rdf
new file mode 100644
index 0000000000..82f0ec1abd
--- /dev/null
+++ b/api/tests/integration/tests/formats/ref/multi_merge5.rdf
@@ -0,0 +1,318 @@
+$RDFILE 1
+$DATM 01/00/00 00:00
+$RDFILE 1
+$DATM 01/00/00 00:00
+$RFMT
+$RXN
+
+ -INDIGO- 0100000000
+
+ 3 3
+$MOL
+
+ -INDIGO-01000000002D
+
+ 8 8 0 0 0 0 0 0 0 0999 V2000
+ 18.5795 -8.7936 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.3634 -8.1760 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 20.3364 -8.3986 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 20.7705 -9.2944 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.5850 -9.8008 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 20.3371 -10.2014 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.3634 -10.4240 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.1046 -7.2101 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 2 1 1 0 0 0 0
+ 1 5 1 0 0 0 0
+ 5 7 1 0 0 0 0
+ 7 6 1 0 0 0 0
+ 6 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 2 1 0 0 0 0
+ 2 8 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 6 4 0 0 0 0 0 0 0 0999 V2000
+ 22.6744 -9.7075 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 23.6756 -9.7075 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 23.1751 -8.8425 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.9673 -10.4146 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 23.1500 -8.2000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
+ 23.5750 -10.3750 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+ 1 4 1 0 0 0 0
+M CHG 2 5 -1 6 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 5 5 0 0 0 0 0 0 0 0999 V2000
+ 26.5572 -9.7975 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 26.5535 -8.8025 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 25.5453 -9.7846 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 25.5428 -8.8025 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 27.2606 -8.0953 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+ 2 5 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 11 9 0 0 0 0 0 0 0 0999 V2000
+ 30.9750 -17.0750 0.0000 Br 0 0 0 0 0 0 0 0 0 0 0 0
+ 30.0545 -14.7936 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 30.8384 -14.1760 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 31.8114 -14.3986 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 32.2455 -15.2944 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 30.0600 -15.8008 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 31.8121 -16.2014 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 30.8384 -16.4240 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 32.6775 -13.8986 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 32.6782 -16.7014 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 33.0000 -15.2500 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 3 2 1 0 0 0 0
+ 2 6 1 0 0 0 0
+ 6 8 1 0 0 0 0
+ 8 7 1 0 0 0 0
+ 7 5 1 0 0 0 0
+ 5 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 4 9 1 0 0 0 0
+ 7 10 1 0 0 0 0
+M CHG 2 1 -1 11 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 3 3 0 0 0 0 0 0 0 0999 V2000
+ 30.6494 -20.1575 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 31.6506 -20.1575 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 31.1501 -19.2925 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 1 0 0 0 0 0 0 0 0 0999 V2000
+ 31.1250 -22.4000 0.0000 Br 0 0 0 0 0 0 0 0 0 0 0 0
+M CHG 1 1 -2
+M END
+$RFMT
+$RXN
+
+ -INDIGO- 0100000000
+
+ 3 2
+$MOL
+
+ -INDIGO-01000000002D
+
+ 11 9 0 0 0 0 0 0 0 0999 V2000
+ 30.9750 -17.0750 0.0000 Br 0 0 0 0 0 0 0 0 0 0 0 0
+ 30.0545 -14.7936 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 30.8384 -14.1760 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 31.8114 -14.3986 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 32.2455 -15.2944 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 30.0600 -15.8008 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 31.8121 -16.2014 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 30.8384 -16.4240 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 32.6775 -13.8986 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 32.6782 -16.7014 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 33.0000 -15.2500 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 3 2 1 0 0 0 0
+ 2 6 1 0 0 0 0
+ 6 8 1 0 0 0 0
+ 8 7 1 0 0 0 0
+ 7 5 1 0 0 0 0
+ 5 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 4 9 1 0 0 0 0
+ 7 10 1 0 0 0 0
+M CHG 2 1 -1 11 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 3 3 0 0 0 0 0 0 0 0999 V2000
+ 30.6494 -20.1575 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 31.6506 -20.1575 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 31.1501 -19.2925 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 1 0 0 0 0 0 0 0 0 0999 V2000
+ 31.1250 -22.4000 0.0000 Br 0 0 0 0 0 0 0 0 0 0 0 0
+M CHG 1 1 -2
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 9 6 0 0 0 0 0 0 0 0999 V2000
+ 11.7000 -15.0806 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.5090 -15.6684 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.2000 -16.6194 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.2000 -16.6194 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.8910 -15.6684 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.2000 -14.2145 0.0000 P 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.1000 -15.6500 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.1250 -15.6250 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 8.1250 -15.6250 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 5 1 0 0 0 0
+ 5 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 2 1 0 0 0 0
+ 2 1 1 0 0 0 0
+ 1 6 1 0 0 0 0
+M CHG 3 7 -1 8 -1 9 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 9 8 0 0 0 0 0 0 0 0999 V2000
+ 10.5045 -18.7686 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.2884 -18.1510 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.2614 -18.3736 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.6955 -19.2694 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.5100 -19.7758 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.2621 -20.1764 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.2884 -20.3990 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.7884 -21.2650 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.4500 -22.0750 0.0000 I 0 0 0 0 0 0 0 0 0 0 0 0
+ 2 1 1 0 0 0 0
+ 1 5 1 0 0 0 0
+ 5 7 1 0 0 0 0
+ 7 6 1 0 0 0 0
+ 6 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 2 1 0 0 0 0
+ 7 8 1 0 0 0 0
+M CHG 1 9 -1
+M END
+$RFMT
+$RXN
+
+ -INDIGO- 0100000000
+
+ 2 3
+$MOL
+
+ -INDIGO-01000000002D
+
+ 9 6 0 0 0 0 0 0 0 0999 V2000
+ 11.7000 -15.0806 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.5090 -15.6684 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.2000 -16.6194 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.2000 -16.6194 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.8910 -15.6684 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.2000 -14.2145 0.0000 P 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.1000 -15.6500 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.1250 -15.6250 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 8.1250 -15.6250 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 5 1 0 0 0 0
+ 5 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 2 1 0 0 0 0
+ 2 1 1 0 0 0 0
+ 1 6 1 0 0 0 0
+M CHG 3 7 -1 8 -1 9 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 9 8 0 0 0 0 0 0 0 0999 V2000
+ 10.5045 -18.7686 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.2884 -18.1510 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.2614 -18.3736 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.6955 -19.2694 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.5100 -19.7758 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.2621 -20.1764 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.2884 -20.3990 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.7884 -21.2650 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.4500 -22.0750 0.0000 I 0 0 0 0 0 0 0 0 0 0 0 0
+ 2 1 1 0 0 0 0
+ 1 5 1 0 0 0 0
+ 5 7 1 0 0 0 0
+ 7 6 1 0 0 0 0
+ 6 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 2 1 0 0 0 0
+ 7 8 1 0 0 0 0
+M CHG 1 9 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 8 8 0 0 0 0 0 0 0 0999 V2000
+ 18.5795 -8.7936 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.3634 -8.1760 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 20.3364 -8.3986 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 20.7705 -9.2944 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.5850 -9.8008 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 20.3371 -10.2014 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.3634 -10.4240 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.1046 -7.2101 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 2 1 1 0 0 0 0
+ 1 5 1 0 0 0 0
+ 5 7 1 0 0 0 0
+ 7 6 1 0 0 0 0
+ 6 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 2 1 0 0 0 0
+ 2 8 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 6 4 0 0 0 0 0 0 0 0999 V2000
+ 22.6744 -9.7075 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 23.6756 -9.7075 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 23.1751 -8.8425 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.9673 -10.4146 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 23.1500 -8.2000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
+ 23.5750 -10.3750 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+ 1 4 1 0 0 0 0
+M CHG 2 5 -1 6 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 5 5 0 0 0 0 0 0 0 0999 V2000
+ 26.5572 -9.7975 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 26.5535 -8.8025 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 25.5453 -9.7846 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 25.5428 -8.8025 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 27.2606 -8.0953 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+ 2 5 1 0 0 0 0
+M END
diff --git a/api/tests/integration/tests/formats/ref/multi_merge6.rdf b/api/tests/integration/tests/formats/ref/multi_merge6.rdf
new file mode 100644
index 0000000000..f9b4772cbb
--- /dev/null
+++ b/api/tests/integration/tests/formats/ref/multi_merge6.rdf
@@ -0,0 +1,201 @@
+$RDFILE 1
+$DATM 01/00/00 00:00
+$RDFILE 1
+$DATM 01/00/00 00:00
+$RFMT
+$RXN
+
+ -INDIGO- 0100000000
+
+ 2 2
+$MOL
+
+ -INDIGO-01000000002D
+
+ 9 6 0 0 0 0 0 0 0 0999 V2000
+ 18.2250 -7.2500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.7250 -8.1160 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.2250 -8.9821 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 16.0750 -7.1000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 16.0750 -8.1000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 16.9410 -8.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 16.9410 -9.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.8071 -10.1000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.2250 -6.1750 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 4 5 1 0 0 0 0
+ 5 6 1 0 0 0 0
+ 6 7 1 0 0 0 0
+ 7 8 1 0 0 0 0
+M CHG 1 9 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 7 6 0 0 0 0 0 0 0 0999 V2000
+ 22.6572 -8.4975 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 22.6535 -7.5025 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.6453 -8.4846 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.6428 -7.5025 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 20.6769 -7.2436 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.5000 -9.5750 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 22.5000 -9.5750 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+ 4 5 1 0 0 0 0
+ 6 7 1 0 0 0 0
+M CHG 1 6 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 6 5 0 0 0 0 0 0 0 0999 V2000
+ 29.1822 -8.4725 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 29.1785 -7.4775 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 28.1703 -8.4596 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 28.1678 -7.4775 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 29.8893 -9.1797 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 29.7250 -8.0500 0.0000 I 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+ 1 5 1 0 0 0 0
+M CHG 1 6 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 2 0 0 0 0 0 0 0 0 0999 V2000
+ 31.5250 -8.1500 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
+ 31.8250 -9.0250 0.0000 Br 0 0 0 0 0 0 0 0 0 0 0 0
+M CHG 2 1 -1 2 -1
+M END
+$RFMT
+$RXN
+
+ -INDIGO- 0100000000
+
+ 2 4
+$MOL
+
+ -INDIGO-01000000002D
+
+ 9 6 0 0 0 0 0 0 0 0999 V2000
+ 18.2250 -7.2500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.7250 -8.1160 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.2250 -8.9821 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 16.0750 -7.1000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 16.0750 -8.1000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 16.9410 -8.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 16.9410 -9.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.8071 -10.1000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.2250 -6.1750 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 4 5 1 0 0 0 0
+ 5 6 1 0 0 0 0
+ 6 7 1 0 0 0 0
+ 7 8 1 0 0 0 0
+M CHG 1 9 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 7 6 0 0 0 0 0 0 0 0999 V2000
+ 22.6572 -8.4975 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 22.6535 -7.5025 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.6453 -8.4846 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.6428 -7.5025 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 20.6769 -7.2436 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.5000 -9.5750 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 22.5000 -9.5750 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+ 4 5 1 0 0 0 0
+ 6 7 1 0 0 0 0
+M CHG 1 6 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 5 4 0 0 0 0 0 0 0 0999 V2000
+ 15.9000 -16.3000 0.0000 Br 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.8572 -16.8725 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.8535 -15.8775 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 16.8453 -16.8596 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 16.8428 -15.8775 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 5 1 0 0 0 0
+ 5 4 1 0 0 0 0
+ 4 2 1 0 0 0 0
+M CHG 1 1 -1
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 4 4 0 0 0 0 0 0 0 0999 V2000
+ 16.8744 -19.8075 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.8756 -19.8075 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.3750 -18.9425 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.8756 -19.8075 0.0000 P 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+ 2 4 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 5 5 0 0 0 0 0 0 0 0999 V2000
+ 20.7750 -15.6306 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.5840 -16.2184 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.2750 -17.1694 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 20.2750 -17.1694 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.9660 -16.2184 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 5 1 0 0 0 0
+ 5 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 2 1 0 0 0 0
+ 2 1 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 11 11 0 0 0 0 0 0 0 0999 V2000
+ 11.3433 -16.9012 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.3435 -15.8988 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.0487 -15.1935 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.0489 -17.6066 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 13.0513 -17.6066 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 13.7567 -16.9012 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 13.7566 -15.8988 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 13.0513 -15.1934 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.3416 -14.4864 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.4773 -17.4012 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 13.3101 -18.5725 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 2 1 1 0 0 0 0
+ 1 4 1 0 0 0 0
+ 4 5 1 0 0 0 0
+ 5 6 1 0 0 0 0
+ 6 7 1 0 0 0 0
+ 7 8 1 0 0 0 0
+ 8 3 1 0 0 0 0
+ 3 2 1 0 0 0 0
+ 3 9 1 0 0 0 0
+ 1 10 1 0 0 0 0
+ 5 11 1 0 0 0 0
+M END
diff --git a/api/tests/integration/tests/formats/ref/multi_overlap.cdxml b/api/tests/integration/tests/formats/ref/multi_overlap.cdxml
index 8a5cadee99..91d8da2381 100644
--- a/api/tests/integration/tests/formats/ref/multi_overlap.cdxml
+++ b/api/tests/integration/tests/formats/ref/multi_overlap.cdxml
@@ -18,45 +18,45 @@
-
-
-
-
-
-
-
-
- O
+
+
+
+
+
+
+
+
+ NH
+ 2
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
- NH
- 2
+
+
+
+
+
+
+
+
+ O
-
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -98,8 +98,8 @@
-
-
+
+
diff --git a/api/tests/integration/tests/formats/ref/multi_overlap.ket b/api/tests/integration/tests/formats/ref/multi_overlap.ket
index 6f08ebda63..4a3a0802e0 100644
--- a/api/tests/integration/tests/formats/ref/multi_overlap.ket
+++ b/api/tests/integration/tests/formats/ref/multi_overlap.ket
@@ -74,6 +74,118 @@
]
},
"mol0": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "C",
+ "location": [
+ 6.014000415802002,
+ -8.237564086914063,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 7.744203567504883,
+ -8.237078666687012,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 6.880739688873291,
+ -7.737484455108643,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 7.744203567504883,
+ -9.237964630126954,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 6.014000415802002,
+ -9.24245262145996,
+ 0.0
+ ]
+ },
+ {
+ "label": "C",
+ "location": [
+ 6.882923603057861,
+ -9.737438201904297,
+ 0.0
+ ]
+ },
+ {
+ "label": "N",
+ "location": [
+ 8.610413551330567,
+ -7.7375102043151859,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": [
+ {
+ "type": 2,
+ "atoms": [
+ 2,
+ 0
+ ]
+ },
+ {
+ "type": 2,
+ "atoms": [
+ 3,
+ 1
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 0,
+ 4
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 2
+ ]
+ },
+ {
+ "type": 2,
+ "atoms": [
+ 4,
+ 5
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 5,
+ 3
+ ]
+ },
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 6
+ ]
+ }
+ ]
+ },
+ "mol1": {
"type": "molecule",
"atoms": [
{
@@ -185,7 +297,7 @@
}
]
},
- "mol1": {
+ "mol2": {
"type": "molecule",
"atoms": [
{
@@ -252,7 +364,7 @@
}
]
},
- "mol2": {
+ "mol3": {
"type": "molecule",
"atoms": [
{
@@ -319,7 +431,7 @@
}
]
},
- "mol3": {
+ "mol4": {
"type": "molecule",
"atoms": [
{
@@ -371,118 +483,6 @@
}
]
},
- "mol4": {
- "type": "molecule",
- "atoms": [
- {
- "label": "C",
- "location": [
- 6.014000415802002,
- -8.237564086914063,
- 0.0
- ]
- },
- {
- "label": "C",
- "location": [
- 7.744203567504883,
- -8.237078666687012,
- 0.0
- ]
- },
- {
- "label": "C",
- "location": [
- 6.880739688873291,
- -7.737484455108643,
- 0.0
- ]
- },
- {
- "label": "C",
- "location": [
- 7.744203567504883,
- -9.237964630126954,
- 0.0
- ]
- },
- {
- "label": "C",
- "location": [
- 6.014000415802002,
- -9.24245262145996,
- 0.0
- ]
- },
- {
- "label": "C",
- "location": [
- 6.882923603057861,
- -9.737438201904297,
- 0.0
- ]
- },
- {
- "label": "N",
- "location": [
- 8.610413551330567,
- -7.7375102043151859,
- 0.0
- ]
- }
- ],
- "bonds": [
- {
- "type": 2,
- "atoms": [
- 2,
- 0
- ]
- },
- {
- "type": 2,
- "atoms": [
- 3,
- 1
- ]
- },
- {
- "type": 1,
- "atoms": [
- 0,
- 4
- ]
- },
- {
- "type": 1,
- "atoms": [
- 1,
- 2
- ]
- },
- {
- "type": 2,
- "atoms": [
- 4,
- 5
- ]
- },
- {
- "type": 1,
- "atoms": [
- 5,
- 3
- ]
- },
- {
- "type": 1,
- "atoms": [
- 1,
- 6
- ]
- }
- ]
- },
"mol5": {
"type": "molecule",
"atoms": [
diff --git a/api/tests/integration/tests/formats/ref/pathway10.rdf b/api/tests/integration/tests/formats/ref/pathway10.rdf
index 2f76d9307d..440f9b8aa8 100644
--- a/api/tests/integration/tests/formats/ref/pathway10.rdf
+++ b/api/tests/integration/tests/formats/ref/pathway10.rdf
@@ -7,118 +7,70 @@ $RXN
-INDIGO- 0100000000
- 7 3
+ 2 1
$MOL
-INDIGO-01000000002D
- 5 5 0 0 0 0 0 0 0 0999 V2000
- 1.7303 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
- 1.7266 0.9951 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
- 0.7183 0.0129 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
- 0.7158 0.9951 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
- 0.0087 1.7022 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
- 1 2 1 0 0 0 0
- 2 4 1 0 0 0 0
- 4 3 1 0 0 0 0
- 3 1 1 0 0 0 0
- 4 5 1 0 0 0 0
-M END
-$MOL
-
- -INDIGO-01000000002D
-
- 4 4 0 0 0 0 0 0 0 0999 V2000
- 0.7290 4.2022 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
- 1.7303 4.2022 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
- 1.2297 5.0671 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
- 1.2297 6.0671 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
- 1 2 1 0 0 0 0
- 2 3 1 0 0 0 0
- 3 1 1 0 0 0 0
- 3 4 1 0 0 0 0
-M END
-$MOL
-
- -INDIGO-01000000002D
-
- 5 5 0 0 0 0 0 0 0 0999 V2000
- 0.9207 10.1072 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
- 1.4211 8.5671 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
- 1.7303 9.5133 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
- 0.4203 8.5671 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
- 0.1110 9.5133 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
- 1 5 1 0 0 0 0
- 5 4 2 0 0 0 0
- 4 2 1 0 0 0 0
- 2 3 2 0 0 0 0
- 3 1 1 0 0 0 0
-M END
-$MOL
-
- -INDIGO-01000000002D
-
- 6 6 0 0 0 0 0 0 0 0999 V2000
- 0.0000 14.1071 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
- 1.7303 14.1076 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
- 0.8668 14.6072 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
- 1.7303 13.1067 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
- 0.0000 13.1022 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
- 0.8690 12.6072 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
- 3 1 2 0 0 0 0
- 1 5 1 0 0 0 0
- 5 6 2 0 0 0 0
- 6 4 1 0 0 0 0
- 4 2 2 0 0 0 0
- 2 3 1 0 0 0 0
-M END
-$MOL
-
- -INDIGO-01000000002D
-
- 4 4 0 0 0 0 0 0 0 0999 V2000
- 7.8497 1.7228 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
- 8.8509 1.7228 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
- 8.3504 2.5878 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
- 8.6092 3.5537 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
- 1 2 1 0 0 0 0
- 2 3 1 0 0 0 0
- 3 1 1 0 0 0 0
- 3 4 1 0 0 0 0
-M END
-$MOL
-
- -INDIGO-01000000002D
-
- 6 6 0 0 0 0 0 0 0 0999 V2000
+ 11 11 0 0 0 0 0 0 0 0999 V2000
9.8367 11.9722 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
9.8367 10.9722 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
10.7027 10.4722 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
11.5687 10.9722 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
11.5687 11.9722 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
10.7027 12.4722 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 7.8745 10.4722 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 7.8708 11.4673 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 6.8626 10.4851 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 6.8601 11.4673 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 8.8367 11.7261 0.0000 P 0 0 0 0 0 0 0 0 0 0 0 0
6 1 1 0 0 0 0
1 2 1 0 0 0 0
2 3 1 0 0 0 0
3 4 1 0 0 0 0
4 5 1 0 0 0 0
5 6 1 0 0 0 0
+ 7 8 1 0 0 0 0
+ 8 10 1 0 0 0 0
+ 10 9 1 0 0 0 0
+ 9 7 1 0 0 0 0
+ 8 11 1 0 0 0 0
M END
$MOL
-INDIGO-01000000002D
- 5 5 0 0 0 0 0 0 0 0999 V2000
+ 15 15 0 0 0 0 0 0 0 0999 V2000
10.8653 1.7228 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
10.8616 2.7179 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
9.8534 1.7357 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
9.8509 2.7179 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
11.5687 3.4250 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
+ 7.8497 1.7228 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 8.8509 1.7228 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 8.3504 2.5878 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 8.6092 3.5537 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
+ 6.0401 3.2629 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 6.5405 1.7228 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 6.8497 2.6691 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 5.5397 1.7228 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 5.2303 2.6691 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 6.0401 4.2629 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0
1 2 1 0 0 0 0
2 4 1 0 0 0 0
4 3 1 0 0 0 0
3 1 1 0 0 0 0
2 5 1 0 0 0 0
+ 6 7 1 0 0 0 0
+ 7 8 1 0 0 0 0
+ 8 6 1 0 0 0 0
+ 8 9 1 0 0 0 0
+ 10 14 1 0 0 0 0
+ 14 13 2 0 0 0 0
+ 13 11 1 0 0 0 0
+ 11 12 2 0 0 0 0
+ 12 10 1 0 0 0 0
+ 10 15 1 0 0 0 0
M END
$MOL
@@ -150,37 +102,143 @@ $MOL
9 3 1 6 0 0 0
10 4 1 6 0 0 0
M END
+$RFMT
+$RXN
+
+ -INDIGO- 0100000000
+
+ 2 1
$MOL
-INDIGO-01000000002D
- 6 6 0 0 0 0 0 0 0 0999 V2000
+ 4 4 0 0 0 0 0 0 0 0999 V2000
+ 0.7290 4.2022 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1.7303 4.2022 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1.2297 5.0671 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1.2297 6.0671 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+ 3 4 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 5 5 0 0 0 0 0 0 0 0999 V2000
+ 1.7303 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1.7266 0.9951 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 0.7183 0.0129 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 0.7158 0.9951 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 0.0087 1.7022 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+ 4 5 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 15 15 0 0 0 0 0 0 0 0999 V2000
+ 10.8653 1.7228 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.8616 2.7179 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.8534 1.7357 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.8509 2.7179 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.5687 3.4250 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
+ 7.8497 1.7228 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 8.8509 1.7228 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 8.3504 2.5878 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 8.6092 3.5537 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
6.0401 3.2629 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
6.5405 1.7228 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
6.8497 2.6691 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
5.5397 1.7228 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
5.2303 2.6691 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
6.0401 4.2629 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+ 2 5 1 0 0 0 0
+ 6 7 1 0 0 0 0
+ 7 8 1 0 0 0 0
+ 8 6 1 0 0 0 0
+ 8 9 1 0 0 0 0
+ 10 14 1 0 0 0 0
+ 14 13 2 0 0 0 0
+ 13 11 1 0 0 0 0
+ 11 12 2 0 0 0 0
+ 12 10 1 0 0 0 0
+ 10 15 1 0 0 0 0
+M END
+$RFMT
+$RXN
+
+ -INDIGO- 0100000000
+
+ 2 1
+$MOL
+
+ -INDIGO-01000000002D
+
+ 6 6 0 0 0 0 0 0 0 0999 V2000
+ 0.0000 14.1071 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1.7303 14.1076 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 0.8668 14.6072 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1.7303 13.1067 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 0.0000 13.1022 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 0.8690 12.6072 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 3 1 2 0 0 0 0
+ 1 5 1 0 0 0 0
+ 5 6 2 0 0 0 0
+ 6 4 1 0 0 0 0
+ 4 2 2 0 0 0 0
+ 2 3 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 5 5 0 0 0 0 0 0 0 0999 V2000
+ 0.9207 10.1072 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1.4211 8.5671 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1.7303 9.5133 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 0.4203 8.5671 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 0.1110 9.5133 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
1 5 1 0 0 0 0
5 4 2 0 0 0 0
4 2 1 0 0 0 0
2 3 2 0 0 0 0
3 1 1 0 0 0 0
- 1 6 1 0 0 0 0
M END
$MOL
-INDIGO-01000000002D
- 5 5 0 0 0 0 0 0 0 0999 V2000
+ 11 11 0 0 0 0 0 0 0 0999 V2000
+ 9.8367 11.9722 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.8367 10.9722 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.7027 10.4722 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.5687 10.9722 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.5687 11.9722 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.7027 12.4722 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
7.8745 10.4722 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
7.8708 11.4673 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
6.8626 10.4851 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
6.8601 11.4673 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
8.8367 11.7261 0.0000 P 0 0 0 0 0 0 0 0 0 0 0 0
+ 6 1 1 0 0 0 0
1 2 1 0 0 0 0
- 2 4 1 0 0 0 0
- 4 3 1 0 0 0 0
- 3 1 1 0 0 0 0
- 2 5 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 4 1 0 0 0 0
+ 4 5 1 0 0 0 0
+ 5 6 1 0 0 0 0
+ 7 8 1 0 0 0 0
+ 8 10 1 0 0 0 0
+ 10 9 1 0 0 0 0
+ 9 7 1 0 0 0 0
+ 8 11 1 0 0 0 0
M END
diff --git a/api/tests/integration/tests/formats/ref/pathway_merge1.rdf b/api/tests/integration/tests/formats/ref/pathway_merge1.rdf
new file mode 100644
index 0000000000..72103f790f
--- /dev/null
+++ b/api/tests/integration/tests/formats/ref/pathway_merge1.rdf
@@ -0,0 +1,230 @@
+$RDFILE 1
+$DATM 01/00/00 00:00
+$RDFILE 1
+$DATM 01/00/00 00:00
+$RFMT
+$RXN
+
+ -INDIGO- 0100000000
+
+ 3 1
+$MOL
+
+ -INDIGO-01000000002D
+
+ 18 18 0 0 0 0 0 0 0 0999 V2000
+ 2.2920 -4.7057 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 4.7080 -1.8264 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 2.8572 -5.0321 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 2.2920 -1.8264 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 4.1428 -1.5000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1.6492 -3.5924 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 2.6340 -3.7660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 4.3660 -2.7660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 5.3508 -2.9397 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 4.7080 -4.7057 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 4.1428 -5.0321 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 3.5000 -4.2660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 3.5000 -2.2660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 2.8572 -1.5000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 2.6340 -2.7660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1.6492 -2.9397 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 5.3508 -3.5924 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 4.3660 -3.7660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 7 15 1 0 0 0 0
+ 15 13 1 0 0 0 0
+ 13 8 1 0 0 0 0
+ 8 18 1 0 0 0 0
+ 18 12 1 0 0 0 0
+ 12 7 1 0 0 0 0
+ 1 7 1 0 0 0 0
+ 8 2 1 0 0 0 0
+ 12 3 1 0 0 0 0
+ 15 4 1 0 0 0 0
+ 5 13 1 0 0 0 0
+ 6 7 1 0 0 0 0
+ 8 9 1 0 0 0 0
+ 10 18 1 0 0 0 0
+ 11 12 1 0 0 0 0
+ 13 14 1 0 0 0 0
+ 15 16 1 0 0 0 0
+ 17 18 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 10 9 0 0 0 0 0 0 0 0999 V2000
+ 2.6340 -10.5321 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 3.5000 -10.0321 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
+ 4.3660 -10.5321 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 3.5000 -9.0321 0.0000 P 0 0 0 0 0 0 0 0 0 0 0 0
+ 2.6340 -8.5321 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
+ 1.7679 -9.0321 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 2.6340 -7.5321 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 4.3660 -8.5321 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
+ 5.2321 -9.0321 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 4.3660 -7.5321 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 5 1 0 0 0 0
+ 5 6 1 0 0 0 0
+ 5 7 1 0 0 0 0
+ 4 8 1 0 0 0 0
+ 8 9 1 0 0 0 0
+ 8 10 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 17 18 0 0 0 0 0 0 0 0999 V2000
+ 3.5000 -14.0321 0.0000 Si 0 0 0 0 0 0 0 0 0 0 0 0
+ 3.5000 -15.0321 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 3.5000 -13.0321 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 4.3660 -15.5321 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 2.6340 -15.5321 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 2.5000 -14.0321 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 2.0000 -13.1661 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1.0000 -13.1661 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 2.0000 -14.8981 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1.0000 -14.8981 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 0.5000 -14.0321 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 4.5000 -14.0321 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 5.0000 -14.8981 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 6.0000 -14.8981 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 5.0000 -13.1661 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 6.0000 -13.1661 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 6.5000 -14.0321 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 1 3 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 2 5 1 0 0 0 0
+ 1 6 1 0 0 0 0
+ 7 6 1 0 0 0 0
+ 7 8 2 0 0 0 0
+ 6 9 2 0 0 0 0
+ 9 10 1 0 0 0 0
+ 10 11 2 0 0 0 0
+ 11 8 1 0 0 0 0
+ 1 12 1 0 0 0 0
+ 13 12 1 0 0 0 0
+ 13 14 2 0 0 0 0
+ 12 15 2 0 0 0 0
+ 15 16 1 0 0 0 0
+ 16 17 2 0 0 0 0
+ 17 14 1 0 0 0 0
+M STY 1 1 SUP
+M SLB 1 1 1
+M SAL 1 8 1 2 3 4 5 6 7 8
+M SAL 1 8 9 10 11 12 13 14 15 16
+M SAL 1 1 17
+M SMT 1 TBDPS
+M SDS EXP 1 1
+M SAP 1 1 1 0 1
+M SDI 1 4 0.0000 0.0000 0.0000 0.0000
+M SDI 1 4 0.0000 0.0000 0.0000 0.0000
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 47 49 0 0 0 0 0 0 0 0999 V2000
+ 14.5000 -9.5241 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 15.3660 -9.0241 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 15.3660 -8.0241 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 16.2321 -9.5241 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.0981 -9.0241 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 17.9641 -8.5241 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0
+ 20.2486 -9.8493 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.9418 -8.8976 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 18.9641 -8.6874 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 20.6126 -8.1560 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.5903 -8.3662 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 22.3350 -7.6988 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
+ 23.1998 -8.2008 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 24.1516 -7.8940 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 24.8932 -8.5649 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 24.6830 -9.5425 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 23.7312 -9.8493 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 22.9896 -9.1785 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.9949 -9.2807 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
+ 35.2282 -6.7829 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 34.3888 -7.3265 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 33.4984 -6.8715 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 34.4399 -8.3252 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
+ 33.6006 -8.8688 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 32.7101 -8.4137 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 32.6590 -7.4151 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
+ 31.8708 -8.9574 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 30.9804 -8.5023 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
+ 30.1410 -9.0459 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 30.1921 -10.0446 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 29.3528 -10.5882 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 28.4623 -10.1331 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 27.6230 -10.6767 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 26.7325 -10.2216 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 26.6814 -9.2229 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
+ 25.8932 -10.7652 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
+ 28.4112 -9.1344 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 29.2506 -8.5908 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 35.3304 -8.7803 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 36.2219 -8.3274 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
+ 36.9282 -9.0354 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 37.9269 -8.9843 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 38.4705 -9.8236 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 38.0154 -10.7141 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 37.0167 -10.7652 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 36.4731 -9.9259 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 35.4856 -9.7682 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 5 2 0 0 0 0
+ 5 6 2 0 0 0 0
+ 7 8 1 0 0 0 0
+ 8 9 1 0 0 0 0
+ 8 10 1 0 0 0 0
+ 10 11 1 0 0 0 0
+ 11 12 4 0 0 0 0
+ 12 13 4 0 0 0 0
+ 13 14 4 0 0 0 0
+ 14 15 4 0 0 0 0
+ 15 16 4 0 0 0 0
+ 16 17 4 0 0 0 0
+ 17 18 4 0 0 0 0
+ 18 19 4 0 0 0 0
+ 19 11 4 0 0 0 0
+ 18 13 4 0 0 0 0
+ 20 21 1 0 0 0 0
+ 21 22 1 0 0 0 0
+ 21 23 1 0 0 0 0
+ 23 24 1 0 0 0 0
+ 24 25 1 0 0 0 0
+ 25 26 1 0 0 0 0
+ 25 27 1 0 0 0 0
+ 27 28 1 0 0 0 0
+ 28 29 1 0 0 0 0
+ 29 30 4 0 0 0 0
+ 30 31 4 0 0 0 0
+ 31 32 4 0 0 0 0
+ 32 33 1 0 0 0 0
+ 33 34 1 0 0 0 0
+ 34 35 1 0 0 0 0
+ 34 36 2 0 0 0 0
+ 32 37 4 0 0 0 0
+ 37 38 4 0 0 0 0
+ 23 39 1 0 0 0 0
+ 39 40 4 0 0 0 0
+ 40 41 4 0 0 0 0
+ 41 42 4 0 0 0 0
+ 42 43 4 0 0 0 0
+ 43 44 4 0 0 0 0
+ 44 45 4 0 0 0 0
+ 45 46 4 0 0 0 0
+ 46 47 4 0 0 0 0
+ 38 29 4 0 0 0 0
+ 47 39 4 0 0 0 0
+ 46 41 4 0 0 0 0
+M END
diff --git a/api/tests/integration/tests/formats/ref/pathway_merge2.rdf b/api/tests/integration/tests/formats/ref/pathway_merge2.rdf
new file mode 100644
index 0000000000..a4d5cc9e00
--- /dev/null
+++ b/api/tests/integration/tests/formats/ref/pathway_merge2.rdf
@@ -0,0 +1,147 @@
+$RDFILE 1
+$DATM 01/00/00 00:00
+$RDFILE 1
+$DATM 01/00/00 00:00
+$RFMT
+$RXN
+
+ -INDIGO- 0100000000
+
+ 2 2
+$MOL
+
+ -INDIGO-01000000002D
+
+ 8 8 0 0 0 0 0 0 0 0999 V2000
+ 10.8822 -1.3904 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 10.8785 -0.3953 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.8703 -1.3775 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 9.8678 -0.3953 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.2822 -1.3904 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.2785 -0.3953 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.2703 -1.3775 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 11.2678 -0.3953 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+ 5 6 1 0 0 0 0
+ 6 8 1 0 0 0 0
+ 8 7 1 0 0 0 0
+ 7 5 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 3 3 0 0 0 0 0 0 0 0999 V2000
+ 13.9744 -1.3753 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 14.9756 -1.3753 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 14.4750 -0.5104 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 3 3 0 0 0 0 0 0 0 0999 V2000
+ 18.9494 -1.3503 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.9506 -1.3503 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 19.4501 -0.4854 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 12 12 0 0 0 0 0 0 0 0999 V2000
+ 21.5045 -0.5615 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 22.2884 0.0561 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 23.2614 -0.1664 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 23.6955 -1.0623 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.5100 -1.5687 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 23.2621 -1.9693 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 22.2884 -2.1918 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 25.1250 -0.2734 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 25.9340 -0.8612 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 25.6250 -1.8123 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 24.6250 -1.8123 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 24.3160 -0.8612 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 2 1 1 0 0 0 0
+ 1 5 1 0 0 0 0
+ 5 7 1 0 0 0 0
+ 7 6 1 0 0 0 0
+ 6 4 1 0 0 0 0
+ 4 3 1 0 0 0 0
+ 3 2 1 0 0 0 0
+ 8 12 1 0 0 0 0
+ 12 11 1 0 0 0 0
+ 11 10 1 0 0 0 0
+ 10 9 1 0 0 0 0
+ 9 8 1 0 0 0 0
+M END
+$RFMT
+$RXN
+
+ -INDIGO- 0100000000
+
+ 2 1
+$MOL
+
+ -INDIGO-01000000002D
+
+ 7 7 0 0 0 0 0 0 0 0999 V2000
+ 13.5744 -5.5847 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 14.5756 -5.5847 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 14.0751 -4.7198 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 13.2072 -5.6998 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 13.2035 -4.7047 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.1953 -5.6869 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.1928 -4.7047 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 1 1 0 0 0 0
+ 4 5 1 0 0 0 0
+ 5 7 1 0 0 0 0
+ 7 6 1 0 0 0 0
+ 6 4 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 6 6 0 0 0 0 0 0 0 0999 V2000
+ 12.8590 -10.0022 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 12.8590 -11.0022 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 13.7250 -11.5022 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 14.5910 -11.0022 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 14.5910 -10.0022 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 13.7250 -9.5022 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 6 1 1 0 0 0 0
+ 1 2 1 0 0 0 0
+ 2 3 1 0 0 0 0
+ 3 4 1 0 0 0 0
+ 4 5 1 0 0 0 0
+ 5 6 1 0 0 0 0
+M END
+$MOL
+
+ -INDIGO-01000000002D
+
+ 6 5 0 0 0 0 0 0 0 0999 V2000
+ 21.2750 -6.9072 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 21.7754 -8.4473 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 22.0847 -7.5010 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 20.7747 -8.4473 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 20.4653 -7.5010 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
+ 23.1500 -7.7522 0.0000 Br 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 5 1 0 0 0 0
+ 5 4 2 0 0 0 0
+ 4 2 1 0 0 0 0
+ 2 3 2 0 0 0 0
+ 3 1 1 0 0 0 0
+M END
diff --git a/api/tests/integration/tests/layout/reactions/acs_before_layout.ket b/api/tests/integration/tests/layout/reactions/acs_before_layout.ket
index 97bbf9023f..a1dc2af0bf 100644
--- a/api/tests/integration/tests/layout/reactions/acs_before_layout.ket
+++ b/api/tests/integration/tests/layout/reactions/acs_before_layout.ket
@@ -22,13 +22,13 @@
"mode": "open-angle",
"pos": [
{
- "x": -7.394363028677862,
- "y": -6.362093778161939,
+ "x": 1.6416666666666604,
+ "y": -9.341666666666667,
"z": 0
},
{
- "x": -5.694363028677859,
- "y": -7.18709377816194,
+ "x": 5.0723036379888065,
+ "y": -8.403760444828606,
"z": 0
}
]
@@ -37,8 +37,8 @@
{
"type": "plus",
"location": [
- -12.377241893411822,
- -7.324774847536024,
+ -3.502241893411818,
+ -9.891441514202688,
0
],
"prop": {}
@@ -46,8 +46,8 @@
{
"type": "plus",
"location": [
- 1.775960072742631,
- -6.424774847536024,
+ 12.034293406075962,
+ -7.583108180869356,
0
],
"prop": {}
@@ -62,32 +62,32 @@
{
"label": "C",
"location": [
- -13.768267539670937,
- -6.949774873495124,
+ -5.168267539670935,
+ -11.29144154016179,
0
]
},
{
"label": "C",
"location": [
- -13.768267390659325,
- -5.949774863718258,
+ -5.168267390659323,
+ -10.291441530384924,
0
]
},
{
"label": "O",
"location": [
- -14.63429292347398,
- -5.4497749705885346,
+ -6.034292923473978,
+ -9.7914416372552,
0
]
},
{
"label": "O",
"location": [
- -12.90224200685628,
- -5.449774821576923,
+ -4.302242006856282,
+ -9.791441488243589,
0
]
}
@@ -114,7 +114,12 @@
3
]
}
- ]
+ ],
+ "stereoFlagPosition": {
+ "x": -4.302242006856282,
+ "y": 8.791441488243589,
+ "z": 0
+ }
},
"mol1": {
"type": "molecule",
@@ -122,32 +127,32 @@
{
"label": "O",
"location": [
- -11.002241779967369,
- -5.599774887233143,
+ -2.402241779967368,
+ -9.941441553899809,
0
]
},
{
"label": "C",
"location": [
- -10.136216694187546,
- -5.099774807838904,
+ -1.5362166941875457,
+ -9.44144147450557,
0
]
},
{
"label": "C",
"location": [
- -9.270191012361279,
- -5.599774812727337,
+ -0.6701910123612785,
+ -9.941441479394003,
0
]
},
{
"label": "C",
"location": [
- -8.404165926581456,
- -5.099774807838904,
+ 0.19583407341854436,
+ -9.44144147450557,
0
]
}
@@ -174,7 +179,12 @@
3
]
}
- ]
+ ],
+ "stereoFlagPosition": {
+ "x": 0.19583407341854436,
+ "y": 8.44144147450557,
+ "z": 0
+ }
},
"mol2": {
"type": "molecule",
@@ -182,56 +192,56 @@
{
"label": "C",
"location": [
- -3.904166661693825,
- -7.524774873495127,
+ 6.404166671639507,
+ -7.658108206828457,
0
]
},
{
"label": "C",
"location": [
- -3.03814097986756,
- -7.024774794100886,
+ 7.270192353465772,
+ -7.158108127434216,
0
]
},
{
"label": "O",
"location": [
- -2.1721152980412946,
- -7.524774798989321,
+ 8.136218035292037,
+ -7.658108132322651,
0
]
},
{
"label": "C",
"location": [
- -1.3060908083079177,
- -7.024774794100886,
+ 9.00224252502541,
+ -7.158108127434216,
0
]
},
{
"label": "C",
"location": [
- -0.4400651264816453,
- -7.524774798989321,
+ 9.868268206851683,
+ -7.658108132322651,
0
]
},
{
"label": "C",
"location": [
- 0.4259605553446235,
- -7.024774794100886,
+ 10.734293888677955,
+ -7.158108127434216,
0
]
},
{
"label": "O",
"location": [
- -3.03814097986756,
- -6.024774821576924,
+ 7.270192353465772,
+ -6.158108154910254,
0
]
}
@@ -287,8 +297,8 @@
{
"label": "O",
"location": [
- 3.300959590140639,
- -7.574774847536024,
+ 13.609292923473967,
+ -7.708108180869354,
0
]
}
@@ -300,56 +310,56 @@
{
"label": "N",
"location": [
- -6.339747371437873,
- -4.792796796383729,
+ 1.635252628562124,
+ -6.467796796383729,
0
]
},
{
"label": "N",
"location": [
- -5.555813985618887,
- -4.175225152463979,
+ 2.419186014381111,
+ -5.850225152463979,
0
]
},
{
"label": "C",
"location": [
- -4.582783087033036,
- -4.397775297256338,
+ 3.3922169129669615,
+ -6.072775297256337,
0
]
},
{
"label": "C",
"location": [
- -4.148700131348928,
- -5.293584700956992,
+ 3.8262998686510694,
+ -6.968584700956992,
0
]
},
{
"label": "C",
"location": [
- -6.334238704487571,
- -5.799981430061476,
+ 1.640761295512426,
+ -7.474981430061476,
0
]
},
{
"label": "N",
"location": [
- -4.582081983966631,
- -6.200611753720088,
+ 3.392918016033366,
+ -7.875611753720088,
0
]
},
{
"label": "C",
"location": [
- -5.555813985618887,
- -6.423161898512448,
+ 2.419186014381111,
+ -8.098161898512448,
0
]
}
@@ -404,6 +414,11 @@
1
]
}
- ]
+ ],
+ "stereoFlagPosition": {
+ "x": 3.8262998686510694,
+ "y": 4.850225152463979,
+ "z": 0
+ }
}
}
\ No newline at end of file
diff --git a/api/tests/integration/tests/layout/reactions/acs_issue_2458.ket b/api/tests/integration/tests/layout/reactions/acs_issue_2458.ket
index c50c942501..4ce08ff875 100644
--- a/api/tests/integration/tests/layout/reactions/acs_issue_2458.ket
+++ b/api/tests/integration/tests/layout/reactions/acs_issue_2458.ket
@@ -34,13 +34,13 @@
"mode": "open-angle",
"pos": [
{
- "x": 21.026647328887037,
- "y": -8.70290088292825,
+ "x": 21.18766570242239,
+ "y": -12.002251479945443,
"z": 0
},
{
- "x": 27.75164732888704,
- "y": -12.552900882928249,
+ "x": 27.912665702422395,
+ "y": -15.852251479945444,
"z": 0
}
]
@@ -56,112 +56,112 @@
{
"label": "C",
"location": [
- 13.126654540369064,
- -5.303906235908338,
+ 13.287672913904416,
+ -8.60325683292553,
0
]
},
{
"label": "C",
"location": [
- 12.126658661215936,
- -5.303906235908338,
+ 12.287677034751287,
+ -8.60325683292553,
0
]
},
{
"label": "C",
"location": [
- 11.626660721639372,
- -6.169902667254945,
+ 11.78767909517472,
+ -9.469253264272137,
0
]
},
{
"label": "C",
"location": [
- 12.126558661628021,
- -7.035899098601554,
+ 12.287577035163373,
+ -10.335249695618748,
0
]
},
{
"label": "C",
"location": [
- 13.126554540781148,
- -7.035899098601554,
+ 13.2875729143165,
+ -10.335249695618748,
0
]
},
{
"label": "C",
"location": [
- 13.626652479945628,
- -6.16980266766703,
+ 13.78767085348098,
+ -9.469153264684223,
0
]
},
{
"label": "C",
"location": [
- 14.626648359098755,
- -6.16980266766703,
+ 14.787666732634108,
+ -9.469153264684223,
0
]
},
{
"label": "C",
"location": [
- 15.12664629867532,
- -7.035899098601554,
+ 15.287664672210672,
+ -10.335249695618748,
0
]
},
{
"label": "C",
"location": [
- 16.126642177828447,
- -7.035899098601554,
+ 16.2876605513638,
+ -10.335249695618748,
0
]
},
{
"label": "C",
"location": [
- 16.62664011740501,
- -7.9018955299481615,
+ 16.787658490940363,
+ -11.201246126965355,
0
]
},
{
"label": "C",
"location": [
- 17.626635996558136,
- -7.9018955299481615,
+ 17.787654370093488,
+ -11.201246126965355,
0
]
},
{
"label": "C",
"location": [
- 18.126633936134702,
- -7.035899098601554,
+ 18.287652309670055,
+ -10.335249695618748,
0
]
},
{
"label": "C",
"location": [
- 17.626635996558136,
- -6.16980266766703,
+ 17.787654370093488,
+ -9.469153264684223,
0
]
},
{
"label": "C",
"location": [
- 16.62664011740501,
- -6.16980266766703,
+ 16.787658490940363,
+ -9.469153264684223,
0
]
}
@@ -280,8 +280,8 @@
{
"label": "P",
"location": [
- 25.301647328887036,
- -7.75290088292825,
+ 25.129332369089063,
+ -10.88558481327878,
0
]
}
@@ -293,12 +293,17 @@
{
"label": "P",
"location": [
- 28.276647328887037,
- -10.50290088292825,
+ 22.97099903575573,
+ -11.660584813278774,
0
]
}
- ]
+ ],
+ "stereoFlagPosition": {
+ "x": 22.97099903575573,
+ "y": 10.660584813278774,
+ "z": 0
+ }
},
"mol3": {
"type": "molecule",
@@ -306,8 +311,8 @@
{
"label": "O",
"location": [
- 18.976647328887037,
- -11.32790088292825,
+ 20.845999035755725,
+ -14.543918146612109,
0
]
}
@@ -319,8 +324,8 @@
{
"label": "O",
"location": [
- 24.826647328887038,
- -14.80290088292825,
+ 24.987665702422397,
+ -18.102251479945448,
0
]
}
@@ -332,8 +337,8 @@
{
"label": "O",
"location": [
- 21.926647328887036,
- -12.87790088292825,
+ 22.087665702422388,
+ -16.177251479945447,
0
]
}
@@ -345,88 +350,88 @@
{
"label": "N",
"location": [
- 32.303405381214695,
- -15.774058314166735,
+ 32.46442375475006,
+ -19.073408911183932,
0
]
},
{
"label": "C",
"location": [
- 33.162859719951705,
- -15.484780338347665,
+ 33.32387809348707,
+ -18.784130935364864,
0
]
},
{
"label": "C",
"location": [
- 31.708697468710085,
- -14.908167479746094,
+ 31.869715842245444,
+ -18.207518076763293,
0
]
},
{
"label": "C",
"location": [
- 33.162859719951705,
- -14.392519165166847,
+ 33.32387809348707,
+ -17.691869762184044,
0
]
},
{
"label": "N",
"location": [
- 34.0241357084105,
- -15.997392570057276,
+ 34.18515408194585,
+ -19.296743167074474,
0
]
},
{
"label": "N",
"location": [
- 32.316399815896744,
- -14.094618713998008,
+ 32.4774181894321,
+ -17.393969311015205,
0
]
},
{
"label": "C",
"location": [
- 34.00239735506389,
- -13.903224049896053,
+ 34.16341572859925,
+ -17.20257464691325,
0
]
},
{
"label": "C",
"location": [
- 34.91200778280731,
- -15.490852504086941,
+ 35.073026156342664,
+ -18.79020310110414,
0
]
},
{
"label": "N",
"location": [
- 34.91200778280731,
- -14.4364816451192,
+ 35.073026156342664,
+ -17.735832242136397,
0
]
},
{
"label": "O",
"location": [
- 34.00239735506389,
- -12.942607429942722,
+ 34.16341572859925,
+ -16.241958026959917,
0
]
},
{
"label": "N",
"location": [
- 35.75130253128992,
- -15.981240609190804,
+ 35.91232090482528,
+ -19.280591206208,
0
]
}
@@ -524,8 +529,8 @@
{
"label": "P",
"location": [
- 28.755000000000003,
- -7.445,
+ 26.624351706868698,
+ -12.286017263683862,
0
]
}
@@ -537,11 +542,16 @@
{
"label": "O",
"location": [
- 18.755000000000003,
- -14.945,
+ 23.941018373535353,
+ -15.477683930350532,
0
]
}
- ]
+ ],
+ "stereoFlagPosition": {
+ "x": 23.941018373535353,
+ "y": 14.477683930350532,
+ "z": 0
+ }
}
}
\ No newline at end of file
diff --git a/api/tests/integration/tests/layout/ref/acs_after_layout_default_margin.ket b/api/tests/integration/tests/layout/ref/acs_after_layout_default_margin.ket
index 9c22d22719..3ab3835d16 100644
--- a/api/tests/integration/tests/layout/ref/acs_after_layout_default_margin.ket
+++ b/api/tests/integration/tests/layout/ref/acs_after_layout_default_margin.ket
@@ -27,7 +27,7 @@
{
"type": "plus",
"location": [
- 19.282232,
+ 19.157232,
0.0,
0.0
]
@@ -176,103 +176,110 @@
"type": "molecule",
"atoms": [
{
- "label": "C",
+ "label": "N",
"location": [
- 13.577106,
- -0.75,
+ 10.953616,
+ 2.690644,
0.0
]
},
{
- "label": "C",
+ "label": "N",
"location": [
- 14.443131,
- -0.25,
+ 9.953617,
+ 2.690644,
0.0
]
},
{
- "label": "O",
+ "label": "C",
"location": [
- 15.309156,
- -0.75,
+ 9.330127,
+ 1.908812,
0.0
]
},
{
"label": "C",
"location": [
- 16.175182,
- -0.25,
+ 9.552648,
+ 0.933884,
0.0
]
},
{
"label": "C",
"location": [
- 17.041206,
- -0.75,
+ 11.577106,
+ 1.90881,
0.0
]
},
{
- "label": "C",
+ "label": "N",
"location": [
- 17.907232,
- -0.25,
+ 10.453616,
+ 0.5,
0.0
]
},
{
- "label": "O",
+ "label": "C",
"location": [
- 14.443131,
- 0.75,
+ 11.354585,
+ 0.933883,
0.0
]
}
],
"bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 0
+ ]
+ },
{
"type": 1,
"atoms": [
0,
- 1
+ 4
]
},
{
"type": 1,
"atoms": [
- 1,
- 2
+ 4,
+ 6
]
},
{
"type": 1,
"atoms": [
- 2,
- 3
+ 6,
+ 5
]
},
{
"type": 1,
"atoms": [
- 3,
- 4
+ 5,
+ 3
]
},
{
"type": 1,
"atoms": [
- 4,
- 5
+ 3,
+ 2
]
},
{
- "type": 2,
+ "type": 1,
"atoms": [
- 1,
- 6
+ 2,
+ 1
]
}
]
@@ -281,126 +288,119 @@
"type": "molecule",
"atoms": [
{
- "label": "O",
- "location": [
- 20.657232,
- 0.0,
- 0.0
- ]
- }
- ],
- "bonds": []
- },
- "mol4": {
- "type": "molecule",
- "atoms": [
- {
- "label": "N",
+ "label": "C",
"location": [
- 10.953616,
- 2.690644,
+ 13.577106,
+ -0.75,
0.0
]
},
{
- "label": "N",
+ "label": "C",
"location": [
- 9.953617,
- 2.690644,
+ 14.443131,
+ -0.25,
0.0
]
},
{
- "label": "C",
+ "label": "O",
"location": [
- 9.330127,
- 1.908812,
+ 15.309156,
+ -0.75,
0.0
]
},
{
"label": "C",
"location": [
- 9.552648,
- 0.933884,
+ 16.175182,
+ -0.25,
0.0
]
},
{
"label": "C",
"location": [
- 11.577106,
- 1.90881,
+ 17.041206,
+ -0.75,
0.0
]
},
{
- "label": "N",
+ "label": "C",
"location": [
- 10.453616,
- 0.5,
+ 17.907232,
+ -0.25,
0.0
]
},
{
- "label": "C",
+ "label": "O",
"location": [
- 11.354585,
- 0.933883,
+ 14.443131,
+ 0.75,
0.0
]
}
],
"bonds": [
- {
- "type": 1,
- "atoms": [
- 1,
- 0
- ]
- },
{
"type": 1,
"atoms": [
0,
- 4
+ 1
]
},
{
"type": 1,
"atoms": [
- 4,
- 6
+ 1,
+ 2
]
},
{
"type": 1,
"atoms": [
- 6,
- 5
+ 2,
+ 3
]
},
{
"type": 1,
"atoms": [
- 5,
- 3
+ 3,
+ 4
]
},
{
"type": 1,
"atoms": [
- 3,
- 2
+ 4,
+ 5
]
},
{
- "type": 1,
+ "type": 2,
"atoms": [
- 2,
- 1
+ 1,
+ 6
]
}
]
+ },
+ "mol4": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "O",
+ "location": [
+ 20.657232,
+ 0.0,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
}
}
\ No newline at end of file
diff --git a/api/tests/integration/tests/layout/ref/acs_after_layout_zero_margin.ket b/api/tests/integration/tests/layout/ref/acs_after_layout_zero_margin.ket
index 71b28d2c33..e72a1b4ba3 100644
--- a/api/tests/integration/tests/layout/ref/acs_after_layout_zero_margin.ket
+++ b/api/tests/integration/tests/layout/ref/acs_after_layout_zero_margin.ket
@@ -27,7 +27,7 @@
{
"type": "plus",
"location": [
- 15.782232,
+ 15.657232,
0.0,
0.0
]
@@ -176,103 +176,110 @@
"type": "molecule",
"atoms": [
{
- "label": "C",
+ "label": "N",
"location": [
- 10.577106,
- -0.75,
+ 8.953616,
+ 2.190644,
0.0
]
},
{
- "label": "C",
+ "label": "N",
"location": [
- 11.443131,
- -0.25,
+ 7.953617,
+ 2.190644,
0.0
]
},
{
- "label": "O",
+ "label": "C",
"location": [
- 12.309156,
- -0.75,
+ 7.330127,
+ 1.408812,
0.0
]
},
{
"label": "C",
"location": [
- 13.175182,
- -0.25,
+ 7.552647,
+ 0.433884,
0.0
]
},
{
"label": "C",
"location": [
- 14.041207,
- -0.75,
+ 9.577106,
+ 1.40881,
0.0
]
},
{
- "label": "C",
+ "label": "N",
"location": [
- 14.907232,
- -0.25,
+ 8.453616,
+ 0.0,
0.0
]
},
{
- "label": "O",
+ "label": "C",
"location": [
- 11.443131,
- 0.75,
+ 9.354585,
+ 0.433883,
0.0
]
}
],
"bonds": [
+ {
+ "type": 1,
+ "atoms": [
+ 1,
+ 0
+ ]
+ },
{
"type": 1,
"atoms": [
0,
- 1
+ 4
]
},
{
"type": 1,
"atoms": [
- 1,
- 2
+ 4,
+ 6
]
},
{
"type": 1,
"atoms": [
- 2,
- 3
+ 6,
+ 5
]
},
{
"type": 1,
"atoms": [
- 3,
- 4
+ 5,
+ 3
]
},
{
"type": 1,
"atoms": [
- 4,
- 5
+ 3,
+ 2
]
},
{
- "type": 2,
+ "type": 1,
"atoms": [
- 1,
- 6
+ 2,
+ 1
]
}
]
@@ -281,126 +288,119 @@
"type": "molecule",
"atoms": [
{
- "label": "O",
- "location": [
- 16.657232,
- 0.0,
- 0.0
- ]
- }
- ],
- "bonds": []
- },
- "mol4": {
- "type": "molecule",
- "atoms": [
- {
- "label": "N",
+ "label": "C",
"location": [
- 8.953616,
- 2.190644,
+ 10.577106,
+ -0.75,
0.0
]
},
{
- "label": "N",
+ "label": "C",
"location": [
- 7.953617,
- 2.190644,
+ 11.443131,
+ -0.25,
0.0
]
},
{
- "label": "C",
+ "label": "O",
"location": [
- 7.330127,
- 1.408812,
+ 12.309156,
+ -0.75,
0.0
]
},
{
"label": "C",
"location": [
- 7.552647,
- 0.433884,
+ 13.175182,
+ -0.25,
0.0
]
},
{
"label": "C",
"location": [
- 9.577106,
- 1.40881,
+ 14.041207,
+ -0.75,
0.0
]
},
{
- "label": "N",
+ "label": "C",
"location": [
- 8.453616,
- 0.0,
+ 14.907232,
+ -0.25,
0.0
]
},
{
- "label": "C",
+ "label": "O",
"location": [
- 9.354585,
- 0.433883,
+ 11.443131,
+ 0.75,
0.0
]
}
],
"bonds": [
- {
- "type": 1,
- "atoms": [
- 1,
- 0
- ]
- },
{
"type": 1,
"atoms": [
0,
- 4
+ 1
]
},
{
"type": 1,
"atoms": [
- 4,
- 6
+ 1,
+ 2
]
},
{
"type": 1,
"atoms": [
- 6,
- 5
+ 2,
+ 3
]
},
{
"type": 1,
"atoms": [
- 5,
- 3
+ 3,
+ 4
]
},
{
"type": 1,
"atoms": [
- 3,
- 2
+ 4,
+ 5
]
},
{
- "type": 1,
+ "type": 2,
"atoms": [
- 2,
- 1
+ 1,
+ 6
]
}
]
+ },
+ "mol4": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "O",
+ "location": [
+ 16.657232,
+ 0.0,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
}
}
\ No newline at end of file
diff --git a/api/tests/integration/tests/layout/ref/acs_issue_2458.ket b/api/tests/integration/tests/layout/ref/acs_issue_2458.ket
index 97bf12c55a..11685f1b3b 100644
--- a/api/tests/integration/tests/layout/ref/acs_issue_2458.ket
+++ b/api/tests/integration/tests/layout/ref/acs_issue_2458.ket
@@ -28,26 +28,18 @@
{
"$ref": "mol8"
},
- {
- "type": "plus",
- "location": [
- 7.166667,
- 0.0,
- 0.0
- ]
- },
{
"type": "arrow",
"data": {
"mode": "open-angle",
"pos": [
{
- "x": 9.708333,
+ "x": 6.916667,
"y": 0.0,
"z": 0.0
},
{
- "x": 21.375,
+ "x": 20.458332,
"y": 0.0,
"z": 0.0
}
@@ -286,7 +278,7 @@
{
"label": "P",
"location": [
- 10.368055,
+ 7.576388,
0.902778,
0.0
]
@@ -300,7 +292,7 @@
{
"label": "P",
"location": [
- 12.243055,
+ 9.451388,
0.902778,
0.0
]
@@ -314,8 +306,8 @@
{
"label": "O",
"location": [
- 9.048611,
- 0.0,
+ 12.298611,
+ 0.902778,
0.0
]
}
@@ -328,7 +320,7 @@
{
"label": "O",
"location": [
- 15.090278,
+ 14.173611,
0.902778,
0.0
]
@@ -342,7 +334,7 @@
{
"label": "O",
"location": [
- 16.965279,
+ 16.048611,
0.902778,
0.0
]
@@ -351,12 +343,40 @@
"bonds": []
},
"mol6": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "P",
+ "location": [
+ 16.951387,
+ 0.902778,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol7": {
+ "type": "molecule",
+ "atoms": [
+ {
+ "label": "O",
+ "location": [
+ 19.798611,
+ 0.902778,
+ 0.0
+ ]
+ }
+ ],
+ "bonds": []
+ },
+ "mol8": {
"type": "molecule",
"atoms": [
{
"label": "N",
"location": [
- 22.520832,
+ 21.604164,
1.309017,
0.0
]
@@ -364,7 +384,7 @@
{
"label": "C",
"location": [
- 23.471889,
+ 22.555222,
1.0,
0.0
]
@@ -372,7 +392,7 @@
{
"label": "C",
"location": [
- 21.933048,
+ 21.01638,
0.5,
0.0
]
@@ -380,7 +400,7 @@
{
"label": "C",
"location": [
- 23.471889,
+ 22.555222,
-0.0,
0.0
]
@@ -388,7 +408,7 @@
{
"label": "N",
"location": [
- 24.337915,
+ 23.421247,
1.5,
0.0
]
@@ -396,7 +416,7 @@
{
"label": "N",
"location": [
- 22.520834,
+ 21.604166,
-0.309017,
0.0
]
@@ -404,7 +424,7 @@
{
"label": "C",
"location": [
- 24.337915,
+ 23.421247,
-0.5,
0.0
]
@@ -412,7 +432,7 @@
{
"label": "C",
"location": [
- 25.203941,
+ 24.287273,
1.0,
0.0
]
@@ -420,7 +440,7 @@
{
"label": "N",
"location": [
- 25.203941,
+ 24.287273,
0.0,
0.0
]
@@ -428,7 +448,7 @@
{
"label": "O",
"location": [
- 24.337915,
+ 23.421247,
-1.5,
0.0
]
@@ -436,7 +456,7 @@
{
"label": "N",
"location": [
- 26.069965,
+ 25.153297,
1.5,
0.0
]
@@ -528,33 +548,5 @@
]
}
]
- },
- "mol7": {
- "type": "molecule",
- "atoms": [
- {
- "label": "P",
- "location": [
- 17.868055,
- 0.902778,
- 0.0
- ]
- }
- ],
- "bonds": []
- },
- "mol8": {
- "type": "molecule",
- "atoms": [
- {
- "label": "O",
- "location": [
- 20.715279,
- 0.902778,
- 0.0
- ]
- }
- ],
- "bonds": []
}
}
\ No newline at end of file
diff --git a/api/tests/integration/tests/rendering/reactions/issue_2457.ket b/api/tests/integration/tests/rendering/reactions/issue_2457.ket
index 56e4ebaae3..c5ca5bb849 100644
--- a/api/tests/integration/tests/rendering/reactions/issue_2457.ket
+++ b/api/tests/integration/tests/rendering/reactions/issue_2457.ket
@@ -16,13 +16,13 @@
"mode": "open-angle",
"pos": [
{
- "x": 41.42391053093357,
- "y": -22.826531337313764,
+ "x": 11.2212789519862,
+ "y": -11.021268179419028,
"z": 0
},
{
- "x": 48.19903844362269,
- "y": -22.826531337313764,
+ "x": 17.996406864675322,
+ "y": -11.021268179419028,
"z": 0
}
]
@@ -38,24 +38,24 @@
{
"label": "O",
"location": [
- 52.35883212136368,
- -28.87562356529608,
+ 22.114533875749654,
+ -16.653693740734674,
0
]
},
{
"label": "C",
"location": [
- 52.92921401192261,
- -28.077275885183393,
+ 22.68491576630858,
+ -15.855346060621986,
0
]
},
{
"label": "C",
"location": [
- 52.33305743045339,
- -27.238196180575166,
+ 22.088759184839358,
+ -15.016266356013759,
0
],
"stereoLabel": "abs"
@@ -63,8 +63,8 @@
{
"label": "C",
"location": [
- 52.89182067795949,
- -26.402054523635464,
+ 22.647522432345458,
+ -14.180124699074057,
0
],
"stereoLabel": "abs"
@@ -72,8 +72,8 @@
{
"label": "C",
"location": [
- 52.30087245372084,
- -25.598498486292197,
+ 22.056574208106813,
+ -13.37656866173079,
0
],
"stereoLabel": "abs"
@@ -81,8 +81,8 @@
{
"label": "C",
"location": [
- 52.895025820870615,
- -24.803355949090637,
+ 22.650727575256585,
+ -12.58142612452923,
0
],
"stereoLabel": "abs"
@@ -90,48 +90,48 @@
{
"label": "C",
"location": [
- 52.33038647802745,
- -23.97549424467134,
+ 22.08608823241342,
+ -11.753564420109932,
0
]
},
{
"label": "O",
"location": [
- 52.76855622350248,
- -23.077386491449893,
+ 22.52425797788845,
+ -10.855456666888486,
0
]
},
{
"label": "O",
"location": [
- 53.89142462336656,
- -24.82779516378796,
+ 23.64712637775253,
+ -12.605865339226554,
0
]
},
{
"label": "O",
"location": [
- 51.304073008361,
- -25.598498486292197,
+ 21.059774762746972,
+ -13.37656866173079,
0
]
},
{
"label": "O",
"location": [
- 53.89356138530731,
- -26.376012737482576,
+ 23.64926313969328,
+ -14.154082912921169,
0
]
},
{
"label": "O",
"location": [
- 51.336525080336145,
- -27.259430252361366,
+ 21.092226834722116,
+ -15.037500427799959,
0
]
}
@@ -218,7 +218,12 @@
],
"stereo": 1
}
- ]
+ ],
+ "stereoFlagPosition": {
+ "x": 23.64926313969328,
+ "y": 9.855456666888486,
+ "z": 0
+ }
},
"mol1": {
"type": "molecule",
@@ -226,80 +231,80 @@
{
"label": "C",
"location": [
- 41.983755007176995,
- -20.151628095586382,
+ 11.781123428229627,
+ -8.346364937691646,
0
]
},
{
"label": "C",
"location": [
- 43.71404225136278,
- -20.151142911641287,
+ 13.511410672415408,
+ -8.345879753746551,
0
]
},
{
"label": "N",
"location": [
- 42.850536125084574,
- -19.65152474418239,
+ 12.647904546137205,
+ -7.846261586287653,
0
]
},
{
"label": "C",
"location": [
- 43.71404225136278,
- -21.152077390366912,
+ 13.511410672415408,
+ -9.346814232472177,
0
]
},
{
"label": "C",
"location": [
- 41.983755007176995,
- -21.156565341859018,
+ 11.781123428229627,
+ -9.351302183964282,
0
]
},
{
"label": "N",
"location": [
- 42.85271945283749,
- -21.651574261839542,
+ 12.650087873890122,
+ -9.846311103944807,
0
]
},
{
"label": "N",
"location": [
- 44.57853097637396,
- -19.65277101955808,
+ 14.375899397426593,
+ -7.847507861663345,
0
]
},
{
"label": "C",
"location": [
- 45.445707621707655,
- -20.15310257689237,
+ 15.243076042760286,
+ -8.347839418997633,
0
]
},
{
"label": "N",
"location": [
- 44.58468676258305,
- -21.654409788878134,
+ 14.382055183635678,
+ -9.849146630983398,
0
]
},
{
"label": "C",
"location": [
- 45.44791060726914,
- -21.149004989836765,
+ 15.245279028321768,
+ -9.34374183194203,
0
]
}
@@ -390,16 +395,16 @@
{
"label": "O",
"location": [
- 34.1487631386849,
- -20.778212519312998,
+ 3.9461315597375304,
+ -8.972949361418262,
0
]
},
{
"label": "C",
"location": [
- 33.32184848832077,
- -21.176618139623265,
+ 3.1192169093733995,
+ -9.37135498172853,
0
],
"stereoLabel": "abs"
@@ -407,8 +412,8 @@
{
"label": "C",
"location": [
- 33.637748467111564,
- -21.94617526442655,
+ 3.4351168881641954,
+ -10.140912106531815,
0
],
"stereoLabel": "abs"
@@ -416,16 +421,16 @@
{
"label": "C",
"location": [
- 34.659777810258234,
- -21.94617526442655,
+ 4.457146231310865,
+ -10.140912106531815,
0
]
},
{
"label": "C",
"location": [
- 34.9755539067044,
- -21.176618139623265,
+ 4.77292232775703,
+ -9.37135498172853,
0
],
"stereoLabel": "abs"
@@ -433,176 +438,176 @@
{
"label": "O",
"location": [
- 33.637748467111564,
- -22.968204607573224,
+ 3.4351168881641954,
+ -11.162941449678488,
0
]
},
{
"label": "C",
"location": [
- 33.32184848832077,
- -20.15458879647659,
+ 3.1192169093733995,
+ -8.349325638581856,
0
]
},
{
"label": "O",
"location": [
- 32.2998191451741,
- -20.15458879647659,
+ 2.0971875662267294,
+ -8.349325638581856,
0
]
},
{
"label": "N",
"location": [
- 34.9755539067044,
- -20.15458879647659,
+ 4.77292232775703,
+ -8.349325638581856,
0
]
},
{
"label": "C",
"location": [
- 36.8479116633491,
- -18.356932093640065,
+ 6.645280084401733,
+ -6.5516689357453295,
0
]
},
{
"label": "N",
"location": [
- 37.7329271333418,
- -18.868070647558024,
+ 7.530295554394435,
+ -7.062807489663289,
0
]
},
{
"label": "C",
"location": [
- 37.7329271333418,
- -19.890099990704694,
+ 7.530295554394435,
+ -8.084836832809959,
0
]
},
{
"label": "N",
"location": [
- 36.8479116633491,
- -20.401114662278033,
+ 6.645280084401733,
+ -8.595851504383297,
0
]
},
{
"label": "C",
"location": [
- 35.96277231101177,
- -19.890099990704694,
+ 5.7601407320644,
+ -8.084836832809959,
0
]
},
{
"label": "N",
"location": [
- 35.06214766559646,
- -18.50323714264082,
+ 4.859516086649094,
+ -6.697973984746085,
0
]
},
{
"label": "C",
"location": [
- 35.96277231101177,
- -18.868070647558024,
+ 5.7601407320644,
+ -7.062807489663289,
0
]
},
{
"label": "C",
"location": [
- 34.41895053230949,
- -19.29744685402425,
+ 4.216318953362119,
+ -7.492183696129516,
0
]
},
{
"label": "N",
"location": [
- 36.8479116633491,
- -17.33490275049339,
+ 6.645280084401733,
+ -5.529639592598656,
0
]
},
{
"label": "O",
"location": [
- 34.659777810258234,
- -22.968204607573224,
+ 4.457146231310865,
+ -11.162941449678488,
0
]
},
{
"label": "P",
"location": [
- 31.277789802027428,
- -20.15458879647659,
+ 1.0751582230800594,
+ -8.349325638581856,
0
]
},
{
"label": "O",
"location": [
- 31.277789802027428,
- -19.13255945332992,
+ 1.0751582230800594,
+ -7.327296295435186,
0
]
},
{
"label": "O",
"location": [
- 31.277789802027428,
- -21.176618139623265,
+ 1.0751582230800594,
+ -9.37135498172853,
0
]
},
{
"label": "O",
"location": [
- 30.255760458880758,
- -20.15458879647659,
+ 0.05312887993338933,
+ -8.349325638581856,
0
]
},
{
"label": "P",
"location": [
- 29.233731115734088,
- -20.15458879647659,
+ -0.9689004632132807,
+ -8.349325638581856,
0
]
},
{
"label": "O",
"location": [
- 29.233731115734088,
- -19.13255945332992,
+ -0.9689004632132807,
+ -7.327296295435186,
0
]
},
{
"label": "O",
"location": [
- 29.233731115734088,
- -21.176618139623265,
+ -0.9689004632132807,
+ -9.37135498172853,
0
]
},
{
"label": "O",
"location": [
- 28.211701772587414,
- -20.15458879647659,
+ -1.9909298063599543,
+ -8.349325638581856,
0
]
}
@@ -816,4 +821,4 @@
}
]
}
-}
+}
\ No newline at end of file
diff --git a/core/indigo-core/common/math/algebra.h b/core/indigo-core/common/math/algebra.h
index 9ec0be286b..4f7750b1f5 100644
--- a/core/indigo-core/common/math/algebra.h
+++ b/core/indigo-core/common/math/algebra.h
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
#include "base_c/defs.h"
#include "base_cpp/exception.h"
@@ -279,6 +280,7 @@ namespace indigo
DLLEXPORT void rotateL(float si, float co);
DLLEXPORT void rotateL(Vec2f vec);
DLLEXPORT void rotateAroundSegmentEnd(const Vec2f& a, const Vec2f& b, float angle);
+ DLLEXPORT float relativeCross(const Vec2f& a, const Vec2f& b) const;
DLLEXPORT static float distSqr(const Vec2f& a, const Vec2f& b);
DLLEXPORT static float dist(const Vec2f& a, const Vec2f& b);
@@ -822,5 +824,248 @@ namespace indigo
float _d;
};
+ inline bool isPointOnSegment(const Vec2f& p, const Vec2f& a, const Vec2f& b)
+ {
+ const float eps = 1e-7f;
+ float c = Vec2f::cross(p - a, b - a);
+ if (std::fabs(c) > eps)
+ return false;
+ float d = (p - a) * (b - a);
+ if (d < 0)
+ return false;
+ float l = (b - a) * (b - a);
+ if (d > l)
+ return false;
+ return true;
+ }
+
+ // Ray casting algorithm
+ inline bool isPointInPolygon(const Vec2f& p, const std::vector& poly)
+ {
+ bool in = false;
+ size_t n = poly.size();
+ for (size_t i = 0; i < n; ++i)
+ {
+ size_t j = (i + 1) % n;
+ if (isPointOnSegment(p, poly[i], poly[j]))
+ return true;
+ if (((poly[i].y > p.y) != (poly[j].y > p.y)) &&
+ (((p.x > poly[i].x) && (p.x < poly[j].x)) || (p.x < (poly[i].x + (p.y - poly[i].y) * (poly[j].x - poly[i].x) / (poly[j].y - poly[i].y)))))
+ in = !in;
+ }
+ return in;
+ }
+
+ inline std::vector getPointsInsidePolygon(const std::vector& polygon1, const std::vector& polygon2)
+ {
+ std::vector result;
+ result.reserve(polygon1.size());
+ std::copy_if(polygon1.begin(), polygon1.end(), std::back_inserter(result), [&](auto& p) { return isPointInPolygon(p, polygon2); });
+ return result;
+ }
+
+ inline bool isPointInConvexPolygon(const Vec2f& p, const std::vector& poly)
+ {
+ auto cross = [](const Vec2f& a, const Vec2f& b, const Vec2f& c) { return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x); };
+ bool sign = cross(poly.back(), poly[0], p) < 0;
+ for (size_t i = 0, n = poly.size(); i < n; ++i)
+ if ((cross(poly[i], poly[(i + 1) % n], p) < 0) != sign)
+ return false;
+ return true;
+ }
+
+ inline std::vector getPointsInsideConvexPolygon(const std::vector& polygon1, const std::vector& polygon2)
+ {
+ std::vector result;
+ result.reserve(polygon1.size());
+ std::copy_if(polygon1.begin(), polygon1.end(), std::back_inserter(result), [&](auto& p) { return isPointInConvexPolygon(p, polygon2); });
+ return result;
+ }
+
+ // Shoelace formula - triangle form
+ inline float convexPolygonArea(const std::vector& poly)
+ {
+ float area = 0.0f;
+ size_t n = poly.size();
+ for (size_t i = 0; i < n; ++i)
+ {
+ const Vec2f& p1 = poly[i];
+ const Vec2f& p2 = poly[(i + 1) % n];
+ area += Vec2f::cross(p1, p2);
+ }
+ return std::abs(area) * 0.5f;
+ }
+
+ inline bool convexPolygonsIntersect(const std::vector& poly1, const std::vector& poly2)
+ {
+ auto project = [](const std::vector& poly, const Vec2f& axis) {
+ auto [min, max] = std::minmax_element(poly.begin(), poly.end(), [&](const Vec2f& a, const Vec2f& b) { return a * axis < b * axis; });
+ return std::pair{*min * axis, *max * axis};
+ };
+
+ auto overlap = [](const auto& range1, const auto& range2) { return !(range1.first > range2.second || range2.first > range1.second); };
+
+ auto getNormals = [](const std::vector& poly) {
+ std::vector normals;
+ for (size_t i = 0; i < poly.size(); ++i)
+ {
+ Vec2f edge = poly[(i + 1) % poly.size()] - poly[i];
+ normals.emplace_back(-edge.y, edge.x);
+ }
+ return normals;
+ };
+
+ auto normals1 = getNormals(poly1), normals2 = getNormals(poly2);
+ for (const auto& normal : normals1)
+ if (!overlap(project(poly1, normal), project(poly2, normal)))
+ return false;
+ for (const auto& normal : normals2)
+ if (!overlap(project(poly1, normal), project(poly2, normal)))
+ return false;
+ return true;
+ }
+
+ inline Vec2f computeIntersection(const Vec2f& s, const Vec2f& e, const Vec2f& edgeStart, const Vec2f& edgeEnd)
+ {
+ float dx1 = e.x - s.x, dy1 = e.y - s.y, dx2 = edgeEnd.x - edgeStart.x, dy2 = edgeEnd.y - edgeStart.y;
+ float det = dx1 * dy2 - dy1 * dx2;
+ if (std::abs(det) < 1e-6)
+ return s;
+ float t = ((edgeStart.x - s.x) * dy2 - (edgeStart.y - s.y) * dx2) / det;
+ return {s.x + t * dx1, s.y + t * dy1};
+ }
+
+ inline std::vector convexClip(const std::vector& subject, const std::vector& clip)
+ {
+ std::vector result = subject;
+ for (size_t i = 0; i < clip.size(); ++i)
+ {
+ const Vec2f& edgeStart = clip[i];
+ const Vec2f& edgeEnd = clip[(i + 1) % clip.size()];
+ std::vector input = std::move(result);
+ result.clear();
+ if (input.empty())
+ break;
+ Vec2f prev = input.back();
+ for (const Vec2f& curr : input)
+ {
+ if (edgeStart.relativeCross(edgeEnd, curr) <= 0)
+ {
+ if (edgeStart.relativeCross(edgeEnd, prev) > 0)
+ result.push_back(computeIntersection(prev, curr, edgeStart, edgeEnd));
+ result.push_back(curr);
+ }
+ else if (edgeStart.relativeCross(edgeEnd, prev) <= 0)
+ {
+ result.push_back(computeIntersection(prev, curr, edgeStart, edgeEnd));
+ }
+ prev = curr;
+ }
+ }
+ return result;
+ }
+
+ inline float computeConvexContainment(const std::vector& poly1, const std::vector& poly2)
+ {
+ float area = convexPolygonArea(poly1);
+ if (area == 0.0f)
+ return 0.0f;
+ std::vector intersection = convexClip(poly1, poly2);
+ if (intersection.empty())
+ return 0.0f;
+ float intersectionArea = convexPolygonArea(intersection);
+ if (std::abs(intersectionArea - area) < 1e-6f)
+ return 1.0f;
+ return intersectionArea / area;
+ }
+
+ inline float distancePointToEdge(const Vec2f& p, const Vec2f& a, const Vec2f& b)
+ {
+ Vec2f ab = b - a;
+ Vec2f ap = p - a;
+ float t = Vec2f::dot(ap, ab) / Vec2f::dot(ab, ab);
+ t = std::max(0.0f, std::min(1.0f, t));
+ Vec2f projection(a.x + ab.x * t, a.y + ab.y * t);
+ Vec2f diff = p - projection;
+ return diff.length();
+ }
+
+ inline float computeConvexDistance(const std::vector& poly1, const std::vector& poly2)
+ {
+ float minDist = std::numeric_limits::max();
+ for (const auto& p : poly1)
+ {
+ float dist = std::numeric_limits::max();
+ size_t n = poly2.size();
+ for (size_t i = 0; i < n; ++i)
+ {
+ float d = distancePointToEdge(p, poly2[i], poly2[(i + 1) % n]);
+ dist = std::min(dist, d);
+ if (d < minDist)
+ break;
+ }
+ minDist = std::min(minDist, dist);
+ }
+ for (const auto& p : poly2)
+ {
+ float dist = std::numeric_limits::max();
+ size_t n = poly1.size();
+ for (size_t i = 0; i < n; ++i)
+ {
+ float d = distancePointToEdge(p, poly1[i], poly1[(i + 1) % n]);
+ dist = std::min(dist, d);
+ if (d < minDist)
+ break;
+ }
+ minDist = std::min(minDist, dist);
+ }
+ return minDist;
+ }
+
+ inline bool doesVerticalLineIntersectPolygon(float x, const std::vector& poly)
+ {
+ for (size_t i = 0, n = poly.size(); i < n; ++i)
+ {
+ const Vec2f& a = poly[i];
+ const Vec2f& b = poly[(i + 1) % n];
+ if ((x > std::min(a.x, b.x) && x < std::max(a.x, b.x)))
+ return true;
+ }
+ return false;
+ }
+
+ inline bool doesHorizontalLineIntersectPolygon(float y, const std::vector& poly)
+ {
+ for (size_t i = 0, n = poly.size(); i < n; ++i)
+ {
+ const Vec2f& a = poly[i];
+ const Vec2f& b = poly[(i + 1) % n];
+ if ((y > std::min(a.y, b.y) && y < std::max(a.y, b.y)))
+ return true;
+ }
+ return false;
+ }
+
+ inline bool doesRayIntersectPolygon(const Vec2f& p1, const Vec2f& p2, const std::vector& poly)
+ {
+ Vec2f dir = p2 - p1;
+ for (size_t i = 0, n = poly.size(); i < n; ++i)
+ {
+ Vec2f A = poly[i];
+ Vec2f B = poly[(i + 1) % n];
+ Vec2f a = A - p1;
+ Vec2f b = B - p1;
+ Vec2f s = b - a;
+ float den = Vec2f::cross(dir, s);
+ if (std::fabs(den) <= +0.0f)
+ continue;
+ float t = Vec2f::cross(a, s) / den;
+ float u = Vec2f::cross(a, dir) / den;
+ if (t >= 0.f && u >= 0.f && u <= 1.f)
+ return true;
+ }
+ return false;
+ }
+
} // namespace indigo
#endif
diff --git a/core/indigo-core/common/math/vec2f.cpp b/core/indigo-core/common/math/vec2f.cpp
index d8c2d9c7f7..3ebf1533d4 100644
--- a/core/indigo-core/common/math/vec2f.cpp
+++ b/core/indigo-core/common/math/vec2f.cpp
@@ -189,6 +189,11 @@ float Vec2f::cross(const Vec2f& a, const Vec2f& b)
return a.x * b.y - a.y * b.x;
}
+float Vec2f::relativeCross(const Vec2f& a, const Vec2f& b) const
+{
+ return cross(a - *this, b - *this);
+}
+
void Vec2f::projectZ(Vec2f& v2, const Vec3f& v3)
{
v2.x = v3.x;
diff --git a/core/indigo-core/layout/src/reaction_layout.cpp b/core/indigo-core/layout/src/reaction_layout.cpp
index f3b548523e..3fe232fcb4 100644
--- a/core/indigo-core/layout/src/reaction_layout.cpp
+++ b/core/indigo-core/layout/src/reaction_layout.cpp
@@ -408,6 +408,26 @@ void ReactionLayout::make()
else
processReactionElements(_r.productBegin(), _r.productEnd(), &BaseReaction::productNext);
+ if (_r.undefinedCount())
+ {
+ Metalayout::LayoutLine& line_undef = _ml.newLine();
+ for (int i = _r.undefinedBegin(); i < _r.undefinedEnd(); i = _r.undefinedNext(i))
+ {
+ Rect2f bbox;
+ _r.getBaseMolecule(i).getBoundingBox(bbox);
+ if (i != _r.undefinedBegin())
+ {
+ if (bbox.height() > _ml.verticalIntervalFactor)
+ _ml.verticalIntervalFactor = bbox.height();
+ _pushSpace(line_undef, reaction_margin_size);
+ }
+ else
+ _ml.verticalIntervalFactor = bbox.height();
+ _pushMol(line_undef, i, true);
+ }
+ _ml.verticalIntervalFactor += reaction_margin_size;
+ }
+
_ml.bondLength = bond_length;
_ml.reactionComponentMarginSize = reaction_margin_size;
_ml.cb_getMol = cb_getMol;
diff --git a/core/indigo-core/molecule/base_molecule.h b/core/indigo-core/molecule/base_molecule.h
index 04def60ddd..ec5d42c7fc 100644
--- a/core/indigo-core/molecule/base_molecule.h
+++ b/core/indigo-core/molecule/base_molecule.h
@@ -589,6 +589,9 @@ namespace indigo
void getBoundingBox(float font_size, LABEL_MODE label_mode, Vec2f& bottom_left, Vec2f& top_right);
void getBoundingBox(float font_size, LABEL_MODE label_mode, Rect2f& bbox);
+ // calc convex hull
+ std::vector getConvexHull(const Vec2f& min_box) const;
+
// aliases
bool isAlias(int atom_idx) const;
const char* getAlias(int atom_idx) const;
diff --git a/core/indigo-core/molecule/meta_commons.h b/core/indigo-core/molecule/meta_commons.h
index 8e72c9eb5c..feea02eaee 100644
--- a/core/indigo-core/molecule/meta_commons.h
+++ b/core/indigo-core/molecule/meta_commons.h
@@ -495,7 +495,8 @@ namespace indigo
ARROW_ELLIPTICAL_ARC_OPEN_ANGLE,
ARROW_ELLIPTICAL_ARC_OPEN_HALF_ANGLE,
ARROW_RETROSYNTHETIC,
- ARROW_MULTITAIL
+ ARROW_MULTITAIL,
+ TEXT
};
enum
diff --git a/core/indigo-core/molecule/src/base_molecule.cpp b/core/indigo-core/molecule/src/base_molecule.cpp
index 77d5a4db9d..fd84a0f3c4 100644
--- a/core/indigo-core/molecule/src/base_molecule.cpp
+++ b/core/indigo-core/molecule/src/base_molecule.cpp
@@ -4775,6 +4775,40 @@ void BaseMolecule::getBoundingBox(float font_size, LABEL_MODE label_mode, Rect2f
bbox = Rect2f(a, b);
}
+std::vector BaseMolecule::getConvexHull(const Vec2f& min_box) const
+{
+ std::vector vertices;
+ std::transform(_xyz.ptr(), _xyz.ptr() + _xyz.size(), std::back_inserter(vertices), [](const Vec3f& v) -> Vec2f { return Vec2f(v.x, v.y); });
+ if (vertices.size() < 3)
+ {
+ Rect2f bbox;
+ getBoundingBox(bbox, min_box);
+ vertices.clear();
+ vertices.emplace_back(bbox.leftTop());
+ vertices.emplace_back(bbox.rightTop());
+ vertices.emplace_back(bbox.rightBottom());
+ vertices.emplace_back(bbox.leftBottom());
+ return vertices;
+ }
+ std::sort(vertices.begin(), vertices.end());
+ std::vector hull;
+ for (const auto& p : vertices)
+ {
+ while (hull.size() >= 2 && hull[hull.size() - 2].relativeCross(hull.back(), p) <= 0)
+ hull.pop_back();
+ hull.push_back(p);
+ }
+ size_t lower_size = hull.size();
+ for (auto it = vertices.rbegin(); it != vertices.rend(); ++it)
+ {
+ while (hull.size() > lower_size && hull[hull.size() - 2].relativeCross(hull.back(), *it) <= 0)
+ hull.pop_back();
+ hull.push_back(*it);
+ }
+ hull.pop_back();
+ return hull;
+}
+
void BaseMolecule::getBoundingBox(Vec2f& a, Vec2f& b) const
{
for (int atom_idx = 0; atom_idx < vertexCount(); ++atom_idx)
diff --git a/core/indigo-core/reaction/reaction_multistep_detector.h b/core/indigo-core/reaction/reaction_multistep_detector.h
index b93ccc1f5c..2a0c00e9af 100644
--- a/core/indigo-core/reaction/reaction_multistep_detector.h
+++ b/core/indigo-core/reaction/reaction_multistep_detector.h
@@ -29,6 +29,7 @@
#include
#include "base_cpp/exception.h"
+#include "layout/metalayout.h"
#include "molecule/meta_commons.h"
namespace indigo
@@ -41,6 +42,15 @@ namespace indigo
class ReactionMultistepDetector
{
public:
+ using MOL_DISTANCES = std::vector>;
+ using MOL_DISTANCES_MAP = std::unordered_map;
+
+ struct MOL_DISTANCES_DESC
+ {
+ MOL_DISTANCES sorted_distances;
+ MOL_DISTANCES_MAP distances_map;
+ };
+
enum class ReactionType
{
ESimpleReaction,
@@ -48,11 +58,62 @@ namespace indigo
EPathwayReaction
};
+ enum class ZoneType
+ {
+ EPlus,
+ EArrow,
+ EPathWay
+ };
+
+ enum class PlusSectionCode : int
+ {
+ ELeft = 0,
+ ERight,
+ ETop,
+ EBottom,
+ };
+
+ enum class ArrowSectionCode : int
+ {
+ ELeft = 0,
+ ERight,
+ ETop,
+ EBottom,
+ };
+
+ enum class PathwaySectionCode : int
+ {
+ ERight,
+ ETop,
+ EBottom,
+ };
+
+ struct SPECIAL_ZONE_DESC
+ {
+ ZoneType zone_type;
+ std::vector> zone_sections;
+ std::vector origin_coordinates;
+ };
+
+ struct COMPONENT_DESC
+ {
+ COMPONENT_DESC(std::unique_ptr mol, std::vector poly, int idx) : mol(std::move(mol)), hull(poly), idx(idx), mapped_idx(-1)
+ {
+ }
+ std::unique_ptr mol;
+ std::vector hull;
+ int idx;
+ int mapped_idx;
+ };
+
ReactionMultistepDetector(BaseMolecule& mol);
~ReactionMultistepDetector();
ReactionType detectReaction();
void constructMultipleArrowReaction(BaseReaction& rxn);
void constructSimpleArrowReaction(BaseReaction& rxn);
+ uint8_t geMoleculeSide(BaseReaction& rxn, BaseMolecule& mol);
+ uint8_t geMoleculeSide(BaseReaction& rxn, BaseMolecule& mol, std::array& sides);
+
void constructPathwayReaction(PathwayReaction& rxn);
void detectPathwayMetadata(PathwayReaction& rxn);
void collectMetadata(int reaction_idx, PathwayReaction& rxn, const Rect2f& bbox);
@@ -62,15 +123,30 @@ namespace indigo
typedef std::vector FLOAT_INT_PAIRS;
const Vec2f PLUS_BBOX_SHIFT = {0.9f, 0.9f};
const Vec2f ARROW_BBOX_SHIFT = {0.0f, 0.9f};
+ const float PLUS_DETECTION_DISTANCE = LayoutOptions::DEFAULT_BOND_LENGTH * 2.0f;
+ const float ARROW_DETECTION_DISTANCE = LayoutOptions::DEFAULT_BOND_LENGTH * 2.0f;
DECL_ERROR;
private:
void createSummBlocks();
+ // collect molecules' distances
+ void collectSortedDistances();
+ void createSpecialZones();
+ void addPlusZones(const Vec2f& pos);
+ void addArrowZones(const Vec2f& tail, const Vec2f& head);
+ void addPathwayZones(const Vec2f& head, const Vec2f& sp_beg, const Vec2f& sp_end, const std::vector& tails);
+ std::map> findSpecialZones(size_t mol_idx);
+ std::optional> findMaxSpecialZone(size_t mol_idx, std::map>& other_zones);
+
+ void mergeCloseComponents();
+ std::optional> isMergeable(size_t mol_idx1, size_t mol_idx2, std::optional>& current_zone);
+ std::unique_ptr extractComponent(int index);
void sortSummblocks();
bool mapReactionComponents();
bool mapMultitailReactionComponents();
+ bool mergeUndefinedComponents();
bool findPlusNeighbours(const Vec2f& plus_pos, const FLOAT_INT_PAIRS& mol_tops, const FLOAT_INT_PAIRS& mol_bottoms, const FLOAT_INT_PAIRS& mol_lefts,
const FLOAT_INT_PAIRS& mol_rights, std::pair& connection);
@@ -78,8 +154,10 @@ namespace indigo
BaseMolecule& _bmol;
std::vector _reaction_components;
std::vector _component_summ_blocks;
- std::list _component_summ_blocks_list;
-
+ std::vector _components;
+ std::vector _merged_components;
+ std::vector _mol_distances;
+ std::vector _zones;
int _moleculeCount;
};
diff --git a/core/indigo-core/reaction/src/reaction_json_loader.cpp b/core/indigo-core/reaction/src/reaction_json_loader.cpp
index 4a630ec30c..84f849de85 100644
--- a/core/indigo-core/reaction/src/reaction_json_loader.cpp
+++ b/core/indigo-core/reaction/src/reaction_json_loader.cpp
@@ -72,7 +72,7 @@ void ReactionJsonLoader::loadReaction(BaseReaction& rxn)
if (arrow_count == 0 && multi_count == 0)
throw Error("No arrow in the reaction");
- if (arrow_count > 1 || multi_count > 0)
+ if (arrow_count > 0 || multi_count > 0)
{
ReactionMultistepDetector md(*_pmol);
switch (md.detectReaction())
@@ -89,8 +89,6 @@ void ReactionJsonLoader::loadReaction(BaseReaction& rxn)
break;
}
}
- else
- parseOneArrowReaction(rxn);
}
void ReactionJsonLoader::parseOneArrowReaction(BaseReaction& rxn)
diff --git a/core/indigo-core/reaction/src/reaction_multistep_detector.cpp b/core/indigo-core/reaction/src/reaction_multistep_detector.cpp
index bf6b7d41a1..254d34e7c0 100644
--- a/core/indigo-core/reaction/src/reaction_multistep_detector.cpp
+++ b/core/indigo-core/reaction/src/reaction_multistep_detector.cpp
@@ -16,6 +16,7 @@
* limitations under the License.
***************************************************************************/
#include
+#include
#include "layout/pathway_layout.h"
#include "reaction/pathway_reaction.h"
@@ -49,32 +50,22 @@ void ReactionMultistepDetector::createSummBlocks()
auto pair_comp_asc = [](const FLOAT_INT_PAIR& a, const FLOAT_INT_PAIR& b) { return b.first > a.first; };
auto pair_comp_des = [](const FLOAT_INT_PAIR& a, const FLOAT_INT_PAIR& b) { return b.first < a.first; };
auto pair_comp_mol_asc = [](const FLOAT_INT_PAIR& a, const FLOAT_INT_PAIR& b) { return b.second > a.second; };
- std::list> s_neighbors;
- getSGroupAtoms(_bmol, s_neighbors);
- _moleculeCount = _bmol.countComponents(s_neighbors);
_reaction_components.reserve(_moleculeCount);
FLOAT_INT_PAIRS mol_tops, mol_bottoms, mol_lefts, mol_rights;
// collect components
for (int i = 0; i < _moleculeCount; ++i)
{
- Filter filter(_bmol.getDecomposition().ptr(), Filter::EQ, i);
- std::unique_ptr component;
- if (_bmol.isQueryMolecule())
- component = std::make_unique();
- else
- component = std::make_unique();
-
- BaseMolecule& mol = *component;
- mol.makeSubmolecule(_bmol, filter, 0, 0);
Rect2f bbox;
- mol.getBoundingBox(bbox, MIN_MOL_SIZE);
-
+ auto& comp = _merged_components[i];
+ comp.mol->getBoundingBox(bbox, MIN_MOL_SIZE);
mol_tops.emplace_back(bbox.top(), i);
mol_bottoms.emplace_back(bbox.bottom(), i);
mol_lefts.emplace_back(bbox.left(), i);
mol_rights.emplace_back(bbox.right(), i);
- _reaction_components.emplace_back(ReactionComponent::MOLECULE, bbox, i, std::move(component));
+ auto mol = std::unique_ptr(comp.mol->neu());
+ mol->clone(*comp.mol);
+ _reaction_components.emplace_back(ReactionComponent::MOLECULE, bbox, i, std::move(mol));
}
for (int i = 0; i < _bmol.meta().getMetaCount(ReactionPlusObject::CID); ++i)
@@ -134,6 +125,8 @@ void ReactionMultistepDetector::createSummBlocks()
std::sort(mol_lefts.begin(), mol_lefts.end(), pair_comp_des);
std::sort(mol_rights.begin(), mol_rights.end(), pair_comp_asc);
+ std::list component_summ_blocks_list;
+
for (int i = 0; i < _bmol.meta().getMetaCount(ReactionPlusObject::CID); ++i)
{
auto& plus = static_cast(_bmol.meta().getMetaObject(ReactionPlusObject::CID, i));
@@ -164,14 +157,14 @@ void ReactionMultistepDetector::createSummBlocks()
// create brand new connection
Rect2f bbox = rc_connection.first.bbox;
merge_bbox(bbox, rc_connection.second.bbox);
- _component_summ_blocks_list.emplace_back(bbox); // add merged boxes of both components
- auto& last_sb = _component_summ_blocks_list.back();
+ component_summ_blocks_list.emplace_back(bbox); // add merged boxes of both components
+ auto& last_sb = component_summ_blocks_list.back();
last_sb.indexes.push_back(plus_connection.first);
last_sb.indexes.push_back(plus_connection.second);
rc_connection.first.summ_block_idx = ReactionComponent::CONNECTED; // mark as connected
rc_connection.second.summ_block_idx = ReactionComponent::CONNECTED;
- auto last_it = std::prev(_component_summ_blocks_list.end());
+ auto last_it = std::prev(component_summ_blocks_list.end());
rc_connection.first.summ_block_it = last_it; // bind to summ blocks list
rc_connection.second.summ_block_it = last_it;
}
@@ -188,7 +181,7 @@ void ReactionMultistepDetector::createSummBlocks()
block_first.indexes.push_back(v); // copy all indexes of block_second to block_first
_reaction_components[v].summ_block_it = rc_connection.first.summ_block_it; // patch copied components. now they belong to block_first.
}
- _component_summ_blocks_list.erase(second_block_it); // remove block_second
+ component_summ_blocks_list.erase(second_block_it); // remove block_second
}
break;
@@ -216,7 +209,7 @@ void ReactionMultistepDetector::createSummBlocks()
}
// copy list to vector and set summ block indexes
- for (auto& csb : _component_summ_blocks_list)
+ for (auto& csb : component_summ_blocks_list)
{
for (int v : csb.indexes)
_reaction_components[v].summ_block_idx = static_cast(_component_summ_blocks.size());
@@ -238,6 +231,437 @@ void ReactionMultistepDetector::createSummBlocks()
}
}
+std::unique_ptr ReactionMultistepDetector::extractComponent(int index)
+{
+ Filter filter(_bmol.getDecomposition().ptr(), Filter::EQ, index);
+ std::unique_ptr component;
+ if (_bmol.isQueryMolecule())
+ component = std::make_unique();
+ else
+ component = std::make_unique();
+ component->makeSubmolecule(_bmol, filter, 0, 0);
+ return component;
+}
+
+// TODO: we can't avoid the calculation like this, but it's optimizable to N(log(N)) complexity
+void ReactionMultistepDetector::collectSortedDistances()
+{
+ _mol_distances.resize(_moleculeCount);
+ for (int i = 0; i < _moleculeCount; ++i)
+ {
+ auto& mdi = _mol_distances[i];
+ for (int j = i + 1; j < _moleculeCount; ++j)
+ {
+ float dist = computeConvexDistance(_components[i].hull, _components[j].hull);
+ auto& mdj = _mol_distances[j];
+ if (dist < LayoutOptions::DEFAULT_BOND_LENGTH * 2)
+ {
+ mdi.sorted_distances.emplace_back(j, dist);
+ mdj.sorted_distances.emplace_back(i, dist);
+ }
+ mdj.distances_map.emplace(i, dist);
+ mdi.distances_map.emplace(j, dist);
+ }
+ std::sort(mdi.sorted_distances.begin(), mdi.sorted_distances.end(), [](auto& lhs, auto& rhs) { return lhs.second < rhs.second; });
+ }
+}
+
+void ReactionMultistepDetector::createSpecialZones()
+{
+ for (int i = 0; i < _bmol.meta().getMetaCount(ReactionArrowObject::CID); ++i)
+ {
+ auto& arrow = (const ReactionArrowObject&)_bmol.meta().getMetaObject(ReactionArrowObject::CID, i);
+ addArrowZones(arrow.getTail(), arrow.getHead());
+ }
+
+ for (int i = 0; i < _bmol.meta().getMetaCount(ReactionPlusObject::CID); ++i)
+ {
+ auto& plus = (const ReactionPlusObject&)_bmol.meta().getMetaObject(ReactionPlusObject::CID, i);
+ const auto& plus_pos = plus.getPos();
+ addPlusZones(plus_pos);
+ }
+
+ for (int i = 0; i < _bmol.meta().getMetaCount(ReactionMultitailArrowObject::CID); ++i)
+ {
+ const auto& multi = (const ReactionMultitailArrowObject&)_bmol.meta().getMetaObject(ReactionMultitailArrowObject::CID, i);
+ const auto& tails = multi.getTails();
+ const auto& head = multi.getHead();
+ const auto& spine_beg = multi.getSpineBegin();
+ const auto& spine_end = multi.getSpineEnd();
+ std::vector tails_vec(tails.begin(), tails.end());
+ addPathwayZones(head, spine_beg, spine_end, tails_vec);
+ }
+}
+
+void ReactionMultistepDetector::addPlusZones(const Vec2f& pos)
+{
+ Rect2f bbox(pos - PLUS_BBOX_SHIFT / 2, pos + PLUS_BBOX_SHIFT / 2);
+ SPECIAL_ZONE_DESC szd;
+ szd.zone_type = ZoneType::EPlus;
+ szd.origin_coordinates.push_back(pos);
+ std::vector left, right, bottom, top;
+
+ // left zone
+ left.push_back(pos);
+ left.push_back(bbox.leftBottom());
+ left.push_back(Vec2f(left.back().x - PLUS_DETECTION_DISTANCE, left.back().y));
+ left.push_back(Vec2f(left.back().x, left.back().y + bbox.height()));
+ left.push_back(bbox.leftTop());
+ left.push_back(pos);
+
+ // right zone
+ right.push_back(pos);
+ right.push_back(bbox.rightTop());
+ right.push_back(Vec2f(right.back().x + PLUS_DETECTION_DISTANCE, right.back().y));
+ right.push_back(Vec2f(right.back().x, right.back().y - bbox.height()));
+ right.push_back(bbox.rightBottom());
+ right.push_back(pos);
+
+ // bottom zone
+ bottom.push_back(pos);
+ bottom.push_back(bbox.rightBottom());
+ bottom.push_back(Vec2f(bottom.back().x, bottom.back().y - PLUS_DETECTION_DISTANCE));
+ bottom.push_back(Vec2f(bottom.back().x - bbox.width(), bottom.back().y));
+ bottom.push_back(bbox.leftBottom());
+ bottom.push_back(pos);
+
+ // top zone
+ top.push_back(pos);
+ top.push_back(bbox.leftTop());
+ top.push_back(Vec2f(top.back().x, top.back().y + PLUS_DETECTION_DISTANCE));
+ top.push_back(Vec2f(top.back().x + bbox.width(), top.back().y));
+ top.push_back(bbox.rightTop());
+ top.push_back(pos);
+ szd.zone_sections.push_back(left);
+ szd.zone_sections.push_back(right);
+ szd.zone_sections.push_back(top);
+ szd.zone_sections.push_back(bottom);
+ _zones.push_back(szd);
+}
+
+void ReactionMultistepDetector::addArrowZones(const Vec2f& tail, const Vec2f& head)
+{
+ float dx = head.x - tail.x, dy = head.y - tail.y;
+ float length = std::hypot(dx, dy), half_length = length * 0.5f;
+ Vec2f dir = {dx, dy};
+ dir.normalize();
+ float inv = 1.0f / length;
+ Vec2f nT = {-dy * inv, dx * inv};
+ Vec2f nB = {dy * inv, -dx * inv};
+
+ Vec2f nTop = nT * half_length;
+ Vec2f nBottom = nB * half_length;
+
+ std::vector top{{head.x, head.y}, {tail.x, tail.y}, {tail.x + nTop.x, tail.y + nTop.y}, {head.x + nTop.x, head.y + nTop.y}};
+ std::vector bottom{{tail.x, tail.y}, {head.x, head.y}, {head.x + nBottom.x, head.y + nBottom.y}, {tail.x + nBottom.x, tail.y + nBottom.y}};
+
+ std::vector left, right;
+ Vec2f pos = tail + nB / 2;
+ left.push_back(pos);
+ pos -= dir * ARROW_DETECTION_DISTANCE;
+ left.push_back(pos);
+ pos += nT;
+ left.push_back(pos);
+ pos += dir * ARROW_DETECTION_DISTANCE;
+ left.push_back(pos);
+ pos += nB;
+ left.push_back(pos);
+
+ pos = head + nT / 2;
+ right.push_back(pos);
+ pos += dir * ARROW_DETECTION_DISTANCE;
+ right.push_back(pos);
+ pos += nB;
+ right.push_back(pos);
+ pos -= dir * ARROW_DETECTION_DISTANCE;
+ right.push_back(pos);
+ pos += nT;
+ right.push_back(pos);
+
+ SPECIAL_ZONE_DESC szd;
+ szd.zone_type = ZoneType::EArrow;
+ szd.zone_sections.push_back(left);
+ szd.zone_sections.push_back(right);
+ szd.zone_sections.push_back(top);
+ szd.zone_sections.push_back(bottom);
+ szd.origin_coordinates.push_back(tail);
+ szd.origin_coordinates.push_back(head);
+ _zones.push_back(szd);
+}
+
+void ReactionMultistepDetector::addPathwayZones(const Vec2f& head, const Vec2f& sp_beg, const Vec2f& sp_end, const std::vector& tails)
+{
+ std::vector right, top, bottom;
+
+ // form products zone
+ Vec2f pos(head);
+ pos.y += LayoutOptions::DEFAULT_BOND_LENGTH / 2.0f;
+ right.push_back(pos);
+ pos.x += ARROW_DETECTION_DISTANCE;
+ right.push_back(pos);
+ pos.y -= LayoutOptions::DEFAULT_BOND_LENGTH;
+ right.push_back(pos);
+ pos.x -= ARROW_DETECTION_DISTANCE;
+ right.push_back(pos);
+ pos.y += LayoutOptions::DEFAULT_BOND_LENGTH;
+ right.push_back(pos);
+
+ // form top agents zone
+ pos = head;
+ top.push_back(pos);
+ pos.x = sp_beg.x;
+ top.push_back(pos);
+ pos.y = sp_beg.y;
+ top.push_back(pos);
+ pos.x = head.x;
+ top.push_back(pos);
+ pos = head;
+ top.push_back(pos);
+ bottom.push_back(pos);
+ pos.y = sp_end.y;
+ bottom.push_back(pos);
+ pos.x = sp_end.x;
+ bottom.push_back(pos);
+ pos.y = head.y;
+ bottom.push_back(pos);
+ bottom.push_back(head);
+ SPECIAL_ZONE_DESC szd;
+ szd.zone_type = ZoneType::EPathWay;
+ szd.zone_sections.push_back(top);
+ szd.zone_sections.push_back(bottom);
+ szd.zone_sections.push_back(right);
+ szd.origin_coordinates.push_back(head);
+ szd.origin_coordinates.push_back(sp_beg);
+ szd.origin_coordinates.push_back(sp_end);
+ for (const auto& tail : tails)
+ {
+ std::vector left;
+ pos = tail;
+ pos.y -= LayoutOptions::DEFAULT_BOND_LENGTH / 2.0f;
+ left.push_back(pos);
+ pos.x -= ARROW_DETECTION_DISTANCE;
+ left.push_back(pos);
+ pos.y += LayoutOptions::DEFAULT_BOND_LENGTH;
+ left.push_back(pos);
+ pos.x += ARROW_DETECTION_DISTANCE;
+ left.push_back(pos);
+ pos.y -= LayoutOptions::DEFAULT_BOND_LENGTH;
+ left.push_back(pos);
+ szd.zone_sections.push_back(left);
+ szd.origin_coordinates.push_back(tail);
+ }
+ _zones.push_back(szd);
+}
+
+std::map> ReactionMultistepDetector::findSpecialZones(size_t mol_idx)
+{
+ auto& hull = _components[mol_idx].hull;
+ std::map> result;
+ for (int i = 0; i < static_cast(_zones.size()); ++i)
+ {
+ auto& zone = _zones[i];
+ std::pair> cur_zone(i, {});
+ for (int j = 0; j < static_cast(zone.zone_sections.size()); ++j)
+ {
+ auto& section = zone.zone_sections[j];
+ if (convexPolygonsIntersect(hull, section))
+ cur_zone.second.insert(j);
+ }
+ if (cur_zone.second.size())
+ result.insert(cur_zone);
+ }
+ return result;
+}
+
+std::optional> ReactionMultistepDetector::findMaxSpecialZone(size_t mol_idx, std::map>& zones)
+{
+ std::optional> result{};
+ float max_containment = 0.0f;
+ auto& hull = _components[mol_idx].hull;
+ for (int i = 0; i < static_cast(_zones.size()); ++i)
+ {
+ auto& zone = _zones[i];
+ for (int j = 0; j < static_cast(zone.zone_sections.size()); ++j)
+ {
+ auto& section = zone.zone_sections[j];
+ float cont = computeConvexContainment(hull, section);
+ if (cont > max_containment)
+ {
+ max_containment = cont;
+ result = {i, j};
+ }
+ if (cont > 0.0f)
+ {
+ auto zone_it = zones.find(i);
+ if (zone_it != zones.end())
+ zone_it->second.insert(j);
+ else
+ zones.insert({i, {j}});
+ }
+ }
+ }
+ return result;
+}
+
+void ReactionMultistepDetector::mergeCloseComponents()
+{
+ for (size_t i = 0; i < _mol_distances.size(); ++i)
+ {
+ auto& mdi = _mol_distances[i];
+ if (mdi.sorted_distances.empty() || !_components[i].mol)
+ continue;
+ std::queue>>> bfs_queue;
+ std::vector cluster;
+ bfs_queue.emplace(i, std::nullopt);
+ cluster.push_back(i);
+ while (!bfs_queue.empty())
+ {
+ auto qel = bfs_queue.front();
+ auto& mdj = _mol_distances[qel.first];
+ bfs_queue.pop();
+ for (auto& sd : mdj.sorted_distances)
+ {
+ auto j = sd.first;
+ if (!_components[j].mol || std::find(cluster.begin(), cluster.end(), j) != cluster.end())
+ continue;
+ auto zone = isMergeable(qel.first, j, qel.second);
+ if (zone.has_value())
+ {
+ cluster.push_back(j);
+ bfs_queue.emplace(j, zone);
+ }
+ }
+ }
+ for (std::size_t k = 1; k < cluster.size(); ++k)
+ {
+ QS_DEF(Array, mapping);
+ if (_components[cluster[k]].mol)
+ {
+ _components[i].mol->mergeWithMolecule(*_components[cluster[k]].mol, &mapping, 0);
+ _components[cluster[k]].idx = (int)i;
+ _components[cluster[k]].mol.reset();
+ }
+ }
+ }
+
+ for (int i = 0; i < _moleculeCount; ++i)
+ {
+ if (_components[i].mol)
+ {
+ _merged_components.emplace_back(std::move(_components[i].mol), _components[i].hull, (int)_merged_components.size());
+ _merged_components.back().mapped_idx = i;
+ _components[i].mapped_idx = (int)_merged_components.size() - 1;
+ }
+ }
+ _moleculeCount = (int)_merged_components.size();
+}
+
+void dumpHull(std::string name, const std::vector& hull)
+{
+ std::cout << name << std::endl;
+ for (auto& v : hull)
+ std::cout << v.x << "," << v.y << std::endl;
+}
+
+std::optional> ReactionMultistepDetector::isMergeable(size_t mol_idx1, size_t mol_idx2, std::optional>& current_zone)
+{
+ auto& mdi = _mol_distances[mol_idx1];
+ auto dist_it = mdi.distances_map.find(mol_idx2);
+ if (dist_it != mdi.distances_map.end() && dist_it->second < LayoutOptions::DEFAULT_BOND_LENGTH * 2)
+ {
+ // collect surrounding zones for both molecules
+ std::map> other_zones1;
+ std::map> other_zones2;
+ std::map> comm_zones;
+
+ auto zone1 = findMaxSpecialZone(mol_idx1, other_zones1);
+ auto zone2 = findMaxSpecialZone(mol_idx2, other_zones2);
+ std::set_intersection(other_zones1.begin(), other_zones1.end(), other_zones2.begin(), other_zones2.end(), std::inserter(comm_zones, comm_zones.begin()),
+ [](auto& a, auto& b) { return a.first < b.first; });
+
+ // no zone - no reason to merge
+ if (zone1.has_value())
+ {
+ // if both molecules has the same zone and section - merge
+ // we never merge molecules with different sections of the same zone
+ if (zone2.has_value())
+ {
+ // disable catalysts merging
+ if ((_zones[zone1.value().first].zone_type == ZoneType::EArrow && zone1.value().second > 1) ||
+ (_zones[zone2.value().first].zone_type == ZoneType::EArrow && zone2.value().second > 1))
+ return std::nullopt;
+
+ // if both molecules are on the same zone - check if they are mergeable
+
+ // check if there are opposite sections
+ for (auto& cz : comm_zones)
+ {
+ auto it_oz2 = other_zones2.find(cz.first);
+ if (it_oz2 != other_zones2.end())
+ {
+ for (auto& section : cz.second)
+ {
+ if ((_zones[cz.first].zone_type == ZoneType::EPathWay && section > 1) || it_oz2->second.count(section ^ 1))
+ return std::nullopt;
+ }
+ }
+ }
+
+ // different zone types are not mergeable
+ if (_zones[zone1.value().first].zone_type != _zones[zone2.value().first].zone_type && comm_zones.empty())
+ return std::nullopt;
+ }
+
+ if (!current_zone.has_value())
+ current_zone = zone1;
+ }
+ else if (!current_zone.has_value())
+ return std::nullopt;
+
+ auto zidx = current_zone.value().first;
+ // if molecules have different zones - check if they are mergeable
+ auto& hull1 = _components[mol_idx1].hull;
+ auto& hull2 = _components[mol_idx2].hull;
+
+ const auto& coords = _zones[zidx].origin_coordinates;
+ // check if both molecules are on the same zone continuation
+ switch (_zones[zidx].zone_type)
+ {
+ case ZoneType::EPlus:
+ if (((current_zone->second == (int)PlusSectionCode::ETop || current_zone->second == (int)PlusSectionCode::EBottom) &&
+ doesVerticalLineIntersectPolygon(coords[0].x, hull1) && doesVerticalLineIntersectPolygon(coords[0].x, hull2)) ||
+ ((current_zone->second == (int)PlusSectionCode::ELeft || current_zone->second == (int)PlusSectionCode::ERight) &&
+ doesHorizontalLineIntersectPolygon(coords[0].y, hull1) && doesHorizontalLineIntersectPolygon(coords[0].y, hull2)))
+ return zone1 ? zone1 : current_zone;
+ break;
+ case ZoneType::EArrow:
+ if ((doesRayIntersectPolygon(coords[0], coords[1], hull1) && doesRayIntersectPolygon(coords[0], coords[1], hull2)) ||
+ (doesRayIntersectPolygon(coords[1], coords[0], hull1) && doesRayIntersectPolygon(coords[1], coords[0], hull2)))
+ {
+ return zone1 ? zone1 : current_zone;
+ }
+ break;
+ case ZoneType::EPathWay: {
+ auto c_it = coords.begin();
+ const Vec2f& head = *c_it++;
+ const Vec2f& spine_beg = *c_it++;
+ const Vec2f& spine_end = *c_it++; // we could skip it because only x is used which is the same as spine_beg
+ Vec2f tail(spine_beg.x, head.y);
+ if (doesRayIntersectPolygon(tail, head, hull1) && doesRayIntersectPolygon(tail, head, hull2))
+ return zone1 ? zone1 : current_zone;
+ for (; c_it != coords.end(); ++c_it)
+ {
+ Vec2f tail_start(spine_end.x, c_it->y);
+ if (doesRayIntersectPolygon(tail_start, *c_it, hull1) && doesRayIntersectPolygon(tail_start, *c_it, hull2))
+ return zone1 ? zone1 : current_zone;
+ }
+ }
+ break;
+ }
+ }
+ return std::nullopt;
+}
+
void ReactionMultistepDetector::sortSummblocks()
{
// Create a list of original indices
@@ -245,8 +669,11 @@ void ReactionMultistepDetector::sortSummblocks()
std::iota(indices.begin(), indices.end(), 0);
// Sort the indices based on reaction_idx
- std::sort(indices.begin(), indices.end(),
- [&](int a, int b) -> bool { return _component_summ_blocks[a].reaction_idx < _component_summ_blocks[b].reaction_idx; });
+ std::stable_sort(indices.begin(), indices.end(), [&](int a, int b) -> bool {
+ auto& csba = _component_summ_blocks[a];
+ auto& csbb = _component_summ_blocks[b];
+ return csba.reaction_idx < csbb.reaction_idx;
+ });
// Create a mapping from old index to new index
std::vector old_to_new(_component_summ_blocks.size());
@@ -256,6 +683,7 @@ void ReactionMultistepDetector::sortSummblocks()
// Sort the blocks based on the sorted indices
std::vector sorted_blocks;
sorted_blocks.reserve(_component_summ_blocks.size());
+
for (auto idx : indices)
sorted_blocks.emplace_back(std::move(_component_summ_blocks[idx]));
_component_summ_blocks = std::move(sorted_blocks);
@@ -271,90 +699,138 @@ void ReactionMultistepDetector::sortSummblocks()
std::for_each(block.arrows_to.begin(), block.arrows_to.end(), update_arrow);
std::for_each(block.arrows_from.begin(), block.arrows_from.end(), update_arrow);
}
+ // Update reaction components with new indices
+ for (auto& rc : _reaction_components)
+ {
+ if (rc.summ_block_idx >= 0 && rc.summ_block_idx < static_cast(old_to_new.size()))
+ rc.summ_block_idx = old_to_new[rc.summ_block_idx];
+ }
}
ReactionMultistepDetector::ReactionType ReactionMultistepDetector::detectReaction()
{
+ createSpecialZones();
+ std::list> s_neighbors;
+ getSGroupAtoms(_bmol, s_neighbors);
+ _moleculeCount = _bmol.countComponents(s_neighbors);
+ for (int i = 0; i < _moleculeCount; ++i)
+ {
+ auto component = extractComponent(i);
+ Rect2f bbox;
+ component->getBoundingBox(bbox, Vec2f(LayoutOptions::DEFAULT_BOND_LENGTH, LayoutOptions::DEFAULT_BOND_LENGTH));
+ // auto hull = component->getConvexHull(Vec2f(LayoutOptions::DEFAULT_BOND_LENGTH, LayoutOptions::DEFAULT_BOND_LENGTH));
+ std::vector hull;
+ hull.push_back(bbox.leftTop());
+ hull.push_back(bbox.leftBottom());
+ hull.push_back(bbox.rightBottom());
+ hull.push_back(bbox.rightTop());
+ hull.push_back(bbox.leftTop());
+ _components.emplace_back(std::move(component), hull, i);
+ }
+
+ collectSortedDistances();
+ mergeCloseComponents();
createSummBlocks();
bool has_multistep = mapReactionComponents();
bool has_multitail = mapMultitailReactionComponents();
sortSummblocks();
+ mergeUndefinedComponents();
return has_multitail ? ReactionType::EPathwayReaction : (has_multistep ? ReactionType ::EMutistepReaction : ReactionType::ESimpleReaction);
}
bool ReactionMultistepDetector::mapReactionComponents()
{
int arrow_count = _bmol.meta().getMetaCount(ReactionArrowObject::CID);
- if (arrow_count == 0)
- return false;
- for (int reaction_index = 0; reaction_index < arrow_count; ++reaction_index)
+ if (arrow_count > 0)
{
- auto& arrow = (const ReactionArrowObject&)_bmol.meta().getMetaObject(ReactionArrowObject::CID, reaction_index);
- int arrow_type = arrow.getArrowType();
- bool reverseReactionOrder = arrow_type == ReactionArrowObject::ERetrosynthetic;
- const Vec2f& arr_begin = !reverseReactionOrder ? arrow.getTail() : arrow.getHead();
- const Vec2f& arr_end = !reverseReactionOrder ? arrow.getHead() : arrow.getTail();
-
- float min_dist_prod = -1, min_dist_reac = -1;
- int idx_cs_min_prod = -1, idx_cs_min_reac = -1;
- for (int index_cs = 0; index_cs < static_cast(_component_summ_blocks.size()); ++index_cs)
+ for (int reaction_index = 0; reaction_index < arrow_count; ++reaction_index)
{
- auto& csb = _component_summ_blocks[index_cs];
- if (csb.bbox.rayIntersectsRect(arr_end, arr_begin))
+ auto& arrow = (const ReactionArrowObject&)_bmol.meta().getMetaObject(ReactionArrowObject::CID, reaction_index);
+ int arrow_type = arrow.getArrowType();
+ bool reverseReactionOrder = arrow_type == ReactionArrowObject::ERetrosynthetic;
+ const Vec2f& arr_begin = !reverseReactionOrder ? arrow.getTail() : arrow.getHead();
+ const Vec2f& arr_end = !reverseReactionOrder ? arrow.getHead() : arrow.getTail();
+
+ float min_dist_prod = -1, min_dist_reac = -1;
+ int idx_cs_min_prod = -1, idx_cs_min_reac = -1;
+ for (int index_cs = 0; index_cs < static_cast(_component_summ_blocks.size()); ++index_cs)
{
- float dist = csb.bbox.pointDistance(arr_end);
- if (min_dist_prod < 0 || dist < min_dist_prod)
+ auto& csb = _component_summ_blocks[index_cs];
+ if (csb.bbox.rayIntersectsRect(arr_end, arr_begin))
{
- min_dist_prod = dist;
- idx_cs_min_prod = index_cs;
+ float dist = csb.bbox.pointDistance(arr_end);
+ if (min_dist_prod < 0 || dist < min_dist_prod)
+ {
+ min_dist_prod = dist;
+ idx_cs_min_prod = index_cs;
+ }
}
- }
- else if (csb.bbox.rayIntersectsRect(arr_begin, arr_end))
- {
- float dist = csb.bbox.pointDistance(arr_begin);
- if (min_dist_reac < 0 || dist < min_dist_reac)
+ else if (csb.bbox.rayIntersectsRect(arr_begin, arr_end))
+ {
+ float dist = csb.bbox.pointDistance(arr_begin);
+ if (min_dist_reac < 0 || dist < min_dist_reac)
+ {
+ min_dist_reac = dist;
+ idx_cs_min_reac = index_cs;
+ }
+ }
+ else
{
- min_dist_reac = dist;
- idx_cs_min_reac = index_cs;
+ for (auto rc_idx : csb.indexes)
+ {
+ auto& rc = _reaction_components[rc_idx];
+ if (rc.component_type == ReactionComponent::MOLECULE)
+ {
+ auto& top_zone = _zones[reaction_index].zone_sections[2];
+ auto& bottom_zone = _zones[reaction_index].zone_sections[3];
+ if (convexPolygonsIntersect(_merged_components[rc_idx].hull, top_zone) ||
+ convexPolygonsIntersect(_merged_components[rc_idx].hull, bottom_zone))
+ csb.role = BaseReaction::CATALYST;
+ }
+ }
}
}
- }
- // TODO: add upper limit
- if (min_dist_prod > 0 && min_dist_reac > 0) // if both ends present
- {
- auto& rc_arrow = _reaction_components[_moleculeCount + _bmol.meta().getMetaCount(ReactionPlusObject::CID) + reaction_index];
- rc_arrow.summ_block_idx = ReactionComponent::CONNECTED; // mark arrow as connected
- auto& csb_min_prod = _component_summ_blocks[idx_cs_min_prod];
- if (csb_min_prod.role == BaseReaction::UNDEFINED)
- csb_min_prod.role = BaseReaction::PRODUCT;
- else if (csb_min_prod.role == BaseReaction::REACTANT)
- csb_min_prod.role = BaseReaction::INTERMEDIATE;
+ // TODO: add upper limit
+ if (min_dist_prod >= 0 || min_dist_reac >= 0) // if both ends present
+ {
+ auto& rc_arrow = _reaction_components[_moleculeCount + _bmol.meta().getMetaCount(ReactionPlusObject::CID) + reaction_index];
+ rc_arrow.summ_block_idx = ReactionComponent::CONNECTED; // mark arrow as connected
+
+ if (min_dist_prod >= 0)
+ {
+ auto& csb_min_prod = _component_summ_blocks[idx_cs_min_prod];
+ if (csb_min_prod.role == BaseReaction::UNDEFINED)
+ csb_min_prod.role = BaseReaction::PRODUCT;
+ else if (csb_min_prod.role == BaseReaction::REACTANT)
+ csb_min_prod.role = BaseReaction::INTERMEDIATE;
+ if (min_dist_reac >= 0)
+ csb_min_prod.arrows_from.push_back(idx_cs_min_reac);
+ csb_min_prod.reaction_idx = reaction_index;
+ }
- auto& csb_min_reac = _component_summ_blocks[idx_cs_min_reac];
- if (csb_min_reac.role == BaseReaction::UNDEFINED)
- csb_min_reac.role = BaseReaction::REACTANT;
- else if (csb_min_reac.role == BaseReaction::PRODUCT)
- csb_min_reac.role = BaseReaction::INTERMEDIATE;
-
- // idx_cs_min_reac <-> idx_cs_min_prod
- csb_min_reac.arrows_to.push_back(idx_cs_min_prod);
- csb_min_prod.arrows_from.push_back(idx_cs_min_reac);
- // csb_min_reac.reaction_idx = reaction_index;
- csb_min_prod.reaction_idx = reaction_index;
+ if (min_dist_reac >= 0)
+ {
+ auto& csb_min_reac = _component_summ_blocks[idx_cs_min_reac];
+ if (csb_min_reac.role == BaseReaction::UNDEFINED)
+ csb_min_reac.role = BaseReaction::REACTANT;
+ else if (csb_min_reac.role == BaseReaction::PRODUCT)
+ csb_min_reac.role = BaseReaction::INTERMEDIATE;
+ if (min_dist_prod >= 0)
+ csb_min_reac.arrows_to.push_back(idx_cs_min_prod);
+ }
+ }
}
+ return arrow_count > 1;
}
- return arrow_count > 1;
+ return false;
}
bool ReactionMultistepDetector::mapMultitailReactionComponents()
{
int pathway_count = _bmol.meta().getMetaCount(ReactionMultitailArrowObject::CID);
- if (pathway_count == 0)
- return false;
-
- bool bad_pathway = false;
+ bool bad_pathway = pathway_count == 0;
for (int pathway_idx = 0; pathway_idx < pathway_count; ++pathway_idx)
{
@@ -373,7 +849,7 @@ bool ReactionMultistepDetector::mapMultitailReactionComponents()
auto& csb = _component_summ_blocks[index_cs];
if (csb.bbox.rayIntersectsRect(arr_begin, arr_end))
{
- float dist = csb.bbox.pointDistance(arr_end);
+ float dist = (csb.bbox.center() - arr_end).length();
if (min_dist_prod < 0 || dist < min_dist_prod)
{
min_dist_prod = dist;
@@ -389,7 +865,7 @@ bool ReactionMultistepDetector::mapMultitailReactionComponents()
if (csb.bbox.rayIntersectsRect(arr_end, arr_begin))
{
- auto dist = csb.bbox.pointDistance(arr_begin);
+ auto dist = (csb.bbox.center() - arr_begin).length();
if (min_dist_reactants[j].first < 0 || dist < min_dist_reactants[j].first)
{
min_dist_reactants[j].first = dist;
@@ -420,7 +896,7 @@ bool ReactionMultistepDetector::mapMultitailReactionComponents()
for (int j = 0; j < (int)min_dist_reactants.size(); ++j)
{
auto& reac = min_dist_reactants[j];
- if (reac.first > 0)
+ if (reac.first >= 0)
{
auto& csb_min_reac = _component_summ_blocks[reac.second];
if (csb_min_reac.role == BaseReaction::UNDEFINED)
@@ -435,41 +911,164 @@ bool ReactionMultistepDetector::mapMultitailReactionComponents()
csb_min_reac.arrows_to.push_back(idx_cs_min_prod);
_component_summ_blocks[idx_cs_min_prod].arrows_from.push_back(reac.second);
}
- // csb_min_reac.reaction_idx = pathway_idx + _bmol.meta().getMetaCount(ReactionArrowObject::CID);
}
else
bad_pathway = true;
}
}
- for (auto& csb : _component_summ_blocks)
+ return !bad_pathway;
+}
+
+// bool ReactionMultistepDetector::mergeUndefinedComponents()
+//{
+// bool result = true; // true means - no more undefined components
+// for (auto& csb : _component_summ_blocks)
+// {
+// // no undefined components allowed
+// if (csb.role == BaseReaction::UNDEFINED)
+// {
+// // consists of only one component
+// if (csb.indexes.size() == 1)
+// {
+// int mol_idx = csb.indexes.front();
+// int mol_orig_idx = _merged_components[mol_idx].mapped_idx;
+// auto& mdi = _mol_distances[mol_orig_idx];
+// // if there are any close components
+// if (mdi.sorted_distances.size())
+// {
+// // if not merged
+// auto closest_idx = mdi.sorted_distances.front().first;
+// if (_components[closest_idx].idx != _components[mol_orig_idx].idx)
+// {
+// auto mol_idx_target = _components[_components[closest_idx].idx].mapped_idx;
+// // merge mol_idx into mol_idx_target
+// _reaction_components[mol_idx_target].molecule->mergeWithMolecule(*_reaction_components[mol_idx].molecule, nullptr, 0);
+// _reaction_components[mol_idx].molecule.reset();
+// // mark the component as merged
+// _components[mol_orig_idx].idx = _components[closest_idx].idx;
+// csb.indexes.clear();
+// }
+// else
+// result = false;
+// }
+// else
+// result = false;
+// }
+// else
+// result = false;
+// }
+// }
+// return result;
+// }
+
+bool ReactionMultistepDetector::mergeUndefinedComponents()
+{
+ bool result = true;
+
+ for (size_t i = 0; i < _reaction_components.size(); ++i)
{
- // no undefined components allowed
- if (csb.role == BaseReaction::UNDEFINED)
+ std::vector cluster, agg_candidates;
+ std::vector visited(_reaction_components.size(), false);
+
+ auto& rc = _reaction_components[i];
+ if (!visited[i] && rc.component_type == ReactionComponent::MOLECULE)
{
- csb.role = BaseReaction::REACTANT;
- bad_pathway = true;
+ auto& csb = _component_summ_blocks[rc.summ_block_idx];
+ if (csb.role == BaseReaction::UNDEFINED && !csb.indexes.empty())
+ {
+ std::queue q;
+ q.push(i);
+ visited[i] = true;
+
+ // trying to build an undefined cluster
+ while (!q.empty())
+ {
+ size_t current = q.front();
+ q.pop();
+ cluster.push_back(current);
+
+ auto& currentCsb = _component_summ_blocks[_reaction_components[current].summ_block_idx];
+ if (!currentCsb.indexes.empty())
+ {
+ int molIdx = currentCsb.indexes.front();
+ int origIdx = _merged_components[molIdx].mapped_idx;
+ for (const auto& [compIdx, dist] : _mol_distances[origIdx].sorted_distances)
+ {
+ int neighborRcIdx = _components[compIdx].mapped_idx;
+ if (neighborRcIdx < 0 || neighborRcIdx == static_cast(current) || visited[neighborRcIdx])
+ continue;
+
+ auto& neighborCsb = _component_summ_blocks[_reaction_components[neighborRcIdx].summ_block_idx];
+ if (neighborCsb.role == BaseReaction::UNDEFINED)
+ {
+ q.push(neighborRcIdx);
+ visited[neighborRcIdx] = true;
+ }
+ else if (neighborCsb.role != BaseReaction::CATALYST)
+ {
+ agg_candidates.push_back(neighborRcIdx);
+ visited[neighborRcIdx] = true;
+ }
+ }
+ }
+ }
+ if (agg_candidates.size())
+ {
+ for (size_t undefIdx : cluster)
+ {
+ int mol_orig_idx = _merged_components[undefIdx].mapped_idx;
+ int closest_idx = -1;
+ float min_dist = 0;
+ for (size_t aggIdx : agg_candidates)
+ {
+ auto agg_orig_idx = _merged_components[aggIdx].mapped_idx;
+ auto dist = _mol_distances[mol_orig_idx].distances_map[agg_orig_idx];
+ if (closest_idx < 0 || dist < min_dist)
+ {
+ closest_idx = (int)agg_orig_idx;
+ min_dist = dist;
+ }
+ }
+ if (_components[closest_idx].idx != _components[mol_orig_idx].idx)
+ {
+ auto mol_idx_target = _components[_components[closest_idx].idx].mapped_idx;
+ // merge mol_idx into mol_idx_target
+ if (_reaction_components[undefIdx].molecule)
+ {
+ _reaction_components[mol_idx_target].molecule->mergeWithMolecule(*_reaction_components[undefIdx].molecule, nullptr, 0);
+ _reaction_components[undefIdx].molecule.reset();
+ // mark the component as merged
+ _components[mol_orig_idx].idx = _components[closest_idx].idx;
+ csb.indexes.clear();
+ }
+ }
+ }
+ }
+ }
}
}
- return !bad_pathway;
+ return result;
}
bool ReactionMultistepDetector::findPlusNeighbours(const Vec2f& plus_pos, const FLOAT_INT_PAIRS& mol_tops, const FLOAT_INT_PAIRS& mol_bottoms,
const FLOAT_INT_PAIRS& mol_lefts, const FLOAT_INT_PAIRS& mol_rights, std::pair& connection)
{
- auto plus_pos_y = std::make_pair(plus_pos.y, 0);
- auto plus_pos_x = std::make_pair(plus_pos.x, 0);
+ auto plus_pos_right = std::make_pair(plus_pos.x + PLUS_BBOX_SHIFT.x, -1);
+ auto plus_pos_left = std::make_pair(plus_pos.x - PLUS_BBOX_SHIFT.x, -1);
+ auto plus_pos_top = std::make_pair(plus_pos.y + PLUS_BBOX_SHIFT.y, -1);
+ auto plus_pos_bottom = std::make_pair(plus_pos.y - PLUS_BBOX_SHIFT.y, -1);
auto pair_comp_asc = [](const FLOAT_INT_PAIR& a, const FLOAT_INT_PAIR& b) { return b.first > a.first; };
auto pair_comp_des = [](const FLOAT_INT_PAIR& a, const FLOAT_INT_PAIR& b) { return b.first < a.first; };
auto pair_comp_mol_asc = [](const FLOAT_INT_PAIR& a, const FLOAT_INT_PAIR& b) { return b.second > a.second; };
- // look for mols where top > y
- auto tops_above_it = std::upper_bound(mol_tops.begin(), mol_tops.end(), plus_pos_y, pair_comp_asc);
- // look for mols where bottom < y
- auto bottoms_below_it = std::upper_bound(mol_bottoms.begin(), mol_bottoms.end(), plus_pos_y, pair_comp_des);
- // look for mols where right > x
- auto rights_after_it = std::upper_bound(mol_rights.begin(), mol_rights.end(), plus_pos_x, pair_comp_asc);
- // look for mols where left < x
- auto lefts_before_it = std::upper_bound(mol_lefts.begin(), mol_lefts.end(), plus_pos_x, pair_comp_des);
+ // look for mols where top > plus_pos_bottom
+ auto tops_above_it = std::upper_bound(mol_tops.begin(), mol_tops.end(), plus_pos_bottom, pair_comp_asc);
+ // look for mols where bottom < plus_pos_top
+ auto bottoms_below_it = std::upper_bound(mol_bottoms.begin(), mol_bottoms.end(), plus_pos_top, pair_comp_des);
+ // look for mols where right > plus_pos_left
+ auto rights_after_it = std::upper_bound(mol_rights.begin(), mol_rights.end(), plus_pos_left, pair_comp_asc);
+ // look for mols where left < plus_pos_right
+ auto lefts_before_it = std::upper_bound(mol_lefts.begin(), mol_lefts.end(), plus_pos_right, pair_comp_des);
FLOAT_INT_PAIRS tops_above, bottoms_below, lefts_before, rights_after;
@@ -496,48 +1095,56 @@ bool ReactionMultistepDetector::findPlusNeighbours(const Vec2f& plus_pos, const
for (const auto& kvp : intersection_top_bottom)
{
auto& tb_box = _reaction_components[kvp.second].bbox;
- if (tb_box.pointInRect(plus_pos))
- continue;
- rights_row.emplace_back(tb_box.right(), kvp.second);
- lefts_row.emplace_back(tb_box.left(), kvp.second);
+ auto dir = tb_box.center() - plus_pos;
+ if (_reaction_components[kvp.second].component_type == ReactionComponent::MOLECULE && std::fabs(dir.x) > std::fabs(dir.y))
+ {
+ rights_row.emplace_back(tb_box.right(), kvp.second);
+ lefts_row.emplace_back(tb_box.left(), kvp.second);
+ }
}
// collect top-bottom
for (const auto& kvp : intersection_left_right)
{
auto& lr_box = _reaction_components[kvp.second].bbox;
- if (lr_box.pointInRect(plus_pos))
- continue;
- tops_col.emplace_back(lr_box.top(), kvp.second);
- bottoms_col.emplace_back(lr_box.bottom(), kvp.second);
+ auto dir = lr_box.center() - plus_pos;
+ if (_reaction_components[kvp.second].component_type == ReactionComponent::MOLECULE && std::fabs(dir.x) < std::fabs(dir.y))
+ {
+ tops_col.emplace_back(lr_box.top(), kvp.second);
+ bottoms_col.emplace_back(lr_box.bottom(), kvp.second);
+ }
}
+ // sort to find the closest to the plus
std::sort(lefts_row.begin(), lefts_row.end(), pair_comp_asc);
std::sort(rights_row.begin(), rights_row.end(), pair_comp_des);
std::sort(tops_col.begin(), tops_col.end(), pair_comp_asc);
std::sort(bottoms_col.begin(), bottoms_col.end(), pair_comp_des);
- auto rights_row_it = std::upper_bound(rights_row.begin(), rights_row.end(), plus_pos_x, pair_comp_des);
- auto lefts_row_it = std::upper_bound(lefts_row.begin(), lefts_row.end(), plus_pos_x, pair_comp_asc);
- auto tops_col_it = std::upper_bound(tops_col.begin(), tops_col.end(), plus_pos_y, pair_comp_asc);
- auto bottoms_col_it = std::upper_bound(bottoms_col.begin(), bottoms_col.end(), plus_pos_y, pair_comp_des);
+ auto rights_row_it = std::upper_bound(rights_row.begin(), rights_row.end(), plus_pos_right, pair_comp_des);
+ auto lefts_row_it = std::upper_bound(lefts_row.begin(), lefts_row.end(), plus_pos_left, pair_comp_asc);
+
+ auto tops_col_it = std::upper_bound(tops_col.begin(), tops_col.end(), plus_pos_top, pair_comp_asc);
+ auto bottoms_col_it = std::upper_bound(bottoms_col.begin(), bottoms_col.end(), plus_pos_bottom, pair_comp_des);
float min_distance_h = 0, min_distance_v = 0;
bool result = false;
- if (rights_row_it != rights_row.end() && lefts_row_it != lefts_row.end())
+ if (rights_row_it != rights_row.end() && lefts_row_it != lefts_row.end() && lefts_row_it->second != rights_row_it->second)
{
- min_distance_h = std::min(std::fabs(rights_row_it->first - plus_pos_x.first), std::fabs(plus_pos_x.first - lefts_row_it->first));
+ // TODO: distances limit?
+ min_distance_h = std::min(std::fabs(rights_row_it->first - plus_pos_right.first), std::fabs(plus_pos_left.first - lefts_row_it->first));
connection.second = lefts_row_it->second;
connection.first = rights_row_it->second;
result = _reaction_components[connection.first].component_type == ReactionComponent::MOLECULE &&
_reaction_components[connection.second].component_type == ReactionComponent::MOLECULE;
}
- if (tops_col_it != tops_col.end() && bottoms_col_it != bottoms_col.end())
+ if (tops_col_it != tops_col.end() && bottoms_col_it != bottoms_col.end() && tops_col_it->second != bottoms_col_it->second)
{
- min_distance_v = std::min(std::fabs(tops_col_it->first - plus_pos_y.first), std::fabs(bottoms_col_it->first - plus_pos_y.first));
+ // TODO: distances limit?
+ min_distance_v = std::min(std::fabs(tops_col_it->first - plus_pos_top.first), std::fabs(bottoms_col_it->first - plus_pos_bottom.first));
if (!result || min_distance_v < min_distance_h)
{
connection.first = tops_col_it->second;
@@ -757,7 +1364,8 @@ void ReactionMultistepDetector::constructMultipleArrowReaction(BaseReaction& rxn
for (auto idx : csb.indexes)
{
auto& rc = _reaction_components[idx];
- if (!copied_components.count(idx))
+ if (rc.molecule && !copied_components.count(idx))
+ {
switch (csb.role)
{
case BaseReaction::INTERMEDIATE:
@@ -772,9 +1380,13 @@ void ReactionMultistepDetector::constructMultipleArrowReaction(BaseReaction& rxn
case BaseReaction::UNDEFINED:
copied_components.emplace(idx, rxn.addUndefinedCopy(*rc.molecule, 0, 0));
break;
+ case BaseReaction::CATALYST:
+ copied_components.emplace(idx, rxn.addCatalystCopy(*rc.molecule, 0, 0));
+ break;
default:
break;
}
+ }
}
}
@@ -804,46 +1416,251 @@ void ReactionMultistepDetector::constructMultipleArrowReaction(BaseReaction& rxn
}
}
+uint8_t ReactionMultistepDetector::geMoleculeSide(BaseReaction& rxn, BaseMolecule& mol)
+{
+ auto& arrow = (const ReactionArrowObject&)rxn.meta().getMetaObject(ReactionArrowObject::CID, 0);
+ bool reverseReactionOrder = arrow.getArrowType() == ReactionArrowObject::ERetrosynthetic;
+ std::array sides{};
+ for (int idx = mol.vertexBegin(); idx < mol.vertexEnd(); idx = mol.vertexNext(idx))
+ {
+ Vec3f& pt3d = mol.getAtomXyz(idx);
+ Vec2f pt(pt3d.x, pt3d.y);
+ int side = !reverseReactionOrder ? getPointSide(pt, arrow.getTail(), arrow.getHead()) : getPointSide(pt, arrow.getHead(), arrow.getTail());
+ sides[side]++;
+ }
+ return (uint8_t)std::distance(sides.begin(), std::max_element(sides.begin(), sides.end()));
+}
+
+uint8_t ReactionMultistepDetector::geMoleculeSide(BaseReaction& rxn, BaseMolecule& mol, std::array& sides)
+{
+ auto& arrow = (const ReactionArrowObject&)rxn.meta().getMetaObject(ReactionArrowObject::CID, 0);
+ bool reverseReactionOrder = arrow.getArrowType() == ReactionArrowObject::ERetrosynthetic;
+ for (int idx = mol.vertexBegin(); idx < mol.vertexEnd(); idx = mol.vertexNext(idx))
+ {
+ Vec3f& pt3d = mol.getAtomXyz(idx);
+ Vec2f pt(pt3d.x, pt3d.y);
+ int side = !reverseReactionOrder ? getPointSide(pt, arrow.getTail(), arrow.getHead()) : getPointSide(pt, arrow.getHead(), arrow.getTail());
+ sides[side]++;
+ }
+ return (uint8_t)std::distance(sides.begin(), std::max_element(sides.begin(), sides.end()));
+}
+
void ReactionMultistepDetector::constructSimpleArrowReaction(BaseReaction& rxn)
{
- for (auto& csb : _component_summ_blocks)
+ enum RecordIndexes
{
- switch (csb.role)
+ BBOX_IDX = 0,
+ FRAGMENT_TYPE_IDX,
+ MOLECULE_IDX
+ };
+
+ if (rxn.meta().getMetaCount(ReactionArrowObject::CID))
+ {
+ auto& arrow = (const ReactionArrowObject&)rxn.meta().getMetaObject(ReactionArrowObject::CID, 0);
+ bool reverseReactionOrder = arrow.getArrowType() == ReactionArrowObject::ERetrosynthetic;
+
+ if (reverseReactionOrder)
+ rxn.setIsRetrosyntetic();
+
+ for (int i = 0; i < rxn.meta().getMetaCount(SimpleTextObject::CID); ++i)
{
- case BaseReaction::PRODUCT: {
- for (auto idx : csb.indexes)
- {
- auto& rc = _reaction_components[idx];
- rxn.addProductCopy(*rc.molecule, 0, 0);
- }
+ auto& text = (const SimpleTextObject&)rxn.meta().getMetaObject(SimpleTextObject::CID, i);
+ Rect2f bbox(Vec2f(text._pos.x, text._pos.y), Vec2f(text._pos.x, text._pos.y)); // change to real text box later
+ _reaction_components.emplace_back(ReactionComponent::TEXT, bbox, i, nullptr);
}
- break;
- case BaseReaction::REACTANT: {
- for (auto idx : csb.indexes)
+
+ int text_meta_idx = 0;
+
+ std::vector> undefined_components;
+ std::vector> product_components, reactant_components;
+
+ for (auto& csb : _component_summ_blocks)
+ {
+ switch (csb.role)
{
- auto& rc = _reaction_components[idx];
- rxn.addReactantCopy(*rc.molecule, 0, 0);
+ case BaseReaction::PRODUCT: {
+ for (auto idx : csb.indexes)
+ {
+ auto& rc = _reaction_components[idx];
+ product_components.emplace_back(idx, rxn.addProductCopy(*rc.molecule, 0, 0));
+ }
+ }
+ break;
+ case BaseReaction::REACTANT: {
+ for (auto idx : csb.indexes)
+ {
+ auto& rc = _reaction_components[idx];
+ reactant_components.emplace_back(idx, rxn.addReactantCopy(*rc.molecule, 0, 0));
+ }
+ }
+ break;
+ // simple reaction does not have intermediates
+ case BaseReaction::INTERMEDIATE: {
+ for (auto idx : csb.indexes)
+ {
+ auto& rc = _reaction_components[idx];
+ rxn.addIntermediateCopy(*rc.molecule, 0, 0);
+ }
+ }
+ break;
+ case BaseReaction::CATALYST: {
+ for (auto idx : csb.indexes)
+ {
+ auto& rc = _reaction_components[idx];
+ rxn.addCatalystCopy(*rc.molecule, 0, 0);
+ }
+ }
+ break;
+ // undefined components are not allowed
+ case BaseReaction::UNDEFINED: {
+ for (auto idx : csb.indexes)
+ {
+ auto& rc = _reaction_components[idx];
+ if (rc.molecule)
+ {
+ rxn.addUndefinedCopy(*rc.molecule, 0, 0);
+ // std::array sides{};
+ // auto side = geMoleculeSide(rxn, *rc.molecule, sides);
+ // if (sides[KReagentUpArea] || sides[KReagentDownArea])
+ // rxn.addCatalystCopy(*rc.molecule, 0, 0);
+ // else
+ // undefined_components.emplace_back(idx, side);
+ }
+ }
+ }
+ break;
+ default:
+ break;
}
}
- break;
- case BaseReaction::INTERMEDIATE: {
- for (auto idx : csb.indexes)
+
+ // map undefined components
+ // for (auto [idx, side] : undefined_components)
+ //{
+ // auto& rc = _reaction_components[idx];
+ // auto& cmol = *rc.molecule;
+
+ // int comp_idx = _merged_components[idx].mapped_idx;
+
+ // switch (side)
+ // {
+ // case KReactantArea:
+ // if (reactant_components.size())
+ // {
+ // int min_idx = -1;
+ // float min_dist = 0;
+ // for (auto [rc_idx, mol_idx] : reactant_components)
+ // {
+ // auto rcm_idx = _merged_components[rc_idx].mapped_idx;
+ // if (rcm_idx > -1)
+ // {
+ // auto& dm = _mol_distances[comp_idx].distances_map;
+ // auto it = dm.find(rcm_idx);
+ // if (it != dm.end() && (min_idx < 0 || it->second < min_dist))
+ // {
+ // min_idx = mol_idx;
+ // min_dist = it->second;
+ // }
+ // }
+ // }
+ // rxn.getBaseMolecule(min_idx).mergeWithMolecule(*rc.molecule, nullptr, 0);
+ // }
+ // else
+ // rxn.addReactantCopy(*rc.molecule, 0, 0);
+ // break;
+ // case KProductArea:
+ // if (product_components.size())
+ // {
+ // int min_idx = -1;
+ // float min_dist = 0;
+ // for (auto [pc_idx, mol_idx] : product_components)
+ // {
+ // auto pcm_idx = _merged_components[pc_idx].mapped_idx;
+ // if (pcm_idx > -1)
+ // {
+ // auto& dm = _mol_distances[comp_idx].distances_map;
+ // auto it = dm.find(pcm_idx);
+ // if (it != dm.end() && (min_idx < 0 || it->second < min_dist))
+ // {
+ // min_idx = mol_idx;
+ // min_dist = it->second;
+ // }
+ // }
+ // }
+ // rxn.getBaseMolecule(min_idx).mergeWithMolecule(*rc.molecule, nullptr, 0);
+ // }
+ // else
+ // rxn.addProductCopy(*rc.molecule, 0, 0);
+ // break;
+ // }
+ //}
+
+ for (const auto& comp : _reaction_components)
+ {
+ switch (comp.component_type)
{
- auto& rc = _reaction_components[idx];
- rxn.addIntermediateCopy(*rc.molecule, 0, 0);
+ case ReactionComponent::TEXT: {
+ const auto& bbox = comp.bbox;
+ Vec2f pt(bbox.center());
+ int side = !reverseReactionOrder ? getPointSide(pt, arrow.getTail(), arrow.getHead()) : getPointSide(pt, arrow.getHead(), arrow.getTail());
+ if (side == KReagentUpArea || side == KReagentDownArea)
+ {
+ rxn.addSpecialCondition(text_meta_idx, bbox);
+ break;
+ }
+ text_meta_idx++;
+ }
+ break;
+ default:
+ break;
}
}
- break;
- case BaseReaction::UNDEFINED: {
- for (auto idx : csb.indexes)
+ }
+ else
+ for (auto& csb : _component_summ_blocks)
+ {
+ switch (csb.role)
{
- auto& rc = _reaction_components[idx];
- rxn.addUndefinedCopy(*rc.molecule, 0, 0);
+ case BaseReaction::PRODUCT: {
+ for (auto idx : csb.indexes)
+ {
+ auto& rc = _reaction_components[idx];
+ rxn.addProductCopy(*rc.molecule, 0, 0);
+ }
}
- }
- break;
- default:
break;
+ case BaseReaction::REACTANT: {
+ for (auto idx : csb.indexes)
+ {
+ auto& rc = _reaction_components[idx];
+ rxn.addReactantCopy(*rc.molecule, 0, 0);
+ }
+ }
+ break;
+ case BaseReaction::INTERMEDIATE: {
+ for (auto idx : csb.indexes)
+ {
+ auto& rc = _reaction_components[idx];
+ rxn.addIntermediateCopy(*rc.molecule, 0, 0);
+ }
+ }
+ break;
+ case BaseReaction::CATALYST: {
+ for (auto idx : csb.indexes)
+ {
+ auto& rc = _reaction_components[idx];
+ rxn.addCatalystCopy(*rc.molecule, 0, 0);
+ }
+ }
+ break;
+ case BaseReaction::UNDEFINED: {
+ for (auto idx : csb.indexes)
+ {
+ auto& rc = _reaction_components[idx];
+ if (rc.molecule)
+ rxn.addUndefinedCopy(*rc.molecule, 0, 0);
+ }
+ }
+ }
}
- }
-}
\ No newline at end of file
+}
diff --git a/utils/indigo-depict/main.c b/utils/indigo-depict/main.c
index 74f0c58b84..bc0b64e516 100644
--- a/utils/indigo-depict/main.c
+++ b/utils/indigo-depict/main.c
@@ -867,8 +867,9 @@ int main(int argc, char* argv[])
indigoSetOption("ignore-stereochemistry-errors", "on");
indigoSetOption("ignore-bad-valence", "on");
- indigoSetOption("molfile-saving-mode", "3000");
+ indigoSetOption("molfile-saving-mode", "2000");
indigoSetOptionBool("json-saving-pretty", "on");
+ indigoSetOptionFloat("reaction-component-margin-size", 0.0f);
if (parseParams(&p, argc, argv) < 0)
return -1;