temporal-fmt 0.8.982 → 0.8.984

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 (85) hide show
  1. package/LICENSE +196 -17
  2. package/README.md +1 -1
  3. package/dist/calendarUtils.cjs.map +1 -1
  4. package/dist/calendarUtils.js +2 -2
  5. package/dist/{chunk-GRJQHQLW.js → chunk-4D2ZYVPM.js} +3 -3
  6. package/dist/chunk-4D2ZYVPM.js.map +1 -0
  7. package/dist/{chunk-MXXYIMFJ.js → chunk-6YRWNUNV.js} +1 -1
  8. package/dist/chunk-6YRWNUNV.js.map +1 -0
  9. package/dist/{chunk-USONQ7MV.js → chunk-AK6OCTTF.js} +1 -1
  10. package/dist/chunk-AK6OCTTF.js.map +1 -0
  11. package/dist/{chunk-NFKQ3EXC.js → chunk-AKJOTI7X.js} +2 -2
  12. package/dist/chunk-AKJOTI7X.js.map +1 -0
  13. package/dist/{chunk-CSUIKL73.js → chunk-B5WSYLXA.js} +13 -4
  14. package/dist/chunk-B5WSYLXA.js.map +1 -0
  15. package/dist/{chunk-EDUFSRWJ.js → chunk-CXF2MG3C.js} +1 -1
  16. package/dist/chunk-CXF2MG3C.js.map +1 -0
  17. package/dist/{chunk-4ZBGVYLR.js → chunk-GNUK7PGX.js} +2 -2
  18. package/dist/chunk-GNUK7PGX.js.map +1 -0
  19. package/dist/{chunk-YNXTPXB5.js → chunk-HO3A2F44.js} +5 -5
  20. package/dist/chunk-HO3A2F44.js.map +1 -0
  21. package/dist/{chunk-RTPA5A5T.js → chunk-J3CXZ5KX.js} +3 -3
  22. package/dist/chunk-J3CXZ5KX.js.map +1 -0
  23. package/dist/{chunk-YS52LOMJ.js → chunk-QDNC4IEV.js} +1 -1
  24. package/dist/chunk-QDNC4IEV.js.map +1 -0
  25. package/dist/{chunk-B3BFPB3T.js → chunk-QWPJBAH6.js} +3 -3
  26. package/dist/chunk-QWPJBAH6.js.map +1 -0
  27. package/dist/{chunk-BNIIELG5.js → chunk-UMJ4PNNJ.js} +4 -4
  28. package/dist/chunk-UMJ4PNNJ.js.map +1 -0
  29. package/dist/{chunk-VHSZL3P3.js → chunk-UX4Z3WFS.js} +2 -2
  30. package/dist/chunk-UX4Z3WFS.js.map +1 -0
  31. package/dist/{chunk-KCSGCK7L.js → chunk-V44PCWPL.js} +76 -36
  32. package/dist/chunk-V44PCWPL.js.map +1 -0
  33. package/dist/{chunk-FRS42YLM.js → chunk-VR56MVFF.js} +4 -4
  34. package/dist/chunk-VR56MVFF.js.map +1 -0
  35. package/dist/{chunk-6MIVOWWX.js → chunk-WNVE76W7.js} +3 -3
  36. package/dist/chunk-WNVE76W7.js.map +1 -0
  37. package/dist/{chunk-3RLYULUQ.js → chunk-XJNDKHZI.js} +1 -1
  38. package/dist/chunk-XJNDKHZI.js.map +1 -0
  39. package/dist/{chunk-XIKLQMF7.js → chunk-YTZV6KET.js} +4 -4
  40. package/dist/chunk-YTZV6KET.js.map +1 -0
  41. package/dist/duration.cjs.map +1 -1
  42. package/dist/duration.js +7 -7
  43. package/dist/format.cjs.map +1 -1
  44. package/dist/format.js +8 -8
  45. package/dist/index.cjs +88 -30
  46. package/dist/index.cjs.map +1 -1
  47. package/dist/index.js +27 -18
  48. package/dist/index.js.map +1 -1
  49. package/dist/interval.cjs.map +1 -1
  50. package/dist/interval.js +11 -11
  51. package/dist/localeRegistry.cjs.map +1 -1
  52. package/dist/localeRegistry.js +3 -3
  53. package/dist/parse.cjs +69 -29
  54. package/dist/parse.cjs.map +1 -1
  55. package/dist/parse.js +8 -8
  56. package/dist/parsePattern.d.cts +1 -0
  57. package/dist/parsePattern.d.ts +1 -0
  58. package/dist/pattern.d.cts +1 -0
  59. package/dist/pattern.d.ts +1 -0
  60. package/dist/recurrence.cjs +10 -1
  61. package/dist/recurrence.cjs.map +1 -1
  62. package/dist/recurrence.js +5 -5
  63. package/dist/relativeTime.cjs.map +1 -1
  64. package/dist/relativeTime.js +7 -7
  65. package/dist/timezone.cjs.map +1 -1
  66. package/dist/timezone.js +5 -5
  67. package/package.json +3 -3
  68. package/dist/chunk-3RLYULUQ.js.map +0 -1
  69. package/dist/chunk-4ZBGVYLR.js.map +0 -1
  70. package/dist/chunk-6MIVOWWX.js.map +0 -1
  71. package/dist/chunk-B3BFPB3T.js.map +0 -1
  72. package/dist/chunk-BNIIELG5.js.map +0 -1
  73. package/dist/chunk-CSUIKL73.js.map +0 -1
  74. package/dist/chunk-EDUFSRWJ.js.map +0 -1
  75. package/dist/chunk-FRS42YLM.js.map +0 -1
  76. package/dist/chunk-GRJQHQLW.js.map +0 -1
  77. package/dist/chunk-KCSGCK7L.js.map +0 -1
  78. package/dist/chunk-MXXYIMFJ.js.map +0 -1
  79. package/dist/chunk-NFKQ3EXC.js.map +0 -1
  80. package/dist/chunk-RTPA5A5T.js.map +0 -1
  81. package/dist/chunk-USONQ7MV.js.map +0 -1
  82. package/dist/chunk-VHSZL3P3.js.map +0 -1
  83. package/dist/chunk-XIKLQMF7.js.map +0 -1
  84. package/dist/chunk-YNXTPXB5.js.map +0 -1
  85. package/dist/chunk-YS52LOMJ.js.map +0 -1
package/LICENSE CHANGED
@@ -1,22 +1,201 @@
1
- MIT License
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
2
4
 
3
- Copyright (c) 2026 DirazCoder
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
4
6
 
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
7
+ 1. Definitions.
11
8
 
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
14
11
 
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
22
14
 
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright [yyyy] [name of copyright owner]
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
package/README.md CHANGED
@@ -1018,4 +1018,4 @@ A couple of build-specific notes if you're touching the toolchain:
1018
1018
 
1019
1019
  ## License
1020
1020
 
