// File: /workspace/github_cpp_makefile_star2_O1/soybin[P]idyll/src/main.cpp
// Function: main
int main(int argc, char* argv[]) {
	// base coordinates
	double y = 0.5, x = 0.5;

	// init gui
	gui::setup();

	// get config info
	int width = config::getInt("width");
	int height = config::getInt("height");
	int threadCount = config::getInt("threads");

	// pointer to seed object and parsing user input
	seed* s;
	if (argc > 2) {
		std::cout << "[-] The only permissible argument is a seed file's location.\n\n";
		return 0;
	} else if (argc == 2) {
		std::ifstream seedFile(argv[1]);
		if (!seedFile.good()) {
			std::cout << "[-] Couldn't find specified seed file.\n\n";
			return 0;
		}
		std::string seedData;
		std::getline(seedFile, seedData);
		s = new seed(seedData);
		if (!s->seedParsingSuccessful) {
			std::cout << "[-] Seed not valid.\n\n";
			delete s;
			return 0;
		}
		std::cout << "[+] Successfully read seed from '" << argv[1] << "'.\n";
	} else {
		s = new seed();
	}

	// pointer to fractal object
	fractal* f = new fractal(s);

	// pointer to renderer object
	renderer* r = new renderer(width, height, s, f);

	// pointer to 2d matrix of pixels. it'll be accessible
	// by every thread
	std::vector<std::vector<math::vec3>>* image = new std::vector<std::vector<math::vec3>>(height, std::vector<math::vec3>(width, math::vec3()));

	// thread array
	std::vector<std::thread> threads;

	// thread constants
	int chunk = width * height / threadCount;
	int lastY = 0;
	int lastX = 0;

	// thread assignment loop. this loop assigns to every thread
	// the render function with the right coordinates and stores
	// it on the thread array	
	for (int i = 0; i < threadCount; ++i) {
		int y = lastY;
		int x = lastX;
		int count = 0;
		for (; y < height && count < chunk; ) {
			for (; x < width && count < chunk; ) {
				if (++count == chunk) {
					break;
				}
				++x;
			}
			if (count < chunk) {
				x = 0;
				++y;
			}
		}

		// skip the first chunk because that one will be rendered
		// by the main thread later
		if (i > 0) {
			threads.push_back(std::thread{renderRange, lastY, y, lastX, x, width, height, chunk, r, image});
		}

		// advance one coordinate to set the starter coordinate
		// for the next loop, since this coordinate has already
		// been enqueued to be computed in the previously called
		// thread
		if (x + 1 == width) {
			x = 0;
			++y;
		} else {
			++x;
		}

		// save starter coordinates
		lastY = y;
		lastX = x;
	}

	// fill the remaining image portion which is smaller
	// than one chunk in case there's any
	if ((width * height) % threadCount != 0) {
		threads.push_back(std::thread{renderRange, lastY, height, lastX, width, width, height, chunk, r, image});
	}

	// render the first chunk in the main application thread
	// so that it can update the gui progress bar
	int count = 0;
	std::thread guiThread(gui::update, &count, chunk);
	for (int y = 0; y < height && count < chunk; ++y) {
		for (int x = 0; x < width && count < chunk; ++x) {
			(*image)[y][x] = r->render((double)height - ((double)y + 0.5f), (double)x + 0.5);
			++count;
		}
	}

	// wait for rendering threads to finish
	for (auto& thread : threads) {
		thread.join();
	}
	
	// wait for graphical user interface thread
	guiThread.join();

	//
	// define output file's path
	//
	int fileCount = 0;
	std::string fileCountStr;
	for (bool ok = true; ok & 1; ++fileCount) {
		fileCountStr = std::to_string(fileCount);
		std::ifstream pngFile("render" + fileCountStr + ".png");
		std::ifstream ppmFile("render" + fileCountStr + ".ppm");
		ok = pngFile.good() || ppmFile.good(); 
	}

	//
	// store seed inside new file
	//
	std::ofstream seedOut("seed" + fileCountStr + ".txt");
	seedOut << s->buildSeed();
	std::cout << "[+] Successfully stored seed at 'seed" << fileCountStr << ".txt'.\n";

	if (config::getInt("png")) {
		//
		// convert to portable network graphics format.
		// all credits for this functionality go to Nayuki for writing
		// the Tiny PNG Output library:
		// https://www.nayuki.io/page/tiny-png-output
		//
		try {
			// write image
			std::ofstream out("render" + fileCountStr + ".png", std::ios::binary);
			TinyPngOut pngout(static_cast<std::uint32_t>(width), static_cast<std::uint32_t>(height), out);
			std::vector<std::uint8_t> line(static_cast<size_t>(width) * 3);
			for (int y = 0; y < height; ++y) {
				for (int x = 0; x < width; ++x) {
					math::vec3 pixel = (*image)[y][x];
					line[(long long)x * 3 + 0] = static_cast<uint8_t>(pixel.x);
					line[(long long)x * 3 + 1] = static_cast<uint8_t>(pixel.y);
					line[(long long)x * 3 + 2] = static_cast<uint8_t>(pixel.z);
				}
				pngout.write(line.data(), static_cast<size_t>(width));
			}
			std::cout << "[+] Successfully stored png file to 'render" << fileCountStr << ".png'.\n\n";	
		} catch (const char* message) {
			std::cout << message << std::endl;
		}
	} else {
		//
		// write image data to ppm file
		//
		std::ofstream out("render" + fileCountStr + ".ppm");
		out << "P3\n" << width << ' ' << height << ' ' << 255 << '\n';
		for (int i = 0; i < height; ++i) {
			for (int j = 0; j < width; ++j) {
				math::vec3 pixel = (*image)[i][j];
				out << (int)pixel.x << ' ' << (int)pixel.y << ' ' << (int)pixel.z << '\n';
			}
		}
		std::cout << "[+] Successfully store ppm file to 'render" << fileCountStr << ".ppm'.\n\n";
	}

	//
	// free heap allocated memory
	//
	delete s;
	delete f;
	delete r;
	delete image;

	// correct teminal color pallette
	std::cout << "\033[0m";
	
#ifdef _WIN32
	std::system("pause");
#endif

	// exit :D
	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x5a8, %rsp            # imm = 0x5A8
movq %rsi, %rbx
movl %edi, %r14d
callq 0x602c
leaq -0x1a8(%rbp), %r12
movq %r12, -0x10(%r12)
leaq 0xa73f(%rip), %rsi      # 0xe010
leaq 0xa73d(%rip), %rdx      # 0xe015
leaq -0x1b8(%rbp), %rdi
callq 0x5342
leaq -0x1b8(%rbp), %rdi
callq 0x57d8
movl %eax, %r15d
movq -0x1b8(%rbp), %rdi
cmpq %r12, %rdi
je 0x390e
movq -0x1a8(%rbp), %rsi
incq %rsi
callq 0x32d0
movl %r15d, -0x2c(%rbp)
leaq -0x188(%rbp), %r12
movq %r12, -0x10(%r12)
leaq 0xb2c9(%rip), %rsi      # 0xebee
leaq 0xb2c8(%rip), %rdx      # 0xebf4
leaq -0x198(%rbp), %rdi
callq 0x5342
leaq -0x198(%rbp), %rdi
callq 0x57d8
movl %eax, %r15d
movq -0x198(%rbp), %rdi
cmpq %r12, %rdi
je 0x3962
movq -0x188(%rbp), %rsi
incq %rsi
callq 0x32d0
movl %r15d, -0x30(%rbp)
leaq -0x168(%rbp), %r12
movq %r12, -0x10(%r12)
leaq 0xa69d(%rip), %rsi      # 0xe016
leaq 0xa69d(%rip), %rdx      # 0xe01d
leaq -0x178(%rbp), %rdi
callq 0x5342
leaq -0x178(%rbp), %rdi
callq 0x57d8
movl %eax, %r15d
movq -0x178(%rbp), %rdi
cmpq %r12, %rdi
je 0x39b6
movq -0x168(%rbp), %rsi
incq %rsi
callq 0x32d0
cmpl $0x3, %r14d
jl 0x39d9
movq 0xf5f5(%rip), %rdi      # 0x12fb8
leaq 0xa654(%rip), %rsi      # 0xe01e
movl $0x3e, %edx
callq 0x3310
jmp 0x49b0
cmpl $0x2, %r14d
jne 0x3a28
movq 0x8(%rbx), %rsi
leaq -0x5c8(%rbp), %r14
movq %r14, %rdi
movl $0x8, %edx
callq 0x34c0
movq (%r14), %rax
movq -0x18(%rax), %rcx
cmpl $0x0, -0x5a8(%rbp,%rcx)
je 0x3a42
movq 0xf5a9(%rip), %rdi      # 0x12fb8
leaq 0xa647(%rip), %rsi      # 0xe05d
movl $0x28, %edx
callq 0x3310
xorl %r13d, %r13d
jmp 0x3bae
movl $0x2748, %edi           # imm = 0x2748
callq 0x32c0
movq %rax, %r13
movq %rax, %rdi
callq 0x9520
jmp 0x3bc6
leaq -0x3b0(%rbp), %rcx
movq %rcx, -0x10(%rcx)
movq $0x0, -0x8(%rcx)
movb $0x0, (%rcx)
addq -0x18(%rax), %r14
movq %r14, %rdi
movl $0xa, %esi
callq 0x32a0
movsbl %al, %edx
leaq -0x5c8(%rbp), %rdi
leaq -0x3c0(%rbp), %rsi
callq 0x34d0
movl $0x2748, %edi           # imm = 0x2748
callq 0x32c0
movq %rax, %r12
leaq -0x148(%rbp), %r14
movq %r14, -0x10(%r14)
movq -0x3c0(%rbp), %rsi
movq -0x3b8(%rbp), %rdx
addq %rsi, %rdx
leaq -0x158(%rbp), %rdi
callq 0x52a8
leaq -0x158(%rbp), %rsi
movq %r12, %r13
movq %r12, %rdi
callq 0xa5f6
movq -0x158(%rbp), %rdi
cmpq %r14, %rdi
je 0x3ae1
movq -0x148(%rbp), %rsi
incq %rsi
callq 0x32d0
movb 0x2710(%r13), %r13b
testb %r13b, %r13b
je 0x3b2d
movq 0xf4c4(%rip), %r14      # 0x12fb8
leaq 0xa5a1(%rip), %rsi      # 0xe09c
movl $0x21, %edx
movq %r14, %rdi
callq 0x3310
movq 0x8(%rbx), %rbx
testq %rbx, %rbx
je 0x3b5c
movq %rbx, %rdi
callq 0x3100
movq 0xf498(%rip), %rdi      # 0x12fb8
movq %rbx, %rsi
movq %rax, %rdx
callq 0x3310
jmp 0x3b74
movq 0xf484(%rip), %rdi      # 0x12fb8
leaq 0xa54b(%rip), %rsi      # 0xe086
movl $0x15, %edx
callq 0x3310
movq %r12, %rdi
callq 0xb058
movl $0x2748, %esi           # imm = 0x2748
movq %r12, %rdi
callq 0x32d0
jmp 0x3b8c
movq (%r14), %rax
movq -0x18(%rax), %rax
leaq (%r14,%rax), %rdi
movl 0x20(%r14,%rax), %esi
orl $0x1, %esi
callq 0x3430
movq 0xf43d(%rip), %rdi      # 0x12fb8
leaq 0xa570(%rip), %rsi      # 0xe0f2
movl $0x3, %edx
callq 0x3310
movq -0x3c0(%rbp), %rdi
leaq -0x3b0(%rbp), %rax
cmpq %rax, %rdi
je 0x3bae
movq -0x3b0(%rbp), %rsi
incq %rsi
callq 0x32d0
leaq -0x5c8(%rbp), %rdi
callq 0x3090
testb %r13b, %r13b
movq %r12, %r13
je 0x49b0
movl $0xa8, %edi
callq 0x32c0
movq %rax, %r14
movq %rax, %rdi
movq %r13, %rsi
callq 0x8738
movl $0xd0, %edi
callq 0x32c0
movq %rax, %rbx
movl -0x2c(%rbp), %esi
movl -0x30(%rbp), %edx
movq %rax, %rdi
movq %r13, %rcx
movq %r14, -0xd8(%rbp)
movq %r14, %r8
callq 0x6f0c
movq %rbx, -0xc8(%rbp)
movl $0x18, %edi
callq 0x32c0
movq %rax, %rbx
movslq -0x30(%rbp), %r14
movslq -0x2c(%rbp), %r12
leaq -0x3c0(%rbp), %rdi
callq 0x61a4
leaq -0x5c8(%rbp), %rdi
leaq -0x3c0(%rbp), %rdx
leaq -0x70(%rbp), %rcx
movq %r12, %rsi
callq 0x4dd4
leaq -0x5c8(%rbp), %rdx
leaq -0xc0(%rbp), %rcx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x4e66
movq %r13, -0xd0(%rbp)
movq -0x5c8(%rbp), %rdi
testq %rdi, %rdi
je 0x3c83
movq -0x5b8(%rbp), %rsi
subq %rdi, %rsi
callq 0x32d0
leaq -0xa0(%rbp), %rax
movq %rbx, (%rax)
xorpd %xmm0, %xmm0
movapd %xmm0, -0x110(%rbp)
movl -0x30(%rbp), %eax
imull -0x2c(%rbp), %eax
movq $0x0, -0x100(%rbp)
cltd
idivl %r15d
leaq -0x34(%rbp), %rcx
movl %eax, (%rcx)
xorl %ebx, %ebx
movl %ebx, -0x40(%rbp)
movl %ebx, -0x3c(%rbp)
testl %r15d, %r15d
jle 0x3dea
leaq -0x5c8(%rbp), %r14
leaq -0x70(%rbp), %r12
leaq -0x110(%rbp), %r13
movl -0x40(%rbp), %eax
movl %eax, -0x3c0(%rbp)
movl -0x3c(%rbp), %ecx
movl %ecx, -0x70(%rbp)
movl -0x30(%rbp), %ecx
movl -0x34(%rbp), %edx
cmpl %ecx, %eax
setl %sil
testl %edx, %edx
setg %dil
andb %sil, %dil
cmpb $0x1, %dil
jne 0x3d4f
movl -0x70(%rbp), %r8d
xorl %edi, %edi
movl -0x2c(%rbp), %esi
cmpl %esi, %r8d
jge 0x3d31
incl %edi
movl %edi, %r9d
movl %r9d, %edi
cmpl %r9d, %edx
je 0x3d31
incl %r8d
movl %r8d, -0x70(%rbp)
cmpl %esi, %r8d
jge 0x3d31
leal 0x1(%rdi), %r9d
cmpl %edx, %edi
jl 0x3d15
cmpl %edx, %edi
jge 0x3d47
movl $0x0, -0x70(%rbp)
incl %eax
movl %eax, -0x3c0(%rbp)
xorl %r8d, %r8d
cmpl %ecx, %eax
jge 0x3d4f
cmpl %edx, %edi
jl 0x3d0b
testl %ebx, %ebx
je 0x3db4
subq $0x8, %rsp
movq %r14, %rdi
leaq -0x5e5(%rip), %rsi      # 0x377c
leaq -0x40(%rbp), %rdx
leaq -0x3c0(%rbp), %rcx
leaq -0x3c(%rbp), %r8
movq %r12, %r9
leaq -0xa0(%rbp), %rax
pushq %rax
leaq -0xc8(%rbp), %rax
pushq %rax
leaq -0x34(%rbp), %rax
pushq %rax
leaq -0x30(%rbp), %rax
pushq %rax
leaq -0x2c(%rbp), %rax
pushq %rax
callq 0x4f08
addq $0x30, %rsp
movq %r13, %rdi
movq %r14, %rsi
callq 0x55c2
cmpq $0x0, -0x5c8(%rbp)
jne 0x49c4
movl -0x70(%rbp), %eax
incl %eax
cmpl -0x2c(%rbp), %eax
jne 0x3dcd
movl $0x0, -0x70(%rbp)
incl -0x3c0(%rbp)
jmp 0x3dd0
movl %eax, -0x70(%rbp)
movl -0x3c0(%rbp), %eax
movl %eax, -0x40(%rbp)
movl -0x70(%rbp), %eax
movl %eax, -0x3c(%rbp)
incl %ebx
cmpl %r15d, %ebx
jne 0x3cd8
movl -0x30(%rbp), %eax
imull -0x2c(%rbp), %eax
cltd
idivl %r15d
testl %edx, %edx
je 0x3e5d
subq $0x8, %rsp
leaq -0x30(%rbp), %rcx
leaq -0x2c(%rbp), %r9
leaq -0x690(%rip), %rsi      # 0x377c
leaq -0x5c8(%rbp), %rdi
leaq -0x40(%rbp), %rdx
leaq -0x3c(%rbp), %r8
leaq -0xa0(%rbp), %rax
pushq %rax
leaq -0xc8(%rbp), %rax
pushq %rax
leaq -0x34(%rbp), %rax
pushq %rax
pushq %rcx
pushq %r9
callq 0x4f08
addq $0x30, %rsp
leaq -0x110(%rbp), %rdi
leaq -0x5c8(%rbp), %rsi
callq 0x55c2
cmpq $0x0, -0x5c8(%rbp)
jne 0x49ce
leaq -0x38(%rbp), %rax
movl $0x0, (%rax)
leaq -0x5c8(%rbp), %rdx
movq %rax, (%rdx)
leaq 0x220b(%rip), %rsi      # 0x6083
leaq -0xf0(%rbp), %rdi
leaq -0x34(%rbp), %rcx
callq 0x4ff4
cmpl $0x0, -0x30(%rbp)
jle 0x3f5d
movl -0x34(%rbp), %eax
cmpl %eax, -0x38(%rbp)
jge 0x3f5d
xorl %r14d, %r14d
leaq -0x5c8(%rbp), %rbx
cmpl $0x0, -0x2c(%rbp)
jle 0x3f45
movl -0x34(%rbp), %eax
cmpl %eax, -0x38(%rbp)
jge 0x3f45
xorps %xmm0, %xmm0
cvtsi2sd %r14d, %xmm0
addsd 0xa13a(%rip), %xmm0     # 0xe008
movsd %xmm0, -0xe8(%rbp)
leaq (%r14,%r14,2), %r15
xorl %r12d, %r12d
xorl %r13d, %r13d
movq -0xc8(%rbp), %rsi
xorps %xmm0, %xmm0
cvtsi2sdl -0x30(%rbp), %xmm0
subsd -0xe8(%rbp), %xmm0
xorps %xmm1, %xmm1
cvtsi2sd %r13d, %xmm1
addsd 0xa101(%rip), %xmm1     # 0xe008
movq %rbx, %rdi
callq 0x7b62
movq -0xa0(%rbp), %rax
movq (%rax), %rax
movq (%rax,%r15,8), %rdi
addq %r12, %rdi
movq %rbx, %rsi
callq 0x6310
movl -0x38(%rbp), %eax
incl %eax
movl %eax, -0x38(%rbp)
incq %r13
movslq -0x2c(%rbp), %rcx
cmpq %rcx, %r13
jge 0x3f45
addq $0x18, %r12
cmpl -0x34(%rbp), %eax
jl 0x3ee0
incq %r14
movslq -0x30(%rbp), %rax
cmpq %rax, %r14
jge 0x3f5d
movl -0x34(%rbp), %eax
cmpl %eax, -0x38(%rbp)
jl 0x3ea8
movq -0x110(%rbp), %rbx
movq -0x108(%rbp), %r14
cmpq %r14, %rbx
je 0x3f7e
movq %rbx, %rdi
callq 0x3440
addq $0x8, %rbx
jmp 0x3f6b
leaq -0xf0(%rbp), %rdi
callq 0x3440
leaq -0xb0(%rbp), %rax
movq %rax, -0x10(%rax)
movq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq -0x5b8(%rbp), %r14
xorl %r15d, %r15d
leaq -0x5c8(%rbp), %r12
leaq -0x70(%rbp), %rbx
movl $0xd1b71759, %edx       # imm = 0xD1B71759
movl $0x1, %r13d
cmpl $0xa, %r15d
jb 0x4008
movl $0x4, %r13d
movl %r15d, %eax
cmpl $0x63, %eax
jbe 0x3fff
cmpl $0x3e7, %eax            # imm = 0x3E7
jbe 0x4005
cmpl $0x2710, %eax           # imm = 0x2710
jb 0x4008
movl %eax, %ecx
imulq %rdx, %rcx
shrq $0x2d, %rcx
addl $0x4, %r13d
cmpl $0x1869f, %eax          # imm = 0x1869F
movl %ecx, %eax
ja 0x3fcf
addl $-0x3, %r13d
jmp 0x4008
addl $-0x2, %r13d
jmp 0x4008
decl %r13d
movl %r13d, %esi
movq %r14, -0x5c8(%rbp)
movq %r12, %rdi
movl $0x2d, %edx
callq 0x3320
movq -0x5c8(%rbp), %rdi
movl %r13d, %esi
movl %r15d, %edx
callq 0x5228
leaq -0xc0(%rbp), %rdi
movq %r12, %rsi
callq 0x3340
movq -0x5c8(%rbp), %rdi
cmpq %r14, %rdi
je 0x405b
movq -0x5b8(%rbp), %rsi
incq %rsi
callq 0x32d0
movq %rbx, %r12
movq %rbx, %rdi
leaq 0xa0b3(%rip), %r14      # 0xe11b
movq %r14, %rsi
leaq -0xc0(%rbp), %rdx
callq 0x5091
leaq -0x60(%rbp), %r13
movq %r12, %rdi
leaq 0xa039(%rip), %rsi      # 0xe0be
callq 0x3500
leaq -0x3b0(%rbp), %rsi
movq %rsi, -0x3c0(%rbp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x40ba
movq %rdx, -0x3c0(%rbp)
movq (%rcx), %rdx
movq %rdx, -0x3b0(%rbp)
jmp 0x40c2
movupd (%rcx), %xmm0
movupd %xmm0, (%rsi)
movq 0x8(%rax), %rdx
movq %rdx, -0x3b8(%rbp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
leaq -0x5c8(%rbp), %rdi
leaq -0x3c0(%rbp), %rsi
movl $0x8, %edx
callq 0x33f0
movq -0x3c0(%rbp), %rdi
leaq -0x3b0(%rbp), %rax
cmpq %rax, %rdi
je 0x4116
movq -0x3b0(%rbp), %rsi
incq %rsi
callq 0x32d0
movq -0x70(%rbp), %rdi
cmpq %r13, %rdi
je 0x412b
movq -0x60(%rbp), %rsi
incq %rsi
callq 0x32d0
leaq -0x90(%rbp), %r12
movq %r12, %rdi
movq %r14, %rsi
leaq -0xc0(%rbp), %rdx
callq 0x5091
movq %r12, %rdi
leaq 0x9f75(%rip), %rsi      # 0xe0c3
callq 0x3500
movq %r13, -0x70(%rbp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x4173
movq %rdx, -0x70(%rbp)
movq (%rcx), %rdx
movq %rdx, -0x60(%rbp)
jmp 0x417d
movupd (%rcx), %xmm0
movupd %xmm0, (%r13)
movq 0x8(%rax), %rdx
movq %rdx, -0x68(%rbp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
leaq -0x3c0(%rbp), %rdi
movq %rbx, %rsi
movl $0x8, %edx
callq 0x33f0
movq -0x70(%rbp), %rdi
cmpq %r13, %rdi
je 0x41bd
movq -0x60(%rbp), %rsi
incq %rsi
callq 0x32d0
movq -0x90(%rbp), %rdi
leaq -0x80(%rbp), %rax
cmpq %rax, %rdi
je 0x41d9
movq -0x80(%rbp), %rsi
incq %rsi
callq 0x32d0
movq -0x5c8(%rbp), %rax
movq -0x18(%rax), %rax
cmpl $0x0, -0x5a8(%rbp,%rax)
je 0x4207
movq -0x3c0(%rbp), %rax
movq -0x18(%rax), %rax
cmpl $0x0, -0x3a0(%rbp,%rax)
sete %r13b
jmp 0x420a
movb $0x1, %r13b
leaq -0x3c0(%rbp), %rdi
callq 0x3090
leaq -0x5c8(%rbp), %r12
movq %r12, %rdi
callq 0x3090
incl %r15d
testb %r13b, %r13b
leaq -0x5b8(%rbp), %r14
movl $0xd1b71759, %edx       # imm = 0xD1B71759
jne 0x3fba
leaq 0x9ea5(%rip), %rsi      # 0xe0e9
leaq -0x70(%rbp), %rdi
leaq -0xc0(%rbp), %rdx
callq 0x5091
leaq 0xa118(%rip), %rsi      # 0xe373
leaq -0x70(%rbp), %rdi
callq 0x3500
movq -0xd0(%rbp), %r15
movq -0xd8(%rbp), %r12
leaq -0x3b0(%rbp), %rbx
movq %rbx, -0x3c0(%rbp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x42a2
movq %rdx, -0x3c0(%rbp)
movq (%rcx), %rdx
movq %rdx, -0x3b0(%rbp)
jmp 0x42aa
movupd (%rcx), %xmm0
movupd %xmm0, (%rbx)
leaq -0x60(%rbp), %r13
movq 0x8(%rax), %rdx
leaq -0x3c0(%rbp), %rsi
movq %rdx, 0x8(%rsi)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
leaq -0x5c8(%rbp), %rdi
movl $0x10, %edx
callq 0x3510
movq -0x3c0(%rbp), %rdi
cmpq %rbx, %rdi
je 0x42f8
movq -0x3b0(%rbp), %rsi
incq %rsi
callq 0x32d0
movq -0x70(%rbp), %rdi
cmpq %r13, %rdi
je 0x430d
movq -0x60(%rbp), %rsi
incq %rsi
callq 0x32d0
leaq -0x3c0(%rbp), %rdi
movq %r15, %rsi
callq 0xb084
movq -0x3c0(%rbp), %rsi
movq -0x3b8(%rbp), %rdx
leaq -0x5c8(%rbp), %rdi
callq 0x3310
movq -0x3c0(%rbp), %rdi
cmpq %rbx, %rdi
je 0x4351
movq -0x3b0(%rbp), %rsi
incq %rsi
callq 0x32d0
movq 0xec60(%rip), %rdi      # 0x12fb8
leaq 0x9d69(%rip), %rsi      # 0xe0c8
movl $0x25, %edx
callq 0x3310
movq -0xc0(%rbp), %rsi
movq -0xb8(%rbp), %rdx
movq 0xec3a(%rip), %rdi      # 0x12fb8
callq 0x3310
leaq 0x9d64(%rip), %rsi      # 0xe0ee
movl $0x7, %edx
movq %rax, %rdi
callq 0x3310
leaq -0x128(%rbp), %r14
movq %r14, -0x10(%r14)
leaq 0x9d16(%rip), %rsi      # 0xe0bf
leaq 0x9d12(%rip), %rdx      # 0xe0c2
leaq -0x138(%rbp), %rdi
callq 0x5342
leaq -0x138(%rbp), %rdi
callq 0x57d8
movl %eax, %ebx
movq -0x138(%rbp), %rdi
cmpq %r14, %rdi
je 0x43e5
movq -0x128(%rbp), %rsi
incq %rsi
callq 0x32d0
testl %ebx, %ebx
je 0x4436
leaq 0x9d2b(%rip), %rsi      # 0xe11b
leaq -0x90(%rbp), %rdi
leaq -0xc0(%rbp), %rdx
callq 0x5091
leaq 0x9cb4(%rip), %rsi      # 0xe0be
leaq -0x90(%rbp), %rdi
callq 0x3500
movq %r13, -0x70(%rbp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x448a
movq %rdx, -0x70(%rbp)
movq (%rcx), %rdx
movq %rdx, -0x60(%rbp)
jmp 0x4494
leaq 0x9cde(%rip), %rsi      # 0xe11b
leaq -0x90(%rbp), %rdi
leaq -0xc0(%rbp), %rdx
callq 0x5091
leaq 0x9c6c(%rip), %rsi      # 0xe0c3
leaq -0x90(%rbp), %rdi
callq 0x3500
movq %r13, -0x70(%rbp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x464c
movq %rdx, -0x70(%rbp)
movq (%rcx), %rdx
movq %rdx, -0x60(%rbp)
jmp 0x4656
movupd (%rcx), %xmm0
movupd %xmm0, (%r13)
movq 0x8(%rax), %rdx
leaq -0x70(%rbp), %rsi
movq %rdx, 0x8(%rsi)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
leaq -0x3c0(%rbp), %rdi
movl $0x4, %edx
callq 0x3510
movq -0x70(%rbp), %rdi
cmpq %r13, %rdi
je 0x44d5
movq -0x60(%rbp), %rsi
incq %rsi
callq 0x32d0
movq -0x90(%rbp), %rdi
leaq -0x80(%rbp), %rax
cmpq %rax, %rdi
je 0x44f1
movq -0x80(%rbp), %rsi
incq %rsi
callq 0x32d0
movl -0x2c(%rbp), %esi
movl -0x30(%rbp), %edx
leaq -0x70(%rbp), %rdi
leaq -0x3c0(%rbp), %rcx
callq 0xcf64
movslq -0x2c(%rbp), %rax
leaq (%rax,%rax,2), %rsi
leaq -0x90(%rbp), %rdi
leaq -0x91(%rbp), %rdx
callq 0x5124
cmpl $0x0, -0x30(%rbp)
jle 0x45b3
xorl %r14d, %r14d
leaq -0x70(%rbp), %rbx
movl -0x2c(%rbp), %edi
testl %edi, %edi
jle 0x4595
leaq (%r14,%r14,2), %rax
xorl %ecx, %ecx
xorl %edx, %edx
movq -0xa0(%rbp), %rsi
movq (%rsi), %rsi
movq (%rsi,%rax,8), %rsi
cvttsd2si (%rsi,%rcx,8), %edi
movq -0x90(%rbp), %r8
cvttsd2si 0x8(%rsi,%rcx,8), %r9d
cvttsd2si 0x10(%rsi,%rcx,8), %esi
movb %dil, (%r8,%rcx)
movq -0x90(%rbp), %rdi
movb %r9b, 0x1(%rdi,%rcx)
movq -0x90(%rbp), %rdi
movb %sil, 0x2(%rdi,%rcx)
incq %rdx
movslq -0x2c(%rbp), %rdi
addq $0x3, %rcx
cmpq %rdi, %rdx
jl 0x4542
movq -0x90(%rbp), %rsi
movslq %edi, %rdx
movq %rbx, %rdi
callq 0xd1e6
incq %r14
movslq -0x30(%rbp), %rax
cmpq %rax, %r14
jl 0x4533
movq 0xe9fe(%rip), %rdi      # 0x12fb8
leaq 0x9b35(%rip), %rsi      # 0xe0f6
movl $0x2b, %edx
callq 0x3310
movq -0xc0(%rbp), %rsi
movq -0xb8(%rbp), %rdx
movq 0xe9d8(%rip), %rdi      # 0x12fb8
callq 0x3310
leaq 0x9b36(%rip), %rsi      # 0xe122
movl $0x8, %edx
movq %rax, %rdi
callq 0x3310
movq -0x90(%rbp), %rdi
testq %rdi, %rdi
je 0x4611
movq -0x80(%rbp), %rsi
subq %rdi, %rsi
callq 0x32d0
movq 0xe980(%rip), %rax      # 0x12f98
movq (%rax), %rcx
movq 0x18(%rax), %rax
leaq -0x3b8(%rbp), %rdi
movq %rcx, -0x8(%rdi)
movq -0x18(%rcx), %rcx
movq %rax, -0x3c0(%rbp,%rcx)
callq 0x3240
leaq -0x2c8(%rbp), %rdi
callq 0x30d0
jmp 0x48be
movupd (%rcx), %xmm0
movupd %xmm0, (%r13)
movq 0x8(%rax), %rdx
leaq -0x70(%rbp), %rsi
movq %rdx, 0x8(%rsi)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
leaq -0x3c0(%rbp), %rdi
movl $0x10, %edx
callq 0x3510
movq -0x70(%rbp), %rdi
cmpq %r13, %rdi
je 0x4697
movq -0x60(%rbp), %rsi
incq %rsi
callq 0x32d0
movq -0x90(%rbp), %rdi
leaq -0x80(%rbp), %rax
cmpq %rax, %rdi
je 0x46b3
movq -0x80(%rbp), %rsi
incq %rsi
callq 0x32d0
leaq 0x9a71(%rip), %rsi      # 0xe12b
leaq -0x3c0(%rbp), %rdi
movl $0x3, %edx
callq 0x3310
movl -0x2c(%rbp), %esi
leaq -0x3c0(%rbp), %rdi
callq 0x3460
leaq -0x70(%rbp), %rsi
movb $0x20, (%rsi)
movl $0x1, %edx
movq %rax, %rdi
callq 0x3310
movl -0x30(%rbp), %esi
movq %rax, %rdi
callq 0x3460
leaq -0x70(%rbp), %rsi
movb $0x20, (%rsi)
movl $0x1, %edx
movq %rax, %rdi
callq 0x3310
movq %rax, %rdi
movl $0xff, %esi
callq 0x3460
leaq -0x70(%rbp), %rsi
movb $0xa, (%rsi)
movl $0x1, %edx
movq %rax, %rdi
callq 0x3310
cmpl $0x0, -0x30(%rbp)
jle 0x4834
movq $0x0, -0xe0(%rbp)
leaq -0x3c0(%rbp), %rbx
leaq -0x70(%rbp), %r14
cmpl $0x0, -0x2c(%rbp)
jle 0x4816
movl $0x10, %r12d
movq -0xe0(%rbp), %rax
leaq (%rax,%rax,2), %r13
xorl %r15d, %r15d
movq -0xa0(%rbp), %rax
movq (%rax), %rax
movq (%rax,%r13,8), %rax
movsd -0x8(%rax,%r12), %xmm0
movsd %xmm0, -0xe8(%rbp)
movsd (%rax,%r12), %xmm0
movsd %xmm0, -0x118(%rbp)
cvttsd2si -0x10(%rax,%r12), %esi
movq %rbx, %rdi
callq 0x3460
movb $0x20, -0x70(%rbp)
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x3310
cvttsd2si -0xe8(%rbp), %esi
movq %rax, %rdi
callq 0x3460
movb $0x20, -0x70(%rbp)
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x3310
cvttsd2si -0x118(%rbp), %esi
movq %rax, %rdi
callq 0x3460
movb $0xa, -0x70(%rbp)
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x3310
incq %r15
movslq -0x2c(%rbp), %rax
addq $0x18, %r12
cmpq %rax, %r15
jl 0x476c
movq -0xe0(%rbp), %rdx
incq %rdx
movslq -0x30(%rbp), %rax
movq %rdx, -0xe0(%rbp)
cmpq %rax, %rdx
jl 0x474e
movq 0xe77d(%rip), %rdi      # 0x12fb8
leaq 0x98ed(%rip), %rsi      # 0xe12f
movl $0x2a, %edx
callq 0x3310
movq -0xc0(%rbp), %rsi
movq -0xb8(%rbp), %rdx
movq 0xe757(%rip), %rdi      # 0x12fb8
callq 0x3310
leaq 0x98ed(%rip), %rsi      # 0xe15a
movl $0x8, %edx
movq %rax, %rdi
callq 0x3310
movq 0xe717(%rip), %rax      # 0x12f98
movq (%rax), %rcx
movq 0x18(%rax), %rax
leaq -0x3b8(%rbp), %rdi
movq %rcx, -0x8(%rdi)
movq -0x18(%rcx), %rcx
movq %rax, -0x3c0(%rbp,%rcx)
callq 0x3240
leaq -0x2c8(%rbp), %rdi
callq 0x30d0
movq -0xd0(%rbp), %r15
movq -0xd8(%rbp), %r12
movq %r15, %rdi
callq 0xb058
movl $0x2748, %esi           # imm = 0x2748
movq %r15, %rdi
callq 0x32d0
movq %r12, %rdi
callq 0x8d02
movl $0xa8, %esi
movq %r12, %rdi
callq 0x32d0
movq -0xc8(%rbp), %rbx
testq %rbx, %rbx
je 0x4909
movq %rbx, %rdi
callq 0x7b16
movl $0xd0, %esi
movq %rbx, %rdi
callq 0x32d0
movq -0xa0(%rbp), %rbx
testq %rbx, %rbx
je 0x492a
movq %rbx, %rdi
callq 0x518e
movl $0x18, %esi
movq %rbx, %rdi
callq 0x32d0
movq 0xe687(%rip), %rdi      # 0x12fb8
leaq 0x982b(%rip), %rsi      # 0xe163
movl $0x4, %edx
callq 0x3310
movq 0xe64f(%rip), %rax      # 0x12f98
movq (%rax), %rcx
movq 0x18(%rax), %rax
leaq -0x5c0(%rbp), %rdi
movq %rcx, -0x8(%rdi)
movq -0x18(%rcx), %rcx
movq %rax, -0x5c8(%rbp,%rcx)
callq 0x3240
leaq -0x4d0(%rbp), %rdi
callq 0x30d0
movq -0xc0(%rbp), %rdi
leaq -0xb0(%rbp), %rax
cmpq %rax, %rdi
je 0x499a
movq -0xb0(%rbp), %rsi
incq %rsi
callq 0x32d0
cmpq $0x0, -0xf0(%rbp)
jne 0x49c9
leaq -0x110(%rbp), %rdi
callq 0x51ea
xorl %eax, %eax
addq $0x5a8, %rsp            # imm = 0x5A8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x30a0
callq 0x30a0
callq 0x30a0
movq %rax, %r15
movq -0x158(%rbp), %rdi
cmpq %r14, %rdi
je 0x49f6
movq -0x148(%rbp), %rsi
incq %rsi
callq 0x32d0
jmp 0x49f6
movq %rax, %r15
movl $0x2748, %esi           # imm = 0x2748
movq %r12, %rdi
callq 0x32d0
jmp 0x4b9f
movq %rax, %r15
movq -0x70(%rbp), %rdi
cmpq %r13, %rdi
je 0x4a25
movq -0x60(%rbp), %rsi
incq %rsi
callq 0x32d0
jmp 0x4a25
movq %rax, %r15
movq -0x90(%rbp), %rdi
leaq -0x80(%rbp), %rax
cmpq %rax, %rdi
je 0x4d82
movq -0x80(%rbp), %rsi
jmp 0x4b12
jmp 0x4c44
movq %rax, %r15
jmp 0x4bc1
jmp 0x4a51
movq %rdx, %rbx
movq %rax, %r15
jmp 0x4c6a
movq %rdx, %rbx
movq %rax, %r15
movq -0x70(%rbp), %rdi
cmpq %r13, %rdi
je 0x4a7f
movq -0x60(%rbp), %rsi
incq %rsi
callq 0x32d0
jmp 0x4a7f
movq %rdx, %rbx
movq %rax, %r15
movq -0x90(%rbp), %rdi
leaq -0x80(%rbp), %rax
cmpq %rax, %rdi
je 0x4c76
movq -0x80(%rbp), %rsi
incq %rsi
callq 0x32d0
jmp 0x4c76
movq %rdx, %rbx
movq %rax, %r15
jmp 0x4c76
cmpq $0x0, -0x5c8(%rbp)
je 0x4cc1
callq 0x30a0
jmp 0x4cc1
movq %rax, %r15
movl $0x2748, %esi           # imm = 0x2748
movq %r13, %rdi
jmp 0x4c2d
movq %rax, %r15
movq -0x138(%rbp), %rdi
cmpq %r14, %rdi
je 0x4d82
movq -0x128(%rbp), %rsi
jmp 0x4b12
jmp 0x4c44
movq %rax, %r15
movq -0x3c0(%rbp), %rdi
cmpq %rbx, %rdi
je 0x4d82
movq -0x3b0(%rbp), %rsi
incq %rsi
callq 0x32d0
jmp 0x4d82
jmp 0x4c44
movq %rax, %r15
movq -0x3c0(%rbp), %rdi
cmpq %rbx, %rdi
jne 0x4cf8
jmp 0x4d07
jmp 0x4cdd
jmp 0x4cd5
jmp 0x4d6e
jmp 0x4cc1
movq %rax, %r15
movq -0x5c8(%rbp), %rdi
testq %rdi, %rdi
je 0x4b75
movq -0x5b8(%rbp), %rsi
subq %rdi, %rsi
callq 0x32d0
jmp 0x4b75
jmp 0x4b72
movq %rax, %r15
movl $0x18, %esi
jmp 0x4b84
movq %rax, %r15
movl $0xd0, %esi
movq %rbx, %rdi
jmp 0x4c2d
movq %rax, %r15
movl $0xa8, %esi
movq %r14, %rdi
jmp 0x4c2d
movq %rax, %r15
movq -0x3c0(%rbp), %rdi
leaq -0x3b0(%rbp), %rax
cmpq %rax, %rdi
je 0x4bc1
movq -0x3b0(%rbp), %rsi
incq %rsi
callq 0x32d0
leaq -0x5c8(%rbp), %rdi
callq 0x3090
jmp 0x4dc6
jmp 0x4c4c
movq %rax, %r15
movq -0x178(%rbp), %rdi
cmpq %r12, %rdi
je 0x4dc6
movq -0x168(%rbp), %rsi
jmp 0x4c2a
jmp 0x4c37
movq %rax, %r15
movq -0x198(%rbp), %rdi
cmpq %r12, %rdi
je 0x4dc6
movq -0x188(%rbp), %rsi
jmp 0x4c2a
jmp 0x4c37
movq %rax, %r15
movq -0x1b8(%rbp), %rdi
cmpq %r12, %rdi
je 0x4dc6
movq -0x1a8(%rbp), %rsi
incq %rsi
callq 0x32d0
jmp 0x4dc6
movq %rax, %r15
jmp 0x4dc6
jmp 0x4d73
movq %rax, %r15
jmp 0x4d82
movq %rdx, %rbx
movq %rax, %r15
movq -0x90(%rbp), %rdi
testq %rdi, %rdi
je 0x4c6a
movq -0x80(%rbp), %rsi
subq %rdi, %rsi
callq 0x32d0
leaq -0x3c0(%rbp), %rdi
callq 0x33b0
cmpl $0x1, %ebx
jne 0x4d82
movq %r15, %rdi
callq 0x30f0
movq 0xe32a(%rip), %rdi      # 0x12fb8
movq %rax, %rsi
callq 0x32b0
movq %rax, %rdi
callq 0x3120
callq 0x3400
jmp 0x48b0
movq %rax, %r15
callq 0x3400
jmp 0x4d82
jmp 0x4cc1
cmpq $0x0, -0x5c8(%rbp)
jne 0x4cc9
movq %rax, %r15
jmp 0x4dba
callq 0x30a0
jmp 0x4d6e
jmp 0x4cd5
movq %rax, %r15
jmp 0x4d8e
movq %rax, %r15
jmp 0x4d07
movq %rax, %r15
movq -0x3c0(%rbp), %rdi
leaq -0x3b0(%rbp), %rax
cmpq %rax, %rdi
je 0x4d07
movq -0x3b0(%rbp), %rsi
incq %rsi
callq 0x32d0
movq -0x70(%rbp), %rdi
leaq -0x60(%rbp), %rax
cmpq %rax, %rdi
je 0x4d8e
movq -0x60(%rbp), %rsi
incq %rsi
callq 0x32d0
jmp 0x4d8e
movq %rax, %r15
jmp 0x4d60
movq %rax, %r15
jmp 0x4d44
movq %rax, %r15
movq -0x70(%rbp), %rdi
cmpq %r13, %rdi
je 0x4d44
movq -0x60(%rbp), %rsi
incq %rsi
callq 0x32d0
movq -0x90(%rbp), %rdi
leaq -0x80(%rbp), %rax
cmpq %rax, %rdi
je 0x4d60
movq -0x80(%rbp), %rsi
incq %rsi
callq 0x32d0
leaq -0x5c8(%rbp), %rdi
callq 0x3090
jmp 0x4d8e
movq %rax, %r15
jmp 0x4db0
movq %rax, %r15
leaq -0x3c0(%rbp), %rdi
callq 0x33b0
leaq -0x5c8(%rbp), %rdi
callq 0x33b0
movq -0xc0(%rbp), %rdi
leaq -0xb0(%rbp), %rax
cmpq %rax, %rdi
je 0x4db0
movq -0xb0(%rbp), %rsi
incq %rsi
callq 0x32d0
cmpq $0x0, -0xf0(%rbp)
jne 0x4dce
leaq -0x110(%rbp), %rdi
callq 0x51ea
movq %r15, %rdi
callq 0x3490
callq 0x30a0
nop