diff options
-rw-r--r-- | .gitignore | 8 | ||||
-rw-r--r-- | Makefile | 25 | ||||
-rw-r--r-- | data/final.csv | 211 | ||||
-rw-r--r-- | data/sol_asteroids.csv | 1915 | ||||
-rw-r--r-- | data/sol_planets.csv | 9 | ||||
-rw-r--r-- | data/sol_satellites.csv | 211 | ||||
-rw-r--r-- | include/camera.hpp | 96 | ||||
-rw-r--r-- | include/csv.hpp | 115 | ||||
-rw-r--r-- | include/ecs.hpp | 139 | ||||
-rw-r--r-- | include/entitycomponents.hpp | 58 | ||||
-rw-r--r-- | include/game.hpp | 52 | ||||
-rw-r--r-- | include/input.hpp | 71 | ||||
-rw-r--r-- | include/keybind.hpp | 71 | ||||
-rw-r--r-- | include/shape.hpp | 197 | ||||
-rw-r--r-- | include/straw.hpp | 312 | ||||
-rw-r--r-- | include/system.hpp | 82 | ||||
-rw-r--r-- | include/timeman.hpp | 27 | ||||
-rw-r--r-- | include/units.hpp | 166 | ||||
-rw-r--r-- | include/util.hpp | 45 | ||||
-rw-r--r-- | include/vex.hpp | 104 | ||||
-rw-r--r-- | include/window.hpp | 69 | ||||
-rw-r--r-- | src/camera.cpp | 197 | ||||
-rw-r--r-- | src/game.cpp | 115 | ||||
-rw-r--r-- | src/input.cpp | 37 | ||||
-rw-r--r-- | src/keybind.cpp | 64 | ||||
-rw-r--r-- | src/main.cpp | 26 | ||||
-rw-r--r-- | src/system.cpp | 517 | ||||
-rw-r--r-- | src/timeman.cpp | 49 | ||||
-rw-r--r-- | src/units.cpp | 61 | ||||
-rw-r--r-- | src/window.cpp | 72 |
30 files changed, 5121 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9425e48 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +keybinds.csv +compile_commands.json +bin +.cache +spacelike +*.o + + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8176c1f --- /dev/null +++ b/Makefile @@ -0,0 +1,25 @@ +PWD := $(shell pwd) + +SDIR := $(PWD)/src +IDIR := $(PWD)/include +ODIR := $(PWD)/bin + +SFILES := $(wildcard $(SDIR)/*.cpp) +OFILES := $(patsubst $(SDIR)/%.cpp,$(ODIR)/%.o,$(SFILES)) + +OUT := spacelike + +CC := g++ +CFLAGS := -std=c++20 -Wall -Wextra -MP -MD -I$(IDIR) -g -Wno-unused + +-include $(SDIR/:.cpp=.d) + +all: ${OFILES} + $(CC) $(CFLAGS) ${OFILES} -o $(OUT) + +clean: + rm ${OFILES} + +$(ODIR)/%.o : $(SDIR)/%.cpp + $(CC) $(CFLAGS) -c $< -o $@ + diff --git a/data/final.csv b/data/final.csv new file mode 100644 index 0000000..ffa2e5f --- /dev/null +++ b/data/final.csv @@ -0,0 +1,211 @@ +,,0,0,0,0,0,0 +Hydra,Pluto,0.000432493,0.006,8.02782e-09,0.00290378,330.6,143.4 +Charon,Pluto,0.000131018,0,0.00026562,0.0951185,192.4,0 +Neso,Neptune,0.334536,0.447,0,0,123.2,338.3 +Sao,Neptune,0.14961,0.299,0,0,179.6,90.9 +Hippocamp,Neptune,0.000703887,0.001,0,0,286.5,346.4 +Proteus,Neptune,0.000786107,0,6.48101e-06,0.0326479,276.8,0 +Galatea,Neptune,0.000414444,0,4.76401e-07,0.0123999,86.7,0 +Despina,Neptune,0.000350941,0,2.9284e-07,0.0116151,125.1,0 +Ferdinand,Uranus,0.138023,0.397,0,0,256.7,79.1 +Trinculo,Uranus,0.0568524,0.219,0,0,88.5,130.1 +Caliban,Uranus,0.0483296,0.204,0,0,224.9,8.3 +Cupid,Uranus,0.000497333,0.005,0,0,160.6,13.5 +Mab,Uranus,0.000653084,0.003,0,0,348,237.9 +Perdita,Uranus,0.000510702,0.002,0,0,32.2,310.4 +Belinda,Uranus,0.000503349,0,0,0,121.3,0 +Rosalind,Uranus,0.000467253,0,0,0,79.4,0 +Juliet,Uranus,0.000430487,0.001,0,0,124.8,291.5 +Cressida,Uranus,0.000413107,0,0,0,332.8,0 +Bianca,Uranus,0.000395728,0.001,0,0,236.2,97 +Cordelia,Uranus,0.000332892,0,0,0,95,0 +Puck,Uranus,0.000574874,0,0,0,174.5,0 +Miranda,Uranus,0.000868328,0.001,1.07874e-05,0.0370115,72.4,155.6 +Ophelia,Uranus,0.000359631,0.011,0,0,280.5,344.3 +Titania,Uranus,0.00291649,0.001,0.000569223,0.123827,53.2,202 +Ariel,Uranus,0.00127609,0.001,0.000209476,0.0908649,119.8,83.3 +S2019_s01,Saturn,0.0751749,0.463,0,0,36.6,86.6 +Portia,Uranus,0.000441851,0,0,0,343.7,0 +S2007_s02,Saturn,0.111753,0.179,0,0,84.1,57.7 +S2006_s03,Saturn,0.149922,0.379,0,0,167.1,188.7 +S2004_s39,Saturn,0.155089,0.102,0,0,98,199.8 +S2004_s38,Saturn,0.148839,0.541,0,0,101.4,346.6 +S2004_s36,Saturn,0.15668,0.617,0,0,138.8,204.4 +S2004_s33,Saturn,0.157629,0.514,0,0,128.3,309.7 +S2004_s29,Saturn,0.114106,0.488,0,0,183.8,318.9 +S2004_s28,Saturn,0.146011,0.161,0,0,95.9,186.6 +S2004_s26,Saturn,0.174515,0.147,0,0,153.2,151.7 +S2004_s24,Saturn,0.156058,0.072,0,0,289.6,181 +S2004_s22,Saturn,0.137689,0.216,0,0,102.8,118.9 +S2007_s03,Saturn,0.126593,0.185,0,0,292.7,111.9 +S2004_s21,Saturn,0.154621,0.409,0,0,187.5,182 +S2004_s27,Saturn,0.132689,0.157,0,0,268.1,142.7 +S2004_s20,Saturn,0.128738,0.182,0,0,122.5,290.1 +S2004_s17,Saturn,0.130002,0.18,0,0,228.5,180.8 +S2004_s13,Saturn,0.123037,0.259,0,0,41.1,346.2 +S2004_s07,Saturn,0.140376,0.529,0,0,79.8,84 +Tarqeq,Saturn,0.120069,0.168,0,0,161,34.8 +Greip,Saturn,0.123377,0.315,0,0,314.5,152.2 +Jarnsaxa,Saturn,0.129373,0.218,0,0,198.7,237.4 +Surtur,Saturn,0.153351,0.446,0,0,136.2,303.7 +Skoll,Saturn,0.118097,0.464,0,0,45,193.1 +Psamathe,Neptune,0.312181,0.451,0,0,70.2,261.3 +Kari,Saturn,0.147683,0.476,0,0,286,163.9 +Margaret,Uranus,0.0940521,0.678,0,0,119.9,90.4 +Hyrrokkin,Saturn,0.123264,0.336,0,0,291.8,273.1 +S2004_s37,Saturn,0.106586,0.446,0,0,185.9,77.2 +Eirene,Jupiter,0.154119,0.258,0,0,329.7,94.8 +S2006_s01,Saturn,0.125537,0.141,0,0,96.6,155 +S2017_j3,Jupiter,0.139982,0.231,0,0,193.3,92.9 +Nereid,Neptune,0.036792,0.749,0,0.0266834,318,290.3 +Chaldene,Jupiter,0.153281,0.265,0,0,266.2,335 +S2011_j2,Jupiter,0.153139,0.355,0,0,284,218.7 +S2010_j1,Jupiter,0.155014,0.252,0,0,161.1,344.2 +Stephano,Uranus,0.0535034,0.218,0,0,190.2,352.6 +Eukelade,Jupiter,0.154196,0.277,0,0,203.6,283.7 +Aoede,Jupiter,0.158947,0.436,0,0,198.8,72.9 +Hegemone,Jupiter,0.156076,0.358,0,0,233.7,282.2 +S2003_j23,Jupiter,0.159289,0.313,0,0,168.5,163.2 +Enceladus,Saturn,0.00159361,0.005,1.80886e-05,0.0395699,57,119.5 +S2004_s35,Saturn,0.146827,0.237,0,0,320.2,154.2 +Kale,Jupiter,0.154097,0.262,0,0,212.7,283.6 +Pallene,Saturn,0.00141914,0.004,0,0,2,194.9 +Sponde,Jupiter,0.157377,0.322,0,0,173.8,184.9 +Calypso,Saturn,0.00197195,0.001,0,0,-0,221.6 +Euporie,Jupiter,0.128784,0.148,0,0,72.2,329.8 +Phobos,Mars,6.28351e-05,0.015,1.77791e-09,0.00173913,189.6,216.3 +Carme,Jupiter,0.154711,0.256,0,0,234,155 +Euanthe,Jupiter,0.13922,0.239,0,0,336.5,169.8 +Francisco,Uranus,0.0286301,0.139,0,0,129.5,297.3 +S2016_j2,Jupiter,0.124963,0.217,0,0,57.6,344.2 +Laomedeia,Neptune,0.157809,0.418,0,0,248.3,146 +S2017_j6,Jupiter,0.155385,0.336,0,0,150.2,100 +Thelxinoe,Jupiter,0.140216,0.228,0,0,267.9,333.4 +Aitne,Jupiter,0.154176,0.277,0,0,106,81.3 +Hermippe,Jupiter,0.141102,0.219,0,0,134.7,356.6 +Pasithee,Jupiter,0.152721,0.27,0,0,216,295.2 +Larissa,Neptune,0.000491317,0.001,6.39315e-07,0.0150683,165.5,247.3 +Sycorax,Uranus,0.0814183,0.521,0,0,146.2,211.4 +Deimos,Mars,0.000157088,0,2.41336e-10,0.00097316,205,0 +Fornjot,Saturn,0.168091,0.208,0,0,214.5,324.8 +Naiad,Neptune,0.000322197,0,2.13992e-08,0.00455188,89.7,0 +Janus,Saturn,0.00101271,0.007,3.17651e-07,0.0140009,111.7,11.1 +S2003_j18,Jupiter,0.13594,0.09,0,0,66.1,304.4 +Magaclite,Jupiter,0.158054,0.421,0,0,138.1,85.1 +Triton,Neptune,0.00237169,0,0.00358366,0.212306,63,0 +Himalia,Jupiter,0.0764757,0.16,3.80192e-07,0.0133417,66.5,328.4 +Halimede,Neptune,0.105307,0.566,0,0,173.9,113.5 +Orthosie,Jupiter,0.139715,0.299,0,0,200.7,140.1 +Leda,Jupiter,0.0745091,0.162,0,0,233.4,270.9 +Adrastea,Jupiter,0.000862312,0,3.51217e-10,0.00128708,214.5,0 +Helike,Jupiter,0.139813,0.153,0,0,44.2,118.1 +Loge,Saturn,0.15414,0.186,0,0,337.2,32.8 +Skathi,Saturn,0.104514,0.272,0,0,114.7,203.5 +Bebhionn,Saturn,0.114413,0.468,0,0,168,358.1 +Bergelmir,Saturn,0.129253,0.142,0,0,306.5,133.4 +Io,Jupiter,0.00281956,0.004,0.0149516,0.285903,330.9,49.1 +Amalthea,Jupiter,0.00121258,0.003,4.12831e-07,0.0131063,310.6,180.1 +Nix,Pluto,0.000325539,0,7.52608e-09,0.0028253,84.8,0 +Callisto,Jupiter,0.0125851,0.007,0.0180106,0.378324,87.4,43.8 +Helene,Saturn,0.0025241,0.007,1.20417e-09,0.0028253,-64.5,194.3 +Prometheus,Saturn,0.000931831,0.002,2.68681e-08,0.00676503,135.4,341.9 +Desdemona,Uranus,0.000419124,0,0,0,160.4,0 +Thyone,Jupiter,0.140229,0.233,0,0,244.4,343.5 +S2016_j1,Jupiter,0.139057,0.232,0,0,192.4,197.8 +Iapetus,Saturn,0.0238085,0.028,0.000302335,0.115257,74.8,254.5 +Europa,Jupiter,0.00448603,0.009,0.00803462,0.244985,345.4,45 +S2003_j4,Jupiter,0.153254,0.328,0,0,242.8,194.4 +Fenrir,Saturn,0.150096,0.135,0,0,131.7,121 +Eurydome,Jupiter,0.15307,0.294,0,0,286.3,340.2 +Metis,Jupiter,0.000855627,0,6.27173e-09,0.00337467,166,0 +Isonoe,Jupiter,0.153621,0.249,0,0,124.9,213.5 +Sinope,Jupiter,0.158317,0.264,0,0,167.5,96.6 +Ganymede,Jupiter,0.00715518,0.001,0.0248055,0.412996,324.8,198.3 +Lysithea,Jupiter,0.078215,0.117,0,0,331.5,47.4 +Mimas,Saturn,0.00124333,0.02,6.28049e-06,0.0311097,275.3,160.4 +Praxidike,Jupiter,0.139945,0.246,0,0,112.2,357.2 +S2004_s31,Saturn,0.116974,0.202,0,0,255.4,262.7 +S2017_j9,Jupiter,0.145515,0.2,0,0,261.5,130.7 +Aegaeon,Saturn,0.00111967,0,0,0,4.4,0 +Kallichore,Jupiter,0.153891,0.252,0,0,54.2,310.1 +Siarnaq,Saturn,0.121539,0.28,0,0,201.3,65.9 +Setebos,Uranus,0.116606,0.588,0,0,281.3,214.4 +Autonoe,Jupiter,0.159043,0.33,0,0,145.7,228.3 +Ananke,Jupiter,0.140607,0.237,0,0,259.4,56.2 +Taygete,Jupiter,0.154467,0.253,0,0,95.7,341 +Callirrhoe,Jupiter,0.159063,0.297,0,0,107.1,180.5 +Kore,Jupiter,0.161802,0.328,0,0,31.8,229.3 +Themisto,Jupiter,0.0494559,0.34,0,0,284.7,236.2 +Pasiphae,Jupiter,0.156875,0.412,0,0,277.8,264.8 +Albiorix,Saturn,0.10958,0.48,0,0,32.8,55.9 +Erinome,Jupiter,0.153965,0.276,0,0,265.5,98.2 +Kalyke,Jupiter,0.155768,0.26,0,0,256,130.3 +Mneme,Jupiter,0.13918,0.247,0,0,253.7,18.5 +S2017_j1,Jupiter,0.158724,0.328,0,0,286.5,252.2 +S2017_j8,Jupiter,0.152739,0.255,0,0,350.4,146.9 +S2003_j9,Jupiter,0.155078,0.263,0,0,354.6,199.6 +Titan,Saturn,0.0081679,0.029,0.0225234,0.404137,11.7,78.3 +Eupheme,Jupiter,0.13883,0.241,0,0,359.1,316.6 +Thalassa,Neptune,0.000334898,0,5.91801e-08,0.00627845,165.7,0 +Philophrosyne,Jupiter,0.151102,0.229,0,0,69.5,271.6 +Farbauti,Saturn,0.136299,0.241,0,0,282.8,343 +Methone,Saturn,0.00130149,0.002,0,0,0,315.5 +S2003_j19,Jupiter,0.154791,0.265,0,0,218.4,123.4 +S2017_j2,Jupiter,0.153433,0.272,0,0,293.3,137.5 +Bestla,Saturn,0.134661,0.52,0,0,238.5,81.1 +Pandia,Jupiter,0.0767457,0.179,0,0,153.9,194.3 +S2004_s34,Saturn,0.161433,0.282,0,0,34.7,346.5 +S2004_s25,Saturn,0.140049,0.519,0,0,208,268.2 +S2010_j2,Jupiter,0.138993,0.248,0,0,306.3,15.1 +S2017_j5,Jupiter,0.155124,0.257,0,0,66.9,211.7 +S2017_j7,Jupiter,0.140141,0.233,0,0,359.1,119.4 +Carpo,Jupiter,0.113921,0.416,0,0,339.8,86.6 +Ersa,Jupiter,0.076211,0.116,0,0,263.4,304.7 +Mundilfari,Saturn,0.124688,0.21,0,0,92.8,309.7 +Elara,Jupiter,0.0782919,0.211,0,0,330.7,140.1 +S2011_j1,Jupiter,0.154578,0.271,0,0,248.4,251.8 +Arche,Jupiter,0.154399,0.261,0,0,39.8,213.5 +S2003_j10,Jupiter,0.157598,0.264,0,0,286.9,227.5 +S2003_j2,Jupiter,0.140361,0.225,0,0,35.2,200.4 +S2004_s32,Saturn,0.141392,0.254,0,0,169.4,32.7 +S2003_j12,Jupiter,0.14013,0.235,0,0,201.3,277.9 +S2003_j16,Jupiter,0.139592,0.243,0,0,307.4,24.6 +Polydeuces,Saturn,0.0025241,0.019,0,0,359,94.1 +Herse,Jupiter,0.154752,0.262,0,0,141.2,101.2 +Cyllene,Jupiter,0.158122,0.419,0,0,121.3,47.8 +S2003_j24,Jupiter,0.152993,0.259,0,0,131.8,24.2 +Tethys,Saturn,0.00197195,0.001,0.000103392,0.0833621,0,335.3 +Harpalyke,Jupiter,0.139655,0.232,0,0,219.3,71.3 +Narvi,Saturn,0.12934,0.43,0,0,114.2,170 +Dione,Saturn,0.00252477,0.002,0.000183426,0.088118,212,116 +Rhea,Saturn,0.00352411,0.001,0.000386193,0.11984,31.5,44.3 +Umbriel,Uranus,0.0017781,0.004,0.00021349,0.0917752,258.3,157.5 +Thebe,Jupiter,0.00148331,0.018,7.56371e-08,0.00773819,182.1,26.6 +Pandora,Saturn,0.000947206,0.004,2.32305e-08,0.00637263,123.9,217.9 +S2004_s23,Saturn,0.143431,0.437,0,0,65.1,22.8 +Aegir,Saturn,0.138712,0.252,0,0,26,242.7 +Hyperion,Saturn,0.00990322,0.105,9.29446e-07,0.0211898,122.9,214 +Prospero,Uranus,0.108738,0.439,0,0,125.3,251.9 +S2004_s30,Saturn,0.138444,0.087,0,0,336.5,269.3 +Phoebe,Saturn,0.0864277,0.164,1.3918e-06,0.0167164,308,240.3 +Telesto,Saturn,0.00197195,0.001,0,0,360,66.2 +S2004_s12,Saturn,0.13293,0.327,0,0,1.6,87.1 +Epimetheus,Saturn,0.00101205,0.02,8.81555e-08,0.00913514,197.2,96.3 +Oberon,Uranus,0.00389979,0.001,0.000515035,0.11951,139.7,182.4 +Atlas,Saturn,0.000920468,0.001,9.28217e-10,0.00237011,289.1,82.3 +Pan,Saturn,0.000893061,0,7.02434e-10,0.00219746,146.6,0 +Daphnis,Saturn,0.000912446,0,0,0,153.6,0 +Anthe,Saturn,0.00132422,0.002,0,0,351.4,293.4 +Dia,Jupiter,0.081955,0.232,0,0,309.6,176.8 +Ymir,Saturn,0.154601,0.334,0,0,228.7,21.4 +Kerberos,Pluto,0.000386369,0,2.75956e-09,0.000941767,303.5,0 +Kiviuq,Saturn,0.0758233,0.212,0,0,171,90.6 +Ijiraq,Saturn,0.0762578,0.272,0,0,17.3,92.9 +Paaliaq,Saturn,0.101378,0.341,0,0,321.3,238.7 +Tarvos,Saturn,0.121947,0.538,0,0,265.8,274.1 +Iocaste,Jupiter,0.140822,0.227,0,0,215.5,244.7 +Suttungr,Saturn,0.130136,0.114,0,0,321.1,34.3 +Erriapus,Saturn,0.117662,0.472,0,0,294.8,282.5 +Thrymr,Saturn,0.136486,0.466,0,0,30.1,125.4 +Styx,Pluto,0.000283426,0,0,0.000816198,180.9,0 +Hati,Saturn,0.132809,0.371,0,0,163.6,21.3 diff --git a/data/sol_asteroids.csv b/data/sol_asteroids.csv new file mode 100644 index 0000000..ac5b2d3 --- /dev/null +++ b/data/sol_asteroids.csv @@ -0,0 +1,1915 @@ +Ceres,2.766,0.0785,939.4,291.38,73.64,1 +Pallas,2.771,0.2300,513,272.48,310.70,2 +Juno,2.669,0.2569,246.596,261.30,247.94,3 +Vesta,2.361,0.0882,525.4,7.03,151.09,4 +Astraea,2.575,0.1901,106.699,160.98,358.74,5 +Hebe,2.426,0.2031,185.18,347.50,239.51,6 +Iris,2.387,0.2295,199.83,47.64,145.34,7 +Flora,2.202,0.1561,147.491,136.26,285.55,8 +Metis,2.385,0.1236,190,184.56,6.16,9 +Hygiea,3.142,0.1116,407.12,328.90,312.49,10 +Parthenope,2.453,0.0995,142.887,175.42,195.60,11 +Victoria,2.334,0.2207,115.087,49.75,69.67,12 +Egeria,2.577,0.0854,202.636,66.24,80.15,13 +Irene,2.586,0.1659,152,42.04,97.71,14 +Eunomia,2.644,0.1866,231.689,152.50,98.63,15 +Psyche,2.924,0.1339,226,125.13,229.22,16 +Thetis,2.471,0.1329,84.899,197.57,135.81,17 +Melpomene,2.296,0.2179,139.594,190.37,228.12,18 +Fortuna,2.443,0.1570,200,95.09,182.47,19 +Massalia,2.409,0.1431,135.680,20.51,257.56,20 +Lutetia,2.435,0.1635,95.76,243.38,250.16,21 +Kalliope,2.91,0.0984,167.536,33.48,357.60,22 +Thalia,2.63,0.2327,107.53,207.14,60.99,23 +Themis,3.142,0.1224,198,171.96,107.60,24 +Phocaea,2.399,0.2550,61.054,78.04,90.25,25 +Proserpina,2.655,0.0894,94.80,333.30,193.66,26 +Euterpe,2.348,0.1721,96,249.69,356.26,27 +Bellona,2.775,0.1515,120.90,126.85,343.83,28 +Amphitrite,2.554,0.0734,189.559,165.88,63.09,29 +Urania,2.366,0.1277,92.787,300.48,87.00,30 +Euphrosyne,3.164,0.2179,267.080,262.86,61.56,31 +Pomona,2.587,0.0817,80.76,269.62,338.68,32 +Polyhymnia,2.875,0.3317,52.929,184.13,338.49,33 +Circe,2.687,0.1066,132.992,351.03,330.22,34 +Leukothea,2.993,0.2248,103.055,45.45,213.46,35 +Atalante,2.747,0.3056,132.842,156.20,47.78,36 +Fides,2.641,0.1759,108.35,211.33,62.62,37 +Leda,2.742,0.1531,92.255,222.44,169.20,38 +Laetitia,2.77,0.1117,179.484,155.00,209.54,39 +Harmonia,2.267,0.0465,111.251,37.30,268.65,40 +Daphne,2.761,0.2746,205.495,349.11,45.92,41 +Isis,2.442,0.2227,110.997,101.85,237.18,42 +Ariadne,2.203,0.1688,71.340,79.28,16.31,43 +Nysa,2.423,0.1489,70.64,342.99,344.19,44 +Eugenia,2.721,0.0836,202.327,258.63,87.66,45 +Hestia,2.525,0.1728,131.471,315.63,177.35,46 +Aglaja,2.882,0.1301,168.174,253.30,315.06,47 +Doris,3.115,0.0706,216.473,250.21,251.98,48 +Pales,3.098,0.2215,166.252,60.40,113.11,49 +Virginia,2.65,0.2852,84.074,27.20,199.90,50 +Nemausa,2.366,0.0676,138.159,7.67,1.91,51 +Europa,3.095,0.1108,303.918,58.66,343.14,52 +Kalypso,2.619,0.2025,97.262,295.87,314.09,53 +Alexandra,2.712,0.1970,160.120,238.89,345.18,54 +Pandora,2.759,0.1438,84.794,215.91,5.42,55 +Melete,2.596,0.2380,121.333,122.30,104.93,56 +Mnemosyne,3.157,0.1099,112.59,319.48,210.36,57 +Concordia,2.702,0.0436,106.517,157.83,33.45,58 +Elpis,2.713,0.1173,165.119,20.11,210.67,59 +Echo,2.392,0.1850,43.218,114.90,271.10,60 +Danae,2.984,0.1648,85.937,103.20,12.66,61 +Erato,3.13,0.1679,106.921,56.90,277.36,62 +Ausonia,2.396,0.1274,116.044,45.15,296.22,63 +Angelina,2.681,0.1256,58.292,260.96,180.67,64 +Cybele,3.433,0.1141,237.26,55.63,103.43,65 +Maja,2.645,0.1733,71.82,248.43,43.75,66 +Asia,2.422,0.1848,56.309,180.09,107.02,67 +Leto,2.783,0.1850,122.509,113.81,304.61,68 +Hesperia,2.975,0.1702,138.13,133.30,288.91,69 +Panopaea,2.615,0.1806,127.911,303.07,255.66,70 +Niobe,2.757,0.1749,83.42,119.07,267.19,71 +Feronia,2.266,0.1205,74.966,295.40,103.13,72 +Klytia,2.664,0.0418,44.590,20.26,55.41,73 +Galatea,2.782,0.2361,118.71,127.08,174.66,74 +Eurydike,2.675,0.3036,62.377,187.07,339.44,75 +Freia,3.414,0.1663,145.423,80.60,252.14,76 +Frigga,2.668,0.1330,61.390,149.59,61.67,77 +Diana,2.622,0.2058,120.60,190.69,152.85,78 +Eurynome,2.445,0.1903,63.479,126.14,201.54,79 +Sappho,2.296,0.2002,68.563,20.84,139.49,80 +Terpsichore,2.852,0.2114,117.727,191.82,51.53,81 +Alkmene,2.764,0.2205,57.621,30.43,111.05,82 +Beatrix,2.434,0.0812,110.503,128.78,169.32,83 +Klio,2.362,0.2364,79.16,18.91,15.04,84 +Io,2.652,0.1942,154.79,89.11,122.82,85 +Semele,3.106,0.2158,109.929,171.86,308.87,86 +Sylvia,3.48,0.0940,253.051,244.12,263.93,87 +Thisbe,2.769,0.1618,232,262.59,36.53,88 +Julia,2.55,0.1847,145.483,19.81,45.04,89 +Antiope,3.147,0.1668,115.974,321.32,245.17,90 +Aegina,2.59,0.1069,103.402,43.15,74.39,91 +Undina,3.191,0.1060,126.42,353.89,238.23,92 +Minerva,2.755,0.1389,154.155,332.17,275.17,93 +Aurora,3.158,0.0947,204.89,124.73,60.22,94 +Arethusa,3.063,0.1532,147.969,258.17,153.66,95 +Aegle,3.049,0.1414,177.774,289.86,208.23,96 +Klotho,2.668,0.2577,100.717,177.22,268.57,97 +Ianthe,2.688,0.1875,132.788,349.69,158.49,98 +Dike,2.665,0.1961,67.354,110.80,195.74,99 +Hekate,3.087,0.1691,85.734,68.70,183.81,100 +Helena,2.584,0.1412,65.84,350.74,348.31,101 +Miriam,2.663,0.2511,82.595,117.99,147.16,102 +Hera,2.703,0.0792,83.908,216.40,189.04,103 +Klymene,3.147,0.1613,136.553,95.05,31.70,104 +Artemis,2.374,0.1776,94.864,75.70,57.27,105 +Dione,3.18,0.1593,207.869,37.30,331.31,106 +Camilla,3.488,0.0650,210.370,118.56,305.68,107 +Hecuba,3.248,0.0574,75.498,139.01,210.23,108 +Felicitas,2.695,0.2995,82.588,114.65,57.59,109 +Lydia,2.732,0.0802,86.09,66.29,282.00,110 +Ate,2.593,0.1025,126.344,300.55,168.17,111 +Iphigenia,2.433,0.1284,69.818,328.54,17.33,112 +Amalthea,2.376,0.0862,50.137,45.18,78.63,113 +Kassandra,2.676,0.1380,94.178,286.43,352.75,114 +Thyra,2.38,0.1932,79.83,285.60,96.87,115 +Sirona,2.766,0.1415,71.70,76.63,94.27,116 +Lomia,2.991,0.0241,208.974,339.88,50.93,117 +Peitho,2.436,0.1646,40.211,209.55,33.18,118 +Althaea,2.581,0.0813,57.30,228.52,171.45,119 +Lachesis,3.117,0.0515,155.132,52.70,234.25,120 +Hermione,3.454,0.1263,209.00,13.21,296.80,121 +Gerda,3.223,0.0307,70.676,144.69,321.05,122 +Brunhild,2.694,0.1209,45.209,182.99,125.45,123 +Alkeste,2.632,0.0766,88.648,84.63,62.61,124 +Liberatrix,2.744,0.0783,48.418,20.67,110.34,125 +Velleda,2.439,0.1055,44.82,100.19,327.99,126 +Johanna,2.754,0.0666,122,140.36,93.12,127 +Nemesis,2.749,0.1281,162.515,288.58,303.46,128 +Antigone,2.867,0.2130,113,143.16,110.83,129 +Elektra,3.127,0.2093,180.652,124.07,237.62,130 +Vala,2.433,0.0675,31.337,88.46,161.23,131 +Aethra,2.61,0.3889,42.87,146.28,255.34,132 +Cyrene,3.064,0.1348,72.175,323.13,290.25,133 +Sophrosyne,2.563,0.1146,108,349.52,85.34,134 +Hertha,2.429,0.2069,79.24,238.35,340.31,135 +Austria,2.287,0.0847,36.893,142.31,132.55,136 +Meliboea,3.126,0.2117,128.678,217.38,107.53,137 +Tolosa,2.449,0.1623,52.905,142.97,260.57,138 +Juewa,2.783,0.1739,151.116,124.98,165.82,139 +Siwa,2.734,0.2141,109.79,276.34,196.95,140 +Lumen,2.665,0.2136,117.916,25.99,57.64,141 +Polana,2.419,0.1346,54.812,305.32,291.72,142 +Adria,2.762,0.0736,95.377,296.18,252.15,143 +Vibilia,2.654,0.2354,142.38,235.13,294.65,144 +Adeona,2.671,0.1464,127.783,323.38,45.25,145 +Lucina,2.719,0.0665,160.310,279.42,145.54,146 +Protogeneia,3.135,0.0231,132.93,86.65,101.77,147 +Gallia,2.77,0.1879,97.75,217.82,252.66,148 +Nuwa,2.985,0.1236,119.128,158.16,153.75,150 +Abundantia,2.591,0.0353,39.037,251.83,133.36,151 +Atala,3.14,0.0815,58.964,47.70,59.00,152 +Hilda,3.977,0.1400,170.63,299.21,39.33,153 +Bertha,3.198,0.0765,192.611,108.35,161.39,154 +Scylla,2.762,0.2727,39.605,303.47,46.59,155 +Xanthippe,2.728,0.2264,143.346,340.51,338.28,156 +Koronis,2.869,0.0526,39.025,56.81,146.61,158 +Aemilia,3.108,0.1045,125.236,214.84,333.15,159 +Una,2.726,0.0673,81.24,223.32,51.75,160 +Athor,2.38,0.1371,40.992,166.14,294.79,161 +Laurentia,3.016,0.1819,97.021,316.79,115.78,162 +Erigone,2.366,0.1922,81.579,100.94,298.65,163 +Eva,2.631,0.3473,100.254,321.19,284.04,164 +Loreley,3.123,0.0845,180.083,124.97,345.04,165 +Rhodope,2.687,0.2115,52.393,323.61,263.98,166 +Urda,2.852,0.0378,39.935,90.86,128.67,167 +Sibylla,3.376,0.0745,145.366,127.68,175.74,168 +Zelia,2.358,0.1309,37.517,74.23,334.68,169 +Maria,2.554,0.0629,33.136,212.51,157.94,170 +Ophelia,3.132,0.1321,130.808,8.24,55.72,171 +Baucis,2.38,0.1149,62.43,351.96,359.66,172 +Ino,2.741,0.2096,125.821,251.09,228.84,173 +Phaedra,2.861,0.1410,64.849,17.29,289.71,174 +Andromache,3.185,0.2330,94.532,23.32,319.79,175 +Iduna,3.182,0.1714,106.976,151.93,188.60,176 +Irma,2.772,0.2340,69.049,108.42,39.44,177 +Belisana,2.461,0.0424,35.81,271.53,211.55,178 +Klytaemnestra,2.973,0.1101,69.946,103.14,104.03,179 +Eucharis,3.127,0.2073,115.383,29.01,318.88,181 +Elsa,2.415,0.1869,39.520,184.66,310.76,182 +Istria,2.794,0.3483,32.927,357.52,263.95,183 +Dejopeja,3.187,0.0654,62.483,104.59,210.73,184 +Eunike,2.738,0.1274,160.464,43.00,223.58,185 +Celuta,2.362,0.1499,49.99,98.60,315.42,186 +Lamberta,2.729,0.2408,147.294,295.27,196.75,187 +Menippe,2.761,0.1796,35.752,56.52,69.91,188 +Phthia,2.451,0.0358,38.490,130.03,168.86,189 +Ismene,3.991,0.1676,159,23.14,271.06,190 +Kolga,2.895,0.0878,94.536,7.35,226.07,191 +Nausikaa,2.402,0.2458,98.776,262.76,30.69,192 +Ambrosia,2.6,0.2975,26.302,80.29,82.52,193 +Prokne,2.616,0.2377,161.667,148.50,163.11,194 +Eurykleia,2.876,0.0430,93.109,158.78,117.88,195 +Philomela,3.115,0.0154,144.626,268.38,202.45,196 +Arete,2.738,0.1636,31.729,95.92,245.88,197 +Ampella,2.458,0.2277,54.323,281.65,89.22,198 +Byblis,3.167,0.1819,76.129,76.50,180.06,199 +Dynamene,2.738,0.1325,128.301,83.90,86.87,200 +Penelope,2.68,0.1792,85.877,169.01,180.91,201 +Chryseis,3.071,0.1041,86.15,19.02,359.94,202 +Pompeja,2.738,0.0592,124.592,120.01,59.95,203 +Kallisto,2.671,0.1737,48.566,322.11,55.42,204 +Martha,2.776,0.0368,76.983,265.85,175.81,205 +Hersilia,2.741,0.0392,113,60.34,302.77,206 +Hedda,2.284,0.0297,57.880,246.44,192.62,207 +Lacrimosa,2.895,0.0105,40.056,237.11,121.40,208 +Dido,3.148,0.0556,179.008,303.32,249.74,209 +Isabella,2.72,0.1242,86.65,232.83,14.65,210 +Isolda,3.051,0.1571,141.125,272.16,173.00,211 +Medea,3.116,0.1026,136.12,22.19,105.10,212 +Lilaea,2.754,0.1444,82.096,270.92,162.39,213 +Oenone,2.767,0.0339,35.210,157.84,317.42,215 +Kleopatra,2.793,0.2514,122,282.10,179.89,216 +Eudora,2.867,0.3107,65.392,35.37,155.21,217 +Bianca,2.668,0.1169,60.62,263.29,62.52,218 +Thusnelda,2.354,0.2233,37.674,64.00,142.63,219 +Stephania,2.348,0.2577,31.738,317.05,78.70,220 +Eos,3.01,0.1023,95.469,85.16,192.33,221 +Lucia,3.141,0.1309,55.350,342.35,181.67,222 +Rosa,3.09,0.1197,79.806,307.84,65.37,223 +Oceana,2.645,0.0451,58.236,100.66,283.21,224 +Henrietta,3.392,0.2631,95.934,115.28,103.81,225 +Weringia,2.711,0.2042,31.494,96.38,153.90,226 +Philosophia,3.165,0.1912,123.891,60.91,267.67,227 +Adelinda,3.424,0.1377,105.912,31.37,309.30,229 +Athamantis,2.382,0.0621,111.332,291.76,139.69,230 +Vindobona,2.925,0.1523,73.545,46.33,269.25,231 +Russia,2.553,0.1745,54.730,337.37,51.89,232 +Asterope,2.66,0.0996,99.672,231.65,126.36,233 +Barbara,2.386,0.2451,45.476,192.04,192.29,234 +Carolina,2.882,0.0614,57.517,222.40,208.00,235 +Honoria,2.799,0.1912,77.708,356.32,174.32,236 +Coelestina,2.762,0.0710,41.08,321.10,200.56,237 +Hypatia,2.905,0.0904,155.659,207.96,210.57,238 +Adrastea,2.965,0.2360,37.609,259.76,209.90,239 +Vanadis,2.664,0.2083,87.928,152.73,300.93,240 +Germania,3.047,0.1038,168.90,288.28,80.58,241 +Kriemhild,2.862,0.1219,40.802,38.73,279.12,242 +Ida,2.862,0.0438,32,83.13,113.94,243 +Vera,3.098,0.1972,75.949,119.88,331.68,245 +Asporina,2.695,0.1090,50.891,258.71,96.19,246 +Eukrate,2.741,0.2457,130.935,149.73,55.33,247 +Lameia,2.471,0.0661,50.120,50.89,11.68,248 +Ilse,2.377,0.2172,34.83,42.08,42.07,249 +Bettina,3.145,0.1358,120.995,51.14,75.87,250 +Sophia,3.099,0.0937,27.495,298.52,288.52,251 +Clementina,3.162,0.0664,65.344,117.95,159.63,252 +Mathilde,2.648,0.2635,52.8,267.13,157.82,253 +Oppavia,2.747,0.0790,56.939,335.38,155.02,255 +Walpurga,2.999,0.0653,66.634,10.53,47.51,256 +Silesia,3.118,0.1119,72.66,24.03,31.65,257 +Tyche,2.614,0.2049,64.78,263.12,155.67,258 +Aletheia,3.131,0.1299,174.318,138.85,166.89,259 +Huberta,3.447,0.1082,101.539,59.66,179.92,260 +Prymno,2.331,0.0896,50.011,228.42,66.78,261 +Libussa,2.8,0.1368,62.969,317.24,339.95,264 +Aline,2.806,0.1541,109.494,111.21,151.78,266 +Tirza,2.775,0.0992,55.998,33.53,197.11,267 +Adorea,3.094,0.1368,144.585,305.94,68.44,268 +Justitia,2.616,0.2129,50.728,325.22,119.73,269 +Anahita,2.198,0.1503,51.400,104.05,80.52,270 +Penthesilea,3.003,0.1044,65.901,263.36,57.55,271 +Antonia,2.778,0.0287,26.870,8.89,68.88,272 +Atropos,2.395,0.1599,29.768,299.54,121.18,273 +Philagoria,3.043,0.1188,27.307,55.99,119.97,274 +Sapientia,2.771,0.1635,103,9.00,39.46,275 +Adelheid,3.12,0.0657,114.723,203.31,265.10,276 +Elvira,2.885,0.0927,30.422,309.73,136.64,277 +Paulina,2.759,0.1317,32.773,114.68,140.52,278 +Thule,4.265,0.0437,126.59,300.08,26.66,279 +Philia,2.942,0.1103,45.69,84.07,89.27,280 +Clorinde,2.339,0.0812,39.03,107.38,296.87,282 +Emma,3.05,0.1444,132.385,135.64,55.49,283 +Amalia,2.359,0.2217,52.95,184.31,58.01,284 +Regina,3.088,0.2045,47.156,141.11,14.42,285 +Iclea,3.192,0.0243,94.30,38.39,209.61,286 +Nephthys,2.353,0.0227,59.615,313.18,119.75,287 +Glauke,2.759,0.2058,28.981,246.35,84.55,288 +Nenetta,2.877,0.2016,37.586,146.83,190.55,289 +Ludovica,2.53,0.0330,30.864,157.65,286.11,292 +Brasilia,2.862,0.1051,57.486,155.20,87.08,293 +Felicia,3.157,0.2332,51.865,205.50,186.19,294 +Theresia,2.797,0.1675,28.340,328.05,148.21,295 +Caecilia,3.166,0.1397,39.48,107.54,353.51,297 +Geraldina,3.205,0.0579,67.373,297.91,324.10,300 +Bavaria,2.725,0.0666,53.042,195.76,124.01,301 +Clarissa,2.406,0.1100,38.53,21.64,55.03,302 +Josephina,3.122,0.0565,124.923,351.31,67.04,303 +Olga,2.404,0.2216,65.990,232.67,172.46,304 +Gordonia,3.091,0.1961,47.739,46.55,260.70,305 +Unitas,2.358,0.1507,47.200,273.31,168.05,306 +Nike,2.905,0.1438,61.313,208.97,324.19,307 +Polyxo,2.749,0.0395,128.578,146.00,112.42,308 +Fraternitas,2.665,0.1137,41.075,282.63,311.08,309 +Margarita,2.76,0.1164,33.708,206.93,325.09,310 +Claudia,2.896,0.0053,26.300,268.20,82.92,311 +Pierretta,2.781,0.1605,46.191,107.52,262.32,312 +Chaldaea,2.375,0.1821,71.183,80.99,315.89,313 +Rosalia,3.159,0.1714,60.689,106.66,191.64,314 +Goberta,3.185,0.1282,56.067,300.24,316.99,316 +Magdalena,3.193,0.0847,85,144.91,295.61,318 +Leona,3.408,0.2160,49.943,273.14,227.79,319 +Florentina,2.884,0.0472,27.974,165.22,35.33,321 +Phaeo,2.782,0.2448,69.855,48.21,114.69,322 +Brucia,2.382,0.2994,27.714,175.03,291.54,323 +Bamberga,2.681,0.3414,220.691,314.55,44.21,324 +Heidelberga,3.215,0.1512,75.72,347.27,70.60,325 +Tamara,2.318,0.1899,93.00,225.02,238.52,326 +Columbia,2.776,0.0610,30.291,277.72,307.88,327 +Gudrun,3.107,0.1069,145.680,321.43,107.18,328 +Svea,2.477,0.0243,81.057,68.05,56.13,329 +Etheridgea,3.026,0.0961,74.92,102.41,333.78,331 +Siri,2.773,0.0883,40.37,251.35,297.91,332 +Badenia,3.133,0.1599,72.199,126.57,22.96,333 +Chicago,3.889,0.0242,198.770,4.30,151.16,334 +Roberta,2.475,0.1727,97.109,141.82,139.83,335 +Lacadiera,2.252,0.0956,63.356,187.74,31.01,336 +Devosa,2.383,0.1362,64.549,344.57,99.43,337 +Budrosa,2.913,0.0188,50.506,340.93,108.53,338 +Dorothea,3.01,0.0986,44.329,288.34,164.68,339 +Eduarda,2.747,0.1167,28.025,95.11,43.13,340 +Endymion,2.568,0.1299,64.266,94.30,225.00,342 +Desiderata,2.597,0.3140,124.181,52.01,237.60,344 +Tercidina,2.325,0.0618,90.243,123.68,231.15,345 +Hermentaria,2.795,0.1027,86.447,250.51,291.91,346 +Pariana,2.612,0.1657,48.615,115.25,86.26,347 +May,2.97,0.0711,82.82,46.87,13.59,348 +Dembowska,2.926,0.0905,139.77,342.96,344.48,349 +Ornamenta,3.108,0.1599,128.729,177.15,337.79,350 +Yrsa,2.765,0.1558,39.720,347.99,31.81,351 +Gisela,2.195,0.1498,26.744,320.98,144.40,352 +Eleonora,2.803,0.1121,148.970,183.83,6.39,354 +Liguria,2.756,0.2409,145.503,98.73,79.38,356 +Ninina,3.152,0.0772,124.107,135.43,255.54,357 +Apollonia,2.875,0.1531,90.116,224.10,252.78,358 +Georgia,2.728,0.1570,43.89,42.15,337.85,359 +Carlova,3.003,0.1734,129.125,6.91,289.86,360 +Bononia,3.965,0.2108,154.334,219.72,68.34,361 +Havnia,2.579,0.0443,98,156.67,31.45,362 +Padua,2.746,0.0719,97,265.82,296.32,363 +Isara,2.221,0.1487,25.901,78.37,313.13,364 +Corduba,2.804,0.1571,86.773,294.95,215.71,365 +Vincentina,3.144,0.0566,86.368,275.69,333.58,366 +Haidea,3.073,0.2013,69.277,275.36,95.42,368 +Aeria,2.649,0.0970,73.767,210.10,269.79,369 +Modestia,2.324,0.0909,38.093,46.04,68.22,370 +Bohemia,2.727,0.0635,52.976,222.47,342.16,371 +Palma,3.163,0.2546,173.642,268.38,115.23,372 +Melusina,3.122,0.1380,98.695,123.96,348.91,373 +Burgundia,2.779,0.0790,44.67,359.99,25.77,374 +Ursula,3.125,0.1036,216,115.26,341.44,375 +Geometria,2.288,0.1727,35.465,112.53,316.76,376 +Campania,2.69,0.0754,90.346,0.02,196.08,377 +Holmia,2.776,0.1308,27.831,278.77,157.26,378 +Huenna,3.143,0.1799,84.787,119.24,180.72,379 +Fiducia,2.679,0.1128,67.508,200.90,240.01,380 +Myrrha,3.223,0.0899,127.639,330.07,144.02,381 +Dodona,3.121,0.1709,65.209,3.36,270.39,382 +Janina,3.14,0.1681,43.482,68.38,324.56,383 +Burdigala,2.655,0.1464,34.435,270.29,34.64,384 +Ilmatar,2.848,0.1256,85.837,214.95,189.06,385 +Siegena,2.899,0.1690,165.01,105.03,220.78,386 +Aquitania,2.74,0.2349,100.51,318.15,157.45,387 +Charybdis,3.007,0.0663,125.754,31.93,330.44,388 +Industria,2.608,0.0665,74.378,96.86,265.07,389 +Alma,2.653,0.1311,25.688,231.91,191.56,390 +Wilhelmina,2.884,0.1391,60.750,5.30,173.45,392 +Lampetia,2.781,0.3302,116.191,238.62,90.82,393 +Arduina,2.762,0.2275,29.970,299.82,271.31,394 +Delia,2.785,0.0846,44.189,277.52,11.13,395 +Aeolia,2.74,0.1601,39.242,156.63,21.42,396 +Vienna,2.634,0.2482,49.032,303.26,140.07,397 +Admete,2.738,0.2237,49.771,27.22,160.54,398 +Persephone,3.05,0.0763,39.566,266.12,192.98,399 +Ducrosa,3.128,0.1158,36.001,291.95,237.30,400 +Ottilia,3.346,0.0317,87.803,128.63,300.89,401 +Chloe,2.559,0.1123,55.421,25.20,17.34,402 +Cyane,2.81,0.0981,53.574,49.80,254.52,403 +Arsinoe,2.593,0.2003,94.970,153.02,120.66,404 +Thia,2.584,0.2434,108.894,241.86,308.72,405 +Erna,2.918,0.1783,46.266,125.08,37.65,406 +Arachne,2.624,0.0705,95.07,258.24,82.42,407 +Fama,3.166,0.1455,35.620,138.88,108.57,408 +Aspasia,2.575,0.0719,171.012,17.36,353.57,409 +Chloris,2.724,0.2414,118.929,204.53,172.82,410 +Xanthe,2.935,0.1151,76.53,202.67,181.32,411 +Elisabetha,2.762,0.0419,96.056,70.22,91.86,412 +Edburga,2.585,0.3416,34.242,197.54,252.88,413 +Liriope,3.507,0.0732,88.760,121.14,318.42,414 +Palatia,2.793,0.3000,83.560,54.92,299.09,415 +Vaticana,2.792,0.2176,85.47,330.38,198.29,416 +Suevia,2.8,0.1356,54.874,325.70,348.57,417 +Alemannia,2.594,0.1195,40.330,345.64,125.92,418 +Aurelia,2.598,0.2514,148.701,48.45,44.65,419 +Bertholda,3.414,0.0290,138.699,173.60,234.85,420 +Diotima,3.069,0.0351,175.859,244.94,199.40,423 +Gratia,2.774,0.1089,102.565,54.71,333.83,424 +Cornelia,2.886,0.0589,67.925,107.01,121.97,425 +Hippo,2.888,0.1058,137.562,289.83,221.81,426 +Galene,2.971,0.1198,32.193,116.14,11.19,427 +Lotis,2.607,0.1236,69.62,196.03,169.17,429 +Hybris,2.85,0.2505,31.702,323.44,179.25,430 +Nephele,3.14,0.1706,101.900,223.72,217.20,431 +Pythia,2.369,0.1462,46.90,185.14,173.87,432 +Ella,2.449,0.1551,34.792,60.11,333.25,435 +Patricia,3.201,0.0694,58.609,166.35,41.05,436 +Zeuxo,2.554,0.0682,58.871,207.46,210.38,438 +Ohio,3.133,0.0663,70.421,27.94,244.49,439 +Bathilde,2.807,0.0812,65.131,46.08,202.95,441 +Eichsfeldia,2.345,0.0703,62.171,15.28,84.56,442 +Photographica,2.215,0.0405,25.504,87.55,348.68,443 +Gyptis,2.77,0.1743,159.331,80.00,154.56,444 +Edna,3.198,0.1975,87.812,174.48,81.66,445 +Aeternitas,2.788,0.1256,53.562,147.56,279.06,446 +Valentine,2.984,0.0452,85.224,241.78,321.41,447 +Natalie,3.135,0.1883,50.534,24.11,293.55,448 +Hamburga,2.552,0.1728,85.59,254.28,48.54,449 +Brigitta,3.019,0.0976,37.038,138.67,359.11,450 +Patientia,3.067,0.0717,253.900,288.40,335.86,451 +Mathesis,2.626,0.1114,81.743,200.67,177.46,454 +Bruchsalia,2.655,0.2951,88.792,315.18,273.52,455 +Abnoba,2.789,0.1789,37.713,64.47,7.17,456 +Hercynia,2.994,0.2424,36.698,122.52,277.15,458 +Signe,2.619,0.2112,25.784,194.64,19.49,459 +Saskia,3.116,0.1449,43.603,318.62,308.56,461 +Eriphyla,2.876,0.0887,34.274,346.93,250.07,462 +Megaira,2.801,0.2050,77.056,19.80,257.86,464 +Alekto,3.093,0.2054,73.34,10.09,284.11,465 +Tisiphone,3.365,0.0936,95.495,155.70,253.47,466 +Laura,2.945,0.1064,39.471,32.62,94.02,467 +Lina,3.133,0.1963,60.238,24.93,332.24,468 +Argentina,3.193,0.1583,133.718,138.29,211.60,469 +Kilia,2.406,0.0947,27.750,127.04,47.81,470 +Papagena,2.89,0.2287,148.128,86.07,315.63,471 +Roma,2.544,0.0950,50.278,138.93,296.51,472 +Prudentia,2.453,0.2109,40.972,9.64,156.13,474 +Hedwig,2.65,0.0730,138.493,13.08,1.40,476 +Tergeste,3.021,0.0806,80.738,250.00,242.21,478 +Caprera,2.721,0.2189,60.088,281.24,269.49,479 +Hansa,2.643,0.0462,56.22,185.05,213.25,480 +Emita,2.739,0.1579,101.829,216.07,349.42,481 +Petrina,3,0.0968,45.751,305.57,87.73,482 +Seppina,3.426,0.0511,66.858,158.08,162.99,483 +Pittsburghia,2.667,0.0579,30.060,79.04,189.55,484 +Genua,2.748,0.1918,63.88,190.98,272.21,485 +Venetia,2.67,0.0861,59.046,54.33,281.16,487 +Kreusa,3.182,0.1570,168.117,184.03,74.26,488 +Comacina,3.151,0.0479,139.39,277.69,9.22,489 +Veritas,3.172,0.0897,118.803,21.14,193.25,490 +Carina,3.195,0.0864,91.176,283.29,231.63,491 +Gismonda,3.112,0.1791,53.418,266.15,296.82,492 +Griseldis,3.115,0.1766,41.550,191.78,46.81,493 +Virtus,2.984,0.0647,100.786,167.95,215.66,494 +Eulalia,2.488,0.1289,37.287,146.99,207.86,495 +Iva,2.849,0.3013,40.932,291.81,3.54,497 +Tokio,2.651,0.2232,81.83,274.30,241.90,498 +Venusia,4.011,0.2169,77.328,35.20,174.82,499 +Selinur,2.614,0.1440,40.828,149.39,74.94,500 +Urhixidur,3.164,0.1416,74.457,190.02,356.28,501 +Evelyn,2.722,0.1758,81.68,177.44,41.66,503 +Cora,2.723,0.2153,30.438,181.40,248.36,504 +Cava,2.688,0.2430,115,308.02,336.88,505 +Marion,3.039,0.1470,105.94,190.61,145.68,506 +Laodica,3.153,0.1013,45.170,181.45,100.43,507 +Princetonia,3.16,0.0077,117.241,3.93,206.85,508 +Iolanda,3.061,0.0964,51.892,258.03,157.46,509 +Mabella,2.611,0.1909,60.450,17.16,91.19,510 +Davida,3.162,0.1884,270.327,149.38,337.16,511 +Centesima,3.013,0.0847,48.805,164.15,225.78,513 +Armida,3.046,0.0374,120.093,59.57,110.78,514 +Athalia,3.122,0.1762,41.190,104.65,300.27,515 +Amherstia,2.681,0.2734,65.144,114.93,258.14,516 +Edith,3.155,0.1794,111.890,32.08,143.55,517 +Sylvania,2.792,0.1831,40.078,166.25,302.76,519 +Franziska,3.003,0.1105,25.261,234.99,21.11,520 +Brixia,2.743,0.2783,107.227,23.05,316.03,521 +Helga,3.628,0.0867,101.22,123.54,248.73,522 +Ada,2.967,0.1790,31.89,56.77,189.93,523 +Fidelio,2.637,0.1280,65.527,297.23,79.23,524 +Jena,3.125,0.1320,44.840,171.91,357.69,526 +Euryanthe,2.725,0.1509,52.627,322.64,204.14,527 +Rezia,3.397,0.0219,91.966,79.40,350.85,528 +Preziosa,3.021,0.0947,32.01,316.82,331.99,529 +Turandot,3.187,0.2182,84.85,79.39,199.46,530 +Herculina,2.771,0.1788,167.791,197.17,76.63,532 +Sara,2.981,0.0445,30.819,316.81,32.39,533 +Nassovia,2.883,0.0592,32.333,146.47,338.36,534 +Montague,2.569,0.0253,79.299,279.77,68.53,535 +Merapi,3.496,0.0874,147.066,243.65,295.73,536 +Pauly,3.073,0.2291,40.732,302.02,187.59,537 +Friederike,3.156,0.1708,70.640,266.65,227.56,538 +Pamina,2.737,0.2140,68.356,291.67,97.42,539 +Deborah,2.814,0.0497,60.147,3.33,359.43,541 +Susanna,2.905,0.1422,42.117,234.56,216.84,542 +Charlotte,3.064,0.1531,45.613,300.84,108.44,543 +Jetta,2.591,0.1532,27.169,118.19,343.07,544 +Messalina,3.201,0.1700,112.631,288.83,331.18,545 +Herodias,2.597,0.1153,65.945,258.84,110.07,546 +Praxedis,2.775,0.2353,52.462,141.85,196.52,547 +Senta,2.588,0.2229,37.434,131.13,45.12,550 +Ortrud,2.967,0.1185,81.113,329.65,70.47,551 +Sigelinde,3.147,0.0900,88.697,149.61,346.41,552 +Peraga,2.375,0.1519,95.87,33.90,127.69,554 +Norma,3.181,0.1546,31.040,255.88,0.56,555 +Phyllis,2.464,0.1043,36.279,90.15,177.85,556 +Carmen,2.912,0.0395,54.811,254.21,311.77,558 +Nanon,2.711,0.0651,79.82,10.36,128.97,559 +Delila,2.755,0.1578,35.334,258.36,4.74,560 +Ingwelde,3.169,0.1221,31.562,312.48,318.31,561 +Salome,3.018,0.1022,32.651,329.92,263.61,562 +Suleika,2.711,0.2364,53.29,185.78,336.80,563 +Dudu,2.747,0.2769,52.010,179.99,214.92,564 +Marbachia,2.442,0.1311,27.332,268.36,292.37,565 +Stereoskopia,3.379,0.1202,167.381,133.61,299.75,566 +Eleutheria,3.133,0.0896,93.41,56.10,133.67,567 +Cheruskia,2.88,0.1686,71.224,207.59,173.93,568 +Misa,2.658,0.1806,72.95,227.34,142.51,569 +Kythera,3.42,0.1188,87.486,70.70,161.68,570 +Rebekka,2.401,0.1564,28.903,82.85,192.11,572 +Recha,3.014,0.1101,47.582,71.67,29.70,573 +Emanuela,2.99,0.1919,74.378,208.94,27.23,576 +Rhea,3.11,0.1548,38.234,105.47,329.85,577 +Happelia,2.752,0.1921,69.29,272.38,261.46,578 +Sidonia,3.014,0.0773,85.57,177.99,228.85,579 +Selene,3.228,0.0872,48.204,20.59,338.65,580 +Tauntonia,3.213,0.0343,61.481,10.44,25.26,581 +Olympia,2.61,0.2219,44.347,195.17,310.24,582 +Klotilde,3.171,0.1600,78.236,77.96,252.03,583 +Semiramis,2.374,0.2340,54.01,345.27,85.29,584 +Bilkis,2.432,0.1281,49.761,219.65,329.83,585 +Thekla,3.04,0.0642,95.203,327.48,253.25,586 +Achilles,5.209,0.1480,130.099,321.40,133.50,588 +Croatia,3.136,0.0400,93.617,81.81,228.11,589 +Tomyris,2.997,0.0804,30.577,187.28,338.67,590 +Irmgard,2.684,0.2068,51.86,131.79,217.90,591 +Bathseba,3.023,0.1338,43.787,106.90,257.50,592 +Titania,2.698,0.2170,70.145,91.27,30.91,593 +Polyxena,3.206,0.0638,90.647,337.44,280.00,595 +Scheila,2.929,0.1626,159.726,335.51,175.50,596 +Bandusia,2.671,0.1444,36.06,69.43,307.06,597 +Octavia,2.76,0.2509,78.237,233.21,292.12,598 +Luisa,2.772,0.2926,70.249,298.82,294.38,599 +Musa,2.66,0.0554,25.115,243.62,113.04,600 +Nerthus,3.133,0.1043,75.535,259.90,160.47,601 +Marianna,3.082,0.2511,110.444,239.80,45.82,602 +Tekmessa,3.154,0.1929,64.536,344.47,28.55,604 +Juvisia,3.002,0.1365,69.86,111.95,15.22,605 +Brangane,2.586,0.2210,35.758,248.17,58.39,606 +Jenny,2.857,0.0748,67.520,123.52,292.18,607 +Fulvia,3.086,0.0393,54.17,182.78,108.86,609 +Valeria,2.979,0.1231,57.468,95.56,256.60,611 +Veronika,3.154,0.2592,38.767,254.26,122.51,612 +Ginevra,2.919,0.0561,81.344,6.37,65.68,613 +Pia,2.693,0.1082,29.191,352.02,209.82,614 +Roswitha,2.631,0.1107,48.626,119.72,247.01,615 +Patroclus,5.211,0.1397,140.362,286.55,308.08,617 +Elfriede,3.191,0.0695,131.292,126.38,229.72,618 +Triberga,2.521,0.0757,29.051,321.97,178.02,619 +Werdandi,3.125,0.1363,29.726,291.28,36.47,621 +Chimaera,2.461,0.1111,44.09,336.34,124.64,623 +Hektor,5.267,0.0226,225,254.22,181.56,624 +Xenia,2.644,0.2282,28.287,72.37,200.44,625 +Notburga,2.574,0.2418,73.236,34.86,43.42,626 +Charis,2.9,0.0586,38.018,277.05,177.80,627 +Christine,2.581,0.0437,48.239,82.62,205.12,628 +Bernardina,3.13,0.1598,35.087,283.85,38.22,629 +Philippina,2.791,0.0839,50.491,278.45,279.45,631 +Zelima,3.019,0.0841,33.387,228.53,190.40,633 +Ute,3.05,0.1813,74.017,106.72,220.79,634 +Vundtia,3.143,0.0782,94.415,70.20,228.19,635 +Erika,2.913,0.1694,73.147,218.15,298.70,636 +Moira,2.734,0.1610,59.594,130.20,128.77,638 +Latona,3.015,0.1076,78.509,269.88,70.86,639 +Brambilla,3.159,0.0792,62.667,188.80,29.36,640 +Clara,3.184,0.1277,33.36,290.47,120.87,642 +Scheherezade,3.359,0.0567,64.997,123.71,229.51,643 +Agrippina,3.215,0.1393,28.916,300.32,88.44,645 +Pippa,3.194,0.2022,68.27,308.48,180.75,648 +Antikleia,3.021,0.1014,31.895,268.81,354.09,651 +Berenike,3.017,0.0426,49.793,167.34,60.68,653 +Zelinda,2.298,0.2308,160.736,257.52,214.48,654 +Briseis,2.989,0.0836,29.057,26.64,281.40,655 +Beagle,3.148,0.1331,62.604,88.38,330.49,656 +Gunlod,2.611,0.1134,39.401,314.71,244.75,657 +Nestor,5.166,0.1172,112.320,64.97,343.85,659 +Crescentia,2.534,0.1074,42.302,314.44,105.93,660 +Cloelia,3.013,0.0378,40.081,262.16,183.97,661 +Gerlinde,3.074,0.1452,107.795,141.28,312.33,663 +Judith,3.194,0.2309,85.214,12.83,102.53,664 +Sabine,3.141,0.1725,51.09,144.41,318.22,665 +Desdemona,2.594,0.2366,32.741,15.09,173.88,666 +Denise,3.183,0.1898,88.630,193.29,305.51,667 +Kypria,3.012,0.0759,29.227,293.23,116.30,669 +Ottegebe,2.803,0.1924,35.886,34.37,194.76,670 +Carnegia,3.093,0.0659,60.604,213.01,89.99,671 +Astarte,2.555,0.1342,35.584,321.20,309.15,672 +Edda,2.817,0.0087,37.622,249.28,243.51,673 +Rachele,2.921,0.1950,96.171,182.65,41.65,674 +Ludmilla,2.768,0.2043,76,166.44,152.63,675 +Melitta,3.064,0.1220,78.369,216.74,184.90,676 +Aaltje,2.955,0.0497,32.403,18.53,275.33,677 +Fredegundis,2.572,0.2200,39.585,190.40,121.20,678 +Pax,2.588,0.3095,63.909,146.83,267.01,679 +Genoveva,3.144,0.2949,83.92,16.74,245.95,680 +Lanzia,3.114,0.0582,83.04,280.24,281.01,683 +Gersuind,2.589,0.2685,55.258,348.96,89.15,686 +Melanie,2.698,0.1389,41.614,153.98,139.11,688 +Wratislavia,3.149,0.1769,134.65,46.91,114.34,690 +Lehigh,3.01,0.1237,79.451,206.86,304.25,691 +Hippodamia,3.384,0.1686,42.771,104.26,53.78,692 +Zerbinetta,2.943,0.0307,82.114,175.58,284.50,693 +Ekard,2.67,0.3230,121.891,291.91,111.88,694 +Bella,2.539,0.1604,40.620,310.46,80.00,695 +Leonora,3.174,0.2498,81.580,297.57,103.51,696 +Galilea,2.882,0.1541,80.14,106.00,333.08,697 +Ernestina,2.868,0.1110,27.037,31.94,98.44,698 +Oriola,3.012,0.0372,42.943,190.87,325.74,701 +Alauda,3.195,0.0165,190.980,224.15,353.26,702 +Interamnia,3.056,0.1555,306.313,285.27,94.80,704 +Erminia,2.924,0.0508,132.261,22.16,102.40,705 +Hirundo,2.728,0.1950,30.819,255.61,31.17,706 +Fringilla,2.915,0.1132,95.173,250.52,19.49,709 +Gertrud,3.132,0.1322,29.208,298.81,99.64,710 +Boliviana,2.576,0.1852,124.125,336.28,181.39,712 +Luscinia,3.399,0.1554,97.968,87.16,138.39,713 +Ulula,2.536,0.0555,41.343,256.68,232.19,714 +Transvaalia,2.767,0.0836,25.458,258.86,301.28,715 +Wisibada,3.137,0.2640,27.656,257.17,24.46,717 +Erida,3.056,0.1983,70.911,13.74,174.57,718 +Bohlinia,2.888,0.0185,33.73,39.79,110.93,720 +Tabora,3.553,0.1175,86.309,153.63,352.58,721 +Joella,2.565,0.2856,44.02,323.00,113.23,726 +Nipponia,2.567,0.1042,32.17,330.83,274.21,727 +Watsonia,2.76,0.0969,50.025,293.98,87.51,729 +Sorga,2.986,0.1417,34.597,315.50,288.76,731 +Tjilaki,2.456,0.0449,29.791,154.00,64.26,732 +Mocia,3.4,0.0583,98.493,13.75,189.29,733 +Benda,3.146,0.1004,67.318,158.06,65.94,734 +Marghanna,2.731,0.3209,67.976,117.76,309.87,735 +Arequipa,2.591,0.2448,47.804,137.95,134.21,737 +Alagasta,3.044,0.0537,62.79,154.84,45.83,738 +Mandeville,2.738,0.1435,104.517,352.48,44.99,739 +Cantabia,3.055,0.1085,90.90,142.67,48.76,740 +Botolphia,2.718,0.0698,29.64,89.29,61.53,741 +Edisona,3.012,0.1154,47.087,82.99,283.61,742 +Eugenisis,2.792,0.0600,51.072,211.48,186.25,743 +Aguntina,3.17,0.1166,58.636,76.18,28.64,744 +Marlu,3.112,0.2365,74.274,167.97,306.97,746 +Winchester,3.001,0.3394,171.71,76.28,277.45,747 +Simeisa,3.951,0.1889,103.714,39.53,177.68,748 +Faina,2.551,0.1511,113.699,78.31,302.51,751 +Sulamitis,2.462,0.0747,60.171,147.73,23.17,752 +Malabar,2.987,0.0505,94.522,347.70,303.15,754 +Quintilla,3.179,0.1368,41.210,38.29,44.08,755 +Lilliana,3.197,0.1479,64.837,267.17,4.32,756 +Portlandia,2.374,0.1082,32.894,313.10,43.81,757 +Mancunia,3.189,0.1502,88.985,247.92,314.29,758 +Vinifera,2.619,0.2053,52.926,218.86,1.06,759 +Massinga,3.147,0.2336,71.29,282.92,200.43,760 +Pulcova,3.154,0.1067,147.343,341.41,188.78,762 +Gedania,3.192,0.0926,58.28,344.25,158.51,764 +Moguntia,3.018,0.0969,41.044,171.21,70.77,766 +Bondia,3.12,0.1828,43.039,244.19,269.23,767 +Struveana,3.138,0.2134,32.597,133.90,16.64,768 +Tatjana,3.167,0.1871,96.720,81.01,253.32,769 +Libera,2.652,0.2470,29.322,3.29,228.58,771 +Tanete,2.998,0.0944,126.473,183.23,145.94,772 +Irmintraud,2.859,0.0786,91.672,267.04,332.89,773 +Armor,3.05,0.1667,50.214,250.82,28.64,774 +Lumiere,3.018,0.0670,31.958,250.08,169.12,775 +Berbericia,2.929,0.1658,151.711,269.02,306.76,776 +Gutemberga,3.221,0.1146,71.749,180.97,264.54,777 +Theobalda,3.179,0.2559,55.317,10.91,135.04,778 +Nina,2.664,0.2273,80.572,77.61,49.00,779 +Armenia,3.118,0.0980,126.263,347.06,212.51,780 +Kartvelia,3.222,0.1191,72.927,44.21,155.62,781 +Nora,2.342,0.2296,38.719,301.71,154.81,783 +Pickeringia,3.098,0.2416,75.596,205.89,238.05,784 +Zwetana,2.569,0.2098,49.460,27.06,131.43,785 +Bredichina,3.175,0.1594,108.309,11.93,133.70,786 +Moskva,2.539,0.1298,27.927,146.29,125.78,787 +Hohensteina,3.121,0.1356,111.295,170.01,47.83,788 +Pretoria,3.413,0.1541,170.37,40.28,38.61,790 +Ani,3.124,0.1928,116.865,139.98,201.70,791 +Metcalfia,2.622,0.1315,61.804,59.52,227.36,792 +Arizona,2.795,0.1241,26.636,71.01,308.20,793 +Irenaea,3.129,0.2961,35.703,138.00,131.35,794 +Fini,2.75,0.1020,85.263,336.49,190.02,795 +Sarita,2.635,0.3201,43.580,42.21,329.48,796 +Ruth,3.014,0.0352,43.19,341.10,44.40,798 +Gudula,2.541,0.0229,47.185,260.37,236.46,799 +Helwerthia,2.606,0.0767,32.404,156.26,335.45,801 +Picka,3.196,0.0639,46.50,83.74,57.13,803 +Hispania,2.837,0.1411,137.952,329.76,344.74,804 +Hormuthia,3.193,0.1866,73.095,118.62,131.81,805 +Gyldenia,3.205,0.0805,83.103,227.22,121.45,806 +Merxia,2.745,0.1292,30.923,84.07,274.63,808 +Tauris,3.159,0.3056,102.229,352.84,296.27,814 +Juliana,3.002,0.1082,50.745,123.12,20.84,816 +Kapteynia,3.17,0.0908,64.255,29.14,291.52,818 +Adriana,3.129,0.0505,58.65,278.79,194.71,820 +Fanny,2.773,0.2116,28.856,278.51,32.86,821 +Anastasia,2.792,0.1373,32.457,148.18,141.44,824 +Lindemannia,3.193,0.0277,47.891,236.28,295.83,828 +Academia,2.581,0.0986,42.685,107.93,42.30,829 +Petropolitana,3.211,0.0656,41.328,40.17,91.00,830 +Burnhamia,3.183,0.2009,61.278,311.58,91.48,834 +Olivia,3.221,0.0880,30.418,103.89,67.36,835 +Seraphina,2.9,0.1311,58.095,134.77,117.37,838 +Zenobia,3.132,0.1026,27.306,69.65,9.55,840 +Kerstin,3.238,0.1165,43.576,91.70,352.81,842 +Leontina,3.204,0.0695,42.154,194.88,353.61,844 +Naema,2.94,0.0700,52.677,24.50,293.22,845 +Lipperta,3.131,0.1754,52.41,23.19,130.04,846 +Inna,3.112,0.1627,33.027,164.07,125.66,848 +Ara,3.146,0.2012,80.756,69.50,63.04,849 +Altona,3.004,0.1270,80.90,72.19,135.16,850 +Wladilena,2.362,0.2744,26.541,330.34,282.39,852 +Nansenia,2.312,0.1050,27.593,357.52,59.82,853 +Backlunda,2.435,0.1193,45.449,293.63,72.76,856 +Bouzareah,3.226,0.1099,65.417,57.92,21.86,859 +Ursina,2.795,0.1072,34.561,308.87,21.94,860 +Aida,3.139,0.1005,66.85,120.63,192.31,861 +Franzia,2.802,0.0827,27.033,180.14,120.69,862 +Benkoela,3.2,0.0283,38.724,34.92,97.80,863 +Fatme,3.126,0.0525,78.061,140.83,263.95,866 +Lova,2.704,0.1464,50.692,357.36,286.68,868 +Holda,2.732,0.0785,34.431,83.90,18.48,872 +Mechthild,2.627,0.1490,34.471,187.38,109.83,873 +Rotraut,3.154,0.0796,58.287,277.89,9.04,874 +Walkure,2.487,0.1592,38.41,13.63,275.66,877 +Herba,2.999,0.3235,32.329,1.23,100.79,880 +Swetlana,3.122,0.2675,42.440,258.89,126.46,882 +Priamus,5.191,0.1247,101.093,14.54,335.88,884 +Ulrike,3.095,0.1839,30.537,66.85,203.89,885 +Washingtonia,3.169,0.2710,86.793,206.47,302.23,886 +Parysatis,2.709,0.1947,44.749,147.01,298.02,888 +Waltraut,3.021,0.0599,28.376,192.44,87.75,890 +Gunhild,2.859,0.0265,55.747,353.18,293.82,891 +Seeligeria,3.228,0.1046,74.481,64.81,286.12,892 +Leopoldina,3.051,0.1464,85.992,42.74,222.49,893 +Erda,3.119,0.1104,28.309,257.22,116.61,894 +Helio,3.203,0.1442,109.568,225.88,177.56,895 +Jokaste,2.905,0.2017,31.018,268.01,127.52,899 +Nealley,3.237,0.0459,58.065,209.01,233.98,903 +Rockefellia,2.995,0.0852,49.146,290.41,253.40,904 +Repsolda,2.893,0.0860,65.752,42.13,293.51,906 +Rhoda,2.799,0.1633,82.660,309.71,88.52,907 +Buda,2.472,0.1479,30.749,149.68,23.36,908 +Ulla,3.542,0.0912,116.44,269.23,232.51,909 +Anneliese,2.925,0.1555,48.590,99.45,208.14,910 +Agamemnon,5.28,0.0672,131.038,349.86,81.04,911 +Maritima,3.129,0.1788,82.675,275.42,91.15,912 +Palisana,2.458,0.2144,76.190,222.88,49.05,914 +America,2.365,0.2366,33.23,68.03,41.57,916 +Lyka,2.381,0.2011,34.878,342.91,359.88,917 +Ilsebill,2.773,0.0838,33.500,142.72,156.24,919 +Rogeria,2.622,0.1046,26.656,300.25,270.17,920 +Jovita,3.17,0.1855,55.312,76.24,70.60,921 +Herluga,2.616,0.1944,34.553,48.09,201.36,923 +Toni,2.94,0.1533,85.49,113.07,220.17,924 +Alphonsina,2.7,0.0808,57.505,335.04,201.77,925 +Imhilde,2.981,0.1824,48.48,212.40,173.63,926 +Ratisbona,3.221,0.0911,75.892,189.07,172.32,927 +Hildrun,3.134,0.1478,62.817,115.93,21.83,928 +Westphalia,2.432,0.1429,34.922,188.22,330.14,930 +Whittemora,3.17,0.2331,45.298,85.34,315.44,931 +Hooveria,2.42,0.0910,58.978,128.58,49.97,932 +Thuringia,2.749,0.2159,53.714,43.50,64.28,934 +Kunigunde,3.132,0.1757,43.227,115.41,253.59,936 +Chlosinde,3.151,0.1958,33.466,12.08,225.34,938 +Kordula,3.368,0.1700,79.852,136.80,283.76,940 +Romilda,3.162,0.1659,36.772,3.02,319.50,942 +Begonia,3.117,0.2135,70.572,58.12,4.01,943 +Hidalgo,5.731,0.6609,38.,84.94,56.54,944 +Barcelona,2.639,0.1610,25.618,215.92,162.15,945 +Poesia,3.116,0.1433,36.210,137.88,37.67,946 +Monterosa,2.754,0.2472,26.060,131.44,339.25,947 +Hel,3.01,0.1938,63.494,110.97,250.19,949 +Caia,2.992,0.2440,88.692,142.18,356.59,952 +Li,3.132,0.1745,58.771,30.93,150.97,954 +Camelia,2.919,0.0813,91.548,316.28,226.01,957 +Asplinda,3.988,0.1838,45.112,227.62,92.67,958 +Arne,3.176,0.2219,45.176,191.37,333.54,959 +Gunnie,2.692,0.0913,36.571,315.38,285.61,961 +Angelica,3.165,0.2784,60.857,268.10,46.98,965 +Muschi,2.719,0.1305,25.509,295.82,178.01,966 +Alsatia,2.64,0.1629,60.867,93.80,6.48,971 +Cohnia,3.056,0.2359,77.827,303.57,93.50,972 +Aralia,3.21,0.1124,51.609,166.74,87.53,973 +Lioba,2.533,0.1097,25.001,34.74,301.98,974 +Benjamina,3.203,0.1057,83.195,145.67,321.01,976 +Philippa,3.116,0.0256,65.471,103.91,71.56,977 +Aidamina,3.203,0.2314,92.105,69.52,132.57,978 +Ilsewa,3.157,0.1384,35.741,228.65,115.59,979 +Anacostia,2.74,0.2026,74.679,32.74,69.61,980 +Martina,3.095,0.2021,32.545,58.16,297.82,981 +Franklina,3.067,0.2340,33.227,145.52,350.89,982 +Gunila,3.161,0.0914,73.87,314.51,348.49,983 +Gretia,2.804,0.1956,32.449,41.72,55.03,984 +Amelia,3.133,0.2035,48.677,317.64,265.44,986 +Wallia,3.137,0.2370,52.651,316.58,16.25,987 +McDonalda,3.14,0.1597,38.556,345.47,254.76,991 +Swasey,3.033,0.0865,27.585,144.62,347.84,992 +Hilaritas,3.088,0.1396,29.128,97.44,146.65,996 +Bodea,3.116,0.2140,31.761,268.43,72.09,998 +Piazzia,3.168,0.2583,47.78,162.91,280.59,1000 +Gaussia,3.209,0.1221,72.711,31.51,145.70,1001 +Lilofee,3.139,0.1599,33.678,135.17,316.88,1003 +Belopolskya,3.399,0.0889,71.60,245.58,214.83,1004 +Arago,3.167,0.1190,61.132,126.31,60.65,1005 +Lagrangea,3.141,0.3582,35.310,206.24,86.21,1006 +"La Paz",3.092,0.0732,41.061,0.31,15.37,1008 +Marlene,2.93,0.1046,46.876,220.23,279.68,1010 +Tombecka,2.683,0.2092,34.613,94.24,99.63,1013 +Christa,3.207,0.0884,82.350,112.38,286.67,1015 +Jacqueline,2.605,0.0778,40.152,73.52,68.10,1017 +Flammario,2.739,0.2849,100.765,316.02,286.60,1021 +Olympiada,2.806,0.1737,34.297,304.17,124.74,1022 +Thomana,3.169,0.0963,58.27,25.15,195.52,1023 +Hale,2.869,0.2215,43.274,97.55,308.00,1024 +Aesculapia,3.152,0.1288,31.225,78.74,131.91,1027 +Lydina,3.405,0.1053,88.526,206.98,24.11,1028 +Vitja,3.121,0.1227,59.717,290.37,5.44,1030 +Arctica,3.047,0.0589,75.400,213.22,310.03,1031 +Pafuri,3.13,0.1417,65.658,206.90,189.02,1032 +Amata,3.154,0.1897,56.063,198.39,324.89,1035 +Ganymed,2.666,0.5331,37.675,140.65,132.43,1036 +Tuckia,3.982,0.2218,58.3,179.19,305.04,1038 +Sonneberga,2.68,0.0610,33.853,281.71,326.52,1039 +Asta,3.073,0.1449,60.571,136.23,344.14,1041 +Amazone,3.236,0.0878,63.920,129.71,298.53,1042 +Beate,3.094,0.0384,31.986,181.83,157.77,1043 +Edwin,2.985,0.0606,29.084,320.65,48.71,1046 +Feodosia,2.732,0.1800,62.218,24.95,183.61,1048 +Gotho,3.092,0.1372,56.296,225.03,41.03,1049 +Merope,3.213,0.1005,60.439,264.46,153.36,1051 +Forsytia,2.923,0.1342,47.780,118.86,295.72,1054 +Wanda,2.894,0.2472,44.657,183.73,114.76,1057 +Mussorgskia,2.642,0.1877,25.227,178.36,87.93,1059 +Ljuba,3.006,0.0705,58.031,124.42,100.58,1062 +Planckia,3.129,0.1096,35.657,2.03,31.30,1069 +Tunica,3.234,0.0800,39.131,169.95,190.77,1070 +Brita,2.801,0.1105,60.862,34.41,29.17,1071 +Malva,3.17,0.2392,53.675,275.91,25.60,1072 +Gellivara,3.186,0.1876,25.992,164.68,289.69,1073 +Beljawskya,3.15,0.1801,49.189,153.60,22.54,1074 +Helina,3.014,0.1097,26.198,97.86,250.67,1075 +Reseda,3.096,0.1483,37.810,94.76,9.26,1081 +Pirola,3.121,0.1801,42.607,57.51,186.41,1082 +Tamariwa,2.687,0.1326,26.476,120.83,109.34,1084 +Amaryllis,3.185,0.0418,69.281,315.60,129.52,1085 +Nata,3.161,0.0537,66.27,158.08,157.52,1086 +Arabis,3.018,0.0901,37.498,314.60,25.46,1087 +Spiraea,3.416,0.0701,35.178,359.35,12.48,1091 +Lilium,2.899,0.0848,40.276,161.50,314.99,1092 +Freda,3.13,0.2710,116.73,100.80,251.20,1093 +Tulipa,3.024,0.0207,27.875,121.62,342.61,1095 +Reunerta,2.6,0.1941,42.333,81.47,247.65,1096 +Hakone,2.688,0.1161,26.684,11.05,81.18,1098 +Clematis,3.23,0.0788,33.765,64.61,105.71,1101 +Pepita,3.07,0.1108,36.632,200.02,117.54,1102 +Fragaria,3.012,0.1065,38.206,16.13,223.64,1105 +Lictoria,3.184,0.1231,79.079,195.82,350.97,1107 +Demeter,2.428,0.2569,25.285,144.52,78.07,1108 +Tata,3.224,0.0983,61.817,334.23,0.16,1109 +Polonia,3.017,0.1081,39.661,230.01,87.07,1112 +Katja,3.122,0.1367,44.792,269.41,118.78,1113 +Lorraine,3.095,0.0716,75.631,64.22,207.58,1114 +Sabauda,3.099,0.1737,75.907,348.06,56.68,1115 +Catriona,2.929,0.2245,38.741,303.08,83.10,1116 +Hanskya,3.214,0.0436,70.954,218.47,337.04,1118 +Euboea,2.612,0.1551,29.443,204.44,229.93,1119 +China,3.126,0.2176,26.084,140.49,10.39,1125 +Mimi,2.594,0.2651,46.006,138.79,282.70,1127 +Astrid,2.788,0.0445,41.851,226.99,234.40,1128 +Neujmina,3.022,0.0838,34.576,145.18,139.66,1129 +Hollandia,2.687,0.2755,27.235,18.26,270.69,1132 +Colchis,2.666,0.1144,50.592,90.65,3.33,1135 +Mercedes,2.567,0.2537,25.296,194.73,148.73,1136 +Crimea,2.772,0.1103,29.179,45.99,310.07,1140 +Odysseus,5.241,0.0917,114.624,298.57,237.02,1143 +Oda,3.764,0.0834,56.337,350.99,217.29,1144 +Biarmia,3.043,0.2555,32.925,121.59,63.64,1146 +Rarahu,3.019,0.1085,27.512,218.13,175.77,1148 +Volga,2.898,0.0963,52.377,218.19,116.41,1149 +Astronomia,3.393,0.0709,55.715,273.55,205.02,1154 +Arabia,3.181,0.1442,29.113,114.80,312.38,1157 +Granada,2.379,0.0589,28.641,105.66,312.44,1159 +Larissa,3.925,0.1056,40.379,160.28,206.78,1162 +Saga,3.219,0.0425,32.429,147.38,200.73,1163 +Imprinetta,3.127,0.2114,53.187,147.54,96.68,1165 +Sakuntala,2.536,0.2087,26.011,208.11,189.85,1166 +Dubiago,3.416,0.0684,63.12,202.76,72.72,1167 +Rusthawelia,3.175,0.1945,82.229,57.65,292.30,1171 +Aneas,5.225,0.1061,118.020,354.37,50.81,1172 +Anchises,5.283,0.1393,99.549,297.39,41.07,1173 +Gonnessia,3.35,0.0337,91.98,229.98,253.35,1177 +Rita,3.987,0.1555,97,74.62,205.85,1180 +Turnera,3.023,0.1011,34.290,191.01,296.26,1186 +Afra,2.639,0.2233,32.348,189.94,74.90,1187 +Terentia,2.931,0.1119,59.246,57.91,95.41,1189 +Alfaterna,2.896,0.0463,47.397,135.54,56.42,1191 +Aletta,2.916,0.0905,41.358,134.42,244.22,1194 +Sheba,2.652,0.1801,25.274,248.42,262.69,1196 +Rhodesia,2.882,0.2340,47.741,244.72,277.07,1197 +Geldonia,3.017,0.0319,30.395,265.04,291.40,1199 +Imperatrix,3.066,0.1060,42.006,47.99,52.45,1200 +Strenua,2.699,0.0388,35.825,131.94,166.11,1201 +Marina,3.999,0.1676,54.93,183.12,307.54,1202 +Nanna,2.885,0.2500,35.18,137.91,177.23,1203 +Troilus,5.253,0.0925,100.477,304.66,295.44,1208 +Pumma,3.171,0.1276,26.889,222.40,176.84,1209 +Morosovia,3.009,0.0623,33.663,107.34,166.53,1210 +Bressole,2.928,0.1599,45.809,63.44,211.21,1211 +Francette,3.948,0.1898,76.387,123.87,348.16,1212 +Algeria,3.138,0.1284,29.175,125.59,110.42,1213 +Richilde,2.712,0.1171,36.668,200.24,32.73,1214 +Tina,2.793,0.2504,25.781,51.01,59.86,1222 +Geranium,3.217,0.1924,46.269,296.31,303.21,1227 +Tilia,3.225,0.1664,27.795,196.03,166.68,1229 +Cortusa,3.187,0.1372,36.367,92.41,340.96,1232 +Kobresia,2.555,0.0566,33.323,144.39,333.84,1233 +Genevieve,2.613,0.0765,39.81,181.34,307.14,1237 +Centenaria,2.866,0.1760,63.035,326.52,24.04,1240 +Dysona,3.19,0.1006,79.190,206.66,320.59,1241 +Zambesia,2.737,0.1902,47.594,126.64,54.07,1242 +Pamela,3.095,0.0463,69.883,99.33,52.17,1243 +Deira,2.343,0.0982,31.799,55.47,260.87,1244 +Calvinia,2.895,0.0832,29.751,338.95,207.07,1245 +Memoria,3.131,0.1763,38.906,55.58,138.88,1247 +Jugurtha,2.723,0.0161,28.468,256.62,341.78,1248 +Erfordia,3.134,0.0305,51.540,106.73,240.38,1254 +Schilowa,3.143,0.1743,33.669,300.03,133.32,1255 +Normannia,3.896,0.0795,68.245,209.95,101.60,1256 +Sicilia,3.184,0.0444,45.669,222.57,77.41,1258 +Ogyalla,3.102,0.1268,36.111,22.35,150.31,1259 +Legia,3.139,0.1784,32.576,341.84,104.17,1261 +Sniadeckia,3.003,0.0044,71.011,274.57,161.91,1262 +Varsavia,2.665,0.1884,49.29,216.61,287.14,1263 +Letaba,2.866,0.1562,66.040,77.16,31.75,1264 +Tone,3.356,0.0509,75.470,357.35,299.80,1266 +Libya,3.98,0.1028,96.710,357.44,118.59,1268 +Rollandia,3.9,0.0984,104.893,120.91,19.46,1269 +Isergina,3.141,0.1208,47.524,81.50,271.99,1271 +Cimbria,2.681,0.1673,27.622,142.12,197.92,1275 +Ucclia,3.177,0.0909,36.499,299.34,337.97,1276 +Dolores,2.7,0.2372,32.587,310.35,47.31,1277 +Baillauda,3.428,0.0473,50.83,317.70,92.79,1280 +Jeanne,2.557,0.2078,25.716,258.29,72.75,1281 +Utopia,3.124,0.1219,57.702,311.75,77.79,1282 +Komsomolia,3.18,0.2219,29.569,263.20,234.76,1283 +Latvia,2.645,0.1719,41.128,130.17,115.38,1284 +Julietta,2.994,0.0499,42.430,346.34,68.67,1285 +Santa,2.886,0.0657,31.378,4.90,52.94,1288 +Phryne,3.012,0.0958,27.418,330.96,118.73,1291 +Antwerpia,2.687,0.2318,37.199,14.50,312.95,1294 +Deflotte,3.39,0.1240,47.407,25.31,274.88,1295 +Andree,2.417,0.1438,26.298,133.89,236.63,1296 +Nocturna,3.129,0.1450,37.802,76.26,58.77,1298 +Marcelle,2.782,0.0066,28.194,49.38,350.18,1300 +Werra,3.111,0.1752,35.041,179.54,354.17,1302 +Luthera,3.228,0.1035,81.685,109.50,100.77,1303 +Arosa,3.197,0.1206,43.613,123.10,148.09,1304 +Scythia,3.144,0.0964,66.780,62.81,141.56,1306 +Halleria,2.908,0.0107,46.951,131.36,163.82,1308 +Hyperborea,3.206,0.1492,57.570,207.61,244.50,1309 +Vassar,3.097,0.2108,36.28,34.02,261.61,1312 +Bronislawa,3.209,0.0746,64.863,225.06,21.45,1315 +Disa,2.988,0.2054,25.651,346.50,316.29,1319 +Impala,2.991,0.2290,37.331,335.29,206.06,1320 +Majuba,2.938,0.1702,37.137,85.85,345.05,1321 +Tugela,3.237,0.1478,78.295,144.63,137.76,1323 +Losaka,2.667,0.2253,26.336,343.52,278.29,1326 +Devota,3.501,0.1352,53.697,255.12,174.01,1328 +Spiridonia,3.172,0.0746,68.417,23.95,3.79,1330 +Solvejg,3.097,0.1905,36.824,75.57,184.53,1331 +Marconia,3.06,0.1332,46.796,259.90,348.96,1332 +Lundmarka,2.915,0.0932,27.621,243.48,129.30,1334 +Gerarda,2.911,0.0996,40.875,214.83,202.26,1337 +Yvette,3.183,0.1272,29.451,40.67,224.65,1340 +Potomac,3.982,0.1812,72.976,155.73,332.83,1345 +Patria,2.573,0.0669,32.40,295.79,201.18,1347 +Uzbekistania,3.197,0.0684,60.010,49.81,64.18,1351 +Maartje,3.009,0.0962,39.013,77.75,96.96,1353 +Botha,3.127,0.2158,41.732,181.25,250.21,1354 +Nyanza,3.081,0.0513,60.895,239.56,301.99,1356 +Khama,3.186,0.1550,38.321,19.42,282.89,1357 +Prieska,3.119,0.0694,46.096,159.33,342.60,1359 +Tarka,2.633,0.2147,33.316,113.97,287.91,1360 +Leuschneria,3.082,0.1309,29.637,345.37,172.94,1361 +Griqua,3.213,0.3728,26.936,256.17,261.72,1362 +Piccolo,2.876,0.1393,27.55,208.47,282.89,1366 +Ostanina,3.118,0.2110,42.401,288.77,128.09,1369 +Resi,3.206,0.1208,27.155,49.28,103.13,1371 +Haremari,2.765,0.1489,26.491,227.07,88.09,1372 +Kniertje,2.68,0.1806,26.517,288.78,275.70,1384 +Abastumani,3.437,0.0362,95.849,209.04,332.66,1390 +Pierre,2.607,0.2034,26.44,259.22,44.08,1392 +Idelsonia,2.717,0.2951,26.531,8.51,192.29,1403 +Ajax,5.287,0.1142,83.990,359.08,61.41,1404 +Trusanda,3.106,0.0954,35.423,229.05,187.34,1408 +Isko,2.675,0.0572,35.54,251.42,207.42,1409 +Brauna,3.002,0.0580,28.272,229.30,94.31,1411 +Renauxa,3.018,0.1080,27.552,135.21,65.94,1416 +Esperanto,3.089,0.0841,43.31,260.19,162.39,1421 +Sundmania,3.19,0.0566,64.691,110.95,303.49,1424 +Ruvuma,2.751,0.2109,35.406,151.73,241.63,1427 +Mombasa,2.809,0.1416,52.464,280.63,252.48,1428 +Margot,3.021,0.0677,27.178,27.52,147.69,1434 +Salonta,3.148,0.0619,53.769,249.37,31.12,1436 +Diomedes,5.212,0.0450,117.786,352.97,128.68,1437 +Wendeline,3.159,0.2382,37.511,321.32,129.28,1438 +Vogtia,3.995,0.1163,50.561,113.07,101.38,1439 +Pannonia,3.154,0.1377,26.363,226.05,310.50,1444 +Saldanha,3.205,0.2211,37.815,227.14,65.33,1456 +Magnya,3.149,0.2291,29.188,44.18,328.54,1459 +Jean-Jacques,3.126,0.0490,35.145,110.00,334.26,1461 +Zamenhof,3.149,0.1082,27.366,290.17,186.90,1462 +Nordenmarkia,3.152,0.1941,36.547,90.60,79.94,1463 +Mashona,3.387,0.1279,89.160,147.75,350.39,1467 +Linzia,3.125,0.0626,74.780,339.19,206.22,1469 +Carla,3.158,0.0705,36.97,317.67,341.55,1470 +Tornio,2.716,0.1192,28.719,180.25,93.87,1471 +Bonsdorffia,3.207,0.2659,25.851,342.75,105.12,1477 +Tubingia,3.019,0.0420,33.770,222.31,314.60,1481 +Postrema,2.737,0.2059,40.871,181.99,126.97,1484 +Boda,3.133,0.1237,25.671,216.97,107.21,1487 +Attila,3.189,0.1511,26.789,194.83,26.40,1489 +Sigrid,2.43,0.2019,28.905,14.56,1.63,1493 +Lahti,3.104,0.2355,31.605,96.12,96.73,1498 +Arenda,2.731,0.0887,35.518,108.11,273.80,1502 +Oulu,3.96,0.1427,79.872,174.36,237.85,1512 +Henry,2.621,0.1860,26.442,228.65,94.18,1516 +Beograd,2.716,0.0445,39.524,153.61,229.57,1517 +Kajaani,3.125,0.2407,31.166,19.82,338.94,1519 +Imatra,3.111,0.0949,53.435,104.80,119.03,1520 +Joensuu,3.11,0.1214,45.056,17.77,1.31,1524 +Oterma,3.986,0.2014,56.319,248.97,294.69,1529 +Borrelly,3.143,0.1912,26.791,191.26,250.35,1539 +Kevola,2.849,0.0854,43.875,6.61,112.35,1540 +Schalen,3.091,0.1174,42.374,251.36,163.83,1542 +Izsak,3.173,0.1269,26.438,356.59,280.77,1546 +Palomaa,2.786,0.0813,30.761,217.73,87.98,1548 +Wingolfia,3.435,0.1085,28.65,350.31,267.12,1556 +Jarnefelt,3.221,0.0280,54.977,7.61,301.06,1558 +Fricke,3.196,0.1265,25.352,346.65,41.75,1561 +Srbija,3.17,0.1981,41.681,58.37,232.68,1564 +Alikoski,3.211,0.0823,69.242,49.44,110.41,1567 +Evita,3.149,0.1329,36.346,19.37,248.35,1569 +Posnania,3.109,0.2042,31.500,66.07,354.17,1572 +Meyer,3.542,0.0342,57.785,15.91,260.16,1574 +Fabiola,3.144,0.1675,27.357,49.68,246.78,1576 +Kirkwood,3.928,0.2408,47.077,38.26,1.72,1578 +Herrick,3.435,0.1260,46.925,131.91,279.48,1579 +Abanderada,3.159,0.1229,29.508,321.88,89.72,1581 +Martir,3.158,0.1262,37.252,310.90,128.13,1582 +Antilochus,5.14,0.0536,108.842,16.09,186.83,1583 +Union,2.927,0.3092,55.271,259.51,264.32,1585 +Tanga,2.644,0.1116,26.572,82.96,189.72,1595 +Itzigsohn,2.89,0.1304,45.534,264.72,160.11,1596 +Giomus,3.133,0.1429,41.295,296.18,355.53,1599 +Neva,2.756,0.0956,39.564,305.98,256.30,1603 +Tombaugh,3.021,0.1030,32.33,299.45,38.20,1604 +Milankovitch,3.02,0.0739,29.598,252.90,275.55,1605 +Brenda,2.583,0.2491,29.64,328.57,229.25,1609 +Goldschmidt,3.001,0.0693,48.007,210.26,346.66,1614 +Bardwell,3.119,0.1829,29.139,94.83,254.07,1615 +Vivian,3.141,0.1541,27.851,350.46,320.78,1623 +Rabe,3.199,0.0917,26.270,197.54,26.28,1624 +"The NORC",3.195,0.2308,53.317,64.01,286.65,1625 +Strobel,3.011,0.0664,59.345,186.88,288.43,1628 +Siebohme,2.654,0.1372,29.351,73.89,126.61,1632 +Chimay,3.206,0.1239,37.428,150.39,68.37,1633 +Swings,3.073,0.0459,52.994,54.55,238.16,1637 +Bower,2.573,0.1479,35.676,328.86,106.52,1639 +Tana,3.021,0.0984,25.66,160.36,0.50,1641 +Waterfield,3.062,0.1100,28.146,150.03,106.45,1645 +Menelaus,5.211,0.0215,42.716,222.33,294.01,1647 +Heckmann,2.435,0.1632,30.202,172.68,56.81,1650 +Bojeva,3.017,0.0866,25.115,100.57,332.97,1654 +"Comas Sola",2.785,0.2315,35.943,303.72,323.45,1655 +Punkaharju,2.783,0.2601,28.010,222.92,36.43,1659 +Dagmar,3.139,0.1093,42.377,49.73,178.41,1669 +Gezelle,3.172,0.2777,26.205,103.21,254.99,1672 +Groeneveld,3.191,0.1265,32.386,322.26,4.29,1674 +Hveen,3.156,0.1100,42.665,143.17,120.94,1678 +Nevanlinna,3.116,0.1532,52.686,163.56,89.80,1679 +Iguassu,3.098,0.1260,30.210,42.04,154.94,1684 +"De Sitter",3.165,0.1596,29.661,178.36,294.62,1686 +Glarona,3.165,0.1686,37.850,342.53,316.89,1687 +Mayrhofer,3.042,0.0977,33.810,323.63,154.94,1690 +Oort,3.162,0.1762,33.644,160.80,232.47,1691 +Subbotina,2.787,0.1373,36.075,141.81,111.76,1692 +Hertzsprung,2.797,0.2733,37.772,141.66,234.81,1693 +Christophe,3.162,0.1075,26.234,220.47,132.60,1698 +Kalahari,2.856,0.1434,34.645,35.43,241.31,1702 +Polit,2.91,0.3079,28.706,171.11,248.74,1708 +Angola,3.164,0.1543,66.892,110.76,17.87,1712 +Peter,2.738,0.0902,26.656,132.60,317.14,1716 +Wells,3.148,0.0494,43.576,23.81,137.90,1721 +Klemola,3.014,0.0405,33.449,151.91,2.15,1723 +Vladimir,2.711,0.0580,38.476,114.14,297.37,1724 +Hoffmeister,2.789,0.0439,25.250,20.43,69.55,1726 +Smuts,3.168,0.1285,54.784,321.59,203.14,1731 +Zhongolovich,2.778,0.2293,26.425,64.32,186.28,1734 +ITA,3.137,0.1304,61.865,123.04,275.10,1735 +Brouwer,3.954,0.2089,62.524,132.65,47.73,1746 +Mauderli,3.948,0.2165,44.908,66.07,198.53,1748 +Telamon,5.144,0.1091,64.898,307.78,113.36,1749 +Cunningham,3.942,0.1695,79.52,282.60,110.09,1754 +Sandra,3.148,0.1278,34.765,289.54,332.16,1760 +Cogshall,3.092,0.1199,26.970,14.15,80.23,1764 +Wrubel,3.175,0.1779,38.299,232.84,265.55,1765 +Makover,3.128,0.1696,46.886,344.52,316.43,1771 +Kuiper,3.102,0.0171,39.952,319.55,312.19,1776 +Kippes,3.017,0.0569,28.164,90.30,338.80,1780 +Raahe,3.021,0.1115,25.532,353.32,347.07,1786 +Patsayev,2.748,0.1419,29.394,34.71,74.93,1791 +Finsen,3.134,0.1532,38.050,140.30,342.10,1794 +Riga,3.354,0.0556,68.167,37.69,26.43,1796 +Dirikis,3.15,0.1092,28.098,156.65,88.44,1805 +Bruwer,3.138,0.1100,28.072,51.01,136.44,1811 +Beethoven,3.153,0.1920,30.598,22.82,358.40,1815 +Laputa,3.134,0.2289,54.165,75.52,166.00,1819 +Kashirina,3.063,0.1073,27.016,70.14,222.96,1828 +Mrkos,3.216,0.0989,29.351,0.97,80.70,1832 +Ursa,3.215,0.0142,40.054,207.51,47.72,1838 +Masaryk,3.415,0.1103,40.240,198.37,124.21,1841 +Jarmila,2.654,0.1702,28.965,25.85,32.50,1843 +Susilva,3.016,0.0510,26.800,13.20,72.28,1844 +Kovalevskaya,3.212,0.0979,44.634,312.61,245.20,1859 +Deiphobus,5.133,0.0461,118.220,5.24,359.95,1867 +Thersites,5.311,0.1103,68.163,29.25,170.96,1868 +Glaukos,5.243,0.0338,47.649,330.00,130.92,1870 +Astyanax,5.232,0.0350,27.828,298.84,165.57,1871 +Helenos,5.322,0.0495,34.046,340.78,115.13,1872 +Agenor,5.228,0.0916,50.799,75.12,358.08,1873 +Marsden,3.945,0.2055,35.642,86.87,305.93,1877 +Pakhmutova,3.087,0.1154,35.243,324.35,83.95,1889 +Konoshenkova,3.209,0.1385,25.68,189.75,15.80,1890 +Moravia,3.245,0.0733,28.096,81.32,148.97,1901 +Shaposhnikov,3.976,0.2220,83.430,26.76,266.97,1902 +Adzhimushkaj,3,0.0480,27.642,292.74,356.64,1903 +Mikhailov,3.046,0.0527,37.201,329.86,326.99,1910 +Schubart,3.973,0.1720,67.476,336.46,181.47,1911 +Lucifer,2.898,0.1417,34.437,293.67,341.88,1930 +Lugano,2.674,0.1383,33.905,291.61,255.22,1936 +Loretta,3.125,0.1246,30.365,310.48,189.49,1939 +Whipple,3.06,0.0607,37.481,307.67,184.85,1940 +Iso-Heikkila,3.156,0.0414,31.611,119.22,145.10,1947 +Hesburgh,3.109,0.1439,37.501,103.28,339.53,1952 +Chandra,3.106,0.1651,34.278,162.14,318.83,1958 +Guisan,2.525,0.1229,27.004,107.27,263.66,1960 +Dufour,3.193,0.1249,50.31,103.97,56.49,1961 +Bezovec,2.422,0.2104,35.536,204.40,355.46,1963 +Colocolo,3.185,0.0774,26.269,125.95,164.51,1973 +Fedynskij,3.011,0.0874,36.413,141.59,127.02,1984 +Hopmann,3.118,0.1563,35.51,261.12,233.55,1985 +Shane,2.679,0.2070,25.15,297.97,89.90,1994 +Hirayama,3.113,0.1178,38.277,327.40,356.17,1999 +McCuskey,2.386,0.1145,25.733,115.23,185.76,2007 +Konstitutsiya,3.217,0.0965,52.023,309.09,201.76,2008 +Voloshina,3.117,0.1406,26.558,188.40,6.01,2009 +Nortia,3.169,0.1148,42.769,51.63,310.17,2025 +Ethel,3.071,0.1263,36.007,202.14,296.69,2032 +Chalonge,3.111,0.1903,33.901,294.73,90.86,2040 +Ortutay,3.105,0.1126,48.460,211.06,60.16,2043 +Tamriko,3.012,0.0827,26.799,284.24,203.34,2052 +Chiron,13.71,0.3766,166,184.80,339.62,2060 +Aksnes,3.97,0.1828,46.003,31.35,297.02,2067 +Dangreen,2.772,0.0978,34.322,66.93,321.42,2068 +Hubble,3.154,0.1894,38.471,3.97,69.70,2069 +Galle,3.138,0.2523,26.330,121.67,29.31,2097 +Toronto,3.186,0.1217,35.874,278.05,290.43,2104 +"Otto Schmidt",2.436,0.0044,28.999,85.49,75.58,2108 +Tyumenia,3.058,0.1279,51.485,97.99,74.64,2120 +Tanya,3.212,0.0319,37.736,254.68,187.96,2127 +Zhukov,2.781,0.0797,30.787,321.31,337.26,2132 +Priscilla,3.193,0.0474,34.957,259.39,140.89,2137 +Kemerovo,2.988,0.0585,34.539,281.98,117.96,2140 +Blaauw,3.212,0.1014,40.549,228.41,278.06,2145 +Stentor,5.19,0.1022,50.755,354.18,274.25,2146 +Epeios,5.217,0.0584,37.980,358.91,232.24,2148 +Hannibal,3.125,0.2207,44.559,280.66,141.88,2152 +Young,3.125,0.1768,27.115,226.34,23.93,2165 +Maresjev,3.14,0.1152,28.324,200.78,166.79,2173 +Fujian,3.178,0.0938,35.690,52.70,121.70,2184 +Pyatigoriya,3.138,0.0797,29.217,225.98,147.16,2192 +Jackson,3.103,0.0751,58.265,152.88,224.08,2193 +Ellicott,3.436,0.0568,57.384,302.99,305.07,2196 +Lyyli,2.59,0.4048,25.16,7.66,284.15,2204 +Antenor,5.165,0.0129,97.658,188.88,307.61,2207 +Pushkin,3.494,0.0308,40.850,192.53,3.34,2208 +Carol,3.154,0.2687,25.860,328.42,137.58,2214 +Eltigen,3.157,0.1699,28.800,23.51,173.50,2217 +Wotho,3.045,0.1568,28.158,357.24,324.31,2218 +Mannucci,3.152,0.1140,38.814,41.47,293.82,2219 +Lermontov,3.122,0.1620,29.644,344.59,340.43,2222 +Sarpedon,5.253,0.0190,77.480,20.89,52.82,2223 +Soyuz-Apollo,3.141,0.1818,26.080,266.33,285.11,2228 +Vittore,3.207,0.2156,41.688,15.56,274.28,2235 +Paracelsus,3.195,0.1061,33.978,187.12,2.98,2239 +Alcathous,5.178,0.0664,113.682,69.94,293.05,2241 +Hekatostos,2.637,0.1336,29.28,283.73,316.50,2245 +Bowell,3.95,0.0922,48.424,84.58,21.95,2246 +Kanda,3.099,0.1149,26.361,99.20,146.22,2248 +Yamamoto,3.19,0.0804,33.606,320.91,112.95,2249 +Tikhov,2.712,0.1492,29.488,339.52,182.97,2251 +Viipuri,2.693,0.0808,26.255,126.28,173.76,2258 +Neoptolemus,5.198,0.0451,76.435,358.59,321.35,2260 +Shaanxi,3.019,0.1085,26.702,120.89,316.24,2263 +Sabrina,3.127,0.1788,34.192,5.19,79.10,2264 +Tchaikovsky,3.397,0.1817,46.94,190.30,205.34,2266 +Efremiana,3.129,0.0828,29.604,211.04,34.47,2269 +Yazhi,3.156,0.1402,25.790,69.57,189.26,2270 +Kiso,2.762,0.0609,31.229,19.44,179.04,2271 +Kevo,3.041,0.0650,41.429,162.04,295.75,2291 +Daghestan,3.167,0.1258,26.579,6.23,93.33,2297 +Garuda,3.045,0.0545,40.139,32.21,341.34,2307 +Olshaniya,3.143,0.1617,26.395,108.88,330.55,2310 +"El Leoncito",3.645,0.0437,53.14,338.79,185.47,2311 +Duboshin,3.966,0.1584,50.122,65.04,342.22,2312 +Czechoslovakia,3.011,0.1079,25.258,123.32,14.10,2315 +Blarney,3.166,0.1333,35.739,181.87,261.03,2320 +Janice,3.082,0.1805,28.463,141.22,305.04,2324 +Tololo,2.859,0.1592,42.550,179.83,259.44,2326 +Ontake,3.182,0.0348,33.061,215.17,130.96,2330 +Kalm,3.072,0.0608,31.734,324.80,244.33,2332 +Fucik,3.023,0.0740,25.155,265.60,134.70,2345 +Vinata,3.087,0.2140,25.398,229.80,108.16,2347 +Kurchatov,3.109,0.1100,30.069,206.87,119.01,2352 +Hirons,3.236,0.0394,43.072,320.83,355.68,2356 +Phereclos,5.221,0.0474,94.625,34.13,76.06,2357 +Cebriones,5.224,0.0392,95.976,35.84,54.49,2363 +Vladvysotskij,3.084,0.2147,26.090,249.05,16.59,2374 +Radek,3.18,0.2094,32.744,25.68,101.71,2375 +Martynov,3.201,0.1186,41.583,241.86,300.96,2376 +Pannekoek,2.89,0.1394,40.373,305.63,266.66,2378 +Heiskanen,3.164,0.2764,33.157,56.09,176.51,2379 +Suzuki,3.227,0.1926,48.406,217.64,114.17,2393 +Astapovich,2.637,0.2416,31.285,97.68,103.22,2408 +Vibeke,3.195,0.1299,31.782,235.53,46.67,2414 +Nininger,3.237,0.0432,39.505,131.90,283.15,2421 +Simonov,2.914,0.1138,25.654,65.01,5.42,2426 +Tomeileen,3.005,0.0571,31.878,42.97,68.28,2443 +Lederle,2.727,0.1320,29.925,230.27,141.86,2444 +Sholokhov,2.792,0.1167,38.519,328.89,72.38,2448 +Palamedes,5.13,0.0753,65.916,344.76,95.34,2456 +Clavel,3.18,0.1683,25.943,252.26,231.96,2461 +Guinevere,3.966,0.2770,35.688,204.70,183.10,2483 +Kutuzov,3.19,0.1412,27.792,314.89,269.12,2492 +Inge,3.16,0.0625,46.628,2.22,95.56,2494 +Novorossijsk,3.106,0.0928,29.946,127.96,315.08,2520 +Budovicium,3.117,0.1573,32.677,158.20,19.86,2524 +O'Steen,3.151,0.1775,29.877,99.59,286.68,2525 +Houzeau,3.15,0.1670,31.052,84.09,201.52,2534 +Madeline,2.626,0.1631,26.004,198.07,314.30,2569 +Yesenin,3.091,0.1272,27.887,275.99,6.17,2576 +Harimaya-Bashi,3.2,0.0640,28.87,124.21,233.82,2582 +Acamas,5.058,0.0860,25.874,2.50,280.24,2594 +Kathryn,2.894,0.1641,25.144,273.28,1.12,2612 +Plzen,3.045,0.0420,28.007,244.31,195.62,2613 +Jiangxi,3.154,0.2377,49.084,78.73,350.11,2617 +Goto,3.084,0.1757,44.723,345.52,271.76,2621 +Hermod,3.072,0.1268,25.165,223.99,23.93,2630 +Guizhou,3.039,0.1104,32.364,345.10,311.98,2632 +"James Bradley",3.458,0.0489,33.726,107.75,332.63,2634 +Millis,3.137,0.1004,27.878,228.30,333.57,2659 +Gramme,3.177,0.2258,30.364,122.57,208.05,2666 +Pandarus,5.194,0.0700,74.267,66.30,41.89,2674 +Magion,2.45,0.1149,25.418,34.92,283.77,2696 +Albina,3.558,0.0794,51.54,250.47,130.90,2697 +Ueferji,3.195,0.1173,25.838,324.76,344.43,2707 +Handley,3.118,0.1555,25.309,298.39,265.90,2718 +"David Bender",3.034,0.1523,36.974,43.22,28.44,2725 +Cucula,3.188,0.1891,44.841,316.09,133.36,2731 +Hasek,3.16,0.0159,25.409,77.22,141.17,2734 +"Cesky Krumlov",3.096,0.1287,29.804,113.77,300.91,2747 +Idomeneus,5.193,0.0648,53.676,235.12,8.18,2759 +Kacha,3.991,0.1193,57.90,307.00,150.48,2760 +Tenojoki,3.192,0.1383,35.697,319.47,107.02,2774 +Valdaj,3.169,0.0293,27.103,122.99,190.74,2793 +Teucer,5.109,0.0883,89.430,294.59,48.11,2797 +Zappala,3.136,0.1539,32.040,25.28,247.37,2813 +Pien,2.726,0.1889,28.256,263.63,264.93,2816 +Ahti,3.222,0.0491,39.975,278.79,146.89,2826 +Bobhope,3.091,0.1873,41.361,202.51,339.63,2829 +Ylppo,3.221,0.0727,27.994,225.45,71.92,2846 +ASP,3.207,0.1905,25.793,351.32,51.07,2848 +McGetchin,3.355,0.1382,35.066,166.48,251.30,2891 +Filipenko,3.172,0.2030,69.492,13.87,94.23,2892 +Peiroos,5.143,0.0774,86.884,351.25,172.85,2893 +Memnon,5.244,0.0488,56.706,237.79,274.98,2895 +Caltech,3.167,0.1039,58.678,62.92,296.94,2906 +Shimoyama,2.978,0.1550,29.663,306.35,153.60,2908 +Automedon,5.112,0.0278,88.574,341.30,197.09,2920 +Kempchinsky,3.633,0.1052,29.283,358.23,195.23,2932 +Perepadin,3.129,0.1179,46.653,242.49,121.85,2951 +Scholl,3.956,0.2722,32.783,281.46,284.75,2959 +Vladisvyat,3.196,0.1356,32.879,258.96,359.57,2967 +Lautaro,3.34,0.1457,46.184,74.70,188.05,2976 +Poltava,2.848,0.0578,30.690,146.95,86.74,2983 +Hainan,3.415,0.1309,37.189,152.54,341.65,3024 +Higson,3.201,0.0857,45.830,272.02,113.15,3025 +Zhangguoxi,3.019,0.0311,25.58,296.28,4.57,3028 +Krat,3.208,0.1007,43.101,256.58,320.01,3036 +Alku,2.674,0.1859,29.876,328.93,330.95,3037 +Alois,3.132,0.1075,27.493,45.49,330.52,3045 +Strugatskia,3.094,0.2098,26.921,70.14,186.95,3054 +Makhaon,5.218,0.0587,111.655,285.72,203.91,3063 +Horrocks,3.147,0.1046,28.284,284.76,140.47,3078 +Oujianquan,2.929,0.1862,35.887,172.42,184.11,3089 +Herodotus,3.537,0.1145,30.346,58.61,9.24,3092 +Omarkhayyam,3.494,0.0797,30.178,75.55,116.73,3095 +Morabito,3.142,0.2395,26.209,180.20,290.30,3106 +Claytonsmith,3.035,0.0568,36.569,69.53,259.17,3118 +Landgraf,3.144,0.1283,35.886,220.18,266.10,3132 +Kostinsky,3.984,0.2194,50.389,246.41,163.05,3134 +Shantou,3.195,0.0217,36.648,120.66,117.06,3139 +Buchar,3.42,0.0689,36.05,226.88,155.30,3141 +Tosa,3.202,0.1170,33.479,200.28,271.91,3150 +Jones,2.625,0.0896,30.952,17.51,289.99,3152 +Ellington,2.855,0.1970,30.794,132.59,119.06,3156 +Novikov,3.148,0.1478,29.876,233.17,322.37,3157 +Nostalgia,3.154,0.1562,28.690,141.79,315.37,3162 +Wangshouguan,3.181,0.1460,38.766,127.59,25.39,3171 +Paolicchi,2.875,0.0324,41.327,135.53,24.01,3176 +Graff,3.928,0.1138,35.910,137.95,268.18,3202 +Liller,3.094,0.0657,34.919,52.58,129.73,3222 +Victorplatt,3.012,0.0668,27.751,168.93,337.46,3237 +Laocoon,5.225,0.1284,51.695,319.32,16.01,3240 +Farinella,3.205,0.1518,36.553,218.00,317.16,3248 +Bus,3.97,0.1553,31.104,25.00,302.78,3254 +Brownlee,3.165,0.1224,25.579,61.05,314.61,3259 +Drukar,3.407,0.0237,27.397,240.60,226.04,3273 +Behounek,3.226,0.0132,31.455,164.00,98.93,3278 +Paris,5.223,0.1284,118.790,0.93,150.42,3317 +TARDIS,3.184,0.0181,28.238,324.16,85.26,3325 +Gantrisch,3.156,0.2011,34.877,217.03,306.37,3330 +Schaber,3.135,0.2210,26.538,221.67,66.48,3333 +Treshnikov,3.18,0.1329,33.541,251.56,147.73,3339 +Gerla,3.187,0.0467,34.628,128.91,21.67,3346 +Duncombe,3.385,0.0903,33.331,305.53,351.00,3368 +Sinon,5.298,0.0839,37.862,313.35,103.63,3391 +Muazzez,3.392,0.1792,32.519,50.60,315.53,3396 +Danby,3.966,0.2484,36.582,286.35,136.29,3415 +Guth,3.21,0.0649,34.589,330.73,226.21,3419 +Nakano,3.093,0.0484,44.339,297.99,45.25,3431 +Inarradas,3.046,0.2031,25.252,317.99,349.81,3438 +Yashin,3.146,0.1412,25.708,256.78,297.84,3442 +Mentor,5.158,0.0726,126.288,356.15,130.27,3451 +Amelin,3.19,0.0511,29.257,143.39,158.78,3471 +Fichte,3.173,0.1265,29.558,163.90,230.63,3475 +Dongguan,3.159,0.1949,31.53,224.32,25.37,3476 +Colchagua,3.221,0.1195,26.312,66.32,108.02,3495 +Protesilaos,5.282,0.1168,70.225,269.16,115.88,3540 +Eurybates,5.202,0.0903,63.885,354.54,27.20,3548 +Link,2.925,0.1586,26.515,345.25,29.84,3550 +Devine,3.959,0.1296,32.74,260.85,176.77,3561 +Talthybius,5.202,0.0383,73.730,168.37,203.19,3564 +Ojima,3.204,0.1236,28.129,37.70,346.42,3565 +Milanstefanik,3.936,0.1122,34.898,317.93,21.46,3571 +Putilin,3.94,0.1959,49.135,161.05,179.37,3577 +Carestia,3.216,0.2044,42.882,134.09,48.14,3578 +Aisha,3.086,0.1021,27.696,111.36,108.92,3584 +Meriones,5.178,0.0745,87.380,358.24,66.14,3596 +Tumilty,2.981,0.1308,47.829,117.94,311.25,3614 +Safronov,3.162,0.1327,25.209,102.06,111.74,3615 +Sigyn,3.093,0.0782,38.505,335.04,159.32,3631 +"Williams Bay",2.994,0.1272,29.710,145.62,293.51,3641 +Frieden,2.791,0.0793,31.899,180.69,15.58,3642 +Dermott,2.801,0.1033,26.754,13.31,218.41,3647 +Kunming,3.117,0.2423,26.645,333.92,285.26,3650 +Eupraksia,4.02,0.2020,36.657,139.86,39.58,3655 +Lazarev,3.223,0.0811,25.830,314.65,215.53,3660 +Dzus,2.727,0.1999,30.932,74.86,113.44,3687 +Barringer,3.147,0.2020,27.494,29.15,184.02,3693 +Sharon,3.93,0.2057,46.032,271.68,80.25,3694 +Socus,5.212,0.1594,75.661,292.60,57.70,3708 +Polypoites,5.23,0.0626,65.297,317.56,247.45,3709 +Maxhell,3.319,0.1508,27.691,236.93,162.41,3727 +Hurban,2.726,0.1621,26.996,251.33,42.72,3730 +Hancock,3.234,0.1141,53.112,160.39,255.05,3731 +Belinskij,3.185,0.1239,26.73,285.88,105.48,3747 +Kathleen,3.159,0.1069,53.699,43.57,55.22,3754 +Piironen,2.718,0.1180,32.15,178.04,165.75,3759 +Romanskaya,3.125,0.2814,32.882,164.51,83.70,3761 +Monroe,3.095,0.2148,26.601,168.61,224.07,3768 +Chopin,3.132,0.1638,29.346,241.08,192.87,3784 +Leonteus,5.221,0.0901,112.046,311.49,262.24,3793 +Sthenelos,5.205,0.1472,34.531,29.46,36.14,3794 +Thrasymedes,5.325,0.0241,34.285,342.38,205.85,3801 +Tuchkova,3.048,0.0503,38.019,82.47,275.09,3803 +Karma,2.577,0.1310,30.344,163.47,68.61,3811 +Lidaksum,3.175,0.1185,33.611,355.13,35.75,3812 +OISCA,3.984,0.1443,30.769,215.72,23.61,3843 +Neyachenko,3.429,0.1563,25.817,200.35,260.36,3845 +Yoritomo,3.224,0.0653,28.402,296.75,354.85,3902 +Chao,2.933,0.0701,46.247,228.40,208.65,3906 +Radzievskij,3.962,0.2205,29.870,227.19,283.00,3923 +Tret'yakov,3.158,0.1950,51.289,323.18,206.59,3925 +Huruhata,3.108,0.1022,30.644,113.17,251.37,3939 +Shekhtelia,3.256,0.0470,29.305,236.15,13.59,3967 +Voronikhin,2.851,0.1849,31.996,343.47,82.91,3971 +Lise,2.757,0.0708,29.049,74.37,102.10,3976 +Klepesta,2.886,0.0024,29.223,238.85,223.86,3978 +Heimdal,3.945,0.2420,35.675,111.94,197.89,3990 +Schumann,3.429,0.0943,36.115,230.92,117.33,4003 +Euryalos,5.182,0.0570,45.515,331.74,77.04,4007 +Heizman,3.419,0.0325,36.83,249.89,106.37,4014 +Thestor,5.281,0.0577,68.733,326.36,198.34,4035 +Miyamotoyohko,3.017,0.0553,26.244,84.24,159.94,4041 +Lowengrub,3.231,0.1004,31.322,196.50,245.19,4045 +Demophon,5.249,0.1205,45.683,311.39,59.91,4057 +Deipylos,5.242,0.1559,84.043,281.80,307.52,4060 +Euforbo,5.187,0.1194,95.619,341.58,318.50,4063 +Menestheus,5.143,0.0743,67.625,261.48,316.38,4068 +Rostovdon,3.204,0.1578,25.982,355.16,126.36,4071 +Podalirius,5.268,0.1222,85.495,9.04,356.70,4086 +Hrabal,3.119,0.0388,45.507,125.14,177.76,4112 +Stasik,3.167,0.1048,29.130,129.67,100.26,4131 +Kalchas,5.17,0.0447,46.462,39.65,165.64,4138 +Branham,3.004,0.1208,33.748,267.75,220.06,4140 +Vladvasil'ev,3.156,0.0332,32.494,46.03,228.55,4144 +Celsius,3.398,0.1625,37.303,30.79,32.14,4169 +Tamashima,3.107,0.0679,29.910,151.40,275.43,4186 +Shuya,3.895,0.0273,36.714,3.57,222.89,4196 +Orosz,3.161,0.2272,32.985,247.55,13.64,4201 +Kiselev,3.205,0.0718,30.413,44.85,218.47,4208 +Briggs,3.157,0.0818,31.303,116.11,13.42,4209 +Susa,2.918,0.1867,34.730,145.60,181.85,4224 +Damiaan,2.865,0.2560,33.065,238.61,133.00,4226 +"van den Bergh",3.945,0.1338,28.461,242.76,19.90,4230 +Lidov,3.439,0.0391,32.880,297.31,145.50,4236 +Garibaldi,3.989,0.1603,38.606,119.76,94.72,4317 +Bata,3.22,0.1034,25.790,124.79,96.44,4318 +Poulydamas,5.237,0.0980,82.032,257.80,159.67,4348 +Tiburcio,2.618,0.2425,28.091,242.35,281.32,4349 +Ortizmoreno,3.245,0.0587,30.74,276.47,34.64,4436 +Sykes,3.163,0.2537,26.693,322.24,291.95,4438 +Carolyn,3.989,0.2815,28.645,249.22,117.26,4446 +Sobinov,3.138,0.0963,30.02,170.33,309.69,4449 +Bihoro,2.92,0.1843,38.742,290.40,30.91,4460 +Dracius,5.199,0.0619,76.595,289.97,7.86,4489 +Eurypylos,5.218,0.0539,45.524,357.86,179.62,4501 +Phoinix,5.135,0.0973,63.836,19.55,84.80,4543 +Massachusetts,2.613,0.0682,33.036,0.53,37.27,4547 +Fanynka,3.187,0.1184,26.315,198.28,4.46,4554 +Pizarro,3.11,0.1055,29.012,276.44,119.79,4609 +Zadunaisky,3.211,0.0706,32.685,345.79,270.95,4617 +Falta,3.212,0.0620,28.824,171.59,12.29,4663 +Takuboku,3.188,0.0480,28.115,286.65,177.02,4672 +Khryses,5.196,0.1219,37.766,273.98,66.23,4707 +Polydoros,5.247,0.0607,54.964,239.49,103.04,4708 +Ennomos,5.266,0.0228,91.433,328.95,76.74,4709 +Iwaizumi,3.146,0.1374,28.778,295.79,350.42,4712 +Medesicaste,5.111,0.0502,62.097,301.64,344.18,4715 +Agelaos,5.204,0.1120,50.378,258.27,315.17,4722 +Froeschle,3.159,0.0725,29.981,300.88,143.71,4732 +Panthoos,5.27,0.0098,53.025,327.32,175.13,4754 +Hartley,3.171,0.2384,34.349,308.08,26.54,4768 +Frankdrake,3.162,0.0693,27.570,270.20,184.81,4772 +Iphidamas,5.159,0.0454,49.528,211.85,163.84,4791 +Lykaon,5.253,0.0924,50.870,289.15,283.61,4792 +Asteropaios,5.201,0.0916,57.647,261.76,90.02,4805 +Dares,5.131,0.0433,42.770,240.72,168.21,4827 +Misenus,5.164,0.0411,45.954,153.26,129.59,4828 +Sergestus,5.178,0.0495,32.220,321.40,118.99,4829 +Palinurus,5.263,0.1414,52.058,299.36,209.67,4832 +Meges,5.231,0.0930,80.165,8.95,281.26,4833 +Thoas,5.207,0.1378,72.331,325.57,352.58,4834 +Asaeus,5.197,0.2520,30.175,292.94,355.22,4835 +Medon,5.214,0.1086,63.277,302.21,33.91,4836 +Bickerton,3.197,0.1379,28.328,179.12,45.47,4837 +Megantic,3.091,0.1176,26.690,68.78,222.89,4843 +Gubbio,2.632,0.1454,25.733,226.89,15.73,4860 +Polites,5.17,0.0193,57.251,35.26,280.60,4867 +Tomoegozen,3.106,0.1705,28.787,197.03,98.47,4896 +Thessandrus,5.203,0.0438,51.263,320.45,270.91,4902 +Rephiltim,3.123,0.0517,35.676,8.18,358.40,4930 +Texstapa,3.113,0.0159,25.603,61.12,291.35,4932 +Askalaphus,5.321,0.0490,48.209,132.05,206.38,4946 +Niinoama,3.149,0.0104,35.842,54.89,317.53,4959 +Glia,3.151,0.0380,30.022,135.20,229.31,4967 +Showa,3.43,0.0766,27.958,59.45,130.34,4973 +Eurymedon,5.264,0.0865,36.960,29.24,335.12,5012 +Roccapalumba,3.15,0.0850,32.547,194.25,68.26,5022 +Agapenor,5.164,0.0529,27.850,358.85,87.31,5023 +Bechmann,3.226,0.0550,26.630,359.45,120.66,5024 +Mecisteus,5.193,0.0763,39.843,337.31,74.16,5025 +Androgeos,5.302,0.0668,59.786,332.49,345.17,5027 +Halaesus,5.26,0.1315,50.770,346.54,11.90,5028 +Theotes,5.195,0.0352,41.899,291.80,103.89,5041 +Arai,3.108,0.0647,28.47,125.23,188.82,5070 +Imbrius,5.199,0.1099,49.251,311.39,16.79,5119 +Bitias,5.267,0.1122,47.987,311.89,24.11,5120 +Cynus,5.228,0.1031,35.387,288.74,32.22,5123 +Achaemenides,5.245,0.0260,51.922,297.99,350.49,5126 +Ilioneus,5.198,0.0121,60.711,270.11,105.70,5130 +Achates,5.186,0.2732,80.958,331.74,331.79,5144 +Pholus,20.33,0.5705,190,119.58,354.71,5145 +Gierasch,2.657,0.1739,27.494,21.97,39.77,5153 +Yabuki,3.189,0.0877,31.503,255.00,300.63,5192 +Oloosson,5.203,0.0513,48.197,5.79,104.51,5209 +Nastes,5.149,0.0449,29.035,93.69,47.10,5233 +Amphilochos,5.18,0.0289,36.689,72.69,128.38,5244 +Ulysses,5.226,0.1228,76.147,336.35,344.09,5254 +Rhoeo,5.166,0.0781,53.275,273.94,230.09,5258 +Epeigeus,5.21,0.0722,44.741,142.19,201.31,5259 +Brucegoldberg,3.081,0.1699,33.25,208.81,93.41,5262 +Arrius,3.201,0.0144,25.615,136.25,320.76,5263 +Telephus,5.209,0.1120,68.472,284.00,359.15,5264 +Pyrrhus,5.196,0.1505,48.356,335.79,356.78,5283 +Orsilocus,5.226,0.0845,50.159,319.45,343.25,5284 +Krethon,5.186,0.0509,49.606,30.39,257.04,5285 +Filatov,3.158,0.0234,45.693,287.68,252.76,5316 +Missing,3.112,0.1461,25.260,193.06,64.05,5336 +Aoki,3.2,0.0971,30.782,128.05,3.12,5337 +Rozhdestvenskij,3.238,0.0141,28.062,349.64,21.46,5360 +Vitagliano,3.966,0.0816,34.807,129.90,338.45,5368 +Hokutosei,3.169,0.1011,38.657,230.73,249.98,5374 +Kameoka,3.155,0.1267,26.301,276.49,3.36,5435 +Eumelos,5.203,0.0781,37.696,291.16,220.73,5436 +Lorre,2.748,0.2758,28.072,113.69,238.65,5438 +Mulius,5.112,0.0749,35.096,354.67,95.66,5476 +Rumyantsev,3.413,0.0481,25.518,340.34,278.18,5495 +Cloanthus,5.247,0.1182,39.773,355.34,121.59,5511 +Durisen,2.94,0.2196,36.475,120.03,308.07,5567 +Jimmiller,3.165,0.0510,25.856,223.01,111.21,5594 +Rausudake,3.982,0.0526,45.677,235.71,9.10,5603 +Gyas,5.168,0.1196,28.168,329.82,331.13,5637 +Deikoon,5.238,0.1068,41.455,14.31,92.87,5638 +Axius,5.144,0.1669,59.295,296.14,269.02,5648 +Traversa,3.142,0.1584,26.88,313.77,228.87,5651 +Amphimachus,5.212,0.0772,53.921,18.15,108.82,5652 +Hildebrand,3.964,0.2355,34.37,245.15,1.82,5661 +Rosstaylor,3.177,0.1107,29.619,78.81,197.61,5670 +Eneev,3.943,0.1647,38.81,242.69,296.01,5711 +Somerville,3.14,0.2164,28.306,57.03,103.15,5771 +Peterson,3.493,0.0326,27.077,142.03,110.98,5833 +Bhanji,3.178,0.0081,28.39,200.97,109.93,5849 +Mickiewicz,3.046,0.1569,26.414,351.97,39.88,5889 +Rhigmus,5.146,0.0986,31.248,34.50,141.99,5907 +Kathywhaler,3.539,0.0899,38.097,305.42,247.35,5914 +Shouichi,3,0.1132,29.417,231.59,148.76,5922 +Pindarus,3.97,0.1193,30.402,117.43,104.68,5928 +Eetion,5.226,0.0921,40.408,279.70,158.64,6002 +Robbia,3.324,0.1005,29.368,124.98,192.74,6057 +Aulis,5.3,0.0583,59.568,348.72,74.59,6090 +Missing,3.427,0.1952,28.761,119.31,149.61,6103 +Johnfletcher,3.213,0.0632,30.720,212.78,86.03,6137 +Kondojiro,4.769,0.3597,32.492,243.25,96.35,6144 +Missing,3.253,0.1234,27.451,142.61,132.10,6222 +Chikushi,3.934,0.0722,37.4,335.32,207.15,6237 +Univermoscow,3.199,0.0796,28.38,155.40,232.73,6355 +Dubinin,3.205,0.1062,31.902,275.65,39.90,6359 +Walker,3.181,0.1612,42.129,136.91,187.53,6372 +Takashimizuno,3.215,0.1333,25.221,123.09,246.84,6392 +Refugium,3.142,0.1607,29.642,67.11,75.10,6475 +Leitus,5.158,0.0522,50.951,359.92,147.91,6545 +Gvishiani,3.398,0.1921,25.393,189.28,240.47,6574 +Kolya,3.169,0.1858,29.519,116.99,112.27,6619 +Missing,3.186,0.0960,27.930,79.11,119.56,6785 +Masuisakura,3.086,0.2129,26.82,309.57,348.42,6794 +Fukui,3.391,0.0997,29.616,231.44,289.62,6924 +Komatsusakyo,3.214,0.1234,26.889,58.08,228.01,6983 +Lewiscarroll,3.973,0.1869,48.053,192.98,247.94,6984 +Laomedon,5.176,0.1022,37.549,28.04,58.65,6997 +Tithonus,5.178,0.0714,27.828,341.71,259.42,6998 +Hiera,5.13,0.1040,59.150,342.61,123.35,7119 +Longtom,3.178,0.1683,29.896,117.74,290.46,7131 +Euneus,5.154,0.0648,39.770,345.26,306.93,7152 +Semois,3.994,0.1757,25.526,112.21,290.16,7174 +Hypsenor,5.127,0.0376,47.731,14.28,128.11,7352 +Xanthomalitia,3.926,0.0352,32.471,226.45,190.64,7394 +Prylis,5.2,0.0646,42.893,17.76,207.16,7543 +Missing,3.21,0.1458,37.034,44.41,260.75,7588 +Cindygraber,3.152,0.0737,38.463,25.72,271.37,7605 +Cteatus,5.216,0.0541,71.839,289.20,227.43,7641 +Dolon,5.267,0.0600,42.516,262.32,218.66,7815 +Kaseda,3.147,0.1515,28.51,279.18,37.20,7895 +Nesvorny,3.049,0.0877,25.143,144.77,164.64,7999 +Anius,5.203,0.0931,37.873,23.89,33.58,8060 +Peterthomas,3.946,0.2078,25.629,60.21,287.62,8086 +Tyndareus,5.196,0.0485,27.088,49.66,57.77,8125 +Agrius,5.157,0.0429,27.174,136.21,265.91,8241 +Eurysaces,5.309,0.0464,26.210,93.67,116.06,8317 +Missing,3.989,0.1981,27.689,253.69,257.79,8376 +Asbolus,18.04,0.6211,66,91.41,290.64,8405 +AMOS,3.886,0.0283,49.91,239.77,85.11,8721 +Sawaishujiro,3.93,0.0511,30.135,28.68,327.15,8915 +Tianjindaxue,3.408,0.1191,37.122,68.28,169.57,8917 +Mnesthus,5.217,0.0655,49.151,306.76,159.45,9023 +Othryoneus,5.312,0.0159,32.186,212.50,13.28,9030 +Rhesus,5.161,0.1309,42.306,316.30,173.75,9142 +Erichthonios,5.261,0.0545,27.532,352.02,311.61,9430 +Pytho,5.116,0.0866,38.358,14.81,185.63,9431 +Hohmann,3.958,0.2339,27.664,352.90,288.11,9661 +Lycomedes,5.082,0.0380,31.736,341.24,59.26,9694 +Nauplius,5.228,0.1283,33.423,311.20,274.42,9712 +Deipyrus,5.242,0.0559,32.771,12.75,152.58,9790 +Thronium,5.19,0.0486,68.033,25.99,115.41,9799 +Eurymachos,5.197,0.0047,28.076,268.94,102.14,9818 +Murillo,3.949,0.1269,25.941,224.63,4.29,9829 +Hecamede,5.161,0.0262,49.518,124.74,6.77,9857 +Malytheatre,3.144,0.1148,25.855,344.30,244.46,10007 +Chariklo,15.82,0.1677,302,103.26,242.87,10199 +Amphiaraos,5.278,0.0072,26.826,314.55,325.68,10247 +Mameta,3.995,0.2557,25.184,52.42,258.23,10608 +Phemios,5.196,0.0311,30.963,316.41,231.89,10664 +Missing,3.935,0.0685,33.20,269.47,173.28,10889 +Missing,5.181,0.0204,37.047,118.25,18.42,11089 +Laertes,5.14,0.0315,41.093,355.29,327.70,11252 +Missing,5.194,0.0909,25.570,308.13,217.41,11275 +Leucus,5.298,0.0654,34.155,11.98,160.41,11351 +Iphinous,5.214,0.0677,68.977,71.20,119.53,11395 +Missing,5.215,0.0650,37.109,32.49,177.77,11396 +Missing,5.261,0.0630,45.431,21.78,151.29,11397 +Alcinoos,5.33,0.0144,32.354,343.95,57.52,11428 +Demodokus,5.236,0.0313,37.630,286.09,91.39,11429 +Missing,5.149,0.0485,32.139,298.06,6.46,11487 +Thersilochos,5.175,0.1438,49.960,299.88,128.50,11509 +Solikamsk,3.949,0.2400,29.686,211.73,49.29,11542 +Boucolion,5.274,0.1534,51.136,334.63,182.24,11552 +Asios,5.279,0.0651,41.561,35.42,127.67,11554 +Missing,5.134,0.1281,31.327,324.79,89.12,11663 +Missing,5.233,0.0434,26.794,321.60,159.56,11869 +Echemmon,5.181,0.0927,31.190,289.22,111.56,11887 +Angel,3.201,0.1578,27.233,327.02,220.74,11911 +Aretaon,5.227,0.0693,39.151,311.12,87.19,12052 +Missing,5.215,0.2094,53.202,335.00,304.47,12126 +Imranakperov,3.2,0.1074,25.452,66.66,82.30,12235 +Actor,5.174,0.1250,30.252,2.51,177.86,12238 +Koon,5.107,0.0685,37.861,337.73,93.41,12242 +Yoshitoki,3.171,0.0334,27.53,269.68,73.73,12365 +Prothoon,5.238,0.0725,63.835,354.49,65.76,12444 +Missing,3.203,0.0363,30.143,149.11,275.20,12559 +Buckjean,2.984,0.0692,25.76,97.93,17.88,12583 +Ascanios,5.155,0.1487,25.102,330.87,342.16,12649 +Peiraios,5.175,0.0580,26.458,353.34,325.51,12658 +Alkimos,5.239,0.0367,47.819,314.92,161.91,12714 +Missing,5.241,0.0939,32.174,328.07,273.81,12921 +Periboea,5.244,0.0404,54.077,330.41,128.73,12929 +Missing,3.975,0.1595,27.435,127.53,211.56,13035 +Missing,5.148,0.1240,36.148,16.90,97.51,13060 +Podarkes,5.175,0.0119,28.958,60.10,285.17,13062 +Missing,5.214,0.1138,30.901,24.65,66.65,13182 +Missing,5.221,0.0905,41.483,89.21,315.53,13183 +Augeias,5.177,0.0494,33.962,95.68,99.12,13184 +Echion,5.261,0.0746,27.554,271.65,166.30,13229 +Dannymeyer,3.161,0.0119,31.63,171.55,329.17,13244 +Missing,5.179,0.0275,28.324,220.22,118.03,13362 +Missing,5.223,0.1053,33.302,308.67,355.80,13366 +Missing,5.24,0.0484,25.420,8.82,304.43,13372 +Missing,5.233,0.0459,36.053,82.55,167.82,13385 +Antiphos,5.191,0.0080,25.326,8.94,86.33,13463 +Missing,5.265,0.0705,29.285,23.12,164.18,13694 +Missing,3.365,0.1122,37.543,59.16,127.55,13832 +Neely,3.113,0.1987,26.385,115.45,186.55,13860 +Missing,5.14,0.0853,28.530,357.89,25.33,14235 +Missing,5.214,0.0921,57.54,333.50,127.77,14268 +Missing,5.211,0.0321,43.169,43.79,6.93,14690 +Missing,5.239,0.0417,25.942,354.45,286.29,14707 +Masanoriabe,3.198,0.0223,25.708,349.27,340.24,14962 +Missing,5.177,0.2036,33.292,345.93,165.09,15033 +Missing,3.217,0.2020,35.539,172.53,99.82,15161 +Paquet,3.985,0.2163,25.417,231.14,64.33,15278 +Missing,5.132,0.0256,35.516,263.59,315.55,15398 +Dexius,5.211,0.0452,87.646,332.15,179.07,15436 +Eioneus,5.294,0.0233,62.519,350.05,283.98,15440 +Missing,5.122,0.0149,53.100,147.04,180.08,15502 +Missing,5.244,0.0695,27.941,231.95,170.86,15521 +Missing,5.212,0.1545,36.433,60.52,168.83,15527 +Missing,5.182,0.0850,39.767,319.77,302.17,15535 +Missing,5.208,0.1442,28.974,321.95,258.90,15536 +Missing,5.269,0.0456,42.208,293.73,333.41,15539 +Missing,3.151,0.1961,29.594,300.07,217.63,15562 +Missing,3.993,0.1852,32.265,174.05,224.61,15638 +Periphas,5.198,0.1055,36.200,18.44,24.01,15663 +Missing,39.74,0.1886,328,72.45,318.44,15789 +Missing,5.176,0.0474,43.530,191.36,227.65,15977 +Charops,5.139,0.1260,63.191,358.88,353.76,16070 +Missing,5.187,0.0830,36.774,30.69,278.12,16099 +Missing,3.102,0.0195,25.982,199.72,176.49,16133 +Missing,3.192,0.1016,27.713,318.52,83.06,16461 +Daitor,5.059,0.0421,43.861,24.40,159.87,16560 +Missing,5.198,0.2003,35.390,298.75,239.31,16667 +Missing,3.156,0.0983,31.056,245.13,90.00,16785 +Missing,5.223,0.1135,38.583,283.76,202.72,16956 +Missing,3.967,0.1126,25.310,102.19,40.81,16970 +Iphthime,5.18,0.0708,57.341,16.59,137.04,16974 +Missing,2.77,0.1708,27.04,244.59,82.67,17109 +Missing,5.137,0.0835,40.946,331.14,356.99,17171 +Missing,5.221,0.0582,34.482,304.14,214.76,17172 +Missing,3.124,0.2243,25.232,260.39,229.37,17252 +Missing,3.173,0.1033,29.731,289.79,18.01,17297 +Caniff,4.002,0.1363,25.368,144.06,118.95,17305 +Aisakos,5.166,0.0737,35.761,199.73,84.91,17314 +Pheidippos,5.16,0.0979,28.749,352.06,46.79,17351 +Missing,5.271,0.0781,44.904,273.31,117.32,17365 +Missing,5.165,0.0838,27.569,292.94,236.35,17417 +Missing,5.223,0.0642,33.138,284.56,330.12,17419 +Charleroi,3.934,0.1145,30.297,16.75,327.30,17428 +Hippasos,5.176,0.0723,53.975,2.46,216.36,17492 +Missing,5.202,0.0587,42.736,315.94,153.09,18046 +Missing,5.243,0.0188,36.222,40.99,129.92,18054 +Zarex,5.124,0.0578,36.431,21.79,154.08,18060 +Missing,5.147,0.0500,30.334,326.48,34.20,18062 +Missing,5.157,0.0580,31.122,24.82,65.10,18063 +Missing,5.103,0.0161,33.664,198.08,203.84,18137 +Drymas,5.178,0.0686,28.885,32.88,208.44,18278 +Missing,3.102,0.0851,27.533,282.43,16.36,18331 +Demoleon,5.288,0.0933,33.474,322.90,90.17,18493 +Missing,5.216,0.1003,32.111,304.65,122.25,19018 +Missing,5.209,0.1138,42.613,321.83,224.71,19020 +Missing,5.146,0.0740,31.668,309.35,36.21,19725 +Missing,3.071,0.0631,47.698,20.21,114.07,19737 +Missing,5.194,0.0505,37.972,339.31,103.64,19844 +Varuna,42.76,0.0578,900,118.82,264.39,20000 +Missing,5.19,0.0108,27.467,219.39,154.28,20144 +Missing,5.208,0.1307,45.804,326.30,4.87,20424 +Missing,5.199,0.1470,27.176,341.92,6.22,20428 +Missing,5.23,0.1294,26.367,20.05,271.97,20716 +Missing,5.284,0.1467,34.120,304.14,351.93,20720 +Missing,5.218,0.0652,50.961,7.30,92.92,20729 +Missing,5.207,0.1371,27.043,279.12,183.51,20739 +Fountainhills,4.287,0.4688,37.31,124.02,236.35,20898 +Missing,5.094,0.1154,26.203,330.01,10.80,20995 +Pandion,5.217,0.1026,28.550,27.32,183.89,21284 +Missing,5.194,0.0738,29.196,291.80,48.08,21370 +Missing,5.206,0.1356,35.178,6.45,258.28,21595 +Missing,5.205,0.1175,28.312,334.09,210.99,21599 +Missing,5.234,0.0357,54.909,325.40,209.45,21601 +Orus,5.124,0.0377,50.810,323.10,180.38,21900 +Missing,5.153,0.1065,39.487,298.70,202.37,22014 +Missing,5.179,0.0370,27.680,346.60,322.99,22052 +Missing,5.199,0.0528,34.000,259.11,230.44,22054 +Missing,5.259,0.0257,31.816,107.26,215.10,22055 +Missing,5.192,0.1092,25.376,241.04,320.81,22059 +Missing,5.167,0.0444,48.190,257.46,225.64,22149 +Missing,5.177,0.0712,39.753,242.67,145.45,22180 +Missing,5.198,0.1724,33.744,333.86,320.41,23075 +Missing,3.141,0.1143,29.213,328.20,11.64,23099 +Missing,5.256,0.1327,32.954,25.98,63.08,23119 +Missing,5.339,0.0592,25.883,325.67,124.80,23123 +Pheidas,5.266,0.0504,66.230,272.14,253.68,23135 +Missing,4.002,0.1244,28.210,31.24,102.08,23186 +Missing,5.109,0.0562,29.690,307.01,132.79,23285 +Missing,5.177,0.0485,26.310,263.87,270.57,23463 +Missing,5.206,0.0854,27.621,178.44,302.52,23480 +Missing,5.228,0.1624,27.292,333.67,235.38,23624 +Missing,5.217,0.0373,32.389,311.08,225.13,23694 +Missing,5.231,0.0999,46.001,302.12,234.54,23958 +Missing,5.255,0.1619,31.358,301.80,28.76,23968 +Missing,5.266,0.0670,32.404,312.77,12.26,23970 +Missing,5.192,0.0459,35.342,328.60,164.39,24244 +Missing,5.122,0.0440,28.389,268.35,216.78,24275 +Missing,5.249,0.1062,25.545,53.68,291.05,24312 +Missing,5.264,0.0865,34.591,6.51,356.94,24313 +Dorippe,5.261,0.0830,31.607,13.81,35.81,24380 +Missing,5.259,0.0561,25.380,274.20,342.71,24390 +Missing,5.278,0.0286,29.392,304.69,326.79,24403 +Missing,3.159,0.1898,25.004,123.36,301.03,24440 +Missing,5.227,0.0814,31.392,270.08,68.61,24446 +Missing,5.155,0.0536,25.907,272.23,198.34,24448 +Missing,5.284,0.1303,40.666,285.43,323.63,24451 +Missing,5.16,0.0549,27.932,330.55,356.65,24453 +Missing,5.072,0.0326,28.224,302.29,258.28,24454 +Missing,5.224,0.0925,25.686,24.25,3.17,24458 +Missing,5.262,0.1192,28.326,316.00,6.99,24459 +Missing,5.238,0.0853,33.067,331.66,67.35,24470 +Missing,5.318,0.0455,29.125,257.38,139.20,24471 +Missing,5.192,0.0445,28.723,287.72,136.39,24472 +Missing,5.145,0.0426,26.422,64.06,191.56,24485 +Missing,5.18,0.0763,33.157,71.04,140.81,24486 +Missing,5.24,0.0496,31.888,76.70,349.07,24505 +Missing,5.323,0.0304,39.052,298.80,124.97,24506 +Missing,5.22,0.0876,26.279,273.89,137.14,24519 +Missing,5.141,0.1193,25.883,9.59,249.90,24530 +Missing,5.211,0.0833,29.913,85.97,306.18,24534 +Missing,5.173,0.0829,31.158,10.07,15.13,24537 +Kapaneus,5.184,0.0100,25.738,256.84,340.60,24587 +Missing,5.243,0.0724,28.649,284.77,164.21,25347 +Missing,5.149,0.0235,29.842,37.96,30.46,25883 +Missing,5.217,0.0749,33.195,168.00,167.98,25895 +Missing,3.097,0.2137,27.139,288.88,56.11,29564 +Missing,5.141,0.0347,32.512,323.15,190.71,29603 +Missing,3.12,0.1548,40.347,121.67,26.24,29943 +Missing,5.162,0.0090,33.952,231.01,102.69,29976 +Missing,5.223,0.0894,33.098,343.48,156.37,29977 +Missing,5.26,0.0419,36.422,82.86,282.98,30102 +Missing,5.224,0.0627,29.232,56.98,287.87,30504 +Missing,5.208,0.0811,25.838,257.00,195.50,30505 +Missing,5.126,0.0819,34.356,291.78,11.33,30506 +Phegeus,5.252,0.0404,27.002,354.73,283.49,30704 +Idaios,5.194,0.0606,44.546,260.00,342.12,30705 +Echepolos,5.203,0.0127,25.351,220.59,19.16,30708 +Helicaon,5.2,0.0650,32.544,244.52,270.26,30942 +Missing,5.225,0.0774,47.396,348.55,191.80,31342 +Agathon,5.345,0.0386,40.645,279.48,325.97,31344 +Missing,5.248,0.0096,29.730,28.48,286.88,31819 +Elatus,11.76,0.3850,57.000,209.83,281.65,31824 +Missing,5.131,0.0527,26.904,349.18,350.94,31835 +Missing,3.186,0.0961,26.399,238.11,74.11,32253 +Missing,5.216,0.1099,27.968,191.37,274.32,32339 +Missing,5.239,0.0093,30.763,345.47,170.39,32397 +Missing,5.216,0.1264,30.829,356.13,344.10,32435 +Missing,5.197,0.1241,28.865,338.26,30.37,32437 +Missing,5.16,0.0284,29.252,349.88,352.59,32440 +Missing,5.217,0.0999,26.879,307.96,65.20,32451 +Missing,5.243,0.0160,30.260,153.48,263.91,32464 +Missing,5.209,0.0963,38.365,333.85,286.62,32475 +Missing,5.244,0.0930,29.583,301.66,207.34,32480 +Missing,5.141,0.0278,27.868,12.79,220.12,32482 +Missing,5.278,0.0795,48.017,313.96,274.24,32496 +Missing,5.17,0.1624,38.923,314.51,245.48,32499 +Missing,5.218,0.0697,35.619,51.35,180.49,32501 +Thereus,10.6,0.2002,86.500,237.49,87.25,32532 +Missing,5.158,0.0336,36.180,281.56,226.21,32615 +Apisaon,5.279,0.0783,28.249,83.42,159.84,32811 +Missing,5.1,0.0746,28.921,324.25,318.34,34521 +Missing,5.213,0.0988,33.306,324.27,266.67,34642 +Thoon,5.157,0.0388,61.684,338.40,197.59,34746 +Missing,5.142,0.0397,29.077,341.48,90.14,34785 +Missing,5.157,0.0761,25.296,55.26,358.70,35276 +Missing,5.09,0.0439,34.836,0.34,359.16,35673 +Missing,5.182,0.0923,39.393,73.73,10.30,36267 +Missing,5.314,0.1010,30.752,317.99,7.20,36279 +Missing,5.16,0.0225,32.117,327.66,346.58,36624 +Missing,5.25,0.0767,26.879,264.59,255.45,37297 +Missing,5.162,0.1029,25.017,313.90,128.46,37299 +Missing,5.181,0.0527,27.099,254.43,167.52,37301 +Amphios,5.21,0.0072,33.076,323.63,292.83,37519 +Bias,5.198,0.0777,61.603,328.03,192.86,38050 +Missing,5.229,0.0127,29.497,185.22,303.76,38610 +Missing,5.248,0.0717,35.944,359.58,206.57,39264 +Missing,5.166,0.0577,33.218,150.70,262.54,39369 +Missing,5.266,0.0895,26.068,345.97,220.28,39474 +Missing,5.162,0.0580,34.950,294.34,285.54,41340 +Missing,5.12,0.0615,31.006,328.10,343.04,41379 +Missing,5.207,0.0324,38.322,131.65,257.18,42187 +Typhon,37.62,0.5339,192.000,24.55,158.77,42355 +Missing,5.22,0.0430,32.160,262.51,341.34,42367 +Missing,5.127,0.0289,27.397,87.08,134.01,42554 +Missing,3.379,0.0816,27.208,324.01,152.53,43390 +Missing,3.343,0.2010,27.818,9.25,88.73,44566 +Missing,5.276,0.0857,26.634,314.81,154.86,47957 +Missing,5.263,0.0297,26.772,342.29,105.91,47963 +Missing,5.149,0.0300,36.052,278.67,287.11,48438 +Missing,5.19,0.0911,28.043,227.08,303.92,48764 +Missing,5.191,0.0547,27.121,280.86,21.96,51350 +Missing,5.149,0.1078,28.731,323.00,58.80,51354 +Missing,5.275,0.0987,27.850,200.14,6.05,51364 +Missing,5.217,0.0573,40.606,354.59,257.58,51365 +Missing,5.166,0.0868,26.350,319.75,298.74,51910 +Missing,5.109,0.1104,27.223,324.56,277.76,51958 +Missing,5.189,0.0579,27.479,25.89,302.65,51962 +Ophelestes,5.292,0.0255,25.070,328.45,200.88,52767 +Okyrhoe,8.375,0.3034,36.000,209.17,337.51,52872 +Missing,5.149,0.0947,25.302,0.33,129.88,53418 +Missing,5.058,0.0119,28.399,350.21,299.98,53436 +Bienor,16.49,0.2001,187.500,327.94,152.70,54598 +Missing,5.289,0.0792,37.743,357.09,178.65,54656 +Missing,5.106,0.0476,28.643,1.67,178.32,55060 +Missing,5.255,0.0465,31.406,344.23,167.82,55419 +Missing,5.135,0.0456,26.631,41.21,54.02,55563 +Missing,5.127,0.0349,27.608,39.70,321.47,55568 +Amycus,25.12,0.3919,100.900,54.21,239.63,55576 +Missing,5.203,0.0361,25.865,140.33,258.48,56968 +Missing,5.229,0.0247,28.255,207.71,316.89,57714 +Missing,5.176,0.0423,25.338,196.87,340.18,58008 +Palmys,5.258,0.0998,27.753,14.81,134.57,58931 +Missing,5.279,0.0725,34.916,90.56,71.24,60383 +Echeclus,10.73,0.4574,59.000,69.05,163.21,60558 +Missing,5.23,0.0778,26.466,77.31,351.93,62426 +Missing,5.216,0.1259,29.767,156.92,259.37,63273 +Missing,5.208,0.0263,28.373,44.09,88.34,68444 +Missing,5.286,0.0144,27.855,33.09,121.44,68519 +Missing,5.264,0.0945,33.098,320.01,256.57,76857 +Missing,5.167,0.0305,42.849,300.51,298.10,76867 +Missing,5.198,0.1478,28.432,347.69,346.18,80119 +Missing,5.237,0.0785,29.391,97.29,72.50,90337 +Missing,23.17,0.2226,230.500,7.48,156.01,95626 +Missing,5.322,0.0858,26.242,340.62,217.84,99334 +Missing,5.252,0.0573,30.603,318.56,187.43,117447 +Missing,20.8,0.4715,82.000,58.43,116.74,120061 +Missing,65.87,0.6819,170.000,9.04,27.63,127546 +Missing,5.284,0.0692,26.632,23.95,156.65,128299 +Missing,5.232,0.0878,28.299,52.18,55.51,134720 +Missing,5.282,0.0959,25.881,29.65,35.69,134749 +Missing,5.268,0.0488,26.039,320.39,60.27,134957 +Missing,20.06,0.2564,118.000,43.51,70.00,136204 +Missing,28.87,0.6748,37.700,26.95,90.69,148975 +Missing,5.254,0.0880,27.048,8.99,14.71,159342 +Missing,22.16,0.4608,78.440,40.16,70.82,248835 +Missing,12.54,0.3152,38.900,102.71,99.31,250112 +Missing,14.69,0.3087,58.000,50.25,141.72,281371 +Missing,15.81,0.3789,39.100,109.19,134.23,309139 +Missing,29.83,0.5641,110.060,26.28,108.39,310071 +Missing,13.2,0.3063,44.200,90.32,136.41,328884 +Missing,12.74,0.4461,33.000,66.18,240.43,332685 +Missing,279.6,0.9663,44.200,0.86,132.79,336756 +Missing,11.58,0.4418,67.100,99.59,330.35,342842 +Missing,35.2,0.6783,28.500,22.53,246.12,413666 +Missing,385.1,0.9841,46.400,0.46,178.90,"2010 BK118" +Missing,21.62,0.5603,26.900,46.86,238.70,"2010 ES65" +Missing,24.5,0.7621,28.000,35.14,314.29,"2010 FH92" +Missing,18.57,0.3246,69.900,79.80,210.41,"2010 TH" +Missing,53.44,0.6496,112.700,14.68,292.88,"2010 WG9" +Missing,21.28,0.4734,63.700,62.50,7.59,"2011 MM4" +Schwassmann-Wachmann,6,0.0436,60.4,197.11,50.64,29P +Swift-Tuttle,26.09,0.9632,26,7.63,152.98,109P +CINEOS,16.14,0.2700,66.170,16.20,343.65,167P +Hale-Bopp,182.1,0.9950,60,1.68,130.66,"1995 O1" +Spacewatch,38.41,0.8729,55.100,0.10,180.60,"2011 KP36" diff --git a/data/sol_planets.csv b/data/sol_planets.csv new file mode 100644 index 0000000..819f9c4 --- /dev/null +++ b/data/sol_planets.csv @@ -0,0 +1,9 @@ +Mercury,Sol,0.387098,0.205630,0.055,0.3829,174.796,29.124 +Venus,Sol,0.723332,0.006772,0.815,0.9499,50.115,54.884 +Earth,Sol,1.0,0.0167086,1.0,1.0,358.617,114.20783 +Mars,Sol,1.523680,0.0934,0.107,0.533,19.412,286.5 +Jupiter,Sol,5.2038,0.0483,317.8,10.973,20.020,273.867 +Saturn,Sol,9.5826,0.0565,95.159,9.1402,317.020,339.392 +Uranus,Sol,19.19126,0.04717,14.536,4.0,142.2386,96.998857 +Neptune,Sol,30.07,0.008678,17.147,3.883,256.228,273.187 +Pluto,Sol,39.482,0.2488,0.00218,0.1868,14.53,113.834 diff --git a/data/sol_satellites.csv b/data/sol_satellites.csv new file mode 100644 index 0000000..993eb9d --- /dev/null +++ b/data/sol_satellites.csv @@ -0,0 +1,211 @@ +Luna,Earth,0.00257,0.0549,0.0123,0.2727,128.0,128.0 +Hydra,Pluto,0.000432493,0.006,8.02782e-09,0.00290378,330.6,143.4 +Charon,Pluto,0.000131018,0,0.00026562,0.0951185,192.4,0 +Neso,Neptune,0.334536,0.447,0,0,123.2,338.3 +Sao,Neptune,0.14961,0.299,0,0,179.6,90.9 +Hippocamp,Neptune,0.000703887,0.001,0,0,286.5,346.4 +Proteus,Neptune,0.000786107,0,6.48101e-06,0.0326479,276.8,0 +Galatea,Neptune,0.000414444,0,4.76401e-07,0.0123999,86.7,0 +Despina,Neptune,0.000350941,0,2.9284e-07,0.0116151,125.1,0 +Ferdinand,Uranus,0.138023,0.397,0,0,256.7,79.1 +Trinculo,Uranus,0.0568524,0.219,0,0,88.5,130.1 +Caliban,Uranus,0.0483296,0.204,0,0,224.9,8.3 +Cupid,Uranus,0.000497333,0.005,0,0,160.6,13.5 +Mab,Uranus,0.000653084,0.003,0,0,348,237.9 +Perdita,Uranus,0.000510702,0.002,0,0,32.2,310.4 +Belinda,Uranus,0.000503349,0,0,0,121.3,0 +Rosalind,Uranus,0.000467253,0,0,0,79.4,0 +Juliet,Uranus,0.000430487,0.001,0,0,124.8,291.5 +Cressida,Uranus,0.000413107,0,0,0,332.8,0 +Bianca,Uranus,0.000395728,0.001,0,0,236.2,97 +Cordelia,Uranus,0.000332892,0,0,0,95,0 +Puck,Uranus,0.000574874,0,0,0,174.5,0 +Miranda,Uranus,0.000868328,0.001,1.07874e-05,0.0370115,72.4,155.6 +Ophelia,Uranus,0.000359631,0.011,0,0,280.5,344.3 +Titania,Uranus,0.00291649,0.001,0.000569223,0.123827,53.2,202 +Ariel,Uranus,0.00127609,0.001,0.000209476,0.0908649,119.8,83.3 +S2019_s01,Saturn,0.0751749,0.463,0,0,36.6,86.6 +Portia,Uranus,0.000441851,0,0,0,343.7,0 +S2007_s02,Saturn,0.111753,0.179,0,0,84.1,57.7 +S2006_s03,Saturn,0.149922,0.379,0,0,167.1,188.7 +S2004_s39,Saturn,0.155089,0.102,0,0,98,199.8 +S2004_s38,Saturn,0.148839,0.541,0,0,101.4,346.6 +S2004_s36,Saturn,0.15668,0.617,0,0,138.8,204.4 +S2004_s33,Saturn,0.157629,0.514,0,0,128.3,309.7 +S2004_s29,Saturn,0.114106,0.488,0,0,183.8,318.9 +S2004_s28,Saturn,0.146011,0.161,0,0,95.9,186.6 +S2004_s26,Saturn,0.174515,0.147,0,0,153.2,151.7 +S2004_s24,Saturn,0.156058,0.072,0,0,289.6,181 +S2004_s22,Saturn,0.137689,0.216,0,0,102.8,118.9 +S2007_s03,Saturn,0.126593,0.185,0,0,292.7,111.9 +S2004_s21,Saturn,0.154621,0.409,0,0,187.5,182 +S2004_s27,Saturn,0.132689,0.157,0,0,268.1,142.7 +S2004_s20,Saturn,0.128738,0.182,0,0,122.5,290.1 +S2004_s17,Saturn,0.130002,0.18,0,0,228.5,180.8 +S2004_s13,Saturn,0.123037,0.259,0,0,41.1,346.2 +S2004_s07,Saturn,0.140376,0.529,0,0,79.8,84 +Tarqeq,Saturn,0.120069,0.168,0,0,161,34.8 +Greip,Saturn,0.123377,0.315,0,0,314.5,152.2 +Jarnsaxa,Saturn,0.129373,0.218,0,0,198.7,237.4 +Surtur,Saturn,0.153351,0.446,0,0,136.2,303.7 +Skoll,Saturn,0.118097,0.464,0,0,45,193.1 +Psamathe,Neptune,0.312181,0.451,0,0,70.2,261.3 +Kari,Saturn,0.147683,0.476,0,0,286,163.9 +Margaret,Uranus,0.0940521,0.678,0,0,119.9,90.4 +Hyrrokkin,Saturn,0.123264,0.336,0,0,291.8,273.1 +S2004_s37,Saturn,0.106586,0.446,0,0,185.9,77.2 +Eirene,Jupiter,0.154119,0.258,0,0,329.7,94.8 +S2006_s01,Saturn,0.125537,0.141,0,0,96.6,155 +S2017_j3,Jupiter,0.139982,0.231,0,0,193.3,92.9 +Nereid,Neptune,0.036792,0.749,0,0.0266834,318,290.3 +Chaldene,Jupiter,0.153281,0.265,0,0,266.2,335 +S2011_j2,Jupiter,0.153139,0.355,0,0,284,218.7 +S2010_j1,Jupiter,0.155014,0.252,0,0,161.1,344.2 +Stephano,Uranus,0.0535034,0.218,0,0,190.2,352.6 +Eukelade,Jupiter,0.154196,0.277,0,0,203.6,283.7 +Aoede,Jupiter,0.158947,0.436,0,0,198.8,72.9 +Hegemone,Jupiter,0.156076,0.358,0,0,233.7,282.2 +S2003_j23,Jupiter,0.159289,0.313,0,0,168.5,163.2 +Enceladus,Saturn,0.00159361,0.005,1.80886e-05,0.0395699,57,119.5 +S2004_s35,Saturn,0.146827,0.237,0,0,320.2,154.2 +Kale,Jupiter,0.154097,0.262,0,0,212.7,283.6 +Pallene,Saturn,0.00141914,0.004,0,0,2,194.9 +Sponde,Jupiter,0.157377,0.322,0,0,173.8,184.9 +Calypso,Saturn,0.00197195,0.001,0,0,-0,221.6 +Euporie,Jupiter,0.128784,0.148,0,0,72.2,329.8 +Phobos,Mars,6.28351e-05,0.015,1.77791e-09,0.00173913,189.6,216.3 +Carme,Jupiter,0.154711,0.256,0,0,234,155 +Euanthe,Jupiter,0.13922,0.239,0,0,336.5,169.8 +Francisco,Uranus,0.0286301,0.139,0,0,129.5,297.3 +S2016_j2,Jupiter,0.124963,0.217,0,0,57.6,344.2 +Laomedeia,Neptune,0.157809,0.418,0,0,248.3,146 +S2017_j6,Jupiter,0.155385,0.336,0,0,150.2,100 +Thelxinoe,Jupiter,0.140216,0.228,0,0,267.9,333.4 +Aitne,Jupiter,0.154176,0.277,0,0,106,81.3 +Hermippe,Jupiter,0.141102,0.219,0,0,134.7,356.6 +Pasithee,Jupiter,0.152721,0.27,0,0,216,295.2 +Larissa,Neptune,0.000491317,0.001,6.39315e-07,0.0150683,165.5,247.3 +Sycorax,Uranus,0.0814183,0.521,0,0,146.2,211.4 +Deimos,Mars,0.000157088,0,2.41336e-10,0.00097316,205,0 +Fornjot,Saturn,0.168091,0.208,0,0,214.5,324.8 +Naiad,Neptune,0.000322197,0,2.13992e-08,0.00455188,89.7,0 +Janus,Saturn,0.00101271,0.007,3.17651e-07,0.0140009,111.7,11.1 +S2003_j18,Jupiter,0.13594,0.09,0,0,66.1,304.4 +Magaclite,Jupiter,0.158054,0.421,0,0,138.1,85.1 +Triton,Neptune,0.00237169,0,0.00358366,0.212306,63,0 +Himalia,Jupiter,0.0764757,0.16,3.80192e-07,0.0133417,66.5,328.4 +Halimede,Neptune,0.105307,0.566,0,0,173.9,113.5 +Orthosie,Jupiter,0.139715,0.299,0,0,200.7,140.1 +Leda,Jupiter,0.0745091,0.162,0,0,233.4,270.9 +Adrastea,Jupiter,0.000862312,0,3.51217e-10,0.00128708,214.5,0 +Helike,Jupiter,0.139813,0.153,0,0,44.2,118.1 +Loge,Saturn,0.15414,0.186,0,0,337.2,32.8 +Skathi,Saturn,0.104514,0.272,0,0,114.7,203.5 +Bebhionn,Saturn,0.114413,0.468,0,0,168,358.1 +Bergelmir,Saturn,0.129253,0.142,0,0,306.5,133.4 +Io,Jupiter,0.00281956,0.004,0.0149516,0.285903,330.9,49.1 +Amalthea,Jupiter,0.00121258,0.003,4.12831e-07,0.0131063,310.6,180.1 +Nix,Pluto,0.000325539,0,7.52608e-09,0.0028253,84.8,0 +Callisto,Jupiter,0.0125851,0.007,0.0180106,0.378324,87.4,43.8 +Helene,Saturn,0.0025241,0.007,1.20417e-09,0.0028253,-64.5,194.3 +Prometheus,Saturn,0.000931831,0.002,2.68681e-08,0.00676503,135.4,341.9 +Desdemona,Uranus,0.000419124,0,0,0,160.4,0 +Thyone,Jupiter,0.140229,0.233,0,0,244.4,343.5 +S2016_j1,Jupiter,0.139057,0.232,0,0,192.4,197.8 +Iapetus,Saturn,0.0238085,0.028,0.000302335,0.115257,74.8,254.5 +Europa,Jupiter,0.00448603,0.009,0.00803462,0.244985,345.4,45 +S2003_j4,Jupiter,0.153254,0.328,0,0,242.8,194.4 +Fenrir,Saturn,0.150096,0.135,0,0,131.7,121 +Eurydome,Jupiter,0.15307,0.294,0,0,286.3,340.2 +Metis,Jupiter,0.000855627,0,6.27173e-09,0.00337467,166,0 +Isonoe,Jupiter,0.153621,0.249,0,0,124.9,213.5 +Sinope,Jupiter,0.158317,0.264,0,0,167.5,96.6 +Ganymede,Jupiter,0.00715518,0.001,0.0248055,0.412996,324.8,198.3 +Lysithea,Jupiter,0.078215,0.117,0,0,331.5,47.4 +Mimas,Saturn,0.00124333,0.02,6.28049e-06,0.0311097,275.3,160.4 +Praxidike,Jupiter,0.139945,0.246,0,0,112.2,357.2 +S2004_s31,Saturn,0.116974,0.202,0,0,255.4,262.7 +S2017_j9,Jupiter,0.145515,0.2,0,0,261.5,130.7 +Aegaeon,Saturn,0.00111967,0,0,0,4.4,0 +Kallichore,Jupiter,0.153891,0.252,0,0,54.2,310.1 +Siarnaq,Saturn,0.121539,0.28,0,0,201.3,65.9 +Setebos,Uranus,0.116606,0.588,0,0,281.3,214.4 +Autonoe,Jupiter,0.159043,0.33,0,0,145.7,228.3 +Ananke,Jupiter,0.140607,0.237,0,0,259.4,56.2 +Taygete,Jupiter,0.154467,0.253,0,0,95.7,341 +Callirrhoe,Jupiter,0.159063,0.297,0,0,107.1,180.5 +Kore,Jupiter,0.161802,0.328,0,0,31.8,229.3 +Themisto,Jupiter,0.0494559,0.34,0,0,284.7,236.2 +Pasiphae,Jupiter,0.156875,0.412,0,0,277.8,264.8 +Albiorix,Saturn,0.10958,0.48,0,0,32.8,55.9 +Erinome,Jupiter,0.153965,0.276,0,0,265.5,98.2 +Kalyke,Jupiter,0.155768,0.26,0,0,256,130.3 +Mneme,Jupiter,0.13918,0.247,0,0,253.7,18.5 +S2017_j1,Jupiter,0.158724,0.328,0,0,286.5,252.2 +S2017_j8,Jupiter,0.152739,0.255,0,0,350.4,146.9 +S2003_j9,Jupiter,0.155078,0.263,0,0,354.6,199.6 +Titan,Saturn,0.0081679,0.029,0.0225234,0.404137,11.7,78.3 +Eupheme,Jupiter,0.13883,0.241,0,0,359.1,316.6 +Thalassa,Neptune,0.000334898,0,5.91801e-08,0.00627845,165.7,0 +Philophrosyne,Jupiter,0.151102,0.229,0,0,69.5,271.6 +Farbauti,Saturn,0.136299,0.241,0,0,282.8,343 +Methone,Saturn,0.00130149,0.002,0,0,0,315.5 +S2003_j19,Jupiter,0.154791,0.265,0,0,218.4,123.4 +S2017_j2,Jupiter,0.153433,0.272,0,0,293.3,137.5 +Bestla,Saturn,0.134661,0.52,0,0,238.5,81.1 +Pandia,Jupiter,0.0767457,0.179,0,0,153.9,194.3 +S2004_s34,Saturn,0.161433,0.282,0,0,34.7,346.5 +S2004_s25,Saturn,0.140049,0.519,0,0,208,268.2 +S2010_j2,Jupiter,0.138993,0.248,0,0,306.3,15.1 +S2017_j5,Jupiter,0.155124,0.257,0,0,66.9,211.7 +S2017_j7,Jupiter,0.140141,0.233,0,0,359.1,119.4 +Carpo,Jupiter,0.113921,0.416,0,0,339.8,86.6 +Ersa,Jupiter,0.076211,0.116,0,0,263.4,304.7 +Mundilfari,Saturn,0.124688,0.21,0,0,92.8,309.7 +Elara,Jupiter,0.0782919,0.211,0,0,330.7,140.1 +S2011_j1,Jupiter,0.154578,0.271,0,0,248.4,251.8 +Arche,Jupiter,0.154399,0.261,0,0,39.8,213.5 +S2003_j10,Jupiter,0.157598,0.264,0,0,286.9,227.5 +S2003_j2,Jupiter,0.140361,0.225,0,0,35.2,200.4 +S2004_s32,Saturn,0.141392,0.254,0,0,169.4,32.7 +S2003_j12,Jupiter,0.14013,0.235,0,0,201.3,277.9 +S2003_j16,Jupiter,0.139592,0.243,0,0,307.4,24.6 +Polydeuces,Saturn,0.0025241,0.019,0,0,359,94.1 +Herse,Jupiter,0.154752,0.262,0,0,141.2,101.2 +Cyllene,Jupiter,0.158122,0.419,0,0,121.3,47.8 +S2003_j24,Jupiter,0.152993,0.259,0,0,131.8,24.2 +Tethys,Saturn,0.00197195,0.001,0.000103392,0.0833621,0,335.3 +Harpalyke,Jupiter,0.139655,0.232,0,0,219.3,71.3 +Narvi,Saturn,0.12934,0.43,0,0,114.2,170 +Dione,Saturn,0.00252477,0.002,0.000183426,0.088118,212,116 +Rhea,Saturn,0.00352411,0.001,0.000386193,0.11984,31.5,44.3 +Umbriel,Uranus,0.0017781,0.004,0.00021349,0.0917752,258.3,157.5 +Thebe,Jupiter,0.00148331,0.018,7.56371e-08,0.00773819,182.1,26.6 +Pandora,Saturn,0.000947206,0.004,2.32305e-08,0.00637263,123.9,217.9 +S2004_s23,Saturn,0.143431,0.437,0,0,65.1,22.8 +Aegir,Saturn,0.138712,0.252,0,0,26,242.7 +Hyperion,Saturn,0.00990322,0.105,9.29446e-07,0.0211898,122.9,214 +Prospero,Uranus,0.108738,0.439,0,0,125.3,251.9 +S2004_s30,Saturn,0.138444,0.087,0,0,336.5,269.3 +Phoebe,Saturn,0.0864277,0.164,1.3918e-06,0.0167164,308,240.3 +Telesto,Saturn,0.00197195,0.001,0,0,360,66.2 +S2004_s12,Saturn,0.13293,0.327,0,0,1.6,87.1 +Epimetheus,Saturn,0.00101205,0.02,8.81555e-08,0.00913514,197.2,96.3 +Oberon,Uranus,0.00389979,0.001,0.000515035,0.11951,139.7,182.4 +Atlas,Saturn,0.000920468,0.001,9.28217e-10,0.00237011,289.1,82.3 +Pan,Saturn,0.000893061,0,7.02434e-10,0.00219746,146.6,0 +Daphnis,Saturn,0.000912446,0,0,0,153.6,0 +Anthe,Saturn,0.00132422,0.002,0,0,351.4,293.4 +Dia,Jupiter,0.081955,0.232,0,0,309.6,176.8 +Ymir,Saturn,0.154601,0.334,0,0,228.7,21.4 +Kerberos,Pluto,0.000386369,0,2.75956e-09,0.000941767,303.5,0 +Kiviuq,Saturn,0.0758233,0.212,0,0,171,90.6 +Ijiraq,Saturn,0.0762578,0.272,0,0,17.3,92.9 +Paaliaq,Saturn,0.101378,0.341,0,0,321.3,238.7 +Tarvos,Saturn,0.121947,0.538,0,0,265.8,274.1 +Iocaste,Jupiter,0.140822,0.227,0,0,215.5,244.7 +Suttungr,Saturn,0.130136,0.114,0,0,321.1,34.3 +Erriapus,Saturn,0.117662,0.472,0,0,294.8,282.5 +Thrymr,Saturn,0.136486,0.466,0,0,30.1,125.4 +Styx,Pluto,0.000283426,0,0,0.000816198,180.9,0 +Hati,Saturn,0.132809,0.371,0,0,163.6,21.3 diff --git a/include/camera.hpp b/include/camera.hpp new file mode 100644 index 0000000..9a8bc00 --- /dev/null +++ b/include/camera.hpp @@ -0,0 +1,96 @@ +#ifndef CAMERA_HPP +#define CAMERA_HPP 1 + +#include "vex.hpp" +#include "shape.hpp" +#include "straw.hpp" + +#include <vector> +#include <concepts> +#include <algorithm> + +class Camera; +struct RenderBatchEntry { + shapes::shapes_variant<long> shape; + straw::color fg, bg; + char c; + + template<class T> + constexpr RenderBatchEntry(T Shape) : shape(Shape), fg(straw::WHITE), bg(straw::BLACK), c('#') {} + template<class T> + constexpr RenderBatchEntry(T Shape, char C) : shape(Shape), fg(straw::WHITE), bg(straw::BLACK), c(C) {} + template<class T> + constexpr RenderBatchEntry(T Shape, straw::color Fg, char C) : shape(Shape), fg(Fg), bg(straw::BLACK), c(C) {} + template<class T> + constexpr RenderBatchEntry(T Shape, straw::color Fg, straw::color Bg, char C) : shape(Shape), fg(Fg), bg(Bg), c(C) {} + + void translate(Camera *camera); + void plot(Camera *camera); +private: + void plotPoint(shapes::point<long> point, Camera *camera); + void plotLine(shapes::line<long> line, Camera *camera); + void plotRectangle(shapes::rectangle<long> rectangle, Camera *camera); + void plotCircle(shapes::circle<long> circle, Camera *camera); + void plotEllipse(shapes::ellipse<long> ellipse, Camera *camera); +}; + +class Camera +{ + friend struct RenderBatchEntry; + + vex::vec2<long> m_position; + vex::vec2<long> m_origin; + shapes::rectangle<long> m_frustum; + + std::vector<RenderBatchEntry> m_shapeBatch; + + long m_scale; + bool m_dirty; + + straw::screen<char> *m_viewport; + + void updateFrustum(); + + template<class T> + void translateShape(T &shape); +public: + Camera(straw::screen<char> *viewport) : + m_position(0, 0), + m_origin(0, 0), + m_frustum(0, 0, 0, 0), + m_scale(16384), + m_dirty(true), + m_viewport(viewport) {} + ~Camera() {} + + constexpr long getscale() const { return m_scale; } + constexpr vex::vec2<long> getpos() const { return m_position; } + constexpr vex::vec2<long> getorigin() const { return m_origin; } + + constexpr bool dirty() const { return m_dirty; } + void markDirty() { m_dirty = true; } + + void zoom(long by) { m_scale = std::max((unsigned)((int)m_scale + by), (unsigned)1); m_dirty = true; } + void setscale(long scale) { m_scale = std::max(scale, (long)1); m_dirty = true; } + + void move(const vex::vec2<long> &pos) { m_position += pos; m_dirty = true; } + void move(long x, long y) { move(vex::vec2<long>(x, y)); } + + void setpos(const vex::vec2<long> &pos) { m_position = pos; m_dirty = true; } + void setpos(long x, long y) { setpos(vex::vec2<long>(x, y)); } + + void setorigin(const vex::vec2<long> &origin) { m_origin = origin; m_dirty = true; } + + template<class T> + void batchShape(T shape) { m_shapeBatch.emplace_back(shape); } + template<class T> + void batchShape(T shape, char c) { m_shapeBatch.emplace_back(shape, c); } + template<class T> + void batchShape(T shape, straw::color fg, char c) { m_shapeBatch.emplace_back(shape, fg, c); } + template<class T> + void batchShape(T shape, straw::color fg, straw::color bg, char c) { m_shapeBatch.emplace_back(shape, fg, bg, c); } + + void draw(); +}; + +#endif diff --git a/include/csv.hpp b/include/csv.hpp new file mode 100644 index 0000000..18e30b0 --- /dev/null +++ b/include/csv.hpp @@ -0,0 +1,115 @@ +#ifndef CSV_HPP +#define CSV_HPP 1 + +#include <tuple> +#include <string> +#include <vector> +#include <sstream> +#include <fstream> +#include <iostream> + +namespace csv { + +template<char T> +struct csv_delim : std::ctype<char> { + csv_delim() : std::ctype<char>(get_table()) {} + static mask const *get_table() { + static mask rc[table_size]; + rc[T] = std::ctype_base::space; + rc['\n'] = std::ctype_base::space; + return &rc[0]; + } +}; + +template<char Seperator, typename... Vals> +class CSVFile { +public: + struct CSVLine { + std::tuple<Vals...> data; + + CSVLine(const std::string &line) { + std::istringstream in(line); + in.imbue(std::locale(std::locale(), new csv_delim<Seperator>)); + read_elements(in, std::make_index_sequence<sizeof...(Vals)>{}); + } + + template<std::size_t... I> + void read_elements(std::istream &in, std::index_sequence<I...>) { + std::initializer_list<bool>{read_element(in, std::get<I>(data))...}; + } + + template<typename T> + bool read_element(std::istream &in, T &value) { + in >> value; return true; + } + }; + struct Reader { + private: + std::vector<CSVLine> m_lines; + public: + Reader() {} + Reader(CSVFile *parent) { + for(std::string line; std::getline(parent->m_rfile, line);) { + m_lines.emplace_back(line); + } + } + std::vector<std::tuple<Vals...>> get() const { + std::vector<std::tuple<Vals...>> r; + for(auto &line : m_lines) r.push_back(line.data); + return r; + } + + }; + struct Writer { + private: + std::vector<std::tuple<Vals...>> m_data; + public: + void put(std::tuple<Vals...> line) { m_data.push_back(line); } + void write(CSVFile *parent) { + for(auto &line : m_data) { + write_line(parent, line, std::make_index_sequence<sizeof...(Vals)>{}); + parent->m_wfile.seekp(-1, std::ios_base::end); + parent->m_wfile << "\n"; + } + } + template<std::size_t... I> + void write_line(CSVFile *parent, std::tuple<Vals...> line, std::index_sequence<I...>) { + std::initializer_list<bool>{write_element(parent, std::get<I>(line))...}; + } + template<typename T> + bool write_element(CSVFile *parent, T &value) { + parent->m_wfile << value << Seperator; return true; + } + }; + + friend struct Reader; + friend struct Writer; + + CSVFile(const std::string &path, bool write = false) { + //std::ios_base::iostate emask = m_file.exceptions() | std::ios::failbit; + if(!write) { + m_rfile.open(path); + m_reader = Reader(this); + }else{ + m_wfile.open(path); + } + } + ~CSVFile() { m_rfile.close(); m_wfile.close(); } + + const std::tuple<Vals...> operator[](std::size_t i) { return m_reader.m_lines[i].data; } + std::size_t size() const { return m_reader.m_lines.size(); } + + std::vector<std::tuple<Vals...>> get() const { return m_reader.get(); } + void put(std::tuple<Vals...> vals) { m_writer.put(vals); } + void write() { m_writer.write(this); } + +protected: + std::ifstream m_rfile; + std::ofstream m_wfile; + Reader m_reader; + Writer m_writer; +}; + +} + +#endif diff --git a/include/ecs.hpp b/include/ecs.hpp new file mode 100644 index 0000000..ab5e2b2 --- /dev/null +++ b/include/ecs.hpp @@ -0,0 +1,139 @@ +#ifndef ECS_HPP +#define ECS_HPP 1 + +#include "entitycomponents.hpp" +#include "util.hpp" +#include <bitset> +#include <typeindex> +#include <queue> +#include <cassert> +#include <ranges> +#include <span> +#include <iostream> + +namespace ecs { + +struct ComponentContainer { + std::vector<component_variant> packed{}; + std::vector<int> sparse{}; + std::queue<unsigned> free{}; + + void resize(size_t n) { sparse.resize(n, -1); } + + template<component_type T> + void insert(unsigned id, const T &c) { + assert(sparse.size() > id); + if(free.empty()) { + sparse[id] = (int)packed.size(); + packed.push_back(c); + }else { + sparse[id] = (int)free.front(); + packed[sparse[id]] = c; + free.pop(); + } + } + + void remove(unsigned id) { + assert(sparse.size() > id); + if(sparse[id] > -1) { + free.push((unsigned)sparse[id]); + } + sparse[id] = -1; + } + + template<component_type T> + T &reduce(unsigned id) { + assert(sparse.size() > id); + assert(sparse[id] > -1); + return std::get<T>(packed[sparse[id]]); + } +}; + +class EntityMan; +struct Entity { + EntityMan *man; + component_sig sig{}; + unsigned id; + + Entity(const Entity &e) = default; + Entity(EntityMan *Man, unsigned Id) : + man(Man), sig(0), id(Id) {} + + + template<component_type T> + constexpr bool contains() { return sig.test(get_index<T, component_variant>()); } + + template<component_type T> + T &get(); + + template<component_type T> + Entity &addComponent(const T &component); +}; + +class EntityMan { + std::array<ComponentContainer, std::variant_size_v<component_variant>> m_components; + std::vector<Entity> m_entities; + std::queue<unsigned> m_free; +public: + Entity &operator[](std::size_t i) { return m_entities[i]; } + + Entity newEntity() { + std::size_t newid = 0; + if(!m_free.empty()) { + newid = m_free.front(); + m_free.pop(); + }else{ + newid = m_entities.size(); + m_entities.emplace_back(this, newid); + for(auto &container : m_components) container.resize(m_entities.size()); + } + return m_entities[newid]; + } + + void deleteEntity(Entity &e) { + for(auto &container : m_components) container.remove(e.id); + e.sig.reset(); + m_free.push(e.id); + } + + template<component_type T> + T &get(const Entity &e) { + constexpr unsigned cid = get_index<T, component_variant>(); + return m_components[cid].reduce<T>(e.id); + } + + template<component_type T> + auto getWith() { + constexpr unsigned cid = get_index<T, component_variant>(); + auto e_hc = [](Entity const e) { return e.sig[cid]; }; + return std::ranges::views::filter(m_entities, e_hc); + } + + std::span<Entity> all() { + return std::span<Entity>(m_entities.begin(), m_entities.end()); + } + + std::size_t size() { return m_entities.size(); } + + template<component_type T> + Entity &addComponent(Entity &entity, const T& component) { + constexpr unsigned cid = get_index<T, component_variant>(); + m_components[cid].insert(entity.id, component); + m_entities[entity.id].sig[cid] = 1; + return entity; + } +}; + +template<component_type T> +T &Entity::get() { + return man->get<T>(*this); +} + +template<component_type T> +Entity &Entity::addComponent(const T& component) { + return man->addComponent(*this, component); +} + +} + +#endif diff --git a/include/entitycomponents.hpp b/include/entitycomponents.hpp new file mode 100644 index 0000000..a263ebf --- /dev/null +++ b/include/entitycomponents.hpp @@ -0,0 +1,58 @@ +#ifndef ENTITY_COMPONENT_HPP +#define ENTITY_COMPONENT_HPP 1 + +#include "vex.hpp" +#include "units.hpp" +#include <bitset> + +namespace ecs { +struct PositionComponent { + vex::vec2<long> position{}; +}; + +struct VelocityComponent { + vex::vec2<long> velocity{}; +}; + +struct MassComponent { + unit::Mass mass; +}; + +struct NameComponent { + std::string name; +}; + +struct OrbitalComponent { + unsigned origin; + long a; + double e; + double w; + double M; + double T; + double v; +}; + +struct RenderCircleComponent { + unsigned radius; +}; + +using component_variant = std::variant< + std::monostate, + PositionComponent, + VelocityComponent, + MassComponent, + NameComponent, + OrbitalComponent, + RenderCircleComponent +>; + +using component_sig = + std::bitset<std::variant_size_v<component_variant>>; + +template<typename T> +concept component_type = + is_variant_v<T, component_variant>; + +} + +#endif diff --git a/include/game.hpp b/include/game.hpp new file mode 100644 index 0000000..9454318 --- /dev/null +++ b/include/game.hpp @@ -0,0 +1,52 @@ +#ifndef GAME_HPP +#define GAME_HPP 1 + +#include "window.hpp" +#include "camera.hpp" +#include "ecs.hpp" +#include "system.hpp" +#include "timeman.hpp" +#include "input.hpp" + +#include <memory> + +#define WINCTX_GAME "Game" + +class Game +{ +public: + enum class State { + STOPPED, RUNNING, RUNNING_INPUT, PAUSED, PAUSED_INPUT + }; + + static void setup(unsigned w, unsigned h); + static void cleanup(); + + static void turn(); + static void setState(State state) { m_state = state; } + static void setContext(const std::string &id) { m_currentContext = id; } + + static bool running() { return m_state != State::STOPPED; } + static bool paused() { return m_state == State::PAUSED || m_state == State::PAUSED_INPUT; } + static bool inputMode() { return m_state == State::RUNNING_INPUT || m_state == State::PAUSED_INPUT; } + + struct WindowContexts { + WindowContext &operator[](const std::string &id) { return Game::m_contexts.at(id); } + WindowContext &operator()() { return Game::m_contexts.at(Game::m_currentContext); } + }; + static WindowContexts contexts; +private: + static std::unordered_map<std::string, WindowContext> m_contexts; + static std::string m_currentContext; + + static std::unique_ptr<Camera> m_camera; + static std::unique_ptr<System> m_system; + static SystemView m_systemView; + + static input::Context m_inputContext; + + static double m_delta; + static State m_state; +}; + +#endif diff --git a/include/input.hpp b/include/input.hpp new file mode 100644 index 0000000..ed5155c --- /dev/null +++ b/include/input.hpp @@ -0,0 +1,71 @@ +#ifndef INPUT_HPP +#define INPUT_HPP 1 + +namespace input +{ + +enum extkeys { + CTRL_RANGE_START = 256, + CTRL_KEY_ARROWUP = 321, + CTRL_KEY_ARROWDOWN, + CTRL_KEY_ARROWRIGHT, + CTRL_KEY_ARROWLEFT, + CTRL_KEY_END = 326, + CTRL_KEY_HOME = 328, + CTRL_KEY_PAGEUP, + CTRL_KEY_PAGEDOWN +}; + +#ifdef __unix__ +#include <termios.h> +#include <unistd.h> + +class Context +{ + struct termios m_termold; + struct termios m_termnow; +public: + Context() { + tcgetattr(STDIN_FILENO, &m_termold); + m_termnow = m_termold; + } + ~Context() { + tcsetattr(STDIN_FILENO, TCSADRAIN, &m_termold); + } + + void echo(bool mode) { + if(mode){ + m_termnow.c_lflag |= ECHO; + }else{ + m_termnow.c_lflag &= ~ECHO; + } + tcsetattr(STDIN_FILENO, TCSANOW, &m_termnow); + } + + void canon(bool mode) { + if(mode) { + m_termnow.c_lflag |= ICANON; + }else{ + m_termnow.c_lflag &= ~ICANON; + } + tcsetattr(STDIN_FILENO, TCSANOW, &m_termnow); + } + + void cbreak(bool mode) { + if(mode){ + m_termnow.c_cc[VMIN] = m_termold.c_cc[VMIN]; + m_termnow.c_cc[VTIME] = m_termold.c_cc[VTIME]; + }else{ + m_termnow.c_cc[VMIN] = 1; + m_termnow.c_cc[VTIME] = 0; + } + tcsetattr(STDIN_FILENO, TCSANOW, &m_termnow); + } +}; + +#endif + +extern int getcode(); +} + +#endif diff --git a/include/keybind.hpp b/include/keybind.hpp new file mode 100644 index 0000000..6541a21 --- /dev/null +++ b/include/keybind.hpp @@ -0,0 +1,71 @@ +#ifndef KEYBIND_HPP +#define KEYBIND_HPP 1 + +#include <string> +#include <vector> +#include <algorithm> +#include <unordered_map> + +#define CTX_GLOBAL "Global" +#define CTX_SYSTEMVIEW "System View" +#define CTX_TIMEMAN "Time Manager" + +#define BIND_G_QUIT "G_Quit" +#define BIND_G_NEXTWIN "G_NextWindow" +#define BIND_G_PREVWIN "G_PrevWindow" +#define BIND_G_EDITBINDS "G_EditBinds" +#define BIND_G_ESCAPE "G_Escape" +#define BIND_G_SELECT "G_Select" + +#define BIND_SYSTEMVIEW_PANUP "Systemview_PanUp" +#define BIND_SYSTEMVIEW_PANDOWN "Systemview_PanDown" +#define BIND_SYSTEMVIEW_PANLEFT "Systemview_PanLeft" +#define BIND_SYSTEMVIEW_PANRIGHT "Systemview_PanRight" +#define BIND_SYSTEMVIEW_DECSCALE "Systemview_DecScale" +#define BIND_SYSTEMVIEW_INCSCALE "Systemview_IncScale" +#define BIND_SYSTEMVIEW_SEARCH "Systemview_Search" + +#define BIND_SYSTEMVIEW_SEARCH_PREV "Systemview_Search_Prev" +#define BIND_SYSTEMVIEW_SEARCH_NEXT "Systemview_Search_Next" +#define BIND_SYSTEMVIEW_SEARCH_TOP "Systemview_Search_Top" +#define BIND_SYSTEMVIEW_SEARCH_BOTTOM "Systemview_Search_Bottom" +#define BIND_SYSTEMVIEW_SEARCH_COLLAPSE "Systemview_Search_Collapse" + +#define BIND_TIMEMAN_STEP "Timeman_Step" +#define BIND_TIMEMAN_INCSTEP "Timeman_IncStep" +#define BIND_TIMEMAN_DECSTEP "Timeman_DecStep" +#define BIND_TIMEMAN_TOGGLEAUTO "Timeman_ToggleAuto" + +class KeyMan { +public: + struct Bind { + int code; + std::string name; + std::string ctx; + std::string desc; + }; + + struct Binds { + std::vector<Bind> operator()() { + std::vector<Bind> bindList; + std::transform( + KeyMan::m_keybinds.begin(), + KeyMan::m_keybinds.end(), + std::back_inserter(bindList), [](auto &pair){return pair.second;}); + return bindList; + } + Bind &operator[](const std::string &name) { return KeyMan::m_keybinds[name]; } + }; + static Binds binds; + + static void registerBind(int def, const std::string &name, const std::string &context, const std::string &desc); + static void loadKeybindsFrom(const std::string &csvPath); + static void writeKeybindsTo(const std::string &csvPath); + static std::string translateCode(int code); + +private: + static std::unordered_map<std::string, Bind> m_keybinds; + static std::unordered_map<std::string, std::string> m_keybindContexts; +}; + +#endif diff --git a/include/shape.hpp b/include/shape.hpp new file mode 100644 index 0000000..0d9db96 --- /dev/null +++ b/include/shape.hpp @@ -0,0 +1,197 @@ +#ifndef SHAPE_HPP +#define SHAPE_HPP 1 + +#include "vex.hpp" +#include <iostream> +#include <variant> + +namespace shapes { + +template<vex::arithmetic T> +struct shape +{ + vex::vec2<T> position; + + constexpr shape(const vex::vec2<T> p) : position(p) {} + constexpr shape(T x, T y) : position(x, y) {} + + virtual void scale(T by) = 0; + virtual void translate(vex::vec2<T> by) { position += by; } +}; + +template<vex::arithmetic T> +struct point : public shape<T> +{ + constexpr point(T x, T y) : shape<T>(vex::vec2<T>(x, y)) {} + constexpr point(const vex::vec2<T> &pos) : shape<T>(pos) {} + + void scale(T by) override { (void)by; } +}; + +template<vex::arithmetic T> +struct line : public shape<T> +{ + vex::vec2<T> end; + constexpr line(T x, T y, T z, T w) : shape<T>(vex::vec2<T>(x, y)), end(z, w){} + constexpr line(const vex::vec2<T> &pos, const vex::vec2<T> End) : shape<T>(pos), end(End) {} + + void translate(vex::vec2<T> by) + { + this->position += by; + end += by; + } + void scale(T by) override { + end = vex::vec2<T>( + (T)std::floor((double)end[0] / (double)by), + (T)std::floor((double)end[1] / (double)by)); + } +}; + +template<vex::arithmetic T> +struct circle : public shape<T> +{ + T radius; + constexpr circle(T x, T y, T r) : shape<T>(vex::vec2<T>(x, y)), radius(r) {} + constexpr circle(const vex::vec2<T> &pos, T r) : shape<T>(pos), radius(r) {} + + void scale(T by) override { radius /= by; } +}; + +template<vex::arithmetic T> +struct ellipse : public shape<T> +{ + T a, b; + constexpr ellipse(T x, T y, T A, T B) : shape<T>(x, y), a(A), b(B) {} + constexpr ellipse(const vex::vec2<T> &pos, T A, T B) : shape<T>(pos), a(A), b(B) {} + + void scale(T by) override {a /= by; b /= by; } +}; + +template<vex::arithmetic T> +struct rectangle : public shape<T> +{ + vex::vec2<T> bounds; + constexpr rectangle(T x, T y, T w, T h) : shape<T>(vex::vec2<T>(x, y)), bounds(w, h) {} + constexpr rectangle(const vex::vec2<T> &pos, const vex::vec2<T> &wh) : shape<T>(pos), bounds(wh) {} + + void scale(T by) override { bounds /= by; } +}; + +template<vex::arithmetic T> +using shapes_variant = std::variant< + point<T>, line<T>, circle<T>, ellipse<T>, rectangle<T> +>; + +template<vex::arithmetic L, vex::arithmetic R> +static bool +intersects(const circle<L> &lhs, const point<R> &rhs) +{ + vex::vec2<L> dist = rhs.position - lhs.position; + //std::cout << dist.magnitude() << ' ' << lhs.radius << ' ' << dist.magnitude() - lhs.radius << std::endl; + return dist.magnitude() < lhs.radius; +} +template<vex::arithmetic L, vex::arithmetic R> +static bool intersects(const point<L> &lhs, const circle<R> &rhs) { return intersects(rhs, lhs); } + +template<vex::arithmetic L, vex::arithmetic R> +static bool +intersects(const ellipse<L> &lhs, const point<R> &rhs) +{ + auto ds = lhs.position - rhs.position; + auto d2 = ds * ds; + L a2 = lhs.a * lhs.a; + L b2 = lhs.b * lhs.b; + + return (((double)d2[0] / a2) + ((double)d2[1] / b2)) <= 1; +} +template<vex::arithmetic L, vex::arithmetic R> +static bool intersects(const point<L> &lhs, const ellipse<R> &rhs) { return intersects(rhs, lhs); } + +template<vex::arithmetic L, vex::arithmetic R> +static bool +intersects(const rectangle<L> &lhs, const point<R> &rhs) +{ + vex::vec2<L> corner = lhs.position + lhs.bounds; + return (rhs.position[0] > lhs.position[0] && rhs.position[0] < corner[0] && + rhs.position[1] > lhs.position[1] && rhs.position[1] < corner[1]); +} +template<vex::arithmetic L, vex::arithmetic R> +static bool intersects(const point<L> &lhs, const rectangle<R> &rhs) { return intersects(rhs, lhs); } + +template<vex::arithmetic L, vex::arithmetic R> +static bool +intersects(const line<L> &lhs, const line<R> &rhs) +{ + double x1 = lhs.position[0], x2 = lhs.end[0], x3 = rhs.position[0], x4 = rhs.end[0]; + double y1 = lhs.position[1], y2 = lhs.end[1], y3 = rhs.position[1], y4 = rhs.end[1]; + double uA = ((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1)); + double uB = ((x2-x1)*(y1-y3) - (y2-y1)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1)); + + if(uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) return true; + return false; +} + +template<vex::arithmetic L, vex::arithmetic R> +static bool +intersects(const rectangle<L> &lhs, const line<R> &rhs) +{ + vex::vec2<L> corner = lhs.position + lhs.bounds; + line<R> l(lhs.position, lhs.position + vex::vec2<R>(0, lhs.bounds[1])); + line<R> r(lhs.position + vex::vec2<R>(lhs.bounds[0], 0), corner); + line<R> d(lhs.position, lhs.position + vex::vec2<R>(lhs.bounds[0], 0)); + line<R> u(lhs.position + vex::vec2<R>(0, lhs.bounds[1]), corner); + + if(intersects(rhs, l) || intersects(rhs, r) || intersects(rhs, d) || intersects(rhs, u)) return true; + return (rhs.position[0] > lhs.position[0] && rhs.position[0] < corner[0] && + rhs.position[1] > lhs.position[1] && rhs.position[1] < corner[1]) && + (rhs.end[0] > lhs.position[0] && rhs.end[0] < corner[0] && + rhs.end[1] > lhs.position[1] && rhs.end[1] < corner[1]); +} +template<vex::arithmetic L, vex::arithmetic R> +static bool intersects(const line<L> &lhs, const rectangle<R> &rhs) { return intersects(rhs, lhs); } + +template<vex::arithmetic L, vex::arithmetic R> +static bool +intersects(const rectangle<L> &lhs, const circle<R> &rhs) +{ + vex::vec2<L> dist{ + rhs.position[0] - std::max(lhs.position[0], std::min(rhs.position[0], lhs.position[0] + lhs.bounds[0])), + rhs.position[1] - std::max(lhs.position[1], std::min(rhs.position[1], lhs.position[1] + lhs.bounds[1])), + }; + return (dist[0] * dist[0]) + (dist[1] * dist[1]) < (rhs.radius * rhs.radius); +} +template<vex::arithmetic L, vex::arithmetic R> +static bool intersects(const circle<L> &lhs, const rectangle<R> &rhs) { return intersects(rhs, lhs); } + +template<vex::arithmetic L, vex::arithmetic R> +static bool +intersects(const rectangle<L> &lhs, const ellipse<R> &rhs) +{ + vex::vec2<L> dist{ + rhs.position[0] - std::max(lhs.position[0], std::min(rhs.position[0], lhs.position[0] + lhs.bounds[0])), + rhs.position[1] - std::max(lhs.position[1], std::min(rhs.position[1], lhs.position[1] + lhs.bounds[1])), + }; + vex::vec2<R> ab2 { + std::max<R>(1, rhs.a * rhs.a), + std::max<R>(1, rhs.b * rhs.b) + }; + return ((dist[0] * dist[0]) / ab2[0]) + ((dist[1] * dist[1]) / ab2[1]) <= 1.0; +} +template<vex::arithmetic L, vex::arithmetic R> +static bool intersects(const ellipse<L> &lhs, const rectangle<R> &rhs) { return intersects(rhs, lhs); } + +template<vex::arithmetic L, vex::arithmetic R> +static bool +intersects(const rectangle<L> &lhs, const rectangle<R> &rhs) +{ + return ( + (lhs.position[0] < rhs.position[0] + rhs.bounds[0]) && + (lhs.position[0] + lhs.bounds[0] > rhs.position[0]) && + (lhs.position[1] + lhs.bounds[1] < rhs.position[1]) && + (lhs.position[1] > rhs.position[1] + rhs.position[1]) + ); +} + +} + +#endif diff --git a/include/straw.hpp b/include/straw.hpp new file mode 100644 index 0000000..c147b06 --- /dev/null +++ b/include/straw.hpp @@ -0,0 +1,312 @@ +#ifndef STRAW_HPP +#define STRAW_HPP 1 + +#include <sstream> +#include <cstdint> +#include <cstddef> +#include <vector> +#include <span> +#include <string> +#include <concepts> +#include <cassert> +#include <iostream> +#include <algorithm> + +namespace straw +{ + +struct color { + std::uint8_t r{}, g{}, b{}; + constexpr color(std::uint8_t R, std::uint8_t G, std::uint8_t B) : r(R), g(G), b(B) {} + constexpr color(std::uint8_t A) : r(A), g(A), b(A) {} + + constexpr uint32_t single() { return (uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b; } + + constexpr bool operator==(const color &o) const = default; +}; + +static constexpr color WHITE{255, 255, 255}; +static constexpr color BLACK{0, 0, 0}; + +struct attribs { + color bg{0, 0, 0}, fg{255, 255, 255}; + bool bold, underline; + constexpr attribs() = default; + constexpr attribs(color Fg) : fg(Fg) {} + constexpr attribs(color Bg, color Fg) : bg(Bg), fg(Fg) {} + constexpr attribs(color Bg, color Fg, bool B, bool U) : bg(Bg), fg(Fg), bold(B), underline(U) {} + + constexpr bool operator==(const attribs &o) const = default; +}; + +template<typename T> +concept char_type = std::integral<T>; + +template<char_type chartype> +struct cell { + chartype chr{}; + attribs attr{}; + + constexpr cell() = default; + constexpr cell(chartype Chr) : chr(Chr) {} + constexpr cell(chartype Chr, color Fg) : chr(Chr), attr(Fg) {} + constexpr cell(chartype Chr, color Bg, color Fg) : chr(Chr), attr(Bg, Fg) {} + constexpr cell(chartype Chr, color Bg, color Fg, bool B, bool U) : chr(Chr), attr(Bg, Fg, B, U) {} + constexpr cell(chartype Chr, attribs Attr) : chr(Chr), attr(Attr) {} + + constexpr bool operator==(const cell &o) const = default; +}; + +const std::string ANSI_ESCAPE = "\E["; +static void ANSI_MOVE(unsigned x, unsigned y) { std::cout << ANSI_ESCAPE << y+1 << ';' << x+1 << 'H' << std::flush; } +static void ANSI_COLOR_FG(color c) { std::cout << ANSI_ESCAPE << "38;2;" << (unsigned)c.r << ';' << (unsigned)c.g << ';' << (unsigned)c.b << 'm' << std::flush; } +static void ANSI_COLOR_BG(color c) { std::cout << ANSI_ESCAPE << "48;2;" << (unsigned)c.r << ';' << (unsigned)c.g << ';' << (unsigned)c.b << 'm' << std::flush; } + +class screen_command_base {}; + +template<char_type chartype> +class screen { +public: + explicit screen(unsigned X, unsigned Y, unsigned W, unsigned H, chartype C, color B, color F) : + m_x(X), m_y(Y), m_width(W), m_height(H), m_front(W * H, cell{C, B, F}), m_back(m_front), + m_cursorAttribs(B,F), m_fillChar(C) + { + redraw(); + } + + explicit screen(unsigned X, unsigned Y, unsigned W, unsigned H, chartype C) : + screen(X, Y, W, H, C, color{0, 0, 0}, color{255, 255, 255}) {} + explicit screen(unsigned X, unsigned Y, unsigned W, unsigned H) : + screen(X, Y, W, H, ' ') {} + + constexpr void setcursorxy(unsigned x, unsigned y) { m_cursorX = x; m_cursorY = y; } + constexpr void setcursorfg(uint8_t r, uint8_t g, uint8_t b) { m_cursorAttribs.fg = color{r, g, b}; } + constexpr void setcursorbg(uint8_t r, uint8_t g, uint8_t b) { m_cursorAttribs.bg = color{r, g, b}; } + constexpr void setcursorfg(color c) { m_cursorAttribs.fg = c; } + constexpr void setcursorbg(color c) { m_cursorAttribs.bg = c; } + constexpr void setcursorbold(bool bold) { m_cursorAttribs.bold = bold; } + constexpr void setcursorunderline(bool underline) { m_cursorAttribs.underline = underline; } + + constexpr unsigned getcursorx() { return m_cursorX; } + constexpr unsigned getcursory() { return m_cursorY; } + constexpr unsigned getx() { return m_x; } + constexpr unsigned gety() { return m_y; } + constexpr unsigned getwidth() { return m_width; } + constexpr unsigned getheight() { return m_height; } + + void clear(const chartype c) { std::fill(m_front.begin(), m_front.end(), cell{c, m_cursorAttribs}); } + + void clearrow(unsigned y, const chartype c) { + assert(y < m_height); + std::fill(m_front.begin() + (y * m_width), + m_front.begin() + (y * m_width) + m_width, + cell{c, m_cursorAttribs}); + } + + void scroll() { + m_cursorY = m_height - 1; + std::copy(m_front.begin() + m_width, m_front.end(), m_front.begin()); + std::fill(m_front.end() - m_width, m_front.end(), cell{m_fillChar, m_cursorAttribs}); + } + + void setc(unsigned x, unsigned y, chartype c) { + assert(x < m_width); + assert(y < m_height); + m_front[x + (y * m_width)] = cell{c, m_cursorAttribs}; + } + + void putc(chartype c){ + if(m_cursorY == m_height) { + scroll(); + } + switch(c) { + case '\n': + m_cursorX = 0; m_cursorY++; + break; + default: + (*this)[m_cursorY][m_cursorX++] = + cell{c, m_cursorAttribs}; + break; + } + if(m_cursorX == m_width) { + m_cursorY++; + m_cursorX = 0; + } + } + + void puts(const std::basic_string<chartype> &s){ + for(const chartype &c : s) this->putc(c); + } + + void redraw() { + attribs cattr = (*this)[0][0].attr; + ANSI_COLOR_BG(cattr.bg); + ANSI_COLOR_FG(cattr.fg); + for(unsigned y = 0; y < m_height; y++) { + ANSI_MOVE(m_x, m_y + y); + for(cell c : (*this)[y]) { + if(cattr != c.attr) { + cattr = c.attr; + ANSI_COLOR_FG(cattr.fg); + ANSI_COLOR_BG(cattr.bg); + } + std::cout << c.chr; + } + std::cout.clear(); + } + m_back = m_front; + } + + void flush() { + attribs currAttr = m_front[0].attr; + ANSI_COLOR_FG(currAttr.fg); + ANSI_COLOR_BG(currAttr.bg); + for(unsigned y = 0; y < m_height; y++) { + auto backspan = std::span<cell<chartype>>( + m_back.begin() + (y * m_width), + m_back.begin() + (y * m_width) + m_width); + auto frontspan = (*this)[y]; + bool change = false; + if(std::equal(backspan.begin(), backspan.end(), frontspan.begin(), frontspan.end())) continue; + for(unsigned x = 0; x < m_width; x++) { + cell c = frontspan[x]; + if(c == backspan[x]) continue; + ANSI_MOVE(x + m_x, y + m_y); + if(c.attr != currAttr) { + ANSI_COLOR_FG(c.attr.fg); + ANSI_COLOR_BG(c.attr.bg); + currAttr = c.attr; + } + change = true; + std::cout << c.chr; + } + if(change) std::cout.clear(); + } + m_back = m_front; + } + + std::span<cell<chartype>> operator[](std::size_t i) { + assert(i < m_width * m_height); + return std::span<cell<chartype>>( + m_front.begin() + (i * m_width), + m_front.begin() + (i * m_width) + m_width); + } + + template<typename T> + requires(!std::is_base_of<screen_command_base, T>::value) + friend screen &operator<<(screen &o, const T &rhs) { + std::basic_stringstream<chartype> ss; + ss << rhs; + o.puts(ss.str()); + return o; + } + +private: + unsigned m_x{}, m_y{}; + unsigned m_width{}, m_height{}; + + std::vector<cell<chartype>> m_front; + std::vector<cell<chartype>> m_back; + + unsigned m_cursorX{}, m_cursorY{}; + attribs m_cursorAttribs; + chartype m_fillChar; +}; + +struct screen_command_flush : public screen_command_base { + explicit screen_command_flush() = default; + template<char_type T> + friend screen<T> &operator<<(screen<T> &o, const screen_command_flush &cmd) { + (void)cmd; + o.flush(); + return o; + } +}; +[[nodiscard]] static screen_command_flush flush() { return screen_command_flush{}; } + +struct screen_command_redraw : public screen_command_base { + explicit screen_command_redraw() = default; + template<char_type T> + friend screen<T> &operator<<(screen<T> &o, const screen_command_redraw &cmd) { + (void)cmd; + o.redraw(); + return o; + } +}; +[[nodiscard]] static screen_command_redraw redraw() { return screen_command_redraw{}; } + +template<char_type chartype> +struct screen_command_clear : public screen_command_base { + chartype c; + explicit screen_command_clear(chartype C) : c(C) {} + friend screen<chartype> &operator<<(screen<chartype> &o, const screen_command_clear &cmd) { + o.clear(cmd.c); + return o; + } +}; +template<char_type chartype> +[[nodiscard]] static screen_command_clear<chartype> clear() { return screen_command_clear{chartype{}}; } +template<char_type chartype> +[[nodiscard]] static screen_command_clear<chartype> clear(chartype c) { return screen_command_clear{c}; } + +struct screen_command_move : public screen_command_base { + unsigned x, y; + explicit screen_command_move(unsigned X, unsigned Y) : x(X), y(Y) {} + template<char_type T> + friend screen<T> &operator<<(screen<T> &o, const screen_command_move &cmd) { + o.setcursorxy(cmd.x, cmd.y); + return o; + } +}; +[[nodiscard]] static screen_command_move move(unsigned x, unsigned y) { return screen_command_move{x, y}; } + +template<char_type chartype> +struct screen_command_plot : public screen_command_base { + chartype c; + unsigned x, y; + explicit screen_command_plot(unsigned X, unsigned Y, chartype C) : c(C), x(X), y(Y) {} + friend screen<chartype> &operator<<(screen<chartype> &o, const screen_command_plot &cmd) { + o.setc(cmd.x, cmd.y, cmd.c); + return o; + } +}; +template<char_type T> +[[nodiscard]] static screen_command_plot<T> plot(unsigned x, unsigned y, T c) { return screen_command_plot{x, y, c}; } + +struct screen_command_recolor : public screen_command_base { + color fg, bg; + bool rfg, rbg; + explicit screen_command_recolor(color Fg, bool side) : fg(Fg), bg(Fg), rfg(side ? true : false), rbg(side ? false : true) {} + explicit screen_command_recolor(color Fg, color Bg) : fg(Fg), bg(Bg), rfg(true), rbg(true) {} + + template<char_type T> + friend screen<T> &operator<<(screen<T> &o, const screen_command_recolor &cmd) { + if(cmd.rbg) o.setcursorbg(cmd.bg); + if(cmd.rfg) o.setcursorfg(cmd.fg); + return o; + } +}; +[[nodiscard]] static screen_command_recolor setfg(uint8_t r, uint8_t g, uint8_t b) { return screen_command_recolor{color{r, g, b}, true}; } +[[nodiscard]] static screen_command_recolor setbg(uint8_t r, uint8_t g, uint8_t b) { return screen_command_recolor{color{r, g, b}, false}; } +[[nodiscard]] static screen_command_recolor setcolor(color fg, color bg) { return screen_command_recolor{fg, bg}; } +[[nodiscard]] static screen_command_recolor resetcolor() { return screen_command_recolor{WHITE, BLACK}; } + +template<char_type chartype> +struct screen_command_fillrow : public screen_command_base { + unsigned row; + chartype c; + + friend screen<chartype> &operator<<(screen<chartype> &o, const screen_command_fillrow &cmd) { + o.clearrow(cmd.row, cmd.c); + return o; + } +}; + +template<char_type T> +[[nodiscard]] static screen_command_fillrow<T> fillrow(unsigned row) { return screen_command_fillrow<T>{.row = row, .c = ' '}; } +template<char_type T> +[[nodiscard]] static screen_command_fillrow<T> fillrow(unsigned row, T c) { return screen_command_fillrow<T>{.row = row, .c = c}; } + +} + +#endif diff --git a/include/system.hpp b/include/system.hpp new file mode 100644 index 0000000..9de10bc --- /dev/null +++ b/include/system.hpp @@ -0,0 +1,82 @@ +#ifndef SYSTEM_HPP +#define SYSTEM_HPP 1 + +#include "ecs.hpp" +#include "camera.hpp" +#include "window.hpp" + +#include <list> + +class System { +private: + friend class SystemView; + struct SystemTreeNode { + unsigned entityId; + std::list<SystemTreeNode> children; + }; + SystemTreeNode m_systemTree; + ecs::EntityMan m_entityMan; + + ecs::Entity &addOrbital(const std::string &name, const std::string &orbitingName, unsigned long a, double e, unit::Mass m, unsigned r, double M, double w); + void tickOrbitals(unit::Time time); + + SystemTreeNode *traverseSystemTree(SystemTreeNode &node, const std::string &name); + SystemTreeNode *getNode(const std::string &name); +public: + System(); + + void update(); + + ecs::Entity &getBody(std::size_t id); +}; + +class SystemView { +private: + System *m_system; + System::SystemTreeNode *m_focus; + + class Search { + private: + struct SystemTreeDisplayNode { + System::SystemTreeNode *node; + std::list<SystemTreeDisplayNode> children; + SystemTreeDisplayNode *parent; + + unsigned index; + bool collapsed; + bool hidden; + }; + SystemView *m_systemView; + SystemTreeDisplayNode m_displayTree; + std::vector<SystemTreeDisplayNode*> m_displayTreeFlat; + + unsigned m_selectionIndex; + std::string m_query; + bool m_dirty; + + void addNodeToTree(SystemTreeDisplayNode &root, System::SystemTreeNode *node); + void drawNode(SystemTreeDisplayNode &root, Window &searchWindow, unsigned indent); + void rebuild(); + public: + Search(SystemView *systemView); + + void finish(); + void keypress(int key); + void draw(); + }; + std::unique_ptr<Search> m_focusSearch; +public: + SystemView(System *system) : m_system(system), m_focusSearch(nullptr) {} + + void keypress(Camera *camera, int key); + void update(Camera *camera); + void draw(Camera *camera); + void drawOver(Camera *camera); + + void view(System *system); + + ecs::Entity &getBody(int id) const; + int getBodyIdByName(const std::string &name); +}; + +#endif diff --git a/include/timeman.hpp b/include/timeman.hpp new file mode 100644 index 0000000..ac5113e --- /dev/null +++ b/include/timeman.hpp @@ -0,0 +1,27 @@ +#ifndef TIME_MANAGER_H +#define TIME_MANAGER_H 1 + +#include "util.hpp" +#include "units.hpp" +#include "straw.hpp" +#include "window.hpp" + +class TimeMan { + static unit::Time m_time; + static unit::Time m_step; + static bool m_auto; + static bool m_changed; +public: + + static void init(); + + static void update(int c); + static void draw(); + + static unit::Time time() { return m_time; } + static bool automatic() { return m_auto; } + static void interrupt() { m_auto = false; } + static bool changed() { return m_changed; } +}; + +#endif diff --git a/include/units.hpp b/include/units.hpp new file mode 100644 index 0000000..5f2fd67 --- /dev/null +++ b/include/units.hpp @@ -0,0 +1,166 @@ +#ifndef UNIT_HPP +#define UNIT_HPP 1 + +#include "util.hpp" +#include <string> + +namespace unit { + +constexpr long MINUTE_SECONDS = 60; +constexpr long HOUR_SECONDS = 3600; +constexpr long DAY_SECONDS = 86400; +constexpr long WEEK_SECONDS = 604800; +constexpr long YEAR_SECONDS = 31556952; +constexpr long CYEAR_SECONDS = 31536000; + +class Mass { + double m_kg; +public: + explicit constexpr Mass(double kg) : m_kg(kg) {} + constexpr ~Mass() = default; + + constexpr double operator()() { return m_kg; } + + constexpr Mass &operator+=(const Mass &rhs) { this->m_kg += rhs.m_kg; return *this; } + constexpr Mass &operator-=(const Mass &rhs) { this->m_kg -= rhs.m_kg; return *this; } + constexpr Mass &operator/=(const Mass &rhs) { this->m_kg *= rhs.m_kg; return *this; } + constexpr Mass &operator*=(const Mass &rhs) { this->m_kg /= rhs.m_kg; return *this; } + + friend Mass operator+(Mass lhs, const Mass &rhs) { lhs += rhs; return lhs; } + friend Mass operator-(Mass lhs, const Mass &rhs) { lhs -= rhs; return lhs; } + friend Mass operator*(Mass lhs, const Mass &rhs) { lhs *= rhs; return lhs; } + friend Mass operator/(Mass lhs, const Mass &rhs) { lhs /= rhs; return lhs; } + + friend inline bool operator<=>(const Mass &lhs, const Mass &rhs) = default; + + constexpr Mass &operator+=(const double &rhs) { this->m_kg += rhs; return *this; } + constexpr Mass &operator-=(const double &rhs) { this->m_kg -= rhs; return *this; } + constexpr Mass &operator*=(const double &rhs) { this->m_kg *= rhs; return *this; } + constexpr Mass &operator/=(const double &rhs) { this->m_kg /= rhs; return *this; } + + friend Mass operator+(Mass lhs, const double &rhs) { lhs += rhs; return lhs; } + friend Mass operator-(Mass lhs, const double &rhs) { lhs -= rhs; return lhs; } + friend Mass operator*(Mass lhs, const double &rhs) { lhs *= rhs; return lhs; } + friend Mass operator/(Mass lhs, const double &rhs) { lhs /= rhs; return lhs; } +}; + +class Time { + long m_seconds; +public: + static constexpr unsigned char month_days[12] = { + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 + }; + static constexpr unsigned char month_days_leap[12] = { + 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 + }; + static const inline std::string month_str[12] = { + "January", "Febuary", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" + }; + + explicit constexpr Time(long seconds) : m_seconds(seconds) {} + + constexpr long operator()() { return m_seconds; } + + constexpr Time &operator+=(const Time &rhs) { this->m_seconds += rhs.m_seconds; return *this; } + constexpr Time &operator-=(const Time &rhs) { this->m_seconds -= rhs.m_seconds; return *this; } + constexpr Time &operator/=(const Time &rhs) { this->m_seconds *= rhs.m_seconds; return *this; } + constexpr Time &operator*=(const Time &rhs) { this->m_seconds /= rhs.m_seconds; return *this; } + + friend Time operator+(Time lhs, const Time &rhs) { lhs += rhs; return lhs; } + friend Time operator-(Time lhs, const Time &rhs) { lhs -= rhs; return lhs; } + friend Time operator*(Time lhs, const Time &rhs) { lhs *= rhs; return lhs; } + friend Time operator/(Time lhs, const Time &rhs) { lhs /= rhs; return lhs; } + + friend inline bool operator<=>(const Time &lhs, const Time &rhs) = default; + + constexpr Time &operator+=(const long &rhs) { this->m_seconds += rhs; return *this; } + constexpr Time &operator-=(const long &rhs) { this->m_seconds -= rhs; return *this; } + constexpr Time &operator*=(const long &rhs) { this->m_seconds *= rhs; return *this; } + constexpr Time &operator/=(const long &rhs) { this->m_seconds /= rhs; return *this; } + + friend Time operator+(Time lhs, const long &rhs) { lhs += rhs; return lhs; } + friend Time operator-(Time lhs, const long &rhs) { lhs -= rhs; return lhs; } + friend Time operator*(Time lhs, const long &rhs) { lhs *= rhs; return lhs; } + friend Time operator/(Time lhs, const long &rhs) { lhs /= rhs; return lhs; } + + constexpr bool leap_year() { return (m_seconds % YEAR_SECONDS) % 4 == 0; } + + constexpr Time current_year() { + return Time((m_seconds % YEAR_SECONDS) + (m_seconds < 0 ? YEAR_SECONDS : 0)); + } + constexpr Time current_month() { + Time year = current_year(); + if(year.m_seconds < 0) { + year.m_seconds = YEAR_SECONDS + year.m_seconds; + } + unsigned month = 0; + const unsigned char *month_days_view = month_days; + if(years() % 4 == 0 && years() % 100 == 0 && years() % 400 != 0) month_days_view = month_days_leap; + for(month; year.days() > month_days_view[month]; month = (month + 1) % 12) year -= month_days_view[month] * DAY_SECONDS; + return year; + } + constexpr Time current_week() { return Time(m_seconds % WEEK_SECONDS); } + constexpr Time current_day() { return Time(m_seconds % DAY_SECONDS); } + constexpr Time current_hour() { return Time(m_seconds % HOUR_SECONDS); } + constexpr Time current_minute() { return Time(m_seconds % MINUTE_SECONDS); } + + constexpr long seconds() { return m_seconds; } + constexpr long minutes() { return m_seconds / MINUTE_SECONDS; } + constexpr long hours() { return m_seconds / HOUR_SECONDS; } + constexpr long days() { return m_seconds / DAY_SECONDS; } + constexpr long weeks() { return m_seconds / WEEK_SECONDS; } + constexpr long months() { + Time copy(*this); + if(copy.m_seconds < 0) { + copy.m_seconds = -copy.m_seconds; + } + unsigned month = 0; + const unsigned char *month_days_view = month_days; + if(years() % 4 == 0) month_days_view = month_days_leap; + for(month; copy.days() > month_days_view[month]; month = (month + 1) % 12) copy -= month_days_view[month] * DAY_SECONDS; + return month; + } + constexpr long years() { return ((m_seconds < 0 ? m_seconds - CYEAR_SECONDS : m_seconds) / CYEAR_SECONDS) + 2000; } + constexpr long real_years() { return (m_seconds < 0 ? m_seconds - YEAR_SECONDS : m_seconds) / YEAR_SECONDS; } + + /* %% = '%' + * %Y = real year + * %C = calendar year + * %S = month string + * %M = month + * %W = week + * %D = day + * %H = hour + * %m = minute + * %s = second + * */ + std::string format(const char *fmt); +}; + +constexpr long Mm = 1000; +constexpr long Gm = cxpow_v<long, 10, 6>; +constexpr long Tm = cxpow_v<long, 10, 9>; +constexpr long Pm = cxpow_v<long, 10, 12>; +constexpr long Em = cxpow_v<long, 10, 15>; +constexpr long Zm = cxpow_v<long, 10, 18>; + +constexpr long AU = 149597871; + +constexpr Mass kg{1}; +constexpr Mass Mg{cxpow_v<double, 10, 3>}; +constexpr Mass Gg{cxpow_v<double, 10, 6>}; +constexpr Mass Tg{cxpow_v<double, 10, 9>}; +constexpr Mass Pg{cxpow_v<double, 10, 12>}; +constexpr Mass Eg{cxpow_v<double, 10, 15>}; +constexpr Mass Zg{cxpow_v<double, 10, 18>}; +constexpr Mass Yg{cxpow_v<double, 10, 21>}; + +constexpr Mass lunarMass{7.342 * cxpow_v<double, 10, 22>}; +constexpr Mass earthMass{5.97237 * cxpow_v<double, 10, 24>}; +constexpr Mass jovMass{1.89813 * cxpow_v<double, 10, 27>}; +constexpr Mass solMass{1.98847 * cxpow_v<double, 10, 30>}; + +constexpr double earthRad = 6371; +} + +#endif diff --git a/include/util.hpp b/include/util.hpp new file mode 100644 index 0000000..3c795d1 --- /dev/null +++ b/include/util.hpp @@ -0,0 +1,45 @@ +#include <type_traits> +#ifndef UTIL_HPP +#define UTIL_HPP 1 + +#include <variant> +#include <cstddef> + +#if UNICODE == 1 +using screenchr = wchar_t; +#else +using screenchr = char; +#endif + +/*Shamelessly stolen from stackoverflow + * https://stackoverflow.com/questions/52303316/get-index-by-type-in-stdvariant + * by Barry*/ +template <typename> struct tag { }; +template <typename T, typename V> +struct get_index; +template <typename T, typename... Ts> +struct get_index<T, std::variant<Ts...>> + : std::integral_constant<size_t, std::variant<tag<Ts>...>(tag<T>()).index()> +{ }; + +template<typename T, typename variant_type> +struct is_variant : std::false_type {}; +template<typename T, typename ... Vs> +struct is_variant<T, std::variant<Vs...>> + : std::disjunction<std::is_same<T, Vs>...> {}; +template<typename T, typename variant_type> +constexpr bool is_variant_v = is_variant<T, variant_type>::value; + +template<typename T, unsigned base, unsigned p> +struct cxpow { static constexpr T value = (T)base * cxpow<T, base, p - 1>::value; }; +template<typename T, unsigned base> +struct cxpow<T, base, 0> { static constexpr T value = 1; }; +template<typename T, unsigned base, unsigned p> +constexpr T cxpow_v = cxpow<T, base, p>::value; + +template<typename T, unsigned base, int p> +struct cxrt { static constexpr T value = (T)base / cxpow<T, base, -p>::value; }; +template<typename T, unsigned base, int p> +constexpr T cxrt_v = cxrt<T, base, p>::value; + +#endif diff --git a/include/vex.hpp b/include/vex.hpp new file mode 100644 index 0000000..0a3bb24 --- /dev/null +++ b/include/vex.hpp @@ -0,0 +1,104 @@ +#ifndef VEX_H +#define VEX_H 1 + +#include <array> +#include <cmath> +#include <cstddef> +#include <ostream> +#include <concepts> + +namespace vex +{ + +template<typename T> +concept arithmetic = std::is_arithmetic<T>::value; + +template<arithmetic T, unsigned D> + requires (D > 1) +struct vec_dimd +{ + std::array<T, D> v; + + explicit vec_dimd() = default; + template<typename ...Args> + explicit vec_dimd(Args&&... args) : v{args...} {} + explicit vec_dimd(T args[D]) : v(args) {} + explicit vec_dimd(T fill) { v.fill(fill); } + + T operator[](std::size_t i) { return v[i]; } + T operator[](std::size_t i) const { return v[i]; } + + vec_dimd<T, D> operator+=(const vec_dimd<T, D> &rhs) { for(size_t i = 0; i < D; i++) v[i] += rhs.v[i]; return *this; } + vec_dimd<T, D> operator-=(const vec_dimd<T, D> &rhs) { for(size_t i = 0; i < D; i++) v[i] -= rhs.v[i]; return *this; } + vec_dimd<T, D> operator*=(const vec_dimd<T, D> &rhs) { for(size_t i = 0; i < D; i++) v[i] *= rhs.v[i]; return *this; } + vec_dimd<T, D> operator/=(const vec_dimd<T, D> &rhs) { for(size_t i = 0; i < D; i++) v[i] /= rhs.v[i]; return *this; } + + vec_dimd<T, D> operator*=(const T &rhs) { for(size_t i = 0; i < D; i++) v[i] *= rhs; return *this; } + vec_dimd<T, D> operator/=(const T &rhs) { for(size_t i = 0; i < D; i++) v[i] /= rhs; return *this; } + + vec_dimd<T, D> operator-() { return vec_dimd<T,D>(0) - *this; } + + auto operator<=>(const vec_dimd<T,D> &rhs) const { return magnitude() <=> rhs.magnitude(); } + bool operator==(const vec_dimd<T,D> &rhs) const { for(unsigned i = 0; i < D; i++) if(v[i] != rhs.v[i]) return false; return true; } + + friend vec_dimd<T, D> operator+(vec_dimd<T, D> lhs, const vec_dimd<T, D> &rhs) { lhs += rhs; return lhs; } + friend vec_dimd<T, D> operator-(vec_dimd<T, D> lhs, const vec_dimd<T, D> &rhs) { lhs -= rhs; return lhs; } + friend vec_dimd<T, D> operator*(vec_dimd<T, D> lhs, const vec_dimd<T, D> &rhs) { lhs *= rhs; return lhs; } + friend vec_dimd<T, D> operator/(vec_dimd<T, D> lhs, const vec_dimd<T, D> &rhs) { lhs /= rhs; return lhs; } + + friend vec_dimd<T, D> operator*(vec_dimd<T, D> lhs, const T &rhs) { lhs *= rhs; return lhs; } + friend vec_dimd<T, D> operator/(vec_dimd<T, D> lhs, const T &rhs) { lhs /= rhs; return lhs; } + + friend std::ostream &operator<<(std::ostream &os, const vec_dimd<T,D> obj) { + os << '{'; + for(std::size_t i = 0; i < D; i++) os << obj.v[i] << ((i < (D - 1)) ? ',' : '}'); + return os; + } + + /*Finds the distance from the origin to the ray cast in D dimension space using components of vec*/ + T sqrMagnitude() const { T t{}; for(size_t i = 0; i < D; i++) t += v[i] * v[i]; return t; } + T magnitude() const { return std::sqrt(sqrMagnitude()); } + + /*Finds the dot product of itself and another vec of same T and D*/ + T dot(const vec_dimd<T, D> &b) const { T t; for(size_t i = 0; i < D; i++) t += (v[i] * b.v[i]); return t; } + friend T dot(const vec_dimd<T,D> &lhs, const vec_dimd<T,D> &rhs) { return lhs.dot(rhs); } + + vex::vec_dimd<T, D> normalize() const { return *this / magnitude(); } + vex::vec_dimd<T, D> abs() const { vex::vec_dimd<T, D> copy(*this); for(unsigned i = 0; i < D; i++) copy.v[i] = std::abs(copy.v[i]); return copy; } + + auto cross(const vec_dimd<T,D> &o) const { + if constexpr(D == 2) return v[0]*o[0] - v[1]*o[1]; + if constexpr(D == 3) return vec_dimd<T, D>{v[1]*o[2]-v[2]*o[1], v[2]*o[0]-v[0]*o[2],v[0]*o[1]-v[1]*o[0]}; + } +}; + +template<arithmetic T> +using vec2 = vec_dimd<T, 2>; + +template<arithmetic T> +using vec3 = vec_dimd<T, 3>; + +/*(x, y) -> (r, theta)*/ +template<arithmetic R, arithmetic P> +static vec2<R> +polar(const vec2<P> &in) +{ + return vec2<R>( + std::sqrt(in[0] * in[0] + in[1] * in[1]), + std::atan2(in[1], in[0]) + ); +} +/*(r, theta) -> (x, y)*/ +template<arithmetic R, arithmetic P> +static vec2<R> +cartesian(const vec2<P> &in) +{ + return vec2<R>( + (R)(cos(in[1]) * in[0]), + (R)(sin(in[1]) * in[0]) + ); +} + +}; + +#endif diff --git a/include/window.hpp b/include/window.hpp new file mode 100644 index 0000000..78001ea --- /dev/null +++ b/include/window.hpp @@ -0,0 +1,69 @@ +#ifndef WINDOW_HPP +#define WINDOW_HPP 1 + +#include "util.hpp" +#include "straw.hpp" +#include <memory> +#include <unordered_map> + +//Wrapper for screens that act like windows +class Window { + straw::screen<screenchr> m_border; + straw::screen<screenchr> m_screen; + std::string m_title; + bool m_hidden; +public: + explicit Window(const std::string Title, unsigned X, unsigned Y, unsigned W, unsigned H, bool hidden = false) : + m_border(X, Y, W, 1), m_screen(X, Y+1, W, H-1), m_title(Title), m_hidden(hidden) {} + ~Window() = default; + + template<typename T> + friend Window &operator<<(Window &o, const T &t) { + o.m_screen << t; + return o; + } + + straw::screen<screenchr> *screen() { return &m_screen; } + std::string title() const { return m_title; } + + void draw(bool focus); + + void setHidden(bool mode) { m_hidden = mode; } + bool hidden() const { return m_hidden; } +}; + +#define WINDOW_SYSTEMVIEW_ID "Systemview" +#define WINDOW_SYSTEMVIEW_SEARCH_ID "SystemviewSearch" +#define WINDOW_BODYINFO_ID "Bodyinfo" +#define WINDOW_EVENTS_ID "Events" +#define WINDOW_TIMEMAN_ID "Timeman" + +class WindowContext { + std::unordered_map<std::string, Window> m_windows; + std::vector<std::string> m_windowOrder; + unsigned m_focus; +public: + WindowContext() : m_focus(0) {} + ~WindowContext() {} + + void registerWindow(const std::string &id, + const std::string &title, + unsigned x, unsigned y, + unsigned w, unsigned h, + bool hidden = false); + + Window &operator[](const std::string &id) { return m_windows.at(id); } + Window &operator[](unsigned id) { return m_windows.at(m_windowOrder[id]); } + Window &operator()() { return m_windows.at(m_windowOrder[m_focus]); } + + void update(int code); + void draw(); + + void setWindowHidden(const std::string &id, bool mode); + void focus(const std::string &id); + + unsigned getFocused() { return m_focus; } + std::string getFocusedString() { return m_windowOrder[m_focus]; } +}; + +#endif diff --git a/src/camera.cpp b/src/camera.cpp new file mode 100644 index 0000000..59e99a0 --- /dev/null +++ b/src/camera.cpp @@ -0,0 +1,197 @@ +#include "camera.hpp" +#include "shape.hpp" +#include <cmath> +#include <algorithm> +#include <variant> +#include <typeinfo> +#include <any> + +void +Camera::updateFrustum(){ + if(m_dirty) { + *m_viewport << straw::clear(' '); + m_frustum = shapes::rectangle<long>(0, 0, (long)m_viewport->getwidth(), (long)m_viewport->getheight()); + m_frustum.position -= (m_frustum.bounds / 2); + m_frustum.position += m_position + m_origin; + m_dirty = false; + } +} + +void +RenderBatchEntry::translate(Camera *camera) +{ + std::visit([camera](auto &shapeval) { + shapeval.translate(-camera->m_frustum.position); + shapeval.translate((camera->m_frustum.bounds * camera->m_scale) / 2); + shapeval.position = vex::vec2<long>( + (long)std::floor((double)shapeval.position[0] / (double)camera->m_scale), + (long)std::floor((double)shapeval.position[1] / (double)camera->m_scale)); + shapeval.scale(camera->m_scale); + }, shape); +} + +void +Camera::draw() +{ + if(!m_dirty) return; + updateFrustum(); + shapes::rectangle<long> ssfrustum{vex::vec2<long>(0, 0), vex::vec2<long>(m_viewport->getwidth(), m_viewport->getheight())}; + + //Remove all batches not intersecting the screenspace frustum + m_shapeBatch.erase( + std::remove_if( + m_shapeBatch.begin(), + m_shapeBatch.end(), + [ssfrustum, this](RenderBatchEntry &entry){ + entry.translate(this); + return std::visit([ssfrustum](auto &&shape) { + return shapes::intersects(shape, ssfrustum) == 0; + }, entry.shape); + }), + m_shapeBatch.end()); + for(RenderBatchEntry &entry : m_shapeBatch) entry.plot(this); + m_shapeBatch.clear(); +} + +void +RenderBatchEntry::plotPoint(shapes::point<long> point, Camera *camera) { + long ploty = camera->m_viewport->getheight() - point.position[1]; + if(point.position[0] < 0 || point.position[0] >= camera->m_viewport->getwidth() || + ploty < 0 || ploty >= camera->m_viewport->getheight()) return; + *camera->m_viewport << straw::setcolor(fg, bg) << straw::plot(point.position[0], ploty, c); +} + +void +RenderBatchEntry::plotLine(shapes::line<long> line, Camera *camera) { + if(line.end == line.position) { + plotPoint(shapes::point<long>(line.position), camera); + } + vex::vec2<long> vpdim(camera->m_viewport->getwidth(), + camera->m_viewport->getheight()); + vex::vec2<long> d(line.end - line.position); + long adx = std::abs(d[0]); + long ady = std::abs(d[1]); + + long offX= d[0] > 0 ? 1 : -1; + long offY = d[1] > 0 ? 1 : -1; + + *camera->m_viewport << straw::setcolor(fg, bg); + if(adx < ady) { + long err = ady / 2; + long x = line.position[0]; + long y = line.position[1]; + for(long i = 0; i < ady; i++) { + if(x > 0 && x < vpdim[0] && y > 0 && y < vpdim[1]) { + long ploty = vpdim[1] - y; + *camera->m_viewport << straw::plot(x, ploty, c); + } + if(err >= ady) { + x += offX; + y += offY; + err += adx - ady; + }else { + y += offY; + err += adx; + } + } + + }else{ + long err = adx / 2; + long x = line.position[0]; + long y = line.position[1]; + for(long i = 0; i < adx; i++) { + if(x > 0 && x < vpdim[0] && y > 0 && y < vpdim[1]) { + long ploty = vpdim[1] - y; + *camera->m_viewport << straw::plot(x, ploty, c); + } + if(err >= adx) { + x += offX; + y += offY; + err += ady - adx; + }else { + x += offX; + err += ady; + } + } + } +} + +void +RenderBatchEntry::plotCircle(shapes::circle<long> circle, Camera *camera) { + if(circle.radius == 1) { + plotPoint(shapes::point<long>(circle.position), camera); + return; + } + long sy = std::max<long>(1, circle.position[1] - circle.radius); + long ey = std::min<long>(camera->m_viewport->getheight(), circle.position[1] + circle.radius); + *camera->m_viewport << straw::setcolor(fg, bg); + for(long y = sy; y <= ey; y++) { + long ploty = camera->m_viewport->getheight() - y; + long r2 = circle.radius * circle.radius; + long dy = circle.position[1] - y; + long dx = (long)std::sqrt(r2 - (dy * dy)); + long sx = std::max<long>(0, circle.position[0] - dx + 1); + long ex = std::min<long>(camera->m_viewport->getwidth(), circle.position[0] + dx); + for(unsigned x = (unsigned)sx; x < ex; x++) { + *camera->m_viewport << straw::plot(x, ploty, c); + } + } +} + +void +RenderBatchEntry::plotRectangle(shapes::rectangle<long> rectangle, Camera *camera) +{ + if(rectangle.bounds[1] == 1) { + plotPoint(shapes::point<long>(rectangle.position), camera); + return; + } + long sy = std::max<long>(1, rectangle.position[1]); + long ey = std::min<long>(camera->m_viewport->getheight(), rectangle.position[1] + rectangle.bounds[1]); + *camera->m_viewport << straw::setcolor(fg, bg); + for(long y = sy; y < ey; y++) { + long ploty = camera->m_viewport->getheight() - y; + long sx = std::max<long>(0, rectangle.position[1]); + long ex = std::min<long>(camera->m_viewport->getwidth(), rectangle.position[1] + rectangle.bounds[1]); + for(unsigned x = (unsigned)sx; x < ex; x++) { + *camera->m_viewport << straw::plot(x, ploty, c); + } + } +} + +void +RenderBatchEntry::plotEllipse(shapes::ellipse<long> shapeval, Camera *camera) { + if(shapeval.a == 1) { + plotPoint(shapes::point<long>(shapeval.position), camera); + return; + } + long sy = std::max<long>(1, shapeval.position[1] - shapeval.b); + long ey = std::min<long>(camera->m_viewport->getheight(), shapeval.position[1] + shapeval.b); + *camera->m_viewport << straw::setcolor(fg, bg); + for(long y = sy; y <= ey; y++) { + long ploty = camera->m_viewport->getheight() - y; + long dy = shapeval.position[1] - y; + long dy2 = dy * dy; + long a2 = shapeval.a * shapeval.a; + long b2 = shapeval.b * shapeval.b; + long dx = (long)(((2.0 * (double)shapeval.a) / + (double)shapeval.b) * std::sqrt(b2 - dy2) / 2.0); + long sx = std::max<long>(0, shapeval.position[0] - dx + 1); + long ex = std::min<long>(camera->m_viewport->getwidth(), shapeval.position[0] + dx); + + for(unsigned x = (unsigned)sx; x < ex; x++) { + *camera->m_viewport << straw::plot(x, ploty, c); + } + } +} +void +RenderBatchEntry::plot(Camera *camera) +{ + std::visit([this, camera](auto &shapeval) -> void{ + using T = std::decay_t<decltype(shapeval)>; + if constexpr(std::is_same_v<T, shapes::point<long>>) plotPoint(shapeval, camera); + if constexpr(std::is_same_v<T, shapes::line<long>>) plotLine(shapeval, camera); + if constexpr(std::is_same_v<T, shapes::ellipse<long>>) plotEllipse(shapeval, camera); + if constexpr(std::is_same_v<T, shapes::circle<long>>) plotCircle(shapeval, camera); + if constexpr(std::is_same_v<T, shapes::rectangle<long>>) plotRectangle(shapeval, camera); + }, shape); +} diff --git a/src/game.cpp b/src/game.cpp new file mode 100644 index 0000000..b1d0b00 --- /dev/null +++ b/src/game.cpp @@ -0,0 +1,115 @@ +#include "game.hpp" +#include "keybind.hpp" +#include "input.hpp" +#include <thread> +#include <chrono> + +constexpr static double REQUESTED_FPS = 60.0; +constexpr static double REQ_FPS_MSPT = 1000.0 / REQUESTED_FPS; + +std::unordered_map<std::string, WindowContext> Game::m_contexts; +std::string Game::m_currentContext; + +std::unique_ptr<Camera> Game::m_camera; +std::unique_ptr<System> Game::m_system; +SystemView Game::m_systemView(nullptr); + +input::Context Game::m_inputContext; + +double Game::m_delta; +Game::State Game::m_state = State::RUNNING; +Game::WindowContexts Game::contexts; + +void +Game::setup(unsigned w, unsigned h) +{ + KeyMan::loadKeybindsFrom("keybinds.csv"); + + m_inputContext.echo(false); + m_inputContext.canon(false); + m_inputContext.cbreak(false); + + unsigned int viewh = h - 1; + unsigned int infow = 24; + unsigned int infoh = 12; + unsigned int timeh = 10; + + TimeMan::init(); + m_contexts.emplace(WINCTX_GAME, WindowContext()); + WindowContext *gameContext = &m_contexts[WINCTX_GAME]; + + gameContext->registerWindow(WINDOW_SYSTEMVIEW_ID, "System View", infow, 0, w - infow, viewh); + gameContext->registerWindow(WINDOW_BODYINFO_ID, "Body Info", 0, 0, infow, infoh); + gameContext->registerWindow(WINDOW_EVENTS_ID, "Events", 0, infoh, infow, viewh - infoh - timeh); + gameContext->registerWindow(WINDOW_TIMEMAN_ID, "Time", 0, viewh - timeh, infow, timeh); + + gameContext->registerWindow(WINDOW_SYSTEMVIEW_SEARCH_ID, "Search", infow, 0, (w - infow) / 4, viewh, true); + m_currentContext = WINCTX_GAME; + + m_camera = std::make_unique<Camera>((*gameContext)[WINDOW_SYSTEMVIEW_ID].screen()); + m_system = std::make_unique<System>(); + m_systemView.view(m_system.get()); + + KeyMan::registerBind('\x1B', BIND_G_ESCAPE, CTX_GLOBAL, "Escape from focused searchbox / window"); + KeyMan::registerBind('\n', BIND_G_SELECT, CTX_GLOBAL, "Select something"); + KeyMan::registerBind('x', BIND_G_NEXTWIN, CTX_GLOBAL, "Change the focused window to the next in the stack"); + KeyMan::registerBind('X', BIND_G_PREVWIN, CTX_GLOBAL, "Change the focused window to the previous in the stack"); + KeyMan::registerBind('y', BIND_G_QUIT, CTX_GLOBAL, "Terminate the game"); + + KeyMan::registerBind('w', BIND_SYSTEMVIEW_PANUP, CTX_SYSTEMVIEW, "Moves the camera upwards on the system viewer"); + KeyMan::registerBind('a', BIND_SYSTEMVIEW_PANLEFT, CTX_SYSTEMVIEW, "Moves the camera to the left on the system viewer"); + KeyMan::registerBind('s', BIND_SYSTEMVIEW_PANDOWN, CTX_SYSTEMVIEW, "Moves the camera downwards on the system viewer"); + KeyMan::registerBind('d', BIND_SYSTEMVIEW_PANRIGHT, CTX_SYSTEMVIEW, "Moves the camera to the right on the system viewer"); + KeyMan::registerBind('-', BIND_SYSTEMVIEW_INCSCALE, CTX_SYSTEMVIEW, "Decreases zoom from center of screen"); + KeyMan::registerBind('+', BIND_SYSTEMVIEW_DECSCALE, CTX_SYSTEMVIEW, "Increases zoom into center of screen"); + KeyMan::registerBind('/', BIND_SYSTEMVIEW_SEARCH, CTX_SYSTEMVIEW, "Search through bodies in the system"); + + KeyMan::registerBind(input::CTRL_KEY_ARROWUP, BIND_SYSTEMVIEW_SEARCH_PREV, CTX_SYSTEMVIEW, "Move the cursor up in the search view"); + KeyMan::registerBind(input::CTRL_KEY_ARROWDOWN, BIND_SYSTEMVIEW_SEARCH_NEXT, CTX_SYSTEMVIEW, "Move the cursor down in the search view"); + KeyMan::registerBind(input::CTRL_KEY_HOME, BIND_SYSTEMVIEW_SEARCH_TOP, CTX_SYSTEMVIEW, "Move to first entry in search view"); + KeyMan::registerBind(input::CTRL_KEY_END, BIND_SYSTEMVIEW_SEARCH_BOTTOM, CTX_SYSTEMVIEW, "Move to last entry in search view"); + KeyMan::registerBind(input::CTRL_KEY_ARROWRIGHT, BIND_SYSTEMVIEW_SEARCH_COLLAPSE, CTX_SYSTEMVIEW, "Toggle collapsed entry in search view"); +} + +void +Game::cleanup() +{ + KeyMan::writeKeybindsTo("keybinds.csv"); +} + +void +Game::turn() +{ + auto start = std::chrono::steady_clock::now(); + auto end = start + std::chrono::milliseconds(16); + int c = input::getcode(); + WindowContext &context = m_contexts.at(m_currentContext); + + /*Global keybinds*/ + if(!inputMode()) { + if(c == KeyMan::binds[BIND_G_QUIT].code) m_state = State::STOPPED; + context.update(c); + } + + if(m_currentContext == WINCTX_GAME) { /*Game Context*/ + m_systemView.keypress(m_camera.get(), c); + + m_system->update(); + m_systemView.update(m_camera.get()); + TimeMan::update(c); + if(TimeMan::changed()) { + m_camera->markDirty(); + } + + m_systemView.draw(m_camera.get()); + TimeMan::draw(); + m_camera->draw(); + m_systemView.drawOver(m_camera.get()); + context.draw(); + } + + std::this_thread::sleep_until(end); + end = std::chrono::steady_clock::now(); + auto diff = end - start; + m_delta = (double)(std::chrono::duration_cast<std::chrono::milliseconds>(diff).count()) / 1000.0; +} diff --git a/src/input.cpp b/src/input.cpp new file mode 100644 index 0000000..5cbedb2 --- /dev/null +++ b/src/input.cpp @@ -0,0 +1,37 @@ +#include "input.hpp" +namespace input { + +int getcode() { + int r = 0; + char c; + if(read(STDIN_FILENO, &c, 1) != 1) return -1; + if(c == '\x1b') { + char seq[3]; + if(read(STDIN_FILENO, &seq[0], 1) != 1) return '\x1b'; + if(read(STDIN_FILENO, &seq[1], 1) != 1) return '\x1b'; + if(seq[0] == '[') { + if(seq[1] >= 0 && seq[1] <= '9') { + if(read(STDIN_FILENO, &seq[2], 1) != 1) return '\x1b'; + if(seq[2] == '~') { + switch(seq[1]) { + case '1': + case '7': return CTRL_KEY_HOME; + case '4': + case '8': return CTRL_KEY_END; + default: return CTRL_RANGE_START + seq[1] + 20; + } + } + }else{ + switch(seq[1]) { + default: return CTRL_RANGE_START + seq[1]; + } + } + }else if(seq[0] == 'O') { + return CTRL_RANGE_START + seq[1]; + } + return '\x1b'; + }else{ + return c; + } +} +} diff --git a/src/keybind.cpp b/src/keybind.cpp new file mode 100644 index 0000000..8283c4c --- /dev/null +++ b/src/keybind.cpp @@ -0,0 +1,64 @@ +#include "keybind.hpp" +#include "csv.hpp" +#include "input.hpp" + +#include <algorithm> + +std::unordered_map<std::string, KeyMan::Bind> KeyMan::m_keybinds; +std::unordered_map<std::string, std::string> KeyMan::m_keybindContexts; + +KeyMan::Binds KeyMan::binds; + +static std::unordered_map<int, std::string> CODENAMES = +{ + { input::CTRL_KEY_ARROWUP, "Up arrow" }, + { input::CTRL_KEY_ARROWDOWN, "Down arrow" }, + { input::CTRL_KEY_ARROWRIGHT, "Right arrow" }, + { input::CTRL_KEY_ARROWLEFT, "Left arrow" } +}; + +void +KeyMan::registerBind(int def, + const std::string &name, + const std::string &context, + const std::string &desc) +{ + auto find = m_keybinds.find(name); + if(find != m_keybinds.end()) { + find->second.ctx = context; + find->second.desc = desc; + }else{ + Bind bind = { def, name, context, desc}; + m_keybinds[name] = bind; + } + m_keybindContexts[name] = context; +} + +void +KeyMan::loadKeybindsFrom(const std::string &csvPath) +{ + csv::CSVFile<',', int, std::string> keybindData(csvPath); + for(auto &bind : keybindData.get()) { + int code = std::get<0>(bind); + std::string name = std::get<1>(bind); + + m_keybinds[name] = { .code = code, .name = name, .ctx = "", .desc = ""}; + } +} + +void +KeyMan::writeKeybindsTo(const std::string &csvPath) +{ + csv::CSVFile<',', int, std::string> keybindData(csvPath, true); + for(Bind &bind : KeyMan::binds()) { + keybindData.put({bind.code, bind.name}); + } + keybindData.write(); +} + +std::string +KeyMan::translateCode(int code) +{ + if(code < 256) return std::string(1, (char)code); + return CODENAMES[code]; +} diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..9ff09a6 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,26 @@ +#include <iostream> +#include "game.hpp" + +#include <sys/ioctl.h> +#include <fcntl.h> +#include <unistd.h> + +int +main(int argc, char **argv) +{ + (void)argc; + (void)argv; + + struct winsize w; + ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); + fcntl(STDIN_FILENO, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK); + + Game::setup(w.ws_col, w.ws_row); + + while(Game::running()) { + Game::turn(); + } + + Game::cleanup(); + return 0; +} diff --git a/src/system.cpp b/src/system.cpp new file mode 100644 index 0000000..974d0dc --- /dev/null +++ b/src/system.cpp @@ -0,0 +1,517 @@ +#include "system.hpp" +#include "timeman.hpp" +#include "ecs.hpp" +#include "vex.hpp" +#include "units.hpp" +#include "csv.hpp" +#include "keybind.hpp" +#include "game.hpp" +#include <numbers> +#include <string> + +static double G = 6.6743 * std::pow(10, -11); + +ecs::Entity & +System::addOrbital(const std::string &name, + const std::string &orbitingName, + unsigned long a, + double e, + unit::Mass m, + unsigned r, + double M, + double w) +{ + M *= (std::numbers::pi / 180.0); + w *= (std::numbers::pi / 180.0); + + SystemTreeNode *treeNode = getNode(orbitingName); + ecs::Entity &newOrbital = m_entityMan.newEntity() + .addComponent(ecs::PositionComponent{vex::vec2<long>{0, 0}}) + .addComponent(ecs::MassComponent{m}) + .addComponent(ecs::OrbitalComponent{.origin = treeNode->entityId, .a = (long)a, .e = e, .w = w, .M = M, .T = 0, .v = 0}) + .addComponent(ecs::RenderCircleComponent{r}) + .addComponent(ecs::NameComponent{name}); + treeNode->children.push_back({newOrbital.id, {}}); + return newOrbital; +} + +System::System() +{ + auto sol = m_entityMan.newEntity() + .addComponent(ecs::PositionComponent{vex::vec2<long>{0, 0}}) + .addComponent(ecs::MassComponent{unit::solMass}) + .addComponent(ecs::RenderCircleComponent{695700}) + .addComponent(ecs::NameComponent{"Sol"}); + m_systemTree.entityId = sol.id; + + csv::CSVFile<',', std::string, std::string, double, double, double, double, double, double> planetData("data/sol_planets.csv"); + for(auto &planet : planetData.get()) { + std::string name = std::get<0>(planet); + std::string orbiting = std::get<1>(planet); + double sma = std::get<2>(planet) * unit::AU; + double e = std::get<3>(planet); + unit::Mass m = unit::earthMass * std::get<4>(planet); + double r = std::get<5>(planet) * unit::earthRad; + double M = std::get<6>(planet); + double w = std::get<7>(planet); + addOrbital(name, orbiting, sma, e, m, r, M, w); + } + + csv::CSVFile<',', std::string, std::string, double, double, double, double, double, double> satelliteData("data/sol_satellites.csv"); + for(auto &satellite : satelliteData.get()) { + std::string name = std::get<0>(satellite); + std::string orbiting = std::get<1>(satellite); + double sma = std::get<2>(satellite) * unit::AU; + double e = std::get<3>(satellite); + unit::Mass m = unit::earthMass * std::get<4>(satellite); + double r = std::get<5>(satellite) * unit::earthRad; + double M = std::get<6>(satellite); + double w = std::get<7>(satellite); + addOrbital(name, orbiting, sma, e, m, r, M, w); + } + + csv::CSVFile<',', std::string, double, double, double, double, double, std::string> asteroidData("data/sol_asteroids.csv"); + for(auto &asteroid : asteroidData.get()) { + std::string name = std::get<0>(asteroid); + if(name == "Missing") name = std::get<6>(asteroid); + addOrbital(name, + "Sol", + (unsigned long)(std::get<1>(asteroid) * unit::AU), + std::get<2>(asteroid), + unit::Mass(0), + (unsigned)std::get<3>(asteroid), + std::get<4>(asteroid), + std::get<5>(asteroid)); + } +} + +constexpr static double tau = std::numbers::pi * 2; + +void +System::tickOrbitals(unit::Time time) +{ + for(ecs::Entity &e : m_entityMan.getWith<ecs::OrbitalComponent>()) { + auto &oc = e.get<ecs::OrbitalComponent>(); + auto &pc = e.get<ecs::PositionComponent>(); + auto &mc = e.get<ecs::MassComponent>(); + + ecs::Entity &o = m_entityMan[oc.origin]; + auto &opc = o.get<ecs::PositionComponent>(); + auto &om = o.get<ecs::MassComponent>(); + + double e2 = oc.e * oc.e; + double td = (double)time(); + if(oc.T == 0) { + double u = G * (om.mass() + mc.mass()); + double am = (double)oc.a * 1000.0; + oc.T = tau * std::sqrt((am * am * am) / u); + } + double n = tau / oc.T; + double M = oc.M + (n * td); + double E = M; + + int its = 0; + while(true) { + double dE = (E - oc.e * std::sin(E) - M) / (1 - oc.e * std::cos(E)); + E -= dE; + its++; + if(std::abs(dE) < 1e-6) break; + } + + double x = std::cos(E) - oc.e; + double y = std::sin(E) * std::sqrt(1 - e2); + + double v = std::atan2(y, x) + oc.w; + oc.v = v; + + double r = std::sqrt(x*x + y*y) * (double)oc.a; + + vex::vec2<double> polar(r, v); + pc.position = vex::cartesian<long>(polar) + opc.position; + } + +} + +void +System::update() +{ + tickOrbitals(TimeMan::time()); +} + +ecs::Entity & +System::getBody(std::size_t id) { + return m_entityMan[id]; +} + +System::SystemTreeNode * +System::traverseSystemTree(SystemTreeNode &node, const std::string &name) +{ + SystemTreeNode *found = nullptr; + ecs::Entity &entity = getBody(node.entityId); + auto &namecomp = entity.get<ecs::NameComponent>(); + if(namecomp.name == name) found = &node; + + for(SystemTreeNode &child : node.children) { + if(found != nullptr) break; + found = traverseSystemTree(child, name); + } + return found; +} + +System::SystemTreeNode * +System::getNode(const std::string &name) +{ + SystemTreeNode *treeRes = traverseSystemTree(m_systemTree, name); + if(treeRes == nullptr) + treeRes = &m_systemTree; + return treeRes; +} + +void +SystemView::view(System *system) +{ + m_system = system; + m_focus = &system->m_systemTree; +} + +void +SystemView::keypress(Camera *camera, int key) +{ + WindowContext &context = Game::contexts(); + if(context.getFocusedString() == WINDOW_SYSTEMVIEW_SEARCH_ID) { + m_focusSearch->keypress(key); + if(!Game::paused()) { + Search *fp = m_focusSearch.release(); + delete fp; + } + } + if(context.getFocusedString() != WINDOW_SYSTEMVIEW_ID) return; + if(key == KeyMan::binds[BIND_SYSTEMVIEW_PANUP].code) camera->move(0, camera->getscale()); + if(key == KeyMan::binds[BIND_SYSTEMVIEW_PANDOWN].code) camera->move(0, -(long)camera->getscale()); + if(key == KeyMan::binds[BIND_SYSTEMVIEW_PANRIGHT].code) camera->move(camera->getscale(), 0); + if(key == KeyMan::binds[BIND_SYSTEMVIEW_PANLEFT].code) camera->move(-(long)camera->getscale(), 0); + if(key == KeyMan::binds[BIND_SYSTEMVIEW_INCSCALE].code) camera->setscale(camera->getscale() * 2); + if(key == KeyMan::binds[BIND_SYSTEMVIEW_DECSCALE].code) camera->setscale(camera->getscale() / 2); + if(key == KeyMan::binds[BIND_SYSTEMVIEW_SEARCH].code) { + Game::setState(Game::State::PAUSED_INPUT); + context.focus(WINDOW_SYSTEMVIEW_SEARCH_ID); + context.setWindowHidden(WINDOW_SYSTEMVIEW_SEARCH_ID, false); + m_focusSearch = std::make_unique<Search>(this); + } +} + +void +SystemView::update(Camera *camera) +{ + if(Game::paused()) return; + auto &efoc = m_system->m_entityMan[m_focus->entityId]; + auto &efocp = efoc.get<ecs::PositionComponent>(); + if(efocp.position != camera->getorigin()) { + camera->setorigin(efocp.position); + } +} + +void +SystemView::drawOver(Camera *camera) { + auto &efoc = m_system->m_entityMan[m_focus->entityId]; + auto &efocp = efoc.get<ecs::PositionComponent>(); + auto &efocm = efoc.get<ecs::MassComponent>(); + + WindowContext &context = Game::contexts(); + Window &infoWindow = context[WINDOW_BODYINFO_ID]; + Window &viewWindow = context[WINDOW_SYSTEMVIEW_ID]; + + infoWindow << straw::clear(' '); + infoWindow << straw::move(0, 0) << "Focus: " << efoc.get<ecs::NameComponent>().name << '\n'; + if(efoc.contains<ecs::OrbitalComponent>()) { + auto &efoco = efoc.get<ecs::OrbitalComponent>(); + ecs::Entity &efoc_origin = m_system->m_entityMan[efoco.origin]; + + infoWindow << "Orbiting: " << efoc_origin.get<ecs::NameComponent>().name << '\n'; + infoWindow << "Distance: " << std::abs((double)(efocp.position - efoc_origin.get<ecs::PositionComponent>().position).magnitude()) << "km\n"; + infoWindow << "Period: " << efoco.T / unit::DAY_SECONDS << " days\n"; + infoWindow << "Angle: " << efoco.v * (180.0 / std::numbers::pi) << '\n'; + infoWindow << "Eccentricity: " << efoco.e << '\n'; + infoWindow << "Mass: " << efocm.mass() << '\n'; + } + vex::vec2<unsigned> viewdims( + viewWindow.screen()->getwidth(), + viewWindow.screen()->getheight()); + + viewWindow << straw::move(0, 0) << + straw::setcolor(straw::WHITE, straw::BLACK) << + "Press '" << + KeyMan::translateCode(KeyMan::binds[BIND_SYSTEMVIEW_SEARCH].code) << + "' to change focus"; + + double scale = camera->getscale() * (viewdims[0] / 2.0); + if(scale > 1e7) { + viewWindow << straw::move(0, viewdims[1] - 1) << scale / unit::AU << " AU"; + }else{ + viewWindow << straw::move(0, viewdims[1] - 1) << scale << " km"; + } + +} + +void +SystemView::draw(Camera *camera) +{ + if(m_focusSearch != nullptr) m_focusSearch->draw(); + if(!camera->dirty()) return; + auto &efoc = m_system->m_entityMan[m_focus->entityId]; + auto &efocp = efoc.get<ecs::PositionComponent>(); + auto &efocm = efoc.get<ecs::MassComponent>(); + + if(efoc.contains<ecs::OrbitalComponent>()) { + auto &oc = efoc.get<ecs::OrbitalComponent>(); + auto &om = efoc.get<ecs::MassComponent>(); + ecs::Entity &origin = m_system->m_entityMan[oc.origin]; + auto pc = origin.get<ecs::PositionComponent>(); + + std::vector<vex::vec2<long>> points; + float i = 0.0; + while(i < tau){ + double e2 = oc.e * oc.e; + double M = oc.M + i; + double E = M; + + int its = 0; + while(its < 512) { + double dE = (E - oc.e * std::sin(E) - M) / (1 - oc.e * std::cos(E)); + E -= dE; + its++; + if(std::abs(dE) < 1e-6) break; + } + + double x = (std::cos(E) - oc.e); + double y = (std::sin(E) * std::sqrt(1 - e2)); + + double v = std::atan2(y, x) + oc.w; + double r = std::sqrt(x*x + y*y) * (double)oc.a; + + + vex::vec2<double> polar{r, v}; + vex::vec2<long> cart = vex::cartesian<long>(polar) + pc.position; + + points.push_back(cart); + i += 0.01; + } + for(unsigned i = 0; i < points.size(); i++) { + if(i == 0) { + camera->batchShape(shapes::line<long>(points[points.size() - 1], points[i]), straw::color(0, 0, 255), '#'); + }else{ + camera->batchShape(shapes::line<long>(points[i-1], points[i]), straw::color(0, 0, 255), '#'); + } + } + } + + for(ecs::Entity &e : m_system->m_entityMan.getWith<ecs::RenderCircleComponent>()) { + auto &pc = e.get<ecs::PositionComponent>(); + auto &cc = e.get<ecs::RenderCircleComponent>(); + unsigned id = e.id; + + long cr = cc.radius; + if(cr < camera->getscale()) cr = camera->getscale(); + shapes::ellipse<long> circle(pc.position, cr, cr); + + straw::color color = id == m_focus->entityId ? straw::color{255, 255, 0} : straw::WHITE; + if(cc.radius < cr) { + camera->batchShape(circle, color, '*'); + }else{ + camera->batchShape(circle, color, '#'); + } + } +} + +ecs::Entity & +SystemView::getBody(int id) const +{ + return m_system->m_entityMan[id]; +} + +int +SystemView::getBodyIdByName(const std::string &name) +{ + for(ecs::Entity &entity : m_system->m_entityMan.all()) { + int id = entity.id; + if(entity.contains<ecs::NameComponent>()) { + auto &namecomp = entity.get<ecs::NameComponent>(); + if(namecomp.name == name) return id; + } + } + return -1; +} + +void +SystemView::Search::addNodeToTree(SystemTreeDisplayNode &root, System::SystemTreeNode *node) +{ + m_displayTreeFlat.emplace_back(&root); + for(auto &child : node->children) + { + ecs::NameComponent &namecomp = m_systemView->m_system->m_entityMan[child.entityId].get<ecs::NameComponent>(); + root.children.push_back( + {&child, + {}, + &root, + (unsigned)m_displayTreeFlat.size(), + m_query.empty(), + m_query.empty() ? false : namecomp.name.find(m_query) == std::string::npos}); + addNodeToTree(root.children.back(), &child); + } +} + +void +SystemView::Search::rebuild() +{ + System::SystemTreeNode *systemRoot = &m_systemView->m_system->m_systemTree; + m_displayTree = {systemRoot, {}, nullptr, 0, false, false}; + m_displayTreeFlat.clear(); + m_selectionIndex = 0; + + addNodeToTree(m_displayTree, systemRoot); + for(unsigned i = 0; auto *node : m_displayTreeFlat) { + if(m_systemView->m_focus == node->node) { + m_selectionIndex = i; + break; + } + i++; + } + SystemTreeDisplayNode *recurse = m_displayTreeFlat[m_selectionIndex]; + while(recurse->parent != nullptr) { + recurse->parent->collapsed = false; + recurse->parent->hidden = false; + recurse = recurse->parent; + } +} + +void +SystemView::Search::drawNode( + SystemTreeDisplayNode &root, + Window &searchWindow, + unsigned indent) +{ + unsigned windowH = searchWindow.screen()->getheight(); + unsigned cursorY = searchWindow.screen()->getcursory(); + if(cursorY == windowH && root.index > m_selectionIndex) return; + + ecs::NameComponent &namecomp = m_systemView->m_system->m_entityMan[root.node->entityId].get<ecs::NameComponent>(); + + if(root.index == m_selectionIndex) { + searchWindow << straw::setcolor(straw::BLACK, straw::WHITE); + }else searchWindow << straw::setcolor(straw::WHITE, straw::BLACK); + + + if(!root.hidden) { + if(m_query.empty()) searchWindow << std::string((indent * 4), ' '); + if(root.children.size() > 0) + searchWindow << '[' << (root.collapsed ? '+' : '-') << "] "; + searchWindow << namecomp.name << straw::setcolor(straw::WHITE, straw::BLACK) << '\n'; + } + + if(!root.collapsed) { + for(auto &child : root.children) drawNode(child, searchWindow, indent + 1); + } +} + +SystemView::Search::Search(SystemView *systemView) : + m_systemView(systemView), m_selectionIndex(0), m_dirty(true) +{ + rebuild(); +} + +void +SystemView::Search::finish() +{ + WindowContext &context = Game::contexts(); + Game::setState(Game::State::RUNNING); + context.setWindowHidden(WINDOW_SYSTEMVIEW_SEARCH_ID, true); + context.focus(WINDOW_SYSTEMVIEW_ID); +} + +void +SystemView::Search::keypress(int key) +{ + if(key == KeyMan::binds[BIND_G_ESCAPE].code) { + finish(); + }else + if(key == KeyMan::binds[BIND_SYSTEMVIEW_SEARCH_NEXT].code) { + if(m_selectionIndex == m_displayTreeFlat.size() - 1) return; + for(m_selectionIndex++; m_selectionIndex < m_displayTreeFlat.size() - 1; ++m_selectionIndex) { + if(!m_displayTreeFlat[m_selectionIndex]->hidden) break; + } + if(m_displayTreeFlat[m_selectionIndex]->hidden) m_selectionIndex = 0; + SystemTreeDisplayNode *node = m_displayTreeFlat[m_selectionIndex]; + while(node->parent != nullptr) { + if(!node->parent->collapsed) break; + m_selectionIndex += node->parent->children.size(); + node = node->parent; + } + + m_dirty = true; + }else + if(key == KeyMan::binds[BIND_SYSTEMVIEW_SEARCH_PREV].code) { + if(m_selectionIndex == 0) return; + for(m_selectionIndex--; m_selectionIndex > 0; --m_selectionIndex) { + if(!m_displayTreeFlat[m_selectionIndex]->hidden) break; + } + SystemTreeDisplayNode *node = m_displayTreeFlat[m_selectionIndex]; + while(node->parent != nullptr) { + if(!node->parent->collapsed) break; + m_selectionIndex -= node->parent->children.size(); + node = node->parent; + } + + m_dirty = true; + }else + if(key == KeyMan::binds[BIND_SYSTEMVIEW_SEARCH_TOP].code) { + m_selectionIndex = 0; + for(; m_selectionIndex < m_displayTreeFlat.size(); ++m_selectionIndex) { + if(!m_displayTreeFlat[m_selectionIndex]->hidden) break; + } + m_dirty = true; + }else + if(key == KeyMan::binds[BIND_SYSTEMVIEW_SEARCH_BOTTOM].code) { + m_selectionIndex = m_displayTreeFlat.size() - 1; + for(; m_selectionIndex > 0; --m_selectionIndex) { + if(!m_displayTreeFlat[m_selectionIndex]->hidden) break; + } + m_dirty = true; + }else + if(key == KeyMan::binds[BIND_SYSTEMVIEW_SEARCH_COLLAPSE].code) { + m_displayTreeFlat[m_selectionIndex]->collapsed = !m_displayTreeFlat[m_selectionIndex]->collapsed; + m_dirty = true; + }else + if(key == KeyMan::binds[BIND_G_SELECT].code) { + m_systemView->m_focus = m_displayTreeFlat[m_selectionIndex]->node; + finish(); + }else + { + if(key < 0) return; + switch(key) { + case 127: + case '\b': { + if(!m_query.empty()) m_query.pop_back(); + } break; + default: m_query.push_back((char)key); break; + } + rebuild(); + m_dirty = true; + } +} + +void +SystemView::Search::draw() +{ + if(!m_dirty) return; + + WindowContext &windowContext = Game::contexts(); + Window &searchWindow = windowContext[WINDOW_SYSTEMVIEW_SEARCH_ID]; + + searchWindow << straw::clear(' ') << straw::move(0, 0); + searchWindow << "Query: " << m_query << '\n'; + + drawNode(m_displayTree, searchWindow, 0); + + searchWindow << straw::flush(); + m_dirty = false; +} diff --git a/src/timeman.cpp b/src/timeman.cpp new file mode 100644 index 0000000..f043894 --- /dev/null +++ b/src/timeman.cpp @@ -0,0 +1,49 @@ +#include "timeman.hpp" +#include "keybind.hpp" +#include "window.hpp" +#include "game.hpp" + +unit::Time TimeMan::m_time(0); +unit::Time TimeMan::m_step(unit::DAY_SECONDS); +bool TimeMan::m_auto; +bool TimeMan::m_changed; + +void +TimeMan::init() +{ + KeyMan::registerBind('.', BIND_TIMEMAN_STEP, CTX_TIMEMAN, "Move time ahead by a step"); + KeyMan::registerBind('+', BIND_TIMEMAN_INCSTEP, CTX_TIMEMAN, "Increase the timestep"); + KeyMan::registerBind('-', BIND_TIMEMAN_DECSTEP, CTX_TIMEMAN, "Decrease the timestep"); + KeyMan::registerBind('a', BIND_TIMEMAN_TOGGLEAUTO, CTX_TIMEMAN, "Toggle if time will move automatically"); + m_changed = true; +} + +void +TimeMan::update(int c) +{ + WindowContext &context = Game::contexts(); + m_changed = false; + if(!Game::paused()) { + if(m_auto) { + m_time += (m_step); + m_changed = true; + } + } + if(context.getFocusedString() != WINDOW_TIMEMAN_ID) return; + if(c == KeyMan::binds[BIND_TIMEMAN_INCSTEP].code) m_step = unit::Time(std::max<long>(1, m_step() * 2)); + if(c == KeyMan::binds[BIND_TIMEMAN_DECSTEP].code) m_step = unit::Time(std::max<long>(1, m_step() / 2)); + if(c == KeyMan::binds[BIND_TIMEMAN_TOGGLEAUTO].code) m_auto = !m_auto; + if(c == KeyMan::binds[BIND_TIMEMAN_STEP].code && !Game::paused()) { m_time += m_step; m_changed = true; } +} + +void +TimeMan::draw() +{ + WindowContext &context = Game::contexts(); + Window &timeWindow = context[WINDOW_TIMEMAN_ID]; + timeWindow << straw::clear(' '); + + timeWindow << straw::move(0, 0) << straw::resetcolor() << m_time.format("%S %D, %C \n%H:%m\n\n"); + timeWindow << m_step.format("Step:\n%Y Years, %M Months\n%D Days, %H Hours\n%m Minutes, %s Seconds\n\n"); + if(m_auto) timeWindow << "Auto"; +} diff --git a/src/units.cpp b/src/units.cpp new file mode 100644 index 0000000..7cc7d61 --- /dev/null +++ b/src/units.cpp @@ -0,0 +1,61 @@ +#include "units.hpp" +#include <sstream> +#include <cstring> +#include <iostream> + +namespace unit { + +std::string +Time::format(const char *fmt) +{ + std::stringstream ss; + for(; *fmt; fmt++) { + if(*fmt != '%') { + ss << *fmt; + continue; + } + fmt++; + switch(*fmt) { + case '%': + ss << '%'; + break; + case 'Y': + ss << real_years(); + break; + case 'C': + ss << years(); + break; + case 'S': { + Time year = current_year(); + ss << month_str[year.months()]; + break; } + case 'M': { + Time year = current_year(); + ss << year.months(); + break; } + case 'W': { + Time month = current_month(); + ss << month.weeks(); + break; } + case 'D': { + Time month = current_month(); + ss << month.days(); + break; } + case 'H': { + Time day = current_day(); + ss << day.hours(); + break; } + case 'm': { + Time hour = current_hour(); + ss << hour.minutes(); + break; } + case 's': { + Time minute = current_minute(); + ss << minute.seconds(); + break; } + } + } + return ss.str(); +} + +} diff --git a/src/window.cpp b/src/window.cpp new file mode 100644 index 0000000..4e487f3 --- /dev/null +++ b/src/window.cpp @@ -0,0 +1,72 @@ +#include "window.hpp" +#include "keybind.hpp" + +void +Window::draw(bool focus) +{ + if(m_hidden) return; + if(focus) { + m_border << straw::setcolor(straw::BLACK, straw::WHITE) << straw::clear(' ') << straw::move(0, 0) << m_title << straw::resetcolor(); + }else{ + m_border << straw::setcolor(straw::WHITE, straw::BLACK) << straw::clear(' ') << straw::move(0, 0) << m_title; + } + m_border.flush(); + m_screen.flush(); +} + +void +WindowContext::registerWindow(const std::string &id, + const std::string &title, + unsigned x, unsigned y, + unsigned w, unsigned h, + bool hidden) +{ + m_windows.emplace(id, Window(title, x, y, w, h, hidden)); + m_windowOrder.push_back(id); +} + +void +WindowContext::update(int code) +{ + if(code == KeyMan::binds[BIND_G_NEXTWIN].code) { + m_focus = (m_focus + 1) % m_windows.size(); + while(m_windows.at(m_windowOrder[m_focus]).hidden()) { + m_focus = (m_focus + 1) % m_windows.size(); + } + } + if(code == KeyMan::binds[BIND_G_PREVWIN].code) { + m_focus = (m_focus == 0 ? m_windows.size() - 1 : m_focus - 1); + while(m_windows.at(m_windowOrder[m_focus]).hidden()) { + m_focus = (m_focus == 0 ? m_windows.size() - 1 : m_focus - 1); + } + } +} + +void +WindowContext::draw() +{ + for(unsigned i = 0; i < m_windows.size(); i++) { + m_windows.at(m_windowOrder[i]).draw(i == m_focus); + } +} + +void +WindowContext::focus(const std::string &id) +{ + for(unsigned i = 0; i < m_windowOrder.size(); i++) { + if(m_windowOrder[i] == id) { + m_focus = i; + return; + } + } +} + +void +WindowContext::setWindowHidden(const std::string &id, bool mode) +{ + m_windows.at(id).setHidden(mode); + for(unsigned i = 0; i < m_windows.size(); i++) { + if(m_windowOrder[i] == id && mode) continue; + m_windows.at(m_windowOrder[i]) << straw::redraw(); + } +} |