text:
using Plots, Printf, DelimitedFiles, Random, Statistics, ProgressMeter
using MDToolbox

qs = readdlm("data/quaternion/QUATERNION_LIST_576_Orient")
models = readpdb("data/t1r/cluster.pdb");
for iatom = 1:models.natom
    models.atomname[iatom] = models.resname[iatom]
end
MDToolbox.decenter!(models)

probe_radius = 20.0
param = AfmizeConfig(10.0 * (pi / 180),
    probe_radius,
    MDToolbox.Point2D(-250, -200),
    MDToolbox.Point2D(250, 200),
    MDToolbox.Point2D(6.25, 6.25),
    MDToolbox.defaultParameters())

myseed = 777
sigma_noise = 3.0
nframe = 1000

seed = MersenneTwister(myseed)
afms = []
imodel_array = []
iq_array = []
dxdy_array = []
@showprogress 1 "Computing..." for i in 1:nframe
    imodel = rand(seed, 1:models.nframe)
    model = models[imodel, :]
    iq = rand(seed, 1:size(qs, 1))
    q = qs[iq, :]
    model = MDToolbox.rotate(model, q)
    dx = rand(seed)*150.0 - 50.0
    dy = rand(seed)*150.0 - 50.0
    model.x .+=  dx
    model.y .+=  dy
    afm = MDToolbox.afmize(model, param)
    h, w = size(afm)
    afm .+= randn(seed, h, w) * sigma_noise
    push!(afms, afm)
    push!(imodel_array, imodel)
    push!(iq_array, iq)
    push!(dxdy_array, (dx, dy))
end

anim = @animate for i = 1:length(afms)
    heatmap(afms[i])
end
gif(anim, "afm_generate_test_data.gif", fps = 10)

using BSON: @save, @load
@save "afm_generate_test_data.bson" models afms qs param imodel_array iq_array dxdy_array sigma_noise

max_stars_repo_name: matsunagalab/notebooks

max_issues_repo_name: matsunagalab/notebooks

max_forks_repo_name: matsunagalab/notebooks


text:
export todevice, todevice!

function todevice(x::Array{T}, dev::Int) where T
    if dev < 0
        x
    else
        CUDA.setdevice(dev)
        if T == Int
            CuArray(Array{Cint}(x))
        else
            CuArray(x)
        end
    end
end

function todevice(x::CuArray{T}, dev::Int) where T
    if dev < 0
        if T == Cint
            Array{Int}(Array(x))
        else
            Array(x)
        end
    elseif CUDA.getdevice() != dev
        throw("Not implemented yet.")
    end
end

function todevice(x::Var, dev::Int)
    data = todevice(x.data, dev)
    grad = todevice(x.grad, dev)
    x = Var(data)
    x.grad = grad
    x
end

function todevice!(x::Var, dev::Int)
    x.data = todevice(x.data, dev)
    isnothing(x.grad) || (x.grad = todevice(x.grad,dev))
    x
end

function todevice(g::Graph, dev::Int)
    nodes = map(g.nodes) do n
        args = map(n.args) do arg
            isa(arg,Var) ? todevice(arg,dev) : arg
        end
        Node(n.f, args, n.name)
    end
    Graph(nodes, g.inputids, g.outputids)
end

#=
export CPUDevice, GPUDevice

abstract type Device end

function Device(dev::Int)
    if str == "cpu"
        CPUDevice()
    elseif startswith(str, "gpu:")
        id = parse(Int, str[5:end])
        GPUDevice(id)
    else
        throw("Unknown device: $str.")
    end
end

struct CPUDevice <: Device
end

struct GPUDevice <: Device
    id::Int
end

(::CPUDevice)(x::Array) = x
(::CPUDevice)(x::CuArray) = Array(x)
(::CPUDevice)(x::CuArray{Cint}) = Array{Int}(Array(x))
(::GPUDevice)(x::CuArray) = x
(::GPUDevice)(x::Array{Int}) = CuArray(Array{Cint}(x))
(::GPUDevice)(x::Array) = CuArray(x)
=#

ext: jl


text:
using Pkg
Pkg.activate((@__DIR__)*"/..")

using Plasmo
using MPI
using PipsNLP

MPI.Init()

comm = MPI.COMM_WORLD
ncores = MPI.Comm_size(comm)
rank = MPI.Comm_rank(comm)

#8 scenarios
Ns = 8

#scenario per processor (SPP)
SPP = round(Int, floor(Ns/ncores))

function create_simple_model(d)
    node = OptiNode()
    @variable(node, 0<=p<=10, start=5)
    @variable(node, u)
    @variable(node, x)
    @constraint(node, x >= p)
    @constraint(node, p + u == d)
    return node
end

#Setup processor information
demand = rand(Ns)*10
graph = OptiGraph()

first_stage = @optinode(graph)
@variable(first_stage,0 <= x <= 8)
@objective(first_stage,Min,x)

owned = []
s = 1

#subgraph contains the scenarios
subgraph = OptiGraph()
add_subgraph!(graph,subgraph)
for j in 1:Ns
    global s
    if round(Int, floor((s-1)/SPP)) == rank
        push!(owned, s)
        node = create_simple_model(demand[j])
        add_node!(subgraph,node)

        #connect children and parent variables
        @linkconstraint(graph, first_stage[:x] == node[:x])

        #reconstruct second stage objective
        @objective(node,Min,1/Ns*(node[:p] + 3*node[:u]))
    else # create a ghost node (empty model)
        node = add_node!(subgraph)
    end
    s = s + 1
end

#create a link constraint between the subproblems (PIPS-NLP supports this kind of constraint)
@linkconstraint(graph, (1/Ns)*sum(getnode(subgraph,s)[:p] for s in owned) == 8)
PipsNLP.pipsnlp_solve(graph)

MPI.Finalize()


text:
function print_build_tarballs(io::IO, state::WizardState;
        with_travis_tags=false)
    urlhashes = zip(state.source_urls, state.source_hashes)
    sources_string = join(map(urlhashes) do x
        string(repr(x[1])," =>\n    ", repr(x[2]), ",\n")
    end,"\n    ")
    platforms_string = join(state.platforms,",\n    ")

    stuff = collect(zip(state.files, state.file_kinds, state.file_varnames))
    products_string = join(map(stuff) do x
        file, kind, varname = x
        # Normalize the filename, e.g. `"foo/libfoo.tar.gz"` would get mapped to `"libfoo"`
        file = normalize_name(file)
        if kind == :executable
            return "ExecutableProduct(prefix, $(repr(file)), $(repr(varname)))"
        elseif kind == :library
            return "LibraryProduct(prefix, $(repr(file)), $(repr(varname)))"
        else
            return "FileProduct(prefix, $(repr(file)), $(repr(varname)))"
        end
    end,",\n    ")

    dependencies_string = ""
    if !isempty(state.dependencies)
        dependencies_string *= join(map(state.dependencies) do dep
            if isa(dep, InlineBuildDependency)
                """
                BinaryBuilder.InlineBuildDependency(raw\"\"\"
                $(dep.script)
                \"\"\")
                """
            elseif isa(dep, RemoteBuildDependency)
                "\"$(dep.url)\""
            end
        end, ",\n    ")
    end

    println(io, """
    # Note that this script can accept some limited command-line arguments, run
    # `julia build_tarballs.jl --help` to see a usage message.
    using BinaryBuilder

    name = $(repr(state.name))
    version = $(repr(state.version))

    # Collection of sources required to build $(state.name)
    sources = [
        $(sources_string)
    ]

    # Bash recipe for building across all platforms
    script = raw\"\"\"
    $(state.history)
    \"\"\"

    # These are the platforms we will build for by default, unless further
    # platforms are passed in on the command line
    platforms = [
        $(platforms_string)
    ]

    # The products that we will ensure are always built
    products(prefix) = [
        $(products_string)
    ]

    # Dependencies that must be installed before this package can be built
    dependencies = [
        $(dependencies_string)
    ]

    # Build the tarballs, and possibly a `build.jl` as well.
    build_tarballs(ARGS, name, version, sources, script, platforms, products, dependencies)
    """)
end

function print_travis_file(io::IO, state::WizardState)
    println(io, """
    language: julia
    os:
      - linux
    julia:
      - 0.6
    notifications:
      email: false
    git:
      depth: 99999999
    cache:
      timeout: 1000
      directories:
        - downloads
    env:
      global:
        - BINARYBUILDER_DOWNLOADS_CACHE=downloads
        - BINARYBUILDER_AUTOMATIC_APPLE=false
    sudo: required

    # Before anything else, get the latest versions of things
    before_script:
      - julia -e 'Pkg.clone("https://github.com/JuliaPackaging/BinaryProvider.jl")'
      - julia -e 'Pkg.clone("https://github.com/JuliaPackaging/BinaryBuilder.jl"); Pkg.build()'

    script:
      - julia build_tarballs.jl
    """)
end

function print_travis_deploy(io, repo, secure_key)
    print(io,
    """
    deploy:
        provider: releases
        api_key:
            # Note; this api_key is only valid for $(GitHub.name(repo)); you need
            # to make your own: https://docs.travis-ci.com/user/deployment/releases/
            secure: $secure_key
        file_glob: true
        file: products/*
        skip_cleanup: true
        on:
            repo: $(GitHub.name(repo))
            tags: true
    """)
end

mutable struct termios
    c_iflag::Cint
    c_oflag::Cint
    c_cflag::Cint
    c_lflag::Cint
    c_line::UInt8
    c_cc::NTuple{19, UInt8}
    termios() = new()
end

const TCGETS = 0x5401
const TCSETS = 0x5402
const ECHO = 0o10

function set_terminal_echo(fd, enable::Bool)
    # Linux only
    t = termios()
    ccall(:ioctl, Cint, (Cint, Cint, Ref{termios}), fd, TCGETS, t)
    old = (t.c_lflag & ECHO) != 0
    if enable
        t.c_lflag |= ECHO
    else
        t.c_lflag &= ~ECHO
    end
    ccall(:ioctl, Cint, (Cint, Cint, Ref{termios}), fd, TCSETS, t)
    old
end

const travis_headers = Dict(
    "Accept" => "application/vnd.travis-ci.2+json",
    "Content-Type" => "application/json",
    "User-Agent" => "Travis-WHY-YOU-HAVE-BAD-DOCS (https://github.com/travis-ci/travis-ci/issues/5649)"
)

