text:
julia> [RpcApi.SimpleOrganism(0x000000000004dd8f,:(function (o::Creature.Organism,)
        local var_229::Int64 = 4656891210541358294
        local var_197::Int8 = 93
        function func_196(var_195::Int8=-12)
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_195))
            return var_195
        end
        local var_161::Int8 = 81
        local var_131::Int16 = 20703
        local var_125::Bool = true
        local var_82::Int16 = -28253
        function func_63(var_62::Int64=-5487471262987408691)
            local var_223::Int8 = 17
            Creature.stepUp(o)
            Creature.stepUp(o)
            if var_223 >= var_223
                Creature.stepUp(o)
                Creature.stepUp(o)
                Creature.stepUp(o)
            end
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.stepUp(o)
            return var_62
        end
        local var_55::Int64 = 8062249648076403993
        function func_45(var_43::String="D42FzkNp",var_44::String="QVktoUuw")
            Creature.stepLeft(o)
            if var_43 === var_43
            end
            return var_43
        end
        function func_25(var_24::Int64=5926471544133193903)
            Creature.stepRight(o)
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.stepLeft(o)
            return var_24
        end
        function func_9(var_8::Int8=-18)
            local var_208::Int16 = -26568
            local var_123::Int64 = 2850089338817388517
            local var_85::Int16 = -29091
            local var_76::Int64 = -8364194871863581978
            local var_57::Bool = true
            local var_28::Int64 = -5547387289894786475
            local var_26::String = "zSGt1MST"
            local var_16::Bool = true
            local var_14::Int8 = 115
            local var_13::Int16 = 31438
            Creature.stepLeft(o)
            o.mem[var_208] = var_13
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.stepUp(o)
            o.mem[var_85] = var_13
            Creature.eatUp(o,Int(var_8))
            Creature.eatRight(o,Int(var_14))
            o.mem[var_13] = var_13
            Creature.eatUp(o,Int(var_8))
            Creature.eatLeft(o,Int(var_14))
            Creature.stepLeft(o)
            Creature.stepDown(o)
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_8))
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            Creature.stepDown(o)
            Creature.eatLeft(o,Int(var_8))
            Creature.eatLeft(o,Int(var_14))
            Creature.eatDown(o,Int(var_8))
            Creature.eatUp(o,Int(var_14))
            Creature.eatDown(o,Int(var_14))
            Creature.eatDown(o,Int(var_8))
            Creature.stepDown(o)
            Creature.eatRight(o,Int(var_14))
            var_85 = if haskey(o.mem,var_13)
                    o.mem[var_13]
                else
                    var_85
                end
            Creature.eatDown(o,Int(var_14))
            if var_28 !== var_28
                local var_228::Int16 = 18507
                local var_222::Bool = false
                Creature.stepUp(o)
                Creature.stepDown(o)
            end
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            var_76 = Int(Creature.getEnergy(o,Int(var_13),Int(var_85)))
            Creature.eatDown(o,Int(var_14))
            Creature.eatDown(o,Int(var_14))
            Creature.stepLeft(o)
            var_13 = var_85 * var_13
            Creature.eatDown(o,Int(var_14))
            Creature.eatUp(o,Int(var_14))
            Creature.stepDown(o)
            if var_8 !== var_14
                local var_227::Bool = true
                Creature.stepUp(o)
            end
            Creature.eatRight(o,Int(var_8))
            Creature.eatDown(o,Int(var_8))
            Creature.eatDown(o,Int(var_14))
            if var_123 === var_123
                local var_224::Int16 = -25190
                Creature.stepDown(o)
            end
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            Creature.eatDown(o,Int(var_14))
            Creature.eatLeft(o,Int(var_14))
            if var_16 === var_16
                Creature.stepDown(o)
                Creature.stepRight(o)
                Creature.stepRight(o)
            end
            Creature.eatRight(o,Int(var_8))
            Creature.eatRight(o,Int(var_14))
            var_26 = var_26 * var_26
            var_57 = var_57 | var_16
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.eatLeft(o,Int(var_8))
            return var_8
        end
        local var_1::Int8 = 59
        function func_135(var_134::Int64=6349986163145892178)
            return var_134
        end
        var_12 = func_9(var_1)
        var_12 = func_9(var_12)
        var_15 = func_9(var_12)
        var_1 = func_9(var_1)
        var_15 = func_9(var_1)
        var_125 = var_125 * var_125
        var_12 = func_9(var_15)
        var_12 = func_9(var_1)
        var_1 = func_9(var_1)
        var_34 = Int(Creature.getEnergy(o,Int(var_131),Int(var_131)))
        var_12 = func_9(var_12)
        Creature.stepUp(o)
        Creature.stepRight(o)
        var_55 = var_34 * var_34
        Creature.stepUp(o)
        Creature.eatRight(o,Int(var_12))
        Creature.stepRight(o)
        Creature.stepRight(o)
        Creature.stepRight(o)
        var_12 = var_1 * var_15
        var_12 = var_12 / var_197
        Creature.stepRight(o)
        o.mem[var_131] = var_131
        Creature.eatLeft(o,Int(var_1))
        Creature.eatDown(o,Int(var_1))
        var_34 = func_25(var_34)
        Creature.stepUp(o)
        var_55 = var_55 - var_55
        var_55 = func_63(var_55)
        var_55 = func_63(var_34)
        Creature.eatUp(o,Int(var_197))
        var_55 = var_34 / var_34
        Creature.stepDown(o)
        var_131 = var_131 / var_131
        var_55 = Int(Creature.getEnergy(o,Int(var_82),Int(var_131)))
        Creature.stepUp(o)
        return true
    end),[100,300,95,0,1,1,1],0,9210,6,16583859,0x0000012c,Dict(20703=>20703,-2660=>-29091,0=>0,31438=>31438,-5320=>-5320,-26568=>31438,-26047=>13442,-572=>-572,17537=>-14079,-28253=>-28253,-29091=>31438,1=>1),[15,292],151),RpcApi.SimpleOrganism(0x000000000004dd88,:(function (o::Creature.Organism,)
        local var_229::Int64 = 4656891210541358294
        local var_197::Int8 = 93
        function func_196(var_195::Int8=-12)
            return var_195
        end
        local var_161::Int8 = 81
        local var_131::Int16 = 20703
        local var_125::Bool = true
        local var_82::Int16 = -28253
        function func_63(var_62::Int64=-5487471262987408691)
            local var_223::Int8 = 17
            Creature.stepUp(o)
            Creature.stepUp(o)
            if var_223 >= var_223
                Creature.stepUp(o)
                Creature.stepUp(o)
                Creature.stepUp(o)
            end
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.stepUp(o)
            return var_62
        end
        local var_55::Int64 = 8062249648076403993
        function func_45(var_43::String="D42FzkNp",var_44::String="QVktoUuw")
            if var_43 === var_43
            end
            return var_43
        end
        function func_25(var_24::Int64=5926471544133193903)
            Creature.stepRight(o)
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.stepLeft(o)
            return var_24
        end
        function func_9(var_8::Int8=-18)
            local var_208::Int16 = -26568
            local var_123::Int64 = 2850089338817388517
            local var_85::Int16 = -29091
            local var_76::Int64 = -8364194871863581978
            local var_57::Bool = true
            local var_28::Int64 = -5547387289894786475
            local var_26::String = "zSGt1MST"
            local var_16::Bool = true
            local var_14::Int8 = 115
            local var_13::Int16 = 31438
            Creature.stepLeft(o)
            o.mem[var_208] = var_13
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.stepUp(o)
            o.mem[var_85] = var_13
            Creature.eatLeft(o,Int(var_8))
            Creature.eatUp(o,Int(var_8))
            Creature.eatRight(o,Int(var_14))
            o.mem[var_13] = var_13
            Creature.eatUp(o,Int(var_8))
            Creature.eatLeft(o,Int(var_14))
            Creature.stepLeft(o)
            Creature.stepDown(o)
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_8))
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            Creature.stepDown(o)
            Creature.eatLeft(o,Int(var_8))
            Creature.eatLeft(o,Int(var_14))
            Creature.eatDown(o,Int(var_8))
            Creature.eatUp(o,Int(var_14))
            Creature.eatDown(o,Int(var_14))
            Creature.eatDown(o,Int(var_8))
            Creature.stepDown(o)
            Creature.eatRight(o,Int(var_14))
            var_85 = if haskey(o.mem,var_13)
                    o.mem[var_13]
                else
                    var_85
                end
            Creature.eatDown(o,Int(var_14))
            if var_28 !== var_28
                local var_228::Int16 = 18507
                local var_222::Bool = false
                Creature.stepDown(o)
            end
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            var_76 = Int(Creature.getEnergy(o,Int(var_13),Int(var_85)))
            Creature.eatDown(o,Int(var_14))
            Creature.eatDown(o,Int(var_14))
            Creature.stepLeft(o)
            var_13 = var_85 * var_13
            Creature.eatDown(o,Int(var_14))
            Creature.eatUp(o,Int(var_14))
            Creature.stepDown(o)
            if var_8 !== var_14
                local var_227::Bool = true
                Creature.stepUp(o)
            end
            Creature.eatRight(o,Int(var_8))
            Creature.eatDown(o,Int(var_8))
            Creature.eatDown(o,Int(var_14))
            if var_123 === var_123
                local var_224::Int16 = -25190
                Creature.stepDown(o)
            end
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            Creature.eatDown(o,Int(var_14))
            Creature.eatLeft(o,Int(var_14))
            if var_16 === var_16
                Creature.stepDown(o)
                Creature.stepRight(o)
                Creature.stepRight(o)
            end
            Creature.eatRight(o,Int(var_8))
            Creature.eatRight(o,Int(var_14))
            var_26 = var_26 * var_26
            var_57 = var_57 | var_16
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.eatLeft(o,Int(var_8))
            return var_8
        end
        local var_1::Int8 = 59
        function func_135(var_134::Int64=6349986163145892178)
            return var_134
        end
        Creature.stepUp(o)
        var_12 = func_9(var_1)
        var_12 = func_9(var_12)
        var_15 = func_9(var_12)
        var_1 = func_9(var_1)
        var_15 = func_9(var_1)
        var_125 = var_125 * var_125
        var_12 = func_9(var_15)
        var_12 = func_9(var_1)
        var_1 = func_9(var_1)
        var_34 = Int(Creature.getEnergy(o,Int(var_131),Int(var_131)))
        var_12 = func_9(var_12)
        Creature.stepUp(o)
        Creature.stepRight(o)
        var_82 = if haskey(o.mem,var_82)
                o.mem[var_82]
            else
                var_82
            end
        var_55 = var_34 * var_34
        Creature.stepUp(o)
        Creature.stepRight(o)
        Creature.stepRight(o)
        Creature.stepRight(o)
        var_12 = var_1 * var_15
        var_12 = var_12 / var_197
        Creature.stepRight(o)
        if var_82 == var_82
        end
        Creature.eatLeft(o,Int(var_1))
        Creature.eatDown(o,Int(var_1))
        var_34 = func_25(var_34)
        Creature.stepUp(o)
        var_55 = var_55 - var_55
        var_55 = func_63(var_55)
        var_55 = func_63(var_34)
        Creature.eatUp(o,Int(var_197))
        var_55 = var_34 / var_34
        Creature.stepRight(o)
        var_131 = var_131 / var_131
        var_55 = Int(Creature.getEnergy(o,Int(var_82),Int(var_131)))
        Creature.stepUp(o)
        return true
    end),[100,300,95,0,1,1,1],0,9210,6,16429730,0x0000012c,Dict(20703=>20703,-2660=>-29091,0=>0,31438=>31438,-5320=>-5320,-26568=>31438,-26047=>13442,-572=>-572,17537=>-14079,-28253=>-28253,-29091=>31438,1=>1),[15,291],149),RpcApi.SimpleOrganism(0x000000000004dd7e,:(function (o::Creature.Organism,)
        local var_229::Int64 = 4656891210541358294
        local var_197::Int8 = 93
        function func_196(var_195::Int8=-12)
            Creature.eatLeft(o,Int(var_195))
            Creature.eatUp(o,Int(var_195))
            for i::Int8 = 1:div(var_195,_LOOP_STEPS_DIVIDER)
            end
            return var_195
        end
        local var_161::Int8 = 81
        local var_131::Int16 = 20703
        local var_125::Bool = true
        local var_82::Int16 = -28253
        function func_63(var_62::Int64=-5487471262987408691)
            local var_223::Int8 = 17
            Creature.stepUp(o)
            Creature.stepUp(o)
            if var_223 >= var_223
                Creature.stepUp(o)
                Creature.stepUp(o)
            end
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.stepUp(o)
            return var_62
        end
        local var_55::Int64 = 8062249648076403993
        function func_45(var_43::String="D42FzkNp",var_44::String="QVktoUuw")
            if var_43 === var_43
            end
            Creature.stepLeft(o)
            return var_43
        end
        function func_25(var_24::Int64=5926471544133193903)
            Creature.stepRight(o)
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.stepLeft(o)
            return var_24
        end
        function func_9(var_8::Int8=-18)
            local var_208::Int16 = -26568
            local var_123::Int64 = 2850089338817388517
            local var_85::Int16 = -29091
            local var_76::Int64 = -8364194871863581978
            local var_57::Bool = true
            local var_28::Int64 = -5547387289894786475
            local var_26::String = "zSGt1MST"
            local var_16::Bool = true
            local var_14::Int8 = 115
            local var_13::Int16 = 31438
            Creature.stepLeft(o)
            o.mem[var_208] = var_13
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.stepUp(o)
            o.mem[var_85] = var_13
            Creature.eatUp(o,Int(var_8))
            Creature.eatRight(o,Int(var_14))
            o.mem[var_13] = var_13
            Creature.eatUp(o,Int(var_8))
            Creature.eatLeft(o,Int(var_14))
            Creature.stepLeft(o)
            Creature.stepDown(o)
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_8))
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            Creature.stepDown(o)
            Creature.eatLeft(o,Int(var_8))
            Creature.eatLeft(o,Int(var_14))
            Creature.eatDown(o,Int(var_8))
            Creature.eatUp(o,Int(var_14))
            Creature.eatDown(o,Int(var_14))
            Creature.eatDown(o,Int(var_8))
            Creature.stepDown(o)
            Creature.eatRight(o,Int(var_14))
            var_85 = if haskey(o.mem,var_13)
                    o.mem[var_13]
                else
                    var_85
                end
            Creature.eatDown(o,Int(var_14))
            if var_28 !== var_28
                local var_228::Int16 = 18507
                local var_222::Bool = false
                Creature.stepUp(o)
                Creature.stepDown(o)
            end
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            var_76 = Int(Creature.getEnergy(o,Int(var_13),Int(var_85)))
            Creature.eatDown(o,Int(var_14))
            Creature.eatDown(o,Int(var_14))
            Creature.stepLeft(o)
            var_13 = var_85 * var_13
            Creature.eatDown(o,Int(var_14))
            Creature.eatUp(o,Int(var_14))
            Creature.stepDown(o)
            if var_8 !== var_14
                local var_227::Bool = true
                Creature.stepUp(o)
            end
            Creature.eatRight(o,Int(var_8))
            Creature.eatDown(o,Int(var_8))
            Creature.eatDown(o,Int(var_14))
            if var_123 === var_123
                local var_224::Int16 = -25190
                Creature.stepDown(o)
            end
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            Creature.eatDown(o,Int(var_14))
            Creature.eatLeft(o,Int(var_14))
            if var_16 === var_16
                Creature.stepDown(o)
                Creature.stepRight(o)
                Creature.stepRight(o)
            end
            Creature.eatRight(o,Int(var_8))
            Creature.eatRight(o,Int(var_14))
            var_26 = var_26 * var_26
            var_57 = var_57 | var_16
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.eatLeft(o,Int(var_8))
            return var_8
        end
        local var_1::Int8 = 59
        function func_135(var_134::Int64=6349986163145892178)
            return var_134
        end
        Creature.stepUp(o)
        var_12 = func_9(var_1)
        var_131 = if haskey(o.mem,var_82)
                o.mem[var_82]
            else
                var_131
            end
        var_12 = func_9(var_12)
        var_15 = func_9(var_12)
        var_1 = func_9(var_1)
        var_15 = func_9(var_1)
        var_125 = var_125 * var_125
        var_12 = func_9(var_15)
        var_12 = func_9(var_1)
        var_1 = func_9(var_1)
        var_34 = Int(Creature.getEnergy(o,Int(var_131),Int(var_131)))
        var_12 = func_9(var_12)
        Creature.stepUp(o)
        Creature.stepRight(o)
        var_55 = var_34 * var_34
        Creature.stepUp(o)
        Creature.eatRight(o,Int(var_12))
        Creature.stepRight(o)
        Creature.stepRight(o)
        Creature.stepRight(o)
        var_12 = var_1 * var_15
        var_12 = var_12 / var_197
        Creature.stepRight(o)
        o.mem[var_131] = var_131
        Creature.eatLeft(o,Int(var_1))
        Creature.eatDown(o,Int(var_1))
        var_34 = func_25(var_34)
        Creature.stepUp(o)
        var_55 = var_55 - var_55
        var_55 = func_63(var_55)
        var_55 = func_63(var_34)
        Creature.eatUp(o,Int(var_197))
        var_55 = var_34 / var_34
        Creature.stepRight(o)
        var_131 = var_131 / var_131
        var_55 = Int(Creature.getEnergy(o,Int(var_82),Int(var_131)))
        Creature.stepUp(o)
        return true
    end),[100,300,95,0,1,1,1],0,9210,6,15754540,0x00000126,Dict(20703=>20703,-2660=>-29091,0=>0,31438=>31438,-5320=>-5320,-26568=>31438,-26047=>13442,-572=>-572,17537=>-14079,-28253=>-28253,-29091=>31438,1=>1),[11,262],153),RpcApi.SimpleOrganism(0x000000000004df68,:(function (o::Creature.Organism,)
        local var_229::Int64 = 4656891210541358294
        local var_197::Int8 = 93
        function func_196(var_195::Int8=-12)
            local var_230::Int16 = -30347
            Creature.stepLeft(o)
            return var_195
        end
        local var_161::Int8 = 81
        local var_131::Int16 = 20703
        local var_125::Bool = true
        local var_82::Int16 = -28253
        function func_63(var_62::Int64=-5487471262987408691)
            local var_223::Int8 = 17
            Creature.stepUp(o)
            Creature.stepUp(o)
            if var_223 >= var_223
                Creature.stepUp(o)
                Creature.stepUp(o)
                Creature.stepUp(o)
            end
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.stepUp(o)
            return var_62
        end
        local var_55::Int64 = 8062249648076403993
        function func_45(var_43::String="D42FzkNp",var_44::String="QVktoUuw")
            if var_43 === var_43
            end
            return var_43
        end
        function func_25(var_24::Int64=5926471544133193903)
            Creature.stepRight(o)
            Creature.stepUp(o)
            Creature.stepRight(o)
            Creature.stepRight(o)
            return var_24
        end
        function func_9(var_8::Int8=-18)
            local var_208::Int16 = -26568
            local var_123::Int64 = 2850089338817388517
            local var_85::Int16 = -29091
            local var_76::Int64 = -8364194871863581978
            local var_57::Bool = true
            local var_28::Int64 = -5547387289894786475
            local var_26::String = "zSGt1MST"
            local var_16::Bool = true
            local var_14::Int8 = 115
            local var_13::Int16 = 31438
            Creature.stepLeft(o)
            o.mem[var_208] = var_13
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.stepUp(o)
            o.mem[var_85] = var_13
            Creature.eatUp(o,Int(var_8))
            Creature.eatRight(o,Int(var_14))
            o.mem[var_13] = var_13
            Creature.eatUp(o,Int(var_8))
            Creature.eatLeft(o,Int(var_14))
            Creature.stepLeft(o)
            Creature.stepDown(o)
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_8))
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            Creature.stepDown(o)
            Creature.eatLeft(o,Int(var_8))
            Creature.eatLeft(o,Int(var_14))
            Creature.eatDown(o,Int(var_8))
            Creature.eatUp(o,Int(var_14))
            Creature.eatDown(o,Int(var_14))
            Creature.eatDown(o,Int(var_8))
            Creature.stepDown(o)
            Creature.eatRight(o,Int(var_14))
            var_85 = if haskey(o.mem,var_13)
                    o.mem[var_13]
                else
                    var_85
                end
            Creature.eatDown(o,Int(var_14))
            if var_28 !== var_28
                local var_228::Int16 = 18507
                local var_222::Bool = false
                Creature.stepUp(o)
                Creature.stepDown(o)
            end
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            var_76 = Int(Creature.getEnergy(o,Int(var_13),Int(var_85)))
            Creature.eatDown(o,Int(var_14))
            Creature.eatDown(o,Int(var_14))
            Creature.stepLeft(o)
            var_13 = var_85 * var_13
            Creature.eatDown(o,Int(var_14))
            Creature.eatUp(o,Int(var_14))
            Creature.stepDown(o)
            if var_8 !== var_14
                local var_227::Bool = true
                Creature.stepUp(o)
            end
            Creature.eatRight(o,Int(var_8))
            Creature.eatDown(o,Int(var_8))
            Creature.eatDown(o,Int(var_14))
            if var_123 === var_123
                local var_224::Int16 = -25190
                Creature.stepDown(o)
            end
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            Creature.eatDown(o,Int(var_14))
            Creature.eatLeft(o,Int(var_14))
            if var_16 === var_16
                Creature.stepDown(o)
                Creature.stepRight(o)
                Creature.stepRight(o)
            end
            Creature.eatRight(o,Int(var_8))
            Creature.eatRight(o,Int(var_14))
            var_26 = var_26 * var_26
            var_57 = var_57 | var_16
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.eatLeft(o,Int(var_8))
            return var_8
        end
        local var_1::Int8 = 59
        function func_135(var_134::Int64=6349986163145892178)
            return var_134
        end
        Creature.stepUp(o)
        var_12 = func_9(var_1)
        var_12 = func_9(var_12)
        var_15 = func_9(var_12)
        var_1 = func_9(var_1)
        var_15 = func_9(var_1)
        var_125 = var_125 * var_125
        var_12 = func_9(var_15)
        var_12 = func_9(var_1)
        var_1 = func_9(var_1)
        var_34 = Int(Creature.getEnergy(o,Int(var_131),Int(var_131)))
        var_12 = func_9(var_12)
        Creature.stepUp(o)
        Creature.stepRight(o)
        var_55 = var_34 * var_34
        Creature.stepUp(o)
        Creature.stepRight(o)
        Creature.stepRight(o)
        Creature.stepRight(o)
        var_12 = var_1 * var_15
        var_12 = var_12 / var_197
        Creature.stepRight(o)
        o.mem[var_131] = var_131
        Creature.eatLeft(o,Int(var_1))
        Creature.eatRight(o,Int(var_1))
        var_34 = func_25(var_34)
        Creature.stepUp(o)
        var_55 = var_55 - var_55
        var_55 = func_63(var_55)
        var_55 = func_63(var_34)
        Creature.eatUp(o,Int(var_197))
        var_55 = var_34 / var_34
        Creature.stepRight(o)
        var_55 = Int(Creature.getEnergy(o,Int(var_131),Int(var_131)))
        var_55 = Int(Creature.getEnergy(o,Int(var_82),Int(var_131)))
        Creature.stepUp(o)
        return true
    end),[100,300,95,0,1,1,1],0,9210,6,15751883,0x0000012f,Dict(20703=>20703,-2660=>-29091,0=>0,31438=>31438,-5320=>-5320,-26568=>31438,-26047=>13442,-572=>-572,17537=>-14079,-28253=>-28253,-29091=>31438,1=>1),[165,276],149),RpcApi.SimpleOrganism(0x000000000004dda7,:(function (o::Creature.Organism,)
        local var_229::Int64 = 4656891210541358294
        local var_197::Int8 = 93
        function func_196(var_195::Int8=-12)
            Creature.eatUp(o,Int(var_195))
            Creature.eatLeft(o,Int(var_195))
            return var_195
        end
        local var_161::Int8 = 81
        local var_131::Int16 = 20703
        local var_125::Bool = true
        local var_82::Int16 = -28253
        function func_63(var_62::Int64=-5487471262987408691)
            local var_223::Int8 = 17
            Creature.stepUp(o)
            Creature.stepUp(o)
            if var_223 >= var_223
                Creature.stepUp(o)
                Creature.stepUp(o)
            end
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.stepUp(o)
            return var_62
        end
        local var_55::Int64 = 8062249648076403993
        function func_45(var_43::String="D42FzkNp",var_44::String="QVktoUuw")
            if var_43 === var_43
                Creature.stepLeft(o)
            end
            Creature.stepLeft(o)
            return var_43
        end
        function func_25(var_24::Int64=5926471544133193903)
            Creature.stepRight(o)
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.stepLeft(o)
            return var_24
        end
        function func_9(var_8::Int8=-18)
            local var_208::Int16 = -26568
            local var_123::Int64 = 2850089338817388517
            local var_85::Int16 = -29091
            local var_76::Int64 = -8364194871863581978
            local var_57::Bool = true
            local var_28::Int64 = -5547387289894786475
            local var_26::String = "zSGt1MST"
            local var_16::Bool = true
            local var_14::Int8 = 115
            local var_13::Int16 = 31438
            Creature.stepLeft(o)
            o.mem[var_208] = var_13
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.stepUp(o)
            o.mem[var_85] = var_13
            Creature.eatUp(o,Int(var_8))
            Creature.eatRight(o,Int(var_14))
            o.mem[var_13] = var_13
            Creature.eatUp(o,Int(var_8))
            Creature.eatLeft(o,Int(var_14))
            Creature.stepLeft(o)
            Creature.stepDown(o)
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_8))
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            Creature.stepDown(o)
            Creature.eatLeft(o,Int(var_8))
            Creature.eatLeft(o,Int(var_14))
            Creature.eatDown(o,Int(var_8))
            Creature.eatUp(o,Int(var_14))
            Creature.eatDown(o,Int(var_14))
            Creature.eatDown(o,Int(var_8))
            Creature.stepDown(o)
            Creature.eatRight(o,Int(var_14))
            var_85 = if haskey(o.mem,var_13)
                    o.mem[var_13]
                else
                    var_85
                end
            Creature.eatDown(o,Int(var_14))
            if var_28 !== var_28
                local var_228::Int16 = 18507
                local var_222::Bool = false
                Creature.stepUp(o)
                Creature.stepDown(o)
            end
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            var_76 = Int(Creature.getEnergy(o,Int(var_13),Int(var_85)))
            Creature.eatDown(o,Int(var_14))
            Creature.eatDown(o,Int(var_14))
            Creature.stepLeft(o)
            Creature.eatDown(o,Int(var_14))
            Creature.eatUp(o,Int(var_14))
            Creature.stepDown(o)
            if var_8 !== var_14
                local var_227::Bool = true
                Creature.stepUp(o)
            end
            Creature.eatRight(o,Int(var_8))
            Creature.eatDown(o,Int(var_8))
            Creature.eatDown(o,Int(var_14))
            if var_123 === var_123
                local var_224::Int16 = -25190
                Creature.stepDown(o)
            end
            Creature.stepDown(o)
            Creature.eatDown(o,Int(var_14))
            Creature.eatDown(o,Int(var_14))
            Creature.eatLeft(o,Int(var_14))
            if var_16 === var_16
                Creature.stepDown(o)
                Creature.stepRight(o)
                Creature.stepRight(o)
            end
            Creature.eatRight(o,Int(var_8))
            Creature.eatRight(o,Int(var_14))
            var_26 = var_26 * var_26
            var_57 = var_57 | var_16
            Creature.stepUp(o)
            Creature.stepUp(o)
            Creature.eatLeft(o,Int(var_8))
            return var_8
        end
        local var_1::Int8 = 59
        function func_135(var_134::Int64=6349986163145892178)
            Creature.stepRight(o)
            return var_134
        end
        Creature.stepUp(o)
        var_12 = func_9(var_1)
        var_12 = func_9(var_12)
        var_15 = func_9(var_12)
        var_1 = func_9(var_1)
        var_15 = func_9(var_1)
        var_125 = var_125 * var_125
        var_12 = func_9(var_15)
        var_12 = func_9(var_1)
        var_1 = func_9(var_1)
        var_34 = Int(Creature.getEnergy(o,Int(var_131),Int(var_131)))
        var_12 = func_9(var_12)
        Creature.stepUp(o)
        Creature.stepRight(o)
        var_55 = var_34 * var_34
        Creature.stepUp(o)
        Creature.eatRight(o,Int(var_12))
        Creature.stepRight(o)
        Creature.stepRight(o)
        Creature.stepRight(o)
        var_12 = var_1 * var_15
        var_12 = var_12 / var_197
        Creature.stepRight(o)
        o.mem[var_131] = var_131
        Creature.eatLeft(o,Int(var_1))
        if var_125 >= var_125
        end
        var_34 = func_25(var_34)
        Creature.stepUp(o)
        var_55 = var_55 - var_55
        var_55 = func_63(var_55)
        var_55 = func_63(var_34)
        Creature.eatUp(o,Int(var_197))
        var_55 = var_34 / var_34
        Creature.stepRight(o)
        var_131 = var_131 / var_131
        var_55 = Int(Creature.getEnergy(o,Int(var_82),Int(var_131)))
        Creature.stepUp(o)
        return true
    end),[100,300,95,0,1,1,1],0,9210,6,14351922,0x0000012c,Dict(20703=>20703,-2660=>-29091,0=>0,31438=>31438,-5320=>-5320,-26568=>31438,-26047=>13442,-572=>-572,17537=>-14079,-28253=>-28253,-29091=>31438,1=>1),[11,261],152)]