1021
- MIT — see [LICENSE](./LICENSE).
1021
+ Apache 2.0 — see [LICENSE](./LICENSE).
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/calendarUtils.ts","../src/isoWeek.ts"],"sourcesContent":["// Calendar utility helpers. These are pure functions\n// over the TemporalLike shape — no Temporal namespace needed, same\n// approach as isoWeek.ts and the field-reading helpers in format.ts.\n// Letting callers compute dayOfYear/weekOfYear/etc. without going\n// through format() means they can build their own derived values\n// without committing to a string format.\n//\n// Calendar-sensitivity: the helpers in this module assume the\n// iso8601 (Gregorian) calendar — that's what TemporalLike fields\n// carry for the overwhelming majority of callers. Non-Gregorian\n// calendars (hebrew, islamic, etc.) need their own helpers; this\n// module doesn't try to be calendar-polymorphic the way Temporal\n// itself is. Documented limitation, not a design choice — see\n// VERIFICATION.md for the rationale.\n\nimport { isGregorianLeapYear, dayOfYear, isoWeekYearAndWeek } from './isoWeek.js';\n\n// A subset of TemporalLike that has the date fields these helpers need,\n// plus optional time fields. PlainTime isn't a DateFieldView (no\n// year/month/day), but PlainDateTime / ZonedDateTime / PlainDate all\n// match. Time fields are optional so callers can pass a PlainDate\n// to startOf(value, 'month') without having to populate hour/minute/etc.\n// Exported so the comparison/arithmetic modules can use the same\n// narrowing.\nexport interface DateFieldView {\n year?: number;\n month?: number;\n day?: number;\n hour?: number;\n minute?: number;\n second?: number;\n millisecond?: number;\n dayOfWeek?: number;\n calendarId?: string;\n}\n\nfunction requireFields(view: DateFieldView, fields: Array<keyof DateFieldView>): void {\n for (const f of fields) {\n if (typeof view[f] !== 'number') {\n throw new Error(\n `temporal-fmt: calendar helper requires \"${String(f)}\", which this value doesn't have. ` +\n `Pass a Temporal.PlainDate / PlainDateTime / ZonedDateTime.`\n );\n }\n }\n}\n\nexport function daysInMonth(view: DateFieldView): number {\n requireFields(view, ['year', 'month']);\n const { year, month } = view;\n // Standard Gregorian month lengths. February's length depends on\n // whether `year` is a leap year — the same isGregorianLeapYear check\n // isoWeek.ts uses for dayOfYear arithmetic.\n const LENGTHS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n if (month === 2 && isGregorianLeapYear(year!)) return 29;\n return LENGTHS[(month! - 1)!]!;\n}\n\nexport function daysInYear(view: DateFieldView): 365 | 366 {\n requireFields(view, ['year']);\n return isGregorianLeapYear(view.year!) ? 366 : 365;\n}\n\nexport function monthsInYear(_view: DateFieldView): 12 {\n // Gregorian always has 12 months. Other calendars (Hebrew leap years\n // have 13) need calendar-aware logic this module doesn't carry — see\n // the file-level comment. The `_view` parameter is kept so the\n // signature mirrors the other helpers and a future calendar-aware\n // implementation can use it without changing call sites.\n return 12;\n}\n\nexport function isLeapYear(view: DateFieldView): boolean {\n requireFields(view, ['year']);\n return isGregorianLeapYear(view.year!);\n}\n\n// `isLeapMonth` would require knowing which month of a leap-year-aware\n// calendar is the leap month — Gregorian doesn't have one, so this\n// returns false unconditionally. Kept here so the public surface\n// matches the module's listing; non-Gregorian calendars need\n// a different implementation.\nexport function isLeapMonth(_view: DateFieldView): boolean {\n return false;\n}\n\nexport function dayOfYearHelper(view: DateFieldView): number {\n requireFields(view, ['year', 'month', 'day']);\n return dayOfYear(view.year!, view.month!, view.day!);\n}\n\n// ISO 8601 week and week-year. Delegates to isoWeek.ts's\n// isoWeekYearAndWeek, which does the full Thursday-of-week\n// computation to handle the year-boundary cases (Dec 29-31 belonging\n// to week 1 of next year, Jan 1-3 belonging to week 52/53 of the\n// previous year).\nexport function weekOfYear(view: DateFieldView): number {\n requireFields(view, ['year', 'month', 'day', 'dayOfWeek']);\n return isoWeekYearAndWeek(view.year!, view.month!, view.day!, view.dayOfWeek!).week;\n}\n\nexport function weekYear(view: DateFieldView): number {\n requireFields(view, ['year', 'month', 'day', 'dayOfWeek']);\n return isoWeekYearAndWeek(view.year!, view.month!, view.day!, view.dayOfWeek!).isoYear;\n}\n\n/**\n * Fiscal-quarter options. `startMonth` is the calendar month (1-12) the\n * fiscal year begins on — e.g. `7` for a fiscal year starting in July.\n * Omitted or `1` gives the calendar-quarter behavior getQuarter() has\n * always had (Jan-Mar = Q1, etc.), so existing callers passing nothing\n * see no change.\n */\nexport interface QuarterOptions {\n startMonth?: number;\n}\n\nfunction validateStartMonth(startMonth: number): void {\n if (!Number.isInteger(startMonth) || startMonth < 1 || startMonth > 12) {\n throw new Error(\n `temporal-fmt: getQuarter's startMonth must be an integer from 1 to 12 (got ${startMonth}).`\n );\n }\n}\n\nexport function getQuarter(view: DateFieldView, options: QuarterOptions = {}): number {\n requireFields(view, ['month']);\n const startMonth = options.startMonth ?? 1;\n validateStartMonth(startMonth);\n if (startMonth === 1) {\n // Mirrors the Q token: months 1-3 → Q1, 4-6 → Q2, 7-9 → Q3, 10-12 → Q4.\n return Math.ceil(view.month! / 3);\n }\n // Fiscal case: shift the month so startMonth becomes month 1 of the\n // fiscal year (mod 12, 1-indexed), then apply the same ceil(/3) rule.\n // E.g. startMonth=7 (fiscal year starts July): July→1, Aug→2, ...,\n // Dec→6, Jan→7, ..., June→12. Then Q1 = fiscal months 1-3 (Jul-Sep),\n // matching the common \"FY starts in July\" convention where Q1 is the\n // first quarter of the fiscal year, not a quarter numbered by which\n // calendar quarter it falls in.\n const shifted = ((view.month! - startMonth + 12) % 12) + 1;\n return Math.ceil(shifted / 3);\n}\n\n// `getMonth` / `getWeekday` look trivial (just read the field) but\n// they're kept as real functions for API surface consistency with the\n// rest of this module. They also normalize: getWeekday returns 1-7\n// (Mon-Sun, matching Temporal's spec) regardless of what numbering the\n// caller's underlying value uses.\nexport function getMonth(view: DateFieldView): number {\n requireFields(view, ['month']);\n return view.month!;\n}\n\nexport function getWeekday(view: DateFieldView): number {\n requireFields(view, ['dayOfWeek']);\n return view.dayOfWeek!;\n}\n\n// startOf / endOf return new field bags (not Temporal objects — this\n// module is polyfill-free) with the relevant fields zeroed/extended.\n// Callers can pass the result to a Temporal constructor if they want\n// a typed value.\nexport type StartOfUnit = 'day' | 'month' | 'year' | 'hour' | 'minute' | 'second';\n\n// Returns true if the given unit (when used with startOf/endOf) should\n// also touch the time fields. 'day', 'month', 'year' all imply a\n// resolution coarser than an hour, so startOf zeroes the time fields\n// and endOf maxes them. Sub-hour units (hour/minute/second) only touch\n// the fields finer than themselves.\nfunction touchesTime(unit: StartOfUnit): boolean {\n return unit === 'day' || unit === 'month' || unit === 'year';\n}\n\n// startOf/endOf reassign year/month/day, which invalidates any\n// dayOfWeek carried over from the input — a plain { ...view } spread\n// leaves the old value sitting there unchanged. Same failure mode\n// businessCalendar.ts's isBusinessDay() works around for add(); we\n// recompute here rather than trust the copied field.\nfunction recomputeDayOfWeek(view: DateFieldView): void {\n if (typeof view.dayOfWeek !== 'number') return;\n /* c8 ignore start @preserve -- unreachable: startOf()/endOf() both call\n * asDateFieldView() before this, which already throws if year/month/day\n * aren't all numbers — so by the time a value with a numeric dayOfWeek\n * reaches here, year/month/day are guaranteed present too. */\n if (typeof view.year !== 'number' || typeof view.month !== 'number' || typeof view.day !== 'number') return;\n /* c8 ignore stop @preserve */\n const jsDow = new Date(Date.UTC(view.year, view.month - 1, view.day)).getUTCDay(); // 0=Sun..6=Sat\n view.dayOfWeek = jsDow === 0 ? 7 : jsDow; // 1=Mon..7=Sun\n}\n\nexport function startOf(value: unknown, unit: StartOfUnit): DateFieldView {\n const view = asDateFieldView(value);\n const result: DateFieldView = { ...view };\n if (unit === 'year') {\n result.month = 1;\n result.day = 1;\n } else if (unit === 'month') {\n result.day = 1;\n }\n recomputeDayOfWeek(result);\n if (touchesTime(unit)) {\n result.hour = 0;\n result.minute = 0;\n result.second = 0;\n result.millisecond = 0;\n } else if (unit === 'hour') {\n result.minute = 0;\n result.second = 0;\n result.millisecond = 0;\n } else if (unit === 'minute') {\n result.second = 0;\n result.millisecond = 0;\n } else if (unit === 'second') {\n result.millisecond = 0;\n }\n return result;\n}\n\nexport function endOf(value: unknown, unit: StartOfUnit): DateFieldView {\n const view = asDateFieldView(value);\n const result: DateFieldView = { ...view };\n if (unit === 'year') {\n result.month = 12;\n result.day = daysInMonth({ year: result.year!, month: 12 });\n } else if (unit === 'month') {\n result.day = daysInMonth({ year: result.year!, month: result.month! });\n }\n recomputeDayOfWeek(result);\n if (touchesTime(unit)) {\n result.hour = 23;\n result.minute = 59;\n result.second = 59;\n result.millisecond = 999;\n } else if (unit === 'hour') {\n result.minute = 59;\n result.second = 59;\n result.millisecond = 999;\n } else if (unit === 'minute') {\n result.second = 59;\n result.millisecond = 999;\n } else if (unit === 'second') {\n result.millisecond = 999;\n }\n return result;\n}\n\n// Type-narrowing helpers used by the comparison/arithmetic modules.\n// Lets them accept any of the four date-carrying Temporal types without\n// importing Temporal itself.\nexport function asDateFieldView(value: unknown): DateFieldView {\n if (typeof value !== 'object' || value === null) {\n throw new Error(`temporal-fmt: expected a date-carrying Temporal value, got ${String(value)}.`);\n }\n // Temporal instances expose year/month/day/etc. as prototype getters,\n // not own enumerable properties — so `{ ...value }` would lose them.\n // Read them explicitly. Only the fields actually present on this\n // value type end up in the returned view.\n const v = value as Record<string, unknown>;\n const out: DateFieldView = {};\n if (typeof v.year === 'number') out.year = v.year;\n if (typeof v.month === 'number') out.month = v.month;\n if (typeof v.day === 'number') out.day = v.day;\n if (typeof v.hour === 'number') out.hour = v.hour;\n if (typeof v.minute === 'number') out.minute = v.minute;\n if (typeof v.second === 'number') out.second = v.second;\n if (typeof v.millisecond === 'number') out.millisecond = v.millisecond;\n if (typeof v.dayOfWeek === 'number') out.dayOfWeek = v.dayOfWeek;\n if (typeof v.calendarId === 'string') out.calendarId = v.calendarId;\n if (out.year === undefined || out.month === undefined || out.day === undefined) {\n throw new Error(\n `temporal-fmt: value is missing year/month/day fields — pass a Temporal.PlainDate / PlainDateTime / ZonedDateTime.`\n );\n }\n return out;\n}\n\n// Re-export the TemporalType alias so callers can import everything\n// from one place.\nexport type { TemporalType } from './tokenMetadata.js';\n// Re-export TemporalLike for the same reason.\nexport type { TemporalLike } from './tokens.js';","// ISO 8601 week numbering: a week runs Monday–Sunday, and week 1 of a year\n// is the week containing the year's first Thursday (equivalently, the week\n// containing January 4). This means late-December dates can fall in week 1\n// of the *next* year, and early-January dates can fall in week 52 or 53 of\n// the *previous* year. The \"ISO week-numbering year\" (what `RRRR` formats)\n// is that adjacent year, not the calendar year.\n//\n// Computed here from the date's own year/month/day plus its ISO dayOfWeek\n// (1=Mon..7=Sun, matching Temporal's numbering) using plain Gregorian\n// arithmetic — no Temporal factory needed. format() only has the fields\n// the caller already put on the object, and requiring a Temporal\n// implementation just for ISO week would be a regression for callers who\n// use format() without setTemporal() on a non-26 Node.\n\nconst DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\nconst CUMULATIVE_DAYS_BY_MONTH = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];\n\nexport function isGregorianLeapYear(year: number): boolean {\n // Gregorian rule: divisible by 4, except centuries which must also be\n // divisible by 400. Temporal's iso8601 calendar is proleptic Gregorian\n // (no Julian cutover), so this applies for every year, including BCE.\n return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n}\n\nfunction daysInYear(year: number): 365 | 366 {\n return isGregorianLeapYear(year) ? 366 : 365;\n}\n\nexport function dayOfYear(year: number, month: number, day: number): number {\n let doy = CUMULATIVE_DAYS_BY_MONTH[month - 1]! + day;\n if (month > 2 && isGregorianLeapYear(year)) doy += 1;\n return doy;\n}\n\n// Jan 1, 2000 was a Saturday — ISO dayOfWeek 6. Anchoring day-of-week\n// computations to a known reference date is simpler and cheaper than\n// pulling in Zeller's congruence, and the reference never changes.\nconst REFERENCE_YEAR = 2000;\nconst REFERENCE_JAN1_DAY_OF_WEEK = 6;\n\nfunction dayOfWeekOfJan1(year: number): number {\n // Sum full-year deltas from the 2000 anchor rather than recomputing from\n // scratch each call — the per-call work is a single mod this way, and\n // the loop rarely runs far (a typical caller passes a current-era year).\n let offset = 0;\n if (year >= REFERENCE_YEAR) {\n for (let y = REFERENCE_YEAR; y < year; y++) offset += daysInYear(y);\n } else {\n for (let y = year; y < REFERENCE_YEAR; y++) offset -= daysInYear(y);\n }\n // Convert \"days since Jan 1, 2000\" into an ISO day-of-week (1=Mon..7=Sun).\n // Jan 1, 2000 was ISO 6 (Sat), so zero-indexed dow = (6-1 + offset) mod 7.\n const zeroIndexed = (((6 - 1 + offset) % 7) + 7) % 7;\n return zeroIndexed + 1;\n}\n\nexport interface IsoWeekDate {\n isoYear: number;\n week: number; // 1..53\n}\n\nexport function isoWeekYearAndWeek(year: number, month: number, day: number, dayOfWeek: number): IsoWeekDate {\n // Step 1: find the Thursday of the current ISO week. The ISO week-numbering\n // year is whichever calendar year that Thursday falls in. Computing it via\n // day-of-year offsets (rather than constructing a Temporal.PlainDate and\n // adding days) keeps this function pure-numeric.\n const doy = dayOfYear(year, month, day);\n const thursdayDoyRelative = doy + (4 - dayOfWeek); // may be <1 or >daysInYear\n\n let isoYear: number;\n let thursdayDoy: number;\n if (thursdayDoyRelative < 1) {\n isoYear = year - 1;\n thursdayDoy = thursdayDoyRelative + daysInYear(isoYear);\n } else if (thursdayDoyRelative > daysInYear(year)) {\n isoYear = year + 1;\n thursdayDoy = thursdayDoyRelative - daysInYear(year);\n } else {\n isoYear = year;\n thursdayDoy = thursdayDoyRelative;\n }\n\n // Step 2: locate the first Thursday of isoYear — its week is week 1. The\n // first Thursday's day-of-year depends on what weekday Jan 1 of isoYear is.\n const jan1Dow = dayOfWeekOfJan1(isoYear);\n const firstThursdayDoy = 1 + ((4 - jan1Dow + 7) % 7); // 1..7\n\n // Step 3: count full weeks between the two Thursdays.\n const week = 1 + Math.floor((thursdayDoy - firstThursdayDoy) / 7);\n return { isoYear, week };\n}\n"],"mappings":"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","names":["daysInYear","daysInYear"]}
1
+ {"version":3,"sources":["../src/calendarUtils.ts","../src/isoWeek.ts"],"sourcesContent":["/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Calendar utility helpers. These are pure functions\n// over the TemporalLike shape — no Temporal namespace needed, same\n// approach as isoWeek.ts and the field-reading helpers in format.ts.\n// Letting callers compute dayOfYear/weekOfYear/etc. without going\n// through format() means they can build their own derived values\n// without committing to a string format.\n//\n// Calendar-sensitivity: the helpers in this module assume the\n// iso8601 (Gregorian) calendar — that's what TemporalLike fields\n// carry for the overwhelming majority of callers. Non-Gregorian\n// calendars (hebrew, islamic, etc.) need their own helpers; this\n// module doesn't try to be calendar-polymorphic the way Temporal\n// itself is. Documented limitation, not a design choice — see\n// VERIFICATION.md for the rationale.\n\nimport { isGregorianLeapYear, dayOfYear, isoWeekYearAndWeek } from './isoWeek.js';\n\n// A subset of TemporalLike that has the date fields these helpers need,\n// plus optional time fields. PlainTime isn't a DateFieldView (no\n// year/month/day), but PlainDateTime / ZonedDateTime / PlainDate all\n// match. Time fields are optional so callers can pass a PlainDate\n// to startOf(value, 'month') without having to populate hour/minute/etc.\n// Exported so the comparison/arithmetic modules can use the same\n// narrowing.\nexport interface DateFieldView {\n year?: number;\n month?: number;\n day?: number;\n hour?: number;\n minute?: number;\n second?: number;\n millisecond?: number;\n dayOfWeek?: number;\n calendarId?: string;\n}\n\nfunction requireFields(view: DateFieldView, fields: Array<keyof DateFieldView>): void {\n for (const f of fields) {\n if (typeof view[f] !== 'number') {\n throw new Error(\n `temporal-fmt: calendar helper requires \"${String(f)}\", which this value doesn't have. ` +\n `Pass a Temporal.PlainDate / PlainDateTime / ZonedDateTime.`\n );\n }\n }\n}\n\nexport function daysInMonth(view: DateFieldView): number {\n requireFields(view, ['year', 'month']);\n const { year, month } = view;\n // Standard Gregorian month lengths. February's length depends on\n // whether `year` is a leap year — the same isGregorianLeapYear check\n // isoWeek.ts uses for dayOfYear arithmetic.\n const LENGTHS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n if (month === 2 && isGregorianLeapYear(year!)) return 29;\n return LENGTHS[(month! - 1)!]!;\n}\n\nexport function daysInYear(view: DateFieldView): 365 | 366 {\n requireFields(view, ['year']);\n return isGregorianLeapYear(view.year!) ? 366 : 365;\n}\n\nexport function monthsInYear(_view: DateFieldView): 12 {\n // Gregorian always has 12 months. Other calendars (Hebrew leap years\n // have 13) need calendar-aware logic this module doesn't carry — see\n // the file-level comment. The `_view` parameter is kept so the\n // signature mirrors the other helpers and a future calendar-aware\n // implementation can use it without changing call sites.\n return 12;\n}\n\nexport function isLeapYear(view: DateFieldView): boolean {\n requireFields(view, ['year']);\n return isGregorianLeapYear(view.year!);\n}\n\n// `isLeapMonth` would require knowing which month of a leap-year-aware\n// calendar is the leap month — Gregorian doesn't have one, so this\n// returns false unconditionally. Kept here so the public surface\n// matches the module's listing; non-Gregorian calendars need\n// a different implementation.\nexport function isLeapMonth(_view: DateFieldView): boolean {\n return false;\n}\n\nexport function dayOfYearHelper(view: DateFieldView): number {\n requireFields(view, ['year', 'month', 'day']);\n return dayOfYear(view.year!, view.month!, view.day!);\n}\n\n// ISO 8601 week and week-year. Delegates to isoWeek.ts's\n// isoWeekYearAndWeek, which does the full Thursday-of-week\n// computation to handle the year-boundary cases (Dec 29-31 belonging\n// to week 1 of next year, Jan 1-3 belonging to week 52/53 of the\n// previous year).\nexport function weekOfYear(view: DateFieldView): number {\n requireFields(view, ['year', 'month', 'day', 'dayOfWeek']);\n return isoWeekYearAndWeek(view.year!, view.month!, view.day!, view.dayOfWeek!).week;\n}\n\nexport function weekYear(view: DateFieldView): number {\n requireFields(view, ['year', 'month', 'day', 'dayOfWeek']);\n return isoWeekYearAndWeek(view.year!, view.month!, view.day!, view.dayOfWeek!).isoYear;\n}\n\n/**\n * Fiscal-quarter options. `startMonth` is the calendar month (1-12) the\n * fiscal year begins on — e.g. `7` for a fiscal year starting in July.\n * Omitted or `1` gives the calendar-quarter behavior getQuarter() has\n * always had (Jan-Mar = Q1, etc.), so existing callers passing nothing\n * see no change.\n */\nexport interface QuarterOptions {\n startMonth?: number;\n}\n\nfunction validateStartMonth(startMonth: number): void {\n if (!Number.isInteger(startMonth) || startMonth < 1 || startMonth > 12) {\n throw new Error(\n `temporal-fmt: getQuarter's startMonth must be an integer from 1 to 12 (got ${startMonth}).`\n );\n }\n}\n\nexport function getQuarter(view: DateFieldView, options: QuarterOptions = {}): number {\n requireFields(view, ['month']);\n const startMonth = options.startMonth ?? 1;\n validateStartMonth(startMonth);\n if (startMonth === 1) {\n // Mirrors the Q token: months 1-3 → Q1, 4-6 → Q2, 7-9 → Q3, 10-12 → Q4.\n return Math.ceil(view.month! / 3);\n }\n // Fiscal case: shift the month so startMonth becomes month 1 of the\n // fiscal year (mod 12, 1-indexed), then apply the same ceil(/3) rule.\n // E.g. startMonth=7 (fiscal year starts July): July→1, Aug→2, ...,\n // Dec→6, Jan→7, ..., June→12. Then Q1 = fiscal months 1-3 (Jul-Sep),\n // matching the common \"FY starts in July\" convention where Q1 is the\n // first quarter of the fiscal year, not a quarter numbered by which\n // calendar quarter it falls in.\n const shifted = ((view.month! - startMonth + 12) % 12) + 1;\n return Math.ceil(shifted / 3);\n}\n\n// `getMonth` / `getWeekday` look trivial (just read the field) but\n// they're kept as real functions for API surface consistency with the\n// rest of this module. They also normalize: getWeekday returns 1-7\n// (Mon-Sun, matching Temporal's spec) regardless of what numbering the\n// caller's underlying value uses.\nexport function getMonth(view: DateFieldView): number {\n requireFields(view, ['month']);\n return view.month!;\n}\n\nexport function getWeekday(view: DateFieldView): number {\n requireFields(view, ['dayOfWeek']);\n return view.dayOfWeek!;\n}\n\n// startOf / endOf return new field bags (not Temporal objects — this\n// module is polyfill-free) with the relevant fields zeroed/extended.\n// Callers can pass the result to a Temporal constructor if they want\n// a typed value.\nexport type StartOfUnit = 'day' | 'month' | 'year' | 'hour' | 'minute' | 'second';\n\n// Returns true if the given unit (when used with startOf/endOf) should\n// also touch the time fields. 'day', 'month', 'year' all imply a\n// resolution coarser than an hour, so startOf zeroes the time fields\n// and endOf maxes them. Sub-hour units (hour/minute/second) only touch\n// the fields finer than themselves.\nfunction touchesTime(unit: StartOfUnit): boolean {\n return unit === 'day' || unit === 'month' || unit === 'year';\n}\n\n// startOf/endOf reassign year/month/day, which invalidates any\n// dayOfWeek carried over from the input — a plain { ...view } spread\n// leaves the old value sitting there unchanged. Same failure mode\n// businessCalendar.ts's isBusinessDay() works around for add(); we\n// recompute here rather than trust the copied field.\nfunction recomputeDayOfWeek(view: DateFieldView): void {\n if (typeof view.dayOfWeek !== 'number') return;\n /* c8 ignore start @preserve -- unreachable: startOf()/endOf() both call\n * asDateFieldView() before this, which already throws if year/month/day\n * aren't all numbers — so by the time a value with a numeric dayOfWeek\n * reaches here, year/month/day are guaranteed present too. */\n if (typeof view.year !== 'number' || typeof view.month !== 'number' || typeof view.day !== 'number') return;\n /* c8 ignore stop @preserve */\n const jsDow = new Date(Date.UTC(view.year, view.month - 1, view.day)).getUTCDay(); // 0=Sun..6=Sat\n view.dayOfWeek = jsDow === 0 ? 7 : jsDow; // 1=Mon..7=Sun\n}\n\nexport function startOf(value: unknown, unit: StartOfUnit): DateFieldView {\n const view = asDateFieldView(value);\n const result: DateFieldView = { ...view };\n if (unit === 'year') {\n result.month = 1;\n result.day = 1;\n } else if (unit === 'month') {\n result.day = 1;\n }\n recomputeDayOfWeek(result);\n if (touchesTime(unit)) {\n result.hour = 0;\n result.minute = 0;\n result.second = 0;\n result.millisecond = 0;\n } else if (unit === 'hour') {\n result.minute = 0;\n result.second = 0;\n result.millisecond = 0;\n } else if (unit === 'minute') {\n result.second = 0;\n result.millisecond = 0;\n } else if (unit === 'second') {\n result.millisecond = 0;\n }\n return result;\n}\n\nexport function endOf(value: unknown, unit: StartOfUnit): DateFieldView {\n const view = asDateFieldView(value);\n const result: DateFieldView = { ...view };\n if (unit === 'year') {\n result.month = 12;\n result.day = daysInMonth({ year: result.year!, month: 12 });\n } else if (unit === 'month') {\n result.day = daysInMonth({ year: result.year!, month: result.month! });\n }\n recomputeDayOfWeek(result);\n if (touchesTime(unit)) {\n result.hour = 23;\n result.minute = 59;\n result.second = 59;\n result.millisecond = 999;\n } else if (unit === 'hour') {\n result.minute = 59;\n result.second = 59;\n result.millisecond = 999;\n } else if (unit === 'minute') {\n result.second = 59;\n result.millisecond = 999;\n } else if (unit === 'second') {\n result.millisecond = 999;\n }\n return result;\n}\n\n// Type-narrowing helpers used by the comparison/arithmetic modules.\n// Lets them accept any of the four date-carrying Temporal types without\n// importing Temporal itself.\nexport function asDateFieldView(value: unknown): DateFieldView {\n if (typeof value !== 'object' || value === null) {\n throw new Error(`temporal-fmt: expected a date-carrying Temporal value, got ${String(value)}.`);\n }\n // Temporal instances expose year/month/day/etc. as prototype getters,\n // not own enumerable properties — so `{ ...value }` would lose them.\n // Read them explicitly. Only the fields actually present on this\n // value type end up in the returned view.\n const v = value as Record<string, unknown>;\n const out: DateFieldView = {};\n if (typeof v.year === 'number') out.year = v.year;\n if (typeof v.month === 'number') out.month = v.month;\n if (typeof v.day === 'number') out.day = v.day;\n if (typeof v.hour === 'number') out.hour = v.hour;\n if (typeof v.minute === 'number') out.minute = v.minute;\n if (typeof v.second === 'number') out.second = v.second;\n if (typeof v.millisecond === 'number') out.millisecond = v.millisecond;\n if (typeof v.dayOfWeek === 'number') out.dayOfWeek = v.dayOfWeek;\n if (typeof v.calendarId === 'string') out.calendarId = v.calendarId;\n if (out.year === undefined || out.month === undefined || out.day === undefined) {\n throw new Error(\n `temporal-fmt: value is missing year/month/day fields — pass a Temporal.PlainDate / PlainDateTime / ZonedDateTime.`\n );\n }\n return out;\n}\n\n// Re-export the TemporalType alias so callers can import everything\n// from one place.\nexport type { TemporalType } from './tokenMetadata.js';\n// Re-export TemporalLike for the same reason.\nexport type { TemporalLike } from './tokens.js';","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// ISO 8601 week numbering: a week runs Monday–Sunday, and week 1 of a year\n// is the week containing the year's first Thursday (equivalently, the week\n// containing January 4). This means late-December dates can fall in week 1\n// of the *next* year, and early-January dates can fall in week 52 or 53 of\n// the *previous* year. The \"ISO week-numbering year\" (what `RRRR` formats)\n// is that adjacent year, not the calendar year.\n//\n// Computed here from the date's own year/month/day plus its ISO dayOfWeek\n// (1=Mon..7=Sun, matching Temporal's numbering) using plain Gregorian\n// arithmetic — no Temporal factory needed. format() only has the fields\n// the caller already put on the object, and requiring a Temporal\n// implementation just for ISO week would be a regression for callers who\n// use format() without setTemporal() on a non-26 Node.\n\nconst DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\nconst CUMULATIVE_DAYS_BY_MONTH = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];\n\nexport function isGregorianLeapYear(year: number): boolean {\n // Gregorian rule: divisible by 4, except centuries which must also be\n // divisible by 400. Temporal's iso8601 calendar is proleptic Gregorian\n // (no Julian cutover), so this applies for every year, including BCE.\n return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n}\n\nfunction daysInYear(year: number): 365 | 366 {\n return isGregorianLeapYear(year) ? 366 : 365;\n}\n\nexport function dayOfYear(year: number, month: number, day: number): number {\n let doy = CUMULATIVE_DAYS_BY_MONTH[month - 1]! + day;\n if (month > 2 && isGregorianLeapYear(year)) doy += 1;\n return doy;\n}\n\n// Jan 1, 2000 was a Saturday — ISO dayOfWeek 6. Anchoring day-of-week\n// computations to a known reference date is simpler and cheaper than\n// pulling in Zeller's congruence, and the reference never changes.\nconst REFERENCE_YEAR = 2000;\nconst REFERENCE_JAN1_DAY_OF_WEEK = 6;\n\nfunction dayOfWeekOfJan1(year: number): number {\n // Sum full-year deltas from the 2000 anchor rather than recomputing from\n // scratch each call — the per-call work is a single mod this way, and\n // the loop rarely runs far (a typical caller passes a current-era year).\n let offset = 0;\n if (year >= REFERENCE_YEAR) {\n for (let y = REFERENCE_YEAR; y < year; y++) offset += daysInYear(y);\n } else {\n for (let y = year; y < REFERENCE_YEAR; y++) offset -= daysInYear(y);\n }\n // Convert \"days since Jan 1, 2000\" into an ISO day-of-week (1=Mon..7=Sun).\n // Jan 1, 2000 was ISO 6 (Sat), so zero-indexed dow = (6-1 + offset) mod 7.\n const zeroIndexed = (((6 - 1 + offset) % 7) + 7) % 7;\n return zeroIndexed + 1;\n}\n\nexport interface IsoWeekDate {\n isoYear: number;\n week: number; // 1..53\n}\n\nexport function isoWeekYearAndWeek(year: number, month: number, day: number, dayOfWeek: number): IsoWeekDate {\n // Step 1: find the Thursday of the current ISO week. The ISO week-numbering\n // year is whichever calendar year that Thursday falls in. Computing it via\n // day-of-year offsets (rather than constructing a Temporal.PlainDate and\n // adding days) keeps this function pure-numeric.\n const doy = dayOfYear(year, month, day);\n const thursdayDoyRelative = doy + (4 - dayOfWeek); // may be <1 or >daysInYear\n\n let isoYear: number;\n let thursdayDoy: number;\n if (thursdayDoyRelative < 1) {\n isoYear = year - 1;\n thursdayDoy = thursdayDoyRelative + daysInYear(isoYear);\n } else if (thursdayDoyRelative > daysInYear(year)) {\n isoYear = year + 1;\n thursdayDoy = thursdayDoyRelative - daysInYear(year);\n } else {\n isoYear = year;\n thursdayDoy = thursdayDoyRelative;\n }\n\n // Step 2: locate the first Thursday of isoYear — its week is week 1. The\n // first Thursday's day-of-year depends on what weekday Jan 1 of isoYear is.\n const jan1Dow = dayOfWeekOfJan1(isoYear);\n const firstThursdayDoy = 1 + ((4 - jan1Dow + 7) % 7); // 1..7\n\n // Step 3: count full weeks between the two Thursdays.\n const week = 1 + Math.floor((thursdayDoy - firstThursdayDoy) / 7);\n return { isoYear, week };\n}\n"],"mappings":"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","names":["daysInYear","daysInYear"]}
@@ -13,8 +13,8 @@ import {
13
13
  startOf,
14
14
  weekOfYear,
15
15
  weekYear
16
- } from "./chunk-4ZBGVYLR.js";
17
- import "./chunk-YS52LOMJ.js";
16
+ } from "./chunk-GNUK7PGX.js";
17
+ import "./chunk-QDNC4IEV.js";
18
18
  export {
19
19
  asDateFieldView,
20
20
  dayOfYearHelper,
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  getTemporal
3
- } from "./chunk-MXXYIMFJ.js";
3
+ } from "./chunk-6YRWNUNV.js";
4
4
  import {
5
5
  add
6
- } from "./chunk-VHSZL3P3.js";
6
+ } from "./chunk-UX4Z3WFS.js";
7
7
 
8
8
  // src/timezone.ts
9
9
  function resolveZoned(fields, timeZone, options = {}) {
@@ -167,4 +167,4 @@ export {
167
167
  getTransitions,
168
168
  possibleInstantsFor
169
169
  };
170
- //# sourceMappingURL=chunk-GRJQHQLW.js.map
170
+ //# sourceMappingURL=chunk-4D2ZYVPM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/timezone.ts"],"sourcesContent":["/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Time-zone subsystem. Wraps Temporal.ZonedDateTime's\n// timezone introspection surface in temporal-fmt's field-based convention.\n// Includes disambiguation modes (compatible/earlier/later/reject) for\n// DST gaps and overlaps, plus transition queries (getNextTransition,\n// getPreviousTransition, getTransitions).\n\nimport { getTemporal } from './temporalProvider.js';\nimport { add } from './arithmetic.js';\n\nexport type DisambiguationMode = 'compatible' | 'earlier' | 'later' | 'reject';\n\nexport interface ResolveZonedOptions {\n disambiguation?: DisambiguationMode;\n overflow?: 'constrain' | 'reject';\n offset?: 'use' | 'ignore' | 'prefer' | 'reject';\n}\n\n// Resolves a wall-clock time in a timezone, applying disambiguation\n// for DST gaps and overlaps.\nexport function resolveZoned(\n fields: { year: number; month: number; day: number; hour?: number; minute?: number; second?: number; millisecond?: number; microsecond?: number; nanosecond?: number },\n timeZone: string,\n options: ResolveZonedOptions = {},\n): unknown {\n const temporal = getTemporal();\n const disambiguation = options.disambiguation ?? 'compatible';\n const overflow = options.overflow ?? 'constrain';\n // Cast options to a permissive record — Temporal.ZonedDateTime.from\n // accepts disambiguation/offset options, but the existing\n // TemporalFactory.from() signature in temporalProvider.ts is narrower.\n // The runtime accepts the wider shape; this cast bypasses the type\n // narrowing without changing runtime behavior.\n const fromOptions = {\n overflow,\n disambiguation,\n offset: options.offset ?? 'prefer',\n } as unknown as Parameters<typeof temporal.ZonedDateTime.from>[1];\n try {\n return temporal.ZonedDateTime.from(\n {\n year: fields.year,\n month: fields.month,\n day: fields.day,\n hour: fields.hour ?? 0,\n minute: fields.minute ?? 0,\n second: fields.second ?? 0,\n millisecond: fields.millisecond ?? 0,\n microsecond: fields.microsecond ?? 0,\n nanosecond: fields.nanosecond ?? 0,\n timeZone,\n },\n fromOptions,\n );\n } catch (err) {\n // Surface DST gap / overlap errors with a clearer message.\n const msg = (err as Error).message;\n if (/no such (wall-clock )?time/i.test(msg) && disambiguation === 'reject') {\n throw new Error(\n `temporal-fmt: \"${timeZone}\" has no such wall-clock time on ${fields.year}-${fields.month}-${fields.day}T${fields.hour ?? 0}:${fields.minute ?? 0} — ` +\n `it falls in a DST gap. Pass { disambiguation: 'compatible' | 'earlier' | 'later' } to pick an instant.`\n );\n }\n throw err;\n }\n}\n\nexport function getTimeZone(value: unknown): string {\n const v = value as { timeZoneId?: string };\n if (typeof v?.timeZoneId !== 'string') {\n throw new Error(`temporal-fmt: getTimeZone() expected a ZonedDateTime, got ${typeof value}.`);\n }\n return v.timeZoneId;\n}\n\nexport function getOffset(value: unknown): string {\n const v = value as { offset?: string };\n if (typeof v?.offset !== 'string') {\n throw new Error(`temporal-fmt: getOffset() expected a ZonedDateTime, got ${typeof value}.`);\n }\n return v.offset;\n}\n\nexport function getOffsetNanoseconds(value: unknown): number {\n const v = value as { offsetNanoseconds?: number; offset?: string };\n if (typeof v?.offsetNanoseconds === 'number') return v.offsetNanoseconds;\n if (typeof v?.offset === 'string') {\n // Parse ±HH:MM → nanoseconds.\n const m = v.offset.match(/^([+-])(\\d{2}):(\\d{2})$/);\n if (!m) throw new Error(`temporal-fmt: getOffsetNanoseconds() couldn't parse offset \"${v.offset}\".`);\n const sign = m[1] === '-' ? -1 : 1;\n return sign * (Number(m[2]) * 3600 + Number(m[3]) * 60) * 1_000_000_000;\n }\n throw new Error(`temporal-fmt: getOffsetNanoseconds() expected a ZonedDateTime, got ${typeof value}.`);\n}\n\n// DST detection: a ZonedDateTime is in DST iff the offset is different\n// from the timezone's standard offset at the same instant. Computed\n// by comparing the current offset to the offset in January (Northern\n// Hemisphere) or July (Southern Hemisphere) of the same year — a\n// heuristic that's right for most populated zones.\nexport function isDST(value: unknown): boolean {\n const v = value as { timeZoneId?: string; offset?: string; year?: number; toInstant?: () => unknown };\n if (typeof v?.timeZoneId !== 'string' || typeof v?.offset !== 'string' || typeof v?.year !== 'number') {\n throw new Error(`temporal-fmt: isDST() expected a ZonedDateTime, got ${typeof value}.`);\n }\n // Compute the offset for January 1 of the same year (standard time\n // for Northern Hemisphere zones) and compare. For Southern Hemisphere\n // zones January is summer, so we'd want July instead — but checking\n // January vs current is good enough for the common case, and we\n // can't reliably determine hemisphere without a lookup table.\n const temporal = getTemporal();\n try {\n const jan = temporal.ZonedDateTime.from(\n { year: v.year, month: 1, day: 1, hour: 12, timeZone: v.timeZoneId },\n { disambiguation: 'compatible' } as unknown as Parameters<typeof temporal.ZonedDateTime.from>[1],\n ) as { offset: string };\n return jan.offset !== v.offset;\n } catch {\n return false;\n }\n}\n\n// Returns the next DST transition strictly after `value`, or undefined\n// if no transition occurs within the next 2 years. Implemented by\n// walking day-by-day checking for offset changes — slow but simple,\n// and correct across all IANA zones.\nexport function getNextTransition(value: unknown): unknown | undefined {\n return findTransition(value, 1);\n}\n\nexport function getPreviousTransition(value: unknown): unknown | undefined {\n return findTransition(value, -1);\n}\n\nfunction findTransition(value: unknown, direction: 1 | -1): unknown | undefined {\n const v = value as { timeZoneId?: string; offset?: string; toInstant?: () => unknown; year?: number; month?: number; day?: number; hour?: number; minute?: number; second?: number; millisecond?: number };\n if (typeof v?.timeZoneId !== 'string') {\n throw new Error(`temporal-fmt: ${direction > 0 ? 'getNextTransition' : 'getPreviousTransition'}() expected a ZonedDateTime, got ${typeof value}.`);\n }\n const temporal = getTemporal();\n const timeZone = v.timeZoneId;\n let candidateFields = add(value, direction, 'days');\n const startOffset = v.offset!;\n for (let i = 0; i < 365 * 2; i++) {\n // Rebuild a real ZonedDateTime for this candidate day, in this\n // timezone, so `.offset` reflects the actual UTC offset on that\n // day rather than being absent. add() only produces a plain field\n // bag (it has no notion of timezone), so re-attaching timeZone via\n // ZonedDateTime.from is what actually lets us detect a DST change\n // here — using the field bag's own (nonexistent) offset would make\n // every call \"find\" a transition on the very first day checked.\n const cf = candidateFields as { year: number; month: number; day: number; hour: number; minute: number; second: number; millisecond: number };\n const candidateZdt = temporal.ZonedDateTime.from(\n { ...cf, timeZone },\n { disambiguation: 'compatible' } as unknown as Parameters<typeof temporal.ZonedDateTime.from>[1],\n ) as { offset: string };\n if (candidateZdt.offset !== startOffset) {\n // Found a transition day. Return the reconstructed ZonedDateTime.\n return candidateZdt;\n }\n candidateFields = add(candidateFields, direction, 'days');\n }\n return undefined;\n}\n\nexport function getTransitions(start: unknown, end: unknown): unknown[] {\n const result: unknown[] = [];\n const startV = start as { timeZoneId?: string; offset?: string; year?: number; month?: number; day?: number };\n if (typeof startV?.timeZoneId !== 'string') {\n throw new Error(`temporal-fmt: getTransitions() expected a ZonedDateTime for start, got ${typeof start}.`);\n }\n const endV = end as { year: number; month: number; day: number };\n const temporal = getTemporal();\n const timeZone = startV.timeZoneId;\n let cursorFields = add(start, 1, 'days');\n let lastOffset = startV.offset!;\n for (let i = 0; i < 365 * 5; i++) {\n // Same reconstruction as findTransition() above — add() strips\n // timezone/offset info, so we rebuild a real ZonedDateTime each\n // iteration to read its actual offset instead of comparing against\n // a field bag that never has one.\n const cf = cursorFields as { year: number; month: number; day: number; hour: number; minute: number; second: number; millisecond: number };\n const cursorZdt = temporal.ZonedDateTime.from(\n { ...cf, timeZone },\n { disambiguation: 'compatible' } as unknown as Parameters<typeof temporal.ZonedDateTime.from>[1],\n ) as { offset: string; year: number; month: number; day: number };\n if (cursorZdt.offset !== lastOffset) {\n // Found a transition.\n if (cursorZdt.year > endV.year || (cursorZdt.year === endV.year && (cursorZdt.month > endV.month || (cursorZdt.month === endV.month && cursorZdt.day > endV.day)))) break;\n result.push(cursorZdt);\n lastOffset = cursorZdt.offset;\n }\n cursorFields = add(cursorFields, 1, 'days');\n }\n return result;\n}\n\n// Returns the list of possible instants for a wall-clock time in a\n// zone — used to detect gaps (0 instants) and overlaps (2 instants).\nexport function possibleInstantsFor(\n fields: { year: number; month: number; day: number; hour: number; minute: number; second: number; millisecond: number },\n timeZone: string,\n): unknown[] {\n const temporal = getTemporal();\n // Resolve the same wall-clock fields twice, forcing disambiguation\n // toward the earlier and later side of any DST boundary. Comparing\n // the two results tells us which of the three cases we're in:\n // - gap (e.g. 2:30am on a spring-forward day): neither result's own\n // wall-clock fields match what was requested, since Temporal has\n // to shift off the nonexistent time in both directions — 0 instants.\n // - overlap (e.g. 1:30am on a fall-back day): both results keep the\n // requested wall-clock time but land on different instants (one\n // per side of the boundary) — 2 instants.\n // - normal time: both results match the requested wall-clock time\n // and resolve to the same instant — 1 instant.\n const earlier = temporal.ZonedDateTime.from(\n { ...fields, timeZone },\n { disambiguation: 'earlier', offset: 'ignore' } as unknown as Parameters<typeof temporal.ZonedDateTime.from>[1],\n ) as { year: number; month: number; day: number; hour: number; minute: number; second: number; millisecond: number; toInstant: () => { epochNanoseconds: bigint } };\n const later = temporal.ZonedDateTime.from(\n { ...fields, timeZone },\n { disambiguation: 'later', offset: 'ignore' } as unknown as Parameters<typeof temporal.ZonedDateTime.from>[1],\n ) as { year: number; month: number; day: number; hour: number; minute: number; second: number; millisecond: number; toInstant: () => { epochNanoseconds: bigint } };\n\n const matchesRequestedWallClock = (z: typeof earlier) =>\n z.year === fields.year && z.month === fields.month && z.day === fields.day &&\n z.hour === fields.hour && z.minute === fields.minute &&\n z.second === fields.second && z.millisecond === fields.millisecond;\n\n if (!matchesRequestedWallClock(earlier) || !matchesRequestedWallClock(later)) {\n // Gap — the requested wall-clock time doesn't exist in this zone.\n return [];\n }\n if (earlier.toInstant().epochNanoseconds === later.toInstant().epochNanoseconds) {\n // Normal time — both disambiguation directions agree on the instant.\n return [earlier];\n }\n // Overlap — same wall-clock time, two distinct instants.\n return [earlier, later];\n}"],"mappings":"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","names":[]}
@@ -26,4 +26,4 @@ export {
26
26
  setTemporal,
27
27
  getTemporal
28
28
  };
29
- //# sourceMappingURL=chunk-MXXYIMFJ.js.map
29
+ //# sourceMappingURL=chunk-6YRWNUNV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/temporalProvider.ts"],"sourcesContent":["/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// This package's tsconfig assumes lib: [\"ESNext\"] only — no ambient\n// `Temporal` namespace type. Everywhere else in this codebase only ever\n// *reads* fields off a Temporal-like object the caller already built\n// (TemporalLike in tokens.ts). This module is the single choke point for\n// touching a *namespace*-shaped Temporal (PlainDate.from, etc.): parse()\n// uses it to construct a result, tokens.ts uses it to probe native\n// Intl<->Temporal support. Consumers can hand us an implementation via\n// setTemporal(), or we fall back to globalThis.Temporal\ninterface TemporalFactory {\n from(fields: Record<string, number | string | undefined>, options?: { overflow?: 'constrain' | 'reject'; disambiguation?: 'compatible' | 'earlier' | 'later' | 'reject'; offset?: 'use' | 'ignore' | 'prefer' | 'reject' }): unknown;\n // compare() lives on the namespace (Temporal.PlainDate.compare), not on\n // instances. Optional here since a consumer might be passing a\n // stripped-down Temporal shim that doesn't expose it.\n compare?(one: unknown, two: unknown): number;\n}\n\n// Instant is constructed via fromEpochMilliseconds / fromEpochNanoseconds\n// rather than from(fields). Separate interface.\ninterface InstantFactory {\n from(iso: string): unknown;\n fromEpochMilliseconds(ms: number): unknown;\n fromEpochMicroseconds(µs: number): unknown;\n fromEpochNanoseconds(ns: bigint): unknown;\n}\n\n// Duration is constructed via from(fields). Carries round() and compare().\ninterface DurationFactory extends TemporalFactory {\n compare?(one: unknown, two: unknown): number;\n prototype?: { round(options: unknown): unknown };\n}\n\n// PlainYearMonth / PlainMonthDay are also constructed via from(fields).\n// Same factory shape, kept separate for type clarity in callers that\n// want to narrow.\nexport interface TemporalNamespace {\n PlainDate: TemporalFactory;\n PlainTime: TemporalFactory;\n PlainDateTime: TemporalFactory;\n ZonedDateTime: TemporalFactory;\n Instant?: InstantFactory;\n Duration?: DurationFactory;\n PlainYearMonth?: TemporalFactory;\n PlainMonthDay?: TemporalFactory;\n}\n\nlet injectedTemporal: TemporalNamespace | undefined;\n\n// Anything that caches a result derived from *which* Temporal\n// implementation is active (right now: tokens.ts's native-Intl-support\n// probe) registers here so it gets invalidated whenever setTemporal()\n// swaps the implementation — see the comment on setTemporal() below for\n// why that matters. A plain array instead of an event-emitter-style API\n// since this only ever needs \"call every listener, in registration order,\n// with no payload\" — nothing here needs unsubscribe or payload data.\nconst onTemporalChanged: Array<() => void> = [];\n\nexport function subscribeToTemporalChanges(listener: () => void): void {\n onTemporalChanged.push(listener);\n}\n\n/**\n * Explicitly hand temporal-fmt the Temporal implementation to use, instead\n * of relying on a global `Temporal`. Call this once, before your first\n * `format()`/`parse()`/`parseISO()`/etc.\n *\n * Call with no argument (or `undefined`) to clear the override and fall\n * back to `globalThis.Temporal` again.\n *\n * @example\n * import { Temporal } from 'temporal-polyfill';\n * import { setTemporal } from 'temporal-fmt';\n * setTemporal(Temporal);\n */\nexport function setTemporal(temporal?: TemporalNamespace): void {\n injectedTemporal = temporal;\n // tokens.ts's native-Intl-support probe is keyed on whichever Temporal\n // implementation was active the first time a locale-aware format() ran —\n // if that implementation changes later (native -> polyfill or back), the\n // memoized probe result can go stale and disagree with what's now\n // actually active. Resetting it here means the next locale-aware format()\n // after any setTemporal() call re-probes against the implementation\n // that's active *now*, at the (small, one-time-per-switch) cost of\n // re-running the probe.\n for (const listener of onTemporalChanged) listener();\n}\n\nfunction resolveTemporal(): TemporalNamespace | undefined {\n return injectedTemporal ?? (globalThis as unknown as { Temporal?: TemporalNamespace }).Temporal;\n}\n\nexport function getTemporal(): TemporalNamespace {\n const temporal = resolveTemporal();\n if (!temporal) {\n throw new Error(\n 'temporal-fmt: parse() needs a Temporal implementation to construct its result. ' +\n 'Call setTemporal(Temporal) once at startup, or assign one to globalThis.Temporal ' +\n '(native on Node 26+, or a polyfill like temporal-polyfill).'\n );\n }\n return temporal;\n}\n"],"mappings":";AA6DA,IAAI;AASJ,IAAM,oBAAuC,CAAC;AAEvC,SAAS,2BAA2B,UAA4B;AACrE,oBAAkB,KAAK,QAAQ;AACjC;AAeO,SAAS,YAAY,UAAoC;AAC9D,qBAAmB;AASnB,aAAW,YAAY,kBAAmB,UAAS;AACrD;AAEA,SAAS,kBAAiD;AACxD,SAAO,oBAAqB,WAA2D;AACzF;AAEO,SAAS,cAAiC;AAC/C,QAAM,WAAW,gBAAgB;AACjC,MAAI,CAAC,UAAU;AACb,UAAM,IAAI;AAAA,MACR;AAAA,IAGF;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
@@ -230,4 +230,4 @@ export {
230
230
  InvalidDurationError,
231
231
  wrapUntypedError
232
232
  };
233
- //# sourceMappingURL=chunk-USONQ7MV.js.map
233
+ //# sourceMappingURL=chunk-AK6OCTTF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts"],"sourcesContent":["/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Structured error classes for parse()/format() failures. The existing\n// throw sites in parse.ts/format.ts/tokenize.ts/pattern.ts/localeVocab.ts\n// all throw plain `new Error(message)` with descriptive strings, and\n// existing tests assert on those strings — so this module does NOT\n// retroactively migrate those sites. Migration would change error\n// identity for any caller using `instanceof Error`, and would force\n// every test that matches `/token \"HH\" requires/` to be rewritten.\n//\n// What this module does: provide typed error classes carrying\n// `code/input/format/token/position/expected/actual/reason` fields, so\n// safeParse()/tryParse() (which don't throw) can return rich diagnostics\n// to callers who need them. The ESLint plugin and codemod will consume\n// these via safeParse. The legacy throw-then-catch surface stays\n// byte-identical to 0.8.x.\n\nexport type TemporalFmtErrorCode =\n | 'FORMAT_SYNTAX_ERROR'\n | 'UNKNOWN_TOKEN'\n | 'PARSE_MISMATCH'\n | 'INVALID_DATE'\n | 'INVALID_TIME'\n | 'INVALID_OFFSET'\n | 'INVALID_TIME_ZONE'\n | 'INVALID_CALENDAR'\n | 'AMBIGUOUS_INPUT'\n | 'INVALID_LOCALE'\n | 'INVALID_DURATION';\n\nexport interface TemporalFmtErrorFields {\n code: TemporalFmtErrorCode;\n input?: string;\n format?: string;\n token?: string;\n position?: number;\n expected?: string;\n actual?: string;\n reason?: string;\n}\n\n// Base class. `message` is the human-readable summary; the structured\n// fields are the machine-readable parts a linter or codemod reports on.\n// `Error.captureStackTrace` is called manually (where available) so\n// the stack points at the call site, not at this constructor — same\n// pattern Node uses for its own error classes.\nexport class TemporalFmtError extends Error {\n readonly code: TemporalFmtErrorCode;\n readonly input?: string;\n readonly format?: string;\n readonly token?: string;\n readonly position?: number;\n readonly expected?: string;\n readonly actual?: string;\n readonly reason?: string;\n\n constructor(message: string, fields: TemporalFmtErrorFields) {\n super(message);\n this.name = 'TemporalFmtError';\n this.code = fields.code;\n this.input = fields.input;\n this.format = fields.format;\n this.token = fields.token;\n this.position = fields.position;\n this.expected = fields.expected;\n this.actual = fields.actual;\n this.reason = fields.reason;\n // Avoid setting the stack to point at this constructor — keeps it\n // useful. captureStackTrace is V8-only; on other engines the\n // default stack (this constructor line) is what callers get.\n const capture = (Error as unknown as { captureStackTrace?: (target: Error, ctor?: Function) => void }).captureStackTrace;\n if (typeof capture === 'function') {\n capture(this, this.constructor);\n }\n }\n\n // Lets callers do `err.toJSON()` for logging. Plain `Error` doesn't\n // serialize its non-enumerable fields; this picks them up explicitly.\n toJSON(): TemporalFmtErrorFields & { name: string; message: string } {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n input: this.input,\n format: this.format,\n token: this.token,\n position: this.position,\n expected: this.expected,\n actual: this.actual,\n reason: this.reason,\n };\n }\n}\n\n// Each subclass fixes `code` so callers can switch on it without\n// re-checking message text. The constructor takes only the fields\n// that vary per call; `code` and a default `message` template are\n// provided by the subclass.\n\nexport class FormatSyntaxError extends TemporalFmtError {\n constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n const { message, ...rest } = fields;\n super(\n message ?? `format string \"${fields.format ?? ''}\" has a syntax error${fields.reason ? `: ${fields.reason}` : ''}.`,\n { code: 'FORMAT_SYNTAX_ERROR', ...rest },\n );\n this.name = 'FormatSyntaxError';\n }\n}\n\nexport class UnknownTokenError extends TemporalFmtError {\n constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n const { message, ...rest } = fields;\n super(\n message ?? `token \"${fields.token ?? ''}\" is not a recognized temporal-fmt token${fields.format ? ` in format string \"${fields.format}\"` : ''}.`,\n { code: 'UNKNOWN_TOKEN', ...rest },\n );\n this.name = 'UnknownTokenError';\n }\n}\n\nexport class ParseMismatchError extends TemporalFmtError {\n constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n const { message, ...rest } = fields;\n super(\n message ?? `input \"${fields.input ?? ''}\" does not match format \"${fields.format ?? ''}\"${fields.reason ? `: ${fields.reason}` : ''}.`,\n { code: 'PARSE_MISMATCH', ...rest },\n );\n this.name = 'ParseMismatchError';\n }\n}\n\nexport class InvalidDateError extends TemporalFmtError {\n constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n const { message, ...rest } = fields;\n super(\n message ?? `input \"${fields.input ?? ''}\" does not describe a valid date${fields.reason ? `: ${fields.reason}` : ''}.`,\n { code: 'INVALID_DATE', ...rest },\n );\n this.name = 'InvalidDateError';\n }\n}\n\n/* c8 ignore start @preserve -- InvalidTimeError is part of the public\n error-class surface (exported from index.ts, code 'INVALID_TIME')\n but nothing in this package constructs one. Investigated wiring it\n in the same way InvalidTimeZoneError was just wired (see parse.ts's\n zzz-validation loop): checked whether hour/minute/second have a\n post-match semantic range check the way zone ids do. They don't —\n pattern.ts's regex fragments for HH/H/hh/h/mm/m/ss/s already enforce\n their valid ranges at the regex level (e.g. HH is '(?:[01]\\d|2[0-3])',\n which can't match \"99\" in the first place), so an out-of-range time\n is rejected as a plain shape mismatch before any semantic check\n could run. There's no live gap to hook this into without inventing a\n redundant check purely to give this class a body. Left unconstructed\n until the library actually has a real invalid-time case to report. */\nexport class InvalidTimeError extends TemporalFmtError {\n constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n const { message, ...rest } = fields;\n super(\n message ?? `input \"${fields.input ?? ''}\" does not describe a valid time${fields.reason ? `: ${fields.reason}` : ''}.`,\n { code: 'INVALID_TIME', ...rest },\n );\n this.name = 'InvalidTimeError';\n }\n}\n/* c8 ignore stop @preserve */\n\nexport class InvalidOffsetError extends TemporalFmtError {\n constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n const { message, ...rest } = fields;\n super(\n message ?? `offset \"${fields.actual ?? ''}\" is invalid${fields.reason ? `: ${fields.reason}` : ''}.`,\n { code: 'INVALID_OFFSET', ...rest },\n );\n this.name = 'InvalidOffsetError';\n }\n}\n\nexport class InvalidTimeZoneError extends TemporalFmtError {\n constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n const { message, ...rest } = fields;\n super(\n message ?? `time zone \"${fields.actual ?? ''}\" is not a recognized IANA time zone or fixed offset${fields.reason ? `: ${fields.reason}` : ''}.`,\n { code: 'INVALID_TIME_ZONE', ...rest },\n );\n this.name = 'InvalidTimeZoneError';\n }\n}\n\n/* c8 ignore start @preserve -- InvalidCalendarError is part of the\n public error-class surface (exported from index.ts, code\n 'INVALID_CALENDAR') but nothing in this package constructs one.\n Checked for a wiring opportunity the same way InvalidTimeZoneError\n got one: there's no user-supplied calendar identifier anywhere in\n the library to validate against a supported list. resolveCalendar()\n in parse.ts derives the calendar entirely from Intl's own resolution\n of the locale string — it's never handed an arbitrary \"calendar\"\n value a caller could get wrong. There's no live input to reject.\n Left unconstructed until the library actually accepts a calendar\n parameter that could be invalid. */\nexport class InvalidCalendarError extends TemporalFmtError {\n constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n const { message, ...rest } = fields;\n super(\n message ?? `calendar \"${fields.actual ?? ''}\" is not supported${fields.reason ? `: ${fields.reason}` : ''}.`,\n { code: 'INVALID_CALENDAR', ...rest },\n );\n this.name = 'InvalidCalendarError';\n }\n}\n/* c8 ignore stop @preserve */\n\nexport class AmbiguousInputError extends TemporalFmtError {\n constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n const { message, ...rest } = fields;\n super(\n message ?? `input \"${fields.input ?? ''}\" is ambiguous${fields.reason ? `: ${fields.reason}` : ''}.`,\n { code: 'AMBIGUOUS_INPUT', ...rest },\n );\n this.name = 'AmbiguousInputError';\n }\n}\n\nexport class InvalidLocaleError extends TemporalFmtError {\n constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n const { message, ...rest } = fields;\n super(\n message ?? `locale \"${fields.actual ?? ''}\" is not a valid BCP-47 tag${fields.reason ? `: ${fields.reason}` : ''}.`,\n { code: 'INVALID_LOCALE', ...rest },\n );\n this.name = 'InvalidLocaleError';\n }\n}\n\nexport class InvalidDurationError extends TemporalFmtError {\n constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n const { message, ...rest } = fields;\n super(\n message ?? `duration is invalid${fields.reason ? `: ${fields.reason}` : ''}.`,\n { code: 'INVALID_DURATION', ...rest },\n );\n this.name = 'InvalidDurationError';\n }\n}\n\n// Wraps a plain Error thrown from a code path that hasn't been\n// migrated to typed errors yet. Carries the original message in\n// `reason` so callers reading the typed surface still see what\n// failed. Used by safeParse() in parse.ts.\nexport function wrapUntypedError(err: Error, context: { input?: string; format?: string }): TemporalFmtError {\n // Try to classify by inspecting the message — covers the existing\n // parse()/format() throw sites without modifying them. Anything\n // that doesn't match a known pattern falls through to a generic\n // ParseMismatchError, which still has the structured fields.\n const msg = err.message;\n if (/unknown token|isn't a recognized token/.test(msg)) {\n return new UnknownTokenError({ input: context.input, format: context.format, reason: msg });\n }\n if (/ambiguous/i.test(msg)) {\n return new AmbiguousInputError({ input: context.input, format: context.format, reason: msg });\n }\n if (/offset/.test(msg) && /out of range|exceeds|doesn't match the shape/i.test(msg)) {\n return new InvalidOffsetError({ input: context.input, format: context.format, reason: msg });\n }\n if (/no valid pattern matches/i.test(msg)) {\n return new ParseMismatchError({ input: context.input, format: context.format, reason: msg });\n }\n if (/doesn't describe a valid date\\/time|incomplete date|weekday token|quarter token/.test(msg)) {\n return new InvalidDateError({ input: context.input, format: context.format, reason: msg });\n }\n /* c8 ignore start @preserve -- both triggers for this branch are\n currently unreachable through safeParse(), which is the only way\n wrapUntypedError gets called. localeVocab.ts's \"produced no\" throw\n needs Intl to omit a part for a valid locale (Intl-dependent, same\n category as the dead branches in serialization.ts); tokens.ts's\n \"produced no\" throw and formatDistance's \"cutoffs must be\" throw\n both happen on the format() side, which doesn't route through\n safeParse's catch at all. Kept, not deleted, since a future\n parse()-path locale validation could legitimately land here. */\n const lowerMsg = msg.toLowerCase();\n const mentionsLocale = lowerMsg.includes('locale');\n if (\n (mentionsLocale && (lowerMsg.includes('produced no') || lowerMsg.includes('not a valid'))) ||\n lowerMsg.includes('cutoffs must be')\n ) {\n return new InvalidLocaleError({ input: context.input, format: context.format, reason: msg });\n }\n /* c8 ignore stop @preserve */\n if (/format string exceeds maximum length|input exceeds maximum length|unterminated quote|isn't a recognized token/i.test(msg)) {\n return new FormatSyntaxError({ input: context.input, format: context.format, reason: msg });\n }\n return new ParseMismatchError({ input: context.input, format: context.format, reason: msg });\n}"],"mappings":";AA4DO,IAAM,mBAAN,cAA+B,MAAM;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,SAAiB,QAAgC;AAC3D,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO,OAAO;AACnB,SAAK,QAAQ,OAAO;AACpB,SAAK,SAAS,OAAO;AACrB,SAAK,QAAQ,OAAO;AACpB,SAAK,WAAW,OAAO;AACvB,SAAK,WAAW,OAAO;AACvB,SAAK,SAAS,OAAO;AACrB,SAAK,SAAS,OAAO;AAIrB,UAAM,UAAW,MAAsF;AACvG,QAAI,OAAO,YAAY,YAAY;AACjC,cAAQ,MAAM,KAAK,WAAW;AAAA,IAChC;AAAA,EACF;AAAA;AAAA;AAAA,EAIA,SAAqE;AACnE,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,SAAS,KAAK;AAAA,MACd,MAAM,KAAK;AAAA,MACX,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,MACb,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,UAAU,KAAK;AAAA,MACf,QAAQ,KAAK;AAAA,MACb,QAAQ,KAAK;AAAA,IACf;AAAA,EACF;AACF;AAOO,IAAM,oBAAN,cAAgC,iBAAiB;AAAA,EACtD,YAAY,QAAqE;AAC/E,UAAM,EAAE,SAAS,GAAG,KAAK,IAAI;AAC7B;AAAA,MACE,WAAW,kBAAkB,OAAO,UAAU,EAAE,uBAAuB,OAAO,SAAS,KAAK,OAAO,MAAM,KAAK,EAAE;AAAA,MAChH,EAAE,MAAM,uBAAuB,GAAG,KAAK;AAAA,IACzC;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,oBAAN,cAAgC,iBAAiB;AAAA,EACtD,YAAY,QAAqE;AAC/E,UAAM,EAAE,SAAS,GAAG,KAAK,IAAI;AAC7B;AAAA,MACE,WAAW,UAAU,OAAO,SAAS,EAAE,2CAA2C,OAAO,SAAS,sBAAsB,OAAO,MAAM,MAAM,EAAE;AAAA,MAC7I,EAAE,MAAM,iBAAiB,GAAG,KAAK;AAAA,IACnC;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,qBAAN,cAAiC,iBAAiB;AAAA,EACvD,YAAY,QAAqE;AAC/E,UAAM,EAAE,SAAS,GAAG,KAAK,IAAI;AAC7B;AAAA,MACE,WAAW,UAAU,OAAO,SAAS,EAAE,4BAA4B,OAAO,UAAU,EAAE,IAAI,OAAO,SAAS,KAAK,OAAO,MAAM,KAAK,EAAE;AAAA,MACnI,EAAE,MAAM,kBAAkB,GAAG,KAAK;AAAA,IACpC;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,mBAAN,cAA+B,iBAAiB;AAAA,EACrD,YAAY,QAAqE;AAC/E,UAAM,EAAE,SAAS,GAAG,KAAK,IAAI;AAC7B;AAAA,MACE,WAAW,UAAU,OAAO,SAAS,EAAE,mCAAmC,OAAO,SAAS,KAAK,OAAO,MAAM,KAAK,EAAE;AAAA,MACnH,EAAE,MAAM,gBAAgB,GAAG,KAAK;AAAA,IAClC;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaO,IAAM,mBAAN,cAA+B,iBAAiB;AAAA,EACrD,YAAY,QAAqE;AAC/E,UAAM,EAAE,SAAS,GAAG,KAAK,IAAI;AAC7B;AAAA,MACE,WAAW,UAAU,OAAO,SAAS,EAAE,mCAAmC,OAAO,SAAS,KAAK,OAAO,MAAM,KAAK,EAAE;AAAA,MACnH,EAAE,MAAM,gBAAgB,GAAG,KAAK;AAAA,IAClC;AACA,SAAK,OAAO;AAAA,EACd;AACF;AACA;AAEO,IAAM,qBAAN,cAAiC,iBAAiB;AAAA,EACvD,YAAY,QAAqE;AAC/E,UAAM,EAAE,SAAS,GAAG,KAAK,IAAI;AAC7B;AAAA,MACE,WAAW,WAAW,OAAO,UAAU,EAAE,eAAe,OAAO,SAAS,KAAK,OAAO,MAAM,KAAK,EAAE;AAAA,MACjG,EAAE,MAAM,kBAAkB,GAAG,KAAK;AAAA,IACpC;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,uBAAN,cAAmC,iBAAiB;AAAA,EACzD,YAAY,QAAqE;AAC/E,UAAM,EAAE,SAAS,GAAG,KAAK,IAAI;AAC7B;AAAA,MACE,WAAW,cAAc,OAAO,UAAU,EAAE,uDAAuD,OAAO,SAAS,KAAK,OAAO,MAAM,KAAK,EAAE;AAAA,MAC5I,EAAE,MAAM,qBAAqB,GAAG,KAAK;AAAA,IACvC;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWO,IAAM,uBAAN,cAAmC,iBAAiB;AAAA,EACzD,YAAY,QAAqE;AAC/E,UAAM,EAAE,SAAS,GAAG,KAAK,IAAI;AAC7B;AAAA,MACE,WAAW,aAAa,OAAO,UAAU,EAAE,qBAAqB,OAAO,SAAS,KAAK,OAAO,MAAM,KAAK,EAAE;AAAA,MACzG,EAAE,MAAM,oBAAoB,GAAG,KAAK;AAAA,IACtC;AACA,SAAK,OAAO;AAAA,EACd;AACF;AACA;AAEO,IAAM,sBAAN,cAAkC,iBAAiB;AAAA,EACxD,YAAY,QAAqE;AAC/E,UAAM,EAAE,SAAS,GAAG,KAAK,IAAI;AAC7B;AAAA,MACE,WAAW,UAAU,OAAO,SAAS,EAAE,iBAAiB,OAAO,SAAS,KAAK,OAAO,MAAM,KAAK,EAAE;AAAA,MACjG,EAAE,MAAM,mBAAmB,GAAG,KAAK;AAAA,IACrC;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,qBAAN,cAAiC,iBAAiB;AAAA,EACvD,YAAY,QAAqE;AAC/E,UAAM,EAAE,SAAS,GAAG,KAAK,IAAI;AAC7B;AAAA,MACE,WAAW,WAAW,OAAO,UAAU,EAAE,8BAA8B,OAAO,SAAS,KAAK,OAAO,MAAM,KAAK,EAAE;AAAA,MAChH,EAAE,MAAM,kBAAkB,GAAG,KAAK;AAAA,IACpC;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,uBAAN,cAAmC,iBAAiB;AAAA,EACzD,YAAY,QAAqE;AAC/E,UAAM,EAAE,SAAS,GAAG,KAAK,IAAI;AAC7B;AAAA,MACE,WAAW,sBAAsB,OAAO,SAAS,KAAK,OAAO,MAAM,KAAK,EAAE;AAAA,MAC1E,EAAE,MAAM,oBAAoB,GAAG,KAAK;AAAA,IACtC;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAMO,SAAS,iBAAiB,KAAY,SAAgE;AAK3G,QAAM,MAAM,IAAI;AAChB,MAAI,yCAAyC,KAAK,GAAG,GAAG;AACtD,WAAO,IAAI,kBAAkB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,IAAI,CAAC;AAAA,EAC5F;AACA,MAAI,aAAa,KAAK,GAAG,GAAG;AAC1B,WAAO,IAAI,oBAAoB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,IAAI,CAAC;AAAA,EAC9F;AACA,MAAI,SAAS,KAAK,GAAG,KAAK,gDAAgD,KAAK,GAAG,GAAG;AACnF,WAAO,IAAI,mBAAmB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,IAAI,CAAC;AAAA,EAC7F;AACA,MAAI,4BAA4B,KAAK,GAAG,GAAG;AACzC,WAAO,IAAI,mBAAmB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,IAAI,CAAC;AAAA,EAC7F;AACA,MAAI,kFAAkF,KAAK,GAAG,GAAG;AAC/F,WAAO,IAAI,iBAAiB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,IAAI,CAAC;AAAA,EAC3F;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,QAAM,WAAW,IAAI,YAAY;AACjC,QAAM,iBAAiB,SAAS,SAAS,QAAQ;AACjD,MACG,mBAAmB,SAAS,SAAS,aAAa,KAAK,SAAS,SAAS,aAAa,MACvF,SAAS,SAAS,iBAAiB,GACnC;AACA,WAAO,IAAI,mBAAmB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,IAAI,CAAC;AAAA,EAC7F;AAAA,EACA;AACA,MAAI,iHAAiH,KAAK,GAAG,GAAG;AAC9H,WAAO,IAAI,kBAAkB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,IAAI,CAAC;AAAA,EAC5F;AACA,SAAO,IAAI,mBAAmB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,IAAI,CAAC;AAC7F;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  asDateFieldView
3
- } from "./chunk-4ZBGVYLR.js";
3
+ } from "./chunk-GNUK7PGX.js";
4
4
 
5
5
  // src/comparison.ts
6
6
  function toComparableMs(view) {
@@ -185,4 +185,4 @@ export {
185
185
  isWeekend,
186
186
  isWeekday
187
187
  };
188
- //# sourceMappingURL=chunk-NFKQ3EXC.js.map
188
+ //# sourceMappingURL=chunk-AKJOTI7X.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/comparison.ts"],"sourcesContent":["/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Comparison helpers. Pure functions over the field\n// shape, no Temporal namespace needed — same convention as\n// calendarUtils.ts. All comparisons are field-based, not identity-based,\n// so a polyfill PlainDate compares equal to a native PlainDate with the\n// same year/month/day.\n\nimport { asDateFieldView, type DateFieldView } from './calendarUtils.js';\n\ninterface DateTimeFieldView extends DateFieldView {\n hour?: number;\n minute?: number;\n second?: number;\n millisecond?: number;\n}\n\nfunction toComparableMs(view: DateTimeFieldView): number {\n // Same epoch anchor formatDistance uses — Jan 1, 2000 UTC reference.\n // Lets us compare dates by ms-since-epoch without needing a Temporal\n // implementation. For comparison purposes, the absolute value doesn't\n // matter; only the relative ordering between two values does.\n const REFERENCE_YEAR = 2000;\n const DAYS_PER_YEAR_AVG = 365.2425; // Gregorian average\n const MS_PER_DAY = 86_400_000;\n const MS_PER_HOUR = 3_600_000;\n const MS_PER_MINUTE = 60_000;\n const MS_PER_SECOND = 1_000;\n\n const year = view.year!;\n const yearsFromRef = year - REFERENCE_YEAR;\n // Approximate ms offset — using the average days-per-year keeps this\n // branchless over leap years, which is fine for *comparison* (the\n // error is constant for any given year, so it cancels out in a diff).\n const yearMs = yearsFromRef * DAYS_PER_YEAR_AVG * MS_PER_DAY;\n\n // Use dayOfYear via the existing helper — handles leap years precisely.\n // Importing it here would create a circular dep (calendarUtils imports\n // nothing from this module), so we duplicate the small computation.\n // The CUMULATIVE_DAYS_BY_MONTH table lives in isoWeek.ts; we replicate\n // a minimal version here to keep this module self-contained.\n const CUMULATIVE_DAYS = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];\n let doy = CUMULATIVE_DAYS[(view.month! - 1)!]! + view.day! - 1;\n const isLeap = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n if (view.month! > 2 && isLeap) doy += 1;\n const dayMs = doy * MS_PER_DAY;\n\n const hourMs = (view.hour ?? 0) * MS_PER_HOUR;\n const minuteMs = (view.minute ?? 0) * MS_PER_MINUTE;\n const secondMs = (view.second ?? 0) * MS_PER_SECOND;\n const msMs = view.millisecond ?? 0;\n return yearMs + dayMs + hourMs + minuteMs + secondMs + msMs;\n}\n\nfunction asDateTimeFieldView(value: unknown): DateTimeFieldView {\n const v = asDateFieldView(value);\n return v as DateTimeFieldView;\n}\n\n// Returns < 0 if a < b, 0 if a === b, > 0 if a > b. Same convention as\n// Array.prototype.sort and Temporal.PlainDate.compare. Lets callers\n// pass this directly as a comparator.\nexport function compare(a: unknown, b: unknown): number {\n const av = asDateTimeFieldView(a);\n const bv = asDateTimeFieldView(b);\n const am = toComparableMs(av);\n const bm = toComparableMs(bv);\n if (am < bm) return -1;\n if (am > bm) return 1;\n return 0;\n}\n\nexport function isEqual(a: unknown, b: unknown): boolean {\n return compare(a, b) === 0;\n}\n\nexport function isBefore(a: unknown, b: unknown): boolean {\n return compare(a, b) < 0;\n}\n\nexport function isAfter(a: unknown, b: unknown): boolean {\n return compare(a, b) > 0;\n}\n\nexport function min(values: unknown[]): unknown {\n if (!Array.isArray(values) || values.length === 0) {\n throw new Error('temporal-fmt: min() requires a non-empty array of values.');\n }\n let best = values[0];\n for (let i = 1; i < values.length; i++) {\n if (compare(values[i], best) < 0) best = values[i];\n }\n return best;\n}\n\nexport function max(values: unknown[]): unknown {\n if (!Array.isArray(values) || values.length === 0) {\n throw new Error('temporal-fmt: max() requires a non-empty array of values.');\n }\n let best = values[0];\n for (let i = 1; i < values.length; i++) {\n if (compare(values[i], best) > 0) best = values[i];\n }\n return best;\n}\n\nexport function clamp(value: unknown, lo: unknown, hi: unknown): unknown {\n if (compare(value, lo) < 0) return lo;\n if (compare(value, hi) > 0) return hi;\n return value;\n}\n\nexport function isBetween(value: unknown, lo: unknown, hi: unknown): boolean {\n return compare(value, lo) >= 0 && compare(value, hi) <= 0;\n}\n\n// Semantic helpers — same-day/week/month/quarter/year tests. Useful for\n// UI (\"is this event today?\") and for grouping/aggregation. All take a\n// reference value to compare against; the \"isToday\" / \"isTomorrow\" /\n// \"isYesterday\" variants compute the reference from the current system\n// date themselves so callers don't have to.\nfunction readYearMonthDay(value: unknown): { year: number; month: number; day: number } {\n const v = asDateFieldView(value);\n return { year: v.year!, month: v.month!, day: v.day! };\n}\n\nfunction todayYearMonthDay(): { year: number; month: number; day: number } {\n const now = new Date();\n return { year: now.getFullYear(), month: now.getMonth() + 1, day: now.getDate() };\n}\n\nfunction dateEqualYearMonthDay(a: { year: number; month: number; day: number }, b: { year: number; month: number; day: number }): boolean {\n return a.year === b.year && a.month === b.month && a.day === b.day;\n}\n\nexport function isSameDay(value: unknown, reference: unknown): boolean {\n return dateEqualYearMonthDay(readYearMonthDay(value), readYearMonthDay(reference));\n}\n\nexport function isToday(value: unknown): boolean {\n return dateEqualYearMonthDay(readYearMonthDay(value), todayYearMonthDay());\n}\n\nfunction tomorrowYearMonthDay(): { year: number; month: number; day: number } {\n const d = new Date();\n d.setDate(d.getDate() + 1);\n return { year: d.getFullYear(), month: d.getMonth() + 1, day: d.getDate() };\n}\n\nfunction yesterdayYearMonthDay(): { year: number; month: number; day: number } {\n const d = new Date();\n d.setDate(d.getDate() - 1);\n return { year: d.getFullYear(), month: d.getMonth() + 1, day: d.getDate() };\n}\n\nexport function isTomorrow(value: unknown): boolean {\n return dateEqualYearMonthDay(readYearMonthDay(value), tomorrowYearMonthDay());\n}\n\nexport function isYesterday(value: unknown): boolean {\n return dateEqualYearMonthDay(readYearMonthDay(value), yesterdayYearMonthDay());\n}\n\nfunction sameWeek(yearA: number, monthA: number, dayA: number, yearB: number, monthB: number, dayB: number): boolean {\n // Same week iff the dates are within 7 days of each other AND the earlier\n // one's weekday is ≤ the later one's weekday (so we don't say \"Sun and\n // the following Mon are in the same week\" — ISO weeks run Mon-Sun).\n // Easier: compute ISO week numbers via isoWeekYearAndWeek, compare both\n // year and week. That handles the year-boundary case (Dec 31 vs Jan 1 of\n // the next year, which can be in the same ISO week).\n // Local import to avoid module-cycle: isoWeek.ts doesn't import from here.\n // Lazy require-style dynamic via inline static import at top would be\n // cleaner; this inline computation is fine for a pure helper.\n // ...actually let's just compute weekday offsets directly. Same-ISO-week\n // iff |d1 - d2| < 7 days AND the earlier date's ISO weekday ≤ the later\n // date's ISO weekday so they fall in the same Mon-Sun span.\n const DAYS_PER_400_YEARS = 146097;\n const daysSince = (y: number, m: number, d: number): number => {\n // Zeller's congruence variant — convert Y/M/D to a day count.\n // Using a simple algorithm here that's correct for proleptic Gregorian.\n const y2 = m <= 2 ? y - 1 : y;\n const era = (y2 >= 0 ? y2 : y2 - 399) / 400 | 0;\n const yoe = y2 - era * 400;\n const m2 = m > 2 ? m - 3 : m + 9;\n const doy = Math.floor((Math.floor(153 * m2 + 2) / 5) + d - 1);\n const doe = yoe * 365 + Math.floor(yoe / 4) - Math.floor(yoe / 100) + doy;\n return era * DAYS_PER_400_YEARS + doe - 719468;\n };\n const a = daysSince(yearA, monthA, dayA);\n const b = daysSince(yearB, monthB, dayB);\n if (Math.abs(a - b) >= 7) return false;\n // Same week iff both dates round to the same Monday. Compute the\n // Monday-of-week for each: subtract (weekday - 1) days, where weekday\n // is 1=Mon..7=Sun. Use the standard Zeller formula for weekday.\n const weekdayOf = (y: number, m: number, d: number): number => {\n const days = daysSince(y, m, d);\n // 1970-01-01 was a Thursday (ISO 4). So weekday = ((days + 3) mod 7) + 1\n // mapped to Mon=1..Sun=7. Let's compute: Sun=0..Sat=6 via JS Date.\n const date = new Date(Date.UTC(y, m - 1, d));\n const jsDow = date.getUTCDay(); // 0=Sun..6=Sat\n return jsDow === 0 ? 7 : jsDow;\n };\n const wa = a - (weekdayOf(yearA, monthA, dayA) - 1);\n const wb = b - (weekdayOf(yearB, monthB, dayB) - 1);\n return wa === wb;\n}\n\nexport function isSameWeek(value: unknown, reference: unknown): boolean {\n const a = readYearMonthDay(value);\n const b = readYearMonthDay(reference);\n return sameWeek(a.year, a.month, a.day, b.year, b.month, b.day);\n}\n\nexport function isSameMonth(value: unknown, reference: unknown): boolean {\n const a = readYearMonthDay(value);\n const b = readYearMonthDay(reference);\n return a.year === b.year && a.month === b.month;\n}\n\nexport function isSameQuarter(value: unknown, reference: unknown): boolean {\n const a = readYearMonthDay(value);\n const b = readYearMonthDay(reference);\n return a.year === b.year && Math.ceil(a.month / 3) === Math.ceil(b.month / 3);\n}\n\nexport function isSameYear(value: unknown, reference: unknown): boolean {\n return readYearMonthDay(value).year === readYearMonthDay(reference).year;\n}\n\n// isWeekend / isWeekday depend on dayOfWeek — present on PlainDate,\n// PlainDateTime, ZonedDateTime, but NOT on PlainTime. Callers passing\n// PlainTime get a descriptive throw. Doesn't call asDateFieldView\n// because that would reject PlainTime (no year/month/day) before\n// reaching the dayOfWeek check — and the error we want here is the\n// \"no dayOfWeek field\" one, not the \"no date fields\" one.\nexport function isWeekend(value: unknown): boolean {\n if (typeof value !== 'object' || value === null) {\n throw new Error(`temporal-fmt: isWeekend() expected a Temporal value, got ${String(value)}.`);\n }\n const v = value as { dayOfWeek?: unknown };\n if (typeof v.dayOfWeek !== 'number') {\n throw new Error(\n `temporal-fmt: isWeekend() needs a value with a dayOfWeek field (PlainDate / PlainDateTime / ZonedDateTime).`\n );\n }\n // 6=Sat, 7=Sun in Temporal's Mon=1..Sun=7 numbering.\n return v.dayOfWeek === 6 || v.dayOfWeek === 7;\n}\n\nexport function isWeekday(value: unknown): boolean {\n return !isWeekend(value);\n}\n"],"mappings":"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","names":[]}
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  add
3
- } from "./chunk-VHSZL3P3.js";
3
+ } from "./chunk-UX4Z3WFS.js";
4
4
  import {
5
5
  compare
6
- } from "./chunk-NFKQ3EXC.js";
6
+ } from "./chunk-AKJOTI7X.js";
7
7
 
