text:
struct PositiveSemidefinite2x2Bridge{T} <: MOIB.Variable.AbstractBridge
    variables::Vector{MOI.VariableIndex}
    rsoc::MOI.ConstraintIndex{MOI.VectorOfVariables,
                              MOI.RotatedSecondOrderCone}
end

function MOIB.Variable.bridge_constrained_variable(
    ::Type{PositiveSemidefinite2x2Bridge{T}}, model::MOI.ModelLike,
    s::SOS.PositiveSemidefinite2x2ConeTriangle) where {T}
    x, rsoc = MOI.add_constrained_variables(model, MOI.RotatedSecondOrderCone(3))
    return PositiveSemidefinite2x2Bridge{T}(x, rsoc)
end

function MOIB.Variable.supports_constrained_variable(
    ::Type{<:PositiveSemidefinite2x2Bridge}, ::Type{SOS.PositiveSemidefinite2x2ConeTriangle})
    return true
end
function MOIB.added_constrained_variable_types(::Type{<:PositiveSemidefinite2x2Bridge})
    return [(MOI.RotatedSecondOrderCone,)]
end
function MOIB.added_constraint_types(::Type{PositiveSemidefinite2x2Bridge{T}}) where T
    return Tuple{DataType, DataType}[]
end

# Attributes, Bridge acting as a model
function MOI.get(::PositiveSemidefinite2x2Bridge,
                 ::MOI.NumberOfVariables)
    return 3
end
function MOI.get(bridge::PositiveSemidefinite2x2Bridge,
                 ::MOI.ListOfVariableIndices)
    return bridge.variables
end
function MOI.get(
    ::PositiveSemidefinite2x2Bridge,
    ::MOI.NumberOfConstraints{MOI.VectorOfVariables,
                              MOI.RotatedSecondOrderCone})
    return 1
end
function MOI.get(
    bridge::PositiveSemidefinite2x2Bridge,
    ::MOI.ListOfConstraintIndices{MOI.VectorOfVariables,
                                  MOI.RotatedSecondOrderCone})
    return [bridge.rsoc]
end

# Indices
function MOI.delete(model::MOI.ModelLike,
                    bridge::PositiveSemidefinite2x2Bridge)
    MOI.delete(model, bridge.variables)
end

# Attributes, Bridge acting as a constraint

function MOI.get(::MOI.ModelLike, ::MOI.ConstraintSet,
                 ::PositiveSemidefinite2x2Bridge)
    return SOS.PositiveSemidefinite2x2ConeTriangle()
end

function MOI.get(model::MOI.ModelLike,
                 attr::MOI.ConstraintPrimal,
                 bridge::PositiveSemidefinite2x2Bridge)
    value = MOI.get(model, attr, bridge.rsoc)
    return [value[1], value[3] / √2, value[2]]
end
function MOI.get(model::MOI.ModelLike,
                 attr::MOI.ConstraintDual,
                 bridge::PositiveSemidefinite2x2Bridge)
    dual = MOI.get(model, attr, bridge.rsoc)
    # / 2 (because of different scalar product) * √2 (because of A^{-*} = 1 / √2
    return [dual[1], dual[3] / √2, dual[2]]
end

function _variable_map(i::MOIB.IndexInVector)
    if i.value == 1
        return 1
    elseif i.value == 2
        return 3
    else
        @assert i.value == 3
        return 2
    end
end
function _variable(bridge::PositiveSemidefinite2x2Bridge,
                   i::MOIB.IndexInVector)
    return bridge.variables[_variable_map(i)]
end

function MOI.get(model::MOI.ModelLike, attr::MOI.VariablePrimal,
                 bridge::PositiveSemidefinite2x2Bridge, i::MOIB.IndexInVector)
    value = MOI.get(model, attr, _variable(bridge, i))
    if i.value == 2
        value /= √2
    end
    return value
end

function MOIB.bridged_function(bridge::PositiveSemidefinite2x2Bridge{T},
                               i::MOIB.IndexInVector) where T
    func = _variable(bridge, i)
    if i.value == 2
        return MOIU.operate(/, T, func, convert(T, √2))
    else
        return convert(MOI.ScalarAffineFunction{T}, func)
    end
end
function MOIB.Variable.unbridged_map(
    bridge::PositiveSemidefinite2x2Bridge{T},
    vi::MOI.VariableIndex, i::MOIB.IndexInVector) where T

    if i.value == 2
        func = MOIU.operate(*, T, convert(T, √2), vi)
    else
        func = convert(MOI.ScalarAffineFunction{T}, vi)
    end
    return (_variable(bridge, i) => func,)
end

max_stars_repo_name: blegat/SumOfSquares

max_issues_repo_name: blegat/SumOfSquares

max_forks_repo_name: blegat/SumOfSquares


text:
###
# Laplacian
###

function LaPlacianJl!(Ap :: Matrix, A_lap :: Matrix)
    d1, d2 = size(Ap)

    for j in 1:d2
        for i in 1:d1

            west  = j == 1  ? d2 : j-1
            east  = j == d2 ? 1  : j+1
            north = i == d1 ? 1  : i+1
            south = i == 1  ? d1 : i-1

            #8-neighbor
            #inflow

            A_lap[i,j] = -Ap[i,j] +(Ap[north, east] +
                                    Ap[north, j   ] +
                                    Ap[north, west] +
                                    Ap[i    , west] +
                                    Ap[south, west] +
                                    Ap[south, j   ] +
                                    Ap[south, east] +
                                    Ap[i    , east]) / 8 ;
        end
    end
end

ext: jl


text:
function strategic_pref(m_prefs::Vector{Vector{Int}},
                        f_prefs::Vector{Vector{Int}},
                        m_matched::Vector{Int},
                        f_matched::Vector{Int},
                        no_f::Int,
                        false_prefs::Vector{Int})
    n = length(f_matched)
    f_first = zeros(Int64, n)
    for i in 1:n
        if f_matched[i] == f_prefs[i][1]
            f_first[i] = 1
        end
    end

    for i in 1:n
        if f_first[i] == 0

    f_new_prefs = copy(f_prefs)
    f_new_prefs[no_f] = false_prefs

    m_new_matched, f_new_matched = my_deferred_acceptance(m_prefs, f_new_prefs)

    if findfirst(f_prefs, f_new_matched[no_f]) < findfirst(f_prefs, f_matched[no_f])
        return no_f, false_prefs
    else
        print("false")
    end
end


text:
using Test
import LispREPL

import REPL: REPL, Terminals

# Setup. From Julia base repo.

mutable struct FakeTerminal <: Terminals.UnixTerminal
    in_stream::Base.IO
    out_stream::Base.IO
    err_stream::Base.IO
    hascolor::Bool
    raw::Bool
    FakeTerminal(stdin,stdout,stderr,hascolor=true) =
        new(stdin,stdout,stderr,hascolor,false)
end

Terminals.hascolor(t::FakeTerminal) = t.hascolor
Terminals.raw!(t::FakeTerminal, raw::Bool) = t.raw = raw
Terminals.size(t::FakeTerminal) = (24, 80)

function fake_repl(@nospecialize(f); options::REPL.Options=REPL.Options(confirm_exit=false))
    # Use pipes so we can easily do blocking reads
    # In the future if we want we can add a test that the right object
    # gets displayed by intercepting the display
    input = Pipe()
    output = Pipe()
    err = Pipe()
    Base.link_pipe!(input, reader_supports_async=true, writer_supports_async=true)
    Base.link_pipe!(output, reader_supports_async=true, writer_supports_async=true)
    Base.link_pipe!(err, reader_supports_async=true, writer_supports_async=true)

    repl = REPL.LineEditREPL(FakeTerminal(input.out, output.in, err.in), true)

    f(input.in, output.out, repl)
    t = @async begin
        close(input.in)
        close(output.in)
        close(err.in)
    end
    @test read(err.out, String) == ""
    #display(read(output.out, String))
    Base.wait(t)
    nothing
end

# Writing ^C to the repl will cause sigint, so let's not die on that
ccall(:jl_exit_on_sigint, Cvoid, (Cint,), 0)
fake_repl() do stdin_write, stdout_read, repl
	@info "Starting REPL"
	repl.specialdisplay = REPL.REPLDisplay(repl)
	repl.history_file = false

	repltask = @async REPL.run_repl(repl)

    global inc = false
    global b = Condition()
    global c = Condition()
    let cmd = "\"Hello REPL\""
        write(stdin_write, "inc || wait(b); r = $cmd; notify(c); r\r")
    end
    inc = true
    notify(b)
    wait(c)

	@info "Init REPL"
	LispREPL.initrepl(repl)

	# Tests.

	# Check we can enter lisp mode.
	write(stdin_write, ")")
	readuntil(stdout_read, "lisp> ")

	# Some basic single line tests.
	write(stdin_write, "1\n")
	readuntil(stdout_read, "lisp> ")
	write(stdin_write, "(+ 1 2)\n")
	readuntil(stdout_read, "lisp> ")

	# More complex multiline entries.
	fac_source =
	"""
	(defn fac [n]
		(if (< n 2)
			1
			(* n (fac (- n 1)))))
	"""

	write(stdin_write, fac_source)
	write(stdin_write, "(def fac_10 (fac 10))\n")
	readuntil(stdout_read, "lisp> ")

	fib_source =
	"""
	(defn fib [n]
		(if (< n 2)
			n
			(+ (fib (- n 1))
			   (fib (- n 2)))))
	"""

	write(stdin_write, fib_source)
	write(stdin_write, "(def fib_10 (fib 10))\n")
	readuntil(stdout_read, "lisp> ")

	# Backspace to return to julia mode.
	write(stdin_write, "\b")
	readuntil(stdout_read, "julia> ")

	@info "Close REPL"

	# Close REPL ^D
	write(stdin_write, '\x04')
	wait(repltask)
end

# Test the actual values defined during lisp mode usage.