max_stars_repo_name: tmptrash/jevo

max_issues_repo_name: tmptrash/jevo

max_forks_repo_name: tmptrash/jevo


text:
"""
    WebDriver

A binding for the [WebDriver](https://w3c.github.io/webdriver) and [JSON Wire Protocol](https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol) for the Julia programing language compatible with the Selenium [WebDriver](https://selenium.dev/documentation/en/webdriver).

[Repository](https://github.com/Nosferican/WebDriver.jl)

# Example
```jldoctest
julia> using WebDriver
```
"""
module WebDriver
    using Base.Filesystem: realpath
    using Base.Iterators: flatten
    using Base64: base64decode
    using Dates: DateTime, datetime2unix, unix2datetime
    using HTTP: HTTP, URI, escapeuri, ExceptionRequest.StatusError
    using JSON3: JSON3, Object
    using Parameters: @unpack
    import Base: show, delete!, getproperty, summary
    import Base.Broadcast: broadcastable
    import JSON3: StructTypes.omitempties
    ENV["WEBDRIVER_HOST"] = get(ENV, "WEBDRIVER_HOST", "localhost")
    ENV["WEBDRIVER_PORT"] = get(ENV, "WEBDRIVER_PORT", "4444")
    for (root, dirs, files) ∈ walkdir(joinpath(@__DIR__))
        foreach(file -> include(joinpath(root, file)), filter!(file -> occursin(r"^\d{2}_\w+\.jl$", file), files))
    end
    export
        # Structs
        Timeouts,
        Proxy,
        Capabilities,
        RemoteWebDriver,
        Session,
        Element,
        WDError,
        Cookie,
        # Commands
        status,
        timeouts,
        timeouts!,
        delete!,
        navigate!,
        current_url,
        back!,
        forward!,
        refresh!,
        document_title,
        window_handle,
        window_close!,
        window!,
        window_handles,
        frame!,
        parent_frame!,
        rect,
        rect!,
        maximize!,
        minimize!,
        active_element,
        Elements,
        isselected,
        element_attr,
        element_css,
        element_text,
        element_tag,
        element_property,
        isenabled,
        click!,
        clear!,
        element_keys!,
        source,
        script!,
        cookie,
        cookies,
        cookie!,
        cookies!,
        moveto!,
        dismiss,
        accept,
        alert_text,
        alert_text!,
        screenshot,
        sessions
