text:
### A Pluto.jl notebook ###
# v0.17.2

using Markdown
using InteractiveUtils

# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error).
macro bind(def, element)
    quote
        local iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end
        local el = $(esc(element))
        global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el)
        el
    end
end

# ╔═╡ 673b5f44-0db4-4848-95d7-24a31e7e86b1
begin
	#try
		using PlutoUI
		using Plots
		using Plots.PlotMeasures
		using LaTeXStrings
		using Markdown
		using StatsBase
		using Images
		using DelimitedFiles

		#using LinearAlgebra
		#using SparseArrays
		#using SpecialFunctions
		#using StatsBase
		using Random
		#using Distributions
		md"""
		### Packages

		All needed Packages available :) """
	#=catch
		using Pkg;
		Pkg.activate(mktempdir())
		Pkg.add("PlutoUI")
		Pkg.add("Plots")
		Pkg.add("LaTeXStrings")
		Pkg.add("Markdown")
		Pkg.add("Images")
		Pkg.add("Random")
		Pkg.add("DelimitedFiles")
		Pkg.add("StatsBase")
		#Pkg.add("LinearAlgebra")
		#Pkg.add("SparseArrays")
		#Pkg.add("SpecialFunctions")
		#Pkg.add("StatsBase")
		#Pkg.add("Distributions")
		using PlutoUI, Plots, LaTeXStrings, Markdown, Images, Plots.PlotMeasures, Random, DelimitedFiles, StatsBase

		#using LinearAlgebra
		#using SparseArrays
		#using StatsBase

		md"""
		### Packages

		Some Package sources not added, this will take approx. 3 minutes"""
	end
	=#
end

# ╔═╡ e342faf1-550f-4b6f-963e-ef53ac581c0b
#todo:
#scale invariance
#vdL im Video nix von multiple orders of magnitude erwähnt, also was jetzt?
#i am confused

# ╔═╡ 2dde8f33-1166-42b9-834f-7bcb54895992
md""" # Benford's Law"""

# ╔═╡ 245d5573-09f4-4536-b104-351a7669cd8b
md""" If you haven't already, you can watch the new episode here!"""

# ╔═╡ 9a4bc5f5-7acd-4640-a71b-82051b6d3db3
html"""

"""

# ╔═╡ 27811f40-08a7-4da7-9788-db4b0c47153b
Markdown.MD(Markdown.Admonition("hint", string("Benford's law"), [md"""For a lot of naturally occurring datasets, the probability that the leading digit of a number in the set is the number  `` d \in \{1, 2, 3, .. 9\}`` can be calculated with

``P(d) = \log_{10}(d + 1) - \log_{10}(d)``"""]))

# ╔═╡ 0527804c-68b7-42f9-8830-c41d6b9036f4
md""" **Bayes:**
...But to be sure, let's have a look at your data!"""

# ╔═╡ 91d8c001-c210-4c42-a7f2-5e84ee907ea6
md""" **Lyra:** I've collected data on different kinds of things - litter in the ocean, how many Frogfish are caught on a weekly basis, and the population of all organisms on the reefs! Which one do you want to see first?"""

# ╔═╡ fb1b6ea0-330c-4744-b3b8-19730b55e7e5
begin
	md"""
	Choose the **data** to compare 👉 $(@bind data_list Select(["Mass of marine litter in g", "Mass of marine litter in lbs", "Pieces of litter on the beach", "Frogfish caught weekly", "Reef population", "Random data"]))
	"""

end

# ╔═╡ 56b1302d-6a0e-4262-aa0e-9ae98c2167df
if data_list == "Random data"
md""" Choose a seed for the randomly generated data! $(@bind seed Scrubbable(0:1:20))"""
end

# ╔═╡ 64d6faa9-1564-4d7d-bf32-02f0720fa552
md"""
## Comparison with Benford's law
"""

# ╔═╡ c13206e8-ff41-405a-b9b8-50b589854901
md""" **Lyra:** You're right, it does coincide quite well! But there are some cases, where it does not work at all! Do you know why, Captain Bayes?

**Bayes:** Benford's law applies to many, albeit not all naturally occurring datasets. The data has to be scale invariant. But the question is how do we know if this is the case?
A good hint for scale invariance is data that spans several magnitudes. In many cases this is a sufficient criteria.

We can examine our data in the histogram below, for some data you can observe a bias which is the reason why Benford's law is violated.

"""

# ╔═╡ a2a6d8c3-c9b7-458d-b5a7-6d3b3f68a926
md"""
## Data analysis and discussion
"""

# ╔═╡ 8a30e661-3057-4a30-a495-b1523b42207b
begin
	MarineLitter = html"Marine Litter"
	ReefPopulation = html"Reef Population"
	Frogfish = html"Frogfish"

	md""" ## Did you know?

	The data analyzed here is acual scientific data! You can find our sources here:

	$(MarineLitter) (yes this is actual litter collected from beaches)

	$(ReefPopulation) (this is actually the population of US cities with more than 6000 inhabitants)

	$(Frogfish) (this is actually Pacific Salmon caught weekly)

	"""

end

# ╔═╡ 4f48ef9a-05ea-41f9-a2a0-381865b8be6a
md""" # Derivation of Benford's Law using scale invariance"""

# ╔═╡ 601c53ed-ac2f-48fe-8afa-6b511a3ef369
html"""

"""

# ╔═╡ a8d53828-ca73-4cb7-906f-ca2c94735a93
md"""
## About the creators

This notebook was created by **Johanna Moser** and **Gerhard Dorn** in the context of the course **Bayesian probability theory**.

The course is a free massive open online course (MOOC) available on the platform [`IMOOX`](https://imoox.at/mooc/local/landingpage/course.php?shortname=bayes&lang=en)

$(Resource("https://raw.githubusercontent.com/Captain-Bayes/images/main/adventure_map.gif"))
"""

# ╔═╡ 7b74d968-8591-49ba-81d8-9d8485676e93
TableOfContents()

# ╔═╡ 05d42951-063d-45d6-87ce-4d15b0472b84
begin

	# how to extract data from the non so csv csv file
	#=
	file_source = readdlm("data_marine_litter.csv", '\\')
		litter_count = []
		litter_mass = []
		for i in 3:986
			append!(litter_count, parse(Float64, reverse(split(file_source[i], ","))[8]))
		append!(litter_mass, parse(Float64, reverse(split(file_source[i], ","))[7]))
			end
		#a1 = convert(Array{Float64,1}, marine_numbers)

	writedlm("litter_beach.txt", [["count" "mass"]; [litter_count litter_mass]], "," )

	=#
end

# ╔═╡ a491e298-7a49-4cef-b269-886455538348
begin

	check_box_skip = @bind skip_low_gram CheckBox()
	select_counting = @bind count_in_pairs_dozens Select(["Single pieces", "Pairs", "Dozens"])

	md"""
	### define Checkboxes and Sliders """
end

# ╔═╡ 8368ba6c-cada-4caa-b37f-752034bfd571
begin
	if data_list =="Mass of marine litter in g🚯" || data_list =="Mass of marine litter in lbs 🚯"

		md""" See what happens if we **exclude objects** with **less than 10 grams** ⚖ from our analysis 👉 $(check_box_skip)

		Check Benford's law now in the first plot 👆"""
	elseif data_list == "Pieces of litter on the beach"
			md""" Change the way of counting 👉 $(select_counting)"""

	end

end

# ╔═╡ 5dfa126f-754f-4d25-a191-6e5437df99da
begin
	#read in data

	# population
	temp_population =  readdlm("data_city_population.csv", ';', skipblanks = true, skipstart = 1)[1:6889,3]

	population = parse.(Float64, filter.(x -> !isspace(x), temp_population))

	# litter
	litter_pieces = readdlm("litter_beach.txt",',', skipstart = 1)[:,1]
	litter_mass = readdlm("litter_beach.txt",',', skipstart = 1)[:,2]
	if skip_low_gram
		litter_mass = litter_mass[litter_mass .>= 10]

	end

	if count_in_pairs_dozens == "Pairs"
		litter_pieces = litter_pieces./2
	elseif count_in_pairs_dozens == "Dozens"
		litter_pieces = litter_pieces./12
	end

	# fish population

	fish_catches = readdlm("data_salmon.csv", ',', skipstart = 1)[:,5]

	md"""
	## Load data"""
end

# ╔═╡ ea7c16d9-dd13-41c6-9c03-431d068fd105
begin
	claire = "https://raw.githubusercontent.com/Captain-Bayes/images/main/claire_100px.gif"
	lyra = "https://raw.githubusercontent.com/Captain-Bayes/images/main/lyra_50px.gif"
	bayes = "https://raw.githubusercontent.com/Captain-Bayes/images/main/bayes_100px.gif"
	bernoulli = "https://raw.githubusercontent.com/Captain-Bayes/images/main/Bernoulli_wet.gif"
	island = "https://raw.githubusercontent.com/Captain-Bayes/images/main/Turtle_island_with_ship.png"
	map = "https://raw.githubusercontent.com/Captain-Bayes/images/main/Fishground_map.png"
	frogfish_image = "https://raw.githubusercontent.com/Captain-Bayes/images/main/frogfish_green_full.gif"
	venn = "https://raw.githubusercontent.com/Captain-Bayes/images/main/venn_100px.gif"
	angles_view = "https://raw.githubusercontent.com/Captain-Bayes/images/main/Gipfel_angles.png"
	mountain_view = "https://raw.githubusercontent.com/Captain-Bayes/images/main/Gipfel_view.png"
	image_of_data = "https://raw.githubusercontent.com/Captain-Bayes/images/main/Daten_brett.png"
	diagram_of_data = "https://raw.githubusercontent.com/Captain-Bayes/images/main/Diagram.png"
	treasure_map = "https://raw.githubusercontent.com/Captain-Bayes/images/main/Treasure_map_2.png"

	md"""Images"""
end

# ╔═╡ 0615b18c-23b6-4f93-99ff-2044588dccf2
md""" $(Resource(lyra, :width=>180))

When strolling on the beach, I find all kinds of stuff getting washed up by the ocean!

I keep a statistic on my findings, and I have noticed a strange pattern regarding the distribution of the first digits of my data:

I would have expected to find an equal distribution of all numbers as the first digit in my statistics, but it turns out that most entries in my datasets start with a 1, followed by 2, and decreasing - up to the point, that it is 6.6 times more likely to find an entry starting with a 1 than with a 9!

Weird, isn't it?"""

# ╔═╡ 468c679f-6a42-4801-a908-82ab5a4c9507
md"""$(Resource(bayes, :width=>180))

That's interesting. Your description does sound like we could apply Benford's law.
"""

# ╔═╡ 7959439c-f947-40b3-8d2a-7dc96e90bbdc
#commentaries
begin
	if data_list =="Mass of marine litter in g🚯"

		md"""
		The data's range spans 4 orders of magnitude and the comparison with Benford's law looks promising. However the data is **biased** 😨🤯, because so much data is in the one digit area and the values are **rounded** to integers in grams, so all 0.5 to 0.9 entries are mapped to one gram. Check the conversion to pound which actually should not alter the result.

		 $(Resource(bayes, :width=>180))"""

	elseif data_list =="Mass of marine litter in lbs 🚯"
		md"""
		**Bayes:** The data's range spans 4 orders of magnitude. Now you see the effect of the bias. We have converted the mass in gram to mass in pound by multiplying with 0.002something. This should not alter the result, but the bias due to rounding and having so many entries in the one digit range in grams has now a considerable effect.

		 $(Resource(bayes, :width=>180))"""
	elseif data_list =="Pieces of litter on the beach"

		md"""

		**Bayes:** The data's range spans 3 orders of magnitude. At first glance the behaviour corresponds to the one predicted by Benford's law.

		**BUT:** There might be a slight bias due to the fact that we can only have integer numbers and a lot of ONES in the data. We could check if the data is scale invariant if we count in pairs or in dozens.

		$(Resource(bayes, :width=>180))"""

	elseif data_list =="Frogfish caught weekly"
		md"""
		**Bayes:** The data spans several orders of magnitude, so this is a good hint for scale invariance and we see that the data behaves according to Benford's law.
$(Resource(bayes, :width=>180))"""

	elseif data_list =="Reef population"
		md""" **Bayes:** The data's range spans almost 3 orders of magnitude. But since there surely are populations at the Reef that have less inhabitants, I am guessing you have cut off the data at some point, is that correct?

$(Resource(bayes, :width=>180))

**Lyra:**  Oh my, yes that is correct! I got so bored with counting groups of only 10 fish! I decided to only count populations that are higher than 6000! Does that interfere with the analysis of the numbers?

$(Resource(lyra, :width=>180))

**Bayes:** I'm afraid so. But at least that can explain the peak at 6!"""

	elseif data_list == "Random data"
		md"""
		This data was generated by generating 10000 random (equally distributed) numbers A in a range of (ln(10^-8), ln(10^+8")) and then calculating exp(A). This way, we can assure data spanning multiple orders of magnitude. This type of data is called **log uniform**
		"""

					end
end