function authenticate_travis(github_token; travis_endpoint=DEFAULT_TRAVIS_ENDPOINT)
    resp = HTTP.post("$(travis_endpoint)auth/github",
        body=JSON.json(Dict(
            "github_token" => github_token
        )), headers = travis_headers)
    JSON.parse(HTTP.payload(resp, String))["access_token"]
end

function sync_and_wait_travis(outs, repo_name, travis_token; travis_endpoint=DEFAULT_TRAVIS_ENDPOINT)
    println(outs, "Asking travis to sync github and waiting until it knows about our new repo.")
    println(outs, "This may take a few seconds (or minutes, depending on Travis' mood)")
    headers = merge!(Dict("Authorization"=>"token $travis_token"),travis_headers)
    resp = HTTP.post("$(travis_endpoint)users/sync"; headers=headers, status_exception=false)
    if resp.status != 200 && resp.status != 409
        error("Failed to sync travis (got status $(resp.status))")
    end
    while true
        resp = HTTP.get("$(travis_endpoint)repos/$(repo_name)"; headers=headers, status_exception=false)
        if resp.status == 200
            println(outs, "Done waiting")
            # Let's sleep another 5 seconds - Sometimes there's still a race here
            sleep(5.0)
            return JSON.parse(HTTP.payload(resp, String))["repo"]["id"]
        end
        println(outs, "Still Waiting..."); sleep(5.0)
    end
end

function activate_travis_repo(repo_id, travis_token; travis_endpoint=DEFAULT_TRAVIS_ENDPOINT)
    headers = merge!(Dict("Authorization"=>"token $travis_token",
                          "Travis-API-Version"=>3))
    HTTP.post("$(travis_endpoint)repo/$(repo_id)/activate"; headers=headers)
end

function obtain_token(outs, ins, repo_name, user; github_api=Github.DEFAULT_API)
    println(outs)
    printstyled(outs, "Creating a github access token.\n", bold=true)
    println(outs, """
    We will use this token to create to repository, and then pass it to travis
    for future uploads of binary artifacts.
    You will be prompted for your GitHub credentials.
    """)
    params = Dict(
        "scopes" => ["public_repo",
        # These are required to authenticate against travis
        "read:org", "user:email", "repo_deployment",
        "repo:status","public_repo", "write:repo_hook"
        ],
        "note" => "GitHub releases deployment for $(user)/$(repo_name) - Generated by BinaryBuilder.jl",
        "note_url" => "https://github.com/JuliaPackaging/BinaryBuilder.jl",
        "fingerpint" => randstring(40)
    )
    while true
        print(outs, "Please enter the github.com password for $(user): ")
        terminal = Terminals.TTYTerminal("xterm", ins, outs, outs)
        old = set_terminal_echo(Base._fd(ins), false)
        pass = try
            readline(ins)
        finally
            set_terminal_echo(Base._fd(ins), old)
        end
        println(outs)
        headers = Dict{String, String}("User-Agent"=>"BinaryBuilder-jl")
        auth = GitHub.UsernamePassAuth(user, pass)
        resp = GitHub.gh_post(github_api, "/authorizations",
            headers=headers, params=params, handle_error=false,
            auth = auth)
        if resp.status == 401 && startswith(strip(HTTP.getkv(resp.headers, "X-GitHub-OTP", "")), "required")
            println(outs, "Two factor authentication in use.  Enter auth code.")
            print(outs, "> ")
            otp_code = readline(ins)
            resp = GitHub.gh_post(github_api, "/authorizations",
                headers=merge(headers, Dict("X-GitHub-OTP"=>otp_code)),
                params=params, handle_error=false,
                auth = auth)
        end
        if resp.status == 401
            printstyled(outs, "Invalid credentials!\n", color=:red)
            continue
        end
        if resp.status != 200
            GitHub.handle_response_error(resp)
        end
        return JSON.parse(HTTP.payload(resp, String))["token"]
    end
end

"""
    set_global_git_config(username, email)

Sets up a `~/.gitconfig` with the given `username` and `email`.
"""
function set_global_git_config(username, email)
    LibGit2.with(LibGit2.GitConfig(LibGit2.Consts.CONFIG_LEVEL_GLOBAL)) do cfg
        LibGit2.set!(cfg, "user.name", username)
        LibGit2.set!(cfg, "user.email", email)
    end
    return nothing
end

"""
    init_git_config(repo, state)

Ask the user for their username and password for a repository-local
`.git/config` file.  This is used during an interactive wizard session.
"""
function init_git_config(repo, state)
    msg = """
    Global `~/.gitconfig` information not found.
    In order to create a git repository, we need a
    "name" and "email address" to identify the git
    commits we are about to create.  To avoid this
    prompt in the future and to set your name and
    email address globally, run

        BinaryBuilder.set_global_git_config(username, email)

    """
    println(state.outs, msg)
    print(state.outs, "Enter your name: ")
    username = readline(state.ins)
    print(state.outs, "Enter your email address: ")
    email = readline(state.ins)

    LibGit2.with(LibGit2.GitConfig(repo)) do cfg
        LibGit2.set!(cfg, "user.name", username)
        LibGit2.set!(cfg, "user.email", email)
    end
end

function common_git_repo_setup(repo_dir, repo, state; git_cfg = LibGit2.GitConfig())
    local license_text
    while true
        print(state.outs, "Enter your desired license [MIT]: ")
        lic = readline(state.ins)
        isempty(lic) && (lic = "MIT")
        license_text = try
            PkgLicenses.readlicense(lic)
        catch e
            printstyled("License $lic is not available.\n", color=:red)
            println("Available licenses are:")
            foreach(PkgLicenses.LICENSES) do lic
                println("- $(lic[1])")
            end
            continue
        end
        break
    end

    # Helper function to get around LibGit2's strange `get()` behavior
    function lg2get(T, cfg, name)
        try
            return LibGit2.get(T, cfg, name)
        catch e
            if typeof(e) <: LibGit2.GitError
                return nothing
            end
            rethrow(e)
        end
    end

    # check to see if the user has already setup git config settings
    if (lg2get(String, git_cfg, "user.name") == nothing ||
        lg2get(String, git_cfg, "user.email") == nothing) &&
        (LibGit2.getconfig(repo, "user.name", nothing) == nothing ||
         LibGit2.getconfig(repo, "user.email", nothing) == nothing)
        # If they haven't, prompt them to make a global one, and then actually
        # make a repository-local config right now.
        init_git_config(repo, state)
    end

    LibGit2.commit(repo, "Initial empty commit")
    # Now create the build_tarballs file
    open(joinpath(repo_dir, "build_tarballs.jl"), "w") do f
        print_build_tarballs(f, state)
    end
    # Create the license file
    open(joinpath(repo_dir, "LICENSE.md"), "w") do f
        print(f, license_text)
    end
    # Create the gitignore file
    open(joinpath(repo_dir, ".gitignore"), "w") do f
        print(f, """
        products/
        downloads/
        build/
        """)
    end
end

function local_deploy(state::WizardState; git_cfg = LibGit2.GitConfig())
    repo_dir = tempname()
    LibGit2.with(LibGit2.init(repo_dir)) do repo
        common_git_repo_setup(repo_dir, repo, state; git_cfg = git_cfg)
        open(joinpath(repo_dir, ".travis.yml"), "w") do f
            # Create the first part of the .travis.yml file
            print_travis_file(f, state)
        end
        # Create README file
        open(joinpath(repo_dir, "README.md"), "w") do f
            print(f, """
            # $(state.name) builder

            This repository builds binary artifacts for the $(state.name) project.
            This repository has a default .travis.yml file that can be used to build
            binary artifacts on Travis CI. You will however need to setup the release
            upload manually. See https://docs.travis-ci.com/user/deployment/releases/.

            If you don't wish to use travis, you can use the build_tarballs.jl
            file manually and upload the resulting artifacts to a hosting provider
            of your choice.
            """)
        end
        LibGit2.add!(repo, "build_tarballs.jl", "LICENSE.md", "README.md",
                           ".travis.yml", ".gitignore")
        LibGit2.commit(repo, "Add autogenerated files to build $(state.name)")
    end

    println("Your repository is all set up in $(repo_dir)")
end

function obtain_secure_key(outs, token, gr; travis_endpoint=DEFAULT_TRAVIS_ENDPOINT)
    travis_token = authenticate_travis(token; travis_endpoint=travis_endpoint)
    repo_id = sync_and_wait_travis(outs, GitHub.name(gr), travis_token; travis_endpoint=travis_endpoint)
    activate_travis_repo(repo_id, travis_token; travis_endpoint=travis_endpoint)
    # Obtain the appropriate encryption key from travis
    key = JSON.parse(HTTP.payload(HTTP.get("$(travis_endpoint)repos/$(GitHub.name(gr))/key"), String))["key"]
    pk_ctx = MbedTLS.PKContext()
    # Some older repositories have keys starting with "BEGIN RSA PUBLIC KEY"
    # which would indicate that they are in PKCS#1 format. However, they are
    # instead in PKCS#8 format with incorrect header guards, so fix that up
    # and never think about it again.
    key = replace(key, "RSA PUBLIC KEY" => "PUBLIC KEY")
    MbedTLS.parse_public_key!(pk_ctx, key)
    # Encrypted the token
    entropy = MbedTLS.Entropy()
    rng = MbedTLS.CtrDrbg()
    MbedTLS.seed!(rng, entropy)
    outbuf = fill(UInt8(0), 4096)
    len = MbedTLS.encrypt!(pk_ctx, token, outbuf, rng)
    secure_key = base64encode(outbuf[1:len])
end

function get_github_user(outs, ins, cfg=LibGit2.GitConfig())
    # Get user name
    user = LibGit2.get(cfg, "github.user", "")
    if isempty(user)
        println(outs, """
        GitHub username not globally configured. You will have to enter your
        GitHub username below. To avoid this prompt in the future, set your
        GitHub username using `git config --global github.user <username>`.
        """)
        print(outs, "GitHub user name: ")
        user = readline(ins)
    end
    user
end

