text:
#!/usr/bin/env julia

# Given some model parameters, plot the channel maps and
# integrated spectrum

using ArgParse

s = ArgParseSettings()
@add_arg_table s begin
    "--config"
    help = "a YAML configuration file"
    default = "config.yaml"
    "--linear"
    help = "Plot the regular linear channel maps."
    action = :store_true
    "--log"
    help = "Plot the channel maps with log stretch."
    action = :store_true
    "--blur"
    help = "Plot the channel maps, convolved with a fake beam."
    action = :store_true
    "--spectrum"
    help = "Plot the spatially-integrated spectrum."
    action = :store_true
end

parsed_args = parse_args(ARGS, s)

import YAML
config = YAML.load(open(parsed_args["config"]))

using DiskJockey.constants
using DiskJockey.image
using DiskJockey.model
using HDF5
using Printf

import PyPlot
import PyPlot.plt
using LaTeXStrings
# import Images

species = config["species"]
transition = config["transition"]
lam0 = lam0s[species * transition]
model = config["model"]

# Read the inclination, position angle, and (grid) radius of the disk. Plot ellipses.
pars = config["parameters"]
r_c = pars["r_c"]
incl = pars["incl"]
PA = pars["PA"]
dpc = pars["dpc"]
vel_sys = pars["vel"]

# from matplotlib.patches import Ellipse
#     ax[:add_artist](PyPlot.matplotlib[:patches][:Ellipse](xy=xy, width=BMIN, height=BMAJ, angle=BPA, facecolor="0.8", linewidth=0.2))
width = r_c / dpc # [arcsec]
height = width * cosd(incl) # [arcsec]

# cmap = plt[:get_cmap]("viridis")
# cmap = plt[:get_cmap]("inferno")
# cmap = plt[:get_cmap]("plasma")
cmap = plt.get_cmap("Blues")

# First contour is at 3 sigma, and then contours go up (or down) in multiples of spacing
function get_levels(rms::Float64, vmax::Float64, spacing = 3)
    levels = Float64[]

    val = 3 * rms
    while (val < vmax)
        append!(levels, [val])
        val += rms * spacing
    end

    return levels
end

# Plot the channel maps using sky convention
"""Plot the channel maps using the sky convention. If log is true, plot intensity using
a log scale."""
function plot_chmaps(img::image.SkyImage; log = false, contours = true, fname = "channel_maps_sky.png")

    if log
        ldata = log10.(img.data .+ 1e-99)
        vvmax = maximum(ldata)
        norm = PyPlot.matplotlib.colors.Normalize(vvmax - 6, vvmax)
    else
        vvmax = maximum(abs, img.data)
        # println(vmin, " ", vmax, " ", vvmax)
        norm = PyPlot.matplotlib.colors.Normalize(0, vvmax)

        if contours
            levels = get_levels(rms, vvmax)
        end
    end

    (im_ny, im_nx) = size(img.data)[1:2] # y and x dimensions of the image

    # Image needs to be flipped along RA dimension
    ext = (img.ra[end], img.ra[1], img.dec[1], img.dec[end])

    # Figure out how many plots we'll have.
    ncols = 8
    nrows = ceil(Int, nlam / ncols)

    xx = 1.5 * 9
    dx = 1.5
    yy = (nrows + 1) * 1.5
    dy = 1.5

    fig, ax = plt.subplots(nrows = nrows, ncols = ncols, figsize = (xx, yy))

    for row = 1:nrows
        for col = 1:ncols
            iframe = col + (row - 1) * ncols

            if col != 1 || row != nrows
                ax[row, col].xaxis.set_ticklabels([])
                ax[row, col].yaxis.set_ticklabels([])
            else
                ax[row, col].set_xlabel(L"$\Delta \alpha \cos \delta$ ('')")
                ax[row, col].set_ylabel(L"$\Delta \delta$ ('')")
            end

            if iframe > nlam
                # Plot a blank square if we run out of channels
                ax[row, col].imshow(zeros((im_ny, im_nx)), cmap = cmap, vmin = 0, vmax = 20, extent = ext, origin = "lower")

            else
                # Flip the frame for Sky convention
                # frame = flipdim(img.data[:,:,iframe], 2)
                frame = reverse(img.data[:,:,iframe], dims = 2)

                if log
                    frame += 1e-15 # Add a tiny bit so that we don't have log10(0)
                    lframe = log10.(frame)
                    im = ax[row, col].imshow(lframe, extent = ext, interpolation = "none", origin = "lower", cmap = cmap, norm = norm)

                else
                    im = ax[row, col].imshow(frame, extent = ext, interpolation = "none", origin = "lower", cmap = cmap, norm = norm)

                    if contours
                        ax[row, col].contour(frame, origin = "lower", colors = "k", levels = levels, extent = ext, linestyles = "solid", linewidths = 0.2)
                    end

                end

                ax[row, col].add_artist(PyPlot.matplotlib.patches.Ellipse((0, 0), width, height, PA, linewidth = 0.15, facecolor = "none", edgecolor = "w"))

                if iframe == 1
                    # Plot the colorbar
                    cax = fig.add_axes([(xx - 0.35 * dx) / xx, (yy - 1.5 * dy) / yy, (0.1 * dx) / xx, dy / yy])
                    cbar = fig.colorbar(mappable = im, cax = cax)

                    cbar.ax.tick_params(labelsize = 6)
                    fig.text(0.99, (yy - 1.7 * dy) / yy, "Jy/beam", size = 8, ha = "right")
                end

                ax[row, col].annotate(@sprintf("%.1f", vels[iframe]), (0.1, 0.8), xycoords = "axes fraction", size = 8)
                ax[row, col].annotate(@sprintf("%.1f", vels_obs[iframe]), (0.1, 0.9), xycoords = "axes fraction", size = 8)
            end

        end
    end

    fig.subplots_adjust(hspace = 0.00, wspace = 0.00, top = (yy - 0.5 * dy) / yy, bottom = (0.5 * dy) / yy, left = (0.5 * dx) / xx, right = (xx - 0.5 * dy) / xx)

    plt.savefig(fname, dpi = 600)