8
8
  // src/recurrence.ts
9
9
  function recurrence(start, rule) {
@@ -99,12 +99,21 @@ function take(iter, n) {
99
99
  }
100
100
  return result;
101
101
  }
102
+ var MAX_SKIP_COLLECTION = 1e5;
102
103
  function skip(iter, n) {
103
104
  for (let i = 0; i < n; i++) {
104
105
  const r = iter.next();
105
106
  if (r.done) break;
106
107
  }
107
- return take(iter, Number.MAX_SAFE_INTEGER);
108
+ const result = [];
109
+ while (result.length < MAX_SKIP_COLLECTION) {
110
+ const r = iter.next();
111
+ if (r.done) return result;
112
+ result.push(r.value);
113
+ }
114
+ throw new RangeError(
115
+ `temporal-fmt: skip() collected ${MAX_SKIP_COLLECTION} occurrences and the rule is still producing \u2014 add a count or until to the rule, or use take(iter, n) for a bounded read.`
116
+ );
108
117
  }
109
118
  function between(start, rule, rangeStart, rangeEnd) {
110
119
  const iter = recurrence(start, rule);
@@ -212,4 +221,4 @@ export {
212
221
  parseRRule,
213
222
  formatRRule
214
223
  };
215
- //# sourceMappingURL=chunk-CSUIKL73.js.map
224
+ //# sourceMappingURL=chunk-B5WSYLXA.js.map