@intech-software/chronera 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +6644 -0
  3. package/dist/calendar/buddhist/adapter.d.ts +2 -0
  4. package/dist/calendar/buddhist/adapter.js +33 -0
  5. package/dist/calendar/buddhist/adapter.js.map +1 -0
  6. package/dist/calendar/buddhist/constants.d.ts +3 -0
  7. package/dist/calendar/buddhist/constants.js +14 -0
  8. package/dist/calendar/buddhist/constants.js.map +1 -0
  9. package/dist/calendar/buddhist/index.d.ts +3 -0
  10. package/dist/calendar/buddhist/index.js +4 -0
  11. package/dist/calendar/buddhist/index.js.map +1 -0
  12. package/dist/calendar/buddhist/validator.d.ts +4 -0
  13. package/dist/calendar/buddhist/validator.js +60 -0
  14. package/dist/calendar/buddhist/validator.js.map +1 -0
  15. package/dist/calendar/gregory/absolute-day.d.ts +12 -0
  16. package/dist/calendar/gregory/absolute-day.js +14 -0
  17. package/dist/calendar/gregory/absolute-day.js.map +1 -0
  18. package/dist/calendar/gregory/adapter.d.ts +3 -0
  19. package/dist/calendar/gregory/adapter.js +93 -0
  20. package/dist/calendar/gregory/adapter.js.map +1 -0
  21. package/dist/calendar/gregory/constants.d.ts +3 -0
  22. package/dist/calendar/gregory/constants.js +18 -0
  23. package/dist/calendar/gregory/constants.js.map +1 -0
  24. package/dist/calendar/gregory/index.d.ts +4 -0
  25. package/dist/calendar/gregory/index.js +5 -0
  26. package/dist/calendar/gregory/index.js.map +1 -0
  27. package/dist/calendar/gregory/leap-year.d.ts +1 -0
  28. package/dist/calendar/gregory/leap-year.js +2 -0
  29. package/dist/calendar/gregory/leap-year.js.map +1 -0
  30. package/dist/calendar/gregory/validator.d.ts +2 -0
  31. package/dist/calendar/gregory/validator.js +45 -0
  32. package/dist/calendar/gregory/validator.js.map +1 -0
  33. package/dist/calendar/hijri/civil-adapter.d.ts +12 -0
  34. package/dist/calendar/hijri/civil-adapter.js +132 -0
  35. package/dist/calendar/hijri/civil-adapter.js.map +1 -0
  36. package/dist/calendar/hijri/index.d.ts +3 -0
  37. package/dist/calendar/hijri/index.js +4 -0
  38. package/dist/calendar/hijri/index.js.map +1 -0
  39. package/dist/calendar/hijri/tabular-adapter.d.ts +4 -0
  40. package/dist/calendar/hijri/tabular-adapter.js +79 -0
  41. package/dist/calendar/hijri/tabular-adapter.js.map +1 -0
  42. package/dist/calendar/hijri/umm-al-qura-adapter.d.ts +4 -0
  43. package/dist/calendar/hijri/umm-al-qura-adapter.js +27 -0
  44. package/dist/calendar/hijri/umm-al-qura-adapter.js.map +1 -0
  45. package/dist/calendar/index.d.ts +13 -0
  46. package/dist/calendar/index.js +12 -0
  47. package/dist/calendar/index.js.map +1 -0
  48. package/dist/calendar/indian/adapter.d.ts +2 -0
  49. package/dist/calendar/indian/adapter.js +66 -0
  50. package/dist/calendar/indian/adapter.js.map +1 -0
  51. package/dist/calendar/indian/constants.d.ts +5 -0
  52. package/dist/calendar/indian/constants.js +43 -0
  53. package/dist/calendar/indian/constants.js.map +1 -0
  54. package/dist/calendar/indian/index.d.ts +3 -0
  55. package/dist/calendar/indian/index.js +4 -0
  56. package/dist/calendar/indian/index.js.map +1 -0
  57. package/dist/calendar/indian/validator.d.ts +6 -0
  58. package/dist/calendar/indian/validator.js +65 -0
  59. package/dist/calendar/indian/validator.js.map +1 -0
  60. package/dist/calendar/japanese/adapter.d.ts +3 -0
  61. package/dist/calendar/japanese/adapter.js +63 -0
  62. package/dist/calendar/japanese/adapter.js.map +1 -0
  63. package/dist/calendar/japanese/constants.d.ts +17 -0
  64. package/dist/calendar/japanese/constants.js +85 -0
  65. package/dist/calendar/japanese/constants.js.map +1 -0
  66. package/dist/calendar/japanese/index.d.ts +3 -0
  67. package/dist/calendar/japanese/index.js +4 -0
  68. package/dist/calendar/japanese/index.js.map +1 -0
  69. package/dist/calendar/japanese/validator.d.ts +5 -0
  70. package/dist/calendar/japanese/validator.js +76 -0
  71. package/dist/calendar/japanese/validator.js.map +1 -0
  72. package/dist/calendar/persian/adapter.d.ts +2 -0
  73. package/dist/calendar/persian/adapter.js +42 -0
  74. package/dist/calendar/persian/adapter.js.map +1 -0
  75. package/dist/calendar/persian/constants.d.ts +5 -0
  76. package/dist/calendar/persian/constants.js +43 -0
  77. package/dist/calendar/persian/constants.js.map +1 -0
  78. package/dist/calendar/persian/index.d.ts +4 -0
  79. package/dist/calendar/persian/index.js +5 -0
  80. package/dist/calendar/persian/index.js.map +1 -0
  81. package/dist/calendar/persian/math.d.ts +24 -0
  82. package/dist/calendar/persian/math.js +109 -0
  83. package/dist/calendar/persian/math.js.map +1 -0
  84. package/dist/calendar/persian/validator.d.ts +4 -0
  85. package/dist/calendar/persian/validator.js +52 -0
  86. package/dist/calendar/persian/validator.js.map +1 -0
  87. package/dist/calendar/registry.d.ts +9 -0
  88. package/dist/calendar/registry.js +119 -0
  89. package/dist/calendar/registry.js.map +1 -0
  90. package/dist/calendar/roc/adapter.d.ts +2 -0
  91. package/dist/calendar/roc/adapter.js +47 -0
  92. package/dist/calendar/roc/adapter.js.map +1 -0
  93. package/dist/calendar/roc/constants.d.ts +6 -0
  94. package/dist/calendar/roc/constants.js +34 -0
  95. package/dist/calendar/roc/constants.js.map +1 -0
  96. package/dist/calendar/roc/index.d.ts +3 -0
  97. package/dist/calendar/roc/index.js +4 -0
  98. package/dist/calendar/roc/index.js.map +1 -0
  99. package/dist/calendar/roc/validator.d.ts +4 -0
  100. package/dist/calendar/roc/validator.js +52 -0
  101. package/dist/calendar/roc/validator.js.map +1 -0
  102. package/dist/calendar/types.d.ts +34 -0
  103. package/dist/calendar/types.js +2 -0
  104. package/dist/calendar/types.js.map +1 -0
  105. package/dist/core/absolute-day.d.ts +8 -0
  106. package/dist/core/absolute-day.js +39 -0
  107. package/dist/core/absolute-day.js.map +1 -0
  108. package/dist/core/calendar-date.d.ts +11 -0
  109. package/dist/core/calendar-date.js +37 -0
  110. package/dist/core/calendar-date.js.map +1 -0
  111. package/dist/core/day-of-year.d.ts +16 -0
  112. package/dist/core/day-of-year.js +30 -0
  113. package/dist/core/day-of-year.js.map +1 -0
  114. package/dist/core/duration.d.ts +2 -0
  115. package/dist/core/duration.js +31 -0
  116. package/dist/core/duration.js.map +1 -0
  117. package/dist/core/fiscal.d.ts +31 -0
  118. package/dist/core/fiscal.js +45 -0
  119. package/dist/core/fiscal.js.map +1 -0
  120. package/dist/core/gregorian-math.d.ts +4 -0
  121. package/dist/core/gregorian-math.js +30 -0
  122. package/dist/core/gregorian-math.js.map +1 -0
  123. package/dist/core/instant.d.ts +6 -0
  124. package/dist/core/instant.js +26 -0
  125. package/dist/core/instant.js.map +1 -0
  126. package/dist/core/integer.d.ts +1 -0
  127. package/dist/core/integer.js +7 -0
  128. package/dist/core/integer.js.map +1 -0
  129. package/dist/core/iso-week.d.ts +19 -0
  130. package/dist/core/iso-week.js +41 -0
  131. package/dist/core/iso-week.js.map +1 -0
  132. package/dist/core/julian-day.d.ts +26 -0
  133. package/dist/core/julian-day.js +35 -0
  134. package/dist/core/julian-day.js.map +1 -0
  135. package/dist/core/local-date-time.d.ts +2 -0
  136. package/dist/core/local-date-time.js +15 -0
  137. package/dist/core/local-date-time.js.map +1 -0
  138. package/dist/core/local-date.d.ts +2 -0
  139. package/dist/core/local-date.js +22 -0
  140. package/dist/core/local-date.js.map +1 -0
  141. package/dist/core/local-time.d.ts +2 -0
  142. package/dist/core/local-time.js +28 -0
  143. package/dist/core/local-time.js.map +1 -0
  144. package/dist/core/range.d.ts +2 -0
  145. package/dist/core/range.js +9 -0
  146. package/dist/core/range.js.map +1 -0
  147. package/dist/create-chronera.d.ts +2 -0
  148. package/dist/create-chronera.js +59 -0
  149. package/dist/create-chronera.js.map +1 -0
  150. package/dist/errors/error-codes.d.ts +1 -0
  151. package/dist/errors/error-codes.js +2 -0
  152. package/dist/errors/error-codes.js.map +1 -0
  153. package/dist/errors/errors.d.ts +16 -0
  154. package/dist/errors/errors.js +22 -0
  155. package/dist/errors/errors.js.map +1 -0
  156. package/dist/errors/index.d.ts +2 -0
  157. package/dist/errors/index.js +2 -0
  158. package/dist/errors/index.js.map +1 -0
  159. package/dist/format/format-date-range.d.ts +2 -0
  160. package/dist/format/format-date-range.js +89 -0
  161. package/dist/format/format-date-range.js.map +1 -0
  162. package/dist/format/format-date-time.d.ts +2 -0
  163. package/dist/format/format-date-time.js +51 -0
  164. package/dist/format/format-date-time.js.map +1 -0
  165. package/dist/format/format-date.d.ts +4 -0
  166. package/dist/format/format-date.js +103 -0
  167. package/dist/format/format-date.js.map +1 -0
  168. package/dist/format/format-pattern.d.ts +4 -0
  169. package/dist/format/format-pattern.js +266 -0
  170. package/dist/format/format-pattern.js.map +1 -0
  171. package/dist/format/format-relative.d.ts +2 -0
  172. package/dist/format/format-relative.js +93 -0
  173. package/dist/format/format-relative.js.map +1 -0
  174. package/dist/format/format-time.d.ts +2 -0
  175. package/dist/format/format-time.js +48 -0
  176. package/dist/format/format-time.js.map +1 -0
  177. package/dist/format/index.d.ts +13 -0
  178. package/dist/format/index.js +12 -0
  179. package/dist/format/index.js.map +1 -0
  180. package/dist/format/pattern-scanner.d.ts +8 -0
  181. package/dist/format/pattern-scanner.js +102 -0
  182. package/dist/format/pattern-scanner.js.map +1 -0
  183. package/dist/format/presets/japanese-official.d.ts +8 -0
  184. package/dist/format/presets/japanese-official.js +39 -0
  185. package/dist/format/presets/japanese-official.js.map +1 -0
  186. package/dist/format/presets/taiwan-official.d.ts +6 -0
  187. package/dist/format/presets/taiwan-official.js +23 -0
  188. package/dist/format/presets/taiwan-official.js.map +1 -0
  189. package/dist/format/presets/thai-official.d.ts +2 -0
  190. package/dist/format/presets/thai-official.js +45 -0
  191. package/dist/format/presets/thai-official.js.map +1 -0
  192. package/dist/format/presets/types.d.ts +2 -0
  193. package/dist/format/presets/types.js +2 -0
  194. package/dist/format/presets/types.js.map +1 -0
  195. package/dist/format/presets/world-locales.d.ts +29 -0
  196. package/dist/format/presets/world-locales.js +330 -0
  197. package/dist/format/presets/world-locales.js.map +1 -0
  198. package/dist/format/resolve-date-input.d.ts +9 -0
  199. package/dist/format/resolve-date-input.js +93 -0
  200. package/dist/format/resolve-date-input.js.map +1 -0
  201. package/dist/format/rfc2822.d.ts +17 -0
  202. package/dist/format/rfc2822.js +59 -0
  203. package/dist/format/rfc2822.js.map +1 -0
  204. package/dist/index.d.ts +19 -0
  205. package/dist/index.js +19 -0
  206. package/dist/index.js.map +1 -0
  207. package/dist/internal/engine.d.ts +8 -0
  208. package/dist/internal/engine.js +11 -0
  209. package/dist/internal/engine.js.map +1 -0
  210. package/dist/locale/numbering-system.d.ts +4 -0
  211. package/dist/locale/numbering-system.js +133 -0
  212. package/dist/locale/numbering-system.js.map +1 -0
  213. package/dist/locale/resolve-locale.d.ts +7 -0
  214. package/dist/locale/resolve-locale.js +51 -0
  215. package/dist/locale/resolve-locale.js.map +1 -0
  216. package/dist/locale/types.d.ts +1 -0
  217. package/dist/locale/types.js +2 -0
  218. package/dist/locale/types.js.map +1 -0
  219. package/dist/operations/arithmetic.d.ts +4 -0
  220. package/dist/operations/arithmetic.js +13 -0
  221. package/dist/operations/arithmetic.js.map +1 -0
  222. package/dist/operations/compare.d.ts +5 -0
  223. package/dist/operations/compare.js +50 -0
  224. package/dist/operations/compare.js.map +1 -0
  225. package/dist/operations/convert-calendar-date.d.ts +4 -0
  226. package/dist/operations/convert-calendar-date.js +54 -0
  227. package/dist/operations/convert-calendar-date.js.map +1 -0
  228. package/dist/operations/day-of-year.d.ts +7 -0
  229. package/dist/operations/day-of-year.js +29 -0
  230. package/dist/operations/day-of-year.js.map +1 -0
  231. package/dist/operations/fiscal.d.ts +5 -0
  232. package/dist/operations/fiscal.js +25 -0
  233. package/dist/operations/fiscal.js.map +1 -0
  234. package/dist/operations/iso-week.d.ts +9 -0
  235. package/dist/operations/iso-week.js +29 -0
  236. package/dist/operations/iso-week.js.map +1 -0
  237. package/dist/operations/julian-day.d.ts +6 -0
  238. package/dist/operations/julian-day.js +37 -0
  239. package/dist/operations/julian-day.js.map +1 -0
  240. package/dist/operations/validate.d.ts +10 -0
  241. package/dist/operations/validate.js +55 -0
  242. package/dist/operations/validate.js.map +1 -0
  243. package/dist/parse/field-normalizer.d.ts +1 -0
  244. package/dist/parse/field-normalizer.js +5 -0
  245. package/dist/parse/field-normalizer.js.map +1 -0
  246. package/dist/parse/index.d.ts +4 -0
  247. package/dist/parse/index.js +4 -0
  248. package/dist/parse/index.js.map +1 -0
  249. package/dist/parse/parse-instant.d.ts +2 -0
  250. package/dist/parse/parse-instant.js +97 -0
  251. package/dist/parse/parse-instant.js.map +1 -0
  252. package/dist/parse/parse-local-date.d.ts +2 -0
  253. package/dist/parse/parse-local-date.js +31 -0
  254. package/dist/parse/parse-local-date.js.map +1 -0
  255. package/dist/parse/pattern-parser.d.ts +2 -0
  256. package/dist/parse/pattern-parser.js +150 -0
  257. package/dist/parse/pattern-parser.js.map +1 -0
  258. package/dist/parse/safe-parse.d.ts +3 -0
  259. package/dist/parse/safe-parse.js +46 -0
  260. package/dist/parse/safe-parse.js.map +1 -0
  261. package/dist/public-types.d.ts +209 -0
  262. package/dist/public-types.js +2 -0
  263. package/dist/public-types.js.map +1 -0
  264. package/dist/runtime/bounded-lru.d.ts +11 -0
  265. package/dist/runtime/bounded-lru.js +42 -0
  266. package/dist/runtime/bounded-lru.js.map +1 -0
  267. package/dist/runtime/capabilities.d.ts +5 -0
  268. package/dist/runtime/capabilities.js +61 -0
  269. package/dist/runtime/capabilities.js.map +1 -0
  270. package/dist/runtime/intl-date-time.d.ts +11 -0
  271. package/dist/runtime/intl-date-time.js +38 -0
  272. package/dist/runtime/intl-date-time.js.map +1 -0
  273. package/dist/runtime/intl-number.d.ts +7 -0
  274. package/dist/runtime/intl-number.js +35 -0
  275. package/dist/runtime/intl-number.js.map +1 -0
  276. package/dist/runtime/intl-relative-time.d.ts +7 -0
  277. package/dist/runtime/intl-relative-time.js +35 -0
  278. package/dist/runtime/intl-relative-time.js.map +1 -0
  279. package/dist/runtime/timezone.d.ts +14 -0
  280. package/dist/runtime/timezone.js +95 -0
  281. package/dist/runtime/timezone.js.map +1 -0
  282. package/package.json +155 -0
@@ -0,0 +1,79 @@
1
+ import { daysInIslamicCivilMonth, isIslamicCivilLeapYear, islamicCivilFromAbsoluteDay, islamicCivilToAbsoluteDay, } from "./civil-adapter.js";
2
+ // Islamic Tabular (Astronomical epoch: Thursday July 15, 622 CE = -492998)
3
+ const ISLAMIC_TBLA_EPOCH = -492998;
4
+ const EPOCH_DIFF = ISLAMIC_TBLA_EPOCH - -492997; // -1
5
+ export const ISLAMIC_TBLA_IDENTITY = {
6
+ id: "islamic-tbla",
7
+ algorithm: "chronera-islamic-tbla-astronomical-v1",
8
+ deterministic: true,
9
+ validRange: {
10
+ first: ISLAMIC_TBLA_EPOCH,
11
+ last: 2932896,
12
+ },
13
+ };
14
+ export const islamicTblaValidator = {
15
+ identity: ISLAMIC_TBLA_IDENTITY,
16
+ validate(date) {
17
+ const issues = [];
18
+ if (date.year < 1) {
19
+ issues.push({
20
+ code: "CHRONERA_OUT_OF_RANGE",
21
+ message: `Islamic tbla year must be >= 1; received ${date.year}.`,
22
+ path: ["year"],
23
+ });
24
+ }
25
+ const month = date.month ?? Number.parseInt(date.monthCode.slice(1), 10);
26
+ if (month < 1 || month > 12) {
27
+ issues.push({
28
+ code: "CHRONERA_INVALID_DATE",
29
+ message: `Invalid month ${month}. Expected 1-12.`,
30
+ path: ["monthCode"],
31
+ });
32
+ }
33
+ else if (date.year >= 1) {
34
+ const maxDay = daysInIslamicCivilMonth(date.year, month);
35
+ if (date.day < 1 || date.day > maxDay) {
36
+ issues.push({
37
+ code: "CHRONERA_INVALID_DATE",
38
+ message: `Invalid day ${date.day} for month ${date.monthCode} in Islamic tbla year ${date.year}.`,
39
+ path: ["day"],
40
+ });
41
+ }
42
+ }
43
+ return issues;
44
+ },
45
+ daysInMonth(year, monthCode) {
46
+ const month = Number.parseInt(monthCode.slice(1), 10);
47
+ return daysInIslamicCivilMonth(year, month);
48
+ },
49
+ isLeapYear(year) {
50
+ return isIslamicCivilLeapYear(year);
51
+ },
52
+ };
53
+ export const islamicTblaAdapter = {
54
+ identity: ISLAMIC_TBLA_IDENTITY,
55
+ converter: {
56
+ identity: ISLAMIC_TBLA_IDENTITY,
57
+ toAbsoluteDay(date) {
58
+ const month = date.month ?? Number.parseInt(date.monthCode.slice(1), 10);
59
+ const civilAbs = islamicCivilToAbsoluteDay(date.year, month, date.day);
60
+ return civilAbs + EPOCH_DIFF;
61
+ },
62
+ fromAbsoluteDay(day) {
63
+ const civilDay = day - EPOCH_DIFF;
64
+ const res = islamicCivilFromAbsoluteDay(civilDay);
65
+ return {
66
+ kind: "calendar-date",
67
+ calendar: "islamic-tbla",
68
+ era: "AH",
69
+ eraYear: res.year,
70
+ year: res.year,
71
+ monthCode: `M${String(res.month).padStart(2, "0")}`,
72
+ month: res.month,
73
+ day: res.day,
74
+ };
75
+ },
76
+ },
77
+ validator: islamicTblaValidator,
78
+ };
79
+ //# sourceMappingURL=tabular-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tabular-adapter.js","sourceRoot":"","sources":["../../../src/calendar/hijri/tabular-adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n daysInIslamicCivilMonth,\n isIslamicCivilLeapYear,\n islamicCivilFromAbsoluteDay,\n islamicCivilToAbsoluteDay,\n} from \"./civil-adapter.js\";\n\nimport type {\n CalendarAdapter,\n CalendarIdentity,\n CalendarValidator,\n} from \"../types.js\";\nimport type {\n CalendarDate,\n ChroneraIssue,\n MonthCode,\n} from \"../../public-types.js\";\n\n// Islamic Tabular (Astronomical epoch: Thursday July 15, 622 CE = -492998)\nconst ISLAMIC_TBLA_EPOCH = -492998;\nconst EPOCH_DIFF = ISLAMIC_TBLA_EPOCH - -492997; // -1\n\nexport const ISLAMIC_TBLA_IDENTITY: CalendarIdentity = {\n id: \"islamic-tbla\",\n algorithm: \"chronera-islamic-tbla-astronomical-v1\",\n deterministic: true,\n validRange: {\n first: ISLAMIC_TBLA_EPOCH,\n last: 2932896,\n },\n};\n\nexport const islamicTblaValidator: CalendarValidator = {\n identity: ISLAMIC_TBLA_IDENTITY,\n validate(date: CalendarDate): readonly ChroneraIssue[] {\n const issues: ChroneraIssue[] = [];\n if (date.year < 1) {\n issues.push({\n code: \"CHRONERA_OUT_OF_RANGE\",\n message: `Islamic tbla year must be >= 1; received ${date.year}.`,\n path: [\"year\"],\n });\n }\n const month = date.month ?? Number.parseInt(date.monthCode.slice(1), 10);\n if (month < 1 || month > 12) {\n issues.push({\n code: \"CHRONERA_INVALID_DATE\",\n message: `Invalid month ${month}. Expected 1-12.`,\n path: [\"monthCode\"],\n });\n } else if (date.year >= 1) {\n const maxDay = daysInIslamicCivilMonth(date.year, month);\n if (date.day < 1 || date.day > maxDay) {\n issues.push({\n code: \"CHRONERA_INVALID_DATE\",\n message: `Invalid day ${date.day} for month ${date.monthCode} in Islamic tbla year ${date.year}.`,\n path: [\"day\"],\n });\n }\n }\n return issues;\n },\n daysInMonth(year: number, monthCode: MonthCode): number {\n const month = Number.parseInt(monthCode.slice(1), 10);\n return daysInIslamicCivilMonth(year, month);\n },\n isLeapYear(year: number): boolean {\n return isIslamicCivilLeapYear(year);\n },\n};\n\nexport const islamicTblaAdapter: CalendarAdapter = {\n identity: ISLAMIC_TBLA_IDENTITY,\n converter: {\n identity: ISLAMIC_TBLA_IDENTITY,\n toAbsoluteDay(date: CalendarDate): number {\n const month = date.month ?? Number.parseInt(date.monthCode.slice(1), 10);\n const civilAbs = islamicCivilToAbsoluteDay(date.year, month, date.day);\n return civilAbs + EPOCH_DIFF;\n },\n fromAbsoluteDay(day: number): CalendarDate {\n const civilDay = day - EPOCH_DIFF;\n const res = islamicCivilFromAbsoluteDay(civilDay);\n return {\n kind: \"calendar-date\",\n calendar: \"islamic-tbla\",\n era: \"AH\",\n eraYear: res.year,\n year: res.year,\n monthCode: `M${String(res.month).padStart(2, \"0\")}`,\n month: res.month,\n day: res.day,\n };\n },\n },\n validator: islamicTblaValidator,\n};\n"]}
@@ -0,0 +1,4 @@
1
+ import type { CalendarAdapter, CalendarIdentity, CalendarValidator } from "../types.js";
2
+ export declare const ISLAMIC_UMALQURA_IDENTITY: CalendarIdentity;
3
+ export declare const islamicUmalquraValidator: CalendarValidator;
4
+ export declare const islamicUmalquraAdapter: CalendarAdapter;
@@ -0,0 +1,27 @@
1
+ export const ISLAMIC_UMALQURA_IDENTITY = {
2
+ id: "islamic-umalqura",
3
+ algorithm: "chronera-islamic-umalqura-v1",
4
+ deterministic: false,
5
+ dataVersion: "cldr-43",
6
+ validRange: {
7
+ first: -146097,
8
+ last: 2932896,
9
+ },
10
+ };
11
+ export const islamicUmalquraValidator = {
12
+ identity: ISLAMIC_UMALQURA_IDENTITY,
13
+ validate(_date) {
14
+ return [];
15
+ },
16
+ daysInMonth(_year, _monthCode) {
17
+ return 30;
18
+ },
19
+ isLeapYear(_year) {
20
+ return false;
21
+ },
22
+ };
23
+ export const islamicUmalquraAdapter = {
24
+ identity: ISLAMIC_UMALQURA_IDENTITY,
25
+ validator: islamicUmalquraValidator,
26
+ };
27
+ //# sourceMappingURL=umm-al-qura-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"umm-al-qura-adapter.js","sourceRoot":"","sources":["../../../src/calendar/hijri/umm-al-qura-adapter.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,yBAAyB,GAAqB;IACzD,EAAE,EAAE,kBAAkB;IACtB,SAAS,EAAE,8BAA8B;IACzC,aAAa,EAAE,KAAK;IACpB,WAAW,EAAE,SAAS;IACtB,UAAU,EAAE;QACV,KAAK,EAAE,CAAC,MAAM;QACd,IAAI,EAAE,OAAO;KACd;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAAsB;IACzD,QAAQ,EAAE,yBAAyB;IACnC,QAAQ,CAAC,KAAmB;QAC1B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,WAAW,CAAC,KAAa,EAAE,UAAqB;QAC9C,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,UAAU,CAAC,KAAa;QACtB,OAAO,KAAK,CAAC;IACf,CAAC;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAoB;IACrD,QAAQ,EAAE,yBAAyB;IACnC,SAAS,EAAE,wBAAwB;CACpC,CAAC","sourcesContent":["import type {\n CalendarAdapter,\n CalendarIdentity,\n CalendarValidator,\n} from \"../types.js\";\nimport type {\n CalendarDate,\n ChroneraIssue,\n MonthCode,\n} from \"../../public-types.js\";\n\nexport const ISLAMIC_UMALQURA_IDENTITY: CalendarIdentity = {\n id: \"islamic-umalqura\",\n algorithm: \"chronera-islamic-umalqura-v1\",\n deterministic: false,\n dataVersion: \"cldr-43\",\n validRange: {\n first: -146097,\n last: 2932896,\n },\n};\n\nexport const islamicUmalquraValidator: CalendarValidator = {\n identity: ISLAMIC_UMALQURA_IDENTITY,\n validate(_date: CalendarDate): readonly ChroneraIssue[] {\n return [];\n },\n daysInMonth(_year: number, _monthCode: MonthCode): number {\n return 30;\n },\n isLeapYear(_year: number): boolean {\n return false;\n },\n};\n\nexport const islamicUmalquraAdapter: CalendarAdapter = {\n identity: ISLAMIC_UMALQURA_IDENTITY,\n validator: islamicUmalquraValidator,\n};\n"]}
@@ -0,0 +1,13 @@
1
+ export { daysInMonth, getCalendarCapabilities, isLeapYear, isValidCalendarDate, } from "../operations/validate.js";
2
+ export { convertCalendarDate } from "../operations/convert-calendar-date.js";
3
+ export { sameAbsoluteDate, sameCalendarDate } from "../operations/compare.js";
4
+ export { gregorianAdapter, iso8601Adapter } from "./gregory/index.js";
5
+ export { buddhistAdapter } from "./buddhist/index.js";
6
+ export { islamicCivilAdapter, islamicTblaAdapter } from "./hijri/index.js";
7
+ export { japaneseAdapter, findJapaneseEraForAbsoluteDay, JAPANESE_ERAS, } from "./japanese/index.js";
8
+ export { rocAdapter, ROC_OFFSET } from "./roc/index.js";
9
+ export { persianAdapter, isPersianLeapYear, daysInPersianMonth, } from "./persian/index.js";
10
+ export { indianAdapter, isIndianLeapYear, daysInIndianMonth, } from "./indian/index.js";
11
+ export { CalendarRegistry, defaultCalendarRegistry } from "./registry.js";
12
+ export type { CalendarAdapter, CalendarConverter, CalendarIdentity, CalendarValidator, CalendarArithmetic, } from "./types.js";
13
+ export type { CalendarCapabilities, CalendarConversionMetadata, CalendarConversionResult, CalendarDate, CalendarId, CalendarPlugin, } from "../public-types.js";
@@ -0,0 +1,12 @@
1
+ export { daysInMonth, getCalendarCapabilities, isLeapYear, isValidCalendarDate, } from "../operations/validate.js";
2
+ export { convertCalendarDate } from "../operations/convert-calendar-date.js";
3
+ export { sameAbsoluteDate, sameCalendarDate } from "../operations/compare.js";
4
+ export { gregorianAdapter, iso8601Adapter } from "./gregory/index.js";
5
+ export { buddhistAdapter } from "./buddhist/index.js";
6
+ export { islamicCivilAdapter, islamicTblaAdapter } from "./hijri/index.js";
7
+ export { japaneseAdapter, findJapaneseEraForAbsoluteDay, JAPANESE_ERAS, } from "./japanese/index.js";
8
+ export { rocAdapter, ROC_OFFSET } from "./roc/index.js";
9
+ export { persianAdapter, isPersianLeapYear, daysInPersianMonth, } from "./persian/index.js";
10
+ export { indianAdapter, isIndianLeapYear, daysInIndianMonth, } from "./indian/index.js";
11
+ export { CalendarRegistry, defaultCalendarRegistry } from "./registry.js";
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/calendar/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,uBAAuB,EACvB,UAAU,EACV,mBAAmB,GACpB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAC;AAE7E,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE9E,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEtE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE3E,OAAO,EACL,eAAe,EACf,6BAA6B,EAC7B,aAAa,GACd,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAExD,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC","sourcesContent":["export {\n daysInMonth,\n getCalendarCapabilities,\n isLeapYear,\n isValidCalendarDate,\n} from \"../operations/validate.js\";\n\nexport { convertCalendarDate } from \"../operations/convert-calendar-date.js\";\n\nexport { sameAbsoluteDate, sameCalendarDate } from \"../operations/compare.js\";\n\nexport { gregorianAdapter, iso8601Adapter } from \"./gregory/index.js\";\n\nexport { buddhistAdapter } from \"./buddhist/index.js\";\n\nexport { islamicCivilAdapter, islamicTblaAdapter } from \"./hijri/index.js\";\n\nexport {\n japaneseAdapter,\n findJapaneseEraForAbsoluteDay,\n JAPANESE_ERAS,\n} from \"./japanese/index.js\";\n\nexport { rocAdapter, ROC_OFFSET } from \"./roc/index.js\";\n\nexport {\n persianAdapter,\n isPersianLeapYear,\n daysInPersianMonth,\n} from \"./persian/index.js\";\n\nexport {\n indianAdapter,\n isIndianLeapYear,\n daysInIndianMonth,\n} from \"./indian/index.js\";\n\nexport { CalendarRegistry, defaultCalendarRegistry } from \"./registry.js\";\n\nexport type {\n CalendarAdapter,\n CalendarConverter,\n CalendarIdentity,\n CalendarValidator,\n CalendarArithmetic,\n} from \"./types.js\";\n\nexport type {\n CalendarCapabilities,\n CalendarConversionMetadata,\n CalendarConversionResult,\n CalendarDate,\n CalendarId,\n CalendarPlugin,\n} from \"../public-types.js\";\n"]}
@@ -0,0 +1,2 @@
1
+ import type { CalendarAdapter } from "../types.js";
2
+ export declare const indianAdapter: CalendarAdapter;
@@ -0,0 +1,66 @@
1
+ import { absoluteDayFromGregorianFields, gregorianFieldsFromAbsoluteDay, } from "../../core/absolute-day.js";
2
+ import { formatGregorianMonthCode, parseGregorianMonthCode, } from "../../core/gregorian-math.js";
3
+ import { ChroneraError } from "../../errors/errors.js";
4
+ import { INDIAN_IDENTITY, SAKA_OFFSET } from "./constants.js";
5
+ import { daysInIndianMonth, indianValidator, isIndianLeapYear, } from "./validator.js";
6
+ function getChaitra1AbsoluteDay(sakaYear) {
7
+ const gYear = sakaYear + SAKA_OFFSET;
8
+ const isLeap = isIndianLeapYear(sakaYear);
9
+ return absoluteDayFromGregorianFields(gYear, 3, isLeap ? 21 : 22);
10
+ }
11
+ export const indianAdapter = {
12
+ identity: INDIAN_IDENTITY,
13
+ validator: indianValidator,
14
+ converter: {
15
+ identity: INDIAN_IDENTITY,
16
+ toAbsoluteDay(date) {
17
+ const month = parseGregorianMonthCode(date.monthCode);
18
+ if (month === null) {
19
+ throw new ChroneraError("CHRONERA_INVALID_DATE", `Invalid monthCode: "${date.monthCode}". Expected M01-M12.`);
20
+ }
21
+ if (date.year < 1) {
22
+ throw new ChroneraError("CHRONERA_OUT_OF_RANGE", `Indian Saka calendar supports years >= 1. Received year ${date.year}.`);
23
+ }
24
+ const chaitra1 = getChaitra1AbsoluteDay(date.year);
25
+ let daysBeforeMonth = 0;
26
+ for (let m = 1; m < month; m++) {
27
+ daysBeforeMonth += daysInIndianMonth(date.year, m);
28
+ }
29
+ return chaitra1 + daysBeforeMonth + (date.day - 1);
30
+ },
31
+ fromAbsoluteDay(absoluteDay) {
32
+ const gFields = gregorianFieldsFromAbsoluteDay(absoluteDay);
33
+ let sakaYear = gFields.year - SAKA_OFFSET;
34
+ // Adjust if before 1 Chaitra of candidate sakaYear
35
+ if (absoluteDay < getChaitra1AbsoluteDay(sakaYear)) {
36
+ sakaYear--;
37
+ }
38
+ if (sakaYear < 1) {
39
+ throw new ChroneraError("CHRONERA_OUT_OF_RANGE", `Date is before Indian Saka epoch (Year 1, 79 CE).`);
40
+ }
41
+ const chaitra1 = getChaitra1AbsoluteDay(sakaYear);
42
+ let dayOfYear = absoluteDay - chaitra1; // 0-based
43
+ let month = 1;
44
+ while (month <= 12) {
45
+ const dim = daysInIndianMonth(sakaYear, month);
46
+ if (dayOfYear < dim) {
47
+ break;
48
+ }
49
+ dayOfYear -= dim;
50
+ month++;
51
+ }
52
+ const day = dayOfYear + 1;
53
+ return {
54
+ kind: "calendar-date",
55
+ calendar: "indian",
56
+ era: "saka",
57
+ eraYear: sakaYear,
58
+ year: sakaYear,
59
+ monthCode: formatGregorianMonthCode(month),
60
+ month,
61
+ day,
62
+ };
63
+ },
64
+ },
65
+ };
66
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/calendar/indian/adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n absoluteDayFromGregorianFields,\n gregorianFieldsFromAbsoluteDay,\n} from \"../../core/absolute-day.js\";\nimport {\n formatGregorianMonthCode,\n parseGregorianMonthCode,\n} from \"../../core/gregorian-math.js\";\nimport { ChroneraError } from \"../../errors/errors.js\";\nimport { INDIAN_IDENTITY, SAKA_OFFSET } from \"./constants.js\";\nimport {\n daysInIndianMonth,\n indianValidator,\n isIndianLeapYear,\n} from \"./validator.js\";\n\nimport type { CalendarAdapter } from \"../types.js\";\nimport type { CalendarDate } from \"../../public-types.js\";\n\nfunction getChaitra1AbsoluteDay(sakaYear: number): number {\n const gYear = sakaYear + SAKA_OFFSET;\n const isLeap = isIndianLeapYear(sakaYear);\n return absoluteDayFromGregorianFields(gYear, 3, isLeap ? 21 : 22);\n}\n\nexport const indianAdapter: CalendarAdapter = {\n identity: INDIAN_IDENTITY,\n validator: indianValidator,\n converter: {\n identity: INDIAN_IDENTITY,\n toAbsoluteDay(date: CalendarDate): number {\n const month = parseGregorianMonthCode(date.monthCode);\n if (month === null) {\n throw new ChroneraError(\n \"CHRONERA_INVALID_DATE\",\n `Invalid monthCode: \"${date.monthCode}\". Expected M01-M12.`,\n );\n }\n\n if (date.year < 1) {\n throw new ChroneraError(\n \"CHRONERA_OUT_OF_RANGE\",\n `Indian Saka calendar supports years >= 1. Received year ${date.year}.`,\n );\n }\n\n const chaitra1 = getChaitra1AbsoluteDay(date.year);\n let daysBeforeMonth = 0;\n for (let m = 1; m < month; m++) {\n daysBeforeMonth += daysInIndianMonth(date.year, m);\n }\n\n return chaitra1 + daysBeforeMonth + (date.day - 1);\n },\n\n fromAbsoluteDay(absoluteDay: number): CalendarDate {\n const gFields = gregorianFieldsFromAbsoluteDay(absoluteDay);\n let sakaYear = gFields.year - SAKA_OFFSET;\n\n // Adjust if before 1 Chaitra of candidate sakaYear\n if (absoluteDay < getChaitra1AbsoluteDay(sakaYear)) {\n sakaYear--;\n }\n\n if (sakaYear < 1) {\n throw new ChroneraError(\n \"CHRONERA_OUT_OF_RANGE\",\n `Date is before Indian Saka epoch (Year 1, 79 CE).`,\n );\n }\n\n const chaitra1 = getChaitra1AbsoluteDay(sakaYear);\n let dayOfYear = absoluteDay - chaitra1; // 0-based\n\n let month = 1;\n while (month <= 12) {\n const dim = daysInIndianMonth(sakaYear, month);\n if (dayOfYear < dim) {\n break;\n }\n dayOfYear -= dim;\n month++;\n }\n\n const day = dayOfYear + 1;\n return {\n kind: \"calendar-date\",\n calendar: \"indian\",\n era: \"saka\",\n eraYear: sakaYear,\n year: sakaYear,\n monthCode: formatGregorianMonthCode(month),\n month,\n day,\n };\n },\n },\n};\n"]}
@@ -0,0 +1,5 @@
1
+ import type { CalendarIdentity } from "../types.js";
2
+ export declare const SAKA_OFFSET = 78;
3
+ export declare const INDIAN_IDENTITY: CalendarIdentity;
4
+ export declare const INDIAN_MONTH_NAMES: readonly ["Chaitra", "Vaishakha", "Jyeshtha", "Ashadha", "Shravana", "Bhadra", "Ashvina", "Kartika", "Agrahayana", "Pausha", "Magha", "Phalguna"];
5
+ export declare const INDIAN_MONTH_NAMES_HI: readonly ["चैत्र", "वैशाख", "ज्येष्ठ", "आषाढ़", "श्रावण", "भाद्रपद", "अश्विन", "कार्तिक", "अग्रहायण", "पौष", "माघ", "फाल्गुन"];
@@ -0,0 +1,43 @@
1
+ import { MAX_ABSOLUTE_DAY } from "../../core/absolute-day.js";
2
+ export const SAKA_OFFSET = 78;
3
+ // 1 Chaitra 1 Saka = 79-03-24 CE (or March 22). Absolute day: -690623
4
+ export const INDIAN_IDENTITY = {
5
+ id: "indian",
6
+ algorithm: "chronera-indian-saka-v1",
7
+ deterministic: true,
8
+ validRange: {
9
+ first: -690623,
10
+ last: MAX_ABSOLUTE_DAY,
11
+ },
12
+ validFrom: { kind: "local-date", year: 79, month: 3, day: 22 },
13
+ validTo: { kind: "local-date", year: 9999, month: 12, day: 31 },
14
+ };
15
+ export const INDIAN_MONTH_NAMES = [
16
+ "Chaitra",
17
+ "Vaishakha",
18
+ "Jyeshtha",
19
+ "Ashadha",
20
+ "Shravana",
21
+ "Bhadra",
22
+ "Ashvina",
23
+ "Kartika",
24
+ "Agrahayana",
25
+ "Pausha",
26
+ "Magha",
27
+ "Phalguna",
28
+ ];
29
+ export const INDIAN_MONTH_NAMES_HI = [
30
+ "चैत्र",
31
+ "वैशाख",
32
+ "ज्येष्ठ",
33
+ "आषाढ़",
34
+ "श्रावण",
35
+ "भाद्रपद",
36
+ "अश्विन",
37
+ "कार्तिक",
38
+ "अग्रहायण",
39
+ "पौष",
40
+ "माघ",
41
+ "फाल्गुन",
42
+ ];
43
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/calendar/indian/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAG9D,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAE9B,sEAAsE;AACtE,MAAM,CAAC,MAAM,eAAe,GAAqB;IAC/C,EAAE,EAAE,QAAQ;IACZ,SAAS,EAAE,yBAAyB;IACpC,aAAa,EAAE,IAAI;IACnB,UAAU,EAAE;QACV,KAAK,EAAE,CAAC,MAAM;QACd,IAAI,EAAE,gBAAgB;KACvB;IACD,SAAS,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;IAC9D,OAAO,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;CAChE,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,SAAS;IACT,WAAW;IACX,UAAU;IACV,SAAS;IACT,UAAU;IACV,QAAQ;IACR,SAAS;IACT,SAAS;IACT,YAAY;IACZ,QAAQ;IACR,OAAO;IACP,UAAU;CACF,CAAC;AAEX,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,OAAO;IACP,OAAO;IACP,SAAS;IACT,OAAO;IACP,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,SAAS;IACT,UAAU;IACV,KAAK;IACL,KAAK;IACL,SAAS;CACD,CAAC","sourcesContent":["import { MAX_ABSOLUTE_DAY } from \"../../core/absolute-day.js\";\nimport type { CalendarIdentity } from \"../types.js\";\n\nexport const SAKA_OFFSET = 78;\n\n// 1 Chaitra 1 Saka = 79-03-24 CE (or March 22). Absolute day: -690623\nexport const INDIAN_IDENTITY: CalendarIdentity = {\n id: \"indian\",\n algorithm: \"chronera-indian-saka-v1\",\n deterministic: true,\n validRange: {\n first: -690623,\n last: MAX_ABSOLUTE_DAY,\n },\n validFrom: { kind: \"local-date\", year: 79, month: 3, day: 22 },\n validTo: { kind: \"local-date\", year: 9999, month: 12, day: 31 },\n};\n\nexport const INDIAN_MONTH_NAMES = [\n \"Chaitra\",\n \"Vaishakha\",\n \"Jyeshtha\",\n \"Ashadha\",\n \"Shravana\",\n \"Bhadra\",\n \"Ashvina\",\n \"Kartika\",\n \"Agrahayana\",\n \"Pausha\",\n \"Magha\",\n \"Phalguna\",\n] as const;\n\nexport const INDIAN_MONTH_NAMES_HI = [\n \"चैत्र\",\n \"वैशाख\",\n \"ज्येष्ठ\",\n \"आषाढ़\",\n \"श्रावण\",\n \"भाद्रपद\",\n \"अश्विन\",\n \"कार्तिक\",\n \"अग्रहायण\",\n \"पौष\",\n \"माघ\",\n \"फाल्गुन\",\n] as const;\n"]}
@@ -0,0 +1,3 @@
1
+ export { SAKA_OFFSET, INDIAN_MONTH_NAMES, INDIAN_MONTH_NAMES_HI, } from "./constants.js";
2
+ export { indianValidator, assertIndianDate, isIndianLeapYear, daysInIndianMonth, } from "./validator.js";
3
+ export { indianAdapter } from "./adapter.js";
@@ -0,0 +1,4 @@
1
+ export { SAKA_OFFSET, INDIAN_MONTH_NAMES, INDIAN_MONTH_NAMES_HI, } from "./constants.js";
2
+ export { indianValidator, assertIndianDate, isIndianLeapYear, daysInIndianMonth, } from "./validator.js";
3
+ export { indianAdapter } from "./adapter.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/calendar/indian/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC","sourcesContent":["export {\n SAKA_OFFSET,\n INDIAN_MONTH_NAMES,\n INDIAN_MONTH_NAMES_HI,\n} from \"./constants.js\";\nexport {\n indianValidator,\n assertIndianDate,\n isIndianLeapYear,\n daysInIndianMonth,\n} from \"./validator.js\";\nexport { indianAdapter } from \"./adapter.js\";\n"]}
@@ -0,0 +1,6 @@
1
+ import type { CalendarValidator } from "../types.js";
2
+ import type { CalendarDate } from "../../public-types.js";
3
+ export declare function assertIndianDate(date: CalendarDate): void;
4
+ export declare function isIndianLeapYear(sakaYear: number): boolean;
5
+ export declare function daysInIndianMonth(sakaYear: number, month: number): number;
6
+ export declare const indianValidator: CalendarValidator;
@@ -0,0 +1,65 @@
1
+ import { isGregorianLeapYear, parseGregorianMonthCode, } from "../../core/gregorian-math.js";
2
+ import { ChroneraError } from "../../errors/errors.js";
3
+ import { INDIAN_IDENTITY, SAKA_OFFSET } from "./constants.js";
4
+ export function assertIndianDate(date) {
5
+ if (date.calendar !== "indian") {
6
+ throw new ChroneraError("CHRONERA_INVALID_CALENDAR", `Expected calendar "indian", received "${date.calendar}".`);
7
+ }
8
+ }
9
+ export function isIndianLeapYear(sakaYear) {
10
+ return isGregorianLeapYear(sakaYear + SAKA_OFFSET);
11
+ }
12
+ export function daysInIndianMonth(sakaYear, month) {
13
+ if (month < 1 || month > 12)
14
+ return 0;
15
+ if (month === 1) {
16
+ return isIndianLeapYear(sakaYear) ? 31 : 30;
17
+ }
18
+ if (month <= 6) {
19
+ return 31;
20
+ }
21
+ return 30;
22
+ }
23
+ export const indianValidator = {
24
+ identity: INDIAN_IDENTITY,
25
+ validate(date) {
26
+ assertIndianDate(date);
27
+ const issues = [];
28
+ const monthNum = parseGregorianMonthCode(date.monthCode);
29
+ if (monthNum === null) {
30
+ issues.push({
31
+ code: "CHRONERA_INVALID_DATE",
32
+ message: `Invalid monthCode: "${date.monthCode}". Expected M01-M12.`,
33
+ path: ["monthCode"],
34
+ });
35
+ return issues;
36
+ }
37
+ if (date.year < 1 || date.year > 9900) {
38
+ issues.push({
39
+ code: "CHRONERA_OUT_OF_RANGE",
40
+ message: `Indian Saka calendar supports years 1..9900. Received year: ${date.year}.`,
41
+ path: ["year"],
42
+ });
43
+ }
44
+ const maxDays = daysInIndianMonth(date.year, monthNum);
45
+ if (date.day < 1 || date.day > maxDays) {
46
+ issues.push({
47
+ code: "CHRONERA_INVALID_DATE",
48
+ message: `Invalid day ${date.day} for Saka year ${date.year} month ${monthNum}. Expected 1..${maxDays}.`,
49
+ path: ["day"],
50
+ });
51
+ }
52
+ return issues;
53
+ },
54
+ daysInMonth(year, monthCode) {
55
+ const month = parseGregorianMonthCode(monthCode);
56
+ if (month === null) {
57
+ throw new ChroneraError("CHRONERA_INVALID_DATE", `Invalid monthCode: "${monthCode}". Expected M01-M12.`);
58
+ }
59
+ return daysInIndianMonth(year, month);
60
+ },
61
+ isLeapYear(year) {
62
+ return isIndianLeapYear(year);
63
+ },
64
+ };
65
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../../src/calendar/indian/validator.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n isGregorianLeapYear,\n parseGregorianMonthCode,\n} from \"../../core/gregorian-math.js\";\nimport { ChroneraError } from \"../../errors/errors.js\";\nimport { INDIAN_IDENTITY, SAKA_OFFSET } from \"./constants.js\";\n\nimport type { CalendarValidator } from \"../types.js\";\nimport type {\n CalendarDate,\n ChroneraIssue,\n MonthCode,\n} from \"../../public-types.js\";\n\nexport function assertIndianDate(date: CalendarDate): void {\n if (date.calendar !== \"indian\") {\n throw new ChroneraError(\n \"CHRONERA_INVALID_CALENDAR\",\n `Expected calendar \"indian\", received \"${date.calendar}\".`,\n );\n }\n}\n\nexport function isIndianLeapYear(sakaYear: number): boolean {\n return isGregorianLeapYear(sakaYear + SAKA_OFFSET);\n}\n\nexport function daysInIndianMonth(sakaYear: number, month: number): number {\n if (month < 1 || month > 12) return 0;\n if (month === 1) {\n return isIndianLeapYear(sakaYear) ? 31 : 30;\n }\n if (month <= 6) {\n return 31;\n }\n return 30;\n}\n\nexport const indianValidator: CalendarValidator = {\n identity: INDIAN_IDENTITY,\n\n validate(date: CalendarDate): readonly ChroneraIssue[] {\n assertIndianDate(date);\n const issues: ChroneraIssue[] = [];\n\n const monthNum = parseGregorianMonthCode(date.monthCode);\n if (monthNum === null) {\n issues.push({\n code: \"CHRONERA_INVALID_DATE\",\n message: `Invalid monthCode: \"${date.monthCode}\". Expected M01-M12.`,\n path: [\"monthCode\"],\n });\n return issues;\n }\n\n if (date.year < 1 || date.year > 9900) {\n issues.push({\n code: \"CHRONERA_OUT_OF_RANGE\",\n message: `Indian Saka calendar supports years 1..9900. Received year: ${date.year}.`,\n path: [\"year\"],\n });\n }\n\n const maxDays = daysInIndianMonth(date.year, monthNum);\n if (date.day < 1 || date.day > maxDays) {\n issues.push({\n code: \"CHRONERA_INVALID_DATE\",\n message: `Invalid day ${date.day} for Saka year ${date.year} month ${monthNum}. Expected 1..${maxDays}.`,\n path: [\"day\"],\n });\n }\n\n return issues;\n },\n\n daysInMonth(year: number, monthCode: MonthCode): number {\n const month = parseGregorianMonthCode(monthCode);\n if (month === null) {\n throw new ChroneraError(\n \"CHRONERA_INVALID_DATE\",\n `Invalid monthCode: \"${monthCode}\". Expected M01-M12.`,\n );\n }\n return daysInIndianMonth(year, month);\n },\n\n isLeapYear(year: number): boolean {\n return isIndianLeapYear(year);\n },\n};\n"]}
@@ -0,0 +1,3 @@
1
+ import type { CalendarAdapter } from "../types.js";
2
+ export declare function findJapaneseEraForAbsoluteDay(absoluteDay: number): import("./constants.js").JapaneseEraDefinition;
3
+ export declare const japaneseAdapter: CalendarAdapter;
@@ -0,0 +1,63 @@
1
+ import { absoluteDayFromGregorianFields, gregorianFieldsFromAbsoluteDay, } from "../../core/absolute-day.js";
2
+ import { formatGregorianMonthCode, parseGregorianMonthCode, } from "../../core/gregorian-math.js";
3
+ import { ChroneraError } from "../../errors/errors.js";
4
+ import { JAPANESE_ERAS, JAPANESE_IDENTITY } from "./constants.js";
5
+ import { japaneseValidator, resolveJapaneseEra } from "./validator.js";
6
+ export function findJapaneseEraForAbsoluteDay(absoluteDay) {
7
+ for (const era of JAPANESE_ERAS) {
8
+ if (absoluteDay >= era.startAbsoluteDay) {
9
+ return era;
10
+ }
11
+ }
12
+ // Fallback to earliest supported era (Meiji)
13
+ return JAPANESE_ERAS[JAPANESE_ERAS.length - 1];
14
+ }
15
+ export const japaneseAdapter = {
16
+ identity: JAPANESE_IDENTITY,
17
+ validator: japaneseValidator,
18
+ converter: {
19
+ identity: JAPANESE_IDENTITY,
20
+ toAbsoluteDay(date) {
21
+ const month = parseGregorianMonthCode(date.monthCode);
22
+ if (month === null) {
23
+ throw new ChroneraError("CHRONERA_INVALID_DATE", `Invalid monthCode: "${date.monthCode}". Expected M01-M12.`);
24
+ }
25
+ let gregorianYear = date.year;
26
+ if (date.era) {
27
+ const eraDef = resolveJapaneseEra(date.era);
28
+ if (!eraDef) {
29
+ throw new ChroneraError("CHRONERA_INVALID_DATE", `Unknown Japanese era: "${date.era}". Expected reiwa, heisei, showa, taisho, meiji.`);
30
+ }
31
+ if (date.eraYear !== undefined) {
32
+ gregorianYear = eraDef.offset + date.eraYear;
33
+ }
34
+ else if (date.year < 100) {
35
+ gregorianYear = eraDef.offset + date.year;
36
+ }
37
+ }
38
+ if (gregorianYear < 1868 || gregorianYear > 9999) {
39
+ throw new ChroneraError("CHRONERA_OUT_OF_RANGE", `Japanese calendar supports dates between 1868 and 9999 CE. Received year ${gregorianYear}.`);
40
+ }
41
+ return absoluteDayFromGregorianFields(gregorianYear, month, date.day);
42
+ },
43
+ fromAbsoluteDay(absoluteDay) {
44
+ const fields = gregorianFieldsFromAbsoluteDay(absoluteDay);
45
+ if (fields.year < 1868 || fields.year > 9999) {
46
+ throw new ChroneraError("CHRONERA_OUT_OF_RANGE", `Japanese calendar supports dates between 1868 and 9999 CE. Received Gregorian year ${fields.year}.`);
47
+ }
48
+ const era = findJapaneseEraForAbsoluteDay(absoluteDay);
49
+ const eraYear = fields.year - era.offset;
50
+ return {
51
+ kind: "calendar-date",
52
+ calendar: "japanese",
53
+ era: era.id,
54
+ eraYear,
55
+ year: fields.year,
56
+ monthCode: formatGregorianMonthCode(fields.month),
57
+ month: fields.month,
58
+ day: fields.day,
59
+ };
60
+ },
61
+ },
62
+ };
63
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/calendar/japanese/adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n absoluteDayFromGregorianFields,\n gregorianFieldsFromAbsoluteDay,\n} from \"../../core/absolute-day.js\";\nimport {\n formatGregorianMonthCode,\n parseGregorianMonthCode,\n} from \"../../core/gregorian-math.js\";\nimport { ChroneraError } from \"../../errors/errors.js\";\nimport { JAPANESE_ERAS, JAPANESE_IDENTITY } from \"./constants.js\";\nimport { japaneseValidator, resolveJapaneseEra } from \"./validator.js\";\n\nimport type { CalendarAdapter } from \"../types.js\";\nimport type { CalendarDate } from \"../../public-types.js\";\n\nexport function findJapaneseEraForAbsoluteDay(absoluteDay: number) {\n for (const era of JAPANESE_ERAS) {\n if (absoluteDay >= era.startAbsoluteDay) {\n return era;\n }\n }\n // Fallback to earliest supported era (Meiji)\n return JAPANESE_ERAS[JAPANESE_ERAS.length - 1]!;\n}\n\nexport const japaneseAdapter: CalendarAdapter = {\n identity: JAPANESE_IDENTITY,\n validator: japaneseValidator,\n converter: {\n identity: JAPANESE_IDENTITY,\n toAbsoluteDay(date: CalendarDate): number {\n const month = parseGregorianMonthCode(date.monthCode);\n if (month === null) {\n throw new ChroneraError(\n \"CHRONERA_INVALID_DATE\",\n `Invalid monthCode: \"${date.monthCode}\". Expected M01-M12.`,\n );\n }\n\n let gregorianYear = date.year;\n if (date.era) {\n const eraDef = resolveJapaneseEra(date.era);\n if (!eraDef) {\n throw new ChroneraError(\n \"CHRONERA_INVALID_DATE\",\n `Unknown Japanese era: \"${date.era}\". Expected reiwa, heisei, showa, taisho, meiji.`,\n );\n }\n if (date.eraYear !== undefined) {\n gregorianYear = eraDef.offset + date.eraYear;\n } else if (date.year < 100) {\n gregorianYear = eraDef.offset + date.year;\n }\n }\n\n if (gregorianYear < 1868 || gregorianYear > 9999) {\n throw new ChroneraError(\n \"CHRONERA_OUT_OF_RANGE\",\n `Japanese calendar supports dates between 1868 and 9999 CE. Received year ${gregorianYear}.`,\n );\n }\n\n return absoluteDayFromGregorianFields(gregorianYear, month, date.day);\n },\n\n fromAbsoluteDay(absoluteDay: number): CalendarDate {\n const fields = gregorianFieldsFromAbsoluteDay(absoluteDay);\n if (fields.year < 1868 || fields.year > 9999) {\n throw new ChroneraError(\n \"CHRONERA_OUT_OF_RANGE\",\n `Japanese calendar supports dates between 1868 and 9999 CE. Received Gregorian year ${fields.year}.`,\n );\n }\n\n const era = findJapaneseEraForAbsoluteDay(absoluteDay);\n const eraYear = fields.year - era.offset;\n\n return {\n kind: \"calendar-date\",\n calendar: \"japanese\",\n era: era.id,\n eraYear,\n year: fields.year,\n monthCode: formatGregorianMonthCode(fields.month),\n month: fields.month,\n day: fields.day,\n };\n },\n },\n};\n"]}
@@ -0,0 +1,17 @@
1
+ export interface JapaneseEraDefinition {
2
+ readonly id: string;
3
+ readonly kanji: string;
4
+ readonly romaji: string;
5
+ readonly startYear: number;
6
+ readonly startMonth: number;
7
+ readonly startDay: number;
8
+ readonly startAbsoluteDay: number;
9
+ readonly offset: number;
10
+ }
11
+ import type { CalendarIdentity } from "../types.js";
12
+ export declare const JAPANESE_IDENTITY: CalendarIdentity;
13
+ export declare const JAPANESE_ERAS: readonly JapaneseEraDefinition[];
14
+ export declare const JAPANESE_WEEKDAY_NAMES: readonly ["日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日"];
15
+ export declare const JAPANESE_WEEKDAY_SHORT: readonly ["日", "月", "火", "水", "木", "金", "土"];
16
+ export declare const ERA_BY_ID: Map<string, JapaneseEraDefinition>;
17
+ export declare const ERA_BY_KANJI: Map<string, JapaneseEraDefinition>;
@@ -0,0 +1,85 @@
1
+ import { MAX_ABSOLUTE_DAY } from "../../core/absolute-day.js";
2
+ export const JAPANESE_IDENTITY = {
3
+ id: "japanese",
4
+ algorithm: "chronera-japanese-v1",
5
+ deterministic: true,
6
+ validRange: {
7
+ first: -36997, // 1868-09-08 (Meiji 1)
8
+ last: MAX_ABSOLUTE_DAY,
9
+ },
10
+ validFrom: { kind: "local-date", year: 1868, month: 9, day: 8 },
11
+ validTo: { kind: "local-date", year: 9999, month: 12, day: 31 },
12
+ };
13
+ export const JAPANESE_ERAS = [
14
+ {
15
+ id: "reiwa",
16
+ kanji: "令和",
17
+ romaji: "Reiwa",
18
+ startYear: 2019,
19
+ startMonth: 5,
20
+ startDay: 1,
21
+ startAbsoluteDay: 18017,
22
+ offset: 2018,
23
+ },
24
+ {
25
+ id: "heisei",
26
+ kanji: "平成",
27
+ romaji: "Heisei",
28
+ startYear: 1989,
29
+ startMonth: 1,
30
+ startDay: 8,
31
+ startAbsoluteDay: 6947,
32
+ offset: 1988,
33
+ },
34
+ {
35
+ id: "showa",
36
+ kanji: "昭和",
37
+ romaji: "Showa",
38
+ startYear: 1926,
39
+ startMonth: 12,
40
+ startDay: 25,
41
+ startAbsoluteDay: -15713,
42
+ offset: 1925,
43
+ },
44
+ {
45
+ id: "taisho",
46
+ kanji: "大正",
47
+ romaji: "Taisho",
48
+ startYear: 1912,
49
+ startMonth: 7,
50
+ startDay: 30,
51
+ startAbsoluteDay: -20974,
52
+ offset: 1911,
53
+ },
54
+ {
55
+ id: "meiji",
56
+ kanji: "明治",
57
+ romaji: "Meiji",
58
+ startYear: 1868,
59
+ startMonth: 9,
60
+ startDay: 8,
61
+ startAbsoluteDay: -36997,
62
+ offset: 1867,
63
+ },
64
+ ];
65
+ export const JAPANESE_WEEKDAY_NAMES = [
66
+ "日曜日", // Sunday
67
+ "月曜日", // Monday
68
+ "火曜日", // Tuesday
69
+ "水曜日", // Wednesday
70
+ "木曜日", // Thursday
71
+ "金曜日", // Friday
72
+ "土曜日", // Saturday
73
+ ];
74
+ export const JAPANESE_WEEKDAY_SHORT = [
75
+ "日",
76
+ "月",
77
+ "火",
78
+ "水",
79
+ "木",
80
+ "金",
81
+ "土",
82
+ ];
83
+ export const ERA_BY_ID = new Map(JAPANESE_ERAS.map((e) => [e.id, e]));
84
+ export const ERA_BY_KANJI = new Map(JAPANESE_ERAS.map((e) => [e.kanji, e]));
85
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/calendar/japanese/constants.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAG9D,MAAM,CAAC,MAAM,iBAAiB,GAAqB;IACjD,EAAE,EAAE,UAAU;IACd,SAAS,EAAE,sBAAsB;IACjC,aAAa,EAAE,IAAI;IACnB,UAAU,EAAE;QACV,KAAK,EAAE,CAAC,KAAK,EAAE,uBAAuB;QACtC,IAAI,EAAE,gBAAgB;KACvB;IACD,SAAS,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;IAC/D,OAAO,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;CAChE,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAqC;IAC7D;QACE,EAAE,EAAE,OAAO;QACX,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,OAAO;QACf,SAAS,EAAE,IAAI;QACf,UAAU,EAAE,CAAC;QACb,QAAQ,EAAE,CAAC;QACX,gBAAgB,EAAE,KAAK;QACvB,MAAM,EAAE,IAAI;KACb;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,QAAQ;QAChB,SAAS,EAAE,IAAI;QACf,UAAU,EAAE,CAAC;QACb,QAAQ,EAAE,CAAC;QACX,gBAAgB,EAAE,IAAI;QACtB,MAAM,EAAE,IAAI;KACb;IACD;QACE,EAAE,EAAE,OAAO;QACX,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,OAAO;QACf,SAAS,EAAE,IAAI;QACf,UAAU,EAAE,EAAE;QACd,QAAQ,EAAE,EAAE;QACZ,gBAAgB,EAAE,CAAC,KAAK;QACxB,MAAM,EAAE,IAAI;KACb;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,QAAQ;QAChB,SAAS,EAAE,IAAI;QACf,UAAU,EAAE,CAAC;QACb,QAAQ,EAAE,EAAE;QACZ,gBAAgB,EAAE,CAAC,KAAK;QACxB,MAAM,EAAE,IAAI;KACb;IACD;QACE,EAAE,EAAE,OAAO;QACX,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,OAAO;QACf,SAAS,EAAE,IAAI;QACf,UAAU,EAAE,CAAC;QACb,QAAQ,EAAE,CAAC;QACX,gBAAgB,EAAE,CAAC,KAAK;QACxB,MAAM,EAAE,IAAI;KACb;CACO,CAAC;AAEX,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,KAAK,EAAE,SAAS;IAChB,KAAK,EAAE,SAAS;IAChB,KAAK,EAAE,UAAU;IACjB,KAAK,EAAE,YAAY;IACnB,KAAK,EAAE,WAAW;IAClB,KAAK,EAAE,SAAS;IAChB,KAAK,EAAE,WAAW;CACV,CAAC;AAEX,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;CACK,CAAC;AAEX,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,GAAG,CAC9B,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CACpC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,GAAG,CACjC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CACvC,CAAC","sourcesContent":["export interface JapaneseEraDefinition {\n readonly id: string;\n readonly kanji: string;\n readonly romaji: string;\n readonly startYear: number;\n readonly startMonth: number;\n readonly startDay: number;\n readonly startAbsoluteDay: number;\n readonly offset: number; // gregorianYear - offset = eraYear\n}\n\nimport { MAX_ABSOLUTE_DAY } from \"../../core/absolute-day.js\";\nimport type { CalendarIdentity } from \"../types.js\";\n\nexport const JAPANESE_IDENTITY: CalendarIdentity = {\n id: \"japanese\",\n algorithm: \"chronera-japanese-v1\",\n deterministic: true,\n validRange: {\n first: -36997, // 1868-09-08 (Meiji 1)\n last: MAX_ABSOLUTE_DAY,\n },\n validFrom: { kind: \"local-date\", year: 1868, month: 9, day: 8 },\n validTo: { kind: \"local-date\", year: 9999, month: 12, day: 31 },\n};\n\nexport const JAPANESE_ERAS: readonly JapaneseEraDefinition[] = [\n {\n id: \"reiwa\",\n kanji: \"令和\",\n romaji: \"Reiwa\",\n startYear: 2019,\n startMonth: 5,\n startDay: 1,\n startAbsoluteDay: 18017,\n offset: 2018,\n },\n {\n id: \"heisei\",\n kanji: \"平成\",\n romaji: \"Heisei\",\n startYear: 1989,\n startMonth: 1,\n startDay: 8,\n startAbsoluteDay: 6947,\n offset: 1988,\n },\n {\n id: \"showa\",\n kanji: \"昭和\",\n romaji: \"Showa\",\n startYear: 1926,\n startMonth: 12,\n startDay: 25,\n startAbsoluteDay: -15713,\n offset: 1925,\n },\n {\n id: \"taisho\",\n kanji: \"大正\",\n romaji: \"Taisho\",\n startYear: 1912,\n startMonth: 7,\n startDay: 30,\n startAbsoluteDay: -20974,\n offset: 1911,\n },\n {\n id: \"meiji\",\n kanji: \"明治\",\n romaji: \"Meiji\",\n startYear: 1868,\n startMonth: 9,\n startDay: 8,\n startAbsoluteDay: -36997,\n offset: 1867,\n },\n] as const;\n\nexport const JAPANESE_WEEKDAY_NAMES = [\n \"日曜日\", // Sunday\n \"月曜日\", // Monday\n \"火曜日\", // Tuesday\n \"水曜日\", // Wednesday\n \"木曜日\", // Thursday\n \"金曜日\", // Friday\n \"土曜日\", // Saturday\n] as const;\n\nexport const JAPANESE_WEEKDAY_SHORT = [\n \"日\",\n \"月\",\n \"火\",\n \"水\",\n \"木\",\n \"金\",\n \"土\",\n] as const;\n\nexport const ERA_BY_ID = new Map<string, JapaneseEraDefinition>(\n JAPANESE_ERAS.map((e) => [e.id, e]),\n);\n\nexport const ERA_BY_KANJI = new Map<string, JapaneseEraDefinition>(\n JAPANESE_ERAS.map((e) => [e.kanji, e]),\n);\n"]}
@@ -0,0 +1,3 @@
1
+ export { JAPANESE_ERAS, JAPANESE_WEEKDAY_NAMES, JAPANESE_WEEKDAY_SHORT, ERA_BY_ID, ERA_BY_KANJI, } from "./constants.js";
2
+ export { japaneseValidator, assertJapaneseDate, resolveJapaneseEra, } from "./validator.js";
3
+ export { japaneseAdapter, findJapaneseEraForAbsoluteDay } from "./adapter.js";
@@ -0,0 +1,4 @@
1
+ export { JAPANESE_ERAS, JAPANESE_WEEKDAY_NAMES, JAPANESE_WEEKDAY_SHORT, ERA_BY_ID, ERA_BY_KANJI, } from "./constants.js";
2
+ export { japaneseValidator, assertJapaneseDate, resolveJapaneseEra, } from "./validator.js";
3
+ export { japaneseAdapter, findJapaneseEraForAbsoluteDay } from "./adapter.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/calendar/japanese/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,sBAAsB,EACtB,sBAAsB,EACtB,SAAS,EACT,YAAY,GACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,6BAA6B,EAAE,MAAM,cAAc,CAAC","sourcesContent":["export {\n JAPANESE_ERAS,\n JAPANESE_WEEKDAY_NAMES,\n JAPANESE_WEEKDAY_SHORT,\n ERA_BY_ID,\n ERA_BY_KANJI,\n} from \"./constants.js\";\nexport {\n japaneseValidator,\n assertJapaneseDate,\n resolveJapaneseEra,\n} from \"./validator.js\";\nexport { japaneseAdapter, findJapaneseEraForAbsoluteDay } from \"./adapter.js\";\n"]}