end

# Plot the spatially-integrated spectrum
function plot_spectrum(img::image.SkyImage; fname = "spectrum.png")

    fig = plt.figure()
    ax = fig.add_subplot(111)

    spec = imToSpec(img)

    ax.plot(vels, spec[:,2], ls = "steps-mid")

    ax.set_ylabel(L"$f_\nu$ [Jy]")
    ax.set_xlabel(L"$v$ [km/s]")

    fig.subplots_adjust(left = 0.15, bottom = 0.15, right = 0.85)

    plt.savefig(fname)

    # Calculate integrated line intensity.
    # tot = image.integrateSpec(spec, lam0)
    # println("Total line flux ", tot, " Jy / km / s")
end

pars = convert_dict(config["parameters"], config["model"])

# Assume that image has already been generated by synthesize_model.jl
im = imread()
skim = imToSky(im, pars.dpc)

# Do the velocity conversion here for plot labels in the disk-frame
global nlam = length(skim.lams)
# convert wavelengths to velocities
global vels = c_kms * (skim.lams .- lam0) / lam0

# calculate velocities in the observed frame (whatever the dataset is)
global vels_obs = vels .+ vel_sys

# Make sure we are always plotting channels from blueshift to redshift.
if vels[2] < vels[1]
  println("Flipping channel maps to plot in order of increasing velocity.")
  skim.data = skim.data[:,:,end:-1:1]
  vels = vels[end:-1:1]
  vels_obs = vels_obs[end:-1:1]
end

if parsed_args["linear"]
    plot_chmaps(skim, fname = "chmaps_linear.png", contours = false)
end

if parsed_args["log"]
    plot_chmaps(skim, fname = "chmaps_log.png", log = true, contours = false)
end

if parsed_args["spectrum"]
    plot_spectrum(skim)
end


text:
# Regular struct
struct TextStyle
    font_family
    font_size
    font_weight
    foreground_color
    background_color
    alignment
    rotation
end

# how do we construct an object?
style = TextStyle("Arial", 11, "Bold", "black", "white", "left", 0)

# a new constructor using keyword args
function TextStyle(;
    font_family,
    font_size,
    font_weight = "Normal",
    foreground_color = "black",
    background_color = "white",
    alignment = "left",
    rotation = 0)