@test map(fac, 0:10) == map(factorial, 0:10)
@test map(fib, 0:10) == [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

@test fac_10 == 3628800
@test fib_10 == 55


text:
struct UNIFACParam <: EoSParam
    A::PairParam{Float64}
    B::PairParam{Float64}
    C::PairParam{Float64}
    R::SingleParam{Float64}
    Q::SingleParam{Float64}
end

abstract type UNIFACModel <: ActivityModel end

struct UNIFAC{c<:EoSModel} <: UNIFACModel
    components::Array{String,1}
    icomponents::UnitRange{Int}
    groups::GroupParam
    params::UNIFACParam
    puremodel::Vector{c}
    absolutetolerance::Float64
    references::Array{String,1}
end

@registermodel UNIFAC
export UNIFAC

function UNIFAC(components; puremodel=PR,
    userlocations=String[],
     verbose=false)
    groups = GroupParam(components, ["Activity/UNIFAC/UNIFAC_groups.csv"]; verbose=verbose)

    params = getparams(groups, ["Activity/UNIFAC/UNIFAC_like.csv", "Activity/UNIFAC/UNIFAC_unlike.csv"]; userlocations=userlocations, asymmetricparams=["A","B","C"], ignore_missing_singleparams=["A","B","C"], verbose=verbose)
    A  = params["A"]
    B  = params["B"]
    C  = params["C"]
    R  = params["R"]
    Q  = params["Q"]
    icomponents = 1:length(components)

    init_puremodel = [puremodel([groups.components[i]]) for i in icomponents]
    packagedparams = UNIFACParam(A,B,C,R,Q)
    references = String[]
    model = UNIFAC(components,icomponents,groups,packagedparams,init_puremodel,1e-12,references)
    return model
end

function activity_coefficient(model::UNIFACModel,V,T,z)
    return exp.(@f(lnγ_comb)+@f(lnγ_res))
end

function lnγ_comb(model::UNIFACModel,V,T,z)
    Q = model.params.Q.values
    R = model.params.R.values

    v  = model.groups.n_flattenedgroups

    x = z ./ sum(z)

    r =[sum(v[i][k]*R[k] for k in @groups) for i in @comps]
    q =[sum(v[i][k]*Q[k] for k in @groups) for i in @comps]

    Φ = r/sum(x[i]*r[i] for i ∈ @comps)
    Φ_p = r.^(3/4)/sum(x[i]*r[i]^(3/4) for i ∈ @comps)
    θ = q/sum(x[i]*q[i] for i ∈ @comps)
    lnγ_comb = @. log(Φ_p)+(1-Φ_p)-5*q*(log(Φ/θ)+(1-Φ/θ))
    return lnγ_comb
end

function lnγ_SG(model::UNIFACModel,V,T,z)
    Q = model.params.Q.values
    R = model.params.R.values

    v  = model.groups.n_flattenedgroups

    x = z ./ sum(z)

    r =[sum(v[i][k]*R[k] for k in @groups) for i ∈ @comps]
    q =[sum(v[i][k]*Q[k] for k in @groups) for i ∈ @comps]

    Φ = r/sum(x[i]*r[i] for i ∈ @comps)
    θ = q/sum(x[i]*q[i] for i ∈ @comps)
    lnγ_SG = @. -5*q*(log(Φ/θ)+(1-Φ/θ))
    return lnγ_SG
end

function lnγ_res(model::UNIFACModel,V,T,z)
    v  = model.groups.n_flattenedgroups

    lnΓ_ = @f(lnΓ)
    lnΓi_ = @f(lnΓi)
    lnγ_res_ =  [sum(v[i][k].*(lnΓ_[k].-lnΓi_[i][k]) for k ∈ @groups) for i ∈ @comps]
    return lnγ_res_
end

function lnΓ(model::UNIFACModel,V,T,z)
    A = model.params.A.values
    B = model.params.B.values
    C = model.params.C.values
    Q = model.params.Q.values

    v  = model.groups.n_flattenedgroups

    x = z ./ sum(z)

    ψ = @. exp(-(A+B*T+C*T^2)/T)
    X = sum(v[i][:]*x[i] for i ∈ @comps) ./ sum(sum(v[i][k]*x[i] for k ∈ @groups) for i ∈ @comps)
    θ = X.*Q / dot(X,Q)

    lnΓ_ = Q.*(1 .-log.(sum(θ[m]*ψ[m,:] for m ∈ @groups)) .- sum(θ[m]*ψ[:,m]./sum(θ[n]*ψ[n,m] for n ∈ @groups) for m ∈ @groups))
    return lnΓ_
end

function lnΓi(model::UNIFACModel,V,T,z)
    A = model.params.A.values
    B = model.params.B.values
    C = model.params.C.values
    Q = model.params.Q.values

    v  = model.groups.n_flattenedgroups

    ψ = @. exp(-(A+B*T+C*T^2)/T)
    X = [v[i][:] ./ sum(v[i][k] for k ∈ @groups) for i ∈ @comps]
    θ = [X[i][:].*Q ./ sum(X[i][n]*Q[n] for n ∈ @groups) for i ∈ @comps]
    lnΓi_ = [Q.*(1 .-log.(sum(θ[i][m]*ψ[m,:] for m ∈ @groups)) .- sum(θ[i][m]*ψ[:,m]./sum(θ[i][n]*ψ[n,m] for n ∈ @groups) for m ∈ @groups)) for i ∈ @comps]
    return lnΓi_
end


text:
module PMDTools

export compute

#%%

using XAM
using BioSequences

include("likelihoods.jl")
include("align.jl")

function get_MD(record)::String
    if haskey(record, "MD")
        md = record["MD"]::String
    else
        md = ""
    end
    return md
end

function make_alignment(read, cigar, md, quals, forward = true)

    seq_aligned, ref_aligned = align(read, cigar, md)

    seq_aligned = LongDNASeq(seq_aligned)
    ref_aligned = LongDNASeq(ref_aligned)
    qual_aligned = quals

    if !forward
        reverse_complement!(seq_aligned)
        reverse_complement!(ref_aligned)
        reverse!(qual_aligned)
    end

    return seq_aligned, ref_aligned, qual_aligned

end

function make_alignment(record::BAM.Record)
    # flag = BAM.flag(record)
    read = BAM.sequence(record)
    cigar = BAM.cigar(record)
    md = record["MD"]::String
    # md = get_MD(record)
    quals = BAM.quality(record)
    forward = BAM.ispositivestrand(record)

    seq_aligned, ref_aligned, qual_aligned = make_alignment(read, cigar, md, quals, forward)
    return seq_aligned, ref_aligned, qual_aligned
end

function compute(record::BAM.Record, max_position::Int = -1)

    # get original sequence
    seq_original = BAM.sequence(record)

    # get aligned sequence, reference and quality score
    seq_aligned, ref_aligned, qual_aligned = make_alignment(record)

    # compute the PMD score
    PMD = compute_PMD_score(seq_aligned, ref_aligned, qual_aligned, max_position)

    # if max_position is set, then return slices
    if max_position > 0
        seq_original =
            seq_original[1:max_position], seq_aligned = seq_aligned[1:max_position]
    end

    return seq_original, seq_aligned, PMD
end

end

max_stars_repo_name: ChristianMichelsen/reference-free

max_issues_repo_name: ChristianMichelsen/reference-free

max_forks_repo_name: ChristianMichelsen/reference-free


text:
module TestThreadLocalStorage

using ConcurrentUtils
using Test

function test_serial()
    tls = ThreadLocalStorage(Ref{Any})
    tls[][] = 123
    @test tls[][] == 123
end

function check_concurrent_increments!(tls, ntasks, ntries)
    outputs = zeros(Int, ntasks)
    @sync begin
        for itask in 1:ntasks
            Threads.@spawn begin
                tls[][] = 0
                for _ in 1:ntries
                    tls[][] += 1
                end
                outputs[itask] = tls[][]
            end
        end
    end
    return outputs
end

function test_concurrent_increments(; ntries = 128)
    @testset for ntasks in [Threads.nthreads(), 64 * Threads.nthreads()]
        tls = ThreadLocalStorage(Ref{Int})
        actual = check_concurrent_increments!(tls, ntasks, ntries)
        @test actual == fill(ntries, ntasks)

        storages = unsafe_takestorages!(tls)
        @test length(storages) == Threads.nthreads()  # in the current implementation
        @test all(ref isa Ref{Int} for ref in storages)

        @test isempty(tls.storages)
        tls[]
        @test !isempty(tls.storages)
        empty!(tls)
        @test isempty(tls.storages)
    end
end

end  # module


text:
using JuliaRunClient
ctx = Context()

job = JuliaBatch("mywebserver")

# code for a simple webserver
webserver_script = """
using HttpServer

http = HttpHandler() do req::Request, res::Response
    Response("JuliaRun says hello from " * gethostname())
end

server = Server(http)
run(server, 8000)
"""

open("/mnt/juliabox/helloweb.jl", "w") do f
    println(f, webserver_script)
end

# start a webserver job, specifying port 8000 to be opened up
@result submitJob(ctx, job; start_script="/mnt/juliabox/helloweb.jl", run_volume="juliabox", image="juliabox", cpu="1", memory="1Gi", shell="/juliabox/scripts/master.sh", ports="8000:8000")

# check that the job has started
@result getJobStatus(ctx, job)

# Get the IP and port that was assigned for the webserver to listen on.
# The webserver may actually be running any of the physical nodes of the cluster.
# And it is running in an isolated container, with its own virtual IP address
# This IP address is accessible only to the user who started the webserver.
ip, portspec = @result getJobEndpoint(ctx, job)

# We can connect to it from here (or anything else run by this user)
using Requests
url = "http://$(ip):$(first(values(portspec)))/"

String(Requests.bytes(get(url)))

# We stop the webserver now
@result deleteJob(ctx, job; force=true)

max_stars_repo_name: grenkoca/JuliaTutorials

max_issues_repo_name: grenkoca/JuliaTutorials

max_forks_repo_name: grenkoca/JuliaTutorials


text:
function optimizeRegModel(data_dictionary) #For now, we default to all of the states being true.
    rFBAsol1 = false.*ones(length(data_dictionary["regulatoryGenes"])); # initial state
    input1state = false.*ones(length(data_dictionary["regulatoryInputs1"]));
    input2state = false.*ones(length(data_dictionary["regulatoryInputs2"]));
    state1 = false.*ones(length(data_dictionary["regulatoryGenes"])+length(data_dictionary["regulatoryInputs1"])+length(data_dictionary["regulatoryInputs2"])); #vector for entire state, 0 and 1s
    optimizeRegModel2(data_dictionary, rFBAsol1, input1state, input2state, state1)
end

function optimizeRegModel(data_dictionary, initialRegState)
    if length(initialRegState) != (length(data_dictionary["regulatoryGenes"]) + length(data_dictionary["regulatoryInputs1"]) + length(data_dictionary["regulatoryInputs2"]))
        error("InitialRegState is invalid length")
    end
    state1 = initialRegState;
    rFBAsol1 = state1[1:length(data_dictionary["regulatoryGenes"])]
    input1state = state1[(length(data_dictionary["regulatoryGenes"])+1):(length(data_dictionary["regulatoryGenes"]) + length(data_dictionary["regulatoryInputs1"]))]
    input2state = state1[(length(data_dictionary["regulatoryGenes"]) + length(data_dictionary["regulatoryInputs1"]) + 1):(length(data_dictionary["regulatoryGenes"]) + length(data_dictionary["regulatoryInputs1"]) + length(data_dictionary["regulatoryInputs2"]))]
    optimizeRegModel2(data_dictionary, rFBAsol1, input1state, input2state, state1)
end

function optimizeRegModel2(data_dictionary, rFBAsol1, input1state, input2state, state1)
rFBAsols = [rFBAsol1];
input1states = [input1state]; #pay attention to the plural, this will hold all our states
input2states = [input2state];
states = [state1];

(rFBAsol2, final_input1state, final_input2state) = solveBooleanReg(data_dictionary, rFBAsol1, input1state, input2state)

state2 = [rFBAsol2;final_input1state;final_input2state]
push!(rFBAsols, rFBAsol2)
push!(input1states, final_input1state)
push!(input2states, final_input2state)
push!(states, state2)
println("Current gene iteration completed: ", length(states))
#now the looping begins
cycleReached = false
cycleStart = []
while ~cycleReached
    rFBAsol1 = rFBAsols[length(rFBAsols)]
    input1state = input1states[length(input1states)]
    input2state = input2states[length(input2states)]
    (rFBAsol2, final_input1state, final_input2state) = solveBooleanReg(data_dictionary, rFBAsol1, input1state, input2state)
    state2 = [rFBAsol2;final_input1state;final_input2state]
    push!(rFBAsols, rFBAsol2)
    push!(input1states, final_input1state)
    push!(input2states, final_input2state)
    push!(states, state2)
    println("Current gene iteration completed: ", length(states))
    for i = 1:(length(states)-1)
        if all(states[length(states)] == states[i])
            cycleStart = i
            println("Gene steady state reached after cycle: ", cycleStart)
        end
    end
    if ~isempty(cycleStart)
        cycleReached = true
    end
end

#now lets do the final FBAs for the steady state regulatory network
FBAsols = []
DRgenes = []
constrainedRxns = []
objsols = []
regulated_data_dicts = []
dv_arrays = []
up_arrays = []
exit_flags = []
status_flags = []
k = 0
for i = cycleStart:(length(states)-1)
    k = k+1
    dgenes = []
    for j = 1:length(data_dictionary["regulatoryGenes"])
        if rFBAsols[i][j] == false
            push!(dgenes, data_dictionary["regulatoryGenes"][j])
        end
    end
    dgenes = intersect(data_dictionary["list_of_gene_symbols"], dgenes)
    (regulated_data_dictionary, hasEffect, crxns) = deleteModelGenes(data_dictionary, dgenes)
    #regulated_data_dictionary = optimize_specific_growth_rate(regulated_data_dictionary) #placeholder
    (objective_value, calculated_flux_array, dual_value_array, uptake_array, exit_flag, status_flag) = calculate_optimal_flux_distribution(regulated_data_dictionary); #change this to 2 version if standalone
    #println("Look at this:", crxns)
    push!(FBAsols, calculated_flux_array)
    push!(DRgenes, dgenes)
    push!(constrainedRxns, crxns)
    push!(objsols, objective_value)
    push!(regulated_data_dicts, regulated_data_dictionary)
    push!(dv_arrays, dual_value_array)
    push!(up_arrays, uptake_array)
    push!(exit_flags, exit_flag)
    push!(status_flags, status_flag)

#return(regulated_data_dictionary, objsols, FBAsols, dual_value_array, uptake_array, DRgenes, constrainedRxns, states, exit_flag, status_flag)
end
return(regulated_data_dicts, objsols, FBAsols, dv_arrays, up_arrays, DRgenes, constrainedRxns, states, exit_flags, status_flags)
end


text:
using MLStyle
using DataStructures

@data LExp begin
    LLet(Bool, Vector{Tuple{String, LExp}}, LExp)
    LFun(Vector{String}, LExp)
    LIf(LExp, LExp, LExp)
    LConst{T} :: T => LExp
    LVar(String)
    LBlock(Vector{LExp})
    LCall(LExp, Vector{LExp})
    LList(Vector{LExp})
    LDefine(String, LExp)
    LLoc(Any, LExp)
    LStaged(Any)

    LImport(Bool, Vector{String}, String)
    LForeign(Vector{String}, String)
    LOps(Vector{String}) # exported operators

    LCustom(LExp, Vector{Tuple{String, LExp}})    # *
    LInfix(String, Int, Bool)
    LModule(String, Vector{String}, Vector{LExp}) # *
    LMatch(LExp, Vector{Tuple{LExp, LExp}})       # *
    LBin(Vector{Union{LExp, Token}})              # *
    LAttr(LExp, String)                           # *
end

to_lexp(s :: RStr) = LLoc(get_loc(s.value), LConst(s.value.str))
to_lexp(s :: RLet) = LLoc(s.loc, LLet(s.rec, [(each.name, to_lexp(each.value)) for each in s.binds], to_lexp(s.body)))
to_lexp(s :: RFun) = LLoc(s.loc, LFun(s.args, to_lexp(s.body)))
to_lexp(s :: RMatch) = LLoc(s.loc, LMatch(to_lexp(s.sc), [(to_lexp(a), to_lexp(b)) for (a, b) in s.cases]))
to_lexp(s :: RIf) = LLoc(s.loc, LIf(to_lexp(s.cond), to_lexp(s.br1), to_lexp(s.br2)))
to_lexp(s :: RNum) =
    let app = s.neg ? (x -> -x) : (x -> x)
        LConst(app(s.int === nothing ? parse(Float64, s.float.str) : parse(Int64, s.int.str)))
    end
to_lexp(s::RBoolean) = LConst(s.value.str == "true" ? true : false)
to_lexp(s:: RNil) = LConst(nothing)
to_lexp(s:: RVar) = LVar(s.value)
to_lexp(s:: RBlock) = LLoc(s.loc, LBlock([to_lexp(each) for each in s.stmts]))
to_lexp(s:: RAttr) = isempty(s.attrs) ? to_lexp(s.value) : foldl(s.attrs, init=to_lexp(s.value)) do prev, attr
                        LAttr(prev, attr)
                     end
to_lexp(s:: RCall) = s.args === nothing ? to_lexp(s.fn) : LCall(to_lexp(s.fn), map(to_lexp, s.args))
to_lexp(s:: RList) = LLoc(s.loc, LList([to_lexp(e) for e in s.elts]))
to_lexp(s:: RTop) = isempty(s.tl) ? to_lexp(s.hd) : let tl = s.tl
        binseq = Union{LExp, Token}[]
        push!(binseq, to_lexp(s.hd))
        for (op, e) in tl
            push!(binseq, op.name)
            push!(binseq, to_lexp(e))
        end
        LBin(binseq)
    end

function _pack(a::RCustom)
    s = []
    while a isa Custom
        v = to_lexp(a.value)
        if a.kw === nothing
            push!(s, ("", v))
        else
            push!(s, (a.kw, v))
        end
        a = a.next
    end
    s
end
_pack(::Nothing) = []
to_lexp(s:: ROps)  = LLoc(s.loc, LOps(s.names))
to_lexp(s:: RInfix) = LLoc(s.loc, LInfix(s.name, parse(Int, s.prec), s.is_right))
to_lexp(s:: RExp) = !s.do_custom ? to_lexp(s.top) : LCustom(to_lexp(s.top), _pack(s.custom))
to_lexp(s:: RDefine) = LLoc(s.loc, LDefine(s.name, to_lexp(s.value)))
to_lexp(s:: RModule) = LLoc(s.loc, LModule(s.name, s.params, [to_lexp(e) for e in s.stmts]))

to_lexp(s:: RImport) =
    @when let [init..., last] = s.paths
        LLoc(s.loc, LImport(s.is_qual, collect(init), last))
    @otherwise
        throw("invalid import")
    end

to_lexp(s:: RForeign) =
    @when let [init..., last] = s.paths
        LLoc(s.loc, LForeign(collect(init), last))
    @otherwise
        throw("invalid foreign import")
    end

max_forks_repo_name: thautwarm/Rupy


text:
using Match
using Printf

function cpureset!(console::Console)
  cpu = console.cpu
  cpu.PC = cpuread16(console, 0xFFFC)
  cpu.SP = 0xFD
  setflags!(cpu, 0x0024)
end

function cpuread(console::Console, address::UInt16)::UInt8
  if address < 0x2000
    @inbounds console.RAM[(address & 0x07FF) + 1]
  elseif address < 0x4000
    ppureadregister(console, 0x2000 + (address & 0x0007))
  elseif address == 0x4014
    ppureadregister(console, address)
  elseif address == 0x4015
    readregister(console.apu, address)
  elseif address == 0x4016
    read(console.controller1)
  elseif address == 0x4017
    read(console.controller2)
  else
    read(console.mapper, console.cartridge, address)
  end
end

function cpuwrite!(console::Console, address::UInt16, val::UInt8)
  if address < 0x2000
    @inbounds console.RAM[address & 0x07FF + 1] = val
  elseif address < 0x4000
    ppuwriteregister!(console, 0x2000 + (address & 0x07), val)
  elseif address < 0x4014
    apuwriteregister!(console, address, val)
  elseif address == 0x4014
    ppuwriteregister!(console, address, val)
  elseif address == 0x4015
    apuwriteregister!(console, address, val)
  elseif address == 0x4016
    write!(console.controller1, val)
    write!(console.controller2, val)
  elseif address == 0x4017
    apuwriteregister!(console, address, val)
  elseif address < 0x6000
      # TODO: I/O registers
  else
    write!(console.mapper, console.cartridge, address, val)
  end
end

# PrintInstruction prints the current CPU state
function printinstruction(console::Console)
  cpu = console.cpu
  opcode = cpuread(console, cpu.PC)
  @inbounds bytes = InstructionSizes[opcode + 1]
  @inbounds name = InstructionNames[opcode + 1]
  w0 = @sprintf("%02X", cpuread(console, cpu.PC + 0x00))
  w1 = @sprintf("%02X", cpuread(console, cpu.PC + 0x01))
  w2 = @sprintf("%02X", cpuread(console, cpu.PC + 0x02))
  if bytes < 2
    w1 = "  "
  end
  if bytes < 3
    w2 = "  "
  end
  @sprintf("%4X  %s %s %s  %s %28s A:%02X X:%02X Y:%02X P:%02X SP:%02X CYC:%3d\n",
      cpu.PC, w0, w1, w2, name, "", cpu.A, cpu.X, cpu.Y, flags(cpu), cpu.SP,
      UInt32((cpu.cycles * 3) % 341))
end

# pagesDiffer returns true if the two addresses reference different pages
function pagesdiffer(a::UInt16, b::UInt16)::Bool
  return (a & 0xFF00) != (b & 0xFF00)
end

# addBranchCycles adds a cycle for taking a branch and adds another cycle
# if the branch jumps to a new page
function addbranchcycles!(cpu::CPU, address::UInt16, pc::UInt16)
  cpu.cycles += 1
  if pagesdiffer(pc, address)
    cpu.cycles += 1
  end
end

function compare(cpu::CPU, a::UInt8, b::UInt8)
  setzn!(cpu, a - b)
  if a >= b
    cpu.C = 1
  else
    cpu.C = 0
  end
end

# Read16 reads two bytes using Read to return a double-word value
function cpuread16(console::Console, address::UInt16)::UInt16
  lo = cpuread(console, address)
  hi = cpuread(console, address + 0x0001)
  return (UInt16(hi) << 8) | lo
end

# read16bug emulates a 6502 bug that caused the low byte to wrap without
# incrementing the high byte
function cpuread16bug(console::Console, address::UInt16)::UInt16
  a = address
  b = (a & 0xFF00) | ((a % UInt8) + 0x01)
  lo = cpuread(console, a)
  hi = cpuread(console, b)
  return (UInt16(hi) << 8) | lo
end

# push pushes a byte onto the stack
function push!(console::Console, val::UInt8)
  cpu = console.cpu
  cpuwrite!(console, 0x100 | cpu.SP, val)
  cpu.SP -= 0x01
end

# pull pops a byte from the stack
function pull!(console::Console)::UInt8
  cpu = console.cpu
  cpu.SP += 0x01
  return cpuread(console, 0x100 | cpu.SP)
end

# push16 pushes two bytes onto the stack
function push16!(console::Console, val::UInt16)
  cpu = console.cpu
  hi = UInt8(val >> 8)
  lo = val % UInt8
  push!(console, hi)
  push!(console, lo)
end

# pull16 pops two bytes from the stack
function pull16!(console::Console)::UInt16
  lo = pull!(console)
  hi = UInt16(pull!(console))
  return (hi << 8) | lo
end

# Flags returns the processor status flags
function flags(cpu::CPU)::UInt8
  flags = 0x00
  flags |= (cpu.C << 0)
  flags |= (cpu.Z << 1)
  flags |= (cpu.I << 2)
  flags |= (cpu.D << 3)
  flags |= (cpu.B << 4)
  flags |= (cpu.U << 5)
  flags |= (cpu.V << 6)
  flags |= (cpu.N << 7)
  flags
end

# SetFlags sets the processor status flags
function setflags!(cpu::CPU, flags::UInt16)
  cpu.C = (flags >> 0) & 1
  cpu.Z = (flags >> 1) & 1
  cpu.I = (flags >> 2) & 1
  cpu.D = (flags >> 3) & 1
  cpu.B = (flags >> 4) & 1
  cpu.U = (flags >> 5) & 1
  cpu.V = (flags >> 6) & 1
  cpu.N = (flags >> 7) & 1
end

# setZ sets the zero flag if the argument is zero
function setz!(cpu::CPU, val::UInt8)
  if val == 0
    cpu.Z = 1
  else
    cpu.Z = 0
  end
end

# setN sets the negative flag if the argument is negative (high bit is set)
function setn!(cpu::CPU, val::UInt8)
  if (val & 0x80) != 0
    cpu.N = 1
  else
    cpu.N = 0
  end
end

# setZN sets the zero flag and the negative flag
function setzn!(cpu::CPU, val::UInt8)
  setz!(cpu, val)
  setn!(cpu, val)
end

# Step executes a single CPU instruction
function cpustep!(console::Console, cpu::CPU)::Int32
  if cpu.stall > 0
    cpu.stall -= Int32(1)
    return Int32(1)
  end

  prevCycles = cpu.cycles

  interruptInt = UInt8(cpu.interrupt)
  if interruptInt == 0x01
    nmi!(console)
  elseif interruptInt == 0x02
    irq!(console)
  end
  cpu.interrupt = InterruptNone::InterruptTypes

  opcode = cpuread(console, cpu.PC)
  @inbounds mode = InstructionModes[opcode + 1]

  address = 0x0000
  pageCrossed = false
  modeInt = UInt8(mode)
  if modeInt == 0x01
    address = cpuread16(console, cpu.PC + 0x01)
  elseif modeInt == 0x02
    address = cpuread16(console, cpu.PC + 0x01) + cpu.X
    pageCrossed = pagesdiffer(address - cpu.X, address)
  elseif modeInt == 0x03
    address = cpuread16(console, cpu.PC + 0x01) + cpu.Y
    pageCrossed = pagesdiffer(address - cpu.Y, address)
  elseif modeInt == 0x04
    address = 0x0000
  elseif modeInt == 0x05
    address = cpu.PC + 0x01
  elseif modeInt == 0x06
    address = 0x0000
  elseif modeInt == 0x07
    address = cpuread16bug(console, UInt16(cpuread(console, cpu.PC + 0x01) + cpu.X))
  elseif modeInt == 0x08
    address = cpuread16bug(console, cpuread16(console, cpu.PC + 0x01))
  elseif modeInt == 0x09
    address = cpuread16bug(console, UInt16(cpuread(console, cpu.PC + 0x01))) + cpu.Y
    pageCrossed = pagesdiffer(address - cpu.Y, address)
  elseif modeInt == 0x0A
    offset = cpuread(console, cpu.PC + 0x01)
    if offset < 0x80
      address = cpu.PC + 0x02 + offset
    else
      address = cpu.PC + 0x02 + offset - 0x100
    end
  elseif modeInt == 0x0B
    address = UInt16(cpuread(console, cpu.PC + 0x01))
  elseif modeInt == 0x0C
    address = (UInt16(cpuread(console, cpu.PC + 0x01)) + cpu.X) & 0xff
  elseif modeInt == 0x0D
    address = (UInt16(cpuread(console, cpu.PC + 0x01)) + cpu.Y) & 0xff
  end

  @inbounds cpu.PC += InstructionSizes[opcode + 1]
  @inbounds cpu.cycles += InstructionCycles[opcode + 1]
  if pageCrossed
    @inbounds cpu.cycles += InstructionPageCycles[opcode + 1]
  end

  if opcode == 0
    brk!(console, address)
  elseif opcode == 1
    ora!(console, address)
  elseif opcode == 2
    kil!(console, address)
  elseif opcode == 3
    slo!(console, address)
  elseif opcode == 4
    nop!(console, address)
  elseif opcode == 5
    ora!(console, address)
  elseif opcode == 6
    asl!(console, address, mode)
  elseif opcode == 7
    slo!(console, address)
  elseif opcode == 8
    php!(console)
  elseif opcode == 9
    ora!(console, address)
  elseif opcode == 10
    asl!(console, address, mode)
  elseif opcode == 11
    anc!(console, address)
  elseif opcode == 12
    nop!(console, address)
  elseif opcode == 13
    ora!(console, address)
  elseif opcode == 14
    asl!(console, address, mode)
  elseif opcode == 15
    slo!(console, address)
  elseif opcode == 16
    bpl!(console, address, cpu.PC)
  elseif opcode == 17
    ora!(console, address)
  elseif opcode == 18
    kil!(console, address)
  elseif opcode == 19
    slo!(console, address)
  elseif opcode == 20
    nop!(console, address)
  elseif opcode == 21
    ora!(console, address)
  elseif opcode == 22
    asl!(console, address, mode)
  elseif opcode == 23
    slo!(console, address)
  elseif opcode == 24
    clc!(console, address)
  elseif opcode == 25
    ora!(console, address)
  elseif opcode == 26
    nop!(console, address)
  elseif opcode == 27
    slo!(console, address)
  elseif opcode == 28
    nop!(console, address)
  elseif opcode == 29
    ora!(console, address)
  elseif opcode == 30
    asl!(console, address, mode)
  elseif opcode == 31
    slo!(console, address)
  elseif opcode == 32
    jsr!(console, address)
  elseif opcode == 33
    and!(console, address)
  elseif opcode == 34
    kil!(console, address)
  elseif opcode == 35
    rla!(console, address)
  elseif opcode == 36
    bit!(console, address)
  elseif opcode == 37
    and!(console, address)
  elseif opcode == 38
    rol!(console, address, mode)
  elseif opcode == 39
    rla!(console, address)
  elseif opcode == 40
    plp!(console, address)
  elseif opcode == 41
    and!(console, address)
  elseif opcode == 42
    rol!(console, address, mode)
  elseif opcode == 43
    anc!(console, address)
  elseif opcode == 44
    bit!(console, address)
  elseif opcode == 45
    and!(console, address)
  elseif opcode == 46
    rol!(console, address, mode)
  elseif opcode == 47
    rla!(console, address)
  elseif opcode == 48
    bmi!(console, address, cpu.PC)
  elseif opcode == 49
    and!(console, address)
  elseif opcode == 50
    kil!(console, address)
  elseif opcode == 51
    rla!(console, address)
  elseif opcode == 52
    nop!(console, address)
  elseif opcode == 53
    and!(console, address)
  elseif opcode == 54
    rol!(console, address, mode)
  elseif opcode == 55
    rla!(console, address)
  elseif opcode == 56
    sec!(console, address)
  elseif opcode == 57
    and!(console, address)
  elseif opcode == 58
    nop!(console, address)
  elseif opcode == 59
    rla!(console, address)
  elseif opcode == 60
    nop!(console, address)
  elseif opcode == 61
    and!(console, address)
  elseif opcode == 62
    rol!(console, address, mode)
  elseif opcode == 63
    rla!(console, address)
  elseif opcode == 64
    rti!(console, address)
  elseif opcode == 65
    eor!(console, address)
  elseif opcode == 66
    kil!(console, address)
  elseif opcode == 67
    sre!(console, address)
  elseif opcode == 68
    nop!(console, address)
  elseif opcode == 69
    eor!(console, address)
  elseif opcode == 70
    lsr!(console, address, mode)
  elseif opcode == 71
    sre!(console, address)
  elseif opcode == 72
    pha!(console, address)
  elseif opcode == 73
    eor!(console, address)
  elseif opcode == 74
    lsr!(console, address, mode)
  elseif opcode == 75
    alr!(console, address)
  elseif opcode == 76
    jmp!(console, address)
  elseif opcode == 77
    eor!(console, address)
  elseif opcode == 78
    lsr!(console, address, mode)
  elseif opcode == 79
    sre!(console, address)
  elseif opcode == 80
    bvc!(console, address, cpu.PC)
  elseif opcode == 81
    eor!(console, address)
  elseif opcode == 82
    kil!(console, address)
  elseif opcode == 83
    sre!(console, address)
  elseif opcode == 84
    nop!(console, address)
  elseif opcode == 85
    eor!(console, address)
  elseif opcode == 86
    lsr!(console, address, mode)
  elseif opcode == 87
    sre!(console, address)
  elseif opcode == 88
    cli!(console, address)
  elseif opcode == 89
    eor!(console, address)
  elseif opcode == 90
    nop!(console, address)
  elseif opcode == 91
    sre!(console, address)
  elseif opcode == 92
    nop!(console, address)
  elseif opcode == 93
    eor!(console, address)
  elseif opcode == 94
    lsr!(console, address, mode)
  elseif opcode == 95
    sre!(console, address)
  elseif opcode == 96
    rts!(console, address)
  elseif opcode == 97
    adc!(console, address)
  elseif opcode == 98
    kil!(console, address)
  elseif opcode == 99
    rra!(console, address)
  elseif opcode == 100
    nop!(console, address)
  elseif opcode == 101
    adc!(console, address)
  elseif opcode == 102
    ror!(console, address, mode)
  elseif opcode == 103
    rra!(console, address)
  elseif opcode == 104
    pla!(console, address)
  elseif opcode == 105
    adc!(console, address)
  elseif opcode == 106
    ror!(console, address, mode)
  elseif opcode == 107
    arr!(console, address)
  elseif opcode == 108
    jmp!(console, address)
  elseif opcode == 109
    adc!(console, address)
  elseif opcode == 110
    ror!(console, address, mode)
  elseif opcode == 111
    rra!(console, address)
  elseif opcode == 112
    bvs!(console, address, cpu.PC)
  elseif opcode == 113
    adc!(console, address)
  elseif opcode == 114
    kil!(console, address)
  elseif opcode == 115
    rra!(console, address)
  elseif opcode == 116
    nop!(console, address)
  elseif opcode == 117
    adc!(console, address)
  elseif opcode == 118
    ror!(console, address, mode)
  elseif opcode == 119
    rra!(console, address)
  elseif opcode == 120
    sei!(console)
  elseif opcode == 121
    adc!(console, address)
  elseif opcode == 122
    nop!(console, address)
  elseif opcode == 123
    rra!(console, address)
  elseif opcode == 124
    nop!(console, address)
  elseif opcode == 125
    adc!(console, address)
  elseif opcode == 126
    ror!(console, address, mode)
  elseif opcode == 127
    rra!(console, address)
  elseif opcode == 128
    nop!(console, address)
  elseif opcode == 129
    sta!(console, address)
  elseif opcode == 130
    nop!(console, address)
  elseif opcode == 131
    sax!(console, address)
  elseif opcode == 132
    sty!(console, address)
  elseif opcode == 133
    sta!(console, address)
  elseif opcode == 134
    stx!(console, address)
  elseif opcode == 135
    sax!(console, address)
  elseif opcode == 136
    dey!(console, address)
  elseif opcode == 137
    nop!(console, address)
  elseif opcode == 138
    txa!(console, address)
  elseif opcode == 139
    xaa!(console, address)
  elseif opcode == 140
    sty!(console, address)
  elseif opcode == 141
    sta!(console, address)
  elseif opcode == 142
    stx!(console, address)
  elseif opcode == 143
    sax!(console, address)
  elseif opcode == 144
    bcc!(console, address, cpu.PC)
  elseif opcode == 145
    sta!(console, address)
  elseif opcode == 146
    kil!(console, address)
  elseif opcode == 147
    ahx!(console, address)
  elseif opcode == 148
    sty!(console, address)
  elseif opcode == 149
    sta!(console, address)
  elseif opcode == 150
    stx!(console, address)
  elseif opcode == 151
    sax!(console, address)
  elseif opcode == 152
    tya!(console, address)
  elseif opcode == 153
    sta!(console, address)
  elseif opcode == 154
    txs!(console, address)
  elseif opcode == 155
    tas!(console, address)
  elseif opcode == 156
    shy!(console, address)
  elseif opcode == 157
    sta!(console, address)
  elseif opcode == 158
    shx!(console, address)
  elseif opcode == 159
    ahx!(console, address)
  elseif opcode == 160
    ldy!(console, address)
  elseif opcode == 161
    lda!(console, address)
  elseif opcode == 162
    ldx!(console, address)
  elseif opcode == 163
    lax!(console, address)
  elseif opcode == 164
    ldy!(console, address)
  elseif opcode == 165
    lda!(console, address)
  elseif opcode == 166
    ldx!(console, address)
  elseif opcode == 167
    lax!(console, address)
  elseif opcode == 168
    tay!(console, address)
  elseif opcode == 169
    lda!(console, address)
  elseif opcode == 170
    tax!(console, address)
  elseif opcode == 171
    lax!(console, address)
  elseif opcode == 172
    ldy!(console, address)
  elseif opcode == 173
    lda!(console, address)
  elseif opcode == 174
    ldx!(console, address)
  elseif opcode == 175
    lax!(console, address)
  elseif opcode == 176
    bcs!(console, address, cpu.PC)
  elseif opcode == 177
    lda!(console, address)
  elseif opcode == 178
    kil!(console, address)
  elseif opcode == 179
    lax!(console, address)
  elseif opcode == 180
    ldy!(console, address)
  elseif opcode == 181
    lda!(console, address)
  elseif opcode == 182
    ldx!(console, address)
  elseif opcode == 183
    lax!(console, address)
  elseif opcode == 184
    clv!(console, address)
  elseif opcode == 185
    lda!(console, address)
  elseif opcode == 186
    tsx!(console, address)
  elseif opcode == 187
    las!(console, address)
  elseif opcode == 188
    ldy!(console, address)
  elseif opcode == 189
    lda!(console, address)
  elseif opcode == 190
    ldx!(console, address)
  elseif opcode == 191
    lax!(console, address)
  elseif opcode == 192
    cpy!(console, address)
  elseif opcode == 193
    cmp!(console, address)
  elseif opcode == 194
    nop!(console, address)
  elseif opcode == 195
    dcp!(console, address)
  elseif opcode == 196
    cpy!(console, address)
  elseif opcode == 197
    cmp!(console, address)
  elseif opcode == 198
    dec!(console, address)
  elseif opcode == 199
    dcp!(console, address)
  elseif opcode == 200
    iny!(console, address)
  elseif opcode == 201
    cmp!(console, address)
  elseif opcode == 202
    dex!(console, address)
  elseif opcode == 203
    axs!(console, address)
  elseif opcode == 204
    cpy!(console, address)
  elseif opcode == 205
    cmp!(console, address)
  elseif opcode == 206
    dec!(console, address)
  elseif opcode == 207
    dcp!(console, address)
  elseif opcode == 208
    bne!(console, address, cpu.PC)
  elseif opcode == 209
    cmp!(console, address)
  elseif opcode == 210
    kil!(console, address)
  elseif opcode == 211
    dcp!(console, address)
  elseif opcode == 212
    nop!(console, address)
  elseif opcode == 213
    cmp!(console, address)
  elseif opcode == 214
    dec!(console, address)
  elseif opcode == 215
    dcp!(console, address)
  elseif opcode == 216
    cld!(console, address)
  elseif opcode == 217
    cmp!(console, address)
  elseif opcode == 218
    nop!(console, address)
  elseif opcode == 219
    dcp!(console, address)
  elseif opcode == 220
    nop!(console, address)
  elseif opcode == 221
    cmp!(console, address)
  elseif opcode == 222
    dec!(console, address)
  elseif opcode == 223
    dcp!(console, address)
  elseif opcode == 224
    cpx!(console, address)
  elseif opcode == 225
    sbc!(console, address)
  elseif opcode == 226
    nop!(console, address)
  elseif opcode == 227
    isc!(console, address)
  elseif opcode == 228
    cpx!(console, address)
  elseif opcode == 229
    sbc!(console, address)
  elseif opcode == 230
    inc!(console, address)
  elseif opcode == 231
    isc!(console, address)
  elseif opcode == 232
    inx!(console, address)
  elseif opcode == 233
    sbc!(console, address)
  elseif opcode == 234
    nop!(console, address)
  elseif opcode == 235
    sbc!(console, address)
  elseif opcode == 236
    cpx!(console, address)
  elseif opcode == 237
    sbc!(console, address)
  elseif opcode == 238
    inc!(console, address)
  elseif opcode == 239
    isc!(console, address)
  elseif opcode == 240
    beq!(console, address, cpu.PC)
  elseif opcode == 241
    sbc!(console, address)
  elseif opcode == 242
    kil!(console, address)
  elseif opcode == 243
    isc!(console, address)
  elseif opcode == 244
    nop!(console, address)
  elseif opcode == 245
    sbc!(console, address)
  elseif opcode == 246
    inc!(console, address)
  elseif opcode == 247
    isc!(console, address)
  elseif opcode == 248
    sed!(console, address)
  elseif opcode == 249
    sbc!(console, address)
  elseif opcode == 250
    nop!(console, address)
  elseif opcode == 251
    isc!(console, address)
  elseif opcode == 252
    nop!(console, address)
  elseif opcode == 253
    sbc!(console, address)
  elseif opcode == 254
    inc!(console, address)
  elseif opcode == 255
    isc!(console, address)
  end

  return Int32(cpu.cycles - prevCycles)
end

# NMI - Non-Maskable Interrupt
function nmi!(console::Console)
  cpu = console.cpu
  push16!(console, cpu.PC)
  php!(console)
  cpu.PC = cpuread16(console, 0xFFFA)
  cpu.I = 1
  cpu.cycles += 7
end

# IRQ - IRQ Interrupt
function irq!(console::Console)
  cpu = console.cpu
  push16!(console, cpu.PC)
  php!(console)
  cpu.PC = cpuread16(console, 0xFFFE)
  cpu.I = 1
  cpu.cycles += 7
end

# ADC - Add with Carry
function adc!(console::Console, address::UInt16)
  cpu = console.cpu
  a = cpu.A
  b = cpuread(console, address)
  c = cpu.C
  sum = UInt16(a) + UInt16(b) + UInt16(c)
  cpu.A = sum % UInt8
  setzn!(cpu, cpu.A)
  if sum > 0xFF
    cpu.C = 1
  else
    cpu.C = 0
  end
  if ((a ⊻ b) & 0x80) == 0 && ((a ⊻ cpu.A) & 0x80) != 0
    cpu.V = 1
  else
    cpu.V = 0
  end
end

# AND - Logical AND
function and!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.A = cpu.A & cpuread(console, address)
  setzn!(cpu, cpu.A)
end

# ASL - Arithmetic Shift Left
function asl!(console::Console, address::UInt16, mode::AddressingModes)
  cpu = console.cpu
  if mode == ModeAccumulator::AddressingModes
    cpu.C = (cpu.A >> 7) & 1
    cpu.A <<= 1
    setzn!(cpu, cpu.A)
  else
    val = cpuread(console, address)
    cpu.C = (val >> 7) & 1
    val <<= 1
    cpuwrite!(console, address, val)
    setzn!(cpu, val)
  end
end

# BCC - Branch if Carry Clear
function bcc!(console::Console, address::UInt16, pc::UInt16)
  cpu = console.cpu
  if cpu.C == 0
    cpu.PC = address
    addbranchcycles!(cpu, address, pc)
  end
end

# BCS - Branch if Carry Set
function bcs!(console::Console, address::UInt16, pc::UInt16)
  cpu = console.cpu
  if cpu.C != 0
    cpu.PC = address
    addbranchcycles!(cpu, address, pc)
  end
end

# BEQ - Branch if Equal
function beq!(console::Console, address::UInt16, pc::UInt16)
  cpu = console.cpu
  if cpu.Z != 0
    cpu.PC = address
    addbranchcycles!(cpu, address, pc)
  end
end

# BIT - Bit Test
function bit!(console::Console, address::UInt16)
  cpu = console.cpu
  val = cpuread(console, address)
  cpu.V = (val >> 6) & 1
  setz!(cpu, val & cpu.A)
  setn!(cpu, val)
end

# BMI - Branch if Minus
function bmi!(console::Console, address::UInt16, pc::UInt16)
  cpu = console.cpu
  if cpu.N != 0
    cpu.PC = address
    addbranchcycles!(cpu, address, pc)
  end
end

# BNE - Branch if Not Equal
function bne!(console::Console, address::UInt16, pc::UInt16)
  cpu = console.cpu
  if cpu.Z == 0
    cpu.PC = address
    addbranchcycles!(cpu, address, pc)
  end
end

# BPL - Branch if Positive
function bpl!(console::Console, address::UInt16, pc::UInt16)
  cpu = console.cpu
  if cpu.N == 0
    cpu.PC = address
    addbranchcycles!(cpu, address, pc)
  end
end

# BRK - Force Interrupt
function brk!(console::Console, address::UInt16)
  cpu = console.cpu
  push16!(console, cpu.PC)
  php!(console)
  sei!(console)
  cpu.PC = cpuread16(console, 0xFFFE)
end

# BVC - Branch if Overflow Clear
function bvc!(console::Console, address::UInt16, pc::UInt16)
  cpu = console.cpu
  if cpu.V == 0
    cpu.PC = address
    addbranchcycles!(cpu, address, pc)
  end
end

# BVS - Branch if Overflow Set
function bvs!(console::Console, address::UInt16, pc::UInt16)
  cpu = console.cpu
  if cpu.V != 0
    cpu.PC = address
    addbranchcycles!(cpu, address, pc)
  end
end

# CLC - Clear Carry Flag
function clc!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.C = 0
end

# CLD - Clear Decimal Mode
function cld!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.D = 0
end

# CLI - Clear Interrupt Disable
function cli!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.I = 0
end

# CLV - Clear Overflow Flag
function clv!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.V = 0
end

# CMP - Compare
function cmp!(console::Console, address::UInt16)
  cpu = console.cpu
  val = cpuread(console, address)
  compare(cpu, cpu.A, val)
end

# CPX - Compare X Register
function cpx!(console::Console, address::UInt16)
  cpu = console.cpu
  val = cpuread(console, address)
  compare(cpu, cpu.X, val)
end

# CPY - Compare Y Register
function cpy!(console::Console, address::UInt16)
  cpu = console.cpu
  val = cpuread(console, address)
  compare(cpu, cpu.Y, val)
end

# DEC - Decrement Memory
function dec!(console::Console, address::UInt16)
  cpu = console.cpu
  val = cpuread(console, address) - 0x01
  cpuwrite!(console, address, val)
  setzn!(cpu, val)
end

# DEX - Decrement X Register
function dex!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.X -= 0x01
  setzn!(cpu, cpu.X)
end

# DEY - Decrement Y Register
function dey!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.Y -= 0x01
  setzn!(cpu, cpu.Y)
end

# EOR - Exclusive OR
function eor!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.A = cpu.A ⊻ cpuread(console, address)
  setzn!(cpu, cpu.A)
end

# INC - Increment Memory
function inc!(console::Console, address::UInt16)
  cpu = console.cpu
  val = cpuread(console, address) + 0x01
  cpuwrite!(console, address, val)
  setzn!(cpu, val)
end

# INX - Increment X Register
function inx!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.X += 0x01
  setzn!(cpu, cpu.X)
end

# INY - Increment Y Register
function iny!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.Y += 0x01
  setzn!(cpu, cpu.Y)
end

# JMP - Jump
function jmp!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.PC = address
end

# JSR - Jump to Subroutine
function jsr!(console::Console, address::UInt16)
  cpu = console.cpu
  push16!(console, cpu.PC - 0x01)
  cpu.PC = address
end

# LDA - Load Accumulator
function lda!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.A = cpuread(console, address)
  setzn!(cpu, cpu.A)
end

# LDX - Load X Register
function ldx!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.X = cpuread(console, address)
  setzn!(cpu, cpu.X)
end

# LDY - Load Y Register
function ldy!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.Y = cpuread(console, address)
  setzn!(cpu, cpu.Y)
end

# LSR - Logical Shift Right
function lsr!(console::Console, address::UInt16, mode::AddressingModes)
  cpu = console.cpu
  if mode == ModeAccumulator::AddressingModes
    cpu.C = cpu.A & 1
    cpu.A >>= 1
    setzn!(cpu, cpu.A)
  else
    val = cpuread(console, address)
    cpu.C = val & 1
    val >>= 1
    cpuwrite!(console, address, val)
    setzn!(cpu, val)
  end
end

# NOP - No Operation
function nop!(console::Console, address::UInt16)
end

# ORA - Logical Inclusive OR
function ora!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.A = cpu.A | cpuread(console, address)
  setzn!(cpu, cpu.A)
end

# PHA - Push Accumulator
function pha!(console::Console, address::UInt16)
  cpu = console.cpu
  push!(console, cpu.A)
end

# PHP - Push Processor Status
function php!(console::Console)
  cpu = console.cpu
  push!(console, flags(cpu) | 0x10)
end

# PLA - Pull Accumulator
function pla!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.A = pull!(console)
  setzn!(cpu, cpu.A)
end

# PLP - Pull Processor Status
function plp!(console::Console, address::UInt16)
  cpu = console.cpu
  setflags!(cpu, (pull!(console)&0x00EF) | 0x20)
end

# ROL - Rotate Left
function rol!(console::Console, address::UInt16, mode::AddressingModes)
  cpu = console.cpu
  if mode == ModeAccumulator::AddressingModes
    c = cpu.C
    cpu.C = (cpu.A >> 7) & 1
    cpu.A = (cpu.A << 1) | c
    setzn!(cpu, cpu.A)
  else
    c = cpu.C
    val = cpuread(console, address)
    cpu.C = (val >> 7) & 1
    val = (val << 1) | c
    cpuwrite!(console, address, val)
    setzn!(cpu, val)
  end
end

# ROR - Rotate Right
function ror!(console::Console, address::UInt16, mode::AddressingModes)
  cpu = console.cpu
  if mode == ModeAccumulator::AddressingModes
    c = cpu.C
    cpu.C = cpu.A & 1
    cpu.A = (cpu.A >> 1) | (c << 7)
    setzn!(cpu, cpu.A)
  else
    c = cpu.C
    val = cpuread(console, address)
    cpu.C = val & 1
    val = (val >> 1) | (c << 7)
    cpuwrite!(console, address, val)
    setzn!(cpu, val)
  end
end

# RTI - Return from Interrupt
function rti!(console::Console, address::UInt16)
  cpu = console.cpu
  setflags!(cpu, (pull!(console)&0x00EF) | 0x20)
  cpu.PC = pull16!(console)
end

# RTS - Return from Subroutine
function rts!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.PC = pull16!(console) + 1
end

# SBC - Subtract with Carry
function sbc!(console::Console, address::UInt16)
  cpu = console.cpu
  a = cpu.A
  b = cpuread(console, address)
  c = cpu.C
  sum = Int16(a) - Int16(b) - (1 - Int16(c))
  cpu.A = sum % UInt8
  setzn!(cpu, cpu.A)
  if sum >= 0
    cpu.C = 1
  else
    cpu.C = 0
  end
  if ((a ⊻ b) & 0x80) != 0 && ((a ⊻ cpu.A) & 0x80) != 0
    cpu.V = 1
  else
    cpu.V = 0
  end
end

# SEC - Set Carry Flag
function sec!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.C = 1
end

# SED - Set Decimal Flag
function sed!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.D = 1
end

# SEI - Set Interrupt Disable
function sei!(console::Console)
  cpu = console.cpu
  cpu.I = 1
end

# STA - Store Accumulator
function sta!(console::Console, address::UInt16)
  cpu = console.cpu
  cpuwrite!(console, address, cpu.A)
end

# STX - Store X Register
function stx!(console::Console, address::UInt16)
  cpu = console.cpu
  cpuwrite!(console, address, cpu.X)
end

# STY - Store Y Register
function sty!(console::Console, address::UInt16)
  cpu = console.cpu
  cpuwrite!(console, address, cpu.Y)
end

# TAX - Transfer Accumulator to X
function tax!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.X = cpu.A
  setzn!(cpu, cpu.X)
end

# TAY - Transfer Accumulator to Y
function tay!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.Y = cpu.A
  setzn!(cpu, cpu.Y)
end

# TSX - Transfer Stack Pointer to X
function tsx!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.X = cpu.SP
  setzn!(cpu, cpu.X)
end

# TXA - Transfer X to Accumulator
function txa!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.A = cpu.X
  setzn!(cpu, cpu.A)
end

# TXS - Transfer X to Stack Pointer
function txs!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.SP = cpu.X
end

# TYA - Transfer Y to Accumulator
function tya!(console::Console, address::UInt16)
  cpu = console.cpu
  cpu.A = cpu.Y
  setzn!(cpu, cpu.A)
end

# illegal opcodes below

function ahx!(console::Console, address::UInt16)
end

function alr!(console::Console, address::UInt16)
end

function anc!(console::Console, address::UInt16)
end

function arr!(console::Console, address::UInt16)
end

function axs!(console::Console, address::UInt16)
end

function dcp!(console::Console, address::UInt16)
end

function isc!(console::Console, address::UInt16)
end

function kil!(console::Console, address::UInt16)
end

function las!(console::Console, address::UInt16)
end

function lax!(console::Console, address::UInt16)
end

function rla!(console::Console, address::UInt16)
end

function rra!(console::Console, address::UInt16)
end

function sax!(console::Console, address::UInt16)
end

function shx!(console::Console, address::UInt16)
end

function shy!(console::Console, address::UInt16)
end

function slo!(console::Console, address::UInt16)
end

function sre!(console::Console, address::UInt16)
end

function tas!(console::Console, address::UInt16)
end

function xaa!(console::Console, address::UInt16)
end

# function table for each instruction
const InstructionTable = [
  brk!, ora!, kil!, slo!, nop!, ora!, asl!, slo!,
  php!, ora!, asl!, anc!, nop!, ora!, asl!, slo!,
  bpl!, ora!, kil!, slo!, nop!, ora!, asl!, slo!,
  clc!, ora!, nop!, slo!, nop!, ora!, asl!, slo!,
  jsr!, and!, kil!, rla!, bit!, and!, rol!, rla!,
  plp!, and!, rol!, anc!, bit!, and!, rol!, rla!,
  bmi!, and!, kil!, rla!, nop!, and!, rol!, rla!,
  sec!, and!, nop!, rla!, nop!, and!, rol!, rla!,
  rti!, eor!, kil!, sre!, nop!, eor!, lsr!, sre!,
  pha!, eor!, lsr!, alr!, jmp!, eor!, lsr!, sre!,
  bvc!, eor!, kil!, sre!, nop!, eor!, lsr!, sre!,
  cli!, eor!, nop!, sre!, nop!, eor!, lsr!, sre!,
  rts!, adc!, kil!, rra!, nop!, adc!, ror!, rra!,
  pla!, adc!, ror!, arr!, jmp!, adc!, ror!, rra!,
  bvs!, adc!, kil!, rra!, nop!, adc!, ror!, rra!,
  sei!, adc!, nop!, rra!, nop!, adc!, ror!, rra!,
  nop!, sta!, nop!, sax!, sty!, sta!, stx!, sax!,
  dey!, nop!, txa!, xaa!, sty!, sta!, stx!, sax!,
  bcc!, sta!, kil!, ahx!, sty!, sta!, stx!, sax!,
  tya!, sta!, txs!, tas!, shy!, sta!, shx!, ahx!,
  ldy!, lda!, ldx!, lax!, ldy!, lda!, ldx!, lax!,
  tay!, lda!, tax!, lax!, ldy!, lda!, ldx!, lax!,
  bcs!, lda!, kil!, lax!, ldy!, lda!, ldx!, lax!,
  clv!, lda!, tsx!, las!, ldy!, lda!, ldx!, lax!,
  cpy!, cmp!, nop!, dcp!, cpy!, cmp!, dec!, dcp!,
  iny!, cmp!, dex!, axs!, cpy!, cmp!, dec!, dcp!,
  bne!, cmp!, kil!, dcp!, nop!, cmp!, dec!, dcp!,
  cld!, cmp!, nop!, dcp!, nop!, cmp!, dec!, dcp!,
  cpx!, sbc!, nop!, isc!, cpx!, sbc!, inc!, isc!,
  inx!, sbc!, nop!, sbc!, cpx!, sbc!, inc!, isc!,
  beq!, sbc!, kil!, isc!, nop!, sbc!, inc!, isc!,
  sed!, sbc!, nop!, isc!, nop!, sbc!, inc!, isc!
]

# InstructionModes indicates the addressing mode for each instruction
const InstructionModes = [
  AddressingModes(6), AddressingModes(7), AddressingModes(6), AddressingModes(7),
  AddressingModes(11), AddressingModes(11), AddressingModes(11), AddressingModes(11),
  AddressingModes(6), AddressingModes(5), AddressingModes(4), AddressingModes(5),
  AddressingModes(1), AddressingModes(1), AddressingModes(1), AddressingModes(1),
  AddressingModes(10), AddressingModes(9), AddressingModes(6), AddressingModes(9),
  AddressingModes(12), AddressingModes(12), AddressingModes(12), AddressingModes(12),
  AddressingModes(6), AddressingModes(3), AddressingModes(6), AddressingModes(3),
  AddressingModes(2), AddressingModes(2), AddressingModes(2), AddressingModes(2),
  AddressingModes(1), AddressingModes(7), AddressingModes(6), AddressingModes(7),
  AddressingModes(11), AddressingModes(11), AddressingModes(11), AddressingModes(11),
  AddressingModes(6), AddressingModes(5), AddressingModes(4), AddressingModes(5),
  AddressingModes(1), AddressingModes(1), AddressingModes(1), AddressingModes(1),
  AddressingModes(10), AddressingModes(9), AddressingModes(6), AddressingModes(9),
  AddressingModes(12), AddressingModes(12), AddressingModes(12), AddressingModes(12),
  AddressingModes(6), AddressingModes(3), AddressingModes(6), AddressingModes(3),
  AddressingModes(2), AddressingModes(2), AddressingModes(2), AddressingModes(2),
  AddressingModes(6), AddressingModes(7), AddressingModes(6), AddressingModes(7),
  AddressingModes(11), AddressingModes(11), AddressingModes(11), AddressingModes(11),
  AddressingModes(6), AddressingModes(5), AddressingModes(4), AddressingModes(5),
  AddressingModes(1), AddressingModes(1), AddressingModes(1), AddressingModes(1),
  AddressingModes(10), AddressingModes(9), AddressingModes(6), AddressingModes(9),
  AddressingModes(12), AddressingModes(12), AddressingModes(12), AddressingModes(12),
  AddressingModes(6), AddressingModes(3), AddressingModes(6), AddressingModes(3),
  AddressingModes(2), AddressingModes(2), AddressingModes(2), AddressingModes(2),
  AddressingModes(6), AddressingModes(7), AddressingModes(6), AddressingModes(7),
  AddressingModes(11), AddressingModes(11), AddressingModes(11), AddressingModes(11),
  AddressingModes(6), AddressingModes(5), AddressingModes(4), AddressingModes(5),
  AddressingModes(8), AddressingModes(1), AddressingModes(1), AddressingModes(1),
  AddressingModes(10), AddressingModes(9), AddressingModes(6), AddressingModes(9),
  AddressingModes(12), AddressingModes(12), AddressingModes(12), AddressingModes(12),
  AddressingModes(6), AddressingModes(3), AddressingModes(6), AddressingModes(3),
  AddressingModes(2), AddressingModes(2), AddressingModes(2), AddressingModes(2),
  AddressingModes(5), AddressingModes(7), AddressingModes(5), AddressingModes(7),
  AddressingModes(11), AddressingModes(11), AddressingModes(11), AddressingModes(11),
  AddressingModes(6), AddressingModes(5), AddressingModes(6), AddressingModes(5),
  AddressingModes(1), AddressingModes(1), AddressingModes(1), AddressingModes(1),
  AddressingModes(10), AddressingModes(9), AddressingModes(6), AddressingModes(9),
  AddressingModes(12), AddressingModes(12), AddressingModes(13), AddressingModes(13),
  AddressingModes(6), AddressingModes(3), AddressingModes(6), AddressingModes(3),
  AddressingModes(2), AddressingModes(2), AddressingModes(3), AddressingModes(3),
  AddressingModes(5), AddressingModes(7), AddressingModes(5), AddressingModes(7),
  AddressingModes(11), AddressingModes(11), AddressingModes(11), AddressingModes(11),
  AddressingModes(6), AddressingModes(5), AddressingModes(6), AddressingModes(5),
  AddressingModes(1), AddressingModes(1), AddressingModes(1), AddressingModes(1),
  AddressingModes(10), AddressingModes(9), AddressingModes(6), AddressingModes(9),
  AddressingModes(12), AddressingModes(12), AddressingModes(13), AddressingModes(13),
  AddressingModes(6), AddressingModes(3), AddressingModes(6), AddressingModes(3),
  AddressingModes(2), AddressingModes(2), AddressingModes(3), AddressingModes(3),
  AddressingModes(5), AddressingModes(7), AddressingModes(5), AddressingModes(7),
  AddressingModes(11), AddressingModes(11), AddressingModes(11), AddressingModes(11),
  AddressingModes(6), AddressingModes(5), AddressingModes(6), AddressingModes(5),
  AddressingModes(1), AddressingModes(1), AddressingModes(1), AddressingModes(1),
  AddressingModes(10), AddressingModes(9), AddressingModes(6), AddressingModes(9),
  AddressingModes(12), AddressingModes(12), AddressingModes(12), AddressingModes(12),
  AddressingModes(6), AddressingModes(3), AddressingModes(6), AddressingModes(3),
  AddressingModes(2), AddressingModes(2), AddressingModes(2), AddressingModes(2),
  AddressingModes(5), AddressingModes(7), AddressingModes(5), AddressingModes(7),
  AddressingModes(11), AddressingModes(11), AddressingModes(11), AddressingModes(11),
  AddressingModes(6), AddressingModes(5), AddressingModes(6), AddressingModes(5),
  AddressingModes(1), AddressingModes(1), AddressingModes(1), AddressingModes(1),
  AddressingModes(10), AddressingModes(9), AddressingModes(6), AddressingModes(9),
  AddressingModes(12), AddressingModes(12), AddressingModes(12), AddressingModes(12),
  AddressingModes(6), AddressingModes(3), AddressingModes(6), AddressingModes(3),
  AddressingModes(2), AddressingModes(2), AddressingModes(2), AddressingModes(2)
]

# InstructionSizes indicates the size of each instruction in bytes
const InstructionSizes = [
  0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x01, 0x00, 0x03, 0x03, 0x03, 0x00,
  0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x03, 0x01, 0x00, 0x03, 0x03, 0x03, 0x00,
  0x03, 0x02, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x01, 0x00, 0x03, 0x03, 0x03, 0x00,
  0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x03, 0x01, 0x00, 0x03, 0x03, 0x03, 0x00,
  0x01, 0x02, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x01, 0x00, 0x03, 0x03, 0x03, 0x00,
  0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x03, 0x01, 0x00, 0x03, 0x03, 0x03, 0x00,
  0x01, 0x02, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x01, 0x00, 0x03, 0x03, 0x03, 0x00,
  0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x03, 0x01, 0x00, 0x03, 0x03, 0x03, 0x00,
  0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03, 0x03, 0x03, 0x00,
  0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00,
  0x02, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x01, 0x00, 0x03, 0x03, 0x03, 0x00,
  0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x03, 0x01, 0x00, 0x03, 0x03, 0x03, 0x00,
  0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x01, 0x00, 0x03, 0x03, 0x03, 0x00,
  0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x03, 0x01, 0x00, 0x03, 0x03, 0x03, 0x00,
  0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x01, 0x00, 0x03, 0x03, 0x03, 0x00,
  0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x03, 0x01, 0x00, 0x03, 0x03, 0x03, 0x00
 ]

# InstructionCycles indicates the number of cycles used by each instruction,
# not including conditional cycles
const InstructionCycles = [
  0x07, 0x06, 0x02, 0x08, 0x03, 0x03, 0x05, 0x05, 0x03, 0x02, 0x02, 0x02, 0x04, 0x04, 0x06, 0x06,
  0x02, 0x05, 0x02, 0x08, 0x04, 0x04, 0x06, 0x06, 0x02, 0x04, 0x02, 0x07, 0x04, 0x04, 0x07, 0x07,
  0x06, 0x06, 0x02, 0x08, 0x03, 0x03, 0x05, 0x05, 0x04, 0x02, 0x02, 0x02, 0x04, 0x04, 0x06, 0x06,
  0x02, 0x05, 0x02, 0x08, 0x04, 0x04, 0x06, 0x06, 0x02, 0x04, 0x02, 0x07, 0x04, 0x04, 0x07, 0x07,
  0x06, 0x06, 0x02, 0x08, 0x03, 0x03, 0x05, 0x05, 0x03, 0x02, 0x02, 0x02, 0x03, 0x04, 0x06, 0x06,
  0x02, 0x05, 0x02, 0x08, 0x04, 0x04, 0x06, 0x06, 0x02, 0x04, 0x02, 0x07, 0x04, 0x04, 0x07, 0x07,
  0x06, 0x06, 0x02, 0x08, 0x03, 0x03, 0x05, 0x05, 0x04, 0x02, 0x02, 0x02, 0x05, 0x04, 0x06, 0x06,
  0x02, 0x05, 0x02, 0x08, 0x04, 0x04, 0x06, 0x06, 0x02, 0x04, 0x02, 0x07, 0x04, 0x04, 0x07, 0x07,
  0x02, 0x06, 0x02, 0x06, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x04,
  0x02, 0x06, 0x02, 0x06, 0x04, 0x04, 0x04, 0x04, 0x02, 0x05, 0x02, 0x05, 0x05, 0x05, 0x05, 0x05,
  0x02, 0x06, 0x02, 0x06, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x04,
  0x02, 0x05, 0x02, 0x05, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, 0x02, 0x04, 0x04, 0x04, 0x04, 0x04,
  0x02, 0x06, 0x02, 0x08, 0x03, 0x03, 0x05, 0x05, 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x06, 0x06,
  0x02, 0x05, 0x02, 0x08, 0x04, 0x04, 0x06, 0x06, 0x02, 0x04, 0x02, 0x07, 0x04, 0x04, 0x07, 0x07,
  0x02, 0x06, 0x02, 0x08, 0x03, 0x03, 0x05, 0x05, 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x06, 0x06,
  0x02, 0x05, 0x02, 0x08, 0x04, 0x04, 0x06, 0x06, 0x02, 0x04, 0x02, 0x07, 0x04, 0x04, 0x07, 0x07
]

# InstructionPageCycles indicates the number of cycles used by each
# instruction when a page is crossed
const InstructionPageCycles = [
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00
]

# InstructionNames indicates the name of each instruction
const InstructionNames = [
  "BRK", "ORA", "KIL", "SLO", "NOP", "ORA", "ASL", "SLO",
  "PHP", "ORA", "ASL", "ANC", "NOP", "ORA", "ASL", "SLO",
  "BPL", "ORA", "KIL", "SLO", "NOP", "ORA", "ASL", "SLO",
  "CLC", "ORA", "NOP", "SLO", "NOP", "ORA", "ASL", "SLO",
  "JSR", "AND", "KIL", "RLA", "BIT", "AND", "ROL", "RLA",
  "PLP", "AND", "ROL", "ANC", "BIT", "AND", "ROL", "RLA",
  "BMI", "AND", "KIL", "RLA", "NOP", "AND", "ROL", "RLA",
  "SEC", "AND", "NOP", "RLA", "NOP", "AND", "ROL", "RLA",
  "RTI", "EOR", "KIL", "SRE", "NOP", "EOR", "LSR", "SRE",
  "PHA", "EOR", "LSR", "ALR", "JMP", "EOR", "LSR", "SRE",
  "BVC", "EOR", "KIL", "SRE", "NOP", "EOR", "LSR", "SRE",
  "CLI", "EOR", "NOP", "SRE", "NOP", "EOR", "LSR", "SRE",
  "RTS", "ADC", "KIL", "RRA", "NOP", "ADC", "ROR", "RRA",
  "PLA", "ADC", "ROR", "ARR", "JMP", "ADC", "ROR", "RRA",
  "BVS", "ADC", "KIL", "RRA", "NOP", "ADC", "ROR", "RRA",
  "SEI", "ADC", "NOP", "RRA", "NOP", "ADC", "ROR", "RRA",
  "NOP", "STA", "NOP", "SAX", "STY", "STA", "STX", "SAX",
  "DEY", "NOP", "TXA", "XAA", "STY", "STA", "STX", "SAX",
  "BCC", "STA", "KIL", "AHX", "STY", "STA", "STX", "SAX",
  "TYA", "STA", "TXS", "TAS", "SHY", "STA", "SHX", "AHX",
  "LDY", "LDA", "LDX", "LAX", "LDY", "LDA", "LDX", "LAX",
  "TAY", "LDA", "TAX", "LAX", "LDY", "LDA", "LDX", "LAX",
  "BCS", "LDA", "KIL", "LAX", "LDY", "LDA", "LDX", "LAX",
  "CLV", "LDA", "TSX", "LAS", "LDY", "LDA", "LDX", "LAX",
  "CPY", "CMP", "NOP", "DCP", "CPY", "CMP", "DEC", "DCP",
  "INY", "CMP", "DEX", "AXS", "CPY", "CMP", "DEC", "DCP",
  "BNE", "CMP", "KIL", "DCP", "NOP", "CMP", "DEC", "DCP",
  "CLD", "CMP", "NOP", "DCP", "NOP", "CMP", "DEC", "DCP",
  "CPX", "SBC", "NOP", "ISC", "CPX", "SBC", "INC", "ISC",
  "INX", "SBC", "NOP", "SBC", "CPX", "SBC", "INC", "ISC",
  "BEQ", "SBC", "KIL", "ISC", "NOP", "SBC", "INC", "ISC",
  "SED", "SBC", "NOP", "ISC", "NOP", "SBC", "INC", "ISC"
]


text:
using Downloads: download
using OrdinaryDiffEq
using Trixi

###############################################################################
# semidiscretization of the compressible Euler equations

equations = CompressibleEulerEquations2D(1.4)

initial_condition = initial_condition_convergence_test

source_terms = source_terms_convergence_test

# BCs must be passed as Dict
boundary_condition = BoundaryConditionDirichlet(initial_condition)
boundary_conditions = Dict(
  :x_neg => boundary_condition,
  :x_pos => boundary_condition,
  :y_neg => boundary_condition,
  :y_pos => boundary_condition
)

solver = DGSEM(polydeg=3, surface_flux=flux_lax_friedrichs)

###############################################################################
# Get the uncurved mesh from a file (downloads the file if not available locally)

coordinates_min = (0.0, 0.0)
coordinates_max = (2.0, 2.0)

trees_per_dimension = (4, 4)
mesh = P4estMesh(trees_per_dimension,
                 polydeg=1, initial_refinement_level=2,
                 coordinates_min=coordinates_min, coordinates_max=coordinates_max,
                 periodicity=false)

semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver,
                                    source_terms=source_terms,
                                    boundary_conditions=boundary_conditions)

