From e1fe5a3f1036d4c302a76803e9d8ac97e4ac5d33 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 31 Oct 2018 10:49:40 +0100 Subject: [PATCH 0001/1328] initial commit --- .codecov.yml | 1 + .gitignore | 3 + .travis.yml | 12 ++ LICENSE.md | 22 +++ README.md | 3 + REQUIRE | 8 ++ appveyor.yml | 25 ++++ src/CairoMakie.jl | 342 ++++++++++++++++++++++++++++++++++++++++++++++ test/runtests.jl | 1 + 9 files changed, 417 insertions(+) create mode 100644 .codecov.yml create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 REQUIRE create mode 100644 appveyor.yml create mode 100644 src/CairoMakie.jl create mode 100644 test/runtests.jl diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 00000000000..69cb76019a4 --- /dev/null +++ b/.codecov.yml @@ -0,0 +1 @@ +comment: false diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000000..8c960ec808d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.jl.cov +*.jl.*.cov +*.jl.mem diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000000..01a9b778a08 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,12 @@ +## Documentation: http://docs.travis-ci.com/user/languages/julia/ +language: julia +os: + - linux + - osx +julia: + - 1.0 + - nightly +notifications: + email: false +git: + depth: 99999999 diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000000..7b4c161480b --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,22 @@ +The CairoMakie.jl package is licensed under the MIT "Expat" License: + +> Copyright (c) 2017: SimonDanisch. +> +> Permission is hereby granted, free of charge, to any person obtaining a copy +> of this software and associated documentation files (the "Software"), to deal +> in the Software without restriction, including without limitation the rights +> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +> copies of the Software, and to permit persons to whom the Software is +> furnished to do so, subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in all +> copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +> SOFTWARE. +> diff --git a/README.md b/README.md new file mode 100644 index 00000000000..c47c03447ed --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# CairoMakie + +The Cairo Backend for Makie diff --git a/REQUIRE b/REQUIRE new file mode 100644 index 00000000000..33888afb862 --- /dev/null +++ b/REQUIRE @@ -0,0 +1,8 @@ +julia 0.7 + +StaticArrays 0.6.6 +GeometryTypes 0.4.5 +AbstractPlotting +Cairo +Colors +Makie diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 00000000000..6f0cb42585c --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,25 @@ +environment: + matrix: + - julia_version: 1 + - julia_version: nightly + +platform: + - x86 # 32-bit + - x64 # 64-bit + +# # Uncomment the following lines to allow failures on nightly julia +# # (tests will run but not make your overall status red) +matrix: + allow_failures: + - julia_version: nightly + +branches: + only: + - master + - /release-.*/ + +notifications: + - provider: Email + on_build_success: false + on_build_failure: false + on_build_status_changed: false diff --git a/src/CairoMakie.jl b/src/CairoMakie.jl new file mode 100644 index 00000000000..b51b9d49831 --- /dev/null +++ b/src/CairoMakie.jl @@ -0,0 +1,342 @@ +module CairoMakie + +import ..Makie +using ..Makie: Scene, Lines, Text, Image, Heatmap, Scatter, @key_str, broadcast_foreach +using ..Makie: convert_attribute, @extractvalue, LineSegments, to_ndim, NativeFont +using ..Makie: @info, @get_attribute +using Reactive, Colors, GeometryTypes + +using AbstractPlotting +using AbstractPlotting: to_value, to_colormap + + +using Cairo + + +struct CairoScreen{S} + scene::Scene + surface::S + context::CairoContext + pane::Nothing#Union{CairoGtkPane, Void} +end +# # we render the scene directly, since we have no screen dependant state like in e.g. opengl +Base.insert!(screen::CairoScreen, scene::Scene, plot) = nothing + +# Default to Gtk Window+Canvas as backing device +function CairoScreen(scene::Scene) + w, h = round.(Int, scene.camera.resolution[]) + @info("Cairo screen: ", w, " ", h) + surf = CairoRGBSurface(w, h) + ctx = CairoContext(surf) + win = GtkWindow() + canv = GtkCanvas(w, h) + push!(win, canv) + CairoScreen(scene, surf, ctx, CairoGtkPane(win, canv)) +end + +function CairoScreen(scene::Scene, path::Union{String, IO}; mode=:svg) + w, h = round.(Int, scene.camera.resolution[]) + # TODO: Add other surface types (PDF, etc.) + if mode == :svg + surf = CairoSVGSurface(path, w, h) + else + error("No available Cairo surface for mode $mode") + end + ctx = CairoContext(surf) + CairoScreen(scene, surf, ctx, nothing) +end + + +function project_position(scene, point, model) + res = scene.camera.resolution[] + p4d = to_ndim(Vec4f0, to_ndim(Vec3f0, point, 0f0), 1f0) + clip = scene.camera.projectionview[] * model * p4d + p = (clip / clip[4])[Vec(1, 2)] + p = Vec2f0(p[1], -p[2]) + ((((p + 1f0) / 2f0) .* (res - 1f0)) + 1f0) +end +project_scale(scene::Scene, s::Number) = project_scale(scene, Vec2f0(s)) +function project_scale(scene::Scene, s) + p4d = to_ndim(Vec4f0, s, 0f0) + p = (scene.camera.projectionview[] * p4d)[Vec(1, 2)] ./ 2f0 + p .* scene.camera.resolution[] +end + +function draw_segment(scene, ctx, point::Point, model, connect, do_stroke, c, linewidth, linestyle, primitive) + pos = project_position(scene, point, model) + function stroke() + Cairo.set_line_width(ctx, Float64(linewidth)) + Cairo.set_source_rgba(ctx, red(c), green(c), blue(c), alpha(c)) + if linestyle != nothing + #set_dash(ctx, linestyle, 0.0) + end + Cairo.stroke(ctx) + end + if !all(isfinite.(pos)) + connect[] = false + else + if connect[] + Cairo.line_to(ctx, pos[1], pos[2]) + isa(primitive, LineSegments) && (connect[] = false) + end + if do_stroke[] + stroke(); do_stroke[] = false; connect[] = true + Cairo.move_to(ctx, pos[1], pos[2]) + else + do_stroke[] = true + end + end +end + +function draw_segment(scene, ctx, segment::Tuple{<: Point, <: Point}, model, connect, do_stroke, c, linewidth, linestyle, primitive) + A = project_position(scene, segment[1], model) + B = project_position(scene, segment[2], model) + function stroke() + Cairo.set_line_width(ctx, Float64(linewidth)) + Cairo.set_source_rgba(ctx, red(c), green(c), blue(c), alpha(c)) + if linestyle != nothing + #set_dash(ctx, linestyle, 0.0) + end + Cairo.stroke(ctx) + end + Cairo.move_to(ctx, A[1], A[2]) + Cairo.line_to(ctx, B[1], B[2]) + stroke() +end + +function cairo_draw(screen::CairoScreen, primitive::Union{Lines, LineSegments}) + scene = screen.scene + fields = @get_attribute(primitive, (color, linewidth, linestyle)) + ctx = screen.context + model = primitive[:model][] + positions = primitive[1][] + N = length(positions) + connect = Ref(true); do_stroke = Ref(true) + broadcast_foreach(1:N, positions, fields...) do i, point, c, linewidth, linestyle + draw_segment(scene, ctx, point, model, connect, do_stroke, c, linewidth, linestyle, primitive) + end + nothing +end +using AbstractPlotting: extrema_nan + +function to_cairo_image(img::AbstractMatrix{<: AbstractFloat}, attributes) + println("joooo") + AbstractPlotting.@get_attribute attributes (colormap, colorrange) + imui32 = to_uint32_color.(AbstractPlotting.interpolated_getindex.(Ref(colormap), img, (colorrange,))) + to_cairo_image(imui32, attributes) +end + +function to_cairo_image(img::Matrix{UInt32}, attributes) + CairoARGBSurface(img) +end +to_uint32_color(c) = reinterpret(UInt32, convert(ARGB32, c)) +function to_cairo_image(img, attributes) + to_cairo_image(to_uint32_color.(img), attributes) +end + +function cairo_draw(screen::CairoScreen, primitive::Image) + draw_image(screen, primitive) +end + +function cairo_draw(screen::CairoScreen, primitive::Union{Heatmap, Image}) + draw_image(screen, primitive) +end + +function draw_image(screen, attributes) + println("Oh Hi") + scene = screen.scene + ctx = screen.context + image = attributes[3][] + x, y = attributes[1][], attributes[2][] + model = attributes[:model][] + imsize = (extrema_nan(x), extrema_nan(y)) + xy = project_position(scene, Point2f0(first.(imsize)), model) + xymax = project_position(scene, Point2f0(last.(imsize)), model) + w, h = xymax .- xy + interp = to_value(get(attributes, :interpolate, true)) + interp = interp ? Cairo.FILTER_BEST : Cairo.FILTER_NEAREST + Cairo.save(ctx); + pattern = Cairo.CairoPattern(to_cairo_image(image, attributes)) + Cairo.pattern_set_extend(pattern, Cairo.EXTEND_PAD) + Cairo.pattern_set_filter(pattern, interp) + Cairo.set_source(ctx, pattern) + Cairo.rectangle(ctx, xy..., w, h) + Cairo.fill(ctx) + Cairo.restore(ctx) +end + + +function cairo_draw(screen::CairoScreen, primitive::Scatter) + scene = screen.scene + fields = @get_attribute(primitive, (color, markersize, strokecolor, strokewidth, marker)) + ctx = screen.context + model = primitive[:model][] + broadcast_foreach(primitive[1][], fields...) do point, c, markersize, strokecolor, strokewidth, marker + # TODO: Implement marker + # TODO: Accept :radius field or similar? + scale = project_scale(scene, markersize) + pos = project_position(scene, point, model) + Cairo.set_source_rgba(ctx, red(c), green(c), blue(c), alpha(c)) + Cairo.arc(ctx, pos[1], pos[2], scale[1] / 2, 0, 2*pi) + Cairo.fill(ctx) + sc = to_color(strokecolor) + Cairo.set_source_rgba(ctx, red(sc), green(sc), blue(sc), alpha(sc)) + Cairo.set_line_width(ctx, Float64(strokewidth)) + #if linestyle != nothing + # set_dash(ctx, convert_attribute(linestyle, key"linestyle"()), 0.0) + #end + Cairo.arc(ctx, pos[1], pos[2], scale[1], 0, 2*pi) + Cairo.stroke(ctx) + end + nothing +end + + + +function cairo_draw(screen::CairoScreen, primitive::Makie.Combined) + foreach(x-> cairo_draw(screen, x), primitive.plots) +end + +scale_matrix(x, y) = Cairo.CairoMatrix(x, 0.0, 0.0, y, 0.0, 0.0) +function rot_scale_matrix(x, y, q) + sx, sy, sz = 2q[4]*q[1], 2q[4]*q[2], 2q[4]*q[3] + xx, xy, xz = 2q[1]^2, 2q[1]*q[2], 2q[1]*q[3] + yy, yz, zz = 2q[2]^2, 2q[2]*q[3], 2q[3]^2 + m = Cairo.CairoMatrix( + x, 1 - (xx + zz), yz + sx, + y, yz - sx, 1 - (xx + yy) + ) + m +end + +function set_font_matrix(cr, matrix) + ccall((:cairo_set_font_matrix, Cairo._jl_libcairo), Cvoid, (Ptr{Cvoid}, Ptr{Cvoid}), cr.ptr, Ref(matrix)) +end + + +function set_ft_font(cr, font) + font_face = ccall( + (:cairo_ft_font_face_create_for_ft_face, Cairo._jl_libcairo), + Ptr{Cvoid}, (Ptr{Cvoid}, Cint), + font, 0 + ) + ccall((:cairo_set_font_face, Cairo._jl_libcairo), Cvoid, (Ptr{Cvoid}, Ptr{Cvoid}), cr.ptr, font_face) +end +fontname(x::String) = x +fontname(x::Symbol) = string(x) +function fontname(x::NativeFont) + ft_rect = unsafe_load(x[1]) + unsafe_string(ft_rect.family_name) +end + +function fontscale(scene, c, font, s) + atlas = AbstractPlotting.get_texture_atlas() + s = (s ./ atlas.scale[AbstractPlotting.glyph_index!(atlas, c, font)]) ./ 0.02 + project_scale(scene, s) +end + +function cairo_draw(screen::CairoScreen, primitive::Text) + scene = screen.scene + ctx = screen.context + @get_attribute(primitive, (textsize, color, font, align, rotation, model)) + txt = value(primitive[1]) + position = primitive.attributes[:position][] + N = length(txt) + broadcast_foreach(1:N, position, textsize, color, font, rotation) do i, p, ts, cc, f, r + Cairo.save(ctx) + pos = project_position(scene, p, model) + Cairo.move_to(ctx, pos[1], pos[2]) + Cairo.set_source_rgba(ctx, red(cc), green(cc), blue(cc), alpha(cc)) + + Cairo.select_font_face( + ctx, fontname(f), + Cairo.FONT_SLANT_NORMAL, + Cairo.FONT_WEIGHT_BOLD + ) + #set_ft_font(ctx, f) + char = N == length(position) ? txt[i] : first(txt) + ts = fontscale(scene, char, f, ts) + mat = scale_matrix(ts...) + set_font_matrix(ctx, mat) + # set_font_size(ctx, 16) + # TODO this only works in 2d + rotate(ctx, 2acos(r[4])) + if N == length(position) # if one position per glyph + Cairo.show_text(ctx, string(txt[i])) + else + Cairo.show_text(ctx, txt) + end + Cairo.restore(ctx) + end + nothing +end + +# TODO: heatmap! + +#TODO those are from Visualize.jl and need to get ported to the above + +#= +function cairo_draw(screen::CairoScreen, primitive::Text) + set_font_face(cr, text.font) + for (c, sprite) in zip(text.data, text.text) + vert = Visualize.vert_particles(sprite, canvas, uniforms) + rect = vert.rect + pos = rect[Vec(1, 2)] + scale = rect[Vec(3, 4)] + pos = clip2pixel_space(Vec4f0(pos[1], pos[2], 0, 1), canvas.resolution) + move_to(cd, pos...) + set_source_rgba(cr, vert.color...) + set_font_size(cr, vert.scale[1]) + show_text(cr, string(c)) + end +end + +function draw_window!(scene::Scene, cr::CairoContext) + Cairo.save(cr) + Cairo.set_source_rgba(cr, scene.backgroundcolor[]...) # light gray + Cairo.rectangle(cr, 0.0, 0.0, get(window, Visualize.Resolution)...) # background + Cairo.fill(cr) + Cairo.restore(cr) + Cairo.reset_clip(cr) + for (prim, (drawable, args)) in window[Visualize.Renderlist] + Cairo.save(cr) + drawable(args...) + Cairo.restore(cr) + end + return +end +=# + +function cairo_clear(screen::CairoScreen) + ctx = screen.context + w, h = Cairo.width(ctx), Cairo.height(ctx) + Cairo.rectangle(ctx, 0, 0, w, h) + # FIXME: Cairo.set_source_rgb(ctx, screen.scene.theme[:color]...) + Cairo.fill(ctx) +end + +function cairo_finish(screen::CairoScreen{CairoRGBSurface}) + @info("draw") + showall(screen.pane.window) + draw(screen.pane.canvas) do canvas + ctx = getgc(canvas) + w, h = Cairo.width(ctx), Cairo.height(ctx) + @info(w, " ", h) + # TODO: Maybe just use set_source(ctx, screen.surface)? + Cairo.image(ctx, screen.surface, 0, 0, w, h) + end +end +cairo_finish(screen::CairoScreen) = finish(screen.surface) + +function Base.display(screen::CairoScreen, scene::Scene) + Makie.center!(scene) + for elem in scene.plots + cairo_draw(screen, elem) + end + foreach(child_scene-> display(screen, child_scene), scene.children) + cairo_finish(screen) + return +end + + +end diff --git a/test/runtests.jl b/test/runtests.jl new file mode 100644 index 00000000000..07e21ab61d9 --- /dev/null +++ b/test/runtests.jl @@ -0,0 +1 @@ +using CairoMakie, Makie From 754eafec78a78eafc3625b7fc355bd7a369575ca Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 31 Oct 2018 14:07:54 +0100 Subject: [PATCH 0002/1328] make backend work with cs/display --- src/CairoMakie.jl | 49 +++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/src/CairoMakie.jl b/src/CairoMakie.jl index b51b9d49831..f58532cb822 100644 --- a/src/CairoMakie.jl +++ b/src/CairoMakie.jl @@ -1,16 +1,17 @@ module CairoMakie -import ..Makie -using ..Makie: Scene, Lines, Text, Image, Heatmap, Scatter, @key_str, broadcast_foreach -using ..Makie: convert_attribute, @extractvalue, LineSegments, to_ndim, NativeFont -using ..Makie: @info, @get_attribute -using Reactive, Colors, GeometryTypes - +import Makie +using Makie: Scene, Lines, Text, Image, Heatmap, Scatter, @key_str, broadcast_foreach +using Makie: convert_attribute, @extractvalue, LineSegments, to_ndim, NativeFont +using Makie: @info, @get_attribute +using Colors, GeometryTypes using AbstractPlotting -using AbstractPlotting: to_value, to_colormap +using AbstractPlotting: to_value, to_colormap, extrema_nan +using Cairo -using Cairo +struct CairoBackend <: AbstractPlotting.AbstractBackend +end struct CairoScreen{S} @@ -25,7 +26,6 @@ Base.insert!(screen::CairoScreen, scene::Scene, plot) = nothing # Default to Gtk Window+Canvas as backing device function CairoScreen(scene::Scene) w, h = round.(Int, scene.camera.resolution[]) - @info("Cairo screen: ", w, " ", h) surf = CairoRGBSurface(w, h) ctx = CairoContext(surf) win = GtkWindow() @@ -117,10 +117,8 @@ function cairo_draw(screen::CairoScreen, primitive::Union{Lines, LineSegments}) end nothing end -using AbstractPlotting: extrema_nan function to_cairo_image(img::AbstractMatrix{<: AbstractFloat}, attributes) - println("joooo") AbstractPlotting.@get_attribute attributes (colormap, colorrange) imui32 = to_uint32_color.(AbstractPlotting.interpolated_getindex.(Ref(colormap), img, (colorrange,))) to_cairo_image(imui32, attributes) @@ -143,7 +141,6 @@ function cairo_draw(screen::CairoScreen, primitive::Union{Heatmap, Image}) end function draw_image(screen, attributes) - println("Oh Hi") scene = screen.scene ctx = screen.context image = attributes[3][] @@ -239,7 +236,7 @@ function cairo_draw(screen::CairoScreen, primitive::Text) scene = screen.scene ctx = screen.context @get_attribute(primitive, (textsize, color, font, align, rotation, model)) - txt = value(primitive[1]) + txt = to_value(primitive[1]) position = primitive.attributes[:position][] N = length(txt) broadcast_foreach(1:N, position, textsize, color, font, rotation) do i, p, ts, cc, f, r @@ -316,27 +313,41 @@ function cairo_clear(screen::CairoScreen) end function cairo_finish(screen::CairoScreen{CairoRGBSurface}) - @info("draw") showall(screen.pane.window) draw(screen.pane.canvas) do canvas ctx = getgc(canvas) w, h = Cairo.width(ctx), Cairo.height(ctx) - @info(w, " ", h) # TODO: Maybe just use set_source(ctx, screen.surface)? Cairo.image(ctx, screen.surface, 0, 0, w, h) end end cairo_finish(screen::CairoScreen) = finish(screen.surface) -function Base.display(screen::CairoScreen, scene::Scene) - Makie.center!(scene) +function AbstractPlotting.backend_display(::CairoBackend, scene::Scene) + AbstractPlotting.update!(scene) + screen = CairoScreen(scene, joinpath(homedir(), "Desktop", "cairo.svg")) + cairo_draw(screen, scene) +end + +AbstractPlotting.backend_showable(::CairoBackend, m::MIME"image/svg", scene::SceneLike) = true + +function AbstractPlotting.backend_show(::CairoBackend, io::IO, ::MIME"image/svg+xml", scene::Scene) + AbstractPlotting.update!(scene) + screen = CairoScreen(scene, io) + cairo_draw(screen, scene) +end + + +function cairo_draw(screen::CairoScreen, scene::Scene) for elem in scene.plots cairo_draw(screen, elem) end - foreach(child_scene-> display(screen, child_scene), scene.children) + foreach(child_scene-> cairo_draw(screen, child_scene), scene.children) cairo_finish(screen) return end - +function __init__() + AbstractPlotting.register_backend!(CairoBackend()) +end end From 2136a25e94a8a5fab09743195efe5808644be9f8 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 7 Nov 2018 18:32:06 +0100 Subject: [PATCH 0003/1328] fix lines + segments --- src/CairoMakie.jl | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/CairoMakie.jl b/src/CairoMakie.jl index f58532cb822..6db2578a1b3 100644 --- a/src/CairoMakie.jl +++ b/src/CairoMakie.jl @@ -62,7 +62,7 @@ function project_scale(scene::Scene, s) p .* scene.camera.resolution[] end -function draw_segment(scene, ctx, point::Point, model, connect, do_stroke, c, linewidth, linestyle, primitive) +function draw_segment(scene, ctx, point::Point, model, c, linewidth, linestyle, primitive, idx, N) pos = project_position(scene, point, model) function stroke() Cairo.set_line_width(ctx, Float64(linewidth)) @@ -73,19 +73,27 @@ function draw_segment(scene, ctx, point::Point, model, connect, do_stroke, c, li Cairo.stroke(ctx) end if !all(isfinite.(pos)) - connect[] = false + stroke() # stroke last points, ignore this one (NaN for disconnects) else - if connect[] - Cairo.line_to(ctx, pos[1], pos[2]) - isa(primitive, LineSegments) && (connect[] = false) - end - if do_stroke[] - stroke(); do_stroke[] = false; connect[] = true - Cairo.move_to(ctx, pos[1], pos[2]) + if isa(primitive, LineSegments) + if isodd(idx) # on each odd move to + Cairo.move_to(ctx, pos[1], pos[2]) + else + Cairo.line_to(ctx, pos[1], pos[2]) + stroke() # stroke after each segment + end else - do_stroke[] = true + if idx == 1 + Cairo.move_to(ctx, pos[1], pos[2]) + else + Cairo.line_to(ctx, pos[1], pos[2]) + Cairo.move_to(ctx, pos[1], pos[2]) + end end end + if idx == N && isa(primitive, Lines) # after adding all points, lines need a stroke + stroke() + end end function draw_segment(scene, ctx, segment::Tuple{<: Point, <: Point}, model, connect, do_stroke, c, linewidth, linestyle, primitive) @@ -110,10 +118,10 @@ function cairo_draw(screen::CairoScreen, primitive::Union{Lines, LineSegments}) ctx = screen.context model = primitive[:model][] positions = primitive[1][] + isempty(positions) && return N = length(positions) - connect = Ref(true); do_stroke = Ref(true) broadcast_foreach(1:N, positions, fields...) do i, point, c, linewidth, linestyle - draw_segment(scene, ctx, point, model, connect, do_stroke, c, linewidth, linestyle, primitive) + draw_segment(scene, ctx, point, model, c, linewidth, linestyle, primitive, i, N) end nothing end From 37abf66b367bf64f0c38e5ec31edaea36a780d86 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 19 Nov 2018 16:42:50 +0100 Subject: [PATCH 0004/1328] initial commit --- .codecov.yml | 1 + .gitignore | 7 + .gitlab-ci.yml | 23 + LICENSE.md | 25 + README.md | 137 + REQUIRE | 32 + src/GLAbstraction/AbstractGPUArray.jl | 249 + src/GLAbstraction/GLAbstraction.jl | 119 + src/GLAbstraction/GLBuffer.jl | 197 + src/GLAbstraction/GLExtendedFunctions.jl | 231 + src/GLAbstraction/GLInfo.jl | 127 + src/GLAbstraction/GLRender.jl | 155 + src/GLAbstraction/GLRenderObject.jl | 203 + src/GLAbstraction/GLShader.jl | 373 + src/GLAbstraction/GLTexture.jl | 513 + src/GLAbstraction/GLTypes.jl | 413 + src/GLAbstraction/GLUniforms.jl | 261 + src/GLAbstraction/GLUtils.jl | 262 + src/GLAbstraction/composition.jl | 121 + src/GLMakie.jl | 101 + src/GLVisualize/GLVisualize.jl | 81 + src/GLVisualize/assets/cat.obj | 10667 ++++++++++++++++ src/GLVisualize/assets/diffusemap.tga | Bin 0 -> 1572908 bytes src/GLVisualize/assets/doge.png | Bin 0 -> 311062 bytes .../assets/shader/attribute_mesh.vert | 26 + src/GLVisualize/assets/shader/copy.frag | 12 + .../assets/shader/distance_shape.frag | 136 + src/GLVisualize/assets/shader/dots.frag | 10 + src/GLVisualize/assets/shader/dots.vert | 40 + .../assets/shader/fragment_output.frag | 9 + src/GLVisualize/assets/shader/fullscreen.vert | 15 + src/GLVisualize/assets/shader/fxaa.frag | 1049 ++ src/GLVisualize/assets/shader/intensity.frag | 46 + .../assets/shader/line_segment.geom | 62 + .../assets/shader/line_segment.vert | 29 + src/GLVisualize/assets/shader/lines.frag | 49 + src/GLVisualize/assets/shader/lines.geom | 177 + src/GLVisualize/assets/shader/lines.vert | 53 + src/GLVisualize/assets/shader/parametric.frag | 54 + src/GLVisualize/assets/shader/parametric.vert | 18 + src/GLVisualize/assets/shader/particles.vert | 146 + src/GLVisualize/assets/shader/plain.frag | 22 + src/GLVisualize/assets/shader/plain.vert | 17 + .../assets/shader/postprocess.frag | 27 + src/GLVisualize/assets/shader/sprites.geom | 113 + src/GLVisualize/assets/shader/sprites.vert | 128 + src/GLVisualize/assets/shader/standard.frag | 62 + src/GLVisualize/assets/shader/standard.vert | 22 + src/GLVisualize/assets/shader/surface.vert | 111 + src/GLVisualize/assets/shader/surface2.vert | 89 + src/GLVisualize/assets/shader/texture.frag | 25 + src/GLVisualize/assets/shader/util.vert | 290 + src/GLVisualize/assets/shader/uv_normal.frag | 63 + src/GLVisualize/assets/shader/uv_normal.vert | 25 + src/GLVisualize/assets/shader/uv_vert.vert | 20 + .../assets/shader/vertexcolor.vert | 25 + src/GLVisualize/assets/shader/volume.frag | 327 + src/GLVisualize/assets/shader/volume.vert | 18 + src/GLVisualize/boundingbox.jl | 58 + src/GLVisualize/types.jl | 239 + src/GLVisualize/utils.jl | 232 + src/GLVisualize/visualize/image_like.jl | 304 + src/GLVisualize/visualize/lines.jl | 178 + src/GLVisualize/visualize/mesh.jl | 59 + src/GLVisualize/visualize/particles.jl | 555 + src/GLVisualize/visualize/surface.jl | 233 + src/GLVisualize/visualize_interface.jl | 74 + src/drawing_primitives.jl | 412 + src/events.jl | 270 + src/glwindow.jl | 233 + src/rendering.jl | 124 + src/screen.jl | 361 + src/surface_contours.frag | 111 + src/video_io.jl | 148 + test/.gitignore | 2 + test/REQUIRE | 13 + test/makie_header.jl | 46 + test/runtests.jl | 5 + 78 files changed, 21270 insertions(+) create mode 100644 .codecov.yml create mode 100644 .gitignore create mode 100644 .gitlab-ci.yml create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 REQUIRE create mode 100644 src/GLAbstraction/AbstractGPUArray.jl create mode 100644 src/GLAbstraction/GLAbstraction.jl create mode 100644 src/GLAbstraction/GLBuffer.jl create mode 100644 src/GLAbstraction/GLExtendedFunctions.jl create mode 100644 src/GLAbstraction/GLInfo.jl create mode 100644 src/GLAbstraction/GLRender.jl create mode 100644 src/GLAbstraction/GLRenderObject.jl create mode 100644 src/GLAbstraction/GLShader.jl create mode 100644 src/GLAbstraction/GLTexture.jl create mode 100644 src/GLAbstraction/GLTypes.jl create mode 100644 src/GLAbstraction/GLUniforms.jl create mode 100644 src/GLAbstraction/GLUtils.jl create mode 100644 src/GLAbstraction/composition.jl create mode 100644 src/GLMakie.jl create mode 100644 src/GLVisualize/GLVisualize.jl create mode 100644 src/GLVisualize/assets/cat.obj create mode 100644 src/GLVisualize/assets/diffusemap.tga create mode 100644 src/GLVisualize/assets/doge.png create mode 100644 src/GLVisualize/assets/shader/attribute_mesh.vert create mode 100644 src/GLVisualize/assets/shader/copy.frag create mode 100644 src/GLVisualize/assets/shader/distance_shape.frag create mode 100644 src/GLVisualize/assets/shader/dots.frag create mode 100644 src/GLVisualize/assets/shader/dots.vert create mode 100644 src/GLVisualize/assets/shader/fragment_output.frag create mode 100644 src/GLVisualize/assets/shader/fullscreen.vert create mode 100644 src/GLVisualize/assets/shader/fxaa.frag create mode 100644 src/GLVisualize/assets/shader/intensity.frag create mode 100644 src/GLVisualize/assets/shader/line_segment.geom create mode 100644 src/GLVisualize/assets/shader/line_segment.vert create mode 100644 src/GLVisualize/assets/shader/lines.frag create mode 100644 src/GLVisualize/assets/shader/lines.geom create mode 100644 src/GLVisualize/assets/shader/lines.vert create mode 100644 src/GLVisualize/assets/shader/parametric.frag create mode 100644 src/GLVisualize/assets/shader/parametric.vert create mode 100644 src/GLVisualize/assets/shader/particles.vert create mode 100644 src/GLVisualize/assets/shader/plain.frag create mode 100644 src/GLVisualize/assets/shader/plain.vert create mode 100644 src/GLVisualize/assets/shader/postprocess.frag create mode 100644 src/GLVisualize/assets/shader/sprites.geom create mode 100644 src/GLVisualize/assets/shader/sprites.vert create mode 100644 src/GLVisualize/assets/shader/standard.frag create mode 100644 src/GLVisualize/assets/shader/standard.vert create mode 100644 src/GLVisualize/assets/shader/surface.vert create mode 100644 src/GLVisualize/assets/shader/surface2.vert create mode 100644 src/GLVisualize/assets/shader/texture.frag create mode 100644 src/GLVisualize/assets/shader/util.vert create mode 100644 src/GLVisualize/assets/shader/uv_normal.frag create mode 100644 src/GLVisualize/assets/shader/uv_normal.vert create mode 100644 src/GLVisualize/assets/shader/uv_vert.vert create mode 100644 src/GLVisualize/assets/shader/vertexcolor.vert create mode 100644 src/GLVisualize/assets/shader/volume.frag create mode 100644 src/GLVisualize/assets/shader/volume.vert create mode 100644 src/GLVisualize/boundingbox.jl create mode 100644 src/GLVisualize/types.jl create mode 100644 src/GLVisualize/utils.jl create mode 100644 src/GLVisualize/visualize/image_like.jl create mode 100644 src/GLVisualize/visualize/lines.jl create mode 100644 src/GLVisualize/visualize/mesh.jl create mode 100644 src/GLVisualize/visualize/particles.jl create mode 100644 src/GLVisualize/visualize/surface.jl create mode 100644 src/GLVisualize/visualize_interface.jl create mode 100644 src/drawing_primitives.jl create mode 100644 src/events.jl create mode 100644 src/glwindow.jl create mode 100644 src/rendering.jl create mode 100644 src/screen.jl create mode 100644 src/surface_contours.frag create mode 100644 src/video_io.jl create mode 100644 test/.gitignore create mode 100644 test/REQUIRE create mode 100644 test/makie_header.jl create mode 100644 test/runtests.jl diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 00000000000..69cb76019a4 --- /dev/null +++ b/.codecov.yml @@ -0,0 +1 @@ +comment: false diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000000..be4a0983bed --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +*.jl.cov +*.jl.*.cov +*.jl.mem +precompile.jl +build +src/glbackend/.cache +test/testimages/* diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 00000000000..612599840e4 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,23 @@ +variables: + CI_IMAGE_TAG: "opengl" + MODERNGL_DEBUGGING: "true" + JULIA_DEPOT_PATH: "$CI_PROJECT_DIR/.julia/" + +job: + image: "juliagpu/julia:v1.0-${CI_IMAGE_TAG}" + before_script: + - apt-get -qq update + # glfw + - apt-get install -y cmake libxrandr-dev libxinerama-dev libxcursor-dev mesa-utils + # cairo etc + - apt-get install -y gettext libpango1.0-0 libcairo2 libmagickwand-6.q16-2 + - apt-get install -y ffmpeg + + script: + - julia -e 'using InteractiveUtils; versioninfo()' + - julia --project -e "using Pkg; + Pkg.instantiate(); + Pkg.add(PackageSpec(name = \"Makie\", path=ENV[\"CI_PROJECT_DIR\"])); + Pkg.pkg\"add AbstractPlotting#master\"; + Pkg.build(); + Pkg.test(\"Makie\");" diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000000..ff81d888300 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,25 @@ +The Makie.jl package is licensed under the MIT "Expat" License: + +> Copyright (c) 2017: SimonDanisch. +> +> Permission is hereby granted, free of charge, to any person obtaining a copy +> of this software and associated documentation files (the "Software"), to deal +> in the Software without restriction, including without limitation the rights +> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +> copies of the Software, and to permit persons to whom the Software is +> furnished to do so, subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in all +> copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +> SOFTWARE. +> + + +Icon made by neungstockr from www.flaticon.com diff --git a/README.md b/README.md new file mode 100644 index 00000000000..357d123173a --- /dev/null +++ b/README.md @@ -0,0 +1,137 @@ +
+Makie.jl +
+ + + +From the japanese word [Maki-e](https://en.wikipedia.org/wiki/Maki-e), which is a technique to sprinkle lacquer with gold and silver powder. +Data is basically the gold and silver of our age, so lets spread it out beautifully on the screen! + +**Documentation**: [![][docs-stable-img]][docs-stable-url] + +Build status: [![][gitlab-img]][gitlab-url] + +[gitlab-img]: https://gitlab.com/JuliaGPU/Makie.jl/badges/master/pipeline.svg +[gitlab-url]: https://gitlab.com/JuliaGPU/Makie.jl/pipelines +[docs-stable-img]: https://img.shields.io/badge/docs-stable-blue.svg +[docs-stable-url]: http://makie.juliaplots.org/stable/ + + + +# Installation + +```julia +julia>] +pkg> add Makie +pkg> test Makie +``` + +## Dependencies +You will need to have ffmpeg in the path to run the video recording examples. +On linux you also need to add the following to get GLFW to build (if you don't have those already): +``` +sudo apt-get install ffmpeg cmake xorg-dev +``` + + +## Examples from the documentation: + +[![](http://makie.juliaplots.org/stable/media/thumb-3d_contour_with_2d_contour_slices.jpg)](http://makie.juliaplots.org/stable/examples-volume.html#3D-Contour-with-2D-contour-slices-1) +[![](http://makie.juliaplots.org/stable/media/thumb-animated_scatter.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#Animated-Scatter-1) +[![](http://makie.juliaplots.org/stable/media/thumb-animated_surface_and_wireframe.jpg)](http://makie.juliaplots.org/stable/examples-surface.html#Animated-surface-and-wireframe-1) +[![](http://makie.juliaplots.org/stable/media/thumb-arrows_3d.jpg)](http://makie.juliaplots.org/stable/examples-arrows.html#Arrows-3D-1) +[![](http://makie.juliaplots.org/stable/media/thumb-arrows_on_sphere.jpg)](http://makie.juliaplots.org/stable/examples-surface.html#Arrows-on-Sphere-1) +[![](http://makie.juliaplots.org/stable/media/thumb-axis___surface.jpg)](http://makie.juliaplots.org/stable/examples-surface.html#Axis-+-Surface-1) +[![](http://makie.juliaplots.org/stable/media/thumb-barplot_1.jpg)](http://makie.juliaplots.org/stable/examples-barplot.html#barplot-1) +[![](http://makie.juliaplots.org/stable/media/thumb-colored_mesh.jpg)](http://makie.juliaplots.org/stable/examples-mesh.html#Colored-Mesh-1) +[![](http://makie.juliaplots.org/stable/media/thumb-colored_triangle.jpg)](http://makie.juliaplots.org/stable/examples-mesh.html#colored-triangle-1) +[![](http://makie.juliaplots.org/stable/media/thumb-colormaps.jpg)](http://makie.juliaplots.org/stable/examples-image.html#colormaps-1) +[![](http://makie.juliaplots.org/stable/media/thumb-connected_sphere.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#Connected-Sphere-1) +[![](http://makie.juliaplots.org/stable/media/thumb-contour_1.jpg)](http://makie.juliaplots.org/stable/examples-contour.html#contour-1) +[![](http://makie.juliaplots.org/stable/media/thumb-contour_function.jpg)](http://makie.juliaplots.org/stable/examples-contour.html#Contour-Function-1) +[![](http://makie.juliaplots.org/stable/media/thumb-fem_mesh_3d.jpg)](http://makie.juliaplots.org/stable/examples-mesh.html#FEM-mesh-3D-1) +[![](http://makie.juliaplots.org/stable/media/thumb-fem_polygon_2d.jpg)](http://makie.juliaplots.org/stable/examples-poly.html#FEM-polygon-2D-1) +[![](http://makie.juliaplots.org/stable/media/thumb-fluctuation_3d.jpg)](http://makie.juliaplots.org/stable/examples-meshscatter.html#Fluctuation-3D-1) +[![](http://makie.juliaplots.org/stable/media/thumb-heatmap_1.jpg)](http://makie.juliaplots.org/stable/examples-heatmap.html#Heatmap-1) +[![](http://makie.juliaplots.org/stable/media/thumb-heatmap_interpolation.jpg)](http://makie.juliaplots.org/stable/examples-heatmap.html#heatmap-interpolation-1) +[![](http://makie.juliaplots.org/stable/media/thumb-image_1.jpg)](http://makie.juliaplots.org/stable/examples-image.html#image-1) +[![](http://makie.juliaplots.org/stable/media/thumb-image_on_surface_sphere.jpg)](http://makie.juliaplots.org/stable/examples-surface.html#Image-on-Surface-Sphere-1) +[![](http://makie.juliaplots.org/stable/media/thumb-image_scatter.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#image-scatter-1) +[![](http://makie.juliaplots.org/stable/media/thumb-interaction.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#Interaction-1) +[![](http://makie.juliaplots.org/stable/media/thumb-interaction_with_mouse.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#Interaction-with-Mouse-1) +[![](http://makie.juliaplots.org/stable/media/thumb-line_function.jpg)](http://makie.juliaplots.org/stable/examples-lines.html#Line-Function-1) +[![](http://makie.juliaplots.org/stable/media/thumb-line_gif.jpg)](http://makie.juliaplots.org/stable/examples-lines.html#Line-GIF-1) +[![](http://makie.juliaplots.org/stable/media/thumb-load_mesh.jpg)](http://makie.juliaplots.org/stable/examples-mesh.html#Load-Mesh-1) +[![](http://makie.juliaplots.org/stable/media/thumb-marker_offset.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#Marker-offset-1) +[![](http://makie.juliaplots.org/stable/media/thumb-marker_sizes.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#Marker-sizes-1) +[![](http://makie.juliaplots.org/stable/media/thumb-marker_sizes___marker_colors.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#Marker-sizes-+-Marker-colors-1) +[![](http://makie.juliaplots.org/stable/media/thumb-merged_color_mesh.jpg)](http://makie.juliaplots.org/stable/examples-mesh.html#Merged-color-Mesh-1) +[![](http://makie.juliaplots.org/stable/media/thumb-meshscatter_function.jpg)](http://makie.juliaplots.org/stable/examples-meshscatter.html#Meshscatter-Function-1) +[![](http://makie.juliaplots.org/stable/media/thumb-moire.jpg)](http://makie.juliaplots.org/stable/examples-linesegments.html#Moire-1) +[![](http://makie.juliaplots.org/stable/media/thumb-mouse_picking.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#Mouse-Picking-1) +[![](http://makie.juliaplots.org/stable/media/thumb-normals_of_a_cat.jpg)](http://makie.juliaplots.org/stable/examples-mesh.html#Normals-of-a-Cat-1) +[![](http://makie.juliaplots.org/stable/media/thumb-polygons.jpg)](http://makie.juliaplots.org/stable/examples-linesegments.html#Polygons-1) +[![](http://makie.juliaplots.org/stable/media/thumb-pong.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#pong-1) +[![](http://makie.juliaplots.org/stable/media/thumb-quiver_1.jpg)](http://makie.juliaplots.org/stable/examples-arrows.html#quiver-1) +[![](http://makie.juliaplots.org/stable/media/thumb-record_video.jpg)](http://makie.juliaplots.org/stable/examples-meshscatter.html#Record-Video-1) +[![](http://makie.juliaplots.org/stable/media/thumb-scatter_1.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#scatter-1) +[![](http://makie.juliaplots.org/stable/media/thumb-scatter_colormap.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#scatter-colormap-1) +[![](http://makie.juliaplots.org/stable/media/thumb-simple_meshscatter.jpg)](http://makie.juliaplots.org/stable/examples-meshscatter.html#Simple-meshscatter-1) +[![](http://makie.juliaplots.org/stable/media/thumb-sphere_mesh.jpg)](http://makie.juliaplots.org/stable/examples-mesh.html#Sphere-Mesh-1) +[![](http://makie.juliaplots.org/stable/media/thumb-subscenes.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#Subscenes-1) +[![](http://makie.juliaplots.org/stable/media/thumb-surface_1.jpg)](http://makie.juliaplots.org/stable/examples-surface.html#Surface-1) +[![](http://makie.juliaplots.org/stable/media/thumb-surface_with_image.jpg)](http://makie.juliaplots.org/stable/examples-surface.html#Surface-with-image-1) +[![](http://makie.juliaplots.org/stable/media/thumb-surface___contour3d.jpg)](http://makie.juliaplots.org/stable/examples-surface.html#surface-+-contour3d-1) +[![](http://makie.juliaplots.org/stable/media/thumb-test_heatmap___image_overlap.jpg)](http://makie.juliaplots.org/stable/examples-heatmap.html#Test-heatmap-+-image-overlap-1) +[![](http://makie.juliaplots.org/stable/media/thumb-textured_mesh.jpg)](http://makie.juliaplots.org/stable/examples-mesh.html#Textured-Mesh-1) +[![](http://makie.juliaplots.org/stable/media/thumb-text_annotation.jpg)](http://makie.juliaplots.org/stable/examples-text.html#Text-Annotation-1) +[![](http://makie.juliaplots.org/stable/media/thumb-text_rotation.jpg)](http://makie.juliaplots.org/stable/examples-text.html#Text-rotation-1) +[![](http://makie.juliaplots.org/stable/media/thumb-travelling_wave.jpg)](http://makie.juliaplots.org/stable/examples-lines.html#Travelling-wave-1) +[![](http://makie.juliaplots.org/stable/media/thumb-type_recipe_for_molecule_simulation.jpg)](http://makie.juliaplots.org/stable/examples-meshscatter.html#Type-recipe-for-molecule-simulation-1) +[![](http://makie.juliaplots.org/stable/media/thumb-unicode_marker.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#Unicode-Marker-1) +[![](http://makie.juliaplots.org/stable/media/thumb-viridis_meshscatter.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#Viridis-meshscatter-1) +[![](http://makie.juliaplots.org/stable/media/thumb-viridis_scatter.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#Viridis-scatter-1) +[![](http://makie.juliaplots.org/stable/media/thumb-volume_function.jpg)](http://makie.juliaplots.org/stable/examples-volume.html#Volume-Function-1) +[![](http://makie.juliaplots.org/stable/media/thumb-wireframe_of_a_mesh.jpg)](http://makie.juliaplots.org/stable/examples-mesh.html#Wireframe-of-a-Mesh-1) +[![](http://makie.juliaplots.org/stable/media/thumb-wireframe_of_a_surface.jpg)](http://makie.juliaplots.org/stable/examples-surface.html#Wireframe-of-a-Surface-1) + + +## Mouse interaction: + +[](https://vimeo.com/237204560 "Mouse Interaction") + +## Animating a surface: + +[](https://vimeo.com/237284958 "Surface Plot") + + +## Complex examples + + +## IJulia examples: + +[![](https://user-images.githubusercontent.com/1010467/32204865-33482ddc-bdec-11e7-9693-b94d999187dc.png)](https://gist.github.com/SimonDanisch/8f5489cffaf6b89c9a3712ba3eb12a84) + + +# Precompilation + +You can compile binary for Makie and add it to your system image for fast plotting times with no JIT overhead. +To do that, you need to check out the additional packages for precompilation. +Then you can build a system image like this: + +```julia +# add PackageCompiler +Pkg.add("PackageCompiler") +using PackageCompiler +# This is not well tested, so please be careful - I don't take any responsibilities for a messed up Julia install. + +# The safe option: +PackageCompiler.compile_package("Makie", force = false) # can take around ~20 minutes + +# Replaces julias system image +# please be very careful with the option below, since this can make your julia stop working. +# If Julia doesn't start for you anymore, consider doing: +# using PackageCompiler; PackageCompiler.revert() <- not well tested + +PackageCompiler.compile_package("Makie", force = true) +``` diff --git a/REQUIRE b/REQUIRE new file mode 100644 index 00000000000..dce3ad2311c --- /dev/null +++ b/REQUIRE @@ -0,0 +1,32 @@ +julia 0.7 + +StaticArrays 0.6.6 +GeometryTypes 0.4.5 +Observables +Contour +FileIO +ImageCore +ImageTransformations +UnicodeFun +ColorBrewer +ModernGL +GLFW 2.3.0 +FreeType +FreeTypeAbstraction 0.3.0 #for findfont +@windows ImageMagick +@linux ImageMagick +@osx QuartzImageIO +AbstractPlotting +Primes +PlotUtils +#Cairo +IntervalSets +Showoff +ColorTypes +Colors +ColorVectorSpace +FixedPointNumbers +IterTools +AxisArrays +ImageAxes +IndirectArrays diff --git a/src/GLAbstraction/AbstractGPUArray.jl b/src/GLAbstraction/AbstractGPUArray.jl new file mode 100644 index 00000000000..6f09aa3e2d7 --- /dev/null +++ b/src/GLAbstraction/AbstractGPUArray.jl @@ -0,0 +1,249 @@ +import Base: copy! +import Base: splice! +import Base: append! +import Base: push! +import Base: resize! +import Base: setindex! +import Base: getindex +import Base: map +import Base: length +import Base: eltype +import Base: lastindex +import Base: ndims +import Base: size +import Base: iterate +using Serialization +import GeometryTypes.SimpleRectangle + +abstract type GPUArray{T, NDim} <: AbstractArray{T, NDim} end + +#= +immutable GPUArray{T, NDim, GPUBuff <: GPUBuffer} <: DenseArray{T, NDim} + buff::GPUBuff{T, NDim} + size::NTuple{Int, NDim} +end + +immutable BufferedGPUArray{GPUArr <: GPUArray} + buff::GPUBuff{T, NDim} + ram::Array{T, NDim} +end +=# +length(A::GPUArray) = prod(size(A)) +eltype(b::GPUArray{T, NDim}) where {T, NDim} = T +lastindex(A::GPUArray) = length(A) +ndims(A::GPUArray{T, NDim}) where {T, NDim} = NDim +size(A::GPUArray) = A.size +size(A::GPUArray, i::Integer) = i <= ndims(A) ? A.size[i] : 1 + +function checkdimensions(value::Array, ranges::Union{Integer, UnitRange}...) + array_size = size(value) + indexes_size = map(length, ranges) + + (array_size != indexes_size) && throw(DimensionMismatch("asigning a $array_size to a $(indexes_size) location")) + true +end +function to_range(index) + map(index) do val + isa(val, Integer) && return val:val + isa(val, AbstractRange) && return val + error("Indexing only defined for integers or ranges. Found: $val") + end +end +setindex!(A::GPUArray{T, N}, value::Union{T, Array{T, N}}) where {T, N} = (A[1] = value) + +function setindex!(A::GPUArray{T, N}, value, indexes...) where {T, N} + ranges = to_range(indexes) + v = isa(value, T) ? [value] : convert(Array{T,N}, value) + setindex!(A, v, ranges...) + nothing +end + +setindex!(A::GPUArray{T, 2}, value::Vector{T}, i::Integer, range::UnitRange) where {T} = + (A[i, range] = reshape(value, (length(value),1))) + +function setindex!(A::GPUArray{T, N}, value::Array{T, N}, ranges::UnitRange...) where {T, N} + checkbounds(A, ranges...) + checkdimensions(value, ranges...) + gpu_setindex!(A, value, ranges...) + nothing +end + +function update!(A::GPUArray{T, N}, value::AbstractArray{T2, N}) where {T, N, T2} + update!(A, convert(Vector{T}, value)) +end +function update!(A::GPUArray{T, N}, value::AbstractArray{T, N}) where {T, N} + if length(A) != length(value) + if isa(A, GLBuffer) + resize!(A, length(value)) + elseif isa(A, Texture) + resize_nocopy!(A, size(value)) + else + error("Dynamic resizing not implemented for $(typeof(A))") + end + end + dims = map(x-> 1:x, size(A)) + A[dims...] = value + nothing +end + +function getindex(A::GPUArray{T, N}, i::Int) where {T, N} + checkbounds(A, i) + gpu_getindex(A, i:i)[1] # not as bad as its looks, as so far gpu data must be loaded into an array anyways +end +function getindex(A::GPUArray{T, N}, ranges::UnitRange...) where {T, N} + checkbounds(A, ranges...) + gpu_getindex(A, ranges...) +end + +function getindex(A::GPUArray{T, N}, rect::SimpleRectangle) where {T, N} + A[rect.x+1:rect.x+rect.w, rect.y+1:rect.y+rect.h] +end +function setindex!(A::GPUArray{T, N}, value::AbstractArray{T, N}, rect::SimpleRectangle) where {T, N} + A[rect.x+1:rect.x+rect.w, rect.y+1:rect.y+rect.h] = value +end + + +mutable struct GPUVector{T} <: GPUArray{T, 1} + buffer + size + real_length +end +GPUVector(x::GPUArray) = GPUVector{eltype(x)}(x, size(x), length(x)) + +function update!(A::GPUVector{T}, value::AbstractVector{T}) where T + if isa(A, GLBuffer) && (length(A) != length(value)) + resize!(A, length(value)) + end + dims = map(x->1:x, size(A)) + A.buffer[dims...] = value + nothing +end + +length(v::GPUVector) = prod(size(v)) +size(v::GPUVector) = v.size +size(v::GPUVector, i::Integer) = v.size[i] +ndims(::GPUVector) = 1 +eltype(::GPUVector{T}) where {T} = T +lastindex(A::GPUVector) = length(A) + + +iterate(b::GPUVector, state = 1) = iterate(b.buffer, state) + +gpu_data(A::GPUVector) = A.buffer[1:length(A)] + +getindex(v::GPUVector, index::Int) = v.buffer[index] +getindex(v::GPUVector, index::UnitRange) = v.buffer[index] +setindex!(v::GPUVector{T}, value::T, index::Int) where {T} = v.buffer[index] = value +setindex!(v::GPUVector{T}, value::T, index::UnitRange) where {T} = v.buffer[index] = value + + +function grow_dimensions(real_length::Int, _size::Int, additonal_size::Int, growfactor::Real=1.5) + new_dim = round(Int, real_length*growfactor) + return max(new_dim, additonal_size+_size) +end +function Base.push!(v::GPUVector{T}, x::AbstractVector{T}) where T + lv, lx = length(v), length(x) + if (v.real_length < lv+lx) + resize!(v.buffer, grow_dimensions(v.real_length, lv, lx)) + end + v.buffer[lv+1:(lv+lx)] = x + v.real_length = length(v.buffer) + v.size = (lv+lx,) + v +end +push!(v::GPUVector{T}, x::T) where {T} = push!(v, [x]) +push!(v::GPUVector{T}, x::T...) where {T} = push!(v, [x...]) +append!(v::GPUVector{T}, x::Vector{T}) where {T} = push!(v, x) + +resize!(A::GPUArray{T, NDim}, dims::Int...) where {T, NDim} = resize!(A, dims) +function resize!(A::GPUArray{T, NDim}, newdims::NTuple{NDim, Int}) where {T, NDim} + newdims == size(A) && return A + gpu_resize!(A, newdims) + A +end + +function resize!(v::GPUVector, newlength::Int) + if v.real_length >= newlength # is still big enough + v.size = (max(0, newlength),) + return v + end + resize!(v.buffer, grow_dimensions(v.real_length, length(v), newlength-length(v))) + v.size = (newlength,) + v.real_length = length(v.buffer) +end +function grow_at(v::GPUVector, index::Int, amount::Int) + resize!(v, length(v)+amount) + copy!(v, index, v, index+amount, amount) +end + +function splice!(v::GPUVector{T}, index::UnitRange, x::Vector=T[]) where T + lenv = length(v) + elements_to_grow = length(x)-length(index) # -1 + buffer = similar(v.buffer, length(v)+elements_to_grow) + copy!(v.buffer, 1, buffer, 1, first(index)-1) # copy first half + copy!(v.buffer, last(index)+1, buffer, first(index)+length(x), lenv-last(index)) # shift second half + v.buffer = buffer + v.real_length = length(buffer) + v.size = (v.real_length,) + copy!(x, 1, buffer, first(index), length(x)) # copy contents of insertion vector + nothing +end +splice!(v::GPUVector{T}, index::Int, x::T) where {T} = v[index] = x +splice!(v::GPUVector{T}, index::Int, x::Vector=T[]) where {T} = splice!(v, index:index, map(T, x)) + + +copy!(a::GPUVector, a_offset::Int, b::Vector, b_offset::Int, amount::Int) = copy!(a.buffer, a_offset, b, b_offset, amount) +copy!(a::GPUVector, a_offset::Int, b::GPUVector, b_offset::Int, amount::Int)= copy!(a.buffer, a_offset, b.buffer, b_offset, amount) + + +copy!(a::GPUArray, a_offset::Int, b::Vector, b_offset::Int, amount::Int) = _copy!(a, a_offset, b, b_offset, amount) +copy!(a::Vector, a_offset::Int, b::GPUArray, b_offset::Int, amount::Int) = _copy!(a, a_offset, b, b_offset, amount) +copy!(a::GPUArray, a_offset::Int, b::GPUArray, b_offset::Int, amount::Int) = _copy!(a, a_offset, b, b_offset, amount) + +#don't overwrite Base.copy! with a::Vector, b::Vector +function _copy!(a::Union{Vector, GPUArray}, a_offset::Int, b::Union{Vector, GPUArray}, b_offset::Int, amount::Int) + (amount <= 0) && return nothing + @assert a_offset > 0 && (a_offset-1) + amount <= length(a) "a_offset $a_offset, amount $amount, lengtha $(length(a))" + @assert b_offset > 0 && (b_offset-1) + amount <= length(b) "b_offset $b_offset, amount $amount, lengthb $(length(b))" + unsafe_copy!(a, a_offset, b, b_offset, amount) + return nothing +end + +# Interface: +gpu_data(t) = error("gpu_data not implemented for: $(typeof(t)). This happens, when you call data on an array, without implementing the GPUArray interface") +gpu_resize!(t) = error("gpu_resize! not implemented for: $(typeof(t)). This happens, when you call resize! on an array, without implementing the GPUArray interface") +gpu_getindex(t) = error("gpu_getindex not implemented for: $(typeof(t)). This happens, when you call getindex on an array, without implementing the GPUArray interface") +gpu_setindex!(t) = error("gpu_setindex! not implemented for: $(typeof(t)). This happens, when you call setindex! on an array, without implementing the GPUArray interface") +max_dim(t) = error("max_dim not implemented for: $(typeof(t)). This happens, when you call setindex! on an array, without implementing the GPUArray interface") + + +function (::Type{T})(x::Node; kw...) where T <: GPUArray + gpu_mem = T(x[]; kw...) + on(x-> update!(gpu_mem, x), x) + gpu_mem +end + +const BaseSerializer = Serialization.AbstractSerializer + +function Serialization.serialize(s::BaseSerializer, t::T) where T<:GPUArray + Serialization.serialize_type(s, T) + Serialization.serialize(s, Array(t)) +end +function Serialization.deserialize(s::BaseSerializer, ::Type{T}) where T <: GPUArray + A = Serialization.deserialize(s) + T(A) +end + + +export data +export resize +export GPUArray +export GPUVector + +export update! + +export gpu_data +export gpu_resize! +export gpu_getindex +export gpu_setindex! +export max_dim diff --git a/src/GLAbstraction/GLAbstraction.jl b/src/GLAbstraction/GLAbstraction.jl new file mode 100644 index 00000000000..ea9b62986e4 --- /dev/null +++ b/src/GLAbstraction/GLAbstraction.jl @@ -0,0 +1,119 @@ +module GLAbstraction + +using StaticArrays +using GeometryTypes +using ModernGL +using AbstractPlotting +using FixedPointNumbers +using ColorTypes +using FileIO +using GLFW +using Printf +using LinearAlgebra +using AbstractPlotting +using Observables + +import FileIO: load, save + +import FixedPointNumbers: N0f8, N0f16, N0f8, Normed + + +import Base: merge, resize!, similar, length, getindex, setindex! + +include("AbstractGPUArray.jl") + +#Methods which get overloaded by GLExtendedFunctions.jl: +import ModernGL.glShaderSource +import ModernGL.glGetAttachedShaders +import ModernGL.glGetActiveUniform +import ModernGL.glGetActiveAttrib +import ModernGL.glGetProgramiv +import ModernGL.glGetIntegerv +import ModernGL.glGenBuffers +import ModernGL.glGetProgramiv +import ModernGL.glGenVertexArrays +import ModernGL.glGenTextures +import ModernGL.glGenFramebuffers +import ModernGL.glGetTexLevelParameteriv +import ModernGL.glGenRenderbuffers +import ModernGL.glDeleteTextures +import ModernGL.glDeleteVertexArrays +import ModernGL.glDeleteBuffers +import ModernGL.glGetShaderiv +import ModernGL.glViewport +import ModernGL.glScissor + +include("composition.jl") +export Composable, Context, convert! + + +include("GLUtils.jl") +export @gputime # measures the time an OpenGL call takes on the GPU (usually OpenGL calls return immidiately) +export @materialize #splats keywords from a dict into variables +export @materialize! #splats keywords from a dict into variables and deletes them from the dict +export close_to_square +export AND, OR, isnotempty + +include("GLTypes.jl") +export GLProgram # Shader/program object +export Texture # Texture object, basically a 1/2/3D OpenGL data array +export TextureParameters +export TextureBuffer # OpenGL texture buffer +export update! # updates a gpu array with a Julia array +export gpu_data # gets the data of a gpu array as a Julia Array + +export RenderObject # An object which holds all GPU handles and datastructes to ready for rendering by calling render(obj) +export prerender! # adds a function to a RenderObject, which gets executed befor setting the OpenGL render state +export postrender! # adds a function to a RenderObject, which gets executed after setting the OpenGL render states +export std_renderobject # creates a renderobject with standard parameters +export instanced_renderobject # simplification for creating a RenderObject which renders instances +export extract_renderable +export set_arg! +export GLVertexArray # VertexArray wrapper object +export GLBuffer # OpenGL Buffer object wrapper +export indexbuffer # Shortcut to create an OpenGL Buffer object for indexes (1D, cardinality of one and GL_ELEMENT_ARRAY_BUFFER set) +export opengl_compatible # infers if a type is opengl compatible and returns stats like cardinality and eltype (will be deprecated) +export cardinality # returns the cardinality of the elements of a buffer + +export Style # Style Type, which is used to choose different visualization/editing styles via multiple dispatch +export mergedefault! # merges a style dict via a given style +export TOrSignal, VecOrSignal, ArrayOrSignal, MatOrSignal, VolumeOrSignal, ArrayTypes, VectorTypes, MatTypes, VolumeTypes +export MouseButton, MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT + + + +include("GLExtendedFunctions.jl") +export glTexImage # Julian wrapper for glTexImage1D, glTexImage2D, glTexImage3D +include("GLShader.jl") +export Shader #Shader Type +export readshader #reads a shader +export glsl_variable_access # creates access string from julia variable for the use in glsl shaders +export createview #creates a view from a templated shader +export TemplateProgram # Creates a shader from a Mustache view and and a shader file, which uses mustache syntax to replace values. +export @comp_str #string macro for the different shader types. +export @frag_str # with them you can write frag""" ..... """, returning shader object +export @vert_str +export @geom_str +export AbstractLazyShader, LazyShader + +include("GLUniforms.jl") +export gluniform # wrapper of all the OpenGL gluniform functions, which call the correct gluniform function via multiple dispatch. Example: gluniform(location, x::Matrix4x4) = gluniformMatrix4fv(location, x) +export toglsltype_string # infers a glsl type string from a julia type. Example: Matrix4x4 -> uniform mat4 +# Also exports Macro generated GLSL alike aliases for Float32 Matrices and Vectors +# only difference to GLSL: first character is uppercase uppercase +export gl_convert + + +include("GLRender.jl") +export render #renders arbitrary objects +export enabletransparency # can be pushed to an renderobject, enables transparency +export renderinstanced # renders objects instanced + +include("GLInfo.jl") +export getUniformsInfo +export getProgramInfo +export getAttributesInfo + +dir(dirs...) = joinpath(dirname(@__FILE__), "..", dirs...) + +end # module diff --git a/src/GLAbstraction/GLBuffer.jl b/src/GLAbstraction/GLBuffer.jl new file mode 100644 index 00000000000..df710a787b1 --- /dev/null +++ b/src/GLAbstraction/GLBuffer.jl @@ -0,0 +1,197 @@ +mutable struct GLBuffer{T} <: GPUArray{T, 1} + id ::GLuint + size ::NTuple{1, Int} + buffertype ::GLenum + usage ::GLenum + context ::GLContext + + function GLBuffer{T}(ptr::Ptr{T}, buff_length::Int, buffertype::GLenum, usage::GLenum) where T + id = glGenBuffers() + glBindBuffer(buffertype, id) + # size of 0 can segfault it seems + buff_length = buff_length == 0 ? 1 : buff_length + glBufferData(buffertype, buff_length * sizeof(T), ptr, usage) + glBindBuffer(buffertype, 0) + + obj = new(id, (buff_length,), buffertype, usage, current_context()) + finalizer(free, obj) + obj + end +end +bind(buffer::GLBuffer) = glBindBuffer(buffer.buffertype, buffer.id) +#used to reset buffer target +bind(buffer::GLBuffer, other_target) = glBindBuffer(buffer.buffertype, other_target) + +function similar(x::GLBuffer{T}, buff_length::Int) where T + GLBuffer{T}(Ptr{T}(C_NULL), buff_length, x.buffertype, x.usage) +end + +cardinality(::GLBuffer{T}) where {T} = cardinality(T) + +#Function to deal with any Immutable type with Real as Subtype +function GLBuffer( + buffer::Union{Base.ReinterpretArray{T, 1}, DenseVector{T}}; + buffertype::GLenum = GL_ARRAY_BUFFER, usage::GLenum = GL_STATIC_DRAW + ) where T <: GLArrayEltypes + GLBuffer{T}(pointer(buffer), length(buffer), buffertype, usage) +end + +function GLBuffer( + buffer::DenseVector{T}; + buffertype::GLenum = GL_ARRAY_BUFFER, usage::GLenum = GL_STATIC_DRAW + ) where T <: GLArrayEltypes + GLBuffer{T}(pointer(buffer), length(buffer), buffertype, usage) +end + +function GLBuffer( + buffer::AbstractVector{T}; + kw_args... + ) where T <: GLArrayEltypes + GLBuffer(collect(buffer); kw_args...) +end + +function GLBuffer{T}( + buffer::AbstractVector; + kw_args... + ) where T <: GLArrayEltypes + GLBuffer(convert(Vector{T}, buffer); kw_args...) +end + +function GLBuffer( + ::Type{T}, len::Int; + buffertype::GLenum = GL_ARRAY_BUFFER, usage::GLenum = GL_STATIC_DRAW + ) where T <: GLArrayEltypes + GLBuffer{T}(Ptr{T}(C_NULL), len, buffertype, usage) +end + + +function indexbuffer( + buffer::VectorTypes{T}; + usage::GLenum = GL_STATIC_DRAW + ) where T <: GLArrayEltypes + GLBuffer(buffer, buffertype = GL_ELEMENT_ARRAY_BUFFER, usage=usage) +end +# GPUArray interface +function gpu_data(b::GLBuffer{T}) where T + data = Vector{T}(undef, length(b)) + bind(b) + glGetBufferSubData(b.buffertype, 0, sizeof(data), data) + bind(b, 0) + data +end + + +# Resize buffer +function gpu_resize!(buffer::GLBuffer{T}, newdims::NTuple{1, Int}) where T + #TODO make this safe! + newlength = newdims[1] + oldlen = length(buffer) + if oldlen > 0 + old_data = gpu_data(buffer) + end + bind(buffer) + glBufferData(buffer.buffertype, newlength*sizeof(T), C_NULL, buffer.usage) + bind(buffer, 0) + buffer.size = newdims + if oldlen>0 + max_len = min(length(old_data), newlength) #might also shrink + buffer[1:max_len] = old_data[1:max_len] + end + #probably faster, but changes the buffer ID + # newbuff = similar(buffer, newdims...) + # unsafe_copy!(buffer, 1, newbuff, 1, length(buffer)) + # buffer.id = newbuff.id + # buffer.size = newbuff.size + nothing +end + + + +function gpu_setindex!(b::GLBuffer{T}, value::Vector{T}, offset::Integer) where T + multiplicator = sizeof(T) + bind(b) + glBufferSubData(b.buffertype, multiplicator*(offset-1), sizeof(value), value) + bind(b, 0) +end +function gpu_setindex!(b::GLBuffer{T}, value::Vector{T}, offset::UnitRange{Int}) where T + multiplicator = sizeof(T) + bind(b) + glBufferSubData(b.buffertype, multiplicator*(first(offset)-1), sizeof(value), value) + bind(b, 0) + return nothing +end + +# copy between two buffers +# could be a setindex! operation, with subarrays for buffers +function unsafe_copy!(a::GLBuffer{T}, readoffset::Int, b::GLBuffer{T}, writeoffset::Int, len::Int) where T + multiplicator = sizeof(T) + glBindBuffer(GL_COPY_READ_BUFFER, a.id) + glBindBuffer(GL_COPY_WRITE_BUFFER, b.id) + glCopyBufferSubData( + GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, + multiplicator*(readoffset-1), + multiplicator*(writeoffset-1), + multiplicator*len + ) + glBindBuffer(GL_COPY_READ_BUFFER, 0) + glBindBuffer(GL_COPY_WRITE_BUFFER, 0) + return nothing +end + +function Base.iterate(buffer::GLBuffer{T}) where T + length(buffer) < 1 && return nothing + glBindBuffer(buffer.buffertype, buffer.id) + ptr = Ptr{T}(glMapBuffer(buffer.buffertype, GL_READ_WRITE)) + (unsafe_load(ptr, i), (ptr, 1)) +end +function Base.iterate(buffer::GLBuffer{T}, state::Tuple{Ptr{T}, Int}) where T + ptr, i = state + if i > length(buffer) + glUnmapBuffer(buffer.buffertype) + return nothing + end + val = unsafe_load(ptr, i) + (val, (ptr, i + 1)) +end + + +#copy inside one buffer +function unsafe_copy!(buffer::GLBuffer{T}, readoffset::Int, writeoffset::Int, len::Int) where T + len <= 0 && return nothing + bind(buffer) + ptr = Ptr{T}(glMapBuffer(buffer.buffertype, GL_READ_WRITE)) + for i=1:len+1 + unsafe_store!(ptr, unsafe_load(ptr, i+readoffset-1), i+writeoffset-1) + end + glUnmapBuffer(buffer.buffertype) + bind(buffer,0) + return nothing +end +function unsafe_copy!(a::Vector{T}, readoffset::Int, b::GLBuffer{T}, writeoffset::Int, len::Int) where T + bind(b) + ptr = Ptr{T}(glMapBuffer(b.buffertype, GL_WRITE_ONLY)) + for i=1:len + unsafe_store!(ptr, a[i+readoffset-1], i+writeoffset-1) + end + glUnmapBuffer(b.buffertype) + bind(b,0) +end +function unsafe_copy!(a::GLBuffer{T}, readoffset::Int, b::Vector{T}, writeoffset::Int, len::Int) where T + bind(a) + ptr = Ptr{T}(glMapBuffer(a.buffertype, GL_READ_ONLY)) + for i in 1:len + b[i+writeoffset-1] = unsafe_load(ptr, i+readoffset-2) #-2 => -1 to zero offset, -1 gl indexing starts at 0 + end + glUnmapBuffer(a.buffertype) + bind(a,0) +end + +function gpu_getindex(b::GLBuffer{T}, range::UnitRange) where T + multiplicator = sizeof(T) + offset = first(range)-1 + value = Vector{T}(undef, length(range)) + bind(b) + glGetBufferSubData(b.buffertype, multiplicator*offset, sizeof(value), value) + bind(b, 0) + value +end diff --git a/src/GLAbstraction/GLExtendedFunctions.jl b/src/GLAbstraction/GLExtendedFunctions.jl new file mode 100644 index 00000000000..102449022d9 --- /dev/null +++ b/src/GLAbstraction/GLExtendedFunctions.jl @@ -0,0 +1,231 @@ +#= +This is the place, where I put functions, which are so annoying in OpenGL, that I felt the need to wrap them and make them more "Julian" +Its also to do some more complex error handling, not handled by the debug callback +=# + +function glGetShaderiv(shaderID::GLuint, variable::GLenum) + result = Ref{GLint}(-1) + glGetShaderiv(shaderID, variable, result) + result[] +end +function glShaderSource(shaderID::GLuint, shadercode::Vector{UInt8}) + shader_code_ptrs = Ptr{UInt8}[pointer(shadercode)] + len = Ref{GLint}(length(shadercode)) + glShaderSource(shaderID, 1, shader_code_ptrs, len) +end +glShaderSource(shaderID::GLuint, shadercode::String) = glShaderSource(shaderID, Vector{UInt8}(shadercode)) +function glGetAttachedShaders(program::GLuint) + shader_count = glGetProgramiv(program, GL_ATTACHED_SHADERS) + length_written = GLsizei[0] + shaders = zeros(GLuint, shader_count) + + glGetAttachedShaders(program, shader_count, length_written, shaders) + shaders[1:first(length_written)] +end + +get_attribute_location(program::GLuint, name) = get_attribute_location(program, ascii(name)) +get_attribute_location(program::GLuint, name::Symbol) = get_attribute_location(program, string(name)) +function get_attribute_location(program::GLuint, name::String) + location::GLint = glGetAttribLocation(program, name) + if location == -1 + # warn( + # "Named attribute (:$(name)) is not an active attribute in the specified program object or\n + # the name starts with the reserved prefix gl_\n" + # ) + elseif location == GL_INVALID_OPERATION + error( + "program is not a value generated by OpenGL or\n + program is not a program object or\n + program has not been successfully linked" + ) + end + location +end + + +get_uniform_location(program::GLuint, name::Symbol) = get_uniform_location(program, String(name)) +function get_uniform_location(program::GLuint, name::String) + location = glGetUniformLocation(program, name) + if location == -1 + error( + """Named uniform (:$(name)) is not an active attribute in the specified program object or + the name starts with the reserved prefix gl_""" + ) + elseif location == GL_INVALID_OPERATION + error("""program is not a value generated by OpenGL or + program is not a program object or + program has not been successfully linked""" + ) + end + location +end + +function glGetActiveUniform(programID::GLuint, index::Integer) + actualLength = GLsizei[1] + uniformSize = GLint[1] + typ = GLenum[1] + maxcharsize = glGetProgramiv(programID, GL_ACTIVE_UNIFORM_MAX_LENGTH) + name = Vector{GLchar}(undef, maxcharsize) + + glGetActiveUniform(programID, index, maxcharsize, actualLength, uniformSize, typ, name) + + actualLength[1] <= 0 && error("No active uniform at given index. Index: ", index) + + uname = unsafe_string(pointer(name), actualLength[1]) + uname = Symbol(replace(uname, r"\[\d*\]" => "")) # replace array brackets. This is not really a good solution. + (uname, typ[1], uniformSize[1]) +end +function glGetActiveAttrib(programID::GLuint, index::Integer) + actualLength = GLsizei[1] + attributeSize = GLint[1] + typ = GLenum[1] + maxcharsize = glGetProgramiv(programID, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH) + name = Vector{GLchar}(undef, maxcharsize) + + glGetActiveAttrib(programID, index, maxcharsize, actualLength, attributeSize, typ, name) + + actualLength[1] <= 0 && error("No active uniform at given index. Index: ", index) + + uname = unsafe_string(pointer(name), actualLength[1]) + uname = Symbol(replace(uname, r"\[\d*\]" => "")) # replace array brackets. This is not really a good solution. + (uname, typ[1], attributeSize[1]) +end +function glGetProgramiv(programID::GLuint, variable::GLenum) + result = Ref{GLint}(-1) + glGetProgramiv(programID, variable, result) + result[] +end +function glGetIntegerv(variable::GLenum) + result = Ref{GLint}(-1) + glGetIntegerv(UInt32(variable), result) + result[] +end + + + + +function glGenBuffers(n=1) + result = GLuint[0] + glGenBuffers(1, result) + id = result[] + if id <= 0 + error("glGenBuffers returned invalid id. OpenGL Context active?") + end + id +end +function glGenVertexArrays() + result = GLuint[0] + glGenVertexArrays(1, result) + id = result[1] + if id <=0 + error("glGenVertexArrays returned invalid id. OpenGL Context active?") + end + id +end +function glGenTextures() + result = GLuint[0] + glGenTextures(1, result) + id = result[1] + if id <= 0 + error("glGenTextures returned invalid id. OpenGL Context active?") + end + id +end +function glGenFramebuffers() + result = GLuint[0] + glGenFramebuffers(1, result) + id = result[1] + if id <= 0 + error("glGenFramebuffers returned invalid id. OpenGL Context active?") + end + id +end + +function glDeleteTextures(id::GLuint) + arr = [id] + glDeleteTextures(1, arr) +end +function glDeleteVertexArrays(id::GLuint) + arr = [id] + glDeleteVertexArrays(1, arr) +end +function glDeleteBuffers(id::GLuint) + arr = [id] + glDeleteBuffers(1, arr) +end + +function glGetTexLevelParameteriv(target::GLenum, level, name::GLenum) + result = GLint[0] + glGetTexLevelParameteriv(target, level, name, result) + result[1] +end + +glViewport(x::SimpleRectangle) = glViewport(x.x, x.y, x.w, x.h) +glScissor(x::SimpleRectangle) = glScissor(x.x, x.y, x.w, x.h) + + +function glGenRenderbuffers(format::GLenum, attachment::GLenum, dimensions) + renderbuffer = GLuint[0] + glGenRenderbuffers(1, renderbuffer) + glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer[1]) + glRenderbufferStorage(GL_RENDERBUFFER, format, dimensions...) + glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, renderbuffer[1]) + renderbuffer[1] +end + + +function glTexImage(ttype::GLenum, level::Integer, internalFormat::GLenum, w::Integer, h::Integer, d::Integer, border::Integer, format::GLenum, datatype::GLenum, data) + glTexImage3D(GL_PROXY_TEXTURE_3D, level, internalFormat, w, h, d, border, format, datatype, C_NULL) + for l in 0:level + result = glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, l, GL_TEXTURE_WIDTH) + if result == 0 + error("glTexImage 3D: width too large. Width: ", w) + end + result = glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, l,GL_TEXTURE_HEIGHT) + if result == 0 + error("glTexImage 3D: height too large. height: ", h) + end + result = glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, l, GL_TEXTURE_DEPTH) + if result == 0 + error("glTexImage 3D: depth too large. Depth: ", d) + end + result = glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, l, GL_TEXTURE_INTERNAL_FORMAT) + if result == 0 + error("glTexImage 3D: internal format not valid. format: ", GLENUM(internalFormat).name) + end + end + glTexImage3D(ttype, level, internalFormat, w, h, d, border, format, datatype, data) +end +function glTexImage(ttype::GLenum, level::Integer, internalFormat::GLenum, w::Integer, h::Integer, border::Integer, format::GLenum, datatype::GLenum, data) + maxsize = glGetIntegerv(GL_MAX_TEXTURE_SIZE) + glTexImage2D(GL_PROXY_TEXTURE_2D, level, internalFormat, w, h, border, format, datatype, C_NULL) + for l in 0:level + result = glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, l, GL_TEXTURE_WIDTH) + if result == 0 + error("glTexImage 2D: width too large. Width: ", w) + end + result = glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, l, GL_TEXTURE_HEIGHT) + if result == 0 + error("glTexImage 2D: height too large. height: ", h) + end + result = glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, l, GL_TEXTURE_INTERNAL_FORMAT) + if result == 0 + error("glTexImage 2D: internal format not valid. format: ", GLENUM(internalFormat).name) + end + end + glTexImage2D(ttype, level, internalFormat, w, h, border, format, datatype, data) +end +function glTexImage(ttype::GLenum, level::Integer, internalFormat::GLenum, w::Integer, border::Integer, format::GLenum, datatype::GLenum, data) + glTexImage1D(GL_PROXY_TEXTURE_1D, level, internalFormat, w, border, format, datatype, C_NULL) + for l in 0:level + result = glGetTexLevelParameteriv(GL_PROXY_TEXTURE_1D, l, GL_TEXTURE_WIDTH) + if result == 0 + error("glTexImage 1D: width too large. Width: ", w) + end + result = glGetTexLevelParameteriv(GL_PROXY_TEXTURE_1D, l, GL_TEXTURE_INTERNAL_FORMAT) + if result == 0 + error("glTexImage 1D: internal format not valid. format: ", GLENUM(internalFormat).name) + end + end + glTexImage1D(ttype, level, internalFormat, w, border, format, datatype, data) +end diff --git a/src/GLAbstraction/GLInfo.jl b/src/GLAbstraction/GLInfo.jl new file mode 100644 index 00000000000..643be80a31a --- /dev/null +++ b/src/GLAbstraction/GLInfo.jl @@ -0,0 +1,127 @@ +getnames(check_function::Function) = filter(check_function, uint32(0:65534)) + +# gets all the names currently boundo to programs +getProgramNames() = getnames(glIsProgram) +getShaderNames() = getnames(glIsShader) +getVertexArrayNames() = getnames(glIsVertexArray) + +# display info for all active uniforms in a program +function getUniformsInfo(p::GLProgram) + program = p.id + # Get uniforms info (not in named blocks) + @show activeUnif = glGetProgramiv(program, GL_ACTIVE_UNIFORMS) + + for i=0:activeUnif-1 + @show index = glGetActiveUniformsiv(program, i, GL_UNIFORM_BLOCK_INDEX) + if (index == -1) + @show name = glGetActiveUniformName(program, i) + @show uniType = glGetActiveUniformsiv(program, i, GL_UNIFORM_TYPE) + + @show uniSize = glGetActiveUniformsiv(program, i, GL_UNIFORM_SIZE) + @show uniArrayStride = glGetActiveUniformsiv(program, i, GL_UNIFORM_ARRAY_STRIDE) + + auxSize = 0 + if (uniArrayStride > 0) + @show auxSize = uniArrayStride * uniSize + else + @show auxSize = spGLSLTypeSize[uniType] + end + end + end + # Get named blocks info + @show count = glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS) + + for i=0:count-1 + # Get blocks name + @show name = glGetActiveUniformBlockName(program, i) + @show dataSize = glGetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_DATA_SIZE) + + @show index = glGetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_BINDING) + @show binding_point = glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, index) + + @show activeUnif = glGetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS) + + indices = zeros(GLuint, activeUnif) + glGetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, indices) + @show indices + for ubindex in indices + @show name = glGetActiveUniformName(program, ubindex) + @show uniType = glGetActiveUniformsiv(program, ubindex, GL_UNIFORM_TYPE) + @show uniOffset = glGetActiveUniformsiv(program, ubindex, GL_UNIFORM_OFFSET) + @show uniSize = glGetActiveUniformsiv(program, ubindex, GL_UNIFORM_SIZE) + @show uniMatStride = glGetActiveUniformsiv(program, ubindex, GL_UNIFORM_MATRIX_STRIDE) + end + end +end + + +# display the values for uniforms in the default block +function getUniformInfo(p::GLProgram, uniName::Symbol) + # is it a program ? + @show program = p.id + @show loc = glGetUniformLocation(program, uniName) + @show name, typ, uniform_size = glGetActiveUniform(program, loc) +end + + +# display the values for a uniform in a named block +function getUniformInBlockInfo(p::GLProgram, + blockName, + uniName) + + program = p.id + + @show index = glGetUniformBlockIndex(program, blockName) + if (index == GL_INVALID_INDEX) + println("$uniName is not a valid uniform name in block $blockName") + end + @show bindIndex = glGetActiveUniformBlockiv(program, index, GL_UNIFORM_BLOCK_BINDING) + @show bufferIndex = glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, bindIndex) + @show uniIndex = glGetUniformIndices(program, uniName) + + @show uniType = glGetActiveUniformsiv(program, uniIndex, GL_UNIFORM_TYPE) + @show uniOffset = glGetActiveUniformsiv(program, uniIndex, GL_UNIFORM_OFFSET) + @show uniSize = glGetActiveUniformsiv(program, uniIndex, GL_UNIFORM_SIZE) + @show uniArrayStride = glGetActiveUniformsiv(program, uniIndex, GL_UNIFORM_ARRAY_STRIDE) + @show uniMatStride = glGetActiveUniformsiv(program, uniIndex, GL_UNIFORM_MATRIX_STRIDE) +end + + +# display information for a program's attributes +function getAttributesInfo(p::GLProgram) + + program = p.id + # how many attribs? + @show activeAttr = glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES) + # get location and type for each attrib + for i=0:activeAttr-1 + @show name, typ, siz = glGetActiveAttrib(program, i) + @show loc = glGetAttribLocation(program, name) + end +end + + +# display program's information +function getProgramInfo(p::GLProgram) + # check if name is really a program + @show program = p.id + # Get the shader's name + @show shaders = glGetAttachedShaders(program) + for shader in shaders + @show info = GLENUM(convert(GLenum, glGetShaderiv(shader, GL_SHADER_TYPE))).name + end + # Get program info + @show info = glGetProgramiv(program, GL_PROGRAM_SEPARABLE) + @show info = glGetProgramiv(program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT) + @show info = glGetProgramiv(program, GL_LINK_STATUS) + @show info = glGetProgramiv(program, GL_VALIDATE_STATUS) + @show info = glGetProgramiv(program, GL_DELETE_STATUS) + @show info = glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES) + @show info = glGetProgramiv(program, GL_ACTIVE_UNIFORMS) + @show info = glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS) + @show info = glGetProgramiv(program, GL_ACTIVE_ATOMIC_COUNTER_BUFFERS) + @show info = glGetProgramiv(program, GL_TRANSFORM_FEEDBACK_BUFFER_MODE) + @show info = glGetProgramiv(program, GL_TRANSFORM_FEEDBACK_VARYINGS) +end + + diff --git a/src/GLAbstraction/GLRender.jl b/src/GLAbstraction/GLRender.jl new file mode 100644 index 00000000000..6e8b6e670cd --- /dev/null +++ b/src/GLAbstraction/GLRender.jl @@ -0,0 +1,155 @@ +function render(list::Tuple) + for elem in list + render(elem) + end + return +end +""" +When rendering a specialised list of Renderables, we can do some optimizations +""" +function render(list::Vector{RenderObject{Pre}}) where Pre + isempty(list) && return nothing + first(list).prerenderfunction() + vertexarray = first(list).vertexarray + program = vertexarray.program + glUseProgram(program.id) + glBindVertexArray(vertexarray.id) + for renderobject in list + Bool(to_value(renderobject.uniforms[:visible])) || continue # skip invisible + # make sure we only bind new programs and vertexarray when it is actually + # different from the previous one + if renderobject.vertexarray != vertexarray + vertexarray = renderobject.vertexarray + if vertexarray.program != program + program = renderobject.vertexarray.program + glUseProgram(program.id) + end + glBindVertexArray(vertexarray.id) + end + for (key,value) in program.uniformloc + if haskey(renderobject.uniforms, key) + if length(value) == 1 + gluniform(value[1], renderobject.uniforms[key]) + elseif length(value) == 2 + gluniform(value[1], value[2], renderobject.uniforms[key]) + else + error("Uniform tuple too long: $(length(value))") + end + end + end + renderobject.postrenderfunction() + end + # we need to assume, that we're done here, which is why + # we need to bind VertexArray to 0. + # Otherwise, every glBind(::GLBuffer) operation will be recorded into the state + # of the currently bound vertexarray + glBindVertexArray(0) + return +end + +""" +Renders a RenderObject +Note, that this function is not optimized at all! +It uses dictionaries and doesn't care about OpenGL call optimizations. +So rewriting this function could get us a lot of performance for scenes with +a lot of objects. +""" +function render(renderobject::RenderObject, vertexarray = renderobject.vertexarray) + if Bool(to_value(renderobject.uniforms[:visible])) + renderobject.prerenderfunction() + program = vertexarray.program + glUseProgram(program.id) + for (key, value) in program.uniformloc + if haskey(renderobject.uniforms, key) + if length(value) == 1 + gluniform(value[1], renderobject.uniforms[key]) + elseif length(value) == 2 + gluniform(value[1], value[2], renderobject.uniforms[key]) + else + error("Uniform tuple too long: $(length(value))") + end + end + end + glBindVertexArray(vertexarray.id) + renderobject.postrenderfunction() + glBindVertexArray(0) + end + return +end + + +""" +Renders a vertexarray, which consists of the usual buffers plus a vector of +unitranges which defines the segments of the buffers to be rendered +""" +function render(vao::GLVertexArray{T}, mode::GLenum = GL_TRIANGLES) where T <: VecOrSignal{UnitRange{Int}} + for elem in to_value(vao.indices) + glDrawArrays(mode, max(first(elem)-1, 0), length(elem)+1) + end + return nothing +end + +function render(vao::GLVertexArray{T}, mode::GLenum = GL_TRIANGLES) where T <: TOrSignal{UnitRange{Int}} + r = to_value(vao.indices) + glDrawArrays(mode, max(first(r)-1, 0), length(r)+1) + return nothing +end +function render(vao::GLVertexArray{T}, mode::GLenum = GL_TRIANGLES) where T <: TOrSignal{Int} + r = to_value(vao.indices) + glDrawArrays(mode, 0, r) + return nothing +end + + + +""" +Renders a vertex array which supplies an indexbuffer +""" +function render(vao::GLVertexArray{GLBuffer{T}}, mode::GLenum=GL_TRIANGLES) where T<:Union{Integer, Face} + glDrawElements( + mode, + length(vao.indices) * cardinality(vao.indices), + julia2glenum(T), C_NULL + ) + return +end +""" +Renders a normal vertex array only containing the usual buffers buffers. +""" +function render(vao::GLVertexArray, mode::GLenum=GL_TRIANGLES) + glDrawArrays(mode, 0, length(vao)) + return +end + +""" +Render instanced geometry +""" +renderinstanced(vao::GLVertexArray, a, primitive=GL_TRIANGLES) = renderinstanced(vao, length(a), primitive) + +""" +Renders `amount` instances of an indexed geometry +""" +function renderinstanced(vao::GLVertexArray{GLBuffer{T}}, amount::Integer, primitive=GL_TRIANGLES) where T<:Union{Integer, Face} + glDrawElementsInstanced(primitive, length(vao.indices)*cardinality(vao.indices), julia2glenum(T), C_NULL, amount) + return +end +""" +Renders `amount` instances of an not indexed geoemtry geometry +""" +function renderinstanced(vao::GLVertexArray, amount::Integer, primitive=GL_TRIANGLES) + glDrawElementsInstanced(primitive, length(vao), GL_UNSIGNED_INT, C_NULL, amount) + return +end +#handle all uniform objects + + + +############################################################################################## +# Generic render functions +##### +function enabletransparency() + glEnablei(GL_BLEND, 0) + glDisablei(GL_BLEND, 1) + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) + return +end diff --git a/src/GLAbstraction/GLRenderObject.jl b/src/GLAbstraction/GLRenderObject.jl new file mode 100644 index 00000000000..f744545790b --- /dev/null +++ b/src/GLAbstraction/GLRenderObject.jl @@ -0,0 +1,203 @@ +function RenderObject( + data::Dict{Symbol}, program, pre, + bbs = Node(AABB{Float32}(Vec3f0(0),Vec3f0(1))), + main = nothing + ) + RenderObject(convert(Dict{Symbol,Any}, data), program, pre, bbs, main) +end + +function Base.show(io::IO, obj::RenderObject) + println(io, "RenderObject with ID: ", obj.id) +end + + +Base.getindex(obj::RenderObject, symbol::Symbol) = obj.uniforms[symbol] +Base.setindex!(obj::RenderObject, value, symbol::Symbol) = obj.uniforms[symbol] = value + +Base.getindex(obj::RenderObject, symbol::Symbol, x::Function) = getindex(obj, Val(symbol), x) +Base.getindex(obj::RenderObject, ::Val{:prerender}, x::Function) = obj.prerenderfunctions[x] +Base.getindex(obj::RenderObject, ::Val{:postrender}, x::Function) = obj.postrenderfunctions[x] + +Base.setindex!(obj::RenderObject, value, symbol::Symbol, x::Function) = setindex!(obj, value, Val(symbol), x) +Base.setindex!(obj::RenderObject, value, ::Val{:prerender}, x::Function) = obj.prerenderfunctions[x] = value +Base.setindex!(obj::RenderObject, value, ::Val{:postrender}, x::Function) = obj.postrenderfunctions[x] = value + +const empty_signal = Node(false) +post_empty() = push!(empty_signal, false) + +""" +Function which sets an argument of a Context/RenderObject. +If multiple RenderObjects are supplied, it'll try to set the same argument in all +of them. +""" +function set_arg!(robj::RenderObject, sym, value) + current_val = robj[sym] + set_arg!(robj, sym, current_val, value) + # GLVisualize relies on reactives event system no for rendering + # so if a change should be visible there must be an event to indicate change + post_empty() + nothing +end +function set_arg!(robj::Context, sym, value) + set_arg!(robj.children, sym, value) + nothing +end +function set_arg!(robj::Vector, sym, value) + for elem in robj + set_arg!(elem, sym, value) + end + nothing +end + +function set_arg!(robj::RenderObject, sym, to_update::GPUArray, value) + update!(to_update, value) +end +function set_arg!(robj::RenderObject, sym, to_update, value) + robj[sym] = value +end +function set_arg!(robj::RenderObject, sym, to_update::Node, value::Node) + robj[sym] = value +end +function set_arg!(robj::RenderObject, sym, to_update::Node, value) + push!(to_update, value) +end + + +""" +Represents standard sets of function applied before rendering +""" +struct StandardPrerender + transparency::Node{Bool} + overdraw::Node{Bool} +end + +function (sp::StandardPrerender)() + if !sp.overdraw[] + glEnable(GL_DEPTH_TEST) + glDepthFunc(GL_LEQUAL) + else + glDisable(GL_DEPTH_TEST) + end + glDepthMask(sp.transparency[] ? GL_FALSE : GL_TRUE) + # Disable cullface for now, untill all rendering code is corrected! + glDisable(GL_CULL_FACE) + # glCullFace(GL_BACK) + enabletransparency() +end + +struct StandardPostrender + vao::GLVertexArray + primitive::GLenum +end +function (sp::StandardPostrender)() + render(sp.vao, sp.primitive) +end +struct StandardPostrenderInstanced{T} + main::T + vao::GLVertexArray + primitive::GLenum +end +function (sp::StandardPostrenderInstanced)() + renderinstanced(sp.vao, to_value(sp.main), sp.primitive) +end + +struct EmptyPrerender +end +function (sp::EmptyPrerender)() +end +export EmptyPrerender +export prerendertype + +function instanced_renderobject(data, program, bb = Node(AABB(Vec3f0(0), Vec3f0(1))), primitive::GLenum=GL_TRIANGLES, main=nothing) + pre = StandardPrerender() + robj = RenderObject(convert(Dict{Symbol,Any}, data), program, pre, nothing, bb, main) + robj.postrenderfunction = StandardPostrenderInstanced(main, robj.vertexarray, primitive) + robj +end + +function std_renderobject(data, program, bb = Node(AABB(Vec3f0(0), Vec3f0(1))), primitive=GL_TRIANGLES, main=nothing) + pre = StandardPrerender() + robj = RenderObject(convert(Dict{Symbol,Any}, data), program, pre, nothing, bb, main) + robj.postrenderfunction = StandardPostrender(robj.vertexarray, primitive) + robj +end + +prerendertype(::Type{RenderObject{Pre}}) where {Pre} = Pre +prerendertype(::RenderObject{Pre}) where {Pre} = Pre + +extract_renderable(context::Vector{RenderObject}) = context +extract_renderable(context::RenderObject) = RenderObject[context] +extract_renderable(context::Vector{T}) where {T <: Composable} = map(extract_renderable, context) +function extract_renderable(context::Context) + result = extract_renderable(context.children[1]) + for elem in context.children[2:end] + push!(result, extract_renderable(elem)...) + end + result +end +transformation(c::RenderObject) = c[:model] +function transformation(c::RenderObject, model) + c[:model] = const_lift(*, model, c[:model]) +end +function transform!(c::RenderObject, model) + c[:model] = const_lift(*, model, c[:model]) +end + +function _translate!(c::RenderObject, trans::TOrSignal{Mat4f0}) + c[:model] = const_lift(*, trans, c[:model]) +end +function _translate!(c::Context, m::TOrSignal{Mat4f0}) + for elem in c.children + _translate!(elem, m) + end +end + +function translate!(c::Composable, vec::TOrSignal{T}) where T <: Vec{3} + _translate!(c, const_lift(translationmatrix, vec)) +end +function _boundingbox(c::RenderObject) + bb = to_value(c[:boundingbox]) + bb == nothing && return AABB() + to_value(c[:model]) * bb +end +function _boundingbox(c::Composable) + robjs = extract_renderable(c) + isempty(robjs) && return AABB() + mapreduce(_boundingbox, union, robjs) +end +""" +Copy function for a context. We only need to copy the children +""" +function Base.copy(c::Context{T}) where T + new_children = [copy(child) for child in c.children] + Context{T}(new_children, c.boundingbox, c.transformation) +end + + +""" +Copy function for a RenderObject. We only copy the uniform dict +""" +function Base.copy(robj::RenderObject{Pre}) where Pre + uniforms = Dict{Symbol, Any}([(k,v) for (k,v) in robj.uniforms]) + robj = RenderObject{Pre}( + robj.main, + uniforms, + robj.vertexarray, + robj.prerenderfunction, + robj.postrenderfunction, + robj.boundingbox, + ) + Context(robj) +end + +# """ +# If you have an array of OptimizedPrograms, you only need to put PreRender in front. +# """ +# type OptimizedProgram{PreRender} +# program::GLProgram +# uniforms::FixedDict +# vertexarray::GLVertexArray +# gl_parameters::PreRender +# renderfunc::Callable +# visible::Boolean +# end diff --git a/src/GLAbstraction/GLShader.jl b/src/GLAbstraction/GLShader.jl new file mode 100644 index 00000000000..8329980ddee --- /dev/null +++ b/src/GLAbstraction/GLShader.jl @@ -0,0 +1,373 @@ +# Different shader string literals- usage: e.g. frag" my shader code" +macro frag_str(source::AbstractString) + quote + ($source, GL_FRAGMENT_SHADER) + end +end +macro vert_str(source::AbstractString) + quote + ($source, GL_VERTEX_SHADER) + end +end +macro geom_str(source::AbstractString) + quote + ($source, GL_GEOMETRY_SHADER) + end +end +macro comp_str(source::AbstractString) + quote + ($source, GL_COMPUTE_SHADER) + end +end + +function getinfolog(obj::GLuint) + # Return the info log for obj, whether it be a shader or a program. + isShader = glIsShader(obj) + getiv = isShader == GL_TRUE ? glGetShaderiv : glGetProgramiv + get_log = isShader == GL_TRUE ? glGetShaderInfoLog : glGetProgramInfoLog + + # Get the maximum possible length for the descriptive error message + maxlength = GLint[0] + getiv(obj, GL_INFO_LOG_LENGTH, maxlength) + maxlength = first(maxlength) + # Return the text of the message if there is any + if maxlength > 0 + buffer = zeros(GLchar, maxlength) + sizei = GLsizei[0] + get_log(obj, maxlength, sizei, buffer) + length = first(sizei) + return unsafe_string(pointer(buffer), length) + else + return "success" + end +end + +function iscompiled(shader::GLuint) + success = GLint[0] + glGetShaderiv(shader, GL_COMPILE_STATUS, success) + return first(success) == GL_TRUE +end +islinked(program::GLuint) = glGetProgramiv(program, GL_LINK_STATUS) == GL_TRUE + +function createshader(shadertype::GLenum) + shaderid = glCreateShader(shadertype) + @assert shaderid > 0 "opengl context is not active or shader type not accepted. Shadertype: $(GLENUM(shadertype).name)" + shaderid::GLuint +end +function createprogram() + program = glCreateProgram() + @assert program > 0 "couldn't create program. Most likely, opengl context is not active" + program::GLuint +end + +shadertype(s::Shader) = s.typ +function shadertype(f::File{format"GLSLShader"}) + shadertype(file_extension(f)) +end +function shadertype(ext::AbstractString) + ext == ".comp" && return GL_COMPUTE_SHADER + ext == ".vert" && return GL_VERTEX_SHADER + ext == ".frag" && return GL_FRAGMENT_SHADER + ext == ".geom" && return GL_GEOMETRY_SHADER + error("$ext not a valid extension for $f") +end + +#Implement File IO interface +function load(f::File{format"GLSLShader"}) + fname = filename(f) + source = open(readstring, fname) + compile_shader(fname, source) +end +function save(f::File{format"GLSLShader"}, data::Shader) + s = open(f, "w") + write(s, data.source) + close(s) +end + +function uniformlocations(nametypedict::Dict{Symbol, GLenum}, program) + result = Dict{Symbol, Tuple}() + texturetarget = -1 # start -1, as texture samplers start at 0 + for (name, typ) in nametypedict + loc = get_uniform_location(program, name) + str_name = string(name) + if istexturesampler(typ) + texturetarget += 1 + result[name] = (loc, texturetarget) + else + result[name] = (loc,) + end + end + return result +end + +abstract type AbstractLazyShader end +struct LazyShader <: AbstractLazyShader + paths::Tuple + kw_args::Dict{Symbol, Any} + function LazyShader(paths...; kw_args...) + args = Dict{Symbol, Any}(kw_args) + get!(args, :view, Dict{String, String}()) + new(paths, args) + end +end + +gl_convert(shader::GLProgram, data) = shader + + + + +# caching templated shaders is a pain -.- + +# cache for template keys per file +# path --> template keys +const _template_cache = Dict{String, Vector{String}}() +# path --> Dict{template_replacements --> Shader) +const _shader_cache = Dict{String, Dict{Any, Shader}}() +const _program_cache = Dict{Any, GLProgram}() + + +function empty_shader_cache!() + empty!(_template_cache) + empty!(_shader_cache) + empty!(_program_cache) +end + +# TODO remove this silly constructor +function compile_shader(source::Vector{UInt8}, typ, name) + shaderid = createshader(typ) + glShaderSource(shaderid, source) + glCompileShader(shaderid) + if !GLAbstraction.iscompiled(shaderid) + GLAbstraction.print_with_lines(String(source)) + @warn("shader $(name) didn't compile. \n$(GLAbstraction.getinfolog(shaderid))") + end + Shader(name, source, typ, shaderid) +end + +function compile_shader(path, source_str::AbstractString) + typ = GLAbstraction.shadertype(query(path)) + source = Vector{UInt8}(source_str) + name = Symbol(path) + compile_shader(source, typ, name) +end + +function get_shader!(path, template_replacement, view, attributes) + # this should always be in here, since we already have the template keys + shader_dict = _shader_cache[path] + get!(shader_dict, template_replacement) do + template_source = read(path, String) + source = mustache_replace(template_replacement, template_source) + compile_shader(path, source) + end::Shader +end +function get_template!(path, view, attributes) + get!(_template_cache, path) do + _, ext = splitext(path) + + typ = shadertype(ext) + template_source = read(path, String) + source, replacements = template2source( + template_source, view, attributes + ) + s = compile_shader(path, source) + template_keys = collect(keys(replacements)) + template_replacements = collect(values(replacements)) + # can't yet be in here, since we didn't even have template keys + _shader_cache[path] = Dict(template_replacements => s) + + template_keys + end +end + + +function compile_program(shaders, fragdatalocation) + # Remove old shaders + program = createprogram() + #attach new ones + foreach(shaders) do shader + glAttachShader(program, shader.id) + end + + #Bind frag data + for (location, name) in fragdatalocation + glBindFragDataLocation(program, location, ascii(name)) + end + + #link program + glLinkProgram(program) + if !GLAbstraction.islinked(program) + error( + "program $program not linked. Error in: \n", + join(map(x-> string(x.name), shaders), " or "), "\n", getinfolog(program) + ) + end + # Can be deleted, as they will still be linked to Program and released after program gets released + #foreach(glDeleteShader, shader_ids) + # generate the link locations + nametypedict = uniform_name_type(program) + uniformlocationdict = uniformlocations(nametypedict, program) + GLProgram(program, shaders, nametypedict, uniformlocationdict) +end + +function get_view(kw_dict) + _view = kw_dict[:view] + extension = Sys.isapple() ? "" : "#extension GL_ARB_draw_instanced : enable\n" + _view["GLSL_EXTENSION"] = extension*get(_view, "GLSL_EXTENSIONS", "") + _view["GLSL_VERSION"] = glsl_version_string() + _view +end + +function gl_convert(lazyshader::AbstractLazyShader, data) + kw_dict = lazyshader.kw_args + paths = lazyshader.paths + if all(x-> isa(x, Shader), paths) + fragdatalocation = get(kw_dict, :fragdatalocation, Tuple{Int, String}[]) + return compile_program([paths...], fragdatalocation) + end + v = get_view(kw_dict) + fragdatalocation = get(kw_dict, :fragdatalocation, Tuple{Int, String}[]) + + # Tuple(Source, ShaderType) + if all(paths) do x + isa(x, Tuple) && length(x) == 2 && + isa(first(x), String) && + isa(last(x), GLenum) + end + # we don't cache view & templates for shader strings! + shaders = map(paths) do source_typ + source, typ = source_typ + src, _ = template2source(source, v, data) + compile_shader(Vector{UInt8}(src), typ, :from_string) + end + return compile_program([shaders...], fragdatalocation) + end + if !all(x-> isa(x, String), paths) + error("Please supply only paths or tuples of (source, typ) for Lazy Shader + Found: $paths" + ) + end + template_keys = Vector{Vector{String}}(undef, length(paths)) + replacements = Vector{Vector{String}}(undef, length(paths)) + for (i, path) in enumerate(paths) + template = get_template!(path, v, data) + template_keys[i] = template + replacements[i] = String[mustache2replacement(t, v, data) for t in template] + end + program = get!(_program_cache, (paths, replacements)) do + # when we're here, this means there were uncached shaders, meaning we definitely have + # to compile a new program + shaders = Vector{Shader}(undef, length(paths)) + for (i, path) in enumerate(paths) + tr = Dict(zip(template_keys[i], replacements[i])) + shaders[i] = get_shader!(path, tr, v, data) + end + compile_program(shaders, fragdatalocation) + end +end + + +function insert_from_view(io, replace_view::Function, keyword::AbstractString) + print(io, replace_view(keyword)) + nothing +end + +function insert_from_view(io, replace_view::Dict, keyword::AbstractString) + if haskey(replace_view, keyword) + print(io, replace_view[keyword]) + end + nothing +end +""" +Replaces +{{keyword}} with the key in `replace_view`, or replace_view(key) +in a string +""" +function mustache_replace(replace_view::Union{Dict, Function}, string) + io = IOBuffer() + replace_started = false + open_mustaches = 0 + closed_mustaches = 0 + i = 0 + replace_begin = i + last_char = SubString(string, 1, 1) + len = lastindex(string) + while i <= len + i = nextind(string, i) + i > len && break + char = string[i] + if replace_started + # ignore, or wait for } + if char == '}' + closed_mustaches += 1 + if closed_mustaches == 2 # we found a complete mustache! + insert_from_view(io, replace_view, SubString(string, replace_begin+1, i-2)) + open_mustaches = 0 + closed_mustaches = 0 + replace_started = false + end + else + closed_mustaches = 0 + continue + end + elseif char == '{' + open_mustaches += 1 + if open_mustaches == 2 + replace_begin = i + replace_started = true + end + else + if open_mustaches == 1 + print(io, last_char) + end + print(io, char) # just copy all the rest + open_mustaches = 0 + closed_mustaches = 0 + end + last_char = char + end + String(take!(io)) +end + + +function mustache2replacement(mustache_key, view, attributes) + haskey(view, mustache_key) && return view[mustache_key] + for postfix in ("_type", "_calculation") + keystring = replace(mustache_key, postfix => "") + keysym = Symbol(keystring) + if haskey(attributes, keysym) + val = attributes[keysym] + if !isa(val, AbstractString) + return if postfix == "_type" + toglsltype_string(val)::String + else postfix == "_calculation" + glsl_variable_access(keystring, val)::String + end + end + end + end + "" # no match found, leave empty! +end + +# Takes a shader template and renders the template and returns shader source +template2source(source::Vector{UInt8}, view, attributes::Dict{Symbol, Any}) = template2source(String(source), attributes, view) +function template2source(source::AbstractString, view, attributes::Dict{Symbol, Any}) + replacements = Dict{String, String}() + source = mustache_replace(source) do mustache_key + r = mustache2replacement(mustache_key, view, attributes) + replacements[mustache_key] = r + r + end + source, replacements +end + +function glsl_version_string() + glsl = split(unsafe_string(glGetString(GL_SHADING_LANGUAGE_VERSION)), ['.', ' ']) + if length(glsl) >= 2 + glsl = VersionNumber(parse(Int, glsl[1]), parse(Int, glsl[2])) + glsl.major == 1 && glsl.minor <= 2 && error("OpenGL shading Language version too low. Try updating graphic driver!") + glsl_version = string(glsl.major) * rpad(string(glsl.minor),2,"0") + return "#version $(glsl_version)\n" + else + error("could not parse GLSL version: $glsl") + end +end diff --git a/src/GLAbstraction/GLTexture.jl b/src/GLAbstraction/GLTexture.jl new file mode 100644 index 00000000000..66eec669c44 --- /dev/null +++ b/src/GLAbstraction/GLTexture.jl @@ -0,0 +1,513 @@ +struct TextureParameters{NDim} + minfilter::Symbol + magfilter::Symbol # magnification + repeat ::NTuple{NDim, Symbol} + anisotropic::Float32 + swizzle_mask::Vector{GLenum} +end + +abstract type OpenglTexture{T, NDIM} <: GPUArray{T, NDIM} end + +mutable struct Texture{T <: GLArrayEltypes, NDIM} <: OpenglTexture{T, NDIM} + id ::GLuint + texturetype ::GLenum + pixeltype ::GLenum + internalformat ::GLenum + format ::GLenum + parameters ::TextureParameters{NDIM} + size ::NTuple{NDIM, Int} + context ::GLContext + function Texture{T, NDIM}( + id ::GLuint, + texturetype ::GLenum, + pixeltype ::GLenum, + internalformat ::GLenum, + format ::GLenum, + parameters ::TextureParameters{NDIM}, + size ::NTuple{NDIM, Int} + ) where {T, NDIM} + tex = new( + id, + texturetype, + pixeltype, + internalformat, + format, + parameters, + size, + current_context() + ) + finalizer(free, tex) + tex + end +end + +# for bufferSampler, aka Texture Buffer +mutable struct TextureBuffer{T <: GLArrayEltypes} <: OpenglTexture{T, 1} + texture::Texture{T, 1} + buffer::GLBuffer{T} +end +Base.size(t::TextureBuffer) = size(t.buffer) +Base.size(t::TextureBuffer, i::Integer) = size(t.buffer, i) +Base.length(t::TextureBuffer) = length(t.buffer) +bind(t::Texture) = glBindTexture(t.texturetype, t.id) +bind(t::Texture, id) = glBindTexture(t.texturetype, id) + +is_texturearray(t::Texture) = t.texturetype == GL_TEXTURE_2D_ARRAY +is_texturebuffer(t::Texture) = t.texturetype == GL_TEXTURE_BUFFER + +colordim(::Type{T}) where {T} = cardinality(T) +colordim(::Type{T}) where {T <: Real} = 1 + +function set_packing_alignment(a) # at some point we should specialize to array/ptr a + glPixelStorei(GL_UNPACK_ALIGNMENT, 1) + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0) + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0) + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0) +end + + +function Texture( + data::Ptr{T}, dims::NTuple{NDim, Int}; + internalformat::GLenum = default_internalcolorformat(T), + texturetype ::GLenum = default_texturetype(NDim), + format ::GLenum = default_colorformat(T), + mipmap = false, + parameters... # rest should be texture parameters + ) where {T, NDim} + texparams = TextureParameters(T, NDim; parameters...) + id = glGenTextures() + glBindTexture(texturetype, id) + set_packing_alignment(data) + numbertype = julia2glenum(eltype(T)) + glTexImage(texturetype, 0, internalformat, dims..., 0, format, numbertype, data) + mipmap && glGenerateMipmap(texturetype) + texture = Texture{T, NDim}( + id, texturetype, numbertype, internalformat, format, + texparams, + dims + ) + set_parameters(texture) + texture::Texture{T, NDim} +end +export resize_nocopy! +function resize_nocopy!(t::Texture{T, ND}, newdims::NTuple{ND, Int}) where {T, ND} + bind(t) + glTexImage(t.texturetype, 0, t.internalformat, newdims..., 0, t.format, t.pixeltype, C_NULL) + t.size = newdims + bind(t, 0) + t +end + +""" +Constructor for empty initialization with NULL pointer instead of an array with data. +You just need to pass the wanted color/vector type and the dimensions. +To which values the texture gets initialized is driver dependent +""" +Texture(::Type{T}, dims::NTuple{N, Int}; kw_args...) where {T <: GLArrayEltypes, N} = + Texture(convert(Ptr{T}, C_NULL), dims; kw_args...)::Texture{T, N} + +""" +Constructor for a normal array, with color or Abstract Arrays as elements. +So Array{Real, 2} == Texture2D with 1D Colorant dimension +Array{Vec1/2/3/4, 2} == Texture2D with 1/2/3/4D Colorant dimension +Colors from Colors.jl should mostly work as well +""" +Texture(image::Array{T, NDim}; kw_args...) where {T <: GLArrayEltypes, NDim} = + Texture(pointer(image), size(image); kw_args...)::Texture{T, NDim} + +""" +Constructor for Array Texture +""" +function Texture( + data::Vector{Array{T, 2}}; + internalformat::GLenum = default_internalcolorformat(T), + texturetype::GLenum = GL_TEXTURE_2D_ARRAY, + format::GLenum = default_colorformat(T), + parameters... + ) where T <: GLArrayEltypes + texparams = TextureParameters(T, 2; parameters...) + id = glGenTextures() + + glBindTexture(texturetype, id) + + numbertype = julia2glenum(eltype(T)) + + layers = length(data) + dims = map(size, data) + maxdims = foldl(dims, init = (0,0)) do v0, x + a = max(v0[1], x[1]) + b = max(v0[2], x[2]) + (a,b) + end + set_packing_alignment(data) + glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, internalformat, maxdims..., layers) + for (layer, texel) in enumerate(data) + width, height = size(texel) + glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layer-1, width, height, 1, format, numbertype, texel) + end + + texture = Texture{T, 2}( + id, texturetype, numbertype, + internalformat, format, texparams, + tuple(maxdims...) + ) + set_parameters(texture) + texture +end + + + +function TextureBuffer(buffer::GLBuffer{T}) where T <: GLArrayEltypes + texture_type = GL_TEXTURE_BUFFER + id = glGenTextures() + glBindTexture(texture_type, id) + internalformat = default_internalcolorformat(T) + glTexBuffer(texture_type, internalformat, buffer.id) + tex = Texture{T, 1}( + id, texture_type, julia2glenum(T), internalformat, + default_colorformat(T), TextureParameters(T, 1), + size(buffer) + ) + TextureBuffer(tex, buffer) +end +function TextureBuffer(buffer::Vector{T}) where T <: GLArrayEltypes + buff = GLBuffer(buffer, buffertype = GL_TEXTURE_BUFFER, usage = GL_DYNAMIC_DRAW) + TextureBuffer(buff) +end + +#= +Some special treatmend for types, with alpha in the First place + +function Texture{T <: Real, NDim}(image::Array{ARGB{T}, NDim}, texture_properties::Vector{(Symbol, Any)}) + data = map(image) do colorvalue + AlphaColorValue(colorvalue.c, colorvalue.alpha) + end + Texture(pointer(data), [size(data)...], texture_properties) +end +=# + +#= +Creates a texture from an Image +=# +##function Texture(image::Image, texture_properties::Vector{(Symbol, Any)}) +# data = image.data +# Texture(mapslices(reverse, data, ndims(data)), texture_properties) +#end + + +GeometryTypes.width(t::Texture) = size(t, 1) +GeometryTypes.height(t::Texture) = size(t, 2) +depth(t::Texture) = size(t, 3) + + +function Base.show(io::IO, t::Texture{T,D}) where {T,D} + println(io, "Texture$(D)D: ") + println(io, " ID: ", t.id) + println(io, " Size: ", reduce(size(t), init = "Dimensions: ") do v0, v1 + v0*"x"*string(v1) + end) + println(io, " Julia pixel type: ", T) + println(io, " OpenGL pixel type: ", GLENUM(t.pixeltype).name) + println(io, " Format: ", GLENUM(t.format).name) + println(io, " Internal format: ", GLENUM(t.internalformat).name) + println(io, " Parameters: ", t.parameters) +end + + +# GPUArray interface: +function unsafe_copy!(a::Vector{T}, readoffset::Int, b::TextureBuffer{T}, writeoffset::Int, len::Int) where T + copy!(a, readoffset, b.buffer, writeoffset, len) + glBindTexture(b.texture.texturetype, b.texture.id) + glTexBuffer(b.texture.texturetype, b.texture.internalformat, b.buffer.id) # update texture +end + +function unsafe_copy!(a::TextureBuffer{T}, readoffset::Int, b::Vector{T}, writeoffset::Int, len::Int) where T + copy!(a.buffer, readoffset, b, writeoffset, len) + glBindTexture(a.texture.texturetype, a.texture.id) + glTexBuffer(a.texture.texturetype, a.texture.internalformat, a.buffer.id) # update texture +end +function unsafe_copy!(a::TextureBuffer{T}, readoffset::Int, b::TextureBuffer{T}, writeoffset::Int, len::Int) where T + unsafe_copy!(a.buffer, readoffset, b.buffer, writeoffset, len) + + glBindTexture(a.texture.texturetype, a.texture.id) + glTexBuffer(a.texture.texturetype, a.texture.internalformat, a.buffer.id) # update texture + + glBindTexture(b.texture.texturetype, btexture..id) + glTexBuffer(b.texture.texturetype, b.texture.internalformat, b.buffer.id) # update texture + glBindTexture(t.texture.texturetype, 0) +end +function gpu_setindex!(t::TextureBuffer{T}, newvalue::Vector{T}, indexes::UnitRange{I}) where {T, I <: Integer} + glBindTexture(t.texture.texturetype, t.texture.id) + t.buffer[indexes] = newvalue # set buffer indexes + glTexBuffer(t.texture.texturetype, t.texture.internalformat, t.buffer.id) # update texture + glBindTexture(t.texture.texturetype, 0) +end +function gpu_setindex!(t::Texture{T, 1}, newvalue::Array{T, 1}, indexes::UnitRange{I}) where {T, I <: Integer} + glBindTexture(t.texturetype, t.id) + texsubimage(t, newvalue, indexes) + glBindTexture(t.texturetype, 0) +end +function gpu_setindex!(t::Texture{T, N}, newvalue::Array{T, N}, indexes::Union{UnitRange,Integer}...) where {T, N} + glBindTexture(t.texturetype, t.id) + texsubimage(t, newvalue, indexes...) + glBindTexture(t.texturetype, 0) +end + + +function gpu_setindex!(target::Texture{T, 2}, source::Texture{T, 2}, fbo=glGenFramebuffers()) where T + glBindFramebuffer(GL_FRAMEBUFFER, fbo) + glFramebufferTexture2D( + GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, source.id, 0 + ) + glFramebufferTexture2D( + GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, + GL_TEXTURE_2D, target.id, 0 + ) + glDrawBuffer(GL_COLOR_ATTACHMENT1); + w, h = map(minimum, zip(size(target), size(source))) + glBlitFramebuffer( + 0, 0, w, h, 0, 0, w, h, + GL_COLOR_BUFFER_BIT, GL_NEAREST + ) +end + + + +#= +function gpu_setindex!{T}(target::Texture{T, 2}, source::Texture{T, 2}, fbo=glGenFramebuffers()) + w, h = map(minimum, zip(size(target), size(source))) + glCopyImageSubData( source.id, source.texturetype, + 0,0,0,0, + target.id, target.texturetype, + 0,0,0,0, w,h,0); +end +=# +# Implementing the GPUArray interface +function gpu_data(t::Texture{T, ND}) where {T, ND} + result = Array{T, ND}(undef, size(t)) + unsafe_copy!(result, t) + return result +end + +function unsafe_copy!(dest::Array{T, N}, source::Texture{T, N}) where {T,N} + bind(source) + glGetTexImage(source.texturetype, 0, source.format, source.pixeltype, dest) + bind(source, 0) + nothing +end + +gpu_data(t::TextureBuffer{T}) where {T} = gpu_data(t.buffer) +gpu_getindex(t::TextureBuffer{T}, i::UnitRange{Int64}) where {T} = t.buffer[i] + + + +similar(t::Texture{T, NDim}, newdims::Int...) where {T, NDim} = similar(t, newdims) +function similar(t::TextureBuffer{T}, newdims::NTuple{1, Int}) where T + buff = similar(t.buffer, newdims...) + return TextureBuffer(buff) +end +function similar(t::Texture{T, NDim}, newdims::NTuple{NDim, Int}) where {T, NDim} + Texture( + Ptr{T}(C_NULL), + newdims, t.texturetype, + t.pixeltype, + t.internalformat, + t.format, + t.parameters + ) +end +# Resize Texture +function gpu_resize!(t::TextureBuffer{T}, newdims::NTuple{1, Int}) where T + resize!(t.buffer, newdims) + glBindTexture(t.texture.texturetype, t.texture.id) + glTexBuffer(t.texture.texturetype, t.texture.internalformat, t.buffer.id) #update data in texture + t.texture.size = newdims + glBindTexture(t.texture.texturetype, 0) + t +end +# Resize Texture +function gpu_resize!(t::Texture{T, ND}, newdims::NTuple{ND, Int}) where {T, ND} + # dangerous code right here...Better write a few tests for this + newtex = similar(t, newdims) + old_size = size(t) + gpu_setindex!(newtex, t) + t.size = newdims + free(t) + t.id = newtex.id + return t +end + +texsubimage(t::Texture{T, 1}, newvalue::Array{T, 1}, xrange::UnitRange, level=0) where {T} = glTexSubImage1D( + t.texturetype, level, first(xrange)-1, length(xrange), t.format, t.pixeltype, newvalue +) +function texsubimage(t::Texture{T, 2}, newvalue::Array{T, 2}, xrange::UnitRange, yrange::UnitRange, level=0) where T + glTexSubImage2D( + t.texturetype, level, + first(xrange)-1, first(yrange)-1, length(xrange), length(yrange), + t.format, t.pixeltype, newvalue + ) +end +texsubimage(t::Texture{T, 3}, newvalue::Array{T, 3}, xrange::UnitRange, yrange::UnitRange, zrange::UnitRange, level=0) where {T} = glTexSubImage3D( + t.texturetype, level, + first(xrange)-1, first(yrange)-1, first(zrange)-1, length(xrange), length(yrange), length(zrange), + t.format, t.pixeltype, newvalue +) + + +Base.iterate(t::TextureBuffer{T}) where {T} = iterate(t.buffer) +function Base.iterate(t::TextureBuffer{T}, state::Tuple{Ptr{T}, Int}) where T + v_idx = iterate(t.buffer, state) + if v_idx === nothing + glBindTexture(t.texturetype, t.id) + glTexBuffer(t.texturetype, t.internalformat, t.buffer.id) + glBindTexture(t.texturetype, 0) + end + v_idx +end +function default_colorformat_sym(colordim::Integer, isinteger::Bool, colororder::AbstractString) + colordim > 4 && error("no colors with dimension > 4 allowed. Dimension given: ", colordim) + sym = "GL_" + # Handle that colordim == 1 => RED instead of R + color = colordim == 1 ? "RED" : colororder[1:colordim] + # Handle gray value + integer = isinteger ? "_INTEGER" : "" + sym *= color * integer + return Symbol(sym) +end + +default_colorformat_sym(::Type{T}) where {T <: Real} = default_colorformat_sym(1, T <: Integer, "RED") +default_colorformat_sym(::Type{T}) where {T <: AbstractArray} = default_colorformat_sym(cardinality(T), eltype(T) <: Integer, "RGBA") +default_colorformat_sym(::Type{T}) where {T <: StaticVector} = default_colorformat_sym(cardinality(T), eltype(T) <: Integer, "RGBA") +default_colorformat_sym(::Type{T}) where {T <: Colorant} = default_colorformat_sym(cardinality(T), eltype(T) <: Integer, string(Base.typename(T).name)) + +@generated function default_colorformat(::Type{T}) where T + sym = default_colorformat_sym(T) + if !isdefined(ModernGL, sym) + error("$T doesn't have a propper mapping to an OpenGL format") + end + :($sym) +end + +function default_internalcolorformat_sym(::Type{T}) where T + cdim = colordim(T) + if cdim > 4 || cdim < 1 + error("$(cdim)-dimensional colors not supported") + end + eltyp = eltype(T) + sym = "GL_" + sym *= "RGBA"[1:cdim] + bits = sizeof(eltyp) * 8 + sym *= bits <= 32 ? string(bits) : error("$(T) has too many bits") + if eltyp <: AbstractFloat + sym *= "F" + elseif eltyp <: FixedPoint + sym *= eltyp <: Normed ? "" : "_SNORM" + elseif eltyp <: Signed + sym *= "I" + elseif eltyp <: Unsigned + sym *= "UI" + end + Symbol(sym) +end + +# for I = 1:4 +# for +@generated function default_internalcolorformat(::Type{T}) where T + sym = default_internalcolorformat_sym(T) + if !isdefined(ModernGL, sym) + error("$T doesn't have a propper mapping to an OpenGL format") + end + :($sym) +end + + +#Supported texture modes/dimensions +function default_texturetype(ndim::Integer) + ndim == 1 && return GL_TEXTURE_1D + ndim == 2 && return GL_TEXTURE_2D + ndim == 3 && return GL_TEXTURE_3D + error("Dimensionality: $(ndim), not supported for OpenGL texture") +end + + +map_texture_paramers(s::NTuple{N, Symbol}) where {N} = map(map_texture_paramers, s) + +function map_texture_paramers(s::Symbol) + + s == :clamp_to_edge && return GL_CLAMP_TO_EDGE + s == :mirrored_repeat && return GL_MIRRORED_REPEAT + s == :repeat && return GL_REPEAT + + s == :linear && return GL_LINEAR + s == :nearest && return GL_NEAREST + s == :nearest_mipmap_nearest && return GL_NEAREST_MIPMAP_NEAREST + s == :linear_mipmap_nearest && return GL_LINEAR_MIPMAP_NEAREST + s == :nearest_mipmap_linear && return GL_NEAREST_MIPMAP_LINEAR + s == :linear_mipmap_linear && return GL_LINEAR_MIPMAP_LINEAR + + error("$s is not a valid texture parameter") +end + +function TextureParameters(T, NDim; + minfilter = T <: Integer ? :nearest : :linear, + magfilter = minfilter, # magnification + x_repeat = :clamp_to_edge, #wrap_s + y_repeat = x_repeat, #wrap_t + z_repeat = x_repeat, #wrap_r + anisotropic = 1f0 + ) + T <: Integer && (minfilter == :linear || magfilter == :linear) && error("Wrong Texture Parameter: Integer texture can't interpolate. Try :nearest") + repeat = (x_repeat, y_repeat, z_repeat) + swizzle_mask = if T <: Gray + GLenum[GL_RED, GL_RED, GL_RED, GL_ONE] + elseif T <: GrayA + GLenum[GL_RED, GL_RED, GL_RED, GL_ALPHA] + else + GLenum[] + end + TextureParameters( + minfilter, magfilter, ntuple(i->repeat[i], NDim), + anisotropic, swizzle_mask + ) +end +function TextureParameters(t::Texture{T, NDim}; kw_args...) where {T, NDim} + TextureParameters(T, NDim; kw_args...) +end + +const GL_TEXTURE_MAX_ANISOTROPY_EXT = GLenum(0x84FE) + +function set_parameters(t::Texture{T, N}, params::TextureParameters=t.parameters) where {T, N} + fnames = (:minfilter, :magfilter, :repeat) + data = Dict([(name, map_texture_paramers(getfield(params, name))) for name in fnames]) + result = Tuple{GLenum, Any}[] + push!(result, (GL_TEXTURE_MIN_FILTER, data[:minfilter])) + push!(result, (GL_TEXTURE_MAG_FILTER, data[:magfilter])) + push!(result, (GL_TEXTURE_WRAP_S, data[:repeat][1])) + if !isempty(params.swizzle_mask) + push!(result, (GL_TEXTURE_SWIZZLE_RGBA, params.swizzle_mask)) + end + N >= 2 && push!(result, (GL_TEXTURE_WRAP_T, data[:repeat][2])) + if N >= 3 && !is_texturearray(t) # for texture arrays, third dimension can not be set + push!(result, (GL_TEXTURE_WRAP_R, data[:repeat][3])) + end + push!(result, (GL_TEXTURE_MAX_ANISOTROPY_EXT, params.anisotropic)) + t.parameters = params + set_parameters(t, result) +end +function texparameter(t::Texture, key::GLenum, val::GLenum) + glTexParameteri(t.texturetype, key, val) +end +function texparameter(t::Texture, key::GLenum, val::Vector) + glTexParameteriv(t.texturetype, key, val) +end +function texparameter(t::Texture, key::GLenum, val::Float32) + glTexParameterf(t.texturetype, key, val) +end +function set_parameters(t::Texture, parameters::Vector{Tuple{GLenum, Any}}) + bind(t) + for elem in parameters + texparameter(t, elem...) + end + bind(t, 0) +end diff --git a/src/GLAbstraction/GLTypes.jl b/src/GLAbstraction/GLTypes.jl new file mode 100644 index 00000000000..dbcb482fdce --- /dev/null +++ b/src/GLAbstraction/GLTypes.jl @@ -0,0 +1,413 @@ +############################################################################ +const TOrSignal{T} = Union{Node{T}, T} + +const ArrayOrSignal{T, N} = TOrSignal{X} where X <: AbstractArray{T, N} +const VecOrSignal{T} = ArrayOrSignal{T, 1} +const MatOrSignal{T} = ArrayOrSignal{T, 2} +const VolumeOrSignal{T} = ArrayOrSignal{T, 3} + +const ArrayTypes{T, N} = Union{GPUArray{T, N}, ArrayOrSignal{T,N}} +const VectorTypes{T} = ArrayTypes{T, 1} +const MatTypes{T} = ArrayTypes{T, 2} +const VolumeTypes{T} = ArrayTypes{T, 3} + +@enum Projection PERSPECTIVE ORTHOGRAPHIC +@enum MouseButton MOUSE_LEFT MOUSE_MIDDLE MOUSE_RIGHT + +const GLContext = Any + +""" +Returns the cardinality of a type. falls back to length +""" +cardinality(x) = length(x) +cardinality(x::Number) = 1 +cardinality(x::Type{T}) where {T <: Number} = 1 + +#= +We need to track the current OpenGL context. +Since we can't do this via pointer identity (OpenGL may reuse the same pointers) +We go for this slightly ugly version. +=# +const context = Base.RefValue{GLContext}(:none) + +function current_context() + context[] == :none && error("No active context") + context[] +end + +function is_current_context(x) + x == context[] +end + +function native_context_alive(x) + error("Not implemented for $(typeof(x))") +end + +""" +Is current context & is alive +""" +is_context_active(x) = is_current_context(x) && context_alive(x) + +""" +Has context been destroyed or is it still living? +""" +context_alive(x) = native_context_alive(x) + +function native_switch_context!(x) + error("Not implemented for $(typeof(x))") +end + +""" +Invalidates the current context +""" +function switch_context!() + # for reverting to no context + context[] = :none +end + +""" +Switches to a new context `x`. Is a noop if `x` is already current +""" +function switch_context!(x) + if !is_current_context(x) + context[] = x + native_switch_context!(x) + end +end + +struct Shader + name::Symbol + source::Vector{UInt8} + typ::GLenum + id::GLuint + context::GLContext + function Shader(name, source, typ, id) + new(name, source, typ, id, current_context()) + end +end +function Shader(name, source::Vector{UInt8}, typ) + compile_shader(source, typ, name) +end +name(s::Shader) = s.name + +import Base: == + +function (==)(a::Shader, b::Shader) + a.source == b.source && a.typ == b.typ && a.id == b.id && a.context == b.context +end + +function Base.hash(s::Shader, h::UInt64) + hash((s.source, s.typ, s.id, s.context), h) +end + + +function Base.show(io::IO, shader::Shader) + println(io, GLENUM(shader.typ).name, " shader: $(shader.name))") + println(io, "source:") + print_with_lines(io, String(shader.source)) +end + +mutable struct GLProgram + id ::GLuint + shader ::Vector{Shader} + nametype ::Dict{Symbol, GLenum} + uniformloc ::Dict{Symbol, Tuple} + context ::GLContext + function GLProgram(id::GLuint, shader::Vector{Shader}, nametype::Dict{Symbol, GLenum}, uniformloc::Dict{Symbol, Tuple}) + obj = new(id, shader, nametype, uniformloc, current_context()) + finalizer(free, obj) + obj + end +end +function Base.show(io::IO, p::GLProgram) + println(io, "GLProgram: $(p.id)") + println(io, "Shaders:") + for shader in p.shader + println(io, shader) + end + println(io, "uniforms:") + for (name, typ) in p.nametype + println(io, " ", name, "::", GLENUM(typ).name) + end +end + + +############################################ +# Framebuffers and the like + +struct RenderBuffer + id ::GLuint + format ::GLenum + context ::GLContext + function RenderBuffer(format, dimension) + @assert length(dimensions) == 2 + id = GLuint[0] + glGenRenderbuffers(1, id) + glBindRenderbuffer(GL_RENDERBUFFER, id[1]) + glRenderbufferStorage(GL_RENDERBUFFER, format, dimension...) + new(id, format, current_context()) + end +end +function resize!(rb::RenderBuffer, newsize::AbstractArray) + if length(newsize) != 2 + error("RenderBuffer needs to be 2 dimensional. Dimension found: ", newsize) + end + glBindRenderbuffer(GL_RENDERBUFFER, rb.id) + glRenderbufferStorage(GL_RENDERBUFFER, rb.format, newsize...) +end + +struct FrameBuffer{T} + id ::GLuint + attachments ::Vector{Any} + context ::GLContext + function FrameBuffer{T}(dimensions::Node) where T + fb = glGenFramebuffers() + glBindFramebuffer(GL_FRAMEBUFFER, fb) + new(id, attachments, current_context()) + end +end +function resize!(fbo::FrameBuffer, newsize::AbstractArray) + if length(newsize) != 2 + error("FrameBuffer needs to be 2 dimensional. Dimension found: ", newsize) + end + for elem in fbo.attachments + resize!(elem) + end +end + +######################################################################################## +# OpenGL Arrays + + +const GLArrayEltypes = Union{StaticVector, Real, Colorant} +""" +Transform julia datatypes to opengl enum type +""" +julia2glenum(x::Type{T}) where {T <: FixedPoint} = julia2glenum(FixedPointNumbers.rawtype(x)) +julia2glenum(x::Type{OffsetInteger{O, T}}) where {O, T} = julia2glenum(T) +julia2glenum(x::Union{Type{T}, T}) where {T <: Union{StaticVector, Colorant}} = julia2glenum(eltype(x)) +julia2glenum(x::Type{GLubyte}) = GL_UNSIGNED_BYTE +julia2glenum(x::Type{GLbyte}) = GL_BYTE +julia2glenum(x::Type{GLuint}) = GL_UNSIGNED_INT +julia2glenum(x::Type{GLushort}) = GL_UNSIGNED_SHORT +julia2glenum(x::Type{GLshort}) = GL_SHORT +julia2glenum(x::Type{GLint}) = GL_INT +julia2glenum(x::Type{GLfloat}) = GL_FLOAT +julia2glenum(x::Type{GLdouble}) = GL_DOUBLE +julia2glenum(x::Type{Float16}) = GL_HALF_FLOAT +function julia2glenum(::Type{T}) where T + error("Type: $T not supported as opengl number datatype") +end + +include("GLBuffer.jl") +include("GLTexture.jl") + +######################################################################## + + +""" +Represents an OpenGL vertex array type. +Can be created from a dict of buffers and an opengl Program. +Keys with the name `indices` will get special treatment and will be used as +the indexbuffer. +""" +mutable struct GLVertexArray{T} + program ::GLProgram + id ::GLuint + bufferlength ::Int + buffers ::Dict{String, GLBuffer} + indices ::T + context ::GLContext + + function GLVertexArray{T}(program, id, bufferlength, buffers, indices) where T + new(program, id, bufferlength, buffers, indices, current_context()) + end +end +""" +returns the length of the vertex array. +This is amount of primitives stored in the vertex array, needed for `glDrawArrays` +""" +function length(vao::GLVertexArray) + length(first(vao.buffers)[2]) # all buffers have same length, so first should do! +end +function GLVertexArray(vao::GLVertexArray) + GLVertexArray(vao.buffers, vao.program) +end +function GLVertexArray(bufferdict::Dict, program::GLProgram) + #get the size of the first array, to assert later, that all have the same size + indexes = -1 + len = -1 + id = glGenVertexArrays() + glBindVertexArray(id) + lenbuffer = 0 + buffers = Dict{String, GLBuffer}() + for (name, buffer) in bufferdict + if isa(buffer, GLBuffer) && buffer.buffertype == GL_ELEMENT_ARRAY_BUFFER + bind(buffer) + indexes = buffer + elseif Symbol(name) == :indices + indexes = buffer + else + attribute = string(name) + len == -1 && (len = length(buffer)) + # TODO: use glVertexAttribDivisor to allow multiples of the longest buffer + len != length(buffer) && error( + "buffer $attribute has not the same length as the other buffers. + Has: $(length(buffer)). Should have: $len" + ) + bind(buffer) + attribLocation = get_attribute_location(program.id, attribute) + (attribLocation == -1) && continue + glVertexAttribPointer(attribLocation, cardinality(buffer), julia2glenum(eltype(buffer)), GL_FALSE, 0, C_NULL) + glEnableVertexAttribArray(attribLocation) + buffers[attribute] = buffer + lenbuffer = buffer + end + end + glBindVertexArray(0) + if indexes == -1 + indexes = len + end + obj = GLVertexArray{typeof(indexes)}(program, id, len, buffers, indexes) + finalizer(free, obj) + obj +end +function Base.show(io::IO, vao::GLVertexArray) + show(io, vao.program) + println(io, "GLVertexArray $(vao.id):") + print( io, "GLVertexArray $(vao.id) buffers: ") + writemime(io, MIME("text/plain"), vao.buffers) + println(io, "\nGLVertexArray $(vao.id) indices: ", vao.indices) +end + + +################################################################################## + +const RENDER_OBJECT_ID_COUNTER = Ref(zero(GLushort)) + +mutable struct RenderObject{Pre} <: Composable{DeviceUnit} + main # main object + uniforms ::Dict{Symbol, Any} + vertexarray ::GLVertexArray + prerenderfunction ::Pre + postrenderfunction + id ::GLushort + boundingbox # workaround for having lazy boundingbox queries, while not using multiple dispatch for boundingbox function (No type hierarchy for RenderObjects) + function RenderObject{Pre}( + main, uniforms::Dict{Symbol, Any}, vertexarray::GLVertexArray, + prerenderfunctions, postrenderfunctions, + boundingbox + ) where Pre + RENDER_OBJECT_ID_COUNTER[] += one(GLushort) + new( + main, uniforms, vertexarray, + prerenderfunctions, postrenderfunctions, + RENDER_OBJECT_ID_COUNTER[], boundingbox + ) + end +end + + +function RenderObject( + data::Dict{Symbol, Any}, program, + pre::Pre, post, + bbs=Node(AABB{Float32}(Vec3f0(0),Vec3f0(1))), + main=nothing + ) where Pre + targets = get(data, :gl_convert_targets, Dict()) + delete!(data, :gl_convert_targets) + passthrough = Dict{Symbol, Any}() # we also save a few non opengl related values in data + for (k,v) in data # convert everything to OpenGL compatible types + if haskey(targets, k) + # glconvert is designed to just convert everything to a fitting opengl datatype, but sometimes exceptions are needed + # e.g. Texture{T,1} and GLBuffer{T} are both usable as an native conversion canditate for a Julia's Array{T, 1} type. + # but in some cases we want a Texture, sometimes a GLBuffer or TextureBuffer + data[k] = gl_convert(targets[k], v) + else + k in (:indices, :visible, :fxaa) && continue + if isa_gl_struct(v) # structs are treated differently, since they have to be composed into their fields + merge!(data, gl_convert_struct(v, k)) + elseif applicable(gl_convert, v) # if can't be converted to an OpenGL datatype, + data[k] = gl_convert(v) + else # put it in passthrough + delete!(data, k) + passthrough[k] = v + end + end + end + # handle meshes seperately, since they need expansion + meshs = filter(((key, value),) -> isa(value, NativeMesh), data) + if !isempty(meshs) + merge!(data, [v.data for (k,v) in meshs]...) + end + buffers = filter(((key, value),) -> isa(value, GLBuffer) || key == :indices, data) + uniforms = filter(((key, value),) -> !isa(value, GLBuffer) && key != :indices, data) + get!(data, :visible, true) # make sure, visibility is set + merge!(data, passthrough) # in the end, we insert back the non opengl data, to keep things simple + p = gl_convert(to_value(program), data) # "compile" lazyshader + vertexarray = GLVertexArray(Dict(buffers), p) + robj = RenderObject{Pre}( + main, + data, + vertexarray, + pre, + post, + bbs + ) + # automatically integrate object ID, will be discarded if shader doesn't use it + robj[:objectid] = robj.id + robj +end + +include("GLRenderObject.jl") + +#################################################################################### +# freeing + +function log_finalizer(x) + open("finalizer_log.txt", "a") do io + print(io, x) + print(io, '\n') + end +end + +function free(x) + try + unsafe_free(x) + catch e + isa(e, ContextNotAvailable) && return # if context got destroyed no need to worry! + if :msg in fieldnames(e) + log_finalizer(e.msg) + else + log_finalizer(typeof(e)) + end + end +end + +# OpenGL has the annoying habit of reusing id's when creating a new context +# We need to make sure to only free the current one +function unsafe_free(x::GLProgram) + is_context_active(x.context) || return + glDeleteProgram(x.id) + return +end +function unsafe_free(x::GLBuffer) + # don't free from other context + is_context_active(x.context) || return + id = Ref(x.id) + glDeleteBuffers(1, id) + return +end +function unsafe_free(x::Texture) + is_context_active(x.context) || return + id = Ref(x.id) + glDeleteTextures(x.id) + return +end + +function unsafe_free(x::GLVertexArray) + is_context_active(x.context) || return + id = Ref(x.id) + glDeleteVertexArrays(1, id) + return +end diff --git a/src/GLAbstraction/GLUniforms.jl b/src/GLAbstraction/GLUniforms.jl new file mode 100644 index 00000000000..07ae59d2472 --- /dev/null +++ b/src/GLAbstraction/GLUniforms.jl @@ -0,0 +1,261 @@ +# Uniforms are OpenGL variables that stay the same for the entirety of a drawcall. +# There are a lot of functions, to upload them, as OpenGL doesn't rely on multiple dispatch. +# here is my approach, to handle all of the uniforms with one function, namely gluniform +# For uniforms, the Vector and Matrix types from ImmutableArrays should be used, as they map the relation almost 1:1 + +const GLSL_COMPATIBLE_NUMBER_TYPES = (GLfloat, GLint, GLuint, GLdouble) +const NATIVE_TYPES = Union{ + StaticArray, GLSL_COMPATIBLE_NUMBER_TYPES..., + ZeroIndex{GLint}, ZeroIndex{GLuint}, + GLBuffer, GPUArray, Shader, GLProgram, NativeMesh +} + +opengl_prefix(T) = error("Object $T is not a supported uniform element type") +opengl_postfix(T) = error("Object $T is not a supported uniform element type") + + +opengl_prefix(x::Type{T}) where {T <: Union{FixedPoint, Float32, Float16}} = "" +opengl_prefix(x::Type{T}) where {T <: Float64} = "d" +opengl_prefix(x::Type{Cint}) = "i" +opengl_prefix(x::Type{T}) where {T <: Union{Cuint, UInt8, UInt16}} = "u" + +opengl_postfix(x::Type{Float64}) = "dv" +opengl_postfix(x::Type{Float32}) = "fv" +opengl_postfix(x::Type{Cint}) = "iv" +opengl_postfix(x::Type{Cuint}) = "uiv" + + +function uniformfunc(typ::DataType, dims::Tuple{Int}) + Symbol(string("glUniform", first(dims), opengl_postfix(typ))) +end +function uniformfunc(typ::DataType, dims::Tuple{Int, Int}) + M, N = dims + Symbol(string("glUniformMatrix", M == N ? "$M" : "$(M)x$(N)", opengl_postfix(typ))) +end + +function gluniform(location::Integer, x::FSA) where FSA <: Union{StaticArray, Colorant} + xref = [x] + gluniform(location, xref) +end + +_size(p) = size(p) +_size(p::Colorant) = (length(p),) +_size(p::Type{T}) where {T <: Colorant} = (length(p),) +_ndims(p) = ndims(p) +_ndims(p::Type{T}) where {T <: Colorant} = 1 + +@generated function gluniform(location::Integer, x::Vector{FSA}) where FSA <: Union{StaticArray, Colorant} + func = uniformfunc(eltype(FSA), _size(FSA)) + callexpr = if _ndims(FSA) == 2 + :($func(location, length(x), GL_FALSE, xref)) + else + :($func(location, length(x), xref)) + end + quote + xref = reinterpret(eltype(FSA), x) + $callexpr + end +end + + +#Some additional uniform functions, not related to Imutable Arrays +gluniform(location::Integer, target::Integer, t::Texture) = gluniform(GLint(location), GLint(target), t) +gluniform(location::Integer, target::Integer, t::GPUVector) = gluniform(GLint(location), GLint(target), t.buffer) +gluniform(location::Integer, target::Integer, t::Node) = gluniform(GLint(location), GLint(target), to_value(t)) +gluniform(location::Integer, target::Integer, t::TextureBuffer) = gluniform(GLint(location), GLint(target), t.texture) +function gluniform(location::GLint, target::GLint, t::Texture) + activeTarget = GL_TEXTURE0 + UInt32(target) + glActiveTexture(activeTarget) + glBindTexture(t.texturetype, t.id) + gluniform(location, target) +end +gluniform(location::Integer, x::Enum) = gluniform(GLint(location), GLint(x)) + +function gluniform(loc::Integer, x::Node{T}) where T + gluniform(GLint(loc), to_value(x)) +end + +gluniform(location::Integer, x::Union{GLubyte, GLushort, GLuint}) = glUniform1ui(GLint(location), x) +gluniform(location::Integer, x::Union{GLbyte, GLshort, GLint, Bool}) = glUniform1i(GLint(location), x) +gluniform(location::Integer, x::GLfloat) = glUniform1f(GLint(location), x) +gluniform(location::Integer, x::GLdouble) = glUniform1d(GLint(location), x) + +#Uniform upload functions for julia arrays... +gluniform(location::GLint, x::Vector{Float32}) = glUniform1fv(location, length(x), x) +gluniform(location::GLint, x::Vector{GLdouble}) = glUniform1dv(location, length(x), x) +gluniform(location::GLint, x::Vector{GLint}) = glUniform1iv(location, length(x), x) +gluniform(location::GLint, x::Vector{GLuint}) = glUniform1uiv(location, length(x), x) + + +glsl_typename(x::T) where {T} = glsl_typename(T) +glsl_typename(t::Type{Nothing}) = "Nothing" +glsl_typename(t::Type{GLfloat}) = "float" +glsl_typename(t::Type{GLdouble}) = "double" +glsl_typename(t::Type{GLuint}) = "uint" +glsl_typename(t::Type{GLint}) = "int" +glsl_typename(t::Type{T}) where {T <: Union{StaticVector, Colorant}} = string(opengl_prefix(eltype(T)), "vec", length(T)) +glsl_typename(t::Type{TextureBuffer{T}}) where {T} = string(opengl_prefix(eltype(T)), "samplerBuffer") + +function glsl_typename(t::Texture{T, D}) where {T, D} + str = string(opengl_prefix(eltype(T)), "sampler", D, "D") + t.texturetype == GL_TEXTURE_2D_ARRAY && (str *= "Array") + str +end +function glsl_typename(t::Type{T}) where T <: SMatrix + M, N = size(t) + string(opengl_prefix(eltype(t)), "mat", M==N ? M : string(M, "x", N)) +end +toglsltype_string(t::Node) = toglsltype_string(to_value(t)) +toglsltype_string(x::T) where {T<:Union{Real, StaticArray, Texture, Colorant, TextureBuffer, Nothing}} = "uniform $(glsl_typename(x))" +#Handle GLSL structs, which need to be addressed via single fields +function toglsltype_string(x::T) where T + if isa_gl_struct(x) + string("uniform ", T.name.name) + else + error("can't splice $T into an OpenGL shader. Make sure all fields are of a concrete type and isbits(FieldType)-->true") + end +end +toglsltype_string(t::Union{GLBuffer{T}, GPUVector{T}}) where {T} = string("in ", glsl_typename(T)) +# Gets used to access a +function glsl_variable_access(keystring, t::Texture{T, D}) where {T,D} + fields = SubString("rgba", 1, length(T)) + if t.texturetype == GL_TEXTURE_BUFFER + return string("texelFetch(", keystring, "index).", fields, ";") + end + return string("getindex(", keystring, "index).", fields, ";") +end +function glsl_variable_access(keystring, ::Union{Real, GLBuffer, GPUVector, StaticArray, Colorant}) + string(keystring, ";") +end +function glsl_variable_access(keystring, s::Node) + glsl_variable_access(keystring, to_value(s)) +end +function glsl_variable_access(keystring, t::Any) + error("no glsl variable calculation available for : ", keystring, " of type ", typeof(t)) +end + +function uniform_name_type(program::GLuint) + uniformLength = glGetProgramiv(program, GL_ACTIVE_UNIFORMS) + Dict{Symbol, GLenum}(ntuple(uniformLength) do i # take size and name + name, typ = glGetActiveUniform(program, i-1) + end) +end +function attribute_name_type(program::GLuint) + uniformLength = glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES) + Dict{Symbol, GLenum}(ntuple(uniformLength) do i + name, typ = glGetActiveAttrib(program, i-1) + end) +end +function istexturesampler(typ::GLenum) + return ( + typ == GL_SAMPLER_BUFFER || typ == GL_INT_SAMPLER_BUFFER || typ == GL_UNSIGNED_INT_SAMPLER_BUFFER || + typ == GL_IMAGE_2D || + typ == GL_SAMPLER_1D || typ == GL_SAMPLER_2D || typ == GL_SAMPLER_3D || + typ == GL_UNSIGNED_INT_SAMPLER_1D || typ == GL_UNSIGNED_INT_SAMPLER_2D || typ == GL_UNSIGNED_INT_SAMPLER_3D || + typ == GL_INT_SAMPLER_1D || typ == GL_INT_SAMPLER_2D || typ == GL_INT_SAMPLER_3D || + typ == GL_SAMPLER_1D_ARRAY || typ == GL_SAMPLER_2D_ARRAY || + typ == GL_UNSIGNED_INT_SAMPLER_1D_ARRAY || typ == GL_UNSIGNED_INT_SAMPLER_2D_ARRAY || + typ == GL_INT_SAMPLER_1D_ARRAY || typ == GL_INT_SAMPLER_2D_ARRAY + ) +end + + +gl_promote(x::Type{T}) where {T <: Integer} = Cint +gl_promote(x::Type{Union{Int16, Int8}}) = x + +gl_promote(x::Type{T}) where {T <: Unsigned} = Cuint +gl_promote(x::Type{Union{UInt16, UInt8}}) = x + +gl_promote(x::Type{T}) where {T <: AbstractFloat} = Float32 +gl_promote(x::Type{Float16}) = x + +gl_promote(x::Type{T}) where {T <: Normed} = N0f32 +gl_promote(x::Type{N0f16}) = x +gl_promote(x::Type{N0f8}) = x + +const Color3{T} = Colorant{T, 3} +const Color4{T} = Colorant{T, 4} + +gl_promote(x::Type{Bool}) = GLboolean +gl_promote(x::Type{T}) where {T <: Gray} = Gray{gl_promote(eltype(T))} +gl_promote(x::Type{T}) where {T <: Color3} = RGB{gl_promote(eltype(T))} +gl_promote(x::Type{T}) where {T <: Color4} = RGBA{gl_promote(eltype(T))} +gl_promote(x::Type{T}) where {T <: BGRA} = BGRA{gl_promote(eltype(T))} +gl_promote(x::Type{T}) where {T <: BGR} = BGR{gl_promote(eltype(T))} + + +gl_promote(x::Type{T}) where {T <: StaticVector} = similar_type(T, gl_promote(eltype(T))) + +gl_promote(x::Type{T}) where {T <: HomogenousMesh} = NativeMesh{T} + +gl_convert(x::AbstractVector{Vec3f0}) = x + +gl_convert(x::T) where {T <: Number} = gl_promote(T)(x) +gl_convert(x::T) where {T <: Colorant} = gl_promote(T)(x) +gl_convert(x::T) where {T <: AbstractMesh} = gl_convert(convert(GLNormalMesh, x)) +gl_convert(x::T) where {T <: HomogenousMesh} = gl_promote(T)(x) +gl_convert(x::Node{T}) where {T <: HomogenousMesh} = gl_promote(T)(x) + +gl_convert(s::Vector{Matrix{T}}) where {T<:Colorant} = Texture(s) +gl_convert(s::AABB) = s +gl_convert(s::Nothing) = s + +isa_gl_struct(x::AbstractArray) = false +isa_gl_struct(x::NATIVE_TYPES) = false +isa_gl_struct(x::Colorant) = false +function isa_gl_struct(x::T) where T + !isconcretetype(T) && return false + if T <: Tuple + return false + end + fnames = fieldnames(T) + !isempty(fnames) && all(name -> isconcretetype(fieldtype(T, name)) && isbits(getfield(x, name)), fnames) +end +function gl_convert_struct(x::T, uniform_name::Symbol) where T + if isa_gl_struct(x) + return Dict{Symbol, Any}(map(fieldnames(x)) do name + (Symbol("$uniform_name.$name") => gl_convert(getfield(x, name))) + end) + else + error("can't convert $x to a OpenGL type. Make sure all fields are of a concrete type and isbits(FieldType)-->true") + end +end + + +# native types don't need convert! +gl_convert(a::T) where {T <: NATIVE_TYPES} = a + +gl_convert(s::Node{T}) where {T <: NATIVE_TYPES} = s +gl_convert(s::Node{T}) where T = const_lift(gl_convert, s) + +gl_convert(x::StaticVector{N, T}) where {N, T} = map(gl_promote(T), x) +gl_convert(x::SMatrix{N, M, T}) where {N, M, T} = map(gl_promote(T), x) + + +gl_convert(a::AbstractVector{<: Face}) = indexbuffer(s) + +gl_convert(t::Type{T}, a::T; kw_args...) where T <: NATIVE_TYPES = a + + +gl_convert(::Type{<: GPUArray}, a::StaticVector) = gl_convert(a) + +function gl_convert(T::Type{<: GPUArray}, a::AbstractArray{X, N}; kw_args...) where {X, N} + T(convert(AbstractArray{gl_promote(X), N}, a); kw_args...) +end + +gl_convert(::Type{<: GLBuffer}, x::GLBuffer; kw_args...) = x +gl_convert(::Type{Texture}, x::Texture) = x +gl_convert(::Type{<: GPUArray}, x::GPUArray) = x + +function gl_convert(::Type{T}, a::Vector{Array{X, 2}}; kw_args...) where {T <: Texture, X} + T(a; kw_args...) +end +gl_convert(::Type{<: GPUArray}, a::Node{<: StaticVector}) = gl_convert(a) + +function gl_convert(::Type{T}, a::Node{<: AbstractArray{X, N}}; kw_args...) where {T <: GPUArray, X, N} + TGL = gl_promote(X) + s = (X == TGL) ? a : lift(x-> convert(Array{TGL, N}, x), a) + T(s; kw_args...) +end + +gl_convert(f::Function, a) = f(a) diff --git a/src/GLAbstraction/GLUtils.jl b/src/GLAbstraction/GLUtils.jl new file mode 100644 index 00000000000..2cdf10a68b5 --- /dev/null +++ b/src/GLAbstraction/GLUtils.jl @@ -0,0 +1,262 @@ +macro gputime(codeblock) + quote + local const query = GLuint[1] + local const elapsed_time = GLuint64[1] + local const done = GLint[0] + glGenQueries(1, query) + glBeginQuery(GL_TIME_ELAPSED, query[1]) + $(esc(codeblock)) + glEndQuery(GL_TIME_ELAPSED) + + while (done[1] != 1) + glGetQueryObjectiv( + query[1], + GL_QUERY_RESULT_AVAILABLE, + done + ) + end + glGetQueryObjectui64v(query[1], GL_QUERY_RESULT, elapsed_time) + println("Time Elapsed: ", elapsed_time[1] / 1000000.0, "ms") + end +end + +struct IterOrScalar{T} + val::T +end + +minlenght(a::Tuple{Vararg{IterOrScalar}}) = foldl(typemax(Int), a) do len, elem + isa(elem.val, AbstractArray) && len > length(elem.val) && return length(elem.val) + len +end +getindex(A::IterOrScalar{T}, i::Integer) where {T<:AbstractArray} = A.val[i] +getindex(A::IterOrScalar, i::Integer) = A.val + +#Some mapping functions for dictionaries +function mapvalues(func, collection::Dict) + Dict([(key, func(value)) for (key, value) in collection]) +end +function mapkeys(func, collection::Dict) + Dict([(func(key), value) for (key, value) in collection]) +end + +function print_with_lines(out::IO, text::AbstractString) + io = IOBuffer() + for (i,line) in enumerate(split(text, "\n")) + println(io, @sprintf("%-4d: %s", i, line)) + end + write(out, take!(io)) +end +print_with_lines(text::AbstractString) = print_with_lines(stdout, text) + + +""" +Style Type, which is used to choose different visualization/editing styles via multiple dispatch +Usage pattern: +visualize(::Style{:Default}, ...) = do something +visualize(::Style{:MyAwesomeNewStyle}, ...) = do something different +""" +struct Style{StyleValue} +end +Style(x::Symbol) = Style{x}() +Style() = Style{:Default}() +mergedefault!(style::Style{S}, styles, customdata) where {S} = merge!(copy(styles[S]), Dict{Symbol, Any}(customdata)) +macro style_str(string) + Style{Symbol(string)} +end +export @style_str + +""" +splats keys from a dict into variables +""" +macro materialize(dict_splat) + keynames, dict = dict_splat.args + keynames = isa(keynames, Symbol) ? [keynames] : keynames.args + dict_instance = gensym() + kd = [:($key = $dict_instance[$(Expr(:quote, key))]) for key in keynames] + kdblock = Expr(:block, kd...) + expr = quote + $dict_instance = $dict # handle if dict is not a variable but an expression + $kdblock + end + esc(expr) +end +""" +splats keys from a dict into variables and removes them +""" +macro materialize!(dict_splat) + keynames, dict = dict_splat.args + keynames = isa(keynames, Symbol) ? [keynames] : keynames.args + dict_instance = gensym() + kd = [:($key = pop!($dict_instance, $(Expr(:quote, key)))) for key in keynames] + kdblock = Expr(:block, kd...) + expr = quote + $dict_instance = $dict # handle if dict is not a variable but an expression + $kdblock + end + esc(expr) +end + + +""" +Needed to match the lazy gl_convert exceptions. + `Target`: targeted OpenGL type + `x`: the variable that gets matched +""" +matches_target(::Type{Target}, x::T) where {Target, T} = applicable(gl_convert, Target, x) || T <: Target # it can be either converted to Target, or it's already the target +matches_target(::Type{Target}, x::Node{T}) where {Target, T} = applicable(gl_convert, Target, x) || T <: Target +matches_target(::Function, x) = true +matches_target(::Function, x::Nothing) = false +export matches_target + + +signal_convert(T, y) = convert(T, y) +signal_convert(T1, y::T2) where {T2<:Node} = lift(convert, Node(T1), y) +""" +Takes a dict and inserts defaults, if not already available. +The variables are made accessible in local scope, so things like this are possible: +gen_defaults! dict begin + a = 55 + b = a * 2 # variables, like a, will get made visible in local scope + c::JuliaType = X # `c` needs to be of type JuliaType. `c` will be made available with it's original type and then converted to JuliaType when inserted into `dict` + d = x => GLType # OpenGL convert target. Get's only applied if `x` is convertible to GLType. Will only be converted when passed to RenderObject + d = x => \"doc string\" + d = x => (GLType, \"doc string and gl target\") +end +""" +macro gen_defaults!(dict, args) + args.head == :block || error("second argument needs to be a block of form + begin + a = 55 + b = a * 2 # variables, like a, will get made visible in local scope + c::JuliaType = X # c needs to be of type JuliaType. c will be made available with it's original type and then converted to JuliaType when inserted into data + d = x => GLType # OpenGL convert target. Get's only applied if x is convertible to GLType. Will only be converted when passed to RenderObject + end") + tuple_list = args.args + dictsym = gensym() + return_expression = Expr(:block) + push!(return_expression.args, :($dictsym = $dict)) # dict could also be an expression, so we need to asign it to a variable at the beginning + push!(return_expression.args, :(gl_convert_targets = get!($dictsym, :gl_convert_targets, Dict{Symbol, Any}()))) # exceptions for glconvert. + push!(return_expression.args, :(doc_strings = get!($dictsym, :doc_string, Dict{Symbol, Any}()))) # exceptions for glconvert. + # @gen_defaults can be used multiple times, so we need to reuse gl_convert_targets if already in here + for (i, elem) in enumerate(tuple_list) + opengl_convert_target = :() # is optional, so first is an empty expression + convert_target = :() # is optional, so first is an empty expression + doc_strings = :() + if Meta.isexpr(elem, :(=)) + key_name, value_expr = elem.args + if isa(key_name, Expr) && key_name.head == :(::) # we need to convert to a julia type + key_name, convert_target = key_name.args + convert_target = :(GLAbstraction.signal_convert($convert_target, $key_name)) + else + convert_target = :($key_name) + end + key_sym = Expr(:quote, key_name) + if isa(value_expr, Expr) && value_expr.head == :call && value_expr.args[1] == :(=>) # we might need to insert a convert target + value_expr, target = value_expr.args[2:end] + undecided = [] + if isa(target, Expr) + undecided = target.args + else + push!(undecided, target) + end + for elem in undecided + isa(elem, Expr) && continue # + if isa(elem, AbstractString) # only docstring + doc_strings = :(doc_strings[$key_sym] = $elem) + elseif isa(elem, Symbol) + opengl_convert_target = quote + if matches_target($elem, $key_name) + gl_convert_targets[$key_sym] = $elem + end + end + end + end + end + expr = quote + $key_name = if haskey($dictsym, $key_sym) + $dictsym[$key_sym] + else + $value_expr # in case that evaluating value_expr is expensive, we use a branch instead of get(dict, key, default) + end + $dictsym[$key_sym] = $convert_target + $opengl_convert_target + $doc_strings + end + push!(return_expression.args, expr) + end + end + #push!(return_expression.args, :($dictsym[:gl_convert_targets] = gl_convert_targets)) #just pass the targets via the dict + push!(return_expression.args, :($dictsym)) #return dict + esc(return_expression) +end +export @gen_defaults! + +makesignal(s::Node) = s +makesignal(v) = Node(v) + +@inline const_lift(f::Union{DataType, Type, Function}, inputs...) = lift(f, map(makesignal, inputs)...) +export const_lift + + + +isnotempty(x) = !isempty(x) +AND(a,b) = a&&b +OR(a,b) = a||b + +#Meshtype holding native OpenGL data. +struct NativeMesh{MeshType <: HomogenousMesh} + data::Dict{Symbol, Any} +end +export NativeMesh + +NativeMesh(m::T) where {T <: HomogenousMesh} = NativeMesh{T}(m) + + +function (MT::Type{NativeMesh{T}})(m::T) where T <: HomogenousMesh + result = Dict{Symbol, Any}() + attribs = attributes(m) + @materialize! vertices, faces = attribs + result[:vertices] = GLBuffer(vertices) + result[:faces] = indexbuffer(faces) + for (field, val) in attribs + if field in (:texturecoordinates, :normals, :attribute_id, :color) + if field == :color + field = :vertex_color + end + if isa(val, AbstractVector) + result[field] = GLBuffer(val) + end + else + result[field] = Texture(val) + end + end + MT(result) +end + +function (MT::Type{NativeMesh{T}})(m::Node{T}) where T <: HomogenousMesh + result = Dict{Symbol, Any}() + mv = to_value(m) + attribs = attributes(mv) + @materialize! vertices, faces = attribs + result[:vertices] = GLBuffer(vertices) + result[:faces] = indexbuffer(faces) + for (field, val) in attribs + if field in (:texturecoordinates, :normals, :attribute_id, :color) + if field == :color + field = :vertex_color + end + if isa(val, AbstractVector) + result[field] = GLBuffer(val) + end + else + result[field] = Texture(val) + end + end + on(m) do mesh + for (field, val) in attributes(mesh) + field == :color && (field = :vertex_color) + haskey(result, field) && update!(result[field], val) + end + end + MT(result) +end diff --git a/src/GLAbstraction/composition.jl b/src/GLAbstraction/composition.jl new file mode 100644 index 00000000000..e38505d450f --- /dev/null +++ b/src/GLAbstraction/composition.jl @@ -0,0 +1,121 @@ + +abstract type Unit end +abstract type Composable{unit} end + +struct DeviceUnit <: Unit end + +mutable struct Context{Unit} <: Composable{Unit} + children + boundingbox + transformation +end +function scale_trans(b) + m = minimum(b) + w = widths(b) + T = eltype(w) + # make code work also for N == 2 + w3 = ndims(w) > 2 ? w[3] : one(T) + m3 = ndims(m) > 2 ? m[3] : zero(T) + Vec3f0(w[1], w[2], w3), Vec3f0(m[1], m[2], m3) +end +function translationmatrix(b) + s,t = scale_trans(b) + Mat4f0( # always return float32 matrix + s[1], 0 , 0 , 0, + 0 , s[2], 0 , 0, + 0 , 0 , s[3], 0, + t[1], t[2], t[3], 1, + ) +end +function inversetransformation(b) + s,t = scale_trans(b) + s = 1f0/s + t = -t + Mat4f0( # always return float32 matrix + s[1], 0 , 0 , 0, + 0 , s[2], 0 , 0, + 0 , 0 , s[3], 0, + t[1], t[2], t[3], 1, + ) +end +layout!(b, c) = layout!(b, (c,))[1] +layout!(b, c, composable...) = layout!(b, (c,composable...)) +function combine_s_t(scale_trans1, scale_trans2) + s1,t1 = scale_trans1 + s2,t2 = scale_trans2 + s2 = 1f0./s2 + t2 = -t2 + s,t = s1.*s2, t1+t2 + Mat4f0( # always return float32 matrix + s[1], 0 , 0 , 0, + 0 , s[2], 0 , 0, + 0 , 0 , s[3], 0, + t[1], t[2], t[3], 1, + ) +end +function layout!(b, composables::Union{Tuple, Vector}) + st_target = const_lift(scale_trans, b) + map(composables) do composable + st_being = const_lift(scale_trans, c_boundingbox(composable)) + transform!(composable, map(combine_s_t, st_target, st_being)) + composable + end +end + +export layout! + + +Context() = Context{DeviceUnit}(Composable[], Node(AABB{Float32}(Vec3f0(0), Vec3f0(0))), Node(Mat{4,4, Float32}(I))) +Context(trans::Node{Mat{4,4, Float32}}) = Context{DeviceUnit}(Composable[], Node(AABB{Float32}(Vec3f0(0), Vec3f0(0))), trans) +function Context(a::Composable...; parent=Context()) + append!(parent, a) + parent +end +c_boundingbox(c::Composable) = c.boundingbox +transformation(c::Composable) = c.transformation + +function transform!(c::Composable, model) + c.transformation = const_lift(*, model, transformation(c)) + for elem in c.children + transform!(elem, c.transformation) + end + c +end +function transformation(c::Composable, model) + c.transformation = const_lift(*, model, c.transformation) + for elem in c.children + transformation(elem, c.transformation) + end + c +end + +convert!(::Type{unit}, x::Composable) where {unit <: Unit} = x # We don't do units just yet + +function Base.append!(context::Context{unit}, x::Union{Vector{Composable}, NTuple{N, Composable}}) where {unit <: Unit, N} + for elem in x + push!(context, elem) + end + context +end + +function Base.push!(context::Context{unit}, x::Composable) where unit <: Unit + x = convert!(unit, x) + context.boundingbox = const_lift(transformation(x), transformation(context), c_boundingbox(x), c_boundingbox(context)) do transa, transb, a,b + a = transa*a + b = transb*b + # we need some zero element for an empty context + # sadly union(zero(AABB), ...) doesn't work for this + if a == AABB{Float32}(Vec3f0(0), Vec3f0(0)) + return b + elseif b == AABB{Float32}(Vec3f0(0), Vec3f0(0)) + return a + end + union(a, b) + end + transformation(x, transformation(context)) + push!(context.children, x) + context +end + + +export transformation diff --git a/src/GLMakie.jl b/src/GLMakie.jl new file mode 100644 index 00000000000..2322e8d17da --- /dev/null +++ b/src/GLMakie.jl @@ -0,0 +1,101 @@ +module GLMakie + +using ModernGL, GLFW, FixedPointNumbers, Colors, GeometryTypes +using AbstractPlotting, StaticArrays +using ..Makie +using AbstractPlotting: Scene, Lines, Text, Image, Heatmap, Scatter, @key_str, Key, broadcast_foreach +using AbstractPlotting: convert_attribute, @extractvalue, LineSegments, to_ndim, NativeFont +using AbstractPlotting: @get_attribute, to_value, to_colormap, extrema_nan +using Base: RefValue +import Base: push!, isopen, show +using FileIO +using ImageCore +import IntervalSets +using IntervalSets: ClosedInterval, (..) +using Base.Iterators: repeated, drop +using FreeType, FreeTypeAbstraction, FixedPointNumbers + +for name in names(AbstractPlotting) + @eval import AbstractPlotting: $(name) +end + +include("GLAbstraction/GLAbstraction.jl") +using .GLAbstraction + +const atlas_texture_cache = Dict{Any, Tuple{Texture{Float16, 2}, Function}}() + +function get_texture!(atlas) + # clean up dead context! + filter!(atlas_texture_cache) do (ctx, tex_func) + if GLAbstraction.context_alive(ctx) + true + else + AbstractPlotting.remove_font_render_callback!(tex_func[2]) + false + end + end + tex, func = get!(atlas_texture_cache, GLAbstraction.current_context()) do + tex = Texture( + atlas.data, + minfilter = :linear, + magfilter = :linear, + anisotropic = 16f0, + ) + # update the texture, whenever a new font is added to the atlas + function callback(distance_field, rectangle) + ctx = tex.context + if GLAbstraction.context_alive(ctx) + prev_ctx = GLAbstraction.current_context() + GLAbstraction.switch_context!(ctx) + tex[rectangle] = distance_field + GLAbstraction.switch_context!(prev_ctx) + end + end + AbstractPlotting.font_render_callback!(callback) + return (tex, callback) + end + tex +end + +include("GLVisualize/GLVisualize.jl") +using .GLVisualize + +include("glwindow.jl") +include("screen.jl") +include("rendering.jl") +include("events.jl") +include("drawing_primitives.jl") + +struct GLBackend <: AbstractPlotting.AbstractBackend +end +function AbstractPlotting.backend_display(x::GLBackend, scene::Scene) + screen = global_gl_screen() + # This should only get called if inline display false, so we display the window + GLFW.set_visibility!(to_native(screen), true) + display(screen, scene) +end + +colorbuffer(screen) = error("Color buffer retrieval not implemented for $(typeof(screen))") + +""" + scene2image(scene::Scene) + +Buffers the `scene` in an image buffer. +""" +function scene2image(scene::Scene) + screen = global_gl_screen() + display(screen, scene) + colorbuffer(screen) +end + +function AbstractPlotting.backend_show(::GLBackend, io::IO, m::MIME"image/png", scene::Scene) + img = scene2image(scene) + GLFW.set_visibility!(to_native(global_gl_screen()), !AbstractPlotting.use_display[]) + FileIO.save(FileIO.Stream(FileIO.format"PNG", io), img) +end + +function __init__() + AbstractPlotting.register_backend!(GLBackend()) +end + +end diff --git a/src/GLVisualize/GLVisualize.jl b/src/GLVisualize/GLVisualize.jl new file mode 100644 index 00000000000..030bc51d653 --- /dev/null +++ b/src/GLVisualize/GLVisualize.jl @@ -0,0 +1,81 @@ +module GLVisualize + +using ..GLAbstraction +using ..Makie: RaymarchAlgorithm, IsoValue, Absorption, MaximumIntensityProjection, AbsorptionRGBA, IndexedAbsorptionRGBA + +using GLFW +using ModernGL +using StaticArrays +using GeometryTypes +using Colors +using AbstractPlotting +using FixedPointNumbers +using FileIO +using FreeType +import IterTools +using Markdown +using FreeTypeAbstraction +using ImageCore +import ColorVectorSpace +using Observables + +import ImageCore +import AxisArrays, ImageAxes + +import Base: merge, convert, show +using Base.Iterators: Repeated, repeated +using LinearAlgebra + +using IndirectArrays +const HasAxesArray{T, N} = AxisArrays.AxisArray{T, N} +const AxisMatrix{T} = HasAxesArray{T, 2} + +import AbstractPlotting: to_font, glyph_uv_width!, glyph_scale! +import ..GLMakie: get_texture! + +const GLBoundingBox = AABB{Float32} + +""" +Replacement of Pkg.dir("GLVisualize") --> GLVisualize.dir, +returning the correct path +""" +dir(dirs...) = joinpath(@__DIR__, dirs...) + +""" +returns path relative to the assets folder +""" +assetpath(folders...) = dir("assets", folders...) + +""" +Loads a file from the asset folder +""" +function loadasset(folders...; kw_args...) + path = assetpath(folders...) + isfile(path) || isdir(path) || error("Could not locate file at $path") + load(path; kw_args...) +end + +export assetpath, loadasset + + +include("types.jl") +export CIRCLE, RECTANGLE, ROUNDED_RECTANGLE, DISTANCEFIELD, TRIANGLE + +include("boundingbox.jl") + +include("visualize_interface.jl") +export visualize # Visualize an object +export visualize_default # get the default parameter for a visualization + +include("utils.jl") +export y_partition, y_partition_abs +export x_partition, x_partition_abs +export loop, bounce + +include(joinpath("visualize", "lines.jl")) +include(joinpath("visualize", "image_like.jl")) +include(joinpath("visualize", "mesh.jl")) +include(joinpath("visualize", "particles.jl")) +include(joinpath("visualize", "surface.jl")) + +end # module diff --git a/src/GLVisualize/assets/cat.obj b/src/GLVisualize/assets/cat.obj new file mode 100644 index 00000000000..efa6392518e --- /dev/null +++ b/src/GLVisualize/assets/cat.obj @@ -0,0 +1,10667 @@ +# +# +mtllib cat.mtl +v 0.000000 0.000000 0.000000 +v 0.062805 0.591207 0.902102 +v 0.058382 0.577691 0.904429 +v 0.066943 0.562335 0.904249 +v 0.033097 0.589028 0.925956 +v 0.034467 0.615638 0.897269 +v 0.018170 0.614425 0.904328 +v 0.039929 0.575789 0.919507 +v -0.018169 0.614425 0.904328 +v 0.000000 0.613796 0.908653 +v 0.000000 0.641496 0.868732 +v 0.015936 0.589077 0.933549 +v 0.020526 0.563241 0.924047 +v 0.025985 0.560463 0.922278 +v 0.028212 0.559800 0.917325 +v 0.026834 0.551429 0.916425 +v 0.023260 0.561339 0.908443 +v 0.016448 0.544276 0.929197 +v 0.012180 0.564820 0.930930 +v 0.023731 0.547379 0.919073 +v 0.025774 0.546715 0.913954 +v 0.024734 0.544564 0.916441 +v 0.027570 0.544739 0.913519 +v 0.026477 0.543011 0.916041 +v 0.032224 0.545480 0.914860 +v 0.030407 0.541228 0.917163 +v 0.020185 0.542870 0.924015 +v 0.023818 0.535506 0.924229 +v 0.023345 0.539542 0.922526 +v 0.045879 0.538628 0.920548 +v 0.044517 0.531227 0.926361 +v 0.070474 0.541001 0.910776 +v 0.039566 0.523852 0.930703 +v 0.062543 0.523955 0.917943 +v 0.023185 0.526806 0.934812 +v 0.021080 0.518292 0.942183 +v 0.030756 0.513881 0.937922 +v 0.024926 0.507784 0.943052 +v 0.017290 0.508326 0.947117 +v 0.006100 0.513254 0.956253 +v 0.004658 0.506358 0.954034 +v 0.015855 0.522666 0.949863 +v 0.016543 0.532934 0.942451 +v 0.007179 0.524737 0.951935 +v 0.013325 0.513565 0.952712 +v 0.000000 0.525294 0.952540 +v -0.006100 0.513254 0.956253 +v -0.004658 0.506358 0.954034 +v 0.010022 0.546346 0.935696 +v 0.007572 0.534506 0.944946 +v 0.000000 0.534982 0.945541 +v -0.007179 0.524737 0.951935 +v -0.010595 0.507868 0.952081 +v -0.013325 0.513565 0.952712 +v -0.017057 0.508274 0.947300 +v -0.017290 0.508326 0.947117 +v -0.015855 0.522666 0.949863 +v -0.007572 0.534506 0.944946 +v 0.000000 0.545261 0.937148 +v -0.024926 0.507784 0.943052 +v -0.021080 0.518292 0.942183 +v -0.016543 0.532934 0.942451 +v -0.010022 0.546346 0.935696 +v 0.000000 0.564028 0.935223 +v 0.000000 0.587694 0.935875 +v -0.012180 0.564820 0.930930 +v -0.016448 0.544276 0.929197 +v -0.023185 0.526806 0.934812 +v -0.015936 0.589077 0.933549 +v -0.020526 0.563241 0.924047 +v -0.025985 0.560463 0.922278 +v -0.023731 0.547379 0.919073 +v -0.039929 0.575789 0.919507 +v -0.033097 0.589028 0.925956 +v -0.058014 0.577594 0.903794 +v -0.062085 0.545563 0.910818 +v -0.066575 0.562239 0.903614 +v -0.077677 0.566059 0.892515 +v -0.062805 0.591207 0.902102 +v -0.034467 0.615638 0.897269 +v -0.054697 0.628515 0.859013 +v -0.045764 0.620904 0.876901 +v -0.072070 0.604157 0.882089 +v -0.060893 0.613364 0.873307 +v -0.072355 0.618005 0.856329 +v -0.071558 0.622247 0.839233 +v -0.096607 0.569740 0.879123 +v -0.070474 0.541001 0.910776 +v -0.076344 0.599618 0.807587 +v -0.053919 0.593748 0.816296 +v -0.091944 0.594970 0.826001 +v -0.047371 0.596641 0.804772 +v -0.053052 0.583997 0.802882 +v -0.093541 0.656137 0.853663 +v -0.084997 0.655048 0.842840 +v -0.082154 0.672327 0.860033 +v -0.092121 0.629276 0.830749 +v -0.075541 0.635992 0.815726 +v -0.054751 0.614456 0.805808 +v -0.036222 0.608996 0.812719 +v -0.033089 0.604172 0.818217 +v -0.042066 0.629218 0.840712 +v -0.048088 0.635161 0.817770 +v -0.079500 0.681048 0.866922 +v -0.072711 0.681979 0.869169 +v -0.079770 0.692510 0.878871 +v -0.086298 0.688909 0.877313 +v -0.074201 0.673010 0.858285 +v -0.072288 0.654556 0.834719 +v -0.051465 0.656201 0.834503 +v -0.042729 0.638989 0.843174 +v -0.050969 0.655414 0.852687 +v -0.064494 0.674607 0.862264 +v -0.068326 0.676240 0.872114 +v -0.039168 0.635250 0.859752 +v -0.083315 0.697776 0.888019 +v -0.089516 0.696958 0.884740 +v 0.007344 0.503339 0.951068 +v 0.000000 0.494430 0.945069 +v 0.000000 0.494228 0.944871 +v 0.011911 0.499628 0.947190 +v 0.009311 0.503336 0.946713 +v 0.005391 0.498697 0.946391 +v 0.007324 0.501978 0.951564 +v 0.004681 0.506294 0.953246 +v 0.000000 0.498405 0.951087 +v -0.009311 0.503336 0.946713 +v -0.011911 0.499628 0.947190 +v -0.005267 0.496540 0.946730 +v -0.007344 0.503339 0.951068 +v -0.005391 0.498697 0.946391 +v -0.007324 0.501978 0.951564 +v 0.000000 0.503954 0.954091 +v -0.005718 0.508726 0.949447 +v -0.003858 0.507618 0.945617 +v -0.004380 0.511670 0.952013 +v -0.004681 0.506294 0.953246 +v 0.000000 0.512876 0.957148 +v -0.009116 0.513522 0.951314 +v -0.010481 0.507772 0.951328 +v -0.012150 0.506681 0.947089 +v -0.006602 0.510906 0.945843 +v -0.009457 0.511556 0.946130 +v 0.000000 0.487664 0.940648 +v -0.002846 0.486017 0.942430 +v -0.006257 0.480187 0.935303 +v -0.013110 0.487988 0.944418 +v -0.023491 0.491187 0.945636 +v -0.027460 0.499854 0.945737 +v -0.013838 0.505851 0.947647 +v -0.030756 0.513881 0.937922 +v -0.038551 0.499020 0.936530 +v -0.031325 0.478783 0.928159 +v -0.014822 0.478463 0.935845 +v -0.012336 0.476009 0.929822 +v -0.021350 0.474344 0.919333 +v -0.022442 0.488632 0.922772 +v -0.032758 0.481841 0.911095 +v -0.032460 0.490630 0.911148 +v -0.030054 0.490716 0.909323 +v -0.021001 0.489018 0.920193 +v -0.015567 0.485847 0.927916 +v -0.015070 0.483781 0.929436 +v -0.005476 0.477412 0.931469 +v -0.017316 0.488169 0.925004 +v -0.006475 0.484377 0.924278 +v -0.005455 0.483959 0.927933 +v -0.005078 0.484906 0.930389 +v 0.000000 0.485034 0.937825 +v 0.005476 0.477412 0.931469 +v 0.006257 0.480187 0.935303 +v 0.005078 0.484906 0.930389 +v 0.005455 0.483959 0.927933 +v 0.015567 0.485847 0.927916 +v 0.006475 0.484377 0.924278 +v 0.015070 0.483781 0.929436 +v -0.006341 0.496218 0.924619 +v 0.012336 0.476009 0.929822 +v 0.022442 0.488632 0.922772 +v 0.021001 0.489018 0.920193 +v 0.017316 0.488169 0.925004 +v 0.017104 0.488689 0.916203 +v 0.023548 0.489921 0.907373 +v 0.030054 0.490716 0.909323 +v 0.027697 0.490703 0.901958 +v 0.033577 0.490812 0.904416 +v 0.030399 0.491833 0.896731 +v 0.018381 0.496908 0.916132 +v 0.013228 0.496491 0.921146 +v 0.037331 0.490755 0.900791 +v 0.033267 0.489128 0.894022 +v 0.037378 0.487375 0.900051 +v 0.028816 0.485356 0.899999 +v 0.032617 0.485306 0.906091 +v 0.017140 0.480570 0.912367 +v 0.019688 0.478466 0.917099 +v 0.011422 0.480092 0.919602 +v 0.038899 0.486727 0.902280 +v 0.040171 0.486574 0.903462 +v 0.034022 0.487724 0.908344 +v 0.031072 0.498233 0.893920 +v -0.019688 0.478466 0.917099 +v -0.032617 0.485306 0.906091 +v -0.034022 0.487724 0.908344 +v -0.017140 0.480570 0.912367 +v -0.011422 0.480092 0.919602 +v 0.000000 0.478611 0.923592 +v 0.011813 0.478747 0.925901 +v 0.020415 0.480124 0.919106 +v -0.011958 0.481091 0.928231 +v 0.000000 0.481659 0.930638 +v 0.011958 0.481091 0.928231 +v 0.020742 0.476305 0.918394 +v 0.035132 0.487429 0.910122 +v 0.036404 0.483712 0.908767 +v 0.020541 0.472294 0.917587 +v 0.025395 0.467603 0.894270 +v -0.025395 0.467603 0.894270 +v 0.000000 0.465880 0.886704 +v 0.000000 0.464362 0.906704 +v 0.017791 0.464925 0.911516 +v 0.012426 0.473075 0.928738 +v 0.012539 0.479503 0.929278 +v -0.020541 0.472294 0.917587 +v -0.036404 0.483712 0.908767 +v -0.017791 0.464925 0.911516 +v 0.000000 0.464928 0.922437 +v 0.007380 0.466782 0.920237 +v 0.000000 0.472951 0.931947 +v 0.000000 0.480910 0.931850 +v -0.012539 0.479503 0.929278 +v -0.012426 0.473075 0.928738 +v -0.007380 0.466782 0.920237 +v -0.020742 0.476305 0.918394 +v -0.011813 0.478747 0.925901 +v -0.020415 0.480124 0.919106 +v 0.000000 0.478720 0.928736 +v -0.035132 0.487429 0.910122 +v -0.029836 0.467053 0.877065 +v 0.000000 0.466146 0.875279 +v -0.050248 0.480041 0.892863 +v -0.042480 0.484901 0.901858 +v -0.040171 0.486574 0.903462 +v -0.035945 0.466764 0.860661 +v -0.058437 0.476442 0.879673 +v -0.060531 0.489768 0.896619 +v -0.044525 0.488616 0.903502 +v -0.041200 0.487288 0.904324 +v -0.038899 0.486727 0.902280 +v -0.028816 0.485356 0.899999 +v -0.037378 0.487375 0.900051 +v -0.019404 0.474029 0.909763 +v -0.033267 0.489128 0.894022 +v -0.037331 0.490755 0.900791 +v -0.039894 0.490750 0.903130 +v -0.030399 0.491833 0.896731 +v -0.027580 0.498891 0.901575 +v -0.043223 0.490192 0.910432 +v -0.054138 0.497968 0.908208 +v -0.036515 0.485363 0.908901 +v -0.035752 0.491047 0.906428 +v -0.033577 0.490812 0.904416 +v -0.027697 0.490703 0.901958 +v -0.042487 0.488050 0.918523 +v -0.023548 0.489921 0.907373 +v -0.017104 0.488689 0.916203 +v -0.022216 0.497232 0.909661 +v -0.018381 0.496908 0.916132 +v 0.000000 0.483617 0.928299 +v 0.000000 0.483453 0.931661 +v 0.054635 0.542201 0.907169 +v 0.060816 0.552579 0.906197 +v 0.044790 0.554355 0.908494 +v 0.044364 0.559576 0.908494 +v 0.059773 0.564652 0.906250 +v 0.042915 0.563347 0.908658 +v 0.051905 0.573807 0.907307 +v 0.040982 0.564806 0.908918 +v 0.040219 0.576547 0.908964 +v 0.029179 0.571827 0.910587 +v 0.039314 0.563200 0.909176 +v 0.038545 0.559131 0.909334 +v 0.023002 0.561451 0.911558 +v 0.038989 0.554132 0.909328 +v 0.024044 0.549382 0.911505 +v 0.040453 0.549985 0.909166 +v 0.031908 0.540227 0.910449 +v 0.042367 0.548697 0.908907 +v 0.043592 0.537484 0.908793 +v 0.044014 0.550359 0.908651 +v 0.061353 0.552454 0.905998 +v 0.054236 0.554245 0.912217 +v 0.050347 0.547717 0.912828 +v 0.054991 0.541774 0.906999 +v 0.031104 0.552234 0.915558 +v 0.036051 0.546475 0.914893 +v 0.042766 0.557059 0.917195 +v 0.043401 0.544750 0.913851 +v 0.043628 0.536920 0.908671 +v 0.055300 0.541334 0.906498 +v 0.061843 0.552320 0.905469 +v 0.060739 0.565100 0.905525 +v 0.060279 0.564879 0.906053 +v 0.043612 0.536339 0.908219 +v 0.056011 0.584354 0.892362 +v 0.052411 0.574792 0.906644 +v 0.040040 0.577693 0.908399 +v 0.052182 0.574301 0.907141 +v 0.040156 0.577120 0.908847 +v 0.028353 0.572697 0.910120 +v 0.028795 0.572263 0.910518 +v 0.021812 0.561712 0.911149 +v 0.022438 0.561584 0.911518 +v 0.022915 0.548934 0.911093 +v 0.023510 0.549164 0.911464 +v 0.031242 0.539242 0.909974 +v 0.031603 0.539743 0.910376 +v 0.030448 0.559826 0.915591 +v 0.034334 0.566353 0.914980 +v 0.041279 0.569323 0.913958 +v 0.053580 0.561840 0.912250 +v 0.048630 0.567599 0.912915 +v 0.042414 0.524935 0.894793 +v -0.032600 0.556445 0.848283 +v -0.007855 0.563396 0.872248 +v -0.009431 0.545103 0.872149 +v -0.021329 0.531229 0.870399 +v -0.039003 0.527072 0.867668 +v -0.055702 0.534221 0.864998 +v -0.065049 0.549944 0.863410 +v -0.063472 0.568237 0.863510 +v -0.051575 0.582111 0.865259 +v -0.017201 0.579119 0.870660 +v -0.033901 0.586268 0.867990 +v -0.069859 0.569374 0.890251 +v -0.071561 0.549627 0.890143 +v -0.031973 0.539199 0.910133 +v -0.044321 0.536296 0.908226 +v -0.024362 0.529422 0.897688 +v -0.043442 0.524935 0.894740 +v -0.055987 0.541291 0.906363 +v -0.062515 0.552275 0.905254 +v -0.061471 0.532652 0.891858 +v -0.061414 0.565054 0.905324 +v -0.053103 0.574746 0.906545 +v -0.040875 0.577078 0.908898 +v -0.040756 0.577651 0.908452 +v -0.052877 0.574253 0.907044 +v -0.060955 0.564831 0.905857 +v -0.062025 0.552410 0.905789 +v -0.055680 0.541733 0.906867 +v -0.044340 0.536877 0.908679 +v -0.054904 0.561844 0.912047 +v -0.055558 0.554251 0.912005 +v -0.029532 0.572225 0.910710 +v -0.042630 0.569330 0.913906 +v -0.049966 0.567603 0.912772 +v -0.044248 0.557073 0.917110 +v -0.051680 0.547725 0.912664 +v -0.044748 0.544756 0.913772 +v -0.037410 0.546480 0.914905 +v -0.032470 0.552240 0.915631 +v -0.031815 0.559835 0.915673 +v -0.024254 0.549120 0.911721 +v -0.023183 0.561546 0.911789 +v -0.035697 0.566363 0.915013 +v -0.032336 0.539698 0.910533 +v -0.023660 0.548892 0.911355 +v -0.022558 0.561673 0.911424 +v -0.029089 0.572658 0.910316 +v -0.057015 0.584352 0.892139 +v -0.037935 0.588840 0.895088 +v -0.019907 0.581122 0.897970 +v -0.009816 0.564148 0.899685 +v -0.011518 0.544401 0.899577 +v -0.118724 0.492069 0.911788 +v -0.118740 0.492381 0.911599 +v -0.146375 0.494266 0.901085 +v -0.084284 0.493044 0.922345 +v -0.084273 0.493505 0.922075 +v -0.039627 0.497751 0.928503 +v -0.039592 0.498296 0.928203 +v -0.051759 0.623494 0.932651 +v -0.051703 0.623505 0.932969 +v -0.063602 0.639021 0.946902 +v -0.042719 0.609925 0.921511 +v -0.042631 0.609967 0.921971 +v -0.034414 0.589767 0.910745 +v -0.034312 0.589854 0.911288 +v -0.066964 0.623486 0.923543 +v -0.066921 0.623727 0.923847 +v -0.086767 0.641721 0.934606 +v -0.051295 0.607591 0.915384 +v -0.051232 0.607965 0.915803 +v -0.034488 0.584273 0.909916 +v -0.034425 0.584749 0.910387 +v -0.085901 0.617085 0.951150 +v -0.085811 0.617420 0.951508 +v -0.109777 0.619526 0.973195 +v -0.062665 0.605468 0.931544 +v -0.062561 0.606024 0.931996 +v -0.037708 0.584291 0.913323 +v -0.037601 0.584981 0.913829 +v -0.023028 0.460129 0.945372 +v -0.023287 0.460222 0.945371 +v -0.029875 0.435328 0.961761 +v -0.018073 0.485126 0.936087 +v -0.018388 0.485246 0.936087 +v -0.050683 0.463462 0.953236 +v -0.050908 0.463724 0.953151 +v -0.071943 0.439924 0.965138 +v -0.025147 0.489308 0.939038 +v -0.025413 0.489627 0.938939 +v -0.086096 0.453885 0.941486 +v -0.086245 0.454171 0.941317 +v -0.115680 0.442883 0.944002 +v -0.056608 0.469126 0.937139 +v -0.056794 0.469550 0.936898 +v -0.028447 0.487769 0.932756 +v -0.028657 0.488285 0.932474 +v -0.060439 0.479688 0.950187 +v -0.060499 0.479998 0.950017 +v -0.092094 0.468081 0.958620 +v -0.027520 0.493205 0.940401 +v -0.027580 0.493578 0.940201 +v -0.143080 0.469171 0.916943 +v -0.143130 0.469394 0.916797 +v -0.167800 0.460731 0.912432 +v -0.113743 0.477905 0.922249 +v -0.113794 0.478238 0.922038 +v -0.082196 0.483559 0.927865 +v -0.082235 0.484051 0.927565 +v -0.033992 0.493576 0.933496 +v -0.034017 0.494166 0.933156 +v 0.044238 0.609317 0.921971 +v 0.033946 0.590138 0.911288 +v 0.034038 0.590042 0.910745 +v 0.044321 0.609266 0.921511 +v 0.054620 0.621878 0.932970 +v 0.054675 0.621862 0.932651 +v 0.068013 0.636123 0.946902 +v -0.020162 0.490400 0.923640 +v -0.025317 0.490529 0.920489 +v -0.015775 0.482642 0.922491 +v 0.051232 0.607965 0.915803 +v 0.034425 0.584749 0.910387 +v 0.034488 0.584273 0.909916 +v 0.051295 0.607591 0.915384 +v 0.066921 0.623727 0.923847 +v 0.066965 0.623486 0.923543 +v 0.086767 0.641721 0.934606 +v -0.015671 0.484411 0.923661 +v 0.067383 0.600045 0.931996 +v 0.038462 0.584901 0.913829 +v 0.038417 0.584204 0.913324 +v 0.067364 0.599480 0.931544 +v 0.092548 0.606141 0.951508 +v 0.092563 0.605794 0.951150 +v 0.116402 0.603011 0.973195 +v 0.030415 0.461745 0.945371 +v 0.018951 0.484522 0.936087 +v 0.018681 0.484321 0.936087 +v 0.030190 0.461585 0.945372 +v 0.043470 0.439548 0.961761 +v 0.050908 0.463724 0.953151 +v 0.025413 0.489627 0.938939 +v 0.025147 0.489308 0.939038 +v 0.050683 0.463462 0.953236 +v 0.071943 0.439924 0.965138 +v 0.056794 0.469550 0.936898 +v 0.028657 0.488285 0.932474 +v 0.028447 0.487769 0.932756 +v 0.056608 0.469126 0.937139 +v 0.086245 0.454171 0.941317 +v 0.086096 0.453885 0.941486 +v 0.115680 0.442883 0.944002 +v 0.060082 0.478537 0.950017 +v 0.027526 0.492966 0.940201 +v 0.027456 0.492595 0.940401 +v 0.060014 0.478228 0.950187 +v 0.091357 0.465804 0.958620 +v 0.083845 0.490214 0.927565 +v 0.034754 0.494366 0.933156 +v 0.034801 0.493778 0.933496 +v 0.083867 0.489721 0.927865 +v 0.115879 0.488298 0.922038 +v 0.115869 0.487962 0.922249 +v 0.146074 0.483102 0.916797 +v 0.146052 0.482875 0.916943 +v 0.171623 0.477555 0.912406 +v 0.083458 0.507215 0.922075 +v 0.039514 0.497822 0.928203 +v 0.039717 0.497315 0.928503 +v 0.083613 0.506780 0.922345 +v 0.116554 0.516904 0.911599 +v 0.116637 0.516602 0.911788 +v 0.142221 0.527319 0.901085 +v -0.029932 0.481730 0.906794 +v -0.021651 0.479147 0.914452 +v -0.000452 0.487042 0.931874 +v -0.010058 0.481781 0.927060 +v -0.008882 0.486855 0.931697 +v -0.003590 0.482318 0.927934 +v 0.000000 0.476386 0.927823 +v -0.004470 0.482353 0.928269 +v -0.014211 0.476377 0.924473 +v -0.008624 0.476194 0.927199 +v -0.015844 0.489611 0.924910 +v -0.014987 0.482289 0.925926 +v -0.018103 0.477155 0.922055 +v -0.014603 0.476860 0.924191 +v -0.062843 0.615441 0.867341 +v -0.036144 0.635913 0.857637 +v -0.053538 0.657635 0.872006 +v -0.077489 0.651241 0.881432 +v -0.066615 0.676905 0.879527 +v -0.082060 0.671245 0.883039 +v -0.081286 0.696441 0.886063 +v -0.086140 0.696305 0.884325 +v -0.089448 0.692009 0.883025 +v -0.092188 0.667592 0.863195 +v -0.094462 0.644488 0.852128 +v -0.089939 0.604378 0.840891 +v -0.031031 0.514655 0.904191 +v -0.065079 0.030394 0.674303 +v -0.064264 0.023035 0.688163 +v -0.061825 0.034829 0.676866 +v -0.065311 0.035034 0.676976 +v -0.062419 0.022926 0.688105 +v -0.061593 0.030189 0.674193 +v -0.066549 0.022794 0.689812 +v -0.068516 0.025398 0.691213 +v -0.069209 0.029880 0.675810 +v -0.068393 0.022905 0.689867 +v -0.069441 0.034592 0.678355 +v -0.066671 0.025287 0.691158 +v -0.065722 0.029672 0.675706 +v -0.065954 0.034384 0.678251 +v -0.094726 0.022557 0.675144 +v -0.094102 0.020109 0.673868 +v -0.092362 0.020686 0.674188 +v -0.095690 0.031005 0.661864 +v -0.094510 0.026380 0.659454 +v -0.092986 0.023133 0.675463 +v -0.091221 0.027471 0.660057 +v -0.092402 0.032096 0.662468 +v -0.008732 0.498493 -0.043835 +v -0.029362 0.498982 -0.040975 +v -0.025960 0.473242 -0.042256 +v 0.000000 0.490837 -0.043917 +v -0.001856 0.498723 -0.041769 +v 0.000000 0.497766 -0.041785 +v -0.058393 0.523958 -0.008919 +v -0.052404 0.476652 -0.055549 +v -0.033753 0.466584 -0.047170 +v -0.036102 0.439811 -0.049881 +v -0.068324 0.410550 -0.054990 +v -0.081393 0.546869 0.157532 +v -0.039228 0.585821 0.152889 +v -0.039228 0.581339 0.094585 +v -0.090336 0.548536 0.103149 +v -0.045288 0.575140 0.053769 +v -0.083477 0.537783 0.046699 +v -0.092578 0.478264 -0.021432 +v -0.106921 0.410533 -0.010444 +v -0.112587 0.360073 0.000270 +v -0.112319 0.481515 0.044620 +v -0.129416 0.416836 0.054430 +v -0.136542 0.363802 0.063123 +v -0.120530 0.492458 0.154213 +v -0.131191 0.429177 0.178254 +v -0.142545 0.364635 0.179035 +v -0.136009 0.310889 0.073633 +v -0.117772 0.305628 0.012279 +v -0.141551 0.259373 0.065677 +v -0.119963 0.265910 0.008569 +v -0.095664 0.427772 0.214796 +v -0.098341 0.347819 0.212912 +v -0.144363 0.304571 0.157733 +v -0.139715 0.244884 0.125962 +v -0.140822 0.202625 0.043883 +v -0.136715 0.192736 0.076758 +v -0.145231 0.147575 -0.004373 +v -0.103778 0.135342 -0.064655 +v -0.124163 0.121612 -0.035015 +v -0.125333 0.150633 -0.037315 +v -0.142148 0.119618 -0.007934 +v -0.122875 0.211689 -0.000436 +v -0.103099 0.150372 -0.063820 +v -0.084011 0.122397 -0.026880 +v -0.091752 0.058141 0.018016 +v -0.122997 0.056607 0.020205 +v -0.143807 0.058160 0.015152 +v -0.082975 0.149033 -0.025392 +v -0.100665 0.018615 0.058942 +v -0.123089 0.016291 0.053555 +v -0.147309 0.018596 0.056544 +v -0.147480 0.012821 0.065522 +v -0.157149 0.016365 0.070544 +v -0.140894 0.003871 0.080112 +v -0.151267 0.067281 0.030444 +v -0.156339 0.024025 0.062603 +v -0.090966 0.024148 0.065907 +v -0.101416 0.012835 0.067892 +v -0.123561 0.009757 0.062694 +v -0.124384 0.003627 0.078650 +v -0.125129 0.001455 0.093080 +v -0.145385 0.001033 0.086432 +v -0.125270 -0.002068 0.100828 +v -0.140503 -0.000110 0.095038 +v -0.154386 0.001069 0.087047 +v -0.141724 0.003655 0.107508 +v -0.139544 0.002114 0.107208 +v -0.126445 0.002050 0.118569 +v -0.112246 0.002114 0.108617 +v -0.126622 0.006506 0.122010 +v -0.110108 0.003655 0.109139 +v -0.145079 0.001707 0.117517 +v -0.126693 0.003569 0.123373 +v -0.133916 0.000690 0.152218 +v -0.129567 0.004156 0.126653 +v -0.128270 0.002714 0.153926 +v -0.122164 0.000691 0.152825 +v -0.124172 0.004156 0.126931 +v -0.120748 -0.001556 0.145421 +v -0.120777 0.001020 0.130564 +v -0.107801 0.001707 0.119441 +v -0.109239 0.003342 0.121202 +v -0.111844 0.000884 0.127091 +v -0.112444 -0.000920 0.144478 +v -0.109436 0.001812 0.148302 +v -0.101467 0.002780 0.132422 +v -0.093837 0.001430 0.126526 +v -0.095430 -0.001060 0.125582 +v -0.096192 -0.000459 0.116296 +v -0.094452 0.001844 0.113039 +v -0.102130 -0.000476 0.120612 +v -0.099523 0.000169 0.128104 +v -0.104966 0.002533 0.120247 +v -0.108114 0.003871 0.081804 +v -0.104296 0.001033 0.088553 +v -0.109522 -0.000110 0.096637 +v -0.049003 0.120142 0.624316 +v -0.040524 0.051822 0.622585 +v -0.042177 0.077235 0.611367 +v -0.044403 0.100253 0.609560 +v -0.037021 0.041602 0.594952 +v -0.039465 0.042730 0.628291 +v -0.039785 0.071025 0.598902 +v -0.037431 0.101624 0.593130 +v -0.039550 0.117444 0.591167 +v -0.037053 0.141207 0.597753 +v -0.046695 0.144277 0.629983 +v -0.036250 0.200833 0.615936 +v -0.035094 0.072230 0.589550 +v -0.042807 0.200773 0.572693 +v -0.035090 0.091937 0.589698 +v -0.044416 0.070883 0.580579 +v -0.045051 0.090645 0.574505 +v -0.050052 0.039258 0.586645 +v -0.034824 0.022946 0.598633 +v -0.025333 0.018856 0.630556 +v -0.023741 0.015313 0.653802 +v -0.028864 -0.000125 0.650216 +v -0.028615 0.030963 0.646801 +v -0.038178 0.042874 0.647083 +v -0.065598 0.052043 0.642074 +v -0.065580 0.059150 0.637633 +v -0.070822 0.120951 0.637097 +v -0.071390 0.145822 0.643662 +v -0.104295 0.145236 0.622379 +v -0.093510 0.119876 0.618848 +v -0.090245 0.051361 0.622757 +v -0.091205 0.042311 0.628206 +v -0.095203 0.043958 0.646175 +v -0.107040 0.019007 0.630444 +v -0.103896 0.031531 0.645891 +v -0.106929 0.016156 0.653957 +v -0.101599 0.000122 0.630801 +v -0.097061 0.041467 0.594862 +v -0.099351 0.022700 0.598619 +v -0.095721 0.001350 0.618441 +v -0.084541 0.002498 0.644298 +v -0.087497 0.003367 0.644951 +v -0.091738 0.004001 0.657261 +v -0.093507 0.001164 0.652803 +v -0.097580 -0.000184 0.650031 +v -0.099267 0.002401 0.650843 +v -0.096304 0.000162 0.640515 +v -0.090431 0.000281 0.645264 +v -0.097920 0.002430 0.637009 +v -0.101806 0.000621 0.650816 +v -0.096121 0.027665 0.675615 +v -0.092561 0.027229 0.669678 +v -0.091301 0.028563 0.678493 +v -0.068361 0.026350 0.690833 +v -0.069325 0.033083 0.685950 +v -0.065335 0.023833 0.685957 +v -0.065335 0.052816 0.668919 +v -0.103760 0.025363 0.659156 +v -0.095727 0.030127 0.671315 +v -0.095457 0.042330 0.651980 +v -0.088996 0.033064 0.676645 +v -0.042157 0.032400 0.675818 +v -0.037787 0.041718 0.654614 +v -0.065335 0.053056 0.660654 +v -0.026906 0.024299 0.659443 +v -0.034916 0.028599 0.671942 +v -0.060767 0.031704 0.685722 +v -0.039369 0.026980 0.678800 +v -0.038109 0.025905 0.669947 +v -0.034549 0.026175 0.675875 +v -0.041790 0.005603 0.665444 +v -0.046453 0.000273 0.675323 +v -0.062771 0.024621 0.690947 +v -0.065335 0.003786 0.678423 +v -0.028481 0.311677 0.684214 +v -0.006463 0.281724 0.652156 +v 0.008124 0.279935 0.584455 +v 0.020477 0.281556 0.650449 +v 0.006463 0.281724 0.652156 +v 0.000000 0.283168 0.653437 +v -0.154205 0.000173 0.125282 +v -0.158017 -0.001060 0.122351 +v -0.156303 -0.000459 0.113193 +v -0.150841 -0.000476 0.118098 +v -0.147983 0.002533 0.118027 +v -0.157698 0.001844 0.109775 +v -0.159699 0.001430 0.123126 +v -0.152716 0.002805 0.129774 +v -0.160955 -0.000227 0.103503 +v -0.162159 -0.000300 0.122924 +v -0.155423 0.001588 0.140968 +v -0.154169 0.025035 0.142425 +v -0.157922 0.025294 0.148018 +v -0.167310 0.014712 0.126146 +v -0.166245 0.018139 0.103410 +v -0.130484 0.023679 0.164197 +v -0.131868 -0.000340 0.157063 +v -0.153389 0.026087 0.151077 +v -0.156115 0.040208 0.125532 +v -0.157329 0.027807 0.143935 +v -0.164509 0.023516 0.131605 +v -0.163985 0.029882 0.118901 +v -0.155581 0.041952 0.119958 +v -0.127308 0.050947 0.135289 +v -0.125994 0.049990 0.104873 +v -0.100250 0.041511 0.123066 +v -0.150344 0.038657 0.092153 +v -0.150243 0.042773 0.080293 +v -0.125240 0.056000 0.091337 +v -0.097590 0.085739 0.058757 +v -0.125325 0.093362 0.067083 +v -0.098803 0.043066 0.082483 +v -0.099932 0.039063 0.094404 +v -0.086957 0.018155 0.107672 +v -0.151881 0.082779 0.051214 +v -0.141282 0.120477 0.031399 +v -0.130345 0.124267 0.044141 +v -0.103261 0.121807 0.039355 +v -0.144639 0.143898 0.036907 +v -0.132041 0.144320 0.055768 +v -0.101950 0.142271 0.049955 +v -0.084822 0.115335 0.003735 +v -0.087492 0.188242 0.095373 +v -0.120255 0.185216 0.106408 +v -0.117900 0.232998 0.155514 +v -0.116259 0.286503 0.196263 +v -0.075579 0.232014 0.142544 +v -0.065531 0.277482 0.172864 +v -0.054670 0.296857 0.188582 +v -0.105288 0.430623 0.455097 +v -0.101094 0.380572 0.473027 +v -0.101722 0.388176 0.532348 +v -0.103053 0.428077 0.393655 +v -0.097629 0.368555 0.412085 +v -0.098113 0.430958 0.326360 +v -0.091216 0.357392 0.335638 +v -0.095483 0.428387 0.254468 +v -0.085692 0.353509 0.264883 +v -0.063196 0.295921 0.270305 +v 0.000000 0.286210 0.182439 +v -0.066087 0.310699 0.422540 +v -0.055590 0.313208 0.491657 +v -0.064502 0.302011 0.344151 +v -0.075897 0.335265 0.533983 +v -0.067092 0.211897 0.552765 +v -0.069887 0.280166 0.533189 +v -0.070924 0.292938 0.534956 +v -0.097138 0.298867 0.555601 +v -0.107859 0.343226 0.561794 +v -0.127496 0.345034 0.594748 +v -0.126305 0.302641 0.595893 +v -0.084030 0.039219 0.586627 +v -0.093227 0.117294 0.567871 +v -0.071978 0.116792 0.563770 +v -0.090829 0.143476 0.564729 +v -0.068490 0.142472 0.560318 +v -0.089647 0.214743 0.557451 +v -0.093553 0.274203 0.555390 +v -0.122084 0.265451 0.593357 +v -0.054618 0.063542 0.582086 +v -0.061464 0.072239 0.576561 +v -0.065384 0.038910 0.581851 +v -0.063091 0.100656 0.571531 +v -0.048018 0.140872 0.567852 +v -0.052101 0.117314 0.567871 +v -0.053690 0.100020 0.569559 +v -0.065335 0.017488 0.587668 +v -0.049356 0.020125 0.592377 +v -0.065335 0.003974 0.607896 +v -0.084819 0.019813 0.592391 +v -0.082223 0.004150 0.610389 +v -0.065335 0.001892 0.622772 +v -0.044166 0.001475 0.616832 +v -0.048447 0.004395 0.610099 +v -0.034949 0.003873 0.616084 +v -0.049047 0.003944 0.633290 +v -0.046129 0.001939 0.643754 +v -0.065335 0.004209 0.649042 +v -0.062556 0.004757 0.652494 +v -0.086504 0.001297 0.617300 +v -0.065335 -0.001601 0.630903 +v -0.049879 0.000267 0.625629 +v -0.051271 0.002363 0.632875 +v -0.065335 0.007222 0.647603 +v -0.065335 0.002588 0.644127 +v -0.079399 0.002600 0.633392 +v -0.080791 0.000302 0.626172 +v -0.081623 0.004197 0.633772 +v -0.068114 0.004956 0.652610 +v -0.071228 0.002386 0.679356 +v -0.084392 0.003524 0.673962 +v -0.081098 0.000592 0.670287 +v -0.072291 -0.000273 0.671697 +v -0.080792 0.001885 0.652395 +v -0.083156 0.004234 0.646135 +v -0.086754 0.002380 0.676271 +v -0.071796 0.001794 0.656219 +v -0.070161 0.001440 0.684246 +v -0.059119 0.000964 0.678849 +v -0.060648 0.000314 0.683859 +v -0.046278 0.002045 0.673500 +v -0.049572 -0.000765 0.669729 +v -0.047514 0.003621 0.645640 +v -0.058056 -0.001255 0.671215 +v -0.058874 0.001570 0.656080 +v -0.038932 0.003042 0.656758 +v -0.037163 0.000357 0.652218 +v -0.033090 -0.000907 0.649408 +v -0.043173 0.002789 0.644432 +v -0.029071 0.002308 0.630061 +v -0.036743 0.001761 0.668470 +v -0.031403 0.001653 0.650294 +v -0.034366 -0.000288 0.639905 +v -0.040239 -0.000306 0.644656 +v -0.032750 0.002081 0.636467 +v -0.029568 0.625356 -0.097193 +v 0.000000 0.637372 -0.094649 +v 0.000000 0.708182 -0.164901 +v 0.000000 0.592027 -0.020294 +v -0.032755 0.576729 -0.024852 +v -0.039399 0.602783 -0.110492 +v -0.029259 0.699000 -0.170987 +v -0.038201 0.684184 -0.189766 +v -0.024146 0.779601 -0.237006 +v -0.031810 0.766902 -0.253101 +v -0.019517 0.856700 -0.294600 +v 0.000000 0.862853 -0.290522 +v 0.000000 0.916997 -0.336833 +v 0.000000 0.787471 -0.231790 +v -0.012710 0.912813 -0.339606 +v -0.025508 0.846773 -0.307183 +v -0.020896 0.758717 -0.268147 +v -0.025469 0.674634 -0.207318 +v -0.025386 0.586227 -0.124658 +v -0.044284 0.543957 -0.036585 +v -0.028334 0.515632 -0.046271 +v -0.016785 0.906061 -0.348163 +v -0.016977 0.840374 -0.318945 +v -0.010983 0.901710 -0.356162 +v 0.000000 0.672173 -0.212803 +v 0.000000 0.919792 -0.353864 +v 0.000000 0.583091 0.014142 +v -0.039067 0.566884 0.009063 +v 0.045288 0.575140 0.053769 +v 0.039067 0.566884 0.009063 +v 0.000000 0.588147 0.055827 +v 0.000000 0.592776 0.092798 +v 0.000000 0.595377 0.147223 +v -0.036208 0.584796 0.229227 +v 0.000000 0.593654 0.222983 +v -0.035806 0.577757 0.295417 +v -0.078691 0.525481 0.483877 +v -0.041242 0.553205 0.465116 +v -0.040767 0.559251 0.413333 +v -0.080297 0.524253 0.423928 +v -0.038319 0.568389 0.355047 +v -0.077816 0.532272 0.363495 +v -0.072192 0.535032 0.302282 +v -0.070762 0.536933 0.231820 +v -0.102154 0.476030 0.438384 +v -0.100853 0.483901 0.379595 +v -0.097258 0.482537 0.314646 +v -0.092463 0.482116 0.240098 +v -0.095926 0.491769 0.193758 +v -0.106594 0.435547 0.515016 +v -0.075673 0.392637 0.748665 +v -0.103608 0.429336 0.733405 +v -0.107776 0.364886 0.710977 +v -0.123156 0.405798 0.669537 +v -0.111240 0.467995 0.701700 +v -0.126509 0.408857 0.609031 +v -0.118315 0.466568 0.615910 +v -0.112073 0.446227 0.560035 +v -0.115555 0.394847 0.560001 +v -0.124642 0.341835 0.645375 +v -0.119494 0.301289 0.637258 +v -0.105459 0.325197 0.688728 +v -0.092205 0.290555 0.667317 +v -0.115974 0.265108 0.632132 +v -0.085442 0.256632 0.658947 +v -0.112330 0.213952 0.627258 +v -0.076424 0.210893 0.652187 +v -0.051900 0.204666 0.640515 +v -0.056360 0.244876 0.652545 +v -0.057501 0.273094 0.665065 +v -0.056396 0.304127 0.691942 +v -0.070605 0.336772 0.717518 +v -0.034033 0.237613 0.631502 +v -0.029581 0.260891 0.642285 +v -0.020477 0.281556 0.650449 +v -0.033930 0.263491 0.575586 +v -0.039531 0.239320 0.572867 +v -0.034455 0.421424 0.783806 +v -0.037003 0.378359 0.756273 +v -0.031351 0.325418 0.707973 +v 0.000000 0.303193 0.690822 +v -0.063018 0.443250 0.770883 +v -0.033918 0.451159 0.814711 +v -0.061186 0.468794 0.802596 +v -0.035762 0.463034 0.839910 +v -0.066291 0.474405 0.836753 +v -0.087449 0.496155 0.795464 +v -0.095964 0.499122 0.832658 +v -0.106730 0.527473 0.824167 +v -0.098089 0.522628 0.788800 +v -0.103644 0.563008 0.822329 +v -0.085630 0.470357 0.758065 +v -0.095092 0.495184 0.739081 +v -0.080986 0.521346 0.723652 +v -0.082197 0.521001 0.670460 +v -0.101259 0.515705 0.601645 +v -0.101657 0.497942 0.545735 +v -0.103076 0.482480 0.498283 +v -0.055605 0.553562 0.688044 +v -0.049467 0.575567 0.640713 +v -0.064628 0.565288 0.592622 +v -0.073790 0.541520 0.539770 +v -0.026794 0.570753 0.686130 +v -0.032274 0.592881 0.739973 +v 0.000000 0.596990 0.731164 +v -0.023791 0.565118 0.637409 +v -0.033752 0.572907 0.578385 +v -0.038450 0.556264 0.517836 +v 0.000000 0.564570 0.574575 +v 0.000000 0.559792 0.511637 +v 0.000000 0.563479 0.629423 +v 0.000000 0.575855 0.682283 +v 0.026794 0.570753 0.686130 +v 0.032274 0.592881 0.739973 +v 0.055605 0.553562 0.688045 +v 0.063416 0.571958 0.757812 +v 0.049467 0.575567 0.640713 +v 0.080987 0.521346 0.723652 +v 0.023791 0.565118 0.637409 +v 0.033752 0.572907 0.578385 +v 0.082197 0.521001 0.670460 +v 0.095092 0.495184 0.739081 +v 0.064628 0.565288 0.592622 +v 0.038450 0.556264 0.517836 +v 0.000000 0.564460 0.460093 +v 0.041242 0.553205 0.465116 +v 0.000000 0.571832 0.406951 +v 0.040789 0.559251 0.413333 +v 0.087449 0.496155 0.795464 +v 0.085630 0.470357 0.758065 +v 0.111240 0.467995 0.701700 +v 0.101259 0.515705 0.601645 +v 0.073791 0.541520 0.539770 +v 0.078691 0.525481 0.483877 +v 0.106594 0.435547 0.515016 +v 0.112073 0.446227 0.560035 +v 0.115555 0.394847 0.560001 +v 0.126509 0.408857 0.609031 +v 0.118316 0.466568 0.615910 +v 0.101657 0.497942 0.545735 +v 0.103077 0.482480 0.498283 +v 0.080344 0.524253 0.423928 +v 0.102208 0.476030 0.438384 +v 0.078360 0.532272 0.363495 +v 0.038488 0.568389 0.355047 +v 0.036245 0.577757 0.295417 +v 0.074141 0.535032 0.302282 +v 0.101330 0.483901 0.379595 +v 0.036568 0.584796 0.229227 +v 0.072711 0.536933 0.231820 +v 0.039228 0.585821 0.152889 +v 0.000000 0.578212 0.353179 +v 0.000000 0.587101 0.291473 +v 0.039228 0.581339 0.094585 +v 0.090336 0.548535 0.103149 +v 0.083477 0.537783 0.046699 +v 0.112319 0.481515 0.044620 +v 0.092578 0.478264 -0.021432 +v 0.129416 0.416836 0.054430 +v 0.106921 0.410533 -0.010444 +v 0.136542 0.363802 0.063123 +v 0.112587 0.360073 0.000270 +v 0.058393 0.523958 -0.008919 +v 0.052404 0.476652 -0.055549 +v 0.068324 0.410550 -0.054990 +v 0.071766 0.350611 -0.044042 +v 0.117772 0.305628 0.012279 +v 0.036102 0.439811 -0.049881 +v 0.021785 0.421401 -0.037123 +v 0.025472 0.441840 -0.040225 +v 0.017461 0.447308 -0.050458 +v 0.000000 0.422437 -0.038038 +v 0.000000 0.341009 -0.006062 +v 0.080372 0.302627 -0.028470 +v 0.119963 0.265910 0.008569 +v 0.095584 0.261333 -0.027662 +v 0.033753 0.466584 -0.047170 +v 0.025961 0.473242 -0.042256 +v 0.017905 0.463998 -0.053655 +v 0.000000 0.507991 -0.042652 +v 0.008732 0.498493 -0.043835 +v 0.000000 0.503264 -0.044613 +v 0.001857 0.498723 -0.041769 +v 0.000000 0.499244 -0.041916 +v 0.000000 0.485464 -0.040877 +v 0.000000 0.468212 -0.054138 +v 0.000000 0.479741 -0.043224 +v -0.077015 0.253436 0.020992 +v -0.081148 0.209008 0.012151 +v -0.097851 0.218648 -0.032752 +v -0.082032 0.145206 0.013397 +v -0.055035 0.294296 0.007906 +v -0.039133 0.279481 0.091924 +v -0.058720 0.231415 0.075893 +v -0.071298 0.195962 0.053129 +v -0.025472 0.441840 -0.040225 +v -0.021785 0.421401 -0.037123 +v -0.071766 0.350611 -0.044042 +v -0.080372 0.302627 -0.028470 +v -0.095584 0.261333 -0.027662 +v 0.000000 0.441506 -0.042893 +v -0.017461 0.447308 -0.050458 +v 0.000000 0.444325 -0.052871 +v -0.017905 0.463998 -0.053655 +v -0.115478 0.214052 0.589475 +v -0.109719 0.143185 0.588499 +v -0.101328 0.117231 0.586442 +v -0.100856 0.628255 0.847739 +v -0.099516 0.628743 0.830740 +v -0.094604 0.595000 0.825854 +v -0.086774 0.656515 0.841477 +v -0.095885 0.656138 0.852994 +v -0.083043 0.674227 0.858351 +v -0.095155 0.674984 0.865990 +v -0.091698 0.698012 0.884593 +v -0.074325 0.675291 0.856784 +v -0.073062 0.656893 0.833480 +v -0.084230 0.635272 0.807398 +v -0.093626 0.595734 0.791968 +v -0.089343 0.549982 0.782604 +v -0.063508 0.677091 0.861440 +v -0.078372 0.683312 0.866924 +v -0.050798 0.658738 0.833536 +v -0.039711 0.658730 0.852482 +v -0.050370 0.658722 0.876956 +v -0.058730 0.676876 0.872727 +v -0.070643 0.684344 0.869622 +v -0.074411 0.692414 0.879136 +v -0.061471 0.678204 0.882604 +v -0.079852 0.700577 0.889141 +v -0.086632 0.691097 0.875733 +v -0.058631 0.657940 0.875927 +v -0.068651 0.677549 0.881646 +v -0.092939 0.675072 0.866659 +v -0.087364 0.605535 0.848278 +v -0.093144 0.628254 0.848408 +v -0.103378 0.586211 0.856822 +v -0.107810 0.564259 0.854452 +v -0.107993 0.536620 0.856255 +v -0.015737 0.511380 0.919432 +v 0.027584 0.480750 0.908928 +v 0.029932 0.481730 0.906794 +v 0.027613 0.489143 0.907347 +v 0.023561 0.488345 0.914601 +v 0.024556 0.490110 0.915544 +v 0.023772 0.480032 0.912524 +v 0.020865 0.477566 0.919577 +v 0.021095 0.485380 0.923614 +v 0.020162 0.490400 0.923640 +v 0.000452 0.487042 0.931874 +v 0.009335 0.486936 0.930755 +v 0.005014 0.487083 0.931583 +v 0.008882 0.486855 0.931697 +v 0.000743 0.482343 0.928169 +v 0.003590 0.482318 0.927934 +v 0.008323 0.476376 0.926440 +v 0.008350 0.482400 0.927564 +v 0.014211 0.476377 0.924473 +v 0.013316 0.482803 0.924920 +v 0.100183 0.018597 0.148280 +v 0.101930 0.019298 0.148725 +v 0.099745 0.026143 0.134503 +v 0.098700 0.031151 0.137544 +v 0.099631 0.021247 0.149889 +v 0.101378 0.021947 0.150333 +v 0.103047 0.027468 0.135343 +v 0.102001 0.032476 0.138383 +v 0.125884 0.020507 0.162582 +v 0.125831 0.023228 0.164278 +v 0.127715 0.020463 0.162557 +v 0.128520 0.028702 0.149193 +v 0.128422 0.033844 0.152399 +v 0.127663 0.023183 0.164253 +v 0.124960 0.033929 0.152447 +v 0.125059 0.028788 0.149242 +v 0.130014 0.020507 0.164152 +v 0.129961 0.023228 0.165848 +v 0.131845 0.020463 0.164127 +v 0.132650 0.028702 0.150763 +v 0.132552 0.033844 0.153969 +v 0.131793 0.023183 0.165823 +v 0.129090 0.033930 0.154017 +v 0.129188 0.028788 0.150812 +v 0.157584 0.019685 0.148072 +v 0.154222 0.026075 0.133622 +v 0.157578 0.024584 0.132689 +v 0.157132 0.017060 0.146478 +v 0.155356 0.017848 0.146972 +v 0.158433 0.029545 0.135702 +v 0.155078 0.031035 0.136635 +v 0.155808 0.020473 0.148566 +v 0.036096 0.025242 0.659520 +v 0.039512 0.026709 0.660366 +v 0.038387 0.019387 0.674224 +v 0.035362 0.029683 0.662002 +v 0.036579 0.018611 0.673776 +v 0.036191 0.020961 0.675090 +v 0.037999 0.021737 0.675537 +v 0.038778 0.031151 0.662848 +v 0.064386 0.025491 0.689577 +v 0.062541 0.025381 0.689519 +v 0.065079 0.030394 0.674303 +v 0.065311 0.035034 0.676976 +v 0.064264 0.023035 0.688163 +v 0.061825 0.034829 0.676866 +v 0.061593 0.030189 0.674193 +v 0.062419 0.022926 0.688105 +v 0.068516 0.023569 0.691307 +v 0.065722 0.028267 0.675923 +v 0.069209 0.028472 0.676033 +v 0.069441 0.033112 0.678706 +v 0.068393 0.021114 0.689893 +v 0.066671 0.023459 0.691249 +v 0.065954 0.032908 0.678596 +v 0.066549 0.021004 0.689834 +v 0.094102 0.018691 0.673819 +v 0.094726 0.021101 0.675165 +v 0.094510 0.025374 0.659591 +v 0.095691 0.029928 0.662134 +v 0.092986 0.021668 0.675500 +v 0.092402 0.031002 0.662769 +v 0.091221 0.026448 0.660226 +v 0.092362 0.019259 0.674155 +v 0.049003 0.120142 0.624316 +v 0.044403 0.100253 0.609560 +v 0.042177 0.077235 0.611367 +v 0.040524 0.051823 0.622584 +v 0.039465 0.042731 0.628291 +v 0.037021 0.041602 0.594952 +v 0.039785 0.071025 0.598902 +v 0.037431 0.101625 0.593130 +v 0.039550 0.117445 0.591167 +v 0.037053 0.141207 0.597753 +v 0.046695 0.144277 0.629983 +v 0.036250 0.200833 0.615936 +v 0.035094 0.072230 0.589550 +v 0.048018 0.140872 0.567852 +v 0.035090 0.091937 0.589698 +v 0.044416 0.070883 0.580579 +v 0.054618 0.063542 0.582086 +v 0.045051 0.090645 0.574505 +v 0.034824 0.022946 0.598633 +v 0.025333 0.018856 0.630556 +v 0.038178 0.042874 0.647083 +v 0.028615 0.030963 0.646801 +v 0.037788 0.041718 0.654614 +v 0.026906 0.024299 0.659443 +v 0.034916 0.028599 0.671942 +v 0.034549 0.026175 0.675875 +v 0.023741 0.015313 0.653802 +v 0.049356 0.020125 0.592377 +v 0.036744 0.001761 0.668470 +v 0.041791 0.005603 0.665444 +v 0.038109 0.025905 0.669947 +v 0.039369 0.026980 0.678800 +v 0.062771 0.024531 0.690953 +v 0.065335 0.022905 0.685998 +v 0.068361 0.024531 0.690953 +v 0.069325 0.031396 0.686256 +v 0.065335 0.052145 0.669398 +v 0.088996 0.031560 0.676968 +v 0.042157 0.032400 0.675818 +v 0.060767 0.031621 0.685737 +v 0.091301 0.027009 0.678686 +v 0.095457 0.041533 0.652580 +v 0.065335 0.052577 0.661080 +v 0.065598 0.051846 0.642424 +v 0.095203 0.043328 0.646824 +v 0.103896 0.030914 0.646183 +v 0.103760 0.024367 0.659264 +v 0.095728 0.028779 0.671556 +v 0.090245 0.051367 0.622842 +v 0.065580 0.059132 0.637689 +v 0.091205 0.042249 0.628567 +v 0.107040 0.018839 0.630381 +v 0.106929 0.015313 0.653802 +v 0.096121 0.026193 0.675782 +v 0.092561 0.025928 0.669835 +v 0.093926 0.001815 0.668402 +v 0.088880 0.006894 0.665119 +v 0.091738 0.003068 0.656755 +v 0.099267 0.001654 0.650294 +v 0.101806 -0.000125 0.650216 +v 0.101599 -0.000048 0.630195 +v 0.095721 0.001512 0.617941 +v 0.099351 0.022946 0.598633 +v 0.097061 0.041602 0.594952 +v 0.097580 -0.000907 0.649408 +v 0.096304 -0.000288 0.639905 +v 0.097920 0.002081 0.636467 +v 0.084541 0.001939 0.643754 +v 0.081623 0.003944 0.633290 +v 0.087497 0.002789 0.644432 +v 0.090431 -0.000306 0.644656 +v 0.093507 0.000361 0.652217 +v 0.065335 0.006874 0.647393 +v 0.065335 0.002292 0.643847 +v 0.079399 0.002359 0.632866 +v 0.065335 0.003853 0.648796 +v 0.068114 0.004457 0.652320 +v 0.047514 0.003621 0.645640 +v 0.062556 0.004457 0.652320 +v 0.058874 0.001232 0.655872 +v 0.046129 0.001939 0.643754 +v 0.049047 0.003944 0.633290 +v 0.051271 0.002359 0.632866 +v 0.065335 -0.001683 0.630608 +v 0.080791 0.000267 0.625629 +v 0.058056 -0.001419 0.671139 +v 0.059119 0.000891 0.678823 +v 0.071228 0.000891 0.678823 +v 0.065335 0.002971 0.678160 +v 0.060648 -0.000169 0.683693 +v 0.049572 -0.000765 0.669729 +v 0.038932 0.003042 0.656758 +v 0.043173 0.002789 0.644432 +v 0.046453 0.000273 0.675323 +v 0.034949 0.003873 0.616084 +v 0.034366 -0.000288 0.639905 +v 0.040239 -0.000306 0.644656 +v 0.037163 0.000357 0.652218 +v 0.033090 -0.000907 0.649408 +v 0.031403 0.001654 0.650294 +v 0.032750 0.002081 0.636467 +v 0.028864 -0.000125 0.650216 +v 0.029071 0.002308 0.630061 +v 0.032460 0.490630 0.911148 +v 0.032758 0.481841 0.911095 +v 0.021350 0.474344 0.919333 +v 0.035752 0.491047 0.906428 +v 0.036515 0.485363 0.908901 +v 0.039894 0.490750 0.903130 +v 0.041201 0.487288 0.904324 +v 0.042480 0.484901 0.901858 +v 0.050248 0.480041 0.892863 +v 0.029836 0.467053 0.877065 +v 0.044525 0.488616 0.903502 +v 0.060531 0.489768 0.896619 +v 0.058437 0.476442 0.879673 +v 0.000000 0.463099 0.857611 +v 0.079206 0.493697 0.885346 +v -0.079206 0.493697 0.885346 +v -0.095418 0.499187 0.862848 +v -0.063066 0.473027 0.859581 +v -0.093681 0.539089 0.884004 +v -0.083633 0.517295 0.895988 +v -0.068832 0.506128 0.904171 +v -0.062543 0.523955 0.917943 +v -0.051739 0.512121 0.921361 +v -0.049555 0.501946 0.921942 +v -0.039566 0.523852 0.930703 +v -0.044517 0.531227 0.926361 +v -0.024734 0.544564 0.916441 +v -0.026477 0.543011 0.916041 +v -0.023345 0.539542 0.922526 +v -0.020185 0.542870 0.924015 +v -0.023818 0.535506 0.924229 +v -0.026834 0.551429 0.916425 +v -0.025774 0.546715 0.913954 +v -0.027570 0.544739 0.913519 +v -0.032224 0.545480 0.914860 +v -0.030407 0.541228 0.917163 +v -0.045879 0.538628 0.920548 +v -0.045254 0.543051 0.913250 +v -0.056955 0.548680 0.908286 +v -0.045936 0.540745 0.908442 +v -0.031652 0.543896 0.908516 +v -0.026138 0.543948 0.907725 +v -0.024335 0.546275 0.907951 +v -0.023132 0.550899 0.909225 +v -0.023291 0.562014 0.910263 +v -0.028212 0.559800 0.917681 +v -0.038399 0.574877 0.909864 +v -0.041918 0.570561 0.915579 +v -0.057183 0.576214 0.899042 +v -0.055611 0.571466 0.906311 +v -0.063871 0.561550 0.898860 +v -0.061075 0.561134 0.906454 +v -0.059377 0.546976 0.903612 +v 0.120748 -0.001556 0.145421 +v 0.120777 0.001020 0.130564 +v 0.124172 0.004156 0.126931 +v 0.122164 0.000691 0.152825 +v 0.126693 0.003569 0.123373 +v 0.143037 -0.000871 0.142849 +v 0.146422 0.001876 0.146331 +v 0.133916 0.000690 0.152218 +v 0.124701 -0.000340 0.157433 +v 0.112444 -0.000920 0.144478 +v 0.109239 0.003342 0.121202 +v 0.107801 0.001707 0.119441 +v 0.104677 0.005272 0.140709 +v 0.099930 0.001536 0.143899 +v 0.101467 0.002780 0.132422 +v 0.093837 0.001430 0.126526 +v 0.095430 -0.001060 0.125582 +v 0.094452 0.001844 0.113039 +v 0.096192 -0.000459 0.116296 +v 0.099523 0.000169 0.128104 +v 0.104966 0.002533 0.120247 +v 0.110108 0.003655 0.109139 +v 0.102130 -0.000476 0.120612 +v 0.104297 0.001033 0.088553 +v 0.109522 -0.000110 0.096637 +v 0.125270 -0.002068 0.100828 +v 0.112246 0.002114 0.108617 +v 0.126622 0.006506 0.122010 +v 0.126445 0.002050 0.118569 +v 0.141724 0.003655 0.107507 +v 0.139544 0.002114 0.107208 +v 0.140503 -0.000110 0.095038 +v 0.145385 0.001033 0.086432 +v 0.125129 0.001455 0.093080 +v 0.108114 0.003871 0.081804 +v 0.091752 0.058141 0.018016 +v 0.084011 0.122397 -0.026880 +v 0.103778 0.135342 -0.064655 +v 0.100665 0.018615 0.058942 +v 0.101416 0.012835 0.067892 +v 0.124385 0.003627 0.078650 +v 0.140894 0.003871 0.080112 +v 0.123089 0.016291 0.053555 +v 0.122997 0.056607 0.020204 +v 0.125333 0.150633 -0.037315 +v 0.124163 0.121612 -0.035016 +v 0.143807 0.058161 0.015152 +v 0.147309 0.018596 0.056544 +v 0.147480 0.012821 0.065521 +v 0.123561 0.009757 0.062694 +v 0.157149 0.016365 0.070544 +v 0.154386 0.001069 0.087047 +v 0.166245 0.018139 0.103410 +v 0.155581 0.041952 0.119958 +v 0.156115 0.040208 0.125532 +v 0.163985 0.029882 0.118901 +v 0.150344 0.038657 0.092153 +v 0.156340 0.024025 0.062603 +v 0.151268 0.067281 0.030444 +v 0.142148 0.119618 -0.007934 +v 0.145231 0.147575 -0.004373 +v 0.140823 0.202625 0.043883 +v 0.141551 0.259373 0.065677 +v 0.139715 0.244884 0.125962 +v 0.136715 0.192736 0.076758 +v 0.144639 0.143898 0.036907 +v 0.141282 0.120477 0.031399 +v 0.151881 0.082779 0.051214 +v 0.150243 0.042773 0.080293 +v 0.125240 0.056000 0.091337 +v 0.065532 0.277482 0.172864 +v 0.116259 0.286503 0.196263 +v 0.098341 0.347819 0.212912 +v 0.144363 0.304571 0.157733 +v 0.117900 0.232998 0.155514 +v 0.120255 0.185216 0.106408 +v 0.132041 0.144320 0.055768 +v 0.075579 0.232014 0.142544 +v 0.087492 0.188242 0.095373 +v 0.101950 0.142271 0.049955 +v 0.071298 0.195962 0.053129 +v 0.054670 0.296857 0.188582 +v 0.063196 0.295921 0.270305 +v 0.085692 0.353509 0.264883 +v 0.064502 0.302011 0.344151 +v 0.095951 0.427772 0.214796 +v 0.022240 0.296419 0.090672 +v 0.091216 0.357392 0.335638 +v 0.095896 0.428387 0.254468 +v 0.096613 0.491769 0.193758 +v 0.066087 0.310699 0.422540 +v 0.097629 0.368555 0.412085 +v 0.055590 0.313208 0.491657 +v 0.098618 0.430958 0.326360 +v 0.094411 0.482116 0.240098 +v 0.081403 0.546869 0.157532 +v 0.101094 0.380572 0.473027 +v 0.103116 0.428077 0.393655 +v 0.099207 0.482537 0.314646 +v 0.105288 0.430623 0.455097 +v 0.101722 0.388176 0.532348 +v 0.075897 0.335265 0.533983 +v 0.107859 0.343226 0.561794 +v 0.097138 0.298867 0.555601 +v 0.070924 0.292938 0.534956 +v 0.126305 0.302641 0.595893 +v 0.122084 0.265451 0.593357 +v 0.127496 0.345034 0.594748 +v 0.103608 0.429336 0.733405 +v 0.123156 0.405798 0.669537 +v 0.124642 0.341835 0.645375 +v 0.119494 0.301289 0.637258 +v 0.105460 0.325197 0.688728 +v 0.092205 0.290555 0.667318 +v 0.056396 0.304127 0.691942 +v 0.107776 0.364886 0.710977 +v 0.057501 0.273094 0.665065 +v 0.029581 0.260891 0.642285 +v 0.022371 0.283187 0.581346 +v 0.033930 0.263491 0.575586 +v 0.039531 0.239320 0.572867 +v 0.034033 0.237613 0.631502 +v 0.056360 0.244876 0.652545 +v 0.085442 0.256632 0.658947 +v 0.115974 0.265108 0.632132 +v 0.112330 0.213952 0.627258 +v 0.076424 0.210893 0.652187 +v 0.051900 0.204666 0.640515 +v 0.071390 0.145822 0.643662 +v 0.104295 0.145236 0.622379 +v 0.109719 0.143185 0.588499 +v 0.115478 0.214053 0.589475 +v 0.090829 0.143476 0.564729 +v 0.089647 0.214743 0.557451 +v 0.068490 0.142472 0.560318 +v 0.101328 0.117231 0.586442 +v 0.093227 0.117294 0.567871 +v 0.071978 0.116792 0.563770 +v 0.084030 0.039258 0.586645 +v 0.086504 0.001475 0.616832 +v 0.082223 0.004395 0.610099 +v 0.084819 0.020125 0.592377 +v 0.065384 0.038910 0.581851 +v 0.063091 0.100656 0.571531 +v 0.065335 0.017667 0.587649 +v 0.061464 0.072239 0.576561 +v 0.052101 0.117314 0.567871 +v 0.053690 0.100020 0.569559 +v 0.050052 0.039258 0.586645 +v 0.065335 0.004143 0.607721 +v 0.065335 0.001909 0.622590 +v 0.044166 0.001475 0.616832 +v 0.048447 0.004395 0.610099 +v 0.049879 0.000267 0.625629 +v 0.100249 0.040387 0.130394 +v 0.090956 0.029929 0.123273 +v 0.089931 0.023450 0.135628 +v 0.098330 0.027633 0.147357 +v 0.100250 0.041511 0.123066 +v 0.086957 0.018155 0.107672 +v 0.086577 0.014712 0.130313 +v 0.098171 0.025276 0.151192 +v 0.101329 0.025013 0.145260 +v 0.102996 0.026059 0.153789 +v 0.105552 0.031329 0.150756 +v 0.124110 0.030573 0.159450 +v 0.127725 0.050528 0.143362 +v 0.128662 0.022097 0.161531 +v 0.132441 0.030354 0.159525 +v 0.151067 0.030512 0.149525 +v 0.127124 0.023679 0.164370 +v 0.130484 0.023679 0.164197 +v 0.128270 0.002714 0.153926 +v 0.153390 0.026087 0.151077 +v 0.127308 0.050947 0.135289 +v 0.099932 0.039063 0.094404 +v 0.125994 0.049990 0.104873 +v 0.154169 0.025036 0.142425 +v 0.157329 0.027807 0.143935 +v 0.098803 0.043066 0.082483 +v 0.090974 0.016459 0.073904 +v 0.095314 0.003365 0.088289 +v 0.090560 0.002064 0.107006 +v 0.091369 -0.000300 0.126577 +v 0.090966 0.024148 0.065907 +v 0.097590 0.085739 0.058757 +v 0.089478 0.070046 0.037540 +v 0.125325 0.093362 0.067083 +v 0.130345 0.124267 0.044141 +v 0.103262 0.121807 0.039355 +v 0.160955 -0.000227 0.103503 +v 0.167310 0.014712 0.126146 +v 0.164509 0.023516 0.131605 +v 0.157922 0.025294 0.148018 +v 0.155423 0.001588 0.140968 +v 0.162159 -0.000300 0.122924 +v 0.159699 0.001430 0.123126 +v 0.157699 0.001844 0.109775 +v 0.156303 -0.000459 0.113193 +v 0.147983 0.002533 0.118027 +v 0.150841 -0.000476 0.118098 +v 0.154205 0.000173 0.125282 +v 0.152716 0.002805 0.129774 +v 0.158017 -0.001060 0.122351 +v 0.129567 0.004156 0.126653 +v 0.134563 -0.001594 0.144713 +v 0.141846 0.000884 0.125542 +v 0.133318 0.001020 0.129916 +v 0.143830 0.003342 0.119416 +v 0.131868 -0.000340 0.157063 +v 0.148828 0.000699 0.148420 +v 0.081148 0.209008 0.012151 +v 0.082975 0.149033 -0.025392 +v 0.084822 0.115335 0.003735 +v 0.082032 0.145206 0.013397 +v 0.097851 0.218648 -0.032752 +v 0.122875 0.211689 -0.000436 +v 0.103099 0.150372 -0.063820 +v 0.136009 0.310889 0.073633 +v 0.120530 0.492458 0.154213 +v 0.131191 0.429177 0.178254 +v 0.142545 0.364635 0.179035 +v 0.077015 0.253436 0.020992 +v 0.055035 0.294296 0.007906 +v 0.039133 0.279481 0.091924 +v 0.058720 0.231415 0.075893 +v 0.093510 0.119876 0.618848 +v 0.070822 0.120951 0.637097 +v 0.036222 0.608996 0.812719 +v 0.033089 0.604172 0.818217 +v 0.053919 0.593748 0.816296 +v 0.047371 0.596641 0.804772 +v 0.053052 0.583997 0.802882 +v 0.076344 0.599619 0.807587 +v 0.071558 0.622247 0.839233 +v 0.054751 0.614456 0.805808 +v 0.042066 0.629218 0.840712 +v 0.048088 0.635161 0.817770 +v 0.075541 0.635992 0.815726 +v 0.091944 0.594970 0.826001 +v 0.092121 0.629276 0.830749 +v 0.084997 0.655048 0.842840 +v 0.072288 0.654556 0.834719 +v 0.051465 0.656201 0.834503 +v 0.042729 0.638989 0.843174 +v 0.072355 0.618005 0.856329 +v 0.054697 0.628515 0.859013 +v 0.039168 0.635250 0.859752 +v 0.050969 0.655414 0.852687 +v 0.064494 0.674607 0.862264 +v 0.068326 0.676240 0.872114 +v 0.058631 0.657940 0.875927 +v 0.074201 0.673010 0.858285 +v 0.082154 0.672327 0.860033 +v 0.092939 0.675072 0.866659 +v 0.086298 0.688909 0.877313 +v 0.079770 0.692510 0.878870 +v 0.072711 0.681979 0.869169 +v 0.079500 0.681048 0.866922 +v -0.038393 0.508447 0.850369 +v 0.013838 0.505851 0.947647 +v 0.012150 0.506681 0.947089 +v 0.010481 0.507772 0.951328 +v 0.010595 0.507868 0.952081 +v 0.017057 0.508274 0.947300 +v 0.009116 0.513522 0.951314 +v 0.009457 0.511556 0.946130 +v 0.006602 0.510906 0.945843 +v 0.003858 0.507618 0.945617 +v 0.005718 0.508726 0.949447 +v 0.004380 0.511670 0.952013 +v 0.014822 0.478463 0.935845 +v 0.013110 0.487988 0.944418 +v 0.002573 0.486017 0.942430 +v 0.023491 0.491187 0.945636 +v 0.005267 0.496540 0.946730 +v 0.027460 0.499854 0.945737 +v 0.038551 0.499020 0.936530 +v 0.031325 0.478783 0.928159 +v 0.051739 0.512121 0.921361 +v 0.049555 0.501946 0.921942 +v 0.042487 0.488050 0.918523 +v 0.043224 0.490192 0.910432 +v 0.054138 0.497968 0.908208 +v 0.031351 0.325418 0.707973 +v 0.070605 0.336772 0.717518 +v 0.075673 0.392637 0.748665 +v 0.037003 0.378359 0.756273 +v 0.034455 0.421392 0.779155 +v 0.063018 0.443250 0.770883 +v 0.033918 0.451159 0.814711 +v 0.061186 0.468794 0.802596 +v 0.035762 0.463034 0.839910 +v 0.066291 0.474405 0.836753 +v 0.000000 0.407281 0.790898 +v 0.000000 0.370124 0.761273 +v 0.000000 0.317003 0.709620 +v 0.028481 0.311677 0.684214 +v 0.095964 0.499122 0.832658 +v 0.106730 0.527473 0.824167 +v 0.098089 0.522628 0.788800 +v 0.089343 0.549982 0.782604 +v 0.103644 0.563008 0.822329 +v 0.107810 0.564259 0.854452 +v 0.095418 0.499187 0.862848 +v 0.063066 0.473027 0.859581 +v 0.100857 0.628255 0.847739 +v 0.093144 0.628254 0.848408 +v 0.087365 0.605535 0.848278 +v 0.094604 0.595000 0.825854 +v 0.103378 0.586211 0.856822 +v 0.093626 0.595734 0.791968 +v 0.062670 0.614989 0.784539 +v 0.029399 0.622722 0.774263 +v 0.022515 0.641951 0.803574 +v 0.046825 0.645339 0.804897 +v 0.088572 0.635272 0.809134 +v 0.099517 0.628743 0.830740 +v 0.000000 0.627700 0.773489 +v 0.000000 0.644547 0.800126 +v 0.019186 0.641639 0.842290 +v 0.000000 0.643021 0.840879 +v -0.019186 0.641639 0.842290 +v -0.022515 0.641951 0.803574 +v -0.029399 0.622722 0.774263 +v -0.025207 0.643663 0.842176 +v -0.048429 0.645339 0.802599 +v -0.062670 0.614989 0.784539 +v -0.063416 0.571958 0.757812 +v 0.068832 0.506128 0.904171 +v 0.083633 0.517295 0.895988 +v 0.093681 0.539089 0.884004 +v 0.096608 0.569740 0.879123 +v 0.077677 0.566059 0.892515 +v 0.072070 0.604157 0.882089 +v 0.107994 0.536620 0.856255 +v 0.060893 0.613364 0.873307 +v 0.045764 0.620904 0.876901 +v 0.062085 0.545563 0.910818 +v 0.024194 0.638730 0.868332 +v 0.045254 0.543051 0.913250 +v 0.056955 0.548680 0.908286 +v 0.061442 0.561231 0.907090 +v 0.055979 0.571563 0.906946 +v 0.041918 0.570561 0.915223 +v 0.057400 0.546076 0.903617 +v 0.045728 0.540696 0.908447 +v 0.062718 0.561157 0.897358 +v 0.057165 0.575621 0.899981 +v 0.039268 0.574249 0.909569 +v 0.023568 0.550884 0.908354 +v 0.024072 0.546295 0.907957 +v 0.026055 0.544210 0.907730 +v 0.030565 0.543902 0.908522 +v -0.100249 0.040387 0.130394 +v -0.098330 0.027633 0.147357 +v -0.089931 0.023450 0.135628 +v -0.090956 0.029929 0.123273 +v -0.105552 0.031329 0.150756 +v -0.127724 0.050528 0.143362 +v -0.086576 0.014712 0.130313 +v -0.098171 0.025276 0.151192 +v -0.101329 0.025013 0.145261 +v -0.102996 0.026059 0.153789 +v -0.124110 0.030573 0.159450 +v -0.128662 0.022097 0.161531 +v -0.132441 0.030354 0.159525 +v -0.151067 0.030512 0.149525 +v -0.127124 0.023679 0.164370 +v -0.099930 0.001536 0.143899 +v -0.104677 0.005272 0.140709 +v -0.109697 0.000089 0.150063 +v -0.124701 -0.000340 0.157433 +v -0.089478 0.070046 0.037540 +v -0.090974 0.016459 0.073904 +v -0.090560 0.002064 0.107006 +v -0.095314 0.003365 0.088289 +v -0.091369 -0.000300 0.126577 +v -0.099745 0.026143 0.134504 +v -0.101930 0.019298 0.148725 +v -0.098700 0.031151 0.137544 +v -0.100183 0.018597 0.148280 +v -0.099631 0.021247 0.149889 +v -0.101378 0.021947 0.150333 +v -0.102001 0.032476 0.138383 +v -0.103046 0.027468 0.135343 +v -0.125884 0.020507 0.162582 +v -0.128520 0.028702 0.149193 +v -0.127715 0.020463 0.162557 +v -0.124960 0.033929 0.152447 +v -0.128422 0.033844 0.152399 +v -0.127663 0.023183 0.164253 +v -0.125059 0.028788 0.149242 +v -0.125831 0.023228 0.164278 +v -0.131845 0.020463 0.164127 +v -0.132650 0.028702 0.150763 +v -0.129188 0.028788 0.150812 +v -0.131792 0.023183 0.165823 +v -0.132552 0.033844 0.153969 +v -0.129961 0.023228 0.165848 +v -0.130014 0.020507 0.164152 +v -0.129090 0.033930 0.154017 +v -0.155808 0.020473 0.148566 +v -0.157584 0.019685 0.148073 +v -0.157577 0.024584 0.132689 +v -0.155356 0.017848 0.146972 +v -0.157132 0.017060 0.146478 +v -0.155078 0.031035 0.136635 +v -0.158433 0.029545 0.135702 +v -0.154222 0.026075 0.133622 +v -0.037999 0.021737 0.675537 +v -0.038387 0.019387 0.674224 +v -0.036096 0.025242 0.659520 +v -0.036579 0.018611 0.673776 +v -0.036191 0.020961 0.675090 +v -0.035362 0.029683 0.662002 +v -0.038778 0.031151 0.662848 +v -0.039512 0.026709 0.660366 +v -0.064386 0.025490 0.689577 +v -0.062541 0.025381 0.689519 +v 0.032820 0.492692 0.903136 +v 0.034392 0.492780 0.900641 +v 0.078373 0.683312 0.866924 +v 0.074325 0.675291 0.856784 +v 0.063508 0.677092 0.861440 +v 0.095155 0.674984 0.865990 +v 0.083043 0.674227 0.858351 +v 0.061472 0.678204 0.882604 +v 0.050370 0.658722 0.876956 +v 0.079852 0.700577 0.889141 +v 0.068651 0.677549 0.881646 +v 0.091698 0.698012 0.884593 +v 0.083315 0.697776 0.888019 +v 0.089516 0.696958 0.884740 +v 0.095885 0.656138 0.852994 +v 0.058731 0.676876 0.872727 +v 0.074411 0.692414 0.879136 +v 0.070643 0.684344 0.869622 +v 0.031177 0.636005 0.865749 +v 0.039711 0.658730 0.852482 +v 0.086632 0.691097 0.875733 +v 0.086774 0.656516 0.841477 +v 0.073063 0.656893 0.833480 +v 0.050798 0.658738 0.833536 +v 0.025208 0.643662 0.842176 +v 0.093541 0.656137 0.853663 +v 0.055044 0.534222 0.865207 +v 0.060476 0.532655 0.892136 +v 0.038313 0.527072 0.867667 +v 0.020606 0.531226 0.870178 +v 0.023298 0.529420 0.897503 +v 0.008686 0.545099 0.871778 +v 0.010430 0.544397 0.899231 +v 0.008724 0.564144 0.899317 +v 0.007106 0.563391 0.871858 +v 0.018833 0.581120 0.897729 +v 0.016470 0.579116 0.870387 +v 0.033702 0.556578 0.847980 +v 0.033200 0.586267 0.867926 +v 0.050908 0.582112 0.865416 +v 0.062828 0.568239 0.863815 +v 0.064408 0.549947 0.863735 +v 0.036895 0.588839 0.895072 +v 0.068879 0.569378 0.890634 +v 0.070585 0.549630 0.890548 +v -0.032649 0.540183 0.910603 +v -0.024796 0.549339 0.911758 +v -0.040252 0.553855 0.909312 +v -0.039772 0.559071 0.909326 +v -0.023755 0.561413 0.911823 +v -0.040548 0.563035 0.909159 +v -0.029925 0.571789 0.910775 +v -0.042196 0.564807 0.908881 +v -0.040947 0.576505 0.909013 +v -0.052609 0.573760 0.907211 +v -0.044113 0.563513 0.908597 +v -0.045570 0.559637 0.908415 +v -0.060458 0.564605 0.906056 +v -0.045993 0.554637 0.908407 +v -0.061498 0.552536 0.905991 +v -0.045268 0.550299 0.908571 +v -0.055333 0.542161 0.907038 +v -0.043608 0.548700 0.908848 +v -0.044314 0.537441 0.908800 +v -0.041702 0.550053 0.909130 +v 0.039399 0.602783 -0.110492 +v 0.029568 0.625356 -0.097193 +v 0.032755 0.576729 -0.024852 +v 0.029259 0.699000 -0.170987 +v 0.038201 0.684184 -0.189766 +v 0.024146 0.779601 -0.237006 +v 0.031810 0.766902 -0.253101 +v 0.019517 0.856700 -0.294600 +v 0.012710 0.912813 -0.339606 +v 0.025508 0.846773 -0.307183 +v 0.020896 0.758717 -0.268147 +v 0.025469 0.674634 -0.207318 +v 0.025386 0.586227 -0.124658 +v 0.044284 0.543957 -0.036585 +v 0.028334 0.515632 -0.046271 +v 0.000000 0.583398 -0.125669 +v 0.000000 0.517059 -0.050514 +v 0.016785 0.906061 -0.348163 +v 0.016977 0.840374 -0.318945 +v 0.000000 0.756607 -0.272848 +v 0.000000 0.838725 -0.322619 +v 0.010983 0.901710 -0.356162 +v 0.000000 0.900588 -0.358661 +v 0.069887 0.280166 0.533190 +v 0.093553 0.274203 0.555390 +v 0.067092 0.211897 0.552765 +v 0.042807 0.200773 0.572693 +v 0.000000 0.285097 0.267639 +v 0.000000 0.289263 0.352467 +v 0.000000 0.296678 0.432109 +v 0.000000 0.294277 0.508399 +v 0.000000 0.278174 0.586936 +v -0.024899 0.507998 0.914949 +v -0.141845 0.000884 0.125542 +v -0.133317 0.001020 0.129916 +v -0.134563 -0.001594 0.144713 +v -0.143036 -0.000871 0.142849 +v -0.146422 0.001876 0.146331 +v -0.143830 0.003342 0.119416 +v -0.148828 0.000699 0.148420 +v 0.084392 0.002110 0.673436 +v 0.083156 0.003621 0.645640 +v 0.080792 0.001092 0.651830 +v 0.071796 0.001232 0.655872 +v 0.086754 0.000900 0.675710 +v 0.072291 -0.001458 0.671144 +v 0.081098 -0.000714 0.669678 +v -0.036638 0.486454 0.888226 +v 0.109697 0.000089 0.150063 +v 0.035945 0.466764 0.860661 +v 0.000000 0.458677 0.841721 +v 0.000000 0.439931 0.819488 +v -0.031177 0.636005 0.865749 +v -0.024194 0.638730 0.868332 +v -0.039026 0.505680 0.870024 +v 0.070161 -0.000169 0.683693 +v 0.049878 0.001092 0.651830 +v 0.046278 0.002045 0.673500 +v -0.031072 0.498233 0.893920 +v 0.000000 0.297222 0.095847 +v 0.033893 0.349947 -0.019369 +v -0.033892 0.349947 -0.019369 +v -0.022240 0.296419 0.090672 +v -0.039868 0.493842 0.866170 +v 0.029362 0.498982 -0.040975 +v -0.017191 0.479155 0.893490 +v -0.026378 0.480340 0.898411 +v 0.145079 0.001707 0.117517 +v 0.150360 0.006526 0.138034 +v -0.011958 0.470684 0.915691 +v 0.111844 0.000884 0.127091 +v 0.109436 0.001812 0.148302 +v 0.000000 0.470013 0.921264 +v 0.000000 0.494721 0.928310 +v 0.000000 0.512760 0.923067 +v 0.000000 0.475777 0.890221 +v 0.006341 0.496218 0.924619 +v 0.015737 0.511380 0.919433 +v -0.019946 0.484636 0.838460 +v 0.014821 0.530400 0.860878 +v -0.035387 0.492415 0.849503 +v 0.000000 0.513535 0.826333 +v 0.019580 0.512958 0.831960 +v -0.019580 0.512958 0.831960 +v 0.000000 0.533196 0.860453 +v 0.000000 0.482809 0.832952 +v -0.035590 0.517593 0.871404 +v -0.014821 0.525126 0.903236 +v -0.014821 0.530400 0.860878 +v 0.019946 0.484636 0.838460 +v -0.013228 0.496491 0.921146 +v 0.035387 0.492415 0.849503 +v 0.011958 0.470684 0.915691 +v 0.017191 0.479155 0.893490 +v -0.008124 0.279935 0.584455 +v -0.022371 0.283187 0.581346 +v 0.019404 0.474029 0.909763 +v -0.150360 0.006526 0.138034 +v 0.036638 0.486454 0.888226 +v -0.049878 0.001092 0.651830 +v 0.038393 0.508447 0.850369 +v 0.039869 0.493842 0.866170 +v -0.088880 0.008066 0.665511 +v -0.093926 0.003084 0.668939 +v 0.026378 0.480340 0.898411 +v 0.018103 0.477155 0.922055 +v 0.053538 0.657635 0.872006 +v 0.035392 0.635437 0.857637 +v 0.062052 0.617181 0.867883 +v 0.076435 0.651241 0.879887 +v 0.066615 0.676905 0.879527 +v 0.081006 0.671245 0.881494 +v 0.081287 0.696441 0.886063 +v 0.086141 0.696305 0.884325 +v 0.089448 0.692009 0.883024 +v 0.092188 0.667592 0.863195 +v 0.094462 0.644488 0.852128 +v 0.088875 0.604935 0.840891 +v 0.015775 0.482642 0.922491 +v 0.039026 0.505680 0.870024 +v 0.022217 0.497232 0.909661 +v 0.024899 0.507998 0.914949 +v 0.027580 0.498891 0.901575 +v 0.011852 0.483738 0.838233 +v 0.014821 0.525126 0.903236 +v 0.035590 0.517593 0.871404 +v 0.031031 0.514655 0.904191 +v 0.000000 0.528753 0.902004 +v 0.006173 0.477800 0.923176 +v 0.022186 0.491489 0.915415 +v 0.022565 0.486169 0.917672 +v 0.016087 0.483309 0.921481 +v 0.015969 0.478127 0.918671 +v 0.012469 0.477833 0.920807 +v -0.015969 0.478127 0.918671 +v -0.016278 0.490014 0.923158 +v -0.031886 0.493050 0.898681 +v -0.030314 0.492963 0.901177 +v -0.030709 0.490512 0.900562 +v -0.026138 0.489434 0.906171 +v -0.025333 0.489777 0.907565 +v -0.022223 0.490468 0.915946 +v -0.021373 0.479955 0.910255 +v -0.022590 0.486169 0.917645 +v -0.022186 0.491489 0.915415 +v -0.003405 0.482626 0.926452 +v -0.007811 0.482315 0.926014 +v -0.008483 0.488164 0.927565 +v -0.004161 0.488311 0.928393 +v -0.012878 0.483165 0.923024 +v 0.000250 0.477427 0.924703 +v -0.003917 0.477394 0.924350 +v -0.007296 0.477477 0.923255 +v -0.007509 0.483074 0.925643 +v -0.006173 0.477800 0.923176 +v -0.011759 0.477984 0.920451 +v 0.031557 0.490106 0.899161 +v 0.030314 0.492963 0.901177 +v 0.025328 0.485275 0.907261 +v 0.027277 0.481645 0.904283 +v 0.024929 0.480665 0.906417 +v 0.026138 0.489434 0.906171 +v 0.025333 0.489777 0.907565 +v 0.026548 0.492318 0.905872 +v 0.020816 0.483104 0.911717 +v 0.021373 0.479955 0.910255 +v 0.004161 0.488311 0.928393 +v 0.007811 0.482315 0.926014 +v 0.008703 0.482782 0.924376 +v 0.006789 0.488503 0.927267 +v 0.012881 0.489096 0.925204 +v 0.003399 0.482953 0.926032 +v 0.003628 0.483028 0.926347 +v 0.003001 0.477366 0.924216 +v 0.008624 0.476194 0.927199 +v 0.009481 0.482698 0.926726 +v -0.013268 0.483072 0.923202 +v -0.012469 0.477833 0.920807 +v 0.018830 0.486075 0.919950 +v 0.017031 0.491359 0.918566 +v 0.000000 0.479260 0.838420 +v -0.011852 0.483738 0.838233 +v 0.017203 0.505284 0.857028 +v -0.031557 0.490106 0.899161 +v -0.033066 0.489941 0.900403 +v -0.034392 0.492780 0.900641 +v -0.026993 0.485342 0.908763 +v -0.027584 0.480750 0.908928 +v -0.024929 0.480665 0.906417 +v -0.026548 0.492318 0.905872 +v -0.027613 0.489143 0.907347 +v -0.028998 0.491845 0.907726 +v -0.023287 0.489729 0.916785 +v -0.022295 0.488434 0.915005 +v -0.019252 0.479069 0.912183 +v -0.021117 0.483295 0.914303 +v -0.017031 0.491359 0.918566 +v -0.018854 0.486075 0.919924 +v -0.021115 0.485380 0.923592 +v -0.020975 0.477566 0.919458 +v -0.000646 0.482087 0.928472 +v -0.000558 0.482777 0.926583 +v -0.000321 0.488173 0.928774 +v -0.005014 0.487083 0.931583 +v -0.004650 0.481739 0.928530 +v -0.006789 0.488503 0.927267 +v -0.008703 0.482782 0.924376 +v -0.000552 0.482978 0.926267 +v -0.003001 0.477366 0.924216 +v -0.009481 0.482698 0.926726 +v 0.031886 0.493050 0.898681 +v 0.033066 0.489941 0.900403 +v 0.028998 0.491845 0.907726 +v 0.022774 0.488143 0.915310 +v 0.023287 0.489729 0.916785 +v 0.022223 0.490468 0.915946 +v 0.021651 0.479147 0.914452 +v 0.021117 0.483295 0.914303 +v 0.019612 0.483235 0.912947 +v 0.019252 0.479069 0.912183 +v 0.000321 0.488173 0.928774 +v 0.004650 0.481739 0.928530 +v 0.010058 0.481781 0.927060 +v -0.000250 0.477427 0.924703 +v 0.014692 0.498946 0.891566 +v 0.017154 0.502545 0.857670 +v -0.017154 0.502545 0.857670 +v 0.000000 0.501002 0.857127 +v -0.017203 0.505284 0.857028 +v -0.014532 0.501725 0.893360 +v 0.014532 0.501725 0.893360 +v 0.014603 0.476860 0.924191 +v 0.014987 0.482289 0.925926 +v 0.013268 0.483072 0.923202 +v 0.015167 0.489920 0.923836 +v 0.012968 0.479759 0.843505 +v 0.000000 0.485800 0.863182 +v 0.000000 0.473016 0.847980 +v -0.012968 0.479759 0.843505 +v 0.000000 0.497777 0.899315 +v -0.014692 0.498946 0.891566 +v 0.000000 0.486900 0.895472 +v 0.000000 0.482707 0.929838 +v 0.000000 0.480938 0.928656 +v 0.015671 0.484411 0.923661 +v 0.023358 0.480897 0.908556 +v 0.004122 0.476309 0.927436 +v 0.003917 0.477394 0.924350 +v 0.007509 0.483074 0.925643 +v 0.007296 0.477477 0.923255 +v 0.011748 0.483784 0.922492 +v 0.011759 0.477984 0.920451 +v 0.016278 0.490014 0.923158 +v 0.017805 0.482526 0.924206 +v -0.033941 0.483749 0.903107 +v -0.022978 0.488765 0.911039 +v -0.022318 0.491642 0.912485 +v -0.024556 0.490110 0.915544 +v -0.023491 0.490849 0.914705 +v -0.023083 0.488636 0.914296 +v -0.003399 0.482953 0.926032 +v -0.004122 0.476309 0.927436 +v -0.008323 0.476376 0.926440 +v 0.029806 0.489437 0.905407 +v 0.030019 0.492337 0.907425 +v 0.027513 0.492607 0.905465 +v 0.031287 0.483663 0.900596 +v 0.024768 0.491169 0.914339 +v 0.022318 0.491642 0.912485 +v 0.023491 0.490849 0.914705 +v -0.025344 0.485543 0.910460 +v -0.021489 0.477842 0.917371 +v -0.024851 0.485474 0.921312 +v -0.003493 0.481936 0.928342 +v -0.004619 0.486824 0.931674 +v -0.004488 0.487956 0.928574 +v -0.008546 0.481549 0.927946 +v -0.009335 0.486936 0.930755 +v -0.014974 0.487448 0.929634 +v -0.012881 0.489096 0.925204 +v 0.004488 0.487956 0.928574 +v 0.004619 0.486824 0.931674 +v 0.003493 0.481936 0.928342 +v 0.008483 0.488164 0.927565 +v 0.012878 0.483165 0.923024 +v 0.014974 0.487448 0.929634 +v 0.027394 0.481856 0.909193 +v 0.025317 0.490529 0.920489 +v 0.024830 0.485474 0.921335 +v 0.025756 0.480974 0.910825 +v -0.030515 0.490120 0.904500 +v -0.032218 0.490347 0.901804 +v -0.029886 0.487917 0.902248 +v 0.021824 0.486669 0.911201 +v 0.021105 0.486391 0.911991 +v -0.029501 0.488258 0.901873 +v -0.029007 0.490286 0.903258 +v 0.024996 0.481779 0.906924 +v -0.030153 0.488248 0.901005 +v -0.030538 0.487908 0.901379 +v -0.030019 0.492337 0.907425 +v 0.025344 0.485543 0.910460 +v -0.029806 0.489437 0.905407 +v 0.023840 0.485482 0.909103 +v -0.028297 0.489603 0.904165 +v -0.027513 0.492607 0.905465 +v -0.031415 0.492514 0.905459 +v -0.032820 0.492692 0.903136 +v 0.022260 0.487100 0.911656 +v 0.024610 0.484301 0.911039 +v 0.023106 0.484241 0.909683 +v -0.028909 0.492784 0.903499 +v 0.021542 0.486822 0.912447 +v 0.023671 0.491881 0.910570 +v 0.025030 0.492141 0.908309 +v 0.027480 0.491668 0.910163 +v 0.026121 0.491407 0.912424 +v 0.025160 0.489166 0.911365 +v -0.028258 0.489553 0.905833 +v 0.024093 0.487547 0.908722 +v -0.026981 0.488768 0.906204 +v -0.028326 0.485196 0.907403 +v -0.029194 0.486389 0.903649 +v -0.030007 0.487763 0.903007 +v -0.032128 0.482773 0.904914 +v -0.031672 0.487829 0.904509 +v -0.031287 0.483663 0.900596 +v 0.024453 0.488473 0.912215 +v 0.022978 0.488765 0.911039 +v 0.024722 0.487566 0.907870 +v -0.027463 0.489245 0.906709 +v -0.027775 0.489076 0.905329 +v 0.023685 0.489458 0.910190 +v -0.030859 0.486455 0.905151 +v 0.024460 0.487179 0.909060 +v 0.025090 0.487198 0.908209 +v -0.027277 0.481645 0.904283 +v -0.029474 0.482687 0.902403 +v 0.026809 0.489486 0.908741 +v 0.026661 0.485130 0.905901 +v -0.026808 0.489486 0.908741 +v 0.029474 0.482687 0.902403 +v -0.024460 0.487179 0.909060 +v -0.023685 0.489458 0.910190 +v 0.030859 0.486455 0.905151 +v 0.027463 0.489245 0.906709 +v -0.024093 0.487547 0.908722 +v -0.024768 0.491169 0.914339 +v 0.033941 0.483749 0.903107 +v 0.031672 0.487829 0.904509 +v -0.024453 0.488473 0.912215 +v 0.032128 0.482773 0.904914 +v 0.030007 0.487763 0.903007 +v 0.026981 0.488768 0.906204 +v -0.025090 0.487198 0.908209 +v -0.024722 0.487566 0.907870 +v -0.026121 0.491407 0.912424 +v 0.027775 0.489076 0.905329 +v -0.027480 0.491668 0.910163 +v -0.025160 0.489166 0.911365 +v -0.023671 0.491881 0.910570 +v 0.029194 0.486389 0.903649 +v -0.025030 0.492141 0.908309 +v 0.028258 0.489553 0.905833 +v -0.022260 0.487100 0.911656 +v 0.028326 0.485196 0.907403 +v 0.028909 0.492784 0.903499 +v 0.031415 0.492514 0.905459 +v -0.023106 0.484241 0.909683 +v -0.021824 0.486669 0.911201 +v -0.021542 0.486822 0.912447 +v -0.022321 0.483164 0.913074 +v -0.021105 0.486391 0.911991 +v 0.030153 0.488248 0.901005 +v -0.023840 0.485482 0.909103 +v -0.024610 0.484301 0.911039 +v 0.028297 0.489603 0.904165 +v 0.029007 0.490286 0.903258 +v -0.027394 0.481856 0.909193 +v -0.025756 0.480974 0.910825 +v 0.030515 0.490120 0.904500 +v 0.032218 0.490347 0.901804 +v -0.023358 0.480897 0.908556 +v -0.024996 0.481779 0.906924 +v 0.029501 0.488258 0.901873 +v -0.023772 0.480032 0.912524 +v -0.020816 0.483104 0.911717 +v 0.029886 0.487917 0.902248 +v 0.030538 0.487908 0.901379 +v -0.016087 0.483309 0.921481 +v -0.017805 0.482526 0.924206 +v 0.015844 0.489611 0.924910 +v 0.016956 0.489705 0.924232 +v 0.007913 0.483679 0.924299 +v 0.004470 0.482353 0.928269 +v 0.000552 0.482978 0.926267 +v 0.014232 0.482164 0.925709 +v 0.003915 0.482505 0.926599 +v 0.008546 0.481549 0.927946 +v 0.003405 0.482626 0.926452 +v 0.000646 0.482087 0.928472 +v 0.000558 0.482777 0.926583 +v 0.021379 0.477842 0.917490 +v 0.022173 0.477598 0.918777 +v 0.020071 0.477809 0.918290 +v 0.022321 0.483164 0.913074 +v 0.023083 0.488636 0.914296 +v 0.022296 0.488434 0.915005 +v 0.026993 0.485342 0.908763 +v 0.030709 0.490512 0.900562 +v -0.016956 0.489705 0.924232 +v -0.015167 0.489920 0.923836 +v -0.007913 0.483679 0.924299 +v -0.011748 0.483784 0.922492 +v -0.013316 0.482803 0.924920 +v -0.003628 0.483028 0.926347 +v -0.008350 0.482400 0.927564 +v -0.000743 0.482343 0.928169 +v -0.014232 0.482164 0.925709 +v -0.003915 0.482505 0.926599 +v -0.020181 0.477809 0.918171 +v -0.022283 0.477598 0.918658 +v -0.019612 0.483235 0.912947 +v -0.022774 0.488143 0.915310 +v -0.023561 0.488345 0.914601 +v -0.026661 0.485130 0.905901 +v -0.025328 0.485275 0.907261 +vt 0.429932 0.989021 +vt 0.419189 0.971573 +vt 0.426270 0.982956 +vt 0.285400 0.184570 +vt 0.281494 0.209473 +vt 0.275879 0.197754 +vt 0.245117 0.211426 +vt 0.250244 0.238281 +vt 0.229614 0.238281 +vt 0.252441 0.196289 +vt 0.204834 0.283203 +vt 0.179932 0.238281 +vt 0.204834 0.238770 +vt 0.223511 0.205078 +vt 0.231445 0.184570 +vt 0.238281 0.182129 +vt 0.243774 0.181641 +vt 0.242310 0.175781 +vt 0.245728 0.180664 +vt 0.220825 0.185059 +vt 0.226318 0.167480 +vt 0.237427 0.171387 +vt 0.242676 0.172363 +vt 0.239746 0.169434 +vt 0.244629 0.170410 +vt 0.241699 0.168457 +vt 0.248413 0.170898 +vt 0.244873 0.166504 +vt 0.232178 0.166992 +vt 0.235718 0.160645 +vt 0.235962 0.164551 +vt 0.257080 0.163574 +vt 0.254395 0.157227 +vt 0.285156 0.166016 +vt 0.248169 0.150391 +vt 0.274902 0.152344 +vt 0.230347 0.151367 +vt 0.225586 0.142578 +vt 0.236084 0.139648 +vt 0.228516 0.133301 +vt 0.220459 0.133301 +vt 0.207764 0.131836 +vt 0.215820 0.137695 +vt 0.208862 0.137695 +vt 0.218994 0.145996 +vt 0.215942 0.138184 +vt 0.221924 0.156250 +vt 0.210815 0.147949 +vt 0.208984 0.137695 +vt 0.204834 0.148438 +vt 0.204834 0.137695 +vt 0.200562 0.137695 +vt 0.201782 0.131836 +vt 0.200684 0.137695 +vt 0.217407 0.168457 +vt 0.212769 0.157227 +vt 0.204834 0.157715 +vt 0.198730 0.147949 +vt 0.193726 0.138184 +vt 0.189453 0.133301 +vt 0.196167 0.132813 +vt 0.193726 0.137695 +vt 0.192627 0.131348 +vt 0.192505 0.130859 +vt 0.189209 0.133301 +vt 0.190552 0.145996 +vt 0.196777 0.157227 +vt 0.204834 0.167480 +vt 0.183960 0.142578 +vt 0.181030 0.133301 +vt 0.187622 0.156250 +vt 0.192139 0.168457 +vt 0.204834 0.184082 +vt 0.204834 0.204590 +vt 0.188721 0.185059 +vt 0.183228 0.167480 +vt 0.179199 0.151367 +vt 0.186035 0.205078 +vt 0.178101 0.184570 +vt 0.171265 0.182129 +vt 0.172119 0.171387 +vt 0.156982 0.196289 +vt 0.164429 0.211426 +vt 0.133545 0.197754 +vt 0.110535 0.187012 +vt 0.133667 0.170410 +vt 0.124207 0.184570 +vt 0.128052 0.209473 +vt 0.159180 0.238281 +vt 0.127563 0.258789 +vt 0.142578 0.247559 +vt 0.111816 0.225586 +vt 0.124390 0.237305 +vt 0.105408 0.242676 +vt 0.095947 0.244629 +vt 0.067139 0.240234 +vt 0.063171 0.223145 +vt 0.076355 0.184570 +vt 0.124451 0.166016 +vt 0.096863 0.261719 +vt 0.081116 0.261230 +vt 0.073364 0.250488 +vt 0.051361 0.270508 +vt 0.097229 0.267090 +vt 0.094482 0.264160 +vt 0.069885 0.316406 +vt 0.055481 0.299316 +vt 0.063599 0.296875 +vt 0.060333 0.272949 +vt 0.073486 0.279785 +vt 0.091431 0.270996 +vt 0.099854 0.270020 +vt 0.118103 0.273438 +vt 0.102234 0.267090 +vt 0.096802 0.281738 +vt 0.086121 0.334961 +vt 0.077331 0.326172 +vt 0.085998 0.327148 +vt 0.072815 0.334473 +vt 0.077515 0.317383 +vt 0.075073 0.296387 +vt 0.094177 0.295898 +vt 0.114014 0.289063 +vt 0.108643 0.300781 +vt 0.089966 0.319336 +vt 0.099304 0.322754 +vt 0.132446 0.283203 +vt 0.124878 0.312500 +vt 0.103943 0.328125 +vt 0.083374 0.341797 +vt 0.073059 0.340820 +vt 0.061676 0.319824 +vt 0.209839 0.127930 +vt 0.208984 0.123047 +vt 0.210205 0.124512 +vt 0.204834 0.121094 +vt 0.215088 0.125488 +vt 0.209106 0.123047 +vt 0.213013 0.128906 +vt 0.207886 0.131348 +vt 0.209351 0.127441 +vt 0.204834 0.125000 +vt 0.200562 0.123047 +vt 0.194580 0.125488 +vt 0.199341 0.124512 +vt 0.196533 0.128906 +vt 0.200439 0.123047 +vt 0.199707 0.127930 +vt 0.200195 0.127441 +vt 0.204834 0.129883 +vt 0.198975 0.129883 +vt 0.198364 0.129395 +vt 0.198730 0.130859 +vt 0.201660 0.131348 +vt 0.197632 0.131348 +vt 0.196289 0.132813 +vt 0.193848 0.130859 +vt 0.193848 0.130371 +vt 0.196777 0.130371 +vt 0.197632 0.129883 +vt 0.196899 0.130371 +vt 0.198242 0.129395 +vt 0.198242 0.108887 +vt 0.204834 0.113281 +vt 0.204224 0.114258 +vt 0.193481 0.115723 +vt 0.183838 0.119141 +vt 0.179688 0.126953 +vt 0.173462 0.139648 +vt 0.166260 0.127441 +vt 0.175171 0.112305 +vt 0.190430 0.107422 +vt 0.191040 0.105469 +vt 0.179321 0.104980 +vt 0.179199 0.104492 +vt 0.163208 0.108398 +vt 0.163208 0.108887 +vt 0.163208 0.107910 +vt 0.179199 0.104004 +vt 0.191162 0.104004 +vt 0.191040 0.104492 +vt 0.198975 0.106934 +vt 0.191528 0.102539 +vt 0.199707 0.104980 +vt 0.199341 0.105957 +vt 0.199219 0.106445 +vt 0.204834 0.111816 +vt 0.210571 0.106934 +vt 0.211304 0.108887 +vt 0.204834 0.111328 +vt 0.210327 0.106445 +vt 0.210205 0.105957 +vt 0.204834 0.108887 +vt 0.209839 0.104980 +vt 0.218384 0.104004 +vt 0.218506 0.104492 +vt 0.209595 0.104004 +vt 0.204834 0.106445 +vt 0.199951 0.104004 +vt 0.218506 0.105469 +vt 0.230347 0.104492 +vt 0.230347 0.104004 +vt 0.218018 0.102539 +vt 0.230103 0.102539 +vt 0.246338 0.107422 +vt 0.246338 0.107910 +vt 0.250977 0.108887 +vt 0.251709 0.109863 +vt 0.250732 0.108398 +vt 0.253906 0.110352 +vt 0.246338 0.106934 +vt 0.229736 0.101563 +vt 0.217773 0.102051 +vt 0.256836 0.111816 +vt 0.253662 0.108887 +vt 0.256104 0.108887 +vt 0.249146 0.106934 +vt 0.249756 0.106445 +vt 0.229126 0.100586 +vt 0.228760 0.099609 +vt 0.217651 0.100586 +vt 0.256348 0.108887 +vt 0.249878 0.105957 +vt 0.257813 0.108398 +vt 0.204834 0.105957 +vt 0.217896 0.101563 +vt 0.229980 0.101563 +vt 0.248901 0.107422 +vt 0.251465 0.108398 +vt 0.251709 0.108887 +vt 0.159668 0.105957 +vt 0.180786 0.099609 +vt 0.159790 0.106445 +vt 0.180420 0.100586 +vt 0.191895 0.100586 +vt 0.191772 0.101563 +vt 0.204834 0.103516 +vt 0.217773 0.098633 +vt 0.228760 0.099121 +vt 0.204834 0.101563 +vt 0.191772 0.098145 +vt 0.204834 0.100586 +vt 0.217773 0.098145 +vt 0.228638 0.098633 +vt 0.250000 0.105469 +vt 0.250488 0.101563 +vt 0.229980 0.093262 +vt 0.245972 0.064941 +vt 0.204834 0.070801 +vt 0.163574 0.064941 +vt 0.204834 0.048828 +vt 0.233643 0.078125 +vt 0.217285 0.090820 +vt 0.218140 0.097168 +vt 0.179565 0.093262 +vt 0.159058 0.101563 +vt 0.175903 0.078125 +vt 0.204834 0.081055 +vt 0.215942 0.084961 +vt 0.204834 0.094727 +vt 0.204834 0.099609 +vt 0.191406 0.097168 +vt 0.192261 0.090820 +vt 0.193604 0.084961 +vt 0.181030 0.098633 +vt 0.180786 0.099121 +vt 0.191772 0.098633 +vt 0.159546 0.105469 +vt 0.152710 0.049805 +vt 0.204834 0.032715 +vt 0.137451 0.097656 +vt 0.147949 0.107422 +vt 0.151611 0.108398 +vt 0.125244 0.080078 +vt 0.145508 0.029297 +vt 0.125854 0.112793 +vt 0.146484 0.113770 +vt 0.151367 0.112793 +vt 0.153076 0.108887 +vt 0.160400 0.106934 +vt 0.153442 0.108887 +vt 0.179565 0.101563 +vt 0.160767 0.107422 +vt 0.155762 0.108887 +vt 0.152710 0.111816 +vt 0.152344 0.112305 +vt 0.155640 0.110352 +vt 0.157959 0.108398 +vt 0.157837 0.108887 +vt 0.158813 0.108398 +vt 0.135498 0.121582 +vt 0.151367 0.116699 +vt 0.158081 0.110840 +vt 0.157715 0.110352 +vt 0.157837 0.109863 +vt 0.158447 0.108887 +vt 0.156128 0.117188 +vt 0.163208 0.107422 +vt 0.179443 0.102539 +vt 0.163208 0.106934 +vt 0.179810 0.101563 +vt 0.191772 0.102051 +vt 0.867188 0.906372 +vt 0.887207 0.879517 +vt 0.905273 0.898254 +vt 0.867676 0.917480 +vt 0.907227 0.924500 +vt 0.863770 0.925354 +vt 0.886719 0.944214 +vt 0.857910 0.928772 +vt 0.858887 0.952637 +vt 0.829590 0.946686 +vt 0.852051 0.925903 +vt 0.848145 0.917603 +vt 0.809570 0.924561 +vt 0.848633 0.907227 +vt 0.809082 0.897461 +vt 0.852051 0.898315 +vt 0.832520 0.878357 +vt 0.857422 0.895874 +vt 0.857910 0.872681 +vt 0.863281 0.898499 +vt 0.873535 0.894836 +vt 0.908691 0.899109 +vt 0.884277 0.907043 +vt 0.889160 0.878113 +vt 0.854980 0.914490 +vt 0.826172 0.906982 +vt 0.836914 0.894836 +vt 0.854980 0.890503 +vt 0.857910 0.870117 +vt 0.890137 0.877380 +vt 0.909668 0.898804 +vt 0.909668 0.925293 +vt 0.908691 0.925049 +vt 0.857910 0.869141 +vt 0.910156 0.854980 +vt 0.944336 0.891296 +vt 0.944336 0.936157 +vt 0.910156 0.972412 +vt 0.890137 0.946716 +vt 0.854492 0.985329 +vt 0.857910 0.954987 +vt 0.889160 0.945923 +vt 0.857910 0.954010 +vt 0.825195 0.946930 +vt 0.826172 0.946136 +vt 0.805176 0.925415 +vt 0.806152 0.925110 +vt 0.805176 0.898743 +vt 0.806152 0.899048 +vt 0.825195 0.877197 +vt 0.826172 0.877991 +vt 0.825684 0.921997 +vt 0.837402 0.933899 +vt 0.855469 0.938629 +vt 0.884766 0.921997 +vt 0.873047 0.933838 +vt 0.803711 0.970551 +vt 0.772949 0.935120 +vt 0.773438 0.891663 +vt 0.803223 0.857544 +vt 0.854980 0.841064 +vt 0.934570 0.917969 +vt 0.938477 0.919189 +vt 0.934570 0.920410 +vt 0.936035 0.915955 +vt 0.938477 0.915283 +vt 0.940918 0.915955 +vt 0.942383 0.917969 +vt 0.942383 0.920410 +vt 0.940918 0.922363 +vt 0.936035 0.922363 +vt 0.938477 0.923157 +vt 0.938477 0.923645 +vt 0.941406 0.922791 +vt 0.943359 0.920593 +vt 0.942871 0.917786 +vt 0.941406 0.915527 +vt 0.938477 0.914673 +vt 0.936035 0.915527 +vt 0.934082 0.917786 +vt 0.934082 0.920593 +vt 0.936035 0.922791 +vt 0.865234 0.267578 +vt 0.867188 0.289063 +vt 0.867188 0.288574 +vt 0.867676 0.314453 +vt 0.866699 0.313965 +vt 0.866211 0.345703 +vt 0.865234 0.345215 +vt 0.864746 0.287109 +vt 0.864746 0.305664 +vt 0.863281 0.324707 +vt 0.862793 0.324707 +vt 0.860840 0.344238 +vt 0.860352 0.344238 +vt 0.866211 0.288086 +vt 0.868164 0.307617 +vt 0.868652 0.328125 +vt 0.868164 0.328125 +vt 0.868652 0.349121 +vt 0.868164 0.349121 +vt 0.862793 0.309570 +vt 0.858398 0.321289 +vt 0.857910 0.321289 +vt 0.853516 0.333984 +vt 0.853027 0.333984 +vt 0.867676 0.297852 +vt 0.870605 0.315918 +vt 0.870117 0.315918 +vt 0.875000 0.336426 +vt 0.874023 0.336426 +vt 0.869141 0.288574 +vt 0.868652 0.308105 +vt 0.866211 0.327637 +vt 0.865723 0.327148 +vt 0.861816 0.346680 +vt 0.860840 0.346680 +vt 0.873047 0.263184 +vt 0.871094 0.280762 +vt 0.869629 0.301758 +vt 0.869141 0.301758 +vt 0.870605 0.324219 +vt 0.870117 0.323730 +vt 0.872559 0.358398 +vt 0.871582 0.357910 +vt 0.868652 0.329102 +vt 0.871094 0.309082 +vt 0.869141 0.329102 +vt 0.870605 0.309082 +vt 0.873047 0.290039 +vt 0.872559 0.290039 +vt 0.876953 0.272461 +vt 0.775879 0.330078 +vt 0.755371 0.315430 +vt 0.752441 0.329590 +vt 0.772949 0.315918 +vt 0.762695 0.291504 +vt 0.769043 0.291992 +vt 0.956543 0.649658 +vt 0.931641 0.651855 +vt 0.930664 0.649902 +vt 0.871094 0.328613 +vt 0.871094 0.308105 +vt 0.871582 0.328613 +vt 0.870605 0.308105 +vt 0.870605 0.288574 +vt 0.870117 0.288574 +vt 0.872070 0.270508 +vt 0.955078 0.651123 +vt 0.870605 0.325195 +vt 0.870117 0.304688 +vt 0.871094 0.325195 +vt 0.869629 0.304688 +vt 0.869629 0.285156 +vt 0.869141 0.285156 +vt 0.870605 0.266602 +vt 0.900391 0.649902 +vt 0.900391 0.648438 +vt 0.861816 0.308594 +vt 0.861328 0.292969 +vt 0.862305 0.308594 +vt 0.860840 0.292969 +vt 0.859375 0.278809 +vt 0.860352 0.323242 +vt 0.865234 0.304688 +vt 0.860840 0.323242 +vt 0.864258 0.304688 +vt 0.867676 0.288574 +vt 0.881836 0.653809 +vt 0.881348 0.650146 +vt 0.875488 0.334473 +vt 0.872559 0.312988 +vt 0.876465 0.333984 +vt 0.871582 0.312988 +vt 0.870605 0.291992 +vt 0.870117 0.291992 +vt 0.870605 0.271973 +vt 0.865234 0.331055 +vt 0.865234 0.310059 +vt 0.866211 0.331055 +vt 0.864746 0.310059 +vt 0.865234 0.290527 +vt 0.863770 0.352539 +vt 0.866211 0.318848 +vt 0.864746 0.352539 +vt 0.865723 0.318848 +vt 0.866699 0.296875 +vt 0.866211 0.296875 +vt 0.865234 0.275879 +vt 0.864746 0.275879 +vt 0.862793 0.257813 +vt 0.875000 0.354004 +vt 0.871582 0.320801 +vt 0.875488 0.354004 +vt 0.871094 0.320801 +vt 0.869141 0.293945 +vt 0.868652 0.293945 +vt 0.869141 0.272461 +vt 0.761719 0.330078 +vt 0.750000 0.304688 +vt 0.759277 0.309570 +vt 0.742676 0.330078 +vt 0.776855 0.330078 +vt 0.789551 0.309082 +vt 0.778809 0.312988 +vt 0.797852 0.330078 +vt 0.762695 0.330078 +vt 0.750000 0.305664 +vt 0.743652 0.330078 +vt 0.782715 0.328613 +vt 0.754395 0.293457 +vt 0.746582 0.328613 +vt 0.776367 0.293457 +vt 0.767578 0.330078 +vt 0.780762 0.306641 +vt 0.769531 0.311035 +vt 0.789063 0.330078 +vt 0.781738 0.330078 +vt 0.748535 0.292969 +vt 0.748047 0.330078 +vt 0.771973 0.292969 +vt 0.787109 0.330078 +vt 0.748047 0.292969 +vt 0.751953 0.330078 +vt 0.779785 0.292480 +vt 0.793945 0.330078 +vt 0.753418 0.292480 +vt 0.744629 0.330078 +vt 0.787109 0.292480 +vt 0.753418 0.330078 +vt 0.777832 0.291992 +vt 0.757324 0.291992 +vt 0.783203 0.330078 +vt 0.731445 0.330078 +vt 0.759766 0.291504 +vt 0.732422 0.291992 +vt 0.761230 0.330078 +vt 0.735352 0.330078 +vt 0.772461 0.291992 +vt 0.746582 0.291992 +vt 0.773438 0.330078 +vt 0.753418 0.313477 +vt 0.764160 0.291992 +vt 0.757813 0.291992 +vt 0.770020 0.313477 +vt 0.748535 0.330078 +vt 0.769043 0.330566 +vt 0.031067 0.621582 +vt 0.101807 0.689453 +vt 0.011124 0.689941 +vt 0.090027 0.608398 +vt 0.038086 0.567383 +vt 0.081909 0.560303 +vt 0.044464 0.511475 +vt 0.058838 0.506348 +vt 0.077942 0.509521 +vt 0.135498 0.556152 +vt 0.175049 0.603516 +vt 0.217163 0.690430 +vt 0.865234 0.550293 +vt 0.884277 0.566406 +vt 0.873047 0.562012 +vt 0.748535 0.272461 +vt 0.761230 0.247559 +vt 0.757324 0.247559 +vt 0.755859 0.272949 +vt 0.770996 0.272949 +vt 0.772949 0.246582 +vt 0.769043 0.249023 +vt 0.778809 0.272949 +vt 0.763184 0.272949 +vt 0.765137 0.249023 +vt 0.615234 0.347656 +vt 0.614746 0.350586 +vt 0.613281 0.347656 +vt 0.611328 0.347656 +vt 0.610352 0.365723 +vt 0.629395 0.347656 +vt 0.627441 0.366699 +vt 0.622070 0.347656 +vt 0.619141 0.347656 +vt 0.617676 0.347656 +vt 0.615723 0.347656 +vt 0.616699 0.347656 +vt 0.625488 0.375977 +vt 0.584473 0.400879 +vt 0.628418 0.370117 +vt 0.643066 0.369141 +vt 0.654785 0.386230 +vt 0.544434 0.448242 +vt 0.584961 0.497559 +vt 0.542480 0.484863 +vt 0.588379 0.467285 +vt 0.552246 0.428711 +vt 0.592773 0.437988 +vt 0.625977 0.403809 +vt 0.656738 0.413574 +vt 0.683105 0.421387 +vt 0.629883 0.439941 +vt 0.663086 0.447266 +vt 0.693848 0.451172 +vt 0.627441 0.499512 +vt 0.666016 0.512939 +vt 0.706543 0.510986 +vt 0.719238 0.460938 +vt 0.717285 0.430664 +vt 0.750000 0.459473 +vt 0.742188 0.430664 +vt 0.661621 0.537598 +vt 0.706543 0.535889 +vt 0.724609 0.499512 +vt 0.758789 0.486816 +vt 0.783691 0.452148 +vt 0.792480 0.468262 +vt 0.814941 0.432129 +vt 0.812012 0.419922 +vt 0.821777 0.409180 +vt 0.824219 0.418457 +vt 0.832031 0.427734 +vt 0.772949 0.424316 +vt 0.814453 0.410156 +vt 0.825195 0.398438 +vt 0.869629 0.395020 +vt 0.872070 0.404785 +vt 0.871582 0.417480 +vt 0.812500 0.396484 +vt 0.830078 0.388184 +vt 0.869629 0.384277 +vt 0.923828 0.389648 +vt 0.921387 0.397461 +vt 0.920410 0.410645 +vt 0.935059 0.408691 +vt 0.933594 0.416992 +vt 0.949707 0.410156 +vt 0.874023 0.427734 +vt 0.920410 0.420410 +vt 0.927734 0.379883 +vt 0.944336 0.382813 +vt 0.941406 0.391113 +vt 0.937988 0.398438 +vt 0.948730 0.401855 +vt 0.958984 0.401855 +vt 0.954102 0.412109 +vt 0.964844 0.402344 +vt 0.960449 0.410156 +vt 0.955078 0.416992 +vt 0.965332 0.411133 +vt 0.965332 0.410156 +vt 0.972656 0.403809 +vt 0.968750 0.395508 +vt 0.975098 0.404297 +vt 0.970215 0.394043 +vt 0.972168 0.414063 +vt 0.978027 0.405273 +vt 0.993164 0.415527 +vt 0.979980 0.406738 +vt 0.995605 0.414551 +vt 0.996582 0.412109 +vt 0.996582 0.408691 +vt 0.993652 0.407227 +vt 0.979004 0.403809 +vt 0.990234 0.405273 +vt 0.981934 0.402832 +vt 0.980469 0.394531 +vt 0.980957 0.395020 +vt 0.982422 0.397461 +vt 0.991211 0.401367 +vt 0.992188 0.402344 +vt 0.992676 0.401855 +vt 0.998047 0.397949 +vt 0.997070 0.393066 +vt 0.988770 0.392090 +vt 0.985352 0.387695 +vt 0.984375 0.388672 +vt 0.979004 0.388184 +vt 0.980957 0.391113 +vt 0.977051 0.386719 +vt 0.985840 0.390625 +vt 0.980469 0.393066 +vt 0.973145 0.384277 +vt 0.986328 0.386719 +vt 0.961426 0.384766 +vt 0.951172 0.392090 +vt 0.958984 0.391113 +vt 0.963867 0.394531 +vt 0.887695 0.555176 +vt 0.886719 0.796143 +vt 0.861816 0.789307 +vt 0.904297 0.792603 +vt 0.872070 0.795898 +vt 0.913574 0.792603 +vt 0.902832 0.808228 +vt 0.886719 0.803833 +vt 0.868652 0.805054 +vt 0.861816 0.807861 +vt 0.849121 0.809937 +vt 0.846680 0.793335 +vt 0.814941 0.810791 +vt 0.882324 0.807129 +vt 0.823730 0.832031 +vt 0.852539 0.825317 +vt 0.863281 0.821899 +vt 0.868652 0.819946 +vt 0.872070 0.806519 +vt 0.882324 0.812134 +vt 0.885254 0.814331 +vt 0.871582 0.815430 +vt 0.900391 0.816406 +vt 0.911133 0.811890 +vt 0.924805 0.805542 +vt 0.925293 0.814941 +vt 0.932129 0.813110 +vt 0.937500 0.803223 +vt 0.944336 0.809326 +vt 0.959473 0.798340 +vt 0.921387 0.820557 +vt 0.909668 0.819580 +vt 0.928223 0.797607 +vt 0.924316 0.790039 +vt 0.915039 0.774414 +vt 0.904297 0.774658 +vt 0.863281 0.777222 +vt 0.845703 0.779419 +vt 0.861328 0.759277 +vt 0.841797 0.760742 +vt 0.904785 0.756104 +vt 0.915527 0.755981 +vt 0.928711 0.754517 +vt 0.931152 0.739746 +vt 0.932617 0.748291 +vt 0.942383 0.744629 +vt 0.943848 0.738281 +vt 0.904297 0.737793 +vt 0.915527 0.736084 +vt 0.937012 0.736328 +vt 0.954102 0.733154 +vt 0.953613 0.735596 +vt 0.958984 0.741211 +vt 0.957031 0.740479 +vt 0.955566 0.740723 +vt 0.954590 0.741699 +vt 0.950684 0.738037 +vt 0.954102 0.737305 +vt 0.947754 0.738037 +vt 0.952637 0.743164 +vt 0.964355 0.743408 +vt 0.947266 0.752441 +vt 0.966309 0.748047 +vt 0.946777 0.754272 +vt 0.962402 0.756104 +vt 0.948242 0.755859 +vt 0.969238 0.769653 +vt 0.955078 0.772339 +vt 0.950195 0.772583 +vt 0.955566 0.774414 +vt 0.934082 0.774048 +vt 0.941406 0.749023 +vt 0.944824 0.753052 +vt 0.932129 0.754883 +vt 0.945801 0.756348 +vt 0.943359 0.790039 +vt 0.929199 0.790283 +vt 0.928711 0.774536 +vt 0.937012 0.798462 +vt 0.942383 0.793823 +vt 0.950195 0.775879 +vt 0.947266 0.791260 +vt 0.944824 0.792969 +vt 0.944336 0.794434 +vt 0.958496 0.795654 +vt 0.963379 0.793335 +vt 0.968262 0.777588 +vt 0.954590 0.776611 +vt 0.966797 0.773804 +vt 0.892090 0.575928 +vt 0.901367 0.569336 +vt 0.901367 0.577393 +vt 0.701172 0.258301 +vt 0.707520 0.235352 +vt 0.727539 0.234863 +vt 0.690430 0.257324 +vt 0.666992 0.258301 +vt 0.677246 0.295898 +vt 0.667480 0.297852 +vt 0.677734 0.257324 +vt 0.660156 0.235352 +vt 0.684082 0.256836 +vt 0.684082 0.234375 +vt 0.684082 0.294434 +vt 0.690918 0.295898 +vt 0.700195 0.297852 +vt 0.968262 0.418945 +vt 0.974609 0.421387 +vt 0.973145 0.421875 +vt 0.971680 0.417969 +vt 0.971680 0.416504 +vt 0.965332 0.418945 +vt 0.972656 0.422363 +vt 0.976563 0.421875 +vt 0.961426 0.418945 +vt 0.970703 0.424316 +vt 0.981934 0.424316 +vt 0.980469 0.437012 +vt 0.964844 0.435059 +vt 0.983887 0.428711 +vt 0.964844 0.433105 +vt 0.959961 0.425293 +vt 0.949219 0.420410 +vt 0.984375 0.455078 +vt 0.972656 0.452637 +vt 0.987305 0.450195 +vt 0.965820 0.437012 +vt 0.949707 0.435547 +vt 0.962402 0.434082 +vt 0.958984 0.430176 +vt 0.950684 0.429199 +vt 0.946777 0.435547 +vt 0.946289 0.455078 +vt 0.932617 0.455566 +vt 0.941406 0.471191 +vt 0.933105 0.437012 +vt 0.921387 0.437988 +vt 0.920898 0.455566 +vt 0.883301 0.477051 +vt 0.878418 0.461914 +vt 0.920898 0.473633 +vt 0.930664 0.473633 +vt 0.942383 0.486816 +vt 0.874023 0.443848 +vt 0.840820 0.448242 +vt 0.845215 0.460938 +vt 0.853516 0.479004 +vt 0.856445 0.497559 +vt 0.887695 0.491699 +vt 0.822754 0.451660 +vt 0.827637 0.464355 +vt 0.839844 0.480469 +vt 0.848633 0.498535 +vt 0.827637 0.507813 +vt 0.807617 0.495605 +vt 0.796875 0.484375 +vt 0.764160 0.502197 +vt 0.733887 0.518066 +vt 0.781738 0.509277 +vt 0.756348 0.523926 +vt 0.750000 0.537109 +vt 0.795898 0.530762 +vt 0.793457 0.541504 +vt 0.811035 0.519287 +vt 0.678711 0.714600 +vt 0.646484 0.671631 +vt 0.676758 0.677734 +vt 0.651367 0.637451 +vt 0.692383 0.639160 +vt 0.653320 0.600098 +vt 0.694824 0.605957 +vt 0.660156 0.558594 +vt 0.704102 0.567139 +vt 0.743652 0.574951 +vt 0.775879 0.581543 +vt 0.781738 0.541504 +vt 0.720215 0.675293 +vt 0.725098 0.642334 +vt 0.733398 0.609131 +vt 0.766602 0.613525 +vt 0.761719 0.640869 +vt 0.762207 0.668213 +vt 0.764648 0.695313 +vt 0.754883 0.697754 +vt 0.759766 0.697754 +vt 0.717285 0.707520 +vt 0.800293 0.714600 +vt 0.787109 0.701660 +vt 0.808594 0.701904 +vt 0.762207 0.717041 +vt 0.773438 0.699219 +vt 0.754395 0.716064 +vt 0.744141 0.727051 +vt 0.713379 0.729248 +vt 0.715332 0.750000 +vt 0.741699 0.751099 +vt 0.854492 0.716797 +vt 0.904297 0.727539 +vt 0.854492 0.729004 +vt 0.837891 0.728760 +vt 0.837891 0.716797 +vt 0.798340 0.727295 +vt 0.761719 0.729492 +vt 0.764648 0.750000 +vt 0.884277 0.710693 +vt 0.865234 0.706055 +vt 0.887695 0.706299 +vt 0.908203 0.707520 +vt 0.904785 0.715820 +vt 0.865723 0.710938 +vt 0.854004 0.706543 +vt 0.839355 0.706299 +vt 0.923828 0.709717 +vt 0.919922 0.717529 +vt 0.931641 0.720947 +vt 0.934082 0.711182 +vt 0.916992 0.727783 +vt 0.932129 0.729980 +vt 0.941406 0.720947 +vt 0.940918 0.710205 +vt 0.943359 0.704102 +vt 0.952637 0.713379 +vt 0.962402 0.713379 +vt 0.959961 0.724121 +vt 0.961426 0.723145 +vt 0.937012 0.730957 +vt 0.947266 0.721680 +vt 0.945801 0.713623 +vt 0.950684 0.714600 +vt 0.957031 0.723633 +vt 0.955078 0.722900 +vt 0.947266 0.729248 +vt 0.942871 0.729004 +vt 0.947266 0.730469 +vt 0.962402 0.726074 +vt 0.975098 0.734619 +vt 0.968750 0.735840 +vt 0.969727 0.738281 +vt 0.971680 0.732910 +vt 0.958984 0.732422 +vt 0.955566 0.732666 +vt 0.970215 0.739746 +vt 0.963379 0.729004 +vt 0.978027 0.733887 +vt 0.978516 0.730957 +vt 0.978516 0.727783 +vt 0.976074 0.726318 +vt 0.974609 0.721191 +vt 0.973633 0.720703 +vt 0.964844 0.716553 +vt 0.962891 0.714355 +vt 0.974609 0.720947 +vt 0.972656 0.724609 +vt 0.963867 0.721680 +vt 0.979980 0.717529 +vt 0.966797 0.707764 +vt 0.970703 0.711426 +vt 0.968262 0.709717 +vt 0.962402 0.711914 +vt 0.955566 0.703369 +vt 0.979004 0.712158 +vt 0.967773 0.707031 +vt 0.960938 0.707031 +vt 0.963379 0.710205 +vt 0.958984 0.705811 +vt 0.968750 0.705811 +vt 0.499023 0.214844 +vt 0.532715 0.288574 +vt 0.499023 0.288574 +vt 0.499023 0.359863 +vt 0.535156 0.356445 +vt 0.561523 0.288574 +vt 0.525879 0.214844 +vt 0.554199 0.214844 +vt 0.521973 0.144043 +vt 0.549316 0.144043 +vt 0.521973 0.068359 +vt 0.499023 0.068359 +vt 0.499023 0.024414 +vt 0.499023 0.144043 +vt 0.524902 0.028809 +vt 0.542969 0.068359 +vt 0.577148 0.144043 +vt 0.581055 0.214844 +vt 0.587402 0.288574 +vt 0.563477 0.353027 +vt 0.592285 0.346191 +vt 0.534668 0.027832 +vt 0.562988 0.068359 +vt 0.548828 0.028320 +vt 0.609863 0.214844 +vt 0.604980 0.144043 +vt 0.581543 0.068359 +vt 0.563965 0.022949 +vt 0.531738 0.012695 +vt 0.499023 0.390137 +vt 0.549805 0.400391 +vt 0.612305 0.333984 +vt 0.616699 0.288574 +vt 0.445557 0.428711 +vt 0.447998 0.400391 +vt 0.499023 0.413574 +vt 0.499023 0.436523 +vt 0.499023 0.471680 +vt 0.545410 0.537109 +vt 0.499023 0.526123 +vt 0.543457 0.573730 +vt 0.538574 0.641602 +vt 0.570313 0.687256 +vt 0.535645 0.673828 +vt 0.575195 0.650879 +vt 0.540527 0.607178 +vt 0.574707 0.614990 +vt 0.575684 0.580078 +vt 0.581055 0.541748 +vt 0.616699 0.661865 +vt 0.614746 0.627686 +vt 0.617676 0.591553 +vt 0.618652 0.548828 +vt 0.618652 0.522461 +vt 0.644531 0.706787 +vt 0.711914 0.813354 +vt 0.720215 0.839844 +vt 0.686523 0.829346 +vt 0.682617 0.793579 +vt 0.646973 0.815063 +vt 0.675293 0.761353 +vt 0.638184 0.766479 +vt 0.642090 0.732666 +vt 0.677734 0.730957 +vt 0.725586 0.776489 +vt 0.748047 0.771362 +vt 0.736328 0.796631 +vt 0.760254 0.790161 +vt 0.770508 0.768066 +vt 0.779785 0.786865 +vt 0.799805 0.763184 +vt 0.806641 0.783813 +vt 0.811523 0.796509 +vt 0.788086 0.799927 +vt 0.769531 0.805420 +vt 0.752441 0.815063 +vt 0.737793 0.824951 +vt 0.799805 0.812134 +vt 0.783691 0.819214 +vt 0.770996 0.825195 +vt 0.797852 0.845459 +vt 0.806641 0.837646 +vt 0.812988 0.835205 +vt 0.743164 0.851929 +vt 0.761719 0.890564 +vt 0.736328 0.879700 +vt 0.766602 0.871826 +vt 0.763184 0.838135 +vt 0.784180 0.849487 +vt 0.790527 0.842163 +vt 0.770996 0.828369 +vt 0.712402 0.867554 +vt 0.737305 0.904846 +vt 0.711914 0.893921 +vt 0.738770 0.930969 +vt 0.716797 0.919373 +vt 0.678711 0.877747 +vt 0.687012 0.907593 +vt 0.658691 0.896118 +vt 0.643555 0.871460 +vt 0.628418 0.898193 +vt 0.679688 0.851196 +vt 0.640625 0.841675 +vt 0.609863 0.837036 +vt 0.603516 0.803223 +vt 0.602539 0.761108 +vt 0.603027 0.725342 +vt 0.608887 0.697021 +vt 0.553223 0.788696 +vt 0.573242 0.820923 +vt 0.557617 0.757324 +vt 0.562012 0.722412 +vt 0.499023 0.841553 +vt 0.535156 0.816650 +vt 0.538574 0.850586 +vt 0.525879 0.785278 +vt 0.529297 0.746582 +vt 0.531250 0.707520 +vt 0.499023 0.702637 +vt 0.499023 0.743652 +vt 0.499023 0.779175 +vt 0.499023 0.812622 +vt 0.462402 0.816650 +vt 0.458984 0.850586 +vt 0.424316 0.820923 +vt 0.423828 0.863647 +vt 0.387939 0.837036 +vt 0.444336 0.788696 +vt 0.471680 0.785278 +vt 0.468506 0.746582 +vt 0.357178 0.841675 +vt 0.394287 0.803223 +vt 0.440186 0.757324 +vt 0.466797 0.707520 +vt 0.499023 0.668945 +vt 0.461914 0.673828 +vt 0.499023 0.635742 +vt 0.459229 0.641602 +vt 0.318848 0.877747 +vt 0.318115 0.851196 +vt 0.350830 0.815063 +vt 0.395020 0.761108 +vt 0.435547 0.722412 +vt 0.427246 0.687256 +vt 0.317383 0.732666 +vt 0.350586 0.706543 +vt 0.352295 0.733154 +vt 0.322021 0.761353 +vt 0.359619 0.766479 +vt 0.390137 0.726563 +vt 0.384033 0.697021 +vt 0.422363 0.650879 +vt 0.380859 0.661865 +vt 0.423340 0.614990 +vt 0.457275 0.607178 +vt 0.454102 0.573730 +vt 0.383057 0.627686 +vt 0.422119 0.580078 +vt 0.452637 0.537109 +vt 0.416748 0.541748 +vt 0.455078 0.484863 +vt 0.499023 0.604004 +vt 0.499023 0.569092 +vt 0.453125 0.448242 +vt 0.409180 0.467285 +vt 0.405029 0.437988 +vt 0.367920 0.439941 +vt 0.371582 0.403809 +vt 0.334717 0.447266 +vt 0.341309 0.413574 +vt 0.303955 0.451172 +vt 0.314941 0.421387 +vt 0.413086 0.400879 +vt 0.372314 0.375977 +vt 0.342773 0.386230 +vt 0.314453 0.398926 +vt 0.280273 0.430664 +vt 0.354736 0.369141 +vt 0.337646 0.362793 +vt 0.355957 0.362793 +vt 0.354004 0.347656 +vt 0.364014 0.358887 +vt 0.337158 0.347656 +vt 0.293701 0.349121 +vt 0.307373 0.382813 +vt 0.283447 0.406250 +vt 0.255371 0.430664 +vt 0.255859 0.412598 +vt 0.387451 0.365723 +vt 0.369141 0.370117 +vt 0.370605 0.366699 +vt 0.366943 0.361816 +vt 0.368164 0.347656 +vt 0.361572 0.347656 +vt 0.383057 0.350586 +vt 0.386230 0.347656 +vt 0.384277 0.347656 +vt 0.382324 0.347656 +vt 0.382080 0.347656 +vt 0.380127 0.347656 +vt 0.378906 0.347656 +vt 0.375977 0.347656 +vt 0.381104 0.347656 +vt 0.893066 0.569336 +vt 0.768555 0.408691 +vt 0.744629 0.393066 +vt 0.769531 0.394043 +vt 0.811523 0.381836 +vt 0.710938 0.349609 +vt 0.717773 0.388672 +vt 0.690430 0.382813 +vt 0.733398 0.357910 +vt 0.757324 0.365723 +vt 0.781738 0.374512 +vt 0.641602 0.362793 +vt 0.660156 0.362793 +vt 0.683105 0.399414 +vt 0.714355 0.406250 +vt 0.741699 0.412598 +vt 0.704102 0.349121 +vt 0.660645 0.347656 +vt 0.643555 0.347656 +vt 0.633789 0.358887 +vt 0.636230 0.347656 +vt 0.630859 0.361816 +vt 0.795410 0.745605 +vt 0.839844 0.744141 +vt 0.857422 0.740723 +vt 0.607422 0.916748 +vt 0.609375 0.950134 +vt 0.596191 0.934814 +vt 0.587402 0.957153 +vt 0.600098 0.969849 +vt 0.578613 0.971573 +vt 0.583984 0.979706 +vt 0.567871 0.989029 +vt 0.573242 0.967407 +vt 0.576660 0.942200 +vt 0.583984 0.916931 +vt 0.594238 0.898132 +vt 0.609375 0.876160 +vt 0.562012 0.965790 +vt 0.573242 0.973816 +vt 0.562012 0.935181 +vt 0.550293 0.943542 +vt 0.554688 0.970230 +vt 0.541992 0.962036 +vt 0.564941 0.973328 +vt 0.562988 0.981644 +vt 0.533203 0.947388 +vt 0.540039 0.965912 +vt 0.529297 0.954102 +vt 0.552246 0.976379 +vt 0.562012 0.988914 +vt 0.571777 0.982956 +vt 0.551758 0.978653 +vt 0.562988 0.990318 +vt 0.567383 0.990440 +vt 0.584473 0.980591 +vt 0.601563 0.969971 +vt 0.613770 0.964020 +vt 0.644531 0.957397 +vt 0.632813 0.930542 +vt 0.641602 0.918396 +vt 0.661621 0.918152 +vt 0.691406 0.928955 +vt 0.719727 0.938812 +vt 0.737305 0.947693 +vt 0.758789 0.957794 +vt 0.760742 0.937714 +vt 0.761719 0.916260 +vt 0.885742 0.572266 +vt 0.776367 0.330078 +vt 0.789063 0.309082 +vt 0.796875 0.330078 +vt 0.778320 0.312988 +vt 0.762207 0.330078 +vt 0.749512 0.305664 +vt 0.743164 0.330078 +vt 0.758789 0.309570 +vt 0.782227 0.328613 +vt 0.753906 0.293457 +vt 0.775879 0.293457 +vt 0.745605 0.328613 +vt 0.767090 0.330078 +vt 0.780273 0.306641 +vt 0.788574 0.330078 +vt 0.769043 0.311035 +vt 0.771973 0.315918 +vt 0.762207 0.291504 +vt 0.768066 0.291992 +vt 0.754883 0.315430 +vt 0.775391 0.330078 +vt 0.751465 0.329590 +vt 0.786621 0.330078 +vt 0.747559 0.292969 +vt 0.779297 0.292480 +vt 0.751465 0.330078 +vt 0.793457 0.330078 +vt 0.752930 0.292480 +vt 0.786621 0.292480 +vt 0.744141 0.330078 +vt 0.730469 0.330078 +vt 0.759277 0.291992 +vt 0.760742 0.330078 +vt 0.731934 0.291992 +vt 0.734863 0.330566 +vt 0.771973 0.291992 +vt 0.772949 0.330078 +vt 0.746094 0.291992 +vt 0.768555 0.249023 +vt 0.760742 0.247559 +vt 0.764648 0.249023 +vt 0.772461 0.246582 +vt 0.748047 0.272461 +vt 0.756348 0.247559 +vt 0.755371 0.272949 +vt 0.770508 0.272949 +vt 0.777832 0.272949 +vt 0.762695 0.272949 +vt 0.111206 0.796143 +vt 0.135864 0.789307 +vt 0.125854 0.795898 +vt 0.093506 0.792603 +vt 0.095276 0.808228 +vt 0.084412 0.792603 +vt 0.111145 0.803833 +vt 0.129272 0.805054 +vt 0.135864 0.807861 +vt 0.148682 0.809937 +vt 0.150879 0.793335 +vt 0.182739 0.810791 +vt 0.115601 0.807129 +vt 0.145264 0.825317 +vt 0.134521 0.821899 +vt 0.129028 0.819946 +vt 0.125732 0.806519 +vt 0.115479 0.812134 +vt 0.112671 0.814331 +vt 0.097656 0.816406 +vt 0.126465 0.815430 +vt 0.086792 0.811890 +vt 0.073242 0.805542 +vt 0.073730 0.790039 +vt 0.069580 0.797607 +vt 0.068481 0.790283 +vt 0.061035 0.798462 +vt 0.055572 0.793823 +vt 0.053558 0.794434 +vt 0.060577 0.803223 +vt 0.065552 0.813110 +vt 0.072693 0.814941 +vt 0.076233 0.820557 +vt 0.088257 0.819580 +vt 0.039551 0.795654 +vt 0.038422 0.798340 +vt 0.053741 0.809326 +vt 0.053223 0.792969 +vt 0.034546 0.793213 +vt 0.050629 0.791260 +vt 0.029617 0.777588 +vt 0.043243 0.776611 +vt 0.031280 0.773804 +vt 0.042175 0.774414 +vt 0.042969 0.772217 +vt 0.047852 0.772583 +vt 0.063843 0.774048 +vt 0.052124 0.756348 +vt 0.054352 0.790039 +vt 0.047607 0.775879 +vt 0.049683 0.755859 +vt 0.065918 0.754883 +vt 0.069031 0.774536 +vt 0.082581 0.774414 +vt 0.069092 0.754517 +vt 0.065002 0.748291 +vt 0.056702 0.749023 +vt 0.053070 0.753052 +vt 0.092896 0.756104 +vt 0.093689 0.774658 +vt 0.082397 0.755981 +vt 0.066834 0.739746 +vt 0.055725 0.744629 +vt 0.050781 0.752441 +vt 0.051025 0.754272 +vt 0.033539 0.743408 +vt 0.031799 0.748047 +vt 0.035217 0.756104 +vt 0.043213 0.741699 +vt 0.038971 0.741211 +vt 0.044983 0.743164 +vt 0.054047 0.738281 +vt 0.060761 0.736328 +vt 0.082275 0.736084 +vt 0.093750 0.737793 +vt 0.047363 0.738037 +vt 0.042328 0.740723 +vt 0.050354 0.738037 +vt 0.043762 0.733154 +vt 0.050415 0.730469 +vt 0.044037 0.735596 +vt 0.043793 0.737305 +vt 0.041046 0.740479 +vt 0.050568 0.729248 +vt 0.040680 0.723633 +vt 0.042969 0.722900 +vt 0.037994 0.724121 +vt 0.035553 0.726074 +vt 0.033783 0.721680 +vt 0.035034 0.714355 +vt 0.036621 0.723145 +vt 0.035431 0.713379 +vt 0.045410 0.713379 +vt 0.047058 0.714600 +vt 0.050751 0.721680 +vt 0.055176 0.729004 +vt 0.025452 0.724609 +vt 0.022018 0.726318 +vt 0.022690 0.734619 +vt 0.019943 0.733887 +vt 0.019455 0.730957 +vt 0.019272 0.727783 +vt 0.023468 0.721191 +vt 0.024277 0.720703 +vt 0.033173 0.716553 +vt 0.023148 0.720947 +vt 0.027023 0.711426 +vt 0.035217 0.711914 +vt 0.018906 0.712158 +vt 0.018127 0.717529 +vt 0.054504 0.704102 +vt 0.042328 0.703369 +vt 0.029739 0.709717 +vt 0.036865 0.707031 +vt 0.034607 0.710205 +vt 0.031204 0.707764 +vt 0.030060 0.707031 +vt 0.029327 0.705811 +vt 0.038757 0.705811 +vt 0.230225 0.104980 +vt 0.246338 0.108398 +vt 0.246338 0.108887 +vt 0.251709 0.110352 +vt 0.251465 0.110840 +vt 0.257080 0.112305 +vt 0.258057 0.112793 +vt 0.261475 0.107422 +vt 0.271973 0.097656 +vt 0.256836 0.049805 +vt 0.262939 0.113770 +vt 0.283691 0.112793 +vt 0.284180 0.080078 +vt 0.263916 0.029297 +vt 0.204834 0.014648 +vt 0.297119 0.064941 +vt 0.312744 0.112305 +vt 0.349609 0.109863 +vt 0.112366 0.064941 +vt 0.096802 0.112305 +vt 0.059875 0.109863 +vt 0.036865 0.184082 +vt 0.075562 0.156738 +vt 0.037872 0.145020 +vt 0.094727 0.140137 +vt 0.116638 0.128418 +vt 0.134644 0.152344 +vt 0.146362 0.142090 +vt 0.149658 0.132324 +vt 0.161377 0.150391 +vt 0.155151 0.157227 +vt 0.173584 0.164551 +vt 0.169800 0.169434 +vt 0.167847 0.168457 +vt 0.177368 0.166992 +vt 0.173828 0.160645 +vt 0.166870 0.172363 +vt 0.167236 0.175781 +vt 0.164917 0.170410 +vt 0.161133 0.170898 +vt 0.164673 0.166504 +vt 0.152466 0.163574 +vt 0.151367 0.170410 +vt 0.138672 0.175293 +vt 0.151855 0.172852 +vt 0.160400 0.172852 +vt 0.162720 0.173340 +vt 0.163940 0.174805 +vt 0.165039 0.176270 +vt 0.163818 0.180664 +vt 0.165771 0.181641 +vt 0.153198 0.187500 +vt 0.153931 0.189941 +vt 0.140991 0.187988 +vt 0.139404 0.190918 +vt 0.136963 0.183594 +vt 0.133911 0.183594 +vt 0.140381 0.176758 +vt 0.018860 0.403809 +vt 0.007637 0.405273 +vt 0.015717 0.402832 +vt 0.004272 0.407227 +vt 0.019943 0.405273 +vt 0.004898 0.415527 +vt 0.011215 0.416992 +vt 0.010574 0.418945 +vt 0.002138 0.414551 +vt 0.001498 0.412109 +vt 0.001377 0.408691 +vt 0.005478 0.402344 +vt 0.006542 0.401367 +vt 0.015328 0.397461 +vt 0.010040 0.420898 +vt 0.005409 0.401855 +vt 0.017151 0.395020 +vt 0.017624 0.394531 +vt -0.000031 0.397949 +vt 0.000878 0.393066 +vt 0.009132 0.392090 +vt 0.012322 0.387695 +vt 0.013435 0.388672 +vt 0.011375 0.386719 +vt 0.020798 0.386719 +vt 0.018997 0.388184 +vt 0.011894 0.390625 +vt 0.017395 0.393066 +vt 0.024567 0.384277 +vt 0.036621 0.384766 +vt 0.027496 0.394043 +vt 0.016739 0.391113 +vt 0.039063 0.391113 +vt 0.034058 0.394531 +vt 0.033203 0.402344 +vt 0.029037 0.395508 +vt 0.022949 0.404297 +vt 0.025406 0.403809 +vt 0.032715 0.411133 +vt 0.032745 0.410156 +vt 0.037567 0.409668 +vt 0.043549 0.412109 +vt 0.038635 0.401855 +vt 0.046448 0.392090 +vt 0.053528 0.382813 +vt 0.176270 0.409180 +vt 0.127930 0.395020 +vt 0.172852 0.398438 +vt 0.128296 0.384277 +vt 0.073975 0.389648 +vt 0.070007 0.379883 +vt 0.056610 0.391113 +vt 0.049164 0.401855 +vt 0.047913 0.410156 +vt 0.076355 0.397461 +vt 0.125977 0.404785 +vt 0.186035 0.419922 +vt 0.173584 0.418457 +vt 0.126221 0.417480 +vt 0.077515 0.410645 +vt 0.062683 0.408691 +vt 0.060089 0.398438 +vt 0.064270 0.416992 +vt 0.048889 0.420410 +vt 0.042938 0.416992 +vt 0.047241 0.429199 +vt 0.051178 0.435547 +vt 0.048187 0.435547 +vt 0.064636 0.437012 +vt 0.077271 0.420410 +vt 0.123718 0.427734 +vt 0.165894 0.427734 +vt 0.183105 0.432129 +vt 0.214233 0.452148 +vt 0.239014 0.486816 +vt 0.247559 0.459473 +vt 0.205444 0.468262 +vt 0.174927 0.451660 +vt 0.156982 0.448242 +vt 0.123718 0.443848 +vt 0.076233 0.437988 +vt 0.076965 0.455566 +vt 0.291504 0.535889 +vt 0.241333 0.523926 +vt 0.263672 0.518066 +vt 0.272949 0.499512 +vt 0.233521 0.502197 +vt 0.201050 0.484375 +vt 0.170166 0.464355 +vt 0.216309 0.509277 +vt 0.190308 0.495605 +vt 0.170288 0.507813 +vt 0.158081 0.480469 +vt 0.186890 0.519287 +vt 0.201782 0.530762 +vt 0.247681 0.537109 +vt 0.254150 0.574951 +vt 0.293457 0.566895 +vt 0.264160 0.609131 +vt 0.336182 0.537598 +vt 0.204224 0.541504 +vt 0.337402 0.558594 +vt 0.302979 0.605957 +vt 0.379150 0.522461 +vt 0.277100 0.643555 +vt 0.314941 0.645264 +vt 0.275635 0.673096 +vt 0.344482 0.600098 +vt 0.379150 0.548828 +vt 0.412598 0.497559 +vt 0.320313 0.679443 +vt 0.349609 0.636963 +vt 0.379883 0.591553 +vt 0.351563 0.672119 +vt 0.316650 0.714355 +vt 0.279053 0.709717 +vt 0.281982 0.735352 +vt 0.249756 0.730469 +vt 0.243408 0.716064 +vt 0.233276 0.750000 +vt 0.253662 0.752197 +vt 0.279297 0.753784 +vt 0.311279 0.829346 +vt 0.314941 0.793579 +vt 0.272461 0.776489 +vt 0.246826 0.771118 +vt 0.261475 0.796631 +vt 0.237305 0.790161 +vt 0.245483 0.815063 +vt 0.286133 0.813354 +vt 0.228149 0.805420 +vt 0.214111 0.819214 +vt 0.226685 0.825073 +vt 0.200073 0.845459 +vt 0.191162 0.837646 +vt 0.198120 0.812134 +vt 0.184937 0.835205 +vt 0.209717 0.799927 +vt 0.217773 0.786865 +vt 0.227173 0.768066 +vt 0.197876 0.763184 +vt 0.191162 0.783813 +vt 0.186523 0.796509 +vt 0.173828 0.832031 +vt 0.152222 0.779419 +vt 0.155884 0.760742 +vt 0.157837 0.744141 +vt 0.202393 0.745605 +vt 0.159912 0.728760 +vt 0.199219 0.727295 +vt 0.159912 0.716797 +vt 0.140381 0.740723 +vt 0.143311 0.729004 +vt 0.143188 0.716797 +vt 0.144043 0.706543 +vt 0.158569 0.706299 +vt 0.189209 0.701904 +vt 0.093567 0.727539 +vt 0.060944 0.730957 +vt 0.065918 0.729980 +vt 0.080872 0.727783 +vt 0.092896 0.715820 +vt 0.131958 0.710938 +vt 0.077942 0.717529 +vt 0.113647 0.710693 +vt 0.132446 0.706055 +vt 0.110352 0.706299 +vt 0.089539 0.707520 +vt 0.074219 0.709717 +vt 0.066223 0.720947 +vt 0.056519 0.720947 +vt 0.063599 0.711182 +vt 0.057098 0.710205 +vt 0.051910 0.713623 +vt 0.877441 0.571045 +vt 0.042938 0.479980 +vt 0.050384 0.471191 +vt 0.051453 0.478516 +vt 0.037659 0.474609 +vt 0.056305 0.471191 +vt 0.055481 0.486816 +vt 0.042480 0.484375 +vt 0.035583 0.475586 +vt 0.035156 0.474121 +vt 0.032684 0.472168 +vt 0.036377 0.470703 +vt 0.029633 0.457031 +vt 0.045929 0.455078 +vt 0.024597 0.455078 +vt 0.030045 0.453613 +vt 0.034302 0.437500 +vt 0.025101 0.457520 +vt 0.013283 0.455078 +vt 0.025116 0.452637 +vt 0.031860 0.437012 +vt 0.051361 0.455078 +vt 0.067078 0.473633 +vt 0.065002 0.455566 +vt 0.033173 0.435059 +vt 0.035370 0.434082 +vt 0.076721 0.473633 +vt 0.078247 0.489258 +vt 0.068481 0.492676 +vt 0.054749 0.496094 +vt 0.047272 0.494141 +vt 0.035889 0.490234 +vt 0.110046 0.491699 +vt 0.114563 0.477051 +vt 0.119446 0.461914 +vt 0.152466 0.460938 +vt 0.149170 0.498535 +vt 0.144165 0.479004 +vt 0.141113 0.497559 +vt 0.036255 0.418945 +vt 0.037872 0.425293 +vt 0.038971 0.430176 +vt 0.032989 0.433105 +vt 0.015808 0.424316 +vt 0.027222 0.424316 +vt 0.025406 0.422363 +vt 0.032440 0.418945 +vt 0.029556 0.418945 +vt 0.013939 0.428711 +vt 0.026230 0.416504 +vt 0.026138 0.417969 +vt 0.025772 0.414063 +vt 0.023300 0.421387 +vt 0.021149 0.421875 +vt 0.024551 0.421875 +vt 0.017960 0.406738 +vt 0.008499 0.414063 +vt 0.020920 0.413086 +vt 0.016571 0.409668 +vt 0.024490 0.413574 +vt 0.010529 0.450195 +vt 0.017380 0.437012 +vt 0.240601 0.365723 +vt 0.228149 0.394043 +vt 0.216187 0.374512 +vt 0.186401 0.381836 +vt 0.185425 0.396484 +vt 0.167725 0.388184 +vt 0.229004 0.408691 +vt 0.224976 0.424316 +vt 0.183350 0.410156 +vt 0.278320 0.460938 +vt 0.370117 0.499512 +vt 0.331543 0.512939 +vt 0.291260 0.510986 +vt 0.253174 0.393066 +vt 0.280029 0.388672 +vt 0.286865 0.349609 +vt 0.264648 0.357910 +vt 0.136475 0.759277 +vt 0.134644 0.777222 +vt 0.312744 0.261719 +vt 0.309570 0.270020 +vt 0.307373 0.267090 +vt 0.312256 0.267090 +vt 0.314941 0.264160 +vt 0.328369 0.261230 +vt 0.313477 0.244629 +vt 0.318115 0.270996 +vt 0.291504 0.273438 +vt 0.312744 0.281738 +vt 0.335938 0.279785 +vt 0.336182 0.250488 +vt 0.342285 0.240234 +vt 0.349121 0.272949 +vt 0.358154 0.270508 +vt 0.345947 0.296875 +vt 0.334473 0.296387 +vt 0.315430 0.295898 +vt 0.295410 0.289063 +vt 0.354004 0.299316 +vt 0.304199 0.242676 +vt 0.346436 0.223145 +vt 0.281982 0.258789 +vt 0.277100 0.283203 +vt 0.300781 0.300781 +vt 0.319580 0.319336 +vt 0.310303 0.322754 +vt 0.284668 0.312500 +vt 0.326172 0.341797 +vt 0.305664 0.328125 +vt 0.332031 0.317383 +vt 0.339600 0.316406 +vt 0.347900 0.319824 +vt 0.336426 0.340820 +vt 0.336670 0.334473 +vt 0.323486 0.334961 +vt 0.323486 0.327148 +vt 0.332275 0.326172 +vt 0.873047 0.549316 +vt 0.887695 0.548828 +vt 0.217041 0.130859 +vt 0.215698 0.130371 +vt 0.216919 0.131348 +vt 0.213257 0.132813 +vt 0.215698 0.130859 +vt 0.213379 0.132813 +vt 0.220093 0.133301 +vt 0.211914 0.131348 +vt 0.212769 0.130371 +vt 0.211914 0.129883 +vt 0.212646 0.130371 +vt 0.211304 0.129395 +vt 0.210571 0.129883 +vt 0.211182 0.129395 +vt 0.210815 0.130859 +vt 0.205322 0.114258 +vt 0.219116 0.107422 +vt 0.216064 0.115723 +vt 0.225708 0.119141 +vt 0.229858 0.126953 +vt 0.243286 0.127441 +vt 0.234375 0.112305 +vt 0.263184 0.142090 +vt 0.259766 0.132324 +vt 0.253418 0.117188 +vt 0.258057 0.116699 +vt 0.273926 0.121582 +vt 0.277832 0.839844 +vt 0.234863 0.838135 +vt 0.259766 0.824951 +vt 0.254639 0.851929 +vt 0.261475 0.879700 +vt 0.285400 0.867554 +vt 0.260254 0.904846 +vt 0.285889 0.893921 +vt 0.259033 0.930908 +vt 0.281006 0.919373 +vt 0.236206 0.890564 +vt 0.230957 0.871826 +vt 0.213745 0.849487 +vt 0.207275 0.842163 +vt 0.226929 0.828369 +vt 0.310791 0.907593 +vt 0.339111 0.896057 +vt 0.354004 0.871460 +vt 0.388184 0.876160 +vt 0.369629 0.898193 +vt 0.355957 0.918396 +vt 0.335938 0.918152 +vt 0.306152 0.928955 +vt 0.278076 0.938812 +vt 0.388672 0.950134 +vt 0.396484 0.969971 +vt 0.383789 0.964020 +vt 0.353271 0.957397 +vt 0.364990 0.930542 +vt 0.390381 0.916687 +vt 0.403564 0.898132 +vt 0.428467 0.890930 +vt 0.439453 0.906250 +vt 0.462891 0.876343 +vt 0.469727 0.902344 +vt 0.413574 0.916931 +vt 0.401367 0.934814 +vt 0.499023 0.874146 +vt 0.499023 0.897888 +vt 0.476074 0.919067 +vt 0.499023 0.918640 +vt 0.479736 0.937988 +vt 0.499023 0.938507 +vt 0.518066 0.938019 +vt 0.521484 0.919128 +vt 0.527832 0.902344 +vt 0.534668 0.876343 +vt 0.539063 0.926086 +vt 0.558105 0.906250 +vt 0.569336 0.890930 +vt 0.573730 0.863647 +vt 0.292969 0.128418 +vt 0.314697 0.140137 +vt 0.333984 0.156738 +vt 0.333252 0.184570 +vt 0.299072 0.187012 +vt 0.297607 0.225586 +vt 0.371582 0.145020 +vt 0.372803 0.184082 +vt 0.266846 0.247559 +vt 0.285156 0.237305 +vt 0.275879 0.170410 +vt 0.259277 0.272461 +vt 0.233398 0.280762 +vt 0.258057 0.170410 +vt 0.270752 0.175293 +vt 0.275635 0.183594 +vt 0.270020 0.190918 +vt 0.255615 0.189941 +vt 0.257568 0.172852 +vt 0.269287 0.176758 +vt 0.272461 0.183594 +vt 0.268555 0.187988 +vt 0.256348 0.187500 +vt 0.244507 0.176270 +vt 0.245605 0.174805 +vt 0.246826 0.173340 +vt 0.249146 0.172852 +vt 0.955078 0.479980 +vt 0.947266 0.471191 +vt 0.960449 0.474609 +vt 0.946289 0.478516 +vt 0.952148 0.455078 +vt 0.961426 0.470703 +vt 0.955566 0.484375 +vt 0.962402 0.475586 +vt 0.962891 0.474121 +vt 0.965332 0.472168 +vt 0.968262 0.457031 +vt 0.973145 0.455078 +vt 0.967773 0.453613 +vt 0.963379 0.437500 +vt 0.972656 0.457520 +vt 0.977051 0.479004 +vt 0.976074 0.476074 +vt 0.980957 0.474609 +vt 0.986816 0.458496 +vt 0.919434 0.489258 +vt 0.929199 0.492676 +vt 0.942871 0.496094 +vt 0.950684 0.494141 +vt 0.961914 0.490234 +vt 0.882324 0.577393 +vt 0.749512 0.304688 +vt 0.742188 0.330078 +vt 0.435547 0.965790 +vt 0.424561 0.973816 +vt 0.424561 0.967407 +vt 0.413818 0.979706 +vt 0.457520 0.965912 +vt 0.445557 0.976379 +vt 0.455811 0.962036 +vt 0.445801 0.978638 +vt 0.435547 0.988907 +vt 0.435059 0.990311 +vt 0.430420 0.990440 +vt 0.413574 0.980591 +vt 0.397461 0.969849 +vt 0.443359 0.970230 +vt 0.435059 0.981628 +vt 0.432861 0.973312 +vt 0.464844 0.947357 +vt 0.468262 0.954102 +vt 0.447754 0.943542 +vt 0.410156 0.957153 +vt 0.420898 0.942169 +vt 0.435547 0.935181 +vt 0.458984 0.926086 +vt 0.462646 0.356445 +vt 0.436279 0.288574 +vt 0.464844 0.288574 +vt 0.471680 0.214844 +vt 0.443604 0.214844 +vt 0.476074 0.144043 +vt 0.448242 0.144043 +vt 0.475830 0.068359 +vt 0.454834 0.068359 +vt 0.472900 0.028809 +vt 0.420654 0.144043 +vt 0.416504 0.214844 +vt 0.410400 0.288574 +vt 0.434326 0.353027 +vt 0.405273 0.346191 +vt 0.387939 0.214844 +vt 0.381348 0.288574 +vt 0.385254 0.333984 +vt 0.463135 0.027832 +vt 0.434570 0.068359 +vt 0.392578 0.144043 +vt 0.416504 0.068359 +vt 0.448975 0.028320 +vt 0.466309 0.012695 +vt 0.433594 0.022949 +vt 0.235718 0.717041 +vt 0.235962 0.729492 +vt 0.197754 0.714600 +vt 0.210938 0.701660 +vt 0.224365 0.699219 +vt 0.238281 0.697754 +vt 0.222168 0.581543 +vt 0.215942 0.541504 +vt 0.231079 0.613525 +vt 0.236328 0.640869 +vt 0.235718 0.668213 +vt 0.232910 0.695313 +vt 0.242920 0.697754 +vt 0.888672 0.581787 +vt 0.989258 0.414063 +vt 0.977051 0.413086 +vt 0.981445 0.409668 +vt 0.986816 0.416992 +vt 0.987305 0.418945 +vt 0.987793 0.420898 +vt 0.973145 0.413574 +vt 0.028381 0.738281 +vt 0.027771 0.739746 +vt 0.042358 0.732666 +vt 0.038696 0.732422 +vt 0.034332 0.729004 +vt 0.026306 0.732910 +vt 0.028961 0.735840 +vt 0.866699 0.540039 +vt 0.885742 0.543457 +vt 0.873535 0.543945 +vt 0.020844 0.479004 +vt 0.021652 0.476074 +vt 0.017029 0.474609 +vt 0.011253 0.458496 +vt 0.260742 0.947693 +vt 0.238892 0.957794 +vt 0.237305 0.937714 +vt 0.236206 0.916260 +vt 0.878906 0.529785 +vt 0.150391 0.272461 +vt 0.176147 0.280762 +vt 0.028732 0.769653 +vt 0.681641 0.191895 +vt 0.698730 0.134277 +vt 0.722656 0.195801 +vt 0.681641 0.137207 +vt 0.709473 0.065918 +vt 0.681641 0.079590 +vt 0.653320 0.065918 +vt 0.664063 0.134277 +vt 0.640137 0.195801 +vt 0.886719 0.522705 +vt 0.889648 0.527588 +vt 0.891602 0.518311 +vt 0.901367 0.514404 +vt 0.901367 0.524414 +vt 0.640625 0.234863 +vt 0.894043 0.541992 +vt 0.908203 0.583496 +vt 0.901367 0.584961 +vt 0.911133 0.575684 +vt 0.901367 0.540283 +vt 0.914063 0.581543 +vt 0.917480 0.572021 +vt 0.907227 0.556641 +vt 0.901367 0.557129 +vt 0.910156 0.569092 +vt 0.895508 0.547852 +vt 0.915527 0.554932 +vt 0.918457 0.566162 +vt 0.901367 0.545898 +vt 0.907715 0.547607 +vt 0.895996 0.556885 +vt 0.915527 0.548584 +vt 0.909180 0.541748 +vt 0.916992 0.543213 +vt 0.913086 0.527344 +vt 0.894531 0.583740 +vt 0.923828 0.529541 +vt 0.911133 0.518066 +vt 0.916504 0.522461 +vt 0.930176 0.549072 +vt 0.936035 0.539795 +vt 0.937988 0.550049 +vt 0.929688 0.543701 +vt 0.748047 0.330566 +vt 0.769043 0.313477 +vt 0.768555 0.330566 +vt 0.752930 0.313477 +vt 0.763672 0.291992 +vt 0.756836 0.291992 +vt 0.826660 0.013672 +vt 0.747070 0.089844 +vt 0.724609 0.013184 +vt 0.813477 0.104492 +vt 0.754883 0.150391 +vt 0.804199 0.158691 +vt 0.762207 0.213379 +vt 0.778320 0.219238 +vt 0.799805 0.215820 +vt 0.864258 0.163086 +vt 0.908691 0.109863 +vt 0.956055 0.012695 +vt 0.920898 0.577148 +vt 0.925781 0.570801 +vt 0.956543 0.674072 +vt 0.931641 0.671875 +vt 0.955078 0.672607 +vt 0.930664 0.673828 +vt 0.900391 0.673828 +vt 0.900391 0.675293 +vt 0.929688 0.561768 +vt 0.881836 0.669922 +vt 0.881348 0.673584 +vt 0.781738 0.291992 +vt 0.755371 0.291992 +vt 0.790039 0.330078 +vt 0.782715 0.330566 +vt 0.762207 0.315918 +vt 0.758789 0.330078 +vt 0.779785 0.315918 +vt 0.770020 0.291992 +vt 0.776367 0.291992 +vt 0.760254 0.312988 +vt 0.768555 0.291992 +vt 0.762207 0.291992 +vt 0.776855 0.313477 +vt 0.756836 0.330078 +vt 0.777344 0.330078 +vt 0.757324 0.330078 +vt 0.777344 0.313477 +vt 0.777832 0.330078 +vt 0.760742 0.312988 +vt 0.762695 0.291992 +vt 0.746094 0.330078 +vt 0.740234 0.305176 +vt 0.727051 0.330078 +vt 0.749512 0.309570 +vt 0.763672 0.330078 +vt 0.777344 0.307617 +vt 0.784180 0.330078 +vt 0.766113 0.311523 +vt 0.747070 0.330078 +vt 0.739746 0.306641 +vt 0.728027 0.330078 +vt 0.749512 0.311035 +vt 0.773438 0.329102 +vt 0.744629 0.293457 +vt 0.766113 0.293457 +vt 0.736816 0.329102 +vt 0.788086 0.306152 +vt 0.797363 0.330078 +vt 0.777344 0.310547 +vt 0.780273 0.315918 +vt 0.770508 0.291992 +vt 0.776855 0.291992 +vt 0.763184 0.315918 +vt 0.783203 0.330566 +vt 0.759277 0.330078 +vt 0.771484 0.330078 +vt 0.738770 0.292969 +vt 0.761719 0.292969 +vt 0.737305 0.330078 +vt 0.770508 0.292480 +vt 0.741211 0.330078 +vt 0.741699 0.292480 +vt 0.775391 0.292480 +vt 0.726563 0.330078 +vt 0.784668 0.291992 +vt 0.791504 0.330078 +vt 0.770020 0.291504 +vt 0.773926 0.330078 +vt 0.742676 0.291992 +vt 0.752441 0.330078 +vt 0.782227 0.291504 +vt 0.790527 0.330078 +vt 0.755859 0.291992 +vt 0.745605 0.330078 +vt 0.739746 0.305176 +vt 0.749023 0.309570 +vt 0.763184 0.330078 +vt 0.776855 0.307617 +vt 0.765625 0.311523 +vt 0.783691 0.330078 +vt 0.746582 0.330078 +vt 0.739258 0.306641 +vt 0.749023 0.311035 +vt 0.772949 0.329102 +vt 0.744141 0.293457 +vt 0.736328 0.329102 +vt 0.765625 0.293457 +vt 0.787598 0.306152 +vt 0.776855 0.310547 +vt 0.738281 0.292969 +vt 0.740723 0.330078 +vt 0.770020 0.292969 +vt 0.741211 0.292480 +vt 0.726074 0.330078 +vt 0.774902 0.292480 +vt 0.769531 0.291992 +vt 0.741699 0.291992 +vt 0.881348 0.661865 +vt 0.899902 0.661865 +vt 0.847656 0.657227 +vt 0.812988 0.645020 +vt 0.842285 0.647217 +vt 0.812012 0.657227 +vt 0.812500 0.669678 +vt 0.841797 0.667480 +vt 0.937012 0.661865 +vt 0.793457 0.648926 +vt 0.796387 0.657227 +vt 0.793457 0.665527 +vt 0.960449 0.661865 +vt 0.871094 0.657227 +vt 0.866211 0.668213 +vt 0.866211 0.646484 +vt 0.961914 0.661865 +vt 0.755859 0.330078 +vt 0.753418 0.310547 +vt 0.779297 0.305664 +vt 0.780273 0.310059 +vt 0.770508 0.310059 +vt 0.789551 0.305664 +vt 0.794922 0.330078 +vt 0.779297 0.330078 +vt 0.734863 0.305664 +vt 0.727539 0.330078 +vt 0.747559 0.307129 +vt 0.779297 0.306152 +vt 0.780762 0.330078 +vt 0.789551 0.304688 +vt 0.794434 0.330078 +vt 0.778809 0.305664 +vt 0.788574 0.305664 +vt 0.778809 0.330078 +vt 0.740234 0.330078 +vt 0.734375 0.305664 +vt 0.747070 0.307129 +vt 0.795898 0.330078 +vt 0.778809 0.306152 +vt 0.789063 0.304688 +vt 0.780273 0.330078 +vt 0.729980 0.330078 +vt 0.744141 0.305176 +vt 0.738770 0.330078 +vt 0.736816 0.305664 +vt 0.743652 0.305176 +vt 0.729492 0.330078 +vt 0.737793 0.330078 +vt 0.736328 0.305664 +vt 0.745605 0.311035 +vt 0.766602 0.292480 +vt 0.760254 0.292480 +vt 0.760742 0.291992 +vt 0.752930 0.291992 +vt 0.768066 0.292480 +vt 0.779785 0.330078 +vt 0.764160 0.330078 +vt 0.756348 0.312012 +vt 0.770508 0.292969 +vt 0.762695 0.292969 +vt 0.764648 0.330078 +vt 0.770020 0.311035 +vt 0.743652 0.310547 +vt 0.751465 0.292969 +vt 0.780273 0.309570 +vt 0.758789 0.292969 +vt 0.765137 0.292480 +vt 0.769043 0.292480 +vt 0.758789 0.292480 +vt 0.757813 0.330078 +vt 0.780762 0.309570 +vt 0.763184 0.291992 +vt 0.743164 0.310547 +vt 0.770508 0.310547 +vt 0.766113 0.292480 +vt 0.755859 0.312012 +vt 0.759277 0.292480 +vt 0.750488 0.292969 +vt 0.762207 0.292969 +vt 0.758301 0.292969 +vt 0.781250 0.330078 +vt 0.765137 0.330078 +vt 0.746094 0.311035 +vt 0.761719 0.291992 +vt 0.753906 0.291992 +vt 0.753906 0.310547 +vt 0.760742 0.292480 +vt 0.770020 0.310059 +vt 0.768555 0.292480 +vt 0.779785 0.310059 +vt 0.759766 0.292480 +vt 0.756348 0.330078 +vn 0.834681 0.500443 0.229835 +vn 0.334483 0.656209 -0.676351 +vn 0.039491 0.757744 -0.651295 +vn 0.487808 0.167272 0.856746 +vn 0.577410 0.309946 0.755303 +vn 0.512314 0.000702 0.858760 +vn 0.481582 0.231971 0.845119 +vn 0.439894 0.699728 0.562883 +vn 0.175604 0.769372 0.614154 +vn 0.537492 -0.304300 0.786431 +vn 0.000000 0.910825 0.412702 +vn -0.175604 0.769372 0.614154 +vn 0.000000 0.766228 0.642537 +vn 0.311197 0.313242 0.897214 +vn 0.454390 -0.088748 0.886349 +vn 0.702719 -0.219764 0.676656 +vn 0.829798 -0.558031 0.004028 +vn 0.984802 -0.172796 0.017182 +vn 0.843410 -0.263527 -0.468123 +vn 0.479598 0.005341 0.877438 +vn 0.760674 0.224952 0.608875 +vn 0.855403 -0.183416 0.484329 +vn 0.981628 0.162938 0.098941 +vn 0.763939 0.310068 0.565874 +vn 0.455092 0.856624 0.243049 +vn 0.335734 0.632344 0.698141 +vn 0.000549 0.942869 0.333110 +vn 0.063234 0.667013 0.742332 +vn 0.798639 0.218787 0.560564 +vn 0.452010 0.601245 0.658895 +vn 0.699759 0.416425 0.580401 +vn 0.076937 0.714866 0.694998 +vn 0.232276 0.517502 0.823511 +vn 0.486740 0.305399 0.818384 +vn 0.414472 0.284677 0.864376 +vn 0.623829 -0.061098 0.779138 +vn 0.564989 0.508621 0.649648 +vn 0.634297 0.263344 0.726829 +vn 0.525895 0.184423 0.830287 +vn 0.417951 0.184454 0.889523 +vn 0.655324 -0.207495 0.726279 +vn 0.440077 -0.493820 0.749962 +vn 0.524186 -0.121738 0.842830 +vn 0.260079 0.061098 0.963622 +vn 0.612049 0.271187 0.742821 +vn 0.666677 0.455123 0.590228 +vn 0.224708 0.433241 0.872799 +vn 0.000000 0.429090 0.903226 +vn 0.000000 -0.108768 0.994049 +vn -0.260079 0.061098 0.963622 +vn -0.440077 -0.493820 0.749962 +vn 0.395154 0.380444 0.836116 +vn 0.199561 0.578326 0.790979 +vn 0.000000 0.599353 0.800470 +vn -0.224708 0.433241 0.872799 +vn -0.524186 -0.121738 0.842830 +vn -0.574145 -0.479690 0.663472 +vn -0.324320 -0.733543 0.597247 +vn -0.088992 -0.452773 0.887143 +vn -0.655324 -0.207495 0.726279 +vn -0.612049 0.271187 0.742821 +vn -0.199561 0.578326 0.790979 +vn 0.000000 0.465072 0.885250 +vn -0.634297 0.263344 0.726829 +vn -0.417951 0.184454 0.889523 +vn -0.666677 0.455123 0.590228 +vn -0.395154 0.380444 0.836085 +vn 0.000000 0.096805 0.995300 +vn 0.000000 0.211554 0.977355 +vn -0.479598 0.005341 0.877438 +vn -0.760674 0.224952 0.608875 +vn -0.564989 0.508621 0.649648 +vn -0.311197 0.313242 0.897214 +vn -0.454390 -0.088748 0.886349 +vn -0.695639 -0.220466 0.683676 +vn -0.855403 -0.183447 0.484329 +vn -0.541734 -0.283486 0.791253 +vn -0.486373 0.227332 0.843623 +vn -0.522324 -0.006043 0.852687 +vn -0.586077 0.301981 0.751854 +vn -0.256020 0.426069 0.867672 +vn -0.462905 0.177282 0.868465 +vn -0.568163 0.292978 0.768975 +vn -0.439894 0.699698 0.562883 +vn -0.497147 0.810389 0.309946 +vn -0.571673 0.679525 0.459761 +vn -0.571856 0.626698 0.529313 +vn -0.449293 0.772942 0.447920 +vn -0.575671 0.750969 0.323405 +vn -0.401074 0.841334 -0.362316 +vn -0.313242 0.752068 0.579821 +vn -0.832820 0.421094 0.359233 +vn -0.744041 0.233314 0.626026 +vn -0.486740 0.305399 0.818384 +vn -0.287088 0.867946 -0.405225 +vn 0.458174 0.534715 0.709983 +vn 0.816187 0.528916 0.232490 +vn 0.821223 -0.086978 0.563891 +vn -0.577807 0.247139 0.777825 +vn -0.330729 0.939451 0.089419 +vn 0.224830 -0.674551 0.703146 +vn 0.211890 -0.406079 0.888913 +vn 0.610523 -0.532945 0.585833 +vn 0.833827 -0.321207 0.448927 +vn 0.360088 -0.460219 0.811487 +vn -0.119694 -0.269295 0.955565 +vn -0.821711 -0.026795 0.569262 +vn -0.948973 0.300668 -0.094943 +vn -0.716208 0.612629 -0.334147 +vn -0.653737 -0.459181 0.601459 +vn -0.300211 -0.820460 0.486465 +vn 0.064821 -0.717338 0.693655 +vn -0.515885 -0.781121 0.351634 +vn 0.028260 -0.745293 0.666097 +vn 0.107517 -0.741325 0.662435 +vn 0.260140 -0.719626 0.643727 +vn -0.520432 -0.716666 0.464217 +vn -0.940001 -0.306772 0.149144 +vn -0.855220 -0.508194 -0.101321 +vn -0.458632 -0.818323 0.346385 +vn -0.828181 -0.555895 -0.071322 +vn -0.977203 -0.036195 0.209143 +vn -0.576617 -0.614978 0.537828 +vn -0.473739 -0.509171 0.718528 +vn -0.405072 -0.605792 0.684744 +vn -0.220252 -0.650380 0.726951 +vn -0.009278 -0.595965 0.802911 +vn 0.990692 0.119633 0.064699 +vn 0.329173 -0.486435 0.809320 +vn 0.791253 0.134739 0.596423 +vn -0.004791 -0.492782 0.870113 +vn 0.000000 -0.771142 0.636647 +vn -0.045228 -0.022858 0.998688 +vn -0.178991 0.051088 0.982513 +vn 0.958708 -0.137303 -0.248970 +vn 0.744133 -0.211035 0.633808 +vn 0.000000 -0.693289 0.720634 +vn -0.329173 -0.486435 0.809320 +vn 0.045228 -0.022858 0.998688 +vn -0.791253 0.134739 0.596423 +vn 0.178991 0.051088 0.982513 +vn -0.990692 0.119633 0.064699 +vn -0.744133 -0.211035 0.633808 +vn 0.000000 -0.397656 0.917508 +vn -0.938932 0.191900 -0.285562 +vn -0.352947 0.140599 0.924986 +vn -0.977599 0.170934 -0.122715 +vn -0.958708 -0.137303 -0.248970 +vn 0.557115 -0.222846 -0.799951 +vn 0.456984 -0.877773 -0.143742 +vn 0.529984 -0.314951 0.787317 +vn 0.886624 -0.279275 0.368603 +vn 0.154759 0.076418 0.984985 +vn 0.286294 -0.809687 0.512253 +vn -0.009857 -0.763451 0.645741 +vn 0.343760 -0.636036 0.690817 +vn -0.034974 -0.524522 0.850673 +vn -0.265114 -0.368236 0.891110 +vn -0.364452 0.108158 0.924894 +vn -0.525895 0.184423 0.830287 +vn -0.709250 -0.150517 0.688681 +vn -0.533586 -0.743004 0.403974 +vn -0.047731 -0.841945 0.537400 +vn 0.593280 -0.737510 -0.322550 +vn 0.399701 -0.756157 -0.518052 +vn 0.483505 -0.569659 -0.664602 +vn 0.490310 -0.690909 -0.531205 +vn -0.038881 -0.733757 -0.678243 +vn -0.056093 -0.996277 -0.065218 +vn 0.028565 -0.974395 -0.222999 +vn 0.067629 -0.804498 -0.590075 +vn 0.315043 -0.424879 -0.848628 +vn 0.564470 -0.797266 -0.213782 +vn 0.339213 -0.670705 -0.659566 +vn -0.023255 -0.743797 -0.667959 +vn -0.125370 -0.990905 -0.048463 +vn 0.111179 -0.975921 -0.187628 +vn 0.000000 -0.981536 0.191198 +vn -0.564470 -0.797266 -0.213782 +vn -0.293558 -0.812159 0.504135 +vn 0.000000 -0.979492 0.201361 +vn -0.111179 -0.975921 -0.187628 +vn 0.125370 -0.990905 -0.048463 +vn 0.000000 -0.727470 -0.686117 +vn 0.023255 -0.743797 -0.667959 +vn -0.067629 -0.804498 -0.590075 +vn -0.315043 -0.424879 -0.848628 +vn -0.366955 -0.140049 -0.919614 +vn 0.000000 -0.143071 -0.989685 +vn 0.366985 -0.140049 -0.919614 +vn -0.593280 -0.737510 -0.322550 +vn -0.483505 -0.569659 -0.664571 +vn -0.028565 -0.974395 -0.222999 +vn -0.339213 -0.670705 -0.659566 +vn -0.633229 -0.653584 -0.414472 +vn -0.526811 -0.713370 -0.462050 +vn 0.056093 -0.996277 -0.065218 +vn -0.541765 -0.716636 -0.439192 +vn 0.026032 -0.998871 -0.039094 +vn -0.882992 0.131962 -0.450392 +vn -0.689413 -0.680349 -0.248604 +vn -0.833766 0.172277 -0.524522 +vn -0.781182 0.197272 -0.592273 +vn -0.663869 -0.113468 -0.739158 +vn -0.519150 -0.747765 0.413862 +vn -0.995331 0.019807 0.094363 +vn -0.558123 0.662709 0.499222 +vn -0.622700 0.775231 -0.105869 +vn -0.310953 0.949553 0.040193 +vn -0.556322 0.776421 -0.296030 +vn -0.266335 0.962951 -0.041963 +vn -0.260689 0.875973 -0.405805 +vn -0.658162 0.545030 0.519333 +vn -0.311624 0.936552 -0.160344 +vn 0.333445 0.504532 0.796381 +vn 0.000000 0.898556 -0.438826 +vn -0.543565 0.715354 -0.439009 +vn -0.711234 0.644856 -0.279763 +vn -0.632008 0.770074 -0.086489 +vn -0.952483 0.151189 -0.264351 +vn -0.923093 -0.059297 -0.379894 +vn 0.311624 0.936552 -0.160344 +vn 0.266335 0.962951 -0.041993 +vn 0.310953 0.949553 0.040193 +vn 0.556322 0.776421 -0.296030 +vn 0.260689 0.875973 -0.405805 +vn 0.543596 0.715354 -0.439009 +vn 0.000000 0.951933 -0.306253 +vn -0.192236 0.947661 -0.254799 +vn -0.224464 0.961333 0.159490 +vn 0.000000 0.822687 -0.568438 +vn -0.263802 0.961577 -0.075686 +vn 0.000000 0.972198 0.234046 +vn 0.263802 0.961577 -0.075686 +vn 0.708090 -0.023225 0.705710 +vn 0.512528 0.476791 0.714103 +vn 0.713614 -0.251350 0.653859 +vn 0.724906 -0.463332 0.509690 +vn 0.417127 -0.882748 0.216102 +vn 0.000000 -0.998474 -0.055055 +vn -0.417127 -0.882748 0.216102 +vn 0.000000 -0.999817 -0.017640 +vn 0.386639 -0.865871 0.317423 +vn 0.532945 -0.491806 0.688498 +vn 0.455031 0.349559 0.818964 +vn -0.724906 -0.463332 0.509690 +vn -0.713614 -0.251350 0.653859 +vn -0.386639 -0.865871 0.317423 +vn 0.000000 -0.894711 0.446608 +vn 0.279397 -0.785852 0.551653 +vn 0.000000 -0.466201 0.884671 +vn 0.000000 0.492416 0.870327 +vn -0.455031 0.349559 0.818964 +vn -0.532945 -0.491806 0.688498 +vn -0.279397 -0.785852 0.551653 +vn -0.708090 -0.023225 0.705710 +vn 0.224464 0.961333 0.159490 +vn 0.192236 0.947661 -0.254799 +vn -0.512528 0.476791 0.714103 +vn -0.190466 -0.973937 0.123020 +vn 0.000000 -0.998291 0.058382 +vn -0.396496 -0.776971 0.488937 +vn -0.424177 -0.555559 0.715110 +vn -0.333445 0.504532 0.796381 +vn -0.393811 -0.852260 0.344249 +vn -0.188940 -0.974273 0.122654 +vn -0.435774 -0.636067 0.636769 +vn -0.437239 -0.701041 0.563311 +vn 0.132298 -0.774010 0.619160 +vn 0.658162 0.545030 0.519333 +vn 0.622700 0.775231 -0.105869 +vn 0.558123 0.662709 0.499222 +vn 0.711234 0.644856 -0.279763 +vn 0.632008 0.770074 -0.086489 +vn 0.995331 0.019837 0.094394 +vn 0.519150 -0.747765 0.413862 +vn 0.807917 -0.588458 0.030488 +vn 0.689413 -0.680349 -0.248604 +vn 0.952483 0.151189 -0.264351 +vn 0.923093 -0.059297 -0.379894 +vn 0.882992 0.131962 -0.450392 +vn -0.516098 -0.702414 0.490127 +vn -0.629139 -0.758568 0.169408 +vn -0.114444 -0.822474 -0.557115 +vn 0.312296 -0.833491 -0.455733 +vn -0.026032 -0.998871 -0.039094 +vn 0.541765 -0.716636 -0.439192 +vn -0.724815 -0.688864 -0.008484 +vn 0.526811 -0.713370 -0.462050 +vn 0.633229 -0.653584 -0.414472 +vn 0.833766 0.172277 -0.524522 +vn 0.781182 0.197272 -0.592273 +vn 0.663869 -0.113468 -0.739158 +vn 0.143956 0.009949 0.989502 +vn 0.143895 0.008118 0.989532 +vn 0.142460 0.009064 0.989746 +vn 0.141728 0.010163 0.989837 +vn 0.140996 0.008515 0.989959 +vn 0.140263 0.008606 0.990051 +vn 0.140599 0.006714 0.990020 +vn 0.142247 0.006806 0.989776 +vn 0.142369 0.005371 0.989776 +vn 0.144383 0.008026 0.989471 +vn 0.145817 0.009522 0.989257 +vn 0.144261 0.009919 0.989471 +vn 0.142582 0.009003 0.989715 +vn 0.141881 0.010132 0.989807 +vn 0.141087 0.008545 0.989929 +vn 0.140324 0.008637 0.990051 +vn 0.140599 0.006775 0.990020 +vn 0.142857 0.006531 0.989715 +vn 0.144017 0.005890 0.989532 +vn 0.145512 0.007599 0.989319 +vn 0.419263 -0.334422 0.843989 +vn 0.675130 -0.095309 0.731468 +vn 0.517289 -0.083773 0.851680 +vn 0.526597 -0.412183 0.743461 +vn 0.141697 0.007904 0.989868 +vn -0.250557 -0.154820 0.955626 +vn -0.111057 -0.389386 0.914335 +vn 0.164190 -0.400189 0.901578 +vn 0.193152 -0.567949 0.800043 +vn 0.561754 -0.517136 0.645711 +vn 0.779168 -0.145024 0.609760 +vn 0.736961 0.285806 0.612476 +vn 0.634114 0.272164 0.723716 +vn 0.170141 -0.686789 0.706626 +vn 0.671133 -0.709799 0.213782 +vn 0.965392 -0.201697 0.165166 +vn 0.907407 0.384930 0.168432 +vn 0.519059 0.825282 0.222358 +vn 0.451735 0.608173 0.652699 +vn -0.050661 0.950591 0.306253 +vn 0.034974 0.698508 0.714713 +vn 0.384594 0.514023 0.766686 +vn 0.023865 0.590930 0.806360 +vn -0.352641 0.524491 0.774926 +vn -0.284433 0.427473 0.858089 +vn -0.565111 0.154820 0.810327 +vn -0.467208 0.101688 0.878262 +vn -0.523972 -0.270486 0.807611 +vn -0.407208 -0.247475 0.879147 +vn -0.243995 -0.591754 0.768273 +vn -0.154118 -0.521317 0.839290 +vn -0.324992 0.112430 0.938994 +vn -0.139653 0.319407 0.937254 +vn 0.086093 0.462539 0.882382 +vn 0.534928 0.181738 0.825098 +vn 0.335673 0.353771 0.872982 +vn -0.583453 0.713462 0.387921 +vn -0.876064 0.205298 0.436232 +vn -0.817530 -0.379742 0.432875 +vn -0.430494 -0.819056 0.379162 +vn 0.137852 -0.945311 0.295541 +vn 0.859371 -0.419202 -0.292764 +vn 0.160985 -0.008484 -0.986908 +vn 0.949919 0.132359 -0.283029 +vn 0.465712 -0.811487 -0.352886 +vn -0.079684 -0.894345 -0.440168 +vn -0.568072 -0.636860 -0.521226 +vn -0.813318 -0.138188 -0.565142 +vn -0.722678 0.411389 -0.555376 +vn -0.330851 0.803003 -0.495651 +vn 0.702841 0.631519 -0.327342 +vn 0.213416 0.887387 -0.408582 +vn 0.023072 0.952666 0.303110 +vn -0.542314 0.811090 0.219062 +vn -0.917600 0.361064 0.166173 +vn -0.960265 -0.225349 0.164556 +vn -0.654408 -0.724967 0.214789 +vn -0.116276 -0.947508 0.297739 +vn 0.449293 -0.807642 0.381817 +vn 0.826258 -0.357952 0.434919 +vn 0.869716 0.229957 0.436628 +vn 0.562731 0.730796 0.386273 +vn -0.162603 -0.688528 0.706717 +vn 0.252327 -0.588672 0.767937 +vn -0.554521 -0.523240 0.647023 +vn -0.775323 -0.158238 0.611377 +vn -0.743126 0.267983 0.613117 +vn -0.470290 0.595325 0.651448 +vn -0.113865 0.597705 0.793542 +vn -0.058504 0.699423 0.712272 +vn -0.446852 0.490371 0.748192 +vn -0.679861 0.200690 0.705313 +vn -0.682485 -0.153630 0.714530 +vn -0.478896 -0.467483 0.743034 +vn -0.148228 -0.572802 0.806146 +vn -0.561724 0.188635 0.805506 +vn -0.541704 -0.086917 0.836055 +vn -0.099155 0.462722 0.880917 +vn 0.224067 0.459853 0.859218 +vn -0.351848 0.361187 0.863521 +vn -0.155004 0.007965 0.987854 +vn -0.437880 -0.342570 0.831172 +vn -0.176916 -0.400128 0.899197 +vn 0.091159 -0.379833 0.920530 +vn 0.223457 -0.149266 0.963195 +vn 0.292673 0.108737 0.949980 +vn 0.405347 -0.190222 0.894131 +vn 0.431013 0.178564 0.884487 +vn 0.120151 0.313120 0.942045 +vn 0.208319 -0.476791 0.853938 +vn 0.530320 -0.259713 0.807001 +vn 0.562822 0.172002 0.808466 +vn 0.336650 0.538591 0.772362 +vn -0.281442 0.486557 0.827021 +vn -0.274850 0.487808 0.828516 +vn -0.272530 0.489151 0.828516 +vn -0.235572 0.494552 0.836573 +vn -0.202643 0.492721 0.846248 +vn -0.169713 0.492325 0.853694 +vn -0.169622 0.483444 0.858760 +vn -0.715079 -0.682791 0.149693 +vn -0.737114 -0.658254 0.152745 +vn -0.735435 -0.656331 0.168249 +vn -0.787774 -0.586474 0.188177 +vn -0.817774 -0.533830 0.214972 +vn -0.854274 -0.470382 0.221107 +vn -0.847560 -0.475600 0.235420 +vn -0.318461 -0.719932 0.616627 +vn -0.353648 -0.707480 0.611835 +vn -0.350139 -0.696799 0.625965 +vn -0.442213 -0.647755 0.620350 +vn -0.497909 -0.598559 0.627491 +vn -0.569811 -0.553606 0.607257 +vn -0.554003 -0.547380 0.627186 +vn 0.438368 -0.708335 0.553209 +vn 0.310770 -0.731529 0.606830 +vn 0.304209 -0.701071 0.644917 +vn 0.165746 -0.675497 0.718467 +vn 0.132084 -0.626728 0.767937 +vn 0.052187 -0.615772 0.786157 +vn 0.077395 -0.597308 0.798242 +vn 0.178838 0.507553 0.842830 +vn 0.146947 0.419294 0.895871 +vn 0.139286 0.387829 0.911130 +vn 0.118442 0.324961 0.938261 +vn 0.123539 0.323801 0.937986 +vn 0.094729 0.379742 0.920225 +vn 0.103000 0.385754 0.916807 +vn 0.108707 0.385205 0.916379 +vn 0.115696 0.387890 0.914396 +vn 0.120090 0.384045 0.915433 +vn -0.099094 0.467391 0.878445 +vn -0.104282 0.465072 0.879086 +vn -0.104678 0.462020 0.880642 +vn -0.122196 0.452101 0.883541 +vn -0.134037 0.440657 0.887570 +vn -0.148289 0.432875 0.889157 +vn -0.145054 0.428449 0.891812 +vn 0.053072 0.488113 0.871120 +vn 0.055574 0.488418 0.870815 +vn 0.058107 0.485488 0.872280 +vn 0.060610 0.484146 0.872860 +vn 0.063112 0.479568 0.875210 +vn -0.311350 0.470717 0.825495 +vn -0.301675 0.474013 0.827204 +vn -0.298563 0.475845 0.827265 +vn -0.274026 0.483657 0.831233 +vn -0.255806 0.488693 0.834101 +vn -0.225623 0.494888 0.839106 +vn -0.213202 0.491287 0.844478 +vn -0.201086 0.490646 0.847804 +vn -0.200140 0.482803 0.852535 +vn 0.802911 -0.553575 0.221015 +vn 0.760125 -0.613117 0.215064 +vn 0.795923 -0.557939 0.234840 +vn 0.725181 -0.662374 0.187994 +vn 0.666524 -0.726402 0.167425 +vn 0.668416 -0.728202 0.151189 +vn 0.644063 -0.750450 0.148137 +vn -0.972869 -0.053133 0.225105 +vn 0.249580 -0.194250 0.948637 +vn 0.241310 -0.055086 0.968871 +vn -0.947508 -0.259987 0.186010 +vn 0.235176 -0.679037 0.695395 +vn -0.432173 -0.901517 -0.020997 +vn -0.783593 -0.529221 0.325358 +vn -0.635762 0.749870 0.182958 +vn -0.862697 -0.494949 -0.103519 +vn 0.569811 -0.553606 0.607257 +vn 0.497909 -0.598559 0.627491 +vn 0.554003 -0.547380 0.627186 +vn 0.442213 -0.647755 0.620350 +vn 0.350139 -0.696799 0.625965 +vn 0.353679 -0.707480 0.611835 +vn 0.318461 -0.719932 0.616627 +vn -0.543779 0.511368 0.665395 +vn -0.184515 -0.589496 0.786370 +vn -0.264718 -0.583117 0.768029 +vn -0.205664 -0.565386 0.798730 +vn -0.307993 -0.623554 0.718528 +vn -0.448897 -0.618244 0.645131 +vn -0.462111 -0.646260 0.607257 +vn -0.581561 -0.596026 0.553606 +vn -0.657277 0.635151 -0.405591 +vn -0.921354 -0.386792 0.038240 +vn -0.202246 0.280709 0.938231 +vn -0.239326 0.335551 0.911100 +vn -0.206885 0.278176 0.937956 +vn -0.255196 0.363750 0.895840 +vn -0.309824 0.440046 0.842799 +vn -0.115665 0.387921 0.914396 +vn -0.108676 0.385205 0.916379 +vn -0.120060 0.384075 0.915433 +vn -0.103000 0.385754 0.916807 +vn -0.094699 0.379742 0.920194 +vn -0.799707 0.270943 -0.535722 +vn -0.826044 -0.446974 0.343211 +vn 0.148289 0.432844 0.889157 +vn 0.134037 0.440657 0.887600 +vn 0.145054 0.428449 0.891812 +vn 0.122166 0.452071 0.883541 +vn 0.104678 0.462020 0.880642 +vn 0.104282 0.465041 0.879086 +vn 0.099094 0.467360 0.878475 +vn -0.048158 0.485336 0.872982 +vn -0.045686 0.486435 0.872494 +vn -0.050508 0.481307 0.875088 +vn -0.043275 0.488998 0.871181 +vn -0.040773 0.488632 0.871517 +vn 0.139683 0.511734 0.847682 +vn 0.151616 0.513779 0.844386 +vn 0.139683 0.504013 0.852290 +vn 0.163488 0.519028 0.838954 +vn 0.194220 0.516800 0.833766 +vn 0.212928 0.514359 0.830683 +vn 0.238319 0.509659 0.826685 +vn 0.241646 0.508316 0.826563 +vn 0.251656 0.506241 0.824824 +vn 0.007660 0.520463 0.853816 +vn 0.038881 0.531053 0.846431 +vn 0.010254 0.512223 0.858760 +vn 0.069643 0.542894 0.836879 +vn 0.106510 0.549272 0.828791 +vn 0.109195 0.548692 0.828822 +vn 0.115879 0.549608 0.827326 +vn -0.752159 -0.453108 0.478408 +vn -0.728233 -0.675954 -0.112674 +vn -0.584674 -0.810694 0.029542 +vn -0.894253 -0.401074 -0.198553 +vn -0.643025 0.156652 0.749626 +vn -0.010315 0.384991 0.922849 +vn -0.130467 0.585009 0.800439 +vn 0.028108 0.032258 0.999054 +vn -0.739647 -0.505020 0.444777 +vn -0.702780 -0.692770 -0.161565 +vn -0.555223 -0.831294 -0.025239 +vn -0.878353 -0.417737 -0.232337 +vn -0.887539 -0.400861 -0.226997 +vn 0.099765 -0.837642 0.537004 +vn 0.057772 -0.669759 0.740287 +vn -0.287362 -0.831629 -0.475173 +vn -0.643055 0.156682 0.749565 +vn -0.010315 0.384808 0.922910 +vn -0.130467 0.584979 0.800470 +vn 0.028138 0.032258 0.999054 +vn -0.695853 -0.507645 0.507981 +vn 0.622852 -0.663625 0.414258 +vn 0.685446 -0.430189 0.587420 +vn -0.314097 -0.949248 0.015809 +vn -0.824732 -0.370464 0.427229 +vn 0.526688 -0.612568 0.589343 +vn 0.557482 -0.382855 0.736595 +vn -0.347179 -0.936155 -0.055422 +vn -0.904843 -0.333415 0.264687 +vn 0.317423 -0.828272 0.461654 +vn 0.364910 -0.672750 0.643605 +vn -0.442976 -0.887722 -0.125065 +vn -0.414014 -0.024628 0.909909 +vn 0.539872 0.313852 0.781030 +vn -0.420484 0.705008 0.571062 +vn 0.000000 0.042207 0.999084 +vn -0.872372 -0.067660 0.484085 +vn 0.423322 0.175878 0.888730 +vn -0.483566 0.723685 0.492355 +vn -0.943876 0.117527 0.308664 +vn 0.182379 0.348033 0.919553 +vn -0.554155 0.743858 0.373547 +vn 0.250465 0.103000 0.962615 +vn -0.968352 0.062075 0.241707 +vn 0.152745 0.417524 0.895718 +vn -0.553453 0.775475 0.303781 +vn 0.231269 -0.133824 0.963622 +vn -0.970336 -0.041597 0.238136 +vn 0.239448 -0.280129 0.929594 +vn 0.418989 -0.160802 0.893613 +vn -0.135838 -0.353526 0.925474 +vn 0.465346 -0.198004 0.862667 +vn -0.292123 -0.256874 0.921232 +vn 0.294229 -0.081606 0.952239 +vn -0.343120 -0.167882 0.924131 +vn -0.036714 -0.117954 0.992309 +vn -0.296121 -0.096957 0.950194 +vn -0.589618 -0.209265 0.780084 +vn -0.838771 -0.231910 0.492599 +vn -0.729392 -0.317789 0.605762 +vn -0.611011 -0.276681 0.741661 +vn 0.887051 -0.218177 -0.406781 +vn -0.484603 -0.784051 -0.387768 +vn 0.285531 -0.913877 0.288522 +vn -0.794824 -0.581408 0.173681 +vn 0.902341 -0.401685 -0.156102 +vn -0.900357 0.312479 0.302744 +vn -0.278268 0.170446 0.945250 +vn 0.483444 0.688040 0.541124 +vn 0.784234 0.122868 0.608173 +vn -0.278268 0.196326 0.940214 +vn 0.285501 -0.905637 0.313486 +vn 0.784234 0.139500 0.604541 +vn -0.794824 -0.576403 0.189581 +vn -0.484603 -0.794397 -0.366100 +vn 0.902341 -0.405835 -0.145024 +vn -0.900357 0.320658 0.294046 +vn 0.483444 0.702628 0.522050 +vn -0.521805 0.126713 0.843562 +vn 0.519761 -0.772454 0.364788 +vn 0.652699 0.265816 0.709433 +vn -0.668264 -0.727500 0.155217 +vn -0.126865 -0.910855 -0.392651 +vn 0.974792 -0.221351 -0.027589 +vn -0.975219 0.147618 0.164678 +vn 0.126133 0.813959 0.567034 +vn 0.000000 -0.527787 -0.849361 +vn 0.025330 -0.116703 -0.992828 +vn 0.000000 -0.102695 -0.994690 +vn 0.000000 -0.016053 -0.999847 +vn -0.132054 -0.083163 -0.987732 +vn 0.000000 0.317545 -0.948210 +vn 0.050478 0.281198 -0.958312 +vn 0.000000 0.541795 -0.840480 +vn 0.000000 -0.018372 -0.999817 +vn 0.000000 -0.007263 -0.999969 +vn 0.156865 -0.089633 -0.983520 +vn 0.000000 0.104038 -0.994568 +vn -0.175451 0.262764 -0.948759 +vn -0.707358 0.509201 -0.490219 +vn 0.465194 0.077181 -0.881832 +vn 0.494369 -0.047945 -0.867885 +vn -0.253517 -0.101016 -0.962035 +vn -0.439283 0.897000 -0.048982 +vn -0.800409 0.585864 0.126652 +vn -0.506180 0.862300 0.013520 +vn -0.762383 0.646901 0.015656 +vn -0.527970 0.825312 -0.200201 +vn -0.738762 0.593432 -0.319376 +vn -0.801080 0.349773 -0.485672 +vn -0.846675 0.064333 -0.528184 +vn -0.860897 -0.039430 -0.507218 +vn -0.933317 0.317515 -0.167516 +vn -0.969634 0.162725 -0.182379 +vn -0.972320 0.025483 -0.232154 +vn -0.874660 0.380261 0.300516 +vn -0.908078 0.192145 0.372082 +vn -0.969024 0.039979 0.243599 +vn -0.979553 0.043611 -0.196356 +vn -0.863613 0.034272 -0.502945 +vn -0.982696 0.061586 -0.174627 +vn -0.865963 0.140049 -0.480087 +vn -0.922544 0.077120 0.378063 +vn -0.704611 -0.251595 0.663442 +vn -0.953124 -0.069247 0.294504 +vn -0.940031 -0.228431 0.253212 +vn -0.977172 0.107730 -0.182958 +vn -0.951445 -0.176397 0.252205 +vn -0.968291 0.062502 -0.241859 +vn -0.829066 0.168065 -0.533250 +vn -0.133213 -0.440535 -0.887783 +vn -0.687338 -0.286538 -0.667379 +vn -0.965423 -0.069460 -0.251167 +vn -0.836634 0.217505 -0.502670 +vn 0.120029 0.266335 -0.956359 +vn 0.957091 -0.132786 -0.257454 +vn 0.667470 -0.566149 -0.483657 +vn -0.035218 -0.680410 -0.731956 +vn -0.590594 -0.468062 -0.657308 +vn 0.975555 0.027619 -0.217994 +vn 0.980468 -0.000610 0.196600 +vn 0.996887 -0.072207 0.031526 +vn 0.520920 -0.644765 -0.559343 +vn 0.038606 -0.771996 -0.634419 +vn -0.463332 -0.633747 -0.619404 +vn -0.256325 -0.845027 -0.469222 +vn -0.796258 -0.438765 -0.416395 +vn -0.109470 -0.906461 -0.407819 +vn -0.978118 -0.033418 -0.205298 +vn -0.977020 -0.056337 -0.205420 +vn 0.990265 -0.081454 -0.112735 +vn 0.825007 -0.457289 -0.331980 +vn 0.295389 -0.842189 -0.451033 +vn 0.030244 -0.880917 -0.472243 +vn 0.019532 -0.940092 -0.340312 +vn 0.015870 -0.953337 -0.301401 +vn -0.068117 -0.984130 -0.163762 +vn 0.001465 -0.999878 -0.015076 +vn -0.355968 -0.925443 0.129673 +vn -0.268868 -0.918119 -0.291055 +vn -0.062563 -0.997314 0.037904 +vn -0.402081 -0.832514 0.381054 +vn -0.025605 -0.855617 0.516923 +vn 0.359752 -0.829676 0.426832 +vn -0.018128 -0.936064 0.351329 +vn 0.133946 -0.989257 0.058077 +vn -0.002441 -0.993408 0.114353 +vn 0.013428 -0.981567 -0.190527 +vn -0.023041 -0.998505 0.049074 +vn 0.219031 -0.974120 0.055452 +vn 0.090091 -0.929685 0.357097 +vn -0.017975 -0.724509 0.688986 +vn -0.158300 -0.943693 0.290475 +vn 0.018464 -0.998627 0.048891 +vn -0.221381 -0.974487 0.036073 +vn -0.303323 -0.952574 -0.023438 +vn -0.283273 -0.902463 -0.324473 +vn 0.006043 -0.996399 0.084292 +vn -0.345897 -0.934812 -0.080142 +vn 0.250618 -0.951659 -0.177465 +vn 0.297098 -0.941404 0.159520 +vn 0.071932 -0.987304 -0.141423 +vn 0.324900 -0.913297 0.245521 +vn -0.226905 -0.680807 0.696402 +vn -0.009186 -0.936613 0.350200 +vn 0.089511 -0.970550 0.223609 +vn 0.159124 -0.985137 0.064333 +vn 0.332560 -0.878872 0.341960 +vn 0.226997 -0.952239 -0.204199 +vn -0.489029 -0.823206 -0.288308 +vn -0.219306 -0.917234 -0.332499 +vn -0.326731 -0.915799 0.233497 +vn -0.292367 -0.955931 -0.025361 +vn 0.510605 -0.857021 -0.068880 +vn 0.149571 -0.987945 0.039186 +vn 0.405377 -0.880551 -0.245399 +vn 0.173254 -0.896329 -0.408063 +vn 0.168371 -0.973724 -0.153111 +vn 0.356243 -0.917814 0.175024 +vn 0.804346 -0.593677 -0.022309 +vn 0.985931 0.101566 0.132542 +vn 0.871853 -0.020844 0.489303 +vn 0.847682 0.251076 0.467269 +vn 0.961882 0.036348 0.270974 +vn 0.854122 0.510178 0.100833 +vn 0.962981 0.100681 -0.249977 +vn 0.966857 -0.237892 -0.092593 +vn 0.984710 0.083468 0.152745 +vn 0.970733 -0.046571 -0.235450 +vn 0.996673 -0.081210 0.006409 +vn 0.737938 -0.151769 0.657521 +vn 0.981109 -0.083712 0.174383 +vn 0.932401 -0.348643 0.095096 +vn 0.817408 -0.037629 -0.574786 +vn 0.749077 -0.048555 -0.660665 +vn 0.426893 -0.169469 -0.888241 +vn 0.486862 -0.029481 -0.872951 +vn 0.899442 0.151677 -0.409803 +vn 0.583117 -0.553636 -0.594470 +vn 0.464949 -0.331065 -0.821070 +vn 0.525376 -0.098025 -0.845180 +vn 0.500595 -0.095950 -0.860317 +vn 0.765069 -0.232429 -0.600513 +vn 0.959380 0.184027 -0.213782 +vn 0.403363 -0.852443 -0.332560 +vn 0.498245 -0.858852 -0.118778 +vn 0.980346 -0.071078 0.183996 +vn 0.151524 -0.987945 0.031373 +vn 0.008911 -0.936644 0.350078 +vn 0.157445 -0.843501 -0.513474 +vn 0.318583 -0.520463 -0.792199 +vn 0.871517 0.490249 -0.009186 +vn 0.602924 0.796319 -0.047945 +vn 0.012207 0.914426 0.404523 +vn -0.025758 0.196204 0.980193 +vn 0.053224 -0.161199 0.985473 +vn -0.058290 -0.214667 0.974914 +vn -0.733329 -0.179540 0.655690 +vn -0.796472 -0.262246 0.544816 +vn -0.827296 0.196265 0.526353 +vn -0.835749 0.540727 0.095431 +vn -0.599170 0.797998 -0.064547 +vn -0.966094 0.145024 -0.213446 +vn -0.900296 0.432447 0.049074 +vn -0.970214 -0.093692 0.223334 +vn -0.503006 -0.860683 0.078402 +vn -0.964812 0.024934 -0.261696 +vn -0.776116 -0.258644 -0.575060 +vn -0.284982 -0.909421 -0.302805 +vn -0.002441 -0.990417 0.138035 +vn 0.220008 -0.961638 0.163671 +vn -0.100894 -0.963256 0.248878 +vn 0.314158 -0.907804 0.277718 +vn -0.350078 -0.868465 0.350932 +vn -0.161657 -0.983123 0.085421 +vn -0.216010 -0.958098 -0.188025 +vn 0.503067 -0.830561 -0.238777 +vn 0.236641 -0.956816 -0.168767 +vn -0.045686 -0.992767 0.110965 +vn 0.022858 -0.920957 0.388928 +vn -0.086062 0.310068 0.946776 +vn 0.195013 -0.626637 0.754479 +vn -0.321329 0.405683 0.855647 +vn -0.483413 -0.854427 0.190313 +vn -0.724845 0.169256 0.667745 +vn 0.022217 -0.933531 0.357707 +vn 0.447707 0.073336 0.891140 +vn 0.141453 0.597095 0.789575 +vn 0.026612 0.366100 0.930174 +vn 0.032960 0.836665 0.546678 +vn -0.871090 0.402264 0.281655 +vn -0.039247 0.857112 0.513627 +vn -0.629231 0.713675 0.307749 +vn -0.498856 0.636952 0.587695 +vn 0.495773 0.649098 0.576922 +vn 0.618397 0.732383 0.284860 +vn 0.020508 0.998321 0.054079 +vn 0.867519 0.428419 0.252632 +vn 0.032563 0.826930 0.561327 +vn -0.090030 0.621021 0.778558 +vn 0.731132 0.174383 0.659536 +vn 0.251564 0.310068 0.916807 +vn 0.100925 0.270516 0.957396 +vn -0.190710 -0.681021 0.706961 +vn 0.331034 -0.915464 0.228706 +vn -0.170415 -0.937376 0.303690 +vn -0.476974 0.100436 0.873135 +vn -0.079165 -0.760979 0.643910 +vn 0.360454 -0.444288 -0.820154 +vn 0.000000 -0.922849 -0.385144 +vn 0.000000 -0.448988 -0.893521 +vn 0.303232 -0.862789 0.404492 +vn -0.005310 -0.803034 0.595843 +vn 0.015931 -0.664602 0.747002 +vn -0.011750 -0.948515 0.316477 +vn -0.303232 -0.862789 0.404492 +vn 0.144536 -0.984313 -0.101047 +vn -0.453322 -0.797845 -0.397320 +vn 0.011750 -0.948515 0.316477 +vn 0.005310 -0.803034 0.595843 +vn 0.000000 -0.902158 0.431379 +vn 0.000000 -0.858699 0.512436 +vn 0.000000 -0.995422 -0.095401 +vn -0.144536 -0.984313 -0.101047 +vn 0.453322 -0.797845 -0.397320 +vn -0.204688 -0.952269 -0.226386 +vn 0.300943 -0.915311 0.267525 +vn -0.366405 -0.878140 0.307505 +vn 0.516129 -0.823237 -0.236274 +vn 0.212836 -0.965911 0.147252 +vn 0.246559 -0.951506 -0.183782 +vn -0.164403 -0.985168 0.048799 +vn -0.112156 -0.969970 0.215705 +vn -0.513169 -0.856624 0.053011 +vn -0.049745 -0.995544 0.079989 +vn 0.004181 -0.931730 0.363109 +vn -0.487197 -0.861293 0.144047 +vn -0.365551 0.380902 0.849239 +vn 0.156804 -0.647816 0.745445 +vn -0.135258 0.282662 0.949614 +vn -0.980285 -0.100040 0.170263 +vn -0.963042 0.133976 -0.233558 +vn 0.398968 0.059816 0.915006 +vn -0.752312 0.141850 0.643330 +vn -0.649007 0.701743 0.293741 +vn -0.067019 0.841853 0.535478 +vn -0.885128 0.393811 0.247810 +vn -0.902371 0.430647 0.014985 +vn -0.613819 0.786004 -0.073489 +vn 0.005219 0.997192 0.074557 +vn -0.004181 0.990234 0.139286 +vn 0.606372 0.794702 -0.026337 +vn -0.811579 0.583087 -0.036012 +vn -0.846431 0.457198 0.272896 +vn -0.068636 0.683401 0.726798 +vn 0.719230 0.359569 0.594440 +vn -0.051790 0.550493 0.833216 +vn 0.788507 0.464095 0.403516 +vn 0.813471 0.575762 0.081912 +vn 0.978942 0.163152 -0.122501 +vn -0.820521 0.361217 0.442976 +vn -0.955718 0.001984 0.294259 +vn -0.324503 0.023164 0.945585 +vn 0.650258 0.090579 0.754265 +vn -0.947020 -0.173345 0.270333 +vn -0.324900 -0.591388 0.737999 +vn 0.525193 -0.544389 0.654042 +vn 0.964080 -0.195563 0.179632 +vn 0.925504 -0.365429 0.099368 +vn 0.450819 -0.704764 0.547716 +vn -0.478439 -0.607868 0.633686 +vn -0.361003 -0.639668 0.678549 +vn -0.339610 -0.437788 0.832423 +vn 0.604938 -0.591571 0.532945 +vn 0.563097 -0.552019 0.614917 +vn -0.013489 -0.980316 0.196875 +vn 0.828211 -0.559709 -0.026887 +vn 0.417646 -0.890042 -0.182684 +vn 0.955046 -0.292550 -0.047426 +vn -0.938108 -0.237800 -0.251656 +vn -0.999542 -0.022126 -0.020478 +vn -0.948882 -0.315439 -0.008972 +vn -0.997711 -0.042726 -0.052248 +vn -0.951689 -0.306986 0.004151 +vn -0.997253 -0.044343 -0.059175 +vn -0.957701 -0.285928 -0.032319 +vn -0.999146 -0.040437 -0.006439 +vn -0.969848 -0.234169 0.067385 +vn -0.594195 -0.802576 0.052461 +vn 0.000000 -0.999969 0.002197 +vn 0.000000 -0.997711 -0.067537 +vn -0.561296 -0.824793 -0.067995 +vn -0.626942 -0.776635 0.061129 +vn -0.627949 -0.776605 0.050050 +vn 0.000000 -0.997284 0.073367 +vn 0.000000 -0.998444 0.055666 +vn 0.000000 -0.998810 -0.048311 +vn -0.713126 -0.415204 -0.564776 +vn 0.168218 -0.139103 -0.975860 +vn 0.889065 -0.113315 -0.443495 +vn 0.070040 -0.091708 -0.993286 +vn 0.898373 -0.176183 -0.402295 +vn 0.242195 0.001587 -0.970214 +vn -0.736625 -0.065004 -0.673147 +vn -0.800409 -0.168889 -0.575152 +vn -0.953520 -0.047884 -0.297403 +vn -0.981567 -0.084597 -0.171239 +vn 0.006684 -0.200018 -0.979766 +vn -0.462111 -0.212867 -0.860866 +vn -0.652181 -0.178991 -0.736595 +vn -0.519211 -0.072634 -0.851527 +vn 0.133702 -0.086184 -0.987243 +vn -0.459914 -0.078127 -0.884487 +vn -0.664266 -0.105472 -0.739982 +vn -0.964171 -0.107395 -0.242500 +vn 0.230873 -0.185186 -0.955168 +vn 0.094394 -0.232795 -0.967925 +vn 0.071261 -0.191748 -0.978851 +vn 0.031983 -0.584674 -0.810602 +vn 0.012940 -0.886135 -0.463210 +vn -0.289132 -0.537675 -0.791986 +vn -0.127659 -0.867611 -0.480544 +vn 0.001312 -0.957274 -0.289132 +vn 0.164068 -0.976257 -0.141301 +vn 0.139042 -0.986511 0.086276 +vn 0.008576 -0.996765 0.079836 +vn -0.050966 -0.983276 -0.174688 +vn -0.223792 -0.973510 0.046144 +vn -0.094119 -0.987823 -0.123722 +vn -0.002472 -0.998993 0.044313 +vn 0.370769 -0.901669 0.222419 +vn 0.386395 -0.800623 0.457900 +vn -0.002106 -0.930662 0.365795 +vn 0.002075 -0.828120 0.560503 +vn -0.384960 -0.794305 0.469955 +vn -0.374615 -0.893521 0.247444 +vn -0.080966 -0.991791 0.098788 +vn 0.218085 -0.973205 0.072451 +vn -0.052004 -0.995483 0.079165 +vn -0.318583 -0.931516 0.175359 +vn -0.201331 -0.978790 -0.037751 +vn 0.290506 -0.956572 0.023652 +vn -0.265603 -0.951384 -0.155736 +vn 0.140233 -0.989776 -0.025391 +vn 0.273934 -0.918149 -0.286203 +vn -0.002838 -0.997894 0.064333 +vn 0.061281 -0.991119 -0.117740 +vn 0.294595 -0.944975 0.142125 +vn 0.218604 -0.955840 -0.196326 +vn -0.365001 -0.929075 -0.059420 +vn -0.316660 -0.948393 -0.015900 +vn -0.321085 -0.894711 -0.310404 +vn 0.349712 -0.878964 0.324168 +vn 0.100925 -0.970580 0.218543 +vn -0.314097 -0.915891 0.249855 +vn -0.293222 -0.955962 -0.010376 +vn 0.162267 -0.985137 0.055940 +vn 0.216071 -0.952239 -0.215674 +vn -0.503189 -0.823206 -0.262795 +vn -0.236061 -0.917234 -0.320780 +vn 0.000000 0.686422 0.727165 +vn -0.603595 0.625416 0.494461 +vn 0.090976 0.791803 0.603931 +vn -0.080386 0.903104 0.421766 +vn -0.744224 0.633503 0.211615 +vn -0.998108 0.060457 0.010620 +vn -0.703787 0.484695 0.519303 +vn -0.993988 -0.049379 -0.097659 +vn -0.704917 0.462050 0.538102 +vn -0.992767 -0.014069 -0.118961 +vn -0.704306 0.472365 0.529893 +vn 0.000000 0.625721 0.780023 +vn 0.000000 0.944487 0.328501 +vn 0.000000 0.635853 0.771783 +vn -0.751396 0.634266 0.181768 +vn -0.990020 0.017579 -0.139805 +vn -0.580767 -0.436048 -0.687399 +vn -0.558763 -0.523026 -0.643574 +vn -0.580340 -0.583117 -0.568468 +vn -0.948119 -0.009217 -0.317759 +vn -0.497299 -0.441328 -0.746910 +vn -0.828516 0.397412 -0.394421 +vn -0.580218 -0.393231 -0.713218 +vn -0.480148 -0.116947 -0.869320 +vn 0.000000 -0.621113 -0.783685 +vn 0.000000 -0.539476 -0.841975 +vn 0.000000 -0.507859 -0.861415 +vn 0.000000 -0.138676 -0.990326 +vn 0.000000 0.701621 -0.712516 +vn 0.000000 0.999756 0.021943 +vn -0.739189 0.666921 -0.093509 +vn 0.000000 -0.626179 -0.779656 +vn 0.000000 -0.711692 -0.702445 +vn 0.527970 0.825312 -0.200201 +vn 0.739189 0.666921 -0.093478 +vn 0.000000 0.993011 -0.117954 +vn 0.000000 0.996551 -0.082766 +vn -0.000336 0.999969 -0.000824 +vn -0.541856 0.839167 0.046419 +vn -0.001190 0.997162 0.075045 +vn -0.501480 0.861415 0.080203 +vn -0.454268 0.885952 0.093295 +vn -0.759514 0.649007 -0.043397 +vn -0.407178 0.913175 0.016846 +vn -0.794580 0.606647 0.023774 +vn -0.460952 0.879879 0.115299 +vn -0.816095 0.577593 0.018921 +vn -0.848720 0.528520 -0.016541 +vn -0.850795 0.522233 0.058199 +vn -0.969420 0.245125 -0.010590 +vn -0.971099 0.236427 -0.032594 +vn -0.976104 0.210212 -0.054598 +vn -0.977722 0.205573 0.042024 +vn -0.930357 0.284799 0.230781 +vn -0.992431 -0.020173 -0.121067 +vn -0.746666 -0.334422 0.574969 +vn -0.441389 -0.400647 0.802881 +vn -0.826044 -0.070559 0.559130 +vn -0.980102 0.014344 0.197913 +vn -0.951506 0.237465 0.195502 +vn -0.994873 0.084414 -0.055483 +vn -0.973968 0.219947 -0.054323 +vn -0.983367 0.110324 -0.144078 +vn -0.944426 -0.055300 -0.324015 +vn -0.978607 -0.097507 0.181005 +vn -0.919248 -0.222480 0.324747 +vn -0.678121 -0.442183 0.586993 +vn -0.494034 -0.440138 0.749779 +vn -0.890164 -0.160863 0.426221 +vn -0.319956 -0.255165 0.912381 +vn -0.865566 -0.137150 0.481613 +vn -0.135502 -0.173833 0.975372 +vn 0.610370 -0.151189 0.777520 +vn 0.392773 -0.287454 0.873531 +vn 0.109897 -0.474868 0.873135 +vn -0.256081 -0.582049 0.771752 +vn 0.916410 -0.233406 0.325053 +vn 0.754204 -0.478530 0.449599 +vn -0.312662 -0.583422 0.749565 +vn 0.026917 -0.591845 0.805567 +vn -0.443983 -0.516465 0.732170 +vn 0.000000 -0.670339 0.742027 +vn -0.128086 -0.717093 0.685049 +vn 0.000000 -0.753960 0.656911 +vn -0.663503 -0.371593 0.649342 +vn -0.456923 -0.719596 0.522813 +vn -0.658193 -0.692251 0.295846 +vn -0.285653 -0.927061 0.242744 +vn -0.502243 -0.864009 0.034486 +vn -0.857051 -0.514115 0.032960 +vn -0.812555 -0.582476 -0.021241 +vn -0.978332 -0.168798 -0.119846 +vn -0.978454 0.020051 -0.205420 +vn -0.965606 0.149998 -0.212317 +vn -0.865383 -0.240303 0.439711 +vn -0.988556 0.124027 0.085788 +vn -0.862545 0.493271 -0.112461 +vn -0.838038 0.537980 0.090579 +vn -0.870327 0.492355 0.009552 +vn -0.925321 0.363109 -0.108982 +vn -0.958586 0.278481 -0.059358 +vn -0.357189 0.919584 0.163579 +vn -0.524064 0.850063 -0.052217 +vn -0.621784 0.779504 -0.075655 +vn -0.694998 0.704917 -0.141514 +vn 0.000000 0.859584 -0.510971 +vn -0.280343 0.919156 -0.276650 +vn -0.451674 0.739311 -0.499405 +vn 0.109073 0.992035 0.062502 +vn 0.020295 0.995575 -0.091708 +vn -0.292673 0.947813 -0.126225 +vn 0.000000 0.996704 -0.080905 +vn 0.000000 0.999939 0.010773 +vn 0.000000 0.994263 -0.106754 +vn 0.000000 0.949553 -0.313517 +vn 0.280343 0.919156 -0.276650 +vn 0.451674 0.739280 -0.499405 +vn 0.524064 0.850063 -0.052217 +vn 0.723533 0.463363 -0.511612 +vn 0.862545 0.493271 -0.112461 +vn 0.357189 0.919584 0.163579 +vn -0.109073 0.992035 0.062502 +vn -0.020295 0.995575 -0.091708 +vn 0.988556 0.124027 0.085788 +vn 0.838038 0.537980 0.090579 +vn 0.621784 0.779504 -0.075655 +vn 0.292673 0.947813 -0.126225 +vn 0.000000 0.998047 0.062105 +vn 0.407147 0.913175 0.016907 +vn -0.000031 0.992401 0.122929 +vn 0.453871 0.886074 0.093844 +vn 0.857051 -0.514115 0.032960 +vn 0.865352 -0.240303 0.439711 +vn 0.951506 0.237465 0.195502 +vn 0.870327 0.492355 0.009552 +vn 0.694998 0.704917 -0.141514 +vn 0.759423 0.649129 -0.043184 +vn 0.944426 -0.055300 -0.324015 +vn 0.992431 -0.020325 -0.120914 +vn 0.983367 0.110324 -0.144078 +vn 0.994873 0.084414 -0.055483 +vn 0.973968 0.219947 -0.054323 +vn 0.925321 0.363109 -0.108982 +vn 0.958556 0.278634 -0.058962 +vn 0.793573 0.607837 0.026734 +vn 0.969268 0.245796 -0.006623 +vn 0.811823 0.583087 0.029878 +vn 0.458388 0.880917 0.117557 +vn 0.493362 0.865688 0.084292 +vn 0.971282 0.237037 -0.019074 +vn 0.842311 0.538926 -0.006073 +vn 0.532487 0.845180 0.045534 +vn 0.847713 0.527970 0.050905 +vn 0.503555 0.863887 0.009735 +vn -0.000366 0.990783 0.135228 +vn -0.001129 0.991760 0.127903 +vn 0.439253 0.897000 -0.049013 +vn 0.762017 0.647359 0.014557 +vn 0.738762 0.593432 -0.319376 +vn 0.933317 0.317515 -0.167516 +vn 0.801080 0.349773 -0.485672 +vn 0.969634 0.162725 -0.182379 +vn 0.846675 0.064333 -0.528184 +vn 0.972320 0.025483 -0.232154 +vn 0.860897 -0.039430 -0.507218 +vn 0.707358 0.509201 -0.490219 +vn 0.175451 0.262764 -0.948759 +vn 0.253517 -0.101016 -0.962035 +vn 0.171239 -0.226539 -0.958800 +vn 0.863613 0.034272 -0.502945 +vn -0.494369 -0.047945 -0.867885 +vn -0.329356 -0.231300 -0.915403 +vn 0.079897 -0.275948 -0.957823 +vn 0.000000 -0.762017 -0.647542 +vn 0.269082 -0.520737 -0.810175 +vn 0.000000 -0.257149 -0.966369 +vn 0.000000 -0.570635 -0.821162 +vn -0.449599 -0.588183 -0.672201 +vn 0.087222 -0.217414 -0.972167 +vn 0.865932 0.140049 -0.480087 +vn -0.018250 -0.097537 -0.995056 +vn 0.132054 -0.083163 -0.987732 +vn -0.465194 0.077151 -0.881832 +vn -0.050478 0.281198 -0.958312 +vn 0.514206 0.093112 -0.852565 +vn 0.000000 -0.621662 -0.783258 +vn -0.025330 -0.116703 -0.992828 +vn -0.156865 -0.089633 -0.983520 +vn 0.397931 -0.833644 -0.382916 +vn 0.614093 0.204901 -0.762139 +vn 0.907865 -0.228278 -0.351573 +vn 0.966094 -0.010712 -0.257942 +vn 0.760338 -0.513047 -0.398297 +vn 0.449599 -0.588183 -0.672201 +vn -0.079897 -0.275948 -0.957823 +vn 0.329356 -0.231300 -0.915403 +vn -0.171239 -0.226539 -0.958800 +vn -0.087252 -0.217414 -0.972167 +vn 0.018250 -0.097537 -0.995056 +vn -0.269082 -0.520737 -0.810175 +vn -0.514206 0.093112 -0.852565 +vn -0.938994 -0.082095 -0.333964 +vn -0.964049 -0.150609 -0.218818 +vn -0.969512 -0.217109 -0.113407 +vn -0.973785 0.123356 -0.191015 +vn -0.794427 0.082522 0.601672 +vn -0.866146 0.321299 -0.382763 +vn -0.594440 0.571520 -0.565661 +vn -0.958251 0.054140 0.280740 +vn -0.334483 0.656209 -0.676382 +vn -0.824549 -0.302591 0.478042 +vn -0.834681 0.500443 0.229835 +vn -0.107669 0.761559 -0.639058 +vn -0.264840 0.754662 -0.600238 +vn -0.609424 0.577746 -0.542924 +vn -0.778741 0.330027 -0.533494 +vn -0.884304 0.208472 -0.417707 +vn 0.284829 0.838496 -0.464461 +vn 0.022248 0.771294 -0.636036 +vn 0.215705 0.865993 -0.451064 +vn 0.721000 0.691733 0.040193 +vn 0.718955 0.692129 -0.063417 +vn 0.645222 0.165136 0.745903 +vn 0.347850 0.805841 -0.479141 +vn 0.305155 0.797845 -0.519913 +vn -0.029908 0.717795 0.695578 +vn 0.403943 0.016297 0.914609 +vn 0.349406 0.793939 0.497513 +vn -0.039491 0.757744 -0.651295 +vn -0.987640 0.110630 0.110752 +vn -0.955840 -0.169652 0.239906 +vn -0.816370 -0.519547 0.252113 +vn -0.495651 -0.858913 0.128636 +vn 0.000000 -0.978790 0.204840 +vn 0.000000 -0.894284 0.447432 +vn 0.014557 -0.723930 0.689688 +vn 0.749870 0.008362 -0.661489 +vn 0.643025 0.156652 0.749626 +vn 0.010315 0.384991 0.922849 +vn -0.028108 0.032258 0.999054 +vn 0.130467 0.585009 0.800439 +vn 0.739647 -0.505020 0.444746 +vn 0.702780 -0.692770 -0.161596 +vn 0.878323 -0.417737 -0.232337 +vn 0.555223 -0.831294 -0.025239 +vn 0.887539 -0.400861 -0.226997 +vn -0.099826 -0.837642 0.536973 +vn 0.287332 -0.831629 -0.475173 +vn -0.057772 -0.669759 0.740287 +vn 0.643055 0.156682 0.749565 +vn 0.010315 0.384808 0.922910 +vn -0.028138 0.032258 0.999054 +vn 0.130467 0.584979 0.800470 +vn 0.945891 -0.266182 0.185430 +vn -0.236549 -0.672140 0.701590 +vn 0.430036 -0.902554 -0.020875 +vn -0.249550 -0.186285 0.950255 +vn 0.972747 -0.056642 0.224738 +vn -0.241493 -0.049898 0.969085 +vn 0.695853 -0.507645 0.507981 +vn -0.622852 -0.663625 0.414258 +vn 0.314097 -0.949248 0.015809 +vn -0.685446 -0.430189 0.587420 +vn 0.824732 -0.370464 0.427229 +vn -0.526688 -0.612568 0.589343 +vn 0.347179 -0.936155 -0.055422 +vn -0.557482 -0.382855 0.736595 +vn 0.904843 -0.333415 0.264687 +vn -0.317423 -0.828272 0.461684 +vn 0.443007 -0.887722 -0.125065 +vn -0.364910 -0.672750 0.643605 +vn 0.414014 -0.024628 0.909909 +vn -0.539872 0.313852 0.781030 +vn 0.420484 0.705008 0.571062 +vn 0.872372 -0.067660 0.484085 +vn -0.423322 0.175878 0.888730 +vn 0.483566 0.723685 0.492355 +vn 0.943876 0.117527 0.308664 +vn -0.182379 0.348033 0.919553 +vn -0.250435 0.103000 0.962615 +vn 0.554155 0.743858 0.373547 +vn -0.548509 0.050661 0.834590 +vn 0.561876 -0.771203 0.299142 +vn 0.650533 0.168432 0.740532 +vn -0.680135 -0.722068 0.126438 +vn -0.063631 -0.876125 -0.477859 +vn 0.972045 -0.227546 -0.057833 +vn -0.971557 0.143406 0.188299 +vn 0.065462 0.747002 0.661550 +vn 0.319590 0.125675 0.939177 +vn -0.344432 -0.912168 0.221931 +vn 0.801324 -0.572405 0.173711 +vn -0.777337 0.051210 0.626942 +vn 0.428999 -0.780206 -0.455214 +vn -0.889920 -0.410108 -0.199530 +vn 0.887051 0.313547 0.338786 +vn -0.427931 0.654378 0.623402 +vn -0.344432 -0.912168 0.221961 +vn -0.777306 0.051241 0.627003 +vn -0.889950 -0.410077 -0.199469 +vn 0.887051 0.313547 0.338755 +vn -0.427900 0.654378 0.623402 +vn 0.564440 0.051241 0.823878 +vn -0.578417 -0.759941 0.296457 +vn 0.686728 -0.711753 0.147496 +vn -0.655934 0.144597 0.740806 +vn 0.032044 -0.877773 -0.477950 +vn -0.969176 -0.237739 -0.064180 +vn 0.969024 0.156346 0.191107 +vn -0.034120 0.747276 0.663594 +vn -0.563494 0.102817 0.819666 +vn 0.563494 -0.756981 0.330790 +vn 0.667959 0.186895 0.720298 +vn -0.685232 -0.704550 0.184332 +vn -0.052858 -0.906125 -0.419660 +vn 0.966857 -0.249611 -0.053346 +vn -0.967589 0.177465 0.179540 +vn 0.052614 0.800470 0.597034 +vn 0.278268 0.170446 0.945250 +vn -0.285501 -0.913907 0.288522 +vn 0.794824 -0.581408 0.173681 +vn -0.784234 0.122868 0.608173 +vn 0.484603 -0.784051 -0.387768 +vn -0.902341 -0.401685 -0.156102 +vn 0.900357 0.312479 0.302744 +vn -0.483474 0.688040 0.541124 +vn 0.278146 0.170385 0.945280 +vn -0.285562 -0.913907 0.288430 +vn 0.794794 -0.581439 0.173711 +vn -0.784265 0.122745 0.608142 +vn 0.484695 -0.784020 -0.387738 +vn -0.902341 -0.401715 -0.156133 +vn -0.483444 0.688040 0.541124 +vn 0.521653 0.102420 0.846950 +vn -0.519883 -0.782586 0.342418 +vn 0.668233 -0.731712 0.134220 +vn -0.652760 0.245277 0.716727 +vn 0.126865 -0.899197 -0.418714 +vn -0.974792 -0.220435 -0.033937 +vn 0.975219 0.142796 0.168859 +vn -0.126194 0.797266 0.590258 +vn -0.985931 0.101566 0.132542 +vn -0.871944 -0.020753 0.489151 +vn -0.961882 0.036348 0.270974 +vn -0.848323 0.253182 0.464980 +vn -0.962981 0.100681 -0.249977 +vn -0.853908 0.510575 0.100497 +vn -0.966857 -0.237892 -0.092624 +vn -0.984710 0.083468 0.152745 +vn -0.970733 -0.046571 -0.235450 +vn -0.996673 -0.081210 0.006409 +vn -0.737938 -0.151769 0.657521 +vn -0.981109 -0.083712 0.174383 +vn -0.932401 -0.348643 0.095096 +vn -0.749077 -0.048555 -0.660665 +vn -0.426893 -0.169469 -0.888241 +vn -0.486862 -0.029481 -0.872951 +vn -0.899442 0.151677 -0.409803 +vn -0.583117 -0.553636 -0.594470 +vn -0.464949 -0.331065 -0.821070 +vn -0.500595 -0.095950 -0.860317 +vn -0.525376 -0.098025 -0.845180 +vn -0.765069 -0.232429 -0.600513 +vn -0.959380 0.184027 -0.213782 +vn -0.599078 0.799402 -0.045137 +vn -0.871517 0.490249 -0.009186 +vn -0.614612 0.734306 0.288034 +vn -0.867519 0.428419 0.252632 +vn -0.032563 0.826930 0.561327 +vn -0.100925 0.270516 0.957396 +vn -0.980346 -0.071078 0.183996 +vn -0.498245 -0.858852 -0.118778 +vn -0.403363 -0.852443 -0.332560 +vn -0.156346 -0.842738 -0.515091 +vn -0.316935 -0.520524 -0.792810 +vn 0.190710 -0.681021 0.706961 +vn -0.008911 -0.936644 0.350078 +vn -0.151524 -0.987945 0.031373 +vn -0.251564 0.310068 0.916807 +vn -0.338176 -0.913663 0.225440 +vn -0.730827 0.173956 0.659993 +vn 0.121433 -0.953154 0.276925 +vn 0.483016 0.085879 0.871364 +vn 0.019379 -0.770165 0.637532 +vn -0.008393 0.351848 0.936003 +vn -0.447859 0.059847 0.892056 +vn -0.127873 0.575976 0.807367 +vn -0.018860 0.827693 0.560808 +vn 0.501572 0.617878 0.605487 +vn -0.492813 0.650929 0.577380 +vn 0.108493 0.620167 0.776910 +vn 0.725120 0.150273 0.671987 +vn 0.632832 0.701926 0.326762 +vn -0.008759 0.997375 0.071505 +vn -0.007172 0.913480 0.406751 +vn 0.604297 0.795587 -0.042970 +vn 0.900296 0.430860 0.061495 +vn 0.871090 0.393963 0.293130 +vn 0.039216 0.841914 0.538133 +vn 0.827265 0.201972 0.524216 +vn 0.025086 0.202460 0.978942 +vn 0.833766 0.542222 0.103946 +vn 0.966308 0.149693 -0.209265 +vn 0.970214 -0.100101 0.220557 +vn 0.086062 0.282632 0.955351 +vn 0.321268 0.380810 0.867031 +vn -0.022828 -0.931761 0.362255 +vn -0.195013 -0.648091 0.736137 +vn 0.482559 -0.859859 0.166509 +vn 0.161657 -0.985168 0.057100 +vn 0.100864 -0.970031 0.221015 +vn 0.045686 -0.995544 0.082339 +vn 0.503006 -0.862606 0.053529 +vn 0.283517 -0.902646 -0.323740 +vn 0.775536 -0.254799 -0.577563 +vn 0.965117 0.026368 -0.260445 +vn 0.216010 -0.952269 -0.215583 +vn 0.350017 -0.878231 0.325785 +vn -0.236671 -0.951537 -0.196295 +vn -0.001434 -0.993866 0.110477 +vn 0.075503 -0.994293 0.075320 +vn -0.220038 -0.965972 0.135899 +vn -0.503128 -0.823298 -0.262642 +vn -0.314188 -0.915433 0.251473 +vn 0.385571 -0.804071 0.452498 +vn 0.000000 -0.936186 0.351482 +vn 0.000000 -0.836451 0.547990 +vn 0.005646 -0.981323 -0.192206 +vn -0.221473 -0.974151 0.043977 +vn 0.299478 -0.902524 -0.309366 +vn 0.349467 -0.934874 -0.062197 +vn 0.219123 -0.974517 0.047334 +vn -0.012574 -0.996765 0.079257 +vn -0.144108 -0.986084 0.082522 +vn -0.385571 -0.804071 0.452498 +vn 0.000000 -0.999512 0.030549 +vn 0.372356 -0.900723 0.223548 +vn 0.304025 -0.952605 -0.007874 +vn -0.031098 -0.998444 0.046022 +vn 0.040193 -0.998077 0.046693 +vn -0.053468 -0.940092 0.336650 +vn -0.059755 -0.987732 -0.144200 +vn -0.304788 -0.941496 0.143803 +vn -0.241035 -0.951689 -0.190100 +vn -0.100925 -0.970580 0.218543 +vn 0.293222 -0.955962 -0.010376 +vn 0.314097 -0.915891 0.249855 +vn -0.216071 -0.952239 -0.215674 +vn 0.503189 -0.823206 -0.262795 +vn -0.349712 -0.878964 0.324168 +vn -0.162267 -0.985137 0.055940 +vn 0.236061 -0.917234 -0.320780 +vn -0.399701 -0.756157 -0.518052 +vn -0.490310 -0.690909 -0.531205 +vn 0.038881 -0.733757 -0.678243 +vn -0.312296 -0.833491 -0.455733 +vn 0.114444 -0.822474 -0.557115 +vn -0.807917 -0.588488 0.030488 +vn -0.132298 -0.774010 0.619160 +vn 0.424177 -0.555559 0.715110 +vn 0.396496 -0.776971 0.488937 +vn 0.190466 -0.973937 0.123020 +vn 0.437239 -0.701041 0.563311 +vn 0.435774 -0.636067 0.636769 +vn 0.393811 -0.852260 0.344249 +vn 0.188940 -0.974273 0.122654 +vn 0.495651 -0.858913 0.128636 +vn 0.619465 -0.620991 0.480178 +vn 0.816370 -0.519547 0.252113 +vn -0.619465 -0.620991 0.480178 +vn -0.827052 -0.022279 0.561632 +vn -0.755730 -0.256783 0.602405 +vn -0.601917 -0.461562 0.651631 +vn -0.623829 -0.061098 0.779138 +vn -0.670095 -0.163518 0.724021 +vn -0.760552 -0.471358 0.446455 +vn -0.414472 0.284646 0.864376 +vn -0.232276 0.517502 0.823511 +vn -0.699759 0.416425 0.580401 +vn -0.763939 0.310068 0.565874 +vn -0.335734 0.632344 0.698111 +vn -0.798639 0.218787 0.560564 +vn -0.452010 0.601245 0.658895 +vn -0.973113 0.209754 0.094852 +vn -0.986236 -0.163823 -0.022126 +vn -0.475753 0.847621 0.234870 +vn 0.009461 0.943541 0.331065 +vn -0.063234 0.667013 0.742332 +vn -0.076937 0.714866 0.694998 +vn 0.032228 0.983276 0.179174 +vn 0.544664 0.822687 0.162816 +vn 0.300211 0.825465 -0.477950 +vn -0.129612 0.944670 -0.301279 +vn -0.245064 0.942534 -0.226966 +vn -0.803552 0.541459 -0.247169 +vn -0.910886 0.127689 -0.392346 +vn -0.796869 -0.236091 -0.556047 +vn -0.831599 -0.554460 -0.031373 +vn -0.243690 -0.747063 -0.618458 +vn -0.456771 -0.871761 0.177038 +vn 0.490280 -0.696036 -0.524522 +vn 0.361980 -0.575762 0.733085 +vn 0.899197 -0.222175 -0.376904 +vn 0.785485 0.252083 0.565172 +vn 0.795831 0.375927 -0.474624 +vn 0.221381 -0.974487 0.036073 +vn 0.303323 -0.952574 -0.023438 +vn 0.283273 -0.902463 -0.324473 +vn -0.018464 -0.998627 0.048891 +vn -0.013459 -0.981567 -0.190527 +vn 0.023041 -0.998505 0.049074 +vn 0.316446 -0.939512 0.131016 +vn 0.196966 -0.977538 -0.074831 +vn -0.090091 -0.929685 0.357097 +vn 0.017975 -0.724509 0.688986 +vn 0.158300 -0.943693 0.290475 +vn -0.071932 -0.987304 -0.141423 +vn -0.297098 -0.941404 0.159520 +vn -0.250618 -0.951659 -0.177465 +vn 0.487197 -0.861293 0.144017 +vn -0.324900 -0.913297 0.245521 +vn 0.345897 -0.934812 -0.080142 +vn -0.006043 -0.996399 0.084292 +vn 0.226936 -0.680776 0.696402 +vn 0.009186 -0.936613 0.350200 +vn -0.089511 -0.970550 0.223609 +vn -0.159124 -0.985137 0.064333 +vn -0.332560 -0.878872 0.341929 +vn -0.149571 -0.987945 0.039186 +vn 0.219306 -0.917234 -0.332499 +vn -0.226997 -0.952239 -0.204199 +vn 0.326731 -0.915799 0.233497 +vn 0.292367 -0.955931 -0.025361 +vn -0.510605 -0.857021 -0.068880 +vn -0.405377 -0.880551 -0.245399 +vn -0.133946 -0.989257 0.058077 +vn 0.489029 -0.823206 -0.288308 +vn -0.168371 -0.973724 -0.153111 +vn -0.356273 -0.917814 0.175024 +vn -0.001465 -0.999878 -0.015076 +vn -0.359752 -0.829676 0.426832 +vn 0.018159 -0.936033 0.351390 +vn 0.025605 -0.855617 0.516923 +vn 0.062593 -0.997314 0.037935 +vn 0.402142 -0.832484 0.381054 +vn 0.355998 -0.925413 0.129673 +vn 0.068117 -0.984130 -0.163762 +vn -0.015870 -0.953337 -0.301401 +vn -0.173254 -0.896329 -0.408063 +vn -0.825007 -0.457289 -0.331980 +vn 0.133213 -0.440535 -0.887783 +vn -0.667470 -0.566149 -0.483657 +vn -0.957091 -0.132786 -0.257454 +vn -0.996887 -0.072207 0.031526 +vn -0.520920 -0.644765 -0.559343 +vn -0.990265 -0.081454 -0.112735 +vn -0.295389 -0.842189 -0.451033 +vn -0.019532 -0.940092 -0.340312 +vn 0.109500 -0.906461 -0.407819 +vn -0.038606 -0.771996 -0.634419 +vn 0.035218 -0.680410 -0.731956 +vn 0.829066 0.168065 -0.533250 +vn 0.687338 -0.286538 -0.667379 +vn 0.590594 -0.468062 -0.657308 +vn 0.463301 -0.633747 -0.619404 +vn 0.256325 -0.845027 -0.469222 +vn -0.030244 -0.880917 -0.472243 +vn 0.796258 -0.438795 -0.416395 +vn 0.963042 0.133976 -0.233558 +vn 0.268868 -0.918119 -0.291055 +vn 0.902371 0.430647 0.014985 +vn 0.613819 0.786004 -0.073489 +vn 0.649007 0.701773 0.293741 +vn 0.811579 0.583087 -0.035981 +vn 0.977020 -0.056368 -0.205420 +vn 0.978118 -0.033418 -0.205298 +vn 0.965423 -0.069460 -0.251167 +vn 0.968291 0.062502 -0.241859 +vn 0.977172 0.107730 -0.182958 +vn 0.940031 -0.228431 0.253212 +vn 0.982696 0.061617 -0.174627 +vn 0.951445 -0.176427 0.252205 +vn 0.947020 -0.173345 0.270333 +vn 0.955687 0.001984 0.294259 +vn 0.820521 0.361248 0.442976 +vn 0.846431 0.457198 0.272896 +vn 0.068636 0.683401 0.726798 +vn 0.704856 -0.252327 0.662923 +vn -0.563097 -0.552019 0.614917 +vn 0.339610 -0.437788 0.832423 +vn 0.953124 -0.069247 0.294504 +vn 0.361003 -0.639668 0.678549 +vn 0.478439 -0.607868 0.633686 +vn 0.324900 -0.591388 0.737999 +vn -0.604938 -0.591571 0.532945 +vn -0.450819 -0.704764 0.547716 +vn -0.925504 -0.365429 0.099368 +vn -0.525193 -0.544389 0.654012 +vn -0.955046 -0.292550 -0.047426 +vn -0.828211 -0.559709 -0.026887 +vn 0.013489 -0.980316 0.196875 +vn 0.594195 -0.802576 0.052461 +vn 0.969268 -0.236579 0.066988 +vn 0.627949 -0.776605 0.050050 +vn 0.924528 0.072085 0.374187 +vn -0.417646 -0.890042 -0.182684 +vn 0.998352 -0.055666 -0.013398 +vn 0.956786 -0.288949 -0.032258 +vn 0.936094 0.276650 0.217109 +vn 0.626942 -0.776635 0.061129 +vn 0.951353 -0.308023 0.005463 +vn 0.561296 -0.824793 -0.067995 +vn 0.996521 -0.060305 -0.057161 +vn 0.981597 0.188879 0.027802 +vn 0.801630 0.586596 0.115085 +vn 0.948851 -0.315531 -0.008789 +vn 0.997742 -0.048585 -0.046052 +vn 0.978301 0.201819 -0.046419 +vn 0.999542 -0.023194 -0.018860 +vn 0.938108 -0.237800 -0.251656 +vn 0.713126 -0.415204 -0.564776 +vn 0.800409 -0.168889 -0.575152 +vn 0.736625 -0.065004 -0.673147 +vn -0.242195 0.001556 -0.970214 +vn 0.964171 -0.107395 -0.242500 +vn 0.981567 -0.084597 -0.171239 +vn 0.953520 -0.047884 -0.297403 +vn 0.826044 -0.070559 0.559130 +vn 0.980102 0.014344 0.197913 +vn 0.978607 -0.097507 0.181005 +vn 0.919248 -0.222480 0.324747 +vn 0.678121 -0.442152 0.586993 +vn 0.494034 -0.440138 0.749779 +vn -0.015931 -0.664602 0.747002 +vn 0.746666 -0.334391 0.574969 +vn -0.109897 -0.474868 0.873135 +vn -0.754204 -0.478500 0.449599 +vn -0.898373 -0.176183 -0.402295 +vn -0.916410 -0.233406 0.325053 +vn -0.889065 -0.113315 -0.443495 +vn -0.392773 -0.287454 0.873531 +vn 0.319956 -0.255196 0.912381 +vn 0.890164 -0.160863 0.426221 +vn 0.865566 -0.137150 0.481613 +vn 0.135502 -0.173833 0.975372 +vn -0.610370 -0.151189 0.777520 +vn -0.817408 -0.037629 -0.574786 +vn 0.058290 -0.214667 0.974914 +vn 0.796472 -0.262246 0.544816 +vn 0.964049 -0.150609 -0.218818 +vn 0.938994 -0.082095 -0.333964 +vn 0.519242 -0.072634 -0.851527 +vn 0.459914 -0.078127 -0.884487 +vn -0.133702 -0.086184 -0.987243 +vn 0.969573 -0.217078 -0.112918 +vn 0.652181 -0.179113 -0.736564 +vn -0.006500 -0.200079 -0.979736 +vn 0.463729 -0.213141 -0.859920 +vn 0.091769 -0.985229 -0.144475 +vn 0.126988 -0.861232 -0.492050 +vn 0.290353 -0.535081 -0.793298 +vn -0.093631 -0.233406 -0.967834 +vn -0.071261 -0.191748 -0.978851 +vn -0.027436 -0.583728 -0.811457 +vn -0.230873 -0.185186 -0.955168 +vn -0.008515 -0.883236 -0.468795 +vn 0.000000 -0.953948 -0.299936 +vn -0.165899 -0.975677 -0.143132 +vn -0.372356 -0.900723 0.223579 +vn -0.853420 0.428236 0.297006 +vn -0.599139 0.734153 0.319346 +vn -0.870937 0.490036 0.035676 +vn -0.003540 0.826807 0.562456 +vn -0.606372 0.794702 -0.026337 +vn -0.978942 0.163152 -0.122501 +vn -0.969543 -0.071017 0.234291 +vn -0.051424 0.270486 0.961333 +vn -0.203803 0.310038 0.928587 +vn -0.690451 0.169225 0.703269 +vn -0.462569 0.650716 0.602130 +vn 0.106174 0.635670 0.764580 +vn 0.008271 0.825251 0.564653 +vn 0.014801 0.407819 0.912931 +vn -0.054018 0.599078 0.798822 +vn 0.532212 0.617725 0.578875 +vn 0.484451 0.073641 0.871700 +vn -0.398968 0.059816 0.914975 +vn 0.752312 0.141850 0.643330 +vn -0.005219 0.997192 0.074587 +vn -0.813471 0.575762 0.081912 +vn 0.004181 0.990234 0.139286 +vn 0.365612 0.380902 0.849239 +vn 0.067019 0.841853 0.535478 +vn -0.788507 0.464095 0.403516 +vn -0.719230 0.359569 0.594440 +vn 0.051790 0.550493 0.833216 +vn 0.324503 0.023164 0.945585 +vn -0.964080 -0.195563 0.179632 +vn -0.650258 0.090579 0.754265 +vn -0.980468 -0.000610 0.196600 +vn 0.513138 -0.856655 0.052980 +vn 0.980285 -0.100040 0.170263 +vn 0.885128 0.393811 0.247810 +vn 0.135289 0.282662 0.949614 +vn -0.004181 -0.931730 0.363109 +vn 0.049715 -0.995544 0.079989 +vn 0.164373 -0.985168 0.048799 +vn -0.246651 -0.951476 -0.183813 +vn 0.204627 -0.952269 -0.226386 +vn -0.156804 -0.647816 0.745445 +vn -0.212836 -0.965911 0.147221 +vn -0.516160 -0.823206 -0.236335 +vn 0.002472 -0.993408 0.114353 +vn -0.300943 -0.915311 0.267525 +vn 0.112156 -0.969970 0.215705 +vn 0.366405 -0.878140 0.307505 +vn -0.219001 -0.974120 0.055422 +vn -0.303476 -0.952818 0.003662 +vn 0.233039 -0.951201 -0.202094 +vn -0.312571 -0.901822 -0.298257 +vn -0.156804 -0.986633 -0.043977 +vn -0.966094 -0.010712 -0.257942 +vn -0.975555 0.027619 -0.217994 +vn -0.614093 0.204901 -0.762139 +vn 0.836634 0.217505 -0.502701 +vn -0.120029 0.266335 -0.956359 +vn 0.979553 0.043611 -0.196356 +vn 0.877468 0.377361 0.296030 +vn 0.908689 0.191534 0.370861 +vn 0.969024 0.039979 0.243599 +vn -0.907865 -0.228278 -0.351573 +vn -0.760338 -0.513047 -0.398297 +vn 0.733329 -0.179174 0.655812 +vn -0.053224 -0.160863 0.985534 +vn 0.287088 0.867946 -0.405225 +vn 0.821711 -0.026795 0.569262 +vn 0.716208 0.612629 -0.334147 +vn 0.577807 0.247139 0.777825 +vn 0.330729 0.939451 0.089450 +vn -0.458174 0.534715 0.709983 +vn 0.401074 0.841334 -0.362285 +vn 0.119694 -0.269295 0.955565 +vn 0.948973 0.300668 -0.094943 +vn 0.653737 -0.459181 0.601459 +vn -0.360088 -0.460219 0.811487 +vn -0.816157 0.528916 0.232521 +vn 0.313242 0.752098 0.579821 +vn -0.833827 -0.321207 0.448927 +vn -0.821223 -0.086978 0.563891 +vn -0.610523 -0.532945 0.585833 +vn -0.260140 -0.719626 0.643727 +vn 0.520432 -0.716666 0.464217 +vn 0.940001 -0.306772 0.149144 +vn -0.211890 -0.406079 0.888913 +vn 0.575671 0.750969 0.323405 +vn 0.832820 0.421094 0.359233 +vn 0.497147 0.810389 0.309946 +vn 0.977203 -0.036195 0.209143 +vn 0.855220 -0.508194 -0.101321 +vn 0.458632 -0.818323 0.346385 +vn 0.828181 -0.555895 -0.071322 +vn 0.576617 -0.615009 0.537828 +vn 0.405072 -0.605792 0.684744 +vn 0.473739 -0.509171 0.718528 +vn -0.107517 -0.741325 0.662435 +vn -0.224830 -0.674551 0.703146 +vn 0.009278 -0.595965 0.802911 +vn 0.220252 -0.650380 0.726951 +vn -0.028291 -0.745293 0.666097 +vn 0.300180 -0.820460 0.486465 +vn 0.515885 -0.781121 0.351634 +vn -0.064821 -0.717338 0.693686 +vn 0.968780 -0.170568 -0.179846 +vn 0.903836 -0.151646 0.400037 +vn 0.088992 -0.452773 0.887143 +vn -0.529984 -0.314951 0.787317 +vn -0.456984 -0.877773 -0.143742 +vn 0.324290 -0.733543 0.597247 +vn 0.574145 -0.479659 0.663472 +vn -0.557115 -0.222846 -0.799951 +vn -0.886593 -0.279305 0.368603 +vn -0.154759 0.076418 0.984985 +vn 0.352947 0.140599 0.924986 +vn 0.938932 0.191900 -0.285562 +vn 0.977599 0.170934 -0.122715 +vn -0.361309 -0.636677 0.681204 +vn 0.047731 -0.842494 0.536515 +vn 0.035401 -0.523850 0.851039 +vn 0.265114 -0.368236 0.891110 +vn 0.364452 0.108158 0.924894 +vn 0.709250 -0.150517 0.688681 +vn 0.533586 -0.743004 0.403974 +vn 0.670095 -0.163518 0.723991 +vn 0.760552 -0.471358 0.446455 +vn 0.724815 -0.688864 -0.008484 +vn 0.629139 -0.758568 0.169408 +vn 0.516098 -0.702414 0.490127 +vn 0.424970 -0.396496 0.813715 +vn 0.128086 -0.717093 0.685049 +vn 0.256081 -0.582049 0.771752 +vn 0.326487 -0.556566 0.763939 +vn 0.446364 -0.512955 0.733207 +vn 0.644276 -0.391430 0.657002 +vn 0.448775 -0.734489 0.508988 +vn 0.658193 -0.692251 0.295846 +vn 0.285653 -0.927061 0.242744 +vn 0.502243 -0.864009 0.034486 +vn 0.812555 -0.582476 -0.021241 +vn 0.978332 -0.168798 -0.119846 +vn 0.978454 0.020051 -0.205420 +vn 0.884304 0.208472 -0.417707 +vn 0.965606 0.149998 -0.212317 +vn 0.987640 0.110630 0.110721 +vn 0.955840 -0.169652 0.239906 +vn 0.794427 0.082522 0.601672 +vn 0.978576 0.104709 -0.177190 +vn 0.783441 0.324595 -0.529923 +vn 0.479385 0.586963 -0.652394 +vn 0.089480 0.828608 -0.552599 +vn 0.202490 0.772942 -0.601245 +vn -0.016663 0.957183 -0.288919 +vn 0.627613 0.568896 -0.531388 +vn 0.884823 0.319712 -0.338816 +vn 0.000000 0.836207 -0.548357 +vn 0.000000 0.986328 -0.164647 +vn 0.001587 0.995788 0.091311 +vn 0.000000 0.997955 0.063631 +vn 0.227912 0.923399 0.308817 +vn -0.227912 0.923399 0.308817 +vn -0.001526 0.995788 0.091342 +vn 0.023469 0.956694 -0.290078 +vn -0.196204 0.766778 -0.611164 +vn 0.476577 0.879055 0.008759 +vn -0.096194 0.818140 -0.566881 +vn -0.476424 0.568255 -0.670858 +vn -0.723533 0.463363 -0.511612 +vn 0.601917 -0.461562 0.651631 +vn 0.755730 -0.256783 0.602405 +vn 0.827052 -0.022279 0.561632 +vn 0.744041 0.233314 0.626026 +vn 0.601093 0.295114 0.742668 +vn 0.571856 0.626698 0.529313 +vn 0.571673 0.679525 0.459761 +vn 0.449293 0.772942 0.447920 +vn 0.267342 0.404981 0.874325 +vn 0.029939 0.717795 0.695578 +vn -0.034761 0.984161 0.173803 +vn -0.544084 0.807092 0.229194 +vn -0.695853 0.241340 0.676382 +vn -0.350749 -0.469558 0.810205 +vn 0.454848 -0.866237 0.206610 +vn -0.307566 0.834895 -0.456374 +vn -0.838282 0.459487 -0.293466 +vn -0.965911 -0.166631 -0.197974 +vn -0.492019 -0.723960 -0.483474 +vn 0.289956 -0.783807 -0.549089 +vn 0.937559 0.049104 -0.344279 +vn 0.811853 0.519456 -0.266518 +vn 0.238472 0.949522 -0.203650 +vn 0.147710 0.935484 -0.320933 +vn 0.853420 0.428236 0.297006 +vn 0.599139 0.734153 0.319346 +vn 0.003571 0.826807 0.562456 +vn 0.870937 0.490036 0.035676 +vn -0.008271 0.825251 0.564653 +vn 0.462569 0.650716 0.602130 +vn 0.969543 -0.071017 0.234291 +vn 0.051454 0.270486 0.961333 +vn 0.203864 0.310038 0.928587 +vn 0.690451 0.169225 0.703299 +vn -0.106174 0.635670 0.764580 +vn -0.014801 0.407819 0.912931 +vn 0.054018 0.599078 0.798853 +vn -0.532243 0.617695 0.578906 +vn -0.484451 0.073641 0.871700 +vn 0.548509 0.050661 0.834590 +vn -0.561907 -0.771203 0.299112 +vn 0.680135 -0.722068 0.126408 +vn -0.650563 0.168401 0.740501 +vn 0.063631 -0.876095 -0.477859 +vn -0.972015 -0.227577 -0.057894 +vn 0.971557 0.143406 0.188299 +vn -0.065493 0.747002 0.661550 +vn -0.319590 0.125675 0.939177 +vn 0.344432 -0.912168 0.221931 +vn 0.777337 0.051210 0.626942 +vn -0.801324 -0.572405 0.173711 +vn -0.428999 -0.780206 -0.455214 +vn 0.889920 -0.410108 -0.199530 +vn -0.887051 0.313547 0.338786 +vn 0.427931 0.654378 0.623402 +vn -0.319559 0.125736 0.939177 +vn 0.344432 -0.912168 0.221961 +vn 0.777306 0.051241 0.627003 +vn -0.801355 -0.572344 0.173833 +vn 0.889950 -0.410077 -0.199469 +vn -0.886990 0.313608 0.338878 +vn 0.427900 0.654378 0.623402 +vn -0.564257 0.051241 0.823969 +vn 0.578539 -0.759850 0.296396 +vn 0.656056 0.144627 0.740684 +vn -0.686636 -0.711875 0.147374 +vn -0.031983 -0.877773 -0.477950 +vn 0.969207 -0.237709 -0.064180 +vn -0.969024 0.156316 0.191046 +vn 0.034272 0.747276 0.663594 +vn 0.563494 0.102817 0.819666 +vn -0.563494 -0.756951 0.330821 +vn 0.685232 -0.704550 0.184362 +vn -0.667959 0.186926 0.720298 +vn 0.052828 -0.906125 -0.419660 +vn -0.966857 -0.249580 -0.053346 +vn 0.967589 0.177465 0.179540 +vn -0.052614 0.800470 0.597034 +vn 0.728233 -0.675954 -0.112674 +vn 0.752159 -0.453108 0.478408 +vn 0.584674 -0.810724 0.029542 +vn 0.894253 -0.401044 -0.198553 +vn -0.284829 0.838527 -0.464461 +vn -0.022248 0.771325 -0.636036 +vn 0.107700 0.761559 -0.639058 +vn 0.824549 -0.302591 0.478042 +vn -0.403943 0.016297 0.914609 +vn -0.645192 0.165136 0.745903 +vn -0.349406 0.793939 0.497513 +vn 0.958220 0.054170 0.280740 +vn -0.718955 0.692129 -0.063387 +vn -0.305155 0.797845 -0.519913 +vn -0.347850 0.805872 -0.479110 +vn -0.721030 0.691733 0.040193 +vn 0.594409 0.571520 -0.565661 +vn 0.271035 0.760674 -0.589801 +vn -0.223212 0.859828 -0.459151 +vn -0.477065 0.878780 0.009949 +vn 0.472335 -0.730338 -0.493423 +vn -0.052553 -0.906339 -0.419233 +vn -0.579424 -0.737205 -0.347484 +vn -0.907407 -0.288430 -0.305551 +vn -0.912198 0.268654 -0.309336 +vn -0.592151 0.722221 -0.357372 +vn -0.135685 -0.007385 -0.990692 +vn -0.068667 0.899533 -0.431410 +vn 0.458968 0.732170 -0.503220 +vn 0.788873 0.283212 -0.545366 +vn 0.794061 -0.275796 -0.541612 +vn -0.152409 0.009613 0.988250 +vn -0.152776 0.007843 0.988220 +vn -0.154118 0.009003 0.988006 +vn -0.154607 0.010193 0.987915 +vn -0.155583 0.008728 0.987762 +vn -0.156316 0.008911 0.987640 +vn -0.156285 0.006989 0.987671 +vn -0.154637 0.006775 0.987945 +vn -0.154729 0.005371 0.987915 +vn -0.152287 0.007569 0.988281 +vn -0.150609 0.008789 0.988525 +vn -0.152104 0.009522 0.988311 +vn -0.153935 0.008942 0.988037 +vn -0.154393 0.010254 0.987945 +vn -0.155492 0.008759 0.987793 +vn -0.156133 0.008759 0.987671 +vn -0.156194 0.006836 0.987701 +vn -0.154180 0.006256 0.988006 +vn -0.153233 0.005585 0.988159 +vn -0.151402 0.007050 0.988433 +vn 0.696799 0.669027 0.258461 +vn 0.998108 0.060457 0.010620 +vn 0.638050 0.588275 0.496750 +vn 0.703787 0.484695 0.519303 +vn 0.993988 -0.049379 -0.097659 +vn 0.704917 0.462050 0.538102 +vn 0.992767 -0.014069 -0.118961 +vn 0.704306 0.472365 0.529893 +vn 0.990020 0.017579 -0.139805 +vn 0.751396 0.634266 0.181768 +vn 0.580767 -0.436048 -0.687399 +vn 0.558763 -0.523026 -0.643574 +vn 0.580340 -0.583117 -0.568468 +vn 0.948119 -0.009247 -0.317759 +vn 0.497299 -0.441328 -0.746910 +vn 0.828516 0.397412 -0.394421 +vn 0.580218 -0.393231 -0.713218 +vn 0.480148 -0.116947 -0.869320 +vn -0.070040 -0.091739 -0.993286 +vn 0.664266 -0.105472 -0.739982 +vn -0.168218 -0.139103 -0.975860 +vn 0.303507 -0.952818 0.003693 +vn -0.232978 -0.951231 -0.202094 +vn 0.312632 -0.901791 -0.298257 +vn -0.316416 -0.939512 0.130985 +vn -0.196905 -0.977538 -0.074831 +vn 0.156835 -0.986633 -0.043977 +vn 0.199225 -0.977844 -0.063845 +vn -0.154241 -0.986633 -0.052034 +vn 0.243049 -0.951231 -0.189795 +vn -0.296640 -0.901914 -0.313883 +vn -0.303140 -0.952849 -0.012024 +vn 0.309153 -0.939573 0.146977 +vn 0.644551 0.702445 0.301798 +vn 0.976653 0.204657 0.064852 +vn 0.000000 -0.945158 -0.326548 +vn 0.214942 0.950377 0.224830 +vn 0.000000 0.991363 0.130985 +vn 0.486099 0.671316 0.559435 +vn -0.360454 -0.444258 -0.820154 +vn 0.000000 0.573199 0.819391 +vn -0.749901 0.008393 -0.661458 +vn -0.326426 -0.929106 0.173711 +vn 0.000000 -0.978362 0.206793 +vn -0.397931 -0.833644 -0.382885 +vn 0.512955 -0.378307 0.770531 +vn -0.804376 -0.593677 -0.022309 +vn -0.887051 -0.218177 -0.406781 +vn 0.000000 -0.616565 0.787286 +vn -0.512955 -0.378307 0.770531 +vn 0.326426 -0.929106 0.173711 +vn -0.903836 -0.151646 0.400037 +vn -0.486099 0.671316 0.559435 +vn -0.644551 0.702445 0.301798 +vn -0.214942 0.950377 0.224830 +vn -0.968780 -0.170568 -0.179846 +vn -0.976653 0.204657 0.064852 +vn 0.970336 -0.041597 0.238136 +vn -0.231269 -0.133824 0.963622 +vn -0.239448 -0.280129 0.929594 +vn 0.968352 0.062075 0.241707 +vn -0.152745 0.417524 0.895718 +vn 0.553453 0.775475 0.303781 +vn 0.139042 -0.341838 0.929380 +vn -0.392956 -0.159398 0.905606 +vn -0.460555 -0.185400 0.868038 +vn 0.291055 -0.254311 0.922269 +vn -0.236457 -0.113712 0.964934 +vn 0.325541 -0.208960 0.922117 +vn 0.066347 -0.178747 0.981628 +vn 0.259102 -0.160680 0.952361 +vn 0.515061 -0.269387 0.813685 +vn 0.794275 -0.258095 0.549974 +vn 0.704733 -0.327891 0.629139 +vn 0.607318 -0.295297 0.737510 +vn 0.783593 -0.529221 0.325358 +vn 0.635762 0.749870 0.182958 +vn 0.543779 0.511368 0.665395 +vn 0.862697 -0.494949 -0.103519 +vn 0.657277 0.635151 -0.405591 +vn 0.921354 -0.386822 0.038240 +vn 0.799738 0.270913 -0.535722 +vn 0.826044 -0.446974 0.343211 +vn 0.012848 0.327891 -0.944609 +vn -0.468398 0.865841 -0.175756 +vn 0.550035 0.601062 -0.579760 +vn -0.955840 0.264412 0.128147 +vn -0.056001 -0.393048 -0.917783 +vn -0.929411 -0.290780 -0.227088 +vn -0.949705 -0.301218 0.085421 +vn 0.225929 -0.148534 -0.962737 +vn -0.625965 -0.623859 -0.467879 +vn 0.419996 -0.428785 -0.799799 +vn 0.239692 0.339244 -0.909604 +vn -0.549425 0.812616 -0.194281 +vn 0.507035 0.565844 -0.650166 +vn -0.937040 0.307077 -0.166295 +vn -0.063875 0.476882 -0.876614 +vn -0.988311 0.097385 0.117069 +vn 0.063875 0.476882 -0.876614 +vn 0.937040 0.307077 -0.166295 +vn 0.988311 0.097385 0.117069 +vn -0.239692 0.339244 -0.909604 +vn 0.549425 0.812616 -0.194281 +vn -0.507035 0.565844 -0.650166 +vn 0.852748 -0.002960 -0.522294 +vn 0.507248 -0.699240 -0.503677 +vn -0.164312 -0.183935 -0.969085 +vn 0.743004 -0.199042 -0.638966 +vn 0.693777 0.196234 -0.692892 +vn 0.633900 0.730918 -0.252693 +vn 0.934446 0.020997 0.355419 +vn 0.783197 0.335704 -0.523331 +vn 0.855800 0.055544 -0.514267 +vn 0.536302 -0.648335 -0.540330 +vn -0.146977 -0.130100 -0.980529 +vn 0.753716 -0.135990 -0.642933 +vn 0.331614 0.239418 -0.912503 +vn 0.744987 -0.458541 -0.484451 +vn -0.112033 -0.166387 -0.979644 +vn 0.937925 -0.182745 0.294717 +vn 0.693960 0.196204 -0.692709 +vn 0.634114 0.730888 -0.252358 +vn 0.934416 0.020936 0.355541 +vn -0.227912 -0.140263 -0.963500 +vn 0.624744 -0.624805 -0.468245 +vn -0.424604 -0.418500 -0.802820 +vn 0.927152 -0.296304 -0.229255 +vn 0.055696 -0.389294 -0.919401 +vn 0.948485 -0.305551 0.083407 +vn -0.416272 0.262490 -0.870510 +vn 0.390790 -0.392712 -0.832484 +vn -0.738456 -0.346507 -0.578417 +vn 0.910672 0.119755 -0.395337 +vn -0.284494 0.226722 -0.931455 +vn 0.479934 -0.459456 -0.747337 +vn -0.638905 -0.254585 -0.725883 +vn 0.981201 0.078860 -0.176000 +vn -0.114566 0.346660 -0.930967 +vn 0.495895 -0.524155 -0.692312 +vn -0.588885 -0.122868 -0.798791 +vn 0.955962 -0.242256 -0.165502 +vn -0.378216 0.299692 -0.875851 +vn 0.356212 0.852382 -0.382763 +vn 0.921323 0.225440 -0.316752 +vn -0.770806 0.565264 -0.293741 +vn -0.247505 0.361187 -0.899014 +vn 0.405499 0.874203 -0.266945 +vn 0.983734 0.156041 -0.088961 +vn -0.669790 0.568651 -0.477432 +vn -0.012848 0.327891 -0.944609 +vn 0.468398 0.865841 -0.175756 +vn 0.955840 0.264412 0.128147 +vn -0.550035 0.601062 -0.579760 +vn -0.852748 -0.002991 -0.522294 +vn -0.507248 -0.699240 -0.503677 +vn -0.743004 -0.199042 -0.638966 +vn 0.164281 -0.183935 -0.969085 +vn -0.693777 0.196234 -0.692892 +vn -0.633900 0.730949 -0.252693 +vn -0.783197 0.335704 -0.523331 +vn -0.934446 0.021027 0.355419 +vn -0.855800 0.055544 -0.514267 +vn -0.536302 -0.648335 -0.540330 +vn -0.753716 -0.135990 -0.642933 +vn 0.146977 -0.130100 -0.980529 +vn -0.331645 0.239418 -0.912503 +vn -0.744987 -0.458510 -0.484481 +vn -0.937925 -0.182714 0.294717 +vn 0.112003 -0.166387 -0.979644 +vn -0.693960 0.196204 -0.692709 +vn -0.634114 0.730888 -0.252358 +vn -0.934416 0.020936 0.355541 +vn 0.416272 0.262490 -0.870510 +vn -0.390790 -0.392712 -0.832484 +vn -0.910672 0.119755 -0.395337 +vn 0.738456 -0.346507 -0.578417 +vn 0.284494 0.226722 -0.931455 +vn -0.479934 -0.459456 -0.747337 +vn -0.981201 0.078860 -0.176000 +vn 0.638905 -0.254585 -0.725883 +vn 0.114536 0.346660 -0.930937 +vn -0.495895 -0.524155 -0.692312 +vn -0.955962 -0.242256 -0.165502 +vn 0.588885 -0.122868 -0.798791 +vn 0.378216 0.299692 -0.875851 +vn -0.356212 0.852382 -0.382763 +vn 0.770806 0.565264 -0.293771 +vn -0.921323 0.225440 -0.316752 +vn 0.247505 0.361187 -0.899014 +vn -0.405499 0.874203 -0.266945 +vn 0.669790 0.568651 -0.477432 +vn -0.983734 0.156041 -0.088961 +vn 0.000000 0.673696 -0.738975 +vn 0.000000 0.974303 -0.225196 +vn 0.000000 -0.997711 -0.067385 +vn 0.000000 -0.848048 0.529862 +vn 0.000000 0.937651 0.347545 +vn 0.000000 -0.765343 0.643605 +vn 0.000000 -0.061342 0.998108 +vn 0.000000 -0.996857 0.078860 +vn -0.710776 0.181555 -0.679556 +vn -0.535386 0.470168 -0.701590 +vn 0.496231 -0.867306 -0.038728 +vn -0.580828 -0.759789 0.292123 +vn 0.890347 -0.317301 -0.326487 +vn -0.468032 -0.791131 0.393689 +vn 0.183538 -0.556780 0.810083 +vn 0.962828 -0.164373 -0.214209 +vn -0.809381 0.537309 -0.237007 +vn 0.276894 0.918912 -0.280831 +vn 0.402814 0.370983 -0.836695 +vn -0.493088 0.575488 0.652394 +vn 0.195257 -0.597095 0.778039 +vn 0.527543 -0.844966 -0.087436 +vn 0.969176 -0.120182 -0.215033 +vn -0.442610 -0.828944 0.341929 +vn -0.183538 -0.556780 0.810083 +vn -0.496231 -0.867306 -0.038728 +vn 0.468001 -0.791162 0.393719 +vn -0.962828 -0.164373 -0.214209 +vn 0.809381 0.537309 -0.237037 +vn -0.276925 0.918912 -0.280831 +vn 0.493088 0.575488 0.652394 +vn -0.402814 0.370983 -0.836695 +vn -0.195257 -0.597064 0.778039 +vn -0.527573 -0.844966 -0.087466 +vn 0.442579 -0.828944 0.341960 +vn -0.969176 -0.120182 -0.215033 +vn -0.809351 0.537339 -0.237037 +vn 0.277108 0.918851 -0.280801 +vn 0.402783 0.371258 -0.836604 +vn -0.492691 0.575365 0.652791 +vn -0.277108 0.918851 -0.280801 +vn 0.809351 0.537339 -0.237037 +vn -0.402783 0.371258 -0.836604 +vn 0.492691 0.575365 0.652791 +vn -0.301920 -0.938414 -0.167882 +vn 0.406171 -0.822321 0.398480 +vn 0.403577 0.489517 0.772942 +vn 0.588031 0.129856 0.798334 +vn 0.814570 -0.473434 -0.335093 +vn -0.551866 0.567919 -0.610614 +vn -0.220649 0.765526 0.604358 +vn 0.306314 0.886288 -0.347270 +vn -0.930357 0.306925 0.200476 +vn 0.031434 -0.466323 -0.884030 +vn -0.793603 -0.439558 0.420606 +vn 0.839625 0.011353 -0.542985 +vn -0.403699 0.489578 0.772820 +vn 0.220832 0.765465 0.604358 +vn -0.306497 0.886349 -0.346995 +vn -0.842372 0.070620 -0.534196 +vn -0.902463 -0.268166 -0.337077 +vn 0.535417 0.470077 -0.701651 +vn 0.552019 0.568011 -0.610401 +vn 0.555681 -0.795587 0.241249 +vn 0.781182 -0.489486 0.387402 +vn 0.930357 0.306833 0.200568 +vn -0.832881 -0.424207 -0.355419 +vn 0.265908 -0.936705 -0.227699 +vn -0.431471 -0.830073 0.353191 +vn -0.057497 -0.409162 -0.910642 +vn -0.588214 0.129978 0.798151 +vn 0.710807 0.181371 -0.679586 +vn -0.555681 -0.795587 0.241249 +vn -0.265908 -0.936705 -0.227699 +vn 0.431471 -0.830103 0.353191 +vn -0.710807 0.181371 -0.679586 +vn -0.535417 0.470077 -0.701621 +vn 0.902463 -0.268166 -0.337077 +vn 0.832881 -0.424207 -0.355419 +vn 0.403699 0.489578 0.772820 +vn 0.588214 0.129978 0.798181 +vn 0.057466 -0.409162 -0.910642 +vn -0.552019 0.568011 -0.610431 +vn -0.220832 0.765465 0.604358 +vn 0.306497 0.886349 -0.346995 +vn -0.930357 0.306803 0.200568 +vn -0.781213 -0.489486 0.387371 +vn 0.842372 0.070620 -0.534227 +vn -0.403577 0.489517 0.772942 +vn 0.220649 0.765526 0.604358 +vn -0.306314 0.886288 -0.347270 +vn 0.535386 0.470168 -0.701590 +vn 0.551866 0.567919 -0.610614 +vn -0.839625 0.011322 -0.542985 +vn -0.890347 -0.317301 -0.326487 +vn 0.930357 0.306925 0.200476 +vn 0.580798 -0.759789 0.292154 +vn 0.793603 -0.439558 0.420637 +vn -0.814570 -0.473434 -0.335093 +vn 0.301920 -0.938414 -0.167913 +vn -0.406171 -0.822321 0.398480 +vn -0.031434 -0.466323 -0.884030 +vn -0.588031 0.129856 0.798334 +vn 0.710776 0.181555 -0.679556 +usemtl cat +s 1 +f 1768/1/1 1763/2/2 1777/3/3 +f 4/4/4 2/5/5 3/6/6 +f 5/7/7 3/6/6 2/5/5 +f 2/5/5 6/8/8 5/7/7 +f 7/9/9 5/7/7 6/8/8 +f 3/6/6 5/7/7 8/10/10 +f 11/11/11 9/12/12 10/13/13 +f 7/9/9 11/11/11 10/13/13 +f 10/13/13 12/14/14 7/9/9 +f 5/7/7 7/9/9 12/14/14 +f 12/14/14 13/15/15 5/7/7 +f 13/15/15 8/10/10 5/7/7 +f 8/10/10 13/15/15 14/16/16 +f 15/17/17 8/10/10 14/16/16 +f 14/16/16 16/18/18 15/17/17 +f 16/18/18 17/19/19 15/17/17 +f 19/20/20 18/21/21 13/15/15 +f 18/21/21 14/16/16 13/15/15 +f 14/16/16 18/21/21 20/22/22 +f 16/18/18 14/16/16 20/22/22 +f 20/22/22 21/23/23 16/18/18 +f 21/23/23 20/22/22 22/24/24 +f 22/24/24 23/25/25 21/23/23 +f 23/25/25 22/24/24 24/26/26 +f 24/26/26 25/27/27 23/25/25 +f 25/27/27 24/26/26 26/28/28 +f 27/29/29 20/22/22 18/21/21 +f 20/22/22 27/29/29 22/24/24 +f 27/29/29 28/30/30 29/31/31 +f 29/31/31 22/24/24 27/29/29 +f 22/24/24 29/31/31 24/26/26 +f 28/30/30 24/26/26 29/31/31 +f 24/26/26 28/30/30 26/28/28 +f 28/30/30 30/32/32 26/28/28 +f 30/32/32 28/30/30 31/33/33 +f 32/34/34 30/32/32 31/33/33 +f 33/35/35 32/34/34 31/33/33 +f 32/34/34 33/35/35 34/36/36 +f 35/37/37 31/33/33 28/30/30 +f 31/33/33 35/37/37 33/35/35 +f 36/38/38 33/35/35 35/37/37 +f 33/35/35 36/38/38 37/39/39 +f 36/38/38 38/40/40 37/39/39 +f 38/40/40 36/38/38 39/41/41 +f 41/42/42 45/43/43 40/44/44 +f 39/41/41 42/45/45 45/46/43 +f 42/45/45 39/41/41 36/38/38 +f 36/38/38 43/47/46 42/45/45 +f 43/47/46 36/38/38 35/37/37 +f 35/37/37 18/21/21 43/47/46 +f 18/21/21 35/37/37 28/30/30 +f 28/30/30 27/29/29 18/21/21 +f 44/48/47 45/46/43 42/45/45 +f 45/46/43 44/48/47 40/49/44 +f 46/50/48 40/49/44 44/48/47 +f 40/49/44 46/50/48 138/51/49 +f 46/50/48 47/52/50 138/51/49 +f 48/53/51 138/51/49 47/54/50 +f 49/55/52 43/47/46 18/21/21 +f 43/47/46 49/55/52 50/56/53 +f 50/56/53 42/45/45 43/47/46 +f 42/45/45 50/56/53 44/48/47 +f 51/57/54 44/48/47 50/56/53 +f 44/48/47 51/57/54 46/50/48 +f 51/57/54 52/58/55 46/50/48 +f 47/52/50 46/50/48 52/58/55 +f 52/58/55 54/59/56 47/52/50 +f 55/60/57 53/61/58 54/62/56 +f 53/61/58 55/60/57 150/63/59 +f 150/64/59 55/60/57 56/65/60 +f 54/62/56 56/65/60 55/60/57 +f 57/66/61 56/65/60 54/59/56 +f 54/59/56 52/58/55 57/66/61 +f 58/67/62 57/66/61 52/58/55 +f 52/58/55 51/57/54 58/67/62 +f 59/68/63 58/67/62 51/57/54 +f 50/56/53 59/68/63 51/57/54 +f 59/68/63 50/56/53 49/55/52 +f 61/69/64 60/70/65 56/65/60 +f 56/65/60 57/66/61 61/69/64 +f 62/71/66 61/69/64 57/66/61 +f 57/66/61 58/67/62 62/71/66 +f 63/72/67 62/71/66 58/67/62 +f 58/67/62 59/68/63 63/72/67 +f 64/73/68 63/72/67 59/68/63 +f 49/55/52 64/73/68 59/68/63 +f 64/73/68 49/55/52 19/20/20 +f 18/21/21 19/20/20 49/55/52 +f 13/15/15 12/14/14 19/20/20 +f 65/74/69 19/20/20 12/14/14 +f 19/20/20 65/74/69 64/73/68 +f 65/74/69 66/75/70 64/73/68 +f 63/72/67 64/73/68 66/75/70 +f 66/75/70 67/76/71 63/72/67 +f 62/71/66 63/72/67 67/76/71 +f 67/76/71 68/77/72 62/71/66 +f 61/69/64 62/71/66 68/77/72 +f 12/14/14 10/13/13 65/74/69 +f 10/13/13 69/78/73 65/74/69 +f 66/75/70 65/74/69 69/78/73 +f 69/78/73 70/79/74 66/75/70 +f 67/76/71 66/75/70 70/79/74 +f 71/80/75 67/76/71 70/79/74 +f 67/76/71 71/80/75 72/81/76 +f 70/79/74 73/82/77 71/80/75 +f 73/82/77 70/79/74 74/83/78 +f 70/79/74 69/78/73 74/83/78 +f 9/12/12 74/83/78 69/78/73 +f 69/78/73 10/13/13 9/12/12 +f 74/83/78 75/84/79 73/82/77 +f 78/85/80 76/86/81 77/87/82 +f 77/87/82 79/88/83 78/85/80 +f 79/88/83 77/87/82 75/84/79 +f 75/84/79 74/83/78 79/88/83 +f 80/89/84 79/88/83 74/83/78 +f 74/83/78 9/12/12 80/89/84 +f 80/89/84 81/90/85 82/91/86 +f 82/91/86 83/92/87 80/89/84 +f 79/88/83 80/89/84 83/92/87 +f 83/92/87 78/85/80 79/88/83 +f 83/92/87 82/91/86 84/93/88 +f 85/94/89 83/92/87 84/93/88 +f 81/90/85 84/93/88 82/91/86 +f 84/93/88 81/90/85 85/94/89 +f 81/90/85 86/95/90 85/94/89 +f 1092/96/91 85/94/89 86/95/90 +f 85/94/89 1092/96/91 1094/97/92 +f 83/92/87 85/94/89 1094/97/92 +f 1094/97/92 87/98/93 83/92/87 +f 78/85/80 83/92/87 87/98/93 +f 87/98/93 88/99/94 78/85/80 +f 76/86/81 78/85/80 88/99/94 +f 90/100/95 89/101/96 86/95/90 +f 91/102/97 86/95/90 89/101/96 +f 86/95/90 91/102/97 1092/96/91 +f 91/102/97 1093/103/98 1092/96/91 +f 90/100/95 92/104/99 93/105/100 +f 89/101/96 90/100/95 93/105/100 +f 92/104/99 89/101/96 93/105/100 +f 96/106/101 94/107/102 95/108/103 +f 1093/103/98 95/108/103 94/107/102 +f 95/108/103 1093/103/98 97/109/104 +f 1093/103/98 91/102/97 97/109/104 +f 91/102/97 98/110/105 97/109/104 +f 98/110/105 91/102/97 89/101/96 +f 99/111/106 98/110/105 89/101/96 +f 89/101/96 92/104/99 99/111/106 +f 100/112/107 99/111/106 92/104/99 +f 90/100/95 100/112/107 92/104/99 +f 102/113/108 100/112/107 101/114/109 +f 100/112/107 102/113/108 103/115/110 +f 99/111/106 100/112/107 103/115/110 +f 98/110/105 99/111/106 103/115/110 +f 106/116/111 104/117/112 105/118/113 +f 104/117/112 106/116/111 107/119/114 +f 96/106/101 104/117/112 107/119/114 +f 104/117/112 96/106/101 108/120/115 +f 95/108/103 108/120/115 96/106/101 +f 108/120/115 95/108/103 109/121/116 +f 97/109/104 109/121/116 95/108/103 +f 109/121/116 97/109/104 98/110/105 +f 98/110/105 110/122/117 109/121/116 +f 110/122/117 98/110/105 103/115/110 +f 110/122/117 111/123/118 112/124/119 +f 112/124/119 113/125/120 110/122/117 +f 113/125/120 109/121/116 110/122/117 +f 109/121/116 113/125/120 108/120/115 +f 113/125/120 112/124/119 114/126/121 +f 111/123/118 110/122/117 103/115/110 +f 102/113/108 111/123/118 103/115/110 +f 111/123/118 102/113/108 115/127/122 +f 115/127/122 112/124/119 111/123/118 +f 112/124/119 115/127/122 1089/128/123 +f 1089/128/123 114/126/121 112/124/119 +f 114/126/121 1089/128/123 1090/129/124 +f 116/130/125 114/126/121 1090/129/124 +f 113/125/120 104/117/112 108/120/115 +f 104/117/112 113/125/120 105/118/113 +f 114/126/121 105/118/113 113/125/120 +f 105/118/113 114/126/121 106/116/111 +f 114/126/121 116/130/125 106/116/111 +f 116/130/125 107/119/114 106/116/111 +f 107/119/114 116/130/125 117/131/126 +f 117/131/126 96/106/101 107/119/114 +f 96/106/101 117/131/126 1091/132/127 +f 94/107/102 96/106/101 1091/132/127 +f 118/133/128 1612/134/129 123/135/130 +f 120/136/131 1612/134/129 119/136/132 +f 121/137/133 123/135/130 1612/138/129 +f 123/135/130 121/137/133 122/139/134 +f 125/140/135 124/141/136 118/133/128 +f 1612/134/129 118/133/128 124/141/136 +f 126/142/137 1612/134/129 124/141/136 +f 1612/134/129 126/142/137 119/136/132 +f 126/142/137 129/143/138 119/136/132 +f 129/143/138 120/136/131 119/136/132 +f 128/144/139 131/145/140 127/146/141 +f 131/145/140 128/144/139 129/147/138 +f 129/143/138 130/148/142 131/145/140 +f 130/148/142 129/143/138 132/149/143 +f 129/143/138 126/142/137 132/149/143 +f 133/150/144 132/149/143 126/142/137 +f 124/141/136 133/150/144 126/142/137 +f 133/150/144 124/141/136 41/42/42 +f 131/145/140 134/151/145 135/152/146 +f 134/151/145 131/145/140 130/148/142 +f 130/148/142 136/153/147 134/151/145 +f 136/153/147 130/148/142 137/154/148 +f 132/149/143 137/154/148 130/148/142 +f 137/154/148 132/149/143 48/53/51 +f 132/149/143 133/150/144 48/53/51 +f 138/51/49 48/53/51 133/150/144 +f 41/42/42 138/51/49 133/150/144 +f 138/51/49 41/42/42 40/44/44 +f 137/154/148 139/155/149 136/153/147 +f 139/155/149 137/154/148 140/156/150 +f 48/53/51 140/156/150 137/154/148 +f 54/62/56 48/53/51 47/54/50 +f 48/53/51 54/62/56 53/61/58 +f 140/156/150 48/53/51 53/61/58 +f 150/63/59 140/156/150 53/61/58 +f 140/156/150 150/63/59 141/157/151 +f 150/64/59 127/146/141 141/158/151 +f 127/146/141 150/64/59 128/144/139 +f 140/156/150 143/159/152 139/155/149 +f 143/159/152 140/156/150 141/157/151 +f 141/158/151 142/160/153 143/161/152 +f 142/160/153 141/158/151 127/146/141 +f 127/146/141 135/162/146 142/160/153 +f 135/162/146 127/146/141 131/145/140 +f 146/163/154 144/164/155 145/165/156 +f 144/164/155 120/136/131 145/165/156 +f 120/136/131 147/166/157 145/165/156 +f 147/166/157 120/136/131 129/147/138 +f 129/147/138 148/167/158 147/166/157 +f 148/167/158 129/147/138 128/144/139 +f 128/144/139 149/168/159 148/167/158 +f 149/168/159 128/144/139 150/64/59 +f 150/64/59 60/70/65 149/168/159 +f 60/70/65 150/64/59 56/65/60 +f 60/70/65 61/69/64 151/169/160 +f 151/169/160 149/168/159 60/70/65 +f 149/168/159 151/169/160 152/170/161 +f 152/170/161 148/167/158 149/168/159 +f 148/167/158 152/170/161 153/171/162 +f 153/171/162 147/166/157 148/167/158 +f 147/166/157 153/171/162 154/172/163 +f 154/172/163 145/165/156 147/166/157 +f 145/165/156 154/172/163 146/163/154 +f 155/173/164 146/163/154 154/172/163 +f 154/172/163 156/174/165 155/173/164 +f 157/175/166 155/173/164 156/174/165 +f 156/174/165 154/172/163 153/171/162 +f 159/176/167 156/174/165 158/177/168 +f 156/174/165 159/176/167 157/175/166 +f 160/178/169 157/175/166 159/176/167 +f 157/175/166 160/178/169 161/179/170 +f 162/180/171 157/175/166 161/179/170 +f 157/175/166 162/180/171 163/181/172 +f 155/173/164 157/175/166 163/181/172 +f 163/181/172 164/182/173 155/173/164 +f 146/163/154 155/173/164 164/182/173 +f 144/164/155 146/163/154 164/182/173 +f 161/179/170 165/183/174 162/180/171 +f 166/184/175 162/180/171 165/183/174 +f 162/180/171 166/184/175 167/185/176 +f 167/185/176 163/181/172 162/180/171 +f 163/181/172 167/185/176 168/186/177 +f 164/182/173 163/181/172 168/186/177 +f 169/187/178 164/182/173 168/186/177 +f 164/182/173 169/187/178 144/164/155 +f 169/187/178 170/188/179 144/164/155 +f 171/189/180 144/164/155 170/188/179 +f 168/186/177 270/190/181 169/187/178 +f 270/190/181 168/186/177 167/185/176 +f 270/190/181 172/191/182 169/187/178 +f 172/191/182 270/190/181 173/192/183 +f 269/193/184 173/192/183 270/190/181 +f 175/194/185 174/195/186 173/192/183 +f 176/196/187 173/192/183 174/195/186 +f 173/192/183 176/196/187 172/191/182 +f 176/196/187 170/188/179 172/191/182 +f 170/188/179 169/187/178 172/191/182 +f 173/192/183 269/193/184 175/194/185 +f 269/193/184 1898/197/188 175/194/185 +f 1898/197/188 269/193/184 1895/198/189 +f 269/193/184 177/199/190 1895/198/189 +f 170/188/179 176/196/187 178/200/191 +f 179/201/192 178/200/191 176/196/187 +f 174/195/186 179/201/192 176/196/187 +f 179/201/192 174/195/186 180/202/193 +f 181/203/194 180/202/193 174/195/186 +f 180/202/193 181/203/194 182/204/195 +f 183/205/196 180/202/193 182/204/195 +f 180/202/193 183/205/196 184/206/197 +f 185/207/198 184/206/197 183/205/196 +f 184/206/197 185/207/198 186/208/199 +f 184/206/197 179/201/192 180/202/193 +f 1944/209/200 187/210/201 185/207/198 +f 185/207/198 1942/211/202 1944/209/200 +f 1942/211/202 185/207/198 183/205/196 +f 183/205/196 188/212/203 1942/211/202 +f 188/212/203 183/205/196 182/204/195 +f 182/204/195 189/213/204 188/212/203 +f 189/213/204 182/204/195 181/203/194 +f 181/203/194 1898/197/188 189/213/204 +f 1898/197/188 181/203/194 175/194/185 +f 174/195/186 175/194/185 181/203/194 +f 187/210/201 186/208/199 185/207/198 +f 186/208/199 187/210/201 190/214/205 +f 191/215/206 190/214/205 187/210/201 +f 190/214/205 191/215/206 192/216/207 +f 193/217/208 192/216/207 191/215/206 +f 192/216/207 193/217/208 194/218/209 +f 195/219/210 194/218/209 193/217/208 +f 194/218/209 195/219/210 196/220/211 +f 197/221/212 196/220/211 195/219/210 +f 198/222/213 190/214/205 192/216/207 +f 194/218/209 198/222/213 192/216/207 +f 200/223/214 199/224/215 198/222/213 +f 198/222/213 194/218/209 200/223/214 +f 196/220/211 200/223/214 194/218/209 +f 1894/225/216 197/221/212 1914/226/217 +f 195/219/210 1914/226/217 197/221/212 +f 1914/226/217 195/219/210 1918/227/218 +f 193/217/208 1918/227/218 195/219/210 +f 1918/227/218 193/217/208 1926/228/219 +f 191/215/206 1926/228/219 193/217/208 +f 1926/228/219 191/215/206 1920/229/220 +f 187/210/201 1920/229/220 191/215/206 +f 1920/229/220 187/210/201 201/230/221 +f 187/210/201 1944/209/200 201/230/221 +f 204/231/222 202/232/223 203/233/224 +f 205/234/225 203/233/224 202/232/223 +f 202/232/223 206/235/226 205/234/225 +f 1891/236/227 205/234/225 206/235/226 +f 206/235/226 1894/225/216 1891/236/227 +f 1894/225/216 206/235/226 207/237/228 +f 197/221/212 1894/225/216 207/237/228 +f 207/237/228 208/238/229 197/221/212 +f 196/220/211 197/221/212 208/238/229 +f 208/238/229 209/239/230 196/220/211 +f 208/238/229 207/237/228 237/240/231 +f 237/240/231 210/241/232 211/242/233 +f 237/240/231 212/243/234 208/238/229 +f 209/239/230 208/238/229 212/243/234 +f 212/243/234 213/244/235 209/239/230 +f 214/245/236 209/239/230 213/244/235 +f 213/244/235 215/246/237 214/245/236 +f 215/246/237 213/244/235 216/247/238 +f 216/247/238 217/248/239 215/246/237 +f 220/249/240 218/250/241 219/251/242 +f 217/248/239 220/249/240 219/251/242 +f 220/249/240 217/248/239 221/252/243 +f 217/248/239 216/247/238 221/252/243 +f 222/253/244 221/252/243 216/247/238 +f 213/244/235 222/253/244 216/247/238 +f 222/253/244 213/244/235 223/254/245 +f 213/244/235 212/243/234 223/254/245 +f 211/242/233 223/254/245 212/243/234 +f 212/243/234 237/240/231 211/242/233 +f 218/250/241 224/255/246 225/256/247 +f 224/255/246 218/250/241 226/257/248 +f 218/250/241 220/249/240 226/257/248 +f 227/258/249 226/257/248 220/249/240 +f 221/252/243 227/258/249 220/249/240 +f 227/258/249 221/252/243 228/259/250 +f 221/252/243 222/253/244 228/259/250 +f 229/260/251 228/259/250 222/253/244 +f 223/254/245 229/260/251 222/253/244 +f 229/260/251 223/254/245 230/261/252 +f 231/262/253 229/260/251 230/261/252 +f 229/260/251 231/262/253 232/263/254 +f 233/264/255 229/260/251 232/263/254 +f 223/254/245 211/242/233 230/261/252 +f 211/242/233 231/262/253 230/261/252 +f 231/262/253 211/242/233 210/241/232 +f 210/241/232 234/265/256 231/262/253 +f 234/265/256 232/263/254 231/262/253 +f 232/263/254 234/265/256 224/255/246 +f 226/257/248 232/263/254 224/255/246 +f 232/263/254 226/257/248 233/264/255 +f 226/257/248 227/258/249 233/264/255 +f 229/260/251 233/264/255 227/258/249 +f 228/259/250 229/260/251 227/258/249 +f 236/266/257 235/267/258 202/232/223 +f 206/235/226 202/232/223 235/267/258 +f 235/267/258 207/237/228 206/235/226 +f 207/237/228 235/267/258 237/240/231 +f 210/241/232 237/240/231 235/267/258 +f 235/267/258 236/266/257 210/241/232 +f 234/265/256 210/241/232 236/266/257 +f 236/266/257 238/268/259 234/265/256 +f 225/256/247 234/265/256 238/268/259 +f 234/265/256 225/256/247 224/255/246 +f 219/251/242 239/269/260 240/270/261 +f 239/269/260 219/251/242 218/250/241 +f 241/271/262 239/269/260 218/250/241 +f 218/250/241 242/272/263 241/271/262 +f 242/272/263 218/250/241 225/256/247 +f 225/256/247 243/273/264 242/272/263 +f 243/273/264 225/256/247 238/268/259 +f 204/231/222 243/273/264 238/268/259 +f 238/268/259 236/266/257 204/231/222 +f 202/232/223 204/231/222 236/266/257 +f 245/274/265 244/275/266 239/269/260 +f 239/269/260 241/271/262 245/274/265 +f 246/276/267 245/274/265 241/271/262 +f 242/272/263 246/276/267 241/271/262 +f 246/276/267 242/272/263 247/277/268 +f 242/272/263 248/278/269 247/277/268 +f 248/278/269 242/272/263 243/273/264 +f 249/279/270 248/278/269 243/273/264 +f 243/273/264 204/231/222 249/279/270 +f 203/233/224 249/279/270 204/231/222 +f 203/233/224 205/234/225 250/280/271 +f 250/280/271 251/281/272 203/233/224 +f 249/279/270 203/233/224 251/281/272 +f 205/234/225 1891/236/227 252/282/273 +f 252/282/273 250/280/271 205/234/225 +f 250/280/271 252/282/273 1888/283/274 +f 1888/283/274 253/284/275 250/280/271 +f 251/281/272 250/280/271 253/284/275 +f 253/284/275 254/285/276 251/281/272 +f 254/285/276 249/279/270 251/281/272 +f 249/279/270 254/285/276 255/286/277 +f 248/278/269 249/279/270 255/286/277 +f 254/285/276 253/284/275 256/287/278 +f 253/284/275 1888/283/274 1869/288/279 +f 1869/288/279 256/287/278 253/284/275 +f 256/287/278 1869/288/279 1880/289/280 +f 257/290/281 256/287/278 1880/289/280 +f 259/291/282 247/277/268 258/292/283 +f 248/278/269 258/292/283 247/277/268 +f 258/292/283 248/278/269 260/293/284 +f 255/286/277 260/293/284 248/278/269 +f 260/293/284 255/286/277 261/294/285 +f 254/285/276 261/294/285 255/286/277 +f 261/294/285 254/285/276 262/295/286 +f 256/287/278 262/295/286 254/285/276 +f 262/295/286 256/287/278 263/296/287 +f 256/287/278 257/290/281 263/296/287 +f 264/297/288 260/293/284 158/177/168 +f 261/294/285 158/177/168 260/293/284 +f 158/177/168 261/294/285 159/176/167 +f 262/295/286 159/176/167 261/294/285 +f 159/176/167 262/295/286 160/178/169 +f 263/296/287 160/178/169 262/295/286 +f 160/178/169 263/296/287 265/298/289 +f 265/298/289 161/179/170 160/178/169 +f 161/179/170 265/298/289 266/299/290 +f 165/183/174 161/179/170 266/299/290 +f 267/300/291 263/296/287 257/290/281 +f 263/296/287 267/300/291 265/298/289 +f 268/301/292 265/298/289 267/300/291 +f 265/298/289 268/301/292 266/299/290 +f 1912/302/293 266/299/290 268/301/292 +f 266/299/290 1912/302/293 165/183/174 +f 177/199/190 165/183/174 1912/302/293 +f 165/183/174 177/199/190 166/184/175 +f 177/199/190 269/193/184 166/184/175 +f 269/193/184 167/185/176 166/184/175 +f 167/185/176 269/193/184 270/190/181 +f 273/303/294 271/304/295 272/305/296 +f 272/305/296 274/306/297 273/303/294 +f 274/306/297 272/305/296 275/307/298 +f 275/307/298 276/308/299 274/306/297 +f 276/308/299 275/307/298 277/309/300 +f 277/309/300 278/310/301 276/308/299 +f 278/310/301 277/309/300 279/311/302 +f 280/312/303 278/310/301 279/311/302 +f 278/310/301 280/312/303 281/313/304 +f 280/312/303 282/314/305 281/313/304 +f 282/314/305 280/312/303 283/315/306 +f 283/315/306 284/316/307 282/314/305 +f 284/316/307 283/315/306 285/317/308 +f 285/317/308 286/318/309 284/316/307 +f 286/318/309 285/317/308 287/319/310 +f 287/319/310 288/320/311 286/318/309 +f 288/320/311 287/319/310 289/321/312 +f 289/321/312 290/322/313 288/320/311 +f 290/322/313 289/321/312 271/304/295 +f 271/304/295 273/303/294 290/322/313 +f 293/323/314 291/324/315 292/325/316 +f 291/324/315 293/323/314 294/326/317 +f 297/327/318 295/328/319 296/329/320 +f 298/330/321 297/327/318 296/329/320 +f 297/327/318 298/330/321 293/323/314 +f 299/331/322 293/323/314 298/330/321 +f 293/323/314 299/331/322 294/326/317 +f 299/331/322 300/332/323 294/326/317 +f 301/333/324 294/326/317 300/332/323 +f 294/326/317 301/333/324 291/324/315 +f 302/334/325 291/324/315 301/333/324 +f 291/324/315 302/334/325 303/335/326 +f 296/329/320 299/331/322 298/330/321 +f 300/332/323 299/331/322 304/336/327 +f 304/336/327 1784/337/328 300/332/323 +f 1801/338/329 300/332/323 1784/337/328 +f 300/332/323 1801/338/329 301/333/324 +f 1800/339/330 301/333/324 1801/338/329 +f 301/333/324 1800/339/330 302/334/325 +f 305/340/331 302/334/325 1800/339/330 +f 302/334/325 305/340/331 306/341/332 +f 1799/342/333 306/341/332 305/340/331 +f 306/341/332 1799/342/333 307/343/334 +f 306/341/332 303/335/326 302/334/325 +f 303/335/326 306/341/332 308/344/335 +f 307/343/334 308/344/335 306/341/332 +f 308/344/335 307/343/334 309/345/336 +f 310/346/337 309/345/336 307/343/334 +f 309/345/336 310/346/337 311/347/338 +f 312/348/339 311/347/338 310/346/337 +f 311/347/338 312/348/339 313/349/340 +f 314/350/341 313/349/340 312/348/339 +f 313/349/340 314/350/341 315/351/342 +f 316/352/343 315/351/342 314/350/341 +f 315/351/342 316/352/343 317/353/344 +f 304/336/327 317/353/344 316/352/343 +f 315/351/342 318/354/345 313/349/340 +f 318/354/345 311/347/338 313/349/340 +f 311/347/338 318/354/345 319/355/346 +f 311/347/338 320/356/347 309/345/336 +f 320/356/347 311/347/338 319/355/346 +f 319/355/346 297/327/318 320/356/347 +f 297/327/318 319/355/346 318/354/345 +f 295/328/319 297/327/318 318/354/345 +f 318/354/345 315/351/342 295/328/319 +f 315/351/342 296/329/320 295/328/319 +f 296/329/320 315/351/342 317/353/344 +f 299/331/322 296/329/320 317/353/344 +f 317/353/344 304/336/327 299/331/322 +f 320/356/347 308/344/335 309/345/336 +f 292/325/316 297/327/318 293/323/314 +f 297/327/318 292/325/316 321/357/348 +f 291/324/315 321/357/348 292/325/316 +f 321/357/348 291/324/315 303/335/326 +f 308/344/335 321/357/348 303/335/326 +f 321/357/348 308/344/335 322/358/349 +f 308/344/335 320/356/347 322/358/349 +f 297/327/318 322/358/349 320/356/347 +f 322/358/349 297/327/318 321/357/348 +f 1792/359/350 307/343/334 1799/342/333 +f 307/343/334 1792/359/350 310/346/337 +f 1790/360/351 310/346/337 1792/359/350 +f 310/346/337 1790/360/351 312/348/339 +f 1789/361/352 312/348/339 1790/360/351 +f 312/348/339 1789/361/352 314/350/341 +f 1787/362/353 314/350/341 1789/361/352 +f 314/350/341 1787/362/353 316/352/343 +f 323/363/354 316/352/343 1787/362/353 +f 316/352/343 323/363/354 304/336/327 +f 1784/337/328 304/336/327 323/363/354 +f 326/364/355 324/365/356 325/366/357 +f 324/365/356 326/364/355 327/367/358 +f 328/368/359 324/365/356 327/367/358 +f 324/365/356 328/368/359 329/369/360 +f 330/370/361 324/365/356 329/369/360 +f 324/365/356 330/370/361 331/371/362 +f 332/372/363 324/365/356 331/371/362 +f 324/365/356 333/373/364 325/366/357 +f 333/373/364 324/365/356 334/374/365 +f 324/365/356 332/372/363 334/374/365 +f 332/372/363 372/375/366 334/374/365 +f 372/375/366 332/372/363 371/376/367 +f 331/371/362 371/376/367 332/372/363 +f 371/376/367 331/371/362 335/377/368 +f 330/370/361 335/377/368 331/371/362 +f 335/377/368 330/370/361 336/378/369 +f 329/369/360 336/378/369 330/370/361 +f 336/378/369 329/369/360 343/379/370 +f 328/368/359 343/379/370 329/369/360 +f 343/379/370 328/368/359 340/380/371 +f 327/367/358 340/380/371 328/368/359 +f 340/380/371 327/367/358 339/381/372 +f 326/364/355 339/381/372 327/367/358 +f 339/381/372 326/364/355 375/382/373 +f 325/366/357 375/382/373 326/364/355 +f 375/382/373 325/366/357 374/383/374 +f 333/373/364 374/383/374 325/366/357 +f 374/383/374 333/373/364 373/384/375 +f 334/374/365 373/384/375 333/373/364 +f 373/384/375 334/374/365 372/375/366 +f 338/336/376 339/337/372 337/332/377 +f 339/337/372 338/336/376 340/363/371 +f 341/352/378 340/363/371 338/336/376 +f 340/363/371 341/352/378 343/362/370 +f 342/350/379 343/362/370 341/352/378 +f 343/362/370 342/350/379 336/361/369 +f 344/348/380 336/361/369 342/350/379 +f 336/361/369 344/348/380 335/360/368 +f 345/346/381 335/360/368 344/348/380 +f 335/360/368 345/346/381 371/359/367 +f 345/346/381 346/345/382 347/343/383 +f 346/345/382 345/346/381 348/347/384 +f 344/348/380 348/347/384 345/346/381 +f 348/347/384 344/348/380 349/349/385 +f 342/350/379 349/349/385 344/348/380 +f 349/349/385 342/350/379 350/351/386 +f 341/352/378 350/351/386 342/350/379 +f 350/351/386 341/352/378 351/353/387 +f 338/336/376 351/353/387 341/352/378 +f 351/353/387 338/336/376 352/331/388 +f 353/354/389 348/347/384 349/349/385 +f 350/351/386 353/354/389 349/349/385 +f 353/354/389 350/351/386 354/328/390 +f 356/356/391 355/344/392 346/345/382 +f 348/347/384 356/356/391 346/345/382 +f 356/356/391 348/347/384 357/355/393 +f 348/347/384 353/354/389 357/355/393 +f 358/327/394 357/355/393 353/354/389 +f 354/328/390 358/327/394 353/354/389 +f 358/327/394 354/328/390 359/329/395 +f 350/351/386 359/329/395 354/328/390 +f 359/329/395 350/351/386 351/353/387 +f 352/331/388 359/329/395 351/353/387 +f 360/330/396 358/327/394 359/329/395 +f 359/329/395 352/331/388 360/330/396 +f 352/331/388 361/323/397 360/330/396 +f 358/327/394 360/330/396 361/323/397 +f 362/325/398 358/327/394 361/323/397 +f 358/327/394 362/325/398 363/357/399 +f 364/324/400 363/357/399 362/325/398 +f 363/357/399 364/324/400 365/335/401 +f 355/344/392 363/357/399 365/335/401 +f 363/357/399 355/344/392 366/358/402 +f 355/344/392 356/356/391 366/358/402 +f 358/327/394 366/358/402 356/356/391 +f 357/355/393 358/327/394 356/356/391 +f 366/358/402 358/327/394 363/357/399 +f 361/323/397 352/331/388 367/326/403 +f 364/324/400 361/323/397 367/326/403 +f 361/323/397 364/324/400 362/325/398 +f 337/332/377 352/331/388 338/336/376 +f 352/331/388 337/332/377 367/326/403 +f 368/333/404 367/326/403 337/332/377 +f 367/326/403 368/333/404 364/324/400 +f 369/334/405 364/324/400 368/333/404 +f 364/324/400 369/334/405 365/335/401 +f 370/341/406 365/335/401 369/334/405 +f 365/335/401 370/341/406 355/344/392 +f 347/343/383 355/344/392 370/341/406 +f 355/344/392 347/343/383 346/345/382 +f 347/343/383 371/359/367 345/346/381 +f 371/359/367 347/343/383 372/342/366 +f 370/341/406 372/342/366 347/343/383 +f 372/342/366 370/341/406 373/340/375 +f 369/334/405 373/340/375 370/341/406 +f 373/340/375 369/334/405 374/339/374 +f 368/333/404 374/339/374 369/334/405 +f 374/339/374 368/333/404 375/338/373 +f 337/332/377 375/338/373 368/333/404 +f 375/338/373 337/332/377 339/337/372 +f 378/385/407 376/386/408 377/387/409 +f 379/388/410 377/387/409 376/386/408 +f 377/387/409 379/388/410 380/389/411 +f 381/390/412 380/389/411 379/388/410 +f 380/389/411 381/390/412 382/391/413 +f 385/392/414 383/393/415 384/393/416 +f 386/394/417 384/393/416 383/393/415 +f 384/393/416 386/394/417 387/395/418 +f 388/396/419 387/395/418 386/394/417 +f 387/395/418 388/396/419 389/397/420 +f 392/398/421 390/399/422 391/399/423 +f 393/400/424 391/399/423 390/399/422 +f 391/399/423 393/400/424 394/401/425 +f 395/402/426 394/401/425 393/400/424 +f 394/401/425 395/402/426 396/403/427 +f 399/392/428 397/393/429 398/393/430 +f 400/394/431 398/393/430 397/393/429 +f 398/393/430 400/394/431 401/395/432 +f 402/396/433 401/395/432 400/394/431 +f 401/395/432 402/396/433 403/397/434 +f 406/404/435 404/405/436 405/406/437 +f 407/407/438 405/406/437 404/405/436 +f 405/406/437 407/407/438 408/408/439 +f 411/409/440 409/410/441 410/411/442 +f 412/412/443 410/411/442 409/410/441 +f 410/411/442 412/412/443 413/413/444 +f 416/414/445 414/415/446 415/399/447 +f 417/416/448 415/399/447 414/415/446 +f 415/399/447 417/416/448 418/417/449 +f 419/418/450 418/417/449 417/416/448 +f 418/417/449 419/418/450 420/419/451 +f 423/393/452 421/394/453 422/395/454 +f 424/396/455 422/395/454 421/394/453 +f 422/395/454 424/396/455 425/397/456 +f 428/420/457 426/421/458 427/421/459 +f 429/422/460 427/421/459 426/421/458 +f 427/421/459 429/422/460 430/423/461 +f 431/424/462 430/423/461 429/422/460 +f 430/423/461 431/424/462 432/425/463 +f 433/426/464 432/425/463 431/424/462 +f 432/425/463 433/426/464 434/427/465 +f 437/428/466 435/429/467 436/430/468 +f 435/429/467 437/428/466 438/431/469 +f 438/431/469 439/432/470 435/429/467 +f 439/432/470 438/431/469 440/433/471 +f 440/433/471 441/434/472 439/432/470 +f 443/435/473 2020/436/474 442/437/475 +f 2020/436/474 443/435/473 2094/438/476 +f 2094/438/476 2021/439/477 2020/436/474 +f 2021/439/477 2094/438/476 2243/440/478 +f 444/441/479 2051/442/480 2062/443/481 +f 447/444/482 445/445/483 446/446/484 +f 445/445/483 447/444/482 448/447/485 +f 448/447/485 449/448/486 445/445/483 +f 449/448/486 448/447/485 450/449/487 +f 450/449/487 451/450/488 449/448/486 +f 2051/442/480 444/441/479 452/451/489 +f 455/452/490 453/453/491 454/454/492 +f 453/453/491 455/452/490 456/455/493 +f 456/455/493 457/456/494 453/453/491 +f 457/456/494 456/455/493 458/457/495 +f 458/457/495 459/458/496 457/456/494 +f 2062/443/481 2050/459/497 2048/460/498 +f 462/461/499 460/462/500 461/463/501 +f 460/462/500 462/461/499 463/464/502 +f 463/464/502 464/465/503 460/462/500 +f 2050/459/497 2062/443/481 2051/442/480 +f 467/466/504 465/467/505 466/468/506 +f 465/467/505 467/466/504 468/469/507 +f 468/469/507 469/470/508 465/467/505 +f 2048/460/498 2003/471/509 2060/472/510 +f 472/473/511 470/474/512 471/475/513 +f 470/474/512 472/473/511 473/476/514 +f 473/476/514 474/477/515 470/474/512 +f 474/477/515 473/476/514 475/478/516 +f 475/478/516 476/479/517 474/477/515 +f 479/480/518 477/481/519 478/482/520 +f 477/481/519 479/480/518 480/483/521 +f 480/483/521 481/484/522 477/481/519 +f 2003/471/509 2048/460/498 2050/459/497 +f 484/485/523 482/486/524 483/487/525 +f 482/486/524 484/485/523 485/488/526 +f 485/488/526 486/489/527 482/486/524 +f 486/489/527 485/488/526 487/490/528 +f 487/490/528 488/491/529 486/489/527 +f 488/491/529 487/490/528 489/492/530 +f 489/492/530 490/493/531 488/491/529 +f 493/494/532 491/495/533 492/496/534 +f 491/495/533 493/494/532 494/497/535 +f 494/497/535 495/498/536 491/495/533 +f 495/498/536 494/497/535 496/499/537 +f 496/499/537 497/500/538 495/498/536 +f 2129/501/539 2006/502/540 2113/503/541 +f 2006/502/540 2129/501/539 2007/504/542 +f 498/505/543 2008/506/544 2143/507/545 +f 2008/506/544 498/505/543 2009/508/546 +f 2180/509/547 2012/510/548 2162/503/549 +f 2012/510/548 2180/509/547 2013/511/550 +f 2079/512/551 2245/513/552 2014/514/553 +f 2245/513/552 2079/512/551 2246/515/554 +f 2207/516/555 2017/517/556 2193/518/557 +f 2017/517/556 2207/516/555 499/519/558 +f 2096/520/559 2022/521/560 500/522/561 +f 2022/521/560 2096/520/559 2095/523/562 +f 2099/524/563 2026/525/564 2025/526/565 +f 2026/525/564 2099/524/563 2098/527/566 +f 2100/528/567 501/529/568 502/530/569 +f 501/529/568 2100/528/567 2240/531/570 +f 2083/532/571 2239/533/572 503/534/573 +f 2239/533/572 2083/532/571 504/535/574 +f 2084/536/575 505/537/576 2238/538/577 +f 505/537/576 2084/536/575 2083/539/571 +f 506/540/578 2031/541/579 2236/542/580 +f 2031/541/579 506/540/578 507/543/581 +f 2212/544/582 508/545/583 2232/546/584 +f 508/545/583 2212/544/582 509/547/585 +f 510/548/586 509/547/585 2212/544/582 +f 509/547/585 510/548/586 511/549/587 +f 514/550/588 512/551/589 513/552/590 +f 512/551/589 514/550/588 515/553/591 +f 516/554/592 515/553/591 514/550/588 +f 515/553/591 516/554/592 517/555/593 +f 518/556/594 517/555/593 516/554/592 +f 517/555/593 518/556/594 519/557/595 +f 520/558/596 517/555/593 519/557/595 +f 517/555/593 520/558/596 521/559/597 +f 521/559/597 515/553/591 517/555/593 +f 515/553/591 521/559/597 522/560/598 +f 522/560/598 512/551/589 515/553/591 +f 512/551/589 522/560/598 523/561/599 +f 1880/562/280 524/563/600 257/564/281 +f 525/565/601 529/566/602 526/567/603 +f 529/566/602 525/565/601 530/568/604 +f 528/569/605 526/570/603 1755/571/606 +f 526/570/603 528/569/605 525/572/601 +f 527/573/607 1755/571/606 1756/574/608 +f 1755/571/606 527/573/607 528/569/605 +f 530/568/604 1756/574/608 529/566/602 +f 1756/574/608 530/568/604 527/573/607 +f 532/571/609 531/566/610 536/574/611 +f 531/566/610 532/571/609 534/570/612 +f 533/565/613 531/566/610 534/567/612 +f 531/566/610 533/565/613 537/568/614 +f 535/569/615 534/570/612 532/571/609 +f 534/570/612 535/569/615 533/572/613 +f 538/573/616 532/571/609 536/574/611 +f 532/571/609 538/573/616 535/569/615 +f 537/568/614 536/574/611 531/566/610 +f 536/574/611 537/568/614 538/573/616 +f 539/571/617 541/566/618 544/574/619 +f 541/566/618 539/571/617 540/570/620 +f 543/565/621 541/566/618 540/567/620 +f 541/566/618 543/565/621 545/568/622 +f 542/569/623 540/570/620 539/571/617 +f 540/570/620 542/569/623 543/572/621 +f 546/573/624 539/571/617 544/574/619 +f 539/571/617 546/573/624 542/569/623 +f 545/568/622 544/574/619 541/566/618 +f 544/574/619 545/568/622 546/573/624 +f 1041/575/625 547/576/626 1039/577/627 +f 547/576/626 1037/578/628 1039/577/627 +f 1037/578/628 547/576/626 548/579/629 +f 1043/580/630 549/581/631 1044/582/632 +f 549/581/631 1042/583/633 1044/582/632 +f 1042/583/633 549/581/631 548/579/629 +f 548/579/629 550/584/634 1042/583/633 +f 550/584/634 548/579/629 547/576/626 +f 551/585/635 550/584/634 547/576/626 +f 547/576/626 1041/575/625 551/585/635 +f 1041/575/625 552/586/636 551/585/635 +f 550/584/634 551/585/635 552/586/636 +f 554/587/637 553/588/638 548/579/629 +f 548/579/629 555/589/639 554/587/637 +f 555/589/639 548/579/629 549/581/631 +f 549/581/631 556/590/640 555/589/639 +f 556/590/640 554/587/637 555/589/639 +f 554/587/637 556/590/640 557/591/641 +f 560/592/642 558/593/643 559/594/644 +f 558/593/643 560/592/642 561/595/645 +f 562/596/646 561/595/645 560/592/642 +f 561/595/645 562/596/646 563/597/647 +f 562/596/646 553/588/638 563/597/647 +f 564/598/648 563/597/647 553/588/638 +f 553/588/638 554/587/637 564/598/648 +f 554/587/637 565/599/649 564/598/648 +f 565/599/649 554/587/637 557/591/641 +f 557/591/641 566/600/650 565/599/649 +f 567/601/651 561/595/645 563/597/647 +f 563/597/647 564/598/648 567/601/651 +f 564/598/648 568/602/652 567/601/651 +f 568/602/652 564/598/648 565/599/649 +f 565/599/649 569/603/653 568/602/652 +f 569/603/653 565/599/649 566/600/650 +f 561/595/645 567/601/651 570/604/654 +f 567/601/651 571/605/655 570/604/654 +f 571/605/655 567/601/651 568/602/652 +f 568/602/652 572/606/656 571/605/655 +f 572/606/656 568/602/652 569/603/653 +f 573/607/657 572/606/656 569/603/653 +f 566/600/650 573/607/657 569/603/653 +f 573/607/657 566/600/650 574/608/658 +f 574/608/658 575/609/659 573/607/657 +f 575/609/659 574/608/658 576/610/660 +f 577/611/661 570/604/654 571/605/655 +f 571/605/655 578/612/662 577/611/661 +f 578/612/662 571/605/655 572/606/656 +f 579/613/663 578/612/662 572/606/656 +f 572/606/656 573/607/657 579/613/663 +f 575/609/659 579/613/663 573/607/657 +f 579/613/663 575/609/659 580/614/664 +f 581/615/665 580/614/664 575/609/659 +f 580/614/664 581/615/665 582/616/666 +f 583/617/667 582/616/666 581/615/665 +f 586/618/668 584/619/669 585/620/670 +f 585/620/670 583/617/667 586/618/668 +f 581/615/665 586/618/668 583/617/667 +f 583/617/667 585/620/670 587/621/671 +f 576/610/660 581/615/665 575/609/659 +f 581/615/665 576/610/660 588/622/672 +f 586/618/668 581/615/665 588/622/672 +f 588/622/672 589/623/673 586/618/668 +f 584/619/669 586/618/668 589/623/673 +f 589/623/673 590/624/674 584/619/669 +f 591/625/675 584/619/669 590/624/674 +f 584/619/669 591/625/675 592/626/676 +f 592/626/676 585/620/670 584/619/669 +f 585/620/670 592/626/676 593/627/677 +f 594/628/678 764/629/679 590/624/674 +f 1710/630/680 590/624/674 764/629/679 +f 590/624/674 1710/630/680 591/625/675 +f 1710/630/680 595/631/681 591/625/675 +f 595/631/681 592/626/676 591/625/675 +f 592/626/676 595/631/681 596/632/682 +f 597/633/683 592/626/676 596/632/682 +f 596/632/682 598/634/684 597/633/683 +f 599/635/685 597/633/683 598/634/684 +f 600/636/686 599/635/685 598/634/684 +f 592/626/676 597/633/683 593/627/677 +f 597/633/683 601/637/687 593/627/677 +f 601/637/687 597/633/683 602/638/688 +f 597/633/683 599/635/685 602/638/688 +f 595/631/681 1710/630/680 603/639/689 +f 1711/640/690 595/631/681 603/639/689 +f 595/631/681 1711/640/690 604/641/691 +f 604/641/691 596/632/682 595/631/681 +f 596/632/682 604/641/691 605/642/692 +f 598/634/684 596/632/682 605/642/692 +f 606/643/693 598/634/684 605/642/692 +f 598/634/684 606/643/693 600/636/686 +f 607/644/694 600/636/686 606/643/693 +f 600/636/686 607/644/694 608/645/695 +f 609/646/696 608/645/695 607/644/694 +f 608/645/695 609/646/696 610/647/697 +f 599/635/685 600/636/686 611/648/698 +f 608/645/695 611/648/698 600/636/686 +f 611/648/698 608/645/695 612/649/699 +f 610/647/697 612/649/699 608/645/695 +f 612/649/699 610/647/697 613/650/700 +f 609/646/696 613/650/700 610/647/697 +f 613/650/700 609/646/696 614/651/701 +f 609/646/696 615/652/702 614/651/701 +f 615/652/702 616/653/703 614/651/701 +f 616/653/703 615/652/702 617/654/704 +f 618/655/705 611/648/698 612/649/699 +f 612/649/699 619/656/706 618/655/705 +f 619/656/706 612/649/699 616/653/703 +f 613/650/700 616/653/703 612/649/699 +f 616/653/703 613/650/700 614/651/701 +f 619/656/706 620/657/707 621/658/708 +f 620/657/707 619/656/706 739/659/709 +f 619/656/706 622/660/710 739/659/709 +f 622/660/710 619/656/706 1709/661/711 +f 619/656/706 623/662/712 1709/661/711 +f 623/662/712 619/656/706 624/663/713 +f 624/663/713 625/664/714 623/662/712 +f 625/664/714 624/663/713 626/665/715 +f 617/654/704 619/656/706 616/653/703 +f 619/656/706 617/654/704 627/666/716 +f 627/666/716 624/663/713 619/656/706 +f 624/663/713 627/666/716 628/667/717 +f 628/667/717 626/665/715 624/663/713 +f 626/665/715 628/667/717 629/668/718 +f 629/668/718 625/664/714 626/665/715 +f 625/664/714 629/668/718 630/669/719 +f 630/669/719 623/662/712 625/664/714 +f 623/662/712 630/669/719 631/670/720 +f 631/670/720 629/668/718 628/667/717 +f 631/670/720 1709/661/711 623/662/712 +f 1709/661/711 631/670/720 1708/671/721 +f 628/667/717 1708/671/721 631/670/720 +f 1708/671/721 628/667/717 627/666/716 +f 627/666/716 1707/672/722 1708/671/721 +f 1707/672/722 627/666/716 1706/673/723 +f 627/666/716 632/674/724 1706/673/723 +f 633/675/725 1706/673/723 632/674/724 +f 632/674/724 634/676/726 633/675/725 +f 635/677/727 633/675/725 634/676/726 +f 637/678/728 636/679/729 635/677/727 +f 633/675/725 635/677/727 636/679/729 +f 638/680/730 635/677/727 634/676/726 +f 635/677/727 638/680/730 637/678/728 +f 638/680/730 639/681/731 637/678/728 +f 636/679/729 637/678/728 639/681/731 +f 639/681/731 1712/682/732 636/679/729 +f 1714/683/733 636/679/729 1712/682/732 +f 636/679/729 1714/683/733 633/675/725 +f 1706/673/723 633/675/725 1714/683/733 +f 634/676/726 632/674/724 638/680/730 +f 639/681/731 638/680/730 632/674/724 +f 632/674/724 627/666/716 639/681/731 +f 1712/682/732 639/681/731 627/666/716 +f 627/666/716 1713/684/734 1712/682/732 +f 1713/684/734 627/666/716 617/654/704 +f 604/641/691 606/643/693 605/642/692 +f 606/643/693 604/641/691 640/685/735 +f 1711/640/690 640/685/735 604/641/691 +f 640/685/735 1711/640/690 1713/684/734 +f 1713/684/734 641/686/736 640/685/735 +f 641/686/736 1713/684/734 617/654/704 +f 617/654/704 642/687/737 641/686/736 +f 642/687/737 617/654/704 615/652/702 +f 615/652/702 609/646/696 642/687/737 +f 609/646/696 641/686/736 642/687/737 +f 641/686/736 609/646/696 607/644/694 +f 607/644/694 640/685/735 641/686/736 +f 640/685/735 607/644/694 606/643/693 +f 524/563/600 1880/562/280 1908/688/738 +f 645/689/739 643/690/740 644/691/741 +f 643/690/740 645/689/739 646/692/742 +f 648/693/743 647/694/744 644/691/741 +f 647/694/744 645/689/739 644/691/741 +f 645/689/739 647/694/744 649/695/745 +f 649/695/745 646/692/742 645/689/739 +f 646/692/742 649/695/745 650/696/746 +f 650/696/746 643/690/740 646/692/742 +f 643/690/740 650/696/746 651/697/747 +f 652/698/748 643/690/740 651/697/747 +f 643/690/740 652/698/748 653/699/749 +f 654/700/750 653/699/749 652/698/748 +f 655/701/751 650/696/746 649/695/745 +f 656/702/752 652/698/748 806/703/753 +f 651/697/747 806/703/753 652/698/748 +f 806/703/753 651/697/747 807/704/754 +f 651/697/747 808/705/755 807/704/754 +f 808/705/755 651/697/747 650/696/746 +f 657/706/756 808/705/755 650/696/746 +f 650/696/746 655/701/751 657/706/756 +f 658/707/757 657/706/756 655/701/751 +f 649/695/745 658/707/757 655/701/751 +f 658/707/757 649/695/745 802/708/758 +f 657/706/756 658/707/757 659/709/759 +f 808/705/755 657/706/756 659/709/759 +f 659/709/759 802/708/758 808/705/755 +f 802/708/758 659/709/759 658/707/757 +f 649/695/745 660/710/760 802/708/758 +f 660/710/760 649/695/745 647/694/744 +f 661/711/761 660/710/760 647/694/744 +f 647/694/744 648/693/743 661/711/761 +f 648/693/743 662/712/762 661/711/761 +f 662/712/762 817/713/763 661/711/761 +f 817/713/763 662/712/762 852/714/764 +f 663/715/765 852/714/764 662/712/762 +f 852/714/764 663/715/765 664/716/766 +f 663/715/765 853/717/767 664/716/766 +f 816/718/768 661/711/761 817/713/763 +f 661/711/761 816/718/768 810/719/769 +f 660/710/760 661/711/761 810/719/769 +f 665/720/770 663/715/765 662/712/762 +f 666/721/771 665/720/770 662/712/762 +f 662/712/762 648/693/743 666/721/771 +f 667/722/772 666/721/771 648/693/743 +f 644/691/741 667/722/772 648/693/743 +f 667/722/772 644/691/741 668/723/773 +f 643/690/740 668/723/773 644/691/741 +f 668/723/773 643/690/740 669/724/774 +f 653/699/749 669/724/774 643/690/740 +f 669/724/774 653/699/749 670/725/775 +f 672/726/776 670/725/775 671/727/777 +f 670/725/775 672/726/776 669/724/774 +f 672/726/776 668/723/773 669/724/774 +f 668/723/773 672/726/776 673/728/778 +f 673/728/778 667/722/772 668/723/773 +f 667/722/772 673/728/778 674/729/779 +f 675/730/780 667/722/772 674/729/779 +f 674/729/779 676/731/781 675/730/780 +f 677/732/782 675/730/780 676/731/781 +f 678/733/783 677/732/782 676/731/781 +f 679/734/784 678/733/783 676/731/781 +f 680/735/785 674/729/779 673/728/778 +f 674/729/779 680/735/785 681/736/786 +f 676/731/781 674/729/779 681/736/786 +f 682/737/787 676/731/781 681/736/786 +f 676/731/781 682/737/787 679/734/784 +f 682/737/787 683/738/788 679/734/784 +f 684/739/789 679/734/784 683/738/788 +f 683/738/788 685/740/790 684/739/789 +f 686/741/791 684/739/789 685/740/790 +f 685/740/790 687/742/792 686/741/791 +f 687/742/792 685/740/790 688/743/793 +f 688/743/793 689/744/794 687/742/792 +f 689/744/794 686/741/791 687/742/792 +f 686/741/791 689/744/794 690/745/795 +f 684/739/789 686/741/791 690/745/795 +f 690/745/795 691/746/796 684/739/789 +f 679/734/784 684/739/789 691/746/796 +f 691/746/796 692/747/797 679/734/784 +f 678/733/783 679/734/784 692/747/797 +f 1925/748/798 678/733/783 692/747/797 +f 691/746/796 690/745/795 689/744/794 +f 689/744/794 688/743/793 691/746/796 +f 692/747/797 691/746/796 688/743/793 +f 688/743/793 1925/748/798 692/747/797 +f 1925/748/798 688/743/793 685/740/790 +f 685/740/790 683/738/788 1925/748/798 +f 678/733/783 1925/748/798 693/749/799 +f 1924/750/800 693/749/799 1925/748/798 +f 693/749/799 1924/750/800 694/751/801 +f 838/752/802 694/751/801 1924/750/800 +f 694/751/801 838/752/802 695/753/803 +f 840/754/804 695/753/803 838/752/802 +f 695/753/803 840/754/804 696/755/805 +f 697/756/806 695/753/803 696/755/805 +f 698/757/807 697/756/806 696/755/805 +f 697/756/806 698/757/807 699/758/808 +f 677/732/782 678/733/783 700/759/809 +f 693/749/799 700/759/809 678/733/783 +f 700/759/809 693/749/799 701/760/810 +f 694/751/801 701/760/810 693/749/799 +f 701/760/810 694/751/801 702/761/811 +f 695/753/803 702/761/811 694/751/801 +f 702/761/811 695/753/803 703/762/812 +f 695/753/803 697/756/806 703/762/812 +f 699/758/808 703/762/812 697/756/806 +f 703/762/812 699/758/808 702/761/811 +f 675/730/780 677/732/782 702/761/811 +f 700/759/809 702/761/811 677/732/782 +f 702/761/811 700/759/809 701/760/810 +f 699/758/808 704/763/813 705/764/814 +f 705/764/814 706/765/815 699/758/808 +f 706/765/815 702/761/811 699/758/808 +f 702/761/811 706/765/815 675/730/780 +f 667/722/772 675/730/780 706/765/815 +f 666/721/771 667/722/772 706/765/815 +f 706/765/815 705/764/814 666/721/771 +f 665/720/770 666/721/771 705/764/814 +f 705/764/814 707/766/816 665/720/770 +f 707/766/816 705/764/814 708/767/817 +f 698/757/807 709/768/818 699/758/808 +f 704/763/813 699/758/808 709/768/818 +f 709/768/818 710/769/819 704/763/813 +f 710/769/819 705/764/814 704/763/813 +f 705/764/814 710/769/819 711/770/820 +f 711/770/820 708/767/817 705/764/814 +f 708/767/817 711/770/820 712/771/821 +f 712/771/821 707/766/816 708/767/817 +f 707/766/816 712/771/821 663/715/765 +f 663/715/765 665/720/770 707/766/816 +f 853/717/767 663/715/765 712/771/821 +f 712/771/821 713/772/822 853/717/767 +f 713/772/822 712/771/821 711/770/820 +f 711/770/820 714/773/823 713/772/822 +f 714/773/823 711/770/820 710/769/819 +f 710/769/819 842/774/824 714/773/823 +f 842/774/824 710/769/819 715/775/825 +f 715/775/825 716/776/826 842/774/824 +f 716/776/826 715/775/825 698/757/807 +f 696/755/805 716/776/826 698/757/807 +f 716/776/826 696/755/805 840/754/804 +f 709/768/818 698/757/807 715/775/825 +f 710/769/819 709/768/818 715/775/825 +f 1097/777/827 1949/778/828 1896/779/829 +f 932/780/830 717/781/831 928/782/832 +f 717/781/831 932/780/830 718/783/833 +f 720/784/834 719/785/835 1455/786/836 +f 719/785/835 720/784/834 721/787/837 +f 720/784/834 1634/788/838 721/787/837 +f 1634/788/838 722/789/839 721/787/837 +f 722/789/839 1634/788/838 938/790/840 +f 717/781/831 722/789/839 938/790/840 +f 722/789/839 717/781/831 718/783/833 +f 718/783/833 1853/791/841 722/789/839 +f 1853/791/841 718/783/833 1916/792/842 +f 932/780/830 1916/792/842 718/783/833 +f 1916/792/842 932/780/830 1917/793/843 +f 721/787/837 1853/791/841 719/785/835 +f 1853/791/841 721/787/837 722/789/839 +f 725/794/844 723/795/845 724/796/846 +f 723/795/845 725/794/844 726/797/847 +f 727/798/848 723/795/845 726/797/847 +f 726/797/847 728/799/849 727/798/848 +f 728/799/849 726/797/847 725/794/844 +f 725/794/844 729/800/850 728/799/849 +f 729/800/850 725/794/844 724/796/846 +f 724/796/846 730/801/851 729/800/850 +f 730/801/851 724/796/846 723/795/845 +f 723/795/845 727/798/848 730/801/851 +f 618/655/705 730/801/851 727/798/848 +f 727/798/848 731/802/852 618/655/705 +f 732/803/853 728/799/849 729/800/850 +f 729/800/850 733/804/854 732/803/853 +f 733/804/854 729/800/850 730/801/851 +f 730/801/851 618/655/705 733/804/854 +f 1861/805/855 734/806/856 1919/807/857 +f 735/808/858 1919/807/857 734/806/856 +f 1919/807/857 735/808/858 733/804/854 +f 736/809/859 733/804/854 735/808/858 +f 733/804/854 736/809/859 732/803/853 +f 736/809/859 731/802/852 732/803/853 +f 728/799/849 732/803/853 731/802/852 +f 731/802/852 727/798/848 728/799/849 +f 731/802/852 736/809/859 737/810/860 +f 622/811/710 738/812/861 739/813/709 +f 740/814/862 739/813/709 738/812/861 +f 739/813/709 740/814/862 1861/805/855 +f 734/806/856 1861/805/855 740/814/862 +f 740/814/862 741/815/863 734/806/856 +f 742/816/864 734/806/856 741/815/863 +f 734/806/856 742/816/864 735/808/858 +f 743/817/865 735/808/858 742/816/864 +f 735/808/858 743/817/865 736/809/859 +f 744/818/866 736/809/859 743/817/865 +f 741/815/863 743/817/865 742/816/864 +f 743/817/865 741/815/863 744/818/866 +f 745/819/867 744/818/866 741/815/863 +f 741/815/863 746/820/868 745/819/867 +f 747/821/869 745/819/867 746/820/868 +f 748/822/870 747/821/869 746/820/868 +f 736/809/859 744/818/866 737/810/860 +f 744/818/866 745/819/867 737/810/860 +f 749/823/871 737/810/860 745/819/867 +f 745/819/867 747/821/869 749/823/871 +f 747/821/869 750/824/872 749/823/871 +f 750/824/872 747/821/869 751/825/873 +f 751/825/873 752/826/874 753/827/875 +f 752/826/874 751/825/873 754/828/876 +f 747/821/869 754/828/876 751/825/873 +f 754/828/876 747/821/869 755/829/877 +f 747/821/869 748/822/870 755/829/877 +f 756/830/878 755/829/877 748/822/870 +f 611/648/698 618/655/705 731/802/852 +f 737/810/860 611/648/698 731/802/852 +f 611/648/698 737/810/860 599/635/685 +f 737/810/860 749/823/871 599/635/685 +f 749/823/871 602/638/688 599/635/685 +f 602/638/688 749/823/871 750/824/872 +f 750/824/872 601/637/687 602/638/688 +f 601/637/687 750/824/872 757/831/879 +f 751/825/873 757/831/879 750/824/872 +f 757/831/879 751/825/873 753/827/875 +f 593/627/677 587/621/671 585/620/670 +f 587/621/671 593/627/677 601/637/687 +f 601/637/687 758/832/880 587/621/671 +f 758/832/880 601/637/687 757/831/879 +f 757/831/879 759/833/881 758/832/880 +f 759/833/881 757/831/879 753/827/875 +f 753/827/875 760/834/882 759/833/881 +f 760/834/882 753/827/875 752/826/874 +f 752/826/874 764/835/679 760/834/882 +f 764/835/679 752/826/874 1710/836/680 +f 582/616/666 583/617/667 761/837/883 +f 587/621/671 761/837/883 583/617/667 +f 761/837/883 587/621/671 758/832/880 +f 758/832/880 762/838/884 761/837/883 +f 762/838/884 758/832/880 759/833/881 +f 759/833/881 763/839/885 762/838/884 +f 763/839/885 759/833/881 760/834/882 +f 760/834/882 1048/840/886 763/839/885 +f 1048/840/886 760/834/882 764/835/679 +f 1052/841/887 763/839/885 1048/840/886 +f 763/839/885 1052/841/887 765/842/888 +f 765/842/888 762/838/884 763/839/885 +f 762/838/884 765/842/888 766/843/889 +f 766/843/889 761/837/883 762/838/884 +f 761/837/883 766/843/889 582/616/666 +f 767/844/890 582/616/666 766/843/889 +f 582/616/666 767/844/890 580/614/664 +f 768/845/891 580/614/664 767/844/890 +f 580/614/664 768/845/891 579/613/663 +f 578/612/662 579/613/663 768/845/891 +f 765/842/888 767/844/890 766/843/889 +f 767/844/890 765/842/888 769/846/892 +f 769/846/892 768/845/891 767/844/890 +f 768/845/891 769/846/892 770/847/893 +f 770/847/893 578/612/662 768/845/891 +f 578/612/662 770/847/893 771/848/894 +f 1050/849/895 771/848/894 770/847/893 +f 771/848/894 1050/849/895 1884/850/896 +f 1052/841/887 769/846/892 765/842/888 +f 769/846/892 1052/841/887 1051/851/897 +f 1051/851/897 770/847/893 769/846/892 +f 770/847/893 1051/851/897 1050/849/895 +f 774/852/898 772/853/899 773/854/900 +f 775/855/901 773/854/900 772/853/899 +f 773/854/900 775/855/901 776/856/902 +f 777/857/903 776/856/902 775/855/901 +f 776/856/902 777/857/903 778/858/904 +f 779/859/905 778/858/904 777/857/903 +f 778/858/904 779/859/905 780/860/906 +f 577/611/661 780/860/906 779/859/905 +f 780/860/906 577/611/661 578/612/662 +f 578/612/662 781/861/907 780/860/906 +f 781/861/907 578/612/662 771/848/894 +f 771/848/894 1849/862/908 781/861/907 +f 1849/862/908 771/848/894 782/863/909 +f 784/864/910 776/856/902 783/865/911 +f 778/858/904 783/865/911 776/856/902 +f 783/865/911 778/858/904 785/866/912 +f 780/860/906 785/866/912 778/858/904 +f 785/866/912 780/860/906 781/861/907 +f 781/861/907 1850/867/913 785/866/912 +f 1850/867/913 781/861/907 1849/862/908 +f 1851/868/914 785/866/912 1850/867/913 +f 785/866/912 1851/868/914 783/865/911 +f 1852/869/915 783/865/911 1851/868/914 +f 783/865/911 1852/869/915 784/864/910 +f 1853/870/841 784/864/910 1852/869/915 +f 784/864/910 1853/870/841 1916/871/842 +f 784/864/910 1917/872/843 786/873/916 +f 787/874/917 934/875/918 656/876/752 +f 934/875/918 787/874/917 788/877/919 +f 788/877/919 933/878/920 934/875/918 +f 933/878/920 788/877/919 789/879/921 +f 789/879/921 1917/872/843 933/878/920 +f 1917/872/843 789/879/921 786/873/916 +f 790/880/922 786/873/916 789/879/921 +f 786/873/916 790/880/922 791/881/923 +f 790/880/922 792/882/924 791/881/923 +f 792/882/924 790/880/922 793/883/925 +f 788/877/919 790/880/922 789/879/921 +f 796/884/926 794/885/927 795/886/928 +f 797/887/929 796/884/926 795/886/928 +f 796/884/926 797/887/929 798/888/930 +f 799/889/931 798/888/930 797/887/929 +f 798/888/930 799/889/931 787/874/917 +f 800/890/932 787/874/917 799/889/931 +f 787/874/917 800/890/932 788/877/919 +f 790/880/922 788/877/919 800/890/932 +f 801/891/933 790/880/922 800/890/932 +f 790/880/922 801/891/933 793/883/925 +f 803/892/934 808/893/755 802/894/758 +f 660/895/760 803/892/934 802/894/758 +f 803/892/934 660/895/760 804/896/935 +f 804/896/935 805/897/936 803/892/934 +f 805/897/936 804/896/935 796/884/926 +f 807/898/754 805/897/936 796/884/926 +f 798/888/930 807/898/754 796/884/926 +f 807/898/754 798/888/930 806/899/753 +f 798/888/930 656/876/752 806/899/753 +f 656/876/752 798/888/930 787/874/917 +f 805/897/936 807/898/754 808/893/755 +f 808/893/755 803/892/934 805/897/936 +f 804/896/935 810/900/769 809/901/937 +f 810/900/769 804/896/935 660/895/760 +f 811/902/938 810/900/769 816/903/768 +f 810/900/769 811/902/938 809/901/937 +f 811/902/938 812/904/939 809/901/937 +f 812/904/939 804/896/935 809/901/937 +f 804/896/935 812/904/939 794/885/927 +f 794/885/927 796/884/926 804/896/935 +f 813/905/940 681/736/786 812/904/939 +f 812/904/939 811/902/938 813/905/940 +f 814/906/941 813/905/940 811/902/938 +f 816/903/768 814/906/941 811/902/938 +f 814/906/941 816/903/768 815/907/942 +f 817/908/763 815/907/942 816/903/768 +f 815/907/942 817/908/763 818/909/943 +f 817/908/763 819/910/944 818/909/943 +f 820/911/945 818/909/943 819/910/944 +f 819/910/944 821/912/946 820/911/945 +f 681/736/786 813/905/940 682/737/787 +f 822/913/947 682/737/787 813/905/940 +f 813/905/940 814/906/941 822/913/947 +f 823/914/948 822/913/947 814/906/941 +f 815/907/942 823/914/948 814/906/941 +f 823/914/948 815/907/942 824/915/949 +f 818/909/943 824/915/949 815/907/942 +f 824/915/949 818/909/943 825/916/950 +f 826/917/951 825/916/950 818/909/943 +f 825/916/950 826/917/951 827/918/952 +f 823/914/948 825/916/950 827/918/952 +f 825/916/950 823/914/948 824/915/949 +f 826/917/951 828/919/953 827/918/952 +f 828/919/953 823/914/948 827/918/952 +f 823/914/948 828/919/953 829/920/954 +f 822/913/947 823/914/948 829/920/954 +f 829/920/954 830/921/955 822/913/947 +f 682/737/787 822/913/947 830/921/955 +f 683/738/788 682/737/787 830/921/955 +f 830/921/955 820/911/945 683/738/788 +f 831/922/956 683/738/788 820/911/945 +f 820/911/945 832/923/957 831/922/956 +f 830/921/955 829/920/954 828/919/953 +f 828/919/953 826/917/951 830/921/955 +f 820/911/945 830/921/955 826/917/951 +f 818/909/943 820/911/945 826/917/951 +f 834/924/958 832/923/957 833/925/959 +f 835/926/960 831/922/956 832/923/957 +f 832/923/957 834/924/958 835/926/960 +f 836/927/961 835/926/960 834/924/958 +f 833/925/959 836/927/961 834/924/958 +f 836/927/961 833/925/959 837/928/962 +f 838/929/802 837/928/962 833/925/959 +f 837/928/962 838/929/802 683/738/788 +f 1924/750/800 683/738/788 838/929/802 +f 837/928/962 839/930/963 836/927/961 +f 835/926/960 836/927/961 839/930/963 +f 831/922/956 835/926/960 839/930/963 +f 839/930/963 837/928/962 831/922/956 +f 683/738/788 831/922/956 837/928/962 +f 833/925/959 840/931/804 838/929/802 +f 840/931/804 833/925/959 832/923/957 +f 832/923/957 820/911/945 840/931/804 +f 820/911/945 716/932/826 840/931/804 +f 716/932/826 820/911/945 842/933/824 +f 820/911/945 841/934/964 842/933/824 +f 843/935/965 842/933/824 841/934/964 +f 841/934/964 844/936/966 843/935/965 +f 843/935/965 1921/937/967 845/938/968 +f 845/938/968 714/939/823 843/935/965 +f 842/933/824 843/935/965 714/939/823 +f 841/934/964 820/911/945 821/912/946 +f 821/912/946 846/940/969 841/934/964 +f 844/936/966 841/934/964 846/940/969 +f 846/940/969 1921/937/967 844/936/966 +f 1921/937/967 846/940/969 847/941/970 +f 847/941/970 845/938/968 1921/937/967 +f 845/938/968 847/941/970 821/912/946 +f 821/912/946 819/910/944 845/938/968 +f 714/939/823 845/938/968 819/910/944 +f 819/910/944 713/942/822 714/939/823 +f 846/940/969 821/912/946 847/941/970 +f 850/943/971 848/944/972 849/945/973 +f 851/946/974 849/945/973 848/944/972 +f 848/944/972 819/910/944 851/946/974 +f 852/947/764 851/946/974 819/910/944 +f 819/910/944 817/908/763 852/947/764 +f 713/942/822 819/910/944 853/948/767 +f 819/910/944 848/944/972 853/948/767 +f 854/949/975 853/948/767 848/944/972 +f 848/944/972 850/943/971 854/949/975 +f 855/950/976 854/949/975 850/943/971 +f 849/945/973 855/950/976 850/943/971 +f 855/950/976 849/945/973 856/951/977 +f 849/945/973 851/946/974 856/951/977 +f 857/952/978 856/951/977 851/946/974 +f 851/946/974 852/947/764 857/952/978 +f 664/953/766 857/952/978 852/947/764 +f 857/952/978 664/953/766 854/949/975 +f 853/948/767 854/949/975 664/953/766 +f 856/951/977 857/952/978 855/950/976 +f 854/949/975 855/950/976 857/952/978 +f 860/954/979 858/955/980 859/956/981 +f 858/955/980 861/957/982 859/956/981 +f 861/957/982 858/955/980 862/958/983 +f 863/959/984 862/958/983 858/955/980 +f 864/960/985 863/959/984 858/955/980 +f 863/959/984 864/960/985 865/961/986 +f 866/962/987 865/961/986 864/960/985 +f 865/961/986 866/962/987 867/963/988 +f 868/964/989 867/963/988 866/962/987 +f 866/962/987 869/965/990 868/964/989 +f 870/966/991 868/964/989 869/965/990 +f 869/965/990 866/962/987 871/967/992 +f 864/960/985 871/967/992 866/962/987 +f 871/967/992 864/960/985 860/954/979 +f 858/955/980 860/954/979 864/960/985 +f 868/964/989 870/966/991 872/968/993 +f 872/968/993 873/969/994 868/964/989 +f 867/963/988 868/964/989 873/969/994 +f 873/969/994 874/970/995 867/963/988 +f 875/971/996 867/963/988 874/970/995 +f 867/963/988 875/971/996 865/961/986 +f 876/972/997 865/961/986 875/971/996 +f 865/961/986 876/972/997 863/959/984 +f 876/972/997 877/973/998 863/959/984 +f 862/958/983 863/959/984 877/973/998 +f 877/973/998 876/972/997 878/974/999 +f 873/969/994 872/968/993 879/975/1000 +f 879/975/1000 880/976/1001 873/969/994 +f 874/970/995 873/969/994 880/976/1001 +f 880/976/1001 879/975/1000 881/977/1002 +f 874/970/995 882/978/1003 875/971/996 +f 882/978/1003 874/970/995 1841/979/1004 +f 880/976/1001 1841/979/1004 874/970/995 +f 1841/979/1004 880/976/1001 1842/980/1005 +f 881/977/1002 1842/980/1005 880/976/1001 +f 1842/980/1005 881/977/1002 1844/981/1006 +f 881/977/1002 883/982/1007 1844/981/1006 +f 883/982/1007 881/977/1002 879/975/1000 +f 879/975/1000 870/966/991 883/982/1007 +f 870/966/991 879/975/1000 872/968/993 +f 562/596/646 884/983/1008 885/984/1009 +f 553/588/638 562/596/646 885/984/1009 +f 885/984/1009 877/973/998 553/588/638 +f 877/973/998 548/579/629 553/588/638 +f 548/579/629 877/973/998 878/974/999 +f 1838/985/1010 548/579/629 878/974/999 +f 876/972/997 1838/985/1010 878/974/999 +f 1838/985/1010 876/972/997 1837/986/1011 +f 875/971/996 1837/986/1011 876/972/997 +f 1837/986/1011 875/971/996 882/978/1003 +f 884/983/1008 886/987/1012 887/988/1013 +f 886/987/1012 884/983/1008 888/989/1014 +f 884/983/1008 562/596/646 888/989/1014 +f 560/592/642 888/989/1014 562/596/646 +f 888/989/1014 560/592/642 889/990/1015 +f 559/594/644 889/990/1015 560/592/642 +f 889/990/1015 559/594/644 890/991/1016 +f 891/992/1017 890/991/1016 559/594/644 +f 890/991/1016 891/992/1017 892/993/1018 +f 893/994/1019 892/993/1018 891/992/1017 +f 896/995/1020 894/996/1021 895/997/1022 +f 894/996/1021 896/995/1020 897/998/1023 +f 898/999/1024 897/998/1023 896/995/1020 +f 897/998/1023 898/999/1024 899/1000/1025 +f 893/994/1019 899/1000/1025 898/999/1024 +f 899/1000/1025 893/994/1019 900/1001/1026 +f 891/992/1017 900/1001/1026 893/994/1019 +f 900/1001/1026 891/992/1017 901/1002/1027 +f 559/594/644 901/1002/1027 891/992/1017 +f 901/1002/1027 559/594/644 558/593/643 +f 899/1000/1025 902/1003/1028 897/998/1023 +f 902/1003/1028 899/1000/1025 903/1004/1029 +f 900/1001/1026 903/1004/1029 899/1000/1025 +f 903/1004/1029 900/1001/1026 904/1005/1030 +f 901/1002/1027 904/1005/1030 900/1001/1026 +f 904/1005/1030 901/1002/1027 905/1006/1031 +f 558/593/643 905/1006/1031 901/1002/1027 +f 905/1006/1031 558/593/643 906/1007/1032 +f 561/595/645 906/1007/1032 558/593/643 +f 906/1007/1032 561/595/645 570/604/654 +f 907/1008/1033 902/1003/1028 772/853/899 +f 903/1004/1029 772/853/899 902/1003/1028 +f 772/853/899 903/1004/1029 775/855/901 +f 904/1005/1030 775/855/901 903/1004/1029 +f 775/855/901 904/1005/1030 777/857/903 +f 905/1006/1031 777/857/903 904/1005/1030 +f 777/857/903 905/1006/1031 779/859/905 +f 906/1007/1032 779/859/905 905/1006/1031 +f 779/859/905 906/1007/1032 577/611/661 +f 570/604/654 577/611/661 906/1007/1032 +f 910/1009/1034 908/1010/1035 909/1011/1036 +f 909/1011/1036 911/1012/1037 910/1009/1034 +f 911/1012/1037 909/1011/1036 912/1013/1038 +f 912/1013/1038 913/1014/1039 911/1012/1037 +f 913/1014/1039 912/1013/1038 914/1015/1040 +f 915/1016/1041 913/1014/1039 914/1015/1040 +f 913/1014/1039 915/1016/1041 916/1017/1042 +f 907/1008/1033 916/1017/1042 915/1016/1041 +f 916/1017/1042 907/1008/1033 774/852/898 +f 772/853/899 774/852/898 907/1008/1033 +f 917/1018/1043 910/1009/1034 911/1012/1037 +f 913/1014/1039 917/1018/1043 911/1012/1037 +f 917/1018/1043 913/1014/1039 792/882/924 +f 916/1017/1042 792/882/924 913/1014/1039 +f 792/882/924 916/1017/1042 791/881/923 +f 774/852/898 791/881/923 916/1017/1042 +f 791/881/923 774/852/898 786/873/916 +f 773/854/900 786/873/916 774/852/898 +f 786/873/916 773/854/900 784/864/910 +f 776/856/902 784/864/910 773/854/900 +f 793/883/925 917/1018/1043 792/882/924 +f 917/1018/1043 793/883/925 918/1019/1044 +f 918/1019/1044 919/1020/1045 917/1018/1043 +f 919/1020/1045 918/1019/1044 920/1021/1046 +f 921/1022/1047 920/1021/1046 918/1019/1044 +f 920/1021/1046 921/1022/1047 922/1023/1048 +f 923/1024/1049 922/1023/1048 921/1022/1047 +f 922/1023/1048 923/1024/1049 924/1025/1050 +f 671/727/777 924/1025/1050 923/1024/1049 +f 924/1025/1050 671/727/777 670/725/775 +f 925/1026/1051 670/725/775 653/699/749 +f 670/725/775 925/1026/1051 924/1025/1050 +f 926/1027/1052 924/1025/1050 925/1026/1051 +f 924/1025/1050 926/1027/1052 922/1023/1048 +f 927/1028/1053 922/1023/1048 926/1027/1052 +f 922/1023/1048 927/1028/1053 920/1021/1046 +f 928/1029/832 920/1021/1046 927/1028/1053 +f 920/1021/1046 928/1029/832 919/1020/1045 +f 928/1029/832 910/1009/1034 919/1020/1045 +f 910/1009/1034 917/1018/1043 919/1020/1045 +f 910/1009/1034 928/1029/832 929/1030/1054 +f 653/699/749 654/700/750 925/1026/1051 +f 930/1031/1055 925/1026/1051 654/700/750 +f 925/1026/1051 930/1031/1055 926/1027/1052 +f 931/1032/1056 926/1027/1052 930/1031/1055 +f 926/1027/1052 931/1032/1056 927/1028/1053 +f 931/1032/1056 928/1029/832 927/1028/1053 +f 928/1029/832 931/1032/1056 932/1033/830 +f 931/1032/1056 1917/1034/843 932/1033/830 +f 1917/1034/843 931/1032/1056 933/1035/920 +f 930/1031/1055 933/1035/920 931/1032/1056 +f 933/1035/920 930/1031/1055 934/1036/918 +f 654/700/750 934/1036/918 930/1031/1055 +f 934/1036/918 654/700/750 656/702/752 +f 652/698/748 656/702/752 654/700/750 +f 936/1037/1057 1631/1038/1058 935/1039/1059 +f 1631/1038/1058 936/1037/1057 1632/1040/1060 +f 937/1041/1061 1632/1040/1060 936/1037/1057 +f 1632/1040/1060 937/1041/1061 1633/1042/1062 +f 937/1041/1061 938/1043/840 1633/1042/1062 +f 938/1043/840 937/1041/1061 717/1044/831 +f 937/1041/1061 928/1029/832 717/1044/831 +f 928/1029/832 937/1041/1061 929/1030/1054 +f 937/1041/1061 908/1010/1035 929/1030/1054 +f 908/1010/1035 910/1009/1034 929/1030/1054 +f 908/1010/1035 937/1041/1061 936/1037/1057 +f 935/1039/1059 908/1010/1035 936/1037/1057 +f 908/1010/1035 935/1039/1059 939/1045/1063 +f 940/1046/1064 939/1045/1063 935/1039/1059 +f 939/1045/1063 940/1046/1064 941/1047/1065 +f 942/1048/1066 941/1047/1065 940/1046/1064 +f 941/1047/1065 942/1048/1066 943/1049/1067 +f 943/1049/1067 944/1050/1068 941/1047/1065 +f 944/1050/1068 943/1049/1067 945/1051/1069 +f 946/1052/1070 944/1050/1068 945/1051/1069 +f 944/1050/1068 946/1052/1070 947/1053/1071 +f 948/1054/1072 947/1053/1071 946/1052/1070 +f 949/1055/1073 941/1047/1065 944/1050/1068 +f 941/1047/1065 949/1055/1073 939/1045/1063 +f 950/1056/1074 944/1050/1068 947/1053/1071 +f 944/1050/1068 950/1056/1074 949/1055/1073 +f 912/1013/1038 949/1055/1073 950/1056/1074 +f 949/1055/1073 912/1013/1038 909/1011/1036 +f 909/1011/1036 939/1045/1063 949/1055/1073 +f 939/1045/1063 909/1011/1036 908/1010/1035 +f 947/1053/1071 951/1057/1075 950/1056/1074 +f 952/1058/1076 950/1056/1074 951/1057/1075 +f 950/1056/1074 952/1058/1076 912/1013/1038 +f 953/1059/1077 912/1013/1038 952/1058/1076 +f 912/1013/1038 953/1059/1077 914/1015/1040 +f 954/1060/1078 914/1015/1040 953/1059/1077 +f 914/1015/1040 954/1060/1078 915/1016/1041 +f 955/1061/1079 915/1016/1041 954/1060/1078 +f 915/1016/1041 955/1061/1079 907/1008/1033 +f 902/1003/1028 907/1008/1033 955/1061/1079 +f 957/1062/1080 951/1057/1075 956/1063/1081 +f 951/1057/1075 957/1062/1080 952/1058/1076 +f 958/1064/1082 952/1058/1076 957/1062/1080 +f 952/1058/1076 958/1064/1082 953/1059/1077 +f 959/1065/1083 953/1059/1077 958/1064/1082 +f 953/1059/1077 959/1065/1083 954/1060/1078 +f 894/996/1021 954/1060/1078 959/1065/1083 +f 954/1060/1078 894/996/1021 955/1061/1079 +f 897/998/1023 955/1061/1079 894/996/1021 +f 955/1061/1079 897/998/1023 902/1003/1028 +f 962/1066/1084 960/1067/1085 961/1068/1086 +f 956/1063/1081 961/1068/1086 960/1067/1085 +f 963/1069/1087 956/1063/1081 960/1067/1085 +f 956/1063/1081 963/1069/1087 957/1062/1080 +f 964/1070/1088 957/1062/1080 963/1069/1087 +f 957/1062/1080 964/1070/1088 958/1064/1082 +f 965/1071/1089 958/1064/1082 964/1070/1088 +f 958/1064/1082 965/1071/1089 959/1065/1083 +f 895/997/1022 959/1065/1083 965/1071/1089 +f 959/1065/1083 895/997/1022 894/996/1021 +f 967/1072/1090 964/1070/1088 966/1073/1091 +f 963/1069/1087 966/1073/1091 964/1070/1088 +f 966/1073/1091 963/1069/1087 968/1074/1092 +f 960/1067/1085 968/1074/1092 963/1069/1087 +f 968/1074/1092 960/1067/1085 969/1075/1093 +f 960/1067/1085 962/1066/1084 969/1075/1093 +f 962/1066/1084 970/1076/1094 969/1075/1093 +f 970/1076/1094 962/1066/1084 971/1077/1095 +f 971/1077/1095 972/1078/1096 970/1076/1094 +f 972/1078/1096 971/1077/1095 973/1079/1097 +f 970/1076/1094 968/1074/1092 969/1075/1093 +f 975/1080/1098 974/1081/1099 972/1078/1096 +f 976/1082/1100 972/1078/1096 974/1081/1099 +f 972/1078/1096 976/1082/1100 970/1076/1094 +f 968/1074/1092 970/1076/1094 976/1082/1100 +f 976/1082/1100 966/1073/1091 968/1074/1092 +f 966/1073/1091 976/1082/1100 977/1083/1101 +f 977/1083/1101 967/1072/1090 966/1073/1091 +f 974/1081/1099 977/1083/1101 976/1082/1100 +f 979/1084/1102 978/1085/1103 975/1080/1098 +f 974/1081/1099 975/1080/1098 978/1085/1103 +f 978/1085/1103 980/1086/1104 974/1081/1099 +f 977/1083/1101 974/1081/1099 980/1086/1104 +f 980/1086/1104 981/1087/1105 977/1083/1101 +f 967/1072/1090 977/1083/1101 981/1087/1105 +f 981/1087/1105 982/1088/1106 967/1072/1090 +f 982/1088/1106 981/1087/1105 983/1089/1107 +f 983/1089/1107 984/1090/1108 982/1088/1106 +f 984/1090/1108 983/1089/1107 985/1091/1109 +f 979/1084/1102 986/1092/1110 987/1093/1111 +f 987/1093/1111 988/1094/1112 979/1084/1102 +f 978/1085/1103 979/1084/1102 988/1094/1112 +f 988/1094/1112 989/1095/1113 978/1085/1103 +f 980/1086/1104 978/1085/1103 989/1095/1113 +f 989/1095/1113 990/1096/1114 980/1086/1104 +f 981/1087/1105 980/1086/1104 990/1096/1114 +f 990/1096/1114 983/1089/1107 981/1087/1105 +f 983/1089/1107 990/1096/1114 991/1097/1115 +f 991/1097/1115 985/1091/1109 983/1089/1107 +f 994/1098/1116 992/1099/1117 993/1100/1118 +f 993/1100/1118 995/1101/1119 994/1098/1116 +f 995/1101/1119 993/1100/1118 996/1102/1120 +f 988/1094/1112 995/1101/1119 996/1102/1120 +f 989/1095/1113 988/1094/1112 996/1102/1120 +f 996/1102/1120 997/1103/1121 989/1095/1113 +f 990/1096/1114 989/1095/1113 997/1103/1121 +f 997/1103/1121 991/1097/1115 990/1096/1114 +f 991/1097/1115 997/1103/1121 998/1104/1122 +f 998/1104/1122 999/1105/1123 991/1097/1115 +f 999/1105/1123 998/1104/1122 1000/1106/1124 +f 1000/1106/1124 1001/1107/1125 999/1105/1123 +f 997/1103/1121 996/1102/1120 993/1100/1118 +f 993/1100/1118 998/1104/1122 997/1103/1121 +f 998/1104/1122 993/1100/1118 992/1099/1117 +f 992/1099/1117 1000/1106/1124 998/1104/1122 +f 985/1091/1109 991/1097/1115 999/1105/1123 +f 999/1105/1123 1002/1108/1126 985/1091/1109 +f 1002/1108/1126 999/1105/1123 1001/1107/1125 +f 1001/1107/1125 1003/1109/1127 1002/1108/1126 +f 1005/1110/1128 1004/1111/1129 1001/1107/1125 +f 1003/1109/1127 1001/1107/1125 1004/1111/1129 +f 1004/1111/1129 1006/1112/1130 1003/1109/1127 +f 1006/1112/1130 1004/1111/1129 1007/1113/1131 +f 1007/1113/1131 1008/1114/1132 1006/1112/1130 +f 985/1091/1109 1009/1115/1133 984/1090/1108 +f 1009/1115/1133 985/1091/1109 1002/1108/1126 +f 1002/1108/1126 1010/1116/1134 1009/1115/1133 +f 1010/1116/1134 1002/1108/1126 1003/1109/1127 +f 1003/1109/1127 892/993/1018 1010/1116/1134 +f 892/993/1018 1003/1109/1127 1006/1112/1130 +f 1006/1112/1130 890/991/1016 892/993/1018 +f 890/991/1016 1006/1112/1130 1008/1114/1132 +f 1008/1114/1132 889/990/1015 890/991/1016 +f 889/990/1015 1008/1114/1132 1011/1117/1135 +f 892/993/1018 893/994/1019 1010/1116/1134 +f 898/999/1024 1010/1116/1134 893/994/1019 +f 1010/1116/1134 898/999/1024 1009/1115/1133 +f 896/995/1020 1009/1115/1133 898/999/1024 +f 1009/1115/1133 896/995/1020 984/1090/1108 +f 895/997/1022 984/1090/1108 896/995/1020 +f 984/1090/1108 895/997/1022 982/1088/1106 +f 965/1071/1089 982/1088/1106 895/997/1022 +f 982/1088/1106 965/1071/1089 967/1072/1090 +f 964/1070/1088 967/1072/1090 965/1071/1089 +f 1011/1117/1135 888/989/1014 889/990/1015 +f 888/989/1014 1011/1117/1135 886/987/1012 +f 1012/1118/1136 886/987/1012 1011/1117/1135 +f 886/987/1012 1012/1118/1136 1013/1119/1137 +f 1012/1118/1136 1014/1120/1138 1013/1119/1137 +f 1015/1121/1139 1013/1119/1137 1014/1120/1138 +f 1016/1122/1140 1015/1121/1139 1014/1120/1138 +f 1015/1121/1139 1016/1122/1140 1017/1123/1141 +f 1018/1124/1142 1017/1123/1141 1016/1122/1140 +f 1017/1123/1141 1018/1124/1142 1019/1125/1143 +f 1020/1126/1144 886/987/1012 1013/1119/1137 +f 1013/1119/1137 1015/1121/1139 1020/1126/1144 +f 1021/1127/1145 1020/1126/1144 1015/1121/1139 +f 1017/1123/1141 1021/1127/1145 1015/1121/1139 +f 1021/1127/1145 1017/1123/1141 1022/1128/1146 +f 1019/1125/1143 1022/1128/1146 1017/1123/1141 +f 1022/1128/1146 1019/1125/1143 1023/1129/1147 +f 1024/1130/1148 1023/1129/1147 1019/1125/1143 +f 1025/1131/1149 1021/1127/1145 1022/1128/1146 +f 1025/1131/1149 1026/1132/1150 1027/1133/1151 +f 1026/1132/1150 1025/1131/1149 1022/1128/1146 +f 1023/1129/1147 1026/1132/1150 1022/1128/1146 +f 1058/1134/1152 1028/1135/1153 1027/1133/1151 +f 1027/1133/1151 1029/1136/1154 1058/1134/1152 +f 1029/1136/1154 1027/1133/1151 1026/1132/1150 +f 1026/1132/1150 1030/1137/1155 1029/1136/1154 +f 1030/1137/1155 1026/1132/1150 1882/1138/1156 +f 1026/1132/1150 1023/1129/1147 1882/1138/1156 +f 1031/1139/1157 1882/1138/1156 1023/1129/1147 +f 1023/1129/1147 1024/1130/1148 1031/1139/1157 +f 1032/1140/1158 1031/1139/1157 1024/1130/1148 +f 1031/1139/1157 1032/1140/1158 1033/1141/1159 +f 1020/1126/1144 1021/1127/1145 1886/1142/1160 +f 1034/1143/1161 1886/1142/1160 1021/1127/1145 +f 1021/1127/1145 1025/1131/1149 1034/1143/1161 +f 1025/1131/1149 1035/1144/1162 1034/1143/1161 +f 1035/1144/1162 1025/1131/1149 1027/1133/1151 +f 1027/1133/1151 1036/1145/1163 1035/1144/1162 +f 1036/1145/1163 1027/1133/1151 1028/1135/1153 +f 1028/1135/1153 1043/1146/630 1036/1145/1163 +f 1043/1146/630 1028/1135/1153 1060/1147/1164 +f 1028/1135/1153 1058/1134/1152 1060/1147/1164 +f 1886/1142/1160 1034/1143/1161 1035/1144/1162 +f 1038/1148/1165 1037/1149/628 1886/1142/1160 +f 1037/1149/628 1038/1148/1165 1039/1150/627 +f 1038/1148/1165 1041/1151/625 1039/1150/627 +f 1041/1151/625 1038/1148/1165 1040/1152/1166 +f 550/1153/634 1040/1152/1166 1038/1148/1165 +f 1886/1142/1160 550/1153/634 1038/1148/1165 +f 550/1153/634 1886/1142/1160 1042/1154/633 +f 1035/1144/1162 1042/1154/633 1886/1142/1160 +f 1042/1154/633 1035/1144/1162 1044/1155/632 +f 1035/1144/1162 1043/1146/630 1044/1155/632 +f 1043/1146/630 1035/1144/1162 1036/1145/1163 +f 1040/1152/1166 550/1153/634 552/1156/636 +f 1949/778/828 1097/777/827 1909/1157/1167 +f 1047/1158/1168 1045/1159/1169 1046/1160/1170 +f 594/628/678 1047/1158/1168 1046/1160/1170 +f 1046/1160/1170 1048/1161/886 594/628/678 +f 764/629/679 594/628/678 1048/1161/886 +f 1884/1162/896 1049/1163/1171 1883/1164/1172 +f 1049/1163/1171 1884/1162/896 1050/1165/895 +f 1050/1165/895 1045/1159/1169 1049/1163/1171 +f 1045/1159/1169 1050/1165/895 1051/1166/897 +f 1051/1166/897 1046/1160/1170 1045/1159/1169 +f 1046/1160/1170 1051/1166/897 1052/1167/887 +f 1048/1161/886 1046/1160/1170 1052/1167/887 +f 556/590/640 549/581/631 1053/1168/1173 +f 1054/1169/1174 556/590/640 1053/1168/1173 +f 556/590/640 1054/1169/1174 557/591/641 +f 1054/1169/1174 1055/1170/1175 557/591/641 +f 1055/1170/1175 1054/1169/1174 1883/1164/1172 +f 1883/1164/1172 1056/1171/1176 1055/1170/1175 +f 1056/1171/1176 1883/1164/1172 1049/1163/1171 +f 1049/1163/1171 1057/1172/1177 1056/1171/1176 +f 1057/1172/1177 1049/1163/1171 1045/1159/1169 +f 1045/1159/1169 1047/1158/1168 1057/1172/1177 +f 566/600/650 557/591/641 1055/1170/1175 +f 1055/1170/1175 574/608/658 566/600/650 +f 574/608/658 1055/1170/1175 1056/1171/1176 +f 1056/1171/1176 576/610/660 574/608/658 +f 576/610/660 1056/1171/1176 1057/1172/1177 +f 1057/1172/1177 588/622/672 576/610/660 +f 588/622/672 1057/1172/1177 1047/1158/1168 +f 589/623/673 588/622/672 1047/1158/1168 +f 1047/1158/1168 594/628/678 589/623/673 +f 590/624/674 589/623/673 594/628/678 +f 1054/1169/1174 1030/1173/1155 1883/1164/1172 +f 1030/1173/1155 1054/1169/1174 1029/1174/1154 +f 1053/1168/1173 1029/1174/1154 1054/1169/1174 +f 1029/1174/1154 1053/1168/1173 1058/1175/1152 +f 1059/1176/1178 1058/1175/1152 1053/1168/1173 +f 1058/1175/1152 1059/1176/1178 1060/1177/1164 +f 1059/1176/1178 1043/580/630 1060/1177/1164 +f 1043/580/630 1059/1176/1178 1061/1178/1179 +f 549/581/631 1043/580/630 1061/1178/1179 +f 1061/1178/1179 1053/1168/1173 549/581/631 +f 1053/1168/1173 1061/1178/1179 1059/1176/1178 +f 801/891/933 918/1019/1044 793/883/925 +f 918/1019/1044 801/891/933 921/1022/1047 +f 1062/1179/1180 921/1022/1047 801/891/933 +f 921/1022/1047 1062/1179/1180 923/1024/1049 +f 1063/1180/1181 923/1024/1049 1062/1179/1180 +f 923/1024/1049 1063/1180/1181 671/727/777 +f 1064/1181/1182 671/727/777 1063/1180/1181 +f 671/727/777 1064/1181/1182 672/726/776 +f 1064/1181/1182 673/728/778 672/726/776 +f 673/728/778 1064/1181/1182 680/735/785 +f 800/890/932 1062/1179/1180 801/891/933 +f 1062/1179/1180 800/890/932 799/889/931 +f 797/887/929 1062/1179/1180 799/889/931 +f 1062/1179/1180 797/887/929 1063/1180/1181 +f 795/886/928 1063/1180/1181 797/887/929 +f 1063/1180/1181 795/886/928 1064/1181/1182 +f 794/885/927 1064/1181/1182 795/886/928 +f 1064/1181/1182 794/885/927 680/735/785 +f 794/885/927 681/736/786 680/735/785 +f 681/736/786 794/885/927 812/904/939 +f 1067/1182/1183 1065/1183/1184 1066/1184/1185 +f 1065/1183/1184 1068/1185/1186 1066/1184/1185 +f 1068/1185/1186 1065/1183/1184 1069/1186/1187 +f 1069/1186/1187 1070/1187/1188 1068/1185/1186 +f 1070/1187/1188 1069/1186/1187 1071/1188/1189 +f 1072/1189/1190 1070/1187/1188 1071/1188/1189 +f 1073/1190/1191 1068/1185/1186 1070/1187/1188 +f 1068/1185/1186 1073/1190/1191 1074/1191/1192 +f 1074/1191/1192 1066/1184/1185 1068/1185/1186 +f 1066/1184/1185 1074/1191/1192 1075/1192/1193 +f 1075/1192/1193 1067/1182/1183 1066/1184/1185 +f 1067/1182/1183 1075/1192/1193 1076/1193/1194 +f 1076/1193/1194 948/1054/1072 1067/1182/1183 +f 948/1054/1072 1076/1193/1194 1077/1194/1195 +f 947/1053/1071 948/1054/1072 1077/1194/1195 +f 951/1057/1075 947/1053/1071 1077/1194/1195 +f 1078/1195/1196 1074/1191/1192 1073/1190/1191 +f 1079/1196/1197 1078/1195/1196 1073/1190/1191 +f 1080/1197/1198 1075/1192/1193 1074/1191/1192 +f 1074/1191/1192 1078/1195/1196 1080/1197/1198 +f 1078/1195/1196 1081/1198/1199 1080/1197/1198 +f 1083/1199/1200 1082/1200/1201 1081/1198/1199 +f 1081/1198/1199 1078/1195/1196 1083/1199/1200 +f 1084/1201/1202 1083/1199/1200 1078/1195/1196 +f 1078/1195/1196 1079/1196/1197 1084/1201/1202 +f 1079/1196/1197 1085/1202/1203 1084/1201/1202 +f 1083/1199/1200 1084/1201/1202 1085/1202/1203 +f 1874/1203/1204 1089/1204/123 115/1205/122 +f 1089/1204/123 1874/1203/1204 1082/1200/1201 +f 1086/1206/1205 1089/1204/123 1082/1200/1201 +f 1082/1200/1201 1083/1199/1200 1086/1206/1205 +f 1083/1199/1200 1087/1207/1206 1086/1206/1205 +f 1087/1207/1206 1083/1199/1200 1085/1202/1203 +f 1088/1208/1207 1087/1207/1206 1085/1202/1203 +f 1085/1202/1203 1079/1196/1197 1088/1208/1207 +f 1079/1196/1197 1070/1187/1188 1088/1208/1207 +f 1070/1187/1188 1079/1196/1197 1073/1190/1191 +f 1087/1207/1206 1088/1208/1207 1072/1189/1190 +f 1089/1204/123 1086/1206/1205 1090/1209/124 +f 1087/1207/1206 1090/1209/124 1086/1206/1205 +f 1090/1209/124 1087/1207/1206 116/1210/125 +f 1072/1189/1190 116/1210/125 1087/1207/1206 +f 116/1210/125 1072/1189/1190 117/1211/126 +f 1071/1188/1189 117/1211/126 1072/1189/1190 +f 117/1211/126 1071/1188/1189 1091/1212/127 +f 1069/1186/1187 1091/1212/127 1071/1188/1189 +f 1091/1212/127 1069/1186/1187 94/1213/102 +f 1065/1183/1184 94/1213/102 1069/1186/1187 +f 94/1213/102 1065/1183/1184 1093/1214/98 +f 1065/1183/1184 1092/1215/91 1093/1214/98 +f 1092/1215/91 1065/1183/1184 1094/1216/92 +f 1065/1183/1184 1067/1182/1183 1094/1216/92 +f 1067/1182/1183 1095/1217/1208 1094/1216/92 +f 1095/1217/1208 1067/1182/1183 948/1054/1072 +f 946/1052/1070 1095/1217/1208 948/1054/1072 +f 1095/1217/1208 946/1052/1070 1096/1218/1209 +f 945/1051/1069 1096/1218/1209 946/1052/1070 +f 1096/1218/1209 945/1051/1069 1300/1219/1210 +f 945/1051/1069 1301/1220/1211 1300/1219/1210 +f 1301/1220/1211 945/1051/1069 943/1049/1067 +f 943/1049/1067 244/1221/266 1301/1220/1211 +f 244/1221/266 943/1049/1067 942/1048/1066 +f 942/1048/1066 1297/1222/1212 244/1221/266 +f 1297/1222/1212 942/1048/1066 1872/1223/1213 +f 940/1046/1064 1872/1223/1213 942/1048/1066 +f 1872/1223/1213 940/1046/1064 1873/1224/1214 +f 935/1039/1059 1873/1224/1214 940/1046/1064 +f 1873/1224/1214 935/1039/1059 1631/1038/1058 +f 1854/1225/1215 1909/1157/1167 1097/777/827 +f 1099/1226/1216 2230/1227/1217 1098/1228/1218 +f 2230/1227/1217 1099/1226/1216 2187/1229/1219 +f 2137/1230/1220 1100/1231/1221 2034/1232/1222 +f 1100/1231/1221 2137/1230/1220 2160/1233/1223 +f 1102/1234/1224 2035/1235/1225 1101/1236/1226 +f 2035/1235/1225 1102/1234/1224 2036/1237/1227 +f 1103/1238/1228 2039/1239/1229 2038/1240/1230 +f 2039/1239/1229 1103/1238/1228 2227/1241/1231 +f 2110/1242/1232 1104/1243/1233 2225/1244/1234 +f 1104/1243/1233 2110/1242/1232 1105/1245/1235 +f 2109/1246/1236 1105/1245/1235 2110/1242/1232 +f 1105/1245/1235 2109/1246/1236 1106/1247/1237 +f 2103/520/1238 2222/521/1239 2104/523/1240 +f 2222/521/1239 2103/520/1238 1107/522/1241 +f 1108/1248/1242 2043/1249/1243 2220/1250/1244 +f 2043/1249/1243 1108/1248/1242 1109/1251/1245 +f 2107/1252/1246 2044/1253/1247 2218/1254/1248 +f 2044/1253/1247 2107/1252/1246 1110/1255/1249 +f 2068/532/1250 1111/533/1251 504/535/574 +f 1111/533/1251 2068/532/1250 1112/534/1252 +f 1113/1256/1253 2216/1257/1254 2068/1258/1250 +f 2216/1257/1254 1113/1256/1253 1114/1259/1255 +f 1115/1260/1256 1997/1261/1257 1996/1262/1258 +f 1997/1261/1257 1115/1260/1256 1116/1263/1259 +f 1121/1264/1260 1118/1265/1261 1122/1266/1262 +f 1118/1265/1261 1121/1264/1260 1117/1267/1263 +f 1119/1268/1264 1118/1265/1261 1117/1269/1263 +f 1118/1265/1261 1119/1268/1264 1123/1270/1265 +f 1120/1271/1266 1117/1267/1263 1121/1264/1260 +f 1117/1267/1263 1120/1271/1266 1119/1272/1264 +f 1124/1273/1267 1121/1264/1260 1122/1266/1262 +f 1121/1264/1260 1124/1273/1267 1120/1271/1266 +f 1123/1270/1265 1122/1266/1262 1118/1265/1261 +f 1122/1266/1262 1123/1270/1265 1124/1273/1267 +f 1130/1264/1268 1125/1265/1269 1127/1267/1270 +f 1125/1265/1269 1130/1264/1268 1126/1266/1271 +f 1128/1268/1272 1125/1265/1269 1132/1270/1273 +f 1125/1265/1269 1128/1268/1272 1127/1269/1270 +f 1129/1271/1274 1127/1267/1270 1128/1272/1272 +f 1127/1267/1270 1129/1271/1274 1130/1264/1268 +f 1131/1273/1275 1130/1264/1268 1129/1271/1274 +f 1130/1264/1268 1131/1273/1275 1126/1266/1271 +f 1132/1270/1273 1126/1266/1271 1131/1273/1275 +f 1126/1266/1271 1132/1270/1273 1125/1265/1269 +f 1138/1264/1268 1133/1265/1276 1135/1267/1270 +f 1133/1265/1276 1138/1264/1268 1134/1266/1277 +f 1136/1268/1272 1133/1265/1276 1140/1270/1278 +f 1133/1265/1276 1136/1268/1272 1135/1269/1270 +f 1137/1271/1279 1135/1267/1270 1136/1272/1272 +f 1135/1267/1270 1137/1271/1279 1138/1264/1268 +f 1139/1273/1280 1138/1264/1268 1137/1271/1279 +f 1138/1264/1268 1139/1273/1280 1134/1266/1277 +f 1140/1270/1278 1134/1266/1277 1139/1273/1280 +f 1134/1266/1277 1140/1270/1278 1133/1265/1276 +f 1141/1264/1281 1145/1265/1282 1144/1267/1283 +f 1145/1265/1282 1141/1264/1281 1148/1266/1284 +f 1143/1268/1285 1145/1265/1282 1142/1270/1286 +f 1145/1265/1282 1143/1268/1285 1144/1269/1283 +f 1146/1271/1287 1144/1267/1283 1143/1272/1285 +f 1144/1267/1283 1146/1271/1287 1141/1264/1281 +f 1147/1273/1288 1141/1264/1281 1146/1271/1287 +f 1141/1264/1281 1147/1273/1288 1148/1266/1284 +f 1142/1270/1286 1148/1266/1284 1147/1273/1288 +f 1148/1266/1284 1142/1270/1286 1145/1265/1282 +f 1154/1264/1289 1151/1265/1290 1155/1266/1291 +f 1151/1265/1290 1154/1264/1289 1153/1267/1292 +f 1149/1268/1293 1151/1265/1290 1153/1269/1292 +f 1151/1265/1290 1149/1268/1293 1150/1270/1294 +f 1152/1271/1295 1153/1267/1292 1154/1264/1289 +f 1153/1267/1292 1152/1271/1295 1149/1272/1293 +f 1156/1273/1296 1154/1264/1289 1155/1266/1291 +f 1154/1264/1289 1156/1273/1296 1152/1271/1295 +f 1150/1270/1294 1155/1266/1291 1151/1265/1290 +f 1155/1266/1291 1150/1270/1294 1156/1273/1296 +f 1157/1264/1297 1164/1265/1298 1161/1267/1299 +f 1164/1265/1298 1157/1264/1297 1158/1266/1300 +f 1159/1268/1301 1164/1265/1298 1163/1270/1302 +f 1164/1265/1298 1159/1268/1301 1161/1269/1299 +f 1160/1271/1303 1161/1267/1299 1159/1272/1301 +f 1161/1267/1299 1160/1271/1303 1157/1264/1297 +f 1162/1273/1304 1157/1264/1297 1160/1271/1303 +f 1157/1264/1297 1162/1273/1304 1158/1266/1300 +f 1163/1270/1302 1158/1266/1300 1162/1273/1304 +f 1158/1266/1300 1163/1270/1302 1164/1265/1298 +f 1165/1264/1305 1172/1265/1306 1169/1267/1307 +f 1172/1265/1306 1165/1264/1305 1170/1266/1308 +f 1167/1268/1309 1172/1265/1306 1166/1270/1310 +f 1172/1265/1306 1167/1268/1309 1169/1269/1307 +f 1168/1271/1303 1169/1267/1307 1167/1272/1309 +f 1169/1267/1307 1168/1271/1303 1165/1264/1305 +f 1171/1273/1311 1165/1264/1305 1168/1271/1303 +f 1165/1264/1305 1171/1273/1311 1170/1266/1308 +f 1166/1270/1310 1170/1266/1308 1171/1273/1311 +f 1170/1266/1308 1166/1270/1310 1172/1265/1306 +f 1174/1264/1312 1180/1265/1313 1173/1267/1314 +f 1180/1265/1313 1174/1264/1312 1177/1266/1315 +f 1175/1268/1316 1180/1265/1313 1179/1270/1317 +f 1180/1265/1313 1175/1268/1316 1173/1269/1314 +f 1176/1271/1318 1173/1267/1314 1175/1272/1316 +f 1173/1267/1314 1176/1271/1318 1174/1264/1312 +f 1178/1273/1319 1174/1264/1312 1176/1271/1318 +f 1174/1264/1312 1178/1273/1319 1177/1266/1315 +f 1179/1270/1317 1177/1266/1315 1178/1273/1319 +f 1177/1266/1315 1179/1270/1317 1180/1265/1313 +f 1183/1274/1320 1181/1275/1321 1182/1276/1322 +f 1181/1275/1321 1183/1274/1320 1184/1277/1323 +f 1186/1278/1324 1185/1279/1325 1184/1277/1323 +f 1183/1274/1320 1186/1278/1324 1184/1277/1323 +f 1186/1278/1324 1183/1274/1320 1187/1280/1326 +f 1182/1276/1322 1187/1280/1326 1183/1274/1320 +f 1187/1280/1326 1182/1276/1322 1188/1281/1327 +f 1181/1275/1321 1188/1281/1327 1182/1276/1322 +f 1188/1281/1327 1181/1275/1321 1189/1282/1328 +f 1181/1275/1321 1190/1283/1329 1189/1282/1328 +f 1190/1283/1329 1181/1275/1321 1191/1284/1330 +f 1191/1284/1330 1192/1285/1331 1190/1283/1329 +f 1188/1281/1327 1193/1286/1332 1187/1280/1326 +f 1194/1287/1333 1189/1282/1328 1190/1283/1329 +f 1189/1282/1328 1194/1287/1333 1483/1288/1334 +f 1484/1289/1335 1189/1282/1328 1483/1288/1334 +f 1189/1282/1328 1484/1289/1335 1188/1281/1327 +f 1484/1289/1335 1195/1290/1336 1188/1281/1327 +f 1193/1286/1332 1188/1281/1327 1195/1290/1336 +f 1195/1290/1336 1196/1291/1337 1193/1286/1332 +f 1196/1291/1337 1187/1280/1326 1193/1286/1332 +f 1187/1280/1326 1196/1291/1337 1197/1292/1338 +f 1485/1293/1339 1187/1280/1326 1197/1292/1338 +f 1196/1291/1337 1195/1290/1336 1198/1294/1340 +f 1198/1294/1340 1197/1292/1338 1196/1291/1337 +f 1197/1292/1338 1198/1294/1340 1484/1289/1335 +f 1195/1290/1336 1484/1289/1335 1198/1294/1340 +f 1187/1280/1326 1485/1293/1339 1186/1278/1324 +f 1485/1293/1339 1199/1295/1341 1186/1278/1324 +f 1185/1279/1325 1186/1278/1324 1199/1295/1341 +f 1200/1296/1342 1185/1279/1325 1199/1295/1341 +f 1185/1279/1325 1200/1296/1342 1201/1297/1343 +f 1202/1298/1344 1201/1297/1343 1200/1296/1342 +f 1201/1297/1343 1202/1298/1344 1203/1299/1345 +f 1204/1300/1346 1203/1299/1345 1202/1298/1344 +f 1203/1299/1345 1204/1300/1346 1205/1301/1347 +f 1204/1300/1346 1206/1302/1348 1205/1301/1347 +f 1206/1302/1348 1204/1300/1346 1207/1303/1349 +f 1202/1298/1344 1207/1303/1349 1204/1300/1346 +f 1207/1303/1349 1202/1298/1344 1200/1296/1342 +f 1283/1304/1350 1207/1303/1349 1200/1296/1342 +f 1200/1296/1342 1275/1305/1351 1283/1304/1350 +f 1275/1305/1351 1200/1296/1342 1199/1295/1341 +f 1199/1295/1341 1489/1306/1352 1275/1305/1351 +f 1489/1306/1352 1199/1295/1341 1208/1307/1353 +f 1199/1295/1341 1485/1293/1339 1208/1307/1353 +f 1210/1308/1354 1206/1302/1348 1209/1309/1355 +f 1207/1303/1349 1209/1309/1355 1206/1302/1348 +f 1209/1309/1355 1207/1303/1349 1282/1310/1356 +f 1207/1303/1349 1283/1304/1350 1282/1310/1356 +f 1211/1311/1357 1205/1301/1347 1206/1302/1348 +f 1206/1302/1348 1210/1308/1354 1211/1311/1357 +f 1274/1312/1358 1211/1311/1357 1210/1308/1354 +f 1211/1311/1357 1274/1312/1358 1212/1313/1359 +f 1270/1314/1360 1212/1313/1359 1274/1312/1358 +f 1212/1313/1359 1270/1314/1360 1213/1315/1361 +f 1269/1316/1362 1213/1315/1361 1270/1314/1360 +f 1213/1315/1361 1269/1316/1362 1214/1317/1363 +f 1269/1316/1362 1215/1318/1364 1214/1317/1363 +f 1216/1319/1365 1214/1317/1363 1215/1318/1364 +f 1214/1317/1363 1216/1319/1365 1217/1320/1366 +f 1218/1321/1367 1217/1320/1366 1216/1319/1365 +f 1219/1322/1368 1217/1320/1366 1203/1299/1345 +f 1217/1320/1366 1219/1322/1368 1220/1323/1369 +f 1220/1323/1369 1214/1317/1363 1217/1320/1366 +f 1214/1317/1363 1220/1323/1369 1213/1315/1361 +f 1220/1323/1369 1212/1313/1359 1213/1315/1361 +f 1212/1313/1359 1220/1323/1369 1219/1322/1368 +f 1203/1299/1345 1212/1313/1359 1219/1322/1368 +f 1212/1313/1359 1203/1299/1345 1211/1311/1357 +f 1205/1301/1347 1211/1311/1357 1203/1299/1345 +f 1221/1324/1370 1216/1319/1365 1215/1318/1364 +f 1216/1319/1365 1221/1324/1370 1218/1321/1367 +f 1221/1324/1370 1222/1325/1371 1218/1321/1367 +f 1217/1320/1366 1218/1321/1367 1222/1325/1371 +f 1222/1325/1371 1223/1326/1372 1217/1320/1366 +f 1223/1326/1372 1203/1299/1345 1217/1320/1366 +f 1203/1299/1345 1223/1326/1372 1201/1297/1343 +f 1224/1327/1373 1201/1297/1343 1223/1326/1372 +f 1201/1297/1343 1224/1327/1373 1185/1279/1325 +f 1224/1327/1373 1184/1277/1323 1185/1279/1325 +f 1225/1328/1374 1224/1327/1373 1223/1326/1372 +f 1223/1326/1372 1222/1325/1371 1225/1328/1374 +f 1226/1329/1375 1225/1328/1374 1222/1325/1371 +f 1222/1325/1371 1227/1330/1376 1226/1329/1375 +f 1227/1330/1376 1222/1325/1371 1228/1331/1377 +f 1224/1327/1373 1229/1332/1378 1230/1333/1379 +f 1229/1332/1378 1224/1327/1373 1231/1334/1380 +f 1224/1327/1373 1225/1328/1374 1231/1334/1380 +f 1232/1335/1381 1231/1334/1380 1225/1328/1374 +f 1225/1328/1374 1226/1329/1375 1232/1335/1381 +f 1226/1329/1375 1233/1336/1382 1232/1335/1381 +f 1233/1336/1382 1226/1329/1375 1227/1330/1376 +f 1227/1330/1376 1234/1337/1383 1233/1336/1382 +f 1234/1337/1383 1227/1330/1376 1228/1331/1377 +f 1228/1331/1377 1235/1338/1384 1234/1337/1383 +f 1236/1339/1385 1233/1336/1382 1234/1337/1383 +f 1234/1337/1383 1237/1340/1386 1236/1339/1385 +f 1237/1340/1386 1234/1337/1383 1235/1338/1384 +f 1235/1338/1384 1866/1341/1387 1237/1340/1386 +f 1239/1342/1388 1236/1339/1385 1238/1343/1389 +f 1236/1339/1385 1239/1342/1388 1240/1344/1390 +f 1233/1336/1382 1236/1339/1385 1240/1344/1390 +f 1241/1345/1391 1233/1336/1382 1240/1344/1390 +f 1233/1336/1382 1241/1345/1391 1232/1335/1381 +f 1242/1346/1392 1232/1335/1381 1241/1345/1391 +f 1232/1335/1381 1242/1346/1392 1243/1347/1393 +f 1231/1334/1380 1232/1335/1381 1243/1347/1393 +f 1244/1348/1394 1231/1334/1380 1243/1347/1393 +f 1231/1334/1380 1244/1348/1394 1229/1332/1378 +f 1246/1349/1395 1239/1342/1388 1245/1350/1396 +f 1239/1342/1388 1246/1349/1395 1247/1351/1397 +f 1247/1351/1397 1240/1344/1390 1239/1342/1388 +f 1240/1344/1390 1247/1351/1397 1241/1345/1391 +f 1242/1346/1392 1248/1352/1398 1249/1353/1399 +f 1248/1352/1398 1242/1346/1392 1241/1345/1391 +f 1241/1345/1391 1250/1354/1400 1248/1352/1398 +f 1250/1354/1400 1241/1345/1391 1247/1351/1397 +f 1247/1351/1397 1251/1355/1401 1250/1354/1400 +f 1251/1355/1401 1247/1351/1397 1246/1349/1395 +f 1246/1349/1395 1252/1356/1402 1251/1355/1401 +f 1252/1356/1402 1246/1349/1395 1245/1350/1396 +f 1245/1350/1396 1238/1343/1389 1252/1356/1402 +f 1238/1343/1389 1245/1350/1396 1239/1342/1388 +f 1252/1356/1402 1250/1354/1400 1251/1355/1401 +f 1250/1354/1400 1252/1356/1402 1238/1343/1389 +f 1238/1343/1389 1248/1352/1398 1250/1354/1400 +f 1248/1352/1398 1238/1343/1389 1236/1339/1385 +f 1255/1357/1403 1253/1358/1404 1254/1359/1405 +f 1253/1358/1404 1255/1357/1403 1249/1353/1399 +f 1249/1353/1399 1256/1360/1406 1253/1358/1404 +f 1256/1360/1406 1249/1353/1399 1248/1352/1398 +f 1248/1352/1398 1257/1361/1407 1256/1360/1406 +f 1260/1362/1408 1258/1363/1409 1259/1364/1410 +f 1261/1365/1411 1259/1364/1410 1258/1363/1409 +f 1259/1364/1410 1261/1365/1411 1256/1360/1406 +f 1262/1366/1412 1256/1360/1406 1261/1365/1411 +f 1256/1360/1406 1262/1366/1412 1253/1358/1404 +f 1263/1367/1413 1253/1358/1404 1262/1366/1412 +f 1253/1358/1404 1263/1367/1413 1254/1359/1405 +f 1263/1367/1413 1264/1368/1414 1254/1359/1405 +f 1264/1368/1414 1255/1357/1403 1254/1359/1405 +f 1255/1357/1403 1264/1368/1414 1265/1369/1415 +f 1259/1364/1410 1266/1370/1416 1260/1362/1408 +f 1266/1370/1416 1259/1364/1410 1267/1371/1417 +f 1256/1360/1406 1267/1371/1417 1259/1364/1410 +f 1256/1360/1406 1268/1372/1418 1877/1373/1419 +f 1269/1374/1362 1256/1360/1406 1877/1373/1419 +f 1256/1360/1406 1269/1374/1362 1270/1375/1360 +f 1267/1371/1417 1256/1360/1406 1270/1375/1360 +f 1270/1375/1360 1879/1376/1420 1267/1371/1417 +f 1271/1377/1421 1267/1371/1417 1879/1376/1420 +f 1267/1371/1417 1271/1377/1421 1266/1370/1416 +f 1878/1378/1422 1266/1370/1416 1271/1377/1421 +f 1266/1370/1416 1878/1378/1422 1260/1362/1408 +f 1258/1363/1409 1260/1362/1408 1878/1378/1422 +f 1879/1376/1420 1270/1375/1360 1274/1379/1358 +f 1261/1365/1411 1272/1380/1423 1273/1381/1424 +f 1272/1380/1423 1261/1365/1411 1209/1382/1355 +f 1261/1365/1411 1210/1383/1354 1209/1382/1355 +f 1210/1383/1354 1261/1365/1411 1274/1379/1358 +f 1258/1363/1409 1274/1379/1358 1261/1365/1411 +f 1274/1379/1358 1258/1363/1409 1879/1376/1420 +f 1878/1378/1422 1879/1376/1420 1258/1363/1409 +f 1275/1384/1351 1261/1365/1411 1283/1385/1350 +f 1261/1365/1411 1275/1384/1351 1262/1366/1412 +f 1278/1386/1425 1276/1387/1426 1277/1388/1427 +f 1276/1387/1426 1278/1386/1425 1279/1389/1428 +f 1272/1380/1423 1279/1389/1428 1278/1386/1425 +f 1279/1389/1428 1272/1380/1423 1280/1390/1429 +f 1209/1382/1355 1280/1390/1429 1272/1380/1423 +f 1280/1390/1429 1209/1382/1355 1282/1391/1356 +f 1282/1391/1356 1281/1392/1430 1280/1390/1429 +f 1281/1392/1430 1282/1391/1356 1283/1385/1350 +f 1283/1385/1350 1273/1381/1424 1281/1392/1430 +f 1273/1381/1424 1283/1385/1350 1261/1365/1411 +f 1278/1386/1425 1273/1381/1424 1272/1380/1423 +f 1273/1381/1424 1278/1386/1425 1277/1388/1427 +f 1277/1388/1427 1281/1392/1430 1273/1381/1424 +f 1281/1392/1430 1277/1388/1427 1276/1387/1426 +f 1276/1387/1426 1280/1390/1429 1281/1392/1430 +f 1280/1390/1429 1276/1387/1426 1279/1389/1428 +f 1909/1157/1167 1854/1225/1215 524/563/600 +f 1286/1393/1431 1284/1394/1432 1285/1395/1433 +f 1287/1396/1434 1285/1395/1433 1284/1394/1432 +f 1285/1395/1433 1287/1396/1434 1288/1397/1435 +f 1289/1398/1436 1288/1397/1435 1287/1396/1434 +f 1288/1397/1435 1289/1398/1436 1290/1399/1437 +f 178/200/191 179/201/192 1286/1393/1431 +f 1284/1394/1432 1286/1393/1431 179/201/192 +f 179/201/192 184/206/197 1284/1394/1432 +f 186/208/199 1284/1394/1432 184/206/197 +f 1284/1394/1432 186/208/199 1287/1396/1434 +f 190/214/205 1287/1396/1434 186/208/199 +f 1287/1396/1434 190/214/205 1289/1398/1436 +f 190/214/205 198/222/213 1289/1398/1436 +f 198/222/213 1290/1399/1437 1289/1398/1436 +f 1290/1399/1437 198/222/213 199/224/215 +f 1291/1400/1438 1290/1399/1437 199/224/215 +f 200/223/214 196/220/211 209/239/230 +f 209/239/230 214/245/236 200/223/214 +f 199/224/215 200/223/214 214/245/236 +f 215/246/237 199/224/215 214/245/236 +f 199/224/215 215/246/237 1291/1400/1438 +f 217/248/239 1291/1400/1438 215/246/237 +f 1291/1400/1438 217/248/239 1292/1401/1439 +f 1293/1402/1440 1292/1401/1439 217/248/239 +f 219/251/242 1293/1402/1440 217/248/239 +f 1293/1402/1440 219/251/242 240/270/261 +f 1290/1399/1437 1291/1400/1438 1294/1403/1441 +f 1291/1400/1438 1295/1404/1442 1294/1403/1441 +f 1295/1404/1442 1291/1400/1438 1292/1401/1439 +f 1296/1405/1443 1295/1404/1442 1292/1401/1439 +f 1292/1401/1439 1293/1402/1440 1296/1405/1443 +f 1871/1406/1444 1296/1405/1443 1293/1402/1440 +f 240/270/261 1871/1406/1444 1293/1402/1440 +f 1871/1406/1444 240/270/261 1297/1407/1212 +f 240/270/261 244/275/266 1297/1407/1212 +f 244/275/266 240/270/261 239/269/260 +f 1296/1405/1443 1871/1406/1444 1642/1408/1445 +f 1642/1408/1445 1298/1409/1446 1296/1405/1443 +f 1295/1404/1442 1296/1405/1443 1298/1409/1446 +f 1298/1409/1446 1642/1408/1445 1641/1410/1447 +f 244/275/266 245/274/265 1301/1411/1211 +f 1301/1411/1211 1299/1412/1448 1300/1413/1210 +f 1299/1412/1448 1301/1411/1211 245/274/265 +f 245/274/265 246/276/267 1299/1412/1448 +f 87/98/93 1094/97/92 1095/1414/1208 +f 1095/1414/1208 1302/1415/1449 87/98/93 +f 1302/1415/1449 1095/1414/1208 1096/1416/1209 +f 1096/1416/1209 1303/1417/1450 1302/1415/1449 +f 1303/1417/1450 1096/1416/1209 1300/1413/1210 +f 1299/1412/1448 1303/1417/1450 1300/1413/1210 +f 1303/1417/1450 1299/1412/1448 1304/1418/1451 +f 246/276/267 1304/1418/1451 1299/1412/1448 +f 1304/1418/1451 246/276/267 259/291/282 +f 247/277/268 259/291/282 246/276/267 +f 88/99/94 87/98/93 1302/1415/1449 +f 1302/1415/1449 1305/1419/1452 88/99/94 +f 1305/1419/1452 1302/1415/1449 1303/1417/1450 +f 1303/1417/1450 1306/1420/1453 1305/1419/1452 +f 1306/1420/1453 1303/1417/1450 1304/1418/1451 +f 1304/1418/1451 1307/1421/1454 1306/1420/1453 +f 1307/1421/1454 1304/1418/1451 259/291/282 +f 258/292/283 1307/1421/1454 259/291/282 +f 1307/1421/1454 258/292/283 264/297/288 +f 260/293/284 264/297/288 258/292/283 +f 88/99/94 1308/1422/1455 1309/1423/1456 +f 1308/1422/1455 88/99/94 1305/1419/1452 +f 1305/1419/1452 151/169/160 1308/1422/1455 +f 151/169/160 1305/1419/1452 1306/1420/1453 +f 1306/1420/1453 152/170/161 151/169/160 +f 152/170/161 1306/1420/1453 1307/1421/1454 +f 1307/1421/1454 153/171/162 152/170/161 +f 153/171/162 1307/1421/1454 264/297/288 +f 158/177/168 153/171/162 264/297/288 +f 153/171/162 158/177/168 156/174/165 +f 1312/1424/1457 1310/1425/1458 1311/1426/1459 +f 1310/1425/1458 1312/1424/1457 1313/1427/1460 +f 1313/1427/1460 72/81/76 1310/1425/1458 +f 72/81/76 1313/1427/1460 67/76/71 +f 1313/1427/1460 1314/1428/1461 67/76/71 +f 68/77/72 67/76/71 1314/1428/1461 +f 1309/1423/1456 68/77/72 1314/1428/1461 +f 68/77/72 1309/1423/1456 1308/1422/1455 +f 1308/1422/1455 61/69/64 68/77/72 +f 61/69/64 1308/1422/1455 151/169/160 +f 1314/1428/1461 1313/1427/1460 1312/1424/1457 +f 1311/1426/1459 1314/1428/1461 1312/1424/1457 +f 1316/1429/1462 72/81/76 1315/1430/1463 +f 72/81/76 1316/1429/1462 1310/1425/1458 +f 1317/1431/1464 1310/1425/1458 1316/1429/1462 +f 1310/1425/1458 1317/1431/1464 1311/1426/1459 +f 1318/1432/1465 1311/1426/1459 1317/1431/1464 +f 1311/1426/1459 1318/1432/1465 1319/1433/1466 +f 1314/1428/1461 1311/1426/1459 1319/1433/1466 +f 1320/1434/1467 1314/1428/1461 1319/1433/1466 +f 1314/1428/1461 1320/1434/1467 1309/1423/1456 +f 1320/1434/1467 88/99/94 1309/1423/1456 +f 1319/1433/1466 1321/1435/1468 1320/1434/1467 +f 1321/1435/1468 1319/1433/1466 1318/1432/1465 +f 88/99/94 1320/1434/1467 76/86/81 +f 1320/1434/1467 1322/1436/1469 76/86/81 +f 1322/1436/1469 1320/1434/1467 1321/1435/1468 +f 1323/1437/1470 1322/1436/1469 1321/1435/1468 +f 1321/1435/1468 1324/1438/1471 1323/1437/1470 +f 1324/1438/1471 1321/1435/1468 1318/1432/1465 +f 1318/1432/1465 1325/1439/1472 1324/1438/1471 +f 1325/1439/1472 1318/1432/1465 1317/1431/1464 +f 1317/1431/1464 1326/1440/1473 1325/1439/1472 +f 1326/1440/1473 1317/1431/1464 1316/1429/1462 +f 1316/1429/1462 1327/1441/1474 1326/1440/1473 +f 1327/1441/1474 1316/1429/1462 1315/1430/1463 +f 1315/1430/1463 1328/1442/1475 1327/1441/1474 +f 1328/1442/1475 1315/1430/1463 1329/1443/1476 +f 1329/1443/1476 1330/1444/1477 1328/1442/1475 +f 1330/1444/1477 1329/1443/1476 1331/1445/1478 +f 1331/1445/1478 1332/1446/1479 1330/1444/1477 +f 1332/1446/1479 1331/1445/1478 1333/1447/1480 +f 1333/1447/1480 1334/1448/1481 1332/1446/1479 +f 1334/1448/1481 1333/1447/1480 1335/1449/1482 +f 1335/1449/1482 1336/1450/1483 1334/1448/1481 +f 1336/1450/1483 1335/1449/1482 1322/1436/1469 +f 1322/1436/1469 1323/1437/1470 1336/1450/1483 +f 1335/1449/1482 76/86/81 1322/1436/1469 +f 76/86/81 1335/1449/1482 77/87/82 +f 1333/1447/1480 77/87/82 1335/1449/1482 +f 77/87/82 1333/1447/1480 75/84/79 +f 1331/1445/1478 75/84/79 1333/1447/1480 +f 75/84/79 1331/1445/1478 73/82/77 +f 1329/1443/1476 73/82/77 1331/1445/1478 +f 73/82/77 1329/1443/1476 71/80/75 +f 1315/1430/1463 71/80/75 1329/1443/1476 +f 71/80/75 1315/1430/1463 72/81/76 +f 1339/1451/1484 1337/1452/1485 1338/1453/1486 +f 1337/1452/1485 1339/1451/1484 1340/1454/1487 +f 1341/1455/1488 1340/1454/1487 1339/1451/1484 +f 1344/1456/1489 1342/1457/1490 1343/1458/1491 +f 1343/1458/1491 1546/1459/1492 1344/1456/1489 +f 1341/1455/1488 1344/1456/1489 1546/1459/1492 +f 1509/1460/1493 1341/1455/1488 1546/1459/1492 +f 1341/1455/1488 1509/1460/1493 1345/1461/1494 +f 1340/1454/1487 1341/1455/1488 1345/1461/1494 +f 1345/1461/1494 1893/1462/1495 1340/1454/1487 +f 1346/1463/1496 1340/1454/1487 1893/1462/1495 +f 1340/1454/1487 1346/1463/1496 1337/1452/1485 +f 1892/1464/1497 1337/1452/1485 1346/1463/1496 +f 1546/1459/1492 1343/1458/1491 1547/1465/1498 +f 1893/1462/1495 1345/1461/1494 1870/1466/1499 +f 1892/1464/1497 1893/1462/1495 1347/1467/1500 +f 1870/1466/1499 1347/1467/1500 1893/1462/1495 +f 1347/1467/1500 1870/1466/1499 1348/1468/1501 +f 1349/1469/1502 1348/1468/1501 1870/1466/1499 +f 1348/1468/1501 1349/1469/1502 1350/1470/1503 +f 1351/1471/1504 1348/1468/1501 1350/1470/1503 +f 1350/1470/1503 1352/1472/1505 1351/1471/1504 +f 1353/1473/1506 1351/1471/1504 1352/1472/1505 +f 1352/1472/1505 1350/1470/1503 1520/1474/1507 +f 1520/1474/1507 1354/1475/1508 1352/1472/1505 +f 1355/1476/1509 1352/1472/1505 1354/1475/1508 +f 1352/1472/1505 1355/1476/1509 1353/1473/1506 +f 1355/1476/1509 1356/1477/1510 1353/1473/1506 +f 1351/1471/1504 1353/1473/1506 1356/1477/1510 +f 1356/1477/1510 1357/1478/1511 1351/1471/1504 +f 1348/1468/1501 1351/1471/1504 1357/1478/1511 +f 1357/1478/1511 1519/1479/1512 1348/1468/1501 +f 1518/1480/1513 1348/1468/1501 1519/1479/1512 +f 1348/1468/1501 1518/1480/1513 1358/1481/1514 +f 1356/1477/1510 1355/1476/1509 1359/1482/1515 +f 1357/1478/1511 1356/1477/1510 1359/1482/1515 +f 1359/1482/1515 1354/1475/1508 1357/1478/1511 +f 1519/1479/1512 1357/1478/1511 1354/1475/1508 +f 1354/1475/1508 1520/1474/1507 1519/1479/1512 +f 1354/1475/1508 1359/1482/1515 1355/1476/1509 +f 1518/1480/1513 1360/1483/1516 1358/1481/1514 +f 1361/1484/1517 1358/1481/1514 1360/1483/1516 +f 1360/1483/1516 1362/1485/1518 1361/1484/1517 +f 1362/1485/1518 1363/1486/1519 1361/1484/1517 +f 1358/1481/1514 1361/1484/1517 1363/1486/1519 +f 1337/1452/1485 1892/1464/1497 1338/1453/1486 +f 1347/1467/1500 1338/1453/1486 1892/1464/1497 +f 1338/1453/1486 1347/1467/1500 1339/1451/1484 +f 1348/1468/1501 1339/1451/1484 1347/1467/1500 +f 1339/1451/1484 1348/1468/1501 1341/1455/1488 +f 1358/1481/1514 1341/1455/1488 1348/1468/1501 +f 1341/1455/1488 1358/1481/1514 1364/1487/1520 +f 1363/1486/1519 1364/1487/1520 1358/1481/1514 +f 1364/1487/1520 1363/1486/1519 1365/1488/1521 +f 1363/1486/1519 1362/1485/1518 1365/1488/1521 +f 1366/1489/1522 1341/1455/1488 1364/1487/1520 +f 1364/1487/1520 1367/1490/1523 1366/1489/1522 +f 1367/1490/1523 1364/1487/1520 1365/1488/1521 +f 1362/1485/1518 1367/1490/1523 1365/1488/1521 +f 1367/1490/1523 1362/1485/1518 1368/1491/1524 +f 1368/1491/1524 1366/1489/1522 1367/1490/1523 +f 1366/1489/1522 1368/1491/1524 1369/1492/1525 +f 1362/1485/1518 1369/1492/1525 1368/1491/1524 +f 1369/1492/1525 1362/1485/1518 1370/1493/1526 +f 1362/1485/1518 1360/1483/1516 1370/1493/1526 +f 1371/1494/1527 1370/1493/1526 1360/1483/1516 +f 1360/1483/1516 1518/1480/1513 1371/1494/1527 +f 1517/1495/1528 1371/1494/1527 1518/1480/1513 +f 1374/1496/1529 1372/1497/1530 1373/1498/1531 +f 1523/1499/1532 1373/1498/1531 1372/1497/1530 +f 1375/1500/1533 1523/1499/1532 1372/1497/1530 +f 1523/1499/1532 1375/1500/1533 1521/1501/1534 +f 1375/1500/1533 1517/1495/1528 1521/1501/1534 +f 1517/1495/1528 1375/1500/1533 1376/1502/1535 +f 1371/1494/1527 1517/1495/1528 1376/1502/1535 +f 1376/1502/1535 1377/1503/1536 1371/1494/1527 +f 1370/1493/1526 1371/1494/1527 1377/1503/1536 +f 1378/1504/1537 1370/1493/1526 1377/1503/1536 +f 1379/1505/1538 1376/1502/1535 1375/1500/1533 +f 1375/1500/1533 1380/1506/1539 1379/1505/1538 +f 1380/1506/1539 1375/1500/1533 1372/1497/1530 +f 1372/1497/1530 1374/1496/1529 1380/1506/1539 +f 1374/1496/1529 1381/1507/1540 1382/1508/1541 +f 1382/1508/1541 1380/1506/1539 1374/1496/1529 +f 1380/1506/1539 1382/1508/1541 1383/1509/1542 +f 1384/1510/1543 1380/1506/1539 1383/1509/1542 +f 1380/1506/1539 1384/1510/1543 1379/1505/1538 +f 1385/1511/1544 1379/1505/1538 1384/1510/1543 +f 1379/1505/1538 1385/1511/1544 1386/1512/1545 +f 1385/1511/1544 1377/1503/1536 1386/1512/1545 +f 1377/1503/1536 1376/1502/1535 1386/1512/1545 +f 1376/1502/1535 1379/1505/1538 1386/1512/1545 +f 1384/1510/1543 1387/1513/1546 1385/1511/1544 +f 1389/1514/1547 1388/1515/1548 1387/1513/1546 +f 1378/1504/1537 1387/1513/1546 1388/1515/1548 +f 1387/1513/1546 1378/1504/1537 1385/1511/1544 +f 1377/1503/1536 1385/1511/1544 1378/1504/1537 +f 1392/1516/1549 1390/1517/1550 1391/1518/1551 +f 1390/1517/1550 1392/1516/1549 1389/1514/1547 +f 1389/1514/1547 1393/1519/1552 1390/1517/1550 +f 1393/1519/1552 1389/1514/1547 1387/1513/1546 +f 1394/1520/1553 1393/1519/1552 1387/1513/1546 +f 1387/1513/1546 1384/1510/1543 1394/1520/1553 +f 1384/1510/1543 1395/1521/1554 1394/1520/1553 +f 1395/1521/1554 1384/1510/1543 1383/1509/1542 +f 1383/1509/1542 1396/1522/1555 1395/1521/1554 +f 1396/1522/1555 1383/1509/1542 1382/1508/1541 +f 1382/1508/1541 1397/1523/1556 1396/1522/1555 +f 1397/1523/1556 1382/1508/1541 1381/1507/1540 +f 1381/1507/1540 1398/1524/1557 1397/1523/1556 +f 1400/1525/1558 1398/1524/1557 1399/1526/1559 +f 1398/1524/1557 1400/1525/1558 1401/1527/1560 +f 1401/1527/1560 1397/1523/1556 1398/1524/1557 +f 1397/1523/1556 1401/1527/1560 1402/1528/1561 +f 1402/1528/1561 1396/1522/1555 1397/1523/1556 +f 1396/1522/1555 1402/1528/1561 1403/1529/1562 +f 1403/1529/1562 1395/1521/1554 1396/1522/1555 +f 1395/1521/1554 1403/1529/1562 1404/1530/1563 +f 1405/1531/1564 1395/1521/1554 1404/1530/1563 +f 1404/1530/1563 1406/1532/1565 1405/1531/1564 +f 1409/1533/1566 1407/1534/1567 1408/1535/1568 +f 1410/1536/1569 1409/1533/1566 1408/1535/1568 +f 1408/1535/1568 1400/1525/1558 1410/1536/1569 +f 1400/1525/1558 1408/1535/1568 1411/1537/1570 +f 1411/1537/1570 1401/1527/1560 1400/1525/1558 +f 1401/1527/1560 1411/1537/1570 1412/1538/1571 +f 1412/1538/1571 1402/1528/1561 1401/1527/1560 +f 1402/1528/1561 1412/1538/1571 1413/1539/1572 +f 1413/1539/1572 1403/1529/1562 1402/1528/1561 +f 1414/1540/1573 1408/1535/1568 1407/1534/1567 +f 1408/1535/1568 1414/1540/1573 1411/1537/1570 +f 1415/1541/1574 1411/1537/1570 1414/1540/1573 +f 1411/1537/1570 1415/1541/1574 1412/1538/1571 +f 1415/1541/1574 1413/1539/1572 1412/1538/1571 +f 1417/1542/1575 1416/1543/1576 1415/1541/1574 +f 1414/1540/1573 1417/1542/1575 1415/1541/1574 +f 1417/1542/1575 1414/1540/1573 1562/1544/1577 +f 1407/1534/1567 1562/1544/1577 1414/1540/1573 +f 1562/1544/1577 1407/1534/1567 1561/1545/1578 +f 1418/1546/1579 1561/1545/1578 1407/1534/1567 +f 1407/1534/1567 1409/1533/1566 1418/1546/1579 +f 1409/1533/1566 1419/1547/1580 1418/1546/1579 +f 1419/1547/1580 1409/1533/1566 1420/1548/1581 +f 1420/1548/1581 1421/1549/1582 1419/1547/1580 +f 1422/1550/1583 1420/1548/1581 1409/1533/1566 +f 1561/1545/1578 1418/1546/1579 1423/1551/1584 +f 1425/1552/1585 1424/1553/1586 1420/1548/1581 +f 1420/1548/1581 1422/1550/1583 1425/1552/1585 +f 1426/1554/1587 1425/1552/1585 1422/1550/1583 +f 1421/1549/1582 1420/1548/1581 1424/1553/1586 +f 1424/1553/1586 1427/1555/1588 1421/1549/1582 +f 1427/1555/1588 1424/1553/1586 1428/1556/1589 +f 1428/1556/1589 1429/1557/1590 1427/1555/1588 +f 1430/1558/1591 1428/1556/1589 1424/1553/1586 +f 1424/1553/1586 1425/1552/1585 1430/1558/1591 +f 1431/1559/1592 1430/1558/1591 1425/1552/1585 +f 1425/1552/1585 1426/1554/1587 1431/1559/1592 +f 1432/1560/1593 1431/1559/1592 1426/1554/1587 +f 1429/1557/1590 1428/1556/1589 1433/1561/1594 +f 1434/1562/1595 1433/1561/1594 1428/1556/1589 +f 1428/1556/1589 1430/1558/1591 1434/1562/1595 +f 1435/1563/1596 1434/1562/1595 1430/1558/1591 +f 1430/1558/1591 1431/1559/1592 1435/1563/1596 +f 1007/1113/1131 1435/1563/1596 1431/1559/1592 +f 1431/1559/1592 1432/1560/1593 1007/1113/1131 +f 1008/1114/1132 1007/1113/1131 1432/1560/1593 +f 1432/1560/1593 1011/1117/1135 1008/1114/1132 +f 1011/1117/1135 1432/1560/1593 1012/1118/1136 +f 1435/1563/1596 1007/1113/1131 1004/1111/1129 +f 1004/1111/1129 1005/1110/1128 1435/1563/1596 +f 1434/1562/1595 1435/1563/1596 1005/1110/1128 +f 1005/1110/1128 1436/1564/1597 1434/1562/1595 +f 1433/1561/1594 1434/1562/1595 1436/1564/1597 +f 1436/1564/1597 1437/1565/1598 1433/1561/1594 +f 1438/1566/1599 1433/1561/1594 1437/1565/1598 +f 1437/1565/1598 1439/1567/1600 1438/1566/1599 +f 1440/1568/1601 1438/1566/1599 1439/1567/1600 +f 1438/1566/1599 1440/1568/1601 1441/1569/1602 +f 1443/1570/1603 1440/1568/1601 1442/1571/1604 +f 1440/1568/1601 1444/1572/1605 1442/1571/1604 +f 1444/1572/1605 1440/1568/1601 1439/1567/1600 +f 994/1098/1116 1444/1572/1605 1439/1567/1600 +f 1439/1567/1600 1437/1565/1598 994/1098/1116 +f 992/1099/1117 994/1098/1116 1437/1565/1598 +f 1437/1565/1598 1436/1564/1597 992/1099/1117 +f 1000/1106/1124 992/1099/1117 1436/1564/1597 +f 1436/1564/1597 1005/1110/1128 1000/1106/1124 +f 1001/1107/1125 1000/1106/1124 1005/1110/1128 +f 1444/1572/1605 994/1098/1116 995/1101/1119 +f 988/1094/1112 987/1093/1111 1445/1573/1606 +f 1445/1573/1606 1446/1574/1607 988/1094/1112 +f 995/1101/1119 988/1094/1112 1446/1574/1607 +f 1447/1575/1608 995/1101/1119 1446/1574/1607 +f 995/1101/1119 1447/1575/1608 1444/1572/1605 +f 1447/1575/1608 1442/1571/1604 1444/1572/1605 +f 1442/1571/1604 1447/1575/1608 1448/1576/1609 +f 1449/1577/1610 1448/1576/1609 1447/1575/1608 +f 1448/1576/1609 1449/1577/1610 1450/1578/1611 +f 1451/1579/1612 1450/1578/1611 1449/1577/1610 +f 1446/1574/1607 1445/1573/1606 1452/1580/1613 +f 1452/1580/1613 1447/1575/1608 1446/1574/1607 +f 1447/1575/1608 1452/1580/1613 1449/1577/1610 +f 1452/1580/1613 1451/1579/1612 1449/1577/1610 +f 1450/1578/1611 1451/1579/1612 1453/1581/1614 +f 1451/1579/1612 1454/1582/1615 1453/1581/1614 +f 1454/1582/1615 1451/1579/1612 720/1583/834 +f 1455/1584/836 1454/1582/1615 720/1583/834 +f 1454/1582/1615 1455/1584/836 1456/1585/1616 +f 1458/1586/1617 1456/1585/1616 1457/1587/1618 +f 1456/1585/1616 1458/1586/1617 1454/1582/1615 +f 1459/1588/1619 1454/1582/1615 1458/1586/1617 +f 1454/1582/1615 1459/1588/1619 1453/1581/1614 +f 1460/1589/1620 1453/1581/1614 1459/1588/1619 +f 1453/1581/1614 1460/1589/1620 1450/1578/1611 +f 1461/1590/1621 1450/1578/1611 1460/1589/1620 +f 1450/1578/1611 1461/1590/1621 1448/1576/1609 +f 1443/1570/1603 1448/1576/1609 1461/1590/1621 +f 1448/1576/1609 1443/1570/1603 1442/1571/1604 +f 1460/1589/1620 1462/1591/1622 1461/1590/1621 +f 1462/1591/1622 1460/1589/1620 1463/1592/1623 +f 1459/1588/1619 1463/1592/1623 1460/1589/1620 +f 1463/1592/1623 1459/1588/1619 1464/1593/1624 +f 1458/1586/1617 1464/1593/1624 1459/1588/1619 +f 1464/1593/1624 1458/1586/1617 1192/1285/1331 +f 1457/1587/1618 1192/1285/1331 1458/1586/1617 +f 1192/1285/1331 1457/1587/1618 1848/1594/1625 +f 1848/1594/1625 1190/1283/1329 1192/1285/1331 +f 1190/1283/1329 1848/1594/1625 1194/1287/1333 +f 1192/1285/1331 1191/1284/1330 1464/1593/1624 +f 1465/1595/1626 1464/1593/1624 1191/1284/1330 +f 1464/1593/1624 1465/1595/1626 1463/1592/1623 +f 1466/1596/1627 1463/1592/1623 1465/1595/1626 +f 1463/1592/1623 1466/1596/1627 1462/1591/1622 +f 1467/1597/1628 1462/1591/1622 1466/1596/1627 +f 1462/1591/1622 1467/1597/1628 1468/1598/1629 +f 1469/1599/1630 1468/1598/1629 1467/1597/1628 +f 1468/1598/1629 1469/1599/1630 1470/1600/1631 +f 1471/1601/1632 1470/1600/1631 1469/1599/1630 +f 1466/1596/1627 1472/1602/1633 1467/1597/1628 +f 1473/1603/1634 1467/1597/1628 1472/1602/1633 +f 1467/1597/1628 1473/1603/1634 1469/1599/1630 +f 1474/1604/1635 1469/1599/1630 1473/1603/1634 +f 1469/1599/1630 1474/1604/1635 1471/1601/1632 +f 1483/1605/1334 1471/1601/1632 1474/1604/1635 +f 1471/1601/1632 1483/1605/1334 1194/1606/1333 +f 1848/1607/1625 1471/1601/1632 1194/1606/1333 +f 1243/1347/1393 1475/1608/1636 1244/1348/1394 +f 1475/1608/1636 1472/1602/1633 1244/1348/1394 +f 1472/1602/1633 1475/1608/1636 1473/1603/1634 +f 1475/1608/1636 1474/1604/1635 1473/1603/1634 +f 1265/1369/1415 1249/1353/1399 1255/1357/1403 +f 1249/1353/1399 1265/1369/1415 1476/1609/1637 +f 1476/1609/1637 1242/1346/1392 1249/1353/1399 +f 1242/1346/1392 1476/1609/1637 1477/1610/1638 +f 1477/1610/1638 1243/1347/1393 1242/1346/1392 +f 1243/1347/1393 1477/1610/1638 1478/1611/1639 +f 1475/1608/1636 1243/1347/1393 1478/1611/1639 +f 1478/1611/1639 1479/1612/1640 1475/1608/1636 +f 1474/1604/1635 1475/1608/1636 1479/1612/1640 +f 1479/1612/1640 1480/1613/1641 1474/1604/1635 +f 1479/1612/1640 1478/1611/1639 1481/1614/1642 +f 1480/1613/1641 1479/1612/1640 1482/1615/1643 +f 1480/1613/1641 1483/1605/1334 1474/1604/1635 +f 1483/1605/1334 1480/1613/1641 1484/1616/1335 +f 1482/1615/1643 1484/1616/1335 1480/1613/1641 +f 1484/1616/1335 1482/1615/1643 1197/1617/1338 +f 1482/1615/1643 1485/1618/1339 1197/1617/1338 +f 1485/1618/1339 1482/1615/1643 1479/1612/1640 +f 1479/1612/1640 1208/1619/1353 1485/1618/1339 +f 1208/1619/1353 1479/1612/1640 1481/1614/1642 +f 1486/1620/1644 1208/1619/1353 1481/1614/1642 +f 1478/1611/1639 1486/1620/1644 1481/1614/1642 +f 1486/1620/1644 1478/1611/1639 1477/1610/1638 +f 1477/1610/1638 1487/1621/1645 1486/1620/1644 +f 1487/1621/1645 1477/1610/1638 1476/1609/1637 +f 1476/1609/1637 1264/1368/1414 1487/1621/1645 +f 1264/1368/1414 1476/1609/1637 1265/1369/1415 +f 1208/1619/1353 1486/1620/1644 1489/1622/1352 +f 1487/1621/1645 1489/1622/1352 1486/1620/1644 +f 1489/1622/1352 1487/1621/1645 1488/1623/1646 +f 1264/1368/1414 1488/1623/1646 1487/1621/1645 +f 1488/1623/1646 1264/1368/1414 1490/1624/1647 +f 1264/1368/1414 1263/1367/1413 1490/1624/1647 +f 1262/1366/1412 1490/1624/1647 1263/1367/1413 +f 1490/1624/1647 1262/1366/1412 1488/1623/1646 +f 1275/1384/1351 1488/1623/1646 1262/1366/1412 +f 1488/1623/1646 1275/1384/1351 1489/1622/1352 +f 257/564/281 1854/1225/1215 267/1625/291 +f 1493/1626/1648 1491/1627/1649 1492/1628/1650 +f 1491/1627/1649 1493/1626/1648 1494/1629/1651 +f 1492/1628/1650 1495/1630/1652 1496/1631/1653 +f 1497/1632/1654 1492/1628/1650 1496/1631/1653 +f 1492/1628/1650 1497/1632/1654 1493/1626/1648 +f 1498/1633/1655 1493/1626/1648 1497/1632/1654 +f 1493/1626/1648 1498/1633/1655 1494/1629/1651 +f 1499/1634/1656 1494/1629/1651 1498/1633/1655 +f 1494/1629/1651 1499/1634/1656 1491/1627/1649 +f 1500/1635/1657 1491/1627/1649 1499/1634/1656 +f 1491/1627/1649 1500/1635/1657 1501/1636/1658 +f 1500/1635/1657 1502/1637/1659 1501/1636/1658 +f 1501/1636/1658 1503/1638/1660 1491/1627/1649 +f 1503/1638/1660 1501/1636/1658 1502/1637/1659 +f 1502/1637/1659 1504/1639/1661 1503/1638/1660 +f 1504/1639/1661 1505/1640/1662 1503/1638/1660 +f 1506/1641/1663 1503/1638/1660 1505/1640/1662 +f 1502/1637/1659 1500/1635/1657 1507/1642/1664 +f 1504/1639/1661 1502/1637/1659 1507/1642/1664 +f 1509/1643/1493 1508/1644/1665 1504/1639/1661 +f 1505/1640/1662 1504/1639/1661 1508/1644/1665 +f 1510/1645/1666 1505/1640/1662 1508/1644/1665 +f 1505/1640/1662 1510/1645/1666 1506/1641/1663 +f 1510/1645/1666 1391/1518/1551 1506/1641/1663 +f 1503/1638/1660 1506/1641/1663 1391/1518/1551 +f 1391/1518/1551 1511/1646/1667 1503/1638/1660 +f 1511/1646/1667 1491/1627/1649 1503/1638/1660 +f 1491/1627/1649 1511/1646/1667 1495/1630/1652 +f 1495/1630/1652 1492/1628/1650 1491/1627/1649 +f 1512/1647/1668 1496/1631/1653 1495/1630/1652 +f 1495/1630/1652 1513/1648/1669 1512/1647/1668 +f 1513/1648/1669 1495/1630/1652 1511/1646/1667 +f 1391/1518/1551 1510/1645/1666 1514/1649/1670 +f 1514/1649/1670 1515/1650/1671 1391/1518/1551 +f 1513/1648/1669 1405/1531/1564 1406/1532/1565 +f 1516/1651/1672 1513/1648/1669 1406/1532/1565 +f 1513/1648/1669 1516/1651/1672 1512/1647/1668 +f 1521/1652/1534 1512/1647/1668 1516/1651/1672 +f 1512/1647/1668 1521/1652/1534 1517/1653/1528 +f 1496/1631/1653 1512/1647/1668 1517/1653/1528 +f 1518/1654/1513 1496/1631/1653 1517/1653/1528 +f 1496/1631/1653 1518/1654/1513 1519/1655/1512 +f 1519/1655/1512 1497/1632/1654 1496/1631/1653 +f 1497/1632/1654 1519/1655/1512 1520/1656/1507 +f 1516/1651/1672 1523/1657/1532 1521/1652/1534 +f 1523/1657/1532 1516/1651/1672 1522/1658/1673 +f 1406/1532/1565 1522/1658/1673 1516/1651/1672 +f 1522/1658/1673 1406/1532/1565 1524/1659/1674 +f 1406/1532/1565 1404/1530/1563 1524/1659/1674 +f 1404/1530/1563 1525/1660/1675 1524/1659/1674 +f 1525/1660/1675 1404/1530/1563 1403/1529/1562 +f 1403/1529/1562 1413/1539/1572 1525/1660/1675 +f 1416/1543/1576 1525/1660/1675 1413/1539/1572 +f 1413/1539/1572 1415/1541/1574 1416/1543/1576 +f 1416/1543/1576 1417/1542/1575 1551/1661/1676 +f 1551/1661/1676 1526/1662/1677 1416/1543/1576 +f 1525/1660/1675 1416/1543/1576 1526/1662/1677 +f 1526/1662/1677 1524/1659/1674 1525/1660/1675 +f 1524/1659/1674 1526/1662/1677 1522/1658/1673 +f 1550/1663/1678 1522/1658/1673 1526/1662/1677 +f 1522/1658/1673 1550/1663/1678 1523/1657/1532 +f 1526/1662/1677 1551/1661/1676 1550/1663/1678 +f 1388/1515/1548 1389/1514/1547 1527/1664/1679 +f 1528/1665/1680 1527/1664/1679 1389/1514/1547 +f 1392/1516/1549 1528/1665/1680 1389/1514/1547 +f 1528/1665/1680 1392/1516/1549 1529/1666/1681 +f 1529/1666/1681 1530/1667/1682 1528/1665/1680 +f 1531/1668/1683 1528/1665/1680 1530/1667/1682 +f 1528/1665/1680 1531/1668/1683 1532/1669/1684 +f 1531/1668/1683 1533/1670/1685 1532/1669/1684 +f 1534/1671/1686 1532/1669/1684 1533/1670/1685 +f 1533/1670/1685 1535/1672/1687 1534/1671/1686 +f 1530/1667/1682 1890/1673/1688 1531/1668/1683 +f 1527/1664/1679 1528/1665/1680 1532/1669/1684 +f 1532/1669/1684 1534/1671/1686 1527/1664/1679 +f 1536/1674/1689 1527/1664/1679 1534/1671/1686 +f 1534/1671/1686 1537/1675/1690 1536/1674/1689 +f 1527/1664/1679 1536/1674/1689 1889/1676/1691 +f 1889/1676/1691 1388/1515/1548 1527/1664/1679 +f 1537/1675/1690 1534/1671/1686 1535/1672/1687 +f 1535/1672/1687 1538/1677/1692 1537/1675/1690 +f 1538/1677/1692 1536/1674/1689 1537/1675/1690 +f 1536/1674/1689 1538/1677/1692 1539/1678/1693 +f 1539/1678/1693 1889/1676/1691 1536/1674/1689 +f 1889/1676/1691 1539/1678/1693 1531/1668/1683 +f 1533/1670/1685 1531/1668/1683 1539/1678/1693 +f 1539/1678/1693 1540/1679/1694 1533/1670/1685 +f 1535/1672/1687 1533/1670/1685 1540/1679/1694 +f 1538/1677/1692 1535/1672/1687 1540/1679/1694 +f 1540/1679/1694 1539/1678/1693 1538/1677/1692 +f 1370/1493/1526 1378/1504/1537 1369/1492/1525 +f 1388/1515/1548 1369/1492/1525 1378/1504/1537 +f 1369/1492/1525 1388/1515/1548 1366/1489/1522 +f 1388/1515/1548 1889/1676/1691 1366/1489/1522 +f 1341/1455/1488 1366/1489/1522 1889/1676/1691 +f 1889/1676/1691 1541/1680/1695 1341/1455/1488 +f 1344/1456/1489 1341/1455/1488 1541/1680/1695 +f 1541/1680/1695 1542/1681/1696 1344/1456/1489 +f 1342/1457/1490 1344/1456/1489 1542/1681/1696 +f 1542/1681/1696 1543/1682/1697 1342/1457/1490 +f 1542/1681/1696 1541/1680/1695 1544/1683/1698 +f 1543/1682/1697 1542/1681/1696 1544/1683/1698 +f 1544/1683/1698 1545/1684/1699 1543/1682/1697 +f 1545/1684/1699 1544/1683/1698 1541/1680/1695 +f 1541/1680/1695 1889/1676/1691 1545/1684/1699 +f 1543/1682/1697 1343/1458/1491 1342/1457/1490 +f 1343/1458/1491 1543/1682/1697 1545/1684/1699 +f 1545/1684/1699 1547/1465/1498 1343/1458/1491 +f 1547/1465/1498 1545/1684/1699 1889/1676/1691 +f 1889/1676/1691 1890/1673/1688 1547/1465/1498 +f 1508/1644/1665 1509/1643/1493 1546/1685/1492 +f 1546/1685/1492 1510/1645/1666 1508/1644/1665 +f 1510/1645/1666 1546/1685/1492 1547/1686/1498 +f 1547/1686/1498 1514/1649/1670 1510/1645/1666 +f 1514/1649/1670 1547/1686/1498 1890/1673/1688 +f 1890/1673/1688 1530/1667/1682 1514/1649/1670 +f 1515/1650/1671 1514/1649/1670 1530/1667/1682 +f 1530/1667/1682 1529/1666/1681 1515/1650/1671 +f 1529/1666/1681 1391/1518/1551 1515/1650/1671 +f 1391/1518/1551 1529/1666/1681 1392/1516/1549 +f 1511/1646/1667 1391/1518/1551 1390/1517/1550 +f 1390/1517/1550 1513/1648/1669 1511/1646/1667 +f 1513/1648/1669 1390/1517/1550 1393/1519/1552 +f 1405/1531/1564 1513/1648/1669 1393/1519/1552 +f 1393/1519/1552 1394/1520/1553 1405/1531/1564 +f 1395/1521/1554 1405/1531/1564 1394/1520/1553 +f 1562/1687/1577 1548/1688/1700 1417/1689/1575 +f 1548/1688/1700 1551/1690/1676 1417/1689/1575 +f 1551/1690/1676 1548/1688/1700 1549/1691/1701 +f 1549/1691/1701 1550/1692/1678 1551/1690/1676 +f 1552/1693/1702 1549/1691/1701 1548/1688/1700 +f 1553/1694/1703 1033/1141/1159 1032/1140/1158 +f 1033/1141/1159 1553/1694/1703 1552/1693/1702 +f 1553/1694/1703 1554/1695/1704 1552/1693/1702 +f 1549/1691/1701 1552/1693/1702 1554/1695/1704 +f 1554/1695/1704 1373/1498/1531 1549/1691/1701 +f 1550/1692/1678 1549/1691/1701 1373/1498/1531 +f 1373/1498/1531 1523/1499/1532 1550/1692/1678 +f 1555/1696/1705 1019/1125/1143 1018/1124/1142 +f 1019/1125/1143 1555/1696/1705 1024/1130/1148 +f 1399/1526/1559 1024/1130/1148 1555/1696/1705 +f 1024/1130/1148 1399/1526/1559 1032/1140/1158 +f 1398/1524/1557 1032/1140/1158 1399/1526/1559 +f 1032/1140/1158 1398/1524/1557 1553/1694/1703 +f 1398/1524/1557 1381/1507/1540 1553/1694/1703 +f 1554/1695/1704 1553/1694/1703 1381/1507/1540 +f 1381/1507/1540 1374/1496/1529 1554/1695/1704 +f 1373/1498/1531 1554/1695/1704 1374/1496/1529 +f 1426/1554/1587 1012/1118/1136 1432/1560/1593 +f 1012/1118/1136 1426/1554/1587 1556/1697/1706 +f 1422/1550/1583 1556/1697/1706 1426/1554/1587 +f 1556/1697/1706 1422/1550/1583 1557/1698/1707 +f 1409/1533/1566 1557/1698/1707 1422/1550/1583 +f 1557/1698/1707 1409/1533/1566 1558/1699/1708 +f 1409/1533/1566 1410/1536/1569 1558/1699/1708 +f 1555/1696/1705 1558/1699/1708 1410/1536/1569 +f 1410/1536/1569 1399/1526/1559 1555/1696/1705 +f 1399/1526/1559 1410/1536/1569 1400/1525/1558 +f 1558/1699/1708 1555/1696/1705 1018/1124/1142 +f 1016/1122/1140 1558/1699/1708 1018/1124/1142 +f 1558/1699/1708 1016/1122/1140 1557/1698/1707 +f 1014/1120/1138 1557/1698/1707 1016/1122/1140 +f 1557/1698/1707 1014/1120/1138 1556/1697/1706 +f 1014/1120/1138 1012/1118/1136 1556/1697/1706 +f 1559/1700/1709 1552/1693/1702 1548/1688/1700 +f 1552/1693/1702 1559/1700/1709 1033/1141/1159 +f 1560/1701/1710 1033/1141/1159 1559/1700/1709 +f 1033/1141/1159 1560/1701/1710 1031/1139/1157 +f 1882/1138/1156 1031/1139/1157 1560/1701/1710 +f 1560/1701/1710 1423/1702/1584 1882/1138/1156 +f 1423/1702/1584 1560/1701/1710 1561/1703/1578 +f 1559/1700/1709 1561/1703/1578 1560/1701/1710 +f 1561/1703/1578 1559/1700/1709 1562/1687/1577 +f 1548/1688/1700 1562/1687/1577 1559/1700/1709 +f 1230/1333/1379 1563/1704/1711 1564/1705/1712 +f 1563/1704/1711 1230/1333/1379 1229/1332/1378 +f 1472/1602/1633 1229/1332/1378 1244/1348/1394 +f 1229/1332/1378 1472/1602/1633 1563/1704/1711 +f 1472/1602/1633 1466/1596/1627 1563/1704/1711 +f 1465/1595/1626 1563/1704/1711 1466/1596/1627 +f 1563/1704/1711 1465/1595/1626 1564/1705/1712 +f 1191/1284/1330 1564/1705/1712 1465/1595/1626 +f 1564/1705/1712 1191/1284/1330 1181/1275/1321 +f 1181/1275/1321 1230/1333/1379 1564/1705/1712 +f 1230/1333/1379 1181/1275/1321 1184/1277/1323 +f 1184/1277/1323 1224/1327/1373 1230/1333/1379 +f 1854/1225/1215 257/564/281 524/563/600 +f 1567/1706/1713 1565/1707/1714 1566/1708/1715 +f 1568/1709/1716 1565/1707/1714 1567/1706/1713 +f 1568/1709/1716 1567/1706/1713 1569/1710/1717 +f 1570/1711/1718 1568/1709/1716 1569/1710/1717 +f 1567/1706/1713 1570/1711/1718 1569/1710/1717 +f 1570/1711/1718 1567/1706/1713 1571/1712/1719 +f 1572/1713/1720 1565/1707/1714 1568/1709/1716 +f 1568/1709/1716 1570/1711/1718 1572/1713/1720 +f 1566/1708/1715 1571/1712/1719 1567/1706/1713 +f 1571/1712/1719 1566/1708/1715 1573/1714/1721 +f 1565/1707/1714 1573/1714/1721 1566/1708/1715 +f 1573/1714/1721 1565/1707/1714 1574/1715/1722 +f 1565/1707/1714 1572/1713/1720 1574/1715/1722 +f 1572/1713/1720 1575/1716/1723 1574/1715/1722 +f 1575/1716/1723 1572/1713/1720 1570/1711/1718 +f 1576/1717/1724 1575/1716/1723 1570/1711/1718 +f 1571/1712/1719 1576/1717/1724 1570/1711/1718 +f 1576/1717/1724 1571/1712/1719 1645/1718/1725 +f 1575/1716/1723 1576/1717/1724 1577/1719/1726 +f 1644/1720/1727 1576/1717/1724 1645/1718/1725 +f 1576/1717/1724 1644/1720/1727 1577/1719/1726 +f 1644/1720/1727 1578/1721/1728 1577/1719/1726 +f 1579/1722/1729 1577/1719/1726 1578/1721/1728 +f 1577/1719/1726 1579/1722/1729 1575/1716/1723 +f 1580/1723/1730 1575/1716/1723 1579/1722/1729 +f 1575/1716/1723 1580/1723/1730 1574/1715/1722 +f 1580/1723/1730 1581/1724/1731 1574/1715/1722 +f 1581/1724/1731 1573/1714/1721 1574/1715/1722 +f 1578/1721/1728 1644/1720/1727 1782/1725/1732 +f 1645/1718/1725 1582/1726/1733 1647/1727/1734 +f 1582/1726/1733 1645/1718/1725 1571/1712/1719 +f 1571/1712/1719 1583/1728/1735 1582/1726/1733 +f 1583/1728/1735 1571/1712/1719 1573/1714/1721 +f 1584/1729/1736 1583/1728/1735 1573/1714/1721 +f 1573/1714/1721 1581/1724/1731 1584/1729/1736 +f 1585/1730/1737 1584/1729/1736 1581/1724/1731 +f 1581/1724/1731 1580/1723/1730 1585/1730/1737 +f 1586/1731/1738 1585/1730/1737 1580/1723/1730 +f 1579/1722/1729 1586/1731/1738 1580/1723/1730 +f 1585/1730/1737 1586/1731/1738 1587/1732/1739 +f 1587/1732/1739 1588/1733/1740 1585/1730/1737 +f 1584/1729/1736 1585/1730/1737 1588/1733/1740 +f 1587/1732/1739 1769/1734/1741 1767/1735/1742 +f 1588/1733/1740 1587/1732/1739 1767/1735/1742 +f 1586/1731/1738 1579/1722/1729 1589/1736/1743 +f 1578/1721/1728 1589/1736/1743 1579/1722/1729 +f 1589/1736/1743 1578/1721/1728 1590/1737/1744 +f 1782/1725/1732 1590/1737/1744 1578/1721/1728 +f 1590/1737/1744 1782/1725/1732 1591/1738/1745 +f 1770/1739/1746 1590/1737/1744 1591/1738/1745 +f 1590/1737/1744 1770/1739/1746 1592/1740/1747 +f 1769/1734/1741 1592/1740/1747 1770/1739/1746 +f 1592/1740/1747 1769/1734/1741 1593/1741/1748 +f 1769/1734/1741 1587/1732/1739 1593/1741/1748 +f 1587/1732/1739 1594/1742/1749 1593/1741/1748 +f 1594/1742/1749 1587/1732/1739 1586/1731/1738 +f 1586/1731/1738 1595/1743/1750 1594/1742/1749 +f 1595/1743/1750 1586/1731/1738 1589/1736/1743 +f 1590/1737/1744 1595/1743/1750 1589/1736/1743 +f 1595/1743/1750 1590/1737/1744 1592/1740/1747 +f 1593/1741/1748 1595/1743/1750 1592/1740/1747 +f 1595/1743/1750 1593/1741/1748 1594/1742/1749 +f 1908/688/738 1876/1744/1751 1596/1745/1752 +f 1597/1746/1753 122/139/134 121/137/133 +f 122/139/134 1597/1746/1753 1598/1747/1754 +f 1597/1748/1753 1599/1749/1755 1598/1750/1754 +f 1599/1749/1755 1597/1748/1753 1600/1751/1756 +f 41/42/42 1599/1749/1755 1600/1751/1756 +f 45/43/43 41/42/42 1600/1751/1756 +f 1600/1751/1756 1601/1752/1757 45/43/43 +f 1601/1752/1757 1600/1751/1756 1597/1748/1753 +f 124/141/136 125/140/135 41/42/42 +f 1599/1749/1755 41/42/42 125/140/135 +f 125/140/135 1602/1753/1758 1599/1749/1755 +f 1603/1754/1759 1599/1749/1755 1602/1753/1758 +f 1599/1749/1755 1603/1754/1759 1598/1750/1754 +f 1604/1755/1760 1598/1747/1754 1603/1756/1759 +f 1598/1747/1754 1604/1755/1760 122/139/134 +f 1605/1757/1761 122/139/134 1604/1755/1760 +f 122/139/134 1605/1757/1761 123/135/130 +f 1606/1758/1762 123/135/130 1605/1759/1761 +f 123/135/130 1606/1758/1762 118/133/128 +f 1607/1760/1763 118/133/128 1606/1758/1762 +f 118/133/128 1607/1760/1763 125/140/135 +f 1602/1753/1758 125/140/135 1607/1760/1763 +f 1610/1761/1764 1608/1762/1765 1609/1763/1766 +f 1608/1762/1765 1610/1761/1764 171/189/180 +f 144/164/155 171/189/180 1610/1761/1764 +f 120/136/131 144/164/155 1610/1761/1764 +f 1609/1763/1766 120/136/131 1610/1761/1764 +f 120/136/131 1609/1763/1766 1612/138/129 +f 1611/1764/1767 1612/138/129 1609/1763/1766 +f 1612/138/129 1611/1764/1767 121/137/133 +f 1613/1765/1768 121/137/133 1611/1764/1767 +f 121/137/133 1613/1765/1768 1597/1746/1753 +f 39/41/41 45/43/43 1601/1752/1757 +f 1601/1752/1757 1597/1746/1753 39/41/41 +f 1597/1746/1753 38/40/40 39/41/41 +f 38/40/40 1597/1746/1753 1613/1765/1768 +f 1613/1765/1768 37/39/39 38/40/40 +f 37/39/39 1613/1765/1768 1614/1766/1769 +f 1611/1764/1767 1614/1766/1769 1613/1765/1768 +f 1614/1766/1769 1611/1764/1767 1615/1767/1770 +f 1609/1763/1766 1615/1767/1770 1611/1764/1767 +f 1615/1767/1770 1609/1763/1766 1608/1762/1765 +f 37/39/39 34/36/36 33/35/35 +f 34/36/36 37/39/39 1616/1768/1771 +f 1614/1766/1769 1616/1768/1771 37/39/39 +f 1616/1768/1771 1614/1766/1769 1617/1769/1772 +f 1615/1767/1770 1617/1769/1772 1614/1766/1769 +f 1617/1769/1772 1615/1767/1770 1618/1770/1773 +f 1619/1771/1774 1617/1769/1772 1618/1770/1773 +f 1617/1769/1772 1619/1771/1774 1620/1772/1775 +f 1294/1403/1441 1620/1772/1775 1619/1771/1774 +f 1620/1772/1775 1294/1403/1441 1295/1404/1442 +f 178/200/191 171/189/180 170/188/179 +f 171/189/180 178/200/191 1608/1762/1765 +f 1286/1393/1431 1608/1762/1765 178/200/191 +f 1608/1762/1765 1286/1393/1431 1615/1767/1770 +f 1285/1395/1433 1615/1767/1770 1286/1393/1431 +f 1615/1767/1770 1285/1395/1433 1618/1770/1773 +f 1288/1397/1435 1618/1770/1773 1285/1395/1433 +f 1618/1770/1773 1288/1397/1435 1619/1771/1774 +f 1290/1399/1437 1619/1771/1774 1288/1397/1435 +f 1619/1771/1774 1290/1399/1437 1294/1403/1441 +f 1876/1744/1751 1908/688/738 1880/562/280 +f 1623/1773/1776 1621/1774/1777 1622/1775/1778 +f 1621/1774/1777 1623/1773/1776 1624/1776/1779 +f 1623/1773/1776 1625/1777/1780 1624/1776/1779 +f 1625/1777/1780 1623/1773/1776 1626/1778/1781 +f 1626/1778/1781 1627/1779/1782 1625/1777/1780 +f 1627/1779/1782 1626/1778/1781 1628/1780/1783 +f 1628/1780/1783 1629/1781/1784 1627/1779/1782 +f 1629/1781/1784 1628/1780/1783 1630/1782/1785 +f 1624/1776/1779 1631/1783/1058 1632/1784/1060 +f 1632/1784/1060 1621/1774/1777 1624/1776/1779 +f 1621/1774/1777 1632/1784/1060 1633/1785/1062 +f 938/1786/840 1621/1774/1777 1633/1785/1062 +f 1621/1774/1777 938/1786/840 1634/1787/838 +f 1451/1579/1612 1621/1774/1777 1634/1787/838 +f 1621/1774/1777 1451/1579/1612 1622/1775/1778 +f 1451/1579/1612 1452/1580/1613 1622/1775/1778 +f 1452/1580/1613 1623/1773/1776 1622/1775/1778 +f 1623/1773/1776 1452/1580/1613 1445/1573/1606 +f 1445/1573/1606 1626/1778/1781 1623/1773/1776 +f 1626/1778/1781 1445/1573/1606 987/1093/1111 +f 987/1093/1111 1628/1780/1783 1626/1778/1781 +f 1628/1780/1783 987/1093/1111 986/1092/1110 +f 986/1092/1110 1630/1782/1785 1628/1780/1783 +f 1630/1782/1785 986/1092/1110 1635/1788/1786 +f 986/1092/1110 1636/1789/1787 1635/1788/1786 +f 1636/1789/1787 986/1092/1110 1637/1790/1788 +f 986/1092/1110 979/1084/1102 1637/1790/1788 +f 975/1080/1098 1637/1790/1788 979/1084/1102 +f 973/1079/1097 975/1080/1098 972/1078/1096 +f 975/1080/1098 973/1079/1097 1638/1791/1789 +f 1637/1790/1788 975/1080/1098 1638/1791/1789 +f 1639/1792/1790 1637/1790/1788 1638/1791/1789 +f 1637/1790/1788 1639/1792/1790 1636/1789/1787 +f 1640/1793/1791 1636/1789/1787 1639/1792/1790 +f 1636/1789/1787 1640/1793/1791 1672/1794/1792 +f 1672/1794/1792 1635/1788/1786 1636/1789/1787 +f 1635/1788/1786 1672/1794/1792 1641/1795/1447 +f 1642/1796/1445 1635/1788/1786 1641/1795/1447 +f 1643/1797/1793 1782/1798/1732 1644/1799/1727 +f 1645/1800/1725 1643/1797/1793 1644/1799/1727 +f 1643/1797/1793 1645/1800/1725 1647/1801/1734 +f 1646/1802/1794 1643/1797/1793 1647/1801/1734 +f 1640/1793/1791 1646/1802/1794 1647/1801/1734 +f 1646/1802/1794 1640/1793/1791 1639/1792/1790 +f 1639/1792/1790 1648/1803/1795 1646/1802/1794 +f 1648/1803/1795 1639/1792/1790 1638/1791/1789 +f 973/1079/1097 1648/1803/1795 1638/1791/1789 +f 1648/1803/1795 973/1079/1097 1649/1804/1796 +f 1652/1805/1797 1650/1806/1798 1651/1807/1799 +f 1650/1806/1798 1652/1805/1797 1649/1804/1796 +f 1652/1805/1797 1648/1803/1795 1649/1804/1796 +f 1648/1803/1795 1652/1805/1797 1653/1808/1800 +f 1653/1808/1800 1646/1802/1794 1648/1803/1795 +f 1646/1802/1794 1653/1808/1800 1654/1809/1801 +f 1643/1797/1793 1646/1802/1794 1654/1809/1801 +f 971/1077/1095 1649/1804/1796 973/1079/1097 +f 1649/1804/1796 971/1077/1095 1650/1806/1798 +f 962/1066/1084 1650/1806/1798 971/1077/1095 +f 1650/1806/1798 962/1066/1084 1655/1810/1802 +f 1655/1810/1802 1651/1807/1799 1650/1806/1798 +f 1651/1807/1799 1655/1810/1802 1656/1811/1803 +f 1656/1811/1803 1657/1812/1804 1651/1807/1799 +f 1657/1812/1804 1656/1811/1803 1658/1813/1805 +f 1658/1813/1805 1676/1814/1806 1657/1812/1804 +f 1676/1814/1806 1658/1813/1805 11/1815/11 +f 1658/1813/1805 1875/1816/1807 11/1815/11 +f 1875/1816/1807 1658/1813/1805 1659/1817/1808 +f 1656/1811/1803 1659/1817/1808 1658/1813/1805 +f 1659/1817/1808 1656/1811/1803 1660/1818/1809 +f 1655/1810/1802 1660/1818/1809 1656/1811/1803 +f 1660/1818/1809 1655/1810/1802 1661/1819/1810 +f 962/1066/1084 1661/1819/1810 1655/1810/1802 +f 1661/1819/1810 962/1066/1084 961/1068/1086 +f 1659/1817/1808 1874/1203/1204 1875/1816/1807 +f 1874/1203/1204 1659/1817/1808 1662/1820/1811 +f 1660/1818/1809 1662/1820/1811 1659/1817/1808 +f 1662/1820/1811 1660/1818/1809 1663/1821/1812 +f 1661/1819/1810 1663/1821/1812 1660/1818/1809 +f 1663/1821/1812 1661/1819/1810 1664/1822/1813 +f 961/1068/1086 1664/1822/1813 1661/1819/1810 +f 1664/1822/1813 961/1068/1086 1665/1823/1814 +f 961/1068/1086 956/1063/1081 1665/1823/1814 +f 951/1057/1075 1665/1823/1814 956/1063/1081 +f 1665/1823/1814 951/1057/1075 1077/1194/1195 +f 1076/1193/1194 1665/1823/1814 1077/1194/1195 +f 1665/1823/1814 1076/1193/1194 1664/1822/1813 +f 1076/1193/1194 1663/1821/1812 1664/1822/1813 +f 1663/1821/1812 1076/1193/1194 1075/1192/1193 +f 1075/1192/1193 1080/1197/1198 1663/1821/1812 +f 1080/1197/1198 1662/1820/1811 1663/1821/1812 +f 1662/1820/1811 1080/1197/1198 1081/1198/1199 +f 1081/1198/1199 1874/1203/1204 1662/1820/1811 +f 1874/1203/1204 1081/1198/1199 1082/1200/1201 +f 1666/1824/1815 1617/1769/1772 1620/1772/1775 +f 1617/1769/1772 1666/1824/1815 1616/1768/1771 +f 1667/1825/1816 1616/1768/1771 1666/1824/1815 +f 1616/1768/1771 1667/1825/1816 34/36/36 +f 1668/1826/1817 34/36/36 1667/1825/1816 +f 34/36/36 1668/1826/1817 32/34/34 +f 1669/1827/1818 32/34/34 1668/1826/1817 +f 32/34/34 1669/1827/1818 1670/1828/1819 +f 1671/1829/1820 1670/1828/1819 1669/1827/1818 +f 1295/1404/1442 1666/1824/1815 1620/1772/1775 +f 1666/1824/1815 1295/1404/1442 1298/1409/1446 +f 1298/1409/1446 1667/1825/1816 1666/1824/1815 +f 1667/1825/1816 1298/1409/1446 1641/1410/1447 +f 1672/1830/1792 1667/1825/1816 1641/1410/1447 +f 1667/1825/1816 1672/1830/1792 1668/1826/1817 +f 1640/1831/1791 1668/1826/1817 1672/1830/1792 +f 1668/1826/1817 1640/1831/1791 1669/1827/1818 +f 1647/1727/1734 1669/1827/1818 1640/1831/1791 +f 1669/1827/1818 1647/1727/1734 1671/1829/1820 +f 1674/1832/1821 1671/1829/1820 1673/1833/1822 +f 1582/1726/1733 1671/1829/1820 1647/1727/1734 +f 1671/1829/1820 1582/1726/1733 1673/1833/1822 +f 1583/1728/1735 1673/1833/1822 1582/1726/1733 +f 1673/1833/1822 1583/1728/1735 1674/1832/1821 +f 1583/1728/1735 6/8/8 1674/1832/1821 +f 1671/1829/1820 1674/1832/1821 6/8/8 +f 6/8/8 2/5/5 1671/1829/1820 +f 1670/1828/1819 1671/1829/1820 2/5/5 +f 2/5/5 4/4/4 1670/1828/1819 +f 1675/1834/1823 1670/1828/1819 4/4/4 +f 1670/1828/1819 1675/1834/1823 32/34/34 +f 30/32/32 32/34/34 1675/1834/1823 +f 1583/1728/1735 1584/1729/1736 1775/1835/1824 +f 6/8/8 1583/1728/1735 1775/1835/1824 +f 1676/1836/1806 6/8/8 1775/1835/1824 +f 6/8/8 1676/1836/1806 7/9/9 +f 11/11/11 7/9/9 1676/1836/1806 +f 26/28/28 1677/1837/1825 25/27/27 +f 1677/1837/1825 26/28/28 30/32/32 +f 30/32/32 1678/1838/1826 1677/1837/1825 +f 1678/1838/1826 30/32/32 1675/1834/1823 +f 1675/1834/1823 1679/1839/1827 1678/1838/1826 +f 1679/1839/1827 1675/1834/1823 4/4/4 +f 4/4/4 1680/1840/1828 1679/1839/1827 +f 1680/1840/1828 4/4/4 3/6/6 +f 3/6/6 1681/1841/1829 1680/1840/1828 +f 1681/1841/1829 3/6/6 8/10/10 +f 8/10/10 15/17/17 1681/1841/1829 +f 1683/1842/1830 1678/1838/1826 1682/1843/1831 +f 1679/1839/1827 1682/1843/1831 1678/1838/1826 +f 1682/1843/1831 1679/1839/1827 1684/1844/1832 +f 1680/1840/1828 1684/1844/1832 1679/1839/1827 +f 1684/1844/1832 1680/1840/1828 1685/1845/1833 +f 1681/1841/1829 1685/1845/1833 1680/1840/1828 +f 1685/1845/1833 1681/1841/1829 1686/1846/1834 +f 15/17/17 1686/1846/1834 1681/1841/1829 +f 1686/1846/1834 15/17/17 17/19/19 +f 17/19/19 16/18/18 1687/1847/1835 +f 21/23/23 1687/1847/1835 16/18/18 +f 1687/1847/1835 21/23/23 1688/1848/1836 +f 23/25/25 1688/1848/1836 21/23/23 +f 1688/1848/1836 23/25/25 1689/1849/1837 +f 25/27/27 1689/1849/1837 23/25/25 +f 1689/1849/1837 25/27/27 1690/1850/1838 +f 1677/1837/1825 1690/1850/1838 25/27/27 +f 1690/1850/1838 1677/1837/1825 1683/1842/1830 +f 1678/1838/1826 1683/1842/1830 1677/1837/1825 +f 1693/1851/1839 1691/1852/1840 1692/1853/1841 +f 1691/1852/1840 1693/1851/1839 1694/1854/1842 +f 1696/1855/1843 1695/1856/1844 1691/1852/1840 +f 1694/1854/1842 1697/1857/1845 756/830/878 +f 1697/1857/1845 1694/1854/1842 1693/1851/1839 +f 1693/1851/1839 1698/1858/1846 1697/1857/1845 +f 1698/1858/1846 1693/1851/1839 1692/1853/1841 +f 1692/1853/1841 1699/1859/1847 1698/1858/1846 +f 1699/1859/1847 1692/1853/1841 1691/1852/1840 +f 1691/1852/1840 1700/1860/1848 1699/1859/1847 +f 1700/1860/1848 1691/1852/1840 1695/1856/1844 +f 1701/1861/1849 1700/1860/1848 1695/1856/1844 +f 1695/1856/1844 1696/1855/1843 1701/1861/1849 +f 1702/1862/1850 1701/1861/1849 1696/1855/1843 +f 1703/1863/1851 1702/1862/1850 1696/1855/1843 +f 1696/1855/1843 1704/1864/1852 1703/1863/1851 +f 1701/1861/1849 1702/1862/1850 1705/1865/1853 +f 1700/1860/1848 1701/1861/1849 1705/1865/1853 +f 1706/1866/723 1697/1857/1845 1698/1858/1846 +f 1698/1858/1846 1707/1867/722 1706/1866/723 +f 1707/1867/722 1698/1858/1846 1699/1859/1847 +f 1699/1859/1847 1708/1868/721 1707/1867/722 +f 1708/1868/721 1699/1859/1847 1700/1860/1848 +f 1700/1860/1848 1709/1869/711 1708/1868/721 +f 1709/1869/711 1700/1860/1848 1705/1865/1853 +f 1705/1865/1853 622/811/710 1709/1869/711 +f 622/811/710 1705/1865/1853 1702/1862/1850 +f 738/812/861 622/811/710 1702/1862/1850 +f 1702/1862/1850 1703/1863/1851 738/812/861 +f 1703/1863/1851 740/814/862 738/812/861 +f 740/814/862 1703/1863/1851 1704/1864/1852 +f 741/815/863 740/814/862 1704/1864/1852 +f 1704/1864/1852 1696/1855/1843 741/815/863 +f 746/820/868 741/815/863 1696/1855/1843 +f 1691/1852/1840 746/820/868 1696/1855/1843 +f 746/820/868 1691/1852/1840 748/822/870 +f 1694/1854/1842 748/822/870 1691/1852/1840 +f 748/822/870 1694/1854/1842 756/830/878 +f 754/828/876 1710/836/680 752/826/874 +f 1710/836/680 754/828/876 603/1870/689 +f 755/829/877 603/1870/689 754/828/876 +f 603/1870/689 755/829/877 1711/1871/690 +f 755/829/877 756/830/878 1711/1871/690 +f 756/830/878 1713/1872/734 1711/1871/690 +f 1713/1872/734 756/830/878 1712/1873/732 +f 1697/1857/1845 1712/1873/732 756/830/878 +f 1712/1873/732 1697/1857/1845 1714/1874/733 +f 1697/1857/1845 1706/1866/723 1714/1874/733 +f 1854/1225/1215 268/1875/292 267/1625/291 +f 1719/571/1854 1716/566/1855 1718/570/1856 +f 1716/566/1855 1719/571/1854 1720/574/1857 +f 1715/565/1858 1716/566/1855 1722/568/1859 +f 1716/566/1855 1715/565/1858 1718/567/1856 +f 1717/569/1860 1718/570/1856 1715/572/1858 +f 1718/570/1856 1717/569/1860 1719/571/1854 +f 1721/573/1861 1719/571/1854 1717/569/1860 +f 1719/571/1854 1721/573/1861 1720/574/1857 +f 1722/568/1859 1720/574/1857 1721/573/1861 +f 1720/574/1857 1722/568/1859 1716/566/1855 +f 1728/571/1862 1723/566/1863 1730/574/1864 +f 1723/566/1863 1728/571/1862 1725/570/1865 +f 1724/565/1866 1723/566/1863 1725/567/1865 +f 1723/566/1863 1724/565/1866 1729/568/1867 +f 1727/569/1868 1725/570/1865 1728/571/1862 +f 1725/570/1865 1727/569/1868 1724/572/1866 +f 1726/573/1869 1728/571/1862 1730/574/1864 +f 1728/571/1862 1726/573/1869 1727/569/1868 +f 1729/568/1867 1730/574/1864 1723/566/1863 +f 1730/574/1864 1729/568/1867 1726/573/1869 +f 1734/571/1870 1737/566/1871 1736/574/1872 +f 1737/566/1871 1734/571/1870 1731/570/1873 +f 1732/565/1866 1737/566/1871 1731/567/1873 +f 1737/566/1871 1732/565/1866 1733/568/1874 +f 1735/569/1875 1731/570/1873 1734/571/1870 +f 1731/570/1873 1735/569/1875 1732/572/1866 +f 1738/573/1876 1734/571/1870 1736/574/1872 +f 1734/571/1870 1738/573/1876 1735/569/1875 +f 1733/568/1874 1736/574/1872 1737/566/1871 +f 1736/574/1872 1733/568/1874 1738/573/1876 +f 1740/571/1877 1742/566/1878 1739/574/1879 +f 1742/566/1878 1740/571/1877 1743/570/1880 +f 1741/565/1881 1742/566/1878 1743/567/1880 +f 1742/566/1878 1741/565/1881 1746/568/1882 +f 1745/569/1883 1743/570/1880 1740/571/1877 +f 1743/570/1880 1745/569/1883 1741/572/1881 +f 1744/573/1884 1740/571/1877 1739/574/1879 +f 1740/571/1877 1744/573/1884 1745/569/1883 +f 1746/568/1882 1739/574/1879 1742/566/1878 +f 1739/574/1879 1746/568/1882 1744/573/1884 +f 1751/571/1885 1748/566/1886 1750/570/1887 +f 1748/566/1886 1751/571/1885 1747/574/1888 +f 1749/565/1889 1748/566/1886 1754/568/1890 +f 1748/566/1886 1749/565/1889 1750/567/1887 +f 1752/569/1891 1750/570/1887 1749/572/1889 +f 1750/570/1887 1752/569/1891 1751/571/1885 +f 1753/573/1892 1751/571/1885 1752/569/1891 +f 1751/571/1885 1753/573/1892 1747/574/1888 +f 1754/568/1890 1747/574/1888 1753/573/1892 +f 1747/574/1888 1754/568/1890 1748/566/1886 +f 529/566/602 1755/571/606 526/570/603 +f 1755/571/606 529/566/602 1756/574/608 +f 2033/1876/1893 1757/1258/1894 2203/1233/1895 +f 1757/1258/1894 2033/1876/1893 1758/1877/1896 +f 1761/1878/1897 1759/1879/1898 1760/1880/1899 +f 1759/1879/1898 1763/2/2 1760/1880/1899 +f 1763/2/2 1759/1879/1898 1777/3/3 +f 1763/2/2 1768/1/1 1762/1881/1900 +f 1588/1882/1740 1764/1883/1901 1765/1884/1902 +f 1764/1883/1901 1588/1882/1740 1767/1885/1742 +f 1767/1885/1742 1766/1886/1903 1764/1883/1901 +f 1766/1886/1903 1767/1885/1742 1769/1887/1741 +f 1769/1887/1741 1768/1/1 1766/1886/1903 +f 1768/1/1 1769/1887/1741 1770/1888/1746 +f 1770/1888/1746 1762/1881/1900 1768/1/1 +f 1762/1881/1900 1770/1888/1746 1591/1889/1745 +f 1591/1889/1745 1771/1890/1904 1762/1881/1900 +f 1771/1890/1904 1763/2/2 1762/1881/1900 +f 1772/1891/1905 1765/1884/1902 1764/1883/1901 +f 1766/1886/1903 1772/1891/1905 1764/1883/1901 +f 1772/1891/1905 1766/1886/1903 1773/1892/1906 +f 1774/1893/1907 1772/1891/1905 1773/1892/1906 +f 1588/1882/1740 1775/1894/1824 1584/1895/1736 +f 1775/1894/1824 1588/1882/1740 1765/1884/1902 +f 1776/1896/1908 1775/1894/1824 1765/1884/1902 +f 1765/1884/1902 1772/1891/1905 1776/1896/1908 +f 1761/1878/1897 1776/1896/1908 1772/1891/1905 +f 1772/1891/1905 1774/1893/1907 1761/1878/1897 +f 1759/1879/1898 1761/1878/1897 1774/1893/1907 +f 1773/1892/1906 1759/1879/1898 1774/1893/1907 +f 1759/1879/1898 1773/1892/1906 1777/3/3 +f 1766/1886/1903 1777/3/3 1773/1892/1906 +f 1777/3/3 1766/1886/1903 1768/1/1 +f 1763/2/2 1771/1890/1904 1778/1897/1909 +f 1778/1897/1909 1760/1880/1899 1763/2/2 +f 1760/1880/1899 1778/1897/1909 1779/1898/1910 +f 1779/1898/1910 1761/1878/1897 1760/1880/1899 +f 1761/1878/1897 1779/1898/1910 1780/1899/1911 +f 1776/1896/1908 1761/1878/1897 1780/1899/1911 +f 1780/1899/1911 1781/1900/1912 1776/1896/1908 +f 1775/1894/1824 1776/1896/1908 1781/1900/1912 +f 1657/1812/1804 1775/1894/1824 1781/1900/1912 +f 1775/1894/1824 1657/1812/1804 1676/1814/1806 +f 1781/1900/1912 1651/1807/1799 1657/1812/1804 +f 1651/1807/1799 1781/1900/1912 1652/1805/1797 +f 1781/1900/1912 1780/1899/1911 1652/1805/1797 +f 1780/1899/1911 1653/1808/1800 1652/1805/1797 +f 1653/1808/1800 1780/1899/1911 1779/1898/1910 +f 1779/1898/1910 1654/1809/1801 1653/1808/1800 +f 1654/1809/1801 1779/1898/1910 1778/1897/1909 +f 1778/1897/1909 1643/1797/1793 1654/1809/1801 +f 1643/1797/1793 1778/1897/1909 1771/1890/1904 +f 1782/1798/1732 1643/1797/1793 1771/1890/1904 +f 1771/1890/1904 1591/1889/1745 1782/1798/1732 +f 323/380/354 1783/367/1913 1784/381/328 +f 1783/367/1913 323/380/354 1785/368/1914 +f 1787/379/353 1785/368/1914 323/380/354 +f 1785/368/1914 1787/379/353 1786/369/1915 +f 1789/378/352 1786/369/1915 1787/379/353 +f 1786/369/1915 1789/378/352 1788/370/1916 +f 1790/377/351 1788/370/1916 1789/378/352 +f 1788/370/1916 1790/377/351 1791/371/1917 +f 1792/376/350 1791/371/1917 1790/377/351 +f 1791/371/1917 1792/376/350 1793/372/1918 +f 1793/372/1918 1794/365/1919 1791/371/1917 +f 1794/365/1919 1793/372/1918 1795/374/1920 +f 1796/373/1921 1794/365/1919 1795/374/1920 +f 1794/365/1919 1796/373/1921 1797/366/1922 +f 1798/364/1923 1794/365/1919 1797/366/1922 +f 1794/365/1919 1798/364/1923 1783/367/1913 +f 1785/368/1914 1794/365/1919 1783/367/1913 +f 1794/365/1919 1785/368/1914 1786/369/1915 +f 1788/370/1916 1794/365/1919 1786/369/1915 +f 1794/365/1919 1788/370/1916 1791/371/1917 +f 1799/375/333 1793/372/1918 1792/376/350 +f 1793/372/1918 1799/375/333 1795/374/1920 +f 305/384/331 1795/374/1920 1799/375/333 +f 1795/374/1920 305/384/331 1796/373/1921 +f 1800/383/330 1796/373/1921 305/384/331 +f 1796/373/1921 1800/383/330 1797/366/1922 +f 1801/382/329 1797/366/1922 1800/383/330 +f 1797/366/1922 1801/382/329 1798/364/1923 +f 1784/381/328 1798/364/1923 1801/382/329 +f 1798/364/1923 1784/381/328 1783/367/1913 +f 1804/303/1924 1802/304/1925 1803/305/1926 +f 1803/305/1926 1805/306/1927 1804/303/1924 +f 1805/306/1927 1803/305/1926 1806/307/1928 +f 1806/307/1928 1807/308/1929 1805/306/1927 +f 1807/308/1929 1806/307/1928 1808/309/1930 +f 1808/309/1930 1809/310/1931 1807/308/1929 +f 1809/310/1931 1808/309/1930 1810/311/1932 +f 1811/312/1933 1809/310/1931 1810/311/1932 +f 1809/310/1931 1811/312/1933 1812/313/1934 +f 1811/312/1933 1813/314/1935 1812/313/1934 +f 1813/314/1935 1811/312/1933 1814/315/1936 +f 1814/315/1936 1815/316/1937 1813/314/1935 +f 1815/316/1937 1814/315/1936 1816/317/1938 +f 1816/317/1938 1817/318/1939 1815/316/1937 +f 1817/318/1939 1816/317/1938 1818/319/1940 +f 1818/319/1940 1819/320/1941 1817/318/1939 +f 1819/320/1941 1818/319/1940 1820/321/1942 +f 1820/321/1942 1821/322/1943 1819/320/1941 +f 1821/322/1943 1820/321/1942 1802/304/1925 +f 1802/304/1925 1804/303/1924 1821/322/1943 +f 1824/1901/1944 1822/1902/1945 1823/1903/1946 +f 1822/1902/1945 1825/1904/1947 1823/1903/1946 +f 1825/1904/1947 1822/1902/1945 1826/1905/1948 +f 1826/1905/1948 1827/1906/1949 1825/1904/1947 +f 1827/1906/1949 1826/1905/1948 1828/1907/1950 +f 1828/1907/1950 1829/1908/1951 1827/1906/1949 +f 1831/1909/1952 1830/1910/1953 1829/1908/1951 +f 1829/1908/1951 1828/1907/1950 1831/1909/1952 +f 1832/1911/1954 1831/1909/1952 1828/1907/1950 +f 1828/1907/1950 1833/1912/1955 1832/1911/1954 +f 1833/1912/1955 1828/1907/1950 1826/1905/1948 +f 1826/1905/1948 1834/1913/1956 1833/1912/1955 +f 1834/1913/1956 1826/1905/1948 1822/1902/1945 +f 1835/1914/1957 1834/1913/1956 1822/1902/1945 +f 1822/1902/1945 1824/1901/1944 1835/1914/1957 +f 887/988/1013 1835/1914/1957 1824/1901/1944 +f 1824/1901/1944 884/983/1008 887/988/1013 +f 1834/1913/1956 1835/1914/1957 1836/1915/1958 +f 882/1916/1003 1832/1911/1954 1833/1912/1955 +f 1833/1912/1955 1837/1917/1011 882/1916/1003 +f 1837/1917/1011 1833/1912/1955 1834/1913/1956 +f 1834/1913/1956 1838/1918/1010 1837/1917/1011 +f 1838/1918/1010 1834/1913/1956 1836/1915/1958 +f 1886/1142/1160 1838/1918/1010 1836/1915/1958 +f 1835/1914/1957 1886/1142/1160 1836/1915/1958 +f 1886/1142/1160 1835/1914/1957 1020/1126/1144 +f 1835/1914/1957 887/988/1013 1020/1126/1144 +f 886/987/1012 1020/1126/1144 887/988/1013 +f 877/973/998 885/984/1009 862/958/983 +f 884/983/1008 862/958/983 885/984/1009 +f 862/958/983 884/983/1008 861/957/982 +f 884/983/1008 1824/1901/1944 861/957/982 +f 1824/1901/1944 859/956/981 861/957/982 +f 859/956/981 1824/1901/1944 1823/1903/1946 +f 1823/1903/1946 860/954/979 859/956/981 +f 860/954/979 1823/1903/1946 1825/1904/1947 +f 1825/1904/1947 871/967/992 860/954/979 +f 871/967/992 1825/1904/1947 1827/1906/1949 +f 1827/1906/1949 869/965/990 871/967/992 +f 869/965/990 1827/1906/1949 1829/1908/1951 +f 1829/1908/1951 870/966/991 869/965/990 +f 870/966/991 1829/1908/1951 1830/1910/1953 +f 1839/1919/1959 870/966/991 1830/1910/1953 +f 1830/1910/1953 1831/1909/1952 1839/1919/1959 +f 1840/1920/1960 1839/1919/1959 1831/1909/1952 +f 1831/1909/1952 1832/1911/1954 1840/1920/1960 +f 1841/1921/1004 1840/1920/1960 1832/1911/1954 +f 1832/1911/1954 882/1916/1003 1841/1921/1004 +f 1840/1920/1960 1841/1921/1004 1842/1922/1005 +f 1842/1922/1005 1843/1923/1961 1840/1920/1960 +f 1839/1919/1959 1840/1920/1960 1843/1923/1961 +f 1843/1923/1961 883/1924/1007 1839/1919/1959 +f 870/966/991 1839/1919/1959 883/1924/1007 +f 1843/1923/1961 1842/1922/1005 1844/1925/1006 +f 883/1924/1007 1843/1923/1961 1844/1925/1006 +f 1440/1568/1601 1845/1926/1962 1441/1569/1602 +f 1845/1926/1962 1440/1568/1601 1846/1927/1963 +f 1440/1568/1601 1443/1570/1603 1846/1927/1963 +f 1468/1598/1629 1846/1927/1963 1443/1570/1603 +f 1461/1590/1621 1468/1598/1629 1443/1570/1603 +f 1468/1598/1629 1461/1590/1621 1462/1591/1622 +f 1846/1927/1963 1468/1598/1629 1470/1600/1631 +f 1847/1928/1964 1846/1927/1963 1470/1600/1631 +f 1846/1927/1963 1847/1928/1964 1845/1926/1962 +f 1470/1600/1631 1471/1601/1632 1847/1928/1964 +f 1471/1601/1632 1848/1607/1625 1847/1928/1964 +f 1457/1929/1618 1847/1928/1964 1848/1607/1625 +f 1847/1928/1964 1457/1929/1618 1845/1926/1962 +f 1456/1930/1616 1845/1926/1962 1457/1929/1618 +f 1845/1926/1962 1456/1930/1616 1441/1569/1602 +f 1455/1931/836 1441/1569/1602 1456/1930/1616 +f 1441/1569/1602 1455/1931/836 1438/1566/1599 +f 1455/1931/836 1429/1557/1590 1438/1566/1599 +f 1433/1561/1594 1438/1566/1599 1429/1557/1590 +f 1418/1546/1579 1849/1932/908 782/1933/909 +f 1849/1932/908 1418/1546/1579 1419/1547/1580 +f 1419/1547/1580 1850/1934/913 1849/1932/908 +f 1850/1934/913 1419/1547/1580 1421/1549/1582 +f 1421/1549/1582 1851/1935/914 1850/1934/913 +f 1851/1935/914 1421/1549/1582 1427/1555/1588 +f 1427/1555/1588 1852/1936/915 1851/1935/914 +f 1852/1936/915 1427/1555/1588 1429/1557/1590 +f 1429/1557/1590 1853/1937/841 1852/1936/915 +f 1853/1937/841 1429/1557/1590 719/1938/835 +f 268/1875/292 1854/1225/1215 1912/1939/293 +f 1857/1940/1965 1855/1941/1966 1856/1942/1967 +f 1855/1941/1966 1857/1940/1965 1858/1943/1968 +f 620/657/707 1858/1943/1968 1857/1940/1965 +f 1858/1943/1968 620/657/707 1859/1944/1969 +f 739/659/709 1859/1944/1969 620/657/707 +f 1859/1944/1969 739/659/709 1861/1945/855 +f 1861/1945/855 1860/1946/1970 1859/1944/1969 +f 1860/1946/1970 1861/1945/855 618/655/705 +f 618/655/705 621/658/708 1860/1946/1970 +f 621/658/708 618/655/705 619/656/706 +f 1919/807/857 618/655/705 1861/1945/855 +f 1857/1940/1965 621/658/708 620/657/707 +f 621/658/708 1857/1940/1965 1856/1942/1967 +f 1856/1942/1967 1860/1946/1970 621/658/708 +f 1860/1946/1970 1856/1942/1967 1855/1941/1966 +f 1855/1941/1966 1859/1944/1969 1860/1946/1970 +f 1859/1944/1969 1855/1941/1966 1858/1943/1968 +f 1877/1373/1419 1862/1947/1971 1866/1948/1387 +f 1863/1949/1972 1866/1948/1387 1862/1947/1971 +f 1862/1947/1971 1864/1950/1973 1863/1949/1972 +f 1865/1951/1974 1863/1949/1972 1864/1950/1973 +f 1248/1352/1398 1237/1340/1386 1866/1948/1387 +f 1866/1948/1387 1863/1949/1972 1248/1352/1398 +f 1257/1361/1407 1248/1352/1398 1863/1949/1972 +f 1863/1949/1972 1865/1951/1974 1257/1361/1407 +f 1867/1952/1975 1257/1361/1407 1865/1951/1974 +f 1864/1950/1973 1867/1952/1975 1865/1951/1974 +f 1867/1952/1975 1864/1950/1973 1868/1953/1976 +f 1864/1950/1973 1862/1947/1971 1868/1953/1976 +f 1268/1372/1418 1868/1953/1976 1862/1947/1971 +f 1862/1947/1971 1877/1373/1419 1268/1372/1418 +f 1268/1372/1418 1256/1360/1406 1257/1361/1407 +f 1257/1361/1407 1867/1952/1975 1268/1372/1418 +f 1868/1953/1976 1268/1372/1418 1867/1952/1975 +f 1869/1954/279 1902/1955/1977 1885/1956/1978 +f 1350/1957/1503 1497/1632/1654 1520/1656/1507 +f 1497/1632/1654 1350/1957/1503 1498/1633/1655 +f 1349/1958/1502 1498/1633/1655 1350/1957/1503 +f 1498/1633/1655 1349/1958/1502 1499/1634/1656 +f 1870/1959/1499 1499/1634/1656 1349/1958/1502 +f 1499/1634/1656 1870/1959/1499 1500/1635/1657 +f 1345/1960/1494 1500/1635/1657 1870/1959/1499 +f 1500/1635/1657 1345/1960/1494 1507/1642/1664 +f 1509/1643/1493 1507/1642/1664 1345/1960/1494 +f 1507/1642/1664 1509/1643/1493 1504/1639/1661 +f 1635/1788/1786 1642/1796/1445 1630/1782/1785 +f 1871/1961/1444 1630/1782/1785 1642/1796/1445 +f 1630/1782/1785 1871/1961/1444 1629/1781/1784 +f 1297/1962/1212 1629/1781/1784 1871/1961/1444 +f 1629/1781/1784 1297/1962/1212 1872/1963/1213 +f 1872/1963/1213 1627/1779/1782 1629/1781/1784 +f 1627/1779/1782 1872/1963/1213 1873/1964/1214 +f 1873/1964/1214 1625/1777/1780 1627/1779/1782 +f 1625/1777/1780 1873/1964/1214 1631/1783/1058 +f 1631/1783/1058 1624/1776/1779 1625/1777/1780 +f 1902/1955/1977 1869/1954/279 1888/1965/274 +f 101/114/109 100/112/107 90/100/95 +f 86/95/90 101/114/109 90/100/95 +f 101/114/109 86/95/90 102/113/108 +f 86/95/90 81/90/85 102/113/108 +f 81/90/85 115/127/122 102/113/108 +f 115/127/122 81/90/85 1874/1966/1204 +f 81/90/85 80/89/84 1874/1966/1204 +f 80/89/84 1875/1967/1807 1874/1966/1204 +f 1875/1967/1807 80/89/84 9/12/12 +f 9/12/12 11/11/11 1875/1967/1807 +f 1885/1956/1978 1596/1745/1752 1876/1744/1751 +f 1235/1338/1384 1228/1331/1377 1222/1325/1371 +f 1222/1325/1371 1221/1324/1370 1235/1338/1384 +f 1866/1341/1387 1235/1338/1384 1221/1324/1370 +f 1221/1324/1370 1877/1968/1419 1866/1341/1387 +f 1877/1968/1419 1221/1324/1370 1215/1318/1364 +f 1215/1318/1364 1269/1316/1362 1877/1968/1419 +f 1237/1340/1386 1248/1352/1398 1236/1339/1385 +f 1596/1745/1752 1885/1956/1978 1902/1955/1977 +f 1879/1376/1420 1878/1378/1422 1271/1377/1421 +f 1869/1954/279 1876/1744/1751 1880/562/280 +f 782/1969/909 1423/1970/1584 1418/1971/1579 +f 1423/1970/1584 782/1969/909 1881/1972/1979 +f 1881/1972/1979 1882/1973/1156 1423/1970/1584 +f 1882/1973/1156 1881/1972/1979 1030/1974/1155 +f 1881/1972/1979 1883/1975/1172 1030/1974/1155 +f 1883/1975/1172 1881/1972/1979 1884/1976/896 +f 782/1969/909 1884/1976/896 1881/1972/1979 +f 1884/1976/896 782/1969/909 771/1977/894 +f 1876/1744/1751 1869/1954/279 1885/1956/1978 +f 1838/1918/1010 1886/1142/1160 1037/1149/628 +f 252/1978/273 1887/1979/1980 1888/1965/274 +f 1890/1673/1688 1889/1676/1691 1531/1668/1683 +f 1887/1979/1980 252/1978/273 1891/1980/227 +f 1893/1462/1495 1892/1464/1497 1346/1463/1496 +f 1887/1979/1980 1894/1981/216 1897/1982/1981 +f 1634/788/838 720/784/834 1451/1983/1612 +f 1894/1981/216 1887/1979/1980 1891/1980/227 +f 1429/1557/1590 1455/1931/836 719/1938/835 +f 1902/1955/1977 1887/1979/1980 1900/1984/1982 +f 1896/779/829 1898/1985/188 1895/1986/189 +f 1887/1979/1980 1902/1955/1977 1888/1965/274 +f 1898/1985/188 1896/779/829 1899/1987/1983 +f 1900/1984/1982 1897/1982/1981 1907/1988/1984 +f 1899/1987/1983 189/1989/204 1898/1985/188 +f 189/1989/204 1899/1987/1983 1943/1990/1985 +f 1901/1991/1986 1949/778/828 1906/1992/1987 +f 1897/1982/1981 1900/1984/1982 1887/1979/1980 +f 1949/778/828 1901/1991/1986 1946/1993/1988 +f 1596/1745/1752 1900/1984/1982 1905/1994/1989 +f 1947/1995/1990 1946/1993/1988 1901/1991/1986 +f 1900/1984/1982 1596/1745/1752 1902/1955/1977 +f 1946/1993/1988 1947/1995/1990 1948/1996/1991 +f 1905/1994/1989 1907/1988/1984 1903/1997/1992 +f 1903/1997/1992 1901/1991/1986 1906/1992/1987 +f 1907/1988/1984 1905/1994/1989 1900/1984/1982 +f 1901/1991/1986 1903/1997/1992 1904/1998/1993 +f 1908/688/738 1905/1994/1989 1910/1999/1994 +f 1904/1998/1993 1947/1995/1990 1901/1991/1986 +f 1905/1994/1989 1908/688/738 1596/1745/1752 +f 1947/1995/1990 1904/1998/1993 1922/2000/1995 +f 1910/1999/1994 1903/1997/1992 1906/1992/1987 +f 1907/1988/1984 1904/1998/1993 1903/1997/1992 +f 1903/1997/1992 1910/1999/1994 1905/1994/1989 +f 1904/1998/1993 1907/1988/1984 1911/2001/1996 +f 1909/1157/1167 1908/688/738 1910/1999/1994 +f 1911/2001/1996 1922/2000/1995 1904/1998/1993 +f 1908/688/738 1909/1157/1167 524/563/600 +f 1922/2000/1995 1911/2001/1996 1913/2002/1997 +f 1949/778/828 1910/1999/1994 1906/1992/1987 +f 1897/1982/1981 1911/2001/1996 1907/1988/1984 +f 1910/1999/1994 1949/778/828 1909/1157/1167 +f 1911/2001/1996 1897/1982/1981 1915/2003/1998 +f 1912/1939/293 1097/777/827 177/2004/190 +f 1915/2003/1998 1913/2002/1997 1911/2001/1996 +f 1097/777/827 1912/1939/293 1854/1225/1215 +f 1913/2002/1997 1915/2003/1998 1926/2005/219 +f 177/2004/190 1896/779/829 1895/1986/189 +f 1894/1981/216 1915/2003/1998 1897/1982/1981 +f 1896/779/829 177/2004/190 1097/777/827 +f 1915/2003/1998 1894/1981/216 1914/2006/217 +f 552/586/636 1041/575/625 1040/585/1166 +f 1915/2003/1998 1918/2007/218 1926/2005/219 +f 1917/872/843 784/864/910 1916/871/842 +f 1918/2007/218 1915/2003/1998 1914/2006/217 +f 629/668/718 631/670/720 630/669/719 +f 1941/2008/1999 1920/2009/220 201/2010/221 +f 618/655/705 1919/807/857 733/804/854 +f 1920/2009/220 1941/2008/1999 1923/2011/2000 +f 548/579/629 1838/985/1010 1037/578/628 +f 1922/2000/1995 1923/2011/2000 1941/2008/1999 +f 1921/937/967 843/935/965 844/936/966 +f 1923/2011/2000 1922/2000/1995 1913/2002/1997 +f 683/738/788 1924/750/800 1925/748/798 +f 1913/2002/1997 1920/2009/220 1923/2011/2000 +f 1070/1187/1188 1072/1189/1190 1088/1208/1207 +f 1920/2009/220 1913/2002/1997 1926/2005/219 +f 1927/2012/2001 2054/2013/2002 2053/2014/2003 +f 2054/2013/2002 1927/2012/2001 2075/2015/2004 +f 2075/2015/2004 2213/2016/2005 2054/2013/2002 +f 2213/2016/2005 2075/2015/2004 2214/2017/2006 +f 1930/2018/2007 1928/2019/2008 1929/2020/2009 +f 1928/2019/2008 1930/2018/2007 1931/2021/2010 +f 1931/2021/2010 1932/2022/2011 1928/2019/2008 +f 1932/2022/2011 1931/2021/2010 1933/2023/2012 +f 1933/2023/2012 1934/2024/2013 1932/2022/2011 +f 1934/2024/2013 1933/2023/2012 1935/2025/2014 +f 1933/2023/2012 1936/2026/2015 1935/2025/2014 +f 1936/2026/2015 1933/2023/2012 1937/2027/2016 +f 1931/2021/2010 1937/2027/2016 1933/2023/2012 +f 1937/2027/2016 1931/2021/2010 1938/2028/2017 +f 1930/2018/2007 1938/2028/2017 1931/2021/2010 +f 1938/2028/2017 1930/2018/2007 1939/2029/2018 +f 188/2030/203 1943/1990/1985 1942/2031/202 +f 1940/2032/2019 2052/2033/2020 2066/2034/2021 +f 1943/1990/1985 188/2030/203 189/1989/204 +f 2052/2033/2020 1940/2032/2019 2046/2035/2022 +f 1941/2008/1999 1947/1995/1990 1922/2000/1995 +f 2046/2035/2022 2004/2036/2023 2052/2033/2020 +f 1947/1995/1990 1941/2008/1999 201/2010/221 +f 2004/2036/2023 2046/2035/2022 2047/2037/2024 +f 1943/1990/1985 1944/2038/200 1942/2031/202 +f 2047/2037/2024 1945/2039/2025 2004/2036/2023 +f 1944/2038/200 1943/1990/1985 1948/1996/1991 +f 1945/2039/2025 2047/2037/2024 2057/2040/2026 +f 1946/1993/1988 1943/1990/1985 1899/1987/1983 +f 201/2010/221 1948/1996/1991 1947/1995/1990 +f 1943/1990/1985 1946/1993/1988 1948/1996/1991 +f 1948/1996/1991 201/2010/221 1944/2038/200 +f 1949/778/828 1899/1987/1983 1896/779/829 +f 1899/1987/1983 1949/778/828 1946/1993/1988 +f 2073/526/2027 2215/2041/2028 2072/2042/2029 +f 2215/2041/2028 2073/526/2027 1950/2043/2030 +f 1951/2044/2031 2000/2045/2032 2001/2046/2033 +f 2000/2045/2032 1951/2044/2031 1952/2047/2034 +f 1952/2047/2034 2226/2048/2035 2000/2045/2032 +f 2226/2048/2035 1952/2047/2034 2224/2049/2036 +f 1953/2050/2037 2056/2051/2038 2074/2052/2039 +f 2056/2051/2038 1953/2050/2037 2055/2053/2040 +f 1954/2054/2041 2055/2053/2040 1953/2050/2037 +f 2055/2053/2040 1954/2054/2041 1955/2055/2042 +f 1956/2056/2043 1998/2057/2044 1999/2058/2045 +f 1998/2057/2044 1956/2056/2043 2211/2059/2046 +f 2211/2059/2046 2233/440/2047 1998/2057/2044 +f 2233/440/2047 2211/2059/2046 1957/2060/2048 +f 1959/2061/2049 2005/2062/2050 1958/2063/2051 +f 2005/2062/2050 1959/2061/2049 1960/2064/2052 +f 2158/2065/2053 2248/2066/2054 2010/2067/2055 +f 2248/2066/2054 2158/2065/2053 2247/2068/2056 +f 2184/2069/2057 1961/2070/2058 2011/2071/2059 +f 1961/2070/2058 2184/2069/2057 1962/2072/2060 +f 2080/2073/2061 2015/2074/2062 2081/2075/2063 +f 2015/2074/2062 2080/2073/2061 1963/2076/2064 +f 1964/1226/2065 2244/2077/2066 2016/2078/2067 +f 2244/2077/2066 1964/1226/2065 2208/2079/2056 +f 1965/2080/2068 2242/2081/2069 2093/2082/2070 +f 2242/2081/2069 1965/2080/2068 2019/2083/2071 +f 1966/2084/2072 2019/2083/2071 1965/2080/2068 +f 2019/2083/2071 1966/2084/2072 2018/2085/2073 +f 2097/2086/2074 2023/2087/2075 1967/2088/2076 +f 2023/2087/2075 2097/2086/2074 2024/2089/2077 +f 1969/1226/2078 2241/2087/2079 1968/2090/2080 +f 2241/2087/2079 1969/1226/2078 1970/2091/2081 +f 2101/435/2082 2028/2092/2083 1971/2093/2084 +f 2028/2092/2083 2101/435/2082 2027/2094/2085 +f 1973/501/2086 2029/2095/2087 1972/2096/2088 +f 2029/2095/2087 1973/501/2086 2082/545/2089 +f 1974/511/2090 2237/2097/2091 2030/2098/2092 +f 2237/2097/2091 1974/511/2090 1975/2099/2093 +f 1977/2100/2094 2234/2101/2095 1976/2102/2096 +f 2234/2101/2095 1977/2100/2094 2235/2103/2097 +f 1979/2104/2098 1978/2105/2099 2231/2106/2100 +f 1978/2105/2099 1979/2104/2098 2032/2094/2101 +f 1981/2107/2102 1980/2108/2103 2161/2109/2104 +f 1980/2108/2103 1981/2107/2102 1982/2110/2105 +f 2136/2111/2106 1983/2112/2107 1984/2113/2108 +f 1983/2112/2107 2136/2111/2106 1985/2063/2109 +f 2091/2114/2110 2229/2115/2111 2037/2116/2112 +f 2229/2115/2111 2091/2114/2110 2228/2117/2113 +f 1987/1246/2114 2040/2118/2115 1986/2119/2104 +f 2040/2118/2115 1987/1246/2114 2041/1228/2116 +f 2102/2086/2117 2223/2087/2118 2042/2089/2119 +f 2223/2087/2118 2102/2086/2117 2221/2088/2120 +f 2105/435/2121 2219/2120/2122 1988/2121/2123 +f 2219/2120/2122 2105/435/2121 1989/2122/2124 +f 1992/1246/2125 1990/2123/2126 1991/2124/2127 +f 1990/2123/2126 1992/1246/2125 2106/2125/2128 +f 2069/501/2129 2217/2095/2130 1993/545/2131 +f 2217/2095/2130 2069/501/2129 2045/2096/2132 +f 2071/1232/2133 1994/2126/2134 2070/2127/2135 +f 1994/2126/2134 2071/1232/2133 1995/543/2136 +f 1997/1261/1257 1950/2043/2030 1996/1262/1258 +f 1950/2043/2030 1997/1261/1257 2215/2041/2028 +f 508/545/583 1998/2057/2044 2233/440/2047 +f 1998/2057/2044 508/545/583 509/547/585 +f 509/547/585 1999/2058/2045 1998/2057/2044 +f 1999/2058/2045 509/547/585 511/549/587 +f 1104/1243/1233 2000/2045/2032 2226/2048/2035 +f 2000/2045/2032 1104/1243/1233 1105/1245/1235 +f 1105/1245/1235 2001/2046/2033 2000/2045/2032 +f 2001/2046/2033 1105/1245/1235 1106/1247/1237 +f 2050/459/497 2002/2128/2137 2003/471/509 +f 2002/2128/2137 2050/459/497 2049/2129/2138 +f 2004/2036/2023 2002/2128/2137 2049/2129/2138 +f 2002/2128/2137 2004/2036/2023 1945/2039/2025 +f 2006/502/540 1958/2063/2051 2005/2062/2050 +f 1958/2063/2051 2006/502/540 2007/504/542 +f 2008/506/544 2010/2067/2055 2248/2066/2054 +f 2010/2067/2055 2008/506/544 2009/508/546 +f 2012/510/548 2011/2071/2059 1961/2070/2058 +f 2011/2071/2059 2012/510/548 2013/511/550 +f 2245/513/552 1963/2076/2064 2014/514/553 +f 1963/2076/2064 2245/513/552 2015/2074/2062 +f 2017/517/556 2016/2078/2067 2244/2077/2066 +f 2016/2078/2067 2017/517/556 499/519/558 +f 2020/436/474 2018/2085/2073 442/437/475 +f 2018/2085/2073 2020/436/474 2019/2083/2071 +f 2021/439/477 2019/2083/2071 2020/436/474 +f 2019/2083/2071 2021/439/477 2242/2081/2069 +f 2022/521/560 2024/2089/2077 500/522/561 +f 2024/2089/2077 2022/521/560 2023/2087/2075 +f 2026/525/564 1970/2091/2081 2025/526/565 +f 1970/2091/2081 2026/525/564 2241/2087/2079 +f 501/529/568 2027/2094/2085 502/530/569 +f 2027/2094/2085 501/529/568 2028/2092/2083 +f 2239/533/572 1972/2096/2088 2029/2095/2087 +f 1972/2096/2088 2239/533/572 504/535/574 +f 505/537/576 2030/2098/2092 2237/2097/2091 +f 2030/2098/2092 505/537/576 2083/539/571 +f 2031/541/579 1976/2102/2096 2234/2101/2095 +f 1976/2102/2096 2031/541/579 507/543/581 +f 2033/1876/1893 2032/2094/2101 1758/1877/1896 +f 2032/2094/2101 2033/1876/1893 1978/2105/2099 +f 2230/1227/1217 1982/2110/2105 1098/1228/1218 +f 1982/2110/2105 2230/1227/1217 1980/2108/2103 +f 1100/1231/1221 1985/2063/2109 2034/1232/1222 +f 1985/2063/2109 1100/1231/1221 1983/2112/2107 +f 2035/1235/1225 2037/2116/2112 2229/2115/2111 +f 2037/2116/2112 2035/1235/1225 2036/1237/1227 +f 2039/1239/1229 2041/1228/2116 2038/1240/1230 +f 2041/1228/2116 2039/1239/1229 2040/2118/2115 +f 2222/521/1239 2042/2089/2119 2223/2087/2118 +f 2042/2089/2119 2222/521/1239 1107/522/1241 +f 2043/1249/1243 1988/2121/2123 2219/2120/2122 +f 1988/2121/2123 2043/1249/1243 1109/1251/1245 +f 2044/1253/1247 1991/2124/2127 1990/2123/2126 +f 1991/2124/2127 2044/1253/1247 1110/1255/1249 +f 1111/533/1251 2045/2096/2132 504/535/574 +f 2045/2096/2132 1111/533/1251 2217/2095/2130 +f 2216/537/1254 1995/2098/2136 2068/539/1250 +f 1995/2098/2136 2216/537/1254 1994/2097/2134 +f 2063/2130/2139 2047/2131/2024 2046/2132/2022 +f 2047/2131/2024 2063/2130/2139 2058/2133/2140 +f 2063/2130/2139 2048/2134/498 2058/2133/2140 +f 2048/2134/498 2063/2130/2139 2062/2135/481 +f 2051/442/480 2049/2129/2138 2050/459/497 +f 2049/2129/2138 2051/442/480 2061/2136/2141 +f 2052/2033/2020 2049/2129/2138 2061/2136/2141 +f 2049/2129/2138 2052/2033/2020 2004/2036/2023 +f 2054/2013/2002 1955/2055/2042 2053/2014/2003 +f 1955/2055/2042 2054/2013/2002 2055/2053/2040 +f 2213/2016/2005 2055/2053/2040 2054/2013/2002 +f 2055/2053/2040 2213/2016/2005 2056/2051/2038 +f 2058/2133/2140 2057/2137/2026 2047/2131/2024 +f 2057/2137/2026 2058/2133/2140 2059/2138/2142 +f 2058/2133/2140 2060/2139/510 2059/2138/2142 +f 2060/2139/510 2058/2133/2140 2048/2134/498 +f 452/451/489 2061/2136/2141 2051/442/480 +f 2061/2136/2141 452/451/489 2064/2140/2143 +f 2066/2034/2021 2061/2136/2141 2064/2140/2143 +f 2061/2136/2141 2066/2034/2021 2052/2033/2020 +f 2062/2135/481 2065/2141/2144 444/2142/479 +f 2065/2141/2144 2062/2135/481 2063/2130/2139 +f 2046/2132/2022 2065/2141/2144 2063/2130/2139 +f 2065/2141/2144 2046/2132/2022 1940/2143/2019 +f 444/441/479 2064/2140/2143 452/451/489 +f 2064/2140/2143 444/441/479 2065/2144/2144 +f 1940/2032/2019 2064/2140/2143 2065/2144/2144 +f 2064/2140/2143 1940/2032/2019 2066/2034/2021 +f 2067/2145/2145 1986/2119/2104 2132/2146/2146 +f 2068/532/1250 1993/545/2131 1112/534/1252 +f 1993/545/2131 2068/532/1250 2069/501/2129 +f 1113/1256/1253 2070/2127/2135 1114/1259/1255 +f 2070/2127/2135 1113/1256/1253 2071/1232/2133 +f 1115/1260/1256 2072/2042/2029 1116/1263/1259 +f 2072/2042/2029 1115/1260/1256 2073/526/2027 +f 2075/2015/2004 2074/2052/2039 2214/2017/2006 +f 2074/2052/2039 2075/2015/2004 1953/2050/2037 +f 1927/2012/2001 1953/2050/2037 2075/2015/2004 +f 1953/2050/2037 1927/2012/2001 1954/2054/2041 +f 2126/2147/2147 2112/2148/2148 2118/2149/2149 +f 2112/2148/2148 2126/2147/2147 2124/2150/2150 +f 2122/2151/2151 2126/2147/2147 2127/2152/2152 +f 2126/2147/2147 2122/2151/2151 2124/2150/2150 +f 2076/2121/2153 2145/2153/2154 2148/2154/2155 +f 2145/2153/2154 2076/2121/2153 2147/2155/2156 +f 2169/1228/2157 2077/2156/2158 2078/2157/2159 +f 2077/2156/2158 2169/1228/2157 2172/2158/2160 +f 2079/512/551 2081/2075/2063 2246/515/554 +f 2081/2075/2063 2079/512/551 2080/2073/2061 +f 2083/532/571 2082/545/2089 1973/501/2086 +f 2082/545/2089 2083/532/571 503/534/573 +f 2084/536/575 1975/2099/2093 1974/511/2090 +f 1975/2099/2093 2084/536/575 2238/538/577 +f 506/540/578 2235/2103/2097 1977/2100/2094 +f 2235/2103/2097 506/540/578 2236/542/580 +f 2086/2159/2161 2198/2160/2162 2085/2161/2163 +f 2198/2160/2162 2086/2159/2161 2087/2162/2164 +f 2170/2163/2165 2174/2164/2166 2171/2165/2167 +f 2174/2164/2166 2170/2163/2165 2088/2063/2168 +f 2089/2166/2169 2150/2167/2170 2149/2168/2171 +f 2150/2167/2170 2089/2166/2169 2090/2169/2172 +f 1102/1234/1224 2228/2117/2113 2091/2114/2110 +f 2228/2117/2113 1102/1234/1224 1101/1236/1226 +f 2200/2170/2173 2196/2171/2174 2205/2172/2175 +f 2196/2171/2174 2200/2170/2173 2092/2173/2176 +f 2094/438/476 2093/2082/2070 2243/440/478 +f 2093/2082/2070 2094/438/476 1965/2080/2068 +f 443/435/473 1965/2080/2068 2094/438/476 +f 1965/2080/2068 443/435/473 1966/2084/2072 +f 2096/520/559 1967/2088/2076 2095/523/562 +f 1967/2088/2076 2096/520/559 2097/2086/2074 +f 2099/524/563 1968/2090/2080 2098/527/566 +f 1968/2090/2080 2099/524/563 1969/1226/2078 +f 2100/528/567 1971/2093/2084 2240/531/570 +f 1971/2093/2084 2100/528/567 2101/435/2082 +f 2103/520/1238 2221/2088/2120 2102/2086/2117 +f 2221/2088/2120 2103/520/1238 2104/523/1240 +f 1108/1248/1242 1989/2122/2124 2105/435/2121 +f 1989/2122/2124 1108/1248/1242 2220/1250/1244 +f 2107/1252/1246 2106/2125/2128 1992/1246/2125 +f 2106/2125/2128 2107/1252/1246 2218/1254/1248 +f 2125/2174/2177 2108/2175/2178 2119/2176/2179 +f 2108/2175/2178 2125/2174/2177 2123/2177/2180 +f 2109/1246/1236 1952/2047/2034 1951/2044/2031 +f 1952/2047/2034 2109/1246/1236 2110/1242/1232 +f 2110/1242/1232 2224/2049/2036 1952/2047/2034 +f 2224/2049/2036 2110/1242/1232 2225/1244/1234 +f 1986/2119/2104 2067/2145/2145 1987/1246/2114 +f 2112/2148/2148 2121/545/2181 2114/2081/2182 +f 2131/2178/2183 1103/1238/1228 2111/2069/2184 +f 2121/545/2181 2112/2148/2148 2113/503/541 +f 1103/1238/1228 2131/2178/2183 2227/1241/1231 +f 2118/2149/2149 2114/2081/2182 2117/2179/2185 +f 2115/2180/2186 2134/2181/2187 2130/2182/2188 +f 2114/2081/2182 2118/2149/2149 2112/2148/2148 +f 2134/2181/2187 2115/2180/2186 2116/2183/2189 +f 1960/2064/2052 2117/2179/2185 2120/2180/2190 +f 2119/2176/2179 2132/2146/2146 2125/2174/2177 +f 2117/2179/2185 1960/2064/2052 2118/2149/2149 +f 2132/2146/2146 2119/2176/2179 2067/2145/2145 +f 2113/503/541 2120/2180/2190 2121/545/2181 +f 2123/2177/2180 2111/2069/2184 2108/2175/2178 +f 2120/2180/2190 2113/503/541 1960/2064/2052 +f 2111/2069/2184 2123/2177/2180 2131/2178/2183 +f 2128/2184/2191 2124/2150/2150 2122/2151/2151 +f 2125/2174/2177 2131/2178/2183 2123/2177/2180 +f 2124/2150/2150 2128/2184/2191 2112/2148/2148 +f 2131/2178/2183 2125/2174/2177 2132/2146/2146 +f 2118/2149/2149 2127/2152/2152 2126/2147/2147 +f 2116/2183/2189 2227/1241/1231 2134/2181/2187 +f 2127/2152/2152 2118/2149/2149 2133/2185/2192 +f 2227/1241/1231 2116/2183/2189 1986/2119/2104 +f 2121/545/2181 2117/2179/2185 2114/2081/2182 +f 2115/2180/2186 1986/2119/2104 2116/2183/2189 +f 2117/2179/2185 2121/545/2181 2120/2180/2190 +f 1986/2119/2104 2115/2180/2186 2132/2146/2146 +f 2129/501/539 2112/2148/2148 2128/2184/2191 +f 2130/2182/2188 2132/2146/2146 2115/2180/2186 +f 2112/2148/2148 2129/501/539 2113/503/541 +f 2132/2146/2146 2130/2182/2188 2131/2178/2183 +f 1960/2064/2052 2133/2185/2192 2118/2149/2149 +f 2134/2181/2187 2131/2178/2183 2130/2182/2188 +f 2133/2185/2192 1960/2064/2052 1959/2061/2049 +f 2131/2178/2183 2134/2181/2187 2227/1241/1231 +f 2155/2186/2193 2152/2187/2194 2140/2188/2195 +f 2135/2189/2196 1984/2113/2108 2154/2190/2197 +f 2152/2187/2194 2155/2186/2193 2143/507/545 +f 1984/2113/2108 2135/2189/2196 2136/2111/2106 +f 2144/2191/2198 2140/2188/2195 2153/2192/2199 +f 2139/2193/2200 2137/1230/1220 2138/2157/2201 +f 2140/2188/2195 2144/2191/2198 2155/2186/2193 +f 2137/1230/1220 2139/2193/2200 2160/1233/1223 +f 2247/2068/2056 2153/2192/2199 2142/2194/2202 +f 2141/2195/2203 2157/2060/2204 2156/2196/2205 +f 2153/2192/2199 2247/2068/2056 2144/2191/2198 +f 2157/2060/2204 2141/2195/2203 2151/2197/2206 +f 2143/507/545 2142/2194/2202 2152/2187/2194 +f 2090/2169/2172 2154/2190/2197 2150/2167/2170 +f 2142/2194/2202 2143/507/545 2247/2068/2056 +f 2154/2190/2197 2090/2169/2172 2135/2189/2196 +f 2155/2186/2193 2145/2153/2154 2147/2155/2156 +f 2145/2153/2154 2155/2186/2193 2144/2191/2198 +f 2146/2198/2207 2147/2155/2156 2076/2121/2153 +f 2149/2168/2171 2138/2157/2201 2089/2166/2169 +f 2147/2155/2156 2146/2198/2207 2155/2186/2193 +f 2138/2157/2201 2149/2168/2171 2139/2193/2200 +f 2144/2191/2198 2148/2154/2155 2145/2153/2154 +f 2150/2167/2170 2139/2193/2200 2149/2168/2171 +f 2139/2193/2200 2150/2167/2170 2154/2190/2197 +f 2151/2197/2206 2160/1233/1223 2157/2060/2204 +f 2148/2154/2155 2144/2191/2198 2159/530/2208 +f 2160/1233/1223 2151/2197/2206 1984/2113/2108 +f 2152/2187/2194 2153/2192/2199 2140/2188/2195 +f 2141/2195/2203 1984/2113/2108 2151/2197/2206 +f 2153/2192/2199 2152/2187/2194 2142/2194/2202 +f 1984/2113/2108 2141/2195/2203 2154/2190/2197 +f 498/505/543 2155/2186/2193 2146/2198/2207 +f 2156/2196/2205 2154/2190/2197 2141/2195/2203 +f 2155/2186/2193 498/505/543 2143/507/545 +f 2154/2190/2197 2156/2196/2205 2139/2193/2200 +f 2247/2068/2056 2159/530/2208 2144/2191/2198 +f 2157/2060/2204 2139/2193/2200 2156/2196/2205 +f 2159/530/2208 2247/2068/2056 2158/2065/2053 +f 2139/2193/2200 2157/2060/2204 2160/1233/1223 +f 2181/2199/2209 2176/2200/2210 2164/2126/2211 +f 2163/1255/2212 2161/2109/2104 2183/2201/2213 +f 2176/2200/2210 2181/2199/2209 2162/503/549 +f 2161/2109/2104 2163/1255/2212 1981/2107/2102 +f 2165/2202/2214 2164/2126/2211 2168/2203/2215 +f 2166/2204/2216 1099/1226/1216 2173/2056/2217 +f 2164/2126/2211 2165/2202/2214 2181/2199/2209 +f 1099/1226/1216 2166/2204/2216 2187/1229/1219 +f 1962/2072/2060 2168/2203/2215 2177/2205/2218 +f 2179/2206/2219 2167/2122/2220 2185/2207/2221 +f 2168/2203/2215 1962/2072/2060 2165/2202/2214 +f 2167/2122/2220 2179/2206/2219 2175/2208/2222 +f 2162/503/549 2177/2205/2218 2176/2200/2210 +f 2088/2063/2168 2183/2201/2213 2174/2164/2166 +f 2177/2205/2218 2162/503/549 1962/2072/2060 +f 2183/2201/2213 2088/2063/2168 2163/1255/2212 +f 2181/2199/2209 2077/2156/2158 2172/2158/2160 +f 2077/2156/2158 2181/2199/2209 2165/2202/2214 +f 2178/2209/2223 2172/2158/2160 2169/1228/2157 +f 2171/2165/2167 2173/2056/2217 2170/2163/2165 +f 2172/2158/2160 2178/2209/2223 2181/2199/2209 +f 2173/2056/2217 2171/2165/2167 2166/2204/2216 +f 2165/2202/2214 2078/2157/2159 2077/2156/2158 +f 2174/2164/2166 2166/2204/2216 2171/2165/2167 +f 2166/2204/2216 2174/2164/2166 2183/2201/2213 +f 2175/2208/2222 2187/1229/1219 2167/2122/2220 +f 2078/2157/2159 2165/2202/2214 2182/2210/2224 +f 2187/1229/1219 2175/2208/2222 2161/2109/2104 +f 2176/2200/2210 2168/2203/2215 2164/2126/2211 +f 2168/2203/2215 2176/2200/2210 2177/2205/2218 +f 2180/509/547 2181/2199/2209 2178/2209/2223 +f 2179/2206/2219 2161/2109/2104 2175/2208/2222 +f 2181/2199/2209 2180/509/547 2162/503/549 +f 2161/2109/2104 2179/2206/2219 2183/2201/2213 +f 1962/2072/2060 2182/2210/2224 2165/2202/2214 +f 2185/2207/2221 2183/2201/2213 2179/2206/2219 +f 2182/2210/2224 1962/2072/2060 2184/2069/2057 +f 2183/2201/2213 2185/2207/2221 2166/2204/2216 +f 2197/2211/2225 2192/2212/2226 2186/2213/2227 +f 2167/2122/2220 2166/2204/2216 2185/2207/2221 +f 2192/2212/2226 2197/2211/2225 2193/518/557 +f 2166/2204/2216 2167/2122/2220 2187/1229/1219 +f 2190/2214/2228 2186/2213/2227 2191/2215/2229 +f 2188/2107/2230 2231/2106/2100 2199/2216/2231 +f 2186/2213/2227 2190/2214/2228 2197/2211/2225 +f 2231/2106/2100 2188/2107/2230 1979/2104/2098 +f 2208/2079/2056 2191/2215/2229 2194/2217/2232 +f 2202/2218/2233 1757/1258/1894 2189/2162/2234 +f 2191/2215/2229 2208/2079/2056 2190/2214/2228 +f 1757/1258/1894 2202/2218/2233 2203/1233/1895 +f 2193/518/557 2194/2217/2232 2192/2212/2226 +f 2206/2203/2235 2210/2016/2236 2209/2048/2237 +f 2194/2217/2232 2193/518/557 2208/2079/2056 +f 2210/2016/2236 2206/2203/2235 2195/2219/2238 +f 2197/2211/2225 2196/2171/2174 2092/2173/2176 +f 2087/2162/2164 2199/2216/2231 2198/2160/2162 +f 2196/2171/2174 2197/2211/2225 2190/2214/2228 +f 2199/2216/2231 2087/2162/2164 2188/2107/2230 +f 2201/522/2239 2092/2173/2176 2200/2170/2173 +f 2085/2161/2163 2189/2162/2234 2086/2159/2161 +f 2092/2173/2176 2201/522/2239 2197/2211/2225 +f 2189/2162/2234 2085/2161/2163 2202/2218/2233 +f 2190/2214/2228 2205/2172/2175 2196/2171/2174 +f 2198/2160/2162 2202/2218/2233 2085/2161/2163 +f 2202/2218/2233 2198/2160/2162 2199/2216/2231 +f 2195/2219/2238 2203/1233/1895 2210/2016/2236 +f 2205/2172/2175 2190/2214/2228 2204/2220/2240 +f 2203/1233/1895 2195/2219/2238 2231/2106/2100 +f 2192/2212/2226 2191/2215/2229 2186/2213/2227 +f 2206/2203/2235 2231/2106/2100 2195/2219/2238 +f 2191/2215/2229 2192/2212/2226 2194/2217/2232 +f 2231/2106/2100 2206/2203/2235 2199/2216/2231 +f 2207/516/555 2197/2211/2225 2201/522/2239 +f 2209/2048/2237 2199/2216/2231 2206/2203/2235 +f 2197/2211/2225 2207/516/555 2193/518/557 +f 2199/2216/2231 2209/2048/2237 2202/2218/2233 +f 2208/2079/2056 2204/2220/2240 2190/2214/2228 +f 2210/2016/2236 2202/2218/2233 2209/2048/2237 +f 2204/2220/2240 2208/2079/2056 1964/1226/2065 +f 2202/2218/2233 2210/2016/2236 2203/1233/1895 +f 510/548/586 2211/2059/2046 1956/2056/2043 +f 2211/2059/2046 510/548/586 2212/544/582 +f 2212/544/582 1957/2060/2048 2211/2059/2046 +f 1957/2060/2048 2212/544/582 2232/546/584 +f 2214/2017/2006 2056/2051/2038 2213/2016/2005 +f 2056/2051/2038 2214/2017/2006 2074/2052/2039 +f 1116/1263/1259 2215/2041/2028 1997/1261/1257 +f 2215/2041/2028 1116/1263/1259 2072/2042/2029 +f 1114/1259/1255 1994/2126/2134 2216/1257/1254 +f 1994/2126/2134 1114/1259/1255 2070/2127/2135 +f 1112/534/1252 2217/2095/2130 1111/533/1251 +f 2217/2095/2130 1112/534/1252 1993/545/2131 +f 2218/1254/1248 1990/2123/2126 2106/2125/2128 +f 1990/2123/2126 2218/1254/1248 2044/1253/1247 +f 2220/1250/1244 2219/2120/2122 1989/2122/2124 +f 2219/2120/2122 2220/1250/1244 2043/1249/1243 +f 2104/523/1240 2223/2087/2118 2221/2088/2120 +f 2223/2087/2118 2104/523/1240 2222/521/1239 +f 2225/1244/1234 2226/2048/2035 2224/2049/2036 +f 2226/2048/2035 2225/1244/1234 1104/1243/1233 +f 2227/1241/1231 2040/2118/2115 2039/1239/1229 +f 2040/2118/2115 2227/1241/1231 1986/2119/2104 +f 1101/1236/1226 2229/2115/2111 2228/2117/2113 +f 2229/2115/2111 1101/1236/1226 2035/1235/1225 +f 2160/1233/1223 1983/2112/2107 1100/1231/1221 +f 1983/2112/2107 2160/1233/1223 1984/2113/2108 +f 2187/1229/1219 1980/2108/2103 2230/1227/1217 +f 1980/2108/2103 2187/1229/1219 2161/2109/2104 +f 2203/1233/1895 1978/2105/2099 2033/1876/1893 +f 1978/2105/2099 2203/1233/1895 2231/2106/2100 +f 2232/546/584 2233/440/2047 1957/2060/2048 +f 2233/440/2047 2232/546/584 508/545/583 +f 2236/542/580 2234/2101/2095 2235/2103/2097 +f 2234/2101/2095 2236/542/580 2031/541/579 +f 2238/538/577 2237/2097/2091 1975/2099/2093 +f 2237/2097/2091 2238/538/577 505/537/576 +f 503/534/573 2029/2095/2087 2082/545/2089 +f 2029/2095/2087 503/534/573 2239/533/572 +f 2240/531/570 2028/2092/2083 501/529/568 +f 2028/2092/2083 2240/531/570 1971/2093/2084 +f 2098/527/566 2241/2087/2079 2026/525/564 +f 2241/2087/2079 2098/527/566 1968/2090/2080 +f 2095/523/562 2023/2087/2075 2022/521/560 +f 2023/2087/2075 2095/523/562 1967/2088/2076 +f 2243/440/478 2242/2081/2069 2021/439/477 +f 2242/2081/2069 2243/440/478 2093/2082/2070 +f 2193/518/557 2244/2077/2066 2208/2079/2056 +f 2244/2077/2066 2193/518/557 2017/517/556 +f 2246/515/554 2015/2074/2062 2245/513/552 +f 2015/2074/2062 2246/515/554 2081/2075/2063 +f 2162/503/549 1961/2070/2058 1962/2072/2060 +f 1961/2070/2058 2162/503/549 2012/510/548 +f 2143/507/545 2248/2066/2054 2247/2068/2056 +f 2248/2066/2054 2143/507/545 2008/506/544 +f 2113/503/541 2005/2062/2050 1960/2064/2052 +f 2005/2062/2050 2113/503/541 2006/502/540 diff --git a/src/GLVisualize/assets/diffusemap.tga b/src/GLVisualize/assets/diffusemap.tga new file mode 100644 index 0000000000000000000000000000000000000000..3098cb90f9c05c4e11d928db10ff7c20c607494c GIT binary patch literal 1572908 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%0AD^5|48Hq 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 z z1_5o}1-(bKR;GA4S#~gu_>@%oauPd0B@M$xFAUh%Q0{9QE~7g1(r`sp>nb zZ#MDFOc2k1c8iN$^jZyO79{34zz)jHtRS5>#_4AqgVud|PQnhrQCsf>s_#65mzBO? z_lF{_|51L}_*Cnr9jvluBDj_0ul!GIWDbjStmW=qCIWUH#vs1=c-I-Cf% zaYvV(3kvWY|19Dzo~|>OmST? z=S;YE z6=+vSSyg9wbvL3D=fCa$J&;5!{;~Z3%1GPcG1Pu!tmEhe*mn)47FgszHpx;nyX4(; z;TrqeQs)=h+H7Zj_Dr;L&hzVIjgaSH8tsYIe1N|WliXZ+7;P$Vm-wA5+tbaDO^dkS zZPyFkQhieg=XtKHzg($jZSjXk^7Vi3i~oW@LjZ@r^B)U9@E`I^8VG1m;9!COTWb3y z_z(6=>IZ0T#xRh->J?VR8T|KjWhAgK_|pL+fmqk!EKLRh!Bw<{(~C$U-iRN z&VRQ6bLX4|0DoD4bsB8fo+SA5W#T_y1LXM>@Ru+G9&yF_Pt8FVfC~Ttw}8R1%P#Ss zR{ZZA&Pw7x@L!kzS^@<2`G2Ry0>HjOIJf|0_8|b|-&Auf90zCocMAaik~mM2w=f?j zc6lD>KYh_2wnt!B)DN*=%vZ~2^#!y%61D)?a!{=Z_2sqpb_A{Ef8rCBhSSJ%z48Z&LEl&Tq90ri=1kFfa9x5xq<{$?~EM^{=eEv<_Gz#j`J;6MC?{}=(-r%(Ndj>r%E z={WqE{6(Js^Y9P+w<&71wkQGKG+BTJ_PXaZ%KZ4Up)VFVS(UJYd#W&0ASqu0rg@#eL8%*MBgQ+ zP|IgUeq5knEvVqn5J3DV=jaw@;IHdA#s7HzX9$1=FfQgU|H=Qd0P&yXFU9$9u|Frmzoh)HA%I2!asFcg666>BmH!p~mH!L) z5B!nfFaFb#|04_7m4N(&f9F5&e{lH^`DFxze=q(k|8oT}M?i@GvH*U83ID1vkoMqRwBo;7-3Y)C zfDftvAXxzLrv!vpsG}gQ7WhMcWIJuc`Oom5{IBG%R^(R+2od?^$5>K3CLZ5 z5rM)#^&gdhy#7P}M?|>11>_EbpacZ}eF!jg-bz4fRsUI=|B3wy|M1`8AFuz^9!Zh> z_0rMuVv7HifZ#vmm*BrFK=mKUi5LhF`&Im*75{0)eBe*`cmB%);`!f;KfD@XU*&x| zgn#G1)f}dmfxq)#E>OV#iiUnf+|v0E;=kZeizBH1&nQ6k9|%nGNB1Fql&Dr-1+b5dnW$fb(C~ z9>@>>WdZPCQv-B#lNT;{^J6FH2=eYh5!ZmUlsuWAwSqxdw>3`3dFjdcnL`S zw;=%k3oKy`7U1yr`VZKbRQyr?_p-n9ANV8B|AN2jKU97Me>&^te_LSl7hC7EZt#9`N9(g6hYqv{41{|jn6IgMj&kCdADC^flg|4cG<&W1QNNw%D!g+iP{1AGvBk(g3M{b9ksPL)Z#HH|QfeN_Bd`NPPrC0SbE zk2KugRN20ziu2FEp)BwpW`WJbB|6vvw3h$VA9M3j5EH(F|K0ot{?31X$;JO9vj92xk7Vul9QaGJ0N^hd zaQ;L7`}3c>z`(v+fcTFEppoo?gbM(F=YMi?-uYkiYSQKKx0=|IOa%WV*UK9JQST@l ztRnv70(Czg6a49@;6~-mCSO2q$o2pq{u@R2_7&Cj$N8^El}OGs{;#w|F(zs`<&!y{D=H- z9v85mJX{1uD{UyXPtk|)M*dLe5&3ZeI(h_a;A@QeVG)s@R?lGZKCA+Q|143?!yhAn z|Hw?CU;M`c#DDU?&7^Q55Z1|GN>d6WV04UR0kucX0^|bXKNf(T|5$*-A0t@2dJC<~ zf59IY$h^M*`4JaMXqPUi7yltY#d%t6#Vw%gC-Z_o{0IJ607$3hAW+CJ@jhzVC#GPB zLI?iqC<(~V*Nguu0htSgodQ^Z_)qZ%3-J2?{rS%_n>hc=p6SK{#D6S6{I5HZl)gIu zWdXPVbc1!z5DM{*%sh7lJ0$OR()lmGYki~qC)MYth`m<5DWfOH&O0spZ8Oa6n?VBeB| zumG@cyG@5|LAdx2X|Vu4)DQqf5dP!*7yP03!pb!y3mBUvw6nrNInFB|H}UZtO7khZ!Qq{j|K1~%Kr=jkn+Fog1@|S zQx>57j|E8l@Y5HUB=KJ@{C5l3_eL82(<0|T9l_tif8aku65!7efY{GVN6Qz0eTlk| z_)jbTN2m|Ww|MVx0r=0`$K&$xeE4U^C&zzWU@iZFzw=*g2QNB^Qu%*f{uBFoXK4%a zf1LloAJ_ta=f8#kQOM8npX-1n0la|!7WH>@x-bQe3;1G^zvhwG<-djhy*9B$^0!H3 z<^R1yaslVRMgjTx-#~ugZ$kiPUUC)y{|W!je;)!U`~!dL|Ev-1#Svz%!vE<@*U`HC z=Pwis5dU?B5Eh`259$Gae14V>75-`AKW`0cIX(^ldsFkye|}wY0a{eRe}#W6VEU)F zgNzpV7x15?4gVGXu>fEHBmP_L5BXn<_k0Lo%j|b`c>d?4<@@lT^LdE<65&6d|2f7% zLjXnrpdMiX>X7`A^B?#-|F`cQQvO%?XSFBT7yk+W@Lv|-`JeEQ_B3=M@;~i^&VTa1 z4*^vFr;YO;3!vaH_*<&+{J-C(dKD3A9U72C^&jycsvy;WfPZ`lfCVW3Q~5#g-}Aro z-z~svKDdCx-}x^W0Q*RNEAp7w3N%)rq*eF1ipD;S0RxjZK{$0+0 z;BOXiW+pxa5d6h|{WZ~Ywi^~87jXE~(N7z-;XVScBw*Mwb#Y1jw^2ZUM)0St?aClF zY9YgZ5I;HacmDIDA;Q1%Kl}&&@%*p)4{w>OK&t!zf9JofL2qtU1-hI6q9yeoCI6@d z6!Jg(CqUZj@o*L~EsMrg|DmNQK?#Ua0AD8lug(8T{x%U%)dBVi|H}WW|7Zx{{I?-M zF8S+Hc%yo*_@j_dOYG-f0Lkniw+cv$NSQ=%{;Ska><9i9{-J%S|K$0ftN#f5v^E6D zods$opiudVsz5RRLw=a=QvHX6fFQq$KY$we7w}(0fO!1}^2hlP`56Tu@UG)Jc^+cF zWYb%r_(O}}KjcSPfWki(Ku5o*@Lv|dJBWA?@;m&U|K$Gy{uBP;KP~)+{F3TFw5tD5 z0zw!87U2Ac{9Xcr{N#VTU@_ExJpWSyQvQekFn=xosRB9wae=k`*CU?)*VcdFzn1!g z{doR&3sB{!wy7_uixaJ-=DV)<{Y%~L8`bmgJM@Sqe98Yz{z~oS|Ja(Jp|_G!>QuV+ zAmP8C7Kz~{b-hI#{<*h%Tir3lh9fSALYM-@A61njo8XMHATEoqI><7Wp=UYRhw*-o zfv7+{Sl?rHA;eAPsrOlgY0K|v&rE-cj-CC8Z>jl_9XL{lx{1&9At9(3xGjjuw7-%cdc&-@N+UTZlX8k?wNhhtv;G z%ap<7#jAr83*6+=dSV=D_Jk2rC*_p$3$z@eqXCPJS>C&(3*VXiwF}<|rt6Q6)3y%J zN)0Ebu?$Xl&{03-2PjRLfIly+TY%QE)=vurR?A(}##t?wm5?C(d#d%KFNtyWyJ zryEfMQuwERWGgrPwtn;P?H~whL3ScUG#6ldvZSK=;Vrc`0u3(E!D-J7A3!&^w{VA- zZ3Hf{b)gFtKl1ljdDJA~ZCv{xwm zgxF8=r>fkyJ-oK;0@GO#jYp@B{A5n*%`Bq9_m(*kLMwB)5gv_Syde$0Z$~$Cu-?+j zHI(OnIzxq4QH^yPsr1zFyPu+=_gUB;fIWMhihxlN|mW9UsaMu&~50=a;!Cg!5O9y6D&OBlWG3+Uq)^7QP?2lI%- z-%zyvCzWYDz~l%;vmU!fXE)2GdNJZn;qErOTL-^pM+SH6RCE-vs>dIX^ zZ|&uzWSKwQ$;%QTb=r?i=nPNW0??P$M&R!LX$13+oy@8u{?jIoj%(n+f+C)i!yGv0 zla0NosJt0%+`4bW-`62JMLXK1lIo7ix~{7Ire`7lfv&ojI;G~8L|bc4xkWYc8q0l| z{8hO9=lYub`v3dzpNU}Lk6MomiT||5hq_+zpH$`+0PW$wD*qMiCv6%+W&r{IysdQL zKk%2pIJ8GKhewb)@(x)5;1c=e0^+|c0PF*Q3H}dHTn7G};RF0#4$pP@zwiqV`Jvc? zYb-neAwT>#osNVHi2p*j;J+^a;}+oj=ZG7(fRUVo=&9oThx|8g-$u87|2dKi=;y!j zyU$Ua|B1J!o&SPA{Aat_*vv9p7}SdYz#oBq@gEBS`{IA?(Q$`AuerltRXe!=Z?yQo zwK3v9%x4r}7LemV9p^t5AoA0)wgmpe6NxgEEP%Er#br8|Xc7De{;fT1z)8VF#34@3 zf4KnscMH%EKrSHuKlGhyI+_dc>0tgZv@KWg#|6ZHBR|`RpK2FjWC0>SEem+We=NW@ z_6A?T0!#t^>|p^}V4nekb{RPTH!`7_5$_lL7yKg^_~42x zfEM_R|NJEIAK75@{DSkJjvWdyvm*Wvr6UW#1w8*7{~1Qf0(STCvIBpqfd97ZHphQP z0bI5f=YPY&w8*a|pjd$5Z{c73@3n(~5agE%_}|5v^I!quzbpXwmppyg`7a9)|7~s3 zj`r<)yTpIUABR5{@WAnZ-TXg1lpYuy@%&Fm{0IKdf5Jb4|48|tGr2Gic5!GJ(*9iWUzr~lQ2sCAziOml(=A~2x3^Jz6hQdD z7yp6PefU53>2>jc?7|At5CHf~`g8ET0QOWl3lRU+D*3Bb@(2EG?Q#Co5&50}Sb*|B z{FepL!hbuVC`hl5EI{F(R{YlxfCah%`;gzHH%l%2*Brfu0LuSy{>uXLqksmkcs5yF z-{0pJ0QLocT9IF)0KuQ|Pe*&=B5R28pDY^ZKkyg-NzNqyuvVl~RUo-QLH-B+)Pj%# zyo_vJ{%_pTVVns=0K3CIB!9Kee;YpJ#svTh@=M~s7MGe4*pz`yBGXyRe_X(dKkTO_ z`CGBn`0r;y@IQO7KdbzY5BhPS;{V{}73Kf6{4dD=jM=qF!%DU3DU!d200X0oE^XRn z!yOX;)hhYJe>!?cumCp668i;z<$nS{z{f$z|H$({JJ~e^u(RO85Mc77Rp5_OW0$c2 z_)qfJDBv#s*RVv2lL7h>`Cmf-MghDpn>b;Ka$Ly&&VN;bGz3ui#|WJNkY7fS&;O90 z{Ev=LdH7$O|DFGO&U^76_#?re@DKkL{_oHK5c|E%^5@F!f3D~8A1q)0={njc@&kW5 znRJHa5BydCVdhs=Ag}=W?eFn!{uBOX0ko?8$OYp3C;6-XV}+nVdw{QwK*WdCj^g=W zM1|GPe=I=!R}1{bf7O3f0>T2~{NzJffGR(P|2Y3C0U=vyAM!uYc3}kM|9J5S{v&># zIR8apEP#1x{lMA_;QVJ40Qr%sK%wk&hc;gSF$?(OOIZM|Ulz>&2=MnIfSggS^1uFd zlE0+-kHWwBPx433e^ux7f~yt(H43otU0DC={AU!PY7fajvVb-Gf9P*F;{wz!w6Gi_ zQ02!80-xCp<5E2TGYW|3f9F3#0De^9uU6z#{YU(#Ehq%3_@gS2DnF46gvt*tU`7xs zKL-CD9bg>70Dtjc@K^rVx7!FJ$A9vFoc|>MDEtThKgv92_*Zy-r1}rBUw;C3@jujm zcvZ0g{@28REWj>O%wALerz8H;@?z>B2$g^!aJX1)Wi9`G2#`GY5&V}0ko@6)*D%|A z7vaB4#eCKCMSg|=;=kap{15phV!wb7|M?k^^Is((EWl!ac%$R|#{$;ne^>XQ$gft( zUvn`czqx9x{=>bB;=hIfasHFrfqzqOARzwJTI`nv^jh%;@~h@k&~g5I{#X6S^Z({2 z8ztvI@b~=h#h-nR9R>9t1_BQX|5*ZhtZ(qlxk)Z=&YYi0zB4v7oI%5b`Tf7GuMJlI z*Iu<8yt6rXbrS!$5R&7+V8!vHw}NrnU{!qS_>S9R>nS}?z+T;>9MnOhfjr- zNXIg*L0F6iAUrwJX=b$9iyWmGO#wsQbk<}gpfK@D%i2re-###jy8m&8N6uWhf+oT> zxQo|sE&uj5qO+9K)i6krPiY9FcJ)@YeuE>_?3vkOz*$3~I5s@Fhz71R7ekodo|jk*NU)E0lP70fSb7}`e7hg-wyt+Q?a z04m`OYMAzHJNkG3;UVU5?|kvE*#)}+7Lf_*qsz;7)j0dV)ONiyFSYbdxAaY-hSxJ_ z-y37B`=Yho+^xxHUkz)CTa#P&bV)2UQY}csflW^yL|dwkuyypIZ&&_ZS&O6vqFO2B z7qxI*3yu)Y>as>Ouv+uT03U{95L_RrGaUG=_V8LKtmou^dp!Q@0)L+ZAi970%R3)^auac-GE=~`Y(E*FU!A_l zPqmZ(X|2PZ<3Sa*{d<~{i2Pr7AYIS;|3f2c83M2inBtGx&YtP+ z-YnuS`2L}}fm8Fe)*qauMaSNpL5JU%#6cR{GS4?A(XQHl79AB=G^5R>wOgKQ+O(}6 zJ<6@qPqvm;w^!~>sC{;Sr{;Y3z0~3IvzWd%b^d#e7b1J&2NwB(KONv7=f7LP(8(0S z0!-}x%2@#Lhy1h%>`ROk;J;e{@UQDk%K|L?=PUs7=iqPrFKHY`@SiP3ZUN4JEWr7% z4y{cM+x07~%(Mbg0soh8m<7--uHFLvkRM?Iz#qv4?!$k!)+Pq*MEW@Y!M-fO`49XJ zYZtDG|FqyYth%@5_sr7Xi~sT_ECBvPeniJBRMxq1$ECk79ihoJl+J%8e_AX+{O?T8 zAbxDfU&-a;hcbe{mi<$Ufd4xaBZzGpZUN%IEI^|G9}8dy2LDFGegyv<|78Kd|KabH z74To=kMo~bDK%{eV%xOuJGSf`iTt!MKhA&PFM&$nuO+6mkRJuJO&^=kEL${GI=12jV}6KXbAK{C}pq=$S6$ z{1^P;e^ncqC#mCe`QMQRz<*hQI#{RRj|&L?xImo$SODk$^J})2|6csT2*5sD@MHnv zKR0ZO|5!kr{|pDH1&ROrI>)hq`|#i4&uP+vzqJ=hLD%I1&i{pFyQEka@YVSb`Q-xe z-v#!!?C3xR{D=I`f0k~-e@O=c#rba+0du1DP;Mg_7BF}}{sVvUzjXIu@n7(l3yA-M ze^p&aod0!=?FbhT|G)O|#}x9z6UZ;Y|Mb}jiTvN!pF&swQt}u7OB)!z*}c6;V{=-D z0M36pjNtMXkjwv&M9H5a0KyAM{&E2wCM*jO{51rqJ(^MYw>35s(e_)BUz5UpVfslH z0RL^soXh{>Kk!F_zgqEME#d!O`Tt)0mj#Ibz@Jfo4Fm%JH41S4lmE3!2MaJbzrUpL z&zV099E});C*r?bfcPKHR@|_f4;Em>pKxcN^It;%jEV3s3xNM3zgmYs9r(`>0RGca z_;>yroergu7yo&WM1CI*5dL}4h5$1s}lz+>HM0RBD%aQ-vF1pjqM1{Og0#{w7ypg8}D{cZt*zgiICg843oKaWuP0sd-r zsz7cCz?5Z1M?;Wlb@m!1ASHjoKm3;wDF4HMw*dHWfjOYUe*|XTUw|0om*}hB{#E#IC7}10y#53Ksr=aRB$od*Nr45xfBF&mL**ax z3;y_sD*yac3H4yfUki7@0VPF*bn_^ z83Mq6S%9^n{u8~evHV{U`#BSyN33=cPJULa{GW4yeEmo8rvyZYRP6bGE&nwH;P*|! z0*L+apB7?^|KOc|Jp7CQQF}N4vNi|MB_{4A80;2e{ZvJN! zz~2J=mlXchs{XSs|LxY-Ad#Qb`4HHL|FqP9#D7_Uia+8%;a~h${RjRl|KE%MlzQO5 zG&H}R$-%+2 zMDeHT(7@Kc-L(8B>w0%WJ~MH}b_;EfN&WC4cf0Ue+M>FF;ulSrMQP(OlVYXpBW{US zoA6X#bD$%hi2rJLzLJ&zLVTwHxN{A&)R5cgLc*C|T$KRqT?)mYxn(w3-CW>$-^FWa z_UG3#Y~z|=QBguqc=*&zbKhj$8yVF6<|JFvx>Fw|-}{u`a5O!?f;1C7{j=5R!O$7~ za2cJNq$IV}8xFT2|2MxmR`b)g&B(;!uXAWU}sEdCnsO{7Y`$tx2R8pO$xo=~r#mqh;ool|Rz=_Yb+^bNySN?|S6%>VN;x zqqRq-NPyD|tJ;RZX=cgE6v-A=~1AW_UFP%on4gJ-vLprU3NySO7*44GLK5$%Jn>!N&I{)8U`y zC!{t-yS1*TjMKTpUWTdz+|D-eEYn_X!#i7s%Nqx1d7YX6ZGVePkgW)#9U@r{XZV%T z{_?duSq^Q!aBU#-Dbnw@Abg3@;O+eR|4i5ooESvfxifk3=F+u0$Yy~s7DJwTh#iW%t)r|NLSSh9nSwv3;~#qX9=hc2W$=QJIWdMXg7zch9Y?3FeSMtzzpel8pY3@w zs}c}x|DdU-FN?ZZCdy>Np)>VO1HgRe-gZQ%j9ZC!w-;Bmns#v>DH8#WrZ5*=THR*w z-`j?st!uB{pQvkS+eh&ysEKLcaF?RBU%NBk;&TD{`oD@lz~2^+4QG2Fvf&XA%7GPfx_;2v1Q`ZOlu>j{Feo=*30=%N930U z=dHQ~amRtq3v;fd8oV#3WMXNAtggf9F3qh5xk1)ja?qq3PfP{>uWy|1H&> zQZzsaR2Rur-WU04wa&-+FY?ox5yTGjS_KS+>& z@ycz@-U5Gw3n1q|9r%xC8P$GZy9P-0;=k9F7+mPkD!BmgXO%DSCKrV9%+7yYfM_KC zgZ=ySzl6$?2k@?;b6xAw`#;vLQK-z=b}75x?PpNRnRfAWI`EFg2FLg18~KRhV@s}=m= zKN9>^${^V`9Gi?>fMbG!1rU?Oe{OH2ll|=G+!Y%I(2D=G*`-y%pHYDL&xf)A@n7?C zSQ6pi^S=)P3iz)ffDZ(e|Kt1z`#hB_fT2VI{|Wz;fPlYi`8PHMphfUs7lQPSTI_d$ zeeyrsxM+#}sJ?G9&VTa1pXW~p_}gdI=J?NWfY`4y-00}Nh~9;lhus2{{CSt@@HG-H z0QP;Yuk)Y$FaFbFe@gxu1y~6vCngi6c>ag~TKq$+^*^eU(~78Az)t?r7rBY`F8&k# zmH)+mT8Dq=Sf1y;09ueDq|?UvZ`-?a`CsIxH6sXf0erD_!jYa4|Fznmwz?baORPs# z{@+%643YmO`@aa`pO*hGei_LBh)zNN2mZJKQreHV8U-+2>qCGz|LxeWz<(?N_>2G6 z`Ql%Z_z(QC04Pl>{xec@{sVvUpOYMbKQ6#$fj=Fq?OeDf3xNO2zcvd{{s;T;UoOBi zgMA+bc>Wjs-PPv#ANboS;BNl^b>x5XU+^dYLw<>YK-bYBq$&{n zhx`wfCJ?{65|l9hBOd~&Q`ax}GYatfk6ggv&nUq2e^hn|Pb>Zt{x!sK{*(U;_>Tp^ zf8~GBiUlBzd1Bhk5-oQY9TmTDz{Bi#C zUI2f+DQ*EGKNg_;ud=`MUti42F8Es~$N!xzTwEA!0j4APt9AbKJaPW3{u7me*h3Ub zK&t;}2te!bw=Jk)9H;sZUx|9Q<(sHflNl!M@;+5s3V> z#CRot_)kat2mW+`KNAWP{6{JQ!GBjKdqwca2!OxD5a28FU+}lpxg5~S?(ARz)c;vq zCH|}OBMT7u*{0RPW{xbwn{m1za{KbC{|H}Vs`H!jPi$4!Y z{RjS2qZ@l~4)~+t(_@Iv!0<@K|KrIN+X4EAQ1yX6$Xv>=|(${vQqME}cb;l%e zUaj`duosd}od05r?gE1V&v&H7meK>*iX9wHs}(`Cz+WfN=wHVU1ZvubW7)(o2jiIf zDC6Wb{L`!B|8xUUQx$b1_Flg;8#H<47E@!%4_8qCun?FKO}5y&kE z-CW&c+S5<#6TWn8VpqkY+<1W?iZqW9jU(8d}>2u{LFS`8-FkLy}GyV`5%oOd~+HRJWjoPdGx~-gk$o%H2;fRh|@l^7jIs^ za)%aO{mmWU68JCw>tCcVzW9PQC&|HK>DtOQ;D76uRe?VL!@u1A-51;iK)dvF!@Gg~ z=QqFn=R4Q0U7vb?0WE&AJj><0pDf?`?VZJoOX$vTZ=&m0u3lSQVxoc0&EMQ)#{s(Y z`#T&{A}xePgG)GynQ!!(6^TCu#PSMd7?pL zI8a)}7w~26RnIj)`$8MVf2po9f%d&*dubtRPVsvC*R7wg|Ht_c_7N7)cQWPtAABqA zmx6V^F(B-_3&;YPhTF_sNw5Hjp?nBcU`w=dKHUF~SxDr6{@w+DI)Xnf68~utT3poF=0FgiS@hZwJUWfcx03C;aod5j%{7==s zHiF~=vVeQ>e~cSm!tAs75BU);ApS!$7C5cTe_4RwKl6)QNaRnkc5dFT{{#NjZQ}^? zZ$FR`{~i8x;J@I{m0r$&0xBGX(t3~bXAZE=lg0n9Mn3EO*W08IdB1?aEPxKBo^|;T z{AB?g4GRA^JlQV(U-|VPAU~qxp^=V_3oc%l1@JNsj4c9x4A`m1!&>FTR{1XJ;?db&;b790^&dLFW|r6Ps=ZczlONL!VL z;LHE{ui`%zaD!FEKfh`4|KdyW|MJCUB>t~*{5VFCU0A(x75LMF{agRv4e=lBBU}J; z0scG#?UkRe-dMeXWC4qxts+?f*k8S}Di!cQGcpeR#sBITJH>zCFaBHmy#@&j&_U3& zs{hCN5Bw$gj{v?@!2iesj!$*GF(HZkz`vfeD0A?q?wYX4)ky=yH%{Ko>w|8f3975EPGmlpbpKj z0O!Bp5C1g;5cY9ubu=`iukcTMFaGo7@ZS~ZKji1sUnKr3{L=z|7yO6(lIQ;j`{Di| zMgdCx3<1P{ECBe^TI|n-|F!(rC?H_ph5&K?bA6=qpMe0$AsPZy+jYGXs8{9RCJR{G z8Ipfg{|SQvm6CXQ$^W`{UdK>q{#W^5{3rR#0?7Yy{zHEF5B#0~p8vTyPWfNw{PXLi z{7>?i3qXDq-WdoG`{ViF`G5V_Hz9vK|6>6R1b{XcAc1}IzlH!{ANY&^U|+%lfIq?o zumFd@4Fq!VhyP!4#7f{l?ak{qB`m<MUrSjJoDKSKcVU!PSyfk$KkTKr?tvBlPc zLVf_Q{I4MZUn%~p1O(VE)`qRYs{g27ZGXSHbwT}wTLAF+pQUw) z{Bi;1e=Ylwr|50fWdXd8HYkhbf9F3P%09L%BvgR}e~pq<`BDC7@sAGy^qXLY&QjG} z@h8rI%l{OAq)_~i=l=-)92OcXKe-{m5y(&d#|lBY`j7FS@Xz7Hlz=Gs#P}ao{(*mv z|9loBQ2u8U0ol1gp|v4EIFC9S1?)~hd+~pBMXR(f|78L3`j3h~YV|5P|21!p3kd$S zasI<+?Kvg?PmN~azfS?E^1~=V`Css72q69||3iMO`~(-E_@n%<`i~C*z`o0iKhA$y zfb*ZuTK-@9*(K^fg#UHqS5(J=ik8pSPAIsR`ZGfJYJ+qjGWJ=MyDi_zZU=7EWoHu z2lO3Jp@9>23k*th^gZ-sV#}WHs+IvH8qnGmQM))+y|t*?{tEcB1rA6ZFZ&3vgnU%f zF|zOI7_+Oi)bq6kSnL(*X#pC^U*caWggQk!>ihfb=zHG}Nx*yB?TL)lu+_IY!9-@qh_ zR&pLp8;uX9w{kfPCz-RtCrkl|+j^wD)%?eI z4B^TErYYH0EJZU56$kBl`dtZb!6cHE{&o z`^%H_oT7He7Senit)*udl`CujwBNm@YqxwNU}14d{6BVlfJ*)!e*Xv8=fD4)xc*lYoBl|FXiq^egd1=|_f9YgKGhJ`==%=Nv{(swxceXuTf~6)lY-@R> zxB8c`9oMs_TbY1%w(}qm%z(drM->U4ReQs^LJY zk?-PnDXiYyzPo+F){pql8!hWVmdJ_bsrsw^B)4s0^-B%A#Usvt@+TkaUpH>IrGbB(|5yP0 zhy1btu2Nm$&T%d*}2VsZT?oLtKVtF{yVZ#ra5EkJ4 zw^b$KQb;%t|M^Pa|79^gSO6`L^950DC!8bU{MUJ*c3(_@e>9cAup+=8BY^zQf7O3* z0rRQd2~7$|MiBVV7w~)A&@(9u0RFDb%oP{#U-;~X1pgtwjs$f6r$#eQ)B^s4Vp#yK z_z(P7uim`#yF2h-;%gv3)3UUyKVOCR5%Yg_lm6$w``ql{R%8J@4_|-l#x3!mc?9v_ zCKUb{|0my@j>BI+v-4l@U(0{U5C73x{$l}1{HI0m-?c9M;Xm-NuI()3|K2XhuLJ+# zKSzCT_?}((LJR*T_|MP)3xNMt|EX_}^I!0PKEv=a$zOv1{2{=98_Vb5Pf%nOApWb=ujCK>VN{&|B8-8H@EKPA@UPfE#B4Ij zpFb!%!FS{WB0nu-dF6i%0pPz|0Pt^Rs}zAh#C|LQ_$NjeAU_sB%hF2E{}2HBdH%O! z$~cs=Bf}8Djx=YL>A3}S0gj&I0MgNU@gMld`7akB_CtQ2uz>%-U;JkjK=Mbp0Q_fp zk1T*z@b~-={5S6&it`@}5dRDEzZpRQzNUa7KOgdX+UwjJiT8zNx4!0+ml~4umeKP6 zE}0SJ@_*5b;TRllUkdd)9|G{UD*P+|JNyaxp8w&$!@q$4BES3y>;w6zG1l{)-Q{8#?R1)y~N*f-$MSg1%z`%;Xg)TWu?IXc>ZS~K=B{=M^nHxorHh6fbzc{cm87m4*xI^uc|AhZs{)hjvfCB!5eGLJW{}uiV_%Ha=KDhkH0^|Y! zKbf8Y__Tt*93gBliG~2JM^i{HAoz>M{BFa4;BO_Mz<-Sbz`o#52e1Htxd7yM#p^%f zKSWaf2MYlHwBo;p0FYn*C`@zy(*bmO3+SI+%YQ6D@Q42h@=N#UKk$$9U!wr9Pe&sB z12OR*X6`zWlHfl)S(pD_0uujK{}KOze*ym?ze+&jKP4cB0OWtwf1)8kM~2EzWk<$J zK%xG_i-QHwNAd!%|3t`TJ5t#BEAs38iu2!#Kg$2SHO_x^;{2~Zcn0iC6oNDs&=5fN zA4UO4^&i4Ng8%-L0DtGd$d3gS@E`0`?TOlGg{KV!;J;BiocROxbrC@10#Dh8@E`2Q z`Onwex9qT)TskWL$P4r#btLzEL(*2C$fAxMV0RewgxXC?g8>Q)kDAPG_X_=rl^E z$A{k@MFS^JamOf^LN+H1Ydim|WkMbDM#t*0VSP1!7aR?`b$>r1WR~t9aFri8<$_Ku zvr+5Jq2u|VPsv~C2>7(h{CtfLuB0t%wYrB^1eG+MLgj}>StL{2KihKd5=yY(g#1qj z=7$N^&U2SE(;CA6!ogFvkcJbAw$%@!$DZpgYZ%z`qcc+7tLZ(hNyOZ4;;k&zTD4qv z?y5bMscubIzLcbe|K&}b_nSuB>INU>V$)q*kv7QUoM&GjW6*){AZd`B^1_cqOUDv4ffm&spWV7YsdKU9YgJtn7zFS~btkjt0=<)s!?U#2ota%f8gcP5GNcM48e0X* zw?`JxlC0$MSJJ5Vuu06XY#ElSU$H@f#FK2@Kj7j;_A`ZePKi4`|E8o>s_lALn}F1E z1q?Fs&s|MUa({iK?$jL8ZZF#BJ4Vs21E+XGUUpi8WNj}}>51Pfexvl;Wwm{Xy(6*V zDZ9g0Shh|`^$?y8=y>FN4d483EiL5dUNE)P?RjLw_7)_PtF^~}&}^HJILSH8{B9_1 z-dNs7e7U0+&vj%6zamIk!A>@#@mbP3hL} zK9^EytN-K{oF|T*7#tg)L`$D7L2nn6yspJd`A;osq+~r`8LzgQz$u@>VBiQ?OKEFW^R@SjH|x8$<|i_4E^&Lp zUippNnm0XVZv<1o%mqa4j>9F@$I$k@LltZaZc0TW-rrjlwZ}@Iv336CHSMTG+j}wM zr`xwZ6YBq!ZAC$wzTe=|TriG62eT-zZr!=3wYm-^_HgnK#s8*6BgsD}e>Kje4*8~LTce+xx9{_AW90$v4+`GX4(7oGpWUow(#E@Ie} zWXuUSjLQWCe7OLl0KuQH7yRV{togwLXbk?#0>uBaAD#&Vgt_L^bC`%30kfsOlak=iLaBQR9qUPzwALT0c4zW7^@ z*C9GQ4%J0?V@`P+!UC+%Z31O2_FaMeYJtD_Z-a#=nl^mDo)$U(Z5wiB%cdt9#DBUTC zefZB8IQ(lmMzz2a3$UG5M>1{!JfVaU0DOl(9oYdb{O4=nKi>%X3IF<*IRBOZaREAD z9}8&Yw6XV>2>Rr;{wiqEC4}%>_f!HUS$E4 zv+VWHS%CB31`fIWPY3?H1vvldKz`{VR{q5Dzb*I-=giO%|1|`F|NZ9{WC8G>{O|lH z`Fs9{{Bi-pzaOU`=RdJu`Tt?&=>q=&xOGBpNBoEI$nJ&zo-tqfAO2hH56esF2>#!A zY!4k#T`nN<1AiL=l(mrj5#NPDNIb0>%@eH}1pt2=Tm%cy>7&4(4)7QMF#_?QR{UqY zfD6zk|7!?9{wMY$TTvGBzwX|G`NV$bKcAI#Vgz4>|01y3%(+Py`QJtUpB$T%xbHQu z)2U2OW9P z{|o`5Q2=Ki2JEZ#Bcla>c5;dTkRS0R?B|WbKl8s;?emX z{#)U{EWq5>`Oo^F2bTY`fVKQr{YU&)3;&UZ08m$lV$pi>hmPt$YxBSOZ}6vfk=tEM z2l!hpNaqrS{I5}f_)n|wuMaT-C4Yne0VBVPKXg?8q4oL?{6~VnN&$KMy zKa~m}0;p;s7f}5N7x4OzNz4&t6rZ3{=R`Ou z4u5_P;`}H4OJr{w^@r=UATt)A{15iAW?X;{SNBTJekn5QGn_{YX4OJH@uv1B{+T|C*RjYCl7y&AP0Xs4u3jef9T|pH1O7- z3j6EU_67O1{Ex$*KK!@XkE=@2>)AlTpUTgpk2lgH?FE4UbPUux4r>&^BMbqMxd5x| za@R!0J76F9OCmqdfa3i3@XzBSzs7EU5X4&kN5!89pZ}SOnbhc{l$n@C>Cwq#ZVDiI zW;~sV4uy-3hC4kqbb6}w=;))I@XsxHPj^ZDVHVfgsfo0j@YU3wT!1hMTS%cqcdi`- z-TdwQ@()X}uZ@@mQ2q@R(yn1&|7r8TO+%aZ^l#x1X_nK6^`CsPb;3J}$dgoIYj zg87EQ@)vq(_i+sYx5ETA5}`XXyXyPV&KAyf98$}brqu^Wq|*J|bIR#4Ty@H8!s2;u zT^!+Ph#|6EP*=tlARRt?sri(RQ=adg+1{3sD%%M5nc~_Zh5$virx2!w+Rx0pI0CNb z^^BymfNGD9@v?ZKh7KQ^MQTZ{-8{~1Unc(VbR8S5-l_7J29PfSqEq_PP{qrU^j<{A zalFva(=zU3+0R22U8rYlY2o^pOC0s^+b=oFl1$5{!Fpc&be%FYDZRK{}9Hr&Bg@?7tBZjYkf zJ5*8=w)O4m+L9ArR>T>tZ2b#jc798Fo3yDsfwnx&tWBRkn{{j;&|boUPE{Sg=a(~o zs`s`^d-jK8|HFYl?D?&KIj``NdTHgZl2`mi_!{)1ACk9&^MBj|Ab*_y5&YNVf8~Kw z;=e3_R`3`9S?a@r{{sGF0fIj*{NHnU1mOa-8Vfl8wd@2V5OY-1cKDkG4N{R=UbA9 z2jM?gZoz+90Q}c_AuIsw7x2I7#5DZxCGTaIfIkxaX}==>S@uc!2n(?FpE3SJepDUS z)2i|h{0Z%lAO1%c5ctoFk8}~U?&93pYHt=T{MT9_;Ex>sbo4H$)ujI;6#oPNcm60- z!2dJTMcKf>g=U;*Uz+e1_{2DK)j-=59_s%>2 z4f{Dg{8)9I|FQtu;%5$%|HXffvw;7=pSJPPkoa#FFhL>6&J{tx9}AGcKJe#kZQ4Hz z|1F%yYVyr(hh6cMZrFF_ydwnr*m0M!Iq18ev*4eIZpe-EpLYuK)8YcWfHt1m*1%g2 z|6K+Amj%!kRdL8(Z={<3BK~;8PCfBoRCoScr@U=bX|rTYjGpe2^pzW*XhY&Zf7k2s z|Jk~>zb5`Oc?A5$f7bjE`>_D!f5G4EAY<17AkY5_|L`BG_z=Kie^6=TApDmF-~wP@ zQ;HBq-&0Lwo250{2E&VP|# z764iihdkf{jU1tQ5B?MWfj{{_&VOP*zYKBy*R-XOlD}GqKSKcJfA|Lf$^WtdbAgcm z#ecAm1>io;fAT*T&^Wx{Lx9po&Q?v4|4~8yhyNX!OIX0ZzDY#>XA1!2SNO*h#eY?7 zod3L8(AD$5^B>?teo6e-qM-6z@(2FB@=E^Vzu9ic{}=)AUzh(Pn1%n*g?#uwnGgRq z1Yj$12>&*SV;(;Y0cbt^7w=Dr|FjIsl>9B&V*!;%*5?0j7B}3L|M^OV|HtdWzCk9m z@L%EI`HuyV|G%+$PZa)(>OA~gCrlPoEaI~w|62YNS>ybd1t|YReqMQ6;4l801u$*2 zzYipn=fZ$L5#|XrK-Iyc()Bd^g|6hdvxC7?m{NGvKApTqUXLcsQUn8lA$t=xc z&s|xo@;`k&4*WNMznMN3AQAo%7J%S?5x0r4Y=BNxhgEe#{?EgodH=wFS{n$kJuo+{ z@bG^h{>RV!@%(R>e|=>iyuVBS|Nq(ij~eH{?s>rlOlQXP%JCl;p!kE7|GoGFTL1!- zL(YG>0Q^_+$MZj5NeKw}Yk**#aNZg&z^5QT#UI4qJCH|^2ka30A^%$b3;r4fXt9m* zzfA$0$jSvM`>6hd3wZwb`j6*-=YPEZBl2SbNaU~FKSW32Uyn0!3Hdb&sC?PZ{Go;a z_EUu+Kmq@OKjhcw!;3#y0Q^V0IwvUsIsfSt@E`bN0px$+uOWbK0W<86DE~u#!ar|{ zBnzO0LY17M8b$$L{DJnW{CNHs|7kt{QwY)zpu=<&W;XQfVF}DR{Yt`j;*NvLlww!`{Vl<0+>yZ z{KF&mU@rd~a2|W!>p$fGdYS+#G2C-QE2jCa*pHTqv{O|lH z{3Feqi2qjh$qfNW{@Nz+KOWtn3pc{sVuT8gOEV zQGn_{YxxiPEz$=Uh>}0>5B!Jx;=lb{PcYHYZibR8{?O5x&lG=D|B1ps%RX}lKCAwt zIvBq8Ao8E}pQD-VsdvJe&)q{^-9x=^r5FoDn}6RK8-8ajnHo=@n?`I69vB>z8r%B# z(_?KXbrM>er(=SKLN_aOsNsjUvMqlWGzX6PK3~?QFbZJyRx`PfA3cBA)~=B1T>#(G zew|hRIkSt-qv6>0qP@LRS<_%Ci+}1_DU?Lwzv|~(o6qcgZ9>Vv`RzGiTX!OhDH!&1 z`JYlu`>C0xaP12}FuQd14799o(P*Wly1QscCoL)q`;KX?!;Qu-^cFvzphXqjx*Jqh zpR8(07uO8YGM3?fG(9ITOGWz`aE%y=bez2;(Qi*JG!4$8eFHN!M<)?s7+w4Qx+K^cbG`@D^GD7zSeTWfDd2F!OZmYxDsD`cws6B^hR)`_9NiPu$DVrmCz6>( zSox{NpG18Xd}zTwwJ+{op_LJA<2WGG@MCoY(&qic5AW_nbhKIt^P>JgyK)B|OU|_( z$#iiD_D|;6G(oHSzxdBAaO<11jmJ$pUl}cb=@i01w>PCq>ewM@E!ThB4d6Ar<0&!* zGrUR~kM8OO^%D1nLv>o_NBG?{>ORrJI-f_jw|tZJKkOmmLCgP*4{vQo-~4VJdSqMk zL*K6c2G#z}&;Q5&ybIZfTWY`cUm9pNL9AH=<{c>bphvbgJW@ibzZUV}H~+qtNBpz? z;UmTNStN+@^C-vaK`Iz_0NoB_5$C_r+0J$({&pA?b7oXWD$zII`_3Hero?|u0q9(* z;q#YmG9|Mx_8~X0o3gX>+5-Gl>;HZ!Ew%a|9?q*RD&14SkJo(S{rngIkOEO*J?Bq( zB*G(4-geN`{)+vh4}FKp`bgo`YkH)(o(`29<1^u(&DZcb+zY@P1hJ9Mh}-bJ=8aDs zM*I#G?;YA)bu3b-0&S}3uqUbPKm;&a`^J(coiFsr_gke6PuTNs_(9voGULBb7Smzc zSK`2*u42% zLqWOi-N>&NmKN|I_&fijb&0t>Twqr4-}OowfhMG-KH@*E)tWf-Gk0ve!=Dj^$S)Uw zv}O|xN!okyANXSdi~0)B0gj*t zY1QW|%_DOBr-KC)@E`cwxuX;!cC?HCmHX{R$hG{Z{(}Y3B9R~X(}Dl8fQ7|t%fDQG zaQRP27XN7zhZ389z)NcUrz8GzY6qQ-p)zCnKSz7uY-5CQMzppJJp3I#Y}Oj-Jp6Hi z9RD{y$;)p1M;o7Lclh%>z~8a~8_+7cApd>%5B%#I4g2VU1%82pL5H3Xm~`MU&v z_)nd|`AY1|G+=ae=NZBzxXfs zm$MT&gn#(2ApqfD{3rHna#Q>l{0sOm3sC;|@DKmV{~7`i-61(IY%~N2{KowktU|2zMA(a8U}z%~Xc%;~U$FP8tse;cHS zWo8C{@xOwJ;Pvyr$PfID|KDpe{^J6yGu&oF0Of!29}9s05&3Plw;`$*1q%Q{$O(@- zU;)nmxCQWK&VR@+{?nm|Ve41|`Q!XAs_wuAJp32rf6bd{6hP&F{K5+GN6Zu;ECBvL z(D@(!`w#&Bm;FC2&VR^H_@}jlo5=YA{5TLr}Vcym-1n~S1 z|3RNb6-b|5%YU%1;tv)e{%aOk{8#kJ;R4Qo)qfzrh5+&W@0A}L0_2K6@L%Cy^&jycbejd_@<05C{3`ya)#hJHKztd= zKhA$U5U-FUbGHv#VbJf&XCN1@<)r zuseT;B2oYG{15*H|F!(L*iW4&oWK(mf3ScjE%__|(;@SF{&)Vj=o0Of!2pZt#ns4b}fDE!j`f64Q|h5(d({-pd*fm$mzZLQ`H54XQ|tn2s?>O9&j z4GpJ~|2W1{KtxBQ{{F#K=NrBHVp_hDWugcYstwB>3xef+KFl*G&VQ~@jPu_JANUXU zo&S(OSMagT!ukCI-=SYi{)hh@B^^$awhomaMEJMgoHhKnw-|-+PfPuW{EzrXTFO3< zzqTR5zTi*$*UEqLe`ahZb#{`Pe@|a@;TP9_F$C!DIfdZ-;Hivn0gE3H$3!sLk+j-G z`CprPqy1d_?ff?#Bfu^2rH!^?pO&xm`oC6wLKr$eF0iKxa{&wl(6@K@AcE`P@9ls1 zN#+{535q-w|9a&sBZyA%Ue?>N2dR(x|F)tnSS$Eoykvj-97%8Jg2A zRCV2x&2P<=zBs(Oss}w>n&1bnIB<&HUbP*gY}G8QBUD%#EUD>1mu*?Zros;@lXw;!Bal{!^ZmFja-WtC&f6kS}sdaTe8lnJe3NHY+Xb{iz_G@>vl zLN>wdKtu0@#%y{|5E_Ho1HtT(U?8N4h(m|OCbM&F9gTCWWTsA6Wlq(p>igh6IDf!> za30(Tb6=nJ{_e%s4cc~Q=2mx)sds&9$?t6R^?t9=;s5RwxDwV%4h&F>UmWz>)jT4VbE{^<$_>8)KI^|+ zyn-0$E%Io-GHb^?XRU2T)UxAan-34O&cdLK8p|{eEzWsEi3^X;6cKHE!EcZ-?onj0XX)@ zB=XzDleGXh{p5`WyVw+J@8xry9a!c^dbIPKAhSFd+DNhyvE_b+)RoB5#)d_N(P-iXZDt4O$+Si#v*6GrfC3N*_7G0dVWNUwH`_HNWjk6yS1b;0HfJSmUQj>2k{^5OSpjNzgfV`6A>^H;=et> zbs!n$KR+J)m%u)f3)uZ5Z(f4`Nc;!>p8vrA{``mhSOB$xOI>sP=jVSA{tN!?XKi7+ zb$CJihx`)%``qUR`K3Jm+s=Q-e|x|!$A1q0w3Gjx1#k+e_zxbp9ZKc#ANb<}@ZVd2 z=YO6B_>Dt({0IK1sBsjD|EZtfMk4>*-Q=lHK%6?6my{O7;l%Ky`+2gmvVf`gX3@e& zi?{&r2L-_2fN(02N{x8_bK?NQ1%`)5y#;vqGgy=P;Wvu^d~V$j?P;&o{Ab3*OTC)^ z>=(7C2JYrRzg#T9^B))3@DvO8%-Y%z*!TR$-}Cqn`I#JSoI*!U)3r2bi(|g@3B}&v88p|6%?! z1yKHH3!l&bngWpj%MYYfw3i~0EB=3rv!iTf7i*h=Rfer0^|Y~`!QeISuX#(W{b@N#D8CL z0m<_pYxeoSv}x4CpFx=a?&073{13;{b7ldW1sL|7FaoZ~j4*d|QvksqP8uo?^vMFq z|DOL$1nAGe^ML>4x|{_F{zARNzgz%Bs~IT%3;qC~KU(MCJ^9NY^>!-o2PxtFALc*d zfBk=si2PLYzxb~T{KbC)s^`C^0Q}A2f6Ba|ioGjrXyM7DxX6zMH22!A_eiq7R~3epvvgL(hM-fD54CiT`+kHx346dt1E)5c`q%Px8kCsP^K!{I915_#^qB@Q(`0 zT2Yw)z#ry||I{%5ef}r>*Lw2*yW~IlANb#k|C$A;TS#4#|C#~>UM zs|5u1y~KZmzx!Z59{$4_kzX#rA3guo|G@>q{O2nJ6ZL;=3UG{P5IAhXwSYqWSN})( zA5@C`>i>}cu`Mj%cjCV_f)4eq$$#a4rU3klz7PND{ICY$`5*580Dt;FU?2Jk{&HAZ z0NAJh!{Tq4|5yN-UsC`+9r%a&j|C8tshV`F+nPJQv_g$pXxen(RPn zr0`GYNBeAj^N0Qqv0o?HFi_`*hClru@n04|^Jn-1N10_Az<=KY6907@ujfAl_z(FJ z1Ncw!m%z2jHh=bb{u}LWEub}+0x%tLn*q!S+{Z(E@;u~+|Gbfb!oOw#@WkhTy~XpN z4~G9>NBtkqf8PQ!?7RF=1@+zn7<>M+3)HTm-*1OPhxxD04;AT@JexGVyMz~D0TTRI z_{Rch{@f@3551MnT$~a44gO34T=LiHUhv;XIG*>({Ppyj{MQtK3jdM%KVklh{6YO_ z0sbS5fGLBwfN<2m*Er07#*rU#DWpvV#D7{q>i+g1&-(vwj3S!<>i+}(*0!GJmN)}#_@w%F(9q9=z@|W`rb}pNAZ;bd|(M!tH32u z>tG-ZqUt3(--cTEqfEtd4kaE&L`1qkyN(PYAiS?L^Fm@;;;NU}$Rc9UHhc;312?@f z&E+Gdk-mamosVv9w*G%?l*eh=s8fAn2$dbO{Kh}q%BIxL7wtx>vV(RxwZy;Wy{EC$t2uv``Lm-^GAF5Ur5gG>zRV#m9ep%Egae~%1cyq zh({sZt?uqnpa$+W<^i!Y^Bw8Mfw?S|Pe+j-Pa;0o+CGiL?3FEKA){fKineh^Q+=|a zIzi<%MBD26QAN|BWbkhrj>N3mg8KB2esC>yVVTR{8-F|%8<^F)$xb&h;ZnN_GJy3ah#hcrU2nIG|u@fB~Qe{(LUtao_;^4BT6Q z|Arkd|8I2sfAR(10_35+Swrqw0QLfHV2jA^7_u!uB@G4TtyDhX@gi#nt^Yr5pesvs zeWBYa)KIXqmG4OG*DQd+7LF3-%mH_y0FOE7ZxMfg?D?;khEdCp(zd<-{E|-0(5u8N zHu2H*;rFsAe&!N&;zL^qpr+ov${vixg{z#{%-}A5o=RjgQ@V|XE=}g*?9jOhlzDeD zIN0ai$(f7u()>qDQ=AKWE<>Hg1THUmeYW%&x-xr(ll;filSrpNiVW$|%>2xyD<3V+ zT$uUnm)CB6@s++~P(R5oeUg<^gnzbs@jq`0z^61c+0DGXfL?{g^+eWneSEHgob_{95*Xey~5@cdhjQmHfqjfE79jZBr?jUbKLk@f>t_q%KUMsP{Gznyzga*m1N_B*u#W}wPJSBZ|DITS zS6d(~V9TKt0{%}_Cq#ZKDn6W&;6Hnu;D3;LEz7Tk9lmkpPZj_9 z8L$BHAM(ou#D8wELV5fr|10^^xB&hV*k@BH6(bP;fj`GSz<-I&pI{#gpo;&%U)zb< z{0aHx0>FPY{}X*F;O`~!GiPV8aiHO| z`(Ymj%K^KSl&{F((cy*a1wulz3y;MD{B%Kr@3mB$5t zGXj_Vu>c1AQoIEa`%yUmTliW1wNh!3-mbnCz3KjGgV z1aMP;JpKd!JpMBa5d0^v+(yg-5Efu^`~T$v!2kBmJK_9q@V_{(1RhvGF8pHwKKwHg z0RBi*0LYI8Xcln(!aOqgf1XwT5B3Nx-{RtU6y`q`0QQkwfbTmudntV`V=gc`>oxjU z6CSzuC#wH2Kj6^-gbSd(kruD2{YSlO>)ZUtvy|-R-*}(F{ePZ6_V=#v|E~Q%j{H9V z1Ajyd2>5$Jeu)nYW(_X?a~c2^AQuSpU(Fv?xGG@;BERRqC4aZiQ}8GMLmt0yX>DG| z|Dd{Ef0_cQ^8^1GKz_t5K>Z)(f2!~QKz^G4nguWg@Xa6ff0Y04!++&}SpeT9%zw3j z)c*ngdHiPz;F~}6e{A02@;`%c{|ESkQ_ug+`vznIpnhKjeP|{1NcS0*L+aUv*|~ z-dn(f5H*Zz@qcygezn^x{P7!Q-E*V>XJYSaq_3^hC$`=bnUAgBgrnH;W7YH!J|X*qUX4b zc$Di@xL^gf4lTsqT12q7{mgvywJB;-a@Ml?i>W7e@Kks^8}Ejl7qoqSpRti5I`>*dQve>qEx>I(z0~+dhtVNfh$reju{|dtj#~2>ib7 z1ERM@l4b<^ZQ(%Ddo?vEVDC^>oN7x3Zm*8fn@yYU)&MF!A{xu~knip`SFQPvmTsZFacy<4+y6pTtcrRIw5sAVvHnd@w2~YoKo9Sq7GXc~p?+3L{-bJS`IG zA}v_|Cw3OK^q%h(6xn8f zzJR#A6=4LBpS9iTsoCt+Wwd<#*I)hmH;D6vSfKY`e`xY5%3QjEQkknrvy8F#t}cCY z3o+1QJ+<%cCEb6dCzSO&RULe10nIOFQTCIiOCMg+bz>6~lPKOhfbL#nz0cM}dlw9U zITrT{vpq)Zent1o{JEW+_xfHd4E*Ee{BQYx=P!@t{|lEq{PXzV-j--S76<-yb&UuM zXnUy}$pRoh!U%8y_+J?5mjwv^Lbupb_evT?x&mPYkRLR0s*F_!e;UhZeN_U5`A;XD zFQ{G+@MkU{{+A!Khks!O{I~O;IbiwK3|yt!VNje5!!Gev{0CgJ04kp-{+okveknT) z*W&-)juG)+@K;pkr?MYx75^LiCb0mjxj>HpJGnmK*ns$t1$g-9@gMk$|5!i;k5)Mg zU;z2|bxlbPe|ZW1Q{lhhFBgFSvVbuEae;!peS$yy_x&GUt33YG{E690ie7U200{8gRuQUK4#_Td61v^59ec6{@=sl-{*gYf5Bh;uc?k8EFgNg8Oa5}zMlo?9w^v| z1weifO@)vm|GoGx3(#gB@!yAk;;X)h+ywrs9b~o6zCQd%B7b#k40-%EiiG+Ii^_rmjzG*^1E4p;II4-{2RJ6QaJw;{_W?iJB@t)hyRBC8awbU zkN*MrbNq+u;y=mXKG>ZR2lkc!#eZ3V^1t|R)gAI_J)(UH)^ip9sjQWV|A2ip|M^np z0_FC&8R0*00h=#G#DB;y!G8%0Q2vMi@zf0Pm#_fRHQ^sVQ^CF${6~a;pZ~ds(eq#V zUtJ(7M)37Nd`0r7A`gG^zvn;S!iRrNF$8}qj%+JkBslm||_&*r`HLsBitjYgQ=L`2h?h4=T@d1GSK|bb>pZ`Am^NSPzH3jhf zA6!8BUlt(#Q<(yI_+tc+UsC{P0c-MK{U6@~BLC}1Neh`L(^vrfr-FS6Bgo^wtw_2R zVcw2#f&25{j%d&n-~b0u1pEj7dHlEL4>O1tQ$GI#kZ}Kp{I3=e|Bp0wumF3&IhX&L z0ziKD0;&H4`N{u$7)Aj9N&XNlkN=RLDF7n>1AO>T760k{s0*|v|8W74pZw3kYrtQ^ z2=e+rw1C8a$SswIazaBSZAoy!u zrsOXdQ2y7lKG;|O?>l#e@Gt)J*NOcV5-tGzMG^+UUsC}156@RD-~sZ#`0s1T0)qaJ zeZhNvod;oi@G+cyeebXH?}7jGYX0zBqE#5>?wfGS5CK_=x#dJhT2cYQLH0@ z`um4i>w*6~5hihjR7s@gk&<@m*4low-R=1#SEK3^BdF%CbH>toG#L0}0ea4hsu_X$ zLX1~z0*{~S#SiTsB2@VogSGK-#CO!{ZNtDUs!L3hrRk!; z@Y)^=|CJmfXM=QQn^jhRBmJ|{GxIgwQ>fz9WOeVw$Qv_OduPf|rcu?YO!*1=^XYBT zVfsIX2a+ptyFj%UbRAD39M0XU6HV!oHL7mv(QgOOLOiC;i@)h`imm>L!Irued57tNRtkoaI& zEwPPXBoB7!uvy3*-9Sf37e{h^3@szu3;JX|kzT1@+j}qt-oByOPN6UOGkdr|oBw^) zxA5l-bJV=;0@}m&q4v$YT1q3msQ9@KRMRj}cVhVHE9v&vGo5ctAqFgn^8%*d&rV;t ziD;c^0Y#m(feYF6ht^dS|EFi>Q2VI_($1gk;u2c;$fPd4>O%I*?47Tv=+f0YDD!hW zWm=m~hu&GVs|PMD4UH`%QZpz$zBv5W0(Icb{K(h>N^_6Txw+A?#nib4iBIo7GZ)MV zUeEBu^OGljcB%W#>A~?!DD#2YkYA7RBzN2n^Z5bBcilVLwQ{Ze1Mz?Dug{Os*w)k1 z-i1!Ye&ppZ!DP_Vv7(i4YWHTY{Wb4?`|q=N1V2A7Lgqrif0*z2j|D(}!C(B39&U;p zh*F~s?MN2j;m@hjM>|tt{saHj{P!o!GZz5<910OU9h|$*k#im(zx5n)vjf?Iy`{;l zK^6e~i@2!$fE}v;#Ip(bj|)KKx}He{b>Tms66SwpyFHwRqNnE&763dw{40+Q7C#pk z{KfwO{;T*8{1HX~_W6$doSy%(01tnR;9mT%@0$|*8HoQ>ECBL*{tN!_pDS#@J{Ex3 z2;}*X1&IIdX)Gf@TXC=e&;OE!A#;Jd`M;6t3}gX3T--P)l^sdR0_@gK=hR{T1AlAo zJsSuk0Q=Hom9{?HGdwFnene!2{~|vYU!gRW3XFE7yNlW zQE+&BRVVAGqN^-G{105f@gK(8ej#^Kw62V?ZojhtY=T(sALDX~J$FP8O8{;yfH&&m zcwE5UAXX3mAIB_QS4aG(ivI?G7L;?%e||8{0(gtP5$t0StROJpEI9GsZho-?u7N); z0RMr%_}}&BEGPz{4CJA}pQz7E2mj>){827o7U0Og^zl_B{%gsJo}nTfp6% zd;pgI+wfoT|M$#)ei5Gk%KunEyer8%ujfCshx}e1{yzT$fA$N(f5N{+_y@}f3(!NR z>;hsS{!>jHDVdXqMEFMmw;SwX0nGv!nAnBVWJgKh0>B^g2eW_>|G~cUKQ55Rf5G2e zpx34VSU{NnWo(Rb;h%~skM(>0EBxykFMEbd@OQ`5d;W`5s&(BNgbRrOk(XIkjx!5j zet|Rv5dW#-KjdGN|5yOwAAx=GU-`f6WQOpMi2Z0a|6w)c7ys2O({@nck2Xd6>;-qs zq_Q;^{(B36|2m_|=YRN*cq9Sx%LRZxfB81?)Y`NaW?{cZ~o7N8Ss!ug*mz?%H$ zC1Msp?AH`P{I}%K6;6)-0sOhz>43$1@!xF|Wof|e7u8Jx741I%;{sv+18`W4S!kCg zog(p{8s@+9zbpW}hxrfu1C`k#vRr_Hw*c|q-sSF*vGC6cmU~*kejfi}z6AN@0=#3Og09E|A6=Cj?Q{15rX|MF%ff8YPn6aaFn|3g*&SM$fJ+d!o$0I^@qA1r|W56Pd(M1T$d z;rs|DXS|0KXp1M1cOV=f7vB-Xd&zJIH&Z|E#>hs{8B1ytR8R{g=)A z#PA=nfau9YP0N5+<+0OVRn4c7x-&l$ zJq)T@y5+>wQyE0IN9D)I5Z9ff%Gd<_=ZD{Ol3QKa5jx3I?+b&r;ET#)6Gd$M>6)zJ z;5+xsmmd4t@?r`VwG2}?AMEF@94apeFVv>GB-*$yvHsbv$Jyh`HpqRv+I>K_^lStv8SCRq8CUbJU?b@%7A4Nipd7K6)xhUEV5R^ce*E{U zcmDp%YyagY;+Tc0%w*zJT>by?=}%9OFCqrK_!lqV9LI=V+lMbWa$%V|F?((D(hVwN zyHRR<5%s^dFg&(|5^qi;(*Dr7ODK6}dhpyl8nOQWygEfb|EJOmh@ZAQ736;gvD4Fy zT^STPX$yZNZ%?E759YZ|ruC(`RMmRctAbi)e4|LWal z68?dp`tEV*Q6A!`>0HsSqx>bzDR_33f4}7+@kg({E&X0O7Z7QGPx+6Lh4=r6|9Z{~ z_>2Eo0OXeiP{aJ^856;u1k#rb_JT6t#w*YNotz=*#LFo1tAhQ){Rzo`u;+it;ePnf zZ*6N`Kf(z3n8N-25?sOp5d2?P-XZv71oz^<$WMF~|8+3kz4%{Rf7B{3qXGOKav{62p~UQN6&vO0Qf`o z!SkQ;)l@zIc?IMZ%}cK7upgaV&91*F7S={-}Cmu+daQ*7Ipk5`C|df|Aac=|LBf(`0p(M{tN!p zJpS{eVgcemlbUe;X9^(x2k<|cf&AouDiZ$#3kaS0AozR!V*!%LPqo)MX940r7N98r z{Pz}M7w$OzEB^!kF#k0R2=hOC<10-8s6PBN0RFUkKWbKm1lbQdm-{DZn2J|MU7kj{Lws>6<_BpSDk4{s;c_ ze~A6?UzPrkT0pn}+sMJS_;1v8+deS@k)KltkoXUjP~rZ*9NxLk$=-_vP{k{`0R0~X z|E&d-YyQB0k^j*rn{ffK5Bw$df5d;mpX&J!`Qbn0M@7$d^KVw2AFzzb|0I9<9i~{?q^A-vZ?4H5C61;Ew;ifFi$Yxc@`=hyR)d=ryO}0zUlnHEI5M z{?qv({7Yf}EBR9~f|<*=6#kh7z<imTHuNIK!KQ18h^D>%gy5vu_ z`?J`imE%7E3G<)ij|*S{bbc)PS9Ty>0jBE!#DCS5{*POTyruD?=Fda^-+SH>&j0i2@#*2WG6QGQiJuI` zdy)vGw;Ycn7JpHFeUn!UFE{UPj-jUG@km{>Djsoqz*<1m_BYZT2Zzdz4VE^Tz#Y|f z8!Y6bg4(_fH9d$y!E-$uzTZXlAkrW(1&jbUaeWEC4ug%)CD5irN$R8A<5}LmvC^LI zhZvRI2;&~Ds(NX>E^!g@#nWSE6@O z&Q&Zg4sz%vmBuwKpk2qu5D#+!e|w~t{tp}e-I4yauT9l(v^DLZSf(m*kwMu@6Gf~P zyfndj_qOODV!&GM`e(Zf51ytL9O(1Xt1XAs>#UcW@rsy>)g}t|o3M<{bxDcw*81f3 zrXhr1{HNjuYyMdOC(xef&Do|Ob292MRsA2DNXRyS9jU;OKf+`V%1@9uo{ z4_`~z@$APpM`yCy|C8ZZ>5JLvkL@@PFL9g68iN7uAV@DF2GYnoi-T`344%{Ge>cc2 zCGe&Al+pK=^%W*&Y|}3l#rmfL{`XJK%`I^03>9$)jbAp6v<)tO@wLRAalf0s{2$pb z|HrLg{{}^0yV%s$ErnSZX-S|D7qkETVE<{3@RPHdN4`_`t$)#fj}#VH?LD4C{Lgwz z3jb`sALHO>@gY99ZC0|y9f zj{H<`1o_qUGYiPENZ8*J=|hage`<$m2hW*INMO zFRhKs0-!y=9bT~j`#Jt^tLhB%ANb<}G6H_ZVg9p6h({;*1<3+%0WI}f=f~RhwtGLA z5tKAw0rrvZ00+UJdme%Rqkmc!=6_%TF7wL;_$4#{vX@>d3pFivL7?vw(9(ehKVL)9mTx9-kclfxq~l8olJ6jE;BTMhB={5lef}r>Bf;OozvI830(ki6@n7&)Ej(c4M+^WFvhKveepsg|fPs$3 zdx@-=LZ$8VspUvFj)3DTnU}`(m@RJ<|78IR|7G?4;y?dd5fcI6@A(h>?Mt~SfcS6y zrHW3GpCD)A0fZd?efWQLQ#8zf$WQoZ79jpp#s9)*yH_m0@xRW1o`)%+LmefZ~(-U0~!@Slo!kqQ5F*rYFbhE9fGj}CU;Kys$mf5i06J(QkN-v0?XrN?{O6ZtL|u#jxB%fl%zxmI zl>gzsb??LZpHm&&P99AGfWPOzhd%?zFaAGPSgjrY;y)XH{1m`kgOeZJF3>Rl!G7=q zJO1;xg(-l~|B;pf)3E{Nf2IIh1=cJ8@=NK9OYmP7p!}~RwQ&K@fBHYbUsC|(f5D%L z0KXT)zXbWc1%Q2o3sALQbI~2y>e(*-Tk?Nv<;};UWM3E%=WGpuGI= z`#&PTxi?|fKg}QYf3N^aoY!kk;P)@Jn*W*zc=(I|=Cke;CI<9>5Cf4P7qBkS-Tb%YpX0xp zKlFdZf2B?3e^u5Z)&Ic)#DAJUw*E`or6<9}xEx`qF_>*7BZiT{Lu@qci90r*pi z{qUdqkpJHl)c-~sM??AF^=(+4K}zz8{-Jnxk`o?UPsAnqJgA|ewf=BR^oM~k0^19e zI}4h_f>Lj$N8iqHTlBy=_AaJh=$@d8{6S@pcjM5eNRkJXHdOT>F+A8|UJ>U3C9FYL zy;Iqpf?tSK!9BJ--AUv9@W6)W0`DmJ^R9I}+NnUSv>{a)W0NQ6@Mj`FI@X?eoa#tFw?zvSRH23&4-t{OylJ$meN587-$%Dbw^VX?W6vHsIrOINKF8tG zgTdK8oENm^nKlIfxqX;bhTs~SI&N~eD_xNMMXL;aM>er&A7kaoF{IRMtH*Z7 z)>n2?5zf1zx{Jz3^4M2Vy)C$-tq1$0?d}Mm(#Ao=SAM)Q?!~p~S_mM=PJNVJ_~lJW z-RX%BZDS#~nV?|%I!8cX_*7yo7`421zP{rux%Y*(!F`Q=sQh48>Hbcs{IK1y%o;rd zE@dvR?LiE-JY%hOF<<+FY*Q%R6&`1B&j?cs>G05guZkn}d92C*RP^zu>?DWv->tWS z+rz`dSqwBg2$l(U9Nq9_oy5CX0%r3k10VAFy>H>rxm~tkWYxV(?yzM~YvI!kh(Qsj zRpi9qjh*!TU9GH7)HWqiG&bDw$|$s?)}Ki6N482LmVHMui;|wIOTWK7ocR=4V&@Ep z4|uh|ynWj?|4)GqK|L!(opfiG&mT#ozf}7WD;&9{ZE6ZQ$mqI1U z&whMcV*6Hl^3!3k&jwVtgO`dhcQ56C@n7=@?<48St4sz_yf?kHxGXJRS(5A&(927H z2_SNEV0!r_8Xel^w_uk`k|Bj{M!6a zrRO6HXg<~s`2~Mm0RH8J#}%eM9Jg-E}s5l+Q?R`oCR2` z=b3if3qcPIm*Z01_yTHCIAk6=={auh>!Uf>JECAqxeOUl5z#qK@^q-ye7GT(S{KpGK ze&CM_?bR-XM~q;i2s^60Dmk1{!8$mFPq1ISpeI&*vh3xInt9$UJC!} z|GbG$ z&;MY&e_)u{k7NOYKNZOW2>pdEB}LixJ_j{4g6RB#{!i9 zRXzL}Y(H%O>VdzLZBUfJ7x32}6~+aTK1~6Dzrw${K#u=51<2)pj6l0|^7zl?(L#sk zKkyg-N&f7~4Cnt1J6aIQU-@7Bhx~E@ksk{{^#3&lpo;&%Kac-19o4GX1o@xJ6hP$H z6hQZaDgS%^V*z>jAO348#PeTMfYtoR1%SU7uc5^3fbfr4>G1q#3c%dW^S`n!cP`Tl zN%$Y^0$R7n^Pjas_z(Ow1(^NCO;E234aNT?yMSDtRQLz};rtK(eg3EaR2C3;TqB1{i^OuKcg$uj={F6hIIEs_Nr` zf0+MnB4DSz$rtkY5Bcc|A|-#|Z?gb<@;8_Qi2tez|Elc3M{)srWmtgi-hY1?@@opf z{!eyzD*P{JZ<722_`Cd%1!xu^{@WQ5i`RVPhyn1wb>}yqUAKvV;6Jr+9f|y5{@bGP zJ3JIT5C1bCW)aC>;U6QgAI2>usE;K0Q$74K0{9R7rTg$7$j>knsJ}k8lC_FJ2X}3uS+w=RcRE z@K2u3kGeqgfBY1{lOJk9ep)~p0Dt9w&wq7+JpUO$iM;*~;otM$H-9|;dBRKZ#|4!C zY5u@}u#W}E1%SWA6hQo^`NP2He+G7ei|hZWstZI5NX;LR#kU6g-U5jIvH)5@p8sVW z{+61@0<;51{8tMI@&^sH9oF`-ifp8x)hd>HU2|HFSOAEW*c{0I9I z`CoH4DieXy=Q@1&X99 z^1mMb_52s)#ecp+ZWa*0pSO$usx*H*|3&`F!+o6g~CH6ypxd7Pb_d>-2Nb->oBk}V*7*+8XXIYIcZyF-cYj24v44?O?NwdtEdz0<~O_B6I521N}6 zo9g=D|Hgei>vwk+{&|fZQdW&0RCd@2IbMSFWU@9ub_qoh?M{z&m_|r$fwXp_8 z-Toi8nxLt@EG!*P;C@epUjQ?eJ5H$9|jqTdk`uKOBU;m$L*KalHbM3E6F6VFF)f#*+ z25yS6<=IY?+wiZQpVk$0+dj(=^aSKT+{ZxwQ+{3$Z69p!O{31AWF&j+iz9%XSPSld z+oZ><>AiCo@Iv<2=;p0|r2mf?WZpIYU%Iq_p#8PKy(XC*EN8|4xkbA>Z1VCg2736H z3eU&qIHr#)=53Jq@EWrWRle8cN7oSpJZOA|-K1ZezWDmmFYidRi#Mf-53;tc*JDpL`w@xGZ$vAEMEQW^BcGBd_~Q?H;s}hI?QqU{}YRMq{&b2{8nW+JTNE!!PrE7 zBGd9xTnaPoVgLWPS;I>I-}8TPc!DwHZ*FPF0_@6W2mi>vsQ6!78%4SZSa$(8H?+$F z(&uLc|2+QV0+CnkD1NGr#1Z^40^aE1FY*I_24G*$3u6Qx{`Q=&hd&@{7=Zke_%E)C z|5V$r?sgoB|B&BH{NKFWp4X_lR)P6BIZ7Jx+lFv=j+yvx@Xzrd7ZCqt0aW0RIPf3-3;rd| z!|>m~fR9ylKC(3m|78Kn_Mkq@e=I<6(R;;zEC8^BdL$PB{^duKsOrQ}^BXK=uUJ6A zbG_of;4l6!eB$!|T$Vu|{1b1@$q{t_7cLkll!G9WV;(zJ> z9>L$H1KjZYeU1a_GDo25!gu&D^7BUqySay}1+WY9hW(Oy1ikH7Uw#x9FqJjx!x)75 z|M-*7^I=}v2DJNT3TYa5eZ)kpde7Jz`i z9{6Pte`Cs9fcQ_x3=07MvViQJ-z+WPf&6j-@t+F++57|iozfJFYekL|eWIj$aa!UaVB%tzM{*yp`iK$!n?pV+}f;y)Gu`4KKa zCItRV%h~($e`4|W+WN(v39sD8U<6_QhtFGk$o~iAKc*@E3;s&}SO6mSdnx>j|C$2G z1;l?@0Quif0o3ZJ+C(5R=_UAM1n^(spILy(k)I0r;Xg9?gG$)zrU0J*o5;_HE&PZ1 zj|GVTJlzBQJ^z*e8-H?9;a?Wu`HuzU@n89$?fSqU3qWQf?$IsyZ`#oe`6Y#a_>X`9 z;a~jM$|LY+7C`v7+h`U3nFT2S^L9P}{_F4`D#>3KU@mZCD9r!Jt9W-X5m=M|#C|Vg|G>!1 ziX0`9~Afc)V1`<+4T7yng5{1@Tj zzbwE8F8pg2z-XwBENQiLVoyKyya?SN;e7DEoPKd1+bUAMAVnGhX_{C4b<5 z`4+KXN5Con>;6Y9faK4Y)f7PCAO14{``!XXepTQv{__x-!awl8^$%`V;_^Q(Aoz>_ zz#riPdHH{B;O8K(_l{k;?d3l{kN*$z|8HY{c#Zh3{txi?{Pz~%;jjKr82;V@;J=>& z47@Rn=Tm33>k0{}K5K|LXrhep$eM_z(Og z9EARlT!8S;hJPygU*sqJEC18~0siX$c>as?R@K@)Dfrmd9K>iP!KkWSMnUFmH)&Bwe2>#a`Hu9@U;`vYbCsgzD zlKjd441E5#m)+4mXv@HVl*rT|nMa2;4~3IPB4 zBNh&vpjYJ@cjhkD5PnfnevSn*#Xoj|D(}HGh2n2MdUv92WnX1*rcs zl37AnfagC0K+P0DEg-?)mH-_8^$0L7p#G1h0PtVe$HRZ%kK_WxeuaMqTDX@BDF5p_ zs{bPkfc%;Q*ax3qBKafnpUw~PN9zCRXH(~g<`23T|I_?PIodN`Q-XiqyZEed{(s2- zZ^nQ2?bE$MLmUD0#&Bn6LSoNPXx~6Zi=8{fO)+$(tTDxg#^*Y%|MOgDd8DhVV^rGv z+GJJtJ9q;W(OFNsn$Y2z0`9UATYQJ6HhG;Z>>pKyt zp)1WElF_MUY4DvzIu)wZS8gDs#LT5@L+>uCYL^SkolFNf{GswtPg!-l>dyV0z#r|| z*N&=ek#qo6uolcgaP07LrzpTx2HT!#!x6T8uZh9toh@GcF?i#S=$7)vZM$0}b^f&k zfMpbxbCQ2k!Hy^=_VDPg&TY_`D)GU3m-cxE{NGLUhrc}B>SFxoOHobkvc5(^v<1JpjDP=#q_M3nD8h!cqcW(aO zZ7Iv9B)1AYH9gPS0<|XxhUacc>BUe@%WWA<+1NJzW z{n74=M+_jp1pnFc1ox?rbgOM*ZAN1p$)({u1&v7ZY0;eX%)H*U!SCg&~r zOBlh(}dL@;}=`5d2s2?>;k2^FPdgjvY|=_x!i;9~-W1PWk*V{sVso;y)Ik@E^|qBx+f} zUHpgM@E_3^%JJU@F8{-Syk6ZQ%>u;#zy)0X7yLzg&wtqg)#raKz*<1a@n5bHxPZ(5 z;y*v6;Lndr`1kzx`CsH0{KNbw|F7mhE*);IS1rYpKg9ZMBedT`!fvOa$P+!ao)O_MJf(|A9XifW&{M z0POZeoKqw*3n2fm$^XIGTPs>ke!bJznuTcR9gKX26TQD{((Q_ zR||*%{0IIhTGtH!t@CrN-Q@Z|LCx`>S%BY{!a&KN@Xr|RLk29sble^(qALHxf2IJm zfZ)Fl2lEy9)Bh3qJ^z*eX#uJ8qbY#$zgj>Fy5hf*Ki_UO|78KChg0z1$nPqDuOy%U z#ea+a)!k|VDgV>_f&U8sRGPh77bgEBu&?G16^45YAofFkxRjUw#eemG!u*H){*U+{TK{#OpB?N1YPu`uyG9UiG3Mud!9Kv9@Wv9rUHoUy z|FfOuIBp4m@K5sx{!?XA{HVVFg9QM8DV+ah1j_%K0?_$EOaXX3MQQj?{)hjxfW&{E z+ZF$*WPVKnsNwvtUJz3Nq|OigSN_+R#RwGsY5pMPe_h`!FVHkW{MWD2^B)&b@|O#E z{xbmnp8rbzK?~>}{ht;1&)$OSYby2rH81}G5BdL1;eXfu|G^}n;BOi$)v^2+2DbMdzw{Q6Y9ra;}_-%*oa=LO|qW(wcD_hS> zb*Iw18j=#1FGKq%ntsm_oLmXwCoT;_8ml1HIOFau@RIPOj&BGN{&F zOeYR_oFj)fNzz2>>=I|emq2T;#2Aoz`(*uPR5$RFbKl%D3cLX5bTXF1cb?m(9 z#1Mhy_Tc(d4GRT(8-NtnITYg8t*ydL;fwUw&(8*>?UT&VS=U(TUm5 zQtw|J6rMR~+mX{KNdOqWKev@2yWn95Z*; z#t|P-{A??)aA|dnU);7`EiwWd0AbMmRFt}9r-^qJZjS@;#Hawo%s?t{7XNE*TX%!IiBntgv3EnZsWiD13u=CzxM<@oUrmM>nm z%YRwnox6HlO8|@6FO~BdOn!6&jlOpk6Ym|FJNw>Mc>z_I5m2WtUq^O=1Sf)C&Z4WI zT)Xl4jqKlETUuJS@V~VD*>d*E;u6*NAi19^^RC?j@O)c;;zCv$;1Pr0roPGSiZ0&h zbHWICEb(}ITnfYRVgEn;YOFP0>Hl-i5AgT=Z#~&9{)gc&7YOqo7cjlpqBrsZp8q@_ zw4uDkTL9QcRVRlq0(BLr7yniXsJDdRi3_SmF0r8(|gAo7uYI=@oHUG<_ z{Z%JMuz)cC+2IrBzu@or&#ocv1=#-2SUSvqS%7W+IW>;N|H7IC!Ugo)wD`|UZRBTV zc4sWie_4Q*QLw@=|BDW@Vv_LuXQlxEAwT?oWK)z{P!)&#SOAr!hXDQ|{^J69{MY%< zRM_IkZ!Q4&CGj8fLk~`b0RE6)68~iZ>i@9#tNzbw{$l}<-&O&hZAG5{Tgn;@`(BR! zSOEM7`@r9~{f+jyM*uXo89{FS*SbB9|5yO?2tK@W%q=0?F|uBntrhvHjhEKYW`yZNXZ}gV*%nn@JHGmBnuGy zmH(CeH46ayUVat;|4IJb)J$b@)5Bl<2VdlW#Bnj6|5yO|UsHfE{}ul8@<03s{;~l0 z&qhSS-;BWJe=7MOwoABx^1tW5EC3hq;otKg7ZCp;KN(f|AO6>*X0QN}Kg@sNFaAGK z5f}f7{a64M3-J8M0to*;|9k%PJcWlpFRzlnW&z6o@SiDw^1mwkh!F74uI&@%KlxweSB3nbo+*F_KCwTK z|Azfs{#WuB{~^C5{#VuaYYHI#GYh~1Aiv;G{3$?qw}1w8zj1t|Y>svA=PpZ^)e&jgo|VdcEn$p6V# zxPX$sEP&XLZ~+AWN&aE}CkN~bfN=gdr2kIJ@gEm>$p3#8{?qwU{#W>i|48sB*stb) z0Ds4S!C(C!IzJEzJ-R7^Gz$Rxh$#R@pycn#&tsePf3N`YpDqw0_6z>Z0)T&2QwlK% z^WVdti2&I5Eg&-RYW_0?@cEyC_^&BInEzlOk^gA{(fRTHpD_Q)>d4^F{a-HpV*xf` zYkiq*L`1qHMlB$)FAJb*cfI&8_*40RRQUJ&2mX?pKg$1tzor0S-}9gFFRkXkECBx3 z#zthUzTyH1{sVuBPY3?Y0+9I6%ZSwfvF6X#DDamBTzzWEclKv@g$7yo4eVg9QNB>vmF@Q!B4FJT10pC`nT_^&B|@;~HP7YO)+ zdf?9h?5p`B{>uV@GuS8jQ*i;G|FM9){4e+uwsjV$`ai%Q3y}EjDF0&tp8pKMzFI(3 zu#a#7W&!-$lm(~@MEKVf0Qe(*F!-`D0a6vgBX_vEKT4RlMX-f{J*iiN{*C%MptyWDlNuMwtB1cQ0>XH)fI> zVRpJFc^Oo;jG~=~Q*>z6KrWB;R5hlmPK<(RJtM4DgBlJ6Y8WoB4Hg_3l+_PfSHFIc z1BHqX^p_n@ZLa1a<&-^|#JTkD380EYDXE6XzM4iQzMz`wH2=%E;)Ijm4s@f6hSO~I z;YxR@_I11P@%f+5qG0`(&8WwQ+2DkAYMT?RMvv`^@j8EdM=P=y+-3(|k{P9Ys-mnh zRl$<_$>DmAnong~UK@+Ds;Q3#)Kh8BJ z<5O3q(?6S=zI=@*fT(EX!c{bN`35z0ez9j{7PY^TY3&_j(|g0IQOMtPiqmg0tbuYF zR_&3#z4blRngj8wgC^d%H=3x}AFJVXp#8D3s@Bq~m{jZ@-(XdD+s+nb#Lk`V!$bfv zBM|Dve@pv1%z;O`o_xOWsRmT=-Fj-6{~L;<1%K8gJ@MU!C!RWLhsAN)n`{0n@Nec~ z%^jTlW3{k6#vm--sJF`$jQrJ!ExTDD;Q6&g`F>MXeNy3{s{Bt2DE8VUYVDqAOH6v5 z{@EpId@4J=aC0g9<*hqk!)k6_7X?)h&cbbMU6X8fY+DDn` zrAr?zWf$$tAHN>W7NF%{W+lJ>XW`1HG==>6|1~F)?dO)H_&dvMs&jn#{=zb9PNiGg z<5C!g5BvY&S7WX5O8=iDogu$0K>P>(Cct@YezF# zT^8W^UwkNm1pmgKGy}mO7eK&Y{HJof7=r&u{I|`PtWmZM2>yBe2mT29VF9I_zMJDe zJ21t62IxNg#|7-fwv%Ziw&OqfzqFZXU>@yb#^B)Rf1ZA8N`dkkdApWxj z2!;92+NI~e^=Dq5Sg`XIx>%HdovRJ_wZ+%6Y&3bSu6avS{{=Hc>ZtUoMhI2 z*-tC@$M}CS0e_3!4*qQe8PuN2cnbjgNEQI<*X?KuTfk#aH6k^CsGk2#J?Sw2aRK1J z^!Xj&&$GZD{$zfUU)94O{saHj{Ko~ve=7X<@aJ{&@Q43fo~G^JXz*tnkK5P}$@vuo ztH5qKn76F(Kld;%{D=IKxqy4xOB;UdE-=r3;Ex43{%hqo$p01G`OC?oR>gm6cmV&O z*unE<>;v@i%6$0N~G408Ou&5%A)83jq6A0Q^VdzbwG>9~Th+ zu>b`2C5&M5{3L?^7Q#Qi#@0|O68V`C0CSz;pbGZW?`I{*FZkQyue*#uRs0A3;=dmI zrCz&slkXDdKk(=LANcR@e+=`#{q0ZJR4o1J{e?R` zeY6GmQ(f#Q`8Tn>NBjr!rk1#-06zcg?e&dz6}#l~KLf%)7C?pnV1HeCGnM=g`2~OY z&wZdIe=1=2;h%{B@F)LE3jb6yf?W8A|Ac>#sFMxEf8fsm{ww@b-41+vxQzTS3s{~1 z)t}K60P@rS&&&T9fx^G|Z;c?A|CtCV{{tUrL-GvspZpL1t2t1V&8{x|lmC7Ahs<{3 zM7KTpYcAl!|K0r8GY)jO7zD|`%wqq2_)qe;@So#9Qvjd;fq&v0`^i@FRBFNyz}4k-U?3cxIY<1f4gsM`~s0>}b@f0+L?f8alYQ4UjcV?X z$kLj+7xu$%f5`uTIsbXo3w6f(X#w@Vmg?x}5%a^fwK*om+B#VR@a>?ZjqRwt#l+!_ zLI?G+;^_K6YeEbjEp4GYK}DN*T-T|hnMK|Vsy#VW&KhWQ(hCcSzH+v$|2$$XSh8mU zST2kWm)0j(I6wu}og1EwncSK7*^Fr;B2PgJE1$=%s@$Ky`k8F*--5CB6+9;17viCSLM#?BwKjaH8}e44OVC48)Q!!~R9Sb*OeK?P6N7nU?^Cacro zdGh%Umh*X%tEJ$nMh2YfS@6`+KqZZZJ6d>SK}lmlQ4|%HHt`kKZ;d?uWK{L>C+j8P zzhRq+{(r$!O;0@4V%ov6(kuLYmc`JPJzZW!&vcd5^soes zYL9Rb5ECEM3(Z5QnZqAq>Bi1+i5Dt)?g~vIDiCJzSL^BH?7jc+Q>3VWc+F4w@>SfqpT)LLMMqOB3mNFNE3wqAaX3^wj9s#>5CDZmD5rY(GIyvSup!0wJ z13M-Z&COn6ZTITZXABlEFCtAh`0h)eW~J#5E+PG#+%4YvQe5Kv|AxUUlI}SQ*M>9m z{PF0}qF3XY1*v6Z@n}xX=a%-K8eJ2B5BvXXzAT|PuJr$bf5Xuj{73NLTR^P6tMzzi zpyn9lN4Nm|C+*7xJp60w+Sl)BM4}Ve2OZ-7BU|ca0pHjN%>c-Y|2AiL$rJwXX&4aysd@bO@Q44KOUwe+)OU@l4bE6`E-&=Et!$0%*Z}2}p$iX;! z8~P=%FaA^W_z(Qa?No(!_-}Xh=HM^>L;f)TWdR$u)d7E1;BPQ@E&%-bbokFe@Xxux z^YCBEe;u3Iws9yN-?YiFFY>E0JHQ2YU=7?Q6bmfC@t+UF1w8y2z<*f)E>L-}4-1g? zMU#^FAN$EgEP$H6_?fo=_R|0Ms%c6K5q|1keG1@QTw&7UNH$WKM$KNXu0|5XY9UVJr@zor0me)Ppx^B?$2 z;=ii+j|DIQ{?iL~{wGra<$tCC_(hoike~cd zd-0zs0OYr*@2Vwy?qvwX#?E%}AM$H64@MyVn;qQEf8f7{4cAHV*zpjrUUR_Ra=9^f8dV=XbJ%NN&Z*> z75NI&&eUwQi^nrL z)9J4KpE*B+;Q#E!*&zIL>6km`K^CCoPh~%nhd+aG{s;c`sWlW$&EH3IfrtG6x8T2K z0q|d9A^`lwe=I=ZANboupvC$>NcmsU6#lFKW6dAOe_a=a3jlw}PsIp4{27q^AwP=t zrop~8g)&g`#{w{jF#K1VKaT%e{KWzwKjGi=ANXq)0Q@B;0>D4a|4<7kLGqV?zgIZ_ zi~q6!;4g*w@AJR-5B#Mt|Ct4Z`49Ph3kd$x{{j9~e_4R%zgj?ozpBsY3<&=c79jp> z=f8)4|CJ%i|1pE=n-!{h9 zbgKRX`3e8Ds{DBUNBN&2K)z@n^1o&HvKsN9{Er31>pxh4fPV%4GXx<2^MSNM)nFg~ z$Kj6!MDX|ePk=ubApQe?vw&6H5t)ffKso+n1mb@*3Sg;N&H_{sit`^AApeW}xB!Cu zh*1E7sGk1`|L6bu0&@Oq%2n`(|H$h`%V@){B0JXF0bV8r=>N&mzr0Wm~->CS;bqeU9xpfiM14pulbz~((KZjd8->| z-LxI?IL|LyZy!~%wRLlh?v17c=xpSS1&-MXi+{GXk8Ij)_dFtYZ>_qweZ{6GRDN&U z`s%P~lM8$keW+wpD=J=Hhsy5CP|_(U{}cFw>|Ow7c)#9Tx|NLp+!5KzEhONgxS|P_ z-PO){FU%LO!AkDo5cqC86Y|b*;?SLqd@6l2v{ieKA+CT&TOU7?U~|OdM>aMcsHp8j z!M{2<)kk}KnF3z8v6&XlUzfgdL+VCut)=CN%P=kCElZ@BcQlt*G9Az&_*W*ntLpcnnn#9!KW*x< z;lBM7yo|JHcmEndJ!TMFn)*|XnMmn; zp`$99MSnCg_2I|+@8Umwh`zUP`1-GuU-Oy%yS{kErY#TmBL2y#yz<}MrzQ61`x)}} zf9HSlTP@AI^A^BCpb`AjQTPY`9Q6tRSprI%tW7!pjSOW8;2$aQKeB-0t=9*^f5D#? zBM|)gD8ef62S>mk3H}-a2>#RgZ$|)yi(qJ{^B?$&|B!zL7xf0%LRu_kN6PVJS&VRFj++MJS6-oFnIsdT$B=XAzbP*)*N0gME|CAJ*|7=5W{^#NU^(^F< z*h~%f#edrA{4ctN1^ispbqV|-KNxrZ&tJA33z+wnO2MBePv<}I7yq$r)nWt%{GYchSN12>ug?~*X%YM{$A92&Mi4dy(4y)5XU(VcANUjgMSfWTwHLR5 z*M53d7C?vC|0W0U{l$4Y;y)Gu{~><_|5pwESO6;EzgGUp0<`~^(_H-^INkXo^3!s? zBjnHYjZp}qb@^{~86re+B~D|4aU7cbM~E@Q44({~7`me`C#F!aoB3kRQ=0;6F==fImi{{7?92&8PDp z7x3^;N93nvAYl9_{KxYD+PZF}@UQ$2{5K_gmH#dF-`^G~tOC*yAkKfnzvq9jul!F7 z{2~AKU#SxR%kFMQ%KubvZ~;aEBL9s1r$)pm0LA&g9_$C{U?2EThqSN!5BzUjRtf+8 z4lmFD;=d<>`3DXikMkc3KwzI4 zmdFDBNHZh9`gGTz|VisKp=nY^PA^2 z1Yi^({>uV}UKp1JoH;Qi^5X)G0-XN`o2yf`F5pl8r=?^8{0aYRc``!) z_)n|k&nUq2e*yfrKgxQ`sQxpZ|5$+Y9}5uwfxiphN>~8=r{1pmkBUFa|1d}Jr&ax@ zfd9Av@Ml*q^&fMAulL6JkIMl60{#Pk=fBr~=*Wq*6AkRcf7$~6d+`VUlmAuof&c0l z{J9p>`M)6*WquA!OZP*52_w+jDl7map#Fme*hf)dxvLrYJO8l&)qmprSN`WGCH}hw z#Opu6pYShHuLJ&S3ICq|RsW%7ATXW(g1@&j@?Z5IC4ZaVy=9vMzcN34$gld3;6G#j z7yq#UKI(G(#{zH=YXkp*KO+1){~p8tWr_|Fiafd32x;`tx!=k@sLmLQBk560n7-^T)9-?&_Wd^f3GX9y5Z&ottNu$*d`{{X57)h6s;}MNwjTkB%^W=oE<)2 z@y*VXE$JI8SVUT1vbEVZv8L@9%<>w$4j8e^Ne4mD&ih(pQDqBaDNb>vJ-&2n2hutJ zOrEa#dM79RptaQRGX+wS?Ql%dE&;vAqjHb*t@Ebs_#pRV4ry zh?770D4qYw9x>U(jTM=tmF=uJ<*(kvU62(`RF+EbYF~eU$L5FnXwj-InH3uw*|@~{ zpBzJnwq%BbMm9AaL|ZZ=RgWDC-`hSm!If8cNToKBVW;O6-O-E~?98o5Y3@TLhv5s? zrHby#lx)k=a*())t+uUUfduX}Aq;LN#vsj|3wnEUB+}Y@2KeZp}u%HxH+wEPn^OtQ!@E@O@yW}2e ze#ry#ODNHsd_+KJ_M#1F{>={{`?-X>o99#Tx9I>ICeWIF-2A}Y;(PS7`<=3f5aj1H zZw3W~|*JhA))@39WSI>;R7;O{Q zYF^s0SI=^q9P9tJ^LOGW6KnyaMK8bd+TkCKA=dm1K6?;#bgCGhuV7d1>Z#oG$I_PX zj=CzpJ8H^~Aw9TNoyTKCgP03!d9**(l!^33{Xg~!e3U!n>;JVo(=OoO*p!9;rX2jS z0N^iS0eSd`vmoGq$$HxvWQYjx#|VHw0{&P4JQ4h9;}ZX60U|#xfFOSa|GKn?i~{#^JHe%^G~;77nHz-9qN{!97Ki^+Zp z;4c?|{}L9!_k#t<1;9RHb)xfM*oXg+pFSP15Bza~0{(C2e$Si*IQ*Baw_`M%|MQkr zivJh^*cbn?0N_9SD;sFVe!kcrxvMJ7g5nKG%PfE`R{^CDI0QTWOEwbr= zU;)+%pV|5EpXx?C>L&&Ku>dyz0)K4*7W|$6MVuYIE(8As|2Y43H9Y(m{Mktj_Thi) zlSffU|G4x2*sJG(zxWUKC#TLy<71OpfF%A?V4)-O1AjU;9h^IX-{DVUf90p=fIlr# z?AL8>kRNf>Cq{$dzbpXkvy~gsv2#9uIyKJ0K0h8m`O}j~E&%^!0nUHEpHTma_)q^M z_#a%rO~E=}@c$FAJ@2!ZcY%EV2mT~~N&LqGklpI|a0byK_CtOS{J{mR__H&WO4=?k z<$v)X_(Oh!Kk+H>U#-JmM!=gE{&V?X#}R;iFZJi)Uy%U&@SoQCFM`PeM0=5cI{)p2 zXTd-4pYj4OK>jEBUylD80(kx}-PB6{7ynf;*3DlU1qlAMSLS~e*NQ#VSHOSZ@A+T+ zC;Th_GXy}DkJu0ZiT_}qApmXhoh|U6S5HF#uy3#SH2#zP<(qVXKhh`w^6LfkmyuTz z{?A+6AQj|)_^_hMf=fCp5EI|A>TL}w<==cyI{&~zwa`|7jVn(o*JA$*cJfiT=o74FZ{I~4vgZ9e* zI!OcmLw>cCfMfx<0Q{E)DE|Y0E&GK0SODSQ^S}5n@&kWF!QV##p8pvFIQ-$i^1tdo z!agk)paRk0k4~5iymU(Zrz8F=|1C}a}^VO~Im zpfB?OKhA$v zeu91SKl2e7fynRhFW^7$_xxYLe{%sYz6{}?mKO>Ee+B|Z_)z@81swZyRR3oPU|Lz{ z7U0DnI$&Q%YKZ@`0Of!B)PJ1+xPbT%`Ne;cUoF^&8-#!7Kk&x|;{0b?L_+}a-}ApJ zKeV3z83mXHlsrKG7ylu%iaGoUl>7_$Z`qzjo-CRT^&dS=t|9*O1SImu`7ij(R`ezK zJo+T^5&NNE%6}ULls5u=+IaoPMgdXf$4&&L{^R^t_@`C=XTnz&0Q@EAzbpVUJO8Qt z$O33R{}2D+QLyhNAP@fx1mM3f85RH4di{rifcUTa57_5T_>U0~`ysztum4~K%Kx$e z;LqkSjRJr_^`DQ)e}Es=e`d=6nisHvKyF?b3;2TnpPm0?`^JXWOs31UJKNCEQdi%M zDd>_HUG>Ga@3o1f=6qQKlzzAw(GmYQRW)3*EHU@iI%)ozhD96Fh~24hUN^#cJD;-= zLb3(*^KR$(8qJh{@kocQ+xM1+MAY^l(2{y>EGx>)?AzI5mhuhb_srWhdqLwpMZl zOige3eQk(G7L-O+Wjagj#;&%FwY}CR?f&{THGR~1tlEEfyA^nIy7lg`{+|`6Y(03e z8~&G6)JZte`ntVH^S_%K_aml&`IflPX!EYV^)(%|QU0%LUvx*);!Q0~I@2y%&z|4t zMWZvPybjG>+kmiuqPw{oENd<2Bi-464ES~$cDqdhY;Lm0!?{V+j^^B!M6*`ZTJe8* z{g=v9()_PBx)!Z#TzpqXD!#LsyU2MA;eY6duOqDsrA>E^ zFoB3NPmXjCj#>Wy-bkW(kcs21^?e%?9hw3N=WO#M;BaiNP)RIUz7-XfvCcD5R8h+- zPluOx;Vlm!I&&9qmgd`Nn5n0fmYJ5)6&h+?^W^o zW|!VYTVB<%zPb}tJe>$J?B#|%BiTMqQevWH#ENG9)qgtfeR%8r0W zl$f#|z4f~?C>2`*#Qg6)dq$-=^UVS-bpcHWZ29ik*6e7cFZlmC)PnN$|A_p7{|i62Q0J|fMsFp*S!yo>GDe<2c z+81rI7Esf1{sVvU-;RCL&aeBjasG4Gv;j8op8#CIf5;DPaRI@f7F~}2cEU{9VHD>- z76AOQ0Qir9e*yoOt#7jZUzhTqS!OKYBl!;xv4A-L!F~b%XT!P}|IG?RAqe=J?rd1F zwoa|Tm{|+7KKCOPNz#pfu54?$BU%POXZG5BS{9m|oM=*|0V02B*>4H|4IH>z?%EGzSi>;k`F~SOJpaRg2Ft05~rT5d75=`vremlD|a$clgtx^sONP{3rkW z5CH7Q^S|IvYuLZ}9t{ED|Lor>#{#HCL4GViE%_hC!$16|O5@n~PN2GBKhA&Ue_Vjr zZ{)`{R_^fp5A(%;I=FzCFYNQXRKR~M02S~b@*@ICl>8qasBakt{t}}A;LnT65P*)7 zzeWMTU;H-<2x~!c0W3g!yJ)S#pW{D60EK_KfXGj)!GhpVQONmE2l8tOU~O38qf)=@ z8~AgfGw_c#1s^@(@F)Kh`+>g%{GI=7L-=U^$Kmh&OI_d#{(oA|Uv3s4KOE!EcZ3U2 z2#WI`>`PW4!U4jzFFJxhZ6-JWiwlVVSU^-ywrn4jj=?X<-|Ii#5&sQtx%!W)K;%`B zC5id8GJSn$7yp(2u>jzYz&?@%=*3hE`LO^*6-fCX3z&T4g7QBtQsqZrpU!`ZKNNy^uUmkx z1;quxzQRAP_|L)Ji2UzTm(;mttxVl;OA^tURhC5B%`|^)5{dS6SJ$}alvTS0 z%(<;DSF)&^%^~pjXVHSn%#y8b$TmaebnDJO#2hQS_5KdTDaQ-fHPE7sJNv3z4j{fm z{!Wqhi><1Pt^;OLm{UME)emTe_RgG=&Cvb-NL$t!>1 z2f;lu{6v@z_|nR{g=?9V&y;RyM~lK>O+Vkoccn{t5!gx)v^lv~r0N`enHoiF?@=94 z-1UPO+nzewxMx_ZYdZ+-F$FrlS&R|?w zHrcUnx7J8DFT+N#zdBG#$0NQqxUp0g&k;MN*CB>aW^+ED7}K=Lp(vyhc(EGvTK zw^Z8`!gIX5qvzbnsi#b)gwGZ|!i)eP6g~nz|0FwT-|(IywB(8MQXg``q#2 z(GzrD8GGgRS6_#~(&&%JG~e3${UJY!laoJn_&+sy&ILOAv(xYX&4qXV&$lLCKPNG_ zdyMPbe)hJcRiL!PKRL~|ZZ!JuPfz@Zx5)noM_CK{CM}=GMjWqBotirJ<`mlsre6D# zNu(7=v}ezp%RbSQd?X_|srdF1yRwyg#;>f+d&XRsJoAb1N>{o+nQoQ*^V9j_{Ga%% zF;hQQ{|~GEo&Q=6YA(Q>?>ADC!{7N2{ILMw-_xE&{PJs-kgP}t^3SiZyWnZ(Rb*zb zY=|sidA;-B@2;Zbkf#H<#Q)jLxrnfeJ`d8ue+hPhedj;ek6Xa9?HwD^L#DugSpe|A zW^v-m{0IB80Oxqz? z`9^z=JX&Kua*3D`AOnOp5C64x+#mceUfY296M*>^dk80+GR}XnFaGm;wWhjT+W633 z@gMl}$^d`0@Sj6afxpz=H;QBdozIc zYJMy`o&Vqn{#Rv&B+jRuQHhp;n0}CGiB$dAU|#92FZe$b-Y-}7@yGM|U%S0*!Dlj~ zjbN+=RsP2UfAT;4C;3zSVH7~@kMkc3Ap9%;FWkrhK_*^US%9^7Hk1Dm9l>8MKZV>6qLJi} z1t9ou%cbmSQyT&Rf5Jba1OH_KT!+vsz*7@)GAO6b%sv8H9 z_)q>P`P1S8nSn`J04?Dk5&jYUmj(DJps#PhETAPT_~QcNzs~;${t%lX0D}Ao+SA6v zKk&EY|C7^nz&^6E06V{qOcDMO7C`J5{BZ&0e_AGdN&dQD01LPR|FHlmnQoa;aHjs2O#p(D*s=u{v-Ya zG}wy;L_>h(wj31r6KFkfLLR}N641g8QTPY=fcW4>FaFb^>{Gyh z{S}k^3Dt-W2@UeYf5b4s>p$W@@Ta5Vk1T-LkK+7i2!K5Qi~lR`&qgI6t^f-qAlCng z|FqNjPvr;ri~l5l;7<$r^?l+3Fkcox$At^Pf8Z~P|JN_B#050-0{rnuhd-S>{HX#3 z_>2Eq=P&;2XTfJig1=g@U%-D20mOeR{%|cwnEX{s@(2FnKjdfXP!=G#sR|_i6aMKu z&^QSBr2_uD1rYv$KdtkhADQ!CLjWi(P{V5Ff1ZO2SlNe-(xD0@^6U3OUO>x}75gs< z|G@<`rl93Bi~nk)%FkMx-YUrd3jfZ3)qkSOPmceBzw@7XfCZ@jQ`d43L4NU{*bnyM zzXbNN0O~(<8lRp-8Uld*0{%xOpd9~k0l)kUG86kDztBzi7yRkKe@Z~SiNL<3H)R3v zU&S9;0H1;Sk46EIpSb|SKl}&#;y;UyJp9v%Q^?^@XGZw*;B@lqkv#k{f-m_0Dc6F= z_`j#0lm9au#=9*+=1j*6Q@^3guWE4%k3oRV|uZp0o}}P3AP4Lqtof(G4Zr zZdhJz{O5=X)?jcf4@2y#EGm64Td}j3-C?w=zS%8t&r9Vu+LwII7MjxOev(6|`ZFy( zv?_zwd}ok@$k+(HHFH3v3_VV}>7g#FMyu}4R#bP>asqS7ooSH1bZv?|jw`;=WnYUn z)R&kk-o%BHJNwse>nLOY0vq2#ZY&V` z+t(!f6VyqXI#ITBfOb9i1+(Ril||comOj{B%DF>3`{_{c`t9Y_=$fxo&gM?u)s$<@ z8Eravb=|ym4LqUf&gKPog!?gxugs5gKAs+2m!`8Iw7_cq+Gd+sSZim>xdqHBwH*O- zxV0HOpbUP8eF$1g&8^bHZSfu4^=xO?Y^v|$K)IUT2c*=VBb0!UYC&uSle)OX_76t2 zj**Vmu4KP&b)jvI16v>NqeUzSMeD1x<@aV*Y)a#pCF@gkmaeHOzO|Z`rJ=y4xABsPr{?lAi*@AdPhmh+iLR&MyRYWy? zi~=+;-1;!Dz(DHp5yVSGD<_p#c6|Sp!9RRm>Ui!1>Ki#pixHraAD=+ny^_Cs_r%oE zqhl!3-UBU1|M+DI6l?L1wSRGD>h(xm^>X~wJG2vTyiNPssdwJ|tDn<(<)@Ke|MLrD zlN=3kMlDB=9-TOg=$!boaOluqzJ2yD-#+=qDORFtJmNDE$9^;#Xa1%Ah(CTQK#cYx zKa~od8lh);;i90E@y`(d{GT@e|M2>+Z1_ya|6g|Klu~>FXE(vz<=QXrIji85B!lT*cSfFQbt%-s{yF~7tw^E*{sVsr{>uVL z{;O&_#ec92_Qiiz90~q>iN@WAeZe0ifc%>{2Kl}$9UTNA3;3k`-&j9@fIscW=fB;+ z6^B2Ss}S$EkfL+^2mV9PaNXXJTY%v2{Qq)AQv3(|c?$@G0$Bj?kIOAUBrgJP8*M`Y z($B>#I86RpAt>-43xNMR`G?KFNUsm@2bFRDE4Ksx%+uqLU%~}||M-L*1mXP8_K$%$ z_z(OuPg;!#){&D_e0ph5&0`w`O{p$ ze^~(h-_|%N!GA8nM9J2J2=YtR%HsTo{F!GaBL)6XPD~+=T%K+Ldj}3c)V{rg;=jXR z{6GCO_%jMn{&)TZ zf0xDn-9x~ix|6;HE&%_5KjiNp7^WrmJL)(7ejo6U^S`3HgZ!`Lf93q|{J(PkC;WT< zC;2=7*FUna6!_=(Uy%RBe}#Wqk-wNdS@&g$_s;)o7Hx0~kP)cW3y1~4B_9aTH$B{=&j*o($?;2?}Z;a@X5gnwQ)_+OC!;Xm+4i~=CJ!as-*|A9ZuC-wt> zWSsziwaU601t|O%cLja5Y z?CnkRv2p&B|DFF9`@<9H@OiKR$@+o+SO8@u%`Y$nApcV!viFAk&o{%jK}&rM3!uFm z{}~048N`2H1d(4Z0Q_wt;Cmx<8uuI{`~zXzRsG{Lc?-zpfA|mlU99a?{-+iH&-}%C zug|*$IRATk`jQZ1 z<^n~YKRLo%+7Iymg8%Mr|9qYN>wjhb1ANc_ssf4p+6CbJuS!s7Zbs1%AXfkJ;*ay+ z;qT#J^&gdh9R3&qaI?w}S4mO=T5jSID*@&5zt?}T01810|G*!CeHZy3_|uC2`#e#C#( ze{2Yl zy+gN2g8do!ukf$359IecHsqH)|Eu@|`6WtZlzkB4A2H{vA%Jy4@kdo4=f6`I_KN=o z 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%0DjN*@IT+zaL#RdY%QMOsz5x_vc9QGE#=e( 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�M;NQkt?EHc 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

*jxEIv@vL@&D$#D$)ORSLJ_q(`E$l*Yf{+H*Z0Z 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

Rc26hd_xg|J>Zt`N=a0yXm%x6A`)@lm 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 literal 0 HcmV?d00001 diff --git a/src/GLVisualize/assets/doge.png b/src/GLVisualize/assets/doge.png new file mode 100644 index 0000000000000000000000000000000000000000..29bc9f0a281eabf72a48032e34338929c09eba89 GIT binary patch literal 311062 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 z

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 yD&ux=t*O|~)3-)!FR_Px8zmphc}s@kdkF4GHf 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

0K{@mo z3lZ&aAfh}hB#=k%3;UU}R*dSBo~C;6s<5oUEQVuoW7xPDzqj`;drhgTBOZApMUkR? zHZ^6Fuzzp#;_3<#BJ%kYAlTI(>|+wk&n5U3i>h9l;Yvhn)3%z~A|jW8gHZr1X11#8 z8tQ`*YhHd$Q?KrQ(P^DK7lXzVGI`&}jM?Lff!4M|r(_T6lAe}%*kD>~`10j5F6$>q zxnf;cTrL-E+go?v{QC9l#No)C5fXONU2MuM9G(W&pYQec6~foPpxtgaz#3`3{gCxj$vKJYxIazQdzIM({N5X7!{_HZuH2X?YZ}@U_xc`7S*$Fpc`a<^YN|G1Z?>xu9fd2ci$3W;p5AJfP2 zW*)zEEemtF+*YlWg_xPk0=>v$QW%Q>Zq@~=_2!A=E$5BKB4QGTld9o|p$d?SDTJT` zM>DvoF_E&!lpEqa5Y-;rn_IBOW{qwk_+c@DpOUY}G^ATXCro2Q2EbfEFhfFpvKNXa z3cG=sK-_J~L$^%E8816YR;hT^gh2*6P8hm%c%+_+Yk@ud%*@s(GOm3*0xM>=f@p23 zS5mr~*~;wp;Z1cRW?yE^7O)6Bk(B`!GZMIIF^5NGq-KI+;5=3Q%^dJ&&sqT~JcTia z^hSUfb%(*eF>!RZEYPOiDT2sn=5OzJ{P5#f{P|Cx@vC3{C4TXX6(UPFKYF{}aocJq zKINQtCzz&W5wl57E@b9OnB`z+e7~!^C9*+?oE;uAI}yRU7F@3jzWL@G{NfkCz&GDq z@$&N0JF;38B7{X!gRR~PTU^hikc@u;P*EW)@mT<25EdvJ%p@j$G}!=K@E&F#i$s%j zLLAWaFk22cM?(0QJW2+ig+3jPlpdj6o1kdwX{r|Lj$8mM6!a9C7&nIU1?AR>$+lD{W@A=Lt7WY)(oC`3<%RS8sic& zMhj01QY_(j&|tV{@vK{ixwDw?qUAVlNEn-YmXR0Fp(fEb5&uf}QP}+zD6X?JGHqVx zz1SQ!#v_4uzP=8{tI`AFFczE{4KQxvXCs)gxp+pxd{!ikNQ1~xmdyuF&ung%qwa@I zTtl;%kpNkNjp#)hND=|qg0g6l3QRDqVWuV!Sq39GM+Du@+|?!!4CZSJj_X<=Q1$35 zJ3&zriR>9E;|MMhMhz}i7GLDAJI^01I5uW`>TVV%X~WNvbJ8gMXZ^Ku5KBagnF^XV zm^rz#Rz<6d)&Pz33-z$G?m+8BD)GWbL`*2=6B0M7u%@k;td zz^Y12#;Q$78oA0}#iX%lWiuu*Wj6QBfnyoXf*9idGv;2XHVw@_lB(JVhFp(686ziS z;9S^nL!`RI6IiLwsBIuF4O-w-pE&+gx7HVrJphfSaY)X9hOZ1~%JRCdBf3xq{zW9D zdZCfu10i`Cp8#BHtqU{1uwiB9PwAl%uAX9Mf<1eMMij%$JQ%vGX&zK2qY@@&j18a` zm2SpYx7|T5#wBUQ#H4e2Xe=DBudn$0`7?g_;RjsSZ}9E6znnZ8ZnqoW-`^*m!m=!A z!JejJQ%>f;cUSkW&0p6Q^Ui;W&f_+&| zXSNAzj|vfGoi=(eGBR>p`o{dMOP|bn4(gPTyerParq0;&$DD<+TRgs&Wai;eKI6i3RgQOG9JNS9d5 zV>65N)7^>o=8^Y?P_!gBL%TA{t(fO1?c4;PAznuxgEaeUVJn_6cQ;NOii~k1?_YBR z84!bK=R8MEbDqo0>B%Bv9ehZpbs&(8okjmrgvlJU?-CD(+*FP!CFJZxRx1!GXtnbXskLU?R&jsd&>C!EaaBoE>WOMz#ITvQ`gKDoMQdH4 zWkFepDycGzh}AAvAys8n6;)L>u6vRJjqcMleRXw7|5=aTc*vSDH}DSOU7{RLedyt( z_Wuup(H%cg)-2OA(kajjF%H>{&p165!m=YSORzC%h;JZhx3`Q9rE>z9)S-`Ly!g09 zSGd(_b7wO$Do$ykg2v4n38@g75Rt%YaanO&4YsaYS2Qffw3^wA)_Sd5yHb%Nye`JL zs>rF*SmkV7Mc9%30;fn|h6D?8zcHWCe?5Z`G-bi>$r!Hb<+#>s6 zujq27>V6QY8>~9nQFH-g1sOr;f<=HYT45+qQdDK!YsK4*@#Tx+&wsw*fBw@SQSFLf z{^qao^;Yq#wcyq&maAaX8~*h53ygpw3|$GA^%9HM4RSG{Z9b2W`<2yQFr_l2GTxW> zuz&XM;$91CGpx2a?bX65uiepZcU(Sw!oUC36@T>`#&15|aBZ*P_YL^+j&i+XErgo=Y0ZZViL+(Uh{p`a!P_?4kzR<7& zODPcb*{q)=MsvmuDgm@KI6bPRj0whurp~))!DXRPo1}RfG`$So`;1k@0KL27gbS91 zKvJN(p=lU7*@2+hKE>;*e)FM4sG55)G#FsTQL*O5RI5N$XW+Y?GDGx?d=tBZy9R_@|y5^&3Jtgyu27*UVzJ$kh7rJ8&U!uPA5D( z%s88a*d!L}H#;Mxg!3tgngpx{*y`7LS{Lx5ZBsp^2~P+{2Tr)GUjtrMbp^njW^jO) z^6A=U`)UTV#jjCQOaKZBRGp4GG2wg`s7@#`{;-(_tT`+?AR#DDT#Kc2J4P~tT;0N* zCPAX)>k>K+1vA(J+(7qKAnKlSyPF@8XI$^%x*>okOk`_ zuC-qL)e?ni>%cG!a{8%du~>Khv{1ja06A=MJjD70tjKbXz`GI=>}UdDW(HU7hxb`) z0(We(0O%Aye-rXrtbyQy%ubcn0}Y{(K`*|qC90@ihAIV#mV?iN*6~B~Qnt4Nu+#Qk)KoEj?5>R5Oy@D8EOn&bb*CPo}o`IAX2m?ILV9F5D_Bt^$ zUP^(9!o-ku#X=W)v&B{{P!L@Tk!Ug)fs0TL@vcxVnXgdIw5$clD<);|G}|-_rF0_G zLRy$n02YQRq+}(MoF)%F5o2OgO>mwiBMFh0`#h&f3?MCq7Rn?95>8}rr`Tj>tP8=3 zB&Gx-kP!#Hfhm&7BHM_fJ8oJj)?s<2%)^A6Zve1X=~kI+UC`}mjGtkFC@RTVacuA*j=%m7a2-HYlrnd6M(yug zSEK?q;{#Fo^|l@|SK!nHyM{LHDswvW`V2%r?K=g#*`)MsTpgmn0Z&2fyBAB~o$D#? z!-o&8)p|akTk2u$4CL!_b4uBtsC<)*d9O0G#3|HP2rFg*&XeHbVaC(b6CNKQ+s`_& zdYe7E84k)ws&^O=Z zBTJ-56EL}i;^6E*j)<@Q)PDb&RdY#qD1*Hm+i z^i<%&jGEE7>w>xrJ39C3tpp+^Qz9zGxNu3OAQKTwYP})}E0py#z%6QnYEWnbQR-My zjhsE~xx?PO^`o339Auxdi-8|-l-zv&>2yLu6Kd8_wnpxZdZdCZWGFB;qDSfbl*Z;m zH)G#D>ujq98ku+&r9X`t!c0cyAXKQ3g?xJ}03@JW6THZ%Le7~G$*SNPu$jot1bTpv zL{7|{U_7bN1m=l^C(tzc986LV){2Xj$pI+=HgV&97n9qMb#B{)!GrVefv4|fvrcu> zt~!`1cuGD)R6~i3h`g*&%K#LQ=QAc2SXq&;7hJDzC}jn+pHe=4{MZ)4d7fL5(H1}( z7o-Yl5@M&<-&oSTwSCPQO937x!hA}YWX9ve2_K#w@%;D!59c#Z(~O5%a5_ys%TIB_ zBMpmbL87@qlDZ6=0KigP+%{2L*epv$A@h!Z7B64iz*Y2`OF^;HIt4XG-P`ip^$cQ| zQ&*6p1Q+I@iFTt058VMVh0;UAC|`wY{&-7QDV*@b#+~75~@&`d_%bWqf)0hL>*_T$XEV?*hOy zSAk|8iq{l@W13f-&u4u2@Pwa!`U#&tK8E1;!HY{wZ~M8f?+;Hb!$Wgldz=%xoPYew5zHDc`7;6e

4`Pv5Cq8*l;aD#In3$3n`(|yzq`MNHL3AFXkO_*Bmr(KaTiQF9i z`teHT6`5^Nv)b{gP&K~}v?Dufi^Zti7y)6L1bUvF?UGA%SXmo~*Ri~X{S0Pxbd3TO zkG?{tOqnCMB&C}XeHb8e2d0$1cEAReY!FLdxU?A;w$u`8uLmj)GQ`wsjPi5QcwEv1IIhWI-N$t&eBG6v6{cKRb*T%t{`lRnfVLo z#+37NemO@s%ZrT1^bHRW5BTum10Eh8 zIvqm@6WjaC4QJjW!HuD-g4Ak*Vt2~#PUrAWj>Vz0rlwY_+P10$m2CY-h^WQV?l5MJ7~5i_QzFA*!uI6qziGo|Lfo~;Ra92ve-?-2EW*Zy2(ur=7FW_Q#M zNK9$S+f7u-ZvhslTvjful>)*5m`&MX8<`alW=f_q8R;ZS6UYJqZjwM#F^UccyO>kt zBs|SXG80V#rbI{+3r|eb%rprRB_jbb)T;Qz$4c6UQ`IYv%JrdY!P$bp07~Q$d1!E{ z5W1Ds7g+IkUbV&%+ZaFW14fu;lywQqt06ICo&-W@fTTJbO-z_XFb4#y7AB<>IJk~M z;);Kh6aiHQnKGb;%o~qDG~5X*prwG>Uw|nQm<^|yah@5ci7=-LGc#r;%#<(@Ae3D*Z&l$bx4l3fiSou?jr3xTxcg1Xj34PZ+;<|LZJ62qB9>*&bVR!NE zm%4#&Namqjn3`tA0NY?xLbB_e>^lK<9G=_r=_04baiV9ahIXPmr%}f#X5g93kLxs&qYe<@^QZb|AE}D7(rb5PKg~(KVfS_#1 z0u>fbu%cnEF@_qk_2N(s(IhqY%nue2_w1~Pg^1^|i0t(kwWzR8wQuiL&o#x(e~%Tt z63tq~GE+6N3{=|vkjT`lGWV`^xg?wzn24+H!X6lOQld)rJTvo2M5ZKZMv_F79u&sW z*&rri+Bz9RL~N~{6cyYq@vi4(&`q;u>(m^noPELBx9Dz9O8X8*PtokV7&WM8-{q(P zu2KpTaT}TR>iW9KsH#J>PA=Fwn}eBjT>*m!7)e4RpNY>i<8<<5)`y1&JUl!!J;ppU zI0TdX4h^?iy&k(LP{Bj{f9E@vHM%*$?5(E#YpOYQLcGf1av>g~rs^ z1O9%`1*?F3M?_rmC3`xv;a99(j;-6dcntWnMQXvz(yGt07MHU0n_vqr<35s39BaL z%e6hH>)FR6)694}o$=|@hnx2;=M1eRQt5JTte|9tviRd6-Y86%Kht=h^6ve=Ddf0n zLUbSjTNNCmw1B$3>#TNtOD0UyM5U<3eePPmVC$=@DGHdG3Si=#EHlq1Dd8$nRi#pj zxWj}>S6GpnGC{${tg3F!^RG)}CZ@_p%1oYPLhUgyRi#+JABW|hV$}SDzNNcklxjzx zEcPHP7R82dwvBDLzrOlnc-lD7puQ8+c2_6-TiuYYUEq;RQkV!F(i8#2$0SCHnUYbN z%ts_M2~7Yd0nJ7>K`}9>*~}&*oQS97ahr2umI)>k7!znF7DgA*Rr^#3?w3O4k<-=brk@p?SrcFDQBi zLTs6YFbP8#uu`yGUvYVxaeaG*mK8~W(=3=pAOI``qf3C0D%M#RH8(*u6_=^4NN^a($I_<*O!M?6dn=2x&7SUdtg z0)~TAVE*_`}S_~Xl;_~Z9)_~Va1@Xvq#i9f!$Cgb(Z4_(B-`EXF6EcNYpw?|vm&PT9T73cZ5 zF73JvO(~OF(6j}`evKg~k8zitOl~UM!w+bn zLnkZ6o1r(A@0}a-0MIeGOL`4P_g;4YNVF9gMBqqRb>6E0u8<{TA+<@(65z#!L$~Mz zYuO|-GoQ@ttgxAgYEH>%>ww_Y5?Z~Sm0l1Ny!KwLJ2YBMjmB9n4%PIBEzRzv+G>2- zToGo5!W+Y)&Ib1Du=-@|j}Qb;Qqk zetyQsk00^;{Dg`v0u<8*_fjP+%YtQD@W21} z|87ObpMSjI%aqhOba_y zOI1rvQjP8g!TBsrqhW4PkkD#0TD3bdUDs%;#MTm8#k`_IWG)O{-paTk3Ek-Jg-Gud z75i=mEz4qQgUoF9R7Ak4pM>e%>Ltz7Fq0;0Gi3rmMO*&eHV&-g6M&H{oE=q|V(um( zBq2%!p2%n-;u%IWK_@D9Vzvo{Ni|2j`!qB2%pz>yWJV_#l7RqWHWCtlVHUK2`8M`aJ^n}yKo;FMN;d=~un%QJrajZ0*D09#DI{xu%(>}s`jK8uLfkPo>!}6|b%}~K1g&3$T!6|jmhFV9 z+k&wbejAd!VxfJZt!-$xuSx@^tzgse%1hH!ST6DJ2oa+%INrn%hffucx7U)9&BMa# z^DWVNvL_ExEM*1L9Ppxqbp_VNu&xZ|$-l?yCp%TepI^V?_uqfV-~Rl9fBxf7{PUmx zbja3n#oOzOwE*+O1es?%J$=IShYvWN9wRufU{OLY6TZBD!8KnUne6f)MtJD5N-pqbvniEI6H}!CLF^u^d5Y1TH+Jp4Rl;T3pxBp=U|xEh@gQ zSF~9{Eo>1kJS?ucl5l0I3<5;%ij3MhX?9yw?t`{s#Ydoit(3As%?ACz-d^5~Oj|cF zHr{!T@85~S>;2RSo=iw0NRkG8wwd8H_W^GG*ZX6-mUSGr?uslCZhEl(b#1V?D&fn% z_E`Vi0F;AH(>?^R50u*%U}-*$MO`;`95gaKj@4>$ur60H38pl6R@H6X+t!%q1pBC0 zq1k`WWeq2a?|2-v>@+#t<9byeLC*~20)tY?W~!OZs>0qiYoumY)Jjrv&jX2wlt3ob z!!SqZ&n$z%LTbef#peO4iQK)CVBnKXT&yI^g^ZO@3Yo102uVt`)F^-?5i-nO-jlvZ z5cr-}!!?^ClzKhJL1k#)X^qgm&c@b`)OvoWLEXA_4|KGQ)NixGQ1p{L;vpL)( zGk{aLMJDnD)x^v*A(C*6#dt_o7a7j-oaqpCMH@J>s)^?)*vNZ z85XTep*Nj}cDjp2QcEOezIkh$X>R(B`nlC*vG;2WXvje57qprJ>A57-i*=BMa887u zKYzr}KmUwhe)$DI{qz%_pPz9$rO4Uwla659e3#z9m;WK{v z{25PA9|2}8i{jh2FL-^q;`c8v`1 znE*%uu|d=~ZEwx4$X72ukblLePapAklDlk#&F<+=l%9IZF?;CW<7&x9X9=xEhg%$T z6Lj{>iN4sVu8;R9utz88J{WQ1LhNXgOgoEqi2b@w*AdyWCxRZ4Dff;u>+bRX{;9;x zqi)B0&W@fF(vMeev`V<2a@%)Od*S7gyXRi_rWP-IF3tDcEH_d0O~+vkX10w*?YrF+ z(-BkOGEY>t0<8xDhA!=NI-vyJ87th*TDrAIgS&)USNKI$b&(Z$WOUcs)DI&(9#aqJ?Gv|__WrgViLc!DH8CDF}C1bg~;q7HYk`u~$ z1&W2z|Acv-J>aZpEU1K8(zprtSn4QBtX!e%73KPda=id$!NkDhIpO)7@c;Oazu>?9 z_6z>~w@>)>^CO;SK_Y@`0c^!IaSPHC@c=F6P^)`3XgeKN3u&F{`XW2;7MQB;4+5^$ zFe++Ls%l#=#cnwtJLiswgsqK+LIs_`QVg9l*}_ukn?7miF>H0pow_R0P(V=R#YKJ~qurMUczyFgyf0tA;J^Os z@A$_*{(-;0e8ZoAyx{BC3{_x00Utg*een&t)Sh*6P|O?_82!3(!@sySDb&tNJy2E)Z`F5IF4f?kX@{B8 ziEjyP3?f5{b*NZz!-+-WG#exlJwBdoMMfzrVO6MRD~{}Sl3od$C~=K-X+{bFRHD-j z0~J#On2M>8aW*q%n6Rn9IFUg>mH=HC5E!_WLWM99HN&(IJ7Y@}(UOva<7+Ye6p6ZLp$b$A;&13s|c2*|MxHYeZFXKA+oN-_OA-iut-a zMYNt+<~iZ{JmcrjpYZv^BmT$#_#gPo=a2aG=@U+;ldH0I(<@BV)QSv;P1V`$o!o)C zkP>cAGUIg^?d-De9*mugx>!==w4k+Pedy&tGHclrKXOypt{5w&Gz|^enCzH`7QDdv z(IGiR%hX3SRPBzD^HEB{TYd}NxZ}f_d?D1bLW|?9wJ??lHhXz_!SBESj^BU(9bdkD z!BQ%S&41qWhY$GWm%rebzx)LsKmLq=|M!2#=g+_5*WZ4_$B#ebbUuT5YS-VlW$~ir zKmU%u|NZay#hC{^X@uUq~!aq7Vp$aa(9Rp zx7Pmo=buPo5G%d_m!I+R<3~)hj}Pjx-Yok!!Is?FYavEhnl+czpp6RE|IvoD7YkMk zW1k(gXKXOjP3Np9(cbD1#_OqeTJ~Lt6gKi}8MAx#qk(#V9TiBb3MIX1Fz?+J_jC{U zgr-#wwBPjKV_wwah(UL?efMa;{qxxiNvjL)o&$xG{1A_0do8x{?OwBX{eeLpL;nQg?gNBck->FgK>?N=7YB2_LCJ?wQKPW z4z5)&sw6rW{u!J+X~yCBaQ1#>PJqcfC1K}hc&B5@8JFuDu9uAE@(O77G)v96Mkv*? zPFV95N$4hax!N9c&d|Jo^on^R$V0-@!xMh_^o-yB`U`&f=>z_s|Km4&d_3X9!-SdL zX;C>Ez>Ji1C^DFAAnw&vxw6M6N8z(QuKi+gyBO9YBP`Kw$xM|XDt@GHECVkxHrUxH z$lMIGK|bw-oTy9_^){(_z|m-hwE~znq99;E$tdQ;)M9`|zKE(p%^fFTf)?L^wG=Ed z3ahEhNfJy8Uf(hHXqDJGM<7Z}nDNtD(2f--9 zqNAB6zt%lv*%8W>Myv({8CZZcF?3ESI@QEzV%`wp%&^ob%wRLqc#d^k(*Mo{HaVP$ zN?2kUq{JpMHcs@(eQrQ9=oaVZ`8(p zGTf%S2?Yl6R|`=F@cDgA_lg@ zgO^fz-!1L9AJp1sRZ~LWpZ|@grrXV}&hC9Fq9(NIPc$hd5P-L39ewbnU|9-YUS9C_ zy5QU84ePoNtp8oiSxc%1R+!xMh{`4j%_-~NJMKYzqu|N2+V zY?ztAnn57UBuKS&D!COIwS!S-++$bZ*h;!_BKB(gGJvo4C&+dp43-E&jA(7vyw_y( zrl(H$$-LS0b~D(c1XgX`pnQ9hv?~0BxBJbIvy)WS$gR!|3m%RltBe%aJ!CeNO!)fk zikEL!m;u*IX>JlPGJeO`uV1jP84Is?eE5K;C&zyO^4nkVZ-4!F{QS#ba6Uib^XJd_ z@Zp0e?&ciYiv^F5k2sx9(An_t@PNPk-up+vCu z*4EyHeD(U$qQho_gM5sB&D(c2m}S@9uwk6HiAr}HSk3yus4bw~I-Dd8ZiTvO_5|Ku z@Oh+7*mwEHj?4Qgtd#`39~;!4Qv=kt=QfURdK>r=Z^U+8rv1*rcdV`Lexh48#(pGp z)B))Qp*zaX@VH6`BkMIZjDE%M`91p%jSSf>`+ap_XlNXq(D*E5frW^*%I0|vZ-a|0 z!${yV4BI*Z+usjb3yQzA?lqHPKi&4)O0Z^wNu;t$MUb=qqEHCGH!k^6P}jZsfKu#s zR_USSM{oa1?W~tK6?*+91fmJrVKLp0${Qx5>tIA`8uh+%QC$E9)@|}zry^25)7*7BHn&Q(#7WIS zVRm`<%?4w;nKrd~HQ>&e;k}NLS1ZCw0MN8FW%>4gD%N%JMT5gB)Ctlk949_fZ6C8SXpW@xyP)VHBj(c?Srvc$!^bSIFISXcJbe1=Gk*K+H~jMRUn0y*@bTj_ ze){DzKK=X?o<2OGSi$*W!qd|e9v&WWxm>J z`x(+ZZqg9FJe9x)r@CSn8%b zhBfZTMRjx|p;gg40daMY=RN|nAB9xmrXC0BnWXq0+&1;*{0TRizm~kAqp`B%g$rwKAiVYj&{|}8QgU&?6lF6MFed^VQc8wIZdcU~HxQjE zXrso4J+&Rs2Mt6Qzu_`bFLT-2h(ra@32=U%nI(fISP?^Ebq)rXl9_1bme6@C{`{VE z+Uod{l}?lFDm)dU^76ob1*z8 zjhRnTV2BqP%pyYINYPMjN?Pi8-WK^JEKFw2$JQ4D)LEgJ=wEo1dss}psGB}x_wTuM ziJjZY$t&ZUVyRfQH06AMVLv{4RQTiLV{3uGyu2VsFjtBc!diqpoSduC$bo#u>FjB) zpFcd}!^a2w{P7vT{PGDueS8|aF#g#5=Q8cPBcq_|RxwU@Rovs>*G@u(iA{%X&<*{p zTMFv_^w%Ii-J)Od#|Njy{(Y(+?ZjDC@{C;qrwalrTx<(CD-PX{+r!)6)agoMVV5np z=6YGM<}31QSgt_MimzW^@%s9T%eu5A-nt=8Q^NVvC;ar&Px$=#vj>>Pe}DY=5mRzX z>pZ!_eOVU#{`>FvumAi9UM}8&c>K>3{^LLX1OM&cJ%a>F`18*{@wdPI4S)ap-#7ZK z5T2i(TRzFRZ)rEHW~9jl!In!4pRIeRus@%dmlv?EP#E&%74!Ks@+si~XYj;e(&%Vd zY?3ucI8U6LSxtMGya;n92ufy8A zKaL<*{h#@OA#v>1Ip#s^$+>$1>Lx_BLw8E$l+c~7OMa)wut3cAPM?v7azEdsX-Rg( z;4M9Qcg^fGSl-d9>^mmoYozVFRJYY$w5#DJh-?#(5SSGrXms7}dFrrF?Dkh08B?u8 zkvmO-?EYN;TSBMUg3`<^sj9$=7#RaWe8i2z!U;x;cdO5ELVuGc%B6_ z64@ zXg8RtN5yB4u6I*H6ec3DBq%}7Gc#O^-Gm?2bW4Eork739G?XHKv%gK9qk|X;+;|v9 z24qDcY!+hF3oJXek1K4+kgY&1LrGoO1;ccjq1P*NUK^RRX2H}fnWl46M$_w%=PXRq z3D;s+^XhC0cp@v!48n|QWn2`|p?Jf~YsR`7lx8r^__}6X3gg>r#_NlVbcqs9rzgni z44qGqrziaM+rQzz|HpsemtTLyhmW6K;7Kzc9-m?A+RiN&n~H{*M3q|Ng)6_3KwWK0e~-pMS;2j~`J`04Yf4 zXPiy2d9h>w6*Wg)1xdCPi1_uDjFIf*T`L3Fa*R#9BbH9iOkqla(4V)WqL8PpnlyXqYT6hZ{`jk2 zLBPU*WpGN6B%vY7P%Z900^CU!0#XqHrW8e)cNJ?VB{6}DVa>t1u+X%ZH{b9)-(b`v zn7J!0_7_uwARbrU!~k&WN1`%3pP-D_fXn_!9G$$kNCw{WS_mmnrKw9K#R%kz|DLLY zt&SICe8q8?(ztIbo2EpOo@>f*JV0WCp`d8?5JPqw{kmSEMq#T@El-5Zc`gq^OANU>cz?U}-YnZ%+< zAk3n8T^1{4g$jc$L1yA)Vw@DKz8E5#C=~@!A!Y(47}&6sg^Z0@jex{JDMXThtbp;= z3fPz!#D+q|V1bI!lH9IZ5@QylNvJS`3QGbDPb5$xtp18vjB6}G8KePp%DTxZk~z*& zBCgEL2uXLjB^!69UQp?Kwv>Ze+aUh*MnMasYGef3POgmGG`Q4NUFkrRQC%ey5hcJ* zL^Q!RKX5ooW@eW9=WY)ngcf5;iGk$cFI1;X5({_9WxX^4sbA}4~TVc|kdvEIaWmQJX1|^1MZFwd&^P##(_VZlh1Y*O96Ry{*w*|>N8IKQ< zqIo*|e?R;8Je?*yJUrm}amLeAWR#pF;8fJbv)iFCMfEo5X;kTRo2B;xtdtJC_d8ti zzw)cs!i*;|I;02g+vj`oqi-mky8vUSL(+(qZVsLpgOz2$Qh@8S;*t%kIlRlrH@mBF zbN6@}>VnH9V<}e{{h8N&M@yqd#vy&zGdG+b8{rKZvj>;&g z)|R3xMO>Utrwc|j0;^r+0w9;qyoufUk20!o`+JQ#r zi0r#xKPoYlAY-S=^tjX0b=-_WPRplT#tC!i)1$~E*}4EOhg64Rx@Mz+B7M+MSs7p> z@*p*1GfN>9O{63Q6_g@ooQOq0nv7HkDr6?%Qt{98p5svmV{>A@Px*ZJ7c*00J643Y zpJex8TOnSF&=HQj_NXyTsU_6;Wy>BYO36opjt`GnlF(LMOuYa!KwCm;N<0M07SU z%|(PoM0gh)-zc6rX9?&QnUxTqck@o(qT8KN;L$POp}2*OQD3*k&5}*WFs$>P~q~ z_wXlcuqWKWZWvo4B4GlH0w`FEMRo<_v?Q$S-m|>Vwput5j z&oiFR4|sfhz{Bb6xbP=0KF;SEPp2~;9%nqBC#0#i3Tu&3;U<-o=*3i`(f(FU#q09wow)PlBR!d;6d()# zUXi?I7xl}#jnBFCFhEPewQ>8UCoox+4vang*o12=fuQQ*ZP0LV1h5&EXh_C=R?z2S zeAj|XT1OQWhLro5_9OiN(WtAAi^iQb)+3IBhFs`eBEzRT)|lh4XJuT6_JrZ~qsTZe z?3CEFWcBp!6b?u$HHKD*$u;a;6Tk;~f)^VEGphC+QOiUSLLpHt;u!`k%qm8jKzRa0 zN?~DACe2I`X3V{?lwWYooiwc~GF!=|iC?Y1;GNvj1yZ$|OtPD&k!Aww8VdjP}BH`*w zE+Me7+7}G#s+m&PrD#XvO;vrHmPqQ*Evs|<;siu09_3znMpg_O_~DE^%pj8_2+!c+ z!8=PFwV-8cQfn%$ROwl2gx?~+vKlNT2c6947}$b1r{L^n5J z)nkxh@Yb);$(>g{=^gg&caT~}PLD=wE;Tnn%mA!p#aF1TKu=K1>iiq}hq7V=p4Xzy1#Ywcou z`0$}=F=`j1YH&&^$gu&uy)BLE`SS9DC2Y>M$bETvf!Qm*efx&%WsS{a9mJCxi^W|h zYYhZM+Qwn*;#Qf_Hqe|Gu;mcSS)<&p>k8t6KmN$D^@``G6A~0mXYixAV79$SUO;yE~3k#(N2y?3Q3^14k)zcBINi5Dy>KNO#9% zq3x(BE@KZbXJ%Fw|Jrzcgore%j^wqLtre@#b@?SiMXw?Jl*louc_zus)_#wUkJ9bk zrPEY;5n}(6PNQBQl)9p2KQf_1Pf~pp&Bq)eC02je5PDkOr0YL3)Yy@R5GIHjl8qgV zZA@a@7=;Z9L^CrbuMRi`Dts0ZA|f#+hOiK`kgymLJ0ESs?DwOa*mlUGYvGK+;C*gR zgLd>L-A)=7Lar8&0rl>JmL1b!0T$N<7*?pcP*KdYDpb{>RFSXE<|l|0B6_f4c5)n` z3_A%-1;SeakV}T?ih?V0xdQ7Id0pML0!2!UbDD5I8y+7CA08QxkBrlaF-?r;=Vwea zb$Z=!m>IcsN&Ph5Cs6uEWP^JDxTEoX z$2Md9`r8F)hcS-7&!LT}a4c$zxEBS|iP6SlrH<3AwXL-fiW+h@T#Kit&ZNi+6m^!w zqKak7c)Mg=uNhyi3RM@#t*c>KoRGO@g%*NhZ5tB_W1a<%&ky+Y(+7P1`4c{U_=pcr z&d8_;X&9XAQGn}u!MB%J{Qmpz_~$?WiLZbDj<=VuST2`VOyuPXEuLMIEl%%NAPkhe zL@`o>p)w54s~{p25OTPyB=k2_ABQAduLcxroC%G4Y}Ep~W_(kFtt%cLCy-^p9>MmE zL>V&q+NQRhkPEF?*97JQfH6e@wjslhA#g6F_Cl~08T(PoQBiq|u%`{SL}4LwRoal^ zi*TnT>V%%OVfSlCFz4Jcahry|bxLmn1ZkgI%mWy#x-lv)yLJp~xL!}XB_deubP%;- zwlZkkB|$fH65FDj+V`nONQq8>!EbhLMagDEv+ka*Fs*$$Y%Maj=YQOt>V>WEq0-;8 z_zvH*f0l<7QXXF4?PqFp+lTTod8lc2pia;-G-?7CL>!wDyZ0Nvx%S!n+Wgr#IB>!iijQB0$mLi|7PDUHqxCj zNwcqv?Y8a!TJH(07*G5GtQr6iLGQlx7_1h;Pw!+%bWx=1Vx$9i$%IH#b%%#{FhYls zV)2-QB$k4lhN$Ec09x0T;j9g+)+HiVQxyP|Dc1#r84O9ZDYi{VXv}W&x@(W>F3#)- zS*UrD!CcYUL6Vd%rL_2B%A{>}?5{ty*02Id$(qN0T`@p#GFj7Yh>@Rqrx}lrXFNVW z;_3X*l3P7p6_{qmX-Xb4#@cQ&x_MqV^EQVk9lRc!&;I!Ib=1ndp*sEup_8^ErvE;w z_T4t@p02pxTuLdBbUfSdPx%`rgHejp5_9(K63~JS_W1XM@BjMx22~%+kJ zZ8O)nf4s{;gYXcIz)(EQ2C)e#Mdx8Rv#+oF<)ZB| zk13&>4YG|zLf~r$@8fnIjMvHadL0XA*?0@89t3!=MSs+(tHlY!4vDu%7Tj?Y9qE(x z-+SWdVHEno&$@MR+^%K%9hb+RW=cD*Q#;|`SszmfxA!ow_Yzp|%>EBMDDQP+j{dyC z7wu3pxBq^%xFy)#gJleo`av4_S-xRfJ-g{W;%khMl_G zJt_4>?Ya!EE#Bgc2`3dHG#h9XNv7hbd{by9h)E!243-UvvcG#$z{vxkiU2uV6XF#% zECkHL(DRmBIg|K!WSa5taKia~#%Z2?qo{s#T9FbXB|um~s6w(8R-ETSrk*$&*x-Kd zm=ZVCw}Uu2@T3V~X|I!_ioG`9ySGo>6~ZKu)VsCF{bb1RFD~^UW_%dw-4@?FSojKa zsvAk`uqfTN4fY>PUWbC9sG(RbBndBX3ydceBV;3(P7dW#!m5m-f^{)0p}koPK_T8& z7HPhJN&=ZCJe*H1+*7mxK_k^JP^`*hzD#}4AbS$#7%m&C!BDuAl+1~(-e)(&$qb^C@98Hm+DB@VJmW~+iSY01Q(n6eRx5=tpd1zY){ zM1)L=WXLOs#OE+Ho0b(|G0SXBqM9dDTBAo^4!RjQ&}H0_{(k>g!hQC5|0dCaAfr_~ z9r2TftoxDnDWT2qs%mtU$X<&P|9yfduQv92h(RTwHWK=dxzl5Kf@(aDbzKw8YJ0)~ zthQZ*EKJ%6Q1$VL7NvN2*$)YmzLN+@->IhS!sTMA0u3Q&PYV2_+YH&SCFjW&~>%MeFz8Ht8{?a>V@Z0Y(%$fkrPR-UU8U^V$1CPdChi zBLQ9?kNrchKknr-jGd_cjZ=T$qPsC{9(&!5VeEbktPrE!=Nn#MuYk-j5@ayebwj#u zr_jpd*n^iMhz{O{PAN4lMrC6(;wdUc(!ZAnm@!^nURoF9%aprUxm0w z`52WPYgR&YarWyaTtTzgkQ%&Slv)IPCwdeKT}4>kGy~VG+fiR1UU9uXU_AkTBB z=<4zCe&77uHoGrvncAEIM@7bQ*Q|$9^(WZAeO@^UcO42p=zMrjSFmXnzPDi>|NJ#9 zv|G5@?Ko)E5sYrQ1~a?E-{?EtJtt@Xde!1%&%#*q<;I0Jh;@q|>bguT{gv*%=0_Tr z{f2q8f$q5=N3U0XtZMn)L2h&@5L=Tq_vHqK2oQOrczO>##w?{2A|g{IsQ(|UDxd+s z^nFguY%w!7Rf81}F`L^Ag~`OKn?yB5CJGbO_59-p?H+$kDYtGkvVRWmX*wyDveq^g z^!7oup%xGt;fsDnLV zg+QcuI6Z*a)y|hoc7b8#vqa=D#fEvBTyyc^dBQ~AshCl~C>}i@t3MvfM5mLQ=0$3o9PGiHaPfC33X_^kdJCl^0H-TL z$aEJ<#se}O@fu`P3|p#JT?>T9V(x-48Eft;fgLDJw170RWmxU3iN97l3= zKe9?G!9ZB9o@HeKsTMO^pjIeNYMK?G!Uh-lv3RqLh0r-m+7_&;T1r7#VWk)et^$z) z%q+}_nMGJUja8LZGdmGG2@@q@k%>i8N}Oa$*Ja5mF^Pwa-A1S&v8E?KPG6 z!CYo$iTW^ycU&ajm)^BExaVOoaZ6tnFE;8t=q71(!mS82RSw1urz&A(kCNPdSm1Kplf`k&d)j*qbDO)G*eZ>5xiwFKMZx&jvWyCp13c3nm>tfgRC z39C5_>bfYd*DEfI2cT(j0dMVYl;RyBBJIeP{`)jdIGs*SQ`1vPtA@hiZ2lPE-rgD) zqtZfM_c4xx*40y9nRDZIRBLF{76ITZH~hGZJL!grvY%NaIuQw_aW%a27CHxA!Dg7I za??3DvL#mcffuD1NSgP?W!|miL*d`(Sm2?%wx@#bvrzV{$o@WI<|Z27YbHbl8OO-* z?`buTIxp4T(*gu{g6ba;Mc%vaYk>m7?!LCWU;AEXVG~jxyU$wTm&>8HgSs%HBlg92 z1>?K!#yxGF^Z|%>+-2YS-p#&B)YjrwDXFUU+6E6XV=$w{b7tErDQdby5oYEZm{z+P zIXV>nZG3O6OsT5TsCta4bC@LT#wK+lfh{kEfDr`Vb-<3I;oJS6nwhAReOSjQ-~)6< z|NFLGtA_wq!HA9EE%kAUn8W%fFij!;WB_80eGu{ky$e18i6VpJ%-k@k%&g2j)xa|& za`exJji3fg(W-JbGBt)VYgo&<1LCu7bAh2-L1QJNW+>!da2A3XA}Fg9imJi+j(InO z3a@vh98xJD)dmkD5Y*P7hi0VHT$MJMNRh&jl!%dqLB+$(>MR|)Wu?^mA(=uzU@8zW zlBBIYDY-)*tIzedKxqjs007ExA3kbUT(2wE>`s*I^ILZO%V#smYTN1Qhn`9eg3-B#Kp#w-+4d#;^gj09Q)_5H$`&I zE~zdZB0!7!c$;pG0ltecOrwLvbtIkPye2hwAC=hWivbxdKFr^wH$=uTNmPrAI(kV& zw7NDx9Tux4p-^^O9kaJWmfc2V%9`?ZGBdHQ0O_+!=I-xObTax5$EL}M){y$ooWhdG2*qyq zxOh|MYP;iI9tA$Q%A#CzH_E+!&b!Q;_SV&g);iDop-f>`wnYCCQ;UaDSqr+J04kz6)P(ij$lbP>#gTx$#Ldybz&o zp4&Jht72UZ*LA_VmO!yfJg<=nP)VOPd#1nUYLQV9^UJa}2FB~_E8gDTnj@p{7BuZe z@h%8cYHk0$=Ar)gx~_P8Ge?{^Hb`!-{r)8DSv>4%zNduKsZv5c&mn;zQ^MmcczkpQ zNbS~4Q@R;h5G4qQqeSve*I{7S?1~Gn7R}1R;G>S)hUuQd{jeP-?NhM`^mZ#TgxHZ`$v$;q_{tW5?v<8?YIU(_ZPF zwcto!anC{Wo-1YO+*V61Q#(}cH61m3=(gjFo|R#ZCTF zC5Ns~hI63^v}Tu-($ZLkoWE8~VS+Xr76QNpV1e+m;gZEqx+nMop5QK!8o)M1w<1;h zMSMRF?mv|r{Fk?#m9w-Hqm%X2zb{$iTUZSbAjQ#8F8W$f0+LK1Ofh$k%s^1&6EG|< zhxV`|kk=l>({nb^1ySv%V7(}JKL$G*-C(E9*<3{4qRTnAw!h{D#Fa4MIVjg;|=hK7_PYEABJ>u!(BOafhaDJFEodk&l zoTTw3yjV`4SiJidJg7!}g=lB%Y=p;m^P^;y$-9Oy!$2hWqJ3?+v)y-P9U^Hl1>g(S?h3Ha}`vV)l-=(^DXx`S5 zG^S+3M{!M1Z6($eiT7j^N;|-Fz4^ZTf|Hrsbq2elXaR8nG!sj0(2~^xOBxe{NJLcp zS7v55W-yC7Rf$b}G)r?Oe6a=sBXV zYa3ETFeMjJZam;vNOhc9u4UOh_Id&tGd#9JK!#}Ko|xAP1(GoIa1)vJ3r92iMmMJ? zp6*XE``7iR*hsr}=&s|^ij{j~8H}ls)MoqAUQZt*>CjepX2k?vwm&;fGI`zsiQ9NZ zz!AbG;*V-0U)Ed>?ZT}RU@3GK+s{iWHGM>Nd@Rd?hx4h+dr;(Dnl58mT=4nw@`AUw zHy2E@+$_BH8q1v%0YvTnsV8dhfY8ACu*KnUY1dh)?*%jCbV~T}@fjZ;W}Ih-_m@&& zSh0}eVHSLNe#Fn8&iMS(6Fz@BwRS^h$xQcJYg5M7<(R-?ZvJ&L7Y9xmDsMxFvKNbg;+MhA}s~OXhs1R)}$l9&<2;GwFD39u*d@NoYfR z=GIA2F=J6!GVfeW@i~(h3Kmb?CJpR4Xk+G+sh@76W6_TyL>OY^84;n<_8ZxvJ5jS0mWX_}cFOOu z%+oXhWCQNEFEWU95X||kKp^4U=bGk7TP}c^_-LVG5>_RMkaI35 z!5El}K$@JW-{cZ_nqVp$qP~($(*$Ed$%b_)?m#)yn4_YKyarx-&B)8@(eY&yawcNT zlG>TaUAiBLL0GB+4lbV$PSG0!uepP%vh;}fPyP}B<~ zTM5F3=Z6_T{rnNXeEx`^e|o^Dr!$@(7^g&-k|G(w)%IRw_;WoLKT;Q^UJJB+{CEW? z)y=WTqW2Dr-bGa13|qkv<3wUGP22UO@%a{l(iYYxXz2vC5eOHBjh%;j4eL-dQyY2K zPT3~J9LE*gGVPt(ZVuBG6Rk+kW05AjjXzzpQ@c_vn0o_S3}zS_THW>fsyR9!_2eTF zKjS!rlC*2E+!PYGLiu}Q*dqb^tw7b?BW$~1yZvEhr{AgBGn+5EI(dpm z8kFp?t$M&H+@NYi+Y3nqs`p|`l6IwM)gOA{Kwe`QQ6?f%EkZ;Z&qd%F=&Y&}L33A7 z_#vK@&5BqdHd9j3iksL&xoBT71it)7BHwAx$+-Ik2dDD)IvBiTXY8}?x$9KS(TSK2 zx)?P@wL-d5=Q5EB-Ky1_lW!??ejkdPkHaHRL2R+j{4%_7KTMVTQC0E&V&3M#3}%CL zU8WkabAv7J6zKg4YX4YjC!qJjx9~!x2zMYuS*meYgm+9wh7A6**Tp~u8B!N zDWTa=MzKiKT?$fCCs$GegFV(c#x4HdS!{9wNeNoExq2>nqglp=S1FwRNB^F+9FJ0l z6K`)3uA4v|2@vYIjGF6WU01Mh+tfXg*BbvMr4-JQG(5)2FtAc^KF>IX1@*&+511yw zn%(wS$P0+a$1|RvpYh?t2RuKY@$`7Yc{WUJt;nDXUDE3A(XrD)TQ*4FQ4#r03!Q1l zZa8M(?Ek)LCnSMs6H=qx>IMiS|Al+9WOpC#wHHTjD&A-P9CT5Scoz3g^!s~iPwd>> zC0j>h_&K`Gn2&T2HI^PkkXkVN;JOK~`%dBhEPKQt*+0i4P+ouCAFUVLI;rFH)bWrt zPqJGd$H%}O>9f9mt!p*#$Ew4meXaE!^&mVMySKzR9uTKgd`c4024lC7jLjTfz~P>3 zNv%v!A+GqS2quk!qNcZ^@~gJJTB@G*pu17`C_1)S-PQFxoF@P50#a2vOlCH-Ej9FPGGGEp zGG-B;5{pP-5oRV$^CZ*6#1j#7wPQ(`iB}4$Mk$%4l08)KF0H@%b@W8`0{E%oVK{sj{k6^#=<;GzSx;bH_BU{6owv6%@cI;+koZ0bTu@tLGUI5hj{I$t(VAp8QhH z-Yw{}2x1p>@~U5OjqlMG#$^+jOX=Srl(ehGqrLKr-=B#=2m!3s!nXkt@ncaV-ln45xVp zon{~t#27Od(7IwRj4xj<5P8GH`57NF;kqhbFDvNlKSNmQmS*FEVv1rJxfn<$O!G75 z^Ea%;XY8kk$HqUnmTy>=1#fR}D8v!&w!*}4dO9Jmei|3lvCwHizb68$T%m|!NP%1m zn1P4K36GC6K7M+@$4@6rPXv?&d3^=R74lF((}MG_AMx?$2b|AtjXjA#6wsw$etd|| zglBfPfa-Hh$=9zj^Y$)UXVCXk%k1f}#kP(Wq9a1axawA*i%4@fw4z|mTfkX-4x$*z zW`NBoF=cG+eo9bwt$WD@g$Pnl`aJohy9$pB4I{I5T}xQpbN05dgglK94zvo5s~v`^ z0-pi%)Mfy9JUzzuw?^gNBFup~&4-cdt)toD`kTGIgYVhYb--!Mc$(tyRQWqXjKYrB zCSo{xS&-JH?QI5b9V#ur3WExT)j9dSsTd3G$K-%K%Ah10kvR6TsMkF!CdNRGR?3V_ z3{z?D6%neUJirXsl958ym!!a$k;?_^>UQw-c=q>`w}R3)Bn3pV+BFETu6yFNAk7OD zE0Gj4O!f7yg$N-8p4B4mm#SGIe>a#3rzuHFNi#!KwM;3|S_;EdCM3?LG*96r6d_`! ztSVSnHWdaF8w#^!n5~ozq{K|Z7I9z%BNAhXcR<`QBj%jah@YT^-*cQ00HlpzwzWj= zRK54wD75QV^s^s{N=Yg|y^1+2p;J32Nkx#yzfYa+qS8L4`}cj?D}7H#;=&f{E50B0 zjpL3DYVfGHYO{<0q1X}#{o1R$_s@3>r#f)=?9}zld=~@0Ur0SaBabKB9mfEbHDaaFIqUUM z)#VO4v*_6HmN3*_7eh)Ep~{N9niE;G;fV=M6P8?%WcGG4T*oja!t3iR)+G?;Q4F}w z!lTYlCvJA%3V*8bv>tGFKA*!aaf+;y2k$1lUIv{@Db~oLs){6N`j8`jLPiSwm zdY)!{{P+=1Pfrc7mVKJm->+th=*D0J&r@?}{X-jUI8nsi?k8RpmsJc09>`)-WBKHAn z9Gy#P&Q!Z$`}hkWcLk%Zpt2I{OmxsX=S-#ca>q#;iOCLNtNUv0XvFJB)0B{N)><@$ z)1;)7jG3+Yec1|-t^>lVD)9Iyy0Zszr^TQHz2heGv}U2GnvObj1KpTLepmn+!q0kx z#JAIKrVOS%|$ zHZx&2SEpgF)V*k;_0Np)#U6_gGkw1suQwv@y>#X>K_Ir#Td9TYmgj~1^< z_2IX6v2AT(5ovskT4dA?NyDClkS2z4f~u#^*5@E1NTQgd`ys|ivn$irvU)dV7EC-A1|wrQx3AB*!9a4UzHkwzGcopo^+ZC8bReO4w||mFU@o=kfOzIVZ%^ z?rCi9lb{#XSF(AT{AS`VSh3qmeBh1JD|m(X%pqsZ_gz zVc=ack$O2p9Ntr4$vJYxnA;SOw!VVhYBLUsiuV{AmbQ6*+mk64sCy(&^gN6MT}BV~ zNX#tpL{g|&duwXn?MT(hx%-@EW9?|4^@YM6p^6;bezjt&HC86C6cyI5l z)-1WJN!eaM8gdPqz^$J4x=p)xg^b;ty6fchSBe*3@wjM&Gu6jg z6G!Wboa<&gFhcx3_xDqg0+uxKgqa-5lS=_0czY#iVPrLw;!)AejOld7!})__jp^DR z^W}1hJd%gFR^A-Oc6x}#YD*sFNY<^)iR-nrR8}p~^+{XTDT18hy{dTi)I_OO<57!@ z{vN5D-*obX*pDBd@$vBqzx?tG5*6fp#r1l{x~@n`@ZrM;eERf+4?mr7I!(j-$uv3) zsxzc*7O+;gP7~kQoCi(BE(@bQ{+h|da&z7G_t^4wIn-IvmJoKMo!Fmbk9ZI5z)&`e z^*$B0C$1jpy{dNTsM=_oxozLS$92Ew#^{BpeH41{zGxkd9Y(wza&Cm#XouNBj462s z!W(%fMEg`%zIFG#ql;^g-^SOuKF)GrdGEish{S=c>c{+}31k&FVp1=L18r_TCaKqA z{k+;iT9<4@L@A{%p6tV6MI0dx2DPxZ?#3A+i7Od%w~gVMWF}ml;G8L2iJeTvg9t5m*QVOSPO;`(t!VN)?k?1CW3^ zh}RdGmB^U@o6NnHgwFFUjh$u4zf_0r?s`%&i3z$}rUSX?2X@amK@dM@r ze0+NJBE=S5uUEhpTrXeo_Kh)dhS?dX(+Os@fuq!4Hzvl@`3brZmZt@l4R6ajjM<9D z1|FhhaIPtmAme~$3Fd^IjW{CL!+m3pFZQ`;}d2kta-)d?G4wr3mA&$ z$0z*dr=RijFCX#oXJ5o;0O#|J52qO?NkCaZMI%v^wiz`?u1;OAXldhvdg8TeEk#Xz z_1v5WS>g>wMlv66PW9hU53-pldc8thEjNoLg+r|d?76#SFkK7>00JP>`KB{bGl(j{ z?r1byA793vV>DV)IoutMD9kb-x{LK_?|O3I973GtJEHbVI?dR1x*J!+%#h|&dp=d0 zQC%{=POaUzPh-R!q*%hBA*t(BJ-GONFT27kx-8AnS6>bdyK+G0Vn?XYpR6L_+1Ji! z*)uz)$Xz7t>lnw^lWUy(kio4Gso2g0f@SqFdW`(4cySw%mu@+;&UNA$jcE!@E3{Oi zHnSM95fRnK_`W$`yZ&qMv<#U6cOQxUVj>>B&}>BkQz9i4z?kgavGzM-6H0CV-yAc( zmzRx9MsYz?S3R}1iXFR0>hIMZA|NDYPB0TyovS{B*vBQ&RY(=K6<^mwxN4z6-DAP7 zQoHGFMC?8HOpH+f;a|~Y^#1H4y+RvB?9v7a;z(Lbpkj_8R~JZ86c+s=vrn{~=XqFM zdRpU=TcW0@Hob+7k9&jL#7T(L4#q<_8i)EbdyYo!x|BQRS#>!aotTbN4mVNW*g+7H zciku3^RY4QwwrS|1}$(`W!}0cZJd&uYW&C^S4U3uQDE zRm}5@)5(U>SSgC)LC+|~gTPXnFwaiGBqEgTfpsr0FR_{V%sq9R!B%8!^Xh5x?~`pz zl5DtSI^JZrnLh0(p=IYjAe>GoJU>6<)2B~(etyPzK6z%!@`~%lI|9$o&-mq+pYh8t zzu?nPPk8=FxLhufQgA+>@%V7YMC^LuH3KnDxal&)uzk&!8?DHYLRxa??BW{@ku;*` z=uEij9x&ZJUm`+TbA<4db7S`F%)Zm|y>n!{Z$ER2B44L+H+l|6El&G!PJ4ahzOMmy6|QDRgWKoE(b8VGSi4&0&^|Um zyMVMnoU3-@8oOEZk2oaz^=a56x^CR271MTTXJ$K}&y{Oab4(y2lv481$fnh??&s4^ zB++*)>Lj4-HH+~+_7i|Wjc)s@Rb6JK&lzgk>!BNSmlbqpTtWsjb-lG$`kumJ!{*g+ znsG)BCmV4I%}e0viE43S5X6T=vRvG0L_)-3P>z7Mh7^wi!|kg6;H8Q`yRiv%g$x2o zmiGNZpWcG&>QExWyKzxQyt$FYc|lj5LY(FG)>SNZC^({K_euAlO3beG$*givI0z6 zlX`GUge<_*nQ@(fuarTQk>I%u<@yavq}b{T2v(d@q-N?B>!P?&MoPZ1ou?Uz040VN z3gW1t>1i7xrYev>3I%{kqA);_!gBE#!`s|DG05-=7SsPO?MItkVF5yE1Vdgj}U&(px+sf1KDb3I43 z!0Hq#5bIvg`u;I;>+Et{FRRAJ+#(d6vH-cU2WdIJ$^3D10jaOs!T?d(ejcr3cpn4` zjo?E+XwB^Fqd)I0!-h#PO%CPi4l-33YAzhM2G$Z06A_F5_9lSap|q1L*sl2KjS-Bx z&)2bwjZz1{OFUxDDIFVXHafYatU=wzUb;UJUb4i`gq!c5+2EfNtX z?@rXtM&n;hs@fbQA$k!4$xgshOF-@_GC6oWM-^4i#jw6I`~T-x-53j%flUFk8!UOf z0b8gGby3hE_}n{2`eI_F5^mLVzSAw(G!EN@=!oCJJ$z>VrvhS9#9A{7LPcD7u=g0-qi&eJ(D;&N3!WYx02HJ-GFc|U<8%UB#=5weZcY=fjf1hr!*A}8 zD)2o@T0PQP+=8~SX*6~P!=_c~j#%CO-Dk-39nY2`%o{oONCR=BdBAOs(R%@4KXOFc z2mcM4Dbt%yPOp)YDcy`{j$AGqH=>d|^=8ali>+}iN$=_^T0mLrevFPAshLepSgM0C zeOZ=aJkqz6Jd3Ct2jTU9u1pjLl2GI6I8S3ebjjqLf$VM+uokLvaFkd;xrm5Z{TDN2$nLzyt?EZ1y%4lIOK3L@*pO2LXNW?}2#pSu_(1txmr3GU zNUA||rrh*{gelGKRCmo+uUn%KaAyfPJEWf|^b-I?3ki`$&PXjbYEi&50fIym0kT{d zVrCMLu1%eVW@7(ELFb&pwo`33b+TW@-Fq7?%nX ztut#krT>0eGN9hSXn|nGKxxJ#g1lUu_Q(?`D~t+?nnO>SP`lh3wyh*GT0x`bR|^pi z7sm!*+D;zcL5UdbX$GeWd0Dqjw$TT>ja+Jjms{wI7o8Q`%_wHbS(^)`28LM#w7K~r zcP$11^W2157J7^56ap3t78B6}5k=Jp3dy{C(eevQg)VAhA zPZzWLhQ6BKw5!L^vk>T7X(NYea>{BCFI(0XIlD%ulmeOYx5S-4Z*1GiTX+o-r#UUv5PSmbbQ(`Pfow1ApywS6sWj(RpbHl+uwjiLquIG#Avm zfZ}Tq5kT>rn{#CAMEF>LI~19g(1Q8l=zKoM>#qaX3fcNt-11X5jjGA`vGlUbKtC>ZFL3@#kzQGlIu#`Su|%gYM@;Nbz_^QPlDpU)66CbzKb^&0>7<6|=STeX`5B)-e|8qe^D`t_ zz?(KIDRmhw90h*OQt3Nr5|FCax!~K>-HozIw>*ghQsjH@*^PdO-tQFfF8cy>>$vKF z)suR=-`m&P9q!He^||Y!zBlH*ms-j@cgVg|(sL^M=kX(b;CqDKqi#VXiqe>=auXlW z0@SD#JN^5)byfK;A7xMO{8u{H_x}6d>+giuF$=}aOjXHt&Wgw|>0gIl$eH7CZM6^y zwE*pGt1Cvl_uwk&j1?W;!FpZ>cG||HKmQ0Hqn!m4`Qk|+9!#>ety9IHAzkzx-$3M= z3fAaUFj$P@&8?M&(8-M7(H3z$e+J&JdiVpFBJ&}0zi zlyORehuOOx6EU8j&-nQ13BUdFjGsQ7@Nfn|1)2+rE|6MeMCM}>hOxVtE_nqdhGrMV zdf(bVEQjVO^^Pb{)eK=zWXMEHED^{g^g*d<&Ja!-?K%t8h38e?gxwj$Husvv9Nr?h zDOe3H@?t>uY=L5&q&Z1?5T1u*daCn#Fdybp2j&+~p;oar(YEmhb_{p-`HATIQ5Jx8Eeq~4O}fFPVd8f!(#eqCsvW1TiR`P+XM-UY>G8Rk)w}mpqS!2ofzg_Q7ThtT*|hlk^sC^RC06kfxTk^ z5=e6h`Kqey*Pw%=6&m0q*H3j$n&zN%RB{v>>~@cOkhZGD;BK?modLoQ3XD4T5LImp zxp!&W=Mkw@v>a(fTOAY_`aNd};Ka{po7iA)*62rej*JFSh$Ph^8Wv*^OV7ASIG})b z&XE&43961p8WA-9d#Kdv3skEvnVLI-nw71q#(a}t=pF6Cj|x6-3k~c@ecm#2JEM<7 z7~JMjmREpd4ADP^gAT($P}~tQ_opwe0X=k^Mq1VF!^xy04Bm`64vMH-KF6N7q2I|) z7(qVXD%E#A`eR7imcg*6A5v@W+YQHKU=a*i5xB{BsT+8018({ZfmDlbULwyUKKJIt z=UNM+E}W{(>;uVG(_7Qj{{1?;E@M6~xIPqImx9Yf#_3_j^-}Qpr?quimSw?mdBx>& z!MaB1*)##>kMVlF2KxJqX`V4n578Z9%<~*$jh`SQ5#cU?d2#XZcnW<;eQag7+329h zs21P6Rzjl}#;4N>AD%zp`S}Tt^9c_R6V4CL>S!7W+Jv;!RQ{#S^y}y>=R6QO`-1QG z)J=yPAPmjt4%U@^efeG&;ij{aQnOSar7Uln7Q+$Np-++R zHD>!!`8`d{5mELCn%MPzhHgd8-0Hg+eSuINokXr==+-~#*a~}Rp4VIPF{ZeuG+6)KXFsQ>}tP#E=b=t9I$Bar&j)WQ)N%KO3r2e7TK;NWg_ zGKXrmMz*Kuo+M$ZL1@xxEXZKgp{B{GcxR&$kYF3JEJ)=SSO`!|}qqNqC#A$8J1)rX0{QUD1e*WpR3qY}AB8Bh@TNh+?ie*Y(aFuJF zp~q&IHbE%`k=57_6N6UC2tpE9edqil@@^tI=#Wf7NM2lHicUr>DdgETy=#N+ZQ}L) z)*baXg6%d=#c1U;+rgfQhGHtmSi7ddqRU{_=)fHcE#qEVH6L1A>;ER1hH+9${*A|< z%M!1ZRJG*6NTm~Dw|`fd6?d=nYg0{Swy>aT=-sL_t#u;o#uAL^L8^tT&g$J{o8Y%g z3pO)Qs`TD^5XoN1bj1-IHNE*>>iD=TDnJ5|uZyDf^IS-*j1ZJEO02OiV5OV!vqa~n zCfBCK-q~o^kNTr$Hz25~_0YwN5Fci<;S?dF(p^mD0NK#X7WR0DdN6PMXJ}-Ys0F0) zF510zFdE>i*UjRV`gz#VsP2;3hm15j1YuRIWUv@d`242f!^dp;eR0v_!c+ITb6;gu zCPr;zbd?*|4o7?su0=+?5TdHkrNnzG+-VD_&k@+q^y=UIpEykRC;Ud}R1FiaAZ)>4 zb7if;(@fP|NJU|BswdsPny)SE!KQjZGHmMa4M`j7dW`MY+mkS;rAMx;T!o$M@-d-QD zEDK(_T1`uII6S-L?d=W1C&!)b~$U6wjazV}+udm-i za5|pOs(SzN;bRmTg7f)|Pai(w<46B^e0)UFE2u0n-pRY~!C0$%MRWVUwOcYx6N;|E zpO7KZv?~4!%GjYg$nZJtP;8osp*yzgPVKS&`)Kuj*KSX|Y@erg*d4i{^6u_Y+{?a0XN;G-j)(*6>f^eNm$=src7ko^ma7M~__?7ivU-RPx+gl%vh8YJ z+A%PI1JgtQyHya$HU&t&H(1>~(Cw{5mI-cg;y* z3f6$8rhzDVSTO2%NcRg2dzXt*#c00Z=Uf0w9^+1oi3KS-89ttID(Lw%0ds?Ps_ z@#QslC)2LL!x|e{1o=TR&z?zgKA$nqo|*Fas1QSBG9)~nAMkKaNSr}-#U$!2dpLi9 zSV5#v%`hVf6O0{LMz+1~71Gqkkv3wiErQ&QM0c(0qE$ntH|_m)-Ni}VhA4Lb z`ZYHB8nX^;kU+;{PdCL_Z)ra|R8%+KK9yiwQt2j(h`LUMFW@=|S2q|Sj~$2FJPr+5 z)w=keS)E0m0S%&fIT%*FOEIMwePYynRZX1HSi~^6?Kl*pZm}F%kQ#_LcDC;Z@a+yc z-o4a%285YeT;FZM>g=t~#~3w|=u8*BhY1OQ<(=_H%`UliT1IOkPk$k|VnqY_di;HG z(7C`nV-pvC+E&HX0)jfFFLg7T`T!&R>@MY#-x-rg_vbn)ky47NYKnlENkkY%+`X6y zXk8WQHW`W{WdpEB0n*!4Z;dkV&o}>-U;Rx)9I@bJJ{qVgf|1aQP(6cPkYr}V%(=Iz zj@ci##YTff84r|D+np9#N+4)=QV+pnn~6uI-A>+gsIAyn>s1`ttF`;h%0~;_P7`}2 zdF{sZoq)ZCbkma3P0```8Y7kPC|72nqV_bk-*V2r zFd7fFEg;|8~}^r?b9ZaXz1MS=P2W3(t6Y zdBNq9@piocCIfe&6vDb#XicuoX~N7%Q*;W7KmYkO;e0;h<3}fY)^5n@v_?BPIy2&3 zk^0^;ZI6E<2}j9-oP7-QeEQH>0AvdLE7g@8Q z_9tiNv7?|zqZZma?#r^gTjbvoH!+MWdyw65|FzJ>^22V9@j1u(rDa%$_V;?t2$71H z@4nuPj8W^=gudWj!!dkz!9lS9TKYKUI ze#2vo0c!3liGZ~FZ=J)0z9S>pKgRo=43+3zz=u&{1ha*Tl0!O3ygNXSy;Cq>w>gby zd3D04Qp!Y$N=bz|3G+mtsjNAP2n$HeEG05w=E^c4A10 zlv%}chM!7{!ipiq&*O=~N|??kBnx?RSwbuFEl8pSn`UGv)H0|Wt#F*u(md^8LebI5 zQDjka*9sDtQg`yr4fXDur$;qUsq!EMEDRwDScugIo2olZENPJTCOLCJ>4r&FXfPDsgsv?9Zu6#&}f@yEAD#(^NEf`1vom)~epju$YxXgs>W5MMzp=5xP;CvRG=7f|87r8`{cXDy* z<$|1-5Rgs~@iEHd(-}`sPk4NK!sFu!^X#Hn;tZY`6Fc}zQo%$EB&|qBNQpdyWO05B z;AFlzobA`wKZC;%o4xsas64sz!6pzT=t)qB@D>>Sk_09b=Bn9gA9Z9RU?HqpPz(_9 z5hSM+VnyfF$mAke)zvvDY1*K2sz|3(+bD`EXfLF0MBa*s3D<-ga@jN$u2D*$M7tvY z)vxXB2a|fRr#O{^30$^ANj(MD4xCP#CTG-c_~Vc{I*afwrkdZEwX>pWj7XPord7>V z-(~DmjA!-(@V6xo8*+a*^6Zii@$+vFXR3;mT)S;5ZB8`+urvg$^-q+^eSz18>kcml zD<)y2(~KvaTGkSxmr>dwJq6^h8^3|T$Vf(@selbAWx@4oSg($+ms5gFbKH}R64-O0 z`o4_g8K#=r96SsyC|Zb6jD>KagyQB7vm8mRX2wj$OoTcOW-dfTmKbKHt0|e8vYTSu z07M`w%4*l_>H~nV2rCS$x!;w}B&1+d2tXHJS&Z>^d8O0*$h2m9keN)COo5V!2$O3J zx#g-6o0>aMS9`Ar5s?=6x(O+LGbcpYX$cD})!q@c%=tayy9!5AeDqz6IX=?Pg);5_ zuG&+Dh^qotHb=|AVc%@5X2dkMcq)HAJkwp`s>O@-ebx5SZ1?U=HBJN5G=as(1Xe;b z(Z!`VxXw;fu|MI~pHj(;w^U2JxoLeoQ3f?QcJ$0v@%KLN4g%IrQrL)j+CW;{DWirnxY7oR4<;fgwVahf|_`$Dy#fAl%j_DYZGf7T)C`_~y}Y;H97xL&-qSD^v+z zzkS0zdjV9ko6V7l5@tKlBYk$wfOn-XYW{?-41(xc);m&YF5@X$#_y^ zMFNA^z(!b>s}~tXLr{k{CNi_OuN>)fdQHTUwx*x?Z?3Abo6FH%ym6k`K^Nl(oFvS< zP8sY_WAvVeVF;QFtqh}?w?*4_MT>=p3Up}`aKQV-ln^~XV}Iu-7-?|t9x#e+9_e!?lFv? z|08qxnhsu&}V>* zFd2bs8f#3zQZP6eYNDx*_zAoA4?@=-<9(*Zqq%vD^yWz4twlzi+Kh`2?Pi?swdXc0 z^{tn@(l(i6^Wi738kY4HB`@w$06{HA0)eHqvO+DRLNI-qkv5a8LiSt;s_c!27<*W# z?u!+eIYG3<3Ew*fUd&Jk#A-TaQTPnp`prJaX5%NFoWng4KkvFOLz}UzG`6kl4XE4e z(Kh|!bQSgh8}HUs<&4r{`?@WD@#m=%who_@(8fFaQIhACpm7!YAK}V%uG+02E^gqn zCN#~S;h{N?8W^>PIVNULUG*udkA>J_RZ`fM?hJ4wfWjoSI@|1h4wjD$^>$p@e{O|o^#WY#a+~@Mek{;v z(1w8mRLAw+cjud@&UOV$&2))QaK&f{`88|gIYge+Yz?!YD-l+GJ+E546kLsMTvejm zkr2bmI}RFrBIdt)_uGh!fq_K&kZ4NBNz-1~IXp6oerFjSR?JbM~!smaVH z07*UkY-Z42kI}O;tmA+64ixLU6%v|@`p$GRJ0Kp9fz-z;rN5&9Cb@Ah_!W5TF1eq9 zv0eB_)olImCfZa(E{q)69JXc@b@7nM7CG%v+xf7<){3*<`N^x$sGeTevW|}_ZfdTs z72VYB_lSdi`%>4?BGkC~*7*p$b)-&K{fJGsm3murVpJhPbZJhUPPk@W$KYr&?iaDW zn5_T24H~tzeUIMXR*1C4ZgjG2{1E>cbxgHSwcR^XXzyH!*ULr02cV-HuT#G{a_fNg zIU@T6Q2>~`l-QaYOVLRXcH*ZNM%J})F`Di{6>_2hvQ=FWb<9?awtf0<{rl_n8pUtD z?yQAzITjj240op{zpIV#V5lK8;Vv<93)HIb!xr#2P-Z(u#vt6@biN%Mu-+(X~Q*O&D(ZGW|(=bE}MxrSR6t7|5x0%yUD8rlH8-X*>k% zGfwid-t7$gSoXFkYWIuXPfgywS83~M3q+)f#UHOT4~85CrZu}{V=Q?gS2Tmm_`Hs; zy}qbxuV2?izUOM{?t6+{l3KwT>6Q^PUOwJY=)W|Y0(D8@Zoj6k6H((gYL|j*L`OF* zkb#pytrDuP?xxS&u{@468e2>sGg7E>iNss9-33ExRzu*aBJ0cwgNUsPJ5wt#DiNTn z08@xW_ahZYgL_9Kv4UMRPC_o)Ci3DAMASL*YrTr7u)qdzwIEp&f^~jnBTJ%0q+s#@ z8e-jnulB+nJ|2;@n{#vV_}5R3yAQ;yTn(@Zu#C%cg{|>*%n+6EmJ8G*#GsK+XkOX7 zrIEw#I=9y4CI$o6OvssV4Pjz^4vavR2R%=iZpH^1ClWJ&WpWGQnp-ENK1Ubsb@>A@ zl+ZdT3KRvLlD`@hiJ`<0^)qVywL(FbTvQcwRG2IGYlo)h9&A=ZZ(kPM;DoNix8c7l z(<8^cpUsJ!)?Ej{7AZ};jRfr7fFM-2jZnkaFVhL63TbHT@x55CE7C+Lrdw`z@B(b7 zzcLgMLgUdkKLN3}lMb#LyMVrW>Bqr zvDtPO;C)D0PpT|^M{GaVeDQLS2u)KJk7RDC@Sjuos__38_)RZ z)*W(MiyUYp2G^@bD;LB(?U+J<>-TlGp;};eWKj*J*ifZ*0Kn26X1$VGtQ(Q=W{Zt6 ziGN79$FpiClS0q{W5h^>Y&*!uvg0o|Q#IDw9m3QtCu2wV>Jg;1Y9ZV*&YQcW+Es~Y z1~5@rRO9tT5>|*N6Z|r5kM$GD6Bam;bPDojr1n+e*e6Pf$p(wX_sT$`7UpuV#U{WF1@1Iw282r8JImzvfG@p0%~L=(JaWz%8XW-`!}x^L>>~vVq9ItE z`449SD00g_sBcv%1#33sY?1co?uTu`XQ+CdxbedP@KJSek}82RP=c(OBAAOpG?gO* zV|`oNEZ>Z}G)O;%7o~^vqR!`YvhYzV3k{Koj=HjP6mIX|%r$8t2l`4`nPxz$b**dH#?6;-yU;N~l zVQYq#1y~DYn!-th))AxVWO-_^L8Y1k8YJzQP9qxLt(71kC(K?eZ(xu3Q zav^;;wc8!u+6HY08+hz%KJFJsncDWg3?dv+Rbn!&3pI^q4T3rg2$abzvtS}Nzf+k& zMY9Wa#CrzRo0NZWoS1+b*5aB5s$HE;cR`&>g}U7!5m72=E|Nfi69br{voS~E(f5t_ z`6X$ma19McdqKG?F4|+?bTJLd8Z#^1s2Eg3uB`L_68etFUX1kK>((cuHj!X1ZGK)# z!5Y5u8U=nnpW|jL<4qUeD|bnsy}n>w*RYPRtrj~5cZIgM*%QDtO}A9U14l;B8L1@Cx-<7F zrhPi*{*<0`#FGc%bKqGBkMC1-k+#nXtwX7`~+AF^2_DYu0IdH z(zYp@8E~53)i08uN5)-xVXf(b-hJ zg^!DP_;~=V%d;7D4z4{Ua~Fmuv2u82$?0x&h4;+3*dxtMU`7PV03mWB6oOKuWcMa2836~k?26zzG657x4J^17={8)%Ezykk)`nHeiAISM?@%q)q8 ziHO#9Wiu0IJ~6WxktmS7A`j{oaS~$U7+4v=SqqbCn*}i?A6>c0or26rMT);#q9~=1 z8MC*s)l^p^Ob|BkWU)9_=R+MU$SD+dZcTyfY#w1-N8?&NUcJ#5o>IUXicCzlf8phzsmWL4f82%k`~2t`zzVEt`dQS*^AB zUA^vtbtgU=ruj5vk?bw37&IBybQsJD%z$DAOKO7GVsP(zw9(7z9T=m?X0XlT3v#Tl z^AeKNL2HXz1T2Er%Vnq3iTB@t0s>7l);4Z3P%Qoe0j8QF3o!iJN+agu~d;uL3BSTUS92fQrCNS3#AB>~JiPQcW_V;tQGAfYg}PKpSmI(7&w<0kmWZlw9-7Qgk{*F%H7}t)}4I`JPZ!#Hn7Z|x%u-=n1 z(_w&E4wzegUH74G?UWaZzO~4e`kc)b{37CP4Qztuel1Fz?u<*g73uvZO&E)jWm$qM zE5m`Mjak4$v9_I1Y_I~@Xop2s9#v^dN{uY{x zCLD~;B$csy6ip#h!(s(8%|S~xOz@FLbDx#cHDJPD zP=tjwh0Rq$UlF1d>opnFMY!)f8`S-KUkO_G_3en$8Dp%o%b=ekZnd?!@M>tqMt;X4JzlBrkNKHpt`ItxLhuHeSK}Gj;j7&*EPl^Wl;I|=y96S z7Kvfz7f>#X)3%DU5Biy}sg(EUoMn7I&HZxcG*;i+{@d0Q_&ps!Pb@T8 z>rz!$NpG)Q^LppxR|Br{ki$Y$t-V_(s_#rt@DNgL)-`!`nx>}ZVfIm1N~!A*pe6ne zmR`!E-4Zr*4EmJR{&n-BGI_AzJ62E7ZMy2<=%D*!kHNKM{H~_r9tqSA7STZ`VES(7 zv+O#R*jcVuTQ_>|?rZz50~s9#uN`SJs^E1jXzI9lEYfNw%r@r05DTy@%Wgz5rZ~4E z=gzOP=EE-CkN)Z(|ByL@ksNyS{#Bky>v)a7xBC#I9**1V)OAUt$RMLbKGFWZJa!<_ zuH#07My(EvcMc${MTWURlB?FjqqnS*AxlvIGkbPPA}=Nq8H9kOHdtNv z;c0`|G?e8GCW;YV<2FfjSS)lSHRF!ERKc)4Q7=lf;1<*yrW9vc5El}W0BvxWWv9(g z-7A@IHYseFU;rpf6Yct}T58~!A!miXthih*czb)p+uIwi*R^#n)^){o`G&W*H@v*O z3^#OZm#=wPghZr;SurzY;-P&lbXwr?j=`D>q`B>Dq3CEw0y~yyd=Had*UZMPUXN7py{EBaw6Vd8G&- zf|&$N1!Vqw{c(F?>Kv1T`E)|f!sJ@$c4Fj0mu<*PU0imk^$FF+8eJ49gic6FATm2A z;~)b=cY#`!iz3=!Llq^ zFIT+1y?H$M+Z&c;>t@stlQF2<1K(X2D-pr6EUl9v(?)+35lr#-Rg3X3pIYm; zo{Suy9GK;uufBF%>W8$)bKKRb>7@I`wRSRUyZGK|RqnyIzN6pRf~IuDj>inY&vQBA zQS61hy^~|qc|~24E?#D?(U|21N zaz@TE;sCYRzuz<)9aMoyBHt#8tTna;;&G<$s|vSkt3KAOBQszV{MpVGg0A2%NQuYU z`JGcNccj!kJHbp*NB-Mddkmdw#YcBdM9Fwp53|=CyqD^Gj~HC9!@b_3-p^Tc15Z^a zNzFW|#N8U)RmI4IJ@k%qhKTQU5AF-xhw)UbzB27nlXsjA{Q=?MzQCe?!S;KPUDOwZ zefspxdePfyb>mnZ6*9d$t6u-LJ7@#{M+Y`d@3v{t@zvVeYqH|-8!-ZrS5oTKu7;Kk zp5?fwIP9sl0na-evuei|MvnWm=B@ZqE;~f zU;tD+>z;zm!KK=2{lc&&0yQ=!h6TmUeaYehLE)$7CVa|vtIDji_MO# zNB%RV1=yKw`4`Kw;M><%yuQBT_4R_w<$`bDzC|IiZQ|>?;)XGh><(vcARm#W%pRCS0!t zWi2R0JRP*n!8ZbY70XO14Z&L6L0ZiOER$bb-K^b=gMwOlBf5ZHMkGxKVU& z43Um0plZ&Gs8Xl{WOaLI!>6xh)V>HM5EG_ZT!6~~N7Ee`jB5~9WNv6|WN~`tB%5QV zc8>@{8~(p+_YWvCTU{9NP}IYQ%v1;m0`02RiAPO!3#?TQvW^2r0v zI*GguoW7d63UZmRy**H?V`^BZ1YU-9*;k3lY%OXQGjP6iKtyADJ}-kqG< zcthl77Fai;Wm#~&{QpS%yY9%597`14fEnFg5m{9|b7$R$`Tu`x*10p?eP+75DlG*B(h?7*4ig- zK&WJ*>tvTo8d^j>0FRkFveW~h961Vm;rY7tXnBn1DqbTym1Y@r9}9Ku|JmHgg0*}M zqGOPip;}8f%BrQJy1aJVj2yXb+u0=OLNAS}GC%Ut)8d7{M(@h$+(}>geZ+fbCC63g%t@V) zKeJ5F-<5hJc9+>peY?BojqEy1>I~5q*JvS1mlZciyN;wGV$#jbxt%&{GM-P66SgTdARCLS^aSV)x z2a-U{9LW;#U@8lfG;??(ZQx1+5$~&;FD#yqij%Od&7!uQbMf)vC*b6I@E2g>R-x)zlnNC>pjM*c*W6=32aW_|>vifcKvb z%%66y?p9<30kF88^kXq{sWyfvLkhX~hY_Kw!@Ez1`YW+pBeNqe<`p9DNGh>0_-C}6 zSMk38>{8pv#~8*po|?;3!ecDNO=utpMn^8bAO>M|E>WTtC{zIw%hq6kJ<9>bK5N?# z^wMmJJ@7yxras&%J*do`|E;$vC|saw5@#e%OfD3yQ1N1?BR=H+J=%PCRD{hB<;FLQ z<91by5>V9KL>SI)_cW1ky)2b*BgTy@c=zM+?1tX0X0l=&mn*7R^dJN$m*5_A&J3#7 zp)X6s7Xbt(l41#%xO0b4%qTC4C5gh-$7yhbr9ezjEQiI~$uc!;^ctGiktcaJ3veYVS}?h{&;k&Ik0%zj}@11jDyo)D3KR@x@*50Ls@?`9aq629I`+t_hHHW@K z4KPEl;ct*LH(F~DFKSBgFg&tc(Z(+N{(<}bj>qF+gwo1ZaPS+JW$BAz>+kEz06!m_ zb5b}W(Pua`b!fI}jfO*?+h_M*=yB37T>h@YpTbW3TA3oCx!iuSkj1D#X@s~tCjoNe z@DP#3fBS5;r=Ygx8#VkKo(*@hBsq!ZUM;bpi7 zlB1=gJMAkc*>TKG1IqBHiXvQ~P>%qky8$ndn{2COkPf!i^|yV z{4;tZe{e+)dl>DEfD&(_pDYTSQc;V7yFKSVEm52&67bdPyuBTQfXWSL17PQ zVknc4DnT3L({|2wtC1I2-pc|MEHEZ z+oG`;60)IT6Z7BD8=K02fKTioX+w}22$0VWWfLsV9rybkZ?^@H9r)M<%g2iQVjPdR z`wa_M%S9;#sP;Fp6%l(WP%dCk^R+@|M{^{j(2?Bg^fQPEet#;KrQ+@OhI)I0EDJU+ zw&}`+>()c}@0Ps_{z>u#V?(tKPY8;G(#*zkf4B zH#AoWYy=iXsqnaQD*)f0zXKvDsz7Ua5JT@bNZX76Dy9)D#GZEAIx>PnApY#qUUfc@ zNtkV9_O`gsK;y$l00(!e6-)eG_~Dzs=c5Q=Yl3gzzCo4I)G}~dUu z;I6Vv3wCKxDLtdaApHUod!AR2Su4hdN;YCED1#ihC3B|mYXN{g;D1;4R2-Xk1I+1> z*^s(~LaD0~Hf^A#V7XE9`Y>cn(k4S(!Bn8s>|Ry#JZb!!J*#m~yQgAd0vITPa5VuM zP=xF&im%$bU2;*lt1ERsi=+4pBI0J}P!68ZzVCf(S#X%DsVY9*Z0&>v2FS(Pr=kvH zv9Z92qNH{HgsL9Dj{-Ir6}w7Ddd zc(s&5zPSa_gqS(_7nTEJl@T86)TA9bCd`YfF3wcFO=v|8b&8Kp%#OSiN|kw} z#G$oj&Za~qjJKwWkX;W=NDPUtN%qC!cDuQp&{O0v+TNmGcRpb(G`K;!O~~{4?6TAU z`1|kp`ST|}KAwZrG`uXb74)2w(V7_p<=lwelOu}Sl@oRLgBaBYdvsqsW}?J-$%V(&toR^S zkqFE~3adI&|km;fziJ z!0ooA^hz6Z9Vh`n{d|q*{r}0Fe?~RG^4B}mcE=<+ooDtmb0A_IGzFWH z9=-`z3b#IPabzt5x`JEOn=w7u{qr%c>v}K-9myguzA^i|bRQ7<5+Tw_X8p>C2xG99 z+ln9l6~{V>&V$ImmVJ)CL`+_ckLLS35ay1ybrl(n>MGgq6acl>NTsi-I-ZK2pc)RKIo&As+7gc6J;Nm2u@8q*^7GKG zB(ih=1&SeEQBH)qyLr5*5K}KMx-3RSN>+meL8P^2-WSw3jXQ!6TKz&Ui7YydNW6Ff zySwQCe zd*FT-)I!O2TX9?1)doFW)j0svJCwo&Tp3&|YB(hBwuvmuawr-)fs4T@Qy^y4hUThW zo83Au@*=0uv4LiL_+;ff6dB?+)4KaLKIV2Kp$?<$G#8Co(icTU=MHof*VGe@Jh({@ z_0T+PHzU8|(oMG|_Q!EoBd5lBjv2mn>n`esS>oA(aP!n8`~5E2)^T1Sd)idk2&yXD zoiG*Fv7x73(!h_|*ppHVdy1->il$h`&Ss&7X@jkYufyOC5hEZY%7XH;K`CU=)H?c~ zgxvouY%gQdxgnuqz8%A}6+gf4&fSoUFh%s|0Caxup6TPCtru45I;nHA&{a|7&xWB& z*(rAz+xUC@{P}Y*_UeE8IsM1acPz_-x{RE!S+d%T3mr!Y2Len-tH)|+ES;a5NFfbm zL_~gZy~?S08xW;w{56s;4}nD|tY)&XDoO;v$&u2W8#1cPa6iO#;vky(@o}IxwA($* z_N?me{4Mfhu;)lcZJl5%^&yVH&rc3j~nk@lHWy_<`3HCjC;kbKCF z=ktkwZaW^22mbn(-|+3*H@rP=xZm$-!7ja{4mdqO>|vQ*s=I2^L9T19^^PNVcbA*O zWMUMHz#bC6;G7HzwsKKqO@0&EOXH$DIvf>oirs!STh5DX*vdyoI4qD;_KG15E~)k0 z9ZU#@=s|iF5tLg&654lyX!tAyAA{+TAZA1>a}J^#J)Os7zVr(1=*UveB|$lvT+Oo1 zBTC-jYc6JLXRvH=g09sQ|8I&5B=y1dQ2E^T4t_8%&ci9hi?4lII`Sww+|N0Aor8rgIV=VAB|6m-(s_*pM9S^au#To+XCI4DQsvJ$a1RDRgHK4yRq$L**+pM* zDW>T2ORh{@*H^{qTvSEl7Zw1SgA<6;E?*%NiA&~2bhvOB%?`!KeG?wz1D8Wf;fx?C z8QEqEQtPUf1;B>G9s88D9_!?k#@^Y&BIZRir+9aJDjlS=b1Ex|h}L8sp5L4!zhvL{ z7=_d$tW3jVyttWpM=*lH>c(8~-z%!hM8vJN#ft?dB5KXtF-k9Gh?x19f;3pZL6<$7 z_d2*s(z<8cLCSIIQe;yAiIwlY1rw++R^1@tN(Ax+4h8GJV_iLmfz4g>`PuLv|NamB z|NgK4h5zgS`k&^~x$Q%d5y*wAO9H75k}!B$XW#5;8;XpG&dx=|{QbqltpH$K+qg-& z>t{(4L^Fok(EKy)``+^s0P)|6jm(3@d<^jZ^Am4xZ&=qIzdd*S_WcdtzkAC}1@E7> zP~D1JM?`M&<+tgr#F!v9KYzIDjv@kbTjH)NfaQ<$hujPmJR#O*%jV-y?caA(Pc*f8 z@(#rkKQBII*$2{|jMh7+iai*)ftM%Q%^cv0`X{V83{tgLE1kpY27 zUT`D?<*o=HTy^}n+7e=#mdnzo?W`5&lIZIgk_nTR`?>w41h>U zei$sB6lz7-QCNf=w`elNn(p6c3u)ycI}(jT`AF?niJMRpLfNNFN3j|RoxdiR#fZ%! z#`CcCjHqpD{y}sEp{XfNGWu$^+p6w`?F8Q99#P?jO4)uQnvrk>>yw7@XDvTXpj5<^ zBylt2YUguTFsJd*IWh&+-dGD`eI)Wl#7 zS!!i_gTiK5P*hcX#=}HZu#^4GB^*-iL)ybjE-_+u54w4_MikCzN*Px5!jFzDUm8N~ zuI74OVc;{ao?_|Bf!}}sfq(gzf5HFwAO8dY{LlYt&Yj!dEy8WVVJC5pTK*#>tPUOd z);@;$U`8@#m%QpmTVW|4dtW@{-De0v^CI(?6NLArXNKoc$c|Y9HsUQ%4$$ z;>nfr!uKVQ82__7xBUltiL&MIAHG9qE}!UrNc?u>M1gn`3^j*C0m z?w4bdG9jWg`B8|pVHA_iyRz!&=zw)#jxNjW_&fS>Yxq|g~@&3wR-*Me@TpGQ8U^D1@!9uc9a`g{yPC`EmrZ5UEiHG6AF z2r4w?dZp{`)Dr4e6ON$ebk<%-gsRhvm*%f0hvP&CTl9;6~yJ7wIK%)Yb3aVZN5n+ptDp0siY-DpSW&chT8L=`54X|!c zee^Wd8rS*pu!q(QIfmsAun~EHW?h8#IP1iICi6?tlY7uXFq8f8*~k)V@f)qyWf%#l zqYY6EGCdtK_`Za(&)?JR?2o>7w;1JSct`pi>0`ihb!uv z3kH^Azpw5F&AtI?pSHG>G*u~CA-aX1H?v2k2o7VeSqge7ah~8}@_d;_FXYe@;t>De zU2*zRN2gw9d3JD-K&K+3bCsY#T}E5|)Wt{RF^?I|QrxDtEcWP5>|CjU_| z23JUUay3mJl!IRb$6AdcTK#ykG~GA;q%cEwO@zC4B6ry+Jz>P1%(b(t#;RD}SR zL?l%n#y5FbknJ-&f`Wr%H8?}}>5^fE#P-Y)7k~D|T|?by(Y!R#)UtNt7>|@(BTK3% zsfY$4mup-H)|6`^P;SA`@ri>oy6otspFZ{?LqOCM){2Of1EFkyHYO-Y8o<5LEZPAypV_uz84lE5=7?G zHAI)!^%O>jbD-W==-Bu<{&U_SVaRBr2o6KA!LPz61V>GzP;hluP4K$4oC(I1_VeI0 zdZ9sjB(Vl1g4oyzBqCsQGtcSf`l8rK{g|RIx7#sisg*tPl$n|C_d7AODNLGhYmF5; z*o3=Eq&jhPN!*S?L{u$&!Mwvu;rQw>j2zjw#%Hirhh1#4IikVZh?SL<$+Yr3_`e%e zR~1a8l1Y-|&BW8q{&>7~DH2mf+ZEg9-98xG*6{xG6aVLb|2zKY|NLM0zyI(5jrX4$ zK0kImKO4Ztn1@=>)$Y;UQE^MNT#V0c2e5(w?)7#eb&De2GNekZNb~y4Mb{&Q^ctEZ@m*0({r1Qu{$6t_I2y5 z`cg`FB$ePsaOq5TQ$J|8zP6bx^$ti$`{o-~;@z>&k(130!(yznZ-!7UVTLBg_b~nd zV{Ple!HIZu^{%{i^+4(8F*2HBw1aH5Dd8M>Qd`K?8P*`%In!^n}3X8Gm??rS&0bu zx9{FWtlj$|;tiP1m`_AJ%cvouNHwLuW&|UXfK{~z^v!Yh9#@qdR_jQzb$8j849Q}Q zm*PFZZ0qh)j0<8iUZN^oX!F{_5epf$%GRM5;=gWQgsofWpX zRbv!lj=G4*4Ty-AQYtg={rNot1+9r^+lw6#fO&Bpo+cv1(0V93jsk;3Bscw61;>zG zg2@Mi<8N1*5EHR`Y6Pm09Xz{}ClOUAd-jo1R8h=KwN@^r1Sf-cM=oe=Aqdd$RM&(0 z)wQ>26xLNHU{~y1rgth%555sd59sa4A30{fkvsB_fBXag_HX}&KmPcmD?IeDgY5*M zgUA$i!Uqv*>^R!+^Ld8ZeK~%iVhGqbkdWu|iT8IaIu4B;Cw%W!ma*Af=W*lANlnzQ`H<$^7 z(E;1}9yh`0@PxPNq+Kg~=DB{~NDBsbd{6O289Kf|B8G(FD?bYBn5KLFn5Ac40TB&m zP@}3~n(Z@Ppt@go(erG6MuBEd$SfoM>h)jclF+Y^nCbN*!S@wsDNO!OybZrz@%`g? zM$SikKg*nF4pSyxzH&&Oc}uF-_PsNqEFpvl2d~-aq-38AGhl-zDg&W4 z@&L>{HNc=XKTiox{OI_*+Gq&br#vGOW#9K=ga{*Vl6Dy@yD3MEL40&bePohyNs2@B zR7#;*YkVK&cI(Dpi5;tbCT|j0h#SLHVG74et40wSX}!)2VEJr!&3URs}pQf z4wIszqqw~tGs*6Pmz+6gxbL)R6-&z8wg#g0h;#QMBXtf#SxO0Jc9tBeY73(Pk z0Ax+q1yGKK+c+I%@o_>BB=bE^o$1)+N1_61W07J^sTyP>pK-L$+50F3?yFWoFN?=n~>dJjr zfZ4r7C=gT>El{u(n<%!aWnT*Nd=K^wE{$U{oK2J8N&GFzZ^BPbFV;)6zFxA~+IoaCYdFY;A>Lj~~$Sea67ORNw}o zUbjJ66uW8%vy{8Ts1SOJtEBOXp$DZOwl9<312#4B?fQG$GQR8}+@O%+HvWP+f zmQ-0LH+N(VjbLLDqbL%AsA&sAu8OfN{W*1S*cgKtO_H36Xt_po99G1~c6JF7yW_S1 z+>|Z&O=;g(VlG6yl!dGLnnPStZc=>00;m#$pdFhX1z|~fdrDzFjJ1w@`CI@n!Biw( zBvd5}MRT4;CV>vW?>vowS=cK!e%x*mJBy@nVYi)j!;$QzE}jn8h={Pf)s(`TJ3d1^ zI&sj)QK5S1XQWoB6wjQ{o<9-Y-nMP{`1rsdfBZ3UF;vYZbKUj{C8#}!C^n_5`FHNz zzEVA0&CRcVF3)2vMY9}9n~9kn9FN8}9%*b|4)ZZ~Y}CrT-})e)8s zt_QuZo+xW0nV&x`Z0&D<`HtUy`>lKVpQ`oDOG&|4Ok+jgGgpqaa9YgQ!4dLsdv*Gg zA{8fztKiSVE-y@(QtW&9Q{-%wxzoyM(cp^^nJzDyuYTX84!e&&GJ?>#4u0>JG3%LP zrIo`OHTx^H$;mMS*%V7^Z02SJxY;mmMUdjJ|mVjm? z?yC5pIV1d{csV-%!(mk7*^SK|BWI_tW26Jc;b?OB@`Na+_3MJa@Fkk@Cuk0m6d zjXB^d3L+x5Bvu0qT5C+)NcNqW8#Iugpo8WamZb& zsxEmrV{puow%T1ewHF?6;%AUlIFU@_uG_G| zs06F~Zc*xcvXzF#Zs!|cWKZ0Z90FvB#{t8S-A-r8@1r@DE!YAnG15VInzWIt#ocde zi|gmU;eNm4>6?W(r$iPbO)?lwE%(sO!h%qycs?5%c0AV|+b(#nf?6X^e#I_?Wx3;a zx7qvN$gB5an^K@VX;C97;8OZ|sy+k99G2$iV%N=M%40kumMb9)7RA1=#ysZ^{5T7J z0norSN(fDuZitE~z-2kc7C8wP2ei$uplFUlS&D1*bXuBN?Cd;);4DOkZ5=W9*Jp2N z9l}Q3x4wz{p8qK=*Bo}-&b3i>UJC79;~$-wbcAnO9b{TV%6%lpfsxHJs7#XZC@#om zDdavGLClrJ(>Jcd?U>RtoBLFX$&Mx=ke@;YObjvcCW=0WqD%s@(=lB$lNYlppf}E5 zjF2dl?fkfYXW*26F0Sh zyd6|3$a1)eA*7fk$0v`BVIIkB&Qsxy;bRZGMy>+sqm!ONZwinK&mzh4Rd>{k0zd&Q zp)SeDMk%Evr3mLaPtxGV3@}))?4I(PxEQo;8=wN?RI#@|iM?NMgAVy>uAjTs=!#ow zXuI(-{`lh$yuZKq4Q1OlJfG_jYDIDD@Gow-+h-!V_A1-%7<0h0yd!c$N zVO^hXkH6?h^YIEDyqDNSGjVhFgShg*m>Y^bJCF2UEz~!;A&Z9ViIZ`~X*!UGajf#0 zd|om)LmV3J637XWIk+ZAmd$uikDLJ^8Km32$nNSRoW=ne=I()RF^UY1OqtaaBa#uv z*c*eM7E8l*Idc(44$_t1$ndv*jcB|=G7eQ6PQEB}H$C|7OlE3>jlO=(1DQE6*)Qf8 zm*@$t%cfe#ICDfp&i*cRGV^*F7ykuPNb|T$M&#D?CU>yFG6h z74=ppln1d%Nr#&=_o4@&aka3cSOg{cWq3+z-*kiq{{;{_f}zp_83(_GIOfQL30K)} zNVQMINJ8HjhmN_Hag!7GI4IG{7EmofJGdJn0&KgDpr}rp9uG6`BW}D*q)+?)V;LO~ zmC`sx*n~;#BJZr{!Bc~!%KYhc7^i9^@OZ+sOU%x4Nl)4st{OX!-qZXNKEgAP;l&$bhtMSy*Z+81~N54 z{(Gb%V(U>5&qD9zTOk>#EDS7(ZSk^at9BP}mHt$jEETO1(Pv;_VPxs|2NxBv3PF^2 z6(YA4Pc{~_Jp|zk$4?RIeiwme#F&JA>d0a~79mkB>`IYju2ldmeEjLjt*TmXw;MUa z!L`<<)=CCsSn<)kVmchhjscR-2x)v64>qky40oTikN@7)7roQriO55zhyL(3kp8=$ zpP%^g;|G5J{F&4zCIyXLj(C`IhZ^1e?WUK~wr+}}`%6vu$uIt5aoo1`3r4lE&qG!@ znCndcJ$Lfz0bDW4bc8eCh5ls6W2%}U2HJ7OxF$L@nw3D1OD6pR1?$8W7*QdrWlS-RjXhr9 z(U`1e$Q@X|etGvObZk<&8wZU6d7#-xq;%vhg7}VbGCrfCI;(>u6&d-u(WL^T^Wvs+ zCr)s!Zp%Jz*hgoqm)(B+_r7mV?B!7^+EWYU%fceRZdMw_`cN?icwNr<>6gx_|4+CX zfbpq9jh4A8s;}QGJ70!UF4h8KxSZEa?0g`9Y{-bBW=3Urich%ajoEuAPMplB(fC;< zskQV^xUIfan9T~NG_IMwOvX+B)d=e-@^X=3_Xvi7#xJu{?A&T^ezIl0NH=LabAc}J zkFF{)5@}D-O_mnj2QGsPEFzXuG6kfj+8`7tl-)t;ipZ5#28&cM0%c+5Qq{Q?f+Aul z1)C7QDo~)Hos|JCYFCMFwUR?C-Q_dIw);k~gnU)K=wOGH>F4$t7sk4OI#OYlyt}j>XvT#B5$h5fVc&Kvq^LL|+JzVF zY^8e9g65eA9~5#{STCI-jmeAp@K`r=hh&y0CWSWxyr~I>`JDZ zp|E3TV&0nHKSN`{=$AoWif-&#I5H=1^1kgwKJv zMZb~f2}Q@(pz1}s$PiW+FZtYdKeii~3eb+iB#@1<7&mVWE#f{Y&BuV|su?5h;3SBv zW9*vQbIOv|f?)rP0KN&U-}|@Q9h-a%MG$J~qbeJ@w&a`?N~mM=dGOmM+1mWDNrI2 zA}~WrVQ?u_HX#uyt+m~7oy3yD5$()G4elL- zLSR}*chV~~gZ(+KM3ya*)FU0uNZuCJ|GgSwK@~vN;IeoiTGH8~wZ`s5#v)Q%YwW6# zKC5Z1Rc7YBP$vBo1u@iIe2z}cNul9X8U1O%byvx%qH?MIKHx)>^UWLdzPD~-_4f9L zx3@Pu9uHSr>;n%Y+x7MhKFvw*%WZ(;=h^(MyqIU0QA}j(@eF_F@ynQ+NyE%GUMmzP zsw3xN?lOBN{e?dL%IBbOR*q0~$IvMSw)-W}I14?Zt1%=m4ju@4_6Z;z7_!~Jq?BU1 z^*|vK!R?A`a?Gl&+q16!aAeIL(6u|{_`QC8Pm)mTi!j-PXvEsGbY)W@39(2Igkgtc zX(_|Kl)LUL+4E)2#RYr6!~g!8JUO<;-&wsB&zhO01*amO3mT5?kX6&5ih9Kbnf*C> zKww*6`cK5z4lmG&xIPEJpqzLBMEbHb|CMuPs1XJZ%yf=hYhS+h(a>DyEbaTJ`}B+o zv-q6|Q_N;p`IyDCKLUX|+>7J6*kg!!(X1wx->jbV|9`*V?b+9BZpfUC(vQE4<2p>n zoWD} zSltoi&QNRm{lLjfDy9$>zzQg}*2o$nioKkZ_XhjuhFFzE1?p)Z&X35U43{Gl@-c{! zH$_WxbxE^udIC^)8)d+Y3KE42d7Ti7$f4J6O&<9pJ`(BH;{G>@NZI$Dm>F`vOK|&WL!7&Vus;9g7Ivt__5= z*+RjUC%BWkEje7}ppkm2gz7#Vi)X5s3+lPhD1A&~yopeUgv7YpRi|iZc4bCqzN_N- zd=AmpOc;uY0^>lD5~LVdsDos42a%$3C;`gBHYdWietMyyojA(O*3}XLdmCoyGig=* zoO34y@G!F5Hun+WYVkqKVQnv}P%6%j_v`E2q2|69m5+@w7a5~`@Pz_`O*ur&{Y(1w zclE|{9|Z6udV=JS`-v~$X2Gm{8%76uF7#% zS8Wj$af+~aBCZ-wM5&n~MI2R9f$))POj5`JiEdNUHNa~86CzgO(m#(?6`buxC;~^F zsoKXPZC4hHPvyj;P<45m2|OB_Dk(Kq5@Ie2seq-jGMKPyqtbTBUQxJs9p1-|)JU%_ z#gkmB_7R7j+(M%SHTV)1NUR!CS5n7VAgyPYc=~E7r7X2pcK(I>37E~kC=nqgos1y9 zu$`=(g2-ojcNw@BwQu5-FLj?k2h;z!(at^2Q%rYEssvF+am8e z_*L|@NJkCA;yfbjuZo~~^fM+b(sidnxJIi)M)eSljChH~arQHa*VxAliG!>~*G`FP z!7ins={8-{(rx2yQC(6Ird{IMksFjjDG;w_W^RI7Z{s;*9?Yj^j!zVl(E%Tv3c5rH znvBJ8`XDcO0ORu$qrJnSR69X>Jb(1EFnEPT#_L}t+g=sUmp&(4uFa?>wM$MA6-ThH z%&z9+Kq(){rez?EkN5qYsUa_vN-af=P$fcBE40>o=-X zFgWxM?~iL`jPbBSX5N{JdT~!MMl>U)5SyyXF%FY?T^j<-^zfe|^^|#W#3G2GB*NMn zK^qY_KpTizUm4F~vJ;Q4zqV~R5~j&gV{}qPq@-}OMO7CODb4P-E?sSH%Mw=(FN^_h zu?tXq{8G}z=G{o5g;c4jlDOp=jf*}(!=cPjAuriT3^4(-otWy%0o!mS{4dmy74-t7 zo)&?5L$LzEij3cW`wf5l+u!ilzy1~LbL+~Hb(KC=$;C+yBFaTZ@7_heBn4d&#fIcT zM*||p`75&6m4vOk>j5ZwEVgmW4h7gI05e+k8@AaTGy>10jjEa`%bSo`as!i^IXuF_MA27>`A8 z8nhIk)~>H#baXTn*yn+##oA(>ySu}0LSa9qB4}doi{^_~3$pCf8=NR!j9bt*SF%qa zO|eS@H$6hI3S*abB#R>G)lQmZlTpjO0qL~CbsKZ?oEcxOx{rt^+w{W(jkx+kA4MP^ z36=(He%ak;GIiXu-5^Q?B_S1;a_+qiBfOLRo33DXT#^C@6@|aY{jprSZuW8BzI|D! z%;?RPRP|Mnai9)*lD!j+X}ISigNElFIwNs>g7vS~mln?o$2wAvB3~76uD;O;4hLELZ|RvTnl{;9B9Vd_N1$N%#yBv`eU;!tEruMs2Dr!iY zHS%?huVBx;qBT?Nbk35PJ7>f0Yfb4$h^V2dOg9J`z&o1x6%*+ZZ)^9h$yKCPQq`vR zhnd`t+$IcQg%uHY{!18d!2GBRs}lQYn5@v?)*6?#aodVk6zpi=ws|5e8%ffWZl!dp zL?puwHs~UX>V(Y*J1bt%Kw66c6c!O`YGV*DGP<*8@GhjMsiG&jx=gi%e}+p~HAW|; z6q1N}^Yph)8tpB$S5m?PMKrG%LOJBJ$1$Ii^SRla=ImxvWetq6KT z9H;RolOw2zXlqT08WA@F6@t+qVkTqG+-PJD?ZdN@>zEjqnA4_+k}7eFIChdEBo#mr z2<<90_!mgFpQY3wdlqJ<+wE5G_dDHgH!h`=`~A+h+l`~hxZm&L1WIONG{Wu9#ZWTm zQQBh>iHB9JxadJ*a(Lex!~?Y5i8O4RDLjocx@O?)O%Vl#Art$$wNJY4FTk zx(Shpb|P4oVpg(?+C?L>iOsB)X$CCMpZD!k}wvrnXa2=F(9NC!Zb-wb`g>4fd&s z4Cn-@b|+6}E`^AKxEaPErRBC@kLI-pD1aD5dc2b|c?(sFcD= zN1jP4B6==RujG&KBgmy9g0}82nc42kKFAT~igligjYY=skmU~jcDwa4h*^j4eq!~s zusom7{;=dR#XP^en%8E>!?_E~JdCTEc0kry4m}&02ShGvuyf{Wwe2>B=9kK^vJj7HkUyqrtGa;t;@8tD< zO^(G70QMFNjWLZkzN$xQze1OUuXLR#`U@2QR#C|KsET#X8bFKN^^f<{gF5HTpTLd$RFUZXi^zk)Ws@#toU0X_TLD4=^Ke;@40ocoWgf z^)ma?yy8nO3%?+-dl8YwJ$7%M`D&Rmz0@f>yJXS zN)400i)236n6Z-9F`ed6dW>!?3{iDJz_d57>IH-zsDX}RAI`{yy1`G-7fxxa8ZM%G zWeuKVKr#|cqDtmK&&_{k_XVyae030v?gI+_xy2$x!B=Jd7!~38+B-%0ELjvg8 zM}c7UP4a&0p>nrd#cg?@mK)Uh5bL^OT{moNL)%T#`0?>PB!~js?{_RH5NRkCSe6Qi z1=HRA_`037Ms`M@dRrGE;<*d#sjHS?YPNj>A;patRC$|%u^mD)EwX({FRRxZ>^X)N-%+59;fqh%k1d7wqbx?kGdpMe-6?WCyclHGD38upsW z&jQp(Uo(P{`4^YO)Cn<|zdv(4UK!lAggkY`z!g*Ly7uBQkGb+QNHxno&xK-0e>+d+ z^f~18Oy*}lk6j{Bb+FMV8B}xjoG6$_^@BNP9-M+qd=2O!K1ViX>*GE>k5WVgo9^A7 zKhydOvGHYEx40arfz-{?CJ8cAzb^T@fo&}6mQ)!>o^caNtzD_(t+` zd-vjshr-9l zHC3%{fv~C2V%oCUKed#C=SpleDS|*r+TIF^)^g*zR9e^7>?oKiJ>Nt&Pf~e46(&$A zY*JoFHNdos3L0|}(zcV9M$(u_1*I00Tfx5Vy*TXqNT_jCZ9QwPl_WuBA}Ybf2y&)h zocKGcrP|qRDaF-)F52g^?>m?95cl8p5VSrM3iKo_%JY25c%(|n4mXKKl>hRVzbLdG zuAm&II%cmLa=@!u?Ce948QHO^%u12l?S}jP-u*NF@#Bx4;}H+!w#7mrxZUr4b&MGP!7)yS)SM-6yYrsYCS*nJ4u?Uud?G<)6n+b{u7J{G6fh z=$P813ef4A90lX3R_L$i*R#X>E-kE;U2f)GkkYW}(ifbAKjX~!vO}J(C0$(SLBx@W zZibA_Jf3UKeyyY3_k0{P=V505&zyl%x6XXFGG`mURv6*3oAgs=Hx^y2tyNY9gG{z`4~m5lnU=jRpA?1UcuV(d&4p*fJv>~C}VdwpHx z;d#v&Ilpor9X<~ZY5a5VXphWbX<*WdpRrf~9%2KVsAZFqt_^decQ2a$oe2+ay ztzigBi((>FDzV5>AOcadgzUBCybTlm7Iy#~S&4@^Nf1~_RrPVZkxCh6frQ$t@hCDz zh`A&;%(=kul+ta(wrLMXdp@6i7_%UO?G(KsQJ{47S^#r(jF2z2v|g78X+uC0l)v&SfDZEa8@Jd>IsjxW?U zqjD$mQer{$PEv2!TJlp6LuL@UD!VNJQo=0J`7Xo*dp;aa$?YIT72MqJ-T4(L?(>l1 zrMsz>UTpwhmKWa1h`(O&Sa_f!%rLvMef8*cHgyS9T-9Ql`haDNBNXILqX@(QkSOz8 zU&OqWG7EGHbweA?y3#mBMX>GL)YbABx)$lJ**pjetrZY~?9VW4OdT*Atee)H?l_4t z6$ha6aSfkU`Abicp3QNY>m&pEbu})^=-1#8JiBx z)?v}Uc&G`p98YKI|4W^IY?9CC6VK1qGdO|(TG+-UZ*Sl6x4-=jywvUq@%d@SP0M1r zCf~k&Lrn-sE<~b3+jqH??_II#uZW+_%{K17FktAQjsj|w!**DL6$$$BwM; zJ!Q5;p)q#abqp{g8aNL$rI+>vG|iIDH=?pTB*)RK z)YPm_xisE2;2*Qk$$}<#a>6Crl7NV+@F%DE}yqo z2*wppYWUsxbE*#OLg!ECnLfT4PgoH$WOh=PrbSO&( zPmUVnJwsTOxq!HMgaUyCV#q}p9ViY1et<1Ats@xW^jX3eqt;s7BZ8gpahc%84(E`y z;1o9G13!a^lyzPZ4dx*+ghJra@8;j2tVfsJl^?Au8fIc#cwjuAPkemX-|K3z?zL7t z?uJVI?Qa&ICM@Q^*jD`U#~*k;pU!o-;oJ8Ie*5;l-)P4DSkc;+7Wdm}k)0R$*)BLQ zMxhkRWY2uhXO&FMlk>P@X7?Ww;h5!mu_s0{+`B&9;c_Rt7Oo!hwV;#*wcc>MJ#fFh z8BfDUM)8$xs8tk-V)K4ijPx{AJ)~>W*pk1rc)o&3)2JExA=0JLfGRc-P%FkS@r_=I zjn5FW%DVUhKh3HmO_yX0ZGxoASF&7Ar>btP-Y8Wi*99z7B6El;*0e2 z`5Z#KjsUapDJYWz=eWtME32TM7lYvUkY%ChLG&9HSpFG%%%(vcjL3J{_A@n1!v$2c!4`>P_uIW2lPR+8U8_@a1u*@S^6E=ZWkP3Ok{ z=f1Y4^h*ds7$x@qEPrww3BB|TIU`8zavTM6Qn~1}r? zxeQLfO9xw8%q0;8c{m#S?+(UDz9$Np-Qm{E>iRPwX|;zcIQg%WGQZM<85~m zA*m)XEhFTCaS5I?2GT#p}2xV`Lfhg+2 zh2}G*oE#Ynkud+5779PH)h@hrP7IylH1A4v?_T-RTwWqsoW5FPgnD6E+mY1E#_*Jq-5hVy`D8V9oBJ z;&Rj@(*-zECM8aKS6z&ShCm1Ig1C;OFd?ry#RJp8)C=f=zoYEl2;+tUJ$|;M9CCO+ zgr5S@C?6Hj<@n;t#$2Y6R+xwZ=ov36v$Q%nESSFY<)(8j86HO`4eb)r*9j({M*~N; zNE)FPR~`vZ7TX!Mn0X6hp_!$s0MPO?^}?&;iU4|5qoZQ9Sg$#XGV+~WdWCTkuZ zG!?dy9a7vWSLX8{z8Hw4ShB=knD>m%ML(k>9#%zA`W%PpVbnJqF9$ zl)O(eGl_&dmtxxM*}OCc)#kx)lBPrjBnl~MTm?(2R!1OrM_wG}@Z&y$fLCdnt;8dL zByMz0#Lt0=nhJ$Z_)JAaTtp6;Y8ZdS|Bvsd1)ksa z39TJ&jT<*Mh2~xuPaWabnF#vx=TE%9zvK7ce_-EtJnn{U+-?u3Dn7Ok{Qmpzcs`#) z$MyMX56|cON9TBiD`;%I=IAGvv*%Z=>v@65KX())*&N9c4J57x9b-6)y0?h*JjN(I z1_kwWK$@L0my_FJAQf|7%N4AhgQzT$+{twC91cwu)PxhKV@|jwdd;~R#%w*Wg8r0> z2*X+KxY!-tmDrvlcx?&WxOX|xx^Aqh3VDU?aCF?h@^b!2sDt}u5o<+>Bp|yr**Ns;QERuMa4NZ%Y z3%TNB-SNl!JJxl@kM}43@#CjEI5PJ3({Hk4u?#ESA3uKJ=Z|NCM*-Ev_yv9}rMenp zZ{6@KygRmSbwZkJ!{wMymue67COZlj6jYQ}f#(yluH9HDZUrtg^0A|Bhe=;kHzR7} z=3HAnDO@TQ-1!DtZn!T1sA1bbv2GRne)qZPu^{jJj`#OZFjw4{2ObX_2QU?E`V&|b zO@NPmMNtBCLE(yz1{5fWDhdMv0dFf5D{29j5{rP^_eDUh1;zj&pprrQbt!hvNK?^5 zsA4X&AfL$xZ^xYoN!jMJPEvvw|KVY#!Hf2;YLf=D%iL|Vsy9eu?7KpB0pJB@bLlQ^ zz5qKBxDi+v4{KVmEX5Sz$po$^V1(IyQwKtow><}Z+g z;6PY-!6#3gi9qi9Cg$W*LH6PC*Yj1Hs;`aGc}gI{wyzFbc@_<^b?9<<*3??DuV?G; zc;+*Tmor7Wx+932YzQ4wSYsc^$iDA~-8N>4?m9xzG;T)W$I^K`QRKPZweUVQEw#6y zs*0T=CAb{vrD*0(slaWybppUHM}`yYSg5qh!@1dIb%*AtlBIJh?EVNYl~_T94CopH?&-E}u#87OHn=@+e^l7*E_ zRV$Ge5%9hfECz#^8HM}cp*Q*Ox)oP_8BtWloHz?m3hC$ef!YixE|pPKa3cm+pq2-A z+WlTorAE|<6k4#EyAPT&Y6;(M%M&4D7CICryeyVK650`=$coc^wL6!Ch!!V(2CKC@ zkozEr-G^i3S9pZ{JQuo{rz;V$m~$f0vgAt2O_01hlY-~A9qFMB(PrPpnQCMxXQ*xDXq3Xt_iq3Z#w()v#TvK z93R(fPFLjcLFBZDdP#^>;3f$Ia-@Ky3lvogV+n{Ki&CXHcxxr8={(hz>&*Z)< z&x!H=Nh34}w#~<}9-FR-Qxa0Y8F9$x{`2#*e=p?J*{@~xPdGR$+&Ae<^+88au zWIxB=M~GeevuhjB#)#Z5>HG#9AD<(SBsBRQmfYPQ+3kh_6}Q@}K!Lr{~U`idJ3S9|11 zzm|H4<*mmi8mr9UT*hSJ@UTvYy=foGa8XO4N z$gFKHMV2^E2T|2$kbQH@MaFa8?D#0Uk=F%bcLJpd?aF)&T*~x}_$P@_HhL2DP0Z0Y zL;+UEaaKrOdj!1~RsQ@8W^&ozVGbCJA}{<5#C=CjFnr|W|an43NjdMt^O~7JZewlVH^Z1vBVpaUTNHLO_!%>ymWM?1u zv0kppR4mBV zEhCzWh>EC|+udZUG#Jq-i9%Ra9P>g?&=Kk~8aL{zVUAU}WR(a=QA|%OcCOux6rm<@ z^$3yiHfpWpgg`mgOb!l!(xDyG-cJ8&GM!e|UA?V?Njc#T;UxuA&7|CJo{JfEf$mm{RKD%9crY%_iKJNVjZGFviVb@5$gGk5qbQU%&I6{Ywr&G`==zQnO}xZok_xr zBV9TBB4@WCefB_+M8tR>B3PFDz}lZT-qLxgWw7BsL&y4ZlZ<;eVD4-yKNA{feP19m zxud;e8WPbpbM1xk+SU1e<&*I$bnS}xJ3s#nZ#23vkvpegxZe{GVL(`Zaes!K-T;bY z9g*h6*jqV>#q3C+JHzJlsB)-Q#-fN$$WKN#p6=uEs^C3PiK!@#;+q1>U@veOiXG&R zn}Lk-6zo^%81KA#Zm(RFLp2hEoTa=#Aum)xd6Y(nIngLfmPr~;G~BE-k3(l7ZC{f# zOJ|~J5x103PhlNKB2kt2^%LK3dgGt2pEzAf^B*@!Br7x;AUi3W&zJRJ+6`vaxxxa~ z>i!k*zk8^d+MFg9eNyV5q=d{BM^*_XPDV&voe*jXt2W~~lqsPYL8*hJb#QI8jjbaa z<2^!``g^*VYt9e$JlmXM(%fl>efan9-|_9+w{9~oaxl{4X11=62bOr=sIGhj=8p4f zBfVPe=5BvZKF#twpN$P;ly23WW1~~m9mqr=Bhe+ly}jYvw{N)L?_OlIVLl!3{(L-F zka5iDvk_9MG^B{$Y8eWztox53qr-?S$96Yo_lqw&W0w=%f2lZ#hB)ktukvNCHjP|_ z&He#YZ3}6*P8A)mBlir5AV3bqCWq50_eJp4<~AEdGT+xe78v*? zSBOWx-!m8J#I5?Jq5*@NCA(3cQ=tjhYb(A)#lBKsT_H%Xd_6Sz9{oA4$@TTQ;%^M! z_utP*QohfQqCqbmZ#xl}rh8?UPKW8@RFpa*kkNb1dyyRDk1T7MRVUwj?I@YEQTpZ zEQbo^sQ3v)v2bZmDm+`zYEKbtviHmf)#eF%V%2{E>cY6+Z@AxYebco7t3%g)*oD)j zP57$^^DFb7JTAx_jgd|78@d}&?dv+A6A?*Y{J6smEL=?05rW{A957+&X`#X2csw5X z?YD3E{{5ScN{E2E4OY%s0gydM%7yulh(LG05xx6Aaw+x+_U8Vqg*zn?V{h6!5D|qo zCvrK*qXdV;pU=*@h?b&-!(Vfo$dKlj*7yytvP4Jmx?$Fj>yagg6~O zA!9K>b5wm05IZ4s+U)o&FV6RA9M`3bq>67{z@b!m*Plb2`$|WUWm_P;e^t z@Tt+s2dJNlee}V=7@vL=S*_cchhM`$4Au#u(D7d97rdA#GUoUN$l(YZ9FjrW8{?Te zD(||VOp11o0La)k^83~L8XZkszARXeU^FJ8c6fAAiLnW#KjI677Z$;t>_Ma?EvN(D zUkOwj!Q$vEAkT-{JDo)yzz$h;^=&^du3+EO0Vcpit z`E~AiyCa}Syaxnr1UT_Afp&}U(adPh1G%36&K=$>1FrdIjG1*-P~?R%Hm^V>GUI#O zwu^^M2OdgBH6j@9@p$yt+EXfJhGT;h(&dX&BzKQ`chj=sk;lE#kEr!PE~YLsK6Cg~ zhb9Wd;Mj|sG1&Gqg zcG{2)P2{qn5Wnnv<2BcHJt*C^3o z#eczxi*X>~a%A@Ep1)EuM$s%H{cvL6oP9C^NjOl9K0cvb=lM7!=>)MIG47;kt@L8# z_?ZuWd(DAt5Li zvjr!j>de#{iV{(+s#>#|Rm^%Uy9C{4JVINDsPi}0!wf8wSjfjD!&oF)vp?F|?Z0b6r>OJe*J(w&T9pa9TJ^ zDV~ub&|R_b4b2e{?r?B({d#pN^3wp*KrFwdtWFFq(zzI!R}xa!b^AmSfD5524XK~@ z-0NT!53C?8UKlJ6AV#~A3YT!6t=v6bN-4O-cuI}*7!IY~YbAUOIzoUi(XzPq^9I(* z)U^)xP7mxu>6s=WX&z;nbXu6lpu94uiH^}94aIQNb!Z5>fm`yKD5U`PnjEITYy0IhTmKUriKg`Iz(b*|yQAB<|~Y2Dju{a@Aa9uF+To6i1Tw4s^tLF!Mn2 z@z3KE>dCym`-Kp%yS}13H`-I15LzyaS1eoPMoUY^?}iz zypL?n#5HnX>2_Nb%Gw|*x+}C;#z`bkI{L2?${!!WIdQD8C8Z*H zT9l};Vy@E+4=t@V_C+LIKq)=+F%DrTkrsCW-baE#ZiMtALqwAE zrH^CC{=KbEZ1q&k;z+@^`C{R-)9v|b3xi+F+X63sy6^f>WbFHHHp3B7Pve|@<$2~@ zz~RwBg0j@az)u_nFETzqywmP6<2p!4Uys_TFJiC4yJm#rO2zVe-aXFZGolv(ZeMqp zxa1^JN?|RfKxscAGVy#2=2cUX5FCqF86TpfO696J0nFb1N^*I1&c-z2_L35D6`(f1 zW=9PZ6L3njeBr|~xu){3kfhhB0bRI#_R*P6gxf@%y?Tbbhe)VM@Sj6mu9}{~?&6nf z5qg0b(wE4?D-WVya$Eu#oQjut*aM*&(RYPdVCslG%5Y$qc!`vKG3X%F^ye~)0|1ov zB}vysCnUZ2eobP^g-j5Y^bDH9MFC-eNEFAtr<8xskE^4BLE&W93Q-~^j-Z!a%~6cW z6eobNh|ngD8Ok^7P#9v4o+wNa7Y~@ZmxrQ3Rkc z8LwOg^K5j^Qy4u*FqnD8gAp>-*bHK`=&B6AvG4c$DGV+9W#oSwH$d(0nUSFg))F7X zENqbb^Yh(gxrO`t#h4>^m(4r-ko?sW7V}5CZZ0yo5{gpiBG9E|5d-^unE5hJxh?8<;Kd)RF z)Js$9vZiCoMC+Udl-I|XYcBKYdC13Emyx-toy*0iB6sH79DE0yxFVRJWuJ(+^i*MC zXtDQFFMea1O79&b~x-M4pq!(AQVVOoVDOmC@G`X z%50klH5HZCbZ-)AXB>8;s;ZSu@=8Q?aun&{PMv*qu1u=(hBuEx=!Knje?I3; z#eFk~?6Z*TI>JvvyAvfkA82f1rbeori^O3(luXv*xy+ksi&S8y<15xRBCxz5|5Eo# zxHOzjF{vcHOXv-Ck@;#&?C{)`5&%HG$$-yj!S0bVlFan%Wb^AeI)A7 zPuoww9|(Oi`O6OiX?TeH{TwPg(LSyqmBu0>M1^vbSbSn|6!Ih&4z^(@fkDB{szw53 zfW(T9;*By#|D)k)63(M8DN&Fp1$l?Ptzf1e_1-xabXatAYpobPg9}E_@<1mzF{(qC z>n2|IJFT_il@=$xKJEL?tu|5vWQgOVeu6=tqUb{Muz zAYD&=L4571wqq=lZP<_da!l|g(53fBMjnO@-0l1Ye~#xcdfOPM11f)-(=lJG%;5>! z{QTcN|0eFy+k`-OPJs^hDNXlC+<)^pAKE=6hOsM!*;o(DjDkmpksS^-2X*$L5lKlc z1H+s*TT>B<@oB0aO7J$aiRLguK{D~0Q_SP%nOVK9%6TZ7)g}FYfDkiTt#r)YY@`Q5 zt?YRqY-uIFxKUFXVqDdx!c3(s6$~a`YE-J)cj?j-642?E9{*HSBC= zTYeKz$YpRa)`zT;zHx}1u-pAU&ZAWNT)*4G3a2cQF}P>nHkUy*w6>u&84RCh)FJZ^ zT5I^Wuf8d7{<$#*a(P92Ec*J=P4Lx1HbdGud!=%Lz`NDt6%w+k%4K}*cz`;tw)djz zeqV6A)$WbaQJh)^E{2UODwbt5>x$^|IlB5PN<26*TeERfAqG7dk@prw$d4aC@c#ae z=kqy|!aCYv+IB7l%k9=vCrkJNke_!oq=VJH16(a}uMGRQwQQuPcND1YWxEJL*W;`O=L!vwrKUKfBq?QXgc>ec(e(3dPH9u=t z8>4LdHF3L-y=0Q4x?x}-60XV+&q$(aT+kxZC!2_oBOW9uT*q;RjQ1z^=l|f$*jO;o zM*$O1BV`n19v_nf=k6Qlye_fO>AYpLt6%+T`{?Q_(Gbj1&{tvOe}W4W*PzAK;4k4f6=_xr@HfQEXd!QvQhMVUA=EYe+VM(DY01g^`{`JQ*P-)$G@LW# zOVsDj{+W|o^&kWMX|=~Iuj}$t{6{`n3^gHnuXF6z^cU`&XPzW zz0i0*pB%R3mS+;!jY73)x!tT-k#5yWEQWj(0d7nxW~x6fs$_|dT5JyQj}5eBhP_~0 zf1vF#m%iXgsG#jDo*$nbnq7)HP>L{~_lnPtA9(-yqu+?z_5^gpQh{4l6tbJ{`BZ$i zC$v3*wxggy+d%}%i?b0w1r0_zv<^J!jb!$fQ7f32 zq}kuQJ0c;ZR}4nQ{r-mU-@p541K_j<;|3E=|qw>cR^i_Xlp(ioJFFL@foC z7cAulhP!sQ9b5};)gG+pN5lI0fj_pNP*p1&ZiI(;!E>(wJs|sUSe6C*X2jBO-+sgG z_CO7Nyl!awj$18m5>~v}j9F;Fr2<+O@S_e3^1`*xbjiJJ!_+IrWXi^v-U$hrvh%v? zbCmMwhHVc^Clk_w;>N8mjkgR5z%^2O;}S<73Ezl zV`&%c*iZyeG)KjnrIJzwFDycvhzQno)l!PymWM9OqHYOJdW_G+%((h^#V9i^NFfFt zNg=50)C3F_Fp)|#3Ij9KjTseBEYiT#!2k3{#zkc+tl;X{tF1NEv}whdUEgy^!pzHg z7e@1R-bI*dInn_4#0a;~h@dTj={mmyB4VhCms+J1ZfO==tN@`vpo;*tR%5a@T$&1T zIf#T2BxUcF;QGdnM9?5{1AynY_iiJ1)Cj+f3DQb)lg3aCSx>Lr;D?Rv}g%ZjSTdWQxiG6YZ{wzVwQSZm^jA+J! z!@hi7S1g6j21x$-pU)>go*(_cZ?_xX?zi5>-|u(qkB3PIo1qtv`=h@%5kdG&Y|W04 zA^9W4N#}1!&taJyYnCDiW-&62pBst@r6U_iN4xT`_$*l|cluMmmXdaYWrqaul4CaBS2`kTxyVT4 zuT8e;_q7|B4P2`fK{E5=I;Trac)()WOB@#aP2;}r?v%d%vu`VH@@S%nZJ&lrJtJ)T zw==`m$2TrSAp=_%J^ z-**V<(1CuXt&fqz_!{fU);bq4@o&8daQSDT67hRBE;+u}C9EXFYsT;Y_S)>&7-wIExD0z6iC;4;7;yAuL2;pPKLcqFnX0(xp#c{9C=kRRia25?}+l!*`RKWDGpx|3p>rNLW^}vcVNt>{^UZd_VduO#Av8yhhfQ+cQ0r2M?2>@k zIg;u?znoWJNlb&#b2TT@8BC%YPK4uuj7u{|VfXWM z5Ci8TBZ_xb#p7`s3WrxIz;n^uH*7j@y3PfgxB#72dL#&E6-{>{#Y=v~)%g{@+Av1j z=X}ocy_ZoNo%4@$L=LV@#;nNVFFWd5>t%5eUy=QCRS4$d_A2AX?x%8@TAF<@u9PxY z>8`&*`mVSzd6Rvm$a%$4Gfu)buAdmyCE5cLR-*j4GQP zz}ftr@=4;!etZb7)eFtOVH08fc&3NOtr^MFCDqdVjNLzxqj1a~jq`9UHru`pBsc4v zEtU28tXt)Gl;9RUq^5&Xdl%=tu-u5#q;@zb$#M?Tkv??94Xp8^P%GLxZ~|^V~+Ln z-4+wsvF$)*>IKHKEZ7(6SrKn3~7z#~kqc6YSX+&M|4% zNZD5f#-Lu)+2?`=g6}D!{q#8xhgAZ-R{dQR$s*F#aeY)+Y|P(egYG-(!e07>=hDHK z$xRA}HHx#;ea}$K5`lSSBxJ$&QrSHd%nJ==;xN^ci=tvSObHGp>tWUF)CmM9LJv<3 zK1L?W-7TA_A?yz=jzJ)HrAbJ;-|+yA1n(l}(Py3oGqb`Y;YZzU^)U+6388*IsFYH& zxl_C*N5>-_P3d;3!TCrLycArE*~M_43EPMA1-l&8c+(N-2-IR-_n|w=MMj1rquYG`^uDSp6O<1&5)R0S%c617#T$g*f)xi?4c3T z!sqje`+Yerl5t++T-t*&juiq;dGgkkA!ZBjh{DC9Ik3AUI1A-cVH4*rq+oo?m60Q@ zHRsTzfFtX4%8;U{7fzK|E<+ib{c2qD6^AB#4PIH-5ARQheR4Rb<}p?j*_?_P_*f|y z7*XtoxgArzWb?n`jAYKmD+qja-<|zkUcXoVw~lxbF3pmJEnb#Gk=}O+4 z5ye<1@+OzB4<{$bOU}Rr8g-?nJ0TQwmKe{?>U>_WubmEDg=6Ep=6UqYn#so_cimaS zdK4KKh4-H*B(8jf26MUPPd-!A`_7ymyx`o-Me>XUHkr-b+<=Ozd#THb3x**}c5>(;_F5YDd(3&}Pw$|``J_oDm$QIe#ifw;_sbb%^{_{Y@ zVHea|(DpWL>PPlRpb({xZOn$6hJ`8E;`7XRb{C9sL+-lzoOv))8hwYwv3C0c9LZRfbuL4KO~ZIuUIz6 z#G4>FrL5*6VeX)>B&uI+*fRohEZXw27#Jeeqd<>MM~^XCjvUW^2V*f(f6+bjOLHr0 zl(*>|(1aMY&IvFAG7s>(s9Y8jo!6KG(q?k#tD-vRD@t26-3&}tJ1m_}%#sitReVrLqQXu28569&HD1x}8 zB3cYVWN;5`q_jT7zNKoa4GJQxBZeHusfxC3-6PDPkYq|6Bj3ZbpMti4BfwNHh@Xn& z`q{0-U2?_DWXs85rbrX{vx_r!dfh~kw$8~wcJ0W<9X{^JLpSmQfdjQ5q8glz(Bn>B z3nh0@N~R!DNN^B#n2GWO)MuhWq-6S%{Y@A1&JikE?|6b+cwlf{{P#U zzIZX`oxAK%Z`ki8SGyMrZzgHRR~}Vdp&IdTxyZ@K7F?2CfMhgg-9CrWN}jF9IOW^7 zZ}`h!{xbMj#3mmKf*`=PwwdzAQ(yn<-~QI$>vp@LV2o7fH$D;6Ohsan+1=AsgYyxu z6NuQ}s2g5crp^d`bD>F>?xfkc=DLsOT?K;^Vqa*dnQ6bDWXyK>RfqB`J$~k3*!}(W zq8Zn1&Zvp6+pTtK?$u)cd_D)Y(Xj~~ooKd6&P7HLEN2JItIzq$%qoy0N$me1wqBWx z9mGyMmd!W0PRJ8Iq`J&KrS__@3F+x8&eW?+puzWJw&e$1&hW#jb2b$lkgth!I;bNq z6edK3PnSquc}C=Qb9@HU{R@40Uz$&hTylQ;_1mY-UPpxXlHZ{Ek|%O?zQ0o4?b@!# zVJDT14v5B8QF&Qt96S1nuM^#IWI$yUULm7P?W^%>CX$Mc`(rYY5Jh4(9z%|G_x(@( zyyc=H7a0Y>KJ_cT$Z)l%>Crqj)r%o^{tAVQtJezc^f_qw@9v=%_kE4Zs@MX~wJrpJ zML_$$6Bn?mfP{*wvS{aL^qPd3#k)&NVOZoej6gE{^(*J7_|J7S0tmv{a|~hW4_WdH zIA-(caBGYun2J66LJ-|iDnP9OXlCQAEvZi$-rgP{0``6LNcY2L900cc3DJhu+@aFZ z1m@Z$gqaB1AHIimhU>bIi!03?a6^*~qC2=y=T5`}_ISH>L#hL&bp(e9g=nGefzYZal|Q{_($7L zv|F`8thscW*(AK1`$a@H4lgt)FV4IO>Rv{HklEOy*ak>46eZuke;+oqc%M@2zIys~ zVy?qjP5UgoeK|(CN(|1$P+casO^r>I2HAEgG!UET_v!17b4A*=yM($78^EOC_~*lV@IvGPW-e2LWEmuZ|d_tIj_^XIF*gwGIMP<3nHieOw*i)%|q-{_8b(F5a%5b%p+EUzn?L zQ1k4iehm-C^E4LnLJ@S5QqPXJR+LX;rJk=MxU%)mj-O_@*1jY}#~QS!nD_KEbof+^ z|2^}a6fL-nT1p`{r_VIfR7%IENqs^d^G;VhjAT8uo zU97WP*H7r)2I;NH8V*JFU_+p?W7~`;)3)7Ge_8*S-WNZvl+a*E$gA%+WG<6?ycK zXW}-)Z}B+V?>Fk#g~?!B0b%d2Uj`ow&9M?heWpI!XajUP@;Jr?uX9nN+nyC5d8~K9 zscn*i(y8DYcoh?h!wV1Nh+J?-6#G!<0AEUmUr8;m3jA0o3lX#&NJR`x3X@UBG+6i4 z)koA-Q1zvJGUqJiAjo`AggWfZAN{qj1$H= zz9Y+r_Of`f7$m5#+{j-i`_eEn8#y;f=b28=&rGWC%@n-h@W!KYto7|ssi=)XvZAH6 zE!}U147+buH>R?^sSWBED$wdLOKPRR?drA{iYUq9SP`P6V?94oi&dnf6+%qvwiC_w zQU4+znUqpW|KN^fglv^ZWr%0kzu=Da2ODn8l`xD*ksRIP zkZiW~g4sUJ`8+AJcg}8-75)IKG<{DdGpyE)f(A|g5$fkR;NC0$?h?ohUdoX)In7J+ z!xUVEjHDPc!YBD^?yNGYG|OubUk7tV-1pszhqpH;c^Z8Gd_Mbo8OPz^0@PZE0ITrb zD5c=-{=l|v`0lUQHyj;p%QxCiUE;p)*q>&4CVR8uif;pw@&4lnK0ZFsXvJ^8nf18& zaCr9yGfu0{TTyXYarI(tD#SV(E@Ax{5zukee1Rg-u=qzOJV&sPMp^nxchl>TwX>t8_M(D%VU&r#(UBi& z5xzt!uG9;c=)r_yoRFp$9vd{-U0=D*8dpd!IRb>QL%m*d&VJ!LaYi!gX|ysIFiv*6 z4uX5>-4aGoqu)rIikLEut8#IDg)Ci3gkK>n0MJNY5<%x<4&NfZFw~M+zTBUu&d}|| z(W@f$KujX#O-^BVuTUhF6R%+)s;1(Y6e^jQ5h>+~lc8Qbu&TB+DxpJhqMR7#L6n}A zC0SjnzI}VxNk=m%+Wm}X5NYDF5UOJb-M1o+pUqG+pcwX_DHP^u4q+5iDR3!8YOU)3 zAD+q@@JxoLG}(+pmkJO;lu*QuhQ%lt+yE}sq^r>hrbu1@5RMy%rYcp@+KN&Z^WztI z^sGX3KZ+3*>!w)Ef8R-Pwm>uXz2W(^`R?=i99Z{61tCX16Wb1{^(qkp)Y+d0J^CrkVlMvMfD?_VIW)kEQis zr*I7Y?b~;#D(;THR4#qC8^^UQ3qb2>G+>;OPkem*MB8`V<&Ii>Ce48CE1v5IK0bfq zb2Brqx4SzpE(IbB6gHlbKqI{4&}PSR*BF=BSY=-gnGz?0@-z-XTJ-Z*n-@tMH|#t* z$z!noz20fJ?u!w>YjCK9sD9i+NIMld^n!EkhEIVi@#^y0jD$1@#M0u0X za>jU$n>>f2EzfZcVH%~9g$^gsD_@Swk%AZAd93wkZNXm=Sr3x=n5-);NMm-h2~7#B zIbFFm6s`vs0geP{?bodJ{ZCLtEjbo8rp_b8mlEPH3XELf9mL^tSlw9QPKbzlPE5a- zy(sr5JIn*K56&Pw2n0uWhzF&bTd$t@AMxCFTZq&Jt9E;9uQxPeS-rW@JUaj#7UTLt z_8J8Q18ADUkdjk3xhj82c zLCeaUA$8NNlZ$A&HdmYH@Z4e~_8sc5dGn`(xu4!++xE#Fkw(|tsbI+73%OIi+SsqS zF|U*yXO4qjcChokldb=+)M~SbP9}a{Z_H=n*J_VjrZiXvizM=>P7*6)|}TLy6PWVD{Mv2k$6CR7Etn zYmw6u>c{E_8FQSl<{@Pw73NZSu~`iTV1i_03Ob+|xXW0{nI^SXag#0;5l#gN`K%;x z5ulJS3L~V8u+~rELhKK+^ci|MejesS;ZYG%F7v+_#~$n6x`lXToaBcnii>?;q1sT& zt#AIKE6%wxxP*fH1_d6vt&CjcY>^x+l{>?1ie(bK+e`9UUMO?-oz1vFTOW-CX){|H zM?nx~S>L{W!*9R+b~tv1V;^ijxvm6ebT)aPr+d*A#LxJ%eAiB3v@kl86o35qiJw1z zV)65Es|Cwa!0xts*qR?w3AX17(q`3l^GpC~j+j}99z4yl!ADQ7;sAv${K#OZ zX$+NZg@p#InjB_R-3jYRrZF8)b}4YfBFlZ1GdsLs#a6-OfwjoeUtKA&H5G7dAfYmbuy zojD@PIW=)a)z;YHCXjeHZ^g9eVYX$Sk6!p9IiF&Pj5+RaHNa#pKEER2=Hf|2`ncq1 z<~%s%=E`KywPKVW1~Dy05wavF#9+?6f^-5YiS zft7$=Q7Q-x1SXIu3ZsfhVdi3U7cL10)npS6vX+;an3%abp_AmOb^?ZBIYK*P#uJ6c zi1=n_Fc@3Mkd33rNM>A@9mQASIws*cg3>aK+M~0bgAuU53Jsi#EL)vB*_a)_nzaQ7 zB+n+HbO~L?>mF&SwfkHICn9Gi^vz@+Np+c&6GcoWh7KqOS$4-9ik3-cu}PLJqkcYJmD6O999CXDN_!s`eVx=e--=5)_uT{O-Yxz1=R4lt-|``Z|Z z=JsAK(wIn&r_P#Jw3%uI@UXL7sU2DiaE z&9Z+co@f7hT4b!yd|k+9pN~8{{z@H@+5Op}c7EPob>q=VU5(*lQ=Fg43}G)f8eANq z(g}(2JdBws?d0X@(i6$aJgQZRn17=t487U?|kj$plOr%s#DM5i?0x}c?=ZZ zH2K`TYPIwAnGOE3YOHg7lutfHIg2H4szWj=yM=#Tk5FmRalLWTaVzkp!Ps0t&*MBFqk$WG8M7jlBO`YYmNJ zQr1ANfk~7|lv$~iqV;>LiUwK>XhYLhm`kaw7Ew+lLPfv}IRmsb1t}?nMG3XAKJGUz zEP$*i2H$%VK_vUmCjDD*TW%b>J;eduw36VS9dJDGa(lY@_#w z=2IEZ&kdxX`2PL78Ao}+0#vNDL0ZGY3{iktvD7y-ReXGW03x_Ai#fLK8(Lv((m>L{ zDkwNeb#eBC+Y2KyD`?j3kFiL1&h+8U zbsIZySfLR`$;bZgvvWtzlKGLLoTYc@-FdTF2i<@{tu@QC>1bGEcAH@i-vr$PU&IPm zJ~%PVgr^61+4b?<4pc`t3hM1`Rxe8SC@NDHP7MzcCA6KGY0y@k9Rd&x$5^oGlv9*h!X|p1YK&!;y)ifF^Ma4#yS{PW{ zr?T2gU2COMizuL*C}fjBvLcz4HHZ#I@}T;5r%i-Onh+5!WiiVM1?jr66|w~c1?!Ux z=&;MM3wXaR4XA3lHHIuPD=9Y+cF|Ri6xIoA8?>{j0?RWRos2#5_ZBCRWa&$gSvWb9 zA#pP(s=p2=P3e5E*y>jd-mA`Imbi%sbUQd1tCRn->@y@{h3#izk?$RKT?WY>vxQyF zuAA;D2_iC6D!<`>d^`u9MJ9#LGt?{Y1r;8Um|Wra+>iwC2Z1d6SIlhq$R)9q%||!w z31sN~-B5c`eC2={*EoAJ z_aeniVSkt#BVuCPW4*FaFrP}r1}106dEJ0JaZ3KK=u>) zN+B{F(|nwRRw^IZQFIS%ThmO-5}A#wUbUDFH1=^mJo-7A&Tm08$Ta`re5 z^D)}G4hV1{5A$`Kc`g0EL-}$KIi9C3F94?*qZ0+pYgD>HLgv5U9PTXC`8c2p2eW~Z0xk@Cqd!slA1^>dvBF7uFW@Q3- zTn1W0DFQV+0;;zKRp?~G!KrSKgUJV8h)BRhN|D^!4c$32TZ1HeNXk_Ldg%*#BGzb- znqMYf`t;vBwg?-$DlD@6Gy5IPnIF7=0vWD_&AkdtRrv))l}1{Kud=$=M=T&VK_bvlQGOcYJ(&4D;3CT?CvNh)9;A z#&JDAK0ylHYPFmYKd$HV+0#`mA@$zRXA}bO@9%iFCzfTwZ@>L!1=Qn?S{Ve3Vg8qY z{a^U~_uuiyKmLw=-|_8n!{7e)H~jY7H%BVoP|5;rPvc2|aa-WA?P|MA$ak~wf z$YhRiLZPMOOv3UP}8kSsS}btvfTu z<`QN`dE=?9AeZaeNQ}A)p%Ac#swbHt#sBOuEyPZmxv$O}Le3UBSw924Q|`r?Mgo)_ zvo<*b8?w(%cMiS|CcFyWyDALUbsabRa5wPJQOc5j=b~r{$5eN#>>YgY9>NV0UDF4F z`dWWne@->Zl@0nlKJE8g4bcHz7O4k;GE%T9Azjhf9^*ae>ckkD6Wb7EPxm(G^nB-_m5{zLuH8GM8spp{gv~RM z96epeb0V8uJm5LoLGox-hO3_5VveE)32GEF!K_~N0%eSOha)R92FHk$x{ajr|6|$#VbVRRhCKaw6D

- - - -From the japanese word [Maki-e](https://en.wikipedia.org/wiki/Maki-e), which is a technique to sprinkle lacquer with gold and silver powder. -Data is basically the gold and silver of our age, so lets spread it out beautifully on the screen! - -**Documentation**: [![][docs-stable-img]][docs-stable-url] - -Build status: [![][gitlab-img]][gitlab-url] - -[gitlab-img]: https://gitlab.com/JuliaGPU/Makie.jl/badges/master/pipeline.svg -[gitlab-url]: https://gitlab.com/JuliaGPU/Makie.jl/pipelines -[docs-stable-img]: https://img.shields.io/badge/docs-stable-blue.svg -[docs-stable-url]: http://makie.juliaplots.org/stable/ - - - -# Installation - -```julia -julia>] -pkg> add Makie -pkg> test Makie -``` - -## Dependencies -You will need to have ffmpeg in the path to run the video recording examples. -On linux you also need to add the following to get GLFW to build (if you don't have those already): -``` -sudo apt-get install ffmpeg cmake xorg-dev -``` - - -## Examples from the documentation: - -[![](http://makie.juliaplots.org/stable/media/thumb-3d_contour_with_2d_contour_slices.jpg)](http://makie.juliaplots.org/stable/examples-volume.html#3D-Contour-with-2D-contour-slices-1) -[![](http://makie.juliaplots.org/stable/media/thumb-animated_scatter.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#Animated-Scatter-1) -[![](http://makie.juliaplots.org/stable/media/thumb-animated_surface_and_wireframe.jpg)](http://makie.juliaplots.org/stable/examples-surface.html#Animated-surface-and-wireframe-1) -[![](http://makie.juliaplots.org/stable/media/thumb-arrows_3d.jpg)](http://makie.juliaplots.org/stable/examples-arrows.html#Arrows-3D-1) -[![](http://makie.juliaplots.org/stable/media/thumb-arrows_on_sphere.jpg)](http://makie.juliaplots.org/stable/examples-surface.html#Arrows-on-Sphere-1) -[![](http://makie.juliaplots.org/stable/media/thumb-axis___surface.jpg)](http://makie.juliaplots.org/stable/examples-surface.html#Axis-+-Surface-1) -[![](http://makie.juliaplots.org/stable/media/thumb-barplot_1.jpg)](http://makie.juliaplots.org/stable/examples-barplot.html#barplot-1) -[![](http://makie.juliaplots.org/stable/media/thumb-colored_mesh.jpg)](http://makie.juliaplots.org/stable/examples-mesh.html#Colored-Mesh-1) -[![](http://makie.juliaplots.org/stable/media/thumb-colored_triangle.jpg)](http://makie.juliaplots.org/stable/examples-mesh.html#colored-triangle-1) -[![](http://makie.juliaplots.org/stable/media/thumb-colormaps.jpg)](http://makie.juliaplots.org/stable/examples-image.html#colormaps-1) -[![](http://makie.juliaplots.org/stable/media/thumb-connected_sphere.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#Connected-Sphere-1) -[![](http://makie.juliaplots.org/stable/media/thumb-contour_1.jpg)](http://makie.juliaplots.org/stable/examples-contour.html#contour-1) -[![](http://makie.juliaplots.org/stable/media/thumb-contour_function.jpg)](http://makie.juliaplots.org/stable/examples-contour.html#Contour-Function-1) -[![](http://makie.juliaplots.org/stable/media/thumb-fem_mesh_3d.jpg)](http://makie.juliaplots.org/stable/examples-mesh.html#FEM-mesh-3D-1) -[![](http://makie.juliaplots.org/stable/media/thumb-fem_polygon_2d.jpg)](http://makie.juliaplots.org/stable/examples-poly.html#FEM-polygon-2D-1) -[![](http://makie.juliaplots.org/stable/media/thumb-fluctuation_3d.jpg)](http://makie.juliaplots.org/stable/examples-meshscatter.html#Fluctuation-3D-1) -[![](http://makie.juliaplots.org/stable/media/thumb-heatmap_1.jpg)](http://makie.juliaplots.org/stable/examples-heatmap.html#Heatmap-1) -[![](http://makie.juliaplots.org/stable/media/thumb-heatmap_interpolation.jpg)](http://makie.juliaplots.org/stable/examples-heatmap.html#heatmap-interpolation-1) -[![](http://makie.juliaplots.org/stable/media/thumb-image_1.jpg)](http://makie.juliaplots.org/stable/examples-image.html#image-1) -[![](http://makie.juliaplots.org/stable/media/thumb-image_on_surface_sphere.jpg)](http://makie.juliaplots.org/stable/examples-surface.html#Image-on-Surface-Sphere-1) -[![](http://makie.juliaplots.org/stable/media/thumb-image_scatter.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#image-scatter-1) -[![](http://makie.juliaplots.org/stable/media/thumb-interaction.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#Interaction-1) -[![](http://makie.juliaplots.org/stable/media/thumb-interaction_with_mouse.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#Interaction-with-Mouse-1) -[![](http://makie.juliaplots.org/stable/media/thumb-line_function.jpg)](http://makie.juliaplots.org/stable/examples-lines.html#Line-Function-1) -[![](http://makie.juliaplots.org/stable/media/thumb-line_gif.jpg)](http://makie.juliaplots.org/stable/examples-lines.html#Line-GIF-1) -[![](http://makie.juliaplots.org/stable/media/thumb-load_mesh.jpg)](http://makie.juliaplots.org/stable/examples-mesh.html#Load-Mesh-1) -[![](http://makie.juliaplots.org/stable/media/thumb-marker_offset.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#Marker-offset-1) -[![](http://makie.juliaplots.org/stable/media/thumb-marker_sizes.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#Marker-sizes-1) -[![](http://makie.juliaplots.org/stable/media/thumb-marker_sizes___marker_colors.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#Marker-sizes-+-Marker-colors-1) -[![](http://makie.juliaplots.org/stable/media/thumb-merged_color_mesh.jpg)](http://makie.juliaplots.org/stable/examples-mesh.html#Merged-color-Mesh-1) -[![](http://makie.juliaplots.org/stable/media/thumb-meshscatter_function.jpg)](http://makie.juliaplots.org/stable/examples-meshscatter.html#Meshscatter-Function-1) -[![](http://makie.juliaplots.org/stable/media/thumb-moire.jpg)](http://makie.juliaplots.org/stable/examples-linesegments.html#Moire-1) -[![](http://makie.juliaplots.org/stable/media/thumb-mouse_picking.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#Mouse-Picking-1) -[![](http://makie.juliaplots.org/stable/media/thumb-normals_of_a_cat.jpg)](http://makie.juliaplots.org/stable/examples-mesh.html#Normals-of-a-Cat-1) -[![](http://makie.juliaplots.org/stable/media/thumb-polygons.jpg)](http://makie.juliaplots.org/stable/examples-linesegments.html#Polygons-1) -[![](http://makie.juliaplots.org/stable/media/thumb-pong.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#pong-1) -[![](http://makie.juliaplots.org/stable/media/thumb-quiver_1.jpg)](http://makie.juliaplots.org/stable/examples-arrows.html#quiver-1) -[![](http://makie.juliaplots.org/stable/media/thumb-record_video.jpg)](http://makie.juliaplots.org/stable/examples-meshscatter.html#Record-Video-1) -[![](http://makie.juliaplots.org/stable/media/thumb-scatter_1.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#scatter-1) -[![](http://makie.juliaplots.org/stable/media/thumb-scatter_colormap.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#scatter-colormap-1) -[![](http://makie.juliaplots.org/stable/media/thumb-simple_meshscatter.jpg)](http://makie.juliaplots.org/stable/examples-meshscatter.html#Simple-meshscatter-1) -[![](http://makie.juliaplots.org/stable/media/thumb-sphere_mesh.jpg)](http://makie.juliaplots.org/stable/examples-mesh.html#Sphere-Mesh-1) -[![](http://makie.juliaplots.org/stable/media/thumb-subscenes.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#Subscenes-1) -[![](http://makie.juliaplots.org/stable/media/thumb-surface_1.jpg)](http://makie.juliaplots.org/stable/examples-surface.html#Surface-1) -[![](http://makie.juliaplots.org/stable/media/thumb-surface_with_image.jpg)](http://makie.juliaplots.org/stable/examples-surface.html#Surface-with-image-1) -[![](http://makie.juliaplots.org/stable/media/thumb-surface___contour3d.jpg)](http://makie.juliaplots.org/stable/examples-surface.html#surface-+-contour3d-1) -[![](http://makie.juliaplots.org/stable/media/thumb-test_heatmap___image_overlap.jpg)](http://makie.juliaplots.org/stable/examples-heatmap.html#Test-heatmap-+-image-overlap-1) -[![](http://makie.juliaplots.org/stable/media/thumb-textured_mesh.jpg)](http://makie.juliaplots.org/stable/examples-mesh.html#Textured-Mesh-1) -[![](http://makie.juliaplots.org/stable/media/thumb-text_annotation.jpg)](http://makie.juliaplots.org/stable/examples-text.html#Text-Annotation-1) -[![](http://makie.juliaplots.org/stable/media/thumb-text_rotation.jpg)](http://makie.juliaplots.org/stable/examples-text.html#Text-rotation-1) -[![](http://makie.juliaplots.org/stable/media/thumb-travelling_wave.jpg)](http://makie.juliaplots.org/stable/examples-lines.html#Travelling-wave-1) -[![](http://makie.juliaplots.org/stable/media/thumb-type_recipe_for_molecule_simulation.jpg)](http://makie.juliaplots.org/stable/examples-meshscatter.html#Type-recipe-for-molecule-simulation-1) -[![](http://makie.juliaplots.org/stable/media/thumb-unicode_marker.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#Unicode-Marker-1) -[![](http://makie.juliaplots.org/stable/media/thumb-viridis_meshscatter.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#Viridis-meshscatter-1) -[![](http://makie.juliaplots.org/stable/media/thumb-viridis_scatter.jpg)](http://makie.juliaplots.org/stable/examples-scatter.html#Viridis-scatter-1) -[![](http://makie.juliaplots.org/stable/media/thumb-volume_function.jpg)](http://makie.juliaplots.org/stable/examples-volume.html#Volume-Function-1) -[![](http://makie.juliaplots.org/stable/media/thumb-wireframe_of_a_mesh.jpg)](http://makie.juliaplots.org/stable/examples-mesh.html#Wireframe-of-a-Mesh-1) -[![](http://makie.juliaplots.org/stable/media/thumb-wireframe_of_a_surface.jpg)](http://makie.juliaplots.org/stable/examples-surface.html#Wireframe-of-a-Surface-1) - - -## Mouse interaction: - -[](https://vimeo.com/237204560 "Mouse Interaction") - -## Animating a surface: - -[](https://vimeo.com/237284958 "Surface Plot") - - -## Complex examples - - -## IJulia examples: - -[![](https://user-images.githubusercontent.com/1010467/32204865-33482ddc-bdec-11e7-9693-b94d999187dc.png)](https://gist.github.com/SimonDanisch/8f5489cffaf6b89c9a3712ba3eb12a84) - - -# Precompilation - -You can compile binary for Makie and add it to your system image for fast plotting times with no JIT overhead. -To do that, you need to check out the additional packages for precompilation. -Then you can build a system image like this: - -```julia -# add PackageCompiler -Pkg.add("PackageCompiler") -using PackageCompiler -# This is not well tested, so please be careful - I don't take any responsibilities for a messed up Julia install. - -# The safe option: -PackageCompiler.compile_package("Makie", force = false) # can take around ~20 minutes - -# Replaces julias system image -# please be very careful with the option below, since this can make your julia stop working. -# If Julia doesn't start for you anymore, consider doing: -# using PackageCompiler; PackageCompiler.revert() <- not well tested - -PackageCompiler.compile_package("Makie", force = true) -``` +OpenGL backend for [Makie](https://github.com/JuliaPlots/Makie.jl) From 031c0e76d212bb38ce81dcbfc801ce47b8eb7b8b Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 19 Nov 2018 16:53:40 +0100 Subject: [PATCH 0006/1328] fix backend --- REQUIRE | 2 +- src/GLMakie.jl | 1 + src/screen.jl | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/REQUIRE b/REQUIRE index dce3ad2311c..312ee779cd4 100644 --- a/REQUIRE +++ b/REQUIRE @@ -19,7 +19,6 @@ FreeTypeAbstraction 0.3.0 #for findfont AbstractPlotting Primes PlotUtils -#Cairo IntervalSets Showoff ColorTypes @@ -30,3 +29,4 @@ IterTools AxisArrays ImageAxes IndirectArrays +Makie diff --git a/src/GLMakie.jl b/src/GLMakie.jl index 2322e8d17da..fed88b9a431 100644 --- a/src/GLMakie.jl +++ b/src/GLMakie.jl @@ -1,5 +1,6 @@ module GLMakie +using Makie using ModernGL, GLFW, FixedPointNumbers, Colors, GeometryTypes using AbstractPlotting, StaticArrays using ..Makie diff --git a/src/screen.jl b/src/screen.jl index cc89e8c65de..3164b4cdc26 100644 --- a/src/screen.jl +++ b/src/screen.jl @@ -5,7 +5,7 @@ const ScreenArea = Tuple{ScreenID, Node{IRect2D}, Node{Bool}, Node{Bool}, Node{R # default icon for Makie function icon() - path = joinpath(@__DIR__, "..", "..", "assets", "icons") + path = joinpath(dirname(pathof(Makie)), "..", "assets", "icons") icons = FileIO.load.(joinpath.(path, readdir(path))) icons = reinterpret.(NTuple{4,UInt8}, icons) end From 7fc5a24d96fd3858cd6ca323055a81632ccc6c7f Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Tue, 20 Nov 2018 19:40:32 +0100 Subject: [PATCH 0007/1328] fix bugs --- src/GLMakie.jl | 3 + src/video_io.jl | 148 ------------------------------------------- test/.gitignore | 2 - test/REQUIRE | 22 ++++--- test/makie_header.jl | 46 -------------- test/runtests.jl | 7 +- 6 files changed, 20 insertions(+), 208 deletions(-) delete mode 100644 src/video_io.jl delete mode 100644 test/.gitignore delete mode 100644 test/makie_header.jl diff --git a/src/GLMakie.jl b/src/GLMakie.jl index fed88b9a431..68e8eb7c6ea 100644 --- a/src/GLMakie.jl +++ b/src/GLMakie.jl @@ -20,6 +20,8 @@ for name in names(AbstractPlotting) @eval import AbstractPlotting: $(name) end +import AbstractPlotting: colorbuffer + include("GLAbstraction/GLAbstraction.jl") using .GLAbstraction @@ -74,6 +76,7 @@ function AbstractPlotting.backend_display(x::GLBackend, scene::Scene) # This should only get called if inline display false, so we display the window GLFW.set_visibility!(to_native(screen), true) display(screen, scene) + return screen end colorbuffer(screen) = error("Color buffer retrieval not implemented for $(typeof(screen))") diff --git a/src/video_io.jl b/src/video_io.jl deleted file mode 100644 index 06df9cb3cc2..00000000000 --- a/src/video_io.jl +++ /dev/null @@ -1,148 +0,0 @@ -struct VideoStream - io - process - screen - path::String -end - - -""" - VideoStream(scene::Scene, dir = mktempdir(), name = "video") - -returns a stream and a buffer that you can use to not allocate for new frames. -Use `add_frame!(stream, window, buffer)` to add new video frames to the stream. -Use `finish(stream)` to save the video to 'dir/name.mkv'. You can also call -`finish(stream, "mkv")`, `finish(stream, "mp4")`, `finish(stream, "gif")` or `finish(stream, "webm")` to convert the stream to those formats. -""" -function VideoStream(scene::Scene) - if !has_ffmpeg[] - error("You can't create a video stream without ffmpeg installed. - Please install ffmpeg, e.g. via https://ffmpeg.org/download.html. - When you download the binaries, please make sure that you add the path to your PATH - environment variable. - On unix you can install ffmpeg with `sudo apt-get install ffmpeg`. - ") - end - #codec = `-codec:v libvpx -quality good -cpu-used 0 -b:v 500k -qmin 10 -qmax 42 -maxrate 500k -bufsize 1000k -threads 8` - dir = mktempdir() - path = joinpath(dir, "$(gensym(:video)).mkv") - - display(scene) - AbstractPlotting.update!(scene) - _xdim, _ydim = widths(pixelarea(scene)[]) - xdim = _xdim % 2 == 0 ? _xdim : _xdim + 1 - ydim = _ydim % 2 == 0 ? _ydim : _ydim + 1 - process = open(`ffmpeg -loglevel quiet -f rawvideo -pixel_format rgb24 -r 24 -s:v $(xdim)x$(ydim) -i pipe:0 -vf vflip -y $path`, "w") - VideoStream(process.in, process, GLMakie.global_gl_screen(), abspath(path)) -end - -""" -Adds a video frame to the VideoStream -""" -function recordframe!(io::VideoStream) - #codec = `-codec:v libvpx -quality good -cpu-used 0 -b:v 500k -qmin 10 -qmax 42 -maxrate 500k -bufsize 1000k -threads 8` - frame = GLMakie.colorbuffer(io.screen) - _xdim, _ydim = size(frame) - xdim = _xdim % 2 == 0 ? _xdim : _xdim + 1 - ydim = _ydim % 2 == 0 ? _ydim : _ydim + 1 - frame_out = fill(RGB{N0f8}(1, 1, 1), ydim, xdim) - for x in 1:_xdim, y in 1:_ydim - c = frame[(_xdim + 1) - x, y] - frame_out[y, x] = RGB{N0f8}(c) - end - write(io.io, frame_out) - return -end - -""" - save(path::String, io::VideoStream) - -Flushes the video stream and converts the file to the extension found in `path` which can -be `mkv` is default and doesn't need convert, `gif`, `mp4` and `webm`. -`mp4` is recommended for the internet, since it's the most supported format. -`webm` yields the smallest file size, `mp4` and `mk4` are marginally bigger and `gif`s are up to -6 times bigger with same quality! -""" -function save(path::String, io::VideoStream) - close(io.process) - wait(io.process) - p, typ = splitext(path) - if typ == ".mkv" - cp(io.path, out) - elseif typ == ".mp4" - run(`ffmpeg -loglevel quiet -i $(io.path) -c:v libx264 -preset slow -crf 24 -pix_fmt yuv420p -c:a libvo_aacenc -b:a 128k -y $path`) - elseif typ == ".webm" - run(`ffmpeg -loglevel quiet -i $(io.path) -c:v libvpx-vp9 -threads 16 -b:v 2000k -c:a libvorbis -threads 16 -vf scale=iw:ih -y $path`) - elseif typ == ".gif" - filters = "fps=15,scale=iw:ih:flags=lanczos" - palette_path = dirname(io.path) - pname = joinpath(palette_path, "palette.bmp") - isfile(pname) && rm(pname, force = true) - run(`ffmpeg -loglevel quiet -i $(io.path) -vf "$filters,palettegen" -y $pname`) - run(`ffmpeg -loglevel quiet -i $(io.path) -i $pname -lavfi "$filters [x]; [x][1:v] paletteuse" -y $path`) - rm(pname, force = true) - else - rm(io.path) - error("Video type $typ not known") - end - rm(io.path) - return path -end - - -""" - record(func, scene, path) -usage: -```example - record(scene, "test.gif") do io - for i = 1:100 - scene.plots[:color] = ...# animate scene - recordframe!(io) # record a new frame - end - end -``` -""" -function record(func, scene, path) - io = VideoStream(scene) - func(io) - save(path, io) -end - -""" - record(func, scene, path, iter) -usage: -```example - record(scene, "test.gif", 1:100) do i - scene.plots[:color] = ...# animate scene - end -``` -""" -function record(func, scene, path, iter) - io = VideoStream(scene) - for i in iter - t1 = time() - func(i) - recordframe!(io) - diff = (1/24) - (time() - t1) - if diff > 0.0 - sleep(diff) - else - yield() - end - end - save(path, io) -end - - - -function show(io::IO, mime::MIME"text/html", vs::VideoStream) - mktempdir() do dir - path = finish(vs, joinpath(dir, "video.mp4")) - print( - io, - """""" - ) - end -end diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index 2f81a62f79a..00000000000 --- a/test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/media/* -/testresults/* diff --git a/test/REQUIRE b/test/REQUIRE index afcc53a6a90..e5985de766f 100644 --- a/test/REQUIRE +++ b/test/REQUIRE @@ -1,13 +1,15 @@ +ImageCore +ImageTransformations +@windows ImageMagick +@linux ImageMagick +@osx QuartzImageIO +Documenter +ModernGL MeshIO -#generate_plots -ImageFiltering # needed for Gaussian-filtering images during resize -BinaryProvider - -#for some examples -DataFrames -RDatasets - -#for WorldClim visualization example +ImageMagick +ImageTransformations GDAL -RData +FileIO +ImageFiltering DataFrames +RDatasets diff --git a/test/makie_header.jl b/test/makie_header.jl deleted file mode 100644 index e63cc652564..00000000000 --- a/test/makie_header.jl +++ /dev/null @@ -1,46 +0,0 @@ -using Makie, GeometryTypes, Colors - -scene = Scene(color = :black, resolution = (600, 100)) -Makie.add_mousebuttons(scene) -brush = to_node(Point2f0[]) -markersize = to_node(Float32[]) - -waspressed_t_lastpos = Ref((false, time(), Point2f0(0))) -lift_node(scene, :mouseposition) do mp - if ispressed(scene, Makie.Mouse.left) - waspressed, t, lastpos = waspressed_t_lastpos[] - elapsed = time() - t - r = elapsed * 30.0 - dir = normalize(lastpos .- mp) - N = 10 - points = map(1:N) do i - mp .+ (rand(Point2f0) .* r) - end - append!(brush, points) - append!(markersize, map(x-> rand() .* 4.0 .+ 0.5, 1:N)) - if !waspressed - waspressed_t_lastpos[] = (true, time(), mp) - else - waspressed_t_lastpos[] = (true, t, mp) - end - else - waspressed_t_lastpos[] = (false, 0, Point2f0(0)) - end - return -end - -c = RGBA(0.95, 0.98, 0.99, 1.0) -aviz = axis( - range(0, stop=600, length=20), range(0, stop=100, length=5), - gridthickness = (0.5, 0.5, 0.5), - gridcolors = (c, c, c) -) - -bv = scatter( - brush, markersize = markersize, - color = :white, - glowwidth = 0.5, - glowcolor = (:yellow, 0.8) -) - -save("header.png", scene) diff --git a/test/runtests.jl b/test/runtests.jl index 2f5f2619108..95119e94a28 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,5 +1,8 @@ using Pkg -pkg"add https://github.com/JuliaPlots/MakieGallery.jl" +pkg"dev Makie https://github.com/JuliaPlots/MakieGallery.jl" -pkg"test MakieGallery" +#pkg"test MakieGallery" +using MakieGallery, GLMakie + +include(joinpath(dirname(pathof(MakieGallery)), "..", "test", "runtests.jl")) From 669d9e04b625d58237f7a062aca42eb131ec8c9d Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Tue, 20 Nov 2018 19:46:03 +0100 Subject: [PATCH 0008/1328] activate gitlab --- .gitlab-ci.yml | 6 +++--- test/runtests.jl | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 612599840e4..3cb4de7cb2f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -17,7 +17,7 @@ job: - julia -e 'using InteractiveUtils; versioninfo()' - julia --project -e "using Pkg; Pkg.instantiate(); - Pkg.add(PackageSpec(name = \"Makie\", path=ENV[\"CI_PROJECT_DIR\"])); - Pkg.pkg\"add AbstractPlotting#master\"; + Pkg.add(PackageSpec(name = \"GLMakie\", path=ENV[\"CI_PROJECT_DIR\"])); + Pkg.pkg\"add AbstractPlotting#gl-makie Makie#gl-makie\"; Pkg.build(); - Pkg.test(\"Makie\");" + Pkg.test(\"GLMakie\");" diff --git a/test/runtests.jl b/test/runtests.jl index 95119e94a28..120c6445e89 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,6 +1,6 @@ using Pkg -pkg"dev Makie https://github.com/JuliaPlots/MakieGallery.jl" +pkg"add Makie#gl-makie https://github.com/JuliaPlots/MakieGallery.jl#gl-makie" #pkg"test MakieGallery" using MakieGallery, GLMakie From e6b1be14805d0e81de5e984beb595c37c5afca49 Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 21 Nov 2018 10:31:34 +0100 Subject: [PATCH 0009/1328] Update runtests.jl --- test/runtests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index 120c6445e89..33b393f976e 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,6 +1,6 @@ using Pkg -pkg"add Makie#gl-makie https://github.com/JuliaPlots/MakieGallery.jl#gl-makie" +pkg"add Makie#gl-makie https://github.com/JuliaPlots/MakieGallery.jl" #pkg"test MakieGallery" using MakieGallery, GLMakie From 98af0a181a2e18bea60d8b00e5a45ddb2299b14f Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 21 Nov 2018 11:16:23 +0100 Subject: [PATCH 0010/1328] fix branch names --- .gitlab-ci.yml | 2 +- test/runtests.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3cb4de7cb2f..be9f36c7f9b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -18,6 +18,6 @@ job: - julia --project -e "using Pkg; Pkg.instantiate(); Pkg.add(PackageSpec(name = \"GLMakie\", path=ENV[\"CI_PROJECT_DIR\"])); - Pkg.pkg\"add AbstractPlotting#gl-makie Makie#gl-makie\"; + Pkg.pkg\"add AbstractPlotting#sd-glmakie Makie#sd-glmakie\"; Pkg.build(); Pkg.test(\"GLMakie\");" diff --git a/test/runtests.jl b/test/runtests.jl index 33b393f976e..c3897b7c5b2 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,6 +1,6 @@ using Pkg -pkg"add Makie#gl-makie https://github.com/JuliaPlots/MakieGallery.jl" +pkg"add Makie#sd-glmakie https://github.com/JuliaPlots/MakieGallery.jl" #pkg"test MakieGallery" using MakieGallery, GLMakie From f3062da84605d2244fbdc0cf3f14fd8b6f94fac0 Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 21 Nov 2018 11:54:53 +0100 Subject: [PATCH 0011/1328] add gitlab badge --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index ad0677cb09c..730e18790d7 100644 --- a/README.md +++ b/README.md @@ -1 +1,7 @@ OpenGL backend for [Makie](https://github.com/JuliaPlots/Makie.jl) + + +Build status: [![][gitlab-img]][gitlab-url] + +[gitlab-img]: https://gitlab.com/JuliaGPU/GLMakie-jl/badges/master/pipeline.svg +[gitlab-url]: https://gitlab.com/JuliaGPU/GLMakie-jl/pipelines From 64c7cd1000be1ac2bad733b5ecba639aa72f5711 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 26 Nov 2018 13:11:07 +0100 Subject: [PATCH 0012/1328] don't depend on makie anymore --- REQUIRE | 1 - src/GLMakie.jl | 2 -- src/GLVisualize/GLVisualize.jl | 2 +- src/screen.jl | 2 +- 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/REQUIRE b/REQUIRE index 312ee779cd4..0f46e9af355 100644 --- a/REQUIRE +++ b/REQUIRE @@ -29,4 +29,3 @@ IterTools AxisArrays ImageAxes IndirectArrays -Makie diff --git a/src/GLMakie.jl b/src/GLMakie.jl index 68e8eb7c6ea..9bfd845c1cc 100644 --- a/src/GLMakie.jl +++ b/src/GLMakie.jl @@ -1,9 +1,7 @@ module GLMakie -using Makie using ModernGL, GLFW, FixedPointNumbers, Colors, GeometryTypes using AbstractPlotting, StaticArrays -using ..Makie using AbstractPlotting: Scene, Lines, Text, Image, Heatmap, Scatter, @key_str, Key, broadcast_foreach using AbstractPlotting: convert_attribute, @extractvalue, LineSegments, to_ndim, NativeFont using AbstractPlotting: @get_attribute, to_value, to_colormap, extrema_nan diff --git a/src/GLVisualize/GLVisualize.jl b/src/GLVisualize/GLVisualize.jl index 030bc51d653..67f69e416fd 100644 --- a/src/GLVisualize/GLVisualize.jl +++ b/src/GLVisualize/GLVisualize.jl @@ -1,7 +1,7 @@ module GLVisualize using ..GLAbstraction -using ..Makie: RaymarchAlgorithm, IsoValue, Absorption, MaximumIntensityProjection, AbsorptionRGBA, IndexedAbsorptionRGBA +using AbstractPlotting: RaymarchAlgorithm, IsoValue, Absorption, MaximumIntensityProjection, AbsorptionRGBA, IndexedAbsorptionRGBA using GLFW using ModernGL diff --git a/src/screen.jl b/src/screen.jl index 3164b4cdc26..b24be23d244 100644 --- a/src/screen.jl +++ b/src/screen.jl @@ -211,7 +211,7 @@ function Screen(; resolution = (10, 10), visible = false, kw_args...) visible = false, kw_args... ) - GLFW.SetWindowIcon(window , icon()) + #GLFW.SetWindowIcon(window , icon()) # tell GLAbstraction that we created a new context. # This is important for resource tracking, and only needed for the first context From acd3fd703a67c98774422ff4914789208abcda31 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 26 Nov 2018 13:13:18 +0100 Subject: [PATCH 0013/1328] add icons via abstractplotting --- src/screen.jl | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/screen.jl b/src/screen.jl index b24be23d244..47df5203de2 100644 --- a/src/screen.jl +++ b/src/screen.jl @@ -3,12 +3,6 @@ const ZIndex = Int # ID, Area, clear, is visible, background color const ScreenArea = Tuple{ScreenID, Node{IRect2D}, Node{Bool}, Node{Bool}, Node{RGBAf0}} -# default icon for Makie -function icon() - path = joinpath(dirname(pathof(Makie)), "..", "assets", "icons") - icons = FileIO.load.(joinpath.(path, readdir(path))) - icons = reinterpret.(NTuple{4,UInt8}, icons) -end abstract type GLScreen <: AbstractScreen end @@ -211,7 +205,7 @@ function Screen(; resolution = (10, 10), visible = false, kw_args...) visible = false, kw_args... ) - #GLFW.SetWindowIcon(window , icon()) + GLFW.SetWindowIcon(window , AbstractPlotting.icon()) # tell GLAbstraction that we created a new context. # This is important for resource tracking, and only needed for the first context From a7686db9352374c69cddf5702f78d51afe462f47 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 26 Nov 2018 13:15:47 +0100 Subject: [PATCH 0014/1328] dont overwrite method --- src/GLMakie.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/GLMakie.jl b/src/GLMakie.jl index 9bfd845c1cc..74ff558f03a 100644 --- a/src/GLMakie.jl +++ b/src/GLMakie.jl @@ -77,8 +77,6 @@ function AbstractPlotting.backend_display(x::GLBackend, scene::Scene) return screen end -colorbuffer(screen) = error("Color buffer retrieval not implemented for $(typeof(screen))") - """ scene2image(scene::Scene) From 281e78d60d47c2ea8d5d0df818f5e8d2e685818f Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 28 Nov 2018 20:21:07 +0100 Subject: [PATCH 0015/1328] improve tests --- .gitlab-ci.yml | 1 - Manifest.toml | 2066 ++++++++++++++++++++++++++++ Project.toml | 39 + deps/.gitignore | 2 + deps/build.jl | 56 + src/GLAbstraction/GLAbstraction.jl | 2 +- src/GLMakie.jl | 105 +- src/GLVisualize/GLVisualize.jl | 20 +- src/gl_backend.jl | 74 + src/screen.jl | 2 +- test/.gitignore | 2 + test/runtests.jl | 21 +- 12 files changed, 2288 insertions(+), 102 deletions(-) create mode 100644 Manifest.toml create mode 100644 Project.toml create mode 100644 deps/.gitignore create mode 100644 deps/build.jl create mode 100644 src/gl_backend.jl create mode 100644 test/.gitignore diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index be9f36c7f9b..c7fa5377d60 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -18,6 +18,5 @@ job: - julia --project -e "using Pkg; Pkg.instantiate(); Pkg.add(PackageSpec(name = \"GLMakie\", path=ENV[\"CI_PROJECT_DIR\"])); - Pkg.pkg\"add AbstractPlotting#sd-glmakie Makie#sd-glmakie\"; Pkg.build(); Pkg.test(\"GLMakie\");" diff --git a/Manifest.toml b/Manifest.toml new file mode 100644 index 00000000000..8c34bfbc412 --- /dev/null +++ b/Manifest.toml @@ -0,0 +1,2066 @@ +[[ASTInterpreter2]] +deps = ["DebuggerFramework"] +git-tree-sha1 = "8df3d36e0286777d226f4fd4956a432b73425186" +uuid = "e6d88f4b-b52a-544c-a8d3-7a4f12cb39c3" +version = "0.1.1" + +[[AbstractFFTs]] +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "8d59c3b1463b5e0ad05a3698167f85fac90e184d" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "0.3.2" + +[[AbstractPlotting]] +deps = ["ColorBrewer", "ColorTypes", "Colors", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "Test", "UnicodeFun"] +git-tree-sha1 = "661703af6c5193a6ef2e7e5d6746abbcd40138c1" +repo-rev = "master" +repo-url = "https://github.com/JuliaPlots/AbstractPlotting.jl.git" +uuid = "537997a7-5e4e-5d89-9595-2241ea00577e" +version = "0.9.0+" + +[[AbstractTrees]] +deps = ["Markdown", "Test"] +git-tree-sha1 = "6621d9645702c1c4e6970cc6a3eae440c768000b" +uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" +version = "0.2.1" + +[[AccurateArithmetic]] +deps = ["Random", "Test"] +git-tree-sha1 = "47acddd710276cfa0184d84ebca07a92b324c263" +uuid = "22286c92-06ac-501d-9306-4abd417d9753" +version = "0.3.0" + +[[Adapt]] +deps = ["LinearAlgebra", "Test"] +git-tree-sha1 = "036ce44a518b912c43df728bfae274f8d8de9059" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "0.3.1" + +[[ApproxFun]] +deps = ["AbstractFFTs", "BandedMatrices", "BlockArrays", "BlockBandedMatrices", "Calculus", "DSP", "DomainSets", "DualNumbers", "FFTW", "FastGaussQuadrature", "FastTransforms", "FillArrays", "InfiniteArrays", "IntervalSets", "LazyArrays", "LinearAlgebra", "LowRankApprox", "Random", "RecipesBase", "SparseArrays", "SpecialFunctions", "StaticArrays", "Statistics", "Test", "ToeplitzMatrices"] +git-tree-sha1 = "88b3fbd0fcf6ad26a518d7809a796c7b19aea2e7" +uuid = "28f2ccd6-bb30-5033-b560-165f7b14dc2f" +version = "0.10.2" + +[[ArgParse]] +deps = ["Compat", "Test", "TextWrap"] +git-tree-sha1 = "37159c768f28ae52ef9af1e70669d25a68ba7d61" +uuid = "c7e460c6-2fb9-53a9-8c5b-16f535851c63" +version = "0.6.1" + +[[ArnoldiMethod]] +deps = ["DelimitedFiles", "LinearAlgebra", "Random", "SparseArrays", "StaticArrays", "Test"] +git-tree-sha1 = "2b6845cea546604fb4dca4e31414a6a59d39ddcd" +uuid = "ec485272-7323-5ecc-a04f-4719b315124d" +version = "0.0.4" + +[[Arpack]] +deps = ["BinaryProvider", "Libdl", "LinearAlgebra", "Random", "SparseArrays", "Test"] +git-tree-sha1 = "1ce1ce9984683f0b6a587d5bdbc688ecb480096f" +uuid = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97" +version = "0.3.0" + +[[AssetRegistry]] +deps = ["Distributed", "JSON", "Pidfile", "SHA", "Test"] +git-tree-sha1 = "b25e88db7944f98789130d7b503276bc34bc098e" +uuid = "bf4720bc-e11a-5d0c-854e-bdca1663c893" +version = "0.1.0" + +[[Atom]] +deps = ["ASTInterpreter2", "Base64", "CodeTools", "DocSeeker", "HTTP", "Hiccup", "JSON", "Juno", "LNR", "Lazy", "Logging", "MacroTools", "Markdown", "Media", "Profile", "REPL", "Reexport", "Requires", "Sockets", "Test", "Traceur", "TreeViews", "WebIO", "WebSockets"] +git-tree-sha1 = "07431ce3d1cb62c5ba7135e196702a0a60618a9d" +uuid = "c52e3926-4ff0-5f6e-af25-54175e0327b1" +version = "0.7.10" + +[[AxisAlgorithms]] +deps = ["Compat", "WoodburyMatrices"] +git-tree-sha1 = "99dabbe853e4f641ab21a676131f2cf9fb29937e" +uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" +version = "0.3.0" + +[[AxisArrays]] +deps = ["Compat", "Dates", "IntervalSets", "IterTools", "Random", "RangeArrays", "Test"] +git-tree-sha1 = "2e2536e9e6f27c4f8d09d8442b61a7ae0b910c28" +uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" +version = "0.3.0" + +[[BandedMatrices]] +deps = ["FillArrays", "LazyArrays", "LinearAlgebra", "Random", "SparseArrays", "Test"] +git-tree-sha1 = "d3c8a883d5470def5f5a2b3c5b20ea5080d325e8" +uuid = "aae01518-5342-5314-be14-df237901396f" +version = "0.7.2" + +[[Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[BenchmarkTools]] +deps = ["JSON", "Printf", "Statistics", "Test"] +git-tree-sha1 = "e686f1754227e4748259f400839b83a1e8773e02" +uuid = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" +version = "0.4.1" + +[[BinDeps]] +deps = ["Compat", "Libdl", "SHA", "URIParser"] +git-tree-sha1 = "12093ca6cdd0ee547c39b1870e0c9c3f154d9ca9" +uuid = "9e28174c-4ba2-5203-b857-d8d62c4213ee" +version = "0.8.10" + +[[BinaryBuilder]] +deps = ["Base64", "BinaryProvider", "GitHub", "HTTP", "InteractiveUtils", "JLD2", "JSON", "LibGit2", "Libdl", "MbedTLS", "ObjectFile", "Pkg", "PkgLicenses", "ProgressMeter", "REPL", "Random", "Reexport", "SHA", "Sockets"] +git-tree-sha1 = "a1c202b04c7d84e3e83dd582c2e0fd1d7e55fda0" +repo-rev = "master" +repo-url = "https://github.com/JuliaPackaging/BinaryBuilder.jl" +uuid = "12aac903-9f7c-5d81-afc2-d9565ea332ae" +version = "0.0.4" + +[[BinaryProvider]] +deps = ["Libdl", "Pkg", "SHA", "Test"] +git-tree-sha1 = "055eb2690182ebc31087859c3dd8598371d3ef9e" +uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" +version = "0.5.3" + +[[BlackBoxOptim]] +deps = ["CPUTime", "Compat", "Distributed", "Distributions", "LinearAlgebra", "Logging", "Pkg", "Printf", "Random", "SHA", "Serialization", "Statistics", "StatsBase", "Test"] +git-tree-sha1 = "1303f4b5d3c84f27a803f53646d68fa1616771b2" +uuid = "a134a8b2-14d6-55f6-9291-3336d3ab0209" +version = "0.4.0" + +[[Blink]] +deps = ["Base64", "BinDeps", "Distributed", "JSExpr", "JSON", "Lazy", "Libdl", "Logging", "MacroTools", "Mustache", "Mux", "Reexport", "Sockets", "Test", "WebIO", "WebSockets"] +git-tree-sha1 = "cd169880989669c2d48a72be9a2a691def62e257" +uuid = "ad839575-38b3-5650-b840-f874b8c74a25" +version = "0.9.0" + +[[BlockArrays]] +deps = ["Base64", "LinearAlgebra", "SparseArrays", "Test"] +git-tree-sha1 = "274280f8a1163553d2a5ff87770a490047147e55" +uuid = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" +version = "0.6.0" + +[[BlockBandedMatrices]] +deps = ["BandedMatrices", "BlockArrays", "Distributed", "FillArrays", "LazyArrays", "LinearAlgebra", "Pkg", "Profile", "Random", "SharedArrays", "SparseArrays", "Statistics", "Test"] +git-tree-sha1 = "91fb4c16507ddcbc2a8d9a78c7c4cdb8148cb7e2" +uuid = "ffab5731-97b5-5995-9138-79e8c1846df0" +version = "0.3.0" + +[[Blosc]] +deps = ["BinaryProvider", "CMakeWrapper", "Compat", "Libdl"] +git-tree-sha1 = "71fb23581e1f0b0ae7be8ccf0ebfb3600e23ca41" +uuid = "a74b3585-a348-5f62-a45c-50e91977d574" +version = "0.5.1" + +[[BoundaryValueDiffEq]] +deps = ["BandedMatrices", "DiffEqBase", "DiffEqDiffTools", "ForwardDiff", "LinearAlgebra", "NLsolve", "Reexport", "SparseArrays", "Test"] +git-tree-sha1 = "7231788899e26d91e8a15840e35f8e382ca0d2ec" +uuid = "764a87c0-6b3e-53db-9096-fe964310641d" +version = "2.2.1" + +[[Bridge]] +deps = ["Distributions", "LinearAlgebra", "Polynomials", "Random", "RecipesBase", "StaticArrays", "Statistics", "Test"] +git-tree-sha1 = "7dbf17d177dc2f38a75d3e304cfcdc01569bb722" +uuid = "2d3116d5-4b8f-5680-861c-71f149790274" +version = "0.9.0" + +[[BufferedStreams]] +deps = ["Compat", "Test"] +git-tree-sha1 = "5d55b9486590fdda5905c275bb21ce1f0754020f" +uuid = "e1450e63-4bb3-523b-b2a4-4ffa8c0fd77d" +version = "1.0.0" + +[[CMake]] +deps = ["BinDeps", "Libdl", "Test"] +git-tree-sha1 = "74853a75c26a4a73ac391ee26ee29ebeb5583d9f" +uuid = "631607c0-34d2-5d66-819e-eb0f9aa2061a" +version = "1.1.0" + +[[CMakeWrapper]] +deps = ["BinDeps", "CMake", "Libdl", "Parameters", "Test"] +git-tree-sha1 = "2b43d451639984e3571951cc687b8509b0a86c6d" +uuid = "d5fb7624-851a-54ee-a528-d3f3bac0b4a0" +version = "0.2.2" + +[[CPUTime]] +deps = ["Compat"] +git-tree-sha1 = "bdaf1b7ecf8eb6fb3843a1b0d3fccc5f727a49fd" +uuid = "a9c8d775-2e2e-55fc-8582-045d282d599e" +version = "0.1.0" + +[[CRC32c]] +uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc" + +[[CRlibm]] +deps = ["Libdl", "Test"] +git-tree-sha1 = "8ed645bb81cf6bb24e0dec6431ec5a0db1d6d005" +uuid = "96374032-68de-5a5b-8d9e-752f78720389" +version = "0.7.0" + +[[CSSUtil]] +deps = ["Colors", "Compat", "JSON", "Measures", "Pkg", "WebIO"] +git-tree-sha1 = "ff13fd99e4dd54f56eb064815f843bc992a871a2" +uuid = "70588ee8-6100-5070-97c1-3cb50ed05fe8" +version = "0.1.0" + +[[CSV]] +deps = ["CategoricalArrays", "DataFrames", "DataStreams", "Dates", "Mmap", "Parsers", "Random", "Tables", "Test", "Unicode", "WeakRefStrings"] +git-tree-sha1 = "4c2fe162202a53603b61ca18526c90711f469288" +repo-rev = "master" +repo-url = "https://github.com/JuliaData/CSV.jl.git" +uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" +version = "0.4.1" + +[[CUDAapi]] +deps = ["Libdl", "Logging", "Test"] +git-tree-sha1 = "da085c9c8668dbb37bd84573d4257b09cf33d053" +uuid = "3895d2a7-ec45-59b8-82bb-cfc6a382f9b3" +version = "0.5.3" + +[[CUDAdrv]] +deps = ["CUDAapi", "Libdl", "Printf", "Test"] +git-tree-sha1 = "94a3b9afb137e8d08136b334e51a25375557ca24" +uuid = "c5f51814-7f29-56b8-a69c-e4d8f6be1fde" +version = "0.8.6" + +[[CUDAnative]] +deps = ["CUDAapi", "CUDAdrv", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Pkg", "Printf", "Statistics", "Test"] +git-tree-sha1 = "debfe5af100e335b5df7109184e2e450f616dd1f" +uuid = "be33ccc6-a3ff-5ff2-a52e-74243cff1e17" +version = "0.9.1" + +[[Cairo]] +deps = ["BinDeps", "Colors", "Compat", "Graphics", "Homebrew", "Libdl", "WinRPM"] +git-tree-sha1 = "a427098d5aa2808504d94b8ed9fc5740ceaf71d0" +uuid = "159f3aea-2a34-519c-b102-8c37f9878175" +version = "0.5.6" + + +[[Calculus]] +deps = ["Compat"] +git-tree-sha1 = "f60954495a7afcee4136f78d1d60350abd37a409" +uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" +version = "0.4.1" + +[[Cassette]] +deps = ["InteractiveUtils", "LinearAlgebra", "Test"] +git-tree-sha1 = "03931a31f1b5c613088e02f55dd0a7458a6430c8" +uuid = "7057c7e9-c182-5462-911a-8362d720325c" +version = "0.1.3" + +[[CatIndices]] +deps = ["CustomUnitRanges", "OffsetArrays", "Test"] +git-tree-sha1 = "254cf73ea369d2e39bfd6c5eb27a2296cfaed68c" +uuid = "aafaddc9-749c-510e-ac4f-586e18779b91" +version = "0.2.0" + +[[CategoricalArrays]] +deps = ["Compat", "Future", "Missings", "Printf", "Reexport", "Requires"] +git-tree-sha1 = "64651a0315fc342e7e35d03d67b2da920937c9be" +uuid = "324d7699-5711-5eae-9e2f-1d82baa6b597" +version = "0.5.0" + +[[ChaosTools]] +deps = ["Combinatorics", "DiffEqBase", "Distances", "DynamicalSystemsBase", "ForwardDiff", "LinearAlgebra", "NearestNeighbors", "OrdinaryDiffEq", "Random", "Reexport", "Roots", "StaticArrays", "Statistics", "StatsBase", "Test"] +git-tree-sha1 = "741f83c8b7de90f4f9ed81f5f68a2808eebec435" +uuid = "608a59af-f2a3-5ad4-90b4-758bdf3122a7" +version = "1.2.1" + +[[ChunkedArrays]] +deps = ["EllipsisNotation"] +git-tree-sha1 = "4f2ed36578a061c2c765b280b143358589cd7bd0" +uuid = "8bab3169-4815-5aad-9f88-5df82062e999" +version = "0.1.1" + +[[Clustering]] +deps = ["Dates", "Distances", "LinearAlgebra", "NearestNeighbors", "Printf", "Random", "SparseArrays", "Statistics", "StatsBase", "Test"] +git-tree-sha1 = "282e5d488cfca89b78b28b9ef28a59898951a62f" +uuid = "aaaa29a8-35af-508c-8bc3-b662a17a0fe5" +version = "0.12.1" + +[[CodeTools]] +deps = ["LNR", "Lazy", "Markdown", "Pkg", "Test", "Tokenize"] +git-tree-sha1 = "d8901c94fa0dff4525217e84eae91bd7efa1adc1" +uuid = "53a63b46-67e4-5edd-8c66-0af0544a99b9" +version = "0.6.2" + +[[CodecZlib]] +deps = ["BinaryProvider", "Libdl", "Test", "TranscodingStreams"] +git-tree-sha1 = "e3df104c84dfc108f0ca203fd7f5bbdc98641ae9" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.5.1" + +[[ColorBrewer]] +deps = ["Colors", "JSON", "Test"] +git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" +uuid = "a2cac450-b92f-5266-8821-25eda20663c8" +version = "0.4.0" + +[[ColorTypes]] +deps = ["FixedPointNumbers", "Random", "Test"] +git-tree-sha1 = "f73b0e10f2a5756de7019818a41654686da06b09" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.7.5" + +[[ColorVectorSpace]] +deps = ["ColorTypes", "Colors", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "StatsBase", "Test"] +git-tree-sha1 = "a890f08e61b40e9843d7177206da61229a3603c8" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.6.2" + +[[Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "InteractiveUtils", "Printf", "Reexport", "Test"] +git-tree-sha1 = "9f0a0210450acb91c730b730a994f8eef1d3d543" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.9.5" + +[[Combinatorics]] +deps = ["LinearAlgebra", "Polynomials", "Test"] +git-tree-sha1 = "50b3ae4d643dc27eaff69fb6be06ee094d5500c9" +uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +version = "0.7.0" + +[[CommonSubexpressions]] +deps = ["Test"] +git-tree-sha1 = "efdaf19ab11c7889334ca247ff4c9f7c322817b0" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.2.0" + +[[Compat]] +deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] +git-tree-sha1 = "ec61a16eed883ad0cfa002d7489b3ce6d039bb9a" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "1.4.0" + +[[ComplexPhasePortrait]] +deps = ["AbstractPlotting", "Colors", "Images", "IntervalSets", "Reactive", "Test"] +git-tree-sha1 = "c6765b8bd5a1f1efe46118ed8b5afac8aaf34de9" +repo-rev = "master" +repo-url = "git://github.com/JuliaHolomorphic/ComplexPhasePortrait.jl.git" +uuid = "e2f66d33-ad5d-5c8f-afd8-ee097a041359" +version = "0.0.0" + +[[ComputationalResources]] +deps = ["Test"] +git-tree-sha1 = "89e7e7ed20af73d9f78877d2b8d1194e7b6ff13d" +uuid = "ed09eef8-17a6-5b46-8889-db040fac31e3" +version = "0.3.0" + +[[Conda]] +deps = ["Compat", "JSON", "VersionParsing"] +git-tree-sha1 = "fb86fe40cb5b35990e368709bfdc1b46dbb99dac" +uuid = "8f4d0f93-b110-5947-807f-2305c1781a2d" +version = "1.1.1" + +[[Contour]] +deps = ["LinearAlgebra", "StaticArrays", "Test"] +git-tree-sha1 = "b974e164358fea753ef853ce7bad97afec15bb80" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.5.1" + +[[CoordinateTransformations]] +deps = ["Compat", "Rotations", "StaticArrays"] +git-tree-sha1 = "47f05d0b7f4999609f92e657147df000818c1f24" +uuid = "150eb455-5306-5404-9cee-2592286d6298" +version = "0.5.0" + +[[Crayons]] +deps = ["Test"] +git-tree-sha1 = "3017c662a988bcb8a3f43306a793617c6524d476" +uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" +version = "1.0.0" + +[[CuArrays]] +deps = ["AbstractFFTs", "Adapt", "CUDAapi", "CUDAdrv", "CUDAnative", "DiffRules", "ForwardDiff", "GPUArrays", "LinearAlgebra", "MacroTools", "NNlib", "Printf", "Random", "Test"] +git-tree-sha1 = "50814c8f6de015f08a4fe2c01c87fb74f42c8a39" +uuid = "3a865a2d-5b23-5a0f-bc46-62713ec82fae" +version = "0.8.1" + +[[CustomUnitRanges]] +deps = ["Test"] +git-tree-sha1 = "0a106457a1831555857e18ac9617279c22fc393b" +uuid = "dc8bdbbb-1ca9-579f-8c36-e416f6a65cce" +version = "0.2.0" + +[[DSP]] +deps = ["AbstractFFTs", "Compat", "FFTW", "LinearAlgebra", "Polynomials", "Random", "Reexport", "SpecialFunctions"] +git-tree-sha1 = "c90967ff4c5e99f652b278624634dcef73b58848" +uuid = "717857b8-e6f2-59f4-9121-6e50c889abd2" +version = "0.5.1" + +[[DataFrames]] +deps = ["CategoricalArrays", "CodecZlib", "Compat", "DataStreams", "Dates", "InteractiveUtils", "IteratorInterfaceExtensions", "LinearAlgebra", "Missings", "Printf", "Random", "Reexport", "SortingAlgorithms", "Statistics", "StatsBase", "TableTraits", "Tables", "Test", "TranscodingStreams", "Unicode", "WeakRefStrings"] +git-tree-sha1 = "03ac36fd3571cd03ea276bd40e8f43d85653659d" +repo-rev = "nl/hash2" +repo-url = "https://github.com/JuliaData/DataFrames.jl.git" +uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +version = "0.14.1+" + +[[DataStreams]] +deps = ["Dates", "Missings", "Test", "WeakRefStrings"] +git-tree-sha1 = "69c72a1beb4fc79490c361635664e13c8e4a9548" +uuid = "9a8bc11e-79be-5b39-94d7-1ccc349a1a85" +version = "0.4.1" + +[[DataStructures]] +deps = ["InteractiveUtils", "OrderedCollections", "Random", "Serialization", "Test"] +git-tree-sha1 = "8fc6e166e24fda04b2b648d4260cdad241788c54" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.14.0" + +[[DataValues]] +deps = ["Dates", "InteractiveUtils", "LinearAlgebra", "Random", "Test"] +git-tree-sha1 = "4fedccda7e5111354c7dcc832c7da83ff7258765" +uuid = "e7dc6d0d-1eca-5fa6-8ad6-5aecde8b7ea5" +version = "0.4.5" + +[[Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[DebuggerFramework]] +git-tree-sha1 = "0288f278a5f58c28c67ad1cf55dce950069709b7" +uuid = "67417a49-6d77-5db2-98c7-c13144130cd2" +version = "0.1.2" + +[[DeepDiffs]] +deps = ["Compat"] +git-tree-sha1 = "cd4648e98d5625c75b9ebbec516533ec1250ce57" +uuid = "ab62b9b5-e342-54a8-a765-a90f495de1a6" +version = "1.1.0" + +[[DelayDiffEq]] +deps = ["DataStructures", "DiffEqBase", "DiffEqDiffTools", "ForwardDiff", "MuladdMacro", "NLSolversBase", "OrdinaryDiffEq", "RecursiveArrayTools", "Reexport", "Roots", "Test"] +git-tree-sha1 = "7a14b9794852211f7d28c243e3d07cdbfc73f1ae" +uuid = "bcd4f6db-9728-5f36-b5f7-82caef46ccdb" +version = "4.7.0" + +[[DelayEmbeddings]] +deps = ["Distances", "LinearAlgebra", "NearestNeighbors", "StaticArrays", "StatsBase", "Test"] +git-tree-sha1 = "6d42460dc2c84058850b26da7b5174fb6fcd213e" +uuid = "5732040d-69e3-5649-938a-b6b4f237613f" +version = "0.1.1" + +[[DelimitedFiles]] +deps = ["Mmap"] +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" + +[[DiffBase]] +deps = ["StaticArrays"] +git-tree-sha1 = "38522d70e417cf9ace93848f17eb9fff20d486d2" +uuid = "c5cfe0b6-c10a-51a5-87e3-fd79235949f0" +version = "0.3.2" + +[[DiffEqBase]] +deps = ["Compat", "IteratorInterfaceExtensions", "LinearAlgebra", "RecipesBase", "RecursiveArrayTools", "Requires", "Roots", "SparseArrays", "StaticArrays", "Statistics", "SuiteSparse", "TableTraits", "Test", "TreeViews"] +git-tree-sha1 = "b8c9c5a296e426d0ad978e6e7ad699dde444d3a1" +uuid = "2b5f629d-d688-5b77-993f-72d75c75574e" +version = "4.31.1" + +[[DiffEqBiological]] +deps = ["Compat", "DataStructures", "DiffEqBase", "DiffEqJump", "MacroTools", "Random", "Reexport", "Statistics", "SymEngine", "Test"] +git-tree-sha1 = "1a107ec930651bfe528f69633c34e5548c335c22" +uuid = "eb300fae-53e8-50a0-950c-e21f52c2b7e0" +version = "3.4.1" + +[[DiffEqCallbacks]] +deps = ["DataStructures", "DiffEqBase", "LinearAlgebra", "OrdinaryDiffEq", "RecipesBase", "RecursiveArrayTools", "StaticArrays", "Test"] +git-tree-sha1 = "eb35747ead057723bd75c830bc012a22f5f5f3d1" +uuid = "459566f4-90b8-5000-8ac3-15dfb0a30def" +version = "2.3.0" + +[[DiffEqDevTools]] +deps = ["DiffEqBase", "DiffEqMonteCarlo", "DiffEqNoiseProcess", "DiffEqPDEBase", "Distributed", "LinearAlgebra", "NLsolve", "Random", "RecipesBase", "RecursiveArrayTools", "Statistics", "Test"] +git-tree-sha1 = "fd0570ec1ff052b9aef8e832015092417fb24dae" +uuid = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" +version = "2.6.1" + +[[DiffEqDiffTools]] +deps = ["LinearAlgebra", "Test"] +git-tree-sha1 = "67700c9fc82033ec68a145bc650f6b9debdf9103" +uuid = "01453d9d-ee7c-5054-8395-0335cb756afa" +version = "0.7.1" + +[[DiffEqFinancial]] +deps = ["DiffEqBase", "DiffEqNoiseProcess", "LinearAlgebra", "Markdown", "RandomNumbers", "Test"] +git-tree-sha1 = "f250512b982b771f6bdb3df05b89df314f2c2580" +uuid = "5a0ffddc-d203-54b0-88ba-2c03c0fc2e67" +version = "2.1.0" + +[[DiffEqJump]] +deps = ["Compat", "DataStructures", "DiffEqBase", "FunctionWrappers", "LinearAlgebra", "PoissonRandom", "Random", "RandomNumbers", "RecursiveArrayTools", "Statistics", "Test", "TreeViews"] +git-tree-sha1 = "7a11954a512000c2a598e6ff74e0adc57907553a" +uuid = "c894b116-72e5-5b58-be3c-e6d8d4ac2b12" +version = "5.6.0" + +[[DiffEqMonteCarlo]] +deps = ["DiffEqBase", "Distributed", "Random", "RecursiveArrayTools", "StaticArrays", "Statistics", "Test"] +git-tree-sha1 = "abaf6fa95b05c5c49fd1fb57a901caed10aacd0e" +uuid = "78ddff82-25fc-5f2b-89aa-309469cbf16f" +version = "0.14.0" + +[[DiffEqNoiseProcess]] +deps = ["DataStructures", "DiffEqBase", "LinearAlgebra", "Random", "RandomNumbers", "RecipesBase", "RecursiveArrayTools", "ResettableStacks", "StaticArrays", "Statistics", "Test"] +git-tree-sha1 = "2cdf1ae0f41bc89bc68c9ba19b7587f695b8ae86" +uuid = "77a26b50-5914-5dd7-bc55-306e6241c503" +version = "2.3.2" + +[[DiffEqOperators]] +deps = ["DiffEqBase", "LinearAlgebra", "Random", "SparseArrays", "StaticArrays", "Test"] +git-tree-sha1 = "332eea616ae687e7e4581602947ad5f053c7c650" +uuid = "9fdde737-9c7f-55bf-ade8-46b3f136cc48" +version = "3.4.0" + +[[DiffEqPDEBase]] +deps = ["ChunkedArrays", "Compat", "DiffEqBase", "RecipesBase", "VectorizedRoutines"] +git-tree-sha1 = "2a997aba53ecff1b19e6c78f1181352787bd9c54" +uuid = "34035eb4-37db-58ae-b003-a3202c898701" +version = "0.4.0" + +[[DiffEqParamEstim]] +deps = ["BlackBoxOptim", "Calculus", "DiffEqBase", "Distributions", "ForwardDiff", "LinearAlgebra", "LsqFit", "Optim", "PenaltyFunctions", "Random", "RecursiveArrayTools", "Test"] +git-tree-sha1 = "285a71332e266cc8046f9d0c860f4eac58132ba9" +uuid = "1130ab10-4a5a-5621-a13d-e4788d82bd4c" +version = "1.5.0" + +[[DiffEqPhysics]] +deps = ["Dates", "DiffEqBase", "DiffEqCallbacks", "ForwardDiff", "LinearAlgebra", "Printf", "Random", "RecipesBase", "RecursiveArrayTools", "Reexport", "StaticArrays", "Test"] +git-tree-sha1 = "d3dbc53318a6477f496ae2347db98c3ded36c486" +uuid = "055956cb-9e8b-5191-98cc-73ae4a59e68a" +version = "3.1.0" + +[[DiffEqSensitivity]] +deps = ["Compat", "DiffEqBase", "DiffEqCallbacks", "DiffEqDiffTools", "ForwardDiff", "LinearAlgebra", "QuadGK", "RecursiveArrayTools", "ReverseDiff", "Statistics", "Test"] +git-tree-sha1 = "76f33416ee523314b7fcdc08696408861489c427" +uuid = "41bf760c-e81c-5289-8e54-58b1f1f8abe2" +version = "2.3.0" + +[[DiffEqUncertainty]] +deps = ["DiffEqBase", "Test"] +git-tree-sha1 = "de2908324d93d201f870ffad020038b9a87350bf" +uuid = "ef61062a-5684-51dc-bb67-a0fcdec5c97d" +version = "1.1.0" + +[[DiffResults]] +deps = ["Compat", "StaticArrays"] +git-tree-sha1 = "db8acf46717b13d6c48deb7a12007c7f85a70cf7" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "0.0.3" + +[[DiffRules]] +deps = ["Random", "Test"] +git-tree-sha1 = "c49ec69428ffea0c1d1bbdc63d1a70f5df5860ad" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "0.0.7" + +[[DifferentialEquations]] +deps = ["BoundaryValueDiffEq", "DelayDiffEq", "DiffEqBase", "DiffEqBiological", "DiffEqCallbacks", "DiffEqDevTools", "DiffEqFinancial", "DiffEqJump", "DiffEqMonteCarlo", "DiffEqNoiseProcess", "DiffEqPDEBase", "DiffEqParamEstim", "DiffEqPhysics", "DiffEqSensitivity", "DiffEqUncertainty", "DimensionalPlotRecipes", "LinearAlgebra", "MultiScaleArrays", "OrdinaryDiffEq", "ParameterizedFunctions", "Random", "RecursiveArrayTools", "Reexport", "SteadyStateDiffEq", "StochasticDiffEq", "Sundials", "Test"] +git-tree-sha1 = "1f5d7977befe3265d9b7fc256d8f88d0bd9b6ffa" +uuid = "0c46a032-eb83-5123-abaf-570d42b7fbaa" +version = "5.3.1" + +[[DimensionalPlotRecipes]] +deps = ["LinearAlgebra", "RecipesBase", "Test"] +git-tree-sha1 = "d348688f9a3d02c24455327231c450c272b7401c" +uuid = "c619ae07-58cd-5f6d-b883-8f17bd6a98f9" +version = "0.2.0" + +[[Distances]] +deps = ["LinearAlgebra", "Printf", "Random", "Statistics", "Test"] +git-tree-sha1 = "2f38605722542f1c0a32dd2856fb529d8c226c69" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.7.3" + +[[Distributed]] +deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[Distributions]] +deps = ["Distributed", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsBase", "StatsFuns", "Test"] +git-tree-sha1 = "c24e9b6500c037673f0241a2783472b8c3d080c7" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.16.4" + +[[DocSeeker]] +deps = ["Hiccup", "IterTools", "Markdown", "REPL", "Requires", "Serialization", "StringDistances", "Test", "URIParser"] +git-tree-sha1 = "8d4d5f9ec970944445c77cfdcd5d3246a4e0cd0d" +uuid = "33d173f1-3be9-53c5-a697-8225b67db89c" +version = "0.2.0" + +[[DocStringExtensions]] +deps = ["LibGit2", "Markdown", "Pkg", "Test"] +git-tree-sha1 = "1df01539a1c952cef21f2d2d1c092c2bcf0177d7" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.6.0" + +[[Documenter]] +deps = ["Base64", "DocStringExtensions", "InteractiveUtils", "LibGit2", "Logging", "Markdown", "Pkg", "REPL", "Random", "Test", "Unicode"] +git-tree-sha1 = "9f2135e0e7ecb63f9c3ef73ea15a31d8cdb79bb7" +uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +version = "0.20.0" + +[[DomainSets]] +deps = ["IntervalSets", "LinearAlgebra", "StaticArrays", "Statistics", "Test"] +git-tree-sha1 = "84beb94a9595c1a7a692880b424f82470a326976" +uuid = "5b8099bc-c8ec-5219-889f-1d9e522a28bf" +version = "0.0.1" + +[[DoubleFloats]] +deps = ["AccurateArithmetic", "LinearAlgebra", "Polynomials", "Random", "Test"] +git-tree-sha1 = "92eb688591448438ccd93685f4f80c6f220f5ccb" +uuid = "497a8b3b-efae-58df-a0af-a86822472b78" +version = "0.4.2" + +[[DualNumbers]] +deps = ["Calculus", "LinearAlgebra", "NaNMath", "SpecialFunctions", "Test"] +git-tree-sha1 = "b1e66ac804402a32184288ec9a78ab6d3a22ae69" +uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" +version = "0.6.1" + +[[DynamicalSystems]] +deps = ["ChaosTools", "DelayEmbeddings", "DynamicalSystemsBase", "Reexport", "StaticArrays"] +git-tree-sha1 = "7d388c4410e3d116a7147969645d018ab796c8d4" +repo-rev = "master" +repo-url = "https://github.com/JuliaDynamics/DynamicalSystems.jl.git" +uuid = "61744808-ddfa-5f27-97ff-6e42cc95d634" +version = "1.0.0+" + +[[DynamicalSystemsBase]] +deps = ["DelayEmbeddings", "DiffEqBase", "ForwardDiff", "LinearAlgebra", "OrdinaryDiffEq", "Reexport", "SparseArrays", "StaticArrays", "Test"] +git-tree-sha1 = "5c86d2492d20947ebbfe96824833ad71b7430d90" +repo-rev = "master" +repo-url = "https://github.com/JuliaDynamics/DynamicalSystemsBase.jl.git" +uuid = "6e36e845-645a-534a-86f2-f5d4aa5a06b4" +version = "1.1.0+" + +[[EllipsisNotation]] +git-tree-sha1 = "c09a512ff36dd5785ddc04fc102f2ff3b7fe05ae" +uuid = "da5c29d0-fa7d-589e-88eb-ea29b0a81949" +version = "0.3.0" + +[[ErrorfreeArithmetic]] +deps = ["Test"] +git-tree-sha1 = "071677938ef6e8f2a51ec0fedf5c312af88e26dc" +uuid = "90fa49ef-747e-5e6f-a989-263ba693cf1a" +version = "0.2.1" + +[[ExponentialUtilities]] +deps = ["LinearAlgebra", "Printf", "Random", "SparseArrays", "Test"] +git-tree-sha1 = "a25edb801ef3299b1c0fbbfe62692a074a82893b" +uuid = "d4d017d3-3776-5f7e-afef-a10c40355c18" +version = "1.3.0" + +[[EzXML]] +deps = ["BinaryProvider", "Libdl", "Printf", "Test"] +git-tree-sha1 = "5623d1486bfaadd815f5c4ca501adda02b5337f1" +uuid = "8f5d6c58-4d21-5cfd-889c-e3ad7ee6a615" +version = "0.9.0" + +[[FFTViews]] +deps = ["CustomUnitRanges", "FFTW", "Test"] +git-tree-sha1 = "9d7993227ca7c0fdb6b31deef193adbba11c8f4e" +uuid = "4f61f5a4-77b1-5117-aa51-3ab5ef4ef0cd" +version = "0.2.0" + +[[FFTW]] +deps = ["AbstractFFTs", "BinaryProvider", "Compat", "Conda", "Libdl", "LinearAlgebra", "Reexport", "Test"] +git-tree-sha1 = "29cda58afbf62f35b1a094882ad6c745a47b2eaa" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "0.2.4" + +[[FastGaussQuadrature]] +deps = ["Compat", "LinearAlgebra", "SpecialFunctions"] +git-tree-sha1 = "3861ecfe06076f9310a43469fbb676aaeba7893d" +uuid = "442a2c76-b920-505d-bb47-c5924d526838" +version = "0.3.2" + +[[FastRounding]] +deps = ["ErrorfreeArithmetic", "Test"] +git-tree-sha1 = "224175e213fd4fe112db3eea05d66b308dc2bf6b" +uuid = "fa42c844-2597-5d31-933b-ebd51ab2693f" +version = "0.2.0" + +[[FastTransforms]] +deps = ["AbstractFFTs", "Compat", "DSP", "FFTW", "HierarchicalMatrices", "LinearAlgebra", "LowRankApprox", "ProgressMeter", "SpecialFunctions", "ToeplitzMatrices"] +git-tree-sha1 = "051b635520e679c8c72aa43a40d86e2c226bbb7f" +uuid = "057dd010-8810-581a-b7be-e3fc3b93f78c" +version = "0.4.2" + +[[FileIO]] +deps = ["Pkg", "Random", "Test"] +git-tree-sha1 = "1a114d08094e7267ba8d4d684f930d5a722184de" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.0.4" + +[[FilePaths]] +deps = ["Compat", "FilePathsBase", "Reexport", "URIParser"] +git-tree-sha1 = "9819e84a360a6254d86c47827ad16f6ada6e39f9" +uuid = "8fc22ac5-c921-52a6-82fd-178b2807b824" +version = "0.7.0" + +[[FilePathsBase]] +deps = ["Compat"] +git-tree-sha1 = "230d04188b262b0795144a5907b495fbc3ce8131" +uuid = "48062228-2e41-5def-b9a4-89aafe57970f" +version = "0.4.0" + +[[FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" + +[[FillArrays]] +deps = ["LinearAlgebra", "Random", "SparseArrays", "Test"] +git-tree-sha1 = "d87b7fc5c086cf157deabec625d53ba55eca6436" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "0.3.0" + +[[FixedPointNumbers]] +deps = ["Test"] +git-tree-sha1 = "b8045033701c3b10bf2324d7203404be7aef88ba" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.5.3" + +[[Flux]] +deps = ["AbstractTrees", "Adapt", "CodecZlib", "Colors", "DiffRules", "ForwardDiff", "Juno", "LinearAlgebra", "MacroTools", "NNlib", "NaNMath", "Printf", "Random", "Reexport", "Requires", "SpecialFunctions", "Statistics", "StatsBase", "Test", "ZipFile"] +git-tree-sha1 = "a9b7a93f9a6627abaf5a2eb576b8559279cb499a" +uuid = "587475ba-b771-5e3f-ad9e-33799f191a9c" +version = "0.6.9" + +[[ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "InteractiveUtils", "LinearAlgebra", "NaNMath", "Random", "SparseArrays", "SpecialFunctions", "StaticArrays", "Test"] +git-tree-sha1 = "b91250044374764e7c29af59a774c4b8d6100b6e" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "0.10.1" + +[[FreeType]] +deps = ["BinaryProvider", "Libdl", "Pkg", "Test"] +git-tree-sha1 = "06462b9d5aca708d764d16e5ba6a83ba7b753d57" +uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" +version = "2.1.1" + +[[FreeTypeAbstraction]] +deps = ["ColorVectorSpace", "Colors", "FreeType", "StaticArrays", "Test"] +git-tree-sha1 = "271ef13438bd0946950fd34d9241e5beefd6d4b3" +uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" +version = "0.4.1" + +[[FreqTables]] +deps = ["CategoricalArrays", "NamedArrays", "Tables", "Test"] +git-tree-sha1 = "93ce75cae27c2d1c6518771d597b6dd0a3d623d3" +uuid = "da1fdf0e-e0ff-5433-a45f-9bb5ff651cb1" +version = "0.3.1" + +[[FunctionWrappers]] +deps = ["Compat"] +git-tree-sha1 = "49bf793ebd37db5adaa7ac1eae96c2c97ec86db5" +uuid = "069b7b12-0de2-55c6-9aab-29f3d0a68a2e" +version = "1.0.0" + +[[FunctionalCollections]] +deps = ["Test"] +git-tree-sha1 = "9fdecc849480c511d7825570c20c9b64c4e5d5ed" +uuid = "de31a74c-ac4f-5751-b3fd-e18cd04993ca" +version = "0.4.0" + +[[Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" + +[[GDAL]] +deps = ["BinaryProvider", "Libdl", "Test"] +git-tree-sha1 = "100429098b7ec9930f7db9ba68aee3495365be24" +uuid = "add2ef01-049f-52c4-9ee2-e494f65e021a" +version = "0.2.0" + +[[GLFW]] +deps = ["BinDeps", "CMakeWrapper", "Homebrew", "Libdl", "Test"] +git-tree-sha1 = "035e2b5e9c335afae1e92ecfe532cf0620da869f" +uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" +version = "2.3.0" + + +[[GPUArrays]] +deps = ["FFTW", "FillArrays", "LinearAlgebra", "Pkg", "Printf", "Random", "Serialization", "StaticArrays", "Test"] +git-tree-sha1 = "ff1d9b711533c00bb3eb800546e764e2035e6ed8" +uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" +version = "0.5.0" + +[[GR]] +deps = ["Base64", "DelimitedFiles", "Pkg", "Random", "Serialization", "Sockets", "Test"] +git-tree-sha1 = "31a672ea6609a53567ca96b1c52d984eaa10790a" +repo-rev = "master" +repo-url = "https://github.com/jheinen/GR.jl.git" +uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" +version = "0.36.0+" + +[[GenericSVD]] +deps = ["LinearAlgebra", "Random", "Test"] +git-tree-sha1 = "c6f411fee94d3e2f1121d635f5a7ab7eec200eea" +uuid = "01680d73-4ee2-5a08-a1aa-533608c188bb" +version = "0.2.0" + +[[GeometricalPredicates]] +deps = ["Test"] +git-tree-sha1 = "ccf306c88eedb19c95432947d8b7f4d0e916e1a2" +uuid = "fd0ad045-b25c-564e-8f9c-8ef5c5f21267" +version = "0.2.0" + +[[GeometryTypes]] +deps = ["ColorTypes", "FixedPointNumbers", "IterTools", "LinearAlgebra", "StaticArrays", "Test"] +git-tree-sha1 = "706fc16aa2a648a2f292732f8e6ee25167484328" +uuid = "4d00f742-c7ba-57c2-abde-4428a4b178cb" +version = "0.7.1" + +[[GitHub]] +deps = ["Base64", "Compat", "Dates", "HTTP", "JSON", "MbedTLS", "Test"] +git-tree-sha1 = "b988ce46c9b682acfeed4801cbaafa1ef954ad31" +uuid = "bc5e4493-9b4d-5f90-b8aa-2b2bcaad7a26" +version = "5.0.2" + +[[Graphics]] +deps = ["Colors", "Compat", "NaNMath"] +git-tree-sha1 = "e3ead4211073d4117a0d2ef7d1efc5c8092c8412" +uuid = "a2bd30eb-e257-5431-a919-1863eab51364" +version = "0.4.0" + +[[HDF5]] +deps = ["BinDeps", "Blosc", "CRC32c", "Distributed", "Homebrew", "Libdl", "LinearAlgebra", "Mmap", "Pkg", "Test", "WinRPM"] +git-tree-sha1 = "2b55a7e957923fa15688c97e91198a3ff24155d2" +uuid = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" +version = "0.10.3" + +[[HTTP]] +deps = ["Base64", "Dates", "Distributed", "IniFile", "MbedTLS", "Sockets", "Test"] +git-tree-sha1 = "b881f69331e85642be315c63d05ed65d6fc8a05b" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "0.7.1" + +[[HTTPClient]] +deps = ["Compat", "LibCURL"] +git-tree-sha1 = "161d5776ae8e585ac0b8c20fb81f17ab755b3671" +uuid = "0862f596-cf2d-50af-8ef4-f2be67dfa83f" +version = "0.2.1" + +[[Hiccup]] +deps = ["MacroTools", "Test"] +git-tree-sha1 = "6187bb2d5fcbb2007c39e7ac53308b0d371124bd" +uuid = "9fb69e20-1954-56bb-a84f-559cc56a8ff7" +version = "0.2.2" + +[[HierarchicalMatrices]] +deps = ["Compat"] +git-tree-sha1 = "acfcaf1aa47d038f593f301ed3bdebc0129035bc" +uuid = "7c893195-952b-5c83-bb6e-be12f22eed51" +version = "0.1.4" + +[[Homebrew]] +deps = ["BinDeps", "InteractiveUtils", "JSON", "Libdl", "Test", "Unicode"] +git-tree-sha1 = "5582ec74f735cf8d12e562a2e65c47f34063bd51" +uuid = "d9be37ee-ecc9-5288-90f1-b9ca67657a75" +version = "0.7.0" + +[[IJulia]] +deps = ["Base64", "Compat", "Conda", "Dates", "InteractiveUtils", "JSON", "Markdown", "MbedTLS", "Pkg", "Printf", "REPL", "Random", "SoftGlobalScope", "Test", "UUIDs", "ZMQ"] +git-tree-sha1 = "38d1ce0fbbefcb67f5ab46f1093cbce0335092e0" +uuid = "7073ff75-c697-5162-941a-fcdaad2a7d2a" +version = "1.14.1" + +[[IdentityRanges]] +deps = ["OffsetArrays", "Test"] +git-tree-sha1 = "f5ca23a08397288924a7535cd898d8ccbcde5ba5" +uuid = "bbac6d45-d8f3-5730-bfe4-7a449cd117ca" +version = "0.2.0" + +[[ImageAxes]] +deps = ["AxisArrays", "Colors", "FixedPointNumbers", "ImageCore", "MappedArrays", "Reexport", "SimpleTraits", "Test"] +git-tree-sha1 = "5735ec90843acaa67a4624611921c686cdf4efbf" +uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" +version = "0.5.0" + +[[ImageCore]] +deps = ["ColorTypes", "Colors", "FFTW", "FixedPointNumbers", "Graphics", "MappedArrays", "OffsetArrays", "PaddedViews", "Random", "Statistics", "Test"] +git-tree-sha1 = "5e7b1f49c80541860e08a7ea91805a24c1641f19" +uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" +version = "0.7.3" + +[[ImageDistances]] +deps = ["Colors", "Distances", "LinearAlgebra", "ProgressMeter", "Test"] +git-tree-sha1 = "a5de7b61f6fa98fb93c39857fa43cf40ca383b28" +uuid = "51556ac3-7006-55f5-8cb3-34580c88182d" +version = "0.1.1" + +[[ImageFiltering]] +deps = ["CatIndices", "ColorVectorSpace", "Colors", "ComputationalResources", "DataStructures", "FFTViews", "FFTW", "FixedPointNumbers", "ImageCore", "LinearAlgebra", "Logging", "MappedArrays", "OffsetArrays", "Random", "StaticArrays", "Statistics", "Test", "TiledIteration"] +git-tree-sha1 = "2d23d8f8c1def1e8d67d05e554baacc780d9313d" +uuid = "6a3955dd-da59-5b1f-98d4-e7296123deb5" +version = "0.5.1" + +[[ImageMagick]] +deps = ["BinaryProvider", "ColorTypes", "FileIO", "FixedPointNumbers", "ImageCore", "InteractiveUtils", "Libdl", "Pkg", "Random", "Test"] +git-tree-sha1 = "0e4cc77fb131061b3525a97fd7d483b253c3aaad" +uuid = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" +version = "0.7.1" + +[[ImageMetadata]] +deps = ["AxisArrays", "ColorVectorSpace", "Colors", "Dates", "FixedPointNumbers", "ImageAxes", "ImageCore", "IndirectArrays", "Statistics", "Test"] +git-tree-sha1 = "3eac47d5b62dfeb4d06ec5be85592ebd437112ea" +uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49" +version = "0.5.1" + +[[ImageMorphology]] +deps = ["ImageCore", "Test"] +git-tree-sha1 = "e94f43b9ff76f3a3810bfdd9b3d2fbcacbc26fd0" +uuid = "787d08f9-d448-5407-9aad-5290dd7ab264" +version = "0.1.1" + +[[ImageShow]] +deps = ["Base64", "ColorTypes", "Colors", "FileIO", "FixedPointNumbers", "ImageCore", "OffsetArrays", "Requires", "Test"] +git-tree-sha1 = "98eb96a852fd2d6f0905cbe4d215ec2113805b46" +uuid = "4e3cecfd-b093-5904-9786-8bbb286a6a31" +version = "0.1.2" + +[[ImageTransformations]] +deps = ["AxisAlgorithms", "ColorTypes", "ColorVectorSpace", "Colors", "CoordinateTransformations", "FixedPointNumbers", "IdentityRanges", "ImageCore", "Interpolations", "LinearAlgebra", "OffsetArrays", "StaticArrays", "Test"] +git-tree-sha1 = "18ae1c0a8df31549a9452ceac93751d4aa166071" +uuid = "02fcd773-0e25-5acc-982a-7f6622650795" +version = "0.7.1" + +[[Images]] +deps = ["AxisArrays", "Base64", "ColorTypes", "ColorVectorSpace", "Colors", "FileIO", "FixedPointNumbers", "Graphics", "ImageAxes", "ImageCore", "ImageDistances", "ImageFiltering", "ImageMetadata", "ImageMorphology", "ImageShow", "ImageTransformations", "IndirectArrays", "LinearAlgebra", "MappedArrays", "OffsetArrays", "Random", "Reexport", "SIUnits", "SparseArrays", "StaticArrays", "Statistics", "StatsBase", "Test", "TiledIteration"] +git-tree-sha1 = "6ccb98fb6d93ade0ddd3954877955f17c2041a66" +uuid = "916415d5-f1e6-5110-898d-aaa5f9f070e0" +version = "0.16.1" + +[[IndexedTables]] +deps = ["DataValues", "Dates", "IteratorInterfaceExtensions", "LinearAlgebra", "OnlineStats", "PooledArrays", "Random", "Serialization", "SparseArrays", "Statistics", "TableTraits", "TableTraitsUtils", "Test", "WeakRefStrings"] +git-tree-sha1 = "cb4406eeed8729f8179940d39e6dec5598971341" +uuid = "6deec6e2-d858-57c5-ab9b-e6ca5bd20e43" +version = "0.8.1" + +[[IndirectArrays]] +deps = ["Compat", "Test"] +git-tree-sha1 = "b6e249be10a3381b2c72ac82f2d13d70067cb2bd" +uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" +version = "0.5.0" + +[[InfiniteArrays]] +deps = ["DSP", "FillArrays", "LazyArrays", "LinearAlgebra", "SparseArrays", "Statistics", "Test"] +git-tree-sha1 = "e65228707f83519678abeb780ff0d53cebcc2584" +uuid = "4858937d-0d70-526a-a4dd-2d5cb5dd786c" +version = "0.0.2" + +[[IniFile]] +deps = ["Test"] +git-tree-sha1 = "098e4d2c533924c921f9f9847274f2ad89e018b8" +uuid = "83e8ac13-25f8-5344-8a64-a9f2b223428f" +version = "0.5.0" + +[[Interact]] +deps = ["CSSUtil", "DataStructures", "InteractBase", "InteractBulma", "JSON", "Knockout", "Observables", "Reexport", "Test", "WebIO", "Widgets"] +git-tree-sha1 = "102666d2d89a672c86bd33399a5f36c7e5d2b3b5" +uuid = "c601a237-2ae4-5e1e-952c-7a85b0c7eef1" +version = "0.9.0" + +[[InteractBase]] +deps = ["Base64", "CSSUtil", "Colors", "DataStructures", "Dates", "JSExpr", "JSON", "Knockout", "Observables", "Random", "Test", "WebIO", "Widgets"] +git-tree-sha1 = "494156a2e3fb192210bd8404da8de1d423d48bb1" +uuid = "d3863d7c-f0c8-5437-a7b4-3ae773c01009" +version = "0.8.1" + +[[InteractBulma]] +deps = ["InteractBase", "Reexport", "Test"] +git-tree-sha1 = "5dd3798331686a512ee98cc59a5b1f3d136cd926" +uuid = "7981ab7d-5bfa-5e03-9ec9-f3d4afc0a1ca" +version = "0.4.2" + +[[InteractiveUtils]] +deps = ["LinearAlgebra", "Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[Interpolations]] +deps = ["AxisAlgorithms", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "SharedArrays", "SparseArrays", "StaticArrays", "Test", "WoodburyMatrices"] +git-tree-sha1 = "3493536a64dae5a21c0cc8aecf680647f3e12313" +uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" +version = "0.11.0" + +[[IntervalArithmetic]] +deps = ["CRlibm", "FastRounding", "LinearAlgebra", "Markdown", "RecipesBase", "SetRounding", "StaticArrays", "Test"] +git-tree-sha1 = "9ce05b28f218d833aedbed0a53ca35948275f336" +uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" +version = "0.15.0" + +[[IntervalSets]] +deps = ["Compat"] +git-tree-sha1 = "9dc556002f23740de13946e8c2e41798e09a9249" +repo-rev = "master" +repo-url = "https://github.com/JuliaMath/IntervalSets.jl.git" +uuid = "8197267c-284f-5f27-9208-e0e47529a953" +version = "0.3.1+" + +[[IterTools]] +deps = ["SparseArrays", "Test"] +git-tree-sha1 = "79246285c43602384e6f1943b3554042a3712056" +uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +version = "1.1.1" + +[[IterableTables]] +deps = ["DataValues", "IteratorInterfaceExtensions", "Requires", "TableTraits", "TableTraitsUtils", "Test"] +git-tree-sha1 = "0eec91e8185899f3926f56db515559bfe95b9db7" +uuid = "1c8ee90f-4401-5389-894e-7a04a3dc0f4d" +version = "0.10.0" + +[[IteratorInterfaceExtensions]] +deps = ["Test"] +git-tree-sha1 = "5484e5ede2a4137b9643f4d646e8e7b87b794415" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "0.1.1" + +[[JLD2]] +deps = ["CodecZlib", "DataStructures", "FileIO", "LinearAlgebra", "Mmap", "Printf", "Random", "Test"] +git-tree-sha1 = "3ba90ff93e1d5b9b2103588051c2d349fae54dac" +uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +version = "0.1.2" + +[[JSExpr]] +deps = ["JSON", "MacroTools", "Observables", "Test", "WebIO"] +git-tree-sha1 = "96429a372b5c4ad63fa9cbff6ba4178a85939705" +uuid = "97c1335a-c9c5-57fe-bc5d-ec35cebe8660" +version = "0.4.0" + +[[JSON]] +deps = ["Dates", "Distributed", "Mmap", "Sockets", "Test", "Unicode"] +git-tree-sha1 = "1f7a25b53ec67f5e9422f1f551ee216503f4a0fa" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.20.0" + +[[Juno]] +deps = ["Base64", "Logging", "Media", "Profile", "Test"] +git-tree-sha1 = "3c29a199713e7ec62cfdc11f44d7760219d5f658" +uuid = "e5e0dc1b-0480-54bc-9374-aad01c23163d" +version = "0.5.3" + +[[KernelDensity]] +deps = ["Distributions", "FFTW", "Interpolations", "Optim", "StatsBase", "Test"] +git-tree-sha1 = "c1048817fe5711f699abc8fabd47b1ac6ba4db04" +uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" +version = "0.5.1" + +[[Knockout]] +deps = ["JSExpr", "JSON", "Observables", "Pkg", "Test", "WebIO"] +git-tree-sha1 = "63e5e0bd2e9923191c30bb1e3d6e4d579155ddfa" +uuid = "bcebb21b-c2e3-54f8-a781-646b90f6d2cc" +version = "0.2.0" + +[[LLVM]] +deps = ["InteractiveUtils", "Libdl", "Printf", "Test", "Unicode"] +git-tree-sha1 = "d98bd8e6e56591caceb7db300a6877fb6daca6ba" +uuid = "929cbde3-209d-540e-8aea-75f648917ca0" +version = "1.0.0" + +[[LNR]] +deps = ["Compat", "Lazy", "Test"] +git-tree-sha1 = "bae0010daaba5f122cefcbee9a97f5d82ea03e5c" +uuid = "7c4cb9fa-83a0-5386-9231-d6167c818060" +version = "0.2.0" + +[[LaTeXStrings]] +deps = ["Compat"] +git-tree-sha1 = "7ab9b8788cfab2bdde22adf9004bda7ad9954b6c" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.0.3" + +[[Lazy]] +deps = ["Compat", "MacroTools", "Test"] +git-tree-sha1 = "aec38c7e7f255a678af22651c74100e3cd39ea20" +uuid = "50d2b5c4-7a5e-59d5-8109-a42b560f39c0" +version = "0.13.2" + +[[LazyArrays]] +deps = ["FillArrays", "LinearAlgebra", "StaticArrays", "Test"] +git-tree-sha1 = "80ae09d512afe478575cadf7e301742996d0330d" +uuid = "5078a376-72f3-5289-bfd5-ec5146d43c02" +version = "0.4.0" + +[[LearnBase]] +deps = ["LinearAlgebra", "SparseArrays", "StatsBase", "Test"] +git-tree-sha1 = "c4b5da6d68517f46f70ed5157b28336b56cd2ff3" +uuid = "7f8f8fb0-2700-5f03-b4bd-41f8cfc144b6" +version = "0.2.2" + +[[LibCURL]] +deps = ["BinaryProvider", "Compat", "Libdl", "Printf"] +git-tree-sha1 = "6339c87cb76923a3cf947fcd213cbc364355c9c9" +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.4.1" + +[[LibExpat]] +deps = ["Compat"] +git-tree-sha1 = "fde352ec13479e2f90e57939da2440fb78c5e388" +uuid = "522f3ed2-3f36-55e3-b6df-e94fee9b0c07" +version = "0.5.0" + +[[LibGit2]] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[Libz]] +deps = ["BufferedStreams", "Random", "Test"] +git-tree-sha1 = "d405194ffc0293c3519d4f7251ce51baac9cc871" +uuid = "2ec943e9-cfe8-584d-b93d-64dcb6d567b7" +version = "1.0.0" + +[[LineSearches]] +deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf", "Test"] +git-tree-sha1 = "54eb90e8dbe745d617c78dee1d6ae95c7f6f5779" +uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" +version = "7.0.1" + +[[LinearAlgebra]] +deps = ["Libdl"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[LinearMaps]] +deps = ["LinearAlgebra", "SparseArrays", "Test"] +git-tree-sha1 = "580bb0efbfe0082c4fb0ce8dbf6548872c3b604c" +uuid = "7a12625a-238d-50fd-b39a-03d52299707e" +version = "2.2.2" + +[[Loess]] +deps = ["Distances", "Random", "Statistics", "Test"] +git-tree-sha1 = "0ee46caf683a422b595be4dfaed6cda28f541e25" +uuid = "4345ca2d-374a-55d4-8d30-97f9976e7612" +version = "0.5.0" + +[[Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[LossFunctions]] +deps = ["InteractiveUtils", "LearnBase", "Markdown", "Random", "RecipesBase", "SparseArrays", "Statistics", "StatsBase", "Test"] +git-tree-sha1 = "b97d2e9a527733649d0205d3374d0daee352c50e" +uuid = "30fc2ffe-d236-52d8-8643-a9d8f7c094a7" +version = "0.5.0" + +[[LowRankApprox]] +deps = ["FFTW", "FillArrays", "LinearAlgebra", "Nullables", "Random", "SparseArrays", "Test"] +git-tree-sha1 = "fed5d60ed818367d4945a95be679461280501f2d" +uuid = "898213cb-b102-5a47-900c-97e73b919f73" +version = "0.2.1" + +[[LsqFit]] +deps = ["Calculus", "Distributions", "LinearAlgebra", "OptimBase", "Random", "Test"] +git-tree-sha1 = "5c1b5ab85e120c6d1734e7f5670aac22fe69270c" +uuid = "2fda8390-95c7-5789-9bda-21331edee243" +version = "0.6.0" + +[[MacroTools]] +deps = ["Compat"] +git-tree-sha1 = "c443e1c8d58a4e9f61b708ad0a88286c7042145b" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.4.4" + +[[Makie]] +deps = ["AbstractPlotting", "AxisArrays", "Base64", "ColorBrewer", "ColorTypes", "ColorVectorSpace", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GLFW", "GLMakie", "GeometryTypes", "ImageAxes", "ImageCore", "ImageMagick", "ImageTransformations", "IndirectArrays", "IntervalSets", "IterTools", "LinearAlgebra", "ModernGL", "Observables", "Pkg", "PlotUtils", "Primes", "QuartzImageIO", "Showoff", "StaticArrays", "Statistics", "UnicodeFun"] +git-tree-sha1 = "a49ae5834b605a14447e04d57a07cbb80ebe8add" +repo-rev = "master" +repo-url = "https://github.com/JuliaPlots/Makie.jl.git" +uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" +version = "0.9.0+" + +[[MakieGallery]] +deps = ["AbstractPlotting", "BinaryProvider", "ColorTypes", "ColorVectorSpace", "Colors", "DataFrames", "Documenter", "FileIO", "FixedPointNumbers", "GDAL", "GeometryTypes", "ImageCore", "ImageFiltering", "ImageMagick", "ImageTransformations", "LinearAlgebra", "Makie", "Markdown", "MeshIO", "ModernGL", "Pkg", "QuartzImageIO", "RDatasets", "Random", "Statistics", "Test"] +git-tree-sha1 = "178252e975f92c3e11a4478577ec4a4faff4119d" +repo-rev = "master" +repo-url = "https://github.com/JuliaPlots/MakieGallery.jl" +uuid = "62e31da0-2f4f-5d53-819c-a7cea9df6aaa" +version = "0.0.0" + +[[MakieThemes]] +deps = ["AbstractPlotting", "Colors"] +git-tree-sha1 = "6a53e0ae8200b572cdd87bf2b10a616051785837" +repo-rev = "master" +repo-url = "https://github.com/mkborregaard/MakieThemes.jl.git" +uuid = "4307a514-e789-11e8-2e8d-7135958f4cf8" +version = "0.1.0" + +[[MappedArrays]] +deps = ["Test"] +git-tree-sha1 = "923441c5ac942b60bd3a842d5377d96646bcbf46" +uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" +version = "0.2.1" + +[[Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[MathProgBase]] +deps = ["Compat"] +git-tree-sha1 = "3bf2e534e635df810e5f4b4f1a8b6de9004a0d53" +uuid = "fdba3010-5040-5b88-9595-932c9decdf73" +version = "0.7.7" + +[[MbedTLS]] +deps = ["BinaryProvider", "Dates", "Libdl", "Random", "Sockets", "Test"] +git-tree-sha1 = "c93a87da4081a3de781f34e0540175795a2ce83d" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "0.6.6" + +[[Measures]] +deps = ["Test"] +git-tree-sha1 = "ddfd6d13e330beacdde2c80de27c1c671945e7d9" +uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e" +version = "0.3.0" + +[[Media]] +deps = ["MacroTools", "Test"] +git-tree-sha1 = "75a54abd10709c01f1b86b84ec225d26e840ed58" +uuid = "e89f7d12-3494-54d1-8411-f7d8b9ae1f27" +version = "0.5.0" + +[[MeshIO]] +deps = ["ColorTypes", "FileIO", "GeometryTypes", "Printf", "Test"] +git-tree-sha1 = "3e01e12c4c626578a9d47fac0d15c9fe8dad5139" +uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" +version = "0.3.1" + +[[Missings]] +deps = ["Dates", "InteractiveUtils", "SparseArrays", "Test"] +git-tree-sha1 = "adc26d2ee85a49c413464110d922cf21efc9d233" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "0.3.1" + +[[Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[Mocking]] +deps = ["Compat", "Dates"] +git-tree-sha1 = "4bf69aaf823b119b034e091e16b18311aa191663" +uuid = "78c3b35d-d492-501b-9361-3d52fe80e533" +version = "0.5.7" + +[[ModernGL]] +deps = ["Libdl"] +git-tree-sha1 = "f4f8fa8d04d3c1e7294f07fc37586c819466ad38" +uuid = "66fc600b-dfda-50eb-8b99-91cfa97b1301" +version = "1.0.0" + +[[MuladdMacro]] +deps = ["MacroTools", "Test"] +git-tree-sha1 = "41e6e7c4b448afeaddaac7f496b414854f83b848" +uuid = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" +version = "0.2.1" + +[[MultiScaleArrays]] +deps = ["DiffEqBase", "RecursiveArrayTools", "Statistics", "Test"] +git-tree-sha1 = "e85772d38263397a8808e98812d3ce49db4f217d" +uuid = "f9640e96-87f6-5992-9c3b-0743c6a49ffa" +version = "1.3.1" + +[[Mustache]] +deps = ["Tables", "Test"] +git-tree-sha1 = "be8d12b4a84ed7b592a6540b71c664440a4dd7f1" +uuid = "ffc61752-8dc7-55ee-8c37-f3e9cdd09e70" +version = "0.5.8" + +[[Mux]] +deps = ["AssetRegistry", "Base64", "HTTP", "Hiccup", "Lazy", "Pkg", "Sockets", "Test", "WebSockets"] +git-tree-sha1 = "487feb060cdd5cc152ef4f75b3cb565c0dc4300a" +uuid = "a975b10e-0019-58db-a62f-e48ff68538c9" +version = "0.5.3" + +[[NLSolversBase]] +deps = ["Calculus", "DiffEqDiffTools", "DiffResults", "Distributed", "ForwardDiff", "LinearAlgebra", "Random", "SparseArrays", "Test"] +git-tree-sha1 = "ebfb2e96970151753575b9c4d31d47e5ae8382a5" +uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" +version = "7.1.1" + +[[NLopt]] +deps = ["BinaryProvider", "CMakeWrapper", "Libdl", "MathProgBase", "Test"] +git-tree-sha1 = "b46237debcacd4fed7bbeb31200667a75b90384f" +uuid = "76087f3c-5699-56af-9a33-bf431cd00edd" +version = "0.5.1" + +[[NLsolve]] +deps = ["DiffBase", "DiffEqDiffTools", "Distances", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "Printf", "Reexport", "SparseArrays", "Test"] +git-tree-sha1 = "0e046f4f72801c9782d64db972ce66a85d3473f1" +uuid = "2774e3e8-f4cf-5e23-947b-6d7e65073b56" +version = "3.0.1" + +[[NNlib]] +deps = ["Libdl", "LinearAlgebra", "MacroTools", "Requires", "Test"] +git-tree-sha1 = "51330bb45927379007e089997bf548fbe232589d" +uuid = "872c559c-99b0-510c-b3b7-b6c96a88d5cd" +version = "0.4.3" + +[[NRRD]] +deps = ["AxisArrays", "ColorVectorSpace", "Colors", "FileIO", "FixedPointNumbers", "ImageAxes", "ImageCore", "Libz", "MappedArrays", "Mmap", "Printf", "Quaternions", "StaticArrays", "Statistics", "Test", "Unitful"] +git-tree-sha1 = "e46066f96c520203743114c0f6fd436887aa86bf" +repo-rev = "master" +repo-url = "https://github.com/JuliaIO/NRRD.jl.git" +uuid = "9bb6cfbd-7763-5393-b1b5-1c8e09872146" +version = "0.4.0+" + +[[NaNMath]] +deps = ["Compat"] +git-tree-sha1 = "ce3b85e484a5d4c71dd5316215069311135fa9f2" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "0.3.2" + +[[NamedArrays]] +deps = ["Combinatorics", "DataStructures", "DelimitedFiles", "LinearAlgebra", "Random", "Requires", "SparseArrays", "Statistics", "Test"] +git-tree-sha1 = "3099281fe5bcccb0cc329655a2b07e0d85e978ca" +uuid = "86f7a689-2022-50b4-a561-43c23ac3c673" +version = "0.9.1" + +[[NearestNeighbors]] +deps = ["Distances", "LinearAlgebra", "Mmap", "StaticArrays", "Test"] +git-tree-sha1 = "aab46b96ae5c2a9c08146188016d6312276094e5" +uuid = "b8a86587-4115-5ab1-83bc-aa920d37bbce" +version = "0.4.2" + +[[NuclearSurfaceVibrations]] +deps = ["AbstractPlotting", "Arpack", "CSV", "ChaosTools", "Colors", "DataFrames", "DataStructures", "DiffEqBase", "DiffEqCallbacks", "DiffEqMonteCarlo", "DifferentialEquations", "Distributed", "DynamicalSystems", "FileIO", "GeometricalPredicates", "ImageMagick", "Images", "IntervalArithmetic", "JLD2", "LaTeXStrings", "LinearAlgebra", "Logging", "Makie", "NLopt", "NLsolve", "Observables", "OrdinaryDiffEq", "ParallelDataTransfer", "Parameters", "Pkg", "PlotlyJS", "Plots", "ProgressMeter", "Query", "Random", "RecipesBase", "RecursiveArrayTools", "Reexport", "Roots", "SparseArrays", "StatPlots", "StaticArrays", "Statistics", "StatsBase", "StatsMakie", "TimerOutputs"] +git-tree-sha1 = "0b3b0e759ceff9399b04838e446f42517d2a0130" +repo-rev = "makie" +repo-url = "https://github.com/SebastianM-C/Nuclear-surface-vibrations" +uuid = "61377714-a6e6-11e8-0d55-23ea14e6950b" +version = "0.1.0" + +[[Nullables]] +deps = ["Compat"] +git-tree-sha1 = "ae1a63457e14554df2159b0b028f48536125092d" +uuid = "4d1e1d77-625e-5b40-9113-a560ec7a8ecd" +version = "0.0.8" + +[[ObjectFile]] +deps = ["Reexport", "StructIO", "Test"] +git-tree-sha1 = "1222547c57de96eaebc9f5d2579359db5d1a479d" +uuid = "d8793406-e978-5875-9003-1fc021f44a92" +version = "0.3.1" + +[[Observables]] +deps = ["Test"] +git-tree-sha1 = "dc02cec22747d1d10d9f70d8a1c03432b5bfbcd0" +uuid = "510215fc-4207-5dde-b226-833fc4488ee2" +version = "0.2.3" + +[[OffsetArrays]] +deps = ["DelimitedFiles", "Test"] +git-tree-sha1 = "f446248f2dfbc13039a0b90994dd25b059b01eab" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "0.9.0" + +[[OnlineStats]] +deps = ["DataStructures", "Dates", "LearnBase", "LinearAlgebra", "LossFunctions", "OnlineStatsBase", "PenaltyFunctions", "Random", "RecipesBase", "Reexport", "Statistics", "StatsBase", "SweepOperator", "Test"] +git-tree-sha1 = "70fe5cbb31d37c18f6312a2994c31b782be50607" +uuid = "a15396b6-48d5-5d58-9928-6d29437db91e" +version = "0.19.2" + +[[OnlineStatsBase]] +deps = ["LearnBase", "Test"] +git-tree-sha1 = "520580a74e09378fb6665fa89339323d411d3df3" +uuid = "925886fa-5bf2-5e8e-b522-a9147a512338" +version = "0.9.1" + +[[OpenCL]] +git-tree-sha1 = "e664123afca13a0caf2f08f2b91714f724732293" +uuid = "08131aa3-fb12-5dee-8b74-c09406e224a2" +version = "0.7.0" + +[[Optim]] +deps = ["Calculus", "DiffEqDiffTools", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "Random", "SparseArrays", "StatsBase", "Test"] +git-tree-sha1 = "0f2a6c6ff9db396cc7af15bb1cf057a26662ff17" +uuid = "429524aa-4258-5aef-a3af-852621145aeb" +version = "0.17.2" + +[[OptimBase]] +deps = ["Compat", "NLSolversBase", "Printf", "Reexport", "Test"] +git-tree-sha1 = "92667ab46a66ad502ec3044f65c41ea68b2e0e9c" +uuid = "87e2bd06-a317-5318-96d9-3ecbac512eee" +version = "2.0.0" + +[[OrderedCollections]] +deps = ["Random", "Serialization", "Test"] +git-tree-sha1 = "85619a3f3e17bb4761fe1b1fd47f0e979f964d5b" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.0.2" + +[[OrdinaryDiffEq]] +deps = ["DataStructures", "DiffEqBase", "DiffEqDiffTools", "DiffEqOperators", "ExponentialUtilities", "ForwardDiff", "GenericSVD", "InteractiveUtils", "LinearAlgebra", "Logging", "MuladdMacro", "NLsolve", "Parameters", "Printf", "Random", "RecursiveArrayTools", "Reexport", "SparseArrays", "StaticArrays", "Statistics", "Test"] +git-tree-sha1 = "06b6488f3f17f816de2c96fc071a8115b84ca736" +uuid = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" +version = "4.18.0" + +[[PDMats]] +deps = ["Arpack", "LinearAlgebra", "SparseArrays", "SuiteSparse", "Test"] +git-tree-sha1 = "9e3e7a5c9b8cfdba8c01a1bcae38fe0144936fda" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.9.5" + + +[[Packing]] +deps = ["GeometryTypes", "Test"] +git-tree-sha1 = "bc7c284233cf0518933bf9977e3e8234efcc1c30" +uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" +version = "0.3.0" + +[[PaddedViews]] +deps = ["OffsetArrays", "Test"] +git-tree-sha1 = "7da3e7e1a58cffbf10177553ae95f17b92516912" +uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" +version = "0.4.2" + +[[ParallelDataTransfer]] +deps = ["Distributed", "Random", "Test"] +git-tree-sha1 = "75e75900c8b0d8dfb69cbe082832b1dc9f8aacfe" +uuid = "2dcacdae-9679-587a-88bb-8b444fb7085b" +version = "0.5.0" + +[[ParameterizedFunctions]] +deps = ["DataStructures", "DiffEqBase", "InteractiveUtils", "LinearAlgebra", "SimpleTraits", "SymEngine", "Test"] +git-tree-sha1 = "6949fb675cd36624581dd3c2487f1d61d019ace7" +uuid = "65888b18-ceab-5e60-b2b9-181511a3b968" +version = "4.0.0" + +[[Parameters]] +deps = ["Markdown", "OrderedCollections", "REPL", "Test"] +git-tree-sha1 = "eec0fe16344cc14aa2e6251874ab30d62aff4f7c" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.10.2" + +[[Parsers]] +deps = ["Dates", "Mmap", "Test", "WeakRefStrings"] +git-tree-sha1 = "949ca36d47010bee093254467166487c921d490b" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "0.2.14" + +[[PenaltyFunctions]] +deps = ["InteractiveUtils", "LearnBase", "LinearAlgebra", "RecipesBase", "Reexport", "Test"] +git-tree-sha1 = "b0baaa5218ca0ffd6a8ae37ef0b58e0df688ac8b" +uuid = "06bb1623-fdd5-5ca2-a01c-88eae3ea319e" +version = "0.1.2" + +[[Pidfile]] +deps = ["FileWatching", "Test"] +git-tree-sha1 = "1ffd82728498b5071cde851bbb7abd780d4445f3" +uuid = "fa939f87-e72e-5be4-a000-7fc836dbe307" +version = "1.1.0" + +[[Pkg]] +deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" + +[[PkgLicenses]] +deps = ["Test"] +git-tree-sha1 = "0af826be249c6751a3e783c07b8cd3034f508943" +uuid = "fc669557-7ec9-5e45-bca9-462afbc28879" +version = "0.2.0" + +[[PlotThemes]] +deps = ["PlotUtils", "Requires", "Test"] +git-tree-sha1 = "f3afd2d58e1f6ac9be2cea46e4a9083ccc1d990b" +uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a" +version = "0.3.0" + +[[PlotUtils]] +deps = ["Colors", "Dates", "Printf", "Random", "Reexport", "Test"] +git-tree-sha1 = "fd28f30a294a38ec847de95d8ac7ac916ccd7c06" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "0.5.5" + +[[PlotlyBase]] +deps = ["Dates", "DelimitedFiles", "DocStringExtensions", "JSON", "LaTeXStrings", "Logging", "Requires", "Statistics", "Test", "UUIDs"] +git-tree-sha1 = "685c331de7712539c1f0d06e061fe57320bba5c9" +uuid = "a03496cd-edff-5a9b-9e67-9cda94a718b5" +version = "0.2.5" + +[[PlotlyJS]] +deps = ["Blink", "Compat", "DelimitedFiles", "JSExpr", "JSON", "Markdown", "Pkg", "PlotlyBase", "REPL", "Reexport", "Requires", "Test", "WebIO"] +git-tree-sha1 = "b0c96bf425c49e6089a78e552043470cb22f73df" +uuid = "f0f68f2c-4968-5e81-91da-67840de0976a" +version = "0.12.0" + +[[Plots]] +deps = ["Base64", "Contour", "Dates", "FixedPointNumbers", "GR", "JSON", "LinearAlgebra", "Measures", "NaNMath", "Pkg", "PlotThemes", "PlotUtils", "Printf", "Random", "RecipesBase", "Reexport", "Requires", "Showoff", "SparseArrays", "StaticArrays", "Statistics", "StatsBase", "Test", "UUIDs"] +git-tree-sha1 = "a32a9328df6c12df20754afc5843374a72fdf266" +repo-rev = "master" +repo-url = "https://github.com/JuliaPlots/Plots.jl.git" +uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +version = "0.21.0+" + +[[PoissonRandom]] +deps = ["Random", "Statistics", "Test"] +git-tree-sha1 = "831a15553303ad6ee277503672b51d1abfd83d38" +uuid = "e409e4f3-bfea-5376-8464-e040bb5c01ab" +version = "0.3.0" + +[[Polynomials]] +deps = ["LinearAlgebra", "SparseArrays", "Test"] +git-tree-sha1 = "1a1eae52956658a6acae6fa1b6d6c3d488192895" +uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" +version = "0.5.1" + +[[PooledArrays]] +deps = ["Test"] +git-tree-sha1 = "5c5ded7adc52867f599c21d3f43542fce491afda" +uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" +version = "0.4.1" + +[[PositiveFactorizations]] +deps = ["LinearAlgebra", "Test"] +git-tree-sha1 = "86ae7329c4b5c266acf5c7c524a972300d991e1c" +uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" +version = "0.2.1" + +[[Primes]] +deps = ["Test"] +git-tree-sha1 = "ff1a2323cb468ec5f201838fcbe3c232266b1f95" +uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" +version = "0.4.0" + +[[Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[Profile]] +deps = ["Printf"] +uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" + +[[ProgressMeter]] +deps = ["Distributed", "Printf", "Random", "Test"] +git-tree-sha1 = "37e7d3982c8d4610196829c01387dd561756aedc" +uuid = "92933f4c-e287-5a05-a399-4b506db050ca" +version = "0.8.0" + +[[PyCall]] +deps = ["Compat", "Conda", "MacroTools", "Statistics", "VersionParsing"] +git-tree-sha1 = "ce4681263f41d98b3faf6107b28284bf8b866f5f" +uuid = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0" +version = "1.18.5" + +[[PyPlot]] +deps = ["Colors", "Compat", "LaTeXStrings", "PyCall", "VersionParsing"] +git-tree-sha1 = "777c48006c57c8bd322d2032267085983a5fd50f" +uuid = "d330b81b-6aea-500a-939a-2ce795aea3ee" +version = "2.6.3" + +[[QBox]] +deps = ["AbstractPlotting", "ArnoldiMethod", "Arpack", "GeometryTypes", "LinearAlgebra", "LinearMaps", "Makie", "NearestNeighbors", "OffsetArrays", "ProgressMeter", "SparseArrays", "StaticArrays"] +git-tree-sha1 = "7375910b589eb23001498aa64cb4d4970e6de117" +repo-rev = "master" +repo-url = "https://github.com/pablosanjose/QBox" +uuid = "7d9ed76e-ca25-11e8-1412-8ff3848046c2" +version = "0.1.0" + +[[QBoxPlots]] +deps = ["AbstractPlotting", "GeometryTypes", "LinearAlgebra", "Makie", "QBox"] +git-tree-sha1 = "27ec515dd8daa6caadaeeb872d1cac5ae0edbb25" +repo-rev = "master" +repo-url = "https://github.com/pablosanjose/QBoxPlots" +uuid = "462ee96f-7267-546d-9451-704919036b07" +version = "0.1.0" + +[[QuadGK]] +deps = ["DataStructures", "LinearAlgebra", "Test"] +git-tree-sha1 = "7e8dff9c205f36eceaf6e62a43ff851637ca45fc" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.0.2" + +[[QuartzImageIO]] +deps = ["ColorTypes", "ColorVectorSpace", "FileIO", "FixedPointNumbers", "ImageCore", "Libdl", "Random", "Test"] +git-tree-sha1 = "c747a56f223919b157e6cd9dc58d59c560586302" +uuid = "dca85d43-d64c-5e67-8c65-017450d5d020" +version = "0.5.0" + +[[Quaternions]] +deps = ["Compat", "DualNumbers"] +git-tree-sha1 = "9ab39a818c92452f6b58d1ce88ea54cb7e038e7c" +uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" +version = "0.3.1" + +[[Query]] +deps = ["DataValues", "Documenter", "IterableTables", "MacroTools", "QueryOperators", "Statistics", "TableTraits", "Test"] +git-tree-sha1 = "e1b8e599878696dd1a9499e93fd8c707e9e7d222" +uuid = "1a8c2f83-1ff3-5112-b086-8aa67b057ba1" +version = "0.10.1" + +[[QueryOperators]] +deps = ["DataStructures", "DataValues", "IteratorInterfaceExtensions", "TableShowUtils", "Test"] +git-tree-sha1 = "4cf225548a6ab0004dfc4ca8c221946e2e8da853" +uuid = "2aef5ad7-51ca-5a8f-8e88-e75cf067b44b" +version = "0.5.1" + +[[RData]] +deps = ["CategoricalArrays", "CodecZlib", "DataFrames", "Dates", "FileIO", "Missings", "Test", "TimeZones"] +git-tree-sha1 = "8f3b644f4ebce291431846f5532272b0864c757c" +uuid = "df47a6cb-8c03-5eed-afd8-b6050d6c41da" +version = "0.5.0" + +[[RDatasets]] +deps = ["CSV", "CodecZlib", "DataFrames", "FileIO", "Printf", "RData", "Reexport", "Test"] +git-tree-sha1 = "4d93a52b94397bf0a9477d04e7a151a688672695" +uuid = "ce6b1742-4840-55fa-b093-852dadbb1d8b" +version = "0.6.1" + +[[REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[Random]] +deps = ["Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[RandomNumbers]] +deps = ["Libdl", "Printf", "Random", "Test"] +git-tree-sha1 = "0687ea782f88706ef7969bc298f170e1ac7cb606" +uuid = "e6cf234a-135c-5ec9-84dd-332b85af5143" +version = "1.0.3" + +[[RangeArrays]] +deps = ["Compat"] +git-tree-sha1 = "d925adfd5b01cb46fde89dc9548d167b3b136f4a" +uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" +version = "0.3.1" + +[[Ratios]] +deps = ["Compat"] +git-tree-sha1 = "fd159bead0a24e6270fd0573a340312bd4645cc2" +uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" +version = "0.3.0" + +[[Reactive]] +deps = ["DataStructures", "Distributed", "Test"] +git-tree-sha1 = "2384e3bda9dcd16750ff605fdf817e18cfdd9bae" +uuid = "a223df75-4e93-5b7c-acf9-bdd599c0f4de" +version = "0.8.2" + +[[RecipesBase]] +deps = ["Random", "Test"] +git-tree-sha1 = "0b3cb370ee4dc00f47f1193101600949f3dcf884" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "0.6.0" + +[[RecursiveArrayTools]] +deps = ["RecipesBase", "Requires", "StaticArrays", "Statistics", "Test"] +git-tree-sha1 = "5ac1ea7d018bec90b0be614a9a37d1fd80dce8d9" +uuid = "731186ca-8d62-57ce-b412-fbd966d074cd" +version = "0.18.4" + +[[Reexport]] +deps = ["Pkg"] +git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "0.2.0" + +[[Requires]] +deps = ["Test"] +git-tree-sha1 = "f6fbf4ba64d295e146e49e021207993b6b48c7d1" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "0.5.2" + +[[ResettableStacks]] +deps = ["Random", "StaticArrays", "Test"] +git-tree-sha1 = "263fe0a06007bf5ba8f72c55475f58fc9bf81834" +uuid = "ae5879a3-cd67-5da8-be7f-38c6eb64a37b" +version = "0.5.0" + +[[ReverseDiff]] +deps = ["DiffResults", "DiffRules", "ForwardDiff", "FunctionWrappers", "LinearAlgebra", "NaNMath", "Random", "SpecialFunctions", "StaticArrays", "Statistics", "Test"] +git-tree-sha1 = "d44e80d815a1a5abaf1ff1def21bb629cabaffec" +uuid = "37e2e3b7-166d-5795-8a7a-e32c996b4267" +version = "0.3.1" + +[[Revise]] +deps = ["Distributed", "FileWatching", "InteractiveUtils", "LibGit2", "OrderedCollections", "Pkg", "REPL", "Random", "Test", "UUIDs", "Unicode"] +git-tree-sha1 = "556c5f7bd46f99dee93b5e49a1339499beec0e05" +repo-rev = "master" +repo-url = "https://github.com/timholy/Revise.jl.git" +uuid = "295af30f-e4ad-537b-8983-00126c2a3abe" +version = "0.7.13+" + +[[Rmath]] +deps = ["BinaryProvider", "Libdl", "Random", "Statistics", "Test"] +git-tree-sha1 = "9a6c758cdf73036c3239b0afbea790def1dabff9" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.5.0" + +[[Roots]] +deps = ["Compat", "Printf"] +git-tree-sha1 = "2e7171b6f3b58b81201ba37d9e1220aff6d904a1" +uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" +version = "0.7.4" + +[[Rotations]] +deps = ["LinearAlgebra", "Random", "StaticArrays", "Statistics", "Test"] +git-tree-sha1 = "b629771d0de88979cbdbf72ceddc54de58fde149" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "0.9.1" + +[[SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" + +[[SIUnits]] +deps = ["Compat", "TexExtensions"] +git-tree-sha1 = "224d83b62711fe7e429454aace2c97eb2cf36031" +uuid = "b9d75638-96e3-5676-bdf0-e9c958f63a55" +version = "0.1.0" + +[[Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[SetRounding]] +deps = ["Test"] +git-tree-sha1 = "faca28c7937138d560ede5bfef2076d0cdf3584b" +uuid = "3cc68bcd-71a2-5612-b932-767ffbe40ab0" +version = "0.2.0" + +[[SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[Showoff]] +deps = ["Compat"] +git-tree-sha1 = "276b24f3ace98bec911be7ff2928d497dc759085" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "0.2.1" + +[[SignedDistanceFields]] +deps = ["Random", "Statistics", "Test"] +git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" +uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" +version = "0.4.0" + +[[SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools", "Test"] +git-tree-sha1 = "c0a542b8d5e369b179ccd296b2ca987f6da5da0a" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.8.0" + +[[SingularIntegralEquations]] +deps = ["ApproxFun", "BandedMatrices", "DomainSets", "DualNumbers", "FastTransforms", "InteractiveUtils", "LinearAlgebra", "LowRankApprox", "RecipesBase", "SpecialFunctions", "Test"] +git-tree-sha1 = "87955f9f6d8b7aa0388230867928fd099743539b" +uuid = "e094c991-5a90-5477-8896-c1e4c9552a1a" +version = "0.4.1" + +[[SnoopCompile]] +deps = ["Pkg", "Serialization", "Test"] +git-tree-sha1 = "bf278fd3d9ec1d8183dcf81291c1994561b66c93" +uuid = "aa65fe97-06da-5843-b5b1-d5d13cad87d2" +version = "0.3.1" + +[[Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[SoftGlobalScope]] +deps = ["Test"] +git-tree-sha1 = "97f6dfcf612b9a7260fde44170725d9ea34b1431" +uuid = "b85f4697-e234-5449-a836-ec8e2f98b302" +version = "1.0.7" + +[[SortingAlgorithms]] +deps = ["DataStructures", "Random", "Test"] +git-tree-sha1 = "03f5898c9959f8115e30bc7226ada7d0df554ddd" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "0.3.1" + +[[SparseArrays]] +deps = ["LinearAlgebra", "Random"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[SpecialFunctions]] +deps = ["BinDeps", "BinaryProvider", "Libdl", "Test"] +git-tree-sha1 = "0b45dc2e45ed77f445617b99ff2adf0f5b0f23ea" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "0.7.2" + +[[StatPlots]] +deps = ["Clustering", "DataStructures", "DataValues", "Distributions", "IterableTables", "KernelDensity", "Observables", "Plots", "Reexport", "StatsBase", "TableTraits", "TableTraitsUtils", "Test", "Widgets"] +git-tree-sha1 = "e35b968df3937eaee1c8df698bcfd7d047c45110" +uuid = "60ddc479-9b66-56df-82fc-76a74619b69c" +version = "0.8.2" + +[[StaticArrays]] +deps = ["InteractiveUtils", "LinearAlgebra", "Random", "Statistics", "Test"] +git-tree-sha1 = "6804a209e3a3cc436c56da0d4d67789159b1b232" +repo-rev = "master" +repo-url = "https://github.com/JuliaArrays/StaticArrays.jl.git" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "0.10.0+" + +[[Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[StatsBase]] +deps = ["DataStructures", "LinearAlgebra", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "Test"] +git-tree-sha1 = "2722397d88f8ffef551948f6c20e1d74a743298c" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.26.0" + +[[StatsFuns]] +deps = ["Rmath", "SpecialFunctions", "Test"] +git-tree-sha1 = "d14bb7b03defd2deaa5675646f6783089e0556f0" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "0.7.0" + +[[StatsMakie]] +deps = ["AbstractPlotting", "Distributions", "FreqTables", "IndexedTables", "IntervalSets", "KernelDensity", "Loess", "NamedArrays", "Observables", "Random", "Statistics", "StatsBase", "Tables", "Test"] +git-tree-sha1 = "7745ba65ac5a3d17514a605dd87ec6fb54c708e9" +repo-rev = "master" +repo-url = "https://github.com/JuliaPlots/StatsMakie.jl.git" +uuid = "9d48ccf0-4268-5716-84ff-21228f561db3" +version = "0.0.0" + +[[SteadyStateDiffEq]] +deps = ["Compat", "DiffEqBase", "DiffEqCallbacks", "LinearAlgebra", "NLsolve", "Reexport", "Test"] +git-tree-sha1 = "fe9852d18c3e30f384003da50d6049e5fbc97071" +uuid = "9672c7b4-1e72-59bd-8a11-6ac3964bc41f" +version = "1.4.0" + +[[StochasticDiffEq]] +deps = ["DataStructures", "DiffEqBase", "DiffEqDiffTools", "DiffEqNoiseProcess", "DiffEqOperators", "Distributed", "ForwardDiff", "LinearAlgebra", "Logging", "MuladdMacro", "NLsolve", "Parameters", "Random", "RandomNumbers", "RecursiveArrayTools", "Reexport", "SparseArrays", "StaticArrays", "Test"] +git-tree-sha1 = "c1542e708fa2947cf7a82c376a8c99dc448e6ca1" +uuid = "789caeaf-c7a9-5a7d-9973-96adeb23e2a0" +version = "5.10.1" + +[[Strided]] +deps = ["LinearAlgebra", "Random", "Test", "TupleTools"] +git-tree-sha1 = "b03964f2d298810910195f3e8d56ceff8f60e02a" +uuid = "5e0ebb24-38b0-5f93-81fe-25c709ecae67" +version = "0.2.2" + +[[StringDistances]] +deps = ["Distances", "IterTools", "Test"] +git-tree-sha1 = "41fddd579b75e0cd0d1bbdb2d68a2a9cc588c164" +uuid = "88034a9c-02f8-509d-84a9-84ec65e18404" +version = "0.3.0" + +[[StructArrays]] +deps = ["Requires", "Test"] +git-tree-sha1 = "d1e764a3afdd6e4326392144fc0c81faf55e48a9" +uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" +version = "0.1.0" + +[[StructIO]] +deps = ["Test"] +git-tree-sha1 = "010dc73c7146869c042b49adcdb6bf528c12e859" +uuid = "53d494c1-5632-5724-8f4c-31dff12d585f" +version = "0.3.0" + +[[SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[Sundials]] +deps = ["BinaryProvider", "DataStructures", "DiffEqBase", "Libdl", "LinearAlgebra", "Reexport", "SparseArrays", "Test"] +git-tree-sha1 = "01ecb3f3dc5c57f9cf0ae3ccf91ede899440d076" +uuid = "c3572dad-4567-51f8-b174-8c6c989267f4" +version = "2.6.0" + +[[Suppressor]] +deps = ["Compat"] +git-tree-sha1 = "a39342763981e766a72938b59032dc02a2d74da5" +uuid = "fd094767-a336-5f1f-9728-57cf17d0bbfb" +version = "0.1.1" + +[[SweepOperator]] +deps = ["LinearAlgebra", "Test"] +git-tree-sha1 = "2039aaa96f7b21634a1b3246cb2699dd1d26d473" +uuid = "7522ee7d-7047-56d0-94d9-4bc626e7058d" +version = "0.2.0" + +[[SymEngine]] +deps = ["BinaryProvider", "Compat", "Libdl", "RecipesBase", "SpecialFunctions"] +git-tree-sha1 = "bd5ca0295542ad6967f3f837bb6bef6add0e4c33" +uuid = "123dc426-2d89-5057-bbad-38513e3affd8" +version = "0.4.3" + +[[TableShowUtils]] +deps = ["DataValues", "Dates", "JSON", "Markdown", "Test"] +git-tree-sha1 = "6ffc18504eab3f900af2d23adc0e7bddf94bd29b" +uuid = "5e66a065-1f0a-5976-b372-e0b8c017ca10" +version = "0.2.1" + +[[TableTraits]] +deps = ["IteratorInterfaceExtensions", "Test"] +git-tree-sha1 = "da062a2c31f16178f68190243c24140801720a43" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "0.4.0" + +[[TableTraitsUtils]] +deps = ["DataValues", "IteratorInterfaceExtensions", "Missings", "TableTraits", "Test"] +git-tree-sha1 = "a355f1882d64881a11f853e64dcc353975c4df6e" +uuid = "382cd787-c1b6-5bf2-a167-d5b971a19bda" +version = "0.3.1" + +[[Tables]] +deps = ["Requires", "Test"] +git-tree-sha1 = "c7fb447deab835fa70ce6717e78c68b0f466a42c" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "0.1.11" + +[[Test]] +deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[TexExtensions]] +deps = ["Compat"] +git-tree-sha1 = "092ad55ed044aa5ab31ee800d4ae5bec526a8f09" +uuid = "9b435220-3ad3-5d4f-b1ea-1e7b29ae9b13" +version = "0.1.0" + +[[TextParse]] +deps = ["CodecZlib", "DataStructures", "Dates", "DoubleFloats", "Mmap", "Nullables", "PooledArrays", "Random", "Test", "WeakRefStrings"] +git-tree-sha1 = "383329847d816310d63df8e220d1be0b68e0cecc" +uuid = "e0df1984-e451-5cb5-8b61-797a481e67e3" +version = "0.6.1" + +[[TextWrap]] +deps = ["Compat", "Test"] +git-tree-sha1 = "8355cc559e85469cd4dbe927c375f61d3750e002" +uuid = "b718987f-49a8-5099-9789-dcd902bef87d" +version = "0.3.0" + +[[TiledIteration]] +deps = ["OffsetArrays", "Test"] +git-tree-sha1 = "58f6f07d3b54a363ec283a8f5fc9fb4ecebde656" +uuid = "06e1c1a7-607b-532d-9fad-de7d9aa2abac" +version = "0.2.3" + +[[TimeZones]] +deps = ["Compat", "EzXML", "Mocking", "Nullables"] +git-tree-sha1 = "4a4ab113913e19ad62b67e6c5c056509eac00c19" +uuid = "f269a46b-ccf7-5d73-abea-4c690281aa53" +version = "0.8.2" + +[[TimerOutputs]] +deps = ["Crayons", "Printf", "Test", "Unicode"] +git-tree-sha1 = "89a9bd610d6bfd62a7c2b85112762b99b979fe5f" +uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" +version = "0.4.0" + +[[ToeplitzMatrices]] +deps = ["Compat", "FFTW", "LinearAlgebra", "StatsBase"] +git-tree-sha1 = "141e0fc05428a280a056cfdea6b98ef54a208535" +uuid = "c751599d-da0a-543b-9d20-d0a503d91d24" +version = "0.4.2" + +[[Tokenize]] +deps = ["Printf", "Test"] +git-tree-sha1 = "4a9fefb5c5c831c6fc06fcc5d2ae7399918bb587" +uuid = "0796e94c-ce3b-5d07-9a54-7f471281c624" +version = "0.5.2" + +[[Traceur]] +deps = ["Cassette", "InteractiveUtils", "Logging", "MacroTools", "Test"] +git-tree-sha1 = "d46ea4a2575f896e90c8a4b52ce2841e6db7d059" +uuid = "37b6cedf-1f77-55f8-9503-c64b63398394" +version = "0.2.0" + +[[TranscodingStreams]] +deps = ["Pkg", "Random", "Test"] +git-tree-sha1 = "a34a2d588e2d2825602bf14a24216d5c8b0921ec" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.8.1" + +[[TreeViews]] +deps = ["Test"] +git-tree-sha1 = "8d0d7a3fe2f30d6a7f833a5f19f7c7a5b396eae6" +uuid = "a2a6695c-b41b-5b7d-aed9-dbfdeacea5d7" +version = "0.3.0" + +[[TupleTools]] +deps = ["Random", "Test"] +git-tree-sha1 = "781df0cfac68723c3800eb9344b85bd86f9e424b" +uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" +version = "1.0.2" + +[[URIParser]] +deps = ["Test", "Unicode"] +git-tree-sha1 = "6ddf8244220dfda2f17539fa8c9de20d6c575b69" +uuid = "30578b45-9adc-5946-b283-645ec420af67" +version = "0.4.0" + +[[UUIDs]] +deps = ["Random"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[UnicodeFun]] +deps = ["Test"] +git-tree-sha1 = "63cbbd00217fc9aafedf055b60459c1ae7e01ecc" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.0" + +[[Unitful]] +deps = ["LinearAlgebra", "Random", "Test"] +git-tree-sha1 = "15c921708e19258fc9e7723aafc5f15c973ee77f" +uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" +version = "0.13.0" + +[[VectorizedRoutines]] +deps = ["Distributions"] +git-tree-sha1 = "3fdeedbc9d462a3d597606ad8183cf5907e04896" +uuid = "0e69188a-a5d4-5622-b4e4-a72373136fc5" +version = "0.0.2" + +[[VegaDatasets]] +deps = ["DataStructures", "DataValues", "FilePaths", "IterableTables", "IteratorInterfaceExtensions", "JSON", "TableShowUtils", "TableTraits", "TableTraitsUtils", "Test", "TextParse"] +git-tree-sha1 = "894794f267e13d4d440a3720e11ba212d5d28f47" +uuid = "0ae4a718-28b7-58ec-9efb-cded64d6d5b4" +version = "0.5.0" + +[[VersionParsing]] +deps = ["Compat"] +git-tree-sha1 = "c9d5aa108588b978bd859554660c8a5c4f2f7669" +uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" +version = "1.1.3" + +[[WeakRefStrings]] +deps = ["Missings", "Random", "Test"] +git-tree-sha1 = "1087e8be380f2c8b96434b02bb1150fc1c511135" +uuid = "ea10d353-3f73-51f8-a26c-33c1cb351aa5" +version = "0.5.3" + + +[[WebSockets]] +deps = ["Base64", "Dates", "Distributed", "HTTP", "Logging", "MbedTLS", "Random", "Sockets", "Test"] +git-tree-sha1 = "c898a35f93bb010d8e44932c1a736e22c6343f9c" +uuid = "104b5d7c-a370-577a-8038-80a2059c5097" +version = "1.1.0" + + +[[Widgets]] +deps = ["DataStructures", "Observables", "Test"] +git-tree-sha1 = "944c2f6c3b92b0689e5f46988536bee26bba4d8a" +uuid = "cc8bc4a8-27d6-5769-a93b-9d913e69aa62" +version = "0.4.3" + +[[WinRPM]] +deps = ["BinDeps", "Compat", "HTTPClient", "LibExpat", "Libdl", "Libz", "URIParser"] +git-tree-sha1 = "2a889d320f3b77d17c037f295859fe570133cfbf" +uuid = "c17dfb99-b4f7-5aad-8812-456da1ad7187" +version = "0.4.2" + +[[WoodburyMatrices]] +deps = ["LinearAlgebra", "Random", "SparseArrays", "Test"] +git-tree-sha1 = "21772c33b447757ec7d3e61fcdfb9ea5c47eedcf" +uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" +version = "0.4.1" + +[[ZMQ]] +deps = ["BinaryProvider", "FileWatching", "Libdl", "Sockets", "Test"] +git-tree-sha1 = "34e7ac2d1d59d19d0e86bde99f1f02262bfa1613" +uuid = "c2297ded-f4af-51ae-bb23-16f91089e4e1" +version = "1.0.0" + +[[ZipFile]] +deps = ["BinaryProvider", "Libdl", "Printf", "Test"] +git-tree-sha1 = "4000c633efe994b2e10b31b6d91382c4b7412dac" +uuid = "a5390f91-8eb1-5f08-bee0-b1d1ffed6cea" +version = "0.8.0" + +[[Zygote]] +deps = ["DiffRules", "ForwardDiff", "InteractiveUtils", "MacroTools", "NNlib", "NaNMath", "Random", "Requires", "SpecialFunctions", "Test"] +git-tree-sha1 = "e41d254728d3968052c3ef62134f063257a4f077" +uuid = "e88e6eb3-aa80-5325-afca-941959d7151f" +version = "0.1.0" diff --git a/Project.toml b/Project.toml new file mode 100644 index 00000000000..1be5a9403f2 --- /dev/null +++ b/Project.toml @@ -0,0 +1,39 @@ +name = "GLMakie" +uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" + +[deps] +AbstractPlotting = "537997a7-5e4e-5d89-9595-2241ea00577e" +AxisArrays = "39de3d68-74b9-583c-8d2d-e117c070f3a9" +ColorBrewer = "a2cac450-b92f-5266-8821-25eda20663c8" +ColorTypes = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +ColorVectorSpace = "c3611d14-8923-5661-9e6a-0046d554d3a4" +Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" +Contour = "d38c429a-6771-53c6-b99e-75d170b6e991" +FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +FixedPointNumbers = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +FreeType = "b38be410-82b0-50bf-ab77-7b57e271db43" +FreeTypeAbstraction = "663a7486-cb36-511b-a19d-713bb74d65c9" +GLFW = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" +GeometryTypes = "4d00f742-c7ba-57c2-abde-4428a4b178cb" +ImageAxes = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" +ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534" +ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" +ImageTransformations = "02fcd773-0e25-5acc-982a-7f6622650795" +IndirectArrays = "9b13fd28-a010-5f03-acff-a1bbcff69959" +IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" +IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a" +ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" +Observables = "510215fc-4207-5dde-b226-833fc4488ee2" +Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +PlotUtils = "995b91a9-d308-5afd-9ec6-746e21dbc043" +Primes = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" +Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" +QuartzImageIO = "dca85d43-d64c-5e67-8c65-017450d5d020" +Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +Showoff = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" +Suppressor = "fd094767-a336-5f1f-9728-57cf17d0bbfb" +UnicodeFun = "1cfade01-22cf-5700-b092-accc4b62d6e1" +MakieGallery = "62e31da0-2f4f-5d53-819c-a7cea9df6aaa" diff --git a/deps/.gitignore b/deps/.gitignore new file mode 100644 index 00000000000..a8075e39ac3 --- /dev/null +++ b/deps/.gitignore @@ -0,0 +1,2 @@ +build.log +deps.jl diff --git a/deps/build.jl b/deps/build.jl new file mode 100644 index 00000000000..849dd007718 --- /dev/null +++ b/deps/build.jl @@ -0,0 +1,56 @@ +install_tips = """ +OpenGL/GLFW wasn't installed correctly. This likely means, +you don't have an OpenGL capable Graphic Card, +you don't have the newest video driver installed, +or the GLFW build failed. If you're on linux and `]build` GLFW failed, +try manually adding `sudo apt-get install libglfw3` and then `]build GLMakie`. +If you're on a headless server, you still need to install x-server and +propper GPU drivers. You can take inspiration from this article +on how to get Makie running on a headless system: +https://nextjournal.com/sdanisch/makie-1.0 +If you don't have a GPU, there is also a Cairo software backend +for Makie which you can use: +https://github.com/JuliaPlots/CairoMakie.jl. +Please check the below error and open an issue at: +https://github.com/JuliaPlots/GLMakie.jl. +After you fixed your OpenGL install, please run `]build GLMakie` again! +GLMakie will still load, but will be disabled as a default backend for Makie +""" +try + using GLFW +catch e + open("deps.jl", "w") do io + println(io, "const WORKING_OPENGL = false") + end + # it would be nice to check if this is a GLFW error, but if GLFW doesn't actually load + # we can't easily use GLFW.GLFWError. Well, GLFW error is the most likely, and + # we will print the error, to inform the user what happens, so I think this should be fine! + error(install_tips) +end + +using ModernGL +# Create a windowed mode window and its OpenGL context +window = GLFW.CreateWindow(10, 10, "OpenGL Example") +# Make the window's context current +GLFW.HideWindow(window) +GLFW.MakeContextCurrent(window) +glversion = unsafe_string(glGetString(GL_VERSION)) +m = match(r"(\d+)\.(\d+)\.(\d+)?(.*)", glversion) +# I don't really trust that all vendors have a version that matches +# the above regex, so let's make no match non fatal! +if m === nothing + @warn("Unknown OpenGL version format: $glversion. You need to verify if it's above OpenGL 3.3 yourself!") +else + v = VersionNumber(parse(Int, m[1]), parse(Int, m[2])) + if !(v >= v"3.3") + open("deps.jl", "w") do io + println(io, "const WORKING_OPENGL = false") + end + println(stderr, "Your OpenGL version is too low! Update your driver or GPU! Version found: $v, version required: 3.3") + error(install_tips) + end +end + +open("deps.jl", "w") do io + println(io, "const WORKING_OPENGL = true") +end diff --git a/src/GLAbstraction/GLAbstraction.jl b/src/GLAbstraction/GLAbstraction.jl index ea9b62986e4..0336fdfbf6a 100644 --- a/src/GLAbstraction/GLAbstraction.jl +++ b/src/GLAbstraction/GLAbstraction.jl @@ -7,7 +7,7 @@ using AbstractPlotting using FixedPointNumbers using ColorTypes using FileIO -using GLFW +using ..GLMakie.GLFW using Printf using LinearAlgebra using AbstractPlotting diff --git a/src/GLMakie.jl b/src/GLMakie.jl index 74ff558f03a..564d246429c 100644 --- a/src/GLMakie.jl +++ b/src/GLMakie.jl @@ -1,101 +1,54 @@ module GLMakie -using ModernGL, GLFW, FixedPointNumbers, Colors, GeometryTypes -using AbstractPlotting, StaticArrays -using AbstractPlotting: Scene, Lines, Text, Image, Heatmap, Scatter, @key_str, Key, broadcast_foreach -using AbstractPlotting: convert_attribute, @extractvalue, LineSegments, to_ndim, NativeFont +using ModernGL, FixedPointNumbers, Colors, GeometryTypes, StaticArrays +using AbstractPlotting, FreeType, FreeTypeAbstraction, FileIO, IntervalSets +using ImageCore + +using AbstractPlotting: @key_str, Key, broadcast_foreach, to_ndim, NativeFont +using AbstractPlotting: Scene, Lines, Text, Image, Heatmap, Scatter +using AbstractPlotting: convert_attribute, @extractvalue, LineSegments using AbstractPlotting: @get_attribute, to_value, to_colormap, extrema_nan +using IntervalSets: ClosedInterval, (..) + using Base: RefValue import Base: push!, isopen, show -using FileIO -using ImageCore -import IntervalSets -using IntervalSets: ClosedInterval, (..) using Base.Iterators: repeated, drop -using FreeType, FreeTypeAbstraction, FixedPointNumbers for name in names(AbstractPlotting) @eval import AbstractPlotting: $(name) end -import AbstractPlotting: colorbuffer - -include("GLAbstraction/GLAbstraction.jl") -using .GLAbstraction - -const atlas_texture_cache = Dict{Any, Tuple{Texture{Float16, 2}, Function}}() - -function get_texture!(atlas) - # clean up dead context! - filter!(atlas_texture_cache) do (ctx, tex_func) - if GLAbstraction.context_alive(ctx) - true - else - AbstractPlotting.remove_font_render_callback!(tex_func[2]) - false - end - end - tex, func = get!(atlas_texture_cache, GLAbstraction.current_context()) do - tex = Texture( - atlas.data, - minfilter = :linear, - magfilter = :linear, - anisotropic = 16f0, - ) - # update the texture, whenever a new font is added to the atlas - function callback(distance_field, rectangle) - ctx = tex.context - if GLAbstraction.context_alive(ctx) - prev_ctx = GLAbstraction.current_context() - GLAbstraction.switch_context!(ctx) - tex[rectangle] = distance_field - GLAbstraction.switch_context!(prev_ctx) - end - end - AbstractPlotting.font_render_callback!(callback) - return (tex, callback) - end - tex -end - -include("GLVisualize/GLVisualize.jl") -using .GLVisualize - -include("glwindow.jl") -include("screen.jl") -include("rendering.jl") -include("events.jl") -include("drawing_primitives.jl") - struct GLBackend <: AbstractPlotting.AbstractBackend end -function AbstractPlotting.backend_display(x::GLBackend, scene::Scene) - screen = global_gl_screen() - # This should only get called if inline display false, so we display the window - GLFW.set_visibility!(to_native(screen), true) - display(screen, scene) - return screen -end """ - scene2image(scene::Scene) +returns path relative to the assets folder +""" +assetpath(folders...) = joinpath(@__DIR__, "GLVisualize", "assets", folders...) -Buffers the `scene` in an image buffer. + +""" +Loads a file from the asset folder """ -function scene2image(scene::Scene) - screen = global_gl_screen() - display(screen, scene) - colorbuffer(screen) +function loadasset(folders...; kw_args...) + path = assetpath(folders...) + isfile(path) || isdir(path) || error("Could not locate file at $path") + load(path; kw_args...) end -function AbstractPlotting.backend_show(::GLBackend, io::IO, m::MIME"image/png", scene::Scene) - img = scene2image(scene) - GLFW.set_visibility!(to_native(global_gl_screen()), !AbstractPlotting.use_display[]) - FileIO.save(FileIO.Stream(FileIO.format"PNG", io), img) +export assetpath, loadasset + +include("../deps/deps.jl") + +if WORKING_OPENGL + # don't put this into try catch, to not mess with normal errors + include("gl_backend.jl") end function __init__() - AbstractPlotting.register_backend!(GLBackend()) + if WORKING_OPENGL + AbstractPlotting.register_backend!(GLBackend()) + end end end diff --git a/src/GLVisualize/GLVisualize.jl b/src/GLVisualize/GLVisualize.jl index 67f69e416fd..59c2393b3b0 100644 --- a/src/GLVisualize/GLVisualize.jl +++ b/src/GLVisualize/GLVisualize.jl @@ -3,7 +3,7 @@ module GLVisualize using ..GLAbstraction using AbstractPlotting: RaymarchAlgorithm, IsoValue, Absorption, MaximumIntensityProjection, AbsorptionRGBA, IndexedAbsorptionRGBA -using GLFW +using ..GLMakie.GLFW using ModernGL using StaticArrays using GeometryTypes @@ -40,23 +40,7 @@ Replacement of Pkg.dir("GLVisualize") --> GLVisualize.dir, returning the correct path """ dir(dirs...) = joinpath(@__DIR__, dirs...) - -""" -returns path relative to the assets folder -""" -assetpath(folders...) = dir("assets", folders...) - -""" -Loads a file from the asset folder -""" -function loadasset(folders...; kw_args...) - path = assetpath(folders...) - isfile(path) || isdir(path) || error("Could not locate file at $path") - load(path; kw_args...) -end - -export assetpath, loadasset - +using ..GLMakie: assetpath, loadasset include("types.jl") export CIRCLE, RECTANGLE, ROUNDED_RECTANGLE, DISTANCEFIELD, TRIANGLE diff --git a/src/gl_backend.jl b/src/gl_backend.jl new file mode 100644 index 00000000000..06234da685c --- /dev/null +++ b/src/gl_backend.jl @@ -0,0 +1,74 @@ +using GLFW + +include("GLAbstraction/GLAbstraction.jl") + +using .GLAbstraction + +const atlas_texture_cache = Dict{Any, Tuple{Texture{Float16, 2}, Function}}() + +function get_texture!(atlas) + # clean up dead context! + filter!(atlas_texture_cache) do (ctx, tex_func) + if GLAbstraction.context_alive(ctx) + true + else + AbstractPlotting.remove_font_render_callback!(tex_func[2]) + false + end + end + tex, func = get!(atlas_texture_cache, GLAbstraction.current_context()) do + tex = Texture( + atlas.data, + minfilter = :linear, + magfilter = :linear, + anisotropic = 16f0, + ) + # update the texture, whenever a new font is added to the atlas + function callback(distance_field, rectangle) + ctx = tex.context + if GLAbstraction.context_alive(ctx) + prev_ctx = GLAbstraction.current_context() + GLAbstraction.switch_context!(ctx) + tex[rectangle] = distance_field + GLAbstraction.switch_context!(prev_ctx) + end + end + AbstractPlotting.font_render_callback!(callback) + return (tex, callback) + end + tex +end + +include("GLVisualize/GLVisualize.jl") +using .GLVisualize + +include("glwindow.jl") +include("screen.jl") +include("rendering.jl") +include("events.jl") +include("drawing_primitives.jl") + +function AbstractPlotting.backend_display(x::GLBackend, scene::Scene) + screen = global_gl_screen() + # This should only get called if inline display false, so we display the window + GLFW.set_visibility!(to_native(screen), AbstractPlotting.use_display[]) + display(screen, scene) + return screen +end + +""" + scene2image(scene::Scene) + +Buffers the `scene` in an image buffer. +""" +function scene2image(scene::Scene) + screen = global_gl_screen() + display(screen, scene) + AbstractPlotting.colorbuffer(screen) +end + +function AbstractPlotting.backend_show(::GLBackend, io::IO, m::MIME"image/png", scene::Scene) + img = scene2image(scene) + GLFW.set_visibility!(to_native(global_gl_screen()), AbstractPlotting.use_display[]) + FileIO.save(FileIO.Stream(FileIO.format"PNG", io), img) +end diff --git a/src/screen.jl b/src/screen.jl index 47df5203de2..dc49f23dd94 100644 --- a/src/screen.jl +++ b/src/screen.jl @@ -112,7 +112,7 @@ function fast_color_data!(dest::Array{RGB{N0f8}, 2}, source::Texture{T, 2}) wher end -function colorbuffer(screen::Screen) +function AbstractPlotting.colorbuffer(screen::Screen) if isopen(screen) GLFW.PollEvents() render_frame(screen) # let it render diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 00000000000..2a639590407 --- /dev/null +++ b/test/.gitignore @@ -0,0 +1,2 @@ +tested_different +test_recordings diff --git a/test/runtests.jl b/test/runtests.jl index c3897b7c5b2..45ed5bbad5b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,8 +1,19 @@ -using Pkg +using MakieGallery, Makie, GLMakie -pkg"add Makie#sd-glmakie https://github.com/JuliaPlots/MakieGallery.jl" +database = MakieGallery.load_database() +# THese examples download additional data - don't want to deal with that! +to_skip = ["WorldClim visualization", "Image on Geometry (Moon)", "Image on Geometry (Earth)"] +# we directly modify the database, which seems easiest for now +filter!(entry-> !(entry.title in to_skip), database) -#pkg"test MakieGallery" -using MakieGallery, GLMakie +ref_path = MakieGallery.download_reference(v"0.0.9") -include(joinpath(dirname(pathof(MakieGallery)), "..", "test", "runtests.jl")) +tested_diff_path = joinpath(@__DIR__, "tested_different") +test_record_path = joinpath(@__DIR__, "test_recordings") +rm(tested_diff_path, force = true, recursive = true) +mkpath(tested_diff_path) +rm(test_record_path, force = true, recursive = true) +mkpath(test_record_path) + +MakieGallery.record_examples(test_record_path) +MakieGallery.run_comparison(test_record_path, ref_path, tested_diff_path) From 1eacee128770400c159f7a7f6cb4841dd008cf3b Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 28 Nov 2018 20:27:47 +0100 Subject: [PATCH 0016/1328] fix libmagick --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c7fa5377d60..b140a4a6d30 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,7 +10,7 @@ job: # glfw - apt-get install -y cmake libxrandr-dev libxinerama-dev libxcursor-dev mesa-utils # cairo etc - - apt-get install -y gettext libpango1.0-0 libcairo2 libmagickwand-6.q16-2 + - apt-get install -y gettext libpango1.0-0 libcairo2 libmagickwand-6.q16 - apt-get install -y ffmpeg script: From 9f289403b654f7de9eacf2fbcb8075374266d9cc Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Thu, 29 Nov 2018 12:22:04 +0100 Subject: [PATCH 0017/1328] conflict free Manifest --- Manifest.toml | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/Manifest.toml b/Manifest.toml index 8c34bfbc412..24f92bbb2e6 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -232,6 +232,13 @@ git-tree-sha1 = "a427098d5aa2808504d94b8ed9fc5740ceaf71d0" uuid = "159f3aea-2a34-519c-b102-8c37f9878175" version = "0.5.6" +[[CairoMakie]] +deps = ["AbstractPlotting", "Cairo", "Colors", "GeometryTypes", "Makie", "StaticArrays"] +git-tree-sha1 = "5d3e8ec512713ccda544c59cb5c41d1184c0f7b5" +repo-rev = "master" +repo-url = "https://github.com/JuliaPlots/CairoMakie.jl.git" +uuid = "f1797859-2bec-5491-832b-e19d79114491" +version = "0.0.0" [[Calculus]] deps = ["Compat"] @@ -774,6 +781,11 @@ git-tree-sha1 = "035e2b5e9c335afae1e92ecfe532cf0620da869f" uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" version = "2.3.0" +[[GLMakie]] +deps = ["AbstractPlotting", "AxisArrays", "ColorBrewer", "ColorTypes", "ColorVectorSpace", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GLFW", "GeometryTypes", "ImageAxes", "ImageCore", "ImageMagick", "ImageTransformations", "IndirectArrays", "IntervalSets", "IterTools", "LinearAlgebra", "Makie", "Markdown", "ModernGL", "Observables", "Pkg", "PlotUtils", "Primes", "Printf", "QuartzImageIO", "Serialization", "Showoff", "StaticArrays", "UnicodeFun"] +git-tree-sha1 = "2e3cb969fd8f8cab98a4863d4a97d24bb1efdbd0" +uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" +version = "0.0.1" [[GPUArrays]] deps = ["FFTW", "FillArrays", "LinearAlgebra", "Pkg", "Printf", "Random", "Serialization", "StaticArrays", "Test"] @@ -1394,6 +1406,11 @@ git-tree-sha1 = "9e3e7a5c9b8cfdba8c01a1bcae38fe0144936fda" uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" version = "0.9.5" +[[PackageCompiler]] +deps = ["ArgParse", "Libdl", "Pkg", "Serialization", "SnoopCompile", "Test", "WinRPM"] +git-tree-sha1 = "ba059afb6e9300fb4b059669cd695521e166c670" +uuid = "9b87118b-4619-50d2-8e1e-99f35a4d4d9d" +version = "0.5.1" [[Packing]] deps = ["GeometryTypes", "Test"] @@ -2021,6 +2038,11 @@ git-tree-sha1 = "1087e8be380f2c8b96434b02bb1150fc1c511135" uuid = "ea10d353-3f73-51f8-a26c-33c1cb351aa5" version = "0.5.3" +[[WebIO]] +deps = ["AssetRegistry", "Base64", "Compat", "FunctionalCollections", "JSON", "Logging", "Observables", "Random", "Requires", "Sockets", "Test", "UUIDs", "Widgets"] +git-tree-sha1 = "c1edaf26cc283d81edd97385fb8fde80018b0770" +uuid = "0f1e0344-ec1d-5b48-a673-e5cf874b6c29" +version = "0.6.1" [[WebSockets]] deps = ["Base64", "Dates", "Distributed", "HTTP", "Logging", "MbedTLS", "Random", "Sockets", "Test"] @@ -2028,7 +2050,6 @@ git-tree-sha1 = "c898a35f93bb010d8e44932c1a736e22c6343f9c" uuid = "104b5d7c-a370-577a-8038-80a2059c5097" version = "1.1.0" - [[Widgets]] deps = ["DataStructures", "Observables", "Test"] git-tree-sha1 = "944c2f6c3b92b0689e5f46988536bee26bba4d8a" From be1b6c875b36b70f877d0f9e9831fd189ba9a312 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Sun, 2 Dec 2018 12:10:57 +0100 Subject: [PATCH 0018/1328] remove manifest for now --- Manifest.toml | 2087 ------------------------------------------------- Project.toml | 39 - test/REQUIRE | 1 + 3 files changed, 1 insertion(+), 2126 deletions(-) delete mode 100644 Manifest.toml delete mode 100644 Project.toml diff --git a/Manifest.toml b/Manifest.toml deleted file mode 100644 index 24f92bbb2e6..00000000000 --- a/Manifest.toml +++ /dev/null @@ -1,2087 +0,0 @@ -[[ASTInterpreter2]] -deps = ["DebuggerFramework"] -git-tree-sha1 = "8df3d36e0286777d226f4fd4956a432b73425186" -uuid = "e6d88f4b-b52a-544c-a8d3-7a4f12cb39c3" -version = "0.1.1" - -[[AbstractFFTs]] -deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "8d59c3b1463b5e0ad05a3698167f85fac90e184d" -uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" -version = "0.3.2" - -[[AbstractPlotting]] -deps = ["ColorBrewer", "ColorTypes", "Colors", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "Test", "UnicodeFun"] -git-tree-sha1 = "661703af6c5193a6ef2e7e5d6746abbcd40138c1" -repo-rev = "master" -repo-url = "https://github.com/JuliaPlots/AbstractPlotting.jl.git" -uuid = "537997a7-5e4e-5d89-9595-2241ea00577e" -version = "0.9.0+" - -[[AbstractTrees]] -deps = ["Markdown", "Test"] -git-tree-sha1 = "6621d9645702c1c4e6970cc6a3eae440c768000b" -uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" -version = "0.2.1" - -[[AccurateArithmetic]] -deps = ["Random", "Test"] -git-tree-sha1 = "47acddd710276cfa0184d84ebca07a92b324c263" -uuid = "22286c92-06ac-501d-9306-4abd417d9753" -version = "0.3.0" - -[[Adapt]] -deps = ["LinearAlgebra", "Test"] -git-tree-sha1 = "036ce44a518b912c43df728bfae274f8d8de9059" -uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "0.3.1" - -[[ApproxFun]] -deps = ["AbstractFFTs", "BandedMatrices", "BlockArrays", "BlockBandedMatrices", "Calculus", "DSP", "DomainSets", "DualNumbers", "FFTW", "FastGaussQuadrature", "FastTransforms", "FillArrays", "InfiniteArrays", "IntervalSets", "LazyArrays", "LinearAlgebra", "LowRankApprox", "Random", "RecipesBase", "SparseArrays", "SpecialFunctions", "StaticArrays", "Statistics", "Test", "ToeplitzMatrices"] -git-tree-sha1 = "88b3fbd0fcf6ad26a518d7809a796c7b19aea2e7" -uuid = "28f2ccd6-bb30-5033-b560-165f7b14dc2f" -version = "0.10.2" - -[[ArgParse]] -deps = ["Compat", "Test", "TextWrap"] -git-tree-sha1 = "37159c768f28ae52ef9af1e70669d25a68ba7d61" -uuid = "c7e460c6-2fb9-53a9-8c5b-16f535851c63" -version = "0.6.1" - -[[ArnoldiMethod]] -deps = ["DelimitedFiles", "LinearAlgebra", "Random", "SparseArrays", "StaticArrays", "Test"] -git-tree-sha1 = "2b6845cea546604fb4dca4e31414a6a59d39ddcd" -uuid = "ec485272-7323-5ecc-a04f-4719b315124d" -version = "0.0.4" - -[[Arpack]] -deps = ["BinaryProvider", "Libdl", "LinearAlgebra", "Random", "SparseArrays", "Test"] -git-tree-sha1 = "1ce1ce9984683f0b6a587d5bdbc688ecb480096f" -uuid = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97" -version = "0.3.0" - -[[AssetRegistry]] -deps = ["Distributed", "JSON", "Pidfile", "SHA", "Test"] -git-tree-sha1 = "b25e88db7944f98789130d7b503276bc34bc098e" -uuid = "bf4720bc-e11a-5d0c-854e-bdca1663c893" -version = "0.1.0" - -[[Atom]] -deps = ["ASTInterpreter2", "Base64", "CodeTools", "DocSeeker", "HTTP", "Hiccup", "JSON", "Juno", "LNR", "Lazy", "Logging", "MacroTools", "Markdown", "Media", "Profile", "REPL", "Reexport", "Requires", "Sockets", "Test", "Traceur", "TreeViews", "WebIO", "WebSockets"] -git-tree-sha1 = "07431ce3d1cb62c5ba7135e196702a0a60618a9d" -uuid = "c52e3926-4ff0-5f6e-af25-54175e0327b1" -version = "0.7.10" - -[[AxisAlgorithms]] -deps = ["Compat", "WoodburyMatrices"] -git-tree-sha1 = "99dabbe853e4f641ab21a676131f2cf9fb29937e" -uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" -version = "0.3.0" - -[[AxisArrays]] -deps = ["Compat", "Dates", "IntervalSets", "IterTools", "Random", "RangeArrays", "Test"] -git-tree-sha1 = "2e2536e9e6f27c4f8d09d8442b61a7ae0b910c28" -uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" -version = "0.3.0" - -[[BandedMatrices]] -deps = ["FillArrays", "LazyArrays", "LinearAlgebra", "Random", "SparseArrays", "Test"] -git-tree-sha1 = "d3c8a883d5470def5f5a2b3c5b20ea5080d325e8" -uuid = "aae01518-5342-5314-be14-df237901396f" -version = "0.7.2" - -[[Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" - -[[BenchmarkTools]] -deps = ["JSON", "Printf", "Statistics", "Test"] -git-tree-sha1 = "e686f1754227e4748259f400839b83a1e8773e02" -uuid = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" -version = "0.4.1" - -[[BinDeps]] -deps = ["Compat", "Libdl", "SHA", "URIParser"] -git-tree-sha1 = "12093ca6cdd0ee547c39b1870e0c9c3f154d9ca9" -uuid = "9e28174c-4ba2-5203-b857-d8d62c4213ee" -version = "0.8.10" - -[[BinaryBuilder]] -deps = ["Base64", "BinaryProvider", "GitHub", "HTTP", "InteractiveUtils", "JLD2", "JSON", "LibGit2", "Libdl", "MbedTLS", "ObjectFile", "Pkg", "PkgLicenses", "ProgressMeter", "REPL", "Random", "Reexport", "SHA", "Sockets"] -git-tree-sha1 = "a1c202b04c7d84e3e83dd582c2e0fd1d7e55fda0" -repo-rev = "master" -repo-url = "https://github.com/JuliaPackaging/BinaryBuilder.jl" -uuid = "12aac903-9f7c-5d81-afc2-d9565ea332ae" -version = "0.0.4" - -[[BinaryProvider]] -deps = ["Libdl", "Pkg", "SHA", "Test"] -git-tree-sha1 = "055eb2690182ebc31087859c3dd8598371d3ef9e" -uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" -version = "0.5.3" - -[[BlackBoxOptim]] -deps = ["CPUTime", "Compat", "Distributed", "Distributions", "LinearAlgebra", "Logging", "Pkg", "Printf", "Random", "SHA", "Serialization", "Statistics", "StatsBase", "Test"] -git-tree-sha1 = "1303f4b5d3c84f27a803f53646d68fa1616771b2" -uuid = "a134a8b2-14d6-55f6-9291-3336d3ab0209" -version = "0.4.0" - -[[Blink]] -deps = ["Base64", "BinDeps", "Distributed", "JSExpr", "JSON", "Lazy", "Libdl", "Logging", "MacroTools", "Mustache", "Mux", "Reexport", "Sockets", "Test", "WebIO", "WebSockets"] -git-tree-sha1 = "cd169880989669c2d48a72be9a2a691def62e257" -uuid = "ad839575-38b3-5650-b840-f874b8c74a25" -version = "0.9.0" - -[[BlockArrays]] -deps = ["Base64", "LinearAlgebra", "SparseArrays", "Test"] -git-tree-sha1 = "274280f8a1163553d2a5ff87770a490047147e55" -uuid = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" -version = "0.6.0" - -[[BlockBandedMatrices]] -deps = ["BandedMatrices", "BlockArrays", "Distributed", "FillArrays", "LazyArrays", "LinearAlgebra", "Pkg", "Profile", "Random", "SharedArrays", "SparseArrays", "Statistics", "Test"] -git-tree-sha1 = "91fb4c16507ddcbc2a8d9a78c7c4cdb8148cb7e2" -uuid = "ffab5731-97b5-5995-9138-79e8c1846df0" -version = "0.3.0" - -[[Blosc]] -deps = ["BinaryProvider", "CMakeWrapper", "Compat", "Libdl"] -git-tree-sha1 = "71fb23581e1f0b0ae7be8ccf0ebfb3600e23ca41" -uuid = "a74b3585-a348-5f62-a45c-50e91977d574" -version = "0.5.1" - -[[BoundaryValueDiffEq]] -deps = ["BandedMatrices", "DiffEqBase", "DiffEqDiffTools", "ForwardDiff", "LinearAlgebra", "NLsolve", "Reexport", "SparseArrays", "Test"] -git-tree-sha1 = "7231788899e26d91e8a15840e35f8e382ca0d2ec" -uuid = "764a87c0-6b3e-53db-9096-fe964310641d" -version = "2.2.1" - -[[Bridge]] -deps = ["Distributions", "LinearAlgebra", "Polynomials", "Random", "RecipesBase", "StaticArrays", "Statistics", "Test"] -git-tree-sha1 = "7dbf17d177dc2f38a75d3e304cfcdc01569bb722" -uuid = "2d3116d5-4b8f-5680-861c-71f149790274" -version = "0.9.0" - -[[BufferedStreams]] -deps = ["Compat", "Test"] -git-tree-sha1 = "5d55b9486590fdda5905c275bb21ce1f0754020f" -uuid = "e1450e63-4bb3-523b-b2a4-4ffa8c0fd77d" -version = "1.0.0" - -[[CMake]] -deps = ["BinDeps", "Libdl", "Test"] -git-tree-sha1 = "74853a75c26a4a73ac391ee26ee29ebeb5583d9f" -uuid = "631607c0-34d2-5d66-819e-eb0f9aa2061a" -version = "1.1.0" - -[[CMakeWrapper]] -deps = ["BinDeps", "CMake", "Libdl", "Parameters", "Test"] -git-tree-sha1 = "2b43d451639984e3571951cc687b8509b0a86c6d" -uuid = "d5fb7624-851a-54ee-a528-d3f3bac0b4a0" -version = "0.2.2" - -[[CPUTime]] -deps = ["Compat"] -git-tree-sha1 = "bdaf1b7ecf8eb6fb3843a1b0d3fccc5f727a49fd" -uuid = "a9c8d775-2e2e-55fc-8582-045d282d599e" -version = "0.1.0" - -[[CRC32c]] -uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc" - -[[CRlibm]] -deps = ["Libdl", "Test"] -git-tree-sha1 = "8ed645bb81cf6bb24e0dec6431ec5a0db1d6d005" -uuid = "96374032-68de-5a5b-8d9e-752f78720389" -version = "0.7.0" - -[[CSSUtil]] -deps = ["Colors", "Compat", "JSON", "Measures", "Pkg", "WebIO"] -git-tree-sha1 = "ff13fd99e4dd54f56eb064815f843bc992a871a2" -uuid = "70588ee8-6100-5070-97c1-3cb50ed05fe8" -version = "0.1.0" - -[[CSV]] -deps = ["CategoricalArrays", "DataFrames", "DataStreams", "Dates", "Mmap", "Parsers", "Random", "Tables", "Test", "Unicode", "WeakRefStrings"] -git-tree-sha1 = "4c2fe162202a53603b61ca18526c90711f469288" -repo-rev = "master" -repo-url = "https://github.com/JuliaData/CSV.jl.git" -uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" -version = "0.4.1" - -[[CUDAapi]] -deps = ["Libdl", "Logging", "Test"] -git-tree-sha1 = "da085c9c8668dbb37bd84573d4257b09cf33d053" -uuid = "3895d2a7-ec45-59b8-82bb-cfc6a382f9b3" -version = "0.5.3" - -[[CUDAdrv]] -deps = ["CUDAapi", "Libdl", "Printf", "Test"] -git-tree-sha1 = "94a3b9afb137e8d08136b334e51a25375557ca24" -uuid = "c5f51814-7f29-56b8-a69c-e4d8f6be1fde" -version = "0.8.6" - -[[CUDAnative]] -deps = ["CUDAapi", "CUDAdrv", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Pkg", "Printf", "Statistics", "Test"] -git-tree-sha1 = "debfe5af100e335b5df7109184e2e450f616dd1f" -uuid = "be33ccc6-a3ff-5ff2-a52e-74243cff1e17" -version = "0.9.1" - -[[Cairo]] -deps = ["BinDeps", "Colors", "Compat", "Graphics", "Homebrew", "Libdl", "WinRPM"] -git-tree-sha1 = "a427098d5aa2808504d94b8ed9fc5740ceaf71d0" -uuid = "159f3aea-2a34-519c-b102-8c37f9878175" -version = "0.5.6" - -[[CairoMakie]] -deps = ["AbstractPlotting", "Cairo", "Colors", "GeometryTypes", "Makie", "StaticArrays"] -git-tree-sha1 = "5d3e8ec512713ccda544c59cb5c41d1184c0f7b5" -repo-rev = "master" -repo-url = "https://github.com/JuliaPlots/CairoMakie.jl.git" -uuid = "f1797859-2bec-5491-832b-e19d79114491" -version = "0.0.0" - -[[Calculus]] -deps = ["Compat"] -git-tree-sha1 = "f60954495a7afcee4136f78d1d60350abd37a409" -uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" -version = "0.4.1" - -[[Cassette]] -deps = ["InteractiveUtils", "LinearAlgebra", "Test"] -git-tree-sha1 = "03931a31f1b5c613088e02f55dd0a7458a6430c8" -uuid = "7057c7e9-c182-5462-911a-8362d720325c" -version = "0.1.3" - -[[CatIndices]] -deps = ["CustomUnitRanges", "OffsetArrays", "Test"] -git-tree-sha1 = "254cf73ea369d2e39bfd6c5eb27a2296cfaed68c" -uuid = "aafaddc9-749c-510e-ac4f-586e18779b91" -version = "0.2.0" - -[[CategoricalArrays]] -deps = ["Compat", "Future", "Missings", "Printf", "Reexport", "Requires"] -git-tree-sha1 = "64651a0315fc342e7e35d03d67b2da920937c9be" -uuid = "324d7699-5711-5eae-9e2f-1d82baa6b597" -version = "0.5.0" - -[[ChaosTools]] -deps = ["Combinatorics", "DiffEqBase", "Distances", "DynamicalSystemsBase", "ForwardDiff", "LinearAlgebra", "NearestNeighbors", "OrdinaryDiffEq", "Random", "Reexport", "Roots", "StaticArrays", "Statistics", "StatsBase", "Test"] -git-tree-sha1 = "741f83c8b7de90f4f9ed81f5f68a2808eebec435" -uuid = "608a59af-f2a3-5ad4-90b4-758bdf3122a7" -version = "1.2.1" - -[[ChunkedArrays]] -deps = ["EllipsisNotation"] -git-tree-sha1 = "4f2ed36578a061c2c765b280b143358589cd7bd0" -uuid = "8bab3169-4815-5aad-9f88-5df82062e999" -version = "0.1.1" - -[[Clustering]] -deps = ["Dates", "Distances", "LinearAlgebra", "NearestNeighbors", "Printf", "Random", "SparseArrays", "Statistics", "StatsBase", "Test"] -git-tree-sha1 = "282e5d488cfca89b78b28b9ef28a59898951a62f" -uuid = "aaaa29a8-35af-508c-8bc3-b662a17a0fe5" -version = "0.12.1" - -[[CodeTools]] -deps = ["LNR", "Lazy", "Markdown", "Pkg", "Test", "Tokenize"] -git-tree-sha1 = "d8901c94fa0dff4525217e84eae91bd7efa1adc1" -uuid = "53a63b46-67e4-5edd-8c66-0af0544a99b9" -version = "0.6.2" - -[[CodecZlib]] -deps = ["BinaryProvider", "Libdl", "Test", "TranscodingStreams"] -git-tree-sha1 = "e3df104c84dfc108f0ca203fd7f5bbdc98641ae9" -uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.5.1" - -[[ColorBrewer]] -deps = ["Colors", "JSON", "Test"] -git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" -uuid = "a2cac450-b92f-5266-8821-25eda20663c8" -version = "0.4.0" - -[[ColorTypes]] -deps = ["FixedPointNumbers", "Random", "Test"] -git-tree-sha1 = "f73b0e10f2a5756de7019818a41654686da06b09" -uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" -version = "0.7.5" - -[[ColorVectorSpace]] -deps = ["ColorTypes", "Colors", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "StatsBase", "Test"] -git-tree-sha1 = "a890f08e61b40e9843d7177206da61229a3603c8" -uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" -version = "0.6.2" - -[[Colors]] -deps = ["ColorTypes", "FixedPointNumbers", "InteractiveUtils", "Printf", "Reexport", "Test"] -git-tree-sha1 = "9f0a0210450acb91c730b730a994f8eef1d3d543" -uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" -version = "0.9.5" - -[[Combinatorics]] -deps = ["LinearAlgebra", "Polynomials", "Test"] -git-tree-sha1 = "50b3ae4d643dc27eaff69fb6be06ee094d5500c9" -uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" -version = "0.7.0" - -[[CommonSubexpressions]] -deps = ["Test"] -git-tree-sha1 = "efdaf19ab11c7889334ca247ff4c9f7c322817b0" -uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" -version = "0.2.0" - -[[Compat]] -deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] -git-tree-sha1 = "ec61a16eed883ad0cfa002d7489b3ce6d039bb9a" -uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "1.4.0" - -[[ComplexPhasePortrait]] -deps = ["AbstractPlotting", "Colors", "Images", "IntervalSets", "Reactive", "Test"] -git-tree-sha1 = "c6765b8bd5a1f1efe46118ed8b5afac8aaf34de9" -repo-rev = "master" -repo-url = "git://github.com/JuliaHolomorphic/ComplexPhasePortrait.jl.git" -uuid = "e2f66d33-ad5d-5c8f-afd8-ee097a041359" -version = "0.0.0" - -[[ComputationalResources]] -deps = ["Test"] -git-tree-sha1 = "89e7e7ed20af73d9f78877d2b8d1194e7b6ff13d" -uuid = "ed09eef8-17a6-5b46-8889-db040fac31e3" -version = "0.3.0" - -[[Conda]] -deps = ["Compat", "JSON", "VersionParsing"] -git-tree-sha1 = "fb86fe40cb5b35990e368709bfdc1b46dbb99dac" -uuid = "8f4d0f93-b110-5947-807f-2305c1781a2d" -version = "1.1.1" - -[[Contour]] -deps = ["LinearAlgebra", "StaticArrays", "Test"] -git-tree-sha1 = "b974e164358fea753ef853ce7bad97afec15bb80" -uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" -version = "0.5.1" - -[[CoordinateTransformations]] -deps = ["Compat", "Rotations", "StaticArrays"] -git-tree-sha1 = "47f05d0b7f4999609f92e657147df000818c1f24" -uuid = "150eb455-5306-5404-9cee-2592286d6298" -version = "0.5.0" - -[[Crayons]] -deps = ["Test"] -git-tree-sha1 = "3017c662a988bcb8a3f43306a793617c6524d476" -uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" -version = "1.0.0" - -[[CuArrays]] -deps = ["AbstractFFTs", "Adapt", "CUDAapi", "CUDAdrv", "CUDAnative", "DiffRules", "ForwardDiff", "GPUArrays", "LinearAlgebra", "MacroTools", "NNlib", "Printf", "Random", "Test"] -git-tree-sha1 = "50814c8f6de015f08a4fe2c01c87fb74f42c8a39" -uuid = "3a865a2d-5b23-5a0f-bc46-62713ec82fae" -version = "0.8.1" - -[[CustomUnitRanges]] -deps = ["Test"] -git-tree-sha1 = "0a106457a1831555857e18ac9617279c22fc393b" -uuid = "dc8bdbbb-1ca9-579f-8c36-e416f6a65cce" -version = "0.2.0" - -[[DSP]] -deps = ["AbstractFFTs", "Compat", "FFTW", "LinearAlgebra", "Polynomials", "Random", "Reexport", "SpecialFunctions"] -git-tree-sha1 = "c90967ff4c5e99f652b278624634dcef73b58848" -uuid = "717857b8-e6f2-59f4-9121-6e50c889abd2" -version = "0.5.1" - -[[DataFrames]] -deps = ["CategoricalArrays", "CodecZlib", "Compat", "DataStreams", "Dates", "InteractiveUtils", "IteratorInterfaceExtensions", "LinearAlgebra", "Missings", "Printf", "Random", "Reexport", "SortingAlgorithms", "Statistics", "StatsBase", "TableTraits", "Tables", "Test", "TranscodingStreams", "Unicode", "WeakRefStrings"] -git-tree-sha1 = "03ac36fd3571cd03ea276bd40e8f43d85653659d" -repo-rev = "nl/hash2" -repo-url = "https://github.com/JuliaData/DataFrames.jl.git" -uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -version = "0.14.1+" - -[[DataStreams]] -deps = ["Dates", "Missings", "Test", "WeakRefStrings"] -git-tree-sha1 = "69c72a1beb4fc79490c361635664e13c8e4a9548" -uuid = "9a8bc11e-79be-5b39-94d7-1ccc349a1a85" -version = "0.4.1" - -[[DataStructures]] -deps = ["InteractiveUtils", "OrderedCollections", "Random", "Serialization", "Test"] -git-tree-sha1 = "8fc6e166e24fda04b2b648d4260cdad241788c54" -uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.14.0" - -[[DataValues]] -deps = ["Dates", "InteractiveUtils", "LinearAlgebra", "Random", "Test"] -git-tree-sha1 = "4fedccda7e5111354c7dcc832c7da83ff7258765" -uuid = "e7dc6d0d-1eca-5fa6-8ad6-5aecde8b7ea5" -version = "0.4.5" - -[[Dates]] -deps = ["Printf"] -uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" - -[[DebuggerFramework]] -git-tree-sha1 = "0288f278a5f58c28c67ad1cf55dce950069709b7" -uuid = "67417a49-6d77-5db2-98c7-c13144130cd2" -version = "0.1.2" - -[[DeepDiffs]] -deps = ["Compat"] -git-tree-sha1 = "cd4648e98d5625c75b9ebbec516533ec1250ce57" -uuid = "ab62b9b5-e342-54a8-a765-a90f495de1a6" -version = "1.1.0" - -[[DelayDiffEq]] -deps = ["DataStructures", "DiffEqBase", "DiffEqDiffTools", "ForwardDiff", "MuladdMacro", "NLSolversBase", "OrdinaryDiffEq", "RecursiveArrayTools", "Reexport", "Roots", "Test"] -git-tree-sha1 = "7a14b9794852211f7d28c243e3d07cdbfc73f1ae" -uuid = "bcd4f6db-9728-5f36-b5f7-82caef46ccdb" -version = "4.7.0" - -[[DelayEmbeddings]] -deps = ["Distances", "LinearAlgebra", "NearestNeighbors", "StaticArrays", "StatsBase", "Test"] -git-tree-sha1 = "6d42460dc2c84058850b26da7b5174fb6fcd213e" -uuid = "5732040d-69e3-5649-938a-b6b4f237613f" -version = "0.1.1" - -[[DelimitedFiles]] -deps = ["Mmap"] -uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" - -[[DiffBase]] -deps = ["StaticArrays"] -git-tree-sha1 = "38522d70e417cf9ace93848f17eb9fff20d486d2" -uuid = "c5cfe0b6-c10a-51a5-87e3-fd79235949f0" -version = "0.3.2" - -[[DiffEqBase]] -deps = ["Compat", "IteratorInterfaceExtensions", "LinearAlgebra", "RecipesBase", "RecursiveArrayTools", "Requires", "Roots", "SparseArrays", "StaticArrays", "Statistics", "SuiteSparse", "TableTraits", "Test", "TreeViews"] -git-tree-sha1 = "b8c9c5a296e426d0ad978e6e7ad699dde444d3a1" -uuid = "2b5f629d-d688-5b77-993f-72d75c75574e" -version = "4.31.1" - -[[DiffEqBiological]] -deps = ["Compat", "DataStructures", "DiffEqBase", "DiffEqJump", "MacroTools", "Random", "Reexport", "Statistics", "SymEngine", "Test"] -git-tree-sha1 = "1a107ec930651bfe528f69633c34e5548c335c22" -uuid = "eb300fae-53e8-50a0-950c-e21f52c2b7e0" -version = "3.4.1" - -[[DiffEqCallbacks]] -deps = ["DataStructures", "DiffEqBase", "LinearAlgebra", "OrdinaryDiffEq", "RecipesBase", "RecursiveArrayTools", "StaticArrays", "Test"] -git-tree-sha1 = "eb35747ead057723bd75c830bc012a22f5f5f3d1" -uuid = "459566f4-90b8-5000-8ac3-15dfb0a30def" -version = "2.3.0" - -[[DiffEqDevTools]] -deps = ["DiffEqBase", "DiffEqMonteCarlo", "DiffEqNoiseProcess", "DiffEqPDEBase", "Distributed", "LinearAlgebra", "NLsolve", "Random", "RecipesBase", "RecursiveArrayTools", "Statistics", "Test"] -git-tree-sha1 = "fd0570ec1ff052b9aef8e832015092417fb24dae" -uuid = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" -version = "2.6.1" - -[[DiffEqDiffTools]] -deps = ["LinearAlgebra", "Test"] -git-tree-sha1 = "67700c9fc82033ec68a145bc650f6b9debdf9103" -uuid = "01453d9d-ee7c-5054-8395-0335cb756afa" -version = "0.7.1" - -[[DiffEqFinancial]] -deps = ["DiffEqBase", "DiffEqNoiseProcess", "LinearAlgebra", "Markdown", "RandomNumbers", "Test"] -git-tree-sha1 = "f250512b982b771f6bdb3df05b89df314f2c2580" -uuid = "5a0ffddc-d203-54b0-88ba-2c03c0fc2e67" -version = "2.1.0" - -[[DiffEqJump]] -deps = ["Compat", "DataStructures", "DiffEqBase", "FunctionWrappers", "LinearAlgebra", "PoissonRandom", "Random", "RandomNumbers", "RecursiveArrayTools", "Statistics", "Test", "TreeViews"] -git-tree-sha1 = "7a11954a512000c2a598e6ff74e0adc57907553a" -uuid = "c894b116-72e5-5b58-be3c-e6d8d4ac2b12" -version = "5.6.0" - -[[DiffEqMonteCarlo]] -deps = ["DiffEqBase", "Distributed", "Random", "RecursiveArrayTools", "StaticArrays", "Statistics", "Test"] -git-tree-sha1 = "abaf6fa95b05c5c49fd1fb57a901caed10aacd0e" -uuid = "78ddff82-25fc-5f2b-89aa-309469cbf16f" -version = "0.14.0" - -[[DiffEqNoiseProcess]] -deps = ["DataStructures", "DiffEqBase", "LinearAlgebra", "Random", "RandomNumbers", "RecipesBase", "RecursiveArrayTools", "ResettableStacks", "StaticArrays", "Statistics", "Test"] -git-tree-sha1 = "2cdf1ae0f41bc89bc68c9ba19b7587f695b8ae86" -uuid = "77a26b50-5914-5dd7-bc55-306e6241c503" -version = "2.3.2" - -[[DiffEqOperators]] -deps = ["DiffEqBase", "LinearAlgebra", "Random", "SparseArrays", "StaticArrays", "Test"] -git-tree-sha1 = "332eea616ae687e7e4581602947ad5f053c7c650" -uuid = "9fdde737-9c7f-55bf-ade8-46b3f136cc48" -version = "3.4.0" - -[[DiffEqPDEBase]] -deps = ["ChunkedArrays", "Compat", "DiffEqBase", "RecipesBase", "VectorizedRoutines"] -git-tree-sha1 = "2a997aba53ecff1b19e6c78f1181352787bd9c54" -uuid = "34035eb4-37db-58ae-b003-a3202c898701" -version = "0.4.0" - -[[DiffEqParamEstim]] -deps = ["BlackBoxOptim", "Calculus", "DiffEqBase", "Distributions", "ForwardDiff", "LinearAlgebra", "LsqFit", "Optim", "PenaltyFunctions", "Random", "RecursiveArrayTools", "Test"] -git-tree-sha1 = "285a71332e266cc8046f9d0c860f4eac58132ba9" -uuid = "1130ab10-4a5a-5621-a13d-e4788d82bd4c" -version = "1.5.0" - -[[DiffEqPhysics]] -deps = ["Dates", "DiffEqBase", "DiffEqCallbacks", "ForwardDiff", "LinearAlgebra", "Printf", "Random", "RecipesBase", "RecursiveArrayTools", "Reexport", "StaticArrays", "Test"] -git-tree-sha1 = "d3dbc53318a6477f496ae2347db98c3ded36c486" -uuid = "055956cb-9e8b-5191-98cc-73ae4a59e68a" -version = "3.1.0" - -[[DiffEqSensitivity]] -deps = ["Compat", "DiffEqBase", "DiffEqCallbacks", "DiffEqDiffTools", "ForwardDiff", "LinearAlgebra", "QuadGK", "RecursiveArrayTools", "ReverseDiff", "Statistics", "Test"] -git-tree-sha1 = "76f33416ee523314b7fcdc08696408861489c427" -uuid = "41bf760c-e81c-5289-8e54-58b1f1f8abe2" -version = "2.3.0" - -[[DiffEqUncertainty]] -deps = ["DiffEqBase", "Test"] -git-tree-sha1 = "de2908324d93d201f870ffad020038b9a87350bf" -uuid = "ef61062a-5684-51dc-bb67-a0fcdec5c97d" -version = "1.1.0" - -[[DiffResults]] -deps = ["Compat", "StaticArrays"] -git-tree-sha1 = "db8acf46717b13d6c48deb7a12007c7f85a70cf7" -uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" -version = "0.0.3" - -[[DiffRules]] -deps = ["Random", "Test"] -git-tree-sha1 = "c49ec69428ffea0c1d1bbdc63d1a70f5df5860ad" -uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" -version = "0.0.7" - -[[DifferentialEquations]] -deps = ["BoundaryValueDiffEq", "DelayDiffEq", "DiffEqBase", "DiffEqBiological", "DiffEqCallbacks", "DiffEqDevTools", "DiffEqFinancial", "DiffEqJump", "DiffEqMonteCarlo", "DiffEqNoiseProcess", "DiffEqPDEBase", "DiffEqParamEstim", "DiffEqPhysics", "DiffEqSensitivity", "DiffEqUncertainty", "DimensionalPlotRecipes", "LinearAlgebra", "MultiScaleArrays", "OrdinaryDiffEq", "ParameterizedFunctions", "Random", "RecursiveArrayTools", "Reexport", "SteadyStateDiffEq", "StochasticDiffEq", "Sundials", "Test"] -git-tree-sha1 = "1f5d7977befe3265d9b7fc256d8f88d0bd9b6ffa" -uuid = "0c46a032-eb83-5123-abaf-570d42b7fbaa" -version = "5.3.1" - -[[DimensionalPlotRecipes]] -deps = ["LinearAlgebra", "RecipesBase", "Test"] -git-tree-sha1 = "d348688f9a3d02c24455327231c450c272b7401c" -uuid = "c619ae07-58cd-5f6d-b883-8f17bd6a98f9" -version = "0.2.0" - -[[Distances]] -deps = ["LinearAlgebra", "Printf", "Random", "Statistics", "Test"] -git-tree-sha1 = "2f38605722542f1c0a32dd2856fb529d8c226c69" -uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" -version = "0.7.3" - -[[Distributed]] -deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] -uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" - -[[Distributions]] -deps = ["Distributed", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsBase", "StatsFuns", "Test"] -git-tree-sha1 = "c24e9b6500c037673f0241a2783472b8c3d080c7" -uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.16.4" - -[[DocSeeker]] -deps = ["Hiccup", "IterTools", "Markdown", "REPL", "Requires", "Serialization", "StringDistances", "Test", "URIParser"] -git-tree-sha1 = "8d4d5f9ec970944445c77cfdcd5d3246a4e0cd0d" -uuid = "33d173f1-3be9-53c5-a697-8225b67db89c" -version = "0.2.0" - -[[DocStringExtensions]] -deps = ["LibGit2", "Markdown", "Pkg", "Test"] -git-tree-sha1 = "1df01539a1c952cef21f2d2d1c092c2bcf0177d7" -uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.6.0" - -[[Documenter]] -deps = ["Base64", "DocStringExtensions", "InteractiveUtils", "LibGit2", "Logging", "Markdown", "Pkg", "REPL", "Random", "Test", "Unicode"] -git-tree-sha1 = "9f2135e0e7ecb63f9c3ef73ea15a31d8cdb79bb7" -uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "0.20.0" - -[[DomainSets]] -deps = ["IntervalSets", "LinearAlgebra", "StaticArrays", "Statistics", "Test"] -git-tree-sha1 = "84beb94a9595c1a7a692880b424f82470a326976" -uuid = "5b8099bc-c8ec-5219-889f-1d9e522a28bf" -version = "0.0.1" - -[[DoubleFloats]] -deps = ["AccurateArithmetic", "LinearAlgebra", "Polynomials", "Random", "Test"] -git-tree-sha1 = "92eb688591448438ccd93685f4f80c6f220f5ccb" -uuid = "497a8b3b-efae-58df-a0af-a86822472b78" -version = "0.4.2" - -[[DualNumbers]] -deps = ["Calculus", "LinearAlgebra", "NaNMath", "SpecialFunctions", "Test"] -git-tree-sha1 = "b1e66ac804402a32184288ec9a78ab6d3a22ae69" -uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" -version = "0.6.1" - -[[DynamicalSystems]] -deps = ["ChaosTools", "DelayEmbeddings", "DynamicalSystemsBase", "Reexport", "StaticArrays"] -git-tree-sha1 = "7d388c4410e3d116a7147969645d018ab796c8d4" -repo-rev = "master" -repo-url = "https://github.com/JuliaDynamics/DynamicalSystems.jl.git" -uuid = "61744808-ddfa-5f27-97ff-6e42cc95d634" -version = "1.0.0+" - -[[DynamicalSystemsBase]] -deps = ["DelayEmbeddings", "DiffEqBase", "ForwardDiff", "LinearAlgebra", "OrdinaryDiffEq", "Reexport", "SparseArrays", "StaticArrays", "Test"] -git-tree-sha1 = "5c86d2492d20947ebbfe96824833ad71b7430d90" -repo-rev = "master" -repo-url = "https://github.com/JuliaDynamics/DynamicalSystemsBase.jl.git" -uuid = "6e36e845-645a-534a-86f2-f5d4aa5a06b4" -version = "1.1.0+" - -[[EllipsisNotation]] -git-tree-sha1 = "c09a512ff36dd5785ddc04fc102f2ff3b7fe05ae" -uuid = "da5c29d0-fa7d-589e-88eb-ea29b0a81949" -version = "0.3.0" - -[[ErrorfreeArithmetic]] -deps = ["Test"] -git-tree-sha1 = "071677938ef6e8f2a51ec0fedf5c312af88e26dc" -uuid = "90fa49ef-747e-5e6f-a989-263ba693cf1a" -version = "0.2.1" - -[[ExponentialUtilities]] -deps = ["LinearAlgebra", "Printf", "Random", "SparseArrays", "Test"] -git-tree-sha1 = "a25edb801ef3299b1c0fbbfe62692a074a82893b" -uuid = "d4d017d3-3776-5f7e-afef-a10c40355c18" -version = "1.3.0" - -[[EzXML]] -deps = ["BinaryProvider", "Libdl", "Printf", "Test"] -git-tree-sha1 = "5623d1486bfaadd815f5c4ca501adda02b5337f1" -uuid = "8f5d6c58-4d21-5cfd-889c-e3ad7ee6a615" -version = "0.9.0" - -[[FFTViews]] -deps = ["CustomUnitRanges", "FFTW", "Test"] -git-tree-sha1 = "9d7993227ca7c0fdb6b31deef193adbba11c8f4e" -uuid = "4f61f5a4-77b1-5117-aa51-3ab5ef4ef0cd" -version = "0.2.0" - -[[FFTW]] -deps = ["AbstractFFTs", "BinaryProvider", "Compat", "Conda", "Libdl", "LinearAlgebra", "Reexport", "Test"] -git-tree-sha1 = "29cda58afbf62f35b1a094882ad6c745a47b2eaa" -uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" -version = "0.2.4" - -[[FastGaussQuadrature]] -deps = ["Compat", "LinearAlgebra", "SpecialFunctions"] -git-tree-sha1 = "3861ecfe06076f9310a43469fbb676aaeba7893d" -uuid = "442a2c76-b920-505d-bb47-c5924d526838" -version = "0.3.2" - -[[FastRounding]] -deps = ["ErrorfreeArithmetic", "Test"] -git-tree-sha1 = "224175e213fd4fe112db3eea05d66b308dc2bf6b" -uuid = "fa42c844-2597-5d31-933b-ebd51ab2693f" -version = "0.2.0" - -[[FastTransforms]] -deps = ["AbstractFFTs", "Compat", "DSP", "FFTW", "HierarchicalMatrices", "LinearAlgebra", "LowRankApprox", "ProgressMeter", "SpecialFunctions", "ToeplitzMatrices"] -git-tree-sha1 = "051b635520e679c8c72aa43a40d86e2c226bbb7f" -uuid = "057dd010-8810-581a-b7be-e3fc3b93f78c" -version = "0.4.2" - -[[FileIO]] -deps = ["Pkg", "Random", "Test"] -git-tree-sha1 = "1a114d08094e7267ba8d4d684f930d5a722184de" -uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -version = "1.0.4" - -[[FilePaths]] -deps = ["Compat", "FilePathsBase", "Reexport", "URIParser"] -git-tree-sha1 = "9819e84a360a6254d86c47827ad16f6ada6e39f9" -uuid = "8fc22ac5-c921-52a6-82fd-178b2807b824" -version = "0.7.0" - -[[FilePathsBase]] -deps = ["Compat"] -git-tree-sha1 = "230d04188b262b0795144a5907b495fbc3ce8131" -uuid = "48062228-2e41-5def-b9a4-89aafe57970f" -version = "0.4.0" - -[[FileWatching]] -uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" - -[[FillArrays]] -deps = ["LinearAlgebra", "Random", "SparseArrays", "Test"] -git-tree-sha1 = "d87b7fc5c086cf157deabec625d53ba55eca6436" -uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" -version = "0.3.0" - -[[FixedPointNumbers]] -deps = ["Test"] -git-tree-sha1 = "b8045033701c3b10bf2324d7203404be7aef88ba" -uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.5.3" - -[[Flux]] -deps = ["AbstractTrees", "Adapt", "CodecZlib", "Colors", "DiffRules", "ForwardDiff", "Juno", "LinearAlgebra", "MacroTools", "NNlib", "NaNMath", "Printf", "Random", "Reexport", "Requires", "SpecialFunctions", "Statistics", "StatsBase", "Test", "ZipFile"] -git-tree-sha1 = "a9b7a93f9a6627abaf5a2eb576b8559279cb499a" -uuid = "587475ba-b771-5e3f-ad9e-33799f191a9c" -version = "0.6.9" - -[[ForwardDiff]] -deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "InteractiveUtils", "LinearAlgebra", "NaNMath", "Random", "SparseArrays", "SpecialFunctions", "StaticArrays", "Test"] -git-tree-sha1 = "b91250044374764e7c29af59a774c4b8d6100b6e" -uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "0.10.1" - -[[FreeType]] -deps = ["BinaryProvider", "Libdl", "Pkg", "Test"] -git-tree-sha1 = "06462b9d5aca708d764d16e5ba6a83ba7b753d57" -uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" -version = "2.1.1" - -[[FreeTypeAbstraction]] -deps = ["ColorVectorSpace", "Colors", "FreeType", "StaticArrays", "Test"] -git-tree-sha1 = "271ef13438bd0946950fd34d9241e5beefd6d4b3" -uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" -version = "0.4.1" - -[[FreqTables]] -deps = ["CategoricalArrays", "NamedArrays", "Tables", "Test"] -git-tree-sha1 = "93ce75cae27c2d1c6518771d597b6dd0a3d623d3" -uuid = "da1fdf0e-e0ff-5433-a45f-9bb5ff651cb1" -version = "0.3.1" - -[[FunctionWrappers]] -deps = ["Compat"] -git-tree-sha1 = "49bf793ebd37db5adaa7ac1eae96c2c97ec86db5" -uuid = "069b7b12-0de2-55c6-9aab-29f3d0a68a2e" -version = "1.0.0" - -[[FunctionalCollections]] -deps = ["Test"] -git-tree-sha1 = "9fdecc849480c511d7825570c20c9b64c4e5d5ed" -uuid = "de31a74c-ac4f-5751-b3fd-e18cd04993ca" -version = "0.4.0" - -[[Future]] -deps = ["Random"] -uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" - -[[GDAL]] -deps = ["BinaryProvider", "Libdl", "Test"] -git-tree-sha1 = "100429098b7ec9930f7db9ba68aee3495365be24" -uuid = "add2ef01-049f-52c4-9ee2-e494f65e021a" -version = "0.2.0" - -[[GLFW]] -deps = ["BinDeps", "CMakeWrapper", "Homebrew", "Libdl", "Test"] -git-tree-sha1 = "035e2b5e9c335afae1e92ecfe532cf0620da869f" -uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" -version = "2.3.0" - -[[GLMakie]] -deps = ["AbstractPlotting", "AxisArrays", "ColorBrewer", "ColorTypes", "ColorVectorSpace", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GLFW", "GeometryTypes", "ImageAxes", "ImageCore", "ImageMagick", "ImageTransformations", "IndirectArrays", "IntervalSets", "IterTools", "LinearAlgebra", "Makie", "Markdown", "ModernGL", "Observables", "Pkg", "PlotUtils", "Primes", "Printf", "QuartzImageIO", "Serialization", "Showoff", "StaticArrays", "UnicodeFun"] -git-tree-sha1 = "2e3cb969fd8f8cab98a4863d4a97d24bb1efdbd0" -uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" -version = "0.0.1" - -[[GPUArrays]] -deps = ["FFTW", "FillArrays", "LinearAlgebra", "Pkg", "Printf", "Random", "Serialization", "StaticArrays", "Test"] -git-tree-sha1 = "ff1d9b711533c00bb3eb800546e764e2035e6ed8" -uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" -version = "0.5.0" - -[[GR]] -deps = ["Base64", "DelimitedFiles", "Pkg", "Random", "Serialization", "Sockets", "Test"] -git-tree-sha1 = "31a672ea6609a53567ca96b1c52d984eaa10790a" -repo-rev = "master" -repo-url = "https://github.com/jheinen/GR.jl.git" -uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" -version = "0.36.0+" - -[[GenericSVD]] -deps = ["LinearAlgebra", "Random", "Test"] -git-tree-sha1 = "c6f411fee94d3e2f1121d635f5a7ab7eec200eea" -uuid = "01680d73-4ee2-5a08-a1aa-533608c188bb" -version = "0.2.0" - -[[GeometricalPredicates]] -deps = ["Test"] -git-tree-sha1 = "ccf306c88eedb19c95432947d8b7f4d0e916e1a2" -uuid = "fd0ad045-b25c-564e-8f9c-8ef5c5f21267" -version = "0.2.0" - -[[GeometryTypes]] -deps = ["ColorTypes", "FixedPointNumbers", "IterTools", "LinearAlgebra", "StaticArrays", "Test"] -git-tree-sha1 = "706fc16aa2a648a2f292732f8e6ee25167484328" -uuid = "4d00f742-c7ba-57c2-abde-4428a4b178cb" -version = "0.7.1" - -[[GitHub]] -deps = ["Base64", "Compat", "Dates", "HTTP", "JSON", "MbedTLS", "Test"] -git-tree-sha1 = "b988ce46c9b682acfeed4801cbaafa1ef954ad31" -uuid = "bc5e4493-9b4d-5f90-b8aa-2b2bcaad7a26" -version = "5.0.2" - -[[Graphics]] -deps = ["Colors", "Compat", "NaNMath"] -git-tree-sha1 = "e3ead4211073d4117a0d2ef7d1efc5c8092c8412" -uuid = "a2bd30eb-e257-5431-a919-1863eab51364" -version = "0.4.0" - -[[HDF5]] -deps = ["BinDeps", "Blosc", "CRC32c", "Distributed", "Homebrew", "Libdl", "LinearAlgebra", "Mmap", "Pkg", "Test", "WinRPM"] -git-tree-sha1 = "2b55a7e957923fa15688c97e91198a3ff24155d2" -uuid = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" -version = "0.10.3" - -[[HTTP]] -deps = ["Base64", "Dates", "Distributed", "IniFile", "MbedTLS", "Sockets", "Test"] -git-tree-sha1 = "b881f69331e85642be315c63d05ed65d6fc8a05b" -uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "0.7.1" - -[[HTTPClient]] -deps = ["Compat", "LibCURL"] -git-tree-sha1 = "161d5776ae8e585ac0b8c20fb81f17ab755b3671" -uuid = "0862f596-cf2d-50af-8ef4-f2be67dfa83f" -version = "0.2.1" - -[[Hiccup]] -deps = ["MacroTools", "Test"] -git-tree-sha1 = "6187bb2d5fcbb2007c39e7ac53308b0d371124bd" -uuid = "9fb69e20-1954-56bb-a84f-559cc56a8ff7" -version = "0.2.2" - -[[HierarchicalMatrices]] -deps = ["Compat"] -git-tree-sha1 = "acfcaf1aa47d038f593f301ed3bdebc0129035bc" -uuid = "7c893195-952b-5c83-bb6e-be12f22eed51" -version = "0.1.4" - -[[Homebrew]] -deps = ["BinDeps", "InteractiveUtils", "JSON", "Libdl", "Test", "Unicode"] -git-tree-sha1 = "5582ec74f735cf8d12e562a2e65c47f34063bd51" -uuid = "d9be37ee-ecc9-5288-90f1-b9ca67657a75" -version = "0.7.0" - -[[IJulia]] -deps = ["Base64", "Compat", "Conda", "Dates", "InteractiveUtils", "JSON", "Markdown", "MbedTLS", "Pkg", "Printf", "REPL", "Random", "SoftGlobalScope", "Test", "UUIDs", "ZMQ"] -git-tree-sha1 = "38d1ce0fbbefcb67f5ab46f1093cbce0335092e0" -uuid = "7073ff75-c697-5162-941a-fcdaad2a7d2a" -version = "1.14.1" - -[[IdentityRanges]] -deps = ["OffsetArrays", "Test"] -git-tree-sha1 = "f5ca23a08397288924a7535cd898d8ccbcde5ba5" -uuid = "bbac6d45-d8f3-5730-bfe4-7a449cd117ca" -version = "0.2.0" - -[[ImageAxes]] -deps = ["AxisArrays", "Colors", "FixedPointNumbers", "ImageCore", "MappedArrays", "Reexport", "SimpleTraits", "Test"] -git-tree-sha1 = "5735ec90843acaa67a4624611921c686cdf4efbf" -uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" -version = "0.5.0" - -[[ImageCore]] -deps = ["ColorTypes", "Colors", "FFTW", "FixedPointNumbers", "Graphics", "MappedArrays", "OffsetArrays", "PaddedViews", "Random", "Statistics", "Test"] -git-tree-sha1 = "5e7b1f49c80541860e08a7ea91805a24c1641f19" -uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" -version = "0.7.3" - -[[ImageDistances]] -deps = ["Colors", "Distances", "LinearAlgebra", "ProgressMeter", "Test"] -git-tree-sha1 = "a5de7b61f6fa98fb93c39857fa43cf40ca383b28" -uuid = "51556ac3-7006-55f5-8cb3-34580c88182d" -version = "0.1.1" - -[[ImageFiltering]] -deps = ["CatIndices", "ColorVectorSpace", "Colors", "ComputationalResources", "DataStructures", "FFTViews", "FFTW", "FixedPointNumbers", "ImageCore", "LinearAlgebra", "Logging", "MappedArrays", "OffsetArrays", "Random", "StaticArrays", "Statistics", "Test", "TiledIteration"] -git-tree-sha1 = "2d23d8f8c1def1e8d67d05e554baacc780d9313d" -uuid = "6a3955dd-da59-5b1f-98d4-e7296123deb5" -version = "0.5.1" - -[[ImageMagick]] -deps = ["BinaryProvider", "ColorTypes", "FileIO", "FixedPointNumbers", "ImageCore", "InteractiveUtils", "Libdl", "Pkg", "Random", "Test"] -git-tree-sha1 = "0e4cc77fb131061b3525a97fd7d483b253c3aaad" -uuid = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" -version = "0.7.1" - -[[ImageMetadata]] -deps = ["AxisArrays", "ColorVectorSpace", "Colors", "Dates", "FixedPointNumbers", "ImageAxes", "ImageCore", "IndirectArrays", "Statistics", "Test"] -git-tree-sha1 = "3eac47d5b62dfeb4d06ec5be85592ebd437112ea" -uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49" -version = "0.5.1" - -[[ImageMorphology]] -deps = ["ImageCore", "Test"] -git-tree-sha1 = "e94f43b9ff76f3a3810bfdd9b3d2fbcacbc26fd0" -uuid = "787d08f9-d448-5407-9aad-5290dd7ab264" -version = "0.1.1" - -[[ImageShow]] -deps = ["Base64", "ColorTypes", "Colors", "FileIO", "FixedPointNumbers", "ImageCore", "OffsetArrays", "Requires", "Test"] -git-tree-sha1 = "98eb96a852fd2d6f0905cbe4d215ec2113805b46" -uuid = "4e3cecfd-b093-5904-9786-8bbb286a6a31" -version = "0.1.2" - -[[ImageTransformations]] -deps = ["AxisAlgorithms", "ColorTypes", "ColorVectorSpace", "Colors", "CoordinateTransformations", "FixedPointNumbers", "IdentityRanges", "ImageCore", "Interpolations", "LinearAlgebra", "OffsetArrays", "StaticArrays", "Test"] -git-tree-sha1 = "18ae1c0a8df31549a9452ceac93751d4aa166071" -uuid = "02fcd773-0e25-5acc-982a-7f6622650795" -version = "0.7.1" - -[[Images]] -deps = ["AxisArrays", "Base64", "ColorTypes", "ColorVectorSpace", "Colors", "FileIO", "FixedPointNumbers", "Graphics", "ImageAxes", "ImageCore", "ImageDistances", "ImageFiltering", "ImageMetadata", "ImageMorphology", "ImageShow", "ImageTransformations", "IndirectArrays", "LinearAlgebra", "MappedArrays", "OffsetArrays", "Random", "Reexport", "SIUnits", "SparseArrays", "StaticArrays", "Statistics", "StatsBase", "Test", "TiledIteration"] -git-tree-sha1 = "6ccb98fb6d93ade0ddd3954877955f17c2041a66" -uuid = "916415d5-f1e6-5110-898d-aaa5f9f070e0" -version = "0.16.1" - -[[IndexedTables]] -deps = ["DataValues", "Dates", "IteratorInterfaceExtensions", "LinearAlgebra", "OnlineStats", "PooledArrays", "Random", "Serialization", "SparseArrays", "Statistics", "TableTraits", "TableTraitsUtils", "Test", "WeakRefStrings"] -git-tree-sha1 = "cb4406eeed8729f8179940d39e6dec5598971341" -uuid = "6deec6e2-d858-57c5-ab9b-e6ca5bd20e43" -version = "0.8.1" - -[[IndirectArrays]] -deps = ["Compat", "Test"] -git-tree-sha1 = "b6e249be10a3381b2c72ac82f2d13d70067cb2bd" -uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" -version = "0.5.0" - -[[InfiniteArrays]] -deps = ["DSP", "FillArrays", "LazyArrays", "LinearAlgebra", "SparseArrays", "Statistics", "Test"] -git-tree-sha1 = "e65228707f83519678abeb780ff0d53cebcc2584" -uuid = "4858937d-0d70-526a-a4dd-2d5cb5dd786c" -version = "0.0.2" - -[[IniFile]] -deps = ["Test"] -git-tree-sha1 = "098e4d2c533924c921f9f9847274f2ad89e018b8" -uuid = "83e8ac13-25f8-5344-8a64-a9f2b223428f" -version = "0.5.0" - -[[Interact]] -deps = ["CSSUtil", "DataStructures", "InteractBase", "InteractBulma", "JSON", "Knockout", "Observables", "Reexport", "Test", "WebIO", "Widgets"] -git-tree-sha1 = "102666d2d89a672c86bd33399a5f36c7e5d2b3b5" -uuid = "c601a237-2ae4-5e1e-952c-7a85b0c7eef1" -version = "0.9.0" - -[[InteractBase]] -deps = ["Base64", "CSSUtil", "Colors", "DataStructures", "Dates", "JSExpr", "JSON", "Knockout", "Observables", "Random", "Test", "WebIO", "Widgets"] -git-tree-sha1 = "494156a2e3fb192210bd8404da8de1d423d48bb1" -uuid = "d3863d7c-f0c8-5437-a7b4-3ae773c01009" -version = "0.8.1" - -[[InteractBulma]] -deps = ["InteractBase", "Reexport", "Test"] -git-tree-sha1 = "5dd3798331686a512ee98cc59a5b1f3d136cd926" -uuid = "7981ab7d-5bfa-5e03-9ec9-f3d4afc0a1ca" -version = "0.4.2" - -[[InteractiveUtils]] -deps = ["LinearAlgebra", "Markdown"] -uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" - -[[Interpolations]] -deps = ["AxisAlgorithms", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "SharedArrays", "SparseArrays", "StaticArrays", "Test", "WoodburyMatrices"] -git-tree-sha1 = "3493536a64dae5a21c0cc8aecf680647f3e12313" -uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" -version = "0.11.0" - -[[IntervalArithmetic]] -deps = ["CRlibm", "FastRounding", "LinearAlgebra", "Markdown", "RecipesBase", "SetRounding", "StaticArrays", "Test"] -git-tree-sha1 = "9ce05b28f218d833aedbed0a53ca35948275f336" -uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" -version = "0.15.0" - -[[IntervalSets]] -deps = ["Compat"] -git-tree-sha1 = "9dc556002f23740de13946e8c2e41798e09a9249" -repo-rev = "master" -repo-url = "https://github.com/JuliaMath/IntervalSets.jl.git" -uuid = "8197267c-284f-5f27-9208-e0e47529a953" -version = "0.3.1+" - -[[IterTools]] -deps = ["SparseArrays", "Test"] -git-tree-sha1 = "79246285c43602384e6f1943b3554042a3712056" -uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" -version = "1.1.1" - -[[IterableTables]] -deps = ["DataValues", "IteratorInterfaceExtensions", "Requires", "TableTraits", "TableTraitsUtils", "Test"] -git-tree-sha1 = "0eec91e8185899f3926f56db515559bfe95b9db7" -uuid = "1c8ee90f-4401-5389-894e-7a04a3dc0f4d" -version = "0.10.0" - -[[IteratorInterfaceExtensions]] -deps = ["Test"] -git-tree-sha1 = "5484e5ede2a4137b9643f4d646e8e7b87b794415" -uuid = "82899510-4779-5014-852e-03e436cf321d" -version = "0.1.1" - -[[JLD2]] -deps = ["CodecZlib", "DataStructures", "FileIO", "LinearAlgebra", "Mmap", "Printf", "Random", "Test"] -git-tree-sha1 = "3ba90ff93e1d5b9b2103588051c2d349fae54dac" -uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.1.2" - -[[JSExpr]] -deps = ["JSON", "MacroTools", "Observables", "Test", "WebIO"] -git-tree-sha1 = "96429a372b5c4ad63fa9cbff6ba4178a85939705" -uuid = "97c1335a-c9c5-57fe-bc5d-ec35cebe8660" -version = "0.4.0" - -[[JSON]] -deps = ["Dates", "Distributed", "Mmap", "Sockets", "Test", "Unicode"] -git-tree-sha1 = "1f7a25b53ec67f5e9422f1f551ee216503f4a0fa" -uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" -version = "0.20.0" - -[[Juno]] -deps = ["Base64", "Logging", "Media", "Profile", "Test"] -git-tree-sha1 = "3c29a199713e7ec62cfdc11f44d7760219d5f658" -uuid = "e5e0dc1b-0480-54bc-9374-aad01c23163d" -version = "0.5.3" - -[[KernelDensity]] -deps = ["Distributions", "FFTW", "Interpolations", "Optim", "StatsBase", "Test"] -git-tree-sha1 = "c1048817fe5711f699abc8fabd47b1ac6ba4db04" -uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" -version = "0.5.1" - -[[Knockout]] -deps = ["JSExpr", "JSON", "Observables", "Pkg", "Test", "WebIO"] -git-tree-sha1 = "63e5e0bd2e9923191c30bb1e3d6e4d579155ddfa" -uuid = "bcebb21b-c2e3-54f8-a781-646b90f6d2cc" -version = "0.2.0" - -[[LLVM]] -deps = ["InteractiveUtils", "Libdl", "Printf", "Test", "Unicode"] -git-tree-sha1 = "d98bd8e6e56591caceb7db300a6877fb6daca6ba" -uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "1.0.0" - -[[LNR]] -deps = ["Compat", "Lazy", "Test"] -git-tree-sha1 = "bae0010daaba5f122cefcbee9a97f5d82ea03e5c" -uuid = "7c4cb9fa-83a0-5386-9231-d6167c818060" -version = "0.2.0" - -[[LaTeXStrings]] -deps = ["Compat"] -git-tree-sha1 = "7ab9b8788cfab2bdde22adf9004bda7ad9954b6c" -uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" -version = "1.0.3" - -[[Lazy]] -deps = ["Compat", "MacroTools", "Test"] -git-tree-sha1 = "aec38c7e7f255a678af22651c74100e3cd39ea20" -uuid = "50d2b5c4-7a5e-59d5-8109-a42b560f39c0" -version = "0.13.2" - -[[LazyArrays]] -deps = ["FillArrays", "LinearAlgebra", "StaticArrays", "Test"] -git-tree-sha1 = "80ae09d512afe478575cadf7e301742996d0330d" -uuid = "5078a376-72f3-5289-bfd5-ec5146d43c02" -version = "0.4.0" - -[[LearnBase]] -deps = ["LinearAlgebra", "SparseArrays", "StatsBase", "Test"] -git-tree-sha1 = "c4b5da6d68517f46f70ed5157b28336b56cd2ff3" -uuid = "7f8f8fb0-2700-5f03-b4bd-41f8cfc144b6" -version = "0.2.2" - -[[LibCURL]] -deps = ["BinaryProvider", "Compat", "Libdl", "Printf"] -git-tree-sha1 = "6339c87cb76923a3cf947fcd213cbc364355c9c9" -uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" -version = "0.4.1" - -[[LibExpat]] -deps = ["Compat"] -git-tree-sha1 = "fde352ec13479e2f90e57939da2440fb78c5e388" -uuid = "522f3ed2-3f36-55e3-b6df-e94fee9b0c07" -version = "0.5.0" - -[[LibGit2]] -uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" - -[[Libdl]] -uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" - -[[Libz]] -deps = ["BufferedStreams", "Random", "Test"] -git-tree-sha1 = "d405194ffc0293c3519d4f7251ce51baac9cc871" -uuid = "2ec943e9-cfe8-584d-b93d-64dcb6d567b7" -version = "1.0.0" - -[[LineSearches]] -deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf", "Test"] -git-tree-sha1 = "54eb90e8dbe745d617c78dee1d6ae95c7f6f5779" -uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" -version = "7.0.1" - -[[LinearAlgebra]] -deps = ["Libdl"] -uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - -[[LinearMaps]] -deps = ["LinearAlgebra", "SparseArrays", "Test"] -git-tree-sha1 = "580bb0efbfe0082c4fb0ce8dbf6548872c3b604c" -uuid = "7a12625a-238d-50fd-b39a-03d52299707e" -version = "2.2.2" - -[[Loess]] -deps = ["Distances", "Random", "Statistics", "Test"] -git-tree-sha1 = "0ee46caf683a422b595be4dfaed6cda28f541e25" -uuid = "4345ca2d-374a-55d4-8d30-97f9976e7612" -version = "0.5.0" - -[[Logging]] -uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" - -[[LossFunctions]] -deps = ["InteractiveUtils", "LearnBase", "Markdown", "Random", "RecipesBase", "SparseArrays", "Statistics", "StatsBase", "Test"] -git-tree-sha1 = "b97d2e9a527733649d0205d3374d0daee352c50e" -uuid = "30fc2ffe-d236-52d8-8643-a9d8f7c094a7" -version = "0.5.0" - -[[LowRankApprox]] -deps = ["FFTW", "FillArrays", "LinearAlgebra", "Nullables", "Random", "SparseArrays", "Test"] -git-tree-sha1 = "fed5d60ed818367d4945a95be679461280501f2d" -uuid = "898213cb-b102-5a47-900c-97e73b919f73" -version = "0.2.1" - -[[LsqFit]] -deps = ["Calculus", "Distributions", "LinearAlgebra", "OptimBase", "Random", "Test"] -git-tree-sha1 = "5c1b5ab85e120c6d1734e7f5670aac22fe69270c" -uuid = "2fda8390-95c7-5789-9bda-21331edee243" -version = "0.6.0" - -[[MacroTools]] -deps = ["Compat"] -git-tree-sha1 = "c443e1c8d58a4e9f61b708ad0a88286c7042145b" -uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.4.4" - -[[Makie]] -deps = ["AbstractPlotting", "AxisArrays", "Base64", "ColorBrewer", "ColorTypes", "ColorVectorSpace", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GLFW", "GLMakie", "GeometryTypes", "ImageAxes", "ImageCore", "ImageMagick", "ImageTransformations", "IndirectArrays", "IntervalSets", "IterTools", "LinearAlgebra", "ModernGL", "Observables", "Pkg", "PlotUtils", "Primes", "QuartzImageIO", "Showoff", "StaticArrays", "Statistics", "UnicodeFun"] -git-tree-sha1 = "a49ae5834b605a14447e04d57a07cbb80ebe8add" -repo-rev = "master" -repo-url = "https://github.com/JuliaPlots/Makie.jl.git" -uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -version = "0.9.0+" - -[[MakieGallery]] -deps = ["AbstractPlotting", "BinaryProvider", "ColorTypes", "ColorVectorSpace", "Colors", "DataFrames", "Documenter", "FileIO", "FixedPointNumbers", "GDAL", "GeometryTypes", "ImageCore", "ImageFiltering", "ImageMagick", "ImageTransformations", "LinearAlgebra", "Makie", "Markdown", "MeshIO", "ModernGL", "Pkg", "QuartzImageIO", "RDatasets", "Random", "Statistics", "Test"] -git-tree-sha1 = "178252e975f92c3e11a4478577ec4a4faff4119d" -repo-rev = "master" -repo-url = "https://github.com/JuliaPlots/MakieGallery.jl" -uuid = "62e31da0-2f4f-5d53-819c-a7cea9df6aaa" -version = "0.0.0" - -[[MakieThemes]] -deps = ["AbstractPlotting", "Colors"] -git-tree-sha1 = "6a53e0ae8200b572cdd87bf2b10a616051785837" -repo-rev = "master" -repo-url = "https://github.com/mkborregaard/MakieThemes.jl.git" -uuid = "4307a514-e789-11e8-2e8d-7135958f4cf8" -version = "0.1.0" - -[[MappedArrays]] -deps = ["Test"] -git-tree-sha1 = "923441c5ac942b60bd3a842d5377d96646bcbf46" -uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" -version = "0.2.1" - -[[Markdown]] -deps = ["Base64"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" - -[[MathProgBase]] -deps = ["Compat"] -git-tree-sha1 = "3bf2e534e635df810e5f4b4f1a8b6de9004a0d53" -uuid = "fdba3010-5040-5b88-9595-932c9decdf73" -version = "0.7.7" - -[[MbedTLS]] -deps = ["BinaryProvider", "Dates", "Libdl", "Random", "Sockets", "Test"] -git-tree-sha1 = "c93a87da4081a3de781f34e0540175795a2ce83d" -uuid = "739be429-bea8-5141-9913-cc70e7f3736d" -version = "0.6.6" - -[[Measures]] -deps = ["Test"] -git-tree-sha1 = "ddfd6d13e330beacdde2c80de27c1c671945e7d9" -uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e" -version = "0.3.0" - -[[Media]] -deps = ["MacroTools", "Test"] -git-tree-sha1 = "75a54abd10709c01f1b86b84ec225d26e840ed58" -uuid = "e89f7d12-3494-54d1-8411-f7d8b9ae1f27" -version = "0.5.0" - -[[MeshIO]] -deps = ["ColorTypes", "FileIO", "GeometryTypes", "Printf", "Test"] -git-tree-sha1 = "3e01e12c4c626578a9d47fac0d15c9fe8dad5139" -uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" -version = "0.3.1" - -[[Missings]] -deps = ["Dates", "InteractiveUtils", "SparseArrays", "Test"] -git-tree-sha1 = "adc26d2ee85a49c413464110d922cf21efc9d233" -uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" -version = "0.3.1" - -[[Mmap]] -uuid = "a63ad114-7e13-5084-954f-fe012c677804" - -[[Mocking]] -deps = ["Compat", "Dates"] -git-tree-sha1 = "4bf69aaf823b119b034e091e16b18311aa191663" -uuid = "78c3b35d-d492-501b-9361-3d52fe80e533" -version = "0.5.7" - -[[ModernGL]] -deps = ["Libdl"] -git-tree-sha1 = "f4f8fa8d04d3c1e7294f07fc37586c819466ad38" -uuid = "66fc600b-dfda-50eb-8b99-91cfa97b1301" -version = "1.0.0" - -[[MuladdMacro]] -deps = ["MacroTools", "Test"] -git-tree-sha1 = "41e6e7c4b448afeaddaac7f496b414854f83b848" -uuid = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" -version = "0.2.1" - -[[MultiScaleArrays]] -deps = ["DiffEqBase", "RecursiveArrayTools", "Statistics", "Test"] -git-tree-sha1 = "e85772d38263397a8808e98812d3ce49db4f217d" -uuid = "f9640e96-87f6-5992-9c3b-0743c6a49ffa" -version = "1.3.1" - -[[Mustache]] -deps = ["Tables", "Test"] -git-tree-sha1 = "be8d12b4a84ed7b592a6540b71c664440a4dd7f1" -uuid = "ffc61752-8dc7-55ee-8c37-f3e9cdd09e70" -version = "0.5.8" - -[[Mux]] -deps = ["AssetRegistry", "Base64", "HTTP", "Hiccup", "Lazy", "Pkg", "Sockets", "Test", "WebSockets"] -git-tree-sha1 = "487feb060cdd5cc152ef4f75b3cb565c0dc4300a" -uuid = "a975b10e-0019-58db-a62f-e48ff68538c9" -version = "0.5.3" - -[[NLSolversBase]] -deps = ["Calculus", "DiffEqDiffTools", "DiffResults", "Distributed", "ForwardDiff", "LinearAlgebra", "Random", "SparseArrays", "Test"] -git-tree-sha1 = "ebfb2e96970151753575b9c4d31d47e5ae8382a5" -uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" -version = "7.1.1" - -[[NLopt]] -deps = ["BinaryProvider", "CMakeWrapper", "Libdl", "MathProgBase", "Test"] -git-tree-sha1 = "b46237debcacd4fed7bbeb31200667a75b90384f" -uuid = "76087f3c-5699-56af-9a33-bf431cd00edd" -version = "0.5.1" - -[[NLsolve]] -deps = ["DiffBase", "DiffEqDiffTools", "Distances", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "Printf", "Reexport", "SparseArrays", "Test"] -git-tree-sha1 = "0e046f4f72801c9782d64db972ce66a85d3473f1" -uuid = "2774e3e8-f4cf-5e23-947b-6d7e65073b56" -version = "3.0.1" - -[[NNlib]] -deps = ["Libdl", "LinearAlgebra", "MacroTools", "Requires", "Test"] -git-tree-sha1 = "51330bb45927379007e089997bf548fbe232589d" -uuid = "872c559c-99b0-510c-b3b7-b6c96a88d5cd" -version = "0.4.3" - -[[NRRD]] -deps = ["AxisArrays", "ColorVectorSpace", "Colors", "FileIO", "FixedPointNumbers", "ImageAxes", "ImageCore", "Libz", "MappedArrays", "Mmap", "Printf", "Quaternions", "StaticArrays", "Statistics", "Test", "Unitful"] -git-tree-sha1 = "e46066f96c520203743114c0f6fd436887aa86bf" -repo-rev = "master" -repo-url = "https://github.com/JuliaIO/NRRD.jl.git" -uuid = "9bb6cfbd-7763-5393-b1b5-1c8e09872146" -version = "0.4.0+" - -[[NaNMath]] -deps = ["Compat"] -git-tree-sha1 = "ce3b85e484a5d4c71dd5316215069311135fa9f2" -uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" -version = "0.3.2" - -[[NamedArrays]] -deps = ["Combinatorics", "DataStructures", "DelimitedFiles", "LinearAlgebra", "Random", "Requires", "SparseArrays", "Statistics", "Test"] -git-tree-sha1 = "3099281fe5bcccb0cc329655a2b07e0d85e978ca" -uuid = "86f7a689-2022-50b4-a561-43c23ac3c673" -version = "0.9.1" - -[[NearestNeighbors]] -deps = ["Distances", "LinearAlgebra", "Mmap", "StaticArrays", "Test"] -git-tree-sha1 = "aab46b96ae5c2a9c08146188016d6312276094e5" -uuid = "b8a86587-4115-5ab1-83bc-aa920d37bbce" -version = "0.4.2" - -[[NuclearSurfaceVibrations]] -deps = ["AbstractPlotting", "Arpack", "CSV", "ChaosTools", "Colors", "DataFrames", "DataStructures", "DiffEqBase", "DiffEqCallbacks", "DiffEqMonteCarlo", "DifferentialEquations", "Distributed", "DynamicalSystems", "FileIO", "GeometricalPredicates", "ImageMagick", "Images", "IntervalArithmetic", "JLD2", "LaTeXStrings", "LinearAlgebra", "Logging", "Makie", "NLopt", "NLsolve", "Observables", "OrdinaryDiffEq", "ParallelDataTransfer", "Parameters", "Pkg", "PlotlyJS", "Plots", "ProgressMeter", "Query", "Random", "RecipesBase", "RecursiveArrayTools", "Reexport", "Roots", "SparseArrays", "StatPlots", "StaticArrays", "Statistics", "StatsBase", "StatsMakie", "TimerOutputs"] -git-tree-sha1 = "0b3b0e759ceff9399b04838e446f42517d2a0130" -repo-rev = "makie" -repo-url = "https://github.com/SebastianM-C/Nuclear-surface-vibrations" -uuid = "61377714-a6e6-11e8-0d55-23ea14e6950b" -version = "0.1.0" - -[[Nullables]] -deps = ["Compat"] -git-tree-sha1 = "ae1a63457e14554df2159b0b028f48536125092d" -uuid = "4d1e1d77-625e-5b40-9113-a560ec7a8ecd" -version = "0.0.8" - -[[ObjectFile]] -deps = ["Reexport", "StructIO", "Test"] -git-tree-sha1 = "1222547c57de96eaebc9f5d2579359db5d1a479d" -uuid = "d8793406-e978-5875-9003-1fc021f44a92" -version = "0.3.1" - -[[Observables]] -deps = ["Test"] -git-tree-sha1 = "dc02cec22747d1d10d9f70d8a1c03432b5bfbcd0" -uuid = "510215fc-4207-5dde-b226-833fc4488ee2" -version = "0.2.3" - -[[OffsetArrays]] -deps = ["DelimitedFiles", "Test"] -git-tree-sha1 = "f446248f2dfbc13039a0b90994dd25b059b01eab" -uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -version = "0.9.0" - -[[OnlineStats]] -deps = ["DataStructures", "Dates", "LearnBase", "LinearAlgebra", "LossFunctions", "OnlineStatsBase", "PenaltyFunctions", "Random", "RecipesBase", "Reexport", "Statistics", "StatsBase", "SweepOperator", "Test"] -git-tree-sha1 = "70fe5cbb31d37c18f6312a2994c31b782be50607" -uuid = "a15396b6-48d5-5d58-9928-6d29437db91e" -version = "0.19.2" - -[[OnlineStatsBase]] -deps = ["LearnBase", "Test"] -git-tree-sha1 = "520580a74e09378fb6665fa89339323d411d3df3" -uuid = "925886fa-5bf2-5e8e-b522-a9147a512338" -version = "0.9.1" - -[[OpenCL]] -git-tree-sha1 = "e664123afca13a0caf2f08f2b91714f724732293" -uuid = "08131aa3-fb12-5dee-8b74-c09406e224a2" -version = "0.7.0" - -[[Optim]] -deps = ["Calculus", "DiffEqDiffTools", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "Random", "SparseArrays", "StatsBase", "Test"] -git-tree-sha1 = "0f2a6c6ff9db396cc7af15bb1cf057a26662ff17" -uuid = "429524aa-4258-5aef-a3af-852621145aeb" -version = "0.17.2" - -[[OptimBase]] -deps = ["Compat", "NLSolversBase", "Printf", "Reexport", "Test"] -git-tree-sha1 = "92667ab46a66ad502ec3044f65c41ea68b2e0e9c" -uuid = "87e2bd06-a317-5318-96d9-3ecbac512eee" -version = "2.0.0" - -[[OrderedCollections]] -deps = ["Random", "Serialization", "Test"] -git-tree-sha1 = "85619a3f3e17bb4761fe1b1fd47f0e979f964d5b" -uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.0.2" - -[[OrdinaryDiffEq]] -deps = ["DataStructures", "DiffEqBase", "DiffEqDiffTools", "DiffEqOperators", "ExponentialUtilities", "ForwardDiff", "GenericSVD", "InteractiveUtils", "LinearAlgebra", "Logging", "MuladdMacro", "NLsolve", "Parameters", "Printf", "Random", "RecursiveArrayTools", "Reexport", "SparseArrays", "StaticArrays", "Statistics", "Test"] -git-tree-sha1 = "06b6488f3f17f816de2c96fc071a8115b84ca736" -uuid = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" -version = "4.18.0" - -[[PDMats]] -deps = ["Arpack", "LinearAlgebra", "SparseArrays", "SuiteSparse", "Test"] -git-tree-sha1 = "9e3e7a5c9b8cfdba8c01a1bcae38fe0144936fda" -uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" -version = "0.9.5" - -[[PackageCompiler]] -deps = ["ArgParse", "Libdl", "Pkg", "Serialization", "SnoopCompile", "Test", "WinRPM"] -git-tree-sha1 = "ba059afb6e9300fb4b059669cd695521e166c670" -uuid = "9b87118b-4619-50d2-8e1e-99f35a4d4d9d" -version = "0.5.1" - -[[Packing]] -deps = ["GeometryTypes", "Test"] -git-tree-sha1 = "bc7c284233cf0518933bf9977e3e8234efcc1c30" -uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" -version = "0.3.0" - -[[PaddedViews]] -deps = ["OffsetArrays", "Test"] -git-tree-sha1 = "7da3e7e1a58cffbf10177553ae95f17b92516912" -uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" -version = "0.4.2" - -[[ParallelDataTransfer]] -deps = ["Distributed", "Random", "Test"] -git-tree-sha1 = "75e75900c8b0d8dfb69cbe082832b1dc9f8aacfe" -uuid = "2dcacdae-9679-587a-88bb-8b444fb7085b" -version = "0.5.0" - -[[ParameterizedFunctions]] -deps = ["DataStructures", "DiffEqBase", "InteractiveUtils", "LinearAlgebra", "SimpleTraits", "SymEngine", "Test"] -git-tree-sha1 = "6949fb675cd36624581dd3c2487f1d61d019ace7" -uuid = "65888b18-ceab-5e60-b2b9-181511a3b968" -version = "4.0.0" - -[[Parameters]] -deps = ["Markdown", "OrderedCollections", "REPL", "Test"] -git-tree-sha1 = "eec0fe16344cc14aa2e6251874ab30d62aff4f7c" -uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" -version = "0.10.2" - -[[Parsers]] -deps = ["Dates", "Mmap", "Test", "WeakRefStrings"] -git-tree-sha1 = "949ca36d47010bee093254467166487c921d490b" -uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "0.2.14" - -[[PenaltyFunctions]] -deps = ["InteractiveUtils", "LearnBase", "LinearAlgebra", "RecipesBase", "Reexport", "Test"] -git-tree-sha1 = "b0baaa5218ca0ffd6a8ae37ef0b58e0df688ac8b" -uuid = "06bb1623-fdd5-5ca2-a01c-88eae3ea319e" -version = "0.1.2" - -[[Pidfile]] -deps = ["FileWatching", "Test"] -git-tree-sha1 = "1ffd82728498b5071cde851bbb7abd780d4445f3" -uuid = "fa939f87-e72e-5be4-a000-7fc836dbe307" -version = "1.1.0" - -[[Pkg]] -deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] -uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" - -[[PkgLicenses]] -deps = ["Test"] -git-tree-sha1 = "0af826be249c6751a3e783c07b8cd3034f508943" -uuid = "fc669557-7ec9-5e45-bca9-462afbc28879" -version = "0.2.0" - -[[PlotThemes]] -deps = ["PlotUtils", "Requires", "Test"] -git-tree-sha1 = "f3afd2d58e1f6ac9be2cea46e4a9083ccc1d990b" -uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a" -version = "0.3.0" - -[[PlotUtils]] -deps = ["Colors", "Dates", "Printf", "Random", "Reexport", "Test"] -git-tree-sha1 = "fd28f30a294a38ec847de95d8ac7ac916ccd7c06" -uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" -version = "0.5.5" - -[[PlotlyBase]] -deps = ["Dates", "DelimitedFiles", "DocStringExtensions", "JSON", "LaTeXStrings", "Logging", "Requires", "Statistics", "Test", "UUIDs"] -git-tree-sha1 = "685c331de7712539c1f0d06e061fe57320bba5c9" -uuid = "a03496cd-edff-5a9b-9e67-9cda94a718b5" -version = "0.2.5" - -[[PlotlyJS]] -deps = ["Blink", "Compat", "DelimitedFiles", "JSExpr", "JSON", "Markdown", "Pkg", "PlotlyBase", "REPL", "Reexport", "Requires", "Test", "WebIO"] -git-tree-sha1 = "b0c96bf425c49e6089a78e552043470cb22f73df" -uuid = "f0f68f2c-4968-5e81-91da-67840de0976a" -version = "0.12.0" - -[[Plots]] -deps = ["Base64", "Contour", "Dates", "FixedPointNumbers", "GR", "JSON", "LinearAlgebra", "Measures", "NaNMath", "Pkg", "PlotThemes", "PlotUtils", "Printf", "Random", "RecipesBase", "Reexport", "Requires", "Showoff", "SparseArrays", "StaticArrays", "Statistics", "StatsBase", "Test", "UUIDs"] -git-tree-sha1 = "a32a9328df6c12df20754afc5843374a72fdf266" -repo-rev = "master" -repo-url = "https://github.com/JuliaPlots/Plots.jl.git" -uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" -version = "0.21.0+" - -[[PoissonRandom]] -deps = ["Random", "Statistics", "Test"] -git-tree-sha1 = "831a15553303ad6ee277503672b51d1abfd83d38" -uuid = "e409e4f3-bfea-5376-8464-e040bb5c01ab" -version = "0.3.0" - -[[Polynomials]] -deps = ["LinearAlgebra", "SparseArrays", "Test"] -git-tree-sha1 = "1a1eae52956658a6acae6fa1b6d6c3d488192895" -uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" -version = "0.5.1" - -[[PooledArrays]] -deps = ["Test"] -git-tree-sha1 = "5c5ded7adc52867f599c21d3f43542fce491afda" -uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" -version = "0.4.1" - -[[PositiveFactorizations]] -deps = ["LinearAlgebra", "Test"] -git-tree-sha1 = "86ae7329c4b5c266acf5c7c524a972300d991e1c" -uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" -version = "0.2.1" - -[[Primes]] -deps = ["Test"] -git-tree-sha1 = "ff1a2323cb468ec5f201838fcbe3c232266b1f95" -uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" -version = "0.4.0" - -[[Printf]] -deps = ["Unicode"] -uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" - -[[Profile]] -deps = ["Printf"] -uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" - -[[ProgressMeter]] -deps = ["Distributed", "Printf", "Random", "Test"] -git-tree-sha1 = "37e7d3982c8d4610196829c01387dd561756aedc" -uuid = "92933f4c-e287-5a05-a399-4b506db050ca" -version = "0.8.0" - -[[PyCall]] -deps = ["Compat", "Conda", "MacroTools", "Statistics", "VersionParsing"] -git-tree-sha1 = "ce4681263f41d98b3faf6107b28284bf8b866f5f" -uuid = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0" -version = "1.18.5" - -[[PyPlot]] -deps = ["Colors", "Compat", "LaTeXStrings", "PyCall", "VersionParsing"] -git-tree-sha1 = "777c48006c57c8bd322d2032267085983a5fd50f" -uuid = "d330b81b-6aea-500a-939a-2ce795aea3ee" -version = "2.6.3" - -[[QBox]] -deps = ["AbstractPlotting", "ArnoldiMethod", "Arpack", "GeometryTypes", "LinearAlgebra", "LinearMaps", "Makie", "NearestNeighbors", "OffsetArrays", "ProgressMeter", "SparseArrays", "StaticArrays"] -git-tree-sha1 = "7375910b589eb23001498aa64cb4d4970e6de117" -repo-rev = "master" -repo-url = "https://github.com/pablosanjose/QBox" -uuid = "7d9ed76e-ca25-11e8-1412-8ff3848046c2" -version = "0.1.0" - -[[QBoxPlots]] -deps = ["AbstractPlotting", "GeometryTypes", "LinearAlgebra", "Makie", "QBox"] -git-tree-sha1 = "27ec515dd8daa6caadaeeb872d1cac5ae0edbb25" -repo-rev = "master" -repo-url = "https://github.com/pablosanjose/QBoxPlots" -uuid = "462ee96f-7267-546d-9451-704919036b07" -version = "0.1.0" - -[[QuadGK]] -deps = ["DataStructures", "LinearAlgebra", "Test"] -git-tree-sha1 = "7e8dff9c205f36eceaf6e62a43ff851637ca45fc" -uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.0.2" - -[[QuartzImageIO]] -deps = ["ColorTypes", "ColorVectorSpace", "FileIO", "FixedPointNumbers", "ImageCore", "Libdl", "Random", "Test"] -git-tree-sha1 = "c747a56f223919b157e6cd9dc58d59c560586302" -uuid = "dca85d43-d64c-5e67-8c65-017450d5d020" -version = "0.5.0" - -[[Quaternions]] -deps = ["Compat", "DualNumbers"] -git-tree-sha1 = "9ab39a818c92452f6b58d1ce88ea54cb7e038e7c" -uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" -version = "0.3.1" - -[[Query]] -deps = ["DataValues", "Documenter", "IterableTables", "MacroTools", "QueryOperators", "Statistics", "TableTraits", "Test"] -git-tree-sha1 = "e1b8e599878696dd1a9499e93fd8c707e9e7d222" -uuid = "1a8c2f83-1ff3-5112-b086-8aa67b057ba1" -version = "0.10.1" - -[[QueryOperators]] -deps = ["DataStructures", "DataValues", "IteratorInterfaceExtensions", "TableShowUtils", "Test"] -git-tree-sha1 = "4cf225548a6ab0004dfc4ca8c221946e2e8da853" -uuid = "2aef5ad7-51ca-5a8f-8e88-e75cf067b44b" -version = "0.5.1" - -[[RData]] -deps = ["CategoricalArrays", "CodecZlib", "DataFrames", "Dates", "FileIO", "Missings", "Test", "TimeZones"] -git-tree-sha1 = "8f3b644f4ebce291431846f5532272b0864c757c" -uuid = "df47a6cb-8c03-5eed-afd8-b6050d6c41da" -version = "0.5.0" - -[[RDatasets]] -deps = ["CSV", "CodecZlib", "DataFrames", "FileIO", "Printf", "RData", "Reexport", "Test"] -git-tree-sha1 = "4d93a52b94397bf0a9477d04e7a151a688672695" -uuid = "ce6b1742-4840-55fa-b093-852dadbb1d8b" -version = "0.6.1" - -[[REPL]] -deps = ["InteractiveUtils", "Markdown", "Sockets"] -uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" - -[[Random]] -deps = ["Serialization"] -uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" - -[[RandomNumbers]] -deps = ["Libdl", "Printf", "Random", "Test"] -git-tree-sha1 = "0687ea782f88706ef7969bc298f170e1ac7cb606" -uuid = "e6cf234a-135c-5ec9-84dd-332b85af5143" -version = "1.0.3" - -[[RangeArrays]] -deps = ["Compat"] -git-tree-sha1 = "d925adfd5b01cb46fde89dc9548d167b3b136f4a" -uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" -version = "0.3.1" - -[[Ratios]] -deps = ["Compat"] -git-tree-sha1 = "fd159bead0a24e6270fd0573a340312bd4645cc2" -uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" -version = "0.3.0" - -[[Reactive]] -deps = ["DataStructures", "Distributed", "Test"] -git-tree-sha1 = "2384e3bda9dcd16750ff605fdf817e18cfdd9bae" -uuid = "a223df75-4e93-5b7c-acf9-bdd599c0f4de" -version = "0.8.2" - -[[RecipesBase]] -deps = ["Random", "Test"] -git-tree-sha1 = "0b3cb370ee4dc00f47f1193101600949f3dcf884" -uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" -version = "0.6.0" - -[[RecursiveArrayTools]] -deps = ["RecipesBase", "Requires", "StaticArrays", "Statistics", "Test"] -git-tree-sha1 = "5ac1ea7d018bec90b0be614a9a37d1fd80dce8d9" -uuid = "731186ca-8d62-57ce-b412-fbd966d074cd" -version = "0.18.4" - -[[Reexport]] -deps = ["Pkg"] -git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" -uuid = "189a3867-3050-52da-a836-e630ba90ab69" -version = "0.2.0" - -[[Requires]] -deps = ["Test"] -git-tree-sha1 = "f6fbf4ba64d295e146e49e021207993b6b48c7d1" -uuid = "ae029012-a4dd-5104-9daa-d747884805df" -version = "0.5.2" - -[[ResettableStacks]] -deps = ["Random", "StaticArrays", "Test"] -git-tree-sha1 = "263fe0a06007bf5ba8f72c55475f58fc9bf81834" -uuid = "ae5879a3-cd67-5da8-be7f-38c6eb64a37b" -version = "0.5.0" - -[[ReverseDiff]] -deps = ["DiffResults", "DiffRules", "ForwardDiff", "FunctionWrappers", "LinearAlgebra", "NaNMath", "Random", "SpecialFunctions", "StaticArrays", "Statistics", "Test"] -git-tree-sha1 = "d44e80d815a1a5abaf1ff1def21bb629cabaffec" -uuid = "37e2e3b7-166d-5795-8a7a-e32c996b4267" -version = "0.3.1" - -[[Revise]] -deps = ["Distributed", "FileWatching", "InteractiveUtils", "LibGit2", "OrderedCollections", "Pkg", "REPL", "Random", "Test", "UUIDs", "Unicode"] -git-tree-sha1 = "556c5f7bd46f99dee93b5e49a1339499beec0e05" -repo-rev = "master" -repo-url = "https://github.com/timholy/Revise.jl.git" -uuid = "295af30f-e4ad-537b-8983-00126c2a3abe" -version = "0.7.13+" - -[[Rmath]] -deps = ["BinaryProvider", "Libdl", "Random", "Statistics", "Test"] -git-tree-sha1 = "9a6c758cdf73036c3239b0afbea790def1dabff9" -uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" -version = "0.5.0" - -[[Roots]] -deps = ["Compat", "Printf"] -git-tree-sha1 = "2e7171b6f3b58b81201ba37d9e1220aff6d904a1" -uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -version = "0.7.4" - -[[Rotations]] -deps = ["LinearAlgebra", "Random", "StaticArrays", "Statistics", "Test"] -git-tree-sha1 = "b629771d0de88979cbdbf72ceddc54de58fde149" -uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" -version = "0.9.1" - -[[SHA]] -uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" - -[[SIUnits]] -deps = ["Compat", "TexExtensions"] -git-tree-sha1 = "224d83b62711fe7e429454aace2c97eb2cf36031" -uuid = "b9d75638-96e3-5676-bdf0-e9c958f63a55" -version = "0.1.0" - -[[Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" - -[[SetRounding]] -deps = ["Test"] -git-tree-sha1 = "faca28c7937138d560ede5bfef2076d0cdf3584b" -uuid = "3cc68bcd-71a2-5612-b932-767ffbe40ab0" -version = "0.2.0" - -[[SharedArrays]] -deps = ["Distributed", "Mmap", "Random", "Serialization"] -uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" - -[[Showoff]] -deps = ["Compat"] -git-tree-sha1 = "276b24f3ace98bec911be7ff2928d497dc759085" -uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" -version = "0.2.1" - -[[SignedDistanceFields]] -deps = ["Random", "Statistics", "Test"] -git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" -uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" -version = "0.4.0" - -[[SimpleTraits]] -deps = ["InteractiveUtils", "MacroTools", "Test"] -git-tree-sha1 = "c0a542b8d5e369b179ccd296b2ca987f6da5da0a" -uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" -version = "0.8.0" - -[[SingularIntegralEquations]] -deps = ["ApproxFun", "BandedMatrices", "DomainSets", "DualNumbers", "FastTransforms", "InteractiveUtils", "LinearAlgebra", "LowRankApprox", "RecipesBase", "SpecialFunctions", "Test"] -git-tree-sha1 = "87955f9f6d8b7aa0388230867928fd099743539b" -uuid = "e094c991-5a90-5477-8896-c1e4c9552a1a" -version = "0.4.1" - -[[SnoopCompile]] -deps = ["Pkg", "Serialization", "Test"] -git-tree-sha1 = "bf278fd3d9ec1d8183dcf81291c1994561b66c93" -uuid = "aa65fe97-06da-5843-b5b1-d5d13cad87d2" -version = "0.3.1" - -[[Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" - -[[SoftGlobalScope]] -deps = ["Test"] -git-tree-sha1 = "97f6dfcf612b9a7260fde44170725d9ea34b1431" -uuid = "b85f4697-e234-5449-a836-ec8e2f98b302" -version = "1.0.7" - -[[SortingAlgorithms]] -deps = ["DataStructures", "Random", "Test"] -git-tree-sha1 = "03f5898c9959f8115e30bc7226ada7d0df554ddd" -uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "0.3.1" - -[[SparseArrays]] -deps = ["LinearAlgebra", "Random"] -uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - -[[SpecialFunctions]] -deps = ["BinDeps", "BinaryProvider", "Libdl", "Test"] -git-tree-sha1 = "0b45dc2e45ed77f445617b99ff2adf0f5b0f23ea" -uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "0.7.2" - -[[StatPlots]] -deps = ["Clustering", "DataStructures", "DataValues", "Distributions", "IterableTables", "KernelDensity", "Observables", "Plots", "Reexport", "StatsBase", "TableTraits", "TableTraitsUtils", "Test", "Widgets"] -git-tree-sha1 = "e35b968df3937eaee1c8df698bcfd7d047c45110" -uuid = "60ddc479-9b66-56df-82fc-76a74619b69c" -version = "0.8.2" - -[[StaticArrays]] -deps = ["InteractiveUtils", "LinearAlgebra", "Random", "Statistics", "Test"] -git-tree-sha1 = "6804a209e3a3cc436c56da0d4d67789159b1b232" -repo-rev = "master" -repo-url = "https://github.com/JuliaArrays/StaticArrays.jl.git" -uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "0.10.0+" - -[[Statistics]] -deps = ["LinearAlgebra", "SparseArrays"] -uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" - -[[StatsBase]] -deps = ["DataStructures", "LinearAlgebra", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "Test"] -git-tree-sha1 = "2722397d88f8ffef551948f6c20e1d74a743298c" -uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" -version = "0.26.0" - -[[StatsFuns]] -deps = ["Rmath", "SpecialFunctions", "Test"] -git-tree-sha1 = "d14bb7b03defd2deaa5675646f6783089e0556f0" -uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" -version = "0.7.0" - -[[StatsMakie]] -deps = ["AbstractPlotting", "Distributions", "FreqTables", "IndexedTables", "IntervalSets", "KernelDensity", "Loess", "NamedArrays", "Observables", "Random", "Statistics", "StatsBase", "Tables", "Test"] -git-tree-sha1 = "7745ba65ac5a3d17514a605dd87ec6fb54c708e9" -repo-rev = "master" -repo-url = "https://github.com/JuliaPlots/StatsMakie.jl.git" -uuid = "9d48ccf0-4268-5716-84ff-21228f561db3" -version = "0.0.0" - -[[SteadyStateDiffEq]] -deps = ["Compat", "DiffEqBase", "DiffEqCallbacks", "LinearAlgebra", "NLsolve", "Reexport", "Test"] -git-tree-sha1 = "fe9852d18c3e30f384003da50d6049e5fbc97071" -uuid = "9672c7b4-1e72-59bd-8a11-6ac3964bc41f" -version = "1.4.0" - -[[StochasticDiffEq]] -deps = ["DataStructures", "DiffEqBase", "DiffEqDiffTools", "DiffEqNoiseProcess", "DiffEqOperators", "Distributed", "ForwardDiff", "LinearAlgebra", "Logging", "MuladdMacro", "NLsolve", "Parameters", "Random", "RandomNumbers", "RecursiveArrayTools", "Reexport", "SparseArrays", "StaticArrays", "Test"] -git-tree-sha1 = "c1542e708fa2947cf7a82c376a8c99dc448e6ca1" -uuid = "789caeaf-c7a9-5a7d-9973-96adeb23e2a0" -version = "5.10.1" - -[[Strided]] -deps = ["LinearAlgebra", "Random", "Test", "TupleTools"] -git-tree-sha1 = "b03964f2d298810910195f3e8d56ceff8f60e02a" -uuid = "5e0ebb24-38b0-5f93-81fe-25c709ecae67" -version = "0.2.2" - -[[StringDistances]] -deps = ["Distances", "IterTools", "Test"] -git-tree-sha1 = "41fddd579b75e0cd0d1bbdb2d68a2a9cc588c164" -uuid = "88034a9c-02f8-509d-84a9-84ec65e18404" -version = "0.3.0" - -[[StructArrays]] -deps = ["Requires", "Test"] -git-tree-sha1 = "d1e764a3afdd6e4326392144fc0c81faf55e48a9" -uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" -version = "0.1.0" - -[[StructIO]] -deps = ["Test"] -git-tree-sha1 = "010dc73c7146869c042b49adcdb6bf528c12e859" -uuid = "53d494c1-5632-5724-8f4c-31dff12d585f" -version = "0.3.0" - -[[SuiteSparse]] -deps = ["Libdl", "LinearAlgebra", "SparseArrays"] -uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" - -[[Sundials]] -deps = ["BinaryProvider", "DataStructures", "DiffEqBase", "Libdl", "LinearAlgebra", "Reexport", "SparseArrays", "Test"] -git-tree-sha1 = "01ecb3f3dc5c57f9cf0ae3ccf91ede899440d076" -uuid = "c3572dad-4567-51f8-b174-8c6c989267f4" -version = "2.6.0" - -[[Suppressor]] -deps = ["Compat"] -git-tree-sha1 = "a39342763981e766a72938b59032dc02a2d74da5" -uuid = "fd094767-a336-5f1f-9728-57cf17d0bbfb" -version = "0.1.1" - -[[SweepOperator]] -deps = ["LinearAlgebra", "Test"] -git-tree-sha1 = "2039aaa96f7b21634a1b3246cb2699dd1d26d473" -uuid = "7522ee7d-7047-56d0-94d9-4bc626e7058d" -version = "0.2.0" - -[[SymEngine]] -deps = ["BinaryProvider", "Compat", "Libdl", "RecipesBase", "SpecialFunctions"] -git-tree-sha1 = "bd5ca0295542ad6967f3f837bb6bef6add0e4c33" -uuid = "123dc426-2d89-5057-bbad-38513e3affd8" -version = "0.4.3" - -[[TableShowUtils]] -deps = ["DataValues", "Dates", "JSON", "Markdown", "Test"] -git-tree-sha1 = "6ffc18504eab3f900af2d23adc0e7bddf94bd29b" -uuid = "5e66a065-1f0a-5976-b372-e0b8c017ca10" -version = "0.2.1" - -[[TableTraits]] -deps = ["IteratorInterfaceExtensions", "Test"] -git-tree-sha1 = "da062a2c31f16178f68190243c24140801720a43" -uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" -version = "0.4.0" - -[[TableTraitsUtils]] -deps = ["DataValues", "IteratorInterfaceExtensions", "Missings", "TableTraits", "Test"] -git-tree-sha1 = "a355f1882d64881a11f853e64dcc353975c4df6e" -uuid = "382cd787-c1b6-5bf2-a167-d5b971a19bda" -version = "0.3.1" - -[[Tables]] -deps = ["Requires", "Test"] -git-tree-sha1 = "c7fb447deab835fa70ce6717e78c68b0f466a42c" -uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "0.1.11" - -[[Test]] -deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] -uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[[TexExtensions]] -deps = ["Compat"] -git-tree-sha1 = "092ad55ed044aa5ab31ee800d4ae5bec526a8f09" -uuid = "9b435220-3ad3-5d4f-b1ea-1e7b29ae9b13" -version = "0.1.0" - -[[TextParse]] -deps = ["CodecZlib", "DataStructures", "Dates", "DoubleFloats", "Mmap", "Nullables", "PooledArrays", "Random", "Test", "WeakRefStrings"] -git-tree-sha1 = "383329847d816310d63df8e220d1be0b68e0cecc" -uuid = "e0df1984-e451-5cb5-8b61-797a481e67e3" -version = "0.6.1" - -[[TextWrap]] -deps = ["Compat", "Test"] -git-tree-sha1 = "8355cc559e85469cd4dbe927c375f61d3750e002" -uuid = "b718987f-49a8-5099-9789-dcd902bef87d" -version = "0.3.0" - -[[TiledIteration]] -deps = ["OffsetArrays", "Test"] -git-tree-sha1 = "58f6f07d3b54a363ec283a8f5fc9fb4ecebde656" -uuid = "06e1c1a7-607b-532d-9fad-de7d9aa2abac" -version = "0.2.3" - -[[TimeZones]] -deps = ["Compat", "EzXML", "Mocking", "Nullables"] -git-tree-sha1 = "4a4ab113913e19ad62b67e6c5c056509eac00c19" -uuid = "f269a46b-ccf7-5d73-abea-4c690281aa53" -version = "0.8.2" - -[[TimerOutputs]] -deps = ["Crayons", "Printf", "Test", "Unicode"] -git-tree-sha1 = "89a9bd610d6bfd62a7c2b85112762b99b979fe5f" -uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" -version = "0.4.0" - -[[ToeplitzMatrices]] -deps = ["Compat", "FFTW", "LinearAlgebra", "StatsBase"] -git-tree-sha1 = "141e0fc05428a280a056cfdea6b98ef54a208535" -uuid = "c751599d-da0a-543b-9d20-d0a503d91d24" -version = "0.4.2" - -[[Tokenize]] -deps = ["Printf", "Test"] -git-tree-sha1 = "4a9fefb5c5c831c6fc06fcc5d2ae7399918bb587" -uuid = "0796e94c-ce3b-5d07-9a54-7f471281c624" -version = "0.5.2" - -[[Traceur]] -deps = ["Cassette", "InteractiveUtils", "Logging", "MacroTools", "Test"] -git-tree-sha1 = "d46ea4a2575f896e90c8a4b52ce2841e6db7d059" -uuid = "37b6cedf-1f77-55f8-9503-c64b63398394" -version = "0.2.0" - -[[TranscodingStreams]] -deps = ["Pkg", "Random", "Test"] -git-tree-sha1 = "a34a2d588e2d2825602bf14a24216d5c8b0921ec" -uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.8.1" - -[[TreeViews]] -deps = ["Test"] -git-tree-sha1 = "8d0d7a3fe2f30d6a7f833a5f19f7c7a5b396eae6" -uuid = "a2a6695c-b41b-5b7d-aed9-dbfdeacea5d7" -version = "0.3.0" - -[[TupleTools]] -deps = ["Random", "Test"] -git-tree-sha1 = "781df0cfac68723c3800eb9344b85bd86f9e424b" -uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" -version = "1.0.2" - -[[URIParser]] -deps = ["Test", "Unicode"] -git-tree-sha1 = "6ddf8244220dfda2f17539fa8c9de20d6c575b69" -uuid = "30578b45-9adc-5946-b283-645ec420af67" -version = "0.4.0" - -[[UUIDs]] -deps = ["Random"] -uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" - -[[Unicode]] -uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" - -[[UnicodeFun]] -deps = ["Test"] -git-tree-sha1 = "63cbbd00217fc9aafedf055b60459c1ae7e01ecc" -uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" -version = "0.4.0" - -[[Unitful]] -deps = ["LinearAlgebra", "Random", "Test"] -git-tree-sha1 = "15c921708e19258fc9e7723aafc5f15c973ee77f" -uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" -version = "0.13.0" - -[[VectorizedRoutines]] -deps = ["Distributions"] -git-tree-sha1 = "3fdeedbc9d462a3d597606ad8183cf5907e04896" -uuid = "0e69188a-a5d4-5622-b4e4-a72373136fc5" -version = "0.0.2" - -[[VegaDatasets]] -deps = ["DataStructures", "DataValues", "FilePaths", "IterableTables", "IteratorInterfaceExtensions", "JSON", "TableShowUtils", "TableTraits", "TableTraitsUtils", "Test", "TextParse"] -git-tree-sha1 = "894794f267e13d4d440a3720e11ba212d5d28f47" -uuid = "0ae4a718-28b7-58ec-9efb-cded64d6d5b4" -version = "0.5.0" - -[[VersionParsing]] -deps = ["Compat"] -git-tree-sha1 = "c9d5aa108588b978bd859554660c8a5c4f2f7669" -uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" -version = "1.1.3" - -[[WeakRefStrings]] -deps = ["Missings", "Random", "Test"] -git-tree-sha1 = "1087e8be380f2c8b96434b02bb1150fc1c511135" -uuid = "ea10d353-3f73-51f8-a26c-33c1cb351aa5" -version = "0.5.3" - -[[WebIO]] -deps = ["AssetRegistry", "Base64", "Compat", "FunctionalCollections", "JSON", "Logging", "Observables", "Random", "Requires", "Sockets", "Test", "UUIDs", "Widgets"] -git-tree-sha1 = "c1edaf26cc283d81edd97385fb8fde80018b0770" -uuid = "0f1e0344-ec1d-5b48-a673-e5cf874b6c29" -version = "0.6.1" - -[[WebSockets]] -deps = ["Base64", "Dates", "Distributed", "HTTP", "Logging", "MbedTLS", "Random", "Sockets", "Test"] -git-tree-sha1 = "c898a35f93bb010d8e44932c1a736e22c6343f9c" -uuid = "104b5d7c-a370-577a-8038-80a2059c5097" -version = "1.1.0" - -[[Widgets]] -deps = ["DataStructures", "Observables", "Test"] -git-tree-sha1 = "944c2f6c3b92b0689e5f46988536bee26bba4d8a" -uuid = "cc8bc4a8-27d6-5769-a93b-9d913e69aa62" -version = "0.4.3" - -[[WinRPM]] -deps = ["BinDeps", "Compat", "HTTPClient", "LibExpat", "Libdl", "Libz", "URIParser"] -git-tree-sha1 = "2a889d320f3b77d17c037f295859fe570133cfbf" -uuid = "c17dfb99-b4f7-5aad-8812-456da1ad7187" -version = "0.4.2" - -[[WoodburyMatrices]] -deps = ["LinearAlgebra", "Random", "SparseArrays", "Test"] -git-tree-sha1 = "21772c33b447757ec7d3e61fcdfb9ea5c47eedcf" -uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" -version = "0.4.1" - -[[ZMQ]] -deps = ["BinaryProvider", "FileWatching", "Libdl", "Sockets", "Test"] -git-tree-sha1 = "34e7ac2d1d59d19d0e86bde99f1f02262bfa1613" -uuid = "c2297ded-f4af-51ae-bb23-16f91089e4e1" -version = "1.0.0" - -[[ZipFile]] -deps = ["BinaryProvider", "Libdl", "Printf", "Test"] -git-tree-sha1 = "4000c633efe994b2e10b31b6d91382c4b7412dac" -uuid = "a5390f91-8eb1-5f08-bee0-b1d1ffed6cea" -version = "0.8.0" - -[[Zygote]] -deps = ["DiffRules", "ForwardDiff", "InteractiveUtils", "MacroTools", "NNlib", "NaNMath", "Random", "Requires", "SpecialFunctions", "Test"] -git-tree-sha1 = "e41d254728d3968052c3ef62134f063257a4f077" -uuid = "e88e6eb3-aa80-5325-afca-941959d7151f" -version = "0.1.0" diff --git a/Project.toml b/Project.toml deleted file mode 100644 index 1be5a9403f2..00000000000 --- a/Project.toml +++ /dev/null @@ -1,39 +0,0 @@ -name = "GLMakie" -uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" - -[deps] -AbstractPlotting = "537997a7-5e4e-5d89-9595-2241ea00577e" -AxisArrays = "39de3d68-74b9-583c-8d2d-e117c070f3a9" -ColorBrewer = "a2cac450-b92f-5266-8821-25eda20663c8" -ColorTypes = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" -ColorVectorSpace = "c3611d14-8923-5661-9e6a-0046d554d3a4" -Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" -Contour = "d38c429a-6771-53c6-b99e-75d170b6e991" -FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -FixedPointNumbers = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -FreeType = "b38be410-82b0-50bf-ab77-7b57e271db43" -FreeTypeAbstraction = "663a7486-cb36-511b-a19d-713bb74d65c9" -GLFW = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" -GeometryTypes = "4d00f742-c7ba-57c2-abde-4428a4b178cb" -ImageAxes = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" -ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534" -ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" -ImageTransformations = "02fcd773-0e25-5acc-982a-7f6622650795" -IndirectArrays = "9b13fd28-a010-5f03-acff-a1bbcff69959" -IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" -IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e" -LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a" -ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" -Observables = "510215fc-4207-5dde-b226-833fc4488ee2" -Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -PlotUtils = "995b91a9-d308-5afd-9ec6-746e21dbc043" -Primes = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" -Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" -QuartzImageIO = "dca85d43-d64c-5e67-8c65-017450d5d020" -Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" -Showoff = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" -StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" -Suppressor = "fd094767-a336-5f1f-9728-57cf17d0bbfb" -UnicodeFun = "1cfade01-22cf-5700-b092-accc4b62d6e1" -MakieGallery = "62e31da0-2f4f-5d53-819c-a7cea9df6aaa" diff --git a/test/REQUIRE b/test/REQUIRE index e5985de766f..56f84bd113a 100644 --- a/test/REQUIRE +++ b/test/REQUIRE @@ -13,3 +13,4 @@ FileIO ImageFiltering DataFrames RDatasets +MakieGallery From cf5c91c760433825834adcbe5ab4832ae7a5b575 Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 2 Dec 2018 15:03:54 +0100 Subject: [PATCH 0019/1328] update for init errors --- deps/build.jl | 55 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/deps/build.jl b/deps/build.jl index 849dd007718..0a726489c50 100644 --- a/deps/build.jl +++ b/deps/build.jl @@ -28,29 +28,40 @@ catch e error(install_tips) end -using ModernGL -# Create a windowed mode window and its OpenGL context -window = GLFW.CreateWindow(10, 10, "OpenGL Example") -# Make the window's context current -GLFW.HideWindow(window) -GLFW.MakeContextCurrent(window) -glversion = unsafe_string(glGetString(GL_VERSION)) -m = match(r"(\d+)\.(\d+)\.(\d+)?(.*)", glversion) -# I don't really trust that all vendors have a version that matches -# the above regex, so let's make no match non fatal! -if m === nothing - @warn("Unknown OpenGL version format: $glversion. You need to verify if it's above OpenGL 3.3 yourself!") -else - v = VersionNumber(parse(Int, m[1]), parse(Int, m[2])) - if !(v >= v"3.3") - open("deps.jl", "w") do io - println(io, "const WORKING_OPENGL = false") +try + using ModernGL + # Create a windowed mode window and its OpenGL context + window = GLFW.CreateWindow(10, 10, "OpenGL Example") + # Make the window's context current + GLFW.HideWindow(window) + GLFW.MakeContextCurrent(window) + glversion = unsafe_string(glGetString(GL_VERSION)) + m = match(r"(\d+)\.(\d+)\.(\d+)?(.*)", glversion) + # I don't really trust that all vendors have a version that matches + # the above regex, so let's make no match non fatal! + if m === nothing + @warn("Unknown OpenGL version format: $glversion. You need to verify if it's above OpenGL 3.3 yourself!") + else + v = VersionNumber(parse(Int, m[1]), parse(Int, m[2])) + if !(v >= v"3.3") + open("deps.jl", "w") do io + println(io, "const WORKING_OPENGL = false") + end + println(stderr, "Your OpenGL version is too low! Update your driver or GPU! Version found: $v, version required: 3.3") + error(install_tips) end - println(stderr, "Your OpenGL version is too low! Update your driver or GPU! Version found: $v, version required: 3.3") - error(install_tips) end -end -open("deps.jl", "w") do io - println(io, "const WORKING_OPENGL = true") + open("deps.jl", "w") do io + println(io, "const WORKING_OPENGL = true") + end +catch e + open("deps.jl", "w") do io + println(io, "const WORKING_OPENGL = false") + end + # it would be nice to check if this is a GLFW error, but if GLFW doesn't actually load + # we can't easily use GLFW.GLFWError. Well, GLFW error is the most likely, and + # we will print the error, to inform the user what happens, so I think this should be fine! + println(stderr, "init error of GLFW") + error(install_tips) end From 2aa72e78dcf74afd5576ab2d62a7b2036b1e36fa Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 2 Dec 2018 15:56:34 +0100 Subject: [PATCH 0020/1328] Sd tests (#1) add tests --- .travis.yml | 24 +- Manifest.toml | 722 +++++++++++++++++++++++++++++++++++++++++ Project.toml | 23 ++ cleanmani.jl | 40 +++ src/CairoMakie.jl | 355 +++++++++++++------- test/.gitignore | 2 + test/install_ffmpeg.sh | 5 + test/runtests.jl | 28 +- 8 files changed, 1078 insertions(+), 121 deletions(-) create mode 100644 Manifest.toml create mode 100644 Project.toml create mode 100644 cleanmani.jl create mode 100644 test/.gitignore create mode 100644 test/install_ffmpeg.sh diff --git a/.travis.yml b/.travis.yml index 01a9b778a08..bfb8a71d46b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,24 @@ -## Documentation: http://docs.travis-ci.com/user/languages/julia/ language: julia -os: - - linux - - osx + julia: - 1.0 - nightly + +matrix: + allow_failures: + - julia: nightly + notifications: email: false -git: - depth: 99999999 +os: + - linux + - osx +sudo: true + +before_install: + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo add-apt-repository ppa:mc3man/trusty-media -y; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get update -q; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install zlib1g-dev -y; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install ffmpeg gstreamer0.10-ffmpeg -y; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install imagemagick -y; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install ffmpeg; fi diff --git a/Manifest.toml b/Manifest.toml new file mode 100644 index 00000000000..2b8c539e3d7 --- /dev/null +++ b/Manifest.toml @@ -0,0 +1,722 @@ +[[AbstractFFTs]] +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "8d59c3b1463b5e0ad05a3698167f85fac90e184d" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "0.3.2" + +[[AbstractPlotting]] +deps = ["ColorBrewer", "ColorTypes", "Colors", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "Test", "UnicodeFun"] +git-tree-sha1 = "0e969852e9c20f24ad6ef705faa8db32f0990238" +repo-rev = "master" +repo-url = "https://github.com/JuliaPlots/AbstractPlotting.jl.git" +uuid = "537997a7-5e4e-5d89-9595-2241ea00577e" +version = "0.9.0+" + +[[AxisAlgorithms]] +deps = ["Compat", "WoodburyMatrices"] +git-tree-sha1 = "99dabbe853e4f641ab21a676131f2cf9fb29937e" +uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" +version = "0.3.0" + +[[AxisArrays]] +deps = ["Compat", "Dates", "IntervalSets", "IterTools", "Random", "RangeArrays", "Test"] +git-tree-sha1 = "2e2536e9e6f27c4f8d09d8442b61a7ae0b910c28" +uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" +version = "0.3.0" + +[[Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[BinDeps]] +deps = ["Compat", "Libdl", "SHA", "URIParser"] +git-tree-sha1 = "12093ca6cdd0ee547c39b1870e0c9c3f154d9ca9" +uuid = "9e28174c-4ba2-5203-b857-d8d62c4213ee" +version = "0.8.10" + +[[BinaryProvider]] +deps = ["Libdl", "Pkg", "SHA", "Test"] +git-tree-sha1 = "055eb2690182ebc31087859c3dd8598371d3ef9e" +uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" +version = "0.5.3" + +[[BufferedStreams]] +deps = ["Compat", "Test"] +git-tree-sha1 = "5d55b9486590fdda5905c275bb21ce1f0754020f" +uuid = "e1450e63-4bb3-523b-b2a4-4ffa8c0fd77d" +version = "1.0.0" + +[[CMake]] +deps = ["BinDeps", "Libdl", "Test"] +git-tree-sha1 = "74853a75c26a4a73ac391ee26ee29ebeb5583d9f" +uuid = "631607c0-34d2-5d66-819e-eb0f9aa2061a" +version = "1.1.0" + +[[CMakeWrapper]] +deps = ["BinDeps", "CMake", "Libdl", "Parameters", "Test"] +git-tree-sha1 = "2b43d451639984e3571951cc687b8509b0a86c6d" +uuid = "d5fb7624-851a-54ee-a528-d3f3bac0b4a0" +version = "0.2.2" + +[[CSV]] +deps = ["CategoricalArrays", "DataFrames", "DataStreams", "Dates", "Mmap", "Parsers", "Profile", "Random", "Tables", "Test", "Unicode", "WeakRefStrings"] +git-tree-sha1 = "b92c6f626a044cc9619156d54994b94084d40abe" +uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" +version = "0.4.3" + +[[Cairo]] +deps = ["BinDeps", "Colors", "Compat", "Graphics", "Homebrew", "Libdl", "WinRPM"] +git-tree-sha1 = "a427098d5aa2808504d94b8ed9fc5740ceaf71d0" +uuid = "159f3aea-2a34-519c-b102-8c37f9878175" +version = "0.5.6" + +[[CatIndices]] +deps = ["CustomUnitRanges", "OffsetArrays", "Test"] +git-tree-sha1 = "254cf73ea369d2e39bfd6c5eb27a2296cfaed68c" +uuid = "aafaddc9-749c-510e-ac4f-586e18779b91" +version = "0.2.0" + +[[CategoricalArrays]] +deps = ["Compat", "Future", "Missings", "Printf", "Reexport", "Requires"] +git-tree-sha1 = "11419d157ab75a54a8af63315e7a279a593971bc" +uuid = "324d7699-5711-5eae-9e2f-1d82baa6b597" +version = "0.5.1" + +[[CodecZlib]] +deps = ["BinaryProvider", "Libdl", "Test", "TranscodingStreams"] +git-tree-sha1 = "e3df104c84dfc108f0ca203fd7f5bbdc98641ae9" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.5.1" + +[[ColorBrewer]] +deps = ["Colors", "JSON", "Test"] +git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" +uuid = "a2cac450-b92f-5266-8821-25eda20663c8" +version = "0.4.0" + +[[ColorTypes]] +deps = ["FixedPointNumbers", "Random", "Test"] +git-tree-sha1 = "f73b0e10f2a5756de7019818a41654686da06b09" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.7.5" + +[[ColorVectorSpace]] +deps = ["ColorTypes", "Colors", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "StatsBase", "Test"] +git-tree-sha1 = "a890f08e61b40e9843d7177206da61229a3603c8" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.6.2" + +[[Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "InteractiveUtils", "Printf", "Reexport", "Test"] +git-tree-sha1 = "9f0a0210450acb91c730b730a994f8eef1d3d543" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.9.5" + +[[Compat]] +deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] +git-tree-sha1 = "ec61a16eed883ad0cfa002d7489b3ce6d039bb9a" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "1.4.0" + +[[ComputationalResources]] +deps = ["Test"] +git-tree-sha1 = "89e7e7ed20af73d9f78877d2b8d1194e7b6ff13d" +uuid = "ed09eef8-17a6-5b46-8889-db040fac31e3" +version = "0.3.0" + +[[Conda]] +deps = ["Compat", "JSON", "VersionParsing"] +git-tree-sha1 = "fb86fe40cb5b35990e368709bfdc1b46dbb99dac" +uuid = "8f4d0f93-b110-5947-807f-2305c1781a2d" +version = "1.1.1" + +[[Contour]] +deps = ["LinearAlgebra", "StaticArrays", "Test"] +git-tree-sha1 = "b974e164358fea753ef853ce7bad97afec15bb80" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.5.1" + +[[CoordinateTransformations]] +deps = ["Compat", "Rotations", "StaticArrays"] +git-tree-sha1 = "47f05d0b7f4999609f92e657147df000818c1f24" +uuid = "150eb455-5306-5404-9cee-2592286d6298" +version = "0.5.0" + +[[CustomUnitRanges]] +deps = ["Test"] +git-tree-sha1 = "0a106457a1831555857e18ac9617279c22fc393b" +uuid = "dc8bdbbb-1ca9-579f-8c36-e416f6a65cce" +version = "0.2.0" + +[[DataFrames]] +deps = ["CategoricalArrays", "CodecZlib", "Compat", "DataStreams", "Dates", "InteractiveUtils", "IteratorInterfaceExtensions", "LinearAlgebra", "Missings", "Printf", "Random", "Reexport", "SortingAlgorithms", "Statistics", "StatsBase", "TableTraits", "Tables", "Test", "TranscodingStreams", "Unicode", "WeakRefStrings"] +git-tree-sha1 = "ad34fefb72b18a8dd5c17fab9089d11111b61935" +uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +version = "0.14.1" + +[[DataStreams]] +deps = ["Dates", "Missings", "Test", "WeakRefStrings"] +git-tree-sha1 = "69c72a1beb4fc79490c361635664e13c8e4a9548" +uuid = "9a8bc11e-79be-5b39-94d7-1ccc349a1a85" +version = "0.4.1" + +[[DataStructures]] +deps = ["InteractiveUtils", "OrderedCollections", "Random", "Serialization", "Test"] +git-tree-sha1 = "8fc6e166e24fda04b2b648d4260cdad241788c54" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.14.0" + +[[Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[DelimitedFiles]] +deps = ["Mmap"] +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" + +[[Distributed]] +deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[DocStringExtensions]] +deps = ["LibGit2", "Markdown", "Pkg", "Test"] +git-tree-sha1 = "1df01539a1c952cef21f2d2d1c092c2bcf0177d7" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.6.0" + +[[Documenter]] +deps = ["Base64", "DocStringExtensions", "InteractiveUtils", "LibGit2", "Logging", "Markdown", "Pkg", "REPL", "Random", "Test", "Unicode"] +git-tree-sha1 = "9f2135e0e7ecb63f9c3ef73ea15a31d8cdb79bb7" +uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +version = "0.20.0" + +[[EzXML]] +deps = ["BinaryProvider", "Libdl", "Printf", "Test"] +git-tree-sha1 = "5623d1486bfaadd815f5c4ca501adda02b5337f1" +uuid = "8f5d6c58-4d21-5cfd-889c-e3ad7ee6a615" +version = "0.9.0" + +[[FFTViews]] +deps = ["CustomUnitRanges", "FFTW", "Test"] +git-tree-sha1 = "9d7993227ca7c0fdb6b31deef193adbba11c8f4e" +uuid = "4f61f5a4-77b1-5117-aa51-3ab5ef4ef0cd" +version = "0.2.0" + +[[FFTW]] +deps = ["AbstractFFTs", "BinaryProvider", "Compat", "Conda", "Libdl", "LinearAlgebra", "Reexport", "Test"] +git-tree-sha1 = "29cda58afbf62f35b1a094882ad6c745a47b2eaa" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "0.2.4" + +[[FileIO]] +deps = ["Pkg", "Random", "Test"] +git-tree-sha1 = "1a114d08094e7267ba8d4d684f930d5a722184de" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.0.4" + +[[FixedPointNumbers]] +deps = ["Test"] +git-tree-sha1 = "b8045033701c3b10bf2324d7203404be7aef88ba" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.5.3" + +[[FreeType]] +deps = ["BinaryProvider", "Libdl", "Pkg", "Test"] +git-tree-sha1 = "06462b9d5aca708d764d16e5ba6a83ba7b753d57" +uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" +version = "2.1.1" + +[[FreeTypeAbstraction]] +deps = ["ColorVectorSpace", "Colors", "FreeType", "StaticArrays", "Test"] +git-tree-sha1 = "271ef13438bd0946950fd34d9241e5beefd6d4b3" +uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" +version = "0.4.1" + +[[Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" + +[[GDAL]] +deps = ["BinaryProvider", "Libdl", "Test"] +git-tree-sha1 = "100429098b7ec9930f7db9ba68aee3495365be24" +uuid = "add2ef01-049f-52c4-9ee2-e494f65e021a" +version = "0.2.0" + +[[GLFW]] +deps = ["BinDeps", "CMakeWrapper", "Homebrew", "Libdl", "Test"] +git-tree-sha1 = "035e2b5e9c335afae1e92ecfe532cf0620da869f" +uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" +version = "2.3.0" + +[[GLMakie]] +deps = ["AbstractPlotting", "AxisArrays", "ColorBrewer", "ColorTypes", "ColorVectorSpace", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GLFW", "GeometryTypes", "ImageAxes", "ImageCore", "ImageMagick", "ImageTransformations", "IndirectArrays", "IntervalSets", "IterTools", "LinearAlgebra", "Markdown", "ModernGL", "Observables", "PlotUtils", "Primes", "Printf", "QuartzImageIO", "Serialization", "Showoff", "StaticArrays", "UnicodeFun"] +git-tree-sha1 = "e5ee5b645d066c14df1f1fad57cc8e2965a72ab6" +repo-rev = "sd-tests" +repo-url = "https://github.com/JuliaPlots/GLMakie.jl.git" +uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" +version = "0.0.1+" + +[[GeometryTypes]] +deps = ["ColorTypes", "FixedPointNumbers", "IterTools", "LinearAlgebra", "StaticArrays", "Test"] +git-tree-sha1 = "709ad3a31bb045cbfd706159fbe8fae4d00e091c" +repo-rev = "sd-bb" +repo-url = "https://github.com/JuliaGeometry/GeometryTypes.jl.git" +uuid = "4d00f742-c7ba-57c2-abde-4428a4b178cb" +version = "0.7.1+" + +[[Graphics]] +deps = ["Colors", "Compat", "NaNMath"] +git-tree-sha1 = "e3ead4211073d4117a0d2ef7d1efc5c8092c8412" +uuid = "a2bd30eb-e257-5431-a919-1863eab51364" +version = "0.4.0" + +[[HTTPClient]] +deps = ["Compat", "LibCURL"] +git-tree-sha1 = "161d5776ae8e585ac0b8c20fb81f17ab755b3671" +uuid = "0862f596-cf2d-50af-8ef4-f2be67dfa83f" +version = "0.2.1" + +[[Homebrew]] +deps = ["BinDeps", "InteractiveUtils", "JSON", "Libdl", "Test", "Unicode"] +git-tree-sha1 = "5582ec74f735cf8d12e562a2e65c47f34063bd51" +uuid = "d9be37ee-ecc9-5288-90f1-b9ca67657a75" +version = "0.7.0" + +[[IdentityRanges]] +deps = ["OffsetArrays", "Test"] +git-tree-sha1 = "f5ca23a08397288924a7535cd898d8ccbcde5ba5" +uuid = "bbac6d45-d8f3-5730-bfe4-7a449cd117ca" +version = "0.2.0" + +[[ImageAxes]] +deps = ["AxisArrays", "Colors", "FixedPointNumbers", "ImageCore", "MappedArrays", "Reexport", "SimpleTraits", "Test"] +git-tree-sha1 = "5735ec90843acaa67a4624611921c686cdf4efbf" +uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" +version = "0.5.0" + +[[ImageCore]] +deps = ["ColorTypes", "Colors", "FFTW", "FixedPointNumbers", "Graphics", "MappedArrays", "OffsetArrays", "PaddedViews", "Random", "Statistics", "Test"] +git-tree-sha1 = "5e7b1f49c80541860e08a7ea91805a24c1641f19" +uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" +version = "0.7.3" + +[[ImageFiltering]] +deps = ["CatIndices", "ColorVectorSpace", "Colors", "ComputationalResources", "DataStructures", "FFTViews", "FFTW", "FixedPointNumbers", "ImageCore", "LinearAlgebra", "Logging", "MappedArrays", "OffsetArrays", "Random", "StaticArrays", "Statistics", "Test", "TiledIteration"] +git-tree-sha1 = "2d23d8f8c1def1e8d67d05e554baacc780d9313d" +uuid = "6a3955dd-da59-5b1f-98d4-e7296123deb5" +version = "0.5.1" + +[[ImageMagick]] +deps = ["BinaryProvider", "ColorTypes", "FileIO", "FixedPointNumbers", "ImageCore", "InteractiveUtils", "Libdl", "Pkg", "Random", "Test"] +git-tree-sha1 = "0e4cc77fb131061b3525a97fd7d483b253c3aaad" +uuid = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" +version = "0.7.1" + +[[ImageTransformations]] +deps = ["AxisAlgorithms", "ColorTypes", "ColorVectorSpace", "Colors", "CoordinateTransformations", "FixedPointNumbers", "IdentityRanges", "ImageCore", "Interpolations", "LinearAlgebra", "OffsetArrays", "StaticArrays", "Test"] +git-tree-sha1 = "18ae1c0a8df31549a9452ceac93751d4aa166071" +uuid = "02fcd773-0e25-5acc-982a-7f6622650795" +version = "0.7.1" + +[[IndirectArrays]] +deps = ["Compat", "Test"] +git-tree-sha1 = "b6e249be10a3381b2c72ac82f2d13d70067cb2bd" +uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" +version = "0.5.0" + +[[InteractiveUtils]] +deps = ["LinearAlgebra", "Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[Interpolations]] +deps = ["AxisAlgorithms", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "SharedArrays", "SparseArrays", "StaticArrays", "Test", "WoodburyMatrices"] +git-tree-sha1 = "3493536a64dae5a21c0cc8aecf680647f3e12313" +uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" +version = "0.11.0" + +[[IntervalSets]] +deps = ["Compat"] +git-tree-sha1 = "9dc556002f23740de13946e8c2e41798e09a9249" +uuid = "8197267c-284f-5f27-9208-e0e47529a953" +version = "0.3.1" + +[[IterTools]] +deps = ["SparseArrays", "Test"] +git-tree-sha1 = "79246285c43602384e6f1943b3554042a3712056" +uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +version = "1.1.1" + +[[IteratorInterfaceExtensions]] +deps = ["Test"] +git-tree-sha1 = "5484e5ede2a4137b9643f4d646e8e7b87b794415" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "0.1.1" + +[[JSON]] +deps = ["Dates", "Distributed", "Mmap", "Sockets", "Test", "Unicode"] +git-tree-sha1 = "1f7a25b53ec67f5e9422f1f551ee216503f4a0fa" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.20.0" + +[[LibCURL]] +deps = ["BinaryProvider", "Compat", "Libdl", "Printf"] +git-tree-sha1 = "6339c87cb76923a3cf947fcd213cbc364355c9c9" +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.4.1" + +[[LibExpat]] +deps = ["Compat"] +git-tree-sha1 = "fde352ec13479e2f90e57939da2440fb78c5e388" +uuid = "522f3ed2-3f36-55e3-b6df-e94fee9b0c07" +version = "0.5.0" + +[[LibGit2]] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[Libz]] +deps = ["BufferedStreams", "Random", "Test"] +git-tree-sha1 = "d405194ffc0293c3519d4f7251ce51baac9cc871" +uuid = "2ec943e9-cfe8-584d-b93d-64dcb6d567b7" +version = "1.0.0" + +[[LinearAlgebra]] +deps = ["Libdl"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[MacroTools]] +deps = ["Compat"] +git-tree-sha1 = "c443e1c8d58a4e9f61b708ad0a88286c7042145b" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.4.4" + +[[Makie]] +deps = ["AbstractPlotting", "AxisArrays", "Base64", "ColorBrewer", "ColorTypes", "ColorVectorSpace", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GLFW", "GLMakie", "GeometryTypes", "ImageAxes", "ImageCore", "ImageMagick", "ImageTransformations", "IndirectArrays", "IntervalSets", "IterTools", "LinearAlgebra", "ModernGL", "Observables", "Pkg", "PlotUtils", "Primes", "QuartzImageIO", "Showoff", "StaticArrays", "Statistics", "UnicodeFun"] +git-tree-sha1 = "a49ae5834b605a14447e04d57a07cbb80ebe8add" +repo-rev = "master" +repo-url = "https://github.com/JuliaPlots/Makie.jl.git" +uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" +version = "0.9.0+" + +[[MakieGallery]] +deps = ["AbstractPlotting", "BinaryProvider", "ColorTypes", "ColorVectorSpace", "Colors", "DataFrames", "Documenter", "FileIO", "FixedPointNumbers", "GDAL", "GeometryTypes", "ImageCore", "ImageFiltering", "ImageMagick", "ImageTransformations", "LinearAlgebra", "Makie", "Markdown", "MeshIO", "ModernGL", "Pkg", "QuartzImageIO", "RDatasets", "Random", "Statistics", "Test"] +git-tree-sha1 = "178252e975f92c3e11a4478577ec4a4faff4119d" +repo-rev = "master" +repo-url = "https://github.com/JuliaPlots/MakieGallery.jl.git" +uuid = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" +version = "0.0.1+" + +[[MappedArrays]] +deps = ["Test"] +git-tree-sha1 = "923441c5ac942b60bd3a842d5377d96646bcbf46" +uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" +version = "0.2.1" + +[[Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[MeshIO]] +deps = ["ColorTypes", "FileIO", "GeometryTypes", "Printf", "Test"] +git-tree-sha1 = "3e01e12c4c626578a9d47fac0d15c9fe8dad5139" +uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" +version = "0.3.1" + +[[Missings]] +deps = ["Dates", "InteractiveUtils", "SparseArrays", "Test"] +git-tree-sha1 = "adc26d2ee85a49c413464110d922cf21efc9d233" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "0.3.1" + +[[Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[Mocking]] +deps = ["Compat", "Dates"] +git-tree-sha1 = "4bf69aaf823b119b034e091e16b18311aa191663" +uuid = "78c3b35d-d492-501b-9361-3d52fe80e533" +version = "0.5.7" + +[[ModernGL]] +deps = ["Libdl"] +git-tree-sha1 = "f4f8fa8d04d3c1e7294f07fc37586c819466ad38" +uuid = "66fc600b-dfda-50eb-8b99-91cfa97b1301" +version = "1.0.0" + +[[NaNMath]] +deps = ["Compat"] +git-tree-sha1 = "ce3b85e484a5d4c71dd5316215069311135fa9f2" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "0.3.2" + +[[Nullables]] +deps = ["Compat"] +git-tree-sha1 = "ae1a63457e14554df2159b0b028f48536125092d" +uuid = "4d1e1d77-625e-5b40-9113-a560ec7a8ecd" +version = "0.0.8" + +[[Observables]] +deps = ["Test"] +git-tree-sha1 = "dc02cec22747d1d10d9f70d8a1c03432b5bfbcd0" +uuid = "510215fc-4207-5dde-b226-833fc4488ee2" +version = "0.2.3" + +[[OffsetArrays]] +deps = ["DelimitedFiles", "Test"] +git-tree-sha1 = "f446248f2dfbc13039a0b90994dd25b059b01eab" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "0.9.0" + +[[OrderedCollections]] +deps = ["Random", "Serialization", "Test"] +git-tree-sha1 = "85619a3f3e17bb4761fe1b1fd47f0e979f964d5b" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.0.2" + +[[Packing]] +deps = ["GeometryTypes", "Test"] +git-tree-sha1 = "bc7c284233cf0518933bf9977e3e8234efcc1c30" +uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" +version = "0.3.0" + +[[PaddedViews]] +deps = ["OffsetArrays", "Test"] +git-tree-sha1 = "7da3e7e1a58cffbf10177553ae95f17b92516912" +uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" +version = "0.4.2" + +[[Parameters]] +deps = ["Markdown", "OrderedCollections", "REPL", "Test"] +git-tree-sha1 = "eec0fe16344cc14aa2e6251874ab30d62aff4f7c" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.10.2" + +[[Parsers]] +deps = ["Dates", "Mmap", "Test", "WeakRefStrings"] +git-tree-sha1 = "949ca36d47010bee093254467166487c921d490b" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "0.2.14" + +[[Pkg]] +deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" + +[[PlotUtils]] +deps = ["Colors", "Dates", "Printf", "Random", "Reexport", "Test"] +git-tree-sha1 = "fd28f30a294a38ec847de95d8ac7ac916ccd7c06" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "0.5.5" + +[[Primes]] +deps = ["Test"] +git-tree-sha1 = "ff1a2323cb468ec5f201838fcbe3c232266b1f95" +uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" +version = "0.4.0" + +[[Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[Profile]] +deps = ["Printf"] +uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" + +[[QuartzImageIO]] +deps = ["ColorTypes", "ColorVectorSpace", "FileIO", "FixedPointNumbers", "ImageCore", "Libdl", "Random", "Test"] +git-tree-sha1 = "c747a56f223919b157e6cd9dc58d59c560586302" +uuid = "dca85d43-d64c-5e67-8c65-017450d5d020" +version = "0.5.0" + +[[RData]] +deps = ["CategoricalArrays", "CodecZlib", "DataFrames", "Dates", "FileIO", "Missings", "Test", "TimeZones"] +git-tree-sha1 = "8f3b644f4ebce291431846f5532272b0864c757c" +uuid = "df47a6cb-8c03-5eed-afd8-b6050d6c41da" +version = "0.5.0" + +[[RDatasets]] +deps = ["CSV", "CodecZlib", "DataFrames", "FileIO", "Printf", "RData", "Reexport", "Test"] +git-tree-sha1 = "4d93a52b94397bf0a9477d04e7a151a688672695" +uuid = "ce6b1742-4840-55fa-b093-852dadbb1d8b" +version = "0.6.1" + +[[REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[Random]] +deps = ["Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[RangeArrays]] +deps = ["Compat"] +git-tree-sha1 = "d925adfd5b01cb46fde89dc9548d167b3b136f4a" +uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" +version = "0.3.1" + +[[Ratios]] +deps = ["Compat"] +git-tree-sha1 = "fd159bead0a24e6270fd0573a340312bd4645cc2" +uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" +version = "0.3.0" + +[[Reexport]] +deps = ["Pkg"] +git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "0.2.0" + +[[Requires]] +deps = ["Test"] +git-tree-sha1 = "f6fbf4ba64d295e146e49e021207993b6b48c7d1" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "0.5.2" + +[[Rotations]] +deps = ["LinearAlgebra", "Random", "StaticArrays", "Statistics", "Test"] +git-tree-sha1 = "b629771d0de88979cbdbf72ceddc54de58fde149" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "0.9.1" + +[[SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" + +[[Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[Showoff]] +deps = ["Compat"] +git-tree-sha1 = "276b24f3ace98bec911be7ff2928d497dc759085" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "0.2.1" + +[[SignedDistanceFields]] +deps = ["Random", "Statistics", "Test"] +git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" +uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" +version = "0.4.0" + +[[SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools", "Test"] +git-tree-sha1 = "c0a542b8d5e369b179ccd296b2ca987f6da5da0a" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.8.0" + +[[Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[SortingAlgorithms]] +deps = ["DataStructures", "Random", "Test"] +git-tree-sha1 = "03f5898c9959f8115e30bc7226ada7d0df554ddd" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "0.3.1" + +[[SparseArrays]] +deps = ["LinearAlgebra", "Random"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[SpecialFunctions]] +deps = ["BinDeps", "BinaryProvider", "Libdl", "Test"] +git-tree-sha1 = "0b45dc2e45ed77f445617b99ff2adf0f5b0f23ea" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "0.7.2" + +[[StaticArrays]] +deps = ["InteractiveUtils", "LinearAlgebra", "Random", "Statistics", "Test"] +git-tree-sha1 = "97c4bf0f647488dd7ac01ea12be5885f88762938" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "0.10.0" + +[[Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[StatsBase]] +deps = ["DataStructures", "LinearAlgebra", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "Test"] +git-tree-sha1 = "2722397d88f8ffef551948f6c20e1d74a743298c" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.26.0" + +[[TableTraits]] +deps = ["IteratorInterfaceExtensions", "Test"] +git-tree-sha1 = "da062a2c31f16178f68190243c24140801720a43" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "0.4.0" + +[[Tables]] +deps = ["Requires", "Test"] +git-tree-sha1 = "c7fb447deab835fa70ce6717e78c68b0f466a42c" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "0.1.11" + +[[Test]] +deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[TiledIteration]] +deps = ["OffsetArrays", "Test"] +git-tree-sha1 = "58f6f07d3b54a363ec283a8f5fc9fb4ecebde656" +uuid = "06e1c1a7-607b-532d-9fad-de7d9aa2abac" +version = "0.2.3" + +[[TimeZones]] +deps = ["Compat", "EzXML", "Mocking", "Nullables"] +git-tree-sha1 = "4a4ab113913e19ad62b67e6c5c056509eac00c19" +uuid = "f269a46b-ccf7-5d73-abea-4c690281aa53" +version = "0.8.2" + +[[TranscodingStreams]] +deps = ["Pkg", "Random", "Test"] +git-tree-sha1 = "a34a2d588e2d2825602bf14a24216d5c8b0921ec" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.8.1" + +[[URIParser]] +deps = ["Test", "Unicode"] +git-tree-sha1 = "6ddf8244220dfda2f17539fa8c9de20d6c575b69" +uuid = "30578b45-9adc-5946-b283-645ec420af67" +version = "0.4.0" + +[[UUIDs]] +deps = ["Random"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[UnicodeFun]] +deps = ["Test"] +git-tree-sha1 = "63cbbd00217fc9aafedf055b60459c1ae7e01ecc" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.0" + +[[VersionParsing]] +deps = ["Compat"] +git-tree-sha1 = "c9d5aa108588b978bd859554660c8a5c4f2f7669" +uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" +version = "1.1.3" + +[[WeakRefStrings]] +deps = ["Missings", "Random", "Test"] +git-tree-sha1 = "1087e8be380f2c8b96434b02bb1150fc1c511135" +uuid = "ea10d353-3f73-51f8-a26c-33c1cb351aa5" +version = "0.5.3" + +[[WinRPM]] +deps = ["BinDeps", "Compat", "HTTPClient", "LibExpat", "Libdl", "Libz", "URIParser"] +git-tree-sha1 = "2a889d320f3b77d17c037f295859fe570133cfbf" +uuid = "c17dfb99-b4f7-5aad-8812-456da1ad7187" +version = "0.4.2" + +[[WoodburyMatrices]] +deps = ["LinearAlgebra", "Random", "SparseArrays", "Test"] +git-tree-sha1 = "21772c33b447757ec7d3e61fcdfb9ea5c47eedcf" +uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" +version = "0.4.1" diff --git a/Project.toml b/Project.toml new file mode 100644 index 00000000000..b2294898ca5 --- /dev/null +++ b/Project.toml @@ -0,0 +1,23 @@ +name = "CairoMakie" +uuid = "f1797859-2bec-5491-832b-e19d79114491" +author = ["Simon Danisch "] +version = "0.0.0" + +[deps] +AbstractPlotting = "537997a7-5e4e-5d89-9595-2241ea00577e" +Cairo = "159f3aea-2a34-519c-b102-8c37f9878175" +Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" +DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" +GeometryTypes = "4d00f742-c7ba-57c2-abde-4428a4b178cb" +ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534" +ImageFiltering = "6a3955dd-da59-5b1f-98d4-e7296123deb5" +ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" +ImageTransformations = "02fcd773-0e25-5acc-982a-7f6622650795" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" +MakieGallery = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" +MeshIO = "7269a6da-0436-5bbc-96c2-40638cbb6118" +RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" +StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" diff --git a/cleanmani.jl b/cleanmani.jl new file mode 100644 index 00000000000..841439a8c7e --- /dev/null +++ b/cleanmani.jl @@ -0,0 +1,40 @@ +using Pkg +using Pkg.TOML +cd(@__DIR__) +mani = TOML.parsefile("Manifest.toml") + +deps = mani["CairoMakie"][1]["deps"] + +function get_all_deps(name, result = Dict{String, Any}()) + pkg = mani[name][1] + println(name) + result[name] = [pkg] + if haskey(pkg, "deps") + deps = pkg["deps"] + for dep in deps + if !haskey(result, dep) + get_all_deps(dep, result) + end + end + end + result +end +deps = get_all_deps("CairoMakie") +@which TOML.parsefile("") +parser = TOML.Parser(IOBuffer()) +@which TOML.parse(parser) + +function print_toml(path, dict) + open(path, "w") do io + for name in keys(dict) + println(io, "[[$name]]") + pkg = dict[name][1] + for (k, v) in pkg + println(io, k, " = ", repr(v)) + end + println(io) + println(io) + end + end +end +print_toml("Manifest.toml", deps) diff --git a/src/CairoMakie.jl b/src/CairoMakie.jl index 6db2578a1b3..6cd0b2fa483 100644 --- a/src/CairoMakie.jl +++ b/src/CairoMakie.jl @@ -1,18 +1,38 @@ module CairoMakie -import Makie -using Makie: Scene, Lines, Text, Image, Heatmap, Scatter, @key_str, broadcast_foreach -using Makie: convert_attribute, @extractvalue, LineSegments, to_ndim, NativeFont -using Makie: @info, @get_attribute -using Colors, GeometryTypes using AbstractPlotting +using AbstractPlotting: Scene, Lines, Text, Image, Heatmap, Scatter, @key_str, broadcast_foreach +using AbstractPlotting: convert_attribute, @extractvalue, LineSegments, to_ndim, NativeFont +using AbstractPlotting: @info, @get_attribute, Combined +using Colors, GeometryTypes using AbstractPlotting: to_value, to_colormap, extrema_nan -using Cairo +using Cairo, FileIO +using LinearAlgebra +@enum RenderType SVG PNG struct CairoBackend <: AbstractPlotting.AbstractBackend + typ::RenderType + path::String +end + +function to_mime(x::RenderType) + x == SVG && return MIME"image/svg+xml"() + return MIME"image/png"() end +to_mime(x::CairoBackend) = to_mime(x.typ) +function CairoBackend(path::String) + ext = splitext(path)[2] + typ = if ext == ".png" + PNG + elseif ext == ".svg" + SVG + else + error("Unsupported extension: $ext") + end + CairoBackend(typ, path) +end struct CairoScreen{S} scene::Scene @@ -25,16 +45,13 @@ Base.insert!(screen::CairoScreen, scene::Scene, plot) = nothing # Default to Gtk Window+Canvas as backing device function CairoScreen(scene::Scene) - w, h = round.(Int, scene.camera.resolution[]) + w, h = size(scene) surf = CairoRGBSurface(w, h) ctx = CairoContext(surf) - win = GtkWindow() - canv = GtkCanvas(w, h) - push!(win, canv) - CairoScreen(scene, surf, ctx, CairoGtkPane(win, canv)) + CairoScreen(scene, surf, ctx, nothing) end -function CairoScreen(scene::Scene, path::Union{String, IO}; mode=:svg) +function CairoScreen(scene::Scene, path::Union{String, IO}; mode = :svg) w, h = round.(Int, scene.camera.resolution[]) # TODO: Add other surface types (PDF, etc.) if mode == :svg @@ -55,10 +72,10 @@ function project_position(scene, point, model) p = Vec2f0(p[1], -p[2]) ((((p + 1f0) / 2f0) .* (res - 1f0)) + 1f0) end -project_scale(scene::Scene, s::Number) = project_scale(scene, Vec2f0(s)) -function project_scale(scene::Scene, s) +project_scale(scene::Scene, s::Number, model = Mat4f0(I)) = project_scale(scene, Vec2f0(s), model) +function project_scale(scene::Scene, s, model = Mat4f0(I)) p4d = to_ndim(Vec4f0, s, 0f0) - p = (scene.camera.projectionview[] * p4d)[Vec(1, 2)] ./ 2f0 + p = (scene.camera.projectionview[] * model * p4d)[Vec(1, 2)] ./ 2f0 p .* scene.camera.resolution[] end @@ -96,31 +113,102 @@ function draw_segment(scene, ctx, point::Point, model, c, linewidth, linestyle, end end -function draw_segment(scene, ctx, segment::Tuple{<: Point, <: Point}, model, connect, do_stroke, c, linewidth, linestyle, primitive) - A = project_position(scene, segment[1], model) - B = project_position(scene, segment[2], model) - function stroke() - Cairo.set_line_width(ctx, Float64(linewidth)) - Cairo.set_source_rgba(ctx, red(c), green(c), blue(c), alpha(c)) - if linestyle != nothing - #set_dash(ctx, linestyle, 0.0) +function draw_segment(scene, ctx, point::Tuple{<: Point, <: Point}, model, c, linewidth, linestyle, primitive, idx, N) + draw_segment(scene, ctx, point[1], model, c, linewidth, linestyle, primitive, 1 + (idx - 1) * 2, N) + draw_segment(scene, ctx, point[2], model, c, linewidth, linestyle, primitive, (idx - 1) * 2, N) +end + +function draw_atomic(::Scene, ::CairoScreen, x) + @warn "$(typeof(x)) is not supported by cairo right now" +end + +struct FaceIterator{Iteration, T, F, ET} <: AbstractVector{ET} + data::T + faces::F +end + +function (::Type{FaceIterator{Typ}})(data::T, faces::F) where {Typ, T, F} + FaceIterator{Typ, T, F}(data, faces) +end +function (::Type{FaceIterator{Typ, T, F}})(data::AbstractVector, faces::F) where {Typ, F, T} + FaceIterator{Typ, T, F, NTuple{3, eltype(data)}}(data, faces) +end +function (::Type{FaceIterator{Typ, T, F}})(data::T, faces::F) where {Typ, T, F} + FaceIterator{Typ, T, F, NTuple{3, T}}(data, faces) +end +function FaceIterator(data::AbstractVector, faces) + if length(data) == length(faces) + FaceIterator{:PerFace}(data, faces) + else + FaceIterator{:PerVert}(data, faces) + end +end + + +Base.size(fi::FaceIterator) = size(fi.faces) +Base.getindex(fi::FaceIterator{:PerFace}, i::Integer) = fi.data[i] +Base.getindex(fi::FaceIterator{:PerVert}, i::Integer) = fi.data[fi.faces[i]] +Base.getindex(fi::FaceIterator{:Const}, i::Integer) = ntuple(i-> fi.data, 3) + +function per_face_colors(color, colormap, colorrange, vertices, faces) + if color isa Colorant + return FaceIterator{:Const}(color, faces) + elseif color isa AbstractVector + if color isa AbstractVector{<: Colorant} + return FaceIterator(color, faces) + elseif color isa AbstractVector{<: Number} + cvec = AbstractPlotting.interpolated_getindex.((colormap,), color, (colorrange,)) + return FaceIterator(cvec, faces) end - Cairo.stroke(ctx) end - Cairo.move_to(ctx, A[1], A[2]) - Cairo.line_to(ctx, B[1], B[2]) - stroke() + error("Unsupported Color type: $(typeof(color))") +end + +function color2tuple3(c) + (red(c), green(c), blue(c)) +end + +function draw_atomic(scene::Scene, screen::CairoScreen, primitive::Mesh) + @get_attribute(primitive, (color,)) + + colormap = get(primitive, :colormap, nothing) |> to_value |> to_colormap + colorrange = get(primitive, :colorrange, nothing) |> to_value + + ctx = screen.context + model = primitive.model[] + mesh = primitive[1][] + vs = vertices(mesh); fs = faces(mesh); + pattern = Cairo.CairoPatternMesh() + cols = per_face_colors(color, colormap, colorrange, vs, fs) + for (f, (c1, c2, c3)) in zip(fs, cols) + t1, t2, t3 = project_position.(scene, vs[f], (model,)) #triangle points + Cairo.mesh_pattern_begin_patch(pattern) + + Cairo.mesh_pattern_move_to(pattern, t1...) + Cairo.mesh_pattern_line_to(pattern, t2...) + Cairo.mesh_pattern_line_to(pattern, t3...) + + Cairo.mesh_pattern_set_corner_color_rgb(pattern, 0, color2tuple3(c1)...) + Cairo.mesh_pattern_set_corner_color_rgb(pattern, 1, color2tuple3(c2)...) + Cairo.mesh_pattern_set_corner_color_rgb(pattern, 2, color2tuple3(c3)...) + + Cairo.mesh_pattern_end_patch(pattern) + + Cairo.set_source(ctx, pattern) + Cairo.close_path(ctx) + Cairo.paint(ctx) + end + nothing end -function cairo_draw(screen::CairoScreen, primitive::Union{Lines, LineSegments}) - scene = screen.scene +function draw_atomic(scene::Scene, screen::CairoScreen, primitive::Union{Lines, LineSegments}) fields = @get_attribute(primitive, (color, linewidth, linestyle)) ctx = screen.context model = primitive[:model][] positions = primitive[1][] isempty(positions) && return N = length(positions) - broadcast_foreach(1:N, positions, fields...) do i, point, c, linewidth, linestyle + broadcast_foreach(1:N, positions, color, linewidth) do i, point, c, linewidth draw_segment(scene, ctx, point, model, c, linewidth, linestyle, primitive, i, N) end nothing @@ -133,23 +221,22 @@ function to_cairo_image(img::AbstractMatrix{<: AbstractFloat}, attributes) end function to_cairo_image(img::Matrix{UInt32}, attributes) - CairoARGBSurface(img) + CairoARGBSurface([img[j, i] for i in size(img, 2):-1:1, j in 1:size(img, 1)]) end to_uint32_color(c) = reinterpret(UInt32, convert(ARGB32, c)) function to_cairo_image(img, attributes) to_cairo_image(to_uint32_color.(img), attributes) end -function cairo_draw(screen::CairoScreen, primitive::Image) - draw_image(screen, primitive) +function draw_atomic(scene::Scene, screen::CairoScreen, primitive::Image) + draw_image(scene, screen, primitive) end -function cairo_draw(screen::CairoScreen, primitive::Union{Heatmap, Image}) - draw_image(screen, primitive) +function draw_atomic(scene::Scene, screen::CairoScreen, primitive::Union{Heatmap, Image}) + draw_image(scene, screen, primitive) end -function draw_image(screen, attributes) - scene = screen.scene +function draw_image(scene, screen, attributes) ctx = screen.context image = attributes[3][] x, y = attributes[1][], attributes[2][] @@ -169,38 +256,63 @@ function draw_image(screen, attributes) Cairo.fill(ctx) Cairo.restore(ctx) end +_extract_color(cmap, range, c) = to_color(c) +_extract_color(cmap, range, c::RGBf0) = RGBAf0(c, 1.0) +_extract_color(cmap, range, c::RGBAf0) = c +function _extract_color(cmap, range, c::Number) + AbstractPlotting.interpolated_getindex(cmap, c, range) +end +function extract_color(cmap, range, c) + c = _extract_color(cmap, range, c) + red(c), green(c), blue(c), alpha(c) +end +function draw_marker(ctx, marker, pos, scale, color, strokecolor, strokewidth) + Cairo.set_source_rgba(ctx, color...) + Cairo.arc(ctx, pos[1], pos[2], scale[1] / 2, 0, 2*pi) + Cairo.fill(ctx) + sc = to_color(strokecolor) + Cairo.set_source_rgba(ctx, red(sc), green(sc), blue(sc), alpha(sc)) + Cairo.set_line_width(ctx, Float64(strokewidth)) + Cairo.arc(ctx, pos[1], pos[2], scale[1], 0, 2*pi) + Cairo.stroke(ctx) +end + +function draw_marker(ctx, marker::Union{Rect, Type{<: Rect}}, pos, scale, color, strokecolor, strokewidth) + Cairo.set_source_rgba(ctx, color...) + Cairo.rectangle(ctx, pos..., scale[1], -scale[2]) + Cairo.fill(ctx); + if strokewidth > 0.0 + sc = to_color(strokecolor) + Cairo.set_source_rgba(ctx, red(sc), green(sc), blue(sc), alpha(sc)) + Cairo.set_line_width(ctx, Float64(strokewidth)) + Cairo.stroke(ctx) + end +end -function cairo_draw(screen::CairoScreen, primitive::Scatter) - scene = screen.scene - fields = @get_attribute(primitive, (color, markersize, strokecolor, strokewidth, marker)) +function draw_atomic(scene::Scene, screen::CairoScreen, primitive::Scatter) + fields = @get_attribute(primitive, (color, markersize, strokecolor, strokewidth, marker, marker_offset)) + cmap = get(primitive, :colormap, nothing) |> to_value |> to_colormap + crange = get(primitive, :colorrange, nothing) |> to_value ctx = screen.context model = primitive[:model][] - broadcast_foreach(primitive[1][], fields...) do point, c, markersize, strokecolor, strokewidth, marker + positions = primitive[1][] + isempty(positions) && return + broadcast_foreach(primitive[1][], fields...) do point, c, markersize, strokecolor, strokewidth, marker, mo # TODO: Implement marker # TODO: Accept :radius field or similar? - scale = project_scale(scene, markersize) + scale = project_scale(scene, markersize, model) pos = project_position(scene, point, model) - Cairo.set_source_rgba(ctx, red(c), green(c), blue(c), alpha(c)) - Cairo.arc(ctx, pos[1], pos[2], scale[1] / 2, 0, 2*pi) - Cairo.fill(ctx) - sc = to_color(strokecolor) - Cairo.set_source_rgba(ctx, red(sc), green(sc), blue(sc), alpha(sc)) - Cairo.set_line_width(ctx, Float64(strokewidth)) - #if linestyle != nothing - # set_dash(ctx, convert_attribute(linestyle, key"linestyle"()), 0.0) - #end - Cairo.arc(ctx, pos[1], pos[2], scale[1], 0, 2*pi) - Cairo.stroke(ctx) + mo = project_scale(scene, mo) + pos += mo + draw_marker(ctx, marker, pos, scale, extract_color(cmap, crange, c), strokecolor, strokewidth) end nothing end -function cairo_draw(screen::CairoScreen, primitive::Makie.Combined) - foreach(x-> cairo_draw(screen, x), primitive.plots) -end + scale_matrix(x, y) = Cairo.CairoMatrix(x, 0.0, 0.0, y, 0.0, 0.0) function rot_scale_matrix(x, y, q) @@ -240,8 +352,7 @@ function fontscale(scene, c, font, s) project_scale(scene, s) end -function cairo_draw(screen::CairoScreen, primitive::Text) - scene = screen.scene +function draw_atomic(scene::Scene, screen::CairoScreen, primitive::Text) ctx = screen.context @get_attribute(primitive, (textsize, color, font, align, rotation, model)) txt = to_value(primitive[1]) @@ -276,86 +387,102 @@ function cairo_draw(screen::CairoScreen, primitive::Text) nothing end -# TODO: heatmap! +function cairo_clear(screen::CairoScreen) + ctx = screen.context + w, h = Cairo.width(ctx), Cairo.height(ctx) + Cairo.rectangle(ctx, 0, 0, w, h) + # FIXME: Cairo.set_source_rgb(ctx, screen.scene.theme[:color]...) + Cairo.fill(ctx) +end + -#TODO those are from Visualize.jl and need to get ported to the above +function draw_background(screen::CairoScreen, scene::Scene) + cr = screen.context + Cairo.save(cr) + if theme(scene, :clear)[] + bg = to_color(theme(scene, :backgroundcolor)[]) + Cairo.set_source_rgba(cr, red(bg), green(bg), blue(bg), alpha(bg)); # light gray + r = pixelarea(scene)[] + Cairo.rectangle(cr, minimum(r)..., widths(r)...) # background + fill(cr) + end + Cairo.restore(cr) + foreach(child_scene-> draw_background(screen, child_scene), scene.children) +end -#= -function cairo_draw(screen::CairoScreen, primitive::Text) - set_font_face(cr, text.font) - for (c, sprite) in zip(text.data, text.text) - vert = Visualize.vert_particles(sprite, canvas, uniforms) - rect = vert.rect - pos = rect[Vec(1, 2)] - scale = rect[Vec(3, 4)] - pos = clip2pixel_space(Vec4f0(pos[1], pos[2], 0, 1), canvas.resolution) - move_to(cd, pos...) - set_source_rgba(cr, vert.color...) - set_font_size(cr, vert.scale[1]) - show_text(cr, string(c)) +function draw_plot(scene::Scene, screen::CairoScreen, primitive::Combined) + isempty(primitive.plots) && return draw_atomic(scene, screen, primitive) + for plot in primitive.plots + draw_plot(scene, screen, plot) end end -function draw_window!(scene::Scene, cr::CairoContext) - Cairo.save(cr) - Cairo.set_source_rgba(cr, scene.backgroundcolor[]...) # light gray - Cairo.rectangle(cr, 0.0, 0.0, get(window, Visualize.Resolution)...) # background - Cairo.fill(cr) - Cairo.restore(cr) - Cairo.reset_clip(cr) - for (prim, (drawable, args)) in window[Visualize.Renderlist] - Cairo.save(cr) - drawable(args...) - Cairo.restore(cr) +function draw_plot(screen::CairoScreen, scene::Scene) + Cairo.save(screen.context) + Cairo.translate(screen.context, minimum(pixelarea(scene)[])...) + for elem in scene.plots + draw_plot(scene, screen, elem) + end + Cairo.restore(screen.context) + for child in scene.children + draw_plot(screen, child) end return end -=# -function cairo_clear(screen::CairoScreen) - ctx = screen.context - w, h = Cairo.width(ctx), Cairo.height(ctx) - Cairo.rectangle(ctx, 0, 0, w, h) - # FIXME: Cairo.set_source_rgb(ctx, screen.scene.theme[:color]...) - Cairo.fill(ctx) + +function cairo_draw(screen::CairoScreen, scene::Scene) + AbstractPlotting.update!(scene) + draw_background(screen, scene) + draw_plot(screen, scene) + return end -function cairo_finish(screen::CairoScreen{CairoRGBSurface}) - showall(screen.pane.window) - draw(screen.pane.canvas) do canvas - ctx = getgc(canvas) - w, h = Cairo.width(ctx), Cairo.height(ctx) - # TODO: Maybe just use set_source(ctx, screen.surface)? - Cairo.image(ctx, screen.surface, 0, 0, w, h) +function AbstractPlotting.backend_display(x::CairoBackend, scene::Scene) + open(x.path, "w") do io + AbstractPlotting.backend_show(x, io, to_mime(x), scene) end + (x, scene) end -cairo_finish(screen::CairoScreen) = finish(screen.surface) -function AbstractPlotting.backend_display(::CairoBackend, scene::Scene) - AbstractPlotting.update!(scene) - screen = CairoScreen(scene, joinpath(homedir(), "Desktop", "cairo.svg")) - cairo_draw(screen, scene) +function AbstractPlotting.colorbuffer(tup::Tuple{<: CairoBackend, Scene}) + screen, scene = tup + # TODO this is super slow, we need to design the colorbuffer + # api to be able to reuse a RGB surface + AbstractPlotting.backend_display(screen, scene) + FileIO.load(screen.path) end +AbstractPlotting.backend_showable(x::CairoBackend, m::MIME"image/svg+xml", scene::SceneLike) = x.typ == SVG +AbstractPlotting.backend_showable(x::CairoBackend, m::MIME"image/png", scene::SceneLike) = x.typ == PNG -AbstractPlotting.backend_showable(::CairoBackend, m::MIME"image/svg", scene::SceneLike) = true -function AbstractPlotting.backend_show(::CairoBackend, io::IO, ::MIME"image/svg+xml", scene::Scene) - AbstractPlotting.update!(scene) +function AbstractPlotting.backend_show(x::CairoBackend, io::IO, ::MIME"image/svg+xml", scene::Scene) screen = CairoScreen(scene, io) cairo_draw(screen, scene) + Cairo.finish(screen.surface) + (x, scene) end +function AbstractPlotting.backend_show(x::CairoBackend, io::IO, m::MIME"image/png", scene::Scene) + screen = CairoScreen(scene, io) + cairo_draw(screen, scene) + write_to_png(screen.surface, io) + (x, scene) +end -function cairo_draw(screen::CairoScreen, scene::Scene) - for elem in scene.plots - cairo_draw(screen, elem) +function __init__() + dir = mktempdir() + temp_file = joinpath(dir, "cairo.svg") + AbstractPlotting.register_backend!(CairoBackend(temp_file)) + atexit() do + rm(dir, force = true, recursive = true) end - foreach(child_scene-> cairo_draw(screen, child_scene), scene.children) - cairo_finish(screen) - return end -function __init__() - AbstractPlotting.register_backend!(CairoBackend()) + +function activate!(inline = false) + AbstractPlotting.current_backend[] = CairoBackend() + AbstractPlotting.use_display[] = !inline + return end end diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 00000000000..95807589828 --- /dev/null +++ b/test/.gitignore @@ -0,0 +1,2 @@ +test_recordings +tested_different diff --git a/test/install_ffmpeg.sh b/test/install_ffmpeg.sh new file mode 100644 index 00000000000..07bedafed64 --- /dev/null +++ b/test/install_ffmpeg.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +add-apt-repository -y ppa:mc3man/trusty-media +apt-get -qq update +apt-get install -y ffmpeg diff --git a/test/runtests.jl b/test/runtests.jl index 07e21ab61d9..484185a0253 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1 +1,27 @@ -using CairoMakie, Makie +using ImageMagick +using CairoMakie, AbstractPlotting, MakieGallery + +tmp = joinpath(@__DIR__, "test.png") +AbstractPlotting.current_backend[] = CairoMakie.CairoBackend(tmp) +database = MakieGallery.load_database() +filter!(database) do entry + "2d" in entry.tags && + "Text rotation" != entry.title && + "fem polygon 2d" != lowercase(entry.title) && + "Hbox" != entry.title && + !("heatmap" in entry.tags) && # why though, they worked -.- + !("image" in entry.tags) +end + +ref_path = MakieGallery.download_reference(v"0.0.9") + +tested_diff_path = joinpath(@__DIR__, "tested_different") +test_record_path = joinpath(@__DIR__, "test_recordings") +rm(tested_diff_path, force = true, recursive = true) +mkpath(tested_diff_path) +rm(test_record_path, force = true, recursive = true) +mkpath(test_record_path) + +MakieGallery.record_examples(test_record_path) +MakieGallery.run_comparison(test_record_path, ref_path, tested_diff_path) +rm(tmp, force = true) From 3ad155bd19d1359b5e970fcb824da5fa2d4beadc Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Sun, 2 Dec 2018 16:18:49 +0100 Subject: [PATCH 0021/1328] move bb functions to GeometryTypes --- src/GLAbstraction/GLUtils.jl | 2 +- src/GLVisualize/GLVisualize.jl | 2 -- src/GLVisualize/boundingbox.jl | 58 ---------------------------------- 3 files changed, 1 insertion(+), 61 deletions(-) delete mode 100644 src/GLVisualize/boundingbox.jl diff --git a/src/GLAbstraction/GLUtils.jl b/src/GLAbstraction/GLUtils.jl index 2cdf10a68b5..f8e5e663f1a 100644 --- a/src/GLAbstraction/GLUtils.jl +++ b/src/GLAbstraction/GLUtils.jl @@ -210,7 +210,7 @@ end export NativeMesh NativeMesh(m::T) where {T <: HomogenousMesh} = NativeMesh{T}(m) - +(B::Type{AABB{T}})(a::NativeMesh) where {T} = B(gpu_data(a.data[:vertices])) function (MT::Type{NativeMesh{T}})(m::T) where T <: HomogenousMesh result = Dict{Symbol, Any}() diff --git a/src/GLVisualize/GLVisualize.jl b/src/GLVisualize/GLVisualize.jl index 59c2393b3b0..a4ea9a453c9 100644 --- a/src/GLVisualize/GLVisualize.jl +++ b/src/GLVisualize/GLVisualize.jl @@ -45,8 +45,6 @@ using ..GLMakie: assetpath, loadasset include("types.jl") export CIRCLE, RECTANGLE, ROUNDED_RECTANGLE, DISTANCEFIELD, TRIANGLE -include("boundingbox.jl") - include("visualize_interface.jl") export visualize # Visualize an object export visualize_default # get the default parameter for a visualization diff --git a/src/GLVisualize/boundingbox.jl b/src/GLVisualize/boundingbox.jl deleted file mode 100644 index c51f6003e9a..00000000000 --- a/src/GLVisualize/boundingbox.jl +++ /dev/null @@ -1,58 +0,0 @@ -AbsoluteRectangle(mini::Vec{N,T}, maxi::Vec{N,T}) where {N,T} = HyperRectangle{N,T}(mini, maxi-mini) - -AABB(a) = AABB{Float32}(a) -function (B::Type{AABB{T}})(a::Pyramid) where T - w,h = a.width/T(2), a.length - m = Vec{3,T}(a.middle) - B(m-Vec{3,T}(w,w,0), m+Vec{3,T}(w, w, h)) -end -(B::Type{AABB{T}})(a::Cube) where {T} = B(origin(a), widths(a)) -(B::Type{AABB{T}})(a::AbstractMesh) where {T} = B(vertices(a)) -(B::Type{AABB{T}})(a::NativeMesh) where {T} = B(gpu_data(a.data[:vertices])) - - -function (B::Type{AABB{T}})( - positions, scale, rotation, - primitive::AABB{T} - ) where T - - ti = TransformationIterator(positions, scale, rotation) - B(ti, primitive) -end -function (B::Type{AABB{T}})(instances::Instances) where T - ti = TransformationIterator(instances) - B(ti, B(instances.primitive)) -end - -function transform(translation, scale, rotation, points) - _max = Vec3f0(typemin(Float32)) - _min = Vec3f0(typemax(Float32)) - for p in points - x = scale.*Vec3f0(p) - rv = rotation*Vec4f0(x[1], x[2], x[3], 1f0) - x = Vec3f0(rv[1], rv[2], rv[3]) - x = Vec3f0(translation)+x - _min = min.(_min, x) - _max = max.(_max, x) - end - AABB{Float32}(_min, _max-_min) -end - -function (B::Type{AABB{T}})( - ti::TransformationIterator, primitive::AABB{T} - ) where T - v_state = iterate(ti) - v_state === nothing && return primitive - - tsr, state = v_state - points = decompose(Point3f0, primitive)::Vector{Point3f0} - bb = transform(tsr[1], tsr[2], tsr[3], points) - v_state = iterate(ti, state) - while v_state !== nothing - tsr, state = v_state - translatet_bb = transform(tsr[1], tsr[2], tsr[3], points) - bb = union(bb, translatet_bb) - v_state = iterate(ti, state) - end - bb -end From 34af81b4968696296f35c582a3ce050a4671fcb4 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Sun, 2 Dec 2018 16:18:57 +0100 Subject: [PATCH 0022/1328] use toml --- Project.toml | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 Project.toml diff --git a/Project.toml b/Project.toml new file mode 100644 index 00000000000..2d871da7015 --- /dev/null +++ b/Project.toml @@ -0,0 +1,38 @@ +name = "GLMakie" +uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" + +[deps] +AbstractPlotting = "537997a7-5e4e-5d89-9595-2241ea00577e" +AxisArrays = "39de3d68-74b9-583c-8d2d-e117c070f3a9" +ColorBrewer = "a2cac450-b92f-5266-8821-25eda20663c8" +ColorTypes = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +ColorVectorSpace = "c3611d14-8923-5661-9e6a-0046d554d3a4" +Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" +Contour = "d38c429a-6771-53c6-b99e-75d170b6e991" +FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +FixedPointNumbers = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +FreeType = "b38be410-82b0-50bf-ab77-7b57e271db43" +FreeTypeAbstraction = "663a7486-cb36-511b-a19d-713bb74d65c9" +GLFW = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" +GeometryTypes = "4d00f742-c7ba-57c2-abde-4428a4b178cb" +ImageAxes = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" +ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534" +ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" +ImageTransformations = "02fcd773-0e25-5acc-982a-7f6622650795" +IndirectArrays = "9b13fd28-a010-5f03-acff-a1bbcff69959" +IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" +IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a" +ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" +Observables = "510215fc-4207-5dde-b226-833fc4488ee2" +Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +PlotUtils = "995b91a9-d308-5afd-9ec6-746e21dbc043" +Primes = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" +Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" +QuartzImageIO = "dca85d43-d64c-5e67-8c65-017450d5d020" +Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +Showoff = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" +UnicodeFun = "1cfade01-22cf-5700-b092-accc4b62d6e1" +MakieGallery = "62e31da0-2f4f-5d53-819c-a7cea9df6aaa" From 0e3c4c5a4709f31e90d193f74a53ebff1d4971dd Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Sun, 2 Dec 2018 16:51:03 +0100 Subject: [PATCH 0023/1328] use manifest --- Manifest.toml | 678 ++++++++++++++++++++++++++++++++++++++++++++++++++ Project.toml | 3 +- 2 files changed, 680 insertions(+), 1 deletion(-) create mode 100644 Manifest.toml diff --git a/Manifest.toml b/Manifest.toml new file mode 100644 index 00000000000..c70360a479c --- /dev/null +++ b/Manifest.toml @@ -0,0 +1,678 @@ +[[AbstractFFTs]] +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "8d59c3b1463b5e0ad05a3698167f85fac90e184d" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "0.3.2" + +[[AbstractPlotting]] +deps = ["ColorBrewer", "ColorTypes", "Colors", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "Test", "UnicodeFun"] +git-tree-sha1 = "0e969852e9c20f24ad6ef705faa8db32f0990238" +repo-rev = "master" +repo-url = "https://github.com/JuliaPlots/AbstractPlotting.jl.git" +uuid = "537997a7-5e4e-5d89-9595-2241ea00577e" +version = "0.9.0+" + +[[AxisAlgorithms]] +deps = ["Compat", "WoodburyMatrices"] +git-tree-sha1 = "99dabbe853e4f641ab21a676131f2cf9fb29937e" +uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" +version = "0.3.0" + +[[AxisArrays]] +deps = ["Compat", "Dates", "IntervalSets", "IterTools", "Random", "RangeArrays", "Test"] +git-tree-sha1 = "2e2536e9e6f27c4f8d09d8442b61a7ae0b910c28" +uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" +version = "0.3.0" + +[[Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[BinDeps]] +deps = ["Compat", "Libdl", "SHA", "URIParser"] +git-tree-sha1 = "12093ca6cdd0ee547c39b1870e0c9c3f154d9ca9" +uuid = "9e28174c-4ba2-5203-b857-d8d62c4213ee" +version = "0.8.10" + +[[BinaryProvider]] +deps = ["Libdl", "Pkg", "SHA", "Test"] +git-tree-sha1 = "055eb2690182ebc31087859c3dd8598371d3ef9e" +uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" +version = "0.5.3" + +[[CMake]] +deps = ["BinDeps", "Libdl", "Test"] +git-tree-sha1 = "74853a75c26a4a73ac391ee26ee29ebeb5583d9f" +uuid = "631607c0-34d2-5d66-819e-eb0f9aa2061a" +version = "1.1.0" + +[[CMakeWrapper]] +deps = ["BinDeps", "CMake", "Libdl", "Parameters", "Test"] +git-tree-sha1 = "2b43d451639984e3571951cc687b8509b0a86c6d" +uuid = "d5fb7624-851a-54ee-a528-d3f3bac0b4a0" +version = "0.2.2" + +[[CSV]] +deps = ["CategoricalArrays", "DataFrames", "DataStreams", "Dates", "Mmap", "Parsers", "Profile", "Random", "Tables", "Test", "Unicode", "WeakRefStrings"] +git-tree-sha1 = "b92c6f626a044cc9619156d54994b94084d40abe" +uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" +version = "0.4.3" + +[[CatIndices]] +deps = ["CustomUnitRanges", "OffsetArrays", "Test"] +git-tree-sha1 = "254cf73ea369d2e39bfd6c5eb27a2296cfaed68c" +uuid = "aafaddc9-749c-510e-ac4f-586e18779b91" +version = "0.2.0" + +[[CategoricalArrays]] +deps = ["Compat", "Future", "Missings", "Printf", "Reexport", "Requires"] +git-tree-sha1 = "11419d157ab75a54a8af63315e7a279a593971bc" +uuid = "324d7699-5711-5eae-9e2f-1d82baa6b597" +version = "0.5.1" + +[[CodecZlib]] +deps = ["BinaryProvider", "Libdl", "Test", "TranscodingStreams"] +git-tree-sha1 = "e3df104c84dfc108f0ca203fd7f5bbdc98641ae9" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.5.1" + +[[ColorBrewer]] +deps = ["Colors", "JSON", "Test"] +git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" +uuid = "a2cac450-b92f-5266-8821-25eda20663c8" +version = "0.4.0" + +[[ColorTypes]] +deps = ["FixedPointNumbers", "Random", "Test"] +git-tree-sha1 = "f73b0e10f2a5756de7019818a41654686da06b09" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.7.5" + +[[ColorVectorSpace]] +deps = ["ColorTypes", "Colors", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "StatsBase", "Test"] +git-tree-sha1 = "a890f08e61b40e9843d7177206da61229a3603c8" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.6.2" + +[[Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "InteractiveUtils", "Printf", "Reexport", "Test"] +git-tree-sha1 = "9f0a0210450acb91c730b730a994f8eef1d3d543" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.9.5" + +[[Compat]] +deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] +git-tree-sha1 = "ec61a16eed883ad0cfa002d7489b3ce6d039bb9a" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "1.4.0" + +[[ComputationalResources]] +deps = ["Test"] +git-tree-sha1 = "89e7e7ed20af73d9f78877d2b8d1194e7b6ff13d" +uuid = "ed09eef8-17a6-5b46-8889-db040fac31e3" +version = "0.3.0" + +[[Conda]] +deps = ["Compat", "JSON", "VersionParsing"] +git-tree-sha1 = "fb86fe40cb5b35990e368709bfdc1b46dbb99dac" +uuid = "8f4d0f93-b110-5947-807f-2305c1781a2d" +version = "1.1.1" + +[[Contour]] +deps = ["LinearAlgebra", "StaticArrays", "Test"] +git-tree-sha1 = "b974e164358fea753ef853ce7bad97afec15bb80" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.5.1" + +[[CoordinateTransformations]] +deps = ["Compat", "Rotations", "StaticArrays"] +git-tree-sha1 = "47f05d0b7f4999609f92e657147df000818c1f24" +uuid = "150eb455-5306-5404-9cee-2592286d6298" +version = "0.5.0" + +[[CustomUnitRanges]] +deps = ["Test"] +git-tree-sha1 = "0a106457a1831555857e18ac9617279c22fc393b" +uuid = "dc8bdbbb-1ca9-579f-8c36-e416f6a65cce" +version = "0.2.0" + +[[DataFrames]] +deps = ["CategoricalArrays", "CodecZlib", "Compat", "DataStreams", "Dates", "InteractiveUtils", "IteratorInterfaceExtensions", "LinearAlgebra", "Missings", "Printf", "Random", "Reexport", "SortingAlgorithms", "Statistics", "StatsBase", "TableTraits", "Tables", "Test", "TranscodingStreams", "Unicode", "WeakRefStrings"] +git-tree-sha1 = "ad34fefb72b18a8dd5c17fab9089d11111b61935" +uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +version = "0.14.1" + +[[DataStreams]] +deps = ["Dates", "Missings", "Test", "WeakRefStrings"] +git-tree-sha1 = "69c72a1beb4fc79490c361635664e13c8e4a9548" +uuid = "9a8bc11e-79be-5b39-94d7-1ccc349a1a85" +version = "0.4.1" + +[[DataStructures]] +deps = ["InteractiveUtils", "OrderedCollections", "Random", "Serialization", "Test"] +git-tree-sha1 = "8fc6e166e24fda04b2b648d4260cdad241788c54" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.14.0" + +[[Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[DelimitedFiles]] +deps = ["Mmap"] +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" + +[[Distributed]] +deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[DocStringExtensions]] +deps = ["LibGit2", "Markdown", "Pkg", "Test"] +git-tree-sha1 = "1df01539a1c952cef21f2d2d1c092c2bcf0177d7" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.6.0" + +[[Documenter]] +deps = ["Base64", "DocStringExtensions", "InteractiveUtils", "LibGit2", "Logging", "Markdown", "Pkg", "REPL", "Random", "Test", "Unicode"] +git-tree-sha1 = "9f2135e0e7ecb63f9c3ef73ea15a31d8cdb79bb7" +uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +version = "0.20.0" + +[[EzXML]] +deps = ["BinaryProvider", "Libdl", "Printf", "Test"] +git-tree-sha1 = "5623d1486bfaadd815f5c4ca501adda02b5337f1" +uuid = "8f5d6c58-4d21-5cfd-889c-e3ad7ee6a615" +version = "0.9.0" + +[[FFTViews]] +deps = ["CustomUnitRanges", "FFTW", "Test"] +git-tree-sha1 = "9d7993227ca7c0fdb6b31deef193adbba11c8f4e" +uuid = "4f61f5a4-77b1-5117-aa51-3ab5ef4ef0cd" +version = "0.2.0" + +[[FFTW]] +deps = ["AbstractFFTs", "BinaryProvider", "Compat", "Conda", "Libdl", "LinearAlgebra", "Reexport", "Test"] +git-tree-sha1 = "29cda58afbf62f35b1a094882ad6c745a47b2eaa" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "0.2.4" + +[[FileIO]] +deps = ["Pkg", "Random", "Test"] +git-tree-sha1 = "1a114d08094e7267ba8d4d684f930d5a722184de" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.0.4" + +[[FixedPointNumbers]] +deps = ["Test"] +git-tree-sha1 = "b8045033701c3b10bf2324d7203404be7aef88ba" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.5.3" + +[[FreeType]] +deps = ["BinaryProvider", "Libdl", "Pkg", "Test"] +git-tree-sha1 = "06462b9d5aca708d764d16e5ba6a83ba7b753d57" +uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" +version = "2.1.1" + +[[FreeTypeAbstraction]] +deps = ["ColorVectorSpace", "Colors", "FreeType", "StaticArrays", "Test"] +git-tree-sha1 = "271ef13438bd0946950fd34d9241e5beefd6d4b3" +uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" +version = "0.4.1" + +[[Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" + +[[GDAL]] +deps = ["BinaryProvider", "Libdl", "Test"] +git-tree-sha1 = "100429098b7ec9930f7db9ba68aee3495365be24" +uuid = "add2ef01-049f-52c4-9ee2-e494f65e021a" +version = "0.2.0" + +[[GLFW]] +deps = ["BinDeps", "CMakeWrapper", "Homebrew", "Libdl", "Test"] +git-tree-sha1 = "035e2b5e9c335afae1e92ecfe532cf0620da869f" +uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" +version = "2.3.0" + +[[GLMakie]] +deps = ["AbstractPlotting", "AxisArrays", "ColorBrewer", "ColorTypes", "ColorVectorSpace", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GLFW", "GeometryTypes", "ImageAxes", "ImageCore", "ImageMagick", "ImageTransformations", "IndirectArrays", "IntervalSets", "IterTools", "LinearAlgebra", "Makie", "Markdown", "ModernGL", "Observables", "Pkg", "PlotUtils", "Primes", "Printf", "QuartzImageIO", "Serialization", "Showoff", "StaticArrays", "UnicodeFun"] +git-tree-sha1 = "2e3cb969fd8f8cab98a4863d4a97d24bb1efdbd0" +uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" +version = "0.0.1" + +[[GeometryTypes]] +deps = ["ColorTypes", "FixedPointNumbers", "IterTools", "LinearAlgebra", "StaticArrays", "Test"] +git-tree-sha1 = "28b193e14466beecf928449e0f8505ff6de3709d" +repo-rev = "sd-bb" +repo-url = "https://github.com/JuliaGeometry/GeometryTypes.jl.git" +uuid = "4d00f742-c7ba-57c2-abde-4428a4b178cb" +version = "0.7.1+" + +[[Graphics]] +deps = ["Colors", "Compat", "NaNMath"] +git-tree-sha1 = "e3ead4211073d4117a0d2ef7d1efc5c8092c8412" +uuid = "a2bd30eb-e257-5431-a919-1863eab51364" +version = "0.4.0" + +[[Homebrew]] +deps = ["BinDeps", "InteractiveUtils", "JSON", "Libdl", "Test", "Unicode"] +git-tree-sha1 = "5582ec74f735cf8d12e562a2e65c47f34063bd51" +uuid = "d9be37ee-ecc9-5288-90f1-b9ca67657a75" +version = "0.7.0" + +[[IdentityRanges]] +deps = ["OffsetArrays", "Test"] +git-tree-sha1 = "f5ca23a08397288924a7535cd898d8ccbcde5ba5" +uuid = "bbac6d45-d8f3-5730-bfe4-7a449cd117ca" +version = "0.2.0" + +[[ImageAxes]] +deps = ["AxisArrays", "Colors", "FixedPointNumbers", "ImageCore", "MappedArrays", "Reexport", "SimpleTraits", "Test"] +git-tree-sha1 = "5735ec90843acaa67a4624611921c686cdf4efbf" +uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" +version = "0.5.0" + +[[ImageCore]] +deps = ["ColorTypes", "Colors", "FFTW", "FixedPointNumbers", "Graphics", "MappedArrays", "OffsetArrays", "PaddedViews", "Random", "Statistics", "Test"] +git-tree-sha1 = "5e7b1f49c80541860e08a7ea91805a24c1641f19" +uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" +version = "0.7.3" + +[[ImageFiltering]] +deps = ["CatIndices", "ColorVectorSpace", "Colors", "ComputationalResources", "DataStructures", "FFTViews", "FFTW", "FixedPointNumbers", "ImageCore", "LinearAlgebra", "Logging", "MappedArrays", "OffsetArrays", "Random", "StaticArrays", "Statistics", "Test", "TiledIteration"] +git-tree-sha1 = "2d23d8f8c1def1e8d67d05e554baacc780d9313d" +uuid = "6a3955dd-da59-5b1f-98d4-e7296123deb5" +version = "0.5.1" + +[[ImageMagick]] +deps = ["BinaryProvider", "ColorTypes", "FileIO", "FixedPointNumbers", "ImageCore", "InteractiveUtils", "Libdl", "Pkg", "Random", "Test"] +git-tree-sha1 = "0e4cc77fb131061b3525a97fd7d483b253c3aaad" +uuid = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" +version = "0.7.1" + +[[ImageTransformations]] +deps = ["AxisAlgorithms", "ColorTypes", "ColorVectorSpace", "Colors", "CoordinateTransformations", "FixedPointNumbers", "IdentityRanges", "ImageCore", "Interpolations", "LinearAlgebra", "OffsetArrays", "StaticArrays", "Test"] +git-tree-sha1 = "18ae1c0a8df31549a9452ceac93751d4aa166071" +uuid = "02fcd773-0e25-5acc-982a-7f6622650795" +version = "0.7.1" + +[[IndirectArrays]] +deps = ["Compat", "Test"] +git-tree-sha1 = "b6e249be10a3381b2c72ac82f2d13d70067cb2bd" +uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" +version = "0.5.0" + +[[InteractiveUtils]] +deps = ["LinearAlgebra", "Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[Interpolations]] +deps = ["AxisAlgorithms", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "SharedArrays", "SparseArrays", "StaticArrays", "Test", "WoodburyMatrices"] +git-tree-sha1 = "3493536a64dae5a21c0cc8aecf680647f3e12313" +uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" +version = "0.11.0" + +[[IntervalSets]] +deps = ["Compat"] +git-tree-sha1 = "9dc556002f23740de13946e8c2e41798e09a9249" +uuid = "8197267c-284f-5f27-9208-e0e47529a953" +version = "0.3.1" + +[[IterTools]] +deps = ["SparseArrays", "Test"] +git-tree-sha1 = "79246285c43602384e6f1943b3554042a3712056" +uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +version = "1.1.1" + +[[IteratorInterfaceExtensions]] +deps = ["Test"] +git-tree-sha1 = "5484e5ede2a4137b9643f4d646e8e7b87b794415" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "0.1.1" + +[[JSON]] +deps = ["Dates", "Distributed", "Mmap", "Sockets", "Test", "Unicode"] +git-tree-sha1 = "1f7a25b53ec67f5e9422f1f551ee216503f4a0fa" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.20.0" + +[[LibGit2]] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[LinearAlgebra]] +deps = ["Libdl"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[MacroTools]] +deps = ["Compat"] +git-tree-sha1 = "c443e1c8d58a4e9f61b708ad0a88286c7042145b" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.4.4" + +[[Makie]] +deps = ["AbstractPlotting", "AxisArrays", "Base64", "ColorBrewer", "ColorTypes", "ColorVectorSpace", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GLFW", "GLMakie", "GeometryTypes", "ImageAxes", "ImageCore", "ImageMagick", "ImageTransformations", "IndirectArrays", "IntervalSets", "IterTools", "LinearAlgebra", "ModernGL", "Observables", "Pkg", "PlotUtils", "Primes", "QuartzImageIO", "Showoff", "StaticArrays", "Statistics", "UnicodeFun"] +git-tree-sha1 = "a49ae5834b605a14447e04d57a07cbb80ebe8add" +repo-rev = "master" +repo-url = "https://github.com/JuliaPlots/Makie.jl.git" +uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" +version = "0.9.0+" + +[[MakieGallery]] +deps = ["AbstractPlotting", "BinaryProvider", "ColorTypes", "ColorVectorSpace", "Colors", "DataFrames", "Documenter", "FileIO", "FixedPointNumbers", "GDAL", "GeometryTypes", "ImageCore", "ImageFiltering", "ImageMagick", "ImageTransformations", "LinearAlgebra", "Makie", "Markdown", "MeshIO", "ModernGL", "Pkg", "QuartzImageIO", "RDatasets", "Random", "Statistics", "Test"] +git-tree-sha1 = "178252e975f92c3e11a4478577ec4a4faff4119d" +repo-rev = "master" +repo-url = "https://github.com/JuliaPlots/MakieGallery.jl.git" +uuid = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" +version = "0.0.1+" + +[[MappedArrays]] +deps = ["Test"] +git-tree-sha1 = "923441c5ac942b60bd3a842d5377d96646bcbf46" +uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" +version = "0.2.1" + +[[Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[MeshIO]] +deps = ["ColorTypes", "FileIO", "GeometryTypes", "Printf", "Test"] +git-tree-sha1 = "3e01e12c4c626578a9d47fac0d15c9fe8dad5139" +uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" +version = "0.3.1" + +[[Missings]] +deps = ["Dates", "InteractiveUtils", "SparseArrays", "Test"] +git-tree-sha1 = "adc26d2ee85a49c413464110d922cf21efc9d233" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "0.3.1" + +[[Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[Mocking]] +deps = ["Compat", "Dates"] +git-tree-sha1 = "4bf69aaf823b119b034e091e16b18311aa191663" +uuid = "78c3b35d-d492-501b-9361-3d52fe80e533" +version = "0.5.7" + +[[ModernGL]] +deps = ["Libdl"] +git-tree-sha1 = "f4f8fa8d04d3c1e7294f07fc37586c819466ad38" +uuid = "66fc600b-dfda-50eb-8b99-91cfa97b1301" +version = "1.0.0" + +[[NaNMath]] +deps = ["Compat"] +git-tree-sha1 = "ce3b85e484a5d4c71dd5316215069311135fa9f2" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "0.3.2" + +[[Nullables]] +deps = ["Compat"] +git-tree-sha1 = "ae1a63457e14554df2159b0b028f48536125092d" +uuid = "4d1e1d77-625e-5b40-9113-a560ec7a8ecd" +version = "0.0.8" + +[[Observables]] +deps = ["Test"] +git-tree-sha1 = "dc02cec22747d1d10d9f70d8a1c03432b5bfbcd0" +uuid = "510215fc-4207-5dde-b226-833fc4488ee2" +version = "0.2.3" + +[[OffsetArrays]] +deps = ["DelimitedFiles", "Test"] +git-tree-sha1 = "f446248f2dfbc13039a0b90994dd25b059b01eab" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "0.9.0" + +[[OrderedCollections]] +deps = ["Random", "Serialization", "Test"] +git-tree-sha1 = "85619a3f3e17bb4761fe1b1fd47f0e979f964d5b" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.0.2" + +[[Packing]] +deps = ["GeometryTypes", "Test"] +git-tree-sha1 = "bc7c284233cf0518933bf9977e3e8234efcc1c30" +uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" +version = "0.3.0" + +[[PaddedViews]] +deps = ["OffsetArrays", "Test"] +git-tree-sha1 = "7da3e7e1a58cffbf10177553ae95f17b92516912" +uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" +version = "0.4.2" + +[[Parameters]] +deps = ["Markdown", "OrderedCollections", "REPL", "Test"] +git-tree-sha1 = "eec0fe16344cc14aa2e6251874ab30d62aff4f7c" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.10.2" + +[[Parsers]] +deps = ["Dates", "Mmap", "Test", "WeakRefStrings"] +git-tree-sha1 = "949ca36d47010bee093254467166487c921d490b" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "0.2.14" + +[[Pkg]] +deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" + +[[PlotUtils]] +deps = ["Colors", "Dates", "Printf", "Random", "Reexport", "Test"] +git-tree-sha1 = "fd28f30a294a38ec847de95d8ac7ac916ccd7c06" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "0.5.5" + +[[Primes]] +deps = ["Test"] +git-tree-sha1 = "ff1a2323cb468ec5f201838fcbe3c232266b1f95" +uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" +version = "0.4.0" + +[[Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[Profile]] +deps = ["Printf"] +uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" + +[[QuartzImageIO]] +deps = ["ColorTypes", "ColorVectorSpace", "FileIO", "FixedPointNumbers", "ImageCore", "Libdl", "Random", "Test"] +git-tree-sha1 = "c747a56f223919b157e6cd9dc58d59c560586302" +uuid = "dca85d43-d64c-5e67-8c65-017450d5d020" +version = "0.5.0" + +[[RData]] +deps = ["CategoricalArrays", "CodecZlib", "DataFrames", "Dates", "FileIO", "Missings", "Test", "TimeZones"] +git-tree-sha1 = "8f3b644f4ebce291431846f5532272b0864c757c" +uuid = "df47a6cb-8c03-5eed-afd8-b6050d6c41da" +version = "0.5.0" + +[[RDatasets]] +deps = ["CSV", "CodecZlib", "DataFrames", "FileIO", "Printf", "RData", "Reexport", "Test"] +git-tree-sha1 = "4d93a52b94397bf0a9477d04e7a151a688672695" +uuid = "ce6b1742-4840-55fa-b093-852dadbb1d8b" +version = "0.6.1" + +[[REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[Random]] +deps = ["Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[RangeArrays]] +deps = ["Compat"] +git-tree-sha1 = "d925adfd5b01cb46fde89dc9548d167b3b136f4a" +uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" +version = "0.3.1" + +[[Ratios]] +deps = ["Compat"] +git-tree-sha1 = "fd159bead0a24e6270fd0573a340312bd4645cc2" +uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" +version = "0.3.0" + +[[Reexport]] +deps = ["Pkg"] +git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "0.2.0" + +[[Requires]] +deps = ["Test"] +git-tree-sha1 = "f6fbf4ba64d295e146e49e021207993b6b48c7d1" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "0.5.2" + +[[Rotations]] +deps = ["LinearAlgebra", "Random", "StaticArrays", "Statistics", "Test"] +git-tree-sha1 = "b629771d0de88979cbdbf72ceddc54de58fde149" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "0.9.1" + +[[SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" + +[[Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[Showoff]] +deps = ["Compat"] +git-tree-sha1 = "276b24f3ace98bec911be7ff2928d497dc759085" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "0.2.1" + +[[SignedDistanceFields]] +deps = ["Random", "Statistics", "Test"] +git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" +uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" +version = "0.4.0" + +[[SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools", "Test"] +git-tree-sha1 = "c0a542b8d5e369b179ccd296b2ca987f6da5da0a" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.8.0" + +[[Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[SortingAlgorithms]] +deps = ["DataStructures", "Random", "Test"] +git-tree-sha1 = "03f5898c9959f8115e30bc7226ada7d0df554ddd" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "0.3.1" + +[[SparseArrays]] +deps = ["LinearAlgebra", "Random"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[SpecialFunctions]] +deps = ["BinDeps", "BinaryProvider", "Libdl", "Test"] +git-tree-sha1 = "0b45dc2e45ed77f445617b99ff2adf0f5b0f23ea" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "0.7.2" + +[[StaticArrays]] +deps = ["InteractiveUtils", "LinearAlgebra", "Random", "Statistics", "Test"] +git-tree-sha1 = "97c4bf0f647488dd7ac01ea12be5885f88762938" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "0.10.0" + +[[Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[StatsBase]] +deps = ["DataStructures", "LinearAlgebra", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "Test"] +git-tree-sha1 = "2722397d88f8ffef551948f6c20e1d74a743298c" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.26.0" + +[[TableTraits]] +deps = ["IteratorInterfaceExtensions", "Test"] +git-tree-sha1 = "da062a2c31f16178f68190243c24140801720a43" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "0.4.0" + +[[Tables]] +deps = ["Requires", "Test"] +git-tree-sha1 = "940944e6b68a35046282897a2218891c7cf14a32" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "0.1.12" + +[[Test]] +deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[TiledIteration]] +deps = ["OffsetArrays", "Test"] +git-tree-sha1 = "58f6f07d3b54a363ec283a8f5fc9fb4ecebde656" +uuid = "06e1c1a7-607b-532d-9fad-de7d9aa2abac" +version = "0.2.3" + +[[TimeZones]] +deps = ["Compat", "EzXML", "Mocking", "Nullables"] +git-tree-sha1 = "4a4ab113913e19ad62b67e6c5c056509eac00c19" +uuid = "f269a46b-ccf7-5d73-abea-4c690281aa53" +version = "0.8.2" + +[[TranscodingStreams]] +deps = ["Pkg", "Random", "Test"] +git-tree-sha1 = "a34a2d588e2d2825602bf14a24216d5c8b0921ec" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.8.1" + +[[URIParser]] +deps = ["Test", "Unicode"] +git-tree-sha1 = "6ddf8244220dfda2f17539fa8c9de20d6c575b69" +uuid = "30578b45-9adc-5946-b283-645ec420af67" +version = "0.4.0" + +[[UUIDs]] +deps = ["Random"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[UnicodeFun]] +deps = ["Test"] +git-tree-sha1 = "63cbbd00217fc9aafedf055b60459c1ae7e01ecc" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.0" + +[[VersionParsing]] +deps = ["Compat"] +git-tree-sha1 = "c9d5aa108588b978bd859554660c8a5c4f2f7669" +uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" +version = "1.1.3" + +[[WeakRefStrings]] +deps = ["Missings", "Random", "Test"] +git-tree-sha1 = "1087e8be380f2c8b96434b02bb1150fc1c511135" +uuid = "ea10d353-3f73-51f8-a26c-33c1cb351aa5" +version = "0.5.3" + +[[WoodburyMatrices]] +deps = ["LinearAlgebra", "Random", "SparseArrays", "Test"] +git-tree-sha1 = "21772c33b447757ec7d3e61fcdfb9ea5c47eedcf" +uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" +version = "0.4.1" diff --git a/Project.toml b/Project.toml index 2d871da7015..a53feac1038 100644 --- a/Project.toml +++ b/Project.toml @@ -23,6 +23,8 @@ IndirectArrays = "9b13fd28-a010-5f03-acff-a1bbcff69959" IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" +MakieGallery = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a" ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" Observables = "510215fc-4207-5dde-b226-833fc4488ee2" @@ -35,4 +37,3 @@ Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" Showoff = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" UnicodeFun = "1cfade01-22cf-5700-b092-accc4b62d6e1" -MakieGallery = "62e31da0-2f4f-5d53-819c-a7cea9df6aaa" From 2232e17ad0831bb02454ec5a37441a58ddd85977 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Sun, 2 Dec 2018 21:05:52 +0100 Subject: [PATCH 0024/1328] update CI script --- .gitlab-ci.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b140a4a6d30..dff1f12d009 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -15,8 +15,4 @@ job: script: - julia -e 'using InteractiveUtils; versioninfo()' - - julia --project -e "using Pkg; - Pkg.instantiate(); - Pkg.add(PackageSpec(name = \"GLMakie\", path=ENV[\"CI_PROJECT_DIR\"])); - Pkg.build(); - Pkg.test(\"GLMakie\");" + - julia --project -e "using Pkg; Pkg.build(); Pkg.test()" From f4ac61a3cade4bba5dbc8164864304b9de923a3d Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Sun, 2 Dec 2018 21:09:17 +0100 Subject: [PATCH 0025/1328] remove ffmpeg install script --- test/install_ffmpeg.sh | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 test/install_ffmpeg.sh diff --git a/test/install_ffmpeg.sh b/test/install_ffmpeg.sh deleted file mode 100644 index 07bedafed64..00000000000 --- a/test/install_ffmpeg.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -add-apt-repository -y ppa:mc3man/trusty-media -apt-get -qq update -apt-get install -y ffmpeg From 282b2bda425b3e9c8f4344be1410e2a382f00947 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Sun, 2 Dec 2018 21:09:40 +0100 Subject: [PATCH 0026/1328] remove osx for now --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index bfb8a71d46b..448fd6f2fb4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,6 @@ notifications: email: false os: - linux - - osx sudo: true before_install: @@ -21,4 +20,3 @@ before_install: - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install zlib1g-dev -y; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install ffmpeg gstreamer0.10-ffmpeg -y; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install imagemagick -y; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install ffmpeg; fi From ef134c0e7870b16118d4f28dbeac5993ac297b42 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Sun, 2 Dec 2018 21:10:04 +0100 Subject: [PATCH 0027/1328] improve text positioning --- src/CairoMakie.jl | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/CairoMakie.jl b/src/CairoMakie.jl index 6cd0b2fa483..75ea64af5b9 100644 --- a/src/CairoMakie.jl +++ b/src/CairoMakie.jl @@ -346,32 +346,38 @@ function fontname(x::NativeFont) unsafe_string(ft_rect.family_name) end -function fontscale(scene, c, font, s) - atlas = AbstractPlotting.get_texture_atlas() +function fontscale(atlas, scene, c, font, s) s = (s ./ atlas.scale[AbstractPlotting.glyph_index!(atlas, c, font)]) ./ 0.02 project_scale(scene, s) end +function to_rel_scale(atlas, c, font, scale) + gs = atlas.scale[AbstractPlotting.glyph_index!(atlas, c, font)] + (scale ./ 0.02) ./ gs +end + function draw_atomic(scene::Scene, screen::CairoScreen, primitive::Text) ctx = screen.context @get_attribute(primitive, (textsize, color, font, align, rotation, model)) txt = to_value(primitive[1]) position = primitive.attributes[:position][] N = length(txt) + atlas = AbstractPlotting.get_texture_atlas() broadcast_foreach(1:N, position, textsize, color, font, rotation) do i, p, ts, cc, f, r Cairo.save(ctx) - pos = project_position(scene, p, model) + char = N == length(position) ? txt[i] : first(txt) + rels = to_rel_scale(atlas, char, f, ts) + b = AbstractPlotting.glyph_bearing!(atlas, char, f, rels) + pos = project_position(scene, p .- to_ndim(typeof(p), b, 0f0), model) Cairo.move_to(ctx, pos[1], pos[2]) Cairo.set_source_rgba(ctx, red(cc), green(cc), blue(cc), alpha(cc)) - Cairo.select_font_face( ctx, fontname(f), Cairo.FONT_SLANT_NORMAL, - Cairo.FONT_WEIGHT_BOLD + Cairo.FONT_WEIGHT_NORMAL ) #set_ft_font(ctx, f) - char = N == length(position) ? txt[i] : first(txt) - ts = fontscale(scene, char, f, ts) + ts = fontscale(atlas, scene, char, f, ts) mat = scale_matrix(ts...) set_font_matrix(ctx, mat) # set_font_size(ctx, 16) From d6a462904631bd9d6ef4f7e195491e26a2aa8e7a Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Sun, 2 Dec 2018 21:10:14 +0100 Subject: [PATCH 0028/1328] remove helper file --- cleanmani.jl | 40 ---------------------------------------- 1 file changed, 40 deletions(-) delete mode 100644 cleanmani.jl diff --git a/cleanmani.jl b/cleanmani.jl deleted file mode 100644 index 841439a8c7e..00000000000 --- a/cleanmani.jl +++ /dev/null @@ -1,40 +0,0 @@ -using Pkg -using Pkg.TOML -cd(@__DIR__) -mani = TOML.parsefile("Manifest.toml") - -deps = mani["CairoMakie"][1]["deps"] - -function get_all_deps(name, result = Dict{String, Any}()) - pkg = mani[name][1] - println(name) - result[name] = [pkg] - if haskey(pkg, "deps") - deps = pkg["deps"] - for dep in deps - if !haskey(result, dep) - get_all_deps(dep, result) - end - end - end - result -end -deps = get_all_deps("CairoMakie") -@which TOML.parsefile("") -parser = TOML.Parser(IOBuffer()) -@which TOML.parse(parser) - -function print_toml(path, dict) - open(path, "w") do io - for name in keys(dict) - println(io, "[[$name]]") - pkg = dict[name][1] - for (k, v) in pkg - println(io, k, " = ", repr(v)) - end - println(io) - println(io) - end - end -end -print_toml("Manifest.toml", deps) From d879502bf88a5361026799a3ce8d304819a0de2e Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 2 Dec 2018 23:15:07 +0100 Subject: [PATCH 0029/1328] clean up tests (#2) clean up tests + fix text positioning --- .travis.yml | 2 -- cleanmani.jl | 40 ---------------------------------------- src/CairoMakie.jl | 19 +++++++++++++------ test/install_ffmpeg.sh | 5 ----- 4 files changed, 13 insertions(+), 53 deletions(-) delete mode 100644 cleanmani.jl delete mode 100644 test/install_ffmpeg.sh diff --git a/.travis.yml b/.travis.yml index bfb8a71d46b..448fd6f2fb4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,6 @@ notifications: email: false os: - linux - - osx sudo: true before_install: @@ -21,4 +20,3 @@ before_install: - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install zlib1g-dev -y; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install ffmpeg gstreamer0.10-ffmpeg -y; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install imagemagick -y; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install ffmpeg; fi diff --git a/cleanmani.jl b/cleanmani.jl deleted file mode 100644 index 841439a8c7e..00000000000 --- a/cleanmani.jl +++ /dev/null @@ -1,40 +0,0 @@ -using Pkg -using Pkg.TOML -cd(@__DIR__) -mani = TOML.parsefile("Manifest.toml") - -deps = mani["CairoMakie"][1]["deps"] - -function get_all_deps(name, result = Dict{String, Any}()) - pkg = mani[name][1] - println(name) - result[name] = [pkg] - if haskey(pkg, "deps") - deps = pkg["deps"] - for dep in deps - if !haskey(result, dep) - get_all_deps(dep, result) - end - end - end - result -end -deps = get_all_deps("CairoMakie") -@which TOML.parsefile("") -parser = TOML.Parser(IOBuffer()) -@which TOML.parse(parser) - -function print_toml(path, dict) - open(path, "w") do io - for name in keys(dict) - println(io, "[[$name]]") - pkg = dict[name][1] - for (k, v) in pkg - println(io, k, " = ", repr(v)) - end - println(io) - println(io) - end - end -end -print_toml("Manifest.toml", deps) diff --git a/src/CairoMakie.jl b/src/CairoMakie.jl index 6cd0b2fa483..3615080a1ef 100644 --- a/src/CairoMakie.jl +++ b/src/CairoMakie.jl @@ -346,32 +346,39 @@ function fontname(x::NativeFont) unsafe_string(ft_rect.family_name) end -function fontscale(scene, c, font, s) - atlas = AbstractPlotting.get_texture_atlas() +function fontscale(atlas, scene, c, font, s) s = (s ./ atlas.scale[AbstractPlotting.glyph_index!(atlas, c, font)]) ./ 0.02 project_scale(scene, s) end +function to_rel_scale(atlas, c, font, scale) + gs = atlas.scale[AbstractPlotting.glyph_index!(atlas, c, font)] + (scale ./ 0.02) ./ gs +end + function draw_atomic(scene::Scene, screen::CairoScreen, primitive::Text) ctx = screen.context @get_attribute(primitive, (textsize, color, font, align, rotation, model)) txt = to_value(primitive[1]) position = primitive.attributes[:position][] N = length(txt) + atlas = AbstractPlotting.get_texture_atlas() broadcast_foreach(1:N, position, textsize, color, font, rotation) do i, p, ts, cc, f, r Cairo.save(ctx) + char = N == length(position) ? txt[i] : first(txt) + rels = to_rel_scale(atlas, char, f, ts) + b = AbstractPlotting.glyph_bearing!(atlas, char, f, rels) + p2 = to_ndim(Point{length(p), Float32}, b, 0f0) pos = project_position(scene, p, model) Cairo.move_to(ctx, pos[1], pos[2]) Cairo.set_source_rgba(ctx, red(cc), green(cc), blue(cc), alpha(cc)) - Cairo.select_font_face( ctx, fontname(f), Cairo.FONT_SLANT_NORMAL, - Cairo.FONT_WEIGHT_BOLD + Cairo.FONT_WEIGHT_NORMAL ) #set_ft_font(ctx, f) - char = N == length(position) ? txt[i] : first(txt) - ts = fontscale(scene, char, f, ts) + ts = fontscale(atlas, scene, char, f, ts) mat = scale_matrix(ts...) set_font_matrix(ctx, mat) # set_font_size(ctx, 16) diff --git a/test/install_ffmpeg.sh b/test/install_ffmpeg.sh deleted file mode 100644 index 07bedafed64..00000000000 --- a/test/install_ffmpeg.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -add-apt-repository -y ppa:mc3man/trusty-media -apt-get -qq update -apt-get install -y ffmpeg From 66df43da2b913b93d9e00af9f0c7da3081bbcb46 Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 2 Dec 2018 23:17:05 +0100 Subject: [PATCH 0030/1328] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c47c03447ed..4cb073b7503 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ # CairoMakie The Cairo Backend for Makie + +![[](https://travis-ci.org/JuliaPlots/CairoMakie.jl)](https://api.travis-ci.org/JuliaPlots/CairoMakie.jl.svg?branch=master) From 220a9f150561e1e20507e92fd8bdb7dc4fa53d84 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 3 Dec 2018 15:04:31 +0100 Subject: [PATCH 0031/1328] use package bounds --- Project.toml | 28 +++++++++++++++++++++++++--- REQUIRE | 2 +- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/Project.toml b/Project.toml index a53feac1038..4be70ccbddf 100644 --- a/Project.toml +++ b/Project.toml @@ -1,5 +1,6 @@ name = "GLMakie" uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" +version = "0.0.1" [deps] AbstractPlotting = "537997a7-5e4e-5d89-9595-2241ea00577e" @@ -23,12 +24,9 @@ IndirectArrays = "9b13fd28-a010-5f03-acff-a1bbcff69959" IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -MakieGallery = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a" ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" Observables = "510215fc-4207-5dde-b226-833fc4488ee2" -Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" PlotUtils = "995b91a9-d308-5afd-9ec6-746e21dbc043" Primes = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" @@ -37,3 +35,27 @@ Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" Showoff = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" UnicodeFun = "1cfade01-22cf-5700-b092-accc4b62d6e1" + +[compat] +FreeTypeAbstraction = ">=0.3.0" +GLFW = ">=2.3.0" +GeometryTypes = ">=0.7.2" +StaticArrays = ">=0.6.6" + +[extras] +DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +GDAL = "add2ef01-049f-52c4-9ee2-e494f65e021a" +ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534" +ImageFiltering = "6a3955dd-da59-5b1f-98d4-e7296123deb5" +ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" +ImageTransformations = "02fcd773-0e25-5acc-982a-7f6622650795" +MakieGallery = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" +MeshIO = "7269a6da-0436-5bbc-96c2-40638cbb6118" +ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" +QuartzImageIO = "dca85d43-d64c-5e67-8c65-017450d5d020" +RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" + +[targets] +test = ["ImageCore", "ImageTransformations", "ImageMagick", "ImageMagick", "QuartzImageIO", "Documenter", "ModernGL", "MeshIO", "ImageMagick", "ImageTransformations", "GDAL", "FileIO", "ImageFiltering", "DataFrames", "RDatasets", "MakieGallery"] diff --git a/REQUIRE b/REQUIRE index 0f46e9af355..89921f7d119 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,7 +1,7 @@ julia 0.7 StaticArrays 0.6.6 -GeometryTypes 0.4.5 +GeometryTypes 0.7.2 Observables Contour FileIO From 9c53dd20878933c389120cb0992dfe0fe55880d2 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 3 Dec 2018 18:16:00 +0100 Subject: [PATCH 0032/1328] set visibility correctly --- src/gl_backend.jl | 3 --- src/screen.jl | 8 +++++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/gl_backend.jl b/src/gl_backend.jl index 06234da685c..4e07ea58989 100644 --- a/src/gl_backend.jl +++ b/src/gl_backend.jl @@ -50,8 +50,6 @@ include("drawing_primitives.jl") function AbstractPlotting.backend_display(x::GLBackend, scene::Scene) screen = global_gl_screen() - # This should only get called if inline display false, so we display the window - GLFW.set_visibility!(to_native(screen), AbstractPlotting.use_display[]) display(screen, scene) return screen end @@ -69,6 +67,5 @@ end function AbstractPlotting.backend_show(::GLBackend, io::IO, m::MIME"image/png", scene::Scene) img = scene2image(scene) - GLFW.set_visibility!(to_native(global_gl_screen()), AbstractPlotting.use_display[]) FileIO.save(FileIO.Stream(FileIO.format"PNG", io), img) end diff --git a/src/screen.jl b/src/screen.jl index dc49f23dd94..aebf7f3f4ab 100644 --- a/src/screen.jl +++ b/src/screen.jl @@ -241,12 +241,14 @@ function Screen(; resolution = (10, 10), visible = false, kw_args...) end function global_gl_screen() - if isassigned(_global_gl_screen) && isopen(_global_gl_screen[]) + screen = if isassigned(_global_gl_screen) && isopen(_global_gl_screen[]) _global_gl_screen[] else _global_gl_screen[] = Screen() _global_gl_screen[] end + GLFW.set_visibility!(to_native(screen), AbstractPlotting.use_display[]) + screen end # TODO per scene screen @@ -297,6 +299,7 @@ function mouse_selection_native(scene::SceneLike) end convert(SelectionID{Int}, _mouse_selection_id[]) end + function mouse_selection(scene::SceneLike) sid = mouse_selection_native(scene) screen = getscreen(scene) @@ -306,6 +309,7 @@ function mouse_selection(scene::SceneLike) end return (nothing, 0) end + function mouseover(scene::SceneLike, plots::AbstractPlot...) p, idx = mouse_selection(scene) p in flatten_plots(plots) @@ -315,12 +319,14 @@ function flatten_plots(x::Atomic, plots = AbstractPlot[]) push!(plots, x) plots end + function flatten_plots(x::Combined, plots = AbstractPlot[]) for elem in x.plots flatten_plots(elem, plots) end plots end + function flatten_plots(array, plots = AbstractPlot[]) for elem in array flatten_plots(elem, plots) From ee97597bf74d99ee6e6b61e6002a848c4ce40180 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 3 Dec 2018 18:16:18 +0100 Subject: [PATCH 0033/1328] dont use makie no more --- Manifest.toml | 34 +++++++++------------------------- Project.toml | 1 + test/runtests.jl | 4 +++- 3 files changed, 13 insertions(+), 26 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index c70360a479c..bc02e7a96a0 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -5,12 +5,12 @@ uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" version = "0.3.2" [[AbstractPlotting]] -deps = ["ColorBrewer", "ColorTypes", "Colors", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "Test", "UnicodeFun"] -git-tree-sha1 = "0e969852e9c20f24ad6ef705faa8db32f0990238" -repo-rev = "master" +deps = ["ColorBrewer", "ColorTypes", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "UnicodeFun"] +git-tree-sha1 = "8c2b1f93b85ae6e119a9e64df8bf3d82daee5d73" +repo-rev = "sd-manifest" repo-url = "https://github.com/JuliaPlots/AbstractPlotting.jl.git" uuid = "537997a7-5e4e-5d89-9595-2241ea00577e" -version = "0.9.0+" +version = "0.9.0" [[AxisAlgorithms]] deps = ["Compat", "WoodburyMatrices"] @@ -137,9 +137,9 @@ version = "0.2.0" [[DataFrames]] deps = ["CategoricalArrays", "CodecZlib", "Compat", "DataStreams", "Dates", "InteractiveUtils", "IteratorInterfaceExtensions", "LinearAlgebra", "Missings", "Printf", "Random", "Reexport", "SortingAlgorithms", "Statistics", "StatsBase", "TableTraits", "Tables", "Test", "TranscodingStreams", "Unicode", "WeakRefStrings"] -git-tree-sha1 = "ad34fefb72b18a8dd5c17fab9089d11111b61935" +git-tree-sha1 = "dd11f0aed840e305050f4b49f53153d2dd622650" uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -version = "0.14.1" +version = "0.15.0" [[DataStreams]] deps = ["Dates", "Missings", "Test", "WeakRefStrings"] @@ -235,19 +235,13 @@ git-tree-sha1 = "035e2b5e9c335afae1e92ecfe532cf0620da869f" uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" version = "2.3.0" -[[GLMakie]] -deps = ["AbstractPlotting", "AxisArrays", "ColorBrewer", "ColorTypes", "ColorVectorSpace", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GLFW", "GeometryTypes", "ImageAxes", "ImageCore", "ImageMagick", "ImageTransformations", "IndirectArrays", "IntervalSets", "IterTools", "LinearAlgebra", "Makie", "Markdown", "ModernGL", "Observables", "Pkg", "PlotUtils", "Primes", "Printf", "QuartzImageIO", "Serialization", "Showoff", "StaticArrays", "UnicodeFun"] -git-tree-sha1 = "2e3cb969fd8f8cab98a4863d4a97d24bb1efdbd0" -uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" -version = "0.0.1" - [[GeometryTypes]] deps = ["ColorTypes", "FixedPointNumbers", "IterTools", "LinearAlgebra", "StaticArrays", "Test"] git-tree-sha1 = "28b193e14466beecf928449e0f8505ff6de3709d" repo-rev = "sd-bb" repo-url = "https://github.com/JuliaGeometry/GeometryTypes.jl.git" uuid = "4d00f742-c7ba-57c2-abde-4428a4b178cb" -version = "0.7.1+" +version = "0.7.2+" [[Graphics]] deps = ["Colors", "Compat", "NaNMath"] @@ -356,19 +350,9 @@ git-tree-sha1 = "c443e1c8d58a4e9f61b708ad0a88286c7042145b" uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" version = "0.4.4" -[[Makie]] -deps = ["AbstractPlotting", "AxisArrays", "Base64", "ColorBrewer", "ColorTypes", "ColorVectorSpace", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GLFW", "GLMakie", "GeometryTypes", "ImageAxes", "ImageCore", "ImageMagick", "ImageTransformations", "IndirectArrays", "IntervalSets", "IterTools", "LinearAlgebra", "ModernGL", "Observables", "Pkg", "PlotUtils", "Primes", "QuartzImageIO", "Showoff", "StaticArrays", "Statistics", "UnicodeFun"] -git-tree-sha1 = "a49ae5834b605a14447e04d57a07cbb80ebe8add" -repo-rev = "master" -repo-url = "https://github.com/JuliaPlots/Makie.jl.git" -uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -version = "0.9.0+" - [[MakieGallery]] -deps = ["AbstractPlotting", "BinaryProvider", "ColorTypes", "ColorVectorSpace", "Colors", "DataFrames", "Documenter", "FileIO", "FixedPointNumbers", "GDAL", "GeometryTypes", "ImageCore", "ImageFiltering", "ImageMagick", "ImageTransformations", "LinearAlgebra", "Makie", "Markdown", "MeshIO", "ModernGL", "Pkg", "QuartzImageIO", "RDatasets", "Random", "Statistics", "Test"] -git-tree-sha1 = "178252e975f92c3e11a4478577ec4a4faff4119d" -repo-rev = "master" -repo-url = "https://github.com/JuliaPlots/MakieGallery.jl.git" +deps = ["AbstractPlotting", "BinaryProvider", "ColorTypes", "ColorVectorSpace", "Colors", "DataFrames", "Documenter", "FileIO", "FixedPointNumbers", "GDAL", "GeometryTypes", "ImageCore", "ImageFiltering", "ImageMagick", "ImageTransformations", "LinearAlgebra", "Markdown", "MeshIO", "ModernGL", "Pkg", "QuartzImageIO", "RDatasets", "Random", "Statistics", "Test"] +path = "/home/sd/.julia/dev/MakieGallery" uuid = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" version = "0.0.1+" diff --git a/Project.toml b/Project.toml index 4be70ccbddf..504191bef5b 100644 --- a/Project.toml +++ b/Project.toml @@ -24,6 +24,7 @@ IndirectArrays = "9b13fd28-a010-5f03-acff-a1bbcff69959" IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +MakieGallery = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a" ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" Observables = "510215fc-4207-5dde-b226-833fc4488ee2" diff --git a/test/runtests.jl b/test/runtests.jl index 45ed5bbad5b..02366fc6f0c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,4 +1,6 @@ -using MakieGallery, Makie, GLMakie +using MakieGallery, AbstractPlotting, GLMakie + +push!(MakieGallery.plotting_backends, "GLMakie") database = MakieGallery.load_database() # THese examples download additional data - don't want to deal with that! From e524ccc4fcc09a5310e162132b53b26d6bd44934 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 3 Dec 2018 18:23:03 +0100 Subject: [PATCH 0034/1328] dont dev --- Manifest.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Manifest.toml b/Manifest.toml index bc02e7a96a0..84c729b2b23 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -352,7 +352,9 @@ version = "0.4.4" [[MakieGallery]] deps = ["AbstractPlotting", "BinaryProvider", "ColorTypes", "ColorVectorSpace", "Colors", "DataFrames", "Documenter", "FileIO", "FixedPointNumbers", "GDAL", "GeometryTypes", "ImageCore", "ImageFiltering", "ImageMagick", "ImageTransformations", "LinearAlgebra", "Markdown", "MeshIO", "ModernGL", "Pkg", "QuartzImageIO", "RDatasets", "Random", "Statistics", "Test"] -path = "/home/sd/.julia/dev/MakieGallery" +git-tree-sha1 = "bdddff9296888ff20c12bd7f57e4ae64f491c41c" +repo-rev = "master" +repo-url = "https://github.com/JuliaPlots/MakieGallery.jl.git" uuid = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" version = "0.0.1+" From 88b5a52a2a0194b1c5209eec1c2796b0661e151e Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 3 Dec 2018 18:36:08 +0100 Subject: [PATCH 0035/1328] use newest version of MakieGallery --- Manifest.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Manifest.toml b/Manifest.toml index 84c729b2b23..43f779d4e0f 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -352,7 +352,7 @@ version = "0.4.4" [[MakieGallery]] deps = ["AbstractPlotting", "BinaryProvider", "ColorTypes", "ColorVectorSpace", "Colors", "DataFrames", "Documenter", "FileIO", "FixedPointNumbers", "GDAL", "GeometryTypes", "ImageCore", "ImageFiltering", "ImageMagick", "ImageTransformations", "LinearAlgebra", "Markdown", "MeshIO", "ModernGL", "Pkg", "QuartzImageIO", "RDatasets", "Random", "Statistics", "Test"] -git-tree-sha1 = "bdddff9296888ff20c12bd7f57e4ae64f491c41c" +git-tree-sha1 = "8885eed8b027d8a3b1d0b2aa5aaa997ad9df4158" repo-rev = "master" repo-url = "https://github.com/JuliaPlots/MakieGallery.jl.git" uuid = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" From 63d1ff400651fb03d7e6ac8356c5098b1c410b84 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Tue, 4 Dec 2018 10:18:26 +0100 Subject: [PATCH 0036/1328] avoid ambiguity --- src/CairoMakie.jl | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/CairoMakie.jl b/src/CairoMakie.jl index 3615080a1ef..c9c3862c597 100644 --- a/src/CairoMakie.jl +++ b/src/CairoMakie.jl @@ -310,10 +310,6 @@ function draw_atomic(scene::Scene, screen::CairoScreen, primitive::Scatter) nothing end - - - - scale_matrix(x, y) = Cairo.CairoMatrix(x, 0.0, 0.0, y, 0.0, 0.0) function rot_scale_matrix(x, y, q) sx, sy, sz = 2q[4]*q[1], 2q[4]*q[2], 2q[4]*q[3] @@ -459,8 +455,10 @@ function AbstractPlotting.colorbuffer(tup::Tuple{<: CairoBackend, Scene}) AbstractPlotting.backend_display(screen, scene) FileIO.load(screen.path) end -AbstractPlotting.backend_showable(x::CairoBackend, m::MIME"image/svg+xml", scene::SceneLike) = x.typ == SVG -AbstractPlotting.backend_showable(x::CairoBackend, m::MIME"image/png", scene::SceneLike) = x.typ == PNG + + +AbstractPlotting.backend_showable(x::CairoBackend, m::MIME"image/svg+xml", scene::Scene) = x.typ == SVG +AbstractPlotting.backend_showable(x::CairoBackend, m::MIME"image/png", scene::Scene) = x.typ == PNG function AbstractPlotting.backend_show(x::CairoBackend, io::IO, ::MIME"image/svg+xml", scene::Scene) From c205c629be2c55067b318cfcc94ec71bc53d6be3 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Tue, 4 Dec 2018 11:14:38 +0100 Subject: [PATCH 0037/1328] merge @louisponet from JuliaPlots/Makie.jl#235 --- Manifest.toml | 18 ++++++++++++++++-- Project.toml | 1 + src/drawing_primitives.jl | 1 - 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 43f779d4e0f..2c85c6836f7 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -6,8 +6,8 @@ version = "0.3.2" [[AbstractPlotting]] deps = ["ColorBrewer", "ColorTypes", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "UnicodeFun"] -git-tree-sha1 = "8c2b1f93b85ae6e119a9e64df8bf3d82daee5d73" -repo-rev = "sd-manifest" +git-tree-sha1 = "5946b2ffd88af5d7a84afecfb35f1f84b089e9ab" +repo-rev = "master" repo-url = "https://github.com/JuliaPlots/AbstractPlotting.jl.git" uuid = "537997a7-5e4e-5d89-9595-2241ea00577e" version = "0.9.0" @@ -235,6 +235,12 @@ git-tree-sha1 = "035e2b5e9c335afae1e92ecfe532cf0620da869f" uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" version = "2.3.0" +[[GLMakie]] +deps = ["AbstractPlotting", "AxisArrays", "ColorBrewer", "ColorTypes", "ColorVectorSpace", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GLFW", "GeometryTypes", "ImageAxes", "ImageCore", "ImageMagick", "ImageTransformations", "IndirectArrays", "IntervalSets", "IterTools", "LinearAlgebra", "Makie", "Markdown", "ModernGL", "Observables", "Pkg", "PlotUtils", "Primes", "Printf", "QuartzImageIO", "Serialization", "Showoff", "StaticArrays", "UnicodeFun"] +git-tree-sha1 = "2e3cb969fd8f8cab98a4863d4a97d24bb1efdbd0" +uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" +version = "0.0.1" + [[GeometryTypes]] deps = ["ColorTypes", "FixedPointNumbers", "IterTools", "LinearAlgebra", "StaticArrays", "Test"] git-tree-sha1 = "28b193e14466beecf928449e0f8505ff6de3709d" @@ -350,6 +356,14 @@ git-tree-sha1 = "c443e1c8d58a4e9f61b708ad0a88286c7042145b" uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" version = "0.4.4" +[[Makie]] +deps = ["AbstractPlotting", "AxisArrays", "Base64", "ColorBrewer", "ColorTypes", "ColorVectorSpace", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GLFW", "GLMakie", "GeometryTypes", "ImageAxes", "ImageCore", "ImageMagick", "ImageTransformations", "IndirectArrays", "IntervalSets", "IterTools", "LinearAlgebra", "MakieGallery", "ModernGL", "Observables", "Pkg", "PlotUtils", "Primes", "QuartzImageIO", "Showoff", "StaticArrays", "Statistics", "UnicodeFun"] +git-tree-sha1 = "03fa9413877a6740b30cc18a0a3d4cb427ea09f1" +repo-rev = "master" +repo-url = "https://github.com/JuliaPlots/Makie.jl.git" +uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" +version = "0.9.0" + [[MakieGallery]] deps = ["AbstractPlotting", "BinaryProvider", "ColorTypes", "ColorVectorSpace", "Colors", "DataFrames", "Documenter", "FileIO", "FixedPointNumbers", "GDAL", "GeometryTypes", "ImageCore", "ImageFiltering", "ImageMagick", "ImageTransformations", "LinearAlgebra", "Markdown", "MeshIO", "ModernGL", "Pkg", "QuartzImageIO", "RDatasets", "Random", "Statistics", "Test"] git-tree-sha1 = "8885eed8b027d8a3b1d0b2aa5aaa997ad9df4158" diff --git a/Project.toml b/Project.toml index 504191bef5b..f55b9861ecb 100644 --- a/Project.toml +++ b/Project.toml @@ -24,6 +24,7 @@ IndirectArrays = "9b13fd28-a010-5f03-acff-a1bbcff69959" IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" MakieGallery = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a" ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" diff --git a/src/drawing_primitives.jl b/src/drawing_primitives.jl index ffb70578778..e1713b1d006 100644 --- a/src/drawing_primitives.jl +++ b/src/drawing_primitives.jl @@ -405,7 +405,6 @@ function draw_atomic(screen::GLScreen, scene::Scene, vol::Volume) ) convert(Mat4f0, m) * m2 end - delete!(gl_attributes, :color) visualize(vol[4], Style(:default), gl_attributes).children[] end end From 3ac701ee0c683a22e68f18c844560ef0aade29d3 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 5 Dec 2018 13:31:36 +0100 Subject: [PATCH 0038/1328] depend on new abstractplotting + update deps --- Manifest.toml | 28 ++++++---------------------- Project.toml | 11 +++++++++-- REQUIRE | 2 +- 3 files changed, 16 insertions(+), 25 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 2c85c6836f7..724e07183fe 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -5,12 +5,10 @@ uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" version = "0.3.2" [[AbstractPlotting]] -deps = ["ColorBrewer", "ColorTypes", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "UnicodeFun"] -git-tree-sha1 = "5946b2ffd88af5d7a84afecfb35f1f84b089e9ab" -repo-rev = "master" -repo-url = "https://github.com/JuliaPlots/AbstractPlotting.jl.git" +deps = ["ColorBrewer", "ColorTypes", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "Test", "UnicodeFun"] +git-tree-sha1 = "22eb6757f34439a84eff8ca5f4ebcb9a1f221102" uuid = "537997a7-5e4e-5d89-9595-2241ea00577e" -version = "0.9.0" +version = "0.9.1" [[AxisAlgorithms]] deps = ["Compat", "WoodburyMatrices"] @@ -137,9 +135,9 @@ version = "0.2.0" [[DataFrames]] deps = ["CategoricalArrays", "CodecZlib", "Compat", "DataStreams", "Dates", "InteractiveUtils", "IteratorInterfaceExtensions", "LinearAlgebra", "Missings", "Printf", "Random", "Reexport", "SortingAlgorithms", "Statistics", "StatsBase", "TableTraits", "Tables", "Test", "TranscodingStreams", "Unicode", "WeakRefStrings"] -git-tree-sha1 = "dd11f0aed840e305050f4b49f53153d2dd622650" +git-tree-sha1 = "60c2820c9ae93cc33e98cd820e0b449d551c7874" uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -version = "0.15.0" +version = "0.15.1" [[DataStreams]] deps = ["Dates", "Missings", "Test", "WeakRefStrings"] @@ -235,12 +233,6 @@ git-tree-sha1 = "035e2b5e9c335afae1e92ecfe532cf0620da869f" uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" version = "2.3.0" -[[GLMakie]] -deps = ["AbstractPlotting", "AxisArrays", "ColorBrewer", "ColorTypes", "ColorVectorSpace", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GLFW", "GeometryTypes", "ImageAxes", "ImageCore", "ImageMagick", "ImageTransformations", "IndirectArrays", "IntervalSets", "IterTools", "LinearAlgebra", "Makie", "Markdown", "ModernGL", "Observables", "Pkg", "PlotUtils", "Primes", "Printf", "QuartzImageIO", "Serialization", "Showoff", "StaticArrays", "UnicodeFun"] -git-tree-sha1 = "2e3cb969fd8f8cab98a4863d4a97d24bb1efdbd0" -uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" -version = "0.0.1" - [[GeometryTypes]] deps = ["ColorTypes", "FixedPointNumbers", "IterTools", "LinearAlgebra", "StaticArrays", "Test"] git-tree-sha1 = "28b193e14466beecf928449e0f8505ff6de3709d" @@ -356,17 +348,9 @@ git-tree-sha1 = "c443e1c8d58a4e9f61b708ad0a88286c7042145b" uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" version = "0.4.4" -[[Makie]] -deps = ["AbstractPlotting", "AxisArrays", "Base64", "ColorBrewer", "ColorTypes", "ColorVectorSpace", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GLFW", "GLMakie", "GeometryTypes", "ImageAxes", "ImageCore", "ImageMagick", "ImageTransformations", "IndirectArrays", "IntervalSets", "IterTools", "LinearAlgebra", "MakieGallery", "ModernGL", "Observables", "Pkg", "PlotUtils", "Primes", "QuartzImageIO", "Showoff", "StaticArrays", "Statistics", "UnicodeFun"] -git-tree-sha1 = "03fa9413877a6740b30cc18a0a3d4cb427ea09f1" -repo-rev = "master" -repo-url = "https://github.com/JuliaPlots/Makie.jl.git" -uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -version = "0.9.0" - [[MakieGallery]] deps = ["AbstractPlotting", "BinaryProvider", "ColorTypes", "ColorVectorSpace", "Colors", "DataFrames", "Documenter", "FileIO", "FixedPointNumbers", "GDAL", "GeometryTypes", "ImageCore", "ImageFiltering", "ImageMagick", "ImageTransformations", "LinearAlgebra", "Markdown", "MeshIO", "ModernGL", "Pkg", "QuartzImageIO", "RDatasets", "Random", "Statistics", "Test"] -git-tree-sha1 = "8885eed8b027d8a3b1d0b2aa5aaa997ad9df4158" +git-tree-sha1 = "6e7acca4083d433cbc92024f579b387b3b4bbd09" repo-rev = "master" repo-url = "https://github.com/JuliaPlots/MakieGallery.jl.git" uuid = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" diff --git a/Project.toml b/Project.toml index f55b9861ecb..f35d399e6b7 100644 --- a/Project.toml +++ b/Project.toml @@ -5,40 +5,47 @@ version = "0.0.1" [deps] AbstractPlotting = "537997a7-5e4e-5d89-9595-2241ea00577e" AxisArrays = "39de3d68-74b9-583c-8d2d-e117c070f3a9" +BinaryProvider = "b99e7846-7c00-51b0-8f62-c81ae34c0232" ColorBrewer = "a2cac450-b92f-5266-8821-25eda20663c8" ColorTypes = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" ColorVectorSpace = "c3611d14-8923-5661-9e6a-0046d554d3a4" Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" Contour = "d38c429a-6771-53c6-b99e-75d170b6e991" +DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" FixedPointNumbers = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" FreeType = "b38be410-82b0-50bf-ab77-7b57e271db43" FreeTypeAbstraction = "663a7486-cb36-511b-a19d-713bb74d65c9" +GDAL = "add2ef01-049f-52c4-9ee2-e494f65e021a" GLFW = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" GeometryTypes = "4d00f742-c7ba-57c2-abde-4428a4b178cb" ImageAxes = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534" +ImageFiltering = "6a3955dd-da59-5b1f-98d4-e7296123deb5" ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" ImageTransformations = "02fcd773-0e25-5acc-982a-7f6622650795" IndirectArrays = "9b13fd28-a010-5f03-acff-a1bbcff69959" IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" MakieGallery = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a" +MeshIO = "7269a6da-0436-5bbc-96c2-40638cbb6118" ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" Observables = "510215fc-4207-5dde-b226-833fc4488ee2" PlotUtils = "995b91a9-d308-5afd-9ec6-746e21dbc043" Primes = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" QuartzImageIO = "dca85d43-d64c-5e67-8c65-017450d5d020" +RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" Showoff = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" UnicodeFun = "1cfade01-22cf-5700-b092-accc4b62d6e1" [compat] +AbstractPlotting = ">=0.9.1" FreeTypeAbstraction = ">=0.3.0" GLFW = ">=2.3.0" GeometryTypes = ">=0.7.2" @@ -60,4 +67,4 @@ QuartzImageIO = "dca85d43-d64c-5e67-8c65-017450d5d020" RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" [targets] -test = ["ImageCore", "ImageTransformations", "ImageMagick", "ImageMagick", "QuartzImageIO", "Documenter", "ModernGL", "MeshIO", "ImageMagick", "ImageTransformations", "GDAL", "FileIO", "ImageFiltering", "DataFrames", "RDatasets", "MakieGallery"] +test = ["ImageCore", "ImageTransformations", "ImageMagick", "ImageMagick", "QuartzImageIO", "ModernGL", "ImageMagick", "ImageTransformations", "FileIO"] diff --git a/REQUIRE b/REQUIRE index 89921f7d119..0b6f48ecd69 100644 --- a/REQUIRE +++ b/REQUIRE @@ -16,7 +16,7 @@ FreeTypeAbstraction 0.3.0 #for findfont @windows ImageMagick @linux ImageMagick @osx QuartzImageIO -AbstractPlotting +AbstractPlotting 0.9.1 Primes PlotUtils IntervalSets From e462a383719611d3c5dc5fc7e492ef7432a98b4d Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 5 Dec 2018 14:19:18 +0100 Subject: [PATCH 0039/1328] use new MakieGallery --- Manifest.toml | 218 +++++++++++++++++++++++++++++++++++++++++++++++++- Project.toml | 1 + 2 files changed, 218 insertions(+), 1 deletion(-) diff --git a/Manifest.toml b/Manifest.toml index 724e07183fe..037a27559d0 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -10,6 +10,12 @@ git-tree-sha1 = "22eb6757f34439a84eff8ca5f4ebcb9a1f221102" uuid = "537997a7-5e4e-5d89-9595-2241ea00577e" version = "0.9.1" +[[Arpack]] +deps = ["BinaryProvider", "Libdl", "LinearAlgebra", "Random", "SparseArrays", "Test"] +git-tree-sha1 = "1ce1ce9984683f0b6a587d5bdbc688ecb480096f" +uuid = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97" +version = "0.3.0" + [[AxisAlgorithms]] deps = ["Compat", "WoodburyMatrices"] git-tree-sha1 = "99dabbe853e4f641ab21a676131f2cf9fb29937e" @@ -55,6 +61,12 @@ git-tree-sha1 = "b92c6f626a044cc9619156d54994b94084d40abe" uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" version = "0.4.3" +[[Calculus]] +deps = ["Compat"] +git-tree-sha1 = "f60954495a7afcee4136f78d1d60350abd37a409" +uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" +version = "0.4.1" + [[CatIndices]] deps = ["CustomUnitRanges", "OffsetArrays", "Test"] git-tree-sha1 = "254cf73ea369d2e39bfd6c5eb27a2296cfaed68c" @@ -97,6 +109,18 @@ git-tree-sha1 = "9f0a0210450acb91c730b730a994f8eef1d3d543" uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" version = "0.9.5" +[[Combinatorics]] +deps = ["LinearAlgebra", "Polynomials", "Test"] +git-tree-sha1 = "50b3ae4d643dc27eaff69fb6be06ee094d5500c9" +uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +version = "0.7.0" + +[[CommonSubexpressions]] +deps = ["Test"] +git-tree-sha1 = "efdaf19ab11c7889334ca247ff4c9f7c322817b0" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.2.0" + [[Compat]] deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] git-tree-sha1 = "ec61a16eed883ad0cfa002d7489b3ce6d039bb9a" @@ -151,6 +175,12 @@ git-tree-sha1 = "8fc6e166e24fda04b2b648d4260cdad241788c54" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" version = "0.14.0" +[[DataValues]] +deps = ["Dates", "InteractiveUtils", "LinearAlgebra", "Random", "Test"] +git-tree-sha1 = "4fedccda7e5111354c7dcc832c7da83ff7258765" +uuid = "e7dc6d0d-1eca-5fa6-8ad6-5aecde8b7ea5" +version = "0.4.5" + [[Dates]] deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" @@ -159,10 +189,40 @@ uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" deps = ["Mmap"] uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" +[[DiffEqDiffTools]] +deps = ["LinearAlgebra", "Test"] +git-tree-sha1 = "67700c9fc82033ec68a145bc650f6b9debdf9103" +uuid = "01453d9d-ee7c-5054-8395-0335cb756afa" +version = "0.7.1" + +[[DiffResults]] +deps = ["Compat", "StaticArrays"] +git-tree-sha1 = "db8acf46717b13d6c48deb7a12007c7f85a70cf7" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "0.0.3" + +[[DiffRules]] +deps = ["Random", "Test"] +git-tree-sha1 = "c49ec69428ffea0c1d1bbdc63d1a70f5df5860ad" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "0.0.7" + +[[Distances]] +deps = ["LinearAlgebra", "Printf", "Random", "Statistics", "Test"] +git-tree-sha1 = "2f38605722542f1c0a32dd2856fb529d8c226c69" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.7.3" + [[Distributed]] deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" +[[Distributions]] +deps = ["Distributed", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsBase", "StatsFuns", "Test"] +git-tree-sha1 = "c24e9b6500c037673f0241a2783472b8c3d080c7" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.16.4" + [[DocStringExtensions]] deps = ["LibGit2", "Markdown", "Pkg", "Test"] git-tree-sha1 = "1df01539a1c952cef21f2d2d1c092c2bcf0177d7" @@ -205,6 +265,12 @@ git-tree-sha1 = "b8045033701c3b10bf2324d7203404be7aef88ba" uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" version = "0.5.3" +[[ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "InteractiveUtils", "LinearAlgebra", "NaNMath", "Random", "SparseArrays", "SpecialFunctions", "StaticArrays", "Test"] +git-tree-sha1 = "b91250044374764e7c29af59a774c4b8d6100b6e" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "0.10.1" + [[FreeType]] deps = ["BinaryProvider", "Libdl", "Pkg", "Test"] git-tree-sha1 = "06462b9d5aca708d764d16e5ba6a83ba7b753d57" @@ -217,6 +283,12 @@ git-tree-sha1 = "271ef13438bd0946950fd34d9241e5beefd6d4b3" uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" version = "0.4.1" +[[FreqTables]] +deps = ["CategoricalArrays", "NamedArrays", "Tables", "Test"] +git-tree-sha1 = "93ce75cae27c2d1c6518771d597b6dd0a3d623d3" +uuid = "da1fdf0e-e0ff-5433-a45f-9bb5ff651cb1" +version = "0.3.1" + [[Future]] deps = ["Random"] uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" @@ -289,6 +361,12 @@ git-tree-sha1 = "18ae1c0a8df31549a9452ceac93751d4aa166071" uuid = "02fcd773-0e25-5acc-982a-7f6622650795" version = "0.7.1" +[[IndexedTables]] +deps = ["DataValues", "Dates", "IteratorInterfaceExtensions", "LinearAlgebra", "OnlineStats", "PooledArrays", "Random", "Serialization", "SparseArrays", "Statistics", "TableTraits", "TableTraitsUtils", "Test", "WeakRefStrings"] +git-tree-sha1 = "cb4406eeed8729f8179940d39e6dec5598971341" +uuid = "6deec6e2-d858-57c5-ab9b-e6ca5bd20e43" +version = "0.8.1" + [[IndirectArrays]] deps = ["Compat", "Test"] git-tree-sha1 = "b6e249be10a3381b2c72ac82f2d13d70067cb2bd" @@ -329,19 +407,49 @@ git-tree-sha1 = "1f7a25b53ec67f5e9422f1f551ee216503f4a0fa" uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" version = "0.20.0" +[[KernelDensity]] +deps = ["Distributions", "FFTW", "Interpolations", "Optim", "StatsBase", "Test"] +git-tree-sha1 = "c1048817fe5711f699abc8fabd47b1ac6ba4db04" +uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" +version = "0.5.1" + +[[LearnBase]] +deps = ["LinearAlgebra", "SparseArrays", "StatsBase", "Test"] +git-tree-sha1 = "c4b5da6d68517f46f70ed5157b28336b56cd2ff3" +uuid = "7f8f8fb0-2700-5f03-b4bd-41f8cfc144b6" +version = "0.2.2" + [[LibGit2]] uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" [[Libdl]] uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +[[LineSearches]] +deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf", "Test"] +git-tree-sha1 = "54eb90e8dbe745d617c78dee1d6ae95c7f6f5779" +uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" +version = "7.0.1" + [[LinearAlgebra]] deps = ["Libdl"] uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +[[Loess]] +deps = ["Distances", "Random", "Statistics", "Test"] +git-tree-sha1 = "0ee46caf683a422b595be4dfaed6cda28f541e25" +uuid = "4345ca2d-374a-55d4-8d30-97f9976e7612" +version = "0.5.0" + [[Logging]] uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" +[[LossFunctions]] +deps = ["InteractiveUtils", "LearnBase", "Markdown", "Random", "RecipesBase", "SparseArrays", "Statistics", "StatsBase", "Test"] +git-tree-sha1 = "b97d2e9a527733649d0205d3374d0daee352c50e" +uuid = "30fc2ffe-d236-52d8-8643-a9d8f7c094a7" +version = "0.5.0" + [[MacroTools]] deps = ["Compat"] git-tree-sha1 = "c443e1c8d58a4e9f61b708ad0a88286c7042145b" @@ -350,7 +458,7 @@ version = "0.4.4" [[MakieGallery]] deps = ["AbstractPlotting", "BinaryProvider", "ColorTypes", "ColorVectorSpace", "Colors", "DataFrames", "Documenter", "FileIO", "FixedPointNumbers", "GDAL", "GeometryTypes", "ImageCore", "ImageFiltering", "ImageMagick", "ImageTransformations", "LinearAlgebra", "Markdown", "MeshIO", "ModernGL", "Pkg", "QuartzImageIO", "RDatasets", "Random", "Statistics", "Test"] -git-tree-sha1 = "6e7acca4083d433cbc92024f579b387b3b4bbd09" +git-tree-sha1 = "2563a69f1a9c43cf0647127a506ba32782e9c45a" repo-rev = "master" repo-url = "https://github.com/JuliaPlots/MakieGallery.jl.git" uuid = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" @@ -393,12 +501,24 @@ git-tree-sha1 = "f4f8fa8d04d3c1e7294f07fc37586c819466ad38" uuid = "66fc600b-dfda-50eb-8b99-91cfa97b1301" version = "1.0.0" +[[NLSolversBase]] +deps = ["Calculus", "DiffEqDiffTools", "DiffResults", "Distributed", "ForwardDiff", "LinearAlgebra", "Random", "SparseArrays", "Test"] +git-tree-sha1 = "ebfb2e96970151753575b9c4d31d47e5ae8382a5" +uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" +version = "7.1.1" + [[NaNMath]] deps = ["Compat"] git-tree-sha1 = "ce3b85e484a5d4c71dd5316215069311135fa9f2" uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" version = "0.3.2" +[[NamedArrays]] +deps = ["Combinatorics", "DataStructures", "DelimitedFiles", "LinearAlgebra", "Random", "Requires", "SparseArrays", "Statistics", "Test"] +git-tree-sha1 = "977c65d68cee14ab28198e89ebc125d0738ef250" +uuid = "86f7a689-2022-50b4-a561-43c23ac3c673" +version = "0.9.2" + [[Nullables]] deps = ["Compat"] git-tree-sha1 = "ae1a63457e14554df2159b0b028f48536125092d" @@ -417,12 +537,36 @@ git-tree-sha1 = "f446248f2dfbc13039a0b90994dd25b059b01eab" uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" version = "0.9.0" +[[OnlineStats]] +deps = ["DataStructures", "Dates", "LearnBase", "LinearAlgebra", "LossFunctions", "OnlineStatsBase", "PenaltyFunctions", "Random", "RecipesBase", "Reexport", "Statistics", "StatsBase", "SweepOperator", "Test"] +git-tree-sha1 = "70fe5cbb31d37c18f6312a2994c31b782be50607" +uuid = "a15396b6-48d5-5d58-9928-6d29437db91e" +version = "0.19.2" + +[[OnlineStatsBase]] +deps = ["LearnBase", "Test"] +git-tree-sha1 = "520580a74e09378fb6665fa89339323d411d3df3" +uuid = "925886fa-5bf2-5e8e-b522-a9147a512338" +version = "0.9.1" + +[[Optim]] +deps = ["Calculus", "DiffEqDiffTools", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "Random", "SparseArrays", "StatsBase", "Test"] +git-tree-sha1 = "0f2a6c6ff9db396cc7af15bb1cf057a26662ff17" +uuid = "429524aa-4258-5aef-a3af-852621145aeb" +version = "0.17.2" + [[OrderedCollections]] deps = ["Random", "Serialization", "Test"] git-tree-sha1 = "85619a3f3e17bb4761fe1b1fd47f0e979f964d5b" uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" version = "1.0.2" +[[PDMats]] +deps = ["Arpack", "LinearAlgebra", "SparseArrays", "SuiteSparse", "Test"] +git-tree-sha1 = "b6c91fc0ab970c0563cbbe69af18d741a49ce551" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.9.6" + [[Packing]] deps = ["GeometryTypes", "Test"] git-tree-sha1 = "bc7c284233cf0518933bf9977e3e8234efcc1c30" @@ -447,6 +591,12 @@ git-tree-sha1 = "949ca36d47010bee093254467166487c921d490b" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" version = "0.2.14" +[[PenaltyFunctions]] +deps = ["InteractiveUtils", "LearnBase", "LinearAlgebra", "RecipesBase", "Reexport", "Test"] +git-tree-sha1 = "b0baaa5218ca0ffd6a8ae37ef0b58e0df688ac8b" +uuid = "06bb1623-fdd5-5ca2-a01c-88eae3ea319e" +version = "0.1.2" + [[Pkg]] deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" @@ -457,6 +607,24 @@ git-tree-sha1 = "fd28f30a294a38ec847de95d8ac7ac916ccd7c06" uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" version = "0.5.5" +[[Polynomials]] +deps = ["LinearAlgebra", "SparseArrays", "Test"] +git-tree-sha1 = "1a1eae52956658a6acae6fa1b6d6c3d488192895" +uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" +version = "0.5.1" + +[[PooledArrays]] +deps = ["Test"] +git-tree-sha1 = "5c5ded7adc52867f599c21d3f43542fce491afda" +uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" +version = "0.4.1" + +[[PositiveFactorizations]] +deps = ["LinearAlgebra", "Test"] +git-tree-sha1 = "86ae7329c4b5c266acf5c7c524a972300d991e1c" +uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" +version = "0.2.1" + [[Primes]] deps = ["Test"] git-tree-sha1 = "ff1a2323cb468ec5f201838fcbe3c232266b1f95" @@ -471,6 +639,12 @@ uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" deps = ["Printf"] uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" +[[QuadGK]] +deps = ["DataStructures", "LinearAlgebra", "Test"] +git-tree-sha1 = "7e8dff9c205f36eceaf6e62a43ff851637ca45fc" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.0.2" + [[QuartzImageIO]] deps = ["ColorTypes", "ColorVectorSpace", "FileIO", "FixedPointNumbers", "ImageCore", "Libdl", "Random", "Test"] git-tree-sha1 = "c747a56f223919b157e6cd9dc58d59c560586302" @@ -509,6 +683,12 @@ git-tree-sha1 = "fd159bead0a24e6270fd0573a340312bd4645cc2" uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" version = "0.3.0" +[[RecipesBase]] +deps = ["Random", "Test"] +git-tree-sha1 = "0b3cb370ee4dc00f47f1193101600949f3dcf884" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "0.6.0" + [[Reexport]] deps = ["Pkg"] git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" @@ -521,6 +701,12 @@ git-tree-sha1 = "f6fbf4ba64d295e146e49e021207993b6b48c7d1" uuid = "ae029012-a4dd-5104-9daa-d747884805df" version = "0.5.2" +[[Rmath]] +deps = ["BinaryProvider", "Libdl", "Random", "Statistics", "Test"] +git-tree-sha1 = "9a6c758cdf73036c3239b0afbea790def1dabff9" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.5.0" + [[Rotations]] deps = ["LinearAlgebra", "Random", "StaticArrays", "Statistics", "Test"] git-tree-sha1 = "b629771d0de88979cbdbf72ceddc54de58fde149" @@ -590,12 +776,42 @@ git-tree-sha1 = "2722397d88f8ffef551948f6c20e1d74a743298c" uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" version = "0.26.0" +[[StatsFuns]] +deps = ["Rmath", "SpecialFunctions", "Test"] +git-tree-sha1 = "d14bb7b03defd2deaa5675646f6783089e0556f0" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "0.7.0" + +[[StatsMakie]] +deps = ["AbstractPlotting", "Distributions", "FreqTables", "IndexedTables", "IntervalSets", "KernelDensity", "Loess", "NamedArrays", "Observables", "Random", "Statistics", "StatsBase", "Tables", "Test"] +git-tree-sha1 = "8694f16862d3d80cf59edf7900de2d19a51aa4b0" +repo-rev = "master" +repo-url = "https://github.com/JuliaPlots/StatsMakie.jl.git" +uuid = "9d48ccf0-4268-5716-84ff-21228f561db3" +version = "0.0.0" + +[[SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[SweepOperator]] +deps = ["LinearAlgebra", "Test"] +git-tree-sha1 = "2039aaa96f7b21634a1b3246cb2699dd1d26d473" +uuid = "7522ee7d-7047-56d0-94d9-4bc626e7058d" +version = "0.2.0" + [[TableTraits]] deps = ["IteratorInterfaceExtensions", "Test"] git-tree-sha1 = "da062a2c31f16178f68190243c24140801720a43" uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" version = "0.4.0" +[[TableTraitsUtils]] +deps = ["DataValues", "IteratorInterfaceExtensions", "Missings", "TableTraits", "Test"] +git-tree-sha1 = "a355f1882d64881a11f853e64dcc353975c4df6e" +uuid = "382cd787-c1b6-5bf2-a167-d5b971a19bda" +version = "0.3.1" + [[Tables]] deps = ["Requires", "Test"] git-tree-sha1 = "940944e6b68a35046282897a2218891c7cf14a32" diff --git a/Project.toml b/Project.toml index f35d399e6b7..65cdcee487b 100644 --- a/Project.toml +++ b/Project.toml @@ -42,6 +42,7 @@ RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" Showoff = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" +StatsMakie = "9d48ccf0-4268-5716-84ff-21228f561db3" UnicodeFun = "1cfade01-22cf-5700-b092-accc4b62d6e1" [compat] From b521c3f12f8fd09871b66cf4a6456037907439d8 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 5 Dec 2018 18:48:56 +0100 Subject: [PATCH 0040/1328] update versions --- Manifest.toml | 24 ++++++++---------------- Project.toml | 1 - REQUIRE | 2 +- 3 files changed, 9 insertions(+), 18 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 2b8c539e3d7..d3601d89b48 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -5,12 +5,12 @@ uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" version = "0.3.2" [[AbstractPlotting]] -deps = ["ColorBrewer", "ColorTypes", "Colors", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "Test", "UnicodeFun"] -git-tree-sha1 = "0e969852e9c20f24ad6ef705faa8db32f0990238" +deps = ["ColorBrewer", "ColorTypes", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "UnicodeFun"] +git-tree-sha1 = "7bc92ab8d600d279c402df1d0dbe5614e578cce6" repo-rev = "master" repo-url = "https://github.com/JuliaPlots/AbstractPlotting.jl.git" uuid = "537997a7-5e4e-5d89-9595-2241ea00577e" -version = "0.9.0+" +version = "0.9.1" [[AxisAlgorithms]] deps = ["Compat", "WoodburyMatrices"] @@ -261,7 +261,7 @@ git-tree-sha1 = "709ad3a31bb045cbfd706159fbe8fae4d00e091c" repo-rev = "sd-bb" repo-url = "https://github.com/JuliaGeometry/GeometryTypes.jl.git" uuid = "4d00f742-c7ba-57c2-abde-4428a4b178cb" -version = "0.7.1+" +version = "0.7.2+" [[Graphics]] deps = ["Colors", "Compat", "NaNMath"] @@ -394,17 +394,9 @@ git-tree-sha1 = "c443e1c8d58a4e9f61b708ad0a88286c7042145b" uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" version = "0.4.4" -[[Makie]] -deps = ["AbstractPlotting", "AxisArrays", "Base64", "ColorBrewer", "ColorTypes", "ColorVectorSpace", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GLFW", "GLMakie", "GeometryTypes", "ImageAxes", "ImageCore", "ImageMagick", "ImageTransformations", "IndirectArrays", "IntervalSets", "IterTools", "LinearAlgebra", "ModernGL", "Observables", "Pkg", "PlotUtils", "Primes", "QuartzImageIO", "Showoff", "StaticArrays", "Statistics", "UnicodeFun"] -git-tree-sha1 = "a49ae5834b605a14447e04d57a07cbb80ebe8add" -repo-rev = "master" -repo-url = "https://github.com/JuliaPlots/Makie.jl.git" -uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -version = "0.9.0+" - [[MakieGallery]] -deps = ["AbstractPlotting", "BinaryProvider", "ColorTypes", "ColorVectorSpace", "Colors", "DataFrames", "Documenter", "FileIO", "FixedPointNumbers", "GDAL", "GeometryTypes", "ImageCore", "ImageFiltering", "ImageMagick", "ImageTransformations", "LinearAlgebra", "Makie", "Markdown", "MeshIO", "ModernGL", "Pkg", "QuartzImageIO", "RDatasets", "Random", "Statistics", "Test"] -git-tree-sha1 = "178252e975f92c3e11a4478577ec4a4faff4119d" +deps = ["AbstractPlotting", "BinaryProvider", "ColorTypes", "ColorVectorSpace", "Colors", "DataFrames", "Documenter", "FileIO", "FixedPointNumbers", "GDAL", "GeometryTypes", "ImageCore", "ImageFiltering", "ImageMagick", "ImageTransformations", "LinearAlgebra", "Markdown", "MeshIO", "ModernGL", "Pkg", "QuartzImageIO", "RDatasets", "Random", "Statistics", "Test"] +git-tree-sha1 = "2563a69f1a9c43cf0647127a506ba32782e9c45a" repo-rev = "master" repo-url = "https://github.com/JuliaPlots/MakieGallery.jl.git" uuid = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" @@ -652,9 +644,9 @@ version = "0.4.0" [[Tables]] deps = ["Requires", "Test"] -git-tree-sha1 = "c7fb447deab835fa70ce6717e78c68b0f466a42c" +git-tree-sha1 = "940944e6b68a35046282897a2218891c7cf14a32" uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "0.1.11" +version = "0.1.12" [[Test]] deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] diff --git a/Project.toml b/Project.toml index b2294898ca5..66f6339ac97 100644 --- a/Project.toml +++ b/Project.toml @@ -16,7 +16,6 @@ ImageFiltering = "6a3955dd-da59-5b1f-98d4-e7296123deb5" ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" ImageTransformations = "02fcd773-0e25-5acc-982a-7f6622650795" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" MakieGallery = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" MeshIO = "7269a6da-0436-5bbc-96c2-40638cbb6118" RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" diff --git a/REQUIRE b/REQUIRE index 33888afb862..4a40558f26f 100644 --- a/REQUIRE +++ b/REQUIRE @@ -2,7 +2,7 @@ julia 0.7 StaticArrays 0.6.6 GeometryTypes 0.4.5 -AbstractPlotting +AbstractPlotting 0.9.1 Cairo Colors Makie From fd36531d7a5188d5da2a90d997c4ea8ae7c620d0 Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 5 Dec 2018 23:20:05 +0100 Subject: [PATCH 0041/1328] move statsmakie to test dependencies --- Project.toml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index 65cdcee487b..81b4c6150e3 100644 --- a/Project.toml +++ b/Project.toml @@ -42,7 +42,7 @@ RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" Showoff = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" -StatsMakie = "9d48ccf0-4268-5716-84ff-21228f561db3" + UnicodeFun = "1cfade01-22cf-5700-b092-accc4b62d6e1" [compat] @@ -66,6 +66,7 @@ MeshIO = "7269a6da-0436-5bbc-96c2-40638cbb6118" ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" QuartzImageIO = "dca85d43-d64c-5e67-8c65-017450d5d020" RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" +StatsMakie = "9d48ccf0-4268-5716-84ff-21228f561db3" [targets] -test = ["ImageCore", "ImageTransformations", "ImageMagick", "ImageMagick", "QuartzImageIO", "ModernGL", "ImageMagick", "ImageTransformations", "FileIO"] +test = ["StatsMakie", "ImageCore", "ImageTransformations", "ImageMagick", "ImageMagick", "QuartzImageIO", "ModernGL", "ImageMagick", "ImageTransformations", "FileIO"] From 7b272cda05fccb6855a36687979c5e356e16cc2f Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Thu, 6 Dec 2018 00:15:14 +0100 Subject: [PATCH 0042/1328] fix marker offset --- src/CairoMakie.jl | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/CairoMakie.jl b/src/CairoMakie.jl index c9c3862c597..8c728c7d4c2 100644 --- a/src/CairoMakie.jl +++ b/src/CairoMakie.jl @@ -269,18 +269,21 @@ end function draw_marker(ctx, marker, pos, scale, color, strokecolor, strokewidth) Cairo.set_source_rgba(ctx, color...) + pos += Point2f0(scale[1] / 2, -scale[2] / 2) Cairo.arc(ctx, pos[1], pos[2], scale[1] / 2, 0, 2*pi) Cairo.fill(ctx) sc = to_color(strokecolor) - Cairo.set_source_rgba(ctx, red(sc), green(sc), blue(sc), alpha(sc)) - Cairo.set_line_width(ctx, Float64(strokewidth)) - Cairo.arc(ctx, pos[1], pos[2], scale[1], 0, 2*pi) - Cairo.stroke(ctx) + if strokewidth > 0.0 + Cairo.set_source_rgba(ctx, red(sc), green(sc), blue(sc), alpha(sc)) + Cairo.set_line_width(ctx, Float64(strokewidth)) + Cairo.stroke(ctx) + end end function draw_marker(ctx, marker::Union{Rect, Type{<: Rect}}, pos, scale, color, strokecolor, strokewidth) Cairo.set_source_rgba(ctx, color...) - Cairo.rectangle(ctx, pos..., scale[1], -scale[2]) + s2 = Point2f0(scale[1], -scale[2]) + Cairo.rectangle(ctx, pos..., s2...) Cairo.fill(ctx); if strokewidth > 0.0 sc = to_color(strokecolor) @@ -292,19 +295,20 @@ end function draw_atomic(scene::Scene, screen::CairoScreen, primitive::Scatter) fields = @get_attribute(primitive, (color, markersize, strokecolor, strokewidth, marker, marker_offset)) + @get_attribute(primitive, (transform_marker,)) + cmap = get(primitive, :colormap, nothing) |> to_value |> to_colormap crange = get(primitive, :colorrange, nothing) |> to_value ctx = screen.context model = primitive[:model][] positions = primitive[1][] isempty(positions) && return + size_model = transform_marker ? model : Mat4f0(I) broadcast_foreach(primitive[1][], fields...) do point, c, markersize, strokecolor, strokewidth, marker, mo - # TODO: Implement marker - # TODO: Accept :radius field or similar? - scale = project_scale(scene, markersize, model) + scale = project_scale(scene, markersize, size_model) pos = project_position(scene, point, model) - mo = project_scale(scene, mo) - pos += mo + mo = project_scale(scene, mo, size_model) + pos += Point2f0(mo[1], -mo[2]) draw_marker(ctx, marker, pos, scale, extract_color(cmap, crange, c), strokecolor, strokewidth) end nothing From 25d97153c9b5c1c4f9d6daf77e0c6cfa8c3b4772 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Thu, 6 Dec 2018 10:39:16 +0100 Subject: [PATCH 0043/1328] clean up deps --- Manifest.toml | 8 +++----- Project.toml | 6 +----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 037a27559d0..b1d236f0710 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -308,10 +308,8 @@ version = "2.3.0" [[GeometryTypes]] deps = ["ColorTypes", "FixedPointNumbers", "IterTools", "LinearAlgebra", "StaticArrays", "Test"] git-tree-sha1 = "28b193e14466beecf928449e0f8505ff6de3709d" -repo-rev = "sd-bb" -repo-url = "https://github.com/JuliaGeometry/GeometryTypes.jl.git" uuid = "4d00f742-c7ba-57c2-abde-4428a4b178cb" -version = "0.7.2+" +version = "0.7.2" [[Graphics]] deps = ["Colors", "Compat", "NaNMath"] @@ -784,9 +782,9 @@ version = "0.7.0" [[StatsMakie]] deps = ["AbstractPlotting", "Distributions", "FreqTables", "IndexedTables", "IntervalSets", "KernelDensity", "Loess", "NamedArrays", "Observables", "Random", "Statistics", "StatsBase", "Tables", "Test"] -git-tree-sha1 = "8694f16862d3d80cf59edf7900de2d19a51aa4b0" +git-tree-sha1 = "12429b8d5308b27483f4d6148cefb86080e4d054" repo-rev = "master" -repo-url = "https://github.com/JuliaPlots/StatsMakie.jl.git" +repo-url = "https://github.com/JuliaPlots/StatsMakie.jl" uuid = "9d48ccf0-4268-5716-84ff-21228f561db3" version = "0.0.0" diff --git a/Project.toml b/Project.toml index 81b4c6150e3..de6fa5ee3d3 100644 --- a/Project.toml +++ b/Project.toml @@ -29,7 +29,6 @@ IndirectArrays = "9b13fd28-a010-5f03-acff-a1bbcff69959" IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -MakieGallery = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a" MeshIO = "7269a6da-0436-5bbc-96c2-40638cbb6118" ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" @@ -42,7 +41,6 @@ RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" Showoff = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - UnicodeFun = "1cfade01-22cf-5700-b092-accc4b62d6e1" [compat] @@ -54,8 +52,6 @@ StaticArrays = ">=0.6.6" [extras] DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" GDAL = "add2ef01-049f-52c4-9ee2-e494f65e021a" ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534" ImageFiltering = "6a3955dd-da59-5b1f-98d4-e7296123deb5" @@ -69,4 +65,4 @@ RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" StatsMakie = "9d48ccf0-4268-5716-84ff-21228f561db3" [targets] -test = ["StatsMakie", "ImageCore", "ImageTransformations", "ImageMagick", "ImageMagick", "QuartzImageIO", "ModernGL", "ImageMagick", "ImageTransformations", "FileIO"] +test = ["DataFrames", "GDAL", "MakieGallery", "MeshIO", "RDatasets", "StatsMakie", "ImageCore", "ImageTransformations", "ImageMagick", "QuartzImageIO", "ModernGL", "ImageMagick", "ImageTransformations"] From 7f2f158e07a536c947d76ffdec828715e459731c Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Thu, 6 Dec 2018 11:12:48 +0100 Subject: [PATCH 0044/1328] clean up deps --- Manifest.toml | 288 +++++++++++++++++++++++++++++++++++++------------- Project.toml | 23 +++- 2 files changed, 236 insertions(+), 75 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index d3601d89b48..091d8336a20 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -5,25 +5,23 @@ uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" version = "0.3.2" [[AbstractPlotting]] -deps = ["ColorBrewer", "ColorTypes", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "UnicodeFun"] -git-tree-sha1 = "7bc92ab8d600d279c402df1d0dbe5614e578cce6" -repo-rev = "master" -repo-url = "https://github.com/JuliaPlots/AbstractPlotting.jl.git" +deps = ["ColorBrewer", "ColorTypes", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "Test", "UnicodeFun"] +git-tree-sha1 = "22eb6757f34439a84eff8ca5f4ebcb9a1f221102" uuid = "537997a7-5e4e-5d89-9595-2241ea00577e" version = "0.9.1" +[[Arpack]] +deps = ["BinaryProvider", "Libdl", "LinearAlgebra", "Random", "SparseArrays", "Test"] +git-tree-sha1 = "1ce1ce9984683f0b6a587d5bdbc688ecb480096f" +uuid = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97" +version = "0.3.0" + [[AxisAlgorithms]] deps = ["Compat", "WoodburyMatrices"] git-tree-sha1 = "99dabbe853e4f641ab21a676131f2cf9fb29937e" uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" version = "0.3.0" -[[AxisArrays]] -deps = ["Compat", "Dates", "IntervalSets", "IterTools", "Random", "RangeArrays", "Test"] -git-tree-sha1 = "2e2536e9e6f27c4f8d09d8442b61a7ae0b910c28" -uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" -version = "0.3.0" - [[Base64]] uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" @@ -45,18 +43,6 @@ git-tree-sha1 = "5d55b9486590fdda5905c275bb21ce1f0754020f" uuid = "e1450e63-4bb3-523b-b2a4-4ffa8c0fd77d" version = "1.0.0" -[[CMake]] -deps = ["BinDeps", "Libdl", "Test"] -git-tree-sha1 = "74853a75c26a4a73ac391ee26ee29ebeb5583d9f" -uuid = "631607c0-34d2-5d66-819e-eb0f9aa2061a" -version = "1.1.0" - -[[CMakeWrapper]] -deps = ["BinDeps", "CMake", "Libdl", "Parameters", "Test"] -git-tree-sha1 = "2b43d451639984e3571951cc687b8509b0a86c6d" -uuid = "d5fb7624-851a-54ee-a528-d3f3bac0b4a0" -version = "0.2.2" - [[CSV]] deps = ["CategoricalArrays", "DataFrames", "DataStreams", "Dates", "Mmap", "Parsers", "Profile", "Random", "Tables", "Test", "Unicode", "WeakRefStrings"] git-tree-sha1 = "b92c6f626a044cc9619156d54994b94084d40abe" @@ -69,6 +55,12 @@ git-tree-sha1 = "a427098d5aa2808504d94b8ed9fc5740ceaf71d0" uuid = "159f3aea-2a34-519c-b102-8c37f9878175" version = "0.5.6" +[[Calculus]] +deps = ["Compat"] +git-tree-sha1 = "f60954495a7afcee4136f78d1d60350abd37a409" +uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" +version = "0.4.1" + [[CatIndices]] deps = ["CustomUnitRanges", "OffsetArrays", "Test"] git-tree-sha1 = "254cf73ea369d2e39bfd6c5eb27a2296cfaed68c" @@ -111,6 +103,18 @@ git-tree-sha1 = "9f0a0210450acb91c730b730a994f8eef1d3d543" uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" version = "0.9.5" +[[Combinatorics]] +deps = ["LinearAlgebra", "Polynomials", "Test"] +git-tree-sha1 = "50b3ae4d643dc27eaff69fb6be06ee094d5500c9" +uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +version = "0.7.0" + +[[CommonSubexpressions]] +deps = ["Test"] +git-tree-sha1 = "efdaf19ab11c7889334ca247ff4c9f7c322817b0" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.2.0" + [[Compat]] deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] git-tree-sha1 = "ec61a16eed883ad0cfa002d7489b3ce6d039bb9a" @@ -165,6 +169,12 @@ git-tree-sha1 = "8fc6e166e24fda04b2b648d4260cdad241788c54" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" version = "0.14.0" +[[DataValues]] +deps = ["Dates", "InteractiveUtils", "LinearAlgebra", "Random", "Test"] +git-tree-sha1 = "4fedccda7e5111354c7dcc832c7da83ff7258765" +uuid = "e7dc6d0d-1eca-5fa6-8ad6-5aecde8b7ea5" +version = "0.4.5" + [[Dates]] deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" @@ -173,10 +183,40 @@ uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" deps = ["Mmap"] uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" +[[DiffEqDiffTools]] +deps = ["LinearAlgebra", "Test"] +git-tree-sha1 = "67700c9fc82033ec68a145bc650f6b9debdf9103" +uuid = "01453d9d-ee7c-5054-8395-0335cb756afa" +version = "0.7.1" + +[[DiffResults]] +deps = ["Compat", "StaticArrays"] +git-tree-sha1 = "db8acf46717b13d6c48deb7a12007c7f85a70cf7" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "0.0.3" + +[[DiffRules]] +deps = ["Random", "Test"] +git-tree-sha1 = "c49ec69428ffea0c1d1bbdc63d1a70f5df5860ad" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "0.0.7" + +[[Distances]] +deps = ["LinearAlgebra", "Printf", "Random", "Statistics", "Test"] +git-tree-sha1 = "2f38605722542f1c0a32dd2856fb529d8c226c69" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.7.3" + [[Distributed]] deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" +[[Distributions]] +deps = ["Distributed", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsBase", "StatsFuns", "Test"] +git-tree-sha1 = "c24e9b6500c037673f0241a2783472b8c3d080c7" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.16.4" + [[DocStringExtensions]] deps = ["LibGit2", "Markdown", "Pkg", "Test"] git-tree-sha1 = "1df01539a1c952cef21f2d2d1c092c2bcf0177d7" @@ -219,6 +259,12 @@ git-tree-sha1 = "b8045033701c3b10bf2324d7203404be7aef88ba" uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" version = "0.5.3" +[[ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "InteractiveUtils", "LinearAlgebra", "NaNMath", "Random", "SparseArrays", "SpecialFunctions", "StaticArrays", "Test"] +git-tree-sha1 = "b91250044374764e7c29af59a774c4b8d6100b6e" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "0.10.1" + [[FreeType]] deps = ["BinaryProvider", "Libdl", "Pkg", "Test"] git-tree-sha1 = "06462b9d5aca708d764d16e5ba6a83ba7b753d57" @@ -231,6 +277,12 @@ git-tree-sha1 = "271ef13438bd0946950fd34d9241e5beefd6d4b3" uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" version = "0.4.1" +[[FreqTables]] +deps = ["CategoricalArrays", "NamedArrays", "Tables", "Test"] +git-tree-sha1 = "93ce75cae27c2d1c6518771d597b6dd0a3d623d3" +uuid = "da1fdf0e-e0ff-5433-a45f-9bb5ff651cb1" +version = "0.3.1" + [[Future]] deps = ["Random"] uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" @@ -241,27 +293,11 @@ git-tree-sha1 = "100429098b7ec9930f7db9ba68aee3495365be24" uuid = "add2ef01-049f-52c4-9ee2-e494f65e021a" version = "0.2.0" -[[GLFW]] -deps = ["BinDeps", "CMakeWrapper", "Homebrew", "Libdl", "Test"] -git-tree-sha1 = "035e2b5e9c335afae1e92ecfe532cf0620da869f" -uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" -version = "2.3.0" - -[[GLMakie]] -deps = ["AbstractPlotting", "AxisArrays", "ColorBrewer", "ColorTypes", "ColorVectorSpace", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GLFW", "GeometryTypes", "ImageAxes", "ImageCore", "ImageMagick", "ImageTransformations", "IndirectArrays", "IntervalSets", "IterTools", "LinearAlgebra", "Markdown", "ModernGL", "Observables", "PlotUtils", "Primes", "Printf", "QuartzImageIO", "Serialization", "Showoff", "StaticArrays", "UnicodeFun"] -git-tree-sha1 = "e5ee5b645d066c14df1f1fad57cc8e2965a72ab6" -repo-rev = "sd-tests" -repo-url = "https://github.com/JuliaPlots/GLMakie.jl.git" -uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" -version = "0.0.1+" - [[GeometryTypes]] deps = ["ColorTypes", "FixedPointNumbers", "IterTools", "LinearAlgebra", "StaticArrays", "Test"] -git-tree-sha1 = "709ad3a31bb045cbfd706159fbe8fae4d00e091c" -repo-rev = "sd-bb" -repo-url = "https://github.com/JuliaGeometry/GeometryTypes.jl.git" +git-tree-sha1 = "28b193e14466beecf928449e0f8505ff6de3709d" uuid = "4d00f742-c7ba-57c2-abde-4428a4b178cb" -version = "0.7.2+" +version = "0.7.2" [[Graphics]] deps = ["Colors", "Compat", "NaNMath"] @@ -287,12 +323,6 @@ git-tree-sha1 = "f5ca23a08397288924a7535cd898d8ccbcde5ba5" uuid = "bbac6d45-d8f3-5730-bfe4-7a449cd117ca" version = "0.2.0" -[[ImageAxes]] -deps = ["AxisArrays", "Colors", "FixedPointNumbers", "ImageCore", "MappedArrays", "Reexport", "SimpleTraits", "Test"] -git-tree-sha1 = "5735ec90843acaa67a4624611921c686cdf4efbf" -uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" -version = "0.5.0" - [[ImageCore]] deps = ["ColorTypes", "Colors", "FFTW", "FixedPointNumbers", "Graphics", "MappedArrays", "OffsetArrays", "PaddedViews", "Random", "Statistics", "Test"] git-tree-sha1 = "5e7b1f49c80541860e08a7ea91805a24c1641f19" @@ -317,11 +347,11 @@ git-tree-sha1 = "18ae1c0a8df31549a9452ceac93751d4aa166071" uuid = "02fcd773-0e25-5acc-982a-7f6622650795" version = "0.7.1" -[[IndirectArrays]] -deps = ["Compat", "Test"] -git-tree-sha1 = "b6e249be10a3381b2c72ac82f2d13d70067cb2bd" -uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" -version = "0.5.0" +[[IndexedTables]] +deps = ["DataValues", "Dates", "IteratorInterfaceExtensions", "LinearAlgebra", "OnlineStats", "PooledArrays", "Random", "Serialization", "SparseArrays", "Statistics", "TableTraits", "TableTraitsUtils", "Test", "WeakRefStrings"] +git-tree-sha1 = "cb4406eeed8729f8179940d39e6dec5598971341" +uuid = "6deec6e2-d858-57c5-ab9b-e6ca5bd20e43" +version = "0.8.1" [[InteractiveUtils]] deps = ["LinearAlgebra", "Markdown"] @@ -357,6 +387,18 @@ git-tree-sha1 = "1f7a25b53ec67f5e9422f1f551ee216503f4a0fa" uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" version = "0.20.0" +[[KernelDensity]] +deps = ["Distributions", "FFTW", "Interpolations", "Optim", "StatsBase", "Test"] +git-tree-sha1 = "c1048817fe5711f699abc8fabd47b1ac6ba4db04" +uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" +version = "0.5.1" + +[[LearnBase]] +deps = ["LinearAlgebra", "SparseArrays", "StatsBase", "Test"] +git-tree-sha1 = "c4b5da6d68517f46f70ed5157b28336b56cd2ff3" +uuid = "7f8f8fb0-2700-5f03-b4bd-41f8cfc144b6" +version = "0.2.2" + [[LibCURL]] deps = ["BinaryProvider", "Compat", "Libdl", "Printf"] git-tree-sha1 = "6339c87cb76923a3cf947fcd213cbc364355c9c9" @@ -381,18 +423,30 @@ git-tree-sha1 = "d405194ffc0293c3519d4f7251ce51baac9cc871" uuid = "2ec943e9-cfe8-584d-b93d-64dcb6d567b7" version = "1.0.0" +[[LineSearches]] +deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf", "Test"] +git-tree-sha1 = "54eb90e8dbe745d617c78dee1d6ae95c7f6f5779" +uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" +version = "7.0.1" + [[LinearAlgebra]] deps = ["Libdl"] uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +[[Loess]] +deps = ["Distances", "Random", "Statistics", "Test"] +git-tree-sha1 = "0ee46caf683a422b595be4dfaed6cda28f541e25" +uuid = "4345ca2d-374a-55d4-8d30-97f9976e7612" +version = "0.5.0" + [[Logging]] uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" -[[MacroTools]] -deps = ["Compat"] -git-tree-sha1 = "c443e1c8d58a4e9f61b708ad0a88286c7042145b" -uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.4.4" +[[LossFunctions]] +deps = ["InteractiveUtils", "LearnBase", "Markdown", "Random", "RecipesBase", "SparseArrays", "Statistics", "StatsBase", "Test"] +git-tree-sha1 = "b97d2e9a527733649d0205d3374d0daee352c50e" +uuid = "30fc2ffe-d236-52d8-8643-a9d8f7c094a7" +version = "0.5.0" [[MakieGallery]] deps = ["AbstractPlotting", "BinaryProvider", "ColorTypes", "ColorVectorSpace", "Colors", "DataFrames", "Documenter", "FileIO", "FixedPointNumbers", "GDAL", "GeometryTypes", "ImageCore", "ImageFiltering", "ImageMagick", "ImageTransformations", "LinearAlgebra", "Markdown", "MeshIO", "ModernGL", "Pkg", "QuartzImageIO", "RDatasets", "Random", "Statistics", "Test"] @@ -439,12 +493,24 @@ git-tree-sha1 = "f4f8fa8d04d3c1e7294f07fc37586c819466ad38" uuid = "66fc600b-dfda-50eb-8b99-91cfa97b1301" version = "1.0.0" +[[NLSolversBase]] +deps = ["Calculus", "DiffEqDiffTools", "DiffResults", "Distributed", "ForwardDiff", "LinearAlgebra", "Random", "SparseArrays", "Test"] +git-tree-sha1 = "ebfb2e96970151753575b9c4d31d47e5ae8382a5" +uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" +version = "7.1.1" + [[NaNMath]] deps = ["Compat"] git-tree-sha1 = "ce3b85e484a5d4c71dd5316215069311135fa9f2" uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" version = "0.3.2" +[[NamedArrays]] +deps = ["Combinatorics", "DataStructures", "DelimitedFiles", "LinearAlgebra", "Random", "Requires", "SparseArrays", "Statistics", "Test"] +git-tree-sha1 = "977c65d68cee14ab28198e89ebc125d0738ef250" +uuid = "86f7a689-2022-50b4-a561-43c23ac3c673" +version = "0.9.2" + [[Nullables]] deps = ["Compat"] git-tree-sha1 = "ae1a63457e14554df2159b0b028f48536125092d" @@ -463,12 +529,36 @@ git-tree-sha1 = "f446248f2dfbc13039a0b90994dd25b059b01eab" uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" version = "0.9.0" +[[OnlineStats]] +deps = ["DataStructures", "Dates", "LearnBase", "LinearAlgebra", "LossFunctions", "OnlineStatsBase", "PenaltyFunctions", "Random", "RecipesBase", "Reexport", "Statistics", "StatsBase", "SweepOperator", "Test"] +git-tree-sha1 = "70fe5cbb31d37c18f6312a2994c31b782be50607" +uuid = "a15396b6-48d5-5d58-9928-6d29437db91e" +version = "0.19.2" + +[[OnlineStatsBase]] +deps = ["LearnBase", "Test"] +git-tree-sha1 = "520580a74e09378fb6665fa89339323d411d3df3" +uuid = "925886fa-5bf2-5e8e-b522-a9147a512338" +version = "0.9.1" + +[[Optim]] +deps = ["Calculus", "DiffEqDiffTools", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "Random", "SparseArrays", "StatsBase", "Test"] +git-tree-sha1 = "0f2a6c6ff9db396cc7af15bb1cf057a26662ff17" +uuid = "429524aa-4258-5aef-a3af-852621145aeb" +version = "0.17.2" + [[OrderedCollections]] deps = ["Random", "Serialization", "Test"] git-tree-sha1 = "85619a3f3e17bb4761fe1b1fd47f0e979f964d5b" uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" version = "1.0.2" +[[PDMats]] +deps = ["Arpack", "LinearAlgebra", "SparseArrays", "SuiteSparse", "Test"] +git-tree-sha1 = "b6c91fc0ab970c0563cbbe69af18d741a49ce551" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.9.6" + [[Packing]] deps = ["GeometryTypes", "Test"] git-tree-sha1 = "bc7c284233cf0518933bf9977e3e8234efcc1c30" @@ -493,6 +583,12 @@ git-tree-sha1 = "949ca36d47010bee093254467166487c921d490b" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" version = "0.2.14" +[[PenaltyFunctions]] +deps = ["InteractiveUtils", "LearnBase", "LinearAlgebra", "RecipesBase", "Reexport", "Test"] +git-tree-sha1 = "b0baaa5218ca0ffd6a8ae37ef0b58e0df688ac8b" +uuid = "06bb1623-fdd5-5ca2-a01c-88eae3ea319e" +version = "0.1.2" + [[Pkg]] deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" @@ -503,11 +599,23 @@ git-tree-sha1 = "fd28f30a294a38ec847de95d8ac7ac916ccd7c06" uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" version = "0.5.5" -[[Primes]] +[[Polynomials]] +deps = ["LinearAlgebra", "SparseArrays", "Test"] +git-tree-sha1 = "1a1eae52956658a6acae6fa1b6d6c3d488192895" +uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" +version = "0.5.1" + +[[PooledArrays]] deps = ["Test"] -git-tree-sha1 = "ff1a2323cb468ec5f201838fcbe3c232266b1f95" -uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" -version = "0.4.0" +git-tree-sha1 = "5c5ded7adc52867f599c21d3f43542fce491afda" +uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" +version = "0.4.1" + +[[PositiveFactorizations]] +deps = ["LinearAlgebra", "Test"] +git-tree-sha1 = "86ae7329c4b5c266acf5c7c524a972300d991e1c" +uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" +version = "0.2.1" [[Printf]] deps = ["Unicode"] @@ -517,6 +625,12 @@ uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" deps = ["Printf"] uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" +[[QuadGK]] +deps = ["DataStructures", "LinearAlgebra", "Test"] +git-tree-sha1 = "7e8dff9c205f36eceaf6e62a43ff851637ca45fc" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.0.2" + [[QuartzImageIO]] deps = ["ColorTypes", "ColorVectorSpace", "FileIO", "FixedPointNumbers", "ImageCore", "Libdl", "Random", "Test"] git-tree-sha1 = "c747a56f223919b157e6cd9dc58d59c560586302" @@ -543,18 +657,18 @@ uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" deps = ["Serialization"] uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -[[RangeArrays]] -deps = ["Compat"] -git-tree-sha1 = "d925adfd5b01cb46fde89dc9548d167b3b136f4a" -uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" -version = "0.3.1" - [[Ratios]] deps = ["Compat"] git-tree-sha1 = "fd159bead0a24e6270fd0573a340312bd4645cc2" uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" version = "0.3.0" +[[RecipesBase]] +deps = ["Random", "Test"] +git-tree-sha1 = "0b3cb370ee4dc00f47f1193101600949f3dcf884" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "0.6.0" + [[Reexport]] deps = ["Pkg"] git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" @@ -567,6 +681,12 @@ git-tree-sha1 = "f6fbf4ba64d295e146e49e021207993b6b48c7d1" uuid = "ae029012-a4dd-5104-9daa-d747884805df" version = "0.5.2" +[[Rmath]] +deps = ["BinaryProvider", "Libdl", "Random", "Statistics", "Test"] +git-tree-sha1 = "9a6c758cdf73036c3239b0afbea790def1dabff9" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.5.0" + [[Rotations]] deps = ["LinearAlgebra", "Random", "StaticArrays", "Statistics", "Test"] git-tree-sha1 = "b629771d0de88979cbdbf72ceddc54de58fde149" @@ -595,12 +715,6 @@ git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" version = "0.4.0" -[[SimpleTraits]] -deps = ["InteractiveUtils", "MacroTools", "Test"] -git-tree-sha1 = "c0a542b8d5e369b179ccd296b2ca987f6da5da0a" -uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" -version = "0.8.0" - [[Sockets]] uuid = "6462fe0b-24de-5631-8697-dd941f90decc" @@ -636,12 +750,42 @@ git-tree-sha1 = "2722397d88f8ffef551948f6c20e1d74a743298c" uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" version = "0.26.0" +[[StatsFuns]] +deps = ["Rmath", "SpecialFunctions", "Test"] +git-tree-sha1 = "d14bb7b03defd2deaa5675646f6783089e0556f0" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "0.7.0" + +[[StatsMakie]] +deps = ["AbstractPlotting", "Distributions", "FreqTables", "IndexedTables", "IntervalSets", "KernelDensity", "Loess", "NamedArrays", "Observables", "Random", "Statistics", "StatsBase", "Tables", "Test"] +git-tree-sha1 = "12429b8d5308b27483f4d6148cefb86080e4d054" +repo-rev = "master" +repo-url = "https://github.com/JuliaPlots/StatsMakie.jl.git" +uuid = "9d48ccf0-4268-5716-84ff-21228f561db3" +version = "0.0.0" + +[[SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[SweepOperator]] +deps = ["LinearAlgebra", "Test"] +git-tree-sha1 = "2039aaa96f7b21634a1b3246cb2699dd1d26d473" +uuid = "7522ee7d-7047-56d0-94d9-4bc626e7058d" +version = "0.2.0" + [[TableTraits]] deps = ["IteratorInterfaceExtensions", "Test"] git-tree-sha1 = "da062a2c31f16178f68190243c24140801720a43" uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" version = "0.4.0" +[[TableTraitsUtils]] +deps = ["DataValues", "IteratorInterfaceExtensions", "Missings", "TableTraits", "Test"] +git-tree-sha1 = "a355f1882d64881a11f853e64dcc353975c4df6e" +uuid = "382cd787-c1b6-5bf2-a167-d5b971a19bda" +version = "0.3.1" + [[Tables]] deps = ["Requires", "Test"] git-tree-sha1 = "940944e6b68a35046282897a2218891c7cf14a32" diff --git a/Project.toml b/Project.toml index 66f6339ac97..5b7b5c7c383 100644 --- a/Project.toml +++ b/Project.toml @@ -9,14 +9,31 @@ Cairo = "159f3aea-2a34-519c-b102-8c37f9878175" Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" GeometryTypes = "4d00f742-c7ba-57c2-abde-4428a4b178cb" ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534" +ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +MeshIO = "7269a6da-0436-5bbc-96c2-40638cbb6118" +StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + + + +[compat] +AbstractPlotting = ">=0.9.1" +GeometryTypes = ">=0.7.2" + +[extras] +DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534" ImageFiltering = "6a3955dd-da59-5b1f-98d4-e7296123deb5" ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" ImageTransformations = "02fcd773-0e25-5acc-982a-7f6622650795" -LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" MakieGallery = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" MeshIO = "7269a6da-0436-5bbc-96c2-40638cbb6118" +ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" +QuartzImageIO = "dca85d43-d64c-5e67-8c65-017450d5d020" RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" -StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" +StatsMakie = "9d48ccf0-4268-5716-84ff-21228f561db3" + +[targets] +test = ["DataFrames", "MakieGallery", "MeshIO", "RDatasets", "StatsMakie", "ImageCore", "ImageTransformations", "ImageMagick", "QuartzImageIO"] From fb67a1b0b719fedccfdf73c6f7255219de129508 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Thu, 6 Dec 2018 16:28:10 +0100 Subject: [PATCH 0045/1328] fix boundaries --- src/GLVisualize/assets/shader/distance_shape.frag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GLVisualize/assets/shader/distance_shape.frag b/src/GLVisualize/assets/shader/distance_shape.frag index 88588469ff2..5b7822f76e4 100644 --- a/src/GLVisualize/assets/shader/distance_shape.frag +++ b/src/GLVisualize/assets/shader/distance_shape.frag @@ -120,7 +120,7 @@ void main(){ else if(shape == ROUNDED_RECTANGLE) signed_distance = rounded_rectangle(f_uv, vec2(0.2), vec2(0.8)); else if(shape == RECTANGLE) - signed_distance = rectangle(f_uv); + signed_distance = 1.0; else if(shape == TRIANGLE) signed_distance = triangle(f_uv); From e1e43dd81ec972894345651da2910fca7aeeb8e9 Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 8 Dec 2018 14:45:00 +0100 Subject: [PATCH 0046/1328] update regex, create window more carefully --- deps/build.jl | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/deps/build.jl b/deps/build.jl index 0a726489c50..a4ab660f9ee 100644 --- a/deps/build.jl +++ b/deps/build.jl @@ -31,12 +31,9 @@ end try using ModernGL # Create a windowed mode window and its OpenGL context - window = GLFW.CreateWindow(10, 10, "OpenGL Example") - # Make the window's context current - GLFW.HideWindow(window) - GLFW.MakeContextCurrent(window) + window = GLFW.Window(resolution = (10, 10), major = 3, minor = 3, visible = false, focus = false) glversion = unsafe_string(glGetString(GL_VERSION)) - m = match(r"(\d+)\.(\d+)\.(\d+)?(.*)", glversion) + m = match(r"(\d+)\.(\d+)\s", glversion) # I don't really trust that all vendors have a version that matches # the above regex, so let's make no match non fatal! if m === nothing From 3e2c6d29002dfc0fec169faf9ab71afd59df9331 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 12 Dec 2018 11:26:41 +0100 Subject: [PATCH 0047/1328] fix build --- deps/build.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/build.jl b/deps/build.jl index a4ab660f9ee..d48b0164899 100644 --- a/deps/build.jl +++ b/deps/build.jl @@ -33,7 +33,7 @@ try # Create a windowed mode window and its OpenGL context window = GLFW.Window(resolution = (10, 10), major = 3, minor = 3, visible = false, focus = false) glversion = unsafe_string(glGetString(GL_VERSION)) - m = match(r"(\d+)\.(\d+)\s", glversion) + m = match(r"(\d+)\.(\d+)(.\d+)?\s", glversion) # I don't really trust that all vendors have a version that matches # the above regex, so let's make no match non fatal! if m === nothing From bc41f07aa5293274fe2a206ed4249404eb67692c Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 12 Dec 2018 12:08:00 +0100 Subject: [PATCH 0048/1328] update manifests --- Manifest.toml | 30 ++++++++++++++---------------- Project.toml | 5 +++-- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index b1d236f0710..9c7c1adcfe4 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -75,9 +75,9 @@ version = "0.2.0" [[CategoricalArrays]] deps = ["Compat", "Future", "Missings", "Printf", "Reexport", "Requires"] -git-tree-sha1 = "11419d157ab75a54a8af63315e7a279a593971bc" +git-tree-sha1 = "94d16e77dfacc59f6d6c1361866906dbb65b6f6b" uuid = "324d7699-5711-5eae-9e2f-1d82baa6b597" -version = "0.5.1" +version = "0.5.2" [[CodecZlib]] deps = ["BinaryProvider", "Libdl", "Test", "TranscodingStreams"] @@ -159,9 +159,9 @@ version = "0.2.0" [[DataFrames]] deps = ["CategoricalArrays", "CodecZlib", "Compat", "DataStreams", "Dates", "InteractiveUtils", "IteratorInterfaceExtensions", "LinearAlgebra", "Missings", "Printf", "Random", "Reexport", "SortingAlgorithms", "Statistics", "StatsBase", "TableTraits", "Tables", "Test", "TranscodingStreams", "Unicode", "WeakRefStrings"] -git-tree-sha1 = "60c2820c9ae93cc33e98cd820e0b449d551c7874" +git-tree-sha1 = "41ec35bcf49a860706924b9b3e322eed03164c83" uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -version = "0.15.1" +version = "0.15.2" [[DataStreams]] deps = ["Dates", "Missings", "Test", "WeakRefStrings"] @@ -231,9 +231,9 @@ version = "0.6.0" [[Documenter]] deps = ["Base64", "DocStringExtensions", "InteractiveUtils", "LibGit2", "Logging", "Markdown", "Pkg", "REPL", "Random", "Test", "Unicode"] -git-tree-sha1 = "9f2135e0e7ecb63f9c3ef73ea15a31d8cdb79bb7" +git-tree-sha1 = "a6db1c69925cdc53aafb38caec4446be26e0c617" uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "0.20.0" +version = "0.21.0" [[EzXML]] deps = ["BinaryProvider", "Libdl", "Printf", "Test"] @@ -531,9 +531,9 @@ version = "0.2.3" [[OffsetArrays]] deps = ["DelimitedFiles", "Test"] -git-tree-sha1 = "f446248f2dfbc13039a0b90994dd25b059b01eab" +git-tree-sha1 = "7d1442cb06fbfbc4fea936c3c56b38daffd22d3b" uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -version = "0.9.0" +version = "0.9.1" [[OnlineStats]] deps = ["DataStructures", "Dates", "LearnBase", "LinearAlgebra", "LossFunctions", "OnlineStatsBase", "PenaltyFunctions", "Random", "RecipesBase", "Reexport", "Statistics", "StatsBase", "SweepOperator", "Test"] @@ -585,9 +585,9 @@ version = "0.10.2" [[Parsers]] deps = ["Dates", "Mmap", "Test", "WeakRefStrings"] -git-tree-sha1 = "949ca36d47010bee093254467166487c921d490b" +git-tree-sha1 = "9c2b96d07344f9f716fee1c4a7258ac327d08a6c" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "0.2.14" +version = "0.2.15" [[PenaltyFunctions]] deps = ["InteractiveUtils", "LearnBase", "LinearAlgebra", "RecipesBase", "Reexport", "Test"] @@ -639,9 +639,9 @@ uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" [[QuadGK]] deps = ["DataStructures", "LinearAlgebra", "Test"] -git-tree-sha1 = "7e8dff9c205f36eceaf6e62a43ff851637ca45fc" +git-tree-sha1 = "3ce467a8e76c6030d4c3786e7d3a73442017cdc0" uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.0.2" +version = "2.0.3" [[QuartzImageIO]] deps = ["ColorTypes", "ColorVectorSpace", "FileIO", "FixedPointNumbers", "ImageCore", "Libdl", "Random", "Test"] @@ -783,10 +783,8 @@ version = "0.7.0" [[StatsMakie]] deps = ["AbstractPlotting", "Distributions", "FreqTables", "IndexedTables", "IntervalSets", "KernelDensity", "Loess", "NamedArrays", "Observables", "Random", "Statistics", "StatsBase", "Tables", "Test"] git-tree-sha1 = "12429b8d5308b27483f4d6148cefb86080e4d054" -repo-rev = "master" -repo-url = "https://github.com/JuliaPlots/StatsMakie.jl" -uuid = "9d48ccf0-4268-5716-84ff-21228f561db3" -version = "0.0.0" +uuid = "65254759-4cff-5aa5-8326-61ce017a8c70" +version = "0.0.1" [[SuiteSparse]] deps = ["Libdl", "LinearAlgebra", "SparseArrays"] diff --git a/Project.toml b/Project.toml index de6fa5ee3d3..648597bccf7 100644 --- a/Project.toml +++ b/Project.toml @@ -62,7 +62,8 @@ MeshIO = "7269a6da-0436-5bbc-96c2-40638cbb6118" ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" QuartzImageIO = "dca85d43-d64c-5e67-8c65-017450d5d020" RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" -StatsMakie = "9d48ccf0-4268-5716-84ff-21228f561db3" +StatsMakie = "65254759-4cff-5aa5-8326-61ce017a8c70" +MakieGallery = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" [targets] -test = ["DataFrames", "GDAL", "MakieGallery", "MeshIO", "RDatasets", "StatsMakie", "ImageCore", "ImageTransformations", "ImageMagick", "QuartzImageIO", "ModernGL", "ImageMagick", "ImageTransformations"] +test = ["DataFrames", "GDAL", "MeshIO", "RDatasets", "ImageCore", "ImageTransformations", "ImageMagick", "QuartzImageIO", "ModernGL", "ImageMagick", "ImageTransformations"] From dae12782c22c7a5d00c26e8ec9ab167bdc532969 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 12 Dec 2018 12:09:21 +0100 Subject: [PATCH 0049/1328] remove duplicate --- Project.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Project.toml b/Project.toml index 648597bccf7..e2cab2cf1f8 100644 --- a/Project.toml +++ b/Project.toml @@ -57,7 +57,6 @@ ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534" ImageFiltering = "6a3955dd-da59-5b1f-98d4-e7296123deb5" ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" ImageTransformations = "02fcd773-0e25-5acc-982a-7f6622650795" -MakieGallery = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" MeshIO = "7269a6da-0436-5bbc-96c2-40638cbb6118" ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" QuartzImageIO = "dca85d43-d64c-5e67-8c65-017450d5d020" From 0b92c99eff488ef393b56bf43d7c615fceae4141 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 12 Dec 2018 12:12:42 +0100 Subject: [PATCH 0050/1328] add MakieGallery to tests --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index e2cab2cf1f8..09e777c51c4 100644 --- a/Project.toml +++ b/Project.toml @@ -65,4 +65,4 @@ StatsMakie = "65254759-4cff-5aa5-8326-61ce017a8c70" MakieGallery = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" [targets] -test = ["DataFrames", "GDAL", "MeshIO", "RDatasets", "ImageCore", "ImageTransformations", "ImageMagick", "QuartzImageIO", "ModernGL", "ImageMagick", "ImageTransformations"] +test = ["DataFrames", "MakieGallery", "GDAL", "MeshIO", "RDatasets", "ImageCore", "ImageTransformations", "ImageMagick", "QuartzImageIO", "ModernGL", "ImageMagick", "ImageTransformations"] From ef6e5784cc31277c24f000fb119da2fa316f0c82 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 12 Dec 2018 12:15:51 +0100 Subject: [PATCH 0051/1328] add MakieGallery#master --- Manifest.toml | 214 -------------------------------------------------- Project.toml | 2 +- 2 files changed, 1 insertion(+), 215 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 9c7c1adcfe4..0eaa59415de 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -10,12 +10,6 @@ git-tree-sha1 = "22eb6757f34439a84eff8ca5f4ebcb9a1f221102" uuid = "537997a7-5e4e-5d89-9595-2241ea00577e" version = "0.9.1" -[[Arpack]] -deps = ["BinaryProvider", "Libdl", "LinearAlgebra", "Random", "SparseArrays", "Test"] -git-tree-sha1 = "1ce1ce9984683f0b6a587d5bdbc688ecb480096f" -uuid = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97" -version = "0.3.0" - [[AxisAlgorithms]] deps = ["Compat", "WoodburyMatrices"] git-tree-sha1 = "99dabbe853e4f641ab21a676131f2cf9fb29937e" @@ -61,12 +55,6 @@ git-tree-sha1 = "b92c6f626a044cc9619156d54994b94084d40abe" uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" version = "0.4.3" -[[Calculus]] -deps = ["Compat"] -git-tree-sha1 = "f60954495a7afcee4136f78d1d60350abd37a409" -uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" -version = "0.4.1" - [[CatIndices]] deps = ["CustomUnitRanges", "OffsetArrays", "Test"] git-tree-sha1 = "254cf73ea369d2e39bfd6c5eb27a2296cfaed68c" @@ -109,18 +97,6 @@ git-tree-sha1 = "9f0a0210450acb91c730b730a994f8eef1d3d543" uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" version = "0.9.5" -[[Combinatorics]] -deps = ["LinearAlgebra", "Polynomials", "Test"] -git-tree-sha1 = "50b3ae4d643dc27eaff69fb6be06ee094d5500c9" -uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" -version = "0.7.0" - -[[CommonSubexpressions]] -deps = ["Test"] -git-tree-sha1 = "efdaf19ab11c7889334ca247ff4c9f7c322817b0" -uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" -version = "0.2.0" - [[Compat]] deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] git-tree-sha1 = "ec61a16eed883ad0cfa002d7489b3ce6d039bb9a" @@ -175,12 +151,6 @@ git-tree-sha1 = "8fc6e166e24fda04b2b648d4260cdad241788c54" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" version = "0.14.0" -[[DataValues]] -deps = ["Dates", "InteractiveUtils", "LinearAlgebra", "Random", "Test"] -git-tree-sha1 = "4fedccda7e5111354c7dcc832c7da83ff7258765" -uuid = "e7dc6d0d-1eca-5fa6-8ad6-5aecde8b7ea5" -version = "0.4.5" - [[Dates]] deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" @@ -189,40 +159,10 @@ uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" deps = ["Mmap"] uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" -[[DiffEqDiffTools]] -deps = ["LinearAlgebra", "Test"] -git-tree-sha1 = "67700c9fc82033ec68a145bc650f6b9debdf9103" -uuid = "01453d9d-ee7c-5054-8395-0335cb756afa" -version = "0.7.1" - -[[DiffResults]] -deps = ["Compat", "StaticArrays"] -git-tree-sha1 = "db8acf46717b13d6c48deb7a12007c7f85a70cf7" -uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" -version = "0.0.3" - -[[DiffRules]] -deps = ["Random", "Test"] -git-tree-sha1 = "c49ec69428ffea0c1d1bbdc63d1a70f5df5860ad" -uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" -version = "0.0.7" - -[[Distances]] -deps = ["LinearAlgebra", "Printf", "Random", "Statistics", "Test"] -git-tree-sha1 = "2f38605722542f1c0a32dd2856fb529d8c226c69" -uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" -version = "0.7.3" - [[Distributed]] deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" -[[Distributions]] -deps = ["Distributed", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsBase", "StatsFuns", "Test"] -git-tree-sha1 = "c24e9b6500c037673f0241a2783472b8c3d080c7" -uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.16.4" - [[DocStringExtensions]] deps = ["LibGit2", "Markdown", "Pkg", "Test"] git-tree-sha1 = "1df01539a1c952cef21f2d2d1c092c2bcf0177d7" @@ -265,12 +205,6 @@ git-tree-sha1 = "b8045033701c3b10bf2324d7203404be7aef88ba" uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" version = "0.5.3" -[[ForwardDiff]] -deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "InteractiveUtils", "LinearAlgebra", "NaNMath", "Random", "SparseArrays", "SpecialFunctions", "StaticArrays", "Test"] -git-tree-sha1 = "b91250044374764e7c29af59a774c4b8d6100b6e" -uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "0.10.1" - [[FreeType]] deps = ["BinaryProvider", "Libdl", "Pkg", "Test"] git-tree-sha1 = "06462b9d5aca708d764d16e5ba6a83ba7b753d57" @@ -283,12 +217,6 @@ git-tree-sha1 = "271ef13438bd0946950fd34d9241e5beefd6d4b3" uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" version = "0.4.1" -[[FreqTables]] -deps = ["CategoricalArrays", "NamedArrays", "Tables", "Test"] -git-tree-sha1 = "93ce75cae27c2d1c6518771d597b6dd0a3d623d3" -uuid = "da1fdf0e-e0ff-5433-a45f-9bb5ff651cb1" -version = "0.3.1" - [[Future]] deps = ["Random"] uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" @@ -359,12 +287,6 @@ git-tree-sha1 = "18ae1c0a8df31549a9452ceac93751d4aa166071" uuid = "02fcd773-0e25-5acc-982a-7f6622650795" version = "0.7.1" -[[IndexedTables]] -deps = ["DataValues", "Dates", "IteratorInterfaceExtensions", "LinearAlgebra", "OnlineStats", "PooledArrays", "Random", "Serialization", "SparseArrays", "Statistics", "TableTraits", "TableTraitsUtils", "Test", "WeakRefStrings"] -git-tree-sha1 = "cb4406eeed8729f8179940d39e6dec5598971341" -uuid = "6deec6e2-d858-57c5-ab9b-e6ca5bd20e43" -version = "0.8.1" - [[IndirectArrays]] deps = ["Compat", "Test"] git-tree-sha1 = "b6e249be10a3381b2c72ac82f2d13d70067cb2bd" @@ -405,49 +327,19 @@ git-tree-sha1 = "1f7a25b53ec67f5e9422f1f551ee216503f4a0fa" uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" version = "0.20.0" -[[KernelDensity]] -deps = ["Distributions", "FFTW", "Interpolations", "Optim", "StatsBase", "Test"] -git-tree-sha1 = "c1048817fe5711f699abc8fabd47b1ac6ba4db04" -uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" -version = "0.5.1" - -[[LearnBase]] -deps = ["LinearAlgebra", "SparseArrays", "StatsBase", "Test"] -git-tree-sha1 = "c4b5da6d68517f46f70ed5157b28336b56cd2ff3" -uuid = "7f8f8fb0-2700-5f03-b4bd-41f8cfc144b6" -version = "0.2.2" - [[LibGit2]] uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" [[Libdl]] uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" -[[LineSearches]] -deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf", "Test"] -git-tree-sha1 = "54eb90e8dbe745d617c78dee1d6ae95c7f6f5779" -uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" -version = "7.0.1" - [[LinearAlgebra]] deps = ["Libdl"] uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -[[Loess]] -deps = ["Distances", "Random", "Statistics", "Test"] -git-tree-sha1 = "0ee46caf683a422b595be4dfaed6cda28f541e25" -uuid = "4345ca2d-374a-55d4-8d30-97f9976e7612" -version = "0.5.0" - [[Logging]] uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" -[[LossFunctions]] -deps = ["InteractiveUtils", "LearnBase", "Markdown", "Random", "RecipesBase", "SparseArrays", "Statistics", "StatsBase", "Test"] -git-tree-sha1 = "b97d2e9a527733649d0205d3374d0daee352c50e" -uuid = "30fc2ffe-d236-52d8-8643-a9d8f7c094a7" -version = "0.5.0" - [[MacroTools]] deps = ["Compat"] git-tree-sha1 = "c443e1c8d58a4e9f61b708ad0a88286c7042145b" @@ -499,24 +391,12 @@ git-tree-sha1 = "f4f8fa8d04d3c1e7294f07fc37586c819466ad38" uuid = "66fc600b-dfda-50eb-8b99-91cfa97b1301" version = "1.0.0" -[[NLSolversBase]] -deps = ["Calculus", "DiffEqDiffTools", "DiffResults", "Distributed", "ForwardDiff", "LinearAlgebra", "Random", "SparseArrays", "Test"] -git-tree-sha1 = "ebfb2e96970151753575b9c4d31d47e5ae8382a5" -uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" -version = "7.1.1" - [[NaNMath]] deps = ["Compat"] git-tree-sha1 = "ce3b85e484a5d4c71dd5316215069311135fa9f2" uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" version = "0.3.2" -[[NamedArrays]] -deps = ["Combinatorics", "DataStructures", "DelimitedFiles", "LinearAlgebra", "Random", "Requires", "SparseArrays", "Statistics", "Test"] -git-tree-sha1 = "977c65d68cee14ab28198e89ebc125d0738ef250" -uuid = "86f7a689-2022-50b4-a561-43c23ac3c673" -version = "0.9.2" - [[Nullables]] deps = ["Compat"] git-tree-sha1 = "ae1a63457e14554df2159b0b028f48536125092d" @@ -535,36 +415,12 @@ git-tree-sha1 = "7d1442cb06fbfbc4fea936c3c56b38daffd22d3b" uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" version = "0.9.1" -[[OnlineStats]] -deps = ["DataStructures", "Dates", "LearnBase", "LinearAlgebra", "LossFunctions", "OnlineStatsBase", "PenaltyFunctions", "Random", "RecipesBase", "Reexport", "Statistics", "StatsBase", "SweepOperator", "Test"] -git-tree-sha1 = "70fe5cbb31d37c18f6312a2994c31b782be50607" -uuid = "a15396b6-48d5-5d58-9928-6d29437db91e" -version = "0.19.2" - -[[OnlineStatsBase]] -deps = ["LearnBase", "Test"] -git-tree-sha1 = "520580a74e09378fb6665fa89339323d411d3df3" -uuid = "925886fa-5bf2-5e8e-b522-a9147a512338" -version = "0.9.1" - -[[Optim]] -deps = ["Calculus", "DiffEqDiffTools", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "Random", "SparseArrays", "StatsBase", "Test"] -git-tree-sha1 = "0f2a6c6ff9db396cc7af15bb1cf057a26662ff17" -uuid = "429524aa-4258-5aef-a3af-852621145aeb" -version = "0.17.2" - [[OrderedCollections]] deps = ["Random", "Serialization", "Test"] git-tree-sha1 = "85619a3f3e17bb4761fe1b1fd47f0e979f964d5b" uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" version = "1.0.2" -[[PDMats]] -deps = ["Arpack", "LinearAlgebra", "SparseArrays", "SuiteSparse", "Test"] -git-tree-sha1 = "b6c91fc0ab970c0563cbbe69af18d741a49ce551" -uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" -version = "0.9.6" - [[Packing]] deps = ["GeometryTypes", "Test"] git-tree-sha1 = "bc7c284233cf0518933bf9977e3e8234efcc1c30" @@ -589,12 +445,6 @@ git-tree-sha1 = "9c2b96d07344f9f716fee1c4a7258ac327d08a6c" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" version = "0.2.15" -[[PenaltyFunctions]] -deps = ["InteractiveUtils", "LearnBase", "LinearAlgebra", "RecipesBase", "Reexport", "Test"] -git-tree-sha1 = "b0baaa5218ca0ffd6a8ae37ef0b58e0df688ac8b" -uuid = "06bb1623-fdd5-5ca2-a01c-88eae3ea319e" -version = "0.1.2" - [[Pkg]] deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" @@ -605,24 +455,6 @@ git-tree-sha1 = "fd28f30a294a38ec847de95d8ac7ac916ccd7c06" uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" version = "0.5.5" -[[Polynomials]] -deps = ["LinearAlgebra", "SparseArrays", "Test"] -git-tree-sha1 = "1a1eae52956658a6acae6fa1b6d6c3d488192895" -uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" -version = "0.5.1" - -[[PooledArrays]] -deps = ["Test"] -git-tree-sha1 = "5c5ded7adc52867f599c21d3f43542fce491afda" -uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" -version = "0.4.1" - -[[PositiveFactorizations]] -deps = ["LinearAlgebra", "Test"] -git-tree-sha1 = "86ae7329c4b5c266acf5c7c524a972300d991e1c" -uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" -version = "0.2.1" - [[Primes]] deps = ["Test"] git-tree-sha1 = "ff1a2323cb468ec5f201838fcbe3c232266b1f95" @@ -637,12 +469,6 @@ uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" deps = ["Printf"] uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" -[[QuadGK]] -deps = ["DataStructures", "LinearAlgebra", "Test"] -git-tree-sha1 = "3ce467a8e76c6030d4c3786e7d3a73442017cdc0" -uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.0.3" - [[QuartzImageIO]] deps = ["ColorTypes", "ColorVectorSpace", "FileIO", "FixedPointNumbers", "ImageCore", "Libdl", "Random", "Test"] git-tree-sha1 = "c747a56f223919b157e6cd9dc58d59c560586302" @@ -681,12 +507,6 @@ git-tree-sha1 = "fd159bead0a24e6270fd0573a340312bd4645cc2" uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" version = "0.3.0" -[[RecipesBase]] -deps = ["Random", "Test"] -git-tree-sha1 = "0b3cb370ee4dc00f47f1193101600949f3dcf884" -uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" -version = "0.6.0" - [[Reexport]] deps = ["Pkg"] git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" @@ -699,12 +519,6 @@ git-tree-sha1 = "f6fbf4ba64d295e146e49e021207993b6b48c7d1" uuid = "ae029012-a4dd-5104-9daa-d747884805df" version = "0.5.2" -[[Rmath]] -deps = ["BinaryProvider", "Libdl", "Random", "Statistics", "Test"] -git-tree-sha1 = "9a6c758cdf73036c3239b0afbea790def1dabff9" -uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" -version = "0.5.0" - [[Rotations]] deps = ["LinearAlgebra", "Random", "StaticArrays", "Statistics", "Test"] git-tree-sha1 = "b629771d0de88979cbdbf72ceddc54de58fde149" @@ -774,40 +588,12 @@ git-tree-sha1 = "2722397d88f8ffef551948f6c20e1d74a743298c" uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" version = "0.26.0" -[[StatsFuns]] -deps = ["Rmath", "SpecialFunctions", "Test"] -git-tree-sha1 = "d14bb7b03defd2deaa5675646f6783089e0556f0" -uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" -version = "0.7.0" - -[[StatsMakie]] -deps = ["AbstractPlotting", "Distributions", "FreqTables", "IndexedTables", "IntervalSets", "KernelDensity", "Loess", "NamedArrays", "Observables", "Random", "Statistics", "StatsBase", "Tables", "Test"] -git-tree-sha1 = "12429b8d5308b27483f4d6148cefb86080e4d054" -uuid = "65254759-4cff-5aa5-8326-61ce017a8c70" -version = "0.0.1" - -[[SuiteSparse]] -deps = ["Libdl", "LinearAlgebra", "SparseArrays"] -uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" - -[[SweepOperator]] -deps = ["LinearAlgebra", "Test"] -git-tree-sha1 = "2039aaa96f7b21634a1b3246cb2699dd1d26d473" -uuid = "7522ee7d-7047-56d0-94d9-4bc626e7058d" -version = "0.2.0" - [[TableTraits]] deps = ["IteratorInterfaceExtensions", "Test"] git-tree-sha1 = "da062a2c31f16178f68190243c24140801720a43" uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" version = "0.4.0" -[[TableTraitsUtils]] -deps = ["DataValues", "IteratorInterfaceExtensions", "Missings", "TableTraits", "Test"] -git-tree-sha1 = "a355f1882d64881a11f853e64dcc353975c4df6e" -uuid = "382cd787-c1b6-5bf2-a167-d5b971a19bda" -version = "0.3.1" - [[Tables]] deps = ["Requires", "Test"] git-tree-sha1 = "940944e6b68a35046282897a2218891c7cf14a32" diff --git a/Project.toml b/Project.toml index 09e777c51c4..c5f759a27f1 100644 --- a/Project.toml +++ b/Project.toml @@ -57,12 +57,12 @@ ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534" ImageFiltering = "6a3955dd-da59-5b1f-98d4-e7296123deb5" ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" ImageTransformations = "02fcd773-0e25-5acc-982a-7f6622650795" +MakieGallery = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" MeshIO = "7269a6da-0436-5bbc-96c2-40638cbb6118" ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" QuartzImageIO = "dca85d43-d64c-5e67-8c65-017450d5d020" RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" StatsMakie = "65254759-4cff-5aa5-8326-61ce017a8c70" -MakieGallery = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" [targets] test = ["DataFrames", "MakieGallery", "GDAL", "MeshIO", "RDatasets", "ImageCore", "ImageTransformations", "ImageMagick", "QuartzImageIO", "ModernGL", "ImageMagick", "ImageTransformations"] From f316f89ecaddb6b813d6389612dd9b895ba8de86 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 12 Dec 2018 12:21:15 +0100 Subject: [PATCH 0052/1328] add both --- Manifest.toml | 214 ++++++++++++++++++++++++++++++++++++++++++++++++++ Project.toml | 2 + 2 files changed, 216 insertions(+) diff --git a/Manifest.toml b/Manifest.toml index 0eaa59415de..9c7c1adcfe4 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -10,6 +10,12 @@ git-tree-sha1 = "22eb6757f34439a84eff8ca5f4ebcb9a1f221102" uuid = "537997a7-5e4e-5d89-9595-2241ea00577e" version = "0.9.1" +[[Arpack]] +deps = ["BinaryProvider", "Libdl", "LinearAlgebra", "Random", "SparseArrays", "Test"] +git-tree-sha1 = "1ce1ce9984683f0b6a587d5bdbc688ecb480096f" +uuid = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97" +version = "0.3.0" + [[AxisAlgorithms]] deps = ["Compat", "WoodburyMatrices"] git-tree-sha1 = "99dabbe853e4f641ab21a676131f2cf9fb29937e" @@ -55,6 +61,12 @@ git-tree-sha1 = "b92c6f626a044cc9619156d54994b94084d40abe" uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" version = "0.4.3" +[[Calculus]] +deps = ["Compat"] +git-tree-sha1 = "f60954495a7afcee4136f78d1d60350abd37a409" +uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" +version = "0.4.1" + [[CatIndices]] deps = ["CustomUnitRanges", "OffsetArrays", "Test"] git-tree-sha1 = "254cf73ea369d2e39bfd6c5eb27a2296cfaed68c" @@ -97,6 +109,18 @@ git-tree-sha1 = "9f0a0210450acb91c730b730a994f8eef1d3d543" uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" version = "0.9.5" +[[Combinatorics]] +deps = ["LinearAlgebra", "Polynomials", "Test"] +git-tree-sha1 = "50b3ae4d643dc27eaff69fb6be06ee094d5500c9" +uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +version = "0.7.0" + +[[CommonSubexpressions]] +deps = ["Test"] +git-tree-sha1 = "efdaf19ab11c7889334ca247ff4c9f7c322817b0" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.2.0" + [[Compat]] deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] git-tree-sha1 = "ec61a16eed883ad0cfa002d7489b3ce6d039bb9a" @@ -151,6 +175,12 @@ git-tree-sha1 = "8fc6e166e24fda04b2b648d4260cdad241788c54" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" version = "0.14.0" +[[DataValues]] +deps = ["Dates", "InteractiveUtils", "LinearAlgebra", "Random", "Test"] +git-tree-sha1 = "4fedccda7e5111354c7dcc832c7da83ff7258765" +uuid = "e7dc6d0d-1eca-5fa6-8ad6-5aecde8b7ea5" +version = "0.4.5" + [[Dates]] deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" @@ -159,10 +189,40 @@ uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" deps = ["Mmap"] uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" +[[DiffEqDiffTools]] +deps = ["LinearAlgebra", "Test"] +git-tree-sha1 = "67700c9fc82033ec68a145bc650f6b9debdf9103" +uuid = "01453d9d-ee7c-5054-8395-0335cb756afa" +version = "0.7.1" + +[[DiffResults]] +deps = ["Compat", "StaticArrays"] +git-tree-sha1 = "db8acf46717b13d6c48deb7a12007c7f85a70cf7" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "0.0.3" + +[[DiffRules]] +deps = ["Random", "Test"] +git-tree-sha1 = "c49ec69428ffea0c1d1bbdc63d1a70f5df5860ad" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "0.0.7" + +[[Distances]] +deps = ["LinearAlgebra", "Printf", "Random", "Statistics", "Test"] +git-tree-sha1 = "2f38605722542f1c0a32dd2856fb529d8c226c69" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.7.3" + [[Distributed]] deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" +[[Distributions]] +deps = ["Distributed", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsBase", "StatsFuns", "Test"] +git-tree-sha1 = "c24e9b6500c037673f0241a2783472b8c3d080c7" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.16.4" + [[DocStringExtensions]] deps = ["LibGit2", "Markdown", "Pkg", "Test"] git-tree-sha1 = "1df01539a1c952cef21f2d2d1c092c2bcf0177d7" @@ -205,6 +265,12 @@ git-tree-sha1 = "b8045033701c3b10bf2324d7203404be7aef88ba" uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" version = "0.5.3" +[[ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "InteractiveUtils", "LinearAlgebra", "NaNMath", "Random", "SparseArrays", "SpecialFunctions", "StaticArrays", "Test"] +git-tree-sha1 = "b91250044374764e7c29af59a774c4b8d6100b6e" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "0.10.1" + [[FreeType]] deps = ["BinaryProvider", "Libdl", "Pkg", "Test"] git-tree-sha1 = "06462b9d5aca708d764d16e5ba6a83ba7b753d57" @@ -217,6 +283,12 @@ git-tree-sha1 = "271ef13438bd0946950fd34d9241e5beefd6d4b3" uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" version = "0.4.1" +[[FreqTables]] +deps = ["CategoricalArrays", "NamedArrays", "Tables", "Test"] +git-tree-sha1 = "93ce75cae27c2d1c6518771d597b6dd0a3d623d3" +uuid = "da1fdf0e-e0ff-5433-a45f-9bb5ff651cb1" +version = "0.3.1" + [[Future]] deps = ["Random"] uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" @@ -287,6 +359,12 @@ git-tree-sha1 = "18ae1c0a8df31549a9452ceac93751d4aa166071" uuid = "02fcd773-0e25-5acc-982a-7f6622650795" version = "0.7.1" +[[IndexedTables]] +deps = ["DataValues", "Dates", "IteratorInterfaceExtensions", "LinearAlgebra", "OnlineStats", "PooledArrays", "Random", "Serialization", "SparseArrays", "Statistics", "TableTraits", "TableTraitsUtils", "Test", "WeakRefStrings"] +git-tree-sha1 = "cb4406eeed8729f8179940d39e6dec5598971341" +uuid = "6deec6e2-d858-57c5-ab9b-e6ca5bd20e43" +version = "0.8.1" + [[IndirectArrays]] deps = ["Compat", "Test"] git-tree-sha1 = "b6e249be10a3381b2c72ac82f2d13d70067cb2bd" @@ -327,19 +405,49 @@ git-tree-sha1 = "1f7a25b53ec67f5e9422f1f551ee216503f4a0fa" uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" version = "0.20.0" +[[KernelDensity]] +deps = ["Distributions", "FFTW", "Interpolations", "Optim", "StatsBase", "Test"] +git-tree-sha1 = "c1048817fe5711f699abc8fabd47b1ac6ba4db04" +uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" +version = "0.5.1" + +[[LearnBase]] +deps = ["LinearAlgebra", "SparseArrays", "StatsBase", "Test"] +git-tree-sha1 = "c4b5da6d68517f46f70ed5157b28336b56cd2ff3" +uuid = "7f8f8fb0-2700-5f03-b4bd-41f8cfc144b6" +version = "0.2.2" + [[LibGit2]] uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" [[Libdl]] uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +[[LineSearches]] +deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf", "Test"] +git-tree-sha1 = "54eb90e8dbe745d617c78dee1d6ae95c7f6f5779" +uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" +version = "7.0.1" + [[LinearAlgebra]] deps = ["Libdl"] uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +[[Loess]] +deps = ["Distances", "Random", "Statistics", "Test"] +git-tree-sha1 = "0ee46caf683a422b595be4dfaed6cda28f541e25" +uuid = "4345ca2d-374a-55d4-8d30-97f9976e7612" +version = "0.5.0" + [[Logging]] uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" +[[LossFunctions]] +deps = ["InteractiveUtils", "LearnBase", "Markdown", "Random", "RecipesBase", "SparseArrays", "Statistics", "StatsBase", "Test"] +git-tree-sha1 = "b97d2e9a527733649d0205d3374d0daee352c50e" +uuid = "30fc2ffe-d236-52d8-8643-a9d8f7c094a7" +version = "0.5.0" + [[MacroTools]] deps = ["Compat"] git-tree-sha1 = "c443e1c8d58a4e9f61b708ad0a88286c7042145b" @@ -391,12 +499,24 @@ git-tree-sha1 = "f4f8fa8d04d3c1e7294f07fc37586c819466ad38" uuid = "66fc600b-dfda-50eb-8b99-91cfa97b1301" version = "1.0.0" +[[NLSolversBase]] +deps = ["Calculus", "DiffEqDiffTools", "DiffResults", "Distributed", "ForwardDiff", "LinearAlgebra", "Random", "SparseArrays", "Test"] +git-tree-sha1 = "ebfb2e96970151753575b9c4d31d47e5ae8382a5" +uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" +version = "7.1.1" + [[NaNMath]] deps = ["Compat"] git-tree-sha1 = "ce3b85e484a5d4c71dd5316215069311135fa9f2" uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" version = "0.3.2" +[[NamedArrays]] +deps = ["Combinatorics", "DataStructures", "DelimitedFiles", "LinearAlgebra", "Random", "Requires", "SparseArrays", "Statistics", "Test"] +git-tree-sha1 = "977c65d68cee14ab28198e89ebc125d0738ef250" +uuid = "86f7a689-2022-50b4-a561-43c23ac3c673" +version = "0.9.2" + [[Nullables]] deps = ["Compat"] git-tree-sha1 = "ae1a63457e14554df2159b0b028f48536125092d" @@ -415,12 +535,36 @@ git-tree-sha1 = "7d1442cb06fbfbc4fea936c3c56b38daffd22d3b" uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" version = "0.9.1" +[[OnlineStats]] +deps = ["DataStructures", "Dates", "LearnBase", "LinearAlgebra", "LossFunctions", "OnlineStatsBase", "PenaltyFunctions", "Random", "RecipesBase", "Reexport", "Statistics", "StatsBase", "SweepOperator", "Test"] +git-tree-sha1 = "70fe5cbb31d37c18f6312a2994c31b782be50607" +uuid = "a15396b6-48d5-5d58-9928-6d29437db91e" +version = "0.19.2" + +[[OnlineStatsBase]] +deps = ["LearnBase", "Test"] +git-tree-sha1 = "520580a74e09378fb6665fa89339323d411d3df3" +uuid = "925886fa-5bf2-5e8e-b522-a9147a512338" +version = "0.9.1" + +[[Optim]] +deps = ["Calculus", "DiffEqDiffTools", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "Random", "SparseArrays", "StatsBase", "Test"] +git-tree-sha1 = "0f2a6c6ff9db396cc7af15bb1cf057a26662ff17" +uuid = "429524aa-4258-5aef-a3af-852621145aeb" +version = "0.17.2" + [[OrderedCollections]] deps = ["Random", "Serialization", "Test"] git-tree-sha1 = "85619a3f3e17bb4761fe1b1fd47f0e979f964d5b" uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" version = "1.0.2" +[[PDMats]] +deps = ["Arpack", "LinearAlgebra", "SparseArrays", "SuiteSparse", "Test"] +git-tree-sha1 = "b6c91fc0ab970c0563cbbe69af18d741a49ce551" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.9.6" + [[Packing]] deps = ["GeometryTypes", "Test"] git-tree-sha1 = "bc7c284233cf0518933bf9977e3e8234efcc1c30" @@ -445,6 +589,12 @@ git-tree-sha1 = "9c2b96d07344f9f716fee1c4a7258ac327d08a6c" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" version = "0.2.15" +[[PenaltyFunctions]] +deps = ["InteractiveUtils", "LearnBase", "LinearAlgebra", "RecipesBase", "Reexport", "Test"] +git-tree-sha1 = "b0baaa5218ca0ffd6a8ae37ef0b58e0df688ac8b" +uuid = "06bb1623-fdd5-5ca2-a01c-88eae3ea319e" +version = "0.1.2" + [[Pkg]] deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" @@ -455,6 +605,24 @@ git-tree-sha1 = "fd28f30a294a38ec847de95d8ac7ac916ccd7c06" uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" version = "0.5.5" +[[Polynomials]] +deps = ["LinearAlgebra", "SparseArrays", "Test"] +git-tree-sha1 = "1a1eae52956658a6acae6fa1b6d6c3d488192895" +uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" +version = "0.5.1" + +[[PooledArrays]] +deps = ["Test"] +git-tree-sha1 = "5c5ded7adc52867f599c21d3f43542fce491afda" +uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" +version = "0.4.1" + +[[PositiveFactorizations]] +deps = ["LinearAlgebra", "Test"] +git-tree-sha1 = "86ae7329c4b5c266acf5c7c524a972300d991e1c" +uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" +version = "0.2.1" + [[Primes]] deps = ["Test"] git-tree-sha1 = "ff1a2323cb468ec5f201838fcbe3c232266b1f95" @@ -469,6 +637,12 @@ uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" deps = ["Printf"] uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" +[[QuadGK]] +deps = ["DataStructures", "LinearAlgebra", "Test"] +git-tree-sha1 = "3ce467a8e76c6030d4c3786e7d3a73442017cdc0" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.0.3" + [[QuartzImageIO]] deps = ["ColorTypes", "ColorVectorSpace", "FileIO", "FixedPointNumbers", "ImageCore", "Libdl", "Random", "Test"] git-tree-sha1 = "c747a56f223919b157e6cd9dc58d59c560586302" @@ -507,6 +681,12 @@ git-tree-sha1 = "fd159bead0a24e6270fd0573a340312bd4645cc2" uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" version = "0.3.0" +[[RecipesBase]] +deps = ["Random", "Test"] +git-tree-sha1 = "0b3cb370ee4dc00f47f1193101600949f3dcf884" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "0.6.0" + [[Reexport]] deps = ["Pkg"] git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" @@ -519,6 +699,12 @@ git-tree-sha1 = "f6fbf4ba64d295e146e49e021207993b6b48c7d1" uuid = "ae029012-a4dd-5104-9daa-d747884805df" version = "0.5.2" +[[Rmath]] +deps = ["BinaryProvider", "Libdl", "Random", "Statistics", "Test"] +git-tree-sha1 = "9a6c758cdf73036c3239b0afbea790def1dabff9" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.5.0" + [[Rotations]] deps = ["LinearAlgebra", "Random", "StaticArrays", "Statistics", "Test"] git-tree-sha1 = "b629771d0de88979cbdbf72ceddc54de58fde149" @@ -588,12 +774,40 @@ git-tree-sha1 = "2722397d88f8ffef551948f6c20e1d74a743298c" uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" version = "0.26.0" +[[StatsFuns]] +deps = ["Rmath", "SpecialFunctions", "Test"] +git-tree-sha1 = "d14bb7b03defd2deaa5675646f6783089e0556f0" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "0.7.0" + +[[StatsMakie]] +deps = ["AbstractPlotting", "Distributions", "FreqTables", "IndexedTables", "IntervalSets", "KernelDensity", "Loess", "NamedArrays", "Observables", "Random", "Statistics", "StatsBase", "Tables", "Test"] +git-tree-sha1 = "12429b8d5308b27483f4d6148cefb86080e4d054" +uuid = "65254759-4cff-5aa5-8326-61ce017a8c70" +version = "0.0.1" + +[[SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[SweepOperator]] +deps = ["LinearAlgebra", "Test"] +git-tree-sha1 = "2039aaa96f7b21634a1b3246cb2699dd1d26d473" +uuid = "7522ee7d-7047-56d0-94d9-4bc626e7058d" +version = "0.2.0" + [[TableTraits]] deps = ["IteratorInterfaceExtensions", "Test"] git-tree-sha1 = "da062a2c31f16178f68190243c24140801720a43" uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" version = "0.4.0" +[[TableTraitsUtils]] +deps = ["DataValues", "IteratorInterfaceExtensions", "Missings", "TableTraits", "Test"] +git-tree-sha1 = "a355f1882d64881a11f853e64dcc353975c4df6e" +uuid = "382cd787-c1b6-5bf2-a167-d5b971a19bda" +version = "0.3.1" + [[Tables]] deps = ["Requires", "Test"] git-tree-sha1 = "940944e6b68a35046282897a2218891c7cf14a32" diff --git a/Project.toml b/Project.toml index c5f759a27f1..de4ba28a3b7 100644 --- a/Project.toml +++ b/Project.toml @@ -29,6 +29,7 @@ IndirectArrays = "9b13fd28-a010-5f03-acff-a1bbcff69959" IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +#MakieGallery = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a" MeshIO = "7269a6da-0436-5bbc-96c2-40638cbb6118" ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" @@ -41,6 +42,7 @@ RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" Showoff = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" +#StatsMakie = "65254759-4cff-5aa5-8326-61ce017a8c70" UnicodeFun = "1cfade01-22cf-5700-b092-accc4b62d6e1" [compat] From 1f9adf2ee9dc9c62c2483cfb66cb6a984d0a5d3f Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 12 Dec 2018 12:42:43 +0100 Subject: [PATCH 0053/1328] introduce test manifest --- .gitlab-ci.yml | 2 +- Project.toml | 18 ---------- Manifest.toml => test/Manifest.toml | 14 +++++--- test/Project.toml | 53 +++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 23 deletions(-) rename Manifest.toml => test/Manifest.toml (97%) create mode 100644 test/Project.toml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index dff1f12d009..138fb28c424 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -15,4 +15,4 @@ job: script: - julia -e 'using InteractiveUtils; versioninfo()' - - julia --project -e "using Pkg; Pkg.build(); Pkg.test()" + - julia --project=test/ -e 'using Pkg; pkg"dev ."; Pkg.test("GLMakie")' diff --git a/Project.toml b/Project.toml index de4ba28a3b7..8011b0a97e6 100644 --- a/Project.toml +++ b/Project.toml @@ -42,7 +42,6 @@ RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" Showoff = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" -#StatsMakie = "65254759-4cff-5aa5-8326-61ce017a8c70" UnicodeFun = "1cfade01-22cf-5700-b092-accc4b62d6e1" [compat] @@ -51,20 +50,3 @@ FreeTypeAbstraction = ">=0.3.0" GLFW = ">=2.3.0" GeometryTypes = ">=0.7.2" StaticArrays = ">=0.6.6" - -[extras] -DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -GDAL = "add2ef01-049f-52c4-9ee2-e494f65e021a" -ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534" -ImageFiltering = "6a3955dd-da59-5b1f-98d4-e7296123deb5" -ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" -ImageTransformations = "02fcd773-0e25-5acc-982a-7f6622650795" -MakieGallery = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" -MeshIO = "7269a6da-0436-5bbc-96c2-40638cbb6118" -ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" -QuartzImageIO = "dca85d43-d64c-5e67-8c65-017450d5d020" -RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" -StatsMakie = "65254759-4cff-5aa5-8326-61ce017a8c70" - -[targets] -test = ["DataFrames", "MakieGallery", "GDAL", "MeshIO", "RDatasets", "ImageCore", "ImageTransformations", "ImageMagick", "QuartzImageIO", "ModernGL", "ImageMagick", "ImageTransformations"] diff --git a/Manifest.toml b/test/Manifest.toml similarity index 97% rename from Manifest.toml rename to test/Manifest.toml index 9c7c1adcfe4..2b671468230 100644 --- a/Manifest.toml +++ b/test/Manifest.toml @@ -159,9 +159,9 @@ version = "0.2.0" [[DataFrames]] deps = ["CategoricalArrays", "CodecZlib", "Compat", "DataStreams", "Dates", "InteractiveUtils", "IteratorInterfaceExtensions", "LinearAlgebra", "Missings", "Printf", "Random", "Reexport", "SortingAlgorithms", "Statistics", "StatsBase", "TableTraits", "Tables", "Test", "TranscodingStreams", "Unicode", "WeakRefStrings"] -git-tree-sha1 = "41ec35bcf49a860706924b9b3e322eed03164c83" +git-tree-sha1 = "60c2820c9ae93cc33e98cd820e0b449d551c7874" uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -version = "0.15.2" +version = "0.15.1" [[DataStreams]] deps = ["Dates", "Missings", "Test", "WeakRefStrings"] @@ -231,9 +231,9 @@ version = "0.6.0" [[Documenter]] deps = ["Base64", "DocStringExtensions", "InteractiveUtils", "LibGit2", "Logging", "Markdown", "Pkg", "REPL", "Random", "Test", "Unicode"] -git-tree-sha1 = "a6db1c69925cdc53aafb38caec4446be26e0c617" +git-tree-sha1 = "9f2135e0e7ecb63f9c3ef73ea15a31d8cdb79bb7" uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "0.21.0" +version = "0.20.0" [[EzXML]] deps = ["BinaryProvider", "Libdl", "Printf", "Test"] @@ -305,6 +305,12 @@ git-tree-sha1 = "035e2b5e9c335afae1e92ecfe532cf0620da869f" uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" version = "2.3.0" +[[GLMakie]] +deps = ["AbstractPlotting", "AxisArrays", "BinaryProvider", "ColorBrewer", "ColorTypes", "ColorVectorSpace", "Colors", "Contour", "DataFrames", "Documenter", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GDAL", "GLFW", "GeometryTypes", "ImageAxes", "ImageCore", "ImageFiltering", "ImageMagick", "ImageTransformations", "IndirectArrays", "IntervalSets", "IterTools", "LinearAlgebra", "Markdown", "MeshIO", "ModernGL", "Observables", "PlotUtils", "Primes", "Printf", "QuartzImageIO", "RDatasets", "Serialization", "Showoff", "StaticArrays", "UnicodeFun"] +path = ".." +uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" +version = "0.0.1" + [[GeometryTypes]] deps = ["ColorTypes", "FixedPointNumbers", "IterTools", "LinearAlgebra", "StaticArrays", "Test"] git-tree-sha1 = "28b193e14466beecf928449e0f8505ff6de3709d" diff --git a/test/Project.toml b/test/Project.toml new file mode 100644 index 00000000000..82797a9f98b --- /dev/null +++ b/test/Project.toml @@ -0,0 +1,53 @@ +name = "MakieTests" +version = "0.0.1" + +[deps] +AbstractPlotting = "537997a7-5e4e-5d89-9595-2241ea00577e" +AxisArrays = "39de3d68-74b9-583c-8d2d-e117c070f3a9" +BinaryProvider = "b99e7846-7c00-51b0-8f62-c81ae34c0232" +ColorBrewer = "a2cac450-b92f-5266-8821-25eda20663c8" +ColorTypes = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +ColorVectorSpace = "c3611d14-8923-5661-9e6a-0046d554d3a4" +Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" +Contour = "d38c429a-6771-53c6-b99e-75d170b6e991" +DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +FixedPointNumbers = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +FreeType = "b38be410-82b0-50bf-ab77-7b57e271db43" +FreeTypeAbstraction = "663a7486-cb36-511b-a19d-713bb74d65c9" +GDAL = "add2ef01-049f-52c4-9ee2-e494f65e021a" +GLFW = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" +GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" +GeometryTypes = "4d00f742-c7ba-57c2-abde-4428a4b178cb" +ImageAxes = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" +ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534" +ImageFiltering = "6a3955dd-da59-5b1f-98d4-e7296123deb5" +ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" +ImageTransformations = "02fcd773-0e25-5acc-982a-7f6622650795" +IndirectArrays = "9b13fd28-a010-5f03-acff-a1bbcff69959" +IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" +IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +MakieGallery = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" +Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a" +MeshIO = "7269a6da-0436-5bbc-96c2-40638cbb6118" +ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" +Observables = "510215fc-4207-5dde-b226-833fc4488ee2" +PlotUtils = "995b91a9-d308-5afd-9ec6-746e21dbc043" +Primes = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" +Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" +QuartzImageIO = "dca85d43-d64c-5e67-8c65-017450d5d020" +RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" +Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +Showoff = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" +StatsMakie = "65254759-4cff-5aa5-8326-61ce017a8c70" +UnicodeFun = "1cfade01-22cf-5700-b092-accc4b62d6e1" + +[compat] +AbstractPlotting = ">=0.9.1" +FreeTypeAbstraction = ">=0.3.0" +GLFW = ">=2.3.0" +GeometryTypes = ">=0.7.2" +StaticArrays = ">=0.6.6" From e0e4f038016c000d270f7e4abb6c3004cb69957c Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 12 Dec 2018 12:45:45 +0100 Subject: [PATCH 0054/1328] already in manifest --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 138fb28c424..d9b2d6054ba 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -15,4 +15,4 @@ job: script: - julia -e 'using InteractiveUtils; versioninfo()' - - julia --project=test/ -e 'using Pkg; pkg"dev ."; Pkg.test("GLMakie")' + - julia --project=test/ -e 'using Pkg; Pkg.test("GLMakie")' From 36a2cf2cf607ddb0ff194b2dc614b09ac717e942 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 12 Dec 2018 13:01:01 +0100 Subject: [PATCH 0055/1328] remove comment --- Project.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Project.toml b/Project.toml index 8011b0a97e6..a4172ea26a3 100644 --- a/Project.toml +++ b/Project.toml @@ -29,7 +29,6 @@ IndirectArrays = "9b13fd28-a010-5f03-acff-a1bbcff69959" IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -#MakieGallery = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a" MeshIO = "7269a6da-0436-5bbc-96c2-40638cbb6118" ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" From 1c4da65dbeab71e8b373c85ae23de4c88ee49482 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 12 Dec 2018 14:29:12 +0100 Subject: [PATCH 0056/1328] build project --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d9b2d6054ba..df5b7e70562 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -15,4 +15,4 @@ job: script: - julia -e 'using InteractiveUtils; versioninfo()' - - julia --project=test/ -e 'using Pkg; Pkg.test("GLMakie")' + - julia --project=test/ -e 'using Pkg; Pkg.build("Makie"); Pkg.test("GLMakie")' From bc9df21f3d0854b99b7eb9f484dcd128dd1894c3 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 12 Dec 2018 14:58:09 +0100 Subject: [PATCH 0057/1328] forgot GL --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index df5b7e70562..35e8ec8d2a1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -15,4 +15,4 @@ job: script: - julia -e 'using InteractiveUtils; versioninfo()' - - julia --project=test/ -e 'using Pkg; Pkg.build("Makie"); Pkg.test("GLMakie")' + - julia --project=test/ -e 'using Pkg; Pkg.build("GLMakie"); Pkg.test("GLMakie")' From 1224438f7d692bb9b2c90f94cc43913a8c867291 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 12 Dec 2018 17:49:57 +0100 Subject: [PATCH 0058/1328] next try --- .gitlab-ci.yml | 2 +- Manifest.toml | 464 +++++++++++++++++++++++++++++++++++++++++++++ Project.toml | 12 -- test/Manifest.toml | 8 +- 4 files changed, 470 insertions(+), 16 deletions(-) create mode 100644 Manifest.toml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 35e8ec8d2a1..b05c9715070 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -15,4 +15,4 @@ job: script: - julia -e 'using InteractiveUtils; versioninfo()' - - julia --project=test/ -e 'using Pkg; Pkg.build("GLMakie"); Pkg.test("GLMakie")' + - julia --project=test/ -e 'using Pkg; Pkg.build("GLMakie"); include("test/runtests.jl")' diff --git a/Manifest.toml b/Manifest.toml new file mode 100644 index 00000000000..57e74429fbf --- /dev/null +++ b/Manifest.toml @@ -0,0 +1,464 @@ +[[AbstractFFTs]] +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "8d59c3b1463b5e0ad05a3698167f85fac90e184d" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "0.3.2" + +[[AbstractPlotting]] +deps = ["ColorBrewer", "ColorTypes", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "ImageMagick", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "Test", "UnicodeFun"] +git-tree-sha1 = "b47cc331607de0daa3d3e40ed77b61b36dd19c17" +uuid = "537997a7-5e4e-5d89-9595-2241ea00577e" +version = "0.9.2" + +[[AxisAlgorithms]] +deps = ["Compat", "WoodburyMatrices"] +git-tree-sha1 = "99dabbe853e4f641ab21a676131f2cf9fb29937e" +uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" +version = "0.3.0" + +[[AxisArrays]] +deps = ["Compat", "Dates", "IntervalSets", "IterTools", "Random", "RangeArrays", "Test"] +git-tree-sha1 = "2e2536e9e6f27c4f8d09d8442b61a7ae0b910c28" +uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" +version = "0.3.0" + +[[Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[BinDeps]] +deps = ["Compat", "Libdl", "SHA", "URIParser"] +git-tree-sha1 = "12093ca6cdd0ee547c39b1870e0c9c3f154d9ca9" +uuid = "9e28174c-4ba2-5203-b857-d8d62c4213ee" +version = "0.8.10" + +[[BinaryProvider]] +deps = ["Libdl", "Pkg", "SHA", "Test"] +git-tree-sha1 = "055eb2690182ebc31087859c3dd8598371d3ef9e" +uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" +version = "0.5.3" + +[[CMake]] +deps = ["BinDeps", "Libdl", "Test"] +git-tree-sha1 = "74853a75c26a4a73ac391ee26ee29ebeb5583d9f" +uuid = "631607c0-34d2-5d66-819e-eb0f9aa2061a" +version = "1.1.0" + +[[CMakeWrapper]] +deps = ["BinDeps", "CMake", "Libdl", "Parameters", "Test"] +git-tree-sha1 = "2b43d451639984e3571951cc687b8509b0a86c6d" +uuid = "d5fb7624-851a-54ee-a528-d3f3bac0b4a0" +version = "0.2.2" + +[[ColorBrewer]] +deps = ["Colors", "JSON", "Test"] +git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" +uuid = "a2cac450-b92f-5266-8821-25eda20663c8" +version = "0.4.0" + +[[ColorTypes]] +deps = ["FixedPointNumbers", "Random", "Test"] +git-tree-sha1 = "f73b0e10f2a5756de7019818a41654686da06b09" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.7.5" + +[[ColorVectorSpace]] +deps = ["ColorTypes", "Colors", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "StatsBase", "Test"] +git-tree-sha1 = "a890f08e61b40e9843d7177206da61229a3603c8" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.6.2" + +[[Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "InteractiveUtils", "Printf", "Reexport", "Test"] +git-tree-sha1 = "9f0a0210450acb91c730b730a994f8eef1d3d543" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.9.5" + +[[Compat]] +deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] +git-tree-sha1 = "ec61a16eed883ad0cfa002d7489b3ce6d039bb9a" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "1.4.0" + +[[Conda]] +deps = ["Compat", "JSON", "VersionParsing"] +git-tree-sha1 = "fb86fe40cb5b35990e368709bfdc1b46dbb99dac" +uuid = "8f4d0f93-b110-5947-807f-2305c1781a2d" +version = "1.1.1" + +[[Contour]] +deps = ["LinearAlgebra", "StaticArrays", "Test"] +git-tree-sha1 = "b974e164358fea753ef853ce7bad97afec15bb80" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.5.1" + +[[CoordinateTransformations]] +deps = ["Compat", "Rotations", "StaticArrays"] +git-tree-sha1 = "47f05d0b7f4999609f92e657147df000818c1f24" +uuid = "150eb455-5306-5404-9cee-2592286d6298" +version = "0.5.0" + +[[DataStructures]] +deps = ["InteractiveUtils", "OrderedCollections", "Random", "Serialization", "Test"] +git-tree-sha1 = "8fc6e166e24fda04b2b648d4260cdad241788c54" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.14.0" + +[[Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[DelimitedFiles]] +deps = ["Mmap"] +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" + +[[Distributed]] +deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[FFTW]] +deps = ["AbstractFFTs", "BinaryProvider", "Compat", "Conda", "Libdl", "LinearAlgebra", "Reexport", "Test"] +git-tree-sha1 = "29cda58afbf62f35b1a094882ad6c745a47b2eaa" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "0.2.4" + +[[FileIO]] +deps = ["Pkg", "Random", "Test"] +git-tree-sha1 = "1a114d08094e7267ba8d4d684f930d5a722184de" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.0.4" + +[[FixedPointNumbers]] +deps = ["Test"] +git-tree-sha1 = "b8045033701c3b10bf2324d7203404be7aef88ba" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.5.3" + +[[FreeType]] +deps = ["BinaryProvider", "Libdl", "Pkg", "Test"] +git-tree-sha1 = "06462b9d5aca708d764d16e5ba6a83ba7b753d57" +uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" +version = "2.1.1" + +[[FreeTypeAbstraction]] +deps = ["ColorVectorSpace", "Colors", "FreeType", "StaticArrays", "Test"] +git-tree-sha1 = "271ef13438bd0946950fd34d9241e5beefd6d4b3" +uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" +version = "0.4.1" + +[[GLFW]] +deps = ["BinDeps", "CMakeWrapper", "Homebrew", "Libdl", "Test"] +git-tree-sha1 = "035e2b5e9c335afae1e92ecfe532cf0620da869f" +uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" +version = "2.3.0" + +[[GeometryTypes]] +deps = ["ColorTypes", "FixedPointNumbers", "IterTools", "LinearAlgebra", "StaticArrays", "Test"] +git-tree-sha1 = "28b193e14466beecf928449e0f8505ff6de3709d" +uuid = "4d00f742-c7ba-57c2-abde-4428a4b178cb" +version = "0.7.2" + +[[Graphics]] +deps = ["Colors", "Compat", "NaNMath"] +git-tree-sha1 = "e3ead4211073d4117a0d2ef7d1efc5c8092c8412" +uuid = "a2bd30eb-e257-5431-a919-1863eab51364" +version = "0.4.0" + +[[Homebrew]] +deps = ["BinDeps", "InteractiveUtils", "JSON", "Libdl", "Test", "Unicode"] +git-tree-sha1 = "5582ec74f735cf8d12e562a2e65c47f34063bd51" +uuid = "d9be37ee-ecc9-5288-90f1-b9ca67657a75" +version = "0.7.0" + +[[IdentityRanges]] +deps = ["OffsetArrays", "Test"] +git-tree-sha1 = "f5ca23a08397288924a7535cd898d8ccbcde5ba5" +uuid = "bbac6d45-d8f3-5730-bfe4-7a449cd117ca" +version = "0.2.0" + +[[ImageAxes]] +deps = ["AxisArrays", "Colors", "FixedPointNumbers", "ImageCore", "MappedArrays", "Reexport", "SimpleTraits", "Test"] +git-tree-sha1 = "5735ec90843acaa67a4624611921c686cdf4efbf" +uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" +version = "0.5.0" + +[[ImageCore]] +deps = ["ColorTypes", "Colors", "FFTW", "FixedPointNumbers", "Graphics", "MappedArrays", "OffsetArrays", "PaddedViews", "Random", "Statistics", "Test"] +git-tree-sha1 = "5e7b1f49c80541860e08a7ea91805a24c1641f19" +uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" +version = "0.7.3" + +[[ImageMagick]] +deps = ["BinaryProvider", "ColorTypes", "FileIO", "FixedPointNumbers", "ImageCore", "InteractiveUtils", "Libdl", "Pkg", "Random", "Test"] +git-tree-sha1 = "0e4cc77fb131061b3525a97fd7d483b253c3aaad" +uuid = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" +version = "0.7.1" + +[[ImageTransformations]] +deps = ["AxisAlgorithms", "ColorTypes", "ColorVectorSpace", "Colors", "CoordinateTransformations", "FixedPointNumbers", "IdentityRanges", "ImageCore", "Interpolations", "LinearAlgebra", "OffsetArrays", "StaticArrays", "Test"] +git-tree-sha1 = "18ae1c0a8df31549a9452ceac93751d4aa166071" +uuid = "02fcd773-0e25-5acc-982a-7f6622650795" +version = "0.7.1" + +[[InteractiveUtils]] +deps = ["LinearAlgebra", "Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[Interpolations]] +deps = ["AxisAlgorithms", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "SharedArrays", "SparseArrays", "StaticArrays", "Test", "WoodburyMatrices"] +git-tree-sha1 = "3493536a64dae5a21c0cc8aecf680647f3e12313" +uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" +version = "0.11.0" + +[[IntervalSets]] +deps = ["Compat"] +git-tree-sha1 = "9dc556002f23740de13946e8c2e41798e09a9249" +uuid = "8197267c-284f-5f27-9208-e0e47529a953" +version = "0.3.1" + +[[IterTools]] +deps = ["SparseArrays", "Test"] +git-tree-sha1 = "79246285c43602384e6f1943b3554042a3712056" +uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +version = "1.1.1" + +[[JSON]] +deps = ["Dates", "Distributed", "Mmap", "Sockets", "Test", "Unicode"] +git-tree-sha1 = "1f7a25b53ec67f5e9422f1f551ee216503f4a0fa" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.20.0" + +[[LibGit2]] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[LinearAlgebra]] +deps = ["Libdl"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[MacroTools]] +deps = ["Compat"] +git-tree-sha1 = "c443e1c8d58a4e9f61b708ad0a88286c7042145b" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.4.4" + +[[MappedArrays]] +deps = ["Test"] +git-tree-sha1 = "923441c5ac942b60bd3a842d5377d96646bcbf46" +uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" +version = "0.2.1" + +[[Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[MeshIO]] +deps = ["ColorTypes", "FileIO", "GeometryTypes", "Printf", "Test"] +git-tree-sha1 = "3e01e12c4c626578a9d47fac0d15c9fe8dad5139" +uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" +version = "0.3.1" + +[[Missings]] +deps = ["Dates", "InteractiveUtils", "SparseArrays", "Test"] +git-tree-sha1 = "adc26d2ee85a49c413464110d922cf21efc9d233" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "0.3.1" + +[[Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[ModernGL]] +deps = ["Libdl"] +git-tree-sha1 = "f4f8fa8d04d3c1e7294f07fc37586c819466ad38" +uuid = "66fc600b-dfda-50eb-8b99-91cfa97b1301" +version = "1.0.0" + +[[NaNMath]] +deps = ["Compat"] +git-tree-sha1 = "ce3b85e484a5d4c71dd5316215069311135fa9f2" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "0.3.2" + +[[Observables]] +deps = ["Test"] +git-tree-sha1 = "dc02cec22747d1d10d9f70d8a1c03432b5bfbcd0" +uuid = "510215fc-4207-5dde-b226-833fc4488ee2" +version = "0.2.3" + +[[OffsetArrays]] +deps = ["DelimitedFiles", "Test"] +git-tree-sha1 = "7d1442cb06fbfbc4fea936c3c56b38daffd22d3b" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "0.9.1" + +[[OrderedCollections]] +deps = ["Random", "Serialization", "Test"] +git-tree-sha1 = "85619a3f3e17bb4761fe1b1fd47f0e979f964d5b" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.0.2" + +[[Packing]] +deps = ["GeometryTypes", "Test"] +git-tree-sha1 = "bc7c284233cf0518933bf9977e3e8234efcc1c30" +uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" +version = "0.3.0" + +[[PaddedViews]] +deps = ["OffsetArrays", "Test"] +git-tree-sha1 = "7da3e7e1a58cffbf10177553ae95f17b92516912" +uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" +version = "0.4.2" + +[[Parameters]] +deps = ["Markdown", "OrderedCollections", "REPL", "Test"] +git-tree-sha1 = "eec0fe16344cc14aa2e6251874ab30d62aff4f7c" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.10.2" + +[[Pkg]] +deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" + +[[PlotUtils]] +deps = ["Colors", "Dates", "Printf", "Random", "Reexport", "Test"] +git-tree-sha1 = "fd28f30a294a38ec847de95d8ac7ac916ccd7c06" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "0.5.5" + +[[Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[Random]] +deps = ["Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[RangeArrays]] +deps = ["Compat"] +git-tree-sha1 = "d925adfd5b01cb46fde89dc9548d167b3b136f4a" +uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" +version = "0.3.1" + +[[Ratios]] +deps = ["Compat"] +git-tree-sha1 = "fd159bead0a24e6270fd0573a340312bd4645cc2" +uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" +version = "0.3.0" + +[[Reexport]] +deps = ["Pkg"] +git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "0.2.0" + +[[Rotations]] +deps = ["LinearAlgebra", "Random", "StaticArrays", "Statistics", "Test"] +git-tree-sha1 = "b629771d0de88979cbdbf72ceddc54de58fde149" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "0.9.1" + +[[SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" + +[[Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[Showoff]] +deps = ["Compat"] +git-tree-sha1 = "276b24f3ace98bec911be7ff2928d497dc759085" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "0.2.1" + +[[SignedDistanceFields]] +deps = ["Random", "Statistics", "Test"] +git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" +uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" +version = "0.4.0" + +[[SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools", "Test"] +git-tree-sha1 = "c0a542b8d5e369b179ccd296b2ca987f6da5da0a" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.8.0" + +[[Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[SortingAlgorithms]] +deps = ["DataStructures", "Random", "Test"] +git-tree-sha1 = "03f5898c9959f8115e30bc7226ada7d0df554ddd" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "0.3.1" + +[[SparseArrays]] +deps = ["LinearAlgebra", "Random"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[SpecialFunctions]] +deps = ["BinDeps", "BinaryProvider", "Libdl", "Test"] +git-tree-sha1 = "0b45dc2e45ed77f445617b99ff2adf0f5b0f23ea" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "0.7.2" + +[[StaticArrays]] +deps = ["InteractiveUtils", "LinearAlgebra", "Random", "Statistics", "Test"] +git-tree-sha1 = "97c4bf0f647488dd7ac01ea12be5885f88762938" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "0.10.0" + +[[Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[StatsBase]] +deps = ["DataStructures", "LinearAlgebra", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "Test"] +git-tree-sha1 = "2722397d88f8ffef551948f6c20e1d74a743298c" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.26.0" + +[[Test]] +deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[URIParser]] +deps = ["Test", "Unicode"] +git-tree-sha1 = "6ddf8244220dfda2f17539fa8c9de20d6c575b69" +uuid = "30578b45-9adc-5946-b283-645ec420af67" +version = "0.4.0" + +[[UUIDs]] +deps = ["Random"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[UnicodeFun]] +deps = ["Test"] +git-tree-sha1 = "63cbbd00217fc9aafedf055b60459c1ae7e01ecc" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.0" + +[[VersionParsing]] +deps = ["Compat"] +git-tree-sha1 = "c9d5aa108588b978bd859554660c8a5c4f2f7669" +uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" +version = "1.1.3" + +[[WoodburyMatrices]] +deps = ["LinearAlgebra", "Random", "SparseArrays", "Test"] +git-tree-sha1 = "21772c33b447757ec7d3e61fcdfb9ea5c47eedcf" +uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" +version = "0.4.1" diff --git a/Project.toml b/Project.toml index a4172ea26a3..829f2d2fc47 100644 --- a/Project.toml +++ b/Project.toml @@ -5,19 +5,13 @@ version = "0.0.1" [deps] AbstractPlotting = "537997a7-5e4e-5d89-9595-2241ea00577e" AxisArrays = "39de3d68-74b9-583c-8d2d-e117c070f3a9" -BinaryProvider = "b99e7846-7c00-51b0-8f62-c81ae34c0232" -ColorBrewer = "a2cac450-b92f-5266-8821-25eda20663c8" ColorTypes = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" ColorVectorSpace = "c3611d14-8923-5661-9e6a-0046d554d3a4" Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" -Contour = "d38c429a-6771-53c6-b99e-75d170b6e991" -DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" FixedPointNumbers = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" FreeType = "b38be410-82b0-50bf-ab77-7b57e271db43" FreeTypeAbstraction = "663a7486-cb36-511b-a19d-713bb74d65c9" -GDAL = "add2ef01-049f-52c4-9ee2-e494f65e021a" GLFW = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" GeometryTypes = "4d00f742-c7ba-57c2-abde-4428a4b178cb" ImageAxes = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" @@ -33,15 +27,9 @@ Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a" MeshIO = "7269a6da-0436-5bbc-96c2-40638cbb6118" ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" Observables = "510215fc-4207-5dde-b226-833fc4488ee2" -PlotUtils = "995b91a9-d308-5afd-9ec6-746e21dbc043" -Primes = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" -QuartzImageIO = "dca85d43-d64c-5e67-8c65-017450d5d020" -RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" -Showoff = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" -UnicodeFun = "1cfade01-22cf-5700-b092-accc4b62d6e1" [compat] AbstractPlotting = ">=0.9.1" diff --git a/test/Manifest.toml b/test/Manifest.toml index 2b671468230..77d2a9016d7 100644 --- a/test/Manifest.toml +++ b/test/Manifest.toml @@ -5,8 +5,10 @@ uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" version = "0.3.2" [[AbstractPlotting]] -deps = ["ColorBrewer", "ColorTypes", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "Test", "UnicodeFun"] -git-tree-sha1 = "22eb6757f34439a84eff8ca5f4ebcb9a1f221102" +deps = ["ColorBrewer", "ColorTypes", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "ImageMagick", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "UnicodeFun"] +git-tree-sha1 = "b47cc331607de0daa3d3e40ed77b61b36dd19c17" +repo-rev = "master" +repo-url = "https://github.com/JuliaPlots/AbstractPlotting.jl.git" uuid = "537997a7-5e4e-5d89-9595-2241ea00577e" version = "0.9.1" @@ -306,7 +308,7 @@ uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" version = "2.3.0" [[GLMakie]] -deps = ["AbstractPlotting", "AxisArrays", "BinaryProvider", "ColorBrewer", "ColorTypes", "ColorVectorSpace", "Colors", "Contour", "DataFrames", "Documenter", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GDAL", "GLFW", "GeometryTypes", "ImageAxes", "ImageCore", "ImageFiltering", "ImageMagick", "ImageTransformations", "IndirectArrays", "IntervalSets", "IterTools", "LinearAlgebra", "Markdown", "MeshIO", "ModernGL", "Observables", "PlotUtils", "Primes", "Printf", "QuartzImageIO", "RDatasets", "Serialization", "Showoff", "StaticArrays", "UnicodeFun"] +deps = ["AbstractPlotting", "AxisArrays", "ColorTypes", "ColorVectorSpace", "Colors", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GLFW", "GeometryTypes", "ImageAxes", "ImageCore", "ImageMagick", "ImageTransformations", "IntervalSets", "IterTools", "LinearAlgebra", "MeshIO", "ModernGL", "Observables", "Printf", "Serialization", "StaticArrays"] path = ".." uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" version = "0.0.1" From 1ec9531b438c20a9347edb543f58a3c5daffbb8f Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 12 Dec 2018 20:01:10 +0100 Subject: [PATCH 0059/1328] clean up tomls --- Project.toml | 19 --------------- Manifest.toml => test/Manifest.toml | 36 ++++++++++++++--------------- test/Project.toml | 28 ++++++++++++++++++++++ 3 files changed, 45 insertions(+), 38 deletions(-) rename Manifest.toml => test/Manifest.toml (96%) create mode 100644 test/Project.toml diff --git a/Project.toml b/Project.toml index 5b7b5c7c383..7e437d22cd9 100644 --- a/Project.toml +++ b/Project.toml @@ -7,7 +7,6 @@ version = "0.0.0" AbstractPlotting = "537997a7-5e4e-5d89-9595-2241ea00577e" Cairo = "159f3aea-2a34-519c-b102-8c37f9878175" Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" -DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" GeometryTypes = "4d00f742-c7ba-57c2-abde-4428a4b178cb" ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534" @@ -16,24 +15,6 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" MeshIO = "7269a6da-0436-5bbc-96c2-40638cbb6118" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - - [compat] AbstractPlotting = ">=0.9.1" GeometryTypes = ">=0.7.2" - -[extras] -DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534" -ImageFiltering = "6a3955dd-da59-5b1f-98d4-e7296123deb5" -ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" -ImageTransformations = "02fcd773-0e25-5acc-982a-7f6622650795" -MakieGallery = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" -MeshIO = "7269a6da-0436-5bbc-96c2-40638cbb6118" -ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" -QuartzImageIO = "dca85d43-d64c-5e67-8c65-017450d5d020" -RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" -StatsMakie = "9d48ccf0-4268-5716-84ff-21228f561db3" - -[targets] -test = ["DataFrames", "MakieGallery", "MeshIO", "RDatasets", "StatsMakie", "ImageCore", "ImageTransformations", "ImageMagick", "QuartzImageIO"] diff --git a/Manifest.toml b/test/Manifest.toml similarity index 96% rename from Manifest.toml rename to test/Manifest.toml index 091d8336a20..314ecaaafe5 100644 --- a/Manifest.toml +++ b/test/Manifest.toml @@ -5,10 +5,10 @@ uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" version = "0.3.2" [[AbstractPlotting]] -deps = ["ColorBrewer", "ColorTypes", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "Test", "UnicodeFun"] -git-tree-sha1 = "22eb6757f34439a84eff8ca5f4ebcb9a1f221102" +deps = ["ColorBrewer", "ColorTypes", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "ImageMagick", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "Test", "UnicodeFun"] +git-tree-sha1 = "b47cc331607de0daa3d3e40ed77b61b36dd19c17" uuid = "537997a7-5e4e-5d89-9595-2241ea00577e" -version = "0.9.1" +version = "0.9.2" [[Arpack]] deps = ["BinaryProvider", "Libdl", "LinearAlgebra", "Random", "SparseArrays", "Test"] @@ -69,9 +69,9 @@ version = "0.2.0" [[CategoricalArrays]] deps = ["Compat", "Future", "Missings", "Printf", "Reexport", "Requires"] -git-tree-sha1 = "11419d157ab75a54a8af63315e7a279a593971bc" +git-tree-sha1 = "94d16e77dfacc59f6d6c1361866906dbb65b6f6b" uuid = "324d7699-5711-5eae-9e2f-1d82baa6b597" -version = "0.5.1" +version = "0.5.2" [[CodecZlib]] deps = ["BinaryProvider", "Libdl", "Test", "TranscodingStreams"] @@ -153,9 +153,9 @@ version = "0.2.0" [[DataFrames]] deps = ["CategoricalArrays", "CodecZlib", "Compat", "DataStreams", "Dates", "InteractiveUtils", "IteratorInterfaceExtensions", "LinearAlgebra", "Missings", "Printf", "Random", "Reexport", "SortingAlgorithms", "Statistics", "StatsBase", "TableTraits", "Tables", "Test", "TranscodingStreams", "Unicode", "WeakRefStrings"] -git-tree-sha1 = "ad34fefb72b18a8dd5c17fab9089d11111b61935" +git-tree-sha1 = "41ec35bcf49a860706924b9b3e322eed03164c83" uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -version = "0.14.1" +version = "0.15.2" [[DataStreams]] deps = ["Dates", "Missings", "Test", "WeakRefStrings"] @@ -225,9 +225,9 @@ version = "0.6.0" [[Documenter]] deps = ["Base64", "DocStringExtensions", "InteractiveUtils", "LibGit2", "Logging", "Markdown", "Pkg", "REPL", "Random", "Test", "Unicode"] -git-tree-sha1 = "9f2135e0e7ecb63f9c3ef73ea15a31d8cdb79bb7" +git-tree-sha1 = "a6db1c69925cdc53aafb38caec4446be26e0c617" uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "0.20.0" +version = "0.21.0" [[EzXML]] deps = ["BinaryProvider", "Libdl", "Printf", "Test"] @@ -525,9 +525,9 @@ version = "0.2.3" [[OffsetArrays]] deps = ["DelimitedFiles", "Test"] -git-tree-sha1 = "f446248f2dfbc13039a0b90994dd25b059b01eab" +git-tree-sha1 = "7d1442cb06fbfbc4fea936c3c56b38daffd22d3b" uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -version = "0.9.0" +version = "0.9.1" [[OnlineStats]] deps = ["DataStructures", "Dates", "LearnBase", "LinearAlgebra", "LossFunctions", "OnlineStatsBase", "PenaltyFunctions", "Random", "RecipesBase", "Reexport", "Statistics", "StatsBase", "SweepOperator", "Test"] @@ -579,9 +579,9 @@ version = "0.10.2" [[Parsers]] deps = ["Dates", "Mmap", "Test", "WeakRefStrings"] -git-tree-sha1 = "949ca36d47010bee093254467166487c921d490b" +git-tree-sha1 = "9c2b96d07344f9f716fee1c4a7258ac327d08a6c" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "0.2.14" +version = "0.2.15" [[PenaltyFunctions]] deps = ["InteractiveUtils", "LearnBase", "LinearAlgebra", "RecipesBase", "Reexport", "Test"] @@ -627,9 +627,9 @@ uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" [[QuadGK]] deps = ["DataStructures", "LinearAlgebra", "Test"] -git-tree-sha1 = "7e8dff9c205f36eceaf6e62a43ff851637ca45fc" +git-tree-sha1 = "3ce467a8e76c6030d4c3786e7d3a73442017cdc0" uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.0.2" +version = "2.0.3" [[QuartzImageIO]] deps = ["ColorTypes", "ColorVectorSpace", "FileIO", "FixedPointNumbers", "ImageCore", "Libdl", "Random", "Test"] @@ -759,10 +759,8 @@ version = "0.7.0" [[StatsMakie]] deps = ["AbstractPlotting", "Distributions", "FreqTables", "IndexedTables", "IntervalSets", "KernelDensity", "Loess", "NamedArrays", "Observables", "Random", "Statistics", "StatsBase", "Tables", "Test"] git-tree-sha1 = "12429b8d5308b27483f4d6148cefb86080e4d054" -repo-rev = "master" -repo-url = "https://github.com/JuliaPlots/StatsMakie.jl.git" -uuid = "9d48ccf0-4268-5716-84ff-21228f561db3" -version = "0.0.0" +uuid = "65254759-4cff-5aa5-8326-61ce017a8c70" +version = "0.0.1" [[SuiteSparse]] deps = ["Libdl", "LinearAlgebra", "SparseArrays"] diff --git a/test/Project.toml b/test/Project.toml new file mode 100644 index 00000000000..8f668d62022 --- /dev/null +++ b/test/Project.toml @@ -0,0 +1,28 @@ +name = "CairoMakie" +uuid = "f1797859-2bec-5491-832b-e19d79114491" +author = ["Simon Danisch "] +version = "0.0.0" + +[deps] +AbstractPlotting = "537997a7-5e4e-5d89-9595-2241ea00577e" +Cairo = "159f3aea-2a34-519c-b102-8c37f9878175" +Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" +DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +GeometryTypes = "4d00f742-c7ba-57c2-abde-4428a4b178cb" +ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534" +ImageFiltering = "6a3955dd-da59-5b1f-98d4-e7296123deb5" +ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" +ImageTransformations = "02fcd773-0e25-5acc-982a-7f6622650795" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +MakieGallery = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" +MeshIO = "7269a6da-0436-5bbc-96c2-40638cbb6118" +ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" +QuartzImageIO = "dca85d43-d64c-5e67-8c65-017450d5d020" +RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" +StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" +StatsMakie = "65254759-4cff-5aa5-8326-61ce017a8c70" + +[compat] +AbstractPlotting = ">=0.9.1" +GeometryTypes = ">=0.7.2" From dd80288b4b528de2aa0c4086c89adce4da0fb872 Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 13 Dec 2018 15:56:45 +0100 Subject: [PATCH 0060/1328] fix CI * remove comment * build project * forgot GL * next try --- .gitlab-ci.yml | 2 +- Manifest.toml | 464 +++++++++++++++++++++++++++++++++++++++++++++ Project.toml | 13 -- test/Manifest.toml | 8 +- 4 files changed, 470 insertions(+), 17 deletions(-) create mode 100644 Manifest.toml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d9b2d6054ba..b05c9715070 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -15,4 +15,4 @@ job: script: - julia -e 'using InteractiveUtils; versioninfo()' - - julia --project=test/ -e 'using Pkg; Pkg.test("GLMakie")' + - julia --project=test/ -e 'using Pkg; Pkg.build("GLMakie"); include("test/runtests.jl")' diff --git a/Manifest.toml b/Manifest.toml new file mode 100644 index 00000000000..57e74429fbf --- /dev/null +++ b/Manifest.toml @@ -0,0 +1,464 @@ +[[AbstractFFTs]] +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "8d59c3b1463b5e0ad05a3698167f85fac90e184d" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "0.3.2" + +[[AbstractPlotting]] +deps = ["ColorBrewer", "ColorTypes", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "ImageMagick", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "Test", "UnicodeFun"] +git-tree-sha1 = "b47cc331607de0daa3d3e40ed77b61b36dd19c17" +uuid = "537997a7-5e4e-5d89-9595-2241ea00577e" +version = "0.9.2" + +[[AxisAlgorithms]] +deps = ["Compat", "WoodburyMatrices"] +git-tree-sha1 = "99dabbe853e4f641ab21a676131f2cf9fb29937e" +uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" +version = "0.3.0" + +[[AxisArrays]] +deps = ["Compat", "Dates", "IntervalSets", "IterTools", "Random", "RangeArrays", "Test"] +git-tree-sha1 = "2e2536e9e6f27c4f8d09d8442b61a7ae0b910c28" +uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" +version = "0.3.0" + +[[Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[BinDeps]] +deps = ["Compat", "Libdl", "SHA", "URIParser"] +git-tree-sha1 = "12093ca6cdd0ee547c39b1870e0c9c3f154d9ca9" +uuid = "9e28174c-4ba2-5203-b857-d8d62c4213ee" +version = "0.8.10" + +[[BinaryProvider]] +deps = ["Libdl", "Pkg", "SHA", "Test"] +git-tree-sha1 = "055eb2690182ebc31087859c3dd8598371d3ef9e" +uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" +version = "0.5.3" + +[[CMake]] +deps = ["BinDeps", "Libdl", "Test"] +git-tree-sha1 = "74853a75c26a4a73ac391ee26ee29ebeb5583d9f" +uuid = "631607c0-34d2-5d66-819e-eb0f9aa2061a" +version = "1.1.0" + +[[CMakeWrapper]] +deps = ["BinDeps", "CMake", "Libdl", "Parameters", "Test"] +git-tree-sha1 = "2b43d451639984e3571951cc687b8509b0a86c6d" +uuid = "d5fb7624-851a-54ee-a528-d3f3bac0b4a0" +version = "0.2.2" + +[[ColorBrewer]] +deps = ["Colors", "JSON", "Test"] +git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" +uuid = "a2cac450-b92f-5266-8821-25eda20663c8" +version = "0.4.0" + +[[ColorTypes]] +deps = ["FixedPointNumbers", "Random", "Test"] +git-tree-sha1 = "f73b0e10f2a5756de7019818a41654686da06b09" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.7.5" + +[[ColorVectorSpace]] +deps = ["ColorTypes", "Colors", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "StatsBase", "Test"] +git-tree-sha1 = "a890f08e61b40e9843d7177206da61229a3603c8" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.6.2" + +[[Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "InteractiveUtils", "Printf", "Reexport", "Test"] +git-tree-sha1 = "9f0a0210450acb91c730b730a994f8eef1d3d543" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.9.5" + +[[Compat]] +deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] +git-tree-sha1 = "ec61a16eed883ad0cfa002d7489b3ce6d039bb9a" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "1.4.0" + +[[Conda]] +deps = ["Compat", "JSON", "VersionParsing"] +git-tree-sha1 = "fb86fe40cb5b35990e368709bfdc1b46dbb99dac" +uuid = "8f4d0f93-b110-5947-807f-2305c1781a2d" +version = "1.1.1" + +[[Contour]] +deps = ["LinearAlgebra", "StaticArrays", "Test"] +git-tree-sha1 = "b974e164358fea753ef853ce7bad97afec15bb80" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.5.1" + +[[CoordinateTransformations]] +deps = ["Compat", "Rotations", "StaticArrays"] +git-tree-sha1 = "47f05d0b7f4999609f92e657147df000818c1f24" +uuid = "150eb455-5306-5404-9cee-2592286d6298" +version = "0.5.0" + +[[DataStructures]] +deps = ["InteractiveUtils", "OrderedCollections", "Random", "Serialization", "Test"] +git-tree-sha1 = "8fc6e166e24fda04b2b648d4260cdad241788c54" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.14.0" + +[[Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[DelimitedFiles]] +deps = ["Mmap"] +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" + +[[Distributed]] +deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[FFTW]] +deps = ["AbstractFFTs", "BinaryProvider", "Compat", "Conda", "Libdl", "LinearAlgebra", "Reexport", "Test"] +git-tree-sha1 = "29cda58afbf62f35b1a094882ad6c745a47b2eaa" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "0.2.4" + +[[FileIO]] +deps = ["Pkg", "Random", "Test"] +git-tree-sha1 = "1a114d08094e7267ba8d4d684f930d5a722184de" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.0.4" + +[[FixedPointNumbers]] +deps = ["Test"] +git-tree-sha1 = "b8045033701c3b10bf2324d7203404be7aef88ba" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.5.3" + +[[FreeType]] +deps = ["BinaryProvider", "Libdl", "Pkg", "Test"] +git-tree-sha1 = "06462b9d5aca708d764d16e5ba6a83ba7b753d57" +uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" +version = "2.1.1" + +[[FreeTypeAbstraction]] +deps = ["ColorVectorSpace", "Colors", "FreeType", "StaticArrays", "Test"] +git-tree-sha1 = "271ef13438bd0946950fd34d9241e5beefd6d4b3" +uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" +version = "0.4.1" + +[[GLFW]] +deps = ["BinDeps", "CMakeWrapper", "Homebrew", "Libdl", "Test"] +git-tree-sha1 = "035e2b5e9c335afae1e92ecfe532cf0620da869f" +uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" +version = "2.3.0" + +[[GeometryTypes]] +deps = ["ColorTypes", "FixedPointNumbers", "IterTools", "LinearAlgebra", "StaticArrays", "Test"] +git-tree-sha1 = "28b193e14466beecf928449e0f8505ff6de3709d" +uuid = "4d00f742-c7ba-57c2-abde-4428a4b178cb" +version = "0.7.2" + +[[Graphics]] +deps = ["Colors", "Compat", "NaNMath"] +git-tree-sha1 = "e3ead4211073d4117a0d2ef7d1efc5c8092c8412" +uuid = "a2bd30eb-e257-5431-a919-1863eab51364" +version = "0.4.0" + +[[Homebrew]] +deps = ["BinDeps", "InteractiveUtils", "JSON", "Libdl", "Test", "Unicode"] +git-tree-sha1 = "5582ec74f735cf8d12e562a2e65c47f34063bd51" +uuid = "d9be37ee-ecc9-5288-90f1-b9ca67657a75" +version = "0.7.0" + +[[IdentityRanges]] +deps = ["OffsetArrays", "Test"] +git-tree-sha1 = "f5ca23a08397288924a7535cd898d8ccbcde5ba5" +uuid = "bbac6d45-d8f3-5730-bfe4-7a449cd117ca" +version = "0.2.0" + +[[ImageAxes]] +deps = ["AxisArrays", "Colors", "FixedPointNumbers", "ImageCore", "MappedArrays", "Reexport", "SimpleTraits", "Test"] +git-tree-sha1 = "5735ec90843acaa67a4624611921c686cdf4efbf" +uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" +version = "0.5.0" + +[[ImageCore]] +deps = ["ColorTypes", "Colors", "FFTW", "FixedPointNumbers", "Graphics", "MappedArrays", "OffsetArrays", "PaddedViews", "Random", "Statistics", "Test"] +git-tree-sha1 = "5e7b1f49c80541860e08a7ea91805a24c1641f19" +uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" +version = "0.7.3" + +[[ImageMagick]] +deps = ["BinaryProvider", "ColorTypes", "FileIO", "FixedPointNumbers", "ImageCore", "InteractiveUtils", "Libdl", "Pkg", "Random", "Test"] +git-tree-sha1 = "0e4cc77fb131061b3525a97fd7d483b253c3aaad" +uuid = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" +version = "0.7.1" + +[[ImageTransformations]] +deps = ["AxisAlgorithms", "ColorTypes", "ColorVectorSpace", "Colors", "CoordinateTransformations", "FixedPointNumbers", "IdentityRanges", "ImageCore", "Interpolations", "LinearAlgebra", "OffsetArrays", "StaticArrays", "Test"] +git-tree-sha1 = "18ae1c0a8df31549a9452ceac93751d4aa166071" +uuid = "02fcd773-0e25-5acc-982a-7f6622650795" +version = "0.7.1" + +[[InteractiveUtils]] +deps = ["LinearAlgebra", "Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[Interpolations]] +deps = ["AxisAlgorithms", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "SharedArrays", "SparseArrays", "StaticArrays", "Test", "WoodburyMatrices"] +git-tree-sha1 = "3493536a64dae5a21c0cc8aecf680647f3e12313" +uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" +version = "0.11.0" + +[[IntervalSets]] +deps = ["Compat"] +git-tree-sha1 = "9dc556002f23740de13946e8c2e41798e09a9249" +uuid = "8197267c-284f-5f27-9208-e0e47529a953" +version = "0.3.1" + +[[IterTools]] +deps = ["SparseArrays", "Test"] +git-tree-sha1 = "79246285c43602384e6f1943b3554042a3712056" +uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +version = "1.1.1" + +[[JSON]] +deps = ["Dates", "Distributed", "Mmap", "Sockets", "Test", "Unicode"] +git-tree-sha1 = "1f7a25b53ec67f5e9422f1f551ee216503f4a0fa" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.20.0" + +[[LibGit2]] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[LinearAlgebra]] +deps = ["Libdl"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[MacroTools]] +deps = ["Compat"] +git-tree-sha1 = "c443e1c8d58a4e9f61b708ad0a88286c7042145b" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.4.4" + +[[MappedArrays]] +deps = ["Test"] +git-tree-sha1 = "923441c5ac942b60bd3a842d5377d96646bcbf46" +uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" +version = "0.2.1" + +[[Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[MeshIO]] +deps = ["ColorTypes", "FileIO", "GeometryTypes", "Printf", "Test"] +git-tree-sha1 = "3e01e12c4c626578a9d47fac0d15c9fe8dad5139" +uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" +version = "0.3.1" + +[[Missings]] +deps = ["Dates", "InteractiveUtils", "SparseArrays", "Test"] +git-tree-sha1 = "adc26d2ee85a49c413464110d922cf21efc9d233" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "0.3.1" + +[[Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[ModernGL]] +deps = ["Libdl"] +git-tree-sha1 = "f4f8fa8d04d3c1e7294f07fc37586c819466ad38" +uuid = "66fc600b-dfda-50eb-8b99-91cfa97b1301" +version = "1.0.0" + +[[NaNMath]] +deps = ["Compat"] +git-tree-sha1 = "ce3b85e484a5d4c71dd5316215069311135fa9f2" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "0.3.2" + +[[Observables]] +deps = ["Test"] +git-tree-sha1 = "dc02cec22747d1d10d9f70d8a1c03432b5bfbcd0" +uuid = "510215fc-4207-5dde-b226-833fc4488ee2" +version = "0.2.3" + +[[OffsetArrays]] +deps = ["DelimitedFiles", "Test"] +git-tree-sha1 = "7d1442cb06fbfbc4fea936c3c56b38daffd22d3b" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "0.9.1" + +[[OrderedCollections]] +deps = ["Random", "Serialization", "Test"] +git-tree-sha1 = "85619a3f3e17bb4761fe1b1fd47f0e979f964d5b" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.0.2" + +[[Packing]] +deps = ["GeometryTypes", "Test"] +git-tree-sha1 = "bc7c284233cf0518933bf9977e3e8234efcc1c30" +uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" +version = "0.3.0" + +[[PaddedViews]] +deps = ["OffsetArrays", "Test"] +git-tree-sha1 = "7da3e7e1a58cffbf10177553ae95f17b92516912" +uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" +version = "0.4.2" + +[[Parameters]] +deps = ["Markdown", "OrderedCollections", "REPL", "Test"] +git-tree-sha1 = "eec0fe16344cc14aa2e6251874ab30d62aff4f7c" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.10.2" + +[[Pkg]] +deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" + +[[PlotUtils]] +deps = ["Colors", "Dates", "Printf", "Random", "Reexport", "Test"] +git-tree-sha1 = "fd28f30a294a38ec847de95d8ac7ac916ccd7c06" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "0.5.5" + +[[Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[Random]] +deps = ["Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[RangeArrays]] +deps = ["Compat"] +git-tree-sha1 = "d925adfd5b01cb46fde89dc9548d167b3b136f4a" +uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" +version = "0.3.1" + +[[Ratios]] +deps = ["Compat"] +git-tree-sha1 = "fd159bead0a24e6270fd0573a340312bd4645cc2" +uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" +version = "0.3.0" + +[[Reexport]] +deps = ["Pkg"] +git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "0.2.0" + +[[Rotations]] +deps = ["LinearAlgebra", "Random", "StaticArrays", "Statistics", "Test"] +git-tree-sha1 = "b629771d0de88979cbdbf72ceddc54de58fde149" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "0.9.1" + +[[SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" + +[[Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[Showoff]] +deps = ["Compat"] +git-tree-sha1 = "276b24f3ace98bec911be7ff2928d497dc759085" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "0.2.1" + +[[SignedDistanceFields]] +deps = ["Random", "Statistics", "Test"] +git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" +uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" +version = "0.4.0" + +[[SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools", "Test"] +git-tree-sha1 = "c0a542b8d5e369b179ccd296b2ca987f6da5da0a" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.8.0" + +[[Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[SortingAlgorithms]] +deps = ["DataStructures", "Random", "Test"] +git-tree-sha1 = "03f5898c9959f8115e30bc7226ada7d0df554ddd" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "0.3.1" + +[[SparseArrays]] +deps = ["LinearAlgebra", "Random"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[SpecialFunctions]] +deps = ["BinDeps", "BinaryProvider", "Libdl", "Test"] +git-tree-sha1 = "0b45dc2e45ed77f445617b99ff2adf0f5b0f23ea" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "0.7.2" + +[[StaticArrays]] +deps = ["InteractiveUtils", "LinearAlgebra", "Random", "Statistics", "Test"] +git-tree-sha1 = "97c4bf0f647488dd7ac01ea12be5885f88762938" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "0.10.0" + +[[Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[StatsBase]] +deps = ["DataStructures", "LinearAlgebra", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "Test"] +git-tree-sha1 = "2722397d88f8ffef551948f6c20e1d74a743298c" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.26.0" + +[[Test]] +deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[URIParser]] +deps = ["Test", "Unicode"] +git-tree-sha1 = "6ddf8244220dfda2f17539fa8c9de20d6c575b69" +uuid = "30578b45-9adc-5946-b283-645ec420af67" +version = "0.4.0" + +[[UUIDs]] +deps = ["Random"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[UnicodeFun]] +deps = ["Test"] +git-tree-sha1 = "63cbbd00217fc9aafedf055b60459c1ae7e01ecc" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.0" + +[[VersionParsing]] +deps = ["Compat"] +git-tree-sha1 = "c9d5aa108588b978bd859554660c8a5c4f2f7669" +uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" +version = "1.1.3" + +[[WoodburyMatrices]] +deps = ["LinearAlgebra", "Random", "SparseArrays", "Test"] +git-tree-sha1 = "21772c33b447757ec7d3e61fcdfb9ea5c47eedcf" +uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" +version = "0.4.1" diff --git a/Project.toml b/Project.toml index 8011b0a97e6..829f2d2fc47 100644 --- a/Project.toml +++ b/Project.toml @@ -5,19 +5,13 @@ version = "0.0.1" [deps] AbstractPlotting = "537997a7-5e4e-5d89-9595-2241ea00577e" AxisArrays = "39de3d68-74b9-583c-8d2d-e117c070f3a9" -BinaryProvider = "b99e7846-7c00-51b0-8f62-c81ae34c0232" -ColorBrewer = "a2cac450-b92f-5266-8821-25eda20663c8" ColorTypes = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" ColorVectorSpace = "c3611d14-8923-5661-9e6a-0046d554d3a4" Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" -Contour = "d38c429a-6771-53c6-b99e-75d170b6e991" -DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" FixedPointNumbers = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" FreeType = "b38be410-82b0-50bf-ab77-7b57e271db43" FreeTypeAbstraction = "663a7486-cb36-511b-a19d-713bb74d65c9" -GDAL = "add2ef01-049f-52c4-9ee2-e494f65e021a" GLFW = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" GeometryTypes = "4d00f742-c7ba-57c2-abde-4428a4b178cb" ImageAxes = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" @@ -29,20 +23,13 @@ IndirectArrays = "9b13fd28-a010-5f03-acff-a1bbcff69959" IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -#MakieGallery = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a" MeshIO = "7269a6da-0436-5bbc-96c2-40638cbb6118" ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" Observables = "510215fc-4207-5dde-b226-833fc4488ee2" -PlotUtils = "995b91a9-d308-5afd-9ec6-746e21dbc043" -Primes = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" -QuartzImageIO = "dca85d43-d64c-5e67-8c65-017450d5d020" -RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" -Showoff = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" -UnicodeFun = "1cfade01-22cf-5700-b092-accc4b62d6e1" [compat] AbstractPlotting = ">=0.9.1" diff --git a/test/Manifest.toml b/test/Manifest.toml index 2b671468230..77d2a9016d7 100644 --- a/test/Manifest.toml +++ b/test/Manifest.toml @@ -5,8 +5,10 @@ uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" version = "0.3.2" [[AbstractPlotting]] -deps = ["ColorBrewer", "ColorTypes", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "Test", "UnicodeFun"] -git-tree-sha1 = "22eb6757f34439a84eff8ca5f4ebcb9a1f221102" +deps = ["ColorBrewer", "ColorTypes", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "ImageMagick", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "UnicodeFun"] +git-tree-sha1 = "b47cc331607de0daa3d3e40ed77b61b36dd19c17" +repo-rev = "master" +repo-url = "https://github.com/JuliaPlots/AbstractPlotting.jl.git" uuid = "537997a7-5e4e-5d89-9595-2241ea00577e" version = "0.9.1" @@ -306,7 +308,7 @@ uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" version = "2.3.0" [[GLMakie]] -deps = ["AbstractPlotting", "AxisArrays", "BinaryProvider", "ColorBrewer", "ColorTypes", "ColorVectorSpace", "Colors", "Contour", "DataFrames", "Documenter", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GDAL", "GLFW", "GeometryTypes", "ImageAxes", "ImageCore", "ImageFiltering", "ImageMagick", "ImageTransformations", "IndirectArrays", "IntervalSets", "IterTools", "LinearAlgebra", "Markdown", "MeshIO", "ModernGL", "Observables", "PlotUtils", "Primes", "Printf", "QuartzImageIO", "RDatasets", "Serialization", "Showoff", "StaticArrays", "UnicodeFun"] +deps = ["AbstractPlotting", "AxisArrays", "ColorTypes", "ColorVectorSpace", "Colors", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GLFW", "GeometryTypes", "ImageAxes", "ImageCore", "ImageMagick", "ImageTransformations", "IntervalSets", "IterTools", "LinearAlgebra", "MeshIO", "ModernGL", "Observables", "Printf", "Serialization", "StaticArrays"] path = ".." uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" version = "0.0.1" From 107f93ef445df6500e9c4e1e924b660311709b35 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Tue, 18 Dec 2018 11:04:37 +0100 Subject: [PATCH 0061/1328] fix char marker scaling --- src/GLVisualize/visualize/particles.jl | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/GLVisualize/visualize/particles.jl b/src/GLVisualize/visualize/particles.jl index 5956170c961..c0b2e9e23cf 100644 --- a/src/GLVisualize/visualize/particles.jl +++ b/src/GLVisualize/visualize/particles.jl @@ -445,6 +445,13 @@ function _default( sprites(p, s, data) end + +function correct_scale(char, scale) + Vec2f0(glyph_scale!(char, scale)) +end +function correct_scale(char, scale::AbstractVector) + Vec2f0(glyph_scale!.(char, scale)) +end """ Main assemble functions for sprite particles. Sprites are anything like distance fields, images and simple geometries @@ -462,17 +469,16 @@ function sprites(p, s, data) position_z = nothing => GLBuffer scale = const_lift(primitive_scale, p[1]) => GLBuffer - scale_x = nothing => GLBuffer - scale_y = nothing => GLBuffer - scale_z = nothing => GLBuffer + scale_x = nothing => GLBuffer + scale_y = nothing => GLBuffer + scale_z = nothing => GLBuffer rotation = rot => GLBuffer image = nothing => Texture end # TODO don't make this dependant on some shady type dispatch - if isa(to_value(p[1]), Char) && !isa(to_value(scale), Vec) # correct dimensions - scale = const_lift(s-> Vec2f0(glyph_scale!(p[1], s)), scale) - data[:scale] = scale + if isa(to_value(p[1]), Char) && !isa(to_value(scale), Union{StaticVector, AbstractVector{<: StaticVector}}) # correct dimensions + data[:scale] = const_lift(correct_scale, p[1], scale) end @gen_defaults! data begin From 7f532e4b8ab0fb5bc0a335324a3b284d66b0cf6b Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Tue, 15 Jan 2019 15:18:07 +0100 Subject: [PATCH 0062/1328] get tests to pass --- test/REQUIRE | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 test/REQUIRE diff --git a/test/REQUIRE b/test/REQUIRE new file mode 100644 index 00000000000..e7292e129a7 --- /dev/null +++ b/test/REQUIRE @@ -0,0 +1,22 @@ +GeometryTypes 0.7.2 +ImageCore +ImageTransformations +@windows ImageMagick +@linux ImageMagick +@osx QuartzImageIO +ColorTypes +Colors +ColorVectorSpace +FixedPointNumbers +Documenter +ModernGL +MeshIO +ImageMagick +ImageTransformations +FileIO +ImageFiltering +DataFrames +RDatasets +BinaryProvider +StatsMakie +MakieGallery From 4fdbca0aa414f3a167df14f3150e904f18aa6dd9 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Tue, 15 Jan 2019 15:26:23 +0100 Subject: [PATCH 0063/1328] update tomls --- Manifest.toml | 858 -------------------------------------------------- Project.toml | 2 +- 2 files changed, 1 insertion(+), 859 deletions(-) delete mode 100644 Manifest.toml diff --git a/Manifest.toml b/Manifest.toml deleted file mode 100644 index 091d8336a20..00000000000 --- a/Manifest.toml +++ /dev/null @@ -1,858 +0,0 @@ -[[AbstractFFTs]] -deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "8d59c3b1463b5e0ad05a3698167f85fac90e184d" -uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" -version = "0.3.2" - -[[AbstractPlotting]] -deps = ["ColorBrewer", "ColorTypes", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "Test", "UnicodeFun"] -git-tree-sha1 = "22eb6757f34439a84eff8ca5f4ebcb9a1f221102" -uuid = "537997a7-5e4e-5d89-9595-2241ea00577e" -version = "0.9.1" - -[[Arpack]] -deps = ["BinaryProvider", "Libdl", "LinearAlgebra", "Random", "SparseArrays", "Test"] -git-tree-sha1 = "1ce1ce9984683f0b6a587d5bdbc688ecb480096f" -uuid = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97" -version = "0.3.0" - -[[AxisAlgorithms]] -deps = ["Compat", "WoodburyMatrices"] -git-tree-sha1 = "99dabbe853e4f641ab21a676131f2cf9fb29937e" -uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" -version = "0.3.0" - -[[Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" - -[[BinDeps]] -deps = ["Compat", "Libdl", "SHA", "URIParser"] -git-tree-sha1 = "12093ca6cdd0ee547c39b1870e0c9c3f154d9ca9" -uuid = "9e28174c-4ba2-5203-b857-d8d62c4213ee" -version = "0.8.10" - -[[BinaryProvider]] -deps = ["Libdl", "Pkg", "SHA", "Test"] -git-tree-sha1 = "055eb2690182ebc31087859c3dd8598371d3ef9e" -uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" -version = "0.5.3" - -[[BufferedStreams]] -deps = ["Compat", "Test"] -git-tree-sha1 = "5d55b9486590fdda5905c275bb21ce1f0754020f" -uuid = "e1450e63-4bb3-523b-b2a4-4ffa8c0fd77d" -version = "1.0.0" - -[[CSV]] -deps = ["CategoricalArrays", "DataFrames", "DataStreams", "Dates", "Mmap", "Parsers", "Profile", "Random", "Tables", "Test", "Unicode", "WeakRefStrings"] -git-tree-sha1 = "b92c6f626a044cc9619156d54994b94084d40abe" -uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" -version = "0.4.3" - -[[Cairo]] -deps = ["BinDeps", "Colors", "Compat", "Graphics", "Homebrew", "Libdl", "WinRPM"] -git-tree-sha1 = "a427098d5aa2808504d94b8ed9fc5740ceaf71d0" -uuid = "159f3aea-2a34-519c-b102-8c37f9878175" -version = "0.5.6" - -[[Calculus]] -deps = ["Compat"] -git-tree-sha1 = "f60954495a7afcee4136f78d1d60350abd37a409" -uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" -version = "0.4.1" - -[[CatIndices]] -deps = ["CustomUnitRanges", "OffsetArrays", "Test"] -git-tree-sha1 = "254cf73ea369d2e39bfd6c5eb27a2296cfaed68c" -uuid = "aafaddc9-749c-510e-ac4f-586e18779b91" -version = "0.2.0" - -[[CategoricalArrays]] -deps = ["Compat", "Future", "Missings", "Printf", "Reexport", "Requires"] -git-tree-sha1 = "11419d157ab75a54a8af63315e7a279a593971bc" -uuid = "324d7699-5711-5eae-9e2f-1d82baa6b597" -version = "0.5.1" - -[[CodecZlib]] -deps = ["BinaryProvider", "Libdl", "Test", "TranscodingStreams"] -git-tree-sha1 = "e3df104c84dfc108f0ca203fd7f5bbdc98641ae9" -uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.5.1" - -[[ColorBrewer]] -deps = ["Colors", "JSON", "Test"] -git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" -uuid = "a2cac450-b92f-5266-8821-25eda20663c8" -version = "0.4.0" - -[[ColorTypes]] -deps = ["FixedPointNumbers", "Random", "Test"] -git-tree-sha1 = "f73b0e10f2a5756de7019818a41654686da06b09" -uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" -version = "0.7.5" - -[[ColorVectorSpace]] -deps = ["ColorTypes", "Colors", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "StatsBase", "Test"] -git-tree-sha1 = "a890f08e61b40e9843d7177206da61229a3603c8" -uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" -version = "0.6.2" - -[[Colors]] -deps = ["ColorTypes", "FixedPointNumbers", "InteractiveUtils", "Printf", "Reexport", "Test"] -git-tree-sha1 = "9f0a0210450acb91c730b730a994f8eef1d3d543" -uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" -version = "0.9.5" - -[[Combinatorics]] -deps = ["LinearAlgebra", "Polynomials", "Test"] -git-tree-sha1 = "50b3ae4d643dc27eaff69fb6be06ee094d5500c9" -uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" -version = "0.7.0" - -[[CommonSubexpressions]] -deps = ["Test"] -git-tree-sha1 = "efdaf19ab11c7889334ca247ff4c9f7c322817b0" -uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" -version = "0.2.0" - -[[Compat]] -deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] -git-tree-sha1 = "ec61a16eed883ad0cfa002d7489b3ce6d039bb9a" -uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "1.4.0" - -[[ComputationalResources]] -deps = ["Test"] -git-tree-sha1 = "89e7e7ed20af73d9f78877d2b8d1194e7b6ff13d" -uuid = "ed09eef8-17a6-5b46-8889-db040fac31e3" -version = "0.3.0" - -[[Conda]] -deps = ["Compat", "JSON", "VersionParsing"] -git-tree-sha1 = "fb86fe40cb5b35990e368709bfdc1b46dbb99dac" -uuid = "8f4d0f93-b110-5947-807f-2305c1781a2d" -version = "1.1.1" - -[[Contour]] -deps = ["LinearAlgebra", "StaticArrays", "Test"] -git-tree-sha1 = "b974e164358fea753ef853ce7bad97afec15bb80" -uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" -version = "0.5.1" - -[[CoordinateTransformations]] -deps = ["Compat", "Rotations", "StaticArrays"] -git-tree-sha1 = "47f05d0b7f4999609f92e657147df000818c1f24" -uuid = "150eb455-5306-5404-9cee-2592286d6298" -version = "0.5.0" - -[[CustomUnitRanges]] -deps = ["Test"] -git-tree-sha1 = "0a106457a1831555857e18ac9617279c22fc393b" -uuid = "dc8bdbbb-1ca9-579f-8c36-e416f6a65cce" -version = "0.2.0" - -[[DataFrames]] -deps = ["CategoricalArrays", "CodecZlib", "Compat", "DataStreams", "Dates", "InteractiveUtils", "IteratorInterfaceExtensions", "LinearAlgebra", "Missings", "Printf", "Random", "Reexport", "SortingAlgorithms", "Statistics", "StatsBase", "TableTraits", "Tables", "Test", "TranscodingStreams", "Unicode", "WeakRefStrings"] -git-tree-sha1 = "ad34fefb72b18a8dd5c17fab9089d11111b61935" -uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -version = "0.14.1" - -[[DataStreams]] -deps = ["Dates", "Missings", "Test", "WeakRefStrings"] -git-tree-sha1 = "69c72a1beb4fc79490c361635664e13c8e4a9548" -uuid = "9a8bc11e-79be-5b39-94d7-1ccc349a1a85" -version = "0.4.1" - -[[DataStructures]] -deps = ["InteractiveUtils", "OrderedCollections", "Random", "Serialization", "Test"] -git-tree-sha1 = "8fc6e166e24fda04b2b648d4260cdad241788c54" -uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.14.0" - -[[DataValues]] -deps = ["Dates", "InteractiveUtils", "LinearAlgebra", "Random", "Test"] -git-tree-sha1 = "4fedccda7e5111354c7dcc832c7da83ff7258765" -uuid = "e7dc6d0d-1eca-5fa6-8ad6-5aecde8b7ea5" -version = "0.4.5" - -[[Dates]] -deps = ["Printf"] -uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" - -[[DelimitedFiles]] -deps = ["Mmap"] -uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" - -[[DiffEqDiffTools]] -deps = ["LinearAlgebra", "Test"] -git-tree-sha1 = "67700c9fc82033ec68a145bc650f6b9debdf9103" -uuid = "01453d9d-ee7c-5054-8395-0335cb756afa" -version = "0.7.1" - -[[DiffResults]] -deps = ["Compat", "StaticArrays"] -git-tree-sha1 = "db8acf46717b13d6c48deb7a12007c7f85a70cf7" -uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" -version = "0.0.3" - -[[DiffRules]] -deps = ["Random", "Test"] -git-tree-sha1 = "c49ec69428ffea0c1d1bbdc63d1a70f5df5860ad" -uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" -version = "0.0.7" - -[[Distances]] -deps = ["LinearAlgebra", "Printf", "Random", "Statistics", "Test"] -git-tree-sha1 = "2f38605722542f1c0a32dd2856fb529d8c226c69" -uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" -version = "0.7.3" - -[[Distributed]] -deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] -uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" - -[[Distributions]] -deps = ["Distributed", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsBase", "StatsFuns", "Test"] -git-tree-sha1 = "c24e9b6500c037673f0241a2783472b8c3d080c7" -uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.16.4" - -[[DocStringExtensions]] -deps = ["LibGit2", "Markdown", "Pkg", "Test"] -git-tree-sha1 = "1df01539a1c952cef21f2d2d1c092c2bcf0177d7" -uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.6.0" - -[[Documenter]] -deps = ["Base64", "DocStringExtensions", "InteractiveUtils", "LibGit2", "Logging", "Markdown", "Pkg", "REPL", "Random", "Test", "Unicode"] -git-tree-sha1 = "9f2135e0e7ecb63f9c3ef73ea15a31d8cdb79bb7" -uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "0.20.0" - -[[EzXML]] -deps = ["BinaryProvider", "Libdl", "Printf", "Test"] -git-tree-sha1 = "5623d1486bfaadd815f5c4ca501adda02b5337f1" -uuid = "8f5d6c58-4d21-5cfd-889c-e3ad7ee6a615" -version = "0.9.0" - -[[FFTViews]] -deps = ["CustomUnitRanges", "FFTW", "Test"] -git-tree-sha1 = "9d7993227ca7c0fdb6b31deef193adbba11c8f4e" -uuid = "4f61f5a4-77b1-5117-aa51-3ab5ef4ef0cd" -version = "0.2.0" - -[[FFTW]] -deps = ["AbstractFFTs", "BinaryProvider", "Compat", "Conda", "Libdl", "LinearAlgebra", "Reexport", "Test"] -git-tree-sha1 = "29cda58afbf62f35b1a094882ad6c745a47b2eaa" -uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" -version = "0.2.4" - -[[FileIO]] -deps = ["Pkg", "Random", "Test"] -git-tree-sha1 = "1a114d08094e7267ba8d4d684f930d5a722184de" -uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -version = "1.0.4" - -[[FixedPointNumbers]] -deps = ["Test"] -git-tree-sha1 = "b8045033701c3b10bf2324d7203404be7aef88ba" -uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.5.3" - -[[ForwardDiff]] -deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "InteractiveUtils", "LinearAlgebra", "NaNMath", "Random", "SparseArrays", "SpecialFunctions", "StaticArrays", "Test"] -git-tree-sha1 = "b91250044374764e7c29af59a774c4b8d6100b6e" -uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "0.10.1" - -[[FreeType]] -deps = ["BinaryProvider", "Libdl", "Pkg", "Test"] -git-tree-sha1 = "06462b9d5aca708d764d16e5ba6a83ba7b753d57" -uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" -version = "2.1.1" - -[[FreeTypeAbstraction]] -deps = ["ColorVectorSpace", "Colors", "FreeType", "StaticArrays", "Test"] -git-tree-sha1 = "271ef13438bd0946950fd34d9241e5beefd6d4b3" -uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" -version = "0.4.1" - -[[FreqTables]] -deps = ["CategoricalArrays", "NamedArrays", "Tables", "Test"] -git-tree-sha1 = "93ce75cae27c2d1c6518771d597b6dd0a3d623d3" -uuid = "da1fdf0e-e0ff-5433-a45f-9bb5ff651cb1" -version = "0.3.1" - -[[Future]] -deps = ["Random"] -uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" - -[[GDAL]] -deps = ["BinaryProvider", "Libdl", "Test"] -git-tree-sha1 = "100429098b7ec9930f7db9ba68aee3495365be24" -uuid = "add2ef01-049f-52c4-9ee2-e494f65e021a" -version = "0.2.0" - -[[GeometryTypes]] -deps = ["ColorTypes", "FixedPointNumbers", "IterTools", "LinearAlgebra", "StaticArrays", "Test"] -git-tree-sha1 = "28b193e14466beecf928449e0f8505ff6de3709d" -uuid = "4d00f742-c7ba-57c2-abde-4428a4b178cb" -version = "0.7.2" - -[[Graphics]] -deps = ["Colors", "Compat", "NaNMath"] -git-tree-sha1 = "e3ead4211073d4117a0d2ef7d1efc5c8092c8412" -uuid = "a2bd30eb-e257-5431-a919-1863eab51364" -version = "0.4.0" - -[[HTTPClient]] -deps = ["Compat", "LibCURL"] -git-tree-sha1 = "161d5776ae8e585ac0b8c20fb81f17ab755b3671" -uuid = "0862f596-cf2d-50af-8ef4-f2be67dfa83f" -version = "0.2.1" - -[[Homebrew]] -deps = ["BinDeps", "InteractiveUtils", "JSON", "Libdl", "Test", "Unicode"] -git-tree-sha1 = "5582ec74f735cf8d12e562a2e65c47f34063bd51" -uuid = "d9be37ee-ecc9-5288-90f1-b9ca67657a75" -version = "0.7.0" - -[[IdentityRanges]] -deps = ["OffsetArrays", "Test"] -git-tree-sha1 = "f5ca23a08397288924a7535cd898d8ccbcde5ba5" -uuid = "bbac6d45-d8f3-5730-bfe4-7a449cd117ca" -version = "0.2.0" - -[[ImageCore]] -deps = ["ColorTypes", "Colors", "FFTW", "FixedPointNumbers", "Graphics", "MappedArrays", "OffsetArrays", "PaddedViews", "Random", "Statistics", "Test"] -git-tree-sha1 = "5e7b1f49c80541860e08a7ea91805a24c1641f19" -uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" -version = "0.7.3" - -[[ImageFiltering]] -deps = ["CatIndices", "ColorVectorSpace", "Colors", "ComputationalResources", "DataStructures", "FFTViews", "FFTW", "FixedPointNumbers", "ImageCore", "LinearAlgebra", "Logging", "MappedArrays", "OffsetArrays", "Random", "StaticArrays", "Statistics", "Test", "TiledIteration"] -git-tree-sha1 = "2d23d8f8c1def1e8d67d05e554baacc780d9313d" -uuid = "6a3955dd-da59-5b1f-98d4-e7296123deb5" -version = "0.5.1" - -[[ImageMagick]] -deps = ["BinaryProvider", "ColorTypes", "FileIO", "FixedPointNumbers", "ImageCore", "InteractiveUtils", "Libdl", "Pkg", "Random", "Test"] -git-tree-sha1 = "0e4cc77fb131061b3525a97fd7d483b253c3aaad" -uuid = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" -version = "0.7.1" - -[[ImageTransformations]] -deps = ["AxisAlgorithms", "ColorTypes", "ColorVectorSpace", "Colors", "CoordinateTransformations", "FixedPointNumbers", "IdentityRanges", "ImageCore", "Interpolations", "LinearAlgebra", "OffsetArrays", "StaticArrays", "Test"] -git-tree-sha1 = "18ae1c0a8df31549a9452ceac93751d4aa166071" -uuid = "02fcd773-0e25-5acc-982a-7f6622650795" -version = "0.7.1" - -[[IndexedTables]] -deps = ["DataValues", "Dates", "IteratorInterfaceExtensions", "LinearAlgebra", "OnlineStats", "PooledArrays", "Random", "Serialization", "SparseArrays", "Statistics", "TableTraits", "TableTraitsUtils", "Test", "WeakRefStrings"] -git-tree-sha1 = "cb4406eeed8729f8179940d39e6dec5598971341" -uuid = "6deec6e2-d858-57c5-ab9b-e6ca5bd20e43" -version = "0.8.1" - -[[InteractiveUtils]] -deps = ["LinearAlgebra", "Markdown"] -uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" - -[[Interpolations]] -deps = ["AxisAlgorithms", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "SharedArrays", "SparseArrays", "StaticArrays", "Test", "WoodburyMatrices"] -git-tree-sha1 = "3493536a64dae5a21c0cc8aecf680647f3e12313" -uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" -version = "0.11.0" - -[[IntervalSets]] -deps = ["Compat"] -git-tree-sha1 = "9dc556002f23740de13946e8c2e41798e09a9249" -uuid = "8197267c-284f-5f27-9208-e0e47529a953" -version = "0.3.1" - -[[IterTools]] -deps = ["SparseArrays", "Test"] -git-tree-sha1 = "79246285c43602384e6f1943b3554042a3712056" -uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" -version = "1.1.1" - -[[IteratorInterfaceExtensions]] -deps = ["Test"] -git-tree-sha1 = "5484e5ede2a4137b9643f4d646e8e7b87b794415" -uuid = "82899510-4779-5014-852e-03e436cf321d" -version = "0.1.1" - -[[JSON]] -deps = ["Dates", "Distributed", "Mmap", "Sockets", "Test", "Unicode"] -git-tree-sha1 = "1f7a25b53ec67f5e9422f1f551ee216503f4a0fa" -uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" -version = "0.20.0" - -[[KernelDensity]] -deps = ["Distributions", "FFTW", "Interpolations", "Optim", "StatsBase", "Test"] -git-tree-sha1 = "c1048817fe5711f699abc8fabd47b1ac6ba4db04" -uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" -version = "0.5.1" - -[[LearnBase]] -deps = ["LinearAlgebra", "SparseArrays", "StatsBase", "Test"] -git-tree-sha1 = "c4b5da6d68517f46f70ed5157b28336b56cd2ff3" -uuid = "7f8f8fb0-2700-5f03-b4bd-41f8cfc144b6" -version = "0.2.2" - -[[LibCURL]] -deps = ["BinaryProvider", "Compat", "Libdl", "Printf"] -git-tree-sha1 = "6339c87cb76923a3cf947fcd213cbc364355c9c9" -uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" -version = "0.4.1" - -[[LibExpat]] -deps = ["Compat"] -git-tree-sha1 = "fde352ec13479e2f90e57939da2440fb78c5e388" -uuid = "522f3ed2-3f36-55e3-b6df-e94fee9b0c07" -version = "0.5.0" - -[[LibGit2]] -uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" - -[[Libdl]] -uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" - -[[Libz]] -deps = ["BufferedStreams", "Random", "Test"] -git-tree-sha1 = "d405194ffc0293c3519d4f7251ce51baac9cc871" -uuid = "2ec943e9-cfe8-584d-b93d-64dcb6d567b7" -version = "1.0.0" - -[[LineSearches]] -deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf", "Test"] -git-tree-sha1 = "54eb90e8dbe745d617c78dee1d6ae95c7f6f5779" -uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" -version = "7.0.1" - -[[LinearAlgebra]] -deps = ["Libdl"] -uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - -[[Loess]] -deps = ["Distances", "Random", "Statistics", "Test"] -git-tree-sha1 = "0ee46caf683a422b595be4dfaed6cda28f541e25" -uuid = "4345ca2d-374a-55d4-8d30-97f9976e7612" -version = "0.5.0" - -[[Logging]] -uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" - -[[LossFunctions]] -deps = ["InteractiveUtils", "LearnBase", "Markdown", "Random", "RecipesBase", "SparseArrays", "Statistics", "StatsBase", "Test"] -git-tree-sha1 = "b97d2e9a527733649d0205d3374d0daee352c50e" -uuid = "30fc2ffe-d236-52d8-8643-a9d8f7c094a7" -version = "0.5.0" - -[[MakieGallery]] -deps = ["AbstractPlotting", "BinaryProvider", "ColorTypes", "ColorVectorSpace", "Colors", "DataFrames", "Documenter", "FileIO", "FixedPointNumbers", "GDAL", "GeometryTypes", "ImageCore", "ImageFiltering", "ImageMagick", "ImageTransformations", "LinearAlgebra", "Markdown", "MeshIO", "ModernGL", "Pkg", "QuartzImageIO", "RDatasets", "Random", "Statistics", "Test"] -git-tree-sha1 = "2563a69f1a9c43cf0647127a506ba32782e9c45a" -repo-rev = "master" -repo-url = "https://github.com/JuliaPlots/MakieGallery.jl.git" -uuid = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" -version = "0.0.1+" - -[[MappedArrays]] -deps = ["Test"] -git-tree-sha1 = "923441c5ac942b60bd3a842d5377d96646bcbf46" -uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" -version = "0.2.1" - -[[Markdown]] -deps = ["Base64"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" - -[[MeshIO]] -deps = ["ColorTypes", "FileIO", "GeometryTypes", "Printf", "Test"] -git-tree-sha1 = "3e01e12c4c626578a9d47fac0d15c9fe8dad5139" -uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" -version = "0.3.1" - -[[Missings]] -deps = ["Dates", "InteractiveUtils", "SparseArrays", "Test"] -git-tree-sha1 = "adc26d2ee85a49c413464110d922cf21efc9d233" -uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" -version = "0.3.1" - -[[Mmap]] -uuid = "a63ad114-7e13-5084-954f-fe012c677804" - -[[Mocking]] -deps = ["Compat", "Dates"] -git-tree-sha1 = "4bf69aaf823b119b034e091e16b18311aa191663" -uuid = "78c3b35d-d492-501b-9361-3d52fe80e533" -version = "0.5.7" - -[[ModernGL]] -deps = ["Libdl"] -git-tree-sha1 = "f4f8fa8d04d3c1e7294f07fc37586c819466ad38" -uuid = "66fc600b-dfda-50eb-8b99-91cfa97b1301" -version = "1.0.0" - -[[NLSolversBase]] -deps = ["Calculus", "DiffEqDiffTools", "DiffResults", "Distributed", "ForwardDiff", "LinearAlgebra", "Random", "SparseArrays", "Test"] -git-tree-sha1 = "ebfb2e96970151753575b9c4d31d47e5ae8382a5" -uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" -version = "7.1.1" - -[[NaNMath]] -deps = ["Compat"] -git-tree-sha1 = "ce3b85e484a5d4c71dd5316215069311135fa9f2" -uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" -version = "0.3.2" - -[[NamedArrays]] -deps = ["Combinatorics", "DataStructures", "DelimitedFiles", "LinearAlgebra", "Random", "Requires", "SparseArrays", "Statistics", "Test"] -git-tree-sha1 = "977c65d68cee14ab28198e89ebc125d0738ef250" -uuid = "86f7a689-2022-50b4-a561-43c23ac3c673" -version = "0.9.2" - -[[Nullables]] -deps = ["Compat"] -git-tree-sha1 = "ae1a63457e14554df2159b0b028f48536125092d" -uuid = "4d1e1d77-625e-5b40-9113-a560ec7a8ecd" -version = "0.0.8" - -[[Observables]] -deps = ["Test"] -git-tree-sha1 = "dc02cec22747d1d10d9f70d8a1c03432b5bfbcd0" -uuid = "510215fc-4207-5dde-b226-833fc4488ee2" -version = "0.2.3" - -[[OffsetArrays]] -deps = ["DelimitedFiles", "Test"] -git-tree-sha1 = "f446248f2dfbc13039a0b90994dd25b059b01eab" -uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -version = "0.9.0" - -[[OnlineStats]] -deps = ["DataStructures", "Dates", "LearnBase", "LinearAlgebra", "LossFunctions", "OnlineStatsBase", "PenaltyFunctions", "Random", "RecipesBase", "Reexport", "Statistics", "StatsBase", "SweepOperator", "Test"] -git-tree-sha1 = "70fe5cbb31d37c18f6312a2994c31b782be50607" -uuid = "a15396b6-48d5-5d58-9928-6d29437db91e" -version = "0.19.2" - -[[OnlineStatsBase]] -deps = ["LearnBase", "Test"] -git-tree-sha1 = "520580a74e09378fb6665fa89339323d411d3df3" -uuid = "925886fa-5bf2-5e8e-b522-a9147a512338" -version = "0.9.1" - -[[Optim]] -deps = ["Calculus", "DiffEqDiffTools", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "Random", "SparseArrays", "StatsBase", "Test"] -git-tree-sha1 = "0f2a6c6ff9db396cc7af15bb1cf057a26662ff17" -uuid = "429524aa-4258-5aef-a3af-852621145aeb" -version = "0.17.2" - -[[OrderedCollections]] -deps = ["Random", "Serialization", "Test"] -git-tree-sha1 = "85619a3f3e17bb4761fe1b1fd47f0e979f964d5b" -uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.0.2" - -[[PDMats]] -deps = ["Arpack", "LinearAlgebra", "SparseArrays", "SuiteSparse", "Test"] -git-tree-sha1 = "b6c91fc0ab970c0563cbbe69af18d741a49ce551" -uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" -version = "0.9.6" - -[[Packing]] -deps = ["GeometryTypes", "Test"] -git-tree-sha1 = "bc7c284233cf0518933bf9977e3e8234efcc1c30" -uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" -version = "0.3.0" - -[[PaddedViews]] -deps = ["OffsetArrays", "Test"] -git-tree-sha1 = "7da3e7e1a58cffbf10177553ae95f17b92516912" -uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" -version = "0.4.2" - -[[Parameters]] -deps = ["Markdown", "OrderedCollections", "REPL", "Test"] -git-tree-sha1 = "eec0fe16344cc14aa2e6251874ab30d62aff4f7c" -uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" -version = "0.10.2" - -[[Parsers]] -deps = ["Dates", "Mmap", "Test", "WeakRefStrings"] -git-tree-sha1 = "949ca36d47010bee093254467166487c921d490b" -uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "0.2.14" - -[[PenaltyFunctions]] -deps = ["InteractiveUtils", "LearnBase", "LinearAlgebra", "RecipesBase", "Reexport", "Test"] -git-tree-sha1 = "b0baaa5218ca0ffd6a8ae37ef0b58e0df688ac8b" -uuid = "06bb1623-fdd5-5ca2-a01c-88eae3ea319e" -version = "0.1.2" - -[[Pkg]] -deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] -uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" - -[[PlotUtils]] -deps = ["Colors", "Dates", "Printf", "Random", "Reexport", "Test"] -git-tree-sha1 = "fd28f30a294a38ec847de95d8ac7ac916ccd7c06" -uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" -version = "0.5.5" - -[[Polynomials]] -deps = ["LinearAlgebra", "SparseArrays", "Test"] -git-tree-sha1 = "1a1eae52956658a6acae6fa1b6d6c3d488192895" -uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" -version = "0.5.1" - -[[PooledArrays]] -deps = ["Test"] -git-tree-sha1 = "5c5ded7adc52867f599c21d3f43542fce491afda" -uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" -version = "0.4.1" - -[[PositiveFactorizations]] -deps = ["LinearAlgebra", "Test"] -git-tree-sha1 = "86ae7329c4b5c266acf5c7c524a972300d991e1c" -uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" -version = "0.2.1" - -[[Printf]] -deps = ["Unicode"] -uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" - -[[Profile]] -deps = ["Printf"] -uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" - -[[QuadGK]] -deps = ["DataStructures", "LinearAlgebra", "Test"] -git-tree-sha1 = "7e8dff9c205f36eceaf6e62a43ff851637ca45fc" -uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.0.2" - -[[QuartzImageIO]] -deps = ["ColorTypes", "ColorVectorSpace", "FileIO", "FixedPointNumbers", "ImageCore", "Libdl", "Random", "Test"] -git-tree-sha1 = "c747a56f223919b157e6cd9dc58d59c560586302" -uuid = "dca85d43-d64c-5e67-8c65-017450d5d020" -version = "0.5.0" - -[[RData]] -deps = ["CategoricalArrays", "CodecZlib", "DataFrames", "Dates", "FileIO", "Missings", "Test", "TimeZones"] -git-tree-sha1 = "8f3b644f4ebce291431846f5532272b0864c757c" -uuid = "df47a6cb-8c03-5eed-afd8-b6050d6c41da" -version = "0.5.0" - -[[RDatasets]] -deps = ["CSV", "CodecZlib", "DataFrames", "FileIO", "Printf", "RData", "Reexport", "Test"] -git-tree-sha1 = "4d93a52b94397bf0a9477d04e7a151a688672695" -uuid = "ce6b1742-4840-55fa-b093-852dadbb1d8b" -version = "0.6.1" - -[[REPL]] -deps = ["InteractiveUtils", "Markdown", "Sockets"] -uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" - -[[Random]] -deps = ["Serialization"] -uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" - -[[Ratios]] -deps = ["Compat"] -git-tree-sha1 = "fd159bead0a24e6270fd0573a340312bd4645cc2" -uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" -version = "0.3.0" - -[[RecipesBase]] -deps = ["Random", "Test"] -git-tree-sha1 = "0b3cb370ee4dc00f47f1193101600949f3dcf884" -uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" -version = "0.6.0" - -[[Reexport]] -deps = ["Pkg"] -git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" -uuid = "189a3867-3050-52da-a836-e630ba90ab69" -version = "0.2.0" - -[[Requires]] -deps = ["Test"] -git-tree-sha1 = "f6fbf4ba64d295e146e49e021207993b6b48c7d1" -uuid = "ae029012-a4dd-5104-9daa-d747884805df" -version = "0.5.2" - -[[Rmath]] -deps = ["BinaryProvider", "Libdl", "Random", "Statistics", "Test"] -git-tree-sha1 = "9a6c758cdf73036c3239b0afbea790def1dabff9" -uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" -version = "0.5.0" - -[[Rotations]] -deps = ["LinearAlgebra", "Random", "StaticArrays", "Statistics", "Test"] -git-tree-sha1 = "b629771d0de88979cbdbf72ceddc54de58fde149" -uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" -version = "0.9.1" - -[[SHA]] -uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" - -[[Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" - -[[SharedArrays]] -deps = ["Distributed", "Mmap", "Random", "Serialization"] -uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" - -[[Showoff]] -deps = ["Compat"] -git-tree-sha1 = "276b24f3ace98bec911be7ff2928d497dc759085" -uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" -version = "0.2.1" - -[[SignedDistanceFields]] -deps = ["Random", "Statistics", "Test"] -git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" -uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" -version = "0.4.0" - -[[Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" - -[[SortingAlgorithms]] -deps = ["DataStructures", "Random", "Test"] -git-tree-sha1 = "03f5898c9959f8115e30bc7226ada7d0df554ddd" -uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "0.3.1" - -[[SparseArrays]] -deps = ["LinearAlgebra", "Random"] -uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - -[[SpecialFunctions]] -deps = ["BinDeps", "BinaryProvider", "Libdl", "Test"] -git-tree-sha1 = "0b45dc2e45ed77f445617b99ff2adf0f5b0f23ea" -uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "0.7.2" - -[[StaticArrays]] -deps = ["InteractiveUtils", "LinearAlgebra", "Random", "Statistics", "Test"] -git-tree-sha1 = "97c4bf0f647488dd7ac01ea12be5885f88762938" -uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "0.10.0" - -[[Statistics]] -deps = ["LinearAlgebra", "SparseArrays"] -uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" - -[[StatsBase]] -deps = ["DataStructures", "LinearAlgebra", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "Test"] -git-tree-sha1 = "2722397d88f8ffef551948f6c20e1d74a743298c" -uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" -version = "0.26.0" - -[[StatsFuns]] -deps = ["Rmath", "SpecialFunctions", "Test"] -git-tree-sha1 = "d14bb7b03defd2deaa5675646f6783089e0556f0" -uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" -version = "0.7.0" - -[[StatsMakie]] -deps = ["AbstractPlotting", "Distributions", "FreqTables", "IndexedTables", "IntervalSets", "KernelDensity", "Loess", "NamedArrays", "Observables", "Random", "Statistics", "StatsBase", "Tables", "Test"] -git-tree-sha1 = "12429b8d5308b27483f4d6148cefb86080e4d054" -repo-rev = "master" -repo-url = "https://github.com/JuliaPlots/StatsMakie.jl.git" -uuid = "9d48ccf0-4268-5716-84ff-21228f561db3" -version = "0.0.0" - -[[SuiteSparse]] -deps = ["Libdl", "LinearAlgebra", "SparseArrays"] -uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" - -[[SweepOperator]] -deps = ["LinearAlgebra", "Test"] -git-tree-sha1 = "2039aaa96f7b21634a1b3246cb2699dd1d26d473" -uuid = "7522ee7d-7047-56d0-94d9-4bc626e7058d" -version = "0.2.0" - -[[TableTraits]] -deps = ["IteratorInterfaceExtensions", "Test"] -git-tree-sha1 = "da062a2c31f16178f68190243c24140801720a43" -uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" -version = "0.4.0" - -[[TableTraitsUtils]] -deps = ["DataValues", "IteratorInterfaceExtensions", "Missings", "TableTraits", "Test"] -git-tree-sha1 = "a355f1882d64881a11f853e64dcc353975c4df6e" -uuid = "382cd787-c1b6-5bf2-a167-d5b971a19bda" -version = "0.3.1" - -[[Tables]] -deps = ["Requires", "Test"] -git-tree-sha1 = "940944e6b68a35046282897a2218891c7cf14a32" -uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "0.1.12" - -[[Test]] -deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] -uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[[TiledIteration]] -deps = ["OffsetArrays", "Test"] -git-tree-sha1 = "58f6f07d3b54a363ec283a8f5fc9fb4ecebde656" -uuid = "06e1c1a7-607b-532d-9fad-de7d9aa2abac" -version = "0.2.3" - -[[TimeZones]] -deps = ["Compat", "EzXML", "Mocking", "Nullables"] -git-tree-sha1 = "4a4ab113913e19ad62b67e6c5c056509eac00c19" -uuid = "f269a46b-ccf7-5d73-abea-4c690281aa53" -version = "0.8.2" - -[[TranscodingStreams]] -deps = ["Pkg", "Random", "Test"] -git-tree-sha1 = "a34a2d588e2d2825602bf14a24216d5c8b0921ec" -uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.8.1" - -[[URIParser]] -deps = ["Test", "Unicode"] -git-tree-sha1 = "6ddf8244220dfda2f17539fa8c9de20d6c575b69" -uuid = "30578b45-9adc-5946-b283-645ec420af67" -version = "0.4.0" - -[[UUIDs]] -deps = ["Random"] -uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" - -[[Unicode]] -uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" - -[[UnicodeFun]] -deps = ["Test"] -git-tree-sha1 = "63cbbd00217fc9aafedf055b60459c1ae7e01ecc" -uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" -version = "0.4.0" - -[[VersionParsing]] -deps = ["Compat"] -git-tree-sha1 = "c9d5aa108588b978bd859554660c8a5c4f2f7669" -uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" -version = "1.1.3" - -[[WeakRefStrings]] -deps = ["Missings", "Random", "Test"] -git-tree-sha1 = "1087e8be380f2c8b96434b02bb1150fc1c511135" -uuid = "ea10d353-3f73-51f8-a26c-33c1cb351aa5" -version = "0.5.3" - -[[WinRPM]] -deps = ["BinDeps", "Compat", "HTTPClient", "LibExpat", "Libdl", "Libz", "URIParser"] -git-tree-sha1 = "2a889d320f3b77d17c037f295859fe570133cfbf" -uuid = "c17dfb99-b4f7-5aad-8812-456da1ad7187" -version = "0.4.2" - -[[WoodburyMatrices]] -deps = ["LinearAlgebra", "Random", "SparseArrays", "Test"] -git-tree-sha1 = "21772c33b447757ec7d3e61fcdfb9ea5c47eedcf" -uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" -version = "0.4.1" diff --git a/Project.toml b/Project.toml index 5b7b5c7c383..50e87c739a8 100644 --- a/Project.toml +++ b/Project.toml @@ -19,7 +19,7 @@ StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" [compat] -AbstractPlotting = ">=0.9.1" +AbstractPlotting = ">=0.9.2" GeometryTypes = ">=0.7.2" [extras] From 1d84e4b7ab246b6044859ef7fc97fe6a54e8c4f1 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Tue, 15 Jan 2019 16:34:23 +0100 Subject: [PATCH 0064/1328] correct tomls --- Project.toml | 2 +- test/Manifest.toml | 856 --------------------------------------------- test/Project.toml | 28 -- 3 files changed, 1 insertion(+), 885 deletions(-) delete mode 100644 test/Manifest.toml delete mode 100644 test/Project.toml diff --git a/Project.toml b/Project.toml index 11a6790a511..49130ea12a2 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "CairoMakie" uuid = "f1797859-2bec-5491-832b-e19d79114491" author = ["Simon Danisch "] -version = "0.0.0" +version = "0.0.2" [deps] AbstractPlotting = "537997a7-5e4e-5d89-9595-2241ea00577e" diff --git a/test/Manifest.toml b/test/Manifest.toml deleted file mode 100644 index 314ecaaafe5..00000000000 --- a/test/Manifest.toml +++ /dev/null @@ -1,856 +0,0 @@ -[[AbstractFFTs]] -deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "8d59c3b1463b5e0ad05a3698167f85fac90e184d" -uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" -version = "0.3.2" - -[[AbstractPlotting]] -deps = ["ColorBrewer", "ColorTypes", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "ImageMagick", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "Test", "UnicodeFun"] -git-tree-sha1 = "b47cc331607de0daa3d3e40ed77b61b36dd19c17" -uuid = "537997a7-5e4e-5d89-9595-2241ea00577e" -version = "0.9.2" - -[[Arpack]] -deps = ["BinaryProvider", "Libdl", "LinearAlgebra", "Random", "SparseArrays", "Test"] -git-tree-sha1 = "1ce1ce9984683f0b6a587d5bdbc688ecb480096f" -uuid = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97" -version = "0.3.0" - -[[AxisAlgorithms]] -deps = ["Compat", "WoodburyMatrices"] -git-tree-sha1 = "99dabbe853e4f641ab21a676131f2cf9fb29937e" -uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" -version = "0.3.0" - -[[Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" - -[[BinDeps]] -deps = ["Compat", "Libdl", "SHA", "URIParser"] -git-tree-sha1 = "12093ca6cdd0ee547c39b1870e0c9c3f154d9ca9" -uuid = "9e28174c-4ba2-5203-b857-d8d62c4213ee" -version = "0.8.10" - -[[BinaryProvider]] -deps = ["Libdl", "Pkg", "SHA", "Test"] -git-tree-sha1 = "055eb2690182ebc31087859c3dd8598371d3ef9e" -uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" -version = "0.5.3" - -[[BufferedStreams]] -deps = ["Compat", "Test"] -git-tree-sha1 = "5d55b9486590fdda5905c275bb21ce1f0754020f" -uuid = "e1450e63-4bb3-523b-b2a4-4ffa8c0fd77d" -version = "1.0.0" - -[[CSV]] -deps = ["CategoricalArrays", "DataFrames", "DataStreams", "Dates", "Mmap", "Parsers", "Profile", "Random", "Tables", "Test", "Unicode", "WeakRefStrings"] -git-tree-sha1 = "b92c6f626a044cc9619156d54994b94084d40abe" -uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" -version = "0.4.3" - -[[Cairo]] -deps = ["BinDeps", "Colors", "Compat", "Graphics", "Homebrew", "Libdl", "WinRPM"] -git-tree-sha1 = "a427098d5aa2808504d94b8ed9fc5740ceaf71d0" -uuid = "159f3aea-2a34-519c-b102-8c37f9878175" -version = "0.5.6" - -[[Calculus]] -deps = ["Compat"] -git-tree-sha1 = "f60954495a7afcee4136f78d1d60350abd37a409" -uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" -version = "0.4.1" - -[[CatIndices]] -deps = ["CustomUnitRanges", "OffsetArrays", "Test"] -git-tree-sha1 = "254cf73ea369d2e39bfd6c5eb27a2296cfaed68c" -uuid = "aafaddc9-749c-510e-ac4f-586e18779b91" -version = "0.2.0" - -[[CategoricalArrays]] -deps = ["Compat", "Future", "Missings", "Printf", "Reexport", "Requires"] -git-tree-sha1 = "94d16e77dfacc59f6d6c1361866906dbb65b6f6b" -uuid = "324d7699-5711-5eae-9e2f-1d82baa6b597" -version = "0.5.2" - -[[CodecZlib]] -deps = ["BinaryProvider", "Libdl", "Test", "TranscodingStreams"] -git-tree-sha1 = "e3df104c84dfc108f0ca203fd7f5bbdc98641ae9" -uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.5.1" - -[[ColorBrewer]] -deps = ["Colors", "JSON", "Test"] -git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" -uuid = "a2cac450-b92f-5266-8821-25eda20663c8" -version = "0.4.0" - -[[ColorTypes]] -deps = ["FixedPointNumbers", "Random", "Test"] -git-tree-sha1 = "f73b0e10f2a5756de7019818a41654686da06b09" -uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" -version = "0.7.5" - -[[ColorVectorSpace]] -deps = ["ColorTypes", "Colors", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "StatsBase", "Test"] -git-tree-sha1 = "a890f08e61b40e9843d7177206da61229a3603c8" -uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" -version = "0.6.2" - -[[Colors]] -deps = ["ColorTypes", "FixedPointNumbers", "InteractiveUtils", "Printf", "Reexport", "Test"] -git-tree-sha1 = "9f0a0210450acb91c730b730a994f8eef1d3d543" -uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" -version = "0.9.5" - -[[Combinatorics]] -deps = ["LinearAlgebra", "Polynomials", "Test"] -git-tree-sha1 = "50b3ae4d643dc27eaff69fb6be06ee094d5500c9" -uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" -version = "0.7.0" - -[[CommonSubexpressions]] -deps = ["Test"] -git-tree-sha1 = "efdaf19ab11c7889334ca247ff4c9f7c322817b0" -uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" -version = "0.2.0" - -[[Compat]] -deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] -git-tree-sha1 = "ec61a16eed883ad0cfa002d7489b3ce6d039bb9a" -uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "1.4.0" - -[[ComputationalResources]] -deps = ["Test"] -git-tree-sha1 = "89e7e7ed20af73d9f78877d2b8d1194e7b6ff13d" -uuid = "ed09eef8-17a6-5b46-8889-db040fac31e3" -version = "0.3.0" - -[[Conda]] -deps = ["Compat", "JSON", "VersionParsing"] -git-tree-sha1 = "fb86fe40cb5b35990e368709bfdc1b46dbb99dac" -uuid = "8f4d0f93-b110-5947-807f-2305c1781a2d" -version = "1.1.1" - -[[Contour]] -deps = ["LinearAlgebra", "StaticArrays", "Test"] -git-tree-sha1 = "b974e164358fea753ef853ce7bad97afec15bb80" -uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" -version = "0.5.1" - -[[CoordinateTransformations]] -deps = ["Compat", "Rotations", "StaticArrays"] -git-tree-sha1 = "47f05d0b7f4999609f92e657147df000818c1f24" -uuid = "150eb455-5306-5404-9cee-2592286d6298" -version = "0.5.0" - -[[CustomUnitRanges]] -deps = ["Test"] -git-tree-sha1 = "0a106457a1831555857e18ac9617279c22fc393b" -uuid = "dc8bdbbb-1ca9-579f-8c36-e416f6a65cce" -version = "0.2.0" - -[[DataFrames]] -deps = ["CategoricalArrays", "CodecZlib", "Compat", "DataStreams", "Dates", "InteractiveUtils", "IteratorInterfaceExtensions", "LinearAlgebra", "Missings", "Printf", "Random", "Reexport", "SortingAlgorithms", "Statistics", "StatsBase", "TableTraits", "Tables", "Test", "TranscodingStreams", "Unicode", "WeakRefStrings"] -git-tree-sha1 = "41ec35bcf49a860706924b9b3e322eed03164c83" -uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -version = "0.15.2" - -[[DataStreams]] -deps = ["Dates", "Missings", "Test", "WeakRefStrings"] -git-tree-sha1 = "69c72a1beb4fc79490c361635664e13c8e4a9548" -uuid = "9a8bc11e-79be-5b39-94d7-1ccc349a1a85" -version = "0.4.1" - -[[DataStructures]] -deps = ["InteractiveUtils", "OrderedCollections", "Random", "Serialization", "Test"] -git-tree-sha1 = "8fc6e166e24fda04b2b648d4260cdad241788c54" -uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.14.0" - -[[DataValues]] -deps = ["Dates", "InteractiveUtils", "LinearAlgebra", "Random", "Test"] -git-tree-sha1 = "4fedccda7e5111354c7dcc832c7da83ff7258765" -uuid = "e7dc6d0d-1eca-5fa6-8ad6-5aecde8b7ea5" -version = "0.4.5" - -[[Dates]] -deps = ["Printf"] -uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" - -[[DelimitedFiles]] -deps = ["Mmap"] -uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" - -[[DiffEqDiffTools]] -deps = ["LinearAlgebra", "Test"] -git-tree-sha1 = "67700c9fc82033ec68a145bc650f6b9debdf9103" -uuid = "01453d9d-ee7c-5054-8395-0335cb756afa" -version = "0.7.1" - -[[DiffResults]] -deps = ["Compat", "StaticArrays"] -git-tree-sha1 = "db8acf46717b13d6c48deb7a12007c7f85a70cf7" -uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" -version = "0.0.3" - -[[DiffRules]] -deps = ["Random", "Test"] -git-tree-sha1 = "c49ec69428ffea0c1d1bbdc63d1a70f5df5860ad" -uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" -version = "0.0.7" - -[[Distances]] -deps = ["LinearAlgebra", "Printf", "Random", "Statistics", "Test"] -git-tree-sha1 = "2f38605722542f1c0a32dd2856fb529d8c226c69" -uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" -version = "0.7.3" - -[[Distributed]] -deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] -uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" - -[[Distributions]] -deps = ["Distributed", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsBase", "StatsFuns", "Test"] -git-tree-sha1 = "c24e9b6500c037673f0241a2783472b8c3d080c7" -uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.16.4" - -[[DocStringExtensions]] -deps = ["LibGit2", "Markdown", "Pkg", "Test"] -git-tree-sha1 = "1df01539a1c952cef21f2d2d1c092c2bcf0177d7" -uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.6.0" - -[[Documenter]] -deps = ["Base64", "DocStringExtensions", "InteractiveUtils", "LibGit2", "Logging", "Markdown", "Pkg", "REPL", "Random", "Test", "Unicode"] -git-tree-sha1 = "a6db1c69925cdc53aafb38caec4446be26e0c617" -uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "0.21.0" - -[[EzXML]] -deps = ["BinaryProvider", "Libdl", "Printf", "Test"] -git-tree-sha1 = "5623d1486bfaadd815f5c4ca501adda02b5337f1" -uuid = "8f5d6c58-4d21-5cfd-889c-e3ad7ee6a615" -version = "0.9.0" - -[[FFTViews]] -deps = ["CustomUnitRanges", "FFTW", "Test"] -git-tree-sha1 = "9d7993227ca7c0fdb6b31deef193adbba11c8f4e" -uuid = "4f61f5a4-77b1-5117-aa51-3ab5ef4ef0cd" -version = "0.2.0" - -[[FFTW]] -deps = ["AbstractFFTs", "BinaryProvider", "Compat", "Conda", "Libdl", "LinearAlgebra", "Reexport", "Test"] -git-tree-sha1 = "29cda58afbf62f35b1a094882ad6c745a47b2eaa" -uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" -version = "0.2.4" - -[[FileIO]] -deps = ["Pkg", "Random", "Test"] -git-tree-sha1 = "1a114d08094e7267ba8d4d684f930d5a722184de" -uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -version = "1.0.4" - -[[FixedPointNumbers]] -deps = ["Test"] -git-tree-sha1 = "b8045033701c3b10bf2324d7203404be7aef88ba" -uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.5.3" - -[[ForwardDiff]] -deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "InteractiveUtils", "LinearAlgebra", "NaNMath", "Random", "SparseArrays", "SpecialFunctions", "StaticArrays", "Test"] -git-tree-sha1 = "b91250044374764e7c29af59a774c4b8d6100b6e" -uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "0.10.1" - -[[FreeType]] -deps = ["BinaryProvider", "Libdl", "Pkg", "Test"] -git-tree-sha1 = "06462b9d5aca708d764d16e5ba6a83ba7b753d57" -uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" -version = "2.1.1" - -[[FreeTypeAbstraction]] -deps = ["ColorVectorSpace", "Colors", "FreeType", "StaticArrays", "Test"] -git-tree-sha1 = "271ef13438bd0946950fd34d9241e5beefd6d4b3" -uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" -version = "0.4.1" - -[[FreqTables]] -deps = ["CategoricalArrays", "NamedArrays", "Tables", "Test"] -git-tree-sha1 = "93ce75cae27c2d1c6518771d597b6dd0a3d623d3" -uuid = "da1fdf0e-e0ff-5433-a45f-9bb5ff651cb1" -version = "0.3.1" - -[[Future]] -deps = ["Random"] -uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" - -[[GDAL]] -deps = ["BinaryProvider", "Libdl", "Test"] -git-tree-sha1 = "100429098b7ec9930f7db9ba68aee3495365be24" -uuid = "add2ef01-049f-52c4-9ee2-e494f65e021a" -version = "0.2.0" - -[[GeometryTypes]] -deps = ["ColorTypes", "FixedPointNumbers", "IterTools", "LinearAlgebra", "StaticArrays", "Test"] -git-tree-sha1 = "28b193e14466beecf928449e0f8505ff6de3709d" -uuid = "4d00f742-c7ba-57c2-abde-4428a4b178cb" -version = "0.7.2" - -[[Graphics]] -deps = ["Colors", "Compat", "NaNMath"] -git-tree-sha1 = "e3ead4211073d4117a0d2ef7d1efc5c8092c8412" -uuid = "a2bd30eb-e257-5431-a919-1863eab51364" -version = "0.4.0" - -[[HTTPClient]] -deps = ["Compat", "LibCURL"] -git-tree-sha1 = "161d5776ae8e585ac0b8c20fb81f17ab755b3671" -uuid = "0862f596-cf2d-50af-8ef4-f2be67dfa83f" -version = "0.2.1" - -[[Homebrew]] -deps = ["BinDeps", "InteractiveUtils", "JSON", "Libdl", "Test", "Unicode"] -git-tree-sha1 = "5582ec74f735cf8d12e562a2e65c47f34063bd51" -uuid = "d9be37ee-ecc9-5288-90f1-b9ca67657a75" -version = "0.7.0" - -[[IdentityRanges]] -deps = ["OffsetArrays", "Test"] -git-tree-sha1 = "f5ca23a08397288924a7535cd898d8ccbcde5ba5" -uuid = "bbac6d45-d8f3-5730-bfe4-7a449cd117ca" -version = "0.2.0" - -[[ImageCore]] -deps = ["ColorTypes", "Colors", "FFTW", "FixedPointNumbers", "Graphics", "MappedArrays", "OffsetArrays", "PaddedViews", "Random", "Statistics", "Test"] -git-tree-sha1 = "5e7b1f49c80541860e08a7ea91805a24c1641f19" -uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" -version = "0.7.3" - -[[ImageFiltering]] -deps = ["CatIndices", "ColorVectorSpace", "Colors", "ComputationalResources", "DataStructures", "FFTViews", "FFTW", "FixedPointNumbers", "ImageCore", "LinearAlgebra", "Logging", "MappedArrays", "OffsetArrays", "Random", "StaticArrays", "Statistics", "Test", "TiledIteration"] -git-tree-sha1 = "2d23d8f8c1def1e8d67d05e554baacc780d9313d" -uuid = "6a3955dd-da59-5b1f-98d4-e7296123deb5" -version = "0.5.1" - -[[ImageMagick]] -deps = ["BinaryProvider", "ColorTypes", "FileIO", "FixedPointNumbers", "ImageCore", "InteractiveUtils", "Libdl", "Pkg", "Random", "Test"] -git-tree-sha1 = "0e4cc77fb131061b3525a97fd7d483b253c3aaad" -uuid = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" -version = "0.7.1" - -[[ImageTransformations]] -deps = ["AxisAlgorithms", "ColorTypes", "ColorVectorSpace", "Colors", "CoordinateTransformations", "FixedPointNumbers", "IdentityRanges", "ImageCore", "Interpolations", "LinearAlgebra", "OffsetArrays", "StaticArrays", "Test"] -git-tree-sha1 = "18ae1c0a8df31549a9452ceac93751d4aa166071" -uuid = "02fcd773-0e25-5acc-982a-7f6622650795" -version = "0.7.1" - -[[IndexedTables]] -deps = ["DataValues", "Dates", "IteratorInterfaceExtensions", "LinearAlgebra", "OnlineStats", "PooledArrays", "Random", "Serialization", "SparseArrays", "Statistics", "TableTraits", "TableTraitsUtils", "Test", "WeakRefStrings"] -git-tree-sha1 = "cb4406eeed8729f8179940d39e6dec5598971341" -uuid = "6deec6e2-d858-57c5-ab9b-e6ca5bd20e43" -version = "0.8.1" - -[[InteractiveUtils]] -deps = ["LinearAlgebra", "Markdown"] -uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" - -[[Interpolations]] -deps = ["AxisAlgorithms", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "SharedArrays", "SparseArrays", "StaticArrays", "Test", "WoodburyMatrices"] -git-tree-sha1 = "3493536a64dae5a21c0cc8aecf680647f3e12313" -uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" -version = "0.11.0" - -[[IntervalSets]] -deps = ["Compat"] -git-tree-sha1 = "9dc556002f23740de13946e8c2e41798e09a9249" -uuid = "8197267c-284f-5f27-9208-e0e47529a953" -version = "0.3.1" - -[[IterTools]] -deps = ["SparseArrays", "Test"] -git-tree-sha1 = "79246285c43602384e6f1943b3554042a3712056" -uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" -version = "1.1.1" - -[[IteratorInterfaceExtensions]] -deps = ["Test"] -git-tree-sha1 = "5484e5ede2a4137b9643f4d646e8e7b87b794415" -uuid = "82899510-4779-5014-852e-03e436cf321d" -version = "0.1.1" - -[[JSON]] -deps = ["Dates", "Distributed", "Mmap", "Sockets", "Test", "Unicode"] -git-tree-sha1 = "1f7a25b53ec67f5e9422f1f551ee216503f4a0fa" -uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" -version = "0.20.0" - -[[KernelDensity]] -deps = ["Distributions", "FFTW", "Interpolations", "Optim", "StatsBase", "Test"] -git-tree-sha1 = "c1048817fe5711f699abc8fabd47b1ac6ba4db04" -uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" -version = "0.5.1" - -[[LearnBase]] -deps = ["LinearAlgebra", "SparseArrays", "StatsBase", "Test"] -git-tree-sha1 = "c4b5da6d68517f46f70ed5157b28336b56cd2ff3" -uuid = "7f8f8fb0-2700-5f03-b4bd-41f8cfc144b6" -version = "0.2.2" - -[[LibCURL]] -deps = ["BinaryProvider", "Compat", "Libdl", "Printf"] -git-tree-sha1 = "6339c87cb76923a3cf947fcd213cbc364355c9c9" -uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" -version = "0.4.1" - -[[LibExpat]] -deps = ["Compat"] -git-tree-sha1 = "fde352ec13479e2f90e57939da2440fb78c5e388" -uuid = "522f3ed2-3f36-55e3-b6df-e94fee9b0c07" -version = "0.5.0" - -[[LibGit2]] -uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" - -[[Libdl]] -uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" - -[[Libz]] -deps = ["BufferedStreams", "Random", "Test"] -git-tree-sha1 = "d405194ffc0293c3519d4f7251ce51baac9cc871" -uuid = "2ec943e9-cfe8-584d-b93d-64dcb6d567b7" -version = "1.0.0" - -[[LineSearches]] -deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf", "Test"] -git-tree-sha1 = "54eb90e8dbe745d617c78dee1d6ae95c7f6f5779" -uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" -version = "7.0.1" - -[[LinearAlgebra]] -deps = ["Libdl"] -uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - -[[Loess]] -deps = ["Distances", "Random", "Statistics", "Test"] -git-tree-sha1 = "0ee46caf683a422b595be4dfaed6cda28f541e25" -uuid = "4345ca2d-374a-55d4-8d30-97f9976e7612" -version = "0.5.0" - -[[Logging]] -uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" - -[[LossFunctions]] -deps = ["InteractiveUtils", "LearnBase", "Markdown", "Random", "RecipesBase", "SparseArrays", "Statistics", "StatsBase", "Test"] -git-tree-sha1 = "b97d2e9a527733649d0205d3374d0daee352c50e" -uuid = "30fc2ffe-d236-52d8-8643-a9d8f7c094a7" -version = "0.5.0" - -[[MakieGallery]] -deps = ["AbstractPlotting", "BinaryProvider", "ColorTypes", "ColorVectorSpace", "Colors", "DataFrames", "Documenter", "FileIO", "FixedPointNumbers", "GDAL", "GeometryTypes", "ImageCore", "ImageFiltering", "ImageMagick", "ImageTransformations", "LinearAlgebra", "Markdown", "MeshIO", "ModernGL", "Pkg", "QuartzImageIO", "RDatasets", "Random", "Statistics", "Test"] -git-tree-sha1 = "2563a69f1a9c43cf0647127a506ba32782e9c45a" -repo-rev = "master" -repo-url = "https://github.com/JuliaPlots/MakieGallery.jl.git" -uuid = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" -version = "0.0.1+" - -[[MappedArrays]] -deps = ["Test"] -git-tree-sha1 = "923441c5ac942b60bd3a842d5377d96646bcbf46" -uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" -version = "0.2.1" - -[[Markdown]] -deps = ["Base64"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" - -[[MeshIO]] -deps = ["ColorTypes", "FileIO", "GeometryTypes", "Printf", "Test"] -git-tree-sha1 = "3e01e12c4c626578a9d47fac0d15c9fe8dad5139" -uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" -version = "0.3.1" - -[[Missings]] -deps = ["Dates", "InteractiveUtils", "SparseArrays", "Test"] -git-tree-sha1 = "adc26d2ee85a49c413464110d922cf21efc9d233" -uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" -version = "0.3.1" - -[[Mmap]] -uuid = "a63ad114-7e13-5084-954f-fe012c677804" - -[[Mocking]] -deps = ["Compat", "Dates"] -git-tree-sha1 = "4bf69aaf823b119b034e091e16b18311aa191663" -uuid = "78c3b35d-d492-501b-9361-3d52fe80e533" -version = "0.5.7" - -[[ModernGL]] -deps = ["Libdl"] -git-tree-sha1 = "f4f8fa8d04d3c1e7294f07fc37586c819466ad38" -uuid = "66fc600b-dfda-50eb-8b99-91cfa97b1301" -version = "1.0.0" - -[[NLSolversBase]] -deps = ["Calculus", "DiffEqDiffTools", "DiffResults", "Distributed", "ForwardDiff", "LinearAlgebra", "Random", "SparseArrays", "Test"] -git-tree-sha1 = "ebfb2e96970151753575b9c4d31d47e5ae8382a5" -uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" -version = "7.1.1" - -[[NaNMath]] -deps = ["Compat"] -git-tree-sha1 = "ce3b85e484a5d4c71dd5316215069311135fa9f2" -uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" -version = "0.3.2" - -[[NamedArrays]] -deps = ["Combinatorics", "DataStructures", "DelimitedFiles", "LinearAlgebra", "Random", "Requires", "SparseArrays", "Statistics", "Test"] -git-tree-sha1 = "977c65d68cee14ab28198e89ebc125d0738ef250" -uuid = "86f7a689-2022-50b4-a561-43c23ac3c673" -version = "0.9.2" - -[[Nullables]] -deps = ["Compat"] -git-tree-sha1 = "ae1a63457e14554df2159b0b028f48536125092d" -uuid = "4d1e1d77-625e-5b40-9113-a560ec7a8ecd" -version = "0.0.8" - -[[Observables]] -deps = ["Test"] -git-tree-sha1 = "dc02cec22747d1d10d9f70d8a1c03432b5bfbcd0" -uuid = "510215fc-4207-5dde-b226-833fc4488ee2" -version = "0.2.3" - -[[OffsetArrays]] -deps = ["DelimitedFiles", "Test"] -git-tree-sha1 = "7d1442cb06fbfbc4fea936c3c56b38daffd22d3b" -uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -version = "0.9.1" - -[[OnlineStats]] -deps = ["DataStructures", "Dates", "LearnBase", "LinearAlgebra", "LossFunctions", "OnlineStatsBase", "PenaltyFunctions", "Random", "RecipesBase", "Reexport", "Statistics", "StatsBase", "SweepOperator", "Test"] -git-tree-sha1 = "70fe5cbb31d37c18f6312a2994c31b782be50607" -uuid = "a15396b6-48d5-5d58-9928-6d29437db91e" -version = "0.19.2" - -[[OnlineStatsBase]] -deps = ["LearnBase", "Test"] -git-tree-sha1 = "520580a74e09378fb6665fa89339323d411d3df3" -uuid = "925886fa-5bf2-5e8e-b522-a9147a512338" -version = "0.9.1" - -[[Optim]] -deps = ["Calculus", "DiffEqDiffTools", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "Random", "SparseArrays", "StatsBase", "Test"] -git-tree-sha1 = "0f2a6c6ff9db396cc7af15bb1cf057a26662ff17" -uuid = "429524aa-4258-5aef-a3af-852621145aeb" -version = "0.17.2" - -[[OrderedCollections]] -deps = ["Random", "Serialization", "Test"] -git-tree-sha1 = "85619a3f3e17bb4761fe1b1fd47f0e979f964d5b" -uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.0.2" - -[[PDMats]] -deps = ["Arpack", "LinearAlgebra", "SparseArrays", "SuiteSparse", "Test"] -git-tree-sha1 = "b6c91fc0ab970c0563cbbe69af18d741a49ce551" -uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" -version = "0.9.6" - -[[Packing]] -deps = ["GeometryTypes", "Test"] -git-tree-sha1 = "bc7c284233cf0518933bf9977e3e8234efcc1c30" -uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" -version = "0.3.0" - -[[PaddedViews]] -deps = ["OffsetArrays", "Test"] -git-tree-sha1 = "7da3e7e1a58cffbf10177553ae95f17b92516912" -uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" -version = "0.4.2" - -[[Parameters]] -deps = ["Markdown", "OrderedCollections", "REPL", "Test"] -git-tree-sha1 = "eec0fe16344cc14aa2e6251874ab30d62aff4f7c" -uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" -version = "0.10.2" - -[[Parsers]] -deps = ["Dates", "Mmap", "Test", "WeakRefStrings"] -git-tree-sha1 = "9c2b96d07344f9f716fee1c4a7258ac327d08a6c" -uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "0.2.15" - -[[PenaltyFunctions]] -deps = ["InteractiveUtils", "LearnBase", "LinearAlgebra", "RecipesBase", "Reexport", "Test"] -git-tree-sha1 = "b0baaa5218ca0ffd6a8ae37ef0b58e0df688ac8b" -uuid = "06bb1623-fdd5-5ca2-a01c-88eae3ea319e" -version = "0.1.2" - -[[Pkg]] -deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] -uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" - -[[PlotUtils]] -deps = ["Colors", "Dates", "Printf", "Random", "Reexport", "Test"] -git-tree-sha1 = "fd28f30a294a38ec847de95d8ac7ac916ccd7c06" -uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" -version = "0.5.5" - -[[Polynomials]] -deps = ["LinearAlgebra", "SparseArrays", "Test"] -git-tree-sha1 = "1a1eae52956658a6acae6fa1b6d6c3d488192895" -uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" -version = "0.5.1" - -[[PooledArrays]] -deps = ["Test"] -git-tree-sha1 = "5c5ded7adc52867f599c21d3f43542fce491afda" -uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" -version = "0.4.1" - -[[PositiveFactorizations]] -deps = ["LinearAlgebra", "Test"] -git-tree-sha1 = "86ae7329c4b5c266acf5c7c524a972300d991e1c" -uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" -version = "0.2.1" - -[[Printf]] -deps = ["Unicode"] -uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" - -[[Profile]] -deps = ["Printf"] -uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" - -[[QuadGK]] -deps = ["DataStructures", "LinearAlgebra", "Test"] -git-tree-sha1 = "3ce467a8e76c6030d4c3786e7d3a73442017cdc0" -uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.0.3" - -[[QuartzImageIO]] -deps = ["ColorTypes", "ColorVectorSpace", "FileIO", "FixedPointNumbers", "ImageCore", "Libdl", "Random", "Test"] -git-tree-sha1 = "c747a56f223919b157e6cd9dc58d59c560586302" -uuid = "dca85d43-d64c-5e67-8c65-017450d5d020" -version = "0.5.0" - -[[RData]] -deps = ["CategoricalArrays", "CodecZlib", "DataFrames", "Dates", "FileIO", "Missings", "Test", "TimeZones"] -git-tree-sha1 = "8f3b644f4ebce291431846f5532272b0864c757c" -uuid = "df47a6cb-8c03-5eed-afd8-b6050d6c41da" -version = "0.5.0" - -[[RDatasets]] -deps = ["CSV", "CodecZlib", "DataFrames", "FileIO", "Printf", "RData", "Reexport", "Test"] -git-tree-sha1 = "4d93a52b94397bf0a9477d04e7a151a688672695" -uuid = "ce6b1742-4840-55fa-b093-852dadbb1d8b" -version = "0.6.1" - -[[REPL]] -deps = ["InteractiveUtils", "Markdown", "Sockets"] -uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" - -[[Random]] -deps = ["Serialization"] -uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" - -[[Ratios]] -deps = ["Compat"] -git-tree-sha1 = "fd159bead0a24e6270fd0573a340312bd4645cc2" -uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" -version = "0.3.0" - -[[RecipesBase]] -deps = ["Random", "Test"] -git-tree-sha1 = "0b3cb370ee4dc00f47f1193101600949f3dcf884" -uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" -version = "0.6.0" - -[[Reexport]] -deps = ["Pkg"] -git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" -uuid = "189a3867-3050-52da-a836-e630ba90ab69" -version = "0.2.0" - -[[Requires]] -deps = ["Test"] -git-tree-sha1 = "f6fbf4ba64d295e146e49e021207993b6b48c7d1" -uuid = "ae029012-a4dd-5104-9daa-d747884805df" -version = "0.5.2" - -[[Rmath]] -deps = ["BinaryProvider", "Libdl", "Random", "Statistics", "Test"] -git-tree-sha1 = "9a6c758cdf73036c3239b0afbea790def1dabff9" -uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" -version = "0.5.0" - -[[Rotations]] -deps = ["LinearAlgebra", "Random", "StaticArrays", "Statistics", "Test"] -git-tree-sha1 = "b629771d0de88979cbdbf72ceddc54de58fde149" -uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" -version = "0.9.1" - -[[SHA]] -uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" - -[[Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" - -[[SharedArrays]] -deps = ["Distributed", "Mmap", "Random", "Serialization"] -uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" - -[[Showoff]] -deps = ["Compat"] -git-tree-sha1 = "276b24f3ace98bec911be7ff2928d497dc759085" -uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" -version = "0.2.1" - -[[SignedDistanceFields]] -deps = ["Random", "Statistics", "Test"] -git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" -uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" -version = "0.4.0" - -[[Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" - -[[SortingAlgorithms]] -deps = ["DataStructures", "Random", "Test"] -git-tree-sha1 = "03f5898c9959f8115e30bc7226ada7d0df554ddd" -uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "0.3.1" - -[[SparseArrays]] -deps = ["LinearAlgebra", "Random"] -uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - -[[SpecialFunctions]] -deps = ["BinDeps", "BinaryProvider", "Libdl", "Test"] -git-tree-sha1 = "0b45dc2e45ed77f445617b99ff2adf0f5b0f23ea" -uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "0.7.2" - -[[StaticArrays]] -deps = ["InteractiveUtils", "LinearAlgebra", "Random", "Statistics", "Test"] -git-tree-sha1 = "97c4bf0f647488dd7ac01ea12be5885f88762938" -uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "0.10.0" - -[[Statistics]] -deps = ["LinearAlgebra", "SparseArrays"] -uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" - -[[StatsBase]] -deps = ["DataStructures", "LinearAlgebra", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "Test"] -git-tree-sha1 = "2722397d88f8ffef551948f6c20e1d74a743298c" -uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" -version = "0.26.0" - -[[StatsFuns]] -deps = ["Rmath", "SpecialFunctions", "Test"] -git-tree-sha1 = "d14bb7b03defd2deaa5675646f6783089e0556f0" -uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" -version = "0.7.0" - -[[StatsMakie]] -deps = ["AbstractPlotting", "Distributions", "FreqTables", "IndexedTables", "IntervalSets", "KernelDensity", "Loess", "NamedArrays", "Observables", "Random", "Statistics", "StatsBase", "Tables", "Test"] -git-tree-sha1 = "12429b8d5308b27483f4d6148cefb86080e4d054" -uuid = "65254759-4cff-5aa5-8326-61ce017a8c70" -version = "0.0.1" - -[[SuiteSparse]] -deps = ["Libdl", "LinearAlgebra", "SparseArrays"] -uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" - -[[SweepOperator]] -deps = ["LinearAlgebra", "Test"] -git-tree-sha1 = "2039aaa96f7b21634a1b3246cb2699dd1d26d473" -uuid = "7522ee7d-7047-56d0-94d9-4bc626e7058d" -version = "0.2.0" - -[[TableTraits]] -deps = ["IteratorInterfaceExtensions", "Test"] -git-tree-sha1 = "da062a2c31f16178f68190243c24140801720a43" -uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" -version = "0.4.0" - -[[TableTraitsUtils]] -deps = ["DataValues", "IteratorInterfaceExtensions", "Missings", "TableTraits", "Test"] -git-tree-sha1 = "a355f1882d64881a11f853e64dcc353975c4df6e" -uuid = "382cd787-c1b6-5bf2-a167-d5b971a19bda" -version = "0.3.1" - -[[Tables]] -deps = ["Requires", "Test"] -git-tree-sha1 = "940944e6b68a35046282897a2218891c7cf14a32" -uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "0.1.12" - -[[Test]] -deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] -uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[[TiledIteration]] -deps = ["OffsetArrays", "Test"] -git-tree-sha1 = "58f6f07d3b54a363ec283a8f5fc9fb4ecebde656" -uuid = "06e1c1a7-607b-532d-9fad-de7d9aa2abac" -version = "0.2.3" - -[[TimeZones]] -deps = ["Compat", "EzXML", "Mocking", "Nullables"] -git-tree-sha1 = "4a4ab113913e19ad62b67e6c5c056509eac00c19" -uuid = "f269a46b-ccf7-5d73-abea-4c690281aa53" -version = "0.8.2" - -[[TranscodingStreams]] -deps = ["Pkg", "Random", "Test"] -git-tree-sha1 = "a34a2d588e2d2825602bf14a24216d5c8b0921ec" -uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.8.1" - -[[URIParser]] -deps = ["Test", "Unicode"] -git-tree-sha1 = "6ddf8244220dfda2f17539fa8c9de20d6c575b69" -uuid = "30578b45-9adc-5946-b283-645ec420af67" -version = "0.4.0" - -[[UUIDs]] -deps = ["Random"] -uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" - -[[Unicode]] -uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" - -[[UnicodeFun]] -deps = ["Test"] -git-tree-sha1 = "63cbbd00217fc9aafedf055b60459c1ae7e01ecc" -uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" -version = "0.4.0" - -[[VersionParsing]] -deps = ["Compat"] -git-tree-sha1 = "c9d5aa108588b978bd859554660c8a5c4f2f7669" -uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" -version = "1.1.3" - -[[WeakRefStrings]] -deps = ["Missings", "Random", "Test"] -git-tree-sha1 = "1087e8be380f2c8b96434b02bb1150fc1c511135" -uuid = "ea10d353-3f73-51f8-a26c-33c1cb351aa5" -version = "0.5.3" - -[[WinRPM]] -deps = ["BinDeps", "Compat", "HTTPClient", "LibExpat", "Libdl", "Libz", "URIParser"] -git-tree-sha1 = "2a889d320f3b77d17c037f295859fe570133cfbf" -uuid = "c17dfb99-b4f7-5aad-8812-456da1ad7187" -version = "0.4.2" - -[[WoodburyMatrices]] -deps = ["LinearAlgebra", "Random", "SparseArrays", "Test"] -git-tree-sha1 = "21772c33b447757ec7d3e61fcdfb9ea5c47eedcf" -uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" -version = "0.4.1" diff --git a/test/Project.toml b/test/Project.toml deleted file mode 100644 index 8f668d62022..00000000000 --- a/test/Project.toml +++ /dev/null @@ -1,28 +0,0 @@ -name = "CairoMakie" -uuid = "f1797859-2bec-5491-832b-e19d79114491" -author = ["Simon Danisch "] -version = "0.0.0" - -[deps] -AbstractPlotting = "537997a7-5e4e-5d89-9595-2241ea00577e" -Cairo = "159f3aea-2a34-519c-b102-8c37f9878175" -Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" -DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -GeometryTypes = "4d00f742-c7ba-57c2-abde-4428a4b178cb" -ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534" -ImageFiltering = "6a3955dd-da59-5b1f-98d4-e7296123deb5" -ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" -ImageTransformations = "02fcd773-0e25-5acc-982a-7f6622650795" -LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -MakieGallery = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" -MeshIO = "7269a6da-0436-5bbc-96c2-40638cbb6118" -ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" -QuartzImageIO = "dca85d43-d64c-5e67-8c65-017450d5d020" -RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" -StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" -StatsMakie = "65254759-4cff-5aa5-8326-61ce017a8c70" - -[compat] -AbstractPlotting = ">=0.9.1" -GeometryTypes = ">=0.7.2" From 8694f0b93d2dfafa6b75cd617dd8d544554321e8 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 16 Jan 2019 01:05:11 +0100 Subject: [PATCH 0065/1328] bump version --- Manifest.toml | 464 -------------------------------------------------- Project.toml | 2 +- 2 files changed, 1 insertion(+), 465 deletions(-) delete mode 100644 Manifest.toml diff --git a/Manifest.toml b/Manifest.toml deleted file mode 100644 index 57e74429fbf..00000000000 --- a/Manifest.toml +++ /dev/null @@ -1,464 +0,0 @@ -[[AbstractFFTs]] -deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "8d59c3b1463b5e0ad05a3698167f85fac90e184d" -uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" -version = "0.3.2" - -[[AbstractPlotting]] -deps = ["ColorBrewer", "ColorTypes", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "ImageMagick", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "Test", "UnicodeFun"] -git-tree-sha1 = "b47cc331607de0daa3d3e40ed77b61b36dd19c17" -uuid = "537997a7-5e4e-5d89-9595-2241ea00577e" -version = "0.9.2" - -[[AxisAlgorithms]] -deps = ["Compat", "WoodburyMatrices"] -git-tree-sha1 = "99dabbe853e4f641ab21a676131f2cf9fb29937e" -uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" -version = "0.3.0" - -[[AxisArrays]] -deps = ["Compat", "Dates", "IntervalSets", "IterTools", "Random", "RangeArrays", "Test"] -git-tree-sha1 = "2e2536e9e6f27c4f8d09d8442b61a7ae0b910c28" -uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" -version = "0.3.0" - -[[Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" - -[[BinDeps]] -deps = ["Compat", "Libdl", "SHA", "URIParser"] -git-tree-sha1 = "12093ca6cdd0ee547c39b1870e0c9c3f154d9ca9" -uuid = "9e28174c-4ba2-5203-b857-d8d62c4213ee" -version = "0.8.10" - -[[BinaryProvider]] -deps = ["Libdl", "Pkg", "SHA", "Test"] -git-tree-sha1 = "055eb2690182ebc31087859c3dd8598371d3ef9e" -uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" -version = "0.5.3" - -[[CMake]] -deps = ["BinDeps", "Libdl", "Test"] -git-tree-sha1 = "74853a75c26a4a73ac391ee26ee29ebeb5583d9f" -uuid = "631607c0-34d2-5d66-819e-eb0f9aa2061a" -version = "1.1.0" - -[[CMakeWrapper]] -deps = ["BinDeps", "CMake", "Libdl", "Parameters", "Test"] -git-tree-sha1 = "2b43d451639984e3571951cc687b8509b0a86c6d" -uuid = "d5fb7624-851a-54ee-a528-d3f3bac0b4a0" -version = "0.2.2" - -[[ColorBrewer]] -deps = ["Colors", "JSON", "Test"] -git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" -uuid = "a2cac450-b92f-5266-8821-25eda20663c8" -version = "0.4.0" - -[[ColorTypes]] -deps = ["FixedPointNumbers", "Random", "Test"] -git-tree-sha1 = "f73b0e10f2a5756de7019818a41654686da06b09" -uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" -version = "0.7.5" - -[[ColorVectorSpace]] -deps = ["ColorTypes", "Colors", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "StatsBase", "Test"] -git-tree-sha1 = "a890f08e61b40e9843d7177206da61229a3603c8" -uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" -version = "0.6.2" - -[[Colors]] -deps = ["ColorTypes", "FixedPointNumbers", "InteractiveUtils", "Printf", "Reexport", "Test"] -git-tree-sha1 = "9f0a0210450acb91c730b730a994f8eef1d3d543" -uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" -version = "0.9.5" - -[[Compat]] -deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] -git-tree-sha1 = "ec61a16eed883ad0cfa002d7489b3ce6d039bb9a" -uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "1.4.0" - -[[Conda]] -deps = ["Compat", "JSON", "VersionParsing"] -git-tree-sha1 = "fb86fe40cb5b35990e368709bfdc1b46dbb99dac" -uuid = "8f4d0f93-b110-5947-807f-2305c1781a2d" -version = "1.1.1" - -[[Contour]] -deps = ["LinearAlgebra", "StaticArrays", "Test"] -git-tree-sha1 = "b974e164358fea753ef853ce7bad97afec15bb80" -uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" -version = "0.5.1" - -[[CoordinateTransformations]] -deps = ["Compat", "Rotations", "StaticArrays"] -git-tree-sha1 = "47f05d0b7f4999609f92e657147df000818c1f24" -uuid = "150eb455-5306-5404-9cee-2592286d6298" -version = "0.5.0" - -[[DataStructures]] -deps = ["InteractiveUtils", "OrderedCollections", "Random", "Serialization", "Test"] -git-tree-sha1 = "8fc6e166e24fda04b2b648d4260cdad241788c54" -uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.14.0" - -[[Dates]] -deps = ["Printf"] -uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" - -[[DelimitedFiles]] -deps = ["Mmap"] -uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" - -[[Distributed]] -deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] -uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" - -[[FFTW]] -deps = ["AbstractFFTs", "BinaryProvider", "Compat", "Conda", "Libdl", "LinearAlgebra", "Reexport", "Test"] -git-tree-sha1 = "29cda58afbf62f35b1a094882ad6c745a47b2eaa" -uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" -version = "0.2.4" - -[[FileIO]] -deps = ["Pkg", "Random", "Test"] -git-tree-sha1 = "1a114d08094e7267ba8d4d684f930d5a722184de" -uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -version = "1.0.4" - -[[FixedPointNumbers]] -deps = ["Test"] -git-tree-sha1 = "b8045033701c3b10bf2324d7203404be7aef88ba" -uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.5.3" - -[[FreeType]] -deps = ["BinaryProvider", "Libdl", "Pkg", "Test"] -git-tree-sha1 = "06462b9d5aca708d764d16e5ba6a83ba7b753d57" -uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" -version = "2.1.1" - -[[FreeTypeAbstraction]] -deps = ["ColorVectorSpace", "Colors", "FreeType", "StaticArrays", "Test"] -git-tree-sha1 = "271ef13438bd0946950fd34d9241e5beefd6d4b3" -uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" -version = "0.4.1" - -[[GLFW]] -deps = ["BinDeps", "CMakeWrapper", "Homebrew", "Libdl", "Test"] -git-tree-sha1 = "035e2b5e9c335afae1e92ecfe532cf0620da869f" -uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" -version = "2.3.0" - -[[GeometryTypes]] -deps = ["ColorTypes", "FixedPointNumbers", "IterTools", "LinearAlgebra", "StaticArrays", "Test"] -git-tree-sha1 = "28b193e14466beecf928449e0f8505ff6de3709d" -uuid = "4d00f742-c7ba-57c2-abde-4428a4b178cb" -version = "0.7.2" - -[[Graphics]] -deps = ["Colors", "Compat", "NaNMath"] -git-tree-sha1 = "e3ead4211073d4117a0d2ef7d1efc5c8092c8412" -uuid = "a2bd30eb-e257-5431-a919-1863eab51364" -version = "0.4.0" - -[[Homebrew]] -deps = ["BinDeps", "InteractiveUtils", "JSON", "Libdl", "Test", "Unicode"] -git-tree-sha1 = "5582ec74f735cf8d12e562a2e65c47f34063bd51" -uuid = "d9be37ee-ecc9-5288-90f1-b9ca67657a75" -version = "0.7.0" - -[[IdentityRanges]] -deps = ["OffsetArrays", "Test"] -git-tree-sha1 = "f5ca23a08397288924a7535cd898d8ccbcde5ba5" -uuid = "bbac6d45-d8f3-5730-bfe4-7a449cd117ca" -version = "0.2.0" - -[[ImageAxes]] -deps = ["AxisArrays", "Colors", "FixedPointNumbers", "ImageCore", "MappedArrays", "Reexport", "SimpleTraits", "Test"] -git-tree-sha1 = "5735ec90843acaa67a4624611921c686cdf4efbf" -uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" -version = "0.5.0" - -[[ImageCore]] -deps = ["ColorTypes", "Colors", "FFTW", "FixedPointNumbers", "Graphics", "MappedArrays", "OffsetArrays", "PaddedViews", "Random", "Statistics", "Test"] -git-tree-sha1 = "5e7b1f49c80541860e08a7ea91805a24c1641f19" -uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" -version = "0.7.3" - -[[ImageMagick]] -deps = ["BinaryProvider", "ColorTypes", "FileIO", "FixedPointNumbers", "ImageCore", "InteractiveUtils", "Libdl", "Pkg", "Random", "Test"] -git-tree-sha1 = "0e4cc77fb131061b3525a97fd7d483b253c3aaad" -uuid = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" -version = "0.7.1" - -[[ImageTransformations]] -deps = ["AxisAlgorithms", "ColorTypes", "ColorVectorSpace", "Colors", "CoordinateTransformations", "FixedPointNumbers", "IdentityRanges", "ImageCore", "Interpolations", "LinearAlgebra", "OffsetArrays", "StaticArrays", "Test"] -git-tree-sha1 = "18ae1c0a8df31549a9452ceac93751d4aa166071" -uuid = "02fcd773-0e25-5acc-982a-7f6622650795" -version = "0.7.1" - -[[InteractiveUtils]] -deps = ["LinearAlgebra", "Markdown"] -uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" - -[[Interpolations]] -deps = ["AxisAlgorithms", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "SharedArrays", "SparseArrays", "StaticArrays", "Test", "WoodburyMatrices"] -git-tree-sha1 = "3493536a64dae5a21c0cc8aecf680647f3e12313" -uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" -version = "0.11.0" - -[[IntervalSets]] -deps = ["Compat"] -git-tree-sha1 = "9dc556002f23740de13946e8c2e41798e09a9249" -uuid = "8197267c-284f-5f27-9208-e0e47529a953" -version = "0.3.1" - -[[IterTools]] -deps = ["SparseArrays", "Test"] -git-tree-sha1 = "79246285c43602384e6f1943b3554042a3712056" -uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" -version = "1.1.1" - -[[JSON]] -deps = ["Dates", "Distributed", "Mmap", "Sockets", "Test", "Unicode"] -git-tree-sha1 = "1f7a25b53ec67f5e9422f1f551ee216503f4a0fa" -uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" -version = "0.20.0" - -[[LibGit2]] -uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" - -[[Libdl]] -uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" - -[[LinearAlgebra]] -deps = ["Libdl"] -uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - -[[Logging]] -uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" - -[[MacroTools]] -deps = ["Compat"] -git-tree-sha1 = "c443e1c8d58a4e9f61b708ad0a88286c7042145b" -uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.4.4" - -[[MappedArrays]] -deps = ["Test"] -git-tree-sha1 = "923441c5ac942b60bd3a842d5377d96646bcbf46" -uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" -version = "0.2.1" - -[[Markdown]] -deps = ["Base64"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" - -[[MeshIO]] -deps = ["ColorTypes", "FileIO", "GeometryTypes", "Printf", "Test"] -git-tree-sha1 = "3e01e12c4c626578a9d47fac0d15c9fe8dad5139" -uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" -version = "0.3.1" - -[[Missings]] -deps = ["Dates", "InteractiveUtils", "SparseArrays", "Test"] -git-tree-sha1 = "adc26d2ee85a49c413464110d922cf21efc9d233" -uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" -version = "0.3.1" - -[[Mmap]] -uuid = "a63ad114-7e13-5084-954f-fe012c677804" - -[[ModernGL]] -deps = ["Libdl"] -git-tree-sha1 = "f4f8fa8d04d3c1e7294f07fc37586c819466ad38" -uuid = "66fc600b-dfda-50eb-8b99-91cfa97b1301" -version = "1.0.0" - -[[NaNMath]] -deps = ["Compat"] -git-tree-sha1 = "ce3b85e484a5d4c71dd5316215069311135fa9f2" -uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" -version = "0.3.2" - -[[Observables]] -deps = ["Test"] -git-tree-sha1 = "dc02cec22747d1d10d9f70d8a1c03432b5bfbcd0" -uuid = "510215fc-4207-5dde-b226-833fc4488ee2" -version = "0.2.3" - -[[OffsetArrays]] -deps = ["DelimitedFiles", "Test"] -git-tree-sha1 = "7d1442cb06fbfbc4fea936c3c56b38daffd22d3b" -uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -version = "0.9.1" - -[[OrderedCollections]] -deps = ["Random", "Serialization", "Test"] -git-tree-sha1 = "85619a3f3e17bb4761fe1b1fd47f0e979f964d5b" -uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.0.2" - -[[Packing]] -deps = ["GeometryTypes", "Test"] -git-tree-sha1 = "bc7c284233cf0518933bf9977e3e8234efcc1c30" -uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" -version = "0.3.0" - -[[PaddedViews]] -deps = ["OffsetArrays", "Test"] -git-tree-sha1 = "7da3e7e1a58cffbf10177553ae95f17b92516912" -uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" -version = "0.4.2" - -[[Parameters]] -deps = ["Markdown", "OrderedCollections", "REPL", "Test"] -git-tree-sha1 = "eec0fe16344cc14aa2e6251874ab30d62aff4f7c" -uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" -version = "0.10.2" - -[[Pkg]] -deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] -uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" - -[[PlotUtils]] -deps = ["Colors", "Dates", "Printf", "Random", "Reexport", "Test"] -git-tree-sha1 = "fd28f30a294a38ec847de95d8ac7ac916ccd7c06" -uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" -version = "0.5.5" - -[[Printf]] -deps = ["Unicode"] -uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" - -[[REPL]] -deps = ["InteractiveUtils", "Markdown", "Sockets"] -uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" - -[[Random]] -deps = ["Serialization"] -uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" - -[[RangeArrays]] -deps = ["Compat"] -git-tree-sha1 = "d925adfd5b01cb46fde89dc9548d167b3b136f4a" -uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" -version = "0.3.1" - -[[Ratios]] -deps = ["Compat"] -git-tree-sha1 = "fd159bead0a24e6270fd0573a340312bd4645cc2" -uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" -version = "0.3.0" - -[[Reexport]] -deps = ["Pkg"] -git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" -uuid = "189a3867-3050-52da-a836-e630ba90ab69" -version = "0.2.0" - -[[Rotations]] -deps = ["LinearAlgebra", "Random", "StaticArrays", "Statistics", "Test"] -git-tree-sha1 = "b629771d0de88979cbdbf72ceddc54de58fde149" -uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" -version = "0.9.1" - -[[SHA]] -uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" - -[[Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" - -[[SharedArrays]] -deps = ["Distributed", "Mmap", "Random", "Serialization"] -uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" - -[[Showoff]] -deps = ["Compat"] -git-tree-sha1 = "276b24f3ace98bec911be7ff2928d497dc759085" -uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" -version = "0.2.1" - -[[SignedDistanceFields]] -deps = ["Random", "Statistics", "Test"] -git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" -uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" -version = "0.4.0" - -[[SimpleTraits]] -deps = ["InteractiveUtils", "MacroTools", "Test"] -git-tree-sha1 = "c0a542b8d5e369b179ccd296b2ca987f6da5da0a" -uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" -version = "0.8.0" - -[[Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" - -[[SortingAlgorithms]] -deps = ["DataStructures", "Random", "Test"] -git-tree-sha1 = "03f5898c9959f8115e30bc7226ada7d0df554ddd" -uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "0.3.1" - -[[SparseArrays]] -deps = ["LinearAlgebra", "Random"] -uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - -[[SpecialFunctions]] -deps = ["BinDeps", "BinaryProvider", "Libdl", "Test"] -git-tree-sha1 = "0b45dc2e45ed77f445617b99ff2adf0f5b0f23ea" -uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "0.7.2" - -[[StaticArrays]] -deps = ["InteractiveUtils", "LinearAlgebra", "Random", "Statistics", "Test"] -git-tree-sha1 = "97c4bf0f647488dd7ac01ea12be5885f88762938" -uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "0.10.0" - -[[Statistics]] -deps = ["LinearAlgebra", "SparseArrays"] -uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" - -[[StatsBase]] -deps = ["DataStructures", "LinearAlgebra", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "Test"] -git-tree-sha1 = "2722397d88f8ffef551948f6c20e1d74a743298c" -uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" -version = "0.26.0" - -[[Test]] -deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] -uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[[URIParser]] -deps = ["Test", "Unicode"] -git-tree-sha1 = "6ddf8244220dfda2f17539fa8c9de20d6c575b69" -uuid = "30578b45-9adc-5946-b283-645ec420af67" -version = "0.4.0" - -[[UUIDs]] -deps = ["Random"] -uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" - -[[Unicode]] -uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" - -[[UnicodeFun]] -deps = ["Test"] -git-tree-sha1 = "63cbbd00217fc9aafedf055b60459c1ae7e01ecc" -uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" -version = "0.4.0" - -[[VersionParsing]] -deps = ["Compat"] -git-tree-sha1 = "c9d5aa108588b978bd859554660c8a5c4f2f7669" -uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" -version = "1.1.3" - -[[WoodburyMatrices]] -deps = ["LinearAlgebra", "Random", "SparseArrays", "Test"] -git-tree-sha1 = "21772c33b447757ec7d3e61fcdfb9ea5c47eedcf" -uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" -version = "0.4.1" diff --git a/Project.toml b/Project.toml index 829f2d2fc47..692e84fbe09 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "GLMakie" uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" -version = "0.0.1" +version = "0.0.4" [deps] AbstractPlotting = "537997a7-5e4e-5d89-9595-2241ea00577e" From 2f2f15156a20c15de34e229dff6ae63b7ab0b5f4 Mon Sep 17 00:00:00 2001 From: eoudet Date: Thu, 24 Jan 2019 13:30:30 +0100 Subject: [PATCH 0066/1328] add shading for MeshScatter --- src/GLVisualize/visualize/particles.jl | 1 + src/drawing_primitives.jl | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/GLVisualize/visualize/particles.jl b/src/GLVisualize/visualize/particles.jl index c0b2e9e23cf..5ff64c37379 100644 --- a/src/GLVisualize/visualize/particles.jl +++ b/src/GLVisualize/visualize/particles.jl @@ -277,6 +277,7 @@ function meshparticle(p, s, data) rotation = rot => TextureBuffer texturecoordinates = nothing + shading = true end @gen_defaults! data begin diff --git a/src/drawing_primitives.jl b/src/drawing_primitives.jl index e1713b1d006..a2b6a9a6711 100644 --- a/src/drawing_primitives.jl +++ b/src/drawing_primitives.jl @@ -110,6 +110,8 @@ end function draw_atomic(screen::GLScreen, scene::Scene, x::Union{Scatter, MeshScatter}) robj = cached_robj!(screen, scene, x) do gl_attributes + # signals not supported for shading yet + gl_attributes[:shading] = AbstractPlotting.to_value(get(gl_attributes, :shading, true)) marker = lift_convert(:marker, pop!(gl_attributes, :marker), x) if isa(x, Scatter) msize = pop!(gl_attributes, :stroke_width) From b3d558a10da2c538a37907f6681be02d410555fc Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 28 Jan 2019 15:56:07 +0100 Subject: [PATCH 0067/1328] use metadata compatible uuid --- Project.toml | 2 +- REQUIRE | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 49130ea12a2..897f0b6ddc5 100644 --- a/Project.toml +++ b/Project.toml @@ -1,5 +1,5 @@ name = "CairoMakie" -uuid = "f1797859-2bec-5491-832b-e19d79114491" +uuid = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" author = ["Simon Danisch "] version = "0.0.2" diff --git a/REQUIRE b/REQUIRE index 4a40558f26f..40ade2dc425 100644 --- a/REQUIRE +++ b/REQUIRE @@ -6,3 +6,4 @@ AbstractPlotting 0.9.1 Cairo Colors Makie +FileIO From 88be8438c7639a96d2a50f96fd6bb7fc578d5860 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Tue, 29 Jan 2019 17:47:18 +0100 Subject: [PATCH 0068/1328] support char markers --- src/CairoMakie.jl | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/CairoMakie.jl b/src/CairoMakie.jl index 8c728c7d4c2..3757ef44b3c 100644 --- a/src/CairoMakie.jl +++ b/src/CairoMakie.jl @@ -267,8 +267,7 @@ function extract_color(cmap, range, c) red(c), green(c), blue(c), alpha(c) end -function draw_marker(ctx, marker, pos, scale, color, strokecolor, strokewidth) - Cairo.set_source_rgba(ctx, color...) +function draw_marker(ctx, marker, pos, scale, strokecolor, strokewidth) pos += Point2f0(scale[1] / 2, -scale[2] / 2) Cairo.arc(ctx, pos[1], pos[2], scale[1] / 2, 0, 2*pi) Cairo.fill(ctx) @@ -280,8 +279,25 @@ function draw_marker(ctx, marker, pos, scale, color, strokecolor, strokewidth) end end -function draw_marker(ctx, marker::Union{Rect, Type{<: Rect}}, pos, scale, color, strokecolor, strokewidth) - Cairo.set_source_rgba(ctx, color...) +function draw_marker(ctx, marker::Char, pos, scale, strokecolor, strokewidth) + pos += Point2f0(scale[1] / 2, -scale[2] / 2) + + #TODO this shouldn't be hardcoded, but isn't available in the plot right now + font = AbstractPlotting.assetpath("DejaVu Sans") + Cairo.select_font_face( + ctx, font, + Cairo.FONT_SLANT_NORMAL, + Cairo.FONT_WEIGHT_NORMAL + ) + Cairo.move_to(ctx, pos[1], pos[2]) + mat = scale_matrix(scale...) + set_font_matrix(ctx, mat) + Cairo.show_text(ctx, string(marker)) + Cairo.fill(ctx) +end + + +function draw_marker(ctx, marker::Union{Rect, Type{<: Rect}}, pos, scale, strokecolor, strokewidth) s2 = Point2f0(scale[1], -scale[2]) Cairo.rectangle(ctx, pos..., s2...) Cairo.fill(ctx); @@ -309,7 +325,9 @@ function draw_atomic(scene::Scene, screen::CairoScreen, primitive::Scatter) pos = project_position(scene, point, model) mo = project_scale(scene, mo, size_model) pos += Point2f0(mo[1], -mo[2]) - draw_marker(ctx, marker, pos, scale, extract_color(cmap, crange, c), strokecolor, strokewidth) + Cairo.set_source_rgba(ctx, extract_color(cmap, crange, c)...) + m = convert_attribute(marker, key"marker"(), key"scatter"()) + draw_marker(ctx, m, pos, scale, strokecolor, strokewidth) end nothing end From 91b967056765903ec99adb2423cdfac2ea54c45b Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Tue, 29 Jan 2019 19:06:58 +0100 Subject: [PATCH 0069/1328] add FastPixel marker --- src/GLVisualize/visualize/particles.jl | 27 +++++++++++++++----------- src/drawing_primitives.jl | 12 +++++++++++- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/GLVisualize/visualize/particles.jl b/src/GLVisualize/visualize/particles.jl index c0b2e9e23cf..0e32d4ba0de 100644 --- a/src/GLVisualize/visualize/particles.jl +++ b/src/GLVisualize/visualize/particles.jl @@ -311,21 +311,26 @@ function meshparticle(p, s, data) data end +to_pointsize(x::Number) = Float32(x) +to_pointsize(x) = Float32(x[1]) + """ This is the most primitive particle system, which uses simple points as primitives. This is supposed to be the fastest way of displaying particles! """ -_default(position::VectorTypes{T}, s::style"speed", data::Dict) where {T <: Point} = @gen_defaults! data begin - vertex = position => GLBuffer - color_map = nothing => Vec2f0 - color = (color_map == nothing ? default(RGBA{Float32}, s) : nothing) => GLBuffer - - color_norm = nothing => Vec2f0 - intensity = nothing => GLBuffer - point_size = 2f0 - prerender = ()->glPointSize(point_size) - shader = GLVisualizeShader("fragment_output.frag", "dots.vert", "dots.frag") - gl_primitive = GL_POINTS +function _default(position::VectorTypes{T}, s::style"speed", data::Dict) where T <: Point + @gen_defaults! data begin + vertex = position => GLBuffer + color_map = nothing => Vec2f0 + color = (color_map == nothing ? default(RGBA{Float32}, s) : nothing) => GLBuffer + color_norm = nothing => Vec2f0 + intensity = nothing => GLBuffer + scale = 2f0 + shader = GLVisualizeShader("fragment_output.frag", "dots.vert", "dots.frag") + gl_primitive = GL_POINTS + end + data[:prerender] = ()-> glPointSize(to_pointsize(data[:scale][])) + data end """ diff --git a/src/drawing_primitives.jl b/src/drawing_primitives.jl index e1713b1d006..d7a26574bf4 100644 --- a/src/drawing_primitives.jl +++ b/src/drawing_primitives.jl @@ -108,6 +108,9 @@ function Base.insert!(screen::GLScreen, scene::Scene, x::Combined) end end +struct FastPixel end +AbstractPlotting.to_spritemarker(x::FastPixel) = x + function draw_atomic(screen::GLScreen, scene::Scene, x::Union{Scatter, MeshScatter}) robj = cached_robj!(screen, scene, x) do gl_attributes marker = lift_convert(:marker, pop!(gl_attributes, :marker), x) @@ -120,7 +123,14 @@ function draw_atomic(screen::GLScreen, scene::Scene, x::Union{Scatter, MeshScatt end positions = handle_view(x[1], gl_attributes) handle_intensities!(gl_attributes) - visualize((marker, positions), Style(:default), Dict{Symbol, Any}(gl_attributes)).children[] + if marker[] isa FastPixel + filter!(gl_attributes) do (k, v,) + k in (:color_map, :color, :color_norm, :intensity, :scale, :fxaa) + end + visualize(positions, Style(:speed), Dict{Symbol, Any}(gl_attributes)).children[] + else + visualize((marker, positions), Style(:default), Dict{Symbol, Any}(gl_attributes)).children[] + end end end From cae15f292ff9293a2ee0befc4a4c71a39a508971 Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 31 Jan 2019 11:41:43 +0100 Subject: [PATCH 0070/1328] Update Project.toml --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 897f0b6ddc5..4178be49035 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "CairoMakie" uuid = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" author = ["Simon Danisch "] -version = "0.0.2" +version = "0.1.0" [deps] AbstractPlotting = "537997a7-5e4e-5d89-9595-2241ea00577e" From 196f0753accbcb4eb711924d384055ed68d4bf88 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Sat, 2 Feb 2019 13:19:07 +0100 Subject: [PATCH 0071/1328] fix #13 --- src/GLVisualize/utils.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/GLVisualize/utils.jl b/src/GLVisualize/utils.jl index 0838bb62b2d..ce8d9d16a13 100644 --- a/src/GLVisualize/utils.jl +++ b/src/GLVisualize/utils.jl @@ -27,7 +27,11 @@ function assemble_robj(data, program, bb, primitive, pre_fun, post_fun) transp = get(data, :transparency, Node(false)) overdraw = get(data, :overdraw, Node(false)) pre = if pre_fun != nothing - () -> (GLAbstraction.StandardPrerender(transp, overdraw); pre_fun()) + _pre_fun = GLAbstraction.StandardPrerender(transp, overdraw) + function () + _pre_fun() + pre_fun() + end else GLAbstraction.StandardPrerender(transp, overdraw) end From 8289a9dbffc4e3336c62fc5d5d9879f3e536a499 Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Wed, 13 Feb 2019 23:51:25 +1000 Subject: [PATCH 0072/1328] Add antialiasing buffer around sprites This fixes #15 for simple billboards and should improve the situation for rotated sprites. --- .../assets/shader/distance_shape.frag | 29 ++++-- src/GLVisualize/assets/shader/sprites.geom | 88 +++++++++++-------- src/GLVisualize/assets/shader/sprites.vert | 4 +- 3 files changed, 72 insertions(+), 49 deletions(-) diff --git a/src/GLVisualize/assets/shader/distance_shape.frag b/src/GLVisualize/assets/shader/distance_shape.frag index 5b7822f76e4..c4d733c974e 100644 --- a/src/GLVisualize/assets/shader/distance_shape.frag +++ b/src/GLVisualize/assets/shader/distance_shape.frag @@ -13,7 +13,8 @@ struct Nothing{ //Nothing type, to encode if some variable doesn't contain any d #define DISTANCEFIELD 3 #define TRIANGLE 4 -#define ALIASING_CONST 1.05 +// Half width of antialiasing smoothstep +#define ANTIALIAS_RADIUS 0.8 #define M_SQRT_2 1.4142135 @@ -33,18 +34,19 @@ flat in vec4 f_stroke_color; flat in vec4 f_glow_color; flat in uvec2 f_id; flat in int f_primitive_index; -in vec2 f_uv; -in vec2 f_uv_offset; +in vec2 f_uv; // f_uv.{x,y} are in -1..1 +flat in vec4 f_uv_texture_bbox; float aastep(float threshold1, float value) { - float afwidth = length(vec2(dFdx(value), dFdy(value))) * ALIASING_CONST; + float afwidth = length(vec2(dFdx(value), dFdy(value))) * ANTIALIAS_RADIUS; return smoothstep(threshold1-afwidth, threshold1+afwidth, value); } float aastep(float threshold1, float threshold2, float value) { - float afwidth = length(vec2(dFdx(value), dFdy(value))) * ALIASING_CONST; - return smoothstep(threshold1-afwidth, threshold1+afwidth, value)-smoothstep(threshold2-afwidth, threshold2+afwidth, value); + float afwidth = length(vec2(dFdx(value), dFdy(value))) * ANTIALIAS_RADIUS; + return smoothstep(threshold1-afwidth, threshold1+afwidth, value) - + smoothstep(threshold2-afwidth, threshold2+afwidth, value); } float step2(float edge1, float edge2, float value){ @@ -110,13 +112,17 @@ float get_distancefield(Nothing distancefield, vec2 uv){ void write2framebuffer(vec4 color, uvec2 id); void main(){ - float signed_distance = 0.0; + // UV coords in the texture are clamped so that they don't stray outside + // the valid subregion of the texture atlas containing the current glyph. + vec2 tex_uv = mix(f_uv_texture_bbox.xy, f_uv_texture_bbox.zw, + clamp(0.5*(f_uv+1.0), 0.0, 1.0)); + if(shape == CIRCLE) signed_distance = circle(f_uv); else if(shape == DISTANCEFIELD) - signed_distance = get_distancefield(distancefield, f_uv_offset); + signed_distance = get_distancefield(distancefield, tex_uv); else if(shape == ROUNDED_RECTANGLE) signed_distance = rounded_rectangle(f_uv, vec2(0.2), vec2(0.8)); else if(shape == RECTANGLE) @@ -129,8 +135,13 @@ void main(){ float inside = aastep(inside_start, signed_distance); vec4 final_color = f_bg_color; - fill(f_color, image, f_uv_offset, inside, final_color); + fill(f_color, image, tex_uv, inside, final_color); stroke(f_stroke_color, signed_distance, half_stroke, final_color); glow(f_glow_color, signed_distance, aastep(-f_scale.x, signed_distance), final_color); + // Antialising debug tool: show the background of the sprite. + //final_color = mix(final_color, vec4(1,0,0,1), 0.2); + // TODO: In 3D, we should arguably discard fragments outside the sprite + //if (final_color == f_bg_color) + // discard; write2framebuffer(final_color, f_id); } diff --git a/src/GLVisualize/assets/shader/sprites.geom b/src/GLVisualize/assets/shader/sprites.geom index fa625171869..45d94529c7d 100644 --- a/src/GLVisualize/assets/shader/sprites.geom +++ b/src/GLVisualize/assets/shader/sprites.geom @@ -4,7 +4,7 @@ layout(points) in; layout(triangle_strip, max_vertices = 4) out; -vec3 qmul(vec4 quat, vec3 vec){ +mat4 qmat(vec4 quat){ float num = quat.x * 2.0; float num2 = quat.y * 2.0; float num3 = quat.z * 2.0; @@ -17,10 +17,11 @@ vec3 qmul(vec4 quat, vec3 vec){ float num10 = quat.w * num; float num11 = quat.w * num2; float num12 = quat.w * num3; - return vec3( - (1.0 - (num5 + num6)) * vec.x + (num7 - num12) * vec.y + (num8 + num11) * vec.z, - (num7 + num12) * vec.x + (1.0 - (num4 + num6)) * vec.y + (num9 - num10) * vec.z, - (num8 - num11) * vec.x + (num9 + num10) * vec.y + (1.0 - (num4 + num5)) * vec.z + return mat4( + (1.0 - (num5 + num6)), (num7 + num12), (num8 - num11), 0.0, + (num7 - num12), (1.0 - (num4 + num6)), (num9 + num10), 0.0, + (num8 + num11), (num9 - num10), (1.0 - (num4 + num5)), 0.0, + 0.0, 0.0, 0.0, 1.0 ); } @@ -31,7 +32,7 @@ uniform float glow_width; uniform vec2 resolution; in int g_primitive_index[]; -in vec4 g_uv_offset_width[]; +in vec4 g_uv_texture_bbox[]; in vec4 g_color[]; in vec4 g_stroke_color[]; in vec4 g_glow_color[]; @@ -47,45 +48,30 @@ flat out vec4 f_bg_color; flat out vec4 f_stroke_color; flat out vec4 f_glow_color; flat out uvec2 f_id; -out vec2 f_uv; -out vec2 f_uv_offset; +out vec2 f_uv; // f_uv.{x,y} are in -1..1 +flat out vec4 f_uv_texture_bbox; uniform mat4 projection, view, model; -void emit_vertex(vec2 vertex, vec2 uv, vec2 uv_offset) +void emit_vertex(vec4 vertex, vec2 uv) { - vec4 sprite_position, final_position; - mat4 mview = projection * view; - vec4 datapoint = mview * model * vec4(g_position[0], 1); - if(scale_primitive) - final_position = model * vec4(vertex, 0, 0); - else{ - final_position = vec4(vertex, 0, 0); - } - if(billboard){ - final_position = projection * final_position; - }else{ - final_position = mview * vec4( - qmul(g_rotation[0], final_position.xyz), 0 - ); - } - gl_Position = datapoint + final_position; - + gl_Position = vertex; f_uv = uv; - f_uv_offset = uv_offset; + f_uv_texture_bbox = g_uv_texture_bbox[0]; f_primitive_index = g_primitive_index[0]; f_color = g_color[0]; f_bg_color = vec4(g_color[0].rgb, 0); f_stroke_color = g_stroke_color[0]; f_glow_color = g_glow_color[0]; f_id = g_id[0]; - EmitVertex(); } +// Half width of antialiasing smoothstep. NB: Should match fragment shader +#define ANTIALIAS_RADIUS 0.8 void main(void) { @@ -97,17 +83,43 @@ void main(void) // |___\| // v1* * v2 vec4 o_w = g_offset_width[0]; - vec4 uv_o_w = g_uv_offset_width[0]; - float glow_stroke = max(glow_width, 0) + max(stroke_width, 0); //we don't need negativity here - vec2 final_scale = o_w.zw + 2*glow_stroke; - vec2 scale_rel = (final_scale / o_w.zw); - float hfs = glow_stroke; + + // Transform central point into scene + mat4 pview = projection * view; + vec4 datapoint = pview * model * vec4(g_position[0], 1); + + // Compute transform for the offset vectors from the central `datapoint` + mat4 trans = scale_primitive ? model : mat4(1.0); + trans = (billboard ? projection : pview * qmat(g_rotation[0])) * trans; + + // Extra buffering is required around sprites which are antialiased so that + // the antialias blur doesn't get cut off (see #15). This blur falls to + // zero at a radius of ANTIALIAS_RADIUS pixels in the viewport coordinates + // and we want to buffer the vertices in the *source* sprite coordinate + // system so that we get this amount in the output coordinates. + // + // However this is quite tricky for arbitrary sprite rotations. For now we + // just do something which is a cheap-ish and works for non-rotated sprites. + // For rotated sprites at glancing angles it's an underestimate, but sdf + // based antialiasing can't work perfectly there anyway. + // + // The following transform is the model->view->proj->clip->ndc->viewport + // forward transformation for vectors. + vec2 aa_viewport_x = 0.5*resolution*(trans*vec4(1,0,0,0)).xy / datapoint.w; + vec2 aa_viewport_y = 0.5*resolution*(trans*vec4(0,1,0,0)).xy / datapoint.w; + float aa_buf = ANTIALIAS_RADIUS/max(length(aa_viewport_x), length(aa_viewport_y)); + + float bbox_buf = aa_buf + max(glow_width, 0) + max(stroke_width, 0); + // Bounding box of billboard + vec4 bbox = vec4(-bbox_buf + o_w.xy, + o_w.xy + o_w.zw + bbox_buf); + vec2 scale_rel = (bbox.zw - bbox.xy) / o_w.zw; vec4 uv_min_max = vec4(-scale_rel, scale_rel); //minx, miny, maxx, maxy - vec4 vertices = vec4(-hfs + o_w.xy, o_w.xy + (o_w.zw) + glow_stroke); // use offset as origin quad (x,y,w,h) f_scale = vec2(stroke_width, glow_width)/o_w.zw; - emit_vertex(vertices.xy, uv_min_max.xw, uv_o_w.xw); - emit_vertex(vertices.xw, uv_min_max.xy, uv_o_w.xy); - emit_vertex(vertices.zy, uv_min_max.zw, uv_o_w.zw); - emit_vertex(vertices.zw, uv_min_max.zy, uv_o_w.zy); + + emit_vertex(datapoint + trans*vec4(bbox.xy,0,0), uv_min_max.xw); + emit_vertex(datapoint + trans*vec4(bbox.xw,0,0), uv_min_max.xy); + emit_vertex(datapoint + trans*vec4(bbox.zy,0,0), uv_min_max.zw); + emit_vertex(datapoint + trans*vec4(bbox.zw,0,0), uv_min_max.zy); EndPrimitive(); } diff --git a/src/GLVisualize/assets/shader/sprites.vert b/src/GLVisualize/assets/shader/sprites.vert index 44ac1ef9414..b5d89d5dc11 100644 --- a/src/GLVisualize/assets/shader/sprites.vert +++ b/src/GLVisualize/assets/shader/sprites.vert @@ -102,7 +102,7 @@ out uvec2 g_id; out int g_primitive_index; out vec3 g_position; out vec4 g_offset_width; -out vec4 g_uv_offset_width; +out vec4 g_uv_texture_bbox; out vec4 g_rotation; out vec4 g_color; out vec4 g_stroke_color; @@ -120,7 +120,7 @@ void main(){ g_offset_width.zw = _scale(scale, scale_x, scale_y, scale_z, g_primitive_index).xy; g_color = _color(color, intensity, color_map, color_norm, g_primitive_index, len); g_rotation = _rotation(rotation); - g_uv_offset_width = uv_offset_width; + g_uv_texture_bbox = uv_offset_width; g_stroke_color = stroke_color; g_glow_color = glow_color; From 7a36ada5c996b174de56cf5102f58d28a906d0ee Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Thu, 14 Feb 2019 01:20:59 +1000 Subject: [PATCH 0073/1328] Scale signed distance function rather than using finite differencing Avoiding finite differencing to get the smoothstep width improves the antialiasing a bit for small text sizes. --- .../assets/shader/distance_shape.frag | 39 +++++++++++++------ 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/src/GLVisualize/assets/shader/distance_shape.frag b/src/GLVisualize/assets/shader/distance_shape.frag index c4d733c974e..fc1222a98f4 100644 --- a/src/GLVisualize/assets/shader/distance_shape.frag +++ b/src/GLVisualize/assets/shader/distance_shape.frag @@ -13,8 +13,6 @@ struct Nothing{ //Nothing type, to encode if some variable doesn't contain any d #define DISTANCEFIELD 3 #define TRIANGLE 4 -// Half width of antialiasing smoothstep -#define ANTIALIAS_RADIUS 0.8 #define M_SQRT_2 1.4142135 @@ -38,15 +36,16 @@ in vec2 f_uv; // f_uv.{x,y} are in -1..1 flat in vec4 f_uv_texture_bbox; - -float aastep(float threshold1, float value) { - float afwidth = length(vec2(dFdx(value), dFdy(value))) * ANTIALIAS_RADIUS; - return smoothstep(threshold1-afwidth, threshold1+afwidth, value); +// Half width of antialiasing smoothstep +#define ANTIALIAS_RADIUS 0.8 +// These versions of aastep assume that `dist` is a signed distance function +// which has been scaled to be in units of pixels. +float aastep(float threshold1, float dist) { + return smoothstep(threshold1-ANTIALIAS_RADIUS, threshold1+ANTIALIAS_RADIUS, dist); } -float aastep(float threshold1, float threshold2, float value) { - float afwidth = length(vec2(dFdx(value), dFdy(value))) * ANTIALIAS_RADIUS; - return smoothstep(threshold1-afwidth, threshold1+afwidth, value) - - smoothstep(threshold2-afwidth, threshold2+afwidth, value); +float aastep(float threshold1, float threshold2, float dist) { + return smoothstep(threshold1-ANTIALIAS_RADIUS, threshold1+ANTIALIAS_RADIUS, dist) - + smoothstep(threshold2-ANTIALIAS_RADIUS, threshold2+ANTIALIAS_RADIUS, dist); } float step2(float edge1, float edge2, float value){ @@ -103,7 +102,12 @@ void glow(vec4 glowcolor, float signed_distance, float inside, inout vec4 color) } float get_distancefield(sampler2D distancefield, vec2 uv){ - return -texture(distancefield, uv).r; + // Glyph distance field units are in pixels. Convert to same scaling as + // f_uv so that it's the same as the programmatic signed_distance + // calculations. + float pixwidth = 2.0 * (f_uv_texture_bbox.z - f_uv_texture_bbox.x) * + textureSize(distancefield, 0).x; + return -texture(distancefield, uv).r / pixwidth; } float get_distancefield(Nothing distancefield, vec2 uv){ return 0.0; @@ -130,6 +134,19 @@ void main(){ else if(shape == TRIANGLE) signed_distance = triangle(f_uv); + // We have our signed distance in uv coords, but want it in viewport + // coords for direct use in antialiasing step functions. The `dist_scale` + // should be correct for cases where the transform has only isotropic + // scaling. + // + // For anisotropic cases we need multiple sampling to do a good job as + // there is no simple transformation of the distance field, but this + // formula should degrades gracefully as the geometric mean of the two + // scale factors. (We could consider multiple sampling for anisotropic + // filtering in important cases such as the text in 3D axes.) + float dist_scale = sqrt(abs(determinant(mat2(dFdx(f_uv), dFdy(f_uv))))); + signed_distance = signed_distance / dist_scale; + float half_stroke = -f_scale.x; float inside_start = max(half_stroke, 0.0); float inside = aastep(inside_start, signed_distance); From a6acce0396e800335658c4606eb077ecfb0769cb Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Thu, 14 Feb 2019 14:07:36 +1000 Subject: [PATCH 0074/1328] Clean up and fix antialias scaling implementation A big cleanup to the antialiasing scale calculation now that I've understood it better. The idea is to compute the isotropic *scale factor* of the uv->viewport transformation, at the centrepoint of the glyph. The key fix here was to incorporate the differential of the perspective divide into the scale calculation, making sure it's evaluated at the glyph centre. Also fix the scale factor for sampled signed distance functions of glyphs by using the average of x and y pixels per uv step. It's unclear why these wouldn't be equivalent... --- .../assets/shader/distance_shape.frag | 29 +++----- src/GLVisualize/assets/shader/sprites.geom | 73 +++++++++++++------ 2 files changed, 61 insertions(+), 41 deletions(-) diff --git a/src/GLVisualize/assets/shader/distance_shape.frag b/src/GLVisualize/assets/shader/distance_shape.frag index fc1222a98f4..5e7cc01c328 100644 --- a/src/GLVisualize/assets/shader/distance_shape.frag +++ b/src/GLVisualize/assets/shader/distance_shape.frag @@ -26,6 +26,7 @@ uniform vec2 resolution; uniform bool transparent_picking; flat in vec2 f_scale; +flat in float f_viewport_from_uv_scale; flat in vec4 f_color; flat in vec4 f_bg_color; flat in vec4 f_stroke_color; @@ -105,9 +106,10 @@ float get_distancefield(sampler2D distancefield, vec2 uv){ // Glyph distance field units are in pixels. Convert to same scaling as // f_uv so that it's the same as the programmatic signed_distance // calculations. - float pixwidth = 2.0 * (f_uv_texture_bbox.z - f_uv_texture_bbox.x) * - textureSize(distancefield, 0).x; - return -texture(distancefield, uv).r / pixwidth; + // TODO: This works, but why are the x and y proportions not the same!? + vec2 pixsize = 2.0 * (f_uv_texture_bbox.zw - f_uv_texture_bbox.xy) * + textureSize(distancefield, 0); + return -texture(distancefield, uv).r / (0.5*(pixsize.x + pixsize.y)); } float get_distancefield(Nothing distancefield, vec2 uv){ return 0.0; @@ -134,18 +136,8 @@ void main(){ else if(shape == TRIANGLE) signed_distance = triangle(f_uv); - // We have our signed distance in uv coords, but want it in viewport - // coords for direct use in antialiasing step functions. The `dist_scale` - // should be correct for cases where the transform has only isotropic - // scaling. - // - // For anisotropic cases we need multiple sampling to do a good job as - // there is no simple transformation of the distance field, but this - // formula should degrades gracefully as the geometric mean of the two - // scale factors. (We could consider multiple sampling for anisotropic - // filtering in important cases such as the text in 3D axes.) - float dist_scale = sqrt(abs(determinant(mat2(dFdx(f_uv), dFdy(f_uv))))); - signed_distance = signed_distance / dist_scale; + // See notes in geometry shader where f_viewport_from_uv_scale is computed. + signed_distance *= f_viewport_from_uv_scale; float half_stroke = -f_scale.x; float inside_start = max(half_stroke, 0.0); @@ -155,10 +147,13 @@ void main(){ fill(f_color, image, tex_uv, inside, final_color); stroke(f_stroke_color, signed_distance, half_stroke, final_color); glow(f_glow_color, signed_distance, aastep(-f_scale.x, signed_distance), final_color); - // Antialising debug tool: show the background of the sprite. - //final_color = mix(final_color, vec4(1,0,0,1), 0.2); // TODO: In 3D, we should arguably discard fragments outside the sprite //if (final_color == f_bg_color) // discard; write2framebuffer(final_color, f_id); + // Debug tools: + // * Show the background of the sprite. + // write2framebuffer(mix(final_color, vec4(1,0,0,1), 0.2), f_id); + // * Show the antialiasing border around glyphs + // write2framebuffer(vec4(vec3(abs(signed_distance)),1), f_id); } diff --git a/src/GLVisualize/assets/shader/sprites.geom b/src/GLVisualize/assets/shader/sprites.geom index 45d94529c7d..2eca424700c 100644 --- a/src/GLVisualize/assets/shader/sprites.geom +++ b/src/GLVisualize/assets/shader/sprites.geom @@ -43,6 +43,7 @@ in uvec2 g_id[]; flat out int f_primitive_index; flat out vec2 f_scale; +flat out float f_viewport_from_uv_scale; flat out vec4 f_color; flat out vec4 f_bg_color; flat out vec4 f_stroke_color; @@ -73,6 +74,10 @@ void emit_vertex(vec4 vertex, vec2 uv) // Half width of antialiasing smoothstep. NB: Should match fragment shader #define ANTIALIAS_RADIUS 0.8 +mat2 diagm(vec2 v){ + return mat2(v.x, 0.0, 0.0, v.y); +} + void main(void) { // emit quad as triangle strip @@ -84,42 +89,62 @@ void main(void) // v1* * v2 vec4 o_w = g_offset_width[0]; - // Transform central point into scene - mat4 pview = projection * view; - vec4 datapoint = pview * model * vec4(g_position[0], 1); + // Centred bounding box of billboard + vec2 bbox_radius = 0.5*o_w.zw; + vec2 sprite_bbox_centre = o_w.xy + bbox_radius; - // Compute transform for the offset vectors from the central `datapoint` + mat4 pview = projection * view; + // Compute transform for the offset vectors from the central point mat4 trans = scale_primitive ? model : mat4(1.0); trans = (billboard ? projection : pview * qmat(g_rotation[0])) * trans; + // Compute centre of billboard in clipping coordinates + vec4 vclip = pview*model*vec4(g_position[0],1) + trans*vec4(sprite_bbox_centre,0,0); + // Extra buffering is required around sprites which are antialiased so that // the antialias blur doesn't get cut off (see #15). This blur falls to // zero at a radius of ANTIALIAS_RADIUS pixels in the viewport coordinates // and we want to buffer the vertices in the *source* sprite coordinate // system so that we get this amount in the output coordinates. // - // However this is quite tricky for arbitrary sprite rotations. For now we - // just do something which is a cheap-ish and works for non-rotated sprites. - // For rotated sprites at glancing angles it's an underestimate, but sdf - // based antialiasing can't work perfectly there anyway. - // - // The following transform is the model->view->proj->clip->ndc->viewport - // forward transformation for vectors. - vec2 aa_viewport_x = 0.5*resolution*(trans*vec4(1,0,0,0)).xy / datapoint.w; - vec2 aa_viewport_y = 0.5*resolution*(trans*vec4(0,1,0,0)).xy / datapoint.w; - float aa_buf = ANTIALIAS_RADIUS/max(length(aa_viewport_x), length(aa_viewport_y)); + // Here we calculate the derivative of the mapping from sprite xy + // coordinates (defined by `trans`) into the viewport pixel coordinates. + // The derivative needs to include the proper term for the perspective + // divide into NDC, evaluated at the centre point `vclip`. + mat4 d_ndc_d_clip = mat4(1.0/vclip.w, 0.0, 0.0, 0.0, + 0.0, 1.0/vclip.w, 0.0, 0.0, + 0.0, 0.0, 1.0/vclip.w, 0.0, + -vclip.xyz/(vclip.w*vclip.w), 0.0); + mat2 dxyv_dxys = diagm(0.5*resolution) * mat2(d_ndc_d_clip*trans); + // Now, the appropriate amount to buffer our sprite by is the scale factor + // of the transformation (for isotropic transformations). For anisotropic + // transformations, the geometric mean of the two principle scale factors + // is a reasonable compromise: + float viewport_from_sprite_scale = sqrt(abs(determinant(dxyv_dxys))); + float aa_buf = ANTIALIAS_RADIUS / viewport_from_sprite_scale; + + // In the fragment shader we will have our signed distance in uv coords, + // but want it in viewport (pixel) coords for direct use in antialiasing + // step functions. We therefore need a scaling factor similar to + // viewport_from_sprite_scale, but including the uv->sprite coordinate + // system scaling factor as well. + float sprite_from_uv_scale = sqrt(bbox_radius.x*bbox_radius.y); + f_viewport_from_uv_scale = viewport_from_sprite_scale * sprite_from_uv_scale; - float bbox_buf = aa_buf + max(glow_width, 0) + max(stroke_width, 0); - // Bounding box of billboard - vec4 bbox = vec4(-bbox_buf + o_w.xy, - o_w.xy + o_w.zw + bbox_buf); - vec2 scale_rel = (bbox.zw - bbox.xy) / o_w.zw; - vec4 uv_min_max = vec4(-scale_rel, scale_rel); //minx, miny, maxx, maxy f_scale = vec2(stroke_width, glow_width)/o_w.zw; - emit_vertex(datapoint + trans*vec4(bbox.xy,0,0), uv_min_max.xw); - emit_vertex(datapoint + trans*vec4(bbox.xw,0,0), uv_min_max.xy); - emit_vertex(datapoint + trans*vec4(bbox.zy,0,0), uv_min_max.zw); - emit_vertex(datapoint + trans*vec4(bbox.zw,0,0), uv_min_max.zy); + // Compute xy bounding box of billboard (in model space units) after + // buffering and associated bounding box of uv coordinates. + float bbox_buf = aa_buf + max(glow_width, 0) + max(stroke_width, 0); + vec2 bbox_radius_buf = bbox_radius + bbox_buf; + vec4 bbox = vec4(-bbox_radius_buf, bbox_radius_buf); + vec2 uv_radius = bbox_radius_buf / bbox_radius; + vec4 uv_bbox = vec4(-uv_radius, uv_radius); //minx, miny, maxx, maxy + + emit_vertex(vclip + trans*vec4(bbox.xy,0,0), uv_bbox.xw); + emit_vertex(vclip + trans*vec4(bbox.xw,0,0), uv_bbox.xy); + emit_vertex(vclip + trans*vec4(bbox.zy,0,0), uv_bbox.zw); + emit_vertex(vclip + trans*vec4(bbox.zw,0,0), uv_bbox.zy); + EndPrimitive(); } From 14f98408ef6a452fc713ed8f6659a35b933722e1 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Thu, 14 Feb 2019 10:46:27 +0100 Subject: [PATCH 0075/1328] fix tests --- .gitlab-ci.yml | 2 +- Project.toml | 2 +- REQUIRE | 2 +- test/Manifest.toml | 882 --------------------------------------------- test/Project.toml | 53 --- test/REQUIRE | 8 +- test/runtests.jl | 10 +- 7 files changed, 8 insertions(+), 951 deletions(-) delete mode 100644 test/Manifest.toml delete mode 100644 test/Project.toml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b05c9715070..96ec0849bcf 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -15,4 +15,4 @@ job: script: - julia -e 'using InteractiveUtils; versioninfo()' - - julia --project=test/ -e 'using Pkg; Pkg.build("GLMakie"); include("test/runtests.jl")' + - julia -e 'using Pkg; Pkg.instantiate(); Pkg.add(PackageSpec(name = "GLMakie", path=ENV["CI_PROJECT_DIR"])); Pkg.test("GLMakie")' diff --git a/Project.toml b/Project.toml index 692e84fbe09..562604026b4 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "GLMakie" uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" -version = "0.0.4" +version = "0.0.5" [deps] AbstractPlotting = "537997a7-5e4e-5d89-9595-2241ea00577e" diff --git a/REQUIRE b/REQUIRE index 0b6f48ecd69..275d6b4d443 100644 --- a/REQUIRE +++ b/REQUIRE @@ -16,7 +16,7 @@ FreeTypeAbstraction 0.3.0 #for findfont @windows ImageMagick @linux ImageMagick @osx QuartzImageIO -AbstractPlotting 0.9.1 +AbstractPlotting 0.9.5 Primes PlotUtils IntervalSets diff --git a/test/Manifest.toml b/test/Manifest.toml deleted file mode 100644 index 77d2a9016d7..00000000000 --- a/test/Manifest.toml +++ /dev/null @@ -1,882 +0,0 @@ -[[AbstractFFTs]] -deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "8d59c3b1463b5e0ad05a3698167f85fac90e184d" -uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" -version = "0.3.2" - -[[AbstractPlotting]] -deps = ["ColorBrewer", "ColorTypes", "Colors", "Contour", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GeometryTypes", "ImageMagick", "IntervalSets", "LinearAlgebra", "Markdown", "Observables", "Packing", "PlotUtils", "Printf", "Random", "Serialization", "Showoff", "SignedDistanceFields", "StaticArrays", "Statistics", "UnicodeFun"] -git-tree-sha1 = "b47cc331607de0daa3d3e40ed77b61b36dd19c17" -repo-rev = "master" -repo-url = "https://github.com/JuliaPlots/AbstractPlotting.jl.git" -uuid = "537997a7-5e4e-5d89-9595-2241ea00577e" -version = "0.9.1" - -[[Arpack]] -deps = ["BinaryProvider", "Libdl", "LinearAlgebra", "Random", "SparseArrays", "Test"] -git-tree-sha1 = "1ce1ce9984683f0b6a587d5bdbc688ecb480096f" -uuid = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97" -version = "0.3.0" - -[[AxisAlgorithms]] -deps = ["Compat", "WoodburyMatrices"] -git-tree-sha1 = "99dabbe853e4f641ab21a676131f2cf9fb29937e" -uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" -version = "0.3.0" - -[[AxisArrays]] -deps = ["Compat", "Dates", "IntervalSets", "IterTools", "Random", "RangeArrays", "Test"] -git-tree-sha1 = "2e2536e9e6f27c4f8d09d8442b61a7ae0b910c28" -uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" -version = "0.3.0" - -[[Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" - -[[BinDeps]] -deps = ["Compat", "Libdl", "SHA", "URIParser"] -git-tree-sha1 = "12093ca6cdd0ee547c39b1870e0c9c3f154d9ca9" -uuid = "9e28174c-4ba2-5203-b857-d8d62c4213ee" -version = "0.8.10" - -[[BinaryProvider]] -deps = ["Libdl", "Pkg", "SHA", "Test"] -git-tree-sha1 = "055eb2690182ebc31087859c3dd8598371d3ef9e" -uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" -version = "0.5.3" - -[[CMake]] -deps = ["BinDeps", "Libdl", "Test"] -git-tree-sha1 = "74853a75c26a4a73ac391ee26ee29ebeb5583d9f" -uuid = "631607c0-34d2-5d66-819e-eb0f9aa2061a" -version = "1.1.0" - -[[CMakeWrapper]] -deps = ["BinDeps", "CMake", "Libdl", "Parameters", "Test"] -git-tree-sha1 = "2b43d451639984e3571951cc687b8509b0a86c6d" -uuid = "d5fb7624-851a-54ee-a528-d3f3bac0b4a0" -version = "0.2.2" - -[[CSV]] -deps = ["CategoricalArrays", "DataFrames", "DataStreams", "Dates", "Mmap", "Parsers", "Profile", "Random", "Tables", "Test", "Unicode", "WeakRefStrings"] -git-tree-sha1 = "b92c6f626a044cc9619156d54994b94084d40abe" -uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" -version = "0.4.3" - -[[Calculus]] -deps = ["Compat"] -git-tree-sha1 = "f60954495a7afcee4136f78d1d60350abd37a409" -uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" -version = "0.4.1" - -[[CatIndices]] -deps = ["CustomUnitRanges", "OffsetArrays", "Test"] -git-tree-sha1 = "254cf73ea369d2e39bfd6c5eb27a2296cfaed68c" -uuid = "aafaddc9-749c-510e-ac4f-586e18779b91" -version = "0.2.0" - -[[CategoricalArrays]] -deps = ["Compat", "Future", "Missings", "Printf", "Reexport", "Requires"] -git-tree-sha1 = "94d16e77dfacc59f6d6c1361866906dbb65b6f6b" -uuid = "324d7699-5711-5eae-9e2f-1d82baa6b597" -version = "0.5.2" - -[[CodecZlib]] -deps = ["BinaryProvider", "Libdl", "Test", "TranscodingStreams"] -git-tree-sha1 = "e3df104c84dfc108f0ca203fd7f5bbdc98641ae9" -uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.5.1" - -[[ColorBrewer]] -deps = ["Colors", "JSON", "Test"] -git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" -uuid = "a2cac450-b92f-5266-8821-25eda20663c8" -version = "0.4.0" - -[[ColorTypes]] -deps = ["FixedPointNumbers", "Random", "Test"] -git-tree-sha1 = "f73b0e10f2a5756de7019818a41654686da06b09" -uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" -version = "0.7.5" - -[[ColorVectorSpace]] -deps = ["ColorTypes", "Colors", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "StatsBase", "Test"] -git-tree-sha1 = "a890f08e61b40e9843d7177206da61229a3603c8" -uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" -version = "0.6.2" - -[[Colors]] -deps = ["ColorTypes", "FixedPointNumbers", "InteractiveUtils", "Printf", "Reexport", "Test"] -git-tree-sha1 = "9f0a0210450acb91c730b730a994f8eef1d3d543" -uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" -version = "0.9.5" - -[[Combinatorics]] -deps = ["LinearAlgebra", "Polynomials", "Test"] -git-tree-sha1 = "50b3ae4d643dc27eaff69fb6be06ee094d5500c9" -uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" -version = "0.7.0" - -[[CommonSubexpressions]] -deps = ["Test"] -git-tree-sha1 = "efdaf19ab11c7889334ca247ff4c9f7c322817b0" -uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" -version = "0.2.0" - -[[Compat]] -deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] -git-tree-sha1 = "ec61a16eed883ad0cfa002d7489b3ce6d039bb9a" -uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "1.4.0" - -[[ComputationalResources]] -deps = ["Test"] -git-tree-sha1 = "89e7e7ed20af73d9f78877d2b8d1194e7b6ff13d" -uuid = "ed09eef8-17a6-5b46-8889-db040fac31e3" -version = "0.3.0" - -[[Conda]] -deps = ["Compat", "JSON", "VersionParsing"] -git-tree-sha1 = "fb86fe40cb5b35990e368709bfdc1b46dbb99dac" -uuid = "8f4d0f93-b110-5947-807f-2305c1781a2d" -version = "1.1.1" - -[[Contour]] -deps = ["LinearAlgebra", "StaticArrays", "Test"] -git-tree-sha1 = "b974e164358fea753ef853ce7bad97afec15bb80" -uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" -version = "0.5.1" - -[[CoordinateTransformations]] -deps = ["Compat", "Rotations", "StaticArrays"] -git-tree-sha1 = "47f05d0b7f4999609f92e657147df000818c1f24" -uuid = "150eb455-5306-5404-9cee-2592286d6298" -version = "0.5.0" - -[[CustomUnitRanges]] -deps = ["Test"] -git-tree-sha1 = "0a106457a1831555857e18ac9617279c22fc393b" -uuid = "dc8bdbbb-1ca9-579f-8c36-e416f6a65cce" -version = "0.2.0" - -[[DataFrames]] -deps = ["CategoricalArrays", "CodecZlib", "Compat", "DataStreams", "Dates", "InteractiveUtils", "IteratorInterfaceExtensions", "LinearAlgebra", "Missings", "Printf", "Random", "Reexport", "SortingAlgorithms", "Statistics", "StatsBase", "TableTraits", "Tables", "Test", "TranscodingStreams", "Unicode", "WeakRefStrings"] -git-tree-sha1 = "60c2820c9ae93cc33e98cd820e0b449d551c7874" -uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -version = "0.15.1" - -[[DataStreams]] -deps = ["Dates", "Missings", "Test", "WeakRefStrings"] -git-tree-sha1 = "69c72a1beb4fc79490c361635664e13c8e4a9548" -uuid = "9a8bc11e-79be-5b39-94d7-1ccc349a1a85" -version = "0.4.1" - -[[DataStructures]] -deps = ["InteractiveUtils", "OrderedCollections", "Random", "Serialization", "Test"] -git-tree-sha1 = "8fc6e166e24fda04b2b648d4260cdad241788c54" -uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.14.0" - -[[DataValues]] -deps = ["Dates", "InteractiveUtils", "LinearAlgebra", "Random", "Test"] -git-tree-sha1 = "4fedccda7e5111354c7dcc832c7da83ff7258765" -uuid = "e7dc6d0d-1eca-5fa6-8ad6-5aecde8b7ea5" -version = "0.4.5" - -[[Dates]] -deps = ["Printf"] -uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" - -[[DelimitedFiles]] -deps = ["Mmap"] -uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" - -[[DiffEqDiffTools]] -deps = ["LinearAlgebra", "Test"] -git-tree-sha1 = "67700c9fc82033ec68a145bc650f6b9debdf9103" -uuid = "01453d9d-ee7c-5054-8395-0335cb756afa" -version = "0.7.1" - -[[DiffResults]] -deps = ["Compat", "StaticArrays"] -git-tree-sha1 = "db8acf46717b13d6c48deb7a12007c7f85a70cf7" -uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" -version = "0.0.3" - -[[DiffRules]] -deps = ["Random", "Test"] -git-tree-sha1 = "c49ec69428ffea0c1d1bbdc63d1a70f5df5860ad" -uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" -version = "0.0.7" - -[[Distances]] -deps = ["LinearAlgebra", "Printf", "Random", "Statistics", "Test"] -git-tree-sha1 = "2f38605722542f1c0a32dd2856fb529d8c226c69" -uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" -version = "0.7.3" - -[[Distributed]] -deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] -uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" - -[[Distributions]] -deps = ["Distributed", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsBase", "StatsFuns", "Test"] -git-tree-sha1 = "c24e9b6500c037673f0241a2783472b8c3d080c7" -uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.16.4" - -[[DocStringExtensions]] -deps = ["LibGit2", "Markdown", "Pkg", "Test"] -git-tree-sha1 = "1df01539a1c952cef21f2d2d1c092c2bcf0177d7" -uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.6.0" - -[[Documenter]] -deps = ["Base64", "DocStringExtensions", "InteractiveUtils", "LibGit2", "Logging", "Markdown", "Pkg", "REPL", "Random", "Test", "Unicode"] -git-tree-sha1 = "9f2135e0e7ecb63f9c3ef73ea15a31d8cdb79bb7" -uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "0.20.0" - -[[EzXML]] -deps = ["BinaryProvider", "Libdl", "Printf", "Test"] -git-tree-sha1 = "5623d1486bfaadd815f5c4ca501adda02b5337f1" -uuid = "8f5d6c58-4d21-5cfd-889c-e3ad7ee6a615" -version = "0.9.0" - -[[FFTViews]] -deps = ["CustomUnitRanges", "FFTW", "Test"] -git-tree-sha1 = "9d7993227ca7c0fdb6b31deef193adbba11c8f4e" -uuid = "4f61f5a4-77b1-5117-aa51-3ab5ef4ef0cd" -version = "0.2.0" - -[[FFTW]] -deps = ["AbstractFFTs", "BinaryProvider", "Compat", "Conda", "Libdl", "LinearAlgebra", "Reexport", "Test"] -git-tree-sha1 = "29cda58afbf62f35b1a094882ad6c745a47b2eaa" -uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" -version = "0.2.4" - -[[FileIO]] -deps = ["Pkg", "Random", "Test"] -git-tree-sha1 = "1a114d08094e7267ba8d4d684f930d5a722184de" -uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -version = "1.0.4" - -[[FixedPointNumbers]] -deps = ["Test"] -git-tree-sha1 = "b8045033701c3b10bf2324d7203404be7aef88ba" -uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.5.3" - -[[ForwardDiff]] -deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "InteractiveUtils", "LinearAlgebra", "NaNMath", "Random", "SparseArrays", "SpecialFunctions", "StaticArrays", "Test"] -git-tree-sha1 = "b91250044374764e7c29af59a774c4b8d6100b6e" -uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "0.10.1" - -[[FreeType]] -deps = ["BinaryProvider", "Libdl", "Pkg", "Test"] -git-tree-sha1 = "06462b9d5aca708d764d16e5ba6a83ba7b753d57" -uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" -version = "2.1.1" - -[[FreeTypeAbstraction]] -deps = ["ColorVectorSpace", "Colors", "FreeType", "StaticArrays", "Test"] -git-tree-sha1 = "271ef13438bd0946950fd34d9241e5beefd6d4b3" -uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" -version = "0.4.1" - -[[FreqTables]] -deps = ["CategoricalArrays", "NamedArrays", "Tables", "Test"] -git-tree-sha1 = "93ce75cae27c2d1c6518771d597b6dd0a3d623d3" -uuid = "da1fdf0e-e0ff-5433-a45f-9bb5ff651cb1" -version = "0.3.1" - -[[Future]] -deps = ["Random"] -uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" - -[[GDAL]] -deps = ["BinaryProvider", "Libdl", "Test"] -git-tree-sha1 = "100429098b7ec9930f7db9ba68aee3495365be24" -uuid = "add2ef01-049f-52c4-9ee2-e494f65e021a" -version = "0.2.0" - -[[GLFW]] -deps = ["BinDeps", "CMakeWrapper", "Homebrew", "Libdl", "Test"] -git-tree-sha1 = "035e2b5e9c335afae1e92ecfe532cf0620da869f" -uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" -version = "2.3.0" - -[[GLMakie]] -deps = ["AbstractPlotting", "AxisArrays", "ColorTypes", "ColorVectorSpace", "Colors", "FileIO", "FixedPointNumbers", "FreeType", "FreeTypeAbstraction", "GLFW", "GeometryTypes", "ImageAxes", "ImageCore", "ImageMagick", "ImageTransformations", "IntervalSets", "IterTools", "LinearAlgebra", "MeshIO", "ModernGL", "Observables", "Printf", "Serialization", "StaticArrays"] -path = ".." -uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" -version = "0.0.1" - -[[GeometryTypes]] -deps = ["ColorTypes", "FixedPointNumbers", "IterTools", "LinearAlgebra", "StaticArrays", "Test"] -git-tree-sha1 = "28b193e14466beecf928449e0f8505ff6de3709d" -uuid = "4d00f742-c7ba-57c2-abde-4428a4b178cb" -version = "0.7.2" - -[[Graphics]] -deps = ["Colors", "Compat", "NaNMath"] -git-tree-sha1 = "e3ead4211073d4117a0d2ef7d1efc5c8092c8412" -uuid = "a2bd30eb-e257-5431-a919-1863eab51364" -version = "0.4.0" - -[[Homebrew]] -deps = ["BinDeps", "InteractiveUtils", "JSON", "Libdl", "Test", "Unicode"] -git-tree-sha1 = "5582ec74f735cf8d12e562a2e65c47f34063bd51" -uuid = "d9be37ee-ecc9-5288-90f1-b9ca67657a75" -version = "0.7.0" - -[[IdentityRanges]] -deps = ["OffsetArrays", "Test"] -git-tree-sha1 = "f5ca23a08397288924a7535cd898d8ccbcde5ba5" -uuid = "bbac6d45-d8f3-5730-bfe4-7a449cd117ca" -version = "0.2.0" - -[[ImageAxes]] -deps = ["AxisArrays", "Colors", "FixedPointNumbers", "ImageCore", "MappedArrays", "Reexport", "SimpleTraits", "Test"] -git-tree-sha1 = "5735ec90843acaa67a4624611921c686cdf4efbf" -uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" -version = "0.5.0" - -[[ImageCore]] -deps = ["ColorTypes", "Colors", "FFTW", "FixedPointNumbers", "Graphics", "MappedArrays", "OffsetArrays", "PaddedViews", "Random", "Statistics", "Test"] -git-tree-sha1 = "5e7b1f49c80541860e08a7ea91805a24c1641f19" -uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" -version = "0.7.3" - -[[ImageFiltering]] -deps = ["CatIndices", "ColorVectorSpace", "Colors", "ComputationalResources", "DataStructures", "FFTViews", "FFTW", "FixedPointNumbers", "ImageCore", "LinearAlgebra", "Logging", "MappedArrays", "OffsetArrays", "Random", "StaticArrays", "Statistics", "Test", "TiledIteration"] -git-tree-sha1 = "2d23d8f8c1def1e8d67d05e554baacc780d9313d" -uuid = "6a3955dd-da59-5b1f-98d4-e7296123deb5" -version = "0.5.1" - -[[ImageMagick]] -deps = ["BinaryProvider", "ColorTypes", "FileIO", "FixedPointNumbers", "ImageCore", "InteractiveUtils", "Libdl", "Pkg", "Random", "Test"] -git-tree-sha1 = "0e4cc77fb131061b3525a97fd7d483b253c3aaad" -uuid = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" -version = "0.7.1" - -[[ImageTransformations]] -deps = ["AxisAlgorithms", "ColorTypes", "ColorVectorSpace", "Colors", "CoordinateTransformations", "FixedPointNumbers", "IdentityRanges", "ImageCore", "Interpolations", "LinearAlgebra", "OffsetArrays", "StaticArrays", "Test"] -git-tree-sha1 = "18ae1c0a8df31549a9452ceac93751d4aa166071" -uuid = "02fcd773-0e25-5acc-982a-7f6622650795" -version = "0.7.1" - -[[IndexedTables]] -deps = ["DataValues", "Dates", "IteratorInterfaceExtensions", "LinearAlgebra", "OnlineStats", "PooledArrays", "Random", "Serialization", "SparseArrays", "Statistics", "TableTraits", "TableTraitsUtils", "Test", "WeakRefStrings"] -git-tree-sha1 = "cb4406eeed8729f8179940d39e6dec5598971341" -uuid = "6deec6e2-d858-57c5-ab9b-e6ca5bd20e43" -version = "0.8.1" - -[[IndirectArrays]] -deps = ["Compat", "Test"] -git-tree-sha1 = "b6e249be10a3381b2c72ac82f2d13d70067cb2bd" -uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" -version = "0.5.0" - -[[InteractiveUtils]] -deps = ["LinearAlgebra", "Markdown"] -uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" - -[[Interpolations]] -deps = ["AxisAlgorithms", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "SharedArrays", "SparseArrays", "StaticArrays", "Test", "WoodburyMatrices"] -git-tree-sha1 = "3493536a64dae5a21c0cc8aecf680647f3e12313" -uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" -version = "0.11.0" - -[[IntervalSets]] -deps = ["Compat"] -git-tree-sha1 = "9dc556002f23740de13946e8c2e41798e09a9249" -uuid = "8197267c-284f-5f27-9208-e0e47529a953" -version = "0.3.1" - -[[IterTools]] -deps = ["SparseArrays", "Test"] -git-tree-sha1 = "79246285c43602384e6f1943b3554042a3712056" -uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" -version = "1.1.1" - -[[IteratorInterfaceExtensions]] -deps = ["Test"] -git-tree-sha1 = "5484e5ede2a4137b9643f4d646e8e7b87b794415" -uuid = "82899510-4779-5014-852e-03e436cf321d" -version = "0.1.1" - -[[JSON]] -deps = ["Dates", "Distributed", "Mmap", "Sockets", "Test", "Unicode"] -git-tree-sha1 = "1f7a25b53ec67f5e9422f1f551ee216503f4a0fa" -uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" -version = "0.20.0" - -[[KernelDensity]] -deps = ["Distributions", "FFTW", "Interpolations", "Optim", "StatsBase", "Test"] -git-tree-sha1 = "c1048817fe5711f699abc8fabd47b1ac6ba4db04" -uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" -version = "0.5.1" - -[[LearnBase]] -deps = ["LinearAlgebra", "SparseArrays", "StatsBase", "Test"] -git-tree-sha1 = "c4b5da6d68517f46f70ed5157b28336b56cd2ff3" -uuid = "7f8f8fb0-2700-5f03-b4bd-41f8cfc144b6" -version = "0.2.2" - -[[LibGit2]] -uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" - -[[Libdl]] -uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" - -[[LineSearches]] -deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf", "Test"] -git-tree-sha1 = "54eb90e8dbe745d617c78dee1d6ae95c7f6f5779" -uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" -version = "7.0.1" - -[[LinearAlgebra]] -deps = ["Libdl"] -uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - -[[Loess]] -deps = ["Distances", "Random", "Statistics", "Test"] -git-tree-sha1 = "0ee46caf683a422b595be4dfaed6cda28f541e25" -uuid = "4345ca2d-374a-55d4-8d30-97f9976e7612" -version = "0.5.0" - -[[Logging]] -uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" - -[[LossFunctions]] -deps = ["InteractiveUtils", "LearnBase", "Markdown", "Random", "RecipesBase", "SparseArrays", "Statistics", "StatsBase", "Test"] -git-tree-sha1 = "b97d2e9a527733649d0205d3374d0daee352c50e" -uuid = "30fc2ffe-d236-52d8-8643-a9d8f7c094a7" -version = "0.5.0" - -[[MacroTools]] -deps = ["Compat"] -git-tree-sha1 = "c443e1c8d58a4e9f61b708ad0a88286c7042145b" -uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.4.4" - -[[MakieGallery]] -deps = ["AbstractPlotting", "BinaryProvider", "ColorTypes", "ColorVectorSpace", "Colors", "DataFrames", "Documenter", "FileIO", "FixedPointNumbers", "GDAL", "GeometryTypes", "ImageCore", "ImageFiltering", "ImageMagick", "ImageTransformations", "LinearAlgebra", "Markdown", "MeshIO", "ModernGL", "Pkg", "QuartzImageIO", "RDatasets", "Random", "Statistics", "Test"] -git-tree-sha1 = "2563a69f1a9c43cf0647127a506ba32782e9c45a" -repo-rev = "master" -repo-url = "https://github.com/JuliaPlots/MakieGallery.jl.git" -uuid = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" -version = "0.0.1+" - -[[MappedArrays]] -deps = ["Test"] -git-tree-sha1 = "923441c5ac942b60bd3a842d5377d96646bcbf46" -uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" -version = "0.2.1" - -[[Markdown]] -deps = ["Base64"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" - -[[MeshIO]] -deps = ["ColorTypes", "FileIO", "GeometryTypes", "Printf", "Test"] -git-tree-sha1 = "3e01e12c4c626578a9d47fac0d15c9fe8dad5139" -uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" -version = "0.3.1" - -[[Missings]] -deps = ["Dates", "InteractiveUtils", "SparseArrays", "Test"] -git-tree-sha1 = "adc26d2ee85a49c413464110d922cf21efc9d233" -uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" -version = "0.3.1" - -[[Mmap]] -uuid = "a63ad114-7e13-5084-954f-fe012c677804" - -[[Mocking]] -deps = ["Compat", "Dates"] -git-tree-sha1 = "4bf69aaf823b119b034e091e16b18311aa191663" -uuid = "78c3b35d-d492-501b-9361-3d52fe80e533" -version = "0.5.7" - -[[ModernGL]] -deps = ["Libdl"] -git-tree-sha1 = "f4f8fa8d04d3c1e7294f07fc37586c819466ad38" -uuid = "66fc600b-dfda-50eb-8b99-91cfa97b1301" -version = "1.0.0" - -[[NLSolversBase]] -deps = ["Calculus", "DiffEqDiffTools", "DiffResults", "Distributed", "ForwardDiff", "LinearAlgebra", "Random", "SparseArrays", "Test"] -git-tree-sha1 = "ebfb2e96970151753575b9c4d31d47e5ae8382a5" -uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" -version = "7.1.1" - -[[NaNMath]] -deps = ["Compat"] -git-tree-sha1 = "ce3b85e484a5d4c71dd5316215069311135fa9f2" -uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" -version = "0.3.2" - -[[NamedArrays]] -deps = ["Combinatorics", "DataStructures", "DelimitedFiles", "LinearAlgebra", "Random", "Requires", "SparseArrays", "Statistics", "Test"] -git-tree-sha1 = "977c65d68cee14ab28198e89ebc125d0738ef250" -uuid = "86f7a689-2022-50b4-a561-43c23ac3c673" -version = "0.9.2" - -[[Nullables]] -deps = ["Compat"] -git-tree-sha1 = "ae1a63457e14554df2159b0b028f48536125092d" -uuid = "4d1e1d77-625e-5b40-9113-a560ec7a8ecd" -version = "0.0.8" - -[[Observables]] -deps = ["Test"] -git-tree-sha1 = "dc02cec22747d1d10d9f70d8a1c03432b5bfbcd0" -uuid = "510215fc-4207-5dde-b226-833fc4488ee2" -version = "0.2.3" - -[[OffsetArrays]] -deps = ["DelimitedFiles", "Test"] -git-tree-sha1 = "7d1442cb06fbfbc4fea936c3c56b38daffd22d3b" -uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -version = "0.9.1" - -[[OnlineStats]] -deps = ["DataStructures", "Dates", "LearnBase", "LinearAlgebra", "LossFunctions", "OnlineStatsBase", "PenaltyFunctions", "Random", "RecipesBase", "Reexport", "Statistics", "StatsBase", "SweepOperator", "Test"] -git-tree-sha1 = "70fe5cbb31d37c18f6312a2994c31b782be50607" -uuid = "a15396b6-48d5-5d58-9928-6d29437db91e" -version = "0.19.2" - -[[OnlineStatsBase]] -deps = ["LearnBase", "Test"] -git-tree-sha1 = "520580a74e09378fb6665fa89339323d411d3df3" -uuid = "925886fa-5bf2-5e8e-b522-a9147a512338" -version = "0.9.1" - -[[Optim]] -deps = ["Calculus", "DiffEqDiffTools", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "Random", "SparseArrays", "StatsBase", "Test"] -git-tree-sha1 = "0f2a6c6ff9db396cc7af15bb1cf057a26662ff17" -uuid = "429524aa-4258-5aef-a3af-852621145aeb" -version = "0.17.2" - -[[OrderedCollections]] -deps = ["Random", "Serialization", "Test"] -git-tree-sha1 = "85619a3f3e17bb4761fe1b1fd47f0e979f964d5b" -uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.0.2" - -[[PDMats]] -deps = ["Arpack", "LinearAlgebra", "SparseArrays", "SuiteSparse", "Test"] -git-tree-sha1 = "b6c91fc0ab970c0563cbbe69af18d741a49ce551" -uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" -version = "0.9.6" - -[[Packing]] -deps = ["GeometryTypes", "Test"] -git-tree-sha1 = "bc7c284233cf0518933bf9977e3e8234efcc1c30" -uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" -version = "0.3.0" - -[[PaddedViews]] -deps = ["OffsetArrays", "Test"] -git-tree-sha1 = "7da3e7e1a58cffbf10177553ae95f17b92516912" -uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" -version = "0.4.2" - -[[Parameters]] -deps = ["Markdown", "OrderedCollections", "REPL", "Test"] -git-tree-sha1 = "eec0fe16344cc14aa2e6251874ab30d62aff4f7c" -uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" -version = "0.10.2" - -[[Parsers]] -deps = ["Dates", "Mmap", "Test", "WeakRefStrings"] -git-tree-sha1 = "9c2b96d07344f9f716fee1c4a7258ac327d08a6c" -uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "0.2.15" - -[[PenaltyFunctions]] -deps = ["InteractiveUtils", "LearnBase", "LinearAlgebra", "RecipesBase", "Reexport", "Test"] -git-tree-sha1 = "b0baaa5218ca0ffd6a8ae37ef0b58e0df688ac8b" -uuid = "06bb1623-fdd5-5ca2-a01c-88eae3ea319e" -version = "0.1.2" - -[[Pkg]] -deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] -uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" - -[[PlotUtils]] -deps = ["Colors", "Dates", "Printf", "Random", "Reexport", "Test"] -git-tree-sha1 = "fd28f30a294a38ec847de95d8ac7ac916ccd7c06" -uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" -version = "0.5.5" - -[[Polynomials]] -deps = ["LinearAlgebra", "SparseArrays", "Test"] -git-tree-sha1 = "1a1eae52956658a6acae6fa1b6d6c3d488192895" -uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" -version = "0.5.1" - -[[PooledArrays]] -deps = ["Test"] -git-tree-sha1 = "5c5ded7adc52867f599c21d3f43542fce491afda" -uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" -version = "0.4.1" - -[[PositiveFactorizations]] -deps = ["LinearAlgebra", "Test"] -git-tree-sha1 = "86ae7329c4b5c266acf5c7c524a972300d991e1c" -uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" -version = "0.2.1" - -[[Primes]] -deps = ["Test"] -git-tree-sha1 = "ff1a2323cb468ec5f201838fcbe3c232266b1f95" -uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" -version = "0.4.0" - -[[Printf]] -deps = ["Unicode"] -uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" - -[[Profile]] -deps = ["Printf"] -uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" - -[[QuadGK]] -deps = ["DataStructures", "LinearAlgebra", "Test"] -git-tree-sha1 = "3ce467a8e76c6030d4c3786e7d3a73442017cdc0" -uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.0.3" - -[[QuartzImageIO]] -deps = ["ColorTypes", "ColorVectorSpace", "FileIO", "FixedPointNumbers", "ImageCore", "Libdl", "Random", "Test"] -git-tree-sha1 = "c747a56f223919b157e6cd9dc58d59c560586302" -uuid = "dca85d43-d64c-5e67-8c65-017450d5d020" -version = "0.5.0" - -[[RData]] -deps = ["CategoricalArrays", "CodecZlib", "DataFrames", "Dates", "FileIO", "Missings", "Test", "TimeZones"] -git-tree-sha1 = "8f3b644f4ebce291431846f5532272b0864c757c" -uuid = "df47a6cb-8c03-5eed-afd8-b6050d6c41da" -version = "0.5.0" - -[[RDatasets]] -deps = ["CSV", "CodecZlib", "DataFrames", "FileIO", "Printf", "RData", "Reexport", "Test"] -git-tree-sha1 = "4d93a52b94397bf0a9477d04e7a151a688672695" -uuid = "ce6b1742-4840-55fa-b093-852dadbb1d8b" -version = "0.6.1" - -[[REPL]] -deps = ["InteractiveUtils", "Markdown", "Sockets"] -uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" - -[[Random]] -deps = ["Serialization"] -uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" - -[[RangeArrays]] -deps = ["Compat"] -git-tree-sha1 = "d925adfd5b01cb46fde89dc9548d167b3b136f4a" -uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" -version = "0.3.1" - -[[Ratios]] -deps = ["Compat"] -git-tree-sha1 = "fd159bead0a24e6270fd0573a340312bd4645cc2" -uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" -version = "0.3.0" - -[[RecipesBase]] -deps = ["Random", "Test"] -git-tree-sha1 = "0b3cb370ee4dc00f47f1193101600949f3dcf884" -uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" -version = "0.6.0" - -[[Reexport]] -deps = ["Pkg"] -git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" -uuid = "189a3867-3050-52da-a836-e630ba90ab69" -version = "0.2.0" - -[[Requires]] -deps = ["Test"] -git-tree-sha1 = "f6fbf4ba64d295e146e49e021207993b6b48c7d1" -uuid = "ae029012-a4dd-5104-9daa-d747884805df" -version = "0.5.2" - -[[Rmath]] -deps = ["BinaryProvider", "Libdl", "Random", "Statistics", "Test"] -git-tree-sha1 = "9a6c758cdf73036c3239b0afbea790def1dabff9" -uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" -version = "0.5.0" - -[[Rotations]] -deps = ["LinearAlgebra", "Random", "StaticArrays", "Statistics", "Test"] -git-tree-sha1 = "b629771d0de88979cbdbf72ceddc54de58fde149" -uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" -version = "0.9.1" - -[[SHA]] -uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" - -[[Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" - -[[SharedArrays]] -deps = ["Distributed", "Mmap", "Random", "Serialization"] -uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" - -[[Showoff]] -deps = ["Compat"] -git-tree-sha1 = "276b24f3ace98bec911be7ff2928d497dc759085" -uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" -version = "0.2.1" - -[[SignedDistanceFields]] -deps = ["Random", "Statistics", "Test"] -git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" -uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" -version = "0.4.0" - -[[SimpleTraits]] -deps = ["InteractiveUtils", "MacroTools", "Test"] -git-tree-sha1 = "c0a542b8d5e369b179ccd296b2ca987f6da5da0a" -uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" -version = "0.8.0" - -[[Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" - -[[SortingAlgorithms]] -deps = ["DataStructures", "Random", "Test"] -git-tree-sha1 = "03f5898c9959f8115e30bc7226ada7d0df554ddd" -uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "0.3.1" - -[[SparseArrays]] -deps = ["LinearAlgebra", "Random"] -uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - -[[SpecialFunctions]] -deps = ["BinDeps", "BinaryProvider", "Libdl", "Test"] -git-tree-sha1 = "0b45dc2e45ed77f445617b99ff2adf0f5b0f23ea" -uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "0.7.2" - -[[StaticArrays]] -deps = ["InteractiveUtils", "LinearAlgebra", "Random", "Statistics", "Test"] -git-tree-sha1 = "97c4bf0f647488dd7ac01ea12be5885f88762938" -uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "0.10.0" - -[[Statistics]] -deps = ["LinearAlgebra", "SparseArrays"] -uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" - -[[StatsBase]] -deps = ["DataStructures", "LinearAlgebra", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "Test"] -git-tree-sha1 = "2722397d88f8ffef551948f6c20e1d74a743298c" -uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" -version = "0.26.0" - -[[StatsFuns]] -deps = ["Rmath", "SpecialFunctions", "Test"] -git-tree-sha1 = "d14bb7b03defd2deaa5675646f6783089e0556f0" -uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" -version = "0.7.0" - -[[StatsMakie]] -deps = ["AbstractPlotting", "Distributions", "FreqTables", "IndexedTables", "IntervalSets", "KernelDensity", "Loess", "NamedArrays", "Observables", "Random", "Statistics", "StatsBase", "Tables", "Test"] -git-tree-sha1 = "12429b8d5308b27483f4d6148cefb86080e4d054" -uuid = "65254759-4cff-5aa5-8326-61ce017a8c70" -version = "0.0.1" - -[[SuiteSparse]] -deps = ["Libdl", "LinearAlgebra", "SparseArrays"] -uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" - -[[SweepOperator]] -deps = ["LinearAlgebra", "Test"] -git-tree-sha1 = "2039aaa96f7b21634a1b3246cb2699dd1d26d473" -uuid = "7522ee7d-7047-56d0-94d9-4bc626e7058d" -version = "0.2.0" - -[[TableTraits]] -deps = ["IteratorInterfaceExtensions", "Test"] -git-tree-sha1 = "da062a2c31f16178f68190243c24140801720a43" -uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" -version = "0.4.0" - -[[TableTraitsUtils]] -deps = ["DataValues", "IteratorInterfaceExtensions", "Missings", "TableTraits", "Test"] -git-tree-sha1 = "a355f1882d64881a11f853e64dcc353975c4df6e" -uuid = "382cd787-c1b6-5bf2-a167-d5b971a19bda" -version = "0.3.1" - -[[Tables]] -deps = ["Requires", "Test"] -git-tree-sha1 = "940944e6b68a35046282897a2218891c7cf14a32" -uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "0.1.12" - -[[Test]] -deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] -uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[[TiledIteration]] -deps = ["OffsetArrays", "Test"] -git-tree-sha1 = "58f6f07d3b54a363ec283a8f5fc9fb4ecebde656" -uuid = "06e1c1a7-607b-532d-9fad-de7d9aa2abac" -version = "0.2.3" - -[[TimeZones]] -deps = ["Compat", "EzXML", "Mocking", "Nullables"] -git-tree-sha1 = "4a4ab113913e19ad62b67e6c5c056509eac00c19" -uuid = "f269a46b-ccf7-5d73-abea-4c690281aa53" -version = "0.8.2" - -[[TranscodingStreams]] -deps = ["Pkg", "Random", "Test"] -git-tree-sha1 = "a34a2d588e2d2825602bf14a24216d5c8b0921ec" -uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.8.1" - -[[URIParser]] -deps = ["Test", "Unicode"] -git-tree-sha1 = "6ddf8244220dfda2f17539fa8c9de20d6c575b69" -uuid = "30578b45-9adc-5946-b283-645ec420af67" -version = "0.4.0" - -[[UUIDs]] -deps = ["Random"] -uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" - -[[Unicode]] -uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" - -[[UnicodeFun]] -deps = ["Test"] -git-tree-sha1 = "63cbbd00217fc9aafedf055b60459c1ae7e01ecc" -uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" -version = "0.4.0" - -[[VersionParsing]] -deps = ["Compat"] -git-tree-sha1 = "c9d5aa108588b978bd859554660c8a5c4f2f7669" -uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" -version = "1.1.3" - -[[WeakRefStrings]] -deps = ["Missings", "Random", "Test"] -git-tree-sha1 = "1087e8be380f2c8b96434b02bb1150fc1c511135" -uuid = "ea10d353-3f73-51f8-a26c-33c1cb351aa5" -version = "0.5.3" - -[[WoodburyMatrices]] -deps = ["LinearAlgebra", "Random", "SparseArrays", "Test"] -git-tree-sha1 = "21772c33b447757ec7d3e61fcdfb9ea5c47eedcf" -uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" -version = "0.4.1" diff --git a/test/Project.toml b/test/Project.toml deleted file mode 100644 index 82797a9f98b..00000000000 --- a/test/Project.toml +++ /dev/null @@ -1,53 +0,0 @@ -name = "MakieTests" -version = "0.0.1" - -[deps] -AbstractPlotting = "537997a7-5e4e-5d89-9595-2241ea00577e" -AxisArrays = "39de3d68-74b9-583c-8d2d-e117c070f3a9" -BinaryProvider = "b99e7846-7c00-51b0-8f62-c81ae34c0232" -ColorBrewer = "a2cac450-b92f-5266-8821-25eda20663c8" -ColorTypes = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" -ColorVectorSpace = "c3611d14-8923-5661-9e6a-0046d554d3a4" -Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" -Contour = "d38c429a-6771-53c6-b99e-75d170b6e991" -DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -FixedPointNumbers = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -FreeType = "b38be410-82b0-50bf-ab77-7b57e271db43" -FreeTypeAbstraction = "663a7486-cb36-511b-a19d-713bb74d65c9" -GDAL = "add2ef01-049f-52c4-9ee2-e494f65e021a" -GLFW = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" -GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" -GeometryTypes = "4d00f742-c7ba-57c2-abde-4428a4b178cb" -ImageAxes = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" -ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534" -ImageFiltering = "6a3955dd-da59-5b1f-98d4-e7296123deb5" -ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" -ImageTransformations = "02fcd773-0e25-5acc-982a-7f6622650795" -IndirectArrays = "9b13fd28-a010-5f03-acff-a1bbcff69959" -IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" -IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e" -LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -MakieGallery = "dbd62bd0-c9f5-5087-a2e1-f5c4bb0cec90" -Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a" -MeshIO = "7269a6da-0436-5bbc-96c2-40638cbb6118" -ModernGL = "66fc600b-dfda-50eb-8b99-91cfa97b1301" -Observables = "510215fc-4207-5dde-b226-833fc4488ee2" -PlotUtils = "995b91a9-d308-5afd-9ec6-746e21dbc043" -Primes = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" -Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" -QuartzImageIO = "dca85d43-d64c-5e67-8c65-017450d5d020" -RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" -Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" -Showoff = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" -StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" -StatsMakie = "65254759-4cff-5aa5-8326-61ce017a8c70" -UnicodeFun = "1cfade01-22cf-5700-b092-accc4b62d6e1" - -[compat] -AbstractPlotting = ">=0.9.1" -FreeTypeAbstraction = ">=0.3.0" -GLFW = ">=2.3.0" -GeometryTypes = ">=0.7.2" -StaticArrays = ">=0.6.6" diff --git a/test/REQUIRE b/test/REQUIRE index 56f84bd113a..c16be5c93d6 100644 --- a/test/REQUIRE +++ b/test/REQUIRE @@ -1,8 +1,6 @@ ImageCore ImageTransformations -@windows ImageMagick -@linux ImageMagick -@osx QuartzImageIO +ImageMagick Documenter ModernGL MeshIO @@ -13,4 +11,6 @@ FileIO ImageFiltering DataFrames RDatasets -MakieGallery +StatsMakie +MakieGallery 0.0.3 +GLFW diff --git a/test/runtests.jl b/test/runtests.jl index 02366fc6f0c..18acd19c256 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,15 +1,7 @@ using MakieGallery, AbstractPlotting, GLMakie push!(MakieGallery.plotting_backends, "GLMakie") - database = MakieGallery.load_database() -# THese examples download additional data - don't want to deal with that! -to_skip = ["WorldClim visualization", "Image on Geometry (Moon)", "Image on Geometry (Earth)"] -# we directly modify the database, which seems easiest for now -filter!(entry-> !(entry.title in to_skip), database) - -ref_path = MakieGallery.download_reference(v"0.0.9") - tested_diff_path = joinpath(@__DIR__, "tested_different") test_record_path = joinpath(@__DIR__, "test_recordings") rm(tested_diff_path, force = true, recursive = true) @@ -18,4 +10,4 @@ rm(test_record_path, force = true, recursive = true) mkpath(test_record_path) MakieGallery.record_examples(test_record_path) -MakieGallery.run_comparison(test_record_path, ref_path, tested_diff_path) +MakieGallery.run_comparison(test_record_path, tested_diff_path) From 9635c778fbb95b95f2c9d03c09eb829539406972 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Thu, 14 Feb 2019 16:41:03 +0100 Subject: [PATCH 0076/1328] fix tests --- REQUIRE | 1 + test/REQUIRE | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/REQUIRE b/REQUIRE index 275d6b4d443..f3b84de4726 100644 --- a/REQUIRE +++ b/REQUIRE @@ -29,3 +29,4 @@ IterTools AxisArrays ImageAxes IndirectArrays +ZipFile diff --git a/test/REQUIRE b/test/REQUIRE index c16be5c93d6..8f2756395a3 100644 --- a/test/REQUIRE +++ b/test/REQUIRE @@ -12,5 +12,5 @@ ImageFiltering DataFrames RDatasets StatsMakie -MakieGallery 0.0.3 +MakieGallery 0.0.4 GLFW From cbf3ee1e14b8a757a234bc854bde5a63f62230bf Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Thu, 14 Feb 2019 16:41:31 +0100 Subject: [PATCH 0077/1328] move to test REQUIRE --- REQUIRE | 1 - test/REQUIRE | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/REQUIRE b/REQUIRE index f3b84de4726..275d6b4d443 100644 --- a/REQUIRE +++ b/REQUIRE @@ -29,4 +29,3 @@ IterTools AxisArrays ImageAxes IndirectArrays -ZipFile diff --git a/test/REQUIRE b/test/REQUIRE index 8f2756395a3..4b28ebb1c24 100644 --- a/test/REQUIRE +++ b/test/REQUIRE @@ -14,3 +14,4 @@ RDatasets StatsMakie MakieGallery 0.0.4 GLFW +ZipFile From 1a92c0bb132f364e776c3321ae35e5b73c56bd33 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 18 Feb 2019 11:39:32 +0100 Subject: [PATCH 0078/1328] fix first click mouse query --- src/screen.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/screen.jl b/src/screen.jl index aebf7f3f4ab..e58db001738 100644 --- a/src/screen.jl +++ b/src/screen.jl @@ -296,6 +296,10 @@ function mouse_selection_native(scene::SceneLike) end if !(query_mouse in selection_queries) push!(selection_queries, query_mouse) + # TODO, this is not optimal since it does way more + # than calling query_mouse() on first click, + # but otherwise it might get into an inconsistent state. + render_frame(getscreen(scene)) end convert(SelectionID{Int}, _mouse_selection_id[]) end From 692905a10e2195ceac95fd04961a306f530ed571 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 18 Feb 2019 11:40:05 +0100 Subject: [PATCH 0079/1328] fix for #75 --- src/screen.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/screen.jl b/src/screen.jl index e58db001738..c486e08bedc 100644 --- a/src/screen.jl +++ b/src/screen.jl @@ -320,7 +320,11 @@ function mouseover(scene::SceneLike, plots::AbstractPlot...) end function flatten_plots(x::Atomic, plots = AbstractPlot[]) - push!(plots, x) + if isempty(x.plots) + push!(plots, x) + else + flatten_plots(x.plots, plots) + end plots end From 85b77a28eadcf2d9c88dc4fc7070b1d458e177af Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Tue, 19 Feb 2019 15:13:56 +1000 Subject: [PATCH 0080/1328] More fixes for scaling of signed distance functions * Use sprite uv coordinates in [0,1]x[0,1] box for simplicity (in removing several confusing factor of two errors!) * Fix any remaining weird scaling factors for glyph signed distance scaling. Correct results here depend on the distance scale factor in AbstractPlotting being set to 1 unit per pixel in the texture atlas. * Update procedural distance functions to compute signed distance with scale factor of exactly 1.0. --- .../assets/shader/distance_shape.frag | 35 +++++++------- src/GLVisualize/assets/shader/sprites.geom | 48 ++++++++++++++----- src/gl_backend.jl | 4 ++ 3 files changed, 57 insertions(+), 30 deletions(-) diff --git a/src/GLVisualize/assets/shader/distance_shape.frag b/src/GLVisualize/assets/shader/distance_shape.frag index 5e7cc01c328..29d06ac7396 100644 --- a/src/GLVisualize/assets/shader/distance_shape.frag +++ b/src/GLVisualize/assets/shader/distance_shape.frag @@ -26,14 +26,15 @@ uniform vec2 resolution; uniform bool transparent_picking; flat in vec2 f_scale; -flat in float f_viewport_from_uv_scale; +flat in float f_viewport_from_u_scale; +flat in float f_distancefield_scale; flat in vec4 f_color; flat in vec4 f_bg_color; flat in vec4 f_stroke_color; flat in vec4 f_glow_color; flat in uvec2 f_id; flat in int f_primitive_index; -in vec2 f_uv; // f_uv.{x,y} are in -1..1 +in vec2 f_uv; // f_uv.{x,y} are in the interval [-a, 1+a] flat in vec4 f_uv_texture_bbox; @@ -53,24 +54,25 @@ float step2(float edge1, float edge2, float value){ return min(step(edge1, value), 1-step(edge2, value)); } +// Procedural signed distance functions on the uv coordinate patch [0,1]x[0,1] +// Note that for antialiasing to work properly these should be *scale preserving* +// (If you must rescale uv, make sure to put the scale factor back in later.) float triangle(vec2 P){ - P /= 2; - float x = M_SQRT_2/2.0 * (P.x - P.y); - float y = M_SQRT_2/2.0 * (P.x + P.y); + P -= vec2(0.5); + float x = M_SQRT_2 * (P.x - P.y); + float y = M_SQRT_2 * (P.x + P.y); float r1 = max(abs(x), abs(y)) - 1./(2*M_SQRT_2); float r2 = P.y; return -max(r1,r2); } float circle(vec2 uv){ - return 1-length(uv); + return 0.5-length(uv-vec2(0.5)); } float rectangle(vec2 uv){ - uv /= 2; uv += 0.5; vec2 d = max(-uv, uv-vec2(1)); return -((length(max(vec2(0.0), d)) + min(0.0, max(d.x, d.y)))); } float rounded_rectangle(vec2 uv, vec2 tl, vec2 br){ - uv /= 2; uv += 0.5; vec2 d = max(tl-uv, uv-br); return -((length(max(vec2(0.0), d)) + min(0.0, max(d.x, d.y)))-tl.x); } @@ -103,13 +105,10 @@ void glow(vec4 glowcolor, float signed_distance, float inside, inout vec4 color) } float get_distancefield(sampler2D distancefield, vec2 uv){ - // Glyph distance field units are in pixels. Convert to same scaling as - // f_uv so that it's the same as the programmatic signed_distance + // Glyph distance field units are in pixels. Convert to same distance + // scaling as f_uv.x for consistency with the procedural signed_distance // calculations. - // TODO: This works, but why are the x and y proportions not the same!? - vec2 pixsize = 2.0 * (f_uv_texture_bbox.zw - f_uv_texture_bbox.xy) * - textureSize(distancefield, 0); - return -texture(distancefield, uv).r / (0.5*(pixsize.x + pixsize.y)); + return f_distancefield_scale * texture(distancefield, uv).r; } float get_distancefield(Nothing distancefield, vec2 uv){ return 0.0; @@ -123,7 +122,7 @@ void main(){ // UV coords in the texture are clamped so that they don't stray outside // the valid subregion of the texture atlas containing the current glyph. vec2 tex_uv = mix(f_uv_texture_bbox.xy, f_uv_texture_bbox.zw, - clamp(0.5*(f_uv+1.0), 0.0, 1.0)); + clamp(f_uv, 0.0, 1.0)); if(shape == CIRCLE) signed_distance = circle(f_uv); @@ -132,12 +131,12 @@ void main(){ else if(shape == ROUNDED_RECTANGLE) signed_distance = rounded_rectangle(f_uv, vec2(0.2), vec2(0.8)); else if(shape == RECTANGLE) - signed_distance = 1.0; + signed_distance = rectangle(f_uv); else if(shape == TRIANGLE) signed_distance = triangle(f_uv); - // See notes in geometry shader where f_viewport_from_uv_scale is computed. - signed_distance *= f_viewport_from_uv_scale; + // See notes in geometry shader where f_viewport_from_u_scale is computed. + signed_distance *= f_viewport_from_u_scale; float half_stroke = -f_scale.x; float inside_start = max(half_stroke, 0.0); diff --git a/src/GLVisualize/assets/shader/sprites.geom b/src/GLVisualize/assets/shader/sprites.geom index 2eca424700c..e43d3f189d1 100644 --- a/src/GLVisualize/assets/shader/sprites.geom +++ b/src/GLVisualize/assets/shader/sprites.geom @@ -1,6 +1,8 @@ {{GLSL_VERSION}} {{GLSL_EXTENSIONS}} +struct Nothing{ bool _; }; + layout(points) in; layout(triangle_strip, max_vertices = 4) out; @@ -25,6 +27,8 @@ mat4 qmat(vec4 quat){ ); } +{{distancefield_type}} distancefield; + uniform bool scale_primitive; uniform bool billboard; uniform float stroke_width; @@ -43,19 +47,30 @@ in uvec2 g_id[]; flat out int f_primitive_index; flat out vec2 f_scale; -flat out float f_viewport_from_uv_scale; +flat out float f_viewport_from_u_scale; +flat out float f_distancefield_scale; flat out vec4 f_color; flat out vec4 f_bg_color; flat out vec4 f_stroke_color; flat out vec4 f_glow_color; flat out uvec2 f_id; -out vec2 f_uv; // f_uv.{x,y} are in -1..1 +out vec2 f_uv; flat out vec4 f_uv_texture_bbox; uniform mat4 projection, view, model; - +float get_distancefield_scale(sampler2D distancefield){ + // Glyph distance field units are in pixels; convert to dimensionless + // x-coordinate of texture instead for consistency with programmatic uv + // distance fields in fragment shader. See also comments below. + float pixsize_x = (g_uv_texture_bbox[0].z - g_uv_texture_bbox[0].x) * + textureSize(distancefield, 0).x; + return -1.0/pixsize_x; +} +float get_distancefield_scale(Nothing distancefield){ + return 1.0; +} void emit_vertex(vec4 vertex, vec2 uv) { @@ -123,13 +138,20 @@ void main(void) float viewport_from_sprite_scale = sqrt(abs(determinant(dxyv_dxys))); float aa_buf = ANTIALIAS_RADIUS / viewport_from_sprite_scale; - // In the fragment shader we will have our signed distance in uv coords, - // but want it in viewport (pixel) coords for direct use in antialiasing - // step functions. We therefore need a scaling factor similar to - // viewport_from_sprite_scale, but including the uv->sprite coordinate - // system scaling factor as well. - float sprite_from_uv_scale = sqrt(bbox_radius.x*bbox_radius.y); - f_viewport_from_uv_scale = viewport_from_sprite_scale * sprite_from_uv_scale; + // In the fragment shader we want our signed distance in viewport (pixel) + // coords for direct use in antialiasing step functions. We therefore need + // a scaling factor similar to viewport_from_sprite_scale, but including + // the uv->sprite coordinate system scaling factor as well. We choose to + // use the bounding box *x* width for this. This comes with some + // consistency conditions: + // * For procedural distance fields, we need the sprite bounding box to be + // square. (If not, the uv coordinates will be anisotropically scaled and + // any calculation based on them will not be a distance function.) + // * For sampled distance fields, we need to consistently choose the *x* + // for the scaling in get_distancefield_scale(). + float sprite_from_u_scale = o_w.z; + f_viewport_from_u_scale = viewport_from_sprite_scale * sprite_from_u_scale; + f_distancefield_scale = get_distancefield_scale(distancefield); f_scale = vec2(stroke_width, glow_width)/o_w.zw; @@ -138,8 +160,10 @@ void main(void) float bbox_buf = aa_buf + max(glow_width, 0) + max(stroke_width, 0); vec2 bbox_radius_buf = bbox_radius + bbox_buf; vec4 bbox = vec4(-bbox_radius_buf, bbox_radius_buf); - vec2 uv_radius = bbox_radius_buf / bbox_radius; - vec4 uv_bbox = vec4(-uv_radius, uv_radius); //minx, miny, maxx, maxy + // uv bounding box is the buffered version of the domain [0,1]x[0,1] + vec2 uv_radius = 0.5 * bbox_radius_buf / bbox_radius; + vec2 uv_center = vec2(0.5); + vec4 uv_bbox = vec4(uv_center-uv_radius, uv_center+uv_radius); //minx, miny, maxx, maxy emit_vertex(vclip + trans*vec4(bbox.xy,0,0), uv_bbox.xw); emit_vertex(vclip + trans*vec4(bbox.xw,0,0), uv_bbox.xy); diff --git a/src/gl_backend.jl b/src/gl_backend.jl index 4e07ea58989..55dafe2f5da 100644 --- a/src/gl_backend.jl +++ b/src/gl_backend.jl @@ -21,6 +21,10 @@ function get_texture!(atlas) atlas.data, minfilter = :linear, magfilter = :linear, + # TODO: Consider alternatives to using the builtin anisotropic + # samplers for signed distance fields; the anisotropic + # filtering should happen *after* the SDF thresholding, but + # with the builtin sampler it happens before. anisotropic = 16f0, ) # update the texture, whenever a new font is added to the atlas From 6421837bc686732b6773706ea23b67acd323f4da Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Wed, 20 Feb 2019 00:52:44 +1000 Subject: [PATCH 0081/1328] Fix stroke units for sprites The units of the sprite stroke were broken by the changes in #21. Oops! Also add a fix for visual artefacts when applying large strokes to sampled distance fields (eg unicode glyphs), by adding on an approximate extension of the distance field. --- .../assets/shader/distance_shape.frag | 27 +++++++++++-------- src/GLVisualize/assets/shader/sprites.geom | 14 +++++----- src/drawing_primitives.jl | 2 -- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/GLVisualize/assets/shader/distance_shape.frag b/src/GLVisualize/assets/shader/distance_shape.frag index 29d06ac7396..b2ce7804528 100644 --- a/src/GLVisualize/assets/shader/distance_shape.frag +++ b/src/GLVisualize/assets/shader/distance_shape.frag @@ -25,7 +25,6 @@ uniform int shape; // shape is a uniform for now. Making them a vary uniform vec2 resolution; uniform bool transparent_picking; -flat in vec2 f_scale; flat in float f_viewport_from_u_scale; flat in float f_distancefield_scale; flat in vec4 f_color; @@ -88,17 +87,16 @@ void fill(vec4 c, sampler2DArray image, vec2 uv, float infill, inout vec4 color) } -void stroke(vec4 strokecolor, float signed_distance, float half_stroke, inout vec4 color){ - if (half_stroke != 0.0){ - float t = aastep(min(half_stroke, 0.0), max(half_stroke, 0.0), signed_distance); +void stroke(vec4 strokecolor, float signed_distance, float width, inout vec4 color){ + if (width != 0.0){ + float t = aastep(min(width, 0.0), max(width, 0.0), signed_distance); color = mix(color, strokecolor, t); } } void glow(vec4 glowcolor, float signed_distance, float inside, inout vec4 color){ if (glow_width > 0.0){ - float lolz = (f_scale.x+f_scale.y); - float outside = (abs(signed_distance)-f_scale.x)/f_scale.y; + float outside = (abs(signed_distance)-stroke_width)/glow_width; float alpha = 1-outside; color = mix(vec4(glowcolor.rgb, glowcolor.a*alpha), color, inside); } @@ -126,8 +124,16 @@ void main(){ if(shape == CIRCLE) signed_distance = circle(f_uv); - else if(shape == DISTANCEFIELD) + else if(shape == DISTANCEFIELD){ signed_distance = get_distancefield(distancefield, tex_uv); + if (stroke_width > 0 || glow_width > 0) { + // Compensate for the clamping of tex_uv by an approximate + // extension of the signed distance outside the valid texture + // region. + vec2 bufuv = f_uv - clamp(f_uv, 0.0, 1.0); + signed_distance -= length(bufuv); + } + } else if(shape == ROUNDED_RECTANGLE) signed_distance = rounded_rectangle(f_uv, vec2(0.2), vec2(0.8)); else if(shape == RECTANGLE) @@ -138,14 +144,13 @@ void main(){ // See notes in geometry shader where f_viewport_from_u_scale is computed. signed_distance *= f_viewport_from_u_scale; - float half_stroke = -f_scale.x; - float inside_start = max(half_stroke, 0.0); + float inside_start = max(-stroke_width, 0.0); float inside = aastep(inside_start, signed_distance); vec4 final_color = f_bg_color; fill(f_color, image, tex_uv, inside, final_color); - stroke(f_stroke_color, signed_distance, half_stroke, final_color); - glow(f_glow_color, signed_distance, aastep(-f_scale.x, signed_distance), final_color); + stroke(f_stroke_color, signed_distance, -stroke_width, final_color); + glow(f_glow_color, signed_distance, aastep(-stroke_width, signed_distance), final_color); // TODO: In 3D, we should arguably discard fragments outside the sprite //if (final_color == f_bg_color) // discard; diff --git a/src/GLVisualize/assets/shader/sprites.geom b/src/GLVisualize/assets/shader/sprites.geom index e43d3f189d1..8c6c6ce7d1c 100644 --- a/src/GLVisualize/assets/shader/sprites.geom +++ b/src/GLVisualize/assets/shader/sprites.geom @@ -46,7 +46,6 @@ in vec4 g_offset_width[]; in uvec2 g_id[]; flat out int f_primitive_index; -flat out vec2 f_scale; flat out float f_viewport_from_u_scale; flat out float f_distancefield_scale; flat out vec4 f_color; @@ -131,12 +130,12 @@ void main(void) 0.0, 0.0, 1.0/vclip.w, 0.0, -vclip.xyz/(vclip.w*vclip.w), 0.0); mat2 dxyv_dxys = diagm(0.5*resolution) * mat2(d_ndc_d_clip*trans); - // Now, the appropriate amount to buffer our sprite by is the scale factor - // of the transformation (for isotropic transformations). For anisotropic + // Now, our buffer size is expressed in viewport pixels but we get back to + // the sprite coordinate system using the scale factor of the + // transformation (for isotropic transformations). For anisotropic // transformations, the geometric mean of the two principle scale factors // is a reasonable compromise: float viewport_from_sprite_scale = sqrt(abs(determinant(dxyv_dxys))); - float aa_buf = ANTIALIAS_RADIUS / viewport_from_sprite_scale; // In the fragment shader we want our signed distance in viewport (pixel) // coords for direct use in antialiasing step functions. We therefore need @@ -153,11 +152,12 @@ void main(void) f_viewport_from_u_scale = viewport_from_sprite_scale * sprite_from_u_scale; f_distancefield_scale = get_distancefield_scale(distancefield); - f_scale = vec2(stroke_width, glow_width)/o_w.zw; - + // Compute required amount of buffering + float sprite_from_viewport_scale = 1.0 / viewport_from_sprite_scale; + float bbox_buf = sprite_from_viewport_scale * + (ANTIALIAS_RADIUS + max(glow_width, 0) + max(stroke_width, 0)); // Compute xy bounding box of billboard (in model space units) after // buffering and associated bounding box of uv coordinates. - float bbox_buf = aa_buf + max(glow_width, 0) + max(stroke_width, 0); vec2 bbox_radius_buf = bbox_radius + bbox_buf; vec4 bbox = vec4(-bbox_radius_buf, bbox_radius_buf); // uv bounding box is the buffered version of the domain [0,1]x[0,1] diff --git a/src/drawing_primitives.jl b/src/drawing_primitives.jl index 467799c015f..7f25851c7dc 100644 --- a/src/drawing_primitives.jl +++ b/src/drawing_primitives.jl @@ -117,8 +117,6 @@ function draw_atomic(screen::GLScreen, scene::Scene, x::Union{Scatter, MeshScatt gl_attributes[:shading] = AbstractPlotting.to_value(get(gl_attributes, :shading, true)) marker = lift_convert(:marker, pop!(gl_attributes, :marker), x) if isa(x, Scatter) - msize = pop!(gl_attributes, :stroke_width) - gl_attributes[:stroke_width] = lift(pixel2world, Node(scene), msize) gl_attributes[:billboard] = map(rot-> isa(rot, Billboard), x.attributes[:rotations]) gl_attributes[:distancefield][] == nothing && delete!(gl_attributes, :distancefield) gl_attributes[:uv_offset_width][] == Vec4f0(0) && delete!(gl_attributes, :uv_offset_width) From febeb9f37d7354b31d7b11e33e9865988cb6267c Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Wed, 20 Feb 2019 18:37:08 +1000 Subject: [PATCH 0082/1328] Refactor to simplify multiline geometry shader Here I've simplified the geometry shader for multilines significatnly so that it always renders only the single central segment. The end points are now accommodated by duplicating them with the index buffer. Fixes #26 and greatly mitigates #27. Ascii art FTW! --- src/GLVisualize/assets/shader/lines.geom | 103 +++++++++++------------ src/GLVisualize/assets/shader/lines.vert | 10 +-- src/GLVisualize/visualize/lines.jl | 24 ++---- 3 files changed, 63 insertions(+), 74 deletions(-) diff --git a/src/GLVisualize/assets/shader/lines.geom b/src/GLVisualize/assets/shader/lines.geom index 1fbd5f12673..1d02e259d90 100644 --- a/src/GLVisualize/assets/shader/lines.geom +++ b/src/GLVisualize/assets/shader/lines.geom @@ -5,13 +5,13 @@ {{GLSL_EXTENSIONS}} layout(lines_adjacency) in; -layout(triangle_strip, max_vertices = 12) out; +layout(triangle_strip, max_vertices = 7) out; in vec4 g_color[]; in float g_lastlen[]; in uvec2 g_id[]; in uint g_line_connections[]; -in int g_startend[]; +in int g_valid_vertex[]; //in float g_thickness[]; out vec4 f_color; @@ -58,10 +58,23 @@ const float infinity = 1.0 / 0.0; void main(void) { - if( - g_line_connections[1] != g_line_connections[2] - ){ - return; // if there is a break in the line, we don't emit anything + // We mark each of the four vertices as valid or not. Vertices can be + // marked invalid on input (eg, if they contain NaN). We also mark them + // invalid if they repeat in the index buffer. This allows us to render to + // the very ends of a polyline without clumsy buffering the position data on the + // CPU side by repeating the first and last points via the index buffer. It + // just requires a little care further down to avoid degenerate normals. + bool isvalid[4] = bool[]( + g_valid_vertex[0] == 1 && g_id[0].y != g_id[1].y, + g_valid_vertex[1] == 1, + g_valid_vertex[2] == 1, + g_valid_vertex[3] == 1 && g_id[2].y != g_id[3].y + ); + + if(g_line_connections[1] != g_line_connections[2] || !isvalid[1] || !isvalid[2]){ + // If one of the central vertices is invalid or there is a break in the + // line, we don't emit anything. + return; } // get the four vertices passed to the shader: vec2 p0 = screen_space(gl_in[0].gl_Position); // start of previous segment @@ -69,7 +82,6 @@ void main(void) vec2 p2 = screen_space(gl_in[2].gl_Position); // end of current segment, start of next segment vec2 p3 = screen_space(gl_in[3].gl_Position); // end of next segment - float thickness_aa = thickness+4; @@ -81,15 +93,36 @@ void main(void) //if( p2.y < -area.y || p2.y > area.y ) return; // determine the direction of each of the 3 segments (previous, current, next) - vec2 v0 = normalize(p1 - p0); - vec2 v1 = normalize(p2 - p1); - vec2 v2 = normalize(p3 - p2); + vec2 v1 = normalize(p2 - p1); + vec2 v0 = isvalid[0] ? normalize(p1 - p0) : v1; + vec2 v2 = isvalid[3] ? normalize(p3 - p2) : v1; // determine the normal of each of the 3 segments (previous, current, next) vec2 n0 = vec2(-v0.y, v0.x); vec2 n1 = vec2(-v1.y, v1.x); vec2 n2 = vec2(-v2.y, v2.x); + /* + The goal here is to make wide line segments join cleanly. For most + joints, it's enough to extend/contract the buffered lines into the + "normal miter" shape below. However, this can get really spiky if the + lines are almost anti-parallel, in which case we want the truncated + mitre. For the truncated miter, we must emit the additional triangle + x-a-b. + + normal miter truncated miter + ------------------* ----------a. + / | '. + x / x_ '. + ------* / ------. '--b + / / / / + / / / / + + Note that the way this is done below is fairly simple but results in + overdraw for semi transparent lines. Ideally would be nice to fix that + somehow. + */ + // determine miter lines by averaging the normals of the 2 segments vec2 miter_a = normalize(n0 + n1); // miter at start of current segment vec2 miter_b = normalize(n1 + n2); // miter at end of current segment @@ -103,45 +136,22 @@ void main(void) float ratio = length(p2 - p1) / (xend - xstart); - /* - over 90 - v0 - / - / - . ------> v1 - under 90 - v - \ - \ - . ------> v1 - */ - bool over_90_deg = dot( v0, v1 ) < -MITER_LIMIT; - /* - n1 - gap true : gap false - v0 : - . ------> : - */ - bool gap = dot( v0, n1 ) > 0; float uvy = thickness_aa/thickness; - if(over_90_deg){ + if(dot( v0, v1 ) < -MITER_LIMIT && isvalid[0]){ + /* + n1 + gap true : gap false + v0 : + . ------> : + */ + bool gap = dot( v0, n1 ) > 0; // close the gap if(gap){ - if (g_startend[0] == 0){ - emit_vertex(p0 - thickness_aa * n0, vec2(1, uvy), 0, ratio); - emit_vertex(p0 + thickness_aa * n0, vec2(1, -uvy), 0, ratio); - emit_vertex(p1 + thickness_aa * n1, vec2(1, uvy), 1, ratio); - } emit_vertex(p1 + thickness_aa * n0, vec2(1, -uvy), 1, ratio); emit_vertex(p1 + thickness_aa * n1, vec2(1, -uvy), 1, ratio); emit_vertex(p1, vec2(0, 0.0), 1, ratio); EndPrimitive(); }else{ - if (g_startend[0] == 0){ - emit_vertex(p0 + thickness_aa * n0, vec2(1, -uvy), 0, ratio); - emit_vertex(p0 - thickness_aa * n0, vec2(1, uvy), 0, ratio); - emit_vertex(p1 + length_a * miter_a, vec2(1, -uvy), 1, ratio); - } emit_vertex(p1 - thickness_aa * n0, vec2(1, uvy), 1, ratio); emit_vertex(p1, vec2(0, 0.0), 1, ratio); emit_vertex(p1 - thickness_aa * n1, vec2(1, uvy), 1, ratio); @@ -149,16 +159,11 @@ void main(void) } miter_a = n1; length_a = thickness_aa; - }else if(g_startend[0] == 0){ - emit_vertex(p0 + thickness_aa * n0, vec2(1, -uvy), 0, ratio); - emit_vertex(p0 - thickness_aa * n0, vec2(1, uvy), 0, ratio); } - vec2 nc = n2; if( dot( v1, v2 ) < -MITER_LIMIT ) { miter_b = n1; length_b = thickness_aa; - nc = -n2; } // generate the triangle strip @@ -168,10 +173,4 @@ void main(void) emit_vertex(p2 + length_b * miter_b, vec2( 0, -uvy ), 2, ratio); emit_vertex(p2 - length_b * miter_b, vec2( 0, uvy), 2, ratio); - - if(g_startend[3] == 1) //last primitive - { - emit_vertex(p3 + (thickness_aa) * nc, vec2(0, -uvy), 3, ratio); - emit_vertex(p3 - (thickness_aa) * nc, vec2(0, uvy), 3, ratio); - } } diff --git a/src/GLVisualize/assets/shader/lines.vert b/src/GLVisualize/assets/shader/lines.vert index 33ba605e690..54a12ec71c8 100644 --- a/src/GLVisualize/assets/shader/lines.vert +++ b/src/GLVisualize/assets/shader/lines.vert @@ -9,7 +9,7 @@ struct Nothing{ //Nothing type, to encode if some variable doesn't contain any d in float lastlen; -{{startend_type}} startend; +{{valid_vertex_type}} valid_vertex; {{color_type}} color; {{color_map_type}} color_map; @@ -28,7 +28,7 @@ uniform ivec2 dims; out uvec2 g_id; out vec4 g_color; out float g_lastlen; -out int g_startend; +out int g_valid_vertex; out uint g_line_connections; vec4 getindex(sampler2D tex, int index); @@ -37,8 +37,8 @@ vec4 getindex(sampler1D tex, int index); vec4 to_vec4(vec3 v){return vec4(v, 1);} vec4 to_vec4(vec2 v){return vec4(v, 0, 1);} -int get_startend(float se){return int(se);} -int get_startend(Nothing se){return 2;} +int get_valid_vertex(float se){return int(se);} +int get_valid_vertex(Nothing se){return 1;} void main() @@ -46,7 +46,7 @@ void main() g_lastlen = lastlen; int index = gl_VertexID; g_id = uvec2(objectid, index+1); - g_startend = get_startend(startend); + g_valid_vertex = get_valid_vertex(valid_vertex); g_color = _color(color, intensity, color_map, color_norm, index, dims.x*dims.y); g_line_connections = uint(index/dims.x); gl_Position = projection*view*model*to_vec4(vertex); diff --git a/src/GLVisualize/visualize/lines.jl b/src/GLVisualize/visualize/lines.jl index 992475356b3..4606524d956 100644 --- a/src/GLVisualize/visualize/lines.jl +++ b/src/GLVisualize/visualize/lines.jl @@ -56,18 +56,10 @@ function _default(position::MatTypes{<:Point}, s::style"lines", data::Dict) line_visualization(position, data) end function line_visualization(position::Union{VectorTypes{T}, MatTypes{T}}, data::Dict) where T<:Point - pv = to_value(position) p_vec = if isa(position, GPUArray) position else - const_lift(position) do p - pvv = vec(p) - if length(pvv) < 4 # geometryshader doesn't work with less then 4 - return [pvv..., fill(T(NaN), 4-length(pvv))...] - else - return pvv - end - end + const_lift(vec, position) end @gen_defaults! data begin @@ -84,16 +76,14 @@ function line_visualization(position::Union{VectorTypes{T}, MatTypes{T}}, data:: pattern = nothing fxaa = false preferred_camera = :orthographic_pixel - indices = const_lift(length, p_vec) => to_index_buffer + # Duplicate the vertex indices on the ends of the line, as our geometry + # shader in `layout(lines_adjacency)` mode requires each rendered + # segment to have neighbouring vertices. + indices = const_lift((p)->[1; 1:length(p); length(p)], p_vec) => to_index_buffer shader = GLVisualizeShader("fragment_output.frag", "util.vert", "lines.vert", "lines.geom", "lines.frag") gl_primitive = GL_LINE_STRIP_ADJACENCY - startend = const_lift(p_vec) do vec - l = length(vec) - map(1:l) do i - (i == 1 || isnan(vec[max(i-1, 1)])) && return Float32(0) # start - (i == l || isnan(vec[min(i+1, l)])) && return Float32(1) # end - Float32(2) # segment - end + valid_vertex = const_lift(p_vec) do pv + map(p-> Float32(all(isfinite, p)), pv) end => GLBuffer end if pattern != nothing From e041a3d902603e984562a27d72ad7d634dce2365 Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Wed, 20 Feb 2019 18:37:08 +1000 Subject: [PATCH 0083/1328] Refactor to simplify multiline geometry shader Here I've simplified the geometry shader for multilines significatnly so that it always renders only the single central segment. The end points are now accommodated by duplicating them with the index buffer. Fixes #26 and greatly mitigates #27. Ascii art FTW! --- src/GLVisualize/assets/shader/lines.geom | 103 +++++++++++------------ src/GLVisualize/assets/shader/lines.vert | 10 +-- src/GLVisualize/visualize/lines.jl | 24 ++---- 3 files changed, 63 insertions(+), 74 deletions(-) diff --git a/src/GLVisualize/assets/shader/lines.geom b/src/GLVisualize/assets/shader/lines.geom index 1fbd5f12673..1d02e259d90 100644 --- a/src/GLVisualize/assets/shader/lines.geom +++ b/src/GLVisualize/assets/shader/lines.geom @@ -5,13 +5,13 @@ {{GLSL_EXTENSIONS}} layout(lines_adjacency) in; -layout(triangle_strip, max_vertices = 12) out; +layout(triangle_strip, max_vertices = 7) out; in vec4 g_color[]; in float g_lastlen[]; in uvec2 g_id[]; in uint g_line_connections[]; -in int g_startend[]; +in int g_valid_vertex[]; //in float g_thickness[]; out vec4 f_color; @@ -58,10 +58,23 @@ const float infinity = 1.0 / 0.0; void main(void) { - if( - g_line_connections[1] != g_line_connections[2] - ){ - return; // if there is a break in the line, we don't emit anything + // We mark each of the four vertices as valid or not. Vertices can be + // marked invalid on input (eg, if they contain NaN). We also mark them + // invalid if they repeat in the index buffer. This allows us to render to + // the very ends of a polyline without clumsy buffering the position data on the + // CPU side by repeating the first and last points via the index buffer. It + // just requires a little care further down to avoid degenerate normals. + bool isvalid[4] = bool[]( + g_valid_vertex[0] == 1 && g_id[0].y != g_id[1].y, + g_valid_vertex[1] == 1, + g_valid_vertex[2] == 1, + g_valid_vertex[3] == 1 && g_id[2].y != g_id[3].y + ); + + if(g_line_connections[1] != g_line_connections[2] || !isvalid[1] || !isvalid[2]){ + // If one of the central vertices is invalid or there is a break in the + // line, we don't emit anything. + return; } // get the four vertices passed to the shader: vec2 p0 = screen_space(gl_in[0].gl_Position); // start of previous segment @@ -69,7 +82,6 @@ void main(void) vec2 p2 = screen_space(gl_in[2].gl_Position); // end of current segment, start of next segment vec2 p3 = screen_space(gl_in[3].gl_Position); // end of next segment - float thickness_aa = thickness+4; @@ -81,15 +93,36 @@ void main(void) //if( p2.y < -area.y || p2.y > area.y ) return; // determine the direction of each of the 3 segments (previous, current, next) - vec2 v0 = normalize(p1 - p0); - vec2 v1 = normalize(p2 - p1); - vec2 v2 = normalize(p3 - p2); + vec2 v1 = normalize(p2 - p1); + vec2 v0 = isvalid[0] ? normalize(p1 - p0) : v1; + vec2 v2 = isvalid[3] ? normalize(p3 - p2) : v1; // determine the normal of each of the 3 segments (previous, current, next) vec2 n0 = vec2(-v0.y, v0.x); vec2 n1 = vec2(-v1.y, v1.x); vec2 n2 = vec2(-v2.y, v2.x); + /* + The goal here is to make wide line segments join cleanly. For most + joints, it's enough to extend/contract the buffered lines into the + "normal miter" shape below. However, this can get really spiky if the + lines are almost anti-parallel, in which case we want the truncated + mitre. For the truncated miter, we must emit the additional triangle + x-a-b. + + normal miter truncated miter + ------------------* ----------a. + / | '. + x / x_ '. + ------* / ------. '--b + / / / / + / / / / + + Note that the way this is done below is fairly simple but results in + overdraw for semi transparent lines. Ideally would be nice to fix that + somehow. + */ + // determine miter lines by averaging the normals of the 2 segments vec2 miter_a = normalize(n0 + n1); // miter at start of current segment vec2 miter_b = normalize(n1 + n2); // miter at end of current segment @@ -103,45 +136,22 @@ void main(void) float ratio = length(p2 - p1) / (xend - xstart); - /* - over 90 - v0 - / - / - . ------> v1 - under 90 - v - \ - \ - . ------> v1 - */ - bool over_90_deg = dot( v0, v1 ) < -MITER_LIMIT; - /* - n1 - gap true : gap false - v0 : - . ------> : - */ - bool gap = dot( v0, n1 ) > 0; float uvy = thickness_aa/thickness; - if(over_90_deg){ + if(dot( v0, v1 ) < -MITER_LIMIT && isvalid[0]){ + /* + n1 + gap true : gap false + v0 : + . ------> : + */ + bool gap = dot( v0, n1 ) > 0; // close the gap if(gap){ - if (g_startend[0] == 0){ - emit_vertex(p0 - thickness_aa * n0, vec2(1, uvy), 0, ratio); - emit_vertex(p0 + thickness_aa * n0, vec2(1, -uvy), 0, ratio); - emit_vertex(p1 + thickness_aa * n1, vec2(1, uvy), 1, ratio); - } emit_vertex(p1 + thickness_aa * n0, vec2(1, -uvy), 1, ratio); emit_vertex(p1 + thickness_aa * n1, vec2(1, -uvy), 1, ratio); emit_vertex(p1, vec2(0, 0.0), 1, ratio); EndPrimitive(); }else{ - if (g_startend[0] == 0){ - emit_vertex(p0 + thickness_aa * n0, vec2(1, -uvy), 0, ratio); - emit_vertex(p0 - thickness_aa * n0, vec2(1, uvy), 0, ratio); - emit_vertex(p1 + length_a * miter_a, vec2(1, -uvy), 1, ratio); - } emit_vertex(p1 - thickness_aa * n0, vec2(1, uvy), 1, ratio); emit_vertex(p1, vec2(0, 0.0), 1, ratio); emit_vertex(p1 - thickness_aa * n1, vec2(1, uvy), 1, ratio); @@ -149,16 +159,11 @@ void main(void) } miter_a = n1; length_a = thickness_aa; - }else if(g_startend[0] == 0){ - emit_vertex(p0 + thickness_aa * n0, vec2(1, -uvy), 0, ratio); - emit_vertex(p0 - thickness_aa * n0, vec2(1, uvy), 0, ratio); } - vec2 nc = n2; if( dot( v1, v2 ) < -MITER_LIMIT ) { miter_b = n1; length_b = thickness_aa; - nc = -n2; } // generate the triangle strip @@ -168,10 +173,4 @@ void main(void) emit_vertex(p2 + length_b * miter_b, vec2( 0, -uvy ), 2, ratio); emit_vertex(p2 - length_b * miter_b, vec2( 0, uvy), 2, ratio); - - if(g_startend[3] == 1) //last primitive - { - emit_vertex(p3 + (thickness_aa) * nc, vec2(0, -uvy), 3, ratio); - emit_vertex(p3 - (thickness_aa) * nc, vec2(0, uvy), 3, ratio); - } } diff --git a/src/GLVisualize/assets/shader/lines.vert b/src/GLVisualize/assets/shader/lines.vert index 33ba605e690..54a12ec71c8 100644 --- a/src/GLVisualize/assets/shader/lines.vert +++ b/src/GLVisualize/assets/shader/lines.vert @@ -9,7 +9,7 @@ struct Nothing{ //Nothing type, to encode if some variable doesn't contain any d in float lastlen; -{{startend_type}} startend; +{{valid_vertex_type}} valid_vertex; {{color_type}} color; {{color_map_type}} color_map; @@ -28,7 +28,7 @@ uniform ivec2 dims; out uvec2 g_id; out vec4 g_color; out float g_lastlen; -out int g_startend; +out int g_valid_vertex; out uint g_line_connections; vec4 getindex(sampler2D tex, int index); @@ -37,8 +37,8 @@ vec4 getindex(sampler1D tex, int index); vec4 to_vec4(vec3 v){return vec4(v, 1);} vec4 to_vec4(vec2 v){return vec4(v, 0, 1);} -int get_startend(float se){return int(se);} -int get_startend(Nothing se){return 2;} +int get_valid_vertex(float se){return int(se);} +int get_valid_vertex(Nothing se){return 1;} void main() @@ -46,7 +46,7 @@ void main() g_lastlen = lastlen; int index = gl_VertexID; g_id = uvec2(objectid, index+1); - g_startend = get_startend(startend); + g_valid_vertex = get_valid_vertex(valid_vertex); g_color = _color(color, intensity, color_map, color_norm, index, dims.x*dims.y); g_line_connections = uint(index/dims.x); gl_Position = projection*view*model*to_vec4(vertex); diff --git a/src/GLVisualize/visualize/lines.jl b/src/GLVisualize/visualize/lines.jl index 992475356b3..4606524d956 100644 --- a/src/GLVisualize/visualize/lines.jl +++ b/src/GLVisualize/visualize/lines.jl @@ -56,18 +56,10 @@ function _default(position::MatTypes{<:Point}, s::style"lines", data::Dict) line_visualization(position, data) end function line_visualization(position::Union{VectorTypes{T}, MatTypes{T}}, data::Dict) where T<:Point - pv = to_value(position) p_vec = if isa(position, GPUArray) position else - const_lift(position) do p - pvv = vec(p) - if length(pvv) < 4 # geometryshader doesn't work with less then 4 - return [pvv..., fill(T(NaN), 4-length(pvv))...] - else - return pvv - end - end + const_lift(vec, position) end @gen_defaults! data begin @@ -84,16 +76,14 @@ function line_visualization(position::Union{VectorTypes{T}, MatTypes{T}}, data:: pattern = nothing fxaa = false preferred_camera = :orthographic_pixel - indices = const_lift(length, p_vec) => to_index_buffer + # Duplicate the vertex indices on the ends of the line, as our geometry + # shader in `layout(lines_adjacency)` mode requires each rendered + # segment to have neighbouring vertices. + indices = const_lift((p)->[1; 1:length(p); length(p)], p_vec) => to_index_buffer shader = GLVisualizeShader("fragment_output.frag", "util.vert", "lines.vert", "lines.geom", "lines.frag") gl_primitive = GL_LINE_STRIP_ADJACENCY - startend = const_lift(p_vec) do vec - l = length(vec) - map(1:l) do i - (i == 1 || isnan(vec[max(i-1, 1)])) && return Float32(0) # start - (i == l || isnan(vec[min(i+1, l)])) && return Float32(1) # end - Float32(2) # segment - end + valid_vertex = const_lift(p_vec) do pv + map(p-> Float32(all(isfinite, p)), pv) end => GLBuffer end if pattern != nothing From ac1e94e43503113f9ba0084d09cb3ac82c6b9b9f Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Thu, 21 Feb 2019 15:53:44 +1000 Subject: [PATCH 0084/1328] Try a triangulation technique which has zero overdraw The downside of this technique is that it generates poorly conditioned interpolation problems with interpolated variables changing quickly across the *width* of long skinny triangles, which can be a problem for really thick lines with sharp bends. On the other hand, the previous technique has excess overdraw. --- src/GLVisualize/assets/shader/lines.geom | 114 ++++++++++++----------- 1 file changed, 59 insertions(+), 55 deletions(-) diff --git a/src/GLVisualize/assets/shader/lines.geom b/src/GLVisualize/assets/shader/lines.geom index 1d02e259d90..5ca834da934 100644 --- a/src/GLVisualize/assets/shader/lines.geom +++ b/src/GLVisualize/assets/shader/lines.geom @@ -5,7 +5,7 @@ {{GLSL_EXTENSIONS}} layout(lines_adjacency) in; -layout(triangle_strip, max_vertices = 7) out; +layout(triangle_strip, max_vertices = 5) out; in vec4 g_color[]; in float g_lastlen[]; @@ -26,7 +26,7 @@ uniform float thickness; uniform float pattern_length; -#define MITER_LIMIT 0.75 +#define MITER_LIMIT -0.75 vec2 screen_space(vec4 vertex) { @@ -102,75 +102,79 @@ void main(void) vec2 n1 = vec2(-v1.y, v1.x); vec2 n2 = vec2(-v2.y, v2.x); - /* - The goal here is to make wide line segments join cleanly. For most - joints, it's enough to extend/contract the buffered lines into the - "normal miter" shape below. However, this can get really spiky if the - lines are almost anti-parallel, in which case we want the truncated - mitre. For the truncated miter, we must emit the additional triangle - x-a-b. - - normal miter truncated miter - ------------------* ----------a. - / | '. - x / x_ '. - ------* / ------. '--b - / / / / - / / / / - - Note that the way this is done below is fairly simple but results in - overdraw for semi transparent lines. Ideally would be nice to fix that - somehow. - */ + // The goal here is to make wide line segments join cleanly. For most + // joints, it's enough to extend/contract the buffered lines into the + // "normal miter" shape below by emitting the vertices ABCD to form two + // triangles. However, this can get really spiky if the lines are almost + // anti-parallel, in which case we want to adjust C and emit an extra + // vertex E to form a truncated miter with the triangle CDE. + // + // normal miter truncated miter + // --A---------------------C --A--------------C + // | current _-' / | .' '. + // | segment _.-*' / | .' * '. + // --B---------D' / --B---------D--------E + // / / / / + // / / / / + // next + // segment // determine miter lines by averaging the normals of the 2 segments vec2 miter_a = normalize(n0 + n1); // miter at start of current segment vec2 miter_b = normalize(n1 + n2); // miter at end of current segment - // determine the length of the miter by projecting it onto normal and then inverse it + // Determine the length of the miter by projecting it onto normal and then + // inverting. float length_a = thickness_aa / dot(miter_a, n1); float length_b = thickness_aa / dot(miter_b, n1); + // Clamp lengths of the miters to avoid problem with short lines and wide + // line widths where the length of the miter can get longer than the line + // itself. + float length0 = length(p1 - p0); + float length1 = length(p2 - p1); + float length2 = length(p3 - p2); + float maxlen_a = min(abs(length1/dot(miter_a, v1)), abs(length0/dot(miter_a, v0))); + float maxlen_b = min(abs(length1/dot(miter_b, v1)), abs(length2/dot(miter_b, v2))); + length_a = clamp(length_a, -maxlen_a, maxlen_a); + length_b = clamp(length_b, -maxlen_b, maxlen_b); float xstart = g_lastlen[1]; float xend = g_lastlen[2]; - - float ratio = length(p2 - p1) / (xend - xstart); - + float ratio = length1 / (xend - xstart); float uvy = thickness_aa/thickness; - if(dot( v0, v1 ) < -MITER_LIMIT && isvalid[0]){ - /* - n1 - gap true : gap false - v0 : - . ------> : - */ - bool gap = dot( v0, n1 ) > 0; - // close the gap - if(gap){ - emit_vertex(p1 + thickness_aa * n0, vec2(1, -uvy), 1, ratio); - emit_vertex(p1 + thickness_aa * n1, vec2(1, -uvy), 1, ratio); - emit_vertex(p1, vec2(0, 0.0), 1, ratio); - EndPrimitive(); - }else{ - emit_vertex(p1 - thickness_aa * n0, vec2(1, uvy), 1, ratio); - emit_vertex(p1, vec2(0, 0.0), 1, ratio); - emit_vertex(p1 - thickness_aa * n1, vec2(1, uvy), 1, ratio); - EndPrimitive(); - } - miter_a = n1; - length_a = thickness_aa; + + vec2 vA = length_a * miter_a; + vec2 vB = -length_a * miter_a; + if(dot( v0, v1 ) < MITER_LIMIT){ + if (dot(n1,v0) > 0) + vA = thickness_aa*n1; + else + vB = -thickness_aa*n1; } - if( dot( v1, v2 ) < -MITER_LIMIT ) { - miter_b = n1; - length_b = thickness_aa; + float Eside = 0; + vec2 pE; + vec2 vC = length_b * miter_b; + vec2 vD = -length_b * miter_b; + if(dot( v1, v2 ) < MITER_LIMIT) { + if (dot(n1,v2) < 0) { + vC = thickness_aa*n1; + Eside = 1.0; + } + else { + vD = -thickness_aa*n1; + Eside = -1.0; + } } // generate the triangle strip - emit_vertex(p1 + length_a * miter_a, vec2( 0, -uvy), 1, ratio); - emit_vertex(p1 - length_a * miter_a, vec2( 0, uvy), 1, ratio); + emit_vertex(p1 + vA, vec2( 0, -uvy), 1, ratio); + emit_vertex(p1 + vB, vec2( 0, uvy), 1, ratio); + + emit_vertex(p2 + vC, vec2( 0, -uvy ), 2, ratio); + emit_vertex(p2 + vD, vec2( 0, uvy), 2, ratio); - emit_vertex(p2 + length_b * miter_b, vec2( 0, -uvy ), 2, ratio); - emit_vertex(p2 - length_b * miter_b, vec2( 0, uvy), 2, ratio); + if(Eside != 0) + emit_vertex(p2 + (Eside*thickness_aa)*n2, vec2(1, -Eside*uvy), 2, ratio); } From 971614bb810959f94fc0b85fed0217f14b2eec46 Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Thu, 21 Feb 2019 16:33:40 +1000 Subject: [PATCH 0085/1328] Revert "Try a triangulation technique which has zero overdraw" Unfortunately this technique suffers from poor conditioning for almost antiparallel lines, and visible artifacts are present even for opaque lines in this case. This reverts commit ac1e94e43503113f9ba0084d09cb3ac82c6b9b9f. --- src/GLVisualize/assets/shader/lines.geom | 114 +++++++++++------------ 1 file changed, 55 insertions(+), 59 deletions(-) diff --git a/src/GLVisualize/assets/shader/lines.geom b/src/GLVisualize/assets/shader/lines.geom index 5ca834da934..1d02e259d90 100644 --- a/src/GLVisualize/assets/shader/lines.geom +++ b/src/GLVisualize/assets/shader/lines.geom @@ -5,7 +5,7 @@ {{GLSL_EXTENSIONS}} layout(lines_adjacency) in; -layout(triangle_strip, max_vertices = 5) out; +layout(triangle_strip, max_vertices = 7) out; in vec4 g_color[]; in float g_lastlen[]; @@ -26,7 +26,7 @@ uniform float thickness; uniform float pattern_length; -#define MITER_LIMIT -0.75 +#define MITER_LIMIT 0.75 vec2 screen_space(vec4 vertex) { @@ -102,79 +102,75 @@ void main(void) vec2 n1 = vec2(-v1.y, v1.x); vec2 n2 = vec2(-v2.y, v2.x); - // The goal here is to make wide line segments join cleanly. For most - // joints, it's enough to extend/contract the buffered lines into the - // "normal miter" shape below by emitting the vertices ABCD to form two - // triangles. However, this can get really spiky if the lines are almost - // anti-parallel, in which case we want to adjust C and emit an extra - // vertex E to form a truncated miter with the triangle CDE. - // - // normal miter truncated miter - // --A---------------------C --A--------------C - // | current _-' / | .' '. - // | segment _.-*' / | .' * '. - // --B---------D' / --B---------D--------E - // / / / / - // / / / / - // next - // segment + /* + The goal here is to make wide line segments join cleanly. For most + joints, it's enough to extend/contract the buffered lines into the + "normal miter" shape below. However, this can get really spiky if the + lines are almost anti-parallel, in which case we want the truncated + mitre. For the truncated miter, we must emit the additional triangle + x-a-b. + + normal miter truncated miter + ------------------* ----------a. + / | '. + x / x_ '. + ------* / ------. '--b + / / / / + / / / / + + Note that the way this is done below is fairly simple but results in + overdraw for semi transparent lines. Ideally would be nice to fix that + somehow. + */ // determine miter lines by averaging the normals of the 2 segments vec2 miter_a = normalize(n0 + n1); // miter at start of current segment vec2 miter_b = normalize(n1 + n2); // miter at end of current segment - // Determine the length of the miter by projecting it onto normal and then - // inverting. + // determine the length of the miter by projecting it onto normal and then inverse it float length_a = thickness_aa / dot(miter_a, n1); float length_b = thickness_aa / dot(miter_b, n1); - // Clamp lengths of the miters to avoid problem with short lines and wide - // line widths where the length of the miter can get longer than the line - // itself. - float length0 = length(p1 - p0); - float length1 = length(p2 - p1); - float length2 = length(p3 - p2); - float maxlen_a = min(abs(length1/dot(miter_a, v1)), abs(length0/dot(miter_a, v0))); - float maxlen_b = min(abs(length1/dot(miter_b, v1)), abs(length2/dot(miter_b, v2))); - length_a = clamp(length_a, -maxlen_a, maxlen_a); - length_b = clamp(length_b, -maxlen_b, maxlen_b); float xstart = g_lastlen[1]; float xend = g_lastlen[2]; - float ratio = length1 / (xend - xstart); - float uvy = thickness_aa/thickness; - vec2 vA = length_a * miter_a; - vec2 vB = -length_a * miter_a; - if(dot( v0, v1 ) < MITER_LIMIT){ - if (dot(n1,v0) > 0) - vA = thickness_aa*n1; - else - vB = -thickness_aa*n1; - } + float ratio = length(p2 - p1) / (xend - xstart); - float Eside = 0; - vec2 pE; - vec2 vC = length_b * miter_b; - vec2 vD = -length_b * miter_b; - if(dot( v1, v2 ) < MITER_LIMIT) { - if (dot(n1,v2) < 0) { - vC = thickness_aa*n1; - Eside = 1.0; - } - else { - vD = -thickness_aa*n1; - Eside = -1.0; + float uvy = thickness_aa/thickness; + if(dot( v0, v1 ) < -MITER_LIMIT && isvalid[0]){ + /* + n1 + gap true : gap false + v0 : + . ------> : + */ + bool gap = dot( v0, n1 ) > 0; + // close the gap + if(gap){ + emit_vertex(p1 + thickness_aa * n0, vec2(1, -uvy), 1, ratio); + emit_vertex(p1 + thickness_aa * n1, vec2(1, -uvy), 1, ratio); + emit_vertex(p1, vec2(0, 0.0), 1, ratio); + EndPrimitive(); + }else{ + emit_vertex(p1 - thickness_aa * n0, vec2(1, uvy), 1, ratio); + emit_vertex(p1, vec2(0, 0.0), 1, ratio); + emit_vertex(p1 - thickness_aa * n1, vec2(1, uvy), 1, ratio); + EndPrimitive(); } + miter_a = n1; + length_a = thickness_aa; } - // generate the triangle strip + if( dot( v1, v2 ) < -MITER_LIMIT ) { + miter_b = n1; + length_b = thickness_aa; + } - emit_vertex(p1 + vA, vec2( 0, -uvy), 1, ratio); - emit_vertex(p1 + vB, vec2( 0, uvy), 1, ratio); + // generate the triangle strip - emit_vertex(p2 + vC, vec2( 0, -uvy ), 2, ratio); - emit_vertex(p2 + vD, vec2( 0, uvy), 2, ratio); + emit_vertex(p1 + length_a * miter_a, vec2( 0, -uvy), 1, ratio); + emit_vertex(p1 - length_a * miter_a, vec2( 0, uvy), 1, ratio); - if(Eside != 0) - emit_vertex(p2 + (Eside*thickness_aa)*n2, vec2(1, -Eside*uvy), 2, ratio); + emit_vertex(p2 + length_b * miter_b, vec2( 0, -uvy ), 2, ratio); + emit_vertex(p2 - length_b * miter_b, vec2( 0, uvy), 2, ratio); } From 4df52e7a110ac8af3f12766797fd00e0194b3d0b Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Thu, 21 Feb 2019 16:46:14 +1000 Subject: [PATCH 0086/1328] Cleanup to line geometry shader * Reduce miter limit to mitigate problems with the miter becoming longer than the line itself. * Remove some unused and unnecessary code --- src/GLVisualize/assets/shader/lines.geom | 55 +++++++++--------------- 1 file changed, 21 insertions(+), 34 deletions(-) diff --git a/src/GLVisualize/assets/shader/lines.geom b/src/GLVisualize/assets/shader/lines.geom index 1d02e259d90..2f9812edda1 100644 --- a/src/GLVisualize/assets/shader/lines.geom +++ b/src/GLVisualize/assets/shader/lines.geom @@ -26,7 +26,7 @@ uniform float thickness; uniform float pattern_length; -#define MITER_LIMIT 0.75 +#define MITER_LIMIT -0.4 vec2 screen_space(vec4 vertex) { @@ -43,16 +43,6 @@ void emit_vertex(vec2 position, vec2 uv, int index, float ratio) EmitVertex(); } -vec2 compute_miter(vec2 normal_a, vec2 normal_b) -{ - vec2 miter = normalize(normal_a + normal_b); - if(miter.x < 0.000001 && miter.y < 0.000001) - { - return vec2(-normal_a.y, normal_a.x); - } - return miter; -} - uniform int max_primtives; const float infinity = 1.0 / 0.0; @@ -102,26 +92,24 @@ void main(void) vec2 n1 = vec2(-v1.y, v1.x); vec2 n2 = vec2(-v2.y, v2.x); - /* - The goal here is to make wide line segments join cleanly. For most - joints, it's enough to extend/contract the buffered lines into the - "normal miter" shape below. However, this can get really spiky if the - lines are almost anti-parallel, in which case we want the truncated - mitre. For the truncated miter, we must emit the additional triangle - x-a-b. - - normal miter truncated miter - ------------------* ----------a. - / | '. - x / x_ '. - ------* / ------. '--b - / / / / - / / / / - - Note that the way this is done below is fairly simple but results in - overdraw for semi transparent lines. Ideally would be nice to fix that - somehow. - */ + // The goal here is to make wide line segments join cleanly. For most + // joints, it's enough to extend/contract the buffered lines into the + // "normal miter" shape below. However, this can get really spiky if the + // lines are almost anti-parallel, in which case we want the truncated + // mitre. For the truncated miter, we must emit the additional triangle + // x-a-b. + // + // normal miter truncated miter + // ------------------* ----------a. + // / | '. + // x / x_ '. + // ------* / ------. '--b + // / / / / + // / / / / + // + // Note that the way this is done below is fairly simple but results in + // overdraw for semi transparent lines. Ideally would be nice to fix that + // somehow. // determine miter lines by averaging the normals of the 2 segments vec2 miter_a = normalize(n0 + n1); // miter at start of current segment @@ -133,11 +121,10 @@ void main(void) float xstart = g_lastlen[1]; float xend = g_lastlen[2]; - float ratio = length(p2 - p1) / (xend - xstart); float uvy = thickness_aa/thickness; - if(dot( v0, v1 ) < -MITER_LIMIT && isvalid[0]){ + if( dot( v0, v1 ) < MITER_LIMIT ){ /* n1 gap true : gap false @@ -161,7 +148,7 @@ void main(void) length_a = thickness_aa; } - if( dot( v1, v2 ) < -MITER_LIMIT ) { + if( dot( v1, v2 ) < MITER_LIMIT ) { miter_b = n1; length_b = thickness_aa; } From 897aaaaa099707585fe5a8ac2aa97ad9d0372b30 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Sun, 24 Feb 2019 15:52:30 +0100 Subject: [PATCH 0087/1328] only require imagemagick --- REQUIRE | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/REQUIRE b/REQUIRE index 275d6b4d443..67d04b28b9d 100644 --- a/REQUIRE +++ b/REQUIRE @@ -13,9 +13,7 @@ ModernGL GLFW 2.3.0 FreeType FreeTypeAbstraction 0.3.0 #for findfont -@windows ImageMagick -@linux ImageMagick -@osx QuartzImageIO +ImageMagick AbstractPlotting 0.9.5 Primes PlotUtils From 6ea449dd1bd7878831e7086a7f20afd9e16f5b30 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Sun, 24 Feb 2019 17:21:28 +0100 Subject: [PATCH 0088/1328] show for screen, fix JuliaPlots/Makie.jl#290 --- src/screen.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/screen.jl b/src/screen.jl index c486e08bedc..0a8f371e384 100644 --- a/src/screen.jl +++ b/src/screen.jl @@ -44,7 +44,7 @@ GeometryTypes.widths(x::Screen) = size(x.framebuffer.color) Base.wait(x::Screen) = isassigned(x.rendertask) && wait(x.rendertask[]) Base.wait(scene::Scene) = wait(global_gl_screen()) # TODO per scene screen - +Base.show(io::IO, screen::Screen) = print(io, "GLMakie.Screen(...)") function insertplots!(screen::GLScreen, scene::Scene) for elem in scene.plots From e99b522bc453ce237ae202c78754f057705533be Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 25 Feb 2019 11:03:48 +0100 Subject: [PATCH 0089/1328] add discard for better transparency --- src/GLVisualize/assets/shader/fragment_output.frag | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/GLVisualize/assets/shader/fragment_output.frag b/src/GLVisualize/assets/shader/fragment_output.frag index 967cb0c4c00..214477a83e0 100644 --- a/src/GLVisualize/assets/shader/fragment_output.frag +++ b/src/GLVisualize/assets/shader/fragment_output.frag @@ -4,6 +4,8 @@ layout(location=0) out vec4 fragment_color; layout(location=1) out uvec2 fragment_groupid; void write2framebuffer(vec4 color, uvec2 id){ + if(color.a <= 0.0) + discard; fragment_color = color; fragment_groupid = id; } From 2739cab9a48c8ec6e9b84de5436be96460c78fb1 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 25 Feb 2019 11:04:02 +0100 Subject: [PATCH 0090/1328] dont allow negative scales --- src/GLVisualize/assets/shader/sprites.vert | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GLVisualize/assets/shader/sprites.vert b/src/GLVisualize/assets/shader/sprites.vert index b5d89d5dc11..01ac199ed6f 100644 --- a/src/GLVisualize/assets/shader/sprites.vert +++ b/src/GLVisualize/assets/shader/sprites.vert @@ -117,7 +117,7 @@ void main(){ {{position_calc}} g_position = pos; g_offset_width.xy = offset.xy; - g_offset_width.zw = _scale(scale, scale_x, scale_y, scale_z, g_primitive_index).xy; + g_offset_width.zw = abs(_scale(scale, scale_x, scale_y, scale_z, g_primitive_index).xy); g_color = _color(color, intensity, color_map, color_norm, g_primitive_index, len); g_rotation = _rotation(rotation); g_uv_texture_bbox = uv_offset_width; From fdd5eb5c1e13e0bab0f584e9794d1242d06dd2bb Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 25 Feb 2019 11:04:15 +0100 Subject: [PATCH 0091/1328] fix for better mime support --- src/gl_backend.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gl_backend.jl b/src/gl_backend.jl index 55dafe2f5da..4c900631ad1 100644 --- a/src/gl_backend.jl +++ b/src/gl_backend.jl @@ -73,3 +73,8 @@ function AbstractPlotting.backend_show(::GLBackend, io::IO, m::MIME"image/png", img = scene2image(scene) FileIO.save(FileIO.Stream(FileIO.format"PNG", io), img) end + +function AbstractPlotting.backend_show(::GLBackend, io::IO, m::MIME"image/jpeg", scene::Scene) + img = scene2image(scene) + FileIO.save(FileIO.Stream(FileIO.format"JPEG", io), img) +end From 9e86dde3965cc293298a4b792c6c966a6de4745c Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 25 Feb 2019 11:04:36 +0100 Subject: [PATCH 0092/1328] improved tests --- test/REQUIRE | 1 - test/runtests.jl | 14 +++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/test/REQUIRE b/test/REQUIRE index 4b28ebb1c24..c424347cbe8 100644 --- a/test/REQUIRE +++ b/test/REQUIRE @@ -6,7 +6,6 @@ ModernGL MeshIO ImageMagick ImageTransformations -GDAL FileIO ImageFiltering DataFrames diff --git a/test/runtests.jl b/test/runtests.jl index 18acd19c256..9d7095698bd 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,13 +1,17 @@ -using MakieGallery, AbstractPlotting, GLMakie +using MakieGallery, AbstractPlotting, GLMakie, Test push!(MakieGallery.plotting_backends, "GLMakie") database = MakieGallery.load_database() tested_diff_path = joinpath(@__DIR__, "tested_different") test_record_path = joinpath(@__DIR__, "test_recordings") -rm(tested_diff_path, force = true, recursive = true) -mkpath(tested_diff_path) -rm(test_record_path, force = true, recursive = true) -mkpath(test_record_path) +for path in (tested_diff_path, test_record_path) + rm(path, force = true, recursive = true) + mkpath(path) +end +recordings = MakieGallery.record_examples(test_record_path) +@test length(recordings) == length(database) + +MakieGallery.run_comparison(test_record_path, tested_diff_path) MakieGallery.record_examples(test_record_path) MakieGallery.run_comparison(test_record_path, tested_diff_path) From f42ed3c4b82dffe165af557953ae34a46c6306fd Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 25 Feb 2019 11:11:46 +0100 Subject: [PATCH 0093/1328] revert abs (barplot) --- src/GLVisualize/assets/shader/sprites.vert | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GLVisualize/assets/shader/sprites.vert b/src/GLVisualize/assets/shader/sprites.vert index 01ac199ed6f..b5d89d5dc11 100644 --- a/src/GLVisualize/assets/shader/sprites.vert +++ b/src/GLVisualize/assets/shader/sprites.vert @@ -117,7 +117,7 @@ void main(){ {{position_calc}} g_position = pos; g_offset_width.xy = offset.xy; - g_offset_width.zw = abs(_scale(scale, scale_x, scale_y, scale_z, g_primitive_index).xy); + g_offset_width.zw = _scale(scale, scale_x, scale_y, scale_z, g_primitive_index).xy; g_color = _color(color, intensity, color_map, color_norm, g_primitive_index, len); g_rotation = _rotation(rotation); g_uv_texture_bbox = uv_offset_width; From d454f29fb3e69f76a13170265c5bace43f52c406 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 25 Feb 2019 11:21:26 +0100 Subject: [PATCH 0094/1328] add backend tests --- test/glmakie_tests.jl | 24 ++++++++++++++++++++++++ test/runtests.jl | 7 +++++++ 2 files changed, 31 insertions(+) create mode 100644 test/glmakie_tests.jl diff --git a/test/glmakie_tests.jl b/test/glmakie_tests.jl new file mode 100644 index 00000000000..6d5d9499258 --- /dev/null +++ b/test/glmakie_tests.jl @@ -0,0 +1,24 @@ +# A test case for wide lines and mitering at joints + +@block Contributors ["GLMakie backend tests"] begin + @cell "Miter Joints for line rendering" [lines] begin + scene = Scene() + + r = 4 + sep = 4*r + scatter!(scene, (sep+2*r)*[-1,-1,1,1], (sep+2*r)*[-1,1,-1,1]) + + for i=-1:1 + for j=-1:1 + angle = pi/2 + pi/4*i + x = r*[-cos(angle/2),0,-cos(angle/2)] + y = r*[-sin(angle/2),0,sin(angle/2)] + + linewidth = 40 * 2.0^j + lines!(scene, x .+ sep*i, y .+ sep*j, color=RGBAf0(0,0,0,0.5), linewidth=linewidth) + lines!(scene, x .+ sep*i, y .+ sep*j, color=:red) + end + end + scene + end +end diff --git a/test/runtests.jl b/test/runtests.jl index 9d7095698bd..f1f66141da0 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -15,3 +15,10 @@ MakieGallery.run_comparison(test_record_path, tested_diff_path) MakieGallery.record_examples(test_record_path) MakieGallery.run_comparison(test_record_path, tested_diff_path) + + +empty!(database) # remove other examples +include("glmakie_tests.jl") # include GLMakie specific tests +# THese examples download additional data - don't want to deal with that! +examples = MakieGallery.record_examples(test_record_path) +MakieGallery.run_comparison(test_record_path, tested_diff_path, maxdiff = 0.0) From 3b9a954ffca6a79ce9554ecab63d33e8a4a27000 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 25 Feb 2019 20:10:15 +0100 Subject: [PATCH 0095/1328] import block + cell --- test/runtests.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/test/runtests.jl b/test/runtests.jl index f1f66141da0..4786a90f8ec 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,4 +1,5 @@ using MakieGallery, AbstractPlotting, GLMakie, Test +using MakieGallery: @block, @cell push!(MakieGallery.plotting_backends, "GLMakie") database = MakieGallery.load_database() From cd604bdbb483ed23662bb8b6b70f6c1dc8643bf2 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Tue, 26 Feb 2019 18:15:15 +0100 Subject: [PATCH 0096/1328] update tests --- test/runtests.jl | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 4786a90f8ec..6df4c20432f 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -12,12 +12,6 @@ end recordings = MakieGallery.record_examples(test_record_path) @test length(recordings) == length(database) -MakieGallery.run_comparison(test_record_path, tested_diff_path) - -MakieGallery.record_examples(test_record_path) -MakieGallery.run_comparison(test_record_path, tested_diff_path) - - empty!(database) # remove other examples include("glmakie_tests.jl") # include GLMakie specific tests # THese examples download additional data - don't want to deal with that! From 40f07a93ccd4a27a90a4bdbb47a80e7938b3777f Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Sat, 2 Mar 2019 12:19:09 +0100 Subject: [PATCH 0097/1328] fix GLNormalVertexcolorMesh --- src/drawing_primitives.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/drawing_primitives.jl b/src/drawing_primitives.jl index 7f25851c7dc..2f7878fa54d 100644 --- a/src/drawing_primitives.jl +++ b/src/drawing_primitives.jl @@ -114,7 +114,7 @@ AbstractPlotting.to_spritemarker(x::FastPixel) = x function draw_atomic(screen::GLScreen, scene::Scene, x::Union{Scatter, MeshScatter}) robj = cached_robj!(screen, scene, x) do gl_attributes # signals not supported for shading yet - gl_attributes[:shading] = AbstractPlotting.to_value(get(gl_attributes, :shading, true)) + gl_attributes[:shading] = AbstractPlotting.to_value(get(gl_attributes, :shading, true)) marker = lift_convert(:marker, pop!(gl_attributes, :marker), x) if isa(x, Scatter) gl_attributes[:billboard] = map(rot-> isa(rot, Billboard), x.attributes[:rotations]) @@ -279,7 +279,7 @@ function draw_atomic(screen::GLScreen, scene::Scene, x::Mesh) crange = get(gl_attributes, :color_norm, Node(nothing)); delete!(gl_attributes, :color_norm) mesh = lift(x[1], color, cmap, crange) do m, c, cmap, crange c = convert_mesh_color(c, cmap, crange) - if isa(m, GLNormalColorMesh) || isa(m, GLNormalAttributeMesh) + if isa(m, GLNormalColorMesh) || isa(m, GLNormalAttributeMesh) || isa(m, GLNormalVertexcolorMesh) m elseif isa(c, Colorant) get!(gl_attributes, :color, Node(c))[] = c From 7103938c4b7b35d9cb54d3132f9f45401847caff Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Thu, 28 Feb 2019 15:06:29 +1000 Subject: [PATCH 0098/1328] Allow negative sprite widths --- src/GLVisualize/assets/shader/distance_shape.frag | 1 + src/GLVisualize/assets/shader/sprites.geom | 13 ++++++------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/GLVisualize/assets/shader/distance_shape.frag b/src/GLVisualize/assets/shader/distance_shape.frag index b2ce7804528..193288a27ee 100644 --- a/src/GLVisualize/assets/shader/distance_shape.frag +++ b/src/GLVisualize/assets/shader/distance_shape.frag @@ -152,6 +152,7 @@ void main(){ stroke(f_stroke_color, signed_distance, -stroke_width, final_color); glow(f_glow_color, signed_distance, aastep(-stroke_width, signed_distance), final_color); // TODO: In 3D, we should arguably discard fragments outside the sprite + // But note that this may interfere with object picking. //if (final_color == f_bg_color) // discard; write2framebuffer(final_color, f_id); diff --git a/src/GLVisualize/assets/shader/sprites.geom b/src/GLVisualize/assets/shader/sprites.geom index 8c6c6ce7d1c..89e3b7fc6c4 100644 --- a/src/GLVisualize/assets/shader/sprites.geom +++ b/src/GLVisualize/assets/shader/sprites.geom @@ -101,11 +101,10 @@ void main(void) // | \ | // |___\| // v1* * v2 - vec4 o_w = g_offset_width[0]; - // Centred bounding box of billboard - vec2 bbox_radius = 0.5*o_w.zw; - vec2 sprite_bbox_centre = o_w.xy + bbox_radius; + vec4 o_w = g_offset_width[0]; + vec2 bbox_signed_radius = 0.5*o_w.zw; // note; components may be negative. + vec2 sprite_bbox_centre = o_w.xy + bbox_signed_radius; mat4 pview = projection * view; // Compute transform for the offset vectors from the central point @@ -148,7 +147,7 @@ void main(void) // any calculation based on them will not be a distance function.) // * For sampled distance fields, we need to consistently choose the *x* // for the scaling in get_distancefield_scale(). - float sprite_from_u_scale = o_w.z; + float sprite_from_u_scale = abs(o_w.z); f_viewport_from_u_scale = viewport_from_sprite_scale * sprite_from_u_scale; f_distancefield_scale = get_distancefield_scale(distancefield); @@ -158,10 +157,10 @@ void main(void) (ANTIALIAS_RADIUS + max(glow_width, 0) + max(stroke_width, 0)); // Compute xy bounding box of billboard (in model space units) after // buffering and associated bounding box of uv coordinates. - vec2 bbox_radius_buf = bbox_radius + bbox_buf; + vec2 bbox_radius_buf = bbox_signed_radius + sign(bbox_signed_radius)*bbox_buf; vec4 bbox = vec4(-bbox_radius_buf, bbox_radius_buf); // uv bounding box is the buffered version of the domain [0,1]x[0,1] - vec2 uv_radius = 0.5 * bbox_radius_buf / bbox_radius; + vec2 uv_radius = 0.5 * bbox_radius_buf / bbox_signed_radius; vec2 uv_center = vec2(0.5); vec4 uv_bbox = vec4(uv_center-uv_radius, uv_center+uv_radius); //minx, miny, maxx, maxy From 573a5b1acde7328ed709eae49f61fa36ad6c5f70 Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Tue, 5 Mar 2019 21:28:18 +1000 Subject: [PATCH 0099/1328] Workaround barplot antialiasing issues with rectangle sprites Disable antialiasing completely for RECTANGLE sprites, reverting to the old behavior for now. This is a hack to make `barplot`s work again until we figure out how to make antialising of transformed signed distance functions work in general. --- src/GLVisualize/assets/shader/distance_shape.frag | 2 +- src/GLVisualize/assets/shader/sprites.geom | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/GLVisualize/assets/shader/distance_shape.frag b/src/GLVisualize/assets/shader/distance_shape.frag index 193288a27ee..98716343c85 100644 --- a/src/GLVisualize/assets/shader/distance_shape.frag +++ b/src/GLVisualize/assets/shader/distance_shape.frag @@ -137,7 +137,7 @@ void main(){ else if(shape == ROUNDED_RECTANGLE) signed_distance = rounded_rectangle(f_uv, vec2(0.2), vec2(0.8)); else if(shape == RECTANGLE) - signed_distance = rectangle(f_uv); + signed_distance = 1.0; // rectangle(f_uv); else if(shape == TRIANGLE) signed_distance = triangle(f_uv); diff --git a/src/GLVisualize/assets/shader/sprites.geom b/src/GLVisualize/assets/shader/sprites.geom index 89e3b7fc6c4..98f555ba5b3 100644 --- a/src/GLVisualize/assets/shader/sprites.geom +++ b/src/GLVisualize/assets/shader/sprites.geom @@ -33,6 +33,7 @@ uniform bool scale_primitive; uniform bool billboard; uniform float stroke_width; uniform float glow_width; +uniform int shape; // for RECTANGLE hack below uniform vec2 resolution; in int g_primitive_index[]; @@ -154,7 +155,11 @@ void main(void) // Compute required amount of buffering float sprite_from_viewport_scale = 1.0 / viewport_from_sprite_scale; float bbox_buf = sprite_from_viewport_scale * - (ANTIALIAS_RADIUS + max(glow_width, 0) + max(stroke_width, 0)); + (// Hack!! antialiasing is disabled for RECTANGLE==1 for now + // because it's used for boxplots where the sprites are + // long and skinny (violating assumption 1 above) + (shape == 1 ? 0.0 : ANTIALIAS_RADIUS) + + max(glow_width, 0) + max(stroke_width, 0)); // Compute xy bounding box of billboard (in model space units) after // buffering and associated bounding box of uv coordinates. vec2 bbox_radius_buf = bbox_signed_radius + sign(bbox_signed_radius)*bbox_buf; From 95995bd121125d197f7fdefe7273f229343e6ece Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Tue, 5 Mar 2019 18:44:07 +0100 Subject: [PATCH 0100/1328] clean up runtests --- test/runtests.jl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/runtests.jl b/test/runtests.jl index 6df4c20432f..46e397672aa 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -11,9 +11,17 @@ for path in (tested_diff_path, test_record_path) end recordings = MakieGallery.record_examples(test_record_path) @test length(recordings) == length(database) +MakieGallery.run_comparison(test_record_path, tested_diff_path) empty!(database) # remove other examples include("glmakie_tests.jl") # include GLMakie specific tests # THese examples download additional data - don't want to deal with that! +for path in (tested_diff_path, test_record_path) + rm(path, force = true, recursive = true) + mkpath(path) +end examples = MakieGallery.record_examples(test_record_path) MakieGallery.run_comparison(test_record_path, tested_diff_path, maxdiff = 0.0) +# MakieGallery.generate_preview(test_record_path) +# repo = joinpath(homedir(), "ReferenceImages", "gallery") +# cp(test_record_path, repo, force = true) From 6c591eca95b2d063f480bb0c3639604460f9ee41 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 6 Mar 2019 16:44:28 +0100 Subject: [PATCH 0101/1328] update versions --- Project.toml | 2 +- REQUIRE | 2 +- test/REQUIRE | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Project.toml b/Project.toml index 562604026b4..b6a9989463f 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "GLMakie" uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" -version = "0.0.5" +version = "0.0.6" [deps] AbstractPlotting = "537997a7-5e4e-5d89-9595-2241ea00577e" diff --git a/REQUIRE b/REQUIRE index 67d04b28b9d..8f699880159 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,5 +1,6 @@ julia 0.7 +AbstractPlotting 0.9.6 StaticArrays 0.6.6 GeometryTypes 0.7.2 Observables @@ -14,7 +15,6 @@ GLFW 2.3.0 FreeType FreeTypeAbstraction 0.3.0 #for findfont ImageMagick -AbstractPlotting 0.9.5 Primes PlotUtils IntervalSets diff --git a/test/REQUIRE b/test/REQUIRE index c424347cbe8..ba8d1c4a2df 100644 --- a/test/REQUIRE +++ b/test/REQUIRE @@ -11,6 +11,6 @@ ImageFiltering DataFrames RDatasets StatsMakie -MakieGallery 0.0.4 +MakieGallery 0.0.5 GLFW ZipFile From b32901ee4b6fdc16773275d93a108e0e4bd52575 Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 6 Mar 2019 17:05:05 +0100 Subject: [PATCH 0102/1328] Update REQUIRE --- test/REQUIRE | 1 + 1 file changed, 1 insertion(+) diff --git a/test/REQUIRE b/test/REQUIRE index ba8d1c4a2df..9508444ee85 100644 --- a/test/REQUIRE +++ b/test/REQUIRE @@ -14,3 +14,4 @@ StatsMakie MakieGallery 0.0.5 GLFW ZipFile +ColorSchemes From 83c5fbff75c0717ee4e3051f361e869b92f13161 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 6 Mar 2019 17:32:35 +0100 Subject: [PATCH 0103/1328] workaround for MakieGallery oversight --- test/REQUIRE | 1 + 1 file changed, 1 insertion(+) diff --git a/test/REQUIRE b/test/REQUIRE index ba8d1c4a2df..40252319fa3 100644 --- a/test/REQUIRE +++ b/test/REQUIRE @@ -14,3 +14,4 @@ StatsMakie MakieGallery 0.0.5 GLFW ZipFile +Makie # not really needed - workaround for MakieGallery bug From f979823b7c0219922f778085a7ac28609910e56c Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 6 Mar 2019 18:31:30 +0100 Subject: [PATCH 0104/1328] fix faulty workaround --- test/REQUIRE | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/REQUIRE b/test/REQUIRE index d1db16a6073..546d0ede26b 100644 --- a/test/REQUIRE +++ b/test/REQUIRE @@ -11,8 +11,7 @@ ImageFiltering DataFrames RDatasets StatsMakie -MakieGallery 0.0.5 +MakieGallery 0.0.6 GLFW ZipFile -Makie # not really needed - workaround for MakieGallery bug ColorSchemes From 21a9813e03b8270742c98f73316cd907bca8cae3 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 6 Mar 2019 18:58:56 +0100 Subject: [PATCH 0105/1328] add GDAL --- test/REQUIRE | 1 + 1 file changed, 1 insertion(+) diff --git a/test/REQUIRE b/test/REQUIRE index 546d0ede26b..17cb47b0c15 100644 --- a/test/REQUIRE +++ b/test/REQUIRE @@ -15,3 +15,4 @@ MakieGallery 0.0.6 GLFW ZipFile ColorSchemes +GDAL From 0061ce2c20ca27b179dda53c1ad30f8cce2ff0cf Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 6 Mar 2019 20:53:55 +0100 Subject: [PATCH 0106/1328] account for small platform differences --- test/runtests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index 46e397672aa..056834632d0 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -21,7 +21,7 @@ for path in (tested_diff_path, test_record_path) mkpath(path) end examples = MakieGallery.record_examples(test_record_path) -MakieGallery.run_comparison(test_record_path, tested_diff_path, maxdiff = 0.0) +MakieGallery.run_comparison(test_record_path, tested_diff_path, maxdiff = 0.00001) # MakieGallery.generate_preview(test_record_path) # repo = joinpath(homedir(), "ReferenceImages", "gallery") # cp(test_record_path, repo, force = true) From 48e7f6555b1693c4ddb771279d6f0517725ea762 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 6 Mar 2019 20:54:04 +0100 Subject: [PATCH 0107/1328] ignore new test artifacts --- test/.gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/.gitignore b/test/.gitignore index 2a639590407..43774ed6f60 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -1,2 +1,7 @@ tested_different test_recordings +*.png +*.jpg +*.zip +tmax +prec From fe55a4a94c7be6af0a0f1b24168424501465529a Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 6 Mar 2019 21:30:46 +0100 Subject: [PATCH 0108/1328] Update Project.toml --- Project.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index b6a9989463f..fc50a7c73da 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "GLMakie" uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" -version = "0.0.6" +version = "0.0.5" [deps] AbstractPlotting = "537997a7-5e4e-5d89-9595-2241ea00577e" @@ -32,7 +32,7 @@ Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" [compat] -AbstractPlotting = ">=0.9.1" +AbstractPlotting = ">=0.9.6" FreeTypeAbstraction = ">=0.3.0" GLFW = ">=2.3.0" GeometryTypes = ">=0.7.2" From b1c6c8e966edaa73cdce1359710bcc1db23b4a5c Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Thu, 14 Mar 2019 17:32:19 +0100 Subject: [PATCH 0109/1328] fix all display problems --- src/GLVisualize/assets/loading.bin | Bin 0 -> 36864 bytes src/drawing_primitives.jl | 10 ++- src/gl_backend.jl | 9 +-- src/screen.jl | 98 ++++++++++++++++++++++++++--- 4 files changed, 103 insertions(+), 14 deletions(-) create mode 100644 src/GLVisualize/assets/loading.bin diff --git a/src/GLVisualize/assets/loading.bin b/src/GLVisualize/assets/loading.bin new file mode 100644 index 0000000000000000000000000000000000000000..6198c533be574e2204b12cd9601a5791f9255ce4 GIT binary patch literal 36864 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 literal 0 HcmV?d00001 diff --git a/src/drawing_primitives.jl b/src/drawing_primitives.jl index 2f7878fa54d..eeced5893e7 100644 --- a/src/drawing_primitives.jl +++ b/src/drawing_primitives.jl @@ -30,6 +30,8 @@ end make_context_current(screen::Screen) = GLFW.MakeContextCurrent(to_native(screen)) function cached_robj!(robj_func, screen, scene, x::AbstractPlot) + # poll inside functions to make wait on compile less prominent + GLFW.PollEvents() robj = get!(screen.cache, objectid(x)) do gl_attributes = map(filter(((k, v),)-> k != :transformation, x.attributes)) do key_value key, value = key_value @@ -101,10 +103,16 @@ function handle_intensities!(attributes) end function Base.insert!(screen::GLScreen, scene::Scene, x::Combined) + # poll inside functions to make wait on compile less prominent + GLFW.PollEvents() if isempty(x.plots) # if no plots inserted, this truely is an atomic draw_atomic(screen, scene, x) else - foreach(x-> insert!(screen, scene, x), x.plots) + foreach(x.plots) do x + # poll inside functions to make wait on compile less prominent + GLFW.PollEvents() + insert!(screen, scene, x) + end end end diff --git a/src/gl_backend.jl b/src/gl_backend.jl index 4c900631ad1..7d715965623 100644 --- a/src/gl_backend.jl +++ b/src/gl_backend.jl @@ -53,8 +53,9 @@ include("events.jl") include("drawing_primitives.jl") function AbstractPlotting.backend_display(x::GLBackend, scene::Scene) - screen = global_gl_screen() - display(screen, scene) + screen = global_gl_screen(size(scene), AbstractPlotting.use_display[]) + display_loading_image(screen) + AbstractPlotting.backend_display(screen, scene) return screen end @@ -64,8 +65,8 @@ end Buffers the `scene` in an image buffer. """ function scene2image(scene::Scene) - screen = global_gl_screen() - display(screen, scene) + screen = global_gl_screen(size(scene), false) + AbstractPlotting.backend_display(screen, scene) AbstractPlotting.colorbuffer(screen) end diff --git a/src/screen.jl b/src/screen.jl index 0a8f371e384..1e7e56425df 100644 --- a/src/screen.jl +++ b/src/screen.jl @@ -16,6 +16,7 @@ mutable struct Screen <: GLScreen cache::Dict{UInt64, RenderObject} cache2plot::Dict{UInt16, AbstractPlot} framecache::Tuple{Matrix{RGB{N0f8}}, Matrix{RGB{N0f8}}} + displayed_scene::Union{Scene, Nothing} function Screen( glscreen::GLFW.Window, framebuffer::GLFramebuffer, @@ -30,7 +31,8 @@ mutable struct Screen <: GLScreen obj = new( glscreen, framebuffer, rendertask, screen2scene, screens, renderlist, cache, cache2plot, - (Matrix{RGB{N0f8}}(undef, s), Matrix{RGB{N0f8}}(undef, reverse(s))) + (Matrix{RGB{N0f8}}(undef, s), Matrix{RGB{N0f8}}(undef, reverse(s))), + nothing ) finalizer(obj) do obj # save_print("Freeing screen") @@ -45,6 +47,7 @@ GeometryTypes.widths(x::Screen) = size(x.framebuffer.color) Base.wait(x::Screen) = isassigned(x.rendertask) && wait(x.rendertask[]) Base.wait(scene::Scene) = wait(global_gl_screen()) # TODO per scene screen Base.show(io::IO, screen::Screen) = print(io, "GLMakie.Screen(...)") +Base.size(x::Screen) = size(x.framebuffer) function insertplots!(screen::GLScreen, scene::Scene) for elem in scene.plots @@ -79,15 +82,16 @@ function Base.resize!(screen::Screen, w, h) resize!(nw, w, h) fb = screen.framebuffer resize!(fb, (w, h)) + GLFW.PollEvents() end -function Base.display(screen::Screen, scene::Scene) +function AbstractPlotting.backend_display(screen::Screen, scene::Scene) empty!(screen) - resize!(screen, size(scene)...) - GLFW.PollEvents() # let the size change go through (TODO is this necessary?) register_callbacks(scene, to_native(screen)) + GLFW.PollEvents() insertplots!(screen, scene) - AbstractPlotting.update!(scene) + GLFW.PollEvents() + screen.displayed_scene = scene return end @@ -178,7 +182,54 @@ function renderloop end # the rendering loop const opengl_renderloop = Ref{Function}(renderloop) -function Screen(; resolution = (10, 10), visible = false, kw_args...) +""" +Loads the makie loading icon and embedds it in an image the size of resolution +""" +function get_loading_image(resolution) + icon = Matrix{N0f8}(undef, 192, 192) + open(GLMakie.assetpath("loading.bin")) do io + read!(io, icon) + end + img = zeros(RGBA{N0f8}, resolution...) + center = resolution .÷ 2 + center_icon = size(icon) .÷ 2 + start = CartesianIndex(max.(center .- center_icon, 1)) + stop = min(start + CartesianIndex(size(icon)), CartesianIndex(resolution)) + width = stop - start + range = CartesianIndices(width) .+ start + for idx in range + gray = icon[idx - start] + img[idx] = RGBA{N0f8}(gray, gray, gray, 1.0) + end + return img +end + +function display_loading_image(screen::Screen) + fb = screen.framebuffer + fbsize = size(fb) + image = get_loading_image(fbsize) + if size(image) == fbsize + GLFW.PollEvents() # poll events to not make the window freeze + nw = to_native(screen) + fb.color[1:size(image, 1), 1:size(image, 2)] = image # transfer loading image to gpu framebuffer + GLAbstraction.is_context_active(nw) || return + w, h = fbsize + glBindFramebuffer(GL_FRAMEBUFFER, 0) # transfer back to window + glViewport(0, 0, w, h) + glClearColor(0, 0, 0, 0) + glClear(GL_COLOR_BUFFER_BIT) + GLAbstraction.render(fb.postprocess[3]) # copy postprocess + GLFW.SwapBuffers(nw) + else + error("loading_image needs to be Matrix{RGBA{N0f8}} with size(loading_image) == resolution") + end + +end + +function Screen(; + resolution = (10, 10), visible = false, title = "Makie", + kw_args... + ) if !isempty(gl_screens) for elem in gl_screens isopen(elem) && destroy!(elem) @@ -187,7 +238,7 @@ function Screen(; resolution = (10, 10), visible = false, kw_args...) end window = GLFW.Window( - name = "Makie", resolution = (10, 10), # 10, because smaller sizes seem to error on some platforms + name = title, resolution = (10, 10), # 10, because smaller sizes seem to error on some platforms windowhints = [ (GLFW.SAMPLES, 0), (GLFW.DEPTH_BITS, 0), @@ -200,7 +251,8 @@ function Screen(; resolution = (10, 10), visible = false, kw_args...) (GLFW.BLUE_BITS, 8), (GLFW.STENCIL_BITS, 0), - (GLFW.AUX_BUFFERS, 0) + (GLFW.AUX_BUFFERS, 0), + (GLFW.RESIZABLE, GL_TRUE) ], visible = false, kw_args... @@ -231,6 +283,12 @@ function Screen(; resolution = (10, 10), visible = false, kw_args...) Dict{UInt64, RenderObject}(), Dict{UInt16, AbstractPlot}(), ) + + GLFW.SetWindowRefreshCallback(window, window -> begin + render_frame(screen) + GLFW.SwapBuffers(window) + end) + if visible GLFW.ShowWindow(window) else @@ -247,7 +305,29 @@ function global_gl_screen() _global_gl_screen[] = Screen() _global_gl_screen[] end - GLFW.set_visibility!(to_native(screen), AbstractPlotting.use_display[]) + return screen +end + +function global_gl_screen(resolution::Tuple, visibility::Bool, tries = 1) + # ugly but easy way to find out if we create new screen. + # could just be returned by global_gl_screen, but dont want to change the API + isold = isassigned(_global_gl_screen) && isopen(_global_gl_screen[]) + screen = global_gl_screen() + GLFW.set_visibility!(to_native(screen), visibility) + resize!(screen, resolution...) + new_size = GLFW.GetWindowSize(to_native(screen)) + # I'm not 100% sure, if there are platforms where I'm never + # able to resize the screen (opengl might just allow that). + # so, we guard against that with just trying another resize one time! + if ((new_size.width, new_size.height) != resolution) && tries == 1 + # resize failed. This may happen when screen was previously + # enlarged to fill screen. WE NEED TO DESTROY!! (I think) + destroy!(screen) + # try again + return global_gl_screen(resolution, visibility, 2) + end + # show loading image on fresh screen + isold || display_loading_image(screen) screen end From 326b799d4a0ddfd19ab42107fce401e8912894c0 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Fri, 15 Mar 2019 15:30:56 +0100 Subject: [PATCH 0110/1328] remove unecessary module --- src/drawing_primitives.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/drawing_primitives.jl b/src/drawing_primitives.jl index eeced5893e7..87a6bef822a 100644 --- a/src/drawing_primitives.jl +++ b/src/drawing_primitives.jl @@ -122,7 +122,7 @@ AbstractPlotting.to_spritemarker(x::FastPixel) = x function draw_atomic(screen::GLScreen, scene::Scene, x::Union{Scatter, MeshScatter}) robj = cached_robj!(screen, scene, x) do gl_attributes # signals not supported for shading yet - gl_attributes[:shading] = AbstractPlotting.to_value(get(gl_attributes, :shading, true)) + gl_attributes[:shading] = to_value(get(gl_attributes, :shading, true)) marker = lift_convert(:marker, pop!(gl_attributes, :marker), x) if isa(x, Scatter) gl_attributes[:billboard] = map(rot-> isa(rot, Billboard), x.attributes[:rotations]) @@ -328,7 +328,7 @@ function draw_atomic(screen::GLScreen, scene::Scene, x::Surface) end gl_attributes[:color] = img args = x[1:3] - gl_attributes[:shading] = AbstractPlotting.to_value(get(gl_attributes, :shading, true)) + gl_attributes[:shading] = to_value(get(gl_attributes, :shading, true)) if all(v-> to_value(v) isa AbstractMatrix, args) visualize(args, Style(:surface), gl_attributes).children[] else From 45ab1d8c06133f2f8b749691828219769f5c2130 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Fri, 15 Mar 2019 17:26:21 +0100 Subject: [PATCH 0111/1328] fixes for 1.0.3 --- src/screen.jl | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/screen.jl b/src/screen.jl index 1e7e56425df..56e954a4787 100644 --- a/src/screen.jl +++ b/src/screen.jl @@ -182,6 +182,15 @@ function renderloop end # the rendering loop const opengl_renderloop = Ref{Function}(renderloop) + +""" +Julia 1.0.3 doesn't have I:J, so we copy the implementation from 1.1 under a new name: +""" +function irange(I::CartesianIndex{N}, J::CartesianIndex{N}) where N + CartesianIndices(map((i,j) -> i:j, Tuple(I), Tuple(J))) +end + + """ Loads the makie loading icon and embedds it in an image the size of resolution """ @@ -194,11 +203,10 @@ function get_loading_image(resolution) center = resolution .÷ 2 center_icon = size(icon) .÷ 2 start = CartesianIndex(max.(center .- center_icon, 1)) - stop = min(start + CartesianIndex(size(icon)), CartesianIndex(resolution)) - width = stop - start - range = CartesianIndices(width) .+ start - for idx in range - gray = icon[idx - start] + I1 = CartesianIndex(1, 1) + stop = min(start + CartesianIndex(size(icon)) - I1, CartesianIndex(resolution)) + for idx in irange(start, stop) + gray = icon[idx - start + I1] img[idx] = RGBA{N0f8}(gray, gray, gray, 1.0) end return img @@ -252,7 +260,7 @@ function Screen(; (GLFW.STENCIL_BITS, 0), (GLFW.AUX_BUFFERS, 0), - (GLFW.RESIZABLE, GL_TRUE) + # (GLFW.RESIZABLE, GL_TRUE) ], visible = false, kw_args... From c42e25c11e06f7f041955e23e4ab902cfc582673 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 20 Mar 2019 20:08:45 +0100 Subject: [PATCH 0112/1328] this seems to be safer --- src/screen.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/screen.jl b/src/screen.jl index 56e954a4787..4c86aa46c72 100644 --- a/src/screen.jl +++ b/src/screen.jl @@ -214,7 +214,7 @@ end function display_loading_image(screen::Screen) fb = screen.framebuffer - fbsize = size(fb) + fbsize = size(fb.color) image = get_loading_image(fbsize) if size(image) == fbsize GLFW.PollEvents() # poll events to not make the window freeze From 571d6fa3df01bfd39e8b24324705d6ef2e860548 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 8 Apr 2019 13:21:58 +0200 Subject: [PATCH 0113/1328] make ranges lifted --- src/GLVisualize/visualize/image_like.jl | 8 ++++++-- src/drawing_primitives.jl | 7 +++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/GLVisualize/visualize/image_like.jl b/src/GLVisualize/visualize/image_like.jl index da718877950..6cd0739769c 100644 --- a/src/GLVisualize/visualize/image_like.jl +++ b/src/GLVisualize/visualize/image_like.jl @@ -53,11 +53,15 @@ function gl_heatmap(main::MatTypes{T}, data::Dict) where T <: AbstractFloat @gen_defaults! data begin ranges = (0:size(main_v, 1), 0:size(main_v, 2)) end - x, y, xw, yh = minimum(ranges[1]), minimum(ranges[2]), maximum(ranges[1]), maximum(ranges[2]) + prim = const_lift(data[:ranges]) do ranges + x, y, xw, yh = minimum(ranges[1]), minimum(ranges[2]), maximum(ranges[1]), maximum(ranges[2]) + SimpleRectangle{Float32}(x, y, xw-x, yh-y) + end + delete!(data, :ranges) @gen_defaults! data begin intensity = main => Texture color_map = default(Vector{RGBA{N0f8}},s) => Texture - primitive::GLUVMesh2D = SimpleRectangle{Float32}(x, y, xw-x, yh-y) + primitive::GLUVMesh2D = prim color_norm = const_lift(extrema2f0, main) stroke_width::Float32 = 0.05f0 levels::Float32 = 5f0 diff --git a/src/drawing_primitives.jl b/src/drawing_primitives.jl index 87a6bef822a..8110ab5d269 100644 --- a/src/drawing_primitives.jl +++ b/src/drawing_primitives.jl @@ -1,5 +1,6 @@ gpuvec(x) = GPUVector(GLBuffer(x)) +to_range(x, y) = to_range.((x, y)) to_range(x::ClosedInterval) = (minimum(x), maximum(x)) to_range(x::VecTypes{2}) = x to_range(x::AbstractRange) = (minimum(x), maximum(x)) @@ -239,9 +240,11 @@ function draw_atomic(screen::GLScreen, scene::Scene, x::Text) end + function draw_atomic(screen::GLScreen, scene::Scene, x::Heatmap) robj = cached_robj!(screen, scene, x) do gl_attributes - gl_attributes[:ranges] = (to_value.((x[1], x[2]))) + gl_attributes[:ranges] = lift(to_range, x[1], x[2]) + @show gl_attributes[:ranges][] interp = to_value(pop!(gl_attributes, :interpolate)) interp = interp ? :linear : :nearest tex = Texture(x[3], minfilter = interp) @@ -268,7 +271,7 @@ end function draw_atomic(screen::GLScreen, scene::Scene, x::Image) robj = cached_robj!(screen, scene, x) do gl_attributes - gl_attributes[:ranges] = to_range.(to_value.((x[1], x[2]))) + gl_attributes[:ranges] = lift(to_range, x[1], x[2]) img = get_image(gl_attributes) # remove_automatic!(gl_attributes) visualize(img, Style(:default), gl_attributes).children[] From 8eb8991b56e33dfa6c59b326ccec7dbfa65ee5cf Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 8 Apr 2019 13:29:20 +0200 Subject: [PATCH 0114/1328] remove debug --- src/drawing_primitives.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/drawing_primitives.jl b/src/drawing_primitives.jl index 8110ab5d269..7dbd1110790 100644 --- a/src/drawing_primitives.jl +++ b/src/drawing_primitives.jl @@ -244,7 +244,6 @@ end function draw_atomic(screen::GLScreen, scene::Scene, x::Heatmap) robj = cached_robj!(screen, scene, x) do gl_attributes gl_attributes[:ranges] = lift(to_range, x[1], x[2]) - @show gl_attributes[:ranges][] interp = to_value(pop!(gl_attributes, :interpolate)) interp = interp ? :linear : :nearest tex = Texture(x[3], minfilter = interp) From c1b80dc66f25b84f6510a313686337ff6d732494 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 8 Apr 2019 15:26:53 +0200 Subject: [PATCH 0115/1328] fix out of bounds issue: --- src/GLAbstraction/GLTexture.jl | 6 +++--- src/screen.jl | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/GLAbstraction/GLTexture.jl b/src/GLAbstraction/GLTexture.jl index 66eec669c44..d6a43024966 100644 --- a/src/GLAbstraction/GLTexture.jl +++ b/src/GLAbstraction/GLTexture.jl @@ -329,12 +329,12 @@ end # Resize Texture function gpu_resize!(t::Texture{T, ND}, newdims::NTuple{ND, Int}) where {T, ND} # dangerous code right here...Better write a few tests for this - newtex = similar(t, newdims) + newtex = similar(t, newdims) old_size = size(t) gpu_setindex!(newtex, t) - t.size = newdims + t.size = newdims free(t) - t.id = newtex.id + t.id = newtex.id return t end diff --git a/src/screen.jl b/src/screen.jl index 4c86aa46c72..4d935c3ff18 100644 --- a/src/screen.jl +++ b/src/screen.jl @@ -82,7 +82,6 @@ function Base.resize!(screen::Screen, w, h) resize!(nw, w, h) fb = screen.framebuffer resize!(fb, (w, h)) - GLFW.PollEvents() end function AbstractPlotting.backend_display(screen::Screen, scene::Scene) @@ -217,7 +216,6 @@ function display_loading_image(screen::Screen) fbsize = size(fb.color) image = get_loading_image(fbsize) if size(image) == fbsize - GLFW.PollEvents() # poll events to not make the window freeze nw = to_native(screen) fb.color[1:size(image, 1), 1:size(image, 2)] = image # transfer loading image to gpu framebuffer GLAbstraction.is_context_active(nw) || return From 9f4f6253d7c394140ea11ef0420d357f1cdfae5d Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Tue, 9 Apr 2019 12:48:47 +0200 Subject: [PATCH 0116/1328] fix JuliaPlots/AbstractPlotting.jl#66 and fix JuliaPlots/GLMakie.jl#31 --- src/GLVisualize/assets/shader/line_segment.vert | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/GLVisualize/assets/shader/line_segment.vert b/src/GLVisualize/assets/shader/line_segment.vert index e9c432fdc34..bc794d1b75f 100644 --- a/src/GLVisualize/assets/shader/line_segment.vert +++ b/src/GLVisualize/assets/shader/line_segment.vert @@ -18,12 +18,17 @@ vec4 getindex(sampler1D tex, int index); vec4 to_vec4(vec3 v){return vec4(v, 1);} vec4 to_vec4(vec2 v){return vec4(v, 0, 1);} +vec4 to_color(vec4 v, int index){return v;} +vec4 to_color(vec3 v, int index){return vec4(v, 1);} +vec4 to_color(sampler2D tex, int index){return getindex(tex, index);} +vec4 to_color(sampler1D tex, int index){return getindex(tex, index);} + void main() { int index = gl_VertexID; g_id = uvec2(objectid, index+1); - g_color = {{color_calculation}}; + g_color = to_color(color, index); g_thickness = thickness; gl_Position = projection*view*model*to_vec4(vertex); } From 59556db965eb8d2a186ec7511d8abebd946f38d3 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 10 Apr 2019 20:52:17 +0200 Subject: [PATCH 0117/1328] fix mesh colors --- src/drawing_primitives.jl | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/drawing_primitives.jl b/src/drawing_primitives.jl index 7dbd1110790..95de84ff060 100644 --- a/src/drawing_primitives.jl +++ b/src/drawing_primitives.jl @@ -291,18 +291,23 @@ function draw_atomic(screen::GLScreen, scene::Scene, x::Mesh) c = convert_mesh_color(c, cmap, crange) if isa(m, GLNormalColorMesh) || isa(m, GLNormalAttributeMesh) || isa(m, GLNormalVertexcolorMesh) m - elseif isa(c, Colorant) + elseif c isa Colorant get!(gl_attributes, :color, Node(c))[] = c if !(isa(m, GLPlainMesh) || isa(m, GLNormalMesh)) GLNormalMesh(m) else m end - elseif isa(c, AbstractMatrix{<: Colorant}) + elseif c isa AbstractMatrix{<: Colorant} get!(gl_attributes, :color, Node(c))[] = c m - else + elseif c isa AbstractVector{<: Colorant} + if length(c) != length(vertices(m)) + error("Please use the same amount of colors as vertices. Found: $(length(vertices(m))) vertices, and $(length(c)) colors") + end HomogenousMesh(GLNormalMesh(m), Dict{Symbol, Any}(:color => c)) + else + error("Unsupported color type: $(typeof(c))") end end visualize(mesh, Style(:default), gl_attributes).children[] From 44da1c1050a4db26c49f01f232fa20cc051090a3 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Thu, 18 Apr 2019 19:35:37 +0200 Subject: [PATCH 0118/1328] Initial commit From 3a42a011e5fab3b7f0f81c6b8e26f777d6e1fdea Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Thu, 18 Apr 2019 19:35:50 +0200 Subject: [PATCH 0119/1328] Files generated by PkgTemplates --- .appveyor.yml | 31 +++++++++++++++++ .gitignore | 7 ++++ .travis.yml | 26 +++++++++++++++ LICENSE | 19 +++++++++++ Project.toml | 10 ++++++ README.md | 7 ++++ REQUIRE | 1 + docs/Manifest.toml | 83 ++++++++++++++++++++++++++++++++++++++++++++++ docs/Project.toml | 2 ++ docs/make.jl | 17 ++++++++++ docs/src/index.md | 8 +++++ src/WGLMakie.jl | 5 +++ test/runtests.jl | 6 ++++ 13 files changed, 222 insertions(+) create mode 100644 .appveyor.yml create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 LICENSE create mode 100644 Project.toml create mode 100644 README.md create mode 100644 REQUIRE create mode 100644 docs/Manifest.toml create mode 100644 docs/Project.toml create mode 100644 docs/make.jl create mode 100644 docs/src/index.md create mode 100644 src/WGLMakie.jl create mode 100644 test/runtests.jl diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 00000000000..bee60a28f49 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,31 @@ +# Documentation: https://github.com/JuliaCI/Appveyor.jl +environment: + matrix: + - julia_version: 1.0 + - julia_version: nightly +platform: + - x86 + - x64 +matrix: + allow_failures: + - julia_version: nightly +branches: + only: + - master + - /release-.*/ +notifications: + - provider: Email + on_build_success: false + on_build_failure: false + on_build_status_changed: false +install: + - ps: iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/JuliaCI/Appveyor.jl/version-1/bin/install.ps1")) +build_script: + - echo "%JL_BUILD_SCRIPT%" + - C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%" +test_script: + - echo "%JL_TEST_SCRIPT%" + - C:\julia\bin\julia -e "%JL_TEST_SCRIPT%" +on_success: + - echo "%JL_CODECOV_SCRIPT%" + - C:\julia\bin\julia -e "%JL_CODECOV_SCRIPT%" diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000000..577aec323e6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +*.jl.*.cov +*.jl.cov +*.jl.mem +.DS_Store +/Manifest.toml +/docs/build/ +/docs/site/ diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000000..21b2985b117 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,26 @@ +# Documentation: http://docs.travis-ci.com/user/languages/julia/ +language: julia +os: + - linux + - osx +julia: + - 1.0 + - nightly +matrix: + allow_failures: + - julia: nightly + fast_finish: true +notifications: + email: false +after_success: + - julia -e 'using Pkg; Pkg.add("Coverage"); using Coverage; Codecov.submit(process_folder())' +jobs: + include: + - stage: Documentation + julia: 1.0 + script: julia --project=docs -e ' + using Pkg; + Pkg.develop(PackageSpec(path=pwd())); + Pkg.instantiate(); + include("docs/make.jl");' + after_success: skip diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000000..31f214587ed --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2019 Simon Danisch + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Project.toml b/Project.toml new file mode 100644 index 00000000000..77a20fff253 --- /dev/null +++ b/Project.toml @@ -0,0 +1,10 @@ +name = "WGLMakie" +uuid = "276b4fcb-3e11-5398-bf8b-a0c2d153d008" +authors = ["SimonDanisch "] +version = "0.1.0" + +[extras] +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[targets] +test = ["Test"] diff --git a/README.md b/README.md new file mode 100644 index 00000000000..976898ccfb4 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# WGLMakie + +[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://SimonDanisch.github.io/WGLMakie.jl/stable) +[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://SimonDanisch.github.io/WGLMakie.jl/dev) +[![Build Status](https://travis-ci.com/SimonDanisch/WGLMakie.jl.svg?branch=master)](https://travis-ci.com/SimonDanisch/WGLMakie.jl) +[![Build Status](https://ci.appveyor.com/api/projects/status/github/SimonDanisch/WGLMakie.jl?svg=true)](https://ci.appveyor.com/project/SimonDanisch/WGLMakie-jl) +[![Codecov](https://codecov.io/gh/SimonDanisch/WGLMakie.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/SimonDanisch/WGLMakie.jl) diff --git a/REQUIRE b/REQUIRE new file mode 100644 index 00000000000..05b5ab4c7d8 --- /dev/null +++ b/REQUIRE @@ -0,0 +1 @@ +julia 1.0 diff --git a/docs/Manifest.toml b/docs/Manifest.toml new file mode 100644 index 00000000000..c08e39b6595 --- /dev/null +++ b/docs/Manifest.toml @@ -0,0 +1,83 @@ +# This file is machine-generated - editing it directly is not advised + +[[Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[DocStringExtensions]] +deps = ["LibGit2", "Markdown", "Pkg", "Test"] +git-tree-sha1 = "4d30e889c9f106a51ffa4791a88ffd4765bf20c3" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.7.0" + +[[Documenter]] +deps = ["Base64", "DocStringExtensions", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "Pkg", "REPL", "Random", "Test", "Unicode"] +git-tree-sha1 = "13a6d15102410d8e70146533b759fc48d844a1d0" +uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +version = "0.22.3" + +[[InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[JSON]] +deps = ["Dates", "Distributed", "Mmap", "Sockets", "Test", "Unicode"] +git-tree-sha1 = "1f7a25b53ec67f5e9422f1f551ee216503f4a0fa" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.20.0" + +[[LibGit2]] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[Pkg]] +deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" + +[[Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[Random]] +deps = ["Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" + +[[Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[Test]] +deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" diff --git a/docs/Project.toml b/docs/Project.toml new file mode 100644 index 00000000000..dfa65cd107d --- /dev/null +++ b/docs/Project.toml @@ -0,0 +1,2 @@ +[deps] +Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" diff --git a/docs/make.jl b/docs/make.jl new file mode 100644 index 00000000000..535db42956d --- /dev/null +++ b/docs/make.jl @@ -0,0 +1,17 @@ +using Documenter, WGLMakie + +makedocs(; + modules=[WGLMakie], + format=Documenter.HTML(), + pages=[ + "Home" => "index.md", + ], + repo="https://github.com/SimonDanisch/WGLMakie.jl/blob/{commit}{path}#L{line}", + sitename="WGLMakie.jl", + authors="Simon Danisch", + assets=[], +) + +deploydocs(; + repo="github.com/SimonDanisch/WGLMakie.jl", +) diff --git a/docs/src/index.md b/docs/src/index.md new file mode 100644 index 00000000000..3b5b81ccc67 --- /dev/null +++ b/docs/src/index.md @@ -0,0 +1,8 @@ +# WGLMakie.jl + +```@index +``` + +```@autodocs +Modules = [WGLMakie] +``` diff --git a/src/WGLMakie.jl b/src/WGLMakie.jl new file mode 100644 index 00000000000..45519055a5d --- /dev/null +++ b/src/WGLMakie.jl @@ -0,0 +1,5 @@ +module WGLMakie + +greet() = print("Hello World!") + +end # module diff --git a/test/runtests.jl b/test/runtests.jl new file mode 100644 index 00000000000..3d9524cb588 --- /dev/null +++ b/test/runtests.jl @@ -0,0 +1,6 @@ +using WGLMakie +using Test + +@testset "WGLMakie.jl" begin + # Write your own tests here. +end From 6e23626861b4d35d924914b99dc84767b26c8cad Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Thu, 18 Apr 2019 19:47:38 +0200 Subject: [PATCH 0120/1328] initial prototype --- Project.toml | 9 ++ src/WGLMakie.jl | 310 ++++++++++++++++++++++++++++++++++++++++++++++- test/runtests.jl | 16 ++- 3 files changed, 330 insertions(+), 5 deletions(-) diff --git a/Project.toml b/Project.toml index 77a20fff253..4feecfd9c7b 100644 --- a/Project.toml +++ b/Project.toml @@ -3,6 +3,15 @@ uuid = "276b4fcb-3e11-5398-bf8b-a0c2d153d008" authors = ["SimonDanisch "] version = "0.1.0" +[deps] +AbstractPlotting = "537997a7-5e4e-5d89-9595-2241ea00577e" +Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" +GeometryTypes = "4d00f742-c7ba-57c2-abde-4428a4b178cb" +JSExpr = "97c1335a-c9c5-57fe-bc5d-ec35cebe8660" +Observables = "510215fc-4207-5dde-b226-833fc4488ee2" +WebIO = "0f1e0344-ec1d-5b48-a673-e5cf874b6c29" +WebSockets = "104b5d7c-a370-577a-8038-80a2059c5097" + [extras] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/src/WGLMakie.jl b/src/WGLMakie.jl index 45519055a5d..6b64b524233 100644 --- a/src/WGLMakie.jl +++ b/src/WGLMakie.jl @@ -1,5 +1,313 @@ module WGLMakie -greet() = print("Hello World!") +using WebSockets, JSCall, WebIO, JSExpr, Colors, GeometryTypes +using JSExpr: jsexpr +using AbstractPlotting, Observables + +function register_js_events!(comm) + @js begin + # TODO, the below doesn't actually work to disable right-click menu + function no_context(event) + event.preventDefault() + return false + end + document.addEventListener("contextmenu", no_context, false) + + function mousemove(event) + $(comm)[] = Dict( + :mouseposition => [event.pageX, event.pageY] + ) + event.preventDefault() + return false + end + document.addEventListener("mousemove", mousemove, false) + + function mousedown(event) + $(comm)[] = Dict( + :mousedown => event.buttons + ) + event.preventDefault() + return false + end + document.addEventListener("mousedown", mousedown, false) + + function mouseup(event) + $(comm)[] = Dict( + :mouseup => event.buttons + ) + event.preventDefault() + return false + end + document.addEventListener("mouseup", mouseup, false) + + function wheel(event) + $(comm)[] = Dict( + :scroll => [event.deltaX, event.deltaY] + ) + event.preventDefault() + return false + end + document.addEventListener("wheel", wheel, false) + end +end + +macro handle(accessor, body) + obj, field = accessor.args + key = string(field.value) + efield = esc(field.value); obj = esc(obj) + quote + if haskey($(obj), $(key)) + $(efield) = $(obj)[$(key)] + $(esc(body)) + return nothing + end + end +end + +function connect_scene_events!(scene, js_doc) + comm = get_comm(js_doc) + evaljs(js_doc, register_js_events!(comm)) + e = events(scene) + on(comm) do msg + msg isa Dict || return + @handle msg.mouseposition begin + x, y = Float64.((mouseposition...,)) + e.mouseposition[] = (x, size(scene)[2] - y) + end + @handle msg.mousedown begin + set = e.mousebuttons[]; empty!(set) + mousedown & 1 != 0 && push!(set, Mouse.left) + mousedown & 2 != 0 && push!(set, Mouse.right) + mousedown & 4 != 0 && push!(set, Mouse.middle) + e.mousebuttons[] = set + end + @handle msg.mouseup begin + set = e.mousebuttons[]; empty!(set) + mouseup & 1 != 0 && push!(set, Mouse.left) + mouseup & 2 != 0 && push!(set, Mouse.right) + mouseup & 4 != 0 && push!(set, Mouse.middle) + e.mousebuttons[] = set + end + @handle msg.scroll begin + e.scroll[] = Float64.((sign.(scroll)...,)) + end + return + end +end + +ENV["WEBIO_BUNDLE_URL"] = "https://simondanisch.github.io/ReferenceImages/generic_http.js" + +function set_positions!(geometry, positions::AbstractVector{<: Point{N, T}}) where {N, T} + flat = reinterpret(T, positions) + geometry.addAttribute( + "position", THREE.new.Float32BufferAttribute(flat, N) + ) +end + +function set_colors!(geometry, colors::AbstractVector{T}) where T <: Colorant + flat = reinterpret(eltype(T), RGB{Float32}.(colors)) + geometry.addAttribute( + "color", THREE.new.Float32BufferAttribute(flat, 3) + ) +end +function set_normals!(geometry, colors::AbstractVector{T}) where T <: Normal + flat = reinterpret(eltype(T), colors) + geometry.addAttribute( + "normal", THREE.new.Float32BufferAttribute(flat, 3) + ) +end +function set_uvs!(geometry, uvs::AbstractVector{T}) where T <: UV + uvs = map(uvs) do uv + (1f0 - uv[2], 1f0 - uv[1]) + end + flat = reinterpret(Float32, uvs) + geometry.addAttribute( + "uv", THREE.new.Float32BufferAttribute(flat, 2) + ) +end + +function material!(geometry, colors::AbstractVector) + material = THREE.new.LineBasicMaterial(vertexColors = THREE.VertexColors) + set_colors!(geometry, colors) + return material +end + +function material!(geometry, color::Colorant) + material = THREE.new.LineBasicMaterial(color = "#"*hex(RGB(color))) + return material +end + +function jslines!(scene, positions, colors, linewidth, model, typ = :lines) + geometry = THREE.new.BufferGeometry() + material = material!(geometry, colors) + set_positions!(geometry, positions) + Typ = typ === :lines ? THREE.new.Line : THREE.new.LineSegments + mesh = Typ(geometry, material) + mesh.matrixAutoUpdate = false; + mesh.matrix.set(model...) + scene.add(mesh) + return mesh +end + +function draw_js(jsscene, mscene::Scene, plot) +end + +function draw_js(jsscene, mscene::Scene, plot::Lines) + @get_attribute plot (color, linewidth, model, transformation) + positions = plot[1][] + jslines!(jsscene, positions, color, linewidth, model) +end +function draw_js(jsscene, mscene::Scene, plot::LineSegments) + @get_attribute plot (color, linewidth, model) + positions = plot[1][] + jslines!(jsscene, positions, color, linewidth, model, :linesegments) +end +function draw_js(jsscene, mscene::Scene, plot::Mesh) + normalmesh = plot[1][] + @get_attribute plot (color, model) + geometry = THREE.new.BufferGeometry() + cmap = vec(reinterpret(UInt8, RGB{Colors.N0f8}.(color))) + data = window.Uint8Array.from(cmap) + tex = THREE.new.DataTexture( + data, size(color, 1), size(color, 2), + THREE.RGBFormat, THREE.UnsignedByteType + ); + tex.needsUpdate = true + material = THREE.new.MeshLambertMaterial( + color = 0xdddddd, map = tex, + transparent = true + ) + set_positions!(geometry, vertices(normalmesh)) + set_normals!(geometry, normals(normalmesh)) + set_uvs!(geometry, texturecoordinates(normalmesh)) + indices = faces(normalmesh) + indices = reinterpret(UInt32, indices) + geometry.setIndex(indices); + mesh = THREE.new.Mesh(geometry, material) + mesh.matrixAutoUpdate = false; + mesh.matrix.set(model...) + jsscene.add(mesh) + return mesh +end + +function add_scene!(jsscene, scene::Scene) + for plot in scene.plots + add_scene!(jsscene, scene, plot) + end + for sub in scene.children + add_scene!(jsscene, sub) + end +end + +function add_scene!(jsscene, scene::Scene, x::Combined) + if isempty(x.plots) # if no plots inserted, this truely is an atomic + draw_js(jsscene, scene, x) + else + foreach(x.plots) do x + add_scene!(jsscene, scene, x) + end + end +end + +function get_camera(renderer, js_scene, scene) + get_camera(renderer, js_scene, AbstractPlotting.camera(scene), cameracontrols(scene)) +end + +function get_camera(renderer, js_scene, cam, cam_controls::Camera2D) + area = cam_controls.area + mini, maxi = minimum(area[]), maximum(area[]) + jscam = THREE.new.OrthographicCamera(mini[1], maxi[1], maxi[2], mini[2], -1, 1000) + onany(area) do area + mini, maxi = minimum(area), maximum(area) + jscam.left = mini[1] + jscam.right = maxi[1] + jscam.top = maxi[2] + jscam.bottom = mini[2] + jscam.updateProjectionMatrix() + renderer.render(js_scene, jscam) + end + return jscam +end + +function get_camera(renderer, js_scene, cam, cam_controls::Camera3D) + jscam = THREE.new.PerspectiveCamera(cam_controls.fov[], (/)(cam.resolution[]...), 1, 1000) + update = Observable(false) + args = ( + cam.projection, cam_controls.eyeposition, cam_controls.lookat, cam_controls.upvector, + cam_controls.fov, cam_controls.near, cam_controls.far + ) + onany(update, args...) do _, proj, pos, lookat, up, fov, near, far + jscam.position.set(pos...) + jscam.lookAt(lookat...) + jscam.up.set(up...) + jscam.fov = fov + jscam.near = near + jscam.far = far + jscam.updateProjectionMatrix() + renderer.render(js_scene, jscam); + end + update[] = true # run onany first time + jscam +end + +# TODO make a scene struct that encapsulates these +global THREE = nothing +global window = nothing + +function get_comm(jso) + # LOL TODO git gud + obs, sync = scope(jso).observs["_jscall_value_comm"] + return obs +end + +function js_display(scene) + global THREE, window + + update!(scene) + mousedrag(scene, nothing) + width, height = size(scene) + THREE, document, window = JSModule( + :THREE, + "https://cdnjs.cloudflare.com/ajax/libs/three.js/103/three.js", + ) + style = Dict( + :width => width, :height => height + ) + + display(scope(THREE)(dom"div#container"())) + + connect_scene_events!(scene, document) + + renderer = THREE.new.WebGLRenderer(antialias = true) + renderer.setSize(width, height) + renderer.setClearColor("#ffffff") + document.body.appendChild(renderer.domElement) + js_scene = THREE.new.Scene() + add_scene!(js_scene, scene) + ambient = THREE.new.AmbientLight(0x666666) + directionalLight = THREE.new.DirectionalLight(0xffffff, 1.5) + directionalLight.position.set((rand(Vec3f0) .- 0.5)...) + directionalLight.position.normalize() + js_scene.add(directionalLight) + js_scene.add(ambient) + cam = get_camera(renderer, js_scene, scene) + renderer.render(js_scene, cam); + document, window +end + +export js_display + +# document.addEventListener("mousedown", onDocumentMouseDown, false) +# document.addEventListener("mouseup", onDocumentMouseDown, false) +# document.addEventListener("wheel", onDocumentMouseDown, false) +# +# document.addEventListener("resize", onWindowResize, false) +# +# document.addEventListener("focus", onWindowResize, false) +# +# document.addEventListener("resize", onWindowResize, false) +# document.addEventListener("keydown", onWindowResize, false) +# +# document.addEventListener("keyup", onWindowResize, false) end # module diff --git a/test/runtests.jl b/test/runtests.jl index 3d9524cb588..3c448542304 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,6 +1,14 @@ -using WGLMakie +using WGLMakie, AbstractPlotting using Test -@testset "WGLMakie.jl" begin - # Write your own tests here. -end +AbstractPlotting.set_theme!(resolution = (650, 300)) + +r = range(0, stop=5pi, length=100) +s = lines(r, sin.(r), linewidth = 3) +d, w = js_display(s); + +using FileIO +cd(joinpath(homedir(), ".julia", "dev", "GLMakie", "src", "GLVisualize", "assets")) +catmesh = load("cat.obj", GLNormalUVMesh) +texture = load("diffusemap.tga"); +js_display(mesh(catmesh, color = texture)); From a083ed34dbfb2fad873a27ee1fc1ee31ac6d776e Mon Sep 17 00:00:00 2001 From: Anshul Singhvi Date: Thu, 18 Apr 2019 15:11:24 -0400 Subject: [PATCH 0121/1328] Update README with instructions --- README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/README.md b/README.md index 976898ccfb4..47878bd238a 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,25 @@ [![Build Status](https://travis-ci.com/SimonDanisch/WGLMakie.jl.svg?branch=master)](https://travis-ci.com/SimonDanisch/WGLMakie.jl) [![Build Status](https://ci.appveyor.com/api/projects/status/github/SimonDanisch/WGLMakie.jl?svg=true)](https://ci.appveyor.com/project/SimonDanisch/WGLMakie-jl) [![Codecov](https://codecov.io/gh/SimonDanisch/WGLMakie.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/SimonDanisch/WGLMakie.jl) + +WGLMakie is a WebGL backend for the [Makie.jl](https://www.github.com/JuliaPlots/Makie.jl) plotting package, implemented using Three.js. + +# Installation + +```julia +]add https://github.com/SimonDanisch/JSCall.jl +]add https://github.com/JuliaPlots/WGLMakie.jl +``` + +Warning - this package is **in development** and **may break often**. + +# Usage + +Still to come, but it will use the `AbstractPlotting` standard interface: + +```julia +using AbstractPlotting, WGLMakie + +AbstractPlotting.current_backend[] = WGLMakie.WGLBackend() +``` + From 6762cfe467571bb4b2b98bde7fe426853454ec55 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Tue, 23 Apr 2019 11:52:38 +0200 Subject: [PATCH 0122/1328] wip --- assets/particles.frag | 11 ++++ assets/particles.vert | 107 +++++++++++++++++++++++++++++++++++++ src/particles.jl | 119 ++++++++++++++++++++++++++++++++++++++++++ test/runtests.jl | 58 ++++++++++++++++++++ 4 files changed, 295 insertions(+) create mode 100644 assets/particles.frag create mode 100644 assets/particles.vert create mode 100644 src/particles.jl diff --git a/assets/particles.frag b/assets/particles.frag new file mode 100644 index 00000000000..48777a54935 --- /dev/null +++ b/assets/particles.frag @@ -0,0 +1,11 @@ +precision highp float; + +uniform sampler2D map; + +varying vec2 vUv; + +void main() { + + gl_FragColor = texture2D(map, vUv); + +} diff --git a/assets/particles.vert b/assets/particles.vert new file mode 100644 index 00000000000..8bfa59cf20c --- /dev/null +++ b/assets/particles.vert @@ -0,0 +1,107 @@ +precision highp float; + +struct Nothing{ //Nothing type, to encode if some variable doesn't contain any data + bool _; //empty structs are not allowed +}; + +struct Grid1D{ + int lendiv; + float start; + float stop; + int dims; +}; + +struct Grid2D{ + ivec2 lendiv; + vec2 start; + vec2 stop; + ivec2 dims; +}; + +struct Grid3D{ + ivec3 lendiv; + vec3 start; + vec3 stop; + ivec3 dims; +}; + +attribute vec3 vertices; +attribute vec3 normals; +attribute vec2 uv; + +uniform mat4 viewMatrix; +uniform mat4 modelMatrix; +uniform mat4 projectionMatrix; + + +varying vec4 o_color; +varying vec2 o_uv; + +{{position_type}} position; +{{rotation_type}} rotations; +{{scale_type}} scale; +{{color_type}} color; +{{color_map_type}} color_map; +{{intensity_type}} intensity; +{{color_norm_type}} color_norm; + + +vec3 qmul(vec4 q, vec3 v){ + return v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v ); +} + +void rotate(vec4 q, int index, inout vec3 V, inout vec3 N){ + V = qmul(q, V); + N = normalize(qmul(q, N)); +} + +vec3 scale3d(vec2 scale){ + return vec3(scale, 1); +} + +vec3 scale3d(vec3 scale){ + return scale; +} + + +// constant color! +vec4 colorize(vec4 color, Nothing intensity, Nothing color_map, Nothing color_norm, int index, int len); +vec4 colorize(vec3 color, Nothing intensity, Nothing color_map, Nothing color_norm, int index, int len); + +// no color, but intensities a color map and color norm. Color will be based on intensity! +vec4 colorize(Nothing color, sampler1D intensity, sampler1D color_map, vec2 color_norm, int index, int len); + +vec4 color_lookup(float intensity, sampler1D color_ramp, vec2 norm); + +varying vec3 o_normal; +varying vec3 o_lightdir; +varying vec3 o_vertex; +varying vec4 o_color; + +void render(vec4 position_world, vec3 normal, mat4 view, mat4 projection, vec3 light[4]) +{ + // normal in world space + // TODO move transpose inverse calculation to cpu + o_normal = normal; + // direction to light + o_lightdir = normalize(light[3] - position_world.xyz); + // direction to camera + o_vertex = -position_world.xyz; + // screen space coordinates of the vertex + gl_Position = projection * view * position_world; +} + +vec2 get_uv(vec2 x){return vec2(1.0 - x.y, x.x);} + +void main(){ + + vec3 s = scale3d(scale); + vec3 V = vertices * s; + vec3 N = normals; + vec3 pos = position; + + o_color = colorize(color, intensity, color_map, color_norm, index, len); + o_uv = get_uv(uv); + rotate(rotation, index, V, N); + render(modelMatrix * vec4(pos + V, 1), N, viewMatrix, projectionMatrix, light); +} diff --git a/src/particles.jl b/src/particles.jl new file mode 100644 index 00000000000..101c5f7e2c6 --- /dev/null +++ b/src/particles.jl @@ -0,0 +1,119 @@ +using Colors, WebIO +using JSCall, JSExpr + + +function instanced_attribute(js_scene, attribute::AbstractVector{T}) where T + window = WGLMakie.window; THREE = WGLMakie.THREE + flat = reinterpret(eltype(T), attribute) + js_f32 = window.new.Float32Array(flat) + return THREE.new.InstancedBufferAttribute(js_f32, length(T)) +end + + +JSCall.@jsfun function create_material(vert, frag, tex) + @var material = @new $(WGLMakie.THREE).RawShaderMaterial( + Dict( + :uniforms => Dict( + :map => Dict(:value => tex) + ), + :vertexShader => vert, + :fragmentShader => frag, + ) + ) + return material +end + +using GLMakie +using GLMakie.GLAbstraction + + +function wgl_convert(sampler::Sampler) + window = WGLMakie.window; THREE = WGLMakie.THREE + cmap = vec(reinterpret(UInt8, RGB{Colors.N0f8}.(sampler.data))) + data = window.Uint8Array.from(cmap) + tex = THREE.new.DataTexture( + data, size(color, 1), size(color, 2), + THREE.RGBFormat, THREE.UnsignedByteType + ); + tex.needsUpdate = true + return tex +end + + +function wgl_convert(vao::VertexArray) + +end + +function convert_attribute(x::AbstractMatrix, ::key"color") + typ_or_scalar(Sampler, x) +end + +function convert_attribute(x::Abstra, ::key"color") + typ_or_scalar(Sampler, x) +end + +convert_uniform(sampler::Sampler) = sampler + +attributes = instanced_program( + shader, + plot.marker[], + VertexArray( + position = plot[1][], + rotations = plot.rotations[], + scale = plot.markersize[], + color = plot.color[], + intensity = nothing, #plot.intensity[], + ) + colormap = plot.colormap[], + colorrange = plot.colorrange[], +) + + +construct_program(nothing, nothing, lasset("particles.vert"), scene[end]) + +scene = meshscatter(rand(Point3f0, 10), rotations = rand(Quaternionf0, 10)) + + +function create_tex(color) + window = WGLMakie.window; THREE = WGLMakie.THREE + cmap = vec(reinterpret(UInt8, RGB{Colors.N0f8}.(color))) + data = window.Uint8Array.from(cmap) + tex = THREE.new.DataTexture( + data, size(color, 1), size(color, 2), + THREE.RGBFormat, THREE.UnsignedByteType + ); + tex.needsUpdate = true + return tex +ende + +lasset(paths...) = read(joinpath(dirname(pathof(WGLMakie)), "..", "assets", paths...), String) +function WGLMakie.draw_js(jsscene, scene::Scene, plot::MeshScatter) + THREE = WGLMakie.THREE + @get_attribute plot (rotations, marker, model) + + bufferGeometry = THREE.new.BoxBufferGeometry(0.1, 0.1, 0.1) + + geometry = THREE.new.InstancedBufferGeometry(); + geometry.index = bufferGeometry.index; + geometry.attributes.position = bufferGeometry.attributes.position; + geometry.attributes.uv = bufferGeometry.attributes.uv; + + positions = plot[1][] + # per instance data + offsets = instanced_attribute(jsscene, positions) + orientation = instanced_attribute(jsscene, rotations).setDynamic(true) + geometry.addAttribute("offset", offsets) + geometry.addAttribute("orientation", orientation) + + tex = create_tex(rand(RGB{Colors.N0f8}, 128, 128)) + material = create_material( + loadasset("particles.vert"), + loadasset("particles.frag"), + tex + ) + mesh = THREE.new.Mesh(geometry, material) + jsscene.add(mesh) + +end +using JSExpr: jsexpr +x = js_display(meshscatter(rand(Point3f0, 10), rotations = rand(Quaternionf0, 10))); diff --git a/test/runtests.jl b/test/runtests.jl index 3c448542304..e73893ea64e 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -7,6 +7,64 @@ r = range(0, stop=5pi, length=100) s = lines(r, sin.(r), linewidth = 3) d, w = js_display(s); + + + + + three.js webgl - indexed instancing (single box), dynamic updates + + + + + + +
+
+ three.js - indexed instancing (single box), dynamic updates + +
+ + + + + + + - - - - -

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΍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 0.0){ + float lolz = (f_scale.x+f_scale.y); + float outside = (abs(signed_distance)-f_scale.x)/f_scale.y; + float alpha = 1-outside; + color = mix(vec4(glowcolor.rgb, glowcolor.a*alpha), color, inside); + } +} + +float get_distancefield(sampler2D distancefield, vec2 uv){ + return -texture(distancefield, uv).r; +} +float get_distancefield(Nothing distancefield, vec2 uv){ + return 0.0; +} + +void write2framebuffer(vec4 color, uvec2 id); + +void main(){ + + float signed_distance = 0.0; + + if(shape == CIRCLE) + signed_distance = circle(f_uv); + else if(shape == DISTANCEFIELD) + signed_distance = get_distancefield(distancefield, f_uv_offset); + else if(shape == ROUNDED_RECTANGLE) + signed_distance = rounded_rectangle(f_uv, vec2(0.2), vec2(0.8)); + else if(shape == RECTANGLE) + signed_distance = rectangle(f_uv); + else if(shape == TRIANGLE) + signed_distance = triangle(f_uv); + + float half_stroke = -f_scale.x; + float inside_start = max(half_stroke, 0.0); + float inside = aastep(inside_start, signed_distance); + vec4 final_color = f_bg_color; + + fill(f_color, image, f_uv_offset, inside, final_color); + stroke(f_stroke_color, signed_distance, half_stroke, final_color); + glow(f_glow_color, signed_distance, aastep(-f_scale.x, signed_distance), final_color); + write2framebuffer(final_color, f_id); +} diff --git a/src/GLVisualize/assets/shader/dots.frag b/src/GLVisualize/assets/shader/dots.frag new file mode 100644 index 00000000000..4f08d9a57fe --- /dev/null +++ b/src/GLVisualize/assets/shader/dots.frag @@ -0,0 +1,10 @@ +{{GLSL_VERSION}} + +flat in vec4 o_color; +flat in uvec2 o_objectid; + +void write2framebuffer(vec4 color, uvec2 id); + +void main(){ + write2framebuffer(o_color, o_objectid); +} diff --git a/src/GLVisualize/assets/shader/dots.vert b/src/GLVisualize/assets/shader/dots.vert new file mode 100644 index 00000000000..318e8342ea4 --- /dev/null +++ b/src/GLVisualize/assets/shader/dots.vert @@ -0,0 +1,40 @@ +{{GLSL_VERSION}} + +struct Nothing{ //Nothing type, to encode if some variable doesn't contain any data + bool _; //empty structs are not allowed +}; + +{{vertex_type}} vertex; +{{color_type}} color; +{{intensity_type}} intensity; +{{color_norm_type}} color_norm; +uniform uint objectid; + +flat out vec4 o_color; +flat out uvec2 o_objectid; + + +float _normalize(float val, float from, float to){return (val-from) / (to - from);} + +vec4 color_lookup(float intensity, sampler1D color_ramp, vec2 norm){ + return texture(color_ramp, _normalize(intensity, norm.x, norm.y)); +} +void colorize(vec3 color, Nothing intensity, Nothing color_norm){ + o_color = vec4(color, 1); +} +void colorize(vec4 color, Nothing intensity, Nothing color_norm){ + o_color = color; +} +void colorize(sampler1D color, float intensity, vec2 color_norm){ + o_color = color_lookup(intensity, color, color_norm); +} +vec4 _position(vec3 p){return vec4(p,1);} +vec4 _position(vec2 p){return vec4(p,0,1);} + +uniform mat4 projectionview, model; + +void main(){ + colorize(color, intensity, color_norm); + o_objectid = uvec2(objectid, gl_VertexID+1); + gl_Position = projectionview*model*_position(vertex); +} diff --git a/src/GLVisualize/assets/shader/fragment_output.frag b/src/GLVisualize/assets/shader/fragment_output.frag new file mode 100644 index 00000000000..967cb0c4c00 --- /dev/null +++ b/src/GLVisualize/assets/shader/fragment_output.frag @@ -0,0 +1,9 @@ +{{GLSL_VERSION}} + +layout(location=0) out vec4 fragment_color; +layout(location=1) out uvec2 fragment_groupid; + +void write2framebuffer(vec4 color, uvec2 id){ + fragment_color = color; + fragment_groupid = id; +} diff --git a/src/GLVisualize/assets/shader/fullscreen.vert b/src/GLVisualize/assets/shader/fullscreen.vert new file mode 100644 index 00000000000..aba2c5e9b95 --- /dev/null +++ b/src/GLVisualize/assets/shader/fullscreen.vert @@ -0,0 +1,15 @@ +{{GLSL_VERSION}} + +out vec2 frag_uv; + +void main() { + vec2 uv = vec2(0,0); + if((gl_VertexID & 1) != 0) + uv.x = 1; + if((gl_VertexID & 2) != 0) + uv.y = 1; + + frag_uv = uv * 2; + gl_Position.xy = (uv * 4) - 1; + gl_Position.zw = vec2(0,1); +} diff --git a/src/GLVisualize/assets/shader/fxaa.frag b/src/GLVisualize/assets/shader/fxaa.frag new file mode 100644 index 00000000000..9b590b3958d --- /dev/null +++ b/src/GLVisualize/assets/shader/fxaa.frag @@ -0,0 +1,1049 @@ +{{GLSL_VERSION}} + +#define FXAA_PC 1 +#define FXAA_GLSL_130 1 +#define FXAA_QUALITY__PRESET 12 +#define FXAA_GREEN_AS_LUMA 0 +#define FXAA_GATHER4_ALPHA 0 +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_PC_CONSOLE + // + // The console algorithm for PC is included + // for developers targeting really low spec machines. + // Likely better to just run FXAA_PC, and use a really low preset. + // + #define FXAA_PC_CONSOLE 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GLSL_120 + #define FXAA_GLSL_120 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GLSL_130 + #define FXAA_GLSL_130 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_3 + #define FXAA_HLSL_3 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_4 + #define FXAA_HLSL_4 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_5 + #define FXAA_HLSL_5 0 +#endif +/*==========================================================================*/ +#ifndef FXAA_GREEN_AS_LUMA + // + // For those using non-linear color, + // and either not able to get luma in alpha, or not wanting to, + // this enables FXAA to run using green as a proxy for luma. + // So with this enabled, no need to pack luma in alpha. + // + // This will turn off AA on anything which lacks some amount of green. + // Pure red and blue or combination of only R and B, will get no AA. + // + // Might want to lower the settings for both, + // fxaaConsoleEdgeThresholdMin + // fxaaQualityEdgeThresholdMin + // In order to insure AA does not get turned off on colors + // which contain a minor amount of green. + // + // 1 = On. + // 0 = Off. + // + #define FXAA_GREEN_AS_LUMA 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_EARLY_EXIT + // + // Controls algorithm's early exit path. + // On PS3 turning this ON adds 2 cycles to the shader. + // On 360 turning this OFF adds 10ths of a millisecond to the shader. + // Turning this off on console will result in a more blurry image. + // So this defaults to on. + // + // 1 = On. + // 0 = Off. + // + #define FXAA_EARLY_EXIT 1 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_DISCARD + // + // Only valid for PC OpenGL currently. + // Probably will not work when FXAA_GREEN_AS_LUMA = 1. + // + // 1 = Use discard on pixels which don't need AA. + // For APIs which enable concurrent TEX+ROP from same surface. + // 0 = Return unchanged color on pixels which don't need AA. + // + #define FXAA_DISCARD 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_FAST_PIXEL_OFFSET + // + // Used for GLSL 120 only. + // + // 1 = GL API supports fast pixel offsets + // 0 = do not use fast pixel offsets + // + #ifdef GL_EXT_gpu_shader4 + #define FXAA_FAST_PIXEL_OFFSET 1 + #endif + #ifdef GL_NV_gpu_shader5 + #define FXAA_FAST_PIXEL_OFFSET 1 + #endif + #ifdef GL_ARB_gpu_shader5 + #define FXAA_FAST_PIXEL_OFFSET 1 + #endif + #ifndef FXAA_FAST_PIXEL_OFFSET + #define FXAA_FAST_PIXEL_OFFSET 0 + #endif +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GATHER4_ALPHA + // + // 1 = API supports gather4 on alpha channel. + // 0 = API does not support gather4 on alpha channel. + // + #if (FXAA_HLSL_5 == 1) + #define FXAA_GATHER4_ALPHA 1 + #endif + #ifdef GL_ARB_gpu_shader5 + #define FXAA_GATHER4_ALPHA 1 + #endif + #ifdef GL_NV_gpu_shader5 + #define FXAA_GATHER4_ALPHA 1 + #endif + #ifndef FXAA_GATHER4_ALPHA + #define FXAA_GATHER4_ALPHA 0 + #endif +#endif + + +/*============================================================================ + FXAA QUALITY - TUNING KNOBS +------------------------------------------------------------------------------ +NOTE the other tuning knobs are now in the shader function inputs! +============================================================================*/ +#ifndef FXAA_QUALITY__PRESET + // + // Choose the quality preset. + // This needs to be compiled into the shader as it effects code. + // Best option to include multiple presets is to + // in each shader define the preset, then include this file. + // + // OPTIONS + // ----------------------------------------------------------------------- + // 10 to 15 - default medium dither (10=fastest, 15=highest quality) + // 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality) + // 39 - no dither, very expensive + // + // NOTES + // ----------------------------------------------------------------------- + // 12 = slightly faster then FXAA 3.9 and higher edge quality (default) + // 13 = about same speed as FXAA 3.9 and better than 12 + // 23 = closest to FXAA 3.9 visually and performance wise + // _ = the lowest digit is directly related to performance + // _ = the highest digit is directly related to style + // + #define FXAA_QUALITY__PRESET 12 +#endif + + +/*============================================================================ + + FXAA QUALITY - PRESETS + +============================================================================*/ + +/*============================================================================ + FXAA QUALITY - MEDIUM DITHER PRESETS +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 10) + #define FXAA_QUALITY__PS 3 + #define FXAA_QUALITY__P0 1.5 + #define FXAA_QUALITY__P1 3.0 + #define FXAA_QUALITY__P2 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 11) + #define FXAA_QUALITY__PS 4 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 3.0 + #define FXAA_QUALITY__P3 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 12) + #define FXAA_QUALITY__PS 5 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 4.0 + #define FXAA_QUALITY__P4 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 13) + #define FXAA_QUALITY__PS 6 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 4.0 + #define FXAA_QUALITY__P5 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 14) + #define FXAA_QUALITY__PS 7 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 4.0 + #define FXAA_QUALITY__P6 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 15) + #define FXAA_QUALITY__PS 8 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 4.0 + #define FXAA_QUALITY__P7 12.0 +#endif + +/*============================================================================ + FXAA QUALITY - LOW DITHER PRESETS +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 20) + #define FXAA_QUALITY__PS 3 + #define FXAA_QUALITY__P0 1.5 + #define FXAA_QUALITY__P1 2.0 + #define FXAA_QUALITY__P2 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 21) + #define FXAA_QUALITY__PS 4 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 22) + #define FXAA_QUALITY__PS 5 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 23) + #define FXAA_QUALITY__PS 6 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 24) + #define FXAA_QUALITY__PS 7 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 3.0 + #define FXAA_QUALITY__P6 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 25) + #define FXAA_QUALITY__PS 8 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 4.0 + #define FXAA_QUALITY__P7 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 26) + #define FXAA_QUALITY__PS 9 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 4.0 + #define FXAA_QUALITY__P8 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 27) + #define FXAA_QUALITY__PS 10 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 4.0 + #define FXAA_QUALITY__P9 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 28) + #define FXAA_QUALITY__PS 11 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 2.0 + #define FXAA_QUALITY__P9 4.0 + #define FXAA_QUALITY__P10 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 29) + #define FXAA_QUALITY__PS 12 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 2.0 + #define FXAA_QUALITY__P9 2.0 + #define FXAA_QUALITY__P10 4.0 + #define FXAA_QUALITY__P11 8.0 +#endif + +/*============================================================================ + FXAA QUALITY - EXTREME QUALITY +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 39) + #define FXAA_QUALITY__PS 12 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.0 + #define FXAA_QUALITY__P2 1.0 + #define FXAA_QUALITY__P3 1.0 + #define FXAA_QUALITY__P4 1.0 + #define FXAA_QUALITY__P5 1.5 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 2.0 + #define FXAA_QUALITY__P9 2.0 + #define FXAA_QUALITY__P10 4.0 + #define FXAA_QUALITY__P11 8.0 +#endif + + + +/*============================================================================ + + API PORTING + +============================================================================*/ +#if (FXAA_GLSL_120 == 1) || (FXAA_GLSL_130 == 1) + #define FxaaBool bool + #define FxaaDiscard discard + #define FxaaFloat float + #define FxaaFloat2 vec2 + #define FxaaFloat3 vec3 + #define FxaaFloat4 vec4 + #define FxaaHalf float + #define FxaaHalf2 vec2 + #define FxaaHalf3 vec3 + #define FxaaHalf4 vec4 + #define FxaaInt2 ivec2 + #define FxaaSat(x) clamp(x, 0.0, 1.0) + #define FxaaTex sampler2D +#else + #define FxaaBool bool + #define FxaaDiscard clip(-1) + #define FxaaFloat float + #define FxaaFloat2 float2 + #define FxaaFloat3 float3 + #define FxaaFloat4 float4 + #define FxaaHalf half + #define FxaaHalf2 half2 + #define FxaaHalf3 half3 + #define FxaaHalf4 half4 + #define FxaaSat(x) saturate(x) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_GLSL_120 == 1) + // Requires, + // #version 120 + // And at least, + // #extension GL_EXT_gpu_shader4 : enable + // (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9) + #define FxaaTexTop(t, p) texture2DLod(t, p, 0.0) + #if (FXAA_FAST_PIXEL_OFFSET == 1) + #define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o) + #else + #define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0) + #endif + #if (FXAA_GATHER4_ALPHA == 1) + // use #extension GL_ARB_gpu_shader5 : enable + #define FxaaTexAlpha4(t, p) textureGather(t, p, 3) + #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3) + #define FxaaTexGreen4(t, p) textureGather(t, p, 1) + #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1) + #endif +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_GLSL_130 == 1) + // Requires "#version 130" or better + #define FxaaTexTop(t, p) textureLod(t, p, 0.0) + #define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o) + #if (FXAA_GATHER4_ALPHA == 1) + // use #extension GL_ARB_gpu_shader5 : enable + #define FxaaTexAlpha4(t, p) textureGather(t, p, 3) + #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3) + #define FxaaTexGreen4(t, p) textureGather(t, p, 1) + #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1) + #endif +#endif +/*--------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_5 == 1) + #define FxaaInt2 int2 + struct FxaaTex { SamplerState smpl; Texture2D tex; }; + #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0) + #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o) + #define FxaaTexAlpha4(t, p) t.tex.GatherAlpha(t.smpl, p) + #define FxaaTexOffAlpha4(t, p, o) t.tex.GatherAlpha(t.smpl, p, o) + #define FxaaTexGreen4(t, p) t.tex.GatherGreen(t.smpl, p) + #define FxaaTexOffGreen4(t, p, o) t.tex.GatherGreen(t.smpl, p, o) +#endif + + +/*============================================================================ + GREEN AS LUMA OPTION SUPPORT FUNCTION +============================================================================*/ +#if (FXAA_GREEN_AS_LUMA == 0) + FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.a; } +#else + FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; } +#endif + + + + +/*============================================================================ + + FXAA3 QUALITY - PC + +============================================================================*/ +#if (FXAA_PC == 1) +/*--------------------------------------------------------------------------*/ +FxaaFloat4 FxaaPixelShader( + // + // Use noperspective interpolation here (turn off perspective interpolation). + // {xy} = center of pixel + FxaaFloat2 pos, + // + // Used only for FXAA Console, and not used on the 360 version. + // Use noperspective interpolation here (turn off perspective interpolation). + // {xy__} = upper left of pixel + // {__zw} = lower right of pixel + FxaaFloat4 fxaaConsolePosPos, + // + // Input color texture. + // {rgb_} = color in linear or perceptual color space + // if (FXAA_GREEN_AS_LUMA == 0) + // {___a} = luma in perceptual color space (not linear) + FxaaTex tex, + // + // Only used on the optimized 360 version of FXAA Console. + // For everything but 360, just use the same input here as for "tex". + // For 360, same texture, just alias with a 2nd sampler. + // This sampler needs to have an exponent bias of -1. + FxaaTex fxaaConsole360TexExpBiasNegOne, + // + // Only used on the optimized 360 version of FXAA Console. + // For everything but 360, just use the same input here as for "tex". + // For 360, same texture, just alias with a 3nd sampler. + // This sampler needs to have an exponent bias of -2. + FxaaTex fxaaConsole360TexExpBiasNegTwo, + // + // Only used on FXAA Quality. + // This must be from a constant/uniform. + // {x_} = 1.0/screenWidthInPixels + // {_y} = 1.0/screenHeightInPixels + FxaaFloat2 fxaaQualityRcpFrame, + // + // Only used on FXAA Console. + // This must be from a constant/uniform. + // This effects sub-pixel AA quality and inversely sharpness. + // Where N ranges between, + // N = 0.50 (default) + // N = 0.33 (sharper) + // {x___} = -N/screenWidthInPixels + // {_y__} = -N/screenHeightInPixels + // {__z_} = N/screenWidthInPixels + // {___w} = N/screenHeightInPixels + FxaaFloat4 fxaaConsoleRcpFrameOpt, + // + // Only used on FXAA Console. + // Not used on 360, but used on PS3 and PC. + // This must be from a constant/uniform. + // {x___} = -2.0/screenWidthInPixels + // {_y__} = -2.0/screenHeightInPixels + // {__z_} = 2.0/screenWidthInPixels + // {___w} = 2.0/screenHeightInPixels + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + // + // Only used on FXAA Console. + // Only used on 360 in place of fxaaConsoleRcpFrameOpt2. + // This must be from a constant/uniform. + // {x___} = 8.0/screenWidthInPixels + // {_y__} = 8.0/screenHeightInPixels + // {__z_} = -4.0/screenWidthInPixels + // {___w} = -4.0/screenHeightInPixels + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__SUBPIX define. + // It is here now to allow easier tuning. + // Choose the amount of sub-pixel aliasing removal. + // This can effect sharpness. + // 1.00 - upper limit (softer) + // 0.75 - default amount of filtering + // 0.50 - lower limit (sharper, less sub-pixel aliasing removal) + // 0.25 - almost off + // 0.00 - completely off + FxaaFloat fxaaQualitySubpix, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD define. + // It is here now to allow easier tuning. + // The minimum amount of local contrast required to apply algorithm. + // 0.333 - too little (faster) + // 0.250 - low quality + // 0.166 - default + // 0.125 - high quality + // 0.063 - overkill (slower) + FxaaFloat fxaaQualityEdgeThreshold, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD_MIN define. + // It is here now to allow easier tuning. + // Trims the algorithm from processing darks. + // 0.0833 - upper limit (default, the start of visible unfiltered edges) + // 0.0625 - high quality (faster) + // 0.0312 - visible limit (slower) + // Special notes when using FXAA_GREEN_AS_LUMA, + // Likely want to set this to zero. + // As colors that are mostly not-green + // will appear very dark in the green channel! + // Tune by looking at mostly non-green content, + // then start at zero and increase until aliasing is a problem. + FxaaFloat fxaaQualityEdgeThresholdMin, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define. + // It is here now to allow easier tuning. + // This does not effect PS3, as this needs to be compiled in. + // Use FXAA_CONSOLE__PS3_EDGE_SHARPNESS for PS3. + // Due to the PS3 being ALU bound, + // there are only three safe values here: 2 and 4 and 8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // For all other platforms can be a non-power of two. + // 8.0 is sharper (default!!!) + // 4.0 is softer + // 2.0 is really soft (good only for vector graphics inputs) + FxaaFloat fxaaConsoleEdgeSharpness, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD define. + // It is here now to allow easier tuning. + // This does not effect PS3, as this needs to be compiled in. + // Use FXAA_CONSOLE__PS3_EDGE_THRESHOLD for PS3. + // Due to the PS3 being ALU bound, + // there are only two safe values here: 1/4 and 1/8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // The console setting has a different mapping than the quality setting. + // Other platforms can use other values. + // 0.125 leaves less aliasing, but is softer (default!!!) + // 0.25 leaves more aliasing, and is sharper + FxaaFloat fxaaConsoleEdgeThreshold, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD_MIN define. + // It is here now to allow easier tuning. + // Trims the algorithm from processing darks. + // The console setting has a different mapping than the quality setting. + // This only applies when FXAA_EARLY_EXIT is 1. + // This does not apply to PS3, + // PS3 was simplified to avoid more shader instructions. + // 0.06 - faster but more aliasing in darks + // 0.05 - default + // 0.04 - slower and less aliasing in darks + // Special notes when using FXAA_GREEN_AS_LUMA, + // Likely want to set this to zero. + // As colors that are mostly not-green + // will appear very dark in the green channel! + // Tune by looking at mostly non-green content, + // then start at zero and increase until aliasing is a problem. + FxaaFloat fxaaConsoleEdgeThresholdMin, + // + // Extra constants for 360 FXAA Console only. + // Use zeros or anything else for other platforms. + // These must be in physical constant registers and NOT immedates. + // Immedates will result in compiler un-optimizing. + // {xyzw} = float4(1.0, -1.0, 0.25, -0.25) + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ + FxaaFloat2 posM; + posM.x = pos.x; + posM.y = pos.y; + #if (FXAA_GATHER4_ALPHA == 1) + #if (FXAA_DISCARD == 0) + FxaaFloat4 rgbyM = FxaaTexTop(tex, posM); + #if (FXAA_GREEN_AS_LUMA == 0) + #define lumaM rgbyM.w + #else + #define lumaM rgbyM.y + #endif + #endif + #if (FXAA_GREEN_AS_LUMA == 0) + FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM); + FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1)); + #else + FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM); + FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1)); + #endif + #if (FXAA_DISCARD == 1) + #define lumaM luma4A.w + #endif + #define lumaE luma4A.z + #define lumaS luma4A.x + #define lumaSE luma4A.y + #define lumaNW luma4B.w + #define lumaN luma4B.z + #define lumaW luma4B.x + #else + FxaaFloat4 rgbyM = FxaaTexTop(tex, posM); + #if (FXAA_GREEN_AS_LUMA == 0) + #define lumaM rgbyM.w + #else + #define lumaM rgbyM.y + #endif + FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy)); + #endif +/*--------------------------------------------------------------------------*/ + FxaaFloat maxSM = max(lumaS, lumaM); + FxaaFloat minSM = min(lumaS, lumaM); + FxaaFloat maxESM = max(lumaE, maxSM); + FxaaFloat minESM = min(lumaE, minSM); + FxaaFloat maxWN = max(lumaN, lumaW); + FxaaFloat minWN = min(lumaN, lumaW); + FxaaFloat rangeMax = max(maxWN, maxESM); + FxaaFloat rangeMin = min(minWN, minESM); + FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold; + FxaaFloat range = rangeMax - rangeMin; + FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled); + FxaaBool earlyExit = range < rangeMaxClamped; +/*--------------------------------------------------------------------------*/ + if(earlyExit) + #if (FXAA_DISCARD == 1) + FxaaDiscard; + #else + return rgbyM; + #endif +/*--------------------------------------------------------------------------*/ + #if (FXAA_GATHER4_ALPHA == 0) + FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy)); + #else + FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy)); + #endif +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNS = lumaN + lumaS; + FxaaFloat lumaWE = lumaW + lumaE; + FxaaFloat subpixRcpRange = 1.0/range; + FxaaFloat subpixNSWE = lumaNS + lumaWE; + FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS; + FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE; +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNESE = lumaNE + lumaSE; + FxaaFloat lumaNWNE = lumaNW + lumaNE; + FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE; + FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE; +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNWSW = lumaNW + lumaSW; + FxaaFloat lumaSWSE = lumaSW + lumaSE; + FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2); + FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2); + FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW; + FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE; + FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4; + FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4; +/*--------------------------------------------------------------------------*/ + FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE; + FxaaFloat lengthSign = fxaaQualityRcpFrame.x; + FxaaBool horzSpan = edgeHorz >= edgeVert; + FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE; +/*--------------------------------------------------------------------------*/ + if(!horzSpan) lumaN = lumaW; + if(!horzSpan) lumaS = lumaE; + if(horzSpan) lengthSign = fxaaQualityRcpFrame.y; + FxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM; +/*--------------------------------------------------------------------------*/ + FxaaFloat gradientN = lumaN - lumaM; + FxaaFloat gradientS = lumaS - lumaM; + FxaaFloat lumaNN = lumaN + lumaM; + FxaaFloat lumaSS = lumaS + lumaM; + FxaaBool pairN = abs(gradientN) >= abs(gradientS); + FxaaFloat gradient = max(abs(gradientN), abs(gradientS)); + if(pairN) lengthSign = -lengthSign; + FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange); +/*--------------------------------------------------------------------------*/ + FxaaFloat2 posB; + posB.x = posM.x; + posB.y = posM.y; + FxaaFloat2 offNP; + offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x; + offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y; + if(!horzSpan) posB.x += lengthSign * 0.5; + if( horzSpan) posB.y += lengthSign * 0.5; +/*--------------------------------------------------------------------------*/ + FxaaFloat2 posN; + posN.x = posB.x - offNP.x * FXAA_QUALITY__P0; + posN.y = posB.y - offNP.y * FXAA_QUALITY__P0; + FxaaFloat2 posP; + posP.x = posB.x + offNP.x * FXAA_QUALITY__P0; + posP.y = posB.y + offNP.y * FXAA_QUALITY__P0; + FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0; + FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN)); + FxaaFloat subpixE = subpixC * subpixC; + FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP)); +/*--------------------------------------------------------------------------*/ + if(!pairN) lumaNN = lumaSS; + FxaaFloat gradientScaled = gradient * 1.0/4.0; + FxaaFloat lumaMM = lumaM - lumaNN * 0.5; + FxaaFloat subpixF = subpixD * subpixE; + FxaaBool lumaMLTZero = lumaMM < 0.0; +/*--------------------------------------------------------------------------*/ + lumaEndN -= lumaNN * 0.5; + lumaEndP -= lumaNN * 0.5; + FxaaBool doneN = abs(lumaEndN) >= gradientScaled; + FxaaBool doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P1; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P1; + FxaaBool doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P1; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P1; +/*--------------------------------------------------------------------------*/ + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P2; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P2; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P2; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P2; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 3) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P3; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P3; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P3; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P3; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 4) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P4; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P4; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P4; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P4; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 5) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P5; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P5; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P5; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P5; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 6) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P6; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P6; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P6; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P6; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 7) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P7; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P7; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P7; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P7; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 8) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P8; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P8; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P8; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P8; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 9) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P9; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P9; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P9; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P9; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 10) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P10; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P10; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P10; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P10; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 11) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P11; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P11; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P11; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P11; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 12) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P12; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P12; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P12; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P12; +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } +/*--------------------------------------------------------------------------*/ + FxaaFloat dstN = posM.x - posN.x; + FxaaFloat dstP = posP.x - posM.x; + if(!horzSpan) dstN = posM.y - posN.y; + if(!horzSpan) dstP = posP.y - posM.y; +/*--------------------------------------------------------------------------*/ + FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero; + FxaaFloat spanLength = (dstP + dstN); + FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero; + FxaaFloat spanLengthRcp = 1.0/spanLength; +/*--------------------------------------------------------------------------*/ + FxaaBool directionN = dstN < dstP; + FxaaFloat dst = min(dstN, dstP); + FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP; + FxaaFloat subpixG = subpixF * subpixF; + FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5; + FxaaFloat subpixH = subpixG * fxaaQualitySubpix; +/*--------------------------------------------------------------------------*/ + FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0; + FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH); + if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign; + if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign; + #if (FXAA_DISCARD == 1) + return FxaaTexTop(tex, posM); + #else + return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM); + #endif +} +/*==========================================================================*/ +#endif + + + + +//---------------------------------------------------------------------------------- +// File: es3-kepler/FXAA/assets/shaders/FXAA_Extreme_Quality.frag +// SDK Version: v2.11 +// Email: gameworks@nvidia.com +// Site: http://developer.nvidia.com/ +// +// Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//---------------------------------------------------------------------------------- + +precision highp float; + +uniform sampler2D color_texture; +uniform vec2 RCPFrame; +in vec2 frag_uv; + +out vec4 fragment_color; + +void main(void) +{ + // fragment_color = texture(color_texture, frag_uv); + fragment_color.rgb = FxaaPixelShader( + frag_uv, + FxaaFloat4(0.0f, 0.0f, 0.0f, 0.0f), // FxaaFloat4 fxaaConsolePosPos, + color_texture, // FxaaTex tex, + color_texture, // FxaaTex fxaaConsole360TexExpBiasNegOne, + color_texture, // FxaaTex fxaaConsole360TexExpBiasNegTwo, + RCPFrame, // FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4(0.0f, 0.0f, 0.0f, 0.0f), // FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4(0.0f, 0.0f, 0.0f, 0.0f), // FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4(0.0f, 0.0f, 0.0f, 0.0f), // FxaaFloat4 fxaaConsole360RcpFrameOpt2, + 0.75f, // FxaaFloat fxaaQualitySubpix, + 0.166f, // FxaaFloat fxaaQualityEdgeThreshold, + 0.0833f, // FxaaFloat fxaaQualityEdgeThresholdMin, + 0.0f, // FxaaFloat fxaaConsoleEdgeSharpness, + 0.0f, // FxaaFloat fxaaConsoleEdgeThreshold, + 0.0f, // FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4(0.0f, 0.0f, 0.0f, 0.0f) // FxaaFloat fxaaConsole360ConstDir, + ).rgb; +} diff --git a/src/GLVisualize/assets/shader/intensity.frag b/src/GLVisualize/assets/shader/intensity.frag new file mode 100644 index 00000000000..79ed1297991 --- /dev/null +++ b/src/GLVisualize/assets/shader/intensity.frag @@ -0,0 +1,46 @@ +{{GLSL_VERSION}} + +in vec2 o_uv; +flat in uvec2 o_objectid; + +{{intensity_type}} intensity; +uniform sampler1D color_map; +uniform vec2 color_norm; +uniform float stroke_width; +uniform vec4 stroke_color; +uniform float levels; + +vec4 getindex(sampler2D image, vec2 uv){return texture(image, vec2(uv.x, 1-uv.y));} +vec4 getindex(sampler1D image, vec2 uv){return texture(image, uv.y);} +float _normalize(float val, float from, float to){return (val-from) / (to - from);} + +vec4 color_lookup(float intensity, sampler1D color_ramp, vec2 norm){ + return texture(color_ramp, _normalize(intensity, norm.x, norm.y)); +} +#define ALIASING_CONST 0.70710678118654757 +#define M_PI 3.1415926535897932384626433832795 +float aastep(float threshold1, float threshold2, float value) { + float afwidth = length(vec2(dFdx(value), dFdy(value))) * ALIASING_CONST; + return smoothstep(threshold1-afwidth, threshold1+afwidth, value)-smoothstep(threshold2-afwidth, threshold2+afwidth, value); +} +float aastep(float threshold1, float value) { + float afwidth = length(vec2(dFdx(value), dFdy(value))) * ALIASING_CONST; + return smoothstep(threshold1-afwidth, threshold1+afwidth, value); +} +void write2framebuffer(vec4 color, uvec2 id); + +void main(){ + float i = float(getindex(intensity, o_uv).x); + vec4 color; + if(isnan(i)){ + color = vec4(0); + }else{ + i = _normalize(i, color_norm.x, color_norm.y); + float lines = i*levels; + lines = abs(fract(lines-0.5)); + float half_stroke = stroke_width*0.5; + lines = aastep(0.5 - half_stroke, 0.5 + half_stroke, lines); + color = mix(texture(color_map, i), stroke_color, lines); + } + write2framebuffer(color, uvec2(o_objectid.x, 0)); +} diff --git a/src/GLVisualize/assets/shader/line_segment.geom b/src/GLVisualize/assets/shader/line_segment.geom new file mode 100644 index 00000000000..3cd09ad34ad --- /dev/null +++ b/src/GLVisualize/assets/shader/line_segment.geom @@ -0,0 +1,62 @@ +{{GLSL_VERSION}} +{{GLSL_EXTENSIONS}} + +layout(lines) in; +layout(triangle_strip, max_vertices = 4) out; + +uniform vec2 resolution; +uniform float maxlength; +uniform float thickness; +uniform float pattern_length; + +in vec4 g_color[]; +in uvec2 g_id[]; +in float g_thickness[]; + +out float f_thickness; +out vec4 f_color; +out vec2 f_uv; +flat out uvec2 f_id; + +#define AA_THICKNESS 2.0 + +vec2 screen_space(vec4 vertex) +{ + return vec2(vertex.xy / vertex.w)*resolution; +} +void emit_vertex(vec2 position, vec2 uv, int index) +{ + vec4 inpos = gl_in[index].gl_Position; + f_uv = uv; + f_color = g_color[index]; + gl_Position = vec4((position / resolution) * inpos.w, inpos.z, inpos.w); + f_id = g_id[index]; + f_thickness = g_thickness[index]+AA_THICKNESS; + EmitVertex(); +} + +uniform int max_primtives; + +void main(void) +{ + // get the four vertices passed to the shader: + vec2 p0 = screen_space(gl_in[0].gl_Position); // start of previous segment + vec2 p1 = screen_space(gl_in[1].gl_Position); // end of previous segment, start of current segment + + float thickness_aa0 = g_thickness[0]+AA_THICKNESS; + float thickness_aa1 = g_thickness[1]+AA_THICKNESS; + // determine the direction of each of the 3 segments (previous, current, next) + vec2 vun0 = p1 - p0; + vec2 v0 = normalize(vun0); + // determine the normal of each of the 3 segments (previous, current, next) + vec2 n0 = vec2(-v0.y, v0.x); + float l = length(p1-p0); + l /= (pattern_length*10); + + float uv0 = thickness_aa0/g_thickness[0]; + float uv1 = thickness_aa1/g_thickness[1]; + emit_vertex(p0 + thickness_aa0 * n0, vec2(0, -uv0), 0); + emit_vertex(p0 - thickness_aa0 * n0, vec2(0, uv0), 0); + emit_vertex(p1 + thickness_aa1 * n0, vec2(l, -uv1), 1); + emit_vertex(p1 - thickness_aa1 * n0, vec2(l, uv1), 1); +} diff --git a/src/GLVisualize/assets/shader/line_segment.vert b/src/GLVisualize/assets/shader/line_segment.vert new file mode 100644 index 00000000000..e9c432fdc34 --- /dev/null +++ b/src/GLVisualize/assets/shader/line_segment.vert @@ -0,0 +1,29 @@ +{{GLSL_VERSION}} +{{GLSL_EXTENSIONS}} + +{{vertex_type}} vertex; +{{color_type}} color; +{{thickness_type}} thickness; + +uniform mat4 projection, view, model; +uniform uint objectid; + +out uvec2 g_id; +out vec4 g_color; +out float g_thickness; + +vec4 getindex(sampler2D tex, int index); +vec4 getindex(sampler1D tex, int index); + +vec4 to_vec4(vec3 v){return vec4(v, 1);} +vec4 to_vec4(vec2 v){return vec4(v, 0, 1);} + + +void main() +{ + int index = gl_VertexID; + g_id = uvec2(objectid, index+1); + g_color = {{color_calculation}}; + g_thickness = thickness; + gl_Position = projection*view*model*to_vec4(vertex); +} diff --git a/src/GLVisualize/assets/shader/lines.frag b/src/GLVisualize/assets/shader/lines.frag new file mode 100644 index 00000000000..fd8e569025a --- /dev/null +++ b/src/GLVisualize/assets/shader/lines.frag @@ -0,0 +1,49 @@ +{{GLSL_VERSION}} +{{GLSL_EXTENSIONS}} +{{SUPPORTED_EXTENSIONS}} + +struct Nothing{ //Nothing type, to encode if some variable doesn't contain any data + bool _; //empty structs are not allowed +}; + +in vec4 f_color; +in vec2 f_uv; +in float f_thickness; +flat in uvec2 f_id; +{{pattern_type}} pattern; + +uniform float pattern_length; + +const float ALIASING_CONST = 0.9; + +float aastep(float threshold1, float value) { + float afwidth = length(vec2(dFdx(value), dFdy(value))) * ALIASING_CONST; + return smoothstep(threshold1-afwidth, threshold1+afwidth, value); +} +float aastep(float threshold1, float threshold2, float value) { + float afwidth = length(vec2(dFdx(value), dFdy(value))) * ALIASING_CONST; + return smoothstep(threshold1-afwidth, threshold1+afwidth, value)-smoothstep(threshold2-afwidth, threshold2+afwidth, value); +} +void write2framebuffer(vec4 color, uvec2 id); + +// x/y pattern +float get_sd(sampler2D pattern, vec2 uv){ + return texture(pattern, uv).x; +} +uniform float maxlength; +// x pattern +vec2 get_sd(sampler1D pattern, vec2 uv){ + return vec2(texture(pattern, uv.x).x, uv.y); +} +// normal line type +vec2 get_sd(Nothing _, vec2 uv){ + return vec2(0.5, uv.y); +} + +void main(){ + vec2 xy = get_sd(pattern, f_uv); + float alpha = aastep(0, xy.x); + float alpha2 = aastep(-1, 1, xy.y); + vec4 color = vec4(f_color.rgb, f_color.a*alpha*alpha2); + write2framebuffer(color, f_id); +} diff --git a/src/GLVisualize/assets/shader/lines.geom b/src/GLVisualize/assets/shader/lines.geom new file mode 100644 index 00000000000..1fbd5f12673 --- /dev/null +++ b/src/GLVisualize/assets/shader/lines.geom @@ -0,0 +1,177 @@ +// ------------------ Geometry Shader -------------------------------- +// This version of the line shader simply cuts off the corners and +// draws the line with no overdraw on neighboring segments at all +{{GLSL_VERSION}} +{{GLSL_EXTENSIONS}} + +layout(lines_adjacency) in; +layout(triangle_strip, max_vertices = 12) out; + +in vec4 g_color[]; +in float g_lastlen[]; +in uvec2 g_id[]; +in uint g_line_connections[]; +in int g_startend[]; +//in float g_thickness[]; + +out vec4 f_color; +out vec2 f_uv; +out float f_thickness; + +flat out uvec2 f_id; + +uniform vec2 resolution; +uniform float maxlength; +uniform float thickness; +uniform float pattern_length; + + +#define MITER_LIMIT 0.75 + +vec2 screen_space(vec4 vertex) +{ + return vec2(vertex.xy / vertex.w) * resolution; +} +void emit_vertex(vec2 position, vec2 uv, int index, float ratio) +{ + vec4 inpos = gl_in[index].gl_Position; + f_uv = vec2((g_lastlen[index] * ratio) / pattern_length / (thickness+4) / 2.0, uv.y); + f_color = g_color[index]; + gl_Position = vec4((position/resolution)*inpos.w, inpos.z, inpos.w); + f_id = g_id[index]; + f_thickness = thickness; + EmitVertex(); +} + +vec2 compute_miter(vec2 normal_a, vec2 normal_b) +{ + vec2 miter = normalize(normal_a + normal_b); + if(miter.x < 0.000001 && miter.y < 0.000001) + { + return vec2(-normal_a.y, normal_a.x); + } + return miter; +} + +uniform int max_primtives; +const float infinity = 1.0 / 0.0; + +void main(void) +{ + if( + g_line_connections[1] != g_line_connections[2] + ){ + return; // if there is a break in the line, we don't emit anything + } + // get the four vertices passed to the shader: + vec2 p0 = screen_space(gl_in[0].gl_Position); // start of previous segment + vec2 p1 = screen_space(gl_in[1].gl_Position); // end of previous segment, start of current segment + vec2 p2 = screen_space(gl_in[2].gl_Position); // end of current segment, start of next segment + vec2 p3 = screen_space(gl_in[3].gl_Position); // end of next segment + + + float thickness_aa = thickness+4; + + + // perform naive culling + //vec2 area = resolution * 1.2; + //if( p1.x < -area.x || p1.x > area.x ) return; + //if( p1.y < -area.y || p1.y > area.y ) return; + //if( p2.x < -area.x || p2.x > area.x ) return; + //if( p2.y < -area.y || p2.y > area.y ) return; + + // determine the direction of each of the 3 segments (previous, current, next) + vec2 v0 = normalize(p1 - p0); + vec2 v1 = normalize(p2 - p1); + vec2 v2 = normalize(p3 - p2); + + // determine the normal of each of the 3 segments (previous, current, next) + vec2 n0 = vec2(-v0.y, v0.x); + vec2 n1 = vec2(-v1.y, v1.x); + vec2 n2 = vec2(-v2.y, v2.x); + + // determine miter lines by averaging the normals of the 2 segments + vec2 miter_a = normalize(n0 + n1); // miter at start of current segment + vec2 miter_b = normalize(n1 + n2); // miter at end of current segment + + // determine the length of the miter by projecting it onto normal and then inverse it + float length_a = thickness_aa / dot(miter_a, n1); + float length_b = thickness_aa / dot(miter_b, n1); + + float xstart = g_lastlen[1]; + float xend = g_lastlen[2]; + + float ratio = length(p2 - p1) / (xend - xstart); + + /* + over 90 + v0 + / + / + . ------> v1 + under 90 + v + \ + \ + . ------> v1 + */ + bool over_90_deg = dot( v0, v1 ) < -MITER_LIMIT; + /* + n1 + gap true : gap false + v0 : + . ------> : + */ + bool gap = dot( v0, n1 ) > 0; + float uvy = thickness_aa/thickness; + if(over_90_deg){ + // close the gap + if(gap){ + if (g_startend[0] == 0){ + emit_vertex(p0 - thickness_aa * n0, vec2(1, uvy), 0, ratio); + emit_vertex(p0 + thickness_aa * n0, vec2(1, -uvy), 0, ratio); + emit_vertex(p1 + thickness_aa * n1, vec2(1, uvy), 1, ratio); + } + emit_vertex(p1 + thickness_aa * n0, vec2(1, -uvy), 1, ratio); + emit_vertex(p1 + thickness_aa * n1, vec2(1, -uvy), 1, ratio); + emit_vertex(p1, vec2(0, 0.0), 1, ratio); + EndPrimitive(); + }else{ + if (g_startend[0] == 0){ + emit_vertex(p0 + thickness_aa * n0, vec2(1, -uvy), 0, ratio); + emit_vertex(p0 - thickness_aa * n0, vec2(1, uvy), 0, ratio); + emit_vertex(p1 + length_a * miter_a, vec2(1, -uvy), 1, ratio); + } + emit_vertex(p1 - thickness_aa * n0, vec2(1, uvy), 1, ratio); + emit_vertex(p1, vec2(0, 0.0), 1, ratio); + emit_vertex(p1 - thickness_aa * n1, vec2(1, uvy), 1, ratio); + EndPrimitive(); + } + miter_a = n1; + length_a = thickness_aa; + }else if(g_startend[0] == 0){ + emit_vertex(p0 + thickness_aa * n0, vec2(1, -uvy), 0, ratio); + emit_vertex(p0 - thickness_aa * n0, vec2(1, uvy), 0, ratio); + } + + vec2 nc = n2; + if( dot( v1, v2 ) < -MITER_LIMIT ) { + miter_b = n1; + length_b = thickness_aa; + nc = -n2; + } + + // generate the triangle strip + + emit_vertex(p1 + length_a * miter_a, vec2( 0, -uvy), 1, ratio); + emit_vertex(p1 - length_a * miter_a, vec2( 0, uvy), 1, ratio); + + emit_vertex(p2 + length_b * miter_b, vec2( 0, -uvy ), 2, ratio); + emit_vertex(p2 - length_b * miter_b, vec2( 0, uvy), 2, ratio); + + if(g_startend[3] == 1) //last primitive + { + emit_vertex(p3 + (thickness_aa) * nc, vec2(0, -uvy), 3, ratio); + emit_vertex(p3 - (thickness_aa) * nc, vec2(0, uvy), 3, ratio); + } +} diff --git a/src/GLVisualize/assets/shader/lines.vert b/src/GLVisualize/assets/shader/lines.vert new file mode 100644 index 00000000000..33ba605e690 --- /dev/null +++ b/src/GLVisualize/assets/shader/lines.vert @@ -0,0 +1,53 @@ +{{GLSL_VERSION}} +{{GLSL_EXTENSIONS}} + +struct Nothing{ //Nothing type, to encode if some variable doesn't contain any data + bool _; //empty structs are not allowed +}; + +{{vertex_type}} vertex; + + +in float lastlen; +{{startend_type}} startend; + +{{color_type}} color; +{{color_map_type}} color_map; +{{intensity_type}} intensity; +{{color_norm_type}} color_norm; + +vec4 _color(vec3 color, Nothing intensity, Nothing color_map, Nothing color_norm, int index, int len); +vec4 _color(vec4 color, Nothing intensity, Nothing color_map, Nothing color_norm, int index, int len); +vec4 _color(Nothing color, float intensity, sampler1D color_map, vec2 color_norm, int index, int len); +vec4 _color(Nothing color, sampler1D intensity, sampler1D color_map, vec2 color_norm, int index, int len); + +uniform mat4 projection, view, model; +uniform uint objectid; +uniform ivec2 dims; + +out uvec2 g_id; +out vec4 g_color; +out float g_lastlen; +out int g_startend; +out uint g_line_connections; + +vec4 getindex(sampler2D tex, int index); +vec4 getindex(sampler1D tex, int index); + +vec4 to_vec4(vec3 v){return vec4(v, 1);} +vec4 to_vec4(vec2 v){return vec4(v, 0, 1);} + +int get_startend(float se){return int(se);} +int get_startend(Nothing se){return 2;} + + +void main() +{ + g_lastlen = lastlen; + int index = gl_VertexID; + g_id = uvec2(objectid, index+1); + g_startend = get_startend(startend); + g_color = _color(color, intensity, color_map, color_norm, index, dims.x*dims.y); + g_line_connections = uint(index/dims.x); + gl_Position = projection*view*model*to_vec4(vertex); +} diff --git a/src/GLVisualize/assets/shader/parametric.frag b/src/GLVisualize/assets/shader/parametric.frag new file mode 100644 index 00000000000..46e7f5ee292 --- /dev/null +++ b/src/GLVisualize/assets/shader/parametric.frag @@ -0,0 +1,54 @@ +{{GLSL_VERSION}} + +float rand(vec2 co){ + // implementation found at: lumina.sourceforge.net/Tutorials/Noise.html + return fract(sin(dot(co.xy, vec2(12.9898,78.233))) * 43758.5453); +} + +// Put your user defined function here... +{{function}} + +uniform float jitter = 1.0; +uniform float thickness = 2000; +uniform int samples = 8; + +in vec2 aa_scale; + + +float getalpha(vec2 pos) { + vec2 step = thickness*vec2(aa_scale.x,aa_scale.y)/samples; + float samples = float(samples); + int count = 0; + int mysamples = 0; + for (float i = 0.0; i < samples; i++) { + for (float j = 0.0;j < samples; j++) { + if (i*i+j*j>samples*samples) continue; + mysamples++; + float ii = i + jitter*rand(vec2(pos.x + i*step.x,pos.y + j*step.y)); + float jj = j + jitter*rand(vec2(pos.y + i*step.x,pos.x + j*step.y)); + float f = function(pos.x+ ii*step.x)-(pos.y+ jj*step.y); + count += (f>0.) ? 1 : -1; + } + } + if (abs(count)!=mysamples) return 1-abs(float(count))/float(mysamples); + return 0.0; +} + +in vec2 o_uv; +uniform vec4 color; + +void write2framebuffer(vec4 color, uvec2 id); + +void main() +{ + write2framebuffer( + vec4(color.rgb, color.a*getalpha(vec2(o_uv.x*5, o_uv.y))), + uvec2(0) + ); +} + + +/* +//note: shadertoy-pluggable, http://www.iquilezles.org/apps/shadertoy/ + +*/ diff --git a/src/GLVisualize/assets/shader/parametric.vert b/src/GLVisualize/assets/shader/parametric.vert new file mode 100644 index 00000000000..2e0e923af89 --- /dev/null +++ b/src/GLVisualize/assets/shader/parametric.vert @@ -0,0 +1,18 @@ +{{GLSL_VERSION}} + +in vec2 vertices; +in vec2 texturecoordinates; + +out vec2 o_uv; +out vec2 aa_scale; + +uniform vec2 resolution; +uniform float AntiAliasScale = 0.75; +uniform float Zoom = 1.; + +uniform mat4 projection, projectionview, model; +void main(){ + o_uv = texturecoordinates; + aa_scale = vec2(projection[0][0],projection[1][1])*(1.0/resolution)*AntiAliasScale/Zoom; + gl_Position = projectionview * model * vec4(vertices, 0, 1); +} diff --git a/src/GLVisualize/assets/shader/particles.vert b/src/GLVisualize/assets/shader/particles.vert new file mode 100644 index 00000000000..dabba9eaa17 --- /dev/null +++ b/src/GLVisualize/assets/shader/particles.vert @@ -0,0 +1,146 @@ +{{GLSL_VERSION}} +{{GLSL_EXTENSIONS}} + +struct Nothing{ //Nothing type, to encode if some variable doesn't contain any data + bool _; //empty structs are not allowed +}; +struct Grid1D{ + int lendiv; + float start; + float stop; + int dims; +}; +struct Grid2D{ + ivec2 lendiv; + vec2 start; + vec2 stop; + ivec2 dims; + +}; +struct Grid3D{ + ivec3 lendiv; + vec3 start; + vec3 stop; + ivec3 dims; +}; + +in vec3 vertices; +in vec3 normals; +{{texturecoordinates_type}} texturecoordinates; + +uniform vec3 light[4]; +uniform mat4 view, model, projection; +uniform uint objectid; +uniform int len; + +flat out uvec2 o_id; +out vec4 o_color; +out vec2 o_uv; + +{{position_type}} position; +{{position_x_type}} position_x; +{{position_y_type}} position_y; +{{position_z_type}} position_z; + +ivec2 ind2sub(ivec2 dim, int linearindex); +ivec3 ind2sub(ivec3 dim, int linearindex); + + +{{rotation_type}} rotation; +void rotate(Nothing vectors, int index, inout vec3 vertices, inout vec3 normal); +void rotate(samplerBuffer vectors, int index, inout vec3 V, inout vec3 N); +void rotate(vec4 vectors, int index, inout vec3 vertices, inout vec3 normal); + + +{{scale_type}} scale; // so in the case of distinct x,y,z, there's no chance to unify them under one variable +{{scale_x_type}} scale_x; +{{scale_y_type}} scale_y; +{{scale_z_type}} scale_z; +vec4 get_rotation(samplerBuffer rotation, int index){ + return texelFetch(rotation, index); +} +vec4 get_rotation(Nothing rotation, int index){ + return vec4(0,0,0,1); +} +vec4 get_rotation(vec4 rotation, int index){ + return rotation; +} +vec3 _scale(samplerBuffer scale, Nothing scale_x, Nothing scale_y, Nothing scale_z, int index); +vec3 _scale(vec3 scale, float scale_x, samplerBuffer scale_y, float scale_z, int index); +vec3 _scale(Nothing scale, float scale_x, samplerBuffer scale_y, float scale_z, int index); +vec3 _scale(vec3 scale, float scale_x, float scale_y, samplerBuffer scale_z, int index); +vec3 _scale(Nothing scale, float scale_x, float scale_y, samplerBuffer scale_z, int index); + +vec3 _scale(Nothing scale, float scale_x, float scale_y, Nothing scale_z, int index){ + vec4 rot = get_rotation(rotation, index); + return vec3(scale_x, scale_y, length(rot)); +} +vec3 _scale(vec2 scale, Nothing scale_x, Nothing scale_y, Nothing scale_z, int index); + +vec3 _scale(vec3 scale, Nothing scale_x, Nothing scale_y, Nothing scale_z, int index){ + return scale; +} + + + +{{color_type}} color; +{{color_map_type}} color_map; +{{intensity_type}} intensity; +{{color_norm_type}} color_norm; +// constant color! +vec4 _color(vec4 color, Nothing intensity, Nothing color_map, Nothing color_norm, int index, int len); +vec4 _color(vec3 color, Nothing intensity, Nothing color_map, Nothing color_norm, int index, int len); +// only a samplerBuffer, this means we have a color per particle +vec4 _color(samplerBuffer color, Nothing intensity, Nothing color_map, Nothing color_norm, int index, int len); +// no color, but intensities a color map and color norm. Color will be based on intensity! +vec4 _color(Nothing color, sampler1D intensity, sampler1D color_map, vec2 color_norm, int index, int len); +vec4 _color(Nothing color, samplerBuffer intensity, sampler1D color_map, vec2 color_norm, int index, int len); +// no color, no intensities a color map and color norm. Color will be based on z_position or rotation! +vec4 _color(Nothing color, Nothing intensity, sampler1D color_map, vec2 color_norm, int index, int len); + +float get_intensity(samplerBuffer rotation, Nothing position_z, int index){ + return texelFetch(rotation, index).w; +} +float get_intensity(vec4 rotation, Nothing position_z, int index){return length(rotation);} +float get_intensity(Nothing rotation, Nothing position_z, int index){return -1.0;} +float get_intensity(Nothing rotation, samplerBuffer position_z, int index){ + return texelFetch(position_z, index).x; +} +float get_intensity(vec4 rotation, samplerBuffer position_z, int index){ + return texelFetch(position_z, index).x; +} +vec4 color_lookup(float intensity, sampler1D color_ramp, vec2 norm); + +float get_intensity(vec4 rotation, float scale_z, int index){ + return scale_z; +} + +vec4 _color(Nothing color, Nothing intensity, sampler1D color_map, vec2 color_norm, int index, int len){ + float _intensity = get_intensity(rotation, scale_z, index); + return color_lookup(_intensity, color_map, color_norm); +} + + +vec4 _color(sampler2D color, Nothing intensity, Nothing color_map, Nothing color_norm, int index, int len){ + return vec4(0); +} + +void render(vec4 vertices, vec3 normal, mat4 view, mat4 projection, vec3 light[4]); + + +vec2 get_uv(Nothing x){return vec2(0.0);} +vec2 get_uv(vec2 x){return vec2(1.0 - x.y, x.x);} + +void main(){ + int index = gl_InstanceID; + o_id = uvec2(objectid, index+1); + vec3 s = _scale(scale, scale_x, scale_y, scale_z, index); + vec3 V = vertices * s; + vec3 N = normals; + vec3 pos; + {{position_calc}} + o_color = _color(color, intensity, color_map, color_norm, index, len); + o_uv = get_uv(texturecoordinates); + rotate(rotation, index, V, N); + render(model * vec4(pos + V, 1), N, view, projection, light); +} diff --git a/src/GLVisualize/assets/shader/plain.frag b/src/GLVisualize/assets/shader/plain.frag new file mode 100644 index 00000000000..6ebfd7c383e --- /dev/null +++ b/src/GLVisualize/assets/shader/plain.frag @@ -0,0 +1,22 @@ +{{GLSL_VERSION}} + +flat in uvec2 o_objectid; + +{{color_type}} color; + +vec4 get_color(vec4 color){ + return color; +} +vec4 get_color(vec3 color){ + return vec4(color, 1); +} + + +void write2framebuffer(vec4 color, uvec2 id); + +void main(){ + write2framebuffer( + get_color(color), + o_objectid + ); +} diff --git a/src/GLVisualize/assets/shader/plain.vert b/src/GLVisualize/assets/shader/plain.vert new file mode 100644 index 00000000000..9e7ac13dc51 --- /dev/null +++ b/src/GLVisualize/assets/shader/plain.vert @@ -0,0 +1,17 @@ +{{GLSL_VERSION}} +{{GLSL_EXTENSIONS}} + +{{vertices_type}} vertices; + +uniform mat4 projection, view, model; +uniform uint objectid; + +flat out uvec2 o_objectid; + +vec4 _position(vec3 p){return vec4(p,1);} +vec4 _position(vec2 p){return vec4(p,0,1);} + +void main(){ + o_objectid = uvec2(objectid, gl_VertexID + 1); + gl_Position = projection * view * model * _position(vertices); +} diff --git a/src/GLVisualize/assets/shader/postprocess.frag b/src/GLVisualize/assets/shader/postprocess.frag new file mode 100644 index 00000000000..fbf420ede90 --- /dev/null +++ b/src/GLVisualize/assets/shader/postprocess.frag @@ -0,0 +1,27 @@ +{{GLSL_VERSION}} + +in vec2 frag_uv; + +uniform sampler2D color_texture; + +layout(location=0) out vec4 fragment_color; + +vec3 linear_tone_mapping(vec3 color, float gamma) +{ + color = clamp(color, 0., 1.); + color = pow(color, vec3(1. / gamma)); + return color; +} + +void main(void) +{ + vec4 color = texture(color_texture, frag_uv).rgba; + if(color.a <= 0){ + discard; + } + // do tonemapping + //opaque = linear_tone_mapping(color.rgb, 1.8); // linear color output + fragment_color.rgb = color.rgb; + // save luma in alpha for FXAA + fragment_color.a = dot(color.rgb, vec3(0.299, 0.587, 0.114)); // compute luma +} diff --git a/src/GLVisualize/assets/shader/sprites.geom b/src/GLVisualize/assets/shader/sprites.geom new file mode 100644 index 00000000000..fa625171869 --- /dev/null +++ b/src/GLVisualize/assets/shader/sprites.geom @@ -0,0 +1,113 @@ +{{GLSL_VERSION}} +{{GLSL_EXTENSIONS}} + +layout(points) in; +layout(triangle_strip, max_vertices = 4) out; + +vec3 qmul(vec4 quat, vec3 vec){ + float num = quat.x * 2.0; + float num2 = quat.y * 2.0; + float num3 = quat.z * 2.0; + float num4 = quat.x * num; + float num5 = quat.y * num2; + float num6 = quat.z * num3; + float num7 = quat.x * num2; + float num8 = quat.x * num3; + float num9 = quat.y * num3; + float num10 = quat.w * num; + float num11 = quat.w * num2; + float num12 = quat.w * num3; + return vec3( + (1.0 - (num5 + num6)) * vec.x + (num7 - num12) * vec.y + (num8 + num11) * vec.z, + (num7 + num12) * vec.x + (1.0 - (num4 + num6)) * vec.y + (num9 - num10) * vec.z, + (num8 - num11) * vec.x + (num9 + num10) * vec.y + (1.0 - (num4 + num5)) * vec.z + ); +} + +uniform bool scale_primitive; +uniform bool billboard; +uniform float stroke_width; +uniform float glow_width; +uniform vec2 resolution; + +in int g_primitive_index[]; +in vec4 g_uv_offset_width[]; +in vec4 g_color[]; +in vec4 g_stroke_color[]; +in vec4 g_glow_color[]; +in vec3 g_position[]; +in vec4 g_rotation[]; +in vec4 g_offset_width[]; +in uvec2 g_id[]; + +flat out int f_primitive_index; +flat out vec2 f_scale; +flat out vec4 f_color; +flat out vec4 f_bg_color; +flat out vec4 f_stroke_color; +flat out vec4 f_glow_color; +flat out uvec2 f_id; +out vec2 f_uv; +out vec2 f_uv_offset; + + +uniform mat4 projection, view, model; + + + +void emit_vertex(vec2 vertex, vec2 uv, vec2 uv_offset) +{ + vec4 sprite_position, final_position; + mat4 mview = projection * view; + vec4 datapoint = mview * model * vec4(g_position[0], 1); + if(scale_primitive) + final_position = model * vec4(vertex, 0, 0); + else{ + final_position = vec4(vertex, 0, 0); + } + if(billboard){ + final_position = projection * final_position; + }else{ + final_position = mview * vec4( + qmul(g_rotation[0], final_position.xyz), 0 + ); + } + gl_Position = datapoint + final_position; + + f_uv = uv; + f_uv_offset = uv_offset; + f_primitive_index = g_primitive_index[0]; + f_color = g_color[0]; + f_bg_color = vec4(g_color[0].rgb, 0); + f_stroke_color = g_stroke_color[0]; + f_glow_color = g_glow_color[0]; + f_id = g_id[0]; + + EmitVertex(); +} + + +void main(void) +{ + // emit quad as triangle strip + // v3. ____ . v4 + // |\ | + // | \ | + // | \ | + // |___\| + // v1* * v2 + vec4 o_w = g_offset_width[0]; + vec4 uv_o_w = g_uv_offset_width[0]; + float glow_stroke = max(glow_width, 0) + max(stroke_width, 0); //we don't need negativity here + vec2 final_scale = o_w.zw + 2*glow_stroke; + vec2 scale_rel = (final_scale / o_w.zw); + float hfs = glow_stroke; + vec4 uv_min_max = vec4(-scale_rel, scale_rel); //minx, miny, maxx, maxy + vec4 vertices = vec4(-hfs + o_w.xy, o_w.xy + (o_w.zw) + glow_stroke); // use offset as origin quad (x,y,w,h) + f_scale = vec2(stroke_width, glow_width)/o_w.zw; + emit_vertex(vertices.xy, uv_min_max.xw, uv_o_w.xw); + emit_vertex(vertices.xw, uv_min_max.xy, uv_o_w.xy); + emit_vertex(vertices.zy, uv_min_max.zw, uv_o_w.zw); + emit_vertex(vertices.zw, uv_min_max.zy, uv_o_w.zy); + EndPrimitive(); +} diff --git a/src/GLVisualize/assets/shader/sprites.vert b/src/GLVisualize/assets/shader/sprites.vert new file mode 100644 index 00000000000..44ac1ef9414 --- /dev/null +++ b/src/GLVisualize/assets/shader/sprites.vert @@ -0,0 +1,128 @@ +{{GLSL_VERSION}} +{{GLSL_EXTENSIONS}} + +struct Nothing{ //Nothing type, to encode if some variable doesn't contain any data + bool _; //empty structs are not allowed +}; +struct Grid1D{ + int lendiv; + float start; + float stop; + int dims; +}; +struct Grid2D{ + ivec2 lendiv; + vec2 start; + vec2 stop; + ivec2 dims; +}; +struct Grid3D{ + ivec3 lendiv; + vec3 start; + vec3 stop; + ivec3 dims; +}; + +{{uv_offset_width_type}} uv_offset_width; +//{{uv_x_type}} uv_width; +{{position_type}} position; +{{position_x_type}} position_x; +{{position_y_type}} position_y; +{{position_z_type}} position_z; +//Assembling functions for creating the right position from the above inputs. They also indicate the type combinations allowed for the above inputs +ivec2 ind2sub(ivec2 dim, int linearindex); +ivec3 ind2sub(ivec3 dim, int linearindex); + +{{scale_type}} scale; // so in the case of distinct x,y,z, there's no chance to unify them under one variable +{{scale_x_type}} scale_x; +{{scale_y_type}} scale_y; +{{scale_z_type}} scale_z; +vec3 _scale(Nothing scale, Nothing scale_x, Nothing scale_y, Nothing scale_z, int index); +vec3 _scale(vec3 scale, Nothing scale_x, Nothing scale_y, Nothing scale_z, int index); +vec3 _scale(vec2 scale, Nothing scale_x, Nothing scale_y, Nothing scale_z, int index); +vec3 _scale(Nothing scale, float scale_x, float scale_y, float scale_z, int index); +vec3 _scale(vec3 scale, float scale_x, float scale_y, float scale_z, int index); +vec3 _scale(vec2 scale, float scale_x, float scale_y, float scale_z, int index); + + + +{{offset_type}} offset; + +{{rotation_type}} rotation; + +vec4 _rotation(Nothing r){return vec4(0,0,0,1);} +vec4 _rotation(vec2 r){return vec4(r, 0, 1);} +vec4 _rotation(vec3 r){return vec4(r, 1);} +vec4 _rotation(vec4 r){return r;} + +float get_rotation_len(Nothing rotation){ + return 1.0; +} + +float get_rotation_len(vec4 rotation){ + return 1.0; +} + +vec3 _scale(Nothing scale, float scale_x, float scale_y, Nothing scale_z, int index){ + float len = get_rotation_len(rotation); + return vec3(scale_x,scale_y, len); +} +vec3 _scale(vec3 scale, Nothing scale_x, Nothing scale_y, Nothing scale_z, int index){ + float len = get_rotation_len(rotation); + return vec3(scale.xy, scale.z*len); +} + +{{color_type}} color; +{{color_map_type}} color_map; +{{intensity_type}} intensity; +{{color_norm_type}} color_norm; + +float get_intensity(vec4 rotation, Nothing position_z, int index){return length(rotation);} +float get_intensity(vec3 rotation, Nothing position_z, int index){return length(rotation);} +float get_intensity(vec2 rotation, Nothing position_z, int index){return length(rotation);} +float get_intensity(Nothing rotation, float position_z, int index){return position_z;} +float get_intensity(vec3 rotation, float position_z, int index){return position_z;} +vec4 color_lookup(float intensity, sampler1D color_ramp, vec2 norm); + +vec4 _color(vec3 color, Nothing intensity, Nothing color_map, Nothing color_norm, int index, int len); +vec4 _color(vec4 color, Nothing intensity, Nothing color_map, Nothing color_norm, int index, int len); +vec4 _color(Nothing color, float intensity, sampler1D color_map, vec2 color_norm, int index, int len); +vec4 _color(Nothing color, sampler1D intensity, sampler1D color_map, vec2 color_norm, int index, int len); +vec4 _color(Nothing color, Nothing intensity, sampler1D color_map, vec2 color_norm, int index, int len){ + return color_lookup(get_intensity(rotation, position_z, index), color_map, color_norm); +} + +{{stroke_color_type}} stroke_color; +{{glow_color_type}} glow_color; + +uniform uint objectid; +uniform int len; + +out uvec2 g_id; +out int g_primitive_index; +out vec3 g_position; +out vec4 g_offset_width; +out vec4 g_uv_offset_width; +out vec4 g_rotation; +out vec4 g_color; +out vec4 g_stroke_color; +out vec4 g_glow_color; + + + +void main(){ + int index = gl_VertexID; + g_primitive_index = index; + vec3 pos; + {{position_calc}} + g_position = pos; + g_offset_width.xy = offset.xy; + g_offset_width.zw = _scale(scale, scale_x, scale_y, scale_z, g_primitive_index).xy; + g_color = _color(color, intensity, color_map, color_norm, g_primitive_index, len); + g_rotation = _rotation(rotation); + g_uv_offset_width = uv_offset_width; + g_stroke_color = stroke_color; + g_glow_color = glow_color; + + g_id = uvec2(objectid, index+1); +} diff --git a/src/GLVisualize/assets/shader/standard.frag b/src/GLVisualize/assets/shader/standard.frag new file mode 100644 index 00000000000..d475d177e17 --- /dev/null +++ b/src/GLVisualize/assets/shader/standard.frag @@ -0,0 +1,62 @@ +{{GLSL_VERSION}} + +struct Nothing{ //Nothing type, to encode if some variable doesn't contain any data + bool _; //empty structs are not allowed +}; + +in vec3 o_normal; +in vec3 o_lightdir; +in vec3 o_vertex; +in vec4 o_color; +in vec2 o_uv; +flat in uvec2 o_id; + +{{color_type}} color; + +vec4 get_color(vec3 color, vec2 uv){ + return vec4(color, 1.0 + (0.0 * uv)); // we must prohibit uv from getting into dead variable removal +} + +vec4 get_color(vec4 color, vec2 uv){ + return color + uv.x * 0.0; // we must prohibit uv from getting into dead variable removal +} + +vec4 get_color(Nothing color, vec2 uv){ + return o_color + uv.x * 0.0; +} +vec4 get_color(samplerBuffer color, vec2 uv){ + return o_color + uv.x * 0.0; +} + +vec4 get_color(sampler2D color, vec2 uv){ + return texture(color, uv); +} + +vec3 blinnphong(vec3 N, vec3 V, vec3 L, vec3 color){ + float diff_coeff = max(dot(L, N), 0.0); + + // specular coefficient + vec3 H = normalize(L+V); + + float spec_coeff = pow(max(dot(H, N), 0.0), 8.0); + if (diff_coeff <= 0.0) + spec_coeff = 0.0; + + // final lighting model + return vec3( + vec3(0.1) * vec3(0.3) + + vec3(0.9) * color * diff_coeff + + vec3(0.3) * spec_coeff + ); +} + +void write2framebuffer(vec4 color, uvec2 id); + +void main(){ + vec4 color = get_color(color, o_uv); + {{light_calc}} + write2framebuffer( + color, + o_id + ); +} diff --git a/src/GLVisualize/assets/shader/standard.vert b/src/GLVisualize/assets/shader/standard.vert new file mode 100644 index 00000000000..b43ffad922d --- /dev/null +++ b/src/GLVisualize/assets/shader/standard.vert @@ -0,0 +1,22 @@ +{{GLSL_VERSION}} + +in vec3 vertices; +in vec3 normals; + +uniform vec3 light[4]; +uniform vec4 color; +uniform mat4 projection, view, model; +void render(vec4 vertices, vec3 normals, mat4 viewmodel, mat4 projection, vec3 light[4]); + +uniform uint objectid; +flat out uvec2 o_id; +out vec2 o_uv; +out vec4 o_color; + +void main() +{ + o_id = uvec2(objectid, gl_VertexID+1); + o_uv = vec2(0); + o_color = color; + render(model * vec4(vertices, 1), (model * vec4(normals, 0)).xyz, view, projection, light); +} diff --git a/src/GLVisualize/assets/shader/surface.vert b/src/GLVisualize/assets/shader/surface.vert new file mode 100644 index 00000000000..b6fd45c2312 --- /dev/null +++ b/src/GLVisualize/assets/shader/surface.vert @@ -0,0 +1,111 @@ +{{GLSL_VERSION}} +{{GLSL_EXTENSIONS}} + +struct Grid2D{ + ivec2 lendiv; + vec2 start; + vec2 stop; + ivec2 dims; +}; + +struct Nothing{ //Nothing type, to encode if some variable doesn't contain any data + bool _; //empty structs are not allowed +} nothing; + +in vec2 vertices; + +{{position_type}} position; +{{position_x_type}} position_x; +{{position_y_type}} position_y; +uniform sampler2D position_z; + +uniform vec3 light[4]; +{{stroke_color_type}} stroke_color; +{{glow_color_type}} glow_color; +{{color_type}} color; +{{color_map_type}} color_map; +{{color_norm_type}} color_norm; + +vec4 color_lookup(float intensity, sampler1D color, vec2 norm); +// constant color! +vec4 get_color(vec4 color, float _intensity, Nothing color_map, Nothing color_norm, int index){ + return color; +} + +vec4 get_color(Nothing color, float _intensity, sampler1D color_map, vec2 color_norm, int index){ + return color_lookup(_intensity, color_map, color_norm); +} +vec4 get_color(sampler2D color, float _intensity, Nothing b, Nothing c, int index){ + return vec4(0); // we fetch the color in fragment shader +} + +uniform vec3 scale; + +uniform mat4 view, model, projection; + +void render(vec4 vertices, vec3 normal, mat4 viewmodel, mat4 projection, vec3 light[4]); +ivec2 ind2sub(ivec2 dim, int linearindex); +vec2 linear_index(ivec2 dims, int index); +vec2 linear_index(ivec2 dims, int index, vec2 offset); +vec4 linear_texture(sampler2D tex, int index, vec2 offset); +vec3 getnormal(sampler2D zvalues, vec2 uv); + +uniform bool wireframe; +uniform uint objectid; +uniform float stroke_width; +flat out uvec2 o_id; +out vec4 o_color; +out vec2 o_uv; + +flat out vec2 f_scale; +flat out vec4 f_color; +flat out vec4 f_bg_color; +flat out vec4 f_stroke_color; +flat out vec4 f_glow_color; +flat out int f_primitive_index; +flat out uvec2 f_id; + +out vec2 f_uv; +out vec2 f_uv_offset; + +void main() +{ + int index = gl_InstanceID; + vec2 offset = vertices; + ivec2 offseti = ivec2(offset); + ivec2 dims = textureSize(position_z, 0); + vec2 final_scale = ((scale.xy)/(scale.xy-stroke_width)); + + const float uv_w = 0.9; + + vec3 pos; + {{position_calc}} + //pos += vec3(scale.xy*vertices, 0.0); + o_color = get_color(color, pos.z, color_map, color_norm, index); + o_id = uvec2(objectid, index1D+1); + + if(wireframe){ + if(offset.x == 0){ + f_uv.x = -uv_w; + }else{ + f_uv.x = uv_w; + } + if(offset.y == 0){ + f_uv.y = -uv_w; + }else{ + f_uv.y = uv_w; + } + f_id = o_id; + f_uv_offset = vec2(0); + f_color = o_color; + f_bg_color = o_color; + f_stroke_color = stroke_color; + f_glow_color = glow_color; + f_scale = vec2(-0.1, 0); + gl_Position = projection * view * model * vec4(pos, 1); + }else{ + o_uv = index01; + vec3 normalvec = {{normal_calc}}; + render(model * vec4(pos, 1), (model * vec4(normalvec, 0)).xyz, view, projection, light); + } +} diff --git a/src/GLVisualize/assets/shader/surface2.vert b/src/GLVisualize/assets/shader/surface2.vert new file mode 100644 index 00000000000..2afca7c1720 --- /dev/null +++ b/src/GLVisualize/assets/shader/surface2.vert @@ -0,0 +1,89 @@ +{{GLSL_VERSION}} +{{GLSL_EXTENSIONS}} + +in vec2 vertices; + +uniform vec3 light[4]; +{{color_type}} color; +uniform vec2 color_norm; + +uniform sampler2D x; +uniform sampler2D y; +uniform sampler2D z; + + +uniform vec3 scale; + +uniform mat4 view, model, projection; + +void render(vec3 vertices, vec3 normal, vec4 color, mat4 viewmodel, mat4 projection, vec3 light[4]); +ivec2 ind2sub(ivec2 dim, int linearindex); +vec2 linear_index(ivec2 dims, int index, vec2 offset); +vec4 linear_texture(sampler2D tex, int index, vec2 offset); +vec4 color_lookup(float intensity, sampler1D color_ramp, vec2 norm); + + +bool isinbounds(vec2 uv) +{ + return (uv.x <= 1.0 && uv.y <= 1.0 && uv.x >= 0.0 && uv.y >= 0.0); +} +vec3 getnormal(sampler2D zvalues, vec2 uv) +{ + float weps = 1.0/textureSize(zvalues,0).x; + float heps = 1.0/textureSize(zvalues,0).y; + + vec3 result = vec3(0); + + vec3 s0 = vec3(uv, texture(zvalues, uv).x); + + vec2 off1 = uv + vec2(-weps,0); + vec2 off2 = uv + vec2(0, heps); + vec2 off3 = uv + vec2(weps, 0); + vec2 off4 = uv + vec2(0,-heps); + vec3 s1, s2, s3, s4; + + s1 = vec3((off1), texture(zvalues, off1).x); + s2 = vec3((off2), texture(zvalues, off2).x); + s3 = vec3((off3), texture(zvalues, off3).x); + s4 = vec3((off4), texture(zvalues, off4).x); + + if(isinbounds(off1) && isinbounds(off2)) + { + result += cross(s2-s0, s1-s0); + } + if(isinbounds(off2) && isinbounds(off3)) + { + result += cross(s3-s0, s2-s0); + } + if(isinbounds(off3) && isinbounds(off4)) + { + result += cross(s4-s0, s3-s0); + } + if(isinbounds(off4) && isinbounds(off1)) + { + result += cross(s1-s0, s4-s0); + } + + return normalize(result); // normal should be zero, but needs to be here, because the dead-code elimanation of GLSL is overly enthusiastic +} + +uniform uint objectid; +flat out uvec2 o_id; + +void main() +{ + ivec2 dims = textureSize(z, 0); + vec3 pos; + int index = gl_InstanceID; + + pos.x = linear_texture(x, index, vertices).x; + pos.y = linear_texture(y, index, vertices).x; + pos.z = linear_texture(z, index, vertices).x; + + vec4 instance_color = color_lookup(pos.z, color, color_norm); + vec3 normalvec = getnormal(z, linear_index(dims, index, vertices)); + render(pos, normalvec, instance_color, view * model, projection, light); + o_id = uvec2(objectid, index+1); +} + + diff --git a/src/GLVisualize/assets/shader/texture.frag b/src/GLVisualize/assets/shader/texture.frag new file mode 100644 index 00000000000..b26cd2cfd80 --- /dev/null +++ b/src/GLVisualize/assets/shader/texture.frag @@ -0,0 +1,25 @@ +{{GLSL_VERSION}} + +in vec2 o_uv; +flat in uvec2 o_objectid; +out vec4 fragment_color; +out uvec2 fragment_groupid; + +{{image_type}} image; + +vec4 getindex(sampler2D image, vec2 uv){ + return texture(image, uv); +} +vec4 getindex(sampler1D image, vec2 uv){ + return texture(image, uv.x); +} + + +void write2framebuffer(vec4 color, uvec2 id); + +void main(){ + write2framebuffer( + getindex(image, vec2(o_uv.x, 1-o_uv.y)), + o_objectid + ); +} diff --git a/src/GLVisualize/assets/shader/util.vert b/src/GLVisualize/assets/shader/util.vert new file mode 100644 index 00000000000..3e8d09b7e8c --- /dev/null +++ b/src/GLVisualize/assets/shader/util.vert @@ -0,0 +1,290 @@ +{{GLSL_VERSION}} + +struct Nothing{ //Nothing type, to encode if some variable doesn't contain any data + bool _; //empty structs are not allowed +}; +struct Grid1D{ + int lendiv; + float start; + float stop; + int dims; +}; +struct Grid2D{ + ivec2 lendiv; + vec2 start; + vec2 stop; + ivec2 dims; +}; +struct Grid3D{ + ivec3 lendiv; + vec3 start; + vec3 stop; + ivec3 dims; +}; +struct Light{ + vec3 diffuse; + vec3 specular; + vec3 ambient; + vec3 position; +}; + +// stretch is +vec3 stretch(vec3 val, vec3 from, vec3 to){ + return from + (val * (to - from)); +} +vec2 stretch(vec2 val, vec2 from, vec2 to){ + return from + (val * (to - from)); +} +float stretch(float val, float from, float to){ + return from + (val * (to - from)); +} + +float _normalize(float val, float from, float to){return (val-from) / (to - from);} +vec2 _normalize(vec2 val, vec2 from, vec2 to){ + return (val-from) / (to - from); +} +vec3 _normalize(vec3 val, vec3 from, vec3 to){ + return (val-from) / (to - from); +} + + +mat4 getmodelmatrix(vec3 xyz, vec3 scale){ + return mat4( + vec4(scale.x, 0, 0, 0), + vec4(0, scale.y, 0, 0), + vec4(0, 0, scale.z, 0), + vec4(xyz, 1)); +} + +mat4 rotationmatrix_z(float angle){ + return mat4( + cos(angle), -sin(angle), 0, 0, + sin(angle), cos(angle), 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1); +} +mat4 rotationmatrix_y(float angle){ + return mat4( + cos(angle), 0, sin(angle), 0, + 0, 1, 0, 0, + -sin(angle), 0, cos(angle), 0, + 0, 0, 0, 1); +} + +vec3 qmul(vec4 quat, vec3 vec){ + float num = quat.x * 2.0; + float num2 = quat.y * 2.0; + float num3 = quat.z * 2.0; + float num4 = quat.x * num; + float num5 = quat.y * num2; + float num6 = quat.z * num3; + float num7 = quat.x * num2; + float num8 = quat.x * num3; + float num9 = quat.y * num3; + float num10 = quat.w * num; + float num11 = quat.w * num2; + float num12 = quat.w * num3; + return vec3( + (1.0 - (num5 + num6)) * vec.x + (num7 - num12) * vec.y + (num8 + num11) * vec.z, + (num7 + num12) * vec.x + (1.0 - (num4 + num6)) * vec.y + (num9 - num10) * vec.z, + (num8 - num11) * vec.x + (num9 + num10) * vec.y + (1.0 - (num4 + num5)) * vec.z + ); +} + + +void rotate(Nothing r, int index, inout vec3 V, inout vec3 N){} // no-op +void rotate(vec4 q, int index, inout vec3 V, inout vec3 N){ + V = qmul(q, V); + N = normalize(qmul(q, N)); +} +void rotate(samplerBuffer vectors, int index, inout vec3 V, inout vec3 N){ + vec4 r = texelFetch(vectors, index); + rotate(r, index, V, N); +} + + + +mat4 translate_scale(vec3 xyz, vec3 scale){ + return mat4( + vec4(scale.x, 0, 0, 0), + vec4(0, scale.y, 0, 0), + vec4(0, 0, scale.z, 0), + vec4(xyz, 1)); +} + +//Mapping 1D index to 1D, 2D and 3D arrays +int ind2sub(int dim, int linearindex){return linearindex;} +ivec2 ind2sub(ivec2 dim, int linearindex){ + return ivec2(linearindex % dim.x, linearindex / dim.x); +} +ivec3 ind2sub(ivec3 dim, int i){ + int z = i / (dim.x*dim.y); + i -= z * dim.x * dim.y; + return ivec3(i % dim.x, i / dim.x, z); +} + +float linear_index(int dims, int index){ + return float(index) / float(dims); +} +vec2 linear_index(ivec2 dims, int index){ + ivec2 index2D = ind2sub(dims, index); + return vec2(index2D) / vec2(dims); +} +vec2 linear_index(ivec2 dims, int index, vec2 offset){ + vec2 index2D = vec2(ind2sub(dims, index))+offset; + return index2D / vec2(dims); +} +vec3 linear_index(ivec3 dims, int index){ + ivec3 index3D = ind2sub(dims, index); + return vec3(index3D) / vec3(dims); +} +vec4 linear_texture(sampler2D tex, int index){ + return texture(tex, linear_index(textureSize(tex, 0), index)); +} + +vec4 linear_texture(sampler2D tex, int index, vec2 offset){ + ivec2 dims = textureSize(tex, 0); + return texture(tex, linear_index(dims, index) + (offset/vec2(dims))); +} + +vec4 linear_texture(sampler3D tex, int index){ + return texture(tex, linear_index(textureSize(tex, 0), index)); +} +uvec4 getindex(usampler2D tex, int index){ + return texelFetch(tex, ind2sub(textureSize(tex, 0), index), 0); +} +vec4 getindex(samplerBuffer tex, int index){ + return texelFetch(tex, index); +} +vec4 getindex(sampler1D tex, int index){ + return texelFetch(tex, index, 0); +} +vec4 getindex(sampler2D tex, int index){ + return texelFetch(tex, ind2sub(textureSize(tex, 0), index), 0); +} +vec4 getindex(sampler3D tex, int index){ + return texelFetch(tex, ind2sub(textureSize(tex, 0), index), 0); +} + + + +//vec3 _scale(vec3 scale, Nothing scale_x, Nothing scale_y, Nothing scale_z, int index){return scale;} +vec3 _scale(vec2 scale, Nothing scale_x, Nothing scale_y, Nothing scale_z, int index){return vec3(scale,1);} +vec3 _scale(float scale, Nothing scale_x, Nothing scale_y, Nothing scale_z, int index){return vec3(scale);} +vec3 _scale(Nothing scale, float scale_x, float scale_y, float scale_z, int index){ + return vec3(scale_x, scale_y, scale_z); +} +vec3 _scale(vec2 scale, float scale_x, float scale_y, float scale_z, int index){ + return vec3(scale.x*scale_x, scale.y*scale_y, scale_z); +} +vec3 _scale(vec3 scale, float scale_x, float scale_y, float scale_z, int index){ + return vec3(scale_x, scale_y, scale_z)*scale; +} +vec3 _scale(samplerBuffer scale, Nothing scale_x, Nothing scale_y, Nothing scale_z, int index){ + return getindex(scale, index).xyz; +} +vec3 _scale(vec3 scale, float scale_x, float scale_y, samplerBuffer scale_z, int index){ + return vec3(scale_x, scale_y, getindex(scale_z, index).x); +} +vec3 _scale(Nothing scale, float scale_x, float scale_y, samplerBuffer scale_z, int index){ + return vec3(scale_x, scale_y, getindex(scale_z, index).x); +} +vec3 _scale(vec3 scale, float scale_x, samplerBuffer scale_y, float scale_z, int index){ + return vec3(scale_x, getindex(scale_y, index).x, scale_z); +} +vec3 _scale(Nothing scale, float scale_x, samplerBuffer scale_y, float scale_z, int index){ + return vec3(scale_x, getindex(scale_y, index).x, scale_z); +} + +vec4 color_lookup(float intensity, vec4 color, vec2 norm){ + return color; +} +vec4 color_lookup(float intensity, sampler1D color_ramp, vec2 norm){ + return texture(color_ramp, _normalize(intensity, norm.x, norm.y)); +} + +vec4 _color(vec3 color, Nothing intensity, Nothing color_map, Nothing color_norm, int index, int len){ + return vec4(color, 1); +} +vec4 _color(vec4 color, Nothing intensity, Nothing color_map, Nothing color_norm, int index, int len){return color;} +vec4 _color(samplerBuffer color, Nothing intensity, Nothing color_norm, int index){ + return texelFetch(color, index); +} +vec4 _color(samplerBuffer color, Nothing intensity, Nothing color_map, Nothing color_norm, int index, int len){ + return texelFetch(color, index); +} +vec4 _color(Nothing color, sampler1D intensity, sampler1D color_map, vec2 color_norm, int index, int len){ + return color_lookup(texture(intensity, float(index)/float(len-1)).x, color_map, color_norm); +} +vec4 _color(Nothing color, samplerBuffer intensity, sampler1D color_map, vec2 color_norm, int index, int len){ + return color_lookup(texelFetch(intensity, index).x, color_map, color_norm); +} +vec4 _color(Nothing color, float intensity, sampler1D color_map, vec2 color_norm, int index, int len){ + return color_lookup(intensity, color_map, color_norm); +} + + + +out vec3 o_normal; +out vec3 o_lightdir; +out vec3 o_vertex; +uniform mat3 normalmatrix; + +void render(vec4 position_world, vec3 normal, mat4 view, mat4 projection, vec3 light[4]) +{ + // normal in world space + // TODO move transpose inverse calculation to cpu + o_normal = normal; + // direction to light + o_lightdir = normalize(light[3] - position_world.xyz); + // direction to camera + o_vertex = -position_world.xyz; + // screen space coordinates of the vertex + gl_Position = projection * view * position_world; +} + + + + +bool isinbounds(vec2 uv) +{ + return (uv.x <= 1.0 && uv.y <= 1.0 && uv.x >= 0.0 && uv.y >= 0.0); +} +vec3 getnormal(sampler2D zvalues, vec2 uv) +{ + float weps = 1.0/textureSize(zvalues,0).x; + float heps = 1.0/textureSize(zvalues,0).y; + + vec3 result = vec3(0); + + vec3 s0 = vec3(uv, texture(zvalues, uv).x); + + vec2 off1 = uv + vec2(-weps,0); + vec2 off2 = uv + vec2(0, heps); + vec2 off3 = uv + vec2(weps, 0); + vec2 off4 = uv + vec2(0,-heps); + vec3 s1, s2, s3, s4; + + s1 = vec3((off1), texture(zvalues, off1).x); + s2 = vec3((off2), texture(zvalues, off2).x); + s3 = vec3((off3), texture(zvalues, off3).x); + s4 = vec3((off4), texture(zvalues, off4).x); + + if(isinbounds(off1) && isinbounds(off2)) + { + result += cross(s2-s0, s1-s0); + } + if(isinbounds(off2) && isinbounds(off3)) + { + result += cross(s3-s0, s2-s0); + } + if(isinbounds(off3) && isinbounds(off4)) + { + result += cross(s4-s0, s3-s0); + } + if(isinbounds(off4) && isinbounds(off1)) + { + result += cross(s1-s0, s4-s0); + } + return normalize(result); // normal should be zero, but needs to be here, because the dead-code elimanation of GLSL is overly enthusiastic +} diff --git a/src/GLVisualize/assets/shader/uv_normal.frag b/src/GLVisualize/assets/shader/uv_normal.frag new file mode 100644 index 00000000000..854f23e48ad --- /dev/null +++ b/src/GLVisualize/assets/shader/uv_normal.frag @@ -0,0 +1,63 @@ +{{GLSL_VERSION}} + +in vec3 o_normal; +in vec3 o_lightdir; +in vec3 o_vertex; +in vec4 o_color; +in vec2 o_uv; +flat in uvec2 o_id; + +out vec4 fragment_color; +out uvec2 fragment_groupid; + + +vec3 blinnphong(vec3 N, vec3 V, vec3 L, vec3 color) +{ + float diff_coeff = max(dot(L,N), 0.0); + + // specular coefficient + vec3 H = normalize(L+V); + + float spec_coeff = pow(max(dot(H,N), 0.0), 8.0); + if (diff_coeff <= 0.0) + spec_coeff = 0.0; + + // final lighting model + return vec3( + vec3(0.1) * vec3(0.3) + + vec3(0.9) * color * diff_coeff + + vec3(0.3) * spec_coeff); +} + + + +const float ALIASING_CONST = 0.70710678118654757; + +float aastep(float threshold1, float threshold2, float value) { + float afwidth = length(vec2(dFdx(value), dFdy(value))) * ALIASING_CONST; + return smoothstep(threshold1-afwidth, threshold1+afwidth, value)-smoothstep(threshold2-afwidth, threshold2+afwidth, value); +} + +const float thickness = 0.01; +float square(vec2 uv) +{ + float xmin = aastep(-0.1, thickness, uv.x); + float xmax = aastep(1.0-thickness, 1.01, uv.x); + float ymin = aastep(-0.01, 0.0+thickness, uv.y); + float ymax = aastep(1.0-thickness, 1.01, uv.y); + return xmin + + xmax + + ((1-xmin)*(1-xmax))*ymin + + ((1-xmin)*(1-xmax))*ymax; +} + +void main(){ + vec3 L = normalize(o_lightdir); + vec3 N = normalize(o_normal); + vec3 f_color = mix(vec3(0,0,1), vec3(1), square(o_uv)); + vec3 light1 = blinnphong(N, o_vertex, L, f_color); + vec3 light2 = blinnphong(N, o_vertex, -L,f_color); + fragment_color = vec4(light1+light2*0.4, 1.0); + if(fragment_color.a > 0.0) + fragment_groupid = o_id; +} diff --git a/src/GLVisualize/assets/shader/uv_normal.vert b/src/GLVisualize/assets/shader/uv_normal.vert new file mode 100644 index 00000000000..6f9fbfb2ac8 --- /dev/null +++ b/src/GLVisualize/assets/shader/uv_normal.vert @@ -0,0 +1,25 @@ +{{GLSL_VERSION}} + +in vec3 vertices; +in vec3 normals; +in vec2 texturecoordinates; + + +uniform vec3 light[4]; +uniform mat4 projection, view, model; +void render(vec4 vertices, vec3 normals, mat4 view, mat4 projection, vec3 light[4]); + +uniform uint objectid; +flat out uvec2 o_id; +out vec2 o_uv; +out vec4 o_color; + + +void main() +{ + o_color = vec4(0); + o_uv = texturecoordinates; + o_uv = vec2(1.0 - o_uv.y, o_uv.x); + o_id = uvec2(objectid, gl_VertexID+1); + render(model * vec4(vertices, 1), (model * vec4(normals, 0)).xyz, view, projection, light); +} diff --git a/src/GLVisualize/assets/shader/uv_vert.vert b/src/GLVisualize/assets/shader/uv_vert.vert new file mode 100644 index 00000000000..bc7fefe03d2 --- /dev/null +++ b/src/GLVisualize/assets/shader/uv_vert.vert @@ -0,0 +1,20 @@ +{{GLSL_VERSION}} +{{GLSL_EXTENSIONS}} + +{{vertices_type}} vertices; +in vec2 texturecoordinates; + +uniform mat4 projection, view, model; +uniform uint objectid; + +out vec2 o_uv; +flat out uvec2 o_objectid; + +vec4 _position(vec3 p){return vec4(p,1);} +vec4 _position(vec2 p){return vec4(p,0,1);} + +void main(){ + o_uv = texturecoordinates; + o_objectid = uvec2(objectid, gl_VertexID+1); + gl_Position = projection * view * model * _position(vertices); +} diff --git a/src/GLVisualize/assets/shader/vertexcolor.vert b/src/GLVisualize/assets/shader/vertexcolor.vert new file mode 100644 index 00000000000..55e674cd164 --- /dev/null +++ b/src/GLVisualize/assets/shader/vertexcolor.vert @@ -0,0 +1,25 @@ +{{GLSL_VERSION}} + +in vec3 vertices; +in vec3 normals; +in vec4 vertex_color; + +uniform vec3 light[4]; + +uniform mat4 projection, view, model; + +void render(vec4 vertices, vec3 normals, mat4 view, mat4 projection, vec3 light[4]); + +uniform uint objectid; + +out vec4 o_color; +flat out uvec2 o_id; +out vec2 o_uv; + +void main() +{ + o_uv = vec2(0.0); + o_id = uvec2(objectid, 0); + o_color = vertex_color; + render(model * vec4(vertices, 1), (model * vec4(normals, 0)).xyz, view, projection, light); +} diff --git a/src/GLVisualize/assets/shader/volume.frag b/src/GLVisualize/assets/shader/volume.frag new file mode 100644 index 00000000000..d4643e065fe --- /dev/null +++ b/src/GLVisualize/assets/shader/volume.frag @@ -0,0 +1,327 @@ +{{GLSL_VERSION}} + +struct Nothing{ //Nothing type, to encode if some variable doesn't contain any data + bool _; //empty structs are not allowed +}; +in vec3 frag_vert; +in vec3 frag_uv; + +{{volumedata_type}} volumedata; + +uniform vec3 light_position = vec3(1.0, 1.0, 3.0); +uniform vec3 light_intensity = vec3(15.0); +{{color_map_type}} color_map; +{{color_type}} color; +{{color_norm_type}} color_norm; + +uniform float absorption = 20.0; + +uniform vec3 eyeposition; + +uniform vec3 ambient = vec3(0.15, 0.15, 0.20); + +uniform mat4 model; +uniform mat4 modelinv; +uniform int algorithm; +uniform float isovalue; +uniform float isorange; + +const float max_distance = 1.3; + +const int num_samples = 200; +const float step_size = max_distance / float(num_samples); +const int num_ligth_samples = 16; +const float lscale = max_distance / float(num_ligth_samples); +const float density_factor = 9; + +const float eps = 0.0001; + +bool intersect(vec3 ray_origin, vec3 ray_dir, vec3 center, vec3 normal, out vec3 intersect){ + float denom = dot(normal, ray_dir); + if (abs(denom) > eps) // if not orthogonal + { + float t = dot(center - ray_origin, normal) / denom; + if (t >= 0){ + intersect.xyz = ray_origin + (ray_dir * t); + return true; + } + } + return false; +} +float _normalize(float val, float from, float to) +{ + return (val-from) / (to - from); +} + +vec4 color_lookup(float intensity, Nothing color_map, Nothing norm, vec4 color) +{ + return color; +} + +vec4 color_lookup(float intensity, samplerBuffer color_ramp, vec2 norm, Nothing color) +{ + return texelFetch(color_ramp, int(_normalize(intensity, norm.x, norm.y)*textureSize(color_ramp))); +} + +vec4 color_lookup(float intensity, samplerBuffer color_ramp, Nothing norm, Nothing color) +{ + return vec4(0); // stub method +} + +vec4 color_lookup(float intensity, sampler1D color_ramp, vec2 norm, Nothing color) +{ + return texture(color_ramp, _normalize(intensity, norm.x, norm.y)); +} + +vec4 color_lookup(samplerBuffer colormap, int index) +{ + return texelFetch(colormap, index); +} + +vec4 color_lookup(sampler1D colormap, int index) +{ + return texelFetch(colormap, index, 0); +} + +vec4 color_lookup(Nothing colormap, int index) +{ + return vec4(0); +} + +float GetDensity(vec3 pos) +{ + return texture(volumedata, pos).x; +} + +vec3 gennormal(vec3 uvw, vec3 gradient_delta) +{ + vec3 a,b; + a.x = texture(volumedata, uvw - vec3(gradient_delta.x,0.0,0.0) ).r; + b.x = texture(volumedata, uvw + vec3(gradient_delta.x,0.0,0.0) ).r; + a.y = texture(volumedata, uvw - vec3(0.0,gradient_delta.y,0.0) ).r; + b.y = texture(volumedata, uvw + vec3(0.0,gradient_delta.y,0.0) ).r; + a.z = texture(volumedata, uvw - vec3(0.0,0.0,gradient_delta.z) ).r; + b.z = texture(volumedata, uvw + vec3(0.0,0.0,gradient_delta.z) ).r; + return normalize(a - b); +} + +vec3 blinn_phong(vec3 N, vec3 V, vec3 L, vec3 diffuse) +{ + // material properties + vec3 Ka = vec3(0.1); + vec3 Kd = vec3(1.0, 1.0, 1.0); + vec3 Ks = vec3(1.0, 1.0, 1.0); + float shininess = 50.0; + + // diffuse coefficient + float diff_coeff = max(dot(L,N),0.0); + + // specular coefficient + vec3 H = normalize(L+V); + float spec_coeff = pow(max(dot(H,N), 0.0), shininess); + if (diff_coeff <= 0.0) + spec_coeff = 0.0; + + // final lighting model + return Ka * vec3(0.5) + + Kd * diffuse * diff_coeff + + Ks * vec3(0.3) * spec_coeff ; +} + +bool is_outside(vec3 position) +{ + return (position.x > 1.0 || position.y > 1.0 || position.z > 1.0 || position.x < 0.0 || position.y < 0.0 || position.z < 0.0); +} + +// Simple random generator found: http://stackoverflow.com/questions/4200224/random-noise-functions-for-glsl +float rand(){ + return fract(sin(gl_FragCoord.x * 12.9898 + gl_FragCoord.y * 78.233) * 43758.5453); +} + + +vec4 volume(vec3 front, vec3 dir, float stepsize) +{ + vec3 stepsize_dir = normalize(dir) * stepsize; + vec3 pos = front; + float T = 1.0; + vec3 Lo = vec3(0.0); + int i = 0; + pos += stepsize_dir;//apply first, to padd + for (i; i < num_samples && (!is_outside(pos) || i < 3); ++i, pos += stepsize_dir) { + + float density = texture(volumedata, pos).x * density_factor; + if (density <= 0.0) + continue; + + T *= 1.0-density*stepsize*absorption; + if (T <= 0.01) + break; + + vec3 lightDir = normalize(light_position-pos)*lscale; + float Tl = 1.0; + vec3 lpos = pos + lightDir; + int s = 0; + for (s; s < num_ligth_samples; ++s) { + float ld = texture(volumedata, lpos).x; + Tl *= 1.0-absorption*stepsize*ld; + if (Tl <= 0.01) + lpos += lightDir; + } + + vec3 Li = light_intensity*Tl; + Lo += Li*T*density*stepsize; + } + return vec4(Lo, 1-T); +} + +vec4 volumergba(vec3 front, vec3 dir, float stepsize) +{ + vec3 stepsize_dir = normalize(dir) * stepsize; + // The per-voxel alpha channel is specified in units of opacity/length. + // If our voxels are not isotropic, then the distance that we trace through + // depends on the direction. + vec3 pos = front; + float T = 1.0; + vec3 Lo = vec3(0.0); + int i = 0; + pos += stepsize_dir * rand();//apply first, to padd + for (i; i < num_samples && (!is_outside(pos) || i < 3); ++i, pos += stepsize_dir) { + + vec4 density = texture(volumedata, pos); + float opacity = stepsize * density.a; + T *= 1.0-opacity; + if (T <= 0.01) + break; + + Lo += (T*opacity)*density.rgb; + } + return vec4(Lo, 1-T); +} + +vec4 volumeindexedrgba(vec3 front, vec3 dir, float stepsize) +{ + vec3 stepsize_dir = normalize(dir) * stepsize; + // The per-voxel alpha channel is specified in units of opacity/length. + // If our voxels are not isotropic, then the distance that we trace through + // depends on the direction. + vec3 pos = front; + float T = 1.0; + vec3 Lo = vec3(0.0); + int i = 0; + pos += stepsize_dir * rand();//apply first, to padd + for (i; i < num_samples && (!is_outside(pos) || i < 3); ++i, pos += stepsize_dir) { + + int index = int(texture(volumedata, pos).x) - 1; + vec4 density = color_lookup(color_map, index); + float opacity = stepsize*density.a; + Lo += (T*opacity)*density.rgb; + T *= 1.0 - opacity; + if (T <= 0.01) + break; + } + return vec4(Lo, 1-T); +} + +vec4 contours(vec3 front, vec3 dir, float stepsize) +{ + vec3 stepsize_dir = normalize(dir) * stepsize; + // The per-voxel alpha channel is specified in units of opacity/length. + // If our voxels are not isotropic, then the distance that we trace through + // depends on the direction. + vec3 pos = front; + float T = 1.0; + vec3 Lo = vec3(0.0); + int i = 0; + pos += stepsize_dir * rand();//apply first, to padd + for (i; i < num_samples && (!is_outside(pos) || i < 3); ++i, pos += stepsize_dir) { + + float intensity = texture(volumedata, pos).x; + vec4 density = color_lookup(intensity, color_map, color_norm, color); + float opacity = density.a; + if(opacity > 0.0){ + vec3 N = gennormal(pos, vec3(stepsize)); + vec3 L = normalize(light_position - pos); + vec3 L2 = -L; + + Lo += (T*opacity) * blinn_phong(N, pos, L, density.rgb); + Lo += (T*opacity) * blinn_phong(N, pos, L2, density.rgb); + T *= 1.0 - opacity; + if (T <= 0.01) + break; + } + } + return vec4(Lo, 1-T); +} + +vec4 isosurface(vec3 front, vec3 dir, float stepsize) +{ + vec3 stepsize_dir = normalize(dir) * stepsize; + vec3 pos = front; + vec3 Lo = vec3(0.0); + int i = 0; + float T = 1.0; + pos += (stepsize_dir * rand());//apply first, to padd and reduce sampling artifacts + + vec4 difuse_color = color_lookup(isovalue, color_map, color_norm, color); + float opacity = difuse_color.a; + + for (i; i < num_samples && (!is_outside(pos) || i == 1); ++i, pos += stepsize_dir) + { + float density = texture(volumedata, pos).x; + if(abs(density - isovalue) < isorange) + { + vec3 N = gennormal(pos, vec3(stepsize)); + vec3 L = normalize(light_position - pos); + vec3 L2 = -L; + + Lo += (T*opacity) * blinn_phong(N, pos, L, difuse_color.rgb); + Lo += (T*opacity) * blinn_phong(N, pos, L2, difuse_color.rgb); + T *= 1.0 - opacity; + if (T <= 0.01) + break; + } + } + return vec4(Lo, 1.0 - T); +} + +vec4 mip(vec3 front, vec3 dir, float stepsize) +{ + vec3 stepsize_dir = normalize(dir) * stepsize; + vec3 pos = front; + int i = 0; + pos += stepsize_dir;//apply first, to padd + float maximum = 0.0; + for (i; i < num_samples && !is_outside(pos); ++i, pos += stepsize_dir) + { + float density = texture(volumedata, pos).x; + if(maximum < density) + maximum = density; + } + return color_lookup(maximum, color_map, color_norm, color); +} + +uniform uint objectid; + +void write2framebuffer(vec4 color, uvec2 id); + +void main() +{ + vec4 color; + vec3 dir = normalize(frag_vert - eyeposition); + dir = vec3(modelinv * vec4(dir, 0)); + float steps = step_size; + if(algorithm == 0) + color = isosurface(frag_uv, dir, steps); + else if(algorithm == 1) + color = volume(frag_uv, dir, steps); + else if(algorithm == 2) + color = mip(frag_uv, dir, steps); + else if(algorithm == 3) + color = volumergba(frag_uv, dir, steps); + else if(algorithm == 4) + color = volumeindexedrgba(frag_uv, dir, steps); + else + color = contours(frag_uv, dir, steps); + + write2framebuffer(color, uvec2(objectid, 0)); +} diff --git a/src/GLVisualize/assets/shader/volume.vert b/src/GLVisualize/assets/shader/volume.vert new file mode 100644 index 00000000000..6a489965b54 --- /dev/null +++ b/src/GLVisualize/assets/shader/volume.vert @@ -0,0 +1,18 @@ +{{GLSL_VERSION}} + +in vec3 vertices; +in vec3 texturecoordinates; + +out vec3 frag_vert; +out vec3 frag_uv; + +uniform mat4 projection, view, model; + + +void main() +{ + vec4 world_vert = model * vec4(vertices, 1); + frag_vert = world_vert.xyz; + frag_uv = texturecoordinates; + gl_Position = projection * view * world_vert; +} diff --git a/src/GLVisualize/boundingbox.jl b/src/GLVisualize/boundingbox.jl new file mode 100644 index 00000000000..c51f6003e9a --- /dev/null +++ b/src/GLVisualize/boundingbox.jl @@ -0,0 +1,58 @@ +AbsoluteRectangle(mini::Vec{N,T}, maxi::Vec{N,T}) where {N,T} = HyperRectangle{N,T}(mini, maxi-mini) + +AABB(a) = AABB{Float32}(a) +function (B::Type{AABB{T}})(a::Pyramid) where T + w,h = a.width/T(2), a.length + m = Vec{3,T}(a.middle) + B(m-Vec{3,T}(w,w,0), m+Vec{3,T}(w, w, h)) +end +(B::Type{AABB{T}})(a::Cube) where {T} = B(origin(a), widths(a)) +(B::Type{AABB{T}})(a::AbstractMesh) where {T} = B(vertices(a)) +(B::Type{AABB{T}})(a::NativeMesh) where {T} = B(gpu_data(a.data[:vertices])) + + +function (B::Type{AABB{T}})( + positions, scale, rotation, + primitive::AABB{T} + ) where T + + ti = TransformationIterator(positions, scale, rotation) + B(ti, primitive) +end +function (B::Type{AABB{T}})(instances::Instances) where T + ti = TransformationIterator(instances) + B(ti, B(instances.primitive)) +end + +function transform(translation, scale, rotation, points) + _max = Vec3f0(typemin(Float32)) + _min = Vec3f0(typemax(Float32)) + for p in points + x = scale.*Vec3f0(p) + rv = rotation*Vec4f0(x[1], x[2], x[3], 1f0) + x = Vec3f0(rv[1], rv[2], rv[3]) + x = Vec3f0(translation)+x + _min = min.(_min, x) + _max = max.(_max, x) + end + AABB{Float32}(_min, _max-_min) +end + +function (B::Type{AABB{T}})( + ti::TransformationIterator, primitive::AABB{T} + ) where T + v_state = iterate(ti) + v_state === nothing && return primitive + + tsr, state = v_state + points = decompose(Point3f0, primitive)::Vector{Point3f0} + bb = transform(tsr[1], tsr[2], tsr[3], points) + v_state = iterate(ti, state) + while v_state !== nothing + tsr, state = v_state + translatet_bb = transform(tsr[1], tsr[2], tsr[3], points) + bb = union(bb, translatet_bb) + v_state = iterate(ti, state) + end + bb +end diff --git a/src/GLVisualize/types.jl b/src/GLVisualize/types.jl new file mode 100644 index 00000000000..725e4f558d6 --- /dev/null +++ b/src/GLVisualize/types.jl @@ -0,0 +1,239 @@ +@enum Shape CIRCLE RECTANGLE ROUNDED_RECTANGLE DISTANCEFIELD TRIANGLE +@enum CubeSides TOP BOTTOM FRONT BACK RIGHT LEFT + +struct Grid{N, T <: AbstractRange} + dims::NTuple{N, T} +end +Base.ndims(::Grid{N,T}) where {N,T} = N + +Grid(ranges::AbstractRange...) = Grid(ranges) +function Grid(a::Array{T, N}) where {N, T} + s = Vec{N, Float32}(size(a)) + smax = maximum(s) + s = s./smax + Grid(ntuple(Val{N}) do i + range(0, stop=s[i], length=size(a, i)) + end) +end + +Grid(a::AbstractArray, ranges...) = Grid(a, ranges) + +""" +This constructor constructs a grid from ranges given as a tuple. +Due to the approach, the tuple `ranges` can consist of NTuple(2, T) +and all kind of range types. The constructor will make sure that all ranges match +the size of the dimension of the array `a`. +""" +function Grid(a::AbstractArray{T, N}, ranges::Tuple) where {T, N} + length(ranges) =! N && throw(ArgumentError( + "You need to supply a range for every dimension of the array. Given: $ranges + given Array: $(typeof(a))" + )) + Grid(ntuple(Val(N)) do i + range(first(ranges[i]), stop=last(ranges[i]), length=size(a, i)) + end) +end + +Base.length(p::Grid) = prod(size(p)) +Base.size(p::Grid) = map(length, p.dims) +function Base.getindex(p::Grid{N,T}, i) where {N,T} + inds = ind2sub(size(p), i) + Point{N, eltype(T)}(ntuple(Val(N)) do i + p.dims[i][inds[i]] + end) +end + +Base.iterate(g::Grid, i = 1) = i <= length(g) ? (g[i], i + 1) : nothing + +GLAbstraction.isa_gl_struct(x::Grid) = true +GLAbstraction.toglsltype_string(t::Grid{N,T}) where {N,T} = "uniform Grid$(N)D" +function GLAbstraction.gl_convert_struct(g::Grid{N, T}, uniform_name::Symbol) where {N,T} + return Dict{Symbol, Any}( + Symbol("$uniform_name.start") => Vec{N, Float32}(minimum.(g.dims)), + Symbol("$uniform_name.stop") => Vec{N, Float32}(maximum.(g.dims)), + Symbol("$uniform_name.lendiv") => Vec{N, Cint}(length.(g.dims) .- 1), + Symbol("$uniform_name.dims") => Vec{N, Cint}(map(length, g.dims)) + ) +end +function GLAbstraction.gl_convert_struct(g::Grid{1, T}, uniform_name::Symbol) where T + x = g.dims[1] + return Dict{Symbol, Any}( + Symbol("$uniform_name.start") => Float32(minimum(x)), + Symbol("$uniform_name.stop") => Float32(maximum(x)), + Symbol("$uniform_name.lendiv") => Cint(length(x) - 1), + Symbol("$uniform_name.dims") => Cint(length(x)) + ) +end +import Base: getindex, length, iterate, ndims, setindex!, eltype + + +to_cpu_mem(x) = x +to_cpu_mem(x::GPUArray) = gpu_data(x) + +const ScaleTypes = Union{Vector, Vec, AbstractFloat, Nothing, Grid} +const PositionTypes = Union{Vector, Point, AbstractFloat, Nothing, Grid} + +mutable struct ScalarRepeat{T} + scalar::T +end +ndims(::ScalarRepeat) = 1 +getindex(s::ScalarRepeat, i...) = s.scalar +#should setindex! really be allowed? It will set the index for the whole row... +setindex!(s::ScalarRepeat{T}, value, i...) where {T} = (s.scalar = T(value)) +eltype(::ScalarRepeat{T}) where {T} = T + +iterate(sr::ScalarRepeat, i = 1) = (sr.scalar, i + 1) + +struct Instances{P,T,S,R} + primitive::P + translation::T + scale::S + rotation::R +end + + + +function _Instances(position,px,py,pz, scale,sx,sy,sz, rotation, primitive) + args = (position,px,py,pz, scale,sx,sy,sz, rotation, primitive) + args = map(to_cpu_mem, args) + p = const_lift(ArrayOrStructOfArray, Point3f0, args[1:4]...) + s = const_lift(ArrayOrStructOfArray, Vec3f0, args[5:8]...) + r = const_lift(ArrayOrStructOfArray, Vec4f0, args[9]) + const_lift(Instances, args[10], p, s, r) +end +function _Instances(position, scale, rotation, primitive) + p = const_lift(ArrayOrStructOfArray, Point3f0, position) + s = const_lift(ArrayOrStructOfArray, Vec3f0, scale) + r = const_lift(ArrayOrStructOfArray, Vec4f0, rotation) + const_lift(Instances, primitive, p, s, r) +end + +struct GridZRepeat{G, T, N} <: AbstractArray{Point{3, T}, N} + grid::G + z::Array{T, N} +end +Base.size(g::GridZRepeat) = size(g.z) +Base.size(g::GridZRepeat, i) = size(g.z, i) +Base.IndexStyle(::Type{<:GridZRepeat}) = Base.IndexLinear() + +function Base.getindex(g::GridZRepeat{G, T}, i) where {G,T} + pxy = g.grid[i] + Point{3, T}(pxy[1], pxy[2], g.z[i]) +end + + + + + + +function ArrayOrStructOfArray(::Type{T}, array::Nothing, a, elements...) where T + StructOfArrays(T, a, elements...) +end +function ArrayOrStructOfArray(::Type{T}, array::StaticVector, a, elements...) where T + StructOfArrays(T, a, elements...) +end +function ArrayOrStructOfArray(::Type{T}, scalar::StaticVector, a::Nothing, elements::Nothing...) where T + ScalarRepeat(transform_convert(T, scalar)) +end +function ArrayOrStructOfArray(::Type{T1}, array::Array{T2}, a::Nothing, elements::Nothing...) where {T1,T2} + array +end +function ArrayOrStructOfArray(::Type{T1}, grid::Grid, x::Nothing, y::Nothing, z::Array) where T1<:Point + GridZRepeat(grid, z) +end +function ArrayOrStructOfArray(::Type{T1}, array::Grid, a::Nothing, elements::Nothing...) where T1<:Point + array +end +function ArrayOrStructOfArray(::Type{T}, scalar::T) where T + ScalarRepeat(scalar) +end +function ArrayOrStructOfArray(::Type{T}, array::Array) where T + array +end + + + + +struct TransformationIterator{T,S,R} + translation::T + scale::S + rotation::R +end +function TransformationIterator(instances::Instances) + TransformationIterator( + instances.translation, + instances.scale, + instances.rotation + ) +end +function iterate(t::TransformationIterator, state = 1) + states = ( + iterate(t.translation, state), + iterate(t.scale, state), + iterate(t.rotation, state) + ) + all(x-> x !== nothing, states) || return nothing + _translation, _scale, _rotation = first.(states) + translation = Point3f0(transform_convert(Vec3f0, _translation)) + scale = Vec3f0(transform_convert(Point3f0, _scale)) + rotation = to_rotation_mat(_rotation) + (translation, scale, rotation), last.(states) +end + + +import GeometryTypes: transform_convert + +# For quaternions +function to_rotation_mat(x::Vec{4, T}) where T + Mat4{T}(AbstractPlotting.Quaternionf0(x[1], x[2], x[3], x[4])) +end +# For relative rotations of a vector +function to_rotation_mat(x::StaticVector{2, T}) where T + to_rotation_mat(Vec3f0(x[1], x[2], 0)) +end +function to_rotation_mat(x::StaticVector{3, T}) where T + rotation = Vec3f0(transform_convert(Point3f0, x)) + v, u = normalize(rotation), Vec3f0(0, 0, 1) + # Unfortunately, we have to check for when u == -v, as u + v + # in this case will be (0, 0, 0), which cannot be normalized. + q = if (u == -v) + # 180 degree rotation around any orthogonal vector + other = (abs(dot(u, Vec{3, T}(1,0,0))) < 1.0) ? Vec{3, T}(1,0,0) : Vec{3, T}(0,1,0) + AbstractPlotting.qrotation(normalize(cross(u, other)), T(180)) + else + half = normalize(u+v) + vc = cross(u, half) + AbstractPlotting.Quaternionf0(dot(u, half), vc[1], vc[2], vc[3]) + end + Mat4{T}(q) +end + + + + +struct Intensity{T <: AbstractFloat} <: FieldVector{1, T} + i::T +end +@inline (I::Type{Intensity{T}})(i::Tuple) where {T <: AbstractFloat} = I(i...) +@inline (I::Type{Intensity{T}})(i::Intensity) where {T <: AbstractFloat} = I(i.i) +Intensity{T}(x::Color{Tc, 1}) where {T <: AbstractFloat, Tc} = Intensity{T}(gray(x)) + +const GLIntensity = Intensity{Float32} +export Intensity, GLIntensity + + +struct GLVisualizeShader <: AbstractLazyShader + paths::Tuple + kw_args::Dict{Symbol, Any} + function GLVisualizeShader(paths::String...; view = Dict{String, String}(), kw_args...) + # TODO properly check what extensions are available + @static if !Sys.isapple() + view["GLSL_EXTENSIONS"] = "#extension GL_ARB_conservative_depth: enable" + view["SUPPORTED_EXTENSIONS"] = "#define DETPH_LAYOUT" + end + args = Dict{Symbol, Any}(kw_args) + args[:view] = view + args[:fragdatalocation] = [(0, "fragment_color"), (1, "fragment_groupid")] + new(map(x-> assetpath("shader", x), paths), args) + end +end diff --git a/src/GLVisualize/utils.jl b/src/GLVisualize/utils.jl new file mode 100644 index 00000000000..0838bb62b2d --- /dev/null +++ b/src/GLVisualize/utils.jl @@ -0,0 +1,232 @@ +""" +Determines if of Image Type +""" +function isa_image(x::Type{T}) where T<:Matrix + eltype(T) <: Union{Colorant, Colors.Fractional} +end +isa_image(x::Matrix) = isa_image(typeof(x)) + +isa_image(x) = false + +# Splits a dictionary in two dicts, via a condition +function Base.split(condition::Function, associative::AbstractDict) + A = similar(associative) + B = similar(associative) + for (key, value) in associative + if condition(key, value) + A[key] = value + else + B[key] = value + end + end + A, B +end + + +function assemble_robj(data, program, bb, primitive, pre_fun, post_fun) + transp = get(data, :transparency, Node(false)) + overdraw = get(data, :overdraw, Node(false)) + pre = if pre_fun != nothing + () -> (GLAbstraction.StandardPrerender(transp, overdraw); pre_fun()) + else + GLAbstraction.StandardPrerender(transp, overdraw) + end + robj = RenderObject(data, program, pre, nothing, bb, nothing) + post = if haskey(data, :instances) + GLAbstraction.StandardPostrenderInstanced(data[:instances], robj.vertexarray, primitive) + else + GLAbstraction.StandardPostrender(robj.vertexarray, primitive) + end + robj.postrenderfunction = if post_fun != nothing + () -> begin + post() + post_fun() + end + else + post + end + robj +end + + +function assemble_shader(data) + shader = data[:shader] + delete!(data, :shader) + default_bb = Node(GeometryTypes.centered(AABB)) + bb = get(data, :boundingbox, default_bb) + if bb == nothing || isa(bb, Node{Nothing}) + bb = default_bb + end + glp = get(data, :gl_primitive, GL_TRIANGLES) + robj = assemble_robj( + data, shader, bb, glp, + get(data, :prerender, nothing), + get(data, :postrender, nothing) + ) + Context(robj) +end + + + + +function y_partition_abs(area, amount) + a = round(Int, amount) + p = const_lift(area) do r + ( + SimpleRectangle{Int}(0, 0, r.w, a), + SimpleRectangle{Int}(0, a, r.w, r.h - a) + ) + end + return lift(first, p), lift(last, p) +end +function x_partition_abs(area, amount) + a = round(Int, amount) + p = const_lift(area) do r + ( + SimpleRectangle{Int}(0, 0, a, r.h), + SimpleRectangle{Int}(a, 0, r.w - a, r.h) + ) + end + return lift(first, p), lift(last, p) +end + +function y_partition(area, percent) + amount = percent / 100.0 + p = const_lift(area) do r + ( + SimpleRectangle{Int}(0, 0, r.w, round(Int, r.h*amount)), + SimpleRectangle{Int}(0, round(Int, r.h*amount), r.w, round(Int, r.h*(1-amount))) + ) + end + return lift(first, p), lift(last, p) +end +function x_partition(area, percent) + amount = percent / 100.0 + p = const_lift(area) do r + ( + SimpleRectangle{Int}(0, 0, round(Int, r.w*amount), r.h ), + SimpleRectangle{Int}(round(Int, r.w*amount), 0, round(Int, r.w*(1-amount)), r.h) + ) + end + return lift(first, p), lift(last, p) +end + + +glboundingbox(mini, maxi) = AABB{Float32}(Vec3f0(mini), Vec3f0(maxi)-Vec3f0(mini)) +function default_boundingbox(main, model) + main == nothing && return Node(AABB{Float32}(Vec3f0(0), Vec3f0(1))) + const_lift(*, model, AABB{Float32}(main)) +end +AABB(a::GPUArray) = AABB{Float32}(gpu_data(a)) +AABB{T}(a::GPUArray) where {T} = AABB{T}(gpu_data(a)) + + + + +points2f0(positions::Vector{T}, range::AbstractRange) where {T} = Point2f0[Point2f0(range[i], positions[i]) for i=1:length(range)] + +extrema2f0(x::Array{T,N}) where {T<:Intensity,N} = Vec2f0(extrema(reinterpret(Float32,x))) +extrema2f0(x::Array{T,N}) where {T,N} = Vec2f0(extrema(x)) +extrema2f0(x::GPUArray) = extrema2f0(gpu_data(x)) +function extrema2f0(x::Array{T,N}) where {T<:Vec,N} + _norm = map(norm, x) + Vec2f0(minimum(_norm), maximum(_norm)) +end + +function mix_linearly(a::C, b::C, s) where C<:Colorant + RGBA{Float32}((1-s)*comp1(a)+s*comp1(b), (1-s)*comp2(a)+s*comp2(b), (1-s)*comp3(a)+s*comp3(b), (1-s)*alpha(a)+s*alpha(b)) +end + +color_lookup(cmap, value, mi, ma) = color_lookup(cmap, value, (mi, ma)) +function color_lookup(cmap, value, color_norm) + mi,ma = color_norm + scaled = clamp((value-mi)/(ma-mi), 0, 1) + index = scaled * (length(cmap)-1) + i_a, i_b = floor(Int, index)+1, ceil(Int, index)+1 + mix_linearly(cmap[i_a], cmap[i_b], scaled) +end + + +""" +Converts index arrays to the OpenGL equivalent. +""" +to_index_buffer(x::GLBuffer) = x +to_index_buffer(x::TOrSignal{Int}) = x +to_index_buffer(x::VecOrSignal{UnitRange{Int}}) = x +to_index_buffer(x::TOrSignal{UnitRange{Int}}) = x +""" +For integers, we transform it to 0 based indices +""" +to_index_buffer(x::AbstractVector{I}) where {I <: Integer} = indexbuffer(Cuint.(x .- 1)) +function to_index_buffer(x::Node{<: AbstractVector{I}}) where I <: Integer + indexbuffer(lift(x-> Cuint.(x .- 1), x)) +end + +""" +If already GLuint, we assume its 0 based (bad heuristic, should better be solved with some Index type) +""" +function to_index_buffer(x::VectorTypes{I}) where I <: Union{GLuint, Face{2, GLIndex}} + indexbuffer(x) +end + +to_index_buffer(x) = error( + "Not a valid index type: $(typeof(x)). + Please choose from Int, Vector{UnitRange{Int}}, Vector{Int} or a signal of either of them" +) + +""" +Creates a moving average and discards values to close together. +If discarded return (false, p), if smoothed, (true, smoothed_p). +""" +function moving_average(p, cutoff, history, n = 5) + if length(history) > 0 + if norm(p - history[end]) < cutoff + return false, p # don't keep point + end + end + if length(history) == 5 + # maybe better to just keep a current index + history[1:5] = circshift(view(history, 1:5), -1) + history[end] = p + else + push!(history, p) + end + true, sum(history) ./ length(history)# smooth +end + +function layoutlinspace(n::Integer) + if n == 1 + 1:1 + else + range(1/n, stop=1, length=n) + end +end +xlayout(x::Int) = zip(layoutlinspace(x), Iterators.repeated("")) +function xlayout(x::AbstractVector{T}) where T <: AbstractFloat + zip(x, Iterators.repeated("")) +end + +function xlayout(x::AbstractVector) + zip(layoutlinspace(length(x)), x) +end +function ylayout(x::AbstractVector) + zip(layoutlinspace(length(x)), x) +end +function ylayout(x::AbstractVector{T}) where T <: Tuple + sizes = map(first, x) + values = map(last, x) + zip(sizes, values) +end + +function layout_rect(area, lastw, lasth, w, h) + wp = widths(area) + xmin = wp[1] * lastw + ymin = wp[2] * lasth + xmax = wp[1] * w + ymax = wp[2] * h + xmax = max(xmin, xmax) + xmin = min(xmin, xmax) + ymax = max(ymin, ymax) + ymin = min(ymin, ymax) + AbstractPlotting.IRect(xmin, ymin, xmax - xmin, ymax - ymin) +end diff --git a/src/GLVisualize/visualize/image_like.jl b/src/GLVisualize/visualize/image_like.jl new file mode 100644 index 00000000000..da718877950 --- /dev/null +++ b/src/GLVisualize/visualize/image_like.jl @@ -0,0 +1,304 @@ +""" +A matrix of colors is interpreted as an image +""" +_default(::Node{Array{RGBA{N0f8}, 2}}, ::Style{:default}, ::Dict{Symbol,Any}) + + +function _default(main::MatTypes{T}, ::Style, data::Dict) where T <: Colorant + @gen_defaults! data begin + spatialorder = "yx" + end + if !(spatialorder in ("xy", "yx")) + error("Spatial order only accepts \"xy\" or \"yz\" as a value. Found: $spatialorder") + end + ranges = get(data, :ranges) do + const_lift(main, spatialorder) do m, s + (0:size(m, s == "xy" ? 1 : 2), 0:size(m, s == "xy" ? 2 : 1)) + end + end + delete!(data, :ranges) + @gen_defaults! data begin + image = main => (Texture, "image, can be a Texture or Array of colors") + primitive::GLUVMesh2D = const_lift(ranges) do r + x, y = minimum(r[1]), minimum(r[2]) + xmax, ymax = maximum(r[1]), maximum(r[2]) + SimpleRectangle{Float32}(x, y, xmax - x, ymax - y) + end + preferred_camera = :orthographic_pixel + fxaa = false + shader = GLVisualizeShader( + "fragment_output.frag", "uv_vert.vert", "texture.frag", + view = Dict("uv_swizzle" => "o_uv.$(spatialorder)") + ) + end +end +function _default(main::VectorTypes{T}, ::Style, data::Dict) where T <: Colorant + @gen_defaults! data begin + image = main => (Texture, "image, can be a Texture or Array of colors") + primitive::GLUVMesh2D = SimpleRectangle{Float32}(0f0, 0f0, length(to_value(main)), 50f0) => "the 2D mesh the image is mapped to. Can be a 2D Geometry or mesh" + preferred_camera = :orthographic_pixel + fxaa = false + shader = GLVisualizeShader( + "fragment_output.frag", "uv_vert.vert", "texture.frag", + view = Dict("uv_swizzle" => "o_uv.xy") + ) + end +end + +""" +A matrix of Intensities will result in a contourf kind of plot +""" +function gl_heatmap(main::MatTypes{T}, data::Dict) where T <: AbstractFloat + main_v = to_value(main) + @gen_defaults! data begin + ranges = (0:size(main_v, 1), 0:size(main_v, 2)) + end + x, y, xw, yh = minimum(ranges[1]), minimum(ranges[2]), maximum(ranges[1]), maximum(ranges[2]) + @gen_defaults! data begin + intensity = main => Texture + color_map = default(Vector{RGBA{N0f8}},s) => Texture + primitive::GLUVMesh2D = SimpleRectangle{Float32}(x, y, xw-x, yh-y) + color_norm = const_lift(extrema2f0, main) + stroke_width::Float32 = 0.05f0 + levels::Float32 = 5f0 + stroke_color = RGBA{Float32}(1,1,1,1) + shader = GLVisualizeShader("fragment_output.frag", "uv_vert.vert", "intensity.frag") + fxaa = false + end +end + +""" +Float matrix with the style distancefield will be interpreted as a distancefield. +A distancefield is describing a shape, with positive values denoting the inside +of the shape, negative values the outside and 0 the border +""" +function _default(main::MatTypes{T}, s::style"distancefield", data::Dict) where T <: AbstractFloat + @gen_defaults! data begin + distancefield = main => Texture + shape = DISTANCEFIELD + fxaa = false + end + rect = SimpleRectangle{Float32}(0f0,0f0, size(to_value(main))...) + _default((rect, Point2f0[0]), s, data) +end + + +export play +""" + play(img, timedim, t) + +Slice a 3D array along axis `timedim` at time `t`. +This can be used to treat a 3D array like a video and create an image stream from it. +""" +function play(array::Array{T, 3}, timedim::Integer, t::Integer) where T + index = ntuple(dim-> dim == timedim ? t : Colon(), Val(3)) + array[index...] +end + +""" + play(buffer, video_stream, t) + +Plays a video stream from VideoIO.jl. You need to supply the image `buffer`, +which will be reused for better performance. +""" +function play(buffer::Array{T, 2}, video_stream, t) where T + eof(video_stream) && seekstart(video_stream) + w, h = size(buffer) + buffer = reinterpret(UInt8, buffer, (3, w,h)) + read!(video_stream, buffer) # looses type and shape + return reinterpret(T, buffer, (w,h)) +end + + +unwrap(img::AxisArrays.AxisArray) = unwrap(img.data) +unwrap(img::AbstractArray) = img + +GLAbstraction.gl_convert(::Type{T}, img::AbstractArray) where {T} = _gl_convert(T, unwrap(img)) +_gl_convert(::Type{T}, img::Array) where {T} = gl_convert(T, img) + +""" + play(img) + +Turns an Image into a video stream +""" +function play(img::HasAxesArray{T, 3}) where T + ax = ImageAxes.timeaxis(img) + if ImageAxes.timeaxis(img) != nothing + return const_lift(play, unwrap(img), ImageAxes.timedim(img), loop(1:length(ax))) + end + error("Image has no time axis: axes(img) = $(axes(img))") +end + +""" +Takes a 3D image and decides if it is a volume or an animated Image. +""" +function _default(img::HasAxesArray{T, 3}, s::Style, data::Dict) where T + # We could do this as a @traitfn, except that those don't + # currently mix well with non-trait specialization. + if ImageAxes.timeaxis(img) != nothing + data[:spatialorder] = "yx" + td = ImageAxes.timedim(img) + video_signal = const_lift(play, unwrap(img), td, loop(1:size(img, timedim))) + return _default(video_signal, s, data) + else + ps = ImageAxes.pixelspacing(img) + spacing = Vec3f0(map(x-> x / maximum(ps), ps)) + pdims = Vec3f0(map(length, indices(img))) + dims = pdims .* spacing + dims = dims/maximum(dims) + data[:dimensions] = dims + _default(unwrap(img), s, data) + end +end +function _default(img::TOrSignal{T}, s::Style, data::Dict) where T <: AxisMatrix + @gen_defaults! data begin + ranges = const_lift(img) do img + ps = ImageAxes.pixelspacing(img) + spacing = Vec2f0(map(x-> x / maximum(ps), ps)) + pdims = Vec2f0(map(length, indices(img))) + dims = pdims .* spacing + dims = dims / maximum(dims) + (0:dims[1], 0:dims[2]) + end + end + _default(const_lift(unwrap, img), s, data) +end + +""" +Displays 3D array as movie with 3rd dimension as time dimension +""" +function _default(img::AbstractArray{T, 3}, s::Style, data::Dict) where T + video_signal = const_lift(play, unwrap(img), 3, loop(1:size(img, 3))) + return _default(video_signal, s, data) +end + + +""" +Takes a shader as a parametric function. The shader should contain a function stubb +like this: +```GLSL +uniform float arg1; // you can add arbitrary uniforms and supply them via the keyword args +float function(float x) { + return arg1*sin(1/tan(x)); +} +``` +""" +_default(func::String, s::Style{:shader}, data::Dict) = @gen_defaults! data begin + color = default(RGBA, s) => Texture + dimensions = (120f0, 120f0) + primitive::GLUVMesh2D = SimpleRectangle{Float32}(0f0,0f0, dimensions...) + preferred_camera = :orthographic_pixel + fxaa = false + shader = GLVisualizeShader( + "fragment_output.frag", "parametric.vert", "parametric.frag", + view = Dict("function" => func) + ) +end + + +#Volumes +const VolumeElTypes = Union{Gray, AbstractFloat, Intensity} + +const default_style = Style{:default}() + +function _default(a::VolumeTypes{T}, s::Style{:iso}, data::Dict) where T <: VolumeElTypes + data = @gen_defaults! data begin + isovalue = 0.5f0 + algorithm = IsoValue + end + _default(a, default_style, data) +end + +function _default(a::VolumeTypes{T}, s::Style{:absorption}, data::Dict) where T<:VolumeElTypes + data = @gen_defaults! data begin + absorption = 1f0 + algorithm = Absorption + end + _default(a, default_style, data) +end + +function _default(a::VolumeTypes{T}, s::Style{:absorption}, data::Dict) where T<:RGBA + data = @gen_defaults! data begin + algorithm = AbsorptionRGBA + end + _default(a, default_style, data) +end + +using .GLAbstraction: StandardPrerender + +struct VolumePrerender + sp::StandardPrerender +end +VolumePrerender(a, b) = VolumePrerender(StandardPrerender(a, b)) + +function (x::VolumePrerender)() + x.sp() + glEnable(GL_CULL_FACE) + glCullFace(GL_FRONT) +end + +function _default(main::VolumeTypes{T}, s::Style, data::Dict) where T <: VolumeElTypes + @gen_defaults! data begin + volumedata = main => Texture + hull::GLUVWMesh = AABB{Float32}(Vec3f0(0), Vec3f0(1)) + light_position = Vec3f0(0.25, 1.0, 3.0) + light_intensity = Vec3f0(15.0) + model = Mat4f0(I) + modelinv = const_lift(inv, model) + + color_map = default(Vector{RGBA}, s) => Texture + color_norm = color_map == nothing ? nothing : const_lift(extrema2f0, main) + color = color_map == nothing ? default(RGBA, s) : nothing + + algorithm = MaximumIntensityProjection + absorption = 1f0 + isovalue = 0.5f0 + isorange = 0.01f0 + shader = GLVisualizeShader("fragment_output.frag", "util.vert", "volume.vert", "volume.frag") + prerender = VolumePrerender(data[:transparency], data[:overdraw]) + postrender = () -> begin + glDisable(GL_CULL_FACE) + end + end +end + +function _default(main::VolumeTypes{T}, s::Style, data::Dict) where T <: RGBA + @gen_defaults! data begin + volumedata = main => Texture + hull::GLUVWMesh = AABB{Float32}(Vec3f0(0), Vec3f0(1)) + model = Mat4f0(I) + modelinv = const_lift(inv, model) + + # These don't do anything but are needed for type specification in the frag shader + color_map = nothing + color_norm = nothing + color = color_map == nothing ? default(RGBA, s) : nothing + + algorithm = AbsorptionRGBA + shader = GLVisualizeShader("fragment_output.frag", "util.vert", "volume.vert", "volume.frag") + prerender = VolumePrerender() + postrender = () -> begin + glDisable(GL_CULL_FACE) + end + end +end + +function _default(main::IndirectArray{T}, s::Style, data::Dict) where T <: RGBA + @gen_defaults! data begin + volumedata = main.index => Texture + hull::GLUVWMesh = AABB{Float32}(Vec3f0(0), Vec3f0(1)) + model = Mat4f0(I) + modelinv = const_lift(inv, model) + + color_map = main.values => TextureBuffer + color_norm = nothing + color = nothing + + algorithm = IndexedAbsorptionRGBA + shader = GLVisualizeShader("fragment_output.frag", "util.vert", "volume.vert", "volume.frag") + prerender = VolumePrerender() + postrender = () -> begin + glDisable(GL_CULL_FACE) + end + end +end diff --git a/src/GLVisualize/visualize/lines.jl b/src/GLVisualize/visualize/lines.jl new file mode 100644 index 00000000000..992475356b3 --- /dev/null +++ b/src/GLVisualize/visualize/lines.jl @@ -0,0 +1,178 @@ +function sumlengths(points) + T = eltype(points[1]) + result = zeros(T, length(points)) + for i=1:length(points) + i0 = max(i-1,1) + p1, p2 = points[i0], points[i] + if !(any(map(isnan, p1)) || any(map(isnan, p2))) + result[i] = result[i0] + norm(p1-p2) + else + result[i] = result[i0] + end + end + result +end + +intensity_convert(intensity, verts) = intensity +function intensity_convert(intensity::VecOrSignal{T}, verts) where T + if length(to_value(intensity)) == length(to_value(verts)) + GLBuffer(intensity) + else + Texture(intensity) + end +end +function intensity_convert_tex(intensity::VecOrSignal{T}, verts) where T + if length(to_value(intensity)) == length(to_value(verts)) + TextureBuffer(intensity) + else + Texture(intensity) + end +end +#TODO NaNMath.min/max? +dist(a, b) = abs(a-b) +mindist(x, a, b) = min(dist(a, x), dist(b, x)) +function gappy(x, ps) + n = length(ps) + x <= first(ps) && return first(ps) - x + for j=1:(n-1) + p0 = ps[j] + p1 = ps[min(j+1, n)] + if p0 <= x && p1 >= x + return mindist(x, p0, p1) * (isodd(j) ? 1 : -1) + end + end + return last(ps) - x +end +function ticks(points, resolution) + Float16[gappy(x, points) for x = range(first(points), stop=last(points), length=resolution)] +end + + +# ambigious signature +function _default(position::VectorTypes{<: Point}, s::style"lines", data::Dict) + line_visualization(position, data) +end +function _default(position::MatTypes{<:Point}, s::style"lines", data::Dict) + line_visualization(position, data) +end +function line_visualization(position::Union{VectorTypes{T}, MatTypes{T}}, data::Dict) where T<:Point + pv = to_value(position) + p_vec = if isa(position, GPUArray) + position + else + const_lift(position) do p + pvv = vec(p) + if length(pvv) < 4 # geometryshader doesn't work with less then 4 + return [pvv..., fill(T(NaN), 4-length(pvv))...] + else + return pvv + end + end + end + + @gen_defaults! data begin + dims::Vec{2, Int32} = const_lift(position) do p + sz = ndims(p) == 1 ? (length(p), 1) : size(p) + Vec{2, Int32}(sz) + end + vertex = p_vec => GLBuffer + intensity = nothing + color_map = nothing => Texture + color_norm = nothing + color = (color_map == nothing ? default(RGBA, s) : nothing) => GLBuffer + thickness::Float32 = 2f0 + pattern = nothing + fxaa = false + preferred_camera = :orthographic_pixel + indices = const_lift(length, p_vec) => to_index_buffer + shader = GLVisualizeShader("fragment_output.frag", "util.vert", "lines.vert", "lines.geom", "lines.frag") + gl_primitive = GL_LINE_STRIP_ADJACENCY + startend = const_lift(p_vec) do vec + l = length(vec) + map(1:l) do i + (i == 1 || isnan(vec[max(i-1, 1)])) && return Float32(0) # start + (i == l || isnan(vec[min(i+1, l)])) && return Float32(1) # end + Float32(2) # segment + end + end => GLBuffer + end + if pattern != nothing + if !isa(pattern, Texture) + if !isa(pattern, Vector) + error("Pattern needs to be a Vector of floats. Found: $(typeof(pattern))") + end + tex = GLAbstraction.Texture(ticks(pattern, 100), x_repeat = :repeat) + data[:pattern] = tex + end + @gen_defaults! data begin + pattern_length = Float32(last(pattern)) + lastlen = const_lift(sumlengths, p_vec) => GLBuffer + maxlength = const_lift(last, lastlen) + end + end + data[:intensity] = intensity_convert(intensity, vertex) + data +end + +to_points(x::Vector{LineSegment{T}}) where {T} = reinterpret(T, x, (length(x)*2,)) + +_default(positions::VectorTypes{LineSegment{T}}, s::Style, data::Dict) where {T <: Point} = + _default(const_lift(to_points, positions), style"linesegment"(), data) + +function _default(positions::VectorTypes{T}, s::style"linesegment", data::Dict) where T <: Point + @gen_defaults! data begin + vertex = positions => GLBuffer + color = default(RGBA, s, 1) => GLBuffer + thickness = 2f0 => GLBuffer + shape = RECTANGLE + pattern = nothing + fxaa = false + indices = const_lift(length, positions) => to_index_buffer + # TODO update boundingbox + shader = GLVisualizeShader("fragment_output.frag", "util.vert", "line_segment.vert", "line_segment.geom", "lines.frag") + gl_primitive = GL_LINES + end + if !isa(pattern, Texture) && pattern != nothing + if !isa(pattern, Vector) + error("Pattern needs to be a Vector of floats") + end + tex = GLAbstraction.Texture(ticks(pattern, 100), x_repeat = :repeat) + data[:pattern] = tex + data[:pattern_length] = Float32(last(pattern)) + end + data +end + +function _default(positions::Vector{T}, range::AbstractRange, s::style"lines", data::Dict) where T <: AbstractFloat + length(positions) != length(range) && throw( + DimensionMismatsch("length of $(typeof(positions)) $(length(positions)) and $(typeof(range)) $(length(range)) must match") + ) + _default(points2f0(positions, range), s, data) +end + +function line_indices(array) + len = length(array) + result = Array(GLuint, len*2) + idx = 1 + for i=0:(len-3), j=0:1 + result[idx] = i+j + idx += 1 + end + result + #GLuint[i+j for i=0:(len-3) for j=0:1] # on 0.5 +end +""" +Fast, non anti aliased lines +""" +function _default(position::VectorTypes{T}, s::style"speedlines", data::Dict) where T <: Point + @gen_defaults! data begin + vertex = position => GLBuffer + color_map = nothing => Vec2f0 + indices = const_lift(line_indices, position) => to_index_buffer + color = (color_map == nothing ? default(RGBA{Float32}, s) : nothing) => GLBuffer + color_norm = nothing => Vec2f0 + intensity = nothing => GLBuffer + shader = GLVisualizeShader("fragment_output.frag", "dots.vert", "dots.frag") + gl_primitive = GL_LINES + end +end diff --git a/src/GLVisualize/visualize/mesh.jl b/src/GLVisualize/visualize/mesh.jl new file mode 100644 index 00000000000..14ec7e58456 --- /dev/null +++ b/src/GLVisualize/visualize/mesh.jl @@ -0,0 +1,59 @@ +function _default(mesh::TOrSignal{M}, s::Style, data::Dict) where M <: GLNormalAttributeMesh + @gen_defaults! data begin + main = mesh + shading = true + color = nothing + shader = GLVisualizeShader( + "fragment_output.frag", "util.vert", "attribute_mesh.vert", "standard.frag", + view = Dict("light_calc" => light_calc(shading)) + ) + end +end + +function _default(mesh::TOrSignal{M}, s::Style, data::Dict) where M <: GLNormalMesh + @gen_defaults! data begin + shading = true + main = mesh + color = default(RGBA{Float32}, s) + shader = GLVisualizeShader( + "fragment_output.frag", "util.vert", "standard.vert", "standard.frag", + view = Dict("light_calc" => light_calc(shading)) + ) + end +end +function _default(mesh::TOrSignal{M}, s::Style, data::Dict) where M <: GLNormalUVMesh + @gen_defaults! data begin + shading = true + main = mesh + color = default(RGBA{Float32}, s) => Texture + + shader = GLVisualizeShader( + "fragment_output.frag", "util.vert", "uv_normal.vert", "standard.frag", + view = Dict("light_calc" => light_calc(shading)) + ) + end +end +function _default(mesh::TOrSignal{M}, s::Style, data::Dict) where M <: GLNormalVertexcolorMesh + @gen_defaults! data begin + shading = true + main = mesh + color = nothing + shader = GLVisualizeShader( + "fragment_output.frag", "util.vert", "vertexcolor.vert", "standard.frag", + view = Dict("light_calc" => light_calc(shading)) + ) + end +end + +function _default(mesh::GLNormalColorMesh, s::Style, data::Dict) + data[:color] = decompose(RGBA{Float32}, mesh) + _default(GLNormalMesh(mesh), s, data) +end + +function _default(mesh::TOrSignal{M}, s::Style, data::Dict) where M <: GLPlainMesh + @gen_defaults! data begin + primitive::GLPlainMesh = mesh + color = default(RGBA, s, 1) + shader = GLVisualizeShader("fragment_output.frag", "plain.vert", "plain.frag") + end +end diff --git a/src/GLVisualize/visualize/particles.jl b/src/GLVisualize/visualize/particles.jl new file mode 100644 index 00000000000..5956170c961 --- /dev/null +++ b/src/GLVisualize/visualize/particles.jl @@ -0,0 +1,555 @@ +#= +A lot of visualization forms in GLVisualize are realised in the form of instanced +particles. This is because they can be handled very efficiently by OpenGL. +There are quite a few different ways to feed instances with different attributes. +The main constructor for particles is a tuple of (Primitive, Position), whereas +position can come in all forms and shapes. You can leave away the primitive. +In that case, GLVisualize will fill in some default that is anticipated to make +the most sense for the datatype. +=# + +#3D primitives +const Primitives3D = Union{AbstractGeometry{3}, AbstractMesh} +#2D primitives AKA sprites, since they are shapes mapped onto a 2D rectangle +const Sprites = Union{AbstractGeometry{2}, Shape, Char, Type} +const AllPrimitives = Union{AbstractGeometry, Shape, Char, AbstractMesh} + + +""" +We plot simple Geometric primitives as particles with length one. +At some point, this should all be appended to the same particle system to increase +performance. +""" +function _default( + geometry::TOrSignal{G}, s::Style, data::Dict + ) where G <: GeometryPrimitive{2} + data[:offset] = Vec2f0(0) + _default((geometry, const_lift(x-> Point2f0[minimum(x)], geometry)), s, data) +end + +""" +Vectors of floats are treated as barplots, so they get a HyperRectangle as +default primitive. +""" +function _default(main::VectorTypes{T}, s::Style, data::Dict) where T <: AbstractFloat + _default((centered(HyperRectangle{2, Float32}), main), s, data) +end +""" +Matrices of floats are represented as 3D barplots with cubes as primitive +""" +function _default(main::MatTypes{T}, s::Style, data::Dict) where T <: AbstractFloat + _default((AABB(Vec3f0(-0.5,-0.5,0), Vec3f0(1.0)), main), s, data) +end +""" +Vectors of n-dimensional points get ndimensional rectangles as default +primitives. (Particles) +""" +function _default(main::VectorTypes{P}, s::Style, data::Dict) where P <: Point + N = length(P) + @gen_defaults! data begin + scale = N == 2 ? Vec2f0(30) : Vec3f0(0.03) # for 2D points we assume they're in pixels + end + _default((centered(HyperRectangle{N, Float32}), main), s, data) +end + +""" +3D matrices of vectors are 3D vector field with a pyramid (arrow) like default +primitive. +""" +function _default(main::ArrayTypes{T, 3}, s::Style, data::Dict) where T<:Vec + _default((Pyramid(Point3f0(0, 0, -0.5), 1f0, 1f0), main), s, data) +end +""" +2D matrices of vectors are 2D vector field with a an unicode arrow as the default +primitive. +""" +function _default(main::ArrayTypes{T, 2}, s::Style, data::Dict) where T<:Vec + _default(('⬆', main), s, data) +end + +""" +Vectors with `Vec` as element type are treated as vectors of rotations. +The position is assumed to be implicitely on the grid the vector defines (1D,2D,3D grid) +""" +function _default( + main::Tuple{P, ArrayTypes{T, N}}, s::Style, data::Dict + ) where {P <: AllPrimitives, T <: Vec, N} + primitive, rotation_s = main + rotation_v = to_value(rotation_s) + @gen_defaults! data begin + color_norm = const_lift(extrema2f0, rotation_s) + ranges = ntuple(i->LinRange(0f0, 1f0, size(rotation_v, i)), N) + end + grid = Grid(rotation_v, ranges) + + if N == 1 + scalevec = Vec2f0(step(grid.dims[1]), 1) + elseif N == 2 + scalevec = Vec2f0(step(grid.dims[1]), step(grid.dims[2])) + else + scalevec = Vec3f0(ntuple(i->step(grid.dims[i]), 3)).*Vec3f0(0.4,0.4, 1/to_value(color_norm)[2]*4) + end + if P <: Char # we need to preserve proportion of the glyph + scalevec = Vec2f0(glyph_scale!(primitive, scalevec[1])) + @gen_defaults! data begin # for chars we need to make sure they're centered + offset = -scalevec/2f0 + end + end + @gen_defaults! data begin + rotation = const_lift(vec, rotation_s) + color_map = default(Vector{RGBA}) + scale = scalevec + color = nothing + end + _default((primitive, grid), s, data) +end + +""" +arrays of floats with any geometry primitive, will be spaced out on a grid defined +by `ranges` and will use the floating points as the +height for the primitives (`scale_z`) +""" +function _default( + main::Tuple{P, ArrayTypes{T,N}}, s::Style, data::Dict + ) where {P<:AbstractGeometry, T<:AbstractFloat, N} + primitive, heightfield_s = main + heightfield = to_value(heightfield_s) + @gen_defaults! data begin + ranges = ntuple(i->LinRange(0f0, 1f0, size(heightfield, i)), N) + end + grid = Grid(heightfield, ranges) + @gen_defaults! data begin + scale = nothing + scale_x::Float32 = step(grid.dims[1]) + scale_y::Float32 = N == 1 ? 1f0 : step(grid.dims[2]) + scale_z = const_lift(vec, heightfield_s) + color = nothing + color_map = color == nothing ? default(Vector{RGBA}) : nothing + color_norm = color == nothing ? const_lift(extrema2f0, heightfield_s) : nothing + end + _default((primitive, grid), s, data) +end + +""" +arrays of floats with the sprite primitive type (2D geometry + picture like), +will be spaced out on a grid defined +by `ranges` and will use the floating points as the +z position for the primitives. +""" +function _default( + main::Tuple{P, ArrayTypes{T,N}}, s::Style, data::Dict + ) where {P <: Sprites, T <: AbstractFloat, N} + primitive, heightfield_s = main + heightfield = to_value(heightfield_s) + @gen_defaults! data begin + ranges = ntuple(i->LinRange(0f0, 1f0, size(heightfield, i)), N) + end + grid = Grid(heightfield, ranges) + @gen_defaults! data begin + position_z = const_lift(vec, heightfield_s) + scale = Vec2f0(step(grid.dims[1]), N>=2 ? step(grid.dims[2]) : 1f0) + color_map = default(Vector{RGBA}) + color = nothing + color_norm = const_lift(extrema2f0, heightfield_s) + end + _default((primitive, grid), s, data) +end + +""" +Sprites primitives with a vector of floats are treated as something barplot like +""" +function _default( + main::Tuple{P, VectorTypes{T}}, s::Style, data::Dict + ) where {P <: AllPrimitives, T <: AbstractFloat} + primitive, heightfield_s = main + heightfield = to_value(heightfield_s) + @gen_defaults! data begin + ranges = range(0f0, stop = 1f0, length = length(heightfield)) + end + grid = Grid(heightfield, ranges) + delete!(data, :ranges) + @gen_defaults! data begin + scale = nothing + scale_x::Float32 = step(grid.dims[1]) + scale_y = heightfield_s + scale_z::Float32 = 1f0 + end + _default((primitive, grid), s, data) +end + + + + +# There is currently no way to get the two following two signatures +# under one function, which is why we delegate to meshparticle +function _default( + p::Tuple{TOrSignal{Pr}, VectorTypes{P}}, s::Style, data::Dict + ) where {Pr <: Primitives3D, P <: Point} + meshparticle(p, s, data) +end + +function _default( + p::Tuple{TOrSignal{Pr}, G}, s::Style, data::Dict + ) where {Pr <: Primitives3D, G <: Tuple} + @gen_defaults! data begin + primitive = p[1] + position = nothing => TextureBuffer + position_x = p[2][1] => TextureBuffer + position_y = p[2][2] => TextureBuffer + position_z = length(p[2]) > 2 ? p[2][3] : 0f0 => TextureBuffer + instances = const_lift(length, position_x) + end + meshparticle(p, s, data) +end + +function _default( + p::Tuple{TOrSignal{Pr}, G}, s::Style, data::Dict + ) where {Pr <: Primitives3D, G <: Grid} + meshparticle(p, s, data) +end + +# make conversion of mesh signals work. TODO move to GeometryTypes? +function Base.convert(::Type{T}, mesh::Node) where T<:GeometryTypes.HomogenousMesh + lift(T, mesh) +end + + +function to_meshcolor(color::TOrSignal{Vector{T}}) where T <: Colorant + TextureBuffer(color) +end + +function to_meshcolor(color::TOrSignal{Matrix{T}}) where T <: Colorant + Texture(color) +end +function to_meshcolor(color) + color +end + +function to_mesh(mesh::TOrSignal{<: GeometryPrimitive}) + gl_convert(const_lift(GLNormalMesh, mesh)) +end + +function to_mesh(mesh::TOrSignal{<: HomogenousMesh}) + gl_convert(to_value(mesh)) +end + +function orthogonal(v::T) where T <: StaticVector{3} + x, y, z = abs.(v) + other = x < y ? (x < z ? unit(T, 1) : unit(T, 3)) : (y < z ? unit(T, 2) : unit(T, 3)) + return cross(v, other) +end + +using AbstractPlotting +using AbstractPlotting: get_texture_atlas + + +vec2quaternion(rotation::StaticVector{4}) = rotation + +function vec2quaternion(r::StaticVector{2}) + vec2quaternion(Vec3f0(r[1], r[2], 0)) +end +function vec2quaternion(rotation::StaticVector{3}) + AbstractPlotting.rotation_between(Vec3f0(0, 0, 1), Vec3f0(rotation)) +end + +vec2quaternion(rotation::Vec4f0) = rotation +vec2quaternion(rotation::VectorTypes) = const_lift(x-> vec2quaternion.(x), rotation) +vec2quaternion(rotation::Node) = lift(vec2quaternion, rotation) +vec2quaternion(rotation::AbstractPlotting.Quaternion)= Vec4f0(rotation.data) +""" +This is the main function to assemble particles with a GLNormalMesh as a primitive +""" +function meshparticle(p, s, data) + rot = get!(data, :rotation, Vec4f0(0, 0, 0, 1)) + rot = vec2quaternion(rot) + delete!(data, :rotation) + @gen_defaults! data begin + primitive = p[1] => to_mesh + position = p[2] => TextureBuffer + position_x = nothing => TextureBuffer + position_y = nothing => TextureBuffer + position_z = nothing => TextureBuffer + + scale = Vec3f0(1) => TextureBuffer + scale_x = nothing => TextureBuffer + scale_y = nothing => TextureBuffer + scale_z = nothing => TextureBuffer + + rotation = rot => TextureBuffer + texturecoordinates = nothing + end + + @gen_defaults! data begin + color_map = nothing => Texture + color_norm = nothing + intensity = nothing + color = if color_map == nothing + default(RGBA{Float32}, s) + else + nothing + end => to_meshcolor + + instances = const_lift(length, position) + shading = true + shader = GLVisualizeShader( + "util.vert", "particles.vert", "fragment_output.frag", "standard.frag", + view = Dict( + "position_calc" => position_calc(position, position_x, position_y, position_z, TextureBuffer), + "light_calc" => light_calc(shading) + ) + ) + end + if AbstractPlotting.to_value(intensity) != nothing + if AbstractPlotting.to_value(position) != nothing + data[:intensity] = intensity_convert_tex(intensity, position) + data[:len] = const_lift(length, position) + else + data[:intensity] = intensity_convert_tex(intensity, position_x) + data[:len] = const_lift(length, position_x) + end + end + data +end + +""" +This is the most primitive particle system, which uses simple points as primitives. +This is supposed to be the fastest way of displaying particles! +""" +_default(position::VectorTypes{T}, s::style"speed", data::Dict) where {T <: Point} = @gen_defaults! data begin + vertex = position => GLBuffer + color_map = nothing => Vec2f0 + color = (color_map == nothing ? default(RGBA{Float32}, s) : nothing) => GLBuffer + + color_norm = nothing => Vec2f0 + intensity = nothing => GLBuffer + point_size = 2f0 + prerender = ()->glPointSize(point_size) + shader = GLVisualizeShader("fragment_output.frag", "dots.vert", "dots.frag") + gl_primitive = GL_POINTS +end + +""" +returns the Shape for the distancefield algorithm +""" +primitive_shape(::Char) = DISTANCEFIELD +primitive_shape(x::X) where {X} = primitive_shape(X) +primitive_shape(::Type{T}) where {T <: Circle} = CIRCLE +primitive_shape(::Type{T}) where {T <: SimpleRectangle} = RECTANGLE +primitive_shape(::Type{T}) where {T <: HyperRectangle{2}} = RECTANGLE +primitive_shape(x::Shape) = x + +""" +Extracts the scale from a primitive. +""" +primitive_scale(prim::GeometryPrimitive) = Vec2f0(widths(prim)) +primitive_scale(::Union{Shape, Char}) = Vec2f0(40) +primitive_scale(c) = Vec2f0(0.1) + +""" +Extracts the offset from a primitive. +""" +primitive_offset(x, scale::Nothing) = Vec2f0(0) # default offset +primitive_offset(x, scale) = const_lift(/, scale, -2f0) # default offset + + +""" +Extracts the uv offset and width from a primitive. +""" +primitive_uv_offset_width(c::Char) = glyph_uv_width!(c) +primitive_uv_offset_width(x) = Vec4f0(0,0,1,1) + +""" +Gets the texture atlas if primitive is a char. +""" +primitive_distancefield(x) = nothing +primitive_distancefield(::Char) = get_texture!(get_texture_atlas()) +primitive_distancefield(::Node{Char}) = get_texture!(get_texture_atlas()) + +function _default( + p::Tuple{TOrSignal{Matrix{C}}, VectorTypes{P}}, s::Style, data::Dict + ) where {C <: Colorant, P <: Point} + data[:image] = p[1] # we don't want this to be overwritten by user + @gen_defaults! data begin + scale = lift(x-> Vec2f0(size(x)), p[1]) + shape = RECTANGLE + offset = Vec2f0(0) + end + sprites(p, s, data) +end +function _default( + p::Tuple{TOrSignal{Matrix{C}}, VectorTypes{P}}, s::Style, data::Dict + ) where {C <: AbstractFloat, P <: Point} + data[:distancefield] = p[1] # we don't want this to be overwritten by user + @gen_defaults! data begin + scale = lift(x-> Vec2f0(size(x)), p[1]) + shape = RECTANGLE + offset = Vec2f0(0) + end + sprites(p, s, data) +end + +function _default( + p::Tuple{VectorTypes{Matrix{C}}, VectorTypes{P}}, s::Style, data::Dict + ) where {C <: Colorant, P <: Point} + images = to_value(p[1]) + isempty(images) && error("Can not display empty vector of images as primitive") + images = sort(images, by=size) + sizes = map(size, images) + scale = Vec2f0(first(sizes)) + if !all(x-> x == sizes[1], sizes) # if differently sized + # create texture atlas + maxdims = sum(map(Vec{2, Int}, sizes)) + rectangles = map(x->SimpleRectangle(0,0,x...), sizes) + rpack = RectanglePacker(SimpleRectangle(0, 0, maxdims...)) + uv_coordinates = [push!(rpack, rect).area for rect in rectangles] + max_xy = mapreduce(maximum, max, uv_coordinates) + texture_atlas = Texture(C, tuple(max_xy...)) + for (area, img) in zip(uv_coordinates, images) + texture_atlas[area] = img #transfer to texture atlas + end + scale = Vec2f0.(widths.(uv_coordinates)) + data[:uv_offset_width] = map(uv_coordinates) do uv + mini = minimum(uv) ./ max_xy + maxi = maximum(uv) ./ max_xy + Vec4f0(mini..., maxi...) + end + images = texture_atlas + end + data[:image] = images # we don't want this to be overwritten by user + @gen_defaults! data begin + scale = scale + shape = RECTANGLE + offset = Vec2f0(0) + end + sprites(p, s, data) +end + +# There is currently no way to get the two following two signatures +# under one function, which is why we delegate to sprites +_default(p::Tuple{TOrSignal{Pr}, VectorTypes{P}}, s::Style, data::Dict) where {Pr <: Sprites, P<:Point} = + sprites(p,s,data) + +_default(p::Tuple{TOrSignal{Pr}, G}, s::Style, data::Dict) where {Pr <: Sprites, G<:Grid} = + sprites(p,s,data) + +function _default( + p::Tuple{TOrSignal{Pr}, G}, s::Style, data::Dict + ) where {Pr <: Sprites, G <: Tuple} + @gen_defaults! data begin + shape = const_lift(primitive_shape, p[1]) + position = nothing => GLBuffer + position_x = p[2][1] => GLBuffer + position_y = p[2][2] => GLBuffer + position_z = length(p[2]) > 2 ? p[2][3] : 0f0 => GLBuffer + end + sprites(p, s, data) +end + +""" +Main assemble functions for sprite particles. +Sprites are anything like distance fields, images and simple geometries +""" +function sprites(p, s, data) + rot = get!(data, :rotation, Vec4f0(0, 0, 0, 1)) + rot = vec2quaternion(rot) + delete!(data, :rotation) + + @gen_defaults! data begin + shape = const_lift(x-> Int32(primitive_shape(x)), p[1]) + position = p[2] => GLBuffer + position_x = nothing => GLBuffer + position_y = nothing => GLBuffer + position_z = nothing => GLBuffer + + scale = const_lift(primitive_scale, p[1]) => GLBuffer + scale_x = nothing => GLBuffer + scale_y = nothing => GLBuffer + scale_z = nothing => GLBuffer + + rotation = rot => GLBuffer + image = nothing => Texture + end + # TODO don't make this dependant on some shady type dispatch + if isa(to_value(p[1]), Char) && !isa(to_value(scale), Vec) # correct dimensions + scale = const_lift(s-> Vec2f0(glyph_scale!(p[1], s)), scale) + data[:scale] = scale + end + + @gen_defaults! data begin + offset = primitive_offset(p[1], scale) => GLBuffer + intensity = nothing => GLBuffer + color_map = nothing => Texture + color_norm = nothing + color = (color_map == nothing ? default(RGBA, s) : nothing) => GLBuffer + + glow_color = RGBA{Float32}(0,0,0,0) => GLBuffer + stroke_color = RGBA{Float32}(0,0,0,0) => GLBuffer + stroke_width = 0f0 + glow_width = 0f0 + uv_offset_width = const_lift(primitive_uv_offset_width, p[1]) => GLBuffer + + distancefield = primitive_distancefield(p[1]) => Texture + indices = const_lift(length, p[2]) => to_index_buffer + # rotation and billboard don't go along + billboard = rotation == Vec4f0(0,0,0,1) => "if `billboard` == true, particles will always face camera" + preferred_camera = :orthographic_pixel + fxaa = false + shader = GLVisualizeShader( + "fragment_output.frag", "util.vert", "sprites.geom", + "sprites.vert", "distance_shape.frag", + view = Dict("position_calc"=>position_calc(position, position_x, position_y, position_z, GLBuffer)) + ) + gl_primitive = GL_POINTS + end + # Exception for intensity, to make it possible to handle intensity with a + # different length compared to position. Intensities will be interpolated in that case + if position != nothing + data[:intensity] = intensity_convert(intensity, position) + data[:len] = const_lift(length, position) + else + data[:intensity] = intensity_convert(intensity, position_x) + data[:len] = const_lift(length, position_x) + end + data +end + + +""" +Transforms text into a particle system of sprites, by inferring the +texture coordinates in the texture atlas, widths and positions of the characters. +""" +function _default(main::Tuple{TOrSignal{S}, P}, s::Style, data::Dict) where {S <: AbstractString, P} + data[:position] = main[2] + _default(main[1], s, data) +end + + + +function _default(main::TOrSignal{S}, s::Style, data::Dict) where S <: AbstractString + @gen_defaults! data begin + relative_scale = 4 # + start_position = Point2f0(0) + atlas = get_texture_atlas() + distancefield = get_texture!(atlas) + stroke_width = 0f0 + glow_width = 0f0 + font = to_font("default") + scale_primitive = true + position = const_lift(calc_position, main, start_position, relative_scale, font, atlas) + offset = const_lift(calc_offset, main, relative_scale, font, atlas) + prerender = () -> begin + glDisable(GL_DEPTH_TEST) + glDepthMask(GL_TRUE) + glDisable(GL_CULL_FACE) + enabletransparency() + end + uv_offset_width = const_lift(main) do str + Vec4f0[glyph_uv_width!(atlas, c, font) for c = str] + end + scale = const_lift(main, relative_scale) do str, s + Vec2f0[glyph_scale!(atlas, c, font, s) for c = str] + end + end + delete!(data, :font) + _default((DISTANCEFIELD, position), s, data) +end diff --git a/src/GLVisualize/visualize/surface.jl b/src/GLVisualize/visualize/surface.jl new file mode 100644 index 00000000000..7832c856da2 --- /dev/null +++ b/src/GLVisualize/visualize/surface.jl @@ -0,0 +1,233 @@ + +function surfboundingbox(position_x, position_y, position_z) + arr = const_lift(StructOfArrays, Point3f0, position_x, position_y, position_z) + map(AABB{Float32}, arr) +end +function surfboundingbox(grid, position_z) + arr = const_lift(GridZRepeat, grid, position_z) + map(AABB{Float32}, arr) +end + +function _default(main::Tuple{MatTypes{T}, MatTypes{T}, MatTypes{T}}, s::Style{:surface}, data::Dict) where T <: AbstractFloat + @gen_defaults! data begin + position_x = main[1] => (Texture, "x position, must be an `Matrix{Float}`") + position_y = main[2] => (Texture, "y position, must be an `Matrix{Float}`") + position_z = main[3] => (Texture, "z position, must be an `Matrix{Float}`") + scale = Vec3f0(0) => "scale must be 0, for a surfacemesh" + end + surface(position_z, s, data) +end + +function _default(main::MatTypes{T}, s::Style{:surface}, data::Dict) where T <: AbstractFloat + @gen_defaults! data begin + ranges = ((-1f0, 1f0), (-1f0,1f0)) => "x, and y position given as `(start, endvalue)` or any `Range`" + end + delete!(data, :ranges) # no need to have them in the OpenGL data + _default((Grid(to_value(main), to_value(ranges)), main), s, data) +end + +function _default(main::Tuple{G, MatTypes{T}}, s::Style{:surface}, data::Dict) where {G <: Grid{2}, T <: AbstractFloat} + xrange = main[1].dims[1];yrange = main[1].dims[2] + xscale = (maximum(xrange) - minimum(xrange)) / (length(xrange)-1) + yscale = (maximum(yrange) - minimum(yrange)) / (length(yrange)-1) + @gen_defaults! data begin + position = main[1] =>" Position given as a `Grid{2}`. + Can be constructed e.g. `Grid(LinRange(0,2,N1), LinRange(0,3, N2))`" + position_z = main[2] => (Texture, "height offset for the surface, must be `Matrix{Float}`") + scale = Vec3f0(xscale, yscale, 1) => "scale of the grid planes forming the surface. Can be made smaller, to let the grid show" + end + surface(position_z, s, data) +end +_extrema(x::AABB) = Vec2f0(minimum(x)[3], maximum(x)[3]) +nothing_or_vec(x) = x +nothing_or_vec(x::Array) = vec(x) + +function normal_calc(x::Bool) + if x + "getnormal(position_z, linear_index(dims, index1D));" + else + "vec3(0, 0, 1);" + end +end +function light_calc(x::Bool) + if x + """ + vec3 L = normalize(o_lightdir); + vec3 N = normalize(o_normal); + vec3 light1 = blinnphong(N, o_vertex, L, color.rgb); + vec3 light2 = blinnphong(N, o_vertex, -L, color.rgb); + color = vec4(light1 + light2 * 0.4, color.a); + """ + else + "" + end +end + +function surface(main, s::Style{:surface}, data::Dict) + @gen_defaults! data begin + primitive::GLMesh2D = SimpleRectangle(0f0,0f0,1f0,1f0) + scale = nothing + position = nothing + position_x = nothing => Texture + position_y = nothing => Texture + position_z = nothing => Texture + wireframe = false + glow_color = RGBA{Float32}(0,0,0,0) => GLBuffer + stroke_color = RGBA{Float32}(0,0,0,1) => GLBuffer + stroke_width = wireframe ? 0.03f0 : 0f0 + glow_width = 0f0 + uv_offset_width = Vec4f0(0) => GLBuffer + shape = RECTANGLE + wireframe = false + image = nothing => Texture + distancefield = nothing => Texture + shading = true + normal = shading + end + @gen_defaults! data begin + color = (wireframe ? RGBA{Float32}(0,0,0,0) : nothing) => (Texture, + "must be single color value, must be nothing for color_map") + color_map = ((!wireframe && color == nothing) ? default(Vector{RGBA}, s) : nothing) => (Texture, + "must be `Vector{Color}`, `color` must be nothing") + color_norm = (!wireframe && color_map != nothing ? Vec2f0(0, 1) : nothing) => begin + "normalizes the heightvalues before looking up color in `color_map`." + end + instances = const_lift(x->(size(x,1)-1) * (size(x,2)-1), main) => "number of planes used to render the surface" + shader = GLVisualizeShader( + "fragment_output.frag", "util.vert", "surface.vert", + to_value(wireframe) ? "distance_shape.frag" : "standard.frag", + view = Dict( + "position_calc" => position_calc(position, position_x, position_y, position_z, Texture), + "normal_calc" => normal_calc(normal), + "light_calc" => light_calc(shading), + ) + ) + end +end + + +function position_calc(x...) + _position_calc(Iterators.filter(x->!isa(x, Nothing), x)...) +end +function glsllinspace(position::Grid, gi, index) + "((1-(index01[$gi]))*position.start[$gi] + (index01[$gi])*position.stop[$gi])" +end +function glsllinspace(grid::Grid{1}, gi, index) + "((1-($index/position.lendiv))*position.start + ($index/position.lendiv)*position.stop)" +end +function grid_pos(grid::Grid{1}) + "$(glsllinspace(grid, 0, "index"))" +end +function grid_pos(grid::Grid{2}) + "vec2($(glsllinspace(grid, 0, "index2D.x")), $(glsllinspace(grid, 1, "index2D.y")))" +end +function grid_pos(grid::Grid{3}) + "vec3( + $(glsllinspace(grid, 0, "index2D.x")), + $(glsllinspace(grid, 1, "index2D.y")), + $(glsllinspace(grid, 2, "index2D.z")) + )" +end + + +function _position_calc( + grid::Grid{2}, position_z::MatTypes{T}, target::Type{Texture} + ) where T<:AbstractFloat + """ + int index1D = index + offseti.x + offseti.y * dims.x + (index/(dims.x-1)); + ivec2 index2D = ind2sub(dims, index1D); + vec2 index01 = vec2(index2D) / (vec2(dims)-1.0); + float height = texture(position_z, index01).x; + pos = vec3($(grid_pos(grid)), height); + """ +end + +function _position_calc( + position_x::MatTypes{T}, position_y::MatTypes{T}, position_z::MatTypes{T}, target::Type{Texture} + ) where T<:AbstractFloat + """ + int index1D = index + offseti.x + offseti.y * dims.x + (index/(dims.x-1)); + ivec2 index2D = ind2sub(dims, index1D); + vec2 index01 = vec2(index2D) / (vec2(dims)-1.0); + pos = vec3( + texelFetch(position_x, index2D, 0).x, + texelFetch(position_y, index2D, 0).x, + texelFetch(position_z, index2D, 0).x + ); + """ +end + +function _position_calc( + position_x::VectorTypes{T}, position_y::T, position_z::T, target::Type{TextureBuffer} + ) where T <: AbstractFloat + "pos = vec3(texelFetch(position_x, index).x, position_y, position_z);" +end +function _position_calc( + position_x::VectorTypes{T}, position_y::T, position_z::T, target::Type{GLBuffer} + ) where T <: AbstractFloat + "pos = vec3(position_x, position_y, position_z);" +end +function _position_calc( + position_xyz::VectorTypes{T}, target::Type{TextureBuffer} + ) where T <: StaticVector + "pos = texelFetch(position, index).xyz;" +end +function _position_calc( + position_xyz::VectorTypes{T}, target::Type{GLBuffer} + ) where T <: StaticVector + len = length(T) + filler = join(ntuple(x->0, 3-len), ", ") + needs_comma = len != 3 ? ", " : "" + "pos = vec3(position $needs_comma $filler);" +end +function _position_calc( + position_x::VectorTypes{T}, position_y::VectorTypes{T}, position_z::VectorTypes{T}, + target::Type{TextureBuffer} + ) where T<:AbstractFloat + "pos = vec3( + texelFetch(position_x, index).x, + texelFetch(position_y, index).x, + texelFetch(position_z, index).x + );" +end +function _position_calc( + position_x::VectorTypes{T}, position_y::VectorTypes{T}, position_z::VectorTypes{T}, + target::Type{GLBuffer} + ) where T<:AbstractFloat + "pos = vec3( + position_x, + position_y, + position_z + );" +end +function _position_calc( + position::Grid{1}, target + ) + " + pos = vec3($(grid_pos(position)), 0, 0); + " +end +function _position_calc( + position::Grid{2}, target + ) + " + ivec2 index2D = ind2sub(position.dims, index); + pos = vec3($(grid_pos(position)), 0); + " +end +function _position_calc( + position::Grid{2}, ::VectorTypes{T}, target::Type{GLBuffer} + ) where T + " + ivec2 index2D = ind2sub(position.dims, index); + pos = vec3($(grid_pos(position)), position_z); + " +end +function _position_calc( + position::Grid{3}, target + ) + " + ivec3 index2D = ind2sub(position.dims, index); + pos = $(grid_pos(position)); + " +end diff --git a/src/GLVisualize/visualize_interface.jl b/src/GLVisualize/visualize_interface.jl new file mode 100644 index 00000000000..3b8e303952b --- /dev/null +++ b/src/GLVisualize/visualize_interface.jl @@ -0,0 +1,74 @@ + +function default(@nospecialize(main), @nospecialize(s), @nospecialize(data)) + _default_light = Vec3f0[Vec3f0(1.0,1.0,1.0), Vec3f0(0.1,0.1,0.1), Vec3f0(0.9,0.9,0.9), Vec3f0(20,20,20)] + data = _default(main, s, copy(data)) + @gen_defaults! data begin # make sure every object has these! + model = Mat4f0(I) + light = _default_light + preferred_camera = :perspective + is_transparent_pass = Cint(false) + end +end + +""" +Creates a default visualization for any value. +The defaults can be customized via the key word arguments and the style parameter. +The style can change the the look completely (e.g points displayed as lines, or particles), +while the key word arguments just alter the parameters of one visualization. +Always returns a context, which can be displayed on a window via view(::Context, [display]). +""" +visualize(@nospecialize(main), s::Symbol=:default; kw_args...) = visualize(main, Style{s}(), Dict{Symbol, Any}(kw_args))::Context +visualize(@nospecialize(main), s::Style, data::Dict) = assemble_shader(default(main, s, data))::Context +visualize(c::Composable, s::Symbol=:default; kw_args...) = Context(c) +visualize(c::Composable, s::Style, data::Dict) = Context(c) + +visualize(c::Context, s::Symbol=:default; kw_args...) = c +visualize(c::Context, s::Style, data::Dict) = c +# + +function _view( + robj::RenderObject, screen = current_screen(); + camera = robj.uniforms[:preferred_camera], + position = Vec3f0(2), lookat = Vec3f0(0) + ) + global _camera_counter + local camsym::Symbol # make things type stable + mouseinside = screen.inputs[:mouseinside] + ishidden = screen.hidden + if isa(camera, Symbol) + camsym = camera::Symbol + if haskey(screen.cameras, camsym) + real_camera = screen.cameras[camsym] + elseif camsym == :perspective + keep = lift((a, b) -> !a && b, ishidden, mouseinside) + real_camera = PerspectiveCamera(screen.inputs, position, lookat, keep = keep) + elseif camsym == :fixed_pixel + real_camera = DummyCamera(window_size = screen.area) + elseif camsym == :orthographic_pixel + keep = lift((a, b) -> !a && b, ishidden, mouseinside) + real_camera = OrthographicPixelCamera(screen.inputs, keep = keep) + elseif camsym == :nothing + push!(screen, robj, :nothing) + return nothing + else + error("Camera symbol $camera not known") + end + elseif isa(camera, Camera) + camsym = :custom + real_camera = camera + else + error("$camera not a known camera type") + end + screen.cameras[camsym] = real_camera + robj.uniforms[:resolution] = lift(screen.area) do area + Vec2f0(widths(area)) + end + collect(real_camera, robj.uniforms) + push!(screen, robj) + nothing +end + +_view(robjs::Vector, screen = current_screen(); kw_args...) = for robj in robjs + _view(robj, screen; kw_args...) +end +_view(c::Composable, screen = current_screen(); kw_args...) = _view(extract_renderable(c), screen; kw_args...) diff --git a/src/drawing_primitives.jl b/src/drawing_primitives.jl new file mode 100644 index 00000000000..ffb70578778 --- /dev/null +++ b/src/drawing_primitives.jl @@ -0,0 +1,412 @@ +gpuvec(x) = GPUVector(GLBuffer(x)) + +to_range(x::ClosedInterval) = (minimum(x), maximum(x)) +to_range(x::VecTypes{2}) = x +to_range(x::AbstractRange) = (minimum(x), maximum(x)) +to_range(x::AbstractVector) = (minimum(x), maximum(x)) +function to_range(x::AbstractArray) + if length(x) in size(x) # assert that just one dim != 1 + to_range(vec(x)) + else + error("Can't convert to a range. Please supply a range/vector/interval or a tuple (min, max)") + end +end +function to_glvisualize_key(k) + k == :rotations && return :rotation + k == :markersize && return :scale + k == :glowwidth && return :glow_width + k == :glowcolor && return :glow_color + k == :strokewidth && return :stroke_width + k == :strokecolor && return :stroke_color + k == :positions && return :position + k == :linewidth && return :thickness + k == :marker_offset && return :offset + k == :colormap && return :color_map + k == :colorrange && return :color_norm + k == :transform_marker && return :scale_primitive + k +end + +make_context_current(screen::Screen) = GLFW.MakeContextCurrent(to_native(screen)) + +function cached_robj!(robj_func, screen, scene, x::AbstractPlot) + robj = get!(screen.cache, objectid(x)) do + gl_attributes = map(filter(((k, v),)-> k != :transformation, x.attributes)) do key_value + key, value = key_value + gl_key = to_glvisualize_key(key) + gl_value = lift_convert(key, value, x) + gl_key => gl_value + end + robj = robj_func(Dict{Symbol, Any}(gl_attributes)) + for key in (:view, :projection, :resolution, :eyeposition, :projectionview) + robj[key] = getfield(scene.camera, key) + end + screen.cache2plot[robj.id] = x + robj + end + push!(screen, scene, robj) + robj +end + +function remove_automatic!(attributes) + filter!(attributes) do (k, v) + to_value(v) != automatic + end +end + +index1D(x::SubArray) = parentindices(x)[1] + +handle_view(array::AbstractVector, attributes) = array +handle_view(array::Node, attributes) = array + +function handle_view(array::SubArray, attributes) + A = parent(array) + indices = index1D(array) + attributes[:indices] = indices + A +end +function handle_view(array::Node{T}, attributes) where T <: SubArray + A = lift(parent, array) + indices = lift(index1D, array) + attributes[:indices] = indices + A +end + +function lift_convert(key, value, plot) + lift(value) do value + convert_attribute(value, Key{key}(), Key{AbstractPlotting.plotkey(plot)}()) + end +end + +pixel2world(scene, msize::Number) = pixel2world(scene, Point2f0(msize))[1] +function pixel2world(scene, msize::StaticVector{2}) + # TODO figure out why Vec(x, y) doesn't work correctly + p0 = AbstractPlotting.to_world(scene, Point2f0(0.0)) + p1 = AbstractPlotting.to_world(scene, Point2f0(msize)) + diff = p1 - p0 + diff +end + +pixel2world(scene, msize::AbstractVector) = pixel2world.(scene, msize) + +function handle_intensities!(attributes) + if haskey(attributes, :color) && attributes[:color][] isa AbstractVector{<: Number} + c = pop!(attributes, :color) + attributes[:intensity] = lift(x-> convert(Vector{Float32}, x), c) + else + delete!(attributes, :intensity) + delete!(attributes, :color_map) + delete!(attributes, :color_norm) + end +end + +function Base.insert!(screen::GLScreen, scene::Scene, x::Combined) + if isempty(x.plots) # if no plots inserted, this truely is an atomic + draw_atomic(screen, scene, x) + else + foreach(x-> insert!(screen, scene, x), x.plots) + end +end + +function draw_atomic(screen::GLScreen, scene::Scene, x::Union{Scatter, MeshScatter}) + robj = cached_robj!(screen, scene, x) do gl_attributes + marker = lift_convert(:marker, pop!(gl_attributes, :marker), x) + if isa(x, Scatter) + msize = pop!(gl_attributes, :stroke_width) + gl_attributes[:stroke_width] = lift(pixel2world, Node(scene), msize) + gl_attributes[:billboard] = map(rot-> isa(rot, Billboard), x.attributes[:rotations]) + gl_attributes[:distancefield][] == nothing && delete!(gl_attributes, :distancefield) + gl_attributes[:uv_offset_width][] == Vec4f0(0) && delete!(gl_attributes, :uv_offset_width) + end + positions = handle_view(x[1], gl_attributes) + handle_intensities!(gl_attributes) + visualize((marker, positions), Style(:default), Dict{Symbol, Any}(gl_attributes)).children[] + end +end + + +function draw_atomic(screen::GLScreen, scene::Scene, x::Lines) + robj = cached_robj!(screen, scene, x) do gl_attributes + linestyle = pop!(gl_attributes, :linestyle) + data = Dict{Symbol, Any}(gl_attributes) + data[:pattern] = to_value(linestyle) + positions = handle_view(x[1], data) + handle_intensities!(data) + visualize(positions, Style(:lines), data).children[] + end +end +function draw_atomic(screen::GLScreen, scene::Scene, x::LineSegments) + robj = cached_robj!(screen, scene, x) do gl_attributes + linestyle = pop!(gl_attributes, :linestyle) + data = Dict{Symbol, Any}(gl_attributes) + data[:pattern] = to_value(linestyle) + positions = handle_view(x.converted[1], data) + delete!(data, :color_map) + delete!(data, :color_norm) + visualize(positions, Style(:linesegment), data).children[] + end +end + + +using AbstractPlotting: get_texture_atlas, glyph_bearing!, glyph_uv_width!, glyph_scale!, calc_position, calc_offset + +function to_gl_text(string, startpos::AbstractVector{T}, textsize, font, align, rot, model) where T <: VecTypes + atlas = get_texture_atlas() + N = length(T) + positions, uv_offset_width, scale = Point{N, Float32}[], Vec4f0[], Vec2f0[] + # toffset = calc_offset(string, textsize, font, atlas) + char_str_idx = iterate(string) + broadcast_foreach(1:length(string), startpos, textsize, (font,), align) do idx, pos, tsize, font, align + char, str_idx = char_str_idx + _font = isa(font[1], NativeFont) ? font[1] : font[1][idx] + mpos = model * Vec4f0(to_ndim(Vec3f0, pos, 0f0)..., 1f0) + push!(positions, to_ndim(Point{N, Float32}, mpos, 0)) + push!(uv_offset_width, glyph_uv_width!(atlas, char, _font)) + if isa(tsize, Vec2f0) # this needs better unit support + push!(scale, tsize) # Vec2f0, we assume it's already in absolute size + else + push!(scale, glyph_scale!(atlas, char,_font, tsize)) + end + char_str_idx = iterate(string, str_idx) + end + positions, Vec2f0(0), uv_offset_width, scale +end + +function to_gl_text(string, startpos::VecTypes{N, T}, textsize, font, aoffsetvec, rot, model) where {N, T} + atlas = get_texture_atlas() + mpos = model * Vec4f0(to_ndim(Vec3f0, startpos, 0f0)..., 1f0) + pos = to_ndim(Point{N, Float32}, mpos, 0f0) + rscale = Float32(textsize) + chars = Vector{Char}(string) + scale = glyph_scale!.(Ref(atlas), chars, (font,), rscale) + positions2d = calc_position(string, Point2f0(0), rscale, font, atlas) + # font is Vector{FreeType.NativeFont} so we need to protec + aoffset = AbstractPlotting.align_offset(Point2f0(0), positions2d[end], atlas, rscale, font, aoffsetvec) + aoffsetn = to_ndim(Point{N, Float32}, aoffset, 0f0) + uv_offset_width = glyph_uv_width!.(Ref(atlas), chars, (font,)) + positions = map(positions2d) do p + pn = rot * (to_ndim(Point{N, Float32}, p, 0f0) .+ aoffsetn) + pn .+ pos + end + positions, Vec2f0(0), uv_offset_width, scale +end + +function draw_atomic(screen::GLScreen, scene::Scene, x::Text) + robj = cached_robj!(screen, scene, x) do gl_attributes + + liftkeys = (:position, :textsize, :font, :align, :rotation, :model) + + gl_text = lift(to_gl_text, x[1], getindex.(Ref(gl_attributes), liftkeys)...) + # unpack values from the one signal: + positions, offset, uv_offset_width, scale = map((1, 2, 3, 4)) do i + lift(getindex, gl_text, i) + end + + atlas = get_texture_atlas() + keys = (:color, :stroke_color, :stroke_width, :rotation) + signals = getindex.(Ref(gl_attributes), keys) + visualize( + (DISTANCEFIELD, positions), + color = signals[1], + stroke_color = signals[2], + stroke_width = signals[3], + rotation = signals[4], + scale = scale, + offset = offset, + uv_offset_width = uv_offset_width, + distancefield = get_texture!(atlas), + visible = gl_attributes[:visible] + ).children[] + end +end + + +function draw_atomic(screen::GLScreen, scene::Scene, x::Heatmap) + robj = cached_robj!(screen, scene, x) do gl_attributes + gl_attributes[:ranges] = (to_value.((x[1], x[2]))) + interp = to_value(pop!(gl_attributes, :interpolate)) + interp = interp ? :linear : :nearest + tex = Texture(x[3], minfilter = interp) + pop!(gl_attributes, :color) + gl_attributes[:stroke_width] = pop!(gl_attributes, :thickness) + GLVisualize.assemble_shader(GLVisualize.gl_heatmap(tex, gl_attributes)).children[] + end +end + + +function vec2color(colors, cmap, crange) + AbstractPlotting.interpolated_getindex.((to_colormap(cmap),), colors, (crange,)) +end + +function get_image(plot) + if isa(plot[:color][], AbstractMatrix{<: Number}) + lift(vec2color, pop!.(Ref(plot), (:color, :color_map, :color_norm))...) + else + delete!(plot, :color_norm) + delete!(plot, :color_map) + return pop!(plot, :color) + end +end + +function draw_atomic(screen::GLScreen, scene::Scene, x::Image) + robj = cached_robj!(screen, scene, x) do gl_attributes + gl_attributes[:ranges] = to_range.(to_value.((x[1], x[2]))) + img = get_image(gl_attributes) + # remove_automatic!(gl_attributes) + visualize(img, Style(:default), gl_attributes).children[] + end +end + +convert_mesh_color(c::AbstractArray{<: Number}, cmap, crange) = vec2color(c, cmap, crange) +convert_mesh_color(c, cmap, crange) = c + +function draw_atomic(screen::GLScreen, scene::Scene, x::Mesh) + robj = cached_robj!(screen, scene, x) do gl_attributes + # signals not supported for shading yet + gl_attributes[:shading] = to_value(pop!(gl_attributes, :shading)) + color = pop!(gl_attributes, :color) + cmap = get(gl_attributes, :color_map, Node(nothing)); delete!(gl_attributes, :color_map) + crange = get(gl_attributes, :color_norm, Node(nothing)); delete!(gl_attributes, :color_norm) + mesh = lift(x[1], color, cmap, crange) do m, c, cmap, crange + c = convert_mesh_color(c, cmap, crange) + if isa(m, GLNormalColorMesh) || isa(m, GLNormalAttributeMesh) + m + elseif isa(c, Colorant) + get!(gl_attributes, :color, Node(c))[] = c + if !(isa(m, GLPlainMesh) || isa(m, GLNormalMesh)) + GLNormalMesh(m) + else + m + end + elseif isa(c, AbstractMatrix{<: Colorant}) + get!(gl_attributes, :color, Node(c))[] = c + m + else + HomogenousMesh(GLNormalMesh(m), Dict{Symbol, Any}(:color => c)) + end + end + visualize(mesh, Style(:default), gl_attributes).children[] + end +end + + +function draw_atomic(screen::GLScreen, scene::Scene, x::Surface) + robj = cached_robj!(screen, scene, x) do gl_attributes + color = pop!(gl_attributes, :color) + img = nothing + # signals not supported for shading yet + # We automatically insert x[3] into the color channel, so if it's equal we don't need to do anything + if isa(to_value(color), AbstractMatrix{<: Number}) && to_value(color) !== to_value(x[3]) + crange = pop!(gl_attributes, :color_norm) + cmap = pop!(gl_attributes, :color_map) + img = lift(color, cmap, crange) do img, cmap, norm + AbstractPlotting.interpolated_getindex.((cmap,), img, (norm,)) + end + elseif isa(to_value(color), AbstractMatrix{<: Colorant}) + img = color + gl_attributes[:color_map] = nothing + gl_attributes[:color] = nothing + gl_attributes[:color_norm] = nothing + end + gl_attributes[:color] = img + args = x[1:3] + gl_attributes[:shading] = AbstractPlotting.to_value(get(gl_attributes, :shading, true)) + if all(v-> to_value(v) isa AbstractMatrix, args) + visualize(args, Style(:surface), gl_attributes).children[] + else + gl_attributes[:ranges] = to_range.(to_value.(args[1:2])) + visualize(args[3], Style(:surface), gl_attributes).children[] + end + end +end + +function to_width(x) + mini, maxi = extrema(x) + maxi - mini +end + +function makieshader(paths...) + view = Dict{String, String}() + if !Sys.isapple() + view["GLSL_EXTENSIONS"] = "#extension GL_ARB_conservative_depth: enable" + view["SUPPORTED_EXTENSIONS"] = "#define DETPH_LAYOUT" + end + LazyShader( + paths..., + view = view, + fragdatalocation = [(0, "fragment_color"), (1, "fragment_groupid")] + ) +end + +function volume_prerender() + glEnable(GL_DEPTH_TEST) + glDepthMask(GL_TRUE) + glDepthFunc(GL_LEQUAL) + enabletransparency() + glEnable(GL_CULL_FACE) + glCullFace(GL_FRONT) +end + +function surface_contours(volume::Volume) + frag = joinpath(@__DIR__, "surface_contours.frag") + paths = assetpath.("shader", ("fragment_output.frag", "util.vert", "volume.vert")) + shader = makieshader(paths..., frag) + model = volume[:model] + x, y, z, vol = volume[1], volume[2], volume[3], volume[4] + model2 = lift(model, x, y, z) do m, xyz... + mi = minimum.(xyz) + maxi = maximum.(xyz) + w = maxi .- mi + m2 = Mat4f0( + w[1], 0, 0, 0, + 0, w[2], 0, 0, + 0, 0, w[3], 0, + mi[1], mi[2], mi[3], 1 + ) + convert(Mat4f0, m) * m2 + end + modelinv = lift(inv, model2) + hull = AABB{Float32}(Vec3f0(0), Vec3f0(1)) + gl_data = Dict( + :hull => GLUVWMesh(hull), + :volumedata => Texture(lift(x-> convert(Array{Float32}, x), vol)), + :model => model2, + :modelinv => modelinv, + :colormap => Texture(lift(to_colormap, volume[:colormap])), + :colorrange => lift(Vec2f0, volume[:colorrange]), + :fxaa => true + ) + bb = lift(m-> m * hull, model) + vp = GLVisualize.VolumePrerender( + lift(identity, volume[:transparency]), + lift(identity, volume[:overdraw]) + ) + robj = RenderObject(gl_data, shader, vp, bb) + robj.postrenderfunction = GLAbstraction.StandardPostrender(robj.vertexarray, GL_TRIANGLES) + robj +end + +function draw_atomic(screen::GLScreen, scene::Scene, vol::Volume) + robj = cached_robj!(screen, scene, vol) do gl_attributes + if gl_attributes[:algorithm][] == 7 + surface_contours(vol) + else + model = vol[:model] + x, y, z = vol[1], vol[2], vol[3] + gl_attributes[:model] = lift(model, x, y, z) do m, xyz... + mi = minimum.(xyz) + maxi = maximum.(xyz) + w = maxi .- mi + m2 = Mat4f0( + w[1], 0, 0, 0, + 0, w[2], 0, 0, + 0, 0, w[3], 0, + mi[1], mi[2], mi[3], 1 + ) + convert(Mat4f0, m) * m2 + end + delete!(gl_attributes, :color) + visualize(vol[4], Style(:default), gl_attributes).children[] + end + end +end diff --git a/src/events.jl b/src/events.jl new file mode 100644 index 00000000000..d0dd9f0417e --- /dev/null +++ b/src/events.jl @@ -0,0 +1,270 @@ + +""" +Throwing an error in a c callback seems to lead to undefined behaviour +""" +macro csafe(func) + func_body = func.args[2] + safe_body = quote + try + $func_body + catch e + println(stderr, "Error in c callback: ") + Base.showerror(stderr, e) + # TODO is it fine to call catch_backtrace here? + Base.show_backtrace(stderr, Base.catch_backtrace()) + end + end + func.args[2] = safe_body + return esc(func) +end + +function addbuttons(scene::Scene, name, button, action, ::Type{ButtonEnum}) where ButtonEnum + event = getfield(scene.events, name) + set = event[] + button_enum = ButtonEnum(Int(button)) + if button != GLFW.KEY_UNKNOWN + if action == GLFW.PRESS + push!(set, button_enum) + elseif action == GLFW.RELEASE + delete!(set, button_enum) + elseif action == GLFW.REPEAT + # nothing needs to be done, besides returning the same set of keys + else + error("Unrecognized enum value for GLFW button press action: $action") + end + end + event[] = set # trigger setfield event! + return +end + +""" +Returns a signal, which is true as long as the window is open. +returns `Node{Bool}` +[GLFW Docs](http://www.glfw.org/docs/latest/group__window.html#gaade9264e79fae52bdb78e2df11ee8d6a) +""" +function window_open(scene::Scene, window::GLFW.Window) + event = scene.events.window_open + @csafe(function windowclose(win) + event[] = false + end) + disconnect!(window, window_open) + event[] = isopen(window) + GLFW.SetWindowCloseCallback(window, windowclose) +end + +import AbstractPlotting: disconnect! + +function disconnect!(window::GLFW.Window, ::typeof(window_open)) + GLFW.SetWindowCloseCallback(window, nothing) +end + +function window_position(window::GLFW.Window) + xy = GLFW.GetWindowPos(window) + (xy.x, xy.y) +end +function window_area(scene::Scene, window) + event = scene.events.window_area + dpievent = scene.events.window_dpi + @csafe function windowposition(window, x::Cint, y::Cint) + rect = event[] + if minimum(rect) != Vec(x, y) + event[] = IRect(x, y, framebuffer_size(window)) + end + end + @csafe function windowsize(window, w::Cint, h::Cint) + rect = event[] + if Vec(w, h) != widths(rect) + monitor = GLFW.GetPrimaryMonitor() + props = MonitorProperties(monitor) + # dpi of a monitor should be the same in x y direction. + # if not, minimum seems to be a fair default + dpievent[] = minimum(props.dpi) + event[] = IRect(minimum(rect), w, h) + end + end + disconnect!(window, window_area) + monitor = GLFW.GetPrimaryMonitor() + props = MonitorProperties(monitor) + dpievent[] = minimum(props.dpi) + GLFW.SetFramebufferSizeCallback(window, windowsize) + # TODO put back window position, but right now it makes more trouble than it helps# + # GLFW.SetWindowPosCallback(window, windowposition) + return +end + +function disconnect!(window::GLFW.Window, ::typeof(window_area)) + GLFW.SetWindowPosCallback(window, nothing) + GLFW.SetFramebufferSizeCallback(window, nothing) +end + + +""" +Registers a callback for the mouse buttons + modifiers +returns `Node{NTuple{4, Int}}` +[GLFW Docs](http://www.glfw.org/docs/latest/group__input.html#ga1e008c7a8751cea648c8f42cc91104cf) +""" +function mouse_buttons(scene::Scene, window::GLFW.Window) + event = scene.events.mousebuttons + @csafe function mousebuttons(window, button, action, mods) + addbuttons(scene, :mousebuttons, button, action, Mouse.Button) + end + disconnect!(window, mouse_buttons) + GLFW.SetMouseButtonCallback(window, mousebuttons) +end +function disconnect!(window::GLFW.Window, ::typeof(mouse_buttons)) + GLFW.SetMouseButtonCallback(window, nothing) +end +function keyboard_buttons(scene::Scene, window::GLFW.Window) + event = scene.events.keyboardbuttons + @csafe function keyoardbuttons(window, button, scancode::Cint, action, mods::Cint) + addbuttons(scene, :keyboardbuttons, button, action, Keyboard.Button) + end + disconnect!(window, keyboard_buttons) + GLFW.SetKeyCallback(window, keyoardbuttons) +end + +function disconnect!(window::GLFW.Window, ::typeof(keyboard_buttons)) + GLFW.SetKeyCallback(window, nothing) +end + +""" +Registers a callback for drag and drop of files. +returns `Node{Vector{String}}`, which are absolute file paths +[GLFW Docs](http://www.glfw.org/docs/latest/group__input.html#gacc95e259ad21d4f666faa6280d4018fd) +""" +function dropped_files(scene::Scene, window::GLFW.Window) + event = scene.events.dropped_files + @csafe function droppedfiles(window, files) + event[] = String.(files) + end + disconnect!(window, dropped_files) + event[] = String[] + GLFW.SetDropCallback(window, droppedfiles) +end +function disconnect!(window::GLFW.Window, ::typeof(dropped_files)) + GLFW.SetDropCallback(window, nothing) +end + + +""" +Registers a callback for keyboard unicode input. +returns an `Node{Vector{Char}}`, +containing the pressed char. Is empty, if no key is pressed. +[GLFW Docs](http://www.glfw.org/docs/latest/group__input.html#ga1e008c7a8751cea648c8f42cc91104cf) +""" +function unicode_input(scene::Scene, window::GLFW.Window) + event = scene.events.unicode_input + @csafe function unicodeinput(window, c::Char) + vals = event[] + push!(vals, c) + event[] = vals + empty!(vals) + event[] = vals + end + disconnect!(window, unicode_input) + x = Char[]; sizehint!(x, 1) + event[] = x + GLFW.SetCharCallback(window, unicodeinput) +end +function disconnect!(window::GLFW.Window, ::typeof(unicode_input)) + GLFW.SetCharCallback(window, nothing) +end + +# TODO memoise? Or to bug ridden for the small performance gain? +function retina_scaling_factor(w, fb) + (w[1] == 0 || w[2] == 0) && return (1.0, 1.0) + fb ./ w +end + +function framebuffer_size(window::GLFW.Window) + wh = GLFW.GetFramebufferSize(window) + (wh.width, wh.height) +end +function window_size(window::GLFW.Window) + wh = GLFW.GetWindowSize(window) + (wh.width, wh.height) +end +function retina_scaling_factor(window::GLFW.Window) + w, fb = window_size(window), framebuffer_size(window) + retina_scaling_factor(w, fb) +end + +function correct_mouse(window::GLFW.Window, w, h) + ws, fb = window_size(window), framebuffer_size(window) + s = retina_scaling_factor(ws, fb) + (w * s[1], fb[2] - (h * s[2])) +end + +""" +Registers a callback for the mouse cursor position. +returns an `Node{Vec{2, Float64}}`, +which is not in scene coordinates, with the upper left window corner being 0 +[GLFW Docs](http://www.glfw.org/docs/latest/group__input.html#ga1e008c7a8751cea648c8f42cc91104cf) +""" +function mouse_position(scene::Scene, window::GLFW.Window) + event = scene.events.mouseposition + @csafe function cursorposition(window, w::Cdouble, h::Cdouble) + event[] = correct_mouse(window, w, h) + end + disconnect!(window, mouse_position) + GLFW.SetCursorPosCallback(window, cursorposition) +end +function disconnect!(window::GLFW.Window, ::typeof(mouse_position)) + GLFW.SetCursorPosCallback(window, nothing) +end + +""" +Registers a callback for the mouse scroll. +returns an `Node{Vec{2, Float64}}`, +which is an x and y offset. +[GLFW Docs](http://www.glfw.org/docs/latest/group__input.html#gacc95e259ad21d4f666faa6280d4018fd) +""" +function scroll(scene::Scene, window::GLFW.Window) + event = scene.events.scroll + @csafe function scrollcb(window, w::Cdouble, h::Cdouble) + event[] = (w, h) + event[] = (0.0, 0.0) + end + disconnect!(window, scroll) + GLFW.SetScrollCallback(window, scrollcb) +end +function disconnect!(window::GLFW.Window, ::typeof(scroll)) + GLFW.SetScrollCallback(window, nothing) +end + +""" +Registers a callback for the focus of a window. +returns an `Node{Bool}`, +which is true whenever the window has focus. +[GLFW Docs](http://www.glfw.org/docs/latest/group__window.html#ga6b5f973531ea91663ad707ba4f2ac104) +""" +function hasfocus(scene::Scene, window::GLFW.Window) + event = scene.events.hasfocus + @csafe function hasfocuscb(window, focus::Bool) + event[] = focus + end + disconnect!(window, hasfocus) + GLFW.SetWindowFocusCallback(window, hasfocuscb) +end +function disconnect!(window::GLFW.Window, ::typeof(hasfocus)) + GLFW.SetWindowFocusCallback(window, nothing) +end + +""" +Registers a callback for if the mouse has entered the window. +returns an `Node{Bool}`, +which is true whenever the cursor enters the window. +[GLFW Docs](http://www.glfw.org/docs/latest/group__input.html#ga762d898d9b0241d7e3e3b767c6cf318f) +""" +function entered_window(scene::Scene, window::GLFW.Window) + event = scene.events.entered_window + @csafe function enteredwindowcb(window, entered::Bool) + event[] = entered + end + disconnect!(window, entered_window) + GLFW.SetCursorEnterCallback(window, enteredwindowcb) +end + +function disconnect!(window::GLFW.Window, ::typeof(entered_window)) + GLFW.SetCursorEnterCallback(window, nothing) +end diff --git a/src/glwindow.jl b/src/glwindow.jl new file mode 100644 index 00000000000..66953cd59f3 --- /dev/null +++ b/src/glwindow.jl @@ -0,0 +1,233 @@ +""" +Selection of random objects on the screen is realized by rendering an +object id + plus an arbitrary index into the framebuffer. +The index can be used for e.g. instanced geometries. +""" +struct SelectionID{T <: Integer} <: FieldVector{2, T} + id::T + index::T +end + +function draw_fullscreen(vao_id) + glBindVertexArray(vao_id) + glDrawArrays(GL_TRIANGLES, 0, 3) + glBindVertexArray(0) +end +struct PostprocessPrerender +end +function (sp::PostprocessPrerender)() + glDepthMask(GL_TRUE) + glDisable(GL_DEPTH_TEST) + glDisable(GL_BLEND) + glDisable(GL_STENCIL_TEST) + glStencilMask(0xff) + glDisable(GL_CULL_FACE) + nothing +end + +const PostProcessROBJ = RenderObject{PostprocessPrerender} +mutable struct GLFramebuffer + resolution ::Node{NTuple{2, Int}} + id ::NTuple{2, GLuint} + color ::Texture{RGBA{N0f8}, 2} + objectid ::Texture{Vec{2, GLushort}, 2} + depth ::Texture{Float32, 2} + color_luma ::Texture{RGBA{N0f8}, 2} + postprocess::NTuple{3, PostProcessROBJ} +end + +Base.size(fb::GLFramebuffer) = size(fb.color) # it's guaranteed, that they all have the same size + +loadshader(name) = joinpath(@__DIR__, "GLVisualize", "assets", "shader", name) + + +rcpframe(x) = 1f0./Vec2f0(x[1], x[2]) + +""" +Creates a postprocessing render object. +This will transfer the pixels from the color texture of the Framebuffer +to the screen and while at it, it can do some postprocessing (not doing it right now): +E.g fxaa anti aliasing, color correction etc. +""" +function postprocess(color, color_luma, framebuffer_size) + shader1 = LazyShader( + loadshader("fullscreen.vert"), + loadshader("postprocess.frag") + ) + data1 = Dict{Symbol, Any}( + :color_texture => color + ) + pass1 = RenderObject(data1, shader1, PostprocessPrerender(), nothing) + pass1.postrenderfunction = () -> draw_fullscreen(pass1.vertexarray.id) + shader2 = LazyShader( + loadshader("fullscreen.vert"), + loadshader("fxaa.frag") + ) + data2 = Dict{Symbol, Any}( + :color_texture => color_luma, + :RCPFrame => lift(rcpframe, framebuffer_size) + ) + pass2 = RenderObject(data2, shader2, PostprocessPrerender(), nothing) + + pass2.postrenderfunction = () -> draw_fullscreen(pass2.vertexarray.id) + + shader3 = LazyShader( + loadshader("fullscreen.vert"), + loadshader("copy.frag") + ) + + data3 = Dict{Symbol, Any}( + :color_texture => color + ) + + pass3 = RenderObject(data3, shader3, PostprocessPrerender(), nothing) + + pass3.postrenderfunction = () -> draw_fullscreen(pass3.vertexarray.id) + + + (pass1, pass2, pass3) +end + +function attach_framebuffer(t::Texture{T, 2}, attachment) where T + glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, t.id, 0) +end + + + +function GLFramebuffer(fb_size::NTuple{2, Int}) + render_framebuffer = glGenFramebuffers() + + glBindFramebuffer(GL_FRAMEBUFFER, render_framebuffer) + + color_buffer = Texture(RGBA{N0f8}, fb_size, minfilter = :nearest, x_repeat = :clamp_to_edge) + + objectid_buffer = Texture(Vec{2, GLushort}, fb_size, minfilter = :nearest, x_repeat = :clamp_to_edge) + + depth_buffer = Texture( + Float32, fb_size, + minfilter = :nearest, x_repeat = :clamp_to_edge, + internalformat = GL_DEPTH_COMPONENT32F, + format = GL_DEPTH_COMPONENT + ) + + + attach_framebuffer(color_buffer, GL_COLOR_ATTACHMENT0) + attach_framebuffer(objectid_buffer, GL_COLOR_ATTACHMENT1) + attach_framebuffer(depth_buffer, GL_DEPTH_ATTACHMENT) + + status = glCheckFramebufferStatus(GL_FRAMEBUFFER) + @assert status == GL_FRAMEBUFFER_COMPLETE + + color_luma = Texture(RGBA{N0f8}, fb_size, minfilter=:linear, x_repeat=:clamp_to_edge) + color_luma_framebuffer = glGenFramebuffers() + glBindFramebuffer(GL_FRAMEBUFFER, color_luma_framebuffer) + attach_framebuffer(color_luma, GL_COLOR_ATTACHMENT0) + @assert status == GL_FRAMEBUFFER_COMPLETE + + glBindFramebuffer(GL_FRAMEBUFFER, 0) + fb_size_node = Node(fb_size) + p = postprocess(color_buffer, color_luma, fb_size_node) + + fb = GLFramebuffer( + fb_size_node, + (render_framebuffer, color_luma_framebuffer), + color_buffer, objectid_buffer, depth_buffer, + color_luma, + p + ) + fb +end + +function Base.resize!(fb::GLFramebuffer, window_size) + ws = Int.((window_size[1], window_size[2])) + if ws != size(fb) && all(x-> x > 0, window_size) + resize_nocopy!(fb.color, ws) + resize_nocopy!(fb.color_luma, ws) + resize_nocopy!(fb.objectid, ws) + resize_nocopy!(fb.depth, ws) + fb.resolution[] = ws + end + nothing +end + + +struct MonitorProperties + name::String + isprimary::Bool + position::Vec{2, Int} + physicalsize::Vec{2, Int} + videomode::GLFW.VidMode + videomode_supported::Vector{GLFW.VidMode} + dpi::Vec{2, Float64} + monitor::GLFW.Monitor +end + +function MonitorProperties(monitor::GLFW.Monitor) + name = GLFW.GetMonitorName(monitor) + isprimary = GLFW.GetPrimaryMonitor() == monitor + position = Vec{2, Int}(GLFW.GetMonitorPos(monitor)...) + physicalsize = Vec{2, Int}(GLFW.GetMonitorPhysicalSize(monitor)...) + videomode = GLFW.GetVideoMode(monitor) + sfactor = Sys.isapple() ? 2.0 : 1.0 + dpi = Vec(videomode.width * 25.4, videomode.height * 25.4) * sfactor ./ Vec{2, Float64}(physicalsize) + videomode_supported = GLFW.GetVideoModes(monitor) + + MonitorProperties(name, isprimary, position, physicalsize, videomode, videomode_supported, dpi, monitor) +end + +abstract type AbstractContext end + +mutable struct GLContext <: AbstractContext + window::GLFW.Window + framebuffer::GLFramebuffer + visible::Bool + cache::Dict +end +GLContext(window, framebuffer, visible) = GLContext(window, framebuffer, visible, Dict()) + + +""" +Sleep is pretty imprecise. E.g. anything under `0.001s` is not guaranteed to wake +up before `0.001s`. So this timer is pessimistic in the way, that it will never +sleep more than `time`. +""" +@inline function sleep_pessimistic(sleep_time) + st = convert(Float64,sleep_time) - 0.002 + start_time = time() + while (time() - start_time) < st + sleep(0.001) # sleep for the minimal amount of time + end +end +function reactive_run_till_now() + +end + +was_destroyed(nw::GLFW.Window) = nw.handle == C_NULL + +function GLAbstraction.native_switch_context!(x::GLFW.Window) + GLFW.MakeContextCurrent(x) +end + +function GLAbstraction.native_context_alive(x::GLFW.Window) + GLFW.is_initialized() && !was_destroyed(x) +end + +function destroy!(nw::GLFW.Window) + was_current = GLAbstraction.is_current_context(nw) + if !was_destroyed(nw) + GLFW.DestroyWindow(nw) + nw.handle = C_NULL + end + was_current && GLAbstraction.switch_context!() +end + +function Base.isopen(window::GLFW.Window) + was_destroyed(window) && return false + try + !GLFW.WindowShouldClose(window) + catch e + # can't be open if GLFW is already terminated + e.code == GLFW.NOT_INITIALIZED && return false + rethrow(e) + end +end diff --git a/src/rendering.jl b/src/rendering.jl new file mode 100644 index 00000000000..1b5505c70f2 --- /dev/null +++ b/src/rendering.jl @@ -0,0 +1,124 @@ +function renderloop(screen::Screen; framerate = 1/30, prerender = () -> nothing) + try + while isopen(screen) + t = time() + GLFW.PollEvents() # GLFW poll + prerender() + make_context_current(screen) + render_frame(screen) + GLFW.SwapBuffers(to_native(screen)) + diff = framerate - (time() - t) + if diff > 0 + sleep(diff) + else # if we don't sleep, we need to yield explicitely + yield() + end + end + catch e + destroy!(screen) + rethrow(e) + end + destroy!(screen) + return +end + + + +function setup!(screen) + glEnable(GL_SCISSOR_TEST) + if isopen(screen) + glScissor(0, 0, widths(screen)...) + glClearColor(1, 1, 1, 1) + glClear(GL_COLOR_BUFFER_BIT) + for (id, rect, clear, visible, color) in screen.screens + if visible[] + a = rect[] + rt = (minimum(a)..., widths(a)...) + glViewport(rt...) + if clear[] + c = color[] + glScissor(rt...) + glClearColor(red(c), green(c), blue(c), alpha(c)) + glClear(GL_COLOR_BUFFER_BIT) + end + end + end + end + glDisable(GL_SCISSOR_TEST) + return +end + +const selection_queries = Function[] + +""" +Renders a single frame of a `window` +""" +function render_frame(screen::Screen) + nw = to_native(screen) + GLAbstraction.is_context_active(nw) || return + fb = screen.framebuffer + wh = Int.(framebuffer_size(nw)) + resize!(fb, wh) + w, h = wh + glDisable(GL_STENCIL_TEST) + #prepare for geometry in need of anti aliasing + glBindFramebuffer(GL_FRAMEBUFFER, fb.id[1]) # color framebuffer + glDrawBuffers(2, [GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1]) + glClearColor(0,0,0,0) + glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT) + setup!(screen) + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE) + GLAbstraction.render(screen, true) + # transfer color to luma buffer and apply fxaa + glBindFramebuffer(GL_FRAMEBUFFER, fb.id[2]) # luma framebuffer + glDrawBuffer(GL_COLOR_ATTACHMENT0) + glViewport(0, 0, w, h) + glClearColor(0,0,0,0) + glClear(GL_COLOR_BUFFER_BIT) + GLAbstraction.render(fb.postprocess[1]) # add luma and preprocess + + glBindFramebuffer(GL_FRAMEBUFFER, fb.id[1]) # transfer to non fxaa framebuffer + glViewport(0, 0, w, h) + glDrawBuffer(GL_COLOR_ATTACHMENT0) + GLAbstraction.render(fb.postprocess[2]) # copy with fxaa postprocess + + #prepare for non anti aliased pass + glDrawBuffers(2, [GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1]) + + GLAbstraction.render(screen, false) + #Read all the selection queries + glReadBuffer(GL_COLOR_ATTACHMENT1) + for query_func in selection_queries + query_func(fb.objectid, w, h) + end + glBindFramebuffer(GL_FRAMEBUFFER, 0) # transfer back to window + glViewport(0, 0, w, h) + glClearColor(0, 0, 0, 0) + glClear(GL_COLOR_BUFFER_BIT) + GLAbstraction.render(fb.postprocess[3]) # copy postprocess + return +end + +function id2rect(screen, id1) + # TODO maybe we should use a different data structure + for (id2, rect, clear, color) in screen.screens + id1 == id2 && return true, rect + end + false, IRect(0,0,0,0) +end + +function GLAbstraction.render(screen::Screen, fxaa::Bool) + for (zindex, screenid, elem) in screen.renderlist + found, rect = id2rect(screen, screenid) + found || continue + a = rect[] + glViewport(minimum(a)..., widths(a)...) + if fxaa && elem[:fxaa][] + render(elem) + end + if !fxaa && !elem[:fxaa][] + render(elem) + end + end + return +end diff --git a/src/screen.jl b/src/screen.jl new file mode 100644 index 00000000000..cc89e8c65de --- /dev/null +++ b/src/screen.jl @@ -0,0 +1,361 @@ +const ScreenID = UInt8 +const ZIndex = Int +# ID, Area, clear, is visible, background color +const ScreenArea = Tuple{ScreenID, Node{IRect2D}, Node{Bool}, Node{Bool}, Node{RGBAf0}} + +# default icon for Makie +function icon() + path = joinpath(@__DIR__, "..", "..", "assets", "icons") + icons = FileIO.load.(joinpath.(path, readdir(path))) + icons = reinterpret.(NTuple{4,UInt8}, icons) +end + +abstract type GLScreen <: AbstractScreen end + +mutable struct Screen <: GLScreen + glscreen::GLFW.Window + framebuffer::GLFramebuffer + rendertask::RefValue{Task} + screen2scene::Dict{WeakRef, ScreenID} + screens::Vector{ScreenArea} + renderlist::Vector{Tuple{ZIndex, ScreenID, RenderObject}} + cache::Dict{UInt64, RenderObject} + cache2plot::Dict{UInt16, AbstractPlot} + framecache::Tuple{Matrix{RGB{N0f8}}, Matrix{RGB{N0f8}}} + function Screen( + glscreen::GLFW.Window, + framebuffer::GLFramebuffer, + rendertask::RefValue{Task}, + screen2scene::Dict{WeakRef, ScreenID}, + screens::Vector{ScreenArea}, + renderlist::Vector{Tuple{ZIndex, ScreenID, RenderObject}}, + cache::Dict{UInt64, RenderObject}, + cache2plot::Dict{UInt16, AbstractPlot}, + ) + s = size(framebuffer) + obj = new( + glscreen, framebuffer, rendertask, screen2scene, + screens, renderlist, cache, cache2plot, + (Matrix{RGB{N0f8}}(undef, s), Matrix{RGB{N0f8}}(undef, reverse(s))) + ) + finalizer(obj) do obj + # save_print("Freeing screen") + empty!.((obj.renderlist, obj.screens, obj.cache, obj.screen2scene, obj.cache2plot)) + return + end + obj + end +end +GeometryTypes.widths(x::Screen) = size(x.framebuffer.color) + +Base.wait(x::Screen) = isassigned(x.rendertask) && wait(x.rendertask[]) +Base.wait(scene::Scene) = wait(global_gl_screen()) # TODO per scene screen + + +function insertplots!(screen::GLScreen, scene::Scene) + for elem in scene.plots + insert!(screen, scene, elem) + end + foreach(s-> insertplots!(screen, s), scene.children) +end + +function Base.empty!(screen::GLScreen) + empty!(screen.renderlist) + empty!(screen.screen2scene) + empty!(screen.screens) +end + +function destroy!(screen::Screen) + empty!(screen) + empty!(screen.cache) + empty!(screen.cache2plot) + destroy!(screen.glscreen) +end + +function Base.resize!(window::GLFW.Window, resolution...) + if isopen(window) + retina_scale = retina_scaling_factor(window) + w, h = resolution ./ retina_scale + GLFW.SetWindowSize(window, round(Int, w), round(Int, h)) + end +end + +function Base.resize!(screen::Screen, w, h) + nw = to_native(screen) + resize!(nw, w, h) + fb = screen.framebuffer + resize!(fb, (w, h)) +end + +function Base.display(screen::Screen, scene::Scene) + empty!(screen) + resize!(screen, size(scene)...) + GLFW.PollEvents() # let the size change go through (TODO is this necessary?) + register_callbacks(scene, to_native(screen)) + insertplots!(screen, scene) + AbstractPlotting.update!(scene) + return +end + + +function to_jl_layout!(A, B) + ind1, ind2 = axes(A) + n = first(ind2) + last(ind2) + for i in ind1 + @simd for j in ind2 + @inbounds B[n-j, i] = ImageCore.clamp01nan(A[i, j]) + end + end + return B +end + +function fast_color_data!(dest::Array{RGB{N0f8}, 2}, source::Texture{T, 2}) where T + GLAbstraction.bind(source) + glPixelStorei(GL_PACK_ALIGNMENT, 1) + glGetTexImage(source.texturetype, 0, GL_RGB, GL_UNSIGNED_BYTE, dest) + GLAbstraction.bind(source, 0) + nothing +end + + +function colorbuffer(screen::Screen) + if isopen(screen) + GLFW.PollEvents() + render_frame(screen) # let it render + GLFW.SwapBuffers(to_native(screen)) + glFinish() # block until opengl is done rendering + ctex = screen.framebuffer.color + if size(ctex) != size(screen.framecache[1]) + s = size(ctex) + screen.framecache = (Matrix{RGB{N0f8}}(undef, s), Matrix{RGB{N0f8}}(undef, reverse(s))) + end + fast_color_data!(screen.framecache[1], ctex) + to_jl_layout!(screen.framecache...) + return screen.framecache[2] + else + error("Screen not open!") + end +end + + +Base.isopen(x::Screen) = isopen(x.glscreen) +function Base.push!(screen::GLScreen, scene::Scene, robj) + filter!(screen.screen2scene) do (k, v) + k.value != nothing + end + screenid = get!(screen.screen2scene, WeakRef(scene)) do + id = length(screen.screens) + 1 + bg = lift(to_color, scene.theme[:backgroundcolor]) + clear = lift(identity, scene.theme[:clear]) + visible = lift(identity, scene.theme[:visible]) + push!(screen.screens, (id, scene.px_area, clear, visible, bg)) + id + end + push!(screen.renderlist, (0, screenid, robj)) + return robj +end + +to_native(x::Screen) = x.glscreen +const gl_screens = GLFW.Window[] + + +""" +OpenGL shares all data containers between shared contexts, but not vertexarrays -.- +So to share a robjs between a context, we need to rewrap the vertexarray into a new one for that +specific context. +""" +function rewrap(robj::RenderObject{Pre}) where Pre + RenderObject{Pre}( + robj.main, + robj.uniforms, + GLVertexArray(robj.vertexarray), + robj.prerenderfunction, + robj.postrenderfunction, + robj.boundingbox, + ) +end + +const _global_gl_screen = Ref{Screen}() + +# will get overloaded later +function renderloop end + +# TODO a global is not very nice, but it's the simplest way right now to swap out +# the rendering loop +const opengl_renderloop = Ref{Function}(renderloop) + +function Screen(; resolution = (10, 10), visible = false, kw_args...) + if !isempty(gl_screens) + for elem in gl_screens + isopen(elem) && destroy!(elem) + end + empty!(gl_screens) + end + + window = GLFW.Window( + name = "Makie", resolution = (10, 10), # 10, because smaller sizes seem to error on some platforms + windowhints = [ + (GLFW.SAMPLES, 0), + (GLFW.DEPTH_BITS, 0), + + # SETTING THE ALPHA BIT IS REALLY IMPORTANT ON OSX, SINCE IT WILL JUST KEEP SHOWING A BLACK SCREEN + # WITHOUT ANY ERROR -.- + (GLFW.ALPHA_BITS, 8), + (GLFW.RED_BITS, 8), + (GLFW.GREEN_BITS, 8), + (GLFW.BLUE_BITS, 8), + + (GLFW.STENCIL_BITS, 0), + (GLFW.AUX_BUFFERS, 0) + ], + visible = false, + kw_args... + ) + GLFW.SetWindowIcon(window , icon()) + + # tell GLAbstraction that we created a new context. + # This is important for resource tracking, and only needed for the first context + GLAbstraction.switch_context!(window) + GLAbstraction.empty_shader_cache!() + push!(gl_screens, window) + + GLFW.SwapInterval(0) + + # Retina screens on osx have a different scaling! + retina_scale = retina_scaling_factor(window) + resolution = round.(Int, retina_scale .* resolution) + # Set the resolution for real now! + GLFW.SetWindowSize(window, resolution...) + fb = GLFramebuffer(Int.(resolution)) + + screen = Screen( + window, fb, + RefValue{Task}(), + Dict{WeakRef, ScreenID}(), + ScreenArea[], + Tuple{ZIndex, ScreenID, RenderObject}[], + Dict{UInt64, RenderObject}(), + Dict{UInt16, AbstractPlot}(), + ) + if visible + GLFW.ShowWindow(window) + else + GLFW.HideWindow(window) + end + screen.rendertask[] = @async((opengl_renderloop[])(screen)) + screen +end + +function global_gl_screen() + if isassigned(_global_gl_screen) && isopen(_global_gl_screen[]) + _global_gl_screen[] + else + _global_gl_screen[] = Screen() + _global_gl_screen[] + end +end + +# TODO per scene screen +getscreen(scene) = global_gl_screen() + +function pick_native(scene::SceneLike, xy::VectorTypes{2}, sid = Base.RefValue{SelectionID{UInt16}}()) + screen = getscreen(scene) + screen == nothing && return SelectionID{Int}(0, 0) + window_size = widths(screen) + fb = screen.framebuffer + buff = fb.objectid + glBindFramebuffer(GL_FRAMEBUFFER, fb.id[1]) + glReadBuffer(GL_COLOR_ATTACHMENT1) + x, y = Int.(floor.(xy)) + w, h = window_size + if x > 0 && y > 0 && x <= w && y <= h + glReadPixels(x, y, 1, 1, buff.format, buff.pixeltype, sid) + return convert(SelectionID{Int}, sid[]) + end + return SelectionID{Int}(0, 0) +end + +pick(scene::SceneLike, xy...) = pick(scene, Float64.(xy)) + +function pick(scene::SceneLike, xy::VectorTypes{2}) + sid = pick_native(scene, xy) + screen = getscreen(scene) + if screen != nothing && haskey(screen.cache2plot, sid.id) + plot = screen.cache2plot[sid.id] + return (plot, sid.index) + end + return (nothing, 0) +end + +# TODO does this actually needs to be a global? +const _mouse_selection_id = Base.RefValue{SelectionID{UInt16}}() +function mouse_selection_native(scene::SceneLike) + function query_mouse(buff, w, h) + xy = events(scene).mouseposition[] + x, y = Int.(floor.(xy)) + if x > 0 && y > 0 && x <= w && y <= h + glReadPixels(x, y, 1, 1, buff.format, buff.pixeltype, _mouse_selection_id) + end + return + end + if !(query_mouse in selection_queries) + push!(selection_queries, query_mouse) + end + convert(SelectionID{Int}, _mouse_selection_id[]) +end +function mouse_selection(scene::SceneLike) + sid = mouse_selection_native(scene) + screen = getscreen(scene) + if screen != nothing && haskey(screen.cache2plot, sid.id) + plot = screen.cache2plot[sid.id] + return (plot, sid.index) + end + return (nothing, 0) +end +function mouseover(scene::SceneLike, plots::AbstractPlot...) + p, idx = mouse_selection(scene) + p in flatten_plots(plots) +end + +function flatten_plots(x::Atomic, plots = AbstractPlot[]) + push!(plots, x) + plots +end +function flatten_plots(x::Combined, plots = AbstractPlot[]) + for elem in x.plots + flatten_plots(elem, plots) + end + plots +end +function flatten_plots(array, plots = AbstractPlot[]) + for elem in array + flatten_plots(elem, plots) + end + plots +end + +function onpick(f, scene::SceneLike, plots::AbstractPlot...) + fplots = flatten_plots(plots) + map_once(events(scene).mouseposition) do mp + p, idx = mouse_selection(scene) + (p in fplots) && f(idx) + return + end +end + +function pick(screen::Screen, rect::IRect2D) + window_size = widths(screen) + buff = screen.framebuffer.objectid + sid = zeros(SelectionID{UInt16}, widths(rect)...) + glReadBuffer(GL_COLOR_ATTACHMENT1) + x, y = minimum(rect) + rw, rh = widths(rect) + w, h = window_size + if x > 0 && y > 0 && x <= w && y <= h + glReadPixels(x, y, rw, rh, buff.format, buff.pixeltype, sid) + return map(unique(vec(SelectionID{Int}.(sid)))) do sid + screen.cache2plot[sid.id], Int(sid.index) + end + end + return SelectionID{Int}[] +end diff --git a/src/surface_contours.frag b/src/surface_contours.frag new file mode 100644 index 00000000000..7e8bdb0b34d --- /dev/null +++ b/src/surface_contours.frag @@ -0,0 +1,111 @@ +{{GLSL_VERSION}} + +in vec3 frag_vert; +in vec3 frag_uv; + +uniform sampler3D volumedata; + +uniform vec3 light_position = vec3(1.0, 1.0, 3.0); +uniform sampler1D colormap; +uniform vec2 colorrange; + +uniform vec3 eyeposition; + +uniform mat4 model; +uniform mat4 modelinv; +const float max_distance = 1.3; + +const int num_samples = 200; +const float step_size = max_distance / float(num_samples); + +float range01(float val, float from, float to) +{ + return clamp((val-from) / (to - from), 0.0, 1.0); +} + +vec3 gennormal(vec3 uvw, vec3 gradient_delta) +{ + vec3 a,b; + a.x = texture(volumedata, uvw - vec3(gradient_delta.x,0.0,0.0) ).r; + b.x = texture(volumedata, uvw + vec3(gradient_delta.x,0.0,0.0) ).r; + a.y = texture(volumedata, uvw - vec3(0.0,gradient_delta.y,0.0) ).r; + b.y = texture(volumedata, uvw + vec3(0.0,gradient_delta.y,0.0) ).r; + a.z = texture(volumedata, uvw - vec3(0.0,0.0,gradient_delta.z) ).r; + b.z = texture(volumedata, uvw + vec3(0.0,0.0,gradient_delta.z) ).r; + return normalize(a - b); +} + +vec3 blinn_phong(vec3 N, vec3 V, vec3 L, vec3 diffuse) +{ + // material properties + vec3 Ka = vec3(0.1); + vec3 Kd = vec3(1.0, 1.0, 1.0); + vec3 Ks = vec3(1.0, 1.0, 1.0); + float shininess = 50.0; + + // diffuse coefficient + float diff_coeff = max(dot(L,N),0.0); + + // specular coefficient + vec3 H = normalize(L+V); + float spec_coeff = pow(max(dot(H,N), 0.0), shininess); + if (diff_coeff <= 0.0) + spec_coeff = 0.0; + + // final lighting model + return Ka * vec3(0.5) + + Kd * diffuse * diff_coeff + + Ks * vec3(0.3) * spec_coeff ; +} + +bool is_outside(vec3 position) +{ + return (position.x > 1.0 || position.y > 1.0 || position.z > 1.0 || position.x < 0.0 || position.y < 0.0 || position.z < 0.0); +} + +// Simple random generator found: http://stackoverflow.com/questions/4200224/random-noise-functions-for-glsl +float rand(){ + return fract(sin(gl_FragCoord.x * 12.9898 + gl_FragCoord.y * 78.233) * 43758.5453); +} + +vec4 contours(vec3 front, vec3 dir, float stepsize) +{ + vec3 stepsize_dir = normalize(dir) * stepsize; + // The per-voxel alpha channel is specified in units of opacity/length. + // If our voxels are not isotropic, then the distance that we trace through + // depends on the direction. + vec3 pos = front; + float T = 1.0; + vec3 Lo = vec3(0.0); + int i = 0; + // add random offset to counteract sampling artifacts + pos += stepsize_dir * rand(); + for (i; i < num_samples && (!is_outside(pos) || i < 3) && T > 0.01; ++i, pos += stepsize_dir) { + float intensity = texture(volumedata, pos).x; + intensity = range01(intensity, colorrange.x, colorrange.y); + vec4 density = texture(colormap, intensity); + float opacity = density.a; + if(opacity > 0.0){ + vec3 N = gennormal(pos, vec3(stepsize)); + vec3 L = normalize(light_position - pos); + vec3 L2 = -L; + Lo += (T*opacity) * blinn_phong(N, pos, L, density.rgb); + Lo += (T*opacity) * blinn_phong(N, pos, L2, density.rgb); + T *= 1.0 - opacity; + } + } + return vec4(Lo, 1-T); +} + + +uniform uint objectid; + +void write2framebuffer(vec4 color, uvec2 id); + +void main() +{ + vec3 dir = normalize(frag_vert - eyeposition); + dir = vec3(modelinv * vec4(dir, 0)); + vec4 color = contours(frag_uv, dir, step_size); + write2framebuffer(color, uvec2(objectid, 0)); +} diff --git a/src/video_io.jl b/src/video_io.jl new file mode 100644 index 00000000000..06df9cb3cc2 --- /dev/null +++ b/src/video_io.jl @@ -0,0 +1,148 @@ +struct VideoStream + io + process + screen + path::String +end + + +""" + VideoStream(scene::Scene, dir = mktempdir(), name = "video") + +returns a stream and a buffer that you can use to not allocate for new frames. +Use `add_frame!(stream, window, buffer)` to add new video frames to the stream. +Use `finish(stream)` to save the video to 'dir/name.mkv'. You can also call +`finish(stream, "mkv")`, `finish(stream, "mp4")`, `finish(stream, "gif")` or `finish(stream, "webm")` to convert the stream to those formats. +""" +function VideoStream(scene::Scene) + if !has_ffmpeg[] + error("You can't create a video stream without ffmpeg installed. + Please install ffmpeg, e.g. via https://ffmpeg.org/download.html. + When you download the binaries, please make sure that you add the path to your PATH + environment variable. + On unix you can install ffmpeg with `sudo apt-get install ffmpeg`. + ") + end + #codec = `-codec:v libvpx -quality good -cpu-used 0 -b:v 500k -qmin 10 -qmax 42 -maxrate 500k -bufsize 1000k -threads 8` + dir = mktempdir() + path = joinpath(dir, "$(gensym(:video)).mkv") + + display(scene) + AbstractPlotting.update!(scene) + _xdim, _ydim = widths(pixelarea(scene)[]) + xdim = _xdim % 2 == 0 ? _xdim : _xdim + 1 + ydim = _ydim % 2 == 0 ? _ydim : _ydim + 1 + process = open(`ffmpeg -loglevel quiet -f rawvideo -pixel_format rgb24 -r 24 -s:v $(xdim)x$(ydim) -i pipe:0 -vf vflip -y $path`, "w") + VideoStream(process.in, process, GLMakie.global_gl_screen(), abspath(path)) +end + +""" +Adds a video frame to the VideoStream +""" +function recordframe!(io::VideoStream) + #codec = `-codec:v libvpx -quality good -cpu-used 0 -b:v 500k -qmin 10 -qmax 42 -maxrate 500k -bufsize 1000k -threads 8` + frame = GLMakie.colorbuffer(io.screen) + _xdim, _ydim = size(frame) + xdim = _xdim % 2 == 0 ? _xdim : _xdim + 1 + ydim = _ydim % 2 == 0 ? _ydim : _ydim + 1 + frame_out = fill(RGB{N0f8}(1, 1, 1), ydim, xdim) + for x in 1:_xdim, y in 1:_ydim + c = frame[(_xdim + 1) - x, y] + frame_out[y, x] = RGB{N0f8}(c) + end + write(io.io, frame_out) + return +end + +""" + save(path::String, io::VideoStream) + +Flushes the video stream and converts the file to the extension found in `path` which can +be `mkv` is default and doesn't need convert, `gif`, `mp4` and `webm`. +`mp4` is recommended for the internet, since it's the most supported format. +`webm` yields the smallest file size, `mp4` and `mk4` are marginally bigger and `gif`s are up to +6 times bigger with same quality! +""" +function save(path::String, io::VideoStream) + close(io.process) + wait(io.process) + p, typ = splitext(path) + if typ == ".mkv" + cp(io.path, out) + elseif typ == ".mp4" + run(`ffmpeg -loglevel quiet -i $(io.path) -c:v libx264 -preset slow -crf 24 -pix_fmt yuv420p -c:a libvo_aacenc -b:a 128k -y $path`) + elseif typ == ".webm" + run(`ffmpeg -loglevel quiet -i $(io.path) -c:v libvpx-vp9 -threads 16 -b:v 2000k -c:a libvorbis -threads 16 -vf scale=iw:ih -y $path`) + elseif typ == ".gif" + filters = "fps=15,scale=iw:ih:flags=lanczos" + palette_path = dirname(io.path) + pname = joinpath(palette_path, "palette.bmp") + isfile(pname) && rm(pname, force = true) + run(`ffmpeg -loglevel quiet -i $(io.path) -vf "$filters,palettegen" -y $pname`) + run(`ffmpeg -loglevel quiet -i $(io.path) -i $pname -lavfi "$filters [x]; [x][1:v] paletteuse" -y $path`) + rm(pname, force = true) + else + rm(io.path) + error("Video type $typ not known") + end + rm(io.path) + return path +end + + +""" + record(func, scene, path) +usage: +```example + record(scene, "test.gif") do io + for i = 1:100 + scene.plots[:color] = ...# animate scene + recordframe!(io) # record a new frame + end + end +``` +""" +function record(func, scene, path) + io = VideoStream(scene) + func(io) + save(path, io) +end + +""" + record(func, scene, path, iter) +usage: +```example + record(scene, "test.gif", 1:100) do i + scene.plots[:color] = ...# animate scene + end +``` +""" +function record(func, scene, path, iter) + io = VideoStream(scene) + for i in iter + t1 = time() + func(i) + recordframe!(io) + diff = (1/24) - (time() - t1) + if diff > 0.0 + sleep(diff) + else + yield() + end + end + save(path, io) +end + + + +function show(io::IO, mime::MIME"text/html", vs::VideoStream) + mktempdir() do dir + path = finish(vs, joinpath(dir, "video.mp4")) + print( + io, + """""" + ) + end +end diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 00000000000..2f81a62f79a --- /dev/null +++ b/test/.gitignore @@ -0,0 +1,2 @@ +/media/* +/testresults/* diff --git a/test/REQUIRE b/test/REQUIRE new file mode 100644 index 00000000000..afcc53a6a90 --- /dev/null +++ b/test/REQUIRE @@ -0,0 +1,13 @@ +MeshIO +#generate_plots +ImageFiltering # needed for Gaussian-filtering images during resize +BinaryProvider + +#for some examples +DataFrames +RDatasets + +#for WorldClim visualization example +GDAL +RData +DataFrames diff --git a/test/makie_header.jl b/test/makie_header.jl new file mode 100644 index 00000000000..e63cc652564 --- /dev/null +++ b/test/makie_header.jl @@ -0,0 +1,46 @@ +using Makie, GeometryTypes, Colors + +scene = Scene(color = :black, resolution = (600, 100)) +Makie.add_mousebuttons(scene) +brush = to_node(Point2f0[]) +markersize = to_node(Float32[]) + +waspressed_t_lastpos = Ref((false, time(), Point2f0(0))) +lift_node(scene, :mouseposition) do mp + if ispressed(scene, Makie.Mouse.left) + waspressed, t, lastpos = waspressed_t_lastpos[] + elapsed = time() - t + r = elapsed * 30.0 + dir = normalize(lastpos .- mp) + N = 10 + points = map(1:N) do i + mp .+ (rand(Point2f0) .* r) + end + append!(brush, points) + append!(markersize, map(x-> rand() .* 4.0 .+ 0.5, 1:N)) + if !waspressed + waspressed_t_lastpos[] = (true, time(), mp) + else + waspressed_t_lastpos[] = (true, t, mp) + end + else + waspressed_t_lastpos[] = (false, 0, Point2f0(0)) + end + return +end + +c = RGBA(0.95, 0.98, 0.99, 1.0) +aviz = axis( + range(0, stop=600, length=20), range(0, stop=100, length=5), + gridthickness = (0.5, 0.5, 0.5), + gridcolors = (c, c, c) +) + +bv = scatter( + brush, markersize = markersize, + color = :white, + glowwidth = 0.5, + glowcolor = (:yellow, 0.8) +) + +save("header.png", scene) diff --git a/test/runtests.jl b/test/runtests.jl new file mode 100644 index 00000000000..2f5f2619108 --- /dev/null +++ b/test/runtests.jl @@ -0,0 +1,5 @@ +using Pkg + +pkg"add https://github.com/JuliaPlots/MakieGallery.jl" + +pkg"test MakieGallery" From d111fb27f81dba2a3bffda6f13c7fe60c099bed0 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 19 Nov 2018 16:43:49 +0100 Subject: [PATCH 0005/1328] update readme --- README.md | 138 +----------------------------------------------------- 1 file changed, 1 insertion(+), 137 deletions(-) diff --git a/README.md b/README.md index 357d123173a..ad0677cb09c 100644 --- a/README.md +++ b/README.md @@ -1,137 +1 @@ -