return TextStyle(
    font_family,
    font_size,
    font_weight,
    foreground_color,
    background_color,
    alignment,
    rotation)
end

# easier usage
style = TextStyle(
    alignment = "left",
    font_family = "Arial",
    font_weight = "Bold",
    font_size = 11)

# using Base.@kwdef macro
Base.@kwdef struct TextStyle
    font_family
    font_size
    font_weight = "Normal"
    foreground_color = "black"
    background_color= "white"
    alignment = "center"
    rotation = 0
end

# Two constructors are available

methods(TextStyle)
#=
julia> methods(TextStyle)
# 2 methods for generic function "(::Type)":
[1] TextStyle(; font_family, font_size, font_weight, foreground_color, background_color, alignment, rotation) in Main at util.jl:728
[2] TextStyle(font_family, font_size, font_weight, foreground_color, background_color, alignment, rotation) in Main at REPL[1]:2
=#

# sample usage

style = TextStyle(
           alignment = "left",
           font_family = "Arial",
           font_weight = "Bold",
           font_size = 11)
#=
julia> style = TextStyle(
           alignment = "left",
           font_family = "Arial",
           font_weight = "Bold",
           font_size = 11)
TextStyle("Arial", 11, "Bold", "black", "white", "left", 0)
=#

# What if missing mandatory arguments?
#=
julia> TextStyle()
ERROR: UndefKeywordError: keyword argument font_family not assigned
Stacktrace:
 [1] TextStyle() at ./util.jl:722
 [2] top-level scope at REPL[8]:1

julia> TextStyle(font_family = "Arial")
ERROR: UndefKeywordError: keyword argument font_size not assigned
Stacktrace:
 [1] (::Core.var"#kw#Type")(::NamedTuple{(:font_family,),Tuple{String}}, ::Type{TextStyle}) at ./none:0
 [2] top-level scope at REPL[9]:1
=#

ext: jl


text:
"""
    transformLog(data::T, base::Real = ℯ) where T <: AbstractArray{<: Number}

Log transform `data` using log-base, `base`.

# Examples:

```julia-repl
julia> data = [0:5;];

julia> transformLog(data)
6-element Array{Float64,1}:
 -Inf
   0.0
   0.6931471805599453
   1.0986122886681098
   1.3862943611198906
   1.6094379124341003

julia> transformLog(data,2)
6-element Array{Float64,1}:
 -Inf
   0.0
   1.0
   1.5849625007211563
   2.0
   2.321928094887362

```

See also: [`transformRoot`](@ref), [`transformBoxCox`](@ref)
"""
function transformLog(data::T, base::Real = ℯ) where T <: AbstractArray{<: Number}
    log.(base,data)
end

"""
    transformRoot(data::T, index::Real = 10) where T <: AbstractArray{<: Number}

Root transform `data` using root index, `index`.

# Examples:

```julia-repl
julia> data = [0:5;];

julia> transformRoot(data)
6-element Array{Float64,1}:
 0.0
 1.0
 1.0717734625362931
 1.1161231740339044
 1.148698354997035
 1.174618943088019

julia> transformRoot(data,2)
6-element Array{Float64,1}:
 0.0
 1.0
 1.4142135623730951
 1.7320508075688772
 2.0
 2.23606797749979
```

See also: [`transformLog`](@ref), [`transformBoxCox`](@ref)
"""
function transformRoot(data::T, index::Real = 10) where T <: AbstractArray{<: Number}
    data .^ (1/index)
end