###############################################################################
# ODE solvers, callbacks etc.

tspan = (0.0, 2.0)
ode = semidiscretize(semi, tspan)

summary_callback = SummaryCallback()

analysis_interval = 100
analysis_callback = AnalysisCallback(semi, interval=analysis_interval)

alive_callback = AliveCallback(analysis_interval=analysis_interval)

save_restart = SaveRestartCallback(interval=100,
                                   save_final_restart=true)

save_solution = SaveSolutionCallback(interval=100,
                                     save_initial_solution=true,
                                     save_final_solution=true,
                                     solution_variables=cons2prim)

stepsize_callback = StepsizeCallback(cfl=1.0)

callbacks = CallbackSet(summary_callback,
                        analysis_callback, alive_callback,
                        save_restart, save_solution,
                        stepsize_callback)
###############################################################################
# run the simulation

sol = solve(ode, CarpenterKennedy2N54(williamson_condition=false),
            dt=1.0, # solve needs some value here but it will be overwritten by the stepsize_callback
            save_everystep=false, callback=callbacks);
summary_callback() # print the timer summary


text:
@show @__DIR__
##
@show @__FILE__


text:
module MaxHelpingHandCustomizableRefill

using ..Ahorn, Maple

@mapdef Entity "MaxHelpingHand/CustomizableRefill" CustomizableRefill(x::Integer, y::Integer, twoDash::Bool=false, oneUse::Bool=false, respawnTime::Number=2.5, sprite::String="",
    shatterParticleColor1::String="", shatterParticleColor2::String="", glowParticleColor1::String="", glowParticleColor2::String="", wave::Bool=true)

