public createAntisenseChain()

in packages/ketcher-core/src/domain/entities/DrawingEntitiesManager.ts [2849:3005]


  public createAntisenseChain() {
    const editor = CoreEditor.provideEditorInstance();
    const command = new Command();
    const selectedMonomers = this.selectedEntities
      .filter(([, drawingEntity]) => drawingEntity instanceof BaseMonomer)
      .map(([, monomer]) => monomer as BaseMonomer);
    const chainsCollection = ChainsCollection.fromMonomers(selectedMonomers);
    const chainsForAntisenseCreation = chainsCollection.chains.filter(
      (chain) => {
        return chain.subChains.some((subChain) =>
          subChain.nodes.some(
            (node) =>
              (node instanceof Nucleotide || node instanceof Nucleoside) &&
              Boolean(this.getAntisenseBaseLabel(node.rnaBase)) &&
              node.monomer.selected,
          ),
        );
      },
    );
    const selectedPiecesInChains: SubChainNode[][] = [];

    chainsForAntisenseCreation.forEach((chain) => {
      let selectedPiece: SubChainNode[] = [];
      let hasRnaInPiece = false;

      chain.nodes.forEach((node) => {
        const hasSelectedMonomerInNode = node.monomers.some(
          (monomer) => monomer.selected,
        );

        if (!hasSelectedMonomerInNode) {
          if (hasRnaInPiece) {
            selectedPiecesInChains.push(selectedPiece);
          }
          selectedPiece = [];
          hasRnaInPiece = false;
        } else {
          selectedPiece.push(node);
        }

        if (node instanceof Nucleoside || node instanceof Nucleotide) {
          hasRnaInPiece = true;
        }
      });

      if (hasRnaInPiece) {
        selectedPiecesInChains.push(selectedPiece);
      }

      selectedPiece = [];
      hasRnaInPiece = false;
    });

    let lastAddedNode;
    let lastAddedMonomer;

    selectedPiecesInChains.forEach((selectedPiece) => {
      selectedPiece.forEach((node) => {
        if (!node.monomer.selected) {
          lastAddedMonomer = undefined;
          lastAddedNode = undefined;

          return;
        }

        if (node instanceof Nucleotide || node instanceof Nucleoside) {
          const antisenseBaseLabel = this.getAntisenseBaseLabel(node.rnaBase);

          if (!antisenseBaseLabel) {
            return;
          }

          const { modelChanges: addNucleotideCommand, node: addedNode } = (
            node instanceof Nucleotide && node.phosphate.selected
              ? Nucleotide
              : Nucleoside
          ).createOnCanvas(
            antisenseBaseLabel,
            node.monomer.position.add(new Vec2(0, 3)),
            RNA_DNA_NON_MODIFIED_PART.SUGAR_RNA,
          );

          command.merge(addNucleotideCommand);

          if (lastAddedNode) {
            command.merge(
              this.createPolymerBond(
                lastAddedMonomer || lastAddedNode.lastMonomerInNode,
                addedNode.firstMonomerInNode,
                AttachmentPointName.R2,
                AttachmentPointName.R1,
              ),
            );
          }

          command.merge(
            this.createPolymerBond(
              node.rnaBase,
              addedNode.rnaBase,
              AttachmentPointName.HYDROGEN,
              AttachmentPointName.HYDROGEN,
              MACROMOLECULES_BOND_TYPES.HYDROGEN,
            ),
          );

          lastAddedMonomer = null;
          lastAddedNode = addedNode;
        } else {
          lastAddedMonomer =
            lastAddedMonomer || lastAddedNode?.lastMonomerInNode;

          node.monomers.forEach((monomer) => {
            if (!monomer.selected) {
              lastAddedMonomer = undefined;
              lastAddedNode = undefined;

              return;
            }

            const monomerAddCommand = this.addMonomer(
              monomer.monomerItem,
              monomer.position.add(new Vec2(0, 4.25)),
            );
            const addedMonomer = monomerAddCommand.operations[0]
              .monomer as BaseMonomer;

            command.merge(monomerAddCommand);

            if (lastAddedMonomer) {
              command.merge(
                this.createPolymerBond(
                  lastAddedMonomer,
                  addedMonomer,
                  AttachmentPointName.R2,
                  AttachmentPointName.R1,
                ),
              );
            }

            lastAddedMonomer = addedMonomer;
          });

          lastAddedNode = node;
        }
      });
      lastAddedNode = undefined;
      lastAddedMonomer = undefined;
    });

    command.merge(
      this.applySnakeLayout(editor.canvas.width.baseVal.value, true, true),
    );

    command.setUndoOperationsByPriority();

    return command;
  }