"""
    transformBoxCox(data::T, λ::Real = 0.0) where T <: AbstractArray{<: Number}

[Box-Cox power transformation](https://en.wikipedia.org/wiki/Power_transform#Box%E2%80%93Cox_transformation)
following the following function:

```math
y_i^{(\\lambda)} = \\left\\{\\begin{matrix}
\\frac{y_i^\\lambda - 1}{\\lambda} & \\mathrm{if} \\lambda \\neq  0, \\\\
\\mathrm{ln} y_i & \\mathrm{if} \\lambda = 0,
\\end{matrix}\\right.
```

# Examples:

```julia-repl
julia> data = [0:5;];

julia> transformBoxCox(data)
6-element Array{Float64,1}:
 -Inf
   0.0
   0.6931471805599453
   1.0986122886681098
   1.3862943611198906
   1.6094379124341003

julia> transformBoxCox(data,.1)
6-element Array{Float64,1}:
 -10.0
   0.0
   0.7177346253629313
   1.1612317403390437
   1.486983549970351
   1.7461894308801895

julia> transformBoxCox(data,1)
6-element Array{Float64,1}:
 -1.0
  0.0
  1.0
  2.0
  3.0
  4.0
```

See also: [`transformLog`](@ref), [`transformRoot`](@ref)
"""
function transformBoxCox(data::T, λ::Real = 0.0) where T <: AbstractArray{<: Number}
    λ == 0 ? log.(data) : (data .^ λ .- 1) ./ λ
end


text:
using MLJLinearModels, Test, LinearAlgebra
using Random, StableRNGs, DataFrames, ForwardDiff
import MLJBase # not MLJModelInterface, to mimic the full interface

DO_COMPARISONS = false; include("testutils.jl")

m("UTILS"); include("utils.jl")

m("LOSS-PENALTY", false); begin
    mm("generic"); include("loss-penalty/generic.jl")
    mm("utils");   include("loss-penalty/utils.jl")
    mm("robust");  include("loss-penalty/robust.jl")
end

m("GLR", false); begin
    mm("constructors"); include("glr/constructors.jl")
    mm("utils");        include("glr/tools-utils.jl")
    mm("grads-hess");   include("glr/grad-hess-prox.jl")
end

m("FIT", false); begin
    mm("ols-ridge-lasso-elnet");  include("fit/ols-ridge-lasso-elnet.jl")
    mm("logistic & multinomial"); include("fit/logistic-multinomial.jl")
    mm("robust");                 include("fit/robust.jl")
    mm("quantile & LAD");         include("fit/quantile.jl")
end

m("MLJ", false); begin
    mm("metadata");    include("interface/meta.jl")
    mm("fit-predict"); include("interface/fitpredict.jl")
    mm("extras");      include("interface/extras.jl")
end


text:
using PlutoQuestions
using Test
using Markdown
using PlutoUI

@testset "Admonition" begin
       @test typeof(PlutoQuestions.fyi("test")) <: Markdown.MD
       @test typeof(PlutoQuestions.correct()) <: Markdown.MD
       @test typeof(PlutoQuestions.keep_working()) <: Markdown.MD
       @test typeof(PlutoQuestions.not_defined("test")) <: Markdown.MD
       @test typeof(PlutoQuestions.hint("test")) <: Markdown.MD
       @test typeof(PlutoQuestions.still_missing()) <: Markdown.MD
end

q1 = Question{NoDiff}(;description=Markdown.MD("correct"), validators= @safe[true])
q2 = Question{NoDiff}(;description=Markdown.MD("correct"), validators= @safe[missing])
q3 = Question{NoDiff}(;description=Markdown.MD("correct"), validators= @safe[false])
q4 = Question{NoDiff}(;description=Markdown.MD("correct"), validators= @safe[true, false, missing])

qb1 = QuestionBlock(;title=Markdown.MD("title"),
                     description=Markdown.MD("description"),
                     questions = [q1],
                     hints=[ hint(Markdown.MD("Have you tried this?")),
                     hint(Markdown.MD("Have you tried switching it on and off again?"))]
);

qb2 = QuestionBlock(;title=Markdown.MD("title"),
                     description=Markdown.MD("description"),
                     questions = [q1, q2, q3, q4],
                     hints=[ hint(Markdown.MD("Have you tried this?")),
                     hint(Markdown.MD("Have you tried switching it on and off again?"))]

);