const placements = Ahorn.PlacementDict(
    "Refill (Customizable) (max480's Helping Hand)" => Ahorn.EntityPlacement(
        CustomizableRefill
    ),

    "Refill (Two Dashes, Customizable) (max480's Helping Hand)" => Ahorn.EntityPlacement(
        CustomizableRefill,
        "point",
        Dict{String, Any}(
            "twoDash" => true
        )
    )
)

spriteOneDash = "objects/refill/idle00"
spriteTwoDash = "objects/refillTwo/idle00"

function getSprite(entity::CustomizableRefill)
    twoDash = get(entity.data, "twoDash", false)
    sprite = get(entity.data, "sprite", "")

    return sprite != "" ? "objects/MaxHelpingHand/refill/" * sprite * "/idle00" : (twoDash ? spriteTwoDash : spriteOneDash)
end

function Ahorn.selection(entity::CustomizableRefill)
    x, y = Ahorn.position(entity)
    sprite = getSprite(entity)

    return Ahorn.getSpriteRectangle(sprite, x, y)
end

function Ahorn.render(ctx::Ahorn.Cairo.CairoContext, entity::CustomizableRefill, room::Maple.Room)
    sprite = getSprite(entity)
    Ahorn.drawSprite(ctx, sprite, 0, 0)