# ╔═╡ 1f8c2dfc-1f42-41f9-b18d-3f04df20e527
begin
almost(text, headline=md"Almost there!") = Markdown.MD(Markdown.Admonition("warning", string(headline), [text]));
#brown

correct(text=md"Great! You got the right answer!", headline=md"Got it!") = Markdown.MD(Markdown.Admonition("correct", string(headline), [text]));
#green

keep_working(text=md"The answer is not quite right.", headline=md"Keep working on it!") = Markdown.MD(Markdown.Admonition("danger", string(headline), [text]));
#red

hint(text, headline=md"Hint") = Markdown.MD(Markdown.Admonition("hint", string(headline), [text]));
#blue

md"definition of boxes"
end

# ╔═╡ ce366a2b-3933-4b4b-a01c-c0a1ed7da96a
#definition of get_firstdigit
function get_first_digit(data) #data must be array of numbers
	#get rounded number (to highest power of 10)
	rounded = floor.(log.(10, data))
	#get number between 0 and 10
	mantissa = data ./ (10 .^rounded)
	digit = floor.(mantissa)
	firstdigit = digit[0 .< digit .< 10]
	return firstdigit

end

# ╔═╡ deb756be-10ee-43c5-b466-9909b4431268
function normalize(array)
	#gets keys and values out of countmap and returns keys and normed values in 2D list
	dict_values = []
	key = sort(collect(keys(countmap(array))))
	for i in key
		append!(dict_values, countmap(array)[i])
		end
	if key[1] == 0
	normed_dict_values = dict_values/sum(dict_values[2:10])
	return [key[2:10], normed_dict_values[2:10]]
	else
		normed_dict_values = dict_values/sum(dict_values)
		return [key, normed_dict_values]
	end
end

# ╔═╡ ac233104-737c-4a92-843d-45042ba25cd1
begin
#data

	if data_list == "Random data"
		#generate data
		rng = MersenneTwister(seed)
		sample_size = 10000
		# parameters of random number generator fort scale invariant random numbers
		x0     = 10^(-10)   # smallest number
		x1     = 10^10      # largest number

		ln0    = log(x0)
		ln1    = log(x1)
		lsx    = rand(rng,ln0:ln1,sample_size)
		a1 = exp.(lsx)

	elseif data_list == "Reef population"
		a1 = population

	elseif data_list == "Frogfish caught weekly"
		#get data
		a1 = fish_catches

	elseif data_list == "Pieces of litter on the beach"
		a1 = litter_pieces

	elseif data_list == "Mass of marine litter in g"
		a1 = litter_mass

	elseif data_list == "Mass of marine litter in lbs"
		a1= litter_mass .* 0.00220462

	end

#get first digits
first_digits = get_first_digit(a1)
#plot
bar(normalize(first_digits)[1], normalize(first_digits)[2], label = "Data")

#theory

d = range(1,stop = 9, length = 50)
p_benford = log.(10, (d .+ 1.0)) - log.(10, d)

d_discrete = range(1,stop = 9, length = 9)
p_benford_discrete = log.(10, (d_discrete .+ 1.0)) - log.(10, d_discrete )

plot!(d , p_benford, label = "Theory",

	linewidth = 3)
plot!(d_discrete,p_benford_discrete, line = :scatter, label = :none,
		title = "Testing Benford's Law for " * String(data_list),
		xlabel = "first digit",
		ylabel = "relative frequency",
		#xlim = [0,10],
		size = (600,400),
		labelfontsize = 15,
		tickfontsize = 13,
		bottom_margin =5mm,
		left_margin = 5mm,
		right_margin = 5mm,
		linewidth = 5,
		titlefontsize = 13,
		#foreground_color_grid = :black,
		#foreground_color_xticks = :black,
		background_color = :transparent,
		#foreground_color_axis = :black,
		#foreground_color_text = :black,
		#foreground_color_border = :black,
		foreground_color = :black,
		fontfamily="Computer Modern")

end

# ╔═╡ d16680ec-541d-42f0-867e-4259b30adcdb
begin
#plot logarithmic histogram of data
a2 = a1[0 .< a1]
	bins_exp = range(log10(minimum(a2)), log10(maximum(a2)), step = 0.1)
		bins =  10 .^ bins_exp

	plot((histogram(a1; bins, xaxis=(:log10, [minimum(a2), :auto]))),
		label = "",
		title = "Frequency analysis of data \n(" * String(data_list) * ")",
		xlabel = "range",
		ylabel = "frequencies",
		#xlim = [0,10],
		size = (600,400),
		labelfontsize = 15,
		tickfontsize = 13,
		bottom_margin =5mm,
		left_margin = 5mm,
		right_margin = 5mm,
		linewidth = 1,
		titlefontsize = 16,
		#foreground_color_grid = :black,
		#foreground_color_xticks = :black,
		background_color = :transparent,
		#foreground_color_axis = :black,
		#foreground_color_text = :black,
		#foreground_color_border = :black,
		foreground_color = :black,
		fontfamily="Computer Modern")

end

# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
DelimitedFiles = "8bb1440f-4735-579b-a4ab-409b98df4dab"
Images = "916415d5-f1e6-5110-898d-aaa5f9f070e0"
LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"

[compat]
Images = "~0.25.0"
LaTeXStrings = "~1.3.0"
Plots = "~1.24.0"
PlutoUI = "~0.7.20"
StatsBase = "~0.33.13"
"""

# ╔═╡ 00000000-0000-0000-0000-000000000002
PLUTO_MANIFEST_TOML_CONTENTS = """
# This file is machine-generated - editing it directly is not advised

