// File: /workspace/github_cpp_makefile_star2_O3/Luthaf[P]zeopp/networkstorage.cc
// Function: check_for_collision(ATOM_NETWORK*, std::vector<MOLECULE, std::allocator<MOLECULE>>*, std::vector<CONNECTION, std::allocator<CONNECTION>>*)
bool check_for_collision(ATOM_NETWORK *framework, vector<MOLECULE> *assembled_molecules, vector<CONNECTION> *two_way_connections) {
  bool verbose = false;
if(verbose) printf("DEBUG: checking for collisions...\n");
  XYZ centre_abc(0.5,0.5,0.5);
  XYZ centre_xyz = framework->abc_to_xyz_returning_XYZ(centre_abc);
  bool collision = false;
  int num_assembled_molecules = assembled_molecules->size();
  int num_c = two_way_connections->size();
  //is it possible to have more than one periodic bond between atoms? depends on unit cell - we need to check all x,y,z in the range -1 to 1, except for redundant combinations, handled below
  bool multiple_periodic_connections_possible = false;
  for(int z=-1; z<2 && !multiple_periodic_connections_possible; z++) {
    for(int y=-1; y<2 && !multiple_periodic_connections_possible; y++) {
      for(int x=0; x<2 && !multiple_periodic_connections_possible; x++) { //x cannot be -1
        if((x==0 && y==0 && z==1) || (x==0 && y==1) || (x==1)) {
          XYZ image_abc(x,y,z);
          double self_distance = framework->abc_to_xyz_returning_XYZ(image_abc).magnitude();
          if(self_distance<=GENERAL_BOND_DISTANCE*2.0) multiple_periodic_connections_possible = true;
        }
      }
    }
  }

  //new and much faster system - build a set of vectors storing the info we need and just query it according to the basic collision rules - and don't include sites or H atoms
  vector <int> atom_molecule_id_vector;
  vector <int> atom_position_id_vector;
  vector <XYZ> atom_abc_vector;
  vector <bool> atom_is_close_to_site_vector;
/*
int debug1=198, debug2=730;
*/
  for(int i=0; i<num_assembled_molecules; i++) { //for each molecule
    int num_at_i = assembled_molecules->at(i).atoms_xyz.size();
    int num_sites_i = assembled_molecules->at(i).sites.size();
    int num_dummy_sites_i = assembled_molecules->at(i).dummy_sites.size();
    vector <XYZ> local_atom_abc_vector;
    vector <XYZ> local_site_abc_vector;
    for(int j=0; j<num_at_i; j++) { //for each atom
      if(assembled_molecules->at(i).atoms_type.at(j)!="H") { //if not H
        XYZ xyz_j = assembled_molecules->at(i).atoms_xyz.at(j);
        XYZ abc_j = framework->xyz_to_abc_returning_XYZ(xyz_j);
        bool is_site_j = false;
        bool is_dummy_site_j = false;
        for(int s=0; s<num_sites_i && !is_site_j; s++) { //find if site
          is_site_j = (j == assembled_molecules->at(i).sites.at(s));
        }
        for(int s=0; s<num_dummy_sites_i && !is_dummy_site_j && !is_site_j; s++) { //find if dummy site
          is_dummy_site_j = (j == assembled_molecules->at(i).dummy_sites.at(s));
        }
        if(is_site_j) {
          local_site_abc_vector.push_back(abc_j);
        } else if(is_dummy_site_j) { //do nothing - don't want to write this one out, and don't want to bypass collision detection near to dummy sites
        } else {
          local_atom_abc_vector.push_back(abc_j);
          atom_abc_vector.push_back(abc_j);
          atom_molecule_id_vector.push_back(i);
          atom_position_id_vector.push_back(j);
        }
      }
    }
    int num_actual_at_i = local_atom_abc_vector.size();
    for(int j=0; j<num_actual_at_i; j++) {
      bool is_close_to_site = false;
      for(int k=0; k<num_sites_i && !is_close_to_site; k++) {
        is_close_to_site = is_part_of_site_abc(local_atom_abc_vector.at(j), local_site_abc_vector.at(k), framework);
/*
if(atom_is_close_to_site_vector.size()==debug1 || atom_is_close_to_site_vector.size()==debug2) {
  if(is_close_to_site) printf("DEBYG: overall atom index %d (fractional %.3f/%.3f/%.3f) is close to site index %d (fractional %.3f/%.3f/%.3f) in molecule index %d\n", (int)(atom_is_close_to_site_vector.size()), local_atom_abc_vector.at(j).x, local_atom_abc_vector.at(j).y, local_atom_abc_vector.at(j).z, k, local_site_abc_vector.at(k).x, local_site_abc_vector.at(k).y, local_site_abc_vector.at(k).z, i);
  else printf("DEBYG: overall atom index %d (fractional %.3f/%.3f/%.3f) is NOT close to site index %d (fractional %.3f/%.3f/%.3f) in molecule index %d (distance = %.3f)\n", (int)(atom_is_close_to_site_vector.size()), local_atom_abc_vector.at(j).x, local_atom_abc_vector.at(j).y, local_atom_abc_vector.at(j).z, k, local_site_abc_vector.at(k).x, local_site_abc_vector.at(k).y, local_site_abc_vector.at(k).z, i, framework->getDistCalc().minimum_periodic_distance(local_atom_abc_vector.at(j).x, local_atom_abc_vector.at(j).y, local_atom_abc_vector.at(j).z, local_site_abc_vector.at(k).x, local_site_abc_vector.at(k).y, local_site_abc_vector.at(k).z));
}
*/
      }
      atom_is_close_to_site_vector.push_back(is_close_to_site);
    }
  }
  int num_total_atoms = atom_abc_vector.size();
  for(int i=0; i<num_total_atoms && !collision; i++) {
    for(int j=i+1; j<num_total_atoms && !collision; j++) {
      if(atom_molecule_id_vector.at(i)==atom_molecule_id_vector.at(j)) { //atoms are in the same molecule
        if(!bonded_xyz(assembled_molecules->at(atom_molecule_id_vector.at(i)).atoms_xyz.at(atom_position_id_vector.at(i)), assembled_molecules->at(atom_molecule_id_vector.at(j)).atoms_xyz.at(atom_position_id_vector.at(j)))) { //if they are not supposed to be bonded
          if(bonded_abc(atom_abc_vector.at(i), atom_abc_vector.at(j), framework)) {
            if(verbose) printf("NOTICE: non-bonded atoms in building block %d are bonded periodically, constituting a collision\n", atom_molecule_id_vector.at(i));
            collision = true; //collision if they are bonded
          }
        } else if(multiple_periodic_connections_possible) { //else they are supposed to be bonded - so we need to make sure that they are not bonded more than once periodically, if that is a possibility given the unit cell parameters
          XYZ shift_i_to_centre = centre_abc - trans_to_origuc(atom_abc_vector.at(i));
          XYZ uc_j = trans_to_origuc(atom_abc_vector.at(j)+shift_i_to_centre);
          int num_periodic_bonds = 0;
          for(int da=-1; da<2 && num_periodic_bonds<2; da++) {
            for(int db=-1; db<2 && num_periodic_bonds<2; db++) {
              for(int dc=-1; dc<2 && num_periodic_bonds<2; dc++) {
                XYZ image(da,db,dc);
                XYZ image_j_xyz = framework->abc_to_xyz_returning_XYZ(uc_j+image);
                if(bonded_xyz(image_j_xyz, centre_xyz)) num_periodic_bonds++;
              }
            }
          }
          if(num_periodic_bonds>1) {
            if(verbose) printf("NOTICE: more than one (%d) bonds were detected between atoms in building block %d, constituting a collision\n", num_periodic_bonds, atom_molecule_id_vector.at(i));
            collision = true;
          }
        }
      } else if(bonded_abc(atom_abc_vector.at(i), atom_abc_vector.at(j), framework)) { //atoms are in different molecules, and they are bonded
        if(!atom_is_close_to_site_vector.at(i) || !atom_is_close_to_site_vector.at(j)) {
          if(verbose) printf("NOTICE: a bond was detected between atoms that are not both part of a site: %s (fractional %.3f/%.3f/%.3f) and %s (fractional %.3f/%.3f/%.3f) in building blocks %d and %d respectively (overall indices %d and %d), constituting a collision (distance = %.3f)\n", assembled_molecules->at(atom_molecule_id_vector.at(i)).atoms_type.at(atom_position_id_vector.at(i)).c_str(), atom_abc_vector.at(i).x, atom_abc_vector.at(i).y, atom_abc_vector.at(i).z, assembled_molecules->at(atom_molecule_id_vector.at(j)).atoms_type.at(atom_position_id_vector.at(j)).c_str(), atom_abc_vector.at(j).x, atom_abc_vector.at(j).y, atom_abc_vector.at(j).z, atom_molecule_id_vector.at(i), atom_molecule_id_vector.at(j), i, j, framework->getDistCalc().minimum_periodic_distance(atom_abc_vector.at(i).x, atom_abc_vector.at(i).y, atom_abc_vector.at(i).z, atom_abc_vector.at(j).x, atom_abc_vector.at(j).y, atom_abc_vector.at(j).z));

          collision = true; //if either atom is not part of a site, this is a collision
        } else { //else they are both part of sites - so we need to check whether these molecules are supposed to be connected
          bool mols_connected = false;
          for(int k=0; k<num_c && !mols_connected; k++) {
            CONNECTION c = two_way_connections->at(k);
            int v1 = c.v1;
            int v2 = c.v2;
            if((v1==atom_molecule_id_vector.at(i) && v2==atom_molecule_id_vector.at(j)) || (v2==atom_molecule_id_vector.at(i) && v1==atom_molecule_id_vector.at(j))) {
              mols_connected = true;
            }
          }
          if(!mols_connected) {
            if(verbose) printf("NOTICE: a bond was detected between disconnected building blocks %d and %d, constituting a collision\n", atom_molecule_id_vector.at(i), atom_molecule_id_vector.at(j));
            collision = true;
          }
        }
      }
    }
  }
  return collision;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1f8, %rsp            # imm = 0x1F8
movq %rdx, %r14
movq %rsi, %r12
movq %rdi, %r15
leaq 0x1e0(%rsp), %rbx
movsd 0xed940(%rip), %xmm0    # 0x14d038
movq %rbx, %rdi
movaps %xmm0, %xmm1
movaps %xmm0, %xmm2
callq 0x84364
movsd (%rbx), %xmm0
movsd 0x8(%rbx), %xmm1
movsd 0x10(%rbx), %xmm2
leaq 0x1c8(%rsp), %rdi
movq %r15, %rsi
callq 0x52dd8
movq 0x8(%r12), %rcx
movq %r12, 0x118(%rsp)
subq (%r12), %rcx
sarq $0x3, %rcx
movabsq $-0x30c30c30c30c30c3, %rax # imm = 0xCF3CF3CF3CF3CF3D
imulq %rax, %rcx
movq %rcx, 0xd0(%rsp)
movq 0x8(%r14), %rax
movq %r14, 0x198(%rsp)
subq (%r14), %rax
sarq $0x2, %rax
movabsq $0x6db6db6db6db6db7, %rcx # imm = 0x6DB6DB6DB6DB6DB7
imulq %rcx, %rax
movq %rax, 0x178(%rsp)
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
xorl %ebx, %ebx
leaq 0xb0(%rsp), %r12
testb $0x1, %bl
movl %ebp, 0x38(%rsp)
je 0x5f7a8
movl 0x38(%rsp), %ebp
testl %ebp, %ebp
jg 0x5f889
incl %ebp
testb $0x1, %bl
je 0x5f787
jmp 0x5f889
xorps %xmm0, %xmm0
cvtsi2sd %ebp, %xmm0
movsd %xmm0, 0x48(%rsp)
movl $0xffffffff, %r13d      # imm = 0xFFFFFFFF
xorl $0x1, %ebp
testb $0x1, %bl
jne 0x5f790
xorps %xmm0, %xmm0
cvtsi2sd %r13d, %xmm0
movsd %xmm0, 0x40(%rsp)
xorl %r14d, %r14d
movb $0x1, %al
xorl %ecx, %ecx
cmpl $0x1, %r13d
sete %dl
movl %ecx, %esi
orl %r13d, %esi
orl %ebp, %esi
je 0x5f7f2
testb $0x1, %r14b
jne 0x5f7f2
andb %al, %dl
je 0x5f858
xorps %xmm0, %xmm0
cvtsi2sd %ecx, %xmm0
leaq 0xd8(%rsp), %rdi
movsd 0x40(%rsp), %xmm1
movsd 0x48(%rsp), %xmm2
callq 0x84364
movsd 0xd8(%rsp), %xmm0
movsd 0xe0(%rsp), %xmm1
movsd 0xe8(%rsp), %xmm2
movq %r12, %rdi
movq %r15, %rsi
callq 0x52dd8
movq %r12, %rdi
callq 0x8398c
movsd 0xf2f50(%rip), %xmm1    # 0x152798
ucomisd %xmm0, %xmm1
jb 0x5f855
movl $0x1, %ebx
jmp 0x5f858
movzbl %bl, %ebx
orb %bl, %r14b
movl $0x1, %ecx
xorl %eax, %eax
testb $0x1, %r14b
movb $0x1, %r14b
je 0x5f7d8
testl %r13d, %r13d
jg 0x5f790
incl %r13d
testb $0x1, %bl
je 0x5f7be
jmp 0x5f790
xorpd %xmm0, %xmm0
movapd %xmm0, 0xb0(%rsp)
xorl %eax, %eax
movq %rax, 0xc0(%rsp)
movq %rax, 0x110(%rsp)
movapd %xmm0, 0x100(%rsp)
movq %rax, 0x60(%rsp)
movapd %xmm0, 0x50(%rsp)
movq %rax, 0xd8(%rsp)
movl %eax, 0xe0(%rsp)
movq %rax, 0xe8(%rsp)
movl %eax, 0xf0(%rsp)
movq %rax, 0xf8(%rsp)
movl %eax, 0x138(%rsp)
cmpl $0x0, 0xd0(%rsp)
jle 0x604c3
movl %ebx, 0x154(%rsp)
xorl %eax, %eax
movq 0x118(%rsp), %r14
movabsq $-0x30c30c30c30c30c3, %r12 # imm = 0xCF3CF3CF3CF3CF3D
movslq %eax, %rsi
movq (%r14), %rax
movq 0x8(%r14), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
imulq %r12, %rdx
cmpq %rsi, %rdx
jbe 0x605bf
imulq $0xa8, %rsi, %rcx
movq 0x8(%rax,%rcx), %rdx
movq 0x50(%rax,%rcx), %rsi
subq (%rax,%rcx), %rdx
shrq $0x3, %rdx
imull $0xaaaaaaab, %edx, %ebp # imm = 0xAAAAAAAB
subq 0x48(%rax,%rcx), %rsi
movq 0x68(%rax,%rcx), %rdx
movq 0x60(%rax,%rcx), %rax
xorl %ecx, %ecx
movq %rcx, 0x80(%rsp)
xorpd %xmm0, %xmm0
movapd %xmm0, 0x70(%rsp)
movq %rcx, 0xa0(%rsp)
movapd %xmm0, 0x90(%rsp)
movl $0x0, 0x120(%rsp)
testl %ebp, %ebp
jle 0x5fe2f
shrq $0x2, %rsi
subq %rax, %rdx
shrq $0x2, %rdx
movq %rsi, 0x40(%rsp)
movslq %esi, %rbx
movq %rdx, 0x48(%rsp)
movslq %edx, %r13
xorl %eax, %eax
movslq 0x138(%rsp), %rsi
movq (%r14), %rcx
movq 0x8(%r14), %rdx
subq %rcx, %rdx
sarq $0x3, %rdx
imulq %r12, %rdx
cmpq %rsi, %rdx
jbe 0x605a3
imulq $0xa8, %rsi, %rdx
movslq %eax, %rsi
movq 0x18(%rcx,%rdx), %rdi
movq 0x20(%rcx,%rdx), %rdx
subq %rdi, %rdx
sarq $0x5, %rdx
cmpq %rsi, %rdx
jbe 0x605a3
shlq $0x5, %rsi
addq %rsi, %rdi
leaq 0xf783c(%rip), %rsi     # 0x157244
callq 0x4170
testl %eax, %eax
je 0x5fd05
movslq 0x138(%rsp), %rsi
movq (%r14), %rax
movq 0x8(%r14), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
imulq %r12, %rdx
cmpq %rsi, %rdx
jbe 0x605b1
imulq $0xa8, %rsi, %rdx
movslq 0x120(%rsp), %rsi
movq (%rax,%rdx), %rcx
movq 0x8(%rax,%rdx), %rdx
subq %rcx, %rdx
sarq $0x3, %rdx
movabsq $-0x5555555555555555, %rax # imm = 0xAAAAAAAAAAAAAAAB
imulq %rax, %rdx
cmpq %rsi, %rdx
jbe 0x605b1
leaq (%rsi,%rsi,2), %rax
movsd (%rcx,%rax,8), %xmm0
movsd 0x8(%rcx,%rax,8), %xmm1
movsd 0x10(%rcx,%rax,8), %xmm2
leaq 0x158(%rsp), %rdi
movq %r15, %rsi
callq 0x52f42
cmpl $0x0, 0x40(%rsp)
jle 0x5fb2c
movslq 0x138(%rsp), %rsi
movq (%r14), %rax
movq 0x8(%r14), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
imulq %r12, %rdx
cmpq %rsi, %rdx
jbe 0x60570
movl 0x120(%rsp), %ecx
imulq $0xa8, %rsi, %rsi
movq 0x48(%rax,%rsi), %rdx
movq 0x50(%rax,%rsi), %rsi
subq %rdx, %rsi
sarq $0x2, %rsi
movq %rsi, %rdi
negq %rdi
movl $0x1, %r9d
leaq (%rdi,%r9), %rax
cmpq $0x1, %rax
je 0x6056d
movl -0x4(%rdx,%r9,4), %r8d
cmpl %r8d, %ecx
sete %al
cmpq %rbx, %r9
jge 0x5fb12
incq %r9
cmpl %r8d, %ecx
jne 0x5faec
cmpl $0x0, 0x48(%rsp)
jle 0x5fb1e
cmpl %r8d, %ecx
jne 0x5fb39
cmpl %r8d, %ecx
je 0x5fbab
jmp 0x5fbf1
cmpl $0x0, 0x48(%rsp)
jle 0x5fbf1
xorl %eax, %eax
movslq 0x138(%rsp), %rsi
movq (%r14), %rdi
movq 0x8(%r14), %rdx
subq %rdi, %rdx
sarq $0x3, %rdx
imulq %r12, %rdx
cmpq %rsi, %rdx
jbe 0x60595
movl 0x120(%rsp), %ecx
imulq $0xa8, %rsi, %rsi
movq 0x60(%rdi,%rsi), %rdx
movq 0x68(%rdi,%rsi), %rsi
subq %rdx, %rsi
sarq $0x2, %rsi
movq %rsi, %rdi
negq %rdi
movl $0x1, %r8d
leaq (%rdi,%r8), %r9
cmpq $0x1, %r9
je 0x60592
movl -0x4(%rdx,%r8,4), %r9d
cmpq %r13, %r8
jge 0x5fba7
incq %r8
cmpl %r9d, %ecx
jne 0x5fb87
testb %al, %al
je 0x5fbe8
movq 0x98(%rsp), %rsi
cmpq 0xa0(%rsp), %rsi
je 0x5fcf0
movq 0x168(%rsp), %rax
movq %rax, 0x10(%rsi)
movupd 0x158(%rsp), %xmm0
movupd %xmm0, (%rsi)
addq $0x18, 0x98(%rsp)
jmp 0x5fd05
cmpl %r9d, %ecx
je 0x5fd05
movq 0x78(%rsp), %rsi
cmpq 0x80(%rsp), %rsi
je 0x5fc21
movq 0x168(%rsp), %rax
movq %rax, 0x10(%rsi)
movupd 0x158(%rsp), %xmm0
movupd %xmm0, (%rsi)
addq $0x18, 0x78(%rsp)
jmp 0x5fc33
leaq 0x70(%rsp), %rdi
leaq 0x158(%rsp), %rdx
callq 0x69b82
movq 0x58(%rsp), %rsi
cmpq 0x60(%rsp), %rsi
je 0x5fc60
movq 0x168(%rsp), %rax
movq %rax, 0x10(%rsi)
movupd 0x158(%rsp), %xmm0
movupd %xmm0, (%rsi)
addq $0x18, 0x58(%rsp)
jmp 0x5fc72
leaq 0x50(%rsp), %rdi
leaq 0x158(%rsp), %rdx
callq 0x69b82
movq 0xb8(%rsp), %rsi
cmpq 0xc0(%rsp), %rsi
je 0x5fc9b
movl 0x138(%rsp), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0xb8(%rsp)
jmp 0x5fcb0
leaq 0xb0(%rsp), %rdi
leaq 0x138(%rsp), %rdx
callq 0xf864
movq 0x108(%rsp), %rsi
cmpq 0x110(%rsp), %rsi
je 0x5fcd9
movl 0x120(%rsp), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x108(%rsp)
jmp 0x5fd05
leaq 0x100(%rsp), %rdi
leaq 0x120(%rsp), %rdx
callq 0xf864
jmp 0x5fd05
leaq 0x90(%rsp), %rdi
leaq 0x158(%rsp), %rdx
callq 0x69b82
movl 0x120(%rsp), %eax
incl %eax
movl %eax, 0x120(%rsp)
cmpl %ebp, %eax
jl 0x5f9b3
movq 0x78(%rsp), %rbx
subq 0x70(%rsp), %rbx
sarq $0x3, %rbx
movabsq $-0x5555555555555555, %rax # imm = 0xAAAAAAAAAAAAAAAB
imulq %rax, %rbx
testl %ebx, %ebx
jle 0x5fe2f
movslq 0x40(%rsp), %r13
andl $0x7fffffff, %ebx       # imm = 0x7FFFFFFF
xorl %ebp, %ebp
cmpl $0x0, 0x40(%rsp)
jle 0x5fe11
xorl %r12d, %r12d
xorl %r14d, %r14d
movq 0x70(%rsp), %rax
movq 0x78(%rsp), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
movabsq $-0x5555555555555555, %rsi # imm = 0xAAAAAAAAAAAAAAAB
imulq %rsi, %rdx
cmpq %rbp, %rdx
jbe 0x60581
movq 0x90(%rsp), %rcx
movq 0x98(%rsp), %rdx
subq %rcx, %rdx
sarq $0x3, %rdx
imulq %rsi, %rdx
cmpq %r14, %rdx
jbe 0x6057e
leaq (,%rbp,2), %rdx
addq %rbp, %rdx
movq 0x10(%rcx,%r12), %rsi
movq %rsi, 0x28(%rsp)
movups (%rcx,%r12), %xmm0
movups %xmm0, 0x18(%rsp)
movq 0x10(%rax,%rdx,8), %rcx
movq %rcx, 0x10(%rsp)
movupd (%rax,%rdx,8), %xmm0
movupd %xmm0, (%rsp)
movq %r15, %rdi
callq 0x59e55
incq %r14
cmpq %r13, %r14
setge %cl
orb %al, %cl
addq $0x18, %r12
testb %cl, %cl
je 0x5fd5f
movq 0x118(%rsp), %r14
movabsq $-0x30c30c30c30c30c3, %r12 # imm = 0xCF3CF3CF3CF3CF3D
jmp 0x5fe13
xorl %eax, %eax
movzbl %al, %esi
leaq 0xd8(%rsp), %rdi
callq 0xea58
incq %rbp
cmpq %rbx, %rbp
jne 0x5fd4e
movq 0x90(%rsp), %rdi
testq %rdi, %rdi
je 0x5fe4c
movq 0xa0(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0x70(%rsp), %rdi
testq %rdi, %rdi
je 0x5fe66
movq 0x80(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movl 0x138(%rsp), %eax
incl %eax
movl %eax, 0x138(%rsp)
cmpl 0xd0(%rsp), %eax
jl 0x5f912
movq 0x58(%rsp), %rcx
subq 0x50(%rsp), %rcx
sarq $0x3, %rcx
movabsq $-0x5555555555555555, %rax # imm = 0xAAAAAAAAAAAAAAAB
imulq %rax, %rcx
testl %ecx, %ecx
jle 0x604c3
movslq 0x178(%rsp), %rax
movq %rax, 0x1a8(%rsp)
movq %rcx, 0x1a0(%rsp)
andl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
movl $0x1, %eax
movq %rax, 0x170(%rsp)
xorl %r13d, %r13d
leaq 0x158(%rsp), %rbx
leaq 0x138(%rsp), %r12
xorl %ebp, %ebp
movq %rcx, 0x188(%rsp)
leaq 0x1(%r13), %rax
movq %rax, 0x190(%rsp)
cmpq %rcx, %rax
jae 0x6049a
testb $0x1, %bpl
jne 0x6049a
movq 0x170(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0xb0(%rsp), %rax
movq 0xb8(%rsp), %rdx
subq %rax, %rdx
sarq $0x2, %rdx
cmpq %r13, %rdx
jbe 0x605e8
movq 0x38(%rsp), %rcx
cmpq %rcx, %rdx
jbe 0x605ed
movslq (%rax,%r13,4), %rsi
cmpl (%rax,%rcx,4), %esi
jne 0x60283
movq (%r14), %rcx
movq 0x8(%r14), %rdx
subq %rcx, %rdx
sarq $0x3, %rdx
movabsq $-0x30c30c30c30c30c3, %rdi # imm = 0xCF3CF3CF3CF3CF3D
imulq %rdi, %rdx
cmpq %rsi, %rdx
jbe 0x6061f
movq 0x100(%rsp), %r9
movq 0x108(%rsp), %r8
subq %r9, %r8
sarq $0x2, %r8
cmpq %r13, %r8
jbe 0x60619
imulq $0xa8, %rsi, %r10
movslq (%r9,%r13,4), %rsi
movq (%rcx,%r10), %rdi
movq 0x8(%rcx,%r10), %r10
subq %rdi, %r10
sarq $0x3, %r10
movabsq $-0x5555555555555555, %r11 # imm = 0xAAAAAAAAAAAAAAAB
imulq %r11, %r10
cmpq %rsi, %r10
jbe 0x60605
movq 0x38(%rsp), %r10
movslq (%rax,%r10,4), %rax
cmpq %rax, %rdx
jbe 0x6060a
cmpq %r10, %r8
jbe 0x6060f
imulq $0xa8, %rax, %rdx
movslq (%r9,%r10,4), %r8
movq (%rcx,%rdx), %rax
movq 0x8(%rcx,%rdx), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
movabsq $-0x5555555555555555, %rcx # imm = 0xAAAAAAAAAAAAAAAB
imulq %rcx, %rdx
cmpq %r8, %rdx
jbe 0x60614
leaq (%rsi,%rsi,2), %rcx
leaq (%rdi,%rcx,8), %rcx
leaq (%r8,%r8,2), %rdx
movq 0x10(%rax,%rdx,8), %rsi
movq %rsi, 0x28(%rsp)
movups (%rax,%rdx,8), %xmm0
movups %xmm0, 0x18(%rsp)
movq 0x10(%rcx), %rax
movq %rax, 0x10(%rsp)
movupd (%rcx), %xmm0
movupd %xmm0, (%rsp)
callq 0x9da26
testb %al, %al
je 0x603f8
testb $0x1, 0x154(%rsp)
je 0x6047a
movq 0x50(%rsp), %rax
movq 0x58(%rsp), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
movabsq $-0x5555555555555555, %r14 # imm = 0xAAAAAAAAAAAAAAAB
imulq %r14, %rdx
cmpq %r13, %rdx
jbe 0x6062d
leaq (,%r13,2), %rcx
addq %r13, %rcx
movq 0x10(%rax,%rcx,8), %rdx
movq %rdx, 0x10(%rsp)
movupd (%rax,%rcx,8), %xmm0
movupd %xmm0, (%rsp)
leaq 0x90(%rsp), %r14
movq %r14, %rdi
callq 0x83a19
leaq 0x70(%rsp), %rdi
leaq 0x1e0(%rsp), %rsi
movq %r14, %rdx
callq 0x8461e
movq 0x50(%rsp), %rax
movq 0x58(%rsp), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
movabsq $-0x5555555555555555, %rcx # imm = 0xAAAAAAAAAAAAAAAB
imulq %rcx, %rdx
movq 0x38(%rsp), %rsi
cmpq %rsi, %rdx
jbe 0x6063e
movq %r13, 0x180(%rsp)
movl %ebp, 0x150(%rsp)
leaq (%rsi,%rsi,2), %rcx
leaq (%rax,%rcx,8), %rsi
leaq 0x1b0(%rsp), %rdi
leaq 0x70(%rsp), %rdx
callq 0x84642
leaq 0x90(%rsp), %rdi
movq 0x1c0(%rsp), %rax
movq %rax, 0x10(%rsp)
movupd 0x1b0(%rsp), %xmm0
movupd %xmm0, (%rsp)
callq 0x83a19
xorl %r13d, %r13d
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl %eax, 0xd0(%rsp)
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
movsd %xmm0, 0x48(%rsp)
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
xorps %xmm0, %xmm0
cvtsi2sd %ebp, %xmm0
movsd %xmm0, 0x40(%rsp)
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
xorps %xmm2, %xmm2
cvtsi2sd %r14d, %xmm2
movq %rbx, %rdi
movsd 0x48(%rsp), %xmm0
movsd 0x40(%rsp), %xmm1
callq 0x84364
leaq 0x120(%rsp), %rdi
leaq 0x90(%rsp), %rsi
movq %rbx, %rdx
callq 0x84642
movsd 0x120(%rsp), %xmm0
movsd 0x128(%rsp), %xmm1
movsd 0x130(%rsp), %xmm2
movq %r12, %rdi
movq %r15, %rsi
callq 0x52dd8
movq 0x1d8(%rsp), %rax
movq %rax, 0x28(%rsp)
movups 0x1c8(%rsp), %xmm0
movups %xmm0, 0x18(%rsp)
movq 0x148(%rsp), %rax
movq %rax, 0x10(%rsp)
movupd 0x138(%rsp), %xmm0
movupd %xmm0, (%rsp)
callq 0x9da26
movzbl %al, %eax
addl %eax, %r13d
testl %r14d, %r14d
jg 0x60230
incl %r14d
cmpl $0x2, %r13d
jl 0x60184
testl %ebp, %ebp
jg 0x60240
incl %ebp
cmpl $0x2, %r13d
jl 0x60171
movl 0xd0(%rsp), %eax
testl %eax, %eax
jg 0x60257
incl %eax
cmpl $0x2, %r13d
jl 0x60158
cmpl $0x2, %r13d
movl 0x150(%rsp), %ebp
movzbl %bpl, %ebp
movl $0x1, %eax
cmovgel %eax, %ebp
movq 0x118(%rsp), %r14
movq 0x180(%rsp), %r13
jmp 0x6047a
movq 0x50(%rsp), %rax
movq 0x58(%rsp), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
movabsq $-0x5555555555555555, %rcx # imm = 0xAAAAAAAAAAAAAAAB
imulq %rcx, %rdx
cmpq %r13, %rdx
jbe 0x605e8
movq 0x38(%rsp), %rsi
cmpq %rsi, %rdx
jbe 0x6061f
leaq (,%r13,2), %rcx
addq %r13, %rcx
leaq (%rsi,%rsi,2), %rdx
movq 0x10(%rax,%rdx,8), %rsi
movq %rsi, 0x28(%rsp)
movups (%rax,%rdx,8), %xmm0
movups %xmm0, 0x18(%rsp)
movq 0x10(%rax,%rcx,8), %rdx
movq %rdx, 0x10(%rsp)
movupd (%rax,%rcx,8), %xmm0
movupd %xmm0, (%rsp)
movq %r15, %rdi
callq 0x59cb9
testb %al, %al
je 0x6047a
leaq 0xd8(%rsp), %rdi
movq %r13, %rsi
callq 0xee36
testq %rdx, (%rax)
je 0x604c7
leaq 0xd8(%rsp), %rdi
movq 0x38(%rsp), %rsi
callq 0xee36
testq %rdx, (%rax)
je 0x604c7
cmpl $0x0, 0x178(%rsp)
jle 0x604c7
movq 0x198(%rsp), %rcx
movq (%rcx), %rax
movq 0x8(%rcx), %rsi
subq %rax, %rsi
sarq $0x2, %rsi
movabsq $0x6db6db6db6db6db7, %rcx # imm = 0x6DB6DB6DB6DB6DB7
imulq %rcx, %rsi
movq 0xb0(%rsp), %rcx
movq 0xb8(%rsp), %rdx
subq %rcx, %rdx
sarq $0x2, %rdx
addq $0x4, %rax
xorl %edi, %edi
cmpq %rdi, %rsi
je 0x605d2
cmpq %r13, %rdx
jbe 0x605cd
movl -0x4(%rax), %r8d
movl (%rax), %r9d
movl (%rcx,%r13,4), %r10d
cmpl %r10d, %r8d
jne 0x603c3
movq 0x38(%rsp), %r11
cmpq %r11, %rdx
jbe 0x605e3
cmpl (%rcx,%r11,4), %r9d
je 0x6047a
cmpl %r10d, %r9d
je 0x603d3
jmp 0x603e2
cmpl %r10d, %r9d
jne 0x603e2
cmpq 0x38(%rsp), %rdx
jbe 0x605f2
movq 0x38(%rsp), %r9
cmpl (%rcx,%r9,4), %r8d
je 0x6047a
incq %rdi
addq $0x1c, %rax
cmpq 0x1a8(%rsp), %rdi
jl 0x60382
jmp 0x604c7
movq 0x50(%rsp), %rax
movq 0x58(%rsp), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
movabsq $-0x5555555555555555, %rcx # imm = 0xAAAAAAAAAAAAAAAB
imulq %rcx, %rdx
cmpq %r13, %rdx
jbe 0x605e8
movq 0x38(%rsp), %rsi
cmpq %rsi, %rdx
jbe 0x6061f
leaq (,%r13,2), %rcx
addq %r13, %rcx
leaq (%rsi,%rsi,2), %rdx
movq 0x10(%rax,%rdx,8), %rsi
movq %rsi, 0x28(%rsp)
movups (%rax,%rdx,8), %xmm0
movups %xmm0, 0x18(%rsp)
movq 0x10(%rax,%rcx,8), %rdx
movq %rdx, 0x10(%rsp)
movupd (%rax,%rcx,8), %xmm0
movupd %xmm0, (%rsp)
movq %r15, %rdi
callq 0x59cb9
movzbl %bpl, %ebp
testb %al, %al
movl $0x1, %eax
cmovnel %eax, %ebp
movq 0x38(%rsp), %rcx
incq %rcx
movq %rcx, 0x38(%rsp)
cmpl %ecx, 0x1a0(%rsp)
jle 0x6049a
testb $0x1, %bpl
je 0x5ff1b
movq 0x188(%rsp), %rcx
movq 0x190(%rsp), %r13
cmpq %rcx, %r13
jae 0x604ca
incq 0x170(%rsp)
testb $0x1, %bpl
je 0x5feef
jmp 0x604ca
xorl %ebp, %ebp
jmp 0x604ca
movb $0x1, %bpl
movq 0xd8(%rsp), %rdi
testq %rdi, %rdi
je 0x60504
movq 0xf8(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
xorl %eax, %eax
movq %rax, 0xd8(%rsp)
movl $0x0, 0xe0(%rsp)
movq %rax, 0xe8(%rsp)
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
je 0x6051b
movq 0x60(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0x100(%rsp), %rdi
testq %rdi, %rdi
je 0x60538
movq 0x110(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0xb0(%rsp), %rdi
testq %rdi, %rdi
je 0x60555
movq 0xc0(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
andb $0x1, %bpl
movl %ebp, %eax
addq $0x1f8, %rsp            # imm = 0x1F8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rsi, %rdx
leaq 0xed17e(%rip), %rdi     # 0x14d6f5
xorl %eax, %eax
callq 0x4630
movq %r14, %rbp
leaq 0xed16d(%rip), %rdi     # 0x14d6f5
movq %rbp, %rsi
xorl %eax, %eax
callq 0x4630
movq %rsi, %rdx
leaq 0xed159(%rip), %rdi     # 0x14d6f5
xorl %eax, %eax
callq 0x4630
leaq 0xed14b(%rip), %rdi     # 0x14d6f5
xorl %eax, %eax
callq 0x4630
leaq 0xed13d(%rip), %rdi     # 0x14d6f5
xorl %eax, %eax
callq 0x4630
leaq 0xed12f(%rip), %rdi     # 0x14d6f5
xorl %eax, %eax
callq 0x4630
movq %r13, %rsi
jmp 0x605f7
leaq 0xed11c(%rip), %rdi     # 0x14d6f5
movq %rsi, %rdx
xorl %eax, %eax
callq 0x4630
movq %r11, %rsi
jmp 0x605f7
movq %r13, %rsi
jmp 0x6061f
movq %rcx, %rsi
jmp 0x6061f
movq 0x38(%rsp), %rsi
leaq 0xed0f7(%rip), %rdi     # 0x14d6f5
xorl %eax, %eax
callq 0x4630
movq %r10, %rdx
jmp 0x6061f
movq %rax, %rsi
jmp 0x6061f
movq %r10, %rsi
jmp 0x6061c
movq %r8, %rsi
jmp 0x6061f
movq %r13, %rsi
movq %r8, %rdx
leaq 0xed0cf(%rip), %rdi     # 0x14d6f5
xorl %eax, %eax
callq 0x4630
leaq 0xed0c1(%rip), %rdi     # 0x14d6f5
movq %r13, %rsi
xorl %eax, %eax
callq 0x4630
leaq 0xed0b0(%rip), %rdi     # 0x14d6f5
xorl %eax, %eax
callq 0x4630
jmp 0x606b2
jmp 0x606b2
jmp 0x606b2
jmp 0x606b2
jmp 0x606b2
jmp 0x606b2
jmp 0x606b2
jmp 0x606b2
jmp 0x606b2
jmp 0x606b2
jmp 0x606b2
jmp 0x60676
jmp 0x60676
jmp 0x60676
jmp 0x60676
jmp 0x60676
jmp 0x60676
jmp 0x60676
jmp 0x60676
jmp 0x606b2
jmp 0x606b2
movq %rax, %rbx
movq 0x90(%rsp), %rdi
testq %rdi, %rdi
je 0x60696
movq 0xa0(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0x70(%rsp), %rdi
testq %rdi, %rdi
je 0x606b5
movq 0x80(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
jmp 0x606b5
movq %rax, %rbx
movq 0xd8(%rsp), %rdi
testq %rdi, %rdi
je 0x606ef
movq 0xf8(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
xorl %eax, %eax
movq %rax, 0xd8(%rsp)
movl $0x0, 0xe0(%rsp)
movq %rax, 0xe8(%rsp)
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
je 0x60706
movq 0x60(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0x100(%rsp), %rdi
testq %rdi, %rdi
je 0x60723
movq 0x110(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0xb0(%rsp), %rdi
testq %rdi, %rdi
je 0x60740
movq 0xc0(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq %rbx, %rdi
callq 0x4780