temporal-fmt 0.9.0 → 0.9.2

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 (105) hide show
  1. package/dist/calendarUtils.cjs +4 -259
  2. package/dist/calendarUtils.cjs.map +1 -1
  3. package/dist/calendarUtils.js +1 -33
  4. package/dist/chunk-2JHEV7ZF.js +7 -0
  5. package/dist/chunk-2JHEV7ZF.js.map +1 -0
  6. package/dist/chunk-3MZLTVP3.js +2 -0
  7. package/dist/{chunk-MXXYIMFJ.js.map → chunk-3MZLTVP3.js.map} +1 -1
  8. package/dist/chunk-4JWGUR4O.js +11 -0
  9. package/dist/{chunk-AXQLUIDY.js.map → chunk-4JWGUR4O.js.map} +1 -1
  10. package/dist/chunk-5U5WJ465.js +36 -0
  11. package/dist/chunk-5U5WJ465.js.map +1 -0
  12. package/dist/chunk-C5YESWFT.js +2 -0
  13. package/dist/chunk-C5YESWFT.js.map +1 -0
  14. package/dist/chunk-C6ZZ62ET.js +2 -0
  15. package/dist/{chunk-YS52LOMJ.js.map → chunk-C6ZZ62ET.js.map} +1 -1
  16. package/dist/chunk-EHLRZULM.js +5 -0
  17. package/dist/{chunk-4ZBGVYLR.js.map → chunk-EHLRZULM.js.map} +1 -1
  18. package/dist/chunk-F4RGUDA3.js +2 -0
  19. package/dist/chunk-F4RGUDA3.js.map +1 -0
  20. package/dist/chunk-J2AQNXF2.js +2 -0
  21. package/dist/{chunk-GRJQHQLW.js.map → chunk-J2AQNXF2.js.map} +1 -1
  22. package/dist/chunk-NBXF7V5B.js +2 -0
  23. package/dist/chunk-NBXF7V5B.js.map +1 -0
  24. package/dist/chunk-R52YOKI3.js +7 -0
  25. package/dist/{chunk-M33NSC4E.js.map → chunk-R52YOKI3.js.map} +1 -1
  26. package/dist/chunk-UJR6DHXY.js +2 -0
  27. package/dist/chunk-UJR6DHXY.js.map +1 -0
  28. package/dist/chunk-VQXUMFB2.js +21 -0
  29. package/dist/{chunk-VHSZL3P3.js.map → chunk-VQXUMFB2.js.map} +1 -1
  30. package/dist/chunk-XH46JNPK.js +2 -0
  31. package/dist/chunk-XH46JNPK.js.map +1 -0
  32. package/dist/chunk-YB6YAG7E.js +35 -0
  33. package/dist/chunk-YB6YAG7E.js.map +1 -0
  34. package/dist/chunk-ZGMTY52O.js +2 -0
  35. package/dist/chunk-ZGMTY52O.js.map +1 -0
  36. package/dist/duration.cjs +9 -624
  37. package/dist/duration.cjs.map +1 -1
  38. package/dist/duration.js +1 -29
  39. package/dist/format.cjs +18 -769
  40. package/dist/format.cjs.map +1 -1
  41. package/dist/format.js +1 -20
  42. package/dist/formatDuration.d.cts +6 -0
  43. package/dist/formatDuration.d.ts +6 -0
  44. package/dist/index.cjs +146 -6672
  45. package/dist/index.cjs.map +1 -1
  46. package/dist/index.js +58 -3004
  47. package/dist/index.js.map +1 -1
  48. package/dist/interval.cjs +18 -952
  49. package/dist/interval.cjs.map +1 -1
  50. package/dist/interval.js +1 -41
  51. package/dist/localeRegistry.cjs +15 -328
  52. package/dist/localeRegistry.cjs.map +1 -1
  53. package/dist/localeRegistry.js +1 -11
  54. package/dist/localeVocab.d.cts +3 -0
  55. package/dist/localeVocab.d.ts +3 -0
  56. package/dist/parse.cjs +53 -1637
  57. package/dist/parse.cjs.map +1 -1
  58. package/dist/parse.js +1 -20
  59. package/dist/parsePattern.d.cts +1 -0
  60. package/dist/parsePattern.d.ts +1 -0
  61. package/dist/pattern.d.cts +1 -0
  62. package/dist/pattern.d.ts +1 -0
  63. package/dist/recurrence.cjs +20 -450
  64. package/dist/recurrence.cjs.map +1 -1
  65. package/dist/recurrence.js +1 -20
  66. package/dist/relativeTime.cjs +24 -177
  67. package/dist/relativeTime.cjs.map +1 -1
  68. package/dist/relativeTime.js +1 -14
  69. package/dist/rounding.d.cts +1 -0
  70. package/dist/rounding.d.ts +1 -0
  71. package/dist/serialization.d.cts +1 -1
  72. package/dist/serialization.d.ts +1 -1
  73. package/dist/timezone.cjs +20 -387
  74. package/dist/timezone.cjs.map +1 -1
  75. package/dist/timezone.js +1 -26
  76. package/dist/typeGuards.d.cts +9 -9
  77. package/dist/typeGuards.d.ts +9 -9
  78. package/package.json +4 -2
  79. package/dist/chunk-4ZBGVYLR.js +0 -182
  80. package/dist/chunk-AXQLUIDY.js +0 -183
  81. package/dist/chunk-CKVHXFX7.js +0 -902
  82. package/dist/chunk-CKVHXFX7.js.map +0 -1
  83. package/dist/chunk-CSUIKL73.js +0 -215
  84. package/dist/chunk-CSUIKL73.js.map +0 -1
  85. package/dist/chunk-EDUFSRWJ.js +0 -9
  86. package/dist/chunk-EDUFSRWJ.js.map +0 -1
  87. package/dist/chunk-FQA4XJME.js +0 -57
  88. package/dist/chunk-FQA4XJME.js.map +0 -1
  89. package/dist/chunk-FTMLZ4EN.js +0 -196
  90. package/dist/chunk-FTMLZ4EN.js.map +0 -1
  91. package/dist/chunk-GRJQHQLW.js +0 -170
  92. package/dist/chunk-JCIMP43G.js +0 -602
  93. package/dist/chunk-JCIMP43G.js.map +0 -1
  94. package/dist/chunk-KDYK72Z2.js +0 -75
  95. package/dist/chunk-KDYK72Z2.js.map +0 -1
  96. package/dist/chunk-M33NSC4E.js +0 -169
  97. package/dist/chunk-MXXYIMFJ.js +0 -29
  98. package/dist/chunk-NFKQ3EXC.js +0 -188
  99. package/dist/chunk-NFKQ3EXC.js.map +0 -1
  100. package/dist/chunk-O6GVMBLW.js +0 -403
  101. package/dist/chunk-O6GVMBLW.js.map +0 -1
  102. package/dist/chunk-VHSZL3P3.js +0 -242
  103. package/dist/chunk-VSUCBUTC.js +0 -295
  104. package/dist/chunk-VSUCBUTC.js.map +0 -1
  105. package/dist/chunk-YS52LOMJ.js +0 -51
