// File: sus304[P]ForRocket/src/solver/rocket_stage.cpp
// Function: forrocket::RocketStage::FlightSequence(forrocket::SequenceClock*, forrocket::EnvironmentWind*, std::array<double, 14ul>&)
void forrocket::RocketStage::FlightSequence(SequenceClock* master_clock, EnvironmentWind* wind, DynamicsBase::state& x0) {
    namespace odeint = boost::numeric::odeint;

    // Sterpper Select
    ////////////////////////////////////
    double eps_abs = 1.0e-12;
    double eps_rel = 1.0e-7;
    // 4th Order Runge-Kutta Method
    // odeint::runge_kutta4<forrocket::DynamicsBase::state> stepper;

    // 5th Order Runge-Kutta-Dormand-Prince Method : Controled : Dense output : Internal info
    using base_stepper_type = odeint::runge_kutta_dopri5<forrocket::DynamicsBase::state>;
    auto stepper = make_controlled( eps_abs , eps_rel , base_stepper_type());

    // 8th Order Runge-Kutta-Fehlberg Method : Controled
    // using base_stepper_type = odeint::runge_kutta_fehlberg78<forrocket::DynamicsBase::state>;
    // auto stepper = make_controlled( eps_abs , eps_rel , base_stepper_type());

    // Dynamics6dofAero dynamics_6dof_aero(&rocket, master_clock, wind);
    // Dynamics6dofProgramRate dynamics_6dof_programrate(&rocket, master_clock, wind);
    DynamicsBase* p_dynamics;
    p_dynamics = new Dynamics6dofAero(&rocket, master_clock, wind);

    double start, end;
    double time_step_on_launcher = 0.001;  // 1000 Hz
    double time_step_decent_parachute = 0.1;  // 10 Hz
    fdr.ReserveCapacity(static_cast<int>((time_end - time_start) / time_step) * 1.3);

    DynamicsBase::state x0_in_stage = x0;  // x0はソルバで次段のために共有するので内部用にコピー

    if (time_ignittion <= time_start) {
        // 計算開始と同時に点火する場合
        rocket.IgnitionEngine(master_clock->UTC_date_init, master_clock->countup_time);
        start = time_start;
    } else {
        // 点火が計算開始より後の場合
        // Flight start から engine ignittion まで
        SwitchDynamics(time_start, &p_dynamics, master_clock, wind);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, time_start, time_ignittion, time_step, std::ref(fdr)); // 点火までの慣性飛行計算
        start = time_ignittion;
        rocket.IgnitionEngine(master_clock->UTC_date_init, master_clock->countup_time);
    }
    // ここまでにIgnitionEngineが実行されている

    if (enable_launcher) {
        // ランチクリア時刻確定のためにコピー品で短時間回す
        Rocket rocket_on_launcher = rocket;
        SequenceClock clock_on_launcher = *master_clock; // copy
        DynamicsBase::state x0_on_launcher = x0;
        FlightDataRecorder fdr_on_launcher(&rocket_on_launcher);
        p_dynamics = new Dynamics3dofOnLauncher(&rocket_on_launcher, &clock_on_launcher);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_on_launcher, start, start+1.0, time_step_on_launcher, std::ref(fdr_on_launcher));
        
        # ifdef DEBUG_NO
        fdr_on_launcher.dump_csv("test_estimate_launcher.csv");
        # endif
        
        for (int i=0; i < fdr_on_launcher.countup_burn_time.size(); ++i) {
            double distance = (fdr_on_launcher.position[i].LLH(2) - fdr_on_launcher.position[0].LLH(2)) / sin(fdr_on_launcher.attitude[i].euler_angle(1));
            if (distance >= length_launcher_rail) {
                end = time_step_on_launcher * i;
                break;
            }
        }

        // ランチャ滑走の本ちゃん
        p_dynamics = new Dynamics3dofOnLauncher(&rocket, master_clock);
        stepper.initialize(std::ref(*p_dynamics), x0_in_stage, start);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, start, start + end, time_step_on_launcher, std::ref(fdr));
        // odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, start, start + end, time_step_on_launcher, std::ref(fdr));
        start = start + end;
        #ifdef DEBUG
        fdr.dump_csv("debug_onlauncher_log.csv");
        #endif
    }
    // ここまでに慣性飛行からの点火もしくはランチクリアまでが実行されている
    
    if (enable_cutoff) {
        // engine cutoff まで 
        SwitchDynamics(start, &p_dynamics, master_clock, wind);
        stepper.initialize(std::ref(*p_dynamics), x0_in_stage, start);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, start, time_cutoff, time_step, std::ref(fdr));
        start = time_cutoff;
        rocket.CutoffEngine();
    }
    // enable_cutoff=false の場合は質量0で自動cutoffされる（Engineクラス側）

    if (enable_despin) {
        SwitchDynamics(start, &p_dynamics, master_clock, wind);
        stepper.initialize(std::ref(*p_dynamics), x0_in_stage, start);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, start, time_despin, time_step, std::ref(fdr));
        start = time_despin;
        rocket.DeSpin();
    }

    if (enable_fairing_jettson) {
        SwitchDynamics(start, &p_dynamics, master_clock, wind);
        stepper.initialize(std::ref(*p_dynamics), x0_in_stage, start);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, start, time_jettson_fairing, time_step, std::ref(fdr));
        start = time_jettson_fairing;
        rocket.JettsonFairing(mass_fairing);
    }

    if (enable_sepation) {
        SwitchDynamics(start, &p_dynamics, master_clock, wind);
        stepper.initialize(std::ref(*p_dynamics), x0_in_stage, start);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, start, time_separation, time_step, std::ref(fdr));
        start = time_separation;
        rocket.SeparateUpperStage(mass_upper_stage);
        x0 = x0_in_stage;  // 次段のために分離情報をコピー
    }

    if (!enable_parachute_open) {
        // 弾道で落ちるまで
        SwitchDynamics(start, &p_dynamics, master_clock, wind);
        stepper.initialize(std::ref(*p_dynamics), x0_in_stage, start);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, start, time_end, time_step, std::ref(fdr));
    } else {
        // パラシュート開傘
        if (enable_apogee_parachute_open) {
            // 頂点時刻確定のためにコピー品で回す
            Rocket rocket_apogee_estimate = rocket;
            SequenceClock clock_apogee_estimate = *master_clock; // copy
            DynamicsBase::state x0_apogee_estimate = x0;
            FlightDataRecorder fdr_apogee_estimate(&rocket_apogee_estimate);
            if (enable_program_attitude) {
                p_dynamics = new Dynamics6dofProgramRate(&rocket, &clock_apogee_estimate, wind);
            } else {
                p_dynamics = new Dynamics6dofAero(&rocket, &clock_apogee_estimate, wind);
            }
            odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_apogee_estimate, start, time_end, time_step, std::ref(fdr_apogee_estimate));
            double max_alt = 0.0;
            for (int i=0; i < fdr_apogee_estimate.position.size(); ++i) {
                double alt = fdr_apogee_estimate.position[i].LLH(2);
                if (max_alt < alt) {
                    max_alt = alt;
                } else {
                    end = fdr_apogee_estimate.countup_time[i];
                    break;
                }
            }
        } else {
            end = time_open_parachute;
        }
        // 開傘までの慣性飛行本ちゃん
        SwitchDynamics(start, &p_dynamics, master_clock, wind);
        stepper.initialize(std::ref(*p_dynamics), x0_in_stage, start);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, start, end, time_step, std::ref(fdr));
        start = end;

        // ここまでで頂点もしくは開傘時刻まで実行されている
        odeint::runge_kutta4<forrocket::DynamicsBase::state> stepper;
        rocket.OpenParachute();
        Dynamics3dofParachute dynamics_3dof_parachute(&rocket, master_clock, wind);

        if (exist_second_parachute) {
            odeint::integrate_const(stepper, dynamics_3dof_parachute, x0_in_stage, start, time_open_second_parachute, time_step_decent_parachute, std::ref(fdr));
            rocket.OpenParachute();
            odeint::integrate_const(stepper, dynamics_3dof_parachute, x0_in_stage, time_open_second_parachute, time_end, time_step_decent_parachute, std::ref(fdr));
        } else {
            odeint::integrate_const(stepper, dynamics_3dof_parachute, x0_in_stage, start, time_end, time_step_decent_parachute, std::ref(fdr));
        }
    }

    // fdr.dump_csv("flight_log_stage"+std::to_string(stage_number)+".csv");
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x79b0, %rsp           # imm = 0x79B0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x7200(%rbp)
movabsq $0x3d719799812dea11, %rax # imm = 0x3D719799812DEA11
movq %rax, -0x28(%rbp)
movabsq $0x3e7ad7f29abcaf48, %rax # imm = 0x3E7AD7F29ABCAF48
movq %rax, -0x30(%rbp)
movsd -0x28(%rbp), %xmm0
movsd %xmm0, -0x7218(%rbp)
movsd -0x30(%rbp), %xmm0
movsd %xmm0, -0x7210(%rbp)
leaq -0x948(%rbp), %rdi
movq %rdi, -0x7208(%rbp)
leaq -0x949(%rbp), %rsi
callq 0x7c3b0
movsd -0x7218(%rbp), %xmm0
movsd -0x7210(%rbp), %xmm1
movq -0x7208(%rbp), %rsi
leaq -0x5b8(%rbp), %rdi
callq 0x7c370
movl $0x20, %edi
callq 0x6430
movq -0x7200(%rbp), %rsi
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x71f8(%rbp)
addq $0x10, %rsi
movq -0x10(%rbp), %rdx
movq -0x18(%rbp), %rcx
callq 0x65820
jmp 0x7a82a
movq -0x7200(%rbp), %rax
movq -0x71f8(%rbp), %rcx
movq %rcx, -0x958(%rbp)
movsd 0x2b8c1(%rip), %xmm0    # 0xa6108
movsd %xmm0, -0x980(%rbp)
movsd 0x2a361(%rip), %xmm0    # 0xa4bb8
movsd %xmm0, -0x988(%rbp)
movq %rax, %rdi
addq $0xe80, %rdi            # imm = 0xE80
movsd 0x11f8(%rax), %xmm0
subsd 0x1150(%rax), %xmm0
divsd 0x1200(%rax), %xmm0
cvttsd2si %xmm0, %eax
cvtsi2sd %eax, %xmm0
movsd 0x2b86f(%rip), %xmm1    # 0xa6100
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %esi
callq 0x44220
movq -0x20(%rbp), %rsi
leaq -0x9f8(%rbp), %rdi
movl $0x70, %edx
callq 0x63a0
movq -0x7200(%rbp), %rax
movsd 0x1158(%rax), %xmm1
movsd 0x1150(%rax), %xmm0
ucomisd %xmm1, %xmm0
jb 0x7a95a
movq -0x7200(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x7220(%rbp)
movq -0x10(%rbp), %rsi
addq $0x18, %rsi
leaq -0xa14(%rbp), %rdi
callq 0x33f00
movq -0x7220(%rbp), %rdi
movq -0x10(%rbp), %rax
movsd 0x38(%rax), %xmm0
leaq -0xa14(%rbp), %rsi
callq 0x52660
movq -0x7200(%rbp), %rax
movsd 0x1150(%rax), %xmm0
movsd %xmm0, -0x970(%rbp)
jmp 0x7aa96
movq -0x71f8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x960(%rbp)
movl %eax, -0x964(%rbp)
movl $0x20, %esi
callq 0x6440
jmp 0x7bdd5
movq -0x7200(%rbp), %rdi
movsd 0x1150(%rdi), %xmm0
movq -0x10(%rbp), %rdx
movq -0x18(%rbp), %rcx
leaq -0x958(%rbp), %rsi
callq 0x7a640
leaq -0xfa0(%rbp), %rdi
leaq -0x5b8(%rbp), %rsi
movl $0x588, %edx            # imm = 0x588
callq 0x63a0
movq -0x958(%rbp), %rdi
callq 0x7c4c0
movq -0x7200(%rbp), %rdi
movq %rax, -0xfa8(%rbp)
movsd 0x1150(%rdi), %xmm0
movsd %xmm0, -0x7248(%rbp)
movsd 0x1158(%rdi), %xmm0
movsd %xmm0, -0x7240(%rbp)
movsd 0x1200(%rdi), %xmm0
movsd %xmm0, -0x7238(%rbp)
addq $0xe80, %rdi            # imm = 0xE80
callq 0x7c4f0
movsd -0x7248(%rbp), %xmm0
movsd -0x7240(%rbp), %xmm1
movsd -0x7238(%rbp), %xmm2
movq %rax, -0xfb0(%rbp)
movq -0xfa8(%rbp), %rax
movq %rax, -0x7230(%rbp)
movq -0xfb0(%rbp), %rdx
movq %rsp, %rdi
movl $0xb1, %ecx
leaq -0xfa0(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movq -0x7230(%rbp), %rdi
leaq -0x9f8(%rbp), %rsi
callq 0x7c400
movq -0x7200(%rbp), %rax
movsd 0x1158(%rax), %xmm0
movsd %xmm0, -0x970(%rbp)
addq $0x10, %rax
movq %rax, -0x7228(%rbp)
movq -0x10(%rbp), %rsi
addq $0x18, %rsi
leaq -0xfcc(%rbp), %rdi
callq 0x33f00
movq -0x7228(%rbp), %rdi
movq -0x10(%rbp), %rax
movsd 0x38(%rax), %xmm0
leaq -0xfcc(%rbp), %rsi
callq 0x52660
movq -0x7200(%rbp), %rax
testb $0x1, 0x1160(%rax)
je 0x7afb4
movq -0x7200(%rbp), %rsi
addq $0x10, %rsi
leaq -0x1e40(%rbp), %rdi
callq 0x7c520
movq -0x10(%rbp), %rsi
leaq -0x1e88(%rbp), %rdi
callq 0x7cb10
jmp 0x7aad3
movq -0x20(%rbp), %rax
movups 0x60(%rax), %xmm0
movaps %xmm0, -0x1ea0(%rbp)
movups 0x50(%rax), %xmm0
movaps %xmm0, -0x1eb0(%rbp)
movups 0x40(%rax), %xmm0
movaps %xmm0, -0x1ec0(%rbp)
movups (%rax), %xmm0
movups 0x10(%rax), %xmm1
movups 0x20(%rax), %xmm2
movups 0x30(%rax), %xmm3
movaps %xmm3, -0x1ed0(%rbp)
movaps %xmm2, -0x1ee0(%rbp)
movaps %xmm1, -0x1ef0(%rbp)
movaps %xmm0, -0x1f00(%rbp)
leaq -0x21d0(%rbp), %rdi
leaq -0x1e40(%rbp), %rsi
callq 0x44030
jmp 0x7ab38
movl $0x18, %edi
callq 0x6430
movq %rax, -0x7250(%rbp)
jmp 0x7ab4b
movq -0x7250(%rbp), %rdi
leaq -0x1e40(%rbp), %rsi
leaq -0x1e88(%rbp), %rdx
callq 0x597c0
jmp 0x7ab67
movq -0x7250(%rbp), %rax
movq %rax, -0x958(%rbp)
leaq -0x2758(%rbp), %rdi
movq %rdi, -0x7278(%rbp)
leaq -0x5b8(%rbp), %rsi
movl $0x588, %edx            # imm = 0x588
callq 0x63a0
movq -0x958(%rbp), %rdi
callq 0x7c4c0
movq %rax, -0x2760(%rbp)
movsd -0x970(%rbp), %xmm0
movsd %xmm0, -0x7270(%rbp)
movsd 0x1aa79(%rip), %xmm1    # 0x95638
addsd %xmm1, %xmm0
movsd %xmm0, -0x7268(%rbp)
movsd -0x980(%rbp), %xmm0
movsd %xmm0, -0x7260(%rbp)
leaq -0x21d0(%rbp), %rdi
callq 0x7c4f0
movq -0x7278(%rbp), %rsi
movsd -0x7270(%rbp), %xmm0
movsd -0x7268(%rbp), %xmm1
movsd -0x7260(%rbp), %xmm2
movq %rax, -0x2768(%rbp)
movq -0x2760(%rbp), %rax
movq %rax, -0x7258(%rbp)
movq -0x2768(%rbp), %rdx
movq %rsp, %rdi
movl $0xb1, %ecx
rep  movsq (%rsi), %es:(%rdi)
movq -0x7258(%rbp), %rdi
leaq -0x1f00(%rbp), %rsi
callq 0x7c400
jmp 0x7ac42
movl $0x0, -0x276c(%rbp)
movslq -0x276c(%rbp), %rax
movq %rax, -0x7280(%rbp)
leaq -0x21d0(%rbp), %rdi
addq $0x20, %rdi
callq 0x86e0
movq %rax, %rcx
movq -0x7280(%rbp), %rax
cmpq %rcx, %rax
jae 0x7adf9
leaq -0x2020(%rbp), %rdi
movslq -0x276c(%rbp), %rsi
callq 0x4a540
movq %rax, %rdi
addq $0x30, %rdi
movl $0x2, %esi
callq 0x372d0
movq %rax, -0x7288(%rbp)
jmp 0x7acaa
movq -0x7288(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x7298(%rbp)
leaq -0x2020(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x4a540
movq %rax, %rdi
addq $0x30, %rdi
movl $0x2, %esi
callq 0x372d0
movq %rax, -0x7290(%rbp)
jmp 0x7ace7
movsd -0x7298(%rbp), %xmm0
movq -0x7290(%rbp), %rax
movsd (%rax), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, -0x72a8(%rbp)
leaq -0x1fa8(%rbp), %rdi
movslq -0x276c(%rbp), %rsi
callq 0x4a6a0
movq %rax, %rdi
movl $0x1, %esi
callq 0x372d0
movq %rax, -0x72a0(%rbp)
jmp 0x7ad2f
movq -0x72a0(%rbp), %rax
movsd (%rax), %xmm0
callq 0x6120
movq -0x7200(%rbp), %rax
movaps %xmm0, %xmm1
movsd -0x72a8(%rbp), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, -0x2778(%rbp)
movsd -0x2778(%rbp), %xmm0
ucomisd 0x1168(%rax), %xmm0
jb 0x7ade3
movsd -0x980(%rbp), %xmm0
cvtsi2sdl -0x276c(%rbp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, -0x978(%rbp)
jmp 0x7adf9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x960(%rbp)
movl %eax, -0x964(%rbp)
jmp 0x7afa3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x960(%rbp)
movl %eax, -0x964(%rbp)
jmp 0x7af97
movq -0x7250(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x960(%rbp)
movl %eax, -0x964(%rbp)
movl $0x18, %esi
callq 0x6440
jmp 0x7af97
jmp 0x7ade5
movl -0x276c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x276c(%rbp)
jmp 0x7ac4c
movl $0x18, %edi
callq 0x6430
movq %rax, -0x72b0(%rbp)
jmp 0x7ae0c
movq -0x72b0(%rbp), %rdi
movq -0x7200(%rbp), %rsi
addq $0x10, %rsi
movq -0x10(%rbp), %rdx
callq 0x597c0
jmp 0x7ae29
movq -0x72b0(%rbp), %rax
movq %rax, -0x958(%rbp)
movq -0x958(%rbp), %rdi
callq 0x7c4c0
movq %rax, -0x2780(%rbp)
movsd -0x970(%rbp), %xmm0
movq -0x2780(%rbp), %rsi
leaq -0x5b8(%rbp), %rdi
leaq -0x9f8(%rbp), %rdx
callq 0x7cb80
jmp 0x7ae6e
leaq -0x2d08(%rbp), %rdi
movq %rdi, -0x72d8(%rbp)
leaq -0x5b8(%rbp), %rsi
movl $0x588, %edx            # imm = 0x588
callq 0x63a0
movq -0x958(%rbp), %rdi
callq 0x7c4c0
movq -0x7200(%rbp), %rdi
movq %rax, -0x2d10(%rbp)
movsd -0x970(%rbp), %xmm0
movsd %xmm0, -0x72d0(%rbp)
movsd -0x978(%rbp), %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, -0x72c8(%rbp)
movsd -0x980(%rbp), %xmm0
movsd %xmm0, -0x72c0(%rbp)
addq $0xe80, %rdi            # imm = 0xE80
callq 0x7c4f0
movq -0x72d8(%rbp), %rsi
movsd -0x72d0(%rbp), %xmm0
movsd -0x72c8(%rbp), %xmm1
movsd -0x72c0(%rbp), %xmm2
movq %rax, -0x2d18(%rbp)
movq -0x2d10(%rbp), %rax
movq %rax, -0x72b8(%rbp)
movq -0x2d18(%rbp), %rdx
movq %rsp, %rdi
movl $0xb1, %ecx
rep  movsq (%rsi), %es:(%rdi)
movq -0x72b8(%rbp), %rdi
leaq -0x9f8(%rbp), %rsi
callq 0x7c400
jmp 0x7af42
movsd -0x970(%rbp), %xmm0
addsd -0x978(%rbp), %xmm0
movsd %xmm0, -0x970(%rbp)
leaq -0x21d0(%rbp), %rdi
callq 0x79ae0
leaq -0x1e40(%rbp), %rdi
callq 0x77d90
jmp 0x7afb4
movq -0x72b0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x960(%rbp)
movl %eax, -0x964(%rbp)
movl $0x18, %esi
callq 0x6440
leaq -0x21d0(%rbp), %rdi
callq 0x79ae0
leaq -0x1e40(%rbp), %rdi
callq 0x77d90
jmp 0x7bdd5
movq -0x7200(%rbp), %rax
testb $0x1, 0x1170(%rax)
je 0x7b107
movq -0x7200(%rbp), %rdi
movsd -0x970(%rbp), %xmm0
movq -0x10(%rbp), %rdx
movq -0x18(%rbp), %rcx
leaq -0x958(%rbp), %rsi
callq 0x7a640
movq -0x958(%rbp), %rdi
callq 0x7c4c0
movq %rax, -0x2d20(%rbp)
movsd -0x970(%rbp), %xmm0
movq -0x2d20(%rbp), %rsi
leaq -0x5b8(%rbp), %rdi
leaq -0x9f8(%rbp), %rdx
callq 0x7cb80
leaq -0x32a8(%rbp), %rdi
leaq -0x5b8(%rbp), %rsi
movl $0x588, %edx            # imm = 0x588
callq 0x63a0
movq -0x958(%rbp), %rdi
callq 0x7c4c0
movq -0x7200(%rbp), %rdi
movq %rax, -0x32b0(%rbp)
movsd -0x970(%rbp), %xmm0
movsd %xmm0, -0x72f8(%rbp)
movsd 0x1178(%rdi), %xmm0
movsd %xmm0, -0x72f0(%rbp)
movsd 0x1200(%rdi), %xmm0
movsd %xmm0, -0x72e8(%rbp)
addq $0xe80, %rdi            # imm = 0xE80
callq 0x7c4f0
movsd -0x72f8(%rbp), %xmm0
movsd -0x72f0(%rbp), %xmm1
movsd -0x72e8(%rbp), %xmm2
movq %rax, -0x32b8(%rbp)
movq -0x32b0(%rbp), %rax
movq %rax, -0x72e0(%rbp)
movq -0x32b8(%rbp), %rdx
movq %rsp, %rdi
movl $0xb1, %ecx
leaq -0x32a8(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movq -0x72e0(%rbp), %rdi
leaq -0x9f8(%rbp), %rsi
callq 0x7c400
movq -0x7200(%rbp), %rdi
movsd 0x1178(%rdi), %xmm0
movsd %xmm0, -0x970(%rbp)
addq $0x10, %rdi
callq 0x526d0
movq -0x7200(%rbp), %rax
testb $0x1, 0x11b0(%rax)
je 0x7b25a
movq -0x7200(%rbp), %rdi
movsd -0x970(%rbp), %xmm0
movq -0x10(%rbp), %rdx
movq -0x18(%rbp), %rcx
leaq -0x958(%rbp), %rsi
callq 0x7a640
movq -0x958(%rbp), %rdi
callq 0x7c4c0
movq %rax, -0x32c0(%rbp)
movsd -0x970(%rbp), %xmm0
movq -0x32c0(%rbp), %rsi
leaq -0x5b8(%rbp), %rdi
leaq -0x9f8(%rbp), %rdx
callq 0x7cb80
leaq -0x3848(%rbp), %rdi
leaq -0x5b8(%rbp), %rsi
movl $0x588, %edx            # imm = 0x588
callq 0x63a0
movq -0x958(%rbp), %rdi
callq 0x7c4c0
movq -0x7200(%rbp), %rdi
movq %rax, -0x3850(%rbp)
movsd -0x970(%rbp), %xmm0
movsd %xmm0, -0x7318(%rbp)
movsd 0x11b8(%rdi), %xmm0
movsd %xmm0, -0x7310(%rbp)
movsd 0x1200(%rdi), %xmm0
movsd %xmm0, -0x7308(%rbp)
addq $0xe80, %rdi            # imm = 0xE80
callq 0x7c4f0
movsd -0x7318(%rbp), %xmm0
movsd -0x7310(%rbp), %xmm1
movsd -0x7308(%rbp), %xmm2
movq %rax, -0x3858(%rbp)
movq -0x3850(%rbp), %rax
movq %rax, -0x7300(%rbp)
movq -0x3858(%rbp), %rdx
movq %rsp, %rdi
movl $0xb1, %ecx
leaq -0x3848(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movq -0x7300(%rbp), %rdi
leaq -0x9f8(%rbp), %rsi
callq 0x7c400
movq -0x7200(%rbp), %rdi
movsd 0x11b8(%rdi), %xmm0
movsd %xmm0, -0x970(%rbp)
addq $0x10, %rdi
callq 0x526f0
movq -0x7200(%rbp), %rax
testb $0x1, 0x11c0(%rax)
je 0x7b3b8
movq -0x7200(%rbp), %rdi
movsd -0x970(%rbp), %xmm0
movq -0x10(%rbp), %rdx
movq -0x18(%rbp), %rcx
leaq -0x958(%rbp), %rsi
callq 0x7a640
movq -0x958(%rbp), %rdi
callq 0x7c4c0
movq %rax, -0x3860(%rbp)
movsd -0x970(%rbp), %xmm0
movq -0x3860(%rbp), %rsi
leaq -0x5b8(%rbp), %rdi
leaq -0x9f8(%rbp), %rdx
callq 0x7cb80
leaq -0x3de8(%rbp), %rdi
leaq -0x5b8(%rbp), %rsi
movl $0x588, %edx            # imm = 0x588
callq 0x63a0
movq -0x958(%rbp), %rdi
callq 0x7c4c0
movq -0x7200(%rbp), %rdi
movq %rax, -0x3df0(%rbp)
movsd -0x970(%rbp), %xmm0
movsd %xmm0, -0x7338(%rbp)
movsd 0x11c8(%rdi), %xmm0
movsd %xmm0, -0x7330(%rbp)
movsd 0x1200(%rdi), %xmm0
movsd %xmm0, -0x7328(%rbp)
addq $0xe80, %rdi            # imm = 0xE80
callq 0x7c4f0
movsd -0x7338(%rbp), %xmm0
movsd -0x7330(%rbp), %xmm1
movsd -0x7328(%rbp), %xmm2
movq %rax, -0x3df8(%rbp)
movq -0x3df0(%rbp), %rax
movq %rax, -0x7320(%rbp)
movq -0x3df8(%rbp), %rdx
movq %rsp, %rdi
movl $0xb1, %ecx
leaq -0x3de8(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movq -0x7320(%rbp), %rdi
leaq -0x9f8(%rbp), %rsi
callq 0x7c400
movq -0x7200(%rbp), %rax
movsd 0x11c8(%rax), %xmm0
movsd %xmm0, -0x970(%rbp)
movq %rax, %rdi
addq $0x10, %rdi
movsd 0x11d0(%rax), %xmm0
callq 0x52740
movq -0x7200(%rbp), %rax
testb $0x1, 0x1198(%rax)
je 0x7b52b
movq -0x7200(%rbp), %rdi
movsd -0x970(%rbp), %xmm0
movq -0x10(%rbp), %rdx
movq -0x18(%rbp), %rcx
leaq -0x958(%rbp), %rsi
callq 0x7a640
movq -0x958(%rbp), %rdi
callq 0x7c4c0
movq %rax, -0x3e00(%rbp)
movsd -0x970(%rbp), %xmm0
movq -0x3e00(%rbp), %rsi
leaq -0x5b8(%rbp), %rdi
leaq -0x9f8(%rbp), %rdx
callq 0x7cb80
leaq -0x4388(%rbp), %rdi
leaq -0x5b8(%rbp), %rsi
movl $0x588, %edx            # imm = 0x588
callq 0x63a0
movq -0x958(%rbp), %rdi
callq 0x7c4c0
movq -0x7200(%rbp), %rdi
movq %rax, -0x4390(%rbp)
movsd -0x970(%rbp), %xmm0
movsd %xmm0, -0x7358(%rbp)
movsd 0x11a0(%rdi), %xmm0
movsd %xmm0, -0x7350(%rbp)
movsd 0x1200(%rdi), %xmm0
movsd %xmm0, -0x7348(%rbp)
addq $0xe80, %rdi            # imm = 0xE80
callq 0x7c4f0
movsd -0x7358(%rbp), %xmm0
movsd -0x7350(%rbp), %xmm1
movsd -0x7348(%rbp), %xmm2
movq %rax, -0x4398(%rbp)
movq -0x4390(%rbp), %rax
movq %rax, -0x7340(%rbp)
movq -0x4398(%rbp), %rdx
movq %rsp, %rdi
movl $0xb1, %ecx
leaq -0x4388(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movq -0x7340(%rbp), %rdi
leaq -0x9f8(%rbp), %rsi
callq 0x7c400
movq -0x7200(%rbp), %rax
movsd 0x11a0(%rax), %xmm0
movsd %xmm0, -0x970(%rbp)
movq %rax, %rdi
addq $0x10, %rdi
movsd 0x11a8(%rax), %xmm0
callq 0x52790
movq -0x20(%rbp), %rdi
leaq -0x9f8(%rbp), %rsi
movl $0x70, %edx
callq 0x63a0
movq -0x7200(%rbp), %rax
testb $0x1, 0x11d8(%rax)
jne 0x7b663
movq -0x7200(%rbp), %rdi
movsd -0x970(%rbp), %xmm0
movq -0x10(%rbp), %rdx
movq -0x18(%rbp), %rcx
leaq -0x958(%rbp), %rsi
callq 0x7a640
movq -0x958(%rbp), %rdi
callq 0x7c4c0
movq %rax, -0x43a0(%rbp)
movsd -0x970(%rbp), %xmm0
movq -0x43a0(%rbp), %rsi
leaq -0x5b8(%rbp), %rdi
leaq -0x9f8(%rbp), %rdx
callq 0x7cb80
leaq -0x4928(%rbp), %rdi
leaq -0x5b8(%rbp), %rsi
movl $0x588, %edx            # imm = 0x588
callq 0x63a0
movq -0x958(%rbp), %rdi
callq 0x7c4c0
movq -0x7200(%rbp), %rdi
movq %rax, -0x4930(%rbp)
movsd -0x970(%rbp), %xmm0
movsd %xmm0, -0x7378(%rbp)
movsd 0x11f8(%rdi), %xmm0
movsd %xmm0, -0x7370(%rbp)
movsd 0x1200(%rdi), %xmm0
movsd %xmm0, -0x7368(%rbp)
addq $0xe80, %rdi            # imm = 0xE80
callq 0x7c4f0
movsd -0x7378(%rbp), %xmm0
movsd -0x7370(%rbp), %xmm1
movsd -0x7368(%rbp), %xmm2
movq %rax, -0x4938(%rbp)
movq -0x4930(%rbp), %rax
movq %rax, -0x7360(%rbp)
movq -0x4938(%rbp), %rdx
movq %rsp, %rdi
movl $0xb1, %ecx
leaq -0x4928(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movq -0x7360(%rbp), %rdi
leaq -0x9f8(%rbp), %rsi
callq 0x7c400
jmp 0x7bdcc
movq -0x7200(%rbp), %rax
testb $0x1, 0x11d9(%rax)
je 0x7ba1e
movq -0x7200(%rbp), %rsi
addq $0x10, %rsi
leaq -0x57b0(%rbp), %rdi
callq 0x7c520
movq -0x10(%rbp), %rsi
leaq -0x57f8(%rbp), %rdi
callq 0x7cb10
jmp 0x7b6a0
movq -0x20(%rbp), %rax
movups 0x60(%rax), %xmm0
movaps %xmm0, -0x5810(%rbp)
movups 0x50(%rax), %xmm0
movaps %xmm0, -0x5820(%rbp)
movups 0x40(%rax), %xmm0
movaps %xmm0, -0x5830(%rbp)
movups (%rax), %xmm0
movups 0x10(%rax), %xmm1
movups 0x20(%rax), %xmm2
movups 0x30(%rax), %xmm3
movaps %xmm3, -0x5840(%rbp)
movaps %xmm2, -0x5850(%rbp)
movaps %xmm1, -0x5860(%rbp)
movaps %xmm0, -0x5870(%rbp)
leaq -0x5b40(%rbp), %rdi
leaq -0x57b0(%rbp), %rsi
callq 0x44030
jmp 0x7b705
movq -0x7200(%rbp), %rax
testb $0x1, 0x1180(%rax)
je 0x7b7b9
movl $0x20, %edi
callq 0x6430
movq %rax, -0x7380(%rbp)
jmp 0x7b72c
movq -0x7380(%rbp), %rdi
movq -0x7200(%rbp), %rsi
addq $0x10, %rsi
movq -0x18(%rbp), %rcx
leaq -0x57f8(%rbp), %rdx
callq 0x6eb40
jmp 0x7b750
movq -0x7380(%rbp), %rax
movq %rax, -0x958(%rbp)
jmp 0x7b828
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x960(%rbp)
movl %eax, -0x964(%rbp)
jmp 0x7ba0d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x960(%rbp)
movl %eax, -0x964(%rbp)
jmp 0x7ba01
movq -0x7380(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x960(%rbp)
movl %eax, -0x964(%rbp)
movl $0x20, %esi
callq 0x6440
jmp 0x7ba01
movl $0x20, %edi
callq 0x6430
movq %rax, -0x7388(%rbp)
jmp 0x7b7cc
movq -0x7388(%rbp), %rdi
movq -0x7200(%rbp), %rsi
addq $0x10, %rsi
movq -0x18(%rbp), %rcx
leaq -0x57f8(%rbp), %rdx
callq 0x65820
jmp 0x7b7f0
movq -0x7388(%rbp), %rax
movq %rax, -0x958(%rbp)
jmp 0x7b828
movq -0x7388(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x960(%rbp)
movl %eax, -0x964(%rbp)
movl $0x20, %esi
callq 0x6440
jmp 0x7ba01
leaq -0x60c8(%rbp), %rdi
movq %rdi, -0x73b0(%rbp)
leaq -0x5b8(%rbp), %rsi
movl $0x588, %edx            # imm = 0x588
callq 0x63a0
movq -0x958(%rbp), %rdi
callq 0x7c4c0
movq %rax, %rcx
movq -0x7200(%rbp), %rax
movq %rcx, -0x60d0(%rbp)
movsd -0x970(%rbp), %xmm0
movsd %xmm0, -0x73a8(%rbp)
movsd 0x11f8(%rax), %xmm0
movsd %xmm0, -0x73a0(%rbp)
movsd 0x1200(%rax), %xmm0
movsd %xmm0, -0x7398(%rbp)
leaq -0x5b40(%rbp), %rdi
callq 0x7c4f0
movq -0x73b0(%rbp), %rsi
movsd -0x73a8(%rbp), %xmm0
movsd -0x73a0(%rbp), %xmm1
movsd -0x7398(%rbp), %xmm2
movq %rax, -0x60d8(%rbp)
movq -0x60d0(%rbp), %rax
movq %rax, -0x7390(%rbp)
movq -0x60d8(%rbp), %rdx
movq %rsp, %rdi
movl $0xb1, %ecx
rep  movsq (%rsi), %es:(%rdi)
movq -0x7390(%rbp), %rdi
leaq -0x5870(%rbp), %rsi
callq 0x7c400
jmp 0x7b8fb
xorps %xmm0, %xmm0
movsd %xmm0, -0x60e0(%rbp)
movl $0x0, -0x60e4(%rbp)
movslq -0x60e4(%rbp), %rax
movq %rax, -0x73b8(%rbp)
leaq -0x5b40(%rbp), %rdi
addq $0x1b0, %rdi            # imm = 0x1B0
callq 0x4b5f0
movq %rax, %rcx
movq -0x73b8(%rbp), %rax
cmpq %rcx, %rax
jae 0x7b9e7
leaq -0x5990(%rbp), %rdi
movslq -0x60e4(%rbp), %rsi
callq 0x4a540
movq %rax, %rdi
addq $0x30, %rdi
movl $0x2, %esi
callq 0x372d0
movq %rax, -0x73c0(%rbp)
jmp 0x7b971
movq -0x73c0(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x60f0(%rbp)
movsd -0x60e0(%rbp), %xmm1
movsd -0x60f0(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x7b9ac
movsd -0x60f0(%rbp), %xmm0
movsd %xmm0, -0x60e0(%rbp)
jmp 0x7b9d1
leaq -0x5b40(%rbp), %rdi
addq $0x8, %rdi
movslq -0x60e4(%rbp), %rsi
callq 0x27d90
movsd (%rax), %xmm0
movsd %xmm0, -0x978(%rbp)
jmp 0x7b9e7
jmp 0x7b9d3
movl -0x60e4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x60e4(%rbp)
jmp 0x7b910
leaq -0x5b40(%rbp), %rdi
callq 0x79ae0
leaq -0x57b0(%rbp), %rdi
callq 0x77d90
jmp 0x7ba35
leaq -0x5b40(%rbp), %rdi
callq 0x79ae0
leaq -0x57b0(%rbp), %rdi
callq 0x77d90
jmp 0x7bdd5
movq -0x7200(%rbp), %rax
movsd 0x11e0(%rax), %xmm0
movsd %xmm0, -0x978(%rbp)
movq -0x7200(%rbp), %rdi
movsd -0x970(%rbp), %xmm0
movq -0x10(%rbp), %rdx
movq -0x18(%rbp), %rcx
leaq -0x958(%rbp), %rsi
callq 0x7a640
movq -0x958(%rbp), %rdi
callq 0x7c4c0
movq %rax, -0x60f8(%rbp)
movsd -0x970(%rbp), %xmm0
movq -0x60f8(%rbp), %rsi
leaq -0x5b8(%rbp), %rdi
leaq -0x9f8(%rbp), %rdx
callq 0x7cb80
leaq -0x6680(%rbp), %rdi
leaq -0x5b8(%rbp), %rsi
movl $0x588, %edx            # imm = 0x588
callq 0x63a0
movq -0x958(%rbp), %rdi
callq 0x7c4c0
movq -0x7200(%rbp), %rdi
movq %rax, -0x6688(%rbp)
movsd -0x970(%rbp), %xmm0
movsd %xmm0, -0x73e0(%rbp)
movsd -0x978(%rbp), %xmm0
movsd %xmm0, -0x73d8(%rbp)
movsd 0x1200(%rdi), %xmm0
movsd %xmm0, -0x73d0(%rbp)
addq $0xe80, %rdi            # imm = 0xE80
callq 0x7c4f0
movsd -0x73e0(%rbp), %xmm0
movsd -0x73d8(%rbp), %xmm1
movsd -0x73d0(%rbp), %xmm2
movq %rax, -0x6690(%rbp)
movq -0x6688(%rbp), %rax
movq %rax, -0x73c8(%rbp)
movq -0x6690(%rbp), %rdx
movq %rsp, %rdi
movl $0xb1, %ecx
leaq -0x6680(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movq -0x73c8(%rbp), %rdi
leaq -0x9f8(%rbp), %rsi
callq 0x7c400
movsd -0x978(%rbp), %xmm0
movsd %xmm0, -0x970(%rbp)
leaq -0x6940(%rbp), %rdi
leaq -0x6941(%rbp), %rsi
callq 0x7cbe0
movq -0x7200(%rbp), %rdi
addq $0x10, %rdi
callq 0x527e0
movq -0x7200(%rbp), %rsi
addq $0x10, %rsi
movq -0x10(%rbp), %rdx
movq -0x18(%rbp), %rcx
leaq -0x6968(%rbp), %rdi
callq 0x63670
movq -0x7200(%rbp), %rax
testb $0x1, 0x11e8(%rax)
je 0x7bd21
leaq -0x6c18(%rbp), %rdi
leaq -0x6940(%rbp), %rsi
callq 0x7cd30
leaq -0x6c38(%rbp), %rdi
leaq -0x6968(%rbp), %rsi
callq 0x7cd60
movq -0x7200(%rbp), %rdi
movsd -0x970(%rbp), %xmm0
movsd %xmm0, -0x7410(%rbp)
movsd 0x11f0(%rdi), %xmm0
movsd %xmm0, -0x7408(%rbp)
movsd -0x988(%rbp), %xmm0
movsd %xmm0, -0x7400(%rbp)
addq $0xe80, %rdi            # imm = 0xE80
callq 0x7c4f0
movsd -0x7410(%rbp), %xmm0
movsd -0x7408(%rbp), %xmm1
movsd -0x7400(%rbp), %xmm2
movq %rax, -0x6c40(%rbp)
movq -0x6c40(%rbp), %rcx
leaq -0x6c18(%rbp), %rdi
leaq -0x6c38(%rbp), %rsi
leaq -0x9f8(%rbp), %rdx
callq 0x7cc90
movq -0x7200(%rbp), %rdi
addq $0x10, %rdi
callq 0x527e0
leaq -0x6ef0(%rbp), %rdi
leaq -0x6940(%rbp), %rsi
callq 0x7cd30
leaq -0x6f10(%rbp), %rdi
leaq -0x6968(%rbp), %rsi
callq 0x7cd60
movq -0x7200(%rbp), %rdi
movsd 0x11f0(%rdi), %xmm0
movsd %xmm0, -0x73f8(%rbp)
movsd 0x11f8(%rdi), %xmm0
movsd %xmm0, -0x73f0(%rbp)
movsd -0x988(%rbp), %xmm0
movsd %xmm0, -0x73e8(%rbp)
addq $0xe80, %rdi            # imm = 0xE80
callq 0x7c4f0
movsd -0x73f8(%rbp), %xmm0
movsd -0x73f0(%rbp), %xmm1
movsd -0x73e8(%rbp), %xmm2
movq %rax, -0x6f18(%rbp)
movq -0x6f18(%rbp), %rcx
leaq -0x6ef0(%rbp), %rdi
leaq -0x6f10(%rbp), %rsi
leaq -0x9f8(%rbp), %rdx
callq 0x7cc90
jmp 0x7bdca
leaq -0x71c8(%rbp), %rdi
leaq -0x6940(%rbp), %rsi
callq 0x7cd30
leaq -0x71e8(%rbp), %rdi
leaq -0x6968(%rbp), %rsi
callq 0x7cd60
movq -0x7200(%rbp), %rdi
movsd -0x970(%rbp), %xmm0
movsd %xmm0, -0x7428(%rbp)
movsd 0x11f8(%rdi), %xmm0
movsd %xmm0, -0x7420(%rbp)
movsd -0x988(%rbp), %xmm0
movsd %xmm0, -0x7418(%rbp)
addq $0xe80, %rdi            # imm = 0xE80
callq 0x7c4f0
movsd -0x7428(%rbp), %xmm0
movsd -0x7420(%rbp), %xmm1
movsd -0x7418(%rbp), %xmm2
movq %rax, -0x71f0(%rbp)
movq -0x71f0(%rbp), %rcx
leaq -0x71c8(%rbp), %rdi
leaq -0x71e8(%rbp), %rsi
leaq -0x9f8(%rbp), %rdx
callq 0x7cc90
jmp 0x7bdcc
addq $0x79b0, %rsp           # imm = 0x79B0
popq %rbp
retq
movq -0x960(%rbp), %rdi
callq 0x6760
nopw %cs:(%rax,%rax)
nopl (%rax,%rax)