"""
Sets up travis for an existing repository
"""
function setup_travis(repo)
    # Get user name
    user = get_github_user(Base.stdout, Base.stdin)
    gr = GitHub.Repo(repo)
    token = obtain_token(Base.stdout, Base.stdin, GitHub.name(gr), user)
    secure_key = obtain_secure_key(Base.stdout, token, gr)
    print_travis_deploy(Base.stdout, gr, secure_key)
end

function push_repo(api::GitHub.GitHubWebAPI, lrepo, rrepo, user, token, refspecs)
    # Push the empty commit
    LibGit2.push(lrepo, remoteurl="https://github.com/$(GitHub.name(rrepo)).git",
        payload=Nullable(LibGit2.UserPasswordCredentials(deepcopy(user),deepcopy(token))),
        refspecs=refspecs)
end

function github_deploy(state::WizardState; git_cfg = LibGit2.GitConfig())
    println(state.outs, """
    Let's deploy a builder repository to GitHub. This repository will be set up
    to use Travis CI to build binaries and then upload them to GitHub releases.
    """)

    # Prompt for the GitHub repository name
    print(state.outs, "Enter the desired name for the new repository: ")
    github_name = readline(state.ins)

    user = get_github_user(state.outs, state.ins, git_cfg)

    # Could re-use the package manager's token here, but we need to create a
    # new token for deployment purposes anyway
    token = obtain_token(state.outs, state.ins, github_name, user; github_api=state.github_api)

    # Create a local repository
    repo_dir = tempname()
    auth = GitHub.OAuth2(token)
    LibGit2.with(LibGit2.init(repo_dir)) do repo
        common_git_repo_setup(repo_dir, repo, state; git_cfg = git_cfg)
        # Create the README file
        open(joinpath(repo_dir, "README.md"), "w") do f
            print(f, """
            # $github_name

            [![Build Status](https://travis-ci.org/$(user)/$(github_name).svg?branch=master)](https://travis-ci.org/$(user)/$(github_name))

            This repository builds binary artifacts for the $(state.name) project. Binary artifacts are automatically uploaded to
            [this repository's GitHub releases page](https://github.com/$(user)/$(github_name)/releases) whenever a tag is created
            on this repository.

            This repository was created using [BinaryBuilder.jl](https://github.com/JuliaPackaging/BinaryBuilder.jl)
            """)
        end
        # Create the GitHub repository
        gr = GitHub.create_repo(state.github_api, GitHub.Owner(user),
                github_name; auth=auth)
        # Set up travis
        push_repo(state.github_api, repo, gr, user, token, ["+HEAD:refs/heads/master"])
        try
            secure_key = obtain_secure_key(state.outs, token, gr; travis_endpoint=state.travis_endpoint)
            open(joinpath(repo_dir, ".travis.yml"), "w") do f
                # Create the first part of the .travis.yml file
                print_travis_file(f, state)
                println(f)
                # Create the deployment portion
                print_travis_deploy(f, gr, secure_key)
            end
        catch e
            Base.display_error(state.outs, e, catch_backtrace())
            printstyled(state.outs, """
                Something went wrong generating the deployment steps.
                We will finish pushing to GitHub, but you may have to setup
                deployment manually.
            """, color = :red)
            open(joinpath(repo_dir, ".travis.yml"), "w") do f
                # Create the first part of the .travis.yml file
                print_travis_file(f, state)
            end
        end
        LibGit2.add!(repo, "build_tarballs.jl", "LICENSE.md", "README.md",
                           ".travis.yml", ".gitignore")
        LibGit2.commit(repo, "Add autogenerated files to build $(state.name)")
        push_repo(state.github_api, repo, gr, user, token, ["+HEAD:refs/heads/master"])
        println(state.outs, "Deployment Complete")
    end
    rm(repo_dir; recursive=true)
end

function step7(state::WizardState)
    printstyled(state.outs, "\t\t\tDone!\n\n", bold=true)

    print(state.outs, "Your build script was:\n\n\t")
    print(state.outs, replace(state.history, "\n" => "\n\t"))

    printstyled(state.outs, "\t\t\t# Step 7: Deployment\n\n", bold=true)

    function nonempty_line_prompt(name, msg)
        val = ""
        while true
            print(state.outs, msg, "\n> ")
            val = readline(state.ins)
            println(state.outs)
            if !isempty(val)
                break
            end
            printstyled(state.outs, "$(name) may not be empty!\n", color=:red)
        end
        return val
    end

    msg = strip("""
    Enter a name for this project.  This will be used for filenames:
    """)
    state.name = nonempty_line_prompt("Name", msg)
    msg = strip("""
    Enter a version number for this project.  This will be used for filenames:
    """)
    state.version = VersionNumber(nonempty_line_prompt("Version", msg))
    println(state.outs, "Use this as your build_tarballs.jl:")
    println(state.outs, "\n```")
    print_build_tarballs(state.outs, state)
    println(state.outs, "```")

    println(state.outs, "Use this as your .travis.yml")
    println(state.outs, "\n```")
    print_travis_file(state.outs, state)
    println(state.outs, "```")

    terminal = TTYTerminal("xterm", state.ins, state.outs, state.outs)
    deploy_select = request(terminal,
        "May I help you with the deployment of these scripts?",
        RadioMenu([
            "Let's create a GitHub repository",
            "Just get me a local git repository",
            "No, thanks"
        ])
    )
    println(state.outs)

    if deploy_select == 1
        github_deploy(state)
    elseif deploy_select == 2
        local_deploy(state)
    else
        return
    end
end


text:
struct Blade{T}<:GeometricAlgebraType
    coef::T
    index::Int
end

scalar(coef) = Blade(coef, 1)

is_scalar(b::Blade) = b.index == 1

eltype(::Type{<:Blade{T}}) where {T} = T
eltype(b::Blade) = eltype(typeof(b))

grade(::Number) = 0

is_homogeneous(::Blade) = true

(==)(x::Blade, y::Blade) = x.index == y.index && x.coef == y.coef
(≈)(x::Blade, y::Blade; kwargs...) = x.index == y.index && isapprox(x.coef, y.coef; kwargs...)

Base.iszero(b::Blade) = b.coef ≈ 0

struct KVector{K,V<:MVector}<:GeometricAlgebraType
    coefs::V
    start::Int
end

KVector{K}(coefs::AbstractVector) where {K} = KVector{K}(MVector{length(coefs)}(coefs))

const Bivector = KVector{2}
const Trivector = KVector{3}
const Quadvector = KVector{4}

vectype(::Type{<:KVector{<:Any,V}}) where {V} = V

eltype(T::Type{<:KVector}) = eltype(vectype(T))

length(T::Type{<:KVector}) = length(vectype(T))

grade(::Type{<:KVector{K}}) where {K} = K
grades(T::Type{<:KVector}) = [grade(T)]

# define methods for instances
for f ∈ [:eltype, :length, :grade, :grades]
    @eval begin
        $f(kvec::KVector) = $f(typeof(kvec))
    end
end

setindex!(kvec::KVector, args...) = setindex!(kvec.coefs, args...)

store!(kvec::KVector, b::Blade) = setindex!(kvec, b.coef, value(kvec, b))

function add!(kvec::KVector, b::Blade)
    i = index(kvec, b)
    setindex!(kvec, kvec[i] + b.coef, i)
end

getindex(kvec::KVector, args...) = getindex(kvec.coefs, args...)

index(kvec::KVector, i) = i - (kvec.start - 1)
index(kvec::KVector, b::Blade) = b.index - (kvec.start - 1)

value(x, i) = x[index(x, i)]

blades(x::GeometricAlgebraType) = (Blade(c, i) for (c, i) ∈ zip(x.coefs, indices(x)))

nonzero_blades(x::GeometricAlgebraType) = (b for b ∈ blades(x) if !iszero(b))

is_homogeneous(::KVector) = true

indices(kvec::KVector) = (kvec.start):(kvec.start + length(kvec) - 1)

function show(io::IO, @nospecialize kvec::KVector)
    if kvec == zero(typeof(kvec), eltype(kvec))
        print(io, string(scalar(zero(eltype(kvec)))))
    else
        print(io, join(string.(blades(kvec)), " + "))
    end
end


text:
@testset "activation broadcast" begin
    for f in NNlib.ACTIVATIONS
        if f ∉ [:rrelu]
            @eval gputest(x -> $f.(x), rand(Float64, 5))
        end
    end
end

@testset "forward diff" begin
    f(x) = logσ.(x)
    ds = Dual.(rand(5),1)
    @test f(ds) ≈ collect(f(CuArray(ds)))
end

@testset "softplus" begin
  # softplus does not give `Inf` for large arguments
   x = CuArray([1000.])
   @test all(softplus.(x) .== x)
end

@testset "input is preserved" begin
    x = CUDA.ones(1)
    @test Array(x) == [1f0]
    tanh.(x)
    @test Array(x) == [1f0]
    y = tanh.(x)
    @test Array(x) == [1f0]
    @test Array(y) == [tanh(1f0)]
    x .= tanh.(y)
    @test Array(y) == [tanh(1f0)]
    @test Array(x) == [tanh(tanh(1f0))]
end


text:
"""
	$(SIGNATURES)

Stacked bar graphs for a matrix by (x,y,z).
Dimension `subPlotIdx` is used for subplots. Dimension `groupIdx` is used to group bars. The remaining dimension makes the bars in each group.

# Example
```julia
grouped_bar_xyz(xyzM, [["x1" "x2"], ["y1", "y2"], ["z1", "z2", z3"]];
    yLabel = "y label", groupIdx = 2, subplotIdx = 3);
```
"""
function grouped_bar_xyz(xyzM :: AbstractArray{F1, 3}, xyzLabelV;
    yLabel :: AbstractString, legendPos = :best,
    groupIdx :: Integer = 2, subPlotIdx :: Integer = 3) where F1 <: Number

    nSub = size(xyzM, subPlotIdx);
    legendIdx = legend_index(groupIdx, subPlotIdx);
    subLabelV = xyzLabelV[subPlotIdx];

    fig = blank_plot();
    nRows, nCols = subplot_layout(nSub);
    axV = Vector{Axis}(undef, nSub);
    for iSub = 1 : nSub
        dataM = selectdim(xyzM, subPlotIdx, iSub);
        if legendIdx < groupIdx
            # Group index must be rows
            dataM = dataM';
        end
        # Legend only for first panel
        if iSub == 1
            subLegPos = legendPos;
        else
            subLegPos = :none;
        end
        pos = subplot_pos(iSub, nRows, nCols);
        _, axV[iSub] = grouped_bar_graph(xyzLabelV[groupIdx], dataM;
            xLabel = subLabelV[iSub], yLabel = yLabel,
            fig = fig, pos = pos);
        # makie +++   legendPos = subLegPos,  legendV = make_legend(xyzLabelV[legendIdx]),
    end
    link_axes(axV...);
    # p = plot(pV..., link = :all);
    return fig, axV
