caelus 0.21.0 → 0.23.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.
@@ -0,0 +1 @@
1
+ { "provenance": "Constellation figures from d3-celestial (github.com/ofrohn/d3-celestial, BSD-3), IAU modern sky culture; vertices as ecliptic J2000 (lon, lat) degrees", "lines": [{ "con": "And", "segs": [[[44.225396, 27.806206], [30.405239, 25.943405], [21.813496, 24.350762], [14.308444, 25.68042]], [[22.376026, 15.930211], [20.579947, 17.620271], [20.924311, 23.022254], [21.813496, 24.350762], [22.679297, 27.148854], [16.084797, 41.029168], [7.779489, 43.750244]], [[16.084797, 41.029168], [17.298492, 41.717969], [18.286962, 43.775919]], [[30.405239, 25.943405], [29.175267, 29.658707], [29.149286, 32.562159], [36.421723, 36.369608], [42.439948, 35.414919]], [[17.298492, 41.717969], [19.94087, 42.948328]]] }, { "con": "Ant", "segs": [[[161.002945, -47.35093], [172.440721, -37.427573], [183.041394, -39.819083]]] }, { "con": "Aps", "segs": [[[254.429923, -58.234891], [261.510046, -55.992697], [262.949557, -54.549312], [262.703522, -56.007049]]] }, { "con": "Aqr", "segs": [[[311.723217, 8.080513], [313.058119, 8.24], [323.395044, 8.614997], [333.352466, 10.661524], [336.714083, 8.235183], [338.909679, 8.845663], [340.403129, 8.146869], [341.576098, -0.386618], [346.729534, -4.283348], [340.017803, -14.490231]], [[323.395044, 8.614997], [328.719942, -2.081028]], [[333.352466, 10.661524], [333.263489, 2.706843]], [[338.909679, 8.845663], [338.598096, 10.472937]], [[343.456761, -14.786492], [346.729534, -4.283348], [348.612731, -14.514182]]] }, { "con": "Aql", "segs": [[[300.938937, 31.24362], [301.77638, 29.303447], [302.423647, 26.659197], [304.913509, 18.727705], [300.433731, 21.523319], [293.637743, 24.817088], [289.795972, 36.185746], [301.77638, 29.303447], [293.637743, 24.817088], [287.332289, 17.565703]]] }, { "con": "Ara", "segs": [[[264.293241, -33.109666], [265.556654, -37.355907], [258.904284, -36.276392], [259.8239, -33.0916], [259.578436, -30.266167], [264.93426, -26.560525], [264.205868, -32.264958]]] }, { "con": "Ari", "segs": [[[48.203557, 10.449678], [37.662513, 9.96508], [33.969961, 8.487233], [33.18464, 7.162419]]] }, { "con": "Aur", "segs": [[[89.910386, 21.508146], [81.857899, 22.864276], [79.446175, 18.283842], [76.639446, 10.454495], [82.574965, 5.385154], [89.942848, 13.773323], [89.910386, 21.508146], [89.919632, 30.845442], [81.857899, 22.864276], [78.841396, 20.944377], [78.63337, 18.202268]]] }, { "con": "Boo", "segs": [[[197.931826, 26.513879], [199.336641, 28.077114], [204.233619, 30.736225], [202.785991, 42.45176], [197.66342, 49.551623], [204.250562, 54.151024], [213.157512, 48.965547], [208.106285, 40.624846], [204.233619, 30.736225], [213.037569, 27.878487]], [[197.66342, 49.551623], [186.96327, 54.648155], [179.954396, 58.894321], [182.610482, 60.108809], [186.96327, 54.648155]]] }, { "con": "Cae", "segs": [[[49.983179, -65.325538], [56.148072, -62.9882], [59.381328, -58.529932], [68.412723, -57.885262]]] }, { "con": "Cam", "segs": [[[79.268517, 30.895333], [81.267779, 37.430989], [80.979574, 43.418929], [74.645629, 49.616648], [71.873294, 44.126709], [66.581163, 39.531689]], [[80.979574, 43.418929], [92.389815, 45.919592], [95.677952, 53.834258]]] }, { "con": "Cnc", "segs": [[[133.641682, -5.080429], [128.721949, 0.077143], [127.538403, 3.190483], [126.338139, 10.429703]], [[128.721949, 0.077143], [124.257295, -10.287647]]] }, { "con": "CVn", "segs": [[[174.564549, 40.116038], [167.705818, 40.543935]]] }, { "con": "CMa", "segs": [[[97.187895, -41.253699], [104.081718, -39.605228], [111.002749, -46.130379], [113.39609, -48.453195], [111.556099, -50.225809], [110.762945, -51.360221], [97.377594, -53.372714]], [[119.536535, -50.608742], [113.39609, -48.453195]], [[104.081718, -39.605228], [107.522433, -39.64362], [109.607928, -37.993817], [106.184305, -34.719859], [107.522433, -39.64362]]] }, { "con": "CMi", "segs": [[[115.785537, -16.019607], [112.191736, -13.487231]]] }, { "con": "Cap", "segs": [[[303.769675, 6.988354], [304.047391, 4.588644], [305.165358, 1.198238], [307.158972, -7.028594], [307.95949, -8.962684], [316.936923, -6.990911], [323.542563, -2.601688], [321.790757, -2.557264], [317.682236, -1.366773], [313.843893, -0.585957], [303.769675, 6.988354]]] }, { "con": "Car", "segs": [[[107.147917, -66.074154], [104.96066, -75.823917], [211.968839, -72.236004], [217.439567, -67.382371], [209.18951, -62.139038], [203.058152, -61.446292], [200.075591, -62.604949], [185.326212, -67.116338], [173.129245, -72.679903], [150.729153, -70.326712], [147.349569, -64.46419], [168.947786, -67.197784], [185.326212, -67.116338]], [[209.18951, -62.139038], [209.461155, -58.850331], [209.083724, -58.355714], [207.499947, -56.88148], [205.127657, -56.28762], [202.437291, -57.574743], [203.058152, -61.446292]]] }, { "con": "Cas", "segs": [[[54.763694, 47.548207], [47.930016, 46.40348], [43.931099, 48.814868], [37.783633, 46.622152], [35.116654, 51.214996]]] }, { "con": "Cen", "segs": [[[202.196483, -51.810726], [207.482367, -44.509664], [210.725507, -42.387841], [212.317133, -40.162431], [225.554804, -39.586001], [224.950594, -32.943388], [221.536168, -28.979207], [221.154277, -28.267972], [222.308531, -22.079948], [230.248891, -25.512952], [234.794752, -24.031366]], [[221.154277, -28.267972], [213.128812, -26.016246]], [[239.477601, -42.598441], [225.554804, -39.586001], [233.792252, -44.137617]], [[210.725507, -42.387841], [209.392171, -45.582657], [209.478722, -54.578223]]] }, { "con": "Cep", "segs": [[[4.854295, 73.932934], [4.677447, 71.779774], [12.778181, 68.913701], [9.707011, 64.19433], [13.048986, 59.942332], [13.962915, 61.147181], [17.609191, 59.541371], [33.240657, 62.616013], [60.092956, 64.669813], [35.54625, 71.152764], [12.778181, 68.913701]], [[35.54625, 71.152764], [33.240657, 62.616013]]] }, { "con": "Cet", "segs": [[[39.432944, -11.996153], [38.387438, -9.180581], [37.469931, -5.855563], [41.94153, -5.566724], [45.09328, -7.785924], [44.320143, -12.585617], [39.432944, -11.996153], [37.5714, -14.46174], [31.521947, -15.936852], [21.950075, -20.334507], [17.818584, -24.815871], [2.583529, -20.783545], [0.916126, -10.02168], [11.767506, -16.118431], [16.226183, -15.767342], [21.950075, -20.334507]]] }, { "con": "Cha", "segs": [[[239.299096, -75.40938], [240.421398, -68.084161], [245.46596, -67.806728], [245.437916, -63.594165], [242.318128, -63.935104], [240.421398, -68.084161]]] }, { "con": "Cir", "segs": [[[244.307149, -38.931597], [242.362609, -46.202531], [245.443556, -39.174799]]] }, { "con": "Col", "segs": [[[98.423586, -56.714145], [86.419531, -59.179505], [82.169154, -57.375169], [78.697681, -58.627752]], [[86.419531, -59.179505], [89.611436, -66.254103]]] }, { "con": "Com", "segs": [[[188.949994, 22.978241], [184.365469, 32.512113], [173.89006, 28.398781]]] }, { "con": "CrA", "segs": [[[282.037819, -14.279594], [283.617229, -14.405765], [284.13487, -15.313602], [284.061789, -16.752299], [283.577092, -17.8594], [282.346851, -19.329747], [279.573842, -20.40591], [276.544061, -19.063292]]] }, { "con": "CrB", "segs": [[[219.450329, 48.552103], [219.116742, 46.054059], [222.295841, 44.323557], [224.873355, 44.506958], [227.026715, 44.76451], [229.117935, 46.068669], [229.012634, 49.159596]]] }, { "con": "Crv", "segs": [[[192.2445, -21.749241], [191.66541, -19.673567], [190.725579, -14.500893], [193.451754, -12.196252], [197.367935, -18.044661], [191.66541, -19.673567]]] }, { "con": "Crt", "segs": [[[178.591341, -11.303772], [176.247517, -13.470002], [176.686942, -17.572448], [173.689444, -22.716361], [178.554588, -25.637789], [179.374553, -20.812675], [179.23403, -19.666545], [184.069525, -18.296589], [186.097572, -16.09084]], [[176.686942, -17.572448], [179.23403, -19.666545]]] }, { "con": "Cru", "segs": [[[221.646077, -48.638796], [215.664761, -50.419482]], [[221.869947, -52.878857], [216.739633, -47.831187]]] }, { "con": "Cyg", "segs": [[[333.041397, 43.694676], [327.745594, 49.422312], [324.841537, 57.124425], [316.249535, 64.414051], [317.968653, 71.451061], [314.918348, 73.802304]], [[335.329209, 59.906109], [324.841537, 57.124425], [312.927906, 54.27451], [301.2516, 48.967736]]] }, { "con": "Del", "segs": [[[314.061018, 29.073194], [316.341397, 31.917952], [317.380558, 33.022366], [319.365563, 32.702938], [318.116246, 31.943672], [316.341397, 31.917952]]] }, { "con": "Dor", "segs": [[[36.545451, -70.141523], [37.829462, -74.581775], [52.122494, -85.044187], [26.444412, -88.253795], [79.085443, -86.472905], [52.122494, -85.044187], [48.684786, -78.940996], [37.829462, -74.581775]]] }, { "con": "Dra", "segs": [[[264.755367, 80.282433], [267.968619, 74.922208], [251.966455, 75.27782], [250.401225, 78.13991], [264.755367, 80.282433], [17.161376, 82.886258], [71.089724, 84.876511], [183.380006, 84.761531], [194.487115, 78.441023], [196.665849, 74.436765], [184.949636, 71.093569], [157.456094, 66.362128], [136.25655, 61.762197], [130.333668, 57.241179]], [[71.089724, 84.876511], [75.930471, 83.567981]], [[17.161376, 82.886258], [32.694157, 79.490269]]] }, { "con": "Equ", "segs": [[[323.117239, 20.121799], [324.444526, 24.732299], [323.42732, 25.182769]]] }, { "con": "Eri", "segs": [[[75.27586, -27.861725], [69.33684, -25.367858], [66.814895, -25.123608], [59.432695, -27.453423], [53.867556, -33.202129], [50.96527, -31.118456], [50.862072, -28.676382], [48.167767, -27.715807], [38.750005, -24.54669], [33.755766, -28.247872], [32.108288, -32.749352], [34.534573, -38.906079], [40.109896, -38.506441], [44.204992, -39.439846], [47.360761, -41.887849], [59.885311, -51.817182], [54.487146, -54.537588], [52.502823, -53.964776], [41.758137, -54.309654], [34.929488, -57.08542], [27.223479, -58.11178], [23.27228, -53.74019], [18.771605, -51.714369], [7.935527, -57.012626], [0.999811, -58.985619], [356.24729, -57.017419], [345.311193, -59.378168]]] }, { "con": "For", "segs": [[[34.612326, -44.690845], [26.234641, -45.856015], [16.34304, -38.921723]]] }, { "con": "Gem", "segs": [[[93.436168, -0.888137], [95.301879, -0.82011], [99.93877, 2.069942], [105.444321, 7.754486], [110.240142, 10.095761], [113.215677, 6.684196], [111.344321, 5.215964], [108.519266, -0.17842], [104.99022, -2.038836], [99.104562, -6.742517], [101.20925, -10.104204]], [[108.519266, -0.17842], [108.778792, -5.635199]]] }, { "con": "Gru", "segs": [[[321.933694, -41.985315], [320.729898, -39.787809], [322.327317, -35.432083], [321.567816, -31.614316], [315.906989, -32.91328], [322.327317, -35.432083]], [[321.602454, -31.347432], [319.998009, -28.342666], [318.939265, -25.969742], [317.4193, -23.05031]]] }, { "con": "Her", "segs": [[[239.2145, 40.007754], [241.091283, 42.702392], [241.459536, 53.109668], [238.787639, 60.289846], [233.242009, 63.161979], [224.384478, 65.829937], [221.632575, 63.778452], [218.239282, 60.299609]], [[241.459536, 53.109668], [248.327012, 53.248336]], [[238.787639, 60.289846], [252.067418, 59.550836]], [[268.477033, 60.684839], [255.373043, 60.125006], [252.067418, 59.550836], [248.327012, 53.248336], [254.76357, 47.685617], [265.224666, 51.103889], [269.19568, 52.685631], [272.696462, 52.184143]], [[256.15195, 37.286118], [241.091283, 42.702392]]] }, { "con": "Hor", "segs": [[[45.823972, -61.730828], [8.235223, -61.014214], [4.624746, -61.848028], [2.478454, -63.663651], [358.12008, -69.458965], [346.335998, -71.345804]]] }, { "con": "Hya", "segs": [[[132.344775, -11.104111], [132.909816, -11.551748], [132.303956, -14.250772], [131.209759, -14.601864], [130.304311, -12.392525], [132.344775, -11.104111], [134.575618, -10.969551], [140.288444, -13.052131], [147.641805, -14.277201], [147.279166, -22.382407], [155.691307, -26.077245], [159.366992, -22.013988], [165.03646, -24.671472], [170.366001, -21.797998], [187.988058, -31.59853], [193.447387, -31.469306], [207.018286, -13.742601], [218.623916, -13.049574], [228.481653, -11.097577]]] }, { "con": "Hyi", "segs": [[[300.971516, -64.784787], [310.472341, -76.756936], [331.913841, -71.216198], [329.176254, -69.801924], [329.028751, -67.112197], [342.117967, -64.242188]]] }, { "con": "Ind", "segs": [[[299.10418, -27.753643], [298.670467, -32.485221], [297.785631, -39.1571], [309.801982, -39.464493], [304.1981, -35.779454], [299.10418, -27.753643]]] }, { "con": "Lac", "segs": [[[8.63218, 55.564387], [8.143191, 53.290546], [5.225102, 51.408532], [2.250231, 51.30182], [1.439517, 47.53576], [4.619639, 47.503501], [5.225102, 51.408532], [5.873011, 53.322117], [8.63218, 55.564387]], [[1.439517, 47.53576], [354.928768, 46.295719], [354.008289, 44.394725]]] }, { "con": "Leo", "segs": [[[149.829172, 0.464844], [147.905066, 4.865732], [149.614997, 8.814859], [161.316604, 14.333571], [171.617505, 12.266909], [163.422992, 9.674327], [149.829172, 0.464844]], [[149.614997, 8.814859], [147.56551, 11.865073], [141.430001, 12.348906], [140.704847, 9.715425]]] }, { "con": "LMi", "segs": [[[141.009179, 22.099946], [145.405163, 22.235471], [150.876922, 24.931161], [144.539497, 25.065228], [141.009179, 22.099946], [133.820353, 20.74575]]] }, { "con": "Lep", "segs": [[[91.896376, -38.364462], [88.899997, -37.603559], [85.986354, -38.215867], [81.380619, -41.057826], [75.394286, -39.050039], [72.055652, -44.964579], [79.672348, -43.914494], [84.846072, -45.818224], [87.167259, -44.297059]], [[75.904033, -35.810205], [75.394286, -39.050039], [77.778542, -36.188316]]] }, { "con": "Lib", "segs": [[[230.687285, -7.644489], [225.082636, 0.33304], [229.371658, 8.495948], [235.138044, 4.38597], [238.609364, -8.507525], [239.350952, -10.020874]], [[225.082636, 0.33304], [235.138044, 4.38597]]] }, { "con": "Lup", "segs": [[[242.840528, -13.179687], [240.698019, -14.470387], [237.494121, -17.178306], [238.656818, -21.425856], [235.025529, -25.046172], [233.503764, -30.025866], [240.757536, -32.831477], [240.373559, -28.502644], [240.122294, -25.245126], [241.49797, -21.24403], [245.771431, -17.444662], [246.744396, -15.624107]], [[238.656818, -21.425856], [241.49797, -21.24403]]] }, { "con": "Lyn", "segs": [[[93.105141, 35.624576], [99.146363, 35.437304], [105.706471, 26.947482], [117.559556, 23.105372], [125.275218, 23.714338], [130.570691, 20.100608], [131.8425, 17.964065]]] }, { "con": "Lyr", "segs": [[[288.10743, 60.342717], [288.62099, 62.336646], [285.316334, 61.732879], [288.10743, 60.342717], [291.666439, 59.317198], [291.922331, 55.01301], [288.883744, 55.98418], [288.10743, 60.342717]]] }, { "con": "Men", "segs": [[[265.295028, -81.765828], [279.564511, -79.98439], [295.053015, -80.13917], [310.73899, -83.025497]]] }, { "con": "Mic", "segs": [[[305.625908, -15.445852], [302.213711, -25.146103], [309.529978, -24.007612], [311.934232, -15.652046], [308.431482, -14.665354], [305.625908, -15.445852]]] }, { "con": "Mon", "segs": [[[119.280934, -30.453503], [125.137465, -22.587156], [109.535753, -22.721884], [98.285724, -30.265406], [94.249162, -29.659327]], [[109.535753, -22.721884], [102.775715, -20.498005], [96.254872, -18.717468], [98.483532, -15.864373], [100.36615, -13.17561]]] }, { "con": "Mus", "segs": [[[220.991911, -58.506957], [226.559317, -57.035305], [230.374199, -56.556993], [230.153753, -55.242762], [236.190113, -56.775563], [234.018314, -58.870616], [230.374199, -56.556993]]] }, { "con": "Nor", "segs": [[[248.514021, -23.828015], [252.868009, -25.486177], [252.068225, -28.263357], [248.870429, -27.909862], [248.514021, -23.828015]]] }, { "con": "Oct", "segs": [[[259.026333, -62.331337], [288.020277, -62.650746], [289.688919, -57.779384], [259.026333, -62.331337]]] }, { "con": "Oph", "segs": [[[269.753145, 13.665483], [266.632569, 26.111217], [265.336692, 27.93973], [262.448594, 35.835172], [251.821506, 31.836153], [245.593849, 23.555889], [242.30211, 17.241222], [243.510083, 16.439701], [249.229148, 11.391314], [257.969553, 7.197806]], [[251.821506, 31.836153], [249.229148, 11.391314], [248.666345, 5.196437], [247.979247, 3.223677], [247.550404, 1.552988], [248.437358, -1.7575]], [[265.336692, 27.93973], [257.969553, 7.197806], [261.394832, -1.843472], [262.880694, -6.629183]]] }, { "con": "Ori", "segs": [[[91.85155, -8.658625], [88.680828, -3.156661], [90.921513, -3.297657], [92.931344, -9.200122], [90.604809, -13.79074], [88.754559, -16.026973], [80.946502, -16.816048], [73.594572, -12.366356]], [[73.538398, -20.851648], [72.490798, -20.00505], [72.1008, -16.771903], [71.924669, -15.38415], [72.367094, -13.483542], [73.594572, -12.366356], [74.343999, -9.064426], [76.535598, -7.389817], [77.794292, -7.310854]], [[76.82963, -31.122732], [80.157567, -25.533473], [82.362161, -23.553033], [80.946502, -16.816048], [83.706842, -13.369414], [88.754559, -16.026973], [84.681326, -25.293124], [86.398604, -33.070633]], [[84.681326, -25.293124], [83.463659, -24.506366], [82.362161, -23.553033]]] }, { "con": "Pav", "segs": [[[293.817463, -36.267634], [292.494207, -45.954645], [287.613235, -44.699458], [277.805125, -39.101555], [273.519064, -38.125524], [271.24625, -40.238588], [267.973452, -41.309698], [275.115632, -48.179816], [283.529621, -50.885939], [292.494207, -45.954645], [298.606513, -46.972022]]] }, { "con": "Peg", "segs": [[[349.549031, 40.982811], [355.713241, 35.108126], [359.374214, 31.140515], [14.308444, 25.68042], [9.156073, 12.599921], [353.485598, 19.406069], [347.947615, 18.404606], [346.151627, 17.679502], [336.833067, 16.340671], [331.884921, 22.099883]], [[353.485598, 19.406069], [359.374214, 31.140515], [354.385913, 29.386898], [353.055119, 28.796381], [344.408712, 34.255476], [338.934106, 36.638574]]] }, { "con": "Per", "segs": [[[61.14319, 12.184333], [63.123836, 11.333469], [64.97248, 14.943801], [65.67782, 19.11454], [63.823171, 22.153545], [64.802111, 27.301782], [63.745785, 27.970871], [62.080936, 30.125492], [60.021423, 34.530169], [58.701817, 37.481874], [57.911816, 34.371293], [59.270163, 30.632043], [57.691235, 26.082948], [56.167555, 22.428488], [56.361719, 20.969729], [54.910797, 20.574653], [53.903712, 21.730743], [54.533147, 22.983036], [56.167555, 22.428488]], [[69.751293, 28.886202], [70.794767, 26.706888], [69.497523, 26.235064], [64.802111, 27.301782]], [[59.270163, 30.632043], [54.667231, 31.616665], [44.593534, 36.85081]]] }, { "con": "Phe", "segs": [[[345.493763, -40.633067], [350.439132, -48.199494], [358.143519, -47.585012], [353.621984, -52.582607], [342.379115, -55.131762], [350.439132, -48.199494], [339.648073, -41.956017], [345.493763, -40.633067]]] }, { "con": "Pic", "segs": [[[144.115556, -83.039848], [82.181333, -79.536947], [82.543559, -74.423512]]] }, { "con": "Psc", "segs": [[[26.459314, 15.50323], [28.317541, 20.739036], [28.788068, 17.465546], [26.459314, 15.50323], [24.532356, 12.440644], [26.815965, 5.377632], [27.743171, -1.620295], [29.378724, -9.060833], [27.52102, -7.921562], [25.506552, -4.694145], [23.13525, -3.06397], [19.877597, -0.213402], [17.525363, 1.09376], [14.147348, 2.176588], [2.583558, 6.362944], [357.644719, 7.153955], [355.189064, 9.033253], [353.026082, 8.872101], [351.453212, 7.257126], [352.903479, 4.432518], [356.58811, 3.417539], [358.266717, 4.551828], [357.644719, 7.153955]], [[351.453212, 7.257126], [348.585357, 9.053049]]] }, { "con": "PsA", "segs": [[[331.328661, -17.273334], [333.860277, -21.135584], [332.195033, -23.64035], [331.327738, -23.64587], [327.181014, -21.365884], [322.115564, -20.083997], [317.250236, -18.342244], [318.607799, -16.553658], [322.115564, -20.083997], [331.328661, -17.273334]]] }, { "con": "Pup", "segs": [[[107.147917, -66.074154], [120.300777, -58.524942], [122.92272, -49.119216], [123.457963, -47.413912], [126.041727, -44.939463], [127.638441, -42.577239], [131.388845, -43.270099], [138.550689, -58.347714], [147.349569, -64.46419]], [[126.041727, -44.939463], [126.06405, -46.050777], [125.884833, -49.211756], [122.92272, -49.119216]]] }, { "con": "Pyx", "segs": [[[138.550689, -58.347714], [146.800835, -51.155773], [146.500501, -48.922902], [145.466785, -43.291322]]] }, { "con": "Ret", "segs": [[[7.505745, -78.040512], [19.607288, -76.317637], [7.054421, -75.909628], [351.395045, -76.088031], [7.505745, -78.040512]]] }, { "con": "Sge", "segs": [[[301.071421, 38.792288], [303.387169, 38.912872], [307.043635, 39.190167]], [[301.205916, 38.218107], [303.387169, 38.912872]]] }, { "con": "Sgr", "segs": [[[273.627743, -13.377887], [275.078547, -11.051781], [274.580865, -6.47223], [276.317119, -2.13562], [273.213528, 2.342116]], [[285.776021, -22.144683], [286.635811, -18.380118], [283.638379, -7.178902], [280.181334, -3.954025], [276.317119, -2.13562]], [[292.556539, -20.659152], [294.870039, -14.385697], [295.850707, -5.421918], [291.84732, -3.259413], [289.336222, -2.48904], [287.044403, -2.927945], [282.385367, -3.449499], [280.181334, -3.954025], [274.580865, -6.47223], [271.261406, -6.991167], [275.078547, -11.051781], [283.638379, -7.178902], [284.834237, -5.088828], [282.385367, -3.449499], [284.994093, 0.860011], [286.251838, 1.437086], [288.348605, 3.258621], [289.450094, 4.224023], [289.727868, 6.095937]], [[284.994093, 0.860011], [283.451131, 1.661194], [282.471602, 0.110091], [282.385367, -3.449499]]] }, { "con": "Sco", "segs": [[[242.939901, -5.475358], [242.571269, -1.986036], [243.190032, 1.007721]], [[242.571269, -1.986036], [247.799645, -4.037364], [249.762279, -4.569944], [251.456873, -6.120393], [255.335136, -11.738484], [256.155594, -15.423153], [257.237259, -19.643879], [260.74285, -20.183543], [265.599405, -19.645088], [267.522528, -16.714398], [266.469464, -15.644348], [264.585738, -13.78843]]] }, { "con": "Scl", "segs": [[[0.492749, -32.513168], [345.571829, -24.558925], [336.998255, -25.687714], [337.236076, -31.707935]]] }, { "con": "Sct", "segs": [[[279.016524, 14.920124], [282.380019, 18.185982], [280.75816, 13.992979], [277.146082, 8.692603], [279.016524, 14.920124]]] }, { "con": "Ser", "segs": [[[229.948473, 34.326652], [227.176785, 38.105013], [229.775903, 37.110662], [232.781339, 35.19571], [229.948473, 34.326652], [228.341761, 28.880518], [232.075183, 25.507989], [234.330978, 24.006685], [242.30211, 17.241222]]] }, { "con": "Ser", "segs": [[[257.969553, 7.197806], [264.546086, 7.934672], [269.753145, 13.665483], [270.790523, 15.256877], [275.679142, 20.435526], [285.755333, 26.877424]]] }, { "con": "Sex", "segs": [[[154.115948, -11.115449], [153.261874, -19.712357], [160.106636, -11.34572], [159.500033, -9.319891]]] }, { "con": "Tau", "segs": [[[84.784642, -2.195668], [69.789223, -5.467335], [67.961944, -5.838466], [65.805713, -5.732295], [66.870699, -3.96952], [68.465068, -2.567197], [82.574965, 5.385154]], [[65.805713, -5.732295], [60.634532, -7.959857], [51.911994, -8.798623], [59.919171, -14.4517]], [[51.911994, -8.798623], [51.163599, -9.334208], [51.952283, -18.436692]]] }, { "con": "Tel", "segs": [[[272.112707, -22.535695], [275.073558, -22.647902], [275.236576, -25.762245]]] }, { "con": "Tri", "segs": [[[36.860847, 16.800485], [42.352542, 20.580701], [43.518092, 18.948254], [36.860847, 16.800485]]] }, { "con": "TrA", "segs": [[[260.895853, -46.151345], [251.841241, -41.945931], [249.39342, -48.102834], [260.895853, -46.151345]]] }, { "con": "Tuc", "segs": [[[309.671356, -45.403767], [320.440055, -47.849949], [326.589899, -57.350985], [322.371421, -57.719574], [318.771954, -56.64963], [307.166748, -49.913687], [309.671356, -45.403767]]] }, { "con": "UMa", "segs": [[[151.064833, 51.656693], [135.197438, 49.680283], [139.434669, 45.132963], [150.476943, 47.14156], [151.064833, 51.656693], [158.933507, 54.318781], [165.700062, 56.378946], [176.933174, 54.388024]], [[150.476943, 47.14156], [153.660144, 41.543895], [156.653604, 26.162438], [157.342324, 24.726616]], [[153.660144, 41.543895], [148.813092, 35.537759], [141.234968, 28.998074]], [[148.813092, 35.537759], [139.5498, 29.885315]], [[135.197438, 49.680283], [120.822831, 45.168774], [112.995786, 40.243427], [126.267732, 42.652297], [139.434669, 45.132963]], [[139.434669, 45.132963], [129.348627, 38.261184], [127.264121, 34.89599], [122.799829, 29.57525]], [[123.93676, 28.979479], [127.264121, 34.89599]]] }, { "con": "UMi", "segs": [[[117.404412, 75.122054], [120.315479, 77.829697], [141.598221, 75.24111], [133.319488, 72.987608], [117.404412, 75.122054], [99.136368, 73.922873], [91.203145, 69.945147], [88.567576, 66.101457]]] }, { "con": "Vel", "segs": [[[168.947786, -67.197784], [178.892071, -63.721731], [185.946607, -59.950494], [190.515846, -51.087794], [176.995687, -48.25898], [164.738756, -51.163888], [161.187658, -55.870838], [147.349569, -64.46419]]] }, { "con": "Vir", "segs": [[[174.159191, 4.586331], [177.164139, 0.694225], [184.83213, 1.365282], [190.141489, 2.790278], [198.237312, 1.742899], [203.841307, -2.054488], [213.797139, 7.19953], [220.131183, 9.672068]], [[189.94027, 16.20503], [191.460902, 8.613476], [190.141489, 2.790278]], [[198.237312, 1.742899], [202.134192, 8.636595], [207.748715, 13.062523], [218.517236, 17.101181]]] }, { "con": "Vol", "segs": [[[200.593349, -72.201399], [195.171989, -75.585212], [204.167947, -77.779985], [199.42398, -82.477127], [219.858784, -82.616941], [204.167947, -77.779985], [200.593349, -72.201399]]] }, { "con": "Vul", "segs": [[[294.650487, 43.212704], [299.507611, 45.858324], [307.039732, 43.939402], [310.850041, 46.991295], [315.364641, 46.052244]]] }], "labels": [{ "name": "Andromeda", "con": "And", "lon": 20.955615, "lat": 38.455988 }, { "name": "Antlia", "con": "Ant", "lon": 174.735788, "lat": -42.080474 }, { "name": "Apus", "con": "Aps", "lon": 257.092353, "lat": -51.904863 }, { "name": "Aquarius", "con": "Aqr", "lon": 337.329617, "lat": 4.110466 }, { "name": "Aquila", "con": "Aql", "lon": 294.113395, "lat": 29.698226 }, { "name": "Ara", "con": "Ara", "lon": 262.041384, "lat": -32.891758 }, { "name": "Aries", "con": "Ari", "lon": 46.188307, "lat": 5.561323 }, { "name": "Auriga", "con": "Aur", "lon": 83.840012, "lat": 13.720946 }, { "name": "Bootes", "con": "Boo", "lon": 205.951338, "lat": 48.637135 }, { "name": "Caelum", "con": "Cae", "lon": 61.428577, "lat": -63.811664 }, { "name": "Camelopardalis", "con": "Cam", "lon": 87.199278, "lat": 48.619038 }, { "name": "Cancer", "con": "Cnc", "lon": 123.845871, "lat": 7.943384 }, { "name": "Canes Venatici", "con": "CVn", "lon": 169.562929, "lat": 43.330531 }, { "name": "Canis Maior", "con": "CMa", "lon": 100.336831, "lat": -49.170521 }, { "name": "Canis Minor", "con": "CMi", "lon": 110.35675, "lat": -17.071843 }, { "name": "Capricornus", "con": "Cap", "lon": 311.138601, "lat": -4.755563 }, { "name": "Carina", "con": "Car", "lon": 203.640954, "lat": -68.948777 }, { "name": "Cassiopeia", "con": "Cas", "lon": 25.897784, "lat": 51.230519 }, { "name": "Centaurus", "con": "Cen", "lon": 214.175793, "lat": -29.211191 }, { "name": "Cepheus", "con": "Cep", "lon": 41.035564, "lat": 66.4993 }, { "name": "Cetus", "con": "Cet", "lon": 24.633932, "lat": -15.607413 }, { "name": "Chamaeleon", "con": "Cha", "lon": 249.594205, "lat": -63.695553 }, { "name": "Circinus", "con": "Cir", "lon": 242.056423, "lat": -48.584367 }, { "name": "Columba", "con": "Col", "lon": 82.457261, "lat": -62.321517 }, { "name": "Coma Berenices", "con": "Com", "lon": 182.183846, "lat": 27.258429 }, { "name": "Corona Australis", "con": "CrA", "lon": 279.585003, "lat": -16.959154 }, { "name": "Corona Borealis", "con": "CrB", "lon": 225.608874, "lat": 50.697817 }, { "name": "Corvus", "con": "Crv", "lon": 193.39099, "lat": -15.489851 }, { "name": "Crater", "con": "Crt", "lon": 181.302013, "lat": -15.820165 }, { "name": "Crux", "con": "Cru", "lon": 224.70154, "lat": -50.040072 }, { "name": "Cygnus", "con": "Cyg", "lon": 337.36534, "lat": 64.915234 }, { "name": "Delphinus", "con": "Del", "lon": 313.155187, "lat": 23.787173 }, { "name": "Dorado", "con": "Dor", "lon": 18.159014, "lat": -83.817272 }, { "name": "Draco", "con": "Dra", "lon": 255.552625, "lat": 87.363775 }, { "name": "Equuleus", "con": "Equ", "lon": 326.66303, "lat": 25.605003 }, { "name": "Eridanus", "con": "Eri", "lon": 44.519798, "lat": -35.707669 }, { "name": "Fornax", "con": "For", "lon": 26.814788, "lat": -41.210591 }, { "name": "Gemini", "con": "Gem", "lon": 105.782595, "lat": 1.000873 }, { "name": "Grus", "con": "Gru", "lon": 326.251441, "lat": -31.056323 }, { "name": "Hercules", "con": "Her", "lon": 244.712309, "lat": 56.999718 }, { "name": "Horologium", "con": "Hor", "lon": 17.951182, "lat": -65.966252 }, { "name": "Hydra", "con": "Hya", "lon": 161.009927, "lat": -31.877244 }, { "name": "Hydrus", "con": "Hyi", "lon": 319.472098, "lat": -70.424343 }, { "name": "Indus", "con": "Ind", "lon": 301.926445, "lat": -37.255007 }, { "name": "Lacerta", "con": "Lac", "lon": 8.55361, "lat": 49.010961 }, { "name": "Leo", "con": "Leo", "lon": 154.997755, "lat": 5.725842 }, { "name": "Leo Minor", "con": "LMi", "lon": 147.846031, "lat": 19.08147 }, { "name": "Lepus", "con": "Lep", "lon": 87.951035, "lat": -48.428623 }, { "name": "Libra", "con": "Lib", "lon": 235.245999, "lat": -7.143373 }, { "name": "Lupus", "con": "Lup", "lon": 235.748543, "lat": -16.335816 }, { "name": "Lynx", "con": "Lyn", "lon": 112.8512, "lat": 28.029299 }, { "name": "Lyra", "con": "Lyr", "lon": 283.019722, "lat": 53.033283 }, { "name": "Mensa", "con": "Men", "lon": 275.537729, "lat": -76.415797 }, { "name": "Microscopium", "con": "Mic", "lon": 307.914456, "lat": -19.480056 }, { "name": "Monoceros", "con": "Mon", "lon": 117.879447, "lat": -27.075403 }, { "name": "Musca", "con": "Mus", "lon": 237.878456, "lat": -57.918356 }, { "name": "Norma", "con": "Nor", "lon": 251.108158, "lat": -30.316864 }, { "name": "Octans", "con": "Oct", "lon": 279.308533, "lat": -57.535505 }, { "name": "Ophiuchus", "con": "Oph", "lon": 256.656955, "lat": 25.885164 }, { "name": "Orion", "con": "Ori", "lon": 84.057939, "lat": -10.315617 }, { "name": "Pavo", "con": "Pav", "lon": 286.171101, "lat": -40.068089 }, { "name": "Pegasus", "con": "Peg", "lon": 342.711491, "lat": 24.677229 }, { "name": "Perseus", "con": "Per", "lon": 71.784076, "lat": 23.066797 }, { "name": "Phoenix", "con": "Phe", "lon": 353.434499, "lat": -45.100485 }, { "name": "Pictor", "con": "Pic", "lon": 73.318613, "lat": -73.005111 }, { "name": "Pisces", "con": "Psc", "lon": 23.651833, "lat": 6.269517 }, { "name": "Piscis Austrinus", "con": "PsA", "lon": 324.437362, "lat": -16.67001 }, { "name": "Puppis", "con": "Pup", "lon": 128.868327, "lat": -66.627854 }, { "name": "Pyxis", "con": "Pyx", "lon": 142.973021, "lat": -40.032582 }, { "name": "Reticulum", "con": "Ret", "lon": 3.889761, "lat": -74.024087 }, { "name": "Sagitta", "con": "Sge", "lon": 296.231267, "lat": 39.546111 }, { "name": "Sagittarius", "con": "Sgr", "lon": 288.928, "lat": -12.027413 }, { "name": "Scorpius", "con": "Sco", "lon": 252.933494, "lat": -15.796715 }, { "name": "Sculptor", "con": "Scl", "lon": 346.808958, "lat": -30.559261 }, { "name": "Scutum", "con": "Sct", "lon": 281.911655, "lat": 10.444467 }, { "name": "Serpens", "con": "Ser", "lon": 228.706062, "lat": 23.224868 }, { "name": "Serpens", "con": "Ser", "lon": 281.683344, "lat": 26.014439 }, { "name": "Sextans", "con": "Sex", "lon": 161.883533, "lat": -15.242268 }, { "name": "Taurus", "con": "Tau", "lon": 55.299145, "lat": -4.208221 }, { "name": "Telescopium", "con": "Tel", "lon": 275.118769, "lat": -30.693895 }, { "name": "Triangulum", "con": "Tri", "lon": 37.546066, "lat": 21.305214 }, { "name": "Triangulum Australe", "con": "TrA", "lon": 254.096715, "lat": -45.709961 }, { "name": "Tucana", "con": "Tuc", "lon": 314.186678, "lat": -52.033726 }, { "name": "Ursa Maior", "con": "UMa", "lon": 144.88515, "lat": 37.801918 }, { "name": "Ursa Minor", "con": "UMi", "lon": 155.134834, "lat": 73.488468 }, { "name": "Vela", "con": "Vel", "lon": 170.294375, "lat": -55.619929 }, { "name": "Virgo", "con": "Vir", "lon": 199.514594, "lat": 3.925366 }, { "name": "Volans", "con": "Vol", "lon": 231.125009, "lat": -80.389936 }, { "name": "Vulpecula", "con": "Vul", "lon": 302.513591, "lat": 41.60393 }] }
@@ -1,5 +1,6 @@
1
1
  /** astroengine chart -- public API: natal charts, aspects, retrogrades. */
