magick-components 0.0.0-stage → 0.1.0

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.
Files changed (173) hide show
  1. package/LICENSE.txt +89 -0
  2. package/README.md +353 -2
  3. package/fonts/FrankRuhlLibre-Bold-letters.woff2 +0 -0
  4. package/fonts/FrankRuhlLibre-OFL.txt +105 -0
  5. package/fonts/NotoSerif-BoldItalic-compass.woff2 +0 -0
  6. package/fonts/NotoSerif-Italic-latin1.woff2 +0 -0
  7. package/fonts/NotoSerif-OFL.txt +93 -0
  8. package/fonts/SOURCES.md +35 -0
  9. package/fonts/gd-hall.css +3 -0
  10. package/lib/astrology/Kamea.d.ts +75 -0
  11. package/lib/astrology/Kamea.js +73 -0
  12. package/lib/astrology/MercuryWidget.d.ts +21 -0
  13. package/lib/astrology/MercuryWidget.js +80 -0
  14. package/lib/astrology/Moon.d.ts +32 -0
  15. package/lib/astrology/Moon.js +39 -0
  16. package/lib/astrology/MoonWidget.d.ts +20 -0
  17. package/lib/astrology/MoonWidget.js +63 -0
  18. package/lib/astrology/PlanetarySpirit.d.ts +103 -0
  19. package/lib/astrology/PlanetarySpirit.js +102 -0
  20. package/lib/astrology/mercuryRetrograde.d.ts +20 -0
  21. package/lib/astrology/mercuryRetrograde.js +80 -0
  22. package/lib/astrology/moonPath.d.ts +20 -0
  23. package/lib/astrology/moonPath.js +45 -0
  24. package/lib/chakras/Chakras.d.ts +34 -0
  25. package/lib/chakras/Chakras.js +149 -0
  26. package/lib/cssString.d.ts +5 -0
  27. package/lib/cssString.js +7 -0
  28. package/lib/drawingVersions.d.ts +29 -0
  29. package/lib/drawingVersions.js +15 -0
  30. package/lib/enochian/Tablet.d.ts +17 -0
  31. package/lib/enochian/Tablet.js +24 -0
  32. package/lib/enochian/tabletSigils.d.ts +46 -0
  33. package/lib/enochian/tabletSigils.js +172 -0
  34. package/lib/enochian/tabletSvg.d.ts +85 -0
  35. package/lib/enochian/tabletSvg.js +278 -0
  36. package/lib/gd/FylfotCross.d.ts +60 -0
  37. package/lib/gd/FylfotCross.js +121 -0
  38. package/lib/gd/GradeTree.d.ts +10 -0
  39. package/lib/gd/GradeTree.js +21 -0
  40. package/lib/gd/Lamen.d.ts +31 -0
  41. package/lib/gd/Lamen.js +317 -0
  42. package/lib/gd/RoseSigil.d.ts +31 -0
  43. package/lib/gd/RoseSigil.js +49 -0
  44. package/lib/gd/RoseSigilImage.d.ts +38 -0
  45. package/lib/gd/RoseSigilImage.js +29 -0
  46. package/lib/gd/SevenBranchedCandlestick.d.ts +54 -0
  47. package/lib/gd/SevenBranchedCandlestick.js +269 -0
  48. package/lib/gd/TableOfShewbread.d.ts +19 -0
  49. package/lib/gd/TableOfShewbread.js +120 -0
  50. package/lib/gd/hall/GdHall.d.ts +94 -0
  51. package/lib/gd/hall/GdHall.js +147 -0
  52. package/lib/gd/hall/art/altar.d.ts +8 -0
  53. package/lib/gd/hall/art/altar.js +21 -0
  54. package/lib/gd/hall/art/altarItems.d.ts +20 -0
  55. package/lib/gd/hall/art/altarItems.js +113 -0
  56. package/lib/gd/hall/art/banner.d.ts +23 -0
  57. package/lib/gd/hall/art/banner.js +64 -0
  58. package/lib/gd/hall/art/board.d.ts +9 -0
  59. package/lib/gd/hall/art/board.js +49 -0
  60. package/lib/gd/hall/art/cards.d.ts +11 -0
  61. package/lib/gd/hall/art/cards.js +124 -0
  62. package/lib/gd/hall/art/furnishings.d.ts +12 -0
  63. package/lib/gd/hall/art/furnishings.js +36 -0
  64. package/lib/gd/hall/art/geometry.d.ts +49 -0
  65. package/lib/gd/hall/art/geometry.js +97 -0
  66. package/lib/gd/hall/art/hebrewLetter.d.ts +10 -0
  67. package/lib/gd/hall/art/hebrewLetter.js +38 -0
  68. package/lib/gd/hall/art/index.d.ts +7 -0
  69. package/lib/gd/hall/art/index.js +61 -0
  70. package/lib/gd/hall/art/items.d.ts +12 -0
  71. package/lib/gd/hall/art/items.js +125 -0
  72. package/lib/gd/hall/art/kamea.d.ts +20 -0
  73. package/lib/gd/hall/art/kamea.js +64 -0
  74. package/lib/gd/hall/art/lamen.d.ts +9 -0
  75. package/lib/gd/hall/art/lamen.js +52 -0
  76. package/lib/gd/hall/art/lightning.d.ts +13 -0
  77. package/lib/gd/hall/art/lightning.js +44 -0
  78. package/lib/gd/hall/art/lights.d.ts +13 -0
  79. package/lib/gd/hall/art/lights.js +64 -0
  80. package/lib/gd/hall/art/marker.d.ts +8 -0
  81. package/lib/gd/hall/art/marker.js +19 -0
  82. package/lib/gd/hall/art/pantacle.d.ts +10 -0
  83. package/lib/gd/hall/art/pantacle.js +119 -0
  84. package/lib/gd/hall/art/pillar.d.ts +4 -0
  85. package/lib/gd/hall/art/pillar.js +25 -0
  86. package/lib/gd/hall/art/placeholder.d.ts +8 -0
  87. package/lib/gd/hall/art/placeholder.js +18 -0
  88. package/lib/gd/hall/art/platform.d.ts +13 -0
  89. package/lib/gd/hall/art/platform.js +28 -0
  90. package/lib/gd/hall/art/seals.d.ts +23 -0
  91. package/lib/gd/hall/art/seals.js +151 -0
  92. package/lib/gd/hall/art/shared.d.ts +87 -0
  93. package/lib/gd/hall/art/shared.js +95 -0
  94. package/lib/gd/hall/art/symbols.d.ts +37 -0
  95. package/lib/gd/hall/art/symbols.js +134 -0
  96. package/lib/gd/hall/art/tarotKey.d.ts +34 -0
  97. package/lib/gd/hall/art/tarotKey.js +101 -0
  98. package/lib/gd/hall/art/veil.d.ts +8 -0
  99. package/lib/gd/hall/art/veil.js +22 -0
  100. package/lib/gd/hall/art/vessels.d.ts +19 -0
  101. package/lib/gd/hall/art/vessels.js +74 -0
  102. package/lib/gd/hall/aspect.d.ts +31 -0
  103. package/lib/gd/hall/aspect.js +161 -0
  104. package/lib/gd/hall/attributes.d.ts +52 -0
  105. package/lib/gd/hall/attributes.js +116 -0
  106. package/lib/gd/hall/describe.d.ts +38 -0
  107. package/lib/gd/hall/describe.js +184 -0
  108. package/lib/gd/hall/dimensions.d.ts +39 -0
  109. package/lib/gd/hall/dimensions.js +49 -0
  110. package/lib/gd/hall/editor.d.ts +13 -0
  111. package/lib/gd/hall/editor.js +13 -0
  112. package/lib/gd/hall/fontMetrics.json +177 -0
  113. package/lib/gd/hall/fonts.d.ts +45 -0
  114. package/lib/gd/hall/fonts.js +73 -0
  115. package/lib/gd/hall/hebrewLetters.d.ts +8 -0
  116. package/lib/gd/hall/hebrewLetters.js +40 -0
  117. package/lib/gd/hall/index.d.ts +19 -0
  118. package/lib/gd/hall/index.js +17 -0
  119. package/lib/gd/hall/labels.d.ts +72 -0
  120. package/lib/gd/hall/labels.js +109 -0
  121. package/lib/gd/hall/layout.d.ts +213 -0
  122. package/lib/gd/hall/layout.js +837 -0
  123. package/lib/gd/hall/planets.d.ts +13 -0
  124. package/lib/gd/hall/planets.js +35 -0
  125. package/lib/gd/hall/presets/index.d.ts +13 -0
  126. package/lib/gd/hall/presets/index.js +29 -0
  127. package/lib/gd/hall/presets/neophyte.d.ts +7 -0
  128. package/lib/gd/hall/presets/neophyte.js +74 -0
  129. package/lib/gd/hall/presets/philosophus.d.ts +30 -0
  130. package/lib/gd/hall/presets/philosophus.js +244 -0
  131. package/lib/gd/hall/presets/portal.d.ts +24 -0
  132. package/lib/gd/hall/presets/portal.js +241 -0
  133. package/lib/gd/hall/presets/practicus.d.ts +17 -0
  134. package/lib/gd/hall/presets/practicus.js +181 -0
  135. package/lib/gd/hall/presets/theoricus.d.ts +13 -0
  136. package/lib/gd/hall/presets/theoricus.js +178 -0
  137. package/lib/gd/hall/presets/types.d.ts +72 -0
  138. package/lib/gd/hall/presets/types.js +58 -0
  139. package/lib/gd/hall/presets/zelator.d.ts +12 -0
  140. package/lib/gd/hall/presets/zelator.js +161 -0
  141. package/lib/gd/hall/spec.d.ts +54 -0
  142. package/lib/gd/hall/spec.js +108 -0
  143. package/lib/gd/hall/types.d.ts +131 -0
  144. package/lib/gd/hall/types.js +1 -0
  145. package/lib/gd/hall/validate.d.ts +13 -0
  146. package/lib/gd/hall/validate.js +285 -0
  147. package/lib/gd/hall/vocabulary.d.ts +139 -0
  148. package/lib/gd/hall/vocabulary.js +435 -0
  149. package/lib/gd/lamenGlyphs.d.ts +16 -0
  150. package/lib/gd/lamenGlyphs.js +167 -0
  151. package/lib/gd/lamenGrades.d.ts +29 -0
  152. package/lib/gd/lamenGrades.js +36 -0
  153. package/lib/gd/roseSigilGeometry.d.ts +10 -0
  154. package/lib/gd/roseSigilGeometry.js +10 -0
  155. package/lib/gd/roseSigilInternals.d.ts +85 -0
  156. package/lib/gd/roseSigilInternals.js +343 -0
  157. package/lib/gd/roseSigilOptimizer.d.ts +15 -0
  158. package/lib/gd/roseSigilOptimizer.js +59 -0
  159. package/lib/gd/roseSigilVersions.d.ts +12 -0
  160. package/lib/gd/roseSigilVersions.js +57 -0
  161. package/lib/hooks/useHydrated.d.ts +9 -0
  162. package/lib/hooks/useHydrated.js +13 -0
  163. package/lib/kabbalah/TreeOfLife.d.ts +135 -0
  164. package/lib/kabbalah/TreeOfLife.js +312 -0
  165. package/lib/kabbalah/fieldPath.d.ts +25 -0
  166. package/lib/kabbalah/fieldPath.js +100 -0
  167. package/lib/kabbalah/treeLabels.d.ts +30 -0
  168. package/lib/kabbalah/treeLabels.js +32 -0
  169. package/lib/kabbalah/treeOfLifeFigure.d.ts +59 -0
  170. package/lib/kabbalah/treeOfLifeFigure.js +151 -0
  171. package/lib/svgCoordinate.d.ts +12 -0
  172. package/lib/svgCoordinate.js +16 -0
  173. package/package.json +162 -3