end

function legend_index(groupIdx, subPlotIdx)
    @assert groupIdx != subPlotIdx
    availV = trues(3);
    availV[groupIdx] = false;
    availV[subPlotIdx] = false;
    legIdx = findfirst(availV);
    return legIdx
end

function group_indices(subPlotIdx)
    if subPlotIdx == 3
        groupIdx = 2;
        legendIdx = 1;
    else
        groupIdx = 3;
        if subPlotIdx == 2
            legendIdx = 1;
        else
            legendIdx = 2;
        end
    end
    @assert sort([subPlotIdx, groupIdx, legendIdx]) == [1,2,3]
    return groupIdx, legendIdx
end

# -----------------


text:
module nanoJulia
using Statistics, FASTX, DataFrames, Printf, Formatting, BioAlignments, XAM, Plots, HDF5, CSV, BioSequences
export nanoread, generateStatSummary, plotReadLen2QualScatter,
       plotReadLen2QualHistogram2D, readFast5, readFastq, readBAM,
       plotReadQual2IdentScatter, plotReadQual2IdentHistogram2D,
       plotReadLenDist, plotSquiggle, readSeqSummary, calculate_GC_content

include("datatype.jl")
include("utilities.jl")
include("record_handler.jl")
include("nanoread.jl")
include("info_handler.jl")
include("statistics_handler.jl")

"""
    readFast5(f5file, basecall_group)

Read and parse a fast5 file to extract basecalled fastq information.
The extracted fastq info will be parsed, then the required information
of each read will be extracted, calculated, and exported as a data frame.
The `basecall_group` could be determined simply by using `h5dump` on a
fast5 file. For example, you can type `h5dump -n single_read.fast5` in
terminal, and the content of this fast5 will be shown like this:
```
HDF5 "fff07ce7-f378-47ce-a71a-488d9a1a9af8.fast5" {
FILE_CONTENTS {
 group      /
 group      /Analyses
 group      /Analyses/Basecall_1D_000
 group      /Analyses/Basecall_1D_000/Summary
 group      /Analyses/Basecall_1D_000/Summary/basecall_1d_template
 group      /Analyses/Basecall_1D_001
 group      /Analyses/Basecall_1D_001/BaseCalled_template
 dataset    /Analyses/Basecall_1D_001/BaseCalled_template/Fastq
 dataset    /Analyses/Basecall_1D_001/BaseCalled_template/Move
 dataset    /Analyses/Basecall_1D_001/BaseCalled_template/Trace
 group      /Analyses/Basecall_1D_001/Summary
 group      /Analyses/Basecall_1D_001/Summary/basecall_1d_template
 group      /Analyses/Segmentation_000
 group      /Analyses/Segmentation_000/Summary
 group      /Analyses/Segmentation_000/Summary/segmentation
 group      /Analyses/Segmentation_001
 group      /Analyses/Segmentation_001/Summary
 group      /Analyses/Segmentation_001/Summary/segmentation
 group      /Raw
 group      /Raw/Reads
 group      /Raw/Reads/Read_1950
 dataset    /Raw/Reads/Read_1950/Signal
 group      /UniqueGlobalKey
 group      /UniqueGlobalKey/channel_id
 group      /UniqueGlobalKey/context_tags
 group      /UniqueGlobalKey/tracking_id
 }
}
```
You can observe this output, and notice that `Fastq` locates in the directory
`/Analyses/Basecall_1D_001/BaseCalled_template`. Therefore, the `basecall_group`
sould be set as `Basecall_1D_001` not `Basecall_1D_000`.

# Examples:
1. Read a single-read fast5.
```
julia> readFast5("fff07ce7-f378-47ce-a71a-488d9a1a9af8.fast5", "Basecall_1D_001")
1×3 DataFrame
 Row │ quality  length  gc_content
     │ Float64  Int64   Float64
─────┼─────────────────────────────
   1 │ 5.05611    1326      0.4759
```

2. Read a multi-reads fast5.
julia> readFast5("FAM93744_fail_6a4bbe82_1.fast5", "Basecall_1D_000")
4000×3 DataFrame
  Row │ quality  length  gc_content
      │ Float64  Int64   Float64
──────┼─────────────────────────────
    1 │     3.7     255      0.4314
    2 │     4.5     331      0.3897
  ⋮   │    ⋮       ⋮         ⋮
 3999 │     6.6     849      0.3604
 4000 │     4.2     164      0.5915
                   3996 rows omitted
"""
function readFast5(fast5file::String, basecall_group::String)::DataFrames.DataFrame
	h5open(fast5file) do f5
        file_version = read(attrs(f5), "file_version")
        extracted_info = nanoread(f5, file_version, basecall_group)
        return extracted_info
	end
end

"""
    readFastq(fastqfile)

Read and parse a fastq file to extract and calculate read length, read quality,
and gc-content, and finally export those information as a data frame.

# Example:

```
julia> readFastq("FAO34954_pass_b9e3d78f_0.fastq")
4000×3 DataFrame
  Row │ quality  length  gc_content
      │ Float64  Int64   Float64
──────┼─────────────────────────────
    1 │     7.5    1571      0.578
    2 │     9.8    1408      0.571
    3 │    10.5     777      0.4041
    4 │     8.6     301      0.4983
    5 │    11.5     318      0.3962
    6 │    10.6     509      0.5108
  ⋮   │    ⋮       ⋮         ⋮
 3996 │    10.6     616      0.5747
 3997 │    11.7     837      0.5388
 3998 │     8.0     403      0.4367
 3999 │    10.7     481      0.5717
 4000 │     7.8     223      0.4888
                   3989 rows omitted
```
"""
function readFastq(fastqfile::String)::DataFrames.DataFrame
    open(FASTQ.Reader, fastqfile) do fastq
        extracted_info = nanoread(fastq)
        return extracted_info
    end
end

"""
    readBAM(bamfile)

Read and parse a sorted and indexed BAM file to extract and calculate read length,
read quality, alignment identity and gc-content, and finally export those information
as a data frame.

# Example:

```
julia> readBAM("map_srt.bam")
5839×4 DataFrame
  Row │ quality  length  identity  gc_content
      │ Float64  Int64   Float64   Float64
──────┼───────────────────────────────────────
    1 │    12.9     119      94.5      0.4034
    2 │    16.1     120      96.7      0.4
    3 │    15.3     145      95.2      0.3793
    4 │    10.7     153      92.1      0.4183
    5 │     9.0     146      93.0      0.4247
    6 │    12.2     147      90.2      0.415
  ⋮   │    ⋮       ⋮        ⋮          ⋮
 5835 │     9.1     296      89.6      0.3716
 5836 │    12.1     283      94.7      0.3958
 5837 │    10.3     341      94.0      0.3871
 5838 │    11.0     244      93.5      0.4016
 5839 │    12.6     157      96.8      0.4076
                             5828 rows omitted
```
"""
function readBAM(bamfile::String)::DataFrames.DataFrame
    open(BAM.Reader, bamfile) do bam
        extracted_info = nanoread(bam)
        return extracted_info
    end
end

"""
    readSeqSummary(sequencing_summary_file)

Read and parse a sequencing summary file to extract and calculate read length and quality, and finally export those information as a data frame.

# Example:

```
julia> readSeqSummary("sequencing_summary_FAO34954_b9e3d78f.txt")
176498×2 DataFrame
    Row │ quality  length
        │ Float64  Int64
────────┼─────────────────
      1 │     7.2    1571
      2 │     9.3    1408
      3 │    10.1     777
      4 │     8.4     301
      5 │    11.0     318
      6 │    10.3     509
   ⋮    │    ⋮       ⋮
 176494 │    10.1     667
       176483 rows omitted
```
"""
function readSeqSummary(seqsummaryfile::String)::DataFrames.DataFrame
    extracted_info = CSV.File(seqsummaryfile) |> DataFrame |> nanoread
    return extracted_info
end

end


text:
struct VectorWithEntryRemoved{T,A} <: AbstractVector{T}
  a::A
  index::Int
  function VectorWithEntryRemoved(a::AbstractVector,index::Integer)
    A = typeof(a)
    T = eltype(a)
    @assert 1 <= index <= length(a)
    new{T,A}(a,index)
  end
end

Base.IndexStyle(::Type{<:VectorWithEntryRemoved}) = IndexLinear()

function Base.getindex(v::VectorWithEntryRemoved,i::Integer)
  i < v.index ? v.a[i] : v.a[i+1]
end

Base.size(v::VectorWithEntryRemoved) = (length(v.a)-1,)

function array_cache(v::VectorWithEntryRemoved)
  array_cache(v.a)
end

function getindex!(cache,v::VectorWithEntryRemoved,i::Integer)
  i < v.index ? getindex!(cache,v.a,i) : getindex!(cache,v.a,i+1)
end

function Base.sum(a::VectorWithEntryRemoved)
  sum(a.a) - a.a[a.index]
end

function Base.setindex!(a::VectorWithEntryRemoved,v,i::Integer)
   i < a.index ? (a.a[i] = v) : (a.a[i+1] = v)
end


text:
# this just generates the necessary wrappers

@_serialized_change_unwrap add_reactions
@_serialized_change_unwrap change_bound
@_serialized_change_unwrap change_bounds
@_serialized_change_unwrap remove_metabolite
@_serialized_change_unwrap remove_metabolites
@_serialized_change_unwrap remove_reaction
@_serialized_change_unwrap remove_reactions

"""
    unwrap_serialized(model::Serialized)

Returns the model stored in the serialized structure.
"""
function unwrap_serialized(model::Serialized)
    precache!(model)
    model.m
end