end

end

max_stars_repo_name: Kitty-Cats/MaxHelpingHand

max_issues_repo_name: Kitty-Cats/MaxHelpingHand

max_forks_repo_name: Kitty-Cats/MaxHelpingHand


text:
# This file was generated, do not modify it. # hide
describe(boston, :mean, :std, :eltype)


text:
# tabular utils

struct ColumnDict <: AbstractColumns
    names::Vector{Symbol}
    columns::Vector{AbstractVector}
end

Tables.columnnames(c::ColumnDict) = getfield(c, 1)
Tables.getcolumn(c::ColumnDict, i::Int) = getfield(c, 2)[i]
function Tables.getcolumn(c::ColumnDict, s::Symbol)
    i = findfirst(==(s), columnnames(c))
    (i === nothing) && throw(ArgumentError("column name :$s not found in the data"))
    getcolumn(c, i)
end

function ColumnDict(t)
    t_cols = columns(t)
    names = collect(columnnames(t_cols))
    cols = map(name -> getcolumn(t_cols, name), names)
    return ColumnDict(names, cols)
end

# integer naming utils

function namedtuple(args::Vararg{Any, N}; kwargs...) where N
    syms = ntuple(Symbol, N)
    return merge(NamedTuple{syms}(args), values(kwargs))
