// File: ChnMasterOG[P]KmerGO2/kmergo/kmer_union.cpp
// Function: get_Son_Matrix(unsigned short, KmerGO_parameters, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>, std::vector<float, std::allocator<float>>)
void get_Son_Matrix(uint16_t Nprocess, KmerGO_parameters p, std::vector<std::string> kmerdb_list, 
	std::vector<std::string> beacon_kmer, std::vector<float> ALLfcounter)
{
	uint32 i;
	uint32 files_number = kmerdb_list.size();
	uint32 _kmer_length;

	CKMCFile* kmer_data_base = new CKMCFile[files_number];
	FILE* out_file;
	std::string out_file_name = joinPath(p.matrixes_path, "son_matrix_" + std::to_string(Nprocess) + ".txt");

	/* open k-mer data base */
	for (i = 0; i < files_number; i++)
	{
		if (!kmer_data_base[i].OpenForListing(joinPath(p.kmercountings_path, kmerdb_list[i])))
		{
			mtx.lock();
			union_err_number = -11;
			mtx.unlock();
			std::cout << "Thread-" << std::to_string(Nprocess) << "[Error]: Can not open some k-mer database in at least one thread." << std::endl;
			return;
		}
	}

	/* open the output file */
	if ((out_file = fopen(out_file_name.c_str(), "wb")) == NULL)
	{
		mtx.lock();
		union_err_number = -12;
		mtx.unlock();
		std::cout << "Thread-" << std::to_string(Nprocess) << "[Error]: Can not open output files in at least one thread." << std::endl;
		return;
	}
	setvbuf(out_file, NULL, _IOFBF, 1 << 24);

	/* get information from the k-mer database */
	_kmer_length = kmer_data_base[0].KmerLength();
	CKmerAPI kmer_object(_kmer_length);
	CKmerAPI beacon_start_kmer_object(_kmer_length);
	CKmerAPI beacon_end_kmer_object(_kmer_length);
	CKmerAPI minimum_kmer_object(_kmer_length);
	CKmerAPI maximum_kmer_object(_kmer_length);
	uint64 counter;

	/* create beacon k-mer object: start-kmer index is 0; end-kmer index is 1 */
	beacon_start_kmer_object.from_string(beacon_kmer[0]);
	beacon_end_kmer_object.from_string(beacon_kmer[1]);

	/* create minimum/maximum k-mer object */
	std::string temp_str = "";
	for (i = 0; i < _kmer_length - 1; i++) temp_str += "A";
	minimum_kmer_object.from_string(temp_str);	// is less than "A"*_kmer_length (modified kmer_api "operator<" function)
	temp_str = "";
	for (i = 0; i < _kmer_length; i++) temp_str += "T";
	maximum_kmer_object.from_string(temp_str);

	/* write head text */
	fwrite("k-mer", 1, 5, out_file);
	for (i = 0; i < files_number; i++)
	{
		fwrite("\t", 1, 1, out_file);
		fwrite(kmerdb_list[i].c_str(), 1, kmerdb_list[i].length(), out_file);
	}
	fwrite("\n", 1, 1, out_file);
	
	/* jump to corresponding k-mer and build k-mer loser tree */
	KmerLoserTree kmer_losertree(files_number, _kmer_length);
	uint32 end_number = 0;
	bool start_flag;
	for (i = 0; i < files_number; i++)
	{
		start_flag = false;
		while (kmer_data_base[i].ReadNextKmer(kmer_object, counter))
		{
			if (!kmer_object.operator<(beacon_start_kmer_object))
			{
				kmer_losertree.kmer_list[i].operator=(kmer_object);
				kmer_losertree.counter_list[i] = counter;
				start_flag = true;
				break;
			}
		}
		if (!start_flag || !kmer_object.operator<(beacon_end_kmer_object))	// no next k-mer
		{
			end_number++;
			kmer_losertree.kmer_list[i].operator=(maximum_kmer_object);
			kmer_losertree.counter_list[i] = 0;
		}
		else
		{
			mtx.lock();
			progress++;
			mtx.unlock();
		}
	}
	if (end_number == files_number)	// end of running
	{
		for (i = 0; i < files_number; i++) kmer_data_base[i].Close();
		fclose(out_file);
		delete[] kmer_data_base;
		return;
	}
	kmer_losertree.kmer_list[files_number].operator=(minimum_kmer_object);
	kmer_losertree.build();

	/* prepare variables for main loop */
	uint32 min_index;
	uint32 no_zero_counter[2] = { 0, 0 };
	uint32 no_zero_counter_thr[2] = { 1, 1 };
	std::vector<std::string> zero_matrix;
	std::vector<std::string> write_matrix;
	CKmerAPI min_kmer(_kmer_length);
	char temp_cstr[1024];

	if (p.single_step == false)
	{
		no_zero_counter_thr[0] = p.groupA_number * 0.2;
		if (!p.groupA_name.compare("")) no_zero_counter_thr[1] = 1;
		else no_zero_counter_thr[1] = (files_number - p.groupA_number) * 0.2;
	}

	for (i = 0; i < files_number; i++)
	{
		zero_matrix.push_back("\t0");
		write_matrix.push_back("\t0");
	}

	/* main loop */
	while (true)
	{
		min_index = kmer_losertree.getMIN();
		sprintf(temp_cstr, "\t%.4f", (double)kmer_losertree.counter_list[min_index] / ALLfcounter[min_index]);	// normalization
		if (min_kmer.operator==(kmer_losertree.kmer_list[min_index]))	// new k-mer is equal to last k-mer
		{
			write_matrix[min_index] = temp_cstr;
		}
		else
		{
			if (no_zero_counter[0] >= no_zero_counter_thr[0] || no_zero_counter[1] >= no_zero_counter_thr[1])	// write last line
			{
				min_kmer.to_string(temp_str);
				fwrite(temp_str.c_str(), 1, _kmer_length, out_file);
				for (i = 0; i < files_number; i++) fwrite(write_matrix[i].c_str(), 1, write_matrix[i].length(), out_file);
				fwrite("\n", 1, 1, out_file);
			}
			no_zero_counter[0] = no_zero_counter[1] = 0;
			write_matrix = zero_matrix;
			write_matrix[min_index] = temp_cstr;
		}
		if (p.single_step == false)	// count no zero numbers
		{
			if (!p.groupA_name.compare("")) no_zero_counter[0]++;
			else if(!p.trait_information_map[kmerdb_list[min_index]].compare(p.groupA_name)) no_zero_counter[0]++;
			else no_zero_counter[1]++;
		}
		else no_zero_counter[0]++;
		min_kmer.operator=(kmer_losertree.kmer_list[min_index]);
		if (!kmer_data_base[min_index].ReadNextKmer(kmer_object, counter) || !kmer_object.operator<(beacon_end_kmer_object))	// no next k-mer
		{
			end_number++;
			kmer_object = maximum_kmer_object;
			counter = 0;
		}
		else
		{
			mtx.lock();
			progress++;	// update progress
			mtx.unlock();
		}
		if (end_number == files_number)	// end of running
		{
			if (no_zero_counter[0] >= no_zero_counter_thr[0] || no_zero_counter[1] >= no_zero_counter_thr[1])	// write last line
			{
				min_kmer.to_string(temp_str);
				fwrite(temp_str.c_str(), 1, _kmer_length, out_file);
				for (i = 0; i < files_number; i++) fwrite(write_matrix[i].c_str(), 1, write_matrix[i].length(), out_file);
				fwrite("\n", 1, 1, out_file);
			}
			break;
		}
		kmer_losertree.kmer_list[min_index].operator=(kmer_object);
		kmer_losertree.counter_list[min_index] = counter;
		kmer_losertree.adjust(min_index);
	}

	/* close files */
	for (i = 0; i < files_number; i++) kmer_data_base[i].Close();
	fclose(out_file);

	delete[] kmer_data_base;

	return;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x8e0, %rsp            # imm = 0x8E0
movq %r8, -0x790(%rbp)
movq %rcx, -0x788(%rbp)
movq %rdx, -0x778(%rbp)
movq %rsi, -0x780(%rbp)
movl %edi, %eax
movq -0x778(%rbp), %rdi
movw %ax, -0x2(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdi, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
callq 0x4072c0
movl %eax, -0x30(%rbp)
movl -0x30(%rbp), %eax
movq %rax, -0x768(%rbp)
movl $0xc0, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
addq $0x8, %rdi
setb %al
orb %al, %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
movq %rdi, -0x770(%rbp)
callq 0x42fb90
movq %rax, %rcx
movq -0x768(%rbp), %rax
movq %rcx, -0x760(%rbp)
movq %rax, (%rcx)
addq $0x8, %rcx
movq %rcx, -0x758(%rbp)
cmpq $0x0, %rax
je 0x408e8a
movq -0x758(%rbp), %rax
movq -0x768(%rbp), %rcx
imulq $0xc0, %rcx, %rdx
movq %rax, %rcx
addq %rdx, %rcx
movq %rcx, -0x7a0(%rbp)
movq %rax, -0x798(%rbp)
movq -0x798(%rbp), %rdi
movq %rdi, -0x7a8(%rbp)
callq 0x424400
jmp 0x408e6a
movq -0x7a0(%rbp), %rcx
movq -0x7a8(%rbp), %rax
addq $0xc0, %rax
cmpq %rcx, %rax
movq %rax, -0x798(%rbp)
jne 0x408e55
movq -0x780(%rbp), %rsi
movq -0x758(%rbp), %rax
movq %rax, -0x40(%rbp)
addq $0x60, %rsi
leaq -0x98(%rbp), %rdi
callq 0x4a15e0
movzwl -0x2(%rbp), %esi
leaq -0xf8(%rbp), %rdi
callq 0x4075b0
jmp 0x408ebe
leaq 0x1ad3cb(%rip), %rsi    # 0x5b6290
leaq -0xd8(%rbp), %rdi
leaq -0xf8(%rbp), %rdx
callq 0x4077b0
jmp 0x408eda
leaq 0x1ad3bb(%rip), %rdx    # 0x5b629c
leaq -0xb8(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0x407350
jmp 0x408ef6
leaq -0x78(%rbp), %rdi
leaq -0x98(%rbp), %rsi
leaq -0xb8(%rbp), %rdx
callq 0x407470
jmp 0x408f0f
leaq -0xb8(%rbp), %rdi
callq 0x49efd0
leaq -0xd8(%rbp), %rdi
callq 0x49efd0
leaq -0xf8(%rbp), %rdi
callq 0x49efd0
leaq -0x98(%rbp), %rdi
callq 0x49efd0
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x30(%rbp), %eax
jae 0x409243
movq -0x780(%rbp), %rsi
movq -0x40(%rbp), %rax
movl -0x2c(%rbp), %ecx
leaq (%rcx,%rcx,2), %rcx
shlq $0x6, %rcx
addq %rcx, %rax
movq %rax, -0x7b0(%rbp)
addq $0x40, %rsi
leaq -0x138(%rbp), %rdi
callq 0x4a15e0
jmp 0x408f84
movq -0x778(%rbp), %rdi
movl -0x2c(%rbp), %eax
movl %eax, %esi
callq 0x4072e0
movq %rax, %rsi
leaq -0x158(%rbp), %rdi
callq 0x4a15e0
jmp 0x408fa6
leaq -0x118(%rbp), %rdi
leaq -0x138(%rbp), %rsi
leaq -0x158(%rbp), %rdx
callq 0x407470
jmp 0x408fc2
movq -0x7b0(%rbp), %rdi
leaq -0x118(%rbp), %rsi
callq 0x424150
movb %al, -0x7b1(%rbp)
jmp 0x408fdd
movb -0x7b1(%rbp), %al
xorb $-0x1, %al
movb %al, -0x7b2(%rbp)
leaq -0x118(%rbp), %rdi
callq 0x49efd0
leaq -0x158(%rbp), %rdi
callq 0x49efd0
leaq -0x138(%rbp), %rdi
callq 0x49efd0
movb -0x7b2(%rbp), %al
testb $0x1, %al
jne 0x40901e
jmp 0x409233
leaq 0x231663(%rip), %rdi    # 0x63a688
callq 0x40b4f0
jmp 0x40902c
movw $0xfff5, 0x231645(%rip) # imm = 0xFFF5
leaq 0x23164c(%rip), %rdi    # 0x63a688
callq 0x40b520
jmp 0x409043
movq $0x1b90900, %rdi        # imm = 0x1B90900
leaq 0x1ad250(%rip), %rsi    # 0x5b62a1
callq 0x498c00
movq %rax, -0x7c0(%rbp)
jmp 0x40905f
movzwl -0x2(%rbp), %esi
leaq -0x178(%rbp), %rdi
callq 0x4075b0
jmp 0x409071
movq -0x7c0(%rbp), %rdi
leaq -0x178(%rbp), %rsi
callq 0x4a1880
movq %rax, -0x7c8(%rbp)
jmp 0x40908d
movq -0x7c8(%rbp), %rdi
leaq 0x1ad20e(%rip), %rsi    # 0x5b62a9
callq 0x498c00
movq %rax, -0x7d0(%rbp)
jmp 0x4090a9
movq -0x7d0(%rbp), %rdi
movq $0x4984e0, %rsi         # imm = 0x4984E0
callq 0x4976f0
jmp 0x4090be
leaq -0x178(%rbp), %rdi
callq 0x49efd0
movl $0x1, -0x17c(%rbp)
jmp 0x40a2ae
movq -0x758(%rbp), %rcx
movq %rax, %rsi
movq -0x7a8(%rbp), %rax
movq %rsi, -0x48(%rbp)
movl %edx, -0x4c(%rbp)
cmpq %rax, %rcx
movq %rax, -0x7d8(%rbp)
je 0x409131
movq -0x7d8(%rbp), %rdi
addq $-0xc0, %rdi
movq %rdi, -0x7e0(%rbp)
callq 0x424450
movq -0x758(%rbp), %rcx
movq -0x7e0(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x7d8(%rbp)
jne 0x4090fd
movq -0x770(%rbp), %rsi
movq -0x760(%rbp), %rdi
callq 0x42ecb0
jmp 0x40a2c9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x4091a3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x409197
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x40918b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0xb8(%rbp), %rdi
callq 0x49efd0
leaq -0xd8(%rbp), %rdi
callq 0x49efd0
leaq -0xf8(%rbp), %rdi
callq 0x49efd0
leaq -0x98(%rbp), %rdi
callq 0x49efd0
jmp 0x40a2c9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x40a2c0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x409205
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x4091f9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x118(%rbp), %rdi
callq 0x49efd0
leaq -0x158(%rbp), %rdi
callq 0x49efd0
leaq -0x138(%rbp), %rdi
callq 0x49efd0
jmp 0x40a2c0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x178(%rbp), %rdi
callq 0x49efd0
jmp 0x40a2c0
jmp 0x409235
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x408f46
leaq -0x78(%rbp), %rdi
callq 0x4a0a10
movq %rax, %rdi
leaq 0x1ad095(%rip), %rsi    # 0x5b62eb
callq 0x5019f0
movq %rax, -0x7e8(%rbp)
jmp 0x409264
movq -0x7e8(%rbp), %rax
movq %rax, -0x58(%rbp)
cmpq $0x0, %rax
jne 0x409351
leaq 0x231408(%rip), %rdi    # 0x63a688
callq 0x40b4f0
jmp 0x409287
movw $0xfff4, 0x2313ea(%rip) # imm = 0xFFF4
leaq 0x2313f1(%rip), %rdi    # 0x63a688
callq 0x40b520
jmp 0x40929e
movq $0x1b90900, %rdi        # imm = 0x1B90900
leaq 0x1acff5(%rip), %rsi    # 0x5b62a1
callq 0x498c00
movq %rax, -0x7f0(%rbp)
jmp 0x4092ba
movzwl -0x2(%rbp), %esi
leaq -0x1a0(%rbp), %rdi
callq 0x4075b0
jmp 0x4092cc
movq -0x7f0(%rbp), %rdi
leaq -0x1a0(%rbp), %rsi
callq 0x4a1880
movq %rax, -0x7f8(%rbp)
jmp 0x4092e8
movq -0x7f8(%rbp), %rdi
leaq 0x1acff8(%rip), %rsi    # 0x5b62ee
callq 0x498c00
movq %rax, -0x800(%rbp)
jmp 0x409304
movq -0x800(%rbp), %rdi
movq $0x4984e0, %rsi         # imm = 0x4984E0
callq 0x4976f0
jmp 0x409319
leaq -0x1a0(%rbp), %rdi
callq 0x49efd0
movl $0x1, -0x17c(%rbp)
jmp 0x40a2ae
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x1a0(%rbp), %rdi
callq 0x49efd0
jmp 0x40a2c0
movq -0x58(%rbp), %rdi
xorl %edx, %edx
movl %edx, %esi
movl $0x1000000, %ecx        # imm = 0x1000000
callq 0x502720
movq -0x40(%rbp), %rdi
callq 0x4257e0
movl %eax, -0x804(%rbp)
jmp 0x409374
movl -0x804(%rbp), %eax
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %esi
leaq -0x1b8(%rbp), %rdi
callq 0x40b540
jmp 0x40938e
movl -0x34(%rbp), %esi
leaq -0x1d0(%rbp), %rdi
callq 0x40b540
jmp 0x40939f
movl -0x34(%rbp), %esi
leaq -0x1e8(%rbp), %rdi
callq 0x40b540
jmp 0x4093b0
movl -0x34(%rbp), %esi
leaq -0x200(%rbp), %rdi
callq 0x40b540
jmp 0x4093c1
movl -0x34(%rbp), %esi
leaq -0x218(%rbp), %rdi
callq 0x40b540
jmp 0x4093d2
movq -0x788(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x4072e0
movq %rax, %rsi
leaq -0x1d0(%rbp), %rdi
callq 0x40b640
jmp 0x4093f3
movq -0x788(%rbp), %rdi
movl $0x1, %esi
callq 0x4072e0
movq %rax, %rsi
leaq -0x1e8(%rbp), %rdi
callq 0x40b640
jmp 0x409415
leaq -0x241(%rbp), %rdi
movq %rdi, -0x810(%rbp)
callq 0x42ffd0
movq -0x810(%rbp), %rdx
leaq 0x1d0acc(%rip), %rsi    # 0x5d9f02
leaq -0x240(%rbp), %rdi
callq 0x406db0
jmp 0x409444
leaq -0x241(%rbp), %rdi
callq 0x42fff0
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movl -0x34(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jae 0x40950d
leaq 0x1c2a1e(%rip), %rsi    # 0x5cbe8d
leaq -0x240(%rbp), %rdi
callq 0x4a07d0
jmp 0x40947d
jmp 0x40947f
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x409457
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x40a2a0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x40a294
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x40a288
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x40a27c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x40a270
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x241(%rbp), %rdi
callq 0x42fff0
jmp 0x40a270
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x40a264
leaq -0x200(%rbp), %rdi
leaq -0x240(%rbp), %rsi
callq 0x40b640
jmp 0x409522
leaq 0x1d09d9(%rip), %rsi    # 0x5d9f02
leaq -0x240(%rbp), %rdi
callq 0x4a0020
jmp 0x409537
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x34(%rbp), %eax
jae 0x409568
leaq 0x1c2948(%rip), %rsi    # 0x5cbe95
leaq -0x240(%rbp), %rdi
callq 0x4a07d0
jmp 0x40955b
jmp 0x40955d
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x40953e
leaq -0x218(%rbp), %rdi
leaq -0x240(%rbp), %rsi
callq 0x40b640
jmp 0x40957d
movq -0x58(%rbp), %rcx
leaq 0x1acda1(%rip), %rdi    # 0x5b6329
movl $0x1, %esi
movl $0x5, %edx
callq 0x501e70
jmp 0x409599
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x30(%rbp), %eax
jae 0x409625
movq -0x58(%rbp), %rcx
leaq 0x1acd7c(%rip), %rdi    # 0x5b632f
movl $0x1, %edx
movq %rdx, %rsi
callq 0x501e70
jmp 0x4095c2
movq -0x778(%rbp), %rdi
movl -0x2c(%rbp), %eax
movl %eax, %esi
callq 0x4072e0
movq %rax, %rdi
callq 0x4a0a10
movq -0x778(%rbp), %rdi
movq %rax, -0x818(%rbp)
movl -0x2c(%rbp), %eax
movl %eax, %esi
callq 0x4072e0
movq %rax, %rdi
callq 0x49f200
movq -0x818(%rbp), %rdi
movq %rax, %rdx
movq -0x58(%rbp), %rcx
movl $0x1, %esi
callq 0x501e70
jmp 0x409615
jmp 0x409617
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x4095a0
movq -0x58(%rbp), %rcx
leaq 0x1b6eba(%rip), %rdi    # 0x5c04ea
movl $0x1, %edx
movq %rdx, %rsi
callq 0x501e70
jmp 0x40963f
movl -0x30(%rbp), %esi
movl -0x34(%rbp), %edx
leaq -0x298(%rbp), %rdi
callq 0x41f480
jmp 0x409653
movl $0x0, -0x29c(%rbp)
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x30(%rbp), %eax
jae 0x409801
movb $0x0, -0x29d(%rbp)
movq -0x40(%rbp), %rdi
movl -0x2c(%rbp), %eax
leaq (%rax,%rax,2), %rax
shlq $0x6, %rax
addq %rax, %rdi
leaq -0x1b8(%rbp), %rsi
leaq -0x220(%rbp), %rdx
callq 0x425170
movb %al, -0x819(%rbp)
jmp 0x4096a4
movb -0x819(%rbp), %al
testb $0x1, %al
jne 0x4096b3
jmp 0x409745
leaq -0x1b8(%rbp), %rdi
leaq -0x1d0(%rbp), %rsi
callq 0x40b6f0
movb %al, -0x81a(%rbp)
jmp 0x4096ce
movb -0x81a(%rbp), %al
testb $0x1, %al
jne 0x409740
jmp 0x4096da
leaq -0x278(%rbp), %rdi
movl -0x2c(%rbp), %eax
movl %eax, %esi
callq 0x40b7a0
movq %rax, %rdi
leaq -0x1b8(%rbp), %rsi
callq 0x40b7c0
jmp 0x4096fc
movq -0x220(%rbp), %rax
movl %eax, -0x820(%rbp)
leaq -0x298(%rbp), %rdi
addq $0x38, %rdi
movl -0x2c(%rbp), %eax
movl %eax, %esi
callq 0x40b8b0
movl -0x820(%rbp), %ecx
movl %ecx, (%rax)
movb $0x1, -0x29d(%rbp)
jmp 0x409745
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x40a258
jmp 0x409677
testb $0x1, -0x29d(%rbp)
je 0x409775
leaq -0x1b8(%rbp), %rdi
leaq -0x1e8(%rbp), %rsi
callq 0x40b6f0
movb %al, -0x821(%rbp)
jmp 0x409769
movb -0x821(%rbp), %al
testb $0x1, %al
jne 0x4097c2
jmp 0x409775
movl -0x29c(%rbp), %eax
incl %eax
movl %eax, -0x29c(%rbp)
leaq -0x278(%rbp), %rdi
movl -0x2c(%rbp), %eax
movl %eax, %esi
callq 0x40b7a0
movq %rax, %rdi
leaq -0x218(%rbp), %rsi
callq 0x40b7c0
jmp 0x4097a5
leaq -0x298(%rbp), %rdi
addq $0x38, %rdi
movl -0x2c(%rbp), %eax
movl %eax, %esi
callq 0x40b8b0
movl $0x0, (%rax)
jmp 0x4097f1
leaq 0x230ebf(%rip), %rdi    # 0x63a688
callq 0x40b4f0
jmp 0x4097d0
movq 0x230ea9(%rip), %rax    # 0x63a680
incq %rax
movq %rax, 0x230e9f(%rip)    # 0x63a680
leaq 0x230ea0(%rip), %rdi    # 0x63a688
callq 0x40b520
jmp 0x4097ef
jmp 0x4097f1
jmp 0x4097f3
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x409664
movl -0x29c(%rbp), %eax
cmpl -0x30(%rbp), %eax
jne 0x4098ff
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x30(%rbp), %eax
jae 0x409845
movq -0x40(%rbp), %rdi
movl -0x2c(%rbp), %eax
leaq (%rax,%rax,2), %rax
shlq $0x6, %rax
addq %rax, %rdi
callq 0x4254b0
jmp 0x409838
jmp 0x40983a
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x409817
movq -0x58(%rbp), %rdi
callq 0x5012c0
jmp 0x409850
movq -0x40(%rbp), %rax
movq %rax, -0x830(%rbp)
cmpq $0x0, %rax
je 0x4098f0
movq -0x830(%rbp), %rcx
movq %rcx, %rax
addq $-0x8, %rax
movq %rax, -0x848(%rbp)
movq -0x8(%rcx), %rax
movq %rax, -0x840(%rbp)
imulq $0xc0, %rax, %rdx
movq %rcx, %rax
addq %rdx, %rax
cmpq %rax, %rcx
movq %rax, -0x838(%rbp)
je 0x4098d2
movq -0x838(%rbp), %rdi
addq $-0xc0, %rdi
movq %rdi, -0x850(%rbp)
callq 0x424450
movq -0x830(%rbp), %rcx
movq -0x850(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x838(%rbp)
jne 0x40989e
movq -0x848(%rbp), %rdi
movq -0x840(%rbp), %rax
imulq $0xc0, %rax, %rsi
addq $0x8, %rsi
callq 0x42ecb0
movl $0x1, -0x17c(%rbp)
jmp 0x40a202
leaq -0x278(%rbp), %rdi
movl -0x30(%rbp), %eax
movl %eax, %esi
callq 0x40b7a0
movq %rax, %rdi
leaq -0x200(%rbp), %rsi
callq 0x40b7c0
jmp 0x409921
leaq -0x298(%rbp), %rdi
callq 0x41f720
jmp 0x40992f
movq $0x0, -0x2b0(%rbp)
movabsq $0x100000001, %rax      # imm = 0x100000001
movq %rax, -0x2b8(%rbp)
leaq -0x2d0(%rbp), %rdi
callq 0x406f20
leaq -0x2e8(%rbp), %rdi
callq 0x406f20
movl -0x34(%rbp), %esi
leaq -0x300(%rbp), %rdi
callq 0x40b540
jmp 0x409974
movq -0x780(%rbp), %rax
movb 0x100(%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x409a1d
movq -0x780(%rbp), %rdi
movl 0x128(%rdi), %eax
cvtsi2sd %rax, %xmm0
movsd 0x1ac8a7(%rip), %xmm1   # 0x5b6250
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %rax
movl %eax, -0x2b8(%rbp)
addq $0x108, %rdi            # imm = 0x108
leaq 0x1d053c(%rip), %rsi    # 0x5d9f02
callq 0x4a11e0
cmpl $0x0, %eax
jne 0x4099ed
movl $0x1, -0x2b4(%rbp)
jmp 0x409a1b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x40a1e8
movq -0x780(%rbp), %rcx
movl -0x30(%rbp), %eax
movl 0x128(%rcx), %ecx
subl %ecx, %eax
cvtsi2sd %rax, %xmm0
movsd 0x1ac844(%rip), %xmm1   # 0x5b6250
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %rax
movl %eax, -0x2b4(%rbp)
jmp 0x409a1d
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x30(%rbp), %eax
jae 0x409b64
leaq -0x721(%rbp), %rdi
movq %rdi, -0x858(%rbp)
callq 0x42ffd0
movq -0x858(%rbp), %rdx
leaq 0x1ac8e0(%rip), %rsi    # 0x5b6331
leaq -0x720(%rbp), %rdi
callq 0x406db0
jmp 0x409a5f
leaq -0x2d0(%rbp), %rdi
leaq -0x720(%rbp), %rsi
callq 0x407910
jmp 0x409a74
leaq -0x720(%rbp), %rdi
callq 0x49efd0
leaq -0x721(%rbp), %rdi
callq 0x42fff0
leaq -0x749(%rbp), %rdi
movq %rdi, -0x860(%rbp)
callq 0x42ffd0
movq -0x860(%rbp), %rdx
leaq 0x1ac884(%rip), %rsi    # 0x5b6331
leaq -0x748(%rbp), %rdi
callq 0x406db0
jmp 0x409abb
leaq -0x2e8(%rbp), %rdi
leaq -0x748(%rbp), %rsi
callq 0x407910
jmp 0x409ad0
leaq -0x748(%rbp), %rdi
callq 0x49efd0
leaq -0x749(%rbp), %rdi
callq 0x42fff0
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x409a24
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x409b1c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x720(%rbp), %rdi
callq 0x49efd0
leaq -0x721(%rbp), %rdi
callq 0x42fff0
jmp 0x40a1dc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x409b53
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x748(%rbp), %rdi
callq 0x49efd0
leaq -0x749(%rbp), %rdi
callq 0x42fff0
jmp 0x40a1dc
jmp 0x409b66
jmp 0x409b68
leaq -0x298(%rbp), %rdi
callq 0x41f7a0
movl %eax, -0x864(%rbp)
jmp 0x409b7c
movl -0x864(%rbp), %eax
movl %eax, -0x2a4(%rbp)
leaq -0x260(%rbp), %rdi
movl -0x2a4(%rbp), %eax
movl %eax, %esi
callq 0x40b8b0
movq -0x790(%rbp), %rdi
movl (%rax), %eax
cvtsi2sd %rax, %xmm0
movsd %xmm0, -0x870(%rbp)
movl -0x2a4(%rbp), %eax
movl %eax, %esi
callq 0x40b8d0
movsd -0x870(%rbp), %xmm0
movss (%rax), %xmm1
cvtss2sd %xmm1, %xmm1
divsd %xmm1, %xmm0
leaq 0x1ac75a(%rip), %rsi    # 0x5b6334
leaq -0x700(%rbp), %rdi
movb $0x1, %al
callq 0x4fad70
leaq -0x278(%rbp), %rdi
movl -0x2a4(%rbp), %eax
movl %eax, %esi
callq 0x40b7a0
movq %rax, %rsi
leaq -0x300(%rbp), %rdi
callq 0x40b8f0
movb %al, -0x865(%rbp)
jmp 0x409c13
movb -0x865(%rbp), %al
testb $0x1, %al
jne 0x409c1f
jmp 0x409c5a
movl -0x2a4(%rbp), %eax
movl %eax, %esi
leaq -0x2e8(%rbp), %rdi
callq 0x4072e0
movq %rax, %rdi
leaq -0x700(%rbp), %rsi
callq 0x4a0020
jmp 0x409c44
jmp 0x409d95
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x40a1dc
movl -0x2b0(%rbp), %eax
cmpl -0x2b8(%rbp), %eax
jae 0x409c7a
movl -0x2ac(%rbp), %eax
cmpl -0x2b4(%rbp), %eax
jb 0x409d45
leaq -0x300(%rbp), %rdi
leaq -0x240(%rbp), %rsi
callq 0x40b970
jmp 0x409c8f
leaq -0x240(%rbp), %rdi
callq 0x4a0a10
movq %rax, %rdi
movl -0x34(%rbp), %eax
movl %eax, %edx
movq -0x58(%rbp), %rcx
movl $0x1, %esi
callq 0x501e70
jmp 0x409cb3
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x30(%rbp), %eax
jae 0x409d29
movl -0x2c(%rbp), %eax
movl %eax, %esi
leaq -0x2e8(%rbp), %rdi
movq %rdi, -0x880(%rbp)
callq 0x4072e0
movq %rax, %rdi
callq 0x4a0a10
movq -0x880(%rbp), %rdi
movq %rax, -0x878(%rbp)
movl -0x2c(%rbp), %eax
movl %eax, %esi
callq 0x4072e0
movq %rax, %rdi
callq 0x49f200
movq -0x878(%rbp), %rdi
movq %rax, %rdx
movq -0x58(%rbp), %rcx
movl $0x1, %esi
callq 0x501e70
jmp 0x409d1c
jmp 0x409d1e
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x409cba
movq -0x58(%rbp), %rcx
leaq 0x1b67b6(%rip), %rdi    # 0x5c04ea
movl $0x1, %edx
movq %rdx, %rsi
callq 0x501e70
jmp 0x409d43
jmp 0x409d45
movl $0x0, -0x2ac(%rbp)
movl $0x0, -0x2b0(%rbp)
leaq -0x2e8(%rbp), %rdi
leaq -0x2d0(%rbp), %rsi
callq 0x40b9c0
jmp 0x409d6e
movl -0x2a4(%rbp), %eax
movl %eax, %esi
leaq -0x2e8(%rbp), %rdi
callq 0x4072e0
movq %rax, %rdi
leaq -0x700(%rbp), %rsi
callq 0x4a0020
jmp 0x409d93
jmp 0x409d95
movq -0x780(%rbp), %rax
movb 0x100(%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x409e74
movq -0x780(%rbp), %rdi
addq $0x108, %rdi            # imm = 0x108
leaq 0x1d013d(%rip), %rsi    # 0x5d9f02
callq 0x4a11e0
cmpl $0x0, %eax
jne 0x409de3
movl -0x2b0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2b0(%rbp)
jmp 0x409e72
movq -0x778(%rbp), %rdi
movq -0x780(%rbp), %rax
addq $0x158, %rax            # imm = 0x158
movq %rax, -0x890(%rbp)
movl -0x2a4(%rbp), %eax
movl %eax, %esi
callq 0x4072e0
movq -0x890(%rbp), %rdi
movq %rax, %rsi
callq 0x40bc10
movq %rax, -0x888(%rbp)
jmp 0x409e23
movq -0x888(%rbp), %rdi
movq -0x780(%rbp), %rsi
addq $0x108, %rsi            # imm = 0x108
callq 0x4a1030
movl %eax, -0x894(%rbp)
jmp 0x409e45
movl -0x894(%rbp), %eax
cmpl $0x0, %eax
jne 0x409e61
movl -0x2b0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2b0(%rbp)
jmp 0x409e70
movl -0x2ac(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2ac(%rbp)
jmp 0x409e72
jmp 0x409e83
movl -0x2b0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2b0(%rbp)
leaq -0x278(%rbp), %rdi
movl -0x2a4(%rbp), %eax
movl %eax, %esi
callq 0x40b7a0
movq %rax, %rsi
leaq -0x300(%rbp), %rdi
callq 0x40b7c0
jmp 0x409ea8
movq -0x40(%rbp), %rdi
movl -0x2a4(%rbp), %eax
leaq (%rax,%rax,2), %rax
shlq $0x6, %rax
addq %rax, %rdi
leaq -0x1b8(%rbp), %rsi
leaq -0x220(%rbp), %rdx
callq 0x425170
movb %al, -0x895(%rbp)
jmp 0x409ed8
movb -0x895(%rbp), %al
testb $0x1, %al
jne 0x409ee4
jmp 0x409f0b
leaq -0x1b8(%rbp), %rdi
leaq -0x1e8(%rbp), %rsi
callq 0x40b6f0
movb %al, -0x896(%rbp)
jmp 0x409eff
movb -0x896(%rbp), %al
testb $0x1, %al
jne 0x409f3b
jmp 0x409f0b
movl -0x29c(%rbp), %eax
incl %eax
movl %eax, -0x29c(%rbp)
leaq -0x1b8(%rbp), %rdi
leaq -0x218(%rbp), %rsi
callq 0x40b7c0
jmp 0x409f2e
movq $0x0, -0x220(%rbp)
jmp 0x409f6a
leaq 0x230746(%rip), %rdi    # 0x63a688
callq 0x40b4f0
jmp 0x409f49
movq 0x230730(%rip), %rax    # 0x63a680
incq %rax
movq %rax, 0x230726(%rip)    # 0x63a680
leaq 0x230727(%rip), %rdi    # 0x63a688
callq 0x40b520
jmp 0x409f68
jmp 0x409f6a
movl -0x29c(%rbp), %eax
cmpl -0x30(%rbp), %eax
jne 0x40a066
movl -0x2b0(%rbp), %eax
cmpl -0x2b8(%rbp), %eax
jae 0x409f99
movl -0x2ac(%rbp), %eax
cmpl -0x2b4(%rbp), %eax
jb 0x40a064
leaq -0x300(%rbp), %rdi
leaq -0x240(%rbp), %rsi
callq 0x40b970
jmp 0x409fae
leaq -0x240(%rbp), %rdi
callq 0x4a0a10
movq %rax, %rdi
movl -0x34(%rbp), %eax
movl %eax, %edx
movq -0x58(%rbp), %rcx
movl $0x1, %esi
callq 0x501e70
jmp 0x409fd2
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x30(%rbp), %eax
jae 0x40a048
movl -0x2c(%rbp), %eax
movl %eax, %esi
leaq -0x2e8(%rbp), %rdi
movq %rdi, -0x8a8(%rbp)
callq 0x4072e0
movq %rax, %rdi
callq 0x4a0a10
movq -0x8a8(%rbp), %rdi
movq %rax, -0x8a0(%rbp)
movl -0x2c(%rbp), %eax
movl %eax, %esi
callq 0x4072e0
movq %rax, %rdi
callq 0x49f200
movq -0x8a0(%rbp), %rdi
movq %rax, %rdx
movq -0x58(%rbp), %rcx
movl $0x1, %esi
callq 0x501e70
jmp 0x40a03b
jmp 0x40a03d
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x409fd9
movq -0x58(%rbp), %rcx
leaq 0x1b6497(%rip), %rdi    # 0x5c04ea
movl $0x1, %edx
movq %rdx, %rsi
callq 0x501e70
jmp 0x40a062
jmp 0x40a064
jmp 0x40a0cc
leaq -0x278(%rbp), %rdi
movl -0x2a4(%rbp), %eax
movl %eax, %esi
callq 0x40b7a0
movq %rax, %rdi
leaq -0x1b8(%rbp), %rsi
callq 0x40b7c0
jmp 0x40a08b
movl -0x220(%rbp), %eax
movl %eax, -0x8ac(%rbp)
leaq -0x260(%rbp), %rdi
movl -0x2a4(%rbp), %eax
movl %eax, %esi
callq 0x40b8b0
movl -0x8ac(%rbp), %ecx
movl %ecx, (%rax)
movl -0x2a4(%rbp), %esi
leaq -0x298(%rbp), %rdi
callq 0x41f610
jmp 0x40a0c7
jmp 0x409b66
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x30(%rbp), %eax
jae 0x40a101
movq -0x40(%rbp), %rdi
movl -0x2c(%rbp), %eax
leaq (%rax,%rax,2), %rax
shlq $0x6, %rax
addq %rax, %rdi
callq 0x4254b0
jmp 0x40a0f4
jmp 0x40a0f6
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x40a0d3
movq -0x58(%rbp), %rdi
callq 0x5012c0
jmp 0x40a10c
movq -0x40(%rbp), %rax
movq %rax, -0x8b8(%rbp)
cmpq $0x0, %rax
je 0x40a1ac
movq -0x8b8(%rbp), %rcx
movq %rcx, %rax
addq $-0x8, %rax
movq %rax, -0x8d0(%rbp)
movq -0x8(%rcx), %rax
movq %rax, -0x8c8(%rbp)
imulq $0xc0, %rax, %rdx
movq %rcx, %rax
addq %rdx, %rax
cmpq %rax, %rcx
movq %rax, -0x8c0(%rbp)
je 0x40a18e
movq -0x8c0(%rbp), %rdi
addq $-0xc0, %rdi
movq %rdi, -0x8d8(%rbp)
callq 0x424450
movq -0x8b8(%rbp), %rcx
movq -0x8d8(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x8c0(%rbp)
jne 0x40a15a
movq -0x8d0(%rbp), %rdi
movq -0x8c8(%rbp), %rax
imulq $0xc0, %rax, %rsi
addq $0x8, %rsi
callq 0x42ecb0
movl $0x1, -0x17c(%rbp)
leaq -0x300(%rbp), %rdi
callq 0x40bcf0
leaq -0x2e8(%rbp), %rdi
callq 0x407800
leaq -0x2d0(%rbp), %rdi
callq 0x407800
jmp 0x40a202
leaq -0x300(%rbp), %rdi
callq 0x40bcf0
leaq -0x2e8(%rbp), %rdi
callq 0x407800
leaq -0x2d0(%rbp), %rdi
callq 0x407800
jmp 0x40a258
leaq -0x298(%rbp), %rdi
callq 0x41f5a0
leaq -0x240(%rbp), %rdi
callq 0x49efd0
leaq -0x218(%rbp), %rdi
callq 0x40bcf0
leaq -0x200(%rbp), %rdi
callq 0x40bcf0
leaq -0x1e8(%rbp), %rdi
callq 0x40bcf0
leaq -0x1d0(%rbp), %rdi
callq 0x40bcf0
leaq -0x1b8(%rbp), %rdi
callq 0x40bcf0
jmp 0x40a2ae
leaq -0x298(%rbp), %rdi
callq 0x41f5a0
leaq -0x240(%rbp), %rdi
callq 0x49efd0
leaq -0x218(%rbp), %rdi
callq 0x40bcf0
leaq -0x200(%rbp), %rdi
callq 0x40bcf0
leaq -0x1e8(%rbp), %rdi
callq 0x40bcf0
leaq -0x1d0(%rbp), %rdi
callq 0x40bcf0
leaq -0x1b8(%rbp), %rdi
callq 0x40bcf0
jmp 0x40a2c0
leaq -0x78(%rbp), %rdi
callq 0x49efd0
addq $0x8e0, %rsp            # imm = 0x8E0
popq %rbp
retq
leaq -0x78(%rbp), %rdi
callq 0x49efd0
movq -0x48(%rbp), %rdi
callq 0x4d3c10
nopw %cs:(%rax,%rax)