text:
module PROPACK

export tsvd, tsvdvals, tsvd_irl, tsvdvals_irl

using LinearOperators
using PROPACK_jll

include("wrappers.jl")

# callback using dparm as passthrough pointer to save the linear operator
# thanks http://julialang.org/blog/2013/05/callback !
function __f__(
  transa_::Ptr{UInt8},
  m_::Ptr{Int},
  n_::Ptr{Int},
  x_::Ptr{T},
  y_::Ptr{T},
  dparm_::Ptr{T},
  iparm::Ptr{Int},
) where {T}
  m = unsafe_load(m_)
  n = unsafe_load(n_)
  dparm = reinterpret(Ptr{Nothing}, dparm_)
  transa = Char(unsafe_load(transa_))
  A = unsafe_pointer_to_objref(dparm)::AbstractLinearOperator
  (nargin, nargout) = transa == 'n' ? (n, m) : (m, n)
  x = unsafe_wrap(Array, x_, nargin)
  if transa == 'n'
    y = A * x
  else
    y = A' * x
  end
  unsafe_copyto!(y_, pointer(y), nargout)
  nothing
end

"""
    tsvd(A::AbstractLinearOperator; kwargs...)

Compute a few leading singular triplets of `A` using only products with `A` and `A'`.

#### Keyword arguments
- `initvec::Vector`: initial vector for the iterations (default: zeros)
- `k::Integer`: number of leading singular values to approximate (default: 1)
- `kmax::Integer`: maximum dimensionality of search space (default: `min(size(A))`+10)
- `tolin::Real`: desired accuracy; the error on `s[i]` is approximately `max(16ϵ s[1], tolin * s[i])`
  (default: √ϵ).

#### Return values
- `U::Array`: orthogonal matrix of left singular vectors
- `s::Vector`: approximate leading singular values
- `V::Array`: orthogonal matrix of right singular vectors
- `bnd::Array`: bound on the accuracy of each singular value
- `nprod::Int`: number of products with `A` required
- `ntprod::Int`: number of products with `A'` required.

The arrays `U`, `s` and `V` are such that `A - U * diagm(s) * V'` should be of the order of the next
largest singular value.
"""
function tsvd(
  A::AbstractLinearOperator{T};
  initvec::Vector{T} = zeros(T, size(A, 1)),
  k::Integer = 1,
  kmax::Integer = min(size(A)...) + 10,
  tolin::Real = sqrt(eps(real(one(T)))),
) where {T}
  __pf__ =
    @cfunction(__f__, Nothing, (Ptr{UInt8}, Ptr{Int}, Ptr{Int}, Ptr{T}, Ptr{T}, Ptr{T}, Ptr{Int}))

  m, n = size(A)
  dparm = pointer_from_objref(A)
  U, s, V, bnd = lansvd('Y', 'Y', m, n, __pf__, initvec, k, kmax, tolin, dparm)
  return (U, s, V, bnd, A.nprod, A.nctprod)
end

"""
    tsvdvals(A::AbstractLinearOperator; kwargs...)

Compute a few leading singular values of `A` using only products with `A` and `A'`.

#### Keyword arguments
See the documentation of `tsvd()`.

#### Return values
- `s::Vector`: approximate leading singular values
- `bnd::Array`: bound on the accuracy of each singular value
- `nprod::Int`: number of products with `A` required
- `ntprod::Int`: number of products with `A'` required.
"""
function tsvdvals(
  A::AbstractLinearOperator{T};
  initvec::Vector{T} = zeros(T, size(A, 1)),
  k::Integer = 1,
  kmax::Integer = min(size(A)...) + 10,
  tolin::Real = sqrt(eps(real(one(T)))),
) where {T}
  __pf__ =
    @cfunction(__f__, Nothing, (Ptr{UInt8}, Ptr{Int}, Ptr{Int}, Ptr{T}, Ptr{T}, Ptr{T}, Ptr{Int}))

  m, n = size(A)
  dparm = pointer_from_objref(A)
  _, s, _, bnd = lansvd('N', 'N', m, n, __pf__, initvec, k, kmax, tolin, dparm)
  return (s, bnd, A.nprod, A.nctprod)
end

"""
    tsvd_irl(A::AbstractLinearOperator; kwargs...)

Compute a few extreme singular triplets of `A` using only products with `A` and `A'` and the
implicitly restarted Lanczos bidiagonalization method.

#### Keyword arguments
- `smallest::Bool`: whether the smallest or leading triplets should be approximated (default: `True`)
- `initvec::Vector`: initial vector for the iterations (default: zeros)
- `kmax::Integer`: maximum dimensionality of search space (default: `min(size(A))`+10)
- `p::Integer`: number of shifts per restart (default: 1)
- `k::Integer`: number of extreme singular values to approximate (default: 1)
- `maxiter::Integer`: maximum number of restarts (default: `min(size(A))`)
- `tolin::Real`: desired accuracy; the error on `s[i]` is approximately `max(16ϵ s[1], tolin * s[i])`
  (default: √ϵ).

#### Return values
- `U::Array`: orthogonal matrix of left singular vectors
- `s::Vector`: approximate leading singular values
- `V::Array`: orthogonal matrix of right singular vectors
- `bnd::Array`: bound on the accuracy of each singular value
- `nprod::Int`: number of products with `A` required
- `ntprod::Int`: number of products with `A'` required.

If `smallest == False`, the arrays `U`, `s` and `V` are such that `A - U * diagm(s) * V'` should be
of the order of the next largest singular value.

If `smallest == True`, `U * diagm(s) * V'` is (an approximation of) the best rank-`k` approximation
of `A`.
"""
function tsvd_irl(
  A::AbstractLinearOperator{T};
  smallest::Bool = true,
  initvec::Vector{T} = zeros(T, size(A, 1)),
  kmax::Integer = min(size(A)...) + 10,
  p::Integer = 1,
  k::Integer = 1,
  maxiter::Integer = min(size(A)...),
  tolin::Real = sqrt(eps(real(one(T)))),
) where {T}
  __pf__ =
    @cfunction(__f__, Nothing, (Ptr{UInt8}, Ptr{Int}, Ptr{Int}, Ptr{T}, Ptr{T}, Ptr{T}, Ptr{Int}))

  m, n = size(A)
  dparm = pointer_from_objref(A)
  U, s, V, bnd = lansvd_irl(
    smallest ? 'S' : 'L',
    'Y',
    'Y',
    m,
    n,
    kmax,
    p,
    k,
    maxiter,
    __pf__,
    initvec,
    tolin,
    dparm,
  )
  return (U, s, V, bnd, A.nprod, A.nctprod)
end

"""
    tsvdvals_irl(A::AbstractLinearOperator; kwargs...)

Compute a few extreme singular values of `A` using only products with `A` and `A'` and the
implicitly restarted Lanczos bidiagonalization method.

#### Keyword arguments
See the documentation of `tsdv_irl()`.

#### Return values
- `s::Vector`: approximate leading singular values
- `bnd::Array`: bound on the accuracy of each singular value
- `nprod::Int`: number of products with `A` required
- `ntprod::Int`: number of products with `A'` required.
"""
function tsvdvals_irl(
  A::AbstractLinearOperator{T};
  smallest::Bool = true,
  initvec::Vector{T} = zeros(T, size(A, 1)),
  kmax::Integer = min(size(A)...) + 10,
  p::Integer = 1,
  k::Integer = 1,
  maxiter::Integer = min(size(A)...),
  tolin::Real = sqrt(eps(real(one(T)))),
) where {T}
  __pf__ =
    @cfunction(__f__, Nothing, (Ptr{UInt8}, Ptr{Int}, Ptr{Int}, Ptr{T}, Ptr{T}, Ptr{T}, Ptr{Int}))

  m, n = size(A)
  dparm = pointer_from_objref(A)
  _, s, _, bnd = lansvd_irl(
    smallest ? 'S' : 'L',
    'N',
    'N',
    m,
    n,
    kmax,
    p,
    k,
    maxiter,
    __pf__,
    initvec,
    tolin,
    dparm,
  )
  return (s, bnd, A.nprod, A.nctprod)
end

# interface for matrices
for fname in (:tsvd, :tsvdvals, :tsvd_irl, :tsvdvals_irl)
  @eval $fname(A::AbstractMatrix{T}; kwargs...) where {T} =
    $fname(PreallocatedLinearOperator(A); kwargs...)
end

end # module


text:
module Bukdu

__precompile__(true)

include("exports.jl")
include("keyword.jl")
include("naming.jl")
include("filter.jl")
include("controller.jl")
include("layout.jl")
include("octo.jl")
include("view.jl")
include("renderers.jl")
include("logger.jl")
include("router.jl")
include("endpoint.jl")
include("config.jl")
include("plug.jl")
include("server.jl")

end # module Bukdu


text:
export tmapfoldr;

"""
    tmapfoldr(f::Function, op::Function, itr::AbstractArray; init)::AbstractArray

Multi-threaded version of [mapfoldr(f, op, itr; init)](https://docs.julialang.org/en/v1.2/base/collections/#Base.mapfoldr-Tuple{Any,Any,Any}). Only the **mapping** part is parallelised.
"""
function tmapfoldr(f::Function, op::Function, itr::T; init) where T<:AbstractArray
	return foldr(op, tmap(f, itr); init = init);
end

"""
    tmapfoldr(f::Function, op::Function, itr::AbstractArray)::AbstractArray

Multi-threaded version of [mapfoldr(f, op, itr)](https://docs.julialang.org/en/v1.2/base/collections/#Base.mapfoldr-Tuple{Any,Any,Any}). Only the **mapping** part is parallelised.
"""
function tmapfoldr(f::Function, op::Function, itr::T) where T<:AbstractArray
	return foldr(op, tmap(f, itr));
end


