// File: AlgoLab[P]bwt-lcp-parallel/bwt_lcp.cpp
// Function: compute_interleave_LCP(unsigned char, unsigned int, std::vector<std::array<unsigned long, 6ul>, std::allocator<std::array<unsigned long, 6ul>>> const&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
void compute_interleave_LCP(
    const strlen_t k, const strnum_t m,
    const occ_countv_t& occv,
    const fnames_t& B_tpl,
    const fname_t& IXk_name
) {
  const fnames_t IX_names = {
    "supportfile-IX0.tmp",
    "supportfile-IX1.tmp",
  };
  const fnames_t Q_tpls[] = {
    template_generator("supportfile-Q0_%.3d.tmp", 0, k+1),
    template_generator("supportfile-Q1_%.3d.tmp", 0, k+1),
  };

  const luint_t tot = static_cast<luint_t>(m)*(k+1);
  const fnames_t L_tpl = template_generator("supportfile-L_%d.tmp", 0, ALPHSIZE);

  const fname_t LCP_name = "outfile-LCP.bin";
  { // IX0/1 and LCP
    strlen_writer_t IX0(IX_names[0]);
    for (strlen_t l = 0; l <= k; ++l) {
      for (strnum_t i = 0; i < m; ++i) {
        IX0.write(l);
      }
    }
    create_empty_file<strlen_t>(LCP_name, tot);
    create_empty_file<strlen_t>(IX_names[1], tot);
  }

  compute_Q1_l(k, occv, Q_tpls[0]);

  lcp_writer_t LCP(LCP_name);
  LCP.seek(0);
  LCP.write(static_cast<strlen_t>(-1));

  bool has_pseg_wider_than_1 = true;
  base_env_t base_env{k, m, IX_names, LCP};

  std::vector<luint_t> end_pos(concurrency_level+1, tot);
  end_pos[0] = 0;
  std::vector<std::vector<strnum_t>> end_pos_Qp(concurrency_level+1, std::vector<strnum_t>(k+1, 0));
  std::vector<bfv_env_t> bfv_envs;
  for (unsigned idx = 0; idx < concurrency_level; ++idx)
    bfv_envs.emplace_back(base_env);

  while (has_pseg_wider_than_1) {
    has_pseg_wider_than_1 = false;
    ++base_env.p;
    std::cout << " - iteration " << static_cast<fuint_t>(base_env.p) << std::endl;
    const fnames_t& prevQ_tpl = Q_tpls[(base_env.p-1)%2];
    const fnames_t& currQ_tpl = Q_tpls[base_env.p%2];
    std::vector<luint_t> this_end_pos = end_pos;
    std::vector<std::vector<strnum_t>> this_end_pos_Qp = end_pos_Qp;
    {
      std::cout << "   - compute IX";
      for (strlen_t l = base_env.p+1; l <= k+1; ++l) {
        base_env.Qp.emplace_back(prevQ_tpl[l-1]);
      }
      std::vector<std::thread> threads;
      unsigned idx;
      for (idx = 1; idx <= concurrency_level && this_end_pos[idx-1] < tot; ++idx) {
        threads
          .emplace_back(worker_IX,
                        idx, std::ref(base_env), std::ref(bfv_envs[idx-1]),
                        std::cref(this_end_pos), std::cref(this_end_pos_Qp)
                        );
      }
      for (auto& t: threads) {
        t.join();
      }
      for (unsigned j = 0; j < idx-1; ++j) {
        has_pseg_wider_than_1 |= bfv_envs[j].has_pseg_wider_than_1;
      }
      std::vector<size_t> pos(idx-1, 0);
      unsigned midi = 0;
      unsigned finished = 0;
      for (unsigned j = 0; j < idx-1; ++j) {
        while (pos[j] < bfv_envs[j].end_pos.size() &&
               bfv_envs[j].end_pos[pos[j]] <  base_env.midpoints[midi]) {
          ++pos[j];
        }
        if (pos[j] >= bfv_envs[j].end_pos.size()) ++finished;
      }
      while (finished < idx - 1) {
        luint_t cmin_j = 0;
        for (unsigned j = 0; j < idx-1; ++j) {
          if (
              pos[j] < bfv_envs[j].end_pos.size() &&
              bfv_envs[j].end_pos[pos[j]] >= base_env.midpoints[midi] &&
              (bfv_envs[j].end_pos[pos[j]] < bfv_envs[cmin_j].end_pos[pos[cmin_j]] ||
               bfv_envs[cmin_j].end_pos[pos[cmin_j]] < base_env.midpoints[midi])
              ) {
            cmin_j = j;
          }
        }
        if (pos[cmin_j] >= bfv_envs[cmin_j].end_pos.size()) break;
        end_pos[midi+1]= bfv_envs[cmin_j].end_pos[pos[cmin_j]];
        end_pos_Qp[midi+1] = bfv_envs[cmin_j].end_pos_Qp[pos[cmin_j]];
        ++midi;
        ++pos[cmin_j];
        finished = 0;
        for (unsigned j = 0; j < idx-1; ++j) {
          while (pos[j] < bfv_envs[j].end_pos.size() &&
                 bfv_envs[j].end_pos[pos[j]] <  base_env.midpoints[midi]) {
            ++pos[j];
          }
          if (pos[j] >= bfv_envs[j].end_pos.size()) ++finished;
        }
      }
      base_env.Qp.clear();
      std::cout << std::endl;
    }
    if (has_pseg_wider_than_1) {
      std::cout << "   - compute Qp" << std::endl;
      remove_file(currQ_tpl[base_env.p-1]);
      remove_file(prevQ_tpl[k]);
      std::vector<std::thread> threads;
      std::atomic<luint_t> shared_l(base_env.p+1);
      for (unsigned idx = 0; idx < concurrency_level; ++idx) {
        threads
          .emplace_back(worker_Qp,
                        std::ref(shared_l), k, m, std::cref(occv),
                        std::cref(B_tpl), std::cref(prevQ_tpl), std::cref(currQ_tpl)
                        );
      }
      for (auto& t: threads) {
        t.join();
      }
    } else {
      remove_file(currQ_tpl[base_env.p-1]);
      remove_file(prevQ_tpl[k]);
      for (strlen_t l = base_env.p+1; l <= k; ++l) {
        remove_file(prevQ_tpl[l-1]);
      }
    }
  }
  rename_file(IX_names[base_env.p%2], IXk_name);
  remove_file(IX_names[(base_env.p-1)%2]);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x650, %rsp            # imm = 0x650
movb %dil, %al
movb %al, -0x1(%rbp)
movl %esi, -0x8(%rbp)
movq %rdx, -0x10(%rbp)
movq %rcx, -0x18(%rbp)
movq %r8, -0x20(%rbp)
movb $0x1, -0xa6(%rbp)
leaq -0x88(%rbp), %rax
movq %rax, -0x468(%rbp)
movq %rax, -0x90(%rbp)
leaq -0x91(%rbp), %rdi
movq %rdi, -0x460(%rbp)
callq 0x3490
movq -0x468(%rbp), %rdi
movq -0x460(%rbp), %rdx
leaq 0x1420c(%rip), %rsi     # 0x190f0
callq 0x7fd0
jmp 0x4eeb
leaq -0x68(%rbp), %rax
movq %rax, -0x478(%rbp)
movq %rax, -0x90(%rbp)
leaq -0xa5(%rbp), %rdi
movq %rdi, -0x470(%rbp)
callq 0x3490
movq -0x478(%rbp), %rdi
movq -0x470(%rbp), %rdx
leaq 0x141df(%rip), %rsi     # 0x19104
callq 0x7fd0
jmp 0x4f2c
movb $0x0, -0xa6(%rbp)
leaq -0x88(%rbp), %rax
movq %rax, -0x48(%rbp)
movq $0x2, -0x40(%rbp)
leaq -0xa7(%rbp), %rdi
movq %rdi, -0x480(%rbp)
callq 0x9820
movq -0x480(%rbp), %rcx
movq -0x48(%rbp), %rsi
movq -0x40(%rbp), %rdx
leaq -0x38(%rbp), %rdi
callq 0x9840
jmp 0x4f73
leaq -0xa7(%rbp), %rdi
callq 0x98c0
leaq -0x88(%rbp), %rax
movq %rax, -0x490(%rbp)
addq $0x40, %rax
movq %rax, -0x488(%rbp)
movq -0x488(%rbp), %rdi
addq $-0x20, %rdi
movq %rdi, -0x498(%rbp)
callq 0x3170
movq -0x490(%rbp), %rcx
movq -0x498(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x488(%rbp)
jne 0x4f98
leaq -0xa5(%rbp), %rdi
callq 0x3300
leaq -0x91(%rbp), %rdi
callq 0x3300
movb $0x1, -0x132(%rbp)
leaq -0xe0(%rbp), %rax
movq %rax, -0xe8(%rbp)
leaq -0x109(%rbp), %rdi
movq %rdi, -0x4a0(%rbp)
callq 0x3490
movq -0x4a0(%rbp), %rdx
leaq 0x14101(%rip), %rsi     # 0x19118
leaq -0x108(%rbp), %rdi
callq 0x7fd0
jmp 0x5025
movzbl -0x1(%rbp), %ecx
incl %ecx
leaq -0xe0(%rbp), %rdi
leaq -0x108(%rbp), %rsi
xorl %edx, %edx
callq 0x3650
jmp 0x5042
leaq -0xc8(%rbp), %rax
movq %rax, -0x4b0(%rbp)
movq %rax, -0xe8(%rbp)
leaq -0x131(%rbp), %rdi
movq %rdi, -0x4a8(%rbp)
callq 0x3490
movq -0x4a8(%rbp), %rdx
leaq 0x140b8(%rip), %rsi     # 0x19130
leaq -0x130(%rbp), %rdi
callq 0x7fd0
jmp 0x5086
movq -0x4b0(%rbp), %rdi
movzbl -0x1(%rbp), %ecx
incl %ecx
leaq -0x130(%rbp), %rsi
xorl %edx, %edx
callq 0x3650
jmp 0x50a3
movb $0x0, -0x132(%rbp)
leaq -0x130(%rbp), %rdi
callq 0x3170
leaq -0x131(%rbp), %rdi
callq 0x3300
leaq -0x108(%rbp), %rdi
callq 0x3170
leaq -0x109(%rbp), %rdi
callq 0x3300
movl -0x8(%rbp), %eax
movzbl -0x1(%rbp), %ecx
incl %ecx
imulq %rcx, %rax
movq %rax, -0x140(%rbp)
leaq -0x179(%rbp), %rdi
movq %rdi, -0x4b8(%rbp)
callq 0x3490
movq -0x4b8(%rbp), %rdx
leaq 0x14039(%rip), %rsi     # 0x19148
leaq -0x178(%rbp), %rdi
callq 0x7fd0
jmp 0x511d
leaq -0x158(%rbp), %rdi
leaq -0x178(%rbp), %rsi
xorl %edx, %edx
movl $0x6, %ecx
callq 0x3650
jmp 0x5139
leaq -0x178(%rbp), %rdi
callq 0x3170
leaq -0x179(%rbp), %rdi
callq 0x3300
leaq -0x1a1(%rbp), %rdi
movq %rdi, -0x4c0(%rbp)
callq 0x3490
movq -0x4c0(%rbp), %rdx
leaq 0x13feb(%rip), %rsi     # 0x1915d
leaq -0x1a0(%rbp), %rdi
callq 0x7fd0
jmp 0x5180
leaq -0x1a1(%rbp), %rdi
callq 0x3300
xorl %eax, %eax
movl %eax, %esi
leaq -0x38(%rbp), %rdi
callq 0x8080
movq %rax, %rsi
leaq 0x13ea1(%rip), %rdx     # 0x19044
leaq -0x1b0(%rbp), %rdi
callq 0x8850
jmp 0x51b1
movb $0x0, -0x1b1(%rbp)
movzbl -0x1b1(%rbp), %eax
movzbl -0x1(%rbp), %ecx
cmpl %ecx, %eax
jg 0x54a6
movl $0x0, -0x1b8(%rbp)
movl -0x1b8(%rbp), %eax
cmpl -0x8(%rbp), %eax
jae 0x5491
movzbl -0x1b1(%rbp), %esi
leaq -0x1b0(%rbp), %rdi
callq 0x88f0
jmp 0x51f9
jmp 0x51fb
movl -0x1b8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1b8(%rbp)
jmp 0x51d5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x52ad
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x52a1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0xa7(%rbp), %rdi
callq 0x98c0
leaq -0x88(%rbp), %rax
movq %rax, -0x4d0(%rbp)
addq $0x40, %rax
movq %rax, -0x4c8(%rbp)
movq -0x4c8(%rbp), %rdi
addq $-0x20, %rdi
movq %rdi, -0x4d8(%rbp)
callq 0x3170
movq -0x4d0(%rbp), %rcx
movq -0x4d8(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x4c8(%rbp)
jne 0x526e
jmp 0x52a1
leaq -0xa5(%rbp), %rdi
callq 0x3300
leaq -0x91(%rbp), %rdi
callq 0x3300
testb $0x1, -0xa6(%rbp)
jne 0x52c4
jmp 0x5311
movq -0x90(%rbp), %rax
leaq -0x88(%rbp), %rcx
cmpq %rax, %rcx
movq %rax, -0x4e0(%rbp)
je 0x530f
movq -0x4e0(%rbp), %rdi
addq $-0x20, %rdi
movq %rdi, -0x4e8(%rbp)
callq 0x3170
movq -0x4e8(%rbp), %rax
leaq -0x88(%rbp), %rcx
cmpq %rcx, %rax
movq %rax, -0x4e0(%rbp)
jne 0x52de
jmp 0x5311
jmp 0x6719
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x5388
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x537c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x5370
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0x130(%rbp), %rdi
callq 0x3170
leaq -0x131(%rbp), %rdi
callq 0x3300
leaq -0x108(%rbp), %rdi
callq 0x3170
leaq -0x109(%rbp), %rdi
callq 0x3300
testb $0x1, -0x132(%rbp)
jne 0x539f
jmp 0x53ec
movq -0xe8(%rbp), %rax
leaq -0xe0(%rbp), %rcx
cmpq %rax, %rcx
movq %rax, -0x4f0(%rbp)
je 0x53ea
movq -0x4f0(%rbp), %rdi
addq $-0x18, %rdi
movq %rdi, -0x4f8(%rbp)
callq 0x7e90
movq -0x4f8(%rbp), %rax
leaq -0xe0(%rbp), %rcx
cmpq %rcx, %rax
movq %rax, -0x4f0(%rbp)
jne 0x53b9
jmp 0x53ec
jmp 0x6710
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x5423
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0x178(%rbp), %rdi
callq 0x3170
leaq -0x179(%rbp), %rdi
callq 0x3300
jmp 0x66c4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0x1a1(%rbp), %rdi
callq 0x3300
jmp 0x66b8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x66ac
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0x1b0(%rbp), %rdi
callq 0x8920
jmp 0x66ac
jmp 0x5493
movb -0x1b1(%rbp), %al
addb $0x1, %al
movb %al, -0x1b1(%rbp)
jmp 0x51b8
movq -0x140(%rbp), %rsi
leaq -0x1a0(%rbp), %rdi
callq 0x9750
jmp 0x54bb
leaq -0x38(%rbp), %rdi
movl $0x1, %esi
callq 0x8080
movq %rax, %rdi
movq -0x140(%rbp), %rsi
callq 0x9750
jmp 0x54da
leaq -0x1b0(%rbp), %rdi
callq 0x8920
movzbl -0x1(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq -0xe0(%rbp), %rdx
callq 0x4050
jmp 0x54fc
leaq -0x1e0(%rbp), %rdi
leaq -0x1a0(%rbp), %rsi
callq 0x98e0
jmp 0x5511
xorl %eax, %eax
movl %eax, %esi
leaq -0x1e0(%rbp), %rdi
callq 0x8620
jmp 0x5523
leaq -0x1e0(%rbp), %rdi
movl $0xff, %esi
callq 0x8780
jmp 0x5536
movb $0x1, -0x1e1(%rbp)
movzbl -0x1(%rbp), %esi
movl -0x8(%rbp), %edx
leaq -0x278(%rbp), %rdi
leaq -0x38(%rbp), %rcx
leaq -0x1e0(%rbp), %r8
callq 0x9940
jmp 0x555d
movl 0x21d45(%rip), %eax     # 0x272a8
incl %eax
movq %rax, -0x508(%rbp)
leaq -0x291(%rbp), %rdi
movq %rdi, -0x500(%rbp)
callq 0x9b90
movq -0x508(%rbp), %rsi
movq -0x500(%rbp), %rcx
leaq -0x290(%rbp), %rdi
leaq -0x140(%rbp), %rdx
callq 0x9bb0
jmp 0x55a2
leaq -0x291(%rbp), %rdi
callq 0x9c30
xorl %eax, %eax
movl %eax, %esi
leaq -0x290(%rbp), %rdi
callq 0x9c50
movq $0x0, (%rax)
movl 0x21cdd(%rip), %eax     # 0x272a8
incl %eax
movq %rax, -0x520(%rbp)
movzbl -0x1(%rbp), %eax
incl %eax
movq %rax, -0x518(%rbp)
movl $0x0, -0x2cc(%rbp)
leaq -0x2cd(%rbp), %rdi
movq %rdi, -0x510(%rbp)
callq 0x9c70
movq -0x518(%rbp), %rsi
movq -0x510(%rbp), %rcx
leaq -0x2c8(%rbp), %rdi
leaq -0x2cc(%rbp), %rdx
callq 0x9c90
jmp 0x5621
leaq -0x2ce(%rbp), %rdi
movq %rdi, -0x528(%rbp)
callq 0x9d10
movq -0x520(%rbp), %rsi
movq -0x528(%rbp), %rcx
leaq -0x2b0(%rbp), %rdi
leaq -0x2c8(%rbp), %rdx
callq 0x9d30
jmp 0x5657
leaq -0x2ce(%rbp), %rdi
callq 0x9db0
leaq -0x2c8(%rbp), %rdi
callq 0x9600
leaq -0x2cd(%rbp), %rdi
callq 0x9dd0
leaq -0x2e8(%rbp), %rdi
callq 0x9df0
movl $0x0, -0x2ec(%rbp)
movl -0x2ec(%rbp), %eax
cmpl 0x21c0b(%rip), %eax     # 0x272a8
jae 0x576b
leaq -0x2e8(%rbp), %rdi
leaq -0x278(%rbp), %rsi
callq 0x9e10
jmp 0x56b8
jmp 0x56ba
movl -0x2ec(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2ec(%rbp)
jmp 0x5691
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x66a0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0x291(%rbp), %rdi
callq 0x9c30
jmp 0x6694
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x5743
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0x2ce(%rbp), %rdi
callq 0x9db0
leaq -0x2c8(%rbp), %rdi
callq 0x9600
leaq -0x2cd(%rbp), %rdi
callq 0x9dd0
jmp 0x6688
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x6670
jmp 0x576d
testb $0x1, -0x1e1(%rbp)
je 0x6573
movb $0x0, -0x1e1(%rbp)
movb -0x248(%rbp), %al
incb %al
movb %al, -0x248(%rbp)
movq 0x2183a(%rip), %rdi     # 0x26fd0
leaq 0x139d0(%rip), %rsi     # 0x1916d
callq 0x3290
movq %rax, -0x530(%rbp)
jmp 0x57ab
movq -0x530(%rbp), %rdi
movzbl -0x248(%rbp), %eax
movl %eax, %esi
callq 0x3060
movq %rax, -0x538(%rbp)
jmp 0x57c9
movq -0x538(%rbp), %rdi
movq 0x217e1(%rip), %rsi     # 0x26fb8
callq 0x32d0
jmp 0x57de
movzbl -0x248(%rbp), %ecx
movl %ecx, %edx
decl %edx
movl %ecx, %eax
shrl $0x1f, %edx
movl %edx, %ecx
leal -0x1(%rax,%rcx), %edx
andl $-0x2, %edx
negl %edx
movl %edx, %ecx
leal -0x1(%rax,%rcx), %eax
cltq
leaq (%rax,%rax,2), %rax
leaq -0xe0(%rbp,%rax,8), %rax
movq %rax, -0x2f8(%rbp)
movzbl -0x248(%rbp), %eax
andl $0x1, %eax
leaq (%rax,%rax,2), %rax
leaq -0xe0(%rbp,%rax,8), %rax
movq %rax, -0x300(%rbp)
leaq -0x318(%rbp), %rdi
leaq -0x290(%rbp), %rsi
callq 0x9e90
jmp 0x5846
leaq -0x330(%rbp), %rdi
leaq -0x2b0(%rbp), %rsi
callq 0x9f80
jmp 0x585b
movq 0x2176e(%rip), %rdi     # 0x26fd0
leaq 0x13912(%rip), %rsi     # 0x1917b
callq 0x3290
jmp 0x5870
movzbl -0x248(%rbp), %eax
addl $0x1, %eax
movb %al, -0x331(%rbp)
movzbl -0x331(%rbp), %eax
movzbl -0x1(%rbp), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
jg 0x5909
leaq -0x260(%rbp), %rax
movq %rax, -0x540(%rbp)
movq -0x2f8(%rbp), %rdi
movzbl -0x331(%rbp), %eax
movl %eax, %esi
decq %rsi
callq 0x8080
movq -0x540(%rbp), %rdi
movq %rax, %rsi
callq 0xa070
jmp 0x58c9
jmp 0x58cb
movb -0x331(%rbp), %al
addb $0x1, %al
movb %al, -0x331(%rbp)
jmp 0x5880
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x6562
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x6556
leaq -0x350(%rbp), %rdi
callq 0xa0f0
movl $0x1, -0x354(%rbp)
movl -0x354(%rbp), %ecx
xorl %eax, %eax
cmpl 0x2197b(%rip), %ecx     # 0x272a8
movb %al, -0x541(%rbp)
ja 0x5961
movl -0x354(%rbp), %eax
subl $0x1, %eax
movl %eax, %eax
movl %eax, %esi
leaq -0x318(%rbp), %rdi
callq 0x9c50
movq (%rax), %rax
cmpq -0x140(%rbp), %rax
setb %al
movb %al, -0x541(%rbp)
movb -0x541(%rbp), %al
testb $0x1, %al
jne 0x5970
jmp 0x5a39
leaq -0x278(%rbp), %rdi
callq 0xa1d0
movq %rax, -0x360(%rbp)
movl -0x354(%rbp), %eax
decl %eax
movl %eax, %esi
leaq -0x2e8(%rbp), %rdi
callq 0xa230
movq %rax, %rdi
callq 0xa200
movq %rax, -0x368(%rbp)
leaq -0x318(%rbp), %rdi
callq 0xa250
movq %rax, -0x370(%rbp)
leaq -0x330(%rbp), %rdi
callq 0xa280
movq %rax, -0x378(%rbp)
movq %rsp, %rax
leaq -0x378(%rbp), %rcx
movq %rcx, (%rax)
leaq -0xf92(%rip), %rsi      # 0x4a50
leaq -0x350(%rbp), %rdi
leaq -0x354(%rbp), %rdx
leaq -0x360(%rbp), %rcx
leaq -0x368(%rbp), %r8
leaq -0x370(%rbp), %r9
callq 0xa110
jmp 0x5a0c
jmp 0x5a0e
movl -0x354(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x354(%rbp)
jmp 0x591f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
jmp 0x63e9
leaq -0x350(%rbp), %rax
movq %rax, -0x380(%rbp)
movq -0x380(%rbp), %rdi
callq 0xa2b0
movq %rax, -0x388(%rbp)
movq -0x380(%rbp), %rdi
callq 0xa2e0
movq %rax, -0x390(%rbp)
leaq -0x388(%rbp), %rdi
leaq -0x390(%rbp), %rsi
callq 0xa310
testb $0x1, %al
jne 0x5a86
jmp 0x5ab7
leaq -0x388(%rbp), %rdi
callq 0xa350
movq %rax, -0x398(%rbp)
movq -0x398(%rbp), %rdi
callq 0x3460
jmp 0x5aa7
jmp 0x5aa9
leaq -0x388(%rbp), %rdi
callq 0xa370
jmp 0x5a6d
movl $0x0, -0x39c(%rbp)
movl -0x39c(%rbp), %eax
movl -0x354(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jae 0x5b1c
movl -0x39c(%rbp), %eax
movl %eax, %esi
leaq -0x2e8(%rbp), %rdi
callq 0xa230
movb 0x29(%rax), %al
andb $0x1, %al
movzbl %al, %ecx
movb -0x1e1(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
orl %ecx, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, -0x1e1(%rbp)
movl -0x39c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x39c(%rbp)
jmp 0x5ac1
movl -0x354(%rbp), %eax
decl %eax
movq %rax, -0x558(%rbp)
movq $0x0, -0x3c0(%rbp)
leaq -0x3c1(%rbp), %rdi
movq %rdi, -0x550(%rbp)
callq 0x9b90
movq -0x558(%rbp), %rsi
movq -0x550(%rbp), %rcx
leaq -0x3b8(%rbp), %rdi
leaq -0x3c0(%rbp), %rdx
callq 0x9bb0
jmp 0x5b6c
leaq -0x3c1(%rbp), %rdi
callq 0x9c30
movl $0x0, -0x3c8(%rbp)
movl $0x0, -0x3cc(%rbp)
movl $0x0, -0x3d0(%rbp)
movl -0x3d0(%rbp), %eax
movl -0x354(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jae 0x5d27
jmp 0x5baf
movl -0x3d0(%rbp), %eax
movl %eax, %esi
leaq -0x3b8(%rbp), %rdi
callq 0x9c50
movq (%rax), %rax
movq %rax, -0x568(%rbp)
movl -0x3d0(%rbp), %eax
movl %eax, %esi
leaq -0x2e8(%rbp), %rdi
callq 0xa230
movq %rax, %rdi
addq $0x30, %rdi
callq 0xa390
movq -0x568(%rbp), %rcx
movq %rax, %rdx
xorl %eax, %eax
cmpq %rdx, %rcx
movb %al, -0x559(%rbp)
jae 0x5c63
movl -0x3d0(%rbp), %eax
movl %eax, %esi
leaq -0x2e8(%rbp), %rdi
callq 0xa230
addq $0x30, %rax
movq %rax, -0x570(%rbp)
movl -0x3d0(%rbp), %eax
movl %eax, %esi
leaq -0x3b8(%rbp), %rdi
callq 0x9c50
movq -0x570(%rbp), %rdi
movq (%rax), %rsi
callq 0x9c50
movq (%rax), %rax
movq -0x240(%rbp), %rcx
movl -0x3c8(%rbp), %edx
cmpq (%rcx,%rdx,8), %rax
setb %al
movb %al, -0x559(%rbp)
movb -0x559(%rbp), %al
testb $0x1, %al
jne 0x5c6f
jmp 0x5cb5
movl -0x3d0(%rbp), %eax
movl %eax, %esi
leaq -0x3b8(%rbp), %rdi
callq 0x9c50
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
jmp 0x5baf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0x3c1(%rbp), %rdi
callq 0x9c30
jmp 0x63e9
movl -0x3d0(%rbp), %eax
movl %eax, %esi
leaq -0x3b8(%rbp), %rdi
callq 0x9c50
movq (%rax), %rax
movq %rax, -0x578(%rbp)
movl -0x3d0(%rbp), %eax
movl %eax, %esi
leaq -0x2e8(%rbp), %rdi
callq 0xa230
movq %rax, %rdi
addq $0x30, %rdi
callq 0xa390
movq %rax, %rcx
movq -0x578(%rbp), %rax
cmpq %rcx, %rax
jb 0x5d11
movl -0x3cc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3cc(%rbp)
jmp 0x5d13
movl -0x3d0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3d0(%rbp)
jmp 0x5b96
jmp 0x5d29
movl -0x3cc(%rbp), %eax
movl -0x354(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jae 0x6239
movq $0x0, -0x3d8(%rbp)
movl $0x0, -0x3dc(%rbp)
movl -0x3dc(%rbp), %eax
movl -0x354(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jae 0x5f2d
movl -0x3dc(%rbp), %eax
movl %eax, %esi
leaq -0x3b8(%rbp), %rdi
callq 0x9c50
movq (%rax), %rax
movq %rax, -0x580(%rbp)
movl -0x3dc(%rbp), %eax
movl %eax, %esi
leaq -0x2e8(%rbp), %rdi
callq 0xa230
movq %rax, %rdi
addq $0x30, %rdi
callq 0xa390
movq %rax, %rcx
movq -0x580(%rbp), %rax
cmpq %rcx, %rax
jae 0x5f17
movl -0x3dc(%rbp), %eax
movl %eax, %esi
leaq -0x2e8(%rbp), %rdi
callq 0xa230
addq $0x30, %rax
movq %rax, -0x588(%rbp)
movl -0x3dc(%rbp), %eax
movl %eax, %esi
leaq -0x3b8(%rbp), %rdi
callq 0x9c50
movq -0x588(%rbp), %rdi
movq (%rax), %rsi
callq 0x9c50
movq (%rax), %rax
movq -0x240(%rbp), %rcx
movl -0x3c8(%rbp), %edx
cmpq (%rcx,%rdx,8), %rax
jb 0x5f17
movl -0x3dc(%rbp), %eax
movl %eax, %esi
leaq -0x2e8(%rbp), %rdi
callq 0xa230
addq $0x30, %rax
movq %rax, -0x5a0(%rbp)
movl -0x3dc(%rbp), %eax
movl %eax, %esi
leaq -0x3b8(%rbp), %rdi
callq 0x9c50
movq -0x5a0(%rbp), %rdi
movq (%rax), %rsi
callq 0x9c50
movq (%rax), %rax
movq %rax, -0x590(%rbp)
movq -0x3d8(%rbp), %rsi
leaq -0x2e8(%rbp), %rdi
callq 0xa230
addq $0x30, %rax
movq %rax, -0x598(%rbp)
movq -0x3d8(%rbp), %rsi
leaq -0x3b8(%rbp), %rdi
callq 0x9c50
movq -0x598(%rbp), %rdi
movq (%rax), %rsi
callq 0x9c50
movq %rax, %rcx
movq -0x590(%rbp), %rax
cmpq (%rcx), %rax
jb 0x5f0a
movq -0x3d8(%rbp), %rsi
leaq -0x2e8(%rbp), %rdi
callq 0xa230
addq $0x30, %rax
movq %rax, -0x5a8(%rbp)
movq -0x3d8(%rbp), %rsi
leaq -0x3b8(%rbp), %rdi
callq 0x9c50
movq -0x5a8(%rbp), %rdi
movq (%rax), %rsi
callq 0x9c50
movq (%rax), %rax
movq -0x240(%rbp), %rcx
movl -0x3c8(%rbp), %edx
cmpq (%rcx,%rdx,8), %rax
jae 0x5f17
movl -0x3dc(%rbp), %eax
movq %rax, -0x3d8(%rbp)
jmp 0x5f19
movl -0x3dc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3dc(%rbp)
jmp 0x5d55
movq -0x3d8(%rbp), %rsi
leaq -0x3b8(%rbp), %rdi
callq 0x9c50
movq (%rax), %rax
movq %rax, -0x5b0(%rbp)
movq -0x3d8(%rbp), %rsi
leaq -0x2e8(%rbp), %rdi
callq 0xa230
movq %rax, %rdi
addq $0x30, %rdi
callq 0xa390
movq %rax, %rcx
movq -0x5b0(%rbp), %rax
cmpq %rcx, %rax
jb 0x5f7d
jmp 0x6239
movq -0x3d8(%rbp), %rsi
leaq -0x2e8(%rbp), %rdi
movq %rdi, -0x5d0(%rbp)
callq 0xa230
addq $0x30, %rax
movq %rax, -0x5e0(%rbp)
movq -0x3d8(%rbp), %rsi
leaq -0x3b8(%rbp), %rdi
movq %rdi, -0x5c8(%rbp)
callq 0x9c50
movq -0x5e0(%rbp), %rdi
movq (%rax), %rsi
callq 0x9c50
movq (%rax), %rax
movq %rax, -0x5d8(%rbp)
movl -0x3c8(%rbp), %eax
incl %eax
movl %eax, %esi
leaq -0x290(%rbp), %rdi
callq 0x9c50
movq -0x5d8(%rbp), %rcx
movq -0x5d0(%rbp), %rdi
movq %rcx, (%rax)
movq -0x3d8(%rbp), %rsi
callq 0xa230
movq -0x5c8(%rbp), %rdi
addq $0x48, %rax
movq %rax, -0x5c0(%rbp)
movq -0x3d8(%rbp), %rsi
callq 0x9c50
movq -0x5c0(%rbp), %rdi
movq (%rax), %rsi
callq 0xa3b0
movq %rax, -0x5b8(%rbp)
movl -0x3c8(%rbp), %eax
incl %eax
movl %eax, %esi
leaq -0x2b0(%rbp), %rdi
callq 0xa3b0
movq -0x5b8(%rbp), %rsi
movq %rax, %rdi
callq 0xa3d0
jmp 0x6063
movl -0x3c8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c8(%rbp)
movq -0x3d8(%rbp), %rsi
leaq -0x3b8(%rbp), %rdi
callq 0x9c50
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
movl $0x0, -0x3cc(%rbp)
movl $0x0, -0x3e0(%rbp)
movl -0x3e0(%rbp), %eax
movl -0x354(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jae 0x6234
jmp 0x60bc
movl -0x3e0(%rbp), %eax
movl %eax, %esi
leaq -0x3b8(%rbp), %rdi
callq 0x9c50
movq (%rax), %rax
movq %rax, -0x5f0(%rbp)
movl -0x3e0(%rbp), %eax
movl %eax, %esi
leaq -0x2e8(%rbp), %rdi
callq 0xa230
movq %rax, %rdi
addq $0x30, %rdi
callq 0xa390
movq -0x5f0(%rbp), %rcx
movq %rax, %rdx
xorl %eax, %eax
cmpq %rdx, %rcx
movb %al, -0x5e1(%rbp)
jae 0x6170
movl -0x3e0(%rbp), %eax
movl %eax, %esi
leaq -0x2e8(%rbp), %rdi
callq 0xa230
addq $0x30, %rax
movq %rax, -0x5f8(%rbp)
movl -0x3e0(%rbp), %eax
movl %eax, %esi
leaq -0x3b8(%rbp), %rdi
callq 0x9c50
movq -0x5f8(%rbp), %rdi
movq (%rax), %rsi
callq 0x9c50
movq (%rax), %rax
movq -0x240(%rbp), %rcx
movl -0x3c8(%rbp), %edx
cmpq (%rcx,%rdx,8), %rax
setb %al
movb %al, -0x5e1(%rbp)
movb -0x5e1(%rbp), %al
testb $0x1, %al
jne 0x617c
jmp 0x61c2
movl -0x3e0(%rbp), %eax
movl %eax, %esi
leaq -0x3b8(%rbp), %rdi
callq 0x9c50
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
jmp 0x60bc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0x3b8(%rbp), %rdi
callq 0xa640
jmp 0x63e9
movl -0x3e0(%rbp), %eax
movl %eax, %esi
leaq -0x3b8(%rbp), %rdi
callq 0x9c50
movq (%rax), %rax
movq %rax, -0x600(%rbp)
movl -0x3e0(%rbp), %eax
movl %eax, %esi
leaq -0x2e8(%rbp), %rdi
callq 0xa230
movq %rax, %rdi
addq $0x30, %rdi
callq 0xa390
movq %rax, %rcx
movq -0x600(%rbp), %rax
cmpq %rcx, %rax
jb 0x621e
movl -0x3cc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3cc(%rbp)
jmp 0x6220
movl -0x3e0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3e0(%rbp)
jmp 0x60a3
jmp 0x5d29
leaq -0x260(%rbp), %rdi
callq 0xa620
movq 0x20d84(%rip), %rdi     # 0x26fd0
movq 0x20d65(%rip), %rsi     # 0x26fb8
callq 0x32d0
jmp 0x625a
leaq -0x3b8(%rbp), %rdi
callq 0xa640
leaq -0x350(%rbp), %rdi
callq 0xa6a0
testb $0x1, -0x1e1(%rbp)
je 0x64ac
movq 0x20d4a(%rip), %rdi     # 0x26fd0
leaq 0x12efe(%rip), %rsi     # 0x1918b
callq 0x3290
movq %rax, -0x608(%rbp)
jmp 0x629b
movq -0x608(%rbp), %rdi
movq 0x20d0f(%rip), %rsi     # 0x26fb8
callq 0x32d0
jmp 0x62b0
movq -0x300(%rbp), %rdi
movzbl -0x248(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x8080
movq %rax, %rdi
callq 0x3830
movq -0x2f8(%rbp), %rdi
movzbl -0x1(%rbp), %eax
movl %eax, %esi
callq 0x8080
movq %rax, %rdi
callq 0x3830
leaq -0x3f8(%rbp), %rdi
callq 0xa0f0
movzbl -0x248(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
leaq -0x400(%rbp), %rdi
callq 0xa700
movl $0x0, -0x404(%rbp)
movl -0x404(%rbp), %eax
cmpl 0x20f82(%rip), %eax     # 0x272a8
jae 0x641d
leaq -0x400(%rbp), %rdi
callq 0xa820
movq %rax, -0x410(%rbp)
movq -0x10(%rbp), %rdi
callq 0xa850
movq %rax, -0x418(%rbp)
movq -0x18(%rbp), %rdi
callq 0xa880
movq %rax, -0x420(%rbp)
movq -0x2f8(%rbp), %rdi
callq 0xa880
movq %rax, -0x428(%rbp)
movq -0x300(%rbp), %rdi
callq 0xa880
movq %rax, -0x430(%rbp)
movq %rsp, %rax
leaq -0x430(%rbp), %rcx
movq %rcx, 0x10(%rax)
leaq -0x428(%rbp), %rcx
movq %rcx, 0x8(%rax)
leaq -0x420(%rbp), %rcx
movq %rcx, (%rax)
leaq -0x189f(%rip), %rsi     # 0x4b10
leaq -0x3f8(%rbp), %rdi
leaq -0x410(%rbp), %rdx
leaq -0x1(%rbp), %rcx
leaq -0x8(%rbp), %r8
leaq -0x418(%rbp), %r9
callq 0xa730
jmp 0x63d3
jmp 0x63d5
movl -0x404(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x404(%rbp)
jmp 0x631a
leaq -0x350(%rbp), %rdi
callq 0xa6a0
jmp 0x6556
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa0(%rbp)
movl %eax, -0xa4(%rbp)
leaq -0x3f8(%rbp), %rdi
callq 0xa6a0
jmp 0x6556
leaq -0x3f8(%rbp), %rax
movq %rax, -0x438(%rbp)
movq -0x438(%rbp), %rdi
callq 0xa2b0
movq %rax, -0x440(%rbp)
movq -0x438(%rbp), %rdi
callq 0xa2e0
movq %rax, -0x448(%rbp)
leaq -0x440(%rbp), %rdi
leaq -0x448(%rbp), %rsi
callq 0xa310
testb $0x1, %al
jne 0x646a
jmp 0x649b
leaq -0x440(%rbp), %rdi
callq 0xa350
movq %rax, -0x450(%rbp)
movq -0x450(%rbp), %rdi
callq 0x3460
jmp 0x648b
jmp 0x648d
leaq -0x440(%rbp), %rdi
callq 0xa370
jmp 0x6451
leaq -0x3f8(%rbp), %rdi
callq 0xa6a0
jmp 0x6539
movq -0x300(%rbp), %rdi
movzbl -0x248(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x8080
movq %rax, %rdi
callq 0x3830
movq -0x2f8(%rbp), %rdi
movzbl -0x1(%rbp), %eax
movl %eax, %esi
callq 0x8080
movq %rax, %rdi
callq 0x3830
movzbl -0x248(%rbp), %eax
addl $0x1, %eax
movb %al, -0x451(%rbp)
movzbl -0x451(%rbp), %eax
movzbl -0x1(%rbp), %ecx
cmpl %ecx, %eax
jg 0x6537
movq -0x2f8(%rbp), %rdi
movzbl -0x451(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x8080
movq %rax, %rdi
callq 0x3830
movb -0x451(%rbp), %al
addb $0x1, %al
movb %al, -0x451(%rbp)
jmp 0x64f7
jmp 0x6539
leaq -0x330(%rbp), %rdi
callq 0xa8b0
leaq -0x318(%rbp), %rdi
callq 0xa640
jmp 0x576d
leaq -0x330(%rbp), %rdi
callq 0xa8b0
leaq -0x318(%rbp), %rdi
callq 0xa640
jmp 0x6670
movzbl -0x248(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movslq %edx, %rsi
leaq -0x38(%rbp), %rdi
callq 0x8080
movq %rax, %rdi
movq -0x20(%rbp), %rsi
callq 0x38d0
movzbl -0x248(%rbp), %eax
subl $0x1, %eax
movl $0x2, %ecx
cltd
idivl %ecx
movslq %edx, %rsi
leaq -0x38(%rbp), %rdi
callq 0x8080
movq %rax, %rdi
callq 0x3830
leaq -0x2e8(%rbp), %rdi
callq 0xa910
leaq -0x2b0(%rbp), %rdi
callq 0xa8b0
leaq -0x290(%rbp), %rdi
callq 0xa640
leaq -0x278(%rbp), %rdi
callq 0xa970
leaq -0x1e0(%rbp), %rdi
callq 0xa9c0
leaq -0x1a0(%rbp), %rdi
callq 0x3170
leaq -0x158(%rbp), %rdi
callq 0x7e90
leaq -0xe0(%rbp), %rax
movq %rax, -0x618(%rbp)
addq $0x30, %rax
movq %rax, -0x610(%rbp)
movq -0x610(%rbp), %rdi
addq $-0x18, %rdi
movq %rdi, -0x620(%rbp)
callq 0x7e90
movq -0x618(%rbp), %rcx
movq -0x620(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x610(%rbp)
jne 0x662d
leaq -0x38(%rbp), %rdi
callq 0x7e90
addq $0x650, %rsp            # imm = 0x650
popq %rbp
retq
leaq -0x2e8(%rbp), %rdi
callq 0xa910
leaq -0x2b0(%rbp), %rdi
callq 0xa8b0
leaq -0x290(%rbp), %rdi
callq 0xa640
leaq -0x278(%rbp), %rdi
callq 0xa970
leaq -0x1e0(%rbp), %rdi
callq 0xa9c0
leaq -0x1a0(%rbp), %rdi
callq 0x3170
leaq -0x158(%rbp), %rdi
callq 0x7e90
leaq -0xe0(%rbp), %rax
movq %rax, -0x630(%rbp)
addq $0x30, %rax
movq %rax, -0x628(%rbp)
movq -0x628(%rbp), %rdi
addq $-0x18, %rdi
movq %rdi, -0x638(%rbp)
callq 0x7e90
movq -0x630(%rbp), %rcx
movq -0x638(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x628(%rbp)
jne 0x66dd
jmp 0x6710
leaq -0x38(%rbp), %rdi
callq 0x7e90
movq -0xa0(%rbp), %rdi
callq 0x3480
nopw %cs:(%rax,%rax)