end

function remove_intkeys(nt::NamedTuple, t::NTuple{N, Any}) where N
    Base.structdiff(nt, NamedTuple{ntuple(Symbol, N)}(t))
end
remove_intkeys(nt) = remove_intkeys(nt, Tuple(nt))
reorder(nt::NamedTuple) = Tuple(nt[Symbol(i)] for i in keys(keys(nt)))

function split(ps::NamedTuple)
    nt = remove_intkeys(ps)
    t = Base.structdiff(ps, nt)
    return reorder(t), nt
end
positional(ps::NamedTuple) = first(split(ps))
keyword(ps::NamedTuple) = last(split(ps))

# naming utils

get_name(v::NamedDimsArray) = dimnames(v)[1]
strip_name(v::NamedDimsArray) = unname(v)
get_name(v) = Symbol("")
strip_name(v) = v

function extract_names(d::Union{NamedTuple, Tuple})
    ns = map(get_name, d)
    vs = map(strip_name, d)
    return ns, vs
end

function fast_sortable(v)
    v1 = strip_name(v)
    return iscategorical(v1) ? refs(categorical(v1)) : v1
end

fast_sortable(v::StructArray) = StructArray(map(fast_sortable, fieldarrays(v)))


text:
# # Searching boundary entities

# In this tutorial, we will learn
#
#    -  How to access an attribute of an incidence relation.
#    -  How to find the bounding box of the mesh.

