// File: 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
movq %rsp, %rbp
subq $0x840, %rsp            # imm = 0x840
movq %rdi, -0x6a0(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movslq 0x4(%rdi), %rax
movq %rax, -0x698(%rbp)
xorps %xmm0, %xmm0
movaps %xmm0, -0x40(%rbp)
movaps %xmm0, -0x50(%rbp)
movaps %xmm0, -0x60(%rbp)
leaq -0x60(%rbp), %rdi
movq %rdi, -0x690(%rbp)
callq 0x125a0
leaq -0x61(%rbp), %rdi
movq %rdi, -0x688(%rbp)
callq 0x125c0
movq -0x698(%rbp), %rsi
movq -0x690(%rbp), %rdx
movq -0x688(%rbp), %rcx
leaq -0x28(%rbp), %rdi
callq 0x125e0
jmp 0xad24
leaq -0x61(%rbp), %rdi
callq 0x12660
leaq -0x60(%rbp), %rdi
callq 0x12680
movq -0x6a0(%rbp), %rax
movslq 0x4(%rax), %rax
movq %rax, -0x6b0(%rbp)
leaq -0xa1(%rbp), %rdi
movq %rdi, -0x6a8(%rbp)
callq 0x126a0
movq -0x6b0(%rbp), %rsi
movq -0x6a8(%rbp), %rdx
leaq -0xa0(%rbp), %rdi
callq 0x126c0
jmp 0xad77
leaq -0xa1(%rbp), %rdi
callq 0x12700
movl $0x0, -0xa8(%rbp)
movq -0x6a0(%rbp), %rcx
movl -0xa8(%rbp), %eax
cmpl 0x4(%rcx), %eax
jge 0xb00b
movslq -0xa8(%rbp), %rsi
leaq -0x28(%rbp), %rdi
callq 0x12720
movq %rax, %rdi
callq 0x12740
cmpq $0x0, %rax
jne 0xaff5
movslq -0xa8(%rbp), %rsi
leaq -0xa0(%rbp), %rdi
callq 0x12760
movq %rdx, -0x6c0(%rbp)
movq %rax, -0x6b8(%rbp)
jmp 0xade8
movq -0x6c0(%rbp), %rax
movq -0x6b8(%rbp), %rcx
movq %rcx, -0xb8(%rbp)
movq %rax, -0xb0(%rbp)
leaq -0xb8(%rbp), %rdi
movl $0x1, %esi
callq 0x127c0
movq -0x6a0(%rbp), %rax
movslq 0x4(%rax), %rax
movq %rax, -0x6d0(%rbp)
leaq -0xe1(%rbp), %rdi
movq %rdi, -0x6c8(%rbp)
callq 0x126a0
movq -0x6d0(%rbp), %rsi
movq -0x6c8(%rbp), %rdx
leaq -0xe0(%rbp), %rdi
callq 0x126c0
jmp 0xae56
leaq -0xe1(%rbp), %rdi
callq 0x12700
movslq -0xa8(%rbp), %rsi
leaq -0xe0(%rbp), %rdi
callq 0x12760
movq %rdx, -0x6e0(%rbp)
movq %rax, -0x6d8(%rbp)
jmp 0xae85
movq -0x6e0(%rbp), %rax
movq -0x6d8(%rbp), %rcx
movq %rcx, -0xf8(%rbp)
movq %rax, -0xf0(%rbp)
leaq -0xf8(%rbp), %rdi
movl $0x1, %esi
callq 0x127c0
movq -0x6a0(%rbp), %rsi
leaq -0x168(%rbp), %rdi
callq 0x47a0
jmp 0xaec7
movl -0xa8(%rbp), %edx
leaq -0x168(%rbp), %rdi
leaq -0x28(%rbp), %rsi
leaq -0xe0(%rbp), %rcx
callq 0xc1a0
jmp 0xaee6
leaq -0x168(%rbp), %rdi
callq 0x4880
movslq -0xa8(%rbp), %rsi
leaq -0xe0(%rbp), %rdi
callq 0x12760
movq %rdx, -0x6f0(%rbp)
movq %rax, -0x6e8(%rbp)
jmp 0xaf15
movq -0x6f0(%rbp), %rax
movq -0x6e8(%rbp), %rcx
movq %rcx, -0x178(%rbp)
movq %rax, -0x170(%rbp)
leaq -0x178(%rbp), %rdi
xorl %esi, %esi
callq 0x127c0
leaq -0xe0(%rbp), %rdi
callq 0x12810
jmp 0xaff5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x61(%rbp), %rdi
callq 0x12660
leaq -0x60(%rbp), %rdi
callq 0x12680
jmp 0xc194
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0xa1(%rbp), %rdi
callq 0x12700
jmp 0xc18b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xc17f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0xe1(%rbp), %rdi
callq 0x12700
jmp 0xc17f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xafe4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x168(%rbp), %rdi
callq 0x4880
leaq -0xe0(%rbp), %rdi
callq 0x12810
jmp 0xc17f
jmp 0xaff7
movl -0xa8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa8(%rbp)
jmp 0xad8d
leaq -0x1a8(%rbp), %rdi
callq 0x12830
movl $0x0, -0x1ac(%rbp)
movq -0x6a0(%rbp), %rcx
movl -0x1ac(%rbp), %eax
cmpl 0x4(%rcx), %eax
jge 0xb1d0
movq -0x6a0(%rbp), %rdi
addq $0x58, %rdi
movslq -0x1ac(%rbp), %rsi
callq 0x121f0
movq %rax, -0x1b8(%rbp)
movq -0x1b8(%rbp), %rdi
callq 0x12850
movq %rax, -0x1c0(%rbp)
movq -0x1b8(%rbp), %rdi
callq 0x12880
movq %rax, -0x1c8(%rbp)
leaq -0x1c0(%rbp), %rdi
leaq -0x1c8(%rbp), %rsi
callq 0x128b0
testb $0x1, %al
jne 0xb097
jmp 0xb1ba
leaq -0x1c0(%rbp), %rdi
callq 0x128e0
movq %rax, %rsi
leaq -0x1e8(%rbp), %rdi
callq 0x6ce0
jmp 0xb0b4
movsbl -0x1e8(%rbp), %eax
cmpl $0x7e, %eax
jne 0xb19d
leaq -0x1e8(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x1f0(%rbp)
movq -0x1f0(%rbp), %rdi
callq 0x12900
movq %rax, -0x1f8(%rbp)
movq -0x1f0(%rbp), %rdi
callq 0x12930
movq %rax, -0x200(%rbp)
leaq -0x1f8(%rbp), %rdi
leaq -0x200(%rbp), %rsi
callq 0x12960
testb $0x1, %al
jne 0xb118
jmp 0xb19b
leaq -0x1f8(%rbp), %rdi
callq 0x129a0
movl (%rax), %eax
movl %eax, -0x204(%rbp)
leaq -0x1a8(%rbp), %rdi
leaq -0x204(%rbp), %rsi
callq 0x129c0
movq %rax, -0x6f8(%rbp)
jmp 0xb148
movq -0x6f8(%rbp), %rdi
leaq -0x1ac(%rbp), %rsi
callq 0x12030
jmp 0xb15d
jmp 0xb15f
leaq -0x1f8(%rbp), %rdi
callq 0x12aa0
jmp 0xb0fc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xc173
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x1e8(%rbp), %rdi
callq 0x6e80
jmp 0xc173
jmp 0xb19d
leaq -0x1e8(%rbp), %rdi
callq 0x6e80
leaq -0x1c0(%rbp), %rdi
callq 0x12ac0
jmp 0xb07b
jmp 0xb1bc
movl -0x1ac(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1ac(%rbp)
jmp 0xb021
movl $0x0, -0x208(%rbp)
movq -0x6a0(%rbp), %rcx
movl -0x208(%rbp), %eax
cmpl 0x4(%rcx), %eax
jge 0xb4a3
leaq -0x258(%rbp), %rdi
callq 0x12af0
jmp 0xb1fe
movq -0x6a0(%rbp), %rax
movslq 0x4(%rax), %rax
movq %rax, -0x708(%rbp)
leaq -0x271(%rbp), %rdi
movq %rdi, -0x700(%rbp)
callq 0x7310
movq -0x708(%rbp), %rsi
movq -0x700(%rbp), %rdx
leaq -0x270(%rbp), %rdi
callq 0x12b20
jmp 0xb23f
leaq -0x271(%rbp), %rdi
callq 0x55f0
leaq -0x258(%rbp), %rdi
leaq -0x208(%rbp), %rsi
callq 0x12b90
jmp 0xb260
movslq -0x208(%rbp), %rsi
leaq -0x270(%rbp), %rdi
callq 0x12bc0
movl $0x1, (%rax)
leaq -0x258(%rbp), %rdi
callq 0x12be0
movb %al, -0x709(%rbp)
jmp 0xb28d
movb -0x709(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0xb29e
jmp 0xb466
leaq -0x258(%rbp), %rdi
callq 0x12c00
movq %rax, -0x718(%rbp)
jmp 0xb2b3
movq -0x718(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x278(%rbp)
leaq -0x258(%rbp), %rdi
callq 0x12c20
jmp 0xb2d0
leaq -0x1a8(%rbp), %rdi
leaq -0x278(%rbp), %rsi
callq 0x129c0
movq %rax, -0x720(%rbp)
jmp 0xb2ec
movq -0x720(%rbp), %rax
movq %rax, -0x280(%rbp)
movq -0x280(%rbp), %rdi
callq 0x12900
movq %rax, -0x288(%rbp)
movq -0x280(%rbp), %rdi
callq 0x12930
movq %rax, -0x290(%rbp)
leaq -0x288(%rbp), %rdi
leaq -0x290(%rbp), %rsi
callq 0x12960
testb $0x1, %al
jne 0xb33c
jmp 0xb461
leaq -0x288(%rbp), %rdi
callq 0x129a0
movl (%rax), %eax
movl %eax, -0x294(%rbp)
movslq -0x294(%rbp), %rsi
leaq -0x270(%rbp), %rdi
callq 0x12bc0
cmpl $0x0, (%rax)
jne 0xb44e
movslq -0x294(%rbp), %rsi
leaq -0x28(%rbp), %rdi
movq %rdi, -0x730(%rbp)
callq 0x12720
movq -0x730(%rbp), %rdi
movq %rax, -0x728(%rbp)
movslq -0x208(%rbp), %rsi
callq 0x12720
movq %rax, %rdi
callq 0x12c80
movq -0x730(%rbp), %rdi
movq %rax, -0x2a0(%rbp)
movslq -0x208(%rbp), %rsi
callq 0x12720
movq %rax, %rdi
callq 0x12cb0
movq -0x728(%rbp), %rdi
movq %rax, -0x2a8(%rbp)
movq -0x2a0(%rbp), %rsi
movq -0x2a8(%rbp), %rdx
callq 0x12c40
jmp 0xb3ea
leaq -0x258(%rbp), %rdi
leaq -0x294(%rbp), %rsi
callq 0x12b90
jmp 0xb3ff
movslq -0x294(%rbp), %rsi
leaq -0x270(%rbp), %rdi
callq 0x12bc0
movl $0x1, (%rax)
jmp 0xb44e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x271(%rbp), %rdi
callq 0x55f0
jmp 0xb492
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x270(%rbp), %rdi
callq 0x4d70
jmp 0xb492
jmp 0xb450
leaq -0x288(%rbp), %rdi
callq 0x12aa0
jmp 0xb320
jmp 0xb279
leaq -0x270(%rbp), %rdi
callq 0x4d70
leaq -0x258(%rbp), %rdi
callq 0x12ce0
movl -0x208(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x208(%rbp)
jmp 0xb1da
leaq -0x258(%rbp), %rdi
callq 0x12ce0
jmp 0xc173
leaq -0x2d8(%rbp), %rdi
callq 0x125a0
movq -0x6a0(%rbp), %rax
addq $0x40, %rax
movq %rax, -0x2e0(%rbp)
movq -0x2e0(%rbp), %rdi
callq 0x12900
movq %rax, -0x2e8(%rbp)
movq -0x2e0(%rbp), %rdi
callq 0x12930
movq %rax, -0x2f0(%rbp)
leaq -0x2e8(%rbp), %rdi
leaq -0x2f0(%rbp), %rsi
callq 0x12960
testb $0x1, %al
jne 0xb500
jmp 0xb56f
leaq -0x2e8(%rbp), %rdi
callq 0x129a0
movl (%rax), %eax
movl %eax, -0x2f4(%rbp)
leaq -0x2d8(%rbp), %rdi
leaq -0x2f4(%rbp), %rsi
callq 0x12d00
movb %dl, -0x739(%rbp)
movq %rax, -0x738(%rbp)
jmp 0xb536
movb -0x739(%rbp), %al
movq -0x738(%rbp), %rcx
movq %rcx, -0x308(%rbp)
movb %al, -0x300(%rbp)
leaq -0x2e8(%rbp), %rdi
callq 0x12aa0
jmp 0xb4e7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xc167
movl $0x0, -0x30c(%rbp)
leaq -0x28(%rbp), %rax
movq %rax, -0x318(%rbp)
movq -0x318(%rbp), %rdi
callq 0x12d50
movq %rax, -0x320(%rbp)
movq -0x318(%rbp), %rdi
callq 0x12d80
movq %rax, -0x328(%rbp)
leaq -0x320(%rbp), %rdi
leaq -0x328(%rbp), %rsi
callq 0x12db0
testb $0x1, %al
jne 0xb5c6
jmp 0xb718
leaq -0x320(%rbp), %rdi
callq 0x12df0
movq %rax, %rsi
leaq -0x358(%rbp), %rdi
callq 0x12e10
jmp 0xb5e3
movl -0x30c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30c(%rbp)
leaq -0x358(%rbp), %rax
movq %rax, -0x360(%rbp)
movq -0x360(%rbp), %rdi
callq 0x12c80
movq %rax, -0x368(%rbp)
movq -0x360(%rbp), %rdi
callq 0x12cb0
movq %rax, -0x370(%rbp)
leaq -0x368(%rbp), %rdi
leaq -0x370(%rbp), %rsi
callq 0x12e40
testb $0x1, %al
jne 0xb642
jmp 0xb6fb
leaq -0x368(%rbp), %rdi
callq 0x12e70
movl (%rax), %eax
movl %eax, -0x374(%rbp)
leaq -0x2d8(%rbp), %rdi
leaq -0x374(%rbp), %rsi
callq 0x12e90
movq %rax, -0x748(%rbp)
jmp 0xb672
movq -0x748(%rbp), %rax
cmpq $0x0, %rax
je 0xb6e8
movl -0x30c(%rbp), %eax
decl %eax
movl %eax, -0x378(%rbp)
leaq -0x2d8(%rbp), %rdi
leaq -0x378(%rbp), %rsi
callq 0x12ef0
movb %dl, -0x751(%rbp)
movq %rax, -0x750(%rbp)
jmp 0xb6af
movb -0x751(%rbp), %al
movq -0x750(%rbp), %rcx
movq %rcx, -0x388(%rbp)
movb %al, -0x380(%rbp)
jmp 0xb6fb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x358(%rbp), %rdi
callq 0x12680
jmp 0xc167
jmp 0xb6ea
leaq -0x368(%rbp), %rdi
callq 0x12f40
jmp 0xb626
leaq -0x358(%rbp), %rdi
callq 0x12680
leaq -0x320(%rbp), %rdi
callq 0x12f70
jmp 0xb5aa
leaq -0x3b8(%rbp), %rdi
callq 0x125a0
movl $0x0, -0x3bc(%rbp)
leaq -0x2d8(%rbp), %rdi
leaq -0x3bc(%rbp), %rsi
callq 0x12e90
movq %rax, -0x760(%rbp)
jmp 0xb74a
movq -0x760(%rbp), %rax
cmpq $0x0, %rax
je 0xb7b0
movl $0x0, -0x3c0(%rbp)
leaq -0x3b8(%rbp), %rdi
leaq -0x3c0(%rbp), %rsi
callq 0x12ef0
movb %dl, -0x769(%rbp)
movq %rax, -0x768(%rbp)
jmp 0xb783
movb -0x769(%rbp), %al
movq -0x768(%rbp), %rcx
movq %rcx, -0x3d0(%rbp)
movb %al, -0x3c8(%rbp)
jmp 0xb7b0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xc15b
leaq -0x400(%rbp), %rdi
movq %rdi, -0x780(%rbp)
callq 0x12f90
leaq -0x418(%rbp), %rdi
callq 0x7250
leaq -0x448(%rbp), %rdi
callq 0x125a0
movq -0x6a0(%rbp), %rax
movl $0x0, -0x44c(%rbp)
movl -0x44c(%rbp), %ecx
movl %ecx, -0x784(%rbp)
incl %ecx
movl %ecx, -0x44c(%rbp)
movslq 0x8(%rax), %rsi
leaq -0x28(%rbp), %rdi
callq 0x12720
movq -0x780(%rbp), %rdi
movq %rax, %rsi
callq 0x12fb0
movq %rax, -0x778(%rbp)
jmp 0xb825
movq -0x778(%rbp), %rax
movl -0x784(%rbp), %ecx
movl %ecx, (%rax)
xorps %xmm0, %xmm0
movaps %xmm0, -0x460(%rbp)
movaps %xmm0, -0x470(%rbp)
movaps %xmm0, -0x480(%rbp)
leaq -0x480(%rbp), %rdi
movq %rdi, -0x790(%rbp)
callq 0x130c0
movq -0x790(%rbp), %rsi
leaq -0x418(%rbp), %rdi
callq 0x13090
jmp 0xb874
leaq -0x480(%rbp), %rdi
callq 0x8600
movq -0x6a0(%rbp), %rax
movslq 0x8(%rax), %rsi
leaq -0x28(%rbp), %rdi
callq 0x12720
movq %rax, %rsi
leaq -0x400(%rbp), %rdi
callq 0x12fb0
movq %rax, -0x798(%rbp)
jmp 0xb8ac
movq -0x798(%rbp), %rsi
leaq -0x448(%rbp), %rdi
callq 0x12d00
movb %dl, -0x7a1(%rbp)
movq %rax, -0x7a0(%rbp)
jmp 0xb8ce
movb -0x7a1(%rbp), %al
movq -0x7a0(%rbp), %rcx
movq %rcx, -0x490(%rbp)
movb %al, -0x488(%rbp)
leaq -0x4e0(%rbp), %rdi
callq 0x130e0
jmp 0xb8f6
movq -0x6a0(%rbp), %rax
movslq 0x8(%rax), %rsi
leaq -0x28(%rbp), %rdi
callq 0x12720
movq %rax, %rsi
leaq -0x4e0(%rbp), %rdi
callq 0x13110
jmp 0xb91b
jmp 0xb91d
leaq -0x4e0(%rbp), %rdi
callq 0x13140
movb %al, -0x7a2(%rbp)
jmp 0xb931
movb -0x7a2(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0xb942
jmp 0xbf84
leaq -0x4e0(%rbp), %rdi
callq 0x13160
movq %rax, -0x7b0(%rbp)
jmp 0xb957
movq -0x7b0(%rbp), %rsi
leaq -0x510(%rbp), %rdi
callq 0x12e10
jmp 0xb96c
leaq -0x4e0(%rbp), %rdi
callq 0x13180
jmp 0xb97a
movq -0x6a0(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x518(%rbp)
movq -0x518(%rbp), %rdi
callq 0x131a0
movq %rax, -0x520(%rbp)
movq -0x518(%rbp), %rdi
callq 0x131d0
movq %rax, -0x528(%rbp)
leaq -0x520(%rbp), %rdi
leaq -0x528(%rbp), %rsi
callq 0x13200
testb $0x1, %al
jne 0xb9ce
jmp 0xbf62
leaq -0x520(%rbp), %rdi
callq 0x13240
movb (%rax), %al
movb %al, -0x529(%rbp)
movsbl -0x529(%rbp), %eax
cmpl $0x7e, %eax
jne 0xba43
jmp 0xbf43
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xc137
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x480(%rbp), %rdi
callq 0x8600
jmp 0xc137
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xc12b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xbf73
leaq -0x560(%rbp), %rdi
callq 0x125a0
leaq -0x510(%rbp), %rax
movq %rax, -0x568(%rbp)
movq -0x568(%rbp), %rdi
callq 0x12c80
movq %rax, -0x570(%rbp)
movq -0x568(%rbp), %rdi
callq 0x12cb0
movq %rax, -0x578(%rbp)
leaq -0x570(%rbp), %rdi
leaq -0x578(%rbp), %rsi
callq 0x12e40
testb $0x1, %al
jne 0xba9f
jmp 0xbc50
leaq -0x570(%rbp), %rdi
callq 0x12e70
movq -0x6a0(%rbp), %rdi
movl (%rax), %eax
movl %eax, -0x57c(%rbp)
addq $0x58, %rdi
movslq -0x57c(%rbp), %rsi
callq 0x121f0
movq %rax, %rdi
leaq -0x529(%rbp), %rsi
callq 0x13260
movq %rax, -0x7b8(%rbp)
jmp 0xbae2
movq -0x7b8(%rbp), %rax
cmpq $0x0, %rax
je 0xbc3d
movq -0x6a0(%rbp), %rdi
addq $0x58, %rdi
movslq -0x57c(%rbp), %rsi
callq 0x121f0
movq %rax, %rdi
leaq -0x529(%rbp), %rsi
callq 0x12210
movq %rax, -0x7c0(%rbp)
jmp 0xbb22
movq -0x7c0(%rbp), %rax
movq %rax, -0x588(%rbp)
movq -0x588(%rbp), %rdi
callq 0x12900
movq %rax, -0x590(%rbp)
movq -0x588(%rbp), %rdi
callq 0x12930
movq %rax, -0x598(%rbp)
leaq -0x590(%rbp), %rdi
leaq -0x598(%rbp), %rsi
callq 0x12960
testb $0x1, %al
jne 0xbb72
jmp 0xbc3b
leaq -0x590(%rbp), %rdi
callq 0x129a0
movl (%rax), %eax
movl %eax, -0x59c(%rbp)
movslq -0x59c(%rbp), %rsi
leaq -0x28(%rbp), %rdi
callq 0x12720
movq %rax, %rsi
leaq -0x5d0(%rbp), %rdi
callq 0x12e10
jmp 0xbba7
leaq -0x5d0(%rbp), %rdi
movq %rdi, -0x7c8(%rbp)
callq 0x12c80
movq -0x7c8(%rbp), %rdi
movq %rax, -0x5d8(%rbp)
callq 0x12cb0
movq %rax, -0x5e0(%rbp)
movq -0x5d8(%rbp), %rsi
movq -0x5e0(%rbp), %rdx
leaq -0x560(%rbp), %rdi
callq 0x12c40
jmp 0xbbf0
leaq -0x5d0(%rbp), %rdi
callq 0x12680
leaq -0x590(%rbp), %rdi
callq 0x12aa0
jmp 0xbb56
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xbf54
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x5d0(%rbp), %rdi
callq 0x12680
jmp 0xbf54
jmp 0xbc3d
jmp 0xbc3f
leaq -0x570(%rbp), %rdi
callq 0x12f40
jmp 0xba83
leaq -0x560(%rbp), %rdi
callq 0x12740
cmpq $0x0, %rax
je 0xbf37
leaq -0x400(%rbp), %rdi
leaq -0x560(%rbp), %rsi
callq 0x132c0
movq %rax, -0x7d0(%rbp)
jmp 0xbc82
movq -0x7d0(%rbp), %rax
cmpq $0x0, %rax
jne 0xbe29
movl -0x44c(%rbp), %eax
movl %eax, -0x7dc(%rbp)
incl %eax
movl %eax, -0x44c(%rbp)
leaq -0x400(%rbp), %rdi
leaq -0x560(%rbp), %rsi
callq 0x12fb0
movq %rax, -0x7d8(%rbp)
jmp 0xbcc3
movq -0x7d8(%rbp), %rax
movl -0x7dc(%rbp), %ecx
movl %ecx, (%rax)
leaq -0x560(%rbp), %rax
movq %rax, -0x5e8(%rbp)
movq -0x5e8(%rbp), %rdi
callq 0x12c80
movq %rax, -0x5f0(%rbp)
movq -0x5e8(%rbp), %rdi
callq 0x12cb0
movq %rax, -0x5f8(%rbp)
leaq -0x5f0(%rbp), %rdi
leaq -0x5f8(%rbp), %rsi
callq 0x12e40
testb $0x1, %al
jne 0xbd22
jmp 0xbdbe
leaq -0x5f0(%rbp), %rdi
callq 0x12e70
movl (%rax), %eax
movl %eax, -0x5fc(%rbp)
leaq -0x2d8(%rbp), %rdi
leaq -0x5fc(%rbp), %rsi
callq 0x12e90
movq %rax, -0x7e8(%rbp)
jmp 0xbd52
movq -0x7e8(%rbp), %rax
cmpq $0x0, %rax
je 0xbdab
movl -0x44c(%rbp), %eax
decl %eax
movl %eax, -0x600(%rbp)
leaq -0x3b8(%rbp), %rdi
leaq -0x600(%rbp), %rsi
callq 0x12ef0
movb %dl, -0x7f1(%rbp)
movq %rax, -0x7f0(%rbp)
jmp 0xbd8f
movb -0x7f1(%rbp), %al
movq -0x7f0(%rbp), %rcx
movq %rcx, -0x610(%rbp)
movb %al, -0x608(%rbp)
jmp 0xbdbe
jmp 0xbdad
leaq -0x5f0(%rbp), %rdi
callq 0x12f40
jmp 0xbd06
xorps %xmm0, %xmm0
movaps %xmm0, -0x620(%rbp)
movaps %xmm0, -0x630(%rbp)
movaps %xmm0, -0x640(%rbp)
leaq -0x640(%rbp), %rdi
movq %rdi, -0x800(%rbp)
callq 0x130c0
movq -0x800(%rbp), %rsi
leaq -0x418(%rbp), %rdi
callq 0x13090
jmp 0xbdfe
leaq -0x640(%rbp), %rdi
callq 0x8600
jmp 0xbe29
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x640(%rbp), %rdi
callq 0x8600
jmp 0xbf54
leaq -0x400(%rbp), %rdi
leaq -0x560(%rbp), %rsi
callq 0x12fb0
movq %rax, -0x808(%rbp)
jmp 0xbe45
movq -0x808(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x644(%rbp)
movl -0x644(%rbp), %eax
movl %eax, -0x814(%rbp)
leaq -0x400(%rbp), %rdi
leaq -0x510(%rbp), %rsi
callq 0x12fb0
movq %rax, -0x810(%rbp)
jmp 0xbe7c
movq -0x810(%rbp), %rax
movslq (%rax), %rsi
leaq -0x418(%rbp), %rdi
callq 0x13320
movq %rax, %rdi
leaq -0x529(%rbp), %rsi
callq 0x13340
movq %rax, -0x820(%rbp)
jmp 0xbeaa
movq -0x820(%rbp), %rax
movl -0x814(%rbp), %ecx
movl %ecx, (%rax)
leaq -0x448(%rbp), %rdi
leaq -0x644(%rbp), %rsi
callq 0x12e90
movq %rax, -0x828(%rbp)
jmp 0xbed5
movq -0x828(%rbp), %rax
cmpq $0x0, %rax
jne 0xbf35
leaq -0x448(%rbp), %rdi
leaq -0x644(%rbp), %rsi
callq 0x12d00
movb %dl, -0x831(%rbp)
movq %rax, -0x830(%rbp)
jmp 0xbf04
movb -0x831(%rbp), %al
movq -0x830(%rbp), %rcx
movq %rcx, -0x658(%rbp)
movb %al, -0x650(%rbp)
leaq -0x4e0(%rbp), %rdi
leaq -0x560(%rbp), %rsi
callq 0x13110
jmp 0xbf33
jmp 0xbf35
jmp 0xbf37
leaq -0x560(%rbp), %rdi
callq 0x12680
leaq -0x520(%rbp), %rdi
callq 0x13420
jmp 0xb9b2
leaq -0x560(%rbp), %rdi
callq 0x12680
jmp 0xbf73
leaq -0x510(%rbp), %rdi
callq 0x12680
jmp 0xb91d
leaq -0x510(%rbp), %rdi
callq 0x12680
jmp 0xc12b
movq -0x6a0(%rbp), %rax
movl (%rax), %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
movl -0x44c(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x4(%rax)
movq -0x10(%rbp), %rax
movl $0x0, 0x8(%rax)
leaq -0x3b8(%rbp), %rdi
callq 0x12740
movq -0x6a0(%rbp), %rsi
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0xc(%rax)
addq $0x10, %rsi
movq -0x10(%rbp), %rdi
addq $0x10, %rdi
callq 0x13440
jmp 0xbfda
movl $0x0, -0x65c(%rbp)
movl -0x65c(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x4(%rcx), %eax
jge 0xc01c
movq -0x10(%rbp), %rdi
addq $0x28, %rdi
leaq -0x65c(%rbp), %rsi
callq 0x12030
jmp 0xc009
jmp 0xc00b
movl -0x65c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x65c(%rbp)
jmp 0xbfe4
leaq -0x3b8(%rbp), %rax
movq %rax, -0x668(%rbp)
movq -0x668(%rbp), %rdi
callq 0x12c80
movq %rax, -0x670(%rbp)
movq -0x668(%rbp), %rdi
callq 0x12cb0
movq %rax, -0x678(%rbp)
leaq -0x670(%rbp), %rdi
leaq -0x678(%rbp), %rsi
callq 0x12e40
testb $0x1, %al
jne 0xc069
jmp 0xc0a3
leaq -0x670(%rbp), %rdi
callq 0x12e70
movl (%rax), %eax
movl %eax, -0x67c(%rbp)
movq -0x10(%rbp), %rdi
addq $0x40, %rdi
leaq -0x67c(%rbp), %rsi
callq 0x12030
jmp 0xc093
jmp 0xc095
leaq -0x670(%rbp), %rdi
callq 0x12f40
jmp 0xc050
movq -0x10(%rbp), %rdi
addq $0x58, %rdi
leaq -0x418(%rbp), %rsi
callq 0x13670
jmp 0xc0b9
leaq -0x4e0(%rbp), %rdi
callq 0x138c0
leaq -0x448(%rbp), %rdi
callq 0x12680
leaq -0x418(%rbp), %rdi
callq 0x8740
leaq -0x400(%rbp), %rdi
callq 0x138e0
leaq -0x3b8(%rbp), %rdi
callq 0x12680
leaq -0x2d8(%rbp), %rdi
callq 0x12680
leaq -0x1a8(%rbp), %rdi
callq 0x13900
leaq -0xa0(%rbp), %rdi
callq 0x12810
leaq -0x28(%rbp), %rdi
callq 0x13920
addq $0x840, %rsp            # imm = 0x840
popq %rbp
retq
leaq -0x4e0(%rbp), %rdi
callq 0x138c0
leaq -0x448(%rbp), %rdi
callq 0x12680
leaq -0x418(%rbp), %rdi
callq 0x8740
leaq -0x400(%rbp), %rdi
callq 0x138e0
leaq -0x3b8(%rbp), %rdi
callq 0x12680
leaq -0x2d8(%rbp), %rdi
callq 0x12680
leaq -0x1a8(%rbp), %rdi
callq 0x13900
leaq -0xa0(%rbp), %rdi
callq 0x12810
leaq -0x28(%rbp), %rdi
callq 0x13920
movq -0x70(%rbp), %rdi
callq 0x34e0
nopl (%rax)