// File: /workspace/github_cpp_makefile_star2_O1/dcarrey[P]hgt-detection/./fonctions.cpp
// Function: findBestHGTtab(InputTree, InputTree, Parameters, HGT*, int*, int*, int)
int findBestHGTtab(struct InputTree SpeciesTree,struct InputTree GeneTree,struct Parameters param,struct HGT *aHGT, int *nbHgtFound,int *initial,int bootstrap){

	struct InputTree tmpTree;
	struct InputTree tmpTree2;
	
	int i,j,k,l,first=1,ret=0,trouve;
	int size = SpeciesTree.size;
	int ktSpecies;
	struct CRITERIA aCrit,aCritRef,aCritRef2,aCrit_tmpTree2;
	struct DescTree *DTSpecies,*DTGene;
	int encore = 0;
  
	initInputTree(&tmpTree);
	initInputTree(&tmpTree2);
	
	(*nbHgtFound) = 0;

	printf("\n\n== NEW STEP OF DETECTION == [size of the trees (after reduction)=%d]",SpeciesTree.size);
  
	//== compute criteria
	InitCriteria(&aCrit,size);
	InitCriteria(&aCritRef,size);
	InitCriteria(&aCritRef2,size);
	InitCriteria(&aCrit_tmpTree2,size);
	computeCriteria(SpeciesTree.ADD,GeneTree.ADD,size,&aCrit,SpeciesTree.LONGUEUR,SpeciesTree.ARETE,GeneTree.LONGUEUR,GeneTree.ARETE);
	computeCriteria(SpeciesTree.ADD,GeneTree.ADD,size,&aCritRef,SpeciesTree.LONGUEUR,SpeciesTree.ARETE,GeneTree.LONGUEUR,GeneTree.ARETE);
	computeCriteria(SpeciesTree.ADD,GeneTree.ADD,size,&aCritRef2,SpeciesTree.LONGUEUR,SpeciesTree.ARETE,GeneTree.LONGUEUR,GeneTree.ARETE);
	loadCriteria(aCrit,&aHGT[0]);
  
	DTGene = (struct DescTree*)malloc((2*GeneTree.size-2-GeneTree.kt+1)*sizeof(struct DescTree));
	RechercherBipartition(GeneTree.ARETE,GeneTree.ADD,GeneTree.Root,GeneTree.Adjacence,DTGene,GeneTree.size,GeneTree.kt);	

	DTSpecies = (struct DescTree*)malloc((2*SpeciesTree.size-2-SpeciesTree.kt+1)*sizeof(struct DescTree));
	RechercherBipartition(SpeciesTree.ARETE,SpeciesTree.ADD,SpeciesTree.Root,SpeciesTree.Adjacence,DTSpecies,SpeciesTree.size,SpeciesTree.kt);

	int flag2 = 1;
	int flag3;   		//== pour tester les especes avec sur la branche au dessus
	int initial3=1;
	
	
	do{
		for(i=1;i<2*size-3-SpeciesTree.kt;i++)
			for(j=i+1;j<2*size-3-SpeciesTree.kt;j++){
				//== is it a valid hgt ?
				trouve=0;
				if(isAValidHGT(SpeciesTree,i,j)==1 && i!=j ){
					copyInputTree(&tmpTree,SpeciesTree,0,0);
				
					if(strcmp(param.subtree,"yes") == 0){
						if(TestSubTreeConstraint(SpeciesTree,i,j,DTSpecies,DTGene) == 0)  {
							continue;
							//FreeMemory_InputTree(&tmpTree);
							tmpTree.ADD = NULL;
							tmpTree.ARETE = NULL;
						}
						flag3=0;
						if(TestSubTreeLeafs(SpeciesTree,i,j,DTSpecies,DTGene) == 1){
							//printf("\nTestSubTreeLeafs => ok");
							flag3=1;
						}
					}
					
					applyHGT(GeneTree.ADD,&tmpTree,i,j);
					
					if(strcmp(param.criterion,"ls") == 0)
						AdjustBranchLength(&tmpTree,GeneTree,0,1);
					computeCriteria(tmpTree.ADD,GeneTree.ADD,size,&aCrit,tmpTree.LONGUEUR,tmpTree.ARETE,GeneTree.LONGUEUR,GeneTree.ARETE);
				
					first=1;
					loadCriteria(aCritRef,&aHGT[(*nbHgtFound)]);
					//printf("\ninitial = %d,initial3= %d",*initial,initial3);
					if(((aCritRef.RF-aCrit.RF) == 1) && (*initial==1) && (
					  (SpeciesTree.ARETE[2*i-1] == SpeciesTree.ARETE[2*j-1]) || 
					  (SpeciesTree.ARETE[2*i-1] == SpeciesTree.ARETE[2*j-2]) || 
					  (SpeciesTree.ARETE[2*i-2] == SpeciesTree.ARETE[2*j-2]) || 
					  (SpeciesTree.ARETE[2*i-2] == SpeciesTree.ARETE[2*j-2])
					  )) {
						UpdateCriterion(&first,param.criterion,aCrit,&aHGT[(*nbHgtFound)],i,j,0);
						//printf("\n===========> initial = %d",*initial);
						//printf("\tRF1=%d | RF2=%d | BD1=%2.1lf | BD2=%2.1lf",aHGT[(*nbHgtFound)].crit.RF,aCrit.RF,aHGT[(*nbHgtFound)].crit.BD,aCrit.BD);
						
						aHGT[(*nbHgtFound)].source_A = SpeciesTree.ARETE[2*i-1];
						aHGT[(*nbHgtFound)].source_B = SpeciesTree.ARETE[2*i-2];
						aHGT[(*nbHgtFound)].dest_A = SpeciesTree.ARETE[2*j-1];
						aHGT[(*nbHgtFound)].dest_B = SpeciesTree.ARETE[2*j-2];
						
						findListSpecies(&aHGT[(*nbHgtFound)],DTSpecies,SpeciesTree);
						trouve=1;
					}
					else  if((*initial==0) && ((flag3 == 1) || (initial3 == 0) )){
						if(TestCriterionAndUpdate(&first,param.criterion,aCrit,&aHGT[(*nbHgtFound)],i,j,0,0) == 1){		
							//printf("\n===========> flag3 = %d, initial3=%d",flag3,initial3);
							//printf("\tRF1=%d | RF2=%d | BD1=%2.1lf | BD2=%2.1lf",aHGT[(*nbHgtFound)].crit.RF,aCrit.RF,aHGT[(*nbHgtFound)].crit.BD,aCrit.BD);
							aHGT[(*nbHgtFound)].source_A = SpeciesTree.ARETE[2*i-1];
							aHGT[(*nbHgtFound)].source_B = SpeciesTree.ARETE[2*i-2];
							aHGT[(*nbHgtFound)].dest_A = SpeciesTree.ARETE[2*j-1];
							aHGT[(*nbHgtFound)].dest_B = SpeciesTree.ARETE[2*j-2];
							findListSpecies(&aHGT[(*nbHgtFound)],DTSpecies,SpeciesTree);
							trouve=1;
						}
					}
				}

				if(isAValidHGT(SpeciesTree,j,i)==1 && i!=j ){
					//initInputTree(&tmpTree2);
					copyInputTree(&tmpTree2,tmpTree,0,0);
					copyInputTree(&tmpTree,SpeciesTree,0,0);
					
					if(strcmp(param.subtree,"yes") == 0){
						if(TestSubTreeConstraint(SpeciesTree,j,i,DTSpecies,DTGene) == 0) {
							continue;
							//FreeMemory_InputTree(&tmpTree);
							tmpTree.ADD = NULL;
							tmpTree.ARETE = NULL;
						}
					
						if(TestSubTreeLeafs(SpeciesTree,j,i,DTSpecies,DTGene)==1){
							//printf("\nTestSubTreeLeafs (reverse) => ok");
							flag3=2;
						 }
					}
					
					//if(flag3 == 0){
						//initial3 = 0;
					//}
					
					applyHGT(GeneTree.ADD,&tmpTree,j,i);
					
					if(strcmp(param.criterion,"ls") == 0)
					  AdjustBranchLength(&tmpTree,GeneTree,0,1);
					computeCriteria(tmpTree.ADD,GeneTree.ADD,size,&aCrit,tmpTree.LONGUEUR,tmpTree.ARETE,GeneTree.LONGUEUR,GeneTree.ARETE);
					if(tmpTree2.ADD == NULL){
						printf("HOUSTON, we have a problem !");
						aCrit_tmpTree2.RF = (int) INFINI;
					}
					else{
						computeCriteria(tmpTree.ADD,tmpTree2.ADD,size,&aCrit_tmpTree2,tmpTree.LONGUEUR,tmpTree.ARETE,tmpTree2.LONGUEUR,tmpTree2.ARETE);
					}
					int flag=0;
					first=1;
					int flag_bootstrap = 0;
					if(trouve==0)
						loadCriteria(aCritRef,&aHGT[(*nbHgtFound)]);
					else{
						//printf("\n===========> rand_bootstrap : RF = %d",aCrit_tmpTree2.RF);
						if((bootstrap == 1) && (aCrit_tmpTree2.RF == 0) && /*(aCrit.BD == aHGT[(*nbHgtFound)].crit.BD) && */(aCrit.RF == aHGT[(*nbHgtFound)].crit.RF) ){
							flag_bootstrap = 1;
							//printf("\n==> rand_bootstrap1 : [%2d--%2d -> %2d--%2d]",aHGT[(*nbHgtFound)].source_A,aHGT[(*nbHgtFound)].source_B,aHGT[(*nbHgtFound)].dest_A,aHGT[(*nbHgtFound)].dest_B);
						}
						else{
							aHGT[(*nbHgtFound)].crit.diff_bd = fabs(aCrit.BD - aHGT[(*nbHgtFound)].crit.BD);
							if((flag2 == 1) && (fabs(aCrit.BD - aHGT[(*nbHgtFound)].crit.BD) <= 1)){
								if( (aHGT[(*nbHgtFound)].crit.RF - aCrit.RF) >= 1 ){
									trouve = 0;
									flag = 2;
								}      
								else{
									flag = 1;
									//printf("\n--> TEST FLAG : RF1=%d | RF2=%d | BD1=%2.1lf | BD2=%2.1lf",aHGT[(*nbHgtFound)].crit.RF,aCrit.RF,aHGT[(*nbHgtFound)].crit.BD,aCrit.BD);
								}
							}
							else{
								//printf("\n-->[%2d--%2d -> %2d--%2d]",aHGT[(*nbHgtFound)].source_A,aHGT[(*nbHgtFound)].source_B,aHGT[(*nbHgtFound)].dest_A,aHGT[(*nbHgtFound)].dest_B);
								//printf("\tRF1=%d | RF2=%d | BD1=%2.1lf | BD2=%2.1lf",aHGT[(*nbHgtFound)].crit.RF,aCrit.RF,aHGT[(*nbHgtFound)].crit.BD,aCrit.BD);
							}
						}
					}
					
					//flag_bootstrap = 0;
					if(flag != 1){
						if(((aCritRef.RF-aCrit.RF) == 1) && (*initial==1) && (
						  (SpeciesTree.ARETE[2*i-1] == SpeciesTree.ARETE[2*j-1]) || 
						  (SpeciesTree.ARETE[2*i-1] == SpeciesTree.ARETE[2*j-2]) || 
						  (SpeciesTree.ARETE[2*i-2] == SpeciesTree.ARETE[2*j-2]) || 
						  (SpeciesTree.ARETE[2*i-2] == SpeciesTree.ARETE[2*j-2])
						)) {
						
							if ((flag_bootstrap == 1) && (rand_bootstrap == 1)){
								
								//printf("\n===========>REVERSE : initial = %d",*initial);
								//printf("\tRF1=%d | RF2=%d | BD1=%2.1lf | BD2=%2.1lf",aHGT[(*nbHgtFound)].crit.RF,aCrit.RF,aHGT[(*nbHgtFound)].crit.BD,aCrit.BD);
								UpdateCriterion(&first,param.criterion,aCrit,&aHGT[(*nbHgtFound)],j,i,flag_bootstrap);
								aHGT[(*nbHgtFound)].source_A = SpeciesTree.ARETE[2*j-1];
								aHGT[(*nbHgtFound)].source_B = SpeciesTree.ARETE[2*j-2];
								aHGT[(*nbHgtFound)].dest_A = SpeciesTree.ARETE[2*i-1];
								aHGT[(*nbHgtFound)].dest_B = SpeciesTree.ARETE[2*i-2];
								findListSpecies(&aHGT[(*nbHgtFound)],DTSpecies,SpeciesTree);
								trouve=1;
								//printf("\n==> rand_bootstrap1.5 : [%2d--%2d -> %2d--%2d]",aHGT[(*nbHgtFound)].source_A,aHGT[(*nbHgtFound)].source_B,aHGT[(*nbHgtFound)].dest_A,aHGT[(*nbHgtFound)].dest_B);
							}
						}
						else if(((*initial==0) && ((flag3 == 2) || (initial3 == 0))) || (flag_bootstrap == 1)){
							if(TestCriterionAndUpdate(&first,param.criterion,aCrit,&aHGT[(*nbHgtFound)],j,i,flag,flag_bootstrap) == 1){	
								//printf("\n===========>REVERSE : flag3 = %d, initial3=%d",flag3,initial3);
								//printf("\tRF1=%d | RF2=%d | BD1=%2.1lf | BD2=%2.1lf",aHGT[(*nbHgtFound)].crit.RF,aCrit.RF,aHGT[(*nbHgtFound)].crit.BD,aCrit.BD);
								aHGT[(*nbHgtFound)].source_A = SpeciesTree.ARETE[2*j-1];
								aHGT[(*nbHgtFound)].source_B = SpeciesTree.ARETE[2*j-2];
								aHGT[(*nbHgtFound)].dest_A = SpeciesTree.ARETE[2*i-1];
								aHGT[(*nbHgtFound)].dest_B = SpeciesTree.ARETE[2*i-2];
								findListSpecies(&aHGT[(*nbHgtFound)],DTSpecies,SpeciesTree);
								trouve=1;
								//printf("\n==> rand_bootstrap2 : [%2d--%2d -> %2d--%2d]",aHGT[(*nbHgtFound)].source_A,aHGT[(*nbHgtFound)].source_B,aHGT[(*nbHgtFound)].dest_A,aHGT[(*nbHgtFound)].dest_B);
							}
						}
					}				
				}
				
				if (trouve == 1){
					(*nbHgtFound)++;
					//printf("\n===================> rand_bootstrap final : [%2d--%2d -> %2d--%2d]",aHGT[(*nbHgtFound)-1].source_A,aHGT[(*nbHgtFound)-1].source_B,aHGT[(*nbHgtFound)-1].dest_A,aHGT[(*nbHgtFound)-1].dest_B);			
				}

			}
			encore = 0;
		
		if((*nbHgtFound == 0) && (flag2==1)){
		  flag2 = 0;
		  encore = 1;
		}
		
		if((*nbHgtFound == 0) && (initial3==1) && (*initial==0) ){
		  initial3 = 0;
		  flag2=1;
		  encore = 1;
		}
		
		if((*nbHgtFound == 0) && (*initial==1)){
		  (*initial) = 0;
		  encore = 1;
		  flag2=1;
		}
		
		//initial3 = 0;

		
	 //   printf("On est rendu icit");
	}while(encore == 1);
	
	
	
	deleteBipartition(DTSpecies,SpeciesTree);
	deleteBipartition(DTGene,GeneTree);
	FreeCriteria(&aCrit,size);
	FreeCriteria(&aCritRef,size);
	FreeMemory_InputTree(&tmpTree,tmpTree.size);

	//printf("\n3)RF=%d",aHGT[0].crit.RF);	
	return (*nbHgtFound);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x378, %rsp            # imm = 0x378
movl %ecx, -0xac(%rbp)
movq %rdx, -0x60(%rbp)
movq %rsi, -0x68(%rbp)
movq %rdi, %r15
leaq 0x10(%rbp), %r14
movl $0x1, %ecx
leaq -0x50(%rbp), %rax
movl %ecx, (%rax)
movslq (%r14), %r12
xorl %eax, %eax
leaq -0x1c0(%rbp), %rcx
movq %rax, 0x8(%rcx)
xorps %xmm0, %xmm0
movups %xmm0, 0x28(%rcx)
movq %rax, 0x38(%rcx)
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
movl %ebx, 0x20(%rcx)
movl %ebx, (%rcx)
movl %eax, 0x48(%rcx)
movups %xmm0, 0x10(%rcx)
leaq -0x2d8(%rbp), %rcx
movq %rax, 0x8(%rcx)
movups %xmm0, 0x28(%rcx)
movq %rax, 0x38(%rcx)
movl %ebx, 0x20(%rcx)
movl %ebx, (%rcx)
movl %eax, 0x48(%rcx)
movups %xmm0, 0x10(%rcx)
movl %eax, (%rsi)
leaq 0x68(%rbp), %r13
leaq 0x9319(%rip), %rdi      # 0x15993
movl %r12d, %esi
xorl %eax, %eax
callq 0x1030
leaq -0x168(%rbp), %rdi
movl %r12d, %esi
callq 0xb933
leaq -0x280(%rbp), %rdi
movl %r12d, %esi
callq 0xb933
leaq -0x338(%rbp), %rdi
movl %r12d, %esi
callq 0xb933
leaq -0x220(%rbp), %rdi
movl %r12d, %esi
callq 0xb933
movq 0x8(%r14), %rdi
movq 0x30(%r14), %rax
movq %rax, -0x38(%rbp)
movq 0x8(%r13), %r14
movq 0x30(%r13), %rax
movq %rax, -0x98(%rbp)
movq %rdi, %r13
movq %rdi, -0x48(%rbp)
movq %r14, %rsi
movl %r12d, %edx
leaq -0x168(%rbp), %rcx
callq 0x8d82
movq %r13, %rdi
movq %r14, %rsi
movl %r12d, %edx
leaq -0x280(%rbp), %rcx
callq 0x8d82
movq %r13, %rdi
movq %r14, %rsi
movl %r12d, %edx
leaq -0x338(%rbp), %rcx
callq 0x8d82
leaq -0x168(%rbp), %rax
movsd (%rax), %xmm0
movsd 0x10(%rax), %xmm1
movq 0x30(%rax), %rax
movsd %xmm0, 0x20(%r15)
movq %rax, 0x50(%r15)
movsd %xmm1, 0x30(%r15)
movq %r15, -0x30(%rbp)
movl $0x1, %eax
movl %eax, (%r15)
leaq 0x68(%rbp), %rax
movl (%rax), %r15d
movl 0x48(%rax), %r13d
movl %r13d, %eax
xorl %ebx, %eax
leal (%rax,%r15,2), %eax
cltq
shlq $0x3, %rax
leaq (%rax,%rax,2), %rdi
callq 0x1140
leaq 0x68(%rbp), %rcx
movl 0x20(%rcx), %edx
movq 0x28(%rcx), %rcx
movl %r13d, (%rsp)
movq %rax, %r13
movq -0x98(%rbp), %rdi
movq %r14, %rsi
movq %rax, %r8
movl %r15d, %r9d
callq 0x4ef6
leaq (%r12,%r12), %r15
leaq 0x10(%rbp), %rax
movl 0x48(%rax), %r14d
xorl %r14d, %ebx
addl %r15d, %ebx
movslq %ebx, %rax
shlq $0x3, %rax
leaq (%rax,%rax,2), %rdi
callq 0x1140
leaq 0x10(%rbp), %rbx
movl 0x20(%rbx), %edx
movq 0x28(%rbx), %rcx
movl %r14d, (%rsp)
movq -0x38(%rbp), %rdi
movq -0x48(%rbp), %rsi
movq %rax, -0x58(%rbp)
movq %rax, %r8
movl %r12d, %r9d
callq 0x4ef6
movq -0x68(%rbp), %r10
leaq -0x3(,%r12,2), %rax
addl $-0x4, %r15d
movq %r15, -0xd0(%rbp)
movslq 0x48(%rbx), %rcx
movq %rax, %rdx
subq %rcx, %rdx
movq %rdx, -0xe0(%rbp)
leaq 0x68(%rbp), %rdx
movq 0x8(%rdx), %rdx
movq %rdx, -0x98(%rbp)
leaq -0x280(%rbp), %rsi
movsd (%rsi), %xmm0
movsd %xmm0, -0xc0(%rbp)
movsd 0x10(%rsi), %xmm0
movsd %xmm0, -0xb8(%rbp)
movl 0x30(%rsi), %edx
movl %edx, -0x6c(%rbp)
movl 0x34(%rsi), %edx
movl %edx, -0x8c(%rbp)
movq 0x30(%rbx), %rdx
movq %rdx, -0x78(%rbp)
movslq %eax, %rdx
subl %ecx, %eax
movq %rax, -0x108(%rbp)
movq %rcx, -0xc8(%rbp)
subq %rcx, %rdx
movq %rdx, -0xd8(%rbp)
movl $0x1, -0x3c(%rbp)
movl $0x1, -0x40(%rbp)
movq %r12, -0xa0(%rbp)
movq %r13, -0x88(%rbp)
movq -0xc8(%rbp), %rax
cmpl -0xd0(%rbp), %eax
jge 0xd1e4
movl $0x2, %r13d
movl $0x1, %r14d
movl $0x20, %ebx
leaq 0x1(%r14), %rax
movq %rax, -0xe8(%rbp)
cmpq -0xe0(%rbp), %rax
movq %r13, -0xf8(%rbp)
movq %rbx, -0xf0(%rbp)
jge 0xd1bb
leaq (%r14,%r14), %rax
movq %rax, -0x80(%rbp)
movq %r14, %rcx
shlq $0x4, %rcx
movq -0x78(%rbp), %rax
movq %rcx, -0x100(%rbp)
addq %rcx, %rax
movq %rax, -0xa8(%rbp)
movq %rbx, -0x48(%rbp)
movq %r14, -0x38(%rbp)
movl $0xb, %ecx
movq %rsp, %rdi
movq %r14, %rax
leaq 0x10(%rbp), %r14
movq %r14, %rsi
rep  movsq (%rsi), %es:(%rdi)
movl %eax, %edi
movl %r13d, %esi
callq 0xa4c5
xorl %r15d, %r15d
movb $0x1, %bl
testl %eax, %eax
je 0xcc8a
movl $0xb, %ecx
movq %rsp, %rdi
movq %r14, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq -0x1c0(%rbp), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0xa621
leaq 0xc0(%rbp), %rax
cmpl $0x736579, 0xe9e(%rax)  # imm = 0x736579
je 0xc960
movq -0x38(%rbp), %r14
jmp 0xc9bc
movl $0xb, %ecx
movq %rsp, %rdi
movq %r14, %rsi
rep  movsq (%rsi), %es:(%rdi)
movq -0x38(%rbp), %r14
movl %r14d, %edi
movl %r13d, %esi
movq -0x58(%rbp), %rdx
movq -0x88(%rbp), %rcx
callq 0x8016
testl %eax, %eax
movq -0x68(%rbp), %r10
je 0xd19c
movl $0xb, %ecx
movq %rsp, %rdi
leaq 0x10(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movl %r14d, %edi
movl %r13d, %esi
movq -0x58(%rbp), %rdx
movq -0x88(%rbp), %rcx
callq 0x8691
movl %eax, -0x4c(%rbp)
leaq -0x1c0(%rbp), %rsi
movl %r14d, %edx
movl %r13d, %ecx
callq 0x8e8a
leaq 0x4bc(%rbp), %rcx
movzwl (%rcx), %eax
xorl $0x736c, %eax           # imm = 0x736C
movzbl 0x2(%rcx), %ecx
orw %ax, %cx
jne 0xca08
movl $0xb, %ecx
movq %rsp, %rdi
leaq 0x68(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq -0x1c0(%rbp), %rdi
xorl %esi, %esi
movl $0x1, %edx
callq 0xb80c
movq -0x1b8(%rbp), %rdi
movq -0x98(%rbp), %rsi
movq -0xa0(%rbp), %rdx
leaq -0x168(%rbp), %rcx
callq 0x8d82
movl $0x1, %edx
movl %edx, -0x50(%rbp)
movq -0x68(%rbp), %r10
movslq (%r10), %rax
imulq $0xa8, %rax, %rax
movsd -0xc0(%rbp), %xmm0
movq -0x30(%rbp), %rdi
movsd %xmm0, 0x20(%rdi,%rax)
movl -0x6c(%rbp), %esi
movl %esi, 0x50(%rdi,%rax)
movsd -0xb8(%rbp), %xmm0
movsd %xmm0, 0x30(%rdi,%rax)
movl -0x8c(%rbp), %ecx
movl %ecx, 0x54(%rdi,%rax)
movl %edx, (%rdi,%rax)
movl -0x138(%rbp), %ecx
movl %esi, %eax
subl %ecx, %eax
cmpl %edx, %eax
leaq 0x10(%rbp), %r14
jne 0xcb68
movq -0x60(%rbp), %rax
cmpl $0x1, (%rax)
jne 0xcb68
movq 0x30(%r14), %rax
movq -0x80(%rbp), %rdx
movq -0x8(%rax,%rdx,8), %rsi
movq -0x48(%rbp), %rdx
movq -0x8(%rax,%rdx), %rdx
cmpq %rdx, %rsi
je 0xcace
movq -0x48(%rbp), %rdi
movq -0x10(%rax,%rdi), %rdi
cmpq %rdi, %rsi
je 0xcace
movq -0x80(%rbp), %r8
cmpq %rdi, -0x10(%rax,%r8,8)
jne 0xcb68
leaq (,%r13,2), %rdi
movsd -0x168(%rbp), %xmm0
movsd -0x158(%rbp), %xmm1
movl -0x134(%rbp), %r8d
movslq (%r10), %r9
imulq $0xa8, %r9, %r9
movq -0x30(%rbp), %r15
movl %r13d, 0x8(%r15,%r9)
movq -0x38(%rbp), %r11
movl %r11d, 0x4(%r15,%r9)
movsd %xmm1, 0x30(%r15,%r9)
movsd %xmm0, 0x20(%r15,%r9)
movl %ecx, 0x50(%r15,%r9)
movl %r8d, 0x54(%r15,%r9)
movslq (%r10), %rcx
imulq $0xa8, %rcx, %rcx
movl %esi, 0x80(%r15,%rcx)
movq -0x80(%rbp), %rcx
movl -0x10(%rax,%rcx,8), %ecx
movslq (%r10), %rsi
imulq $0xa8, %rsi, %rsi
movl %ecx, 0x84(%r15,%rsi)
movslq (%r10), %rcx
imulq $0xa8, %rcx, %rcx
movl %edx, 0x88(%r15,%rcx)
leaq (%rax,%rdi,8), %rax
jmp 0xcc3d
cmpl $0x0, -0x40(%rbp)
sete %al
cmpl $0x1, -0x4c(%rbp)
sete %cl
movq -0x60(%rbp), %rdx
cmpl $0x0, (%rdx)
jne 0xcc8a
orb %al, %cl
je 0xcc8a
movslq (%r10), %rax
imulq $0xa8, %rax, %rdx
addq -0x30(%rbp), %rdx
movl $0xc, %ecx
movq %rsp, %rdi
leaq -0x168(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movl $0x0, 0x60(%rsp)
xorl %r15d, %r15d
leaq -0x50(%rbp), %rdi
leaq 0x4bc(%rbp), %rsi
movq -0x38(%rbp), %rcx
movl %r13d, %r8d
xorl %r9d, %r9d
movq %r10, %r14
callq 0xa331
testl %eax, %eax
je 0xcc86
leaq 0x10(%rbp), %rsi
movq 0x30(%rsi), %rax
movq -0x100(%rbp), %rdi
movl -0x8(%rax,%rdi), %ecx
movslq (%r14), %rdx
imulq $0xa8, %rdx, %rdx
movq -0x30(%rbp), %r8
movl %ecx, 0x80(%r8,%rdx)
movl -0x10(%rax,%rdi), %ecx
movslq (%r14), %rdx
imulq $0xa8, %rdx, %rdx
movl %ecx, 0x84(%r8,%rdx)
movq -0x48(%rbp), %rdx
movl -0x8(%rax,%rdx), %ecx
addq %rdx, %rax
movslq (%r14), %rdx
imulq $0xa8, %rdx, %rdx
movl %ecx, 0x88(%r8,%rdx)
movq %r14, %r10
movq %rsi, %r14
movl -0x10(%rax), %eax
movslq (%r10), %rcx
imulq $0xa8, %rcx, %rcx
movq -0x30(%rbp), %rdx
movl %eax, 0x8c(%rdx,%rcx)
movslq (%r10), %rax
imulq $0xa8, %rax, %rax
addq %rdx, %rax
movl $0xb, %ecx
movq %rsp, %rdi
movq %r14, %rsi
rep  movsq (%rsi), %es:(%rdi)
movq %rax, %rdi
movq -0x58(%rbp), %rsi
callq 0xa1f8
movl $0x1, %r15d
xorl %ebx, %ebx
jmp 0xcc8a
leaq 0x10(%rbp), %r14
movl $0xb, %ecx
movq %rsp, %rdi
movq %r14, %rsi
rep  movsq (%rsi), %es:(%rdi)
movl %r13d, %edi
movq -0x38(%rbp), %rsi
callq 0xa4c5
testl %eax, %eax
je 0xcd00
movl $0xb, %ecx
movq %rsp, %rdi
leaq -0x1c0(%rbp), %r15
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq -0x2d8(%rbp), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0xa621
movl $0xb, %ecx
movq %rsp, %rdi
movq %r14, %rsi
rep  movsq (%rsi), %es:(%rdi)
movq %r15, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0xa621
leaq 0xc0(%rbp), %rax
cmpl $0x736579, 0xe9e(%rax)  # imm = 0x736579
je 0xcd0d
movq -0x38(%rbp), %r14
jmp 0xcd7f
movq -0x68(%rbp), %r10
movq -0x38(%rbp), %r14
jmp 0xd194
movl %ebx, -0xb0(%rbp)
movl $0xb, %ecx
movq %rsp, %rdi
movq %r14, %rsi
rep  movsq (%rsi), %es:(%rdi)
movl %r13d, %edi
movq -0x38(%rbp), %rbx
movl %ebx, %esi
movq -0x58(%rbp), %r12
movq %r12, %rdx
movq -0x88(%rbp), %r15
movq %r15, %rcx
callq 0x8016
testl %eax, %eax
je 0xd07e
movl $0xb, %ecx
movq %rsp, %rdi
movq %r14, %rsi
rep  movsq (%rsi), %es:(%rdi)
movl %r13d, %edi
movl %ebx, %esi
movq %r12, %rdx
movq %r15, %rcx
callq 0x8691
testl %eax, %eax
movl $0x2, %eax
movl -0x4c(%rbp), %ecx
cmovnel %eax, %ecx
movl %ecx, -0x4c(%rbp)
movq %rbx, %r14
movl -0xb0(%rbp), %ebx
leaq -0x1c0(%rbp), %rsi
movl %r13d, %edx
movl %r14d, %ecx
callq 0x8e8a
leaq 0x4bc(%rbp), %rcx
movzwl (%rcx), %eax
xorl $0x736c, %eax           # imm = 0x736C
movzbl 0x2(%rcx), %ecx
orw %ax, %cx
jne 0xcdcb
movl $0xb, %ecx
movq %rsp, %rdi
leaq 0x68(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq -0x1c0(%rbp), %rdi
xorl %esi, %esi
movl $0x1, %edx
callq 0xb80c
movq -0x1b8(%rbp), %r15
movq %r15, %rdi
movq -0x98(%rbp), %rsi
movq -0xa0(%rbp), %r12
movl %r12d, %edx
leaq -0x168(%rbp), %rcx
callq 0x8d82
movq -0x2d0(%rbp), %rsi
testq %rsi, %rsi
je 0xce12
movq %r15, %rdi
movl %r12d, %edx
leaq -0x220(%rbp), %rcx
callq 0x8d82
jmp 0xce2a
leaq 0x8bc1(%rip), %rdi      # 0x159da
xorl %eax, %eax
callq 0x1030
movl $0xf423f, -0x1f0(%rbp)  # imm = 0xF423F
movl $0x1, -0x50(%rbp)
testb %bl, %bl
movq -0x68(%rbp), %r10
je 0xce8a
movslq (%r10), %rax
imulq $0xa8, %rax, %rax
movsd -0xc0(%rbp), %xmm0
movq -0x30(%rbp), %rdx
movsd %xmm0, 0x20(%rdx,%rax)
movl -0x6c(%rbp), %ecx
movl %ecx, 0x50(%rdx,%rax)
movsd -0xb8(%rbp), %xmm0
movsd %xmm0, 0x30(%rdx,%rax)
movl -0x8c(%rbp), %ecx
movl %ecx, 0x54(%rdx,%rax)
movl $0x1, (%rdx,%rax)
xorl %r15d, %r15d
xorl %ecx, %ecx
xorl %r9d, %r9d
xorl %eax, %eax
jmp 0xcf52
cmpl $0x1, -0xac(%rbp)
jne 0xcece
cmpl $0x0, -0x1f0(%rbp)
jne 0xcece
movl -0x138(%rbp), %eax
movslq (%r10), %rcx
imulq $0xa8, %rcx, %rcx
movq -0x30(%rbp), %rdx
cmpl 0x50(%rdx,%rcx), %eax
jne 0xcece
movb $0x1, %al
xorl %ecx, %ecx
movl $0x1, %r15d
xorl %r9d, %r9d
movl $0x1, %r8d
jmp 0xcf55
movslq (%r10), %rax
imulq $0xa8, %rax, %rdx
xorl %ecx, %ecx
movsd -0x158(%rbp), %xmm0
movq -0x30(%rbp), %rax
subsd 0x30(%rax,%rdx), %xmm0
andpd 0x818c(%rip), %xmm0     # 0x15080
movlpd %xmm0, 0x48(%rax,%rdx)
movl $0x1, %r15d
cmpl $0x1, -0x3c(%rbp)
jne 0xce80
movsd 0x8156(%rip), %xmm1     # 0x15068
ucomisd %xmm0, %xmm1
movl $0x0, %r9d
movl $0x0, %eax
movl $0x0, %r8d
jb 0xcf55
movq -0x30(%rbp), %rax
addq %rdx, %rax
addq $0x20, %rax
movl 0x30(%rax), %eax
xorl %r15d, %r15d
cmpl -0x138(%rbp), %eax
setle %r15b
movl $0x2, %r9d
subl %r15d, %r9d
xorl %eax, %eax
movl %r15d, %ecx
xorl %r8d, %r8d
testb %cl, %cl
jne 0xd194
movl -0x138(%rbp), %edx
movl -0x6c(%rbp), %ecx
subl %edx, %ecx
cmpl $0x1, %ecx
jne 0xd06c
movq -0x60(%rbp), %rcx
cmpl $0x1, (%rcx)
jne 0xd06c
movq -0x78(%rbp), %rsi
movq -0x80(%rbp), %rcx
movq -0x8(%rsi,%rcx,8), %rcx
movq -0x48(%rbp), %rdi
movq -0x8(%rsi,%rdi), %rsi
cmpq %rsi, %rcx
je 0xcfbe
movq -0x78(%rbp), %rdi
movq -0x48(%rbp), %r11
movq -0x10(%rdi,%r11), %rdi
cmpq %rdi, %rcx
je 0xcfbe
movq -0x78(%rbp), %r11
movq -0x80(%rbp), %rbx
cmpq %rdi, -0x10(%r11,%rbx,8)
jne 0xd06c
cmpl $0x1, 0xd18f(%rip)      # 0x1a154
sete %dil
andb %dil, %al
cmpb $0x1, %al
jne 0xd194
movsd -0x168(%rbp), %xmm0
movsd -0x158(%rbp), %xmm1
movl -0x134(%rbp), %eax
movslq (%r10), %rdi
imulq $0xa8, %rdi, %rdi
movq -0x30(%rbp), %r8
movl %r14d, 0x8(%r8,%rdi)
movl %r13d, 0x4(%r8,%rdi)
movsd %xmm1, 0x30(%r8,%rdi)
movsd %xmm0, 0x20(%r8,%rdi)
movl %edx, 0x50(%r8,%rdi)
movl %eax, 0x54(%r8,%rdi)
movslq (%r10), %rax
imulq $0xa8, %rax, %rax
movl %esi, 0x80(%r8,%rax)
movq -0x78(%rbp), %rax
movq -0x48(%rbp), %rdx
movl -0x10(%rax,%rdx), %eax
movslq (%r10), %rdx
imulq $0xa8, %rdx, %rdx
movl %eax, 0x84(%r8,%rdx)
movslq (%r10), %rax
imulq $0xa8, %rax, %rax
movl %ecx, 0x88(%r8,%rax)
movq -0x58(%rbp), %rdx
movq -0xa8(%rbp), %rsi
jmp 0xd144
movq -0x60(%rbp), %rcx
cmpl $0x0, (%rcx)
je 0xd08a
testb %al, %al
jne 0xd0a2
jmp 0xd194
movq -0x68(%rbp), %r10
movq %rbx, %r14
jmp 0xd19c
cmpl $0x0, -0x40(%rbp)
sete %cl
cmpl $0x2, -0x4c(%rbp)
sete %dl
orb %cl, %dl
orb %al, %dl
je 0xd194
movslq (%r10), %rax
imulq $0xa8, %rax, %rdx
addq -0x30(%rbp), %rdx
movl $0xc, %ecx
movq %rsp, %rdi
leaq -0x168(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movl %r8d, 0x60(%rsp)
leaq -0x50(%rbp), %rdi
leaq 0x4bc(%rbp), %rsi
movl %r13d, %ecx
movl %r14d, %r8d
movq %r10, %r14
callq 0xa331
testl %eax, %eax
je 0xd1b3
movq -0x78(%rbp), %rdx
movq -0x48(%rbp), %rsi
movl -0x8(%rdx,%rsi), %eax
movslq (%r14), %rcx
imulq $0xa8, %rcx, %rcx
movq -0x30(%rbp), %rdi
movl %eax, 0x80(%rdi,%rcx)
movl -0x10(%rdx,%rsi), %eax
movslq (%r14), %rcx
imulq $0xa8, %rcx, %rcx
movl %eax, 0x84(%rdi,%rcx)
movq -0xa8(%rbp), %rsi
movl -0x8(%rsi), %eax
movslq (%r14), %rcx
imulq $0xa8, %rcx, %rcx
movl %eax, 0x88(%rdi,%rcx)
movq %r14, %r10
movq -0x58(%rbp), %rdx
movq -0x38(%rbp), %r14
movq %rsi, -0xa8(%rbp)
movl -0x10(%rsi), %eax
movslq (%r10), %rcx
imulq $0xa8, %rcx, %rcx
movq -0x30(%rbp), %rsi
movl %eax, 0x8c(%rsi,%rcx)
movslq (%r10), %rax
imulq $0xa8, %rax, %rax
addq %rsi, %rax
movl $0xb, %ecx
movq %rsp, %rdi
leaq 0x10(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movq %rax, %rdi
movq %rdx, %rsi
callq 0xa1f8
movq -0x68(%rbp), %r10
movl $0x1, %r15d
testl %r15d, %r15d
je 0xd19c
incl (%r10)
incq %r13
addq $0x10, -0x48(%rbp)
cmpl %r13d, -0x108(%rbp)
jg 0xc8fd
jmp 0xd1bb
movq %r14, %r10
jmp 0xcd04
movq -0xf8(%rbp), %r13
incq %r13
movq -0xf0(%rbp), %rbx
addq $0x10, %rbx
movq -0xe8(%rbp), %r14
cmpq -0xd8(%rbp), %r14
jl 0xc8ab
movl (%r10), %ecx
testl %ecx, %ecx
sete %dl
movl -0x3c(%rbp), %edi
cmpl $0x1, %edi
sete %al
andb %dl, %al
movl $0x0, %esi
cmovnel %esi, %edi
movl %edi, -0x3c(%rbp)
cmpl $0x1, -0x40(%rbp)
sete %sil
andb %dl, %sil
cmpb $0x1, %sil
jne 0xd243
movl $0x1, -0x40(%rbp)
movq -0x60(%rbp), %rdx
cmpl $0x0, (%rdx)
movq -0x88(%rbp), %r13
movq -0xa0(%rbp), %r12
jne 0xd251
movl $0x0, -0x40(%rbp)
movl $0x1, -0x3c(%rbp)
movb $0x1, %al
jmp 0xd251
movq -0x88(%rbp), %r13
movq -0xa0(%rbp), %r12
testl %ecx, %ecx
jne 0xd271
movq -0x60(%rbp), %rcx
cmpl $0x1, (%rcx)
jne 0xd271
movq -0x60(%rbp), %rax
movl $0x0, (%rax)
movl $0x1, -0x3c(%rbp)
movb $0x1, %al
testb %al, %al
jne 0xc887
movl $0xb, %ecx
movq %rsp, %rdi
leaq 0x10(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movq -0x58(%rbp), %rdi
movq %r10, %rbx
callq 0x7a5a
movl $0xb, %ecx
movq %rsp, %rdi
leaq 0x68(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movq %r13, %rdi
callq 0x7a5a
leaq -0x168(%rbp), %rdi
movl %r12d, %esi
callq 0xb9fb
leaq -0x280(%rbp), %rdi
movl %r12d, %esi
callq 0xb9fb
leaq -0x1c0(%rbp), %rdi
movl (%rdi), %esi
callq 0xb0f6
movl (%rbx), %eax
addq $0x378, %rsp            # imm = 0x378
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq