@johnmorrisdotca/hoshi-stars 0.0.0-stage → 0.2.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.
- package/CHANGELOG.md +25 -0
- package/LICENSE +21 -0
- package/NOTICE.md +146 -0
- package/README.md +337 -2
- package/dist/boundaries.d.ts +95 -0
- package/dist/boundaries.js +195 -0
- package/dist/constellations.d.ts +72 -0
- package/dist/constellations.js +105 -0
- package/dist/data/boundaries.d.ts +4 -0
- package/dist/data/boundaries.js +449 -0
- package/dist/data/constellations.d.ts +1 -0
- package/dist/data/constellations.js +91 -0
- package/dist/data/lines.d.ts +2 -0
- package/dist/data/lines.js +92 -0
- package/dist/data/messier.d.ts +2 -0
- package/dist/data/messier.js +116 -0
- package/dist/data/milky-way.d.ts +5 -0
- package/dist/data/milky-way.js +7 -0
- package/dist/data/ngc-ic.d.ts +2 -0
- package/dist/data/ngc-ic.js +11794 -0
- package/dist/data/star-names-ja.d.ts +2 -0
- package/dist/data/star-names-ja.js +4 -0
- package/dist/data/stars.d.ts +4 -0
- package/dist/data/stars.js +5088 -0
- package/dist/deep-sky-core.d.ts +123 -0
- package/dist/deep-sky-core.js +139 -0
- package/dist/deep-sky-ngc-ic.d.ts +34 -0
- package/dist/deep-sky-ngc-ic.js +43 -0
- package/dist/deep-sky.d.ts +49 -0
- package/dist/deep-sky.js +59 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/lines.d.ts +49 -0
- package/dist/lines.js +64 -0
- package/dist/milky-way.d.ts +144 -0
- package/dist/milky-way.js +242 -0
- package/dist/projection.d.ts +127 -0
- package/dist/projection.js +284 -0
- package/dist/sky.d.ts +202 -0
- package/dist/sky.js +283 -0
- package/dist/stars.d.ts +162 -0
- package/dist/stars.js +195 -0
- package/dist/time-scale.d.ts +14 -0
- package/dist/time-scale.js +71 -0
- package/dist/when.d.ts +16 -0
- package/dist/when.js +18 -0
- package/package.json +184 -4
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The kinds of deep-sky object, a small fixed list.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```ts
|
|
6
|
+
* import { DEEP_SKY_TYPES } from "@johnmorrisdotca/hoshi-stars/deep-sky";
|
|
7
|
+
*
|
|
8
|
+
* console.log(DEEP_SKY_TYPES.length, DEEP_SKY_TYPES.includes("galaxy"));
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
export declare const DEEP_SKY_TYPES: readonly ["other", "galaxy", "globular cluster", "open cluster", "nebula", "planetary nebula", "supernova remnant"];
|
|
12
|
+
/**
|
|
13
|
+
* The kind of a deep-sky object: `galaxy`, `globular cluster`, `open cluster`, `nebula` (emission, reflection and dark nebulae and H II regions), `planetary nebula`, `supernova remnant`, or
|
|
14
|
+
* `other` (an asterism, a star cloud, a double star, a source that is not any of those).
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { deepSkyObject, type DeepSkyType } from "@johnmorrisdotca/hoshi-stars/deep-sky";
|
|
19
|
+
*
|
|
20
|
+
* const type: DeepSkyType = deepSkyObject("M1")!.type;
|
|
21
|
+
* console.log(type);
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export type DeepSkyType = (typeof DEEP_SKY_TYPES)[number];
|
|
25
|
+
/**
|
|
26
|
+
* One deep-sky object. Positions are J2000 (equator and equinox of 2000), the same frame as `Star`.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* import { deepSkyObject, type DeepSkyObject } from "@johnmorrisdotca/hoshi-stars/deep-sky";
|
|
31
|
+
*
|
|
32
|
+
* const andromeda: DeepSkyObject = deepSkyObject("M31")!;
|
|
33
|
+
* console.log(andromeda.id, andromeda.ngc, andromeda.name, andromeda.magnitude);
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export interface DeepSkyObject {
|
|
37
|
+
/** The Messier designation (`M31`) if the object has one, else the NGC (`NGC 7000`), else the IC (`IC 434`). Unique, and a name `deepSkyObject` finds. */
|
|
38
|
+
id: string;
|
|
39
|
+
/** The Messier designation (`M31`), or `undefined`. */
|
|
40
|
+
messier: string | undefined;
|
|
41
|
+
/** The New General Catalogue designation (`NGC 224`), or `undefined`. Where an object has several (a duplicate entry, a component), the lowest plain number. */
|
|
42
|
+
ngc: string | undefined;
|
|
43
|
+
/** The Index Catalogue designation (`IC 434`), or `undefined`. */
|
|
44
|
+
ic: string | undefined;
|
|
45
|
+
/** The object's other NGC and IC designations (`NGC 978A`, `NGC 1051` for the object that is also `NGC 961`), each one found by `deepSkyObject` too. Usually empty. */
|
|
46
|
+
otherIds: string[];
|
|
47
|
+
/** The common name where Wikidata's English label is one (`Andromeda Galaxy`, `Crab Nebula`), else `undefined`. */
|
|
48
|
+
name: string | undefined;
|
|
49
|
+
/** The kind of object. */
|
|
50
|
+
type: DeepSkyType;
|
|
51
|
+
/** The IAU three-letter constellation abbreviation (`And`), or `undefined`. It is the same text as `Star.constellation`. */
|
|
52
|
+
constellation: string | undefined;
|
|
53
|
+
/** Right ascension in degrees at J2000, 0 up to 360. Given to 0.0001 degree (0.36 arc-second). */
|
|
54
|
+
rightAscension: number;
|
|
55
|
+
/** Declination in degrees at J2000, -90 to 90. Given to 0.0001 degree. */
|
|
56
|
+
declination: number;
|
|
57
|
+
/** Visual (V band) magnitude of the whole object, or `undefined` where there is none (for the Messier objects there always is one). Smaller is brighter: M31 is 3.4. */
|
|
58
|
+
magnitude: number | undefined;
|
|
59
|
+
/** The major axis in arc-minutes, or `undefined` where it is not known (most NGC and IC objects). */
|
|
60
|
+
sizeArcmin: number | undefined;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The catalogue names `deepSky` accepts for its `catalogue` option.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```ts
|
|
67
|
+
* import { DEEP_SKY_CATALOGUES, deepSky } from "@johnmorrisdotca/hoshi-stars/deep-sky";
|
|
68
|
+
*
|
|
69
|
+
* console.log(DEEP_SKY_CATALOGUES.map((catalogue) => deepSky({ catalogue }).length));
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export declare const DEEP_SKY_CATALOGUES: readonly ["messier", "ngc", "ic"];
|
|
73
|
+
/**
|
|
74
|
+
* The options of `deepSky`: all optional, and together they narrow the list.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* import { deepSky, type DeepSkyOptions } from "@johnmorrisdotca/hoshi-stars/deep-sky";
|
|
79
|
+
*
|
|
80
|
+
* const options: DeepSkyOptions = { type: "globular cluster", magnitude: 6.5 };
|
|
81
|
+
* console.log(deepSky(options).map((o) => o.id));
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
export interface DeepSkyOptions {
|
|
85
|
+
/** Only objects that have a number in that catalogue: `"messier"`, `"ngc"` or `"ic"`. */
|
|
86
|
+
catalogue?: (typeof DEEP_SKY_CATALOGUES)[number];
|
|
87
|
+
/** Only objects as bright as this magnitude (an object of exactly that magnitude is in). An object with no magnitude is never in. */
|
|
88
|
+
magnitude?: number;
|
|
89
|
+
/** Only objects of that kind. */
|
|
90
|
+
type?: DeepSkyType;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* What a table of objects offers: the list, a filtered list and a lookup. Each entry point makes one from its data.
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```ts
|
|
97
|
+
* import { deepSky } from "@johnmorrisdotca/hoshi-stars/deep-sky";
|
|
98
|
+
*
|
|
99
|
+
* console.log(deepSky({ type: "planetary nebula" }).length);
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
export interface DeepSkyTable {
|
|
103
|
+
/** All the objects in catalogue order, as a fresh array. */
|
|
104
|
+
all(): DeepSkyObject[];
|
|
105
|
+
/** The objects that meet the options, in catalogue order. */
|
|
106
|
+
select(options: DeepSkyOptions): DeepSkyObject[];
|
|
107
|
+
/** One object by any of its names, or `undefined`. */
|
|
108
|
+
find(text: string): DeepSkyObject | undefined;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Parse rows of the data into a table. A row is `Messier | NGC numbers | IC numbers | type | RA | Dec | magnitude | size | constellation | name | other names`, as `scripts/make-deep-sky-data.py` writes them.
|
|
112
|
+
*
|
|
113
|
+
* @param rowSets - One or more strings of rows, one object a line, in catalogue order.
|
|
114
|
+
* @returns The table.
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```ts
|
|
118
|
+
* import { deepSkyTable } from "../src/deep-sky-core.ts";
|
|
119
|
+
*
|
|
120
|
+
* console.log(deepSkyTable(["31|224||1|106847|412688|344||And|Andromeda Galaxy|"]).all()[0]?.id);
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
export declare function deepSkyTable(rowSets: string[]): DeepSkyTable;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// The part the two deep-sky entry points share: what an object is, how a row of the data becomes one, and the lookups. Not an entry point itself.
|
|
2
|
+
// Pure: no DOM, no clock, no state beyond the parsed table.
|
|
3
|
+
/**
|
|
4
|
+
* The kinds of deep-sky object, a small fixed list.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { DEEP_SKY_TYPES } from "@johnmorrisdotca/hoshi-stars/deep-sky";
|
|
9
|
+
*
|
|
10
|
+
* console.log(DEEP_SKY_TYPES.length, DEEP_SKY_TYPES.includes("galaxy"));
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export const DEEP_SKY_TYPES = ["other", "galaxy", "globular cluster", "open cluster", "nebula", "planetary nebula", "supernova remnant"];
|
|
14
|
+
/**
|
|
15
|
+
* The catalogue names `deepSky` accepts for its `catalogue` option.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { DEEP_SKY_CATALOGUES, deepSky } from "@johnmorrisdotca/hoshi-stars/deep-sky";
|
|
20
|
+
*
|
|
21
|
+
* console.log(DEEP_SKY_CATALOGUES.map((catalogue) => deepSky({ catalogue }).length));
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export const DEEP_SKY_CATALOGUES = ["messier", "ngc", "ic"];
|
|
25
|
+
function fold(text) {
|
|
26
|
+
return text.normalize("NFD").replace(/[̀-ͯ]/g, "").replace(/\s+/g, " ").trim().toLowerCase();
|
|
27
|
+
}
|
|
28
|
+
/** The lookup key of a text: `M 31`, `m31` and `Messier 31` all give `m31`; `ngc 0224` gives `ngc224`; any other text is its folded self. */
|
|
29
|
+
function key(text) {
|
|
30
|
+
const folded = fold(text);
|
|
31
|
+
const designation = /^(m|messier|ngc|ic) ?0*(\d+) ?([a-z]?)$/.exec(folded);
|
|
32
|
+
return designation === null ? folded : `${designation[1] === "messier" ? "m" : designation[1]}${designation[2]}${designation[3]}`;
|
|
33
|
+
}
|
|
34
|
+
function designations(prefix, list) {
|
|
35
|
+
return list === "" ? [] : list.split(",").map((number) => `${prefix}${number}`);
|
|
36
|
+
}
|
|
37
|
+
const parsedRows = new Map();
|
|
38
|
+
const aliasesOf = new WeakMap();
|
|
39
|
+
/** The objects of a string of rows, parsed once however many tables use it (the large table's Messier objects are the small table's). */
|
|
40
|
+
function parsed(rows) {
|
|
41
|
+
const found = parsedRows.get(rows);
|
|
42
|
+
if (found !== undefined)
|
|
43
|
+
return found;
|
|
44
|
+
const list = [];
|
|
45
|
+
for (const row of rows.split("\n")) {
|
|
46
|
+
const p = row.split("|");
|
|
47
|
+
const messier = p[0] === "" ? undefined : `M${p[0]}`;
|
|
48
|
+
const ngc = designations("NGC ", p[1]);
|
|
49
|
+
const ic = designations("IC ", p[2]);
|
|
50
|
+
const object = Object.freeze({
|
|
51
|
+
id: messier ?? ngc[0] ?? ic[0],
|
|
52
|
+
messier,
|
|
53
|
+
ngc: ngc[0],
|
|
54
|
+
ic: ic[0],
|
|
55
|
+
otherIds: Object.freeze([...ngc.slice(1), ...ic.slice(1)]),
|
|
56
|
+
name: p[9] === "" ? undefined : p[9],
|
|
57
|
+
type: DEEP_SKY_TYPES[Number(p[3])],
|
|
58
|
+
constellation: p[8] === "" ? undefined : p[8],
|
|
59
|
+
rightAscension: Number(p[4]) / 10000,
|
|
60
|
+
declination: Number(p[5]) / 10000,
|
|
61
|
+
magnitude: p[6] === "" ? undefined : Number(p[6]) / 100,
|
|
62
|
+
sizeArcmin: p[7] === "" ? undefined : Number(p[7]) / 10,
|
|
63
|
+
});
|
|
64
|
+
if (p[10] !== "")
|
|
65
|
+
aliasesOf.set(object, p[10].split(";"));
|
|
66
|
+
list.push(object);
|
|
67
|
+
}
|
|
68
|
+
parsedRows.set(rows, list);
|
|
69
|
+
return list;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Parse rows of the data into a table. A row is `Messier | NGC numbers | IC numbers | type | RA | Dec | magnitude | size | constellation | name | other names`, as `scripts/make-deep-sky-data.py` writes them.
|
|
73
|
+
*
|
|
74
|
+
* @param rowSets - One or more strings of rows, one object a line, in catalogue order.
|
|
75
|
+
* @returns The table.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* import { deepSkyTable } from "../src/deep-sky-core.ts";
|
|
80
|
+
*
|
|
81
|
+
* console.log(deepSkyTable(["31|224||1|106847|412688|344||And|Andromeda Galaxy|"]).all()[0]?.id);
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
export function deepSkyTable(rowSets) {
|
|
85
|
+
const stored = [];
|
|
86
|
+
const byKey = new Map();
|
|
87
|
+
const ambiguous = new Set();
|
|
88
|
+
let loaded = false;
|
|
89
|
+
function add(text, object) {
|
|
90
|
+
if (text === undefined || text === "")
|
|
91
|
+
return;
|
|
92
|
+
const k = key(text);
|
|
93
|
+
const other = byKey.get(k);
|
|
94
|
+
if (other !== undefined && other !== object) {
|
|
95
|
+
// A Messier object keeps a name that a fainter object also carries (Wikidata calls a part of Barnard's Galaxy "Ring Nebula" too).
|
|
96
|
+
if (other.messier !== undefined && object.messier === undefined)
|
|
97
|
+
return;
|
|
98
|
+
ambiguous.add(k);
|
|
99
|
+
}
|
|
100
|
+
byKey.set(k, object);
|
|
101
|
+
}
|
|
102
|
+
function load() {
|
|
103
|
+
if (loaded)
|
|
104
|
+
return;
|
|
105
|
+
loaded = true;
|
|
106
|
+
for (const rows of rowSets) {
|
|
107
|
+
for (const object of parsed(rows)) {
|
|
108
|
+
stored.push(object);
|
|
109
|
+
for (const text of [object.messier, object.ngc, object.ic, ...object.otherIds, object.name, ...(aliasesOf.get(object) ?? [])])
|
|
110
|
+
add(text, object);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
for (const k of ambiguous)
|
|
114
|
+
byKey.delete(k);
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
all: () => {
|
|
118
|
+
load();
|
|
119
|
+
return [...stored];
|
|
120
|
+
},
|
|
121
|
+
select: (options) => {
|
|
122
|
+
load();
|
|
123
|
+
const { catalogue, magnitude, type } = options;
|
|
124
|
+
if (catalogue !== undefined && !DEEP_SKY_CATALOGUES.includes(catalogue))
|
|
125
|
+
throw new RangeError(`catalogue must be "messier", "ngc" or "ic", got ${JSON.stringify(catalogue)}`);
|
|
126
|
+
if (magnitude !== undefined && (typeof magnitude !== "number" || Number.isNaN(magnitude)))
|
|
127
|
+
throw new TypeError(`magnitude must be a number, got ${String(magnitude)}`);
|
|
128
|
+
if (type !== undefined && !DEEP_SKY_TYPES.includes(type))
|
|
129
|
+
throw new RangeError(`type must be one of ${DEEP_SKY_TYPES.join(", ")}, got ${JSON.stringify(type)}`);
|
|
130
|
+
return stored.filter((o) => (catalogue === undefined || o[catalogue] !== undefined) && (type === undefined || o.type === type) && (magnitude === undefined || (o.magnitude !== undefined && o.magnitude <= magnitude)));
|
|
131
|
+
},
|
|
132
|
+
find: (text) => {
|
|
133
|
+
if (typeof text !== "string")
|
|
134
|
+
throw new TypeError(`text must be a string, got ${typeof text}`);
|
|
135
|
+
load();
|
|
136
|
+
return byKey.get(key(text));
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type DeepSkyObject, type DeepSkyOptions } from "./deep-sky-core.ts";
|
|
2
|
+
export { DEEP_SKY_CATALOGUES, DEEP_SKY_TYPES, type DeepSkyObject, type DeepSkyOptions, type DeepSkyType } from "./deep-sky-core.ts";
|
|
3
|
+
/**
|
|
4
|
+
* The Messier, NGC and IC objects that meet the options: the Messier objects first in Messier order, then the others by NGC number and then IC number. The NGC and IC objects are those Wikidata gives a
|
|
5
|
+
* position (11,788 besides the 110 Messier objects, about nine in ten of the two catalogues), and their magnitudes and types are Wikidata's as well. Magnitude is missing for about four in ten.
|
|
6
|
+
*
|
|
7
|
+
* @param options - `catalogue`: only objects with a number in `"messier"`, `"ngc"` or `"ic"`. `magnitude`: only objects as bright as that (an object with no magnitude is never in). `type`: only that kind.
|
|
8
|
+
* @returns A fresh array of the shared, frozen objects.
|
|
9
|
+
* @throws RangeError if `catalogue` or `type` is not one of the listed values. TypeError if `magnitude` is not a number.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { deepSky } from "@johnmorrisdotca/hoshi-stars/deep-sky/ngc-ic";
|
|
14
|
+
*
|
|
15
|
+
* console.log(deepSky({ catalogue: "ngc", type: "planetary nebula", magnitude: 10 }).length);
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare function deepSky(options?: DeepSkyOptions): DeepSkyObject[];
|
|
19
|
+
/**
|
|
20
|
+
* An object by any of its names, ignoring case, spacing and the accent on a letter: `M31`, `Messier 31`, `NGC 224`, `IC 434`, an object's other NGC or IC number (`NGC 1051` for `NGC 961`) or its common
|
|
21
|
+
* name in English (`North America Nebula`). A name that two objects share finds neither, except that a Messier object keeps its name.
|
|
22
|
+
*
|
|
23
|
+
* @param text - The designation or name.
|
|
24
|
+
* @returns The object, or `undefined` if the text names none.
|
|
25
|
+
* @throws TypeError if `text` is not a string.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* import { deepSkyObject } from "@johnmorrisdotca/hoshi-stars/deep-sky/ngc-ic";
|
|
30
|
+
*
|
|
31
|
+
* console.log(deepSkyObject("IC 434")?.type, deepSkyObject("NGC 7000")?.name, deepSkyObject("Andromeda Galaxy")?.id);
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare function deepSkyObject(text: string): DeepSkyObject | undefined;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// The Messier, NGC and IC objects that Wikidata gives a position: 11,898 in all. The large deep-sky tier (`@johnmorrisdotca/hoshi-stars/deep-sky/ngc-ic`): the table is about 150 kB gzipped, so it is its own
|
|
2
|
+
// import and the Messier-only `@johnmorrisdotca/hoshi-stars/deep-sky` stays small. Pure: no DOM, no clock, no state beyond the parsed table.
|
|
3
|
+
import { MESSIER_ROWS } from "./data/messier.js";
|
|
4
|
+
import { NGC_IC_ROWS } from "./data/ngc-ic.js";
|
|
5
|
+
import { deepSkyTable } from "./deep-sky-core.js";
|
|
6
|
+
export { DEEP_SKY_CATALOGUES, DEEP_SKY_TYPES } from "./deep-sky-core.js";
|
|
7
|
+
const table = deepSkyTable([MESSIER_ROWS, NGC_IC_ROWS]);
|
|
8
|
+
/**
|
|
9
|
+
* The Messier, NGC and IC objects that meet the options: the Messier objects first in Messier order, then the others by NGC number and then IC number. The NGC and IC objects are those Wikidata gives a
|
|
10
|
+
* position (11,788 besides the 110 Messier objects, about nine in ten of the two catalogues), and their magnitudes and types are Wikidata's as well. Magnitude is missing for about four in ten.
|
|
11
|
+
*
|
|
12
|
+
* @param options - `catalogue`: only objects with a number in `"messier"`, `"ngc"` or `"ic"`. `magnitude`: only objects as bright as that (an object with no magnitude is never in). `type`: only that kind.
|
|
13
|
+
* @returns A fresh array of the shared, frozen objects.
|
|
14
|
+
* @throws RangeError if `catalogue` or `type` is not one of the listed values. TypeError if `magnitude` is not a number.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { deepSky } from "@johnmorrisdotca/hoshi-stars/deep-sky/ngc-ic";
|
|
19
|
+
*
|
|
20
|
+
* console.log(deepSky({ catalogue: "ngc", type: "planetary nebula", magnitude: 10 }).length);
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export function deepSky(options = {}) {
|
|
24
|
+
return table.select(options);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* An object by any of its names, ignoring case, spacing and the accent on a letter: `M31`, `Messier 31`, `NGC 224`, `IC 434`, an object's other NGC or IC number (`NGC 1051` for `NGC 961`) or its common
|
|
28
|
+
* name in English (`North America Nebula`). A name that two objects share finds neither, except that a Messier object keeps its name.
|
|
29
|
+
*
|
|
30
|
+
* @param text - The designation or name.
|
|
31
|
+
* @returns The object, or `undefined` if the text names none.
|
|
32
|
+
* @throws TypeError if `text` is not a string.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* import { deepSkyObject } from "@johnmorrisdotca/hoshi-stars/deep-sky/ngc-ic";
|
|
37
|
+
*
|
|
38
|
+
* console.log(deepSkyObject("IC 434")?.type, deepSkyObject("NGC 7000")?.name, deepSkyObject("Andromeda Galaxy")?.id);
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export function deepSkyObject(text) {
|
|
42
|
+
return table.find(text);
|
|
43
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type DeepSkyObject, type DeepSkyOptions } from "./deep-sky-core.ts";
|
|
2
|
+
export { DEEP_SKY_CATALOGUES, DEEP_SKY_TYPES, type DeepSkyObject, type DeepSkyOptions, type DeepSkyType } from "./deep-sky-core.ts";
|
|
3
|
+
/**
|
|
4
|
+
* The 110 Messier objects, M1 first and M110 last. M102 is the one the literature disagrees about: Messier's own description matches M101 (a repeat of it), and the modern lists take it for the
|
|
5
|
+
* lenticular galaxy NGC 5866, which is what this table does (a note on M102 is in `NOTICE.md`). M40 (Winnecke 4, a double star) and M73 (four stars) are in the list as `other`, since Messier
|
|
6
|
+
* listed them.
|
|
7
|
+
*
|
|
8
|
+
* @returns A fresh array of the shared, frozen objects.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { messier } from "@johnmorrisdotca/hoshi-stars/deep-sky";
|
|
13
|
+
*
|
|
14
|
+
* console.log(messier().length, messier()[30]?.name);
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare function messier(): DeepSkyObject[];
|
|
18
|
+
/**
|
|
19
|
+
* The Messier objects that meet the options, in Messier order. For the NGC and IC objects too, use `deepSky` from `@johnmorrisdotca/hoshi-stars/deep-sky/ngc-ic`.
|
|
20
|
+
*
|
|
21
|
+
* @param options - `catalogue`: only objects with a number in `"messier"`, `"ngc"` or `"ic"` (here 110, 106 and 3: M24 and M25 have only an IC number, and M40 and M45 have none). `magnitude`: only objects as
|
|
22
|
+
* bright as that. `type`: only that kind (`"galaxy"`, `"globular cluster"`, `"open cluster"`, `"nebula"`, `"planetary nebula"`, `"supernova remnant"` or `"other"`).
|
|
23
|
+
* @returns A fresh array of the shared, frozen objects.
|
|
24
|
+
* @throws RangeError if `catalogue` or `type` is not one of those. TypeError if `magnitude` is not a number.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* import { deepSky } from "@johnmorrisdotca/hoshi-stars/deep-sky";
|
|
29
|
+
*
|
|
30
|
+
* console.log(deepSky({ type: "globular cluster", magnitude: 6.5 }).map((o) => o.id));
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare function deepSky(options?: DeepSkyOptions): DeepSkyObject[];
|
|
34
|
+
/**
|
|
35
|
+
* A Messier object by any of its names, ignoring case, spacing and the accent on a letter: the Messier designation (`M31`, `m 31`, `Messier 31`), its NGC or IC designation (`NGC 224`, `ngc224`) or its
|
|
36
|
+
* common name in English (`Andromeda Galaxy`, `Andromeda Nebula`). A name that two objects share finds neither, except that a Messier object keeps its name.
|
|
37
|
+
*
|
|
38
|
+
* @param text - The designation or name.
|
|
39
|
+
* @returns The object, or `undefined` if the text names none of the Messier objects.
|
|
40
|
+
* @throws TypeError if `text` is not a string.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* import { deepSkyObject } from "@johnmorrisdotca/hoshi-stars/deep-sky";
|
|
45
|
+
*
|
|
46
|
+
* console.log(deepSkyObject("M31")?.ngc, deepSkyObject("Crab Nebula")?.id, deepSkyObject("NGC 1976")?.name);
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare function deepSkyObject(text: string): DeepSkyObject | undefined;
|
package/dist/deep-sky.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// The 110 Messier objects, and the lookups for them. The deep-sky tier (`@johnmorrisdotca/hoshi-stars/deep-sky`): a table of about 3 kB gzipped. The NGC and IC objects, about 150 kB more, are the
|
|
2
|
+
// separate `@johnmorrisdotca/hoshi-stars/deep-sky/ngc-ic`, so a page that wants the Messier objects pays for them only. Pure: no DOM, no clock, no state beyond the parsed table.
|
|
3
|
+
import { MESSIER_ROWS } from "./data/messier.js";
|
|
4
|
+
import { deepSkyTable } from "./deep-sky-core.js";
|
|
5
|
+
export { DEEP_SKY_CATALOGUES, DEEP_SKY_TYPES } from "./deep-sky-core.js";
|
|
6
|
+
const table = deepSkyTable([MESSIER_ROWS]);
|
|
7
|
+
/**
|
|
8
|
+
* The 110 Messier objects, M1 first and M110 last. M102 is the one the literature disagrees about: Messier's own description matches M101 (a repeat of it), and the modern lists take it for the
|
|
9
|
+
* lenticular galaxy NGC 5866, which is what this table does (a note on M102 is in `NOTICE.md`). M40 (Winnecke 4, a double star) and M73 (four stars) are in the list as `other`, since Messier
|
|
10
|
+
* listed them.
|
|
11
|
+
*
|
|
12
|
+
* @returns A fresh array of the shared, frozen objects.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { messier } from "@johnmorrisdotca/hoshi-stars/deep-sky";
|
|
17
|
+
*
|
|
18
|
+
* console.log(messier().length, messier()[30]?.name);
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export function messier() {
|
|
22
|
+
return table.all();
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* The Messier objects that meet the options, in Messier order. For the NGC and IC objects too, use `deepSky` from `@johnmorrisdotca/hoshi-stars/deep-sky/ngc-ic`.
|
|
26
|
+
*
|
|
27
|
+
* @param options - `catalogue`: only objects with a number in `"messier"`, `"ngc"` or `"ic"` (here 110, 106 and 3: M24 and M25 have only an IC number, and M40 and M45 have none). `magnitude`: only objects as
|
|
28
|
+
* bright as that. `type`: only that kind (`"galaxy"`, `"globular cluster"`, `"open cluster"`, `"nebula"`, `"planetary nebula"`, `"supernova remnant"` or `"other"`).
|
|
29
|
+
* @returns A fresh array of the shared, frozen objects.
|
|
30
|
+
* @throws RangeError if `catalogue` or `type` is not one of those. TypeError if `magnitude` is not a number.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* import { deepSky } from "@johnmorrisdotca/hoshi-stars/deep-sky";
|
|
35
|
+
*
|
|
36
|
+
* console.log(deepSky({ type: "globular cluster", magnitude: 6.5 }).map((o) => o.id));
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export function deepSky(options = {}) {
|
|
40
|
+
return table.select(options);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* A Messier object by any of its names, ignoring case, spacing and the accent on a letter: the Messier designation (`M31`, `m 31`, `Messier 31`), its NGC or IC designation (`NGC 224`, `ngc224`) or its
|
|
44
|
+
* common name in English (`Andromeda Galaxy`, `Andromeda Nebula`). A name that two objects share finds neither, except that a Messier object keeps its name.
|
|
45
|
+
*
|
|
46
|
+
* @param text - The designation or name.
|
|
47
|
+
* @returns The object, or `undefined` if the text names none of the Messier objects.
|
|
48
|
+
* @throws TypeError if `text` is not a string.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* import { deepSkyObject } from "@johnmorrisdotca/hoshi-stars/deep-sky";
|
|
53
|
+
*
|
|
54
|
+
* console.log(deepSkyObject("M31")?.ngc, deepSkyObject("Crab Nebula")?.id, deepSkyObject("NGC 1976")?.name);
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export function deepSkyObject(text) {
|
|
58
|
+
return table.find(text);
|
|
59
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// The entry point: the bright stars. Constellations, deep-sky objects and charts will be their own entry points, so a page pays only for what it imports.
|
|
2
|
+
export { blackBodyColour, starByHr, starByName, starColour, starDistanceLightYears, starPosition, starTemperatureK, stars } from "./stars.js";
|
package/dist/lines.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type Constellation } from "./constellations.ts";
|
|
2
|
+
import { type Star } from "./stars.ts";
|
|
3
|
+
/**
|
|
4
|
+
* The stick figure of one constellation.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { figureOf, type Figure } from "@johnmorrisdotca/hoshi-stars/lines";
|
|
9
|
+
*
|
|
10
|
+
* const orion: Figure = figureOf("Ori");
|
|
11
|
+
* console.log(orion.constellation.name, orion.stars.length, orion.segments.length);
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export interface Figure {
|
|
15
|
+
/** The constellation the figure is drawn in. */
|
|
16
|
+
constellation: Constellation;
|
|
17
|
+
/** The stars the figure uses, each once, in the order the figure first reaches them. */
|
|
18
|
+
stars: Star[];
|
|
19
|
+
/** The lines to draw, each a pair of stars of the constellation, no pair twice. Empty where the figure is one star. */
|
|
20
|
+
segments: Array<[Star, Star]>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The stick figures of all 88 constellations, in the order of `constellations()` (alphabetical by Latin name).
|
|
24
|
+
*
|
|
25
|
+
* @returns A fresh array of the shared, frozen figures.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* import { figures } from "@johnmorrisdotca/hoshi-stars/lines";
|
|
30
|
+
*
|
|
31
|
+
* console.log(figures().length, figures().reduce((sum, f) => sum + f.segments.length, 0));
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare function figures(): Figure[];
|
|
35
|
+
/**
|
|
36
|
+
* The stick figure of one constellation: the bright stars to join, as pairs. Every star of a pair lies inside the constellation, so a chart can draw one figure without crossing into another.
|
|
37
|
+
*
|
|
38
|
+
* @param text - The constellation, as the IAU abbreviation (`Ori`) or any other name `constellation` accepts.
|
|
39
|
+
* @returns The shared, frozen figure.
|
|
40
|
+
* @throws TypeError if `text` is not a string. RangeError if it is not one of the 88 constellations.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* import { figureOf } from "@johnmorrisdotca/hoshi-stars/lines";
|
|
45
|
+
*
|
|
46
|
+
* for (const [a, b] of figureOf("Great Bear").segments) console.log(a.name ?? a.designation, "to", b.name ?? b.designation);
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare function figureOf(text: string): Figure;
|
package/dist/lines.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// The stick figures of the 88 constellations, as pairs of bright stars to join with a line.
|
|
2
|
+
// The lines tier (`@johnmorrisdotca/hoshi-stars/lines`): about 2 kB of data gzipped, on top of the constellations table and the bright-star table it points into. Pure: no DOM, no state beyond the parsed table.
|
|
3
|
+
// The figures are our own, decided from the stars' positions and brightness; none is copied from a book, an atlas or another program's files.
|
|
4
|
+
import { LINE_ROWS } from "./data/lines.js";
|
|
5
|
+
import { constellation, constellations } from "./constellations.js";
|
|
6
|
+
import { starByHr } from "./stars.js";
|
|
7
|
+
const stored = new Map();
|
|
8
|
+
function load() {
|
|
9
|
+
if (stored.size > 0)
|
|
10
|
+
return;
|
|
11
|
+
const byAbbreviation = new Map(constellations().map((c) => [c.abbreviation, c]));
|
|
12
|
+
for (const row of LINE_ROWS.split("\n")) {
|
|
13
|
+
const [abbreviation, chains] = row.split("|");
|
|
14
|
+
const used = new Map();
|
|
15
|
+
const segments = [];
|
|
16
|
+
for (const chain of chains.split(";")) {
|
|
17
|
+
const members = chain.split("-").map((hr) => {
|
|
18
|
+
const star = starByHr(Number(hr));
|
|
19
|
+
used.set(star.hr, star);
|
|
20
|
+
return star;
|
|
21
|
+
});
|
|
22
|
+
for (let i = 1; i < members.length; i++)
|
|
23
|
+
segments.push(Object.freeze([members[i - 1], members[i]]));
|
|
24
|
+
}
|
|
25
|
+
stored.set(abbreviation, Object.freeze({ constellation: byAbbreviation.get(abbreviation), stars: Object.freeze([...used.values()]), segments: Object.freeze(segments) }));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The stick figures of all 88 constellations, in the order of `constellations()` (alphabetical by Latin name).
|
|
30
|
+
*
|
|
31
|
+
* @returns A fresh array of the shared, frozen figures.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* import { figures } from "@johnmorrisdotca/hoshi-stars/lines";
|
|
36
|
+
*
|
|
37
|
+
* console.log(figures().length, figures().reduce((sum, f) => sum + f.segments.length, 0));
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export function figures() {
|
|
41
|
+
load();
|
|
42
|
+
return constellations().map((c) => stored.get(c.abbreviation));
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The stick figure of one constellation: the bright stars to join, as pairs. Every star of a pair lies inside the constellation, so a chart can draw one figure without crossing into another.
|
|
46
|
+
*
|
|
47
|
+
* @param text - The constellation, as the IAU abbreviation (`Ori`) or any other name `constellation` accepts.
|
|
48
|
+
* @returns The shared, frozen figure.
|
|
49
|
+
* @throws TypeError if `text` is not a string. RangeError if it is not one of the 88 constellations.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* import { figureOf } from "@johnmorrisdotca/hoshi-stars/lines";
|
|
54
|
+
*
|
|
55
|
+
* for (const [a, b] of figureOf("Great Bear").segments) console.log(a.name ?? a.designation, "to", b.name ?? b.designation);
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export function figureOf(text) {
|
|
59
|
+
const found = constellation(text);
|
|
60
|
+
if (found === undefined)
|
|
61
|
+
throw new RangeError(`"${text}" is not one of the 88 constellations (use the IAU abbreviation such as "Ori")`);
|
|
62
|
+
load();
|
|
63
|
+
return stored.get(found.abbreviation);
|
|
64
|
+
}
|