end

ext: jl


text:
import Base: adjoint, *, \
import LinearAlgebra: logdet

###### ' ######
adjoint(L::T) where {T <: SymSemiseparableMatrix} = AdjointOperator(L)

## Fix (*) and (\) overloadings. Not nice to have if/else statements
###### * ######
function (*)(L::SymSemiseparableMatrix, x::AbstractArray)
	if typeof(L) <: AdjointOperator
		y = zeros(L.A.n, size(x,2));
		mul!(y, L, x)
		return y
	else
		y = zeros(L.n, size(x,2));
		mul!(y, L, x)
		return y
	end
end

###### \ ######
function (\)(L::SymSemiseparableMatrix, x::AbstractArray)
	if typeof(L) <: AdjointOperator
		y = zeros(L.A.n, size(x,2));
		inv!(y, L, x)
		return y
	else
		y = zeros(L.n, size(x,2));
		inv!(y, L, x)
		return y
	end
end
#### Log-determinant ####
function logdet(L::SymSemiseparableMatrix)
	return newlogdet(L)
end


text:
using ChebyshevExpansions
using Documenter

DocMeta.setdocmeta!(ChebyshevExpansions, :DocTestSetup, :(using ChebyshevExpansions); recursive=true)

makedocs(;
    modules=[ChebyshevExpansions],
    authors="Fernando Peñaranda, Pablo San-Jose",
    repo="https://github.com/fernandopenaranda/ChebyshevExpansions.jl/blob/{commit}{path}#{line}",
    sitename="ChebyshevExpansions.jl",
    format=Documenter.HTML(;
        prettyurls=get(ENV, "CI", "false") == "true",
        canonical="https://fernandopenaranda.github.io/ChebyshevExpansions.jl",
        assets=String[],
    ),
    pages=[
        "Home" => "index.md",
    ],
)

deploydocs(;
    repo="github.com/fernandopenaranda/ChebyshevExpansions.jl",
    devbranch="main",
)

max_stars_repo_name: fernandopenaranda/ChebyshevExpansions

max_issues_repo_name: fernandopenaranda/ChebyshevExpansions

max_forks_repo_name: fernandopenaranda/ChebyshevExpansions


text:
# -*- coding: utf-8 -*-
# ---
# jupyter:
#   jupytext:
#     formats: ipynb,jl:hydrogen
#     text_representation:
#       extension: .jl
#       format_name: hydrogen
#       format_version: '1.3'
#       jupytext_version: 1.11.2
#   kernelspec:
#     display_name: Julia 1.6.2
#     language: julia
#     name: julia-1.6
# ---

# %% [markdown]
# https://discourse.julialang.org/t/solve-ode-with-many-different-initial-conditions/66384

# %%
using DifferentialEquations
using BenchmarkTools
using StaticArrays
using Base.Threads
using PyPlot

# %%
# define system parameters
const Ip = 0.5
const N  = 2
const w  = 0.057
const T  = 2π/w
const F0 = 0.075

# define laser pulse
Fx(t) = F0 * cos(w*t/(2N))^2 * cos(w*t) * (abs(t) < N*T/2)
Fy(t) = F0 * cos(w*t/(2N))^2 * sin(w*t) * (abs(t) < N*T/2)

# define rate
W_adk(F,kd) = exp(-(2.0*(kd^2+2Ip)^1.5)/3F)

# define electron trajectory
const a = 1.0
function traj(u,p,t)
    r3i = (u[1]^2+u[2]^2+a)^(-1.5)
    du1 = u[3]
    du2 = u[4]
    du3 = -u[1]*r3i-Fx(t)
    du4 = -u[2]*r3i-Fy(t)
    @SVector [du1,du2,du3,du4]
end

# define result box
const Px_min = -2.0
const Px_max =  2.0
const Px_num =  200
const Px  = LinRange(Px_min,Px_max,Px_num)
const dPx = (Px_max-Px_min)/(Px_num-1)

const Py_min = -2.0
const Py_max =  2.0
const Py_num =  200
const Py  = LinRange(Py_min,Py_max,Py_num)
const dPy = (Py_max-Py_min)/(Py_num-1)

# define simulation parameters
const Nt = 500
const Nkd = 100
const kd_max = 2.0;

# %%
# classical trajectory simulation
Prob_nthreads = let Prob_nthreads = zeros(Float64,Px_num,Py_num,nthreads())
@time @threads for tr in LinRange(-0.9N*T/2,0.9N*T/2,Nt)
    Fxtr = Fx(tr)
    Fytr = Fy(tr)
    Ftr = hypot(Fxtr,Fytr)
    phi = atan(-Fytr,-Fxtr)
    r0 = Ip/Ftr
    x0 = r0*cos(phi)
    y0 = r0*sin(phi)
    tspan = (tr,N*T/2)
    for kd in LinRange(-kd_max,kd_max,Nkd)
        kx0 = kd*cos(phi+0.5π)
        ky0 = kd*sin(phi+0.5π)
        rate = W_adk(Ftr,kd)

        u0 = @SVector [x0,y0,kx0,ky0]
        Traj = ODEProblem(traj,u0,tspan)
        sol = solve(Traj,Tsit5(),reltol=1e-6,save_everystep=false,save_start=false)
        (x,y,px,py) = sol.u[end]

        E_inf = 0.5*(px^2+py^2)-1/(x^2+y^2+a)
        E_inf >= zero(E_inf) || continue
        pxidx = Int64(round((px-Px[1])/dPx))+1
        pyidx = Int64(round((py-Py[1])/dPy))+1
        checkbounds(Bool,Prob_nthreads,pxidx,pyidx,threadid()) || continue
        @inbounds Prob_nthreads[pxidx,pyidx,threadid()] += rate
    end
end
Prob_nthreads
end
flush(stdout)

Prob = reshape(sum(Prob_nthreads,dims=3),size(Prob_nthreads)[1:2])