package/dist/format.cjs CHANGED
@@ -1,116 +1,4 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/format.ts
21
- var format_exports = {};
22
- __export(format_exports, {
23
- _getPieces: () => _getPieces,
24
- _handlerFor: () => _handlerFor,
25
- compileFormat: () => compileFormat,
26
- format: () => format,
27
- formatToParts: () => formatToParts
28
- });
29
- module.exports = __toCommonJS(format_exports);
30
-
31
- // src/temporalProvider.ts
32
- var injectedTemporal;
33
- var onTemporalChanged = [];
34
- function subscribeToTemporalChanges(listener) {
35
- onTemporalChanged.push(listener);
36
- }
37
- function resolveTemporal() {
38
- return injectedTemporal ?? globalThis.Temporal;
39
- }
40
- function getTemporal() {
41
- const temporal = resolveTemporal();
42
- if (!temporal) {
43
- throw new Error(
44
- "temporal-fmt: parse() needs a Temporal implementation to construct its result. Call setTemporal(Temporal) once at startup, or assign one to globalThis.Temporal (native on Node 26+, or a polyfill like temporal-polyfill)."
45
- );
46
- }
47
- return temporal;
48
- }
49
-
50
- // src/errors.ts
51
- var TemporalFmtError = class extends Error {
52
- code;
53
- input;
54
- format;
55
- token;
56
- position;
57
- expected;
58
- actual;
59
- reason;
60
- constructor(message, fields) {
61
- super(message);
62
- this.name = "TemporalFmtError";
63
- this.code = fields.code;
64
- this.input = fields.input;
65
- this.format = fields.format;
66
- this.token = fields.token;
67
- this.position = fields.position;
68
- this.expected = fields.expected;
69
- this.actual = fields.actual;
70
- this.reason = fields.reason;
71
- const capture = Error.captureStackTrace;
72
- if (typeof capture === "function") {
73
- capture(this, this.constructor);
74
- }
75
- }
76
- // Lets callers do `err.toJSON()` for logging. Plain `Error` doesn't
77
- // serialize its non-enumerable fields; this picks them up explicitly.
78
- toJSON() {
79
- return {
80
- name: this.name,
81
- message: this.message,
82
- code: this.code,
83
- input: this.input,
84
- format: this.format,
85
- token: this.token,
86
- position: this.position,
87
- expected: this.expected,
88
- actual: this.actual,
89
- reason: this.reason
90
- };
91
- }
92
- };
93
- var FormatSyntaxError = class extends TemporalFmtError {
94
- constructor(fields) {
95
- const { message, ...rest } = fields;
96
- super(
97
- message ?? `format string "${fields.format ?? ""}" has a syntax error${fields.reason ? `: ${fields.reason}` : ""}.`,
98
- { code: "FORMAT_SYNTAX_ERROR", ...rest }
99
- );
100
- this.name = "FormatSyntaxError";
101
- }
102
- };
103
- var UnknownTokenError = class extends TemporalFmtError {
104
- constructor(fields) {
105
- const { message, ...rest } = fields;
106
- super(
107
- message ?? `token "${fields.token ?? ""}" is not a recognized temporal-fmt token${fields.format ? ` in format string "${fields.format}"` : ""}.`,
108
- { code: "UNKNOWN_TOKEN", ...rest }
109
- );
110
- this.name = "UnknownTokenError";
111
- }
112
- };
113
- /* c8 ignore start @preserve -- InvalidTimeError is part of the public
1
+ "use strict";var V=Object.defineProperty;var Q=Object.getOwnPropertyDescriptor;var J=Object.getOwnPropertyNames;var ee=Object.prototype.hasOwnProperty;var te=(e,t)=>{for(var n in t)V(e,n,{get:t[n],enumerable:!0})},ne=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of J(t))!ee.call(e,i)&&i!==n&&V(e,i,{get:()=>t[i],enumerable:!(o=Q(t,i))||o.enumerable});return e};var oe=e=>ne(V({},"__esModule",{value:!0}),e);var Le={};te(Le,{_getPieces:()=>Ee,_handlerFor:()=>be,compileFormat:()=>ke,format:()=>we,formatToParts:()=>Te});module.exports=oe(Le);var re,ae=[];function W(e){ae.push(e)}function ie(){return re??globalThis.Temporal}function K(){let e=ie();if(!e)throw new Error("temporal-fmt: parse() needs a Temporal implementation to construct its result. Call setTemporal(Temporal) once at startup, or assign one to globalThis.Temporal (native on Node 26+, or a polyfill like temporal-polyfill).");return e}var w=class extends Error{code;input;format;token;position;expected;actual;reason;constructor(t,n){super(t),this.name="TemporalFmtError",this.code=n.code,this.input=n.input,this.format=n.format,this.token=n.token,this.position=n.position,this.expected=n.expected,this.actual=n.actual,this.reason=n.reason;let o=Error.captureStackTrace;typeof o=="function"&&o(this,this.constructor)}toJSON(){return{name:this.name,message:this.message,code:this.code,input:this.input,format:this.format,token:this.token,position:this.position,expected:this.expected,actual:this.actual,reason:this.reason}}},c=class extends w{constructor(t){let{message:n,...o}=t;super(n??`format string "${t.format??""}" has a syntax error${t.reason?`: ${t.reason}`:""}.`,{code:"FORMAT_SYNTAX_ERROR",...o}),this.name="FormatSyntaxError"}},d=class extends w{constructor(t){let{message:n,...o}=t;super(n??`token "${t.token??""}" is not a recognized temporal-fmt token${t.format?` in format string "${t.format}"`:""}.`,{code:"UNKNOWN_TOKEN",...o}),this.name="UnknownTokenError"}};/* c8 ignore start @preserve -- InvalidTimeError is part of the public
114
2
  error-class surface (exported from index.ts, code 'INVALID_TIME')
115
3
  but nothing in this package constructs one. Investigated wiring it
116
4
  in the same way InvalidTimeZoneError was just wired (see parse.ts's
@@ -122,9 +10,7 @@ var UnknownTokenError = class extends TemporalFmtError {
122
10
  is rejected as a plain shape mismatch before any semantic check
123
11
  could run. There's no live gap to hook this into without inventing a
124
12
  redundant check purely to give this class a body. Left unconstructed
125
- until the library actually has a real invalid-time case to report. */
126
- /* c8 ignore stop @preserve */
127
- /* c8 ignore start @preserve -- InvalidCalendarError is part of the
13
+ until the library actually has a real invalid-time case to report. *//* c8 ignore stop @preserve *//* c8 ignore start @preserve -- InvalidCalendarError is part of the
128
14
  public error-class surface (exported from index.ts, code
129
15
  'INVALID_CALENDAR') but nothing in this package constructs one.
130
16
  Checked for a wiring opportunity the same way InvalidTimeZoneError
@@ -134,657 +20,20 @@ var UnknownTokenError = class extends TemporalFmtError {
134
20
  of the locale string — it's never handed an arbitrary "calendar"
135
21
  value a caller could get wrong. There's no live input to reject.
136
22
  Left unconstructed until the library actually accepts a calendar
137
- parameter that could be invalid. */
138
- /* c8 ignore stop @preserve */
139
- var InvalidLocaleError = class extends TemporalFmtError {
140
- constructor(fields) {
141
- const { message, ...rest } = fields;
142
- super(
143
- message ?? `locale "${fields.actual ?? ""}" is not a valid BCP-47 tag${fields.reason ? `: ${fields.reason}` : ""}.`,
144
- { code: "INVALID_LOCALE", ...rest }
145
- );
146
- this.name = "InvalidLocaleError";
147
- }
148
- };
149
- /* c8 ignore start @preserve -- unreachable from the current test suite,
150
- see rationale above */
151
- /* c8 ignore stop @preserve */
152
-
153
- // src/localeVocab.ts
154
- var customVocabs = /* @__PURE__ */ new Map();
155
- function canonicalCacheKey(locale) {
156
- try {
157
- return new Intl.Locale(locale.replace(/_/g, "-")).toString().toLowerCase();
158
- } catch {
159
- return locale;
160
- }
161
- }
162
- function getCustomVocab(locale) {
163
- const cacheKey = canonicalCacheKey(locale);
164
- return customVocabs.get(cacheKey);
165
- }
166
-
167
- // src/isoWeek.ts
168
- var CUMULATIVE_DAYS_BY_MONTH = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
169
- function isGregorianLeapYear(year) {
170
- return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
171
- }
172
- function daysInYear(year) {
173
- return isGregorianLeapYear(year) ? 366 : 365;
174
- }
175
- function dayOfYear(year, month, day) {
176
- let doy = CUMULATIVE_DAYS_BY_MONTH[month - 1] + day;
177
- if (month > 2 && isGregorianLeapYear(year)) doy += 1;
178
- return doy;
179
- }
180
- var REFERENCE_YEAR = 2e3;
181
- function dayOfWeekOfJan1(year) {
182
- let offset = 0;
183
- if (year >= REFERENCE_YEAR) {
184
- for (let y = REFERENCE_YEAR; y < year; y++) offset += daysInYear(y);
185
- } else {
186
- for (let y = year; y < REFERENCE_YEAR; y++) offset -= daysInYear(y);
187
- }
188
- const zeroIndexed = ((6 - 1 + offset) % 7 + 7) % 7;
189
- return zeroIndexed + 1;
190
- }
191
- function isoWeekYearAndWeek(year, month, day, dayOfWeek) {
192
- const doy = dayOfYear(year, month, day);
193
- const thursdayDoyRelative = doy + (4 - dayOfWeek);
194
- let isoYear;
195
- let thursdayDoy;
196
- if (thursdayDoyRelative < 1) {
197
- isoYear = year - 1;
198
- thursdayDoy = thursdayDoyRelative + daysInYear(isoYear);
199
- } else if (thursdayDoyRelative > daysInYear(year)) {
200
- isoYear = year + 1;
201
- thursdayDoy = thursdayDoyRelative - daysInYear(year);
202
- } else {
203
- isoYear = year;
204
- thursdayDoy = thursdayDoyRelative;
205
- }
206
- const jan1Dow = dayOfWeekOfJan1(isoYear);
207
- const firstThursdayDoy = 1 + (4 - jan1Dow + 7) % 7;
208
- const week = 1 + Math.floor((thursdayDoy - firstThursdayDoy) / 7);
209
- return { isoYear, week };
210
- }
211
-
212
- // src/tokens.ts
213
- function pad(n, len) {
214
- const negative = n < 0;
215
- const digits = String(Math.abs(n)).padStart(len, "0");
216
- return negative ? "-" + digits : digits;
217
- }
218
- pad.fraction = function formatFraction(t, width) {
219
- const nanoOfSecond = t.millisecond * 1e6 + (t.microsecond ?? 0) * 1e3 + (t.nanosecond ?? 0);
220
- return pad(nanoOfSecond, 9).slice(0, width);
221
- };
222
- var DEFAULT_LOCALE = "en-US";
223
- var formatterCache = /* @__PURE__ */ new Map();
224
- var MAX_CACHE_SIZE = 500;
225
- function getFormatter(locale, options) {
226
- const key = JSON.stringify([canonicalCacheKey(locale), options]);
227
- let formatter = formatterCache.get(key);
228
- if (formatter) {
229
- return formatter;
230
- }
231
- if (formatterCache.size >= MAX_CACHE_SIZE) {
232
- const oldestKey = formatterCache.keys().next().value;
233
- if (oldestKey !== void 0) formatterCache.delete(oldestKey);
234
- }
235
- formatter = new Intl.DateTimeFormat(locale, options);
236
- formatterCache.set(key, formatter);
237
- return formatter;
238
- }
239
- var nativeSupport;
240
- subscribeToTemporalChanges(() => {
241
- nativeSupport = void 0;
242
- });
243
- function intlSupportsNativeTemporal() {
244
- if (nativeSupport === void 0) {
245
- nativeSupport = false;
246
- try {
247
- const temporal = getTemporal();
248
- new Intl.DateTimeFormat("en-US", { day: "numeric" }).formatToParts(temporal.PlainDate.from({ year: 1970, month: 1, day: 1 }));
249
- nativeSupport = true;
250
- } catch {
251
- }
252
- }
253
- return nativeSupport;
254
- }
255
- function intlPart(temporal, locale, options, partType) {
256
- const calendar = temporal?.calendarId;
257
- const formatterOptions = {
258
- ...options,
259
- calendar: calendar && calendar !== "iso8601" ? calendar : "gregory"
260
- };
261
- if (!intlSupportsNativeTemporal()) {
262
- return temporal.toLocaleString(locale, formatterOptions);
263
- }
264
- const { toInstant, timeZoneId } = temporal;
265
- const isZoned = typeof toInstant === "function" && typeof timeZoneId === "string";
266
- const intlSafeTemporal = isZoned ? temporal.toInstant() : temporal;
267
- const nativeOptions = {
268
- ...formatterOptions,
269
- ...isZoned ? { timeZone: timeZoneId } : {}
270
- };
271
- const formatter = getFormatter(locale, nativeOptions);
272
- const parts = formatter.formatToParts(intlSafeTemporal);
273
- const index = parts.findIndex((p) => p.type === partType);
274
- if (index === -1) {
275
- throw new Error(
276
- `temporal-fmt: locale "${locale}" produced no "${partType}" part for this token. This usually means the Temporal object is missing the field the token needs.`
277
- );
278
- }
279
- let value = parts[index].value;
280
- const prev = parts[index - 1];
281
- const next = parts[index + 1];
282
- if (prev?.type === "literal" && !/\s/.test(prev.value)) value = prev.value + value;
283
- if (next?.type === "literal" && !/\s/.test(next.value)) value = value + next.value;
284
- return value;
285
- }
286
- function dayPeriodPart(hour, locale) {
287
- const custom = getCustomVocab(locale);
288
- if (custom) {
289
- return hour < 12 ? custom.dayPeriod[0] : custom.dayPeriod[1];
290
- }
291
- const date = new Date(Date.UTC(1970, 0, 1, hour));
292
- const formatter = getFormatter(locale, { hour: "numeric", hour12: true, timeZone: "UTC" });
293
- const part = formatter.formatToParts(date).find((p) => p.type === "dayPeriod");
294
- if (!part) {
295
- throw new Error(`temporal-fmt: locale "${locale}" produced no "dayPeriod" part for token "a".`);
296
- }
297
- return part.value;
298
- }
299
- function localeAwareName(temporal, locale, options, partType, customArray, customIndex) {
300
- if (customArray && customIndex !== void 0 && customIndex >= 0 && customIndex < customArray.length) {
301
- return customArray[customIndex];
302
- }
303
- return intlPart(temporal, locale, options, partType);
304
- }
305
- function formatOffset(offset, variant) {
306
- if (offset === "+00:00" && (variant === "X" || variant === "XX" || variant === "XXX")) {
307
- return "Z";
308
- }
309
- const sign = offset[0];
310
- const hours = offset.slice(1, 3);
311
- const minutes = offset.slice(4, 6);
312
- switch (variant) {
313
- case "X":
314
- case "x":
315
- return minutes === "00" ? `${sign}${hours}` : `${sign}${hours}${minutes}`;
316
- case "XX":
317
- case "xx":
318
- return `${sign}${hours}${minutes}`;
319
- case "XXX":
320
- case "xxx":
321
- return `${sign}${hours}:${minutes}`;
322
- }
323
- }
324
- var TOKENS = [
325
- ["yyyy", (t) => pad(t.year, 4), "year"],
326
- ["yy", (t) => {
327
- if (t.year < 0) {
328
- throw new Error(
329
- `temporal-fmt: token "yy" doesn't support negative years (got ${t.year}), since truncating to 2 digits would make it indistinguishable from a positive year. Use "yyyy" instead.`
330
- );
331
- }
332
- return pad(t.year % 100, 2);
333
- }, "year"],
334
- ["MMMM", (t, locale) => {
335
- const custom = getCustomVocab(locale);
336
- return localeAwareName(t, locale, { month: "long" }, "month", custom?.monthLong, t.month - 1);
337
- }, "month"],
338
- ["MMM", (t, locale) => {
339
- const custom = getCustomVocab(locale);
340
- return localeAwareName(t, locale, { month: "short" }, "month", custom?.monthShort, t.month - 1);
341
- }, "month"],
342
- ["MM", (t) => pad(t.month, 2), "month"],
343
- ["M", (t) => String(t.month), "month"],
344
- ["dd", (t) => pad(t.day, 2), "day"],
345
- ["d", (t) => String(t.day), "day"],
346
- ["EEEE", (t, locale) => {
347
- const custom = getCustomVocab(locale);
348
- return localeAwareName(t, locale, { weekday: "long" }, "weekday", custom?.weekdayLong, t.dayOfWeek - 1);
349
- }, "dayOfWeek"],
350
- ["EEE", (t, locale) => {
351
- const custom = getCustomVocab(locale);
352
- return localeAwareName(t, locale, { weekday: "short" }, "weekday", custom?.weekdayShort, t.dayOfWeek - 1);
353
- }, "dayOfWeek"],
354
- ["HH", (t) => pad(t.hour, 2), "hour"],
355
- ["H", (t) => String(t.hour), "hour"],
356
- ["hh", (t) => pad(t.hour % 12 || 12, 2), "hour"],
357
- ["h", (t) => String(t.hour % 12 || 12), "hour"],
358
- ["mm", (t) => pad(t.minute, 2), "minute"],
359
- ["m", (t) => String(t.minute), "minute"],
360
- ["ss", (t) => pad(t.second, 2), "second"],
361
- ["s", (t) => String(t.second), "second"],
362
- // Fractional-second tokens, S through SSSSSSSSS (1-9 digits). Each token
363
- // formats a slice of the same underlying nanosecond-of-second value —
364
- // combining millisecond/microsecond/nanosecond into one 9-digit number
365
- // and truncating to the token's width — so "SSS" keeps meaning exactly
366
- // what it always meant (3-digit milliseconds) while wider tokens expose
367
- // the precision Temporal actually carries. formatFraction below is the
368
- // shared implementation; see its comment for the truncate-not-round
369
- // rule and why.
370
- ["SSSSSSSSS", (t) => pad.fraction(t, 9), "millisecond"],
371
- ["SSSSSSSS", (t) => pad.fraction(t, 8), "millisecond"],
372
- ["SSSSSSS", (t) => pad.fraction(t, 7), "millisecond"],
373
- ["SSSSSS", (t) => pad.fraction(t, 6), "millisecond"],
374
- ["SSSSS", (t) => pad.fraction(t, 5), "millisecond"],
375
- ["SSSS", (t) => pad.fraction(t, 4), "millisecond"],
376
- ["SSS", (t) => pad.fraction(t, 3), "millisecond"],
377
- ["SS", (t) => pad.fraction(t, 2), "millisecond"],
378
- ["S", (t) => pad.fraction(t, 1), "millisecond"],
379
- // dayPeriod text is locale-specific (AM/PM in en-US, م/ص in ar-EG) but
380
- // still needs .hour on the input to compute which period it is
381
- ["a", (t, locale) => dayPeriodPart(t.hour, locale), "hour"],
382
- ["zzz", (t) => t.timeZoneId, "timeZoneId"],
383
- // Numeric UTC offset tokens (date-fns/Unicode-LDML family). Only
384
- // ZonedDateTime carries an offset, so the field check in format() throws
385
- // the same "requires offset, which this Temporal object doesn't have"
386
- // error zzz throws on PlainDate/PlainTime/PlainDateTime — same
387
- // validation path, just a different field name. See formatOffset above
388
- // for the per-variant width and Z/numeric distinction.
389
- ["xxx", (t) => formatOffset(t.offset, "xxx"), "offset"],
390
- ["xx", (t) => formatOffset(t.offset, "xx"), "offset"],
391
- ["X", (t) => formatOffset(t.offset, "X"), "offset"],
392
- ["XX", (t) => formatOffset(t.offset, "XX"), "offset"],
393
- ["XXX", (t) => formatOffset(t.offset, "XXX"), "offset"],
394
- ["x", (t) => formatOffset(t.offset, "x"), "offset"],
395
- // Ordinal day (1st, 2nd, 3rd, ... 21st). English suffix rules only —
396
- // locale-aware ordinals ("2." in de-DE, "2日" in ja-JP) are out of scope,
397
- // since the rest of this library routes locale-specific names through
398
- // Intl.DateTimeFormat, and Intl has no part type for ordinals. Format-only:
399
- // the suffix isn't structurally distinguishable from a literal in a parse
400
- // context (a "st"/"nd"/"rd"/"th" suffix isn't a digit and would collide
401
- // with any adjacent literal text), so there's no good way to read it back.
402
- ["do", (t) => {
403
- const day = t.day;
404
- const lastDigit = day % 10;
405
- const lastTwoDigits = day % 100;
406
- if (lastTwoDigits >= 11 && lastTwoDigits <= 13) {
407
- return day + "th";
408
- }
409
- if (lastDigit === 1) return day + "st";
410
- if (lastDigit === 2) return day + "nd";
411
- if (lastDigit === 3) return day + "rd";
412
- return day + "th";
413
- }, "day"],
414
- // Quarter computed from month: 1-3=Q1, 4-6=Q2, 7-9=Q3, 10-12=Q4.
415
- // `Q` is plain numeric, `QQQ` renders as "Q3" — same convention as
416
- // date-fns's `Q` and `QQQ` for parity with the most common prior art.
417
- // Both format and parse; parse() cross-checks Q/QQQ against the parsed
418
- // month in the same spirit as the EEEE-vs-date cross-check.
419
- ["Q", (t) => String(Math.ceil(t.month / 3)), "month"],
420
- ["QQQ", (t) => "Q" + Math.ceil(t.month / 3), "month"],
421
- // ISO 8601 week and week-numbering year. Both are format-only — parsing
422
- // "ww"/"RRRR" back into a real date requires resolving an ISO week + a
423
- // weekday (or some other disambiguator) to a specific date, which is a
424
- // different parsing surface than the token-based parse() here. The
425
- // ISO-week year (RRRR) can differ from the calendar year at the boundary:
426
- // Dec 29-31 often belong to week 1 of the *next* year; Jan 1-3 often
427
- // belong to week 52/53 of the *previous* year. See isoWeekYearAndWeek().
428
- ["ww", (t) => {
429
- const { week } = isoWeekYearAndWeek(t.year, t.month, t.day, t.dayOfWeek);
430
- return pad(week, 2);
431
- }, "dayOfWeek"],
432
- ["RRRR", (t) => {
433
- const { isoYear } = isoWeekYearAndWeek(t.year, t.month, t.day, t.dayOfWeek);
434
- return pad(isoYear, 4);
435
- }, "dayOfWeek"],
436
- // Day of year — number of days since Jan 1 (1-366). Three widths:
437
- // D — unpadded (1, 2, 366)
438
- // DD — 2-digit minimum (zero-padded if <100)
439
- // DDD — 3-digit zero-padded (001, 002, 366)
440
- // Format-only — parsing day-of-year requires resolving against a year,
441
- // which is a different shape from the token-based parse() surface.
442
- // The dayOfYearHelper() in calendarUtils.ts covers the same field for
443
- // callers who need the numeric value.
444
- ["D", (t) => String(dayOfYear(t.year, t.month, t.day)), "day"],
445
- ["DD", (t) => pad(dayOfYear(t.year, t.month, t.day), 2), "day"],
446
- ["DDD", (t) => pad(dayOfYear(t.year, t.month, t.day), 3), "day"],
447
- // Stand-alone month — uses Intl's stand-alone form. In most locales
448
- // (en, fr, de, es) this is identical to MMMM/MMM. In Slavic/Baltic
449
- // locales (cs, sk, pl, ru) the stand-alone form differs from the
450
- // format form (nominative vs genitive case). LLLL = long, LLL = short.
451
- ["LLLL", (t, locale) => {
452
- const custom = getCustomVocab(locale);
453
- return localeAwareName(t, locale, { month: "long" }, "month", custom?.monthLong, t.month - 1);
454
- }, "month"],
455
- ["LLL", (t, locale) => {
456
- const custom = getCustomVocab(locale);
457
- return localeAwareName(t, locale, { month: "short" }, "month", custom?.monthShort, t.month - 1);
458
- }, "month"],
459
- // Stand-alone weekday — same pattern as stand-alone month but for
460
- // weekday names. cccc = long, ccc = short.
461
- ["cccc", (t, locale) => {
462
- const custom = getCustomVocab(locale);
463
- return localeAwareName(t, locale, { weekday: "long" }, "weekday", custom?.weekdayLong, t.dayOfWeek - 1);
464
- }, "dayOfWeek"],
465
- ["ccc", (t, locale) => {
466
- const custom = getCustomVocab(locale);
467
- return localeAwareName(t, locale, { weekday: "short" }, "weekday", custom?.weekdayShort, t.dayOfWeek - 1);
468
- }, "dayOfWeek"],
469
- // Era — locale-aware ("AD"/"BC" in en, "ap. J.-C."/"av. J.-C." in fr).
470
- // GGGG = long, G = short. Format-only.
471
- ["GGGG", (t, locale) => {
472
- return intlPart(t, locale, { era: "long" }, "era");
473
- }, "year"],
474
- ["G", (t, locale) => {
475
- return intlPart(t, locale, { era: "short" }, "era");
476
- }, "year"],
477
- // Localized timezone name — uses Intl's longLocalized/short timezone
478
- // name option. Format-only — these names are locale-dependent and
479
- // vary by season (EST vs EDT), so parsing them back requires a
480
- // lookup table that isn't practical to ship.
481
- ["zzzz", (t, locale) => {
482
- return intlPart(t, locale, { timeZoneName: "longGeneric" }, "timeZoneName");
483
- }, "timeZoneId"],
484
- ["z", (t, locale) => {
485
- return intlPart(t, locale, { timeZoneName: "short" }, "timeZoneName");
486
- }, "timeZoneId"]
487
- ];
488
-
489
- // src/tokenize.ts
490
- var SORTED_TOKEN_STRINGS = TOKENS.map(([tok]) => tok).sort((a, b) => b.length - a.length);
491
- function tokenize(format2) {
492
- const pieces = [];
493
- let i = 0;
494
- while (i < format2.length) {
495
- const ch = format2[i];
496
- if (ch === "'") {
497
- if (format2[i + 1] === "'") {
498
- appendLiteral(pieces, "'");
499
- i += 2;
500
- continue;
501
- }
502
- let j = i + 1;
503
- let literal = "";
504
- let closed = false;
505
- while (j < format2.length) {
506
- if (format2[j] === "'") {
507
- if (format2[j + 1] === "'") {
508
- literal += "'";
509
- j += 2;
510
- continue;
511
- }
512
- closed = true;
513
- j += 1;
514
- break;
515
- }
516
- literal += format2[j];
517
- j += 1;
518
- }
519
- if (!closed) {
520
- throw new FormatSyntaxError({
521
- format: format2,
522
- message: `temporal-fmt: unterminated quote in format string "${format2}"`
523
- });
524
- }
525
- appendLiteral(pieces, literal);
526
- i = j;
527
- continue;
528
- }
529
- const match = SORTED_TOKEN_STRINGS.find((tok) => format2.startsWith(tok, i));
530
- if (match) {
531
- const runChar = match[match.length - 1];
532
- if (format2[i + match.length] === runChar) {
533
- let end = i + match.length;
534
- while (format2[end] === runChar) end += 1;
535
- throw new UnknownTokenError({
536
- format: format2,
537
- token: format2.slice(i, end),
538
- message: `temporal-fmt: "${format2.slice(i, end)}" in format string "${format2}" isn't a recognized token \u2014 did you mean "${match}"?`
539
- });
540
- }
541
- pieces.push({ kind: "token", value: match });
542
- i += match.length;
543
- continue;
544
- }
545
- appendLiteral(pieces, ch);
546
- i += 1;
547
- }
548
- return pieces;
549
- }
550
- function appendLiteral(pieces, value) {
551
- const last = pieces[pieces.length - 1];
552
- if (last && last.kind === "literal") {
553
- last.value += value;
554
- } else {
555
- pieces.push({ kind: "literal", value });
556
- }
557
- }
558
-
559
- // src/constants.ts
560
- var MAX_FORMAT_LENGTH = 1e3;
561
-
562
- // src/numbering.ts
563
- var SUPPORTED_NUMBERING_SYSTEMS = /* @__PURE__ */ new Set([
564
- "latn",
565
- "arab",
566
- "deva",
567
- "beng",
568
- "guru",
569
- "gujr",
570
- "orya",
571
- "tamldec",
572
- "telu",
573
- "knda",
574
- "mlym",
575
- "fullwide",
576
- "hanidec"
577
- ]);
578
- var digitMapCache = /* @__PURE__ */ new Map();
579
- function getDigitMap(system) {
580
- let map = digitMapCache.get(system);
581
- if (map) return map;
582
- /* c8 ignore start @preserve -- dead by construction, not just
583
- untested: both callers (convertDigits, convertDigitsToAscii) already
584
- return early on system === 'latn' before calling getDigitMap at all,
585
- so this function is never invoked with 'latn'. Kept as a defensive
586
- fallback rather than trusting that stays true for any future
587
- caller. */
588
- if (system === "latn") {
589
- map = {};
590
- for (let i = 0; i < 10; i++) map[String(i)] = String(i);
591
- } else {
592
- /* c8 ignore stop @preserve */
593
- const fmt = new Intl.NumberFormat("en-US-u-nu-" + system, { useGrouping: false });
594
- map = {};
595
- for (let i = 0; i < 10; i++) {
596
- map[String(i)] = fmt.format(i);
597
- }
598
- }
599
- digitMapCache.set(system, map);
600
- return map;
601
- }
602
- function convertDigits(s, system) {
603
- if (system === "latn") return s;
604
- if (!SUPPORTED_NUMBERING_SYSTEMS.has(system)) {
605
- throw new InvalidLocaleError({ actual: system, reason: `numbering system "${system}" is not supported. Supported: ${[...SUPPORTED_NUMBERING_SYSTEMS].join(", ")}.` });
606
- }
607
- const map = getDigitMap(system);
608
- let result = "";
609
- for (const ch of s) {
610
- if (ch >= "0" && ch <= "9") {
611
- result += map[ch] ?? ch;
612
- } else {
613
- result += ch;
614
- }
615
- }
616
- return result;
617
- }
618
- function applyNumbering(s, options) {
619
- const system = options.numberingSystem ?? "latn";
620
- if (system === "latn") return s;
621
- return convertDigits(s, system);
622
- }
623
-
624
- // src/format.ts
625
- var HANDLER_BY_TOKEN = new Map(TOKENS.map(([tok, fn, field]) => [tok, { fn, field }]));
626
- var tokenizeCache = /* @__PURE__ */ new Map();
627
- var MAX_TOKENIZE_CACHE_SIZE = 500;
628
- function getPieces(formatStr) {
629
- let pieces = tokenizeCache.get(formatStr);
630
- if (pieces) return pieces;
631
- if (tokenizeCache.size >= MAX_TOKENIZE_CACHE_SIZE) {
632
- const oldestKey = tokenizeCache.keys().next().value;
633
- if (oldestKey !== void 0) tokenizeCache.delete(oldestKey);
634
- }
635
- pieces = tokenize(formatStr);
636
- tokenizeCache.set(formatStr, pieces);
637
- return pieces;
638
- }
639
- function format(temporal, formatStr, options = {}) {
640
- if (formatStr.length > MAX_FORMAT_LENGTH) {
641
- throw new FormatSyntaxError({
642
- format: formatStr,
643
- message: `temporal-fmt: format string exceeds maximum length of ${MAX_FORMAT_LENGTH} characters (got ${formatStr.length}).`
644
- });
645
- }
646
- const locale = options.locale ?? DEFAULT_LOCALE;
647
- const pieces = getPieces(formatStr);
648
- let result = "";
649
- for (const piece of pieces) {
650
- if (piece.kind === "literal") {
651
- result += piece.value;
652
- continue;
653
- }
654
- const handler = HANDLER_BY_TOKEN.get(piece.value);
655
- /* c8 ignore start @preserve -- unreachable: tokenize() only ever emits
656
- tokens present in TOKENS, and HANDLER_BY_TOKEN is built from that
657
- same list, so every token piece.value can hold already has an entry
658
- here. Same defensive-guard category as the twin checks in
659
- analyze.ts/formatDuration.ts. */
660
- if (!handler) {
661
- throw new UnknownTokenError({ token: piece.value, format: formatStr, message: `temporal-fmt: unknown token "${piece.value}"` });
662
- }
663
- /* c8 ignore stop @preserve */
664
- if (temporal[handler.field] === void 0) {
665
- throw new FormatSyntaxError({
666
- format: formatStr,
667
- token: piece.value,
668
- message: `temporal-fmt: token "${piece.value}" requires "${handler.field}", which this Temporal object doesn't have. (e.g. PlainDate has no time fields, PlainTime has no date fields)`
669
- });
670
- }
671
- result += handler.fn(temporal, locale);
672
- }
673
- return applyNumbering(result, options);
674
- }
675
- function formatToParts(temporal, formatStr, options = {}) {
676
- if (formatStr.length > MAX_FORMAT_LENGTH) {
677
- throw new FormatSyntaxError({
678
- format: formatStr,
679
- message: `temporal-fmt: format string exceeds maximum length of ${MAX_FORMAT_LENGTH} characters (got ${formatStr.length}).`
680
- });
681
- }
682
- const locale = options.locale ?? DEFAULT_LOCALE;
683
- const pieces = getPieces(formatStr);
684
- const result = [];
685
- for (const piece of pieces) {
686
- if (piece.kind === "literal") {
687
- const last = result[result.length - 1];
688
- /* c8 ignore start @preserve -- unreachable through tokenize()'s own
689
- output: appendLiteral() in tokenize.ts already merges every
690
- adjacent literal character before pieces ever reaches here, so
691
- two 'literal' pieces never sit back-to-back in the array this
692
- loop walks. Kept as defense-in-depth in case that invariant ever
693
- changes upstream. */
694
- if (last && last.type === "literal") {
695
- last.value += piece.value;
696
- } else {
697
- /* c8 ignore stop @preserve */
698
- result.push({ type: "literal", value: piece.value });
699
- }
700
- continue;
701
- }
702
- const handler = HANDLER_BY_TOKEN.get(piece.value);
703
- /* c8 ignore start @preserve -- unreachable, see the note in format() above */
704
- if (!handler) {
705
- throw new UnknownTokenError({ token: piece.value, format: formatStr, message: `temporal-fmt: unknown token "${piece.value}"` });
706
- }
707
- /* c8 ignore stop @preserve */
708
- if (temporal[handler.field] === void 0) {
709
- throw new FormatSyntaxError({
710
- format: formatStr,
711
- token: piece.value,
712
- message: `temporal-fmt: token "${piece.value}" requires "${handler.field}", which this Temporal object doesn't have. (e.g. PlainDate has no time fields, PlainTime has no date fields)`
713
- });
714
- }
715
- result.push({ type: "token", value: applyNumbering(handler.fn(temporal, locale), options), token: piece.value });
716
- }
717
- return result;
718
- }
719
- function compileFormat(formatStr) {
720
- if (formatStr.length > MAX_FORMAT_LENGTH) {
721
- throw new FormatSyntaxError({
722
- format: formatStr,
723
- message: `temporal-fmt: format string exceeds maximum length of ${MAX_FORMAT_LENGTH} characters (got ${formatStr.length}).`
724
- });
725
- }
726
- const pieces = getPieces(formatStr);
727
- return {
728
- formatStr,
729
- pieces,
730
- format(temporal, options = {}) {
731
- const locale = options.locale ?? DEFAULT_LOCALE;
732
- let result = "";
733
- for (const piece of pieces) {
734
- if (piece.kind === "literal") {
735
- result += piece.value;
736
- continue;
737
- }
738
- const handler = HANDLER_BY_TOKEN.get(piece.value);
739
- if (!handler) throw new UnknownTokenError({ token: piece.value, format: formatStr, message: `temporal-fmt: unknown token "${piece.value}"` });
740
- if (temporal[handler.field] === void 0) {
741
- throw new FormatSyntaxError({
742
- format: formatStr,
743
- token: piece.value,
744
- message: `temporal-fmt: token "${piece.value}" requires "${handler.field}", which this Temporal object doesn't have. (e.g. PlainDate has no time fields, PlainTime has no date fields)`
745
- });
746
- }
747
- result += handler.fn(temporal, locale);
748
- }
749
- return applyNumbering(result, options);
750
- },
751
- formatToParts(temporal, options = {}) {
752
- const locale = options.locale ?? DEFAULT_LOCALE;
753
- const out = [];
754
- for (const piece of pieces) {
755
- if (piece.kind === "literal") {
756
- const last = out[out.length - 1];
757
- if (last && last.type === "literal") last.value += piece.value;
758
- else out.push({ type: "literal", value: piece.value });
759
- continue;
760
- }
761
- const handler = HANDLER_BY_TOKEN.get(piece.value);
762
- if (!handler) throw new UnknownTokenError({ token: piece.value, format: formatStr, message: `temporal-fmt: unknown token "${piece.value}"` });
763
- if (temporal[handler.field] === void 0) {
764
- throw new FormatSyntaxError({
765
- format: formatStr,
766
- token: piece.value,
767
- message: `temporal-fmt: token "${piece.value}" requires "${handler.field}", which this Temporal object doesn't have. (e.g. PlainDate has no time fields, PlainTime has no date fields)`
768
- });
769
- }
770
- out.push({ type: "token", value: applyNumbering(handler.fn(temporal, locale), options), token: piece.value });
771
- }
772
- return out;
773
- }
774
- };
775
- }
776
- function _getPieces(formatStr) {
777
- return getPieces(formatStr);
778
- }
779
- function _handlerFor(token) {
780
- return HANDLER_BY_TOKEN.get(token);
781
- }
782
- // Annotate the CommonJS export names for ESM import in node:
783
- 0 && (module.exports = {
784
- _getPieces,
785
- _handlerFor,
786
- compileFormat,
787
- format,
788
- formatToParts
789
- });
23
+ parameter that could be invalid. *//* c8 ignore stop @preserve */var g=class extends w{constructor(t){let{message:n,...o}=t;super(n??`locale "${t.actual??""}" is not a valid BCP-47 tag${t.reason?`: ${t.reason}`:""}.`,{code:"INVALID_LOCALE",...o}),this.name="InvalidLocaleError"}};/* c8 ignore start @preserve -- unreachable from the current test suite,
24
+ see rationale above *//* c8 ignore stop @preserve */var se=new Map;function R(e){return e.replace(/_/g,"-")}var T=new Map,me=500;function X(e){let t=T.get(e);if(t!==void 0)return t;let n;try{n=new Intl.Locale(e.replace(/_/g,"-")).toString().toLowerCase()}catch{n=e}if(T.size>=me){let o=T.keys().next().value;o!==void 0&&T.delete(o)}return T.set(e,n),n}function u(e){let t=X(e);return se.get(t)}var ce=[0,31,59,90,120,151,181,212,243,273,304,334];function Y(e){return e%4===0&&e%100!==0||e%400===0}function k(e){return Y(e)?366:365}function E(e,t,n){let o=ce[t-1]+n;return t>2&&Y(e)&&(o+=1),o}var U=2e3;function le(e){let t=0;if(e>=U)for(let o=U;o<e;o++)t+=k(o);else for(let o=e;o<U;o++)t-=k(o);return((5+t)%7+7)%7+1}function Z(e,t,n,o){let a=E(e,t,n)+(4-o),r,s;a<1?(r=e-1,s=a+k(r)):a>k(e)?(r=e+1,s=a-k(e)):(r=e,s=a);let I=1+(4-le(r)+7)%7,M=1+Math.floor((s-I)/7);return{isoYear:r,week:M}}function m(e,t){let n=e<0,o=String(Math.abs(e)).padStart(t,"0");return n?"-"+o:o}m.fraction=function(t,n){let o=t.millisecond*1e6+(t.microsecond??0)*1e3+(t.nanosecond??0);return m(o,9).slice(0,n)};var S="en-US",b=new Map,ue=500;function j(e,t){let n=JSON.stringify([X(e),t]),o=b.get(n);if(o)return o;if(b.size>=ue){let i=b.keys().next().value;i!==void 0&&b.delete(i)}try{o=new Intl.DateTimeFormat(R(e),t)}catch(i){throw new g({actual:e,reason:i.message})}return b.set(n,o),o}var L;W(()=>{L=void 0});function de(){if(L===void 0){L=!1;try{let e=K();new Intl.DateTimeFormat("en-US",{day:"numeric"}).formatToParts(e.PlainDate.from({year:1970,month:1,day:1})),L=!0}catch{}}return L}function F(e,t,n,o){let i=e?.calendarId,a={...n,calendar:i&&i!=="iso8601"?i:"gregory"},r=e.toLocaleString;if(typeof r!="function"||r===Object.prototype.toLocaleString)throw new Error(`temporal-fmt: locale-aware part "${o}" needs a value that implements toLocaleString (a real Temporal object). A plain field bag cannot render locale-aware names \u2014 pass a Temporal.PlainDate/PlainDateTime/ZonedDateTime.`);if(!de())try{return r.call(e,R(t),a)}catch(y){throw y instanceof RangeError?new g({actual:t,reason:y.message}):y}let{toInstant:s,timeZoneId:l}=e,I=typeof s=="function"&&typeof l=="string",M=I?e.toInstant():e,B={...a,...I?{timeZone:l}:{}},v=j(t,B).formatToParts(M),N=v.findIndex(y=>y.type===o);if(N===-1)throw new Error(`temporal-fmt: locale "${t}" produced no "${o}" part for this token. This usually means the Temporal object is missing the field the token needs.`);let h=v[N].value,_=v[N-1],C=v[N+1];return _?.type==="literal"&&!/\s/.test(_.value)&&(h=_.value+h),C?.type==="literal"&&!/\s/.test(C.value)&&(h=h+C.value),h}function pe(e,t){let n=u(t);if(n)return e<12?n.dayPeriod[0]:n.dayPeriod[1];let o=new Date(Date.UTC(1970,0,1,e)),a=j(t,{hour:"numeric",hour12:!0,timeZone:"UTC"}).formatToParts(o).find(r=>r.type==="dayPeriod");if(!a)throw new Error(`temporal-fmt: locale "${t}" produced no "dayPeriod" part for token "a".`);return a.value}function p(e,t,n,o,i,a){return i&&a!==void 0&&a>=0&&a<i.length?i[a]:F(e,t,n,o)}function f(e,t){if(e==="+00:00"&&(t==="X"||t==="XX"||t==="XXX"))return"Z";let n=e[0],o=e.slice(1,3),i=e.slice(4,6);switch(t){case"X":case"x":return i==="00"?`${n}${o}`:`${n}${o}${i}`;case"XX":case"xx":return`${n}${o}${i}`;case"XXX":case"xxx":return`${n}${o}:${i}`}}var A=[["yyyy",e=>m(e.year,4),"year"],["yy",e=>{if(e.year<0)throw new Error(`temporal-fmt: token "yy" doesn't support negative years (got ${e.year}), since truncating to 2 digits would make it indistinguishable from a positive year. Use "yyyy" instead.`);return m(e.year%100,2)},"year"],["MMMM",(e,t)=>{let n=u(t);return p(e,t,{month:"long"},"month",n?.monthLong,e.month-1)},"month"],["MMM",(e,t)=>{let n=u(t);return p(e,t,{month:"short"},"month",n?.monthShort,e.month-1)},"month"],["MM",e=>m(e.month,2),"month"],["M",e=>String(e.month),"month"],["dd",e=>m(e.day,2),"day"],["d",e=>String(e.day),"day"],["EEEE",(e,t)=>{let n=u(t);return p(e,t,{weekday:"long"},"weekday",n?.weekdayLong,e.dayOfWeek-1)},"dayOfWeek"],["EEE",(e,t)=>{let n=u(t);return p(e,t,{weekday:"short"},"weekday",n?.weekdayShort,e.dayOfWeek-1)},"dayOfWeek"],["HH",e=>m(e.hour,2),"hour"],["H",e=>String(e.hour),"hour"],["hh",e=>m(e.hour%12||12,2),"hour"],["h",e=>String(e.hour%12||12),"hour"],["mm",e=>m(e.minute,2),"minute"],["m",e=>String(e.minute),"minute"],["ss",e=>m(e.second,2),"second"],["s",e=>String(e.second),"second"],["SSSSSSSSS",e=>m.fraction(e,9),"millisecond"],["SSSSSSSS",e=>m.fraction(e,8),"millisecond"],["SSSSSSS",e=>m.fraction(e,7),"millisecond"],["SSSSSS",e=>m.fraction(e,6),"millisecond"],["SSSSS",e=>m.fraction(e,5),"millisecond"],["SSSS",e=>m.fraction(e,4),"millisecond"],["SSS",e=>m.fraction(e,3),"millisecond"],["SS",e=>m.fraction(e,2),"millisecond"],["S",e=>m.fraction(e,1),"millisecond"],["a",(e,t)=>pe(e.hour,t),"hour"],["zzz",e=>e.timeZoneId,"timeZoneId"],["xxx",e=>f(e.offset,"xxx"),"offset"],["xx",e=>f(e.offset,"xx"),"offset"],["X",e=>f(e.offset,"X"),"offset"],["XX",e=>f(e.offset,"XX"),"offset"],["XXX",e=>f(e.offset,"XXX"),"offset"],["x",e=>f(e.offset,"x"),"offset"],["do",e=>{let t=e.day,n=t%10,o=t%100;return o>=11&&o<=13?t+"th":n===1?t+"st":n===2?t+"nd":n===3?t+"rd":t+"th"},"day"],["Q",e=>String(Math.ceil(e.month/3)),"month"],["QQQ",e=>"Q"+Math.ceil(e.month/3),"month"],["ww",e=>{let{week:t}=Z(e.year,e.month,e.day,e.dayOfWeek);return m(t,2)},"dayOfWeek"],["RRRR",e=>{let{isoYear:t}=Z(e.year,e.month,e.day,e.dayOfWeek);return m(t,4)},"dayOfWeek"],["D",e=>String(E(e.year,e.month,e.day)),"day"],["DD",e=>m(E(e.year,e.month,e.day),2),"day"],["DDD",e=>m(E(e.year,e.month,e.day),3),"day"],["LLLL",(e,t)=>{let n=u(t);return p(e,t,{month:"long"},"month",n?.monthLong,e.month-1)},"month"],["LLL",(e,t)=>{let n=u(t);return p(e,t,{month:"short"},"month",n?.monthShort,e.month-1)},"month"],["cccc",(e,t)=>{let n=u(t);return p(e,t,{weekday:"long"},"weekday",n?.weekdayLong,e.dayOfWeek-1)},"dayOfWeek"],["ccc",(e,t)=>{let n=u(t);return p(e,t,{weekday:"short"},"weekday",n?.weekdayShort,e.dayOfWeek-1)},"dayOfWeek"],["GGGG",(e,t)=>F(e,t,{era:"long"},"era"),"year"],["G",(e,t)=>F(e,t,{era:"short"},"era"),"year"],["zzzz",(e,t)=>F(e,t,{timeZoneName:"longGeneric"},"timeZoneName"),"timeZoneId"],["z",(e,t)=>F(e,t,{timeZoneName:"short"},"timeZoneName"),"timeZoneId"]];var ge=A.map(([e])=>e).sort((e,t)=>t.length-e.length);function H(e){let t=[],n=0;for(;n<e.length;){let o=e[n];if(o==="'"){if(e[n+1]==="'"){z(t,"'"),n+=2;continue}let a=n+1,r="",s=!1;for(;a<e.length;){if(e[a]==="'"){if(e[a+1]==="'"){r+="'",a+=2;continue}s=!0,a+=1;break}r+=e[a],a+=1}if(!s)throw new c({format:e,message:`temporal-fmt: unterminated quote in format string "${e}"`});z(t,r),n=a;continue}let i=ge.find(a=>e.startsWith(a,n));if(i){let a=i[i.length-1];if(e[n+i.length]===a){let r=n+i.length;for(;e[r]===a;)r+=1;throw new d({format:e,token:e.slice(n,r),message:`temporal-fmt: "${e.slice(n,r)}" in format string "${e}" isn't a recognized token \u2014 did you mean "${i}"?`})}t.push({kind:"token",value:i}),n+=i.length;continue}z(t,o),n+=1}return t}function z(e,t){let n=e[e.length-1];n&&n.kind==="literal"?n.value+=t:e.push({kind:"literal",value:t})}var G=new Set(["latn","arab","deva","beng","guru","gujr","orya","tamldec","telu","knda","mlym","fullwide","hanidec"]),q=new Map;function fe(e){let t=q.get(e);if(t)return t;/* c8 ignore start @preserve -- dead by construction, not just
25
+ untested: both callers (convertDigits, convertDigitsToAscii) already
26
+ return early on system === 'latn' before calling getDigitMap at all,
27
+ so this function is never invoked with 'latn'. Kept as a defensive
28
+ fallback rather than trusting that stays true for any future
29
+ caller. */if(e==="latn"){t={};for(let n=0;n<10;n++)t[String(n)]=String(n)}else{/* c8 ignore stop @preserve */let n=new Intl.NumberFormat("en-US-u-nu-"+e,{useGrouping:!1});t={};for(let o=0;o<10;o++)t[String(o)]=n.format(o)}return q.set(e,t),t}function he(e,t){if(t==="latn")return e;if(!G.has(t))throw new g({actual:t,reason:`numbering system "${t}" is not supported. Supported: ${[...G].join(", ")}.`});let n=fe(t),o="";for(let i of e)i>="0"&&i<="9"?o+=n[i]??i:o+=i;return o}function x(e,t){let n=t.numberingSystem??"latn";return n==="latn"?e:he(e,n)}var O=new Map(A.map(([e,t,n])=>[e,{fn:t,field:n}])),$=new Map,ye=500;function P(e){let t=$.get(e);if(t)return t;if($.size>=ye){let n=$.keys().next().value;n!==void 0&&$.delete(n)}return t=H(e),$.set(e,t),t}function we(e,t,n={}){if(t.length>1e3)throw new c({format:t,message:`temporal-fmt: format string exceeds maximum length of ${1e3} characters (got ${t.length}).`});let o=n.locale??S,i=P(t),a="";for(let r of i){if(r.kind==="literal"){a+=r.value;continue}let s=O.get(r.value);/* c8 ignore start @preserve -- unreachable: tokenize() only ever emits
30
+ tokens present in TOKENS, and HANDLER_BY_TOKEN is built from that
31
+ same list, so every token piece.value can hold already has an entry
32
+ here. Same defensive-guard category as the twin checks in
33
+ analyze.ts/formatDuration.ts. */if(!s)throw new d({token:r.value,format:t,message:`temporal-fmt: unknown token "${r.value}"`});/* c8 ignore stop @preserve */if(e[s.field]===void 0)throw new c({format:t,token:r.value,message:`temporal-fmt: token "${r.value}" requires "${s.field}", which this Temporal object doesn't have. (e.g. PlainDate has no time fields, PlainTime has no date fields)`});a+=s.fn(e,o)}return x(a,n)}function Te(e,t,n={}){if(t.length>1e3)throw new c({format:t,message:`temporal-fmt: format string exceeds maximum length of ${1e3} characters (got ${t.length}).`});let o=n.locale??S,i=P(t),a=[];for(let r of i){if(r.kind==="literal"){let l=a[a.length-1];/* c8 ignore start @preserve -- unreachable through tokenize()'s own
34
+ output: appendLiteral() in tokenize.ts already merges every
35
+ adjacent literal character before pieces ever reaches here, so
36
+ two 'literal' pieces never sit back-to-back in the array this
37
+ loop walks. Kept as defense-in-depth in case that invariant ever
38
+ changes upstream. */if(l&&l.type==="literal")l.value+=r.value;else{/* c8 ignore stop @preserve */a.push({type:"literal",value:r.value})}continue}let s=O.get(r.value);/* c8 ignore start @preserve -- unreachable, see the note in format() above */if(!s)throw new d({token:r.value,format:t,message:`temporal-fmt: unknown token "${r.value}"`});/* c8 ignore stop @preserve */if(e[s.field]===void 0)throw new c({format:t,token:r.value,message:`temporal-fmt: token "${r.value}" requires "${s.field}", which this Temporal object doesn't have. (e.g. PlainDate has no time fields, PlainTime has no date fields)`});a.push({type:"token",value:x(s.fn(e,o),n),token:r.value})}return a}function ke(e){if(e.length>1e3)throw new c({format:e,message:`temporal-fmt: format string exceeds maximum length of ${1e3} characters (got ${e.length}).`});let t=P(e);return{formatStr:e,pieces:t,format(n,o={}){let i=o.locale??S,a="";for(let r of t){if(r.kind==="literal"){a+=r.value;continue}let s=O.get(r.value);if(!s)throw new d({token:r.value,format:e,message:`temporal-fmt: unknown token "${r.value}"`});if(n[s.field]===void 0)throw new c({format:e,token:r.value,message:`temporal-fmt: token "${r.value}" requires "${s.field}", which this Temporal object doesn't have. (e.g. PlainDate has no time fields, PlainTime has no date fields)`});a+=s.fn(n,i)}return x(a,o)},formatToParts(n,o={}){let i=o.locale??S,a=[];for(let r of t){if(r.kind==="literal"){let l=a[a.length-1];l&&l.type==="literal"?l.value+=r.value:a.push({type:"literal",value:r.value});continue}let s=O.get(r.value);if(!s)throw new d({token:r.value,format:e,message:`temporal-fmt: unknown token "${r.value}"`});if(n[s.field]===void 0)throw new c({format:e,token:r.value,message:`temporal-fmt: token "${r.value}" requires "${s.field}", which this Temporal object doesn't have. (e.g. PlainDate has no time fields, PlainTime has no date fields)`});a.push({type:"token",value:x(s.fn(n,i),o),token:r.value})}return a}}}function Ee(e){return P(e)}function be(e){return O.get(e)}0&&(module.exports={_getPieces,_handlerFor,compileFormat,format,formatToParts});
790
39
  //# sourceMappingURL=format.cjs.map