// File: /workspace/github_cpp_makefile_star2_O2/MarkCBell[P]twister/./twister/kernel/manifold.cpp
// Function: construct_manifold(manifold&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
void construct_manifold(manifold &M, std::string surface_file_contents, std::string gluing, std::string handles)
{
	// These will hold all the pieces of information for the manifold.
	std::vector<annulus> annuli;
	std::vector<rectangle> rectangles;
	std::vector<std::string> annulus_name, annulus_name_inverse, rectangle_name, rectangle_name_inverse, macro_name, macro;
	
	// Fill up the manifold with interesting information from the surface_file_contents.
	initialise_manifold(M, annuli, rectangles, annulus_name, annulus_name_inverse, rectangle_name, rectangle_name_inverse, macro_name, macro, surface_file_contents);
	
	// Format the commands.
	format_command(handles, annulus_name, annulus_name_inverse, rectangle_name, rectangle_name_inverse, macro_name, macro);
	format_command(gluing, annulus_name, annulus_name_inverse, rectangle_name, rectangle_name_inverse, macro_name, macro);
	
	output_debugging("\nParsed handles: " + handles + "\nParsed gluing: " + gluing + "\n", 1);
	
	int num_annuli = int(annulus_name.size());
	int num_rectangles = int(rectangle_name.size());
	
	if (handles != "")  // Attach handles (if needed).
	{
		size_t marker = 0;
		
		do
		{
			std::string handle_location = find_next_substring(handles, separator, marker);
			
			if (handle_location == "") continue;  // Skip it if there is no action.
			
			bool performed_action = false;  // Records if we actually performed an action.
			for (int i = 0; i < num_annuli; i++)
			{
				if ((annulus_name[i] == handle_location) || (annulus_name_inverse[i] == handle_location))
				{
					annuli[i].twohandle((annulus_name[i] == handle_location));
					performed_action = true;
					break;  // Annuli / rectangle names are unique, so we can give up if we get a hit.
				}
			}
			if (performed_action) continue;
			
			output_warning("No annulus named '" + handle_location + "' found to attach a handle to.");
		} while (marker != 0);
	}
	
	M.insert_layer();  // Insert layer #1 to prevent rooftop access.
	
	// Reset the layer flags on cubes and marked points.
	for (int i = 0; i < int(M.marked_points.size()); i++)
		M.marked_points[i] = half_twisted;
	
	for (int i = 0; i < int(M.cubes.size()); i++)
		M.cubes[i]->set_status(false);
	
	// We parse the gluing w = w_1 ... w_n from left to right, so our twists are 
	// stacked from top to bottom. So when a curve c at the bottom is pushed up 
	// the resulting curve at the top is w(c) = w_1( ... w_n(c) ... ), i.e. mapping
	// classes act on the left.
	if (gluing != "")  // Twist / drill (if needed).
	{
		size_t marker = 0;
		
		do
		{
			std::string action_name = find_next_substring(gluing, separator, marker);
			
			if (action_name == "") continue;  // Skip it if there is no action.
			
			bool drilling = (action_name.substr(0, 1) == drill);  // Are we drilling?
			if (drilling) action_name = action_name.substr(1);  // If so, drop the drill symbol.
			
			bool performed_action = false;  // Records if we actually performed an action.
			
			for (int i = 0; i < num_annuli; i++)
			{
				if ((annulus_name[i] == action_name) || (annulus_name_inverse[i] == action_name))
				{
					if (drilling)
						annuli[i].drill();
					else
						annuli[i].twist((annulus_name[i] == action_name) ? plus : minus);
					
					performed_action = true;
					break;  // Annuli / rectangle names are unique, so we can give up if we get a hit.
				}
			}
			if (performed_action) continue;
			
			for (int i = 0; i < num_rectangles; i++)
			{
				if ((rectangle_name[i] == action_name) || (rectangle_name_inverse[i] == action_name))
				{
					if (drilling)
						rectangles[i].drill();
					else
						rectangles[i].half_twist((rectangle_name[i] == action_name) ? plus : minus);
					
					performed_action = true;
					break;  // Annuli / rectangle names are unique, so we can give up if we get a hit.
				}
			}
			if (performed_action) continue;
			
			// If our action_name didn't match any curves then throw a warning.
			output_warning("No annulus or rectangle named '" + action_name + "' found to twist or half-twist.");
		} while (marker != 0);
	}
	
	M.tidy_boundary();
	
	return;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x268, %rsp            # imm = 0x268
movq %rcx, %r12
movq %rdx, (%rsp)
movq %rdi, %r15
xorps %xmm0, %xmm0
movaps %xmm0, 0xf0(%rsp)
andq $0x0, 0x100(%rsp)
movaps %xmm0, 0x110(%rsp)
andq $0x0, 0x120(%rsp)
movaps %xmm0, 0x10(%rsp)
andq $0x0, 0x20(%rsp)
movaps %xmm0, 0x70(%rsp)
andq $0x0, 0x80(%rsp)
movaps %xmm0, 0x50(%rsp)
andq $0x0, 0x60(%rsp)
movaps %xmm0, 0xb0(%rsp)
andq $0x0, 0xc0(%rsp)
movaps %xmm0, 0xd0(%rsp)
andq $0x0, 0xe0(%rsp)
movaps %xmm0, 0x150(%rsp)
andq $0x0, 0x160(%rsp)
leaq 0x1e8(%rsp), %rbx
movq %rbx, %rdi
callq 0x32e0
leaq 0x150(%rsp), %r14
leaq 0xd0(%rsp), %rax
leaq 0xb0(%rsp), %r10
leaq 0xf0(%rsp), %rsi
leaq 0x110(%rsp), %rdx
leaq 0x10(%rsp), %rcx
leaq 0x70(%rsp), %r8
leaq 0x50(%rsp), %r9
movq %r15, %rdi
pushq %rbx
pushq %r14
pushq %rax
pushq %r10
callq 0x3fe8
addq $0x20, %rsp
leaq 0x1e8(%rsp), %rdi
callq 0x3458
subq $0x8, %rsp
leaq 0x18(%rsp), %rsi
leaq 0x78(%rsp), %rdx
leaq 0x58(%rsp), %rcx
leaq 0xb8(%rsp), %r8
leaq 0xd8(%rsp), %r9
movq %r12, %rdi
pushq %r14
callq 0x9a39
popq %rax
popq %rcx
subq $0x8, %rsp
leaq 0x18(%rsp), %rsi
leaq 0x78(%rsp), %rdx
leaq 0x58(%rsp), %rcx
leaq 0xb8(%rsp), %r8
leaq 0xd8(%rsp), %r9
movq 0x8(%rsp), %rdi
pushq %r14
callq 0x9a39
popq %rax
popq %rcx
leaq 0xb615(%rip), %rsi      # 0x111ba
leaq 0x30(%rsp), %rdi
movq %r12, %rdx
callq 0x3ebd
leaq 0xb613(%rip), %rdx      # 0x111cc
leaq 0x90(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0x3f33
leaq 0x130(%rsp), %rdi
leaq 0x90(%rsp), %rsi
movq (%rsp), %rdx
callq 0x6703
leaq 0xb474(%rip), %rdx      # 0x1105f
leaq 0x188(%rsp), %rdi
leaq 0x130(%rsp), %rsi
callq 0x3f33
leaq 0x188(%rsp), %rdi
pushq $0x1
popq %rsi
callq 0x3d1a
leaq 0x188(%rsp), %rdi
callq 0x3458
leaq 0x130(%rsp), %rdi
callq 0x3458
leaq 0x90(%rsp), %rdi
callq 0x3458
leaq 0x30(%rsp), %rdi
callq 0x3458
movq 0x18(%rsp), %rax
subq 0x10(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x58(%rsp), %rax
subq 0x50(%rsp), %rax
movq %rax, 0x8(%rsp)
leaq 0xb6a9(%rip), %rsi      # 0x1130f
movq %r12, %rdi
callq 0x62e5
shrq $0x5, 0x28(%rsp)
testb %al, %al
movq %r15, 0x88(%rsp)
je 0x5e00
leaq 0x30(%rsp), %rbx
andq $0x0, (%rbx)
xorl %r15d, %r15d
movq 0x28(%rsp), %rax
testl %eax, %eax
cmovgl %eax, %r15d
leaq 0x168(%rsp), %rdi
leaq 0x1c8(%rsp), %r14
leaq 0x130(%rsp), %rbp
movq %r12, %rsi
callq 0x32e0
movq %r14, %rdi
leaq 0x13743(%rip), %rsi     # 0x19408
callq 0x32e0
movq %rbp, %rdi
leaq 0x168(%rsp), %r13
movq %r13, %rsi
movq %r14, %rdx
movq %rbx, %rcx
callq 0x8133
movq %r14, %rdi
callq 0x3458
movq %r13, %rdi
callq 0x3458
movq %rbp, %rdi
leaq 0xb612(%rip), %rsi      # 0x1130f
callq 0x631c
testb %al, %al
jne 0x5dd4
movq %r12, %r14
xorl %ecx, %ecx
cmpq %r15, %rcx
je 0x5d7b
movq %rcx, %rbx
movq %rcx, %r12
shlq $0x5, %r12
movq 0x10(%rsp), %rdi
addq %r12, %rdi
movq %rbp, %rsi
callq 0x6722
testb %al, %al
jne 0x5d4a
movq 0x70(%rsp), %rdi
addq %r12, %rdi
movq %rbp, %rsi
callq 0x6722
leaq 0x1(%rbx), %rcx
testb %al, %al
je 0x5d0f
imulq $0x18, %rbx, %rbx
addq 0xf0(%rsp), %rbx
addq 0x10(%rsp), %r12
movq %r12, %rdi
movq %rbp, %rsi
callq 0x6722
movzbl %al, %esi
movq %rbx, %rdi
callq 0xb8d2
movq %r14, %r12
leaq 0x30(%rsp), %rbx
jmp 0x5dd4
leaq 0x90(%rsp), %rbx
movq %rbx, %rdi
leaq 0xb450(%rip), %rsi      # 0x111dd
movq %rbp, %rdx
callq 0x3ebd
leaq 0x248(%rsp), %r13
movq %r13, %rdi
movq %rbx, %rsi
leaq 0xb446(%rip), %rdx      # 0x111f0
callq 0x3f33
leaq 0x30(%rsp), %rbx
movq %r14, %r12
movq %r13, %rdi
callq 0x3d6c
movq %r13, %rdi
callq 0x3458
leaq 0x90(%rsp), %rdi
callq 0x3458
movq %rbp, %rdi
callq 0x3458
cmpq $0x0, 0x30(%rsp)
leaq 0x168(%rsp), %rdi
leaq 0x1c8(%rsp), %r14
jne 0x5cb3
movq 0x88(%rsp), %r15
movq %r15, %rdi
callq 0xc7d2
shrq $0x5, 0x8(%rsp)
movq 0x58(%r15), %rax
movq 0x60(%r15), %rcx
subq %rax, %rcx
shrq $0x2, %rcx
xorl %edx, %edx
testl %ecx, %ecx
cmovlel %edx, %ecx
cmpq %rdx, %rcx
je 0x5e35
movl $0x2, (%rax,%rdx,4)
incq %rdx
jmp 0x5e24
movq 0x40(%r15), %rax
movq 0x48(%r15), %rcx
subq %rax, %rcx
shrq $0x3, %rcx
xorl %edx, %edx
testl %ecx, %ecx
cmovlel %edx, %ecx
cmpq %rdx, %rcx
je 0x5e5d
movq (%rax,%rdx,8), %rsi
movb $0x0, 0x32(%rsi)
incq %rdx
jmp 0x5e4b
leaq 0xb4ab(%rip), %rsi      # 0x1130f
movq (%rsp), %rdi
callq 0x62e5
testb %al, %al
je 0x60fa
leaq 0x30(%rsp), %r14
andq $0x0, (%r14)
xorl %eax, %eax
movq 0x28(%rsp), %rbp
testl %ebp, %ebp
cmovlel %eax, %ebp
movq 0x8(%rsp), %rcx
testl %ecx, %ecx
cmovlel %eax, %ecx
movq %rcx, 0x8(%rsp)
leaq 0x228(%rsp), %rdi
leaq 0x1a8(%rsp), %r15
leaq 0x130(%rsp), %rbx
movq %rdi, %r13
movq (%rsp), %rsi
callq 0x32e0
movq %r15, %rdi
leaq 0x13541(%rip), %rsi     # 0x19408
callq 0x32e0
movq %rbx, %rdi
movq %r13, %r12
movq %r13, %rsi
movq %r15, %rdx
movq %r14, %rcx
callq 0x8133
movq %r15, %rdi
callq 0x3458
movq %r12, %rdi
callq 0x3458
movq %rbx, %rdi
leaq 0xb415(%rip), %rsi      # 0x1130f
callq 0x631c
testb %al, %al
jne 0x60d3
leaq 0x90(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
xorl %edx, %edx
pushq $0x1
popq %rcx
callq 0x3260
movq %r14, %rdi
leaq 0x134ff(%rip), %rsi     # 0x19428
callq 0x6722
movl %eax, %r12d
movq %r14, %rdi
callq 0x3458
testb %r12b, %r12b
je 0x5f62
movq %r14, %rdi
movq %rbx, %rsi
pushq $0x1
popq %rdx
pushq $-0x1
popq %rcx
callq 0x3260
movq %rbx, %rdi
movq %r14, %rsi
callq 0x32a0
movq %r14, %rdi
callq 0x3458
xorl %ecx, %ecx
cmpq %rbp, %rcx
je 0x5fc2
movq %rcx, %r15
movq %rcx, %r14
shlq $0x5, %r14
movq 0x10(%rsp), %rdi
addq %r14, %rdi
movq %rbx, %rsi
callq 0x6722
testb %al, %al
jne 0x5f9f
movq 0x70(%rsp), %rdi
addq %r14, %rdi
movq %rbx, %rsi
callq 0x6722
leaq 0x1(%r15), %rcx
testb %al, %al
je 0x5f64
imulq $0x18, %r15, %r15
addq 0xf0(%rsp), %r15
testb %r12b, %r12b
je 0x602f
movq %r15, %rdi
callq 0xc5b2
leaq 0x30(%rsp), %r14
jmp 0x60d3
xorl %ecx, %ecx
cmpq 0x8(%rsp), %rcx
je 0x6056
movq %rcx, %r15
movq %rcx, %r14
shlq $0x5, %r14
movq 0x50(%rsp), %rdi
addq %r14, %rdi
movq %rbx, %rsi
callq 0x6722
testb %al, %al
jne 0x6008
movq 0xb0(%rsp), %rdi
addq %r14, %rdi
movq %rbx, %rsi
callq 0x6722
leaq 0x1(%r15), %rcx
testb %al, %al
je 0x5fc4
imulq $0x28, %r15, %r15
addq 0x110(%rsp), %r15
testb %r12b, %r12b
je 0x60ae
movq %r15, %rdi
callq 0xcc4e
leaq 0x30(%rsp), %r14
jmp 0x60d3
addq 0x10(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x6722
movzbl %al, %esi
decl %esi
orl $0x1, %esi
movq %r15, %rdi
callq 0xbd60
leaq 0x30(%rsp), %r14
jmp 0x60d3
leaq 0x90(%rsp), %r14
movq %r14, %rdi
leaq 0xb1a7(%rip), %rsi      # 0x1120f
movq %rbx, %rdx
callq 0x3ebd
leaq 0x208(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
leaq 0xb1aa(%rip), %rdx      # 0x1122f
callq 0x3f33
leaq 0x30(%rsp), %r14
movq %r15, %rdi
callq 0x3d6c
movq %r15, %rdi
callq 0x3458
leaq 0x90(%rsp), %rdi
callq 0x3458
jmp 0x60d3
addq 0x50(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x6722
movzbl %al, %esi
decl %esi
orl $0x1, %esi
movq %r15, %rdi
callq 0xd1ce
leaq 0x30(%rsp), %r14
movq %rbx, %rdi
callq 0x3458
cmpq $0x0, 0x30(%rsp)
movq %r13, %rdi
leaq 0x1a8(%rsp), %r15
jne 0x5eb1
movq 0x88(%rsp), %r15
movq %r15, %rdi
callq 0xeb5e
leaq 0x150(%rsp), %rdi
callq 0x66e2
leaq 0xd0(%rsp), %rdi
callq 0x66e2
leaq 0xb0(%rsp), %rdi
callq 0x66e2
leaq 0x50(%rsp), %rdi
callq 0x66e2
leaq 0x70(%rsp), %rdi
callq 0x66e2
leaq 0x10(%rsp), %rdi
callq 0x66e2
leaq 0x110(%rsp), %rdi
callq 0x674c
leaq 0xf0(%rsp), %rdi
callq 0x676e
addq $0x268, %rsp            # imm = 0x268
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq 0x208(%rsp), %rdi
callq 0x3458
jmp 0x6188
movq %rax, %rbx
leaq 0x90(%rsp), %rdi
callq 0x3458
jmp 0x622c
jmp 0x6229
movq %rax, %rbx
leaq 0x188(%rsp), %rdi
callq 0x3458
jmp 0x61b4
movq %rax, %rbx
leaq 0x130(%rsp), %rdi
callq 0x3458
jmp 0x61c6
movq %rax, %rbx
leaq 0x90(%rsp), %rdi
callq 0x3458
jmp 0x61d8
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
jmp 0x6279
jmp 0x6257
movq %rax, %rbx
leaq 0x1e8(%rsp), %rdi
jmp 0x6279
jmp 0x6229
movq %rax, %rbx
leaq 0x248(%rsp), %rdi
callq 0x3458
jmp 0x620b
movq %rax, %rbx
leaq 0x90(%rsp), %rdi
callq 0x3458
jmp 0x6227
jmp 0x6224
jmp 0x6257
jmp 0x6229
jmp 0x6257
jmp 0x6229
movq %rax, %rbx
jmp 0x622c
movq %rax, %rbx
leaq 0x130(%rsp), %rdi
jmp 0x6279
jmp 0x6257
movq %rax, %rbx
jmp 0x624d
movq %rax, %rbx
leaq 0x1a8(%rsp), %rdi
callq 0x3458
leaq 0x228(%rsp), %rdi
jmp 0x6279
movq %rax, %rbx
jmp 0x627e
movq %rax, %rbx
jmp 0x6271
movq %rax, %rbx
leaq 0x1c8(%rsp), %rdi
callq 0x3458
leaq 0x168(%rsp), %rdi
callq 0x3458
leaq 0x150(%rsp), %rdi
callq 0x66e2
leaq 0xd0(%rsp), %rdi
callq 0x66e2
leaq 0xb0(%rsp), %rdi
callq 0x66e2
leaq 0x50(%rsp), %rdi
callq 0x66e2
leaq 0x70(%rsp), %rdi
callq 0x66e2
leaq 0x10(%rsp), %rdi
callq 0x66e2
leaq 0x110(%rsp), %rdi
callq 0x674c
leaq 0xf0(%rsp), %rdi
callq 0x676e
movq %rbx, %rdi
callq 0x33d0