# The tutorial will produce files for mesh visualization in the
# [Paraview](https://www.paraview.org/) format (VTK). One can display this
# information by loading the file with `paraview.exe`. When the tutorial is
# executed in `mybinder.org`, the graphics file needs to be downloaded to your
# desktop, and then visualized locally.

# We load the truncated cylindrical shell mesh from a file:
using StaticArrays
using MeshSteward: import_NASTRAN

connectivities = import_NASTRAN("trunc_cyl_shell_0.nas")
# There should be only a single incidence relation here:
@show length(connectivities) == 1

# The incidence relation is now extracted from the array:
connectivity = connectivities[1]

# We can check that the mesh was loaded correctly (of course in this case we
# know how many vertices and how many elements there should be).
using MeshCore: nshapes
@show (nshapes(connectivity.right), nshapes(connectivity.left)) == (376, 996)

# The vertices are the shape collection on the right of the incidence relation.
vertices = connectivity.right

# We now write out a postprocessing file with the elements. Note that we pass
# the `connectivity` incidence relation to get the elements stored in the
# file.
using MeshSteward: vtkwrite
vtkwrite("trunc_cyl_shell_0-search", connectivity)

# Compute the boundary incidence relation: the facets bounding the domain.
using MeshCore: ir_boundary
bir = ir_boundary(connectivity)