2
- import { EngineData, AYANAMSA_J2000 } from "./core.js";
2
+ import { EngineData, AYANAMSA_J2000, XyzSource } from "./core.js";
3
+ import type { SyntheticRender } from "./synthetic.js";
3
4
  import type { AspectPhase } from "./electional.js";
4
5
  export declare const BODIES: readonly ["sun", "moon", "mercury", "venus", "mars", "jupiter", "saturn", "uranus", "neptune", "pluto", "chiron", "mean_node", "true_node"];
5
6
  export type Body = (typeof BODIES)[number];
@@ -173,7 +174,35 @@ export declare class Engine {
173
174
  private moonCheb;
174
175
  private chironCheb;
175
176
  private packs;
177
+ private runtimeSources;
178
+ private renderAttrs;
176
179
  constructor(data: EngineData);
180
+ /**
181
+ * Register a runtime {@link XyzSource} under a body id, so it resolves through
182
+ * {@link Engine.position}, {@link Engine.longitude}, {@link Engine.chartAt},
183
+ * and everything built on them (transits, returns, retrograde, SkyView) with
184
+ * no special-casing — exactly like a baked-in Chebyshev or Kepler pack. The
185
+ * source yields heliocentric ecliptic-J2000 xyz in AU at a **TT** Julian Day,
186
+ * the same contract Chiron and the Uranian bodies satisfy; the engine applies
187
+ * light-time, aberration, precession and nutation to it like any real body.
188
+ *
189
+ * This is the seam the `synthetic` module plugs imaginary bodies into (see
190
+ * {@link registerSyntheticSystem}). A registered id shadows a baked-in pack of
191
+ * the same name and persists for the engine's lifetime.
192
+ *
193
+ * @param id The body id to register (any string).
194
+ * @param source A heliocentric xyz source; see {@link XyzSource}.
195
+ * @returns This engine, for chaining.
196
+ */
197
+ registerSource(id: string, source: XyzSource): this;
198
+ /** Author how a runtime body should look in SkyView (size, magnitude, colour).
199
+ * Position still comes from {@link registerSource}; this owns appearance only. */
200
+ registerRender(id: string, render: SyntheticRender): this;
201
+ /** SkyView appearance for a registered body, if any. */
202
+ renderFor(id: string): SyntheticRender | undefined;
203
+ /** Whether `body` resolves through the generic packed-source path: a baked-in
204
+ * Chebyshev/Kepler pack or a runtime source from {@link registerSource}. */
205
+ private hasPack;
177
206
  private pack;
178
207
  private moonInRange;
179
208
  /**
package/dist/src/chart.js CHANGED
@@ -135,11 +135,51 @@ export class Engine {
135
135
  moonCheb;
136
136
  chironCheb;
137
137
  packs = new Map();
138
+ runtimeSources = new Map();
139
+ renderAttrs = new Map();
138
140
  constructor(data) {
139
141
  this.data = data;
140
142
  this.moonCheb = data.moonCheb ? new ChebSeries(data.moonCheb) : null;
141
143
  this.chironCheb = data.chiron ? new ChebSeries(data.chiron) : null;
142
144
  }
145
+ /**
146
+ * Register a runtime {@link XyzSource} under a body id, so it resolves through
147
+ * {@link Engine.position}, {@link Engine.longitude}, {@link Engine.chartAt},
148
+ * and everything built on them (transits, returns, retrograde, SkyView) with
149
+ * no special-casing — exactly like a baked-in Chebyshev or Kepler pack. The
150
+ * source yields heliocentric ecliptic-J2000 xyz in AU at a **TT** Julian Day,
151
+ * the same contract Chiron and the Uranian bodies satisfy; the engine applies
152
+ * light-time, aberration, precession and nutation to it like any real body.
153
+ *
154
+ * This is the seam the `synthetic` module plugs imaginary bodies into (see
155
+ * {@link registerSyntheticSystem}). A registered id shadows a baked-in pack of
156
+ * the same name and persists for the engine's lifetime.
157
+ *
158
+ * @param id The body id to register (any string).
159
+ * @param source A heliocentric xyz source; see {@link XyzSource}.
160
+ * @returns This engine, for chaining.
161
+ */
162
+ registerSource(id, source) {
163
+ this.runtimeSources.set(id, source);
164
+ this.packs.set(id, source);
165
+ return this;
166
+ }
167
+ /** Author how a runtime body should look in SkyView (size, magnitude, colour).
168
+ * Position still comes from {@link registerSource}; this owns appearance only. */
169
+ registerRender(id, render) {
170
+ this.renderAttrs.set(id, render);
171
+ return this;
172
+ }
173
+ /** SkyView appearance for a registered body, if any. */
174
+ renderFor(id) {
175
+ return this.renderAttrs.get(id);
176
+ }
177
+ /** Whether `body` resolves through the generic packed-source path: a baked-in
178
+ * Chebyshev/Kepler pack or a runtime source from {@link registerSource}. */
179
+ hasPack(body) {
180
+ return !!(this.data.chebPacks?.[body] || this.data.keplerPack?.bodies[body])
181
+ || this.runtimeSources.has(body);
182
+ }
143
183
  pack(body) {
144
184
  let s = this.packs.get(body);
145
185
  if (!s) {
@@ -176,6 +216,7 @@ export class Engine {
176
216
  ...[...BODIES, ...EXTRA_BODIES].filter((b) => b !== "chiron" || this.chironCheb),
177
217
  ...Object.keys(this.data.chebPacks ?? {}),
178
218
  ...Object.keys(this.data.keplerPack?.bodies ?? {}),
219
+ ...this.runtimeSources.keys(),
179
220
  ];
180
221
  }
181
222
  /**
@@ -231,8 +272,9 @@ export class Engine {
231
272
  : oscApogeeSeries(this.data, jde);
232
273
  return [lon, lat, km / KM_PER_AU];
233
274
  }
234
- if (this.data.chebPacks?.[body] || this.data.keplerPack?.bodies[body]) {
235
- // same heliocentric pipeline as Chiron (Chebyshev or Kepler source)
275
+ if (this.hasPack(body)) {
276
+ // same heliocentric pipeline as Chiron (Chebyshev, Kepler, or a runtime
277
+ // source registered via registerSource — e.g. a synthetic body)
236
278
  return chironApparent(this.data, this.pack(body), jde);
237
279
  }
238
280
  if (this.data.vsop[body])
@@ -425,7 +467,7 @@ export class Engine {
425
467
  b = Math.atan2(z, Math.hypot(x, y));
426
468
  [l, b] = precessEcliptic(l, b, J2000, jde);
427
469
  }
428
- else if (this.data.chebPacks?.[body] || this.data.keplerPack?.bodies[body]) {
470
+ else if (this.hasPack(body)) {
429
471
  const [x, y, z] = this.pack(body).xyz(jde);
430
472
  r = Math.sqrt(x * x + y * y + z * z);
431
473
  l = mod(Math.atan2(y, x), TWO_PI);
@@ -58,6 +58,11 @@ export interface EngineData {
58
58
  keplerPack?: KeplerPack;
59
59
  /** Fixed-star catalog (HYG-derived; ICRS J2000 + proper motions). */
60
60
  fixedStars?: import("./stars.js").StarPack;
61
+ /** Deep naked-eye star pack (HYG to ~mag 6.5), the complete background field
62
+ * for SkyView. Opt-in: node-loaded, not in the embedded web bundle. */
63
+ deepStars?: import("./stars.js").StarPack;
64
+ /** Constellation figure lines and labels for SkyView overlays. */
65
+ constellations?: import("./stars.js").ConstellationPack;
61
66
  }
62
67
  /**
63
68
  * Convert a UT calendar date and time to a Julian Day (UT) — the time
@@ -16,7 +16,8 @@ import moonMeeus from "../data/moon_meeus47.json" with { type: "json" };
16
16
  import pluto from "../data/pluto_meeus37.json" with { type: "json" };
17
17
  import chiron from "../data/chiron_cheb.json" with { type: "json" };
18
18
  import fixedStars from "../data/fixed_stars.json" with { type: "json" };
19
+ import constellations from "../data/constellations.json" with { type: "json" };
19
20
  export const embeddedData = {
20
21
  vsop: { mercury, venus, earth, mars, jupiter, saturn, uranus, neptune },
21
- nutation, moonMeeus, pluto, chiron, fixedStars,
22
+ nutation, moonMeeus, pluto, chiron, fixedStars, constellations,
22
23
  };
@@ -11,10 +11,12 @@ export * from "./turbo.js";
11
11
  export * from "./electional.js";
12
12
  export * from "./scan.js";
13
13
  export * from "./spherical.js";
14
+ export * from "./skyview.js";
14
15
  export * from "./astrocartography.js";
15
16
  export * from "./ephemeris.js";
16
17
  export * from "./features.js";
17
18
  export * from "./compiler.js";
19
+ export * from "./synthetic.js";
18
20
  export * from "./lots.js";
19
21
  export * from "./profections.js";
20
22
  export * from "./firdaria.js";
package/dist/src/index.js CHANGED
@@ -11,10 +11,12 @@ export * from "./turbo.js";
11
11
  export * from "./electional.js";
12
12
  export * from "./scan.js";
13
13
  export * from "./spherical.js";
14
+ export * from "./skyview.js";
14
15
  export * from "./astrocartography.js";
15
16
  export * from "./ephemeris.js";
16
17
  export * from "./features.js";
17
18
  export * from "./compiler.js";
19
+ export * from "./synthetic.js";
18
20
  export * from "./lots.js";
19
21
  export * from "./profections.js";
20
22
  export * from "./firdaria.js";
@@ -375,6 +375,8 @@ export function interpretationContext(chart, opts = {}) {
375
375
  ["l1", tl.zr.l1], ["l2", tl.zr.l2], ["l3", tl.zr.l3], ["l4", tl.zr.l4],
376
376
  ];
377
377
  for (const [level, sign] of zrLevels) {
378
+ if (!sign)
379
+ continue; // deeper levels (l3/l4) can be absent when the period does not subdivide
378
380
  const signIdx = SIGNS.indexOf(sign);
379
381
  const lord = signIdx >= 0 ? SIGN_RULER[signIdx] : "";
380
382
  atoms.push({
@@ -34,6 +34,12 @@ export function loadNodeData(dir, level = "embedded", moonTier = "full") {
34
34
  if (existsSync(join(dir, "fixed_stars.json"))) {
35
35
  data.fixedStars = j("fixed_stars.json");
36
36
  }
37
+ if (existsSync(join(dir, "fixed_stars_deep.json"))) {
38
+ data.deepStars = j("fixed_stars_deep.json");
39
+ }
40
+ if (existsSync(join(dir, "constellations.json"))) {
41
+ data.constellations = j("constellations.json");
42
+ }
37
43
  // asteroid packs (Horizons fits): loaded when present, ~380 KB total.
38
44
  // `pluto` is optional too: when a wide-range Chebyshev pack is present it
39
45
  // supersedes the embedded Meeus ch.37 series (valid 1885-2099) above, so
@@ -0,0 +1,351 @@
1
+ import { Engine, Observer, HouseSystem } from "./chart.js";
2
+ import type { SyntheticRender } from "./synthetic.js";
3
+ export type SkyProjection = "rectilinear" | "fisheye";
4
+ /** A resolved lens: field of view and projection actually used. */
5
+ export interface SkyLens {
6
+ name: string;
7
+ focalLengthMm: number;
8
+ sensorWidthMm: number;
9
+ projection: SkyProjection;
10
+ hfovDeg: number;
11
+ vfovDeg: number;
12
+ }
13
+ export declare const LENS_NAMES: string[];
14
+ export type LensSpec = string | {
15
+ focalLengthMm: number;
16
+ sensorWidthMm?: number;
17
+ projection?: SkyProjection;
18
+ } | {
19
+ hfovDeg: number;
20
+ projection?: SkyProjection;
21
+ };
22
+ export type TwilightStage = "day" | "civil" | "nautical" | "astronomical" | "night";
23
+ export interface SkyAim {
24
+ /** Center azimuth: degrees from true north (east positive), or a compass
25
+ * point (`"W"`, `"WNW"`). */
26
+ azimuth: number | string;
27
+ /** Center altitude in degrees: 0 looks at the horizon, positive tilts up. */
28
+ altitude: number;
29
+ }
30
+ export interface SkyViewSpec {
31
+ observer: Observer;
32
+ aim: SkyAim;
33
+ lens: LensSpec;
34
+ image: {
35
+ width: number;
36
+ height: number;
37
+ };
38
+ }
39
+ export interface SkyViewOptions {
40
+ /** Atmospheric pressure (hPa) and temperature (C) for refraction. */
41
+ pressure?: number;
42
+ tempC?: number;
43
+ /** Lift apparent altitudes by refraction. Defaults to true. */
44
+ refraction?: boolean;
45
+ /** Bortle dark-sky class, 1 (pristine) to 9 (inner city). Sets the night
46
+ * naked-eye limit and drives the background star-field density and Milky Way
47
+ * visibility. Omit for the legacy suburban default (limit 6.0). */
48
+ bortle?: number;
49
+ /** Include bright catalog stars. Defaults to true when a catalog is loaded. */
50
+ includeStars?: boolean;
51
+ /** Brightest-magnitude cutoff for stars (smaller is brighter). Default 2.5. */
52
+ maxStarMag?: number;
53
+ /** Cap on the number of stars returned. Default 40 (named) or 4000 (deep). */
54
+ maxStars?: number;
55
+ /** Pin the complete deep star field (needs the deep pack loaded). Defaults to
56
+ * on when the sky is dark and no bright Moon is up. */
57
+ deepField?: boolean;
58
+ /** Reference-frame overlays to project onto the sky (annotations, not part of
59
+ * a photoreal render). */
60
+ overlays?: SkyViewOverlaysRequest;
61
+ /** Bodies to place. Defaults to Sun, Moon, and the naked-eye planets. Any
62
+ * string id works for runtime bodies registered via {@link Engine.registerSource}. */
63
+ bodies?: readonly string[];
64
+ /** Per-body appearance overrides (size, magnitude, colour). Merged with
65
+ * {@link Engine.renderFor} for registered bodies; opts win on conflict. */
66
+ render?: Record<string, SyntheticRender>;
67
+ }
68
+ export interface SkyBody {
69
+ id: string;
70
+ name: string;
71
+ azimuthDeg: number;
72
+ altitudeDeg: number;
73
+ x: number;
74
+ y: number;
75
+ inFrame: boolean;
76
+ sizePx: number;
77
+ angularDiameterDeg: number;
78
+ magnitude: number | null;
79
+ /** Bright enough to see at this sky brightness. */
80
+ nakedEye: boolean;
81
+ /** How prominent to render the body, derived from its magnitude (a prompt
82
+ * cue, not a physical size). See {@link brightnessDescriptor}. */
83
+ brightnessHint?: string;
84
+ /** Moon only: illuminated fraction, phase name, and bright-limb orientation. */
85
+ illum?: number;
86
+ phaseName?: string;
87
+ brightLimbAngleDeg?: number;
88
+ brightLimbClock?: string;
89
+ /** Authored colour hint for synthetic or overridden bodies. */
90
+ color?: string;
91
+ note?: string;
92
+ }
93
+ export interface SkyOffFrameBody {
94
+ id: string;
95
+ name: string;
96
+ side: "left" | "right" | "above" | "below" | "behind";
97
+ /** Angular distance from the frame center, degrees. */
98
+ deltaDeg: number;
99
+ azimuthDeg: number;
100
+ altitudeDeg: number;
101
+ magnitude: number | null;
102
+ }
103
+ export interface SkySummary {
104
+ twilight: TwilightStage;
105
+ sunAltitudeDeg: number;
106
+ sunAzimuthDeg: number;
107
+ limitingMag: number;
108
+ moonAltitudeDeg: number | null;
109
+ moonIllum: number | null;
110
+ /** Azimuth of the brightest part of the sky (afterglow, then Moon), or null. */
111
+ brightestAzimuthDeg: number | null;
112
+ /** Pixel row of the true horizon, or null when it is behind the camera. */
113
+ horizonY: number | null;
114
+ }
115
+ /** The Milky Way band's appearance in the frame. Visible only in a dark sky
116
+ * (astronomical twilight or night) without a bright Moon or heavy light
117
+ * pollution. The band is the galactic equator; its bright bulge is the
118
+ * galactic center in Sagittarius. */
119
+ export interface MilkyWay {
120
+ /** Dark enough to see, and at least partly above the horizon. */
121
+ visible: boolean;
122
+ /** The band crosses the frame (implies `visible`). */
123
+ inFrame: boolean;
124
+ /** Pixel where the band enters the frame, and where it exits. */
125
+ entry: {
126
+ x: number;
127
+ y: number;
128
+ } | null;
129
+ exit: {
130
+ x: number;
131
+ y: number;
132
+ } | null;
133
+ /** The galactic center (Sagittarius), the brightest part, when above the
134
+ * horizon: its pixel, whether it is in frame, its altitude, and which way it
135
+ * lies relative to the frame. */
136
+ galacticCenter: {
137
+ x: number;
138
+ y: number;
139
+ inFrame: boolean;
140
+ altitudeDeg: number;
141
+ side: string;
142
+ } | null;
143
+ /** Plain-language state, e.g. "crosses the frame, bright center in view" or
144
+ * "washed out by a bright Moon". */
145
+ note: string;
146
+ }
147
+ /** The visible celestial pole: the fixed point the whole sky rotates about as
148
+ * time passes (north pole for northern observers, south for southern). Its
149
+ * altitude equals the observer's |latitude|. The rotation center for star
150
+ * trails and for reprojecting an animation frame to frame. */
151
+ export interface CelestialPole {
152
+ which: "north" | "south";
153
+ altitudeDeg: number;
154
+ /** Pixel of the pole, or null when it is behind the camera. */
155
+ x: number | null;
156
+ y: number | null;
157
+ inFrame: boolean;
158
+ }
159
+ /** What the star field in `bodies` represents. A `deep` field is the complete
160
+ * naked-eye sky to `limitingMag`, pinned at exact pixels (animation-grade); a
161
+ * `named` field is the bright catalog, to be fleshed out by the model. */
162
+ export interface StarfieldSummary {
163
+ source: "deep" | "named" | "none";
164
+ /** Stars placed in the frame. */
165
+ count: number;
166
+ /** The field is complete to `limitingMag` (deep pack); do not add stars. */
167
+ complete: boolean;
168
+ limitingMag: number;
169
+ }
170
+ /** Which reference frames to project. The ecliptic, the zodiac signs (its 30
171
+ * degree divisions), the house cusps and angles, and the constellation figure
172
+ * lines. These are annotations: real reference frames drawn over the sky, not
173
+ * things a camera sees. */
174
+ export interface SkyViewOverlaysRequest {
175
+ ecliptic?: boolean;
176
+ signs?: boolean;
177
+ houses?: boolean;
178
+ constellations?: boolean;
179
+ /** House system for the cusps. Defaults to Placidus. */
180
+ houseSystem?: HouseSystem;
181
+ }
182
+ /** A labeled point projected into the frame (sign, house, constellation name). */
183
+ export interface OverlayMark {
184
+ text: string;
185
+ x: number;
186
+ y: number;
187
+ /** Ecliptic longitude (deg), for signs and house cusps. */
188
+ lon?: number;
189
+ }
190
+ /** An in-frame polyline (the ecliptic, a constellation figure stroke). */
191
+ export interface OverlayLine {
192
+ label?: string;
193
+ points: Array<{
194
+ x: number;
195
+ y: number;
196
+ }>;
197
+ }
198
+ /** Projected reference-frame overlays. Each is null when not requested; arrays
199
+ * hold only the in-frame parts. Pixels match the bodies' coordinate system. */
200
+ export interface SkyViewOverlays {
201
+ ecliptic: OverlayLine[] | null;
202
+ signs: OverlayMark[] | null;
203
+ houses: OverlayMark[] | null;
204
+ constellations: {
205
+ lines: OverlayLine[];
206
+ labels: OverlayMark[];
207
+ } | null;
208
+ }
209
+ /** One layer of the hybrid render: what Caelus computes and the pipeline
210
+ * composites locally over the image-model background plate. */
211
+ export interface RenderLayer {
212
+ kind: "bodies" | "stars" | "milkyWay" | "overlays";
213
+ /** The layer has content in this frame. */
214
+ present: boolean;
215
+ /** Items in the layer (bodies, stars, figure strokes...). */
216
+ count: number;
217
+ /** How to composite this layer locally, over the plate. */
218
+ composite: string;
219
+ }
220
+ /**
221
+ * A machine-readable render contract for a hybrid pipeline: ask an image model
222
+ * for a body-free background plate, then composite the computed layers (bodies,
223
+ * stars, the Milky Way, overlays) locally at their exact pixels. The image model
224
+ * supplies atmosphere; Caelus supplies the physically correct objects. This is
225
+ * the structured complement to `prompt`, which is for humans and image models.
226
+ */
227
+ export interface RenderPlan {
228
+ /** The body-free sky/atmosphere plate to generate with an image model. */
229
+ background: {
230
+ prompt: string;
231
+ width: number;
232
+ height: number;
233
+ /** Hard constraints on the plate (no bodies, horizon row, even sky). */
234
+ constraints: string[];
235
+ };
236
+ /** Layers to composite locally; do not ask the model to draw these. */
237
+ layers: RenderLayer[];
238
+ /** How to drive an animation. `static` for a single frame. */
239
+ animation: {
240
+ strategy: "static" | "sequence-composite";
241
+ /** Sidereal rotation of the sky about the pole, degrees/hour. */
242
+ rotationDegPerHour: number;
243
+ pole: CelestialPole;
244
+ notes: string;
245
+ };
246
+ /** Post-processing and grading notes for the composite. */
247
+ postprocess: string[];
248
+ }
249
+ export interface SkyViewResult {
250
+ instant: {
251
+ jdUt: number;
252
+ utc: string;
253
+ };
254
+ observer: Observer;
255
+ aim: {
256
+ azimuthDeg: number;
257
+ altitudeDeg: number;
258
+ compass: string;
259
+ };
260
+ lens: SkyLens;
261
+ image: {
262
+ width: number;
263
+ height: number;
264
+ };
265
+ sky: SkySummary;
266
+ bodies: SkyBody[];
267
+ offFrame: SkyOffFrameBody[];
268
+ milkyWay: MilkyWay;
269
+ pole: CelestialPole;
270
+ starfield: StarfieldSummary;
271
+ overlays: SkyViewOverlays | null;
272
+ renderPlan: RenderPlan;
273
+ directives: string[];
274
+ prompt: string;
275
+ }
276
+ /**
277
+ * Project the visible sky into an image frame for a place, instant, aim, and
278
+ * lens. Returns each in-frame body's pixel position, apparent size, brightness,
279
+ * and (for the Moon) phase orientation, a sky-state summary, the bright bodies
280
+ * just outside the frame, and a serialized prompt.
281
+ *
282
+ * Caelus computes geometry and photometry only. It does not render an image;
283
+ * the `prompt` and `directives` hand color and atmosphere to an image model.
284
+ *
285
+ * @param engine The engine used to evaluate positions.
286
+ * @param jdUt The instant, Julian Day (UT). For "at sunset", resolve it first
287
+ * with `riseSet(engine, "sun", jdStart, lat, lonEast, "set")`.
288
+ * @param view Observer, aim (azimuth and altitude), lens, and image size.
289
+ * @param opts Refraction inputs, star selection, and the body set.
290
+ * @returns A {@link SkyViewResult}.
291
+ * @example
292
+ * ```ts
293
+ * const set = riseSet(engine, "sun", julianDay(2026, 6, 21), 47.6, -122.3, "set")!;
294
+ * const view = skyView(engine, set, {
295
+ * observer: { lat: 47.6, lonEast: -122.3, altM: 9 },
296
+ * aim: { azimuth: "W", altitude: 5 },
297
+ * lens: "normal",
298
+ * image: { width: 1024, height: 683 },
299
+ * });
300
+ * view.bodies.find((b) => b.id === "moon")?.brightLimbClock;
301
+ * ```
302
+ */
303
+ export declare function skyView(engine: Engine, jdUt: number, view: SkyViewSpec, opts?: SkyViewOptions): SkyViewResult;
304
+ export interface SkyViewSequenceSpec {
305
+ /** First frame instant, Julian Day (UT). */
306
+ startJdUt: number;
307
+ /** Number of frames (>= 1). */
308
+ frames: number;
309
+ /** Minutes between frames. Provide this or `endJdUt`. */
310
+ stepMinutes?: number;
311
+ /** Last frame instant (UT); the step is `(end - start) / (frames - 1)`.
312
+ * Takes precedence over `stepMinutes` when both are given. */
313
+ endJdUt?: number;
314
+ }
315
+ export interface SkyViewSequence {
316
+ /** One full {@link SkyViewResult} per frame, in time order. */
317
+ frames: SkyViewResult[];
318
+ count: number;
319
+ startJdUt: number;
320
+ endJdUt: number;
321
+ stepMinutes: number;
322
+ durationMinutes: number;
323
+ /** Sidereal rotation of the sky about the celestial pole: 15.041 deg/hour. */
324
+ rotationDegPerHour: number;
325
+ /** Sky rotation between consecutive frames, degrees about the pole. */
326
+ rotationDegPerStep: number;
327
+ }
328
+ /**
329
+ * A time sequence of {@link skyView} frames for the same place, aim, and lens:
330
+ * the keyframes for an accurate night-sky animation. Each frame is a complete,
331
+ * physically exact spec; across frames the sky rotates about the pole, the Moon
332
+ * drifts and changes phase, twilight evolves, and the Milky Way wheels. The
333
+ * geometry is continuous, so the frames are temporally coherent; supplying them
334
+ * as control images (or reprojecting one rendered plate by the per-frame
335
+ * rotation) is how to keep the rendered output coherent too.
336
+ *
337
+ * @param engine The engine used to evaluate positions.
338
+ * @param view Observer, aim, lens, and image size, shared by every frame.
339
+ * @param seq Frame count and timing (`stepMinutes` or `endJdUt`).
340
+ * @param opts Per-frame {@link SkyViewOptions} (bortle, refraction, bodies).
341
+ * @returns A {@link SkyViewSequence}: the frames plus timing and the sky's
342
+ * per-step rotation about the celestial pole (each frame carries its `pole`).
343
+ * @example
344
+ * ```ts
345
+ * // One frame per 6 minutes for two hours from astronomical dusk
346
+ * const seq = skyViewSequence(engine, view, { startJdUt: dusk, frames: 21, stepMinutes: 6 });
347
+ * seq.rotationDegPerStep; // ~1.5 deg of sky rotation per frame
348
+ * seq.frames[0].pole; // the rotation center in pixels
349
+ * ```
350
+ */
351
+ export declare function skyViewSequence(engine: Engine, view: SkyViewSpec, seq: SkyViewSequenceSpec, opts?: SkyViewOptions): SkyViewSequence;