@testset "Question" begin
       @test Question{NoDiff}(;description=Markdown.MD("correct"), validators= @safe[true]) |> typeof <: Question{NoDiff}
       @test Question{NoDiff}(;description=Markdown.MD("missing"), validators= @safe[missing]) |> typeof <: Question{NoDiff}
       @test Question{NoDiff}(;description=Markdown.MD("incorrect"), validators= @safe[false]) |> typeof <: Question{NoDiff}
       @test Question{NoDiff}(;description=Markdown.MD("crash"), validators= @safe[a[0]]) |> typeof <: Question{NoDiff}

       @test Question{Easy}(;description=Markdown.MD("correct"), validators= @safe[true]) |> typeof <: Question{Easy}
       @test Question{Easy}(;description=Markdown.MD("missing"), validators= @safe[missing]) |> typeof <: Question{Easy}
       @test Question{Easy}(;description=Markdown.MD("incorrect"), validators= @safe[false]) |> typeof <: Question{Easy}
       @test Question{Easy}(;description=Markdown.MD("crash"), validators= @safe[a[0]]) |> typeof <: Question{Easy}

       @test Question{Intermediate}(;description=Markdown.MD("correct"), validators= @safe[true]) |> typeof <: Question{Intermediate}
       @test Question{Intermediate}(;description=Markdown.MD("missing"), validators= @safe[missing]) |> typeof <: Question{Intermediate}
       @test Question{Intermediate}(;description=Markdown.MD("incorrect"), validators= @safe[false]) |> typeof <: Question{Intermediate}
       @test Question{Intermediate}(;description=Markdown.MD("crash"), validators= @safe[a[0]]) |> typeof <: Question{Intermediate}

       @test Question{Hard}(;description=Markdown.MD("correct"), validators= @safe[true]) |> typeof <: Question{Hard}
       @test Question{Hard}(;description=Markdown.MD("missing"), validators= @safe[missing]) |> typeof <: Question{Hard}
       @test Question{Hard}(;description=Markdown.MD("incorrect"), validators= @safe[false]) |> typeof <: Question{Hard}
       @test Question{Hard}(;description=Markdown.MD("crash"), validators= @safe[a[0]]) |> typeof <: Question{Hard}

       @test Question{NoDiff}(;description=Markdown.MD("correct"), validators= @safe[missing, true, false, missing]) |> typeof <: Question{NoDiff}

       @test q1 |> PlutoQuestions.check_answer |> typeof <: Markdown.MD
       @test q4 |> PlutoQuestions.check_answer |> typeof <: Markdown.MD
       @test qb1 |> typeof <: QuestionBlock
       @test qb1 |> validate |> typeof <:QuestionBlock
       @test qb1 |> PlutoQuestions.tohtml |> typeof <:String

       @test qb2 |> typeof <: QuestionBlock
       @test qb2 |> validate |> typeof <:QuestionBlock
       @test qb2 |> PlutoQuestions.tohtml |> typeof <:String

end

@testset "Macros" begin
     # I use zero-indexing to induce a `BoundsError`
     @test !@safe([2.0][0])
     @test @safe([2.0][1]) == 2.0
end

max_stars_repo_name: Beramos/PlutoTeaching

max_issues_repo_name: Beramos/PlutoTeaching

max_forks_repo_name: Beramos/PlutoTeaching


text:
export ortho_latin, check_ortho

"""
`A,B = ortho_latin(n)` returns a pair of orthogonal `n`-by-`n`
Latin squares.

`A,B = ortho_latin(n,true)` returns a pair of orthogonal Latin squares
that are transposes of each other.

`A,B = ortho_latin(n,r,s)` builds the Latin squares `latin(n,r)`
and `latin(n,s)` and, if they are orthogonal, returns them as the
answer. (Otherwise, throws an error.) See: `find_ortho_parameters`.
"""
function ortho_latin(n::Int, self::Bool = false)
    if !self
        try
            r, s = find_ortho_parameters(n)
            return ortho_latin(n, r, s)
        catch
        end
    end
    println("No quick solution. Using integer programming.")

    return ortho_latin_IP(n, self)
end