# Select the boundary faces whose normals point in the direction `[0.0, 0.0,
# 1.0]`, in the sense that the dot product between the normal in this
# direction  >= 0.99.
using MeshSteward: eselect
el = eselect(bir; facing = true, direction = x -> [0.0, 0.0, 1.0], dotmin = 0.99)

# We know how many triangles compose this part of the boundary: check the length
# of the list of the triangles.
@show length(el) == 44

# Now export the triangles as a VTK file. This can now be displayed side-by-side
# with the original mesh in `"trunc_cyl_shell_0-search.vtk"`. The subset
# defined by the list `el` from the boundary incidence relation is extracted
# and passed to `vtkwrite`.
using MeshCore: ir_subset
vtkwrite("trunc_cyl_shell_0-search-z=top", ir_subset(bir, el))

# Similar procedure can be applied to select the triangular faces on the
# cylindrical surface inside the shell. The direction is now defined by taking
# the location of the point where the normal is calculated, connecting it with
# the axis of revolution.
el = eselect(bir; facing = true, direction = x -> [-x[1], -x[2], 0.0], dotmin = 0.99)

# Again, we know how many triangles compose this part of the boundary: check the
# length of the list of the triangles.
@show length(el) == 304

# Now export the triangles as a VTK file. This can now be displayed side-by-side
# with the original mesh in `"trunc_cyl_shell_0-search.vtk"`.
vtkwrite("trunc_cyl_shell_0-search-interior", ir_subset(bir, el))


text:
module SEARCH_TESTS

using Reproduce, Test, FileIO

const TEST_DIR = "TEST_DIR"

function arg_parse(args; use_git_info=false, as_symbols=false)

    s = ArgParseSettings()
    @add_arg_table! s begin
        "--a"
        help = "a file to save the results to"
        arg_type = Int64
        required = true
    end

    @add_arg_table! s begin
        "--b"
        help = "a file to save the results to"
        arg_type = Int64
        required = true
    end
    parsed = create_info(args, s, joinpath(TEST_DIR, "data");
                         use_git_info=use_git_info,
                         as_symbols=as_symbols)
    return parsed
end

function setup_tests()
    used_keys = ["a", "b"]
    parsed_dicts = Dict{UInt64, Dict}()
    for i in 1:5
        for j in 1:5
            args=["--a", "$(i)", "--b", "$(j)"]
            parsed = arg_parse(args)
            parsed_dicts[parsed["_HASH"]] = filter(k->(k[1] in used_keys), parsed)
        end
    end
end

function reset_tests()
    working_dir = pwd()
    rm(joinpath(working_dir, TEST_DIR); recursive=true)
end

function item_collection_test()

    ic = ItemCollection(TEST_DIR)
    tests = fill(false, 5, 5)
    for item in ic.items
        tests[item.parsed_args["a"], item.parsed_args["b"]] = true
    end

    return all(tests)
end

function search_test()
    search_dict = Dict("a"=>1)
    ic = search(ItemCollection(TEST_DIR), search_dict)
    tests = fill(false, 1, 5)
    for item in ic
        tests[1, item.parsed_args["b"]] = true
    end
    return all(tests)
end

function diff_test()
    ic = ItemCollection(TEST_DIR)
    diff_dict = diff(ic)
    return diff_dict["a"] == [1,2,3,4,5] && diff_dict["b"] == [1,2,3,4,5]
end

macro testsearch()
    @testset "Search Tests" begin
        setup_tests()
        @test item_collection_test() == true
        @test search_test() == true
        @test diff_test() == true
        reset_tests()
    end
end

end


text:
#using Gadfly
using DataFrames
using Statistics
import Cairo, Fontconfig
using StatsBase
using LinearAlgebra
using Plots
import GR
using Plots.PlotMeasures
#using Gadfly

#Function to convert dictionary to dataframe
function DictToDf(InputDict)
    return DataFrame(; [Symbol(k)=>v for (k,v) in InputDict]...)
end

#Find mean number of isoforms per gene per cell in real data
function MeanIsoPerGenePerCell(singleGeneCounts::DataFrame)

    arr = []

    for i in 3:ncol(singleGeneCounts)
        isoPerGenePerCell = sum(x->x>0, singleGeneCounts[:, i])
        push!(arr, isoPerGenePerCell)
    end

    return mean(arr)
end

#Histogram plot with real mean value marked on it for a single gene
function OneGeneHistPlot(InputDict, singleGeneCounts, output)

    #Prep df for histogram part of plot
    df = DictToDf(InputDict)
    df = stack(df, 1:ncol(df))

    #Find mean for line on plot
    mean_val = MeanIsoPerGenePerCell(singleGeneCounts)

    test = Gadfly.plot(df, x = "value", color = "variable", xintercept = [mean_val],
    Geom.histogram(position=:dodge), Geom.vline(color = "black"),
    Guide.xlabel("Mean isoforms per gene per cell", orientation=:horizontal),
    Guide.ylabel("Frequency", orientation=:vertical),
     Guide.colorkey(title = "Number of Isoforms"),
    Theme(major_label_font_size=14Gadfly.pt,minor_label_font_size=14Gadfly.pt,
    key_label_font_size=11Gadfly.pt, key_title_font_size=11Gadfly.pt))

    img = PNG(output)
    draw(img, test)

end

#Function that finds the means number of isoforms per gene
#This has to be re-written due to a bullshit memory bug
#Function that finds the means number of isoforms per gene
function MeanNumIsoformsPerGenePerCellReal(countsDict)

    meansArr = Float64[]
    meansDict = Dict()

    for (key, value) in countsDict

        tmp_df = DictToDf(value)
        cellArr =[]

        for row in eachrow(tmp_df)
            cellMean = sum(row .> 0)
            push!(cellArr, cellMean)
        end

        push!(meansArr, mean(cellArr))
        meansDict[key] = mean(cellArr)

    end

    return [meansArr, meansDict]
end

function makeNormalisedHistogram(Arr, titleArg)

    #Do some magic to make the histogram as x and y coordinates
    hist = fit(Histogram, Arr, nbins=100, closed=:right);
    hist = normalize(hist, mode=:pdf)

    if titleArg == "3 Isoforms"
        #Untransformed plot
        p1 = histogram(Arr,
        title = titleArg,
        xlims = (0, 4),
        ylims = (0, 15),
        ylabel = "Normalised Frequency",
        normalize=:pdf,
        bins = 100,
        axis = (font(18)), titlefontsize=18, yticks = 0:5:15, left_margin=1.0mm)

    else
        #Untransformed plot
        p1 = histogram(Arr,
        title = titleArg,
        xlims = (0, 4),
        ylims = (0, 15),
        normalize=:pdf,
        bins = 100,
        axis = (font(18)), titlefontsize=18, yticks = 0:5:15, left_margin=1.0mm)
    end

    #Log transformed plot
    p2 = plot(hist.edges[1][2:end],
    log10.(hist.weights.+1),
    title = titleArg,
    xlims = (0, 4),
    ylims = (0, 2),
    ylabel = "Log Normalised Frequency")

    return (p1, p2)
end

function makeNormalisedHistogramReal(Arr, titleArg)

    #Do some magic to make the histogram as x and y coordinates
    hist = fit(Histogram, Arr, nbins=100, closed=:right);
    hist = normalize(hist, mode=:pdf)

    println("Making real histogram")

    p1 = histogram(Arr,
    title = titleArg,
    xlims = (0, 4),
    xlabel = "Mean Isoforms per Gene per Cell",
    ylims = (0, 15),
    normalize=:pdf,
    bins = 100,
    axis = (font(18)), titlefontsize=18, yticks = 0:5:15, left_margin=1.0mm,
    bottom_margin = 1.0mm)

    #Log transformed plot
    p2 = plot(hist.edges[1][2:end],
    log10.(hist.weights.+1),
    title = titleArg,
    xlims = (0, 4),
    xlabel = "Mean Isoforms per Gene per Cell",
    ylims = (0, 2),
    ylabel = "Log Normalised Frequency",
    normalize=:pdf)

    return (p1, p2)
end

function makeHistogramforNIsoforms(df, condition, titleArg)

    #Extract data from dataframe and make plot
    get_data = df[df.type .== condition, :]
    p1 = makeNormalisedHistogram(get_data.means, titleArg)
    return p1
end

function GlobalGeneDensityPlot(globalMeans, realArr, output)

    prinln("Making plots")

    #Make plots
    pReal = makeNormalisedHistogramReal(realArr, "Real")
    p1 = makeHistogramforNIsoforms(globalMeans, 1, "One Isoform")
    p2 = makeHistogramforNIsoforms(globalMeans, 2, "Two Isoforms")
    p3 = makeHistogramforNIsoforms(globalMeans, 3, "Three Isoforms")
    p4 = makeHistogramforNIsoforms(globalMeans, 4, "Four Isoforms")

    #Make panel of normalised histograms
    graph = plot(p1[1],p2[1],p3[1],p4[1],pReal[1], layout=(5,1),legend=false, size = (300, 600) )
    savefig(graph, output)

    #Make panel of normalised log histograms
    log_graph = plot(p1[2],p2[2],p3[2],p4[2],pReal[2],layout=(5,1),legend=false, size = (300, 600))
    log_out = "log_" * output
    savefig(log_graph, log_out)

end

function pDropoutDistribution(Arr, output)

    #Default dropout distribution
    p1 = Plots.histogram(Arr, title = "Dropout Distribution", axis = (font(70)),
    titlefontsize=70, margin = 10.0mm, bins = collect(0:0.05:1),
    ylims = (0, 1000))

    #Beta distribution
    params = fit(Beta, Arr)
    @show params

    #plot Beta distribution
    p2 = Plots.plot(collect(0:0.01:1), pdf(Beta(params.α, params.β), 0:0.01:1),
    title = "Beta Distribution", axis = (font(70)), titlefontsize=70,
    margin = 10.0mm, linestyle=:solid, linealpha=0.5, linewidth=2*8,
    xlabel = "p(Dropout)", ylims = (0,3))

    #merge plots
    p_all = plot(p1,p2, layout = (2,1))

    #Save
    savefig(p_all, output)
    return (p1, p2)
end

function meanDistribution(Arr)
    p1 = histogram(Arr, title = "Mean Expression Distribution")
    savefig(p1, "expression_distribution.png" )
end

max_stars_repo_name: jenni-westoby/Obstacles

max_issues_repo_name: jenni-westoby/Obstacles

max_forks_repo_name: jenni-westoby/Obstacles


text:
module Redux

include("action.jl")
export AbstractAction, AbstractSyncAction, AbstractAsyncAction
using .ActionTypes

include("store.jl")
export AbstractStore, Store
export create_store, get_state, subscribe!, dispatch!

include("middleware.jl")
export MiddlewareStore, identity_middleware

include("state.jl")
export AbstractState, AbstractMutableState, AbstractImmutableState

end # module


text:
function solve()
    h, w = [parse(Int, x) for x in split(readline())]
    a = zeros(Int, h, w)
    for i=1:h
        a[i, :] = [parse(Int, x) for x in split(readline())]
    end
    m = minimum(a)
    sum(a.-m)
end

println(solve())

max_stars_repo_name: aishikawa/atcoder-julia

max_issues_repo_name: aishikawa/atcoder-julia

max_forks_repo_name: aishikawa/atcoder-julia


text:
function solve_diagTR(λ, Δ, g̃, δ, ϵ; M = [0.0])
    # λ underestimates the required value λstar such that ||d̃(λstar)|| = δ
    # where d̃(λ) =  -(Δ + λ * M) .\ g̃
    T = eltype(δ)
    M = T.(M)

    if M == [0.0]
        # M = ones(Δ) ;
        M = fill(T.(1.0), size(Δ)[1]);
    end
    @assert (minimum(M) > 0.0)
    λin = T.(λ)
    d̃ = -(Δ .+ λ * M) .\ g̃
    d̃d̃ = d̃⋅d̃
    normd̃ = sqrt(d̃d̃)

    tol1 = sqrt(eps(T))
    tolerance = tol1 * T(100.0)

    # Newton iterations
    iter_nwt = 0
    while (normd̃ >= (δ + tolerance * normd̃)) && (iter_nwt < 40)
        dotd̃ = (Δ .+ λ * M) .\ (M .* d̃)
        Δλ = ((normd̃-δ)/δ) * (d̃d̃/(d̃ ⋅ dotd̃))
        λeps = tol1 / T(100.0)
        λ =  max(λ + Δλ, λin + λeps)
        d̃ = -(Δ .+ λ * M) .\ g̃
        d̃d̃ = d̃⋅d̃
        normd̃ = sqrt(d̃d̃)
        @assert (λ >= 0.0)
        iter_nwt += 1
    end

    return d̃, λ
end