@@ -0,0 +1,54 @@
1
+ import { type PlanetId } from "magick-data/astrology/planets";
2
+ import React from "react";
3
+ import { type DrawingSource, type DrawingVersionNote } from "../drawingVersions.ts";
4
+ /**
5
+ * The versions of the candlestick: the figure of *The Equinox* I(2)
6
+ * (1909), Diagram 17 (`equinox1909`, the default), and the arrangement
7
+ * of recent editions of Regardie (`modern`), which this package drew
8
+ * alone until 14 November 2026. A new version is a new id; neither of
9
+ * these moves.
10
+ */
11
+ export declare const CANDLESTICK_VERSIONS: readonly ["equinox1909", "modern"];
12
+ /** A version of the candlestick. */
13
+ export type CandlestickVersionId = (typeof CANDLESTICK_VERSIONS)[number];
14
+ /** The version the candlestick is drawn in unless another is asked for. */
15
+ export declare const DEFAULT_CANDLESTICK_VERSION: CandlestickVersionId;
16
+ /** One version of the candlestick: its name, its note and its sources. */
17
+ export type CandlestickVersionNote = DrawingVersionNote<CandlestickVersionId>;
18
+ export type { DrawingSource };
19
+ /** Each version's note, by its id. */
20
+ export declare const CANDLESTICK_VERSION_NOTES: Readonly<Record<CandlestickVersionId, CandlestickVersionNote>>;
21
+ /**
22
+ * Each version's seven lamps, clockwise from the top; the image's inputs
23
+ * name these rows.
24
+ */
25
+ export declare const CANDLESTICK_PLANETS: Readonly<Record<CandlestickVersionId, readonly PlanetId[]>>;
26
+ /** Props of the diagram. */
27
+ export interface SevenBranchedCandlestickProps {
28
+ /**
29
+ * Which candlestick (`CANDLESTICK_VERSIONS`): the figure of *The
30
+ * Equinox* I(2) (1909), Diagram 17 (`equinox1909`), when not given or
31
+ * not a version, or the arrangement of recent editions (`modern`).
32
+ * `CANDLESTICK_VERSION_NOTES` says where each comes from.
33
+ */
34
+ version?: CandlestickVersionId;
35
+ /**
36
+ * Prefixes the text paths' ids, which are document-wide: two of these
37
+ * on one page need different prefixes. No hook makes one, so that the
38
+ * component also renders where React's hooks are not available.
39
+ */
40
+ idPrefix?: string;
41
+ /** The `<svg>`, for exporting the drawing. */
42
+ ref?: React.Ref<SVGSVGElement>;
43
+ }
44
+ /**
45
+ * The Golden Dawn's seven-branched candlestick, in a version (`version`):
46
+ * by default the figure of *The Equinox* I(2) (1909), seven lamps about a
47
+ * central one, each with its double letter, the planet's Hebrew name, the
48
+ * archangel of its Sephirah and one of the seven churches, joined by a
49
+ * heptagram in the Chaldean order; or the modern arrangement, a branch
50
+ * for each planet with its symbol, Hebrew name, planetary angel and
51
+ * letter, set about a heptagram.
52
+ */
53
+ export declare function SevenBranchedCandlestick({ version, idPrefix, ref, }: SevenBranchedCandlestickProps): React.JSX.Element;
54
+ export default SevenBranchedCandlestick;
@@ -0,0 +1,269 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { assemble } from "magick-data/assemble";
3
+ import planetRows from "magick-data/astrology/planets";
4
+ import hebrewLetterRows from "magick-data/hebrewLetters";
5
+ import archangelRows from "magick-data/kabbalah/archangels";
6
+ import sephirahRows from "magick-data/kabbalah/sephirot";
7
+ import { archiveLeaf, } from "../drawingVersions.js";
8
+ import { svgCoordinate } from "../svgCoordinate.js";
9
+ /**
10
+ * The planets with their archangels and letters joined, and the sephirot
11
+ * whose archangels the 1909 figure gives: the four tables the lamps read,
12
+ * rather than the whole barrel.
13
+ */
14
+ const data = assemble({
15
+ planet: planetRows,
16
+ archangel: archangelRows,
17
+ hebrewLetter: hebrewLetterRows,
18
+ sephirah: sephirahRows,
19
+ });
20
+ /**
21
+ * The versions of the candlestick: the figure of *The Equinox* I(2)
22
+ * (1909), Diagram 17 (`equinox1909`, the default), and the arrangement
23
+ * of recent editions of Regardie (`modern`), which this package drew
24
+ * alone until 14 November 2026. A new version is a new id; neither of
25
+ * these moves.
26
+ */
27
+ export const CANDLESTICK_VERSIONS = ["equinox1909", "modern"];
28
+ /** The version the candlestick is drawn in unless another is asked for. */
29
+ export const DEFAULT_CANDLESTICK_VERSION = "equinox1909";
30
+ /** A version by its id, or the default for anything that is none. */
31
+ function versionOf(version) {
32
+ return CANDLESTICK_VERSIONS.includes(version ?? "")
33
+ ? version
34
+ : DEFAULT_CANDLESTICK_VERSION;
35
+ }
36
+ /** Each version's note, by its id. */
37
+ export const CANDLESTICK_VERSION_NOTES = {
38
+ equinox1909: {
39
+ id: "equinox1909",
40
+ title: "Equinox 1909",
41
+ text: "This is the figure printed in The Equinox I(2) (1909), p. 265, " +
42
+ "Diagram 17, from the Zelator ritual as Crowley received it. Each " +
43
+ "lamp bears a double letter, the Hebrew name of its planet, the " +
44
+ "archangel of that planet's Sephirah and one of the seven churches " +
45
+ "of Asia, and the lines of the star pass through the planets from " +
46
+ "Saturn down to the Moon. Taking every second lamp round the circle " +
47
+ "gives the days of the week.",
48
+ sources: [
49
+ {
50
+ text: "The Equinox, vol. I no. 2 (London, 1909), Diagram 17, p. 265 " +
51
+ "(archive.org leaf n266)",
52
+ url: archiveLeaf("crowley-equinox_202110", 266, "The Equinox Vol. 1, No. 2"),
53
+ },
54
+ ],
55
+ },
56
+ modern: {
57
+ id: "modern",
58
+ title: "Modern",
59
+ text: "This arrangement appears in recent editions of Regardie's The " +
60
+ "Golden Dawn; his text of 1938 (vol. 2, p. 62) describes the lamps " +
61
+ "but does not say which planet goes where. The planets stand in the " +
62
+ "order of the double letters on the Rose of 22 petals, with " +
63
+ "Agrippa's planetary angels in place of the archangels of the " +
64
+ "Sephiroth, and the triangles point inward. Unlike the 1909 figure, " +
65
+ "its star does not trace the days of the week, and it leaves out " +
66
+ "the churches and the central lamp.",
67
+ sources: [
68
+ {
69
+ text: "Israel Regardie, The Golden Dawn, vol. 2 (Aries Press, Chicago, " +
70
+ "1938), p. 62 (archive.org leaf n56), for the lamps",
71
+ url: archiveLeaf("IsraelRegardie-TheGoldenDawn-Vol2-1938", 56),
72
+ },
73
+ {
74
+ text: "Israel Regardie, The Golden Dawn (Llewellyn, 2015 edition), " +
75
+ "for the order, a fact only; nothing of it is copied",
76
+ },
77
+ ],
78
+ },
79
+ };
80
+ function degreesToPointOnCircle(degrees, radius, center = { x: 0, y: 0 }) {
81
+ const radians = (degrees * Math.PI) / 180;
82
+ // console.log(degrees, radians);
83
+ return {
84
+ x: radius * Math.cos(radians) + center.x,
85
+ y: radius * Math.sin(radians) + center.y,
86
+ };
87
+ }
88
+ /*
89
+ const branches: PlanetId[] = [
90
+ "sol",
91
+ "mars",
92
+ "jupiter",
93
+ "saturn",
94
+ "luna",
95
+ "mercury",
96
+ "venus",
97
+ ];
98
+ */
99
+ /**
100
+ * Each version's seven lamps, clockwise from the top; the image's inputs
101
+ * name these rows.
102
+ */
103
+ export const CANDLESTICK_PLANETS = {
104
+ // Diagram 17: Saturn at the top, then Mars, Venus, the Moon, Jupiter,
105
+ // the Sun and Mercury, so that the star, from Saturn, runs Saturn,
106
+ // Jupiter, Mars, Sun, Venus, Mercury, Moon (the Chaldean order), and
107
+ // every second lamp backwards from the Sun gives the week.
108
+ equinox1909: ["saturn", "mars", "venus", "luna", "jupiter", "sol", "mercury"],
109
+ modern: ["venus", "mercury", "sol", "mars", "jupiter", "saturn", "luna"],
110
+ };
111
+ const branches = CANDLESTICK_PLANETS.modern;
112
+ function Branch({ index, idPrefix }) {
113
+ const radius = 7.4; // TODO, work it out properly
114
+ const center = degreesToPointOnCircle((index * 360) / 7 - 90, 25 + radius);
115
+ const planetId = branches[index];
116
+ const planet = data.planet[planetId];
117
+ // console.log(planet);
118
+ const texts = [
119
+ planet.archangel?.name.he,
120
+ planet.hebrewLetter?.letter?.he,
121
+ planet.name.he?.he,
122
+ ];
123
+ // With extend radius so text is offset from the side of the triangle
124
+ const textPaths = [
125
+ [
126
+ degreesToPointOnCircle(90, radius + 1, center),
127
+ degreesToPointOnCircle(90 + 360 / 3, radius + 1, center),
128
+ ],
129
+ [
130
+ // Extend the radius even further so text path (which is on the
131
+ // bottom side of the text) still fits the top of the text below
132
+ // the triangle.
133
+ degreesToPointOnCircle(90 + (360 / 3) * 2, radius + 4.5, center),
134
+ degreesToPointOnCircle(90 + 360 / 3, radius + 4.5, center),
135
+ ],
136
+ [
137
+ degreesToPointOnCircle(90 + (360 / 3) * 2, radius + 1, center),
138
+ degreesToPointOnCircle(90, radius + 1, center),
139
+ ],
140
+ ];
141
+ const bottom = degreesToPointOnCircle(90, radius - 0.4, center);
142
+ const topLeft = degreesToPointOnCircle(90 + 360 / 3, radius - 0.4, center);
143
+ const topRight = degreesToPointOnCircle(90 + (360 / 3) * 2, radius - 0.4, center);
144
+ const rotation = (360 / 7) * index;
145
+ return (_jsxs("g", { transform: `rotate(${rotation} ${center.x} ${center.y})`, children: [_jsx("circle", { cx: center.x, cy: center.y, r: radius, fill: "none", stroke: "black", strokeWidth: "0.5" }), _jsx("path", { d: `M ${bottom.x} ${bottom.y} L ${topLeft.x} ${topLeft.y} L ${topRight.x} ${topRight.y} L ${bottom.x} ${bottom.y}`, fill: "none", stroke: "black", strokeWidth: "0.5" }), _jsx("text", { x: center.x, y: center.y, transform: `rotate(180 ${center.x} ${center.y})`, textAnchor: "middle", dominantBaseline: "middle", fontSize: "4", fontWeight: "bold", children: planet.symbol }), texts.map((text, i) => (_jsxs("g", { children: [_jsx("path", { id: `${idPrefix}-path-${index}-l${i}`, d: `M ${textPaths[i][0].x} ${textPaths[i][0].y} L ${textPaths[i][1].x} ${textPaths[i][1].y}`, fill: "none", stroke: "none" }), _jsx("text", { children: _jsx("textPath", { fontSize: "3", href: `#${idPrefix}-path-${index}-l${i}`, textAnchor: "middle", startOffset: "50%", children: texts[i] }) })] }, i)))] }));
146
+ }
147
+ /**
148
+ * The seven churches of Asia (Revelation 1:11) on Diagram 17's lamps, by
149
+ * planet, as the figure names them. magick-data has no table of them.
150
+ */
151
+ const CHURCHES = {
152
+ saturn: "Ephesus",
153
+ mars: "Pergamos",
154
+ venus: "Thyatira",
155
+ luna: "Laodicea",
156
+ jupiter: "Philadelphia",
157
+ sol: "Smyrna",
158
+ mercury: "Sardis",
159
+ };
160
+ /** Hebrew without its points, as the figure writes every name. */
161
+ const unpointed = (text) => text?.replace(/[\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7]/g, "");
162
+ /** "x y", each rounded as the package writes coordinates. */
163
+ const pair = (point) => `${svgCoordinate(point.x)} ${svgCoordinate(point.y)}`;
164
+ // Diagram 17's proportions in the 100 × 100 viewBox, kept within the
165
+ // modern drawing's outer circle (r 40), which the halls' disc fills.
166
+ /** The lamps' centres lie on this circle. */
167
+ const LAMP_RING = 29;
168
+ /** Each lamp's radius. */
169
+ const LAMP = 10.5;
170
+ /** The circle through the triangle's corners, inside its lamp. */
171
+ const TRIANGLE = LAMP - 0.8;
172
+ /** The star's points touch the lamps, as in the figure. */
173
+ const STAR = LAMP_RING - LAMP;
174
+ /** The central lamp, inside the star's innermost lines. */
175
+ const CENTRAL_LAMP = 3.4;
176
+ /** How far out along its arm each planet's symbol stands. */
177
+ const SYMBOL_AT = STAR * 0.55;
178
+ /** A lamp's direction from the centre: clockwise from the top. */
179
+ const lampAngle = (index) => (index * 360) / 7 - 90;
180
+ /**
181
+ * One lamp of Diagram 17, drawn as if it stood at the top and turned to
182
+ * its place, as the figure turns each lamp: the triangle with its apex
183
+ * outward, the double letter inside it, the planet's Hebrew name along
184
+ * its left side and the archangel of the planet's Sephirah along its
185
+ * right, and the church's name under its base.
186
+ *
187
+ * Where the figure departs from Regardie's text of 1938 (vol. 2, p. 62),
188
+ * which puts the archangel on the triangle's right, the sphere's name on
189
+ * its left and the letter beneath the base, this follows the figure: the
190
+ * letter is inside, and the church's name beneath. The figure's Mars lamp
191
+ * has its two names the other way about, alone of the seven; it is drawn
192
+ * here as the other six and the text have them. The names are
193
+ * magick-data's, without points; where its spelling differs from the
194
+ * figure's (נגה for נוגה, חמאל for כמאל, הניאל for האניאל) it is kept.
195
+ */
196
+ function Lamp1909({ index, idPrefix }) {
197
+ const planetId = CANDLESTICK_PLANETS.equinox1909[index];
198
+ const planet = data.planet[planetId];
199
+ const sephirah = Object.values(data.sephirah).find((row) => row.planetId === planetId);
200
+ const center = degreesToPointOnCircle(lampAngle(index), LAMP_RING);
201
+ // Corners and text lines, before the turn: up is away from the centre.
202
+ const corner = (degrees, radius = TRIANGLE) => degreesToPointOnCircle(degrees, radius, center);
203
+ const apex = corner(270);
204
+ const left = corner(150);
205
+ const right = corner(30);
206
+ const along = TRIANGLE + 1.6;
207
+ const sides = [
208
+ // The sphere's name, read up the left side; the archangel's, down
209
+ // the right; each outside its side.
210
+ [unpointed(planet.name.he?.he), corner(150, along), corner(270, along)],
211
+ [
212
+ unpointed(sephirah?.archangel?.name.he),
213
+ corner(270, along),
214
+ corner(30, along),
215
+ ],
216
+ ];
217
+ const x = svgCoordinate(center.x);
218
+ const y = svgCoordinate(center.y);
219
+ return (_jsxs("g", { transform: `rotate(${svgCoordinate((index * 360) / 7)} ${x} ${y})`, children: [_jsx("circle", { cx: x, cy: y, r: LAMP, fill: "none", stroke: "black", strokeWidth: "0.5" }), _jsx("path", { d: `M ${pair(apex)} L ${pair(left)} L ${pair(right)} Z`, fill: "none", stroke: "black", strokeWidth: "0.5" }), _jsx("text", { x: x, y: y, textAnchor: "middle", dominantBaseline: "middle", fontSize: "5", fontWeight: "bold", children: planet.hebrewLetter?.letter?.he }), sides.map(([text, from, to], side) => (_jsxs("g", { children: [_jsx("path", { id: `${idPrefix}-path-${index}-l${side}`, d: `M ${pair(from)} L ${pair(to)}`, fill: "none", stroke: "none" }), _jsx("text", { children: _jsx("textPath", { fontSize: "3", href: `#${idPrefix}-path-${index}-l${side}`, textAnchor: "middle", startOffset: "50%", children: text }) })] }, from.x))), _jsx("text", { x: x, y: svgCoordinate(center.y + TRIANGLE / 2 + 2.6), textAnchor: "middle", fontSize: "2.3", children: CHURCHES[planetId] })] }));
220
+ }
221
+ /**
222
+ * Diagram 17 of *The Equinox* I(2) (1909): seven lamps about a central
223
+ * one, joined by a heptagram whose lines run through the planets in the
224
+ * Chaldean order, each planet's symbol on its arm.
225
+ */
226
+ function Equinox1909({ idPrefix, ref, }) {
227
+ // The star from Saturn, three lamps on each time: Saturn, Jupiter,
228
+ // Mars, the Sun, Venus, Mercury, the Moon, and back.
229
+ const star = [0, 4, 1, 5, 2, 6, 3]
230
+ .map((i) => pair(degreesToPointOnCircle(lampAngle(i), STAR)))
231
+ .join(" L ");
232
+ return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", version: "1.1", viewBox: "-50 -50 100 100", ref: ref, children: [_jsx("path", { d: `M ${star} Z`, fill: "none", stroke: "black", strokeWidth: ".5" }), _jsx("circle", { cx: "0", cy: "0", r: CENTRAL_LAMP, fill: "none", stroke: "black", strokeWidth: ".5" }), CANDLESTICK_PLANETS.equinox1909.map((planetId, i) => {
233
+ const at = degreesToPointOnCircle(lampAngle(i), SYMBOL_AT);
234
+ return (_jsx("text", { x: svgCoordinate(at.x), y: svgCoordinate(at.y), textAnchor: "middle", dominantBaseline: "middle", fontSize: "3.5", children: data.planet[planetId].symbol }, planetId));
235
+ }), CANDLESTICK_PLANETS.equinox1909.map((planetId, i) => (_jsx(Lamp1909, { index: i, idPrefix: idPrefix }, planetId)))] }));
236
+ }
237
+ /**
238
+ * The Golden Dawn's seven-branched candlestick, in a version (`version`):
239
+ * by default the figure of *The Equinox* I(2) (1909), seven lamps about a
240
+ * central one, each with its double letter, the planet's Hebrew name, the
241
+ * archangel of its Sephirah and one of the seven churches, joined by a
242
+ * heptagram in the Chaldean order; or the modern arrangement, a branch
243
+ * for each planet with its symbol, Hebrew name, planetary angel and
244
+ * letter, set about a heptagram.
245
+ */
246
+ export function SevenBranchedCandlestick({ version, idPrefix = "candlestick", ref, }) {
247
+ return versionOf(version) === "modern" ? (_jsx(Modern, { idPrefix: idPrefix, ref: ref })) : (_jsx(Equinox1909, { idPrefix: idPrefix, ref: ref }));
248
+ }
249
+ /**
250
+ * The modern arrangement, as this package drew it before the versions:
251
+ * its markup is unchanged.
252
+ */
253
+ function Modern({ idPrefix, ref, }) {
254
+ const indexes = [0, 1, 2, 3, 4, 5, 6];
255
+ return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", version: "1.1", viewBox: "-50 -50 100 100", ref: ref, children: [_jsx("circle", { cx: "0", cy: "0", r: "40", fill: "none", stroke: "black", strokeWidth: ".5" }), _jsx("circle", { cx: "0", cy: "0", r: "25", fill: "none", stroke: "black", strokeWidth: ".5" }), (function () {
256
+ // Start from bottom left corner, to top, etc.
257
+ const orderedIndexes = [4, 0, 3, 6, 2, 5, 1, 4];
258
+ const d = "M " +
259
+ orderedIndexes
260
+ .concat([0])
261
+ .map((i) => {
262
+ const p = degreesToPointOnCircle((i * 360) / indexes.length - 90, 25);
263
+ return `${p.x} ${p.y}`;
264
+ })
265
+ .join(" L ");
266
+ return _jsx("path", { d: d, fill: "none", stroke: "black", strokeWidth: ".5" });
267
+ })(), indexes.map((i) => (_jsx(Branch, { index: i, idPrefix: idPrefix }, i)))] }));
268
+ }
269
+ export default SevenBranchedCandlestick;
@@ -0,0 +1,19 @@
1
+ import React from "react";
2
+ /** Props of the diagram. */
3
+ export interface TableOfShewbreadProps {
4
+ /**
5
+ * Prefixes the text paths' ids, which are document-wide: two of these
6
+ * on one page need different prefixes. No hook makes one, so that the
7
+ * component also renders where React's hooks are not available.
8
+ */
9
+ idPrefix?: string;
10
+ /** The `<svg>`, for exporting the drawing. */
11
+ ref?: React.Ref<SVGSVGElement>;
12
+ }
13
+ /**
14
+ * The Golden Dawn's Table of Shewbread: the twelve signs of the zodiac on a
15
+ * circle, with the permutations of the Tetragrammaton and the tribes of
16
+ * Israel the signs are given.
17
+ */
18
+ export declare function TableOfShewbread({ idPrefix, ref, }: TableOfShewbreadProps): React.JSX.Element;
19
+ export default TableOfShewbread;
@@ -0,0 +1,120 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { assemble } from "magick-data/assemble";
3
+ import zodiacRows from "magick-data/astrology/zodiac";
4
+ import archangels from "magick-data/kabbalah/archangels";
5
+ import tribeRows from "magick-data/kabbalah/tribesOfIsrael";
6
+ /**
7
+ * Two tables, joined: the table draws each sign's tribe, and used to index
8
+ * the tribes with `tribesOfIsrael[zodiac.tribeOfIsraelId]` by hand, which is
9
+ * the join `tribeOfIsraelId` has declared in the graph since step 2. Scoped
10
+ * rather than the barrel on purpose — the barrel would put all 23 of its
11
+ * tables in this route's chunk, and this needs two, and the archangels'
12
+ * names.
13
+ */
14
+ const { zodiac } = assemble({
15
+ zodiac: zodiacRows,
16
+ tribeOfIsrael: tribeRows,
17
+ });
18
+ const zodiacArray = Object.values(zodiac);
19
+ function degreesToPointOnCircle(degrees, radius, center = { x: 0, y: 0 }) {
20
+ const radians = (degrees * Math.PI) / 180;
21
+ // console.log(degrees, radians);
22
+ return {
23
+ x: radius * Math.cos(radians) + center.x,
24
+ y: radius * Math.sin(radians) + center.y,
25
+ };
26
+ }
27
+ const yhvH = {
28
+ y: "י",
29
+ h: "ה",
30
+ v: "ו",
31
+ H: "הּ",
32
+ };
33
+ const transToHeb = (str) => str
34
+ .split("")
35
+ .map((c) => yhvH[c] || c)
36
+ .join("");
37
+ function Branch({ zodiac, index, idPrefix, }) {
38
+ const numBranches = 12;
39
+ const radius = 8; // TODO, work it out properly
40
+ const center = degreesToPointOnCircle((-index * 360) / numBranches - 90, 23.7 + radius);
41
+ const texts = [
42
+ transToHeb(zodiac.tetragrammatonPermutation),
43
+ "הוזחטילנסעצק"[index],
44
+ zodiac.tribeOfIsrael?.name.he,
45
+ // planet.archangel?.name.he,
46
+ // planet.hebrewLetter?.letter?.he,
47
+ // planet.name.he.he,
48
+ ];
49
+ // With extend radius so text is offset from the side of the triangle
50
+ const textPaths = [
51
+ [
52
+ degreesToPointOnCircle(90, radius + 1, center),
53
+ degreesToPointOnCircle(90 + 360 / 3, radius + 1, center),
54
+ ],
55
+ [
56
+ // Extend the radius even further so text path (which is on the
57
+ // bottom side of the text) still fits the top of the text below
58
+ // the triangle.
59
+ degreesToPointOnCircle(90 + (360 / 3) * 2, radius + 4.5, center),
60
+ degreesToPointOnCircle(90 + 360 / 3, radius + 4.5, center),
61
+ ],
62
+ [
63
+ degreesToPointOnCircle(90 + (360 / 3) * 2, radius + 1, center),
64
+ degreesToPointOnCircle(90, radius + 1, center),
65
+ ],
66
+ ];
67
+ const bottom = degreesToPointOnCircle(90, radius - 0.4, center);
68
+ const topLeft = degreesToPointOnCircle(90 + 360 / 3, radius - 0.4, center);
69
+ const topRight = degreesToPointOnCircle(90 + (360 / 3) * 2, radius - 0.4, center);
70
+ const rotation = (360 / numBranches) * -index;
71
+ return (_jsxs("g", { transform: `rotate(${rotation} ${center.x} ${center.y})`, children: [_jsx("circle", { cx: center.x, cy: center.y, r: radius, fill: "none", stroke: "black", strokeWidth: "0.35" }), _jsx("path", { d: `M ${bottom.x} ${bottom.y} L ${topLeft.x} ${topLeft.y} L ${topRight.x} ${topRight.y} L ${bottom.x} ${bottom.y}`, fill: "none", stroke: "black", strokeWidth: "0.35" }), _jsx("text", { x: center.x, y: center.y, transform: `rotate(180 ${center.x} ${center.y})`, textAnchor: "middle", dominantBaseline: "middle", fontSize: "4", fontWeight: "bold", children: zodiac.symbol }), texts.map((text, i) => (_jsxs("g", { children: [_jsx("path", { id: `${idPrefix}-path-${index}-l${i}`, d: `M ${textPaths[i][0].x} ${textPaths[i][0].y} L ${textPaths[i][1].x} ${textPaths[i][1].y}`, fill: "none", stroke: "none" }), _jsx("text", { children: _jsx("textPath", { fontSize: "3", href: `#${idPrefix}-path-${index}-l${i}`, textAnchor: "middle", startOffset: "50%", children: texts[i] }) })] }, i)))] }, index));
72
+ }
73
+ /**
74
+ * The archangels of the quarters, each with the Kerub of its element: their
75
+ * names in Hebrew, as the figure's other labels are, from magick-data.
76
+ */
77
+ const innerCircleData = [
78
+ { angelId: "raphael", kerub: "אדם", symbol: "👨" },
79
+ { angelId: "michael", kerub: "אריה", symbol: "🦁" },
80
+ { angelId: "gabriel", kerub: "נשר", symbol: "🦅" },
81
+ { angelId: "uriel", kerub: "שור", symbol: "🐂" },
82
+ ].map((circle) => ({
83
+ ...circle,
84
+ angelName: archangels[circle.angelId].name.he,
85
+ }));
86
+ const innerRadius = 23.5;
87
+ const pentagramRadius = innerRadius * 0.45;
88
+ const innerCircleRadius = (innerRadius - pentagramRadius) / 2;
89
+ // We use this center point since Raphael's circle is not rotated when
90
+ // looking at the table. We then rely on transform-rotate to place the
91
+ // remaining inner circles and present contents at correct angles.
92
+ const raphaelCircleCenter = degreesToPointOnCircle(90, innerRadius - innerCircleRadius);
93
+ const innerCircles = innerCircleData.map((data, index) => ({
94
+ ...data,
95
+ radius: innerCircleRadius,
96
+ center: degreesToPointOnCircle((270 + 90 * index) % 360, innerRadius - innerCircleRadius),
97
+ }));
98
+ function TextOnCircle({ text, pathKey = text, center, radius, position, offset = 0, idPrefix, }) {
99
+ const fontSize = 2.5;
100
+ const textPathId = `${idPrefix}-text-path-${pathKey}-${position}`;
101
+ radius -= offset;
102
+ return (_jsxs("g", { children: [_jsx("path", { id: textPathId, d: `M ${center.x - radius} ${center.y} A ${radius} ${radius} 0 1 ${position === "inner-top" ? 1 : 0} ${center.x + radius} ${center.y}`, fill: "none", stroke: "none" }), _jsx("text", { children: _jsx("textPath", { href: `#${textPathId}`, textAnchor: "middle", dominantBaseline: position === "inner-top" ? "text-before-edge" : "text-after-edge", startOffset: "50%", fontSize: fontSize, children: text }) })] }));
103
+ }
104
+ /**
105
+ * The Golden Dawn's Table of Shewbread: the twelve signs of the zodiac on a
106
+ * circle, with the permutations of the Tetragrammaton and the tribes of
107
+ * Israel the signs are given.
108
+ */
109
+ export function TableOfShewbread({ idPrefix = "shewbread", ref, }) {
110
+ const innerTriangles = [0, 30, 60, 90].map((offset) => [
111
+ degreesToPointOnCircle(30 + offset, innerRadius),
112
+ degreesToPointOnCircle(150 + offset, innerRadius),
113
+ degreesToPointOnCircle(270 + offset, innerRadius),
114
+ ]);
115
+ // degrees = 360 / 5 = 72;
116
+ // offset = 270 (top point of cirlce) - 288 (degrees at index 4) = -18
117
+ const pentagramPoints = [3, 0, 2, 4, 1].map((index) => degreesToPointOnCircle(index * 72 - 18, pentagramRadius));
118
+ return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", version: "1.1", viewBox: "-50 -50 100 100", ref: ref, children: [_jsx("circle", { cx: "0", cy: "0", r: "40", fill: "none", stroke: "black", strokeWidth: ".35" }), _jsx("circle", { cx: "0", cy: "0", r: innerRadius, fill: "none", stroke: "black", strokeWidth: ".35" }), _jsx("g", { children: innerTriangles.map((triangle, i) => (_jsx("path", { d: `M ${triangle[0].x} ${triangle[0].y} L ${triangle[1].x} ${triangle[1].y} L ${triangle[2].x} ${triangle[2].y} Z`, fill: "none", stroke: "black", strokeWidth: ".35" }, i))) }), _jsx("path", { d: `M ${pentagramPoints.map((p) => `${p.x} ${p.y}`).join(" L ")} Z`, fill: "none", stroke: "black", strokeWidth: ".35" }), zodiacArray.map((zodiac, i) => (_jsx(Branch, { zodiac: zodiac, index: i, idPrefix: idPrefix }, i))), _jsx("g", { children: innerCircles.map((circle, i) => (_jsxs("g", { transform: `rotate(${180 + 90 * i}, 0, 0)`, children: [_jsx("circle", { cx: raphaelCircleCenter.x, cy: raphaelCircleCenter.y, r: circle.radius, fill: "white", stroke: "black", strokeWidth: ".35" }), _jsx(TextOnCircle, { text: circle.angelName, pathKey: circle.angelId, center: raphaelCircleCenter, radius: circle.radius, position: "inner-top", idPrefix: idPrefix }), _jsx("text", { x: raphaelCircleCenter.x, y: raphaelCircleCenter.y, textAnchor: "middle", dominantBaseline: "central", fontSize: 5, children: circle.symbol }), _jsx(TextOnCircle, { text: circle.kerub, center: raphaelCircleCenter, radius: circle.radius, position: "inner-bottom", idPrefix: idPrefix })] }, i))) })] }));
119
+ }
120
+ export default TableOfShewbread;
@@ -0,0 +1,94 @@
1
+ import { type CSSProperties, type Ref } from "react";
2
+ import { type HallResolvedObject, type ResolvedHall } from "./layout.ts";
3
+ import type { HallArt, HallArtRegistry, HallNode } from "./types.ts";
4
+ /** Props of `GdHall`. */
5
+ export interface GdHallProps {
6
+ /** The compiled `gdHall` node; anything else draws an empty hall. */
7
+ hall: HallNode;
8
+ /**
9
+ * The art for each kind of object; the package's own when not given. A
10
+ * registry of your own can add kinds or draw them differently.
11
+ */
12
+ art?: HallArtRegistry;
13
+ /**
14
+ * Where the hall's WOFF2 subsets are served (such as `/fonts`). When set,
15
+ * the SVG carries its own `@font-face` rules; otherwise the page must.
16
+ */
17
+ fontBaseUrl?: string;
18
+ /** The `<svg>`'s class. */
19
+ className?: string;
20
+ /** The `<svg>`'s style. */
21
+ style?: CSSProperties;
22
+ /** The SVG's width; from the height and the hall's shape when not given. */
23
+ width?: number | string;
24
+ /** The SVG's height; from the width and the hall's shape when not given. */
25
+ height?: number | string;
26
+ /** The drawn `<svg>`, for exporting it. */
27
+ ref?: Ref<SVGSVGElement>;
28
+ }
29
+ /**
30
+ * One drawing in the hall's `<defs>`: the first object drawn with it, and
31
+ * its art (none for the placeholder).
32
+ */
33
+ export interface HallArtDefinition {
34
+ id: string;
35
+ object: HallResolvedObject;
36
+ art?: HallArt;
37
+ }
38
+ /** The drawings of a hall, as `GdHall` memoises them. */
39
+ export interface HallDrawings {
40
+ definitions: readonly HallArtDefinition[];
41
+ uses: ReadonlyMap<HallResolvedObject, string>;
42
+ }
43
+ /**
44
+ * The hall a node draws: itself when it is a `gdHall`, an empty hall for
45
+ * anything else.
46
+ */
47
+ export declare function hallRoot(hall: HallNode): HallNode;
48
+ /** Props of `GdHallSvg`: a resolved hall, drawn without hooks. */
49
+ export interface GdHallSvgProps {
50
+ /** The hall as `resolveHall` resolved it with `art`. */
51
+ resolved: ResolvedHall;
52
+ /** The art `resolved` was resolved with. */
53
+ art: HallArtRegistry;
54
+ /**
55
+ * Prefixes the pattern, gradient and drawing ids, which must be unique
56
+ * in the document: `useId`'s in `GdHall`, a fixed name in an image.
57
+ */
58
+ idPrefix: string;
59
+ /** The drawings, when the caller memoises them; computed otherwise. */
60
+ drawings?: HallDrawings;
61
+ /** `@font-face` rules carried inside the SVG, if any. */
62
+ fontCss?: string;
63
+ /**
64
+ * Draw for a server-side image renderer: the viewBox rounded
65
+ * outward to whole units, which resvg writes back unchanged, and no
66
+ * `<title>`, `role` or `aria-labelledby`, since outlining drops the
67
+ * title an accessible name would point at.
68
+ */
69
+ image?: boolean;
70
+ className?: string;
71
+ style?: CSSProperties;
72
+ width?: number | string;
73
+ height?: number | string;
74
+ ref?: Ref<SVGSVGElement>;
75
+ }
76
+ /** A resolved viewBox in SVG units, as `GdHallSvg` writes it. */
77
+ export declare function hallViewBox(resolved: ResolvedHall, image?: boolean): [number, number, number, number];
78
+ /**
79
+ * The drawing of a resolved hall, without hooks, so a server-side renderer
80
+ * with no hook dispatcher can render it. `GdHall` draws through it.
81
+ */
82
+ export declare function GdHallSvg({ resolved, art, idPrefix: id, drawings, fontCss, image, className, style, width, height, ref, }: GdHallSvgProps): import("react").JSX.Element;
83
+ /**
84
+ * A Golden Dawn temple hall as inline SVG, drawn from a `gdHall` node such
85
+ * as a preset's (`magick-components/gd/hall/presets`). It renders on the
86
+ * server as well as in the browser: its layout is computed from the node,
87
+ * its labels' widths from the metrics of the fonts the package ships, and
88
+ * its gradient and pattern ids from `useId`, so several halls can share a
89
+ * page. The node is treated as untrusted: its strings only reach text
90
+ * nodes, unknown tags draw as dashed placeholders, and nothing is loaded
91
+ * by URL except the fonts `fontBaseUrl` points at.
92
+ */
93
+ export declare function GdHall({ hall, art, fontBaseUrl, className, style, width, height, ref, }: GdHallProps): import("react").JSX.Element;
94
+ export default GdHall;