mihrab-methods 0.0.0-stage → 1.0.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/LICENSE +373 -0
- package/README.md +319 -2
- package/certification.json +120 -0
- package/data/corrections/algeria.json +784 -0
- package/data/corrections/diyanet.json +18444 -0
- package/data/corrections/indonesia.json +210 -0
- package/data/corrections/morocco.json +993 -0
- package/data/corrections/sweden.json +516 -0
- package/dist/cjs/algeria.d.ts +4 -0
- package/dist/cjs/algeria.js +22 -0
- package/dist/cjs/authorities/algeria.d.ts +3 -0
- package/dist/cjs/authorities/algeria.js +57 -0
- package/dist/cjs/authorities/diyanet.d.ts +9 -0
- package/dist/cjs/authorities/diyanet.js +90 -0
- package/dist/cjs/authorities/indonesia.d.ts +4 -0
- package/dist/cjs/authorities/indonesia.js +82 -0
- package/dist/cjs/authorities/morocco.d.ts +5 -0
- package/dist/cjs/authorities/morocco.js +65 -0
- package/dist/cjs/authorities/slug.d.ts +2 -0
- package/dist/cjs/authorities/slug.js +17 -0
- package/dist/cjs/authorities/sweden.d.ts +3 -0
- package/dist/cjs/authorities/sweden.js +58 -0
- package/dist/cjs/core/api.d.ts +61 -0
- package/dist/cjs/core/api.js +176 -0
- package/dist/cjs/core/civilDate.d.ts +17 -0
- package/dist/cjs/core/civilDate.js +41 -0
- package/dist/cjs/core/clock.d.ts +15 -0
- package/dist/cjs/core/clock.js +46 -0
- package/dist/cjs/core/compute.d.ts +10 -0
- package/dist/cjs/core/compute.js +59 -0
- package/dist/cjs/core/correctionList.d.ts +25 -0
- package/dist/cjs/core/correctionList.js +62 -0
- package/dist/cjs/core/fetchLatest.d.ts +57 -0
- package/dist/cjs/core/fetchLatest.js +137 -0
- package/dist/cjs/core/index.d.ts +14 -0
- package/dist/cjs/core/index.js +45 -0
- package/dist/cjs/core/registry.d.ts +28 -0
- package/dist/cjs/core/registry.js +29 -0
- package/dist/cjs/core/types.d.ts +193 -0
- package/dist/cjs/core/types.js +22 -0
- package/dist/cjs/core.d.ts +2 -0
- package/dist/cjs/core.js +18 -0
- package/dist/cjs/data/generated/algeriaCertification.d.ts +3 -0
- package/dist/cjs/data/generated/algeriaCertification.js +4 -0
- package/dist/cjs/data/generated/algeriaCities.d.ts +8 -0
- package/dist/cjs/data/generated/algeriaCities.js +5 -0
- package/dist/cjs/data/generated/algeriaCorrections.d.ts +3 -0
- package/dist/cjs/data/generated/algeriaCorrections.js +4 -0
- package/dist/cjs/data/generated/algeriaMethodPoints.d.ts +2 -0
- package/dist/cjs/data/generated/algeriaMethodPoints.js +5 -0
- package/dist/cjs/data/generated/countryOutlines.d.ts +5 -0
- package/dist/cjs/data/generated/countryOutlines.js +5 -0
- package/dist/cjs/data/generated/diyanetCertification.d.ts +3 -0
- package/dist/cjs/data/generated/diyanetCertification.js +4 -0
- package/dist/cjs/data/generated/diyanetCorrections.d.ts +3 -0
- package/dist/cjs/data/generated/diyanetCorrections.js +4 -0
- package/dist/cjs/data/generated/diyanetCountries.d.ts +5 -0
- package/dist/cjs/data/generated/diyanetCountries.js +5 -0
- package/dist/cjs/data/generated/diyanetTurkeyPoints.d.ts +7 -0
- package/dist/cjs/data/generated/diyanetTurkeyPoints.js +5 -0
- package/dist/cjs/data/generated/diyanetWorldPoints.d.ts +10 -0
- package/dist/cjs/data/generated/diyanetWorldPoints.js +5 -0
- package/dist/cjs/data/generated/indonesiaCertification.d.ts +3 -0
- package/dist/cjs/data/generated/indonesiaCertification.js +4 -0
- package/dist/cjs/data/generated/indonesiaCorrections.d.ts +3 -0
- package/dist/cjs/data/generated/indonesiaCorrections.js +4 -0
- package/dist/cjs/data/generated/kemenagMethodPoints.d.ts +2 -0
- package/dist/cjs/data/generated/kemenagMethodPoints.js +5 -0
- package/dist/cjs/data/generated/kemenagPlaces.d.ts +8 -0
- package/dist/cjs/data/generated/kemenagPlaces.js +5 -0
- package/dist/cjs/data/generated/moroccoCertification.d.ts +3 -0
- package/dist/cjs/data/generated/moroccoCertification.js +4 -0
- package/dist/cjs/data/generated/moroccoCities.d.ts +8 -0
- package/dist/cjs/data/generated/moroccoCities.js +5 -0
- package/dist/cjs/data/generated/moroccoCorrections.d.ts +3 -0
- package/dist/cjs/data/generated/moroccoCorrections.js +4 -0
- package/dist/cjs/data/generated/moroccoMethodPoints.d.ts +2 -0
- package/dist/cjs/data/generated/moroccoMethodPoints.js +5 -0
- package/dist/cjs/data/generated/swedenCertification.d.ts +3 -0
- package/dist/cjs/data/generated/swedenCertification.js +4 -0
- package/dist/cjs/data/generated/swedenCorrections.d.ts +3 -0
- package/dist/cjs/data/generated/swedenCorrections.js +4 -0
- package/dist/cjs/data/generated/swedenPlaces.d.ts +5 -0
- package/dist/cjs/data/generated/swedenPlaces.js +5 -0
- package/dist/cjs/diyanet.d.ts +4 -0
- package/dist/cjs/diyanet.js +22 -0
- package/dist/cjs/index.d.ts +19 -0
- package/dist/cjs/index.js +37 -0
- package/dist/cjs/indonesia.d.ts +4 -0
- package/dist/cjs/indonesia.js +22 -0
- package/dist/cjs/locate.d.ts +21 -0
- package/dist/cjs/locate.js +204 -0
- package/dist/cjs/methods/algeria.d.ts +56 -0
- package/dist/cjs/methods/algeria.js +119 -0
- package/dist/cjs/methods/indonesia.d.ts +31 -0
- package/dist/cjs/methods/indonesia.js +94 -0
- package/dist/cjs/methods/morocco.d.ts +61 -0
- package/dist/cjs/methods/morocco.js +113 -0
- package/dist/cjs/methods/revisions.d.ts +15 -0
- package/dist/cjs/methods/revisions.js +18 -0
- package/dist/cjs/methods/scratch-congress.d.ts +87 -0
- package/dist/cjs/methods/scratch-congress.js +539 -0
- package/dist/cjs/methods/sweden.d.ts +88 -0
- package/dist/cjs/methods/sweden.js +568 -0
- package/dist/cjs/morocco.d.ts +4 -0
- package/dist/cjs/morocco.js +22 -0
- package/dist/cjs/sun/preciseSun.d.ts +19 -0
- package/dist/cjs/sun/preciseSun.js +185 -0
- package/dist/cjs/sweden.d.ts +4 -0
- package/dist/cjs/sweden.js +22 -0
- package/dist/esm/algeria.d.ts +4 -0
- package/dist/esm/algeria.js +4 -0
- package/dist/esm/authorities/algeria.d.ts +3 -0
- package/dist/esm/authorities/algeria.js +51 -0
- package/dist/esm/authorities/diyanet.d.ts +9 -0
- package/dist/esm/authorities/diyanet.js +83 -0
- package/dist/esm/authorities/indonesia.d.ts +4 -0
- package/dist/esm/authorities/indonesia.js +75 -0
- package/dist/esm/authorities/morocco.d.ts +5 -0
- package/dist/esm/authorities/morocco.js +59 -0
- package/dist/esm/authorities/slug.d.ts +2 -0
- package/dist/esm/authorities/slug.js +14 -0
- package/dist/esm/authorities/sweden.d.ts +3 -0
- package/dist/esm/authorities/sweden.js +52 -0
- package/dist/esm/core/api.d.ts +61 -0
- package/dist/esm/core/api.js +162 -0
- package/dist/esm/core/civilDate.d.ts +17 -0
- package/dist/esm/core/civilDate.js +36 -0
- package/dist/esm/core/clock.d.ts +15 -0
- package/dist/esm/core/clock.js +39 -0
- package/dist/esm/core/compute.d.ts +10 -0
- package/dist/esm/core/compute.js +56 -0
- package/dist/esm/core/correctionList.d.ts +25 -0
- package/dist/esm/core/correctionList.js +56 -0
- package/dist/esm/core/fetchLatest.d.ts +57 -0
- package/dist/esm/core/fetchLatest.js +98 -0
- package/dist/esm/core/index.d.ts +14 -0
- package/dist/esm/core/index.js +14 -0
- package/dist/esm/core/registry.d.ts +28 -0
- package/dist/esm/core/registry.js +23 -0
- package/dist/esm/core/types.d.ts +193 -0
- package/dist/esm/core/types.js +18 -0
- package/dist/esm/core.d.ts +2 -0
- package/dist/esm/core.js +2 -0
- package/dist/esm/data/generated/algeriaCertification.d.ts +3 -0
- package/dist/esm/data/generated/algeriaCertification.js +2 -0
- package/dist/esm/data/generated/algeriaCities.d.ts +8 -0
- package/dist/esm/data/generated/algeriaCities.js +3 -0
- package/dist/esm/data/generated/algeriaCorrections.d.ts +3 -0
- package/dist/esm/data/generated/algeriaCorrections.js +2 -0
- package/dist/esm/data/generated/algeriaMethodPoints.d.ts +2 -0
- package/dist/esm/data/generated/algeriaMethodPoints.js +3 -0
- package/dist/esm/data/generated/countryOutlines.d.ts +5 -0
- package/dist/esm/data/generated/countryOutlines.js +3 -0
- package/dist/esm/data/generated/diyanetCertification.d.ts +3 -0
- package/dist/esm/data/generated/diyanetCertification.js +2 -0
- package/dist/esm/data/generated/diyanetCorrections.d.ts +3 -0
- package/dist/esm/data/generated/diyanetCorrections.js +2 -0
- package/dist/esm/data/generated/diyanetCountries.d.ts +5 -0
- package/dist/esm/data/generated/diyanetCountries.js +3 -0
- package/dist/esm/data/generated/diyanetTurkeyPoints.d.ts +7 -0
- package/dist/esm/data/generated/diyanetTurkeyPoints.js +3 -0
- package/dist/esm/data/generated/diyanetWorldPoints.d.ts +10 -0
- package/dist/esm/data/generated/diyanetWorldPoints.js +3 -0
- package/dist/esm/data/generated/indonesiaCertification.d.ts +3 -0
- package/dist/esm/data/generated/indonesiaCertification.js +2 -0
- package/dist/esm/data/generated/indonesiaCorrections.d.ts +3 -0
- package/dist/esm/data/generated/indonesiaCorrections.js +2 -0
- package/dist/esm/data/generated/kemenagMethodPoints.d.ts +2 -0
- package/dist/esm/data/generated/kemenagMethodPoints.js +3 -0
- package/dist/esm/data/generated/kemenagPlaces.d.ts +8 -0
- package/dist/esm/data/generated/kemenagPlaces.js +3 -0
- package/dist/esm/data/generated/moroccoCertification.d.ts +3 -0
- package/dist/esm/data/generated/moroccoCertification.js +2 -0
- package/dist/esm/data/generated/moroccoCities.d.ts +8 -0
- package/dist/esm/data/generated/moroccoCities.js +3 -0
- package/dist/esm/data/generated/moroccoCorrections.d.ts +3 -0
- package/dist/esm/data/generated/moroccoCorrections.js +2 -0
- package/dist/esm/data/generated/moroccoMethodPoints.d.ts +2 -0
- package/dist/esm/data/generated/moroccoMethodPoints.js +3 -0
- package/dist/esm/data/generated/swedenCertification.d.ts +3 -0
- package/dist/esm/data/generated/swedenCertification.js +2 -0
- package/dist/esm/data/generated/swedenCorrections.d.ts +3 -0
- package/dist/esm/data/generated/swedenCorrections.js +2 -0
- package/dist/esm/data/generated/swedenPlaces.d.ts +5 -0
- package/dist/esm/data/generated/swedenPlaces.js +3 -0
- package/dist/esm/diyanet.d.ts +4 -0
- package/dist/esm/diyanet.js +4 -0
- package/dist/esm/index.d.ts +19 -0
- package/dist/esm/index.js +19 -0
- package/dist/esm/indonesia.d.ts +4 -0
- package/dist/esm/indonesia.js +4 -0
- package/dist/esm/locate.d.ts +21 -0
- package/dist/esm/locate.js +196 -0
- package/dist/esm/methods/algeria.d.ts +56 -0
- package/dist/esm/methods/algeria.js +114 -0
- package/dist/esm/methods/indonesia.d.ts +31 -0
- package/dist/esm/methods/indonesia.js +90 -0
- package/dist/esm/methods/morocco.d.ts +61 -0
- package/dist/esm/methods/morocco.js +107 -0
- package/dist/esm/methods/revisions.d.ts +15 -0
- package/dist/esm/methods/revisions.js +15 -0
- package/dist/esm/methods/scratch-congress.d.ts +87 -0
- package/dist/esm/methods/scratch-congress.js +534 -0
- package/dist/esm/methods/sweden.d.ts +88 -0
- package/dist/esm/methods/sweden.js +563 -0
- package/dist/esm/morocco.d.ts +4 -0
- package/dist/esm/morocco.js +4 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/sun/preciseSun.d.ts +19 -0
- package/dist/esm/sun/preciseSun.js +181 -0
- package/dist/esm/sweden.d.ts +4 -0
- package/dist/esm/sweden.js +4 -0
- package/docs/methods.md +190 -0
- package/package.json +178 -4
- package/schemas/certification.schema.json +59 -0
- package/schemas/corrections.schema.json +29 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A precise apparent Sun: the Earth's VSOP87 series (truncated), IAU 2006
|
|
3
|
+
* precession, IAU 2000B nutation and light time, after Don Cross's
|
|
4
|
+
* Astronomy Engine (MIT licence). It agrees with JPL DE421 to about 0.05 s
|
|
5
|
+
* in the equation of time and 0.5″ in declination, where Meeus's short
|
|
6
|
+
* series (`meeusApparentSun`) drifts by about a second over the year —
|
|
7
|
+
* enough to move a published minute.
|
|
8
|
+
*/
|
|
9
|
+
const ASEC2RAD = 4.848136811095359935899141e-6;
|
|
10
|
+
const ASEC360 = 1296000;
|
|
11
|
+
const DEG = Math.PI / 180;
|
|
12
|
+
const C_AUDAY = 173.1446326846693;
|
|
13
|
+
const DAYS_PER_MILLENNIUM = 365250;
|
|
14
|
+
/** Heliocentric ecliptic (J2000) longitude, latitude and radius of the Earth: [ampl, phase, freq] per power of t. */
|
|
15
|
+
const EARTH = [
|
|
16
|
+
[
|
|
17
|
+
[
|
|
18
|
+
[1.75347045673, 0, 0], [0.03341656453, 4.66925680415, 6283.0758499914], [0.00034894275, 4.62610242189, 12566.1516999828],
|
|
19
|
+
[0.00003417572, 2.82886579754, 3.523118349], [0.00003497056, 2.74411783405, 5753.3848848968], [0.00003135899, 3.62767041756, 77713.7714681205],
|
|
20
|
+
[0.00002676218, 4.41808345438, 7860.4193924392], [0.00002342691, 6.13516214446, 3930.2096962196], [0.00001273165, 2.03709657878, 529.6909650946],
|
|
21
|
+
[0.00001324294, 0.74246341673, 11506.7697697936], [0.00000901854, 2.04505446477, 26.2983197998], [0.00001199167, 1.10962946234, 1577.3435424478],
|
|
22
|
+
[0.00000857223, 3.50849152283, 398.1490034082], [0.00000779786, 1.17882681962, 5223.6939198022], [0.0000099025, 5.23268072088, 5884.9268465832],
|
|
23
|
+
[0.00000753141, 2.53339052847, 5507.5532386674], [0.00000505267, 4.58292599973, 18849.2275499742], [0.00000492392, 4.20505711826, 775.522611324],
|
|
24
|
+
[0.00000356672, 2.91954114478, 0.0673103028], [0.00000284125, 1.89869240932, 796.2980068164], [0.00000242879, 0.34481445893, 5486.777843175],
|
|
25
|
+
[0.00000317087, 5.84901948512, 11790.6290886588], [0.00000271112, 0.31486255375, 10977.078804699], [0.00000206217, 4.80646631478, 2544.3144198834],
|
|
26
|
+
[0.00000205478, 1.86953770281, 5573.1428014331], [0.00000202318, 2.45767790232, 6069.7767545534], [0.00000126225, 1.08295459501, 20.7753954924],
|
|
27
|
+
[0.00000155516, 0.83306084617, 213.299095438],
|
|
28
|
+
],
|
|
29
|
+
[[6283.0758499914, 0, 0], [0.00206058863, 2.67823455808, 6283.0758499914], [0.00004303419, 2.63512233481, 12566.1516999828]],
|
|
30
|
+
[[0.00008721859, 1.07253635559, 6283.0758499914]],
|
|
31
|
+
],
|
|
32
|
+
[[], [[0.00227777722, 3.4137662053, 6283.0758499914], [0.00003805678, 3.37063423795, 12566.1516999828]]],
|
|
33
|
+
[
|
|
34
|
+
[
|
|
35
|
+
[1.00013988784, 0, 0], [0.01670699632, 3.09846350258, 6283.0758499914], [0.00013956024, 3.05524609456, 12566.1516999828],
|
|
36
|
+
[0.0000308372, 5.19846674381, 77713.7714681205], [0.00001628463, 1.17387558054, 5753.3848848968], [0.00001575572, 2.84685214877, 7860.4193924392],
|
|
37
|
+
[0.00000924799, 5.45292236722, 11506.7697697936], [0.00000542439, 4.56409151453, 3930.2096962196], [0.0000047211, 3.66100022149, 5884.9268465832],
|
|
38
|
+
[0.00000085831, 1.27079125277, 161000.6857376741], [0.00000057056, 2.01374292245, 83996.84731811189], [0.00000055736, 5.2415979917, 71430.69561812909],
|
|
39
|
+
[0.00000174844, 3.01193636733, 18849.2275499742], [0.00000243181, 4.2734953079, 11790.6290886588],
|
|
40
|
+
],
|
|
41
|
+
[[0.00103018607, 1.10748968172, 6283.0758499914], [0.00001721238, 1.06442300386, 12566.1516999828]],
|
|
42
|
+
[[0.00004359385, 5.78455133808, 6283.0758499914]],
|
|
43
|
+
],
|
|
44
|
+
];
|
|
45
|
+
function vsop(formula, t, clamp) {
|
|
46
|
+
let tp = 1;
|
|
47
|
+
let out = 0;
|
|
48
|
+
for (const series of formula) {
|
|
49
|
+
let sum = 0;
|
|
50
|
+
for (const [a, p, f] of series)
|
|
51
|
+
sum += a * Math.cos(p + t * f);
|
|
52
|
+
let incr = tp * sum;
|
|
53
|
+
if (clamp)
|
|
54
|
+
incr %= 2 * Math.PI;
|
|
55
|
+
out += incr;
|
|
56
|
+
tp *= t;
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
/** Earth−J2000 equatorial position (AU) at `tt` days from J2000. */
|
|
61
|
+
function earthJ2000(tt) {
|
|
62
|
+
const t = tt / DAYS_PER_MILLENNIUM;
|
|
63
|
+
const lon = vsop(EARTH[0], t, true);
|
|
64
|
+
const lat = vsop(EARTH[1], t, false);
|
|
65
|
+
const r = vsop(EARTH[2], t, false);
|
|
66
|
+
const x = r * Math.cos(lat) * Math.cos(lon);
|
|
67
|
+
const y = r * Math.cos(lat) * Math.sin(lon);
|
|
68
|
+
const z = r * Math.sin(lat);
|
|
69
|
+
return [
|
|
70
|
+
x + 0.00000044036 * y - 0.000000190919 * z,
|
|
71
|
+
-0.000000479966 * x + 0.917482137087 * y - 0.397776982902 * z,
|
|
72
|
+
0.397776982902 * y + 0.917482137087 * z,
|
|
73
|
+
];
|
|
74
|
+
}
|
|
75
|
+
/** ΔT (s), Espenak & Meeus, for UT days from J2000 — held at its 2017 value onward (about 69 s, as observed), as JPL Horizons does. */
|
|
76
|
+
export function deltaT(ut) {
|
|
77
|
+
const y = 2000 + (Math.min(ut, 17 * 365.24217) - 14) / 365.24217;
|
|
78
|
+
if (y >= 2005 && y < 2050) {
|
|
79
|
+
const u = y - 2000;
|
|
80
|
+
return 62.92 + 0.32217 * u + 0.005589 * u * u;
|
|
81
|
+
}
|
|
82
|
+
if (y >= 2050 && y < 2150) {
|
|
83
|
+
const u = (y - 1820) / 100;
|
|
84
|
+
return -20 + 32 * u * u - 0.5628 * (2150 - y);
|
|
85
|
+
}
|
|
86
|
+
if (y >= 1986 && y < 2005) {
|
|
87
|
+
const u = y - 2000;
|
|
88
|
+
return 63.86 + 0.3345 * u - 0.060374 * u ** 2 + 0.0017275 * u ** 3 + 0.000651814 * u ** 4 + 0.00002373599 * u ** 5;
|
|
89
|
+
}
|
|
90
|
+
const u = (y - 1820) / 100;
|
|
91
|
+
return -20 + 32 * u * u;
|
|
92
|
+
}
|
|
93
|
+
function nutation(tt) {
|
|
94
|
+
const mod = (x) => (x % ASEC360) * ASEC2RAD;
|
|
95
|
+
const t = tt / 36525;
|
|
96
|
+
const elp = mod(1287104.79305 + t * 129596581.0481);
|
|
97
|
+
const f = mod(335779.526232 + t * 1739527262.8478);
|
|
98
|
+
const d = mod(1072260.70369 + t * 1602961601.209);
|
|
99
|
+
const om = mod(450160.398036 - t * 6962890.5431);
|
|
100
|
+
let dp = (-172064161.0 - 174666.0 * t) * Math.sin(om) + 33386.0 * Math.cos(om);
|
|
101
|
+
let de = (92052331.0 + 9086.0 * t) * Math.cos(om) + 15377.0 * Math.sin(om);
|
|
102
|
+
let a = 2 * (f - d + om);
|
|
103
|
+
dp += (-13170906.0 - 1675.0 * t) * Math.sin(a) - 13696.0 * Math.cos(a);
|
|
104
|
+
de += (5730336.0 - 3015.0 * t) * Math.cos(a) - 4587.0 * Math.sin(a);
|
|
105
|
+
a = 2 * (f + om);
|
|
106
|
+
dp += (-2276413.0 - 234.0 * t) * Math.sin(a) + 2796.0 * Math.cos(a);
|
|
107
|
+
de += (978459.0 - 485.0 * t) * Math.cos(a) + 1374.0 * Math.sin(a);
|
|
108
|
+
a = 2 * om;
|
|
109
|
+
dp += (2074554.0 + 207.0 * t) * Math.sin(a) - 698.0 * Math.cos(a);
|
|
110
|
+
de += (-897492.0 + 470.0 * t) * Math.cos(a) - 291.0 * Math.sin(a);
|
|
111
|
+
dp += (1475877.0 - 3633.0 * t) * Math.sin(elp) + 11817.0 * Math.cos(elp);
|
|
112
|
+
de += (73871.0 - 184.0 * t) * Math.cos(elp) - 1924.0 * Math.sin(elp);
|
|
113
|
+
return { dpsi: -0.000135 + dp * 1e-7, deps: 0.000388 + de * 1e-7 };
|
|
114
|
+
}
|
|
115
|
+
function meanObliquity(tt) {
|
|
116
|
+
const t = tt / 36525;
|
|
117
|
+
return ((((-0.0000000434 * t - 0.000000576) * t + 0.0020034) * t - 0.0001831) * t - 46.836769) * t + 84381.406;
|
|
118
|
+
}
|
|
119
|
+
/** J2000 equatorial → mean equator and equinox of date (IAU 2006). */
|
|
120
|
+
function precess(v, tt) {
|
|
121
|
+
const t = tt / 36525;
|
|
122
|
+
const eps0 = 84381.406 * ASEC2RAD;
|
|
123
|
+
const psia = (((((-0.0000000951 * t + 0.000132851) * t - 0.00114045) * t - 1.0790069) * t + 5038.481507) * t) * ASEC2RAD;
|
|
124
|
+
const omegaa = (((((0.0000003337 * t - 0.000000467) * t - 0.00772503) * t + 0.0512623) * t - 0.025754) * t + 84381.406) * ASEC2RAD;
|
|
125
|
+
const chia = (((((-0.000000056 * t + 0.000170663) * t - 0.00121197) * t - 2.3814292) * t + 10.556403) * t) * ASEC2RAD;
|
|
126
|
+
const sa = Math.sin(eps0), ca = Math.cos(eps0);
|
|
127
|
+
const sb = Math.sin(-psia), cb = Math.cos(-psia);
|
|
128
|
+
const sc = Math.sin(-omegaa), cc = Math.cos(-omegaa);
|
|
129
|
+
const sd = Math.sin(chia), cd = Math.cos(chia);
|
|
130
|
+
const xx = cd * cb - sb * sd * cc;
|
|
131
|
+
const yx = cd * sb * ca + sd * cc * cb * ca - sa * sd * sc;
|
|
132
|
+
const zx = cd * sb * sa + sd * cc * cb * sa + ca * sd * sc;
|
|
133
|
+
const xy = -sd * cb - sb * cd * cc;
|
|
134
|
+
const yy = -sd * sb * ca + cd * cc * cb * ca - sa * cd * sc;
|
|
135
|
+
const zy = -sd * sb * sa + cd * cc * cb * sa + ca * cd * sc;
|
|
136
|
+
const xz = sb * sc;
|
|
137
|
+
const yz = -sc * cb * ca - sa * cc;
|
|
138
|
+
const zz = -sc * cb * sa + cc * ca;
|
|
139
|
+
return [xx * v[0] + yx * v[1] + zx * v[2], xy * v[0] + yy * v[1] + zy * v[2], xz * v[0] + yz * v[1] + zz * v[2]];
|
|
140
|
+
}
|
|
141
|
+
/** Mean → true equator and equinox of date. */
|
|
142
|
+
function nutate(v, oblm, oblt, psi) {
|
|
143
|
+
const cobm = Math.cos(oblm), sobm = Math.sin(oblm);
|
|
144
|
+
const cobt = Math.cos(oblt), sobt = Math.sin(oblt);
|
|
145
|
+
const cpsi = Math.cos(psi), spsi = Math.sin(psi);
|
|
146
|
+
const xx = cpsi;
|
|
147
|
+
const yx = -spsi * cobm;
|
|
148
|
+
const zx = -spsi * sobm;
|
|
149
|
+
const xy = spsi * cobt;
|
|
150
|
+
const yy = cpsi * cobm * cobt + sobm * sobt;
|
|
151
|
+
const zy = cpsi * sobm * cobt - cobm * sobt;
|
|
152
|
+
const xz = spsi * sobt;
|
|
153
|
+
const yz = cpsi * cobm * sobt - sobm * cobt;
|
|
154
|
+
const zz = cpsi * sobm * sobt + cobm * cobt;
|
|
155
|
+
return [xx * v[0] + yx * v[1] + zx * v[2], xy * v[0] + yy * v[1] + zy * v[2], xz * v[0] + yz * v[1] + zz * v[2]];
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* The apparent Sun at `d` days from J2000.0 (UT): declination (rad) and
|
|
159
|
+
* equation of time (minutes), such that the transit at longitude λ (east) is
|
|
160
|
+
* 720 − 4λ − eot minutes UT. Same contract as `meeusApparentSun`.
|
|
161
|
+
*/
|
|
162
|
+
export function preciseApparentSun(d) {
|
|
163
|
+
const tt = d + deltaT(d) / 86400;
|
|
164
|
+
const e = earthJ2000(tt - 1 / C_AUDAY);
|
|
165
|
+
const nut = nutation(tt);
|
|
166
|
+
const mobl = meanObliquity(tt);
|
|
167
|
+
const oblm = (mobl / 3600) * DEG;
|
|
168
|
+
const oblt = ((mobl + nut.deps) / 3600) * DEG;
|
|
169
|
+
const v = nutate(precess([-e[0], -e[1], -e[2]], tt), oblm, oblt, nut.dpsi * ASEC2RAD);
|
|
170
|
+
const ra = Math.atan2(v[1], v[0]) / DEG;
|
|
171
|
+
const dec = Math.atan2(v[2], Math.hypot(v[0], v[1]));
|
|
172
|
+
// Greenwich apparent sidereal time (degrees): Earth rotation angle + the precession and equation of the equinoxes.
|
|
173
|
+
const t = tt / 36525;
|
|
174
|
+
const era = 360 * (((0.779057273264 + 0.00273781191135448 * d + (d % 1)) % 1) + 1);
|
|
175
|
+
const eqeq = nut.dpsi * Math.cos(oblm);
|
|
176
|
+
const st = eqeq + 0.014506 + ((((-0.0000000368 * t - 0.000029956) * t - 0.00000044) * t + 1.3915817) * t + 4612.156534) * t;
|
|
177
|
+
const gast = era + st / 3600;
|
|
178
|
+
const tmin = (d - Math.floor(d + 0.5) + 0.5) * 1440; // minutes past 0h UT
|
|
179
|
+
const eotDeg = ((((gast - ra - (tmin - 720) / 4 + 180) % 360) + 360) % 360) - 180;
|
|
180
|
+
return { dec, eot: 4 * eotDeg };
|
|
181
|
+
}
|
package/docs/methods.md
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# The methods, in words and formulas
|
|
2
|
+
|
|
3
|
+
What each authority's program does, as read off its published tables, so
|
|
4
|
+
that a port in another language can do the same. The TypeScript under
|
|
5
|
+
`src/methods/` is the reference: where this page and the code differ, the
|
|
6
|
+
code is what the certification holds. `test/vectors.json` has a small sample
|
|
7
|
+
of places, dates and the times to expect, with the clock they print in.
|
|
8
|
+
|
|
9
|
+
Conventions throughout:
|
|
10
|
+
|
|
11
|
+
- Angles in degrees unless marked; φ the place's latitude, λ its longitude
|
|
12
|
+
(east positive), δ the sun's declination, E the equation of time in
|
|
13
|
+
minutes (apparent solar time less mean), T Julian centuries since J2000.0.
|
|
14
|
+
- The **hour angle** at which the sun's centre is at altitude *a*:
|
|
15
|
+
`cos H = (sin a − sin φ · sin δ) / (cos φ · cos δ)`, H in degrees, 4 minutes per degree.
|
|
16
|
+
- **Transit** (local apparent noon) in minutes past 0h UT: `720 − 4λ − E`.
|
|
17
|
+
- A time that does not form (the sun never reaches the altitude that day)
|
|
18
|
+
is null unless the method says otherwise.
|
|
19
|
+
- The **printed minute** is the instant on the table's clock. A table prints
|
|
20
|
+
the whole day in the clock kept at noon of that day, so on the morning the
|
|
21
|
+
clocks go forward a Fajr before the change is printed in the new time.
|
|
22
|
+
- Each method is followed by its **correction list**
|
|
23
|
+
(`data/corrections/<authority>.json`): the few times the authority's own
|
|
24
|
+
arithmetic puts a fraction of a second on the other side of a minute's
|
|
25
|
+
rounding point. An entry moves one printed time of one point on one date by
|
|
26
|
+
one minute. The lists are not part of the method; they are what remains
|
|
27
|
+
after it.
|
|
28
|
+
|
|
29
|
+
## Sweden and Diyanet
|
|
30
|
+
|
|
31
|
+
`src/methods/sweden.ts`. The International Prayer Times Congress method
|
|
32
|
+
(Istanbul, 2021 — the Diyanet and the European Council for Fatwa and
|
|
33
|
+
Research) as Diyanet's program realises it. Islamiska Förbundet's Swedish
|
|
34
|
+
tables are Diyanet's, row for row. Diyanet's worldwide tables are the same
|
|
35
|
+
program with Isha's angle by country.
|
|
36
|
+
|
|
37
|
+
**Published rules** (awqatsalah.com, "Tespit Kriterleri"):
|
|
38
|
+
|
|
39
|
+
- Dhuhr five minutes after transit. Asr at one shadow length, four minutes
|
|
40
|
+
late; where the shadow never forms, Asr is printed at Dhuhr's time.
|
|
41
|
+
- Sunrise seven minutes early, Maghrib seven minutes late ("temkin"), at
|
|
42
|
+
the standard −0.833°.
|
|
43
|
+
- True Fajr at −18°, true Isha at −16° (the Congress) or −17° (Diyanet's own,
|
|
44
|
+
outside the countries listed below).
|
|
45
|
+
- Neither the day nor the night is shorter than five hours.
|
|
46
|
+
- Where the 18° dawn no longer forms, the share of the night that the sharia
|
|
47
|
+
night's third took on the last day it did is carried: Isha that share of
|
|
48
|
+
the night after Maghrib, Fajr the same share scaled by 18/16 before sunrise.
|
|
49
|
+
- The move from the true times to the carried ones is gradual, starting
|
|
50
|
+
twenty minutes before (Isha) or after (Fajr) the takdir.
|
|
51
|
+
|
|
52
|
+
**What the tables do with them**, read off Diyanet's own tables for 160
|
|
53
|
+
Swedish places and 8 000 places worldwide, 2024–2027:
|
|
54
|
+
|
|
55
|
+
- The **sun is taken once a day**, at 0h UT less 45 seconds, from Meeus's
|
|
56
|
+
mean elements:
|
|
57
|
+
- `L0 = 280.46646 + 36000.76983 T + 0.0003032 T²` (mean longitude)
|
|
58
|
+
- `M = 357.52911 + 35999.05029 T − 0.0001537 T²` (mean anomaly)
|
|
59
|
+
- `C = (1.914602 − 0.004817 T − 0.000014 T²) sin M + (0.019993 − 0.000101 T) sin 2M + 0.000289 sin 3M`
|
|
60
|
+
- true longitude `λ☉ = L0 + C` (the *true*, not the apparent, longitude:
|
|
61
|
+
no aberration, no nutation in longitude);
|
|
62
|
+
- obliquity `ε = 23°26′21.448″ − 46.815″ T − 0.00059″ T² + 0.001813″ T³`
|
|
63
|
+
plus the nutation in obliquity `9.2 cos Ω + 0.57 cos 2L☉ + 0.1 cos 2L☾ − 0.09 cos 2Ω` arc-seconds,
|
|
64
|
+
with `Ω = 125.04 − 1934.136 T`, `L☉ = 280.4665 + 36000.7698 T`, `L☾ = 218.3165 + 481267.8813 T`;
|
|
65
|
+
- right ascension `α = atan2(cos ε · sin λ☉, cos λ☉)`, declination `δ = asin(sin ε · sin λ☉)`;
|
|
66
|
+
- equation of time `E = 4 (L0 − α)` minutes, wrapped to ±720, plus 0.00176 min;
|
|
67
|
+
- and two small waves in the mean longitude the formula leaves out, read
|
|
68
|
+
off the tables (`eotResidualS`, `decResidualDeg` in the code): a few
|
|
69
|
+
hundredths of a second on the transit, a tenth of an arc-second on the
|
|
70
|
+
declination. A port that omits them will be a minute off on a few times
|
|
71
|
+
in ten thousand.
|
|
72
|
+
- Coordinates are kept to **three decimals** of a degree.
|
|
73
|
+
- The night a share is taken of is the day's own: 24 h less the printed day
|
|
74
|
+
(sunrise to Maghrib, after temkin).
|
|
75
|
+
- The **five-hour floors** hold each end separately: 150 minutes from the
|
|
76
|
+
printed Dhuhr, or from the midnight after it. Where midsummer's night is
|
|
77
|
+
floored at both ends (to within a minute), that night anchors the season,
|
|
78
|
+
and the floored times never step back: before midsummer no sunrise earlier
|
|
79
|
+
than midsummer's and a floored Maghrib no earlier than the day before;
|
|
80
|
+
after it no sunrise earlier nor Maghrib later than on any day since
|
|
81
|
+
midsummer — and Fajr and Isha carried the same way.
|
|
82
|
+
- The **gradual transition** is a straight line across the days next to the
|
|
83
|
+
gap on which the true time lies within twenty minutes of the takdir at the
|
|
84
|
+
gap's edge: twenty minutes away at the far end, the takdir at the edge.
|
|
85
|
+
- Where the dawn forms all summer but midsummer's true Isha (at 16°) falls
|
|
86
|
+
later than the share carried from that night, **midsummer is the takdir's
|
|
87
|
+
day** — a gap of one day, with its ramps (from about 44.4° north).
|
|
88
|
+
- **Isha by country:** 16° in most of Europe, Russia, Ukraine, Belarus,
|
|
89
|
+
Kazakhstan, Mongolia, China, the United States and Canada; 17° elsewhere.
|
|
90
|
+
The high-latitude rules are worked at 16° either way.
|
|
91
|
+
- **Türkiye's districts** (and Northern Cyprus's): each prayer is computed at
|
|
92
|
+
a point of its own in the district, and the points move by a few
|
|
93
|
+
thousandths of a degree from one year's tables to the next
|
|
94
|
+
(`Place.prayerPoints`: a point per prayer per year; the nearest year's
|
|
95
|
+
beyond the tables).
|
|
96
|
+
- **Past local midnight:** where the first true dawn after the summer gap
|
|
97
|
+
falls before local midnight on the table's clock (far east of a zone's
|
|
98
|
+
meridian), there is no transition: the gap's last day is printed twenty
|
|
99
|
+
minutes after the takdir and the true times follow.
|
|
100
|
+
- **Tables on their own clocks:** some of Diyanet's tables are printed on a
|
|
101
|
+
clock other than their place's zone (Alberta keeping summer time, Xinjiang
|
|
102
|
+
on Beijing time, and so on); `Place.clock` gives that clock, read off the
|
|
103
|
+
table. The instants are the method's; only the labels differ.
|
|
104
|
+
- Every time is rounded to the nearest minute after the temkin.
|
|
105
|
+
|
|
106
|
+
The full algorithm — the search for the gap, the anchoring, the ramps — is
|
|
107
|
+
`CongressYear` in the code, about four hundred lines; there is no shorter
|
|
108
|
+
statement of it that gives the tables.
|
|
109
|
+
|
|
110
|
+
## Morocco
|
|
111
|
+
|
|
112
|
+
`src/methods/morocco.ts`. The Ministry of Habous and Islamic Affairs, read
|
|
113
|
+
off its tables for 164 cities.
|
|
114
|
+
|
|
115
|
+
- The sun is **Meeus's apparent sun** with the full nutation (the mean
|
|
116
|
+
elements above; apparent longitude `L0 + C − 0.00569 + Δψ`, with
|
|
117
|
+
`Δψ = −17.2 sin Ω − 1.32 sin 2L☉ − 0.23 sin 2L☾ + 0.21 sin 2Ω` arc-seconds)
|
|
118
|
+
and his chapter-28 equation of time
|
|
119
|
+
`E = L0 − 0.0057183 − α + Δψ cos ε`, taken at **each prayer's own
|
|
120
|
+
moment** (iterated), declination and equation of time alike.
|
|
121
|
+
- Fajr −19°, Isha −17°, Asr one shadow length (Shafiʿi).
|
|
122
|
+
- Dhuhr five minutes after the transit.
|
|
123
|
+
- Sunrise 2.85 minutes before, and Maghrib 3.7 minutes after, the sun's
|
|
124
|
+
upper limb on the horizon: altitude `−(34′ + s) − dip`, with s the sun's
|
|
125
|
+
semi-diameter for its distance that day and dip the city's own horizon
|
|
126
|
+
dip — eastward at sunrise (`Place.dipDeg`), westward at Maghrib
|
|
127
|
+
(`Place.dipMaghribDeg`), each fitted from the tables with the city's
|
|
128
|
+
point; where not fitted, `0.02°·√height(m)`, and 0.86 of it at Maghrib.
|
|
129
|
+
- Fajr rounded **down** to the minute, every other time to the nearest.
|
|
130
|
+
- The ministry's clock is GMT+1 until 17 September 2026 and GMT from then
|
|
131
|
+
on (`Place.clock`); the zone databases still move Morocco's clock, so the
|
|
132
|
+
table's clock is not a zone's.
|
|
133
|
+
|
|
134
|
+
## Algeria
|
|
135
|
+
|
|
136
|
+
`src/methods/algeria.ts`. The Ministry of Religious Affairs and Wakfs, read
|
|
137
|
+
off its 1448 AH table for 68 cities.
|
|
138
|
+
|
|
139
|
+
- The sun from **NOAA's solar-calculator formulas**: the mean elements above
|
|
140
|
+
with the eccentricity `e = 0.016708634 − 0.000042037 T − 0.0000001267 T²`,
|
|
141
|
+
NOAA's series for the equation of time
|
|
142
|
+
`E = 4 [ y sin 2L0 − 2e sin M + 4e y sin M cos 2L0 − ½ y² sin 4L0 − 1¼ e² sin 2M ]`
|
|
143
|
+
with `y = tan²(ε₀/2)` (the mean obliquity), and its declination from the
|
|
144
|
+
apparent longitude `L0 + C − 0.00569 − 0.00478 sin Ω` and the obliquity
|
|
145
|
+
`ε₀ + 0.00256 cos Ω`. They fit the table far better than a precise
|
|
146
|
+
ephemeris, so this is what the ministry's program uses.
|
|
147
|
+
- Dhuhr at the sun's transit, the equation of time taken there.
|
|
148
|
+
- Every other time is the transit plus or minus the hour angle, with the
|
|
149
|
+
declination taken at that prayer's own moment (three iterations) and the
|
|
150
|
+
equation of time kept at noon's value (itself iterated three times).
|
|
151
|
+
- Fajr −18°, Isha −17°, sunrise and sunset at −0.833°.
|
|
152
|
+
- Asr from the noon shadow `tan(φ − δ)` **with its sign**, so where the sun
|
|
153
|
+
culminates north of the zenith (the far south around June) Asr comes
|
|
154
|
+
earlier, up to thirteen minutes.
|
|
155
|
+
- Maghrib three minutes after sunset.
|
|
156
|
+
- Every time rounded **up** to the minute.
|
|
157
|
+
|
|
158
|
+
## Indonesia
|
|
159
|
+
|
|
160
|
+
`src/methods/indonesia.ts`. Kemenag's tables for all 517 regencies and
|
|
161
|
+
cities.
|
|
162
|
+
|
|
163
|
+
- The **precise apparent sun** (`src/sun/preciseSun.ts`: a VSOP87 series
|
|
164
|
+
after Astronomy Engine, within 0.05 s and 0.5″ of JPL's DE421), taken at
|
|
165
|
+
each prayer's own moment, iterated three times. Meeus's shorter series
|
|
166
|
+
drifts by a second and leaves a minute in two hundred off.
|
|
167
|
+
- Fajr −20°, Isha −18°.
|
|
168
|
+
- Sunrise and Maghrib at −1°, and at −2° in the regencies the ministry
|
|
169
|
+
classes as highland (`Place.highland`); in six highland regencies of Papua
|
|
170
|
+
the degree is taken off Fajr and Isha too (`Place.twilightDip`).
|
|
171
|
+
- Asr when the shadow is its length plus the noon shadow, the noon shadow
|
|
172
|
+
from the sun's declination at 00:00 UT of the day (as an almanac's daily
|
|
173
|
+
entry gives it), the hour angle from the sun at Asr (four iterations).
|
|
174
|
+
- Every time rounded **up**, after a margin: +2 minutes on Fajr, Asr,
|
|
175
|
+
Maghrib and Isha, +3 on Dhuhr, −3 on sunrise.
|
|
176
|
+
- Each regency at its own fitted point; Karawang's Asr, Maghrib and Isha at a
|
|
177
|
+
second point about 2 km north-east (`Place.afternoon`).
|
|
178
|
+
- Each regency is printed in its province's zone (WIB, WITA or WIT).
|
|
179
|
+
|
|
180
|
+
## Checking a port
|
|
181
|
+
|
|
182
|
+
1. Take `test/vectors.json`. For each case, compute the six times at the
|
|
183
|
+
given point (with the place's own fields: dips, highland class, Isha
|
|
184
|
+
angle, per-prayer points, clock) and compare the instants and the printed
|
|
185
|
+
minutes.
|
|
186
|
+
2. The vectors include the days the clocks change and a table on its own
|
|
187
|
+
clock; a port that prints the wrong day's offset shows up there.
|
|
188
|
+
3. Then apply the correction list and compare against the authority's own
|
|
189
|
+
published table for a place and a month. The list is small on purpose: if
|
|
190
|
+
a port needs more than it, the port is not the method.
|
package/package.json
CHANGED
|
@@ -1,6 +1,180 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mihrab-methods",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "The prayer-time authorities' own calculation methods, each reproducing its published timetable to the minute: Sweden (Diyanet, as Islamiska Förbundet prints it), Diyanet worldwide, Morocco (Habous), Algeria (Ministry of Religious Affairs), Indonesia (Kemenag).",
|
|
5
|
+
"license": "MPL-2.0",
|
|
6
|
+
"author": "Hassan El Ghamri",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/MihrabHQ/mihrab-methods.git"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/MihrabHQ/mihrab-methods#readme",
|
|
12
|
+
"bugs": "https://github.com/MihrabHQ/mihrab-methods/issues",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"prayer times",
|
|
15
|
+
"salah",
|
|
16
|
+
"namaz",
|
|
17
|
+
"diyanet",
|
|
18
|
+
"habous",
|
|
19
|
+
"kemenag",
|
|
20
|
+
"islamiska förbundet",
|
|
21
|
+
"adhan",
|
|
22
|
+
"mihrab"
|
|
23
|
+
],
|
|
24
|
+
"sideEffects": [
|
|
25
|
+
"./dist/*/index.js",
|
|
26
|
+
"./dist/*/sweden.js",
|
|
27
|
+
"./dist/*/diyanet.js",
|
|
28
|
+
"./dist/*/morocco.js",
|
|
29
|
+
"./dist/*/algeria.js",
|
|
30
|
+
"./dist/*/indonesia.js",
|
|
31
|
+
"./dist/*/authorities/*.js"
|
|
32
|
+
],
|
|
33
|
+
"engines": {
|
|
34
|
+
"node": ">=18"
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"dist",
|
|
38
|
+
"schemas",
|
|
39
|
+
"docs/methods.md",
|
|
40
|
+
"certification.json",
|
|
41
|
+
"data/corrections"
|
|
42
|
+
],
|
|
43
|
+
"main": "./dist/cjs/index.js",
|
|
44
|
+
"module": "./dist/esm/index.js",
|
|
45
|
+
"types": "./dist/cjs/index.d.ts",
|
|
46
|
+
"exports": {
|
|
47
|
+
".": {
|
|
48
|
+
"import": {
|
|
49
|
+
"types": "./dist/esm/index.d.ts",
|
|
50
|
+
"default": "./dist/esm/index.js"
|
|
51
|
+
},
|
|
52
|
+
"require": {
|
|
53
|
+
"types": "./dist/cjs/index.d.ts",
|
|
54
|
+
"default": "./dist/cjs/index.js"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"./core": {
|
|
58
|
+
"import": {
|
|
59
|
+
"types": "./dist/esm/core.d.ts",
|
|
60
|
+
"default": "./dist/esm/core.js"
|
|
61
|
+
},
|
|
62
|
+
"require": {
|
|
63
|
+
"types": "./dist/cjs/core.d.ts",
|
|
64
|
+
"default": "./dist/cjs/core.js"
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"./sweden": {
|
|
68
|
+
"import": {
|
|
69
|
+
"types": "./dist/esm/sweden.d.ts",
|
|
70
|
+
"default": "./dist/esm/sweden.js"
|
|
71
|
+
},
|
|
72
|
+
"require": {
|
|
73
|
+
"types": "./dist/cjs/sweden.d.ts",
|
|
74
|
+
"default": "./dist/cjs/sweden.js"
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"./diyanet": {
|
|
78
|
+
"import": {
|
|
79
|
+
"types": "./dist/esm/diyanet.d.ts",
|
|
80
|
+
"default": "./dist/esm/diyanet.js"
|
|
81
|
+
},
|
|
82
|
+
"require": {
|
|
83
|
+
"types": "./dist/cjs/diyanet.d.ts",
|
|
84
|
+
"default": "./dist/cjs/diyanet.js"
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
"./morocco": {
|
|
88
|
+
"import": {
|
|
89
|
+
"types": "./dist/esm/morocco.d.ts",
|
|
90
|
+
"default": "./dist/esm/morocco.js"
|
|
91
|
+
},
|
|
92
|
+
"require": {
|
|
93
|
+
"types": "./dist/cjs/morocco.d.ts",
|
|
94
|
+
"default": "./dist/cjs/morocco.js"
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"./algeria": {
|
|
98
|
+
"import": {
|
|
99
|
+
"types": "./dist/esm/algeria.d.ts",
|
|
100
|
+
"default": "./dist/esm/algeria.js"
|
|
101
|
+
},
|
|
102
|
+
"require": {
|
|
103
|
+
"types": "./dist/cjs/algeria.d.ts",
|
|
104
|
+
"default": "./dist/cjs/algeria.js"
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
"./indonesia": {
|
|
108
|
+
"import": {
|
|
109
|
+
"types": "./dist/esm/indonesia.d.ts",
|
|
110
|
+
"default": "./dist/esm/indonesia.js"
|
|
111
|
+
},
|
|
112
|
+
"require": {
|
|
113
|
+
"types": "./dist/cjs/indonesia.d.ts",
|
|
114
|
+
"default": "./dist/cjs/indonesia.js"
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
"./locate": {
|
|
118
|
+
"import": {
|
|
119
|
+
"types": "./dist/esm/locate.d.ts",
|
|
120
|
+
"default": "./dist/esm/locate.js"
|
|
121
|
+
},
|
|
122
|
+
"require": {
|
|
123
|
+
"types": "./dist/cjs/locate.d.ts",
|
|
124
|
+
"default": "./dist/cjs/locate.js"
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
"./certification.json": "./certification.json",
|
|
128
|
+
"./data/corrections/*.json": "./data/corrections/*.json",
|
|
129
|
+
"./schemas/*.json": "./schemas/*.json",
|
|
130
|
+
"./package.json": "./package.json"
|
|
131
|
+
},
|
|
132
|
+
"typesVersions": {
|
|
133
|
+
"*": {
|
|
134
|
+
"core": [
|
|
135
|
+
"./dist/cjs/core.d.ts"
|
|
136
|
+
],
|
|
137
|
+
"sweden": [
|
|
138
|
+
"./dist/cjs/sweden.d.ts"
|
|
139
|
+
],
|
|
140
|
+
"diyanet": [
|
|
141
|
+
"./dist/cjs/diyanet.d.ts"
|
|
142
|
+
],
|
|
143
|
+
"morocco": [
|
|
144
|
+
"./dist/cjs/morocco.d.ts"
|
|
145
|
+
],
|
|
146
|
+
"algeria": [
|
|
147
|
+
"./dist/cjs/algeria.d.ts"
|
|
148
|
+
],
|
|
149
|
+
"indonesia": [
|
|
150
|
+
"./dist/cjs/indonesia.d.ts"
|
|
151
|
+
],
|
|
152
|
+
"locate": [
|
|
153
|
+
"./dist/cjs/locate.d.ts"
|
|
154
|
+
]
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
"scripts": {
|
|
158
|
+
"embed": "node scripts/embed.mjs",
|
|
159
|
+
"build": "npm run embed && rm -rf dist && tsc -p tsconfig.build.cjs.json && tsc -p tsconfig.build.esm.json && echo '{\"type\":\"module\"}' > dist/esm/package.json",
|
|
160
|
+
"prepack": "npm run build",
|
|
161
|
+
"pretest": "npm run embed",
|
|
162
|
+
"test": "tsx --test test/*.test.ts",
|
|
163
|
+
"pretypecheck": "npm run embed",
|
|
164
|
+
"typecheck": "tsc --noEmit",
|
|
165
|
+
"preverify": "npm run embed",
|
|
166
|
+
"verify": "tsx tools/verify.ts",
|
|
167
|
+
"precorrections": "npm run embed",
|
|
168
|
+
"corrections": "tsx tools/corrections.ts",
|
|
169
|
+
"precertify": "npm run embed",
|
|
170
|
+
"certify": "tsx tools/certify.ts",
|
|
171
|
+
"vectors": "npm run embed && tsx tools/vectors.ts",
|
|
172
|
+
"serve": "npm run embed && tsx tools/serve.ts"
|
|
173
|
+
},
|
|
174
|
+
"devDependencies": {
|
|
175
|
+
"@types/node": "^22.10.0",
|
|
176
|
+
"ajv": "^8.20.0",
|
|
177
|
+
"tsx": "^4.19.2",
|
|
178
|
+
"typescript": "^5.7.2"
|
|
179
|
+
}
|
|
180
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://raw.githubusercontent.com/MihrabHQ/mihrab-methods/main/schemas/certification.schema.json",
|
|
4
|
+
"title": "mihrab-methods certification",
|
|
5
|
+
"description": "What may be used: for each authority, whether its method reproduces every time of the authority's tables on the printed minute, over which dates, at which method revision, and which correction list that holds with. Written by `npm run certify`; read by apps to keep current (fetchLatestCorrections).",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"propertyNames": { "enum": ["sweden", "diyanet", "morocco", "algeria", "indonesia"] },
|
|
8
|
+
"additionalProperties": { "$ref": "#/$defs/entry" },
|
|
9
|
+
"$defs": {
|
|
10
|
+
"date": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" },
|
|
11
|
+
"entry": {
|
|
12
|
+
"type": "object",
|
|
13
|
+
"required": ["certified", "checkedAt", "checks"],
|
|
14
|
+
"additionalProperties": false,
|
|
15
|
+
"properties": {
|
|
16
|
+
"certified": { "type": "boolean", "description": "True only when every check below has every time on the printed minute. Not trusted alone: apps re-derive it from the checks." },
|
|
17
|
+
"checkedAt": { "$ref": "#/$defs/date" },
|
|
18
|
+
"checks": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/check" } },
|
|
19
|
+
"corrections": {
|
|
20
|
+
"type": "object",
|
|
21
|
+
"description": "The correction list this certification is for: its identity, and the SHA-256 of data/corrections/<authority>.json as published.",
|
|
22
|
+
"required": ["from", "to", "entries"],
|
|
23
|
+
"additionalProperties": false,
|
|
24
|
+
"properties": {
|
|
25
|
+
"from": { "$ref": "#/$defs/date" },
|
|
26
|
+
"to": { "$ref": "#/$defs/date" },
|
|
27
|
+
"entries": { "type": "integer", "minimum": 0 },
|
|
28
|
+
"sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" }
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"revision": { "type": "integer", "minimum": 1, "description": "The method's revision the list is for. An app computing another revision must not apply the list." }
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"check": {
|
|
35
|
+
"type": "object",
|
|
36
|
+
"required": ["tables", "places", "times", "off", "from", "to"],
|
|
37
|
+
"additionalProperties": false,
|
|
38
|
+
"properties": {
|
|
39
|
+
"tables": { "type": "string", "description": "Whose tables were checked." },
|
|
40
|
+
"places": { "type": "integer", "minimum": 0 },
|
|
41
|
+
"times": { "type": "integer", "minimum": 0 },
|
|
42
|
+
"off": { "type": "integer", "minimum": 0, "description": "Times not on the printed minute. Certified only at 0." },
|
|
43
|
+
"from": { "$ref": "#/$defs/date" },
|
|
44
|
+
"to": { "$ref": "#/$defs/date" },
|
|
45
|
+
"setAside": {
|
|
46
|
+
"type": "object",
|
|
47
|
+
"description": "Rows set aside as the source's fault, not the method's, so each can be judged.",
|
|
48
|
+
"required": ["misplaced", "sourceFaults", "copiedRows"],
|
|
49
|
+
"additionalProperties": false,
|
|
50
|
+
"properties": {
|
|
51
|
+
"misplaced": { "type": "array", "items": { "type": "string" } },
|
|
52
|
+
"sourceFaults": { "type": "integer", "minimum": 0 },
|
|
53
|
+
"copiedRows": { "type": "integer", "minimum": 0 }
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://raw.githubusercontent.com/MihrabHQ/mihrab-methods/main/schemas/corrections.schema.json",
|
|
4
|
+
"title": "mihrab-methods correction list",
|
|
5
|
+
"description": "A method's correction list: the few times its authority's own program puts on the other side of a minute's rounding point. Each entry moves one printed time of one point on one date by a minute. Published at data/corrections/<authority>.json; certification.json names the list in force (its dates, its size and its SHA-256).",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["from", "to", "points"],
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"properties": {
|
|
10
|
+
"from": { "$ref": "#/$defs/date", "description": "The first date the list was made over." },
|
|
11
|
+
"to": { "$ref": "#/$defs/date", "description": "The last date the list was made over; past it the method alone applies." },
|
|
12
|
+
"points": {
|
|
13
|
+
"type": "object",
|
|
14
|
+
"description": "The point the method is computed at, as 'lat,lon' to three decimals → its corrections.",
|
|
15
|
+
"propertyNames": { "pattern": "^-?[0-9]+\\.[0-9]{3},-?[0-9]+\\.[0-9]{3}$" },
|
|
16
|
+
"additionalProperties": {
|
|
17
|
+
"type": "array",
|
|
18
|
+
"items": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"description": "'YYYY-MM-DD prayer ±1': the minutes to add to that prayer's printed time on that date.",
|
|
21
|
+
"pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2} (fajr|sunrise|dhuhr|asr|maghrib|isha) [+-]1$"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"$defs": {
|
|
27
|
+
"date": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" }
|
|
28
|
+
}
|
|
29
|
+
}
|