function ortho_latin_IP(n::Int, self::Bool = false)
    MOD = Model(get_solver())
    # Z[i,j,k,l] is an indicator that there is a k in A[i,j] and
    # an l in B[i,j]
    @variable(MOD, Z[1:n, 1:n, 1:n, 1:n], Bin)

    # one entry per cell constraint
    for i = 1:n
        for j = 1:n
            @constraint(MOD, sum(Z[i, j, k, l] for k = 1:n for l = 1:n) == 1)
        end
    end

    # Top row 11 22 33 ... nn
    if !self
        for i = 1:n
            @constraint(MOD, Z[1, i, i, i] == 1)  # A[1,i] = B[1,i] = i
        end
    end

    # orthogonality constraint
    for k = 1:n
        for l = 1:n
            @constraint(MOD, sum(Z[i, j, k, l] for i = 1:n for j = 1:n) == 1)
        end
    end

    # Row constraints

    for i = 1:n
        for k = 1:n
            @constraint(MOD, sum(Z[i, j, k, l] for j = 1:n for l = 1:n) == 1)
        end
    end

    for i = 1:n
        for l = 1:n
            @constraint(MOD, sum(Z[i, j, k, l] for j = 1:n for k = 1:n) == 1)
        end
    end

    # Col constraints
    for j = 1:n
        for k = 1:n
            @constraint(MOD, sum(Z[i, j, k, l] for i = 1:n for l = 1:n) == 1)
        end
    end

    for j = 1:n
        for l = 1:n
            @constraint(MOD, sum(Z[i, j, k, l] for i = 1:n for k = 1:n) == 1)
        end
    end

    if self   # force A^T==B
        for i = 1:n
            for j = 1:n
                for k = 1:n
                    for l = 1:n
                        @constraint(MOD, Z[i, j, k, l] == Z[j, i, l, k])
                    end
                end
            end
        end
    end

    optimize!(MOD)
    status = Int(termination_status(MOD))

    if status != 1
        error("No pair of orthogonal Latin squares of order $n can be found.")
    end

    ZZ = value.(Z)
    A = zeros(Int, n, n)
    B = zeros(Int, n, n)

    for i = 1:n
        for j = 1:n
            for k = 1:n
                for l = 1:n
                    if ZZ[i, j, k, l] > 0
                        A[i, j] = k
                        B[i, j] = l
                    end
                end
            end
        end
    end

    return A, B
end

function ortho_latin(n::Int, r::Int, s::Int)
    A = latin(n, r)
    B = latin(n, s)
    @assert check_ortho(A, B) "Parameters n=$n, r=$r, and s=$s do not generate a pair of orthogonal Latin squares"
    return A, B
end

"""
`find_ortho_parameters(n)` tries to find parameters `r` and `s`
so that `ortho_latin(n,r,s)` will succeed. Returns `(r,s)` if
successful or throws an error if not.
"""
function find_ortho_parameters(n::Int)
    for r = 1:n-1
        for s = 1:n-1
            if gcd(n, r) == 1 && gcd(n, s) == 1 && gcd(n, r - s) == 1
                return r, s
            end
        end
    end
    error("No parameters for n=$n found")
end

"""
`check_ortho(A,B)` checks that matrices `A` and `B` are a pair of
orthogonal Latin squares.
"""
function check_ortho(A::Matrix{Int}, B::Matrix{Int})::Bool
    if size(A) != size(B)
        return false
    end
    if !check_latin(A) || !check_latin(B)
        return false
    end
    n, r = size(A)

    vals = unique((n + 1) * A + B)
    return length(vals) == n * n
end


text:
using Documenter, Theta

makedocs(sitename="Theta.jl")

deploydocs(
    repo = "github.com/chualynn/Theta.jl.git",
)


text:
using Symbolics, Test
using DomainSets
@variables x y

I1 = Integral(x in ClosedInterval(1, 5))
I2 = Integral(x in ClosedInterval(1, 5))
@test I1 == I2

@variables v(..) u(..) x y
D = Differential(x)
Dxx = Differential(x)^2
I = Integral(y in ClosedInterval(1, 5))
eq = D(I(u(x,y))) ~ 0
eq_test = I(D(u(x,y)))
@test isequal(expand_derivatives(eq.lhs), Symbolics.value(eq_test))

eq = Dxx((I(u(x,y)))) + I(D(u(x,y))) ~ 0
eq_test = I(D(u(x,y))) + I(D(D(u(x,y))))
@test isequal(expand_derivatives(eq.lhs), Symbolics.value(eq_test))

I = Integral(y in ClosedInterval(1, v(x)))
eq = D((I(u(x,y)))) ~ 0
eq_test = I(D(u(x,y))) + D(v(x))*u(x, v(x))
@test isequal(expand_derivatives(eq.lhs), Symbolics.value(eq_test))