text:
@testset "MSA Widget" begin
    @testset "Options" begin
        color = ColorScheme(scheme="taylor", colorBackground=true)
        @test color.fields == Dict("colorscheme" => Dict("scheme" => "taylor", "colorBackground" => true))

        conf = Conf(eventBus = true, alphabetSize = 20)
        @test conf.fields == Dict("conf" => Dict("eventBus" => true, "alphabetSize" => 20))

        columns = Columns(hidden = [1,2])
        @test columns.fields == Dict("columns" => Dict("hidden" => [1,2]))

        vis = Vis(sequences =  true, markers = true)
        @test vis.fields == Dict("vis" => Dict("sequences" => true, "markers" => true))

        zoomer = Zoomer(alignmentWidth =  "auto", alignmentHeight = 225)
        @test zoomer.fields == Dict("zoomer" => Dict("alignmentWidth" => "auto", "alignmentHeight" => 225))
    end

    @testset "MSA" begin
        seqs = ">seq1\nACGT\n>seq2\nACGT"

        msa = MSA(seqs)
        @test typeof(msa) == MSA

        msa = MSA(seqs, ColorScheme(scheme="taylor"), Zoomer(aling = "auto"))
        @test typeof(msa) == MSA

        @test_throws BioviewError MSA(seqs, Dict("color" => "taylor"))
    end
end


text:
function ueberpruefeLaengePixel(A,Pixel,Laenge1, Laenge2, Laenge3,Laenge4, Laenge5, Laenge6,Laenge7,Laenge8,Laenge9,Laenge10,Laenge11,Laenge12)

if round(A[1,Pixel];digits=1) == round(Laenge1;digits=1)
    if round(A[2,Pixel];digits=1) == round(Laenge2;digits=1)
        if round(A[3,Pixel];digits=1) == round(Laenge3;digits=1)
            if round(A[4,Pixel];digits=1) == round(Laenge4;digits=1)
                if round(A[5,Pixel];digits=1) == round(Laenge5;digits=1)
                    if round(A[6,Pixel];digits=1) == round(Laenge6;digits=1)
                        if round(A[7,Pixel];digits=1) == round(Laenge7;digits=1)
                           if round(A[8,Pixel];digits=1) == round(Laenge8;digits=1)
                               if round(A[9,Pixel];digits=1) == round(Laenge9;digits=1)
                                   if round(A[10,Pixel];digits=1) == round(Laenge10;digits=1)
                                        if round(A[11,Pixel];digits=1) == round(Laenge11;digits=1)
                                            if round(A[12,Pixel];digits=1) == round(Laenge12;digits=1)
                                                println("Ihr habt die Spalte der Matrix korrekt interpretiert.")
                                            else
                                                println("Überprüft noch einmal den Eintrag für Laenge12.")
                                            end
                                        else
                                            println("Überprüft noch einmal den Eintrag für Laenge11.")
                                        end
                                   else
                                        println("Überprüft noch einmal den Eintrag für Laenge10.")
                                   end
                               else
                                    println("Überprüft noch einmal den Eintrag für Laenge9.")
                               end
                           else
                                println("Überprüft noch einmal den Eintrag für Laenge8.")
                           end
                        else
                            println("Überprüft noch einmal den Eintrag für Laenge7.")
                        end
                    else
                        println("Überprüft noch einmal den Eintrag für Laenge6.")
                    end
                else
                    println("Überprüft noch einmal den Eintrag für Laenge5.")
                end
            else
                println("Überprüft noch einmal den Eintrag für Laenge4.")
            end
        else
            println("Überprüft noch einmal den Eintrag für Laenge3.")
        end
    else
        println("Überprüft noch einmal den Eintrag für Laenge2.")
    end
else
    println("Überprüft noch einmal den Eintrag für Laenge1.")
end

end


text:
#  models created by contextualizing Human1 using data from Hart et al., “High-Resolution CRISPR Screens Reveal Fitness Genes and Genotype-Specific Cancer Liabilities.”

const HART_GEM_PREFIX = "HartGEM"

function load_Hart_raw_dat()
    hart_file = rawdir(Human1, [ "Human1_Publication_Data_Scripts/tINIT_GEMs/run_tINIT_outputs/Hart2015" ], "tINIT_Hart2015_HumanGEM_outputs.mat")
    return MAT.matread(hart_file)["INIT_output"]
end

function load_Hart_mat_model(;tissue = "GBM")
    dat = load_Hart_raw_dat()
    target_modeli = findfirst(isequal(tissue), vec(dat["tissues"]))
    return vec(dat["model"])[target_modeli]
end

function load_Hart_raw_model(; uncompress = false, tissue = "GBM")
    model_dict = load_Hart_mat_model(;tissue)
    model = MetNets.MetNet(model_dict; reshape = true)
    uncompress ? model : MetNets.compressed_model(model)
end

save_model(model::MetNets.MetNet; verbose = true, model_params...) =
    sdat(HartGEMs, MetNets.compressed_model(model),
        HART_GEM_PREFIX, model_params, ".jls";  verbose
    )

function load_model(;uncompress = false, verbose = false,
        model_params...
    )

    modelid = get(model_params, :modelid, "") |> string
    tissue = get(model_params, :tissue, "") |> string
    stst = get(model_params, :stst, "") |> string

    if modelid == "mat"
        return load_Hart_mat_model(;tissue)
    elseif modelid == "raw"
        return load_Hart_raw_model(;tissue, uncompress)
    elseif modelid == "base" || modelid == "fva_base" || modelid == "scaled" || modelid == "fva_scaled"
        model = ldat(HartGEMs, HART_GEM_PREFIX, (;modelid, tissue), ".jls"; verbose)
        return uncompress ? MetNets.uncompressed_model(model) : model
    elseif modelid == "stst_base" || modelid == "stst_scaled"
        model = ldat(HartGEMs, HART_GEM_PREFIX, (;modelid, tissue, stst), ".jls"; verbose)
        return uncompress ? MetNets.uncompressed_model(model) : model
    else
        error("Unknown '$(modelid)' modelid")
    end
end

function check_modelfile(;params...)
    exist = isfile(datdir(HartGEMs, HART_GEM_PREFIX, params, ".jls"))
    exist && @info("Model cached ", params...)
    return exist
end


text:
# Storing a table of normal quantiles so I don't need to add a Distributions.jl dependency