[[AbstractFFTs]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "485ee0867925449198280d4af84bdb46a2a404d0"
uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c"
version = "1.0.1"

[[AbstractPlutoDingetjes]]
deps = ["Pkg"]
git-tree-sha1 = "0bc60e3006ad95b4bb7497698dd7c6d649b9bc06"
uuid = "6e696c72-6542-2067-7265-42206c756150"
version = "1.1.1"

[[Adapt]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "84918055d15b3114ede17ac6a7182f68870c16f7"
uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
version = "3.3.1"

[[ArgTools]]
uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f"

[[ArnoldiMethod]]
deps = ["LinearAlgebra", "Random", "StaticArrays"]
git-tree-sha1 = "62e51b39331de8911e4a7ff6f5aaf38a5f4cc0ae"
uuid = "ec485272-7323-5ecc-a04f-4719b315124d"
version = "0.2.0"

[[ArrayInterface]]
deps = ["Compat", "IfElse", "LinearAlgebra", "Requires", "SparseArrays", "Static"]
git-tree-sha1 = "e527b258413e0c6d4f66ade574744c94edef81f8"
uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9"
version = "3.1.40"

[[Artifacts]]
uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"

[[AxisAlgorithms]]
deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"]
git-tree-sha1 = "66771c8d21c8ff5e3a93379480a2307ac36863f7"
uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950"
version = "1.0.1"

[[AxisArrays]]
deps = ["Dates", "IntervalSets", "IterTools", "RangeArrays"]
git-tree-sha1 = "d127d5e4d86c7680b20c35d40b503c74b9a39b5e"
uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9"
version = "0.4.4"

[[Base64]]
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"

[[Bzip2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "19a35467a82e236ff51bc17a3a44b69ef35185a2"
uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0"
version = "1.0.8+0"

[[CEnum]]
git-tree-sha1 = "215a9aa4a1f23fbd05b92769fdd62559488d70e9"
uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82"
version = "0.4.1"

[[Cairo_jll]]
deps = ["Artifacts", "Bzip2_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"]
git-tree-sha1 = "f2202b55d816427cd385a9a4f3ffb226bee80f99"
uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a"
version = "1.16.1+0"

[[CatIndices]]
deps = ["CustomUnitRanges", "OffsetArrays"]
git-tree-sha1 = "a0f80a09780eed9b1d106a1bf62041c2efc995bc"
uuid = "aafaddc9-749c-510e-ac4f-586e18779b91"
version = "0.2.2"

[[ChainRulesCore]]
deps = ["Compat", "LinearAlgebra", "SparseArrays"]
git-tree-sha1 = "f885e7e7c124f8c92650d61b9477b9ac2ee607dd"
uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
version = "1.11.1"

[[ChangesOfVariables]]
deps = ["LinearAlgebra", "Test"]
git-tree-sha1 = "9a1d594397670492219635b35a3d830b04730d62"
uuid = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0"
version = "0.1.1"

[[Clustering]]
deps = ["Distances", "LinearAlgebra", "NearestNeighbors", "Printf", "SparseArrays", "Statistics", "StatsBase"]
git-tree-sha1 = "75479b7df4167267d75294d14b58244695beb2ac"
uuid = "aaaa29a8-35af-508c-8bc3-b662a17a0fe5"
version = "0.14.2"

[[ColorSchemes]]
deps = ["ColorTypes", "Colors", "FixedPointNumbers", "Random"]
git-tree-sha1 = "a851fec56cb73cfdf43762999ec72eff5b86882a"
uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4"
version = "3.15.0"

[[ColorTypes]]
deps = ["FixedPointNumbers", "Random"]
git-tree-sha1 = "024fe24d83e4a5bf5fc80501a314ce0d1aa35597"
uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f"
version = "0.11.0"

[[ColorVectorSpace]]
deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "TensorCore"]
git-tree-sha1 = "3f1f500312161f1ae067abe07d13b40f78f32e07"
uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4"
version = "0.9.8"

[[Colors]]
deps = ["ColorTypes", "FixedPointNumbers", "Reexport"]
git-tree-sha1 = "417b0ed7b8b838aa6ca0a87aadf1bb9eb111ce40"
uuid = "5ae59095-9a9b-59fe-a467-6f913c188581"
version = "0.12.8"

[[Compat]]
deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "SHA", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"]
git-tree-sha1 = "dce3e3fea680869eaa0b774b2e8343e9ff442313"
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
version = "3.40.0"

[[CompilerSupportLibraries_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"

[[ComputationalResources]]
git-tree-sha1 = "52cb3ec90e8a8bea0e62e275ba577ad0f74821f7"
uuid = "ed09eef8-17a6-5b46-8889-db040fac31e3"
version = "0.3.2"

[[Contour]]
deps = ["StaticArrays"]
git-tree-sha1 = "9f02045d934dc030edad45944ea80dbd1f0ebea7"
uuid = "d38c429a-6771-53c6-b99e-75d170b6e991"
version = "0.5.7"

[[CoordinateTransformations]]
deps = ["LinearAlgebra", "StaticArrays"]
git-tree-sha1 = "681ea870b918e7cff7111da58791d7f718067a19"
uuid = "150eb455-5306-5404-9cee-2592286d6298"
version = "0.6.2"

[[CustomUnitRanges]]
git-tree-sha1 = "1a3f97f907e6dd8983b744d2642651bb162a3f7a"
uuid = "dc8bdbbb-1ca9-579f-8c36-e416f6a65cce"
version = "1.0.2"

[[DataAPI]]
git-tree-sha1 = "cc70b17275652eb47bc9e5f81635981f13cea5c8"
uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
version = "1.9.0"

[[DataStructures]]
deps = ["Compat", "InteractiveUtils", "OrderedCollections"]
git-tree-sha1 = "7d9d316f04214f7efdbb6398d545446e246eff02"
uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
version = "0.18.10"

[[DataValueInterfaces]]
git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6"
uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464"
version = "1.0.0"

[[Dates]]
deps = ["Printf"]
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"

[[DelimitedFiles]]
deps = ["Mmap"]
uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab"

[[Distances]]
deps = ["LinearAlgebra", "Statistics", "StatsAPI"]
git-tree-sha1 = "837c83e5574582e07662bbbba733964ff7c26b9d"
uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7"
version = "0.10.6"

[[Distributed]]
deps = ["Random", "Serialization", "Sockets"]
uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"

[[DocStringExtensions]]
deps = ["LibGit2"]
git-tree-sha1 = "b19534d1895d702889b219c382a6e18010797f0b"
uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
version = "0.8.6"

[[Downloads]]
deps = ["ArgTools", "LibCURL", "NetworkOptions"]
uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6"

[[EarCut_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "3f3a2501fa7236e9b911e0f7a588c657e822bb6d"
uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5"
version = "2.2.3+0"

[[EllipsisNotation]]
deps = ["ArrayInterface"]
git-tree-sha1 = "9aad812fb7c4c038da7cab5a069f502e6e3ae030"
uuid = "da5c29d0-fa7d-589e-88eb-ea29b0a81949"
version = "1.1.1"

[[Expat_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "b3bfd02e98aedfa5cf885665493c5598c350cd2f"
uuid = "2e619515-83b5-522b-bb60-26c02a35a201"
version = "2.2.10+0"

[[FFMPEG]]
deps = ["FFMPEG_jll"]
git-tree-sha1 = "b57e3acbe22f8484b4b5ff66a7499717fe1a9cc8"
uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a"
version = "0.4.1"

[[FFMPEG_jll]]
deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "Pkg", "Zlib_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"]
git-tree-sha1 = "d8a578692e3077ac998b50c0217dfd67f21d1e5f"
uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5"
version = "4.4.0+0"

[[FFTViews]]
deps = ["CustomUnitRanges", "FFTW"]
git-tree-sha1 = "cbdf14d1e8c7c8aacbe8b19862e0179fd08321c2"
uuid = "4f61f5a4-77b1-5117-aa51-3ab5ef4ef0cd"
version = "0.3.2"

[[FFTW]]
deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"]
git-tree-sha1 = "463cb335fa22c4ebacfd1faba5fde14edb80d96c"
uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"
version = "1.4.5"

[[FFTW_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "c6033cc3892d0ef5bb9cd29b7f2f0331ea5184ea"
uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a"
version = "3.3.10+0"

[[FileIO]]
deps = ["Pkg", "Requires", "UUIDs"]
git-tree-sha1 = "2db648b6712831ecb333eae76dbfd1c156ca13bb"
uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
version = "1.11.2"

[[FixedPointNumbers]]
deps = ["Statistics"]
git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc"
uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93"
version = "0.8.4"

[[Fontconfig_jll]]
deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03"
uuid = "a3f928ae-7b40-5064-980b-68af3947d34b"
version = "2.13.93+0"

[[Formatting]]
deps = ["Printf"]
git-tree-sha1 = "8339d61043228fdd3eb658d86c926cb282ae72a8"
uuid = "59287772-0a20-5a39-b81b-1366585eb4c0"
version = "0.4.2"

[[FreeType2_jll]]
deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "87eb71354d8ec1a96d4a7636bd57a7347dde3ef9"
uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7"
version = "2.10.4+0"

[[FriBidi_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91"
uuid = "559328eb-81f9-559d-9380-de523a88c83c"
version = "1.0.10+0"

[[GLFW_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pkg", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"]
git-tree-sha1 = "0c603255764a1fa0b61752d2bec14cfbd18f7fe8"
uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89"
version = "3.3.5+1"

[[GR]]
deps = ["Base64", "DelimitedFiles", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Pkg", "Printf", "Random", "Serialization", "Sockets", "Test", "UUIDs"]
git-tree-sha1 = "30f2b340c2fff8410d89bfcdc9c0a6dd661ac5f7"
uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71"
version = "0.62.1"

[[GR_jll]]
deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Pkg", "Qt5Base_jll", "Zlib_jll", "libpng_jll"]
git-tree-sha1 = "fd75fa3a2080109a2c0ec9864a6e14c60cca3866"
uuid = "d2c73de3-f751-5644-a686-071e5b155ba9"
version = "0.62.0+0"

[[GeometryBasics]]
deps = ["EarCut_jll", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"]
git-tree-sha1 = "58bcdf5ebc057b085e58d95c138725628dd7453c"
uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326"
version = "0.4.1"

[[Gettext_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"]
git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046"
uuid = "78b55507-aeef-58d4-861c-77aaff3498b1"
version = "0.21.0+0"

[[Glib_jll]]
deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "7bf67e9a481712b3dbe9cb3dac852dc4b1162e02"
uuid = "7746bdde-850d-59dc-9ae8-88ece973131d"
version = "2.68.3+0"

[[Graphics]]
deps = ["Colors", "LinearAlgebra", "NaNMath"]
git-tree-sha1 = "1c5a84319923bea76fa145d49e93aa4394c73fc2"
uuid = "a2bd30eb-e257-5431-a919-1863eab51364"
version = "1.1.1"

[[Graphite2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011"
uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472"
version = "1.3.14+0"

[[Graphs]]
deps = ["ArnoldiMethod", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"]
git-tree-sha1 = "92243c07e786ea3458532e199eb3feee0e7e08eb"
uuid = "86223c79-3864-5bf0-83f7-82e725a168b6"
version = "1.4.1"

[[Grisu]]
git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2"
uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe"
version = "1.0.2"

[[HTTP]]
deps = ["Base64", "Dates", "IniFile", "Logging", "MbedTLS", "NetworkOptions", "Sockets", "URIs"]
git-tree-sha1 = "0fa77022fe4b511826b39c894c90daf5fce3334a"
uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3"
version = "0.9.17"

[[HarfBuzz_jll]]
deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"]
git-tree-sha1 = "8a954fed8ac097d5be04921d595f741115c1b2ad"
uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566"
version = "2.8.1+0"

[[Hyperscript]]
deps = ["Test"]
git-tree-sha1 = "8d511d5b81240fc8e6802386302675bdf47737b9"
uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91"
version = "0.0.4"

[[HypertextLiteral]]
git-tree-sha1 = "2b078b5a615c6c0396c77810d92ee8c6f470d238"
uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2"
version = "0.9.3"

[[IOCapture]]
deps = ["Logging", "Random"]
git-tree-sha1 = "f7be53659ab06ddc986428d3a9dcc95f6fa6705a"
uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89"
version = "0.2.2"

[[IfElse]]
git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1"
uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173"
version = "0.1.1"

[[ImageAxes]]
deps = ["AxisArrays", "ImageBase", "ImageCore", "Reexport", "SimpleTraits"]
git-tree-sha1 = "c54b581a83008dc7f292e205f4c409ab5caa0f04"
uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac"
version = "0.6.10"

[[ImageBase]]
deps = ["ImageCore", "Reexport"]
git-tree-sha1 = "b51bb8cae22c66d0f6357e3bcb6363145ef20835"
uuid = "c817782e-172a-44cc-b673-b171935fbb9e"
version = "0.1.5"

[[ImageContrastAdjustment]]
deps = ["ImageCore", "ImageTransformations", "Parameters"]
git-tree-sha1 = "0d75cafa80cf22026cea21a8e6cf965295003edc"
uuid = "f332f351-ec65-5f6a-b3d1-319c6670881a"
version = "0.3.10"

[[ImageCore]]
deps = ["AbstractFFTs", "ColorVectorSpace", "Colors", "FixedPointNumbers", "Graphics", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "Reexport"]
git-tree-sha1 = "9a5c62f231e5bba35695a20988fc7cd6de7eeb5a"
uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534"
version = "0.9.3"

[[ImageDistances]]
deps = ["Distances", "ImageCore", "ImageMorphology", "LinearAlgebra", "Statistics"]
git-tree-sha1 = "7a20463713d239a19cbad3f6991e404aca876bda"
uuid = "51556ac3-7006-55f5-8cb3-34580c88182d"
version = "0.2.15"

[[ImageFiltering]]
deps = ["CatIndices", "ComputationalResources", "DataStructures", "FFTViews", "FFTW", "ImageBase", "ImageCore", "LinearAlgebra", "OffsetArrays", "Reexport", "SparseArrays", "StaticArrays", "Statistics", "TiledIteration"]
git-tree-sha1 = "15bd05c1c0d5dbb32a9a3d7e0ad2d50dd6167189"
uuid = "6a3955dd-da59-5b1f-98d4-e7296123deb5"
version = "0.7.1"

[[ImageIO]]
deps = ["FileIO", "Netpbm", "OpenEXR", "PNGFiles", "TiffImages", "UUIDs"]
git-tree-sha1 = "a2951c93684551467265e0e32b577914f69532be"
uuid = "82e4d734-157c-48bb-816b-45c225c6df19"
version = "0.5.9"

[[ImageMagick]]
deps = ["FileIO", "ImageCore", "ImageMagick_jll", "InteractiveUtils", "Libdl", "Pkg", "Random"]
git-tree-sha1 = "5bc1cb62e0c5f1005868358db0692c994c3a13c6"
uuid = "6218d12a-5da1-5696-b52f-db25d2ecc6d1"
version = "1.2.1"

[[ImageMagick_jll]]
deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pkg", "Zlib_jll", "libpng_jll"]
git-tree-sha1 = "ea2b6fd947cdfc43c6b8c15cff982533ec1f72cd"
uuid = "c73af94c-d91f-53ed-93a7-00f77d67a9d7"
version = "6.9.12+0"

[[ImageMetadata]]
deps = ["AxisArrays", "ImageAxes", "ImageBase", "ImageCore"]
git-tree-sha1 = "36cbaebed194b292590cba2593da27b34763804a"
uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49"
version = "0.9.8"

[[ImageMorphology]]
deps = ["ImageCore", "LinearAlgebra", "Requires", "TiledIteration"]
git-tree-sha1 = "5581e18a74a5838bd919294a7138c2663d065238"
uuid = "787d08f9-d448-5407-9aad-5290dd7ab264"
version = "0.3.0"

[[ImageQualityIndexes]]
deps = ["ImageContrastAdjustment", "ImageCore", "ImageDistances", "ImageFiltering", "OffsetArrays", "Statistics"]
git-tree-sha1 = "1d2d73b14198d10f7f12bf7f8481fd4b3ff5cd61"
uuid = "2996bd0c-7a13-11e9-2da2-2f5ce47296a9"
version = "0.3.0"

[[ImageSegmentation]]
deps = ["Clustering", "DataStructures", "Distances", "Graphs", "ImageCore", "ImageFiltering", "ImageMorphology", "LinearAlgebra", "MetaGraphs", "RegionTrees", "SimpleWeightedGraphs", "StaticArrays", "Statistics"]
git-tree-sha1 = "36832067ea220818d105d718527d6ed02385bf22"
uuid = "80713f31-8817-5129-9cf8-209ff8fb23e1"
version = "1.7.0"

[[ImageShow]]
deps = ["Base64", "FileIO", "ImageBase", "ImageCore", "OffsetArrays", "StackViews"]
git-tree-sha1 = "d0ac64c9bee0aed6fdbb2bc0e5dfa9a3a78e3acc"
uuid = "4e3cecfd-b093-5904-9786-8bbb286a6a31"
version = "0.3.3"

[[ImageTransformations]]
deps = ["AxisAlgorithms", "ColorVectorSpace", "CoordinateTransformations", "ImageBase", "ImageCore", "Interpolations", "OffsetArrays", "Rotations", "StaticArrays"]
git-tree-sha1 = "b4b161abc8252d68b13c5cc4a5f2ba711b61fec5"
uuid = "02fcd773-0e25-5acc-982a-7f6622650795"
version = "0.9.3"

[[Images]]
deps = ["Base64", "FileIO", "Graphics", "ImageAxes", "ImageBase", "ImageContrastAdjustment", "ImageCore", "ImageDistances", "ImageFiltering", "ImageIO", "ImageMagick", "ImageMetadata", "ImageMorphology", "ImageQualityIndexes", "ImageSegmentation", "ImageShow", "ImageTransformations", "IndirectArrays", "IntegralArrays", "Random", "Reexport", "SparseArrays", "StaticArrays", "Statistics", "StatsBase", "TiledIteration"]
git-tree-sha1 = "35dc1cd115c57ad705c7db9f6ef5cc14412e8f00"
uuid = "916415d5-f1e6-5110-898d-aaa5f9f070e0"
version = "0.25.0"

[[Imath_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "87f7662e03a649cffa2e05bf19c303e168732d3e"
uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1"
version = "3.1.2+0"

[[IndirectArrays]]
git-tree-sha1 = "012e604e1c7458645cb8b436f8fba789a51b257f"
uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959"
version = "1.0.0"

[[Inflate]]
git-tree-sha1 = "f5fc07d4e706b84f72d54eedcc1c13d92fb0871c"
uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9"
version = "0.1.2"

[[IniFile]]
deps = ["Test"]
git-tree-sha1 = "098e4d2c533924c921f9f9847274f2ad89e018b8"
uuid = "83e8ac13-25f8-5344-8a64-a9f2b223428f"
version = "0.5.0"

[[IntegralArrays]]
deps = ["IntervalSets"]
git-tree-sha1 = "26c4df96fdf6127a92d53cb8ffb577104617adca"
uuid = "1d092043-8f09-5a30-832f-7509e371ab51"
version = "0.1.0"

[[IntelOpenMP_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "d979e54b71da82f3a65b62553da4fc3d18c9004c"
uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0"
version = "2018.0.3+2"

[[InteractiveUtils]]
deps = ["Markdown"]
uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"

[[Interpolations]]
deps = ["AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"]
git-tree-sha1 = "61aa005707ea2cebf47c8d780da8dc9bc4e0c512"
uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59"
version = "0.13.4"

[[IntervalSets]]
deps = ["Dates", "EllipsisNotation", "Statistics"]
git-tree-sha1 = "3cc368af3f110a767ac786560045dceddfc16758"
uuid = "8197267c-284f-5f27-9208-e0e47529a953"
version = "0.5.3"

[[InverseFunctions]]
deps = ["Test"]
git-tree-sha1 = "a7254c0acd8e62f1ac75ad24d5db43f5f19f3c65"
uuid = "3587e190-3f89-42d0-90ee-14403ec27112"
version = "0.1.2"

[[IrrationalConstants]]
git-tree-sha1 = "7fd44fd4ff43fc60815f8e764c0f352b83c49151"
uuid = "92d709cd-6900-40b7-9082-c6be49f344b6"
version = "0.1.1"

[[IterTools]]
git-tree-sha1 = "05110a2ab1fc5f932622ffea2a003221f4782c18"
uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e"
version = "1.3.0"

[[IteratorInterfaceExtensions]]
git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856"
uuid = "82899510-4779-5014-852e-03e436cf321d"
version = "1.0.0"

[[JLD2]]
deps = ["DataStructures", "FileIO", "MacroTools", "Mmap", "Pkg", "Printf", "Reexport", "TranscodingStreams", "UUIDs"]
git-tree-sha1 = "46b7834ec8165c541b0b5d1c8ba63ec940723ffb"
uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819"
version = "0.4.15"

[[JLLWrappers]]
deps = ["Preferences"]
git-tree-sha1 = "642a199af8b68253517b80bd3bfd17eb4e84df6e"
uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210"
version = "1.3.0"

[[JSON]]
deps = ["Dates", "Mmap", "Parsers", "Unicode"]
git-tree-sha1 = "8076680b162ada2a031f707ac7b4953e30667a37"
uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
version = "0.21.2"

[[JpegTurbo_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "d735490ac75c5cb9f1b00d8b5509c11984dc6943"
uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8"
version = "2.1.0+0"

[[LAME_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c"
uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d"
version = "3.100.1+0"

[[LZO_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6"
uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac"
version = "2.10.1+0"

[[LaTeXStrings]]
git-tree-sha1 = "f2355693d6778a178ade15952b7ac47a4ff97996"
uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
version = "1.3.0"

[[Latexify]]
deps = ["Formatting", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "Printf", "Requires"]
git-tree-sha1 = "a8f4f279b6fa3c3c4f1adadd78a621b13a506bce"
uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316"
version = "0.15.9"

[[LazyArtifacts]]
deps = ["Artifacts", "Pkg"]
uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3"

[[LibCURL]]
deps = ["LibCURL_jll", "MozillaCACerts_jll"]
uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21"

[[LibCURL_jll]]
deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"]
uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0"

[[LibGit2]]
deps = ["Base64", "NetworkOptions", "Printf", "SHA"]
uuid = "76f85450-5226-5b5a-8eaa-529ad045b433"

[[LibSSH2_jll]]
deps = ["Artifacts", "Libdl", "MbedTLS_jll"]
uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8"

[[Libdl]]
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"

[[Libffi_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "0b4a5d71f3e5200a7dff793393e09dfc2d874290"
uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490"
version = "3.2.2+1"

[[Libgcrypt_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"]
git-tree-sha1 = "64613c82a59c120435c067c2b809fc61cf5166ae"
uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4"
version = "1.8.7+0"

[[Libglvnd_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll"]
git-tree-sha1 = "7739f837d6447403596a75d19ed01fd08d6f56bf"
uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29"
version = "1.3.0+3"

[[Libgpg_error_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9"
uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8"
version = "1.42.0+0"

[[Libiconv_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "42b62845d70a619f063a7da093d995ec8e15e778"
uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531"
version = "1.16.1+1"

[[Libmount_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "9c30530bf0effd46e15e0fdcf2b8636e78cbbd73"
uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9"
version = "2.35.0+0"

[[Libtiff_jll]]
deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "Zlib_jll", "Zstd_jll"]
git-tree-sha1 = "340e257aada13f95f98ee352d316c3bed37c8ab9"
uuid = "89763e89-9b03-5906-acba-b20f662cd828"
version = "4.3.0+0"

[[Libuuid_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "7f3efec06033682db852f8b3bc3c1d2b0a0ab066"
uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700"
version = "2.36.0+0"

[[LinearAlgebra]]
deps = ["Libdl"]
uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"

[[LogExpFunctions]]
deps = ["ChainRulesCore", "ChangesOfVariables", "DocStringExtensions", "InverseFunctions", "IrrationalConstants", "LinearAlgebra"]
git-tree-sha1 = "be9eef9f9d78cecb6f262f3c10da151a6c5ab827"
uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688"
version = "0.3.5"

[[Logging]]
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"

[[MKL_jll]]
deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"]
git-tree-sha1 = "5455aef09b40e5020e1520f551fa3135040d4ed0"
uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7"
version = "2021.1.1+2"

[[MacroTools]]
deps = ["Markdown", "Random"]
git-tree-sha1 = "3d3e902b31198a27340d0bf00d6ac452866021cf"
uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
version = "0.5.9"

[[MappedArrays]]
git-tree-sha1 = "e8b359ef06ec72e8c030463fe02efe5527ee5142"
uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900"
version = "0.4.1"

[[Markdown]]
deps = ["Base64"]
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"

[[MbedTLS]]
deps = ["Dates", "MbedTLS_jll", "Random", "Sockets"]
git-tree-sha1 = "1c38e51c3d08ef2278062ebceade0e46cefc96fe"
uuid = "739be429-bea8-5141-9913-cc70e7f3736d"
version = "1.0.3"

[[MbedTLS_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"

[[Measures]]
git-tree-sha1 = "e498ddeee6f9fdb4551ce855a46f54dbd900245f"
uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e"
version = "0.3.1"

[[MetaGraphs]]
deps = ["Graphs", "JLD2", "Random"]
git-tree-sha1 = "2af69ff3c024d13bde52b34a2a7d6887d4e7b438"
uuid = "626554b9-1ddb-594c-aa3c-2596fe9399a5"
version = "0.7.1"

[[Missings]]
deps = ["DataAPI"]
git-tree-sha1 = "bf210ce90b6c9eed32d25dbcae1ebc565df2687f"
uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28"
version = "1.0.2"

[[Mmap]]
uuid = "a63ad114-7e13-5084-954f-fe012c677804"

[[MosaicViews]]
deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"]
git-tree-sha1 = "b34e3bc3ca7c94914418637cb10cc4d1d80d877d"
uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389"
version = "0.3.3"

[[MozillaCACerts_jll]]
uuid = "14a3606d-f60d-562e-9121-12d972cd8159"

[[NaNMath]]
git-tree-sha1 = "bfe47e760d60b82b66b61d2d44128b62e3a369fb"
uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
version = "0.3.5"

[[NearestNeighbors]]
deps = ["Distances", "StaticArrays"]
git-tree-sha1 = "16baacfdc8758bc374882566c9187e785e85c2f0"
uuid = "b8a86587-4115-5ab1-83bc-aa920d37bbce"
version = "0.4.9"

[[Netpbm]]
deps = ["FileIO", "ImageCore"]
git-tree-sha1 = "18efc06f6ec36a8b801b23f076e3c6ac7c3bf153"
uuid = "f09324ee-3d7c-5217-9330-fc30815ba969"
version = "1.0.2"

[[NetworkOptions]]
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"

[[OffsetArrays]]
deps = ["Adapt"]
git-tree-sha1 = "043017e0bdeff61cfbb7afeb558ab29536bbb5ed"
uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
version = "1.10.8"

[[Ogg_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "7937eda4681660b4d6aeeecc2f7e1c81c8ee4e2f"
uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051"
version = "1.3.5+0"

[[OpenEXR]]
deps = ["Colors", "FileIO", "OpenEXR_jll"]
git-tree-sha1 = "327f53360fdb54df7ecd01e96ef1983536d1e633"
uuid = "52e1d378-f018-4a11-a4be-720524705ac7"
version = "0.3.2"

[[OpenEXR_jll]]
deps = ["Artifacts", "Imath_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "923319661e9a22712f24596ce81c54fc0366f304"
uuid = "18a262bb-aa17-5467-a713-aee519bc75cb"
version = "3.1.1+0"

[[OpenLibm_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "05823500-19ac-5b8b-9628-191a04bc5112"

[[OpenSSL_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "15003dcb7d8db3c6c857fda14891a539a8f2705a"
uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95"
version = "1.1.10+0"

[[OpenSpecFun_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1"
uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e"
version = "0.5.5+0"

[[Opus_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720"
uuid = "91d4177d-7536-5919-b921-800302f37372"
version = "1.3.2+0"

[[OrderedCollections]]
git-tree-sha1 = "85f8e6578bf1f9ee0d11e7bb1b1456435479d47c"
uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
version = "1.4.1"

[[PCRE_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "b2a7af664e098055a7529ad1a900ded962bca488"
uuid = "2f80f16e-611a-54ab-bc61-aa92de5b98fc"
version = "8.44.0+0"

[[PNGFiles]]
deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"]
git-tree-sha1 = "6d105d40e30b635cfed9d52ec29cf456e27d38f8"
uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883"
version = "0.3.12"

[[PaddedViews]]
deps = ["OffsetArrays"]
git-tree-sha1 = "646eed6f6a5d8df6708f15ea7e02a7a2c4fe4800"
uuid = "5432bcbf-9aad-5242-b902-cca2824c8663"
version = "0.5.10"

[[Parameters]]
deps = ["OrderedCollections", "UnPack"]
git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe"
uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a"
version = "0.12.3"

[[Parsers]]
deps = ["Dates"]
git-tree-sha1 = "ae4bbcadb2906ccc085cf52ac286dc1377dceccc"
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
version = "2.1.2"

[[Pixman_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "b4f5d02549a10e20780a24fce72bea96b6329e29"
uuid = "30392449-352a-5448-841d-b1acce4e97dc"
version = "0.40.1+0"

[[Pkg]]
deps = ["Artifacts", "Dates", "Downloads", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"]
uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"

[[PkgVersion]]
deps = ["Pkg"]
git-tree-sha1 = "a7a7e1a88853564e551e4eba8650f8c38df79b37"
uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688"
version = "0.1.1"

[[PlotThemes]]
deps = ["PlotUtils", "Requires", "Statistics"]
git-tree-sha1 = "a3a964ce9dc7898193536002a6dd892b1b5a6f1d"
uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a"
version = "2.0.1"

[[PlotUtils]]
deps = ["ColorSchemes", "Colors", "Dates", "Printf", "Random", "Reexport", "Statistics"]
git-tree-sha1 = "b084324b4af5a438cd63619fd006614b3b20b87b"
uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043"
version = "1.0.15"

[[Plots]]
deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "GeometryBasics", "JSON", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "PlotThemes", "PlotUtils", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "UUIDs", "UnicodeFun"]
git-tree-sha1 = "02a083caba3f73e42decb810b2e0740783022978"
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
version = "1.24.0"

[[PlutoUI]]
deps = ["AbstractPlutoDingetjes", "Base64", "Dates", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "Markdown", "Random", "Reexport", "UUIDs"]
git-tree-sha1 = "1e0cb51e0ccef0afc01aab41dc51a3e7f781e8cb"
uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8"
version = "0.7.20"

[[Preferences]]
deps = ["TOML"]
git-tree-sha1 = "00cfd92944ca9c760982747e9a1d0d5d86ab1e5a"
uuid = "21216c6a-2e73-6563-6e65-726566657250"
version = "1.2.2"

[[Printf]]
deps = ["Unicode"]
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"

[[ProgressMeter]]
deps = ["Distributed", "Printf"]
git-tree-sha1 = "afadeba63d90ff223a6a48d2009434ecee2ec9e8"
uuid = "92933f4c-e287-5a05-a399-4b506db050ca"
version = "1.7.1"

[[Qt5Base_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "xkbcommon_jll"]
git-tree-sha1 = "ad368663a5e20dbb8d6dc2fddeefe4dae0781ae8"
uuid = "ea2cea3b-5b76-57ae-a6ef-0a8af62496e1"
version = "5.15.3+0"

[[REPL]]
deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"]
uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"

[[Random]]
deps = ["Serialization"]
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"

[[RangeArrays]]
git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5"
uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d"
version = "0.3.2"

[[Ratios]]
deps = ["Requires"]
git-tree-sha1 = "01d341f502250e81f6fec0afe662aa861392a3aa"
uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439"
version = "0.4.2"

[[RecipesBase]]
git-tree-sha1 = "6bf3f380ff52ce0832ddd3a2a7b9538ed1bcca7d"
uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
version = "1.2.1"

[[RecipesPipeline]]
deps = ["Dates", "NaNMath", "PlotUtils", "RecipesBase"]
git-tree-sha1 = "7ad0dfa8d03b7bcf8c597f59f5292801730c55b8"
uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c"
version = "0.4.1"

[[Reexport]]
git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b"
uuid = "189a3867-3050-52da-a836-e630ba90ab69"
version = "1.2.2"

[[RegionTrees]]
deps = ["IterTools", "LinearAlgebra", "StaticArrays"]
git-tree-sha1 = "4618ed0da7a251c7f92e869ae1a19c74a7d2a7f9"
uuid = "dee08c22-ab7f-5625-9660-a9af2021b33f"
version = "0.3.2"

[[Requires]]
deps = ["UUIDs"]
git-tree-sha1 = "4036a3bd08ac7e968e27c203d45f5fff15020621"
uuid = "ae029012-a4dd-5104-9daa-d747884805df"
version = "1.1.3"

[[Rotations]]
deps = ["LinearAlgebra", "Random", "StaticArrays", "Statistics"]
git-tree-sha1 = "6a23472b6b097d66da87785b61137142ac104f94"
uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc"
version = "1.0.4"

[[SHA]]
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"

[[Scratch]]
deps = ["Dates"]
git-tree-sha1 = "0b4b7f1393cff97c33891da2a0bf69c6ed241fda"
uuid = "6c6a2e73-6563-6170-7368-637461726353"
version = "1.1.0"

[[Serialization]]
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"

[[SharedArrays]]
deps = ["Distributed", "Mmap", "Random", "Serialization"]
uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383"

[[Showoff]]
deps = ["Dates", "Grisu"]
git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de"
uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f"
version = "1.0.3"

[[SimpleTraits]]
deps = ["InteractiveUtils", "MacroTools"]
git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231"
uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d"
version = "0.9.4"

[[SimpleWeightedGraphs]]
deps = ["Graphs", "LinearAlgebra", "Markdown", "SparseArrays", "Test"]
git-tree-sha1 = "a6f404cc44d3d3b28c793ec0eb59af709d827e4e"
uuid = "47aef6b3-ad0c-573a-a1e2-d07658019622"
version = "1.2.1"

[[Sockets]]
uuid = "6462fe0b-24de-5631-8697-dd941f90decc"

[[SortingAlgorithms]]
deps = ["DataStructures"]
git-tree-sha1 = "b3363d7460f7d098ca0912c69b082f75625d7508"
uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c"
version = "1.0.1"

[[SparseArrays]]
deps = ["LinearAlgebra", "Random"]
uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"

[[SpecialFunctions]]
deps = ["ChainRulesCore", "IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"]
git-tree-sha1 = "e08890d19787ec25029113e88c34ec20cac1c91e"
uuid = "276daf66-3868-5448-9aa4-cd146d93841b"
version = "2.0.0"

[[StackViews]]
deps = ["OffsetArrays"]
git-tree-sha1 = "46e589465204cd0c08b4bd97385e4fa79a0c770c"
uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15"
version = "0.1.1"

[[Static]]
deps = ["IfElse"]
git-tree-sha1 = "e7bc80dc93f50857a5d1e3c8121495852f407e6a"
uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3"
version = "0.4.0"

[[StaticArrays]]
deps = ["LinearAlgebra", "Random", "Statistics"]
git-tree-sha1 = "3c76dde64d03699e074ac02eb2e8ba8254d428da"
uuid = "90137ffa-7385-5640-81b9-e52037218182"
version = "1.2.13"

[[Statistics]]
deps = ["LinearAlgebra", "SparseArrays"]
uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"

[[StatsAPI]]
git-tree-sha1 = "0f2aa8e32d511f758a2ce49208181f7733a0936a"
uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0"
version = "1.1.0"

[[StatsBase]]
deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"]
git-tree-sha1 = "2bb0cb32026a66037360606510fca5984ccc6b75"
uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
version = "0.33.13"

[[StructArrays]]
deps = ["Adapt", "DataAPI", "StaticArrays", "Tables"]
git-tree-sha1 = "2ce41e0d042c60ecd131e9fb7154a3bfadbf50d3"
uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a"
version = "0.6.3"

[[TOML]]
deps = ["Dates"]
uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76"

[[TableTraits]]
deps = ["IteratorInterfaceExtensions"]
git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39"
uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c"
version = "1.0.1"

[[Tables]]
deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "TableTraits", "Test"]
git-tree-sha1 = "fed34d0e71b91734bf0a7e10eb1bb05296ddbcd0"
uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
version = "1.6.0"

[[Tar]]
deps = ["ArgTools", "SHA"]
uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e"

[[TensorCore]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6"
uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50"
version = "0.1.1"

[[Test]]
deps = ["InteractiveUtils", "Logging", "Random", "Serialization"]
uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[[TiffImages]]
deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"]
git-tree-sha1 = "c342ae2abf4902d65a0b0bf59b28506a6e17078a"
uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69"
version = "0.5.2"

[[TiledIteration]]
deps = ["OffsetArrays"]
git-tree-sha1 = "5683455224ba92ef59db72d10690690f4a8dc297"
uuid = "06e1c1a7-607b-532d-9fad-de7d9aa2abac"
version = "0.3.1"

[[TranscodingStreams]]
deps = ["Random", "Test"]
git-tree-sha1 = "216b95ea110b5972db65aa90f88d8d89dcb8851c"
uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa"
version = "0.9.6"

[[URIs]]
git-tree-sha1 = "97bbe755a53fe859669cd907f2d96aee8d2c1355"
uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4"
version = "1.3.0"

[[UUIDs]]
deps = ["Random", "SHA"]
uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"

[[UnPack]]
git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b"
uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed"
version = "1.0.2"

[[Unicode]]
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"

[[UnicodeFun]]
deps = ["REPL"]
git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf"
uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1"
version = "0.4.1"

[[Wayland_jll]]
deps = ["Artifacts", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg", "XML2_jll"]
git-tree-sha1 = "3e61f0b86f90dacb0bc0e73a0c5a83f6a8636e23"
uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89"
version = "1.19.0+0"

[[Wayland_protocols_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "66d72dc6fcc86352f01676e8f0f698562e60510f"
uuid = "2381bf8a-dfd0-557d-9999-79630e7b1b91"
version = "1.23.0+0"

[[WoodburyMatrices]]
deps = ["LinearAlgebra", "SparseArrays"]
git-tree-sha1 = "de67fa59e33ad156a590055375a30b23c40299d3"
uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6"
version = "0.5.5"

[[XML2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "1acf5bdf07aa0907e0a37d3718bb88d4b687b74a"
uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a"
version = "2.9.12+0"

[[XSLT_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"]
git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a"
uuid = "aed1982a-8fda-507f-9586-7b0439959a61"
version = "1.1.34+0"

[[Xorg_libX11_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxcb_jll", "Xorg_xtrans_jll"]
git-tree-sha1 = "5be649d550f3f4b95308bf0183b82e2582876527"
uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc"
version = "1.6.9+4"

[[Xorg_libXau_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "4e490d5c960c314f33885790ed410ff3a94ce67e"
uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec"
version = "1.0.9+4"

[[Xorg_libXcursor_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"]
git-tree-sha1 = "12e0eb3bc634fa2080c1c37fccf56f7c22989afd"
uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724"
version = "1.2.0+4"

[[Xorg_libXdmcp_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "4fe47bd2247248125c428978740e18a681372dd4"
uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05"
version = "1.1.3+4"

[[Xorg_libXext_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3"
uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3"
version = "1.3.4+4"

[[Xorg_libXfixes_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "0e0dc7431e7a0587559f9294aeec269471c991a4"
uuid = "d091e8ba-531a-589c-9de9-94069b037ed8"
version = "5.0.3+4"

[[Xorg_libXi_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXfixes_jll"]
git-tree-sha1 = "89b52bc2160aadc84d707093930ef0bffa641246"
uuid = "a51aa0fd-4e3c-5386-b890-e753decda492"
version = "1.7.10+4"

[[Xorg_libXinerama_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll"]
git-tree-sha1 = "26be8b1c342929259317d8b9f7b53bf2bb73b123"
uuid = "d1454406-59df-5ea1-beac-c340f2130bc3"
version = "1.1.4+4"

[[Xorg_libXrandr_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll"]
git-tree-sha1 = "34cea83cb726fb58f325887bf0612c6b3fb17631"
uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484"
version = "1.5.2+4"

[[Xorg_libXrender_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96"
uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa"
version = "0.9.10+4"

[[Xorg_libpthread_stubs_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "6783737e45d3c59a4a4c4091f5f88cdcf0908cbb"
uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74"
version = "0.1.0+3"

[[Xorg_libxcb_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"]
git-tree-sha1 = "daf17f441228e7a3833846cd048892861cff16d6"
uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b"
version = "1.13.0+3"

[[Xorg_libxkbfile_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "926af861744212db0eb001d9e40b5d16292080b2"
uuid = "cc61e674-0454-545c-8b26-ed2c68acab7a"
version = "1.1.0+4"

[[Xorg_xcb_util_image_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "0fab0a40349ba1cba2c1da699243396ff8e94b97"
uuid = "12413925-8142-5f55-bb0e-6d7ca50bb09b"
version = "0.4.0+1"

[[Xorg_xcb_util_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxcb_jll"]
git-tree-sha1 = "e7fd7b2881fa2eaa72717420894d3938177862d1"
uuid = "2def613f-5ad1-5310-b15b-b15d46f528f5"
version = "0.4.0+1"

[[Xorg_xcb_util_keysyms_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "d1151e2c45a544f32441a567d1690e701ec89b00"
uuid = "975044d2-76e6-5fbe-bf08-97ce7c6574c7"
version = "0.4.0+1"

[[Xorg_xcb_util_renderutil_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "dfd7a8f38d4613b6a575253b3174dd991ca6183e"
uuid = "0d47668e-0667-5a69-a72c-f761630bfb7e"
version = "0.3.9+1"

[[Xorg_xcb_util_wm_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "e78d10aab01a4a154142c5006ed44fd9e8e31b67"
uuid = "c22f9ab0-d5fe-5066-847c-f4bb1cd4e361"
version = "0.4.1+1"

[[Xorg_xkbcomp_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxkbfile_jll"]
git-tree-sha1 = "4bcbf660f6c2e714f87e960a171b119d06ee163b"
uuid = "35661453-b289-5fab-8a00-3d9160c6a3a4"
version = "1.4.2+4"

[[Xorg_xkeyboard_config_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xkbcomp_jll"]
git-tree-sha1 = "5c8424f8a67c3f2209646d4425f3d415fee5931d"
uuid = "33bec58e-1273-512f-9401-5d533626f822"
version = "2.27.0+4"

[[Xorg_xtrans_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "79c31e7844f6ecf779705fbc12146eb190b7d845"
uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10"
version = "1.4.0+3"

[[Zlib_jll]]
deps = ["Libdl"]
uuid = "83775a58-1f1d-513f-b197-d71354ab007a"

[[Zstd_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "cc4bf3fdde8b7e3e9fa0351bdeedba1cf3b7f6e6"
uuid = "3161d3a3-bdf6-5164-811a-617609db77b4"
version = "1.5.0+0"

[[libass_jll]]
deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "5982a94fcba20f02f42ace44b9894ee2b140fe47"
uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0"
version = "0.15.1+0"

[[libfdk_aac_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55"
uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280"
version = "2.0.2+0"

[[libpng_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "94d180a6d2b5e55e447e2d27a29ed04fe79eb30c"
uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f"
version = "1.6.38+0"

[[libvorbis_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"]
git-tree-sha1 = "c45f4e40e7aafe9d086379e5578947ec8b95a8fb"
uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a"
version = "1.3.7+0"

[[nghttp2_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d"

[[p7zip_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0"

[[x264_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2"
uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a"
version = "2021.5.5+0"

[[x265_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9"
uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76"
version = "3.5.0+0"

[[xkbcommon_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Wayland_jll", "Wayland_protocols_jll", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"]
git-tree-sha1 = "ece2350174195bb31de1a63bea3a41ae1aa593b6"
uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd"
version = "0.9.1+5"
"""

# ╔═╡ Cell order:
# ╟─e342faf1-550f-4b6f-963e-ef53ac581c0b
# ╟─2dde8f33-1166-42b9-834f-7bcb54895992
# ╟─245d5573-09f4-4536-b104-351a7669cd8b
# ╟─9a4bc5f5-7acd-4640-a71b-82051b6d3db3
# ╟─0615b18c-23b6-4f93-99ff-2044588dccf2
# ╟─468c679f-6a42-4801-a908-82ab5a4c9507
# ╟─27811f40-08a7-4da7-9788-db4b0c47153b
# ╟─0527804c-68b7-42f9-8830-c41d6b9036f4
# ╟─91d8c001-c210-4c42-a7f2-5e84ee907ea6
# ╟─fb1b6ea0-330c-4744-b3b8-19730b55e7e5
# ╟─56b1302d-6a0e-4262-aa0e-9ae98c2167df
# ╟─8368ba6c-cada-4caa-b37f-752034bfd571
# ╟─64d6faa9-1564-4d7d-bf32-02f0720fa552
# ╟─ac233104-737c-4a92-843d-45042ba25cd1
# ╟─c13206e8-ff41-405a-b9b8-50b589854901
# ╟─a2a6d8c3-c9b7-458d-b5a7-6d3b3f68a926
# ╟─d16680ec-541d-42f0-867e-4259b30adcdb
# ╟─7959439c-f947-40b3-8d2a-7dc96e90bbdc
# ╟─8a30e661-3057-4a30-a495-b1523b42207b
# ╟─4f48ef9a-05ea-41f9-a2a0-381865b8be6a
# ╟─601c53ed-ac2f-48fe-8afa-6b511a3ef369
# ╟─a8d53828-ca73-4cb7-906f-ca2c94735a93
# ╟─7b74d968-8591-49ba-81d8-9d8485676e93
# ╟─5dfa126f-754f-4d25-a191-6e5437df99da
# ╟─05d42951-063d-45d6-87ce-4d15b0472b84
# ╟─673b5f44-0db4-4848-95d7-24a31e7e86b1
# ╟─a491e298-7a49-4cef-b269-886455538348
# ╟─ea7c16d9-dd13-41c6-9c03-431d068fd105
# ╟─1f8c2dfc-1f42-41f9-b18d-3f04df20e527
# ╟─ce366a2b-3933-4b4b-a01c-c0a1ed7da96a
# ╟─deb756be-10ee-43c5-b466-9909b4431268
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002

max_stars_repo_name: moserjo/bayes-imoox

max_issues_repo_name: moserjo/bayes-imoox

max_forks_repo_name: moserjo/bayes-imoox


text:
using Calculus
# moments should operate on a vector and return a nXg matrix
# of moment contributions

# ordinary GMM with provided weight matrix
# weight should be gXg positive definite
function gmm(moments, theta, weight)
    # average moments
    m = theta -> vec(mean(moments(theta),1)) # 1Xg
    # moment contributions
    momentcontrib = theta -> moments(theta) # nXg
    # GMM criterion
    obj = theta -> ((m(theta))'weight*m(theta))
    # do minimization
    thetahat, objvalue, converged = fminunc(obj, theta)
    # derivative of average moments
    D = (Calculus.jacobian(m, vec(thetahat), :central))'
    # moment contributions at estimate
    ms = momentcontrib(thetahat)
    return thetahat, objvalue, D, ms, converged
end

# CUE GMM, weight computed by NW
function gmm(moments, theta)
    # average moments
    m = theta -> vec(mean(moments(theta),1)) # 1Xg
    # moment contributions
    momentcontrib = theta -> moments(theta) # nXg
    # weight
    weight = theta -> inv(NeweyWest(momentcontrib(theta)))
    # objective
    obj = theta -> m(theta)'*weight(theta)*m(theta)
    # do minimization
    thetahat, objvalue, converged = fminunc(obj, theta)
    # derivative of average moments
    D = (Calculus.jacobian(m, vec(thetahat), :central))'
    # moment contributions at estimate
    ms = momentcontrib(thetahat)
    return thetahat, objvalue, D, ms, converged
end

# called with no args runs this example
function gmm()
    println("simple GMM example, sampling from N(0,1)")
    println("and using 3 moment conditions to estimate")
    println("do edit(gmm,()) to see the example code that this is running")
    # example of GMM: draws from N(0,1)
    y = randn(100,1)
    # 3 moment conditions
    moments = theta -> [y-theta[1] (y.^2.0).-theta[2] (y.-theta[1]).^3.0]
    # first round consistent
    W = eye(3)
    theta = [0.0, 1.0]
    thetahat, objvalue, D, ms, converged = gmm(moments, theta, W)
    # second round efficient
    W = inv(cov(ms))
    thetahat, objvalue, D, ms, converged = gmm(moments, thetahat, W)
    # CUE
    thetahat, objvalue, D, ms, converged = gmm(moments, thetahat)
end

ext: jl


text:
@testset "Symmetric/Hermitian rules" begin
    @testset "$(SymHerm)(::AbstractMatrix{$T}, :$(uplo))" for
        SymHerm in (Symmetric, Hermitian),
        T in (Float64, ComplexF64),
        uplo in (:U, :L)

        @testset "frule" begin
            test_frule(SymHerm, rand(T, 3, 3), uplo)
        end
        @testset "rrule" begin
            # on old versions of julia this combination doesn't infer but we don't care as
            # it infers fine on modern versions.
            check_inferred = !(VERSION < v"1.5" && T <: ComplexF64 && SymHerm <: Hermitian)

            @testset "back(::$MT)" for MT in (Matrix, LowerTriangular, UpperTriangular)
                x = randn(T, 3, 3)
                ΔΩ = MT(randn(T, 3, 3))
                test_rrule(
                    SymHerm, x, uplo;
                    output_tangent = ΔΩ,
                    # type stability here critically relies on uplo being constant propagated,
                    # so we need to test this more carefully below
                    check_inferred=false,
                )
                if check_inferred && false # ChainRulesCore #407
                    @maybe_inferred (function (SymHerm, x, ΔΩ, ::Val)
                        return rrule(SymHerm, x, uplo)[2](ΔΩ)
                    end)(SymHerm, x, ΔΩ, Val(uplo))
                end
            end
            @testset "back(::Diagonal)" begin
                x = randn(T, 3, 3)
                ΔΩ = Diagonal(randn(T, 3, 3))
                test_rrule(
                    SymHerm, x ⊢ Diagonal(randn(T, 3)), uplo;
                    check_inferred=false,
                    output_tangent = ΔΩ,
                )
                if check_inferred && false # ChainRulesCore #407
                    @maybe_inferred (function (SymHerm, x, ΔΩ, ::Val)
                        return rrule(SymHerm, x, uplo)[2](ΔΩ)
                    end)(SymHerm, x, ΔΩ, Val(uplo))
                end
            end
        end
    end
    # constructing a `Matrix`/`Array` from `SymHerm`
    @testset "$(f)(::$(SymHerm){$T}) with uplo=:$uplo" for f in (Matrix, Array),
        SymHerm in (Symmetric, Hermitian),
        T in (Float64, ComplexF64),
        uplo in (:U, :L)

        x = SymHerm(randn(T, 3, 3), uplo)
        test_rrule(f, x)

        # intentionally specifying tangents here to test both SymHerm (default) and Matrix
        test_frule(f, x)
        test_frule(f, x ⊢ randn(T, 3, 3))
    end

    # symmetric/hermitian eigendecomposition follows the sign convention
    # v = v * sign(real(vₖ)) * sign(vₖ)', where vₖ is the first or last coordinate
    # in the eigenvector. This is unstable for finite differences, but using the convention
    # v = v * sign(vₖ)' seems to be more stable, the (co)tangents are related as
    # ∂v_ad = sign(real(vₖ)) * ∂v_fd
    function _eigvecs_stabilize_mat(vectors, uplo)
        Ui = Symbol(uplo) === :U ? @view(vectors[end, :]) : @view(vectors[1, :])
        return Diagonal(conj.(sign.(Ui)))
    end

    @testset "eigendecomposition" begin
        @testset "eigen/eigen!" begin
            # avoid implementing to_vec(::Eigen)
            asnt(E::Eigen) = (values=E.values, vectors=E.vectors)

            function _eigen_stable(A)
                F = eigen(A)
                rmul!(F.vectors, _eigvecs_stabilize_mat(F.vectors, A.uplo))
                return F
            end

            n = 10
            @testset "frule for eigen!(::$SymHerm{$T}) uplo=$uplo" for SymHerm in (Symmetric, Hermitian),
                T in (SymHerm === Symmetric ? (Float64,) : (Float64, ComplexF64)),
                uplo in (:L, :U)

                A, ΔA = randn(T, n, n), randn(T, n, n)
                symA = SymHerm(A, uplo)
                ΔsymA = frule((ZeroTangent(), ΔA, ZeroTangent()), SymHerm, A, uplo)[2]

                F = eigen!(copy(symA))
                @test @maybe_inferred(frule((ZeroTangent(), ZeroTangent()), eigen!, copy(symA))) == (F, ZeroTangent())
                F_ad, ∂F_ad = @maybe_inferred frule((ZeroTangent(), copy(ΔsymA)), eigen!, copy(symA))
                @test F_ad == F
                @test ∂F_ad isa Tangent{typeof(F)}
                @test ∂F_ad.values isa typeof(F.values)
                @test ∂F_ad.vectors isa typeof(F.vectors)

                f = x -> asnt(eigen(SymHerm(x, uplo)))
                ∂F_fd = jvp(_fdm, f, (A, ΔA))
                @test ∂F_ad.values ≈ ∂F_fd.values

                f_stable = x -> asnt(_eigen_stable(SymHerm(x, uplo)))
                F_stable = f_stable(A)
                ∂F_stable_fd = jvp(_fdm, f_stable, (A, ΔA))
                C = _eigvecs_stabilize_mat(F.vectors, uplo)
                @test ∂F_ad.vectors * C ≈ ∂F_stable_fd.vectors
            end

            @testset "rrule for eigen(::$SymHerm{$T}) uplo=$uplo" for SymHerm in (Symmetric, Hermitian),
                T in (SymHerm === Symmetric ? (Float64,) : (Float64, ComplexF64)),
                uplo in (:L, :U)

                A, ΔU, Δλ = randn(T, n, n), randn(T, n, n), randn(n)
                symA = SymHerm(A, uplo)

                F = eigen(symA)
                ΔF = Tangent{typeof(F)}(; values=Δλ, vectors=ΔU)
                F_ad, back = @maybe_inferred rrule(eigen, symA)
                @test F_ad == F

                C = _eigvecs_stabilize_mat(F.vectors, uplo)
                CT = Tangent{typeof(F)}

                @testset for nzprops in ([:values], [:vectors], [:values, :vectors])
                    ∂F = CT(; [s => getproperty(ΔF, s) for s in nzprops]...)
                    ∂F_stable = (; [s => copy(getproperty(ΔF, s)) for s in nzprops]...)
                    :vectors in nzprops && rmul!(∂F_stable.vectors, C)

                    f_stable = function(x)
                        F_ = _eigen_stable(SymHerm(x, uplo))
                        return (; (s => getproperty(F_, s) for s in nzprops)...)
                    end

                    ∂self, ∂symA = @maybe_inferred back(∂F)
                    @test ∂self === NoTangent()
                    @test ∂symA isa typeof(symA)
                    @test ∂symA.uplo == symA.uplo
                    ∂A = rrule(SymHerm, A, uplo)[2](∂symA)[2]
                    ∂A_fd = j′vp(_fdm, f_stable, ∂F_stable, A)[1]
                    @test ∂A ≈ ∂A_fd
                end

                @test @maybe_inferred(back(ZeroTangent())) == (NoTangent(), ZeroTangent())
                @test @maybe_inferred(back(CT())) == (NoTangent(), ZeroTangent())
            end

            # when value used to determine phase convention is low, the usual derivatives
            # become unstable, causing the rules to compose poorly in a program.
            # this test set checks that the rules compose correctly for the function
            # f(A) = I, using eigenvectors, where all sensitivities should cancel
            @testset "phase convention from low value" begin
                @testset for min_val in [0, eps(), sqrt(eps()), cbrt(eps()), eps()^(1//4)],
                    uplo in (:U, :L)

                    U = randn(ComplexF64, n, n)
                    U[uplo === :U ? n : 1] = min_val
                    U = Matrix(qr(U).Q)
                    λ = sort(randn(n))
                    A = Hermitian(U * Diagonal(λ) * U')
                    function f(A)
                        V = eigen(A).vectors
                        return V * V'
                    end

                    Ȧ = Hermitian(randn(eltype(A), size(A)))
                    F, Ḟ_ad = frule((ZeroTangent(), copy(Ȧ)), eigen!, copy(A))
                    V, V̇_ad = F.vectors, Ḟ_ad.vectors
                    Ω̇_ad = V̇_ad' * V + V' * V̇_ad
                    @test maximum(abs, Ω̇_ad) < sqrt(eps())

                    Ω̄ = randn(eltype(A), (n, n))
                    V̄ = V * (Ω̄ + Ω̄')
                    F̄ = Tangent{typeof(F)}(vectors = V̄)
                    _, back = rrule(eigen, A)
                    Ā = back(F̄)[2]
                    @test maximum(abs, Ā) < sqrt(eps())
                end
            end
        end

        @testset "eigvals!/eigvals" begin
            n = 10
            @testset "frule for eigvals!(::$SymHerm{$T}) uplo=$uplo" for SymHerm in (Symmetric, Hermitian),
                T in (SymHerm === Symmetric ? (Float64,) : (Float64, ComplexF64)),
                uplo in (:L, :U)

                A, ΔA = randn(T, n, n), randn(T, n, n)
                symA = SymHerm(A, uplo)
                ΔsymA = @maybe_inferred frule((ZeroTangent(), ΔA, ZeroTangent()), SymHerm, A, uplo)[2]

                λ = eigvals!(copy(symA))
                λ_ad, ∂λ_ad = @maybe_inferred frule((ZeroTangent(), copy(ΔsymA)), eigvals!, copy(symA))
                @test λ_ad ≈ λ # inexact because frule uses eigen not eigvals
                @test ∂λ_ad isa typeof(λ)
                @test ∂λ_ad ≈ jvp(_fdm, A -> eigvals(SymHerm(A, uplo)), (A, ΔA))
            end

            @testset "rrule for eigvals(::$SymHerm{$T}) uplo=$uplo" for SymHerm in (Symmetric, Hermitian),
                T in (SymHerm === Symmetric ? (Float64,) : (Float64, ComplexF64)),
                uplo in (:L, :U)

                A, Δλ = randn(T, n, n), randn(n)
                symA = SymHerm(A, uplo)

                λ = eigvals(symA)
                λ_ad, back = @maybe_inferred rrule(eigvals, symA)
                @test λ_ad ≈ λ # inexact because rrule uses eigen not eigvals
                ∂self, ∂symA = @maybe_inferred back(Δλ)
                @test ∂self === NoTangent()
                @test ∂symA isa typeof(symA)
                @test ∂symA.uplo == symA.uplo

                # pull the cotangent back to A to test against finite differences
                ∂A = rrule(SymHerm, A, uplo)[2](∂symA)[2]
                @test ∂A ≈ j′vp(_fdm, A -> eigvals(SymHerm(A, uplo)), Δλ, A)[1]

                @test @maybe_inferred(back(ZeroTangent())) == (NoTangent(), ZeroTangent())
            end
        end
    end

    @testset "singular value decomposition" begin
        # avoid implementing to_vec(::SVD)
        asnt(F::SVD) = (U=F.U, S=F.S, V=F.V, Vt=F.Vt)

        function _svd_stable(A)
            F = svd(A)
            C = _eigvecs_stabilize_mat(F.U, A.uplo)
            rmul!(F.U, C)
            lmul!(C, F.Vt)
            return F
        end

        n = 10
        @testset "rrule for svd(::$SymHerm{$T}) uplo=$uplo" for SymHerm in (Symmetric, Hermitian),
            T in (SymHerm === Symmetric ? (Float64,) : (Float64, ComplexF64)),
            uplo in (:L, :U)

            A, ΔU, ΔV, ΔVt = ntuple(_ -> randn(T, n, n), 4)
            ΔS = randn(n)
            symA = SymHerm(A, uplo)

            F = svd(symA)
            CT = Tangent{typeof(F)}
            ΔF = CT(; U=ΔU, V=ΔV, Vt=ΔVt, S=ΔS)
            F_ad, back = @maybe_inferred rrule(svd, symA)
            @test F_ad == F

            C = _eigvecs_stabilize_mat(F.U, uplo)

            # pull back different combination of non-ZeroTangent cotangents
            @testset for nzprops in ([:U], [:S], [:V], [:Vt], [:U, :S, :V, :Vt])
                ∂F = CT(; [s => getproperty(ΔF, s) for s in nzprops]...)
                ∂F_stable = (; [s => copy(getproperty(ΔF, s)) for s in nzprops]...)
                :U in nzprops && rmul!(∂F_stable.U, C)
                :Vt in nzprops && lmul!(C, ∂F_stable.Vt)
                :V in nzprops && rmul!(∂F_stable.V, C)

                f_stable = function(x)
                    F_ = _svd_stable(SymHerm(x, uplo))
                    return (; (s => getproperty(F_, s) for s in nzprops)...)
                end

                @maybe_inferred back(∂F)
                ∂self, ∂symA = back(∂F)
                @test ∂self === NoTangent()
                @test ∂symA isa typeof(symA)
                @test ∂symA.uplo == symA.uplo
                ∂A = rrule(SymHerm, A, uplo)[2](∂symA)[2]
                ∂A_fd = j′vp(_fdm, f_stable, ∂F_stable, A)[1]
                @test ∂A ≈ ∂A_fd
            end

            @test @maybe_inferred(back(ZeroTangent())) == (NoTangent(), ZeroTangent())
            @test @maybe_inferred(back(CT())) == (NoTangent(), ZeroTangent())
        end

        @testset "rrule for svdvals(::$SymHerm{$T}) uplo=$uplo" for SymHerm in (Symmetric, Hermitian),
            T in (SymHerm === Symmetric ? (Float64,) : (Float64, ComplexF64)),
            uplo in (:L, :U)

            A, ΔS = randn(T, n, n), randn(n)
            symA = SymHerm(A, uplo)

            S = svdvals(symA)
            S_ad, back = @maybe_inferred rrule(svdvals, symA)
            @test S_ad ≈ S # inexact because rrule uses svd not svdvals
            ∂self, ∂symA = @maybe_inferred back(ΔS)
            @test ∂self === NoTangent()
            @test ∂symA isa typeof(symA)
            @test ∂symA.uplo == symA.uplo

            # pull the cotangent back to A to test against finite differences
            ∂A = rrule(SymHerm, A, uplo)[2](∂symA)[2]
            @test ∂A ≈ j′vp(_fdm, A -> svdvals(SymHerm(A, uplo)), ΔS, A)[1]

            @test @maybe_inferred(back(ZeroTangent())) == (NoTangent(), ZeroTangent())
        end
    end

    @testset "Symmetric/Hermitian matrix functions" begin
        # generate random matrices of type TA in the domain of f
        function rand_matfun_input(f, TA, T, uplo, n, hermout)
            U = Matrix(qr(randn(T, n, n)).Q)
            if hermout # f(A) will also be a TA
                λ = if f in (acos, asin, atanh)
                    # generate random number between -1 and 0.9. This would be between
                    # -1 and 1 but we want to avoid domain errors from numerical error
                    T(1.9) .* rand(real(T), n) .- 1
                elseif f in (log, sqrt)
                    abs.(randn(real(T), n))
                elseif f === acosh
                    1 .+ abs.(randn(real(T), n))
                else
                    randn(real(T), n)
                end
            else
                λ = randn(real(T), n)
                λ = if f === atanh
                    2 .* rand(real(T), n) .- 1
                else
                    randn(real(T), n)
                end
            end
            return TA(U * Diagonal(λ) * U', uplo)
        end

        # Adapted From ChainRulesTestUtils._is_inferrable
        function is_inferrable(f, A)
            try
                @maybe_inferred f(A)
                return true
            catch ErrorException
                return false
            end
        end

        @testset "$(f)(::$TA{<:$T})" for f in
            (exp, log, sqrt, cos, sin, tan, cosh, sinh, tanh, acos, asin, atan, acosh, asinh, atanh),
            TA in (Symmetric, Hermitian),
            T in (TA <: Symmetric ? (Float64,) : (Float64, ComplexF64))
            TC = Complex{real(T)}

            n = 10
            @testset "frule" begin
                @testset for uplo in (:L, :U), hermout in (true, false)
                    A, ΔA = rand_matfun_input(f, TA, T, uplo, n, hermout), TA(randn(T, n, n), uplo)
                    Y = f(A)
                    if is_inferrable(f, A)
                        Y_ad, ∂Y_ad = @maybe_inferred frule((ZeroTangent(), ΔA), f, A)
                    else
                        TY = T∂Y = if T <: Real
                            Union{Symmetric{Complex{T}},Symmetric{T}}
                        else
                            Union{Matrix{T},Hermitian{T}}
                        end
                        Y_ad, ∂Y_ad = @maybe_inferred Tuple{TY,T∂Y} frule((ZeroTangent(), ΔA), f, A)
                    end
                    @test Y_ad == Y
                    @test typeof(Y_ad) === typeof(Y)
                    hasproperty(Y, :uplo) && @test Y_ad.uplo == Y.uplo
                    @test ∂Y_ad isa typeof(Y)
                    hasproperty(∂Y_ad, :uplo) && @test ∂Y_ad.uplo == Y.uplo
                    @test parent(∂Y_ad) ≈ jvp(_fdm, x -> Matrix{TC}(parent(f(TA(x, uplo)))), (A.data, ΔA.data))
                end

                @testset "stable for (almost-)singular input" begin
                    λ, U = eigen(rand_matfun_input(f, TA, T, :U, n, true))
                    m = div(n, 2)
                    λ[1:m] .= λ[m+1:2m] .+ cbrt(eps(eltype(λ))) / 100
                    A = TA(U * Diagonal(λ) * U')
                    ΔA = TA(randn(T, n, n))
                    _, ∂Y = frule((ZeroTangent(), ΔA), f, A)
                    @test parent(∂Y) ≈ jvp(_fdm, x -> Matrix{TC}(parent(f(TA(x)))), (A.data, ΔA.data))

                    λ[1:m] .= λ[m+1:2m]
                    A2 = TA(U * Diagonal(λ) * U')
                    ΔA2 = TA(randn(T, n, n))
                    _, ∂Y2 = frule((ZeroTangent(), ΔA2), f, A2)
                    @test parent(∂Y2) ≈ jvp(_fdm, x -> Matrix{TC}(parent(f(TA(x)))), (A2.data, ΔA2.data))
                end

                f ∉ (log,sqrt,acosh) && @testset "low-rank matrix" begin
                    λ, U = eigen(rand_matfun_input(f, TA, T, :U, n, true))
                    λ[2:n] .= 0
                    A = TA(U * Diagonal(λ) * U')
                    ΔA = TA(randn(T, n, n))
                    _, ∂Y = frule((ZeroTangent(), ΔA), f, A)
                    @test parent(∂Y) ≈ jvp(_fdm, x -> Matrix{TC}(parent(f(TA(x)))), (A.data, ΔA.data))
                end
            end

            @testset "rrule" begin
                @testset for uplo in (:L, :U), hermout in (true, false)
                    A = rand_matfun_input(f, TA, T, uplo, n, hermout)
                    Y = f(A)
                    ΔY = if Y isa Matrix
                        randn(eltype(Y), n, n)
                    else
                        typeof(Y)(randn(eltype(Y), n, n), Y.uplo)
                    end
                    if is_inferrable(f, A)
                        Y_ad, back = @maybe_inferred rrule(f, A)
                    else
                        TY = if T <: Real
                            Union{Symmetric{Complex{T}},Symmetric{T}}
                        else
                            Union{Matrix{T},Hermitian{T}}
                        end
                        Y_ad, back = @maybe_inferred Tuple{TY,Any} rrule(f, A)
                    end
                    @test Y_ad == Y
                    @test typeof(Y_ad) === typeof(Y)
                    hasproperty(Y, :uplo) && @test Y_ad.uplo == Y.uplo
                    ∂self, ∂A = @maybe_inferred back(ΔY)
                    @test ∂self === NoTangent()
                    @test ∂A isa typeof(A)
                    @test ∂A.uplo == A.uplo
                    # check pullback composes correctly
                    ∂data = rrule(Hermitian, A.data, uplo)[2](∂A)[2]
                    @test ∂data ≈ j′vp(_fdm, x -> parent(f(TA(x, uplo))), ΔY, A.data)[1]

                    # check works correctly even when cotangent is different type than Y
                    ΔY2 = randn(Complex{real(T)}, n, n)
                    _, ∂A2 = back(ΔY2)
                    ∂data2 = rrule(Hermitian, A.data, uplo)[2](∂A2)[2]
                    @test ∂data2 ≈ j′vp(_fdm, x -> Matrix{Complex{real(T)}}(f(TA(x, uplo))), ΔY2, A.data)[1]
                end

                @testset "stable for (almost-)singular input" begin
                    λ, U = eigen(rand_matfun_input(f, TA, T, :U, n, true))
                    m = div(n, 2)
                    λ[1:m] .= λ[m+1:2m] .+ cbrt(eps(eltype(λ))) / 100
                    A = TA(U * Diagonal(λ) * U')
                    ΔY = TA(randn(T, n, n))
                    ∂A = rrule(f, A)[2](ΔY)[2]
                    ∂data = rrule(Hermitian, A.data, :U)[2](∂A)[2]
                    @test ∂data ≈ j′vp(_fdm, x -> parent(f(TA(x))), ΔY, A.data)[1]

                    λ[1:m] .= λ[m+1:2m]
                    A2 = TA(U * Diagonal(λ) * U')
                    ΔY2 = TA(randn(T, n, n))
                    ∂A2 = rrule(f, A2)[2](ΔY2)[2]
                    ∂data2 = rrule(Hermitian, A2.data, :U)[2](∂A2)[2]
                    @test ∂data2 ≈ j′vp(_fdm, x -> parent(f(TA(x))), ΔY2, A2.data)[1]
                end

                f ∉ (log,sqrt,acosh) && @testset "low-rank matrix" begin
                    λ, U = eigen(rand_matfun_input(f, TA, T, :U, n, true))
                    λ[2:n] .= 0
                    A = TA(U * Diagonal(λ) * U')
                    ΔY = TA(randn(T, n, n))
                    ∂A = rrule(f, A)[2](ΔY)[2]
                    ∂data = rrule(Hermitian, A.data, :U)[2](∂A)[2]
                    @test ∂data ≈ j′vp(_fdm, x -> parent(f(TA(x))), ΔY, A.data)[1]
                end
            end
        end

        @testset "sincos(::$TA{<:$T})" for TA in (Symmetric, Hermitian),
            T in (TA <: Symmetric ? (Float64,) : (Float64, ComplexF64))

            n = 10
            @testset "frule" begin
                @testset for uplo in (:L, :U)
                    A, ΔA = TA(randn(T, n, n), uplo), TA(randn(T, n, n), uplo)
                    Y = sincos(A)
                    sinA, cosA = Y
                    Y_ad, ∂Y_ad = @maybe_inferred frule((ZeroTangent(), ΔA), sincos, A)
                    @test Y_ad == Y
                    @test typeof(Y_ad) === typeof(Y)
                    @test Y_ad[1].uplo === Y[1].uplo
                    @test Y_ad[2].uplo === Y[2].uplo

                    @test ∂Y_ad isa Tangent{typeof(Y)}
                    ∂Y_ad2 = Tangent{typeof(Y)}(
                        frule((ZeroTangent(), ΔA), sin, A)[2],
                        frule((ZeroTangent(), ΔA), cos, A)[2],
                    )
                    # not exact because evaluated in a more efficient way
                    ChainRulesTestUtils.test_approx(∂Y_ad, ∂Y_ad2)
                end
            end

            @testset "rrule" begin
                @testset for uplo in (:L, :U)
                    A = TA(randn(T, n, n), uplo)
                    Y = sincos(A)
                    sinA, cosA = Y
                    ΔsinA = typeof(sinA)(randn(T, n, n), sinA.uplo)
                    ΔcosA = typeof(cosA)(randn(T, n, n), cosA.uplo)
                    Y_ad, back = @maybe_inferred rrule(sincos, A)
                    @test Y_ad == Y
                    @test typeof(Y_ad) === typeof(Y)
                    @test Y_ad[1].uplo === Y[1].uplo
                    @test Y_ad[2].uplo === Y[2].uplo

                    ΔY = Tangent{typeof(Y)}(ΔsinA, ΔcosA)
                    ∂self, ∂A = @maybe_inferred back(ΔY)
                    @test ∂self === NoTangent()
                    @test ∂A ≈ rrule(sin, A)[2](ΔsinA)[2] + rrule(cos, A)[2](ΔcosA)[2]

                    ΔY2 = Tangent{typeof(Y)}(ZeroTangent(), ZeroTangent())
                    @test @maybe_inferred(back(ΔY2)) === (NoTangent(), ZeroTangent())

                    ΔY3 = Tangent{typeof(Y)}(ΔsinA, ZeroTangent())
                    @test @maybe_inferred(back(ΔY3)) == rrule(sin, A)[2](ΔsinA)

                    ΔY4 = Tangent{typeof(Y)}(ZeroTangent(), ΔcosA)
                    @test @maybe_inferred(back(ΔY4)) == rrule(cos, A)[2](ΔcosA)
                end
            end
        end
    end
end


text:
# module Bukdu.Plug

import ..Bukdu

struct ServerSentEvents <: AbstractPlug
end

"""
    plug(::Type{ServerSentEvents})
"""
function plug(::Type{ServerSentEvents})
    Bukdu.env[:check_server_sent_events] = true
end

# module Bukdu.Plug

max_stars_repo_name: wookay/TestBukdu

max_issues_repo_name: wookay/TestBukdu

max_forks_repo_name: wookay/TestBukdu


text:
#
# Very similar to RemoteWorld module, but works in Real Time. In
# this case RT - means Real Time. It listens remote server and
# shows only differences in remote world, but not all plane.
# It uses canvas within a window for showing dots. This module works
# in a simple way: first, you have to create RemoteWorldRT object
# calling create() function. This object, used in all functions.
# create() doesn't start displaying world. For this, you have to
# call start() function. To stop displaying, call stop(). Speed
# of showing depends on network speed.
#
# @author DeadbraiN
# TODO: describe two clients here (slow and fast)
module RemoteWorldRT
  import Event
  import OpenGlWindow
  import Connection
  import Creature
  import Client
  import RpcApi
  import FastApi
  import Config
  import Helper
  import Dots

  export create
  export start
  export stop

  export RemoteDataRT
  #
  # Contains data of for remote host, from where we displaying
  # world's region and shows it on a canvas.
  #
  type RemoteDataRT
    #
    # Required fields
    #
    cmdCon::Client.ClientConnection
    poolingCon::Client.ClientConnection
    win::OpenGlWindow.Window
    width::UInt16
    height::UInt16
    #
    # Lazy loading fields
    #
    poolingBeforeCb::Function
    cmdAfterCb::Function
    ts::Float64
    poolingRequests::Int
    oldRequests::Int
    ips::Float64

    RemoteDataRT(
      cmdCon::Client.ClientConnection,
      poolingCon::Client.ClientConnection,
      win::OpenGlWindow.Window,
      width::UInt16,
      height::UInt16
    ) = new(cmdCon, poolingCon, win, width, height)
  end
  #
  # Creates connection with remote host for display pixels from remote world.
  # @param cfg Global config type
  # @param host Remote host we are connecting to
  # @param cmdPort Remote port for commands
  # @param poolingPort Remote port for pooling requests
  # @return {RemoteDataRT}
  #
  function create(cfg::Config.ConfigData, host::Base.IPAddr, cmdPort::Int, poolingPort::Int)
    RemoteDataRT(
      Client.create(host, cmdPort),
      Client.create(host, poolingPort, true),
      OpenGlWindow.create(cfg.worldWidth, cfg.worldHeight, cfg.worldZoom),
      UInt16(cfg.worldWidth),
      UInt16(cfg.worldHeight)
    )
  end
  #
  # Start displaying remote plane. It handles requests from remote
  # server with dots diffs. Response of first request will be all dots
  # of remote plane. All other requests will be runned from remove
  # server back to this client.
  # @param rd Remote world data object. See create()
  #
  function start(rd::RemoteDataRT)
    local color::Dots.Color

    rd.poolingBeforeCb = (sock::Base.TCPSocket, data::Array{Any, 1}, ans::Connection.Answer) -> _onDot(rd, data)
    rd.cmdAfterCb      = (ans::Connection.Answer) -> _onRegion(rd, ans)
    rd.ts              = time()
    rd.poolingRequests = 0
    rd.oldRequests     = 0
    #
    # This is how we redefine colors for world's objects
    #
    for color in Dots.COLORS OpenGlWindow.setColor(Int(color.index), color.rgb...) end

    Event.on(rd.poolingCon.observer, Connection.EVENT_BEFORE_RESPONSE, rd.poolingBeforeCb)
    Event.on(rd.cmdCon.observer, Connection.EVENT_AFTER_REQUEST, rd.cmdAfterCb)
    Client.request(rd.cmdCon, RpcApi.RPC_SET_WORLD_STREAMING)
  end
  #
  # Stops displaying organism's world. Closes the connection.
  # @param rd Remote world data object
  #
  function stop(rd::RemoteDataRT)
    Event.off(rd.poolingCon.observer, Connection.EVENT_BEFORE_RESPONSE, rd.poolingBeforeCb)
    Event.off(rd.cmdCon.observer, Connection.EVENT_AFTER_REQUEST, rd.cmdAfterCb)
    Client.stop(rd.cmdCon)
    Client.stop(rd.poolingCon)
    OpenGlWindow.destroy(rd.win)
  end
  #
  # Handler of remote server pooling request. It may contain two types
  # of data:
  #    x::Uint16, y::UInt16, color::UInt16, ips::UInt16 or
  #    ips::UInt16
  # @param rd Remote Data object
  # @param data Command related data
  #
  function _onDot(rd::RemoteDataRT, data::Array{Any, 1})
    local paramAmount::Int = length(data)
    if time() - rd.ts > 1.0
      rd.ts = time()
      rd.oldRequests = rd.poolingRequests
      rd.poolingRequests = 0
      OpenGlWindow.title(rd.win, string("ips: ", round(rd.ips), ", rps: ", rd.oldRequests))
      OpenGlWindow.update(rd.win)
    end
    rd.poolingRequests += 1
    # TODO: it's better to check type of request by FastApi.API_XXX constants
    if paramAmount === 5 _onOrganismDot(rd, data)
    elseif paramAmount === 3 _onEnergyDot(rd, data)
    elseif paramAmount === 1 _onIps(rd, data)
    end
  end
  #
  # Request for drawing organism dot
  # @param rd Remote Data object
  # @param data Command related data
  #
  function _onOrganismDot(rd::RemoteDataRT, data::Array{Any, 1})
    local x::UInt16       = UInt16(data[1])
    local y::UInt16       = UInt16(data[2])
    local nibbles::UInt16 = UInt16(data[3])
    local infoBits::UInt8 = UInt8(data[5])
    local color::UInt16   = nibbles & 0x0fff # last 3 nibbles are color
    local dir::Int        = nibbles >> 12    # first nibble is direction
    local outOfBorder::Bool = infoBits & 0b1 > 0
    #
    # This is moving of the dot. We have to draw empty dot
    # on previous dot position and colored dot on new position.
    # This code also knows about moving of organisms out of border
    # in a cyclical mode
    #
    # TIP!!!
    # - local orgId::UInt = UInt(data[4]) # is an organism id
    # - if color === Dots.INDEX_EMPTY, then organism has died
    # - if dir === Dots.DIRECTION_NO, then organism changes it's color, but stay on the same position
    # - if color !== Dots.INDEX_EMPTY && dir === Dots.DIRECTION_NO, then organism has born
    #
    if dir === Dots.DIRECTION_UP
      if outOfBorder OpenGlWindow.dot(rd.win, x, rd.height, Dots.INDEX_EMPTY)
      else OpenGlWindow.dot(rd.win, x, y + 0x0001, Dots.INDEX_EMPTY)
      end
    elseif dir === Dots.DIRECTION_RIGHT
      if outOfBorder OpenGlWindow.dot(rd.win, 0x0001, y, Dots.INDEX_EMPTY)
      else OpenGlWindow.dot(rd.win, x - 0x0001, y, Dots.INDEX_EMPTY)
      end
    elseif dir === Dots.DIRECTION_DOWN
      if outOfBorder OpenGlWindow.dot(rd.win, x, 0x0001, Dots.INDEX_EMPTY)
      else OpenGlWindow.dot(rd.win, x, y - 0x0001, Dots.INDEX_EMPTY)
      end
    elseif dir === Dots.DIRECTION_LEFT
      if outOfBorder OpenGlWindow.dot(rd.win, rd.width, y, Dots.INDEX_EMPTY)
      else OpenGlWindow.dot(rd.win, x + 0x0001, y, Dots.INDEX_EMPTY)
      end
    elseif dir === Dots.DIRECTION_NO
      #println("x: ", x, ", y: ", y, ", id: ", UInt(data[4]), ", c: ", color)
      OpenGlWindow.dot(rd.win, x, y, Dots.INDEX_EMPTY)
    end
    OpenGlWindow.dot(rd.win, x, y, color)
    OpenGlWindow.update(rd.win)
  end
  #
  # Request for drawing energy dot. If we are here, then new energy block was created
  # @param rd Remote Data object
  # @param data Command related data
  #
  function _onEnergyDot(rd::RemoteDataRT, data::Array{Any, 1})
    OpenGlWindow.dot(rd.win, UInt16(data[1]), UInt16(data[2]), UInt16(data[3]))
    OpenGlWindow.update(rd.win)
  end
  #
  # Request for drawing ips valus
  # @param rd Remote Data object
  # @param data Command related data
  #
  function _onIps(rd::RemoteDataRT, data::Array{Any, 1})
    rd.ips = data[1]
  end
  #
  # Handler of RpcApi.RPC_SET_WORLD_STREAMING request
  # @param data Answer object with region data
  #
  function _onRegion(rd::RemoteDataRT, ans::Connection.Answer)
    local region::RpcApi.Region = ans.data
    local blockIdx::Int
    local block::RpcApi.Block
    local offs::UInt8
    local org::RpcApi.Org
    local xOffs::UInt16
    local yOffs::UInt16

    for blockIdx = 0:length(region.blocks) - 1
      block = region.blocks[blockIdx + 1]
      yOffs = div(blockIdx, region.xBlocks) * RpcApi.BLOCK_SIZE
      xOffs = blockIdx % region.xBlocks * RpcApi.BLOCK_SIZE
      for offs in block.energy
        OpenGlWindow.dot(rd.win, xOffs + UInt16(offs % RpcApi.BLOCK_SIZE + 1), yOffs + UInt16(div(offs, RpcApi.BLOCK_SIZE) + 1), UInt16(Dots.INDEX_ENERGY))
      end
      for org in block.orgs
        OpenGlWindow.dot(rd.win, xOffs + UInt16(org.offs % RpcApi.BLOCK_SIZE + 1), yOffs + UInt16(div(org.offs, RpcApi.BLOCK_SIZE) + 1), org.color)
      end
    end
    #
    # This command means "turn on server pooling"
    #
    Client.request(rd.poolingCon, UInt8(FastApi.API_UINT8), UInt8(0))
  end
end

max_stars_repo_name: tmptrash/jevo

max_issues_repo_name: tmptrash/jevo

max_forks_repo_name: tmptrash/jevo


text:
using Test
using CompScienceMeshes
using LinearAlgebra
using StaticArrays

Γ32 = meshrectangle(Float32(1.0), Float32(1.0), Float32(0.2))
Γ64 = meshrectangle(Float64(1.0), Float64(1.0), Float64(0.2))

Γ_converted = convert(Float32, Γ64)

@test Γ32.vertices == Γ_converted.vertices
@test Γ32.faces == Γ_converted.faces

max_stars_repo_name: krcools/CompScienceMeshes

max_issues_repo_name: krcools/CompScienceMeshes

max_forks_repo_name: krcools/CompScienceMeshes


text:
@sumProductRule(:node_type     => SampleList,
                :outbound_type => Message{SampleList},
                :inbound_types => (Nothing, Message{PointMass}, Message{PointMass}),
                :name          => SPSampleListOutNPP)

@naiveVariationalRule(:node_type     => SampleList,
                      :outbound_type => Message{SampleList},
                      :inbound_types => (Nothing, ProbabilityDistribution, ProbabilityDistribution),
                      :name          => VBSampleListOut)