// File: /workspace/github_c_makefile_star2_O3/evanwire[P]GitClone/client.c
// Function: commit
void commit(char* project_name){
  //Check if project exists
  DIR* dir = opendir(project_name);
  if(!dir){
    printf("\nError: project does not exist locally. Please create it first.\n");
    exit(1);
  }
  closedir(dir);

  //Check for if the local project has a .Update file
  char update_path[strlen(project_name) + 10];
  strcpy(update_path, "./");
  strcat(update_path, project_name);
  strcat(update_path, "/.Update");
  struct stat update_file;
  if(stat(update_path, &update_file) == 0){
    if(update_file.st_size > 0){
      printf("\nError: your local version of the project has a .Update file that is not empty.\n");
      exit(1);
    }
  }

  //Check for if the local project has a .Conflict file
  char conflict_path[strlen(project_name) + 12];
  strcpy(conflict_path, "./");
  strcat(conflict_path, project_name);
  strcat(conflict_path, "/.Conflict");
  struct stat conflict_file;
  if(stat(conflict_path, &conflict_file) == 0){
    printf("\nError: your local version of the project has a .Conflict file.\n");
    exit(1);
  }

  //Prepare message to server
  int i;
  char to_be_written[strlen(project_name) + 3];
  memset(to_be_written, 0, sizeof(to_be_written));
  to_be_written[0] = 'o';
  to_be_written[1] = ' ';
  int message_idx = 2;
  for(i = 0; i < strlen(project_name); i++){
    if(project_name[i]){
      to_be_written[message_idx] = project_name[i];
      message_idx++;
    }
  }

  //Connect to server, store the response
  char* response = connect_to_WTFserver(to_be_written);

  if(strcmp(response, "e") == 0){
    printf("\nError: project does not exist on server. Make sure you create it first.\n");
    exit(1);
  }else if(strcmp(response, "x") == 0){
    printf("\nError: could not find the manifest file on the server.\n");
    exit(1);
  }

  //Open and tokenize local manifest file
  char manifestPath[sizeof(project_name) + 11];
  strcpy(manifestPath, project_name);
  strcat(manifestPath, "/.Manifest");
  char* local_manifest = readFile(manifestPath);

  //To tokenize the local manifest file by \n
  char* local_token;
  char* l_saveptr = local_manifest;

  //Get the first line of both manifest files and compare them, ultimately checking version numbers
  local_token = strtok_r(l_saveptr, "\n", &l_saveptr);
  for(i = 0; i < strlen(local_token); i++){
    if(local_token[i] != response[i]){
      printf("\nError: the local and server project versions do not match. Please update your local version before running again.\n");
      free(response);
      free(local_manifest);
      exit(1);
    }
  }

  //Creating a path for the commit file
  char commitPath[sizeof(project_name) + 8];
  strcpy(commitPath, project_name);
  strcat(commitPath, "/.Commit");


  int commit_fd = open(commitPath, O_WRONLY | O_TRUNC | O_CREAT, 0777);
  if(commit_fd < 0){
    printf("\nError: could not open/create the .Commit file.");
    close(commit_fd);
    free(response);
    free(local_manifest);
    exit(1);
  }

  //Write project name to commit file
  int first_write = write(commit_fd, project_name, strlen(project_name));
  if(first_write < 0){
    printf("\nError: was unable to write to .Commit file.\n");
    close(commit_fd);
    exit(1);
  }

  first_write = write(commit_fd, "\n", 1);
  if(first_write < 0){
    printf("\nError: was unable to write to .Commit file.\n");
    close(commit_fd);
    exit(1);
  }

  //Loop through local manifest, looking for where files were added, removed or modified
  while(local_token = strtok_r(l_saveptr, "\n", &l_saveptr)){

    //If a file was added locally but not on the server yet*********
    if(local_token[0] == 'A'){

      //Tokenize this line of the local manifest to make it easier to identify the file path and its hash
      char* token;
      char* saveptr = local_token;
      token = strtok_r(saveptr, "~", &saveptr);


      //Write A<filepath> to .Commit
      int bytes_written = write(commit_fd, token, strlen(token));
      if(bytes_written < 0){
        printf("\nError: was unable to write to .Commit file.\n");
        close(commit_fd);
        exit(1);
      }


      //Navigate to the file's hash, which we can do manually since the layout of the manifest file is standardized
      token = strtok_r(saveptr, "~", &saveptr);
      token = strtok_r(saveptr, "~", &saveptr);
      char* inner_token;
      char* inner_saveptr = token;
      inner_token = strtok_r(inner_saveptr, ":", &inner_saveptr);
      inner_token = strtok_r(inner_saveptr, ":", &inner_saveptr);


      //Write a separator symbol and the file's hash to .Commit
      bytes_written = write(commit_fd, "^", 1);
      if(bytes_written < 0){
        printf("\nError: was unable to write to .Commit file.\n");
        close(commit_fd);
        exit(1);
      }
      bytes_written = write(commit_fd, inner_token, strlen(inner_token));
      if(bytes_written < 0){
        printf("\nError: was unable to write to .Commit file.\n");
        close(commit_fd);
        exit(1);
      }
      bytes_written = write(commit_fd, "\n", 1);
      if(bytes_written < 0){
        printf("\nError: was unable to write to .Commit file.\n");
        close(commit_fd);
        exit(1);
      }



      //If a file was removed locally but not on the server yet*********
    }else if(local_token[0] == 'D'){
      //Tokenize this line of the local manifest to make it easier to identify the file path and its hash
      char* token;
      char* saveptr = local_token;
      token = strtok_r(saveptr, "~", &saveptr);


      //Write R<filepath> to .Commit
      int bytes_written = write(commit_fd, token, strlen(token));
      if(bytes_written < 0){
        printf("\nError: was unable to write to .Commit file.\n");
        close(commit_fd);
        exit(1);
      }


      //Navigate to the file's hash, which we can do manually since the layout of the manifest file is standardized
      token = strtok_r(saveptr, "~", &saveptr);
      token = strtok_r(saveptr, "~", &saveptr);
      char* inner_token;
      char* inner_saveptr = token;
      inner_token = strtok_r(inner_saveptr, ":", &inner_saveptr);
      inner_token = strtok_r(inner_saveptr, ":", &inner_saveptr);


      //Write a separator symbol and the file's hash to .Commit
      bytes_written = write(commit_fd, "^", 1);
      if(bytes_written < 0){
        printf("\nError: was unable to write to .Commit file.\n");
        close(commit_fd);
        exit(1);
      }
      bytes_written = write(commit_fd, inner_token, strlen(inner_token));
      if(bytes_written < 0){
        printf("\nError: was unable to write to .Commit file.\n");
        close(commit_fd);
        exit(1);
      }
      bytes_written = write(commit_fd, "\n", 1);
      if(bytes_written < 0){
        printf("\nError: was unable to write to .Commit file.\n");
        close(commit_fd);
        exit(1);
      }

      //If a file has not been added or removed on local manifest (checking for modifications)*********
    }else{
      //Tokenize this line of the local manifest to make it easier to identify the file path and its hash
      char* token;
      char* saveptr = local_token;
      token = strtok_r(saveptr, "~", &saveptr);

      //Preserve server response in temporary buffer so that strtok does not mess it up
      char* temp_buff = (char*)malloc(strlen(response) + 1);
      if(temp_buff == NULL){
        printf("\nError: could not use malloc().\n");
        exit(1);
      }
      strcpy(temp_buff, response);


      //Get a pointer to this file in the server's manifest
      char* file_in_server = strstr(temp_buff, token);
      if(!file_in_server){
        printf("\nError: commit failed. Found a local file that was not recently added that could not be found on the server.\n");
        char command[strlen(commitPath) + 7];
        strcpy(command, "rm -rf ");
        strcat(command, commitPath);
        system(command);
        exit(1);
      }

      //Storing the path for the file so we can hash it later if we need to
      char* buff_for_file_path = malloc(strlen(token) + 1);
      strcpy(buff_for_file_path, token);



      //Navigate to both the server and the client's hash
      token = strtok_r(saveptr, "~", &saveptr);
      char* v_num_storage = malloc(strlen(token) + 1);
      strcpy(v_num_storage, token);
      token = strtok_r(saveptr, "~", &saveptr);
      char* l_inner_token;
      char* l_inner_saveptr = token;
      l_inner_token = strtok_r(l_inner_saveptr, ":", &l_inner_saveptr);
      l_inner_token = strtok_r(l_inner_saveptr, ":", &l_inner_saveptr);

      char* temp_token;
      char* t_saveptr = file_in_server;
      temp_token = strtok_r(t_saveptr, "\n", &t_saveptr);
      char* s_token;
      char* s_saveptr = temp_token;
      s_token = strtok_r(s_saveptr, "~", &s_saveptr);
      s_token = strtok_r(s_saveptr, "~", &s_saveptr);
      char* version_number_storage = malloc(strlen(s_token) + 1);
      strcpy(version_number_storage, s_token);
      s_token = strtok_r(s_saveptr, "~", &s_saveptr);
      char* s_inner_token;
      char* s_inner_saveptr = s_token;
      s_inner_token = strtok_r(s_inner_saveptr, ":", &s_inner_saveptr);
      s_inner_token = strtok_r(s_inner_saveptr, ":", &s_inner_saveptr);


      //If they have the same hash
      if(strcmp(l_inner_token, s_inner_token) == 0){
        char* file_contents = readFile(buff_for_file_path);
        char* file_hash= hashIt(file_contents);

        //Extract version numbers
        char* yet_another_token;
        char* yet_another_saveptr = version_number_storage;
        yet_another_token = strtok_r(yet_another_saveptr, ":", &yet_another_saveptr);
        yet_another_token = strtok_r(yet_another_saveptr, ":", &yet_another_saveptr);
        int versionNumber_s = atoi(yet_another_token);

        char* hopefullly_last_token;
        char* hopefully_last_saveptr = v_num_storage;
        hopefullly_last_token = strtok_r(hopefully_last_saveptr, ":", &hopefully_last_saveptr);
        hopefullly_last_token = strtok_r(hopefully_last_saveptr, ":", &hopefully_last_saveptr);
        int versionNumber_l = atoi(hopefullly_last_token);


        //If the file's live has is  different than the one on the local manifest
        if(strcmp(file_hash, l_inner_token) != 0){
          //Increment version number of local copy
          versionNumber_l++;
          char numStorage[5];
          sprintf(numStorage, "%d", versionNumber_l);

          //Add to the .Commit
          int bytes_written = write(commit_fd, "M", 1);
          if(bytes_written < 0){
            printf("\nError: was unable to write to .Commit file.\n");
            close(commit_fd);
            exit(1);
          }
          bytes_written = write(commit_fd, buff_for_file_path, strlen(buff_for_file_path));
          if(bytes_written < 0){
            printf("\nError: was unable to write to .Commit file.\n");
            close(commit_fd);
            exit(1);
          }
          bytes_written = write(commit_fd, "^", 1);
          if(bytes_written < 0){
            printf("\nError: was unable to write to .Commit file.\n");
            close(commit_fd);
            exit(1);
          }
          bytes_written = write(commit_fd, numStorage, strlen(numStorage));
          if(bytes_written < 0){
            printf("\nError: was unable to write to .Commit file.\n");
            close(commit_fd);
            exit(1);
          }
          bytes_written = write(commit_fd, "^", 1);
          if(bytes_written < 0){
            printf("\nError: was unable to write to .Commit file.\n");
            close(commit_fd);
            exit(1);
          }
          bytes_written = write(commit_fd, file_hash, strlen(file_hash));
          if(bytes_written < 0){
            printf("\nError: was unable to write to .Commit file.\n");
            close(commit_fd);
            exit(1);
          }
          bytes_written = write(commit_fd, "\n", 1);
          if(bytes_written < 0){
            printf("\nError: was unable to write to .Commit file.\n");
            close(commit_fd);
            exit(1);
          }

          //different hashes, compare the version numbers to see if client must sync its repository
        }else{
          if(versionNumber_s > versionNumber_l){
            printf("\nError: please synch this project to the server's project before committing changes.");
            char command[strlen(commitPath) + 7];
            strcpy(command, "rm -rf ");
            strcat(command, commitPath);
            system(command);
            exit(1);
          }
        }

        free(file_contents);
        free(file_hash);
      }

      free(version_number_storage);
      free(temp_buff);
      free(buff_for_file_path);
    }

  }
  close(commit_fd);
  struct stat commit;
  stat(commitPath, &commit);
  int size = commit.st_size;
  if(size == 0){
    char command[strlen(commitPath) + 7];
    strcpy(command, "rm -rf ");
    strcat(command, commitPath);
    system(command);
  }else{
    char* commit_contents = readFile(commitPath);
    char sendBuff[strlen(commit_contents) + strlen(project_name) + 3];
    memset(sendBuff, 0, strlen(commit_contents) + strlen(project_name) + 3);
    strcpy(sendBuff, "z ");
    strcat(sendBuff, project_name);
    strcat(sendBuff, " ");
    strcat(sendBuff, commit_contents);
    char* server_response_2 = connect_to_WTFserver(sendBuff);
    printf("\n%s", server_response_2);
    free(commit_contents);
    free(server_response_2);
  }

  printf("\n");

  free(response);
  free(local_manifest);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x268, %rsp            # imm = 0x268
movq %rdi, %r15
callq 0x11d0
testq %rax, %rax
je 0x3585
movq %rax, %rdi
callq 0x1210
movq %r15, %rdi
callq 0x10a0
movq %rsp, %rcx
addq $0x19, %rax
andq $-0x10, %rax
movq %rcx, %rbx
subq %rax, %rbx
movq %rbx, %rsp
negq %rax
xorl %r14d, %r14d
movb %r14b, 0x2(%rbx)
movw $0x2f2e, (%rcx,%rax)    # imm = 0x2F2E
movq %rbx, %rdi
movq %r15, %rsi
callq 0x1230
movq %rbx, %rdi
callq 0x10a0
movabsq $0x6574616470552e2f, %rcx # imm = 0x6574616470552E2F
movq %rcx, (%rax,%rbx)
movb %r14b, 0x8(%rax,%rbx)
leaq -0x200(%rbp), %rsi
movq %rbx, %rdi
callq 0x1140
testl %eax, %eax
jne 0x2c2b
cmpq $0x0, -0x1d0(%rbp)
jg 0x358e
movq %r15, %rdi
callq 0x10a0
movq %rsp, %rcx
addq $0x1b, %rax
andq $-0x10, %rax
movq %rcx, %rbx
subq %rax, %rbx
movq %rbx, %rsp
negq %rax
movw $0x2f2e, (%rcx,%rax)    # imm = 0x2F2E
movb $0x0, 0x2(%rbx)
movq %rbx, %rdi
movq %r15, %rsi
callq 0x1230
movq %rbx, %rdi
callq 0x10a0
movabsq $0x696c666e6f432e2f, %rcx # imm = 0x696C666E6F432E2F
movq %rcx, (%rax,%rbx)
movl $0x746369, 0x7(%rax,%rbx) # imm = 0x746369
leaq -0x290(%rbp), %rsi
movq %rbx, %rdi
callq 0x1140
testl %eax, %eax
je 0x3597
movq %r15, %rdi
callq 0x10a0
movq %rax, %rbx
leaq 0x3(%rax), %rdx
movq %r15, -0x88(%rbp)
movq %rsp, %r15
leaq 0x12(%rax), %r12
andq $-0x10, %r12
movq %r15, %r14
subq %r12, %r14
movq %r14, %rsp
negq %r12
movq %r14, %rdi
xorl %esi, %esi
callq 0x10c0
movw $0x206f, (%r15,%r12)    # imm = 0x206F
movq -0x88(%rbp), %r15
testq %rbx, %rbx
je 0x2cfd
movl $0x2, %eax
xorl %ecx, %ecx
movb (%r15,%rcx), %dl
testb %dl, %dl
je 0x2cf5
cltq
movb %dl, (%r14,%rax)
incl %eax
incq %rcx
cmpq %rcx, %rbx
jne 0x2ce5
movq %r14, %rdi
callq 0x41ca
movq %rax, %r12
movzbl (%rax), %eax
cmpl $0x78, %eax
je 0x2d29
cmpl $0x65, %eax
jne 0x2d35
cmpb $0x0, 0x1(%r12)
jne 0x2d35
leaq 0x2f06(%rip), %rdi      # 0x5c2a
jmp 0x3562
cmpb $0x0, 0x1(%r12)
je 0x35ce
leaq -0xe0(%rbp), %rbx
movq %rbx, %rdi
movq %r15, %rsi
callq 0x1150
movq %rbx, %rdi
callq 0x10a0
movabsq $0x6566696e614d2e2f, %rcx # imm = 0x6566696E614D2E2F
movq %rcx, -0xe0(%rbp,%rax)
movl $0x747365, -0xd9(%rbp,%rax) # imm = 0x747365
movq %rbx, %rdi
callq 0x4387
leaq -0x78(%rbp), %rdx
movq %rax, (%rdx)
leaq 0x293c(%rip), %rsi      # 0x56be
movq %rax, -0x68(%rbp)
movq %rax, %rdi
callq 0x1240
movq %rax, %rbx
movq %rax, %rdi
callq 0x10a0
testq %rax, %rax
je 0x2db5
xorl %ecx, %ecx
movb (%rbx,%rcx), %dl
cmpb (%r12,%rcx), %dl
jne 0x34d9
incq %rcx
cmpq %rcx, %rax
jne 0x2da0
leaq -0x60(%rbp), %rbx
movq %rbx, %rdi
movq %r15, %rsi
callq 0x1150
movq %rbx, %rdi
callq 0x10a0
movabsq $0x74696d6d6f432e2f, %rcx # imm = 0x74696D6D6F432E2F
movq %rcx, -0x60(%rbp,%rax)
movb $0x0, -0x58(%rbp,%rax)
movq %rbx, %rdi
movl $0x241, %esi            # imm = 0x241
movl $0x1ff, %edx            # imm = 0x1FF
xorl %eax, %eax
callq 0x10f0
movl %eax, %r14d
testl %eax, %eax
js 0x35a0
movq %r15, %rdi
callq 0x10a0
movl %r14d, %edi
movq %r15, %rsi
movq %rax, %rdx
callq 0x1080
testl %eax, %eax
js 0x34c0
leaq 0x289a(%rip), %rsi      # 0x56be
movl $0x1, %edx
movl %r14d, %edi
callq 0x1080
testl %eax, %eax
js 0x34c0
leaq -0x78(%rbp), %rdx
movq (%rdx), %rdi
leaq 0x2877(%rip), %rsi      # 0x56be
callq 0x1240
testq %rax, %rax
movq %r12, -0x90(%rbp)
je 0x333c
leaq 0x27e1(%rip), %r15      # 0x5644
leaq -0x170(%rbp), %rbx
movl %r14d, -0x34(%rbp)
movzbl (%rax), %ecx
cmpl $0x44, %ecx
je 0x2e7f
cmpl $0x41, %ecx
jne 0x2f6a
movq %rax, -0x170(%rbp)
movq %rax, %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x1240
movq %rax, %r13
movq %rax, %rdi
callq 0x10a0
movl %r14d, %edi
movq %r13, %rsi
movq %rax, %rdx
callq 0x1080
testl %eax, %eax
js 0x34c0
movq -0x170(%rbp), %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x1240
movq -0x170(%rbp), %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x1240
movq %rax, -0x30(%rbp)
movq %rax, %rdi
leaq 0x27e4(%rip), %rbx      # 0x56cb
movq %rbx, %rsi
leaq -0x30(%rbp), %r13
movq %r13, %rdx
callq 0x1240
movq -0x30(%rbp), %rdi
movq %rbx, %rsi
movq %r13, %rdx
callq 0x1240
movq %rax, %rbx
movl $0x1, %edx
movl %r14d, %edi
leaq 0x272f(%rip), %rsi      # 0x5646
callq 0x1080
testl %eax, %eax
js 0x34c0
movq %rbx, %rdi
callq 0x10a0
movl %r14d, %edi
movq %rbx, %rsi
movq %rax, %rdx
callq 0x1080
testl %eax, %eax
js 0x34c0
movl $0x1, %edx
movl %r14d, %edi
leaq 0x276d(%rip), %rsi      # 0x56be
callq 0x1080
testl %eax, %eax
leaq -0x170(%rbp), %rbx
jns 0x331f
jmp 0x34c0
movq %rax, -0x170(%rbp)
movq %rax, %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x1240
movq %rax, %r15
movq %r12, %rdi
callq 0x10a0
leaq 0x1(%rax), %rdi
callq 0x1190
testq %rax, %rax
je 0x355b
movq %rax, %rbx
movq %rax, %rdi
movq %r12, %rsi
callq 0x1150
movq %rbx, -0xb8(%rbp)
movq %rbx, %rdi
movq %r15, %rsi
callq 0x1060
testq %rax, %rax
je 0x3509
movq %rax, %rbx
movq %r15, %rdi
callq 0x10a0
leaq 0x1(%rax), %rdi
callq 0x1190
movq %rax, -0x40(%rbp)
movq %rax, %rdi
movq %r15, %rsi
callq 0x1150
movq -0x170(%rbp), %rdi
leaq 0x264e(%rip), %r13      # 0x5644
movq %r13, %rsi
leaq -0x170(%rbp), %r12
movq %r12, %rdx
callq 0x1240
movq %rax, %r15
movq %rax, %rdi
callq 0x10a0
leaq 0x1(%rax), %rdi
callq 0x1190
movq %rax, -0x48(%rbp)
movq %rax, %rdi
movq %r15, %rsi
callq 0x1150
movq -0x170(%rbp), %rdi
movq %r13, %rsi
movq %r12, %rdx
callq 0x1240
movq %rax, -0x30(%rbp)
movq %rax, %rdi
leaq 0x2680(%rip), %r15      # 0x56cb
movq %r15, %rsi
leaq -0x30(%rbp), %r12
movq %r12, %rdx
callq 0x1240
movq -0x30(%rbp), %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x1240
movq %rax, %r14
movq %rbx, -0xc0(%rbp)
movq %rbx, %rdi
leaq 0x2641(%rip), %rsi      # 0x56be
leaq -0xc0(%rbp), %rdx
callq 0x1240
movq %rax, -0x70(%rbp)
movq %rax, %rdi
movq %r13, %rsi
leaq -0x70(%rbp), %rbx
movq %rbx, %rdx
callq 0x1240
movq -0x70(%rbp), %rdi
movq %r13, %rsi
movq %rbx, %rdx
callq 0x1240
movq %rax, %r12
movq %rax, %rdi
callq 0x10a0
leaq 0x1(%rax), %rdi
callq 0x1190
movq %rax, -0x50(%rbp)
movq %rax, %rdi
movq %r12, %rsi
callq 0x1150
movq -0x70(%rbp), %rdi
movq %r13, %rsi
movq %rbx, %rdx
callq 0x1240
movq %rax, -0xa8(%rbp)
movq %rax, %rdi
movq %r15, %rsi
leaq -0xa8(%rbp), %rbx
movq %rbx, %rdx
callq 0x1240
movq -0xa8(%rbp), %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x1240
movq %r14, %r12
movq %r14, %rdi
movq %rax, %rsi
callq 0x11b0
testl %eax, %eax
jne 0x32e8
movq -0x40(%rbp), %rdi
callq 0x4387
movq %rax, -0xb0(%rbp)
movq %rax, %rdi
callq 0x4435
movq %rax, %r14
movq -0x50(%rbp), %rdi
movq %rdi, -0xa0(%rbp)
leaq 0x257a(%rip), %r15      # 0x56cb
movq %r15, %rsi
leaq -0xa0(%rbp), %rbx
movq %rbx, %rdx
callq 0x1240
movq -0xa0(%rbp), %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x1240
movq %rax, %rdi
callq 0x1200
movl %eax, -0x7c(%rbp)
movq -0x48(%rbp), %rdi
movq %rdi, -0x98(%rbp)
movq %r15, %rsi
leaq -0x98(%rbp), %rbx
movq %rbx, %rdx
callq 0x1240
movq -0x98(%rbp), %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x1240
movq %rax, %rdi
callq 0x1200
movl %eax, %r13d
movq %r14, -0x48(%rbp)
movq %r14, %rdi
movq %r12, %rsi
callq 0x11b0
testl %eax, %eax
je 0x32c6
incl %r13d
leaq -0xc5(%rbp), %rbx
movq %rbx, %rdi
leaq 0x24c4(%rip), %rsi      # 0x56a9
movl %r13d, %edx
xorl %eax, %eax
callq 0x1050
movl $0x1, %edx
movl -0x34(%rbp), %r15d
movl %r15d, %edi
leaq 0x2446(%rip), %rsi      # 0x5648
callq 0x1080
testl %eax, %eax
js 0x34f8
movq -0x40(%rbp), %r14
movq %r14, %rdi
callq 0x10a0
movl %r15d, %edi
movq %r14, %rsi
movq %rax, %rdx
callq 0x1080
testl %eax, %eax
movq -0x48(%rbp), %r13
js 0x34f8
movl $0x1, %edx
movl %r15d, %edi
leaq 0x2402(%rip), %rsi      # 0x5646
callq 0x1080
testl %eax, %eax
js 0x34f8
movq %rbx, %rdi
callq 0x10a0
movl %r15d, %edi
movq %rbx, %rsi
movq %rax, %rdx
callq 0x1080
testl %eax, %eax
js 0x34f8
movl $0x1, %edx
movl %r15d, %edi
leaq 0x23c8(%rip), %rsi      # 0x5646
callq 0x1080
testl %eax, %eax
js 0x34f8
movq %r13, %rdi
callq 0x10a0
movl %r15d, %edi
movq %r13, %rsi
movq %rax, %rdx
callq 0x1080
testl %eax, %eax
js 0x34f8
movl $0x1, %edx
movl %r15d, %edi
leaq 0x2406(%rip), %rsi      # 0x56be
callq 0x1080
testl %eax, %eax
jns 0x32d4
jmp 0x3571
cmpl %r13d, -0x7c(%rbp)
movq -0x48(%rbp), %r13
jg 0x35bb
movq -0xb0(%rbp), %rdi
callq 0x1170
movq %r13, %rdi
callq 0x1170
movq -0x50(%rbp), %rdi
callq 0x1170
movq -0xb8(%rbp), %rdi
callq 0x1170
movq -0x40(%rbp), %rdi
callq 0x1170
movq -0x90(%rbp), %r12
movl -0x34(%rbp), %r14d
leaq 0x232c(%rip), %r15      # 0x5644
leaq -0x170(%rbp), %rbx
movq -0x78(%rbp), %rdi
leaq 0x2394(%rip), %rsi      # 0x56be
leaq -0x78(%rbp), %rdx
callq 0x1240
testq %rax, %rax
jne 0x2e6e
movl %r14d, %edi
callq 0x1250
leaq -0x60(%rbp), %rdi
leaq -0x170(%rbp), %rbx
movq %rbx, %rsi
callq 0x1140
cmpl $0x0, 0x30(%rbx)
je 0x344c
leaq -0x60(%rbp), %rdi
callq 0x4387
movq %rax, -0x40(%rbp)
movq %rax, %rdi
callq 0x10a0
movq %rax, %r14
movq -0x88(%rbp), %rbx
movq %rbx, %rdi
callq 0x10a0
movq %rsp, -0x50(%rbp)
leaq (%r14,%rax), %r13
addq $0x12, %r13
andq $-0x10, %r13
movq %rsp, %r12
movq %r12, %r14
subq %r13, %r14
movq %r14, %rsp
movq -0x40(%rbp), %rdi
callq 0x10a0
movq %rax, %r15
movq %rbx, %rdi
callq 0x10a0
leaq (%r15,%rax), %rcx
addq $0x3, %rcx
addq %rax, %r15
cmpq $0x4, %rcx
movl $0x0, %edx
cmovaeq %r15, %rdx
movq -0x50(%rbp), %r15
leaq 0x3(%r14), %rdi
xorl %esi, %esi
callq 0x10c0
negq %r13
movb $0x0, 0x2(%r12,%r13)
movq -0x90(%rbp), %r12
movw $0x207a, (%r14)         # imm = 0x207A
movq %r14, %rdi
movq %rbx, %rsi
callq 0x1230
movq %r14, %rdi
callq 0x10a0
movw $0x20, (%rax,%r14)
movq %r14, %rdi
movq -0x40(%rbp), %rbx
movq %rbx, %rsi
callq 0x1230
movq %r14, %rdi
callq 0x41ca
movq %rax, %r14
leaq 0x2272(%rip), %rdi      # 0x56a2
movq %rax, %rsi
xorl %eax, %eax
callq 0x1040
movq %rbx, %rdi
callq 0x1170
movq %r14, %rdi
callq 0x1170
jmp 0x3493
leaq -0x60(%rbp), %rbx
movq %rbx, %rdi
callq 0x10a0
movq %rsp, %r15
movq %rsp, %rcx
addq $0x16, %rax
andq $-0x10, %rax
movq %rcx, %r14
subq %rax, %r14
movq %r14, %rsp
negq %rax
movabsq $0x2066722d206d72, %rdx # imm = 0x2066722D206D72
movq %rdx, (%rcx,%rax)
movq %r14, %rdi
movq %rbx, %rsi
callq 0x1230
movq %r14, %rdi
callq 0x1130
movq %r15, %rsp
movl $0xa, %edi
callq 0x11a0
movq %r12, %rdi
callq 0x1170
movq -0x68(%rbp), %rdi
callq 0x1170
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x268b(%rip), %rdi      # 0x5b52
callq 0x11e0
movl %r14d, %edi
callq 0x1250
jmp 0x3567
leaq 0x269f(%rip), %rdi      # 0x5b7f
callq 0x11e0
movq %r12, %rdi
callq 0x1170
movq -0x68(%rbp), %rdi
callq 0x1170
jmp 0x3567
leaq 0x2653(%rip), %rdi      # 0x5b52
callq 0x11e0
movl %r15d, %edi
jmp 0x34cf
leaq 0x25b5(%rip), %rdi      # 0x5ac5
callq 0x11e0
leaq -0x60(%rbp), %rbx
movq %rbx, %rdi
callq 0x10a0
movq %rsp, %rcx
addq $0x16, %rax
andq $-0x10, %rax
movq %rcx, %r14
subq %rax, %r14
movq %r14, %rsp
negq %rax
movabsq $0x2066722d206d72, %rdx # imm = 0x2066722D206D72
movq %rdx, (%rcx,%rax)
movq %r14, %rdi
movq %rbx, %rsi
callq 0x1230
movq %r14, %rdi
callq 0x1130
jmp 0x3567
leaq 0x25d0(%rip), %rdi      # 0x5b32
callq 0x11e0
movl $0x1, %edi
callq 0x1180
leaq 0x25da(%rip), %rdi      # 0x5b52
callq 0x11e0
movl -0x34(%rbp), %edi
jmp 0x34cf
leaq 0x24f9(%rip), %rdi      # 0x5a85
jmp 0x3562
leaq 0x271e(%rip), %rdi      # 0x5cb3
jmp 0x3562
leaq 0x26d5(%rip), %rdi      # 0x5c73
jmp 0x3562
leaq 0x206d(%rip), %rdi      # 0x5614
xorl %eax, %eax
callq 0x1040
movl %r14d, %edi
callq 0x1250
jmp 0x34e5
leaq 0x2088(%rip), %rdi      # 0x564a
xorl %eax, %eax
callq 0x1040
jmp 0x3515
leaq 0x261d(%rip), %rdi      # 0x5bf2
jmp 0x3562