const NORM_TABLE = [
    -3.09052913792527
    -2.87847701476615
    -2.74810910322958
    -2.65240725811552
    -2.57617489950329
    -2.51249701319257
    -2.45762240440889
    -2.40928031214796
    -2.3659881908323
    -2.3267228670994
    -2.29074749435689
    -2.25751322631763
    -2.22659989524007
    -2.19767845464965
    -2.17048623927379
    -2.14481011722988
    -2.12047468772263
    -2.09733380936838
    -2.07526438887675
    -2.05416174130811
    -2.03393606655888
    -2.01450973381435
    -1.99581516082526
    -1.97779313781454
    -1.96039148835635
    -1.94356398885586
    -1.92726948876869
    -1.9114711882875
    -1.89613604074919
    -1.8812342547096
    -1.86673887632534
    -1.85262543694045
    -1.83887165399534
    -1.82545717583174
    -1.81236336286033
    -1.79957309902681
    -1.78707062866264
    -1.77484141471404
    -1.76287201506288
    -1.75114997422944
    -1.73966372820952
    -1.72840252057389
    -1.71735632826212
    -1.70651579575289
    -1.6958721764973
    -1.68541728067125
    -1.67514342844331
    -1.66504340807147
    -1.65511043824015
    -1.64533813413102
    -1.63572047679064
    -1.62625178541637
    -1.61692669223222
    -1.60774011966837
    -1.59868725959458
    -1.58976355438896
    -1.5809646796499
    -1.57228652838263
    -1.56372519651115
    -1.55527696958423
    -1.54693831055869
    -1.53870584855661
    -1.53057636850434
    -1.52254680157137
    -1.51461421633577
    -1.50677581061069
    -1.49902890387327
    -1.49137093024321
    -1.48379943196366
    -1.47631205334164
    -1.46890653510976
    -1.46158070917414
    -1.45433249371732
    -1.44715988862754
    -1.4400609712286
    -1.43303389228667
    -1.42607687227285
    -1.4191881978619
    -1.4123662186494
    -1.40560934407114
    -1.39891604050989
    -1.39228482857606
    -1.38571428054967
    -1.37920301797242
    -1.37274970937914
    -1.36635306815929
    -1.36001185053937
    -1.35372485367826
    -1.3474909138679
    -1.34130890483236
    -1.33517773611894
    -1.32909635157526
    -1.32306372790702
    -1.31707887331116
    -1.31114082617984
    -1.30524865387087
    -1.29940145154036
    -1.29359834103413
    -1.28783846983403
    -1.28212101005616
    -1.27644515749782
    -1.27081013073041
    -1.26521517023564
    -1.2596595375825
    -1.25414251464285
    -1.2486634028433
    -1.24322152245147
    -1.23781621189474
    -1.23244682710972
    -1.22711274092072
    -1.22181334244574
    -1.2165480365286
    -1.21131624319561
    -1.20611739713578
    -1.20095094720313
    -1.19581635594011
    -1.19071309912105
    -1.18564066531454
    -1.18059855546391
    -1.17558628248485
    -1.17060337087942
    -1.16564935636544
    -1.16072378552085
    -1.15582621544201
    -1.15095621341549
    -1.14611335660259
    -1.14129723173609
    -1.13650743482863
    -1.1317435708921
    -1.12700525366775
    -1.12229210536627
    -1.11760375641764
    -1.11293984523014
    -1.1083000179582
    -1.10368392827867
    -1.09909123717521
    -1.0945216127303
    -1.08997472992474
    -1.08545027044417
    -1.08094792249234
    -1.07646738061097
    -1.07200834550571
    -1.06757052387814
    -1.06315362826348
    -1.05875737687376
    -1.05438149344627
    -1.05002570709708
    -1.04568975217935
    -1.0413733681464
    -1.03707629941914
    -1.03279829525789
    -1.02853910963827
    -1.02429850113113
    -1.0200762327862
    -1.01587207201954
    -1.01168579050441
    -1.00751716406563
    -1.00336597257717
    -0.999231999862866
    -0.995115033600283
    -0.991014865227371
    -0.986931289852029
    -0.982864106164351
    -0.978813116351504
    -0.97477812601512
    -0.970758944091136
    -0.966755382771977
    -0.962767257431005
    -0.958794386549162
    -0.954836591643717
    -0.950893697199062
    -0.946965530599463
    -0.943051922063731
    -0.93915270458171
    -0.935267713852561
    -0.931396788224743
    -0.927539768637666
    -0.923696498564941
    -0.919866823959183
    -0.916050593198315
    -0.912247657033316
    -0.908457868537385
    -0.904681083056451
    -0.900917158161006
    -0.897165953599211
    -0.893427331251229
    -0.88970115508476
    -0.885987291111723
    -0.882285607346064
    -0.878595973762652
    -0.874918262257221
    -0.871252346607333
    -0.867598102434333
    -0.863955407166258
    -0.860324140001676
    -0.856704181874433
    -0.853095415419262
    -0.849497724938252
    -0.845910996368134
    -0.842335117248368
    -0.838769976690004
    -0.835215465345297
    -0.831671475378053
    -0.828137900434687
    -0.824614635615961
    -0.821101577449406
    -0.817598623862384
    -0.814105674155782
    -0.810622628978331
    -0.807149390301506
    -0.803685861395022
    -0.800231946802882
    -0.796787552319982
    -0.793352584969242
    -0.789926952979265
    -0.786510565762491
    -0.783103333893848
    -0.77970516908988
    -0.776315984188337
    -0.77293569312822
    -0.769564210930266
    -0.766201453677858
    -0.762847338498361
    -0.75950178354485
    -0.75616470797825
    -0.752836031949848
    -0.749515676584188
    -0.746203563962325
    -0.742899617105447
    -0.739603759958828
    -0.73631591737613
    -0.733036015104032
    -0.729763979767182
    -0.726499738853455
    -0.723243220699528
    -0.719994354476738
    -0.716753070177244
    -0.713519298600464
    -0.71029297133979
    -0.707074020769574
    -0.70386238003237
    -0.700657983026445
    -0.697460764393524
    -0.694270659506794
    -0.691087604459134
    -0.687911536051589
    -0.684742391782056
    -0.681580109834208
    -0.678424629066621
    -0.67527588900212
    -0.672133829817328
    -0.668998392332415
    -0.665869518001048
    -0.662747148900528
    -0.659631227722116
    -0.656521697761549
    -0.653418502909723
    -0.65032158764356
    -0.647230897017041
    -0.644146376652413
    -0.641067972731549
    -0.637995631987479
    -0.634929301696065
    -0.63186892966784
    -0.628814464239987
    -0.625765854268473
    -0.622723049120314
    -0.619685998665991
    -0.616654653271996
    -0.61362896379351
    -0.61060888156722
    -0.607594358404251
    -0.604585346583237
    -0.601581798843501
    -0.598583668378363
    -0.595590908828565
    -0.592603474275806
    -0.58962131923639
    -0.586644398654988
    -0.583672667898502
    -0.580706082750039
    -0.577744599402985
    -0.574788174455178
    -0.571836764903184
    -0.56889032813667
    -0.565948821932863
    -0.563012204451115
    -0.560080434227546
    -0.557153470169786
    -0.554231271551797
    -0.551313798008786
    -0.548401009532195
    -0.545492866464778
    -0.542589329495759
    -0.539690359656064
    -0.536795918313634
    -0.53390596716881
    -0.531020468249798
    -0.528139383908199
    -0.525262676814613
    -0.52239030995432
    -0.519522246623016
    -0.516658450422623
    -0.513798885257171
    -0.510943515328731
    -0.508092305133422
    -0.505245219457474
    -0.502402223373355
    -0.499563282235957
    -0.496728361678837
    -0.49389742761052
    -0.491070446210858
    -0.488247383927438
    -0.485428207472053
    -0.48261288381722
    -0.479801380192749
    -0.476993664082371
    -0.474189703220406
    -0.471389465588489
    -0.468592919412335
    -0.465800033158564
    -0.463010775531561
    -0.460225115470383
    -0.457443022145722
    -0.454664464956894
    -0.451889413528889
    -0.449117837709448
    -0.446349707566195
    -0.443584993383799
    -0.440823665661185
    -0.438065695108774
    -0.435311052645773
    -0.432559709397495
    -0.429811636692721
    -0.427066806061093
    -0.42432518923055
    -0.421586758124793
    -0.418851484860787
    -0.416119341746303
    -0.41339030127748
    -0.410664336136433
    -0.407941419188885
    -0.405221523481836
    -0.40250462224126
    -0.399790688869832
    -0.397079696944688
    -0.394371620215214
    -0.391666432600858
    -0.388964108188981
    -0.38626462123273
    -0.383567946148934
    -0.380874057516038
    -0.378182930072053
    -0.37549453871254
    -0.372808858488616
    -0.370125864604981
    -0.367445532417981
    -0.364767837433686
    -0.362092755305993
    -0.359420261834756
    -0.356750332963938
    -0.354082944779782
    -0.351418073509011
    -0.348755695517045
    -0.346095787306239
    -0.343438325514148
    -0.340783286911806
    -0.33813064840203
    -0.335480387017742
    -0.332832479920312
    -0.330186904397919
    -0.327543637863934
    -0.32490265785532
    -0.322263942031046
    -0.319627468170533
    -0.316993214172097
    -0.314361158051431
    -0.31173127794009
    -0.309103552083997
    -0.306477958841968
    -0.303854476684253
    -0.301233084191088
    -0.298613760051268
    -0.295996483060739
    -0.293381232121193
    -0.290767986238692
    -0.288156724522299
    -0.285547426182722
    -0.282940070530981
    -0.280334636977082
    -0.277731105028704
    -0.275129454289906
    -0.272529664459841
    -0.269931715331488
    -0.267335586790394
    -0.264741258813429
    -0.262148711467555
    -0.259557924908607
    -0.256968879380086
    -0.25438155521196
    -0.251795932819487
    -0.249211992702035
    -0.246629715441926
    -0.244049081703287
    -0.241470072230908
    -0.238892667849114
    -0.236316849460652
    -0.233742598045577
    -0.231169894660161
    -0.228598720435803
    -0.226029056577955
    -0.223460884365049
    -0.220894185147445
    -0.21832894034638
    -0.215765131452928
    -0.213202740026971
    -0.210641747696179
    -0.208082136154993
    -0.205523887163626
    -0.202966982547062
    -0.200411404194074
    -0.197857134056242
    -0.19530415414698
    -0.192752446540576
    -0.190201993371232
    -0.18765277683212
    -0.18510477917444
    -0.182557982706481
    -0.180012369792705
    -0.177467922852816
    -0.174924624360856
    -0.172382456844294
    -0.169841402883129
    -0.167301445108997
    -0.164762566204284
    -0.162224748901244
    -0.159687975981129
    -0.157152230273319
    -0.154617494654456
    -0.152083752047593
    -0.149550985421342
    -0.147019177789025
    -0.144488312207837
    -0.141958371778012
    -0.139429339641993
    -0.136901198983604
    -0.134373933027236
    -0.131847525037031
    -0.129321958316068
    -0.126797216205564
    -0.124273282084069
    -0.121750139366671
    -0.119227771504207
    -0.116706161982469
    -0.114185294321428
    -0.11166515207445
    -0.10914571882752
    -0.106626978198473
    -0.104108913836226
    -0.101591509420012
    -0.09907474865862
    -0.096558615289639
    -0.094043093078702
    -0.091528165818736
    -0.089013817329217
    -0.086500031455423
    -0.083986792067693
    -0.081474083060691
    -0.078961888352667
    -0.076450191884726
    -0.073938977620099
    -0.071428229543413
    -0.068917931659967
    -0.06640806799501
    -0.063898622593019
    -0.061389579516982
    -0.058880922847681
    -0.056372636682979
    -0.053864705137108
    -0.051357112339956
    -0.048849842436363
    -0.046342879585409
    -0.043836207959717
    -0.041329811744739
    -0.038823675138062
    -0.036317782348706
    -0.03381211759642
    -0.03130666511099
    -0.028801409131539
    -0.026296333905829
    -0.023791423689573
    -0.021286662745731
    -0.018782035343826
    -0.016277525759247
    -0.013773118272557
    -0.011268797168804
    -0.008764546736828
    -0.006260351268573
    -0.003756195058396
    -0.001252062402375
    0.001252062402375
    0.003756195058396
    0.006260351268573
    0.008764546736828
    0.011268797168804
    0.013773118272557
    0.016277525759247
    0.018782035343826
    0.021286662745731
    0.023791423689572
    0.026296333905829
    0.028801409131539
    0.03130666511099
    0.03381211759642
    0.036317782348706
    0.038823675138062
    0.041329811744739
    0.043836207959717
    0.046342879585409
    0.048849842436362
    0.051357112339956
    0.053864705137108
    0.056372636682979
    0.058880922847681
    0.061389579516982
    0.063898622593019
    0.06640806799501
    0.068917931659967
    0.071428229543413
    0.073938977620099
    0.076450191884726
    0.078961888352667
    0.081474083060691
    0.083986792067693
    0.086500031455423
    0.089013817329217
    0.091528165818736
    0.094043093078702
    0.096558615289639
    0.099074748658621
    0.101591509420012
    0.104108913836226
    0.106626978198473
    0.10914571882752
    0.11166515207445
    0.114185294321428
    0.116706161982469
    0.119227771504207
    0.121750139366671
    0.124273282084069
    0.126797216205564
    0.129321958316068
    0.131847525037031
    0.134373933027236
    0.136901198983604
    0.139429339641993
    0.141958371778012
    0.144488312207837
    0.147019177789024
    0.149550985421342
    0.152083752047593
    0.154617494654456
    0.157152230273319
    0.159687975981129
    0.162224748901244
    0.164762566204284
    0.167301445108997
    0.169841402883129
    0.172382456844294
    0.174924624360856
    0.177467922852816
    0.180012369792705
    0.182557982706482
    0.18510477917444
    0.18765277683212
    0.190201993371232
    0.192752446540576
    0.19530415414698
    0.197857134056242
    0.200411404194075
    0.202966982547062
    0.205523887163626
    0.208082136154993
    0.210641747696179
    0.213202740026971
    0.215765131452928
    0.21832894034638
    0.220894185147445
    0.223460884365049
    0.226029056577955
    0.228598720435803
    0.231169894660161
    0.233742598045577
    0.236316849460652
    0.238892667849114
    0.241470072230908
    0.244049081703287
    0.246629715441926
    0.249211992702035
    0.251795932819487
    0.25438155521196
    0.256968879380086
    0.259557924908607
    0.262148711467555
    0.264741258813429
    0.267335586790394
    0.269931715331488
    0.272529664459841
    0.275129454289906
    0.277731105028704
    0.280334636977082
    0.282940070530981
    0.285547426182722
    0.288156724522299
    0.290767986238692
    0.293381232121193
    0.295996483060739
    0.298613760051268
    0.301233084191088
    0.303854476684253
    0.306477958841968
    0.309103552083997
    0.31173127794009
    0.314361158051431
    0.316993214172097
    0.319627468170533
    0.322263942031046
    0.324902657855319
    0.327543637863934
    0.330186904397919
    0.332832479920312
    0.335480387017742
    0.33813064840203
    0.340783286911806
    0.343438325514148
    0.346095787306239
    0.348755695517045
    0.351418073509011
    0.354082944779782
    0.356750332963938
    0.359420261834756
    0.362092755305993
    0.364767837433686
    0.367445532417981
    0.370125864604981
    0.372808858488616
    0.37549453871254
    0.378182930072053
    0.380874057516038
    0.383567946148934
    0.38626462123273
    0.388964108188981
    0.391666432600858
    0.394371620215214
    0.397079696944688
    0.399790688869832
    0.40250462224126
    0.405221523481836
    0.407941419188885
    0.410664336136433
    0.41339030127748
    0.416119341746303
    0.418851484860787
    0.421586758124792
    0.42432518923055
    0.427066806061093
    0.429811636692721
    0.432559709397496
    0.435311052645773
    0.438065695108774
    0.440823665661185
    0.443584993383799
    0.446349707566195
    0.449117837709448
    0.451889413528889
    0.454664464956894
    0.457443022145722
    0.460225115470384
    0.463010775531561
    0.465800033158564
    0.468592919412335
    0.471389465588489
    0.474189703220406
    0.476993664082371
    0.47980138019275
    0.48261288381722
    0.485428207472053
    0.488247383927438
    0.491070446210858
    0.49389742761052
    0.496728361678837
    0.499563282235957
    0.502402223373355
    0.505245219457474
    0.508092305133422
    0.510943515328731
    0.513798885257171
    0.516658450422623
    0.519522246623016
    0.52239030995432
    0.525262676814614
    0.528139383908199
    0.531020468249798
    0.53390596716881
    0.536795918313634
    0.539690359656064
    0.542589329495759
    0.545492866464778
    0.548401009532195
    0.551313798008786
    0.554231271551798
    0.557153470169786
    0.560080434227546
    0.563012204451115
    0.565948821932863
    0.56889032813667
    0.571836764903184
    0.574788174455178
    0.577744599402985
    0.580706082750039
    0.583672667898502
    0.586644398654988
    0.58962131923639
    0.592603474275806
    0.595590908828565
    0.598583668378363
    0.601581798843501
    0.604585346583237
    0.607594358404251
    0.61060888156722
    0.61362896379351
    0.616654653271996
    0.619685998665991
    0.622723049120314
    0.625765854268473
    0.628814464239987
    0.63186892966784
    0.634929301696065
    0.637995631987479
    0.641067972731549
    0.644146376652413
    0.647230897017041
    0.650321587643559
    0.653418502909723
    0.656521697761549
    0.659631227722116
    0.662747148900528
    0.665869518001048
    0.668998392332415
    0.672133829817328
    0.67527588900212
    0.678424629066621
    0.681580109834208
    0.684742391782056
    0.687911536051589
    0.691087604459134
    0.694270659506794
    0.697460764393524
    0.700657983026445
    0.70386238003237
    0.707074020769574
    0.71029297133979
    0.713519298600464
    0.716753070177244
    0.719994354476738
    0.723243220699528
    0.726499738853455
    0.729763979767182
    0.733036015104032
    0.73631591737613
    0.739603759958828
    0.742899617105447
    0.746203563962326
    0.749515676584188
    0.752836031949848
    0.75616470797825
    0.75950178354485
    0.762847338498361
    0.766201453677858
    0.769564210930266
    0.77293569312822
    0.776315984188337
    0.77970516908988
    0.783103333893848
    0.786510565762491
    0.789926952979265
    0.793352584969242
    0.796787552319982
    0.800231946802882
    0.803685861395022
    0.807149390301506
    0.810622628978331
    0.814105674155782
    0.817598623862384
    0.821101577449406
    0.824614635615961
    0.828137900434687
    0.831671475378053
    0.835215465345296
    0.838769976690004
    0.842335117248368
    0.845910996368134
    0.849497724938252
    0.853095415419262
    0.856704181874433
    0.860324140001677
    0.863955407166258
    0.867598102434333
    0.871252346607333
    0.874918262257221
    0.878595973762652
    0.882285607346063
    0.885987291111723
    0.88970115508476
    0.893427331251229
    0.897165953599211
    0.900917158161006
    0.904681083056451
    0.908457868537385
    0.912247657033316
    0.916050593198315
    0.919866823959183
    0.923696498564941
    0.927539768637666
    0.931396788224743
    0.935267713852561
    0.93915270458171
    0.943051922063731
    0.946965530599464
    0.950893697199062
    0.954836591643717
    0.958794386549162
    0.962767257431005
    0.966755382771977
    0.970758944091136
    0.97477812601512
    0.978813116351504
    0.982864106164351
    0.986931289852029
    0.991014865227371
    0.995115033600283
    0.999231999862867
    1.00336597257717
    1.00751716406563
    1.01168579050441
    1.01587207201954
    1.0200762327862
    1.02429850113113
    1.02853910963827
    1.03279829525789
    1.03707629941914
    1.0413733681464
    1.04568975217935
    1.05002570709708
    1.05438149344627
    1.05875737687376
    1.06315362826348
    1.06757052387814
    1.07200834550571
    1.07646738061097
    1.08094792249234
    1.08545027044417
    1.08997472992474
    1.0945216127303
    1.09909123717521
    1.10368392827867
    1.1083000179582
    1.11293984523014
    1.11760375641764
    1.12229210536627
    1.12700525366775
    1.1317435708921
    1.13650743482863
    1.14129723173609
    1.14611335660259
    1.15095621341549
    1.15582621544201
    1.16072378552085
    1.16564935636544
    1.17060337087942
    1.17558628248485
    1.18059855546391
    1.18564066531454
    1.19071309912105
    1.19581635594011
    1.20095094720313
    1.20611739713578
    1.21131624319561
    1.2165480365286
    1.22181334244574
    1.22711274092072
    1.23244682710972
    1.23781621189474
    1.24322152245147
    1.2486634028433
    1.25414251464285
    1.2596595375825
    1.26521517023564
    1.27081013073041
    1.27644515749782
    1.28212101005616
    1.28783846983403
    1.29359834103413
    1.29940145154036
    1.30524865387087
    1.31114082617984
    1.31707887331116
    1.32306372790702
    1.32909635157526
    1.33517773611894
    1.34130890483236
    1.3474909138679
    1.35372485367826
    1.36001185053937
    1.36635306815929
    1.37274970937914
    1.37920301797242
    1.38571428054967
    1.39228482857606
    1.39891604050989
    1.40560934407114
    1.4123662186494
    1.4191881978619
    1.42607687227285
    1.43303389228667
    1.4400609712286
    1.44715988862754
    1.45433249371732
    1.46158070917414
    1.46890653510976
    1.47631205334164
    1.48379943196366
    1.49137093024321
    1.49902890387327
    1.50677581061069
    1.51461421633577
    1.52254680157137
    1.53057636850434
    1.53870584855661
    1.54693831055869
    1.55527696958423
    1.56372519651115
    1.57228652838263
    1.5809646796499
    1.58976355438896
    1.59868725959458
    1.60774011966837
    1.61692669223222
    1.62625178541637
    1.63572047679064
    1.64533813413102
    1.65511043824015
    1.66504340807147
    1.67514342844331
    1.68541728067125
    1.6958721764973
    1.70651579575289
    1.71735632826212
    1.72840252057389
    1.73966372820953
    1.75114997422944
    1.76287201506288
    1.77484141471404
    1.78707062866264
    1.79957309902681
    1.81236336286033
    1.82545717583174
    1.83887165399534
    1.85262543694045
    1.86673887632534
    1.8812342547096
    1.89613604074919
    1.9114711882875
    1.92726948876869
    1.94356398885586
    1.96039148835635
    1.97779313781454
    1.99581516082526
    2.01450973381435
    2.03393606655888
    2.05416174130811
    2.07526438887675
    2.09733380936838
    2.12047468772263
    2.14481011722988
    2.17048623927379
    2.19767845464965
    2.22659989524007
    2.25751322631763
    2.29074749435689
    2.3267228670994
    2.3659881908323
    2.40928031214796
    2.45762240440889
    2.51249701319257
    2.57617489950328
    2.65240725811553
    2.74810910322958
    2.87847701476614
    3.09052913792528
]

