kerykeion 4.18.5__py3-none-any.whl → 4.20.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of kerykeion might be problematic. Click here for more details.
- kerykeion/aspects/natal_aspects.py +15 -5
- kerykeion/aspects/synastry_aspects.py +4 -7
- kerykeion/astrological_subject.py +39 -18
- kerykeion/charts/charts_utils.py +23 -21
- kerykeion/charts/kerykeion_chart_svg.py +57 -28
- kerykeion/charts/templates/aspect_grid_only.xml +20 -2
- kerykeion/charts/templates/chart.xml +77 -50
- kerykeion/charts/templates/wheel_only.xml +21 -3
- kerykeion/charts/themes/dark-high-contrast.css +1 -1
- kerykeion/charts/themes/dark.css +1 -1
- kerykeion/charts/themes/light.css +1 -1
- kerykeion/enums.py +2 -0
- kerykeion/kr_types/kr_literals.py +1 -1
- kerykeion/kr_types/kr_models.py +4 -2
- kerykeion/kr_types/settings_models.py +3 -1
- kerykeion/settings/kerykeion_settings.py +4 -4
- kerykeion/settings/kr.config.json +65 -27
- kerykeion/utilities.py +12 -7
- {kerykeion-4.18.5.dist-info → kerykeion-4.20.0.dist-info}/METADATA +64 -18
- kerykeion-4.20.0.dist-info/RECORD +42 -0
- {kerykeion-4.18.5.dist-info → kerykeion-4.20.0.dist-info}/WHEEL +1 -1
- kerykeion-4.18.5.dist-info/RECORD +0 -42
- {kerykeion-4.18.5.dist-info → kerykeion-4.20.0.dist-info}/LICENSE +0 -0
- {kerykeion-4.18.5.dist-info → kerykeion-4.20.0.dist-info}/entry_points.txt +0 -0
|
@@ -54,8 +54,18 @@ class NatalAspects:
|
|
|
54
54
|
for first in range(len(active_points_list)):
|
|
55
55
|
# Generates the aspects list without repetitions
|
|
56
56
|
for second in range(first + 1, len(active_points_list)):
|
|
57
|
+
# South Node and North Node are always in opposition
|
|
58
|
+
nodes_pairs = {
|
|
59
|
+
("True_Node", "True_South_Node"),
|
|
60
|
+
("Mean_Node", "Mean_South_Node"),
|
|
61
|
+
("True_South_Node", "True_Node"),
|
|
62
|
+
("Mean_South_Node", "Mean_Node"),
|
|
63
|
+
}
|
|
64
|
+
if (active_points_list[first]["name"], active_points_list[second]["name"]) in nodes_pairs:
|
|
65
|
+
continue
|
|
66
|
+
|
|
57
67
|
aspect = get_aspect_from_two_points(
|
|
58
|
-
self.aspects_settings, active_points_list[first]["abs_pos"],
|
|
68
|
+
self.aspects_settings, active_points_list[first]["abs_pos"],
|
|
59
69
|
active_points_list[second]["abs_pos"]
|
|
60
70
|
)
|
|
61
71
|
|
|
@@ -132,12 +142,12 @@ if __name__ == "__main__":
|
|
|
132
142
|
|
|
133
143
|
johnny = AstrologicalSubject("Johnny Depp", 1963, 6, 9, 0, 0, "Owensboro", "US")
|
|
134
144
|
|
|
135
|
-
# All aspects
|
|
145
|
+
# All aspects as a list of dictionaries
|
|
136
146
|
aspects = NatalAspects(johnny)
|
|
137
|
-
print(aspects.all_aspects)
|
|
147
|
+
print([a.model_dump() for a in aspects.all_aspects])
|
|
138
148
|
|
|
139
149
|
print("\n")
|
|
140
150
|
|
|
141
|
-
# Relevant aspects
|
|
151
|
+
# Relevant aspects as a list of dictionaries
|
|
142
152
|
aspects = NatalAspects(johnny)
|
|
143
|
-
print(aspects.relevant_aspects)
|
|
153
|
+
print([a.model_dump() for a in aspects.relevant_aspects])
|
|
@@ -101,13 +101,10 @@ if __name__ == "__main__":
|
|
|
101
101
|
|
|
102
102
|
setup_logging(level="debug")
|
|
103
103
|
|
|
104
|
-
john = AstrologicalSubject("John", 1940, 10, 9,
|
|
105
|
-
yoko = AstrologicalSubject("Yoko", 1933, 2, 18,
|
|
104
|
+
john = AstrologicalSubject("John", 1940, 10, 9, 10, 30, "Liverpool", "GB")
|
|
105
|
+
yoko = AstrologicalSubject("Yoko", 1933, 2, 18, 10, 30, "Tokyo", "JP")
|
|
106
106
|
|
|
107
107
|
synastry_aspects = SynastryAspects(john, yoko)
|
|
108
108
|
|
|
109
|
-
# All aspects
|
|
110
|
-
print(synastry_aspects.all_aspects)
|
|
111
|
-
|
|
112
|
-
# Relevant aspects
|
|
113
|
-
print(synastry_aspects.relevant_aspects)
|
|
109
|
+
# All aspects as a list of dictionaries
|
|
110
|
+
print([aspect.dict() for aspect in synastry_aspects.all_aspects])
|
|
@@ -25,8 +25,8 @@ from kerykeion.kr_types import (
|
|
|
25
25
|
Houses
|
|
26
26
|
)
|
|
27
27
|
from kerykeion.utilities import (
|
|
28
|
-
get_number_from_name,
|
|
29
|
-
get_kerykeion_point_from_degree,
|
|
28
|
+
get_number_from_name,
|
|
29
|
+
get_kerykeion_point_from_degree,
|
|
30
30
|
get_planet_house,
|
|
31
31
|
get_moon_emoji_from_phase_int,
|
|
32
32
|
get_moon_phase_name_from_phase_int,
|
|
@@ -79,7 +79,7 @@ class AstrologicalSubject:
|
|
|
79
79
|
- online (bool, optional): Sets if you want to use the online mode, which fetches the timezone and coordinates from geonames.
|
|
80
80
|
If you already have the coordinates and timezone, set this to False. Defaults to True.
|
|
81
81
|
- disable_chiron: Deprecated, use disable_chiron_and_lilith instead.
|
|
82
|
-
- sidereal_mode (SiderealMode, optional): Also known as Ayanamsa.
|
|
82
|
+
- sidereal_mode (SiderealMode, optional): Also known as Ayanamsa.
|
|
83
83
|
The mode to use for the sidereal zodiac, according to the Swiss Ephemeris.
|
|
84
84
|
Defaults to "FAGAN_BRADLEY".
|
|
85
85
|
Available modes are visible in the SiderealMode Literal.
|
|
@@ -139,6 +139,8 @@ class AstrologicalSubject:
|
|
|
139
139
|
mean_node: KerykeionPointModel
|
|
140
140
|
chiron: Union[KerykeionPointModel, None]
|
|
141
141
|
mean_lilith: Union[KerykeionPointModel, None]
|
|
142
|
+
true_south_node: KerykeionPointModel
|
|
143
|
+
mean_south_node: KerykeionPointModel
|
|
142
144
|
|
|
143
145
|
# Houses
|
|
144
146
|
first_house: KerykeionPointModel
|
|
@@ -197,10 +199,10 @@ class AstrologicalSubject:
|
|
|
197
199
|
"Please use 'disable_chiron' instead.",
|
|
198
200
|
DeprecationWarning
|
|
199
201
|
)
|
|
200
|
-
|
|
202
|
+
|
|
201
203
|
if disable_chiron_and_lilith:
|
|
202
204
|
raise ValueError("Cannot specify both 'disable_chiron' and 'disable_chiron_and_lilith'. Use 'disable_chiron_and_lilith' only.")
|
|
203
|
-
|
|
205
|
+
|
|
204
206
|
self.disable_chiron_and_lilith = disable_chiron
|
|
205
207
|
# <--- Deprecation warnings
|
|
206
208
|
|
|
@@ -225,7 +227,7 @@ class AstrologicalSubject:
|
|
|
225
227
|
#---------------#
|
|
226
228
|
|
|
227
229
|
# Geonames username
|
|
228
|
-
if geonames_username is None and online:
|
|
230
|
+
if geonames_username is None and online and (not lat or not lng or not tz_str):
|
|
229
231
|
logging.warning(GEONAMES_DEFAULT_USERNAME_WARNING)
|
|
230
232
|
self.geonames_username = DEFAULT_GEONAMES_USERNAME
|
|
231
233
|
else:
|
|
@@ -251,7 +253,7 @@ class AstrologicalSubject:
|
|
|
251
253
|
logging.info("No latitude specified, using London as default")
|
|
252
254
|
else:
|
|
253
255
|
self.lat = lat # type: ignore
|
|
254
|
-
|
|
256
|
+
|
|
255
257
|
# Longitude
|
|
256
258
|
if not lng and not self.online:
|
|
257
259
|
self.lng = 0
|
|
@@ -278,7 +280,7 @@ class AstrologicalSubject:
|
|
|
278
280
|
# Chart Perspective check and setup --->
|
|
279
281
|
if self.perspective_type not in get_args(PerspectiveType):
|
|
280
282
|
raise KerykeionException(f"\n* ERROR: '{self.perspective_type}' is NOT a valid chart perspective! Available perspectives are: *" + "\n" + str(get_args(PerspectiveType)))
|
|
281
|
-
|
|
283
|
+
|
|
282
284
|
if self.perspective_type == "True Geocentric":
|
|
283
285
|
self._iflag += swe.FLG_TRUEPOS
|
|
284
286
|
elif self.perspective_type == "Heliocentric":
|
|
@@ -304,14 +306,14 @@ class AstrologicalSubject:
|
|
|
304
306
|
|
|
305
307
|
if self.sidereal_mode and self.zodiac_type == "Tropic":
|
|
306
308
|
raise KerykeionException("You can't set a sidereal mode with a Tropic zodiac type!")
|
|
307
|
-
|
|
309
|
+
|
|
308
310
|
if self.zodiac_type == "Sidereal" and not self.sidereal_mode:
|
|
309
311
|
self.sidereal_mode = DEFAULT_SIDEREAL_MODE
|
|
310
312
|
logging.info("No sidereal mode set, using default FAGAN_BRADLEY")
|
|
311
313
|
|
|
312
314
|
if self.zodiac_type == "Sidereal":
|
|
313
315
|
# Check if the sidereal mode is valid
|
|
314
|
-
|
|
316
|
+
|
|
315
317
|
if not self.sidereal_mode or not self.sidereal_mode in get_args(SiderealMode):
|
|
316
318
|
raise KerykeionException(f"\n* ERROR: '{self.sidereal_mode}' is NOT a valid sidereal mode! Available modes are: *" + "\n" + str(get_args(SiderealMode)))
|
|
317
319
|
|
|
@@ -328,7 +330,7 @@ class AstrologicalSubject:
|
|
|
328
330
|
# UTC, julian day and local time setup --->
|
|
329
331
|
if (self.online) and (not self.tz_str) and (not self.lat) and (not self.lng):
|
|
330
332
|
self._fetch_and_set_tz_and_coordinates_from_geonames()
|
|
331
|
-
|
|
333
|
+
|
|
332
334
|
self.lat = check_and_adjust_polar_latitude(self.lat)
|
|
333
335
|
|
|
334
336
|
# Local time to UTC
|
|
@@ -496,6 +498,10 @@ class AstrologicalSubject:
|
|
|
496
498
|
pluto_deg = swe.calc(self.julian_day, 9, self._iflag)[0][0]
|
|
497
499
|
mean_node_deg = swe.calc(self.julian_day, 10, self._iflag)[0][0]
|
|
498
500
|
true_node_deg = swe.calc(self.julian_day, 11, self._iflag)[0][0]
|
|
501
|
+
# For south nodes there exist no Swiss Ephemeris library calculation function,
|
|
502
|
+
# but they are simply opposite the north node.
|
|
503
|
+
mean_south_node_deg = (mean_node_deg + 180) % 360
|
|
504
|
+
true_south_node_deg = (true_node_deg + 180) % 360
|
|
499
505
|
|
|
500
506
|
self.sun = get_kerykeion_point_from_degree(sun_deg, "Sun", point_type=point_type)
|
|
501
507
|
self.moon = get_kerykeion_point_from_degree(moon_deg, "Moon", point_type=point_type)
|
|
@@ -509,6 +515,8 @@ class AstrologicalSubject:
|
|
|
509
515
|
self.pluto = get_kerykeion_point_from_degree(pluto_deg, "Pluto", point_type=point_type)
|
|
510
516
|
self.mean_node = get_kerykeion_point_from_degree(mean_node_deg, "Mean_Node", point_type=point_type)
|
|
511
517
|
self.true_node = get_kerykeion_point_from_degree(true_node_deg, "True_Node", point_type=point_type)
|
|
518
|
+
self.mean_south_node = get_kerykeion_point_from_degree(mean_south_node_deg, "Mean_South_Node", point_type=point_type)
|
|
519
|
+
self.true_south_node = get_kerykeion_point_from_degree(true_south_node_deg, "True_South_Node", point_type=point_type)
|
|
512
520
|
|
|
513
521
|
self.sun.house = get_planet_house(sun_deg, self._houses_degree_ut)
|
|
514
522
|
self.moon.house = get_planet_house(moon_deg, self._houses_degree_ut)
|
|
@@ -522,6 +530,9 @@ class AstrologicalSubject:
|
|
|
522
530
|
self.pluto.house = get_planet_house(pluto_deg, self._houses_degree_ut)
|
|
523
531
|
self.mean_node.house = get_planet_house(mean_node_deg, self._houses_degree_ut)
|
|
524
532
|
self.true_node.house = get_planet_house(true_node_deg, self._houses_degree_ut)
|
|
533
|
+
self.mean_south_node.house = get_planet_house(mean_south_node_deg, self._houses_degree_ut)
|
|
534
|
+
self.true_south_node.house = get_planet_house(true_south_node_deg, self._houses_degree_ut)
|
|
535
|
+
|
|
525
536
|
|
|
526
537
|
# Deprecated
|
|
527
538
|
planets_list = [
|
|
@@ -537,6 +548,8 @@ class AstrologicalSubject:
|
|
|
537
548
|
self.pluto,
|
|
538
549
|
self.mean_node,
|
|
539
550
|
self.true_node,
|
|
551
|
+
self.mean_south_node,
|
|
552
|
+
self.true_south_node,
|
|
540
553
|
]
|
|
541
554
|
|
|
542
555
|
if not self.disable_chiron_and_lilith:
|
|
@@ -563,6 +576,14 @@ class AstrologicalSubject:
|
|
|
563
576
|
# Check in retrograde or not:
|
|
564
577
|
for planet in planets_list:
|
|
565
578
|
planet_number = get_number_from_name(planet["name"])
|
|
579
|
+
|
|
580
|
+
# Swiss ephemeris library does not offer calculation of direction of south nodes.
|
|
581
|
+
# But south nodes have same direction as north nodes. We can use those to calculate direction.
|
|
582
|
+
if planet_number == 1000: # Number of Mean South Node
|
|
583
|
+
planet_number = 10 # Number of Mean North Node
|
|
584
|
+
elif planet_number == 1100: # Number of True South Node
|
|
585
|
+
planet_number = 11 # Number of True North Node
|
|
586
|
+
|
|
566
587
|
if swe.calc(self.julian_day, planet_number, self._iflag)[0][3] < 0:
|
|
567
588
|
planet["retrograde"] = True
|
|
568
589
|
else:
|
|
@@ -651,7 +672,7 @@ class AstrologicalSubject:
|
|
|
651
672
|
Returns the UTC time as a float.
|
|
652
673
|
"""
|
|
653
674
|
dt = datetime.fromisoformat(self.iso_formatted_utc_datetime)
|
|
654
|
-
|
|
675
|
+
|
|
655
676
|
# Extract the hours, minutes, and seconds
|
|
656
677
|
hours = dt.hour
|
|
657
678
|
minutes = dt.minute
|
|
@@ -669,7 +690,7 @@ class AstrologicalSubject:
|
|
|
669
690
|
Returns the local time as a float.
|
|
670
691
|
"""
|
|
671
692
|
dt = datetime.fromisoformat(self.iso_formatted_local_datetime)
|
|
672
|
-
|
|
693
|
+
|
|
673
694
|
# Extract the hours, minutes, and seconds
|
|
674
695
|
hours = dt.hour
|
|
675
696
|
minutes = dt.minute
|
|
@@ -684,8 +705,8 @@ class AstrologicalSubject:
|
|
|
684
705
|
@staticmethod
|
|
685
706
|
def get_from_iso_utc_time(
|
|
686
707
|
name: str,
|
|
687
|
-
iso_utc_time: str,
|
|
688
|
-
city: str = "Greenwich",
|
|
708
|
+
iso_utc_time: str,
|
|
709
|
+
city: str = "Greenwich",
|
|
689
710
|
nation: str = "GB",
|
|
690
711
|
tz_str: str = "Etc/GMT",
|
|
691
712
|
online: bool = False,
|
|
@@ -697,7 +718,7 @@ class AstrologicalSubject:
|
|
|
697
718
|
sidereal_mode: Union[SiderealMode, None] = None,
|
|
698
719
|
houses_system_identifier: HousesSystemIdentifier = DEFAULT_HOUSES_SYSTEM_IDENTIFIER,
|
|
699
720
|
perspective_type: PerspectiveType = DEFAULT_PERSPECTIVE_TYPE
|
|
700
|
-
|
|
721
|
+
|
|
701
722
|
) -> "AstrologicalSubject":
|
|
702
723
|
"""
|
|
703
724
|
Creates an AstrologicalSubject object from an iso formatted UTC time.
|
|
@@ -775,7 +796,7 @@ if __name__ == "__main__":
|
|
|
775
796
|
from kerykeion.utilities import setup_logging
|
|
776
797
|
|
|
777
798
|
setup_logging(level="debug")
|
|
778
|
-
|
|
799
|
+
|
|
779
800
|
# With Chiron enabled
|
|
780
801
|
johnny = AstrologicalSubject("Johnny Depp", 1963, 6, 9, 0, 0, "Owensboro", "US")
|
|
781
802
|
print(json.loads(johnny.json(dump=True)))
|
|
@@ -814,5 +835,5 @@ if __name__ == "__main__":
|
|
|
814
835
|
print(johnny.mean_lilith)
|
|
815
836
|
|
|
816
837
|
# Offline mode
|
|
817
|
-
johnny = AstrologicalSubject("Johnny Depp", 1963, 6, 9, 0, 0, "Owensboro", "US", online=False, tz_str="America/New_York", lng=-87.1111, lat=37.7711)
|
|
838
|
+
johnny = AstrologicalSubject("Johnny Depp", 1963, 6, 9, 0, 0, "Owensboro", "US", online=False, tz_str="America/New_York", lng=-87.1111, lat=37.7711, sidereal_mode="FAGAN_BRADLEY", zodiac_type="Sidereal")
|
|
818
839
|
print(johnny.json(dump=True, indent=2))
|
kerykeion/charts/charts_utils.py
CHANGED
|
@@ -34,7 +34,8 @@ def get_decoded_kerykeion_celestial_point_name(input_planet_name: str, celestial
|
|
|
34
34
|
return celestial_point_language[input_planet_name]
|
|
35
35
|
|
|
36
36
|
# Return the special house name if it exists, otherwise return an empty string
|
|
37
|
-
|
|
37
|
+
decoded_special_name = special_house_names.get(input_planet_name, "")
|
|
38
|
+
return celestial_point_language[decoded_special_name]
|
|
38
39
|
|
|
39
40
|
|
|
40
41
|
def decHourJoin(inH: int, inM: int, inS: int) -> float:
|
|
@@ -515,8 +516,8 @@ def draw_third_circle(
|
|
|
515
516
|
|
|
516
517
|
|
|
517
518
|
def draw_aspect_grid(
|
|
518
|
-
stroke_color: str,
|
|
519
|
-
available_planets: list,
|
|
519
|
+
stroke_color: str,
|
|
520
|
+
available_planets: list,
|
|
520
521
|
aspects: list,
|
|
521
522
|
x_start: int = 380,
|
|
522
523
|
y_start: int = 468,
|
|
@@ -705,7 +706,7 @@ def draw_transit_aspect_list(
|
|
|
705
706
|
Returns:
|
|
706
707
|
- A string containing the SVG path data for the aspect transit grid.
|
|
707
708
|
"""
|
|
708
|
-
|
|
709
|
+
|
|
709
710
|
if isinstance(celestial_point_language, dict):
|
|
710
711
|
celestial_point_language = KerykeionLanguageCelestialPointModel(**celestial_point_language)
|
|
711
712
|
|
|
@@ -719,26 +720,29 @@ def draw_transit_aspect_list(
|
|
|
719
720
|
line = 0
|
|
720
721
|
nl = 0
|
|
721
722
|
inner_path = ""
|
|
722
|
-
scale = 1
|
|
723
723
|
for i, aspect in enumerate(aspects_list):
|
|
724
724
|
# Adjust the vertical position for every 12 aspects
|
|
725
|
-
if i ==
|
|
725
|
+
if i == 14:
|
|
726
726
|
nl = 100
|
|
727
727
|
line = 0
|
|
728
728
|
|
|
729
|
-
elif i ==
|
|
729
|
+
elif i == 28:
|
|
730
730
|
nl = 200
|
|
731
731
|
line = 0
|
|
732
732
|
|
|
733
|
-
elif i ==
|
|
733
|
+
elif i == 42:
|
|
734
734
|
nl = 300
|
|
735
735
|
line = 0
|
|
736
736
|
|
|
737
|
-
elif i ==
|
|
737
|
+
elif i == 56:
|
|
738
738
|
nl = 400
|
|
739
|
+
line = 0
|
|
740
|
+
|
|
741
|
+
elif i == 70:
|
|
742
|
+
nl = 500
|
|
739
743
|
# When there are more than 60 aspects, the text is moved up
|
|
740
|
-
if len(aspects_list) >
|
|
741
|
-
line = -1 * (len(aspects_list) -
|
|
744
|
+
if len(aspects_list) > 84:
|
|
745
|
+
line = -1 * (len(aspects_list) - 84) * 14
|
|
742
746
|
else:
|
|
743
747
|
line = 0
|
|
744
748
|
|
|
@@ -761,7 +765,7 @@ def draw_transit_aspect_list(
|
|
|
761
765
|
inner_path += f"</g>"
|
|
762
766
|
line = line + 14
|
|
763
767
|
|
|
764
|
-
out = f'<g style="transform: translate(
|
|
768
|
+
out = f'<g style="transform: translate(43%, 50%)">'
|
|
765
769
|
out += f'<text y="-15" x="0" style="fill: var(--kerykeion-chart-color-paper-0); font-size: 14px;">{grid_title}:</text>'
|
|
766
770
|
out += inner_path
|
|
767
771
|
out += "</g>"
|
|
@@ -863,11 +867,11 @@ def draw_house_grid(
|
|
|
863
867
|
Returns:
|
|
864
868
|
- str: The SVG code for the grid of houses.
|
|
865
869
|
"""
|
|
866
|
-
|
|
870
|
+
|
|
867
871
|
if chart_type in ["Synastry", "Transit"] and secondary_subject_houses_list is None:
|
|
868
872
|
raise KerykeionException("secondary_houses is None")
|
|
869
873
|
|
|
870
|
-
svg_output = '<g transform="translate(
|
|
874
|
+
svg_output = '<g transform="translate(650,-20)">'
|
|
871
875
|
|
|
872
876
|
line_increment = 10
|
|
873
877
|
for i, house in enumerate(main_subject_houses_list):
|
|
@@ -885,7 +889,7 @@ def draw_house_grid(
|
|
|
885
889
|
|
|
886
890
|
if chart_type == "Synastry":
|
|
887
891
|
svg_output += '<!-- Synastry Houses -->'
|
|
888
|
-
svg_output += '<g transform="translate(
|
|
892
|
+
svg_output += '<g transform="translate(910, -20)">'
|
|
889
893
|
line_increment = 10
|
|
890
894
|
|
|
891
895
|
for i, house in enumerate(secondary_subject_houses_list): # type: ignore
|
|
@@ -935,8 +939,7 @@ def draw_planet_grid(
|
|
|
935
939
|
offset_between_lines = 14
|
|
936
940
|
|
|
937
941
|
svg_output = (
|
|
938
|
-
f'<g transform="translate(
|
|
939
|
-
f'<g transform="translate(140, -15)">'
|
|
942
|
+
f'<g transform="translate(175, -15)">'
|
|
940
943
|
f'<text text-anchor="end" style="fill:{text_color}; font-size: 14px;">{planets_and_houses_grid_title} {subject_name}:</text>'
|
|
941
944
|
f'</g>'
|
|
942
945
|
)
|
|
@@ -1003,13 +1006,12 @@ def draw_planet_grid(
|
|
|
1003
1006
|
svg_output += end_of_line
|
|
1004
1007
|
second_line_height += offset_between_lines
|
|
1005
1008
|
|
|
1006
|
-
svg_output += end_of_line
|
|
1007
1009
|
return svg_output
|
|
1008
1010
|
|
|
1009
1011
|
|
|
1010
1012
|
def draw_transit_aspect_grid(
|
|
1011
|
-
stroke_color: str,
|
|
1012
|
-
available_planets: list,
|
|
1013
|
+
stroke_color: str,
|
|
1014
|
+
available_planets: list,
|
|
1013
1015
|
aspects: list,
|
|
1014
1016
|
x_indent: int = 50,
|
|
1015
1017
|
y_indent: int = 250,
|
|
@@ -1080,4 +1082,4 @@ def draw_transit_aspect_grid(
|
|
|
1080
1082
|
if (aspect["p1"] == planet_a["id"] and aspect["p2"] == planet_b["id"]):
|
|
1081
1083
|
svg_output += f'<use x="{x_aspect - box_size + 1}" y="{y_aspect + 1}" xlink:href="#orb{aspect["aspect_degrees"]}" />'
|
|
1082
1084
|
|
|
1083
|
-
return svg_output
|
|
1085
|
+
return svg_output
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
import logging
|
|
8
|
+
import swisseph as swe
|
|
8
9
|
from typing import get_args
|
|
9
10
|
|
|
10
11
|
from kerykeion.settings.kerykeion_settings import get_settings
|
|
@@ -17,8 +18,8 @@ from kerykeion.kr_types.kr_models import AstrologicalSubjectModel
|
|
|
17
18
|
from kerykeion.kr_types.settings_models import KerykeionSettingsCelestialPointModel, KerykeionSettingsModel
|
|
18
19
|
from kerykeion.kr_types.kr_literals import KerykeionChartTheme, KerykeionChartLanguage
|
|
19
20
|
from kerykeion.charts.charts_utils import (
|
|
20
|
-
draw_zodiac_slice,
|
|
21
|
-
convert_latitude_coordinate_to_string,
|
|
21
|
+
draw_zodiac_slice,
|
|
22
|
+
convert_latitude_coordinate_to_string,
|
|
22
23
|
convert_longitude_coordinate_to_string,
|
|
23
24
|
draw_aspect_line,
|
|
24
25
|
draw_elements_percentages,
|
|
@@ -62,13 +63,16 @@ class KerykeionChartSVG:
|
|
|
62
63
|
- double_chart_aspect_grid_type: Set the type of the aspect grid for the double chart (transit or synastry). (Default: list.)
|
|
63
64
|
- chart_language: Set the language for the chart (default: EN).
|
|
64
65
|
"""
|
|
65
|
-
|
|
66
|
+
|
|
66
67
|
# Constants
|
|
67
|
-
_BASIC_CHART_VIEWBOX = "0 0
|
|
68
|
-
_WIDE_CHART_VIEWBOX = "0 0
|
|
69
|
-
|
|
68
|
+
_BASIC_CHART_VIEWBOX = "0 0 820 550.0"
|
|
69
|
+
_WIDE_CHART_VIEWBOX = "0 0 1200 546.0"
|
|
70
|
+
_TRANSIT_CHART_WITH_TABLE_VIWBOX = "0 0 960 546.0"
|
|
71
|
+
|
|
72
|
+
_DEFAULT_HEIGHT = 550
|
|
70
73
|
_DEFAULT_FULL_WIDTH = 1200
|
|
71
|
-
_DEFAULT_NATAL_WIDTH =
|
|
74
|
+
_DEFAULT_NATAL_WIDTH = 820
|
|
75
|
+
_DEFAULT_FULL_WIDTH_WITH_TABLE = 960
|
|
72
76
|
_PLANET_IN_ZODIAC_EXTRA_POINTS = 10
|
|
73
77
|
|
|
74
78
|
# Set at init
|
|
@@ -170,6 +174,8 @@ class KerykeionChartSVG:
|
|
|
170
174
|
self.height = self._DEFAULT_HEIGHT
|
|
171
175
|
if self.chart_type == "Synastry" or self.chart_type == "Transit":
|
|
172
176
|
self.width = self._DEFAULT_FULL_WIDTH
|
|
177
|
+
elif self.double_chart_aspect_grid_type == "table" and self.chart_type == "Transit":
|
|
178
|
+
self.width = self._DEFAULT_FULL_WIDTH_WITH_TABLE
|
|
173
179
|
else:
|
|
174
180
|
self.width = self._DEFAULT_NATAL_WIDTH
|
|
175
181
|
|
|
@@ -177,7 +183,7 @@ class KerykeionChartSVG:
|
|
|
177
183
|
self.location = self.user.city
|
|
178
184
|
self.geolat = self.user.lat
|
|
179
185
|
self.geolon = self.user.lng
|
|
180
|
-
|
|
186
|
+
|
|
181
187
|
if self.chart_type == "Transit":
|
|
182
188
|
self.t_name = self.language_settings["transit_name"]
|
|
183
189
|
|
|
@@ -284,7 +290,7 @@ class KerykeionChartSVG:
|
|
|
284
290
|
{"name": "Aqu", "element": "air"},
|
|
285
291
|
{"name": "Pis", "element": "water"},
|
|
286
292
|
)
|
|
287
|
-
|
|
293
|
+
|
|
288
294
|
# Available bodies
|
|
289
295
|
available_celestial_points_names = []
|
|
290
296
|
for body in self.available_planets_setting:
|
|
@@ -364,7 +370,12 @@ class KerykeionChartSVG:
|
|
|
364
370
|
template_dict["stringName"] = f"{self.user.name}:" if self.chart_type in ["Synastry", "Transit"] else f'{self.language_settings["info"]}:'
|
|
365
371
|
|
|
366
372
|
# Set viewbox based on chart type
|
|
367
|
-
|
|
373
|
+
if self.chart_type in ["Natal", "ExternalNatal"]:
|
|
374
|
+
template_dict['viewbox'] = self._BASIC_CHART_VIEWBOX
|
|
375
|
+
elif self.double_chart_aspect_grid_type == "table" and self.chart_type == "Transit":
|
|
376
|
+
template_dict['viewbox'] = self._TRANSIT_CHART_WITH_TABLE_VIWBOX
|
|
377
|
+
else:
|
|
378
|
+
template_dict['viewbox'] = self._WIDE_CHART_VIEWBOX
|
|
368
379
|
|
|
369
380
|
# Generate rings and circles based on chart type
|
|
370
381
|
if self.chart_type in ["Transit", "Synastry"]:
|
|
@@ -398,11 +409,19 @@ class KerykeionChartSVG:
|
|
|
398
409
|
else:
|
|
399
410
|
template_dict["stringTitle"] = self.user.name
|
|
400
411
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
412
|
+
if self.user.zodiac_type == 'Tropic':
|
|
413
|
+
zodiac_info = "Tropical Zodiac"
|
|
414
|
+
|
|
415
|
+
else:
|
|
416
|
+
mode_const = "SIDM_" + self.user.sidereal_mode # type: ignore
|
|
417
|
+
mode_name = swe.get_ayanamsa_name(getattr(swe, mode_const))
|
|
418
|
+
zodiac_info = f"Ayanamsa: {mode_name}"
|
|
419
|
+
|
|
420
|
+
template_dict["bottomLeft0"] = f"{self.user.houses_system_name} Houses"
|
|
421
|
+
template_dict["bottomLeft1"] = zodiac_info
|
|
422
|
+
|
|
404
423
|
if self.chart_type in ["Natal", "ExternalNatal", "Synastry"]:
|
|
405
|
-
template_dict["bottomLeft2"] = f'{self.language_settings.get("lunar_phase", "Lunar Phase")}
|
|
424
|
+
template_dict["bottomLeft2"] = f'{self.language_settings.get("lunar_phase", "Lunar Phase")} {self.language_settings.get("day", "Day").lower()}: {self.user.lunar_phase.get("moon_phase", "")}'
|
|
406
425
|
template_dict["bottomLeft3"] = f'{self.language_settings.get("lunar_phase", "Lunar Phase")}: {self.user.lunar_phase.moon_phase_name}'
|
|
407
426
|
template_dict["bottomLeft4"] = f'{self.user.perspective_type}'
|
|
408
427
|
else:
|
|
@@ -412,7 +431,7 @@ class KerykeionChartSVG:
|
|
|
412
431
|
|
|
413
432
|
# Draw moon phase
|
|
414
433
|
template_dict['moon_phase'] = draw_moon_phase(
|
|
415
|
-
self.user.lunar_phase["degrees_between_s_m"],
|
|
434
|
+
self.user.lunar_phase["degrees_between_s_m"],
|
|
416
435
|
self.geolat
|
|
417
436
|
)
|
|
418
437
|
|
|
@@ -513,20 +532,20 @@ class KerykeionChartSVG:
|
|
|
513
532
|
# Draw planets
|
|
514
533
|
if self.chart_type in ["Transit", "Synastry"]:
|
|
515
534
|
template_dict["makePlanets"] = draw_planets(
|
|
516
|
-
available_kerykeion_celestial_points=self.available_kerykeion_celestial_points,
|
|
535
|
+
available_kerykeion_celestial_points=self.available_kerykeion_celestial_points,
|
|
517
536
|
available_planets_setting=self.available_planets_setting,
|
|
518
537
|
second_subject_available_kerykeion_celestial_points=self.t_available_kerykeion_celestial_points,
|
|
519
|
-
radius=self.main_radius,
|
|
538
|
+
radius=self.main_radius,
|
|
520
539
|
main_subject_first_house_degree_ut=self.user.first_house.abs_pos,
|
|
521
540
|
main_subject_seventh_house_degree_ut=self.user.seventh_house.abs_pos,
|
|
522
|
-
chart_type=self.chart_type,
|
|
541
|
+
chart_type=self.chart_type,
|
|
523
542
|
third_circle_radius=self.third_circle_radius,
|
|
524
543
|
)
|
|
525
544
|
else:
|
|
526
545
|
template_dict["makePlanets"] = draw_planets(
|
|
527
546
|
available_planets_setting=self.available_planets_setting,
|
|
528
547
|
chart_type=self.chart_type,
|
|
529
|
-
radius=self.main_radius,
|
|
548
|
+
radius=self.main_radius,
|
|
530
549
|
available_kerykeion_celestial_points=self.available_kerykeion_celestial_points,
|
|
531
550
|
third_circle_radius=self.third_circle_radius,
|
|
532
551
|
main_subject_first_house_degree_ut=self.user.first_house.abs_pos,
|
|
@@ -585,7 +604,7 @@ class KerykeionChartSVG:
|
|
|
585
604
|
|
|
586
605
|
DATA_DIR = Path(__file__).parent
|
|
587
606
|
xml_svg = DATA_DIR / "templates" / "chart.xml"
|
|
588
|
-
|
|
607
|
+
|
|
589
608
|
# read template
|
|
590
609
|
with open(xml_svg, "r", encoding="utf-8", errors="ignore") as f:
|
|
591
610
|
template = Template(f.read()).substitute(td)
|
|
@@ -619,16 +638,16 @@ class KerykeionChartSVG:
|
|
|
619
638
|
|
|
620
639
|
def makeWheelOnlyTemplate(self, minify: bool = False):
|
|
621
640
|
"""Creates the template for the SVG file with only the wheel"""
|
|
622
|
-
|
|
641
|
+
|
|
623
642
|
with open(Path(__file__).parent / "templates" / "wheel_only.xml", "r", encoding="utf-8", errors="ignore") as f:
|
|
624
643
|
template = f.read()
|
|
625
644
|
|
|
626
645
|
template_dict = self._create_template_dictionary()
|
|
627
646
|
template = Template(template).substitute(template_dict)
|
|
628
|
-
|
|
647
|
+
|
|
629
648
|
if minify:
|
|
630
649
|
template = scourString(template).replace('"', "'").replace("\n", "").replace("\t","").replace(" ", "").replace(" ", "")
|
|
631
|
-
|
|
650
|
+
|
|
632
651
|
else:
|
|
633
652
|
template = template.replace('"', "'")
|
|
634
653
|
|
|
@@ -647,7 +666,7 @@ class KerykeionChartSVG:
|
|
|
647
666
|
|
|
648
667
|
def makeAspectGridOnlyTemplate(self, minify: bool = False):
|
|
649
668
|
"""Creates the template for the SVG file with only the aspect grid"""
|
|
650
|
-
|
|
669
|
+
|
|
651
670
|
with open(Path(__file__).parent / "templates" / "aspect_grid_only.xml", "r", encoding="utf-8", errors="ignore") as f:
|
|
652
671
|
template = f.read()
|
|
653
672
|
|
|
@@ -659,10 +678,10 @@ class KerykeionChartSVG:
|
|
|
659
678
|
aspects_grid = draw_aspect_grid(self.chart_colors_settings['paper_0'], self.available_planets_setting, self.aspects_list, x_start=50, y_start=250)
|
|
660
679
|
|
|
661
680
|
template = Template(template).substitute({**template_dict, "makeAspectGrid": aspects_grid})
|
|
662
|
-
|
|
681
|
+
|
|
663
682
|
if minify:
|
|
664
683
|
template = scourString(template).replace('"', "'").replace("\n", "").replace("\t","").replace(" ", "").replace(" ", "")
|
|
665
|
-
|
|
684
|
+
|
|
666
685
|
else:
|
|
667
686
|
template = template.replace('"', "'")
|
|
668
687
|
|
|
@@ -702,7 +721,7 @@ if __name__ == "__main__":
|
|
|
702
721
|
# Transits Chart
|
|
703
722
|
transits_chart = KerykeionChartSVG(first, "Transit", second)
|
|
704
723
|
transits_chart.makeSVG()
|
|
705
|
-
|
|
724
|
+
|
|
706
725
|
# Sidereal Birth Chart (Lahiri)
|
|
707
726
|
sidereal_subject = AstrologicalSubject("John Lennon Lahiri", 1940, 10, 9, 18, 30, "Liverpool", "GB", zodiac_type="Sidereal", sidereal_mode="LAHIRI")
|
|
708
727
|
sidereal_chart = KerykeionChartSVG(sidereal_subject)
|
|
@@ -841,6 +860,11 @@ if __name__ == "__main__":
|
|
|
841
860
|
aspect_grid_dark_synastry_chart = KerykeionChartSVG(aspect_grid_dark_synastry_subject, "Synastry", second, theme="dark")
|
|
842
861
|
aspect_grid_dark_synastry_chart.makeAspectGridOnlySVG()
|
|
843
862
|
|
|
863
|
+
# Synastry Chart With draw_transit_aspect_list table
|
|
864
|
+
synastry_chart_with_table_list_subject = AstrologicalSubject("John Lennon - SCTWL", 1940, 10, 9, 18, 30, "Liverpool", "GB")
|
|
865
|
+
synastry_chart_with_table_list = KerykeionChartSVG(synastry_chart_with_table_list_subject, "Synastry", second, double_chart_aspect_grid_type="list", theme="dark")
|
|
866
|
+
synastry_chart_with_table_list.makeSVG()
|
|
867
|
+
|
|
844
868
|
# Transit Chart With draw_transit_aspect_grid table
|
|
845
869
|
transit_chart_with_table_grid_subject = AstrologicalSubject("John Lennon - TCWTG", 1940, 10, 9, 18, 30, "Liverpool", "GB")
|
|
846
870
|
transit_chart_with_table_grid = KerykeionChartSVG(transit_chart_with_table_grid_subject, "Transit", second, double_chart_aspect_grid_type="table", theme="dark")
|
|
@@ -889,4 +913,9 @@ if __name__ == "__main__":
|
|
|
889
913
|
# Hindi Language Chart
|
|
890
914
|
hindi_subject = AstrologicalSubject("Amitabh Bachchan", 1942, 10, 11, 4, 0, "Allahabad", "IN")
|
|
891
915
|
hindi_chart = KerykeionChartSVG(hindi_subject, chart_language="HI")
|
|
892
|
-
hindi_chart.makeSVG()
|
|
916
|
+
hindi_chart.makeSVG()
|
|
917
|
+
|
|
918
|
+
# Kanye West Natal Chart
|
|
919
|
+
kanye_west_subject = AstrologicalSubject("Kanye", 1977, 6, 8, 8, 45, "Atlanta", "US")
|
|
920
|
+
kanye_west_chart = KerykeionChartSVG(kanye_west_subject)
|
|
921
|
+
kanye_west_chart.makeSVG()
|
|
@@ -7,7 +7,7 @@ OpenAstro.org -->
|
|
|
7
7
|
xmlns:kr="https://www.kerykeion.net/"
|
|
8
8
|
width="100%"
|
|
9
9
|
height="100%"
|
|
10
|
-
viewBox="
|
|
10
|
+
viewBox="28 20 255 250"
|
|
11
11
|
preserveAspectRatio="xMidYMid"
|
|
12
12
|
style="background-color: $paper_color_1"
|
|
13
13
|
>
|
|
@@ -146,6 +146,24 @@ OpenAstro.org -->
|
|
|
146
146
|
/>
|
|
147
147
|
</g>
|
|
148
148
|
</symbol>
|
|
149
|
+
<symbol id="Mean_South_Node">
|
|
150
|
+
<g transform="translate(2,5)">
|
|
151
|
+
<g transform="scale(.75)">
|
|
152
|
+
<path
|
|
153
|
+
d="M 13.891439,23.899148 C 16.831061,23.16167 19.42871,20.957929 20.393204,18.051853 C 21.020409,16.655337 20.990829,15.041667 20.533362,13.600675 C 20.114218,11.835116 19.107819,10.284901 18.004613,8.8731359 C 17.010334,7.1652064 16.695528,4.9968194 17.378257,3.1191925 C 17.758616,2.134839 18.612459,1.1290194 19.747609,1.122205 C 20.856714,1.1522691 21.68807,2.1940507 21.762984,3.2502572 C 21.912267,4.7681974 20.969993,6.4261707 19.471746,6.8713331 C 19.067889,7.1616711 18.25164,6.6059847 18.085179,6.9788263 C 19.290894,8.1433226 21.294758,8.0903554 22.639135,7.1933294 C 23.815746,6.4142182 24.244753,4.8354574 23.866042,3.513777 C 23.579596,1.951978 22.299181,0.68814445 20.784404,0.28003765 C 19.338156,-0.21325355 17.636132,-0.074257846 16.389677,0.85208495 C 14.815514,1.7718962 14.147431,3.6918765 14.163087,5.4368764 C 14.158082,6.4844752 14.521263,7.4854719 14.829092,8.4735115 C 15.207397,9.5849835 15.743054,10.635344 16.373553,11.623268 C 17.391254,13.444769 18.097991,15.578055 17.73759,17.680935 C 17.264619,20.303885 14.771995,22.367369 12.114619,22.391402 C 10.221592,22.570108 8.4623977,21.408784 7.3640695,19.946934 C 5.9800493,18.024601 5.7632677,15.423089 6.5407261,13.21741 C 7.0447364,11.683217 7.9039267,10.303136 8.7551602,8.9442496 C 9.3673378,7.7170077 9.5453858,6.3050768 9.4520188,4.9498232 C 9.3273658,3.5827422 9.055649,2.055641 7.9264908,1.1408811 C 5.9170924,-0.45587205 2.5879904,-0.21634735 1.0121097,1.878869 C -0.10699561,3.3638861 -0.077071356,5.7321616 1.3439679,7.0142862 C 2.2628957,7.7723325 3.5523542,8.1172364 4.7082249,7.7533106 C 5.2902186,7.5823499 5.8305214,7.2547717 6.2290478,6.7948231 C 5.2075081,6.7604711 3.9811354,6.8872988 3.2192579,6.0602046 C 2.4586494,4.9643087 2.1899922,3.4530691 2.7277339,2.20348 C 3.1104121,1.3003657 4.160788,0.64048665 5.1397626,0.98349485 C 6.2468062,1.3370711 6.9552792,2.4455554 7.0537996,3.5696899 C 7.3808409,5.492555 7.1315,7.5939422 5.9619608,9.2041629 C 5.2025142,10.29701 4.2871193,11.315357 3.8562083,12.598809 C 2.7918212,15.240251 3.4299247,18.367596 5.1702811,20.571791 C 6.8286269,22.84876 9.6781638,24.154892 12.482992,23.997045 C 12.953784,23.989488 13.423977,23.955037 13.891439,23.899148 z "
|
|
154
|
+
style="fill: $planets_color_10" />
|
|
155
|
+
</g>
|
|
156
|
+
</g>
|
|
157
|
+
</symbol>
|
|
158
|
+
<symbol id="True_South_Node">
|
|
159
|
+
<g transform="translate(2,5)">
|
|
160
|
+
<g transform="scale(.75)">
|
|
161
|
+
<path
|
|
162
|
+
d="M 13.891439,23.899148 C 16.831061,23.16167 19.42871,20.957929 20.393204,18.051853 C 21.020409,16.655337 20.990829,15.041667 20.533362,13.600675 C 20.114218,11.835116 19.107819,10.284901 18.004613,8.8731359 C 17.010334,7.1652064 16.695528,4.9968194 17.378257,3.1191925 C 17.758616,2.134839 18.612459,1.1290194 19.747609,1.122205 C 20.856714,1.1522691 21.68807,2.1940507 21.762984,3.2502572 C 21.912267,4.7681974 20.969993,6.4261707 19.471746,6.8713331 C 19.067889,7.1616711 18.25164,6.6059847 18.085179,6.9788263 C 19.290894,8.1433226 21.294758,8.0903554 22.639135,7.1933294 C 23.815746,6.4142182 24.244753,4.8354574 23.866042,3.513777 C 23.579596,1.951978 22.299181,0.68814445 20.784404,0.28003765 C 19.338156,-0.21325355 17.636132,-0.074257846 16.389677,0.85208495 C 14.815514,1.7718962 14.147431,3.6918765 14.163087,5.4368764 C 14.158082,6.4844752 14.521263,7.4854719 14.829092,8.4735115 C 15.207397,9.5849835 15.743054,10.635344 16.373553,11.623268 C 17.391254,13.444769 18.097991,15.578055 17.73759,17.680935 C 17.264619,20.303885 14.771995,22.367369 12.114619,22.391402 C 10.221592,22.570108 8.4623977,21.408784 7.3640695,19.946934 C 5.9800493,18.024601 5.7632677,15.423089 6.5407261,13.21741 C 7.0447364,11.683217 7.9039267,10.303136 8.7551602,8.9442496 C 9.3673378,7.7170077 9.5453858,6.3050768 9.4520188,4.9498232 C 9.3273658,3.5827422 9.055649,2.055641 7.9264908,1.1408811 C 5.9170924,-0.45587205 2.5879904,-0.21634735 1.0121097,1.878869 C -0.10699561,3.3638861 -0.077071356,5.7321616 1.3439679,7.0142862 C 2.2628957,7.7723325 3.5523542,8.1172364 4.7082249,7.7533106 C 5.2902186,7.5823499 5.8305214,7.2547717 6.2290478,6.7948231 C 5.2075081,6.7604711 3.9811354,6.8872988 3.2192579,6.0602046 C 2.4586494,4.9643087 2.1899922,3.4530691 2.7277339,2.20348 C 3.1104121,1.3003657 4.160788,0.64048665 5.1397626,0.98349485 C 6.2468062,1.3370711 6.9552792,2.4455554 7.0537996,3.5696899 C 7.3808409,5.492555 7.1315,7.5939422 5.9619608,9.2041629 C 5.2025142,10.29701 4.2871193,11.315357 3.8562083,12.598809 C 2.7918212,15.240251 3.4299247,18.367596 5.1702811,20.571791 C 6.8286269,22.84876 9.6781638,24.154892 12.482992,23.997045 C 12.953784,23.989488 13.423977,23.955037 13.891439,23.899148 z "
|
|
163
|
+
style="fill: $planets_color_11" />
|
|
164
|
+
</g>
|
|
165
|
+
</g>
|
|
166
|
+
</symbol>
|
|
149
167
|
<symbol id="Chiron">
|
|
150
168
|
<path
|
|
151
169
|
d="M 10.019873,13.068981 L 10.185542,0.80951431 M 10.195591,6.7442901 L 15.496983,2.2712408 M 10.214831,6.6321726 L 15.516217,11.105216 M 17.192934,17.998774 C 17.192934,20.8646 14.867052,23.190487 12.001226,23.190487 C 9.1353988,23.190487 6.8095128,20.8646 6.8095128,17.998774 C 6.8095128,15.132953 9.1353988,12.807066 12.001226,12.807066 C 14.867052,12.807066 17.192934,15.132953 17.192934,17.998774 z "
|
|
@@ -449,4 +467,4 @@ OpenAstro.org -->
|
|
|
449
467
|
/>
|
|
450
468
|
</symbol>
|
|
451
469
|
</defs>
|
|
452
|
-
</svg>
|
|
470
|
+
</svg>
|