// File: /workspace/github_cpp_makefile_star2_O1/jaudoux[P]countTags/src/countTags.cpp
// Function: main
int main (int argc, char *argv[]) {

  // Config vars
  const char * tags_file;
  const char * seq_file;
  uint32_t tag_length = 22;
  bool stranded = false;
  bool normalize = false;
  bool print_tag_names = false;
  uint32_t nb_tags = 0;
  uint32_t max_reads = UINT32_MAX;
  int nb_threads = 1;
  uint32_t nb_samples;
  uint32_t i;
  uint32_t read_id;

  char * seq;
  std::string tag_name;
  uint32_t seq_length;
  uint64_t tag;
  uint64_t valrev,valfwd;
  uint64_t nb_factors;
  int64_t last;
  std::unordered_map<uint64_t,double*>  tags_counts;
  std::unordered_map<uint64_t,std::vector<std::string>> tags_names;
  std::unordered_map<uint64_t,double*>::iterator it_counts;
  std::vector<uint64_t> nb_factors_by_sample;

  // File vars
  std::string gzip_pipe = "gunzip -fc ";
  std::string cat_pipe = "cat ";
  std::string tmp;
  FILE * file;
  char * line = NULL;
  size_t len = 0;
  ssize_t read;
  uint32_t line_id = 0;

  /**********************************
   *
   *        Parsing options
   *
   *********************************/
  argc-=(argc>0); argv+=(argc>0); // skip program name argv[0] if present
  option::Stats  stats(usage, argc, argv);
  option::Option options[stats.options_max], buffer[stats.buffer_max];
  option::Parser parse(usage, argc, argv, options, buffer);

  if (parse.error())
    return 1;

  if (options[HELP] || argc == 0) {
    option::printUsage(std::cout, usage);
    return 0;
  }

  // TODO we should check the length to choose the appropriate
  // integer size to use
  if (options[PROBE_LENGTH]) {
    tag_length = atoi(options[PROBE_LENGTH].arg);
  }

  if (options[MAX_READS]) {
    max_reads = atoi(options[MAX_READS].arg);
  }

  //if (options[NB_THREADS]) {
  //  nb_threads = atoi(options[NB_THREADS].arg);
  //}

  if (options[STRANDED]) {
    stranded = true;
  }

  if (options[NORMALIZE]) {
    normalize = true;
  }

  if (options[TAG_NAMES]) {
    print_tag_names = true;
  }

  if(parse.nonOptionsCount() < 2) {
    option::printUsage(std::cout, usage);
    return 0;
  }

  tags_file = parse.nonOption(0);
  nb_samples = parse.nonOptionsCount() - 1;

  /**********************************
   *
   *   Create tags counting table
   *
   *********************************/
  file = popen(tmp.append(cat_pipe).append(tags_file).c_str(),"r");
  line_id = 0;

  std::cerr << "Counting k-mers" << std::endl;
  // Create hash table of k-mer counts
  line_id = 0;
  nb_tags = 0;
  while ((read = getline(&line, &len, file)) != -1) {
    if(line_id % 2 == 0) {
      tag_name = line;
      tag_name.pop_back(); // remove new_line char
      tag_name.erase(0,1); // remove the fasta ">" prefix
    }
    if(line_id % 2 == 1) {
      tag = DNAtoInt(line,tag_length,stranded);
      tags_counts[tag] = new double[nb_samples]();
      tags_names[tag].push_back(tag_name);
      nb_tags++;
    }
    line_id++;
  }
  fclose(file);
  if (line)
    free(line);

  std::cerr << "Finished indexing tags" << std::endl;


  /**********************************
   *
   *            First pass
   *
   *********************************/
//#pragma omp parallel num_threads(nb_threads)
  for (int s = 0; s < nb_samples; ++s) {
    std::cerr << "Counting tags for file: " << parse.nonOption(s+1) << "\n";

    line = NULL;
    len = 0;
    line_id = 0;
    tmp = "";
    file = popen(tmp.append(gzip_pipe).append(parse.nonOption(s+1)).c_str(),"r");
    nb_factors = 0;

    while ((read = getline(&line, &len, file)) != -1) {
      // If this line is a sequence
      if(line_id % 4 == 1) {
        read_id = ((int)((double)line_id*0.25) + 1);
        if(read_id >= max_reads) {
          break;
        }
        // Print a user-friendly output on STDERR every each XXXX reads processed
        if(read_id % MILLION == 0) {
          std::cerr << (int)((double)line_id*0.25) + 1 << " reads parsed" << std::endl;
        }
        // set seq to line
        seq = line;
        seq_length = strlen(seq) - 1; // Minus 1 because we have a new line

        // Skip the sequence if the read length is < to the tag_length
        if(seq_length < tag_length)
          continue;

        nb_tags = seq_length - tag_length + 1;
        nb_factors += nb_tags;

        //uint64_t valrev,valfwd;
        last = -3;

        for(i = 0; i < nb_tags; i++) {
          it_counts = tags_counts.find(valns(i,seq,tag_length,&last,&valfwd,&valrev,stranded));
          if(it_counts != tags_counts.end()) {
            it_counts->second[s]++;
          }
        }
      }
      line_id++;
    }

    nb_factors_by_sample.push_back(nb_factors);

    if(normalize && nb_factors > 0) {
      std::cerr << "Normalize counts" << std::endl;
      for (it_counts=tags_counts.begin(); it_counts!=tags_counts.end(); ++it_counts) {
        // TODO We should take into accout the error rate...
        if(it_counts->second[s] > 0)
          it_counts->second[s] = it_counts->second[s] * MILLION / nb_factors;
      }
    }

    // Close file and clear line buffer
    fclose(file);
    if (line)
      free(line);
  }

  /****
   * PRINT THE RESULTS
   */
  // First print headers
  std::cout << "tag";
  if (print_tag_names)
    std::cout << "\ttag_names";
  for (int s = 0; s < nb_samples; ++s) {
    std::cout << "\t" << parse.nonOption(s+1);
  }
  std::cout << "\n";
  char *tag_seq = new char[tag_length];
  for (it_counts=tags_counts.begin(); it_counts!=tags_counts.end(); ++it_counts) {
    intToDNA(it_counts->first,tag_length,tag_seq);
    std::cout << tag_seq;
    if(print_tag_names) {
      std::cout << "\t" << join(tags_names[it_counts->first],",");
    }
    for (int s = 0; s < nb_samples; ++s) {
      std::cout << "\t" << it_counts->second[s];
    }
    std::cout << std::endl;
  }

  std::cout << "total_factors";
  if (print_tag_names)
    std::cout << "\t*";
  for (int s = 0; s < nb_samples; ++s) {
    std::cout << "\t" << nb_factors_by_sample[s];
  }
  std::cout << std::endl;

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x208, %rsp            # imm = 0x208
movq %rsi, %r14
movl %edi, %ebx
leaq -0x88(%rbp), %r15
movq %r15, -0x10(%r15)
xorl %eax, %eax
movq %rax, -0x8(%r15)
movb $0x0, (%r15)
leaq -0x1c0(%rbp), %rcx
movq %rcx, -0x30(%rcx)
movl $0x1, %edx
movq %rdx, -0x28(%rcx)
xorpd %xmm0, %xmm0
movupd %xmm0, -0x20(%rcx)
movl $0x3f800000, %esi       # imm = 0x3F800000
movl %esi, -0x10(%rcx)
movupd %xmm0, -0x8(%rcx)
leaq -0x1f8(%rbp), %rcx
movq %rcx, -0x30(%rcx)
movq %rdx, -0x28(%rcx)
movupd %xmm0, -0x20(%rcx)
movl %esi, -0x10(%rcx)
movupd %xmm0, -0x8(%rcx)
movq %rax, -0xc0(%rbp)
movapd %xmm0, -0xd0(%rbp)
leaq -0x158(%rbp), %rax
movq %rax, -0x10(%rax)
leaq 0x4962(%rip), %rsi      # 0x7070
leaq 0x4966(%rip), %rdx      # 0x707b
leaq -0x168(%rbp), %rdi
callq 0x4172
leaq -0x138(%rbp), %rax
movq %rax, -0x10(%rax)
leaq 0x4949(%rip), %rsi      # 0x707c
leaq 0x4946(%rip), %rdx      # 0x7080
leaq -0x148(%rbp), %rdi
callq 0x4172
leaq -0xe8(%rbp), %rcx
movq %rcx, -0x10(%rcx)
xorl %eax, %eax
movq %rax, -0x8(%rcx)
movb $0x0, (%rcx)
movq %rax, -0x48(%rbp)
movq %rax, -0xa8(%rbp)
xorl %eax, %eax
testl %ebx, %ebx
setg %al
subl %eax, %ebx
xorl %eax, %eax
testl %ebx, %ebx
setg %al
leaq (%r14,%rax,8), %r15
leaq 0x7420(%rip), %rsi      # 0x9ba0
leaq -0x108(%rbp), %rdi
movl %ebx, %edx
movq %r15, %rcx
xorl %r8d, %r8d
xorl %r9d, %r9d
callq 0x369a
movq %rsp, -0x188(%rbp)
movl -0x104(%rbp), %ecx
movq %rsp, %r14
movq %rcx, %rax
shlq $0x4, %rax
leaq (%rax,%rax,2), %rax
subq %rax, %r14
movq %r14, %rsp
testq %rcx, %rcx
je 0x27ed
leaq 0x10(%r14), %rcx
leaq 0x1(%r14), %rdx
xorl %esi, %esi
xorpd %xmm0, %xmm0
leaq (%rdx,%rsi), %rdi
movupd %xmm0, 0xc(%rcx,%rsi)
movapd %xmm0, (%rcx,%rsi)
movq %rdi, -0x8(%rcx,%rsi)
movq %rdi, -0x10(%rcx,%rsi)
addq $0x30, %rsi
cmpq %rsi, %rax
jne 0x27cb
movl -0x108(%rbp), %ecx
movq %rsp, %r9
movq %rcx, %rax
shlq $0x4, %rax
leaq (%rax,%rax,2), %rax
subq %rax, %r9
movq %r9, %rsp
testq %rcx, %rcx
je 0x283c
leaq 0x10(%r9), %rcx
leaq 0x1(%r9), %rdx
xorl %esi, %esi
xorpd %xmm0, %xmm0
leaq (%rdx,%rsi), %rdi
movupd %xmm0, 0xc(%rcx,%rsi)
movapd %xmm0, (%rcx,%rsi)
movq %rdi, -0x8(%rcx,%rsi)
movq %rdi, -0x10(%rcx,%rsi)
addq $0x30, %rsi
cmpq %rsi, %rax
jne 0x281a
subq $0x8, %rsp
xorl %eax, %eax
leaq 0x7357(%rip), %rsi      # 0x9ba0
leaq -0x180(%rbp), %rdi
movl %ebx, %edx
movq %r15, %rcx
movq %r14, %r8
pushq $-0x1
pushq %rax
pushq %rax
callq 0x3706
addq $0x20, %rsp
movl $0x1, %r15d
cmpb $0x0, -0x170(%rbp)
jne 0x34ae
testl %ebx, %ebx
je 0x289b
cmpq $0x0, 0x40(%r14)
jne 0x289b
cmpq $0x0, 0x70(%r14)
je 0x28d5
movq 0x80(%r14), %rdi
callq 0x22a0
movl %eax, %r12d
jmp 0x28db
leaq 0x74ce(%rip), %rax      # 0x9d70
leaq -0x128(%rbp), %rdi
movq %rax, (%rdi)
movq 0x7715(%rip), %rax      # 0x9fc8
movq %rax, 0x8(%rdi)
leaq 0x72e2(%rip), %rsi      # 0x9ba0
movl $0x50, %edx
movl $0x32, %ecx
movl $0x4b, %r8d
callq 0x4248
jmp 0x2940
movl $0x16, %r12d
cmpq $0x0, 0xd0(%r14)
je 0x28f6
movq 0xe0(%r14), %rdi
callq 0x22a0
movl %eax, -0x64(%rbp)
jmp 0x28fd
movl $0xffffffff, -0x64(%rbp) # imm = 0xFFFFFFFF
movl -0x17c(%rbp), %eax
cmpl $0x1, %eax
jg 0x2948
leaq 0x7461(%rip), %rax      # 0x9d70
leaq -0x128(%rbp), %rdi
movq %rax, (%rdi)
movq 0x76a8(%rip), %rax      # 0x9fc8
movq %rax, 0x8(%rdi)
leaq 0x7275(%rip), %rsi      # 0x9ba0
movl $0x50, %edx
movl $0x32, %ecx
movl $0x4b, %r8d
callq 0x4248
xorl %r15d, %r15d
jmp 0x34ae
movl %eax, %r15d
movq 0xa0(%r14), %rax
movq %rax, -0xd8(%rbp)
movq 0x130(%r14), %rax
movq %rax, -0x190(%rbp)
movq 0x160(%r14), %rax
movq %rax, -0xa0(%rbp)
movq -0x178(%rbp), %rax
movq (%rax), %rbx
movq -0x148(%rbp), %rsi
movq -0x140(%rbp), %rdx
leaq -0xf8(%rbp), %rdi
callq 0x2080
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2330
movq (%rax), %rdi
leaq 0x46d3(%rip), %rsi      # 0x7081
callq 0x2070
movq %rax, -0x30(%rbp)
movq 0x7632(%rip), %rbx      # 0x9ff0
leaq 0x46be(%rip), %rsi      # 0x7083
movl $0xf, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x2160
movsbl %al, %esi
movq 0x7600(%rip), %rdi      # 0x9ff0
callq 0x2040
movq %rax, %rdi
callq 0x2110
decl %r15d
movl %r12d, %eax
movq %rax, -0x58(%rbp)
leal (%r12,%r12), %ecx
movq $-0x1, %rax
movq $-0x1, %rdx
movl %ecx, -0x50(%rbp)
shlq %cl, %rdx
movq %r12, -0x40(%rbp)
cmpl $0x20, %r12d
notq %rdx
cmoveq %rax, %rdx
movq %rdx, -0x70(%rbp)
movl %r15d, -0x34(%rbp)
movl %r15d, %eax
movq %rax, -0x78(%rbp)
leaq (,%rax,8), %r12
xorl %r13d, %r13d
leaq -0x98(%rbp), %r14
leaq -0x48(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
movq -0x30(%rbp), %rdx
callq 0x2200
cmpq $-0x1, %rax
je 0x2bd5
movq -0x48(%rbp), %r15
testb $0x1, %r13b
jne 0x2ab5
movq -0x90(%rbp), %rbx
movq %r15, %rdi
callq 0x20c0
movq %r14, %rdi
xorl %esi, %esi
movq %rbx, %rdx
movq %r15, %rcx
movq %rax, %r8
callq 0x2290
movq %r14, %rdi
callq 0x21f0
movl $0x1, %edx
movq %r14, %rdi
xorl %esi, %esi
callq 0x2050
jmp 0x2bcd
cmpl $0x0, -0x40(%rbp)
je 0x2b2a
xorl %ecx, %ecx
xorl %eax, %eax
movzbl (%r15,%rcx), %edx
addl $-0x43, %edx
cmpl $0x31, %edx
ja 0x2b26
movabsq $0x100000001, %rsi      # imm = 0x100000001
btq %rdx, %rsi
jb 0x2b0f
movabsq $0x1000000010, %rsi     # imm = 0x1000000010
btq %rdx, %rsi
jb 0x2b08
movabsq $0x2000000020000, %rsi  # imm = 0x2000000020000
btq %rdx, %rsi
movl $0x0, %edx
jae 0x2b14
movl $0x3, %edx
jmp 0x2b14
movl $0x2, %edx
jmp 0x2b14
movl $0x1, %edx
shlq $0x2, %rax
orq %rdx, %rax
incq %rcx
cmpq %rcx, -0x58(%rbp)
jne 0x2abf
jmp 0x2b2c
xorl %edx, %edx
jmp 0x2b14
xorl %eax, %eax
cmpq $0x0, -0xd8(%rbp)
jne 0x2b77
movq -0x40(%rbp), %rcx
testl %ecx, %ecx
je 0x2b70
movq %rax, %rsi
xorq -0x70(%rbp), %rsi
movl $0x3, %edi
movl %ecx, %r8d
xorl %edx, %edx
xorl %ecx, %ecx
shlq $0x2, %rdx
movq %rdi, %r9
andq %rsi, %r9
shrq %cl, %r9
orq %r9, %rdx
shlq $0x2, %rdi
addq $0x2, %rcx
decl %r8d
jne 0x2b51
jmp 0x2b72
xorl %edx, %edx
cmpq %rax, %rdx
jb 0x2b7a
movq %rax, %rdx
movq %rdx, -0x100(%rbp)
movq %r12, %rdi
callq 0x2030
movq %rax, %rbx
movq %rax, %rdi
xorl %esi, %esi
movq %r12, %rdx
callq 0x20f0
leaq -0x1f0(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0x4e72
movq %rbx, (%rax)
leaq -0x228(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0x5156
movq %rax, %rdi
movq %r14, %rsi
callq 0x37aa
incl %r13d
jmp 0x2a4f
movq -0x30(%rbp), %rdi
callq 0x2170
movq -0x48(%rbp), %rdi
testq %rdi, %rdi
je 0x2bec
callq 0x21e0
movq 0x73fd(%rip), %rbx      # 0x9ff0
leaq 0x4499(%rip), %rsi      # 0x7093
movl $0x16, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x2160
movsbl %al, %esi
movq 0x73cb(%rip), %rdi      # 0x9ff0
callq 0x2040
movq %rax, %rdi
callq 0x2110
cmpl $0x0, -0x34(%rbp)
je 0x31f8
movq $-0x1, %rdx
movl -0x50(%rbp), %ecx
shlq %cl, %rdx
movq $-0x1, %rsi
movq -0x40(%rbp), %rax
cmpl $0x20, %eax
notq %rdx
cmoveq %rsi, %rdx
movq %rdx, -0x1a0(%rbp)
leal -0x2(,%rax,2), %ecx
movq %rcx, -0x1b0(%rbp)
shlq %cl, %rsi
notq %rsi
movq %rsi, -0x1b8(%rbp)
decl %eax
movq %rax, -0x1a8(%rbp)
leaq -0xf8(%rbp), %r15
movq $0x0, -0x30(%rbp)
movl $0x18, %edx
movq 0x734c(%rip), %rdi      # 0x9ff0
leaq 0x43ff(%rip), %rsi      # 0x70aa
callq 0x21c0
movq -0x178(%rbp), %rax
movq -0x30(%rbp), %rcx
movq 0x8(%rax,%rcx,8), %rbx
testq %rbx, %rbx
je 0x2ce1
movq %rbx, %rdi
callq 0x20c0
movq 0x731c(%rip), %rdi      # 0x9ff0
movq %rbx, %rsi
movq %rax, %rdx
callq 0x21c0
jmp 0x2cff
movq 0x7308(%rip), %rcx      # 0x9ff0
movq (%rcx), %rax
movq -0x18(%rax), %rax
leaq (%rcx,%rax), %rdi
movl 0x20(%rcx,%rax), %esi
orl $0x1, %esi
callq 0x22f0
movl $0x1, %edx
movq 0x72e5(%rip), %rdi      # 0x9ff0
leaq 0x4552(%rip), %rsi      # 0x7264
callq 0x21c0
xorl %eax, %eax
movq %rax, -0x48(%rbp)
movq %rax, -0xa8(%rbp)
movq -0xf0(%rbp), %rdx
movq %r15, %rdi
xorl %esi, %esi
leaq 0x43bb(%rip), %rcx      # 0x70f2
xorl %r8d, %r8d
callq 0x2290
movq -0x168(%rbp), %rsi
movq -0x160(%rbp), %rdx
movq %r15, %rdi
callq 0x2080
movq -0x30(%rbp), %rcx
leaq 0x1(%rcx), %rdx
movq -0x178(%rbp), %rcx
movq %rdx, -0x198(%rbp)
movq (%rcx,%rdx,8), %rsi
movq %rax, %rdi
callq 0x2330
movq (%rax), %rdi
leaq 0x4300(%rip), %rsi      # 0x7081
callq 0x2070
movq %rax, -0x70(%rbp)
movq $0x0, -0x60(%rbp)
xorl %eax, %eax
movl %eax, %ecx
andl $0x3, %ecx
movl %ecx, -0x50(%rbp)
movl %eax, -0xac(%rbp)
movl %eax, %eax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
mulsd 0x4254(%rip), %xmm0     # 0x7008
cvttsd2si %xmm0, %r15d
incl %r15d
imulq $0x431bde83, %r15, %rax # imm = 0x431BDE83
shrq $0x32, %rax
imull $0xf4240, %eax, %eax    # imm = 0xF4240
movl %r15d, %ecx
subl %eax, %ecx
movl %ecx, -0xb0(%rbp)
leaq -0x48(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
movq -0x70(%rbp), %rdx
callq 0x2200
cmpq $-0x1, %rax
je 0x30c7
cmpl $0x1, -0x50(%rbp)
jne 0x2e86
cmpl -0x64(%rbp), %r15d
jae 0x30c7
cmpl $0x0, -0xb0(%rbp)
jne 0x2e60
movq 0x71d6(%rip), %rdi      # 0x9ff0
movl %r15d, %esi
callq 0x2300
movq %rax, %rbx
movl $0xd, %edx
movq %rax, %rdi
leaq 0x428f(%rip), %rsi      # 0x70c3
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2160
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2110
movq -0x48(%rbp), %r12
movq %r12, %rdi
callq 0x20c0
decl %eax
subl -0x40(%rbp), %eax
jb 0x2dd8
leal 0x1(%rax), %ecx
addq %rcx, -0x60(%rbp)
incl %eax
movq -0x58(%rbp), %rdx
jne 0x2e93
movl -0xac(%rbp), %eax
incl %eax
jmp 0x2d94
movq -0x1f0(%rbp), %rcx
movq %rcx, -0x50(%rbp)
movq -0x1e8(%rbp), %r9
movl %eax, %r10d
movl $0xfffffffd, %eax       # imm = 0xFFFFFFFD
movq %r12, %r11
xorl %ebx, %ebx
movl %ebx, %ecx
subl %eax, %ecx
cmpl $0x1, %ecx
jne 0x2f20
movq -0x1a8(%rbp), %rax
addl %ebx, %eax
movzbl (%r12,%rax), %eax
addl $-0x43, %eax
cmpl $0x31, %eax
ja 0x30c0
movabsq $0x100000001, %rcx      # imm = 0x100000001
btq %rax, %rcx
jb 0x2fe3
movabsq $0x1000000010, %rcx     # imm = 0x1000000010
btq %rax, %rcx
jb 0x2fdc
movabsq $0x2000000020000, %rcx  # imm = 0x2000000020000
btq %rax, %rcx
movl $0x0, %eax
jae 0x2fe8
movl $0x3, %eax
jmp 0x2fe8
cmpl $0x0, -0x40(%rbp)
je 0x2f95
xorl %eax, %eax
xorl %r13d, %r13d
movabsq $0x100000001, %rsi      # imm = 0x100000001
movabsq $0x1000000010, %rdi     # imm = 0x1000000010
movabsq $0x2000000020000, %r8   # imm = 0x2000000020000
movzbl (%r11,%rax), %ecx
addl $-0x43, %ecx
cmpl $0x31, %ecx
ja 0x2f91
btq %rcx, %rsi
jb 0x2f7b
btq %rcx, %rdi
jb 0x2f74
btq %rcx, %r8
movl $0x0, %ecx
jae 0x2f80
movl $0x3, %ecx
jmp 0x2f80
movl $0x2, %ecx
jmp 0x2f80
movl $0x1, %ecx
shlq $0x2, %r13
orq %rcx, %r13
incq %rax
cmpq %rax, %rdx
jne 0x2f49
jmp 0x2f98
xorl %ecx, %ecx
jmp 0x2f80
xorl %r13d, %r13d
movq -0x40(%rbp), %rcx
testl %ecx, %ecx
je 0x2fd7
movq %r13, %rax
xorq -0x1a0(%rbp), %rax
movl $0x3, %edx
movl %ecx, %esi
xorl %r14d, %r14d
xorl %ecx, %ecx
movq %r14, %rdi
shlq $0x2, %rdi
movq %rdx, %r14
andq %rax, %r14
shrq %cl, %r14
orq %rdi, %r14
shlq $0x2, %rdx
addq $0x2, %rcx
decl %esi
jne 0x2fb6
jmp 0x300b
xorl %r14d, %r14d
jmp 0x300b
movl $0x2, %eax
jmp 0x2fe8
movl $0x1, %eax
andq -0x1b8(%rbp), %r13
shlq $0x2, %r13
orq %rax, %r13
shrq $0x2, %r14
xorq $0x3, %rax
movq -0x1b0(%rbp), %rcx
shlq %cl, %rax
addq %rax, %r14
cmpq %r14, %r13
movq %r14, %rcx
cmovbq %r13, %rcx
cmpq $0x0, -0xd8(%rbp)
cmovneq %r13, %rcx
movq %rcx, %rax
xorl %edx, %edx
divq %r9
movq %rdx, %rsi
movq -0x50(%rbp), %rax
movq (%rax,%rdx,8), %rdx
movl $0x0, %eax
testq %rdx, %rdx
je 0x3077
movq (%rdx), %r15
movq %rdx, %rax
cmpq 0x8(%r15), %rcx
je 0x3077
movq %r15, %r8
movq (%r15), %r15
testq %r15, %r15
je 0x3075
movq 0x8(%r15), %rdi
movq %rdi, %rax
xorl %edx, %edx
divq %r9
movl $0x0, %eax
cmpq %rsi, %rdx
jne 0x3077
movq %r8, %rax
cmpq %rdi, %rcx
jne 0x304a
jmp 0x3077
xorl %eax, %eax
testq %rax, %rax
je 0x3081
movq (%rax), %rax
jmp 0x3083
xorl %eax, %eax
testq %rax, %rax
movq -0x58(%rbp), %rdx
je 0x30a6
movq 0x10(%rax), %rax
movq -0x30(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
addsd 0x3f6f(%rip), %xmm0     # 0x7010
movsd %xmm0, (%rax,%rcx,8)
movl %ebx, %eax
leaq 0x1(%rbx), %rcx
incq %r11
movq %rcx, %rbx
cmpq %r10, %rcx
jne 0x2eb2
jmp 0x2e86
xorl %eax, %eax
jmp 0x2fe8
movq -0xc8(%rbp), %rsi
cmpq -0xc0(%rbp), %rsi
je 0x30f2
movq -0x60(%rbp), %rax
movq %rax, (%rsi)
addq $0x8, %rsi
movq %rsi, -0xc8(%rbp)
leaq -0xf8(%rbp), %r15
jmp 0x3109
leaq -0xd0(%rbp), %rdi
leaq -0x60(%rbp), %rdx
callq 0x56a4
leaq -0xf8(%rbp), %r15
cmpq $0x0, -0x190(%rbp)
je 0x31cc
cmpq $0x0, -0x60(%rbp)
je 0x31cc
movl $0x10, %edx
movq 0x6ec2(%rip), %rdi      # 0x9ff0
leaq 0x3f9c(%rip), %rsi      # 0x70d1
callq 0x21c0
movq 0x6eaf(%rip), %rcx      # 0x9ff0
movq (%rcx), %rax
movq -0x18(%rax), %rdi
addq %rcx, %rdi
movl $0xa, %esi
callq 0x2160
movsbl %al, %esi
movq 0x6e91(%rip), %rdi      # 0x9ff0
callq 0x2040
movq %rax, %rdi
callq 0x2110
movq -0x1e0(%rbp), %rax
testq %rax, %rax
je 0x31cc
movsd -0x60(%rbp), %xmm1
unpcklps 0x3eac(%rip), %xmm1     # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x3eb4(%rip), %xmm1     # 0x7040
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
movq 0x10(%rax), %rcx
movq -0x30(%rbp), %rdx
movsd (%rcx,%rdx,8), %xmm1
ucomisd 0x3e73(%rip), %xmm1     # 0x7020
jbe 0x31c4
mulsd 0x3e61(%rip), %xmm1     # 0x7018
divsd %xmm0, %xmm1
movq -0x30(%rbp), %rdx
movsd %xmm1, (%rcx,%rdx,8)
movq (%rax), %rax
testq %rax, %rax
jne 0x3198
movq -0x70(%rbp), %rdi
callq 0x2170
movq -0x48(%rbp), %rdi
testq %rdi, %rdi
je 0x31e3
callq 0x21e0
movq -0x198(%rbp), %rax
movq %rax, -0x30(%rbp)
cmpq -0x78(%rbp), %rax
jne 0x2c98
movq 0x6dc9(%rip), %r15      # 0x9fc8
leaq 0x3edc(%rip), %rsi      # 0x70e2
movl $0x3, %edx
movq %r15, %rdi
callq 0x21c0
cmpq $0x0, -0xa0(%rbp)
je 0x3235
movq 0x6da4(%rip), %rdi      # 0x9fc8
leaq 0x3ebb(%rip), %rsi      # 0x70e6
movl $0xa, %edx
callq 0x21c0
cmpl $0x0, -0x34(%rbp)
je 0x329f
xorl %r14d, %r14d
leaq 0x3eac(%rip), %rbx      # 0x70f1
movl $0x1, %edx
movq %r15, %rdi
movq %rbx, %rsi
callq 0x21c0
movq -0x178(%rbp), %rax
movq 0x8(%rax,%r14,8), %r12
testq %r12, %r12
je 0x327e
movq %r12, %rdi
callq 0x20c0
movq %r15, %rdi
movq %r12, %rsi
movq %rax, %rdx
callq 0x21c0
jmp 0x3296
movq (%r15), %rax
movq -0x18(%rax), %rax
leaq (%r15,%rax), %rdi
movl 0x20(%r15,%rax), %esi
orl $0x1, %esi
callq 0x22f0
incq %r14
cmpq %r14, -0x78(%rbp)
jne 0x3245
movq 0x6d22(%rip), %r15      # 0x9fc8
leaq 0x3fb7(%rip), %rsi      # 0x7264
movl $0x1, %edx
movq %r15, %rdi
callq 0x21c0
movq -0x58(%rbp), %rdi
callq 0x2030
movq -0x1e0(%rbp), %r14
testq %r14, %r14
je 0x3400
movq %rax, %r12
leaq 0x3e14(%rip), %r13      # 0x70f1
leaq 0x8(%r14), %rbx
cmpl $0x0, -0x40(%rbp)
je 0x330e
movq (%rbx), %rax
movq -0x58(%rbp), %rdx
leal (,%rax,8), %ecx
movl $0x54474341, %esi       # imm = 0x54474341
shrl %cl, %esi
decq %rdx
movl %edx, %ecx
movb %sil, (%r12,%rcx)
shrq $0x2, %rax
testq %rdx, %rdx
jne 0x32ee
movq %r12, %rdi
callq 0x20c0
movq %r15, %rdi
movq %r12, %rsi
movq %rax, %rdx
callq 0x21c0
cmpq $0x0, -0xa0(%rbp)
je 0x339b
movl $0x1, %edx
movq %r15, %rdi
movq %r13, %rsi
callq 0x21c0
leaq -0x228(%rbp), %rdi
movq %rbx, %rsi
callq 0x5156
leaq -0x128(%rbp), %rdi
movq %rax, %rsi
leaq 0x3d95(%rip), %rdx      # 0x70f3
callq 0x253c
movq -0x128(%rbp), %rsi
movq -0x120(%rbp), %rdx
movq %r15, %rdi
callq 0x21c0
movq -0x128(%rbp), %rdi
leaq -0x118(%rbp), %rax
cmpq %rax, %rdi
je 0x339b
movq -0x118(%rbp), %rsi
incq %rsi
callq 0x2190
cmpl $0x0, -0x34(%rbp)
je 0x33cd
xorl %ebx, %ebx
movl $0x1, %edx
movq %r15, %rdi
movq %r13, %rsi
callq 0x21c0
movq 0x10(%r14), %rax
movsd (%rax,%rbx,8), %xmm0
movq %r15, %rdi
callq 0x22c0
incq %rbx
cmpq %rbx, -0x78(%rbp)
jne 0x33a3
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x2160
movsbl %al, %esi
movq %r15, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2110
movq (%r14), %r14
testq %r14, %r14
jne 0x32dd
movq 0x6bc1(%rip), %rbx      # 0x9fc8
leaq 0x3ce7(%rip), %rsi      # 0x70f5
movl $0xd, %edx
movq %rbx, %rdi
callq 0x21c0
cmpq $0x0, -0xa0(%rbp)
je 0x343d
movq 0x6b9c(%rip), %rdi      # 0x9fc8
leaq 0x3cd0(%rip), %rsi      # 0x7103
movl $0x2, %edx
callq 0x21c0
cmpl $0x0, -0x34(%rbp)
je 0x3480
xorl %r12d, %r12d
movq 0x6b7b(%rip), %r14      # 0x9fc8
leaq 0x3c9d(%rip), %r15      # 0x70f1
movl $0x1, %edx
movq %r14, %rdi
movq %r15, %rsi
callq 0x21c0
movq -0xd0(%rbp), %rax
movq (%rax,%r12,8), %rsi
movq %r14, %rdi
callq 0x2100
incq %r12
cmpq %r12, -0x78(%rbp)
jne 0x3454
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x2160
movsbl %al, %esi
movq 0x6b2a(%rip), %rdi      # 0x9fc8
callq 0x2040
xorl %r15d, %r15d
movq %rax, %rdi
callq 0x2110
movq -0x188(%rbp), %rsp
movq -0xf8(%rbp), %rdi
leaq -0xe8(%rbp), %rax
cmpq %rax, %rdi
je 0x34d7
movq -0xe8(%rbp), %rsi
incq %rsi
callq 0x2190
movq -0x148(%rbp), %rdi
leaq -0x138(%rbp), %rax
cmpq %rax, %rdi
je 0x34f9
movq -0x138(%rbp), %rsi
incq %rsi
callq 0x2190
movq -0x168(%rbp), %rdi
leaq -0x158(%rbp), %rax
cmpq %rax, %rdi
je 0x351b
movq -0x158(%rbp), %rsi
incq %rsi
callq 0x2190
movq -0xd0(%rbp), %rdi
testq %rdi, %rdi
je 0x3536
movq -0xc0(%rbp), %rsi
subq %rdi, %rsi
callq 0x2190
leaq -0x228(%rbp), %rdi
callq 0x3f72
leaq -0x1f0(%rbp), %rdi
callq 0x4072
movq -0x98(%rbp), %rdi
leaq -0x88(%rbp), %rax
cmpq %rax, %rdi
je 0x3570
movq -0x88(%rbp), %rsi
incq %rsi
callq 0x2190
movl %r15d, %eax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x35d4
jmp 0x35d4
movq %rax, %rbx
leaq -0x88(%rbp), %r15
jmp 0x3622
movq %rax, %rbx
jmp 0x3644
movq %rax, %rbx
movq -0x128(%rbp), %rdi
leaq -0x118(%rbp), %rax
cmpq %rax, %rdi
je 0x35d7
movq -0x118(%rbp), %rsi
incq %rsi
callq 0x2190
jmp 0x35d7
jmp 0x35d4
jmp 0x35d4
jmp 0x35d4
jmp 0x35d4
jmp 0x35d4
jmp 0x35d4
jmp 0x35d4
jmp 0x35d4
movq %rax, %rbx
leaq -0x88(%rbp), %r15
movq -0xf8(%rbp), %rdi
leaq -0xe8(%rbp), %rax
cmpq %rax, %rdi
je 0x3600
movq -0xe8(%rbp), %rsi
incq %rsi
callq 0x2190
movq -0x148(%rbp), %rdi
leaq -0x138(%rbp), %rax
cmpq %rax, %rdi
je 0x3622
movq -0x138(%rbp), %rsi
incq %rsi
callq 0x2190
movq -0x168(%rbp), %rdi
leaq -0x158(%rbp), %rax
cmpq %rax, %rdi
je 0x3644
movq -0x158(%rbp), %rsi
incq %rsi
callq 0x2190
movq -0xd0(%rbp), %rdi
testq %rdi, %rdi
je 0x365f
movq -0xc0(%rbp), %rsi
subq %rdi, %rsi
callq 0x2190
leaq -0x228(%rbp), %rdi
callq 0x3f72
leaq -0x1f0(%rbp), %rdi
callq 0x4072
movq -0x98(%rbp), %rdi
cmpq %r15, %rdi
je 0x3692
movq -0x88(%rbp), %rsi
incq %rsi
callq 0x2190
movq %rbx, %rdi
callq 0x2310