// File: /workspace/github_cpp_makefile_star2_O3/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 $0x598, %rsp            # imm = 0x598
movq %rsi, %rbx
movl %edi, %r14d
callq 0x6054
leaq -0x1a0(%rbp), %r12
movq %r12, -0x10(%r12)
leaq 0xa73f(%rip), %rsi      # 0xe010
leaq 0xa73d(%rip), %rdx      # 0xe015
leaq -0x1b0(%rbp), %rdi
callq 0x5366
leaq -0x1b0(%rbp), %rdi
callq 0x5800
movl %eax, %r15d
movq -0x1b0(%rbp), %rdi
cmpq %r12, %rdi
je 0x390e
movq -0x1a0(%rbp), %rsi
incq %rsi
callq 0x32d0
movl %r15d, -0x30(%rbp)
leaq -0x180(%rbp), %r12
movq %r12, -0x10(%r12)
leaq 0xb2b9(%rip), %rsi      # 0xebde
leaq 0xb2b8(%rip), %rdx      # 0xebe4
leaq -0x190(%rbp), %rdi
callq 0x5366
leaq -0x190(%rbp), %rdi
callq 0x5800
movl %eax, %r15d
movq -0x190(%rbp), %rdi
cmpq %r12, %rdi
je 0x3962
movq -0x180(%rbp), %rsi
incq %rsi
callq 0x32d0
movl %r15d, -0x2c(%rbp)
leaq -0x160(%rbp), %r12
movq %r12, -0x10(%r12)
leaq 0xa69d(%rip), %rsi      # 0xe016
leaq 0xa69d(%rip), %rdx      # 0xe01d
leaq -0x170(%rbp), %rdi
callq 0x5366
leaq -0x170(%rbp), %rdi
callq 0x5800
movl %eax, %r15d
movq -0x170(%rbp), %rdi
cmpq %r12, %rdi
je 0x39b6
movq -0x160(%rbp), %rsi
incq %rsi
callq 0x32d0
cmpl $0x3, %r14d
jl 0x39d9
movq 0xf5ed(%rip), %rdi      # 0x12fb0
leaq 0xa654(%rip), %rsi      # 0xe01e
movl $0x3e, %edx
callq 0x3310
jmp 0x496e
cmpl $0x2, %r14d
jne 0x3a35
movq 0x8(%rbx), %rsi
leaq -0x5c0(%rbp), %r14
movq %r14, %rdi
movl $0x8, %edx
callq 0x34c0
movq (%r14), %rax
movq -0x18(%rax), %rcx
cmpl $0x0, -0x5a0(%rbp,%rcx)
je 0x4325
movq 0xf59d(%rip), %rdi      # 0x12fb0
leaq 0xa643(%rip), %rsi      # 0xe05d
movl $0x28, %edx
callq 0x3310
leaq -0x5c0(%rbp), %rdi
callq 0x3090
jmp 0x496e
movl $0x2748, %edi           # imm = 0x2748
callq 0x32c0
movq %rax, %r12
movq %rax, %rdi
callq 0x9354
movl $0xa8, %edi
callq 0x32c0
movq %rax, %r14
movq %rax, %rdi
movq %r12, %rsi
callq 0x8590
movl $0xd0, %edi
callq 0x32c0
movq %rax, %rbx
movl -0x30(%rbp), %esi
movl -0x2c(%rbp), %edx
movq %rax, %rdi
movq %r12, -0xd8(%rbp)
movq %r12, %rcx
movq %r14, -0xd0(%rbp)
movq %r14, %r8
callq 0x6e48
movq %rbx, -0xc8(%rbp)
movl $0x18, %edi
callq 0x32c0
movq %rax, %rbx
movslq -0x2c(%rbp), %r14
movslq -0x30(%rbp), %r12
leaq -0x3b8(%rbp), %rdi
callq 0x61cc
leaq -0x5c0(%rbp), %rdi
leaq -0x3b8(%rbp), %rdx
leaq -0x68(%rbp), %rcx
movq %r12, %rsi
callq 0x4e02
leaq -0x5c0(%rbp), %rdx
leaq -0xc0(%rbp), %rcx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x4ea0
movq -0x5c0(%rbp), %rdi
testq %rdi, %rdi
je 0x3b07
movq -0x5b0(%rbp), %rsi
subq %rdi, %rsi
callq 0x32d0
leaq -0xa0(%rbp), %rax
movq %rbx, (%rax)
xorpd %xmm0, %xmm0
movapd %xmm0, -0x100(%rbp)
movq $0x0, -0xf0(%rbp)
movl -0x30(%rbp), %esi
movl -0x2c(%rbp), %ecx
imull %esi, %ecx
movl %ecx, %eax
cltd
idivl %r15d
leaq -0x34(%rbp), %rdx
movl %eax, (%rdx)
xorl %ebx, %ebx
movl %ebx, -0x94(%rbp)
movl %ebx, -0x90(%rbp)
testl %r15d, %r15d
jle 0x3c70
leaq -0x5c0(%rbp), %r14
leaq -0x100(%rbp), %r13
xorl %eax, %eax
xorl %ecx, %ecx
xorl %r12d, %r12d
movl %ecx, -0x3b8(%rbp)
movl %eax, -0x68(%rbp)
movl -0x2c(%rbp), %edx
movl -0x34(%rbp), %edi
cmpl %edx, %ecx
setl %r8b
testl %edi, %edi
setg %r9b
andb %r8b, %r9b
cmpb $0x1, %r9b
jne 0x3bcd
leal -0x1(%rdi), %r8d
xorl %r9d, %r9d
cmpl %esi, %eax
jge 0x3bae
cmpl %r9d, %r8d
je 0x3bcd
incl %r9d
incl %eax
movl %eax, -0x68(%rbp)
cmpl %esi, %eax
jge 0x3bae
cmpl %edi, %r9d
jl 0x3b98
cmpl %edi, %r9d
jge 0x3bcd
movl $0x0, -0x68(%rbp)
incl %ecx
movl %ecx, -0x3b8(%rbp)
xorl %eax, %eax
cmpl %edx, %ecx
jge 0x3bcd
cmpl %edi, %r9d
jl 0x3b94
testl %r12d, %r12d
je 0x3c40
subq $0x8, %rsp
movq %r14, %rdi
leaq -0x464(%rip), %rsi      # 0x377c
leaq -0x94(%rbp), %rdx
leaq -0x3b8(%rbp), %rcx
leaq -0x90(%rbp), %r8
leaq -0x68(%rbp), %r9
leaq -0xa0(%rbp), %rax
pushq %rax
leaq -0xc8(%rbp), %rax
pushq %rax
leaq -0x34(%rbp), %rax
pushq %rax
leaq -0x2c(%rbp), %rax
pushq %rax
leaq -0x30(%rbp), %rax
pushq %rax
callq 0x4f42
addq $0x30, %rsp
movq %r13, %rdi
movq %r14, %rsi
callq 0x55ea
cmpq $0x0, -0x5c0(%rbp)
jne 0x49eb
movl -0x68(%rbp), %eax
movl -0x30(%rbp), %esi
incl %eax
xorl %ecx, %ecx
cmpl %esi, %eax
sete %cl
cmovel %ebx, %eax
addl -0x3b8(%rbp), %ecx
movl %ecx, -0x94(%rbp)
movl %eax, -0x90(%rbp)
incl %r12d
cmpl %r15d, %r12d
jne 0x3b69
imull -0x2c(%rbp), %esi
movl %esi, %ecx
movl %ecx, %eax
cltd
idivl %r15d
testl %edx, %edx
je 0x3ce4
subq $0x8, %rsp
leaq -0x2c(%rbp), %rcx
leaq -0x30(%rbp), %r9
leaq -0x511(%rip), %rsi      # 0x377c
leaq -0x5c0(%rbp), %rdi
leaq -0x94(%rbp), %rdx
leaq -0x90(%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 0x4f42
addq $0x30, %rsp
leaq -0x100(%rbp), %rdi
leaq -0x5c0(%rbp), %rsi
callq 0x55ea
cmpq $0x0, -0x5c0(%rbp)
jne 0x49f5
leaq -0x8c(%rbp), %rax
movl $0x0, (%rax)
leaq -0x5c0(%rbp), %rdx
movq %rax, (%rdx)
leaq 0x23a9(%rip), %rsi      # 0x60ab
leaq -0xe8(%rbp), %rdi
leaq -0x34(%rbp), %rcx
callq 0x501e
movl -0x2c(%rbp), %esi
testl %esi, %esi
setg %dl
movl -0x8c(%rbp), %eax
movl -0x34(%rbp), %ecx
cmpl %ecx, %eax
setl %dil
andb %dl, %dil
cmpb $0x1, %dil
jne 0x3df8
movl -0x30(%rbp), %edx
xorl %r14d, %r14d
leaq -0x5c0(%rbp), %rbx
testl %edx, %edx
jle 0x3de5
cmpl %ecx, %eax
jge 0x3de5
xorps %xmm0, %xmm0
cvtsi2sd %r14d, %xmm0
addsd 0xa2a5(%rip), %xmm0     # 0xe008
movsd %xmm0, -0xe0(%rbp)
leaq (%r14,%r14,2), %r15
xorl %r12d, %r12d
xorl %r13d, %r13d
movq -0xc8(%rbp), %rsi
xorps %xmm0, %xmm0
cvtsi2sdl -0x2c(%rbp), %xmm0
subsd -0xe0(%rbp), %xmm0
xorps %xmm1, %xmm1
cvtsi2sd %r13d, %xmm1
addsd 0xa26c(%rip), %xmm1     # 0xe008
movq %rbx, %rdi
callq 0x79f4
movq -0xa0(%rbp), %rax
movq (%rax), %rax
movq (%rax,%r15,8), %rdi
addq %r12, %rdi
movq %rbx, %rsi
callq 0x6338
movl -0x8c(%rbp), %eax
incl %eax
movl %eax, -0x8c(%rbp)
incq %r13
movslq -0x30(%rbp), %rdx
movl -0x34(%rbp), %ecx
cmpq %rdx, %r13
jge 0x3de2
addq $0x18, %r12
cmpl %ecx, %eax
jl 0x3d75
movl -0x2c(%rbp), %esi
incq %r14
movslq %esi, %rdi
cmpq %rdi, %r14
jge 0x3df8
cmpl %ecx, %eax
jl 0x3d43
movq -0x100(%rbp), %rbx
movq -0xf8(%rbp), %r14
cmpq %r14, %rbx
je 0x3e19
movq %rbx, %rdi
callq 0x3440
addq $0x8, %rbx
jmp 0x3e06
leaq -0xe8(%rbp), %rdi
callq 0x3440
leaq -0xb0(%rbp), %rax
movq %rax, -0x10(%rax)
movq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq -0x5b0(%rbp), %r14
xorl %r15d, %r15d
leaq -0x5c0(%rbp), %r12
leaq -0x68(%rbp), %rbx
movl $0xd1b71759, %edx       # imm = 0xD1B71759
movl $0x1, %r13d
cmpl $0xa, %r15d
jb 0x3ea3
movl $0x4, %r13d
movl %r15d, %eax
cmpl $0x63, %eax
jbe 0x3e9a
cmpl $0x3e7, %eax            # imm = 0x3E7
jbe 0x3ea0
cmpl $0x2710, %eax           # imm = 0x2710
jb 0x3ea3
movl %eax, %ecx
imulq %rdx, %rcx
shrq $0x2d, %rcx
addl $0x4, %r13d
cmpl $0x1869f, %eax          # imm = 0x1869F
movl %ecx, %eax
ja 0x3e6a
addl $-0x3, %r13d
jmp 0x3ea3
addl $-0x2, %r13d
jmp 0x3ea3
decl %r13d
movl %r13d, %esi
movq %r14, -0x5c0(%rbp)
movq %r12, %rdi
movl $0x2d, %edx
callq 0x3320
movq -0x5c0(%rbp), %rdi
movl %r13d, %esi
movl %r15d, %edx
callq 0x5248
leaq -0xc0(%rbp), %rdi
movq %r12, %rsi
callq 0x3340
movq -0x5c0(%rbp), %rdi
cmpq %r14, %rdi
je 0x3ef6
movq -0x5b0(%rbp), %rsi
incq %rsi
callq 0x32d0
movq %rbx, %r12
movq %rbx, %rdi
leaq 0xa218(%rip), %r14      # 0xe11b
movq %r14, %rsi
leaq -0xc0(%rbp), %rdx
callq 0x50ab
leaq -0x58(%rbp), %r13
movq %r12, %rdi
leaq 0xa19e(%rip), %rsi      # 0xe0be
callq 0x3500
leaq -0x3a8(%rbp), %rsi
movq %rsi, -0x3b8(%rbp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x3f55
movq %rdx, -0x3b8(%rbp)
movq (%rcx), %rdx
movq %rdx, -0x3a8(%rbp)
jmp 0x3f5d
movupd (%rcx), %xmm0
movupd %xmm0, (%rsi)
movq 0x8(%rax), %rdx
movq %rdx, -0x3b0(%rbp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
leaq -0x5c0(%rbp), %rdi
leaq -0x3b8(%rbp), %rsi
movl $0x8, %edx
callq 0x33f0
movq -0x3b8(%rbp), %rdi
leaq -0x3a8(%rbp), %rax
cmpq %rax, %rdi
je 0x3fb1
movq -0x3a8(%rbp), %rsi
incq %rsi
callq 0x32d0
movq -0x68(%rbp), %rdi
cmpq %r13, %rdi
je 0x3fc6
movq -0x58(%rbp), %rsi
incq %rsi
callq 0x32d0
leaq -0x88(%rbp), %r12
movq %r12, %rdi
movq %r14, %rsi
leaq -0xc0(%rbp), %rdx
callq 0x50ab
movq %r12, %rdi
leaq 0xa0da(%rip), %rsi      # 0xe0c3
callq 0x3500
movq %r13, -0x68(%rbp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x400e
movq %rdx, -0x68(%rbp)
movq (%rcx), %rdx
movq %rdx, -0x58(%rbp)
jmp 0x4018
movupd (%rcx), %xmm0
movupd %xmm0, (%r13)
movq 0x8(%rax), %rdx
movq %rdx, -0x60(%rbp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
leaq -0x3b8(%rbp), %rdi
movq %rbx, %rsi
movl $0x8, %edx
callq 0x33f0
movq -0x68(%rbp), %rdi
cmpq %r13, %rdi
je 0x4058
movq -0x58(%rbp), %rsi
incq %rsi
callq 0x32d0
movq -0x88(%rbp), %rdi
leaq -0x78(%rbp), %rax
cmpq %rax, %rdi
je 0x4074
movq -0x78(%rbp), %rsi
incq %rsi
callq 0x32d0
movq -0x5c0(%rbp), %rax
movq -0x18(%rax), %rax
cmpl $0x0, -0x5a0(%rbp,%rax)
je 0x40a2
movq -0x3b8(%rbp), %rax
movq -0x18(%rax), %rax
cmpl $0x0, -0x398(%rbp,%rax)
sete %r13b
jmp 0x40a5
movb $0x1, %r13b
leaq -0x3b8(%rbp), %rdi
callq 0x3090
leaq -0x5c0(%rbp), %r12
movq %r12, %rdi
callq 0x3090
incl %r15d
testb %r13b, %r13b
leaq -0x5b0(%rbp), %r14
movl $0xd1b71759, %edx       # imm = 0xD1B71759
jne 0x3e55
leaq 0xa00a(%rip), %rsi      # 0xe0e9
leaq -0x68(%rbp), %rdi
leaq -0xc0(%rbp), %rdx
callq 0x50ab
leaq 0xa27d(%rip), %rsi      # 0xe373
leaq -0x68(%rbp), %rdi
callq 0x3500
movq -0xd8(%rbp), %r15
leaq -0x3a8(%rbp), %rbx
movq %rbx, -0x3b8(%rbp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x4136
movq %rdx, -0x3b8(%rbp)
movq (%rcx), %rdx
movq %rdx, -0x3a8(%rbp)
jmp 0x413e
movupd (%rcx), %xmm0
movupd %xmm0, (%rbx)
leaq -0x58(%rbp), %r12
movq 0x8(%rax), %rdx
leaq -0x3b8(%rbp), %rsi
movq %rdx, 0x8(%rsi)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
leaq -0x5c0(%rbp), %rdi
movl $0x10, %edx
callq 0x3510
movq -0x3b8(%rbp), %rdi
cmpq %rbx, %rdi
je 0x418c
movq -0x3a8(%rbp), %rsi
incq %rsi
callq 0x32d0
movq -0x68(%rbp), %rdi
cmpq %r12, %rdi
je 0x41a1
movq -0x58(%rbp), %rsi
incq %rsi
callq 0x32d0
leaq -0x3b8(%rbp), %rdi
movq %r15, %rsi
callq 0xaee4
movq -0x3b8(%rbp), %rsi
movq -0x3b0(%rbp), %rdx
leaq -0x5c0(%rbp), %rdi
callq 0x3310
movq -0x3b8(%rbp), %rdi
cmpq %rbx, %rdi
je 0x41e5
movq -0x3a8(%rbp), %rsi
incq %rsi
callq 0x32d0
movq 0xedc4(%rip), %rdi      # 0x12fb0
leaq 0x9ed5(%rip), %rsi      # 0xe0c8
movl $0x25, %edx
callq 0x3310
movq -0xc0(%rbp), %rsi
movq -0xb8(%rbp), %rdx
movq 0xed9e(%rip), %rdi      # 0x12fb0
callq 0x3310
leaq 0x9ed0(%rip), %rsi      # 0xe0ee
movl $0x7, %edx
movq %rax, %rdi
callq 0x3310
leaq -0x120(%rbp), %r14
movq %r14, -0x10(%r14)
leaq 0x9e82(%rip), %rsi      # 0xe0bf
leaq 0x9e7e(%rip), %rdx      # 0xe0c2
leaq -0x130(%rbp), %rdi
callq 0x5366
leaq -0x130(%rbp), %rdi
callq 0x5800
movl %eax, %ebx
movq -0x130(%rbp), %rdi
cmpq %r14, %rdi
je 0x4279
movq -0x120(%rbp), %rsi
incq %rsi
callq 0x32d0
testl %ebx, %ebx
je 0x42d1
leaq 0x9e97(%rip), %rsi      # 0xe11b
leaq -0x88(%rbp), %rdi
leaq -0xc0(%rbp), %rdx
callq 0x50ab
leaq 0x9e20(%rip), %rsi      # 0xe0be
leaq -0x88(%rbp), %rdi
callq 0x3500
movq %r12, -0x68(%rbp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x4419
movq %rdx, -0x68(%rbp)
movq (%rcx), %rdx
movq %rdx, -0x58(%rbp)
jmp 0x4423
leaq 0x9e43(%rip), %rsi      # 0xe11b
leaq -0x88(%rbp), %rdi
leaq -0xc0(%rbp), %rdx
callq 0x50ab
leaq 0x9dd1(%rip), %rsi      # 0xe0c3
leaq -0x88(%rbp), %rdi
callq 0x3500
movq %r12, -0x68(%rbp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x4612
movq %rdx, -0x68(%rbp)
movq (%rcx), %rdx
movq %rdx, -0x58(%rbp)
jmp 0x461c
leaq -0x3a8(%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 -0x5c0(%rbp), %rdi
leaq -0x3b8(%rbp), %rsi
callq 0x34d0
movl $0x2748, %edi           # imm = 0x2748
callq 0x32c0
movq %rax, %r12
leaq -0x140(%rbp), %r14
movq %r14, -0x10(%r14)
movq -0x3b8(%rbp), %rsi
movq -0x3b0(%rbp), %rdx
addq %rsi, %rdx
leaq -0x150(%rbp), %rdi
callq 0x52c8
leaq -0x150(%rbp), %rsi
movq %r12, %rdi
callq 0xa42a
movq -0x150(%rbp), %rdi
cmpq %r14, %rdi
je 0x43c1
movq -0x140(%rbp), %rsi
incq %rsi
callq 0x32d0
movb 0x2710(%r12), %r13b
testb %r13b, %r13b
je 0x45e0
movq 0xebd7(%rip), %r14      # 0x12fb0
leaq 0x9cbc(%rip), %rsi      # 0xe09c
movl $0x21, %edx
movq %r14, %rdi
callq 0x3310
movq 0x8(%rbx), %rbx
testq %rbx, %rbx
je 0x4982
movq %rbx, %rdi
callq 0x3100
movq 0xeba7(%rip), %rdi      # 0x12fb0
movq %rbx, %rsi
movq %rax, %rdx
callq 0x3310
jmp 0x499a
movupd (%rcx), %xmm0
movupd %xmm0, (%r12)
movq 0x8(%rax), %rdx
leaq -0x68(%rbp), %rsi
movq %rdx, 0x8(%rsi)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
leaq -0x3b8(%rbp), %rdi
movl $0x4, %edx
callq 0x3510
movq -0x68(%rbp), %rdi
cmpq %r12, %rdi
je 0x4464
movq -0x58(%rbp), %rsi
incq %rsi
callq 0x32d0
movq -0x88(%rbp), %rdi
leaq -0x78(%rbp), %rax
cmpq %rax, %rdi
je 0x4480
movq -0x78(%rbp), %rsi
incq %rsi
callq 0x32d0
movl -0x30(%rbp), %esi
movl -0x2c(%rbp), %edx
leaq -0x68(%rbp), %rdi
leaq -0x3b8(%rbp), %rcx
callq 0xcdbc
movslq -0x30(%rbp), %rax
leaq (%rax,%rax,2), %rsi
leaq -0x88(%rbp), %rdi
leaq -0x95(%rbp), %rdx
callq 0x513e
cmpl $0x0, -0x2c(%rbp)
jle 0x4540
xorl %r14d, %r14d
leaq -0x68(%rbp), %rbx
movslq -0x30(%rbp), %rdx
testq %rdx, %rdx
jle 0x4525
leaq (%r14,%r14,2), %rax
xorl %ecx, %ecx
xorl %esi, %esi
movq -0xa0(%rbp), %rdx
movq (%rdx), %rdx
movq (%rdx,%rax,8), %rdx
cvttsd2si (%rdx,%rcx,8), %edi
movq -0x88(%rbp), %r8
cvttsd2si 0x8(%rdx,%rcx,8), %r9d
cvttsd2si 0x10(%rdx,%rcx,8), %edx
movb %dil, (%r8,%rcx)
movq -0x88(%rbp), %rdi
movb %r9b, 0x1(%rdi,%rcx)
movq -0x88(%rbp), %rdi
movb %dl, 0x2(%rdi,%rcx)
incq %rsi
movslq -0x30(%rbp), %rdx
addq $0x3, %rcx
cmpq %rdx, %rsi
jl 0x44d3
movq -0x88(%rbp), %rsi
movq %rbx, %rdi
callq 0xd044
incq %r14
movslq -0x2c(%rbp), %rax
cmpq %rax, %r14
jl 0x44c2
movq 0xea69(%rip), %rdi      # 0x12fb0
leaq 0x9ba8(%rip), %rsi      # 0xe0f6
movl $0x2b, %edx
callq 0x3310
movq -0xc0(%rbp), %rsi
movq -0xb8(%rbp), %rdx
movq 0xea43(%rip), %rdi      # 0x12fb0
callq 0x3310
leaq 0x9ba9(%rip), %rsi      # 0xe122
movl $0x8, %edx
movq %rax, %rdi
callq 0x3310
movq -0x88(%rbp), %rdi
testq %rdi, %rdi
movq -0xd0(%rbp), %rbx
je 0x45a5
movq -0x78(%rbp), %rsi
subq %rdi, %rsi
callq 0x32d0
movq 0xe9e4(%rip), %rax      # 0x12f90
movq (%rax), %rcx
movq 0x18(%rax), %rax
leaq -0x3b0(%rbp), %rdi
movq %rcx, -0x8(%rdi)
movq -0x18(%rcx), %rcx
movq %rax, -0x3b8(%rbp,%rcx)
callq 0x3240
leaq -0x2c0(%rbp), %rdi
callq 0x30d0
jmp 0x4878
movq 0xe9c9(%rip), %rdi      # 0x12fb0
leaq 0x9a98(%rip), %rsi      # 0xe086
movl $0x15, %edx
callq 0x3310
movq %r12, %rdi
callq 0xaeb8
movl $0x2748, %esi           # imm = 0x2748
movq %r12, %rdi
callq 0x32d0
jmp 0x49b2
movupd (%rcx), %xmm0
movupd %xmm0, (%r12)
movq 0x8(%rax), %rdx
leaq -0x68(%rbp), %rsi
movq %rdx, 0x8(%rsi)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
leaq -0x3b8(%rbp), %rdi
movl $0x10, %edx
callq 0x3510
movq -0x68(%rbp), %rdi
cmpq %r12, %rdi
je 0x465d
movq -0x58(%rbp), %rsi
incq %rsi
callq 0x32d0
movq -0x88(%rbp), %rdi
leaq -0x78(%rbp), %rax
cmpq %rax, %rdi
je 0x4679
movq -0x78(%rbp), %rsi
incq %rsi
callq 0x32d0
leaq 0x9aab(%rip), %rsi      # 0xe12b
leaq -0x3b8(%rbp), %rdi
movl $0x3, %edx
callq 0x3310
movl -0x30(%rbp), %esi
leaq -0x3b8(%rbp), %rdi
callq 0x3460
leaq -0x68(%rbp), %rsi
movb $0x20, (%rsi)
movl $0x1, %edx
movq %rax, %rdi
callq 0x3310
movl -0x2c(%rbp), %esi
movq %rax, %rdi
callq 0x3460
leaq -0x68(%rbp), %rsi
movb $0x20, (%rsi)
movl $0x1, %edx
movq %rax, %rdi
callq 0x3310
movq %rax, %rdi
movl $0xff, %esi
callq 0x3460
leaq -0x68(%rbp), %rsi
movb $0xa, (%rsi)
movl $0x1, %edx
movq %rax, %rdi
callq 0x3310
movl -0x2c(%rbp), %ecx
testl %ecx, %ecx
jle 0x47f5
movl -0x30(%rbp), %eax
xorl %esi, %esi
leaq -0x3b8(%rbp), %rbx
leaq -0x68(%rbp), %r14
testl %eax, %eax
jle 0x47e6
movl $0x10, %r12d
movq %rsi, -0x108(%rbp)
leaq (%rsi,%rsi,2), %r13
xorl %r15d, %r15d
movq -0xa0(%rbp), %rax
movq (%rax), %rax
movq (%rax,%r13,8), %rax
movsd -0x8(%rax,%r12), %xmm0
movsd %xmm0, -0xe0(%rbp)
movsd (%rax,%r12), %xmm0
movsd %xmm0, -0x110(%rbp)
cvttsd2si -0x10(%rax,%r12), %esi
movq %rbx, %rdi
callq 0x3460
movb $0x20, -0x68(%rbp)
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x3310
cvttsd2si -0xe0(%rbp), %esi
movq %rax, %rdi
callq 0x3460
movb $0x20, -0x68(%rbp)
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x3310
cvttsd2si -0x110(%rbp), %esi
movq %rax, %rdi
callq 0x3460
movb $0xa, -0x68(%rbp)
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x3310
incq %r15
movslq -0x30(%rbp), %rax
addq $0x18, %r12
cmpq %rax, %r15
jl 0x472b
movl -0x2c(%rbp), %ecx
movq -0xd8(%rbp), %r15
movq -0x108(%rbp), %rsi
incq %rsi
movslq %ecx, %rdx
cmpq %rdx, %rsi
jl 0x470f
movq 0xe7b4(%rip), %rdi      # 0x12fb0
leaq 0x992c(%rip), %rsi      # 0xe12f
movl $0x2a, %edx
callq 0x3310
movq -0xc0(%rbp), %rsi
movq -0xb8(%rbp), %rdx
movq 0xe78e(%rip), %rdi      # 0x12fb0
callq 0x3310
leaq 0x992c(%rip), %rsi      # 0xe15a
movl $0x8, %edx
movq %rax, %rdi
callq 0x3310
movq 0xe74e(%rip), %rax      # 0x12f90
movq (%rax), %rcx
movq 0x18(%rax), %rax
leaq -0x3b0(%rbp), %rdi
movq %rcx, -0x8(%rdi)
movq -0x18(%rcx), %rcx
movq %rax, -0x3b8(%rbp,%rcx)
callq 0x3240
leaq -0x2c0(%rbp), %rdi
callq 0x30d0
movq -0xd0(%rbp), %rbx
movq %r15, %rdi
callq 0xaeb8
movl $0x2748, %esi           # imm = 0x2748
movq %r15, %rdi
callq 0x32d0
movq %rbx, %rdi
callq 0x8b5a
movl $0xa8, %esi
movq %rbx, %rdi
callq 0x32d0
movq -0xc8(%rbp), %rbx
testq %rbx, %rbx
je 0x48b6
movq %rbx, %rdi
callq 0x79a8
movl $0xd0, %esi
movq %rbx, %rdi
callq 0x32d0
movq -0xa0(%rbp), %rbx
testq %rbx, %rbx
je 0x48d7
movq %rbx, %rdi
callq 0x51a8
movl $0x18, %esi
movq %rbx, %rdi
callq 0x32d0
movq 0xe6c5(%rip), %rdi      # 0x12fb0
leaq 0x9871(%rip), %rsi      # 0xe163
movl $0x4, %edx
callq 0x3310
movq 0xe68d(%rip), %rax      # 0x12f90
movq (%rax), %rcx
movq 0x18(%rax), %rax
leaq -0x5b8(%rbp), %rdi
movq %rcx, -0x8(%rdi)
movq -0x18(%rcx), %rcx
movq %rax, -0x5c0(%rbp,%rcx)
callq 0x3240
leaq -0x4c8(%rbp), %rdi
callq 0x30d0
movq -0xc0(%rbp), %rdi
leaq -0xb0(%rbp), %rax
cmpq %rax, %rdi
je 0x4954
movq -0xb0(%rbp), %rsi
incq %rsi
callq 0x32d0
cmpq $0x0, -0xe8(%rbp)
jne 0x49f0
leaq -0x100(%rbp), %rdi
callq 0x520a
xorl %eax, %eax
addq $0x598, %rsp            # imm = 0x598
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq (%r14), %rax
movq -0x18(%rax), %rax
leaq (%r14,%rax), %rdi
movl 0x20(%r14,%rax), %esi
orl $0x1, %esi
callq 0x3430
movq 0xe60f(%rip), %rdi      # 0x12fb0
leaq 0x974a(%rip), %rsi      # 0xe0f2
movl $0x3, %edx
callq 0x3310
movq -0x3b8(%rbp), %rdi
leaq -0x3a8(%rbp), %rax
cmpq %rax, %rdi
je 0x49d4
movq -0x3a8(%rbp), %rsi
incq %rsi
callq 0x32d0
leaq -0x5c0(%rbp), %rdi
callq 0x3090
testb %r13b, %r13b
jne 0x3a4a
jmp 0x496e
callq 0x30a0
callq 0x30a0
callq 0x30a0
movq %rax, %r15
movq -0x150(%rbp), %rdi
cmpq %r14, %rdi
je 0x4a1d
movq -0x140(%rbp), %rsi
incq %rsi
callq 0x32d0
jmp 0x4a1d
movq %rax, %r15
movl $0x2748, %esi           # imm = 0x2748
movq %r12, %rdi
callq 0x32d0
jmp 0x4bc6
movq %rax, %r15
movq -0x68(%rbp), %rdi
cmpq %r12, %rdi
je 0x4a4c
movq -0x58(%rbp), %rsi
incq %rsi
callq 0x32d0
jmp 0x4a4c
movq %rax, %r15
movq -0x88(%rbp), %rdi
leaq -0x78(%rbp), %rax
cmpq %rax, %rdi
je 0x4db0
movq -0x78(%rbp), %rsi
jmp 0x4b39
jmp 0x4c6b
movq %rax, %r15
jmp 0x4be8
jmp 0x4a78
movq %rdx, %rbx
movq %rax, %r15
jmp 0x4c91
movq %rdx, %rbx
movq %rax, %r15
movq -0x68(%rbp), %rdi
cmpq %r12, %rdi
je 0x4aa6
movq -0x58(%rbp), %rsi
incq %rsi
callq 0x32d0
jmp 0x4aa6
movq %rdx, %rbx
movq %rax, %r15
movq -0x88(%rbp), %rdi
leaq -0x78(%rbp), %rax
cmpq %rax, %rdi
je 0x4c9d
movq -0x78(%rbp), %rsi
incq %rsi
callq 0x32d0
jmp 0x4c9d
movq %rdx, %rbx
movq %rax, %r15
jmp 0x4c9d
cmpq $0x0, -0x5c0(%rbp)
je 0x4cef
callq 0x30a0
jmp 0x4cef
movq %rax, %r15
movl $0x2748, %esi           # imm = 0x2748
movq %r12, %rdi
jmp 0x4c54
movq %rax, %r15
movq -0x130(%rbp), %rdi
cmpq %r14, %rdi
je 0x4db0
movq -0x120(%rbp), %rsi
jmp 0x4b39
jmp 0x4c6b
movq %rax, %r15
movq -0x3b8(%rbp), %rdi
cmpq %rbx, %rdi
je 0x4db0
movq -0x3a8(%rbp), %rsi
incq %rsi
callq 0x32d0
jmp 0x4db0
jmp 0x4c6b
movq %rax, %r15
movq -0x3b8(%rbp), %rdi
cmpq %rbx, %rdi
jne 0x4d26
jmp 0x4d35
jmp 0x4d0b
jmp 0x4d03
jmp 0x4d9c
jmp 0x4cef
movq %rax, %r15
movq -0x5c0(%rbp), %rdi
testq %rdi, %rdi
je 0x4b9c
movq -0x5b0(%rbp), %rsi
subq %rdi, %rsi
callq 0x32d0
jmp 0x4b9c
jmp 0x4b99
movq %rax, %r15
movl $0x18, %esi
jmp 0x4bab
movq %rax, %r15
movl $0xd0, %esi
movq %rbx, %rdi
jmp 0x4c54
movq %rax, %r15
movl $0xa8, %esi
movq %r14, %rdi
jmp 0x4c54
movq %rax, %r15
movq -0x3b8(%rbp), %rdi
leaq -0x3a8(%rbp), %rax
cmpq %rax, %rdi
je 0x4be8
movq -0x3a8(%rbp), %rsi
incq %rsi
callq 0x32d0
leaq -0x5c0(%rbp), %rdi
callq 0x3090
jmp 0x4df4
jmp 0x4c73
movq %rax, %r15
movq -0x170(%rbp), %rdi
cmpq %r12, %rdi
je 0x4df4
movq -0x160(%rbp), %rsi
jmp 0x4c51
jmp 0x4c5e
movq %rax, %r15
movq -0x190(%rbp), %rdi
cmpq %r12, %rdi
je 0x4df4
movq -0x180(%rbp), %rsi
jmp 0x4c51
jmp 0x4c5e
movq %rax, %r15
movq -0x1b0(%rbp), %rdi
cmpq %r12, %rdi
je 0x4df4
movq -0x1a0(%rbp), %rsi
incq %rsi
callq 0x32d0
jmp 0x4df4
movq %rax, %r15
jmp 0x4df4
jmp 0x4da1
movq %rax, %r15
jmp 0x4db0
movq %rdx, %rbx
movq %rax, %r15
movq -0x88(%rbp), %rdi
testq %rdi, %rdi
je 0x4c91
movq -0x78(%rbp), %rsi
subq %rdi, %rsi
callq 0x32d0
leaq -0x3b8(%rbp), %rdi
callq 0x33b0
cmpl $0x1, %ebx
jne 0x4db0
movq %r15, %rdi
callq 0x30f0
movq 0xe2fb(%rip), %rdi      # 0x12fb0
movq %rax, %rsi
callq 0x32b0
movq %rax, %rdi
callq 0x3120
callq 0x3400
movq -0xd8(%rbp), %r15
jmp 0x4871
movq %rax, %r15
callq 0x3400
jmp 0x4db0
jmp 0x4cef
cmpq $0x0, -0x5c0(%rbp)
jne 0x4cf7
movq %rax, %r15
jmp 0x4de8
callq 0x30a0
jmp 0x4d9c
jmp 0x4d03
movq %rax, %r15
jmp 0x4dbc
movq %rax, %r15
jmp 0x4d35
movq %rax, %r15
movq -0x3b8(%rbp), %rdi
leaq -0x3a8(%rbp), %rax
cmpq %rax, %rdi
je 0x4d35
movq -0x3a8(%rbp), %rsi
incq %rsi
callq 0x32d0
movq -0x68(%rbp), %rdi
leaq -0x58(%rbp), %rax
cmpq %rax, %rdi
je 0x4dbc
movq -0x58(%rbp), %rsi
incq %rsi
callq 0x32d0
jmp 0x4dbc
movq %rax, %r15
jmp 0x4d8e
movq %rax, %r15
jmp 0x4d72
movq %rax, %r15
movq -0x68(%rbp), %rdi
cmpq %r13, %rdi
je 0x4d72
movq -0x58(%rbp), %rsi
incq %rsi
callq 0x32d0
movq -0x88(%rbp), %rdi
leaq -0x78(%rbp), %rax
cmpq %rax, %rdi
je 0x4d8e
movq -0x78(%rbp), %rsi
incq %rsi
callq 0x32d0
leaq -0x5c0(%rbp), %rdi
callq 0x3090
jmp 0x4dbc
movq %rax, %r15
jmp 0x4dde
movq %rax, %r15
leaq -0x3b8(%rbp), %rdi
callq 0x33b0
leaq -0x5c0(%rbp), %rdi
callq 0x33b0
movq -0xc0(%rbp), %rdi
leaq -0xb0(%rbp), %rax
cmpq %rax, %rdi
je 0x4dde
movq -0xb0(%rbp), %rsi
incq %rsi
callq 0x32d0
cmpq $0x0, -0xe8(%rbp)
jne 0x4dfc
leaq -0x100(%rbp), %rdi
callq 0x520a
movq %r15, %rdi
callq 0x3490
callq 0x30a0
nop