// File: /workspace/github_cpp_makefile_star2_O1/cpottamus[P]btree_lab/btree.cc
// Function: BTreeIndex::Rebalance(unsigned int const&, std::vector<unsigned int, std::allocator<unsigned int>>)
ERROR_T BTreeIndex::Rebalance(const SIZE_T &node, std::vector<SIZE_T> ptrPath)
{
  BTreeNode b;
  BTreeNode leftNode;
  BTreeNode rightNode;
  ERROR_T rc;
  SIZE_T offset;
    
  int newType;
  //SIZE_T ptr;
  rc = b.Unserialize(buffercache, node);
  if (rc) { return rc;}
  //std::cout<<":::: Allocating new Nodes :::::"<<std::endl;
  //Allocate 2 new nodes, fill them from the place you're splitting
  SIZE_T leftPtr;
  SIZE_T rightPtr;
  AllocateNode(leftPtr);
  if(b.info.nodetype == BTREE_LEAF_NODE){
    newType = BTREE_LEAF_NODE;
  }else{
    newType = BTREE_INTERIOR_NODE;
  }
  leftNode = BTreeNode(newType, superblock.info.keysize, superblock.info.valuesize, superblock.info.blocksize);
  rc = leftNode.Serialize(buffercache, leftPtr);
  AllocateNode(rightPtr);
  rightNode = BTreeNode(newType, superblock.info.keysize, superblock.info.valuesize, superblock.info.blocksize);
  rc = rightNode.Serialize(buffercache, rightPtr);
  //Unserialize to write to new nodes
  rc = leftNode.Unserialize(buffercache, leftPtr);
  if (rc) { return rc;}
  rc = rightNode.Unserialize(buffercache, rightPtr);
  if (rc) { return rc;}

  //Variables to hold spot/key vals  
  KEY_T keySpot;
  KEY_T testKey;
  VALUE_T valSpot;
  SIZE_T ptrSpot;

  //Find splitting point
  int midpoint = (b.info.numkeys+0.5)/2;

  //If A leafNode
  if(b.info.nodetype==BTREE_LEAF_NODE){
  //Build left leaf node, include the splitting key (this is a <= B+ tree)
    for(offset = 0; (int)offset < midpoint; offset++){
      //std::cout<<":::: OFFSET for building new left leaf node = "<<offset<<std::endl;
      leftNode.info.numkeys++;

    //Get old node values
      rc = b.GetKey(offset, keySpot);
      if (rc) { return rc;}
      rc = b.GetVal(offset, valSpot);
      if (rc) { return rc;}
    //set values in new left node.
      rc = leftNode.SetKey(offset, keySpot);
      if (rc) { return rc;}
      rc = leftNode.SetVal(offset, valSpot);
      if (rc) { return rc;}
    }
  //Build right leaf node
    int spot=0;
    for(offset = midpoint; offset<b.info.numkeys; offset++){
      //std::cout<<":::: OFFSET (spot) for building new right leaf node = "<<spot<<std::endl;
      //std::cout<<":::: Total Block OFFSET (offset), while rebuilding right leaf node"<<offset<<std::endl;
    //Get values from old node.
      rightNode.info.numkeys++;
      rc = b.GetKey(offset, keySpot);
      if (rc) { return rc;}
      rc = b.GetVal(offset, valSpot);
      if (rc) { return rc;}
    //set values in new right node.
      rc = rightNode.SetKey(spot, keySpot);
      if (rc) { return rc;}
      rc = rightNode.SetVal(spot, valSpot);
      if (rc) { return rc;}
      spot++;
    }
  } else {//if it's an interior node.
      //Build left interior node
  for(offset = 0; (int)offset < midpoint; offset++){
    //std::cout<<":::: OFFSET for building new left interior node = "<<offset<<std::endl;
    leftNode.info.numkeys++;
        //Get old key and pointers
    rc = b.GetKey(offset, keySpot);
    if (rc) { return rc;}
    rc = b.GetPtr(offset, ptrSpot);
    if (rc) { return rc;}
        //Set new key and Pointer vals
    rc = leftNode.SetKey(offset, keySpot);
    if (rc) { return rc;}
    rc = leftNode.SetPtr(offset, ptrSpot);
  }
      //Build Right interior node
  int spot=0;
  for(offset = midpoint; offset<b.info.numkeys; offset++){
    //std::cout<<":::: OFFSET (spot) for building new right interior node = "<<spot<<std::endl;
    //std::cout<<":::: Total Block OFFSET (offset), while rebuilding right interior node"<<offset<<std::endl;
    rightNode.info.numkeys++;
    //Get values from old node.
    rc = b.GetKey(offset, keySpot);
    if (rc) { return rc;}
    rc = b.GetPtr(offset, ptrSpot);
    if (rc) { return rc;}
    //set values in new right node.
    rc = rightNode.SetKey(spot, keySpot);
    if (rc) { return rc;}
    rc = rightNode.SetPtr(spot, ptrSpot);
    if (rc) { return rc;}
    spot++;
  }
  rc = b.GetPtr(offset, ptrSpot);
  if (rc) { return rc;}
  rc = rightNode.SetPtr(spot, ptrSpot);
  if (rc) { return rc;}
}
  //Serialize the new nodes
rc = leftNode.Serialize(buffercache, leftPtr);
if (rc) { return rc;}
rc = rightNode.Serialize(buffercache, rightPtr);
if (rc) { return rc;}
rc = b.Serialize(buffercache, node);

  //Find split key
KEY_T splitKey;
rc = b.GetKey(midpoint-1, splitKey);
if (rc) { return rc;}


  //If we're all the way up at the root, we need to make a new root.
  //  std::cout << ":::: NODE TYPE = " << b.info.nodetype << std::endl;
    
  //  std::cout<<"current node nodetype :::: "<<b.info.nodetype<<std::endl;
if (b.info.nodetype == BTREE_ROOT_NODE) {
  //std::cout<<":::: AT THE TOP, BUILDING A NEW ROOT ::::"<<std::endl;
  SIZE_T newRootPtr;
  BTreeNode newRootNode;
  AllocateNode(newRootPtr);
  newRootNode = BTreeNode(BTREE_ROOT_NODE, superblock.info.keysize, superblock.info.valuesize, superblock.info.blocksize);
  superblock.info.rootnode = newRootPtr;
    newRootNode.info.rootnode = newRootPtr;
    newRootNode.info.numkeys = 1;
    newRootNode.SetKey(0, splitKey);
    newRootNode.SetPtr(0, leftPtr);
    newRootNode.SetPtr(1, rightPtr);
  rc = newRootNode.Serialize(buffercache, newRootPtr);
  if(rc) {return rc;}
//std::cout<<"::: We made it here! Root node"<<std::endl;
}
else{
//Find the parent node
  SIZE_T parentPtr = ptrPath.back();
//  std::cout<<"WE BUILT THIS CITY ON ROCK AND ROLL COW ::: "<<parentPtr<<std::endl;
      //std::cout<<"ALSO THIS  IN OUR REBALANCE::: "<<ptrPath.size()<<std::endl;
//    for(int i =ptrPath.size()-1; i>=0; i--) {
//        std::cout<<"Little sumpin"<<ptrPath.at(i)<<std::endl;
//      }
  ptrPath.pop_back();
  BTreeNode parentNode;
  rc = parentNode.Unserialize(buffercache, parentPtr);
  if(rc) {return rc;}

    if (parentNode.info.nodetype == BTREE_SUPERBLOCK) {
        AllocateNode(parentPtr);
        
    }
//Increment the key count for the given node.
  //parentNode.info.numkeys++;
    
    BTreeNode newParentNode = BTreeNode(parentNode.info.nodetype, superblock.info.keysize, superblock.info.valuesize, superblock.info.blocksize);
    newParentNode.info.numkeys = parentNode.info.numkeys + 1;
    newParentNode.info.freelist = parentNode.info.freelist;
    
    bool newKeyInserted = false;
    for (offset = 0; offset < newParentNode.info.numkeys - 1; offset++) {
        rc = parentNode.GetKey(offset, testKey);
        //    if(rc){ return rc;}
        if (newKeyInserted) {
            rc = parentNode.GetKey(offset, keySpot);
            newParentNode.SetKey(offset + 1, keySpot);
            
            rc = parentNode.GetPtr(offset + 1, ptrSpot);
            newParentNode.SetPtr(offset + 2, ptrSpot);
        } else {
            if (splitKey < testKey) {
                newKeyInserted = true;
                newParentNode.SetPtr(offset, leftPtr);
                newParentNode.SetKey(offset, splitKey);
                newParentNode.SetPtr(offset+1, rightPtr);
                offset = offset - 1;
                
            } else {
                rc = parentNode.GetKey(offset, keySpot);
                if (rc) {return rc;}
                rc = newParentNode.SetKey(offset, keySpot);
                if (rc) {return rc;}
                
                rc = parentNode.GetPtr(offset, ptrSpot);
                if (rc) {return rc;}
                rc = newParentNode.SetPtr(offset, ptrSpot);
                if (rc) {return rc;}
            }
        }
    }
    if (newKeyInserted == false) {
        newKeyInserted = true;
        newParentNode.SetPtr(offset, leftPtr);
        newParentNode.SetKey(offset, splitKey);
        newParentNode.SetPtr(offset+1, rightPtr);
    }
    
    newParentNode.Serialize(buffercache, parentPtr);
    
    
//find split keys spot in parent (interior) node, insert it and update keys and pointers.
//  for(offset = 0; offset<parentNode.info.numkeys-1; offset++){
//    //std::cout<<":::: Searching Interior Nodes for splitKey Insertion ::::: offset = "<<offset<<std::endl;
//    rc = parentNode.GetKey(offset, testKey);
//    if(rc){ return rc;}
//    if(splitKey < testKey || splitKey == testKey){ // if testkey > splitkey
//      //std::cout<<":::: Moving through the parent node for rebalance insertion ::: Number of keys in parent = "<<parentNode.info.numkeys<<std::endl;
//      //std::cout<<":::: Moving through the parent node for rebalance insertion ::: parent nodetype = "<<parentNode.info.nodetype<<std::endl;
//          //Once you've found the insertion point for the new key, move all other keys & pointers over by 1
//      for(offset2= parentNode.info.numkeys-2 ; offset2 >= offset; offset2-- ){
//        //std::cout<<":::: Found INSERTION POINT, moving spots over :::: = offset"<<offset<<std::endl;
//            //Grab the old key and pointer
//        rc = parentNode.GetKey(offset2, keySpot);
//        if(rc){ return rc;}
//        rc = parentNode.GetPtr(offset2, ptrSpot);
//        if(rc){ return rc;}
//            //Move it up by 1
//        rc = parentNode.SetKey(offset2+1, keySpot);
//        if(rc){ return rc;}
//        rc = parentNode.SetPtr(offset2+2, ptrSpot);
//      }
//          //We now have moved every pointer over except for the  1 to the immediate right of where we will be inserting our splitKey
//          //Set our pointers and our new key
//      rc = parentNode.SetPtr(offset2+1, rightPtr);
//      if(rc){ return rc;}
//      rc = parentNode.SetPtr(offset,leftPtr);
//      if(rc){ return rc;}
//      rc = parentNode.SetKey(offset, splitKey);
//      if(rc){ return rc;}
//
//      break;
//    }
//  }


  //Check the length of the node and call rebalance if necessary
  //parentNode.Serialize(buffercache, parentPtr);

  if((int)newParentNode.info.numkeys > (int)(2*maxNumKeys/3)){
    rc = Rebalance(parentPtr, ptrPath);
    if(rc){ return rc;}
  }
}
  //Deallocate the old (too large) node
DeallocateNode(node);
return ERROR_NOERROR;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1b8, %rsp            # imm = 0x1B8
movq %rdx, %r15
movq %rsi, %rbx
movq %rdi, %r14
leaq 0x80(%rsp), %rdi
callq 0x7d2a
leaq 0x100(%rsp), %rdi
callq 0x7d2a
leaq 0xd8(%rsp), %rdi
callq 0x7d2a
movq 0x8(%r14), %rsi
movl (%rbx), %edx
leaq 0x80(%rsp), %rdi
callq 0x7eee
movl %eax, %ebp
testl %eax, %eax
jne 0x696e
leaq 0x14(%rsp), %rsi
movq %r14, %rdi
callq 0x5630
xorl %ebp, %ebp
cmpl $0x4, 0x80(%rsp)
sete %bpl
addl $0x3, %ebp
movl 0x1c(%r14), %edx
movl 0x20(%r14), %ecx
movl 0x24(%r14), %r8d
leaq 0x58(%rsp), %rdi
movl %ebp, %esi
callq 0x7d5c
leaq 0x100(%rsp), %rdi
leaq 0x58(%rsp), %rsi
callq 0x7e1a
leaq 0x58(%rsp), %rdi
callq 0x7d3a
movq 0x8(%r14), %rsi
movl 0x14(%rsp), %edx
leaq 0x100(%rsp), %rdi
callq 0x7e28
leaq 0x10(%rsp), %rsi
movq %r14, %rdi
callq 0x5630
movl 0x1c(%r14), %edx
movl 0x20(%r14), %ecx
movl 0x24(%r14), %r8d
leaq 0x58(%rsp), %rdi
movl %ebp, %esi
callq 0x7d5c
leaq 0xd8(%rsp), %rdi
leaq 0x58(%rsp), %rsi
callq 0x7e1a
leaq 0x58(%rsp), %rdi
callq 0x7d3a
movq 0x8(%r14), %rsi
movl 0x10(%rsp), %edx
leaq 0xd8(%rsp), %rdi
callq 0x7e28
movq 0x8(%r14), %rsi
movl 0x14(%rsp), %edx
leaq 0x100(%rsp), %rdi
callq 0x7eee
movl %eax, %ebp
testl %eax, %eax
jne 0x696e
movq 0x8(%r14), %rsi
movl 0x10(%rsp), %edx
leaq 0xd8(%rsp), %rdi
callq 0x7eee
movl %eax, %ebp
testl %eax, %eax
jne 0x696e
leaq 0x58(%rsp), %rdi
callq 0x2c54
leaq 0x190(%rsp), %rdi
callq 0x2c54
leaq 0x168(%rsp), %rdi
callq 0x2c54
movq %r15, 0xd0(%rsp)
movq %rbx, 0x28(%rsp)
movl 0x98(%rsp), %eax
cvtsi2sd %rax, %xmm0
movsd 0x3098(%rip), %xmm1     # 0x9688
addsd %xmm1, %xmm0
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
cmpl $0x4, 0x80(%rsp)
movq %rax, 0x18(%rsp)
jne 0x6781
testl %eax, %eax
jle 0x66aa
xorl %r13d, %r13d
leaq 0x80(%rsp), %r15
leaq 0x58(%rsp), %r12
leaq 0x168(%rsp), %rbx
incl 0x118(%rsp)
movq %r15, %rdi
movl %r13d, %esi
movq %r12, %rdx
callq 0x8114
movl %eax, %ebp
testl %eax, %eax
jne 0x694a
movq %r15, %rdi
movl %r13d, %esi
movq %rbx, %rdx
callq 0x8180
movl %eax, %ebp
testl %eax, %eax
jne 0x694a
leaq 0x100(%rsp), %rdi
movl %r13d, %esi
movq %r12, %rdx
callq 0x8202
movl %eax, %ebp
testl %eax, %eax
jne 0x694a
leaq 0x100(%rsp), %rdi
movl %r13d, %esi
movq %rbx, %rdx
callq 0x8256
movl %eax, %ebp
testl %eax, %eax
jne 0x694a
incl %r13d
cmpl %r13d, 0x18(%rsp)
jne 0x662f
movq 0x18(%rsp), %rax
cmpl %eax, 0x98(%rsp)
seta %r15b
jbe 0x68e1
xorl %r13d, %r13d
movq 0x28(%rsp), %r12
movq 0x18(%rsp), %rdx
leal (%rdx,%r13), %ebx
incl 0xf0(%rsp)
leaq 0x80(%rsp), %rdi
movl %ebx, %esi
leaq 0x58(%rsp), %rdx
callq 0x8114
movl %eax, %ebp
testl %eax, %eax
jne 0x68e6
leaq 0x80(%rsp), %rdi
movl %ebx, %esi
leaq 0x168(%rsp), %rdx
callq 0x8180
movl %eax, %ebp
testl %eax, %eax
jne 0x68e6
leaq 0xd8(%rsp), %rdi
movl %r13d, %esi
leaq 0x58(%rsp), %rdx
callq 0x8202
movl %eax, %ebp
testl %eax, %eax
jne 0x68e6
leaq 0xd8(%rsp), %rdi
movl %r13d, %esi
leaq 0x168(%rsp), %rdx
callq 0x8256
movl %eax, %ebp
testl %eax, %eax
jne 0x68e6
movq 0x18(%rsp), %rdx
leal (%rdx,%r13), %eax
incl %eax
movl %r13d, %ecx
incl %ecx
movl %ecx, %r13d
cmpl 0x98(%rsp), %eax
setb %r15b
jb 0x66cd
jmp 0x68eb
testl %eax, %eax
jle 0x680f
xorl %r15d, %r15d
leaq 0x80(%rsp), %r12
leaq 0x58(%rsp), %r13
leaq 0xc(%rsp), %rbx
incl 0x118(%rsp)
movq %r12, %rdi
movl %r15d, %esi
movq %r13, %rdx
callq 0x8114
movl %eax, %ebp
testl %eax, %eax
jne 0x694a
movq %r12, %rdi
movl %r15d, %esi
movq %rbx, %rdx
callq 0x8162
movl %eax, %ebp
testl %eax, %eax
jne 0x694a
leaq 0x100(%rsp), %rdi
movl %r15d, %esi
movq %r13, %rdx
callq 0x8202
movl %eax, %ebp
testl %eax, %eax
jne 0x694a
leaq 0x100(%rsp), %rdi
movl %r15d, %esi
movq %rbx, %rdx
callq 0x8238
incl %r15d
cmpl %r15d, 0x18(%rsp)
jne 0x679e
xorl %r13d, %r13d
movq 0x18(%rsp), %r15
movl %r15d, %esi
cmpl %r15d, 0x98(%rsp)
movq 0x28(%rsp), %r12
jbe 0x68c5
xorl %r13d, %r13d
leal (%r15,%r13), %ebx
incl 0xf0(%rsp)
leaq 0x80(%rsp), %rdi
movl %ebx, %esi
leaq 0x58(%rsp), %rdx
callq 0x8114
movl %eax, %ebp
testl %eax, %eax
jne 0x68dd
leaq 0x80(%rsp), %rdi
movl %ebx, %esi
leaq 0xc(%rsp), %rdx
callq 0x8162
movl %eax, %ebp
testl %eax, %eax
jne 0x68dd
leaq 0xd8(%rsp), %rdi
movl %r13d, %esi
leaq 0x58(%rsp), %rdx
callq 0x8202
movl %eax, %ebp
testl %eax, %eax
jne 0x68dd
leaq 0xd8(%rsp), %rdi
movl %r13d, %esi
leaq 0xc(%rsp), %rdx
callq 0x8238
movl %eax, %ebp
testl %eax, %eax
jne 0x68dd
movl %r13d, %eax
incl %r13d
addl %r15d, %eax
incl %eax
cmpl 0x98(%rsp), %eax
jb 0x6830
leal (%r15,%r13), %esi
leaq 0x80(%rsp), %rdi
leaq 0xc(%rsp), %rdx
callq 0x8162
movl %eax, %ebp
testl %eax, %eax
je 0x68f6
xorl %eax, %eax
jmp 0x6912
movq 0x28(%rsp), %r12
movq 0x18(%rsp), %rdx
testb $0x1, %r15b
movq %rdx, %r15
je 0x6916
jmp 0x694a
leaq 0xd8(%rsp), %rdi
leaq 0xc(%rsp), %rdx
movl %r13d, %esi
callq 0x8238
movl %eax, %ebp
testl %eax, %eax
sete %al
testb %al, %al
je 0x694a
movq 0x8(%r14), %rsi
movl 0x14(%rsp), %edx
leaq 0x100(%rsp), %rdi
callq 0x7e28
testl %eax, %eax
jne 0x6948
movq 0x8(%r14), %rsi
movl 0x10(%rsp), %edx
leaq 0xd8(%rsp), %rdi
callq 0x7e28
testl %eax, %eax
je 0x69a9
movl %eax, %ebp
leaq 0x168(%rsp), %rdi
callq 0x2e22
leaq 0x190(%rsp), %rdi
callq 0x2e22
leaq 0x58(%rsp), %rdi
callq 0x2e22
leaq 0xd8(%rsp), %rdi
callq 0x7d3a
leaq 0x100(%rsp), %rdi
callq 0x7d3a
leaq 0x80(%rsp), %rdi
callq 0x7d3a
movl %ebp, %eax
addq $0x1b8, %rsp            # imm = 0x1B8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x8(%r14), %rsi
movl (%r12), %edx
leaq 0x80(%rsp), %rdi
callq 0x7e28
leaq 0x140(%rsp), %rdi
callq 0x2c54
decl %r15d
leaq 0x80(%rsp), %rdi
leaq 0x140(%rsp), %rdx
movl %r15d, %esi
callq 0x8114
movl %eax, %ebx
testl %eax, %eax
jne 0x6dc3
cmpl $0x2, 0x80(%rsp)
jne 0x6ad7
leaq 0xa8(%rsp), %rdi
callq 0x7d2a
leaq 0x24(%rsp), %rsi
movq %r14, %rdi
callq 0x5630
movl 0x1c(%r14), %edx
movl 0x20(%r14), %ecx
movl 0x24(%r14), %r8d
leaq 0x30(%rsp), %rdi
movl $0x2, %esi
callq 0x7d5c
leaq 0xa8(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0x7e1a
leaq 0x30(%rsp), %rdi
callq 0x7d3a
movl 0x24(%rsp), %ebx
movl %ebx, 0x28(%r14)
leaq 0xa8(%rsp), %rdi
movl %ebx, 0x10(%rdi)
movl $0x1, 0x18(%rdi)
leaq 0x140(%rsp), %rdx
xorl %esi, %esi
callq 0x8202
leaq 0xa8(%rsp), %rdi
leaq 0x14(%rsp), %rdx
xorl %esi, %esi
callq 0x8238
leaq 0xa8(%rsp), %rdi
leaq 0x10(%rsp), %rdx
movl $0x1, %esi
callq 0x8238
movq 0x8(%r14), %rsi
leaq 0xa8(%rsp), %rdi
movl %ebx, %edx
callq 0x7e28
movl %eax, %ebx
leaq 0xa8(%rsp), %rdi
callq 0x7d3a
testl %ebx, %ebx
cmovnel %ebx, %ebp
movl %ebp, %ebx
jne 0x6dc3
jmp 0x6db6
movq 0xd0(%rsp), %rcx
movq 0x8(%rcx), %rax
movl -0x4(%rax), %ebx
addq $-0x4, %rax
movl %ebx, 0x24(%rsp)
movq %rax, 0x8(%rcx)
leaq 0xa8(%rsp), %rdi
callq 0x7d2a
movq 0x8(%r14), %rsi
leaq 0xa8(%rsp), %rdi
movl %ebx, %edx
callq 0x7eee
testl %eax, %eax
je 0x6b20
xorl %r15d, %r15d
movl %eax, %ebp
jmp 0x6da2
cmpl $0x1, 0xa8(%rsp)
jne 0x6b37
leaq 0x24(%rsp), %rsi
movq %r14, %rdi
callq 0x5630
movl 0xa8(%rsp), %esi
movl 0x1c(%r14), %edx
movl 0x20(%r14), %ecx
movl 0x24(%r14), %r8d
leaq 0x30(%rsp), %rdi
callq 0x7d5c
movl 0xbc(%rsp), %eax
movl 0xc0(%rsp), %ecx
leal 0x1(%rcx), %edx
movl %edx, 0x48(%rsp)
movl %eax, 0x44(%rsp)
testl %ecx, %ecx
je 0x6cc5
xorl %r15d, %r15d
leaq 0xa8(%rsp), %r13
xorl %r12d, %r12d
movq %r13, %rdi
movl %r12d, %esi
leaq 0x190(%rsp), %rdx
callq 0x8114
testb $0x1, %r15b
je 0x6bea
movq %r13, %rdi
movl %r12d, %esi
leaq 0x58(%rsp), %rdx
callq 0x8114
leal 0x1(%r12), %ebx
leaq 0x30(%rsp), %rdi
movl %ebx, %esi
leaq 0x58(%rsp), %rdx
callq 0x8202
movq %r13, %rdi
movl %ebx, %esi
leaq 0xc(%rsp), %rdx
callq 0x8162
leal 0x2(%r12), %esi
leaq 0x30(%rsp), %rdi
leaq 0xc(%rsp), %rdx
callq 0x8238
jmp 0x6caa
leaq 0x140(%rsp), %rdi
leaq 0x190(%rsp), %rsi
callq 0x2ebc
testb %al, %al
je 0x6c46
leaq 0x30(%rsp), %rdi
movl %r12d, %esi
leaq 0x14(%rsp), %rdx
callq 0x8238
leaq 0x30(%rsp), %rdi
movl %r12d, %esi
leaq 0x140(%rsp), %rdx
callq 0x8202
leal 0x1(%r12), %esi
leaq 0x30(%rsp), %rdi
leaq 0x10(%rsp), %rdx
callq 0x8238
decl %r12d
movb $0x1, %r15b
jmp 0x6caa
movq %r13, %rdi
movl %r12d, %esi
leaq 0x58(%rsp), %rdx
callq 0x8114
testl %eax, %eax
jne 0x6d8e
leaq 0x30(%rsp), %rdi
movl %r12d, %esi
leaq 0x58(%rsp), %rdx
callq 0x8202
testl %eax, %eax
jne 0x6d8e
movq %r13, %rdi
movl %r12d, %esi
leaq 0xc(%rsp), %rdx
callq 0x8162
testl %eax, %eax
jne 0x6d8e
leaq 0x30(%rsp), %rdi
movl %r12d, %esi
leaq 0xc(%rsp), %rdx
callq 0x8238
testl %eax, %eax
jne 0x6d8e
incl %r12d
movl 0x48(%rsp), %eax
decl %eax
cmpl %eax, %r12d
jb 0x6b83
testb $0x1, %r15b
sete %al
jmp 0x6cca
movb $0x1, %al
xorl %r12d, %r12d
testb %al, %al
je 0x6d0a
leaq 0x30(%rsp), %rdi
leaq 0x14(%rsp), %rdx
movl %r12d, %esi
callq 0x8238
leaq 0x30(%rsp), %rdi
leaq 0x140(%rsp), %rdx
movl %r12d, %esi
callq 0x8202
incl %r12d
leaq 0x30(%rsp), %rdi
leaq 0x10(%rsp), %rdx
movl %r12d, %esi
callq 0x8238
movq 0x8(%r14), %rsi
movl 0x24(%rsp), %edx
leaq 0x30(%rsp), %rdi
callq 0x7e28
movl 0x40(%r14), %eax
addl %eax, %eax
movl $0xaaaaaaab, %ecx       # imm = 0xAAAAAAAB
imulq %rax, %rcx
shrq $0x21, %rcx
cmpl %ecx, 0x48(%rsp)
jle 0x6d89
leaq 0x128(%rsp), %rdi
movq 0xd0(%rsp), %rsi
callq 0x79e6
leaq 0x24(%rsp), %rsi
leaq 0x128(%rsp), %rdx
movq %r14, %rdi
callq 0x6452
movl %eax, %ebx
movq 0x128(%rsp), %rdi
testq %rdi, %rdi
je 0x6d7e
movq 0x138(%rsp), %rsi
subq %rdi, %rsi
callq 0x21e0
testl %ebx, %ebx
je 0x6d89
xorl %r15d, %r15d
movl %ebx, %ebp
jmp 0x6d93
movb $0x1, %r15b
jmp 0x6d93
xorl %r15d, %r15d
movl %eax, %ebp
movq 0x28(%rsp), %r12
leaq 0x30(%rsp), %rdi
callq 0x7d3a
leaq 0xa8(%rsp), %rdi
callq 0x7d3a
movl %ebp, %ebx
testb %r15b, %r15b
je 0x6dc3
xorl %ebx, %ebx
movq %r14, %rdi
movq %r12, %rsi
callq 0x56e0
leaq 0x140(%rsp), %rdi
callq 0x2e22
movl %ebx, %ebp
jmp 0x694a
movq %rax, %rbx
movq 0x128(%rsp), %rdi
testq %rdi, %rdi
je 0x6e16
movq 0x138(%rsp), %rsi
subq %rdi, %rsi
callq 0x21e0
jmp 0x6e16
jmp 0x6e07
jmp 0x6e13
jmp 0x6e13
jmp 0x6e07
jmp 0x6e0e
jmp 0x6e0e
jmp 0x6e07
movq %rax, %rbx
jmp 0x6e20
jmp 0x6e67
movq %rax, %rbx
jmp 0x6e2d
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x7d3a
leaq 0xa8(%rsp), %rdi
callq 0x7d3a
leaq 0x140(%rsp), %rdi
callq 0x2e22
jmp 0x6e6a
jmp 0x6e67
jmp 0x6e67
movq %rax, %rbx
jmp 0x6e77
movq %rax, %rbx
jmp 0x6e84
jmp 0x6e9c
jmp 0x6e67
jmp 0x6e67
jmp 0x6e54
jmp 0x6e9c
movq %rax, %rbx
leaq 0x58(%rsp), %rdi
callq 0x7d3a
jmp 0x6e9f
jmp 0x6e9c
jmp 0x6e67
movq %rax, %rbx
leaq 0x168(%rsp), %rdi
callq 0x2e22
leaq 0x190(%rsp), %rdi
callq 0x2e22
leaq 0x58(%rsp), %rdi
callq 0x2e22
jmp 0x6e9f
jmp 0x6e9c
movq %rax, %rbx
jmp 0x6eac
movq %rax, %rbx
jmp 0x6eb9
movq %rax, %rbx
leaq 0xd8(%rsp), %rdi
callq 0x7d3a
leaq 0x100(%rsp), %rdi
callq 0x7d3a
leaq 0x80(%rsp), %rdi
callq 0x7d3a
movq %rbx, %rdi
callq 0x2370