I = Integral(y in ClosedInterval(1, v(x)))
eq = Dxx((I(u(x,y)))) ~ 0
eq_test = D(I(D(u(x,y))) + D(v(x))*u(x, v(x)))
eq_test_ = I(D(D(u(x,y)))) + D(D(v(x)))*u(x, v(x)) + 2D(u(x,v(x)))*D(v(x))
@test isequal(expand_derivatives(eq.lhs), Symbolics.value(eq_test_))
@test isequal(expand_derivatives(eq.lhs), expand_derivatives(eq_test))

eq = D((I(u(x,y)^2))) ~ 0
eq_test = I(2D(u(x,y))*u(x,y)) + D(v(x))*u(x, v(x))^2
@test isequal(expand_derivatives(eq.lhs), Symbolics.value(eq_test))


text:
using LatticeVis
using Base.Test

# write your own tests here

lattice = Lattice(Honeycomb, 10)
plot(lattice)


text:
using Cxx
using Gallium

if isdefined(Base, :active_repl)
    include(Pkg.dir("Cxx","src","CxxREPL","replpane.jl"))
    include(Pkg.dir("Gallium","src","lldbrepl.jl"))
end

const dbg = debugger()
RunLLDBRepl(dbg)

function Base.CFILE(fd::RawFD, mode)
    @unix_only FILEp = ccall(:fdopen, Ptr{Void}, (Cint, Ptr{UInt8}), convert(Cint, fd.fd), mode)
    @windows_only FILEp = ccall(:_fdopen, Ptr{Void}, (Cint, Ptr{UInt8}), convert(Cint, fd.fd), mode)
    systemerror("fdopen", FILEp == C_NULL)
    CFILE(FILEp)
end

SetOutputFileHandle(dbg,CFILE(Base._fd(STDOUT),Base.modestr(false,true)), false)
SetErrorFileHandle(dbg,CFILE(Base._fd(STDERR),Base.modestr(false,true)), false)

lldb_exec(dbg,"target create ~/os161/root/kernel")
lldb_exec(dbg,"process connect connect://localhost:2000")
const target = targets(dbg)[0]


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

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

"""

Gets details about a specified subscription.
Param: subscriptionId::String (required)
Param: api_version::String (required)
Return: Subscription
"""
function subscriptionsGet(_api::SubscriptionsApi, subscriptionId::String, api_version::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", Subscription, "/subscriptions/{subscriptionId}", ["azure_auth"])
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

Gets all subscriptions for a tenant.
Param: api_version::String (required)
Return: SubscriptionListResult
"""
function subscriptionsList(_api::SubscriptionsApi, api_version::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", SubscriptionListResult, "/subscriptions", ["azure_auth"])
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""
Gets all available geo-locations.
This operation provides all the locations that are available for resource providers; however, each resource provider may support a subset of this list.
Param: subscriptionId::String (required)
Param: api_version::String (required)
Return: LocationListResult
"""
function subscriptionsListLocations(_api::SubscriptionsApi, subscriptionId::String, api_version::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", LocationListResult, "/subscriptions/{subscriptionId}/locations", ["azure_auth"])
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    Swagger.exec(_ctx)
end

export subscriptionsGet, subscriptionsList, subscriptionsListLocations


text:
module EMLstreams
	using DanaTypes
	using DotPlusInheritance
	using Reexport
	@reexport using ...types.EMLtypes
	import EMLtypes.length
	include("streams/stream.jl")
	include("streams/liquid_stream.jl")
	include("streams/vapour_stream.jl")
	include("streams/streamPH.jl")
	include("streams/streamPHS.jl")
	include("streams/source.jl")
	include("streams/source2.jl")
	include("streams/simple_source.jl")
	include("streams/simple_source2.jl")
	include("streams/sink.jl")
	include("streams/sink2.jl")
	include("streams/simple_sink.jl")
	include("streams/simple_sink2.jl")
	include("streams/energy_source.jl")
	include("streams/energy_source2.jl")
	include("streams/energy_sink.jl")
	include("streams/work_source.jl")
	include("streams/info_stream.jl")
	include("streams/sourceNoFlow.jl")
	include("streams/sinkNoFlow.jl")
end