max_stars_repo_name: ParadaCarleton/Bombe

max_issues_repo_name: ParadaCarleton/Bombe

max_forks_repo_name: ParadaCarleton/Bombe


text:
# This file was generated by the Julia Swagger Code Generator
# Do not modify this file directly. Modify the swagger specification instead.

struct RateCardApi <: SwaggerApi
    client::Swagger.Client
end

"""

Enables you to query for the resource/meter metadata and related prices used in a given subscription by Offer ID, Currency, Locale and Region. The metadata associated with the billing meters, including but not limited to service names, types, resources, units of measure, and regions, is subject to change at any time and without notice. If you intend to use this billing data in an automated fashion, please use the billing meter GUID to uniquely identify each billable item. If the billing meter GUID is scheduled to change due to a new billing model, you will be notified in advance of the change.
Param: filter::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: ResourceRateCardInfo
"""
function _swaggerinternal_rateCardGet(_api::RateCardApi, filter::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", ResourceRateCardInfo, "/subscriptions/{subscriptionId}/providers/Microsoft.Commerce/RateCard", [])
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "\$filter", filter)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json", "text/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json", "text/json"] : [_mediaType])
    return _ctx
end

function rateCardGet(_api::RateCardApi, filter::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_rateCardGet(_api, filter, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function rateCardGet(_api::RateCardApi, response_stream::Channel, filter::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_rateCardGet(_api, filter, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

export rateCardGet