Compare commits
591 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9490a06303 | |||
| 5fb1ae0678 | |||
| 97c03e216b | |||
|
|
bab4490847 | ||
|
8e824d4afa
|
|||
|
|
777cf1a31d | ||
|
efacb2a332
|
|||
|
|
17c4e9dd22 | ||
| 503ccbb2ad | |||
|
54c40d7acc
|
|||
|
d8d5e076ba
|
|||
|
|
fd2b3fe691 | ||
| 6ae7a7dac8 | |||
|
e429a855e5
|
|||
|
|
9ed60b7cc8 | ||
|
|
175df0ce33 | ||
|
|
d5cde19250 | ||
| 2e1165d99c | |||
| a100ffa77b | |||
| 95c3608d85 | |||
| 15d91d87bf | |||
| f6ec692ebf | |||
| f41617c08e | |||
| 2bf0d82a5b | |||
| 3e61cfb939 | |||
| 21ec3a04ab | |||
| 5d6fe5572b | |||
| 0a543c7b21 | |||
| b1ba2effe3 | |||
| 626ce34dc0 | |||
| b879555e6a | |||
| ed08980df3 | |||
| 6aee2bbc60 | |||
| d4701c958c | |||
| 446d4f4171 | |||
| 1ed2a15c4c | |||
| 42b746871a | |||
| 6c20b01cc2 | |||
| 4f879252a0 | |||
|
|
11724987b0 | ||
| d90703453f | |||
|
eaea4b2e21
|
|||
|
|
68efc76e8e | ||
| 6df17c88c7 | |||
|
ec109328fb
|
|||
|
|
f4943a148b | ||
|
15e348c17b
|
|||
|
6cf5262dd5
|
|||
|
|
4b229cd7d7 | ||
| e372be192a | |||
|
ab37e88bb0
|
|||
|
|
d38a784326 | ||
| 4d18b105c8 | |||
|
492651e0f3
|
|||
|
cd678a41f6
|
|||
| 03fbc14b72 | |||
|
d86db7a66c
|
|||
|
7182f7c9f0
|
|||
|
eac23e7d1a
|
|||
|
b500fdb211
|
|||
|
180aba4fa5
|
|||
|
|
d9d7221e90 | ||
| b3fe6f8b70 | |||
| 4792720d74 | |||
| 46e86eb5f9 | |||
| 9a890f30fc | |||
| 66c44976d8 | |||
| 608caeeda2 | |||
| 55bcaaf963 | |||
|
|
ce10ea93db | ||
|
e513d87d24
|
|||
|
|
08061bc6ce | ||
| dd55a0c9df | |||
| 89f0f768e3 | |||
|
5315a05fa2
|
|||
| 57b28daf4e | |||
|
|
0ba060d78c | ||
|
|
b2077ae317 | ||
|
4cd3673d15
|
|||
|
|
771712ad9a | ||
| 1d6941ecc6 | |||
|
56d34767d7
|
|||
| 5fbd914e24 | |||
| 5f193c559f | |||
| a998483d2c | |||
|
|
a4159f0fff | ||
| 866f3a317b | |||
|
4eac05cbb7
|
|||
|
efb3292d9f
|
|||
|
6e822bd5d1
|
|||
|
d8bf174d3a
|
|||
|
2f7be7b051
|
|||
| 18bb207e4a | |||
|
c914f4a477
|
|||
|
2da1be0c6b
|
|||
|
eb00b8c19d
|
|||
|
09a9e47348
|
|||
|
156ae2315a
|
|||
|
|
cf6bedbd9b | ||
| 36aa90519e | |||
|
14c1a57331
|
|||
| d7f0630693 | |||
| 3b7149f161 | |||
| 5545e90160 | |||
| da5b38d1ea | |||
|
65928c4064
|
|||
|
|
033b61dd4f | ||
| 5725d43b11 | |||
|
a8a187a412
|
|||
|
|
f30e16b15e | ||
| bd745042df | |||
|
70878e1423
|
|||
|
937b2c367b
|
|||
| faa0a8533e | |||
|
1cb9d455db
|
|||
|
|
453c9d234c | ||
| 369127e081 | |||
|
|
563faa6c0b | ||
|
|
17163ab002 | ||
|
|
6293e9e67a | ||
|
|
a68ef32614 | ||
| 4de10614be | |||
|
|
2887e6a909 | ||
|
|
e75ffc41e5 | ||
|
|
a620c26812 | ||
|
|
f2bb57b50d | ||
| 8e0cb2105a | |||
|
|
048e80356b | ||
|
|
a47fb89143 | ||
|
|
1b8167c66e | ||
|
|
48d46eda62 | ||
|
|
36307c822e | ||
|
|
dca32db800 | ||
|
|
a153238f79 | ||
|
|
c1fa85fd1b | ||
|
|
69b380e665 | ||
|
|
afc888ab60 | ||
|
|
9a4ef08060 | ||
|
f68b7f68c8
|
|||
|
|
d8143a6b8d | ||
|
e04d36ca12
|
|||
|
|
275ec44a97 | ||
|
fff7913cd5
|
|||
|
|
23ba2efe96 | ||
|
759bbc6f60
|
|||
|
3140c07ad0
|
|||
|
b109dbdcbd
|
|||
|
c1be7c468d
|
|||
|
|
d3797115f7 | ||
|
6d04af6230
|
|||
|
7cf50641f9
|
|||
|
dd398bd96b
|
|||
|
|
63d782ade4 | ||
| e3a1f56b87 | |||
|
|
2f18948cce | ||
|
|
4786850431 | ||
|
|
7584bf661f | ||
|
|
f23b3f1821 | ||
|
|
5bb2ffd67c | ||
| c3c9e8e4e2 | |||
| b03908f93e | |||
| c2e7762df8 | |||
|
|
c83beadd45 | ||
| 46d6b1277b | |||
|
|
10a8c42319
|
||
| 9ed4165ebc | |||
|
|
8cc840adc5 | ||
|
|
79c6e2abd0 | ||
|
|
3093757454 | ||
|
028945bfca
|
|||
|
|
09556bc5df | ||
|
|
94b7f25852 | ||
|
|
2831c8a5cb | ||
|
|
1fed7adf80 | ||
|
|
a9145f6f79 | ||
|
|
ccbe07619f | ||
| 95e6096fbb | |||
|
|
65c29879ab | ||
| b794fc3b68 | |||
| df7be8d894 | |||
|
a474e7cbd4
|
|||
| 5aa83c4bf2 | |||
| 210a04c24d | |||
| 6a35b374c2 | |||
|
785d0d57ae
|
|||
| 7e376f3609 | |||
| ae233cb764 | |||
| 0b9751a97b | |||
| c6c5659b2c | |||
| e1d67df304 | |||
| 7b00f80ac9 | |||
| 92be7a0201 | |||
| 7700924d0e | |||
| 6620c44202 | |||
|
ca5c6791d3
|
|||
|
|
d80797bb17 | ||
|
|
4d9e78cd69 | ||
|
|
4980a41a44
|
||
|
|
d5047b0189 | ||
|
|
8c17a644d5 | ||
|
|
c77ce73a69 | ||
|
|
020a2f2e00 | ||
|
847270877a
|
|||
| d4dd7945cb | |||
| 4626333c74 | |||
| d5341acd28 | |||
| 3c2da99235 | |||
| 013b5fea91 | |||
| 7ea657b582 | |||
| d1e416c850 | |||
| 232c095954 | |||
|
|
f5a3920eea | ||
|
|
51cb94a2e0 | ||
|
|
e0b5522b8f | ||
|
|
19827701aa | ||
| 48dcee7d7f | |||
| 02b6b36f95 | |||
| 8f38f19dd0 | |||
| 04bde9e221 | |||
| 3d948d3ba9 | |||
| 67c23b8707 | |||
| fbe0e59175 | |||
| 1f86f950d6 | |||
| ffce84bb37 | |||
| 2308d50310 | |||
| 1f5dd53673 | |||
|
f8940c9220
|
|||
| 9566bce0bd | |||
|
|
2f9b292ee4 | ||
|
54d8c3fe09
|
|||
| ddd84b2af3 | |||
|
f8ab41bbda
|
|||
| 2f4a458964 | |||
|
|
799fbe67e5 | ||
| 33d94c5d94 | |||
|
|
beedeb836b | ||
| d4766f249b | |||
|
|
fc41c91d41 | ||
| 679ab2f945 | |||
| 13b257f7ff | |||
| bfc25a2894 | |||
| 9f112aedd8 | |||
|
|
61b4323803 | ||
|
|
271f40cdbc | ||
|
|
2bf628103c | ||
|
|
5be346e0fc | ||
|
|
d8f38c496d | ||
|
|
917058b7be | ||
|
|
1b4f4ef360 | ||
|
|
da6a1995c1 | ||
| b030e8eeb7 | |||
| 6c8bb8b95a | |||
|
|
a9c6ebc0de | ||
| b50fe38a06 | |||
|
a627b08df2
|
|||
|
b062f66cf9
|
|||
| 99c0279a1f | |||
| ba3906da71 | |||
|
|
db87ef5df1 | ||
|
|
dacc30da0d | ||
|
|
6d5a72412b | ||
|
|
748ba286ab | ||
|
|
49d50b4bb1 | ||
|
|
039df744d3 | ||
|
|
3a9c616f6b | ||
| 570a2237f1 | |||
| 50b5524c13 | |||
| b2c475101c | |||
|
|
187a5e36e3 | ||
| cde779ea00 | |||
| 8106bb9380 | |||
| df56303949 | |||
| 79238c2a8f | |||
|
|
637d22e0f0 | ||
| ac82e2c7ba | |||
| 5b429bd94f | |||
|
754477b679
|
|||
| c9bed6623c | |||
|
993e5680bb
|
|||
| cf8ec277cb | |||
|
|
9b6a3ef133 | ||
|
|
2476d9f83c | ||
|
|
e9c21c1292 | ||
|
|
c6eee07317 | ||
| aaa56271b0 | |||
| 4280431d0f | |||
|
|
e85a114a23 | ||
|
|
1d1ddf2fef | ||
|
|
0bd66f89fd | ||
|
|
e886589332 | ||
|
|
a7cb34d7ba | ||
|
|
1edf1c2e55 | ||
|
|
234cd19af7 | ||
|
|
40414db1f6 | ||
|
|
f160e341ce | ||
|
5a4ef2bd70
|
|||
|
0473f7b765
|
|||
|
|
7fb92d18c7 | ||
|
|
7054ade55d | ||
|
|
0a54ae3dcc | ||
| 6016cda9ef | |||
|
|
4257ec5598 | ||
| 009008e0d7 | |||
|
|
554bb6b184 | ||
|
b5c21bb62c
|
|||
| 3b0de79bd8 | |||
| ed916c1362 | |||
|
|
77c8b95af4 | ||
|
8482921420
|
|||
| d3d1851142 | |||
| 7a93caecb1 | |||
| 7ebaaa419f | |||
| 4850f9d4c3 | |||
| 7075cc50b9 | |||
| 2a1761e5eb | |||
| c6c4eb57a9 | |||
| 6d92b9b929 | |||
| 90a5c83ca1 | |||
| aadb8d6b50 | |||
|
90bab5ecc0
|
|||
| 0cf2b641cd | |||
| 6183d235ac | |||
| 79ae757e7d | |||
| 4782cde597 | |||
| e934101db7 | |||
| dbea593b1c | |||
| 8f0c414775 | |||
| 17181f6ca2 | |||
| 8792637774 | |||
| 506b76fc00 | |||
| edfd519b8e | |||
| 5520ab8d30 | |||
| 8f06be26ef | |||
| a627d509ac | |||
| 1fa65def25 | |||
| d805997470 | |||
| 1e1e429c9a | |||
| 9eed6af711 | |||
| a046e7d849 | |||
| db37040209 | |||
| 217fd54ec4 | |||
| 17c8c12f55 | |||
| 3ff2a0f63c | |||
| edcf95f71e | |||
| aafc0d55bf | |||
| 215409c7c8 | |||
| 59d5557bdd | |||
| 22ea4b29b8 | |||
| 59ce5b98b8 | |||
| 51fc7503b5 | |||
| 143b55634e | |||
| 3ba59a39bf | |||
| 0dbd11ed68 | |||
| f7fbc5d70d | |||
| 7e3a520dad | |||
| 9a26a258b6 | |||
| 94432247b3 | |||
| 86425a2292 | |||
| 9bd0562b47 | |||
| 1a7777acd1 | |||
| 214fb650c1 | |||
| e9b3c4adba | |||
| fa63ade2e1 | |||
| eab1b42f76 | |||
| c5b85e9ad4 | |||
| 79daa83aca | |||
| 761946660c | |||
| 723064ae52 | |||
| 7db499b1c7 | |||
| c28664b9ee | |||
| f250e8bf16 | |||
| b6818cd7fa | |||
| 3055b8d489 | |||
| 819964ec87 | |||
| 0898faec4d | |||
| 3b4ec021af | |||
| 3ddd22edd1 | |||
| cd4431db1b | |||
| b7ba8eb771 | |||
| f74aacf53b | |||
| cacff8d4df | |||
| b028e54c52 | |||
| 34774e57de | |||
| 9181b43732 | |||
| 1e12fa52aa | |||
| 7176919e94 | |||
| 5ee01e58d8 | |||
| ce495ebcb8 | |||
| b91a528108 | |||
| 333ddd0ba3 | |||
| 291c077536 | |||
| 362718dd9c | |||
| 7e12df8cc0 | |||
| c862cb172f | |||
| 6cdafc22b4 | |||
| 750d1a0803 | |||
| ff7ce98672 | |||
|
|
03eab47d23 | ||
| 1b12faa61a | |||
|
9388d3758d
|
|||
|
7f6ad2b853
|
|||
|
|
4467957b8f | ||
| cafe1204ef | |||
|
16f968657b
|
|||
|
|
8274bb982a | ||
| b3da5b2a96 | |||
|
|
b293044258 | ||
|
|
4db102157f | ||
| 16a4ccbc6b | |||
|
|
407a278e28 | ||
|
|
8134999600 | ||
|
|
f29aafe943 | ||
|
d64ee45d9e
|
|||
|
48b5da9da3
|
|||
|
|
4882fa51e1 | ||
|
|
f72107751f | ||
|
|
cb6265dcb1 | ||
|
|
92ef67a75f | ||
|
|
2e2ae7a0be | ||
| 209f668879 | |||
|
|
f3e1d98704 | ||
|
|
f8045f6dcc | ||
|
|
9a41f0a2f3 | ||
|
|
81743540d0 | ||
|
|
a332fe72a2 | ||
|
|
9bb9d855e4 | ||
|
|
16643c3460 | ||
|
|
eacaa05236 | ||
|
5476583cb2
|
|||
|
|
cb5f059661 | ||
| 23498f5b04 | |||
|
|
5e84185950 | ||
|
|
22339c6ade | ||
|
|
690ce80957 | ||
|
|
d7b373630c | ||
|
60a47b0308
|
|||
|
|
bbb3ebc97c | ||
|
|
a5b348e439 | ||
|
|
aebcfb2e1e | ||
|
904845fe0a
|
|||
|
|
94ccb3583d | ||
|
|
4ecd386f47 | ||
| d182900b02 | |||
|
|
c6f2a04b07 | ||
|
|
c75d13711a | ||
|
|
7fff70b7d5 | ||
|
|
43d36ded42 | ||
|
|
9ea31be332 | ||
|
|
6151eb86f0 | ||
|
|
bda39dea78 | ||
|
|
63294887b1 | ||
|
|
598fd5a7b0 | ||
|
|
582d0377ab | ||
|
704242e120
|
|||
| 5a3474a282 | |||
|
|
3e984d7ee2 | ||
|
|
e3a2d2a1fb | ||
| ea335bc3fb | |||
|
|
c0ac950062 | ||
| e34464782a | |||
| be1f942413 | |||
|
|
3749e2d87d | ||
| 94c8accf45 | |||
|
|
07858a5c7e | ||
| 1a0ca268ab | |||
| fe21779363 | |||
| b7a3d3a3ce | |||
| 60981b6edf | |||
| 845ea0cbc2 | |||
| 1742b99f19 | |||
| 61140b656c | |||
| a6ee8e24fd | |||
| 443bf8e9bd | |||
| a3d98f24b3 | |||
| 143f0ca988 | |||
| b4ef9d9c93 | |||
| 4dc956c9e6 | |||
| c3cc338b20 | |||
| 79f02c18b7 | |||
| 9737cb154b | |||
| 4c6a93ae60 | |||
| a48e7f2f22 | |||
| 190b227d97 | |||
| b4c8de2e09 | |||
| 0922a8fa08 | |||
|
|
ce3d0321c2 | ||
|
93c166144e
|
|||
|
|
09f11c2e4d | ||
|
b9b97205c2
|
|||
|
91e73b7904
|
|||
|
|
6501f45238 | ||
| 7894dba21a | |||
|
0586f2f7d3
|
|||
|
|
352421d5ee | ||
|
|
05f6e35d72 | ||
|
7b90371f84
|
|||
|
|
a3bb3285e1 | ||
| 1e76a29131 | |||
| f6ce5d26c3 | |||
| 295fb9c116 | |||
|
29eeb17306
|
|||
|
ebc12b9ef9
|
|||
|
|
7a4a9f4f05 | ||
| d76fd50321 | |||
|
5fb18877c4
|
|||
| 046dd4ac11 | |||
|
|
e162a8a320 | ||
| cd5a397c3a | |||
|
b2d8dec9a4
|
|||
| a4f1752e72 | |||
| ace083af9e | |||
|
|
7216ddd67b | ||
|
2e260d1184
|
|||
|
|
c222803ef1 | ||
| 05bdb97e1d | |||
| 5a6c7258a4 | |||
|
902a28932d
|
|||
|
|
3519a0df5c | ||
|
c2a99ac1ee
|
|||
|
|
550e3f153b | ||
| 0c3388cf08 | |||
| 2a074357e0 | |||
| 5402af7f8f | |||
| 9cd9518a38 | |||
|
|
704c310b83 | ||
|
|
12fe518235 | ||
|
|
03733df79d | ||
|
|
1247d4d092 | ||
| ad91a3dd23 | |||
|
|
8ad5cdb3ee | ||
|
2c6a30a4f6
|
|||
|
|
4a893d8a56 | ||
| 9ba2c73e5c | |||
|
|
8e72010740 | ||
|
|
6affdada5d | ||
| bf92311c11 | |||
| ac25329204 | |||
| 047d74723e | |||
| 3a7df65f0a | |||
|
|
e7ae2ee38a | ||
|
|
e73ac386a4 | ||
|
6e31e77f03
|
|||
| 8c7334f121 | |||
|
27df77bfeb
|
|||
|
fd76b47789
|
|||
|
|
ce01aac316 | ||
| dae8ceacd6 | |||
| 4806dd97de | |||
| d58deea636 | |||
|
|
e77895c2eb
|
||
|
|
12f215c6a0 | ||
|
f441a15f69
|
|||
|
|
8827130729 | ||
|
b2cce311b5
|
|||
|
|
a3212fa80f | ||
|
cee62b15e6
|
|||
|
|
ba481964e4 | ||
| cd72635051 | |||
|
7205dfe7ca
|
|||
|
|
8e05f95ecc | ||
|
|
4596fd750f | ||
|
|
55c798d7f7 | ||
| 124a900b44 | |||
| 90b17a59a2 | |||
| 015f24669e | |||
|
|
e439057c5b | ||
| db21ab46d4 | |||
|
d35f666664
|
|||
|
|
957d9e72a4 | ||
| d7dff3dbc3 | |||
|
|
62b09deb8d | ||
|
|
9db2ec0d64 | ||
| 3bd402937f | |||
|
1780867a89
|
|||
|
7d378a52d1
|
|||
|
5ecb1b0945
|
|||
|
|
62b1431ed8 | ||
| e48555d88e | |||
|
8d9843d467
|
|||
|
|
0e6dbda05f | ||
| e89237e493 | |||
|
f6267962b3
|
|||
|
7983d948f1
|
|||
| 5df2fba6b7 | |||
|
6e7fa4b9c7
|
|||
|
|
396699f1f1 | ||
|
|
9f776e5e01 | ||
|
|
2c0b264ebd | ||
| d230509984 | |||
|
2a3bb68e3e
|
|||
| 3593a4494d |
@@ -1,38 +0,0 @@
|
||||
open Fake.Core
|
||||
open Fake.IO
|
||||
open Farmer
|
||||
open Farmer.Builders
|
||||
|
||||
open Helpers
|
||||
|
||||
initializeContext()
|
||||
|
||||
let packPath = Path.getFullName "packages"
|
||||
|
||||
Target.create "Clean" (fun _ -> Shell.cleanDir packPath)
|
||||
|
||||
Target.create "InstallClient" (fun _ ->
|
||||
run bun "install" "."
|
||||
run dotnet "tool restore" "."
|
||||
)
|
||||
|
||||
Target.create "Run" ignore
|
||||
|
||||
Target.create "Format" (fun _ ->
|
||||
run dotnet "fantomas . -r" "src"
|
||||
)
|
||||
|
||||
open Fake.Core.TargetOperators
|
||||
|
||||
let dependencies = [
|
||||
"Clean"
|
||||
==> "InstallClient"
|
||||
|
||||
"Run"
|
||||
==> "InstallClient"
|
||||
|
||||
"Format"
|
||||
]
|
||||
|
||||
[<EntryPoint>]
|
||||
let main args = runOrDefault args
|
||||
@@ -1,127 +0,0 @@
|
||||
module Helpers
|
||||
|
||||
open Fake.Core
|
||||
|
||||
let initializeContext () =
|
||||
let execContext = Context.FakeExecutionContext.Create false "build.fsx" [ ]
|
||||
Context.setExecutionContext (Context.RuntimeContext.Fake execContext)
|
||||
|
||||
module Proc =
|
||||
module Parallel =
|
||||
open System
|
||||
|
||||
let locker = obj()
|
||||
|
||||
let colors =
|
||||
[| ConsoleColor.Blue
|
||||
ConsoleColor.Yellow
|
||||
ConsoleColor.Magenta
|
||||
ConsoleColor.Cyan
|
||||
ConsoleColor.DarkBlue
|
||||
ConsoleColor.DarkYellow
|
||||
ConsoleColor.DarkMagenta
|
||||
ConsoleColor.DarkCyan |]
|
||||
|
||||
let print color (colored: string) (line: string) =
|
||||
lock locker
|
||||
(fun () ->
|
||||
let currentColor = Console.ForegroundColor
|
||||
Console.ForegroundColor <- color
|
||||
Console.Write colored
|
||||
Console.ForegroundColor <- currentColor
|
||||
Console.WriteLine line)
|
||||
|
||||
let onStdout index name (line: string) =
|
||||
let color = colors.[index % colors.Length]
|
||||
if isNull line then
|
||||
print color $"{name}: --- END ---" ""
|
||||
else if String.isNotNullOrEmpty line then
|
||||
print color $"{name}: " line
|
||||
|
||||
let onStderr name (line: string) =
|
||||
let color = ConsoleColor.Red
|
||||
if isNull line |> not then
|
||||
print color $"{name}: " line
|
||||
|
||||
let redirect (index, (name, createProcess)) =
|
||||
createProcess
|
||||
|> CreateProcess.redirectOutputIfNotRedirected
|
||||
|> CreateProcess.withOutputEvents (onStdout index name) (onStderr name)
|
||||
|
||||
let printStarting indexed =
|
||||
for (index, (name, c: CreateProcess<_>)) in indexed do
|
||||
let color = colors.[index % colors.Length]
|
||||
let wd =
|
||||
c.WorkingDirectory
|
||||
|> Option.defaultValue ""
|
||||
let exe = c.Command.Executable
|
||||
let args = c.Command.Arguments.ToStartInfo
|
||||
print color $"{name}: {wd}> {exe} {args}" ""
|
||||
|
||||
let run cs =
|
||||
cs
|
||||
|> Seq.toArray
|
||||
|> Array.indexed
|
||||
|> fun x -> printStarting x; x
|
||||
|> Array.map redirect
|
||||
|> Array.Parallel.map Proc.run
|
||||
|
||||
let createProcess exe arg dir =
|
||||
CreateProcess.fromRawCommandLine exe arg
|
||||
|> CreateProcess.withWorkingDirectory dir
|
||||
|> CreateProcess.ensureExitCode
|
||||
|
||||
let dotnet = createProcess "dotnet"
|
||||
|
||||
let fable = createProcess "fable"
|
||||
|
||||
let bun =
|
||||
let bunPath =
|
||||
match ProcessUtils.tryFindFileOnPath "bun" with
|
||||
| Some path -> path
|
||||
| None ->
|
||||
"bun was not found in path. Please install it and make sure it's available from your path. " +
|
||||
"See https://safe-stack.github.io/docs/quickstart/#install-pre-requisites for more info"
|
||||
|> failwith
|
||||
|
||||
createProcess bunPath
|
||||
|
||||
let bunx = createProcess "bunx"
|
||||
|
||||
type BundleMode =
|
||||
| Prod
|
||||
| Devel
|
||||
| Watch
|
||||
with
|
||||
override this.ToString() =
|
||||
match this with
|
||||
| Prod -> "production"
|
||||
| Devel -> "development"
|
||||
| Watch -> "watch"
|
||||
|
||||
let viteCmd (m: BundleMode) outDir =
|
||||
match m with
|
||||
| Prod -> $"vite build -c ../../vite.config.js -m {m} --emptyOutDir --outDir {outDir}/public"
|
||||
| Devel -> $"vite build -c ../../vite.config.js -m {m} --minify false --sourcemap true --emptyOutDir --outDir {outDir}/public"
|
||||
| Watch -> "vite -c ../../vite.config.js"
|
||||
|
||||
let run proc arg dir =
|
||||
proc arg dir
|
||||
|> Proc.run
|
||||
|> ignore
|
||||
|
||||
let runParallel processes =
|
||||
processes
|
||||
|> Proc.Parallel.run
|
||||
|> ignore
|
||||
|
||||
let runOrDefault args =
|
||||
try
|
||||
match args with
|
||||
| [| target |] -> Target.runOrDefault target
|
||||
| _ ->
|
||||
Target.runOrDefault "Run"
|
||||
0
|
||||
with e ->
|
||||
printfn "%A" e
|
||||
1
|
||||
@@ -1,27 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"fable": {
|
||||
"version": "4.25.0",
|
||||
"commands": [
|
||||
"fable"
|
||||
],
|
||||
"rollForward": false
|
||||
},
|
||||
"fantomas": {
|
||||
"version": "7.0.2",
|
||||
"commands": [
|
||||
"fantomas"
|
||||
],
|
||||
"rollForward": false
|
||||
},
|
||||
"dotnet-outdated-tool": {
|
||||
"version": "4.6.7",
|
||||
"commands": [
|
||||
"dotnet-outdated"
|
||||
],
|
||||
"rollForward": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,23 @@ insert_final_newline = false
|
||||
|
||||
[*.js]
|
||||
indent_size = 2
|
||||
max_line_length = 80
|
||||
|
||||
[*.scss]
|
||||
indent_size = 2
|
||||
max_line_length = 80
|
||||
|
||||
[*.nix]
|
||||
indent_size = 2
|
||||
max_line_length= 80
|
||||
|
||||
[*.scss]
|
||||
indent_size = 2
|
||||
max_line_length = 80
|
||||
|
||||
[*.yaml]
|
||||
indent_size = 2
|
||||
|
||||
[*.fs]
|
||||
max_line_length= 120
|
||||
|
||||
@@ -21,6 +36,7 @@ fsharp_space_before_uppercase_invocation = true
|
||||
fsharp_blank_lines_around_nested_multiline_expressions = false
|
||||
fsharp_newline_between_type_definition_and_members = false
|
||||
fsharp_multiline_bracket_style = stroustrup
|
||||
fsharp_multi_line_lambda_closing_newline = true
|
||||
|
||||
fsharp_array_or_list_multiline_formatter = character_width
|
||||
fsharp_max_array_or_list_width = 70
|
||||
|
||||
18
.envrc
18
.envrc
@@ -1,18 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
export NPINS_DIRECTORY="nix"
|
||||
export APP_ENV=$USER
|
||||
|
||||
# the shebang is ignored, but nice for editors
|
||||
watch_file npins/sources.json
|
||||
watch_file nix/sources.json
|
||||
|
||||
# Load .env file if it exists
|
||||
dotenv_if_exists
|
||||
|
||||
# Activate development shell
|
||||
if type -P lorri &>/dev/null; then
|
||||
eval "$(lorri direnv)"
|
||||
else
|
||||
echo 'while direnv evaluated .envrc, could not find the command "lorri" [https://github.com/nix-community/lorri]'
|
||||
use nix
|
||||
fi
|
||||
use nix
|
||||
|
||||
# Load agenix-gen shell hook
|
||||
use nix -A passthru.agenix-gen
|
||||
unset TMP TMPDIR TEMP TEMPDIR # hacky workaround for direnv bug
|
||||
# HACK: Workaround for direnv bug
|
||||
unset TMP TMPDIR TEMP TEMPDIR
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -5,6 +5,7 @@
|
||||
.idea/
|
||||
.ionide/
|
||||
.certs/
|
||||
.config/
|
||||
obj/
|
||||
bin/
|
||||
node_modules/
|
||||
@@ -12,6 +13,7 @@ release.cmd
|
||||
release.sh
|
||||
*.orig
|
||||
*.DotSettings.user
|
||||
.pre-commit-config.yaml
|
||||
deploy/
|
||||
dist/
|
||||
build/
|
||||
@@ -28,7 +30,6 @@ _*.yaml
|
||||
tilt/base/_manifest.yaml
|
||||
NuGet.Config
|
||||
sync.list
|
||||
packages.lock.json
|
||||
package-lock.json
|
||||
*.nupkg
|
||||
*.fable-temp*
|
||||
.env
|
||||
@@ -1,29 +1,51 @@
|
||||
# yaml-language-server: $schema=https://gitlab.com/gitlab-org/gitlab/-/raw/master/app/assets/javascripts/editor/schema/ci.json
|
||||
variables:
|
||||
SDK_VERSION: 9.0
|
||||
SKIP_TESTS: "true"
|
||||
SKIP_TESTS: "true"
|
||||
|
||||
default:
|
||||
tags:
|
||||
- nix
|
||||
|
||||
include:
|
||||
- project: oceanbox/gitlab-ci
|
||||
ref: v4.2
|
||||
file: template/Base.gitlab-ci.yml
|
||||
- local: '/src/Atlantis/.gitlab-ci.yml'
|
||||
rules:
|
||||
- changes:
|
||||
- 'src/Atlantis/**/*'
|
||||
- local: '/src/Sorcerer/.gitlab-ci.yml'
|
||||
rules:
|
||||
- changes:
|
||||
- 'src/Sorcerer/**/*'
|
||||
- local: '/src/Interfaces/.gitlab-ci.yml'
|
||||
rules:
|
||||
- changes:
|
||||
- 'src/Interfaces/**/*'
|
||||
- local: '/src/DataAgent/.gitlab-ci.yml'
|
||||
rules:
|
||||
- changes:
|
||||
- 'src/DataAgent/**/*'
|
||||
- local: '/src/ServerPack/.gitlab-ci.yml'
|
||||
rules:
|
||||
- changes:
|
||||
- 'src/ServerPack/**/*'
|
||||
- project: oceanbox/gitlab-ci
|
||||
ref: v4.5
|
||||
file: template/Base.gitlab-ci.yml
|
||||
- local: "/src/Atlantis/.gitlab-ci.yml"
|
||||
rules:
|
||||
- changes:
|
||||
- "src/Atlantis/**/*"
|
||||
- "nix/packages/atlantis.nix"
|
||||
- "nix/packages/atlantis-client.nix"
|
||||
- "nix/containers.nix"
|
||||
- local: "/src/Sorcerer/.gitlab-ci.yml"
|
||||
rules:
|
||||
- changes:
|
||||
- "src/Sorcerer/**/*"
|
||||
- "nix/packages/sorcerer.nix"
|
||||
- "nix/containers.nix"
|
||||
- local: "/src/Archivist/.gitlab-ci.yml"
|
||||
rules:
|
||||
- changes:
|
||||
- "src/Archivist/**/*"
|
||||
- "nix/packages/archivist.nix"
|
||||
- local: "/src/Interfaces/.gitlab-ci.yml"
|
||||
rules:
|
||||
- changes:
|
||||
- "src/Interfaces/**/*"
|
||||
- "nix/packages/api.nix"
|
||||
- local: "/src/DataAgent/.gitlab-ci.yml"
|
||||
rules:
|
||||
- changes:
|
||||
- "src/DataAgent/**/*"
|
||||
- "nix/packages/dataagent.nix"
|
||||
- local: "/src/ServerPack/.gitlab-ci.yml"
|
||||
rules:
|
||||
- changes:
|
||||
- "src/ServerPack/**/*"
|
||||
- "nix/packages/serverpack.nix"
|
||||
- local: "/src/Codex/.gitlab-ci.yml"
|
||||
rules:
|
||||
- changes:
|
||||
- "src/Codex/**/*"
|
||||
- "nix/packages/node-modules.nix"
|
||||
- "nix/packages/sources.nix"
|
||||
|
||||
@@ -15,7 +15,7 @@ plugins:
|
||||
- "src/Atlantis/src/**.fsproj"
|
||||
- "src/Sorcerer/src/**.fsproj"
|
||||
- "src/DataAgent/src/**.fsproj"
|
||||
- "src/ServerPack/src/*.fsproj"
|
||||
- "src/ServerPack/src/**.fsproj"
|
||||
- "src/Interfaces/**.fsproj"
|
||||
- - '@semantic-release/exec'
|
||||
- generateNotesCmd: "echo ${nextRelease.version} > VERSION"
|
||||
@@ -29,7 +29,7 @@ plugins:
|
||||
- "src/Atlantis/src/**.fsproj"
|
||||
- "src/Sorcerer/src/**.fsproj"
|
||||
- "src/DataAgent/src/**.fsproj"
|
||||
- "src/ServerPack/src/*.fsproj"
|
||||
- "src/ServerPack/src/**.fsproj"
|
||||
- "src/Interfaces/**.fsproj"
|
||||
|
||||
analyzeCommits:
|
||||
|
||||
17
Build.fsproj
17
Build.fsproj
@@ -1,17 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include=".build/Helpers.fs" />
|
||||
<Compile Include=".build/Build.fs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Fake.Core.Target" Version="6.1.3" />
|
||||
<PackageReference Include="Fake.DotNet.Cli" Version="6.1.3" />
|
||||
<PackageReference Include="Fake.IO.FileSystem" Version="6.1.3" />
|
||||
<PackageReference Include="Farmer" Version="1.9.6" />
|
||||
<PackageReference Update="FSharp.Core" Version="9.0.100" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
35
Directory.Build.props
Normal file
35
Directory.Build.props
Normal file
@@ -0,0 +1,35 @@
|
||||
<Project>
|
||||
<!-- Make F# support Central Package Management -->
|
||||
<PropertyGroup>
|
||||
<DisableImplicitSystemValueTupleReference>true</DisableImplicitSystemValueTupleReference>
|
||||
<DisableImplicitFSharpCoreReference>true</DisableImplicitFSharpCoreReference>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<!-- <DebugType Condition=" '$(DebugType)' == '' ">embedded</DebugType> -->
|
||||
<!-- <DebugType>embedded</DebugType> -->
|
||||
<!-- <Deterministic>true</Deterministic> -->
|
||||
<!-- <NetCoreTargetingPackRoot>[UNDEFINED]</NetCoreTargetingPackRoot> -->
|
||||
|
||||
<!-- Warnings and Errors -->
|
||||
<!--
|
||||
FS0025: Incomplete pattern matches on this expression.
|
||||
FS1182: Unused variables
|
||||
FS1178: Does not support structural equality
|
||||
FS3390: Malformed XML doc comment
|
||||
-->
|
||||
<!-- <WarnOn>FS3388,FS3559</WarnOn> -->
|
||||
<!-- <WarnOn>1182;3390;1178;$(WarnOn)</WarnOn> -->
|
||||
<!-- <TreatWarningsAsErrors>true</TreatWarningsAsErrors> -->
|
||||
<WarningsAsErrors>FS0025</WarningsAsErrors>
|
||||
<NoWarn>NU1603;MSB3277</NoWarn>
|
||||
|
||||
<!-- Restore with Lockfiles -->
|
||||
<!-- https://www.gresearch.co.uk/blog/article/improve-nuget-restores-with-static-graph-evaluation/ -->
|
||||
<RestoreUseStaticGraphEvaluation>true</RestoreUseStaticGraphEvaluation>
|
||||
<DisableImplicitNuGetFallbackFolder>true</DisableImplicitNuGetFallbackFolder>
|
||||
|
||||
<!-- Performance -->
|
||||
<ServerGarbageCollection>true</ServerGarbageCollection>
|
||||
<OtherFlags>$(OtherFlags) --test:GraphBasedChecking --test:ParallelOptimization --test:ParallelIlxGen</OtherFlags>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
109
Directory.Packages.props
Normal file
109
Directory.Packages.props
Normal file
@@ -0,0 +1,109 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- Common -->
|
||||
<PackageVersion Include="FSharp.Core" Version="9.0.303" />
|
||||
<PackageVersion Include="Fargo.CmdLine" Version="1.7.5" />
|
||||
<PackageVersion Include="FSharpPlus" Version="1.7.0" />
|
||||
<PackageVersion Include="FSharp.Data" Version="6.4.1" />
|
||||
<PackageVersion Include="FsToolkit.ErrorHandling" Version="5.0.1" />
|
||||
<PackageVersion Include="Thoth.Json.Giraffe" Version="6.0.0" />
|
||||
<PackageVersion Include="Thoth.Json.Net" Version="12.0.0" />
|
||||
<PackageVersion Include="Serilog" Version="4.2.0" />
|
||||
<PackageVersion Include="Serilog.Sinks.Console" Version="6.0.0"/>
|
||||
<PackageVersion Include="Drifters.Api" Version="6.22.0" />
|
||||
<!-- Client -->
|
||||
<PackageVersion Include="Fable.Browser.IndexedDB" Version="2.2.0" />
|
||||
<PackageVersion Include="Fable.Browser.ResizeObserver" Version="1.0.0" />
|
||||
<PackageVersion Include="Fable.Browser.WebGL" Version="1.3.0" />
|
||||
<PackageVersion Include="Fable.Core" Version="4.4.0"/>
|
||||
<PackageVersion Include="Fable.Elmish" Version="4.2.0" />
|
||||
<PackageVersion Include="Fable.Fetch" Version="2.7.0" />
|
||||
<PackageVersion Include="Fable.FontAwesome.Free" Version="3.0.0"/>
|
||||
<PackageVersion Include="Fable.Lit.Elmish" Version="1.6.2-oceanbox" />
|
||||
<PackageVersion Include="Fable.Lit.React" Version="1.6.2-oceanbox" />
|
||||
<PackageVersion Include="Fable.Lit" Version="1.6.2-oceanbox" />
|
||||
<PackageVersion Include="Fable.OpenLayers" Version="2.19.0" />
|
||||
<PackageVersion Include="Fable.Promise" Version="3.2.0" />
|
||||
<PackageVersion Include="Fable.React" Version="9.4.0" />
|
||||
<PackageVersion Include="Fable.Remoting.Client" Version="7.32.0" />
|
||||
<PackageVersion Include="Fable.Remoting.MsgPack" Version="1.24.0" />
|
||||
<PackageVersion Include="Fable.SignalR.Elmish" Version="2.1.0" />
|
||||
<PackageVersion Include="Fable.SimpleHttp" Version="3.6.0" />
|
||||
<PackageVersion Include="Feliz.Router" Version="4.0.0"/>
|
||||
<PackageVersion Include="Feliz" Version="2.9.0" />
|
||||
<PackageVersion Include="Feliz.UseElmish" Version="2.5.0" />
|
||||
<PackageVersion Include="Feliz.CompilerPlugins" Version="2.2.0" />
|
||||
<PackageVersion Include="Matplotlib.ColorMaps" Version="3.0.1" />
|
||||
<PackageVersion Include="Thoth.Fetch" Version="3.0.1" />
|
||||
<PackageVersion Include="Thoth.Json" Version="10.4.1"/>
|
||||
<PackageVersion Include="FS.FluentUI" Version="3.0.0"/>
|
||||
<!-- Serverpack -->
|
||||
<PackageVersion Include="OpenFga.Sdk" Version="0.7.0"/>
|
||||
<PackageVersion Include="FSharp.SystemTextJson" Version="1.3.13"/>
|
||||
<PackageVersion Include="Saturn.OpenTelemetry" Version="0.6.0-alpha"/>
|
||||
<!-- Atlantis -->
|
||||
<PackageVersion Include="Argu" Version="6.2.5" />
|
||||
<PackageVersion Include="AspNetCore.Serilog.RequestLoggingMiddleware" Version="1.0.2" />
|
||||
<PackageVersion Include="Azure.Extensions.AspNetCore.DataProtection.Blobs" Version="1.5.0" />
|
||||
<PackageVersion Include="Azure.Extensions.AspNetCore.DataProtection.Keys" Version="1.4.0" />
|
||||
<PackageVersion Include="Azure.Identity" Version="1.13.2" />
|
||||
<PackageVersion Include="Azure.Security.KeyVault.Secrets" Version="4.7.0" />
|
||||
<PackageVersion Include="Dapr.Actors" Version="1.16.0" />
|
||||
<PackageVersion Include="Dapr.Actors.AspNetCore" Version="1.16.0" />
|
||||
<PackageVersion Include="Dapr.AspNetCore" Version="1.16.0" />
|
||||
<PackageVersion Include="Dapr.Client" Version="1.16.0" />
|
||||
<PackageVersion Include="Fable.Remoting.DotnetClient" Version="3.35.0" />
|
||||
<PackageVersion Include="Fable.Remoting.Giraffe" Version="5.21.0" />
|
||||
<PackageVersion Include="Fable.Remoting.Server" Version="5.39.0" />
|
||||
<PackageVersion Include="Fable.SignalR.Saturn" Version="2.1.0" />
|
||||
<PackageVersion Include="Giraffe" Version="7.0.2" />
|
||||
<PackageVersion Include="IdentityModel.AspNetCore" Version="4.3.0" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.2" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="9.0.2" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="9.0.2" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Http.Polly" Version="9.0.2" />
|
||||
<PackageVersion Include="Oceanbox.FvcomKit" Version="5.13.0" />
|
||||
<PackageVersion Include="prometheus-net.AspNetCore" Version="8.2.1" />
|
||||
<PackageVersion Include="Saturn" Version="0.17.0" />
|
||||
<PackageVersion Include="SecurityCodeScan" Version="3.5.4">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageVersion>
|
||||
<PackageVersion Include="Sentry.AspNetCore" Version="5.11.0" />
|
||||
<PackageVersion Include="Serilog.AspNetCore" Version="9.0.0" />
|
||||
<PackageVersion Include="Serilog.Enrichers.CorrelationId" Version="3.0.1" />
|
||||
<PackageVersion Include="Serilog.Expressions" Version="5.0.0" />
|
||||
<PackageVersion Include="Serilog.Sinks.OpenTelemetry" Version="4.1.1" />
|
||||
<PackageVersion Include="System.Text.Encodings.Web" Version="9.0.2" />
|
||||
<!-- Sorcerer -->
|
||||
<PackageVersion Include="MessagePack" Version="3.1.3" />
|
||||
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageVersion Include="ProjNet.FSharp" Version="5.2.0" />
|
||||
<!-- Dapperizer -->
|
||||
<PackageVersion Include="Oceanbox.SDSLite" Version="2.8.0" />
|
||||
<PackageVersion Include="Dapper.FSharp" Version="4.9.0"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="9.0.2"/>
|
||||
<PackageVersion Include="NetTopologySuite" Version="2.5.0"/>
|
||||
<PackageVersion Include="Npgsql" Version="9.0.2" />
|
||||
<PackageVersion Include="Npgsql.NetTopologySuite" Version="9.0.2"/>
|
||||
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.2"/>
|
||||
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite" Version="9.0.2"/>
|
||||
<!-- Entity -->
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.1">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageVersion>
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.1">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageVersion>
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.1" />
|
||||
<!-- Analyzers -->
|
||||
<PackageVersion Include="G-Research.FSharp.Analyzers" Version="0.19.0" />
|
||||
<PackageVersion Include="Ionide.Analyzers" Version="0.14.9" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
21
LICENSE
21
LICENSE
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Serit Tromsø AS
|
||||
|
||||
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.
|
||||
@@ -24,6 +24,10 @@
|
||||
<Project Path="src/Atlantis/src/Server/Petimeter/Petimeter.fsproj" />
|
||||
<Project Path="src/Atlantis/src/Server/Server.fsproj" />
|
||||
</Folder>
|
||||
<Folder Name="/Codex/">
|
||||
<Project Path="src\Codex\src\Client\Codex.Client.fsproj" />
|
||||
<Project Path="src\Codex\src\Server\Codex.Server.fsproj" />
|
||||
</Folder>
|
||||
<Folder Name="/DataAgent/">
|
||||
<Project Path="src/DataAgent/src/Entity/Entity.csproj" />
|
||||
</Folder>
|
||||
@@ -31,6 +35,7 @@
|
||||
<Project Path="src/DataAgent/src/DataAgent/Oceanbox.DataAgent.fsproj" />
|
||||
</Folder>
|
||||
<Folder Name="/Interfaces/">
|
||||
<Project Path="src/Interfaces/Api/Poseidon.Api.fsproj" />
|
||||
<Project Path="src/Interfaces/Archmaester/Archmaester.Api.fsproj" />
|
||||
<Project Path="src/Interfaces/Atlantis/Atlantis.Api.fsproj" />
|
||||
<Project Path="src/Interfaces/Hipster/Hipster.Api.fsproj" />
|
||||
@@ -46,7 +51,6 @@
|
||||
<File Path="global.json" />
|
||||
</Folder>
|
||||
<Folder Name="/Sorcerer/">
|
||||
<Project Path="src/Sorcerer/src/Client/Client.fsproj" />
|
||||
<Project Path="src/Sorcerer/src/Server/Sorcerer.fsproj" />
|
||||
</Folder>
|
||||
</Solution>
|
||||
91
README.md
91
README.md
@@ -12,9 +12,10 @@ Oceanbox's comprehensive platform for oceanic data visualization, analysis, and
|
||||
## Bootstrapping Guide
|
||||
|
||||
To bootstrap Atlantis for development, build and run it using Tilt.
|
||||
|
||||
Some setup is required:
|
||||
|
||||
### k8s access
|
||||
### Kubernetes Access
|
||||
|
||||
To run our application on the kubernetes cluster, Tilt needs access.
|
||||
You need to authenticate with `oidc`, using your microsoft account.
|
||||
@@ -45,21 +46,21 @@ Next, configure the required contexts to use `oidc` (also in your `~/.kube/confi
|
||||
```yaml
|
||||
---
|
||||
- context:
|
||||
cluster: ekman
|
||||
namespace: sorcerer
|
||||
user: oidc
|
||||
cluster: ekman
|
||||
namespace: sorcerer
|
||||
user: oidc
|
||||
name: ekman
|
||||
- context:
|
||||
cluster: oceanbox
|
||||
user: oidc
|
||||
cluster: oceanbox
|
||||
namespace: atlantis
|
||||
user: oidc
|
||||
name: oceanbox
|
||||
---
|
||||
```
|
||||
|
||||
Finally, **you must be granted the necessary priveleges in Entra to access the clusters.**
|
||||
Verify that you have access with `kubectl`:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
kubectl --context oceanbox -n default get pods
|
||||
```
|
||||
|
||||
@@ -68,26 +69,7 @@ kubectl --context oceanbox -n default get pods
|
||||
Required helm manifests are hosted in a separate repository: <https://gitlab.com/oceanbox/manifests>.
|
||||
Clone it into a directory _in the same parent directory as this repository._
|
||||
|
||||
The Bitnami respository must also be added to helm:
|
||||
|
||||
```sh
|
||||
helm repo add bitnami https://charts.bitnami.com/bitnami
|
||||
```
|
||||
|
||||
### DNS
|
||||
|
||||
Some DNS masking is required.
|
||||
Add the following to your NixOS configuration:
|
||||
|
||||
```nix
|
||||
services.dnsmasq = {
|
||||
enable = true;
|
||||
settings.address = [
|
||||
"/.local/127.0.0.1"
|
||||
"/.local.oceanbox.io/127.0.0.1"
|
||||
];
|
||||
};
|
||||
```
|
||||
You'll have to run `helm dependency update` in the atlantis directory within the manifest repo to download the charts.
|
||||
|
||||
### NuGet
|
||||
|
||||
@@ -102,28 +84,45 @@ To retrieve packages from the private Oceanbox nuget registry, configure it with
|
||||
</packageSources>
|
||||
<packageSourceCredentials>
|
||||
<oceanbox>
|
||||
<add key="Username" value="oceanbox-nuget" />
|
||||
<add key="ClearTextPassword" value="<...>" />
|
||||
<add key="Username" value="<Your-GitLab-Username>" />
|
||||
<add key="ClearTextPassword" value="<Your-GitLab-PAT>" />
|
||||
</oceanbox>
|
||||
</packageSourceCredentials>
|
||||
<packageSourceMapping>
|
||||
<packageSource key="nuget.org">
|
||||
<package pattern="*" />
|
||||
</packageSource>
|
||||
<packageSource key="oceanbox">
|
||||
<package pattern="Oceanbox.*" />
|
||||
<package pattern="ProjNet.FSharp" />
|
||||
<package pattern="Drifters.Api" />
|
||||
<package pattern="Fable.Lit" />
|
||||
<package pattern="Fable.Lit.*" />
|
||||
<package pattern="Fable.SignalR" />
|
||||
<package pattern="Fable.SignalR.*" />
|
||||
<package pattern="Fable.OpenLayers" />
|
||||
<package pattern="Matplotlib.*" />
|
||||
</packageSource>
|
||||
</packageSourceMapping>
|
||||
</configuration>
|
||||
```
|
||||
|
||||
Substitute `<...>` for the corresponding secret.
|
||||
Substitute with your own gitlab username and PAT in the credentials.
|
||||
|
||||
Now, we should be able to `restore`:
|
||||
|
||||
```sh
|
||||
dotnet tool restore
|
||||
```shell
|
||||
dotnet restore Poseidon.slnx
|
||||
```
|
||||
|
||||
for `dotnet-tools` we use nix, so entering the shell using `nix-shell` or `direnv` is enough.
|
||||
|
||||
### Mkcert
|
||||
|
||||
To generate certificates correctly, vite needs the `mkcert` binary in a predefined path in our home directory.
|
||||
`mkcert` is included in our dev shell, so we can create a symlink to its location in the nix store:
|
||||
|
||||
```sh
|
||||
```fish
|
||||
which mkcert | xargs -I{} ln -s {} ~/.vite-plugin-mkcert
|
||||
```
|
||||
|
||||
@@ -132,12 +131,16 @@ which mkcert | xargs -I{} ln -s {} ~/.vite-plugin-mkcert
|
||||
### Docker Login
|
||||
|
||||
In order for Tilt to push the images it builds to the oceanbox registry, we must use `docker login` to authenticate with it.
|
||||
First, create a personal access token in your gitlab account.
|
||||
It should have the `read_registry` and `write_registry` scopes set.
|
||||
First, create a personal access token in your gitlab account. It should have the `read_registry` and `write_registry` scopes set.
|
||||
|
||||
```fish
|
||||
set -x TOKEN glpat-xxxx
|
||||
```
|
||||
|
||||
Then, supply it to `docker login`:
|
||||
|
||||
```sh
|
||||
docker login registry.gitlab.com/oceanbox
|
||||
```shell
|
||||
echo "$TOKEN" | docker login gitlab.com -u <user> --password-stdin
|
||||
```
|
||||
|
||||
When prompted, authenticate with your gitlab username and the PAT you just created.
|
||||
@@ -146,7 +149,7 @@ When prompted, authenticate with your gitlab username and the PAT you just creat
|
||||
|
||||
A namespace must be created for your tilt application to live in on the cluster.
|
||||
|
||||
```sh
|
||||
```shell
|
||||
kubectl create ns "$APP_NAMESPACE" --context oceanbox
|
||||
```
|
||||
|
||||
@@ -154,7 +157,7 @@ kubectl create ns "$APP_NAMESPACE" --context oceanbox
|
||||
|
||||
In the project root, run tilt with the following command:
|
||||
|
||||
```sh
|
||||
```shell
|
||||
tilt up --context oceanbox
|
||||
```
|
||||
|
||||
@@ -162,6 +165,9 @@ You should now be able to access the Atlantis client (with HMR) on <atlantis.loc
|
||||
|
||||
### Trust Root Certificate
|
||||
|
||||
> [!note]
|
||||
> You'll need to run `just run-client` in `src/Atlantis` to generate the certificates in `~/.vite-plugin-mkcert/certs`
|
||||
|
||||
In order for your browser to allow you to access the web application, you must add the root certificate generated by `mkcert` to the list of trusted authorities in your browser:
|
||||
|
||||
1. In firefox, navigate to settings and search for _"Certificates"._
|
||||
@@ -171,8 +177,9 @@ In order for your browser to allow you to access the web application, you must a
|
||||
|
||||
### Add `user` to OpenFGA
|
||||
|
||||
Ask [sales](moritz.jorg@oceanbox.io) to add your `azure-ad-user` to OpenFGA.
|
||||
Ask [sales](support@oceanbox.io) to add your `azure-ad-user` to OpenFGA.
|
||||
|
||||
### CORS for Sorcerer
|
||||
|
||||
Add the `url` of your instance to the CORS list of Sorcerer [here](https://gitlab.com/oceanbox/manifests/-/blob/main/values/sorcerer/kustomize/prod/appsettings.json?ref_type=heads#L52).
|
||||
Add the `url` of your instance to the CORS list of Sorcerer
|
||||
[here](https://gitlab.com/oceanbox/manifests/-/blob/main/values/sorcerer/kustomize/prod/appsettings.json?ref_type=heads#L52).
|
||||
800
RELEASE_NOTES.md
800
RELEASE_NOTES.md
@@ -1,5 +1,805 @@
|
||||
# Changelog
|
||||
|
||||
## [1.40.5](https://gitlab.com/oceanbox/Poseidon/compare/v1.40.4...v1.40.5) (2026-01-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **xtractor:** Reduce to 4 cores per task ([8e824d4](https://gitlab.com/oceanbox/Poseidon/commit/8e824d4afa0b03f59e006d3a0d50fb216e71483e))
|
||||
|
||||
## [1.40.4](https://gitlab.com/oceanbox/Poseidon/compare/v1.40.3...v1.40.4) (2026-01-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **xtractor:** Reduce core requirement to 8 ([efacb2a](https://gitlab.com/oceanbox/Poseidon/commit/efacb2a3322de0ced45db4eec240846f4e371a75))
|
||||
|
||||
## [1.40.3](https://gitlab.com/oceanbox/Poseidon/compare/v1.40.2...v1.40.3) (2026-01-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **inbox|xtracto:** Delete/Read msg and allow non-ascii xtractor names ([d8d5e07](https://gitlab.com/oceanbox/Poseidon/commit/d8d5e076baf8b559200f2da91237f9874678b216))
|
||||
* **multiauth:** Add clientId to redirect on signout ([54c40d7](https://gitlab.com/oceanbox/Poseidon/commit/54c40d7accc4bbc43f66dda0df647ccac482a2b0))
|
||||
|
||||
## [1.40.2](https://gitlab.com/oceanbox/Poseidon/compare/v1.40.1...v1.40.2) (2026-01-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **xtract:** Disabled if not allowed to simulate transport ([e429a85](https://gitlab.com/oceanbox/Poseidon/commit/e429a855e5bd00493e2f99647092aebce9c99a2a))
|
||||
|
||||
## [1.40.1](https://gitlab.com/oceanbox/Poseidon/compare/v1.40.0...v1.40.1) (2026-01-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fix tilt build on net10 ([d5cde19](https://gitlab.com/oceanbox/Poseidon/commit/d5cde19250847f7b091cfa5f65eb703405c202b6))
|
||||
|
||||
# [1.40.0](https://gitlab.com/oceanbox/Poseidon/compare/v1.39.2...v1.40.0) (2026-01-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Codex:** expose days instead of frames in arcive form ([6cf5262](https://gitlab.com/oceanbox/Poseidon/commit/6cf5262dd5c98517a3c767f410c858fe32c07bd5))
|
||||
* **Codex:** only allow inbounds time intervals on edit archive ([eaea4b2](https://gitlab.com/oceanbox/Poseidon/commit/eaea4b2e215669cec19f2a8cec122ba670a7a202))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Codex:** edit archives ([ec10932](https://gitlab.com/oceanbox/Poseidon/commit/ec109328fbf5f237a52ef77cbd44dff571deee5f))
|
||||
|
||||
## [1.39.2](https://gitlab.com/oceanbox/Poseidon/compare/v1.39.1...v1.39.2) (2026-01-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fix net10 issues ([f4943a1](https://gitlab.com/oceanbox/Poseidon/commit/f4943a148b72fb7e10a745cc3e806b9c4bdd76d8))
|
||||
|
||||
## [1.39.1](https://gitlab.com/oceanbox/Poseidon/compare/v1.39.0...v1.39.1) (2026-01-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **ci:** Remove schedule check ([ab37e88](https://gitlab.com/oceanbox/Poseidon/commit/ab37e88bb0f669a7aa94bf831f95f8c60dc28804))
|
||||
|
||||
# [1.39.0](https://gitlab.com/oceanbox/Poseidon/compare/v1.38.5...v1.39.0) (2026-01-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Codex:** add * user in archmeister on public archives ([cd678a4](https://gitlab.com/oceanbox/Poseidon/commit/cd678a41f64a64c6f3616f32bafeaae6715c08a4))
|
||||
* **Codex:** use feliz router guid matching ([7182f7c](https://gitlab.com/oceanbox/Poseidon/commit/7182f7c9f094d65c884e8e02d4aaa89561ca5e82))
|
||||
* **Codex:** utc start_time ([492651e](https://gitlab.com/oceanbox/Poseidon/commit/492651e0f34035d8c61174aa50336222bcfd979c))
|
||||
* **DataAgent:** use files from parent attribs instead of archive_files ([eac23e7](https://gitlab.com/oceanbox/Poseidon/commit/eac23e7d1a541f2e90374a2add689846d9e7b642))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Codex:** ability to add FVCOM archives ([d86db7a](https://gitlab.com/oceanbox/Poseidon/commit/d86db7a66ca5ecb6a9ad45ce3d47be3a98d56bb8))
|
||||
|
||||
## [1.38.5](https://gitlab.com/oceanbox/Poseidon/compare/v1.38.4...v1.38.5) (2026-01-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Archmaester:** Rollback add archive if openfga fails ([46e86eb](https://gitlab.com/oceanbox/Poseidon/commit/46e86eb5f961a45fba2da1525c1472bdca79ab47))
|
||||
|
||||
## [1.38.4](https://gitlab.com/oceanbox/Poseidon/compare/v1.38.3...v1.38.4) (2026-01-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **nix:** Bump node deps ([e513d87](https://gitlab.com/oceanbox/Poseidon/commit/e513d87d249843423f0e0a62275afe45e6c73a46))
|
||||
|
||||
## [1.38.3](https://gitlab.com/oceanbox/Poseidon/compare/v1.38.2...v1.38.3) (2026-01-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **xtractor:** Set maxEndDate to 1 year and format ([5315a05](https://gitlab.com/oceanbox/Poseidon/commit/5315a05fa255c6164d3ef73c0f5e20cdb4c632d0))
|
||||
|
||||
## [1.38.2](https://gitlab.com/oceanbox/Poseidon/compare/v1.38.1...v1.38.2) (2026-01-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **atlas:** Disable Snowflakes ([4cd3673](https://gitlab.com/oceanbox/Poseidon/commit/4cd3673d15783afa72ca3358e6bd8c3a8cfbfd16))
|
||||
|
||||
## [1.38.1](https://gitlab.com/oceanbox/Poseidon/compare/v1.38.0...v1.38.1) (2026-01-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **xtractor:** Move to short partition and 16 CPU, also set max duration to 1 year ([56d3476](https://gitlab.com/oceanbox/Poseidon/commit/56d34767d7a2e0bc6aadaa5987344c6e7a58698a))
|
||||
|
||||
# [1.38.0](https://gitlab.com/oceanbox/Poseidon/compare/v1.37.1...v1.38.0) (2026-01-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* client layout ([efb3292](https://gitlab.com/oceanbox/Poseidon/commit/efb3292d9f4a8fccf2cebbdd75b3d3ffc186fa11))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add fluent ui to codex ([d8bf174](https://gitlab.com/oceanbox/Poseidon/commit/d8bf174d3aa181169365c178b4335052e13eabc5))
|
||||
|
||||
## [1.37.1](https://gitlab.com/oceanbox/Poseidon/compare/v1.37.0...v1.37.1) (2026-01-05)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **xtractor:** Avoid using union types in Dapr Actors ([14c1a57](https://gitlab.com/oceanbox/Poseidon/commit/14c1a57331f981b1e1e0793426448ea261002e6d))
|
||||
|
||||
# [1.37.0](https://gitlab.com/oceanbox/Poseidon/compare/v1.36.0...v1.37.0) (2025-12-22)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add XtractActor ([a8a187a](https://gitlab.com/oceanbox/Poseidon/commit/a8a187a412c13d3e9d21cbbcfc2e1813c0e38dfe))
|
||||
|
||||
# [1.36.0](https://gitlab.com/oceanbox/Poseidon/compare/v1.35.2...v1.36.0) (2025-12-12)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add Saturn.ReverseProxy middleware ([bd74504](https://gitlab.com/oceanbox/Poseidon/commit/bd745042dfa51fbbef7bf7b55d31b8b57e6ad0a4))
|
||||
|
||||
## [1.35.2](https://gitlab.com/oceanbox/Poseidon/compare/v1.35.1...v1.35.2) (2025-12-01)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **drifters:** reverse toggle on postdrift analysis ([563faa6](https://gitlab.com/oceanbox/Poseidon/commit/563faa6c0bd20a7d3f184bba66ae5df340e7ef4e))
|
||||
|
||||
## [1.35.1](https://gitlab.com/oceanbox/Poseidon/compare/v1.35.0...v1.35.1) (2025-12-01)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **stats:** no stats banner showing when stats are available, closing [#87](https://gitlab.com/oceanbox/Poseidon/issues/87) ([e75ffc4](https://gitlab.com/oceanbox/Poseidon/commit/e75ffc41e5d298e2ecf92c5c4d11e0f930f633ab))
|
||||
* **stats:** set priority order of depth plots, closing [#88](https://gitlab.com/oceanbox/Poseidon/issues/88) ([2887e6a](https://gitlab.com/oceanbox/Poseidon/commit/2887e6a90951f4aaa088ad14b3d2bbcb6fd25b93))
|
||||
|
||||
# [1.35.0](https://gitlab.com/oceanbox/Poseidon/compare/v1.34.2...v1.35.0) (2025-12-01)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* ❄️ ([a620c26](https://gitlab.com/oceanbox/Poseidon/commit/a620c26812d3ec7517c34e7931e03b411f725907))
|
||||
|
||||
## [1.34.2](https://gitlab.com/oceanbox/Poseidon/compare/v1.34.1...v1.34.2) (2025-11-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Temporarily use vtn as only source for wind barbs ([048e803](https://gitlab.com/oceanbox/Poseidon/commit/048e80356b59cfcd408bf6784bbc2e22aebe25c6))
|
||||
|
||||
## [1.34.1](https://gitlab.com/oceanbox/Poseidon/compare/v1.34.0...v1.34.1) (2025-11-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **stats:** find available stats archives ([48d46ed](https://gitlab.com/oceanbox/Poseidon/commit/48d46eda62160d3efe1423238a25f26a439c6b88))
|
||||
|
||||
# [1.34.0](https://gitlab.com/oceanbox/Poseidon/compare/v1.33.11...v1.34.0) (2025-11-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* extract data cage interaction matrix, closing [#84](https://gitlab.com/oceanbox/Poseidon/issues/84) ([afc888a](https://gitlab.com/oceanbox/Poseidon/commit/afc888ab604f4759e3787e3feab568a322109b34))
|
||||
* reintroduce active layer selector, closes [#74](https://gitlab.com/oceanbox/Poseidon/issues/74) ([c1fa85f](https://gitlab.com/oceanbox/Poseidon/commit/c1fa85fd1b955e810bd76973e5873a7ab4cb8f18))
|
||||
* remove parameter limitations on particle sims ([69b380e](https://gitlab.com/oceanbox/Poseidon/commit/69b380e6659521c9f9ab489fa75d1221cc9b7db2))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* fly-to coordinate button, closes [#85](https://gitlab.com/oceanbox/Poseidon/issues/85) ([a153238](https://gitlab.com/oceanbox/Poseidon/commit/a153238f79e2b2c87ac3553acce00bb17c1529f4))
|
||||
|
||||
## [1.33.11](https://gitlab.com/oceanbox/Poseidon/compare/v1.33.10...v1.33.11) (2025-11-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **ci:** Run archivist ci on coffee ([f68b7f6](https://gitlab.com/oceanbox/Poseidon/commit/f68b7f68c8fd95d5d593702632cc2e9a7b36007a))
|
||||
|
||||
## [1.33.10](https://gitlab.com/oceanbox/Poseidon/compare/v1.33.9...v1.33.10) (2025-11-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **ci:** Build on Coffee ([e04d36c](https://gitlab.com/oceanbox/Poseidon/commit/e04d36ca124693b471ac973cd4d0f39f42f0fec0))
|
||||
|
||||
## [1.33.9](https://gitlab.com/oceanbox/Poseidon/compare/v1.33.8...v1.33.9) (2025-11-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **nix:** Bump hash for node_modules ([fff7913](https://gitlab.com/oceanbox/Poseidon/commit/fff7913cd5280f0732bb23bc1cb6ed5282631b90))
|
||||
|
||||
## [1.33.8](https://gitlab.com/oceanbox/Poseidon/compare/v1.33.7...v1.33.8) (2025-11-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **ci:** Format .gitlab-ci.yml and move codex to nix runner ([3140c07](https://gitlab.com/oceanbox/Poseidon/commit/3140c07ad078d3b8b3082d2f86eaa73f4ba08969))
|
||||
* **ci:** Remove unsed var ([759bbc6](https://gitlab.com/oceanbox/Poseidon/commit/759bbc6f60e5b364dd83653193d1501ce86c9eef))
|
||||
* **ci:** Try using v4.4 ([c1be7c4](https://gitlab.com/oceanbox/Poseidon/commit/c1be7c468dd9a689eb0b1b61797841c398fadc02))
|
||||
* **ci:** Use 4.4 for check ([b109dbd](https://gitlab.com/oceanbox/Poseidon/commit/b109dbdcbdfa3315e099b2edf72eb10518732c8f))
|
||||
|
||||
## [1.33.7](https://gitlab.com/oceanbox/Poseidon/compare/v1.33.6...v1.33.7) (2025-11-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **ci:** Change name to codex ([6d04af6](https://gitlab.com/oceanbox/Poseidon/commit/6d04af6230b536c1cbadf9abd2b59cf13609b451))
|
||||
* **ci:** Correct tag for codex pipeline ([7cf5064](https://gitlab.com/oceanbox/Poseidon/commit/7cf50641f986ab81b030e678ff7db0de83acae98))
|
||||
* **ci:** Run Codex on Coffee ([dd398bd](https://gitlab.com/oceanbox/Poseidon/commit/dd398bd96b0d79c8585a3156edcd2158982744d9))
|
||||
|
||||
## [1.33.6](https://gitlab.com/oceanbox/Poseidon/compare/v1.33.5...v1.33.6) (2025-11-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **maps:** Make FluentUI DatePicker popup inline; closes [#83](https://gitlab.com/oceanbox/Poseidon/issues/83) ([e3a1f56](https://gitlab.com/oceanbox/Poseidon/commit/e3a1f56b87c20ad9aada6108c92854b9d12671df))
|
||||
|
||||
## [1.33.5](https://gitlab.com/oceanbox/Poseidon/compare/v1.33.4...v1.33.5) (2025-11-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* General fixes "stats" menu ([c3c9e8e](https://gitlab.com/oceanbox/Poseidon/commit/c3c9e8e4e2b473564d1f6434a28dd934457189e9)), closes [#79](https://gitlab.com/oceanbox/Poseidon/issues/79) [#80](https://gitlab.com/oceanbox/Poseidon/issues/80) [#81](https://gitlab.com/oceanbox/Poseidon/issues/81) [#82](https://gitlab.com/oceanbox/Poseidon/issues/82)
|
||||
* no more DateFlicker (thanks Simen) ([7584bf6](https://gitlab.com/oceanbox/Poseidon/commit/7584bf661f2fd1cbf95e473a3334efcd69c77392))
|
||||
* remove goto today in date picker ([f23b3f1](https://gitlab.com/oceanbox/Poseidon/commit/f23b3f18213682e0b41c1db13b72e3c0bb0534b6))
|
||||
* **stats:** alert banner on missing stats ([5bb2ffd](https://gitlab.com/oceanbox/Poseidon/commit/5bb2ffd67c16078854b9f86a6728958c3923626c))
|
||||
|
||||
## [1.33.4](https://gitlab.com/oceanbox/Poseidon/compare/v1.33.3...v1.33.4) (2025-11-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **js:** Remove unused packages ([10a8c42](https://gitlab.com/oceanbox/Poseidon/commit/10a8c42319bbceebbf413d330fc72071f428e2dd))
|
||||
|
||||
## [1.33.3](https://gitlab.com/oceanbox/Poseidon/compare/v1.33.2...v1.33.3) (2025-11-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **nix:** Pre-commit with prek ([3093757](https://gitlab.com/oceanbox/Poseidon/commit/309375745443add8347ad6fca7b2dfe86ed1b7a7))
|
||||
* **nix:** Watch correct lock file ([79c6e2a](https://gitlab.com/oceanbox/Poseidon/commit/79c6e2abd0e26d220c10e532dffe53511f5dea0a))
|
||||
|
||||
## [1.33.2](https://gitlab.com/oceanbox/Poseidon/compare/v1.33.1...v1.33.2) (2025-11-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* create input display modal on demand ([1fed7ad](https://gitlab.com/oceanbox/Poseidon/commit/1fed7adf8009282184cacb4ddabf91274ee22b60))
|
||||
* **drifters:** Add datepickers for drifters sims ([785d0d5](https://gitlab.com/oceanbox/Poseidon/commit/785d0d57ae6cc53b59ad1d8708e5f513aca8dd77))
|
||||
* sim duration with restrictions ([a9145f6](https://gitlab.com/oceanbox/Poseidon/commit/a9145f6f79aa30cbe529d7a797b38dd2abe0a6cd))
|
||||
* **timeline:** display use local time in timeline ([ccbe076](https://gitlab.com/oceanbox/Poseidon/commit/ccbe07619f31c1b7511c8a8f4ca11fe3af8cbd53))
|
||||
* **timeline:** Marker uses UTC instead of CET + DST ([a474e7c](https://gitlab.com/oceanbox/Poseidon/commit/a474e7cbd4a894b9c1f5f20420dc728f93bc2e07))
|
||||
|
||||
## [1.33.1](https://gitlab.com/oceanbox/Poseidon/compare/v1.33.0...v1.33.1) (2025-11-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Add missing * in Drifters ArchiveType FromString ([7054ade](https://gitlab.com/oceanbox/Poseidon/commit/7054ade55dffd058f0d622447da08587633b815c))
|
||||
* **Atlantis:** Add wildcards in allow origin ([cde779e](https://gitlab.com/oceanbox/Poseidon/commit/cde779ea00f0666e6b548c7d711873b64cb294d9))
|
||||
|
||||
# [1.33.0](https://gitlab.com/oceanbox/Poseidon/compare/v1.32.0...v1.33.0) (2025-11-24)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* properly display sim parameters, and fix clone, closing [#70](https://gitlab.com/oceanbox/Poseidon/issues/70) ([4980a41](https://gitlab.com/oceanbox/Poseidon/commit/4980a41a4456be53c8a0193f1fbc40e0238c0111))
|
||||
|
||||
# [1.32.0](https://gitlab.com/oceanbox/Poseidon/compare/v1.31.0...v1.32.0) (2025-11-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* spell out units in plots ([020a2f2](https://gitlab.com/oceanbox/Poseidon/commit/020a2f2e000ed907ad1eb7768e47f6b053038e4e))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add Density profile plot and cancelable jobs ([8472708](https://gitlab.com/oceanbox/Poseidon/commit/847270877abc3bd983a400a29a0b4bebae033b06)), closes [oceanbox/Poseidon#30](https://gitlab.com/oceanbox/Poseidon/issues/30)
|
||||
|
||||
# [1.31.0](https://gitlab.com/oceanbox/Poseidon/compare/v1.30.1...v1.31.0) (2025-11-19)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **DataAgent:** offline eval function when you have a dto ([1982770](https://gitlab.com/oceanbox/Poseidon/commit/19827701aad9625d55f3bab4d48cb44122d512ae))
|
||||
|
||||
## [1.30.1](https://gitlab.com/oceanbox/Poseidon/compare/v1.30.0...v1.30.1) (2025-11-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Remove implicit FSharp.Core, Lib and Nuget for better CPM compat ([f8ab41b](https://gitlab.com/oceanbox/Poseidon/commit/f8ab41bbda9957727de63970a80f3c69e8715098))
|
||||
|
||||
# [1.30.0](https://gitlab.com/oceanbox/Poseidon/compare/v1.29.0...v1.30.0) (2025-11-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* don't fetch tz contour on update timeframe ([beedeb8](https://gitlab.com/oceanbox/Poseidon/commit/beedeb836b4353a5253362c11c3f772f65ad503d))
|
||||
* switch to element path and use haversine distance ([61b4323](https://gitlab.com/oceanbox/Poseidon/commit/61b432380310a9cbc5c1383854d71055034a49dd))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add Chaikin curve smoothing algorithm ([d4766f2](https://gitlab.com/oceanbox/Poseidon/commit/d4766f249b2ec1238a7df61df1a8fd3f3525f797))
|
||||
* sea distance circle, closing [#73](https://gitlab.com/oceanbox/Poseidon/issues/73) ([fc41c91](https://gitlab.com/oceanbox/Poseidon/commit/fc41c91d41ee35036ca6482e0f5128a51e175d7f))
|
||||
|
||||
# [1.29.0](https://gitlab.com/oceanbox/Poseidon/compare/v1.28.0...v1.29.0) (2025-11-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* move map type picker to the usual place ([917058b](https://gitlab.com/oceanbox/Poseidon/commit/917058b7be861a674a975f0ba939f5a227c11cf9))
|
||||
* naming ([5be346e](https://gitlab.com/oceanbox/Poseidon/commit/5be346e0fc7473640f2506a94e81f9e28a95b0c2))
|
||||
* switch to node path and use lonlat coord in api ([d8f38c4](https://gitlab.com/oceanbox/Poseidon/commit/d8f38c496d8fefb575157082ea1d6fc8f03fe806))
|
||||
* update fvcomkit ([da6a199](https://gitlab.com/oceanbox/Poseidon/commit/da6a1995c11702fe29965e77abfa7da525ff9e9c))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* calculation of sea distance, closes [#51](https://gitlab.com/oceanbox/Poseidon/issues/51) ([1b4f4ef](https://gitlab.com/oceanbox/Poseidon/commit/1b4f4ef3606354e09d5c20f8413b939291c6a78d))
|
||||
|
||||
# [1.28.0](https://gitlab.com/oceanbox/Poseidon/compare/v1.27.2...v1.28.0) (2025-11-05)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Don't build Sorcerer Client ([a627b08](https://gitlab.com/oceanbox/Poseidon/commit/a627b08df2fc02e28db105068a9766be5bf6ac10))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Centralize Nuget Package Management ([b062f66](https://gitlab.com/oceanbox/Poseidon/commit/b062f66cf90639ec3cccdbcf54826a622f28bb08))
|
||||
|
||||
## [1.27.2](https://gitlab.com/oceanbox/Poseidon/compare/v1.27.1...v1.27.2) (2025-11-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* cage interaction matrix and labeling, closes [#72](https://gitlab.com/oceanbox/Poseidon/issues/72) ([6d5a724](https://gitlab.com/oceanbox/Poseidon/commit/6d5a72412ba144cb9d948ba0cfdb1d464747e41f))
|
||||
|
||||
## [1.27.1](https://gitlab.com/oceanbox/Poseidon/compare/v1.27.0...v1.27.1) (2025-10-31)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Atlantis:** add sanity check for sim names, closes [#66](https://gitlab.com/oceanbox/Poseidon/issues/66) ([637d22e](https://gitlab.com/oceanbox/Poseidon/commit/637d22e0f094042504b50922932da5d1786f0cfe))
|
||||
* **Atlantis:** minor tweaks in ui naming and layout ([187a5e3](https://gitlab.com/oceanbox/Poseidon/commit/187a5e36e3bd28bf73dde4eaa1634df4fecb5ce1))
|
||||
* **Atlantis:** switch to chart-trend icon ([9b6a3ef](https://gitlab.com/oceanbox/Poseidon/commit/9b6a3ef1334eb0e2f74c1e398f3873a7095e5d43))
|
||||
* **Atlantis:** use Conc instead of activeLayer ([039df74](https://gitlab.com/oceanbox/Poseidon/commit/039df744d3901e3e476c53db2a39daaae0d93855))
|
||||
* **Atlantis:** use tab for statistics ([3a9c616](https://gitlab.com/oceanbox/Poseidon/commit/3a9c616f6b29df39fc679126036a79d76a4c2909))
|
||||
|
||||
# [1.27.0](https://gitlab.com/oceanbox/Poseidon/compare/v1.26.4...v1.27.0) (2025-10-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Atlantis:** fix buttons on sim setup ([c6eee07](https://gitlab.com/oceanbox/Poseidon/commit/c6eee0731705254bd32b68de8ceac7b6a37a5cc6))
|
||||
* **Atlantis:** fix style in point samples section ([e85a114](https://gitlab.com/oceanbox/Poseidon/commit/e85a114a234006c7aa4456ebf383f2dfbb884b65))
|
||||
* **Atlantis:** read sample radius from string ([0bd66f8](https://gitlab.com/oceanbox/Poseidon/commit/0bd66f89fd8539a323a3fcc34aca7a6620b26370))
|
||||
* **Mapster:** Do not disable timeline when not in OceanControls ([aaa5627](https://gitlab.com/oceanbox/Poseidon/commit/aaa56271b0e97132550eb687725d39174d7446b5))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Atlantis:** add alternative unit for downwelling, closes [#47](https://gitlab.com/oceanbox/Poseidon/issues/47) ([234cd19](https://gitlab.com/oceanbox/Poseidon/commit/234cd19af7021c45cf74e6792b38784f27ca981e))
|
||||
* **Atlantis:** introduce average point values within circle ([a7cb34d](https://gitlab.com/oceanbox/Poseidon/commit/a7cb34d7bad0fcb76b67a36c6292e5d65b878448))
|
||||
* **Atlantis:** time series from point samples, closes [#29](https://gitlab.com/oceanbox/Poseidon/issues/29) ([1d1ddf2](https://gitlab.com/oceanbox/Poseidon/commit/1d1ddf2fef4d8687a1eb9652538e9d2fa2c1a40f))
|
||||
* **Hipster:** add slurm account and comment ([40414db](https://gitlab.com/oceanbox/Poseidon/commit/40414db1f6976fcfd87e55e60b57feec0189e9cf))
|
||||
|
||||
## [1.26.4](https://gitlab.com/oceanbox/Poseidon/compare/v1.26.3...v1.26.4) (2025-10-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Create TMP directory for atlantis and add errorhandler ([0473f7b](https://gitlab.com/oceanbox/Poseidon/commit/0473f7b7656accd8bc493fd12908c2dd4a59a1b9))
|
||||
|
||||
## [1.26.3](https://gitlab.com/oceanbox/Poseidon/compare/v1.26.2...v1.26.3) (2025-10-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Atlas:** Fix top nav logo offset ([c5b85e9](https://gitlab.com/oceanbox/Poseidon/commit/c5b85e9ad44d02edda765ce7a8b6f314adaea669))
|
||||
* **Atlas:** Show loading when waiting for model area archives ([9181b43](https://gitlab.com/oceanbox/Poseidon/commit/9181b43732151fae37f0a837d946458b6544103d))
|
||||
* **Mapster:** Add back stats download button ([86425a2](https://gitlab.com/oceanbox/Poseidon/commit/86425a2292ea413bc9a6b24aab2105c9e85fade1))
|
||||
* **Mapster:** Add timeseries help text on stats ([0dbd11e](https://gitlab.com/oceanbox/Poseidon/commit/0dbd11ed68991a13d94f8a3053794751b5185bc4))
|
||||
* **Mapster:** Catch potential timeout error fetching time series ([214fb65](https://gitlab.com/oceanbox/Poseidon/commit/214fb650c1c06f5fbb9e42d922fb352833f3efec))
|
||||
* **Mapster:** Choose better warn condition for missing post drift ([17181f6](https://gitlab.com/oceanbox/Poseidon/commit/17181f6ca2d5f6a23a8d5f7f8853b1a64c670324))
|
||||
* **Mapster:** Fix plotly chart not auto ranging properly ([c862cb1](https://gitlab.com/oceanbox/Poseidon/commit/c862cb172fd24dbb3cb071e0e223665804965ed3))
|
||||
* **Mapster:** Handle grid search case for sub grids/models ([a046e7d](https://gitlab.com/oceanbox/Poseidon/commit/a046e7d84957cdc31d047b397ddd9d9470fdb847))
|
||||
* **Mapster:** Handle probing errors and show toast ([db37040](https://gitlab.com/oceanbox/Poseidon/commit/db370402090fc78206c31a48347338624fdabbed))
|
||||
* **Mapster:** Make loading clearer when loading ([215409c](https://gitlab.com/oceanbox/Poseidon/commit/215409c7c880e2ca48e8df58e591cbb3f385000c))
|
||||
* **Mapster:** Make notifier list an array ([3b4ec02](https://gitlab.com/oceanbox/Poseidon/commit/3b4ec021af8f1efff3f994a8ce912d8780eb966c))
|
||||
* **Mapster:** More sane stat selection in depth plots ([fa63ade](https://gitlab.com/oceanbox/Poseidon/commit/fa63ade2e1a974cc4cbf2c40b67b999b2040a1af))
|
||||
* **Mapster:** Redirect to /signin if entering map unauthenticated ([7176919](https://gitlab.com/oceanbox/Poseidon/commit/7176919e944fab87f7081887077a25c7ec2a5f33))
|
||||
* **Mapster:** Remove Esc listener from side nav stats controls ([59ce5b9](https://gitlab.com/oceanbox/Poseidon/commit/59ce5b98b83bd53dd47e0a7666fedcaf5b8bad20))
|
||||
* **Mapster:** Show warning when non-transport sims are missing post ([9bd0562](https://gitlab.com/oceanbox/Poseidon/commit/9bd0562b47eac0a36338ca0ce479b9207f142a67))
|
||||
* **Mapster:** Sidebar styling updates ([f7fbc5d](https://gitlab.com/oceanbox/Poseidon/commit/f7fbc5d70dc277f2f9bb9df2fa020b9b49a06416))
|
||||
* **Mapster:** Update field probing data extraction view ([9eed6af](https://gitlab.com/oceanbox/Poseidon/commit/9eed6af711e570fb4b7079686a7e01a592c3f383))
|
||||
* Use custom plotly bundle in react-plotly.js ([51fc750](https://gitlab.com/oceanbox/Poseidon/commit/51fc7503b5fae6c05c233888ece06e314f0555a3))
|
||||
|
||||
## [1.26.2](https://gitlab.com/oceanbox/Poseidon/compare/v1.26.1...v1.26.2) (2025-10-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **tmp:** Add prints to debug ([b5c21bb](https://gitlab.com/oceanbox/Poseidon/commit/b5c21bb62c31c98e21da7a670eda92e1b5c9d02d))
|
||||
|
||||
## [1.26.1](https://gitlab.com/oceanbox/Poseidon/compare/v1.26.0...v1.26.1) (2025-10-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Don't use nodejs in dev ([90bab5e](https://gitlab.com/oceanbox/Poseidon/commit/90bab5ecc0d095f494bb3c65c16c5ad5a36cc8a8)), closes [oceanbox/Poseidon#1](https://gitlab.com/oceanbox/Poseidon/issues/1)
|
||||
* Typo and build archivist with netcdf runtimeDeps ([8482921](https://gitlab.com/oceanbox/Poseidon/commit/84829214204828cbf1fed6f54f4055dc9d456561))
|
||||
|
||||
# [1.26.0](https://gitlab.com/oceanbox/Poseidon/compare/v1.25.5...v1.26.0) (2025-10-23)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **fga:** Add start_time to ReadChanges ([9388d37](https://gitlab.com/oceanbox/Poseidon/commit/9388d3758dc769106c2413686e59821352e74967))
|
||||
|
||||
## [1.25.5](https://gitlab.com/oceanbox/Poseidon/compare/v1.25.4...v1.25.5) (2025-10-22)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **nix:** Build Archivist SIF in pipeline ([16f9686](https://gitlab.com/oceanbox/Poseidon/commit/16f968657b61cb6ce6cecb12d8016565a25919fc))
|
||||
|
||||
## [1.25.4](https://gitlab.com/oceanbox/Poseidon/compare/v1.25.3...v1.25.4) (2025-10-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* reduce number of cpus per drifter job ([b293044](https://gitlab.com/oceanbox/Poseidon/commit/b293044258ecc9699e62205181e8963f8470d1c2))
|
||||
|
||||
## [1.25.3](https://gitlab.com/oceanbox/Poseidon/compare/v1.25.2...v1.25.3) (2025-10-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Atlantis:** set limitations on simulation parameters ([407a278](https://gitlab.com/oceanbox/Poseidon/commit/407a278e283144ef2d163108c63e8b2a586b560c))
|
||||
|
||||
## [1.25.2](https://gitlab.com/oceanbox/Poseidon/compare/v1.25.1...v1.25.2) (2025-10-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Send Drifters to Inbox instantly and Track Plumes ([48b5da9](https://gitlab.com/oceanbox/Poseidon/commit/48b5da9da3f3fcffc57592ea66f3a3d3c8828761))
|
||||
* Submit as queued if there is a queue ([d64ee45](https://gitlab.com/oceanbox/Poseidon/commit/d64ee45d9e82da86c6ca348d36169dbbdb363edd))
|
||||
|
||||
## [1.25.1](https://gitlab.com/oceanbox/Poseidon/compare/v1.25.0...v1.25.1) (2025-10-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Cleanup ([f721077](https://gitlab.com/oceanbox/Poseidon/commit/f72107751f0e81c1685a7b07ef5c22d512e5c031))
|
||||
* Release ([cb6265d](https://gitlab.com/oceanbox/Poseidon/commit/cb6265dcb1c2458eb69098be61df77afdd85ef32))
|
||||
|
||||
# [1.25.0](https://gitlab.com/oceanbox/Poseidon/compare/v1.24.5...v1.25.0) (2025-10-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Atlantis:** avoid positive release depth, closes [#42](https://gitlab.com/oceanbox/Poseidon/issues/42) ([16643c3](https://gitlab.com/oceanbox/Poseidon/commit/16643c346033b6d3e134152a2bf6f79bbfd45ca3))
|
||||
* **Atlantis:** clear point samples on deselect ([8174354](https://gitlab.com/oceanbox/Poseidon/commit/81743540d053dbc789cda41fdbc9b716decda53e))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Atlantis:** add point samples to any sim type, closes [#54](https://gitlab.com/oceanbox/Poseidon/issues/54) ([9a41f0a](https://gitlab.com/oceanbox/Poseidon/commit/9a41f0a2f3c804d5d6728c1d28020c51e61d060f))
|
||||
* **Atlantis:** add toggle button for showing releases, closes [#53](https://gitlab.com/oceanbox/Poseidon/issues/53) ([f8045f6](https://gitlab.com/oceanbox/Poseidon/commit/f8045f6dcc46a1ba0de33e9092db87f798fb6255))
|
||||
* **Atlantis:** copy release sites, closes [#56](https://gitlab.com/oceanbox/Poseidon/issues/56) ([9bb9d85](https://gitlab.com/oceanbox/Poseidon/commit/9bb9d855e4f93f07e634b1f7e499feb7136643f1))
|
||||
* **Atlantis:** fetch time series data from plot, closes [#55](https://gitlab.com/oceanbox/Poseidon/issues/55) ([a332fe7](https://gitlab.com/oceanbox/Poseidon/commit/a332fe72a2c745ffe8ed45598c6a9ab8f3391cb0))
|
||||
|
||||
## [1.24.5](https://gitlab.com/oceanbox/Poseidon/compare/v1.24.4...v1.24.5) (2025-10-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **mapster:** Set static artifact for plume downloads ([5476583](https://gitlab.com/oceanbox/Poseidon/commit/5476583cb2fde0beed37b6235144532c6234432c))
|
||||
|
||||
## [1.24.4](https://gitlab.com/oceanbox/Poseidon/compare/v1.24.3...v1.24.4) (2025-10-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* broken vite version ([5e84185](https://gitlab.com/oceanbox/Poseidon/commit/5e8418595046d7685eb405c36953f7b888650aea))
|
||||
* update drifters.api version ([22339c6](https://gitlab.com/oceanbox/Poseidon/commit/22339c6adebe584254b6c1a5c52804ce970435d5))
|
||||
|
||||
## [1.24.3](https://gitlab.com/oceanbox/Poseidon/compare/v1.24.2...v1.24.3) (2025-10-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Remove client from archivist cli and use correct path ([60a47b0](https://gitlab.com/oceanbox/Poseidon/commit/60a47b030801c6fc36f3d7599455624058e9c075))
|
||||
|
||||
## [1.24.2](https://gitlab.com/oceanbox/Poseidon/compare/v1.24.1...v1.24.2) (2025-10-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* remove tz contours on deselect ([a5b348e](https://gitlab.com/oceanbox/Poseidon/commit/a5b348e439c33ff7367ae299f8e5afed87b2be8c))
|
||||
|
||||
## [1.24.1](https://gitlab.com/oceanbox/Poseidon/compare/v1.24.0...v1.24.1) (2025-10-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Update lockfiles ([904845f](https://gitlab.com/oceanbox/Poseidon/commit/904845fe0aeb1b1daaa75f785205ad4242eb4f05))
|
||||
|
||||
# [1.24.0](https://gitlab.com/oceanbox/Poseidon/compare/v1.23.3...v1.24.0) (2025-10-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Atlantis:** sync import of sp-picker ([6151eb8](https://gitlab.com/oceanbox/Poseidon/commit/6151eb86f0ce9bcc013fa5f12c3713035e39cc7d))
|
||||
* Build Archivist with correct archmaester interface ([d182900](https://gitlab.com/oceanbox/Poseidon/commit/d182900b028549fcf443c841ba8aad0adec57a19))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Atlantis:** add multiple transition zone contours, closes [#34](https://gitlab.com/oceanbox/Poseidon/issues/34) ([c75d137](https://gitlab.com/oceanbox/Poseidon/commit/c75d13711ae681b428cf177e7463888ac9a997f3))
|
||||
* **Atlantis:** first take on cage interaction matrix, closes [#33](https://gitlab.com/oceanbox/Poseidon/issues/33) ([9ea31be](https://gitlab.com/oceanbox/Poseidon/commit/9ea31be3329afca6f29d869c95251c64e61bb6b4))
|
||||
* **Atlantis:** point values section to sedimentation fields, closes [#43](https://gitlab.com/oceanbox/Poseidon/issues/43) ([7fff70b](https://gitlab.com/oceanbox/Poseidon/commit/7fff70b7d5e9f01303d6036f0e299ce92d44950a))
|
||||
* **Atlantis:** separate groups in accumulate, closes [#44](https://gitlab.com/oceanbox/Poseidon/issues/44) ([bda39de](https://gitlab.com/oceanbox/Poseidon/commit/bda39dea78edc85f273ab471a12ae24d2b6c9485))
|
||||
* **Sorcerer:** add api for field2d contours ([598fd5a](https://gitlab.com/oceanbox/Poseidon/commit/598fd5a7b05fc169b14ead197c51e00385c01f06))
|
||||
|
||||
## [1.23.3](https://gitlab.com/oceanbox/Poseidon/compare/v1.23.2...v1.23.3) (2025-09-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Atlantis:** Go back to how secrets were fetched ([ea335bc](https://gitlab.com/oceanbox/Poseidon/commit/ea335bc3fb1ca68ef2e23247ec17baac362fee4f))
|
||||
|
||||
## [1.23.2](https://gitlab.com/oceanbox/Poseidon/compare/v1.23.1...v1.23.2) (2025-09-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Atlantis:** Ensure dapr is healthy before running ([e344647](https://gitlab.com/oceanbox/Poseidon/commit/e34464782ab95613f786c24a139be0ecbf97a043))
|
||||
* **Atlantis:** Use correct DI settings type in FgaActor ([be1f942](https://gitlab.com/oceanbox/Poseidon/commit/be1f942413b78f288fe26a042fa53ac1d482eda9))
|
||||
|
||||
## [1.23.1](https://gitlab.com/oceanbox/Poseidon/compare/v1.23.0...v1.23.1) (2025-09-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Atlantis:** Overwrite slurm token with value from secrets ([94c8acc](https://gitlab.com/oceanbox/Poseidon/commit/94c8accf45b44bf9840c8165a2668d3ba948c696))
|
||||
|
||||
# [1.23.0](https://gitlab.com/oceanbox/Poseidon/compare/v1.22.8...v1.23.0) (2025-09-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add slurm-access-token stub to tilt ([190b227](https://gitlab.com/oceanbox/Poseidon/commit/190b227d97880f310e14d6459b6e9b0e18f3715a))
|
||||
* change slurm secret token key to SLURM_JWT ([b4c8de2](https://gitlab.com/oceanbox/Poseidon/commit/b4c8de2e09b7a6676f96dbeee520496c13d8059a))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* move slurmrestd from basic auth to jwt ([0922a8f](https://gitlab.com/oceanbox/Poseidon/commit/0922a8fa08c81e967edf03fdedb9dfba77b2ee8a))
|
||||
|
||||
## [1.22.8](https://gitlab.com/oceanbox/Poseidon/compare/v1.22.7...v1.22.8) (2025-09-22)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **dataagent:** Add privateassets and bump api to match version ([93c1661](https://gitlab.com/oceanbox/Poseidon/commit/93c166144eb0b411aa147dc4e935aa560de2badd))
|
||||
|
||||
## [1.22.7](https://gitlab.com/oceanbox/Poseidon/compare/v1.22.6...v1.22.7) (2025-09-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **dataagent:** Actual bump in version ([b9b9720](https://gitlab.com/oceanbox/Poseidon/commit/b9b97205c27c1d9a9d1f50f1c7c7d86b2d9e4eba))
|
||||
|
||||
## [1.22.6](https://gitlab.com/oceanbox/Poseidon/compare/v1.22.5...v1.22.6) (2025-09-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **dataagent:** Add back weird Targets ([0586f2f](https://gitlab.com/oceanbox/Poseidon/commit/0586f2f7d3c5dec1c3b8b8d7039f8214690238c2))
|
||||
|
||||
## [1.22.5](https://gitlab.com/oceanbox/Poseidon/compare/v1.22.4...v1.22.5) (2025-09-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **mapster:** Add authorization for plume usage ([7b90371](https://gitlab.com/oceanbox/Poseidon/commit/7b90371f849f92260d84bfd03f581799a7e86fb5))
|
||||
|
||||
## [1.22.4](https://gitlab.com/oceanbox/Poseidon/compare/v1.22.3...v1.22.4) (2025-09-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Add archivist binary to shell and allow dirs in add ([ebc12b9](https://gitlab.com/oceanbox/Poseidon/commit/ebc12b9ef9cfc483cdb4c0319ce08f761930a9f6))
|
||||
* **Atlantis:** Remove heuristic caching tags instead of cache control ([f6ce5d2](https://gitlab.com/oceanbox/Poseidon/commit/f6ce5d26c383027b5363ab7804d766a057e60b28))
|
||||
* Don't validate files in parser ([29eeb17](https://gitlab.com/oceanbox/Poseidon/commit/29eeb17306ab6b44e3aea6136601f259f98ab123))
|
||||
|
||||
## [1.22.3](https://gitlab.com/oceanbox/Poseidon/compare/v1.22.2...v1.22.3) (2025-09-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Load agenix secrets in direnv ([b2d8dec](https://gitlab.com/oceanbox/Poseidon/commit/b2d8dec9a4be788f7c38dd26369ddd37f32fcd22))
|
||||
|
||||
## [1.22.2](https://gitlab.com/oceanbox/Poseidon/compare/v1.22.1...v1.22.2) (2025-09-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Umami:** Add some initial event tracking ([ace083a](https://gitlab.com/oceanbox/Poseidon/commit/ace083af9e7318a0eece2f7c88fd728607b3395e))
|
||||
|
||||
## [1.22.1](https://gitlab.com/oceanbox/Poseidon/compare/v1.22.0...v1.22.1) (2025-09-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Typo rename URL -> WEB_ID ([2e260d1](https://gitlab.com/oceanbox/Poseidon/commit/2e260d118445f86b733bbe5068fd9d9adc7df207))
|
||||
|
||||
# [1.22.0](https://gitlab.com/oceanbox/Poseidon/compare/v1.21.11...v1.22.0) (2025-09-12)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Atlantis:** Add user id to umami payload as unique id ([5a6c725](https://gitlab.com/oceanbox/Poseidon/commit/5a6c7258a49bbd91e8ddc9b0ccce715d34afed58))
|
||||
|
||||
## [1.21.11](https://gitlab.com/oceanbox/Poseidon/compare/v1.21.10...v1.21.11) (2025-09-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Change from plausible to umami ([c2a99ac](https://gitlab.com/oceanbox/Poseidon/commit/c2a99ac1eed9dbdafac52f163dc49a384ee7399a))
|
||||
|
||||
## [1.21.10](https://gitlab.com/oceanbox/Poseidon/compare/v1.21.9...v1.21.10) (2025-09-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Atlantis:** Configure static files manually ([5402af7](https://gitlab.com/oceanbox/Poseidon/commit/5402af7f8f3f588131862b2c9a95d7469ed68561))
|
||||
* **Atlantis:** Use correct barentswatch secret ([9cd9518](https://gitlab.com/oceanbox/Poseidon/commit/9cd9518a38912b2b50fd4e01ead348e92a7e1a40))
|
||||
|
||||
## [1.21.9](https://gitlab.com/oceanbox/Poseidon/compare/v1.21.8...v1.21.9) (2025-09-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Add no-cache header to served content ([1247d4d](https://gitlab.com/oceanbox/Poseidon/commit/1247d4d0923b2cce16c278012abdeb16b6e8e913))
|
||||
* **Slurm:** Catch decode errors in handleSlurmEvents ([ad91a3d](https://gitlab.com/oceanbox/Poseidon/commit/ad91a3dd2339d9e9252eeb0ca82e1a37e205d5b4))
|
||||
|
||||
## [1.21.8](https://gitlab.com/oceanbox/Poseidon/compare/v1.21.7...v1.21.8) (2025-09-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Add closing bracket vite atlantis ([2c6a30a](https://gitlab.com/oceanbox/Poseidon/commit/2c6a30a4f6d5adad548443e4558e3fee1fda5545))
|
||||
|
||||
## [1.21.7](https://gitlab.com/oceanbox/Poseidon/compare/v1.21.6...v1.21.7) (2025-09-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Add hash to vite output artifacts ([8e72010](https://gitlab.com/oceanbox/Poseidon/commit/8e72010740d20bfb99ac7b635a5f679546d407ba))
|
||||
|
||||
## [1.21.6](https://gitlab.com/oceanbox/Poseidon/compare/v1.21.5...v1.21.6) (2025-09-05)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Atlantis:** convert release span from sec to hr ([e7ae2ee](https://gitlab.com/oceanbox/Poseidon/commit/e7ae2ee38aa49fd5bfe4a3404aed7c8aeab7139e))
|
||||
* **Mapster:** Redirect to Atlas if no archive is chosen ([047d747](https://gitlab.com/oceanbox/Poseidon/commit/047d74723ec7ec2710cbf4e219a80d7dcbd7926e))
|
||||
* **Mapster:** Test session storage on loading map ([3a7df65](https://gitlab.com/oceanbox/Poseidon/commit/3a7df65f0a94440ec2fae401730cc2fa0bcd8937))
|
||||
|
||||
## [1.21.5](https://gitlab.com/oceanbox/Poseidon/compare/v1.21.4...v1.21.5) (2025-09-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Clean up package.json ([27df77b](https://gitlab.com/oceanbox/Poseidon/commit/27df77bfebcaa2efdd22f5057d5b811c209d9a53))
|
||||
* Ignore buildkit builder ([6e31e77](https://gitlab.com/oceanbox/Poseidon/commit/6e31e77f0347c6b3a3953d043b0e0842f057ad8a))
|
||||
|
||||
## [1.21.4](https://gitlab.com/oceanbox/Poseidon/compare/v1.21.3...v1.21.4) (2025-09-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Mapster:** Fix aquaculture locations not showing ([4806dd9](https://gitlab.com/oceanbox/Poseidon/commit/4806dd97de3ffbe2d683e8318d16a53db217e171))
|
||||
|
||||
## [1.21.3](https://gitlab.com/oceanbox/Poseidon/compare/v1.21.2...v1.21.3) (2025-08-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Default to Debug and rename to env ([f441a15](https://gitlab.com/oceanbox/Poseidon/commit/f441a15f693c9beb0f01c17634a9bbc1a8addc9d))
|
||||
|
||||
## [1.21.2](https://gitlab.com/oceanbox/Poseidon/compare/v1.21.1...v1.21.2) (2025-08-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Add Error propagation and diagnosticlogging ([b2cce31](https://gitlab.com/oceanbox/Poseidon/commit/b2cce311b5a2cea329e95a755d1db71d24876b76))
|
||||
|
||||
## [1.21.1](https://gitlab.com/oceanbox/Poseidon/compare/v1.21.0...v1.21.1) (2025-08-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 4GB maxRequestBodySize in prod and update fsi file ([cee62b1](https://gitlab.com/oceanbox/Poseidon/commit/cee62b15e6b2e15fd86fd5f9f5e05aaa6a92d136))
|
||||
|
||||
# [1.21.0](https://gitlab.com/oceanbox/Poseidon/compare/v1.20.2...v1.21.0) (2025-08-27)
|
||||
|
||||
## [1.20.2](https://gitlab.com/oceanbox/Poseidon/compare/v1.20.1...v1.20.2) (2025-08-22)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Mapster:** Fix ArchiveDialog table squeeze ([90b17a5](https://gitlab.com/oceanbox/Poseidon/commit/90b17a59a24aa5be03cf5fc168a63bf131f05bce))
|
||||
* **Mapster:** Fix InboxDialog table squeeze ([124a900](https://gitlab.com/oceanbox/Poseidon/commit/124a900b4413a3526692d6d736feb0aab423f126))
|
||||
|
||||
## [1.20.1](https://gitlab.com/oceanbox/Poseidon/compare/v1.20.0...v1.20.1) (2025-08-22)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Downgrade vite plugin for correct js bundle ([d35f666](https://gitlab.com/oceanbox/Poseidon/commit/d35f666664c740e7778a889d2a7be1f8f9f776ac))
|
||||
|
||||
# [1.20.0](https://gitlab.com/oceanbox/Poseidon/compare/v1.19.4...v1.20.0) (2025-08-22)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add custom depth separator in conc analysis ([62b09de](https://gitlab.com/oceanbox/Poseidon/commit/62b09deb8d64feeae3a242c39314c28b16842cc3))
|
||||
|
||||
## [1.19.4](https://gitlab.com/oceanbox/Poseidon/compare/v1.19.3...v1.19.4) (2025-08-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Don't run linter ([1780867](https://gitlab.com/oceanbox/Poseidon/commit/1780867a89244bbd7b6c095e477acbabb3fd4cc7))
|
||||
* **nix:** Format, lint and remove dead code ([7d378a5](https://gitlab.com/oceanbox/Poseidon/commit/7d378a52d1e6f2293d6f3bcae9b0a97b23fb4d74))
|
||||
|
||||
## [1.19.3](https://gitlab.com/oceanbox/Poseidon/compare/v1.19.2...v1.19.3) (2025-08-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Add fable temp files to gitignore ([8d9843d](https://gitlab.com/oceanbox/Poseidon/commit/8d9843d4679198c88bee8261e8cf5091f45280a1))
|
||||
|
||||
## [1.19.2](https://gitlab.com/oceanbox/Poseidon/compare/v1.19.1...v1.19.2) (2025-08-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Add libnetcdf as runtime dependency for containers ([6e7fa4b](https://gitlab.com/oceanbox/Poseidon/commit/6e7fa4b9c702e1e7bb694443163693397293f27f))
|
||||
* Add memorysize ([f626796](https://gitlab.com/oceanbox/Poseidon/commit/f6267962b34920288e3b625ea637890cd2e9a289))
|
||||
* Include nix files for CI ([7983d94](https://gitlab.com/oceanbox/Poseidon/commit/7983d948f10e11461be91dc6a9259a3eb2749953))
|
||||
|
||||
## [1.19.1](https://gitlab.com/oceanbox/Poseidon/compare/v1.19.0...v1.19.1) (2025-08-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Atlas:** Fix squashed archive table in modal ([3593a44](https://gitlab.com/oceanbox/Poseidon/commit/3593a4494d332ae042c13e345fd0a0d59b46984e))
|
||||
|
||||
# [1.19.0](https://gitlab.com/oceanbox/Poseidon/compare/v1.18.3...v1.19.0) (2025-08-19)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add OpenLayer FullScreen Controls ([2a3bb68](https://gitlab.com/oceanbox/Poseidon/commit/2a3bb68e3e1ffe57772c961c27b904d9023a5294))
|
||||
|
||||
## [1.18.3](https://gitlab.com/oceanbox/Poseidon/compare/v1.18.2...v1.18.3) (2025-08-18)
|
||||
|
||||
|
||||
|
||||
@@ -5,29 +5,22 @@ Stage: build
|
||||
%files
|
||||
. /build
|
||||
|
||||
# Install apt packages
|
||||
%post
|
||||
# Add keys and sources lists
|
||||
apt-get update && apt-get install -y ca-certificates gnupg
|
||||
mkdir -p /etc/apt/keyrings
|
||||
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
|
||||
NODE_MAJOR=20
|
||||
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list
|
||||
|
||||
# Install node, 7zip, yarn, git, process tools
|
||||
apt update \
|
||||
&& apt install -y nodejs p7zip-full git procps ssh-client
|
||||
&& apt install -y p7zip-full git procps ssh-client
|
||||
|
||||
# Clean up
|
||||
apt autoremove -y \
|
||||
&& apt clean -y \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install dotnet tools
|
||||
dotnet tool install fable -g
|
||||
|
||||
# Build application
|
||||
%post
|
||||
cd /build/src/Archivist
|
||||
dotnet restore --force-evaluate
|
||||
dotnet run bundle
|
||||
|
||||
|
||||
Bootstrap: docker
|
||||
From: mcr.microsoft.com/dotnet/runtime:9.0
|
||||
Stage: runtime
|
||||
@@ -39,7 +32,6 @@ Stage: runtime
|
||||
apt update \
|
||||
&& apt install -y libnetcdf-dev
|
||||
|
||||
# Clean up
|
||||
apt autoremove -y \
|
||||
&& apt clean -y \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
@@ -52,4 +44,4 @@ Stage: runtime
|
||||
export ARCHMAESTER_AUTH="admin:en-to-tre-fire"
|
||||
|
||||
%runscript
|
||||
exec /app/Archivist "$@"
|
||||
exec /app/archivist "$@"
|
||||
45
default.nix
45
default.nix
@@ -1,12 +1,13 @@
|
||||
{
|
||||
sources ? import ./npins,
|
||||
sources ? import ./nix,
|
||||
system ? builtins.currentSystem,
|
||||
debug ? "Release",
|
||||
pkgs ? import sources.nixpkgs {
|
||||
inherit system;
|
||||
config = { };
|
||||
overlays = [ ];
|
||||
},
|
||||
env ? "Debug",
|
||||
nix-utils ? import sources.nix-utils { },
|
||||
}:
|
||||
let
|
||||
version =
|
||||
@@ -16,26 +17,42 @@ let
|
||||
in
|
||||
clean version;
|
||||
|
||||
dotnet-sdk = pkgs.dotnetCorePackages.sdk_9_0;
|
||||
dotnet-runtime = pkgs.dotnetCorePackages.aspnetcore_9_0;
|
||||
dotnet-sdk = pkgs.dotnetCorePackages.sdk_10_0;
|
||||
dotnet-runtime = pkgs.dotnetCorePackages.aspnetcore_10_0;
|
||||
deps = nix-utils.output.lib.nuget.deps;
|
||||
|
||||
# Usage: export NETRC="$(agenix -d netrc.age)" in `./nix/secrets`
|
||||
netrcConfig = builtins.getEnv "NETRC";
|
||||
|
||||
scripts = import ./scripts { inherit pkgs sources; };
|
||||
scripts = import ./scripts { inherit pkgs; };
|
||||
|
||||
packages = import ./nix/packages {
|
||||
inherit
|
||||
env
|
||||
deps
|
||||
pkgs
|
||||
version
|
||||
dotnet-sdk
|
||||
dotnet-runtime
|
||||
debug
|
||||
;
|
||||
inherit netrcConfig;
|
||||
};
|
||||
|
||||
containers = pkgs.callPackage ./nix/containers.nix {
|
||||
inherit (packages)
|
||||
atlantis
|
||||
sorcerer
|
||||
atlantis-client
|
||||
archivist
|
||||
;
|
||||
inherit
|
||||
version
|
||||
env
|
||||
;
|
||||
codex = packages.codex;
|
||||
};
|
||||
in
|
||||
rec {
|
||||
{
|
||||
inherit packages;
|
||||
|
||||
inherit scripts;
|
||||
@@ -44,13 +61,9 @@ rec {
|
||||
default = packages.atlantis;
|
||||
|
||||
# Docker and Singurlarity images
|
||||
containers = pkgs.callPackage ./nix/containers.nix {
|
||||
inherit (packages)
|
||||
atlantis
|
||||
sorcerer
|
||||
atlantis-client
|
||||
archivist
|
||||
;
|
||||
inherit version;
|
||||
containers = containers;
|
||||
|
||||
checks = {
|
||||
pre-commit = import ./nix/pre-commit.nix;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "9.0.0",
|
||||
"version": "10.0.100",
|
||||
"rollForward": "latestMinor"
|
||||
}
|
||||
}
|
||||
42
justfile
Normal file
42
justfile
Normal file
@@ -0,0 +1,42 @@
|
||||
# Poseidon build commands
|
||||
# Install just: https://github.com/casey/just
|
||||
#
|
||||
# Sub-projects with justfiles:
|
||||
# - Atlantis (src/Atlantis) - Server + Client application with Fable/Vite
|
||||
# - ServerPack (src/ServerPack) - Server package library
|
||||
# - DataAgent (src/DataAgent) - Data agent library
|
||||
# - Interfaces (src/Interfaces) - API interfaces library
|
||||
# - Archivist (src/Archivist) - CLI tool with client
|
||||
# - Sorcerer (src/Sorcerer) - Server application with client
|
||||
#
|
||||
# Run 'just <project>' to see available commands for each project (e.g., 'just atlantis')
|
||||
|
||||
set dotenv-load
|
||||
|
||||
# Default recipe - show available commands
|
||||
default:
|
||||
@just --list
|
||||
|
||||
# Show available commands for Atlantis (src/Atlantis)
|
||||
atlantis:
|
||||
@just src/Atlantis/
|
||||
|
||||
# Show available commands for ServerPack (src/ServerPack)
|
||||
serverpack:
|
||||
@just src/ServerPack/
|
||||
|
||||
# Show available commands for DataAgent (src/DataAgent)
|
||||
dataagent:
|
||||
@just src/DataAgent/
|
||||
|
||||
# Show available commands for Interfaces (src/Interfaces)
|
||||
interfaces:
|
||||
@just src/Interfaces/
|
||||
|
||||
# Show available commands for Archivist (src/Archivist)
|
||||
archivist:
|
||||
@just src/Archivist/
|
||||
|
||||
# Show available commands for Sorcerer (src/Sorcerer)
|
||||
sorcerer:
|
||||
@just src/Sorcerer/
|
||||
@@ -1,6 +1,6 @@
|
||||
# Nix
|
||||
|
||||
This directory contains Nix expressions defining the packages, containers and workflows used to run/build Poseidon.
|
||||
This directory contains Nix expressions defining the packages, and containers used to run/build Poseidon.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
@@ -15,11 +15,7 @@ nix/
|
||||
│ ├── atlantis-client.json # Client dependencies metadata
|
||||
│ ├── atlantis-deps.json # Atlantis backend dependencies metadata
|
||||
│ ├── sorcerer.nix
|
||||
│ ├── archivist.nix
|
||||
│ └── bun.nix # JavaScript/TypeScript dependencies via Bun
|
||||
├── workflows/ # GitHub Actions workflows
|
||||
│ ├── build.nix
|
||||
│ └── update.nix
|
||||
│ └── archivist.nix
|
||||
├── secrets/ # Age encrypted files
|
||||
│ ├── secrets.nix
|
||||
│ └── *.age
|
||||
@@ -27,7 +23,6 @@ nix/
|
||||
│ ├── atlantis
|
||||
│ ├── sorcerer
|
||||
│ └── archivist
|
||||
├── workflows.nix # GitHub Actions workflow orchestration
|
||||
└── pre-commit.nix # Pre-commit hooks for code quality
|
||||
```
|
||||
|
||||
@@ -37,7 +32,13 @@ Note: `nix-build` can be switched for `nom-build` for a pretty-printed output (u
|
||||
|
||||
### Secrets
|
||||
|
||||
```bash
|
||||
# To run nix-build
|
||||
$ set -x NETRC $(agenix -d netrc.age)
|
||||
```
|
||||
|
||||
Secrets used for development and production are stored as `*.age` files and decrypted/encrypted using agenix via ssh-keys.
|
||||
|
||||
```bash
|
||||
# To encrypt
|
||||
$ agenix -e name.age # And add to secrets.nix
|
||||
@@ -80,12 +81,6 @@ $ nix-shell
|
||||
$ nix-shell -A packages.atlantis
|
||||
```
|
||||
|
||||
### Generating Github Actions
|
||||
```bash
|
||||
# Updates the generate workflows in `.githhub/workflows`
|
||||
$ nix-shell -A workflows --run "echo Generate"
|
||||
```
|
||||
|
||||
### Running Services
|
||||
```bash
|
||||
# Run Atlantis server
|
||||
@@ -95,12 +90,20 @@ $ ./result/bin/atlantis
|
||||
$ ./result/bin/sorcerer
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
### Update dependencies
|
||||
|
||||
The build system automatically handles:
|
||||
- .NET SDK and runtime dependencies
|
||||
- JavaScript packages via Bun
|
||||
- Private NuGet packages from the Oceanbox registry
|
||||
- System libraries (NetCDF, etc.)
|
||||
When updating the `npm` dependencies, the `outputHash` in `atlantis-client.nix` needs to be updated. Simply run
|
||||
|
||||
For updating dependencies, see the [scripts documentation](../scripts/README.md).
|
||||
```bash
|
||||
nix-build -A packages.atlantis-client # in the root
|
||||
```
|
||||
|
||||
It will then fail on the wrong hash and provide the correct one.
|
||||
|
||||
#### Deterministic builds, vendor hashes, and lock files
|
||||
|
||||
Nix aims for deterministic (reproducible) builds. A key part of this is **fixed-output derivations (FODs)** such as `fetchurl`, `buildDotnetModule`’s vendor step, `fetchgit`, etc. For any FOD, Nix requires a **content hash** up front. After the build/fetch runs, Nix verifies that the resulting output’s hash exactly matches what was declared; if it doesn’t, the build fails with a “hash mismatch in fixed-output derivation” error. This protects you from drifting dependencies and ensures that CI and local builds use the exact same inputs.
|
||||
|
||||
#### Why vendor hashes need to be pinned
|
||||
|
||||
Language ecosystems resolve and download a lot of upstream content (Go modules, npm/yarn, cargo crates, vendored tarballs…). To make those fetches deterministic, Nix needs the **expected content hash**. For example, with `makeDerivation`, you must set `outputHash` so Nix knows what the fully-resolved module tree should hash to. If you bump a version or change dependencies, the **content changes** and the old hash becomes invalid—Nix will (correctly) refuse the build until you update the pinned hash.
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
{
|
||||
env,
|
||||
pkgs,
|
||||
version,
|
||||
atlantis,
|
||||
atlantis-client,
|
||||
sorcerer,
|
||||
archivist,
|
||||
codex,
|
||||
}:
|
||||
let
|
||||
# Entrypoints
|
||||
startArchivist = pkgs.writeScriptBin "entrypoint" ''
|
||||
#!${pkgs.runtimeShell}
|
||||
set -euo pipefail
|
||||
exec archivist "$@"
|
||||
'';
|
||||
in
|
||||
{
|
||||
atlantis = pkgs.dockerTools.buildLayeredImage {
|
||||
name = "Atlantis";
|
||||
@@ -13,19 +23,26 @@
|
||||
created = "now";
|
||||
contents = [
|
||||
atlantis
|
||||
# pkgs.dockerTools.binSh
|
||||
pkgs.dockerTools.caCertificates
|
||||
# pkgs.busybox
|
||||
pkgs.netcdf
|
||||
]
|
||||
++ pkgs.lib.optionals (env == "Debug") [
|
||||
pkgs.busybox
|
||||
pkgs.dockerTools.binSh
|
||||
];
|
||||
|
||||
extraCommands = ''
|
||||
mkdir -m 0777 tmp
|
||||
mkdir -p ./app
|
||||
cp -r ${atlantis}/lib/Atlantis/* ./app/
|
||||
cp -r ${atlantis-client}/public ./app/
|
||||
'';
|
||||
|
||||
config = {
|
||||
cmd = [ "Server" ];
|
||||
workingDir = "/app";
|
||||
env = [
|
||||
"SERVER_CONTENT_ROOT=/app/public"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
@@ -35,9 +52,11 @@
|
||||
created = "now";
|
||||
contents = [
|
||||
sorcerer
|
||||
# pkgs.dockerTools.binSh
|
||||
pkgs.dockerTools.caCertificates
|
||||
pkgs.netcdf
|
||||
]
|
||||
++ pkgs.lib.optionals (env == "Debug") [
|
||||
pkgs.busybox
|
||||
pkgs.dockerTools.binSh
|
||||
];
|
||||
extraCommands = ''
|
||||
mkdir -p ./app
|
||||
@@ -49,20 +68,35 @@
|
||||
};
|
||||
};
|
||||
|
||||
archivist = pkgs.singularity-tools.buildImage {
|
||||
archivist = pkgs.dockerTools.buildLayeredImage {
|
||||
name = "archivist";
|
||||
tag = archivist.version;
|
||||
created = "now";
|
||||
|
||||
contents = [
|
||||
archivist
|
||||
pkgs.netcdf
|
||||
pkgs.coreutils
|
||||
pkgs.bash
|
||||
]
|
||||
++ pkgs.lib.optionals (env == "Debug") [
|
||||
pkgs.busybox
|
||||
pkgs.dockerTools.binSh
|
||||
];
|
||||
diskSize = 2048; # MB
|
||||
runScript = ''
|
||||
#!/bin/bash
|
||||
export ARCHMAESTER_URL="https://maps.oceanbox.io"
|
||||
export ARCHMAESTER_AUTH="admin:en-to-tre-fire"
|
||||
exec ${archivist}/bin/archivist "$@"
|
||||
|
||||
compressor = "none";
|
||||
|
||||
extraCommands = ''
|
||||
mkdir -p ./app
|
||||
cp -r ${archivist}/lib/Archivist/* ./app/
|
||||
'';
|
||||
|
||||
config = {
|
||||
entrypoint = [ "${startArchivist}/bin/entrypoint" ];
|
||||
workingDir = "/app";
|
||||
env = [
|
||||
"ARCHMAESTER_URL=https://maps.oceanbox.io"
|
||||
"ARCHMAESTER_AUTH=admin:en-to-tre-fire"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
codex = pkgs.callPackage ../src/Codex/container.nix { server = codex; };
|
||||
}
|
||||
@@ -9,8 +9,15 @@
|
||||
*/
|
||||
# Generated by npins. Do not modify; will be overwritten regularly
|
||||
let
|
||||
data = builtins.fromJSON (builtins.readFile ./sources.json);
|
||||
version = data.version;
|
||||
# Backwards-compatibly make something that previously didn't take any arguments take some
|
||||
# The function must return an attrset, and will unfortunately be eagerly evaluated
|
||||
# Same thing, but it catches eval errors on the default argument so that one may still call it with other arguments
|
||||
mkFunctor =
|
||||
fn:
|
||||
let
|
||||
e = builtins.tryEval (fn { });
|
||||
in
|
||||
(if e.success then e.value else { error = fn { }; }) // { __functor = _self: fn; };
|
||||
|
||||
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295
|
||||
range =
|
||||
@@ -21,7 +28,6 @@ let
|
||||
|
||||
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269
|
||||
stringAsChars = f: s: concatStrings (map f (stringToCharacters s));
|
||||
# concatMapStrings = f: list: concatStrings (map f list);
|
||||
concatStrings = builtins.concatStringsSep "";
|
||||
|
||||
# If the environment variable NPINS_OVERRIDE_${name} is set, then use
|
||||
@@ -48,41 +54,87 @@ let
|
||||
|
||||
mkSource =
|
||||
name: spec:
|
||||
{
|
||||
pkgs ? null,
|
||||
}:
|
||||
assert spec ? type;
|
||||
let
|
||||
# Unify across builtin and pkgs fetchers.
|
||||
# `fetchGit` requires a wrapper because of slight API differences.
|
||||
fetchers =
|
||||
if pkgs == null then
|
||||
{
|
||||
inherit (builtins) fetchTarball fetchurl;
|
||||
# For some fucking reason, fetchGit has a different signature than the other builtin fetchers …
|
||||
fetchGit = args: (builtins.fetchGit args).outPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
fetchTarball =
|
||||
{
|
||||
url,
|
||||
sha256,
|
||||
}:
|
||||
pkgs.fetchzip {
|
||||
inherit url sha256;
|
||||
extension = "tar";
|
||||
};
|
||||
inherit (pkgs) fetchurl;
|
||||
fetchGit =
|
||||
{
|
||||
url,
|
||||
submodules,
|
||||
rev,
|
||||
name,
|
||||
narHash,
|
||||
}:
|
||||
pkgs.fetchgit {
|
||||
inherit url rev name;
|
||||
fetchSubmodules = submodules;
|
||||
hash = narHash;
|
||||
};
|
||||
};
|
||||
|
||||
# Dispatch to the correct code path based on the type
|
||||
path =
|
||||
if spec.type == "Git" then
|
||||
mkGitSource spec
|
||||
mkGitSource fetchers spec
|
||||
else if spec.type == "GitRelease" then
|
||||
mkGitSource spec
|
||||
mkGitSource fetchers spec
|
||||
else if spec.type == "PyPi" then
|
||||
mkPyPiSource spec
|
||||
mkPyPiSource fetchers spec
|
||||
else if spec.type == "Channel" then
|
||||
mkChannelSource spec
|
||||
mkChannelSource fetchers spec
|
||||
else if spec.type == "Tarball" then
|
||||
mkTarballSource spec
|
||||
mkTarballSource fetchers spec
|
||||
else if spec.type == "Container" then
|
||||
mkContainerSource pkgs spec
|
||||
else
|
||||
builtins.throw "Unknown source type ${spec.type}";
|
||||
in
|
||||
spec // { outPath = mayOverride name path; };
|
||||
|
||||
mkGitSource =
|
||||
{
|
||||
fetchTarball,
|
||||
fetchGit,
|
||||
...
|
||||
}:
|
||||
{
|
||||
repository,
|
||||
revision,
|
||||
url ? null,
|
||||
submodules,
|
||||
hash,
|
||||
# branch ? null,
|
||||
...
|
||||
}:
|
||||
assert repository ? type;
|
||||
# At the moment, either it is a plain git repository (which has an url), or it is a GitHub/GitLab repository
|
||||
# In the latter case, there we will always be an url to the tarball
|
||||
if url != null && !submodules then
|
||||
builtins.fetchTarball {
|
||||
fetchTarball {
|
||||
inherit url;
|
||||
sha256 = hash; # FIXME: check nix version & use SRI hashes
|
||||
sha256 = hash;
|
||||
}
|
||||
else
|
||||
let
|
||||
@@ -93,6 +145,8 @@ let
|
||||
"https://github.com/${repository.owner}/${repository.repo}.git"
|
||||
else if repository.type == "GitLab" then
|
||||
"${repository.server}/${repository.repo_path}.git"
|
||||
else if repository.type == "Forgejo" then
|
||||
"${repository.server}/${repository.owner}/${repository.repo}.git"
|
||||
else
|
||||
throw "Unrecognized repository type ${repository.type}";
|
||||
urlToName =
|
||||
@@ -107,40 +161,89 @@ let
|
||||
"${if matched == null then "source" else builtins.head matched}${appendShort}";
|
||||
name = urlToName url revision;
|
||||
in
|
||||
builtins.fetchGit {
|
||||
fetchGit {
|
||||
rev = revision;
|
||||
inherit name;
|
||||
# hash = hash;
|
||||
inherit url submodules;
|
||||
narHash = hash;
|
||||
|
||||
inherit name submodules url;
|
||||
};
|
||||
|
||||
mkPyPiSource =
|
||||
{ url, hash, ... }:
|
||||
builtins.fetchurl {
|
||||
{ fetchurl, ... }:
|
||||
{
|
||||
url,
|
||||
hash,
|
||||
...
|
||||
}:
|
||||
fetchurl {
|
||||
inherit url;
|
||||
sha256 = hash;
|
||||
};
|
||||
|
||||
mkChannelSource =
|
||||
{ url, hash, ... }:
|
||||
builtins.fetchTarball {
|
||||
{ fetchTarball, ... }:
|
||||
{
|
||||
url,
|
||||
hash,
|
||||
...
|
||||
}:
|
||||
fetchTarball {
|
||||
inherit url;
|
||||
sha256 = hash;
|
||||
};
|
||||
|
||||
mkTarballSource =
|
||||
{ fetchTarball, ... }:
|
||||
{
|
||||
url,
|
||||
locked_url ? url,
|
||||
hash,
|
||||
...
|
||||
}:
|
||||
builtins.fetchTarball {
|
||||
fetchTarball {
|
||||
url = locked_url;
|
||||
sha256 = hash;
|
||||
};
|
||||
|
||||
mkContainerSource =
|
||||
pkgs:
|
||||
{
|
||||
image_name,
|
||||
image_tag,
|
||||
image_digest,
|
||||
...
|
||||
}:
|
||||
if pkgs == null then
|
||||
builtins.throw "container sources require passing in a Nixpkgs value: https://github.com/andir/npins/blob/master/README.md#using-the-nixpkgs-fetchers"
|
||||
else
|
||||
pkgs.dockerTools.pullImage {
|
||||
imageName = image_name;
|
||||
imageDigest = image_digest;
|
||||
finalImageTag = image_tag;
|
||||
};
|
||||
in
|
||||
if version == 5 then
|
||||
builtins.mapAttrs mkSource data.pins
|
||||
else
|
||||
throw "Unsupported format version ${toString version} in sources.json. Try running `npins upgrade`"
|
||||
mkFunctor (
|
||||
{
|
||||
input ? ./sources.json,
|
||||
}:
|
||||
let
|
||||
data =
|
||||
if builtins.isPath input then
|
||||
# while `readFile` will throw an error anyways if the path doesn't exist,
|
||||
# we still need to check beforehand because *our* error can be caught but not the one from the builtin
|
||||
# *piegames sighs*
|
||||
if builtins.pathExists input then
|
||||
builtins.fromJSON (builtins.readFile input)
|
||||
else
|
||||
throw "Input path ${toString input} does not exist"
|
||||
else if builtins.isAttrs input then
|
||||
input
|
||||
else
|
||||
throw "Unsupported input type ${builtins.typeOf input}, must be a path or an attrset";
|
||||
version = data.version;
|
||||
in
|
||||
if version == 7 then
|
||||
builtins.mapAttrs (name: spec: mkFunctor (mkSource name spec)) data.pins
|
||||
else
|
||||
throw "Unsupported format version ${toString version} in sources.json. Try running `npins upgrade`"
|
||||
)
|
||||
@@ -1,7 +1,11 @@
|
||||
{
|
||||
lib,
|
||||
dotnet-sdk,
|
||||
env,
|
||||
deps,
|
||||
pkgs,
|
||||
netrcConfig,
|
||||
nix-gitignore,
|
||||
packageSources,
|
||||
dotnet-sdk,
|
||||
dotnet-runtime,
|
||||
buildDotnetModule,
|
||||
}:
|
||||
@@ -13,7 +17,7 @@ let
|
||||
);
|
||||
version = builtins.head versionMatch;
|
||||
in
|
||||
buildDotnetModule {
|
||||
buildDotnetModule rec {
|
||||
inherit
|
||||
dotnet-sdk
|
||||
dotnet-runtime
|
||||
@@ -23,10 +27,21 @@ buildDotnetModule {
|
||||
;
|
||||
name = "Poseidon.Api";
|
||||
pname = "Poseidon.Api";
|
||||
nugetDeps = ./atlantis-deps.json;
|
||||
nugetDeps = deps {
|
||||
inherit
|
||||
name
|
||||
pkgs
|
||||
netrcConfig
|
||||
packageSources
|
||||
;
|
||||
lockfiles = [
|
||||
../../src/Interfaces/Api/packages.lock.json
|
||||
];
|
||||
};
|
||||
doCheck = false;
|
||||
packNupkg = true;
|
||||
buildType = env;
|
||||
# packNupkg = true;
|
||||
# NOTE(mrtz): Can't package nuget without it
|
||||
# [ref](https://github.com/dotnet/fsharp/issues/12320)
|
||||
dotnetFlags = "--property:TargetsForTfmSpecificContentInPackage=";
|
||||
# dotnetFlags = "--property:TargetsForTfmSpecificContentInPackage=";
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
{
|
||||
lib,
|
||||
env,
|
||||
pkgs,
|
||||
deps,
|
||||
netrcConfig,
|
||||
nix-gitignore,
|
||||
packageSources,
|
||||
dotnet-sdk,
|
||||
dotnet-runtime,
|
||||
dotnetCorePackages,
|
||||
buildDotnetModule,
|
||||
}:
|
||||
let
|
||||
@@ -15,20 +16,31 @@ let
|
||||
);
|
||||
version = builtins.head versionMatch;
|
||||
in
|
||||
buildDotnetModule {
|
||||
buildDotnetModule rec {
|
||||
inherit
|
||||
dotnet-sdk
|
||||
dotnet-runtime
|
||||
version
|
||||
src
|
||||
projectFile
|
||||
;
|
||||
name = "Archivist";
|
||||
pname = "Archivist";
|
||||
nugetDeps = ./atlantis-deps.json;
|
||||
doCheck = false;
|
||||
|
||||
nativeBuildInputs = [
|
||||
pname = name;
|
||||
dotnet-runtime = pkgs.dotnetCorePackages.runtime_10_0;
|
||||
dotnetRestoreFlags = "--force-evaluate";
|
||||
nugetDeps = deps {
|
||||
inherit
|
||||
name
|
||||
pkgs
|
||||
netrcConfig
|
||||
packageSources
|
||||
;
|
||||
lockfiles = [
|
||||
../../src/Archivist/src/Cli/packages.lock.json
|
||||
];
|
||||
};
|
||||
runtimeDeps = [
|
||||
pkgs.netcdf
|
||||
];
|
||||
buildType = env;
|
||||
doCheck = false;
|
||||
}
|
||||
|
||||
@@ -1,415 +0,0 @@
|
||||
[
|
||||
{
|
||||
"pname": "Dapr.Actors",
|
||||
"version": "1.15.4",
|
||||
"hash": "sha256-kRLzDebnHcAWLRhlpyIsJV/vmn3+jLG0Jsb1W1P0yyw="
|
||||
},
|
||||
{
|
||||
"pname": "Dapr.Client",
|
||||
"version": "1.15.4",
|
||||
"hash": "sha256-vYX5BvEffGrDJM1p+YHZMhI31DVsuYDqCEBO3cyxCic="
|
||||
},
|
||||
{
|
||||
"pname": "Dapr.Common",
|
||||
"version": "1.15.4",
|
||||
"hash": "sha256-DA12rEL0VmB8yxzcJ5YTgZWhsNHEl3Iwm/d7MdCuxiA="
|
||||
},
|
||||
{
|
||||
"pname": "Dapr.Protos",
|
||||
"version": "1.15.4",
|
||||
"hash": "sha256-dpVP+r8OTCYxAl2lE0NdlHkCek+OX2ITrSTp+AJb5Tc="
|
||||
},
|
||||
{
|
||||
"pname": "dotnet-outdated-tool",
|
||||
"version": "4.6.7",
|
||||
"hash": "sha256-xG0x3LSLEYHZbzul96r9UU6OPZo99SXRR9RTnbXGSr8="
|
||||
},
|
||||
{
|
||||
"pname": "Drifters.Api",
|
||||
"version": "6.19.2",
|
||||
"hash": "sha256-emAjyWKrDwgu9CElPnpMrx3HgibqFLY95QJFZCB93nQ=",
|
||||
"url": "https://gitlab.com/api/v4/projects/37086336/packages/nuget/download/drifters.api/6.19.2/drifters.api.6.19.2.nupkg"
|
||||
},
|
||||
{
|
||||
"pname": "Fable",
|
||||
"version": "4.25.0",
|
||||
"hash": "sha256-1T6cJKODI5Rm6Ze0f7X/Ecdrrn1NulKSnO3lMW73W0M="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.AST",
|
||||
"version": "4.2.1",
|
||||
"hash": "sha256-8ivlkonyH7E2UieVCadhxJtpmyxY0vkhlOg4EJKPvx4="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.Blob",
|
||||
"version": "1.0.0",
|
||||
"hash": "sha256-j3NdnEUT4WxQjQnygGUeu1Ri2ln1R5Qe/rnd0o0Z9qo="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.Blob",
|
||||
"version": "1.1.0",
|
||||
"hash": "sha256-7vbzHTnQMaQKdIVKBnPymW8oIJX4JglFmBc6E3buMW0="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.Blob",
|
||||
"version": "1.1.4",
|
||||
"hash": "sha256-NH0maz+vS0lLLcl0ttVPtqxTodE0IMGJ4QWUQegcAqs="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.Blob",
|
||||
"version": "1.2.0",
|
||||
"hash": "sha256-5SNsyfcL7i/ctDxgWCBKR0N3IwNSLfGWghKdhVuHb+g="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.Blob",
|
||||
"version": "1.3.0",
|
||||
"hash": "sha256-g6zafxbBJvV+Pp1H/t7mskYROXx/u5ke5dv1XnXO1DE="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.Blob",
|
||||
"version": "1.4.0",
|
||||
"hash": "sha256-0oLelzzor71cvBeb1R47Ozkg5hQeqo5RxGrXG8G3bkA="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.Dom",
|
||||
"version": "1.0.0",
|
||||
"hash": "sha256-oY/huCImKf+W3uN2asjaRPdyN3BWLJlWhZyGg7rFtag="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.Dom",
|
||||
"version": "2.14.0",
|
||||
"hash": "sha256-bANfm6g6Ngtm782P3u0TtJ5JjBJspnUsBMCXPSdlxz4="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.Dom",
|
||||
"version": "2.16.0",
|
||||
"hash": "sha256-ESa99JVQ/80a/XuEwmvrRun34JEOGpfMzlVrocQeH1U="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.Dom",
|
||||
"version": "2.17.0",
|
||||
"hash": "sha256-Ud2Qxnwipuc/8xV0YY+LkLP1WJiy02numohTRtegals="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.Dom",
|
||||
"version": "2.18.0",
|
||||
"hash": "sha256-OGazXYi6KcJt4cHJBv9MOYCOs4Ct/H5nKMtO8jjBqg8="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.Dom",
|
||||
"version": "2.4.4",
|
||||
"hash": "sha256-414N5oHz1u0gBkJW+EarRR8E4elKAm2s3tVCnZX0KM4="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.Event",
|
||||
"version": "1.0.0",
|
||||
"hash": "sha256-KqJYRausyk0bM8HBvha2uNS0OQSYorTek9HM+h6edSc="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.Event",
|
||||
"version": "1.4.4",
|
||||
"hash": "sha256-SOA47R1wmWm3CD92w4e57/nHvKF7V7tSRvfPHRahG+k="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.Event",
|
||||
"version": "1.5.0",
|
||||
"hash": "sha256-w2YQUtqTRnssiXiDrp0e2WzsydbjXSDlTrWfANuxsEM="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.Event",
|
||||
"version": "1.6.0",
|
||||
"hash": "sha256-psHNKghiH4qkB7/3d1ehCf1H/cW5DAGuKQWW3SEL7nQ="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.Event",
|
||||
"version": "1.7.0",
|
||||
"hash": "sha256-XENjfVqLWRtiUytplFZI8sWKGgpRg3LVsCTqTqsY5Pc="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.Gamepad",
|
||||
"version": "1.0.3",
|
||||
"hash": "sha256-Sh+bNU9+NdJ9KXv6jn8nH1YWgmVYvk1DxpskHgNGBYM="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.Gamepad",
|
||||
"version": "1.1.0",
|
||||
"hash": "sha256-0V8Y2Vm6+9TCOxQWEAzgEt1847UjK1MSg9rddWGURCk="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.Gamepad",
|
||||
"version": "1.3.0",
|
||||
"hash": "sha256-diYYi5a3zzuKEeQqXVV+i9u8JJQKJKrZyXGpF2YodhU="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.IndexedDB",
|
||||
"version": "2.2.0",
|
||||
"hash": "sha256-JKOFxMNx2yiDpxWobd6iYLZIMkT2efbWkU6g4Xt1h6I="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.WebGL",
|
||||
"version": "1.3.0",
|
||||
"hash": "sha256-I+24Sh7J7ouuAgej+khStbRB05luZlg26ljbfUAhQUk="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.WebStorage",
|
||||
"version": "1.0.0",
|
||||
"hash": "sha256-OpNJHSPVkXpELdI+ExdgcGjEsYUhn1kW7pJGHxSnv3c="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.WebStorage",
|
||||
"version": "1.0.4",
|
||||
"hash": "sha256-d5jFgiNAEl2btC63CbC4xgr5J1jgSPqr/pP/NIwZejY="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.WebStorage",
|
||||
"version": "1.2.0",
|
||||
"hash": "sha256-Sobhu9db8/hDm+hta1FZwccuBcGxhtYIFgmIQS5Og34="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.WebStorage",
|
||||
"version": "1.3.0",
|
||||
"hash": "sha256-wV3rJoBAIH0tA7O251dnLKynblWPDWs/TW+gYhL/NQ4="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.XMLHttpRequest",
|
||||
"version": "1.0.0",
|
||||
"hash": "sha256-9MzCAmJVqTs5yItRcNBf1i2JtluUrXTuGEb0MaVHqGI="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Browser.XMLHttpRequest",
|
||||
"version": "1.1.0",
|
||||
"hash": "sha256-misbm8JOPebyFaDfdxF08uitAtvjc8arb8YaTRsDFcg="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Core",
|
||||
"version": "4.4.0",
|
||||
"hash": "sha256-cRSN1zRZx5cSeZ+kj76/PKs0zZsJRiDV4m53JQei7X8="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Elmish",
|
||||
"version": "4.2.0",
|
||||
"hash": "sha256-LSx5/BgNcAvGfZR1oKJra//WAHJQQUN3VNqjuQOFY/0="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Fetch",
|
||||
"version": "2.7.0",
|
||||
"hash": "sha256-9TfAu4YIRA8vBH7wROGtp8AP41IU7TKL3IR8w4lB8xo="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Lit",
|
||||
"version": "1.6.2-oceanbox",
|
||||
"hash": "sha256-0H+OmdqnvgyxBIY9+1lNi9luj70COiyahj9Yp26w5hs=",
|
||||
"url": "https://gitlab.com/api/v4/projects/61744837/packages/nuget/download/fable.lit/1.6.2-oceanbox/fable.lit.1.6.2-oceanbox.nupkg"
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Lit.Elmish",
|
||||
"version": "1.6.2-oceanbox",
|
||||
"hash": "sha256-Hp8zwu04hnx4FEs7nUXH4YTcdD/I9jy1e/hgQ6nLGxI=",
|
||||
"url": "https://gitlab.com/api/v4/projects/61744837/packages/nuget/download/fable.lit.elmish/1.6.2-oceanbox/fable.lit.elmish.1.6.2-oceanbox.nupkg"
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Lit.React",
|
||||
"version": "1.6.2-oceanbox",
|
||||
"hash": "sha256-CvwsSGCba26KplbypqPinpkPDJu9lVOsW0fg8zbw8v0=",
|
||||
"url": "https://gitlab.com/api/v4/projects/61744837/packages/nuget/download/fable.lit.react/1.6.2-oceanbox/fable.lit.react.1.6.2-oceanbox.nupkg"
|
||||
},
|
||||
{
|
||||
"pname": "Fable.OpenLayers",
|
||||
"version": "2.18.0",
|
||||
"hash": "sha256-nHzWmlRXkzidCD9a0cf4iPvw9UYH4N3WjbnwgnlWFi0=",
|
||||
"url": "https://gitlab.com/api/v4/projects/36202053/packages/nuget/download/fable.openlayers/2.18.0/fable.openlayers.2.18.0.nupkg"
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Parsimmon",
|
||||
"version": "4.0.0",
|
||||
"hash": "sha256-SqPKrSUUavanxXuB8XLp+31Ey+aC6KIZelvSw4CHNKk="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Promise",
|
||||
"version": "3.2.0",
|
||||
"hash": "sha256-E5sV1LTsZn1as3ndNHixNvNIrXX7lTN3TWcKyiFelM4="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.React",
|
||||
"version": "9.4.0",
|
||||
"hash": "sha256-eqNjSExYTvWv6mMqXLBk6yU8wCjpwnWxLQgSWRU60DY="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.React.Types",
|
||||
"version": "18.3.0",
|
||||
"hash": "sha256-08kHLsUSHIgu85bAQ8dnCV44YUUlFjYULQo6dfZrfQA="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.ReactDom.Types",
|
||||
"version": "18.2.0",
|
||||
"hash": "sha256-32EA2PxwDuctsTt3bNfLWwM3AoiEN9CeH+SLUaHlAKY="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Remoting.Client",
|
||||
"version": "7.32.0",
|
||||
"hash": "sha256-iCrLPVyNq0M5TmJW//9zdVtGcuieV5D7XQlHgEq9AKE="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.Remoting.MsgPack",
|
||||
"version": "1.24.0",
|
||||
"hash": "sha256-6aLdGW8K+KKjs9GJvvahu6Uq/JA6XkdoTkKpkKARu7M="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.SignalR",
|
||||
"version": "2.1.0",
|
||||
"hash": "sha256-1ydTareEJaHJJ8keJpn0AHHsoi4niHaDcbSx0D6I19E=",
|
||||
"url": "https://gitlab.com/api/v4/projects/40255650/packages/nuget/download/fable.signalr/2.1.0/fable.signalr.2.1.0.nupkg"
|
||||
},
|
||||
{
|
||||
"pname": "Fable.SignalR.Elmish",
|
||||
"version": "2.1.0",
|
||||
"hash": "sha256-88QWEA3iE8q72oIobuXs18to1StEjchZ9IJq4lz1H3E=",
|
||||
"url": "https://gitlab.com/api/v4/projects/40255650/packages/nuget/download/fable.signalr.elmish/2.1.0/fable.signalr.elmish.2.1.0.nupkg"
|
||||
},
|
||||
{
|
||||
"pname": "Fable.SimpleHttp",
|
||||
"version": "3.6.0",
|
||||
"hash": "sha256-Q4uQfFMUS+W+E1uvDDZ9nP75s/QwvqJSBl/D/Fv2faY="
|
||||
},
|
||||
{
|
||||
"pname": "Fable.SimpleJson",
|
||||
"version": "3.24.0",
|
||||
"hash": "sha256-G9Ny3N5md5nMPUibOCbiKDthz2Vs00n6HNxEYrJzrWs="
|
||||
},
|
||||
{
|
||||
"pname": "fantomas",
|
||||
"version": "7.0.2",
|
||||
"hash": "sha256-BAaENIm/ksTiXrUImRgKoIXTGIlgsX7ch6ayoFjhJXA="
|
||||
},
|
||||
{
|
||||
"pname": "Feliz",
|
||||
"version": "2.9.0",
|
||||
"hash": "sha256-pkpfzLQiAkTMMidKDLTTu+CthpfXX1OqgIhn8rG/2BI="
|
||||
},
|
||||
{
|
||||
"pname": "Feliz.CompilerPlugins",
|
||||
"version": "2.2.0",
|
||||
"hash": "sha256-x9dNiwpI4HKfV+YYSK2+HrmwIT2gs1hxXM1x2PM7UoA="
|
||||
},
|
||||
{
|
||||
"pname": "FSharp.Core",
|
||||
"version": "9.0.201",
|
||||
"hash": "sha256-38Y0QFg/knogSJtxDVpVXKo5n4zAo8zaffeT6tbhahk="
|
||||
},
|
||||
{
|
||||
"pname": "Google.Api.CommonProtos",
|
||||
"version": "2.2.0",
|
||||
"hash": "sha256-K8kshR/N9wKfnxGfd6lOTvNk4oRoIabyvx0D7MZNXDU="
|
||||
},
|
||||
{
|
||||
"pname": "Google.Protobuf",
|
||||
"version": "3.13.0",
|
||||
"hash": "sha256-Oix2B0nMCG/CoJW7BqjS0+eZNl2RYGDF61pgiENJEVQ="
|
||||
},
|
||||
{
|
||||
"pname": "Google.Protobuf",
|
||||
"version": "3.30.2",
|
||||
"hash": "sha256-GbyaRLeBNyvJrx4+SkgewClk1nCTtdE7sNqnSjk8VBM="
|
||||
},
|
||||
{
|
||||
"pname": "Grpc.Core.Api",
|
||||
"version": "2.71.0",
|
||||
"hash": "sha256-OEA0FHDwIlegydD1+Ml5erYx4qTQnkL6NCpxq3r2InM="
|
||||
},
|
||||
{
|
||||
"pname": "Grpc.Net.Client",
|
||||
"version": "2.71.0",
|
||||
"hash": "sha256-qswuDuRoMSkXlVOIex9KTfTagRhzfoIBCV5GO7RddoA="
|
||||
},
|
||||
{
|
||||
"pname": "Grpc.Net.Common",
|
||||
"version": "2.71.0",
|
||||
"hash": "sha256-TEPDYKHR6b9iJtmEULjWtJZLBPIw2RO6/6HSNV1SMNI="
|
||||
},
|
||||
{
|
||||
"pname": "Matplotlib.ColorMaps",
|
||||
"version": "3.0.1",
|
||||
"hash": "sha256-zZ9w0g1hhDSZbXoIdd7GnB+VARpp8bu3ybZGu8iqS7g=",
|
||||
"url": "https://gitlab.com/api/v4/projects/36675671/packages/nuget/download/matplotlib.colormaps/3.0.1/matplotlib.colormaps.3.0.1.nupkg"
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Extensions.Configuration",
|
||||
"version": "6.0.1",
|
||||
"hash": "sha256-v55PAURxnSGYgbv9x+4/pMeI51H27ikRfHBuUB+N5nE="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Extensions.Configuration.Abstractions",
|
||||
"version": "6.0.0",
|
||||
"hash": "sha256-Evg+Ynj2QUa6Gz+zqF+bUyfGD0HI5A2fHmxZEXbn3HA="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Extensions.DependencyInjection",
|
||||
"version": "6.0.0",
|
||||
"hash": "sha256-gZuMaunMJVyvvepuzNodGPRc6eqKH//bks3957dYkPI="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Extensions.DependencyInjection",
|
||||
"version": "8.0.1",
|
||||
"hash": "sha256-O9g0jWS+jfGoT3yqKwZYJGL+jGSIeSbwmvomKDC3hTU="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Extensions.DependencyInjection.Abstractions",
|
||||
"version": "6.0.0",
|
||||
"hash": "sha256-SZke0jNKIqJvvukdta+MgIlGsrP2EdPkkS8lfLg7Ju4="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Extensions.DependencyInjection.Abstractions",
|
||||
"version": "8.0.2",
|
||||
"hash": "sha256-UfLfEQAkXxDaVPC7foE/J3FVEXd31Pu6uQIhTic3JgY="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Extensions.Http",
|
||||
"version": "6.0.0",
|
||||
"hash": "sha256-JVUjIgj7kblLhiEPsbL1psav8pWrKmjB5Csr4d3GuvM="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Extensions.Logging",
|
||||
"version": "6.0.0",
|
||||
"hash": "sha256-8WsZKRGfXW5MsXkMmNVf6slrkw+cR005czkOP2KUqTk="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Extensions.Logging.Abstractions",
|
||||
"version": "6.0.0",
|
||||
"hash": "sha256-QNqcQ3x+MOK7lXbWkCzSOWa/2QyYNbdM/OEEbWN15Sw="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Extensions.Logging.Abstractions",
|
||||
"version": "6.0.4",
|
||||
"hash": "sha256-lmupgJs9PNzpMfe1LcxY903S6LwiaR8Zm+dOK7JaTV4="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Extensions.Options",
|
||||
"version": "6.0.0",
|
||||
"hash": "sha256-DxnEgGiCXpkrxFkxXtOXqwaiAtoIjA8VSSWCcsW0FwE="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Extensions.Primitives",
|
||||
"version": "6.0.0",
|
||||
"hash": "sha256-AgvysszpQ11AiTBJFkvSy8JnwIWTj15Pfek7T7ThUc4="
|
||||
},
|
||||
{
|
||||
"pname": "System.Diagnostics.DiagnosticSource",
|
||||
"version": "6.0.0",
|
||||
"hash": "sha256-RY9uWSPdK2fgSwlj1OHBGBVo3ZvGQgBJNzAsS5OGMWc="
|
||||
},
|
||||
{
|
||||
"pname": "System.Runtime.CompilerServices.Unsafe",
|
||||
"version": "6.0.0",
|
||||
"hash": "sha256-bEG1PnDp7uKYz/OgLOWs3RWwQSVYm+AnPwVmAmcgp2I="
|
||||
},
|
||||
{
|
||||
"pname": "Thoth.Fetch",
|
||||
"version": "3.0.1",
|
||||
"hash": "sha256-2AtKvI2cSBqyVEe1IGQf6B5KxW0VShhzhaH90YAdowc="
|
||||
},
|
||||
{
|
||||
"pname": "Thoth.Json",
|
||||
"version": "10.4.1",
|
||||
"hash": "sha256-+yxHy4ekiazO9ayfi38JBQQlBgVVWfWib65uf1Db9Cs="
|
||||
}
|
||||
]
|
||||
@@ -1,91 +1,89 @@
|
||||
{
|
||||
lib,
|
||||
bun,
|
||||
pkgs,
|
||||
deps,
|
||||
fable,
|
||||
version,
|
||||
dotnet-sdk,
|
||||
netrcConfig,
|
||||
nodeModules,
|
||||
nix-gitignore,
|
||||
packageSources,
|
||||
dotnet-runtime,
|
||||
buildDotnetModule,
|
||||
sources ? import ../../npins,
|
||||
}:
|
||||
let
|
||||
mkBunNodeModules = pkgs.callPackage "${sources.bun2nix}/nix/lib/mkBunNodeModules.nix" { };
|
||||
mkBunDerivation = pkgs.callPackage "${sources.bun2nix}/nix/lib/mkBunDerivation.nix" {
|
||||
inherit mkBunNodeModules;
|
||||
};
|
||||
root = ../../.;
|
||||
|
||||
root = nix-gitignore.gitignoreSource [ ] ../../.;
|
||||
pname = "Atlantis-Client";
|
||||
src = nix-gitignore.gitignoreSource [ ] root;
|
||||
# src = lib.cleanSource root;
|
||||
|
||||
src = root;
|
||||
pname = "Atlantis";
|
||||
|
||||
nodeDeps = mkBunDerivation {
|
||||
pname = "atlantis-node-deps";
|
||||
version = "0.0.0";
|
||||
src = root;
|
||||
bunNix = ./bun.nix;
|
||||
|
||||
# Only install dependencies, don't build
|
||||
buildPhase = ''
|
||||
echo "Dependencies installed"
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out
|
||||
cp -r node_modules $out/
|
||||
'';
|
||||
};
|
||||
|
||||
atlantis-client = buildDotnetModule {
|
||||
inherit dotnet-sdk dotnet-runtime;
|
||||
inherit src version;
|
||||
pname = "${pname}-client";
|
||||
|
||||
projectFile = "src/Atlantis/src/Client/Client.fsproj";
|
||||
nugetDeps = ./atlantis-client.json; # nix-build -A packages.atlantis-client.fetch-deps && ./result src/Atlantis/nix/atlantis-client.json
|
||||
|
||||
# Skip the default dotnet build since we're using Fable
|
||||
dontDotnetBuild = true;
|
||||
|
||||
buildInputs = [
|
||||
pkgs.fable
|
||||
pkgs.bun
|
||||
];
|
||||
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
|
||||
export HOME=$TMPDIR
|
||||
|
||||
cp -r ${nodeDeps}/node_modules ./.
|
||||
chmod -R u+rw node_modules
|
||||
|
||||
chmod -R u+x node_modules/.bin
|
||||
patchShebangs node_modules/.bin
|
||||
export PATH="$PWD/node_modules/.bin:$PATH"
|
||||
|
||||
cd src/Atlantis/src/Client
|
||||
|
||||
# NOTE(mrtz): Uses fable from nixpkgs instead of dotnet (Could be out of sync).
|
||||
${pkgs.fable}/bin/fable -e .jsx -o build --test:MSBuildCracker --optimize
|
||||
|
||||
# Run vite from the Atlantis directory with proper config, always bundle for prod
|
||||
${pkgs.bun}/bin/bun ../../../../node_modules/.bin/vite build -c ../../vite.config.js --emptyOutDir --outDir dist/public --mode production
|
||||
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
# Copy output (*.js, *.css and *.html) to `/public`.
|
||||
mkdir -p $out/public
|
||||
cp -r dist/public/* $out/public/
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
dontPatchELF = true;
|
||||
dontStrip = true;
|
||||
};
|
||||
in
|
||||
atlantis-client
|
||||
buildDotnetModule {
|
||||
inherit dotnet-sdk dotnet-runtime;
|
||||
inherit src version;
|
||||
pname = "${pname}-Client";
|
||||
|
||||
projectFile = "src/Atlantis/src/Client/Client.fsproj";
|
||||
dotnetRestoreFlags = "--force-evaluate";
|
||||
# nugetDeps = ./atlantis-client.json; # nix-build -A packages.atlantis-client.fetch-deps && ./result src/Atlantis/nix/atlantis-client.json
|
||||
nugetDeps = deps {
|
||||
inherit
|
||||
pkgs
|
||||
netrcConfig
|
||||
packageSources
|
||||
;
|
||||
name = "${pname}-Client";
|
||||
lockfiles = [
|
||||
../../src/Atlantis/src/Client/packages.lock.json
|
||||
];
|
||||
};
|
||||
|
||||
# Skip the default dotnet build since we're using Fable
|
||||
dontDotnetBuild = true;
|
||||
|
||||
buildInputs = [
|
||||
fable
|
||||
bun
|
||||
];
|
||||
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
|
||||
export HOME=$TMPDIR
|
||||
|
||||
cp -r ${nodeModules}/node_modules ./.
|
||||
chmod -R u+rw node_modules
|
||||
|
||||
chmod -R u+x node_modules/.bin
|
||||
patchShebangs node_modules/.bin
|
||||
export PATH="./node_modules/.bin:$PATH"
|
||||
|
||||
cd src/Atlantis/src/Client
|
||||
|
||||
# NOTE(mrtz): Uses fable from nixpkgs instead of dotnet (Could be out of sync). --MSBuildCracker
|
||||
${lib.getExe fable} -e .jsx -o build
|
||||
|
||||
# Run vite from the Atlantis directory with proper config, always bundle for prod
|
||||
${lib.getExe bun} ../../../../node_modules/.bin/vite build -c ../../vite.config.js --outDir dist/public --mode Production
|
||||
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
# Copy output (*.js, *.css and *.html) to `/public`.
|
||||
mkdir -p $out/public
|
||||
cp -r dist/public/* $out/public/
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
dontFixup = true;
|
||||
dontPatchELF = true;
|
||||
dontStrip = true;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,13 +1,16 @@
|
||||
{
|
||||
# lib,
|
||||
debug,
|
||||
env,
|
||||
pkgs,
|
||||
deps,
|
||||
version,
|
||||
dotnet-sdk,
|
||||
netrcConfig,
|
||||
nix-gitignore,
|
||||
packageSources,
|
||||
dotnet-sdk,
|
||||
dotnet-runtime,
|
||||
buildDotnetModule,
|
||||
}:
|
||||
buildDotnetModule {
|
||||
buildDotnetModule rec {
|
||||
inherit
|
||||
version
|
||||
dotnet-sdk
|
||||
@@ -17,13 +20,27 @@ buildDotnetModule {
|
||||
pname = "Atlantis";
|
||||
# NOTE(mrtz): Ensures reproducibility and reduces closure size,
|
||||
# by filtering out irrelevant files and `.git` which changes between commits.
|
||||
src = nix-gitignore.gitignoreSource [ ] ../../.;
|
||||
# NOTE(mrtz): Needed for running `updates-deps` which relies on the Nuget.Config
|
||||
# src = lib.cleanSource ../../.;
|
||||
src = nix-gitignore.gitignoreSource [ ] ../..;
|
||||
projectFile = "src/Atlantis/src/Server/Server.fsproj";
|
||||
nugetDeps = ./atlantis-deps.json; # nix-build -A default.fetch-deps && ./result nix/packages/atlantis-deps.json
|
||||
dotnetRestoreFlags = "--force-evaluate";
|
||||
nugetDeps = deps {
|
||||
inherit
|
||||
name
|
||||
pkgs
|
||||
netrcConfig
|
||||
packageSources
|
||||
;
|
||||
lockfiles = [
|
||||
../../src/Atlantis/src/Server/packages.lock.json
|
||||
../../src/DataAgent/src/Entity/packages.lock.json
|
||||
];
|
||||
};
|
||||
runtimeDeps = [
|
||||
pkgs.netcdf
|
||||
];
|
||||
# NOTE: Add back when we have tests
|
||||
doCheck = false;
|
||||
buildType = debug;
|
||||
buildType = env;
|
||||
# Copy `appsettings` for local build
|
||||
postBuild = ''
|
||||
mkdir -p $out/bin
|
||||
|
||||
7885
nix/packages/bun.nix
7885
nix/packages/bun.nix
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,10 @@
|
||||
{
|
||||
lib,
|
||||
dotnet-sdk,
|
||||
pkgs,
|
||||
deps,
|
||||
netrcConfig,
|
||||
nix-gitignore,
|
||||
packageSources,
|
||||
dotnet-sdk,
|
||||
dotnet-runtime,
|
||||
buildDotnetModule,
|
||||
}:
|
||||
@@ -12,21 +15,35 @@ let
|
||||
builtins.readFile (../../. + "/${projectFile}")
|
||||
);
|
||||
version = builtins.head versionMatch;
|
||||
runtimeId = "linux-x64";
|
||||
in
|
||||
buildDotnetModule {
|
||||
buildDotnetModule rec {
|
||||
inherit
|
||||
dotnet-sdk
|
||||
dotnet-runtime
|
||||
version
|
||||
src
|
||||
projectFile
|
||||
runtimeId
|
||||
;
|
||||
name = "Oceanbox.DataAgent";
|
||||
pname = "Oceanbox.DataAgent";
|
||||
nugetDeps = ./atlantis-deps.json;
|
||||
doCheck = false;
|
||||
packNupkg = true;
|
||||
dotnetRestoreFlags = "--force-evaluate";
|
||||
# NOTE(mrtz): Can't package nuget without it
|
||||
# [ref](https://github.com/dotnet/fsharp/issues/12320)
|
||||
dotnetFlags = "--property:TargetsForTfmSpecificContentInPackage=";
|
||||
nugetDeps = deps {
|
||||
inherit
|
||||
name
|
||||
pkgs
|
||||
netrcConfig
|
||||
packageSources
|
||||
;
|
||||
lockfiles = [
|
||||
../../src/DataAgent/src/Entity/packages.lock.json
|
||||
../../src/DataAgent/src/DataAgent/packages.lock.json
|
||||
];
|
||||
};
|
||||
doCheck = false;
|
||||
# packNupkg = true;
|
||||
# dotnetFlags = [ "--property:TargetsForTfmSpecificContentInPackage="];
|
||||
}
|
||||
|
||||
@@ -1,111 +1,113 @@
|
||||
{
|
||||
env,
|
||||
deps,
|
||||
pkgs,
|
||||
version,
|
||||
debug,
|
||||
dotnet-sdk,
|
||||
dotnet-runtime,
|
||||
netrcConfig ? null,
|
||||
}:
|
||||
let
|
||||
# Custom overlay to add netrc support to fetchurl
|
||||
fetchurlWithNetrcOverlay = final: prev: {
|
||||
fetchurl =
|
||||
args:
|
||||
(prev.fetchurl.override {
|
||||
inherit (pkgs) cacert; # required to avoid infinite recursion
|
||||
})
|
||||
(
|
||||
args
|
||||
// {
|
||||
netrcPhase =
|
||||
if (netrcConfig != null) then
|
||||
''
|
||||
# NOTE(mrtz): Get credentials for private nuget registries from netrcConfig
|
||||
# [ref](https://wiki.nixos.org/wiki/Enterprise)
|
||||
cat > netrc <<EOF
|
||||
${netrcConfig}
|
||||
EOF
|
||||
''
|
||||
else
|
||||
''
|
||||
# No netrc config provided, create empty netrc
|
||||
touch netrc
|
||||
'';
|
||||
}
|
||||
);
|
||||
# NOTE(mrtz): Gitlab Nuget Registry does not support groupwide fetches :/
|
||||
packageSources = import ./sources.nix;
|
||||
|
||||
nodeModules = pkgs.callPackage ./node-modules.nix {};
|
||||
|
||||
codex-client = pkgs.callPackage ../../src/Codex/src/Client {
|
||||
inherit
|
||||
deps
|
||||
dotnet-sdk
|
||||
netrcConfig
|
||||
nodeModules
|
||||
packageSources
|
||||
;
|
||||
};
|
||||
|
||||
# Apply the overlay to get pkgs with netrc support
|
||||
pkgsWithNetrc = pkgs.extend fetchurlWithNetrcOverlay;
|
||||
|
||||
# Custom buildDotnetModule with netrc support
|
||||
buildDotnetModuleWithNetrc = pkgsWithNetrc.buildDotnetModule.override {
|
||||
addNuGetDeps = pkgsWithNetrc.dotnetCorePackages.addNuGetDeps.override {
|
||||
fetchNupkg = pkgsWithNetrc.dotnetCorePackages.fetchNupkg.override {
|
||||
fetchurl = pkgsWithNetrc.fetchurl;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Use custom buildDotnetModule with netrc support
|
||||
buildDotnetModule = buildDotnetModuleWithNetrc;
|
||||
in
|
||||
{
|
||||
serverpack = pkgs.callPackage ./serverpack.nix {
|
||||
inherit
|
||||
deps
|
||||
netrcConfig
|
||||
dotnet-sdk
|
||||
dotnet-runtime
|
||||
buildDotnetModule
|
||||
packageSources
|
||||
;
|
||||
};
|
||||
|
||||
# NOTE(mrtz): It's acutally Oceanbox.DataAgent
|
||||
archmaester = pkgs.callPackage ./dataagent.nix {
|
||||
inherit
|
||||
deps
|
||||
netrcConfig
|
||||
dotnet-sdk
|
||||
dotnet-runtime
|
||||
buildDotnetModule
|
||||
packageSources
|
||||
;
|
||||
};
|
||||
|
||||
# NOTE(mrtz): It's acutally Poseidon.Api
|
||||
interfaces = pkgs.callPackage ./api.nix {
|
||||
inherit
|
||||
env
|
||||
deps
|
||||
netrcConfig
|
||||
dotnet-sdk
|
||||
dotnet-runtime
|
||||
buildDotnetModule
|
||||
packageSources
|
||||
;
|
||||
};
|
||||
|
||||
atlantis = pkgs.callPackage ./atlantis.nix {
|
||||
inherit
|
||||
env
|
||||
deps
|
||||
netrcConfig
|
||||
version
|
||||
debug
|
||||
dotnet-sdk
|
||||
dotnet-runtime
|
||||
buildDotnetModule
|
||||
packageSources
|
||||
;
|
||||
};
|
||||
|
||||
sorcerer = pkgs.callPackage ./sorcerer.nix {
|
||||
inherit
|
||||
debug
|
||||
env
|
||||
deps
|
||||
netrcConfig
|
||||
dotnet-sdk
|
||||
dotnet-runtime
|
||||
buildDotnetModule
|
||||
packageSources
|
||||
;
|
||||
};
|
||||
|
||||
archivist = pkgs.callPackage ./archivist.nix {
|
||||
inherit
|
||||
env
|
||||
deps
|
||||
netrcConfig
|
||||
dotnet-sdk
|
||||
packageSources
|
||||
;
|
||||
};
|
||||
atlantis-client = pkgs.callPackage ./atlantis-client.nix {
|
||||
inherit
|
||||
deps
|
||||
version
|
||||
dotnet-sdk
|
||||
netrcConfig
|
||||
nodeModules
|
||||
dotnet-runtime
|
||||
buildDotnetModule
|
||||
packageSources
|
||||
;
|
||||
};
|
||||
|
||||
atlantis-client = pkgs.callPackage ./atlantis-client.nix {
|
||||
codex = pkgs.callPackage ../../src/Codex/src/Server {
|
||||
inherit
|
||||
version
|
||||
deps
|
||||
dotnet-sdk
|
||||
netrcConfig
|
||||
dotnet-runtime
|
||||
buildDotnetModule
|
||||
packageSources
|
||||
;
|
||||
client = codex-client;
|
||||
};
|
||||
}
|
||||
}
|
||||
52
nix/packages/node-modules.nix
Normal file
52
nix/packages/node-modules.nix
Normal file
@@ -0,0 +1,52 @@
|
||||
{
|
||||
bun,
|
||||
stdenvNoCC,
|
||||
nix-gitignore,
|
||||
writableTmpDirAsHomeHook,
|
||||
}:
|
||||
stdenvNoCC.mkDerivation {
|
||||
name = "node-modules";
|
||||
|
||||
nativeBuildInputs = [
|
||||
bun
|
||||
writableTmpDirAsHomeHook
|
||||
];
|
||||
|
||||
src = nix-gitignore.gitignoreSource [ ] ../../.;
|
||||
|
||||
dontConfigure = true;
|
||||
|
||||
# Required else we get errors that our fixed-output derivation references store paths
|
||||
dontFixup = true;
|
||||
|
||||
# Only install dependencies, don't build
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
|
||||
export BUN_INSTALL_CACHE_DIR=$(mktemp -d)
|
||||
|
||||
# Disable post-install scripts to avoid shebang issues
|
||||
bun install \
|
||||
--frozen-lockfile \
|
||||
--ignore-scripts \
|
||||
--backend copyfile \
|
||||
--no-progress \
|
||||
--force
|
||||
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
mkdir -p $out
|
||||
cp -r node_modules $out/
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
outputHashMode = "recursive";
|
||||
outputHashAlgo = "sha256";
|
||||
# NOTE: Empty this when a new dependency is added
|
||||
outputHash = "sha256-bbCaGoZRE7vRuAS3eRyP8yHANYXBJVaHmuL99BAovjY=";
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
{
|
||||
lib,
|
||||
dotnet-sdk,
|
||||
pkgs,
|
||||
deps,
|
||||
netrcConfig,
|
||||
nix-gitignore,
|
||||
packageSources,
|
||||
dotnet-sdk,
|
||||
dotnet-runtime,
|
||||
buildDotnetModule,
|
||||
}:
|
||||
@@ -13,7 +16,7 @@ let
|
||||
);
|
||||
version = builtins.head versionMatch;
|
||||
in
|
||||
buildDotnetModule {
|
||||
buildDotnetModule rec {
|
||||
inherit
|
||||
dotnet-sdk
|
||||
dotnet-runtime
|
||||
@@ -23,7 +26,17 @@ buildDotnetModule {
|
||||
;
|
||||
name = "Oceanbox.ServerPack";
|
||||
pname = "Oceanbox.ServerPack";
|
||||
nugetDeps = ./atlantis-deps.json;
|
||||
nugetDeps = deps {
|
||||
inherit
|
||||
name
|
||||
pkgs
|
||||
netrcConfig
|
||||
packageSources
|
||||
;
|
||||
lockfiles = [
|
||||
../../src/ServerPack/src/packages.lock.json
|
||||
];
|
||||
};
|
||||
packNupkg = true;
|
||||
# NOTE(mrtz): Can't package nuget without it
|
||||
# [ref](https://github.com/dotnet/fsharp/issues/12320)
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
{
|
||||
debug,
|
||||
dotnet-sdk,
|
||||
env,
|
||||
deps,
|
||||
pkgs,
|
||||
netrcConfig,
|
||||
nix-gitignore,
|
||||
packageSources,
|
||||
dotnet-sdk,
|
||||
dotnet-runtime,
|
||||
buildDotnetModule,
|
||||
}:
|
||||
@@ -14,7 +18,7 @@ let
|
||||
);
|
||||
version = builtins.head versionMatch;
|
||||
in
|
||||
buildDotnetModule {
|
||||
buildDotnetModule rec {
|
||||
inherit
|
||||
dotnet-sdk
|
||||
dotnet-runtime
|
||||
@@ -23,8 +27,24 @@ buildDotnetModule {
|
||||
projectFile
|
||||
;
|
||||
name = "Sorcerer";
|
||||
pname = "Sorcerer";
|
||||
nugetDeps = ./atlantis-deps.json;
|
||||
buildType = debug;
|
||||
pname = name;
|
||||
dotnetRestoreFlags = "--force-evaluate";
|
||||
nugetDeps = deps {
|
||||
inherit
|
||||
name
|
||||
pkgs
|
||||
netrcConfig
|
||||
packageSources
|
||||
;
|
||||
lockfiles = [
|
||||
../../src/Sorcerer/src/Server/packages.lock.json
|
||||
../../src/DataAgent/src/Entity/packages.lock.json
|
||||
];
|
||||
};
|
||||
runtimeDeps = [
|
||||
pkgs.netcdf
|
||||
];
|
||||
# TODO: Add back when we have tests
|
||||
doCheck = false;
|
||||
buildType = env;
|
||||
}
|
||||
|
||||
19
nix/packages/sources.nix
Normal file
19
nix/packages/sources.nix
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"Drifters.Api" = "https://gitlab.com/api/v4/projects/37086336/packages/nuget/download";
|
||||
"Fable.Lit" = "https://gitlab.com/api/v4/projects/61744837/packages/nuget/download";
|
||||
"Fable.Lit.Elmish" = "https://gitlab.com/api/v4/projects/61744837/packages/nuget/download";
|
||||
"Fable.Lit.React" = "https://gitlab.com/api/v4/projects/61744837/packages/nuget/download";
|
||||
"Fable.OpenLayers" = "https://gitlab.com/api/v4/projects/36202053/packages/nuget/download";
|
||||
"Fable.SignalR" = "https://gitlab.com/api/v4/projects/40255650/packages/nuget/download";
|
||||
"Fable.SignalR.AspNetCore" = "https://gitlab.com/api/v4/projects/40255650/packages/nuget/download";
|
||||
"Fable.SignalR.Elmish" = "https://gitlab.com/api/v4/projects/40255650/packages/nuget/download";
|
||||
"Fable.SignalR.Saturn" = "https://gitlab.com/api/v4/projects/40255650/packages/nuget/download";
|
||||
"Fable.SignalR.Shared" = "https://gitlab.com/api/v4/projects/40255650/packages/nuget/download";
|
||||
"Matplotlib.ColorMaps" = "https://gitlab.com/api/v4/projects/36675671/packages/nuget/download";
|
||||
"Oceanbox.DataAgent" = "https://gitlab.com/api/v4/projects/37541600/packages/nuget/download";
|
||||
"Oceanbox.FvcomKit" = "https://gitlab.com/api/v4/projects/35569541/packages/nuget/download";
|
||||
"Oceanbox.ServerPack" = "https://gitlab.com/api/v4/projects/67427353/packages/nuget/download";
|
||||
"ProjNet.FSharp" = "https://gitlab.com/api/v4/projects/35009572/packages/nuget/download";
|
||||
"Oceanbox.SDSLite" = "https://gitlab.com/api/v4/projects/34025102/packages/nuget/download";
|
||||
}
|
||||
|
||||
@@ -1,33 +1,36 @@
|
||||
let
|
||||
sources = import ../npins;
|
||||
system = builtins.currentSystem;
|
||||
pkgs = import sources.nixpkgs {
|
||||
inherit system;
|
||||
config = { };
|
||||
overlays = [ ];
|
||||
};
|
||||
sources = import ./default.nix;
|
||||
pkgs = import sources.nixpkgs { };
|
||||
pre-commit = import sources.pre-commit;
|
||||
in
|
||||
pre-commit.run {
|
||||
src = ../.;
|
||||
# Do not run at pre-commit time
|
||||
src = ./.;
|
||||
# NOTE: Do not run at pre-commit time
|
||||
default_stages = [
|
||||
"pre-push"
|
||||
];
|
||||
package = pkgs.prek;
|
||||
hooks = {
|
||||
nixfmt-rfc-style = {
|
||||
enable = true;
|
||||
package = pkgs.nixfmt-rfc-style;
|
||||
};
|
||||
statix = {
|
||||
deadnix = {
|
||||
enable = true;
|
||||
settings.ignore = [ "npins/default.nix" ];
|
||||
};
|
||||
fantomas = {
|
||||
enable = true;
|
||||
name = "fantomas";
|
||||
entry = "${pkgs.fantomas}/bin/fantomas src";
|
||||
files = "(\\.fs$)|(\\.fsx$)|(\\.fsi$)";
|
||||
package = pkgs.deadnix;
|
||||
};
|
||||
# NOTE(mrtz): Does not work with |>
|
||||
# statix = {
|
||||
# enable = true;
|
||||
# package = pkgs.statix;
|
||||
# settings.ignore = [ "../nix/default.nix" ];
|
||||
# };
|
||||
# TODO(mrtz): Format manually for now
|
||||
# fantomas = {
|
||||
# enable = true;
|
||||
# name = "fantomas";
|
||||
# entry = "${pkgs.fantomas}/bin/fantomas src";
|
||||
# files = "(\\.fs$)|(\\.fsx$)|(\\.fsi$)";
|
||||
# };
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,31 +1,34 @@
|
||||
age-encryption.org/v1
|
||||
-> ssh-ed25519 7bzzBw bb4FQMLrwLPBzGHpeURlIpPuVt4pgtkzERamH0gDqhw
|
||||
wy6PZlLLi/YWaGaPk7LxFoQOYl+LPdkEut1jOnNjTHs
|
||||
-> ssh-ed25519 7au5uA keMvx3jM8pSxU9ADnpDdXnVpWtvqGPr0EjY4YB/yJwg
|
||||
+sMhy+0Ti4JfCetFRxmxkPHZq79F/PP/CM1iPas1eLU
|
||||
-> ssh-ed25519 7bzzBw +aTkCV7hy4aJfDYbuHWFLP/1fSit2IFavOB0g2U/7EA
|
||||
w5Eu3FiX/4USe2HOXtbebv9tArwrgIvM60+N8vVFJOA
|
||||
-> ssh-ed25519 NV/uBA ynrvtm8t5Nlgpg/fJKF6svts4CcwzQxubMWzin8LHlo
|
||||
nDLJpmUsy2FX6lGWgf5p3cTQ0lMIoAOQkOIyzLhNOsA
|
||||
-> ssh-ed25519 7au5uA uq0WLcauhAx55gBHewUrVHLoZ5l1wqqNLIyc5pijgSw
|
||||
lQtu0SGM5gg+uSQkT2uVFenisKBZxYAuKkOjxodluNw
|
||||
-> ssh-rsa mafBQw
|
||||
GoS75umTeRj4notHjQxBBtn7stupiXHs4jbI8VwLhzzAKEs3QCrl8vq3jgipk8ir
|
||||
H3spAcwR/f0iaK/7QAuItRxY8DwLMcDp3kLA61edmXNgjswP5S7CZq/f7VGiNQEZ
|
||||
qDjmGxfGh9roPCXfr5JGplh6v2mOZMxpn9KhH1SAy3ku3is7QJT/HFEiHLCcaPS8
|
||||
pJkLNPfdG4g/1d4CE2tseMPRquOHwU4dMXFU1xf6CpP0leUDqPRSomlp4yhTQ6h6
|
||||
xs9C3fzxxxROsB32aXCX/n7uOKdPhVmFR/AQ4DOckTFx5QBBS5GrbKHhWWpOxJ8g
|
||||
A5sY1cjyFQy1f4W5q98AasfxgcAyFB53W5KiSjADJL6t505fq9RsMOK1hwnUq6fp
|
||||
8yWwP+nYnS9twCUdWs0N7HvV5OSgkv4BxJpgWeQHlK8ASIVi/pbVx0hw6CvLd03P
|
||||
gqGOkfVrkLuPNfjx6xya8jbzlPUkFDPCkufUSVPN+nauv/lmefC5UDfvW4EiZfb7
|
||||
lKWdqgtpUd8UUQYG2z+mFejTZKd3tjNnXuQX7A88oZbuwK0OS+e2Q60AEezH9/+z
|
||||
za6huPKwJWBo1YP3nnREBINmRH0rSYvSSvhW+X01Mupb2xoBf5ba4FAevDEMXlZh
|
||||
SfdduBF3X71dLEtrsZnwUmpNwcSKFzYHin1JugsWKiYfmiMJ0ZdIUHmneyimUgGx
|
||||
BpRlTaQyf4n6joDgNX4XhhmPafSJ6FpEmQTEy9XLUNjWPlhKLIgswS97Xm0NHab8
|
||||
wY6/ZsL1Um8008dcMeq+KjT6P7jGjifhwY97m4f8C/Pc5NZewNPPVo8l+X2F/uSd
|
||||
5cHKZCLcwwIbFfhWaJD51E2o1mf7ZvS+CgdVkO09lqb4tVABQOvWVHxzj+nh7sP6
|
||||
/LXCdzkVbopPI3XxNzn0PDIlx/mcCiv30rUqMR/9q3NS2p51YOF8FvniHesNusHE
|
||||
Kkr5rTkfUqN/MOJ0an9o+wNL7g6HPvNR3BRcyuSc5qJJ+4ZDZcPyfngNP/YVe0BN
|
||||
|
||||
-> ssh-ed25519 m/eJnA MiFdOFQKYvycaARS9cA84Pr4UKuOjKxR1tbSERmQXCk
|
||||
yZCzJ3nMqO8ySSUsqMz62ZYmaXNa3pYPwjBz5c93THM
|
||||
-> ssh-ed25519 m/eJnA JzmTs9RX/dF9p49AEKvS2e9xCSHPOWn2r7CHZ61Cd1s
|
||||
X4/Hbazgs9H9kc25HFFxFVKMU3FKAr6hj30+SoA7gHU
|
||||
-> ssh-rsa HJx+NA
|
||||
BLLqSg4Ag+LTarYo3fajiNq3Bs3XBweA55MFOTeKmWLd/WQQqY6vFMEb/4WGTHqz
|
||||
o9uPBNlVOM1N3qEphS1ltN75gBvSieQrElQnJdXt2j+dNRgHADTPj0nYDESzd+tr
|
||||
zgcT9LpBQsEitSQb0BWqtnrFAuQMZlOtwip6BNYLoN1f5dSp+r5w+Sib/4/lAeeV
|
||||
x5uSkyoy1smpi3BDLjywlLnbijyyjBDO8OYWPq2I7a0XqAabbNf4EngLp7XiMwLU
|
||||
+5mjCjo4qHDsNDzTbsiVH7IUPZeK3OMsrYVD8O2IjY6EyDOis0ibyQEwK3EZ6fAV
|
||||
Sm8qsKv4yDrXaq65ClcVjTHeN9x8d5rNR1qN8A03legbI/rt2j3n6gfUZU2tcsq/
|
||||
WwtjEdd67EMNijJMqYLjEwO/mXfGaQs5Xs37oLB72cyxvvCGuXUKGL+VaBNFD0Ss
|
||||
AbnDUmWo+S6dZipzJg6/NkOq/kWz9js4+fr+bWDgVqxsQzaX3HHQVFF9oX1GllGv
|
||||
itoNYmBciaK9n8aj51dwpV0vKSoqEBydZqhbhPvxAaHONzsfanpJz1swr/5YAVtV
|
||||
yTMKNho9dNLSsS11W5mSvyPjVu0Km8HJOyfrSkfo9nR+0SHuT5wNh0dqC9TzsUvk
|
||||
PsxCFMJaSskHS0Ir9cSSBy1ABcS4oWysR3Iqs1oMSzE
|
||||
--- PW0Q8S0QHXR01Xyyof7E0vpVgwqMTnY4M2GFLSP76v8
|
||||
D–ˆecÑ«‘óâr6…¥„ÿ‡Nùկ†¿”ìí·_C?<3F>Qtþ© A•`E’|'¾iùaì®Mý:>ΰ cKKÊ¥`æôl_Ñ^<5E>¶[4O _,êÿz:3d˜¬çœ
|
||||
L7otgs2FGW0/vMg+QoC/xK3wnD/l98cF6TVASE5NAHGwmm6CurtftoMnsQ7I6XUN
|
||||
OP3gDYWPvSnDvGkhQC39KKtGZWpCeDepicrXabySfbjJb0qEKkwekh2D9SJCCNPQ
|
||||
N3b0rL0IRuTEBkUCRyOxwIZ4jbBrfMF0TTIL6mdfg/PRIshvwb/fp3+1AFZqOxt5
|
||||
pqHTku5vVHcNzfv4CdNkeksME10W1HccK/Jwyk41Cny4xoOSnlFEsP1bJAB6h5LX
|
||||
MLmTkXMd0dwHTvLjSNbHsoOKh/a2m+LIAc70Bp4mgzv9x0gUUQcVObpJ6HZJTUvc
|
||||
JqOSzcGukUdt7zZPWDA4Ty6w422JGpq5ZTX8kCV0wTBtsT4Ne1GeMOUVFYPaoFof
|
||||
I4bQZeWnOnvqabN6mhLDx+aXSnHX07nHcvQS2c6vTH9qKIU7Ujopox2EqHClkyD6
|
||||
d2qHwem9PvWHzFKfUq3u51MTeJvQSHkK+61fIUZdjMEEQhvd/ixTavzLjmi84X0X
|
||||
XLgbJ46NEMwAWG03fys4Te9IEbXkW/gGJEC1gq4Ui9BTerfhC5F+2B51neVLm+xp
|
||||
U6K4LtjKJStrCjZL/ZJ8AJHgBgeRzMfB69OanEGJsXDP5OOz21x7ToYx2FrDxLTi
|
||||
4L0dY1WjiaI7yTeE99C08YaopjQRsGGiFfQ25ibc1kQ
|
||||
--- 84bJaUdMhO93N0qltdsWhEhKZbCma9hK7sJpUUH1N+c
|
||||
|Ðß3Å]„ÍKôsdð-<2D>Qwð•%K´D”öµj{Øá*Ç
|
||||
Š=4VÍb3·^mÙcl˜'›¼ÏøúýŒÈ¶07èƒ&AÒ·é)ZµÕÿ/ÝõoYˆ6{c¡&ø¼®ž)*¥
|
||||
@@ -10,6 +10,7 @@
|
||||
let
|
||||
user-keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII77Aa2MFZMTha8PdkNg32UR8y6Hwb4R0aR9Ad9qifNq" # Moritz
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBksFS1H6QZNQsrmWSnWuvVVaOcjvPZ0CLisWCDDDtU/" # Moritz 2
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKiAS30ZO+wgfAqDE9Y7VhRunn2QszPHA5voUwo+fGOf" # Jonas
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDULdlLC8ZLu9qBZUYsjhpr6kv5RH4yPkekXQdD7prkqapyoptUkO1nOTDwy7ZsKDxmp9Zc6OtdhgoJbowhGW3VIZPmooWO8twcaYDpkxEBLUehY/n8SlAwBtiHJ4mTLLcynJMVrjmTQLF3FeWVof0Aqy6UtZceFpLp1eNkiHTCM3anwtb9+gfr91dX1YsAOqxqv7ooRDu5rCRUvOi4OvRowepyuBcCjeWpTkJHkC9WGxuESvDV3CySWkGC2fF2LHkAu6SFsFE39UA5ZHo0b1TK+AFqRFiBAb7ULmtuno1yxhpBxbozf8+Yyc7yLfMNCyBpL1ci7WnjKkghQv7yM1xN2XMJLpF56v0slSKMoAs7ThoIlmkRm/6o3NCChgu0pkpNg/YP6A3HfYiEDgChvA6rAHX6+to50L9xF3ajqk4BUzWd/sCk7Q5Op2lzj31L53Ryg8vMP8hjDjYcgEcCCsGOcjUVgcsmfC9LupwRIEz3aF14AWg66+3zAxVho8ozjes=" # Jonas 2
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKfgY468dPNpdXZCkD9jw1p2qA0+z56Wi/c1VYE+riki" # Stig
|
||||
|
||||
49
nix/sources.json
Normal file
49
nix/sources.json
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"pins": {
|
||||
"agenix": {
|
||||
"type": "Git",
|
||||
"repository": {
|
||||
"type": "GitHub",
|
||||
"owner": "ryantm",
|
||||
"repo": "agenix"
|
||||
},
|
||||
"branch": "main",
|
||||
"submodules": false,
|
||||
"revision": "fcdea223397448d35d9b31f798479227e80183f6",
|
||||
"url": "https://github.com/ryantm/agenix/archive/fcdea223397448d35d9b31f798479227e80183f6.tar.gz",
|
||||
"hash": "sha256-wyT7Pl6tMFbFrs8Lk/TlEs81N6L+VSybPfiIgzU8lbQ="
|
||||
},
|
||||
"nix-utils": {
|
||||
"type": "Git",
|
||||
"repository": {
|
||||
"type": "Git",
|
||||
"url": "https://git.sr.ht/~mrtz/nix-utils"
|
||||
},
|
||||
"branch": "trunk",
|
||||
"submodules": false,
|
||||
"revision": "098f594425d2b9dde0657becad0f6498d074f8b3",
|
||||
"url": null,
|
||||
"hash": "sha256-y++BijM+FRkKDhVrL7YXZQiJ0DNVMiRN7yHf6QIXBUI="
|
||||
},
|
||||
"nixpkgs": {
|
||||
"type": "Channel",
|
||||
"name": "nixpkgs-unstable",
|
||||
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.05pre930822.ed142ab1b3a0/nixexprs.tar.xz",
|
||||
"hash": "sha256-XH6awru9NnBc/m+2YhRNT8r1PAKEiPGF3gs//F3ods0="
|
||||
},
|
||||
"pre-commit": {
|
||||
"type": "Git",
|
||||
"repository": {
|
||||
"type": "GitHub",
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix"
|
||||
},
|
||||
"branch": "master",
|
||||
"submodules": false,
|
||||
"revision": "a1ef738813b15cf8ec759bdff5761b027e3e1d23",
|
||||
"url": "https://github.com/cachix/git-hooks.nix/archive/a1ef738813b15cf8ec759bdff5761b027e3e1d23.tar.gz",
|
||||
"hash": "sha256-Efs3VUPelRduf3PpfPP2ovEB4CXT7vHf8W+xc49RL/U="
|
||||
}
|
||||
},
|
||||
"version": 7
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
let
|
||||
sources = import ../npins;
|
||||
system = builtins.currentSystem;
|
||||
pkgs = import sources.nixpkgs {
|
||||
inherit system;
|
||||
config = { };
|
||||
overlays = [ ];
|
||||
};
|
||||
nix-actions = import sources.nix-actions { inherit pkgs; };
|
||||
lib = pkgs.lib;
|
||||
in
|
||||
nix-actions.install {
|
||||
src = ../.;
|
||||
platform = "github";
|
||||
workflows = lib.mapAttrs' (
|
||||
name: _:
|
||||
lib.nameValuePair (lib.removeSuffix ".nix" name) (
|
||||
let
|
||||
w = import ./workflows/${name};
|
||||
args = {
|
||||
inherit nix-actions;
|
||||
inherit (pkgs) lib;
|
||||
};
|
||||
in
|
||||
if (lib.isFunction w) then (w args) else w
|
||||
)
|
||||
) (builtins.readDir ./workflows);
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
{ nix-actions, ... }:
|
||||
let
|
||||
inherit (nix-actions.lib) expr secret;
|
||||
in
|
||||
{
|
||||
name = "Build and Checks";
|
||||
on = {
|
||||
push = {
|
||||
branches = [
|
||||
"main"
|
||||
"master"
|
||||
"review/**"
|
||||
];
|
||||
tags = [
|
||||
"v*.*.*"
|
||||
"*.*.*"
|
||||
];
|
||||
};
|
||||
pull_request = {
|
||||
branches = [
|
||||
"main"
|
||||
"master"
|
||||
"review/**"
|
||||
];
|
||||
};
|
||||
workflow_dispatch = { };
|
||||
};
|
||||
env = {
|
||||
FORCE_COLOR = "1";
|
||||
NETRC = secret "NETRC";
|
||||
};
|
||||
jobs = {
|
||||
build-nix = {
|
||||
runs-on = "ubuntu-latest";
|
||||
"if" =
|
||||
"!contains(github.event.head_commit.message, 'chore(release):') && !startsWith(github.event.head_commit.message, 'WIP:') && !startsWith(github.event.head_commit.message, 'wip:') && !contains(github.event.head_commit.message, '[ci skip]') && !startsWith(github.event.head_commit.message, 'skip:') && !startsWith(github.event.head_commit.message, 'ci skip:')";
|
||||
strategy = {
|
||||
matrix = {
|
||||
package = [
|
||||
"containers.atlantis-container"
|
||||
"containers.sorcerer-container"
|
||||
];
|
||||
};
|
||||
};
|
||||
steps = [
|
||||
{
|
||||
name = "Checkout";
|
||||
uses = "actions/checkout@v4";
|
||||
"with".fetch-depth = "0"; # Fetch all history for all branches and tags
|
||||
}
|
||||
{
|
||||
name = "Set up Netrc for Package Registry";
|
||||
run = "sudo mkdir -p /etc/nix && echo ${secret "NETRC"} | sudo tee /etc/nix/netrc > /dev/null";
|
||||
}
|
||||
{
|
||||
name = "Install Nix";
|
||||
uses = "DeterminateSystems/nix-installer-action@main";
|
||||
"with" = {
|
||||
github-token = secret "GITHUB_TOKEN";
|
||||
diagnostic-endpoint = "";
|
||||
source-url = "https://install.lix.systems/lix/lix-installer-x86_64-linux";
|
||||
};
|
||||
}
|
||||
{
|
||||
name = "Set up Cache";
|
||||
uses = "DeterminateSystems/magic-nix-cache-action@main";
|
||||
}
|
||||
# {
|
||||
# name = "Set up cachix";
|
||||
# uses = "cachix/cachix-action@v16";
|
||||
# "with" = {
|
||||
# name = "poseidon";
|
||||
# authToken = "\${{ secrets.CACHIX_AUTH_TOKEN }}";
|
||||
# };
|
||||
# }
|
||||
{
|
||||
name = "Build ${expr "matrix.package"}";
|
||||
run = "nix-build default.nix -A ${expr "matrix.package"}";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
{ nix-actions, ... }:
|
||||
let
|
||||
inherit (nix-actions.lib) nix-shell secret;
|
||||
in
|
||||
{
|
||||
name = "Update dependencies";
|
||||
on = {
|
||||
schedule = [
|
||||
# Run at 06:06 on Wednesday
|
||||
# This should avoid spikes in usage caused by other scheduled jobs
|
||||
{ cron = "6 6 * * 3"; }
|
||||
];
|
||||
# Allow manual trigger
|
||||
workflow_dispatch = { };
|
||||
};
|
||||
env = {
|
||||
FORCE_COLOR = "1";
|
||||
};
|
||||
jobs = {
|
||||
update = {
|
||||
runs-on = "ubuntu-latest";
|
||||
permissions = {
|
||||
contents = "write";
|
||||
pull-requests = "write";
|
||||
issues = "write";
|
||||
};
|
||||
steps = [
|
||||
{
|
||||
uses = "actions/checkout@v4";
|
||||
"with".fetch-depth = 0;
|
||||
}
|
||||
{
|
||||
name = "Set up Netrc for Package Registry";
|
||||
run = "sudo mkdir -p /etc/nix && echo ${secret "NETRC"} | sudo tee /etc/nix/netrc > /dev/null";
|
||||
}
|
||||
{
|
||||
name = "Install Nix";
|
||||
uses = "DeterminateSystems/nix-installer-action@main";
|
||||
"with" = {
|
||||
github-token = secret "GITHUB_TOKEN";
|
||||
diagnostic-endpoint = "";
|
||||
source-url = "https://install.lix.systems/lix/lix-installer-x86_64-linux";
|
||||
};
|
||||
}
|
||||
{
|
||||
run = nix-shell {
|
||||
script = "npins update";
|
||||
shell = "npins-update";
|
||||
};
|
||||
}
|
||||
# {
|
||||
# name = "Update dependencies";
|
||||
# run = nix-shell {
|
||||
# script = ''
|
||||
# set -o pipefail
|
||||
# set -o nounset
|
||||
# set -o errexit
|
||||
|
||||
# # Build and run the update-deps script
|
||||
# nix-build -A scripts.update-deps --no-out-link
|
||||
# ./result/bin/update-deps --no-backup
|
||||
# '';
|
||||
# shell = "";
|
||||
# };
|
||||
# }
|
||||
{
|
||||
name = "Create PR";
|
||||
uses = "peter-evans/create-pull-request@v7";
|
||||
"with" = {
|
||||
token = secret "GITHUB_TOKEN";
|
||||
commit-message = "chore: npins update";
|
||||
title = "chore: weekly npins update";
|
||||
body = ''
|
||||
Automatic npins update performed by GitHub Actions
|
||||
'';
|
||||
branch = "npins-auto-update";
|
||||
delete-branch = true;
|
||||
base = "main";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
{
|
||||
"pins": {
|
||||
"agenix": {
|
||||
"type": "Git",
|
||||
"repository": {
|
||||
"type": "GitHub",
|
||||
"owner": "ryantm",
|
||||
"repo": "agenix"
|
||||
},
|
||||
"branch": "main",
|
||||
"submodules": false,
|
||||
"revision": "9edb1787864c4f59ae5074ad498b6272b3ec308d",
|
||||
"url": "https://github.com/ryantm/agenix/archive/9edb1787864c4f59ae5074ad498b6272b3ec308d.tar.gz",
|
||||
"hash": "06w2dxnf8qxwcmqvgyxnrrx62ca5x1cw3lminpgs112md17wa3rl"
|
||||
},
|
||||
"bun2nix": {
|
||||
"type": "GitRelease",
|
||||
"repository": {
|
||||
"type": "GitHub",
|
||||
"owner": "baileyluTCD",
|
||||
"repo": "bun2nix"
|
||||
},
|
||||
"pre_releases": false,
|
||||
"version_upper_bound": null,
|
||||
"release_prefix": null,
|
||||
"submodules": false,
|
||||
"version": "1.5.1",
|
||||
"revision": "85d692d68a5345d868d3bb1158b953d2996d70f7",
|
||||
"url": "https://api.github.com/repos/baileyluTCD/bun2nix/tarball/1.5.1",
|
||||
"hash": "0qqcq6dv63m3v567j7w9h7hlaj1xwnj7crw444y2cbil6h0mqjmd"
|
||||
},
|
||||
"nix-actions": {
|
||||
"type": "GitRelease",
|
||||
"repository": {
|
||||
"type": "Git",
|
||||
"url": "https://git.dgnum.eu/DGNum/nix-actions.git"
|
||||
},
|
||||
"pre_releases": false,
|
||||
"version_upper_bound": null,
|
||||
"release_prefix": null,
|
||||
"submodules": false,
|
||||
"version": "v0.5.1",
|
||||
"revision": "06847b3256df402da0475dccb290832ec92a9f8c",
|
||||
"url": null,
|
||||
"hash": "03s87spp56n1xpd14xp7j84619zpv2xxz1jj83iclzclm1s9j4yv"
|
||||
},
|
||||
"nixpkgs": {
|
||||
"type": "Channel",
|
||||
"name": "nixpkgs-unstable",
|
||||
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-25.11pre844992.32f313e49e42/nixexprs.tar.xz",
|
||||
"hash": "04wxwmhvc8y3gdkgzgh4zlwbv6jh21v3qdsmzbfy73q6ywqvb34s"
|
||||
},
|
||||
"pre-commit": {
|
||||
"type": "Git",
|
||||
"repository": {
|
||||
"type": "GitHub",
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix"
|
||||
},
|
||||
"branch": "master",
|
||||
"submodules": false,
|
||||
"revision": "4b04db83821b819bbbe32ed0a025b31e7971f22e",
|
||||
"url": "https://github.com/cachix/git-hooks.nix/archive/4b04db83821b819bbbe32ed0a025b31e7971f22e.tar.gz",
|
||||
"hash": "0hrrmkjfxgm5aa452m4lp0g6r1h1dxjv676z7miwvhc3w7aa8hr3"
|
||||
}
|
||||
},
|
||||
"version": 5
|
||||
}
|
||||
112
package.json
112
package.json
@@ -1,75 +1,79 @@
|
||||
{
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "vite src/Client",
|
||||
"build": "vite build -p",
|
||||
"test": "vite test/Client"
|
||||
},
|
||||
"version": "1.0.0",
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-node-resolve": "^16.0.1",
|
||||
"@semantic-release/changelog": "^6.0.3",
|
||||
"@semantic-release/exec": "^6.0.3",
|
||||
"@semantic-release/git": "^10.0.1",
|
||||
"@semantic-release/gitlab": "^13.2.6",
|
||||
"@sentry/vite-plugin": "^3.5.0",
|
||||
"@vitejs/plugin-react": "^5.0.0",
|
||||
"@semantic-release/gitlab": "^13.2.8",
|
||||
"@sentry/vite-plugin": "^4.3.0",
|
||||
"@vitejs/plugin-react": "^5.0.4",
|
||||
"rollup-plugin-scss": "^4.0.1",
|
||||
"sass": "^1.89.2",
|
||||
"semantic-release": "^24.2.5",
|
||||
"sass": "^1.93.0",
|
||||
"semantic-release": "^24.2.9",
|
||||
"semantic-release-dotnet": "^1.0.0",
|
||||
"vite": "npm:rolldown-vite@latest",
|
||||
"vite": "^7.1.9",
|
||||
"vite-plugin-mkcert": "^1.17.8"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fluentui/react-components": "^9.72.9",
|
||||
"@fluentui/react-datepicker-compat": "^0.6.20",
|
||||
"@fluentui/react-calendar-compat": "^0.3.15",
|
||||
"@fluentui/react-timepicker-compat": "^0.4.26",
|
||||
"@fluentui-contrib/react-data-grid-react-window": "^1.4.2",
|
||||
"@fluentui/react-icons": "^2.0.316",
|
||||
"react-window": "^2.2.3",
|
||||
"@fortawesome/fontawesome-free": "^6.7.2",
|
||||
"@lit-labs/motion": "^1.0.8",
|
||||
"@lit/context": "^1.1.5",
|
||||
"@microsoft/signalr": "^8.0.7",
|
||||
"@sentry/browser": "^9.30.0",
|
||||
"@lit/context": "^1.1.6",
|
||||
"@microsoft/signalr": "^8.0.17",
|
||||
"@sentry/browser": "^9.46.0",
|
||||
"@shoelace-style/shoelace": "^2.20.1",
|
||||
"@spectrum-web-components/accordion": "^1.7.0",
|
||||
"@spectrum-web-components/action-button": "^1.6.0",
|
||||
"@spectrum-web-components/action-group": "^1.7.0",
|
||||
"@spectrum-web-components/action-menu": "^1.7.0",
|
||||
"@spectrum-web-components/button": "^1.6.0",
|
||||
"@spectrum-web-components/card": "^1.7.0",
|
||||
"@spectrum-web-components/checkbox": "^1.6.0",
|
||||
"@spectrum-web-components/color-slider": "^1.7.0",
|
||||
"@spectrum-web-components/dialog": "^1.7.0",
|
||||
"@spectrum-web-components/divider": "^1.6.0",
|
||||
"@spectrum-web-components/field-group": "^1.6.0",
|
||||
"@spectrum-web-components/field-label": "^1.6.0",
|
||||
"@spectrum-web-components/icon": "^1.6.0",
|
||||
"@spectrum-web-components/menu": "^1.6.0",
|
||||
"@spectrum-web-components/number-field": "^1.6.0",
|
||||
"@spectrum-web-components/overlay": "^1.6.0",
|
||||
"@spectrum-web-components/popover": "^1.6.0",
|
||||
"@spectrum-web-components/progress-bar": "^1.7.0",
|
||||
"@spectrum-web-components/progress-circle": "^1.6.0",
|
||||
"@spectrum-web-components/radio": "^1.7.0",
|
||||
"@spectrum-web-components/slider": "^1.7.0",
|
||||
"@spectrum-web-components/split-view": "^1.7.0",
|
||||
"@spectrum-web-components/status-light": "^1.7.0",
|
||||
"@spectrum-web-components/styles": "^1.6.0",
|
||||
"@spectrum-web-components/switch": "^1.7.0",
|
||||
"@spectrum-web-components/table": "^1.7.0",
|
||||
"@spectrum-web-components/tabs": "^1.6.0",
|
||||
"@spectrum-web-components/theme": "^1.6.0",
|
||||
"@spectrum-web-components/toast": "^1.7.0",
|
||||
"@spectrum-web-components/tooltip": "^1.6.0",
|
||||
"@spectrum-web-components/top-nav": "^1.7.0",
|
||||
"@spectrum-web-components/underlay": "^1.6.0",
|
||||
"@spectrum-web-components/accordion": "^1.8.0",
|
||||
"@spectrum-web-components/action-button": "^1.8.0",
|
||||
"@spectrum-web-components/action-group": "^1.8.0",
|
||||
"@spectrum-web-components/action-menu": "^1.8.0",
|
||||
"@spectrum-web-components/alert-banner": "^1.8.0",
|
||||
"@spectrum-web-components/button": "^1.8.0",
|
||||
"@spectrum-web-components/card": "^1.8.0",
|
||||
"@spectrum-web-components/checkbox": "^1.8.0",
|
||||
"@spectrum-web-components/color-slider": "^1.8.0",
|
||||
"@spectrum-web-components/combobox": "^1.8.0",
|
||||
"@spectrum-web-components/contextual-help": "^1.8.0",
|
||||
"@spectrum-web-components/dialog": "^1.8.0",
|
||||
"@spectrum-web-components/divider": "^1.8.0",
|
||||
"@spectrum-web-components/field-group": "^1.8.0",
|
||||
"@spectrum-web-components/field-label": "^1.8.0",
|
||||
"@spectrum-web-components/icon": "^1.8.0",
|
||||
"@spectrum-web-components/menu": "^1.8.0",
|
||||
"@spectrum-web-components/number-field": "^1.8.0",
|
||||
"@spectrum-web-components/overlay": "^1.8.0",
|
||||
"@spectrum-web-components/popover": "^1.8.0",
|
||||
"@spectrum-web-components/progress-bar": "^1.8.0",
|
||||
"@spectrum-web-components/progress-circle": "^1.8.0",
|
||||
"@spectrum-web-components/radio": "^1.8.0",
|
||||
"@spectrum-web-components/slider": "^1.8.0",
|
||||
"@spectrum-web-components/split-view": "^1.8.0",
|
||||
"@spectrum-web-components/status-light": "^1.8.0",
|
||||
"@spectrum-web-components/styles": "^1.8.0",
|
||||
"@spectrum-web-components/switch": "^1.8.0",
|
||||
"@spectrum-web-components/table": "^1.8.0",
|
||||
"@spectrum-web-components/tabs": "^1.8.0",
|
||||
"@spectrum-web-components/theme": "^1.8.0",
|
||||
"@spectrum-web-components/toast": "^1.8.0",
|
||||
"@spectrum-web-components/tooltip": "^1.8.0",
|
||||
"@spectrum-web-components/top-nav": "^1.8.0",
|
||||
"@spectrum-web-components/underlay": "^1.8.0",
|
||||
"@turf/bezier-spline": "^7.2.0",
|
||||
"@vaadin/login": "^24.8.0",
|
||||
"lit": "^3.3.0",
|
||||
"lit-html": "^3.3.0",
|
||||
"ol": "^10.6.0",
|
||||
"lit": "^3.3.1",
|
||||
"lit-html": "^3.3.1",
|
||||
"ol": "^10.6.1",
|
||||
"plotly.js": "^2.35.3",
|
||||
"proj4": "^2.17.0",
|
||||
"proj4": "^2.19.10",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-plotly.js": "^2.6.0",
|
||||
"vis-timeline": "^7.7.4"
|
||||
"vis-timeline": "^8.4.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Development helper scripts.
|
||||
|
||||
```
|
||||
```shell
|
||||
├── update-deps.sh
|
||||
│ └─ Updates dependencies for the Poseidon project, including both .NET and npm.
|
||||
├── configure-manifests.sh
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{ sources, pkgs }:
|
||||
{ pkgs }:
|
||||
let
|
||||
inherit (pkgs.lib) mapAttrs;
|
||||
|
||||
@@ -13,18 +13,12 @@ let
|
||||
gnused
|
||||
;
|
||||
|
||||
bun2nix = import "${sources.bun2nix}/nix/package.nix" {
|
||||
flake = sources.bun2nix;
|
||||
inherit pkgs;
|
||||
};
|
||||
|
||||
scripts = {
|
||||
update-deps = [
|
||||
jaq
|
||||
coreutils
|
||||
fd
|
||||
ripgrep
|
||||
bun2nix
|
||||
];
|
||||
configure-manifests = [
|
||||
coreutils
|
||||
|
||||
@@ -60,19 +60,19 @@ declare -A PRIVATE_DEPS=(
|
||||
add_private_urls() {
|
||||
local json_file="$1"
|
||||
local temp_file="${json_file}.tmp"
|
||||
|
||||
|
||||
info "Processing private URLs for $json_file"
|
||||
|
||||
|
||||
# NOTE: Thanks in large to Claude :) for this monstrosity
|
||||
# shellcheck disable=SC2016
|
||||
local jaq_filter='map(if $private_deps[.pname] then . + {"url": ($url_map[.pname] + "/" + (.version | ascii_downcase) + "/" + (.pname | ascii_downcase) + "." + (.version | ascii_downcase) + ".nupkg")} else . end)'
|
||||
|
||||
|
||||
jaq --argjson private_deps "$(printf '%s\n' "${!PRIVATE_DEPS[@]}" | jaq -R . | jaq -s 'map({key: ., value: 1}) | from_entries')" \
|
||||
--argjson url_map "$(for pkg in "${!PRIVATE_DEPS[@]}"; do
|
||||
echo "{\"$pkg\": \"${PRIVATE_DEPS[$pkg]}\"}"
|
||||
done | jaq -s 'add')" \
|
||||
"$jaq_filter" "$json_file" > "$temp_file"
|
||||
|
||||
|
||||
if [[ -s "$temp_file" ]]; then
|
||||
mv "$temp_file" "$json_file"
|
||||
success "Updated private URLs in $json_file"
|
||||
@@ -87,20 +87,20 @@ add_private_urls() {
|
||||
update_dotnet_deps() {
|
||||
local package_name="$1"
|
||||
local json_file="$2"
|
||||
|
||||
|
||||
info "Updating .NET dependencies for $package_name"
|
||||
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
|
||||
# Run nix-build to generate new dependencies
|
||||
if nix-build -A "packages.$package_name.fetch-deps" --no-out-link > /dev/null 2>&1; then
|
||||
local result_path
|
||||
result_path=$(nix-build -A "packages.$package_name.fetch-deps" --no-out-link)
|
||||
|
||||
|
||||
# Run the result to update the JSON file
|
||||
if "$result_path" "$json_file"; then
|
||||
success "Generated new dependencies for $package_name"
|
||||
|
||||
|
||||
# Add private URLs if this JSON file has any
|
||||
if [[ -f "$json_file" ]]; then
|
||||
add_private_urls "$json_file"
|
||||
@@ -115,40 +115,18 @@ update_dotnet_deps() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to update bun dependencies
|
||||
update_bun_deps() {
|
||||
info "Updating bun dependencies"
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
# Check if bun2nix is available
|
||||
if ! command -v bun2nix &> /dev/null; then
|
||||
error "bun2nix not found in PATH. Please ensure bun2nix is installed."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Update bun.nix from the project root where package.json and bun.lock are located
|
||||
if bun2nix --lock-file "$PROJECT_ROOT/bun.lock" -o "$PACKAGES_DIR/bun.nix"; then
|
||||
success "Updated bun.nix"
|
||||
else
|
||||
error "Failed to update bun.nix"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to backup files
|
||||
backup_files() {
|
||||
local timestamp
|
||||
timestamp=$(date +%Y%m%d_%H%M%S)
|
||||
local backup_dir="$PROJECT_ROOT/.deps_backup_$timestamp"
|
||||
|
||||
|
||||
info "Creating backup in $backup_dir"
|
||||
mkdir -p "$backup_dir"
|
||||
|
||||
|
||||
cp "$PACKAGES_DIR/atlantis-deps.json" "$backup_dir/" 2>/dev/null || true
|
||||
cp "$PACKAGES_DIR/atlantis-client.json" "$backup_dir/" 2>/dev/null || true
|
||||
cp "$PACKAGES_DIR/bun.nix" "$backup_dir/" 2>/dev/null || true
|
||||
|
||||
|
||||
success "Backup created in $backup_dir"
|
||||
}
|
||||
|
||||
@@ -157,21 +135,19 @@ usage() {
|
||||
cat << EOF
|
||||
Usage: $0 [OPTIONS]
|
||||
|
||||
Update Poseidon project dependencies including .NET packages and bun dependencies.
|
||||
Update Poseidon project dependencies including .NET packages
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Show this help message
|
||||
-b, --backup Create backup before updating (default: true)
|
||||
--no-backup Skip creating backup
|
||||
--atlantis-only Update only atlantis dependencies
|
||||
--client-only Update only atlantis-client dependencies
|
||||
--bun-only Update only bun dependencies
|
||||
--client-only Update only atlantis-client dependencies
|
||||
--dry-run Show what would be updated without making changes
|
||||
|
||||
EXAMPLES:
|
||||
$0 Update all dependencies
|
||||
$0 --atlantis-only Update only atlantis server dependencies
|
||||
$0 --bun-only Update only JavaScript dependencies
|
||||
$0 --dry-run Preview changes without applying them
|
||||
|
||||
EOF
|
||||
@@ -181,9 +157,8 @@ main() {
|
||||
local create_backup=true
|
||||
local update_atlantis=true
|
||||
local update_client=true
|
||||
local update_bun=true
|
||||
local dry_run=false
|
||||
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-h|--help)
|
||||
@@ -200,17 +175,10 @@ main() {
|
||||
;;
|
||||
--atlantis-only)
|
||||
update_client=false
|
||||
update_bun=false
|
||||
shift
|
||||
;;
|
||||
--client-only)
|
||||
update_atlantis=false
|
||||
update_bun=false
|
||||
shift
|
||||
;;
|
||||
--bun-only)
|
||||
update_atlantis=false
|
||||
update_client=false
|
||||
shift
|
||||
;;
|
||||
--dry-run)
|
||||
@@ -224,9 +192,9 @@ main() {
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
|
||||
info "Starting dependency update process"
|
||||
|
||||
|
||||
if [[ "$dry_run" == "true" ]]; then
|
||||
warn "DRY RUN MODE - No files will be modified"
|
||||
if [[ "$update_atlantis" == "true" ]]; then
|
||||
@@ -235,55 +203,46 @@ main() {
|
||||
if [[ "$update_client" == "true" ]]; then
|
||||
info "Would update: atlantis-client.json"
|
||||
fi
|
||||
if [[ "$update_bun" == "true" ]]; then
|
||||
info "Would update: bun.nix"
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
# Verify we're in the right directory
|
||||
if [[ ! -f "$PROJECT_ROOT/default.nix" ]] || [[ ! -d "$PACKAGES_DIR" ]]; then
|
||||
error "This script must be run from the Poseidon project root or scripts directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# Check dependencies
|
||||
if ! command -v jaq &> /dev/null; then
|
||||
error "jaq not found in PATH. Please install jaq."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
if ! command -v nix-build &> /dev/null; then
|
||||
error "nix-build not found in PATH. Please install Nix."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# Create backup if requested
|
||||
if [[ "$create_backup" == "true" ]]; then
|
||||
backup_files
|
||||
fi
|
||||
|
||||
|
||||
# Update dependencies
|
||||
local exit_code=0
|
||||
|
||||
|
||||
if [[ "$update_atlantis" == "true" ]]; then
|
||||
if ! update_dotnet_deps "atlantis" "$PACKAGES_DIR/atlantis-deps.json"; then
|
||||
exit_code=1
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [[ "$update_client" == "true" ]]; then
|
||||
if ! update_dotnet_deps "atlantis-client" "$PACKAGES_DIR/atlantis-client.json"; then
|
||||
exit_code=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$update_bun" == "true" ]]; then
|
||||
if ! update_bun_deps; then
|
||||
exit_code=1
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [[ $exit_code -eq 0 ]]; then
|
||||
success "All dependency updates completed successfully!"
|
||||
info "You may want to commit these changes:"
|
||||
@@ -292,7 +251,7 @@ main() {
|
||||
else
|
||||
error "Some dependency updates failed. Check the output above."
|
||||
fi
|
||||
|
||||
|
||||
exit $exit_code
|
||||
}
|
||||
|
||||
|
||||
101
scripts/update-rider.sh
Executable file
101
scripts/update-rider.sh
Executable file
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/env nix-shell
|
||||
#! nix-shell -i bash --pure
|
||||
#! nix-shell -p bash which xmlstarlet
|
||||
|
||||
if [[ ! $# -eq 1 ]]; then
|
||||
echo "Usage: $0 <dotnet-path>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dotnet_path=$1
|
||||
|
||||
function stderr() {
|
||||
echo "$@" 1>&2;
|
||||
}
|
||||
|
||||
function create_settings_file() {
|
||||
cat << EOF
|
||||
<?xml version="1.0"?>
|
||||
<wpf:ResourceDictionary
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:s="clr-namespace:System;assembly=mscorlib"
|
||||
xmlns:ss="urn:schemas-jetbrains-com:settings-storage-xaml"
|
||||
xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xml:space="preserve"
|
||||
>
|
||||
<s:String x:Key="/Default/Environment/Hierarchy/Build/BuildTool/DotNetCliExePath/@EntryValue">${1}</s:String>
|
||||
<s:String x:Key="/Default/Environment/Hierarchy/Build/BuildTool/CustomBuildToolPath/@EntryValue">${2}</s:String>
|
||||
</wpf:ResourceDictionary>
|
||||
EOF
|
||||
}
|
||||
|
||||
# HACK: Configure Rider to use the correct .NET paths from an ambient .NET
|
||||
function use_rider_dotnet() {
|
||||
local solution_file=$(find . -maxdepth 1 -type f -name '*.slnx' | cut -d'.' -f2 | cut -d'/' -f2)
|
||||
local settings_file=$(find . -maxdepth 1 -type f -name '*.sln.DotSettings.user')
|
||||
# Get paths
|
||||
local cli_path=$(realpath "$dotnet_path")
|
||||
local dir=$(dirname $cli_path)
|
||||
local msbuild_path=$(find "$dir" -maxdepth 3 -type f -name MSBuild.dll)
|
||||
|
||||
# stderr "dotnet path is $dir"
|
||||
# stderr "Found msbuild: $msbuild_path"
|
||||
|
||||
if [ -f "$settings_file" ] ; then
|
||||
# stderr "Updating rider settings file: $settings_file"
|
||||
# stderr "Setting DotNetCliExePath to $cli_path"
|
||||
|
||||
# NOTE: check if dotnet binary in share folder settings exists
|
||||
xml sel -t -v "wpf:ResourceDictionary/s:String[@x:Key='/Default/Environment/Hierarchy/Build/BuildTool/DotNetCliExePath/@EntryValue']" "$settings_file"
|
||||
if [[ $? -eq 0 ]]; then
|
||||
xml ed --inplace \
|
||||
-N wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation" \
|
||||
-N x="http://schemas.microsoft.com/winfx/2006/xaml" \
|
||||
-N s="clr-namespace:System;assembly=mscorlib" \
|
||||
-N ss="urn:schemas-jetbrains-com:settings-storage-xaml" \
|
||||
--update "//s:String[@x:Key='/Default/Environment/Hierarchy/Build/BuildTool/DotNetCliExePath/@EntryValue']" \
|
||||
--value "$cli_path" \
|
||||
"$settings_file"
|
||||
else
|
||||
xml ed --inplace \
|
||||
-N wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation" \
|
||||
-N x="http://schemas.microsoft.com/winfx/2006/xaml" \
|
||||
-N s="clr-namespace:System;assembly=mscorlib" \
|
||||
-N ss="urn:schemas-jetbrains-com:settings-storage-xaml" \
|
||||
-s /wpf:ResourceDictionary -t elem -n s:String -v "$cli_path" \
|
||||
--var new_node '$prev' \
|
||||
-i '$new_node' -t attr -n "x:Key" -v "/Default/Environment/Hierarchy/Build/BuildTool/DotNetCliExePath/@EntryValue" \
|
||||
"$settings_file"
|
||||
fi
|
||||
|
||||
xml sel -t -v "wpf:ResourceDictionary/s:String[@x:Key='/Default/Environment/Hierarchy/Build/BuildTool/CustomBuildToolPath/@EntryValue']" "$settings_file"
|
||||
if [[ $? -eq 0 ]]; then
|
||||
xmlstarlet ed --inplace \
|
||||
-N wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation" \
|
||||
-N x="http://schemas.microsoft.com/winfx/2006/xaml" \
|
||||
-N s="clr-namespace:System;assembly=mscorlib" \
|
||||
-N ss="urn:schemas-jetbrains-com:settings-storage-xaml" \
|
||||
--update "//s:String[@x:Key='/Default/Environment/Hierarchy/Build/BuildTool/CustomBuildToolPath/@EntryValue']" \
|
||||
--value "$msbuild_path" \
|
||||
"$settings_file"
|
||||
else
|
||||
xml ed --inplace \
|
||||
-N wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation" \
|
||||
-N x="http://schemas.microsoft.com/winfx/2006/xaml" \
|
||||
-N s="clr-namespace:System;assembly=mscorlib" \
|
||||
-N ss="urn:schemas-jetbrains-com:settings-storage-xaml" \
|
||||
-s /wpf:ResourceDictionary -t elem -n s:String -v "$cli_path" \
|
||||
--var new_node '$prev' \
|
||||
-i '$new_node' -t attr -n "x:Key" -v "/Default/Environment/Hierarchy/Build/BuildTool/CustomBuildToolPath/@EntryValue" \
|
||||
"$settings_file"
|
||||
fi
|
||||
else
|
||||
create_settings_file $cli_path $msbuild_path > "$solution_file.sln.DotSettings.user"
|
||||
fi
|
||||
}
|
||||
|
||||
function main() {
|
||||
use_rider_dotnet
|
||||
}
|
||||
|
||||
main
|
||||
64
shell.nix
64
shell.nix
@@ -1,56 +1,68 @@
|
||||
{
|
||||
sources ? import ./npins,
|
||||
sources ? import ./nix,
|
||||
pkgs ? import sources.nixpkgs { },
|
||||
pre-commit ? import ./nix/pre-commit.nix,
|
||||
workflows ? import ./nix/workflows.nix,
|
||||
}:
|
||||
let
|
||||
# NOTE(mrtz): Should match the version in `default.nix`
|
||||
dotnet-sdk = pkgs.dotnetCorePackages.sdk_9_0;
|
||||
|
||||
dotnet-sdk = pkgs.dotnetCorePackages.sdk_10_0;
|
||||
agenix = pkgs.callPackage "${sources.agenix}/pkgs/agenix.nix" { };
|
||||
fable = pkgs.buildDotnetGlobalTool {
|
||||
pname = "fable";
|
||||
version = "4.24.0";
|
||||
nugetHash = "sha256-ERewWqfEyyZKpHFFALpMGJT0fDWywBYY5buU/wTZZTg=";
|
||||
};
|
||||
in
|
||||
pkgs.mkShellNoCC {
|
||||
# .NET
|
||||
buildInputs = [ dotnet-sdk ];
|
||||
|
||||
packages = with pkgs; [
|
||||
# Fsharp
|
||||
packages = [
|
||||
# F#
|
||||
fable
|
||||
dotnet-outdated
|
||||
fantomas
|
||||
pkgs.dotnet-outdated
|
||||
pkgs.fantomas
|
||||
pkgs.fsautocomplete
|
||||
|
||||
# JavaScript
|
||||
bun
|
||||
nodejs-slim
|
||||
pkgs.bun
|
||||
pkgs.nodejs_25
|
||||
|
||||
# Devlopment tools
|
||||
npins
|
||||
mkcert
|
||||
dive
|
||||
nix-output-monitor
|
||||
pkgs.npins
|
||||
pkgs.mkcert
|
||||
pkgs.dive
|
||||
pkgs.nix-output-monitor
|
||||
pkgs.just
|
||||
pkgs.skopeo
|
||||
|
||||
# Secret management with agenix
|
||||
agenix
|
||||
|
||||
# Kubernetes tools
|
||||
tilt
|
||||
dapr-cli
|
||||
kustomize
|
||||
kubernetes-helm
|
||||
pkgs.tilt
|
||||
pkgs.dapr-cli
|
||||
pkgs.kustomize
|
||||
pkgs.kubernetes-helm
|
||||
];
|
||||
|
||||
# Environment variables
|
||||
DOTNET_ROOT = dotnet-sdk;
|
||||
DOTNET_CLI_TELEMETRY_OPTOUT = "true";
|
||||
DOTNET_ROOT = "${dotnet-sdk}/share/dotnet";
|
||||
LOG_LEVEL = "verbose";
|
||||
|
||||
shellHook = ''
|
||||
scripts/update-rider.sh ${dotnet-sdk}/bin/dotnet
|
||||
'';
|
||||
|
||||
# Alternative shells
|
||||
passthru = pkgs.lib.mapAttrs (name: value: pkgs.mkShellNoCC (value // { inherit name; })) {
|
||||
pre-commit.shellHook = pre-commit.shellHook;
|
||||
workflows.shellHook = workflows.shellHook;
|
||||
npins-update.packages = [ pkgs.npins ];
|
||||
dotnet-shell.packages = [ dotnet-sdk ];
|
||||
ci-shell = {
|
||||
packages = [
|
||||
pkgs.npins
|
||||
];
|
||||
shellHook = ''
|
||||
export NPINS_DIRECTORY="nix"
|
||||
'';
|
||||
};
|
||||
agenix-gen = {
|
||||
packages = [ agenix ];
|
||||
shellHook = ''
|
||||
@@ -66,4 +78,4 @@ pkgs.mkShellNoCC {
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
open Fake.Core
|
||||
open Fake.IO
|
||||
open Farmer
|
||||
open Farmer.Builders
|
||||
|
||||
open Helpers
|
||||
|
||||
initializeContext()
|
||||
|
||||
let clientPath = Path.getFullName "src/Client"
|
||||
let cliPath = Path.getFullName "src/Cli"
|
||||
let testPath = Path.getFullName "tests"
|
||||
|
||||
let distPath = Path.getFullName "dist"
|
||||
|
||||
let vite = $"bunx --bun vite -c ../../vite.config.js"
|
||||
let viteBundle = $"{vite} build --outDir {distPath}/public"
|
||||
|
||||
Target.create "Clean" (fun _ -> Shell.cleanDir distPath)
|
||||
|
||||
// Target.create "Bundle" (fun _ ->
|
||||
// let vite = $"{viteBundle} -m production"
|
||||
// run dotnet $"publish -c Release -o \"{distPath}\"" serverPath
|
||||
// run dotnet $"fable -o build/client --run {vite}" clientPath
|
||||
// )
|
||||
|
||||
// Target.create "BundleDebug" (fun _ ->
|
||||
// let vite = $"{viteBundle} -m development --minify false"
|
||||
// run dotnet $"publish -c Debug -o \"{distPath}\"" serverPath
|
||||
// run dotnet $"fable -o build/client --run {vite}" clientPath
|
||||
// )
|
||||
|
||||
Target.create "Bundle" (fun _ ->
|
||||
run dotnet $"publish -c Release -o \"{distPath}\"" cliPath
|
||||
)
|
||||
|
||||
Target.create "BundleDebug" (fun _ ->
|
||||
run dotnet $"publish -c Debug -o \"{distPath}\"" cliPath
|
||||
)
|
||||
|
||||
Target.create "Format" (fun _ ->
|
||||
run dotnet "fantomas . -r" "src"
|
||||
)
|
||||
|
||||
Target.create "Test" (fun _ ->
|
||||
if System.IO.Directory.Exists testPath then
|
||||
run dotnet "run" testPath
|
||||
else ()
|
||||
)
|
||||
|
||||
Target.create "Run" (fun _ -> Target.runOrDefault "Bundle")
|
||||
|
||||
open Fake.Core.TargetOperators
|
||||
|
||||
let dependencies = [
|
||||
"Clean"
|
||||
==> "Bundle"
|
||||
|
||||
"Clean"
|
||||
==> "BundleDebug"
|
||||
|
||||
"Clean"
|
||||
==> "Test"
|
||||
]
|
||||
|
||||
[<EntryPoint>]
|
||||
let main args = runOrDefault args
|
||||
@@ -1,127 +0,0 @@
|
||||
module Helpers
|
||||
|
||||
open Fake.Core
|
||||
|
||||
let initializeContext () =
|
||||
let execContext = Context.FakeExecutionContext.Create false "build.fsx" [ ]
|
||||
Context.setExecutionContext (Context.RuntimeContext.Fake execContext)
|
||||
|
||||
module Proc =
|
||||
module Parallel =
|
||||
open System
|
||||
|
||||
let locker = obj()
|
||||
|
||||
let colors =
|
||||
[| ConsoleColor.Blue
|
||||
ConsoleColor.Yellow
|
||||
ConsoleColor.Magenta
|
||||
ConsoleColor.Cyan
|
||||
ConsoleColor.DarkBlue
|
||||
ConsoleColor.DarkYellow
|
||||
ConsoleColor.DarkMagenta
|
||||
ConsoleColor.DarkCyan |]
|
||||
|
||||
let print color (colored: string) (line: string) =
|
||||
lock locker
|
||||
(fun () ->
|
||||
let currentColor = Console.ForegroundColor
|
||||
Console.ForegroundColor <- color
|
||||
Console.Write colored
|
||||
Console.ForegroundColor <- currentColor
|
||||
Console.WriteLine line)
|
||||
|
||||
let onStdout index name (line: string) =
|
||||
let color = colors.[index % colors.Length]
|
||||
if isNull line then
|
||||
print color $"{name}: --- END ---" ""
|
||||
else if String.isNotNullOrEmpty line then
|
||||
print color $"{name}: " line
|
||||
|
||||
let onStderr name (line: string) =
|
||||
let color = ConsoleColor.Red
|
||||
if isNull line |> not then
|
||||
print color $"{name}: " line
|
||||
|
||||
let redirect (index, (name, createProcess)) =
|
||||
createProcess
|
||||
|> CreateProcess.redirectOutputIfNotRedirected
|
||||
|> CreateProcess.withOutputEvents (onStdout index name) (onStderr name)
|
||||
|
||||
let printStarting indexed =
|
||||
for (index, (name, c: CreateProcess<_>)) in indexed do
|
||||
let color = colors.[index % colors.Length]
|
||||
let wd =
|
||||
c.WorkingDirectory
|
||||
|> Option.defaultValue ""
|
||||
let exe = c.Command.Executable
|
||||
let args = c.Command.Arguments.ToStartInfo
|
||||
print color $"{name}: {wd}> {exe} {args}" ""
|
||||
|
||||
let run cs =
|
||||
cs
|
||||
|> Seq.toArray
|
||||
|> Array.indexed
|
||||
|> fun x -> printStarting x; x
|
||||
|> Array.map redirect
|
||||
|> Array.Parallel.map Proc.run
|
||||
|
||||
let createProcess exe arg dir =
|
||||
CreateProcess.fromRawCommandLine exe arg
|
||||
|> CreateProcess.withWorkingDirectory dir
|
||||
|> CreateProcess.ensureExitCode
|
||||
|
||||
let dotnet = createProcess "dotnet"
|
||||
|
||||
let fable = createProcess "fable"
|
||||
|
||||
let bun =
|
||||
let bunPath =
|
||||
match ProcessUtils.tryFindFileOnPath "bun" with
|
||||
| Some path -> path
|
||||
| None ->
|
||||
"bun was not found in path. Please install it and make sure it's available from your path. " +
|
||||
"See https://safe-stack.github.io/docs/quickstart/#install-pre-requisites for more info"
|
||||
|> failwith
|
||||
|
||||
createProcess bunPath
|
||||
|
||||
let bunx = createProcess "bunx"
|
||||
|
||||
type BundleMode =
|
||||
| Prod
|
||||
| Devel
|
||||
| Watch
|
||||
with
|
||||
override this.ToString() =
|
||||
match this with
|
||||
| Prod -> "production"
|
||||
| Devel -> "development"
|
||||
| Watch -> "watch"
|
||||
|
||||
let viteCmd (m: BundleMode) outDir =
|
||||
match m with
|
||||
| Prod -> $"vite build -c ../../vite.config.js -m {m} --emptyOutDir --outDir {outDir}/public"
|
||||
| Devel -> $"vite build -c ../../vite.config.js -m {m} --minify false --sourcemap true --emptyOutDir --outDir {outDir}/public"
|
||||
| Watch -> "vite -c ../../vite.config.js"
|
||||
|
||||
let run proc arg dir =
|
||||
proc arg dir
|
||||
|> Proc.run
|
||||
|> ignore
|
||||
|
||||
let runParallel processes =
|
||||
processes
|
||||
|> Proc.Parallel.run
|
||||
|> ignore
|
||||
|
||||
let runOrDefault args =
|
||||
try
|
||||
match args with
|
||||
| [| target |] -> Target.runOrDefault target
|
||||
| _ ->
|
||||
Target.runOrDefault "Run"
|
||||
0
|
||||
with e ->
|
||||
printfn "%A" e
|
||||
1
|
||||
@@ -1 +1,6 @@
|
||||
use nix
|
||||
#!/usr/bin/env bash
|
||||
# the shebang is ignored, but nice for editors
|
||||
use nix
|
||||
|
||||
# HACK: Workaround for direnv bug
|
||||
unset TMP TMPDIR TEMP TEMPDIR
|
||||
15
src/Archivist/.gitlab-ci.yml
Normal file
15
src/Archivist/.gitlab-ci.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
# yaml-language-server: $schema=https://gitlab.com/gitlab-org/gitlab/-/raw/master/app/assets/javascripts/editor/schema/ci.json
|
||||
variables:
|
||||
SKIP_TESTS: "true"
|
||||
|
||||
include:
|
||||
- project: oceanbox/gitlab-ci
|
||||
ref: v4.5
|
||||
file: DotnetDeployment.gitlab-ci.yml
|
||||
inputs:
|
||||
project-name: archivist
|
||||
project-dir: src/Cli
|
||||
|
||||
dockerize-archivist:
|
||||
tags:
|
||||
- nix
|
||||
@@ -1,17 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include=".build/Helpers.fs" />
|
||||
<Compile Include=".build/Build.fs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Fake.Core.Target" Version="6.1.3" />
|
||||
<PackageReference Include="Fake.DotNet.Cli" Version="6.1.3" />
|
||||
<PackageReference Include="Fake.IO.FileSystem" Version="6.1.3" />
|
||||
<PackageReference Include="Farmer" Version="1.9.10" />
|
||||
<PackageReference Update="FSharp.Core" Version="9.0.201" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
40
src/Archivist/justfile
Normal file
40
src/Archivist/justfile
Normal file
@@ -0,0 +1,40 @@
|
||||
# Archivist build commands
|
||||
# Install just: https://github.com/casey/just
|
||||
|
||||
set dotenv-load
|
||||
|
||||
src_path := "src"
|
||||
client_path := "src/Client"
|
||||
cli_path := "src/Cli"
|
||||
test_path := "tests"
|
||||
dist_path := "dist"
|
||||
|
||||
# Default recipe - show available commands
|
||||
default:
|
||||
@just --list
|
||||
|
||||
# Clean build artifacts
|
||||
clean:
|
||||
rm -rf {{dist_path}}
|
||||
|
||||
# Build production bundle
|
||||
bundle: clean
|
||||
dotnet publish -c Release -o {{dist_path}} {{cli_path}}
|
||||
|
||||
# Build debug bundle
|
||||
bundle-debug: clean
|
||||
dotnet publish -c Debug -o {{dist_path}} {{cli_path}}
|
||||
|
||||
# Format code with Fantomas
|
||||
format:
|
||||
fantomas {{src_path}} -r
|
||||
|
||||
# Run tests
|
||||
test: clean
|
||||
#!/usr/bin/env bash
|
||||
if [ -d "{{test_path}}" ]; then
|
||||
dotnet run {{test_path}}
|
||||
fi
|
||||
|
||||
# Run (builds bundle)
|
||||
run: bundle
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
sources ? import ./../../npins,
|
||||
sources ? import ./../../nix,
|
||||
pkgs ? import sources.nixpkgs { },
|
||||
}:
|
||||
let
|
||||
@@ -29,7 +29,10 @@ pkgs.mkShellNoCC {
|
||||
SERVER_PORT = port + 85;
|
||||
TILT_PORT = port + 50;
|
||||
|
||||
DOTNET_ROOT = "${pkgs.dotnetCorePackages.sdk_10_0}/share/dotnet";
|
||||
|
||||
shellHook = ''
|
||||
export PATH="$PWD/src/Cli/bin/Release/net9.0/linux-x64/:$PATH"
|
||||
export ARCHMAESTER_URL="https://$USER-atlantis.dev.oceanbox.io"
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -74,7 +74,11 @@ let addUsers (args: PrincipalArgs) =
|
||||
|
||||
async {
|
||||
try
|
||||
match! aclApi.addUsers users with
|
||||
let req : Archmaester.AddUsersRequest = {
|
||||
group = ""
|
||||
users = users
|
||||
}
|
||||
match! aclApi.addUsers req with
|
||||
| Ok _ ->
|
||||
Log.Information $"Added users %A{users}"
|
||||
return Ok ()
|
||||
|
||||
@@ -231,6 +231,7 @@ let readDriftersInputJson file =
|
||||
|
||||
let rec addArchive (args: AddArchiveArgs) =
|
||||
let basePath = getArchiveBasePath args
|
||||
Log.Information $"BasePath: %s{basePath}"
|
||||
|
||||
let idx =
|
||||
match args.Index with
|
||||
|
||||
@@ -117,7 +117,9 @@ let inline withCliAuth f =
|
||||
| None ->
|
||||
Log.Fatal "You must provide ARCHMAESTER_AUTH"
|
||||
Error "You are not logged in" |> async.Return
|
||||
| Some auth -> f auth
|
||||
| Some auth ->
|
||||
Log.Debug "You are logged in"
|
||||
f auth
|
||||
|
||||
let private (|NumSeq|_|) x =
|
||||
let rex = Text.RegularExpressions.Regex @".+[-_]([0-9]+)\..+$"
|
||||
@@ -299,7 +301,7 @@ let FvStatsArchive =
|
||||
member x.getNumFrames ds = 12 // year
|
||||
}
|
||||
|
||||
let getArchiveFiles format basePath (files: string[]) =
|
||||
let getArchiveFiles format basePath (files: string array) =
|
||||
let fs =
|
||||
if files.Length = 1 then
|
||||
Directory.GetFiles(basePath, "*.nc", SearchOption.AllDirectories)
|
||||
@@ -463,32 +465,34 @@ let initiateModelArea (idx: ArchiveIndex) (basePath: string) =
|
||||
|
||||
let getParentModelAreaId rid =
|
||||
async {
|
||||
let! parent = adminApi.getArchiveDto rid
|
||||
|
||||
match parent with
|
||||
| Ok p -> return Ok p.props.modelArea
|
||||
| Error e -> return failwith $"Could not get model area id: {e}"
|
||||
try
|
||||
let! parent = adminApi.getArchiveDto rid
|
||||
match parent with
|
||||
| Ok p ->
|
||||
return Ok p.props.modelArea
|
||||
| Error e -> return failwith $"Could not get model area id: {e}"
|
||||
with e -> return failwith $"Failed to get parent archive: %A{rid} with %A{e.Message}"
|
||||
}
|
||||
|
||||
let checkModelArea () =
|
||||
let failBadly () =
|
||||
Log.Error "Either modelArea or reference must be specified!"
|
||||
Environment.Exit 1
|
||||
failwith "Missing modelArea or reference."
|
||||
let failBadly () =
|
||||
Log.Error "Either modelArea or reference must be specified!"
|
||||
Environment.Exit 1
|
||||
failwith "Missing modelArea or reference."
|
||||
|
||||
match idx.modelArea with
|
||||
| None ->
|
||||
if idx.reference.IsSome then
|
||||
async {
|
||||
match! inventoryApi.getArchive idx.reference.Value with
|
||||
| Ok ref -> return! modelAreaApi.getModelArea ref.modelArea
|
||||
| Error e ->
|
||||
Log.Error $"{e}"
|
||||
return None
|
||||
}
|
||||
else
|
||||
failBadly ()
|
||||
| Some mid -> modelAreaApi.getModelArea mid
|
||||
match idx.modelArea with
|
||||
| None ->
|
||||
if idx.reference.IsSome then
|
||||
async {
|
||||
match! inventoryApi.getArchive idx.reference.Value with
|
||||
| Ok ref -> return! modelAreaApi.getModelArea ref.modelArea
|
||||
| Error e ->
|
||||
Log.Error $"{e}"
|
||||
return None
|
||||
}
|
||||
else
|
||||
failBadly ()
|
||||
| Some mid -> modelAreaApi.getModelArea mid
|
||||
// match model with
|
||||
// | ModelAreaId mid -> modelAreaApi.getModelArea mid
|
||||
// | ModelArea m -> tryAddModelArea m basePath
|
||||
@@ -498,7 +502,6 @@ let initiateModelArea (idx: ArchiveIndex) (basePath: string) =
|
||||
// | Ok m -> return! tryAddModelArea m basePath
|
||||
// | Error e -> return Error e
|
||||
// }
|
||||
|
||||
match idx.archiveType with
|
||||
| FvStats _
|
||||
| Atmo _ ->
|
||||
@@ -516,14 +519,11 @@ let initiateModelArea (idx: ArchiveIndex) (basePath: string) =
|
||||
| Fvcom _ ->
|
||||
async {
|
||||
let! model = modelAreaApi.getModelAreaId idx.name
|
||||
|
||||
match model with
|
||||
| Ok m ->
|
||||
Log.Debug $"Existing model area: %A{model}"
|
||||
return Ok m
|
||||
| Error _ ->
|
||||
Log.Debug "Make new model area"
|
||||
|
||||
match! checkModelArea () with
|
||||
| Some ma ->
|
||||
Log.Debug $"New model area: %A{ma}"
|
||||
@@ -631,7 +631,6 @@ let instantiateArchiveDto (idx, modelArea, basePath, files, reverse, json, publi
|
||||
}
|
||||
|
||||
let retireArchive (archive: string) =
|
||||
// TODO: retire all dependent archies
|
||||
let aid =
|
||||
try
|
||||
Guid.Parse archive
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
||||
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
|
||||
<AssemblyName>archivist</AssemblyName>
|
||||
<Version>7.1.0</Version>
|
||||
</PropertyGroup>
|
||||
@@ -17,27 +19,26 @@
|
||||
<Compile Include="Main.fs"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Fargo.CmdLine" Version="1.7.5"/>
|
||||
<PackageReference Include="FSharp.Data" Version="6.4.1"/>
|
||||
<PackageReference Include="FSharpPlus" Version="1.7.0"/>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.1"/>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.1">
|
||||
<PackageReference Include="Fargo.CmdLine" />
|
||||
<PackageReference Include="FSharp.Data" />
|
||||
<PackageReference Include="FSharpPlus" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" >
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.1">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" >
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Oceanbox.FvcomKit" Version="5.12.0"/>
|
||||
<PackageReference Include="Serilog" Version="4.2.0"/>
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0"/>
|
||||
<PackageReference Include="Serilog.Sinks.Seq" Version="9.0.0"/>
|
||||
<PackageReference Include="Thoth.Json.Net" Version="12.0.0"/>
|
||||
<PackageReference Update="FSharp.Core" Version="9.0.201"/>
|
||||
<PackageReference Include="Serilog" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" />
|
||||
<PackageReference Include="Thoth.Json.Net" />
|
||||
<PackageReference Include="FSharp.Core" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\DataAgent\src\DataAgent\Oceanbox.DataAgent.fsproj"/>
|
||||
<ProjectReference Include="..\..\..\DataAgent\src\Entity\Entity.csproj"/>
|
||||
<ProjectReference Include="..\..\..\Interfaces\Archmaester\Archmaester.Api.fsproj" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,15 +1,16 @@
|
||||
module Args
|
||||
|
||||
open System
|
||||
open System.IO
|
||||
|
||||
open Fargo
|
||||
open Fargo.Operators
|
||||
open Serilog
|
||||
open System
|
||||
open System.IO
|
||||
|
||||
open Archmaester.Dto
|
||||
|
||||
let showVersion () =
|
||||
let assembly = System.Reflection.Assembly.GetExecutingAssembly()
|
||||
let assembly = System.Reflection.Assembly.GetExecutingAssembly ()
|
||||
let version = System.Diagnostics.FileVersionInfo.GetVersionInfo assembly.Location
|
||||
printfn $"{version.FileVersion}"
|
||||
|
||||
@@ -196,7 +197,8 @@ let argParser: Arg<Command * int> =
|
||||
match Int32.TryParse s with
|
||||
| true, v when v >= 0 && v <= 4 -> Ok v
|
||||
| true, _ -> Error "Log level must be between 0 and 4"
|
||||
| false, _ -> Error "Invalid log level value")
|
||||
| false, _ -> Error "Invalid log level value"
|
||||
)
|
||||
|> defaultValue 2
|
||||
|
||||
let! version = flag "version" "v" "Show version"
|
||||
@@ -303,10 +305,13 @@ let argParser: Arg<Command * int> =
|
||||
|> optParse (fun s ->
|
||||
match Boolean.TryParse s with
|
||||
| true, v -> Ok v
|
||||
| false, _ -> Error "Invalid boolean value")
|
||||
and! files = arg "files" "Files to add" |> Pipe.orStdIn |> nonEmpty "No files to add" |> listParse (fun s ->
|
||||
if File.Exists s then Ok s
|
||||
else Error $"File '{s}' does not exist")
|
||||
| false, _ -> Error "Invalid boolean value"
|
||||
)
|
||||
and! files =
|
||||
arg "files" "Files to add"
|
||||
|> Pipe.orStdIn
|
||||
// |> nonEmpty "No files to add"
|
||||
|> listParse Ok
|
||||
return
|
||||
AddArchive {
|
||||
Index = index
|
||||
@@ -324,20 +329,23 @@ let argParser: Arg<Command * int> =
|
||||
|> optParse (fun s ->
|
||||
match Int32.TryParse s with
|
||||
| true, v -> Ok v
|
||||
| false, _ -> Error "Invalid integer value")
|
||||
| false, _ -> Error "Invalid integer value"
|
||||
)
|
||||
|> reqOpt
|
||||
and! to' =
|
||||
opt "to" null "int" "Index of last file to include"
|
||||
|> optParse (fun s ->
|
||||
match Int32.TryParse s with
|
||||
| true, v -> Ok v
|
||||
| false, _ -> Error "Invalid integer value")
|
||||
| false, _ -> Error "Invalid integer value"
|
||||
)
|
||||
and! published =
|
||||
opt "published" null "bool" "Publish archive (default: true)"
|
||||
|> optParse (fun s ->
|
||||
match Boolean.TryParse s with
|
||||
| true, v -> Ok v
|
||||
| false, _ -> Error "Invalid boolean value")
|
||||
| false, _ -> Error "Invalid boolean value"
|
||||
)
|
||||
and! name = arg "name" "Name of the new archive" |> reqArg
|
||||
return
|
||||
AddSub {
|
||||
@@ -353,15 +361,27 @@ let argParser: Arg<Command * int> =
|
||||
return AddModel { File = file }, logLevel
|
||||
| AddType.Owner ->
|
||||
let! archive = opt "archive" null "id" "Apply to archive" |> optParse parseArchiveId
|
||||
and! ids = arg "ids" "Identities" |> Pipe.orStdIn |> nonEmpty "No ids to add" |> listParse Ok
|
||||
and! ids =
|
||||
arg "ids" "Identities"
|
||||
|> Pipe.orStdIn
|
||||
|> nonEmpty "No ids to add"
|
||||
|> listParse Ok
|
||||
return AddOwner { Archive = archive; Ids = ids }, logLevel
|
||||
| AddType.User ->
|
||||
let! archive = opt "archive" null "id" "Apply to archive" |> optParse parseArchiveId
|
||||
and! ids = arg "ids" "Identities" |> Pipe.orStdIn |> nonEmpty "No ids to add" |> listParse Ok
|
||||
and! ids =
|
||||
arg "ids" "Identities"
|
||||
|> Pipe.orStdIn
|
||||
|> nonEmpty "No ids to add"
|
||||
|> listParse Ok
|
||||
return AddUser { Archive = archive; Ids = ids }, logLevel
|
||||
| AddType.Group ->
|
||||
let! archive = opt "archive" null "id" "Apply to archive" |> optParse parseArchiveId
|
||||
and! ids = arg "ids" "Identities" |> Pipe.orStdIn |> nonEmpty "No ids to add" |> listParse Ok
|
||||
and! ids =
|
||||
arg "ids" "Identities"
|
||||
|> Pipe.orStdIn
|
||||
|> nonEmpty "No ids to add"
|
||||
|> listParse Ok
|
||||
return AddGroup { Archive = archive; Ids = ids }, logLevel
|
||||
|
||||
| AddType.Type ->
|
||||
@@ -388,17 +408,29 @@ let argParser: Arg<Command * int> =
|
||||
|
||||
| DeleteType.Owner ->
|
||||
let! archive = opt "archive" null "id" "Apply to archive" |> optParse parseArchiveId
|
||||
and! ids = arg "ids" "Identities" |> Pipe.orStdIn |> nonEmpty "No ids to add" |> listParse Ok
|
||||
and! ids =
|
||||
arg "ids" "Identities"
|
||||
|> Pipe.orStdIn
|
||||
|> nonEmpty "No ids to add"
|
||||
|> listParse Ok
|
||||
return DeleteOwner { Archive = archive; Ids = ids }, logLevel
|
||||
|
||||
| DeleteType.User ->
|
||||
let! archive = opt "archive" null "id" "Apply to archive" |> optParse parseArchiveId
|
||||
and! ids = arg "ids" "Identities" |> Pipe.orStdIn |> nonEmpty "No ids to add" |> listParse Ok
|
||||
and! ids =
|
||||
arg "ids" "Identities"
|
||||
|> Pipe.orStdIn
|
||||
|> nonEmpty "No ids to add"
|
||||
|> listParse Ok
|
||||
return DeleteUser { Archive = archive; Ids = ids }, logLevel
|
||||
|
||||
| DeleteType.Group ->
|
||||
let! archive = opt "archive" null "id" "Apply to archive" |> optParse parseArchiveId
|
||||
and! ids = arg "ids" "Identities" |> Pipe.orStdIn |> nonEmpty "No ids to add" |> listParse Ok
|
||||
and! ids =
|
||||
arg "ids" "Identities"
|
||||
|> Pipe.orStdIn
|
||||
|> nonEmpty "No ids to add"
|
||||
|> listParse Ok
|
||||
return DeleteGroup { Archive = archive; Ids = ids }, logLevel
|
||||
|
||||
| DeleteType.Type ->
|
||||
@@ -419,13 +451,15 @@ let argParser: Arg<Command * int> =
|
||||
|> optParse (fun s ->
|
||||
match Boolean.TryParse s with
|
||||
| true, v -> Ok v
|
||||
| false, _ -> Error "Invalid boolean value")
|
||||
| false, _ -> Error "Invalid boolean value"
|
||||
)
|
||||
and! public' =
|
||||
opt "public" null "bool" "Make archive public (careful!)"
|
||||
|> optParse (fun s ->
|
||||
match Boolean.TryParse s with
|
||||
| true, v -> Ok v
|
||||
| false, _ -> Error "Invalid boolean value")
|
||||
| false, _ -> Error "Invalid boolean value"
|
||||
)
|
||||
and! expires = opt "expires" null "datetime" "Set expiry"
|
||||
and! json = opt "json" null "file" "Any json you fancy"
|
||||
and! fence =
|
||||
@@ -456,13 +490,15 @@ let argParser: Arg<Command * int> =
|
||||
|> optParse (fun s ->
|
||||
match Single.TryParse s with
|
||||
| true, v -> Ok v
|
||||
| false, _ -> Error "Invalid float value")
|
||||
| false, _ -> Error "Invalid float value"
|
||||
)
|
||||
and! retired =
|
||||
opt "retired" null "bool" "Retired status"
|
||||
|> optParse (fun s ->
|
||||
match Boolean.TryParse s with
|
||||
| true, v -> Ok v
|
||||
| false, _ -> Error "Invalid boolean value")
|
||||
| false, _ -> Error "Invalid boolean value"
|
||||
)
|
||||
and! polygon = opt "polygon" null "file" "Polygon file"
|
||||
and! modelArea = opt "model-area" null "id" "Model area ID" |> optParse parseModelAreaId
|
||||
and! json = opt "json" null "json" "JSON data"
|
||||
@@ -497,7 +533,8 @@ let argParser: Arg<Command * int> =
|
||||
|> optParse (fun s ->
|
||||
match Single.TryParse s with
|
||||
| true, v -> Ok v
|
||||
| false, _ -> Error "Invalid float value")
|
||||
| false, _ -> Error "Invalid float value"
|
||||
)
|
||||
and! polygon = opt "polygon" null "file" "Bounding polygon file"
|
||||
and! projection = opt "projection" null "proj" "Projection of bounding polygon"
|
||||
and! modelId = arg "model-id" "Model ID" |> reqArg |> parse parseModelAreaId
|
||||
@@ -518,9 +555,11 @@ let argParser: Arg<Command * int> =
|
||||
opt "archive" null "guid" "Archive id to augment"
|
||||
|> optParse parseArchiveId
|
||||
|> reqOpt
|
||||
and! files = arg "files" "Files to add" |> Pipe.orStdIn |> nonEmpty "No files to add" |> listParse (fun s ->
|
||||
if File.Exists s then Ok s
|
||||
else Error $"File '{s}' does not exist")
|
||||
and! files =
|
||||
arg "files" "Files to add"
|
||||
|> Pipe.orStdIn
|
||||
|> nonEmpty "No files to add"
|
||||
|> listParse Ok
|
||||
return Augment { Archive = archive; Files = files }, logLevel
|
||||
|
||||
| CmdType.ResizeCmd ->
|
||||
@@ -529,14 +568,16 @@ let argParser: Arg<Command * int> =
|
||||
|> optParse (fun s ->
|
||||
match Int32.TryParse s with
|
||||
| true, v -> Ok v
|
||||
| false, _ -> Error "Invalid integer value")
|
||||
| false, _ -> Error "Invalid integer value"
|
||||
)
|
||||
|> reqOpt
|
||||
and! to' =
|
||||
opt "to" null "int" "Index of last file to include"
|
||||
|> optParse (fun s ->
|
||||
match Int32.TryParse s with
|
||||
| true, v -> Ok v
|
||||
| false, _ -> Error "Invalid integer value")
|
||||
| false, _ -> Error "Invalid integer value"
|
||||
)
|
||||
and! archive = arg "archive" "Archive to resize" |> reqArg |> parse parseArchiveId
|
||||
return Resize { From = from; To = to'; Archive = archive }, logLevel
|
||||
}
|
||||
859
src/Archivist/src/Cli/packages.lock.json
Normal file
859
src/Archivist/src/Cli/packages.lock.json
Normal file
@@ -0,0 +1,859 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dependencies": {
|
||||
"net10.0": {
|
||||
"Fargo.CmdLine": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.7.5, )",
|
||||
"resolved": "1.7.5",
|
||||
"contentHash": "u2fPQAmwJSAfCJRUDoN1NEg1ZmkZw5NsbvgLHhkCjLCkefEiRS/2EVu0W5BcxgkehkgI0Wx6E2qn7rnpPR2YKQ==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "8.0.100"
|
||||
}
|
||||
},
|
||||
"FSharp.Core": {
|
||||
"type": "Direct",
|
||||
"requested": "[9.0.303, )",
|
||||
"resolved": "9.0.303",
|
||||
"contentHash": "6JlV8aD8qQvcmfoe/PMOxCHXc0uX4lR23u0fAyQtnVQxYULLoTZgwgZHSnRcuUHOvS3wULFWcwdnP1iwslH60g=="
|
||||
},
|
||||
"FSharp.Data": {
|
||||
"type": "Direct",
|
||||
"requested": "[6.4.1, )",
|
||||
"resolved": "6.4.1",
|
||||
"contentHash": "P/ShAsNsuKrV9cpK7Mb/fSJ/kpinjOnVGRDXDzi/dYECS/lmlDrAvNVlodPbqCo5hIXvMMkKMc5C4f8ULLW7JQ==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "6.0.1",
|
||||
"FSharp.Data.Csv.Core": "6.4.1",
|
||||
"FSharp.Data.Html.Core": "6.4.1",
|
||||
"FSharp.Data.Http": "6.4.1",
|
||||
"FSharp.Data.Json.Core": "6.4.1",
|
||||
"FSharp.Data.Runtime.Utilities": "6.4.1",
|
||||
"FSharp.Data.WorldBank.Core": "6.4.1",
|
||||
"FSharp.Data.Xml.Core": "6.4.1"
|
||||
}
|
||||
},
|
||||
"FSharpPlus": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.7.0, )",
|
||||
"resolved": "1.7.0",
|
||||
"contentHash": "9+PXT3nG7K5bzgYOzxgwZu5ij25BH7OtMkMJUrWkf+HcfbvsEGCvIf3InF8MCvJ5lO02NfGb9fC8slLEytqw0Q==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "6.0.6"
|
||||
}
|
||||
},
|
||||
"Microsoft.EntityFrameworkCore": {
|
||||
"type": "Direct",
|
||||
"requested": "[9.0.1, )",
|
||||
"resolved": "9.0.1",
|
||||
"contentHash": "E25w4XugXNykTr5Y/sLDGaQ4lf67n9aXVPvsdGsIZjtuLmbvb9AoYP8D50CDejY8Ro4D9GK2kNHz5lWHqSK+wg==",
|
||||
"dependencies": {
|
||||
"Microsoft.EntityFrameworkCore.Abstractions": "9.0.1",
|
||||
"Microsoft.EntityFrameworkCore.Analyzers": "9.0.1",
|
||||
"Microsoft.Extensions.Caching.Memory": "9.0.1",
|
||||
"Microsoft.Extensions.Logging": "9.0.1"
|
||||
}
|
||||
},
|
||||
"Microsoft.EntityFrameworkCore.Design": {
|
||||
"type": "Direct",
|
||||
"requested": "[9.0.1, )",
|
||||
"resolved": "9.0.1",
|
||||
"contentHash": "/pchcadGU57ChRYH0/bvLTeU/n1mpWO+0pVK7pUzzuwRu5SIQb8dVMZVPhzvEI2VO5rP1yricSQBBnOmDqQhvg==",
|
||||
"dependencies": {
|
||||
"Humanizer.Core": "2.14.1",
|
||||
"Microsoft.Build.Framework": "17.8.3",
|
||||
"Microsoft.Build.Locator": "1.7.8",
|
||||
"Microsoft.CodeAnalysis.CSharp": "4.8.0",
|
||||
"Microsoft.CodeAnalysis.CSharp.Workspaces": "4.8.0",
|
||||
"Microsoft.CodeAnalysis.Workspaces.MSBuild": "4.8.0",
|
||||
"Microsoft.EntityFrameworkCore.Relational": "9.0.1",
|
||||
"Microsoft.Extensions.Caching.Memory": "9.0.1",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyModel": "9.0.1",
|
||||
"Microsoft.Extensions.Logging": "9.0.1",
|
||||
"Mono.TextTemplating": "3.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.EntityFrameworkCore.Tools": {
|
||||
"type": "Direct",
|
||||
"requested": "[9.0.1, )",
|
||||
"resolved": "9.0.1",
|
||||
"contentHash": "Yu0+5OInULF5PJX/ILZFWNT4ODBv4CSbS1TCXhkZYI6FxC7WguanhmCY9DL6U1R1YQ1tC38RspbxklmBBuk1SA==",
|
||||
"dependencies": {
|
||||
"Microsoft.EntityFrameworkCore.Design": "9.0.1"
|
||||
}
|
||||
},
|
||||
"Serilog": {
|
||||
"type": "Direct",
|
||||
"requested": "[4.2.0, )",
|
||||
"resolved": "4.2.0",
|
||||
"contentHash": "gmoWVOvKgbME8TYR+gwMf7osROiWAURterc6Rt2dQyX7wtjZYpqFiA/pY6ztjGQKKV62GGCyOcmtP1UKMHgSmA=="
|
||||
},
|
||||
"Serilog.Sinks.Console": {
|
||||
"type": "Direct",
|
||||
"requested": "[6.0.0, )",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "fQGWqVMClCP2yEyTXPIinSr5c+CBGUvBybPxjAGcf7ctDhadFhrQw03Mv8rJ07/wR5PDfFjewf2LimvXCDzpbA==",
|
||||
"dependencies": {
|
||||
"Serilog": "4.0.0"
|
||||
}
|
||||
},
|
||||
"Thoth.Json.Net": {
|
||||
"type": "Direct",
|
||||
"requested": "[12.0.0, )",
|
||||
"resolved": "12.0.0",
|
||||
"contentHash": "n2YyONYdWCFS4Pu7wrqgV/l5tPuN+t3gxEfs/2RwqCiQkRnbgKs9dK61zHeZS5YganAoFbxLSwbaNL7SvSrS9g==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.7.2",
|
||||
"Fable.Core": "3.1.6",
|
||||
"Newtonsoft.Json": "13.0.1"
|
||||
}
|
||||
},
|
||||
"Dapper": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.35",
|
||||
"contentHash": "YKRwjVfrG7GYOovlGyQoMvr1/IJdn+7QzNXJxyMh0YfFF5yvDmTYaJOVYWsckreNjGsGSEtrMTpnzxTUq/tZQw=="
|
||||
},
|
||||
"Dapr.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.16.0",
|
||||
"contentHash": "6JyPI8LxNXSjSpO9vTdbfJh78zOiiC0sgeaXuY8O6SJQh2epaRdEPw0UpamNnld3CkDjp69/VCphox7pU/lh1Q==",
|
||||
"dependencies": {
|
||||
"Dapr.Protos": "1.16.0",
|
||||
"Google.Api.CommonProtos": "2.17.0",
|
||||
"Google.Protobuf": "3.32.0",
|
||||
"Grpc.Net.Client": "2.71.0",
|
||||
"Microsoft.Extensions.Configuration": "9.0.8",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.8",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Http": "9.0.8",
|
||||
"Microsoft.Extensions.Logging": "9.0.8",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Options": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Dapr.Protos": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.16.0",
|
||||
"contentHash": "4k4iKjyRCsFwX7KY5tDcBWDe6JPkhnvN1nqd8zRhDw3YcajF/Br3SU072YdEQKUQ/MJNvqafvzCNPbqSbK3nqg==",
|
||||
"dependencies": {
|
||||
"Google.Api.CommonProtos": "2.17.0",
|
||||
"Google.Protobuf": "3.32.0",
|
||||
"Grpc.Net.Client": "2.71.0",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.8"
|
||||
}
|
||||
},
|
||||
"DynamicInterop": {
|
||||
"type": "Transitive",
|
||||
"resolved": "0.9.1",
|
||||
"contentHash": "n21+Hd+tceX8lgaOosPV+Pne+YqnZUd5RLW3OhnsVxWRzYXiAIAKmKweHIePYeY+fmcn3N5tjkJyQUccFuL3bg=="
|
||||
},
|
||||
"Fable.Remoting.Json": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.25.0",
|
||||
"contentHash": "ycmxT5L7jUKLkSJ4uti+WiX1OU50UYhLLiFQwJpQzwPWpNbSXowPjUtGycl8G5429edzeIHGW/77hUlIAufiAg==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "6.0.0",
|
||||
"Newtonsoft.Json": "13.0.3"
|
||||
}
|
||||
},
|
||||
"FSharp.Data.Csv.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.4.1",
|
||||
"contentHash": "/RmEq3HSafm4RPAPATDsDTY0aAkJ8ioDDJ0Qf/NuJW7c7/CC3xeU0XC3sHmDkp9v98aeQOSJdTa+NJrMTHzT7g==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "6.0.1",
|
||||
"FSharp.Data.Runtime.Utilities": "6.4.1"
|
||||
}
|
||||
},
|
||||
"FSharp.Data.Html.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.4.1",
|
||||
"contentHash": "/T7k5FkR8nRJ3fZ8Bfaf/c9eda2ru0xCIbM+i2Qt/PgtHp2d1ZmDvQIWbYfDLWVcKjRVu/YpRYOw/2fX0RT8ew==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "6.0.1",
|
||||
"FSharp.Data.Csv.Core": "6.4.1",
|
||||
"FSharp.Data.Runtime.Utilities": "6.4.1"
|
||||
}
|
||||
},
|
||||
"FSharp.Data.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.4.1",
|
||||
"contentHash": "7KxlBNwnSIiR1nsPal2ofmgU4Rag8dyDJ+cziW1L9Z+iA55aXeXO/RapQDnyVIwl/Fbm1scGAuSTWP36JNpQFg==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "6.0.1"
|
||||
}
|
||||
},
|
||||
"FSharp.Data.Json.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.4.1",
|
||||
"contentHash": "mUyqLZiI0XPEiE9FIJLJ3Ndof4hEc2paW049Cw224knmp/b0brMwznLaOqtlmCr49QCELj0tcT0ZCKfb2cFS0g==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "6.0.1",
|
||||
"FSharp.Data.Http": "6.4.1",
|
||||
"FSharp.Data.Runtime.Utilities": "6.4.1"
|
||||
}
|
||||
},
|
||||
"FSharp.Data.Runtime.Utilities": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.4.1",
|
||||
"contentHash": "pG4X3QWilYMF3qjZWpod6QgO38uiYUM3/bkEsEyT69E3zAlFQFO9uUy0tqEhDznHvNx4QtZaScUM+06r94HHnQ==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "6.0.1",
|
||||
"FSharp.Data.Http": "6.4.1"
|
||||
}
|
||||
},
|
||||
"FSharp.Data.WorldBank.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.4.1",
|
||||
"contentHash": "opXr3YMArDQCiA1nkEnhSf1s6E0QsotO0VZ5nvQcMXmDuDU4IA1i1DlYp4QVmCXRKj5EHPKMwZkTVNeQDuZ5Bg==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "6.0.1",
|
||||
"FSharp.Data.Http": "6.4.1",
|
||||
"FSharp.Data.Json.Core": "6.4.1",
|
||||
"FSharp.Data.Runtime.Utilities": "6.4.1"
|
||||
}
|
||||
},
|
||||
"FSharp.Data.Xml.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.4.1",
|
||||
"contentHash": "TprbqQu+DdrR6Kl5biNCAsM8yeQs+pgqRpQYDorbbFIroGw1LBMoX+1iiigJcK89TwJAtiEzVrZCQzHvCDrCbA==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "6.0.1",
|
||||
"FSharp.Data.Http": "6.4.1",
|
||||
"FSharp.Data.Json.Core": "6.4.1",
|
||||
"FSharp.Data.Runtime.Utilities": "6.4.1"
|
||||
}
|
||||
},
|
||||
"FsPickler": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.3.2",
|
||||
"contentHash": "LFtxXpQNor8az1ez3rN9oz2cqf/06i9yTrPyJ9R83qLEpFAU7Of0WL2hoSXzLHer4lh+6mO1NV4VQFiBzNRtjw==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.3.2"
|
||||
}
|
||||
},
|
||||
"Google.Api.CommonProtos": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.17.0",
|
||||
"contentHash": "elfQPknFr495hm7vdy6ZlgyQh6yzZq9TU7sS35L/Fj/fqjM/mUGau9gVJLhvQEtUlPjtR80hpn/m9HvBMyCXIw==",
|
||||
"dependencies": {
|
||||
"Google.Protobuf": "[3.31.1, 4.0.0]"
|
||||
}
|
||||
},
|
||||
"Google.Protobuf": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.32.0",
|
||||
"contentHash": "fsKxV5bhcvXmZi+cUo5+IxzRMBHwHeFO8G5utNa9f+Mu37kmfy8JcUVvWPt4cX7EuQWAjjHUjZqVl7nGSTRHRg=="
|
||||
},
|
||||
"Grpc.Core.Api": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.71.0",
|
||||
"contentHash": "QquqUC37yxsDzd1QaDRsH2+uuznWPTS8CVE2Yzwl3CvU4geTNkolQXoVN812M2IwT6zpv3jsZRc9ExJFNFslTg=="
|
||||
},
|
||||
"Grpc.Net.Client": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.71.0",
|
||||
"contentHash": "U1vr20r5ngoT9nlb7wejF28EKN+taMhJsV9XtK9MkiepTZwnKxxiarriiMfCHuDAfPUm9XUjFMn/RIuJ4YY61w==",
|
||||
"dependencies": {
|
||||
"Grpc.Net.Common": "2.71.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "6.0.0"
|
||||
}
|
||||
},
|
||||
"Grpc.Net.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.71.0",
|
||||
"contentHash": "v0c8R97TwRYwNXlC8GyRXwYTCNufpDfUtj9la+wUrZFzVWkFJuNAltU+c0yI3zu0jl54k7en6u2WKgZgd57r2Q==",
|
||||
"dependencies": {
|
||||
"Grpc.Core.Api": "2.71.0"
|
||||
}
|
||||
},
|
||||
"Humanizer.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.14.1",
|
||||
"contentHash": "lQKvtaTDOXnoVJ20ibTuSIOf2i0uO0MPbDhd1jm238I+U/2ZnRENj0cktKZhtchBMtCUSRQ5v4xBCUbKNmyVMw=="
|
||||
},
|
||||
"KdTree": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.4.1",
|
||||
"contentHash": "yWbb35v/V9y88SLLMUPTlAN3pQEoPhDfZf9PApFnlU4kLtwVQ75U9vW5mW4/alQnLBuLKWBKcy4W5xK95mYsuA=="
|
||||
},
|
||||
"MathNet.Numerics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "pg1W2VwaEQMAiTpGK840hZgzavnqjlCMTVSbtVCXVyT+7AX4mc1o89SPv4TBlAjhgCOo9c1Y+jZ5m3ti2YgGgA=="
|
||||
},
|
||||
"MathNet.Numerics.FSharp": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "lKYhd68fReW5odX/q+Uzxw3357Duq3zmvkYvnZVqqcc2r/EmrYGDoOdUGuHnhfr8yj9V34js5gQH/7IWcxZJxg==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "6.0.2",
|
||||
"MathNet.Numerics": "5.0.0"
|
||||
}
|
||||
},
|
||||
"MessagePack.Annotations": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.1.3",
|
||||
"contentHash": "XTy4njgTAf6UVBKFj7c7ad5R0WVKbvAgkbYZy4f00kplzX2T3VOQ34AUke/Vn/QgQZ7ETdd34/IDWS3KBInSGA=="
|
||||
},
|
||||
"MessagePackAnalyzer": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.1.3",
|
||||
"contentHash": "19u1oVNv2brCs5F/jma8O8CnsKMMpYwNqD0CAEDEzvqwDTAhqC9r7xHZP4stPb3APs/ryO/zVn7LvjoEHfvs7Q=="
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.0",
|
||||
"contentHash": "3aeMZ1N0lJoSyzqiP03hqemtb1BijhsJADdobn/4nsMJ8V1H+CrpuduUe4hlRdx+ikBQju1VGjMD1GJ3Sk05Eg=="
|
||||
},
|
||||
"Microsoft.Build.Framework": {
|
||||
"type": "Transitive",
|
||||
"resolved": "17.8.3",
|
||||
"contentHash": "NrQZJW8TlKVPx72yltGb8SVz3P5mNRk9fNiD/ao8jRSk48WqIIdCn99q4IjlVmPcruuQ+yLdjNQLL8Rb4c916g=="
|
||||
},
|
||||
"Microsoft.Build.Locator": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.7.8",
|
||||
"contentHash": "sPy10x527Ph16S2u0yGME4S6ohBKJ69WfjeGG/bvELYeZVmJdKjxgnlL8cJJJLGV/cZIRqSfB12UDB8ICakOog=="
|
||||
},
|
||||
"Microsoft.CodeAnalysis.Analyzers": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.3.4",
|
||||
"contentHash": "AxkxcPR+rheX0SmvpLVIGLhOUXAKG56a64kV9VQZ4y9gR9ZmPXnqZvHJnmwLSwzrEP6junUF11vuc+aqo5r68g=="
|
||||
},
|
||||
"Microsoft.CodeAnalysis.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.8.0",
|
||||
"contentHash": "/jR+e/9aT+BApoQJABlVCKnnggGQbvGh7BKq2/wI1LamxC+LbzhcLj4Vj7gXCofl1n4E521YfF9w0WcASGg/KA==",
|
||||
"dependencies": {
|
||||
"Microsoft.CodeAnalysis.Analyzers": "3.3.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.CodeAnalysis.CSharp": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.8.0",
|
||||
"contentHash": "+3+qfdb/aaGD8PZRCrsdobbzGs1m9u119SkkJt8e/mk3xLJz/udLtS2T6nY27OTXxBBw10HzAbC8Z9w08VyP/g==",
|
||||
"dependencies": {
|
||||
"Microsoft.CodeAnalysis.Common": "[4.8.0]"
|
||||
}
|
||||
},
|
||||
"Microsoft.CodeAnalysis.CSharp.Workspaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.8.0",
|
||||
"contentHash": "3amm4tq4Lo8/BGvg9p3BJh3S9nKq2wqCXfS7138i69TUpo/bD+XvD0hNurpEBtcNZhi1FyutiomKJqVF39ugYA==",
|
||||
"dependencies": {
|
||||
"Humanizer.Core": "2.14.1",
|
||||
"Microsoft.CodeAnalysis.CSharp": "[4.8.0]",
|
||||
"Microsoft.CodeAnalysis.Common": "[4.8.0]",
|
||||
"Microsoft.CodeAnalysis.Workspaces.Common": "[4.8.0]"
|
||||
}
|
||||
},
|
||||
"Microsoft.CodeAnalysis.Workspaces.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.8.0",
|
||||
"contentHash": "LXyV+MJKsKRu3FGJA3OmSk40OUIa/dQCFLOnm5X8MNcujx7hzGu8o+zjXlb/cy5xUdZK2UKYb9YaQ2E8m9QehQ==",
|
||||
"dependencies": {
|
||||
"Humanizer.Core": "2.14.1",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "7.0.0",
|
||||
"Microsoft.CodeAnalysis.Common": "[4.8.0]",
|
||||
"System.Composition": "7.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.CodeAnalysis.Workspaces.MSBuild": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.8.0",
|
||||
"contentHash": "IEYreI82QZKklp54yPHxZNG9EKSK6nHEkeuf+0Asie9llgS1gp0V1hw7ODG+QyoB7MuAnNQHmeV1Per/ECpv6A==",
|
||||
"dependencies": {
|
||||
"Microsoft.Build.Framework": "16.10.0",
|
||||
"Microsoft.CodeAnalysis.Common": "[4.8.0]",
|
||||
"Microsoft.CodeAnalysis.Workspaces.Common": "[4.8.0]"
|
||||
}
|
||||
},
|
||||
"Microsoft.EntityFrameworkCore.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.1",
|
||||
"contentHash": "qy+taGVLUs82zeWfc32hgGL8Z02ZqAneYvqZiiXbxF4g4PBUcPRuxHM9K20USmpeJbn4/fz40GkCbyyCy5ojOA=="
|
||||
},
|
||||
"Microsoft.EntityFrameworkCore.Analyzers": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.1",
|
||||
"contentHash": "c6ZZJZhPKrXFkE2z/81PmuT69HBL6Y68Cl0xJ5SRrDjJyq5Aabkq15yCqPg9RQ3R0aFLVaJok2DA8R3TKpejDQ=="
|
||||
},
|
||||
"Microsoft.Extensions.Caching.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.1",
|
||||
"contentHash": "Eghsg9SyIvq0c8x6cUpe71BbQoOmsytXxqw2+ZNiTnP8a8SBLKgEor1zZeWhC0588IbS2M0PP4gXGAd9qF862Q==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "9.0.1"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Caching.Memory": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.1",
|
||||
"contentHash": "JeC+PP0BCKMwwLezPGDaciJSTfcFG4KjsG8rX4XZ6RSvzdxofrFmcnmW2L4+cWUcZSBTQ+Dd7H5Gs9XZz/OlCA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Caching.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Options": "9.0.1",
|
||||
"Microsoft.Extensions.Primitives": "9.0.1"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "6m+8Xgmf8UWL0p/oGqBM+0KbHE5/ePXbV1hKXgC59zEv0aa0DW5oiiyxDbK5kH5j4gIvyD5uWL0+HadKBJngvQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Primitives": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "yNou2KM35RvzOh4vUFtl2l33rWPvOCoba+nzEDJ+BgD8aOL/jew4WPCibQvntRfOJ2pJU8ARygSMD+pdjvDHuA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Binder": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "0vK9DnYrYChdiH3yRZWkkp4x4LbrfkWEdBc5HOsQ8t/0CLOWKXKkkhOE8A1shlex0hGydbGrhObeypxz/QTm+w==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "JJjI2Fa+QtZcUyuNjbKn04OjIUX5IgFGFu/Xc+qvzh1rXdZHLcnqqVXhR4093bGirTwacRlHiVg1XYI9xum6QQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "xY3lTjj4+ZYmiKIkyWitddrp1uL5uYiweQjqo4BKBw01ZC4HhcfgLghDpPZcUlppgWAFqFy9SgkiYWOMx365pw=="
|
||||
},
|
||||
"Microsoft.Extensions.DependencyModel": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.1",
|
||||
"contentHash": "FHPy9cbb0y09riEpsrU5XYpOgf4nTfHj7a0m1wLC5DosGtjJn9g03gGg1GTJmEdRFBQrJwbwTnHqLCdNLsoYgA=="
|
||||
},
|
||||
"Microsoft.Extensions.Diagnostics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "BKkLCFXzJvNmdngeYBf72VXoZqTJSb1orvjdzDLaGobicoGFBPW8ug2ru1nnEewMEwJzMgnsjHQY8EaKWmVhKg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "9.0.8",
|
||||
"Microsoft.Extensions.Diagnostics.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Options.ConfigurationExtensions": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Diagnostics.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "UDY7blv4DCyIJ/8CkNrQKLaAZFypXQavRZ2DWf/2zi1mxYYKKw2t8AOCBWxNntyPZHPGhtEmL3snFM98ADZqTw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Options": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "jDj+4aDByk47oESlDDTtk6LWzlXlmoCsjCn6ihd+i9OntN885aPLszUII5+w0B/7wYSZcS3KdjqLAIhKLSiBXQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Diagnostics": "9.0.8",
|
||||
"Microsoft.Extensions.Logging": "9.0.8",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Options": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "Z/7ze+0iheT7FJeZPqJKARYvyC2bmwu3whbm/48BJjdlGVvgDguoCqJIkI/67NkroTYobd5geai1WheNQvWrgA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.8",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Options": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "pYnAffJL7ARD/HCnnPvnFKSIHnTSmWz84WIlT9tPeQ4lHNiu0Az7N/8itihWvcF8sT+VVD5lq8V+ckMzu4SbOw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "OmTaQ0v4gxGQkehpwWIqPoEiwsPuG/u4HUsbOFoWGx4DKET2AXzopnFe/fE608FIhzc/kcg2p8JdyMRCCUzitQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Primitives": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Options.ConfigurationExtensions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "eW2s6n06x0w6w4nsX+SvpgsFYkl+Y0CttYAt6DKUXeqprX+hzNqjSfOh637fwNJBg7wRBrOIRHe49gKiTgJxzQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Configuration.Binder": "9.0.8",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Options": "9.0.8",
|
||||
"Microsoft.Extensions.Primitives": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "tizSIOEsIgSNSSh+hKeUVPK7xmTIjR8s+mJWOu1KXV3htvNQiPMFRMO17OdI1y/4ZApdBVk49u/08QGC9yvLug=="
|
||||
},
|
||||
"Microsoft.NET.StringTools": {
|
||||
"type": "Transitive",
|
||||
"resolved": "17.11.4",
|
||||
"contentHash": "mudqUHhNpeqIdJoUx2YDWZO/I9uEDYVowan89R6wsomfnUJQk6HteoQTlNjZDixhT2B4IXMkMtgZtoceIjLRmA=="
|
||||
},
|
||||
"Mono.TextTemplating": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "YqueG52R/Xej4VVbKuRIodjiAhV0HR/XVbLbNrJhCZnzjnSjgMJ/dCdV0akQQxavX6hp/LC6rqLGLcXeQYU7XA==",
|
||||
"dependencies": {
|
||||
"System.CodeDom": "6.0.0"
|
||||
}
|
||||
},
|
||||
"NetTopologySuite.IO.PostGis": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.0",
|
||||
"contentHash": "3W8XTFz8iP6GQ5jDXK1/LANHiU+988k1kmmuPWNKcJLpmSg6CvFpbTpz+s4+LBzkAp64wHGOldSlkSuzYfrIKA==",
|
||||
"dependencies": {
|
||||
"NetTopologySuite": "[2.0.0, 3.0.0-A)"
|
||||
}
|
||||
},
|
||||
"ProjNET": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.0.0",
|
||||
"contentHash": "iMJG8qpGJ8SjFrB044O8wgo0raAWCdG1Bvly0mmVcjzsrexDHhC+dUct6Wb1YwQtupMBjSTWq7Fn00YeNErprA=="
|
||||
},
|
||||
"Serilog.Sinks.File": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "lxjg89Y8gJMmFxVkbZ+qDgjl+T4yC5F7WSLTvA+5q0R04tfKVLRL/EHpYoJ/MEQd2EeCKDuylBIVnAYMotmh2A==",
|
||||
"dependencies": {
|
||||
"Serilog": "4.0.0"
|
||||
}
|
||||
},
|
||||
"Serilog.Sinks.Seq": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.0",
|
||||
"contentHash": "aNU8A0K322q7+voPNmp1/qNPH+9QK8xvM1p72sMmCG0wGlshFzmtDW9QnVSoSYCj0MgQKcMOlgooovtBhRlNHw==",
|
||||
"dependencies": {
|
||||
"Serilog": "4.2.0",
|
||||
"Serilog.Sinks.File": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.CodeDom": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "CPc6tWO1LAer3IzfZufDBRL+UZQcj5uS207NHALQzP84Vp/z6wF0Aa0YZImOQY8iStY0A2zI/e3ihKNPfUm8XA=="
|
||||
},
|
||||
"System.Composition": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.0",
|
||||
"contentHash": "tRwgcAkDd85O8Aq6zHDANzQaq380cek9lbMg5Qma46u5BZXq/G+XvIYmu+UI+BIIZ9zssXLYrkTykEqxxvhcmg==",
|
||||
"dependencies": {
|
||||
"System.Composition.AttributedModel": "7.0.0",
|
||||
"System.Composition.Convention": "7.0.0",
|
||||
"System.Composition.Hosting": "7.0.0",
|
||||
"System.Composition.Runtime": "7.0.0",
|
||||
"System.Composition.TypedParts": "7.0.0"
|
||||
}
|
||||
},
|
||||
"System.Composition.AttributedModel": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.0",
|
||||
"contentHash": "2QzClqjElKxgI1jK1Jztnq44/8DmSuTSGGahXqQ4TdEV0h9s2KikQZIgcEqVzR7OuWDFPGLHIprBJGQEPr8fAQ=="
|
||||
},
|
||||
"System.Composition.Convention": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.0",
|
||||
"contentHash": "IMhTlpCs4HmlD8B+J8/kWfwX7vrBBOs6xyjSTzBlYSs7W4OET4tlkR/Sg9NG8jkdJH9Mymq0qGdYS1VPqRTBnQ==",
|
||||
"dependencies": {
|
||||
"System.Composition.AttributedModel": "7.0.0"
|
||||
}
|
||||
},
|
||||
"System.Composition.Hosting": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.0",
|
||||
"contentHash": "eB6gwN9S+54jCTBJ5bpwMOVerKeUfGGTYCzz3QgDr1P55Gg/Wb27ShfPIhLMjmZ3MoAKu8uUSv6fcCdYJTN7Bg==",
|
||||
"dependencies": {
|
||||
"System.Composition.Runtime": "7.0.0"
|
||||
}
|
||||
},
|
||||
"System.Composition.Runtime": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.0",
|
||||
"contentHash": "aZJ1Zr5Txe925rbo4742XifEyW0MIni1eiUebmcrP3HwLXZ3IbXUj4MFMUH/RmnJOAQiS401leg/2Sz1MkApDw=="
|
||||
},
|
||||
"System.Composition.TypedParts": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.0",
|
||||
"contentHash": "ZK0KNPfbtxVceTwh+oHNGUOYV2WNOHReX2AXipuvkURC7s/jPwoWfsu3SnDBDgofqbiWr96geofdQ2erm/KTHg==",
|
||||
"dependencies": {
|
||||
"System.Composition.AttributedModel": "7.0.0",
|
||||
"System.Composition.Hosting": "7.0.0",
|
||||
"System.Composition.Runtime": "7.0.0"
|
||||
}
|
||||
},
|
||||
"entity": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.EntityFrameworkCore": "[9.0.1, )",
|
||||
"Microsoft.EntityFrameworkCore.Relational": "[9.0.1, )",
|
||||
"Npgsql.EntityFrameworkCore.PostgreSQL": "[9.0.2, )",
|
||||
"Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite": "[9.0.2, )"
|
||||
}
|
||||
},
|
||||
"oceanbox.dataagent": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Dapper.FSharp": "[4.9.0, )",
|
||||
"Dapr.Actors": "[1.16.0, )",
|
||||
"Entity": "[1.0.0, )",
|
||||
"FSharp.Core": "[9.0.303, )",
|
||||
"FSharp.Data": "[6.4.1, )",
|
||||
"FSharpPlus": "[1.7.0, )",
|
||||
"Fable.Remoting.DotnetClient": "[3.35.0, )",
|
||||
"Microsoft.EntityFrameworkCore": "[9.0.1, )",
|
||||
"Microsoft.EntityFrameworkCore.Relational": "[9.0.1, )",
|
||||
"NetTopologySuite": "[2.5.0, )",
|
||||
"Npgsql.EntityFrameworkCore.PostgreSQL": "[9.0.2, )",
|
||||
"Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite": "[9.0.2, )",
|
||||
"Npgsql.NetTopologySuite": "[9.0.2, )",
|
||||
"Oceanbox.FvcomKit": "[5.13.0, )",
|
||||
"Oceanbox.SDSLite": "[2.8.0, )",
|
||||
"Serilog.Sinks.Console": "[6.0.0, )",
|
||||
"Thoth.Json.Net": "[12.0.0, )"
|
||||
}
|
||||
},
|
||||
"Oceanbox.DataAgent.Api": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "[9.0.303, )"
|
||||
}
|
||||
},
|
||||
"Dapper.FSharp": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.9.0, )",
|
||||
"resolved": "4.9.0",
|
||||
"contentHash": "wqMi/wHSQV9v79/u8OELxO+lmUOxk3J5CAUuAmWbltbIYH0A64CV1z1RG+9EVpyAAD9bovKYAnQ2wNwDoPxTxA==",
|
||||
"dependencies": {
|
||||
"Dapper": "2.1.35",
|
||||
"FSharp.Core": "8.0.200"
|
||||
}
|
||||
},
|
||||
"Dapr.Actors": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[1.16.0, )",
|
||||
"resolved": "1.16.0",
|
||||
"contentHash": "s9v6VofXXYoRqZJQlQbvNYYSlGhkL+Z+bpqrx1TRo06kLhANeDmXA9yeVaD+1KwJIO1chUFj5O4iKuTxIkg1sA==",
|
||||
"dependencies": {
|
||||
"Dapr.Client": "1.16.0",
|
||||
"Dapr.Common": "1.16.0",
|
||||
"Google.Api.CommonProtos": "2.17.0",
|
||||
"Google.Protobuf": "3.32.0",
|
||||
"Grpc.Net.Client": "2.71.0",
|
||||
"Microsoft.Extensions.Configuration": "9.0.8",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.8",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Http": "9.0.8",
|
||||
"Microsoft.Extensions.Logging": "9.0.8",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Options": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Dapr.Client": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[1.16.0, )",
|
||||
"resolved": "1.16.0",
|
||||
"contentHash": "dFDKol+mtQrk1lIKlEyCx3k6W0Pf+0wC6xcsaDqa0Bg+XCWDc4juROuDcSb0/L1Y+Ev6LSLDMC/FgzNWMw9YtQ==",
|
||||
"dependencies": {
|
||||
"Dapr.Common": "1.16.0",
|
||||
"Dapr.Protos": "1.16.0",
|
||||
"Google.Api.CommonProtos": "2.17.0",
|
||||
"Google.Protobuf": "3.32.0",
|
||||
"Grpc.Net.Client": "2.71.0",
|
||||
"Microsoft.Extensions.Configuration": "9.0.8",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.8",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Http": "9.0.8",
|
||||
"Microsoft.Extensions.Logging": "9.0.8",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Options": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Fable.Core": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.4.0, )",
|
||||
"resolved": "3.1.6",
|
||||
"contentHash": "w6M1F0zoLk4kTFc1Lx6x1Ft6BD3QwRe0eaLiinAqbjVkcF+iK+NiXGJO+a6q9RAF9NCg0vI48Xku7aNeqG4JVw==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.7.1"
|
||||
}
|
||||
},
|
||||
"Fable.Remoting.DotnetClient": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.35.0, )",
|
||||
"resolved": "3.35.0",
|
||||
"contentHash": "xaxt9nKfqIWh30+cOrG9GNl06+7yTy5htrcF5eXsZ7QJLLy7T5ZD3xeGpAb0xbh+TZTVQGluSQzxh/opIZm2PQ==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "6.0.0",
|
||||
"Fable.Remoting.Json": "2.25.0",
|
||||
"Fable.Remoting.MsgPack": "1.24.0"
|
||||
}
|
||||
},
|
||||
"Fable.Remoting.MsgPack": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[1.24.0, )",
|
||||
"resolved": "1.24.0",
|
||||
"contentHash": "Bn3nzoZbib6lPk70bIJumEu2wFMxciB4o8k0Zw6tRfAOpNKvUsi79OOll2nW3FU1P6MVBepT43m+R8JvfYnNiw==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.7.2"
|
||||
}
|
||||
},
|
||||
"MessagePack": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.3, )",
|
||||
"resolved": "3.1.3",
|
||||
"contentHash": "UiNv3fknvPzh5W+S0VV96R17RBZQQU71qgmsMnjjRZU2rtQM/XcTnOB+klT2dA6T1mxjnNKYrEm164AoXvGmYg==",
|
||||
"dependencies": {
|
||||
"MessagePack.Annotations": "3.1.3",
|
||||
"MessagePackAnalyzer": "3.1.3",
|
||||
"Microsoft.NET.StringTools": "17.11.4"
|
||||
}
|
||||
},
|
||||
"Microsoft.EntityFrameworkCore.Relational": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[9.0.1, )",
|
||||
"resolved": "9.0.1",
|
||||
"contentHash": "7Iu0h4oevRvH4IwPzmxuIJGYRt55TapoREGlluk75KCO7lenN0+QnzCl6cQDY48uDoxAUpJbpK2xW7o8Ix69dw==",
|
||||
"dependencies": {
|
||||
"Microsoft.EntityFrameworkCore": "9.0.1",
|
||||
"Microsoft.Extensions.Caching.Memory": "9.0.1",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Logging": "9.0.1"
|
||||
}
|
||||
},
|
||||
"NetTopologySuite": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.5.0, )",
|
||||
"resolved": "2.5.0",
|
||||
"contentHash": "5/+2O2ADomEdUn09mlSigACdqvAf0m/pVPGtIPEPQWnyrVykYY0NlfXLIdkMgi41kvH9kNrPqYaFBTZtHYH7Xw=="
|
||||
},
|
||||
"Newtonsoft.Json": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[13.0.3, )",
|
||||
"resolved": "13.0.3",
|
||||
"contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ=="
|
||||
},
|
||||
"Npgsql": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[9.0.2, )",
|
||||
"resolved": "9.0.2",
|
||||
"contentHash": "hCbO8box7i/XXiTFqCJ3GoowyLqx3JXxyrbOJ6om7dr+eAknvBNhhUHeJVGAQo44sySZTfdVffp4BrtPeLZOAA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "8.0.2"
|
||||
}
|
||||
},
|
||||
"Npgsql.EntityFrameworkCore.PostgreSQL": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[9.0.2, )",
|
||||
"resolved": "9.0.2",
|
||||
"contentHash": "cYdOGplIvr9KgsG8nJ8xnzBTImeircbgetlzS1OmepS5dAQW6PuGpVrLOKBNEwEvGYZPsV8037X5vZ/Dmpwz7Q==",
|
||||
"dependencies": {
|
||||
"Microsoft.EntityFrameworkCore": "[9.0.0, 10.0.0)",
|
||||
"Microsoft.EntityFrameworkCore.Relational": "[9.0.0, 10.0.0)",
|
||||
"Npgsql": "9.0.2"
|
||||
}
|
||||
},
|
||||
"Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[9.0.2, )",
|
||||
"resolved": "9.0.2",
|
||||
"contentHash": "D38a3+CF8dO7nPiwt/NtQ/sLbrzZpX910jaaGiETdeS18KI0yMYEFvWWO5I/JBjVXLVnruodsukIUupdoD4fRA==",
|
||||
"dependencies": {
|
||||
"Npgsql.EntityFrameworkCore.PostgreSQL": "9.0.2",
|
||||
"Npgsql.NetTopologySuite": "9.0.2"
|
||||
}
|
||||
},
|
||||
"Npgsql.NetTopologySuite": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[9.0.2, )",
|
||||
"resolved": "9.0.2",
|
||||
"contentHash": "DCwN+IVl3yWfOftPe0UBUUDOqa877ca+z+xSDQVi5ShDnOIAipaaYZlzDYm8Nga8hcxx6UrIQuImFnXv8fDpwg==",
|
||||
"dependencies": {
|
||||
"NetTopologySuite": "2.5.0",
|
||||
"NetTopologySuite.IO.PostGIS": "2.1.0",
|
||||
"Npgsql": "9.0.2"
|
||||
}
|
||||
},
|
||||
"Oceanbox.FvcomKit": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[5.13.0, )",
|
||||
"resolved": "5.13.0",
|
||||
"contentHash": "6uVL3fLhRf4OU1hWygGpVex4pI5YB+GaWrKZUgoL/LkGmdFv0qU8Y7v+meHNM3E9bjR7xKinCVfrw5SXsF6C8g==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "9.0.201",
|
||||
"FSharp.Data": "6.4.1",
|
||||
"FSharpPlus": "1.7.0",
|
||||
"FsPickler": "5.3.2",
|
||||
"KDTree": "1.4.1",
|
||||
"MathNet.Numerics.FSharp": "5.0.0",
|
||||
"MessagePack": "3.1.3",
|
||||
"Oceanbox.SDSLite": "2.8.0",
|
||||
"ProjNet.FSharp": "5.2.0",
|
||||
"Serilog": "4.2.0",
|
||||
"Serilog.Sinks.Console": "6.0.0",
|
||||
"Serilog.Sinks.Seq": "9.0.0",
|
||||
"Thoth.Json.Net": "12.0.0"
|
||||
}
|
||||
},
|
||||
"Oceanbox.SDSLite": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[2.8.0, )",
|
||||
"resolved": "2.8.0",
|
||||
"contentHash": "DzMcnywHhtmLVDZSVCZq6Mqq+SIm4snGRYgquho9xZSyEq5RhBkLdSa5k59m7o24FGZyt75DGpElN9p+dezU7Q==",
|
||||
"dependencies": {
|
||||
"DynamicInterop": "0.9.1"
|
||||
}
|
||||
},
|
||||
"ProjNet.FSharp": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[5.2.0, )",
|
||||
"resolved": "5.2.0",
|
||||
"contentHash": "sYSePg/0sVo16Fk3r7okVSga6i9GAN0kkjt1haEXVw25SF8A4S3Gcpf5+6lgknBGdYiZBmJ+3S6v5g1WSSCp2g==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "8.0.100",
|
||||
"FSharp.Data": "6.3.0",
|
||||
"FSharpPlus": "1.5.0",
|
||||
"ProjNet": "2.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"net10.0/linux-x64": {}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Version>7.1.0</Version>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
@@ -9,9 +9,9 @@
|
||||
<Compile Include="App.fs"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Fable.Lit" Version="1.4.2"/>
|
||||
<PackageReference Include="Fable.Remoting.Client" Version="7.32.0"/>
|
||||
<PackageReference Update="FSharp.Core" Version="9.0.201"/>
|
||||
<PackageReference Include="Fable.Lit" />
|
||||
<PackageReference Include="Fable.Remoting.Client" />
|
||||
<PackageReference Include="FSharp.Core" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../../../Interfaces/Archmaester/Archmaester.Api.fsproj"/>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Version>7.1.0</Version>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
@@ -11,23 +11,23 @@
|
||||
<Compile Include="Main.fs"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Argu" Version="6.2.5"/>
|
||||
<PackageReference Include="Dapper.FSharp" Version="4.9.0"/>
|
||||
<PackageReference Include="FSharp.Data" Version="6.4.1"/>
|
||||
<PackageReference Include="FSharpPlus" Version="1.7.0"/>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.2">
|
||||
<PackageReference Include="Argu" />
|
||||
<PackageReference Include="Dapper.FSharp" />
|
||||
<PackageReference Include="FSharp.Data" />
|
||||
<PackageReference Include="FSharpPlus" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" >
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.2"/>
|
||||
<PackageReference Include="Npgsql.NetTopologySuite" Version="9.0.2"/>
|
||||
<PackageReference Include="Serilog" Version="4.2.0"/>
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0"/>
|
||||
<PackageReference Include="Thoth.Json.Net" Version="12.0.0"/>
|
||||
<PackageReference Include="NetTopologySuite" Version="2.5.0"/>
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.2"/>
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite" Version="9.0.2"/>
|
||||
<PackageReference Update="FSharp.Core" Version="9.0.201"/>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" />
|
||||
<PackageReference Include="Npgsql.NetTopologySuite" />
|
||||
<PackageReference Include="Serilog" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" />
|
||||
<PackageReference Include="Thoth.Json.Net" />
|
||||
<PackageReference Include="NetTopologySuite" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite" />
|
||||
<PackageReference Update="FSharp.Core" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Interfaces\Archmaester\Archmaester.Api.fsproj"/>
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
open Fake.Core
|
||||
open Fake.IO
|
||||
open Farmer
|
||||
open Farmer.Builders
|
||||
|
||||
open Helpers
|
||||
|
||||
initializeContext()
|
||||
|
||||
let serverPath = Path.getFullName "src/Server"
|
||||
let clientPath = Path.getFullName "src/Client"
|
||||
let testPath = Path.getFullName "test"
|
||||
let libPath = Path.getFullName "src/Interfaces" |> Some
|
||||
|
||||
let distPath = Path.getFullName "dist"
|
||||
let packPath = Path.getFullName "packages"
|
||||
let versionFile = Path.getFullName ".version"
|
||||
|
||||
let vite = """bunx --bun vite -c ../../vite.config.js"""
|
||||
|
||||
let fable opts =
|
||||
$"fable -e .jsx -o build --test:MSBuildCracker --run {vite} build --emptyOutDir --outDir {distPath}/public {opts}"
|
||||
|
||||
let fableWatch = $"fable watch -e .jsx -o build --run {vite}"
|
||||
|
||||
Target.create "Clean" (fun _ -> Shell.cleanDir distPath)
|
||||
|
||||
Target.create "Bundle" (fun _ ->
|
||||
[ "server", dotnet $"build -tl -c Release -o {distPath} -p:DefineConstants=" serverPath
|
||||
"client", dotnet (fable "-m production") clientPath ]
|
||||
|> runParallel
|
||||
)
|
||||
|
||||
Target.create "BundleDebug" (fun _ ->
|
||||
[ "server", dotnet $"build -tl -c Debug -o {distPath} -p:DefineConstants=" serverPath
|
||||
"client", dotnet (fable "-m development --minify false --sourcemap true") clientPath ]
|
||||
|> runParallel
|
||||
)
|
||||
|
||||
Target.create "Pack" (fun _ ->
|
||||
match libPath with
|
||||
| Some p -> run dotnet $"pack -c Release -o \"{packPath}\"" p
|
||||
| None -> ()
|
||||
)
|
||||
|
||||
Target.create "Run" (fun _ ->
|
||||
[ "server", dotnet "watch run" serverPath
|
||||
"client", dotnet fableWatch clientPath ]
|
||||
|> runParallel
|
||||
)
|
||||
|
||||
Target.create "Client" (fun _ ->
|
||||
run dotnet fableWatch clientPath
|
||||
)
|
||||
|
||||
Target.create "Format" (fun _ ->
|
||||
run dotnet "fantomas . -r" "src"
|
||||
)
|
||||
|
||||
Target.create "Test" (fun _ ->
|
||||
if System.IO.Directory.Exists testPath then
|
||||
[ "server", dotnet "run" (testPath + "/Server")
|
||||
"client", dotnet $"fable -e .jsx -o build --run {vite}" (testPath + "/Client") ]
|
||||
|> runParallel
|
||||
else ()
|
||||
)
|
||||
|
||||
open Fake.Core.TargetOperators
|
||||
|
||||
let dependencies = [
|
||||
"Clean"
|
||||
==> "Bundle"
|
||||
|
||||
"Clean"
|
||||
==> "BundleDebug"
|
||||
|
||||
"Clean"
|
||||
==> "Test"
|
||||
|
||||
"Clean"
|
||||
==> "Run"
|
||||
|
||||
"Clean"
|
||||
==> "Pack"
|
||||
|
||||
"Client"
|
||||
]
|
||||
|
||||
[<EntryPoint>]
|
||||
let main args = runOrDefault args
|
||||
@@ -1 +1,6 @@
|
||||
use nix
|
||||
#!/usr/bin/env bash
|
||||
# the shebang is ignored, but nice for editors
|
||||
use nix
|
||||
|
||||
# HACK: Workaround for direnv bug
|
||||
unset TMP TMPDIR TEMP TEMPDIR
|
||||
@@ -1,16 +1,15 @@
|
||||
# yaml-language-server: $schema=https://gitlab.com/gitlab-org/gitlab/-/raw/master/app/assets/javascripts/editor/schema/ci.json
|
||||
variables:
|
||||
SKIP_TESTS: "true"
|
||||
SKIP_TESTS: "true"
|
||||
|
||||
include:
|
||||
- project: oceanbox/gitlab-ci
|
||||
ref: v4.2
|
||||
file: DotnetDeployment.gitlab-ci.yml
|
||||
inputs:
|
||||
project-name: atlantis
|
||||
project-dir: src/Atlantis
|
||||
- project: oceanbox/gitlab-ci
|
||||
ref: v4.5
|
||||
file: DotnetDeployment.gitlab-ci.yml
|
||||
inputs:
|
||||
project-name: atlantis
|
||||
project-dir: src/Atlantis
|
||||
|
||||
# TODO(mrtz): Create a nix-runner
|
||||
dockerize-atlantis:
|
||||
tags:
|
||||
- saas-linux-large-amd64
|
||||
- nix
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="../../.build/Helpers.fs" />
|
||||
<Compile Include=".build/Build.fs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Fake.Core.Target" Version="6.1.3" />
|
||||
<PackageReference Include="Fake.DotNet.Cli" Version="6.1.3" />
|
||||
<PackageReference Include="Fake.IO.FileSystem" Version="6.1.3" />
|
||||
<PackageReference Include="Farmer" Version="1.9.6" />
|
||||
<PackageReference Update="FSharp.Core" Version="9.0.201" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:9.0.6
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:10.0
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y gcc-multilib libnetcdf19 libnetcdf-dev
|
||||
@@ -12,4 +12,4 @@ ENV SERVER_CONTENT_ROOT=/app/public
|
||||
COPY dist/ /app
|
||||
|
||||
WORKDIR /app
|
||||
CMD [ "dotnet", "/app/Server.dll" ]
|
||||
CMD [ "dotnet", "/app/Server.dll" ]
|
||||
@@ -38,15 +38,10 @@ docker_build_with_restart(
|
||||
# build_nix_image(
|
||||
# '{repository}:latest'.format(repository=repository),
|
||||
# "../../default.nix",
|
||||
# "atlantis-container",
|
||||
# "containers.atlantis --argstr debug 'Debug' --show-trace",
|
||||
# "../../default.nix",
|
||||
# )
|
||||
|
||||
redis=str(local(
|
||||
'helm template -f ./tilt/tilt/redis.yaml --namespace {namespace} {env}-{name}-redis bitnami/redis'
|
||||
.format(namespace=namespace, env=env, name=name), echo_off=False, quiet=True)).replace('<x>',"{env}".format(env=env))
|
||||
k8s_yaml(blob(redis))
|
||||
|
||||
manifest=helm(
|
||||
'../../../manifests/charts/{name}'.format(name=name),
|
||||
name='{env}'.format(env=env),
|
||||
@@ -65,13 +60,13 @@ k8s_yaml(namespace_inject(blob(kustomizations), namespace))
|
||||
|
||||
local_resource(
|
||||
'create-bundle',
|
||||
cmd='dotnet run bundledebug',
|
||||
cmd='just bundle-debug',
|
||||
trigger_mode=TRIGGER_MODE_MANUAL
|
||||
)
|
||||
|
||||
local_resource(
|
||||
'build-server',
|
||||
cmd='dotnet publish -o ./dist src/Server',
|
||||
cmd='just bundle-debug-server',
|
||||
deps=[
|
||||
'./src/Server',
|
||||
'./src/Shared'
|
||||
@@ -79,6 +74,10 @@ local_resource(
|
||||
ignore=[
|
||||
'src/Server/bin',
|
||||
'src/Server/obj',
|
||||
'src/Server/Archmaester/obj',
|
||||
'src/Server/Hipster/obj',
|
||||
'src/Server/Petimeter/obj',
|
||||
'src/Server/Common/obj',
|
||||
'src/Shared/bin',
|
||||
'src/Shared/obj',
|
||||
],
|
||||
@@ -89,7 +88,7 @@ local_resource(
|
||||
|
||||
local_resource(
|
||||
'run-client',
|
||||
serve_cmd='dotnet fable watch -e .jsx -o build --run vite -c ../../vite.config.js',
|
||||
serve_cmd='just run-client',
|
||||
serve_dir='./src/Client',
|
||||
links=['https://{name}.local.oceanbox.io:{port}'.format(name=name, port=clientPort)],
|
||||
resource_deps=['build-server'],
|
||||
|
||||
86
src/Atlantis/justfile
Normal file
86
src/Atlantis/justfile
Normal file
@@ -0,0 +1,86 @@
|
||||
# Atlantis build commands
|
||||
# Install just: https://github.com/casey/just
|
||||
|
||||
set dotenv-load
|
||||
|
||||
src_path := "src"
|
||||
server_path := "src/Server"
|
||||
client_path := "src/Client"
|
||||
test_path := "test"
|
||||
lib_path := "src/Interfaces"
|
||||
|
||||
dist_path := "../../dist"
|
||||
pack_path := "../../packages"
|
||||
|
||||
vite_prod := "bunx --bun vite build -c ../../vite.config.js -m production --emptyOutDir --outDir " + "../../dist/public"
|
||||
vite_dev := "bunx --bun vite build -c ../../vite.config.js -m development --minify false --sourcemap true --emptyOutDir --outDir " + "../../dist/public"
|
||||
vite := "bunx vite -c ../../vite.config.js -m development "
|
||||
|
||||
# Default recipe - show available commands
|
||||
default:
|
||||
@just --list
|
||||
|
||||
# Clean build artifacts
|
||||
clean:
|
||||
rm -rf {{dist_path}}
|
||||
|
||||
# Build production bundle (server + client)
|
||||
[parallel]
|
||||
bundle: clean bundle-server bundle-client
|
||||
|
||||
[working-directory: 'src/Server']
|
||||
bundle-server:
|
||||
dotnet build -tl -c Release -o {{dist_path}}
|
||||
|
||||
[working-directory: 'src/Client']
|
||||
install-client:
|
||||
bun install --frozen-lockfile
|
||||
|
||||
[working-directory: 'src/Client']
|
||||
bundle-client: install-client
|
||||
|
||||
# Build debug bundle (server + client)
|
||||
[parallel]
|
||||
bundle-debug: clean bundle-debug-server bundle-debug-client
|
||||
|
||||
[working-directory: 'src/Server']
|
||||
bundle-debug-server:
|
||||
dotnet build -tl -c Debug -o {{dist_path}}
|
||||
|
||||
[working-directory: 'src/Client']
|
||||
bundle-debug-client:
|
||||
fable -e .jsx -o build --test:MSBuildCracker --run {{vite_dev}}
|
||||
|
||||
# Create NuGet package
|
||||
[working-directory: 'src/Server']
|
||||
pack: clean
|
||||
dotnet pack -c Release -o "{{pack_path}}" {{lib_path}}
|
||||
|
||||
# Run development server (watch mode)
|
||||
[parallel]
|
||||
run: clean run-server run-client
|
||||
|
||||
[working-directory: 'src/Server']
|
||||
run-server:
|
||||
dotnet watch run
|
||||
|
||||
# Run client only in watch mode
|
||||
[working-directory: 'src/Client']
|
||||
run-client: install-client
|
||||
fable watch -e .jsx -o build --test:MSBuildCracker --run {{vite}}
|
||||
|
||||
# Format code with Fantomas
|
||||
format:
|
||||
fantomas {{src_path}} -r
|
||||
|
||||
# Run tests
|
||||
[parallel]
|
||||
test: clean test-server test-client
|
||||
|
||||
[working-directory: 'src']
|
||||
test-server:
|
||||
dotnet run {{test_path}}/Server
|
||||
|
||||
[working-directory: 'src/Client']
|
||||
test-client: install-client
|
||||
fable -e .jsx -o build --run {{vite}}
|
||||
@@ -14,4 +14,4 @@ import barpolar from 'plotly-dist/lib/barpolar';
|
||||
|
||||
Plotly.register([scatter, contour, heatmap, box, bar, barpolar]);
|
||||
|
||||
export default Plotly;
|
||||
export default Plotly;
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
sources ? import ./../../npins,
|
||||
sources ? import ./../../nix,
|
||||
pkgs ? import sources.nixpkgs { },
|
||||
}:
|
||||
let
|
||||
@@ -8,6 +8,7 @@ let
|
||||
in
|
||||
pkgs.mkShellNoCC {
|
||||
inputsFrom = [ baseShell ];
|
||||
|
||||
LOG_LEVEL = "verbose";
|
||||
REDIS = "localhost:6379";
|
||||
|
||||
@@ -18,8 +19,7 @@ pkgs.mkShellNoCC {
|
||||
DAPR_API_TOKEN = "anVzdCBmb3IgbG9jYWwgdXNlCg==";
|
||||
ARCHMAESTER_AUTH = "YWRtaW46ZW4tdG8tdHJlLWZpcmU=";
|
||||
|
||||
# Fixes docker build error
|
||||
# `Build Failed: failed to dial gRPC: unable to upgrade to h2c`
|
||||
# NOTE: Fixes docker error `Build Failed: failed to dial gRPC: unable to upgrade to h2c`
|
||||
DOCKER_BUILDKIT = 0;
|
||||
# NOTE(mrtz): Needed for tilt podman compat.
|
||||
# DOCKER_HOST = "unix:///run/user/1000/podman/podman.sock";
|
||||
@@ -29,4 +29,4 @@ pkgs.mkShellNoCC {
|
||||
export APP_NAME=atlantis
|
||||
export APP_NAMESPACE=$USER-atlantis
|
||||
'';
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ open Fable.Core.JsInterop
|
||||
open Lit
|
||||
open Remoting
|
||||
|
||||
let initSentry = Array.contains window.location.hostname Sentry.hostTargets
|
||||
let initSentry = Sentry.hostTargets |> Array.contains window.location.hostname
|
||||
|
||||
if initSentry then
|
||||
console.debug "Pushing to Sentry"
|
||||
@@ -18,8 +18,9 @@ let InitApp () =
|
||||
Hook.useEffectOnce (fun () ->
|
||||
async {
|
||||
let! authenticated = authApi.IsAuthenticated()
|
||||
do! Auth.setId ()
|
||||
if authenticated.IsSome && not (isNullOrUndefined sessionStorage["archive_id"]) then
|
||||
do! Utils.initAtlantisSessionUrls ()
|
||||
do! Auth.initSessionUrls ()
|
||||
window.location.href <- "/map.html"
|
||||
else
|
||||
sessionStorage.removeItem "archive_id"
|
||||
@@ -27,4 +28,5 @@ let InitApp () =
|
||||
return ()
|
||||
} |> Async.StartImmediate
|
||||
)
|
||||
Lit.nothing
|
||||
|
||||
Lit.nothing
|
||||
@@ -1,21 +1,22 @@
|
||||
module Atlas
|
||||
|
||||
open System
|
||||
|
||||
open Browser
|
||||
open Fable.Core
|
||||
open Fable.Core.JsInterop
|
||||
open Fable.OpenLayers
|
||||
open Fable.OpenLayers.Event
|
||||
open Feliz.prop
|
||||
open Lit
|
||||
open Lit.Elmish
|
||||
open Remoting
|
||||
|
||||
open Archmaester.Dto
|
||||
open Atlantis.Types
|
||||
open Maps
|
||||
open Remoting
|
||||
|
||||
importSideEffects "../public/style.scss"
|
||||
|
||||
importSideEffects "@spectrum-web-components/action-button/sp-action-button.js"
|
||||
importSideEffects "@spectrum-web-components/action-group/sp-action-group.js"
|
||||
importSideEffects "@spectrum-web-components/action-menu/sp-action-menu.js"
|
||||
@@ -53,12 +54,8 @@ importSideEffects "@spectrum-web-components/table/sp-table-row.js"
|
||||
importSideEffects "@spectrum-web-components/dialog/sp-dialog.js"
|
||||
importSideEffects "@spectrum-web-components/underlay/sp-underlay.js"
|
||||
|
||||
importSideEffects "@shoelace-style/shoelace/dist/components/dialog/dialog.js"
|
||||
|
||||
let register () = ()
|
||||
|
||||
let private hmr = HMR.createToken ()
|
||||
|
||||
let polygonStyle (feature: Feature) =
|
||||
let name = feature.get "name" :?> string
|
||||
let models = feature.get "models" :?> int
|
||||
@@ -96,7 +93,8 @@ let private createSelectInteraction () =
|
||||
|
||||
type private Model = {
|
||||
activeTab: Tab
|
||||
archives: Map<ModelAreaId, ArchiveProps[]>
|
||||
// TODO: Save this in localstorage or IndexedDB
|
||||
archives: Map<ModelAreaId, ArchiveProps array>
|
||||
helloWorld: ModelArea option
|
||||
map: OlMap
|
||||
mapKind: MapKind
|
||||
@@ -237,6 +235,7 @@ let createMapWithLayers center (layers: Layer.Layer[]) : OlMap =
|
||||
let private init () =
|
||||
let map = createMapWithLayers theCenter [| baseMapLayer |]
|
||||
map.addControl (ScaleLine.scaleLine [ scaleLine.bar false; scaleLine.minWidth 75 ])
|
||||
map.addControl (FullScreen.fullScreen [ ])
|
||||
let model = { Model.empty with map = map }
|
||||
model, Elmish.Cmd.none
|
||||
|
||||
@@ -253,11 +252,21 @@ let emptyModel = {
|
||||
json = ""
|
||||
}
|
||||
|
||||
let private hmr = HMR.createToken ()
|
||||
|
||||
[<HookComponent>]
|
||||
let private archivePopup (m: ModelArea option) =
|
||||
Hook.useHmr hmr
|
||||
|
||||
let modelArea, setModelArea =
|
||||
Hook.useState<ModelArea> (fun () -> m |> Option.defaultValue emptyModel)
|
||||
Hook.useEffectOnChange (m, Option.iter setModelArea)
|
||||
|
||||
Hook.useEffectOnChange (
|
||||
m,
|
||||
function
|
||||
| Some modelArea -> setModelArea modelArea
|
||||
| None -> ()
|
||||
)
|
||||
|
||||
let archives =
|
||||
if modelArea.archives > 0 then
|
||||
@@ -268,7 +277,8 @@ let private archivePopup (m: ModelArea option) =
|
||||
let areas =
|
||||
if modelArea.models > 0 then
|
||||
html $""" Available areas: {modelArea.models} """
|
||||
else Lit.nothing
|
||||
else
|
||||
Lit.nothing
|
||||
|
||||
html
|
||||
$"""
|
||||
@@ -299,20 +309,23 @@ let private archivePopup (m: ModelArea option) =
|
||||
"
|
||||
>
|
||||
{modelArea.name}
|
||||
<sp-divider> </sp-divider>
|
||||
<sp-divider size="s"></sp-divider>
|
||||
</div>
|
||||
<div>
|
||||
<span>{archives}</span>
|
||||
<span>{areas}</span>
|
||||
</div>
|
||||
<p>
|
||||
{archives}
|
||||
{areas}
|
||||
</p>
|
||||
</sp-popover>
|
||||
</div>
|
||||
"""
|
||||
|
||||
[<HookComponent>]
|
||||
let private topNav (dispatch: Msg -> unit) (model: Model) =
|
||||
Hook.useHmr hmr
|
||||
|
||||
let icon =
|
||||
match model.activeTab with
|
||||
| Tab.Select -> html $"""<img src="ob.png" height="35px"/>"""
|
||||
| Tab.Select -> html $"""<img src="ob.png" />"""
|
||||
| _ -> html $"""<sp-icon-undo></sp-icon-undo>"""
|
||||
|
||||
let handleActionMenu (ev: Types.Event) =
|
||||
@@ -320,87 +333,100 @@ let private topNav (dispatch: Msg -> unit) (model: Model) =
|
||||
| "logout" -> window.location.href <- "/signout"
|
||||
| _ -> ()
|
||||
|
||||
let menu =
|
||||
html
|
||||
$"""
|
||||
<sp-top-nav-item href="#about">Oceanbox</sp-top-nav-item>
|
||||
<sp-action-menu label="Account" placement="bottom-end" @change={Ev (handleActionMenu)} style="margin-inline-start: auto;">
|
||||
// NOTE: The img sizing is a bit weird, which the height is explicit
|
||||
html
|
||||
$"""
|
||||
<div class="atlas-top-nav">
|
||||
<div class="atlas-top-nav-start">
|
||||
<a href="/" style="height: 32px;">{icon}</a>
|
||||
<a href="#about">Oceanbox</a>
|
||||
</div>
|
||||
|
||||
<sp-action-menu
|
||||
label="Account"
|
||||
placement="bottom-end"
|
||||
@change={Ev handleActionMenu}
|
||||
>
|
||||
<sp-menu-item disabled>Settings</sp-menu-item>
|
||||
<sp-menu-item disabled>Profile</sp-menu-item>
|
||||
<sp-menu-divider></sp-menu-divider>
|
||||
<sp-menu-item disabled>Help</sp-menu-item>
|
||||
<sp-menu-item value="logout">Logout</sp-menu-item>
|
||||
</sp-action-menu>
|
||||
"""
|
||||
let menuButton =
|
||||
match model.activeTab with
|
||||
| Tab.Select -> menu
|
||||
| _ -> menu
|
||||
|
||||
html
|
||||
$"""
|
||||
<sp-top-nav size="s">
|
||||
<sp-top-nav-item @click={Ev (fun _ -> window.location.reload ())}>
|
||||
{icon}
|
||||
</sp-top-nav-item>
|
||||
{menuButton}
|
||||
</sp-top-nav>
|
||||
</div>
|
||||
"""
|
||||
|
||||
[<HookComponent>]
|
||||
let archiveSelectModal (modelAreaOpt: ModelArea option) (archives: ArchiveProps array) onClose =
|
||||
let private archiveSelectModal (modelAreaOpt: ModelArea option) (archives: ArchiveProps array) onClose =
|
||||
Hook.useHmr hmr
|
||||
|
||||
let modelAreaName = modelAreaOpt |> Option.map (fun model -> $"{model.name} archives") |> Option.defaultValue "N/A"
|
||||
let archiveRow (archive: ArchiveProps) =
|
||||
let selectArchive (archive: ArchiveProps) =
|
||||
do Lib.Umami.track("atlas-select-archive", {| id = archive.archiveId; name = archive.name |})
|
||||
sessionStorage["archive_id"] <- string archive.archiveId
|
||||
window.location.href <- "/map.html"
|
||||
|
||||
let startTimeStr = archive.startTime.ToString "dd/MM/yyyy"
|
||||
let daysLong = archive.endTime - archive.startTime
|
||||
|
||||
html
|
||||
$"""
|
||||
html $"""
|
||||
<sp-table-row @click={Ev (fun _ -> selectArchive archive)}>
|
||||
<sp-table-cell>{archive.name}</sp-table-cell>
|
||||
<sp-table-cell>{startTimeStr}</sp-table-cell>
|
||||
<sp-table-cell>{daysLong.Days}</sp-table-cell>
|
||||
</sp-table-row>
|
||||
"""
|
||||
|
||||
let archiveRows =
|
||||
match modelAreaOpt with
|
||||
| None -> html $"""No model area selected"""
|
||||
| Some modelArea -> archives |> Lit.mapUnique (fun a -> a.archiveId.ToString ()) archiveRow
|
||||
| Some modelArea ->
|
||||
archives
|
||||
|> Array.sortByDescending _.startTime
|
||||
|> Lit.mapUnique (fun a -> a.archiveId.ToString ()) archiveRow
|
||||
|
||||
let content () =
|
||||
if Array.isEmpty archives then
|
||||
html
|
||||
$"""
|
||||
<div class="full-box flex-center">
|
||||
<sp-progress-circle label="Loading archives" size="l" indeterminate></sp-progress-circle>
|
||||
</div>
|
||||
"""
|
||||
else
|
||||
html
|
||||
$"""
|
||||
<sp-table
|
||||
size="s"
|
||||
scroller="true"
|
||||
style="width: 100%%;"
|
||||
>
|
||||
<sp-table-head>
|
||||
<sp-table-head-cell>Name</sp-table-head-cell>
|
||||
<sp-table-head-cell>Start</sp-table-head-cell>
|
||||
<sp-table-head-cell>Days</sp-table-head-cell>
|
||||
</sp-table-head>
|
||||
<sp-table-body>
|
||||
{archiveRows}
|
||||
</sp-table-body>
|
||||
</sp-table>
|
||||
"""
|
||||
|
||||
html
|
||||
$"""
|
||||
<sp-underlay ?open={modelAreaOpt.IsSome} @click={fun _ -> onClose ()}></sp-underlay>
|
||||
|
||||
<sp-dialog size="l" dismissable @close={Ev (fun _ -> onClose ())}>
|
||||
<h2 slot="heading"> {modelAreaOpt
|
||||
|> Option.map _.name
|
||||
|> Option.defaultValue "N/A"}</h2>
|
||||
<h4>Archives</h4>
|
||||
<sp-table
|
||||
size="s"
|
||||
scroller="true"
|
||||
>
|
||||
<sp-table-head>
|
||||
<sp-table-head-cell>Name</sp-table-head-cell>
|
||||
<sp-table-head-cell>Start</sp-table-head-cell>
|
||||
<sp-table-head-cell>Days</sp-table-head-cell>
|
||||
</sp-table-head>
|
||||
<sp-table-body>
|
||||
{archiveRows}
|
||||
</sp-table-body>
|
||||
</sp-table>
|
||||
<h2 slot="heading">{modelAreaName}</h2>
|
||||
{content ()}
|
||||
</sp-dialog>
|
||||
"""
|
||||
"""
|
||||
|
||||
let selectStyle name =
|
||||
let stroke' =
|
||||
Style.stroke [ stroke.color "rgba(50, 50, 50, 0.9)"; stroke.width 1.3 ]
|
||||
let fill' = Style.fill [ fill.color "rgba(255, 255, 255, 0.5)" ]
|
||||
Fable.OpenLayers.Style.style [
|
||||
|
||||
Style.style [
|
||||
style.fill fill'
|
||||
style.stroke stroke'
|
||||
style.text (
|
||||
@@ -414,9 +440,8 @@ let selectStyle name =
|
||||
|
||||
[<HookComponent>]
|
||||
let userAccessModal isRegistered isActive =
|
||||
// let showModal, setModal = Hook.useState (isActive || isRegistered)
|
||||
Hook.useHmr hmr
|
||||
|
||||
console.debug $"user registered={isRegistered} active={isActive}"
|
||||
let accessNotifier =
|
||||
if not isRegistered then
|
||||
html
|
||||
@@ -445,9 +470,8 @@ let userAccessModal isRegistered isActive =
|
||||
</div>
|
||||
"""
|
||||
|
||||
|
||||
[<LitElement("atlas-app")>]
|
||||
let SelectApp () =
|
||||
let AtlasApp () =
|
||||
Hook.useHmr hmr
|
||||
LitElement.init (fun cfg -> cfg.useShadowDom <- false) |> ignore
|
||||
|
||||
@@ -474,7 +498,9 @@ let SelectApp () =
|
||||
Hook.useEffectOnce (fun () ->
|
||||
async {
|
||||
do! Auth.establishAuthentication ()
|
||||
do! Auth.setId ()
|
||||
// do! Auth.startTokenRefreshLoopOrLogin ()
|
||||
do! Lib.Umami.init ()
|
||||
|
||||
do! Atlantis.IDB.tryResetOutdatedIDB () |> Async.AwaitPromise
|
||||
|
||||
@@ -492,7 +518,7 @@ let SelectApp () =
|
||||
// // TODO: Refresh in expiry time?
|
||||
// sessionStorage["barentswatch_token"] <- token.AccessToken
|
||||
|
||||
do! Utils.initAtlantisSessionUrls ()
|
||||
do! Auth.initSessionUrls ()
|
||||
|
||||
// let drifters = driftersJobApi ()
|
||||
// let! fenceRadius = drifters.getFenceRadius()
|
||||
@@ -536,7 +562,6 @@ let SelectApp () =
|
||||
"click",
|
||||
fun (event: MapBrowserEvent) ->
|
||||
let features = model.map.getFeaturesAtPixel event.pixel
|
||||
console.debug ("Features:", features)
|
||||
features
|
||||
|> Array.tryHead
|
||||
|> Option.iter (fun feature ->
|
||||
@@ -562,12 +587,10 @@ let SelectApp () =
|
||||
|
||||
let selectedModelAreaArchives =
|
||||
model.selectedModelArea
|
||||
|> Option.map (fun modelArea ->
|
||||
if Map.containsKey modelArea.modelAreaId model.archives then
|
||||
model.archives[modelArea.modelAreaId]
|
||||
else
|
||||
[||]
|
||||
)
|
||||
|> Option.bind (fun modelArea ->
|
||||
model.archives
|
||||
|> Map.tryFind modelArea.modelAreaId
|
||||
)
|
||||
|> Option.defaultValue [||]
|
||||
|
||||
html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<DefineConstants>FABLE_COMPILER</DefineConstants>
|
||||
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
||||
<Version>2.87.0</Version>
|
||||
@@ -11,27 +11,27 @@
|
||||
<Compile Include="Atlas.fs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Fable.Browser.IndexedDB" Version="2.2.0" />
|
||||
<PackageReference Include="Fable.Browser.WebGL" Version="1.3.0" />
|
||||
<PackageReference Include="Fable.Core" Version="4.4.0" />
|
||||
<PackageReference Include="Fable.Elmish" Version="4.2.0" />
|
||||
<PackageReference Include="Fable.Fetch" Version="2.7.0" />
|
||||
<PackageReference Include="Fable.Lit" Version="1.6.2-oceanbox" />
|
||||
<PackageReference Include="Fable.Lit.React" Version="1.6.2-oceanbox" />
|
||||
<PackageReference Include="Fable.Lit.Elmish" Version="1.6.2-oceanbox" />
|
||||
<PackageReference Include="Fable.Promise" Version="3.2.0" />
|
||||
<PackageReference Include="Fable.React" Version="9.4.0" />
|
||||
<PackageReference Include="Fable.Remoting.Client" Version="7.32.0" />
|
||||
<PackageReference Include="Fable.Remoting.MsgPack" Version="1.24.0" />
|
||||
<PackageReference Include="Fable.OpenLayers" Version="2.18.0" />
|
||||
<PackageReference Include="Fable.SignalR.Elmish" Version="2.1.0" />
|
||||
<PackageReference Include="Fable.SimpleHttp" Version="3.6.0" />
|
||||
<PackageReference Include="Feliz" Version="2.9.0" />
|
||||
<PackageReference Include="Feliz.CompilerPlugins" Version="2.2.0" />
|
||||
<PackageReference Include="Thoth.Fetch" Version="3.0.1" />
|
||||
<PackageReference Include="Thoth.Json" Version="10.4.1" />
|
||||
<PackageReference Update="FSharp.Core" Version="9.0.201" />
|
||||
<PackageReference Include="Matplotlib.ColorMaps" Version="3.0.1" />
|
||||
<PackageReference Include="Fable.Browser.IndexedDB" />
|
||||
<PackageReference Include="Fable.Browser.WebGL" />
|
||||
<PackageReference Include="Fable.Core" />
|
||||
<PackageReference Include="Fable.Elmish" />
|
||||
<PackageReference Include="Fable.Fetch" />
|
||||
<PackageReference Include="Fable.Lit" />
|
||||
<PackageReference Include="Fable.Lit.React" />
|
||||
<PackageReference Include="Fable.Lit.Elmish" />
|
||||
<PackageReference Include="Fable.Promise" />
|
||||
<PackageReference Include="Fable.React" />
|
||||
<PackageReference Include="Fable.Remoting.Client" />
|
||||
<PackageReference Include="Fable.Remoting.MsgPack" />
|
||||
<PackageReference Include="Fable.OpenLayers" />
|
||||
<PackageReference Include="Fable.SignalR.Elmish" />
|
||||
<PackageReference Include="Fable.SimpleHttp" />
|
||||
<PackageReference Include="Feliz" />
|
||||
<PackageReference Include="Feliz.CompilerPlugins" />
|
||||
<PackageReference Include="Thoth.Fetch" />
|
||||
<PackageReference Include="Thoth.Json" />
|
||||
<PackageReference Include="Matplotlib.ColorMaps" />
|
||||
<PackageReference Include="FSharp.Core" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Lib\Lib.fsproj" />
|
||||
|
||||
654
src/Atlantis/src/Client/Atlas/packages.lock.json
Normal file
654
src/Atlantis/src/Client/Atlas/packages.lock.json
Normal file
@@ -0,0 +1,654 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dependencies": {
|
||||
"net10.0": {
|
||||
"Fable.Browser.IndexedDB": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "6RU8aqUeb4qpAekPEjnpaWP+RRTyYMB4ICE06eZoMoTXPq0oGWxsEkHPgDJIPVTmyDuAGJ4YMcDCt2D8850xMw==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.7.2",
|
||||
"Fable.Browser.Dom": "2.14.0",
|
||||
"Fable.Browser.Event": "1.5.0",
|
||||
"Fable.Core": "3.2.8"
|
||||
}
|
||||
},
|
||||
"Fable.Browser.WebGL": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.3.0, )",
|
||||
"resolved": "1.3.0",
|
||||
"contentHash": "iQognakmr62KccqZg++oenn1J0eSdCexAFUII0fSWAz1tTfdaPxrFKIjagHd/3HWw5NettpyNJREVRDghklYTQ==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.7.2",
|
||||
"Fable.Browser.Dom": "2.16.0",
|
||||
"Fable.Browser.Event": "1.6.0",
|
||||
"Fable.Core": "3.2.8"
|
||||
}
|
||||
},
|
||||
"Fable.Core": {
|
||||
"type": "Direct",
|
||||
"requested": "[4.4.0, )",
|
||||
"resolved": "4.4.0",
|
||||
"contentHash": "zVQdiC8RqCOBb3KACTp9ASU9Q46esXXWosZQT/Vu/RhCpkfVwXPmBxVayy3iyqaRWc7XSu4Af7pbOqlcL/RtdA=="
|
||||
},
|
||||
"Fable.Elmish": {
|
||||
"type": "Direct",
|
||||
"requested": "[4.2.0, )",
|
||||
"resolved": "4.2.0",
|
||||
"contentHash": "A8lDcHbz2AKcwFa6IlnK8I/21nbsxBcP5Vxq6Gp+jT8dU7Vjpnk8Pbry5+zQrlqjwt1XHU/S5Oo0KZqaGemPUA==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.7.2",
|
||||
"Fable.Core": "3.7.1"
|
||||
}
|
||||
},
|
||||
"Fable.Fetch": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.7.0, )",
|
||||
"resolved": "2.7.0",
|
||||
"contentHash": "2ndGZZTqpX9Hyso51tnIxWAskN2zrHX+7LeAwfG4zew+DtMMGa/3IyJGl2BOYUwweq2MhfuVqs1K3avgBFDq+Q==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.7.2",
|
||||
"Fable.Browser.Blob": "1.2.0",
|
||||
"Fable.Browser.Event": "1.5.0",
|
||||
"Fable.Core": "3.7.1",
|
||||
"Fable.Promise": "2.2.2"
|
||||
}
|
||||
},
|
||||
"Fable.Lit": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.6.2-oceanbox, )",
|
||||
"resolved": "1.6.2-oceanbox",
|
||||
"contentHash": "ylo6UgB6FiGyINpDvryYt3GPl8MH6fvB5tiNizCmsNNerGxw/THFMGGJHmukQDh64NHru4ARhPTPgkBvsyOTVA==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "8.0.300",
|
||||
"Fable.Browser.Dom": "2.17.0",
|
||||
"Fable.Core": "4.3.0",
|
||||
"Fable.Promise": "3.2.0"
|
||||
}
|
||||
},
|
||||
"Fable.Lit.Elmish": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.6.2-oceanbox, )",
|
||||
"resolved": "1.6.2-oceanbox",
|
||||
"contentHash": "K0fBlpHWZs07s3OYcpBZXVo+xoot62f+USdw8Pi9yxd8a6rmfsbbPlDQvGe2k6VpkEelXNL0AMwEt9GxEY1DeQ==",
|
||||
"dependencies": {
|
||||
"Fable.Elmish": "4.2.0",
|
||||
"Fable.Lit": "1.6.2-oceanbox"
|
||||
}
|
||||
},
|
||||
"Fable.Lit.React": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.6.2-oceanbox, )",
|
||||
"resolved": "1.6.2-oceanbox",
|
||||
"contentHash": "+k0/F4mWZe91GuPDJxBTawUFKegQyNU48OjwAQTzzp3RlibCo1wvFtZjISJz83OvHcjuCSmO02i7uxWm9j6gFw==",
|
||||
"dependencies": {
|
||||
"Fable.Lit": "1.6.2-oceanbox",
|
||||
"Feliz": "2.8.0"
|
||||
}
|
||||
},
|
||||
"Fable.OpenLayers": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.19.0, )",
|
||||
"resolved": "2.19.0",
|
||||
"contentHash": "zVwnqj8LHHUVuw4loS88ZvFCYILKDtG/NWzhGOLwZ5yqj+pRxlD6Mex7zsGrSc08y3P/D/LLdjKmJuE/Nbgo6Q==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "9.0.303",
|
||||
"Fable.Browser.Dom": "2.18.0",
|
||||
"Fable.Browser.WebGL": "1.3.0",
|
||||
"Fable.Core": "4.3.0"
|
||||
}
|
||||
},
|
||||
"Fable.Promise": {
|
||||
"type": "Direct",
|
||||
"requested": "[3.2.0, )",
|
||||
"resolved": "3.2.0",
|
||||
"contentHash": "4A+Iiembrny2h3AE2BIbchfuLmWHNhpkOTvbTtFXHtGzHVMqEVFRXrAfdy83wX2wK5Og3fqRo1y8t/Bqkd7j6g==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.7.2",
|
||||
"Fable.Core": "3.7.1"
|
||||
}
|
||||
},
|
||||
"Fable.React": {
|
||||
"type": "Direct",
|
||||
"requested": "[9.4.0, )",
|
||||
"resolved": "9.4.0",
|
||||
"contentHash": "c33FD2BumoYvu4/8bz2ToWaLZyfq2GMo7nq0RB/Bdoj7KdNObNBw2s1jWTi9whcf/s3tmikoXS4gZUKpD9MJ8g==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.7.2",
|
||||
"Fable.React.Types": "18.3.0",
|
||||
"Fable.ReactDom.Types": "18.2.0"
|
||||
}
|
||||
},
|
||||
"Fable.Remoting.Client": {
|
||||
"type": "Direct",
|
||||
"requested": "[7.32.0, )",
|
||||
"resolved": "7.32.0",
|
||||
"contentHash": "PMZ0gj8UXXBKrLg71IwGGTMmy2woSdesjFYkrkDNYmhNDvz3Z/h05fJYOVXYYKXp/d2XRX0fHtGV0DuYppip7A==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.7.2",
|
||||
"Fable.Browser.XMLHttpRequest": "1.0.0",
|
||||
"Fable.Core": "3.1.5",
|
||||
"Fable.Remoting.MsgPack": "1.24.0",
|
||||
"Fable.SimpleJson": "3.24.0"
|
||||
}
|
||||
},
|
||||
"Fable.Remoting.MsgPack": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.24.0, )",
|
||||
"resolved": "1.24.0",
|
||||
"contentHash": "Bn3nzoZbib6lPk70bIJumEu2wFMxciB4o8k0Zw6tRfAOpNKvUsi79OOll2nW3FU1P6MVBepT43m+R8JvfYnNiw==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.7.2"
|
||||
}
|
||||
},
|
||||
"Fable.SignalR.Elmish": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.1.0, )",
|
||||
"resolved": "2.1.0",
|
||||
"contentHash": "sPPuEcpKlRGACbX7Hk4kh31+aii8GAM8toTwYpmrtU+Zl9QocwbWK6nPJaE0YbQ41ZJgohyU6bNhKt7+SPKZhw==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "9.0.100",
|
||||
"Fable.Elmish": "4.2.0",
|
||||
"Fable.Promise": "3.2.0",
|
||||
"Fable.SignalR": "2.1.0"
|
||||
}
|
||||
},
|
||||
"Fable.SimpleHttp": {
|
||||
"type": "Direct",
|
||||
"requested": "[3.6.0, )",
|
||||
"resolved": "3.6.0",
|
||||
"contentHash": "RHXu3OQVxoxObErhUWl7J9JWXqDxLaQrpIXyo2MECF1a9ekNZ5bBnDGVB1RCEKRpVFB6SOun/pk+DB5wJDYmmg==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.6.2",
|
||||
"Fable.Browser.Dom": "1.0.0",
|
||||
"Fable.Browser.XMLHttpRequest": "1.1.0",
|
||||
"Fable.Core": "3.0.0"
|
||||
}
|
||||
},
|
||||
"Feliz": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.9.0, )",
|
||||
"resolved": "2.9.0",
|
||||
"contentHash": "8nyGREGA60RysdSBamVWmr68MG+3lLy76W17fBiGaKi7uMFbtRcYBLyNtp2NyGZFfnuWCEyDAmAXM5YFnDhbhg==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.7.2",
|
||||
"Fable.ReactDom.Types": "18.2.0",
|
||||
"Feliz.CompilerPlugins": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Feliz.CompilerPlugins": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.2.0, )",
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "ACkO++Hp4lUrEx/axeehIL5/3R8jMnak+CYpzd0/kLpejp9BETtrgjHK7oj6Lh3V9fB7WoAKsCxyPSrm4ADN2w==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.7.2",
|
||||
"Fable.AST": "4.2.1"
|
||||
}
|
||||
},
|
||||
"FSharp.Core": {
|
||||
"type": "Direct",
|
||||
"requested": "[9.0.303, )",
|
||||
"resolved": "9.0.303",
|
||||
"contentHash": "6JlV8aD8qQvcmfoe/PMOxCHXc0uX4lR23u0fAyQtnVQxYULLoTZgwgZHSnRcuUHOvS3wULFWcwdnP1iwslH60g=="
|
||||
},
|
||||
"Matplotlib.ColorMaps": {
|
||||
"type": "Direct",
|
||||
"requested": "[3.0.1, )",
|
||||
"resolved": "3.0.1",
|
||||
"contentHash": "Amw/NumOXIOB4Z/YbBErDd7gcZrtNhG10aeF9MydXUVNmmf7BJKeHDroSnzMRbsUOf3oQCXhzyjng6mhmRA0LA==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "6.0.4"
|
||||
}
|
||||
},
|
||||
"Thoth.Fetch": {
|
||||
"type": "Direct",
|
||||
"requested": "[3.0.1, )",
|
||||
"resolved": "3.0.1",
|
||||
"contentHash": "5i8KQwTFzDEoIjE/fAwCw0GFICCsFzVkVq2w4uU1fRlOqbSfLlUNcCEq6JkeAvQ+Jj7syMKNPSH994T8NswcpA==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.7.2",
|
||||
"Fable.Core": "3.2.8",
|
||||
"Fable.Fetch": "2.1.0",
|
||||
"Fable.Promise": "2.0.0",
|
||||
"Thoth.Json": "6.0.0"
|
||||
}
|
||||
},
|
||||
"Thoth.Json": {
|
||||
"type": "Direct",
|
||||
"requested": "[10.4.1, )",
|
||||
"resolved": "10.4.1",
|
||||
"contentHash": "hs76/uO+gHhvnlaxQDqbpUX2Y0L97ilEZ1Nx+LA4D6N7fuAYJmNwQWZB/KQLBE7wIeWK5oXMFHCuKdImSrF1Bg==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "5.0.2",
|
||||
"Fable.Core": "4.1.0"
|
||||
}
|
||||
},
|
||||
"Dapr.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.16.0",
|
||||
"contentHash": "6JyPI8LxNXSjSpO9vTdbfJh78zOiiC0sgeaXuY8O6SJQh2epaRdEPw0UpamNnld3CkDjp69/VCphox7pU/lh1Q==",
|
||||
"dependencies": {
|
||||
"Dapr.Protos": "1.16.0",
|
||||
"Google.Api.CommonProtos": "2.17.0",
|
||||
"Google.Protobuf": "3.32.0",
|
||||
"Grpc.Net.Client": "2.71.0",
|
||||
"Microsoft.Extensions.Configuration": "9.0.8",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.8",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Http": "9.0.8",
|
||||
"Microsoft.Extensions.Logging": "9.0.8",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Options": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Dapr.Protos": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.16.0",
|
||||
"contentHash": "4k4iKjyRCsFwX7KY5tDcBWDe6JPkhnvN1nqd8zRhDw3YcajF/Br3SU072YdEQKUQ/MJNvqafvzCNPbqSbK3nqg==",
|
||||
"dependencies": {
|
||||
"Google.Api.CommonProtos": "2.17.0",
|
||||
"Google.Protobuf": "3.32.0",
|
||||
"Grpc.Net.Client": "2.71.0",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Fable.AST": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.2.1",
|
||||
"contentHash": "/4V6U7Qw/WIRRxm9NJ7b+YTXTRCTk6/YKeJnbKYaVbtT45MstA3jkFvRfV0FqVFtkG9AL4uccetreygTjK7nbQ=="
|
||||
},
|
||||
"Fable.Browser.Blob": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.4.0",
|
||||
"contentHash": "UlaxrIXUfMmABjP+8a4XJp/Af+eCRKa8KJ57Olq4sqphmPLn/gNtp3sk5hRNBZ385lwUszbO5yd3Q/rrl9BdOQ==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.7.2",
|
||||
"Fable.Core": "3.2.8"
|
||||
}
|
||||
},
|
||||
"Fable.Browser.Dom": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.18.0",
|
||||
"contentHash": "usu19HS3yRIPvzQ//Yj+Dp6SkJ1fkVUVOREaeDR4iLXGTKl0UqR1nPT1tEBX2GGMefj7dVrmG0dbONirOlVFBw==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.7.2",
|
||||
"Fable.Browser.Blob": "1.4.0",
|
||||
"Fable.Browser.Event": "1.7.0",
|
||||
"Fable.Browser.WebStorage": "1.3.0",
|
||||
"Fable.Core": "3.2.8"
|
||||
}
|
||||
},
|
||||
"Fable.Browser.Event": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.7.0",
|
||||
"contentHash": "x+wqXQK0l4VlCnELDp68GC/mZAx6NbicDxYPliyAoNq8RPNDeR3R782icNwI5YmA+ufq11XvG6w1JjsL/ldy7w==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.7.2",
|
||||
"Fable.Browser.Gamepad": "1.3.0",
|
||||
"Fable.Core": "3.2.8"
|
||||
}
|
||||
},
|
||||
"Fable.Browser.Gamepad": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.3.0",
|
||||
"contentHash": "C4HZDzCgff+U094QjpQlJh425W5j5/vojvOi2FV5UFS34l7TJ6YBgBPpKoro02QhAi/UF3AeocR+V2yiYxHb0A==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.7.2",
|
||||
"Fable.Core": "3.2.8"
|
||||
}
|
||||
},
|
||||
"Fable.Browser.WebStorage": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.3.0",
|
||||
"contentHash": "x8JL9oEtPiK0JY4GrRTqhomiLxT6Jaiv5uu8VXiNeA78bFvUogZWxQeejsK83iNFGErK5wpdiPd0tsREZTRLeg==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.7.2",
|
||||
"Fable.Browser.Event": "1.6.0",
|
||||
"Fable.Core": "3.2.8"
|
||||
}
|
||||
},
|
||||
"Fable.Browser.XMLHttpRequest": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "27p/F8781NrnV9vQ23RhX10ww9MDkX+Yi3yTiV9s8U8Bufi/VCCjS4swX0LXvgKQANN3k87CwaNeiO75r2U7gw==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.6.2",
|
||||
"Fable.Browser.Blob": "1.1.0",
|
||||
"Fable.Browser.Event": "1.0.0",
|
||||
"Fable.Core": "3.0.0"
|
||||
}
|
||||
},
|
||||
"Fable.Parsimmon": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.0.0",
|
||||
"contentHash": "AaHqEcwjjv8q5S2gCNu6XsVcpChYM8D6aEb3sjjsAiLspwLrNLqm6vOEKdJKGnh0gSLHg6UWzLGA/Q4jrk+t/w==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.6.2",
|
||||
"Fable.Core": "3.0.0"
|
||||
}
|
||||
},
|
||||
"Fable.React.Types": {
|
||||
"type": "Transitive",
|
||||
"resolved": "18.3.0",
|
||||
"contentHash": "/b8WZ3Bdfhqy9r60ZK9JGZaGNjIMb0ogsrvWIg3k7KfCEvJs5X6+7hCybVkyjVoxwzn9wLyYGRbh5wmuHQT/Vg==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.7.2",
|
||||
"Fable.Browser.Dom": "2.4.4",
|
||||
"Fable.Core": "3.2.7"
|
||||
}
|
||||
},
|
||||
"Fable.ReactDom.Types": {
|
||||
"type": "Transitive",
|
||||
"resolved": "18.2.0",
|
||||
"contentHash": "2WoBjsLiSgrvR68OJXko0iVaqeMbkPM5Bx813A1WlxOSCJ50M9fwnlwG/MUEZtiOIhQmku/YTJY5a8E8r1+j2Q==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.7.2",
|
||||
"Fable.React.Types": "18.3.0"
|
||||
}
|
||||
},
|
||||
"Fable.SignalR": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.0",
|
||||
"contentHash": "CTBaS44I4fGG++g9wRbNO/gOxy5gPKBkw1UPP9rA8j/bX0SpfJENtavVI0ZHJLltf5umy01RG9HMWlMpi1Q6Sw==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "9.0.100",
|
||||
"Fable.Promise": "3.2.0",
|
||||
"Fable.Remoting.MsgPack": "1.24.0",
|
||||
"Fable.SimpleJson": "3.24.0"
|
||||
}
|
||||
},
|
||||
"Fable.SimpleJson": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.24.0",
|
||||
"contentHash": "mNk5s+8arkrrupT52/840xybT/DmaPUsJ926fTHk2uHOaWLnyNbUPY63Yg8zJZFCxSCzWrFpmB8rS9fcLVLJSg==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "4.7.0",
|
||||
"Fable.Core": "3.1.5",
|
||||
"Fable.Parsimmon": "4.0.0"
|
||||
}
|
||||
},
|
||||
"Google.Api.CommonProtos": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.17.0",
|
||||
"contentHash": "elfQPknFr495hm7vdy6ZlgyQh6yzZq9TU7sS35L/Fj/fqjM/mUGau9gVJLhvQEtUlPjtR80hpn/m9HvBMyCXIw==",
|
||||
"dependencies": {
|
||||
"Google.Protobuf": "[3.31.1, 4.0.0]"
|
||||
}
|
||||
},
|
||||
"Google.Protobuf": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.32.0",
|
||||
"contentHash": "fsKxV5bhcvXmZi+cUo5+IxzRMBHwHeFO8G5utNa9f+Mu37kmfy8JcUVvWPt4cX7EuQWAjjHUjZqVl7nGSTRHRg=="
|
||||
},
|
||||
"Grpc.Core.Api": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.71.0",
|
||||
"contentHash": "QquqUC37yxsDzd1QaDRsH2+uuznWPTS8CVE2Yzwl3CvU4geTNkolQXoVN812M2IwT6zpv3jsZRc9ExJFNFslTg=="
|
||||
},
|
||||
"Grpc.Net.Client": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.71.0",
|
||||
"contentHash": "U1vr20r5ngoT9nlb7wejF28EKN+taMhJsV9XtK9MkiepTZwnKxxiarriiMfCHuDAfPUm9XUjFMn/RIuJ4YY61w==",
|
||||
"dependencies": {
|
||||
"Grpc.Net.Common": "2.71.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "6.0.0"
|
||||
}
|
||||
},
|
||||
"Grpc.Net.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.71.0",
|
||||
"contentHash": "v0c8R97TwRYwNXlC8GyRXwYTCNufpDfUtj9la+wUrZFzVWkFJuNAltU+c0yI3zu0jl54k7en6u2WKgZgd57r2Q==",
|
||||
"dependencies": {
|
||||
"Grpc.Core.Api": "2.71.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "6m+8Xgmf8UWL0p/oGqBM+0KbHE5/ePXbV1hKXgC59zEv0aa0DW5oiiyxDbK5kH5j4gIvyD5uWL0+HadKBJngvQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Primitives": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "yNou2KM35RvzOh4vUFtl2l33rWPvOCoba+nzEDJ+BgD8aOL/jew4WPCibQvntRfOJ2pJU8ARygSMD+pdjvDHuA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Binder": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "0vK9DnYrYChdiH3yRZWkkp4x4LbrfkWEdBc5HOsQ8t/0CLOWKXKkkhOE8A1shlex0hGydbGrhObeypxz/QTm+w==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "JJjI2Fa+QtZcUyuNjbKn04OjIUX5IgFGFu/Xc+qvzh1rXdZHLcnqqVXhR4093bGirTwacRlHiVg1XYI9xum6QQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "xY3lTjj4+ZYmiKIkyWitddrp1uL5uYiweQjqo4BKBw01ZC4HhcfgLghDpPZcUlppgWAFqFy9SgkiYWOMx365pw=="
|
||||
},
|
||||
"Microsoft.Extensions.Diagnostics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "BKkLCFXzJvNmdngeYBf72VXoZqTJSb1orvjdzDLaGobicoGFBPW8ug2ru1nnEewMEwJzMgnsjHQY8EaKWmVhKg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "9.0.8",
|
||||
"Microsoft.Extensions.Diagnostics.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Options.ConfigurationExtensions": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Diagnostics.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "UDY7blv4DCyIJ/8CkNrQKLaAZFypXQavRZ2DWf/2zi1mxYYKKw2t8AOCBWxNntyPZHPGhtEmL3snFM98ADZqTw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Options": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Http": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "jDj+4aDByk47oESlDDTtk6LWzlXlmoCsjCn6ihd+i9OntN885aPLszUII5+w0B/7wYSZcS3KdjqLAIhKLSiBXQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Diagnostics": "9.0.8",
|
||||
"Microsoft.Extensions.Logging": "9.0.8",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Options": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "Z/7ze+0iheT7FJeZPqJKARYvyC2bmwu3whbm/48BJjdlGVvgDguoCqJIkI/67NkroTYobd5geai1WheNQvWrgA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.8",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Options": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "pYnAffJL7ARD/HCnnPvnFKSIHnTSmWz84WIlT9tPeQ4lHNiu0Az7N/8itihWvcF8sT+VVD5lq8V+ckMzu4SbOw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "OmTaQ0v4gxGQkehpwWIqPoEiwsPuG/u4HUsbOFoWGx4DKET2AXzopnFe/fE608FIhzc/kcg2p8JdyMRCCUzitQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Primitives": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Options.ConfigurationExtensions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "eW2s6n06x0w6w4nsX+SvpgsFYkl+Y0CttYAt6DKUXeqprX+hzNqjSfOh637fwNJBg7wRBrOIRHe49gKiTgJxzQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Configuration.Binder": "9.0.8",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Options": "9.0.8",
|
||||
"Microsoft.Extensions.Primitives": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.8",
|
||||
"contentHash": "tizSIOEsIgSNSSh+hKeUVPK7xmTIjR8s+mJWOu1KXV3htvNQiPMFRMO17OdI1y/4ZApdBVk49u/08QGC9yvLug=="
|
||||
},
|
||||
"atlantis.api": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "[9.0.303, )",
|
||||
"Hipster.Api": "[1.0.1, )",
|
||||
"Petimeter.Api": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
"hipster.api": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Dapr.Actors": "[1.16.0, )",
|
||||
"Drifters.Api": "[6.22.0, )",
|
||||
"FSharp.Core": "[9.0.303, )"
|
||||
}
|
||||
},
|
||||
"lib": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Atlantis.Api": "[1.0.1, )",
|
||||
"FSharp.Core": "[9.0.303, )",
|
||||
"Fable.Browser.IndexedDB": "[2.2.0, )",
|
||||
"Fable.Browser.WebGL": "[1.3.0, )",
|
||||
"Fable.Core": "[4.4.0, )",
|
||||
"Fable.Elmish": "[4.2.0, )",
|
||||
"Fable.Fetch": "[2.7.0, )",
|
||||
"Fable.Lit": "[1.6.2-oceanbox, )",
|
||||
"Fable.Lit.Elmish": "[1.6.2-oceanbox, )",
|
||||
"Fable.Lit.React": "[1.6.2-oceanbox, )",
|
||||
"Fable.OpenLayers": "[2.19.0, )",
|
||||
"Fable.Promise": "[3.2.0, )",
|
||||
"Fable.React": "[9.4.0, )",
|
||||
"Fable.Remoting.Client": "[7.32.0, )",
|
||||
"Fable.Remoting.MsgPack": "[1.24.0, )",
|
||||
"Fable.SignalR.Elmish": "[2.1.0, )",
|
||||
"Fable.SimpleHttp": "[3.6.0, )",
|
||||
"Feliz": "[2.9.0, )",
|
||||
"Feliz.CompilerPlugins": "[2.2.0, )",
|
||||
"FsToolkit.ErrorHandling": "[5.0.1, )",
|
||||
"Hipster.Api": "[1.0.1, )",
|
||||
"Matplotlib.ColorMaps": "[3.0.1, )",
|
||||
"Oceanbox.DataAgent.Api": "[7.2.1, )",
|
||||
"Petimeter.Api": "[1.0.0, )",
|
||||
"Sorcerer.Api": "[4.19.0, )",
|
||||
"Thoth.Fetch": "[3.0.1, )",
|
||||
"Thoth.Json": "[10.4.1, )"
|
||||
}
|
||||
},
|
||||
"Oceanbox.DataAgent.Api": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "[9.0.303, )"
|
||||
}
|
||||
},
|
||||
"petimeter.api": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Dapr.Actors": "[1.16.0, )",
|
||||
"FSharp.Core": "[9.0.303, )"
|
||||
}
|
||||
},
|
||||
"sorcerer.api": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Drifters.Api": "[6.22.0, )",
|
||||
"FSharp.Core": "[9.0.303, )",
|
||||
"Oceanbox.DataAgent.Api": "[7.2.1, )"
|
||||
}
|
||||
},
|
||||
"Dapr.Actors": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[1.16.0, )",
|
||||
"resolved": "1.16.0",
|
||||
"contentHash": "s9v6VofXXYoRqZJQlQbvNYYSlGhkL+Z+bpqrx1TRo06kLhANeDmXA9yeVaD+1KwJIO1chUFj5O4iKuTxIkg1sA==",
|
||||
"dependencies": {
|
||||
"Dapr.Client": "1.16.0",
|
||||
"Dapr.Common": "1.16.0",
|
||||
"Google.Api.CommonProtos": "2.17.0",
|
||||
"Google.Protobuf": "3.32.0",
|
||||
"Grpc.Net.Client": "2.71.0",
|
||||
"Microsoft.Extensions.Configuration": "9.0.8",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.8",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Http": "9.0.8",
|
||||
"Microsoft.Extensions.Logging": "9.0.8",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Options": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Dapr.Client": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[1.16.0, )",
|
||||
"resolved": "1.16.0",
|
||||
"contentHash": "dFDKol+mtQrk1lIKlEyCx3k6W0Pf+0wC6xcsaDqa0Bg+XCWDc4juROuDcSb0/L1Y+Ev6LSLDMC/FgzNWMw9YtQ==",
|
||||
"dependencies": {
|
||||
"Dapr.Common": "1.16.0",
|
||||
"Dapr.Protos": "1.16.0",
|
||||
"Google.Api.CommonProtos": "2.17.0",
|
||||
"Google.Protobuf": "3.32.0",
|
||||
"Grpc.Net.Client": "2.71.0",
|
||||
"Microsoft.Extensions.Configuration": "9.0.8",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.8",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Http": "9.0.8",
|
||||
"Microsoft.Extensions.Logging": "9.0.8",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.8",
|
||||
"Microsoft.Extensions.Options": "9.0.8"
|
||||
}
|
||||
},
|
||||
"Drifters.Api": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.22.0, )",
|
||||
"resolved": "6.22.0",
|
||||
"contentHash": "EQguKE22Tfd3ayO/jdWiWMBK5R1uzcYo+8agG3ZzAJ1ltl72mIXHqr68BKqO4uhOLtiFs8ErZa4cZ9NVueYHWA==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "9.0.201"
|
||||
}
|
||||
},
|
||||
"FsToolkit.ErrorHandling": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[5.0.1, )",
|
||||
"resolved": "5.0.1",
|
||||
"contentHash": "93oG3WSogK05H4gkikAmx5pBf30TQJfO1Jky+o/N/nv+RTP3nfOfjlmCHzuyUjQCRFOQog/xQabcky+WBWceeQ==",
|
||||
"dependencies": {
|
||||
"FSharp.Core": "9.0.300"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Version>6.20.0</Version>
|
||||
<RootNamespace>Archivist</RootNamespace>
|
||||
</PropertyGroup>
|
||||
@@ -10,9 +10,9 @@
|
||||
<Compile Include="App.fs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Fable.Lit" Version="1.4.2" />
|
||||
<PackageReference Include="Fable.Remoting.Client" Version="7.32.0" />
|
||||
<PackageReference Update="FSharp.Core" Version="9.0.201" />
|
||||
<PackageReference Include="Fable.Lit" />
|
||||
<PackageReference Include="Fable.Remoting.Client" />
|
||||
<PackageReference Include="FSharp.Core" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\Interfaces\Archmaester\Archmaester.Api.fsproj" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<DefineConstants>FABLE_COMPILER</DefineConstants>
|
||||
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
||||
<Version>2.102.0</Version>
|
||||
@@ -9,19 +9,19 @@
|
||||
<RootNamespace>Main</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Include="index.html"/>
|
||||
<None Include="map.html"/>
|
||||
<None Include="atlas.html"/>
|
||||
<None Include="./public/*.scss"/>
|
||||
<None Include="./public\js\*.js"/>
|
||||
<None Include="./public\js\modules\*"/>
|
||||
<Compile Include="App.fs"/>
|
||||
<None Include="index.html" />
|
||||
<None Include="map.html" />
|
||||
<None Include="atlas.html" />
|
||||
<None Include="./public/*.scss" />
|
||||
<None Include="./public\js\*.js" />
|
||||
<None Include="./public\js\modules\*" />
|
||||
<Compile Include="App.fs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Update="FSharp.Core" Version="9.0.201"/>
|
||||
<PackageReference Include="FSharp.Core" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="Atlas\Atlas.fsproj"/>
|
||||
<ProjectReference Include="Mapster\Mapster.fsproj"/>
|
||||
<ProjectReference Include="Atlas\Atlas.fsproj" />
|
||||
<ProjectReference Include="Mapster\Mapster.fsproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -1,8 +1,10 @@
|
||||
module Auth
|
||||
|
||||
open System
|
||||
|
||||
open Browser
|
||||
open Thoth.Json
|
||||
|
||||
open Remoting
|
||||
|
||||
type private JwtToken = { exp: int }
|
||||
@@ -13,17 +15,26 @@ let private jwtDecoder =
|
||||
let establishAuthentication () =
|
||||
async {
|
||||
match! authApi.IsAuthenticated () with
|
||||
| Some _ ->
|
||||
console.debug $"user authenticated"
|
||||
| Some _ -> console.debug $"user authenticated"
|
||||
| None ->
|
||||
console.log "user not authenticated"
|
||||
console.error "User not authenticated"
|
||||
window.location.href <- "/signin"
|
||||
}
|
||||
|
||||
let setId () : Async<unit> =
|
||||
async {
|
||||
match! authApi.GetIdentity () with
|
||||
| Some id ->
|
||||
sessionStorage["id"] <- id.user
|
||||
| None ->
|
||||
console.error "[Auth] User not authenticated"
|
||||
window.location.href <- "/signin"
|
||||
}
|
||||
|
||||
let rec tokenRefreshLoop () =
|
||||
async {
|
||||
let decode (token: string) =
|
||||
localStorage[ token ].Split '.'
|
||||
localStorage[token].Split '.'
|
||||
|> fun x -> Utils.fromBase64String x[1]
|
||||
|> jwtDecoder
|
||||
|> function
|
||||
@@ -31,7 +42,7 @@ let rec tokenRefreshLoop () =
|
||||
| Error e ->
|
||||
console.log e
|
||||
0
|
||||
let t = DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()
|
||||
let t = DateTimeOffset(DateTime.Now).ToUnixTimeSeconds ()
|
||||
|
||||
do! Async.Sleep 1000
|
||||
let aExp = decode "access_token"
|
||||
@@ -39,29 +50,44 @@ let rec tokenRefreshLoop () =
|
||||
let dtA = int64 aExp - t
|
||||
let dtR = int64 rExp - t
|
||||
console.log $"{t} {dtA} {dtR}"
|
||||
if dtR < 0 then Dom.window.location.href <- "/signin"
|
||||
if dtR < 0 then
|
||||
window.location.href <- "/signin"
|
||||
if dtA < 30 then
|
||||
async {
|
||||
match! authApi.RefreshAccessToken localStorage["refresh_token"] with
|
||||
| Some (access, refresh) ->
|
||||
localStorage.setItem ("access_token", access)
|
||||
localStorage.setItem ("refresh_token", refresh)
|
||||
| None ->
|
||||
Dom.window.location.href <- "/signin"
|
||||
| None -> window.location.href <- "/signin"
|
||||
}
|
||||
|> Async.StartImmediate
|
||||
do! Async.Sleep((int dtA - 30) * 1000)
|
||||
do! Async.Sleep ((int dtA - 30) * 1000)
|
||||
tokenRefreshLoop ()
|
||||
}
|
||||
|> Async.StartImmediate
|
||||
|
||||
let startTokenRefreshLoopOrLogin () =
|
||||
async {
|
||||
match! authApi.IsAuthenticated() with
|
||||
match! authApi.IsAuthenticated () with
|
||||
| Some _ ->
|
||||
console.log "already authenticated"
|
||||
tokenRefreshLoop ()
|
||||
| None ->
|
||||
console.log "not already authenticated"
|
||||
Dom.window.location.href <- "/login"
|
||||
window.location.href <- "/login"
|
||||
}
|
||||
|
||||
let initSessionUrls () =
|
||||
async {
|
||||
try
|
||||
let! archiveUrl = servicesApi.GetArchiveService ()
|
||||
let! dataUrl = servicesApi.GetFileService ()
|
||||
|
||||
console.log $"Archive service: {archiveUrl}"
|
||||
sessionStorage["archmaester_url"] <- archiveUrl
|
||||
console.log $"Data service: {dataUrl}"
|
||||
sessionStorage["sorcerer_url"] <- dataUrl
|
||||
with e ->
|
||||
console.error("Failed fetching services. Redirecting to signin. %s", e.Message)
|
||||
window.location.href <- "/signin"
|
||||
}
|
||||
48
src/Atlantis/src/Client/Lib/Chaikin.fs
Normal file
48
src/Atlantis/src/Client/Lib/Chaikin.fs
Normal file
@@ -0,0 +1,48 @@
|
||||
module Chaikin
|
||||
|
||||
let private cut (start: float * float) (end': float * float) (ratio: float) =
|
||||
let startX, startY = start
|
||||
let endX, endY = end'
|
||||
|
||||
// Find point at a given ratio going from A to B
|
||||
let r1 =
|
||||
startX * (1.0 - ratio) + endX * ratio, startY * (1.0 - ratio) + endY * ratio
|
||||
|
||||
// Find point at a given ratio going from B to A
|
||||
let r2 =
|
||||
startX * ratio + endX * (1.0 - ratio), startY * ratio + endY * (1.0 - ratio)
|
||||
|
||||
r1, r2
|
||||
|
||||
let private chaikin (curve: (float * float) array) (iterations: int) (closed: bool) (ratio: float) =
|
||||
// If ratio is greater than 0.5 flip it so we avoid cutting across the midpoint of the line.
|
||||
let adjustedRatio = if ratio > 0.5 then 1.0 - ratio else ratio
|
||||
|
||||
let rec iterate (currentPoints: (float * float) array) remainingIterations =
|
||||
let len = currentPoints.Length
|
||||
if remainingIterations <= 0 || len = 0 then
|
||||
currentPoints
|
||||
else
|
||||
let refined = ResizeArray<float * float> ()
|
||||
|
||||
refined.Add (currentPoints[0])
|
||||
|
||||
for i in 0 .. len - 2 do
|
||||
let r1, r2 = cut currentPoints[i] currentPoints[i + 1] adjustedRatio
|
||||
refined.Add r1
|
||||
refined.Add r2
|
||||
|
||||
if closed then
|
||||
let r1, r2 = cut currentPoints[len - 1] currentPoints[0] adjustedRatio
|
||||
refined.Add r1
|
||||
refined.Add r2
|
||||
else
|
||||
refined.Add (currentPoints[len - 1])
|
||||
|
||||
iterate (refined.ToArray ()) (remainingIterations - 1)
|
||||
|
||||
iterate curve iterations
|
||||
|
||||
let chaikinDefault curve = chaikin curve 1 false 0.25
|
||||
let chaikinWithIterations iterations curve = chaikin curve iterations false 0.25
|
||||
let chaikinWithClosed closed curve = chaikin curve 1 closed 0.25
|
||||
20
src/Atlantis/src/Client/Lib/Colors.fs
Normal file
20
src/Atlantis/src/Client/Lib/Colors.fs
Normal file
@@ -0,0 +1,20 @@
|
||||
namespace Lib
|
||||
|
||||
module Colors =
|
||||
open Matplotlib.ColorMaps
|
||||
|
||||
open Atlantis.Types
|
||||
|
||||
let getColormap (colorMap: ColorMode * ColorMap) (lo, hi) =
|
||||
let mode, cmap = colorMap
|
||||
|
||||
let cm =
|
||||
match cmap with
|
||||
| ColorMap.Ocean name -> ColorMap<single>(name, lo, hi, 256, Ocean.colors)
|
||||
| ColorMap.Color16 name -> ColorMap<single>(name, lo, hi, 256, Color16.colors)
|
||||
| ColorMap.Custom _ -> failwith "not implemented"
|
||||
|
||||
match mode with
|
||||
| ColorMode.Normal -> cm
|
||||
| ColorMode.Mirror -> ColorMap<single>.mirrorPalette cm
|
||||
| ColorMode.Gray -> ColorMap<single>.toGrayscale cm
|
||||
@@ -43,9 +43,7 @@ module Types =
|
||||
let RGBAFormat: obj = jsNative
|
||||
|
||||
[<AllowNullLiteral>]
|
||||
type Matrix4 =
|
||||
interface
|
||||
end
|
||||
type Matrix4 = interface end
|
||||
|
||||
[<AllowNullLiteral>]
|
||||
type Euler =
|
||||
@@ -77,9 +75,7 @@ module Types =
|
||||
abstract Create: ?p1: obj * ?p2: obj * ?p3: obj * ?p4: obj -> Vector4
|
||||
|
||||
[<AllowNullLiteral>]
|
||||
type Float32BufferAttribute =
|
||||
interface
|
||||
end
|
||||
type Float32BufferAttribute = interface end
|
||||
and [<AllowNullLiteral>] Float32BufferAttributeType =
|
||||
[<Emit("new THREE.$0($1...)")>]
|
||||
abstract Create: p1: obj * p2: int -> Float32BufferAttribute
|
||||
@@ -221,9 +217,7 @@ module Types =
|
||||
abstract Create: unit -> DirectionalLight
|
||||
|
||||
[<AllowNullLiteral>]
|
||||
type EventDispatcher =
|
||||
interface
|
||||
end
|
||||
type EventDispatcher = interface end
|
||||
|
||||
// Type to resolve parameters for Geometries.
|
||||
[<AllowNullLiteral>]
|
||||
|
||||
@@ -91,7 +91,7 @@ module rec Timeline =
|
||||
abstract ``end``: DateTime option with set, get
|
||||
abstract start: DateTime with get, set
|
||||
abstract object: obj
|
||||
abstract type' : ItemType
|
||||
abstract type': ItemType
|
||||
|
||||
[<StringEnum>]
|
||||
[<RequireQualifiedAccess>]
|
||||
@@ -116,11 +116,14 @@ module rec Timeline =
|
||||
let inline mkTooltip (key: string) (value: obj) : TimelineTooltipOption = unbox (key, value)
|
||||
type tooltip' =
|
||||
static member inline template(value: string) : TimelineTooltipOption = mkTooltip "template" value
|
||||
static member inline template(value: (TimelineItem) -> string) : TimelineTooltipOption = mkTooltip "template" value
|
||||
static member inline template(value: (TimelineItem * TimelineItem) -> string) : TimelineTooltipOption = mkTooltip "template" value
|
||||
static member inline followMouse(value: bool): TimelineTooltipOption = mkTooltip "followMouse" value
|
||||
static member inline overflowMethod(value: TimelineTooltipOptionOverflowMethod): TimelineTooltipOption = mkTooltip "overflowMethod" value
|
||||
static member inline delay(value: int): TimelineTooltipOption = mkTooltip "delay" value
|
||||
static member inline template(value: (TimelineItem) -> string) : TimelineTooltipOption =
|
||||
mkTooltip "template" value
|
||||
static member inline template(value: (TimelineItem * TimelineItem) -> string) : TimelineTooltipOption =
|
||||
mkTooltip "template" value
|
||||
static member inline followMouse(value: bool) : TimelineTooltipOption = mkTooltip "followMouse" value
|
||||
static member inline overflowMethod(value: TimelineTooltipOptionOverflowMethod) : TimelineTooltipOption =
|
||||
mkTooltip "overflowMethod" value
|
||||
static member inline delay(value: int) : TimelineTooltipOption = mkTooltip "delay" value
|
||||
|
||||
|
||||
let private createTimelineItem options : TimelineItem = unbox options
|
||||
@@ -174,7 +177,8 @@ module rec Timeline =
|
||||
static member inline maxHeight(value: string) : TimelineOptions = mkTimelineOption "maxHeight" value
|
||||
/// This option allows you to scroll horizontally to move backwards and forwards in the time range.
|
||||
/// Only applicable when option zoomKey is defined or zoomable is false.
|
||||
static member inline horizontalScroll(value: bool) : TimelineOptions = mkTimelineOption "horizontalScroll" value
|
||||
static member inline horizontalScroll(value: bool) : TimelineOptions =
|
||||
mkTimelineOption "horizontalScroll" value
|
||||
/// NOTE: This probably does not work. Only functioning workaround we have found for nb locales is:
|
||||
///
|
||||
/// o?moment <- fun x ->
|
||||
@@ -202,18 +206,19 @@ module rec Timeline =
|
||||
static member inline groupOrder(value: string) : TimelineOptions = mkTimelineOption "groupOrder" value
|
||||
/// Use a function to render groups as react elements.
|
||||
/// Uses React.render in the bindings to apply the given function to all groups.
|
||||
static member inline groupTemplate(renderFunc: obj -> Feliz.ReactElement): TimelineOptions =
|
||||
static member inline groupTemplate(renderFunc: obj -> Feliz.ReactElement) : TimelineOptions =
|
||||
let value (item, elem, _data) =
|
||||
let root = Feliz.ReactDOM.createRoot elem
|
||||
root.render(renderFunc item)
|
||||
root.render (renderFunc item)
|
||||
mkTimelineOption "groupTemplate" value
|
||||
static member inline selectable(value: bool) : TimelineOptions = mkTimelineOption "selectable" value
|
||||
static member inline showWeekScale(value: bool) : TimelineOptions = mkTimelineOption "showWeekScale" value
|
||||
/// Reduces down to timeline.template, renamed to itemTemplate to match groupTemplate.
|
||||
/// Use a function to render items as react elements.
|
||||
/// Uses React.render in the bindings to apply the given function to all items.
|
||||
static member inline itemTemplate(renderFunc: obj -> Feliz.ReactElement): TimelineOptions =
|
||||
mkTimelineOption "template"
|
||||
static member inline itemTemplate(renderFunc: obj -> Feliz.ReactElement) : TimelineOptions =
|
||||
mkTimelineOption
|
||||
"template"
|
||||
(fun (item, element, data) ->
|
||||
Browser.Dom.console.log item
|
||||
Browser.Dom.console.log element
|
||||
@@ -223,7 +228,7 @@ module rec Timeline =
|
||||
()
|
||||
else
|
||||
let root = Feliz.ReactDOM.createRoot element
|
||||
root.render(renderFunc item)
|
||||
root.render (renderFunc item)
|
||||
)
|
||||
static member inline timeAxis(value: timeAxis) : TimelineOptions = mkTimelineOption "timeAxis" value
|
||||
static member inline tooltip(value: TimelineTooltipOption) : TimelineOptions = mkTimelineOption "tooltip" value
|
||||
@@ -231,7 +236,7 @@ module rec Timeline =
|
||||
/// Specifies whether the Timeline can be zoomed by pinching or scrolling in the window. Only applicable when option moveable is set true.
|
||||
static member inline zoomable(value: bool) : TimelineOptions = mkTimelineOption "zoomable" value
|
||||
/// Specifies how strong the zooming is for each scroll tick. Higher zooming friction will slow zooming speed.
|
||||
static member inline zoomFriction(value: float): TimelineOptions = mkTimelineOption "zoomFriction" value
|
||||
static member inline zoomFriction(value: float) : TimelineOptions = mkTimelineOption "zoomFriction" value
|
||||
/// Specifies whether the Timeline is only zoomed when an additional key is down.
|
||||
/// Available values are '' (does not apply), 'altKey', 'ctrlKey', 'shiftKey' or 'metaKey'.
|
||||
/// Only applicable when option moveable is set true.
|
||||
@@ -243,17 +248,10 @@ module rec Timeline =
|
||||
/// <example>36_000_000. ms is a minimum zoom of 1 hour in ms</example>
|
||||
static member inline zoomMin(value: float) : TimelineOptions = mkTimelineOption "zoomMin" value
|
||||
static member inline xssWhitelist(value: obj) : TimelineOptions =
|
||||
let xss = {|
|
||||
disabled = false
|
||||
filterOptions = {|
|
||||
whiteList = value
|
||||
|}
|
||||
|}
|
||||
let xss = {| disabled = false; filterOptions = {| whiteList = value |} |}
|
||||
mkTimelineOption "xss" xss
|
||||
|
||||
type timeAxis =
|
||||
interface
|
||||
end
|
||||
type timeAxis = interface end
|
||||
|
||||
[<StringEnum(CaseRules.LowerFirst)>]
|
||||
[<RequireQualifiedAccess>]
|
||||
@@ -274,9 +272,7 @@ module rec Timeline =
|
||||
static member inline showStipes(value: bool) = mkTimelineOption "showStipes" value
|
||||
|
||||
// Timeline Options
|
||||
type EditableOption =
|
||||
interface
|
||||
end
|
||||
type EditableOption = interface end
|
||||
|
||||
let inline mkEditableOption (key: string) (value: obj) : EditableOption = unbox (key, value)
|
||||
|
||||
@@ -318,9 +314,9 @@ type IDataSet =
|
||||
[<Import("DataSet", "vis-timeline/standalone")>]
|
||||
type DataSet(data: U2<TimelineItem array, TimelineGroup array>, ?options: obj) =
|
||||
|
||||
new(data: TimelineItem array) = DataSet(U2.Case1 data)
|
||||
new(data: TimelineItem array) = DataSet (U2.Case1 data)
|
||||
|
||||
new(data: TimelineGroup array) = DataSet(U2.Case2 data)
|
||||
new(data: TimelineGroup array) = DataSet (U2.Case2 data)
|
||||
|
||||
/// <summary>
|
||||
/// Add one or multiple items to the DataSet. data can be a single item or an array with items. Adding an item will fail when there already is an item with the same id. The function returns an array with the ids of the added items. See section Data Manipulation.
|
||||
@@ -450,38 +446,34 @@ type DataSet(data: U2<TimelineItem array, TimelineGroup array>, ?options: obj) =
|
||||
type AnimationOptions =
|
||||
| Animation of AnimationOption
|
||||
| Bool of bool
|
||||
and AnimationOption = {
|
||||
duration: float
|
||||
easingFunction: EasingFunction
|
||||
}
|
||||
and
|
||||
[<StringEnum(CaseRules.LowerFirst)>]
|
||||
EasingFunction =
|
||||
| Linear
|
||||
| EaseInQuad
|
||||
| EaseOutQuad
|
||||
| EaseInOutQuad
|
||||
| EaseInCubic
|
||||
| EaseOutCubic
|
||||
| EaseInOutCubic
|
||||
| EaseInQuart
|
||||
| EaseOutQuart
|
||||
| EaseInOutQuart
|
||||
| EaseInQuint
|
||||
| EaseOutQuint
|
||||
| EaseInOutQuint
|
||||
and AnimationOption = { duration: float; easingFunction: EasingFunction }
|
||||
and [<StringEnum(CaseRules.LowerFirst)>] EasingFunction =
|
||||
| Linear
|
||||
| EaseInQuad
|
||||
| EaseOutQuad
|
||||
| EaseInOutQuad
|
||||
| EaseInCubic
|
||||
| EaseOutCubic
|
||||
| EaseInOutCubic
|
||||
| EaseInQuart
|
||||
| EaseOutQuart
|
||||
| EaseInOutQuart
|
||||
| EaseInQuint
|
||||
| EaseOutQuint
|
||||
| EaseInOutQuint
|
||||
|
||||
[<AllowNullLiteral>]
|
||||
[<Import("Timeline", "vis-timeline/standalone")>]
|
||||
type Timeline(container: HTMLElement, items: U2<TimelineItem seq, DataSet>, ?groups: U2<TimelineGroup seq, DataSet>, ?options: TimelineOptions) =
|
||||
type Timeline
|
||||
(
|
||||
container: HTMLElement,
|
||||
items: U2<TimelineItem seq, DataSet>,
|
||||
?groups: U2<TimelineGroup seq, DataSet>,
|
||||
?options: TimelineOptions
|
||||
) =
|
||||
|
||||
new(container, items, groups, options) =
|
||||
Timeline(
|
||||
container = container,
|
||||
items = U2.Case2 items,
|
||||
groups = U2.Case2 groups,
|
||||
options = options
|
||||
)
|
||||
Timeline (container = container, items = U2.Case2 items, groups = U2.Case2 groups, options = options)
|
||||
|
||||
/// <summary>
|
||||
/// Add new vertical bar representing a custom time that can be dragged by the user. Parameter time can be a Date,
|
||||
@@ -559,8 +551,8 @@ type Timeline(container: HTMLElement, items: U2<TimelineItem seq, DataSet>, ?gro
|
||||
member _.getCustomTime() : DateTime = jsNative
|
||||
member _.getCustomTime(ids: Id array) : DateTime = jsNative
|
||||
|
||||
member _.itemsData : IDataSet = jsNative
|
||||
member _.groupsData : IDataSet = jsNative
|
||||
member _.itemsData: IDataSet = jsNative
|
||||
member _.groupsData: IDataSet = jsNative
|
||||
member _.moveTo(time: DateTime, ?options, ?callback) : unit = jsNative
|
||||
|
||||
member _.on(_: string, _: 'a -> unit) : unit = jsNative
|
||||
@@ -601,7 +593,7 @@ type Timeline(container: HTMLElement, items: U2<TimelineItem seq, DataSet>, ?gro
|
||||
member _.setGroups(_: DataSet) : unit = jsNative
|
||||
|
||||
member _.setOptions(_: obj) : unit = jsNative
|
||||
member _.setSelection(_: string []) : unit = jsNative
|
||||
member _.setSelection(_: string[]) : unit = jsNative
|
||||
member _.setWindow(start: DateTime, end': DateTime, ?options: obj, ?callback: obj -> unit) : unit = jsNative
|
||||
member _.zoomIn(_: float) : unit = jsNative
|
||||
|
||||
@@ -630,10 +622,11 @@ type Timeline(container: HTMLElement, items: U2<TimelineItem seq, DataSet>, ?gro
|
||||
///
|
||||
/// A callback function can be passed as an optional parameter. This function will be called at the end of zoomOut function.
|
||||
/// </summary>
|
||||
member _.zoomOut(percentage: float, options: {| animation: AnimationOption |}, ?callback: obj -> unit) : unit = jsNative
|
||||
member _.zoomOut(percentage: float, options: {| animation: AnimationOption |}, ?callback: obj -> unit) : unit =
|
||||
jsNative
|
||||
member _.zoomOut(percentage: float, options: {| animation: bool |}, ?callback: obj -> unit) : unit = jsNative
|
||||
member _.zoomOut(percentage: float) : unit = jsNative
|
||||
|
||||
[<ImportDefault("moment")>]
|
||||
type Moment(timestamp: int) =
|
||||
member _.locale(_:string): Moment = jsNative
|
||||
member _.locale(_: string) : Moment = jsNative
|
||||
@@ -13,14 +13,14 @@ let floatingBox () =
|
||||
let this, props =
|
||||
LitElement.init (fun cfg ->
|
||||
cfg.useShadowDom <- true
|
||||
cfg.props <-
|
||||
{|
|
||||
title = Prop.Of ""
|
||||
xPos = Prop.Of (Dom.window.document.documentElement.clientWidth - 250.0)
|
||||
yPos = Prop.Of 50.0
|
||||
|}
|
||||
cfg.props <- {|
|
||||
title = Prop.Of ""
|
||||
xPos = Prop.Of (Dom.window.document.documentElement.clientWidth - 250.0)
|
||||
yPos = Prop.Of 50.0
|
||||
|}
|
||||
cfg.styles <- [
|
||||
css $"""
|
||||
css
|
||||
$"""
|
||||
#floating-box {{
|
||||
position: fixed;
|
||||
padding: 3px;
|
||||
@@ -38,8 +38,8 @@ let floatingBox () =
|
||||
font-family: Georgia;
|
||||
}}
|
||||
"""
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
let xPos = props.xPos.Value
|
||||
let yPos = props.yPos.Value
|
||||
@@ -47,35 +47,41 @@ let floatingBox () =
|
||||
if this.shadowRoot |> isNull |> not then
|
||||
Hook.useEffectOnce (fun () ->
|
||||
let document = Dom.document
|
||||
let floatingBox = getShadowElementById this "floating-box" :?> Browser.Types.HTMLDivElement
|
||||
let floatingBox =
|
||||
getShadowElementById this "floating-box" :?> Browser.Types.HTMLDivElement
|
||||
let mutable x, y = xPos, yPos
|
||||
let mutable x', y' = xPos, yPos
|
||||
floatingBox.onmousedown <- fun e ->
|
||||
this.dispatchCustomEvent("dragStart")
|
||||
// e.preventDefault ()
|
||||
// NOTE(SimenLK): Hacky attempt to prevent moving the floating box when pressing items within it
|
||||
x' <- e.clientX
|
||||
y' <- e.clientY
|
||||
floatingBox.onmousedown <-
|
||||
fun e ->
|
||||
this.dispatchCustomEvent ("dragStart")
|
||||
// e.preventDefault ()
|
||||
// NOTE(SimenLK): Hacky attempt to prevent moving the floating box when pressing items within it
|
||||
x' <- e.clientX
|
||||
y' <- e.clientY
|
||||
|
||||
floatingBox?style?cursor <- "grabbing"
|
||||
document.onmouseup <- fun _ ->
|
||||
this.dispatchCustomEvent("dragStop")
|
||||
floatingBox?style?cursor <- ""
|
||||
document.onmouseup <- fun _ -> ()
|
||||
document.onmousemove <- fun _ -> ()
|
||||
document.onmousemove <- fun e' ->
|
||||
this.dispatchCustomEvent("dragging")
|
||||
e.preventDefault ()
|
||||
x <- x' - e'.clientX
|
||||
y <- y' - e'.clientY
|
||||
x' <- e'.clientX
|
||||
y' <- e'.clientY
|
||||
floatingBox?style?left <- $"{(floatingBox.offsetLeft - x)}px" // $"{e'.clientX}px"
|
||||
floatingBox?style?top <- $"{(floatingBox.offsetTop - y)}px" // $"{e'.clientY}px"
|
||||
()
|
||||
())
|
||||
floatingBox?style?cursor <- "grabbing"
|
||||
document.onmouseup <-
|
||||
fun _ ->
|
||||
this.dispatchCustomEvent ("dragStop")
|
||||
floatingBox?style?cursor <- ""
|
||||
document.onmouseup <- fun _ -> ()
|
||||
document.onmousemove <- fun _ -> ()
|
||||
document.onmousemove <-
|
||||
fun e' ->
|
||||
this.dispatchCustomEvent ("dragging")
|
||||
e.preventDefault ()
|
||||
x <- x' - e'.clientX
|
||||
y <- y' - e'.clientY
|
||||
x' <- e'.clientX
|
||||
y' <- e'.clientY
|
||||
floatingBox?style?left <- $"{(floatingBox.offsetLeft - x)}px" // $"{e'.clientX}px"
|
||||
floatingBox?style?top <- $"{(floatingBox.offsetTop - y)}px" // $"{e'.clientY}px"
|
||||
()
|
||||
()
|
||||
)
|
||||
|
||||
html $"""
|
||||
html
|
||||
$"""
|
||||
<div
|
||||
id="floating-box" resize="both"
|
||||
style="top: {yPos}px; left: {xPos}px;"
|
||||
|
||||
@@ -11,74 +11,85 @@ let openDB () : IDBDatabase JS.Promise =
|
||||
Promise.create (fun resolve reject ->
|
||||
let openRequest = indexedDB.``open`` ("oceanbox", dbVersion)
|
||||
|
||||
openRequest.onerror <- (fun _ ->
|
||||
console.error "Failed opening oceanbox database"
|
||||
reject (unbox "Fail"))
|
||||
openRequest.onerror <-
|
||||
fun _ ->
|
||||
console.error "Failed opening oceanbox database"
|
||||
reject (unbox "Fail")
|
||||
|
||||
openRequest.onsuccess <-
|
||||
fun _ ->
|
||||
// console.log "oceanbox database opened"
|
||||
let db: IDBDatabase = unbox openRequest.result
|
||||
resolve db
|
||||
|
||||
openRequest.onupgradeneeded <-
|
||||
fun ev ->
|
||||
// console.log $"Upgrading oceanbox database"
|
||||
let db: IDBDatabase = ev.target?result
|
||||
db.onerror <- (fun ev -> console.error $"Could not upgrade database: {ev.target}")
|
||||
let archives =
|
||||
db.createObjectStore ("PlainGrids", !!{| keyPath = "GridSha"; autoIncrement = true |})
|
||||
archives.createIndex ("Vertices", "Vertices") |> ignore
|
||||
archives.createIndex ("Indices", "Indices") |> ignore
|
||||
|
||||
openRequest.onsuccess <- (fun _ ->
|
||||
// console.log "oceanbox database opened"
|
||||
let db: IDBDatabase = unbox openRequest.result
|
||||
resolve db
|
||||
)
|
||||
openRequest.onupgradeneeded <- (fun ev ->
|
||||
// console.log $"Upgrading oceanbox database"
|
||||
let db: IDBDatabase = ev.target?result
|
||||
db.onerror <- (fun ev -> console.error $"Could not upgrade database: {ev.target}")
|
||||
let archives = db.createObjectStore("PlainGrids", !!{| keyPath = "GridSha"; autoIncrement = true |})
|
||||
archives.createIndex("Vertices", "Vertices") |> ignore
|
||||
archives.createIndex("Indices", "Indices") |> ignore
|
||||
)
|
||||
)
|
||||
|
||||
let getFromIDB<'T> (db: IDBDatabase) (store: string) (sha: string): 'T option JS.Promise =
|
||||
let getFromIDB<'T> (db: IDBDatabase) (store: string) (sha: string) : 'T option JS.Promise =
|
||||
Promise.create (fun resolve reject ->
|
||||
let t = db.transaction(store, IDBTransactionMode.Readonly)
|
||||
let t = db.transaction (store, IDBTransactionMode.Readonly)
|
||||
let index = t.objectStore store
|
||||
let request = index.get sha
|
||||
t.commit ()
|
||||
|
||||
request.onerror <- (fun _ ->
|
||||
console.error $"Failed retrieving {store}: {sha}"
|
||||
reject (unbox false))
|
||||
request.onerror <-
|
||||
fun _ ->
|
||||
console.error $"Failed retrieving {store}: {sha}"
|
||||
reject (unbox false)
|
||||
|
||||
request.onsuccess <- (fun _ ->
|
||||
// console.log $"checking {store} {sha}"
|
||||
// NOTE(SimenLK): when getting on aid, if it is not present, the result will be undefined, otherwise, unbox
|
||||
// to get the DB archive grid
|
||||
request.result
|
||||
|> Option.map unbox<'T>
|
||||
|> resolve)
|
||||
request.onsuccess <-
|
||||
fun _ ->
|
||||
// console.log $"checking {store} {sha}"
|
||||
// NOTE(SimenLK): when getting on aid, if it is not present, the result will be undefined, otherwise, unbox
|
||||
// to get the DB archive grid
|
||||
request.result |> Option.map unbox<'T> |> resolve
|
||||
)
|
||||
|
||||
let saveToIDB (db: IDBDatabase) (store: string) item =
|
||||
Promise.create (fun resolve reject ->
|
||||
let t = db.transaction(store, IDBTransactionMode.Readwrite)
|
||||
let archives = t.objectStore(store)
|
||||
let t = db.transaction (store, IDBTransactionMode.Readwrite)
|
||||
let archives = t.objectStore (store)
|
||||
|
||||
let req = archives.add item
|
||||
req.onerror <- (fun ev ->
|
||||
let error = ev.target :?> IDBRequest
|
||||
console.error $"saveToIDB error: {error.error}"
|
||||
reject (error.error :?> exn))
|
||||
req.onsuccess <- (fun _ ->
|
||||
console.debug $"Successfully added {store} to indexedDB"
|
||||
resolve ())
|
||||
)
|
||||
req.onerror <-
|
||||
fun ev ->
|
||||
let error = ev.target :?> IDBRequest
|
||||
console.error $"saveToIDB error: {error.error}"
|
||||
reject (error.error :?> exn)
|
||||
|
||||
req.onsuccess <-
|
||||
fun _ ->
|
||||
console.debug $"Successfully added {store} to indexedDB"
|
||||
resolve ()
|
||||
)
|
||||
|
||||
let tryResetOutdatedIDB () =
|
||||
Promise.create (fun resolve reject ->
|
||||
openDB () |> Promise.iter (fun db ->
|
||||
openDB ()
|
||||
|> Promise.iter (fun db ->
|
||||
if db.objectStoreNames.contains "WireframeGrids" then
|
||||
db.close ()
|
||||
let req = indexedDB.deleteDatabase "oceanbox"
|
||||
req.onerror <- (fun ev ->
|
||||
let error = ev.target :?> IDBRequest
|
||||
console.error $"Reset indexDB error: {error.error}"
|
||||
reject (error.error :?> exn))
|
||||
req.onsuccess <- (fun _ ->
|
||||
console.debug $"Successfully reset indexedDB"
|
||||
resolve ())
|
||||
req.onerror <-
|
||||
fun ev ->
|
||||
let error = ev.target :?> IDBRequest
|
||||
console.error $"Reset indexDB error: {error.error}"
|
||||
reject (error.error :?> exn)
|
||||
|
||||
req.onsuccess <-
|
||||
fun _ ->
|
||||
console.debug $"Successfully reset indexedDB"
|
||||
resolve ()
|
||||
else
|
||||
resolve ()
|
||||
resolve ()
|
||||
)
|
||||
)
|
||||
@@ -5,11 +5,18 @@ open Fable.Core.JsInterop
|
||||
let register () = ()
|
||||
|
||||
importAll "../public/style.scss"
|
||||
|
||||
importSideEffects "@spectrum-web-components/theme/sp-theme.js"
|
||||
importSideEffects "@spectrum-web-components/theme/spectrum-two/scale-medium.js"
|
||||
importSideEffects "@spectrum-web-components/theme/spectrum-two/scale-large.js"
|
||||
importSideEffects "@spectrum-web-components/theme/spectrum-two/theme-light.js"
|
||||
importSideEffects "@spectrum-web-components/theme/spectrum-two/theme-dark.js"
|
||||
importSideEffects "@spectrum-web-components/accordion/sp-accordion.js"
|
||||
importSideEffects "@spectrum-web-components/accordion/sp-accordion-item.js"
|
||||
importSideEffects "@spectrum-web-components/action-button/sp-action-button.js"
|
||||
importSideEffects "@spectrum-web-components/action-group/sp-action-group.js"
|
||||
importSideEffects "@spectrum-web-components/action-menu/sp-action-menu.js"
|
||||
importSideEffects "@spectrum-web-components/action-menu/sync/sp-action-menu.js"
|
||||
importSideEffects "@spectrum-web-components/alert-banner/sp-alert-banner.js"
|
||||
importSideEffects "@spectrum-web-components/button/sp-button.js"
|
||||
importSideEffects "@spectrum-web-components/card/sp-card.js"
|
||||
importSideEffects "@spectrum-web-components/checkbox/sp-checkbox.js"
|
||||
@@ -24,13 +31,12 @@ importSideEffects "@spectrum-web-components/menu/sp-menu-group.js"
|
||||
importSideEffects "@spectrum-web-components/menu/sp-menu-item.js"
|
||||
importSideEffects "@spectrum-web-components/menu/sp-menu-divider.js"
|
||||
importSideEffects "@spectrum-web-components/number-field/sp-number-field.js"
|
||||
importSideEffects "@spectrum-web-components/picker/sp-picker.js"
|
||||
importSideEffects "@spectrum-web-components/popover/sp-popover.js"
|
||||
importSideEffects "@spectrum-web-components/progress-bar/sp-progress-bar.js"
|
||||
importSideEffects "@spectrum-web-components/progress-circle/sp-progress-circle.js"
|
||||
importSideEffects "@spectrum-web-components/radio/sp-radio.js"
|
||||
importSideEffects "@spectrum-web-components/radio/sp-radio-group.js"
|
||||
importSideEffects "@spectrum-web-components/slider/sp-slider.js"
|
||||
importSideEffects "@spectrum-web-components/slider/sync/sp-slider.js"
|
||||
importSideEffects "@spectrum-web-components/slider/sp-slider-handle.js"
|
||||
importSideEffects "@spectrum-web-components/split-view/sp-split-view.js"
|
||||
importSideEffects "@spectrum-web-components/switch/sp-switch.js"
|
||||
@@ -44,28 +50,31 @@ importSideEffects "@spectrum-web-components/table/sp-table-head-cell.js"
|
||||
importSideEffects "@spectrum-web-components/table/sp-table-row.js"
|
||||
importSideEffects "@spectrum-web-components/tabs/sp-tabs.js"
|
||||
importSideEffects "@spectrum-web-components/tabs/sp-tab.js"
|
||||
importSideEffects "@spectrum-web-components/tabs/sp-tab-panel.js"
|
||||
importSideEffects "@spectrum-web-components/textfield/sp-textfield.js"
|
||||
importSideEffects "@spectrum-web-components/theme/sp-theme.js"
|
||||
importSideEffects "@spectrum-web-components/theme/spectrum-two/scale-medium.js"
|
||||
importSideEffects "@spectrum-web-components/theme/spectrum-two/scale-large.js"
|
||||
importSideEffects "@spectrum-web-components/theme/spectrum-two/theme-light.js"
|
||||
importSideEffects "@spectrum-web-components/theme/spectrum-two/theme-dark.js"
|
||||
importSideEffects "@spectrum-web-components/toast/sp-toast.js"
|
||||
importSideEffects "@spectrum-web-components/top-nav/sp-top-nav.js"
|
||||
importSideEffects "@spectrum-web-components/top-nav/sp-top-nav-item.js"
|
||||
importSideEffects "@spectrum-web-components/underlay/sp-underlay.js"
|
||||
importSideEffects "@spectrum-web-components/overlay/overlay-trigger.js"
|
||||
importSideEffects "@spectrum-web-components/overlay/sync/overlay-trigger.js"
|
||||
importSideEffects "@spectrum-web-components/overlay/sp-overlay.js"
|
||||
importSideEffects "@spectrum-web-components/tooltip/sp-tooltip.js"
|
||||
importSideEffects "@spectrum-web-components/dialog/sp-dialog.js"
|
||||
importSideEffects "@spectrum-web-components/dialog/sp-dialog-base.js"
|
||||
importSideEffects "@spectrum-web-components/dialog/sp-dialog-wrapper.js"
|
||||
importSideEffects "@spectrum-web-components/infield-button/sp-infield-button.js"
|
||||
importSideEffects "@spectrum-web-components/picker/sync/sp-picker.js"
|
||||
importSideEffects "@spectrum-web-components/contextual-help/sp-contextual-help.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-add.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-add-circle.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-alert.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-prototyping.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-close.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-copy.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-crosshairs.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-target.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-delete.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-color-harmony.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-deselect.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-erase.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-reorder.js"
|
||||
@@ -83,11 +92,17 @@ importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-asteris
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-bug.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-sampler.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-measure.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-ruler.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-circle.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-image-map-rectangle.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-histogram.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-chart-bar-vert.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-chart-trend.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-location.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-crop.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-download.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-edit.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-cancel.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-browse.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-filter.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-filter-remove.js"
|
||||
@@ -106,4 +121,4 @@ importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-checkma
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-rotate-cc-w.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-align-bottom.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-transform-perspective.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-search.js"
|
||||
importSideEffects "@spectrum-web-components/icons-workflow/icons/sp-icon-search.js"
|
||||
41
src/Atlantis/src/Client/Lib/Intl.fs
Normal file
41
src/Atlantis/src/Client/Lib/Intl.fs
Normal file
@@ -0,0 +1,41 @@
|
||||
module Intl
|
||||
|
||||
open Browser
|
||||
open Fable.Core
|
||||
open Fable.Core.JsInterop
|
||||
|
||||
|
||||
[<Emit("new Intl.DateTimeFormat($0, $1)")>]
|
||||
let private dateTimeFormat (lang: string) (opt: obj) = jsNative
|
||||
|
||||
// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat
|
||||
let private uk : obj =
|
||||
let opts = {|
|
||||
dateStyle = "full"
|
||||
timeStyle = "short"
|
||||
|}
|
||||
|
||||
dateTimeFormat "en-GB" opts
|
||||
|
||||
// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat
|
||||
let private ukShort : obj =
|
||||
let opts = {|
|
||||
dateStyle = "short"
|
||||
|}
|
||||
|
||||
dateTimeFormat "en-GB" opts
|
||||
|
||||
// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat
|
||||
let private ukDateTimeShort : obj =
|
||||
let opts = {|
|
||||
dateStyle = "short"
|
||||
timeStyle = "short"
|
||||
|}
|
||||
|
||||
dateTimeFormat "en-GB" opts
|
||||
|
||||
/// Returns date string formatted as e.g.: "Wednesday 11 June 2025 at 06:00"
|
||||
let format (date: System.DateTime) : string = uk?format date
|
||||
|
||||
let shortDate (date: System.DateTime) : string = ukShort?format date
|
||||
let shortDateTime (date: System.DateTime) : string = ukDateTimeShort?format date
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<DefineConstants>FABLE_COMPILER</DefineConstants>
|
||||
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
||||
<Version>2.87.0</Version>
|
||||
@@ -9,42 +9,49 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="../../Shared/Atlantis.Shared.fs" />
|
||||
<Compile Include="Sentry.fs"/>
|
||||
<Compile Include="Fable.VisJS.fs" />
|
||||
<Compile Include="Types.fs" />
|
||||
<Compile Include="Utils.fs" />
|
||||
<Compile Include="React.fs" />
|
||||
<Compile Include="Sentry.fs" />
|
||||
<Compile Include="Remoting.fs" />
|
||||
<Compile Include="Auth.fs" />
|
||||
<Compile Include="Search.fs" />
|
||||
<Compile Include="Imports.fs" />
|
||||
<Compile Include="Fable.VisJS.fs" />
|
||||
<Compile Include="IDB.fs" />
|
||||
<Compile Include="FloatingBox.fs" />
|
||||
<Compile Include="Turf.fs" />
|
||||
<Compile Include="Types.fs" />
|
||||
<Compile Include="Remoting.fs" />
|
||||
<Compile Include="Utils.fs" />
|
||||
<Compile Include="Auth.fs" />
|
||||
<Compile Include="Chaikin.fs" />
|
||||
<Compile Include="Umami.fs" />
|
||||
<Compile Include="StreamLayer.fs" />
|
||||
<Compile Include="WebGLLayer.fs" />
|
||||
<Compile Include="Intl.fs" />
|
||||
<Compile Include="Colors.fs" />
|
||||
<Compile Include="Maps.fs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Fable.Browser.IndexedDB" Version="2.2.0" />
|
||||
<PackageReference Include="Fable.Browser.WebGL" Version="1.3.0" />
|
||||
<PackageReference Include="Fable.Core" Version="4.4.0" />
|
||||
<PackageReference Include="Fable.Elmish" Version="4.2.0" />
|
||||
<PackageReference Include="Fable.Fetch" Version="2.7.0" />
|
||||
<PackageReference Include="Fable.Lit" Version="1.6.2-oceanbox" />
|
||||
<PackageReference Include="Fable.Lit.React" Version="1.6.2-oceanbox" />
|
||||
<PackageReference Include="Fable.Lit.Elmish" Version="1.6.2-oceanbox" />
|
||||
<PackageReference Include="Fable.Promise" Version="3.2.0" />
|
||||
<PackageReference Include="Fable.React" Version="9.4.0" />
|
||||
<PackageReference Include="Fable.Remoting.Client" Version="7.32.0" />
|
||||
<PackageReference Include="Fable.Remoting.MsgPack" Version="1.24.0" />
|
||||
<PackageReference Include="Fable.OpenLayers" Version="2.18.0" />
|
||||
<PackageReference Include="Fable.SignalR.Elmish" Version="2.1.0" />
|
||||
<PackageReference Include="Fable.SimpleHttp" Version="3.6.0" />
|
||||
<PackageReference Include="Feliz" Version="2.9.0" />
|
||||
<PackageReference Include="Feliz.CompilerPlugins" Version="2.2.0" />
|
||||
<PackageReference Include="Thoth.Fetch" Version="3.0.1" />
|
||||
<PackageReference Include="Thoth.Json" Version="10.4.1" />
|
||||
<PackageReference Update="FSharp.Core" Version="9.0.201" />
|
||||
<PackageReference Include="Matplotlib.ColorMaps" Version="3.0.1" />
|
||||
<PackageReference Include="Fable.Browser.IndexedDB" />
|
||||
<PackageReference Include="Fable.Browser.WebGL" />
|
||||
<PackageReference Include="Fable.Core" />
|
||||
<PackageReference Include="Fable.Elmish" />
|
||||
<PackageReference Include="Fable.Fetch" />
|
||||
<PackageReference Include="Fable.Lit" />
|
||||
<PackageReference Include="Fable.Lit.React" />
|
||||
<PackageReference Include="Fable.Lit.Elmish" />
|
||||
<PackageReference Include="Fable.Promise" />
|
||||
<PackageReference Include="Fable.React" />
|
||||
<PackageReference Include="Fable.Remoting.Client" />
|
||||
<PackageReference Include="Fable.Remoting.MsgPack" />
|
||||
<PackageReference Include="Fable.OpenLayers" />
|
||||
<PackageReference Include="Fable.SignalR.Elmish" />
|
||||
<PackageReference Include="Fable.SimpleHttp" />
|
||||
<PackageReference Include="Feliz" />
|
||||
<PackageReference Include="Feliz.CompilerPlugins" />
|
||||
<PackageReference Include="FsToolkit.ErrorHandling" />
|
||||
<PackageReference Include="Thoth.Fetch" />
|
||||
<PackageReference Include="Thoth.Json" />
|
||||
<PackageReference Include="Matplotlib.ColorMaps" />
|
||||
<PackageReference Include="FSharp.Core" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\Interfaces\Atlantis\Atlantis.Api.fsproj" />
|
||||
@@ -53,4 +60,4 @@
|
||||
<ProjectReference Include="..\..\..\..\Interfaces\Archmaester\Archmaester.Api.fsproj" />
|
||||
<ProjectReference Include="..\..\..\..\Interfaces\Sorcerer\Sorcerer.Api.fsproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -1,6 +1,5 @@
|
||||
module Maps
|
||||
|
||||
open System.Text.RegularExpressions
|
||||
open Browser
|
||||
open Fable.Core
|
||||
open Fable.Core.JsInterop
|
||||
@@ -18,7 +17,7 @@ open Atlantis.Types
|
||||
|
||||
let theCenter = [| 14.39; 65.2 |]
|
||||
|
||||
let flyTo (map: OlMap) (zoom: float) (c: float []) =
|
||||
let flyTo (map: OlMap) (zoom: float) (c: float[]) =
|
||||
let v = map.getView ()
|
||||
|
||||
Animation.animationOptions [
|
||||
@@ -32,7 +31,7 @@ let flyTo (map: OlMap) (zoom: float) (c: float []) =
|
||||
|
||||
let zoomOut (map: OlMap) (zoom: Zoom) =
|
||||
let v = map.getView ()
|
||||
let center = v.getCenter()
|
||||
let center = v.getCenter ()
|
||||
let anim =
|
||||
Animation.animationOptions [
|
||||
Animation.animation.center center
|
||||
@@ -42,7 +41,7 @@ let zoomOut (map: OlMap) (zoom: Zoom) =
|
||||
Animation.animation.easing Animation.easeOut
|
||||
]
|
||||
|
||||
do v.animate(anim)
|
||||
do v.animate (anim)
|
||||
|
||||
module SimpleWebGLLayer =
|
||||
[<ImportDefault("../public/js/WebGLLayer")>]
|
||||
@@ -69,6 +68,7 @@ type barbTile =
|
||||
static member inline drawColor(value: string) = unbox ("drawColor", value)
|
||||
static member inline time(value: int) = unbox ("time", value)
|
||||
static member inline url(value: string) = unbox ("url", value)
|
||||
static member inline template(value: string) = unbox ("template", value)
|
||||
|
||||
module BarbTile =
|
||||
type BarbTile =
|
||||
@@ -103,50 +103,40 @@ let getInteractionByName (map: OlMap) name =
|
||||
|> fun c -> c.getArray ()
|
||||
|> Seq.tryFind (fun i ->
|
||||
let name' = i.get "name"
|
||||
name' = name)
|
||||
name' = name
|
||||
)
|
||||
|
||||
let simpleWebGL layerName (data: MapData) =
|
||||
webGLLayer [
|
||||
webglLayer.className layerName
|
||||
webglLayer.indices data.Grid.Indices
|
||||
webglLayer.props data.Props
|
||||
// NOTE(SimenLK): Breaks if you change the source from xyz
|
||||
// NOTE(simkir): Breaks if you change the source from xyz
|
||||
webglLayer.source (Source.xyz [])
|
||||
webglLayer.vertices data.Grid.Vertices
|
||||
webglLayer.opacity 0.15
|
||||
webglLayer.attenuate 0.0
|
||||
]
|
||||
|
||||
let osmLayer =
|
||||
Layer.tileLayer [
|
||||
layer.source (Source.osm [])
|
||||
]
|
||||
let osmLayer = Layer.tileLayer [ layer.source (Source.osm []) ]
|
||||
|
||||
let baseMapLayer =
|
||||
Layer.tileLayer [
|
||||
layer.source ((MapKind.MapTiler MapTiler.Basic).source())
|
||||
] :> Layer.Layer
|
||||
Layer.tileLayer [ layer.source ((MapKind.MapTiler MapTiler.Basic).source ()) ] :> Layer.Layer
|
||||
|
||||
let selectedMapLayer (kind: MapKind) =
|
||||
match kind with
|
||||
| OSM
|
||||
| MapTiler _ ->
|
||||
Layer.tileLayer [
|
||||
layer.source (kind.source())
|
||||
layer.source (kind.source ())
|
||||
layer.minZoom 0.0
|
||||
// layer.maxZoom 15.0
|
||||
] :> Layer.Layer
|
||||
// layer.maxZoom 15.0
|
||||
]
|
||||
:> Layer.Layer
|
||||
| NorgesKart Sentinel2
|
||||
| NorgesKart SeaRaster ->
|
||||
Layer.imageLayer [
|
||||
layer.source (kind.source ())
|
||||
layer.minZoom (kind.minZoom())
|
||||
] :> Layer.Layer
|
||||
| NorgesKart _ ->
|
||||
Layer.tileLayer [
|
||||
layer.source (kind.source ())
|
||||
layer.minZoom (kind.minZoom())
|
||||
] :> Layer.Layer
|
||||
Layer.imageLayer [ layer.source (kind.source ()); layer.minZoom (kind.minZoom ()) ] :> Layer.Layer
|
||||
| NorgesKart _ -> Layer.tileLayer [ layer.source (kind.source ()); layer.minZoom (kind.minZoom ()) ] :> Layer.Layer
|
||||
|
||||
let createStreamsLayer (data: MapData) uvFlat bbox =
|
||||
let streamIndices = data.Grid.Indices
|
||||
@@ -161,13 +151,20 @@ let createStreamsLayer (data: MapData) uvFlat bbox =
|
||||
]
|
||||
|
||||
// Example filter from openlayers example: https://openlayers.org/en/latest/examples/vector-wfs-getfeature.html
|
||||
let private wfsLoader (vectorSource: VectorSource) = // must return a lambda!
|
||||
fun (extent: Extent) (_: Resolution) (_: Projection) (success: Feature[] -> unit) (failure: unit -> unit) ->
|
||||
let private wfsLoader (vectorSource: VectorSource) = // NOTE: must return a lambda!
|
||||
fun
|
||||
(extent: Extent)
|
||||
(_resolution: Resolution)
|
||||
(projection: Projection)
|
||||
(success: Feature array -> unit)
|
||||
(failure: unit -> unit) ->
|
||||
let proj = projection?getCode()
|
||||
let url = Lokaliteter.wfsUrl ()
|
||||
let lower = extent[0], extent[1]
|
||||
let upper = extent[2], extent[3]
|
||||
// NOTE: THE XML IS CASE SENSITIVE!
|
||||
let filter = $"""
|
||||
let filter =
|
||||
$"""
|
||||
<fes:Filter>
|
||||
<fes:And>
|
||||
<fes:And>
|
||||
@@ -190,93 +187,118 @@ let private wfsLoader (vectorSource: VectorSource) = // must return a lambda!
|
||||
</fes:And>
|
||||
</fes:Filter>"""
|
||||
|
||||
let query = $"""
|
||||
<wfs:GetFeature service="WFS" version="2.0.0" outputFormat="GeoJSON"
|
||||
let query =
|
||||
$"""<wfs:GetFeature service="WFS" version="2.0.0" outputFormat="GeoJSON"
|
||||
xmlns:FiskeridirWFS="http://gis.fiskeridir.no/wfs/2.0"
|
||||
xmlns:wfs="http://www.opengis.net/wfs/2.0"
|
||||
xmlns:fes="http://www.opengis.net/fes/2.0"
|
||||
xmlns:gml="http://www.opengis.net/gml/3.2">
|
||||
xmlns:gml="http://www.opengis.net/gml/3.2"
|
||||
>
|
||||
<wfs:Query typeName="FiskeridirWFS:Akvakultur_-_Lokaliteter" srsName="EPSG:3857">
|
||||
{filter}
|
||||
{filter}
|
||||
</wfs:Query>
|
||||
</wfs:GetFeature>"""
|
||||
let xhr = XMLHttpRequest.Create()
|
||||
|
||||
let xhr = XMLHttpRequest.Create ()
|
||||
xhr.``open`` ("POST", url)
|
||||
xhr.addEventListener("error", fun _ ->
|
||||
vectorSource.removeLoadedExtent(extent)
|
||||
failure ())
|
||||
xhr.addEventListener("load", fun _ ->
|
||||
if xhr.status = 200 then
|
||||
let fmt = vectorSource.getFormat () :?> GeoJSON
|
||||
let features = fmt.readFeatures(xhr.responseText)
|
||||
vectorSource.addFeatures features
|
||||
success(features)
|
||||
else
|
||||
xhr.addEventListener (
|
||||
"error",
|
||||
fun _ ->
|
||||
vectorSource.removeLoadedExtent extent
|
||||
failure ()
|
||||
)
|
||||
)
|
||||
xhr.addEventListener (
|
||||
"load",
|
||||
fun _ ->
|
||||
if xhr.status = 200 then
|
||||
let fmt = vectorSource.getFormat () :?> GeoJSON
|
||||
let features = fmt.readFeatures xhr.responseText
|
||||
|
||||
do
|
||||
features
|
||||
|> Array.iter (fun feature ->
|
||||
let geom = feature.getGeometry()
|
||||
let coords = geom?getCoordinates()
|
||||
let transformed = Utils.coordToEpsg3857 coords
|
||||
|
||||
geom?setCoordinates transformed
|
||||
)
|
||||
|
||||
vectorSource.addFeatures features
|
||||
success features
|
||||
else
|
||||
failure ()
|
||||
)
|
||||
xhr.send query
|
||||
|
||||
let private createAquacultureLocalityLayer () =
|
||||
// let f : FeatureUrlFunction = emitJsExpr urlFunc "$0"
|
||||
let vectorSource =
|
||||
Source.vectorSource [
|
||||
source.projection epsg3857
|
||||
source.format (Format.geoJSON [])
|
||||
source.strategy LoadingStrategy.bbox
|
||||
]
|
||||
let proj = vectorSource.getProjection()
|
||||
console.debug("[Maps] Vector source projection: %o", proj)
|
||||
// NOTE(simkir): Here is were we set the custom WFS loader
|
||||
do vectorSource.setLoader (wfsLoader vectorSource)
|
||||
let defaultStyle =
|
||||
Style.style [
|
||||
style.image (
|
||||
Style.circle [
|
||||
circle.radius 5.0
|
||||
circle.fill (
|
||||
Style.fill [
|
||||
fill.color "rgba(150, 0, 0, 1.0)"
|
||||
]
|
||||
)
|
||||
circle.stroke (
|
||||
Style.stroke [
|
||||
stroke.color "white"
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
]
|
||||
let polygonStyle =
|
||||
Style.style [
|
||||
style.stroke (
|
||||
Style.stroke [
|
||||
stroke.color "white"
|
||||
stroke.width 1
|
||||
]
|
||||
)
|
||||
style.fill (
|
||||
Style.fill [
|
||||
fill.color "rgba(0.5, 0.5, 0.5, 0.1)"
|
||||
]
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
Layer.vectorLayer [
|
||||
layer.className (string MapLayer.Aquaculture)
|
||||
layer.zIndex 12
|
||||
layer.minZoom 7.5
|
||||
layer.source vectorSource
|
||||
layer.style (fun feature ->
|
||||
if feature.get "type" = "polygon" then
|
||||
polygonStyle
|
||||
else
|
||||
if feature.get "selected" = "true" then
|
||||
Style.style []
|
||||
else
|
||||
defaultStyle
|
||||
)
|
||||
]
|
||||
|
||||
// Ref: https://gis.fiskeridir.no/server/services/FiskeridirWFS_akva/MapServer/WFSServer?SERVICE=WFS&REQUEST=GetCapabilities
|
||||
// arcgis wfs info: https://enterprise.arcgis.com/en/server/latest/publish-services/linux/communicating-with-a-wfs-service-in-a-web-browser.htm
|
||||
let fiskeri (topic: InfoLayer) : Ol.Layer.Layer =
|
||||
if topic = Lokaliteter then
|
||||
console.debug("fiskeri")
|
||||
// let f : FeatureUrlFunction = emitJsExpr urlFunc "$0"
|
||||
let vectorSource =
|
||||
Source.vectorSource [
|
||||
source.projection epsg3857
|
||||
source.format (Format.geoJSON [])
|
||||
source.strategy LoadingStrategy.bbox
|
||||
]
|
||||
vectorSource.setLoader (wfsLoader vectorSource)
|
||||
let defaultStyle =
|
||||
Style.style [
|
||||
style.image (
|
||||
Style.circle [
|
||||
circle.radius 5.0
|
||||
circle.fill (
|
||||
Style.fill [
|
||||
fill.color "rgba(150, 0, 0, 1.0)"
|
||||
]
|
||||
)
|
||||
circle.stroke (
|
||||
Style.stroke [
|
||||
stroke.color "white"
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
]
|
||||
let polygonStyle =
|
||||
Style.style [
|
||||
style.stroke (
|
||||
Style.stroke [
|
||||
stroke.color "white"
|
||||
stroke.width 1
|
||||
]
|
||||
)
|
||||
style.fill (
|
||||
Style.fill [
|
||||
fill.color "rgba(0.5, 0.5, 0.5, 0.1)"
|
||||
]
|
||||
)
|
||||
]
|
||||
|
||||
// TODO: Try webglPoints again
|
||||
Layer.vectorLayer [
|
||||
layer.className (string MapLayer.Aquaculture)
|
||||
layer.minZoom 7.5
|
||||
layer.source vectorSource
|
||||
layer.style (fun feature ->
|
||||
if feature.get "type" = "polygon" then
|
||||
polygonStyle
|
||||
else
|
||||
if feature.get "selected" = "true" then
|
||||
Style.style []
|
||||
else
|
||||
defaultStyle)
|
||||
layer.zIndex 12
|
||||
]
|
||||
console.debug ("[Map] Creating fiskeri OpenLayers Layer on topic %o", topic)
|
||||
createAquacultureLocalityLayer ()
|
||||
else
|
||||
let alpha =
|
||||
match topic with
|
||||
@@ -290,30 +312,22 @@ let fiskeri (topic: InfoLayer) : Ol.Layer.Layer =
|
||||
source.serverType Source.ServerType.Geoserver
|
||||
source.params' !!{| layers = string topic |}
|
||||
]
|
||||
Layer.imageLayer [
|
||||
layer.source source
|
||||
layer.opacity alpha
|
||||
]
|
||||
|
||||
Layer.imageLayer [ layer.source source; layer.opacity alpha ]
|
||||
|
||||
let toGeometry ((x, y): single * single) =
|
||||
Geometry.point [
|
||||
geometry.coordinates [|
|
||||
float x
|
||||
float y
|
||||
|]
|
||||
geometry.coordinates [| float x; float y |]
|
||||
geometry.layout GeometryLayout.XY
|
||||
]
|
||||
|
||||
let toFeature (p: single * single) =
|
||||
let g = toGeometry p
|
||||
let f =
|
||||
Feature.feature [
|
||||
feature.geometryOrProperties g
|
||||
]
|
||||
let f = Feature.feature [ feature.geometryOrProperties g ]
|
||||
f.setGeometry g
|
||||
f
|
||||
|
||||
let toFeatures (p: (single * single) []) = Array.map toFeature p
|
||||
let toFeatures (p: (single * single)[]) = Array.map toFeature p
|
||||
|
||||
// let conc (r, b) (p: Particles) =
|
||||
// let source =
|
||||
@@ -362,49 +376,38 @@ let createWebGLWireframeLayer (grid: WireframeGrid) =
|
||||
WebGLWireframeLayer.webGLWireframeLayer [
|
||||
layer.source (Source.osm [])
|
||||
layer.className "wireframe"
|
||||
(Interop.mkLayerProp "vertices" grid.Vertices)
|
||||
(Interop.mkLayerProp "barycentric" grid.BarycentricCoords)
|
||||
Interop.mkLayerProp "vertices" grid.Vertices
|
||||
Interop.mkLayerProp "barycentric" grid.BarycentricCoords
|
||||
]
|
||||
|
||||
let createMapWithLayers center (layers: Layer.Layer []) =
|
||||
let createMapWithLayers center (layers: Layer.Layer[]) =
|
||||
let lonLat = fromLonLat center
|
||||
let view =
|
||||
View.view [
|
||||
view.projection epsg3857
|
||||
view.center lonLat
|
||||
view.zoom 5.5
|
||||
]
|
||||
let view = View.view [ view.projection epsg3857; view.center lonLat; view.zoom 5.5 ]
|
||||
|
||||
OlMap.map [
|
||||
map.layers layers
|
||||
map.view view
|
||||
]
|
||||
OlMap.map [ map.layers layers; map.view view ]
|
||||
|
||||
let crossHairSelect (map: OlMap) (clickKey: Event.EventsKey option ref) onClick active =
|
||||
let elem = map.getTargetElement()
|
||||
let elem = map.getTargetElement ()
|
||||
let key =
|
||||
if active then
|
||||
elem?style?cursor <- "crosshair"
|
||||
map.on (
|
||||
"click",
|
||||
(fun (e: Event.MapBrowserEvent) ->
|
||||
onClick e)
|
||||
)
|
||||
|> Some
|
||||
map.on ("click", (fun (e: Event.MapBrowserEvent) -> onClick e)) |> Some
|
||||
else
|
||||
None
|
||||
|
||||
clickKey.contents <- key
|
||||
|
||||
Hook.createDisposable (fun () ->
|
||||
console.debug("Maps.crossHairSelect dispose")
|
||||
if not (isNullOrUndefined elem) then elem?style?cursor <- ""
|
||||
Observable.unByKey key)
|
||||
console.debug ("Maps.crossHairSelect dispose")
|
||||
if not (isNullOrUndefined elem) then
|
||||
elem?style?cursor <- ""
|
||||
Observable.unByKey key
|
||||
)
|
||||
|
||||
let private hmr = HMR.createToken ()
|
||||
|
||||
// let private olCss': {| ``default``: string |} =
|
||||
// importSideEffects "../public/ol.css"
|
||||
// importSideEffects "../public/ol.css"
|
||||
|
||||
// let private olCss = olCss'.``default``
|
||||
// console.log olCss
|
||||
@@ -413,15 +416,15 @@ let private hmr = HMR.createToken ()
|
||||
let unsafeCSS _ = jsNative
|
||||
|
||||
[<LitElement("ol-map")>]
|
||||
let OlMapElement() =
|
||||
let OlMapElement () =
|
||||
let this, props =
|
||||
LitElement.init (fun cfg ->
|
||||
cfg.useShadowDom <- true
|
||||
cfg.props <- {| map = Prop.Of(OlMap.map [], attribute = "map") |}
|
||||
cfg.styles <-
|
||||
[
|
||||
// unsafeCSS olCss
|
||||
unsafeCSS """
|
||||
cfg.props <- {| map = Prop.Of (OlMap.map [], attribute = "map") |}
|
||||
cfg.styles <- [
|
||||
// unsafeCSS olCss
|
||||
unsafeCSS
|
||||
"""
|
||||
:host {
|
||||
height: 100%;
|
||||
}
|
||||
@@ -447,12 +450,14 @@ let OlMapElement() =
|
||||
padding: 10px;
|
||||
}
|
||||
"""
|
||||
])
|
||||
]
|
||||
)
|
||||
|
||||
Hook.useEffect (fun () ->
|
||||
if isNull this.shadowRoot |> not then
|
||||
let target = getShadowElementById this "map"
|
||||
props.map.Value.setTarget target)
|
||||
props.map.Value.setTarget target
|
||||
)
|
||||
|
||||
let classes = Lit.classes [ "map", true ]
|
||||
|
||||
|
||||
7
src/Atlantis/src/Client/Lib/React.fs
Normal file
7
src/Atlantis/src/Client/Lib/React.fs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Lib
|
||||
|
||||
module React =
|
||||
open Fable.Core
|
||||
open Feliz
|
||||
|
||||
let inline fromJsx (el: JSX.Element) : ReactElement = unbox el
|
||||
@@ -1,10 +1,32 @@
|
||||
module Remoting
|
||||
|
||||
open Browser
|
||||
open Fable.Remoting.Client
|
||||
open FsToolkit.ErrorHandling
|
||||
|
||||
open Atlantis
|
||||
open Sorcerer
|
||||
|
||||
let getArchiveUrl () = sessionStorage["archmaester_url"]
|
||||
let getDataUrl () = sessionStorage["sorcerer_url"]
|
||||
let tryGetArchiveUrl () = sessionStorage["archmaester_url"] |> Utils.tryStr
|
||||
let tryGetDataUrl () = sessionStorage["sorcerer_url"] |> Utils.tryStr
|
||||
|
||||
/// NOTE: This function will redirect the user on a ProxyRequestException
|
||||
let tryCatch (comp: Async<'T>) : Async<Result<'T, exn>> =
|
||||
comp
|
||||
|> Async.Catch
|
||||
|> Async.map (fun choice ->
|
||||
choice
|
||||
|> Result.ofChoice
|
||||
|> Result.teeError (function
|
||||
| :? ProxyRequestException as ex ->
|
||||
console.error("[Remoting] Proxy request error: %o", ex.Response)
|
||||
window.location.href <- "/signin"
|
||||
| _ -> ()
|
||||
)
|
||||
)
|
||||
|
||||
let authApi =
|
||||
Remoting.createApi ()
|
||||
|> Remoting.withCredentials true
|
||||
@@ -87,6 +109,7 @@ type DriftersApi(url) =
|
||||
member val Particles = createBinApi Remoting.buildProxy<Api.Drifters.Particles>
|
||||
member val FieldMetaData = createBinApi Remoting.buildProxy<Api.Drifters.FieldMetaData>
|
||||
member val Sedimentation = createBinApi Remoting.buildProxy<Api.Drifters.Sedimentation>
|
||||
member val WaterContact = createBinApi Remoting.buildProxy<Api.Drifters.WaterContact>
|
||||
member val Field2D = createBinApi Remoting.buildProxy<Api.Drifters.Field2D>
|
||||
member val Field3D = createBinApi Remoting.buildProxy<Api.Drifters.Field3D>
|
||||
member val Network = createApi Remoting.buildProxy<Api.Drifters.Network>
|
||||
@@ -109,12 +132,17 @@ type StatsApi(url) =
|
||||
|> Remoting.withRouteBuilder Api.Stats.routeBuilder
|
||||
|> f
|
||||
|
||||
member val FvStatsInfo =
|
||||
createApi Remoting.buildProxy<Api.Stats.FvStatsInfo>
|
||||
member val FvStatsInfo = createApi Remoting.buildProxy<Api.Stats.FvStatsInfo>
|
||||
member val FvStatsByLayer =
|
||||
createApi (Remoting.withBinarySerialization >> Remoting.buildProxy<Api.Stats.FvStatsByLayer>)
|
||||
createApi (
|
||||
Remoting.withBinarySerialization
|
||||
>> Remoting.buildProxy<Api.Stats.FvStatsByLayer>
|
||||
)
|
||||
member val FvStatsByIndex =
|
||||
createApi (Remoting.withBinarySerialization >> Remoting.buildProxy<Api.Stats.FvStatsByIndex>)
|
||||
createApi (
|
||||
Remoting.withBinarySerialization
|
||||
>> Remoting.buildProxy<Api.Stats.FvStatsByIndex>
|
||||
)
|
||||
member val FvStatsSeries =
|
||||
createApi (Remoting.withBinarySerialization >> Remoting.buildProxy<Api.Stats.FvStatsSeries>)
|
||||
|
||||
@@ -124,8 +152,6 @@ let driftersJobApi () =
|
||||
|> Remoting.withRouteBuilder Api.authorizedRouteBuilder
|
||||
|> Remoting.buildProxy<Api.Drifters>
|
||||
|
||||
let archiveUrl = Browser.WebStorage.sessionStorage["archmaester_url"]
|
||||
|
||||
let archiveApi () =
|
||||
Remoting.createApi ()
|
||||
|> Remoting.withCredentials true
|
||||
@@ -168,3 +194,9 @@ let plumeApi () =
|
||||
|> Remoting.withCredentials true
|
||||
|> Remoting.withRouteBuilder Api.authorizedRouteBuilder
|
||||
|> Remoting.buildProxy<Api.Plume>
|
||||
|
||||
let xtractApi () =
|
||||
Remoting.createApi ()
|
||||
|> Remoting.withCredentials true
|
||||
|> Remoting.withRouteBuilder Api.authorizedRouteBuilder
|
||||
|> Remoting.buildProxy<Api.Xtract>
|
||||
44
src/Atlantis/src/Client/Lib/Search.fs
Normal file
44
src/Atlantis/src/Client/Lib/Search.fs
Normal file
@@ -0,0 +1,44 @@
|
||||
module Search
|
||||
|
||||
open FsToolkit.ErrorHandling
|
||||
|
||||
open Sorcerer.Types
|
||||
|
||||
/// Search an archive for the closest node and elem idx based on the given coordinate
|
||||
let tryGetNearestNodeAndElement aid (x, y) : Async<Option<NodeIdx * ElemIdx>> =
|
||||
async {
|
||||
let dataSvc = Remoting.getDataUrl ()
|
||||
let api = Remoting.proximityApi dataSvc
|
||||
let! nodes = api.GetNearestNodes (aid, [| x, y |])
|
||||
let! elems = api.GetNearestElements (aid, [| x, y |])
|
||||
let firstNode = nodes |> Array.tryHead |> Option.flatten
|
||||
let firstElem = elems |> Array.tryHead |> Option.flatten
|
||||
let result =
|
||||
firstNode
|
||||
|> Option.bind (fun node -> firstElem |> Option.map (fun elem -> node, elem))
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/// Search an archive for the closest node and elem idx based on the given coordinate
|
||||
let tryGetNearestNodeAndElementRes dataSvc aid (x, y) : Async<Result<NodeIdx * ElemIdx, exn>> =
|
||||
asyncResult {
|
||||
let api = Remoting.proximityApi dataSvc
|
||||
let! nodes = api.GetNearestNodes (aid, [| x, y |]) |> Remoting.tryCatch
|
||||
let! elems = api.GetNearestElements (aid, [| x, y |]) |> Remoting.tryCatch
|
||||
let firstNode = nodes |> Array.tryHead |> Option.flatten
|
||||
let firstElem = elems |> Array.tryHead |> Option.flatten
|
||||
let result =
|
||||
firstNode
|
||||
|> Option.bind (fun node -> firstElem |> Option.map (fun elem -> node, elem))
|
||||
|> Result.requireSome (exn "Could not find node")
|
||||
|
||||
return! result
|
||||
}
|
||||
|
||||
let probePoint (aid: System.Guid) (point: float * float) : Async<Option<(float * float) * Atlantis.Types.GridIdx>> =
|
||||
async {
|
||||
let! idxOpt = tryGetNearestNodeAndElement aid point
|
||||
let res = idxOpt |> Option.map (fun idx -> point, idx)
|
||||
return res
|
||||
}
|
||||
@@ -9,10 +9,10 @@ type StreamLayerProp = interface end
|
||||
|
||||
|
||||
type StreamLayer =
|
||||
inherit Layer
|
||||
inherit Layer
|
||||
|
||||
abstract updateProps: single array -> unit
|
||||
abstract updateUvs: single array -> unit
|
||||
abstract updateProps: single array -> unit
|
||||
abstract updateUvs: single array -> unit
|
||||
|
||||
let inline mkStreamLineProp (key: string) (value: obj) : StreamLayerProp = unbox (key, value)
|
||||
|
||||
@@ -24,7 +24,7 @@ type stream =
|
||||
static member inline uvs(value: single array) = mkStreamLineProp "uvs" value
|
||||
static member inline source(value: Source) = mkStreamLineProp "source" value
|
||||
static member inline vertices(value: single array) = mkStreamLineProp "vertices" value
|
||||
static member inline geoCenter(value: single * single ) = mkStreamLineProp "geoCenter" value
|
||||
static member inline geoCenter(value: single * single) = mkStreamLineProp "geoCenter" value
|
||||
static member inline bbox(value: Sorcerer.Types.BBox) = mkStreamLineProp "bbox" value
|
||||
|
||||
[<ImportDefault("../public/js/StreamLayer")>]
|
||||
@@ -32,7 +32,6 @@ type stream =
|
||||
let private createStreamLayer _ : StreamLayer = jsNative
|
||||
|
||||
let streamLayer (opts: StreamLayerProp seq) : StreamLayer =
|
||||
let options = keyValueList CaseRules.LowerFirst opts
|
||||
|
||||
createStreamLayer options
|
||||
let options = keyValueList CaseRules.LowerFirst opts
|
||||
|
||||
createStreamLayer options
|
||||
@@ -4,10 +4,7 @@ open Fable.Core
|
||||
open Fable.Core.JsInterop
|
||||
|
||||
[<Erase>]
|
||||
type Geometry = {
|
||||
``type``: string
|
||||
coordinates: (float * float) array
|
||||
}
|
||||
type Geometry = { ``type``: string; coordinates: (float * float) array }
|
||||
|
||||
[<Erase>]
|
||||
type Feature = {
|
||||
@@ -26,22 +23,15 @@ type Feature = {
|
||||
/// <param name="sharpness">How curvy the path should be between splines. Defaults to 85.0</param>
|
||||
[<AllowNullLiteral>]
|
||||
[<Global>]
|
||||
type BezierOptions
|
||||
[<ParamObject; Emit("$0")>]
|
||||
(
|
||||
?properties,
|
||||
?resolution: float,
|
||||
?sharpness: float
|
||||
)
|
||||
=
|
||||
type BezierOptions [<ParamObject; Emit("$0")>] (?properties, ?resolution: float, ?sharpness: float) =
|
||||
member val properties: obj option = jsNative with get, set
|
||||
member val resolution: float option = jsNative with get, set
|
||||
member val sharpness: float option = jsNative with get, set
|
||||
|
||||
type Helpers () =
|
||||
type Helpers() =
|
||||
[<Import("lineString", "@turf/helpers")>]
|
||||
static member lineString(coordinates, ?properties, ?options) : Feature = jsNative
|
||||
|
||||
type Bezier () =
|
||||
type Bezier() =
|
||||
[<ImportDefault("@turf/bezier-spline")>]
|
||||
static member bezier(feature: Feature, ?options: BezierOptions) : Feature = jsNative
|
||||
@@ -1,15 +1,18 @@
|
||||
// TODO: Atlantis.Types? Atlantis client types?
|
||||
module Atlantis.Types
|
||||
|
||||
open Archmaester.Dto
|
||||
open System
|
||||
|
||||
open Fable.Core.JsInterop
|
||||
open Fable.OpenLayers
|
||||
open Proj4
|
||||
open System
|
||||
|
||||
open Archmaester.Dto
|
||||
open Drifters.ApiTypes
|
||||
open Sorcerer.Types
|
||||
open Hipster.Job
|
||||
open Sorcerer.Types
|
||||
|
||||
// TODO(simkir): These are not Types :^)
|
||||
proj4.defs ("EPSG:25832", "+proj=utm +zone=32 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs")
|
||||
proj4.defs ("EPSG:25833", "+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs")
|
||||
Proj.proj4.register proj4.proj4
|
||||
@@ -22,6 +25,36 @@ let epsg25832 = Proj.get "EPSG:25832"
|
||||
let mapAlpha0 = 0.35
|
||||
let mapAlpha1 = 0.95
|
||||
|
||||
// TODO: DU or maybe couple with properties, as they decide which to use
|
||||
/// Either a node or an elem on an FVCOM grid. Mostly used when probing for data.
|
||||
type GridIdx = NodeIdx * ElemIdx
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
type TimeUnit =
|
||||
| Hour
|
||||
| Day
|
||||
| Week
|
||||
| Month
|
||||
| Quarter
|
||||
| Year
|
||||
override x.ToString() =
|
||||
match x with
|
||||
| Hour -> "hour"
|
||||
| Day -> "day"
|
||||
| Week -> "week"
|
||||
| Month -> "month"
|
||||
| Quarter -> "quarter"
|
||||
| Year -> "year"
|
||||
static member FromString(s: string) =
|
||||
match s with
|
||||
| "hour" -> Hour
|
||||
| "day" -> Day
|
||||
| "week" -> Week
|
||||
| "month" -> Month
|
||||
| "quarter" -> Quarter
|
||||
| "year" -> Year
|
||||
| _ -> Hour
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
type Tab =
|
||||
| Select
|
||||
@@ -68,6 +101,12 @@ type NorgesKart =
|
||||
| BackgroundNorway -> "topo"
|
||||
| GEBCO -> "gebco"
|
||||
| Sentinel2 -> "2023"
|
||||
member this.ToLabel() =
|
||||
match this with
|
||||
| SeaRaster -> "Nautical"
|
||||
| BackgroundNorway -> "Kartverket"
|
||||
| GEBCO -> "Gebco"
|
||||
| Sentinel2 -> "Sentinel"
|
||||
static member epsgId =
|
||||
function
|
||||
| GEBCO -> "25833"
|
||||
@@ -92,15 +131,16 @@ type NorgesKart =
|
||||
| SeaRaster -> epsg3857 // epsg25833 //wgs84
|
||||
| _ -> epsg3857
|
||||
match x with
|
||||
| Sentinel2 | SeaRaster ->
|
||||
Source.imageWMS
|
||||
[
|
||||
source.url (x.url ())
|
||||
source.projection proj
|
||||
source.ratio 1.0
|
||||
source.serverType Source.ServerType.Geoserver
|
||||
source.params' !!{| layers = string x |}
|
||||
] :> Source
|
||||
| Sentinel2
|
||||
| SeaRaster ->
|
||||
Source.imageWMS [
|
||||
source.url (x.url ())
|
||||
source.projection proj
|
||||
source.ratio 1.0
|
||||
source.serverType Source.ServerType.Geoserver
|
||||
source.params' !!{| layers = string x |}
|
||||
]
|
||||
:> Source
|
||||
| _ -> Source.xyz [ source.projection proj; source.url (x.url ()) ] :> Source
|
||||
|
||||
type MapTiler =
|
||||
@@ -122,12 +162,22 @@ type MapTiler =
|
||||
| Toner -> "toner-v2"
|
||||
| OB_Basic -> "3f4c3c94-eac3-459b-8519-13f500453711"
|
||||
| OB_Terrain -> "b44735b0-893f-43a2-8fc9-45a1f8f3ab49"
|
||||
member this.ToLabel() =
|
||||
match this with
|
||||
| Basic -> "Basic"
|
||||
| Streets -> "Streets"
|
||||
| Topo -> "Topo"
|
||||
| Satellite -> "Satellite"
|
||||
| Ocean -> "Ocean"
|
||||
| Toner -> "Toner"
|
||||
| OB_Basic -> "Oceanbox Basic"
|
||||
| OB_Terrain -> "Terrain"
|
||||
member this.url() =
|
||||
let key = "JIDuhwaFCRDHWJjXYtJb"
|
||||
$"https://api.maptiler.com/maps/{string this}/tiles.json?key={key}"
|
||||
member this.source() =
|
||||
Source.tileJSON [
|
||||
source.url (this.url())
|
||||
source.url (this.url ())
|
||||
source.tileSize 512
|
||||
source.crossOrigin "anonymous"
|
||||
]
|
||||
@@ -141,6 +191,11 @@ type MapKind =
|
||||
| OSM -> "OpenStreetmap"
|
||||
| MapTiler x -> string x
|
||||
| NorgesKart x -> string x
|
||||
member this.ToLabel() =
|
||||
match this with
|
||||
| OSM -> "OpenStreetmap"
|
||||
| MapTiler x -> x.ToLabel()
|
||||
| NorgesKart x -> x.ToLabel()
|
||||
member this.source() =
|
||||
match this with
|
||||
| OSM -> Source.osm [] :> Source
|
||||
@@ -161,42 +216,56 @@ type MapKind =
|
||||
| SeaRaster -> 10.0
|
||||
| _ -> 5.0
|
||||
|
||||
type MapData =
|
||||
{
|
||||
Grid: PlainGrid
|
||||
Props: float32 array
|
||||
Zoom: int
|
||||
Center: float[]
|
||||
}
|
||||
static member empty =
|
||||
{
|
||||
Grid = PlainGrid.empty
|
||||
Props = Array.empty
|
||||
Zoom = 9
|
||||
Center = [| 14.39; 67.9 |]
|
||||
}
|
||||
static member OfString (str: string): MapKind option =
|
||||
match str with
|
||||
| "OpenStreetmap" -> Some OSM
|
||||
| "basic" -> Some (MapTiler Basic)
|
||||
| "streets-v2" -> Some (MapTiler Streets)
|
||||
| "topo-v2" -> Some (MapTiler Topo)
|
||||
| "satellite" -> Some (MapTiler Satellite)
|
||||
| "ocean" -> Some (MapTiler Ocean)
|
||||
| "toner-v2" -> Some (MapTiler Toner)
|
||||
| "3f4c3c94-eac3-459b-8519-13f500453711" -> Some (MapTiler OB_Basic)
|
||||
| "b44735b0-893f-43a2-8fc9-45a1f8f3ab49" -> Some (MapTiler OB_Terrain)
|
||||
| "hoved" -> Some (NorgesKart SeaRaster)
|
||||
| "topo" -> Some (NorgesKart BackgroundNorway)
|
||||
| "gebco" -> Some (NorgesKart GEBCO)
|
||||
| "2023" -> Some (NorgesKart Sentinel2)
|
||||
| _ -> None
|
||||
|
||||
type Particles = ApiParticle []
|
||||
type MapData = {
|
||||
Grid: PlainGrid
|
||||
Props: float32 array
|
||||
Zoom: int
|
||||
Center: float[]
|
||||
} with
|
||||
static member empty = {
|
||||
Grid = PlainGrid.empty
|
||||
Props = Array.empty
|
||||
Zoom = 9
|
||||
Center = [| 14.39; 67.9 |]
|
||||
}
|
||||
|
||||
type Particles = ApiParticle[]
|
||||
|
||||
type ParticleFilter = {
|
||||
fetched: bool
|
||||
availableFieldTypes: FieldKind list
|
||||
availableSedimentTypes: SedimentKind list
|
||||
availableDepthLayers: LayerType list
|
||||
availableGroupTypes: GroupType list
|
||||
availableParticleTypes: ParticleType list
|
||||
availableFieldTypes: FieldKind array
|
||||
availableSedimentTypes: SedimentKind array
|
||||
availableDepthLayers: LayerType array
|
||||
availableGroupTypes: GroupType array
|
||||
availableParticleTypes: ParticleType array
|
||||
showDepthLayer: Map<LayerIdx, bool>
|
||||
showGroupKind: Map<GroupKind, bool>
|
||||
showParticleKind: Map<ParticleKind, bool>
|
||||
}
|
||||
with
|
||||
} with
|
||||
static member empty = {
|
||||
fetched = false
|
||||
availableFieldTypes = [ UndefinedField ]
|
||||
availableSedimentTypes = [ TPM ]
|
||||
availableDepthLayers = [ { idx = 0; min = Surface; max = Bottom } ]
|
||||
availableGroupTypes = [ { idx = 0; kind = AnyGroup; name = "AnyGroup" } ]
|
||||
availableParticleTypes = [ { idx = 0; kind = AnyParticle; name = "AnyParticle" } ]
|
||||
availableFieldTypes = [| UndefinedField |]
|
||||
availableSedimentTypes = [| TPM |]
|
||||
availableDepthLayers = [| { idx = 0; min = Surface; max = Bottom } |]
|
||||
availableGroupTypes = [| { idx = 0; kind = AnyGroup; name = "AnyGroup" } |]
|
||||
availableParticleTypes = [| { idx = 0; kind = AnyParticle; name = "AnyParticle" } |]
|
||||
showDepthLayer = Map [ 0, true ]
|
||||
showGroupKind = Map [ AnyGroup, true ]
|
||||
showParticleKind = Map [ AnyParticle, true ]
|
||||
@@ -208,13 +277,15 @@ type Prop =
|
||||
| Temp
|
||||
| Salt
|
||||
| Zeta
|
||||
| Dens
|
||||
| Speed
|
||||
| Conc2D
|
||||
| Conc3D
|
||||
| SedV2
|
||||
| Sed of SedimentKind
|
||||
| SW
|
||||
| WC
|
||||
| DW
|
||||
| DW of int
|
||||
| Map
|
||||
override x.ToString() =
|
||||
match x with
|
||||
@@ -222,13 +293,15 @@ type Prop =
|
||||
| Temp -> "temp"
|
||||
| Salt -> "salt"
|
||||
| Zeta -> "zeta"
|
||||
| Dens -> "dens"
|
||||
| Speed -> "speed"
|
||||
| Conc2D -> "concentration2D"
|
||||
| Conc3D -> "concentration3D"
|
||||
| SedV2 -> "sedimentationV2"
|
||||
| Sed s -> s.ToString()
|
||||
| SW -> "shannonwiener"
|
||||
| WC -> "watercontact"
|
||||
| DW -> "downwelling"
|
||||
| DW i -> $"downwelling-{i}"
|
||||
| Map -> "map"
|
||||
|
||||
member x.ToLabel() =
|
||||
@@ -237,83 +310,137 @@ type Prop =
|
||||
| Temp -> "Temperature"
|
||||
| Salt -> "Salinity"
|
||||
| Zeta -> "Tide"
|
||||
| Dens -> "Density"
|
||||
| Speed -> "Current"
|
||||
| Conc2D -> "Concentration2D"
|
||||
| Conc3D -> "Concentration3D"
|
||||
| SedV2 -> "SedimentationV2"
|
||||
| Sed s -> s.ToLabel()
|
||||
| SW -> "Shannon-Wiener Index"
|
||||
| WC -> "Water Contact"
|
||||
| DW -> "Downwelling"
|
||||
| DW i -> "Downwelling"
|
||||
| Map -> "Map"
|
||||
|
||||
// Initial values
|
||||
/// Initial values
|
||||
member x.viewRange =
|
||||
match x with
|
||||
| Temp -> 0.0, 15.0
|
||||
| Salt -> 27.5, 35.0
|
||||
| Zeta -> -1.5, 1.5
|
||||
| Speed -> 0.0, 1.0
|
||||
| Dens -> 20.0, 27.0
|
||||
| Speed -> 0.0, 2.0
|
||||
| Conc2D -> 0.0, 1.0
|
||||
| Conc3D -> 0.0, 1.0
|
||||
| SedV2 -> 0.0, 10.0
|
||||
| Sed _ -> 0.0, 10.0
|
||||
| SW -> -4.0, 0.0
|
||||
| WC -> -100.0, 0.0
|
||||
| DW -> 0.0, 1000.0
|
||||
| DW 2 -> 0.0, 100.0
|
||||
| DW _ -> 0.0, 1000.0
|
||||
| Bathy -> 0.0, 500.0
|
||||
| _ -> 0.0, 1.0
|
||||
|
||||
// Absolute min and max
|
||||
/// Absolute min and max
|
||||
member x.minMax =
|
||||
match x with
|
||||
| Temp -> -5.0, 45.0
|
||||
| Salt -> 0.0, 50.0
|
||||
| Zeta -> -5.0, 5.0
|
||||
| Dens -> 15.0, 28.0
|
||||
| Speed -> 0.0, 5.0
|
||||
| Conc2D -> 0.0, 100.0
|
||||
| Conc3D -> 0.0, 100.0
|
||||
| SedV2 -> 0.0, 10_000.0
|
||||
| Sed _ -> 0.0, 10_000.0
|
||||
| SW -> -6.0, 0.0
|
||||
| WC -> -100.0, 0.0
|
||||
| DW -> 0.0, 10_000.0
|
||||
| DW 2 -> 0.0, 1000.0
|
||||
| DW _ -> 0.0, 10_000.0
|
||||
| Bathy -> 0.0, 1500.0
|
||||
| _ -> 0.0, 1.0
|
||||
|
||||
/// The step amount when updating a range
|
||||
member this.step : float =
|
||||
match this with
|
||||
| Temp -> 1.0
|
||||
| Salt -> 1.0
|
||||
| Zeta -> 0.1
|
||||
| Dens -> 0.1
|
||||
| Speed -> 0.1
|
||||
| Conc2D -> 0.1
|
||||
| Conc3D -> 1.0
|
||||
| Sed _ -> 10.0
|
||||
| SW -> 0.1
|
||||
| WC -> 1.0
|
||||
| DW 2 -> 1.0
|
||||
| DW _ -> 10.0
|
||||
| Bathy -> 10.0
|
||||
| _ -> 1.0
|
||||
|
||||
member x.unit =
|
||||
match x with
|
||||
| Bathy -> "m"
|
||||
| Temp -> "°C"
|
||||
| Salt -> "psu"
|
||||
| Zeta -> "m"
|
||||
| Dens -> "(ρ - 1000) kg/m3"
|
||||
| Speed -> "m/s"
|
||||
| Conc2D -> "1/km2"
|
||||
| Conc3D -> "1/km2"
|
||||
| SedV2 -> "g/m2"
|
||||
| Sed s -> s.ToUnit()
|
||||
| SW -> "H'"
|
||||
| WC -> ""
|
||||
| DW -> "ml/l"
|
||||
| DW 2 -> "%"
|
||||
| DW _ -> "ml/l"
|
||||
| Map -> ""
|
||||
|
||||
/// Chooses what type of index to use based on the property
|
||||
member this.Idx (node: NodeIdx, elem: ElemIdx) : int =
|
||||
match this with
|
||||
| Speed -> elem
|
||||
| Temp
|
||||
| Salt
|
||||
| Dens
|
||||
| Bathy
|
||||
| Temp
|
||||
| Salt
|
||||
| Zeta
|
||||
| Speed
|
||||
| Conc2D
|
||||
| Conc3D
|
||||
| Sed _
|
||||
| SedV2
|
||||
| SW
|
||||
| WC
|
||||
| DW _
|
||||
| Map -> node
|
||||
|
||||
static member fromString(str: String) =
|
||||
match str.ToLower() with
|
||||
match str.ToLower () with
|
||||
| "bathy" -> Prop.Bathy
|
||||
| "zeta" -> Prop.Zeta
|
||||
| "temp" -> Prop.Temp
|
||||
| "salt" -> Prop.Salt
|
||||
| "dens" -> Prop.Dens
|
||||
| "speed" -> Prop.Speed
|
||||
| "concentration2D" -> Prop.Conc2D
|
||||
| "concentration3D" -> Prop.Conc3D
|
||||
| "sedimentationV2" -> Prop.SedV2
|
||||
| "tpm" -> Sed TPM
|
||||
| "poc" -> Sed POC
|
||||
| "pon" -> Sed PON
|
||||
| "pop" -> Sed POP
|
||||
| "shannonwiener" -> Prop.SW
|
||||
| "watercontact" -> Prop.WC
|
||||
| "downwelling" -> Prop.DW
|
||||
| _ -> Prop.Map
|
||||
| "shannonwiener" -> SW
|
||||
| "watercontact" -> WC
|
||||
| "downwelling-1" -> DW 1
|
||||
| "downwelling-2" -> DW 2
|
||||
| _ -> Map
|
||||
|
||||
static member findRange(props: 'a array) = Array.min props, Array.max props
|
||||
|
||||
type Spinner =
|
||||
[<RequireQualifiedAccess>]
|
||||
type MapLoading =
|
||||
| Spinning
|
||||
| Progress
|
||||
|
||||
@@ -324,8 +451,10 @@ type MapLayer =
|
||||
| Ocean
|
||||
| Conc
|
||||
| Heatmap
|
||||
| SeaDistance
|
||||
| GridCircle
|
||||
| AzeContour
|
||||
| TransitionZoneContour
|
||||
| TransitionZoneContour of int
|
||||
| IsoValueContour of int
|
||||
| Particles
|
||||
| Crop
|
||||
@@ -341,14 +470,15 @@ type MapLayer =
|
||||
| GeoFences
|
||||
| Aquaculture
|
||||
| Networks
|
||||
with
|
||||
override x.ToString () =
|
||||
override x.ToString() =
|
||||
match x with
|
||||
| Ocean -> "basegl"
|
||||
| Conc -> "concgl"
|
||||
| SeaDistance -> "sea_distance"
|
||||
| GridCircle -> "grid-circle"
|
||||
| AzeContour -> "aze-contour"
|
||||
| IsoValueContour id -> $"iso-contour-{id}"
|
||||
| TransitionZoneContour -> "distance-contour"
|
||||
| TransitionZoneContour id -> $"distance-contour-{id}"
|
||||
| Crop -> "cropgl"
|
||||
| Particles -> "particles"
|
||||
| Streams -> "streams"
|
||||
@@ -364,12 +494,14 @@ with
|
||||
| GeoFences -> "geo-fences"
|
||||
| Aquaculture -> "aquaculture"
|
||||
| Networks -> "networks"
|
||||
member x.Label () =
|
||||
member x.Label() =
|
||||
match x with
|
||||
| Ocean -> "Ocean"
|
||||
| Conc -> "Concentration"
|
||||
| Ocean -> "Oceanography"
|
||||
| Conc -> "Concentrations"
|
||||
| SeaDistance -> "SeaDistance"
|
||||
| GridCircle -> $"GridCircle"
|
||||
| AzeContour -> "AzeContour"
|
||||
| TransitionZoneContour -> "DistanceContour"
|
||||
| TransitionZoneContour id -> $"DistanceContour-{id}"
|
||||
| IsoValueContour id -> $"ValueContour-{id}"
|
||||
| Crop -> "Crop"
|
||||
| Wireframe -> "Wireframe"
|
||||
@@ -386,20 +518,20 @@ with
|
||||
| GeoFences -> "Fences"
|
||||
| Aquaculture -> "Aquaculture"
|
||||
| Networks -> "Networks"
|
||||
member x.Attenuate =
|
||||
member x.Attenuate =
|
||||
match x with
|
||||
| Conc -> 0.85
|
||||
| Crop -> 1.0
|
||||
| _ -> 0.0
|
||||
|
||||
member x.Id = x.ToString()
|
||||
member x.Id = x.ToString ()
|
||||
|
||||
static member All = [|
|
||||
Ocean
|
||||
Conc
|
||||
Heatmap
|
||||
SeaDistance
|
||||
AzeContour
|
||||
TransitionZoneContour
|
||||
Particles
|
||||
Crop
|
||||
Streams
|
||||
@@ -441,14 +573,6 @@ type InfoLayer =
|
||||
| Lokaliteter -> "fiskeridirWMS_akva"
|
||||
$"https://gis.fiskeridir.no/server/services/{svc}/MapServer/WMSServer"
|
||||
member x.wfsUrl() =
|
||||
let svc =
|
||||
match x with
|
||||
| Gyting
|
||||
| Beite
|
||||
| Korall
|
||||
| Vern -> "fiskeridirWFS"
|
||||
| POs
|
||||
| Lokaliteter -> "FiskeridirWFS_akva"
|
||||
"https://gis.fiskeridir.no/server/services/FiskeridirWFS/MapServer/WFSServer"
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
@@ -462,106 +586,98 @@ type ColorMap =
|
||||
| Ocean of string
|
||||
| Color16 of string
|
||||
| Custom of string
|
||||
with
|
||||
member x.ToLabel () =
|
||||
match x with
|
||||
| Ocean n
|
||||
| Color16 n
|
||||
| Custom n -> n[ 0..0 ].ToUpper() + n[1..]
|
||||
member x.ToLabel() =
|
||||
match x with
|
||||
| Ocean n
|
||||
| Color16 n
|
||||
| Custom n -> n[0..0].ToUpper () + n[1..]
|
||||
|
||||
type PropColor =
|
||||
{
|
||||
Levels: int
|
||||
LogScale: bool
|
||||
Scientific: bool
|
||||
ViewRange: float * float
|
||||
PropRange: float * float
|
||||
ColorMap: ColorMode * ColorMap
|
||||
type PropColor = {
|
||||
Levels: int
|
||||
LogScale: bool
|
||||
Scientific: bool
|
||||
ViewRange: float * float
|
||||
PropRange: float * float
|
||||
ColorMap: ColorMode * ColorMap
|
||||
} with
|
||||
static member empty = {
|
||||
Levels = 10
|
||||
LogScale = false
|
||||
Scientific = false
|
||||
ViewRange = 0.0, 1.0
|
||||
PropRange = 0.0, 1.0
|
||||
ColorMap = ColorMode.Normal, ColorMap.Color16 "jet"
|
||||
}
|
||||
static member empty =
|
||||
{
|
||||
Levels = 10
|
||||
LogScale = false
|
||||
Scientific = false
|
||||
ViewRange = 0.0, 1.0
|
||||
PropRange = 0.0, 1.0
|
||||
ColorMap = ColorMode.Normal, ColorMap.Color16 "jet"
|
||||
}
|
||||
|
||||
type ViewProp =
|
||||
{
|
||||
PropType: Prop
|
||||
FieldKind: FieldKind
|
||||
PropData: single array
|
||||
Alpha: float
|
||||
type ViewProp = {
|
||||
PropType: Prop
|
||||
FieldKind: FieldKind
|
||||
PropData: single array
|
||||
ScalingFactor: single
|
||||
Alpha: float
|
||||
} with
|
||||
static member empty = {
|
||||
PropType = Prop.Map
|
||||
FieldKind = UndefinedField
|
||||
PropData = [||]
|
||||
ScalingFactor = 1.f
|
||||
Alpha = 1.0
|
||||
}
|
||||
static member empty =
|
||||
{
|
||||
PropType = Prop.Map
|
||||
FieldKind = UndefinedField
|
||||
PropData = [||]
|
||||
Alpha = 1.0
|
||||
}
|
||||
|
||||
type WireframeGrid =
|
||||
{
|
||||
Vertices: single array
|
||||
BarycentricCoords: int array
|
||||
}
|
||||
type WireframeGrid = {
|
||||
Vertices: single array
|
||||
BarycentricCoords: int array
|
||||
} with
|
||||
static member empty = { Vertices = Array.empty; BarycentricCoords = Array.empty }
|
||||
|
||||
type DBPlainGrid =
|
||||
{
|
||||
GridSha: string
|
||||
Grid: PlainGrid
|
||||
}
|
||||
type DBPlainGrid = {
|
||||
GridSha: string
|
||||
Grid: PlainGrid
|
||||
} with
|
||||
static member store = "PlainGrids"
|
||||
|
||||
// NOTE(simkir): ArchiveDetails does not have number of frames
|
||||
type ArchiveInfo =
|
||||
{
|
||||
id: Guid
|
||||
sha: string
|
||||
name: string
|
||||
/// Seconds
|
||||
saveFreq: int
|
||||
startTime: DateTime
|
||||
defaultZoom: float
|
||||
focalPoint: float * float
|
||||
polygon: (float * float) [] option
|
||||
frames: int
|
||||
type ArchiveInfo = {
|
||||
id: Guid
|
||||
sha: string
|
||||
name: string
|
||||
/// Seconds
|
||||
saveFreq: int
|
||||
startTime: DateTime
|
||||
defaultZoom: float
|
||||
focalPoint: float * float
|
||||
polygon: (float * float) array option
|
||||
frames: int
|
||||
} with
|
||||
static member empty = {
|
||||
id = Guid.Empty
|
||||
sha = ""
|
||||
name = ""
|
||||
saveFreq = 0
|
||||
startTime = DateTime.MinValue
|
||||
defaultZoom = 10.0
|
||||
focalPoint = 0.0, 0.0
|
||||
polygon = None
|
||||
frames = 0
|
||||
}
|
||||
static member empty =
|
||||
{
|
||||
id = Guid.Empty
|
||||
sha = ""
|
||||
name = ""
|
||||
saveFreq = 0
|
||||
startTime = DateTime.MinValue
|
||||
defaultZoom = 10.0
|
||||
focalPoint = 0.0, 0.0
|
||||
polygon = None
|
||||
frames = 0
|
||||
|
||||
type SimArchive = {
|
||||
Archive: ArchiveProps
|
||||
Duration: TimeSpan
|
||||
Reverse: bool
|
||||
Status: JobStatus
|
||||
JobId: int option
|
||||
SimType: DriftersVariant
|
||||
SimFormat: DriftersFormat
|
||||
} with
|
||||
static member Create(sim: SimulationModel) =
|
||||
let archive = {
|
||||
ArchiveProps.empty with
|
||||
reference = sim.aid |> Some
|
||||
freq = sim.saveFreq.ToFloat () |> int
|
||||
startTime = sim.startTime
|
||||
}
|
||||
|
||||
|
||||
type SimArchive =
|
||||
{
|
||||
Archive: ArchiveProps
|
||||
Duration: TimeSpan
|
||||
Reverse: bool
|
||||
Status: JobStatus
|
||||
JobId: int option
|
||||
SimType: DriftersVariant
|
||||
SimFormat: DriftersFormat
|
||||
}
|
||||
static member Create (sim: SimulationModel) =
|
||||
let archive =
|
||||
{ ArchiveProps.empty with
|
||||
reference = sim.aid |> Some
|
||||
freq = sim.saveFreq.ToFloat() |> int
|
||||
startTime = sim.startTime
|
||||
}
|
||||
{
|
||||
Archive = archive
|
||||
Duration = sim.simDays |> TimeSpan.FromDays
|
||||
@@ -578,11 +694,12 @@ type SimArchive =
|
||||
| DownwellingSim -> DriftersVariant.Downwelling
|
||||
SimFormat = DriftersFormat.Particle
|
||||
}
|
||||
static member Create (ana: AnalysisModel) =
|
||||
|
||||
static member Create(ana: AnalysisModel) =
|
||||
let tStart = ana.startTime |> Option.defaultValue DateTime.Now
|
||||
let tEnd = ana.endTime |> Option.defaultValue DateTime.Now
|
||||
{
|
||||
Archive = { ArchiveProps.empty with freq = ana.saveFreq.ToFloat() |> int; startTime = tStart }
|
||||
Archive = { ArchiveProps.empty with freq = ana.saveFreq.ToFloat () |> int; startTime = tStart }
|
||||
Duration = tEnd - tStart
|
||||
Reverse = ana.reverse
|
||||
Status = JobStatus.New
|
||||
@@ -617,7 +734,7 @@ type PlumeSimModel = {
|
||||
name = ""
|
||||
fvcom = System.Guid.Empty
|
||||
start = DateTime.Now
|
||||
stop = DateTime.Now.AddDays(4)
|
||||
stop = DateTime.Now.AddDays (4)
|
||||
timeIdx = 0
|
||||
}
|
||||
|
||||
@@ -639,54 +756,82 @@ type PlumeTraits = {
|
||||
salt: float
|
||||
transport: float
|
||||
} with
|
||||
static member empty = {
|
||||
temp = 15.0
|
||||
salt = 0.0
|
||||
transport = 0.333
|
||||
}
|
||||
static member empty = { temp = 15.0; salt = 0.0; transport = 0.333 }
|
||||
|
||||
type PlumeType =
|
||||
| DefaultPlume
|
||||
override this.ToString (): string =
|
||||
match this with
|
||||
| DefaultPlume -> "plume"
|
||||
|
||||
member this.ToLabel() =
|
||||
match this with
|
||||
| DefaultPlume -> "Plume"
|
||||
|
||||
type XtractType =
|
||||
| DefaultXtract
|
||||
override this.ToString (): string =
|
||||
match this with
|
||||
| DefaultXtract -> "xtract"
|
||||
|
||||
member this.ToLabel() =
|
||||
match this with
|
||||
| DefaultXtract -> "Xtract"
|
||||
|
||||
type XtractData = {
|
||||
name: string
|
||||
fvcom: System.Guid
|
||||
start: DateTime
|
||||
stop: DateTime
|
||||
} with
|
||||
static member empty = {
|
||||
name = ""
|
||||
fvcom = System.Guid.Empty
|
||||
start = DateTime.Now
|
||||
stop = DateTime.Now.AddDays (2)
|
||||
}
|
||||
|
||||
type SimControlKind =
|
||||
| Drifters of SimType
|
||||
| Plume of PlumeType
|
||||
| DataExtraction of XtractType
|
||||
override this.ToString (): string =
|
||||
match this with
|
||||
| Drifters simType -> string simType
|
||||
| Plume plumeType -> string plumeType
|
||||
| DataExtraction xtractType -> string xtractType
|
||||
member this.ToLabel() =
|
||||
match this with
|
||||
| Drifters simType -> simType.ToLabel ()
|
||||
| Plume plumeType -> plumeType.ToLabel ()
|
||||
| DataExtraction xtractType -> xtractType.ToLabel ()
|
||||
member this.simTypeOpt =
|
||||
match this with
|
||||
| Drifters simType -> Some simType
|
||||
| Plume plumeType -> None
|
||||
| DataExtraction xtractType -> None
|
||||
|
||||
// TODO: Not sure if anything but Mapster needs to know about this
|
||||
type SideNavMode =
|
||||
| OceanControls
|
||||
| SimControls of SimControlKind
|
||||
| AnalysisControls of SimArchive
|
||||
| ColorControls
|
||||
| LayerControls
|
||||
| StatsControls
|
||||
| CropControls
|
||||
// | NetworkControls
|
||||
with
|
||||
member this.ToLabel () =
|
||||
match this with
|
||||
| OceanControls -> "Ocean controls"
|
||||
| SimControls simControlKind -> $"Simulation controls {simControlKind.ToLabel ()}"
|
||||
| AnalysisControls _ -> "Analysis controls"
|
||||
| ColorControls -> "Color controls"
|
||||
| LayerControls -> "Layer controls"
|
||||
| StatsControls -> "Stats controls"
|
||||
| CropControls -> "Crop controls"
|
||||
| OceanControls
|
||||
| SimControls of SimControlKind
|
||||
| AnalysisControls of SimArchive
|
||||
| ColorControls
|
||||
| LayerControls
|
||||
| CropControls
|
||||
// | NetworkControls
|
||||
member this.ToLabel() =
|
||||
match this with
|
||||
| OceanControls -> "Ocean controls"
|
||||
| SimControls simControlKind -> $"Simulation controls {simControlKind.ToLabel ()}"
|
||||
| AnalysisControls _ -> "Analysis controls"
|
||||
| ColorControls -> "Color controls"
|
||||
| LayerControls -> "Layer controls"
|
||||
| CropControls -> "Crop controls"
|
||||
|
||||
type Props =
|
||||
{
|
||||
arrows: Arrow<float>[]
|
||||
}
|
||||
type Props = {
|
||||
arrows: Arrow<float>[]
|
||||
} with
|
||||
static member empty = { arrows = [||] }
|
||||
|
||||
module HeatMap =
|
||||
@@ -697,13 +842,15 @@ type SampleData = {
|
||||
name: string
|
||||
coord: Coordinate
|
||||
radius: float
|
||||
value: float
|
||||
value: float option
|
||||
nodes: NodeIdx array option
|
||||
} with
|
||||
static member empty = {
|
||||
coord = [| 0.0; 0.0 |]
|
||||
name = "Sample"
|
||||
radius = 5.0
|
||||
value = 0.0
|
||||
value = None
|
||||
nodes = None
|
||||
}
|
||||
|
||||
type LineData = {
|
||||
|
||||
69
src/Atlantis/src/Client/Lib/Umami.fs
Normal file
69
src/Atlantis/src/Client/Lib/Umami.fs
Normal file
@@ -0,0 +1,69 @@
|
||||
module Lib
|
||||
|
||||
open Browser
|
||||
open Fable.Core
|
||||
open Fable.Core.JsInterop
|
||||
|
||||
type private IUmami =
|
||||
abstract track : payload: obj -> unit
|
||||
abstract track : eventName: string * ?data: obj -> unit
|
||||
|
||||
type Umami =
|
||||
static member track(eventName: string) =
|
||||
let umami : IUmami = window?umami
|
||||
console.debug("[Umami] Umami %o track event %s", umami, eventName)
|
||||
umami.track eventName
|
||||
|
||||
static member track(eventName: string, data: obj) =
|
||||
let umami : IUmami = window?umami
|
||||
console.debug("[Umami] Umami %o track event %s with data %o", umami, eventName, data)
|
||||
umami.track(eventName, data)
|
||||
|
||||
module Umami =
|
||||
|
||||
module ReactLib =
|
||||
open Feliz
|
||||
|
||||
let inline private toReact (elem: JSX.Element) : ReactElement = unbox elem
|
||||
|
||||
// TODO: This requires React 19
|
||||
// <script defer src="https://umami.srv.oceanbox.io/umami" data-website-id="6f26c702-2c6d-46ea-8122-ffcedda5f762"></script>
|
||||
[<JSX.Component>]
|
||||
let UmamiScriptComponent () =
|
||||
let handleLoad () =
|
||||
console.info("[Umami] Loaded")
|
||||
|
||||
React.useEffectOnce (fun () ->
|
||||
console.debug("[Umami] Mounting UmamiScript")
|
||||
)
|
||||
|
||||
JSX.html
|
||||
$"""
|
||||
<script async src="https://umami.srv.oceanbox.io/umami" onLoad={fun () -> handleLoad ()} />
|
||||
"""
|
||||
|> toReact
|
||||
|
||||
|
||||
let createScriptElement (websiteId: System.Guid) =
|
||||
let script = document.createElement "script"
|
||||
script.setAttribute("src", "https://umami.srv.oceanbox.io/umami")
|
||||
script.setAttribute("data-website-id", string websiteId)
|
||||
// NOTE: This function must exist in the head tag. See atlas.html
|
||||
script.setAttribute("data-before-send", "beforeSendHandler")
|
||||
|
||||
script
|
||||
|
||||
/// Appends the elem to <head>
|
||||
let addScriptElem (scriptElem: Types.HTMLElement) =
|
||||
// NOTE: Can we append this somewhere else?
|
||||
do document.head.appendChild scriptElem |> ignore
|
||||
|
||||
/// Downloads the id for the current env, creates the script element, and adds it to the DOM
|
||||
let init () =
|
||||
async {
|
||||
match! Remoting.servicesApi.GetAnalyticsWebId () with
|
||||
| Some id ->
|
||||
let script = createScriptElement (System.Guid id)
|
||||
do addScriptElem script
|
||||
| None -> ()
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
module Utils
|
||||
|
||||
open System
|
||||
|
||||
open Browser
|
||||
open Fable.Core
|
||||
open Fable.Core.JsInterop
|
||||
open Fable.OpenLayers
|
||||
open FsToolkit.ErrorHandling
|
||||
|
||||
open Proj4
|
||||
|
||||
proj4.defs ("EPSG:25832", "+proj=utm +zone=32 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs")
|
||||
@@ -19,17 +22,27 @@ let epsg25832 = Proj.get "EPSG:25832"
|
||||
let dimap f (a, b) = f a, f b
|
||||
|
||||
let inline posToCoord (pos: 'a * 'a) : Coordinate = unbox pos
|
||||
let inline coordToPos (coord : Coordinate) = coord[0], coord[1]
|
||||
let inline coordToPos (coord: Coordinate) = coord[0], coord[1]
|
||||
|
||||
let inline tryMaxDefault d s = if (Seq.isEmpty s) then d else Seq.max s
|
||||
let inline tryParseFloat (s: string) : float option = s |> Double.TryParse |> function | true, f -> Some f | _ -> None
|
||||
let inline tryMaxDefault d s = if Seq.isEmpty s then d else Seq.max s
|
||||
let inline tryParseFloat (s: string) : float option =
|
||||
s
|
||||
|> Double.TryParse
|
||||
|> function
|
||||
| true, f -> Some f
|
||||
| _ -> None
|
||||
|
||||
let formatDigits n m = {| minimumFractionDigits = n; maximumFractionDigits = m |} |> JS.JSON.stringify
|
||||
let formatPercent n = {| style = "percent"; minimumFractionDigits = n; maximumFractionDigits = n |} |> JS.JSON.stringify
|
||||
let formatDigits n m =
|
||||
{| minimumFractionDigits = n; maximumFractionDigits = m |} |> JS.JSON.stringify
|
||||
let formatPercent n =
|
||||
{| style = "percent"; minimumFractionDigits = n; maximumFractionDigits = n |}
|
||||
|> JS.JSON.stringify
|
||||
|
||||
let toWgs84 (x, y) = Proj.transform (posToCoord(x, y), epsg3857, wgs84)
|
||||
let toWgs84 (x, y) =
|
||||
Proj.transform (posToCoord (x, y), epsg3857, wgs84)
|
||||
|
||||
let toEpsg3857 (x, y) = Proj.transform (posToCoord(x, y), wgs84, epsg3857)
|
||||
let toEpsg3857 (x, y) =
|
||||
Proj.transform (posToCoord (x, y), wgs84, epsg3857)
|
||||
|
||||
let inline toWgs84' pos = toWgs84 pos |> coordToPos
|
||||
|
||||
@@ -44,7 +57,24 @@ let coordToWgs84Pos = coordToWgs84 >> coordToPos
|
||||
let coordToEpsg3857Pos = coordToEpsg3857 >> coordToPos
|
||||
|
||||
let mercatorScaleFactor (lat: float) =
|
||||
1.0 / (lat * Math.PI / 180.0 |> Math.Cos)
|
||||
1.0 / (lat * Math.PI / 180.0 |> Math.Cos)
|
||||
|
||||
let toRadians degrees = degrees * Math.PI / 180.0
|
||||
|
||||
let haversineDistance (lon1: float, lat1: float) (lon2: float, lat2: float) =
|
||||
let earthRadius = 6.371e6 // Earth's radius in meters
|
||||
|
||||
let dLat = toRadians(lat2 - lat1)
|
||||
let dLon = toRadians(lon2 - lon1)
|
||||
let lat1 = toRadians(lat1)
|
||||
let lat2 = toRadians(lat2)
|
||||
|
||||
let a = Math.Sin(dLat/2.0) * Math.Sin(dLat/2.0) +
|
||||
Math.Sin(dLon/2.0) * Math.Sin(dLon/2.0) *
|
||||
Math.Cos(lat1) * Math.Cos(lat2)
|
||||
|
||||
let c = 2.0 * Math.Asin(Math.Sqrt(a))
|
||||
earthRadius * c // Returns distance in meters
|
||||
|
||||
[<Emit("atob($0)")>]
|
||||
let fromBase64String (s: string) : string = jsNative
|
||||
@@ -52,96 +82,38 @@ let fromBase64String (s: string) : string = jsNative
|
||||
[<Emit("btoa($0)")>]
|
||||
let toBase64String (s: string) : string = jsNative
|
||||
|
||||
let strNull = String.IsNullOrWhiteSpace
|
||||
let strNotNull = strNull >> not
|
||||
/// Helper function for testing whether a string is null or only whitespace
|
||||
let tryStr str =
|
||||
if String.IsNullOrWhiteSpace str then
|
||||
None
|
||||
else
|
||||
Some str
|
||||
let tryStr str = if strNotNull str then Some str else None
|
||||
|
||||
let tryGetElemRect id =
|
||||
let elem : Types.HTMLElement = document.getElementById id
|
||||
/// Uses js getElementById on the HTML id. Tests elem for isNullOrUndefined
|
||||
let tryElem (id: string) : Types.Element option =
|
||||
let elem = document.getElementById id
|
||||
|
||||
if isNullOrUndefined elem then
|
||||
None
|
||||
else
|
||||
elem.getBoundingClientRect()
|
||||
|> Some
|
||||
if isNullOrUndefined elem then None else Some elem
|
||||
|
||||
let tryGetElemRect (id: string) : Types.ClientRect option =
|
||||
tryElem id |> Option.map _.getBoundingClientRect()
|
||||
|
||||
module Result =
|
||||
let apply fRes xRes =
|
||||
match fRes, xRes with
|
||||
| Ok f, Ok x -> Ok (f x)
|
||||
| _ -> Error ()
|
||||
let prettyPrintCoord (p: float * float) : string =
|
||||
let lat, lng = toWgs84' p
|
||||
sprintf "%0.3f, %0.3f" lat lng
|
||||
|
||||
let mapError (f: 'a -> 'b) (res: Result<'T, 'a>) : Result<_, 'b> =
|
||||
match res with
|
||||
| Ok x -> Ok x
|
||||
| Error err ->
|
||||
f err
|
||||
|> Error
|
||||
|
||||
module Array =
|
||||
let (<*>) = Result.apply
|
||||
|
||||
let notEmpty (arr : 'T array) : bool =
|
||||
arr
|
||||
|> Array.isEmpty
|
||||
|> not
|
||||
|
||||
let traverseResult f array =
|
||||
let cons head tail = Array.append [| head |] tail
|
||||
let init = Ok [||]
|
||||
let folder head tail =
|
||||
Ok cons <*> f head <*> tail
|
||||
|
||||
Array.foldBack folder array init
|
||||
|
||||
let sequenceResults x = traverseResult id x
|
||||
|
||||
let depthsToCommon5m depths =
|
||||
let depthsToCommon5m (depths: single array) : (int * int) list =
|
||||
let dp = [| -5.f; -10.f; -15.f; -25.f; -50.f; -99999.f |]
|
||||
|
||||
((0, [ 0 ]), Array.indexed depths)
|
||||
||> Array.fold (fun (n, a) (l, x) ->
|
||||
if x > dp[n] then
|
||||
n, a
|
||||
else
|
||||
(n + 1, l :: a))
|
||||
||> Array.fold (fun (n, a) (l, x) -> if x > dp[n] then n, a else n + 1, l :: a)
|
||||
|> snd
|
||||
|> fun x -> (depths.Length - 1) :: x
|
||||
|> fun x -> depths.Length - 1 :: x
|
||||
|> List.rev
|
||||
|> List.map (fun n -> n, Math.Round(float depths[n] / 5.0) * 5.0 |> int)
|
||||
|
||||
let tryGetNearestNodeAndElement dataSvc aid (x, y) =
|
||||
async {
|
||||
let api = Remoting.proximityApi dataSvc
|
||||
let! nodes = api.GetNearestNodes (aid, [| x, y |])
|
||||
let! elems = api.GetNearestElements (aid, [| x, y |])
|
||||
let firstNode =
|
||||
nodes
|
||||
|> Array.tryHead
|
||||
|> Option.flatten
|
||||
let firstElem =
|
||||
elems
|
||||
|> Array.tryHead
|
||||
|> Option.flatten
|
||||
|
||||
return
|
||||
firstNode
|
||||
|> Option.bind (fun node ->
|
||||
firstElem
|
||||
|> Option.map (fun elem ->
|
||||
node, elem
|
||||
)
|
||||
)
|
||||
}
|
||||
|> List.map (fun n -> n, Math.Round (float depths[n] / 5.0) * 5.0 |> int)
|
||||
|
||||
let handleKeyPress key action =
|
||||
fun () ->
|
||||
let handleKeyup (ev: Browser.Types.Event) =
|
||||
let kev = ev :?> Browser.Types.KeyboardEvent
|
||||
let handleKeyup (ev: Types.Event) =
|
||||
let kev = ev :?> Types.KeyboardEvent
|
||||
if kev.key = key then
|
||||
action ()
|
||||
|
||||
@@ -150,8 +122,7 @@ let handleKeyPress key action =
|
||||
// the two functions between add and remove..
|
||||
window.addEventListener ("keyup", handleKeyup, true)
|
||||
|
||||
Lit.Hook.createDisposable (fun () ->
|
||||
window.removeEventListener ("keyup", handleKeyup, true))
|
||||
Lit.Hook.createDisposable (fun () -> window.removeEventListener ("keyup", handleKeyup, true))
|
||||
|
||||
let onEnterOrEscape onEnter onEscape (ev: Types.Event) =
|
||||
let kev = ev :?> Types.KeyboardEvent
|
||||
@@ -160,17 +131,22 @@ let onEnterOrEscape onEnter onEscape (ev: Types.Event) =
|
||||
| "Escape" -> onEscape ev
|
||||
| _ -> ()
|
||||
|
||||
let debounce delay (f: 'T -> unit) : 'T -> unit =
|
||||
let mutable timer = unbox null
|
||||
fun args ->
|
||||
do JS.clearTimeout timer
|
||||
do timer <- JS.setTimeout (fun () -> f args) delay
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the ISO week number from a date. Taken from https://weeknumber.com/how-to/javascript since we cannot
|
||||
/// use https://learn.microsoft.com/en-us/dotnet/api/system.globalization.calendar.getweekofyear?view=net-8.0
|
||||
/// or https://learn.microsoft.com/en-us/dotnet/api/system.globalization.isoweek?view=net-8.0
|
||||
/// </summary>
|
||||
let getWeek (date: DateTime) : int =
|
||||
let findThursdayInWeek (day: int) (dayInWeek : int) : int =
|
||||
day + 3 - (dayInWeek + 6) % 7
|
||||
let thisWeeksThursday : int = findThursdayInWeek date.Day (int date.DayOfWeek)
|
||||
let findThursdayInWeek (day: int) (dayInWeek: int) : int = day + 3 - (dayInWeek + 6) % 7
|
||||
let thisWeeksThursday: int = findThursdayInWeek date.Day (int date.DayOfWeek)
|
||||
let thursdayThisWeek =
|
||||
DateTime(
|
||||
DateTime (
|
||||
year = date.Year,
|
||||
month = date.Month,
|
||||
day = thisWeeksThursday,
|
||||
@@ -180,18 +156,10 @@ let getWeek (date: DateTime) : int =
|
||||
kind = DateTimeKind.Utc
|
||||
)
|
||||
let weekOne =
|
||||
DateTime(
|
||||
year = date.Year,
|
||||
month = 1,
|
||||
day = 4,
|
||||
hour = 0,
|
||||
minute = 0,
|
||||
second = 0,
|
||||
kind = DateTimeKind.Utc
|
||||
)
|
||||
DateTime (year = date.Year, month = 1, day = 4, hour = 0, minute = 0, second = 0, kind = DateTimeKind.Utc)
|
||||
let thursday = findThursdayInWeek weekOne.Day (int weekOne.DayOfWeek)
|
||||
let thursdayWeekOne =
|
||||
DateTime(
|
||||
DateTime (
|
||||
year = date.Year,
|
||||
month = 1,
|
||||
day = thursday,
|
||||
@@ -203,38 +171,66 @@ let getWeek (date: DateTime) : int =
|
||||
let diff = thursdayThisWeek - thursdayWeekOne
|
||||
let week = 1 + int (diff.TotalDays / 7.0)
|
||||
|
||||
// TODO: Test when there are 53 weeks ...
|
||||
Int32.Clamp(week, 1, 52)
|
||||
// TODO: Test when there are 53 weeks...
|
||||
Int32.Clamp (week, 1, 52)
|
||||
|
||||
/// Given a list of indices, try adding a new one by adding the last one by 1, or return 1. If 1 it is then the first entry
|
||||
let tryAddIdx: int seq -> int =
|
||||
Seq.tryLast
|
||||
>> Option.map ((+) 1)
|
||||
>> Option.defaultValue 1
|
||||
module Archives =
|
||||
open Atlantis.Types
|
||||
|
||||
/// Given a list of indices, return last idx, or if there's a missing index in the sequence
|
||||
let findIdx (idxs: int seq) : int =
|
||||
// NOTE: We want the indices to start at 1
|
||||
(1, idxs)
|
||||
||> Seq.fold (fun index idx ->
|
||||
if index = idx then
|
||||
// NOTE: If the sequence advances as expected, increment the acc together with the indices ...
|
||||
idx + 1
|
||||
/// Calculates the time for the given frame
|
||||
let findFrameTime (archive: Atlantis.Types.ArchiveInfo) (frame: int) : DateTime =
|
||||
let duration = System.TimeSpan.FromSeconds (float frame * float archive.saveFreq)
|
||||
archive.startTime.ToUniversalTime() + duration
|
||||
|
||||
/// Calculates the time for the given frame. Must be within range of the archives' total frames.
|
||||
let tryFindFrameTime (archive: Atlantis.Types.ArchiveInfo) (frame: int) : DateTime option =
|
||||
if 0 <= frame && frame <= archive.frames then
|
||||
Some (findFrameTime archive frame)
|
||||
else
|
||||
// ... but if the sequence is broken, remember which index it stopped at, and remember that
|
||||
index
|
||||
)
|
||||
None
|
||||
|
||||
/// Given a list of indices, try to getting the very last key, otherwise return 1
|
||||
let tryLastIdx: int seq -> int = Seq.tryLast >> Option.defaultValue 1
|
||||
/// Calculates when the archive ends based on the total number of frames, the save frequency and the start time.
|
||||
let findEndTime (archive: Atlantis.Types.ArchiveInfo) : DateTime =
|
||||
let duration = System.TimeSpan.FromSeconds (float archive.frames * float archive.saveFreq)
|
||||
archive.startTime.ToUniversalTime() + duration
|
||||
|
||||
let initAtlantisSessionUrls () =
|
||||
async {
|
||||
let! aUrl = Remoting.servicesApi.GetArchiveService()
|
||||
console.log $"Archive service: {aUrl}"
|
||||
sessionStorage["archmaester_url"] <- aUrl
|
||||
let getMaxTimeStep (timeUnit: Atlantis.Types.TimeUnit) (archive: Atlantis.Types.ArchiveInfo) frame : int option =
|
||||
let availableSeconds = (archive.frames - frame) * archive.saveFreq |> float
|
||||
let ts = TimeSpan.FromSeconds availableSeconds
|
||||
|
||||
let! sUrl = Remoting.servicesApi.GetFileService()
|
||||
console.log $"Data service: {sUrl}"
|
||||
sessionStorage["sorcerer_url"] <- sUrl
|
||||
}
|
||||
match timeUnit with
|
||||
| TimeUnit.Hour -> if ts.Hours >= 1 then Some ts.Hours else None
|
||||
| TimeUnit.Day -> if ts.Days >= 1 then Some ts.Hours else None
|
||||
| TimeUnit.Week -> if ts.Days >= 7 then Some (ts.Days / 7) else None
|
||||
| TimeUnit.Month -> if ts.Days >= 30 then Some (ts.Days / 30) else None
|
||||
| TimeUnit.Quarter -> if ts.Days >= 90 then Some (ts.Days / 90) else None
|
||||
| TimeUnit.Year -> if ts.Days >= 365 then Some (ts.Days / 365) else None
|
||||
|
||||
module Result =
|
||||
let apply (fRes: Result<'T -> 'U, 'Err>) (xRes: Result<'T, 'Err>) : Result<'U, 'Err> =
|
||||
match fRes, xRes with
|
||||
| Ok f, Ok x -> Ok (f x)
|
||||
| Ok _, Error err -> Error err
|
||||
| Error err, Ok _ -> Error err
|
||||
// TODO: Which error should you return?
|
||||
| Error _, Error err -> Error err
|
||||
|
||||
let mapError (f: 'T -> 'U) (res: Result<'Ok, 'T>) : Result<'Ok, 'U> =
|
||||
match res with
|
||||
| Ok x -> Ok x
|
||||
| Error err -> Error (f err)
|
||||
|
||||
module Array =
|
||||
let (<*>) = Result.apply
|
||||
|
||||
let notEmpty (arr: 'T array) : bool = arr |> Array.isEmpty |> not
|
||||
|
||||
/// Monadic foldBack
|
||||
let traverseResult (f: 'T -> Result<'U, 'Err>) (array: 'T array) : Result<'U array, 'Err> =
|
||||
let cons head tail = tail |> Array.append [| head |]
|
||||
let init = Ok [||]
|
||||
let folder head tail = Ok cons <*> f head <*> tail
|
||||
|
||||
init |> Array.foldBack folder array
|
||||
|
||||
let sequenceResults x = traverseResult id x
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user