text:
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# Description
#
#   Tests of the configuration framework.
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

@testset "Configurations" begin
    data = [1 2 3
            4 5 6]

    conf1 = set_pt_conf(tf = tf_markdown)
    conf2 = set_pt_conf(tf = tf_ascii_dots, formatters = ft_printf("%5.3d"))
    set_pt_conf!(conf2, hlinetf_s = :none)

    expected = """
| Col. 1 | Col. 2 | Col. 3 |
|--------|--------|--------|
|      1 |      2 |      3 |
|      4 |      5 |      6 |
"""

    result = pretty_table_with_conf(conf1, String, data)
    @test result == expected

    expected = """
: Col. 1 : Col. 2 : Col. 3 :
:    001 :    002 :    003 :
:    004 :    005 :    006 :
"""

    clear_pt_conf!(conf2)
    expected = pretty_table(String, data)
    result = pretty_table_with_conf(conf2, String, data)

    @test result == expected
end

@testset "@pt" begin
    # To get the output of the macro @pt, we must redirect the stdout.
    old_stdout = stdout
    in, out    = redirect_stdout()

    # The configurations must not interfere with the printings of any type
    # except for the `Dict`.
    @ptconf sortkeys = true

    # Test 1
    # --------------------------------------------------------------------------

    expected = """
.......................
: 1 :     2 :   3 : 4 :
:...:.......:.....:...:
: 1 : false : 1.0 : 1 :
: 2 :  true : 2.0 : 2 :
: 3 : false : 3.0 : 3 :
: 4 :  true : 4.0 : 4 :
: 5 : false : 5.0 : 5 :
: 6 :  true : 6.0 : 6 :
:...:.......:.....:...:
"""

    @ptconf tf = tf_ascii_dots
    @pt :header = ["1", "2", "3", "4"] data

    result = String(readavailable(in))
    @test result == expected

    # Test 2
    # --------------------------------------------------------------------------

    expected = """
╭────────┬────────┬────────┬────────╮
│ Col. 1 │ Col. 2 │ Col. 3 │ Col. 4 │
├────────┼────────┼────────┼────────┤
│   1    │ false  │  1.0   │   1    │
│   2    │  true  │  2.0   │   2    │
│   3    │ false  │  3.0   │   3    │
│   4    │  true  │  4.0   │   4    │
│   5    │ false  │  5.0   │   5    │
│   6    │  true  │  6.0   │   6    │
╰────────┴────────┴────────┴────────╯
"""

    @ptconf tf = tf_unicode_rounded
    @ptconf alignment = :c
    @pt data

    result = String(readavailable(in))
    @test result == expected

    # Test 3
    # --------------------------------------------------------------------------

    expected = """
.----------.----------.
| Column 1 | Column 2 |
|   Sub. 1 |   Sub. 2 |
:----------+----------:
|        1 |        2 |
|        3 |        4 |
|        5 |        6 |
'----------'----------'
"""

header = (["Column 1", "Column 2"], ["Sub. 1", "Sub. 2"])

    @ptconfclean
    @ptconf tf = tf_ascii_rounded
    @pt :header = header [1 2; 3 4; 5 6]

    result = String(readavailable(in))
    @test result == expected

    # Test 4
    # --------------------------------------------------------------------------

    expected = """
.-------.---------------------.
| Keys  | Values              |
| Int64 | String              |
:-------+---------------------:
| 1     | São José dos Campos |
| 2     | SP                  |
| 3     | Brasil              |
'-------'---------------------'
"""

    @ptconf sortkeys = true
    @ptconf alignment = :l
    @pt d = Dict(
        Int64(1) => "São José dos Campos",
        Int64(2) => "SP",
        Int64(3) => "Brasil"
    )

    result = String(readavailable(in))
    @test result == expected

    # Restore the original stdout.
    close(in)
    close(out)
    redirect_stdout(old_stdout)

    # The expression after `@pt` must be evaluated. Hence, `d` must be a dict
    # with the defined elements.
    @test d isa Dict
    @test d[1] == "São José dos Campos"
    @test d[2] == "SP"
    @test d[3] == "Brasil"

    # Clean configurations to avoid test failures if this is run in the same
    # section.
    @ptconfclean
end

@testset "Issue #107" begin
    # To get the output of the macro @pt, we must redirect the stdout.
    old_stdout = stdout
    in, out    = redirect_stdout()

    tf_compact2 = TextFormat(
        up_right_corner = '─',
        up_left_corner      = '─',
        bottom_left_corner  = '─',
        bottom_right_corner = '─',
        up_intersection     = '─',
        left_intersection   = '─',
        right_intersection  = '─',
        middle_intersection = '─',
        bottom_intersection = '─',
        column              = ' ',
        row                 = '─',
        hlines              = [:begin, :header, :end],
        vlines              = :all
    );

    expected = """
─────────────────────────────────────
  Col. 1   Col. 2   Col. 3   Col. 4
─────────────────────────────────────
       1    false      1.0        1
       2     true      2.0        2
       3    false      3.0        3
       4     true      4.0        4
       5    false      5.0        5
       6     true      6.0        6
─────────────────────────────────────
"""

    @ptconf tf = tf_compact2
    @pt data

    result = String(readavailable(in))
    @test result == expected

    # Restore the original stdout.
    close(in)
    close(out)
    redirect_stdout(old_stdout)

    @ptconfclean
end


text:
@testset "Test total multi order indices" begin

# Nx = 1
midxs = totalorder([0])
@test midxs == reshape([0],(1,1))
midxs = totalorder([1])
@test midxs == reshape([0; 1],(2,1))
midxs = totalorder([3])
@test midxs == reshape([0; 1; 2; 3],(4,1))

#Nx = 2

midxs = totalorder([0; 0])
@test midxs == reshape([0; 0],(1,2))
midxs = totalorder([1; 0])
@test midxs == [0 0; 1 0]
midxs = totalorder([3;4])
@test midxs ==
     [0     0
     0     1
     0     2
     0     3
     0     4
     1     0
     1     1
     1     2
     1     3
     2     0
     2     1
     2     2
     3     0
     3     1]

# Nx = 3

midxs = totalorder([0; 0; 0])
@test midxs == reshape([0; 0; 0],(1,3))
midxs = totalorder([0; 1; 0])
@test midxs == [0 0 0; 0 1 0]

midxs = totalorder([2;4;3])

@test midxs ==
[0     0     0
0     0     1
0     0     2
0     0     3
0     1     0
0     1     1
0     1     2
0     1     3
0     2     0
0     2     1
0     2     2
0     3     0
0     3     1
0     4     0
1     0     0
1     0     1
1     0     2
1     0     3
1     1     0
1     1     1
1     1     2
1     2     0
1     2     1
1     3     0
2     0     0
2     0     1
2     0     2
2     1     0
2     1     1
2     2     0]
end

ext: jl


text:
using StatPlots, StatsBase, DataFrames, RDatasets, Distributions, ProgressMeter#, Iterators

doc_path(args...) = joinpath(@__DIR__, args...)

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

gr()
# define the Lorenz attractor
mutable struct Lorenz
    dt; σ; ρ; β; x; y; z
end

function step!(l::Lorenz)
    dx = l.σ*(l.y - l.x)       ; l.x += l.dt * dx
    dy = l.x*(l.ρ - l.z) - l.y ; l.y += l.dt * dy
    dz = l.x*l.y - l.β*l.z     ; l.z += l.dt * dz
end

attractor = Lorenz((dt = 0.02, σ = 10., ρ = 28., β = 8//3, x = 1., y = 1., z = 1.)...)

# initialize a 3D plot with 1 empty series
plt = plot3d(1, xlim=(-25,25), ylim=(-25,25), zlim=(0,50),
            title = "Lorenz Attractor", marker = 2)

# build an animated gif by pushing new points to the plot, saving every 10th frame
anim = @gif for i=1:1500
    step!(attractor)
    push!(plt, attractor.x, attractor.y, attractor.z)
end every 10

mv(anim.filename, doc_path("index", "lorenz_attractor.gif"), force = true)

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

pyplot(leg=false, ticks=nothing) #change to the pyplot backend and define some defaults
x = y = range(-5, stop = 5, length = 40)
zs = zeros(0,40)
n = 100

# create a progress bar for tracking the animation generation
prog = Progress(n,1)

anim = @gif for i in range(0, stop = 2π, length = n)
    f(x,y) = sin(x + 10sin(i)) + cos(y)

    # create a plot with 3 subplots and a custom layout
    l = Plots.@layout [a{0.7w} b; c{0.2h}]
    p = plot(x, y, f, st = [:surface, :contourf], layout=l)

    # induce a slight oscillating camera angle sweep, in degrees (azimuth, altitude)
    plot!(p[1], camera=(15*cos(i), 40))

    # add a tracking line
    fixed_x = zeros(40)
    z = map(f, fixed_x, y)
    plot!(p[1], fixed_x, y, z, line = (:black, 5, 0.2))
    vline!(p[2], [0], line = (:black, 5))

    # add to and show the tracked values over time
    global zs = vcat(zs, z')
    plot!(p[3], zs, alpha = 0.2, palette = cgrad(:blues).colors)

    # increment the progress bar
    next!(prog)
end

mv(anim.filename, doc_path("index", "waves.gif"), force = true)

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

gr(leg=false, bg=:lightgrey)

# Create a filled contour and boxplot side by side.
plot(contourf(randn(10,20)), boxplot(rand(1:4,1000),randn(1000)))

# Add a histogram inset on the heatmap.
# We set the (optional) position relative to bottom-right of the 1st subplot.
# The call is `bbox(x, y, width, height, origin...)`, where numbers are treated as "percent of parent"
histogram!(randn(1000), inset = (1, bbox(0.05,0.05,0.5,0.25,:bottom,:right)), ticks=nothing, subplot=3, bg_inside=nothing)

# Add sticks floating in the window (inset relative to the window, as opposed to being relative to a subplot)
sticks!(randn(100), inset = bbox(0,-0.2,200Plots.px,100Plots.px,:center), ticks=nothing, subplot=4)
png(doc_path("layout", "layout_5"))
theme(:default)

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

gr()
# load a dataset
iris = dataset("datasets", "iris");

# Scatter plot with some custom settings
@df iris scatter(:SepalLength, :SepalWidth, group=:Species,
    title = "My awesome plot",
    xlabel = "Length", ylabel = "Width",
    m=(0.5, [:cross :hex :star7], 12),
    bg=RGB(.2,.2,.2))

png(doc_path("index", "iris"))

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

# iris = dataset("datasets","iris")
@df iris marginalhist(:PetalLength, :PetalWidth)
png(doc_path("tutorial", "plot_recipes"))

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

@df iris scatter(:SepalLength, :SepalWidth, group=:Species,
    m=(0.5, [:+ :h :star7], 12), bg=RGB(.2,.2,.2))
png(doc_path("input", "dataframes"))

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

dfr = DataFrame(a = 1:10, b = 10*rand(10), c = 10 * rand(10))
# Plot the DataFrame by declaring the points by the column names
@df dfr plot(:a, [:b :c]) # x = :a, y = [:b :c]. Notice this is two columns!
png(doc_path("tutorial", "user_recipes_1"))

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

@df dfr scatter(:a, :b, title="My DataFrame Scatter Plot!") # x = :a, y = :b
png(doc_path("tutorial", "user_recipes_2"))

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

gr()
x = 1:10; y = rand(10); # These are the plotting data
plot(x,y)
png(doc_path("tutorial", "lines_1"))

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

x = 1:10; y = rand(10,2) # 2 columns means two lines
plot(x,y)
png(doc_path("tutorial", "lines_2"))

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

z = rand(10)
plot!(x,z)
png(doc_path("tutorial", "lines_3"))

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

x = 1:10; y = rand(10,2) # 2 columns means two lines
p = plot(x,y)
z = rand(10)
plot!(p,x,z)
png(doc_path("tutorial", "lines_4"))

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

x = 1:10; y = rand(10,2) # 2 columns means two lines
plot(x,y,title="Two Lines",label=["Line 1" "Line 2"],lw=3)
png(doc_path("tutorial", "attr_1"))

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

xlabel!("My x label")
png(doc_path("tutorial", "attr_2"))

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

x = 1:10; y = rand(10,2) # 2 columns means two lines
plotlyjs() # Set the backend to Plotly
plot(x,y,title="This is Plotted using Plotly")
png(doc_path("tutorial", "backends_1"))

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

gr() # Set the backend to GR
plot(x,y,title="This is Plotted using GR") # This plots using GR
png(doc_path("tutorial", "backends_2"))

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

gr() # We will continue onward using the GR backend
plot(x,y,seriestype=:scatter,title="My Scatter Plot")
png(doc_path("tutorial", "scatter_1"))

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

gr()
scatter(x,y,title="My Scatter Plot")
png(doc_path("tutorial", "scatter_2"))

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

y = rand(10,4)
plot(x,y,layout=(4,1))
png(doc_path("tutorial", "subplots_1"))

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

p1 = plot(x,y) # Make a line plot
p2 = scatter(x,y) # Make a scatter plot
p3 = plot(x,y,xlabel="This one is labelled",lw=3,title="Subtitle")
p4 = histogram(x,y) # Four histograms each with 10 points? Why not!
plot(p1,p2,p3,p4,layout=(2,2),legend=false)
png(doc_path("tutorial", "subplots_2"))

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

plot(Normal(3,5),lw=3)
png(doc_path("tutorial", "type_recipes"))

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

y = rand(100,4) # Four series of 100 points each
violin(["Series 1" "Series 2" "Series 3" "Series 4"],y,leg=false)
png(doc_path("tutorial", "series_recipes_1"))

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

boxplot!(["Series 1" "Series 2" "Series 3" "Series 4"],y,leg=false)
png(doc_path("tutorial", "series_recipes_2"))

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

gr()

# 10 data points in 4 series
xs = 0 : 2π/10 : 2π
data = [sin.(xs) cos.(xs) 2sin.(xs) 2cos.(xs)]

# We put labels in a row vector: applies to each series
labels = ["Apples" "Oranges" "Hats" "Shoes"]

# Marker shapes in a column vector: applies to data points
markershapes = [:circle, :star5]

# Marker colors in a matrix: applies to series and data points
markercolors = [:green :orange :black :purple
            :red   :yellow :brown :white]

plot(xs, data, label = labels, shape = markershapes, color = markercolors,
 markersize = 10)

png(doc_path("input", "columns_are_series"))

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

plotlyjs()

function rectangle_from_coords(xb,yb,xt,yt)
    [
        xb yb
        xt yb
        xt yt
        xb yt
        xb yb
        NaN NaN
    ]
end

some_rects=[
    rectangle_from_coords(1 ,1 ,5 ,5 )
    rectangle_from_coords(10,10,15,15)
    ]
other_rects=[
    rectangle_from_coords(1 ,10,5 ,15)
    rectangle_from_coords(10,1 ,15,5 )
    ]

plot(some_rects[:,1], some_rects[:,2],label="some group")
plot!(other_rects[:,1], other_rects[:,2],label="other group")

png(doc_path("input", "unconnected"))

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

# itr = repeatedly(()->rand(10), 20)
# anim = animate(itr, ylims=(0,1), c=:red, fps=5)
# gif(anim, doc_path("animations", "rand_anim.gif"), fps = 15)

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

gr(size=(300,300), leg=false)

@userplot MyCount
Plots.@recipe function f(mc::MyCount)
    # get the array from the args field
    arr = mc.args[1]

    T = typeof(arr)
    if T.parameters[1] == Float64
        seriestype := :histogram
        arr
    else
        seriestype := :bar
        cm = countmap(arr)
        x = sort!(collect(keys(cm)))
        y = [cm[xi] for xi=x]
        x, y
    end
end
mycount(rand(500))

png(doc_path("contributing", "my_count_1"))

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

mycount(rand(["A","B","C"],100))
png(doc_path("contributing", "my_count_2"))

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

mycount(rand(1:500, 500))
png(doc_path("contributing", "my_count_3"))

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

pyplot()
plot(x, y, line = (0.5, [4 1 0], [:path :scatter :density]),
    marker=(10, 0.5, [:none :+ :none]), fill=0.5,
    orientation = :h, title = "My title")
png(doc_path("pipeline", "pipeline_1"))

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

gr()
mutable struct MyVecWrapper
    v::Vector{Float64}
end
mvw = MyVecWrapper(rand(100))

@recipe function f(mvw::MyVecWrapper)
    markershape --> :circle
    markersize  --> 30
    mvw.v
end

plot(
    plot(mvw.v),
    plot(mvw)
    )

png(doc_path("pipeline", "pipeline_2"))

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

scatter(rand(100), group = rand(1:3, 100), marker = (10,0.3,[:s :o :x]))
png(doc_path("pipeline", "pipeline_3"))

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

# create a 2x2 grid, and map each of the 4 series to one of the subplots
plot(rand(100,4), layout = 4)
png(doc_path("layout", "layout_1"))

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

# create a 4x1 grid, and map each of the 4 series to one of the subplots
plot(rand(100,4), layout = (4,1))
png(doc_path("layout", "layout_2"))

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

plot(rand(100,4), layout = grid(4,1,heights=[0.1,0.4,0.4,0.1]))
png(doc_path("layout", "layout_3"))

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

l = Plots.@layout [  a{0.3w} [grid(3,3)
                                 b{0.2h} ]]
plot(
    rand(10,11),
    layout = l, label = "", seriestype = [:bar :scatter :path],
    title = ["($i)" for j = 1:1, i=1:11], titleloc = :right, titlefont = font(8)
    )
png(doc_path("layout", "layout_4"))


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

mutable struct RetentionPolicyParameters <: SwaggerModel
    days::Any # spec type: Union{ Nothing, Int32 } # spec name: days
    enabled::Any # spec type: Union{ Nothing, Bool } # spec name: enabled

    function RetentionPolicyParameters(;days=nothing, enabled=false)
        o = new()
        validate_property(RetentionPolicyParameters, Symbol("days"), days)
        setfield!(o, Symbol("days"), days)
        validate_property(RetentionPolicyParameters, Symbol("enabled"), enabled)
        setfield!(o, Symbol("enabled"), enabled)
        o
    end
end # type RetentionPolicyParameters

const _property_map_RetentionPolicyParameters = Dict{Symbol,Symbol}(Symbol("days")=>Symbol("days"), Symbol("enabled")=>Symbol("enabled"))
const _property_types_RetentionPolicyParameters = Dict{Symbol,String}(Symbol("days")=>"Int32", Symbol("enabled")=>"Bool")
Base.propertynames(::Type{ RetentionPolicyParameters }) = collect(keys(_property_map_RetentionPolicyParameters))
Swagger.property_type(::Type{ RetentionPolicyParameters }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_RetentionPolicyParameters[name]))}
Swagger.field_name(::Type{ RetentionPolicyParameters }, property_name::Symbol) =  _property_map_RetentionPolicyParameters[property_name]

function check_required(o::RetentionPolicyParameters)
    true
end

function validate_property(::Type{ RetentionPolicyParameters }, name::Symbol, val)
end


text:
const DS = DataStructure101

export MinMaxHeap
export pop_min!, pop_max!, bubble_up!, push_bubble!

mutable struct MinMaxHeap <: DS.Heap
    data::Vector{Int64}
    heapified::Bool

    MinMaxHeap() = new(Int64[], true)
end

is_min_level(heap::MinMaxHeap, i::Int64) = isodd(DS.level(heap, i))

Base.minimum(heap::MinMaxHeap) = DS.heapified(heap) ? heap.data[1] : throw("Not Heap")

function Base.maximum(heap::MinMaxHeap)
    !DS.heapified(heap) && throw("Not Heap")
    return (heap.data[2] > heap.data[3] ? heap.data[2] : heap.data[3])
end

function min_heapify!(heap::MinMaxHeap, i::Int64, n::Int64)
    smallest_i = i

    right_i = DS.right_child(heap, i)
    right_grand_right_i = DS.right_child(heap, right_i)
    right_grand_left_i = DS.left_child(heap, right_i)
    left_i = DS.left_child(heap, i)
    left_grand_right_i = DS.right_child(heap, left_i)
    left_grand_left_i = DS.left_child(heap, left_i)

    (right_i <= n && heap[i] > heap[right_i]) &&
        (smallest_i = right_i)
    (right_grand_right_i <= n && heap[smallest_i] > heap[right_grand_right_i]) &&
        (smallest_i = right_grand_right_i)
    (right_grand_left_i <= n && heap[smallest_i] > heap[right_grand_left_i]) &&
        (smallest_i = right_grand_left_i)
    (left_i <= n && heap[smallest_i] > heap[left_i]) &&
        (smallest_i = left_i)
    (left_grand_right_i <= n && heap[smallest_i] > heap[left_grand_right_i]) &&
        (smallest_i = left_grand_right_i)
    (left_grand_left_i <= n && heap[smallest_i] > heap[left_grand_left_i]) &&
        (smallest_i = left_grand_left_i)

    (smallest_i == i) && return

    if smallest_i != right_i && smallest_i != left_i # smallest is grand child
        (heap[smallest_i] >= heap[i]) && return

        heap[smallest_i], heap[i] = heap[i], heap[smallest_i]
        p = DS.parent(heap, smallest_i)
        if heap[smallest_i] > heap[p]
            heap[smallest_i], heap[p] = heap[p], heap[smallest_i]
        end
        min_heapify!(heap, smallest_i, n)
    elseif heap[smallest_i] < heap[i] # smallest is child
        heap[smallest_i], heap[i] = heap[i], heap[smallest_i]
    end
end

function max_heapify!(heap::MinMaxHeap, i::Int64, n::Int64)
    largest_i = i

    right_i = DS.right_child(heap, i)
    right_grand_right_i = DS.right_child(heap, right_i)
    right_grand_left_i = DS.left_child(heap, right_i)
    left_i = DS.left_child(heap, i)
    left_grand_right_i = DS.right_child(heap, left_i)
    left_grand_left_i = DS.left_child(heap, left_i)

    (right_i <= n && heap[i] < heap[right_i]) &&
        (largest_i = right_i)
    (right_grand_right_i <= n && heap[largest_i] < heap[right_grand_right_i]) &&
        (largest_i = right_grand_right_i)
    (right_grand_left_i <= n && heap[largest_i] < heap[right_grand_left_i]) &&
        (largest_i = right_grand_left_i)
    (left_i <= n && heap[largest_i] < heap[left_i]) &&
        (largest_i = left_i)
    (left_grand_right_i <= n && heap[largest_i] < heap[left_grand_right_i]) &&
        (largest_i = left_grand_right_i)
    (left_grand_left_i <= n && heap[largest_i] < heap[left_grand_left_i]) &&
        (largest_i = left_grand_left_i)

    (largest_i == i) && return

    if largest_i != right_i && largest_i != left_i # largest is grand child
        (heap[largest_i] <= heap[i]) && return

        heap[largest_i], heap[i] = heap[i], heap[largest_i]
        p = DS.parent(heap, largest_i)
        if heap[largest_i] < heap[p]
            heap[largest_i], heap[p] = heap[p], heap[largest_i]
        end
        max_heapify!(heap, largest_i, n)
    elseif heap[largest_i] > heap[i] # largest is child
        heap[largest_i], heap[i] = heap[i], heap[largest_i]
    end
end

function heapify!(heap::MinMaxHeap, i::Int64, n::Int64)
    return is_min_level(heap, i) ? min_heapify!(heap, i, n) : max_heapify!(heap, i, n)
end

function pop_min!(heap::MinMaxHeap)
    !DS.heapified(heap) && throw("Not Heap")

    len = length(heap)
    heap[1], heap[len] = heap[len], heap[1]
    value = pop!(heap.data)
    heapify!(heap, 1, len-1)

    return value
end

function pop_max!(heap::MinMaxHeap)
    !DS.heapified(heap) && throw("Not Heap")

    index = heap.data[2] > heap.data[3] ? 2 : 3

    len = length(heap)
    heap[index], heap[len] = heap[len], heap[index]
    value = pop!(heap.data)
    heapify!(heap, index, len-1)

    return value
end

function min_bubble_up!(heap::MinMaxHeap, i::Int64)
    gp = DS.parent(heap, DS.parent(heap, i))
    !(gp > 0 && heap[i] < heap[gp]) && return

    heap[i], heap[gp] = heap[gp], heap[i]
    min_bubble_up!(heap, gp)
end

function max_bubble_up!(heap::MinMaxHeap, i::Int64)
    gp = DS.parent(heap, DS.parent(heap, i))
    !(gp > 0 && heap[i] > heap[gp]) && return

    heap[i], heap[gp] = heap[gp], heap[i]
    max_bubble_up!(heap, gp)
end

function bubble_up!(heap::MinMaxHeap, i::Int64)
    (i <= 1) && return

    p = DS.parent(heap, i)
    if is_min_level(heap, i)
        if heap[i] > heap[p]
            heap[i], heap[p] = heap[p], heap[i]
            max_bubble_up!(heap, p)
        else
            min_bubble_up!(heap, i)
        end
    else
        if heap[i] < heap[p]
            heap[i], heap[p] = heap[p], heap[i]
            min_bubble_up!(heap, p)
        else
            max_bubble_up!(heap, i)
        end
    end
end

function push_bubble!(heap::MinMaxHeap, v::Int64)
    push!(heap, v)
    bubble_up!(heap, length(heap))
    heap.heapified = true
end


text:
@service S3
struct MinioConfig <: AbstractAWSConfig
    endpoint::String
    region::String
    creds
end
struct SimpleCredentials
    access_key_id::String
    secret_key::String
    token::String
end

AWS.region(c::MinioConfig) = c.region
AWS.credentials(c::MinioConfig) = c.creds
AWS.check_credentials(c::SimpleCredentials) = c

function AWS.generate_service_url(aws::MinioConfig, service::String, resource::String)
    service == "s3" || throw(ArgumentError("Can only handle s3 requests to Minio"))
    return string(aws.endpoint, resource)
end

AWS.global_aws_config(MinioConfig("http://127.0.0.1:9000", "aregion", SimpleCredentials("minio", "minio123", "")))
datadir = joinpath(dirname(pathof(AWS)),"..","data")

# Create bucket and place objects in it
S3.create_bucket("anewbucket")
S3.put_object("anewbucket","myobject",Dict("body"=>"Hi from Minio"))
S3.put_object("anewbucket","empty")
S3.put_object("anewbucket","foo/bar",Dict("body"=>"a nested object"))
S3.put_object("anewbucket","foo/baz",Dict("body"=>"a secondnested object"))

# Test retrieving an object
@test S3.get_object("anewbucket","myobject") |> String == "Hi from Minio"

# Test listing
objs = S3.list_objects_v2("anewbucket")
@test length(objs["Contents"]) == 4

# Test api version 2 of list-objects
objs_truncated = S3.list_objects_v2("anewbucket", Dict("max-keys"=>2))
@test length(objs_truncated["Contents"]) == 2
@test objs_truncated["IsTruncated"] == "true"
@test haskey(objs_truncated,"NextContinuationToken")

# Test listing with prefixes
objs_prefix = S3.list_objects_v2("anewbucket", Dict("prefix"=>"", "delimiter"=>"/"))
@test length(objs_prefix["Contents"]) == 2
@test sort(getindex.(objs_prefix["Contents"],"Key")) == ["empty","myobject"]
@test objs_prefix["CommonPrefixes"]["Prefix"] == "foo/"

# And delete all objects and the bucket
objs = S3.list_objects_v2("anewbucket")

for obj in objs["Contents"]
    S3.delete_object("anewbucket",obj["Key"])
end

S3.delete_bucket("anewbucket")

@test isempty(filter(!isequal(".minio.sys"),readdir(datadir)))


text:
# Eric S. Tellez <eric.tellez@infotec.mx>

#Pkg.add("GZip")
#Pkg.add("Glob")
#Pkg.add("JSON")

import JSON
import Glob

include("textmodel.jl")
include("io.jl")

function normpatterns(patlist::Vector{Vector{String}}, config::TextConfig)
    A = Vector{String}[]
    for patterns in patlist
        B = String[]
        for pat in patterns
            T = tokenize(pat, config)
            length(T) > 0 && push!(B, join(T, ' '))
        end
        length(B) > 0 && push!(A, B)
    end

    Set(A)
end

function normpatternsset(patlist::Vector{Vector{String}}, config::TextConfig)
    A = Vector{Set{String}}[]
    for patterns in patlist
        B = Set{String}[]
        for pat in patterns
            T = tokenize(pat, config)
            length(T) > 0 && push!(B, Set(T))
        end
        length(B) > 0 && push!(A, B)
    end

    Set(A)
end

function intersectmatch(fun, input, config::TextConfig, sep, key, patlist::Vector{Vector{String}})
    patlist = normpatternsset(patlist, config)

    while !eof(input)
        arr = split(rstrip(readline(input)), sep)
        if key < 0
            tokens = tokenize(arr[length(arr)+key+1], config) |> Set
        else
            tokens = tokenize(arr[key], config) |> Set
        end

        matches = 0
        for (i, patterns) in enumerate(patlist)
            for pat in patterns
                iset = intersect(tokens, pat)
                if length(iset) == length(pat)
                    matches += 1
                    break
                end
            end
            matches != i && break
        end

        matches == length(patlist) && fun(arr)
    end
end

function kerrorsmatch{T1 <: Any, T2 <: Any}(a::T1, b::T2, errors::Int)::Bool
    # if length(a) < length(b)
    #     a, b = b, a
    # end

    alen::Int = length(a)
    blen::Int = length(b)

    alen == 0 && return alen == blen
    blen == 0 && return true

    C::Vector{Int} = Vector{Int}(0:blen)

    for i in 1:alen
	prevA::Int = 0
	prevC::Int = C[1]
	j::Int = 1

	while j <= blen
	    cost::Int = 1
	    @inbounds if a[i] == b[j]
		cost = 0
	    end
	    @inbounds C[j] = prevA
	    j += 1
	    @inbounds prevA = min(C[j]+1, prevA+1, prevC+cost)
	    @inbounds prevC = C[j]
	end
	@inbounds C[j] = prevA
        if prevA <= errors
            return true
        end
    end

    return false
end

function kerrorsmatch(fun, input, config::TextConfig, sep, key, patlist::Vector{Vector{String}}, maxerrors::Int=1)
    # config.stem = false
    patlist = normpatterns(patlist, config)

    while !eof(input)
        arr = split(rstrip(readline(input)), sep)
        if key < 0
            text = normtext(arr[length(arr)+key+1], config)
        else
            text = normtext(arr[key], config)
        end

        matches = 0
        for (i, patterns) in enumerate(patlist)
            for pat in patterns
                if kerrorsmatch(text, pat, maxerrors)
                    matches += 1
                    break
                end
            end
            matches != i && break
        end

        matches == length(patlist) && fun(arr)
    end
end

function substringmatch(fun, input, config::TextConfig, sep, key, patlist::Vector{Vector{String}})
    # patlist = [[normtext(pat, config) for pat in patterns] for patterns in patlist]
    patlist = normpatterns(patlist, config)

    while !eof(input)
        arr = split(rstrip(readline(input)), sep)
        if key < 0
            text = normtext(arr[length(arr)+key+1], config)
        else
            text = normtext(arr[key], config)
        end

        matches = 0
        for (i, patterns) in enumerate(patlist)
            for pat in patterns
                if contains(text, pat)
                    matches += 1
                    break
                end
            end
            matches != i && break
        end

        matches == length(patlist) && fun(arr)
    end
end

function harvesine(p1::Vector{Float64}, p2::Vector{Float64})
    # Tweets use GEOJson format: [longitude, latitude]
    lon1, lat1 = p1
    lon2, lat2 = p2
    2 * 6372.8 * asin(sqrt(sind((lat2-lat1)/2)^2 + cosd(lat1) * cosd(lat2) * sind((lon2 - lon1)/2)^2))
end

function radius(fun, input, sep, key, coordinates)
    center = [x |> Float64 for x in coordinates["coordinates"]]
    distance = coordinates["radius"]

    while !eof(input)
        arr = split(rstrip(readline(input)), sep)
        if key < 0
            _coord = arr[length(arr)+key+1]
        else
            _coord = arr[key]
        end

        _coord == "{}" && continue
        p = JSON.parse(_coord)

        coord = [x |> Float64 for x in p["coordinates"]]

        if harvesine(center, coord) <= distance
            fun(arr)
        end
    end
end

function vocextraction(fun, input, config::TextConfig, sep, key)
    # patlist = [[normtext(pat, config) for pat in patterns] for patterns in patlist]
    thesaurus = Dict{String,Int}()
    while !eof(input)
        arr = split(rstrip(readline(input)), sep)
        if key < 0
            tokens = tokenize(arr[length(arr)+key+1], config)
        else
            tokens = tokenize(arr[key], config)
        end

        for tok in tokens
            thesaurus[tok] = get(thesaurus, tok, 0) + 1
        end
    end

    L = [(v, k) for (k,v) in thesaurus]
    sort!(L, by=(x) -> x[1])
    for x in L
        fun(x)
    end
end

config = TextConfig()
patlist = Vector{String}[]
stopwords = ""
kind = ""
key = -1
sep = "\t"
coordinates = nothing
errors = 1

for arg in ARGS
    arg = strip(arg)
    if arg[1] == '{'
        _config = JSON.parse(arg)
        for (k, v) in JSON.parse(arg)
            setfield!(config, Symbol(k), v)
        end
    elseif arg[1] == '['
        push!(patlist, JSON.parse(arg))
    elseif startswith(arg, "file:")
        push!(patlist, readlines(arg[6:end]))
    elseif startswith(arg, "stopwords:")
        stopwords = arg[length("stopwords:")+1:end]
    else
        if startswith(arg, "substring")
            kind = "substring"
        elseif startswith(arg, "intersect")
            kind = "intersect"
        elseif startswith(arg, "kerror")
            kind = "kerrors"
            if ':' in kind
                errors = parse(Int, split(arg, ':')[2])
            end
        elseif startswith(arg, "voc")
            kind = "voc"
        elseif startswith(arg, "key")
            key = parse(Int, split(arg, ':')[2])
        elseif startswith(arg, "sep")
            key = split(arg, ':')[2]
        elseif startswith(arg, "radius")
            kind = "radius"
            coordinates = JSON.parse(arg[8:end])  ## radius:{"coordinates":[long,lat],"radius":radius}
        else
            error("Unknown command $arg")
        end
    end
end

if length(stopwords) > 0
    config.stopwords = Set([join(normchars(strip(line), config)) for line in readlines(stopwords)])
end

if kind == "substring"
    substringmatch(STDIN, config, sep, key, patlist) do arr
        write(STDOUT, join(arr, sep), '\n')
    end
elseif kind == "intersect"
    intersectmatch(STDIN, config, sep, key, patlist) do arr
        write(STDOUT, join(arr, sep), '\n')
    end
elseif kind == "kerrors"
    kerrorsmatch(STDIN, config, sep, key, patlist, errors) do arr
        write(STDOUT, join(arr, sep), '\n')
    end
elseif kind == "radius"
    radius(STDIN, sep, key, coordinates) do arr
        write(STDOUT, join(arr, sep), '\n')
    end
elseif kind == "voc"
    vocextraction(STDIN, config, sep, key) do arr
        write(STDOUT, join(arr, '\t'), '\n')
    end
else
    info("""
    Usage: julia PatternSearch/matches.jl KIND SEP KEY CONFIG STOPWORDS PAT1 PAT2 ...
    Where

    KIND is substring|intersect|kerrors|voc|radius
    - in the case of kerrors you can specify the maximum number of errors using the syntax kerrors:numerrors
    - the default kind is not specified, it is a mandatory argument
    - radius dumps records intersecting a ball; the center and radius of the ball (in kilometers). It uses the harvesing formulae to compute distances. The syntax is radius:JSON-coordinates
        - JSON-coordinates are of the form {"coordinates": [longitude, latitute], "radius": kilometers}
        - for example,
             - radius:'{"coordinates":[-102.295914,21.918859], "radius": 0.3}'
    - voc dumps the vocabulary's histogram sorted by increasing frequency

    SEP is the separator string
    - the syntax is sep:sepstring, e.g.,
        - sep:"<SEP>" -- a <SEP> string
        - sep:,       -- a single comma
        - sep:\$'\\t'  -- a single tab
    - the tabulator is the default separator

    KEY indicates the id of the column
    - the syntax is key:numcolumn, e.g., key:1
    - negative keys are mapped to numcolumns-abs(key)+1 (so, the last column, -1, is just numcolumns)
    - the default key is the last one, i.e., key:-1

    CONFIG is a json-dictionary representing a TextConfig object, it controls how the text is preprocessed for the match
    - please check PatternSearch/textmodel.jl to check the fields and default values
    - the default value is created with the default constructor of TextConfig

    STOPWORDS indicates the path of the stopwords file
    - the syntax is stopwords:filename

    PAT is a json-list of strings, each string is a pattern in the list
    - PatternSearch/matches.jl basically evaluates a intersection-union tree
    - each PAT defines a list of patterns, the text needs to match at least one to be a candidate (union)
    - a real match is a candidate matching all given PATs (intersection)

    The input is always read from STDIN

    Note: This tool is intended to be used with unix pipes and command line tools like awk, perl, grep, PatternSearch/matches.jl, etc.;
    so a lot of possible features will never be implemented.

    """)
    error("please read the help")
end

max_stars_repo_name: INGEOTEC/PatternAnalysisTools

max_issues_repo_name: INGEOTEC/PatternAnalysisTools

max_forks_repo_name: INGEOTEC/PatternAnalysisTools


text:
_stand_medium_raw_file() = rawdir(RathData, "rath2017___42_MAX_UB_standard_medium.tsv")

function _exp_medium_raw_file(expid)
    expid = string(expid)
    (expid in ["A", "B", "C"]) && (expid = "ABC")
    rawdir(RathData, "rath2017___feed_medium_exp_$(expid).tsv")
end

function _cont_culture_raw_file(expid)
    expid = string(expid)
    rawdir(RathData, "rath2017___cont_exp_$(expid).tsv")
end

_max_invitro_fluxs_raw_file() = rawdir(RathData, "rath2017___max_invitro_fluxs.tsv")


text:
using DataFrames
using CSV

# Structs
"""Struct containing information about nodes and lines."""
struct PowerGrid
    nodes::DataFrame
    lines::DataFrame
    c::Int
    m::Int
    n::Int
    # LY
end

# Functions
"""
    init_power_grid(nodes, lines, settings)

Create a PowerGrid struct from nodes and lines DataFrames and converts all quantities to the p.u. system.

Indexing (c, m, n) could be done better by being based on number of nodes of certain type. It could make sense to also add LY to PowerGrid struct.
"""
function init_power_grid(nodes::DataFrame, lines::DataFrame, settings)
    n = size(nodes, 1)  # total number of nodes
    if "PV" in nodes.type
        c = length(nodes[nodes[:,"type"] .== "PV",:].ID) + 1  # ID of last PV node
    else
        c = 1  # correct choice?
    end
    if "nonlinear" in nodes.type
        m = minimum(nodes[nodes[:,"type"] .== "nonlinear",:].ID)  # ID of first nonlinear node
    else
        m = n + 1   # correct choice?
        print("Warning: No nonlinear node detected.")
    end

    # convert quantities to p.u. system
    nodes.S = nodes.S./settings.base_power
    nodes.P = nodes.P./settings.base_power
    nodes.Q = nodes.Q./settings.base_power
    nodes.X_sh = nodes.X_sh./settings.base_impedance

    lines.R = lines.R./settings.base_impedance
    lines.X = lines.X./settings.base_impedance
    lines.G = lines.G./settings.base_admittance
    lines.B = lines.B./settings.base_admittance

    return PowerGrid(nodes, lines, c, m, n)
end

function import_nodes_from_csv(filename)
    CSV.read(filename, DataFrame)
end

function import_lines_from_csv(filename)
    CSV.read(filename, DataFrame)
end

"""
   create_nodes_manually()

Manually create a nodes DataFrame.

Note that linear nodes are added first, then nonlinear ones.
Within the linear ones, first add PV, then PQ nodes. First node contains the slack.
"""
function create_nodes_manually()
    DataFrame(
        ID = 1:5,
        type = ["slack", "PQ", "PQ", "PQ", "nonlinear"],
        component = ["generator", "lin_load_1", "lin_load_2", nothing, "smps"],
        S = [1000, nothing, nothing, nothing, nothing],
        P = [nothing, 100, 100, 0, 250],
        Q = [nothing, 100, 100, 0, 100],
        X_sh = [0.0001, 0, 0, 0, 0])
end

function create_lines_manually()
    DataFrame(
        ID = 1:5,
        fromID = 1:5,
        toID = [2,3,4,5,1],
        R = [0.01, 0.02, 0.01, 0.01, 0.01],
        X = [0.01, 0.08, 0.02, 0.02, 0.02],
        G = [0, 0, 0, 0, 0],
        B = [0, 0, 0, 0, 0])
end


text:
__precompile__()

module PhantomJS

export renderhtml, execjs

const phantomjspath = joinpath(dirname(@__FILE__),
                               "../deps/usr/bin/phantomjs")

"""
Function `execjs(jsscript::String)` executes script `jsscript` in Phantomjs.
"""
function execjs(jsscript::String)
  mktempdir() do tdir
    jspath = joinpath(tdir, randstring() * ".js")
    open(io -> write(io, jsscript), jspath, "w")

    run(`$phantomjspath $jspath`)
  end

  nothing
end

"""
Function `renderhtml(source::IO; kwargs...)` loads the html provided in argument
`source` and returns the page capture in a `Vector{UInt8}`

Keyword arguments are :

`format` (String, default "png") : output format, possible values are "png",
"jpeg", "pdf", "bmp", "ppm" and "gif"
`width` & `height` (Int) : simulated size of view used for the layout, in pixels.
And output size except if `format` = "pdf" or if `smartSize` is `true`.
`clipToSelector` (String) : if set, the capture will be cropped to the element
identified by the selector
`quality` (Int, default 75) : quality setting for compressed formats (jpeg and
  png)
`background` (String, default `white`) : background color for image, set to
"transparent" if you do not want any color

Pdf format only :
`paperSize` (String, default "A4") : possible values are
"A3", "A4", "A5", "Legal", "Letter", "Tabloid"
`orientation` (String, default "portait") : possible values are
"portrait", "landscape"
`margin` (String or Int, default "0") : Supported dimension units are: 'mm',
'cm', 'in', 'px'. No unit means 'px'.

"""
function renderhtml(source::IO;
                    format::String="png",
                    width::Int=1024,
                    height::Int=800,
                    clipToSelector::String="",
                    quality::Int=75,
                    paperSize::String="A4",
                    orientation::String="portrait",
                    margin::Union{String, Int}=0,
                    background::String="white")

  local result

  mktempdir() do tdir
    htmlpath = joinpath(tdir, randstring() * ".html")
    open(io -> write(io, read(source)), htmlpath, "w")
    htmlpath = replace(htmlpath, "\\", "/")

    destpath = joinpath(tdir, randstring() * ".png")
    destpath = replace(destpath, "\\", "/")

    bgjs = background == "transparent" ? "" :
             """page.evaluate(function() {
                  document.body.bgColor = '$background';
                });
             """

    clipjs = clipToSelector == "" ? "" :
               """
                var clipRect = page.evaluate(function(){
                    return document.querySelector('$clipToSelector').getBoundingClientRect();
                  });

                page.clipRect = {
                  top:    clipRect.top,
                  left:   clipRect.left,
                  width:  clipRect.width,
                  height: clipRect.height
                };
               """

    jsscript = """
      "use strict";
      var page = require('webpage').create(),
          system = require('system'),
          address, output, size, pageWidth, pageHeight;

      address = 'file:///$htmlpath';
      output = '$destpath';

      page.viewportSize = { width: $width, height: $height };

      page.paperSize = { format: '$paperSize',
                         orientation: '$orientation',
                         margin: '$margin' };

      page.open(address, function (status) {
          if (status !== 'success') {
              console.log('Unable to load the address : ' + address);
              phantom.exit(1);
          } else {
              window.setTimeout(function () {
                  $bgjs
                  $clipjs
                  page.render(output,
                              {format: '$format',
                               quality: '$quality'});
                  phantom.exit();
              }, 200);
          }
      });
    """

    jspath = joinpath(tdir, randstring() * ".js")
    open(io -> write(io, jsscript), jspath, "w")

    run(`$phantomjspath $jspath`)
    result = read(destpath)
  end

  result
end

end # module


text:
"""
    bi00()

Frame bias components of IAU 2000 precession-nutation models (part
of MHB2000 with additions).

### Returned ###

- `dpsibi`, `depsbi`: Longitude and obliquity corrections
- `dra`: The ICRS RA of the J2000.0 mean equinox

### Notes ###

1. The frame bias corrections in longitude and obliquity (radians)
   are required in order to correct for the offset between the GCRS
   pole and the mean J2000.0 pole.  They define, with respect to the
   GCRS frame, a J2000.0 mean pole that is consistent with the rest
   of the IAU 2000A precession-nutation model.

2. In addition to the displacement of the pole, the complete
   description of the frame bias requires also an offset in right
   ascension.  This is not part of the IAU 2000A model, and is from
   Chapront et al. (2002).  It is returned in radians.

3. This is a supplemented implementation of one aspect of the IAU
   2000A nutation model, formally adopted by the IAU General
   Assembly in 2000, namely MHB2000 (Mathews et al. 2002).

### References ###

- Chapront, J., Chapront-Touze, M. & Francou, G., Astron.
    Astrophys., 387, 700, 2002.

- Mathews, P.M., Herring, T.A., Buffet, B.A., "Modeling of nutation
    and precession: New nutation series for nonrigid Earth and
    insights into the Earth's interior", J.Geophys.Res., 107, B4, 2002.
    The MHB2000 code itself was obtained on 9th September 2002
    from ftp://maia.usno.navy.mil/conv2000/chapter5/IAU2000A.

"""
function bi00()
    dpsibi = Ref{Cdouble}()
    depsbi = Ref{Cdouble}()
    dra = Ref{Cdouble}()
    ccall((:eraBi00, liberfa), Cvoid,
          (Ref{Cdouble}, Ref{Cdouble}, Ref{Cdouble}),
          dpsibi, depsbi, dra)
    return dpsibi[], depsbi[], dra[]
end

"""
    bpn2xy(rbpn)

Extract from the bias-precession-nutation matrix the X,Y coordinates
of the Celestial Intermediate Pole.

### Given ###

- `rbpn`: Celestial-to-true matrix (Note 1)

### Returned ###

- `x`, `y`: Celestial Intermediate Pole (Note 2)

### Notes ###

1. The matrix rbpn transforms vectors from GCRS to true equator (and
   CIO or equinox) of date, and therefore the Celestial Intermediate
   Pole unit vector is the bottom row of the matrix.

2. The arguments x,y are components of the Celestial Intermediate
   Pole unit vector in the Geocentric Celestial Reference System.

### Reference ###

- "Expressions for the Celestial Intermediate Pole and Celestial
    Ephemeris Origin consistent with the IAU 2000A precession-
    nutation model", Astron.Astrophys. 400, 1145-1154
    (2003)

- n.b. The celestial ephemeris origin (CEO) was renamed "celestial
    intermediate origin" (CIO) by IAU 2006 Resolution 2.

"""
function bpn2xy(rbpn)
    @checkdims 3 3 rbpn
    x = Ref{Cdouble}()
    y = Ref{Cdouble}()
    ccall((:eraBpn2xy, liberfa), Cvoid,
          (Ptr{Cdouble}, Ref{Cdouble}, Ref{Cdouble}),
          permutedims(rbpn), x, y)
    return x[], y[]
end

"""
    bp00(date1, date2)

Frame bias and precession, IAU 2000.

### Given ###

- `date1`, `date2`: TT as a 2-part Julian Date (Note 1)

### Returned ###

- `rb`: Frame bias matrix (Note 2)
- `rp`: Precession matrix (Note 3)
- `rbp`: Bias-precession matrix (Note 4)

### Notes ###

1. The TT date date1+date2 is a Julian Date, apportioned in any
   convenient way between the two arguments.  For example,
   JD(TT)=2450123.7 could be expressed in any of these ways,
   among others:

   |   `date1` | `date2` | Method      |
   |:----------|:--------|:------------|
   | 2450123.7 |     0.0 | JD          |
   | 2451545.0 | -1421.3 | J2000       |
   | 2400000.5 | 50123.2 | MJD         |
   | 2450123.5 |     0.2 | date & time |

   The JD method is the most natural and convenient to use in
   cases where the loss of several decimal digits of resolution
   is acceptable.  The J2000 method is best matched to the way
   the argument is handled internally and will deliver the
   optimum resolution.  The MJD method and the date & time methods
   are both good compromises between resolution and convenience.

2. The matrix rb transforms vectors from GCRS to mean J2000.0 by
   applying frame bias.

3. The matrix rp transforms vectors from J2000.0 mean equator and
   equinox to mean equator and equinox of date by applying
   precession.

4. The matrix rbp transforms vectors from GCRS to mean equator and
   equinox of date by applying frame bias then precession.  It is
   the product rp x rb.

5. It is permissible to re-use the same array in the returned
   arguments.  The arrays are filled in the order given.

### Called ###

- [`bi00`](@ref): frame bias components, IAU 2000
- [`pr00`](@ref): IAU 2000 precession adjustments
- [`ir`](@ref): initialize r-matrix to identity
- [`rx`](@ref): rotate around X-axis
- [`ry`](@ref): rotate around Y-axis
- [`rz`](@ref): rotate around Z-axis
- [`cr`](@ref): copy r-matrix
- [`rxr`](@ref): product of two r-matrices

### Reference ###

- "Expressions for the Celestial Intermediate Pole and Celestial
    Ephemeris Origin consistent with the IAU 2000A precession-
    nutation model", Astron.Astrophys. 400, 1145-1154 (2003)

- n.b. The celestial ephemeris origin (CEO) was renamed "celestial
    intermediate origin" (CIO) by IAU 2006 Resolution 2.

"""
bp00

"""
    bp06(date1, date2)

Frame bias and precession, IAU 2006.

### Given ###

- `date1`, `date2`: TT as a 2-part Julian Date (Note 1)

### Returned ###

- `rb`: Frame bias matrix (Note 2)
- `rp`: Precession matrix (Note 3)
- `rbp`: Bias-precession matrix (Note 4)

### Notes ###

1. The TT date date1+date2 is a Julian Date, apportioned in any
   convenient way between the two arguments.  For example,
   JD(TT)=2450123.7 could be expressed in any of these ways,
   among others:

   |   `date1` | `date2` | Method      |
   |:----------|:--------|:------------|
   | 2450123.7 |     0.0 | JD          |
   | 2451545.0 | -1421.3 | J2000       |
   | 2400000.5 | 50123.2 | MJD         |
   | 2450123.5 |     0.2 | date & time |

   The JD method is the most natural and convenient to use in
   cases where the loss of several decimal digits of resolution
   is acceptable.  The J2000 method is best matched to the way
   the argument is handled internally and will deliver the
   optimum resolution.  The MJD method and the date & time methods
   are both good compromises between resolution and convenience.

2. The matrix rb transforms vectors from GCRS to mean J2000.0 by
   applying frame bias.

3. The matrix rp transforms vectors from mean J2000.0 to mean of
   date by applying precession.

4. The matrix rbp transforms vectors from GCRS to mean of date by
   applying frame bias then precession.  It is the product rp x rb.

5. It is permissible to re-use the same array in the returned
   arguments.  The arrays are filled in the order given.

### Called ###

- [`pfw06`](@ref): bias-precession F-W angles, IAU 2006
- [`fw2m`](@ref): F-W angles to r-matrix
- [`pmat06`](@ref): PB matrix, IAU 2006
- [`tr`](@ref): transpose r-matrix
- [`rxr`](@ref): product of two r-matrices
- [`cr`](@ref): copy r-matrix

### References ###

- Capitaine, N. & Wallace, P.T., 2006, Astron.Astrophys. 450, 855

- Wallace, P.T. & Capitaine, N., 2006, Astron.Astrophys. 459, 981

"""
bp06

for name in ("bp00",
             "bp06")
    f = Symbol(name)
    fc = "era" * uppercasefirst(name)
    @eval begin
        function ($f)(a, b)
            rb = zeros(Cdouble, 3, 3)
            rp = zeros(Cdouble, 3, 3)
            rbp = zeros(Cdouble, 3, 3)
            ccall(($fc, liberfa),
                  Cvoid,
                  (Cdouble, Cdouble, Ptr{Cdouble}, Ptr{Cdouble}, Ptr{Cdouble}),
                  a, b, rb, rp, rbp)
            return permutedims(rb), permutedims(rp), permutedims(rbp)
        end
    end
end


text:
# Autogenerated wrapper script for QCDNUM_jll for aarch64-linux-musl-libgfortran5-cxx03
export libqcdnum

using CompilerSupportLibraries_jll
JLLWrappers.@generate_wrapper_header("QCDNUM")
JLLWrappers.@declare_library_product(libqcdnum, "libQCDNUM.so.0")
function __init__()
    JLLWrappers.@generate_init_header(CompilerSupportLibraries_jll)
    JLLWrappers.@init_library_product(
        libqcdnum,
        "lib/libQCDNUM.so",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@generate_init_footer()
end  # __init__()


text:
"""
    IndicatorActiveOnFalseBridge{T}

The `IndicatorActiveOnFalseBridge` replaces an indicator constraint activated
on 0 with a variable ``z_0`` with the constraint activated on 1, with a variable ``z_1``.
It stores the added `variable` and added constraints:
- ``z_1 \\in \\mathbb{B}`` in `zero_one_cons`
- ``z_0 + z_1 == 1`` in `` in `disjunction_cons`
- The added `ACTIVATE_ON_ONE` indicator constraint in `indicator_cons_index`.
"""
struct IndicatorActiveOnFalseBridge{
    T,
    F<:MOI.AbstractVectorFunction,
    S<:MOI.AbstractScalarSet,
} <: AbstractBridge
    variable::MOI.VariableIndex
    zero_one_cons::MOI.ConstraintIndex{MOI.VariableIndex,MOI.ZeroOne}
    disjunction_cons::MOI.ConstraintIndex{
        MOI.ScalarAffineFunction{T},
        MOI.EqualTo{T},
    }
    indicator_cons_index::MOI.ConstraintIndex{
        F,
        MOI.Indicator{MOI.ACTIVATE_ON_ONE,S},
    }
end

function bridge_constraint(
    ::Type{IndicatorActiveOnFalseBridge{T,F,S}},
    model::MOI.ModelLike,
    f::MOI.VectorAffineFunction{T},
    s::IS,
) where {
    S<:MOI.AbstractScalarSet,
    T<:Real,
    F,
    IS<:MOI.Indicator{MOI.ACTIVATE_ON_ZERO,S},
}
    f_scalars = MOIU.eachscalar(f)
    z2, zo_cons = MOI.add_constrained_variable(model, MOI.ZeroOne())
    # z1 + z2 == 1
    z1_z2 = MOIU.operate(+, T, f_scalars[1], z2)
    dcons = MOIU.normalize_and_add_constraint(model, z1_z2, MOI.EqualTo(one(T)))
    f2 = MOIU.operate(vcat, T, z2, f_scalars[2])
    ci =
        MOI.add_constraint(model, f2, MOI.Indicator{MOI.ACTIVATE_ON_ONE}(s.set))
    return IndicatorActiveOnFalseBridge{T,F,S}(z2, zo_cons, dcons, ci)
end

function MOI.supports_constraint(
    ::Type{<:IndicatorActiveOnFalseBridge{T}},
    ::Type{<:MOI.VectorAffineFunction},
    ::Type{<:MOI.Indicator{MOI.ACTIVATE_ON_ZERO}},
) where {T}
    return true
end

function MOIB.added_constrained_variable_types(
    ::Type{<:IndicatorActiveOnFalseBridge},
)
    return Tuple{Type}[(MOI.ZeroOne,)]
end

function MOIB.added_constraint_types(
    ::Type{IndicatorActiveOnFalseBridge{T,F,S}},
) where {T,F,S}
    return Tuple{Type,Type}[
        (MOI.ScalarAffineFunction{T}, MOI.EqualTo{T}),
        (F, MOI.Indicator{MOI.ACTIVATE_ON_ONE,S}),
    ]
end

function concrete_bridge_type(
    ::Type{<:IndicatorActiveOnFalseBridge{T}},
    ::Type{F},
    ::Type{MOI.Indicator{MOI.ACTIVATE_ON_ZERO,S}},
) where {T,F<:MOI.VectorAffineFunction,S<:MOI.AbstractScalarSet}
    return IndicatorActiveOnFalseBridge{T,F,S}
end

function concrete_bridge_type(
    ::Type{<:IndicatorActiveOnFalseBridge},
    ::Type{F},
    ::Type{MOI.Indicator{MOI.ACTIVATE_ON_ZERO,S}},
) where {F<:MOI.VectorAffineFunction,S<:MOI.AbstractScalarSet}
    return IndicatorActiveOnFalseBridge{Float64,F,S}
end


text:
struct RPCMsg
  signature::String
  payloadtype::String
  payload::String
end

struct AddColonyRPC
  colony::Colony
  msgtype::String
end

struct AddRuntimeRPC
  runtime::Runtime
  msgtype::String
end

struct ApproveRuntimeRPC
  runtimeid::String
  msgtype::String
end

struct SubmitProcessSpecRPC
  spec::ProcessSpec
  msgtype::String
end

struct GetProcessRPC
  processid::String
  msgtype::String
end

struct AssignProcessRPC
  colonyid::String
  msgtype::String
end

struct AddAttributeRPC
  attribute::Attribute
  msgtype::String
end

struct CloseSuccessfulRPC
  processid::String
  msgtype::String
end

struct CloseFailedRPC
  processid::String
  msgtype::String
end

function base64enc(msg::String)
  io = IOBuffer()
  iob64_encode = Base64EncodePipe(io)
  write(iob64_encode, msg)
  close(iob64_encode)
  String(take!(io))
end

function sendrpcmsg(rpcmsg::RPCMsg)
  url = "https://localhost:8080/api"
  body = ""
  try
    r = HTTP.request("POST", url,
                    ["Content-Type" => "plain/text"],
                    JSON2.write(rpcmsg),
                    require_ssl_verification=false)
    body = String(r.body)
    rpcreplymsg = JSON.parse(body)
    payload = String(base64decode(rpcreplymsg["payload"]))
    return payload, rpcreplymsg["payloadtype"]
  catch err
    rpcreplymsg = JSON.parse(String(err.response.body))
    payload = String(base64decode(rpcreplymsg["payload"]))
    failure_msg = JSON.parse(payload)
    Base.error(failure_msg["message"])
  end
end


text:
include("../common/layers.jl")
include("../ch04/negative_sampling_layer.jl")

using Random

mutable struct CBOW
    in_layers
    ns_loss
    params
    grads
    word_vecs
    function CBOW(vocab_size, hidden_size, windows_size, corpus)
        self = new()
        V, H = vocab_size, hidden_size

        # 重みの初期化
        W_in = 0.01 .* randn(V, H)
        W_out = 0.01 .* randn(V, H)

        # レイヤの生成
        self.in_layers = []
        for i = 1:(2 .* windows_size)
            layer = Embedding(W_in)
            push!(self.in_layers, layer)
        end
        self.ns_loss = NegativeSamplingLoss(W_out, corpus; power = 0.75, sample_size = 5)

        # 全ての重みと勾配を配列にまとめる
        layers = vcat(self.in_layers, self.ns_loss)

        self.params, self.grads = [], []
        for layer in layers
            push!(self.params, layer.params)
            push!(self.grads, layer.grads)
        end

        # 構造体の変数に単語の分散表現を設定
        self.word_vecs = W_in
        return self
    end
end

function forward!(self::CBOW, contexts, target)
    h = 0
    for (i, layer) in enumerate(self.in_layers)
        h .+= forward!(layer, contexts[:, i])
    end
    h .*= 1 ./ length(self.in_layers)
    loss = forward!(self.ns_loss, h, target)
    return loss
end

function backward!(self::CBOW; dout = 1)
    dout = backward!(self.ns_loss, dout = dout)
    dout .*= 1 ./ length(self.in_layers)
    for layer in self.in_layers
        backward!(layer, dout = dout)
    end
end


text:
__precompile__(true)
module Seaborn

export
jointplot,
pairplot,
distplot,
kdeplot,
rugplot,
lmplot,
regplot,
residplot,
interactplot,
coefplot,
factorplot,
boxplot,
violinplot,
stripplot,
swarmplot,
pointplot,
barplot,
countplot,
heatmap,
clustermap,
tsplot,
palplot,
FacetGrid,
PairGrid,
JointGrid,
axes_style,
set_style,
plotting_context,
set_context,
set_color_codes,
reset_defaults,
reset_orig,
load_dataset

using Reexport
using PyCall
import Pandas
@reexport using PyPlot

const seaborn = PyNULL()

function __init__()
    copy!(seaborn, pyimport_conda("seaborn", "seaborn"))
end

macro delegate(f_list...)
    blocks = Expr(:block)
    for f in f_list
        block = quote
            function $(esc(f))(args...; kwargs...)
                seaborn[$(QuoteNode(f))](args...; kwargs...)
            end
        end
        push!(blocks.args, block)
    end
    blocks
end

@delegate jointplot pairplot kdeplot lmplot regplot residplot interactplot coefplot boxplot violinplot stripplot swarmplot pointplot clustermap tsplot palplot FacetGrid PairGrid JointGrid axes_style set_style plotting_context set_context set_color_codes reset_defaults reset_orig set

"""
    distplot(a; <keyword arguments>)

Flexibly plot a univariate distribution of observations.

This function combines the matplotlib `hist` function (with automatic
calculation of a good default bin size) with the seaborn `kdeplot`
and `rugplot` functions. It can also fit `scipy.stats`
distributions and plot the estimated PDF over the data.

# Arguments

* `a` : Series, 1d-array, or list.
    Observed data. If this is a Series object with a ``name`` attribute,
    the name will be used to label the data axis.
* `bins` : argument for matplotlib hist(), or None, optional.
    Specification of hist bins, or None to use Freedman-Diaconis rule.
* `hist` : bool, optional.
    Whether to plot a (normed) histogram.
* `kde` : bool, optional.
    Whether to plot a gaussian kernel density estimate.
* `rug` : bool, optional.
    Whether to draw a rugplot on the support axis.
* `fit` : random variable object, optional.
    An object with `fit` method, returning a tuple that can be passed to a
    `pdf` method a positional arguments following an grid of values to
    evaluate the pdf on.
* `{hist, kde, rug, fit}_kws` : dictionaries, optional.
    Keyword arguments for underlying plotting functions.
* `color` : matplotlib color, optional.
    Color to plot everything but the fitted curve in.
* `vertical` : bool, optional.
    If True, oberved values are on y-axis.
* `norm_hist` : bool, optional.
    If True, the histogram height shows a density rather than a count.
    This is implied if a KDE or fitted density is plotted.
* `axlabel` : string, False, or None, optional.
    Name for the support axis label. If None, will try to get it
    from a.namel if False, do not set a label.
* `label` : string, optional.
    Legend label for the relevent component of the plot
* `ax` : matplotlib axis, optional.
    if provided, plot on this axis

# Returns
`ax` : matplotlib Axes
    Returns the Axes object with the plot for further tweaking.

# See Also

* `kdeplot` : Show a univariate or bivariate distribution with a kernel
          density estimate.
* `rugplot` : Draw small vertical lines to show each observation in a
          distribution.
"""
function distplot(args...; kwargs...)
    seaborn[:distplot](args...; kwargs...)
end

"""
    rugplot(a; <keyword arguments>)

Plot datapoints in an array as sticks on an axis.

# Arguments

* `a` : 1D array of observations.
* `height` : Height of ticks as proportion of the axis.
* `axis` : Axis to draw rugplot on.
* `ax` : Axes to draw plot into; otherwise grabs current axes.
* `kwargs` :  Other keyword arguments are passed to `axvline` or `axhline`.

# Returns

* `ax` :  The `Axes` object with the plot on it.
"""
function rugplot(args...; kwargs...)
    seaborn[:rugplot](args...; kwargs...)
end

"""
    countplot(x; <keyword arguments>)

Show the counts of observations in each categorical bin using bars.

A count plot can be thought of as a histogram across a categorical, instead
of quantitative, variable. The basic API and options are identical to those
for `barplot`, so you can compare counts across nested variables.

Input data can be passed in a variety of formats, including:

* Vectors of data represented as lists, numpy arrays, or pandas Series
  objects passed directly to the ``x``, ``y``, and/or ``hue`` parameters.
* A "long-form" DataFrame, in which case the ``x``, ``y``, and ``hue``
  variables will determine how the data are plotted.
* A "wide-form" DataFrame, such that each numeric column will be plotted.
* Anything accepted by `plt.boxplot` (e.g. a 2d array or list of vectors)

In most cases, it is possible to use numpy or Python objects, but pandas
objects are preferable because the associated names will be used to
annotate the axes. Additionally, you can use Categorical types for the
grouping variables to control the order of plot elements.

# Parameters

* `x`, `y`, `hue` : names of variables in ``data`` or vector data, optional.
    Inputs for plotting long-form data. See examples for interpretation.
* `data` : DataFrame, array, or list of arrays, optional.
    Dataset for plotting. If ``x`` and ``y`` are absent, this is
    interpreted as wide-form. Otherwise it is expected to be long-form.
* `order`, `hue_order` : lists of strings, optional.
    Order to plot the categorical levels in, otherwise the levels are
    inferred from the data objects.
* `orient` : "v" | "h", optional.
    Orientation of the plot (vertical or horizontal). This is usually
    inferred from the dtype of the input variables, but can be used to
    specify when the "categorical" variable is a numeric or when plotting
    wide-form data.
* `color` : matplotlib color, optional.
    Color for all of the elements, or seed for `light_palette` when
    using hue nesting.
* `palette` : seaborn color palette or dict, optional.
    Colors to use for the different levels of the ``hue`` variable. Should
    be something that can be interpreted by `color_palette`, or a
    dictionary mapping hue levels to matplotlib colors.
* `saturation` : float, optional.
    Proportion of the original saturation to draw colors at. Large patches
    often look better with slightly desaturated colors, but set this to
    ``1`` if you want the plot colors to perfectly match the input color
    spec.
* `ax` : matplotlib Axes, optional.
    Axes object to draw the plot onto, otherwise uses the current Axes.
* `kwargs` : key, value mappings.
    Other keyword arguments are passed to ``plt.bar``.

# Returns

`ax` : matplotlib Axes
    Returns the Axes object with the boxplot drawn onto it.

# See Also

* `barplot` : Show point estimates and confidence intervals using bars.
* `factorplot` : Combine categorical plots and a class:`FacetGrid`.
"""
function countplot(args...; kwargs...)
    seaborn[:countplot](args...; kwargs...)
end

"""
    barplot(x, y; <keyword arguments>)

Show point estimates and confidence intervals as rectangular bars.

A bar plot represents an estimate of central tendency for a numeric
variable with the height of each rectangle and provides some indication of
the uncertainty around that estimate using error bars. Bar plots include 0
in the quantitative axis range, and they are a good choice when 0 is a
meaningful value for the quantitative variable, and you want to make
comparisons against it.

For datasets where 0 is not a meaningful value, a point plot will allow you
to focus on differences between levels of one or more categorical
variables.

It is also important to keep in mind that a bar plot shows only the mean
(or other estimator) value, but in many cases it may be more informative to
show the distribution of values at each level of the categorical variables.
In that case, other approaches such as a box or violin plot may be more
appropriate.

Input data can be passed in a variety of formats, including:

- Vectors of data represented as lists, numpy arrays, or pandas Series
  objects passed directly to the `x`, `y`, and/or `hue` parameters.
- A "long-form" DataFrame, in which case the `x`, `y`, and `hue`
  variables will determine how the data are plotted.
- A "wide-form" DataFrame, such that each numeric column will be plotted.
- Anything accepted by `plt.boxplot` (e.g. a 2d array or list of vectors)

In most cases, it is possible to use numpy or Python objects, but pandas
objects are preferable because the associated names will be used to
annotate the axes. Additionally, you can use Categorical types for the
grouping variables to control the order of plot elements.

# Parameters

* `x`, `y`, `hue` : names of variables in ``data`` or vector data, optional.
    Inputs for plotting long-form data. See examples for interpretation.
* `data` : DataFrame, array, or list of arrays, optional.
    Dataset for plotting. If `x` and `y` are absent, this is
    interpreted as wide-form. Otherwise it is expected to be long-form.
* `order`, `hue_order` : lists of strings, optional.
    Order to plot the categorical levels in, otherwise the levels are
    inferred from the data objects.
* `estimator` : callable that maps vector -> scalar, optional.
    Statistical function to estimate within each categorical bin.
* `ci` : float or None, optional.
    Size of confidence intervals to draw around estimated values. If
    `nothing`, no bootstrapping will be performed, and error bars will
    not be drawn.
* `n_boot` : int, optional.
    Number of bootstrap iterations to use when computing confidence
    intervals.
* `units` : name of variable in `data` or vector data, optional.
    Identifier of sampling units, which will be used to perform a
    multilevel bootstrap and account for repeated measures design.
* `orient` : "v" | "h", optional.
    Orientation of the plot (vertical or horizontal). This is usually
    inferred from the dtype of the input variables, but can be used to
    specify when the "categorical" variable is a numeric or when plotting
    wide-form data.
* `color` : matplotlib color, optional.
    Color for all of the elements, or seed for `light_palette` when
    using hue nesting.
* `palette` : seaborn color palette or dict, optional.
    Colors to use for the different levels of the `hue` variable. Should
    be something that can be interpreted by `color_palette`, or a
    dictionary mapping hue levels to matplotlib colors.
* `saturation` : float, optional.
    Proportion of the original saturation to draw colors at. Large patches
    often look better with slightly desaturated colors, but set this to
    `1` if you want the plot colors to perfectly match the input color
    spec.
* `errcolor` : matplotlib color.
    Color for the lines that represent the confidence interval.
* `ax` : matplotlib Axes, optional.
    Axes object to draw the plot onto, otherwise uses the current Axes.
* `errwidth` : float, optional.
    Thickness of error bar lines (and caps).
* `capsize` : float, optional.
    Width of the "caps" on error bars.

* `kwargs` : key, value mappings.
    Other keyword arguments are passed through to `plt.bar` at draw
    time.

# Returns

`ax` : matplotlib Axes.
    Returns the Axes object with the boxplot drawn onto it.

# See Also

* `countplot` : Show the counts of observations in each categorical bin.
* `pointplot` : Show point estimates and confidence intervals using scatterplot
            glyphs.
* `factorplot` : Combine categorical plots and a class:`FacetGrid`.
"""
function barplot(args...; kwargs...)
    seaborn[:barplot](args...; kwargs...)
end

"""
    heatmap(data; <keyword arguments>)

Plot rectangular data as a color-encoded matrix.

This function tries to infer a good colormap to use from the data, but
this is not guaranteed to work, so take care to make sure the kind of
colormap (sequential or diverging) and its limits are appropriate.

This is an Axes-level function and will draw the heatmap into the
currently-active Axes if none is provided to the ``ax`` argument.  Part of
this Axes space will be taken and used to plot a colormap, unless ``cbar``
is False or a separate Axes is provided to ``cbar_ax``.

# Parameters

* `data` : rectangular dataset.
    2D dataset that can be coerced into an ndarray. If a Pandas DataFrame
    is provided, the index/column information will be used to label the
    columns and rows.
* `vmin`, `vmax` : floats, optional.
    Values to anchor the colormap, otherwise they are inferred from the
    data and other keyword arguments. When a diverging dataset is inferred,
    one of these values may be ignored.
* `cmap` : matplotlib colormap name or object, optional.
    The mapping from data values to color space. If not provided, this
    will be either a cubehelix map (if the function infers a sequential
    dataset) or ``RdBu_r`` (if the function infers a diverging dataset).
* `center` : float, optional.
    The value at which to center the colormap. Passing this value implies
    use of a diverging colormap.
* `robust` : bool, optional.
    If True and ``vmin`` or ``vmax`` are absent, the colormap range is
    computed with robust quantiles instead of the extreme values.
* `annot` : bool or rectangular dataset, optional.
    If `true`, write the data value in each cell. If an array-like with the
    same shape as ``data``, then use this to annotate the heatmap instead
    of the raw data.
* `fmt` : string, optional.
    String formatting code to use when adding annotations.
* `annot_kws` : dict of key, value mappings, optional.
    Keyword arguments for ``ax.text`` when ``annot`` is True.
* `linewidths` : float, optional.
    Width of the lines that will divide each cell.
* `linecolor` : color, optional.
    Color of the lines that will divide each cell.
* `cbar` : boolean, optional.
    Whether to draw a colorbar.
* `cbar_kws` : dict of key, value mappings, optional.
    Keyword arguments for `fig.colorbar`.
* `cbar_ax` : matplotlib Axes, optional.
    Axes in which to draw the colorbar, otherwise take space from the
    main Axes.
* `square` : boolean, optional.
    If `true`, set the Axes aspect to "equal" so each cell will be
    square-shaped.
* `ax` : matplotlib Axes, optional.
    Axes in which to draw the plot, otherwise use the currently-active
    Axes.
* `xticklabels` : list-like, int, or bool, optional.
    If `true`, plot the column names of the dataframe. If `false`, don't plot
    the column names. If list-like, plot these alternate labels as the
    xticklabels. If an integer, use the column names but plot only every
    n label.
* `yticklabels` : list-like, int, or bool, optional.
    If `true`, plot the row names of the dataframe. If `false`, don't plot
    the row names. If list-like, plot these alternate labels as the
    yticklabels. If an integer, use the index names but plot only every
    n label.
* `mask` : boolean array or DataFrame, optional.
    If passed, data will not be shown in cells where ``mask`` is True.
    Cells with missing values are automatically masked.
* `kwargs` : other keyword arguments.
    All other keyword arguments are passed to ``ax.pcolormesh``.

# Returns

`ax` : matplotlib Axes.
    Axes object with the heatmap.
"""
function heatmap(args...; kwargs...)
    seaborn[:heatmap](args...; kwargs...)
end

"""
    factorplot(<keyword arguments>)

Draw a categorical plot onto a FacetGrid.

The default plot that is shown is a point plot, but other seaborn
categorical plots can be chosen with the ``kind`` parameter, including
box plots, violin plots, bar plots, or strip plots.

It is important to choose how variables get mapped to the plot structure
such that the most important comparisons are easiest to make. As a general
rule, it is easier to compare positions that are closer together, so the
``hue`` variable should be used for the most important comparisons. For
secondary comparisons, try to share the quantitative axis (so, use ``col``
for vertical plots and ``row`` for horizontal plots). Note that, although
it is possible to make rather complex plots using this function, in many
cases you may be better served by created several smaller and more focused
plots than by trying to stuff many comparisons into one figure.

After plotting, the :class:`FacetGrid` with the plot is returned and can
be used directly to tweak supporting plot details or add other layers.

Note that, unlike when using the underlying plotting functions directly,
data must be passed in a long-form DataFrame with variables specified by
passing strings to ``x``, ``y``, ``hue``, and other parameters.

As in the case with the underlying plot functions, if variables have a
``categorical`` data type, the correct orientation of the plot elements,
the levels of the categorical variables, and their order will be inferred
from the objects. Otherwise you may have to use the function parameters
(``orient``, ``order``, ``hue_order``, etc.) to set up the plot correctly.

# Parameters

* `x`, `y`, hue : names of variables in ``data``.
    Inputs for plotting long-form data. See examples for interpretation.
* `data` : DataFrame.
    Long-form (tidy) dataset for plotting. Each column should correspond
    to a variable, and each row should correspond to an observation.
* `row`, `col` : names of variables in ``data``, optional.
    Categorical variables that will determine the faceting of the grid.
* `col_wrap` : int, optional.
    "Wrap" the column variable at this width, so that the column facets
    span multiple rows. Incompatible with a ``row`` facet.
* `estimator` : callable that maps vector -> scalar, optional.
    Statistical function to estimate within each categorical bin.
* `ci` : float or None, optional.
    Size of confidence intervals to draw around estimated values. If
    ``None``, no bootstrapping will be performed, and error bars will
    not be drawn.
* `n_boot` : int, optional.
    Number of bootstrap iterations to use when computing confidence
    intervals.
* `units` : name of variable in ``data`` or vector data, optional.
    Identifier of sampling units, which will be used to perform a
    multilevel bootstrap and account for repeated measures design.
* `order`, `hue_order` : lists of strings, optional.
    Order to plot the categorical levels in, otherwise the levels are
    inferred from the data objects.
* `row_order`, `col_order` : lists of strings, optional.
    Order to organize the rows and/or columns of the grid in, otherwise the
    orders are inferred from the data objects.
* `kind` : {``point``, ``bar``, ``count``, ``box``, ``violin``, ``strip``}.
    The kind of plot to draw.
* `size` : scalar, optional.
    Height (in inches) of each facet. See also: ``aspect``.
* `aspect` : scalar, optional.
    Aspect ratio of each facet, so that ``aspect * size`` gives the width
    of each facet in inches.
* `orient` : "v" | "h", optional.
    Orientation of the plot (vertical or horizontal). This is usually
    inferred from the dtype of the input variables, but can be used to
    specify when the "categorical" variable is a numeric or when plotting
    wide-form data.
* `color` : matplotlib color, optional.
    Color for all of the elements, or seed for :func:`light_palette` when
    using hue nesting.
* `palette` : seaborn color palette or dict, optional.
    Colors to use for the different levels of the ``hue`` variable. Should
    be something that can be interpreted by :func:`color_palette`, or a
    dictionary mapping hue levels to matplotlib colors.
* `legend` : bool, optional.
    If ``True`` and there is a ``hue`` variable, draw a legend on the plot.
* `legend_out` : bool, optional.
    If ``True``, the figure size will be extended, and the legend will be
    drawn outside the plot on the center right.
* `share{x,y}` : bool, optional.
    If true, the facets will share y axes across columns and/or x axes
    across rows.
* `margin_titles` : bool, optional.
    If ``True``, the titles for the row variable are drawn to the right of
    the last column. This option is experimental and may not work in all
    cases.
* `facet_kws` : dict, optional.
    Dictionary of other keyword arguments to pass to :class:`FacetGrid`.
* `kwargs` : key, value pairings.
    Other keyword arguments are passed through to the underlying plotting
    function.

# Returns

`g` : `FacetGrid`.
    Returns the `FacetGrid` object with the plot on it for further
    tweaking.
"""
function factorplot(args...; kwargs...)
    seaborn[:factorplot](args...; kwargs...)
end

function load_dataset(name)
    o = seaborn[:load_dataset](name)
    Pandas.DataFrame(o)
end

end # module


text:
# # A simple FEM application
#
# ## Introduction
#
# ### General description
# The Finite Element Method is widely used to solve PDEs in Engineering applications and particularly in Structural Analysis problems [[BAT14]](@ref). The procedure consists discretizing the domain into _elements_ and assembly a system of balance equations. For linear problems, this system can be usually written as
#
# ```math
# K \cdot d = f
# \qquad
# K = \sum_e K_e
# ```
# where $f$ is the vector of external loads, $K_e$ is the element stiffness matrix and $d$ is the vector of unknown displacements.
#
# ### FEM for truss structures
# A frequent and simple type of structures are _Truss structures_, which are formed by bars connected but not welded. Truss models are considered during the conceptual design of bridges or other structures.
#
# The stiffness matrix of a truss element in the local coordinate system is given by
# ```math
# K_L = s
# \left(
#  \begin{matrix}
#  1 & 0 & -1 & 0 \\
#  0 & 0 &  0 & 0 \\
# -1 & 0 &  1 & 0 \\
#  0 & 0 &  0 & 0
# \end{matrix}
# \right),
# ```
#
# where $s =\frac{E A}{L}$, with $E$ being the Young modulus, $A$ the area of the cross-section and $L$ the length of that truss element.
#
# The change-of-basis matrix is given by
# ```math
# _G(Q)_L = Q =
# \left(
#   \begin{matrix}
# \cos(\alpha) & -\sin(\alpha) & 0 & 0 \\
#  \sin(\alpha) & \cos(\alpha) &  0 & 0 \\
#  0 & 0 &  \cos(\alpha) & -\sin(\alpha) \\
#  0 & 0 &  \sin(\alpha) & \cos(\alpha)
# \end{matrix}
# \right),
# ```
#
# The system of equations for each element is written in local coordinates as
# ```math
# K_L d_L = f_L
# ```
# and using the change-of-basis we obtain
# ```math
# K_G d_G = f_G \qquad K_G = Q K_L Q^T
# ```
#
# The unitary stiffness matrix (for $s=1$) can be computed using the following function.
function unitaryStiffnessMatrix( coordFirstNode, coordSecondNode  )
  diff      = (coordSecondNode - coordFirstNode)
  length   = sqrt( diff' * diff )
  c        = diff[1] / length ;
  s        = diff[2] / length ;
  Qloc2glo = [ c -s 0 0 ; s c 0 0 ; 0 0 c -s ; 0 0 s c ] ;
  Kloc     = [ 1 0 -1 0 ; 0 0 0 0 ; -1 0 1 0 ; 0 0 0 0 ] ;
  Kglo     = Qloc2glo * Kloc * transpose(Qloc2glo)
  return     Kglo, length
end
#
# ## Example problem
#
# A problem based on Example 4.1 from [[SKA06]](@ref) is considered. The following diagram shows the truss structure considered.
#
# ```@raw html
# <img src="../../assets/trussDiagram.svg" style="width: 100%" alt="truss diagram"/>
# ```
#
# ### Case with fixed parameters
#
# The scalar parameters considered are given by
E = 2e11 ; # Young modulus
A = 5e-3 ; # Cross-section area
# The coordinate matrix is given by
## coordinates   x  y
nodesCMatrix = [ 0. 0. ;
                 1. 1. ;
                 2. 0. ;
                 3. 1. ;
                 4. 0. ];
# the connectivity matrix is given by
## connectivity  start end
connecMatrix = [ 1     2 ;
                 1     3 ;
                 2     3 ;
                 2     4 ;
                 3     4 ;
                 3     5 ;
                 4     5 ];
# and the fixed degrees of freedom (supports) are defined by the vector
fixedDofs     = [2 9 10 ];
#
# calculations
numNodes = size( nodesCMatrix )[1]; # compute the number of nodes
numElems = size( connecMatrix )[1]; # compute the number of elements
freeDofs = zeros(Int8, 2*numNodes-length(fixedDofs));
indDof  = 1 ; counter = 0 ;
while indDof <= (2*numNodes)
  if !(indDof in fixedDofs)
    global counter = counter + 1 ;
    freeDofs[ counter ] = indDof ;
  end
  global indDof = indDof + 1 ;
end
#
# assembly
KG = zeros( 2*numNodes, 2*numNodes );
FG = zeros( 2*numNodes );
for elem in 1:numElems
  print(" assembling stiffness matrix of element ", elem , "\n")
  indexFirstNode  = connecMatrix[ elem, 1 ]
  indexSecondNode = connecMatrix[ elem, 2 ]
  dofsElem = [2*indexFirstNode-1 2*indexFirstNode 2*indexSecondNode-1 2*indexSecondNode ]
  KGelem, lengthElem = unitaryStiffnessMatrix( nodesCMatrix[ indexSecondNode, : ], nodesCMatrix[ indexFirstNode, : ] )
  stiffnessParam = E * A / lengthElem ;
  for i in 1:4
    for j in 1:4
      KG[ dofsElem[i], dofsElem[j] ] = KG[ dofsElem[i], dofsElem[j] ] + stiffnessParam * KGelem[i,j]
    end
  end
end
FG[4] = -1e4 ;
KG = KG[ freeDofs, : ] ;
KG = KG[ :, freeDofs ] ;
FG = FG[ freeDofs ];

u = KG \ FG
UG = zeros( 2*numNodes );
UG[ freeDofs ] = u ;
#
# #### Deformed structure
#
# The reference (dashed blue line) and deformed (solid red)  configurations of the structure are ploted. Since the displacements are very small, a `scaleFactor` is considered to amplify the deformation and ease the visualization.
#
using Plots
scaleFactor = 2e3 ;
plot();
for elem in 1:numElems
  indexFirstNode  = connecMatrix[ elem, 1 ];
  indexSecondNode = connecMatrix[ elem, 2 ];
  ## plot reference element
  plot!( nodesCMatrix[ [indexFirstNode, indexSecondNode], 1 ],
         nodesCMatrix[ [indexFirstNode, indexSecondNode], 2 ],
         linestyle = :dash,  aspect_ratio = :equal,
         linecolor = "blue", legend = false)

  ## plot deformed element
  plot!( nodesCMatrix[ [indexFirstNode, indexSecondNode], 1 ]
           + scaleFactor* [ UG[indexFirstNode*2-1], UG[indexSecondNode*2-1]] ,
         nodesCMatrix[ [indexFirstNode, indexSecondNode], 2 ]
           + scaleFactor* [ UG[indexFirstNode*2  ], UG[indexSecondNode*2  ]] , markershape = :circle, aspect_ratio = :equal, linecolor = "red",
           linewidth=1.5, legend = false )
end
xlabel!("x (m)") # hide
ylabel!("y (m)") # hide
title!( "Deformed with scale factor " * string(scaleFactor) ) # hide
savefig("deformed.png") # hide
#
# ![](deformed.png)
#
# ### Problem with interval parameters
#
# TO DO

max_stars_repo_name: lucaferranti/IntervalLinearAlgebra

max_issues_repo_name: lucaferranti/IntervalLinearAlgebra

max_forks_repo_name: lucaferranti/IntervalLinearAlgebra


text:
module penetrators

#projectiles
lb = 0.00014286
nato_7p62 = AP(55*lb, 700, 0, 0.244, 0.281, 0.500)
us_7p62 = AP(81*lb, 700, 0, 0.244, 0.281, 0.781)
us_p50 = AP(404*lb, 700, 0, 0.429, 0.493, 1.2464)

#fragments

frag_p5 = Sphere(0.5)
frag_cyl = Cylinder(1.25, 0.5)

end


text:
using .HyperDualNumbers

function blkimpv_hyper(num1,num2,num3,num4,num5)
	@eval function blkimpv(S0::$num1,K::$num2,r::$num3,T::$num4,Price::$num5,FlagIsCall::Bool=true,xtol::Real=1e-14,ytol::Real=1e-15)

		blscheck(S0,K,r,T,0.1,r);

		return blsimpv(S0,K,r,T,Price,r,FlagIsCall);

	end
end

type_blkimpv_hyper_1=[Hyper,Union{Real,Hyper},Union{Real,Hyper},Union{Real,Hyper},Union{Real,Hyper}]
type_blkimpv_hyper_2=[Real,Hyper,Union{Real,Hyper},Union{Real,Hyper},Union{Real,Hyper}]
type_blkimpv_hyper_3=[Real,Real,Union{Real,Hyper},Union{Real,Hyper},Union{Real,Hyper}]
blkimpv_hyper(type_blkimpv_hyper_1[1],type_blkimpv_hyper_1[2],type_blkimpv_hyper_1[3],type_blkimpv_hyper_1[4],type_blkimpv_hyper_1[5])
blkimpv_hyper(type_blkimpv_hyper_2[1],type_blkimpv_hyper_2[2],type_blkimpv_hyper_2[3],type_blkimpv_hyper_2[4],type_blkimpv_hyper_2[5])
blkimpv_hyper(type_blkimpv_hyper_3[1],type_blkimpv_hyper_3[2],type_blkimpv_hyper_3[3],type_blkimpv_hyper_3[4],type_blkimpv_hyper_3[5])

function blsimpv_hyper(num1,num2,num3,num4,num5,num6)
	@eval function blsimpv(S0::$num1,K::$num2,r::$num3,T::$num4,Price::$num5,d::$num6=0.0,FlagIsCall::Bool=true,xtol::Real=1e-14,ytol::Real=1e-15)
	if (Price < 0)
		throw(ErrorException("Option Price Cannot Be Negative"));
	end
	FinancialToolbox.blscheck(S0,K,r,T,0.1,d);
	value__(x)=x.value;
	value__(x::Real)=x;
	f(x)=(blsprice(value__(S0),value__(K),value__(r),value__(T),x,value__(d),FlagIsCall)-value__(Price));
	σ=FinancialToolbox.brentMethod(f,0.001,1.2,xtol,ytol);
	out=hyper(0.0)
	if(!ishyper(Price))
		der_=-(blsprice(S0,K,r,T,σ,d,FlagIsCall)/blsvega(value__(S0),value__(K),value__(r),value__(T),σ,value__(d),FlagIsCall)).epsilon1
		der_2=((blsprice(S0,K,r,T,σ,d,FlagIsCall).epsilon12+blsvega(S0,K,r,T,σ,d,FlagIsCall).epsilon1*der_)*blsvega(value__(S0),value__(K),value__(r),value__(T),σ,value__(d),FlagIsCall)-blsprice(S0,K,r,T,σ,d,FlagIsCall).epsilon1*(blsvega(S0,K,r,T,σ,d,FlagIsCall).epsilon1+blsvega(value__(S0),value__(K),value__(r),value__(T),hyper(σ,1.0,1.0,0.0),value__(d),FlagIsCall).epsilon1*der_))/(blsvega(value__(S0),value__(K),value__(r),value__(T),σ,value__(d),FlagIsCall)^2)
		out=hyper(σ,der_,der_,-der_2);
	else
		der_=1/blsvega(value__(S0),value__(K),value__(r),value__(T),σ,value__(d),FlagIsCall)
		der_2=-(blsprice(S0,K,r,T,hyper(σ,1.0,1.0,0.0),d,FlagIsCall).epsilon12)/(blsvega(value__(S0),value__(K),value__(r),value__(T),σ,value__(d),FlagIsCall)^3)
		out=hyper(σ,der_,der_,der_2);
	end

	return out;

	end
end

type_blsimpv_hyper_1=[Hyper,Union{Real,Hyper},Union{Real,Hyper},Union{Real,Hyper},Union{Real,Hyper},Union{Real,Hyper}]
type_blsimpv_hyper_2=[Real,Hyper,Union{Real,Hyper},Union{Real,Hyper},Union{Real,Hyper},Union{Real,Hyper}]
type_blsimpv_hyper_3=[Real,Real,Union{Real,Hyper},Union{Real,Hyper},Union{Real,Hyper},Union{Real,Hyper}]
blsimpv_hyper(type_blsimpv_hyper_1[1],type_blsimpv_hyper_1[2],type_blsimpv_hyper_1[3],type_blsimpv_hyper_1[4],type_blsimpv_hyper_1[5],type_blsimpv_hyper_1[6])
blsimpv_hyper(type_blsimpv_hyper_2[1],type_blsimpv_hyper_2[2],type_blsimpv_hyper_2[3],type_blsimpv_hyper_2[4],type_blsimpv_hyper_2[5],type_blsimpv_hyper_2[6])
blsimpv_hyper(type_blsimpv_hyper_3[1],type_blsimpv_hyper_3[2],type_blsimpv_hyper_3[3],type_blsimpv_hyper_3[4],type_blsimpv_hyper_3[5],type_blsimpv_hyper_3[6])


text:
#############################################################################
#############################################################################
#
# This file implements polynomial GCD
#
#############################################################################
#############################################################################

"""
The extended euclid algorithm for polynomials modulo prime.
"""
function extended_euclid_alg(a::PolynomialModP, b::PolynomialModP)
    @assert a.prime == b.prime
    old_r, r = mod(a.terms,a.prime), mod(b.terms,b.prime)
    old_s, s = one(Polynomial), zero(Polynomial)
    old_t, t = zero(Polynomial), one(Polynomial)

    while !iszero(mod(r,a.prime))
        q = divide(PolynomialModP(old_r, a.prime), PolynomialModP(r, a.prime)) |> first
        old_r, r = r, mod(old_r - q*r, a.prime)
        old_s, s = s, mod(old_s - q*s, a.prime)
        old_t, t = t, mod(old_t - q*t, a.prime)
    end
    g, s, t = old_r, old_s, old_t
    @assert mod(s*a.terms + t*b.terms - g, a.prime) == 0
    return g, s, t
end

"""
The GCD of two polynomials modulo prime.
"""
gcd(a::PolynomialModP, b::PolynomialModP) = extended_euclid_alg(a,b) |> first


text:
module PiecewiseTransformation

using SPPL

n = @sppl begin
    X ~ SPPL.Normal(0, 2)
    X < 1 ? Z .> -X^3 + X^2 + 6*X : Z .> -5 * Sqrt(X) + 11
end

model = n.model
modelc = model.condition((0 < n.Z) < 2)

end # module


text:
# load ImpvolEquilibrium first so that methods are accessible
include("../../equilibrium.jl")
using ImpvolEquilibrium, FileIO, JLD2

## these are needed for data -> parameters mapping
parameters = Dict{Symbol, Any}()

# CES parameters
sigmas = [0.3 0.4 0.5 0.7 0.8 0.9 0.999 1.1 1.2 1.3 1.5 1.75 2.0]
parameters[:theta] = 4.0
parameters[:eta] = 4.0

########## parameters common across scenarios
## these are function of data
# inverse of adjustment cost, 0 if cannot readjust
parameters[:one_over_rho] = 0.0

for sigma in sigmas
	parameters[:sigma] = sigma
	include("../config.jl")

	try
		mkdir("$sigma")
	catch
	end
	jldopen("$sigma/common_parameters.jld2", "w") do file
		file["parameters"] = parameters
	end
end


text:
using ClimateMachine
const clima_dir = dirname(dirname(pathof(ClimateMachine)));

if parse(Bool, get(ENV, "CLIMATEMACHINE_PLOT_EDMF_COMPARISON", "false"))
    plot_dir = joinpath(clima_dir, "output", "bomex_edmf", "pycles_comparison")
else
    plot_dir = nothing
end

include(joinpath(@__DIR__, "compute_mse.jl"))

data_file = Dataset(joinpath(PyCLES_output_dataset_path, "Bomex.nc"), "r")

#! format: off
best_mse = OrderedDict()
best_mse["prog_ρ"] = 3.4936203419421122e-02
best_mse["prog_ρu_1"] = 3.0715584660655654e+03
best_mse["prog_ρu_2"] = 1.2897432819935302e-03
best_mse["prog_moisture_ρq_tot"] = 4.1572900459802775e-02
best_mse["prog_turbconv_environment_ρatke"] = 8.5590220998989253e+02
best_mse["prog_turbconv_environment_ρaθ_liq_cv"] = 8.5667227621106434e+01
best_mse["prog_turbconv_environment_ρaq_tot_cv"] = 1.6437582130429374e+02
best_mse["prog_turbconv_updraft_1_ρa"] = 8.0846471185616252e+01
best_mse["prog_turbconv_updraft_1_ρaw"] = 8.5071186636845333e-02
best_mse["prog_turbconv_updraft_1_ρaθ_liq"] = 9.0386637425608303e+00
best_mse["prog_turbconv_updraft_1_ρaq_tot"] = 1.0803377515313473e+01
#! format: on

computed_mse = compute_mse(
    solver_config.dg.grid,
    solver_config.dg.balance_law,
    time_data,
    dons_arr,
    data_file,
    "Bomex",
    best_mse,
    400,
    plot_dir,
)

@testset "BOMEX EDMF Solution Quality Assurance (QA) tests" begin
    #! format: off
    test_mse(computed_mse, best_mse, "prog_ρ")
    test_mse(computed_mse, best_mse, "prog_ρu_1")
    test_mse(computed_mse, best_mse, "prog_ρu_2")
    test_mse(computed_mse, best_mse, "prog_moisture_ρq_tot")
    test_mse(computed_mse, best_mse, "prog_turbconv_environment_ρatke")
    test_mse(computed_mse, best_mse, "prog_turbconv_environment_ρaθ_liq_cv")
    test_mse(computed_mse, best_mse, "prog_turbconv_environment_ρaq_tot_cv")
    test_mse(computed_mse, best_mse, "prog_turbconv_updraft_1_ρa")
    test_mse(computed_mse, best_mse, "prog_turbconv_updraft_1_ρaw")
    test_mse(computed_mse, best_mse, "prog_turbconv_updraft_1_ρaθ_liq")
    test_mse(computed_mse, best_mse, "prog_turbconv_updraft_1_ρaq_tot")
    #! format: on
end


text:
struct BinDateTimeFactor{T<:Unsigned} <: AbstractFactor{T}
    name::String
    levels::AbstractVector{<:AbstractString}
    bins::AbstractVector{Int64}
    datetimevariate::AbstractDateTimeVariate
end

Base.length(var::BinDateTimeFactor{T}) where {T<:Unsigned} = length(var.datetimevariate)

function BinDateTimeFactor(name::String, bins::AbstractVector{Int64}, dtvariate::AbstractDateTimeVariate)
    bins = issorted(bins) ? bins : sort(bins)
    levelcount = length(bins) - 1
    levels = [@sprintf("[%s,%s%s", string(Dates.epochms2datetime(bins[i])), string(Dates.epochms2datetime(bins[i + 1])), i == levelcount ? "]" : ")") for i in 1:levelcount]
    if levelcount <= typemax(UInt8)
        BinDateTimeFactor{UInt8}(name, levels, bins, dtvariate)
    elseif levelcount <= typemax(UInt16)
        BinDateTimeFactor{UInt16}(name, levels, bins, dtvariate)
    else
        BinDateTimeFactor{UInt32}(name, levels, bins, dtvariate)
    end
end

function factor(dtvariate::AbstractDateTimeVariate, bins::AbstractVector{Int64})
    BinDateTimeFactor(getname(dtvariate), bins, dtvariate)
end

function factor(dtvariate::AbstractDateTimeVariate)
    fromobs = 1
    toobs = length(dtvariate)
    slicelength = verifyslicelength(fromobs, toobs, SLICELENGTH)
    slices = slice(dtvariate, fromobs, toobs, slicelength)
    vset = fold(Set{Int64}(), slices) do acc, slice
        for i in 1:length(slice)
            v = slice[i]
            push!(acc, v)
        end
        acc
    end
    bins = collect(vset)
    sort!(bins)
    BinDateTimeFactor(getname(dtvariate), bins, dtvariate)
end

function slice(factor::BinDateTimeFactor{T}, fromobs::Integer, toobs::Integer, slicelength::Integer) where {T<:Unsigned}
    bins = factor.bins
    binlenm1 = convert(T, length(bins) - 1)
    z = bins[length(bins)]
    f = (x ->
            begin
                if x == z
                    return binlenm1
                elseif x > z || x == zero(Int64)
                    return zero(T)
                else
                    i = searchsortedlast(bins, x)
                    return convert(T, i)
                end
            end
        )
    slicelength = verifyslicelength(fromobs, toobs, slicelength)
    slices = slice(factor.datetimevariate, fromobs, toobs, slicelength)
    mapslice(f, slices, slicelength, T)
end

function Base.map(factor::BinDateTimeFactor{T}, dataframe::AbstractDataFrame) where {T<:Unsigned}
    BinDateTimeFactor(getname(factor), factor.bins, map(factor.datetimevariate, dataframe))
end

function isordinal(factor::BinDateTimeFactor{T}) where {T<:Unsigned}
    true
end

max_stars_repo_name: Statfactory/JuML

max_issues_repo_name: Statfactory/JuML

max_forks_repo_name: Statfactory/JuML


text:
using ADCME

function gpu_test(a)
    gpu_test_ = load_op_and_grad("$(@__DIR__)/build/libGpuTest","gpu_test")
    a = convert_to_tensor([a], [Float64]); a = a[1]
    gpu_test_(a)
end

# TODO: specify your input parameters
a = rand(3)
u = gpu_test(a)
sess = Session(); init(sess)
v1 = run(sess, u)
v2 = 2a
println("Computed: $v1; expected: $v2")


text:
# interactive scan match test

using GLMakie
using Images, ImageTransformations
using ImageView

##

# arp = AlignRadarPose2(...)

##

fig = Figure()
ax = GLMakie.Axis(fig[1,1])
guidict = ImageView.imshow(overlayScanMatcher(arp, [0;0], 0))
canvas = guidict["gui"]["canvas"]

guidict2 = imshow(arp.im1 - arp.im2)
canvas2 = guidict2["gui"]["canvas"]

sl_x = Slider(fig[2, 1], range = -40:1:40, startvalue = 0)
sl_r = Slider(fig[3, 1], range = (-pi/2):0.01:(pi/2), startvalue = 0)
sl_y = Slider(fig[1, 2], range = -40:1:40, horizontal = false, startvalue = 0)

score = Ref(0.0)

##

lift(sl_x.value, sl_y.value, sl_r.value) do x, y, r
  im_ = overlayScanMatcher(arp, [x;y], r; score)
  println("Making x,y,r = $x,$y,$r = $(score[])")
  ImageView.imshow(canvas, im_)

  a = arp.im1
  b = arp.im2
  bp = Caesar.transformImage_SE2(b, [x;y], r, arp.gridscale)
  # get matching padded views
  ap, bpp = paddedviews(0.0, a, bp)
  # @show sqrt(sum((ap-bpp).^2))
  ImageView.imshow(canvas2, ap-bpp)
end

fig

##

#


text:
# #MvLogNormal truncations
# const BoxTruncatedMvLogNormal = TruncatedMvDistribution{MvLogNormal,BoxTruncationRegion}
# const EllipsoidTruncatedMvLogNormal = TruncatedMvDistribution{MvLogNormal,EllipticalTruncationRegion}
# const PolytopeTruncatedMvLogNormal = TruncatedMvDistribution{MvLogNormal,PolytopeTruncationRegion}

# #MvTDist (multi-variate T-distribution) truncations
# const BoxTruncatedMvTDist = TruncatedMvDistribution{MvTDist,BoxTruncationRegion}
# const EllipsoidTruncatedMvTDist = TruncatedMvDistribution{MvTDist,EllipticalTruncationRegion}
# const PolytopeTruncatedMvTDist = TruncatedMvDistribution{MvTDist,PolytopeTruncationRegion}