# plotting
fig,ax = plt.subplots()
ax.imshow(Prob',extent=(Px[1],Px[end],Py[1],Py[end]),origin="lower")
ax.set_xlim(Px[1],Px[end])
ax.set_ylim(Py[1],Py[end])
ax.set_xlabel("\$p_x\$ (a.u.)")
ax.set_ylabel("\$p_y\$ (a.u.)")
#plt.show()

# %%
Prob_nthreads = let Prob_nthreads = zeros(Float64,Px_num,Py_num,nthreads())
@time @threads for tr in LinRange(-0.9N*T/2,0.9N*T/2,Nt)
    Fxtr = Fx(tr)
    Fytr = Fy(tr)
    Ftr = hypot(Fxtr,Fytr)
    phi = atan(-Fytr,-Fxtr)
    r0 = Ip/Ftr
    x0 = r0*cos(phi)
    y0 = r0*sin(phi)
    Traj = ODEProblem(traj,zeros(Float64,4),(tr,N*T/2))
    for kd in LinRange(-kd_max,kd_max,Nkd)
        kx0 = kd*cos(phi+0.5π)
        ky0 = kd*sin(phi+0.5π)
        rate = W_adk(Ftr,kd)

        u0 = @SVector [x0,y0,kx0,ky0]
        Traj = remake(Traj;u0=u0)
        sol = solve(Traj,Tsit5(),reltol=1e-6,save_everystep=false,save_start=false)
        (x,y,px,py) = sol.u[end]

        E_inf = 0.5*(px^2+py^2)-1/(x^2+y^2+a)
        E_inf >= zero(E_inf) || continue
        pxidx = Int64(round((px-Px[1])/dPx))+1
        pyidx = Int64(round((py-Py[1])/dPy))+1
        checkbounds(Bool,Prob_nthreads,pxidx,pyidx,threadid()) || continue
        @inbounds Prob_nthreads[pxidx,pyidx,threadid()] += rate
    end
end
Prob_nthreads
end
flush(stdout)

Prob = reshape(sum(Prob_nthreads,dims=3),size(Prob_nthreads)[1:2])

# plotting
fig,ax = plt.subplots()
ax.imshow(Prob',extent=(Px[1],Px[end],Py[1],Py[end]),origin="lower")
ax.set_xlim(Px[1],Px[end])
ax.set_ylim(Py[1],Py[end])
ax.set_xlabel("\$p_x\$ (a.u.)")
ax.set_ylabel("\$p_y\$ (a.u.)")
#plt.show()

# %%
Prob_nthreads = let Prob_nthreads = zeros(Float64,Px_num,Py_num,nthreads())
@time @threads for tr in LinRange(-0.9N*T/2,0.9N*T/2,Nt)
    Fxtr = Fx(tr)
    Fytr = Fy(tr)
    Ftr = hypot(Fxtr,Fytr)
    phi = atan(-Fytr,-Fxtr)
    r0 = Ip/Ftr
    x0 = r0*cos(phi)
    y0 = r0*sin(phi)
    Traj = ODEProblem(traj,@SVector(zeros(Float64,4)),(tr,N*T/2))
    for kd in LinRange(-kd_max,kd_max,Nkd)
        kx0 = kd*cos(phi+0.5π)
        ky0 = kd*sin(phi+0.5π)
        rate = W_adk(Ftr,kd)

        u0 = @SVector [x0,y0,kx0,ky0]
        Traj = remake(Traj;u0=u0)
        sol = solve(Traj,Tsit5(),reltol=1e-6,save_everystep=false,save_start=false)
        (x,y,px,py) = sol.u[end]

        E_inf = 0.5*(px^2+py^2)-1/(x^2+y^2+a)
        E_inf >= zero(E_inf) || continue
        pxidx = Int64(round((px-Px[1])/dPx))+1
        pyidx = Int64(round((py-Py[1])/dPy))+1
        checkbounds(Bool,Prob_nthreads,pxidx,pyidx,threadid()) || continue
        @inbounds Prob_nthreads[pxidx,pyidx,threadid()] += rate
    end
end
Prob_nthreads
end
flush(stdout)

Prob = reshape(sum(Prob_nthreads,dims=3),size(Prob_nthreads)[1:2])

# plotting
fig,ax = plt.subplots()
ax.imshow(Prob',extent=(Px[1],Px[end],Py[1],Py[end]),origin="lower")
ax.set_xlim(Px[1],Px[end])
ax.set_ylim(Py[1],Py[end])
ax.set_xlabel("\$p_x\$ (a.u.)")
ax.set_ylabel("\$p_y\$ (a.u.)")
#plt.show()

# %%
Prob_nthreads = let Prob_nthreads = zeros(Float64,Px_num,Py_num,nthreads())
Trajs = Vector{ODEProblem}(undef,nthreads())
for i=1:nthreads()
    Trajs[i] = ODEProblem(traj,zeros(Float64,4),(-N*T/2,N*T/2))
end
@show typeof(Trajs)
@time @threads for tr in LinRange(-0.9N*T/2,0.9N*T/2,Nt)
    Fxtr = Fx(tr)
    Fytr = Fy(tr)
    Ftr = hypot(Fxtr,Fytr)
    phi = atan(-Fytr,-Fxtr)
    r0 = Ip/Ftr
    x0 = r0*cos(phi)
    y0 = r0*sin(phi)
    tspan = (tr,N*T/2)
    for kd in LinRange(-kd_max,kd_max,Nkd)
        kx0 = kd*cos(phi+0.5π)
        ky0 = kd*sin(phi+0.5π)
        rate = W_adk(Ftr,kd)

        u0 = @SVector [x0,y0,kx0,ky0]
        Traj = remake(Trajs[threadid()];u0=u0,tspan=tspan)
        sol = solve(Traj,Tsit5(),reltol=1e-6,save_everystep=false,save_start=false)
        (x,y,px,py) = sol.u[end]

        E_inf = 0.5*(px^2+py^2)-1/(x^2+y^2+a)
        E_inf >= zero(E_inf) || continue
        pxidx = Int64(round((px-Px[1])/dPx))+1
        pyidx = Int64(round((py-Py[1])/dPy))+1
        checkbounds(Bool,Prob_nthreads,pxidx,pyidx,threadid()) || continue
        @inbounds Prob_nthreads[pxidx,pyidx,threadid()] += rate
    end
end
Prob_nthreads
end
flush(stdout)

Prob = reshape(sum(Prob_nthreads,dims=3),size(Prob_nthreads)[1:2])

# plotting
fig,ax = plt.subplots()
ax.imshow(Prob',extent=(Px[1],Px[end],Py[1],Py[end]),origin="lower")
ax.set_xlim(Px[1],Px[end])
ax.set_ylim(Py[1],Py[end])
ax.set_xlabel("\$p_x\$ (a.u.)")
ax.set_ylabel("\$p_y\$ (a.u.)")
#plt.show()

# %%
Prob_nthreads = let Prob_nthreads = zeros(Float64,Px_num,Py_num,nthreads())
prob = ODEProblem(traj,@SVector(zeros(Float64,4)),(-N*T/2,N*T/2))
Trajs = Vector{typeof(prob)}(undef,nthreads())
for i=1:nthreads()
    Trajs[i] = ODEProblem(traj,@SVector(zeros(Float64,4)),(-N*T/2,N*T/2))
end
@time @threads for tr in LinRange(-0.9N*T/2,0.9N*T/2,Nt)
    Fxtr = Fx(tr)
    Fytr = Fy(tr)
    Ftr = hypot(Fxtr,Fytr)
    phi = atan(-Fytr,-Fxtr)
    r0 = Ip/Ftr
    x0 = r0*cos(phi)
    y0 = r0*sin(phi)
    tspan = (tr,N*T/2)
    for kd in LinRange(-kd_max,kd_max,Nkd)
        kx0 = kd*cos(phi+0.5π)
        ky0 = kd*sin(phi+0.5π)
        rate = W_adk(Ftr,kd)

        u0 = @SVector [x0,y0,kx0,ky0]
        Traj = remake(Trajs[threadid()];u0=u0,tspan=tspan)
        sol = solve(Traj,Tsit5(),reltol=1e-6,save_everystep=false,save_start=false)
        (x,y,px,py) = sol.u[end]

        E_inf = 0.5*(px^2+py^2)-1/(x^2+y^2+a)
        E_inf >= zero(E_inf) || continue
        pxidx = Int64(round((px-Px[1])/dPx))+1
        pyidx = Int64(round((py-Py[1])/dPy))+1
        checkbounds(Bool,Prob_nthreads,pxidx,pyidx,threadid()) || continue
        @inbounds Prob_nthreads[pxidx,pyidx,threadid()] += rate
    end
end
Prob_nthreads
end
flush(stdout)

Prob = reshape(sum(Prob_nthreads,dims=3),size(Prob_nthreads)[1:2])

# plotting
fig,ax = plt.subplots()
ax.imshow(Prob',extent=(Px[1],Px[end],Py[1],Py[end]),origin="lower")
ax.set_xlim(Px[1],Px[end])
ax.set_ylim(Py[1],Py[end])
ax.set_xlabel("\$p_x\$ (a.u.)")
ax.set_ylabel("\$p_y\$ (a.u.)")
#plt.show()

# %%
Prob_nthreads = let Prob_nthreads = zeros(Float64,Px_num,Py_num,nthreads())
Trajs = [ODEProblem(traj,@SVector(zeros(Float64,4)),(-N*T/2,N*T/2)) for _ in 1:nthreads()]
@show typeof(Trajs)
@time @threads for tr in LinRange(-0.9N*T/2,0.9N*T/2,Nt)
    Fxtr = Fx(tr)
    Fytr = Fy(tr)
    Ftr = hypot(Fxtr,Fytr)
    phi = atan(-Fytr,-Fxtr)
    r0 = Ip/Ftr
    x0 = r0*cos(phi)
    y0 = r0*sin(phi)
    tspan = (tr,N*T/2)
    for kd in LinRange(-kd_max,kd_max,Nkd)
        kx0 = kd*cos(phi+0.5π)
        ky0 = kd*sin(phi+0.5π)
        rate = W_adk(Ftr,kd)

        u0 = @SVector [x0,y0,kx0,ky0]
        Traj = remake(Trajs[threadid()];u0=u0,tspan=tspan)
        sol = solve(Traj,Tsit5(),reltol=1e-6,save_everystep=false,save_start=false)
        (x,y,px,py) = sol.u[end]

        E_inf = 0.5*(px^2+py^2)-1/(x^2+y^2+a)
        E_inf >= zero(E_inf) || continue
        pxidx = Int64(round((px-Px[1])/dPx))+1
        pyidx = Int64(round((py-Py[1])/dPy))+1
        checkbounds(Bool,Prob_nthreads,pxidx,pyidx,threadid()) || continue
        @inbounds Prob_nthreads[pxidx,pyidx,threadid()] += rate
    end
end
Prob_nthreads
end
flush(stdout)

Prob = reshape(sum(Prob_nthreads,dims=3),size(Prob_nthreads)[1:2])

# plotting
fig,ax = plt.subplots()
ax.imshow(Prob',extent=(Px[1],Px[end],Py[1],Py[end]),origin="lower")
ax.set_xlim(Px[1],Px[end])
ax.set_ylim(Py[1],Py[end])
ax.set_xlabel("\$p_x\$ (a.u.)")
ax.set_ylabel("\$p_y\$ (a.u.)")
#plt.show()

# %%

max_stars_repo_path: 0018/Solve ODE with many different initial conditions.jl

max_stars_repo_name: genkuroki/public

max_issues_repo_name: genkuroki/public

max_forks_repo_name: genkuroki/public


text:
import Pkg
Pkg.activate(@__DIR__)

using Documenter
using Plots # this needs to be imported here so that Require.jl includes animate_draws when building docs
using NoisySignalIntegration

# include doctests from docstrings
DocMeta.setdocmeta!(NoisySignalIntegration, :DocTestSetup, :(using NoisySignalIntegration); recursive=true)

makedocs(
    sitename="NoisySignalIntegration.jl",
    modules=[NoisySignalIntegration],
    pages = [
        "Home" => "index.md",
        "Installation" => "installation.md",
        "Package Overview" => "overview.md",
        "Usage Guide" => "guide.md",
        "Examples" => "examples.md",
        "Baseline Handling" => "baseline.md",
        "Internals" => "internals.md",
        "API reference" => "API.md"
    ],
    highlightsig=true
)


text:
sort(xs::Vector{T}, lt::Function=<, rev::Bool=false) where {T <: ArbFloat} = sort(xs, alg=QuickSort, lt=lt, rev=rev)
function sort_intervals(xs::Vector{T}, rev::Bool=false) where {T <: ArbFloat}
   lessthan = rev ? pred : succ
   return sort(xs, alg=MergeSort, lt=lessthan)
end


text:
import Base: getindex, axes

axes(x::TS) = axes(x.values)
axes(x::TS, d) = axes(x.values, d)

# all element indexing
getindex(x::TS) = x
getindex(x::TS, ::Colon) = x
getindex(x::TS, ::Colon, ::Colon) = x

# cartesian index support
getindex(x::TS, idx::CartesianIndex{2}) = x.values[idx.I[1], idx.I[2]]
getindex(x::TS, idx::CI) where {CI<:AbstractArray{CartesianIndex{2}}} = TS(x.values[idx],
                                                                           x.index[[idx[i].I[1] for i in 1:length(idx)]],
                                                                           x.fields[unique([idx[i].I[2] for i in 1:length(idx)])])

# general interface
getindex(x::TS, r, c) = (rows=findrows(r,x); cols=findcols(c,x); TS(x.values[rows,cols],x.index[rows],x.fields[cols]))
getindex(x::TS, r, ::Colon) = (rows=findrows(r,x); TS(x.values[rows,:],x.index[rows],x.fields))
getindex(x::TS, ::Colon, c) = (cols=findcols(c,x); TS(x.values[:,cols],x.index,x.fields[cols]))

# types only used to index rows
getindex(x::TS, r::R) where {R<:Int} = (rows=findrows(r,x); TS(x.values[rows,:],x.index[rows],x.fields))
getindex(x::TS, r::R) where {R<:AbstractVector{<:Integer}} = (rows=findrows(r,x); TS(x.values[rows,:],x.index[rows],x.fields))
getindex(x::TS, r::R) where {R<:TimeType} = (rows=findrows(r,x); TS(x.values[rows,:],x.index[rows],x.fields))
getindex(x::TS, r::R) where {R<:AbstractVector{<:TimeType}} = (rows=findrows(r,x); TS(x.values[rows,:],x.index[rows],x.fields))
getindex(x::TS, r::R) where {R<:AbstractString} = (rows=findrows(r,x); TS(x.values[rows,:],x.index[rows],x.fields))

# types only used to index columns
getindex(x::TS, c::C) where {C<:Symbol} = (cols=findcols(c,x); TS(x.values[:,cols],x.index,x.fields[cols]))
getindex(x::TS, c::C) where {C<:AbstractVector{<:Symbol}} = (cols=findcols(c,x); TS(x.values[:,cols],x.index,x.fields[cols]))


text:
# SplineSpace represents a Spline, right now piecewise constant HeavisideSpace is only implemented case
immutable SplineSpace{order,T} <: RealUnivariateSpace{PiecewiseInterval{T}}
    domain::PiecewiseInterval{T}
end

@compat (::Type{SplineSpace{m}}){m,T}(d::PiecewiseInterval{T}) = SplineSpace{m,T}(d)
@compat (::Type{SplineSpace{m}}){m}(d::AbstractVector) = SplineSpace{m}(PiecewiseInterval(sort(d)))

typealias HeavisideSpace{T} SplineSpace{0,T}
dimension{λ}(h::SplineSpace{λ}) = length(h.domain.points)+λ-1

Base.convert(::Type{HeavisideSpace},d::PiecewiseInterval)=HeavisideSpace{eltype(d)}(d)

Base.convert(::Type{HeavisideSpace},d::AbstractVector) =
    HeavisideSpace(PiecewiseInterval(sort(d)))

spacescompatible{λ}(a::SplineSpace{λ},b::SplineSpace{λ}) = domainscompatible(a,b)
canonicalspace(sp::HeavisideSpace) = PiecewiseSpace(map(Chebyshev,pieces(domain(sp))))

function evaluate{T<:Real}(f::Fun{HeavisideSpace{T}},x::Real)
    p = domain(f).points
    c = f.coefficients
    for k=1:length(p)-1
        if p[k] ≤ x ≤ p[k+1]
            return c[k]
        end
    end
    return zero(T)
end

function evaluate{T<:Real}(f::Fun{SplineSpace{1,T}},x::Real)
    p = domain(f).points
    c = f.coefficients
    for k=1:length(p)-1
        if p[k] ≤ x ≤ p[k+1]
            return (x-p[k])*c[k+1]/(p[k+1]-p[k]) + (p[k+1]-x)*c[k]/(p[k+1]-p[k])
        end
    end
    return zero(T)
end

function points(sp::HeavisideSpace,n)
    x=sp.domain.points
    (x[1:end-1] + diff(x)/2)[1:n]
end

points(sp::SplineSpace{1},n) = sp.domain.points[1:n]

for λ = [0,1]
    @eval begin
        function transform(S::SplineSpace{$λ},vals::Vector,plan...)
            @assert length(vals) ≤ dimension(S)
            vals
        end
        itransform(S::SplineSpace{$λ},cfs::Vector,plan...) = pad(cfs,dimension(S))
    end
end

conversion_rule{k,PS<:PolynomialSpace}(sp::HeavisideSpace,sp2::PiecewiseSpace{NTuple{k,PS}}) = sp

Conversion{kk,CC<:PolynomialSpace,DD}(a::HeavisideSpace,b::PiecewiseSpace{NTuple{kk,CC},RealBasis,DD,1}) =
    ConcreteConversion(a,b)
bandinds{HS<:HeavisideSpace,CC<:PolynomialSpace,DD,kk}(::ConcreteConversion{HS,PiecewiseSpace{NTuple{kk,CC},RealBasis,DD,1}}) =
    0,0
#bandinds{HS<:HeavisideSpace,DD,D}(::ConcreteConversion{PiecewiseSpace{ChebyshevDirichlet{1,1,D},RealBasis,DD,1},HS})=0,0
getindex{HS<:HeavisideSpace,CC<:PolynomialSpace,DD,kk}(C::ConcreteConversion{HS,PiecewiseSpace{NTuple{kk,CC},RealBasis,DD,1}},k::Integer,j::Integer) =
    k ≤ dimension(domainspace(C)) && j==k? one(eltype(C)) : zero(eltype(C))

bandinds{HS<:HeavisideSpace}(D::ConcreteDerivative{HS})=-1,0

rangespace{HS<:HeavisideSpace}(D::ConcreteDerivative{HS})=DiracSpace(domain(D).points)

function getindex{HS<:HeavisideSpace}(D::ConcreteDerivative{HS},k::Integer,j::Integer)
    n=numpieces(domain(D))
    if k≤n && j==k
        one(eltype(D))
    elseif j≤n && j==k-1
        -one(eltype(D))
    else
        zero(eltype(D))
    end
end

Base.sum{HS<:HeavisideSpace}(f::Fun{HS}) = dotu(f.coefficients,diff(space(f).domain.points))
function Base.sum{T}(f::Fun{SplineSpace{1,T}})
    vals=pad(f.coefficients,dimension(space(f)))
    dfs=diff(space(f).domain.points)
    ret=vals[1]*dfs[1]/2
    for k=2:length(vals)-1
        ret+=vals[k]*(dfs[k]+dfs[k+1])/2
    end
    ret+=vals[end]*dfs[end]/2
    ret
end

differentiate{T}(f::Fun{SplineSpace{1,T}}) =
    Fun(diff(pad(f.coefficients,dimension(space(f))))./diff(space(f).domain.points),
        HeavisideSpace(space(f).domain))

integrate{T}(f::Fun{HeavisideSpace{T}}) =
    Fun([0;cumsum(f.coefficients).*diff(space(f).domain.points)],
        SplineSpace{1,T}(space(f).domain))


text:
using DataFrames, Test, Random, FixedEffectModels
Random.seed!(0)
df = DataFrame(x1 = randn(10000) * 100 )
df[:x2] = df[:x1].^4

## Make sure all coefficients are estimated
result = reg(df, @model(x1 ~ x2 ))
@test sum(abs.(coef(result)) .> 0)  == 2


text:
mutable struct DescriptorSet
    mVkDevice::vk.VkDevice
    mPool::DescriptorPool
    mLayout::DescriptorSetLayout
    mInfo::vk.VkDescriptorSetAllocateInfo
    mHandleRef::Ref{vk.VkDescriptorSet}
    # Keep Samplers/Views etc. to keep them from being destroyed while in use
    mBindingResources::Dict{UInt32, Vector{Any}}

    function DescriptorSet(device::vk.VkDevice,
                             pool::DescriptorPool,
                           layout::DescriptorSetLayout)
        this = new()
        this.mVkDevice = device
        this.mPool = pool
        this.mLayout = layout
        this.mBindingResources = Dict{UInt32, Vector{Any}}()

        setLayouts = [this.mLayout.handleRef()[]]
        info = Ref(vk.VkDescriptorSetAllocateInfo(
            vk.VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, #sType::VkStructureType
            C_NULL, #pNext::Ptr{Cvoid}
            handleRef(this.mPool)[], #descriptorPool::VkDescriptorPool
            UInt32(length(setLayouts)), #descriptorSetCount::UInt32
            pointer(setLayouts) #pSetLayouts::Ptr{VkDescriptorSetLayout}
        ))

        descriptorSets = Vector{vk.VkDescriptorSet}(undef, info[].descriptorSetCount)
        vk.vkAllocateDescriptorSets(this.mVkDevice, info, pointer(descriptorSets))
        this.mHandleRef = Ref(descriptorSets[1])
        return this
    end

    # TODO
    # // Keep Samplers/Views etc. to keep them from being destroyed while in use
    # using ResourceList = std::vector<std::shared_ptr<void>>;
    # std::unordered_map<uint32_t, ResourceList> mBindingResources;
end
@class DescriptorSet

function destroy(this::DescriptorSet)
    vk.vkFreeDescriptorSets(this.mVkDevice, handleRef(this.mPool)[], 1, this.mHandleRef[])
end

function handleRef(this::DescriptorSet)::Ref{vk.VkDescriptorSet}
    return this.mHandleRef
end

function writeCombinedImageSamplers(this::DescriptorSet, sampler::Sampler, views::Vector{ImageView}, binding::UInt32)::DescriptorSet
    writer = DescriptorSetWriter(this, binding)
    writer.combinedImageSamplers(sampler, views).write()
    return this
end

function writeCombinedImageSampler(this::DescriptorSet, sampler::Sampler, view::ImageView, binding::UInt32)::DescriptorSet
    writer = DescriptorSetWriter(this, binding)
    writer.combinedImageSampler(sampler, view).write()
    return this
end

function writeUniformBuffer(this::DescriptorSet, buffer::Buffer, binding::UInt32)::DescriptorSet
    writer = DescriptorSetWriter(this, binding)
    writer.uniformBuffer(buffer).write()
    return this
end

function writeUniformBuffers(this::DescriptorSet, buffers::Vector{Buffer}, binding::UInt32)::DescriptorSet
    writer = DescriptorSetWriter(this, binding)
    writer.uniformBuffers(buffers).write()
    return this
end

function writeSampledImage(this::DescriptorSet, view::ImageView, binding::UInt32)::DescriptorSet
    writer = DescriptorSetWriter(this, binding)
    writer.sampledImage(view).write()
    return this
end


text:
# Autogenerated wrapper script for Graphite2_jll for armv7l-linux-musleabihf
export libgraphite2

JLLWrappers.@generate_wrapper_header("Graphite2")
JLLWrappers.@declare_library_product(libgraphite2, "libgraphite2.so.3")
function __init__()
    JLLWrappers.@generate_init_header()
    JLLWrappers.@init_library_product(
        libgraphite2,
        "lib/libgraphite2.so",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@generate_init_footer()
end  # __init__()


text:
using OrderedCollections: OrderedDict

function ordered_dict_show(dict::OrderedDict, padchar)
    name = "OrderedDict"
    N = length(dict)

    if N === 0
        return "$name with no entries"
    elseif N == 1
        return string("$name with 1 entry:", '\n',
                      padchar, "   └── ", dict.keys[1], " => ", summary(dict.vals[1]))
    else
        return string(name, " with $N entries:\n",
                      Tuple(string(padchar, "   ├── $name => ", summary(dict[name]), '\n') for name in dict.keys[1:end-1])...,
                            string(padchar, "   └── ", dict.keys[end], " => ", summary(dict.vals[end])))
    end
end


text:
mutable struct TypedUnaryOperator{X, Z} <: AbstractTypedOp{Z}
    p::libgb.GrB_UnaryOp
    function TypedUnaryOperator{X, Z}(p) where {X, Z}
        unop = new(p)
        function f(op)
            libgb.GrB_UnaryOp_free(Ref(op.p))
        end
        return finalizer(f, unop)
    end
end
function TypedUnaryOperator(p::libgb.GrB_UnaryOp)
    return TypedUnaryOperator{xtype(p), ztype(p)}(p)
end
Base.unsafe_convert(::Type{libgb.GrB_UnaryOp}, op::TypedUnaryOperator) = op.p

mutable struct TypedBinaryOperator{X, Y, Z} <: AbstractTypedOp{Z}
    p::libgb.GrB_BinaryOp
    function TypedBinaryOperator{X, Y, Z}(p) where {X, Y, Z}
        binop = new(p)
        function f(op)
            libgb.GrB_BinaryOp_free(Ref(op.p))
        end
        return finalizer(f, binop)
    end
end
function TypedBinaryOperator(p::libgb.GrB_BinaryOp)
    return TypedBinaryOperator{xtype(p), ytype(p), ztype(p)}(p)
end
Base.unsafe_convert(::Type{libgb.GrB_BinaryOp}, op::TypedBinaryOperator) = op.p

mutable struct TypedMonoid{X, Y, Z} <: AbstractTypedOp{Z}
    p::libgb.GrB_Monoid
    function TypedMonoid{X, Y, Z}(p) where {X, Y, Z}
        monoid = new(p)
        function f(m)
            libgb.GrB_Monoid_free(Ref(m.p))
        end
        return finalizer(f, monoid)
    end
end
function TypedMonoid(p::libgb.GrB_Monoid)
    return TypedMonoid{xtype(p), ytype(p), ztype(p)}(p)
end
Base.unsafe_convert(::Type{libgb.GrB_Monoid}, op::TypedMonoid) = op.p

mutable struct TypedSemiring{X, Y, Z} <: AbstractTypedOp{Z}
    p::libgb.GrB_Semiring
    function TypedSemiring{X, Y, Z}(p) where {X, Y, Z}
        semiring = new(p)
        function f(rig)
            libgb.GrB_Semiring_free(Ref(rig.p))
        end
        return finalizer(f, semiring)
    end
end
function TypedSemiring(p::libgb.GrB_Semiring)
    return TypedSemiring{xtype(p), ytype(p), ztype(p)}(p)
end
Base.unsafe_convert(::Type{libgb.GrB_Semiring}, op::TypedSemiring) = op.p

"""
"""
mutable struct GBScalar{T}
    p::libgb.GxB_Scalar
    function GBScalar{T}(p::libgb.GxB_Scalar) where {T}
        s = new(p)
        function f(scalar)
            libgb.GxB_Scalar_free(Ref(scalar.p))
        end
        return finalizer(f, s)
    end
end

"""
    GBVector{T} <: AbstractSparseArray{T, UInt64, 1}

One-dimensional GraphBLAS array with elements of type T. Internal representation is
specified as opaque, but may be either a dense array, bitmap array, or
compressed sparse vector.

See also: [`GBMatrix`](@ref).
"""
mutable struct GBVector{T} <: AbstractSparseArray{T, UInt64, 1}
    p::libgb.GrB_Matrix
    function GBVector{T}(p::libgb.GrB_Matrix) where {T}
        v = new(p)
        function f(vector)
            libgb.GrB_Matrix_free(Ref(vector.p))
        end
        return finalizer(f, v)
    end
end

"""
    GBMatrix{T} <: AbstractSparseArray{T, UInt64, 2}

Two-dimensional GraphBLAS array with elements of type T. Internal representation is
specified as opaque, but in this implementation is stored as one of the following in either
row or column orientation:

    1. Dense
    2. Bitmap
    3. Sparse Compressed
    4. Hypersparse

The storage type is automatically determined by the library.
"""
mutable struct GBMatrix{T} <: AbstractSparseArray{T, UInt64, 2}
    p::libgb.GrB_Matrix
    function GBMatrix{T}(p::libgb.GrB_Matrix) where {T}
        A = new(p)
        function f(matrix)
            libgb.GrB_Matrix_free(Ref(matrix.p))
        end
        return finalizer(f, A)
    end
end


text:
"""
    AbstractSampler

Abstract supertype for sampler objects.
"""
abstract type AbstractSampler{S <: AbstractScenario} end
"""
    sample(sampler::AbstractSampler{S})

Sample a scenario of type `S` using `sampler`.
"""
function sample(sampler::AbstractSampler)
    return sampler()
end
function Base.show(io::IO, sampler::AbstractSampler{S}) where S <: AbstractScenario
    print(io, "$(S.name.name) sampler")
    return io
end
function Base.show(io::IO, sampler::AbstractSampler{S}) where S <: Scenario
    print(io, "Scenario sampler")
    return io
end
"""
    sample(sampler::AbstractSampler{S}, π::AbstractSampler)

Sample a scenario of type `S` using `sampler` and set the probability of the sampled scenario to `π`.
"""
function sample(sampler::AbstractSampler, π::AbstractFloat)
    scenario = sampler()
    set_probability!(scenario, π)
    return scenario
end
"""
    Sampler

General purpose sampler object that samples Scenario.

See also: [`Scenario`](@ref), [`@sampler`](@ref)
"""
struct Sampler <: AbstractSampler{Scenario}
    sampler::Function
end

function (sampler::Sampler)()
    return sampler.sampler()
end

function sample!(scenarios::Scenarios{S}, sampler::AbstractSampler{S}, n::Integer) where S <: AbstractScenario
    _sample!(scenarios, sampler, n, length(scenarios), 1/n)
    return nothing
end
function sample!(scenarios::Scenarios{S}, sampler::AbstractSampler{Scenario}, n::Integer) where S <: Scenario
    _sample!(scenarios, sampler, n, length(scenarios), 1/n)
    return nothing
end

function _sample!(scenarios::Scenarios, sampler::AbstractSampler, n::Integer, m::Integer, π::AbstractFloat)
    if m > 0
        # Rescale probabilities of existing scenarios
        for scenario in scenarios
            p = probability(scenario) * m / (m+n)
            set_probability!(scenario, p)
        end
        π *= n/(m+n)
    end
    for i = 1:n
        push!(scenarios, sample(sampler, π))
    end
    return nothing
end


text:
# Integrator specifically for SSA
# Built to have 0-overhead stepping

struct SSAStepper <: DiffEqBase.DEAlgorithm end

mutable struct SSAIntegrator{F,uType,tType,P,S,CB,SA,OPT,TS} <: DiffEqBase.DEIntegrator{SSAStepper,Nothing,uType,tType}
    f::F
    u::uType
    t::tType
    tprev::tType
    p::P
    sol::S
    i::Int
    tstop::tType
    cb::CB
    saveat::SA
    save_everystep::Bool
    save_end::Bool
    cur_saveat::Int
    opts::OPT
    tstops::TS
    tstops_idx::Int
    u_modified::Bool
    keep_stepping::Bool          # false if should terminate a simulation
end

(integrator::SSAIntegrator)(t) = copy(integrator.u)
(integrator::SSAIntegrator)(out,t) = (out .= integrator.u)

function DiffEqBase.__solve(jump_prob::JumpProblem,
                         alg::SSAStepper;
                         kwargs...)
    integrator = init(jump_prob,alg;kwargs...)
    solve!(integrator)
    integrator.sol
end

function DiffEqBase.solve!(integrator)

    end_time = integrator.sol.prob.tspan[2]
    while should_continue_solve(integrator) # It stops before adding a tstop over
        step!(integrator)
    end

    integrator.t = end_time

    if integrator.saveat !== nothing && !isempty(integrator.saveat)
        # Split to help prediction
        while integrator.cur_saveat <= length(integrator.saveat) &&
           integrator.saveat[integrator.cur_saveat] < integrator.t

            push!(integrator.sol.t,integrator.saveat[integrator.cur_saveat])
            push!(integrator.sol.u,copy(integrator.u))
            integrator.cur_saveat += 1

        end
    end

    if integrator.save_end && integrator.sol.t[end] != end_time
        push!(integrator.sol.t,end_time)
        push!(integrator.sol.u,copy(integrator.u))
    end
end

function DiffEqBase.__init(jump_prob::JumpProblem,
                         alg::SSAStepper;
                         save_start = true,
                         save_end = true,
                         seed = nothing,
                         alias_jump = Threads.threadid() == 1,
                         saveat = nothing,
                         callback = nothing,
                         tstops = (),
                         numsteps_hint=100)
    if !(jump_prob.prob isa DiscreteProblem)
        error("SSAStepper only supports DiscreteProblems.")
    end
    @assert isempty(jump_prob.jump_callback.continuous_callbacks)

    if alias_jump
      cb = jump_prob.jump_callback.discrete_callbacks[end]
      if seed !== nothing
          Random.seed!(cb.condition.rng,seed)
      end
    else
      cb = deepcopy(jump_prob.jump_callback.discrete_callbacks[end])
      if seed === nothing
          Random.seed!(cb.condition.rng,seed_multiplier()*rand(UInt64))
      else
          Random.seed!(cb.condition.rng,seed)
      end
    end

    opts = (callback = CallbackSet(callback),)
    prob = jump_prob.prob

    if save_start
        t = [prob.tspan[1]]
        u = [copy(prob.u0)]
    else
        t = typeof(prob.tspan[1])[]
        u = typeof(prob.u0)[]
    end

    sol = DiffEqBase.build_solution(prob,alg,t,u,dense=false,
                         calculate_error = false,
                         destats = DiffEqBase.DEStats(0),
                         interp = DiffEqBase.ConstantInterpolation(t,u))
    save_everystep = any(cb.save_positions)

    if typeof(saveat) <: Number
        _saveat = prob.tspan[1]:saveat:prob.tspan[2]
    else
        _saveat = saveat
    end

   if _saveat !== nothing && !isempty(_saveat) && _saveat[1] == prob.tspan[1]
       cur_saveat = 2
   else
       cur_saveat = 1
   end

   if _saveat !== nothing && !isempty(_saveat)
     sizehint!(u,length(_saveat)+1)
     sizehint!(t,length(_saveat)+1)
   elseif save_everystep
     sizehint!(u,numsteps_hint)
     sizehint!(t,numsteps_hint)
   else
     sizehint!(u,save_start+save_end)
     sizehint!(t,save_start+save_end)
   end

    integrator = SSAIntegrator(prob.f,copy(prob.u0),prob.tspan[1],prob.tspan[1],prob.p,
                               sol,1,prob.tspan[1],
                               cb,_saveat,save_everystep,save_end,cur_saveat,
                               opts,tstops,1,false,true)
    cb.initialize(cb,integrator.u,prob.tspan[1],integrator)
    integrator
end

DiffEqBase.add_tstop!(integrator::SSAIntegrator,tstop) = integrator.tstop = tstop

function DiffEqBase.step!(integrator::SSAIntegrator)
    integrator.tprev = integrator.t
    next_jump_time = integrator.tstop > integrator.t ? integrator.tstop : typemax(integrator.tstop)

    doaffect = false
    if !isempty(integrator.tstops) &&
        integrator.tstops_idx <= length(integrator.tstops) &&
        integrator.tstops[integrator.tstops_idx] < next_jump_time

        integrator.t = integrator.tstops[integrator.tstops_idx]
        integrator.tstops_idx += 1
    else
        integrator.t = integrator.tstop
        doaffect = true # delay effect until after saveat
    end

    @inbounds if integrator.saveat !== nothing && !isempty(integrator.saveat)
        # Split to help prediction
        while integrator.cur_saveat < length(integrator.saveat) &&
           integrator.saveat[integrator.cur_saveat] < integrator.t

            saved = true
            push!(integrator.sol.t,integrator.saveat[integrator.cur_saveat])
            push!(integrator.sol.u,copy(integrator.u))
            integrator.cur_saveat += 1
        end
    end

    doaffect && integrator.cb.affect!(integrator)

    if !(typeof(integrator.opts.callback.discrete_callbacks)<:Tuple{})
        discrete_modified,saved_in_cb = DiffEqBase.apply_discrete_callback!(integrator,integrator.opts.callback.discrete_callbacks...)
    else
        saved_in_cb = false
    end

    !saved_in_cb && savevalues!(integrator)
    nothing
end

function DiffEqBase.savevalues!(integrator::SSAIntegrator,force=false)
    saved, savedexactly = false, false

    # No saveat in here since it would only use previous values,
    # so in the specific case of SSAStepper it's already handled

    if integrator.save_everystep || force
        saved = true
        savedexactly = true
        push!(integrator.sol.t,integrator.t)
        push!(integrator.sol.u,copy(integrator.u))
    end

    saved, savedexactly
end

function should_continue_solve(integrator::SSAIntegrator)
    end_time = integrator.sol.prob.tspan[2]

    # we continue the solve if there is a tstop between now and end_time
    has_tstop = !isempty(integrator.tstops) &&
        integrator.tstops_idx <= length(integrator.tstops) &&
        integrator.tstops[integrator.tstops_idx] < end_time

    # we continue the solve if there will be a jump between now and end_time
    has_jump = integrator.t < integrator.tstop < end_time

    integrator.keep_stepping && (has_jump || has_tstop)
end

function reset_aggregated_jumps!(integrator::SSAIntegrator,uprev = nothing)
     reset_aggregated_jumps!(integrator,uprev,integrator.cb)
     nothing
end

function DiffEqBase.terminate!(integrator::SSAIntegrator, retcode = :Terminated)
    integrator.keep_stepping = false
    integrator.sol = DiffEqBase.solution_new_retcode(integrator.sol, retcode)
    nothing
end

export SSAStepper


text:
using TensorOperators
using Base.Test
using ArrayViews

input_framesize = 5
output_framesize = 4
kW = 2
dW = 1

m = TemporalConvolution(cpu, Float64, input_framesize, output_framesize, kW, dW)
init!(m)

x = rand(5, 10)

y = forward!(m, x)

# Compute the output

output_length = div(size(x, 2) - kW, dW) + 1
y2 = zeros(output_framesize, output_length)
for i in 1:output_length
    xi = flatten_view(x[:, i:(i+kW-1)])
    y2[:, i] = m.bias.values + m.weight.values * xi
end

@test_approx_eq y y2


text:
module RQC
using QXZoo.Circuit
using QXZoo.GateMap
using QXZoo.DefaultGates
using QXZoo.GateOps
using Random

export create_RQC

# *************************************************************************** #
#                              RQC functions
# *************************************************************************** #

"""
    lin_idx(i,j)

Linearise 2D indices to 1D as [j,i] -> (i-1)*max_j + j
"""
function lin_idx(i, j, max_j)
    return (i-1)*max_j + j
end

"""
    grid_idx(i, i_stride, i_max)

Turn 1D linear indices to 2D as [j,i] -> (i-1)*max_i + j
"""
function grid_idx(i, i_stride)
    return ( (i-1)%i_stride +1, Integer(floor((i-1)/i_stride)+1),)
end

"Struct to represent a random quantum circuit"
struct RQC_DS
    # The dimensions of the 2-dimensional array of qubits.
    n::Int
    m::Int

    # Circuit object to house gates
    circ::Circuit.Circ

    # A 2-dimensional array of integers to keep track of which single qubit
    # gate should next be applied to a given qubit in the circuit.
    # The integers map to gates as follows:
    # 1 => T, 2 => sqrt(X), 3 => sqrt(Y).
    # The sign of the integer is used to indicate if the corresponding qubit
    # has been hit by a two qubit gate and can be hit by a single qubit gate.
    # This should be initialised as an array of ones as the first single qubit
    # gate is always a T gate.
    next_gate::Array{Int, 2}

    # A dictionary to convert integers from the above array into gates
    single_qubit_gates::Dict{Int, AGateSymbol}
end

"""
    RQC creation structure.

Holds the circuit, and generator datatypes
"""
function RQC_DS(n::Int, m::Int)
    RQC_DS(n, m, Circuit.Circ(n*m), -ones(Int, n, m),
        Dict(1=>DefaultGates.GateSymbols.t, 2=>sqrt(DefaultGates.GateSymbols.x), 3=>sqrt(DefaultGates.GateSymbols.y)) )
end

"""
    random_gate!(rqc::RQC, i::Int, j::Int)

Returns the gate name for the next single qubit gate to be applied to the qubit
at (i, j).
"""
function random_gate!(rqc::RQC_DS, i::Int, j::Int, rng::MersenneTwister)
    gate = rqc.next_gate[i, j]
    if gate > 0
        rqc.next_gate[i, j] = (rqc.next_gate[i, j] + rand(rng, [0,1]))%3 + 1
        rqc.next_gate[i, j] *= -1
        return rqc.single_qubit_gates[gate]
    else
        return nothing
    end
end

"""
    patterns(rqc::RQC)

Generate a dictionary of patterns of qubit pairs to apply two qubit gates to.
The patterns are numbers 1 to 8 like in Boxio_2018 but in a different order.
(Note, the order used in Boxio_2018 is 3, 1, 6, 8, 5, 7, 2, 4)
"""
function patterns(rqc::RQC_DS)
    key = 1
    gp = Dict()
    N = max(rqc.m, rqc.n)
    for v in [1, -1]
        for shift in [0, 1]
            for flip in [false, true]
                gp[key] = [[[i, j], [i, j+v]] for j in 1:2:N
                                              for i in 1+((j+shift)÷2)%2:2:N]
                if flip; gp[key] = map(x->reverse.(x), gp[key]); end
                filter!(gp[key]) do p
                    out_of_bounds(rqc, p)
                end
                key += 1
            end
        end
    end
    gp
end

"""
    out_of_bounds(rqc::RQC, targets::Array{Array{Int, 1}, 1})

Check if any of the qubits, in the given qubit pair, are out of bounds.
"""
function out_of_bounds(rqc::RQC_DS, targets::Array{Array{Int, 1}, 1})
    ((i, j), (u, v)) = targets
    (0 < i <= rqc.n) && (0 < u <= rqc.n) &&
    (0 < j <= rqc.m) && (0 < v <= rqc.m)
end

"""
    create_RQC(rows::Int, cols::Int, depth::Int,
                        seed::Union{Int, Nothing}=nothing;
                        use_iswap::Bool=false,
                        final_Hadamard_layer::Bool=false)

Generate a random quantum circuit with a (rows x cols) grid of qubits. The
parameter 'depth' is the number of one and two qubit gate layers to be used in
the circuit.

The single qubit gates used are chossen randomly from the set
{T, sqrt(X), sqrt(Y)}. The seed for the random selection can be set with the
seed parameter.

CZ gates are used by default as the two qubit gates.
[TODO] Setting 'use_iswap' to true will use iSWAP gates inplace of CZ gates.

Setting 'final_Hadamard_layer' to true will include a layer of Hadamard gates
at the end of the circuit.
"""
function create_RQC(rows::Int, cols::Int, depth::Int,
                    seed::Union{Int, Nothing}=nothing;
                    use_iswap::Bool=false,
                    final_Hadamard_layer::Bool=false)

    if seed === nothing
        rng = MersenneTwister()
    else
        rng = MersenneTwister(seed)
    end

    # Create an empty rqc.
    rqc = RQC_DS(rows, cols)

    # A dictionary to map gate names to methods that add the
    # corresponding gate to the rqc.
    # TODO: x and y should be replaced by sqrt of x and y
    gates = Dict("h" => DefaultGates.h, "cz" => DefaultGates.c_z, "t" => DefaultGates.t,
                 "x" => target -> rqc.circ.rx(pi/2, target),
                 "y" => target -> rqc.circ.ry(pi/2, target) )

    # The rqc starts with a layer of hadamard gates applied to all qubits.
    for i in 1:rqc.n, j in 1:rqc.m
        rqc.circ << DefaultGates.h(lin_idx(i, j, rqc.m))
    end

    # Get the patterns to apply two qubit gates in.
    gate_patterns = patterns(rqc)

    # Loop through the patterns applying the two qubit gates and apply a random
    # single qubit gate to the appropriate qubits.
    pattern = [3, 1, 6, 8, 5, 7, 2, 4]
    two_qubit_gate = use_iswap ? nothing : DefaultGates.c_z
    for i in 0:depth-1
        i = pattern[i%8 + 1]

        if !(length(gate_patterns[i]) == 0)
            # Apply the two qubit gates.
            for targets in gate_patterns[i]
                rqc.circ << two_qubit_gate( lin_idx(targets[2][2], targets[2][1], rqc.n),  lin_idx(targets[1][2], targets[1][1], rqc.n))
            end

            # Apply the single qubit gates
            qubits_hit = reduce(vcat, gate_patterns[i])
            for idx in 1:rqc.n, jdx in 1:rqc.m
                if !([idx, jdx] in qubits_hit)
                    gate = random_gate!(rqc, idx, jdx, rng)
                    if gate !== nothing
                        rqc.circ << DefaultGates.u(gate, lin_idx(idx, jdx, rqc.m))
                    end
                end
            end

            # Update rqc with which qubits were hit by a two qubit gate
            # and so may be hit by a single qubit gate next round.
            for ((idx, jdx), (u, v)) in gate_patterns[i]
                rqc.next_gate[idx, jdx] = abs(rqc.next_gate[idx, jdx])
                rqc.next_gate[u, v] = abs(rqc.next_gate[u, v])
            end
        end

    end

    if final_Hadamard_layer
        for i in 1:rqc.n, j in 1:rqc.m
            rqc.circ << DefaultGates.h(lin_idx(i, j, rqc.m))
        end
    end

    rqc.circ
end

end


text:
mutable struct Physics{F, V, G}
    grid::G
    TwoΩ::F            # 1/second             Coriolis
      f₀::F            # 1/second
       β::F            # 1/(second * meter)
       g::F            # meters/second^2      Buoyancy

coriolis::V            # vector with units 1/second

      Fr::F            # Nondimensional       Nondimensional
      Ro::F            # Nondimensional
end

"""

Cartesian version of Physics

"""
function Physics(geometry::Cartesian;
    grid,
    TwoΩ = 4π/(24*3600),
      f₀ = TwoΩ*sin(grid.ϕmid),
       β = TwoΩ*cos(grid.ϕmid)/grid.a,
       g = 9.81,
      Fr = 0.0,
      Ro = 0.0
)

    coriolis = f₀ .+ β * grid.y

return Physics(grid, TwoΩ, f₀, β, g, coriolis, Fr, Ro)
end

"""

Spherical version of Physics

"""
function Physics(geometry::Spherical;
    grid,
    TwoΩ = 4π/(24*3600),
      f₀ = TwoΩ*sin(grid.ϕmid),
       β = TwoΩ*cos(grid.ϕmid)/grid.a,
       g = 9.81,
      Fr = 0.0,
      Ro = 0.0
)

    coriolis = TwoΩ * sin.(grid.ϕ)

return Physics(grid, TwoΩ, f₀, β, g, coriolis, Fr, Ro)
end


text:
using Documenter
using QuizQuestions

makedocs(sitename="QuizQuestions documentation",
         format = Documenter.HTML(ansicolor=true)
         )


text:
### A Pluto.jl notebook ###
# v0.12.21

using Markdown
using InteractiveUtils

# ╔═╡ 55da2efe-fd40-11ea-1fb2-237b206602b5
using Pkg, DrWatson

# ╔═╡ 55da724c-fd40-11ea-3868-3baa56009723
begin
	#@quickactivate "StatisticalRethinkingStan"
	using StanQuap
	using StatisticalRethinking
end

# ╔═╡ c46bb522-fd3b-11ea-1165-63af86a6f974
md"## Clip-05-19-24s.jl"

# ╔═╡ 788c3970-833b-11eb-3e93-93e43770b0fd
begin
	df = CSV.read(sr_datadir("WaffleDivorce.csv"), DataFrame)
	scale!(df, [:Marriage, :MedianAgeMarriage, :Divorce])
end

# ╔═╡ 55e74cfe-fd40-11ea-20b3-1519e2e34159
md"##### Include snippets 5.19-5.21."

# ╔═╡ 55e7d3f6-fd40-11ea-14c5-21a0ef390e6d
stan5_3_A = "
data {
  int N;
  vector[N] divorce_s;
  vector[N] marriage_s;
  vector[N] medianagemarriage_s;
}
parameters {
  real a;
  real bA;
  real bM;
  real aM;
  real bAM;
  real<lower=0> sigma;
  real<lower=0> sigma_M;
}
model {
  // A -> D <- M
  vector[N] mu = a + bA * medianagemarriage_s + bM * marriage_s;
  a ~ normal( 0 , 0.2 );
  bA ~ normal( 0 , 0.5 );
  bM ~ normal( 0 , 0.5 );
  sigma ~ exponential( 1 );
  divorce_s ~ normal( mu , sigma );
  // A -> M
  vector[N] mu_M = aM + bAM * medianagemarriage_s;
  aM ~ normal( 0 , 0.2 );
  bAM ~ normal( 0 , 0.5 );
  sigma_M ~ exponential( 1 );
  marriage_s ~ normal( mu_M , sigma_M );
}
";

# ╔═╡ f6fe6174-82a1-11eb-04bb-3be618429897
begin
	data = (N = size(df, 1), divorce_s = df.Divorce_s,
	  marriage_s = df.Marriage_s, medianagemarriage_s = df.MedianAgeMarriage_s)
	init = (a = 0.0, bM = 0.0, bA = -1.0, sigma = 1.0,
		aM = 0.0, bAM = -1.0, sigma_m = 1.0)
	q5_3_As, m5_3_As, o5_3_As = stan_quap("m5.3_A", stan5_3_A; data, init)
	if !isnothing(q5_3_As)
		quap5_3_As_df = sample(q5_3_As)
	end
	if !isnothing(m5_3_As)
	  post5_3_As_df = read_samples(m5_3_As, :dataframe)
	  PRECIS(post5_3_As_df)
	end
end

# ╔═╡ 55f30276-fd40-11ea-3e70-d1600cb0f556
# Rethinking results

rethinking_results = "
           mean   sd  5.5% 94.5%
  a        0.00 0.10 -0.16  0.16
  bM      -0.07 0.15 -0.31  0.18
  bA      -0.61 0.15 -0.85 -0.37
  sigma    0.79 0.08  0.66  0.91
  aM       0.00 0.09 -0.14  0.14
  bAM     -0.69 0.10 -0.85 -0.54
  sigma_M  0.68 0.07  0.57  0.79
";

# ╔═╡ d02e57a0-82a1-11eb-0305-e71ad0138683
	if !isnothing(q5_3_As)
		PRECIS(quap5_3_As_df)
	end

# ╔═╡ 55fefeaa-fd40-11ea-2c88-a910f049dcf0
md"## Snippet 5.22"

# ╔═╡ 55fff1b6-fd40-11ea-38e0-3b694162f66e
a_seq = range(-2, stop=2, length=100);

# ╔═╡ 560a4aa6-fd40-11ea-1103-7191fff677fb
md"## Snippet 5.23"

# ╔═╡ 560dcb42-fd40-11ea-0b2e-f14e70a7425a
begin
	m_sim, d_sim = simulate(post5_3_As_df, [:aM, :bAM, :sigma_M],
		a_seq, [:bM, :sigma])
end;

# ╔═╡ 5618ec0c-fd40-11ea-3a0f-85fb3e33f1b1
md"## Snippet 5.24"

# ╔═╡ 5621e8fc-fd40-11ea-2f52-095b7196c40c
begin
	fig1 = plot(xlab="Manipulated A", ylab="Counterfactual D",
		title="Total counterfactual effect of A on D")
	plot!(a_seq, mean(d_sim, dims=1)[1, :], leg=false)
	hpdi_array = zeros(length(a_seq), 2)
	for i in 1:length(a_seq)
		hpdi_array[i, :] =  hpdi(d_sim[i, :])
	end
	plot!(a_seq, mean(d_sim, dims=1)[1, :]; ribbon=(hpdi_array[:, 1], -hpdi_array[:, 2]))
end

# ╔═╡ 56236592-fd40-11ea-2be2-b9b04f0ce30c
begin
	fig2 = plot(xlab="Manipulated A", ylab="Counterfactual M",
		title="Counterfactual effect of A on M")
	plot!(a_seq, mean(m_sim, dims=1)[1, :], leg=false)
	hpdi_array1 = zeros(length(a_seq), 2)
	for i in 1:length(a_seq)
		hpdi_array1[i, :] =  hpdi(m_sim[i, :])
	end
	plot!(a_seq, mean(m_sim, dims=1)[1, :]; ribbon=(hpdi_array1[:, 1], -hpdi_array1[:, 2]))
end

# ╔═╡ 5631855a-fd40-11ea-173a-a187c5976832
md"##### M -> D"

# ╔═╡ 56339584-fd40-11ea-3c75-4f679d500b1c
begin
	m_seq = range(-2, stop=2, length=100)
	md_sim = zeros(size(post5_3_As_df, 1), length(m_seq))
	for j in 1:size(post5_3_As_df, 1)
		for i in 1:length(m_seq)
			d = Normal(post5_3_As_df[j, :a] + post5_3_As_df[j, :bM] * m_seq[i], post5_3_As_df[j, :sigma])
			md_sim[j, i] = rand(d, 1)[1]
		end
	end
	fig3 = plot(xlab="Manipulated M", ylab="Counterfactual D",
		title="Counterfactual effect of M on D")
	plot!(m_seq, mean(md_sim, dims=1)[1, :], leg=false)
	hpdi_array2 = zeros(length(m_seq), 2)
	for i in 1:length(m_seq)
		hpdi_array2[i, :] =  hpdi(md_sim[i, :])
	end
	plot!(m_seq, mean(md_sim, dims=1)[1, :]; ribbon=(hpdi_array2[:, 1], -hpdi_array2[:, 2]))
end

# ╔═╡ 563b3f8c-fd40-11ea-1d4b-3fc4eec893fa
plot(fig1, fig2, fig3, layout=(3, 1))

# ╔═╡ 56426262-fd40-11ea-22a7-5bbc6089cb07
md"## End of clip-05-19-24s.jl"

# ╔═╡ Cell order:
# ╟─c46bb522-fd3b-11ea-1165-63af86a6f974
# ╠═55da2efe-fd40-11ea-1fb2-237b206602b5
# ╠═55da724c-fd40-11ea-3868-3baa56009723
# ╠═788c3970-833b-11eb-3e93-93e43770b0fd
# ╟─55e74cfe-fd40-11ea-20b3-1519e2e34159
# ╠═55e7d3f6-fd40-11ea-14c5-21a0ef390e6d
# ╠═f6fe6174-82a1-11eb-04bb-3be618429897
# ╠═55f30276-fd40-11ea-3e70-d1600cb0f556
# ╠═d02e57a0-82a1-11eb-0305-e71ad0138683
# ╟─55fefeaa-fd40-11ea-2c88-a910f049dcf0
# ╠═55fff1b6-fd40-11ea-38e0-3b694162f66e
# ╟─560a4aa6-fd40-11ea-1103-7191fff677fb
# ╠═560dcb42-fd40-11ea-0b2e-f14e70a7425a
# ╟─5618ec0c-fd40-11ea-3a0f-85fb3e33f1b1
# ╠═5621e8fc-fd40-11ea-2f52-095b7196c40c
# ╠═56236592-fd40-11ea-2be2-b9b04f0ce30c
# ╟─5631855a-fd40-11ea-173a-a187c5976832
# ╠═56339584-fd40-11ea-3c75-4f679d500b1c
# ╠═563b3f8c-fd40-11ea-1d4b-3fc4eec893fa
# ╟─56426262-fd40-11ea-22a7-5bbc6089cb07


text:
### A Pluto.jl notebook ###
# v0.12.21

using Markdown
using InteractiveUtils

# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error).
macro bind(def, element)
    quote
        local el = $(esc(element))
        global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : missing
        el
    end
end

# ╔═╡ 2ffc155a-8853-11eb-0c4f-8bc96a3f08f2
begin
	using DrWatson

	md"""
	## EDH Deck: Kraum and Tymna

	To get started, define a `deck` Dict object below of type Dict{String,Int} where the key is the official card name and the value is the quantity of that card in the deck.
	"""
end

# ╔═╡ 2ffd3e94-8853-11eb-15b3-ffcb09c9661d
begin
	@quickactivate

	using GameZero
	using JSON
	using HTTP
	using Images: load, RGB
	using PlutoUI
	using Serialization
	using PlaymatSimulator
	using ImageTransformations: imresize

	AC = PlaymatSimulator.Actors

	pd = projectdir()

	mtg_cards = JSON.parsefile("$pd/Base/json/oracle-cards-20201224220555.json")

	md"**Found $(length(mtg_cards)) cards in JSON db!**"
end

# ╔═╡ 35d467ca-8853-11eb-16b5-65036e2a1f24
deck = if !(@isdefined deck)
	Dict{Symbol,Any}(
	:name => split(@__DIR__, "/")[end],
    :commander_names => [
        "Kraum, Ludevic's Opus",
		"Tymna the Weaver",
    	],
    :card_names => [
		"Ad Nauseam",
		"Alms Collector",
		"Ancient Tomb",
		"Angel's Grace",
		"Arid Mesa",
		"Aven Mindcensor",
		"Blood Crypt",
		"Bloodstained Mire",
		"Brainstorm",
		"Burning Inquiry",
		"Chain of Vapor",
		"Chrome Mox",
		"City of Brass",
		"Command Tower",
		"Counterspell",
		"Cursed Totem",
		"Cyclonic Rift",
		"Dark Confidant",
		"Dark Deal",
		"Dark Ritual",
		"Demonic Consultation",
		"Demonic Tutor",
		"Dimir Signet",
		"Dispel",
		"Dovin's Veto",
		"Enlightened Tutor",
		"Exotic Orchard",
		"Fellwar Stone",
		"Fire Covenant",
		"Flame Sweep",
		"Flooded Strand",
		"Flusterstorm",
		"Forbidden Orchard",
		"Force of Will",
		"Gemstone Caverns",
		"Gilded Drake",
		"Gitaxian Probe",
		"Godless Shrine",
		"Grim Monolith",
		"Hallowed Fountain",
		"Imperial Seal",
		"Island",
		"Jace, Wielder of Mysteries",
		"Kraum, Ludevic's Opus",
		"Laboratory Maniac",
		"Lim-Dûl's Vault",
		"Lotus Petal",
		"Mana Confluence",
		"Mana Crypt",
		"Mana Drain",
		"Mana Vault",
		"Marsh Flats",
		"Meltdown",
		"Mental Misstep",
		"Misty Rainforest",
		"Mnemonic Betrayal",
		"Morphic Pool",
		"Mox Diamond",
		"Mystic Remora",
		"Mystical Tutor",
		"Narset's Reversal",
		"Narset, Parter of Veils",
		"Necropotence",
		"Notion Thief",
		"Pact of Negation",
		"Polluted Delta",
		"Ponder",
		"Preordain",
		"Pyroclasm",
		"Reflecting Pool",
		"Rhystic Study",
		"Sacred Foundry",
		"Scalding Tarn",
		"Sea of Clouds",
		"Silence",
		"Smothering Tithe",
		"Snow-Covered Island",
		"Sol Ring",
		"Spell Pierce",
		"Steam Vents",
		"Suppression Field",
		"Swan Song",
		"Tainted Pact",
		"Talisman of Creativity",
		"Talisman of Dominance",
		"Talisman of Progress",
		"Toxic Deluge",
		"Tymna the Weaver",
		"Underground River",
		"Vampiric Tutor",
		"Verdant Catacombs",
		"Waste Not",
		"Watery Grave",
		"Wheel of Fortune",
		"Whispering Madness",
		"Windfall",
		"Winds of Change",
		"Windswept Heath",
		"Wooded Foothills",
		"Yawgmoth's Will",
    ]
)
else
	nothing
end

# ╔═╡ 300953aa-8853-11eb-373d-f54f8766d833
md"**Found $(length(deck[:card_names])) cards in $(deck[:name]) deck**"

# ╔═╡ 301d6246-8853-11eb-0e77-791a8e2a040d
md"""
Look OK? Keep in mind that images that do not require in-game scaling will suffer less distortion.
"""

# ╔═╡ 30219d16-8853-11eb-34f9-e9ac95eea58e
begin
	cards = []

	for n in sort(deck[:card_names])

		for c in mtg_cards

			if n == c["name"]
				push!(cards, c)
			end
		end
	end

	md"""
	**Found $(length(cards)) matching cards in mtg_cards!**
	"""
end

# ╔═╡ 30252f9e-8853-11eb-0129-9d151ffb5839
missing_cards = filter!(x->!(x in [ c["name"] for c in cards ]), vcat(deck[:card_names], deck[:commander_names]))

# ╔═╡ 302c833e-8853-11eb-0039-b116bd127ba1
md"""Card #: $(@bind i Slider(1:length(cards), default=50, show_value=true))
Shrink card by $(@bind card_ratio Slider(0.1:0.05:1.25, default=0.5, show_value=true))

or: $(@bind customw CheckBox(default=true)) specify the default card width: $(@bind card_width NumberField(1:10; default=270)) in pixels
"""

# ╔═╡ 3037a502-8853-11eb-2884-9bfb699d081e
md"""
##### Download card imgs? $(@bind download_imgs CheckBox())
"""

# ╔═╡ 3046ea30-8853-11eb-39b6-ff96a085c14b
md"""
##### Save data to disk? $(@bind save_data CheckBox())
"""

# ╔═╡ 30534bae-8853-11eb-181a-798130ecab86
deck

# ╔═╡ 305982a8-8853-11eb-3623-db4d3a2dca4c
function get_face_img(img_uri::String)
	img_resp = HTTP.get(img_uri)
	card_img = img_resp.body |> IOBuffer |> load
end

# ╔═╡ 305f084a-8853-11eb-1514-75e789bb1d9b
function get_card_preview_img(c)
	if haskey(all_cards[i], "card_faces") && haskey(all_cards[i]["card_faces"][1], "image_uris")
		hcat([get_face_img(f["image_uris"]["border_crop"])
			for f in all_cards[i]["card_faces"] ]...)
	else
		get_face_img(all_cards[i]["image_uris"]["border_crop"])
	end
end

# ╔═╡ 30657cc0-8853-11eb-1d78-8bed4b88d3a3
function get_card_faces(c, faces=[])
	if haskey(c, "image_uris")
		push!(faces, get_face_img(c["image_uris"]["border_crop"]))

	elseif haskey(c, "card_faces")
		for f in c["card_faces"]
			push!(faces, get_face_img(f["image_uris"]["border_crop"]))
		end
	end

	return faces
end

# ╔═╡ 303153aa-8853-11eb-0f16-77023647c760
if length(cards) > 0 && (@isdefined cards)

	if customw
		fs = get_card_faces(cards[i])
		sz = size(fs[end])
		imresize.(fs, ceil(Int, card_width * sz[1]/sz[2]), card_width)[end]
	else
		imresize.(get_card_faces(cards[i]), ratio=card_ratio)[end]
	end
else
	nothing
end

# ╔═╡ 3040ea2c-8853-11eb-176f-f3ef24eeebc1
if download_imgs
	CARD_FACES = []

	for c in cards
		faces = get_card_faces(c)

		if customw
			sz = size(faces[end])
			faces = imresize.(faces, ceil(Int, card_width * sz[1]/sz[2]), card_width)
		else
			faces = imresize.(faces, ratio=card_ratio)
		end

		push!(CARD_FACES, c["name"] => faces)
		sleep(0.1)
	end
end

# ╔═╡ 30404d24-8853-11eb-2885-e1870b8c82eb
if @isdefined CARD_FACES
	CARD_FACES[i][end][end]
end

# ╔═╡ 306bec22-8853-11eb-15a3-5db375f241b7
function search_mtg_cards_by_keyword(q::String, mtg_cards::Array)
	[ n for n in [ c["name"] for c in mtg_cards ] if occursin(q, n) ]
end

# ╔═╡ 3072a3f0-8853-11eb-2457-ffa9fd3857a3
function hbox(x, y, gap=16; sy=size(y), sx=size(x))
	w,h = (max(sx[1], sy[1]),
		   gap + sx[2] + sy[2])

	slate = fill(RGB(1,1,1), w,h)
	slate[1:size(x,1), 1:size(x,2)] .= RGB.(x)
	slate[1:size(y,1), size(x,2) + gap .+ (1:size(y,2))] .= RGB.(y)
	slate
end

# ╔═╡ 30183ea6-8853-11eb-36b5-b7b1a2229a89
begin
	CARD_BACK_PATH = "$pd/Base/ui/cards/card_back.png"
	CARD_BACK_IMG = imresize(load(CARD_BACK_PATH), ratio=card_ratio)

	hbox(CARD_BACK_IMG, CARD_BACK_IMG)
end

# ╔═╡ 304e1698-8853-11eb-0661-233ddd5bf224
if save_data
	deck[:CARD_BACK_IMG] = CARD_BACK_IMG
	deck[:CARD_FACES] = CARD_FACES

	fn = "$pd/EDH/decks/$(deck[:name])/$(deck[:name]).jls"
	serialize(fn, deck)

	md"Deck data saved to $fn"
end

# ╔═╡ 3079c428-8853-11eb-04e6-133b5af8af4a
vbox(x,y, gap=16) = hbox(x', y')'

# ╔═╡ Cell order:
# ╠═2ffc155a-8853-11eb-0c4f-8bc96a3f08f2
# ╠═2ffd3e94-8853-11eb-15b3-ffcb09c9661d
# ╠═35d467ca-8853-11eb-16b5-65036e2a1f24
# ╟─300953aa-8853-11eb-373d-f54f8766d833
# ╟─30183ea6-8853-11eb-36b5-b7b1a2229a89
# ╟─301d6246-8853-11eb-0e77-791a8e2a040d
# ╟─30219d16-8853-11eb-34f9-e9ac95eea58e
# ╠═30252f9e-8853-11eb-0129-9d151ffb5839
# ╟─302c833e-8853-11eb-0039-b116bd127ba1
# ╟─303153aa-8853-11eb-0f16-77023647c760
# ╟─3037a502-8853-11eb-2884-9bfb699d081e
# ╟─30404d24-8853-11eb-2885-e1870b8c82eb
# ╟─3040ea2c-8853-11eb-176f-f3ef24eeebc1
# ╟─3046ea30-8853-11eb-39b6-ff96a085c14b
# ╟─304e1698-8853-11eb-0661-233ddd5bf224
# ╟─30534bae-8853-11eb-181a-798130ecab86
# ╟─305982a8-8853-11eb-3623-db4d3a2dca4c
# ╟─305f084a-8853-11eb-1514-75e789bb1d9b
# ╟─30657cc0-8853-11eb-1d78-8bed4b88d3a3
# ╟─306bec22-8853-11eb-15a3-5db375f241b7
# ╟─3072a3f0-8853-11eb-2457-ffa9fd3857a3
# ╟─3079c428-8853-11eb-04e6-133b5af8af4a

max_stars_repo_path: EDH/decks/Kraum and Tymna/Kraum and Tymna.jl


text:
using Base.Test

# path.jl
import WaveletScattering: Literal, PathKey, Path, PathRange

# Literal
@test isimmutable(Literal(:time))
@test Literal(:time).depth == 1
@test isimmutable(Literal((:γ, 2)))
@test Literal((:γ, 2)).depth == 2

# Conversion to String
@test string(Literal(:time)) == "time"
@test string(Literal(:γ, 2)) == "γ2"

# isless for Literal's
@test Literal(:a) < Literal(:b)
@test Literal(:a, 1) < Literal(:b)
@test Literal(:a, 1) < Literal(:a, 2)
@test !(Literal(:a) < Literal(:a))
@test !(Literal(:a, 2) < Literal(:a, 1))
@test !(Literal(:b) < Literal(:a))

# PathKey
@test isimmutable(PathKey())
@test isempty(PathKey().literals)
@test isimmutable(PathKey(:time))
@test PathKey(:time).literals == [Literal(:time)]
@test PathKey(PathKey(:time)) == PathKey(:time)
@test isimmutable(PathKey(:γ, 2, :time))
@test PathKey(:γ, 2, :time).literals == [Literal(:γ,2), Literal(:time)]

# Conversion from Symbol
@test convert(PathKey, :time)== PathKey(:time)

# Conversion from Tuple
@test convert(PathKey, (:γ, 2, :time)) == PathKey(:γ, 2, :time)

# isless for PathKey's
@test PathKey(:a) < PathKey(:b)
@test PathKey(:a) < PathKey(:a, :b)
@test PathKey(:a) < PathKey((:a, 2))
@test !(PathKey(:a, :b) < PathKey(:a))

# Conversion to string
@test string(PathKey(:time)) == "time"
@test string(PathKey(:γ, 1, :time)) == "γ_time"
@test string(PathKey(:γ, 2, :time)) == "γ2_time"

# Conversion to symbol
@test Symbol(PathKey(:time)) == :time
@test Symbol(PathKey(:γ, 1, :time)) == :γ_time
@test Symbol(PathKey(:γ, 2, :time)) == :γ2_time

# Path
@test Path((:a, 2) => 2, :b => 3, :a => 1) ==
    Path(:a => 1, (:a, 2) => 2, :b => 3)

# isless for Path
@test Path(:a => 1) < Path((:a, 2) => 2)
@test !(Path((:a, 2) => 1) < Path(:a => 2))
@test Path(:a => 1) < Path(:a => 2)

# PathRange
@test PathRange((:a, 2) => 2:4, :b => 3, :a => 1:1:3) ==
    PathRange(:a => 1:3, (:a, 2) => 2:1:4, :b => 3:3)


text:
struct TRSolver{T} <: NearlyExactTRSP
    abstol::T
    maxiter::Integer
end
function (ms::TRSolver)(∇f, H, Δ, p)
    T = eltype(p)
    x, info = trs(H, ∇f, Δ)
    p .= x[:,1]

    m = dot(∇f, p) + dot(p, H * p)/2
    interior = norm(p, 2) ≤ Δ
    return (p=p, mz=m, interior=interior, λ=info.λ, hard_case=info.hard_case, solved=true)
end


text:
### first, a simple bayesian estimator ###

confidence(χ) = χ/(1+χ)

function update_confidence(event, p_q, p_a, χ)

    χ *= p_q(event)/p_a(event)
    χ

end

function compute_χ(events, p_q, p_a)
    χ = 1.
    for event in events
        χ = update_confidence(event, p_q, p_a, χ)
    end
    χ
end

"""
    compute_confidence(events,p_q, p_a)

A bayesian confidence estimator: return the probability that the null hypothesis
Q is right compared to the alternative hypothesis A.
"""
function compute_confidence(events,p_q, p_a)

    confidence(compute_χ(events,p_q, p_a))
end

"""
    compute_confidence_array(events, p_q, p_a)

Return an array of the probabilities of H being true as we process more and
more events.
"""
function compute_confidence_array(events, p_q, p_a)

    χ_array = [1.]

    for event in events
        push!(χ_array, update_confidence(event, p_q, p_a, χ_array[end]))
    end

    confidence.(χ_array)

end

### tests with standard boson sampling ###

# we will test that we are indeed in the bosonic case
# compared to the distinguishable one

# first we generate a series of bosonic events

n_events = 10
n = 3
m = 4
interf = RandHaar(m)
input_state = Input{Bosonic}(first_modes(n,m))

events = []

for i in 1:n_events

    # generate a random output pattern
    output_state = FockDetection(random_mode_occupation_collisionless(n,m))

    # compute the event probability
    this_event = Event(input_state, output_state, interf)
    compute_probability!(this_event)
    push!(events, this_event)

end

# now we have the vector of observed events with probabilities

events

# next, from events, recover the probabilities under both
# hypothesis

function p_B(event::Event)

    interf = event.interferometer
    r = event.input_state.r
    input_state = Input{Bosonic}(r)
    output_state = event.output_measurement

    event_H = Event(input_state, output_state, interf)
    compute_probability!(event_H)

    event_H.proba_params.probability

end

function p_D(event::Event)

    interf = event.interferometer
    r = event.input_state.r
    input_state = Input{Distinguishable}(r)
    output_state = event.output_measurement

    event_A = Event(input_state, output_state, interf)
    compute_probability!(event_A)

    event_A.proba_params.probability

end

# hypothesis : the events were from a bosonic distribution

p_q = p_B
p_a = p_D

confidence(compute_χ(events, p_q, p_a))

# hypothesis : the events were from a distinguishable distribution

p_q = p_D
p_a = p_B

confidence(compute_χ(events, p_q, p_a))

@test confidence(compute_χ(events, p_q, p_a)) + confidence(compute_χ(events, p_a, p_q)) ≈ 1 atol = 1e-6

##### the only thing I see is a problem in the probabilities themselves?