// File: /workspace/github_cpp_makefile_star2_O3/JameyWoo[P]re2graph/algorithms.cpp
// Function: nfa2dfa(NFA, DFA&)
void nfa2dfa(NFA nfa, DFA &dfa) {
    /**
     * 思路: 
     * 先统一求出所有状态的闭包closure, 因为如果在线求解会导致总是重复计算. 
     * 可以以O(n)的代价求出所有状态的闭包.
     * 然后再进行复杂的子集构造算法
     */
    // ! 所有状态的闭包, 一次性算出, 避免重复计算
    vector<set<int>> closures = vector<set<int>>(nfa.state_cnt, set<int>());
    vector<bool> ext_start(nfa.state_cnt);
    for (int i = 0; i < nfa.state_cnt; ++i) {
        if (closures[i].size() == 0) {
            ext_start[i] = true;
            vector<bool> visted(nfa.state_cnt);
            visted[i] = true;
            get_closure(nfa, closures, i, visted);
            visted[i] = false;
        }
    }
    // * 如果闭包成环, 会出现一种闭包没有求完整的情况. 已用反向边遍历方法解决
    // 但有的状态的闭包一定是完整的. 就是环的开始部分, 所以还需要进行调整. 进行闭包的扩展, 进行边的反向扩展
    map<int, vector<int>> ext_closure_map;
    for (int i = 0; i < nfa.state_cnt; ++i) {
        for (auto m : nfa.jump[i]) {
            if (m.first == '~') {
                for (auto v : m.second) {
                    ext_closure_map[v].push_back(i);
                }
            }
        }
    }
    // cout << "ext_closure_map:" << endl;
    // for (auto m: ext_closure_map) {
    //     for (auto v: m.second) {
    //         cout << m.first << ' ' << v << endl;
    //     }
    // }
    for (int i = 0; i < nfa.state_cnt; ++i) {
        // if (ext_start[i]) { // 不需要判断, 如果环的入口不是起点这种情况会出错
            queue<int> inq;
            vector<int> visted(nfa.state_cnt);
            inq.push(i);
            visted[i] = true;
            while (not inq.empty()) {
                int now = inq.front();
                inq.pop();
                for (auto v : ext_closure_map[now]) {
                    if (visted[v] == false) {
                        closures[v].insert(closures[i].begin(), closures[i].end());
                        inq.push(v);
                        visted[v] = true;
                    }
                }
            // }
        }
    }

    // 查看闭包
    // cout << "closures: " << endl;
    // for (int i = 0; i < nfa.state_cnt; ++i) {
    //     cout << i << ": ";
    //     for (auto clo : closures[i]) {
    //         cout << clo << ' ';
    //     }
    //     cout << endl;
    // }

    // 进行接受状态的扩展, 因为后面可能会漏掉
    set<int> ext_end_states;
    for (auto x : nfa.end_states) {
        ext_end_states.insert(x);  // 先插入最基本的接受状态
    }
    int ic = 0;
    for (auto closure : closures) {
        ic++;
        for (auto x : closure) {
            if (ext_end_states.count(x)) {
                ext_end_states.insert(ic - 1);
                break;
            }
        }
    }
    // cout << "ext_end_states: ";
    // for (auto s : ext_end_states) {
    //     cout << s << ' ';
    // }
    // cout << endl;

    // ! 进行子集构造算法
    set<int> end_states;                                // dfa的终止状态
    if (ext_end_states.count(0)) end_states.insert(0);  // 因为先单独将起始状态0加入了工作列表, 所以对他的接收状态需要提前处理
    map<set<int>, int> set_hash;                        // 集合对整数的hash, 也就是对子集编码
    vector<map<char, int>> jump_dfa;                    // dfa的jump
    set<int> set_visted;                                // 保存一个set是否被访问过的信息
    int set_state                       = 0;            // 集合的整数状态
    set_hash[closures[nfa.start_state]] = set_state++;  // 初始状态编码为0
    // cout << "0: ";
    // for (auto s: closures[nfa.start_state]) {
    //     cout << s << ' ';
    // }
    // cout << endl;
    jump_dfa.push_back(map<char, int>());                     // 压入初始状态的map
    set_visted.insert(set_hash[closures[nfa.start_state]]);   // 标记访问过
                                                              // 初始化变量之后开始工作
    queue<set<int>> work_queue;                               // 队列
    work_queue.push(closures[nfa.start_state]);               // 将初始状态闭包集插入工作队列
    while (not work_queue.empty()) {                          // 当工作队列不为空
        set<int> now = work_queue.front();                    // 取出当前工作集合
        work_queue.pop();                                     // 弹出
        for (auto c : nfa.chars) {                            // 遍历每个字符
            if (c == '~') continue;                           // c 不能是~ 也就是ε, 它不可以接下一状态
            set<int> next_state_set;                          // 下一状态
            for (auto state : now) {                          // 遍历每个状态. 要获取当前集合所有状态对某字符的下一状态的闭包
                if (nfa.jump[state].count(c) != 0) {          // 当可以跳转的时候
                    for (auto v : nfa.jump[state][c]) {       // 一个状态对同一个字符可能有好几个下一状态
                        set<int> next_closure = closures[v];  // 求闭包
                        // 要获取所有可以走下去的状态的闭包, 都插入到集合中
                        next_state_set.insert(next_closure.begin(), next_closure.end());
                    }
                }
            }
            if (next_state_set.size() != 0) {                // 如果不是空, 说明是一个dfa状态
                if (set_hash.count(next_state_set) == 0) {   // 遇到新状态, 计次, 转化为dfa中的状态
                    set_hash[next_state_set] = set_state++;  // 新状态分配int型状态号
                    // cout << set_state - 1 << ": ";
                    // for (auto s: next_state_set) {
                    //     cout << s << ' ';
                    // }
                    // cout << endl;
                    for (auto s : next_state_set) {  // 查找当前集合是否存在nfa的接受状态, 如果存在, 那它也是dfa的终止状态
                        if (ext_end_states.count(s) != 0) {
                            end_states.insert(set_state - 1);  // 是终止状态
                            break;
                        }
                    }
                    jump_dfa.push_back(map<char, int>());  // 新状态的map, 用来存储dfa的转移函数
                }
                int set_hash_next_state    = set_hash[next_state_set];  // 一次得到hash值保存, 方便后面操作, 省的每次都查找set
                jump_dfa[set_hash[now]][c] = set_hash_next_state;       // 经过hash之后的dfa状态表示
                if (set_visted.count(set_hash_next_state) == 0) {       // 如果之前没访问过
                    set_visted.insert(set_hash_next_state);             // 插入set_visted中标记访问
                    work_queue.push(next_state_set);                    // 插入work_queu中, 由于set_visted的存在, 只会进一次work_queue
                }
            }
        }
    }

    // for (auto s: set_hash) {
    //     cout << s.second << ": ";
    //     for (auto v: s.first) {
    //         cout << ' ';
    //     }
    //     cout << endl;
    // }

    // 构造dfa, 按照DFA数据定义的顺序
    dfa.char_cnt      = nfa.char_cnt;
    dfa.state_cnt     = set_state;
    dfa.start_state   = 0;
    dfa.end_state_cnt = end_states.size();
    dfa.chars         = nfa.chars;
    for (int i = 0; i < dfa.state_cnt; ++i) {
        dfa.states.push_back(i);
    }
    for (auto s : end_states) {
        dfa.end_states.push_back(s);
    }
    dfa.jump_map = jump_dfa;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x2d8, %rsp            # imm = 0x2D8
movq %rsi, %r14
movq %rdi, %r15
movslq 0x4(%rdi), %rsi
leaq 0x28(%rsp), %rcx
xorl %eax, %eax
movq %rax, 0x8(%rcx)
xorps %xmm0, %xmm0
movaps %xmm0, -0x8(%rcx)
movq %rcx, 0x10(%rcx)
movq %rcx, 0x18(%rcx)
movq %rax, 0x20(%rcx)
leaq 0xa8(%rsp), %rdi
leaq 0x20(%rsp), %rdx
leaq 0x238(%rsp), %rcx
callq 0xd604
leaq 0x20(%rsp), %rbx
movq %rbx, %rdi
callq 0xe2d8
movslq 0x4(%r15), %rsi
movb $0x0, (%rbx)
leaq 0x210(%rsp), %rdi
leaq 0x20(%rsp), %rdx
leaq 0x238(%rsp), %rcx
callq 0xf6cc
movq %r14, 0x1a0(%rsp)
movq %r15, 0x10(%rsp)
movl 0x4(%r15), %eax
testl %eax, %eax
jle 0x6399
movl $0x28, %r14d
xorl %r15d, %r15d
leaq 0x20(%rsp), %r12
leaq 0x268(%rsp), %rbx
movq 0xa8(%rsp), %rcx
cmpq $0x0, (%rcx,%r14)
jne 0x6386
movq 0x210(%rsp), %rdx
movl %r15d, %ebp
movl $0x1, %r13d
movl %r15d, %ecx
shlq %cl, %r13
shrl $0x6, %ebp
orq %r13, (%rdx,%rbp,8)
movslq %eax, %rsi
movb $0x0, 0x238(%rsp)
movq %r12, %rdi
leaq 0x238(%rsp), %rdx
leaq 0x70(%rsp), %rcx
callq 0xf6cc
movq 0x20(%rsp), %rax
orq %r13, (%rax,%rbp,8)
movq %rbx, %rdi
movq 0x10(%rsp), %rsi
callq 0x3a10
movq %rbx, %rdi
leaq 0xa8(%rsp), %rsi
movl %r15d, %edx
movq %r12, %rcx
callq 0x7112
leaq 0x2c0(%rsp), %rdi
callq 0x410c
movq 0x2a8(%rsp), %rdi
testq %rdi, %rdi
je 0x632b
movq 0x2b8(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
movq 0x290(%rsp), %rdi
testq %rdi, %rdi
je 0x6348
movq 0x2a0(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
movq 0x278(%rsp), %rdi
testq %rdi, %rdi
je 0x6365
movq 0x288(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
movq 0x20(%rsp), %rdi
notq %r13
andq %r13, (%rdi,%rbp,8)
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
movq 0x10(%rsp), %rax
movl 0x4(%rax), %eax
incq %r15
movslq %eax, %rcx
addq $0x30, %r14
cmpq %rcx, %r15
jl 0x6284
leaq 0x240(%rsp), %rdx
xorl %ecx, %ecx
movl %ecx, (%rdx)
movq %rcx, 0x8(%rdx)
movq %rdx, 0x10(%rdx)
movq %rdx, 0x18(%rdx)
movq %rcx, 0x20(%rdx)
movl %ecx, 0x70(%rsp)
testl %eax, %eax
jle 0x66e8
leaq 0x238(%rsp), %r15
leaq 0xc0(%rsp), %r12
leaq 0x70(%rsp), %r13
movq 0x10(%rsp), %rdi
movslq %ecx, %rdx
movq 0x58(%rdi), %rsi
leaq (%rdx,%rdx,2), %rdx
shlq $0x4, %rdx
addq %rsi, %rdx
addq $0x8, %rdx
movq 0x10(%rdx), %rbp
movq %rdx, 0xa0(%rsp)
cmpq %rdx, %rbp
je 0x64b2
movb 0x20(%rbp), %al
movb %al, 0x20(%rsp)
leaq 0x28(%rbp), %rsi
leaq 0x28(%rsp), %rdi
callq 0x3c64
cmpb $0x7e, 0x20(%rsp)
movq 0x28(%rsp), %rbx
jne 0x6478
movq 0x30(%rsp), %r14
cmpq %r14, %rbx
je 0x6478
movl (%rbx), %eax
movl %eax, 0xc0(%rsp)
movq %r15, %rdi
movq %r12, %rsi
callq 0xd69e
movq 0x8(%rax), %rsi
cmpq 0x10(%rax), %rsi
je 0x645f
movl 0x70(%rsp), %ecx
movl %ecx, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x8(%rax)
jmp 0x646a
movq %rax, %rdi
movq %r13, %rdx
callq 0xef76
addq $0x4, %rbx
cmpq %r14, %rbx
jne 0x6431
movq 0x28(%rsp), %rbx
testq %rbx, %rbx
je 0x648d
movq 0x38(%rsp), %rsi
subq %rbx, %rsi
movq %rbx, %rdi
callq 0x2200
movq %rbp, %rdi
callq 0x2160
movq %rax, %rbp
cmpq 0xa0(%rsp), %rax
movq 0x10(%rsp), %rdi
jne 0x6406
movl 0x70(%rsp), %ecx
movl 0x4(%rdi), %eax
incl %ecx
movl %ecx, 0x70(%rsp)
cmpl %eax, %ecx
jl 0x63db
movl $0x0, 0xc0(%rsp)
testl %eax, %eax
jle 0x66e8
leaq 0x20(%rsp), %rbx
leaq 0x1e0(%rsp), %r12
leaq 0x238(%rsp), %rbp
leaq 0x1b0(%rsp), %r13
xorps %xmm0, %xmm0
movaps %xmm0, 0x60(%rsp)
movaps %xmm0, 0x50(%rsp)
movaps %xmm0, 0x40(%rsp)
movaps %xmm0, 0x30(%rsp)
movaps %xmm0, 0x20(%rsp)
movq %rbx, %rdi
xorl %esi, %esi
callq 0xfa0c
movq 0x10(%rsp), %rax
movslq 0x4(%rax), %rsi
leaq 0x70(%rsp), %rdi
movq %r12, %rdx
callq 0xd704
movq 0x50(%rsp), %rcx
movq 0x60(%rsp), %rax
addq $-0x4, %rax
cmpq %rax, %rcx
je 0x6553
movl 0xc0(%rsp), %eax
movl %eax, (%rcx)
addq $0x4, %rcx
movq %rcx, 0x50(%rsp)
jmp 0x656f
movq %rbx, %rdi
leaq 0xc0(%rsp), %rsi
callq 0xfb82
movl 0xc0(%rsp), %eax
movq 0x50(%rsp), %rcx
cltq
movq 0x70(%rsp), %rdi
movl $0x1, (%rdi,%rax,4)
movq 0x30(%rsp), %rax
cmpq %rax, %rcx
je 0x66b2
movl (%rax), %ecx
movl %ecx, 0x1e0(%rsp)
movq 0x40(%rsp), %rcx
addq $-0x4, %rcx
cmpq %rcx, %rax
je 0x65a8
addq $0x4, %rax
jmp 0x65da
movq 0x38(%rsp), %rdi
movl $0x200, %esi            # imm = 0x200
callq 0x2200
movq 0x48(%rsp), %rax
leaq 0x8(%rax), %rcx
movq %rcx, 0x48(%rsp)
movq 0x8(%rax), %rax
movq %rax, 0x38(%rsp)
leaq 0x200(%rax), %rcx
movq %rcx, 0x40(%rsp)
movq %rax, 0x30(%rsp)
movq %rbp, %rdi
movq %r12, %rsi
callq 0xd69e
movq (%rax), %r14
movq 0x8(%rax), %r15
cmpq %r15, %r14
je 0x6698
movq 0x70(%rsp), %rax
movslq (%r14), %rcx
movl %ecx, 0x1b0(%rsp)
cmpl $0x0, (%rax,%rcx,4)
jne 0x668b
movq 0xa8(%rsp), %rax
leaq (%rcx,%rcx,2), %rdi
shlq $0x4, %rdi
addq %rax, %rdi
movslq 0xc0(%rsp), %rcx
leaq (%rcx,%rcx,2), %rcx
shlq $0x4, %rcx
leaq (%rax,%rcx), %rdx
addq $0x8, %rdx
movq 0x10(%rdx), %rsi
callq 0xfd96
movq 0x50(%rsp), %rax
movq 0x60(%rsp), %rcx
addq $-0x4, %rcx
cmpq %rcx, %rax
je 0x666a
movl 0x1b0(%rsp), %ecx
movl %ecx, (%rax)
addq $0x4, %rax
movq %rax, 0x50(%rsp)
jmp 0x667c
movq %rbx, %rdi
movq %r13, %rsi
callq 0xfb82
movl 0x1b0(%rsp), %ecx
movslq %ecx, %rcx
movq 0x70(%rsp), %rax
movl $0x1, (%rax,%rcx,4)
addq $0x4, %r14
cmpq %r15, %r14
jne 0x65ff
movq 0x30(%rsp), %rax
cmpq %rax, 0x50(%rsp)
jne 0x658b
movq 0x70(%rsp), %rdi
testq %rdi, %rdi
je 0x66c2
movq 0x80(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
movq %rbx, %rdi
callq 0xe328
movl 0xc0(%rsp), %eax
incl %eax
movl %eax, 0xc0(%rsp)
movq 0x10(%rsp), %rcx
cmpl 0x4(%rcx), %eax
jl 0x64f0
leaq 0x78(%rsp), %rcx
movl $0x0, (%rcx)
xorl %eax, %eax
movq %rax, 0x8(%rcx)
movq %rcx, 0x10(%rcx)
movq %rcx, 0x18(%rcx)
movq %rax, 0x20(%rcx)
movq 0x10(%rsp), %rax
movq 0x40(%rax), %r14
movq 0x48(%rax), %r12
cmpq %r12, %r14
je 0x673c
leaq 0x70(%rsp), %rbx
leaq 0x20(%rsp), %r15
movl (%r14), %eax
movl %eax, 0x20(%rsp)
movq %rbx, %rdi
movq %r15, %rsi
callq 0xffb0
addq $0x4, %r14
cmpq %r12, %r14
jne 0x6721
movq 0xa8(%rsp), %rbx
movq 0xb0(%rsp), %r14
cmpq %r14, %rbx
je 0x680e
xorl %ebp, %ebp
leaq 0x20(%rsp), %r15
leaq 0xc0(%rsp), %r13
movq %r15, %rdi
movq %rbx, %rsi
callq 0xe380
movq 0x38(%rsp), %rax
leaq 0x28(%rsp), %rcx
cmpq %rcx, %rax
je 0x67f7
movq 0x80(%rsp), %r12
testq %r12, %r12
je 0x67cf
movl 0x20(%rax), %ecx
movq %r12, %r9
leaq 0x78(%rsp), %r8
movq %r8, %rdx
movq %r9, %rsi
movl 0x20(%r9), %edi
xorl %r9d, %r9d
cmpl %ecx, %edi
setl %r9b
movq %rsi, %r8
cmovlq %rdx, %r8
movq 0x10(%rsi,%r9,8), %r9
testq %r9, %r9
jne 0x6796
leaq 0x78(%rsp), %r9
cmpq %r9, %r8
je 0x67cf
cmpl %ecx, %edi
cmovlq %rdx, %rsi
cmpl 0x20(%rsi), %ecx
jge 0x67e3
movq %rax, %rdi
callq 0x2250
leaq 0x28(%rsp), %rcx
cmpq %rcx, %rax
jne 0x6786
jmp 0x67f7
movl %ebp, 0xc0(%rsp)
leaq 0x70(%rsp), %rdi
movq %r13, %rsi
callq 0xffe6
incl %ebp
movq %r15, %rdi
callq 0xe2d8
addq $0x30, %rbx
cmpq %r14, %rbx
jne 0x6764
leaq 0xc8(%rsp), %rax
movl $0x0, (%rax)
xorl %ebx, %ebx
movq %rbx, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
movq %rbx, 0x20(%rax)
movq 0x80(%rsp), %rsi
testq %rsi, %rsi
je 0x688f
leaq 0x78(%rsp), %rdi
movq %rdi, %rax
movq %rsi, %rcx
movl 0x20(%rsi), %edx
testl %edx, %edx
movq %rsi, %rdi
cmovsq %rax, %rdi
movl %edx, %esi
shrl $0x1f, %esi
movq 0x10(%rcx,%rsi,8), %rsi
testq %rsi, %rsi
jne 0x6840
leaq 0x78(%rsp), %rsi
cmpq %rsi, %rdi
je 0x688f
testl %edx, %edx
cmovsq %rax, %rcx
cmpl $0x0, 0x20(%rcx)
jg 0x688f
leaq 0x20(%rsp), %rsi
movl $0x0, (%rsi)
leaq 0xc0(%rsp), %rdi
callq 0xffe6
leaq 0x1e8(%rsp), %rax
movl %ebx, (%rax)
movq %rbx, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
movq %rbx, 0x20(%rax)
movq %rbx, 0x100(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0xf0(%rsp)
leaq 0x1b8(%rsp), %rax
movl %ebx, (%rax)
movq %rbx, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
movq %rbx, 0x20(%rax)
movq 0x10(%rsp), %rbx
movslq 0x8(%rbx), %rax
leaq (%rax,%rax,2), %rsi
shlq $0x4, %rsi
addq 0xa8(%rsp), %rsi
leaq 0x1e0(%rsp), %rdi
callq 0xd790
movl $0x0, (%rax)
xorl %eax, %eax
leaq 0x20(%rsp), %rsi
movq %rax, 0x10(%rsi)
xorps %xmm0, %xmm0
movaps %xmm0, (%rsi)
leaq 0x28(%rsp), %rcx
movq %rcx, 0x18(%rsi)
movq %rcx, 0x20(%rsi)
movq %rax, 0x28(%rsi)
leaq 0xf0(%rsp), %rdi
callq 0x104a0
leaq 0x20(%rsp), %rdi
callq 0x4470
movslq 0x8(%rbx), %rax
leaq (%rax,%rax,2), %rsi
shlq $0x4, %rsi
addq 0xa8(%rsp), %rsi
leaq 0x1e0(%rsp), %rdi
callq 0xd790
leaq 0x1b0(%rsp), %rdi
movq %rax, %rsi
callq 0xffb0
xorps %xmm0, %xmm0
leaq 0x20(%rsp), %rdi
movaps %xmm0, 0x40(%rdi)
movaps %xmm0, 0x30(%rdi)
movaps %xmm0, 0x20(%rdi)
movaps %xmm0, 0x10(%rdi)
movaps %xmm0, (%rdi)
xorl %esi, %esi
callq 0x1069e
movslq 0x8(%rbx), %rax
leaq (%rax,%rax,2), %rsi
shlq $0x4, %rsi
addq 0xa8(%rsp), %rsi
leaq 0x20(%rsp), %rdi
callq 0x1083c
movq 0x30(%rsp), %rsi
cmpq %rsi, 0x50(%rsp)
je 0x6d71
leaq 0x148(%rsp), %r14
leaq 0x118(%rsp), %r15
movl $0x1, 0x1c(%rsp)
leaq 0x170(%rsp), %rdi
leaq 0x140(%rsp), %rbp
leaq 0x110(%rsp), %r13
callq 0xe380
leaq 0x20(%rsp), %rdi
callq 0x10ac6
movq 0x10(%rbx), %rax
movq 0x18(%rbx), %rcx
movq %rcx, 0x1a8(%rsp)
cmpq %rcx, %rax
je 0x6d4c
movq %rax, 0xa0(%rsp)
movb (%rax), %al
movb %al, 0xf(%rsp)
cmpb $0x7e, %al
je 0x6d33
movl $0x0, 0x148(%rsp)
xorl %eax, %eax
movq %rax, 0x150(%rsp)
movq %r14, 0x158(%rsp)
movq %r14, 0x160(%rsp)
movq %rax, 0x168(%rsp)
movq 0x188(%rsp), %rbx
leaq 0x178(%rsp), %rax
cmpq %rax, %rbx
je 0x6bf0
movslq 0x20(%rbx), %rax
movq 0x10(%rsp), %rcx
movq 0x58(%rcx), %rcx
leaq (%rax,%rax,2), %rdx
shlq $0x4, %rdx
movq 0x10(%rcx,%rdx), %rax
testq %rax, %rax
je 0x6ac4
leaq (%rcx,%rdx), %rdi
leaq (%rcx,%rdx), %rsi
addq $0x8, %rsi
movb 0xf(%rsp), %cl
movq %rsi, %rdx
xorl %r8d, %r8d
cmpb %cl, 0x20(%rax)
setl %r8b
cmovgeq %rax, %rdx
movq 0x10(%rax,%r8,8), %rax
testq %rax, %rax
jne 0x6aa2
cmpq %rsi, %rdx
je 0x6ac4
cmpb 0x20(%rdx), %cl
jge 0x6ade
movq %rbx, %rdi
callq 0x2250
movq %rax, %rbx
leaq 0x178(%rsp), %rax
cmpq %rax, %rbx
jne 0x6a70
jmp 0x6b31
leaq 0xf(%rsp), %rsi
callq 0xd41c
movq (%rax), %r12
movq 0x8(%rax), %r14
cmpq %r14, %r12
je 0x6ac4
movslq (%r12), %rax
leaq (%rax,%rax,2), %rsi
shlq $0x4, %rsi
addq 0xa8(%rsp), %rsi
movq %r13, %rdi
callq 0xe380
movq 0x128(%rsp), %rsi
movq %rbp, %rdi
movq %r15, %rdx
callq 0xfd96
movq %r13, %rdi
callq 0xe2d8
addq $0x4, %r12
jmp 0x6aef
cmpq $0x0, 0x168(%rsp)
je 0x6bf0
leaq 0x1e0(%rsp), %rdi
movq %rbp, %rsi
callq 0x10b30
leaq 0x148(%rsp), %r14
leaq 0x1e8(%rsp), %rcx
cmpq %rcx, %rax
jne 0x6c66
leaq 0x1e0(%rsp), %rdi
movq %rbp, %rsi
callq 0xd790
movl 0x1c(%rsp), %ecx
movl %ecx, (%rax)
movq 0x158(%rsp), %rax
cmpq %r14, %rax
je 0x6c1d
movq 0x80(%rsp), %rbx
testq %rbx, %rbx
je 0x6be1
movl 0x20(%rax), %ecx
movq %rbx, %r9
leaq 0x78(%rsp), %r8
movq %r8, %rdx
movq %r9, %rsi
movl 0x20(%r9), %edi
xorl %r9d, %r9d
cmpl %ecx, %edi
setl %r9b
movq %rsi, %r8
cmovlq %rdx, %r8
movq 0x10(%rsi,%r9,8), %r9
testq %r9, %r9
jne 0x6ba8
leaq 0x78(%rsp), %r9
cmpq %r9, %r8
je 0x6be1
cmpl %ecx, %edi
cmovlq %rdx, %rsi
cmpl 0x20(%rsi), %ecx
jge 0x6c02
movq %rax, %rdi
callq 0x2250
cmpq %r14, %rax
jne 0x6b98
jmp 0x6c1d
movq 0x10(%rsp), %rbx
leaq 0x148(%rsp), %r14
jmp 0x6d2b
movl 0x1c(%rsp), %eax
movl %eax, 0x110(%rsp)
leaq 0xc0(%rsp), %rdi
movq %r13, %rsi
callq 0xffe6
xorps %xmm0, %xmm0
movaps %xmm0, 0x110(%rsp)
xorl %eax, %eax
movq %rax, 0x120(%rsp)
movq %r15, 0x128(%rsp)
movq %r15, 0x130(%rsp)
movq %rax, 0x138(%rsp)
leaq 0xf0(%rsp), %rdi
movq %r13, %rsi
callq 0x104a0
incl 0x1c(%rsp)
movq %r13, %rdi
callq 0x4470
leaq 0x1e0(%rsp), %rdi
movq %rbp, %rsi
callq 0xd790
movl (%rax), %ebx
movl %ebx, 0x110(%rsp)
leaq 0x1e0(%rsp), %rdi
leaq 0x170(%rsp), %rsi
callq 0xd790
movslq (%rax), %rax
leaq (%rax,%rax,2), %rdi
shlq $0x4, %rdi
addq 0xf0(%rsp), %rdi
leaq 0xf(%rsp), %rsi
callq 0xd800
movl %ebx, (%rax)
movq 0x1c0(%rsp), %rdi
testq %rdi, %rdi
je 0x6d09
movl 0x110(%rsp), %eax
leaq 0x1b8(%rsp), %r8
movq %r8, %rcx
movq %rdi, %rdx
movl 0x20(%rdi), %esi
xorl %edi, %edi
cmpl %eax, %esi
setl %dil
movq %rdx, %r8
cmovlq %rcx, %r8
movq 0x10(%rdx,%rdi,8), %rdi
testq %rdi, %rdi
jne 0x6ccf
leaq 0x1b8(%rsp), %rdi
cmpq %rdi, %r8
je 0x6d09
cmpl %eax, %esi
cmovlq %rcx, %rdx
cmpl 0x20(%rdx), %eax
jge 0x6d26
leaq 0x1b0(%rsp), %rdi
movq %r13, %rsi
callq 0xffb0
leaq 0x20(%rsp), %rdi
movq %rbp, %rsi
callq 0x1083c
movq 0x10(%rsp), %rbx
movq %rbp, %rdi
callq 0xe2d8
movq 0xa0(%rsp), %rax
incq %rax
cmpq 0x1a8(%rsp), %rax
jne 0x6a14
leaq 0x170(%rsp), %r12
movq %r12, %rdi
callq 0xe2d8
movq %r12, %rdi
movq 0x30(%rsp), %rsi
cmpq %rsi, 0x50(%rsp)
jne 0x69ec
jmp 0x6d79
movl $0x1, 0x1c(%rsp)
movl (%rbx), %eax
movq 0x1a0(%rsp), %r12
movl %eax, (%r12)
movl 0x1c(%rsp), %eax
movl %eax, 0x4(%r12)
movl $0x0, 0x8(%r12)
movl 0xe8(%rsp), %eax
movl %eax, 0xc(%r12)
addq $0x10, %rbx
leaq 0x10(%r12), %rdi
movq %rbx, %rsi
callq 0xd866
movl $0x0, 0x170(%rsp)
cmpl $0x0, 0x4(%r12)
jle 0x6e13
leaq 0x28(%r12), %rbx
xorl %eax, %eax
leaq 0x170(%rsp), %r14
movq 0x30(%r12), %rsi
cmpq 0x38(%r12), %rsi
je 0x6df1
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x30(%r12)
jmp 0x6dfc
movq %rbx, %rdi
movq %r14, %rdx
callq 0xef76
movl 0x170(%rsp), %eax
incl %eax
movl %eax, 0x170(%rsp)
cmpl 0x4(%r12), %eax
jl 0x6dd8
movq 0xd8(%rsp), %rbx
leaq 0xc8(%rsp), %rax
cmpq %rax, %rbx
je 0x6e7b
leaq 0x40(%r12), %r14
leaq 0x170(%rsp), %r15
movl 0x20(%rbx), %eax
movl %eax, 0x170(%rsp)
movq 0x48(%r12), %rsi
cmpq 0x50(%r12), %rsi
je 0x6e58
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x48(%r12)
jmp 0x6e63
movq %r14, %rdi
movq %r15, %rdx
callq 0xef76
movq %rbx, %rdi
callq 0x2250
movq %rax, %rbx
leaq 0xc8(%rsp), %rax
cmpq %rax, %rbx
jne 0x6e35
addq $0x58, %r12
leaq 0xf0(%rsp), %rsi
movq %r12, %rdi
callq 0xd92a
leaq 0x20(%rsp), %rdi
callq 0xe518
leaq 0x1b0(%rsp), %rdi
callq 0xe2d8
leaq 0xf0(%rsp), %rdi
callq 0x4484
leaq 0x1e0(%rsp), %rdi
callq 0xe660
leaq 0xc0(%rsp), %rdi
callq 0xe2d8
leaq 0x70(%rsp), %rdi
callq 0xe2d8
leaq 0x238(%rsp), %rdi
callq 0xe6b8
movq 0x210(%rsp), %rdi
testq %rdi, %rdi
je 0x6f01
movq 0x230(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
leaq 0xa8(%rsp), %rdi
callq 0xdaac
addq $0x2d8, %rsp            # imm = 0x2D8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
jmp 0x709f
jmp 0x6f58
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x4470
jmp 0x7078
movq %rax, %rbx
jmp 0x70fd
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0xe2d8
jmp 0x710a
jmp 0x6fbf
movq %rax, %rbx
jmp 0x7078
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
jmp 0x70a7
jmp 0x6ff3
jmp 0x7051
jmp 0x6fbf
jmp 0x6fbf
movq %rax, %rbx
jmp 0x6f98
movq %rax, %rbx
jmp 0x70c3
movq %rax, %rbx
leaq 0x268(%rsp), %rdi
callq 0x3ac4
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
je 0x70c3
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
jmp 0x70c3
jmp 0x6fe9
movq %rax, %rbx
jmp 0x7010
movq %rax, %rbx
jmp 0x706e
jmp 0x6fc9
movq %rax, %rbx
jmp 0x70ac
movq %rax, %rbx
leaq 0x110(%rsp), %rdi
callq 0x4470
jmp 0x7054
jmp 0x7051
jmp 0x6ff3
jmp 0x7051
movq %rax, %rbx
jmp 0x70b6
jmp 0x7051
movq %rax, %rbx
movq 0x70(%rsp), %rdi
testq %rdi, %rdi
je 0x7010
movq 0x80(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
leaq 0x20(%rsp), %rdi
callq 0xe328
jmp 0x70b6
movq %rax, %rbx
movq 0x28(%rsp), %rdi
testq %rdi, %rdi
je 0x70b6
movq 0x38(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
jmp 0x70b6
movq %rax, %rbx
leaq 0x110(%rsp), %rdi
callq 0xe2d8
jmp 0x7054
movq %rax, %rbx
leaq 0x140(%rsp), %rdi
callq 0xe2d8
leaq 0x170(%rsp), %rdi
callq 0xe2d8
leaq 0x20(%rsp), %rdi
callq 0xe518
leaq 0x1b0(%rsp), %rdi
callq 0xe2d8
leaq 0xf0(%rsp), %rdi
callq 0x4484
leaq 0x1e0(%rsp), %rdi
callq 0xe660
leaq 0xc0(%rsp), %rdi
callq 0xe2d8
leaq 0x70(%rsp), %rdi
callq 0xe2d8
leaq 0x238(%rsp), %rdi
callq 0xe6b8
movq 0x210(%rsp), %rdi
testq %rdi, %rdi
je 0x70fd
movq 0x230(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
xorl %eax, %eax
movq %rax, 0x210(%rsp)
movl $0x0, 0x218(%rsp)
movq %rax, 0x220(%rsp)
leaq 0xa8(%rsp), %rdi
callq 0xdaac
movq %rbx, %rdi
callq 0x2350