text:
# syntax: proto3
using ProtoBuf
import ProtoBuf.meta
import ProtoBuf.google.protobuf

mutable struct PdfSampleRaw_SampleId <: ProtoType
    customer_id::AbstractString
    batch_id::AbstractString
    timestamp::Float32
    uuid::AbstractString
    PdfSampleRaw_SampleId(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_SampleId

mutable struct PdfSampleRaw_BoundingBox <: ProtoType
    x::Float32
    y::Float32
    width::Float32
    height::Float32
    PdfSampleRaw_BoundingBox(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_BoundingBox

mutable struct PdfSampleRaw_MultiObj_MultiObjOcc_AttributesEntry <: ProtoType
    key::AbstractString
    value::AbstractString
    PdfSampleRaw_MultiObj_MultiObjOcc_AttributesEntry(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_MultiObj_MultiObjOcc_AttributesEntry (mapentry)

mutable struct PdfSampleRaw_MultiObj_MultiObjOcc <: ProtoType
    gen_id::UInt32
    byte_position::UInt64
    attributes::Base.Dict{AbstractString,AbstractString} # map entry
    PdfSampleRaw_MultiObj_MultiObjOcc(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_MultiObj_MultiObjOcc

mutable struct PdfSampleRaw_MultiObj <: ProtoType
    obj_id::UInt32
    occurrences::Base.Vector{PdfSampleRaw_MultiObj_MultiObjOcc}
    occ_differs::Bool
    PdfSampleRaw_MultiObj(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_MultiObj

mutable struct PdfSampleRaw_Page_Overlap <: ProtoType
    page::UInt32
    hidden_text::AbstractString
    bbox::PdfSampleRaw_BoundingBox
    replacement_text::AbstractString
    PdfSampleRaw_Page_Overlap(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_Page_Overlap

mutable struct PdfSampleRaw_Page_TextAppend_WordBoundingBox <: ProtoType
    word::AbstractString
    bbox::PdfSampleRaw_BoundingBox
    PdfSampleRaw_Page_TextAppend_WordBoundingBox(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_Page_TextAppend_WordBoundingBox

mutable struct PdfSampleRaw_Page_TextAppend <: ProtoType
    page::UInt32
    sentence::AbstractString
    seq_dist::UInt32
    distance_from_bottom::Float32
    blue_words::Base.Vector{PdfSampleRaw_Page_TextAppend_WordBoundingBox}
    red_words::Base.Vector{PdfSampleRaw_Page_TextAppend_WordBoundingBox}
    PdfSampleRaw_Page_TextAppend(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_Page_TextAppend

mutable struct PdfSampleRaw_Page_Image <: ProtoType
    page::UInt32
    seq_id::UInt32
    bbox::PdfSampleRaw_BoundingBox
    name::AbstractString
    src_width::UInt32
    src_height::UInt32
    image_mask::ProtoBuf.google.protobuf.BoolValue
    bits::UInt32
    color_space::Base.Vector{AbstractString}
    matrix::Base.Vector{Float32}
    stream_length::Int64
    stream_obj_id::UInt32
    PdfSampleRaw_Page_Image(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_Page_Image
const __pack_PdfSampleRaw_Page_Image = Symbol[:matrix]
const __wtype_PdfSampleRaw_Page_Image = Dict(:stream_length => :sint64)
meta(t::Type{PdfSampleRaw_Page_Image}) = meta(t, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, true, __pack_PdfSampleRaw_Page_Image, __wtype_PdfSampleRaw_Page_Image, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES, ProtoBuf.DEF_FIELD_TYPES)

struct __enum_PdfSampleRaw_Page_Curve_CurveType <: ProtoEnum
    CURVE::Int32
    LINE::Int32
    RECTANGLE::Int32
    __enum_PdfSampleRaw_Page_Curve_CurveType() = new(0,1,2)
end #struct __enum_PdfSampleRaw_Page_Curve_CurveType
const PdfSampleRaw_Page_Curve_CurveType = __enum_PdfSampleRaw_Page_Curve_CurveType()

mutable struct PdfSampleRaw_Page_Curve_Point <: ProtoType
    x::Float32
    y::Float32
    PdfSampleRaw_Page_Curve_Point(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_Page_Curve_Point

struct __enum_PdfSampleRaw_Page_Curve_Color_ColorType <: ProtoEnum
    FLOAT::Int32
    STRING::Int32
    __enum_PdfSampleRaw_Page_Curve_Color_ColorType() = new(0,1)
end #struct __enum_PdfSampleRaw_Page_Curve_Color_ColorType
const PdfSampleRaw_Page_Curve_Color_ColorType = __enum_PdfSampleRaw_Page_Curve_Color_ColorType()

mutable struct PdfSampleRaw_Page_Curve_Color <: ProtoType
    _type::Int32
    value::AbstractString
    PdfSampleRaw_Page_Curve_Color(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_Page_Curve_Color

mutable struct PdfSampleRaw_Page_Curve <: ProtoType
    page::UInt32
    seq_id::UInt32
    bbox::PdfSampleRaw_BoundingBox
    curve_type::Int32
    even_odd::Bool
    fill::Bool
    line_width::Float32
    stroke::Bool
    non_stroking_color::Base.Vector{PdfSampleRaw_Page_Curve_Color}
    stroking_color::Base.Vector{PdfSampleRaw_Page_Curve_Color}
    points::Base.Vector{PdfSampleRaw_Page_Curve_Point}
    PdfSampleRaw_Page_Curve(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_Page_Curve

mutable struct PdfSampleRaw_Page_Char <: ProtoType
    page::UInt32
    seq_id::UInt32
    bbox::PdfSampleRaw_BoundingBox
    char::AbstractString
    adv::Float32
    matrix::Base.Vector{Float32}
    PdfSampleRaw_Page_Char(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_Page_Char
const __pack_PdfSampleRaw_Page_Char = Symbol[:matrix]
meta(t::Type{PdfSampleRaw_Page_Char}) = meta(t, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, true, __pack_PdfSampleRaw_Page_Char, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES, ProtoBuf.DEF_FIELD_TYPES)

mutable struct PdfSampleRaw_Page_Text <: ProtoType
    page::UInt32
    seq_id::UInt32
    bbox::PdfSampleRaw_BoundingBox
    text::AbstractString
    font_name::AbstractString
    render_style::UInt32
    upright::Bool
    cs_name::ProtoBuf.google.protobuf.StringValue
    cs_components::ProtoBuf.google.protobuf.UInt32Value
    chars::Base.Vector{PdfSampleRaw_Page_Char}
    PdfSampleRaw_Page_Text(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_Page_Text

struct __enum_PdfSampleRaw_Page_MarkedContent_Type <: ProtoEnum
    POINT::Int32
    SEQUENCE::Int32
    __enum_PdfSampleRaw_Page_MarkedContent_Type() = new(0,1)
end #struct __enum_PdfSampleRaw_Page_MarkedContent_Type
const PdfSampleRaw_Page_MarkedContent_Type = __enum_PdfSampleRaw_Page_MarkedContent_Type()

mutable struct PdfSampleRaw_Page_MarkedContent_PropertiesEntry <: ProtoType
    key::AbstractString
    value::AbstractString
    PdfSampleRaw_Page_MarkedContent_PropertiesEntry(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_Page_MarkedContent_PropertiesEntry (mapentry)

mutable struct PdfSampleRaw_Page_MarkedContent <: ProtoType
    page::UInt32
    seq_id::UInt32
    bbox::PdfSampleRaw_BoundingBox
    name::AbstractString
    _type::Int32
    properties::Base.Dict{AbstractString,AbstractString} # map entry
    tagged_text::Base.Vector{PdfSampleRaw_Page_Text}
    PdfSampleRaw_Page_MarkedContent(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_Page_MarkedContent

mutable struct PdfSampleRaw_Page_Annotation <: ProtoType
    page::UInt32
    seq_id::UInt32
    bbox::PdfSampleRaw_BoundingBox
    subtype::ProtoBuf.google.protobuf.StringValue
    text::ProtoBuf.google.protobuf.StringValue
    PdfSampleRaw_Page_Annotation(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_Page_Annotation

mutable struct PdfSampleRaw_Page_VatNumber <: ProtoType
    page::UInt32
    text::AbstractString
    bbox::PdfSampleRaw_BoundingBox
    validated::Bool
    PdfSampleRaw_Page_VatNumber(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_Page_VatNumber

mutable struct PdfSampleRaw_Page_VisualRepresentation <: ProtoType
    letter_representation::Base.Vector{Float32}
    PdfSampleRaw_Page_VisualRepresentation(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_Page_VisualRepresentation
const __pack_PdfSampleRaw_Page_VisualRepresentation = Symbol[:letter_representation]
meta(t::Type{PdfSampleRaw_Page_VisualRepresentation}) = meta(t, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, true, __pack_PdfSampleRaw_Page_VisualRepresentation, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES, ProtoBuf.DEF_FIELD_TYPES)

struct __enum_PdfSampleRaw_Page_AccountNumber_AccountType <: ProtoEnum
    IBAN::Int32
    CZECH_NATIONAL::Int32
    __enum_PdfSampleRaw_Page_AccountNumber_AccountType() = new(0,1)
end #struct __enum_PdfSampleRaw_Page_AccountNumber_AccountType
const PdfSampleRaw_Page_AccountNumber_AccountType = __enum_PdfSampleRaw_Page_AccountNumber_AccountType()

mutable struct PdfSampleRaw_Page_AccountNumber <: ProtoType
    page::UInt32
    text::AbstractString
    bbox::PdfSampleRaw_BoundingBox
    validated::Bool
    _type::Int32
    PdfSampleRaw_Page_AccountNumber(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_Page_AccountNumber

mutable struct PdfSampleRaw_Page_CharHistEntry <: ProtoType
    key::AbstractString
    value::UInt32
    PdfSampleRaw_Page_CharHistEntry(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_Page_CharHistEntry (mapentry)

mutable struct PdfSampleRaw_Page <: ProtoType
    page_id::UInt32
    obj_id::UInt32
    layout_bbox::PdfSampleRaw_BoundingBox
    is_scanned::Bool
    is_scanned_with_ocr::Bool
    annotations::Base.Vector{PdfSampleRaw_Page_Annotation}
    images::Base.Vector{PdfSampleRaw_Page_Image}
    curves::Base.Vector{PdfSampleRaw_Page_Curve}
    lines::Base.Vector{PdfSampleRaw_Page_Curve}
    rectangles::Base.Vector{PdfSampleRaw_Page_Curve}
    texts::Base.Vector{PdfSampleRaw_Page_Text}
    marked_contents::Base.Vector{PdfSampleRaw_Page_MarkedContent}
    word_appends::Base.Vector{PdfSampleRaw_Page_TextAppend}
    word_overlaps::Base.Vector{PdfSampleRaw_Page_Overlap}
    char_hist::Base.Dict{AbstractString,UInt32} # map entry
    vat_numbers::Base.Vector{PdfSampleRaw_Page_VatNumber}
    visual_representation::PdfSampleRaw_Page_VisualRepresentation
    account_numbers::Base.Vector{PdfSampleRaw_Page_AccountNumber}
    visual_class::ProtoBuf.google.protobuf.StringValue
    attribution_key::ProtoBuf.google.protobuf.StringValue
    recognized_account_number::PdfSampleRaw_Page_AccountNumber
    PdfSampleRaw_Page(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_Page

mutable struct PdfSampleRaw_StreamOperations_StreamOperation_StreamOperand <: ProtoType
    _type::AbstractString
    value::AbstractString
    PdfSampleRaw_StreamOperations_StreamOperation_StreamOperand(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_StreamOperations_StreamOperation_StreamOperand

mutable struct PdfSampleRaw_StreamOperations_StreamOperation <: ProtoType
    operator::AbstractString
    operands::Base.Vector{PdfSampleRaw_StreamOperations_StreamOperation_StreamOperand}
    PdfSampleRaw_StreamOperations_StreamOperation(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_StreamOperations_StreamOperation

mutable struct PdfSampleRaw_StreamOperations <: ProtoType
    obj_id::UInt32
    operations::Base.Vector{PdfSampleRaw_StreamOperations_StreamOperation}
    PdfSampleRaw_StreamOperations(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_StreamOperations

mutable struct PdfSampleRaw_StreamWhitespaces <: ProtoType
    obj_id::UInt32
    whitespaces::Base.Vector{AbstractString}
    PdfSampleRaw_StreamWhitespaces(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_StreamWhitespaces

mutable struct PdfSampleRaw_ObjPos <: ProtoType
    byte_pos::UInt32
    obj_id::UInt32
    gen_no::UInt32
    PdfSampleRaw_ObjPos(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_ObjPos

mutable struct PdfSampleRaw_PdfCatalog_Xrefs_Xref <: ProtoType
    obj_id::UInt32
    gen::UInt32
    pos::UInt32
    stream_id::ProtoBuf.google.protobuf.UInt32Value
    PdfSampleRaw_PdfCatalog_Xrefs_Xref(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_PdfCatalog_Xrefs_Xref

mutable struct PdfSampleRaw_PdfCatalog_Xrefs <: ProtoType
    pdf_miner_type::AbstractString
    xrefs::Base.Vector{PdfSampleRaw_PdfCatalog_Xrefs_Xref}
    json_trailer::AbstractString
    PdfSampleRaw_PdfCatalog_Xrefs(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_PdfCatalog_Xrefs

mutable struct PdfSampleRaw_PdfCatalog_JsonCatalogEntry <: ProtoType
    key::UInt32
    value::AbstractString
    PdfSampleRaw_PdfCatalog_JsonCatalogEntry(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_PdfCatalog_JsonCatalogEntry (mapentry)

mutable struct PdfSampleRaw_PdfCatalog <: ProtoType
    json_catalog::Base.Dict{UInt32,AbstractString} # map entry
    xrefs::Base.Vector{PdfSampleRaw_PdfCatalog_Xrefs}
    PdfSampleRaw_PdfCatalog(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_PdfCatalog

mutable struct PdfSampleRaw_SignedBytesDigestsEntry <: ProtoType
    key::AbstractString
    value::Array{UInt8,1}
    PdfSampleRaw_SignedBytesDigestsEntry(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw_SignedBytesDigestsEntry (mapentry)

mutable struct PdfSampleRaw <: ProtoType
    sample_id::PdfSampleRaw_SampleId
    sha256::AbstractString
    file_length::UInt64
    is_edi::Bool
    is_generated_with_preview::Bool
    is_generated_with_preview_print_to_pdf::Bool
    pdf_comment_lines::Base.Vector{Array{UInt8,1}}
    pages::Base.Vector{PdfSampleRaw_Page}
    stream_operations::Base.Vector{PdfSampleRaw_StreamOperations}
    stream_whitespaces::Base.Vector{PdfSampleRaw_StreamWhitespaces}
    obj_positions::Base.Vector{PdfSampleRaw_ObjPos}
    multi_objs::Base.Vector{PdfSampleRaw_MultiObj}
    pdf_catalog::PdfSampleRaw_PdfCatalog
    signed_bytes_digests::Base.Dict{AbstractString,Array{UInt8,1}} # map entry
    PdfSampleRaw(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct PdfSampleRaw

export PdfSampleRaw_SampleId, PdfSampleRaw_BoundingBox, PdfSampleRaw_MultiObj_MultiObjOcc_AttributesEntry, PdfSampleRaw_MultiObj_MultiObjOcc, PdfSampleRaw_MultiObj, PdfSampleRaw_Page_Overlap, PdfSampleRaw_Page_TextAppend_WordBoundingBox, PdfSampleRaw_Page_TextAppend, PdfSampleRaw_Page_Image, PdfSampleRaw_Page_Curve_CurveType, PdfSampleRaw_Page_Curve_Point, PdfSampleRaw_Page_Curve_Color_ColorType, PdfSampleRaw_Page_Curve_Color, PdfSampleRaw_Page_Curve, PdfSampleRaw_Page_Char, PdfSampleRaw_Page_Text, PdfSampleRaw_Page_MarkedContent_Type, PdfSampleRaw_Page_MarkedContent_PropertiesEntry, PdfSampleRaw_Page_MarkedContent, PdfSampleRaw_Page_Annotation, PdfSampleRaw_Page_VatNumber, PdfSampleRaw_Page_VisualRepresentation, PdfSampleRaw_Page_AccountNumber_AccountType, PdfSampleRaw_Page_AccountNumber, PdfSampleRaw_Page_CharHistEntry, PdfSampleRaw_Page, PdfSampleRaw_StreamOperations_StreamOperation_StreamOperand, PdfSampleRaw_StreamOperations_StreamOperation, PdfSampleRaw_StreamOperations, PdfSampleRaw_StreamWhitespaces, PdfSampleRaw_ObjPos, PdfSampleRaw_PdfCatalog_Xrefs_Xref, PdfSampleRaw_PdfCatalog_Xrefs, PdfSampleRaw_PdfCatalog_JsonCatalogEntry, PdfSampleRaw_PdfCatalog, PdfSampleRaw_SignedBytesDigestsEntry, PdfSampleRaw
# mapentries: "PdfSampleRaw_Page_CharHistEntry" => ("AbstractString", "UInt32"), "PdfSampleRaw_Page_MarkedContent_PropertiesEntry" => ("AbstractString", "AbstractString"), "PdfSampleRaw_PdfCatalog_JsonCatalogEntry" => ("UInt32", "AbstractString"), "PdfSampleRaw_SignedBytesDigestsEntry" => ("AbstractString", "Array{UInt8,1}"), "PdfSampleRaw_MultiObj_MultiObjOcc_AttributesEntry" => ("AbstractString", "AbstractString")


text:
# ```@meta
# CurrentModule = PowerSystems
# ```

# # Network Matrices

# Use these matrices wisely

# ```@autodocs
# Modules = [PowerSystems]
# Pages   = ["utils/network_calculations/ybus_calculations.jl",
#            "utils/network_calculations/ptdf_calculations.jl",
#            "utils/network_calculations/lodf_calculations.jl"]
# ```

ext: jl


text:
vars = Array{Any,1}()
vals = Array{Any,1}()

c = 0

for line in eachline(STDIN)
	if ismatch(r"======", line)
		if length(vars) > 0
			if c == 0
				println(STDOUT, "| " * join(vars, " | ") * " |")
				println(STDOUT, "|" * repeat("--|", length(vars)))
				c += 1
			end

			println(STDOUT, "| " * join(vals, " | ") * " |")

			empty!(vars)
			empty!(vals)
		end
	elseif ismatch(r"hostname|jobnumber|jobname|ru_wallclock|maxvmem|taskid", chomp(line))
		m = match(r"([^ ]+) +([^ ]+)", chomp(line)).captures
		push!(vars, m[1])
		push!(vals, m[2])
	end
end

if length(vars) > 0
	if c == 0
				println(STDOUT, "| " * join(vars, " | ") * " |")
				println(STDOUT, "|" * repeat("--|", length(vars)))
				c += 1
	end

	println(STDOUT, "| " * join(vals, " | ") * " |")

	empty!(vars)
	empty!(vals)
end

max_stars_repo_name: yuifu/qacctTable

max_issues_repo_name: yuifu/qacctTable

max_forks_repo_name: yuifu/qacctTable


text:
module Bincounts

using DocStringExtensions
using Distributions

"""
$(TYPEDSIGNATURES)

Similar to numpy.bincount:
(https://docs.scipy.org/doc/numpy/reference/generated/numpy.bincount.html)

Count the weighted occurrences of each integer from one to the maximum integer in obs.
obs cannot contain integers below 1.

Specifying a minlength will guarantee at least this length of output - equivalent to
creating counts for integers above the maximum integer in obs.
Each location of the output gives the count of occurrences of its index value in obs,
i.e. it represents a number line starting from one.

Counts of occurences in obs are weighted by weights, therefore obs and weights must be the
same length. A weights consisting entirely of 1.0 is equivalent to calling without weights.
"""
function bincount(
    obs::Vector{Int}, weights::Vector{Float64}, minlength::Int
)::Vector{Float64}

    if isempty(obs)
        return ones(minlength)
    end

    if minimum(obs) < 1
        throw(DomainError("obs must be greater than 0"))
    end

    if length(obs) != length(weights)
        throw(DimensionMismatch(string(
            "The number of observations: ", length(obs),
            " is not equal to the number of weights: ", length(weights)
        )))
    end

    return Distributions.fit(
        Distributions.Histogram, obs, Distributions.Weights(weights),
        1:max(minlength + 1, maximum(obs) + 1)
    ).weights
end
bincount(obs::Vector{Int}, minlength::Int)::Vector{Float64} = bincount(obs, ones(size(obs)), minlength)

end # module Bincounts


text:
export Vec2, Vec3, rmfile, read_shd, getCenterFreq

"""
    Vec2
This is the central type for BellHop2D. All of the other types are defined building
upon this.
All the fields of the Ve2 instance contains `Array`s.
### Fields:
* `x`
* `z`
The types of `x` and `z` must match. Also, if scalar input is given to the
constructor it will be cnverted into a 1-element Vector.
"""
struct Vec2{T<:AbstractArray}
    x::T
    z::T
    function Vec2(x::T, z::T) where {T<:AbstractArray}
        @assert size(x) == size(z)
        new{T}(x, z)
    end
end

Vec2(a::T) where {T<:Real} = Vec3([a], [a])

Vec2(a::T) where {T<:AbstractArray} = Vec2(copy(a), copy(a))

Vec2(a::T, b::T) where {T<:Real} = Vec2([a], [b])

#Vec2(1.01f0,2.0f0)

# -------- #
# Vector 3 #
# -------- #

"""
    Vec3
This is the central type for Bellhop3D. All of the other types are defined building
upon this.
All the fields of the Vec3 instance contains `Array`s. This ensures that we can collect
the gradients w.r.t the fields using the `Params` API of Zygote.
### Fields:
* `x`
* `y`
* `z`
The types of `x`, `y`, and `z` must match. Also, if scalar input is given to the
constructor it will be cnverted into a 1-element Vector.
"""
struct Vec3{T<:AbstractArray}
    x::T
    y::T
    z::T
    function Vec3(x::T, y::T, z::T) where {T<:AbstractArray}
        @assert size(x) == size(y) == size(z)
        new{T}(x, y, z)
    end
    function Vec3(x::T1, y::T2, z::T3) where {T1<:AbstractArray, T2<:AbstractArray, T3<:AbstractArray}
        # Yes, I know it is a terrible hack but Zygote.FillArray was pissing me off.
        T = eltype(x) <: Real ? eltype(x) : eltype(y) <: Real ? eltype(y) : eltype(z)
        @warn "Converting the type to $(T) by default" maxlog=1
        @assert size(x) == size(y) == size(z)
        new{AbstractArray{T, ndims(x)}}(T.(x), T.(y), T.(z))
    end
end

Vec3(a::T) where {T<:Real} = Vec3([a], [a], [a])

Vec3(a::T) where {T<:AbstractArray} = Vec3(copy(a), copy(a), copy(a))

Vec3(a::T, b::T, c::T) where {T<:Real} = Vec3([a], [b], [c])

# -------- #
# rmfile #
# -------- #
function rmfile(filename::String)
    f1 = "$filename.brc"
    f2 = "$filename.bty"
    f3 = "$filename.env"
    f4 = "$filename.trc"
    f5 = "$filename.prt"

    rm(f1, force=true)
    rm(f2, force=true)
    rm(f3, force=true)
    rm(f4, force=true)
    rm(f5, force=true)

end

# -------- #
# read_shd file #
# -------- #
function read_shd(filename::String)
    recl = Array{Int32}(undef, 1, 1)

         #read!(filename, recl)

        io = open(filename,"r")

        #open(filename) do file
        recl = read(io, Int32)

        for i=1:80
                read(io, Char)
        end

        #end

        seekstart(io)
        seek(io, 4*recl)

        for i=1:10
                read(io, Char)
        end

        seekstart(io)
        seek(io, 2*4*recl) # end of 2nd record

        Nfreq = read(io, Int32)
        Ntheta = read(io, Int32)

        Nsx = read(io, Int32)
        Nsy = read(io, Int32)
        Nsz = read(io, Int32)

        Nrz = read(io, Int32)
        Nrr = read(io, Int32)
        freq0 = read(io, Float32)
        atten = read(io, Float32)

        seekstart(io)
        seek(io, 3*4*recl) # end of 3rd record

        freqVec = read(io, Float64)

        seekstart(io)
        seek(io, 4*4*recl) # end of 4th record

        Pos_theta = read(io, Float64)

        seekstart(io)
        seek(io, 5*4*recl) # end of 5th record

        Pos_s_x = read(io, Float32)

        seekstart(io)
        seek(io, 6*4*recl) # end of 6th record

        Pos_s_y = read(io, Float32)

        seekstart(io)
        seek(io, 7*4*recl) # end of 7th record

        Pos_s_z = read(io, Float32)

        seekstart(io)
        seek(io, 8*4*recl) # end of 8th record

        Pos_r_z = Array{Float32}(undef, Nrz, 1)
        read!(io, Pos_r_z)

        seekstart(io)
        seek(io, 9*4*recl) # end of 9th record

        Pos_r_r = Array{Float32}(undef, Nrr, 1)
        read!(io, Pos_r_r)

        pressure = Array{Complex{Float32}}(undef,Nrz,Nrr)
        count = 10

        function read_pressure!(pressure,count)
                for ii = 1:Nrz
                        seekstart(io)
                        seek(io, count*4*recl) # end of 10th record

                        temp = Array{Float32}(undef, 2*Nrr, 1)
                        read!(io, temp)

                        temp = temp .+ 1f-6

                        real_temp = temp[1:2:2*Nrr]
                        im_temp = temp[2:2:2*Nrr]
                        complex_temp = real_temp .+ 1im*im_temp

                        pressure[ii,:] = complex_temp
                        count +=1
                end
        end

        read_pressure!(pressure,count)
        position(io)
        close(io) # Done read shd file

        return pressure, Pos_r_r, Pos_r_z
end

function getCenterFreq(Bandwidth::String)

        Bandwidth = "1/3 octave"

        fcentre = 10 .^(0.1.*(1:43))
        fd = 10^0.05
        fupper = fcentre * fd
        flower = fcentre / fd
end

# ANSI S1.11-2004
# Ref. https://law.resource.org/pub/us/cfr/ibr/002/ansi.s1.11.2004.pdf

function getCenterFreq(;bandwidth::Int64=1, lim=(3.0,22_000.0))

        fr = 1000.
        G10 = 10^(3/10) # Conversion constant based 10
        x = -10:1:50 # band number

        if isodd(bandwidth)
                fm = ( G10 .^( (x .- 30) ./bandwidth ) )*(fr)
        elseif iseven(bandwidth)
                fm = ( G10 .^( (2*x .- 59) ./(2*bandwidth) ) )*(fr)
        else
                @warn "Fraction of an octave band should be a Int number"
        end

        idx = findall(x-> (x>=lim[1]) & (x<=lim[2]), fm)

        return fm[idx]

end


text:
############################################################
# Multinomial Logistic Loss
############################################################
@defstruct MultinomialLogisticLossLayer Layer (
  name :: AbstractString = "multinomial-logistic-loss",
  weights :: Array = [],
  (weight :: AbstractFloat = 1.0, weight >= 0),
  (dim :: Int = -2, dim != 0),
  (normalize:: Symbol = :local, in(normalize,[:local,:global,:no])),
  (bottoms :: Vector{Symbol} = Symbol[], length(bottoms) == 2),
)
@characterize_layer(MultinomialLogisticLossLayer,
  has_loss => true,
  is_sink  => true,
)

type MultinomialLogisticLossLayerState{T} <: LayerState
  layer :: MultinomialLogisticLossLayer
  loss  :: T

  op_dim       :: Int
  weights_blob :: Blob
end

function setup(backend::Backend, layer::MultinomialLogisticLossLayer, inputs::Vector{Blob}, diffs::Vector{Blob})
  data_type = eltype(inputs[1])
  tensor_dim = ndims(inputs[1])
  dims = size(inputs[1])

  op_dim = layer.dim
  if op_dim < 0
    op_dim += tensor_dim + 1
  end
  @assert 1 <= op_dim <= tensor_dim
  @assert op_dim != tensor_dim # the last dimension is the mini-batch dimension

  # weights for each class
  if isempty(layer.weights)
    weights_blob = NullBlob()
  else
    weights = layer.weights

    if ndims(weights) == 1
      if length(weights) != dims[op_dim]
        error("Invalid weights: size should be equal to number of classes")
      end
      new_shape = ones(Int, tensor_dim-1); new_shape[op_dim] = dims[op_dim]
      rep_shape = [dims[1:end-1]...]; rep_shape[op_dim] = 1
      weights = repeat(reshape(weights, new_shape...), inner=rep_shape)
    end

    if ndims(weights) == tensor_dim-1
      @assert size(weights) == dims[1:end-1]
      new_shape = [size(weights)..., 1]
      rep_shape = [ones(Int, length(dims)-1)..., dims[end]]
      weights = repeat(reshape(weights, new_shape...), inner=rep_shape)
    end

    @assert size(weights) == dims
    weights = convert(Array{data_type}, weights)

    if layer.normalize == :local
      weights = weights .* (dims[op_dim] ./ sum(weights, op_dim))
    elseif layer.normalize == :global
      for i = 1:dims[end]
        idx = map(x -> 1:x, dims[1:end-1])
        weights[idx..., i] = weights[idx..., i] * (prod(dims[1:end-1]) / sum(weights[idx..., i]))
      end
    else
      @assert layer.normalize == :no
    end

    weights_blob = make_blob(backend, weights)
  end

  state = MultinomialLogisticLossLayerState(layer, convert(data_type, 0), op_dim, weights_blob)
  return state
end
function shutdown(backend::Backend, state::MultinomialLogisticLossLayerState)
end

function forward(backend::CPUBackend, state::MultinomialLogisticLossLayerState, inputs::Vector{Blob})
  pred = inputs[1].data
  label = inputs[2].data

  dims = size(pred)
  label_dim = [i == state.op_dim ? 1 : dims[i] for i = 1:length(dims)]
  label = reshape(label, label_dim...)

  # make sure that the labels are in [0..(n_class-1)]
  n_class = size(pred, state.op_dim)
  @assert all(0 .<= label .< n_class) "labels should be index in [0, n_class-1]"

  idx_all = map(1:length(dims)) do i
    if i == state.op_dim
      map(x -> round(Int, x), label) .+ 1
    else
      dim = dims[i]
      reshape(1:dim, [j == i? dim : 1 for j = 1:length(dims)]...)
    end
  end

  if isa(state.weights_blob, NullBlob)
    loss = sum(-log.(max.(broadcast_getindex(pred, idx_all...), 1e-20)))
  else
    loss = sum(-log.(max.(broadcast_getindex(pred, idx_all...), 1e-20)) .*
        broadcast_getindex(state.weights_blob.data, idx_all...))
  end
  state.loss = state.layer.weight * loss / (prod(dims) / dims[state.op_dim])
end

function backward(backend::Backend, state::MultinomialLogisticLossLayerState, inputs::Vector{Blob}, diffs::Vector{Blob})
end


text:
#=
Serial direct estimation of the probability for the Schlögl chemical reaction network
with X(0)= x₀ to reach X(T) ∈ A, the target set.

This reaction network corresponds to:
A + 2S → 3S
3S → A + 2S
B → S
S → B

Parameters were chosen so that the system is bistable, as in:
https://doi.org/10.1063/1.5017955
=#

using Statistics
using HypothesisTests
using Printf

include("schlogl_setup.jl");

Random.seed!(100);
n_trials = 10^6;
n_in_set = 0;
for j in 1:n_trials
    X₀ = copy(x₀);
    global n_in_set+= f(integrate_schlogl(X₀, Tmax));
end
CI = confint(BinomialTest(n_in_set, n_trials));
@printf("P Estimate = %g\n",n_in_set/n_trials);
@printf("95%% CI = (%g,%g)\n", CI[1], CI[2]);


text:
using Photometry.Aperture: circular_overlap,
                           circular_overlap_core,
                           circular_overlap_single_exact,
                           circular_overlap_single_subpixel,
                           area_arc,
                           area_triangle,
                           inside_ellipse,
                           inside_triangle,
                           inside_rectangle,
                           circle_line,
                           circle_segment,
                           circle_segment_single2,
                           triangle_unitcircle_overlap,
                           elliptical_overlap,
                           elliptical_overlap_exact,
                           elliptical_overlap_single_subpixel,
                           rectangular_overlap,
                           rectangular_overlap_exact,
                           rectangular_overlap_single_subpixel

@testset "overlap - circular" begin

    @testset "circular overlap" for grid_size in [50, 500, 1000], circ_size in (0.2, 0.4, 0.8), method in [:exact, :center, (:subpixel, 2), (:subpixel, 5), (:subpixel, 10)]

        g = circular_overlap(-1, -1, 1, 1, grid_size, grid_size, circ_size, method = method)
        any(g .> 0) &&  @test maximum(g) ≈ 1.0
        any(g .< 1) &&  @test minimum(g) ≈ 0.0
    end

    @testset "overlap core (r = $r)" for r in 1:10
        @test circular_overlap_core(0, 0, 0, 0, r) ≈ 0
        @test circular_overlap_single_exact(0, 0, r, r, r) ≈ r^2 * π / 4
        @test circular_overlap_core(0, 0, r, r, r) ≈ r^2 * π / 4
    end

    @testset "overlap single exact" begin
        @test circular_overlap_single_exact(0, 0, 0, 0, 1) ≈ 0
        @test circular_overlap_single_exact(0, 0, 20, 20, 15) ≈ 176.714586764429
    end

    @testset "overlap subpixel" begin
        @test circular_overlap_single_subpixel(0, 0, 0, 0, 1, 1) ≈ 1

        @test circular_overlap_single_subpixel(0, 0, 20, 20, 15, 2) ≈ 0.25
        @test circular_overlap_single_subpixel(0, 0, 20, 20, 15, 5) ≈ 0.44
        @test circular_overlap_single_subpixel(0, 0, 20, 20, 15, 10) ≈ 0.43
        @test circular_overlap_single_subpixel(0, 0, 20, 20, 15, 100) ≈ 0.4423
    end

    @testset "overlap grid" begin
        @test circular_overlap(0, 0, 0, 0, 1, 1, 1) == ones(1, 1)

        @test circular_overlap(0, 20, 0, 20, 5, 5, 15) ≈ [1 1 1 0.70506901 0;
    1 1 1 0.42240835 0;
    1 1 0.74542733 0.02213982 0;
    0.70506901 0.42240835 0.02213982 0 0;
    0 0 0 0 0]

        @test circular_overlap(-10, 10, -10, 10, 5, 5, 4) ≈ [0 0         0        0        0;
    0 0.07878669 0.45661148 0.07878669 0;
    0 0.45661148 1         0.45661148 0;
    0 0.07878669 0.45661148 0.07878669 0;
    0 0         0         0        0]

    end

    @testset "type stability" begin
        for grid_size in [50, 500, 1000], circ_size in (0.2, 0.4, 0.8), method in [:exact, :center, (:subpixel, 2), (:subpixel, 5), (:subpixel, 10)]
            @inferred circular_overlap(-1, -1, 1, 1, grid_size, grid_size, circ_size, method = method)
        end
        r = 5
        @inferred circular_overlap_core(0, 0, r, r, r)
        @inferred circular_overlap_single_exact(0, 0, r, r, r)
        @inferred circular_overlap_single_subpixel(0, 0, 20, 20, 15, 5)
    end

end # circles

@testset "overlap - elliptical" begin

    @testset "elliptical overlap" for grid_size in [50, 500, 1000], ellipse_size in ([0.2,0.2,0], [0.4, 0.4, 0], [0.8, 0.8, 0]), method in [:center, (:subpixel, 2), (:subpixel, 5), (:subpixel, 10)]

        g = elliptical_overlap(-1, -1, 1, 1, grid_size, grid_size, ellipse_size, method = method)
        any(g .> 0) &&  @test maximum(g) ≈ 1.0
        any(g .< 1) &&  @test minimum(g) ≈ 0.0
    end

    @testset "overlap subpixel (elliptical apperture)" begin
        @test elliptical_overlap_single_subpixel(0, 0, 0, 0, 1, 1, 0, 1) ≈ 1

        @test elliptical_overlap_single_subpixel(0, 0, 20, 20, 1 / 225, 1 / 225, 0, 2) ≈ 0.25
        @test elliptical_overlap_single_subpixel(0, 0, 20, 20, 1 / 225, 1 / 225, 0, 5) ≈ 0.44
        @test elliptical_overlap_single_subpixel(0, 0, 20, 20, 1 / 225, 1 / 225, 0, 10) ≈ 0.43
        @test elliptical_overlap_single_subpixel(0, 0, 20, 20, 1 / 225, 1 / 225, 0, 100) ≈ 0.4423
    end

    @testset "circle line" for line in readlines(joinpath(@__DIR__, "..", "data", "circle_line.csv"))
        tokens = split(line, ',')
        numbers = parse.(Float64, tokens)
        x1, y1, x2, y2 = numbers[1:4]
        point1, point2 = circle_line(x1, y1, x2, y2)
        @test point1[1] ≈ numbers[5] atol = 1e-6
        @test point1[2] ≈ numbers[6] atol = 1e-6
        @test point2[1] ≈ numbers[7] atol = 1e-6
        @test point2[2] ≈ numbers[8] atol = 1e-6
    end

    @testset "circle segment" for line in readlines(joinpath(@__DIR__, "..", "data", "circle_segment.csv"))
        tokens = split(line, ',')
        numbers = parse.(Float64, tokens)
        x1, y1, x2, y2 = numbers[1:4]
        point1, point2 = circle_segment(x1, y1, x2, y2)
        @test point1[1] ≈ numbers[5] atol = 1e-6
        @test point1[2] ≈ numbers[6] atol = 1e-6
        @test point2[1] ≈ numbers[7] atol = 1e-6
        @test point2[2] ≈ numbers[8] atol = 1e-6
    end

    @testset "circle segment single" for line in readlines(joinpath(@__DIR__, "..", "data", "circle_segment_single.csv"))
        tokens = split(line, ',')
        numbers = parse.(Float64, tokens)
        x1, y1, x2, y2 = numbers[1:4]
        point1 = circle_segment_single2(x1, y1, x2, y2)
        @test point1[1] ≈ numbers[5] atol = 1e-6
        @test point1[2] ≈ numbers[6] atol = 1e-6
    end

    @testset "triangle unitcircle overlap" for line in readlines(joinpath(@__DIR__, "..", "data", "triangle_unitcircle_overlap.csv"))
        tokens = split(line, ',')
        numbers = parse.(Float64, tokens)
        x1, y1, x2, y2, x3, y3 = numbers[1:6]
        @test triangle_unitcircle_overlap(x1, y1, x2, y2, x3, y3) ≈ numbers[end] atol = 1e-6
    end

    @testset "elliptical overlap" begin
        @test elliptical_overlap_exact(0.5, 2.5, 1.5, 3.5, 3.0, 3.0, 0) ≈ 0.311725 atol = 1e-6
        @test elliptical_overlap_exact(0, 2, 1, 3, 3.0, 3.0, 0) ≈ 0.943480 atol = 1e-6
    end

    @testset "type stability" begin
        for grid_size in [50, 500, 1000], ellipse_size in ([0.2,0.2,0], [0.4, 0.4, 0], [0.8, 0.8, 0]), method in [:center, (:subpixel, 2), (:subpixel, 5), (:subpixel, 10)]
            @inferred elliptical_overlap(-1, -1, 1, 1, grid_size, grid_size, ellipse_size, method = method)
        end
    end
end # overlap elliptical

@testset "overlap - rectangular" begin
    @testset "exact" begin
        @test rectangular_overlap_exact(0, 0, 1, 1, 1, 1, 0) ≈ 0.25
    end

    @testset "type stability" begin
        for grid_size in [50, 500, 1000], w in (0.2, 0.4, 0.8), method in [:exact, :center, (:subpixel, 2), (:subpixel, 5), (:subpixel, 10)]
            method === :exact && continue  # TODO area in LazySets.jl not type stable
            @inferred rectangular_overlap(-1, -1, 1, 1, grid_size, grid_size, w, w, 0, method = method)
        end
        # @inferred rectangular_overlap_exact(0, 0, 1, 1, 2, 2, 0) # TODO area in LazySets.jl not type stable
        @inferred rectangular_overlap_single_subpixel(0, 0, 1, 1, 2, 2, 0, 5)
    end
end # overlap rectangular

@testset "overlap - utils" begin

    @testset "inside triangle" begin
        t1 = [0, 0, 0, 1, 1, 0]
        @test inside_triangle(0, 0, t1...)
        @test inside_triangle(0.1, 0.1, t1...)
        @test inside_triangle(0.25, 0.25, t1...)
    end

    @testset "area triangle" begin
        @test area_triangle(0, 0, 0, 0, 0, 0) ≈ 0
        @test area_triangle(0, 0, 1, 0, 0, 1) ≈ 0.5
        @test area_triangle(1, 1, 1, 4, 6, 1) ≈ 7.5

    end

    @testset "area arc (r = $r)" for r in 1:10
        @test area_arc(0, 0, 0, 0, r) ≈ 0
        @test area_arc(0, r, r, 0, r) ≈ r^2 / 2 * (π / 2 - 1)
    end

    @testset "inside ellipse" begin
        @test inside_ellipse(0, 0, 0, 0, 1, 1, 1)
        @test !inside_ellipse(10, 10, 5, 5, 1, 1, 1)
        @test !inside_ellipse(5, 3, 0, 0, 1 / 16, 1 / 32, 0)
        @test inside_ellipse(0, 0, 0, 0, 5, 6.2, 0)
        @test inside_ellipse(1, 2, 0, 0, 1 / 37, 1 / 36, -1 / 80)
    end

    @testset "inside rectangle" begin
        @test inside_rectangle(0, 0, 3, 4, 0)
        @test !inside_rectangle(10, 10, 3, 4, 0)
    end

    @testset "type stability" begin
        @inferred area_arc(0, 0, 0, 0, 10)
        @inferred area_triangle(0, 0, 1, 0, 0, 1)
        @inferred inside_triangle(0, 0, 0, 0, 0, 1, 1, 0)
        @inferred inside_ellipse(0, 0, 5, 5, 1, 1, 1)
        @inferred inside_rectangle(0, 0, 3, 4, 0)
    end

end # overlap utils


text:
using TensorOperations
import Base: ==, ≈
using LinearAlgebra

export QuantumRegister, FullStateQuantumRegister, to_str
export apply_1qubit_full, apply_1qubit, apply_1qubit!
export apply_2qubit_full, apply_2qubit, apply_2qubit!
export decompose_2_qubit_gate
export swap_2qubits, get_conf, measure, get_counts, measure_probs
export binary_repr, execute!

"Abstract type and parent of all quantum register types"
abstract type QuantumRegister end

"Implementation type for full state quantum register"
mutable struct FullStateQuantumRegister{T} <: QuantumRegister
    N::Integer
    state::Array{T, 1}
    FullStateQuantumRegister{T}(N) where T <: Number = new(NTuple, zeros(T, 2^N))
    FullStateQuantumRegister{T}(N, state) where T <: Number = new(N, state)
    function FullStateQuantumRegister{T}(N, conf::String) where T <: Number
        @assert length(conf) == N
        new(N, configuration2vector(conf))
    end
end

FullStateQuantumRegister(N) = FullStateQuantumRegister{ComplexF64}(N)
FullStateQuantumRegister(N, state) = FullStateQuantumRegister{ComplexF64}(N, state)
FullStateQuantumRegister(N, conf::String) = FullStateQuantumRegister{ComplexF64}(N, conf)

"""
    configuration2vector(conf::String)

Convert a configuration given as a string to a hilbert space vector
# Examples
```jldoctest
julia> configuration2vector("01")
4-element Array{Float64,1}:
 0.0
 1.0
 0.0
 0.0
```
"""
function configuration2vector(conf::String)
    state = 1
    for i in 1:length(conf)
        state = kron(state, conf[i] == '0' ? [1., 0.] : [0., 1.])
    end
    state
end

"""
    binary_repr(num, N)

Get the binary string representation
of a decimal integer.
# Examples
```jldoctest
julia> println(binary_repr(5, 6))
"000101"
```
"""
function binary_repr(num, N)
    if num >= 1 << N
        num %= 1 << N
    end
    binary_str = ""
    while N > 0
        if num >= (1 << (N - 1))
            binary_str *= "1"
            num -= 1 << (N - 1)
        else
            binary_str *= "0"
        end
        N -= 1
    end
    return binary_str
end

"""
    to_str(qreg::FullStateQuantumRegister)

Function to convert express fullstate quantum register as a string

# Examples
```jldoctest
julia> ψ = FullStateQuantumRegister{Int}(3, "000")
julia> ψ.state[end] = 1
julia> to_str(ψ)
"(1|000>) + (1|111>)"
```
"""
function to_str(qreg::FullStateQuantumRegister)
    N = qreg.N
    str_rep = ""
    for i in 1:length(qreg.state)
        if abs(qreg.state[i]) > 1e-15
            if str_rep != ""
                str_rep *= " + "
            end
            str_rep *= "($(qreg.state[i])|$(binary_repr(i-1, N))>)"
        end
    end
    str_rep
end

"""
    ≈(a::FullStateQuantumRegister{T},
      b::FullStateQuantumRegister{T}) where T <: Complex

Function which does an approximate comparision of quantum registers with complex elements
"""
function ≈(a::FullStateQuantumRegister{T},
           b::FullStateQuantumRegister{T}) where T <: Complex
    maximum(abs.(a.state - b.state)) < eps(T.types[1])*log2(length(a.state))*2
end

"""
    ≈(a::FullStateQuantumRegister{T},
      b::FullStateQuantumRegister{T}) where T <: Complex

Function which does an approximate comparision of quantum registers with float elements
"""
function ≈(a::FullStateQuantumRegister{T},
           b::FullStateQuantumRegister{T}) where T <: AbstractFloat
    maximum(abs.(a.state - b.state)) < eps(T)*log2(length(a.state))*2
end

"""
    ==(a::FullStateQuantumRegister{T},
       b::FullStateQuantumRegister{T})

Function which does an exact comparision of elements of quantum registers
"""
function ==(a::FullStateQuantumRegister, b::FullStateQuantumRegister)
    a.state == b.state
end

"""
    apply_1qubit_full(qreg, gate, i)

Apply the 1 qubit gate to qubit i by expanding operator fully
"""
function apply_1qubit_full(qreg::QuantumRegister, gate, i)
    op = 1
    for j = 1:qreg.N
        op = kron(op, j == i ? gate : Gates.Id)
    end
    op * qreg.state
end

"""
    apply_1qubit(qreg, gate, i)

Apply the 1 qubit gate to qubit i
"""
function apply_1qubit(qreg::QuantumRegister, gate, i)
    # reshape to separate link to apply tensor to
    state = reshape(qreg.state, (2^(qreg.N-i), 2, 2^(i-1)))
    @tensor state[a, d, c] := gate[d, b] * state[a, b, c]
    reshape(state, (2^qreg.N))
end

"""
    apply_1qubit!(qreg, gate, i)

Apply the 1 qubit gate to qubit i inplace
"""
function apply_1qubit!(qreg::QuantumRegister, gate, i)
    # reshape to separate link to apply tensor to
    # state = reshape(qreg.state, (2^(qreg.N-i), 2, 2^(i-1)))
    #@tensor state[a, d, c] = gate[d, b] * state[a, b, c]
    # state = reshape(state, (2^qreg.N))
    qreg.state = apply_1qubit(qreg, gate, i)
end

"""
    decompose_2_qubit_gate(gate; threshold=1e-15)

Decompose a 2 qubit gate into a sum of 1 qubit gates on each qubit
"""
function decompose_2_qubit_gate(gate; threshold=1e-15)
    gate = reshape(gate, (2, 2, 2, 2))
    gate = permutedims(gate, (1 ,3, 2, 4))
    gate = reshape(gate, (4, 4))
    F = svd(gate)
    s = [x for x in F.S if x > threshold]
    ops = Array{Any, 1}()
    for i in 1:length(s)
        push!(ops, (reshape(F.U[:, i:i] * s[i], (2, 2)), reshape(F.Vt[i:i, :], (2, 2))))
    end
    ops
end

"""
    apply_2qubit_full(qreg, gate, i, j)

Apply the provided 2 qubit gate to qubits i and j by expanding full operator matrix
"""
function apply_2qubit_full(qreg::QuantumRegister, gate, i, j)
    gate_ops = decompose_2_qubit_gate(gate)
    total_op = nothing
    for gate_op in gate_ops
        op = 1
        for k = 1:qreg.N
            op = kron(op, k == j ? gate_op[1] : (k == i ? gate_op[2] : Gates.Id))
        end
        if total_op == nothing
            total_op = op
        else
            total_op += op
        end
    end
    total_op * qreg.state
end

"""
    apply_2qubit_full!(qreg, gate, i, j)

Apply the provided 2 qubit gate to qubits i and j by expanding full operator matrix
"""
function apply_2qubit_full!(qreg::QuantumRegister, gate, i, j)
    qreg.state = apply_2qubit_full(qreg, gate, i, j)
end

"""
    swap_2qubits(X)

Given a two qubit operation, switch the order of the qubits
"""
function swap_2qubits(X)
    X = reshape(X, (2, 2, 2, 2))
    X = permutedims(X, (2, 1, 4, 3))
    reshape(X, (4, 4))
end

"""
    apply_2qubit(qreg, gate, i, j)

Apply the provided 2 qubit gate to qubits i and j
"""
function apply_2qubit(qreg::QuantumRegister, gate, i, j)
    if i > j
        return apply_2qubit(qreg, swap_2qubits(gate), j, i)
    else
        # reshape to separate i and j indices
        state = reshape(qreg.state, (2^(qreg.N-j), 2, 2^(j-i-1), 2, 2^(i-1)))
        gate = reshape(gate, (2, 2, 2, 2))
        @tensor state[a, b, c, d, e] := gate[b, d, x, y] * state[a, x, c, y, e]
        reshape(state, (2^qreg.N))
    end
end

"""
    apply_2qubit!(qreg, gate, i, j)

Apply the provided 2 qubit gate to qubits i and j inplace
"""
function apply_2qubit!(qreg::QuantumRegister, gate, i, j)
    qreg.state = apply_2qubit(qreg, gate, i, j)
end

"""
    measure_probs(qreg)

Get for each bitstring
"""
function measure_probs(qreg::QuantumRegister)
    real(qreg.state .* conj(qreg.state))
end

"""
    get_conf(cprobs, num, N)

Given an array of cumulative probabilities of
configurations and a random number from [0, 1],
return the bitstring it corresponds to
"""
function get_conf(cprobs, num, N)
    binary_repr(searchsortedfirst(cprobs, num)-1, N)
end

"""
    measure(qreg, shots)

Given a quantum register, return a typical set of
measurements expected
"""
function measure(qreg::QuantumRegister; shots=100)
    cprobs = cumsum(measure_probs(qreg))
    rands = rand(shots)
    return [get_conf(cprobs, x, qreg.N) for x in rands]
end

"""
    get_counts(results)

Given a set of measurement results in the form of bitstrings,
return the counts of each
"""
function get_counts(results)
    counts = Dict{String, Integer}()
    for conf in results
        if haskey(counts, conf)
            counts[conf] += 1
        else
            counts[conf] = 1
        end
    end
    counts
end

"""
    execute!(qc::QuantumCircuit, state::FullStateQuantumRegister)

Apply the given quantum circuit to the given quantum register in place
"""
function execute!(qc::Gates.QuantumCircuit, state::FullStateQuantumRegister)
    for op in qc.ops
        if op.n == 1
            apply_1qubit!(state, op.gate, op.qubits[1])
        elseif op.n == 2
            apply_2qubit!(state, op.gate, op.qubits[1], op.qubits[2])
        end
    end
end


text:
# Autogenerated wrapper script for p7zip_jll for i686-w64-mingw32
export p7zip

JLLWrappers.@generate_wrapper_header("p7zip")
JLLWrappers.@declare_executable_product(p7zip)
function __init__()
    JLLWrappers.@generate_init_header()
    JLLWrappers.@init_executable_product(
        p7zip,
        "bin\\7z.exe",
    )

    JLLWrappers.@generate_init_footer()
end  # __init__()


text:
push!(LOAD_PATH, "../src/")
using Documenter
using IntegralTransforms

makedocs(
    modules = [IntegralTransforms]
)

# Documenter can also automatically deploy documentation to gh-pages.
# See "Hosting Documentation" and deploydocs() in the Documenter manual
# for more information.
deploydocs(
    deps = Deps.pip("mkdocs", "python-markdown-math", "pygments")
    repo = "github.com/miguelraz/IntegralTransforms.jl.git"
    julia = "0.6"
    osname = "linux"
)


text:
@testset "SimulatedAnnealing" begin
    img = generate_surface(SynthSphere(50), 0.5, [0,0,1])
    p,q = synthetic_gradient(SynthSphere(40))
    p,q = SimulatedAnnealing(pin = p, qin = q, max_iter = 100)(img)
    @test 1 == 1
end


text:
vis = Visualizer()
open(vis)

# Create Roadway
roadway_opts = HighwayRoadwayOptions()
roadway = build_roadway(roadway_opts)

# Create players
T = Float64
p = 3
model = UnicycleGame(p=p)

players = Vector{Player{T}}(undef, p)
players[1] = Player(model, roadway.lane[1],
    Q=Diagonal(SVector{model.ni[1],T}(0.0, 1.0, 1.0, 1.0)),
    x0=VehicleState(0.1, 0.1, 0.0, 0.7),
    xf=VehicleState(3.6, 0.1, 0.0, 0.7))
players[2] = Player(model, roadway.lane[2],
    Q=Diagonal(SVector{model.ni[2],T}(0.0, 1.0, 1.0, 1.0)),
    x0=VehicleState(0.1,-0.1, 0.0, 0.7),
    xf=VehicleState(3.6,-0.1, 0.0, 0.7))
players[3] = Player(model, roadway.lane[3],
    Q=Diagonal(SVector{model.ni[3],T}(0.0, 1.0, 1.0, 1.0)),
    x0=VehicleState(0.3,-0.1, 0.0, 0.7),
    xf=VehicleState(3.8, 0.1, 0.0, 0.7))

# Create Scenario
sce = Scenario(model, roadway, players)

# Create AutoProblem
N = 50
dt = 0.1
solver_opts = Options()
solver_opts.inner_print = true
solver_opts.outer_print = true
prob = GameProblem(N, dt, sce, solver_opts)
@time newton_solve!(prob)

plot!(model, prob.pdtraj.pr)
plot!(prob.stats)

# Visualize trajectory
set_scenario!(vis, sce)
set_env!(vis, VehicleState(2.0, 0.0, 0.0, 0.0))
set_camera_birdseye!(vis, height=7.0)
build_waypoint!(vis, sce.player, N)

@time set_state!(vis, model, sce, Algames.state(prob.pdtraj.pr[10]))
@time set_traj!(vis, model, sce, prob.pdtraj.pr)
@time set_waypoint_traj!(vis, model, sce, prob.pdtraj.pr)


text:
#
# How do we include time-varying inputs?
#

# p[0]   to p[p-1]     represents the system parameters    (p=> number of parameters)
# p[p]   to p[p+r-1]   represents the rate inputs          (r=> number of infusion rate inputs)
# p[p+r] to p[p+r+v-1] represents the timevarying inputs   (v=> number of time varying inputs)

function system_DYDT!(SIMINT_du, SIMINT_u, SIMINT_p, SIMINT_TIME)
<SYSTEM_PARAM><SS_PARAM><STATES><DS_PARAM>

# Defining the differential equations
<ODES>

# Mapping back to du variables
<ODES_REMAP>

return(SIMINT_du)
end

max_stars_repo_name: john-harrold/ubiquity-pkpd

max_issues_repo_name: john-harrold/ubiquity-pkpd

max_forks_repo_name: john-harrold/ubiquity-pkpd


text:
function textDocument_didOpen_notification(params::DidOpenTextDocumentParams, server::LanguageServerInstance, conn)
    uri = params.textDocument.uri
    if hasdocument(server, URI2(uri))
        doc = getdocument(server, URI2(uri))
        set_text!(doc, params.textDocument.text)
        doc._version = params.textDocument.version
        set_open_in_editor(doc, true)
        get_line_offsets(doc, true)
    else
        doc = Document(uri, params.textDocument.text, false, server)
        setdocument!(server, URI2(uri), doc)
        doc._version = params.textDocument.version
        doc._workspace_file = any(i -> startswith(uri, filepath2uri(i)), server.workspaceFolders)
        set_open_in_editor(doc, true)

        fpath = getpath(doc)

        !isempty(fpath) && try_to_load_parents(fpath, server)
    end
    parse_all(doc, server)
end

function textDocument_didClose_notification(params::DidCloseTextDocumentParams, server::LanguageServerInstance, conn)
    uri = params.textDocument.uri
    doc = getdocument(server, URI2(uri))

    if is_workspace_file(doc)
        set_open_in_editor(doc, false)
    else
        if any(getroot(d) == getroot(doc) && (d._open_in_editor || is_workspace_file(d)) for (uri, d::Document) in getdocuments_pair(server) if d != doc)
            # If any other open document shares doc's root we just mark it as closed...
            set_open_in_editor(doc, false)
        else
            # ...otherwise we delete all documents that share root with doc.
            for (u, d) in getdocuments_pair(server)
                if getroot(d) == getroot(doc)
                    deletedocument!(server, u)
                    empty!(doc.diagnostics)
                    publish_diagnostics(doc, server, conn)
                end
            end
        end
    end
end

function textDocument_didSave_notification(params::DidSaveTextDocumentParams, server::LanguageServerInstance, conn)
    uri = params.textDocument.uri
    doc = getdocument(server, URI2(uri))
    if params.text isa String
        if get_text(doc) != params.text
            JSONRPC.send(conn, window_showMessage_notification_type, ShowMessageParams(MessageTypes.Error, "Julia Extension: Please contact us! Your extension just crashed with a bug that we have been trying to replicate for a long time. You could help the development team a lot by contacting us at https://github.com/julia-vscode/julia-vscode so that we can work together to fix this issue."))
            throw(LSSyncMismatch("Mismatch between server and client text for $(doc._uri). _open_in_editor is $(doc._open_in_editor). _workspace_file is $(doc._workspace_file). _version is $(doc._version)."))
        end
    end
    parse_all(doc, server)
end

function textDocument_willSave_notification(params::WillSaveTextDocumentParams, server::LanguageServerInstance, conn)
end

function textDocument_willSaveWaitUntil_request(params::WillSaveTextDocumentParams, server::LanguageServerInstance, conn)
    return TextEdit[]
end

comp(x, y) = x == y
function comp(x::CSTParser.EXPR, y::CSTParser.EXPR)
    comp(x.head, y.head) &&
    x.span == y.span &&
    x.fullspan == y.fullspan &&
    x.val == y.val &&
    length(x) == length(y) &&
    all(comp(x[i], y[i]) for i = 1:length(x))
end

function textDocument_didChange_notification(params::DidChangeTextDocumentParams, server::LanguageServerInstance, conn)
    doc = getdocument(server, URI2(params.textDocument.uri))
    s0 = deepcopy(get_text(doc)) # I don't think deepcopy is needed
    if params.textDocument.version < doc._version
        error("The client and server have different textDocument versions for $(doc._uri). LS version is $(doc._version), request version is $(params.textDocument.version).")
    end
    doc._version = params.textDocument.version

    for tdcce in params.contentChanges
        applytextdocumentchanges(doc, tdcce)
    end
    if endswith(doc._uri, ".jmd")
        parse_all(doc, server)
    else
        cst0, cst1 = getcst(doc), CSTParser.parse(get_text(doc), true)
        r1, r2, r3 = CSTParser.minimal_reparse(s0, get_text(doc), cst0, cst1, inds = true)
        for i in setdiff(1:length(cst0.args), r1 , r3) # clean meta from deleted expr
            StaticLint.clear_meta(cst0[i])
        end
        setcst(doc, EXPR(cst0.head, EXPR[cst0.args[r1]; cst1.args[r2]; cst0.args[r3]], nothing))
        comp(cst1, getcst(doc)) || @error "File didn't update properly." # expensive check, remove
        sizeof(get_text(doc)) == getcst(doc).fullspan || @error "CST does not match input string length."
        headof(doc.cst) === :file ? set_doc(doc.cst, doc) : @info "headof(doc) isn't :file for $(doc._path)"

        target_exprs = getcst(doc).args[last(r1) .+ (1:length(r2))]
        semantic_pass(getroot(doc), target_exprs)
        lint!(doc, server)
    end
end

function convert_lsrange_to_jlrange(doc::Document, range::Range)
    start_offset_ls = get_offset2(doc, range.start.line, range.start.character)
    stop_offset = get_offset2(doc, range.stop.line, range.stop.character)

    text = get_text(doc)

    # we use prevind for the stop value here because Julia stop values in
    # a range are inclusive, while the stop value is exclusive in a LS
    # range
    return start_offset_ls:prevind(text, stop_offset)
end

function applytextdocumentchanges(doc::Document, tdcce::TextDocumentContentChangeEvent)
    if ismissing(tdcce.range) && ismissing(tdcce.rangeLength)
        # No range given, replace all text
        set_text!(doc, tdcce.text)
    else
        editrange = convert_lsrange_to_jlrange(doc, tdcce.range)
        text = get_text(doc)
        new_text = string(text[1:prevind(text, editrange.start)], tdcce.text, text[nextind(text, editrange.stop):lastindex(text)])
        set_text!(doc, new_text)
    end
end

function parse_all(doc::Document, server::LanguageServerInstance)
    ps = CSTParser.ParseState(get_text(doc))
    StaticLint.clear_meta(getcst(doc))
    if endswith(doc._uri, ".jmd")
        doc.cst, ps = parse_jmd(ps, get_text(doc))
    else
        doc.cst, ps = CSTParser.parse(ps, true)
    end
    sizeof(get_text(doc)) == getcst(doc).fullspan || @error "CST does not match input string length."
    if headof(doc.cst) === :file
        set_doc(doc.cst, doc)
    end
    semantic_pass(getroot(doc))

    lint!(doc, server)
end

function mark_errors(doc, out=Diagnostic[])
    line_offsets = get_line_offsets(doc)
    errs = StaticLint.collect_hints(getcst(doc), getenv(doc), doc.server.lint_missingrefs)
    n = length(errs)
    n == 0 && return out
    i = 1
    start = true
    offset = errs[i][1]
    r = Int[0, 0]
    nlines = length(line_offsets)
    if offset > last(line_offsets)
        line = nlines
    else
        line = 1
        io = IOBuffer(get_text(doc))
        while line < nlines
            seek(io, line_offsets[line])
            char = 0
            while line_offsets[line] <= offset < line_offsets[line + 1]
                while offset > position(io)
                    c = read(io, Char)
                    if UInt32(c) >= 0x010000
                        char += 1
                    end
                    char += 1
                end
                if start
                    r[1] = line
                    r[2] = char
                    offset += errs[i][2].span
                else
                    if headof(errs[i][2]) === :errortoken
                        push!(out, Diagnostic(Range(r[1] - 1, r[2], line - 1, char), DiagnosticSeverities.Error, missing, "Julia", "Parsing error", missing, missing))
                    elseif CSTParser.isidentifier(errs[i][2]) && !StaticLint.haserror(errs[i][2])
                        push!(out, Diagnostic(Range(r[1] - 1, r[2], line - 1, char), DiagnosticSeverities.Warning, missing, "Julia", "Missing reference: $(errs[i][2].val)", missing, missing))
                    elseif StaticLint.haserror(errs[i][2]) && StaticLint.errorof(errs[i][2]) isa StaticLint.LintCodes
                        if StaticLint.errorof(errs[i][2]) in (StaticLint.UnusedFunctionArgument, StaticLint.UnusedBinding, StaticLint.UnusedTypeParameter)
                            push!(out, Diagnostic(Range(r[1] - 1, r[2], line - 1, char), DiagnosticSeverities.Hint, missing, "Julia", get(StaticLint.LintCodeDescriptions, StaticLint.errorof(errs[i][2]), ""), [DiagnosticTags.Unnecessary], missing))
                        else
                            push!(out, Diagnostic(Range(r[1] - 1, r[2], line - 1, char), DiagnosticSeverities.Information, missing, "Julia", get(StaticLint.LintCodeDescriptions, StaticLint.errorof(errs[i][2]), ""), missing, missing))
                        end
                    end
                    i += 1
                    i > n && break
                    offset = errs[i][1]
                end
                start = !start
                offset = start ? errs[i][1] : errs[i][1] + errs[i][2].span
            end
            line += 1
        end
        close(io)
    end
    return out
end

isunsavedfile(doc::Document) = startswith(doc._uri, "untitled:") # Not clear if this is consistent across editors.

"""
is_diag_dependent_on_env(diag::Diagnostic)::Bool

Is this diagnostic reliant on the current environment being accurately represented?
"""
function is_diag_dependent_on_env(diag::Diagnostic)
    startswith(diag.message, "Missing reference: ") ||
    startswith(diag.message, "Possible method call error") ||
    startswith(diag.message, "An imported")
end

function publish_diagnostics(doc::Document, server, conn)
    diagnostics = if server.runlinter && server.symbol_store_ready && (is_workspace_file(doc) || isunsavedfile(doc))
        pkgpath = getpath(doc)
        if any(is_in_target_dir_of_package.(Ref(pkgpath), server.lint_disableddirs))
            filter!(!is_diag_dependent_on_env, doc.diagnostics)
        end
        doc.diagnostics
    else
        Diagnostic[]
    end
    params = PublishDiagnosticsParams(doc._uri, doc._version, diagnostics)
    JSONRPC.send(conn, textDocument_publishDiagnostics_notification_type, params)
end

function clear_diagnostics(uri::URI2, server, conn)
    doc = getdocument(server, uri)
    empty!(doc.diagnostics)
    publishDiagnosticsParams = PublishDiagnosticsParams(doc._uri, doc._version, Diagnostic[])
    JSONRPC.send(conn, textDocument_publishDiagnostics_notification_type, publishDiagnosticsParams)
end

function clear_diagnostics(server, conn)
    for uri in getdocuments_key(server)
        clear_diagnostics(uri, server, conn)
    end
end

function parse_jmd(ps, str)
    currentbyte = 1
    blocks = []
    while ps.nt.kind != Tokens.ENDMARKER
        CSTParser.next(ps)
        if ps.t.kind == Tokens.CMD || ps.t.kind == Tokens.TRIPLE_CMD
            push!(blocks, (ps.t.startbyte, CSTParser.INSTANCE(ps)))
        end
    end
    top = EXPR(:file, EXPR[], nothing)
    if isempty(blocks)
        return top, ps
    end

    for (startbyte, b) in blocks
        if CSTParser.ismacrocall(b) && headof(b.args[1]) === :globalrefcmd && headof(b.args[3]) === :TRIPLESTRING && (startswith(b.args[3].val, "julia") || startswith(b.args[3].val, "{julia"))

            blockstr = b.args[3].val
            ps = CSTParser.ParseState(blockstr)
            # skip first line
            while ps.nt.startpos[1] == 1
                CSTParser.next(ps)
            end
            prec_str_size = currentbyte:startbyte + ps.nt.startbyte + 3

            push!(top, EXPR(:STRING, length(prec_str_size), length(prec_str_size)))

            args, ps = CSTParser.parse(ps, true)
            for a in args.args
                push!(top, a)
            end

            CSTParser.update_span!(top)
            currentbyte = top.fullspan + 1
        elseif CSTParser.ismacrocall(b) && headof(b.args[1]) === :globalrefcmd && headof(b.args[3]) === :STRING && b.val !== nothing && startswith(b.val, "j ")
            blockstr = b.args[3].val
            ps = CSTParser.ParseState(blockstr)
            CSTParser.next(ps)
            prec_str_size = currentbyte:startbyte + ps.nt.startbyte + 1
            push!(top, EXPR(:STRING, length(prec_str_size), length(prec_str_size)))

            args, ps = CSTParser.parse(ps, true)
            for a in args.args
                push!(top, a)
            end

            CSTParser.update_span!(top)
            currentbyte = top.fullspan + 1
        end
    end

    prec_str_size = currentbyte:sizeof(str) # OK
    push!(top, EXPR(:STRING, length(prec_str_size), length(prec_str_size)))
    CSTParser.update_span!(top)

    return top, ps
end

function search_for_parent(dir::String, file::String, drop=3, parents=String[])
    drop < 1 && return parents
    try
        !isdir(dir) && return parents
        !hasreadperm(dir) && return parents
        for f in readdir(dir)
            filename = joinpath(dir, f)
            if isvalidjlfile(filename)
                # Could be sped up?
                content = try
                    s = read(filename, String)
                    isvalid(s) || continue
                    s
                catch err
                    isa(err, Base.IOError) || isa(err, Base.SystemError) || rethrow()
                    continue
                end
                occursin(file, content) && push!(parents, joinpath(dir, f))
            end
        end
        search_for_parent(splitdir(dir)[1], file, drop - 1, parents)
    catch err
        isa(err, Base.IOError) || isa(err, Base.SystemError) || rethrow()
        return parents
    end

    return parents
end

function is_parentof(parent_path, child_path, server)
    !isvalidjlfile(parent_path) && return false
    previous_server_docs = collect(getdocuments_key(server)) # additions to this to be removed at end
    # load parent file
    puri = filepath2uri(parent_path)
    if !hasdocument(server, URI2(puri))
        content = try
            s = read(parent_path, String)
            isvalid(s) || return false
            s
        catch err
            isa(err, Base.IOError) || isa(err, Base.SystemError) || rethrow()
            return false
        end
        pdoc = Document(puri, content, false, server)
        setdocument!(server, URI2(puri), pdoc)
        CSTParser.parse(get_text(pdoc), true)
        if headof(pdoc.cst) === :file
            set_doc(pdoc.cst, pdoc)
        end
    else
        pdoc = getdocument(server, URI2(puri))
    end
    semantic_pass(getroot(pdoc))
    # check whether child has been included automatically
    if any(getpath(d) == child_path for (k, d) in getdocuments_pair(server) if !(k in previous_server_docs))
        cdoc = getdocument(server, URI2(filepath2uri(child_path)))
        parse_all(cdoc, server)
        semantic_pass(getroot(cdoc))
        return true, "", CSTParser.Tokens.STRING
    else
        # clean up
        foreach(k -> !(k in previous_server_docs) && deletedocument!(server, k), getdocuments_key(server))
        return false
    end
end

function try_to_load_parents(child_path, server)
    for p in search_for_parent(splitdir(child_path)...)
        p == child_path && continue
        success = is_parentof(p, child_path, server)
        if success
            return try_to_load_parents(p, server)
        end
    end
end


text:
module test_julia_docs

using Test

"hello"
A

@test !isdefined(@__MODULE__, :A)

struct A
end

@test isdefined(@__MODULE__, :A)
@test string(Base.Docs.doc(A)) == "hello\n"

@test (:if, :else) ⊆ keys(Base.Docs.keywords)

end # module test_julia_docs


text:
using Makie: volume

@cell "align" begin
    fig, ax, sc = scatter(RNG.rand(10), color=:red)
    text!(ax, "adding text", textsize=0.6, align=(:center, :center))
    fig
end

@cell "fillrange" begin
    x = LinRange(-1, 1, 20)
    y = LinRange(-1, 1, 20)
    z = x .* y'
    contour(x, y, z, levels=0, linewidth=0, fillrange=true)
end

@cell "font" begin
    fig, ax, sc = scatter(RNG.rand(10), color=:red)
    text!(ax, "adding text", textsize=0.6, align=(:center, :center), font="Blackchancery")
    fig
end

@cell "glowcolor, glowwidth" begin
    scatter(RNG.randn(10), color=:blue, glowcolor=:orange, glowwidth=10)
end

@cell "isorange, isovalue" begin
    r = range(-1, stop=1, length=100)
    matr = [(x.^2 + y.^2 + z.^2) for x = r, y = r, z = r]
    volume(matr .* (matr .> 1.4), algorithm=:iso, isorange=0.05, isovalue=1.7)
end

@cell "levels" begin
    x = LinRange(-1, 1, 20)
    y = LinRange(-1, 1, 20)
    z = x .* y'
    contour(x, y, z, linewidth=3, colormap=:colorwheel, levels=50)
end

@cell "position" begin
    fig, ax, sc = scatter(RNG.rand(10), color=:red)
    text!(ax, "adding text", textsize=0.6, position=(5.0, 1.1))
    fig
end

@cell "rotation" begin
    text("Hello World", rotation=1.1)
end

@cell "shading" begin
    mesh(Sphere(Point3f0(0), 1f0), color=:orange, shading=false)
end

@cell "visible" begin
    fig = Figure()
    scatter(fig[1, 1], RNG.randn(20), color=to_colormap(:deep, 20), markersize=10, visible=true)
    scatter(fig[1, 2], RNG.randn(20), color=to_colormap(:deep, 20), markersize=10, visible=false)
    fig
end


text:
function gen_carrier_replica!(
    carrier_replica::StructArray{Complex{T}},
    carrier_frequency,
    sampling_frequency,
    start_phase,
    start_sample,
    num_samples
) where T
    c_re = carrier_replica.re; c_im = carrier_replica.im
    carr_freq = T(upreferred(carrier_frequency / Hz))
    sample_freq = T(upreferred(sampling_frequency / Hz))
    twopi = T(2π)
    phase = T(start_phase)
    @avx for i in 0:num_samples - 1
        c_im[i + start_sample], c_re[i + start_sample] =
            sincos(twopi * (i * carr_freq / sample_freq + phase))
    end
    carrier_replica
end

"""
$(SIGNATURES)

Updates the carrier phase.
"""
function update_carrier_phase(
    num_samples,
    carrier_frequency,
    sampling_frequency,
    start_phase,
)
    phase = num_samples * carrier_frequency / sampling_frequency + start_phase
    mod(phase + 0.5, 1) - 0.5
end

"""
$(SIGNATURES)

Calculates the current carrier frequency.
"""
function get_current_carrier_frequency(intermediate_frequency, carrier_doppler)
    carrier_doppler + intermediate_frequency
end


text:
open("data/uniprotkb/trembl_" * ARGS[1] * ".csv", "w") do fp
    open("data/uniprotkb/uniprot_trembl.dat", "r") do fp2
        # 空の配列を用意 : [Accession, TaxID, Sub.Loc.]の順
        eachentry = ["","","",""]
        eachcc = []
        eachpmid = []
        # フラグ
        isac = false
        istax = false
        isloc = false
        isncbi = false
        hit = false
        # 毎行パース
        for line in eachline(fp2)
            # AC   Q6GZX4;
            # みたいな行を切り出す
            # !!!1行に複数書かれていることが多い!!!
            if occursin(r"^AC   ", line)
                eachentry[1] = replace(replace(replace(line, r"^AC   " => ""), r";$" => ""), "," => " ")
                isac = true
            end

            # OX   NCBI_TaxID=9606;
            # みたいな行を切り出す
            # !!!1つだけ!!!
            if occursin(r"^OX   NCBI_TaxID=", line)
                tmp = match(r"^OX   NCBI_TaxID=(\d*).*;", line)
                if tmp.captures[1] == ARGS[1]
                    istax = true
                end
            end

            # RX   PubMed=15165820;
            # みたいな行を切り出す
            # !!!複数行にまたがっている!!!
            if occursin(r"^RX   PubMed=", line)
                tmp = match(r"^RX   PubMed=(\d*);", line)
                push!(eachpmid, replace(tmp.captures[1], "," => " "))
            end

            # 先頭が"CC"
            if occursin(r"^CC   ", line)
                # 先頭が"CC" かつ "CC   -!- SUBCELLULAR LOCATION:"
                if occursin(r"^CC   -!- SUBCELLULAR LOCATION:", line)
                    push!(eachcc, replace(replace(line, r"^CC   -!- SUBCELLULAR LOCATION: " => ""), "," => " "))
                    hit = true

                # 先頭が"CC" かつ "CC   -!- SUBCELLULAR LOCATION:"ではない
                else
                    # 先頭が"CC" かつ "CC   -!- SUBCELLULAR LOCATION:"ではなく かつ CC   みたいなやつ
                    if occursin(r"^CC   -!-", line) && hit
                        push!(eachcc, replace(replace(line, r"^CC   " => ""), "," => " "))
                    end
                end
            end

            # CCから出てからtmpを格納して、islocを作動
            if !occursin(r"^CC   -!-", line) && hit
                # 次のCCの情報になったタイミングで保存
                tmp = ""
                for i in 1:length(eachcc)
                    tmp = tmp * eachcc[i]
                end
                eachentry[2] = replace(replace(tmp, r",$" => ""), "," => " ")
                eachcc = []
                isloc = true
                hit = false
            end

            # DR   GeneID;
            # みたいな形を取り出す
            if occursin(r"^DR   GeneID;", line)
                ncbi = replace(line, r"^DR   GeneID; " => "")
                ncbi = replace(ncbi, r"; -." => "")
                ncbi = replace(ncbi, r";" => "")
                eachentry[3] = replace(ncbi, "," => " ")
                isncbi = true
            end

            # もし該当する生物種だったら保存
            if isac && istax && isloc && isncbi
                # PMIDをまとめ
                if length(eachpmid) != 0
                    tmp = ""
                    for i in 1:length(eachpmid)
                        tmp = tmp * eachpmid[i] * ";"
                    end
                    eachentry[4] = replace(replace(tmp, r";$" => ""), "," => " ")
                else
                    eachentry[4] = "-"
                end

                write(fp, eachentry[1] * "," * eachentry[2] * "," * eachentry[3] * "," * eachentry[4] * "\n")
                eachentry = ["","","",""]
                eachpmid = []
                isac = false
                istax = false
                isloc = false
                isncbi = false
            end

            # 1エントリー終わったら一度リセット
            if occursin(r"^//", line)
                eachentry = ["","","",""]
                eachpmid = []
                isac = false
                istax = false
                isloc = false
                isncbi = false
            end
        end
    end
end

max_stars_repo_name: manabuishii/lrbase-workflow

max_issues_repo_name: manabuishii/lrbase-workflow

max_forks_repo_name: manabuishii/lrbase-workflow


text:
module InvariantSetApproximation

# imports
using LightGraphs
using SpatialIndexing
using LazySets

# constants to avoid using long names
const SI = SpatialIndexing
const LS = LazySets

include("abstracts.jl")
include("systems.jl")
include("options.jl")
include("solvers.jl")
include("hyperrectangle.jl")
include("core.jl")
include("solution.jl")

# exports to be used outside the module
export system, Options, computeISet, ConvexHullArray

end # module


text:
# Use baremodule to shave off a few KB from the serialized `.ji` file
baremodule nanoflann_jll
using Base
using Base: UUID
import JLLWrappers

JLLWrappers.@generate_main_file_header("nanoflann")
JLLWrappers.@generate_main_file("nanoflann", UUID("d35a0d8d-9068-5be2-914f-8871ec93937d"))
end  # module nanoflann_jll


text:
# * Multipole expansion

"""
    multipole_expand_scalar_product(a, b, P, Q, c, d)

Multipole-expand the matrix element `⟨ab|P⋅Q|cd⟩`, where the tensor
`P` acts on orbitals `a` & `c`, and the tensor `Q` acts on orbitals
`b` & `d`. The definition is taken from Eq. (13.1.26) of Varshalovich
(1988).
"""
function multipole_expand_scalar_product(a, b, P, Q, c, d, f::Int=1)
    multipole_terms = Pair{Int,Float64}[]

    couples(a, P, c) && couples(b, Q, d) ||
        return multipole_terms

    ks = ranks(a,P,c) ∩ ranks(b,Q,d)

    for k in ks
        X = P(k)⋅Q(k)
        v = dot((a,b), X, (c,d))
        iszero(v) && continue

        push!(multipole_terms, k => f*v)
    end

    multipole_terms
end

"""
    multipole_expand(integral::OrbitalMatrixElement{2,A,<:CoulombInteraction,B})

Multipole-expand the two-body integral resulting from the Coulomb
repulsion between two electrons.
"""
function multipole_expand(integral::OrbitalMatrixElement{2,<:Any,<:CoulombInteraction,<:Any})
    (a,b),g,(c,d) = integral.a,integral.o,integral.b

    terms = NBodyTerm[]

    for (k,coeff) in multipole_expand_scalar_product(a, b, CoulombTensor, CoulombTensor, c, d)
        # Remember: integral.a == (a,b), integral.b == (c,d) => two-body integral
        push!(terms, NBodyTerm([radial_integral(integral.a, (k,g), integral.b)], coeff))
    end

    NBodyMatrixElement(terms)
end

export multipole_expand_scalar_product, multipole_expand


text:
using MPI
using StaticArrays
using ClimateMachine
using ClimateMachine.VariableTemplates
using ClimateMachine.Mesh.Topologies
using ClimateMachine.Mesh.Grids
using ClimateMachine.MPIStateArrays
using ClimateMachine.DGMethods
using Printf

using ClimateMachine.BalanceLaws

import ClimateMachine.BalanceLaws: vars_state, nodal_init_state_auxiliary!

using ClimateMachine.Mesh.Geometry: LocalGeometry

if !@isdefined integration_testing
    const integration_testing = parse(
        Bool,
        lowercase(get(ENV, "JULIA_CLIMA_INTEGRATION_TESTING", "false")),
    )
end

struct GradTestModel{dim, dir} <: BalanceLaw end

vars_state(m::GradTestModel, ::Auxiliary, T) = @vars begin
    a::T
    ∇a::SVector{3, T}
end
vars_state(::GradTestModel, ::Prognostic, T) = @vars()

function nodal_init_state_auxiliary!(
    ::GradTestModel{dim, dir},
    aux::Vars,
    tmp::Vars,
    g::LocalGeometry,
) where {dim, dir}
    x, y, z = g.coord
    if dim == 2
        aux.a = x^2 + y^3 - x * y
        if dir isa EveryDirection
            aux.∇a = SVector(2 * x - y, 3 * y^2 - x, 0)
        elseif dir isa HorizontalDirection
            aux.∇a = SVector(2 * x - y, 0, 0)
        elseif dir isa VerticalDirection
            aux.∇a = SVector(0, 3 * y^2 - x, 0)
        end
    else
        aux.a = x^2 + y^3 + z^2 * y^2 - x * y * z
        if dir isa EveryDirection
            aux.∇a = SVector(
                2 * x - y * z,
                3 * y^2 + 2 * z^2 * y - x * z,
                2 * z * y^2 - x * y,
            )
        elseif dir isa HorizontalDirection
            aux.∇a = SVector(2 * x - y * z, 3 * y^2 + 2 * z^2 * y - x * z, 0)
        elseif dir isa VerticalDirection
            aux.∇a = SVector(0, 0, 2 * z * y^2 - x * y)
        end
    end
end

using Test
function test_run(mpicomm, dim, direction, Ne, N, FT, ArrayType)
    connectivity = dim == 3 ? :full : :face
    brickrange = ntuple(j -> range(FT(0); length = Ne[j] + 1, stop = 3), dim)
    topl = StackedBrickTopology(
        mpicomm,
        brickrange,
        periodicity = ntuple(j -> false, dim),
        connectivity = connectivity,
    )

    grid = DiscontinuousSpectralElementGrid(
        topl,
        FloatType = FT,
        DeviceArray = ArrayType,
        polynomialorder = N,
    )

    model = GradTestModel{dim, direction}()
    dg = DGModel(
        model,
        grid,
        nothing,
        nothing,
        nothing;
        state_gradient_flux = nothing,
    )

    exact_aux = copy(dg.state_auxiliary)

    auxiliary_field_gradient!(
        model,
        dg.state_auxiliary,
        (:∇a,),
        dg.state_auxiliary,
        (:a,),
        grid,
        direction,
    )

    # Wrapping in Array ensure both GPU and CPU code use same approx
    approx = Array(dg.state_auxiliary.∇a) ≈ Array(exact_aux.∇a)
    err = euclidean_distance(exact_aux, dg.state_auxiliary)
    return approx, err
end

let
    ClimateMachine.init()
    ArrayType = ClimateMachine.array_type()

    mpicomm = MPI.COMM_WORLD

    numelem = (5, 5, 5)

    expected_result = Dict()
    expected_result[Float64, 2, 1] = 6.2135207410935696e+00
    expected_result[Float64, 2, 2] = 2.3700094936518794e+00
    expected_result[Float64, 2, 3] = 8.7105082013050261e-01
    expected_result[Float64, 2, 4] = 3.1401219279927611e-01

    expected_result[Float64, 3, 1] = 7.9363467666175236e+00
    expected_result[Float64, 3, 2] = 2.8059223082616098e+00
    expected_result[Float64, 3, 3] = 9.9204334582727094e-01
    expected_result[Float64, 3, 4] = 3.5074028853276679e-01

    expected_result[Float32, 2, 1] = 6.2135176658630371e+00
    expected_result[Float32, 2, 2] = 2.3700129985809326e+00
    expected_result[Float32, 3, 1] = 7.9363408088684082e+00
    expected_result[Float32, 3, 2] = 2.8059237003326416e+00

    @testset for FT in (Float64, Float32)
        lvls =
            integration_testing || ClimateMachine.Settings.integration_testing ?
            (FT === Float32 ? 2 : 4) : 1

        @testset for polynomialorder in ((4, 4), (4, 0))
            @testset for dim in 2:3
                @testset for direction in (
                    EveryDirection(),
                    HorizontalDirection(),
                    VerticalDirection(),
                )
                    err = zeros(FT, lvls)
                    for l in 1:lvls
                        approx, err[l] = test_run(
                            mpicomm,
                            dim,
                            direction,
                            ntuple(j -> 2^(l - 1) * numelem[j], dim),
                            polynomialorder,
                            FT,
                            ArrayType,
                        )
                        if polynomialorder[end] != 0 ||
                           direction isa HorizontalDirection
                            @test approx
                        else
                            @test err[l] ≈ expected_result[FT, dim, l]
                        end
                    end
                    if polynomialorder[end] != 0 ||
                       direction isa HorizontalDirection
                        @info begin
                            msg = "Polynomial order = $polynomialorder, direction = $direction\n"
                            for l in 1:(lvls - 1)
                                rate = log2(err[l]) - log2(err[l + 1])
                                msg *= @sprintf(
                                    "\n  rate for level %d = %e\n",
                                    l,
                                    rate
                                )
                            end
                            msg
                        end
                    end
                end
            end
        end
    end
end

nothing


text:
@testset "Compute Autodiff on CPU" begin
    @testset "Case $case" for case in ["case9.m", "case30.m"]
        datafile = joinpath(dirname(@__FILE__), "..", "..", "data", case)
        tolerance = 1e-8
        pf = PS.PowerNetwork(datafile)
        nbus = pf.nbus
        pv = pf.pv ; npv = length(pv)
        pq = pf.pq ; npq = length(pq)
        ref = pf.ref ; nref = length(ref)

        polar = PolarForm(pf, CPU())
        cache = ExaPF.get(polar, ExaPF.PhysicalState())
        ExaPF.init_buffer!(polar, cache)

        xk = ExaPF.initial(polar, State())
        u = ExaPF.initial(polar, Control())

        jx = AutoDiff.Jacobian(polar, ExaPF.power_balance, State())
        ju = AutoDiff.Jacobian(polar, ExaPF.power_balance, Control())

        # Solve power flow
        conv = powerflow(polar, jx, cache, NewtonRaphson(tol=1e-12))
        # Get solution in complex form.
        V = cache.vmag .* exp.(im .* cache.vang)

        # Test Jacobian w.r.t. State
        @testset "Constraint $(cons)" for cons in [
            ExaPF.voltage_magnitude_constraints,
            ExaPF.power_balance,
            ExaPF.active_power_constraints,
            ExaPF.reactive_power_constraints,
            ExaPF.flow_constraints,
        ]
            m = ExaPF.size_constraint(polar, cons)
            # Allocation
            pbm = AutoDiff.TapeMemory(polar, cons, typeof(u))
            tgt = rand(m)
            c = zeros(m)

            ## STATE JACOBIAN

            xjacobianAD = ExaPF.AutoDiff.Jacobian(polar, cons, State())
            # Evaluate Jacobian with AD
            J = AutoDiff.jacobian!(polar, xjacobianAD, cache)
            # Matpower Jacobian
            Jmat_x = ExaPF.matpower_jacobian(polar, State(), cons, V)
            # Evaluate Jacobian transpose vector product

            # Compare with FiniteDiff
            function jac_fd_x(x)
                cache.vang[pv] .= x[1:npv]
                cache.vang[pq] .= x[npv+1:npv+npq]
                cache.vmag[pq] .= x[npv+npq+1:end]
                c = zeros(m)
                cons(polar, c, cache.vmag, cache.vang, cache.pinj, cache.qinj)
                return c
            end
            x = [cache.vang[pv]; cache.vang[pq]; cache.vmag[pq]]
            Jd = FiniteDiff.finite_difference_jacobian(jac_fd_x, x)
            @test size(J) == (m, length(x))
            # Test that AutoDiff matches MATPOWER
            @test isapprox(Jd, xjacobianAD.J, rtol=1e-5)
            @test isapprox(Jmat_x, xjacobianAD.J, rtol=1e-4)

            ## JACOBIAN VECTOR PRODUCT
            ExaPF.jacobian_transpose_product!(polar, pbm, cache, tgt)
            ∂cons = pbm.stack
            @test isapprox(∂cons.∂x, xjacobianAD.J' * tgt, rtol=1e-6)

            ## CONTROL JACOBIAN
            if !isa(cons, typeof(ExaPF.voltage_magnitude_constraints))
                ujacobianAD = ExaPF.AutoDiff.Jacobian(polar, cons, Control())
                # Evaluate Jacobian with AD
                J = AutoDiff.jacobian!(polar, ujacobianAD, cache)
                # Matpower Jacobian
                Jmat_u = ExaPF.matpower_jacobian(polar, Control(), cons, V)

                # Compare with FiniteDiff
                function jac_fd_u(u)
                    cache.vmag[ref] .= u[1:nref]
                    cache.vmag[pv] .= u[nref+1:npv+nref]
                    cache.pinj[pv] .= u[nref+npv+1:end]
                    c = zeros(m)
                    cons(polar, c, cache.vmag, cache.vang, cache.pinj, cache.qinj)
                    return c
                end
                u = [cache.vmag[ref]; cache.vmag[pv]; cache.pinj[pv]]
                Jd = FiniteDiff.finite_difference_jacobian(jac_fd_u, u)
                @test size(J) == (m, length(u))
                @test isapprox(Jd, ujacobianAD.J, rtol=1e-5)
                @test isapprox(Jmat_u, ujacobianAD.J, rtol=1e-6)
                @test isapprox(∂cons.∂u, ujacobianAD.J' * tgt, rtol=1e-6)
            end

            # ADJOINT
            ExaPF.adjoint!(polar, pbm, tgt, c, cache)
            function test_fd(vvm)
                cache.vmag .= vvm[1:nbus]
                cache.vang .= vvm[1+nbus:2*nbus]
                cons(polar, c, cache.vmag, cache.vang, cache.pinj, cache.qinj)
                return dot(c, tgt)
            end
            vv = [cache.vmag; cache.vang]
            vv_fd = FiniteDiff.finite_difference_gradient(test_fd, vv)
            @test isapprox(vv_fd[1:nbus], ∂cons.∂vm, rtol=1e-6)
            @test isapprox(vv_fd[1+nbus:2*nbus], ∂cons.∂va, rtol=1e-6)
        end
    end
end


text:
#EasyPlotInspect AbstractBuilder interface implementation
#-------------------------------------------------------------------------------

#==Types
===============================================================================#
mutable struct Builder <: EasyPlot.AbstractBuilder
	postproc::Optional{Function}
	#TODO: Support passing PlotLayout by argument???
end
EasyPlot.AbstractBuilder(::DS{:InspectDR}) = Builder #Register builder

#==Constructor interface
===============================================================================#
#Use same builder irrespective of target application:
function EasyPlot.getbuilder(::Target{T}, ::Type{Builder}; postproc=nothing) where T
	return Builder(postproc)
end

#==I/O interface
===============================================================================#
function EasyPlot._show(io::IO, mime::MIME, opt::EasyPlot.ShowOptions, mplot::InspectDR.Multiplot)
	if EasyPlot.isauto(opt.dim)
		InspectDR.show(io, mime, mplot) #Uses dimension values in mplot
	elseif isa(opt.dim, EasyPlot.CanvasDim)
		#Access internal show function:
		InspectDR._show(io, mime, mplot, Float64(opt.dim.w), Float64(opt.dim.h))
	else #Specified individual plot dimensions.
		#Use InspectDR's h/v-alloc (allocates space for title, etc)
		layout = deepcopy(mplot.layout)
			layout[:halloc_plot] = opt.dim.w
			layout[:valloc_plot] = opt.dim.h
		mplot = InspectDR.Multiplot(mplot.title, mplot.subplots, layout)
		InspectDR.show(io, mime, mplot)
	end
	return
end
EasyPlot._show(io::IO, mime::MIME, opt::EasyPlot.ShowOptions, plot::InspectDR.GtkPlot) =
	EasyPlot._show(io, mime, opt, plot.src)

EasyPlot._showable(mime::MIME, b::Builder) =
	hasmethod(show, (IO, typeof(mime), InspectDR.Multiplot))

#==Display interface
===============================================================================#
EasyPlot.displaygui(mplot::InspectDR.Multiplot) = display(InspectDR.GtkDisplay(), mplot)
EasyPlot.displaygui(gplot::InspectDR.GtkPlot) = gplot #Should we force a display??

#==Plot building functions
===============================================================================#
function _build(eplot::EasyPlot.Plot, theme::EasyPlot.Theme)
	iplot = InspectDR.Plot2D()
	fold = isa(eplot.xaxis, EasyPlot.FoldedAxis) ? eplot.xaxis : nothing
	layout = iplot.layout #Reference
		layout[:enable_legend] = eplot.legend

	#x-axis properties:
	iplot.xext_full = InspectDR.PExtents1D(eplot.xext.min, eplot.xext.max)
	iplot.xscale = InspectDR.AxisScale(scalemap[Symbol(eplot.xaxis)])

	#Want more resolution on y-axis than default:
	#TODO: is there a better way???
	_yaxisscale(s::Symbol) = InspectDR.AxisScale(s, tgtmajor=8, tgtminor=2)

	#y-strip properties:
	iplot.strips = [] #Reset
	for srcstrip in eplot.ystriplist
		strip = InspectDR.GraphStrip()
		push!(iplot.strips, strip)
		strip.yscale = _yaxisscale(scalemap[srcstrip.scale])
		strip.yext_full = InspectDR.PExtents1D(srcstrip.ext.min, srcstrip.ext.max)
		strip.grid = mapgrid(srcstrip.grid)
	end

	#Apply x/y labels:
	a = iplot.annotation
	a.title = eplot.title
	a.xlabel = eplot.xlabel
	a.ylabels = String[strip.axislabel for strip in eplot.ystriplist]
	a.ystriplabels = String[strip.striplabel for strip in eplot.ystriplist]

	#Add data using EasyPlot.AbstractWfrmBuilder interface:
	wfrmbuilder = WfrmBuilder(iplot, theme, fold)
	for (i, wfrm) in enumerate(eplot.wfrmlist)
		EasyPlot.addwfrm(wfrmbuilder, wfrm, i)
	end

	#Add extra annotation objects:
	for a in eplot.annot
		addannot(theme, iplot, a)
	end

	return iplot
end

#Method build(::Multiplot, PlotCollection) needed for live-slice:
function EasyPlot.build(mplot::InspectDR.Multiplot, ecoll::EasyPlot.PlotCollection)
	layout = mplot.layout #Reference
		layout[:ncolumns] = ecoll.ncolumns
	mplot.title = ecoll.title
	mplot.bblist = deepcopy(ecoll.bblist)

	mplot.subplots=[] #Start fresh in case being overwritten
	for eplot in ecoll.plotlist
		plot = _build(eplot, ecoll.theme)
		add(mplot, plot)
	end

	return mplot
end

function EasyPlot.build(b::Builder, ecoll::EasyPlot.PlotCollection)
	mplot = InspectDR.Multiplot()
	return EasyPlot.build(mplot, ecoll)
end

#Last line