Spaces:
Sleeping
Sleeping
Upload 5 files
Browse files- Dockerfile +11 -0
- Manifest.toml +558 -0
- Project.toml +10 -0
- index.html +498 -0
- server.jl +161 -0
Dockerfile
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM julia:1.9
|
| 2 |
+
|
| 3 |
+
WORKDIR /app
|
| 4 |
+
|
| 5 |
+
COPY . .
|
| 6 |
+
|
| 7 |
+
RUN julia --project=. -e 'using Pkg; Pkg.instantiate(); Pkg.precompile()'
|
| 8 |
+
|
| 9 |
+
EXPOSE 7860
|
| 10 |
+
|
| 11 |
+
CMD ["julia", "--project=.", "server.jl"]
|
Manifest.toml
ADDED
|
@@ -0,0 +1,558 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# This file is machine-generated - editing it directly is not advised
|
| 2 |
+
|
| 3 |
+
julia_version = "1.9.3"
|
| 4 |
+
manifest_format = "2.0"
|
| 5 |
+
project_hash = "b83afd87647a69c61287d3f2945d7025e21be452"
|
| 6 |
+
|
| 7 |
+
[[deps.Adapt]]
|
| 8 |
+
deps = ["LinearAlgebra", "Requires"]
|
| 9 |
+
git-tree-sha1 = "7e35fca2bdfba44d797c53dfe63a51fabf39bfc0"
|
| 10 |
+
uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
|
| 11 |
+
version = "4.4.0"
|
| 12 |
+
weakdeps = ["SparseArrays", "StaticArrays"]
|
| 13 |
+
|
| 14 |
+
[deps.Adapt.extensions]
|
| 15 |
+
AdaptSparseArraysExt = "SparseArrays"
|
| 16 |
+
AdaptStaticArraysExt = "StaticArrays"
|
| 17 |
+
|
| 18 |
+
[[deps.ArgTools]]
|
| 19 |
+
uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f"
|
| 20 |
+
version = "1.1.1"
|
| 21 |
+
|
| 22 |
+
[[deps.Artifacts]]
|
| 23 |
+
uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"
|
| 24 |
+
|
| 25 |
+
[[deps.AxisAlgorithms]]
|
| 26 |
+
deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"]
|
| 27 |
+
git-tree-sha1 = "01b8ccb13d68535d73d2b0c23e39bd23155fb712"
|
| 28 |
+
uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950"
|
| 29 |
+
version = "1.1.0"
|
| 30 |
+
|
| 31 |
+
[[deps.Base64]]
|
| 32 |
+
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
|
| 33 |
+
|
| 34 |
+
[[deps.BitFlags]]
|
| 35 |
+
git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d"
|
| 36 |
+
uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35"
|
| 37 |
+
version = "0.1.9"
|
| 38 |
+
|
| 39 |
+
[[deps.CSV]]
|
| 40 |
+
deps = ["CodecZlib", "Dates", "FilePathsBase", "InlineStrings", "Mmap", "Parsers", "PooledArrays", "PrecompileTools", "SentinelArrays", "Tables", "Unicode", "WeakRefStrings", "WorkerUtilities"]
|
| 41 |
+
git-tree-sha1 = "deddd8725e5e1cc49ee205a1964256043720a6c3"
|
| 42 |
+
uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
|
| 43 |
+
version = "0.10.15"
|
| 44 |
+
|
| 45 |
+
[[deps.ChainRulesCore]]
|
| 46 |
+
deps = ["Compat", "LinearAlgebra"]
|
| 47 |
+
git-tree-sha1 = "06ee8d1aa558d2833aa799f6f0b31b30cada405f"
|
| 48 |
+
uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
|
| 49 |
+
version = "1.25.2"
|
| 50 |
+
weakdeps = ["SparseArrays"]
|
| 51 |
+
|
| 52 |
+
[deps.ChainRulesCore.extensions]
|
| 53 |
+
ChainRulesCoreSparseArraysExt = "SparseArrays"
|
| 54 |
+
|
| 55 |
+
[[deps.CodecZlib]]
|
| 56 |
+
deps = ["TranscodingStreams", "Zlib_jll"]
|
| 57 |
+
git-tree-sha1 = "962834c22b66e32aa10f7611c08c8ca4e20749a9"
|
| 58 |
+
uuid = "944b1d66-785c-5afd-91f1-9de20f533193"
|
| 59 |
+
version = "0.7.8"
|
| 60 |
+
|
| 61 |
+
[[deps.Compat]]
|
| 62 |
+
deps = ["TOML", "UUIDs"]
|
| 63 |
+
git-tree-sha1 = "9d8a54ce4b17aa5bdce0ea5c34bc5e7c340d16ad"
|
| 64 |
+
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
|
| 65 |
+
version = "4.18.1"
|
| 66 |
+
weakdeps = ["Dates", "LinearAlgebra"]
|
| 67 |
+
|
| 68 |
+
[deps.Compat.extensions]
|
| 69 |
+
CompatLinearAlgebraExt = "LinearAlgebra"
|
| 70 |
+
|
| 71 |
+
[[deps.CompilerSupportLibraries_jll]]
|
| 72 |
+
deps = ["Artifacts", "Libdl"]
|
| 73 |
+
uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"
|
| 74 |
+
version = "1.0.5+0"
|
| 75 |
+
|
| 76 |
+
[[deps.ConcurrentUtilities]]
|
| 77 |
+
deps = ["Serialization", "Sockets"]
|
| 78 |
+
git-tree-sha1 = "d9d26935a0bcffc87d2613ce14c527c99fc543fd"
|
| 79 |
+
uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb"
|
| 80 |
+
version = "2.5.0"
|
| 81 |
+
|
| 82 |
+
[[deps.Crayons]]
|
| 83 |
+
git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15"
|
| 84 |
+
uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f"
|
| 85 |
+
version = "4.1.1"
|
| 86 |
+
|
| 87 |
+
[[deps.DataAPI]]
|
| 88 |
+
git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe"
|
| 89 |
+
uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
|
| 90 |
+
version = "1.16.0"
|
| 91 |
+
|
| 92 |
+
[[deps.DataFrames]]
|
| 93 |
+
deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"]
|
| 94 |
+
git-tree-sha1 = "a37ac0840a1196cd00317b57e39d6586bf0fd6f6"
|
| 95 |
+
uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
|
| 96 |
+
version = "1.7.1"
|
| 97 |
+
|
| 98 |
+
[[deps.DataStructures]]
|
| 99 |
+
deps = ["Compat", "InteractiveUtils", "OrderedCollections"]
|
| 100 |
+
git-tree-sha1 = "4e1fe97fdaed23e9dc21d4d664bea76b65fc50a0"
|
| 101 |
+
uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
|
| 102 |
+
version = "0.18.22"
|
| 103 |
+
|
| 104 |
+
[[deps.DataValueInterfaces]]
|
| 105 |
+
git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6"
|
| 106 |
+
uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464"
|
| 107 |
+
version = "1.0.0"
|
| 108 |
+
|
| 109 |
+
[[deps.Dates]]
|
| 110 |
+
deps = ["Printf"]
|
| 111 |
+
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"
|
| 112 |
+
|
| 113 |
+
[[deps.Distributed]]
|
| 114 |
+
deps = ["Random", "Serialization", "Sockets"]
|
| 115 |
+
uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"
|
| 116 |
+
|
| 117 |
+
[[deps.Downloads]]
|
| 118 |
+
deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"]
|
| 119 |
+
uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
|
| 120 |
+
version = "1.6.0"
|
| 121 |
+
|
| 122 |
+
[[deps.ExceptionUnwrapping]]
|
| 123 |
+
deps = ["Test"]
|
| 124 |
+
git-tree-sha1 = "d36f682e590a83d63d1c7dbd287573764682d12a"
|
| 125 |
+
uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4"
|
| 126 |
+
version = "0.1.11"
|
| 127 |
+
|
| 128 |
+
[[deps.FilePathsBase]]
|
| 129 |
+
deps = ["Compat", "Dates"]
|
| 130 |
+
git-tree-sha1 = "3bab2c5aa25e7840a4b065805c0cdfc01f3068d2"
|
| 131 |
+
uuid = "48062228-2e41-5def-b9a4-89aafe57970f"
|
| 132 |
+
version = "0.9.24"
|
| 133 |
+
weakdeps = ["Mmap", "Test"]
|
| 134 |
+
|
| 135 |
+
[deps.FilePathsBase.extensions]
|
| 136 |
+
FilePathsBaseMmapExt = "Mmap"
|
| 137 |
+
FilePathsBaseTestExt = "Test"
|
| 138 |
+
|
| 139 |
+
[[deps.FileWatching]]
|
| 140 |
+
uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee"
|
| 141 |
+
|
| 142 |
+
[[deps.Future]]
|
| 143 |
+
deps = ["Random"]
|
| 144 |
+
uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820"
|
| 145 |
+
|
| 146 |
+
[[deps.HTTP]]
|
| 147 |
+
deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "PrecompileTools", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"]
|
| 148 |
+
git-tree-sha1 = "5e6fe50ae7f23d171f44e311c2960294aaa0beb5"
|
| 149 |
+
uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3"
|
| 150 |
+
version = "1.10.19"
|
| 151 |
+
|
| 152 |
+
[[deps.InlineStrings]]
|
| 153 |
+
git-tree-sha1 = "8f3d257792a522b4601c24a577954b0a8cd7334d"
|
| 154 |
+
uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48"
|
| 155 |
+
version = "1.4.5"
|
| 156 |
+
|
| 157 |
+
[deps.InlineStrings.extensions]
|
| 158 |
+
ArrowTypesExt = "ArrowTypes"
|
| 159 |
+
ParsersExt = "Parsers"
|
| 160 |
+
|
| 161 |
+
[deps.InlineStrings.weakdeps]
|
| 162 |
+
ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd"
|
| 163 |
+
Parsers = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
|
| 164 |
+
|
| 165 |
+
[[deps.InteractiveUtils]]
|
| 166 |
+
deps = ["Markdown"]
|
| 167 |
+
uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
|
| 168 |
+
|
| 169 |
+
[[deps.Interpolations]]
|
| 170 |
+
deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"]
|
| 171 |
+
git-tree-sha1 = "65d505fa4c0d7072990d659ef3fc086eb6da8208"
|
| 172 |
+
uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59"
|
| 173 |
+
version = "0.16.2"
|
| 174 |
+
|
| 175 |
+
[deps.Interpolations.extensions]
|
| 176 |
+
InterpolationsForwardDiffExt = "ForwardDiff"
|
| 177 |
+
InterpolationsUnitfulExt = "Unitful"
|
| 178 |
+
|
| 179 |
+
[deps.Interpolations.weakdeps]
|
| 180 |
+
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
|
| 181 |
+
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
|
| 182 |
+
|
| 183 |
+
[[deps.InvertedIndices]]
|
| 184 |
+
git-tree-sha1 = "6da3c4316095de0f5ee2ebd875df8721e7e0bdbe"
|
| 185 |
+
uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f"
|
| 186 |
+
version = "1.3.1"
|
| 187 |
+
|
| 188 |
+
[[deps.IteratorInterfaceExtensions]]
|
| 189 |
+
git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856"
|
| 190 |
+
uuid = "82899510-4779-5014-852e-03e436cf321d"
|
| 191 |
+
version = "1.0.0"
|
| 192 |
+
|
| 193 |
+
[[deps.JLLWrappers]]
|
| 194 |
+
deps = ["Artifacts", "Preferences"]
|
| 195 |
+
git-tree-sha1 = "0533e564aae234aff59ab625543145446d8b6ec2"
|
| 196 |
+
uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210"
|
| 197 |
+
version = "1.7.1"
|
| 198 |
+
|
| 199 |
+
[[deps.JSON3]]
|
| 200 |
+
deps = ["Dates", "Mmap", "Parsers", "PrecompileTools", "StructTypes", "UUIDs"]
|
| 201 |
+
git-tree-sha1 = "411eccfe8aba0814ffa0fdf4860913ed09c34975"
|
| 202 |
+
uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
|
| 203 |
+
version = "1.14.3"
|
| 204 |
+
|
| 205 |
+
[deps.JSON3.extensions]
|
| 206 |
+
JSON3ArrowExt = ["ArrowTypes"]
|
| 207 |
+
|
| 208 |
+
[deps.JSON3.weakdeps]
|
| 209 |
+
ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd"
|
| 210 |
+
|
| 211 |
+
[[deps.LaTeXStrings]]
|
| 212 |
+
git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c"
|
| 213 |
+
uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
|
| 214 |
+
version = "1.4.0"
|
| 215 |
+
|
| 216 |
+
[[deps.LibCURL]]
|
| 217 |
+
deps = ["LibCURL_jll", "MozillaCACerts_jll"]
|
| 218 |
+
uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21"
|
| 219 |
+
version = "0.6.3"
|
| 220 |
+
|
| 221 |
+
[[deps.LibCURL_jll]]
|
| 222 |
+
deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"]
|
| 223 |
+
uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0"
|
| 224 |
+
version = "7.84.0+0"
|
| 225 |
+
|
| 226 |
+
[[deps.LibGit2]]
|
| 227 |
+
deps = ["Base64", "NetworkOptions", "Printf", "SHA"]
|
| 228 |
+
uuid = "76f85450-5226-5b5a-8eaa-529ad045b433"
|
| 229 |
+
|
| 230 |
+
[[deps.LibSSH2_jll]]
|
| 231 |
+
deps = ["Artifacts", "Libdl", "MbedTLS_jll"]
|
| 232 |
+
uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8"
|
| 233 |
+
version = "1.10.2+0"
|
| 234 |
+
|
| 235 |
+
[[deps.Libdl]]
|
| 236 |
+
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
|
| 237 |
+
|
| 238 |
+
[[deps.LinearAlgebra]]
|
| 239 |
+
deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"]
|
| 240 |
+
uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
|
| 241 |
+
|
| 242 |
+
[[deps.Logging]]
|
| 243 |
+
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"
|
| 244 |
+
|
| 245 |
+
[[deps.LoggingExtras]]
|
| 246 |
+
deps = ["Dates", "Logging"]
|
| 247 |
+
git-tree-sha1 = "f00544d95982ea270145636c181ceda21c4e2575"
|
| 248 |
+
uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36"
|
| 249 |
+
version = "1.2.0"
|
| 250 |
+
|
| 251 |
+
[[deps.MIMEs]]
|
| 252 |
+
git-tree-sha1 = "c64d943587f7187e751162b3b84445bbbd79f691"
|
| 253 |
+
uuid = "6c6e2e6c-3030-632d-7369-2d6c69616d65"
|
| 254 |
+
version = "1.1.0"
|
| 255 |
+
|
| 256 |
+
[[deps.Markdown]]
|
| 257 |
+
deps = ["Base64"]
|
| 258 |
+
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"
|
| 259 |
+
|
| 260 |
+
[[deps.MbedTLS]]
|
| 261 |
+
deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"]
|
| 262 |
+
git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf"
|
| 263 |
+
uuid = "739be429-bea8-5141-9913-cc70e7f3736d"
|
| 264 |
+
version = "1.1.9"
|
| 265 |
+
|
| 266 |
+
[[deps.MbedTLS_jll]]
|
| 267 |
+
deps = ["Artifacts", "Libdl"]
|
| 268 |
+
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"
|
| 269 |
+
version = "2.28.2+0"
|
| 270 |
+
|
| 271 |
+
[[deps.Missings]]
|
| 272 |
+
deps = ["DataAPI"]
|
| 273 |
+
git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d"
|
| 274 |
+
uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28"
|
| 275 |
+
version = "1.2.0"
|
| 276 |
+
|
| 277 |
+
[[deps.Mmap]]
|
| 278 |
+
uuid = "a63ad114-7e13-5084-954f-fe012c677804"
|
| 279 |
+
|
| 280 |
+
[[deps.MozillaCACerts_jll]]
|
| 281 |
+
uuid = "14a3606d-f60d-562e-9121-12d972cd8159"
|
| 282 |
+
version = "2022.10.11"
|
| 283 |
+
|
| 284 |
+
[[deps.NetworkOptions]]
|
| 285 |
+
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"
|
| 286 |
+
version = "1.2.0"
|
| 287 |
+
|
| 288 |
+
[[deps.OffsetArrays]]
|
| 289 |
+
git-tree-sha1 = "117432e406b5c023f665fa73dc26e79ec3630151"
|
| 290 |
+
uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
|
| 291 |
+
version = "1.17.0"
|
| 292 |
+
weakdeps = ["Adapt"]
|
| 293 |
+
|
| 294 |
+
[deps.OffsetArrays.extensions]
|
| 295 |
+
OffsetArraysAdaptExt = "Adapt"
|
| 296 |
+
|
| 297 |
+
[[deps.OpenBLAS_jll]]
|
| 298 |
+
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"]
|
| 299 |
+
uuid = "4536629a-c528-5b80-bd46-f80d51c5b363"
|
| 300 |
+
version = "0.3.21+4"
|
| 301 |
+
|
| 302 |
+
[[deps.OpenSSL]]
|
| 303 |
+
deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "NetworkOptions", "OpenSSL_jll", "Sockets"]
|
| 304 |
+
git-tree-sha1 = "1d1aaa7d449b58415f97d2839c318b70ffb525a0"
|
| 305 |
+
uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c"
|
| 306 |
+
version = "1.6.1"
|
| 307 |
+
|
| 308 |
+
[[deps.OpenSSL_jll]]
|
| 309 |
+
deps = ["Artifacts", "JLLWrappers", "Libdl"]
|
| 310 |
+
git-tree-sha1 = "f19301ae653233bc88b1810ae908194f07f8db9d"
|
| 311 |
+
uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95"
|
| 312 |
+
version = "3.5.4+0"
|
| 313 |
+
|
| 314 |
+
[[deps.OrderedCollections]]
|
| 315 |
+
git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee"
|
| 316 |
+
uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
|
| 317 |
+
version = "1.8.1"
|
| 318 |
+
|
| 319 |
+
[[deps.Oxygen]]
|
| 320 |
+
deps = ["DataStructures", "Dates", "HTTP", "JSON3", "MIMEs", "Reexport", "RelocatableFolders", "Requires", "Sockets", "Statistics", "StructTypes"]
|
| 321 |
+
git-tree-sha1 = "2ad010b0de6172faf1d09ed5e0837eb0b7355bd8"
|
| 322 |
+
uuid = "df9a0d86-3283-4920-82dc-4555fc0d1d8b"
|
| 323 |
+
version = "1.5.16"
|
| 324 |
+
|
| 325 |
+
[[deps.Parsers]]
|
| 326 |
+
deps = ["Dates", "PrecompileTools", "UUIDs"]
|
| 327 |
+
git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810"
|
| 328 |
+
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
|
| 329 |
+
version = "2.8.3"
|
| 330 |
+
|
| 331 |
+
[[deps.Pkg]]
|
| 332 |
+
deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"]
|
| 333 |
+
uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
|
| 334 |
+
version = "1.9.2"
|
| 335 |
+
|
| 336 |
+
[[deps.PooledArrays]]
|
| 337 |
+
deps = ["DataAPI", "Future"]
|
| 338 |
+
git-tree-sha1 = "36d8b4b899628fb92c2749eb488d884a926614d3"
|
| 339 |
+
uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720"
|
| 340 |
+
version = "1.4.3"
|
| 341 |
+
|
| 342 |
+
[[deps.PrecompileTools]]
|
| 343 |
+
deps = ["Preferences"]
|
| 344 |
+
git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f"
|
| 345 |
+
uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
|
| 346 |
+
version = "1.2.1"
|
| 347 |
+
|
| 348 |
+
[[deps.Preferences]]
|
| 349 |
+
deps = ["TOML"]
|
| 350 |
+
git-tree-sha1 = "522f093a29b31a93e34eaea17ba055d850edea28"
|
| 351 |
+
uuid = "21216c6a-2e73-6563-6e65-726566657250"
|
| 352 |
+
version = "1.5.1"
|
| 353 |
+
|
| 354 |
+
[[deps.PrettyTables]]
|
| 355 |
+
deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"]
|
| 356 |
+
git-tree-sha1 = "66b20dd35966a748321d3b2537c4584cf40387c7"
|
| 357 |
+
uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d"
|
| 358 |
+
version = "2.3.2"
|
| 359 |
+
|
| 360 |
+
[[deps.Printf]]
|
| 361 |
+
deps = ["Unicode"]
|
| 362 |
+
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"
|
| 363 |
+
|
| 364 |
+
[[deps.REPL]]
|
| 365 |
+
deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"]
|
| 366 |
+
uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
|
| 367 |
+
|
| 368 |
+
[[deps.Random]]
|
| 369 |
+
deps = ["SHA", "Serialization"]
|
| 370 |
+
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
|
| 371 |
+
|
| 372 |
+
[[deps.Ratios]]
|
| 373 |
+
deps = ["Requires"]
|
| 374 |
+
git-tree-sha1 = "1342a47bf3260ee108163042310d26f2be5ec90b"
|
| 375 |
+
uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439"
|
| 376 |
+
version = "0.4.5"
|
| 377 |
+
|
| 378 |
+
[deps.Ratios.extensions]
|
| 379 |
+
RatiosFixedPointNumbersExt = "FixedPointNumbers"
|
| 380 |
+
|
| 381 |
+
[deps.Ratios.weakdeps]
|
| 382 |
+
FixedPointNumbers = "53c48c17-4a7d-5ca2-90c5-79b7896eea93"
|
| 383 |
+
|
| 384 |
+
[[deps.Reexport]]
|
| 385 |
+
git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b"
|
| 386 |
+
uuid = "189a3867-3050-52da-a836-e630ba90ab69"
|
| 387 |
+
version = "1.2.2"
|
| 388 |
+
|
| 389 |
+
[[deps.RelocatableFolders]]
|
| 390 |
+
deps = ["SHA", "Scratch"]
|
| 391 |
+
git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864"
|
| 392 |
+
uuid = "05181044-ff0b-4ac5-8273-598c1e38db00"
|
| 393 |
+
version = "1.0.1"
|
| 394 |
+
|
| 395 |
+
[[deps.Requires]]
|
| 396 |
+
deps = ["UUIDs"]
|
| 397 |
+
git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64"
|
| 398 |
+
uuid = "ae029012-a4dd-5104-9daa-d747884805df"
|
| 399 |
+
version = "1.3.1"
|
| 400 |
+
|
| 401 |
+
[[deps.SHA]]
|
| 402 |
+
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
|
| 403 |
+
version = "0.7.0"
|
| 404 |
+
|
| 405 |
+
[[deps.Scratch]]
|
| 406 |
+
deps = ["Dates"]
|
| 407 |
+
git-tree-sha1 = "9b81b8393e50b7d4e6d0a9f14e192294d3b7c109"
|
| 408 |
+
uuid = "6c6a2e73-6563-6170-7368-637461726353"
|
| 409 |
+
version = "1.3.0"
|
| 410 |
+
|
| 411 |
+
[[deps.SentinelArrays]]
|
| 412 |
+
deps = ["Dates", "Random"]
|
| 413 |
+
git-tree-sha1 = "ebe7e59b37c400f694f52b58c93d26201387da70"
|
| 414 |
+
uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c"
|
| 415 |
+
version = "1.4.9"
|
| 416 |
+
|
| 417 |
+
[[deps.Serialization]]
|
| 418 |
+
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
|
| 419 |
+
|
| 420 |
+
[[deps.SharedArrays]]
|
| 421 |
+
deps = ["Distributed", "Mmap", "Random", "Serialization"]
|
| 422 |
+
uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383"
|
| 423 |
+
|
| 424 |
+
[[deps.SimpleBufferStream]]
|
| 425 |
+
git-tree-sha1 = "f305871d2f381d21527c770d4788c06c097c9bc1"
|
| 426 |
+
uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7"
|
| 427 |
+
version = "1.2.0"
|
| 428 |
+
|
| 429 |
+
[[deps.Sockets]]
|
| 430 |
+
uuid = "6462fe0b-24de-5631-8697-dd941f90decc"
|
| 431 |
+
|
| 432 |
+
[[deps.SortingAlgorithms]]
|
| 433 |
+
deps = ["DataStructures"]
|
| 434 |
+
git-tree-sha1 = "64d974c2e6fdf07f8155b5b2ca2ffa9069b608d9"
|
| 435 |
+
uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c"
|
| 436 |
+
version = "1.2.2"
|
| 437 |
+
|
| 438 |
+
[[deps.SparseArrays]]
|
| 439 |
+
deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"]
|
| 440 |
+
uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
|
| 441 |
+
|
| 442 |
+
[[deps.StaticArrays]]
|
| 443 |
+
deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"]
|
| 444 |
+
git-tree-sha1 = "b8693004b385c842357406e3af647701fe783f98"
|
| 445 |
+
uuid = "90137ffa-7385-5640-81b9-e52037218182"
|
| 446 |
+
version = "1.9.15"
|
| 447 |
+
weakdeps = ["ChainRulesCore", "Statistics"]
|
| 448 |
+
|
| 449 |
+
[deps.StaticArrays.extensions]
|
| 450 |
+
StaticArraysChainRulesCoreExt = "ChainRulesCore"
|
| 451 |
+
StaticArraysStatisticsExt = "Statistics"
|
| 452 |
+
|
| 453 |
+
[[deps.StaticArraysCore]]
|
| 454 |
+
git-tree-sha1 = "6ab403037779dae8c514bad259f32a447262455a"
|
| 455 |
+
uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c"
|
| 456 |
+
version = "1.4.4"
|
| 457 |
+
|
| 458 |
+
[[deps.Statistics]]
|
| 459 |
+
deps = ["LinearAlgebra", "SparseArrays"]
|
| 460 |
+
uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
|
| 461 |
+
version = "1.9.0"
|
| 462 |
+
|
| 463 |
+
[[deps.StringManipulation]]
|
| 464 |
+
deps = ["PrecompileTools"]
|
| 465 |
+
git-tree-sha1 = "a04cabe79c5f01f4d723cc6704070ada0b9d46d5"
|
| 466 |
+
uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e"
|
| 467 |
+
version = "0.3.4"
|
| 468 |
+
|
| 469 |
+
[[deps.StructTypes]]
|
| 470 |
+
deps = ["Dates", "UUIDs"]
|
| 471 |
+
git-tree-sha1 = "159331b30e94d7b11379037feeb9b690950cace8"
|
| 472 |
+
uuid = "856f2bd8-1eba-4b0a-8007-ebc267875bd4"
|
| 473 |
+
version = "1.11.0"
|
| 474 |
+
|
| 475 |
+
[[deps.SuiteSparse_jll]]
|
| 476 |
+
deps = ["Artifacts", "Libdl", "Pkg", "libblastrampoline_jll"]
|
| 477 |
+
uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c"
|
| 478 |
+
version = "5.10.1+6"
|
| 479 |
+
|
| 480 |
+
[[deps.TOML]]
|
| 481 |
+
deps = ["Dates"]
|
| 482 |
+
uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
|
| 483 |
+
version = "1.0.3"
|
| 484 |
+
|
| 485 |
+
[[deps.TableTraits]]
|
| 486 |
+
deps = ["IteratorInterfaceExtensions"]
|
| 487 |
+
git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39"
|
| 488 |
+
uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c"
|
| 489 |
+
version = "1.0.1"
|
| 490 |
+
|
| 491 |
+
[[deps.Tables]]
|
| 492 |
+
deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "OrderedCollections", "TableTraits"]
|
| 493 |
+
git-tree-sha1 = "f2c1efbc8f3a609aadf318094f8fc5204bdaf344"
|
| 494 |
+
uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
|
| 495 |
+
version = "1.12.1"
|
| 496 |
+
|
| 497 |
+
[[deps.Tar]]
|
| 498 |
+
deps = ["ArgTools", "SHA"]
|
| 499 |
+
uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e"
|
| 500 |
+
version = "1.10.0"
|
| 501 |
+
|
| 502 |
+
[[deps.Test]]
|
| 503 |
+
deps = ["InteractiveUtils", "Logging", "Random", "Serialization"]
|
| 504 |
+
uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
| 505 |
+
|
| 506 |
+
[[deps.TranscodingStreams]]
|
| 507 |
+
git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742"
|
| 508 |
+
uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa"
|
| 509 |
+
version = "0.11.3"
|
| 510 |
+
|
| 511 |
+
[[deps.URIs]]
|
| 512 |
+
git-tree-sha1 = "bef26fb046d031353ef97a82e3fdb6afe7f21b1a"
|
| 513 |
+
uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4"
|
| 514 |
+
version = "1.6.1"
|
| 515 |
+
|
| 516 |
+
[[deps.UUIDs]]
|
| 517 |
+
deps = ["Random", "SHA"]
|
| 518 |
+
uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
|
| 519 |
+
|
| 520 |
+
[[deps.Unicode]]
|
| 521 |
+
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"
|
| 522 |
+
|
| 523 |
+
[[deps.WeakRefStrings]]
|
| 524 |
+
deps = ["DataAPI", "InlineStrings", "Parsers"]
|
| 525 |
+
git-tree-sha1 = "b1be2855ed9ed8eac54e5caff2afcdb442d52c23"
|
| 526 |
+
uuid = "ea10d353-3f73-51f8-a26c-33c1cb351aa5"
|
| 527 |
+
version = "1.4.2"
|
| 528 |
+
|
| 529 |
+
[[deps.WoodburyMatrices]]
|
| 530 |
+
deps = ["LinearAlgebra", "SparseArrays"]
|
| 531 |
+
git-tree-sha1 = "c1a7aa6219628fcd757dede0ca95e245c5cd9511"
|
| 532 |
+
uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6"
|
| 533 |
+
version = "1.0.0"
|
| 534 |
+
|
| 535 |
+
[[deps.WorkerUtilities]]
|
| 536 |
+
git-tree-sha1 = "cd1659ba0d57b71a464a29e64dbc67cfe83d54e7"
|
| 537 |
+
uuid = "76eceee3-57b5-4d4a-8e66-0e911cebbf60"
|
| 538 |
+
version = "1.6.1"
|
| 539 |
+
|
| 540 |
+
[[deps.Zlib_jll]]
|
| 541 |
+
deps = ["Libdl"]
|
| 542 |
+
uuid = "83775a58-1f1d-513f-b197-d71354ab007a"
|
| 543 |
+
version = "1.2.13+0"
|
| 544 |
+
|
| 545 |
+
[[deps.libblastrampoline_jll]]
|
| 546 |
+
deps = ["Artifacts", "Libdl"]
|
| 547 |
+
uuid = "8e850b90-86db-534c-a0d3-1478176c7d93"
|
| 548 |
+
version = "5.8.0+0"
|
| 549 |
+
|
| 550 |
+
[[deps.nghttp2_jll]]
|
| 551 |
+
deps = ["Artifacts", "Libdl"]
|
| 552 |
+
uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d"
|
| 553 |
+
version = "1.48.0+0"
|
| 554 |
+
|
| 555 |
+
[[deps.p7zip_jll]]
|
| 556 |
+
deps = ["Artifacts", "Libdl"]
|
| 557 |
+
uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0"
|
| 558 |
+
version = "17.4.0+0"
|
Project.toml
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[deps]
|
| 2 |
+
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
|
| 3 |
+
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
|
| 4 |
+
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
|
| 5 |
+
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
|
| 6 |
+
Interpolations = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59"
|
| 7 |
+
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
|
| 8 |
+
Oxygen = "df9a0d86-3283-4920-82dc-4555fc0d1d8b"
|
| 9 |
+
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
|
| 10 |
+
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
|
index.html
ADDED
|
@@ -0,0 +1,498 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<title>3D Mosquito Trajectory Visualizer</title>
|
| 6 |
+
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
|
| 7 |
+
|
| 8 |
+
<style>
|
| 9 |
+
body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; overflow: hidden; }
|
| 10 |
+
#controls.top-banner {
|
| 11 |
+
position: fixed;
|
| 12 |
+
top: 0;
|
| 13 |
+
left: 0;
|
| 14 |
+
width: 100%;
|
| 15 |
+
height: 60px; /* Fixed height for a slim look */
|
| 16 |
+
background: rgba(255, 255, 255, 0.95);
|
| 17 |
+
display: flex;
|
| 18 |
+
align-items: center;
|
| 19 |
+
justify-content: space-around; /* Distributes items evenly */
|
| 20 |
+
padding: 0 20px;
|
| 21 |
+
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
| 22 |
+
z-index: 1000;
|
| 23 |
+
box-sizing: border-box;
|
| 24 |
+
font-family: sans-serif;
|
| 25 |
+
font-size: 13px;
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
.control-group {
|
| 29 |
+
display: flex;
|
| 30 |
+
flex-direction: column; /* Stack label over slider */
|
| 31 |
+
justify-content: center;
|
| 32 |
+
min-width: 150px;
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
.slider-header {
|
| 36 |
+
display: flex;
|
| 37 |
+
justify-content: space-between;
|
| 38 |
+
margin-bottom: 4px;
|
| 39 |
+
font-weight: bold;
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
.checkbox-label {
|
| 43 |
+
display: flex;
|
| 44 |
+
align-items: center; /* Centers the box with the text vertically */
|
| 45 |
+
gap: 8px; /* Adds consistent space between box and text */
|
| 46 |
+
font-weight: bold;
|
| 47 |
+
cursor: pointer;
|
| 48 |
+
white-space: nowrap;
|
| 49 |
+
height: 100%; /* Ensures it takes up full banner height if needed */
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
#reset-view {
|
| 53 |
+
padding: 6px 12px;
|
| 54 |
+
background: #f0f0f0;
|
| 55 |
+
border: 1px solid #ccc;
|
| 56 |
+
border-radius: 4px;
|
| 57 |
+
cursor: pointer;
|
| 58 |
+
transition: background 0.2s;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
#reset-view:hover {
|
| 62 |
+
background: #e0e0e0;
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
.info-text {
|
| 66 |
+
font-size: 11px;
|
| 67 |
+
color: #888;
|
| 68 |
+
max-width: 240px;
|
| 69 |
+
line-height: 1.5;
|
| 70 |
+
text-align: center;
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
/* Adjust your Plotly container to make room for the banner */
|
| 74 |
+
#plot-container {
|
| 75 |
+
display: none; /* Hidden until data is loaded */
|
| 76 |
+
margin-top: 60px;
|
| 77 |
+
height: calc(100vh - 60px);
|
| 78 |
+
}
|
| 79 |
+
.slider-label { display: flex; justify-content: space-between; margin-bottom: 8px; font-weight: bold; }
|
| 80 |
+
input[type=range] { width: 100%; }
|
| 81 |
+
</style>
|
| 82 |
+
</head>
|
| 83 |
+
<body>
|
| 84 |
+
|
| 85 |
+
<div id="controls" class="top-banner">
|
| 86 |
+
<div class="control-group" style="max-width: 300px; flex-direction: row; align-items: stretch;">
|
| 87 |
+
<input type="file" id="file-selector" style="display: none;" onchange="updateFilename(this)">
|
| 88 |
+
|
| 89 |
+
<label for="file-selector" id="drop-zone"
|
| 90 |
+
style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding: 8px; border: 1px solid #ccc; border-radius: 4px 4px 4px 4px; background: white; cursor: pointer; color: #666; display: flex; align-items: center; overflow: hidden;">
|
| 91 |
+
<span id="file-name-display">Click to select or Drop CSV...</span>
|
| 92 |
+
</label>
|
| 93 |
+
|
| 94 |
+
<button class="btn" id="process-btn"
|
| 95 |
+
style="background: #007bff; color: white; border: 1px solid #007bff; border-radius: 4px 4px 4px 4px; cursor: pointer; white-space: nowrap; margin-left:6px;"
|
| 96 |
+
onclick="uploadAndProcess()">
|
| 97 |
+
Process File
|
| 98 |
+
</button>
|
| 99 |
+
</div>
|
| 100 |
+
|
| 101 |
+
<div class="control-group">
|
| 102 |
+
<label class="checkbox-label">
|
| 103 |
+
<input type="checkbox" id="toggle-heatmap"> Density Heatmaps
|
| 104 |
+
</label>
|
| 105 |
+
</div>
|
| 106 |
+
|
| 107 |
+
<div class="control-group">
|
| 108 |
+
<div class="slider-header">
|
| 109 |
+
<span>Trajectories:</span>
|
| 110 |
+
<span id="percent-val">2%</span>
|
| 111 |
+
</div>
|
| 112 |
+
<input type="range" id="percent" min="1" max="100" value="2">
|
| 113 |
+
</div>
|
| 114 |
+
|
| 115 |
+
<div class="control-group">
|
| 116 |
+
<div class="slider-header">
|
| 117 |
+
<span>Opacity:</span>
|
| 118 |
+
<span id="opacity-val">0.99</span>
|
| 119 |
+
</div>
|
| 120 |
+
<input type="range" id="opacity" min="0" max="0.99" step="0.01" value="0.99">
|
| 121 |
+
</div>
|
| 122 |
+
|
| 123 |
+
<div class="control-group">
|
| 124 |
+
<button id="reset-view">Reset View</button>
|
| 125 |
+
</div>
|
| 126 |
+
|
| 127 |
+
<div class="info-text">
|
| 128 |
+
L: Rotate | Scroll: Zoom | R: Pan <br>
|
| 129 |
+
<i>Trajectories colored by starting times</i>
|
| 130 |
+
</div>
|
| 131 |
+
</div>
|
| 132 |
+
|
| 133 |
+
|
| 134 |
+
<div id="plot-container"></div>
|
| 135 |
+
|
| 136 |
+
<script>
|
| 137 |
+
|
| 138 |
+
let allData = [];
|
| 139 |
+
let xMin, yMax, zMin;
|
| 140 |
+
let floorData, wallData, sideData;
|
| 141 |
+
|
| 142 |
+
function handleDrop(event) {
|
| 143 |
+
event.preventDefault();
|
| 144 |
+
const file = event.dataTransfer.files[0];
|
| 145 |
+
if (file) {
|
| 146 |
+
// Note: In local Chrome/Firefox, this usually grabs the filename.
|
| 147 |
+
// If the user drops from a local folder, it provides the name.
|
| 148 |
+
document.getElementById('path-input').value = file.name;
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
}
|
| 152 |
+
|
| 153 |
+
function updateFilename(input) {
|
| 154 |
+
const nameDisplay = document.getElementById('file-name-display');
|
| 155 |
+
if (input.files.length > 0) {
|
| 156 |
+
nameDisplay.innerText = input.files[0].name;
|
| 157 |
+
nameDisplay.style.color = "#333";
|
| 158 |
+
}
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
async function uploadAndProcess() {
|
| 162 |
+
// 1. Get the file from a standard file input
|
| 163 |
+
// <input type="file" id="file-selector">
|
| 164 |
+
const fileElement = document.getElementById('file-selector');
|
| 165 |
+
const file = fileElement.files[0];
|
| 166 |
+
|
| 167 |
+
if (!file) { alert("Please select a file first"); return; }
|
| 168 |
+
|
| 169 |
+
const btn = document.getElementById('process-btn');
|
| 170 |
+
btn.innerText = "Processing...";
|
| 171 |
+
btn.style.background = "#6c757d"; // Change to grey
|
| 172 |
+
btn.style.pointerEvents = "none"; // Prevent double-clicking
|
| 173 |
+
|
| 174 |
+
try {
|
| 175 |
+
// 2. Send the raw file to the backend
|
| 176 |
+
const response = await fetch('/process-file', {
|
| 177 |
+
method: 'POST',
|
| 178 |
+
body: file // Sending the blob directly
|
| 179 |
+
});
|
| 180 |
+
|
| 181 |
+
const data = await response.json();
|
| 182 |
+
|
| 183 |
+
if (data.error) {
|
| 184 |
+
alert("Error: " + data.error);
|
| 185 |
+
} else {
|
| 186 |
+
allData = data.trajectories;
|
| 187 |
+
|
| 188 |
+
// Re-flatten coordinate arrays for grid calculations
|
| 189 |
+
const allX = allData.flatMap(t => t.x);
|
| 190 |
+
const allY = allData.flatMap(t => t.y);
|
| 191 |
+
const allZ = allData.flatMap(t => t.z);
|
| 192 |
+
|
| 193 |
+
// Define the boundaries of your "box"
|
| 194 |
+
xMin = allX.reduce((a, b) => Math.min(a, b), Infinity);
|
| 195 |
+
yMax = allY.reduce((a, b) => Math.max(a, b), -Infinity);
|
| 196 |
+
zMin = allZ.reduce((a, b) => Math.min(a, b), Infinity);
|
| 197 |
+
|
| 198 |
+
floorData = computeDensityGrid(allX, allY);
|
| 199 |
+
wallData = computeDensityGrid(allX, allZ);
|
| 200 |
+
sideData = computeDensityGrid(allY, allZ);
|
| 201 |
+
|
| 202 |
+
// 6. Trigger UI
|
| 203 |
+
document.getElementById('plot-container').style.display = 'block';
|
| 204 |
+
// updatePlot(document.getElementById('percent').value);
|
| 205 |
+
//update slider to 2%
|
| 206 |
+
document.getElementById('percent').value = 2;
|
| 207 |
+
percentVal.innerText = "2%";
|
| 208 |
+
updatePlot(2);
|
| 209 |
+
console.log("Processed tracks:", allData.length);
|
| 210 |
+
}
|
| 211 |
+
} catch (err) {
|
| 212 |
+
console.error(err);
|
| 213 |
+
alert("Upload failed. Check file size.");
|
| 214 |
+
} finally {
|
| 215 |
+
btn.innerText = "Process File";
|
| 216 |
+
btn.style.background = "#3498db";
|
| 217 |
+
btn.style.pointerEvents = "auto"; // Re-enable button
|
| 218 |
+
}
|
| 219 |
+
}
|
| 220 |
+
|
| 221 |
+
// async function sendPathToJulia() {
|
| 222 |
+
// const path = document.getElementById('path-input').value;
|
| 223 |
+
// const btn = document.getElementById('process-btn');
|
| 224 |
+
|
| 225 |
+
// if (!path) {
|
| 226 |
+
// alert("Please provide a file path.");
|
| 227 |
+
// return;
|
| 228 |
+
// }
|
| 229 |
+
|
| 230 |
+
// btn.innerText = "Processing...";
|
| 231 |
+
// btn.style.background = "#6c757d"; // Change to grey
|
| 232 |
+
// btn.style.pointerEvents = "none"; // Prevent double-clicking
|
| 233 |
+
|
| 234 |
+
// try {
|
| 235 |
+
// const response = await fetch('http://localhost:8080/process-path', {
|
| 236 |
+
// method: 'POST',
|
| 237 |
+
// headers: { 'Content-Type': 'application/json' },
|
| 238 |
+
// body: JSON.stringify({ path: path })
|
| 239 |
+
// });
|
| 240 |
+
|
| 241 |
+
// const data = await response.json();
|
| 242 |
+
|
| 243 |
+
// if (data.error) {
|
| 244 |
+
// alert("Julia Error: " + data.error);
|
| 245 |
+
// } else {
|
| 246 |
+
// console.log("Data received:", data);
|
| 247 |
+
// allData = data.trajectories;
|
| 248 |
+
|
| 249 |
+
// // Re-flatten coordinate arrays for grid calculations
|
| 250 |
+
// const allX = allData.flatMap(t => t.x);
|
| 251 |
+
// const allY = allData.flatMap(t => t.y);
|
| 252 |
+
// const allZ = allData.flatMap(t => t.z);
|
| 253 |
+
|
| 254 |
+
// // Define the boundaries of your "box"
|
| 255 |
+
// xMin = allX.reduce((a, b) => Math.min(a, b), Infinity);
|
| 256 |
+
// yMax = allY.reduce((a, b) => Math.max(a, b), -Infinity);
|
| 257 |
+
// zMin = allZ.reduce((a, b) => Math.min(a, b), Infinity);
|
| 258 |
+
|
| 259 |
+
// floorData = computeDensityGrid(allX, allY);
|
| 260 |
+
// wallData = computeDensityGrid(allX, allZ);
|
| 261 |
+
// sideData = computeDensityGrid(allY, allZ);
|
| 262 |
+
|
| 263 |
+
// // 6. Trigger UI
|
| 264 |
+
// document.getElementById('plot-container').style.display = 'block';
|
| 265 |
+
// // updatePlot(document.getElementById('percent').value);
|
| 266 |
+
// //update slider to 2%
|
| 267 |
+
// document.getElementById('percent').value = 2;
|
| 268 |
+
// percentVal.innerText = "2%";
|
| 269 |
+
// updatePlot(2);
|
| 270 |
+
// console.log("Processed tracks:", allData.length);
|
| 271 |
+
|
| 272 |
+
// }
|
| 273 |
+
// } catch (err) {
|
| 274 |
+
// alert("Could not connect to Julia server. Is server.jl running?");
|
| 275 |
+
// console.error(err);
|
| 276 |
+
// } finally {
|
| 277 |
+
// btn.innerText = "Process File";
|
| 278 |
+
// btn.style.background = "#3498db";
|
| 279 |
+
// btn.style.pointerEvents = "auto"; // Re-enable button
|
| 280 |
+
// }
|
| 281 |
+
// }
|
| 282 |
+
|
| 283 |
+
// Use the variable name you defined in your Julia export
|
| 284 |
+
|
| 285 |
+
const plotDiv = document.getElementById('plot-container');
|
| 286 |
+
const slider = document.getElementById('percent');
|
| 287 |
+
const percentVal = document.getElementById('percent-val');
|
| 288 |
+
const opacitySlider = document.getElementById('opacity');
|
| 289 |
+
const opacityVal = document.getElementById('opacity-val');
|
| 290 |
+
|
| 291 |
+
function computeDensityGrid(allX, allY, dX = 0.2) {
|
| 292 |
+
// 1. Define the grid boundaries
|
| 293 |
+
const xMin = allX.reduce((a, b) => Math.min(a, b), Infinity);
|
| 294 |
+
const xMax = allX.reduce((a, b) => Math.max(a, b), -Infinity);
|
| 295 |
+
const yMin = allY.reduce((a, b) => Math.min(a, b), Infinity);
|
| 296 |
+
const yMax = allY.reduce((a, b) => Math.max(a, b), -Infinity);
|
| 297 |
+
|
| 298 |
+
// 2. Calculate number of bins based on fixed dX
|
| 299 |
+
// We use Math.ceil to ensure we cover the entire range
|
| 300 |
+
const xBins = Math.ceil((xMax - xMin) / dX) + 1;
|
| 301 |
+
const yBins = Math.ceil((yMax - yMin) / dX) + 1;
|
| 302 |
+
|
| 303 |
+
// 3. Create 1D axis arrays for Plotly
|
| 304 |
+
// These represent the "ticks" on your floor/wall
|
| 305 |
+
const xRange = Array.from({length: xBins}, (_, i) => xMin + (i * dX));
|
| 306 |
+
const yRange = Array.from({length: yBins}, (_, i) => yMin + (i * dX));
|
| 307 |
+
|
| 308 |
+
// 4. Initialize 2D density grid with zeros [rows][columns]
|
| 309 |
+
// Plotly Surface expects z[yIndex][xIndex]
|
| 310 |
+
let density = Array.from({ length: yBins }, () => Array(xBins).fill(0));
|
| 311 |
+
|
| 312 |
+
// 5. Populate the grid (Binning)
|
| 313 |
+
for (let i = 0; i < allX.length; i++) {
|
| 314 |
+
// Calculate which bin the point falls into
|
| 315 |
+
const xIdx = Math.floor((allX[i] - xMin) / dX);
|
| 316 |
+
const yIdx = Math.floor((allY[i] - yMin) / dX);
|
| 317 |
+
|
| 318 |
+
// Safety check to ensure indices stay within bounds
|
| 319 |
+
if (xIdx >= 0 && xIdx < xBins && yIdx >= 0 && yIdx < yBins) {
|
| 320 |
+
density[yIdx][xIdx]++;
|
| 321 |
+
}
|
| 322 |
+
}
|
| 323 |
+
|
| 324 |
+
return { x: xRange, y: yRange, z: density };
|
| 325 |
+
}
|
| 326 |
+
|
| 327 |
+
|
| 328 |
+
|
| 329 |
+
let currentOpacity = 0.99;
|
| 330 |
+
let heatmapOpacity = 0.0;
|
| 331 |
+
|
| 332 |
+
function updatePlot(percent) {
|
| 333 |
+
|
| 334 |
+
if (!allData || allData.length === 0) return;
|
| 335 |
+
|
| 336 |
+
const plotDiv = document.getElementById('plot-container');
|
| 337 |
+
|
| 338 |
+
// 1. Capture the CURRENT camera state
|
| 339 |
+
let currentCamera = null;
|
| 340 |
+
if (plotDiv && plotDiv.layout && plotDiv.layout.scene) {
|
| 341 |
+
currentCamera = plotDiv.layout.scene.camera;
|
| 342 |
+
}
|
| 343 |
+
|
| 344 |
+
// 1. Calculate how many trajectories to show
|
| 345 |
+
const totalToDisplay = Math.floor(allData.length * (percent / 100));
|
| 346 |
+
const subset = allData.slice(0, totalToDisplay);
|
| 347 |
+
|
| 348 |
+
// console.log("X range:", floorData.x[0], "to", floorData.x[floorData.x.length-1]);
|
| 349 |
+
// console.log("Y range:", floorData.y[0], "to", floorData.y[floorData.y.length-1]);
|
| 350 |
+
|
| 351 |
+
|
| 352 |
+
// 2. Map data to Plotly traces
|
| 353 |
+
const traces = subset.map(t => ({
|
| 354 |
+
type: 'scatter3d',
|
| 355 |
+
mode: 'lines',
|
| 356 |
+
x: t.x,
|
| 357 |
+
y: t.y,
|
| 358 |
+
z: t.z,
|
| 359 |
+
line: {
|
| 360 |
+
width: 2,
|
| 361 |
+
// color: viridis(t.start_time / 3600) // Color by start time (assuming in seconds, converting to hours)
|
| 362 |
+
// color:'#2c3e50'
|
| 363 |
+
color: Array(t.x.length).fill(t.start_time),
|
| 364 |
+
colorscale: 'YlGnBu',
|
| 365 |
+
cmin: 0,
|
| 366 |
+
cmax: 3600, // Assuming max start time is 60 minutes (3600 seconds)
|
| 367 |
+
},
|
| 368 |
+
opacity: currentOpacity, // Low opacity helps see the "void" density
|
| 369 |
+
hoverinfo: 'none' // Improves performance for 10k lines
|
| 370 |
+
}));
|
| 371 |
+
|
| 372 |
+
const floorSurface = {
|
| 373 |
+
type: 'surface',
|
| 374 |
+
x: floorData.x,
|
| 375 |
+
y: floorData.y,
|
| 376 |
+
z: floorData.y.map(() => floorData.x.map(() => zMin - 0.1)), // Constant Z
|
| 377 |
+
surfacecolor: floorData.z,
|
| 378 |
+
colorscale: 'Portland',
|
| 379 |
+
opacity: heatmapOpacity,
|
| 380 |
+
showscale: false,
|
| 381 |
+
hoverinfo: 'skip',
|
| 382 |
+
contours: {
|
| 383 |
+
x: { show: false },
|
| 384 |
+
y: { show: false },
|
| 385 |
+
z: { show: false }
|
| 386 |
+
}
|
| 387 |
+
|
| 388 |
+
};
|
| 389 |
+
|
| 390 |
+
const wallSurface = {
|
| 391 |
+
type: 'surface',
|
| 392 |
+
// X-matrix: Create a row for every Z-bin
|
| 393 |
+
x: wallData.y.map(() => wallData.x),
|
| 394 |
+
|
| 395 |
+
// Y-matrix: Every single point in the grid is at the same 'yMax' (the wall)
|
| 396 |
+
y: wallData.z.map(row => row.map(() => yMax + 0.2)),
|
| 397 |
+
|
| 398 |
+
// Z-matrix: Create a column for every X-bin
|
| 399 |
+
z: wallData.y.map(zVal => Array(wallData.x.length).fill(zVal)),
|
| 400 |
+
|
| 401 |
+
surfacecolor: wallData.z,
|
| 402 |
+
colorscale: 'Portland',
|
| 403 |
+
opacity: heatmapOpacity,
|
| 404 |
+
showscale: false,
|
| 405 |
+
hoverinfo: 'skip',
|
| 406 |
+
contours: { x: {show: false}, y: {show: false}, z: {show: false} }
|
| 407 |
+
};
|
| 408 |
+
|
| 409 |
+
const sideSurface = {
|
| 410 |
+
type: 'surface',
|
| 411 |
+
// X-matrix: Every single point in the grid is at the same 'xMin' (the side wall)
|
| 412 |
+
x: sideData.z.map(row => row.map(() => xMin - 0.1)),
|
| 413 |
+
|
| 414 |
+
// Y-matrix: Create a row for every Z-bin
|
| 415 |
+
y: sideData.y.map(() => sideData.x),
|
| 416 |
+
|
| 417 |
+
// Z-matrix: Create a column for every Y-bin
|
| 418 |
+
z: sideData.y.map(zVal => Array(sideData.x.length).fill(zVal)),
|
| 419 |
+
|
| 420 |
+
surfacecolor: sideData.z,
|
| 421 |
+
colorscale: 'Portland',
|
| 422 |
+
opacity: heatmapOpacity,
|
| 423 |
+
showscale: false,
|
| 424 |
+
hoverinfo: 'skip',
|
| 425 |
+
contours: { x: {show: false}, y: {show: false}, z: {show: false} }
|
| 426 |
+
};
|
| 427 |
+
|
| 428 |
+
// 3. Define Layout (Crucial for seeing the exclusion zone)
|
| 429 |
+
const layout = {
|
| 430 |
+
scene: {
|
| 431 |
+
camera: currentCamera || {
|
| 432 |
+
eye: {x: 1.25, y: 1.25, z: 1.25}
|
| 433 |
+
},
|
| 434 |
+
xaxis: { title: 'X (m)', backgroundcolor: "#f8f9fa", showbackground: true, showspikes: false, showgrid: true, zeroline: false, gridcolor: '#ffffff', gridwidth: 2 },
|
| 435 |
+
yaxis: { title: 'Y (m)', backgroundcolor: "#f8f9fa", showbackground: true, showspikes: false, showgrid: true, zeroline: false, gridcolor: '#ffffff', gridwidth: 2 },
|
| 436 |
+
zaxis: { title: 'Z (m)', backgroundcolor: "#f8f9fa", showbackground: true, showspikes: false, showgrid: true, zeroline: false, gridcolor: '#ffffff', gridwidth: 2 },
|
| 437 |
+
aspectmode: 'data' // Ensures 1:1:1 spatial scale
|
| 438 |
+
|
| 439 |
+
},
|
| 440 |
+
margin: { l: 0, r: 0, b: 0, t: 0 },
|
| 441 |
+
showlegend: false,
|
| 442 |
+
uirevision: 'constant-state-key' // Preserve camera view on updates
|
| 443 |
+
};
|
| 444 |
+
|
| 445 |
+
const config = {
|
| 446 |
+
responsive: true,
|
| 447 |
+
displaylogo: false
|
| 448 |
+
};
|
| 449 |
+
|
| 450 |
+
const dataToPlot = [ floorSurface, wallSurface, sideSurface, ...traces ];
|
| 451 |
+
|
| 452 |
+
Plotly.react(plotDiv, dataToPlot, layout, config);
|
| 453 |
+
}
|
| 454 |
+
|
| 455 |
+
|
| 456 |
+
// Event Listeners
|
| 457 |
+
slider.oninput = function() {
|
| 458 |
+
percentVal.innerText = this.value + "%";
|
| 459 |
+
};
|
| 460 |
+
|
| 461 |
+
slider.onchange = function() {
|
| 462 |
+
updatePlot(this.value);
|
| 463 |
+
};
|
| 464 |
+
|
| 465 |
+
opacitySlider.oninput = function() {
|
| 466 |
+
currentOpacity = parseFloat(this.value);
|
| 467 |
+
opacityVal.innerText = currentOpacity;
|
| 468 |
+
// Trigger a re-render with the new opacity
|
| 469 |
+
updatePlot(document.getElementById('percent').value);
|
| 470 |
+
};
|
| 471 |
+
|
| 472 |
+
// 3. Reset View Listener
|
| 473 |
+
document.getElementById('reset-view').onclick = function() {
|
| 474 |
+
Plotly.relayout('plot-container', {
|
| 475 |
+
'scene.camera': {
|
| 476 |
+
eye: {x: 1.25, y: 1.25, z: 1.25}, // Default Plotly camera position
|
| 477 |
+
center: {x: 0, y: 0, z: 0},
|
| 478 |
+
up: {x: 0, y: 0, z: 1}
|
| 479 |
+
}
|
| 480 |
+
});
|
| 481 |
+
};
|
| 482 |
+
|
| 483 |
+
document.getElementById('toggle-heatmap').onchange = function() {
|
| 484 |
+
showHeatmaps = this.checked;
|
| 485 |
+
// if checked set heatmapOpacity to 0.6 else 0.0
|
| 486 |
+
heatmapOpacity = showHeatmaps ? 0.6 : 0.0;
|
| 487 |
+
// Get the current trajectory percentage to maintain state
|
| 488 |
+
const currentPercent = document.getElementById('percent').value;
|
| 489 |
+
updatePlot(currentPercent);
|
| 490 |
+
};
|
| 491 |
+
|
| 492 |
+
|
| 493 |
+
// Initial render
|
| 494 |
+
window.onload = () => updatePlot(2);
|
| 495 |
+
|
| 496 |
+
</script>
|
| 497 |
+
</body>
|
| 498 |
+
</html>
|
server.jl
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
using Oxygen, HTTP, JSON3, CSV, DataFrames, Dates, Random, Statistics, Interpolations
|
| 2 |
+
|
| 3 |
+
parse_date(d::AbstractString) = DateTime(d, dateformat"yyyy-mm-dd HH:MM:SS.ssss")
|
| 4 |
+
|
| 5 |
+
function export_clean_traces(file;
|
| 6 |
+
min_track_length = 1.0, min_start_time = 300.0, max_start_time=Inf,
|
| 7 |
+
wall_buffer_x = 0.0 , wall_buffer_y = 0.0, wall_buffer_z = 0.0
|
| 8 |
+
)
|
| 9 |
+
|
| 10 |
+
data = CSV.read(file, DataFrame)
|
| 11 |
+
df = convert(DataFrame,data)
|
| 12 |
+
groups = groupby(df, 1)
|
| 13 |
+
|
| 14 |
+
starting_times, clean_traces = save_data(groups, file;
|
| 15 |
+
min_track_length=min_track_length, min_start_time=min_start_time, max_start_time=max_start_time,
|
| 16 |
+
wall_buffer_x=wall_buffer_x, wall_buffer_y=wall_buffer_y, wall_buffer_z=wall_buffer_z
|
| 17 |
+
)
|
| 18 |
+
|
| 19 |
+
return starting_times, clean_traces
|
| 20 |
+
|
| 21 |
+
end
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
function save_data(groups, file;
|
| 25 |
+
min_track_length = 1.0, min_start_time = 300.0, max_start_time = Inf,
|
| 26 |
+
wall_buffer_x = 0.0 , wall_buffer_y = 0.0, wall_buffer_z = 0.0
|
| 27 |
+
)
|
| 28 |
+
# first, compute positions of wall
|
| 29 |
+
min_x = Vector{Float64}()
|
| 30 |
+
max_x = Vector{Float64}()
|
| 31 |
+
min_y = Vector{Float64}()
|
| 32 |
+
max_y = Vector{Float64}()
|
| 33 |
+
min_z = Vector{Float64}()
|
| 34 |
+
max_z = Vector{Float64}()
|
| 35 |
+
for g in groups
|
| 36 |
+
push!(min_x,minimum(g[:,3]))
|
| 37 |
+
push!(max_x,maximum(g[:,3]))
|
| 38 |
+
push!(min_y,minimum(g[:,4]))
|
| 39 |
+
push!(max_y,maximum(g[:,4]))
|
| 40 |
+
push!(min_z,minimum(g[:,5]))
|
| 41 |
+
push!(max_z,maximum(g[:,5]))
|
| 42 |
+
end
|
| 43 |
+
|
| 44 |
+
wall_robust = [(quantile(min_x,0.01),quantile(max_x,0.99)),(quantile(min_y,0.01),quantile(max_y,0.99)),(quantile(min_z,0.01),quantile(max_z,0.99))]
|
| 45 |
+
println("Wall x position: ", wall_robust[1])
|
| 46 |
+
println("Wall y position: ", wall_robust[2])
|
| 47 |
+
println("Wall z position: ", wall_robust[3])
|
| 48 |
+
|
| 49 |
+
# Filter tracks based on time requirements
|
| 50 |
+
experiment_start_time = parse_date(groups[1].datetime[1][1:end-3])
|
| 51 |
+
long_traces = []
|
| 52 |
+
for g in groups
|
| 53 |
+
track_end_time = parse_date(g.datetime[end][1:end-3])
|
| 54 |
+
track_start_time = parse_date(g.datetime[1][1:end-3])
|
| 55 |
+
if Dates.value(track_end_time - track_start_time)/1000 > min_track_length && Dates.value(track_start_time-experiment_start_time)/1000 > min_start_time && Dates.value(track_start_time-experiment_start_time)/1000 < max_start_time
|
| 56 |
+
push!(long_traces,g)
|
| 57 |
+
end
|
| 58 |
+
end
|
| 59 |
+
|
| 60 |
+
# Filter tracks based on position from wall
|
| 61 |
+
final_traces = []
|
| 62 |
+
times = []
|
| 63 |
+
starting_times = []
|
| 64 |
+
for g in long_traces
|
| 65 |
+
if all(g[:,3] .> wall_robust[1][1]+wall_buffer_x) && all(g[:,3] .< wall_robust[1][2]-wall_buffer_x) && all(g[:,4] .> wall_robust[2][1]+wall_buffer_y) && all(g[:,4] .< wall_robust[2][2]-wall_buffer_y) && all(g[:,5] .> wall_robust[3][1]+wall_buffer_z) && all(g[:,5] .< wall_robust[3][2]-wall_buffer_z)
|
| 66 |
+
push!(final_traces,g)
|
| 67 |
+
tmp = []
|
| 68 |
+
for i in 1:length(g.datetime)
|
| 69 |
+
push!(tmp,Dates.value(parse_date(g.datetime[i][1:end-3])-parse_date(g.datetime[1][1:end-3]))/1000)
|
| 70 |
+
end
|
| 71 |
+
push!(starting_times,Dates.value(parse_date(g.datetime[1][1:end-3])-experiment_start_time)/1000)
|
| 72 |
+
push!(times,tmp)
|
| 73 |
+
end
|
| 74 |
+
end
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
clean_traces = Vector{Matrix{Float64}}()
|
| 78 |
+
for g in 1:length(final_traces)
|
| 79 |
+
if sum(diff(times[g]) .<= 0.0) == 0
|
| 80 |
+
# ts = LinRange(0.0,times[g][end],Int(round(times[g][end]*100)+1))
|
| 81 |
+
ts = collect(0.0:0.01:times[g][end]) # fix dt to 0.01 seconds
|
| 82 |
+
interp_linear_xs = linear_interpolation(times[g], final_traces[g][:,3])
|
| 83 |
+
interp_linear_ys = linear_interpolation(times[g], final_traces[g][:,4])
|
| 84 |
+
interp_linear_zs = linear_interpolation(times[g], final_traces[g][:,5])
|
| 85 |
+
|
| 86 |
+
temp = zeros(length(ts),5)
|
| 87 |
+
temp[:,1] = interp_linear_xs.(ts) / 100 # convert cm to m
|
| 88 |
+
temp[:,2] = interp_linear_ys.(ts) / 100
|
| 89 |
+
temp[:,3] = interp_linear_zs.(ts) / 100
|
| 90 |
+
temp[:,4] = ts
|
| 91 |
+
|
| 92 |
+
for j in 1:length(ts)
|
| 93 |
+
if round(ts[j],digits=2) in times[g]
|
| 94 |
+
temp[j,5] = 1.0
|
| 95 |
+
else
|
| 96 |
+
temp[j,5] = 0.0
|
| 97 |
+
end
|
| 98 |
+
end
|
| 99 |
+
push!(clean_traces,temp)
|
| 100 |
+
else
|
| 101 |
+
println("Skipping track ",g)
|
| 102 |
+
deleteat!(starting_times, g)
|
| 103 |
+
end
|
| 104 |
+
end
|
| 105 |
+
|
| 106 |
+
return starting_times, clean_traces
|
| 107 |
+
|
| 108 |
+
end
|
| 109 |
+
|
| 110 |
+
function unzip(collection)
|
| 111 |
+
firsts = [x[1] for x in collection]
|
| 112 |
+
seconds = [x[2] for x in collection]
|
| 113 |
+
return firsts, seconds
|
| 114 |
+
end
|
| 115 |
+
|
| 116 |
+
# Re-use your existing processing logic here
|
| 117 |
+
function process_big_csv(filepath)
|
| 118 |
+
start_times, traces = export_clean_traces(filepath;
|
| 119 |
+
min_track_length = 1.0, min_start_time = 0.0, max_start_time=Inf,
|
| 120 |
+
)
|
| 121 |
+
combined = collect(zip(start_times, traces))
|
| 122 |
+
shuffle!(combined)
|
| 123 |
+
# Separate the shuffled arrays
|
| 124 |
+
start_times, traces = unzip(combined);
|
| 125 |
+
payload = Dict("trajectories"=> [Dict("start_time" => start_times[i],
|
| 126 |
+
"x" => Float32.(traces[i][:,1]),
|
| 127 |
+
"y" => Float32.(traces[i][:,3]),
|
| 128 |
+
"z" => Float32.(traces[i][:,2]),
|
| 129 |
+
) for i in 1:length(traces)]
|
| 130 |
+
)
|
| 131 |
+
return payload # A dictionary/struct
|
| 132 |
+
end
|
| 133 |
+
|
| 134 |
+
@get "/" function()
|
| 135 |
+
return file("index.html")
|
| 136 |
+
end
|
| 137 |
+
|
| 138 |
+
@post "/process-path" function(req)
|
| 139 |
+
# Julia receives the file path or raw bytes
|
| 140 |
+
# Processes it at 100% precision
|
| 141 |
+
data = JSON3.read(String(req.body))
|
| 142 |
+
filepath = data.path
|
| 143 |
+
data = process_big_csv(filepath)
|
| 144 |
+
return data # Automatically converted to JSON
|
| 145 |
+
end
|
| 146 |
+
|
| 147 |
+
@post "/process-file" function(req)
|
| 148 |
+
try
|
| 149 |
+
# req.body contains the raw bytes of the uploaded 600MB file
|
| 150 |
+
# We wrap it in an IOBuffer so CSV.read can process it in RAM
|
| 151 |
+
data = process_big_csv(IOBuffer(req.body))
|
| 152 |
+
|
| 153 |
+
# Return results (Oxygen handles JSON conversion)
|
| 154 |
+
return data
|
| 155 |
+
catch e
|
| 156 |
+
return HTTP.Response(500, JSON3.write(Dict("error" => string(e))))
|
| 157 |
+
end
|
| 158 |
+
end
|
| 159 |
+
|
| 160 |
+
staticfiles(".")
|
| 161 |
+
serve(host="0.0.0.0", port=7860)
|