@hebcal/core 6.14.2 → 6.14.4

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 (52) hide show
  1. package/dist/bundle.js +564 -504
  2. package/dist/bundle.js.map +1 -1
  3. package/dist/bundle.min.js +6 -6
  4. package/dist/bundle.min.js.map +1 -1
  5. package/dist/esm/DailyLearning.js +1 -1
  6. package/dist/esm/HebrewDateEvent.js +1 -1
  7. package/dist/esm/HolidayEvent.js +1 -1
  8. package/dist/esm/KiddushLevanaEvent.js +1 -1
  9. package/dist/esm/MevarchimChodeshEvent.js +1 -1
  10. package/dist/esm/ParshaEvent.js +1 -1
  11. package/dist/esm/TimedEvent.js +1 -1
  12. package/dist/esm/YomKippurKatanEvent.js +1 -1
  13. package/dist/esm/ashkenazi.po.js +1 -1
  14. package/dist/esm/calendar.d.ts +10 -0
  15. package/dist/esm/calendar.js +57 -24
  16. package/dist/esm/calendar.js.map +1 -1
  17. package/dist/esm/candles.js +1 -1
  18. package/dist/esm/cities.json.js +1 -1
  19. package/dist/esm/event.js +1 -1
  20. package/dist/esm/getStartAndEnd.js +1 -1
  21. package/dist/esm/hallel.js +1 -1
  22. package/dist/esm/he-x-NoNikud.po.js +1 -1
  23. package/dist/esm/he.po.js +1 -1
  24. package/dist/esm/hebcal.js +1 -1
  25. package/dist/esm/holidays.d.ts +37 -0
  26. package/dist/esm/holidays.js +76 -8
  27. package/dist/esm/holidays.js.map +1 -1
  28. package/dist/esm/index.js +1 -1
  29. package/dist/esm/isAssurBemlacha.js +1 -1
  30. package/dist/esm/isAveilut.js +1 -1
  31. package/dist/esm/isFastDay.js +1 -1
  32. package/dist/esm/locale.js +1 -1
  33. package/dist/esm/location.js +1 -1
  34. package/dist/esm/modern.js +1 -1
  35. package/dist/esm/molad.js +1 -1
  36. package/dist/esm/moladBase.js +1 -1
  37. package/dist/esm/moladDate.js +1 -1
  38. package/dist/esm/omer.js +1 -1
  39. package/dist/esm/parshaName.js +1 -1
  40. package/dist/esm/parshaYear.js +1 -1
  41. package/dist/esm/pkgVersion.d.ts +1 -1
  42. package/dist/esm/pkgVersion.js +2 -2
  43. package/dist/esm/pkgVersion.js.map +1 -1
  44. package/dist/esm/reformatTimeStr.js +1 -1
  45. package/dist/esm/sedra.js +1 -1
  46. package/dist/esm/sefira.json.js +1 -1
  47. package/dist/esm/staticHolidays.js +1 -1
  48. package/dist/esm/string.js +1 -1
  49. package/dist/esm/tachanun.js +1 -1
  50. package/dist/esm/zenith.js +1 -1
  51. package/dist/esm/zmanim.js +1 -1
  52. package/package.json +6 -6
package/dist/bundle.js CHANGED
@@ -1,9 +1,9 @@
1
- /*! @hebcal/core v6.14.2, distributed under GPLv2 or later https://www.gnu.org/licenses/gpl-2.0.txt */
1
+ /*! @hebcal/core v6.14.4, distributed under GPLv2 or later https://www.gnu.org/licenses/gpl-2.0.txt */
2
2
  var hebcal = (function (exports) {
3
3
  'use strict';
4
4
 
5
5
  /** DO NOT EDIT THIS AUTO-GENERATED FILE! */
6
- const version = '6.14.2';
6
+ const version = '6.14.4';
7
7
 
8
8
  /*! @hebcal/hdate v0.23.1, distributed under GPLv2 or later https://www.gnu.org/licenses/gpl-2.0.txt */
9
9
  /**
@@ -2961,259 +2961,6 @@ function requireObjectLike(arg) {
2961
2961
  return arg;
2962
2962
  }
2963
2963
 
2964
- function normalizeOptionsOrString(options, optionName) {
2965
- return "string" == typeof options ? ((optionName, optionVal) => {
2966
- const res = Object.create(null);
2967
- return res[optionName] = optionVal, res;
2968
- })(optionName, options) : requireObjectLike(options);
2969
- }
2970
-
2971
- const smallestUnitStr = "smallestUnit";
2972
-
2973
- const overflowMap = {
2974
- constrain: 0,
2975
- reject: 1
2976
- };
2977
-
2978
- const epochDisambigMap = {
2979
- compatible: 0,
2980
- reject: 1,
2981
- earlier: 2,
2982
- later: 3
2983
- };
2984
-
2985
- const offsetDisambigMap = {
2986
- reject: 0,
2987
- use: 1,
2988
- prefer: 2,
2989
- ignore: 3
2990
- };
2991
-
2992
- const calendarDisplayMap = {
2993
- auto: 0,
2994
- never: 1,
2995
- critical: 2,
2996
- always: 3
2997
- };
2998
-
2999
- const timeZoneDisplayMap = {
3000
- auto: 0,
3001
- never: 1,
3002
- critical: 2
3003
- };
3004
-
3005
- const offsetDisplayMap = {
3006
- auto: 0,
3007
- never: 1
3008
- };
3009
-
3010
- const roundingModeMap = {
3011
- floor: 0,
3012
- halfFloor: 1,
3013
- ceil: 2,
3014
- halfCeil: 3,
3015
- trunc: 4,
3016
- halfTrunc: 5,
3017
- expand: 6,
3018
- halfExpand: 7,
3019
- halfEven: 8
3020
- };
3021
-
3022
- const roundingModeFuncs = [ Math.floor, roundHalfFloor, Math.ceil, roundHalfCeil, Math.trunc, roundHalfTrunc, roundExpand, roundHalfExpand, roundHalfEven ];
3023
-
3024
- const directionMap = {
3025
- previous: -1,
3026
- next: 1
3027
- };
3028
-
3029
- function coerceRoundingIncInteger(options) {
3030
- const roundingInc = options.roundingIncrement;
3031
- return void 0 === roundingInc ? 1 : toIntegerWithTrunc(roundingInc, "roundingIncrement");
3032
- }
3033
-
3034
- function coerceFractionalSecondDigits(options) {
3035
- let subsecDigits = options.fractionalSecondDigits;
3036
- if (void 0 !== subsecDigits) {
3037
- if ("number" != typeof subsecDigits) {
3038
- if ("auto" === toString(subsecDigits)) {
3039
- return;
3040
- }
3041
- throwRangeError(invalidEntity("fractionalSecondDigits", subsecDigits));
3042
- }
3043
- subsecDigits = clampEntity("fractionalSecondDigits", Math.floor(subsecDigits), 0, 9, 1);
3044
- }
3045
- return subsecDigits;
3046
- }
3047
-
3048
- function coerceUnitOption(optionName, options, minUnit = 0, ensureDefined) {
3049
- let unitStr = options[optionName];
3050
- if (void 0 === unitStr) {
3051
- return ensureDefined ? minUnit : void 0;
3052
- }
3053
- if (unitStr = toString(unitStr), "auto" === unitStr) {
3054
- return ensureDefined ? minUnit : null;
3055
- }
3056
- let unit = unitNameMap[unitStr];
3057
- return void 0 === unit && (unit = durationFieldNamesAsc.indexOf(unitStr)), unit < 0 && throwRangeError(invalidChoice(optionName, unitStr, unitNameMap)),
3058
- unit;
3059
- }
3060
-
3061
- function coerceChoiceOption(optionName, enumNameMap, options, defaultChoice = 0) {
3062
- const enumArg = options[optionName];
3063
- if (void 0 === enumArg) {
3064
- return defaultChoice;
3065
- }
3066
- const enumStr = toString(enumArg);
3067
- const enumNum = enumNameMap[enumStr];
3068
- return void 0 === enumNum && throwRangeError(invalidChoice(optionName, enumStr, enumNameMap)),
3069
- enumNum;
3070
- }
3071
-
3072
- const coerceSmallestUnit = /*@__PURE__*/ bindArgs(coerceUnitOption, smallestUnitStr);
3073
-
3074
- const coerceLargestUnit = /*@__PURE__*/ bindArgs(coerceUnitOption, "largestUnit");
3075
-
3076
- const coerceTotalUnit = /*@__PURE__*/ bindArgs(coerceUnitOption, "unit");
3077
-
3078
- const coerceOverflow = /*@__PURE__*/ bindArgs(coerceChoiceOption, "overflow", overflowMap);
3079
-
3080
- const coerceEpochDisambig = /*@__PURE__*/ bindArgs(coerceChoiceOption, "disambiguation", epochDisambigMap);
3081
-
3082
- const coerceOffsetDisambig = /*@__PURE__*/ bindArgs(coerceChoiceOption, "offset", offsetDisambigMap);
3083
-
3084
- const coerceCalendarDisplay = /*@__PURE__*/ bindArgs(coerceChoiceOption, "calendarName", calendarDisplayMap);
3085
-
3086
- const coerceTimeZoneDisplay = /*@__PURE__*/ bindArgs(coerceChoiceOption, "timeZoneName", timeZoneDisplayMap);
3087
-
3088
- const coerceOffsetDisplay = /*@__PURE__*/ bindArgs(coerceChoiceOption, "offset", offsetDisplayMap);
3089
-
3090
- const coerceRoundingMode = /*@__PURE__*/ bindArgs(coerceChoiceOption, "roundingMode", roundingModeMap);
3091
-
3092
- const coerceDirection = /*@__PURE__*/ bindArgs(coerceChoiceOption, "direction", directionMap);
3093
-
3094
- function validateRoundingInc(roundingInc, smallestUnit, allowManyLargeUnits, solarMode) {
3095
- const upUnitNano = solarMode ? nanoInUtcDay : unitNanoMap[smallestUnit + 1];
3096
- if (upUnitNano) {
3097
- const unitNano = unitNanoMap[smallestUnit];
3098
- upUnitNano % ((roundingInc = clampEntity("roundingIncrement", roundingInc, 1, upUnitNano / unitNano - (solarMode ? 0 : 1), 1)) * unitNano) && throwRangeError(invalidEntity("roundingIncrement", roundingInc));
3099
- } else {
3100
- roundingInc = clampEntity("roundingIncrement", roundingInc, 1, allowManyLargeUnits ? 10 ** 9 : 1, 1);
3101
- }
3102
- return roundingInc;
3103
- }
3104
-
3105
- function validateUnitRange(optionName, unit, minUnit, maxUnit) {
3106
- return null != unit && clampEntity(optionName, unit, minUnit, maxUnit, 1, unitNamesAsc),
3107
- unit;
3108
- }
3109
-
3110
- function checkLargestSmallestUnit(largestUnit, smallestUnit) {
3111
- smallestUnit > largestUnit && throwRangeError(flippedSmallestLargestUnit);
3112
- }
3113
-
3114
- function refineDiffOptions(roundingModeInvert, options, defaultLargestUnit, maxUnit = 9, minUnit = 0, defaultRoundingMode = 4) {
3115
- options = normalizeOptions(options);
3116
- let largestUnit = coerceLargestUnit(options, minUnit);
3117
- let roundingInc = coerceRoundingIncInteger(options);
3118
- let roundingMode = coerceRoundingMode(options, defaultRoundingMode);
3119
- let smallestUnit = coerceSmallestUnit(options, minUnit, 1);
3120
- return largestUnit = validateUnitRange("largestUnit", largestUnit, minUnit, maxUnit),
3121
- smallestUnit = validateUnitRange(smallestUnitStr, smallestUnit, minUnit, maxUnit),
3122
- null == largestUnit ? largestUnit = Math.max(defaultLargestUnit, smallestUnit) : checkLargestSmallestUnit(largestUnit, smallestUnit),
3123
- roundingInc = validateRoundingInc(roundingInc, smallestUnit, 1), roundingModeInvert && (roundingMode = (roundingMode => roundingMode < 4 ? (roundingMode + 2) % 4 : roundingMode)(roundingMode)),
3124
- [ largestUnit, smallestUnit, roundingInc, roundingMode ];
3125
- }
3126
-
3127
- function refineDurationRoundOptions(options, defaultLargestUnit, refineRelativeTo) {
3128
- options = normalizeOptionsOrString(options, smallestUnitStr);
3129
- let largestUnit = coerceLargestUnit(options);
3130
- const relativeToInternals = refineRelativeTo(options.relativeTo);
3131
- let roundingInc = coerceRoundingIncInteger(options);
3132
- const roundingMode = coerceRoundingMode(options, 7);
3133
- let smallestUnit = coerceSmallestUnit(options);
3134
- return void 0 === largestUnit && void 0 === smallestUnit && throwRangeError(missingSmallestLargestUnit),
3135
- null == smallestUnit && (smallestUnit = 0), null == largestUnit && (largestUnit = Math.max(smallestUnit, defaultLargestUnit)),
3136
- checkLargestSmallestUnit(largestUnit, smallestUnit), roundingInc = validateRoundingInc(roundingInc, smallestUnit, 1),
3137
- roundingInc > 1 && smallestUnit > 5 && largestUnit !== smallestUnit && throwRangeError("For calendar units with roundingIncrement > 1, use largestUnit = smallestUnit"),
3138
- [ largestUnit, smallestUnit, roundingInc, roundingMode, relativeToInternals ];
3139
- }
3140
-
3141
- function refineRoundingOptions(options, maxUnit = 6, solarMode) {
3142
- let roundingInc = coerceRoundingIncInteger(options = normalizeOptionsOrString(options, smallestUnitStr));
3143
- const roundingMode = coerceRoundingMode(options, 7);
3144
- let smallestUnit = coerceSmallestUnit(options);
3145
- return smallestUnit = requirePropDefined(smallestUnitStr, smallestUnit), smallestUnit = validateUnitRange(smallestUnitStr, smallestUnit, 0, maxUnit),
3146
- roundingInc = validateRoundingInc(roundingInc, smallestUnit, void 0, solarMode),
3147
- [ smallestUnit, roundingInc, roundingMode ];
3148
- }
3149
-
3150
- function refineTotalOptions(options, refineRelativeTo) {
3151
- const relativeToInternals = refineRelativeTo((options = normalizeOptionsOrString(options, "unit")).relativeTo);
3152
- let totalUnit = coerceTotalUnit(options);
3153
- return totalUnit = requirePropDefined("unit", totalUnit), [ totalUnit, relativeToInternals ];
3154
- }
3155
-
3156
- function refineOverflowOptions(options) {
3157
- return void 0 === options ? 0 : coerceOverflow(requireObjectLike(options));
3158
- }
3159
-
3160
- function refineZonedFieldOptions(options, defaultOffsetDisambig = 0) {
3161
- options = normalizeOptions(options);
3162
- const epochDisambig = coerceEpochDisambig(options);
3163
- const offsetDisambig = coerceOffsetDisambig(options, defaultOffsetDisambig);
3164
- return [ coerceOverflow(options), offsetDisambig, epochDisambig ];
3165
- }
3166
-
3167
- function refineEpochDisambigOptions(options) {
3168
- return coerceEpochDisambig(normalizeOptions(options));
3169
- }
3170
-
3171
- function refineTimeDisplayTuple(options, maxSmallestUnit = 4) {
3172
- const subsecDigits = coerceFractionalSecondDigits(options);
3173
- const roundingMode = coerceRoundingMode(options, 4);
3174
- const smallestUnit = coerceSmallestUnit(options);
3175
- return [ roundingMode, ...resolveSmallestUnitAndSubsecDigits(validateUnitRange(smallestUnitStr, smallestUnit, 0, maxSmallestUnit), subsecDigits) ];
3176
- }
3177
-
3178
- function refineDateTimeDisplayOptions(options) {
3179
- return options = normalizeOptions(options), [ coerceCalendarDisplay(options), ...refineTimeDisplayTuple(options) ];
3180
- }
3181
-
3182
- function refineDateDisplayOptions(options) {
3183
- return coerceCalendarDisplay(normalizeOptions(options));
3184
- }
3185
-
3186
- function refineTimeDisplayOptions(options, maxSmallestUnit) {
3187
- return refineTimeDisplayTuple(normalizeOptions(options), maxSmallestUnit);
3188
- }
3189
-
3190
- function refineZonedDateTimeDisplayOptions(options) {
3191
- options = normalizeOptions(options);
3192
- const calendarDisplay = coerceCalendarDisplay(options);
3193
- const subsecDigits = coerceFractionalSecondDigits(options);
3194
- const offsetDisplay = coerceOffsetDisplay(options);
3195
- const roundingMode = coerceRoundingMode(options, 4);
3196
- const smallestUnit = coerceSmallestUnit(options);
3197
- return [ calendarDisplay, coerceTimeZoneDisplay(options), offsetDisplay, roundingMode, ...resolveSmallestUnitAndSubsecDigits(validateUnitRange(smallestUnitStr, smallestUnit, 0, 4), subsecDigits) ];
3198
- }
3199
-
3200
- function refineInstantDisplayOptions(options) {
3201
- const subsecDigits = coerceFractionalSecondDigits(options = normalizeOptions(options));
3202
- const roundingMode = coerceRoundingMode(options, 4);
3203
- const smallestUnit = coerceSmallestUnit(options);
3204
- return [ options.timeZone, roundingMode, ...resolveSmallestUnitAndSubsecDigits(validateUnitRange(smallestUnitStr, smallestUnit, 0, 4), subsecDigits) ];
3205
- }
3206
-
3207
- function resolveSmallestUnitAndSubsecDigits(smallestUnit, subsecDigits) {
3208
- return null != smallestUnit ? [ unitNanoMap[smallestUnit], smallestUnit < 4 ? 9 - 3 * smallestUnit : -1 ] : [ void 0 === subsecDigits ? 1 : 10 ** (9 - subsecDigits), subsecDigits ];
3209
- }
3210
-
3211
- function refineDirectionOptions(options) {
3212
- const normalizedOptions = normalizeOptionsOrString(options, "direction");
3213
- const res = coerceDirection(normalizedOptions, 0);
3214
- return res || throwRangeError(invalidEntity("direction", res)), res;
3215
- }
3216
-
3217
2964
  const invalidEntity = invalidEntity$1;
3218
2965
 
3219
2966
  const missingField = fieldName => `Missing ${fieldName}`;
@@ -3240,10 +2987,6 @@ const invalidTimeZone = calendarId => invalidEntity$1("TimeZone", calendarId);
3240
2987
 
3241
2988
  const outOfBoundsDate = "Out-of-bounds date";
3242
2989
 
3243
- const missingSmallestLargestUnit = "Required smallestUnit or largestUnit";
3244
-
3245
- const flippedSmallestLargestUnit = "smallestUnit > largestUnit";
3246
-
3247
2990
  const failedParse = s => `Cannot parse: ${s}`;
3248
2991
 
3249
2992
  const invalidSubstring = substring => `Invalid substring: ${substring}`;
@@ -3429,34 +3172,10 @@ function modTrunc(num, divisor) {
3429
3172
  return num % divisor || 0;
3430
3173
  }
3431
3174
 
3432
- function roundExpand(num) {
3433
- return num < 0 ? Math.floor(num) : Math.ceil(num);
3434
- }
3435
-
3436
3175
  function fabricateNearHalfFraction(halfCompare, sign = 1) {
3437
3176
  return sign * (.5 + halfCompare / 5);
3438
3177
  }
3439
3178
 
3440
- function roundHalfExpand(num) {
3441
- return Math.sign(num) * Math.round(Math.abs(num)) || 0;
3442
- }
3443
-
3444
- function roundHalfFloor(num) {
3445
- return hasHalf(num) ? Math.floor(num) : Math.round(num);
3446
- }
3447
-
3448
- function roundHalfCeil(num) {
3449
- return hasHalf(num) ? Math.ceil(num) : Math.round(num);
3450
- }
3451
-
3452
- function roundHalfTrunc(num) {
3453
- return hasHalf(num) ? Math.trunc(num) || 0 : Math.round(num);
3454
- }
3455
-
3456
- function roundHalfEven(num) {
3457
- return hasHalf(num) ? (num = Math.trunc(num) || 0) + num % 2 : Math.round(num);
3458
- }
3459
-
3460
3179
  function hasHalf(num) {
3461
3180
  return .5 === Math.abs(num % 1);
3462
3181
  }
@@ -3892,73 +3611,245 @@ function computeCalendarDayOfYear(calendar, isoDate) {
3892
3611
  return isoDateToEpochDays(isoDate) - isoDateToEpochDays(yearStartIsoDate) + 1;
3893
3612
  }
3894
3613
 
3895
- function computeCalendarWeekOfYear(calendar, isoDate) {
3896
- return calendar === isoCalendarImpl ? computeIsoWeekFields(isoDate).weekOfYear : void 0;
3614
+ function computeCalendarWeekOfYear(calendar, isoDate) {
3615
+ return calendar === isoCalendarImpl ? computeIsoWeekFields(isoDate).weekOfYear : void 0;
3616
+ }
3617
+
3618
+ function computeCalendarYearOfWeek(calendar, isoDate) {
3619
+ return calendar === isoCalendarImpl ? computeIsoWeekFields(isoDate).yearOfWeek : void 0;
3620
+ }
3621
+
3622
+ const durationFieldNamesAsc = /*@__PURE__*/ unitNamesAsc.map(unitName => unitName + "s");
3623
+
3624
+ const durationGetters = /*@__PURE__*/ createPropGetters(durationFieldNamesAsc);
3625
+
3626
+ const durationFieldNamesAlpha = /*@__PURE__*/ sortStrings(durationFieldNamesAsc);
3627
+
3628
+ const durationTimeFieldNamesAsc = /*@__PURE__*/ durationFieldNamesAsc.slice(0, 6);
3629
+
3630
+ const durationDateFieldNamesAsc = /*@__PURE__*/ durationFieldNamesAsc.slice(6);
3631
+
3632
+ const durationCalendarFieldNamesAsc = /*@__PURE__*/ durationDateFieldNamesAsc.slice(1);
3633
+
3634
+ const durationFieldDefaults = /*@__PURE__*/ zipPropsConst(durationFieldNamesAsc, 0);
3635
+
3636
+ const durationTimeFieldDefaults = /*@__PURE__*/ zipPropsConst(durationTimeFieldNamesAsc, 0);
3637
+
3638
+ const clearDurationFields = /*@__PURE__*/ bindArgs(zeroOutProps, durationFieldNamesAsc);
3639
+
3640
+ function requirePropDefined(optionName, optionVal) {
3641
+ return null == optionVal && throwRangeError(missingField(optionName)), optionVal;
3642
+ }
3643
+
3644
+ const requireString = /*@__PURE__*/ bindArgs(requireType, "string");
3645
+
3646
+ function requireType(typeName, arg, entityName = typeName) {
3647
+ return typeof arg !== typeName && throwTypeError(invalidEntity(entityName, arg)),
3648
+ arg;
3649
+ }
3650
+
3651
+ function requireNumberIsInteger(num, entityName = "number") {
3652
+ return Number.isInteger(num) || throwRangeError(((entityName, num) => `Non-integer ${entityName}: ${num}`)(entityName, num)),
3653
+ num || 0;
3654
+ }
3655
+
3656
+ function toString(arg) {
3657
+ return "symbol" == typeof arg && throwTypeError("Cannot convert Symbol to string"),
3658
+ String(arg);
3659
+ }
3660
+
3661
+ function toPrimitiveWithStringHint(arg) {
3662
+ if (!isObjectLike$1(arg)) {
3663
+ return arg;
3664
+ }
3665
+ const exoticToPrimitive = arg[Symbol.toPrimitive];
3666
+ if (null != exoticToPrimitive) {
3667
+ "function" != typeof exoticToPrimitive && throwTypeError();
3668
+ const primitive = Reflect.apply(exoticToPrimitive, arg, [ "string" ]);
3669
+ return isObjectLike$1(primitive) && throwTypeError(), primitive;
3670
+ }
3671
+ return Date.prototype[Symbol.toPrimitive].call(arg, "string");
3672
+ }
3673
+
3674
+ function toBigInt(bi) {
3675
+ return "boolean" == typeof bi ? BigInt(bi ? 1 : 0) : "string" == typeof bi ? BigInt(bi) : ("bigint" != typeof bi && throwTypeError(`Invalid bigint: ${bi}`),
3676
+ bi);
3677
+ }
3678
+
3679
+ function toStrictInteger(arg, entityName) {
3680
+ return requireNumberIsInteger(toFiniteNumber(arg, entityName), entityName);
3681
+ }
3682
+
3683
+ const smallestUnitStr = "smallestUnit";
3684
+
3685
+ const overflowMap = {
3686
+ constrain: 0,
3687
+ reject: 1
3688
+ };
3689
+
3690
+ const epochDisambigMap = {
3691
+ compatible: 0,
3692
+ reject: 1,
3693
+ earlier: 2,
3694
+ later: 3
3695
+ };
3696
+
3697
+ const offsetDisambigMap = {
3698
+ reject: 0,
3699
+ use: 1,
3700
+ prefer: 2,
3701
+ ignore: 3
3702
+ };
3703
+
3704
+ const calendarDisplayMap = {
3705
+ auto: 0,
3706
+ never: 1,
3707
+ critical: 2,
3708
+ always: 3
3709
+ };
3710
+
3711
+ const timeZoneDisplayMap = {
3712
+ auto: 0,
3713
+ never: 1,
3714
+ critical: 2
3715
+ };
3716
+
3717
+ const offsetDisplayMap = {
3718
+ auto: 0,
3719
+ never: 1
3720
+ };
3721
+
3722
+ const roundingModeMap = {
3723
+ floor: 0,
3724
+ halfFloor: 1,
3725
+ ceil: 2,
3726
+ halfCeil: 3,
3727
+ trunc: 4,
3728
+ halfTrunc: 5,
3729
+ expand: 6,
3730
+ halfExpand: 7,
3731
+ halfEven: 8
3732
+ };
3733
+
3734
+ const roundingModeFuncs = [ Math.floor, num => hasHalf(num) ? Math.floor(num) : Math.round(num), Math.ceil, num => hasHalf(num) ? Math.ceil(num) : Math.round(num), Math.trunc, num => hasHalf(num) ? Math.trunc(num) || 0 : Math.round(num), num => num < 0 ? Math.floor(num) : Math.ceil(num), num => Math.sign(num) * Math.round(Math.abs(num)) || 0, num => hasHalf(num) ? (num = Math.trunc(num) || 0) + num % 2 : Math.round(num) ];
3735
+
3736
+ const directionMap = {
3737
+ previous: -1,
3738
+ next: 1
3739
+ };
3740
+
3741
+ function coerceRoundingIncInteger(options) {
3742
+ const roundingInc = options.roundingIncrement;
3743
+ return void 0 === roundingInc ? 1 : toIntegerWithTrunc(roundingInc, "roundingIncrement");
3744
+ }
3745
+
3746
+ function coerceFractionalSecondDigits(options) {
3747
+ let subsecDigits = options.fractionalSecondDigits;
3748
+ if (void 0 !== subsecDigits) {
3749
+ if ("number" != typeof subsecDigits) {
3750
+ if ("auto" === toString(subsecDigits)) {
3751
+ return;
3752
+ }
3753
+ throwRangeError(invalidEntity("fractionalSecondDigits", subsecDigits));
3754
+ }
3755
+ subsecDigits = clampEntity("fractionalSecondDigits", Math.floor(subsecDigits), 0, 9, 1);
3756
+ }
3757
+ return subsecDigits;
3758
+ }
3759
+
3760
+ function coerceUnitOption(optionName, options, minUnit = 0, ensureDefined) {
3761
+ let unitStr = options[optionName];
3762
+ if (void 0 === unitStr) {
3763
+ return ensureDefined ? minUnit : void 0;
3764
+ }
3765
+ if (unitStr = toString(unitStr), "auto" === unitStr) {
3766
+ return ensureDefined ? minUnit : null;
3767
+ }
3768
+ let unit = unitNameMap[unitStr];
3769
+ return void 0 === unit && (unit = durationFieldNamesAsc.indexOf(unitStr)), unit < 0 && throwRangeError(invalidChoice(optionName, unitStr, unitNameMap)),
3770
+ unit;
3897
3771
  }
3898
3772
 
3899
- function computeCalendarYearOfWeek(calendar, isoDate) {
3900
- return calendar === isoCalendarImpl ? computeIsoWeekFields(isoDate).yearOfWeek : void 0;
3773
+ function coerceChoiceOption(optionName, enumNameMap, options, defaultChoice = 0) {
3774
+ const enumArg = options[optionName];
3775
+ if (void 0 === enumArg) {
3776
+ return defaultChoice;
3777
+ }
3778
+ const enumStr = toString(enumArg);
3779
+ const enumNum = enumNameMap[enumStr];
3780
+ return void 0 === enumNum && throwRangeError(invalidChoice(optionName, enumStr, enumNameMap)),
3781
+ enumNum;
3901
3782
  }
3902
3783
 
3903
- const durationFieldNamesAsc = /*@__PURE__*/ unitNamesAsc.map(unitName => unitName + "s");
3784
+ const coerceSmallestUnit = /*@__PURE__*/ bindArgs(coerceUnitOption, smallestUnitStr);
3904
3785
 
3905
- const durationGetters = /*@__PURE__*/ createPropGetters(durationFieldNamesAsc);
3786
+ const coerceLargestUnit = /*@__PURE__*/ bindArgs(coerceUnitOption, "largestUnit");
3906
3787
 
3907
- const durationFieldNamesAlpha = /*@__PURE__*/ sortStrings(durationFieldNamesAsc);
3788
+ const coerceTotalUnit = /*@__PURE__*/ bindArgs(coerceUnitOption, "unit");
3908
3789
 
3909
- const durationTimeFieldNamesAsc = /*@__PURE__*/ durationFieldNamesAsc.slice(0, 6);
3790
+ const coerceOverflow = /*@__PURE__*/ bindArgs(coerceChoiceOption, "overflow", overflowMap);
3910
3791
 
3911
- const durationDateFieldNamesAsc = /*@__PURE__*/ durationFieldNamesAsc.slice(6);
3792
+ const coerceEpochDisambig = /*@__PURE__*/ bindArgs(coerceChoiceOption, "disambiguation", epochDisambigMap);
3912
3793
 
3913
- const durationCalendarFieldNamesAsc = /*@__PURE__*/ durationDateFieldNamesAsc.slice(1);
3794
+ const coerceOffsetDisambig = /*@__PURE__*/ bindArgs(coerceChoiceOption, "offset", offsetDisambigMap);
3914
3795
 
3915
- const durationFieldDefaults = /*@__PURE__*/ zipPropsConst(durationFieldNamesAsc, 0);
3796
+ const coerceCalendarDisplay = /*@__PURE__*/ bindArgs(coerceChoiceOption, "calendarName", calendarDisplayMap);
3916
3797
 
3917
- const durationTimeFieldDefaults = /*@__PURE__*/ zipPropsConst(durationTimeFieldNamesAsc, 0);
3798
+ const coerceTimeZoneDisplay = /*@__PURE__*/ bindArgs(coerceChoiceOption, "timeZoneName", timeZoneDisplayMap);
3918
3799
 
3919
- const clearDurationFields = /*@__PURE__*/ bindArgs(zeroOutProps, durationFieldNamesAsc);
3800
+ const coerceOffsetDisplay = /*@__PURE__*/ bindArgs(coerceChoiceOption, "offset", offsetDisplayMap);
3920
3801
 
3921
- function requirePropDefined(optionName, optionVal) {
3922
- return null == optionVal && throwRangeError(missingField(optionName)), optionVal;
3923
- }
3802
+ const coerceRoundingMode = /*@__PURE__*/ bindArgs(coerceChoiceOption, "roundingMode", roundingModeMap);
3924
3803
 
3925
- const requireString = /*@__PURE__*/ bindArgs(requireType, "string");
3804
+ const coerceDirection = /*@__PURE__*/ bindArgs(coerceChoiceOption, "direction", directionMap);
3926
3805
 
3927
- function requireType(typeName, arg, entityName = typeName) {
3928
- return typeof arg !== typeName && throwTypeError(invalidEntity(entityName, arg)),
3929
- arg;
3806
+ function normalizeOptionsOrString(options, optionName) {
3807
+ return "string" == typeof options ? ((optionName, optionVal) => {
3808
+ const res = Object.create(null);
3809
+ return res[optionName] = optionVal, res;
3810
+ })(optionName, options) : requireObjectLike(options);
3930
3811
  }
3931
3812
 
3932
- function requireNumberIsInteger(num, entityName = "number") {
3933
- return Number.isInteger(num) || throwRangeError(((entityName, num) => `Non-integer ${entityName}: ${num}`)(entityName, num)),
3934
- num || 0;
3813
+ function validateRoundingInc(roundingInc, smallestUnit, allowManyLargeUnits, solarMode) {
3814
+ const upUnitNano = solarMode ? nanoInUtcDay : unitNanoMap[smallestUnit + 1];
3815
+ if (upUnitNano) {
3816
+ const unitNano = unitNanoMap[smallestUnit];
3817
+ upUnitNano % ((roundingInc = clampEntity("roundingIncrement", roundingInc, 1, upUnitNano / unitNano - (solarMode ? 0 : 1), 1)) * unitNano) && throwRangeError(invalidEntity("roundingIncrement", roundingInc));
3818
+ } else {
3819
+ roundingInc = clampEntity("roundingIncrement", roundingInc, 1, allowManyLargeUnits ? 10 ** 9 : 1, 1);
3820
+ }
3821
+ return roundingInc;
3935
3822
  }
3936
3823
 
3937
- function toString(arg) {
3938
- return "symbol" == typeof arg && throwTypeError("Cannot convert Symbol to string"),
3939
- String(arg);
3824
+ function validateUnitRange(optionName, unit, minUnit, maxUnit) {
3825
+ return null != unit && clampEntity(optionName, unit, minUnit, maxUnit, 1, unitNamesAsc),
3826
+ unit;
3940
3827
  }
3941
3828
 
3942
- function toPrimitiveWithStringHint(arg) {
3943
- if (!isObjectLike$1(arg)) {
3944
- return arg;
3945
- }
3946
- const exoticToPrimitive = arg[Symbol.toPrimitive];
3947
- if (null != exoticToPrimitive) {
3948
- "function" != typeof exoticToPrimitive && throwTypeError();
3949
- const primitive = Reflect.apply(exoticToPrimitive, arg, [ "string" ]);
3950
- return isObjectLike$1(primitive) && throwTypeError(), primitive;
3951
- }
3952
- return Date.prototype[Symbol.toPrimitive].call(arg, "string");
3829
+ function checkLargestSmallestUnit(largestUnit, smallestUnit) {
3830
+ smallestUnit > largestUnit && throwRangeError("smallestUnit > largestUnit");
3953
3831
  }
3954
3832
 
3955
- function toBigInt(bi) {
3956
- return "boolean" == typeof bi ? BigInt(bi ? 1 : 0) : "string" == typeof bi ? BigInt(bi) : ("bigint" != typeof bi && throwTypeError(`Invalid bigint: ${bi}`),
3957
- bi);
3833
+ function refineDiffOptions(roundingModeInvert, options, defaultLargestUnit, maxUnit = 9, minUnit = 0, defaultRoundingMode = 4) {
3834
+ options = normalizeOptions(options);
3835
+ let largestUnit = coerceLargestUnit(options, minUnit);
3836
+ let roundingInc = coerceRoundingIncInteger(options);
3837
+ let roundingMode = coerceRoundingMode(options, defaultRoundingMode);
3838
+ let smallestUnit = coerceSmallestUnit(options, minUnit, 1);
3839
+ return largestUnit = validateUnitRange("largestUnit", largestUnit, minUnit, maxUnit),
3840
+ smallestUnit = validateUnitRange(smallestUnitStr, smallestUnit, minUnit, maxUnit),
3841
+ null == largestUnit ? largestUnit = Math.max(defaultLargestUnit, smallestUnit) : checkLargestSmallestUnit(largestUnit, smallestUnit),
3842
+ roundingInc = validateRoundingInc(roundingInc, smallestUnit, 1), roundingModeInvert && (roundingMode = (roundingMode => roundingMode < 4 ? (roundingMode + 2) % 4 : roundingMode)(roundingMode)),
3843
+ [ largestUnit, smallestUnit, roundingInc, roundingMode ];
3958
3844
  }
3959
3845
 
3960
- function toStrictInteger(arg, entityName) {
3961
- return requireNumberIsInteger(toFiniteNumber(arg, entityName), entityName);
3846
+ function refineRoundingOptions(options, maxUnit = 6, solarMode) {
3847
+ let roundingInc = coerceRoundingIncInteger(options = normalizeOptionsOrString(options, smallestUnitStr));
3848
+ const roundingMode = coerceRoundingMode(options, 7);
3849
+ let smallestUnit = coerceSmallestUnit(options);
3850
+ return smallestUnit = requirePropDefined(smallestUnitStr, smallestUnit), smallestUnit = validateUnitRange(smallestUnitStr, smallestUnit, 0, maxUnit),
3851
+ roundingInc = validateRoundingInc(roundingInc, smallestUnit, void 0, solarMode),
3852
+ [ smallestUnit, roundingInc, roundingMode ];
3962
3853
  }
3963
3854
 
3964
3855
  function combineDateAndTime(isoDate, time) {
@@ -4308,7 +4199,7 @@ function getStartOfDayInstantFor(timeZone, isoDateTime) {
4308
4199
  }
4309
4200
 
4310
4201
  function moveYearMonth(calendar, isoDate, durationSlots, overflow = 0) {
4311
- computeDurationSign(durationSlots) && getMaxDurationUnit(durationSlots) < 8 && throwRangeError("Cannot use small units");
4202
+ computeDurationSign(durationSlots) && clampEntity("unit", getMaxDurationUnit(durationSlots), 8, 9, 1, durationFieldNamesAsc);
4312
4203
  const first = checkIsoDateInBounds(moveToStartOfMonth(calendar, isoDate));
4313
4204
  return moveToStartOfMonth(calendar, moveDate(calendar, first, durationSlots, overflow));
4314
4205
  }
@@ -4346,7 +4237,7 @@ function moveTime(timeFields, durationFields) {
4346
4237
  }
4347
4238
 
4348
4239
  function moveEpochNano(epochNano, durationFields) {
4349
- return moveEpochNanoByNano(epochNano, (durationHasDateParts(fields = durationFields) && throwRangeError("Cannot use large units"),
4240
+ return moveEpochNanoByNano(epochNano, (clampEntity("unit", getMaxDurationUnit(fields = durationFields), 0, 5, 1, durationFieldNamesAsc),
4350
4241
  durationTimeToBigNano(fields)));
4351
4242
  var fields;
4352
4243
  }
@@ -4692,7 +4583,7 @@ const maxDurationSeconds = 2 ** 53;
4692
4583
 
4693
4584
  function addDurationsWithoutRelativeTo(doSubtract, slots, otherSlots) {
4694
4585
  const maxUnit = Math.max(getMaxDurationUnit(slots), getMaxDurationUnit(otherSlots));
4695
- return maxUnit > 6 && throwRangeError("Cannot use large units"), ((doSubtract, slots, otherSlots, maxUnit) => createDurationSlots(validateDurationFields(((a, b, largestUnit, doSubtract) => {
4586
+ return clampEntity("unit", maxUnit, 0, 6, 1, durationFieldNamesAsc), ((doSubtract, slots, otherSlots, maxUnit) => createDurationSlots(validateDurationFields(((a, b, largestUnit, doSubtract) => {
4696
4587
  const combined = durationDayTimeToBigNano(a) + durationDayTimeToBigNano(b) * BigInt(doSubtract ? -1 : 1);
4697
4588
  return Number.isFinite(Number(combined / bigNanoInUtcDay)) || throwRangeError(outOfBoundsDate),
4698
4589
  {
@@ -4704,7 +4595,19 @@ function addDurationsWithoutRelativeTo(doSubtract, slots, otherSlots) {
4704
4595
 
4705
4596
  function roundDuration(refineRelativeTo, slots, options) {
4706
4597
  const durationLargestUnit = getMaxDurationUnit(slots);
4707
- const [largestUnit, smallestUnit, roundingInc, roundingMode, relativeToSlots] = refineDurationRoundOptions(options, durationLargestUnit, refineRelativeTo);
4598
+ const [largestUnit, smallestUnit, roundingInc, roundingMode, relativeToSlots] = ((options, defaultLargestUnit, refineRelativeTo) => {
4599
+ options = normalizeOptionsOrString(options, smallestUnitStr);
4600
+ let largestUnit = coerceLargestUnit(options);
4601
+ const relativeToInternals = refineRelativeTo(options.relativeTo);
4602
+ let roundingInc = coerceRoundingIncInteger(options);
4603
+ const roundingMode = coerceRoundingMode(options, 7);
4604
+ let smallestUnit = coerceSmallestUnit(options);
4605
+ return void 0 === largestUnit && void 0 === smallestUnit && throwRangeError("Required smallestUnit or largestUnit"),
4606
+ null == smallestUnit && (smallestUnit = 0), null == largestUnit && (largestUnit = Math.max(smallestUnit, defaultLargestUnit)),
4607
+ checkLargestSmallestUnit(largestUnit, smallestUnit), roundingInc = validateRoundingInc(roundingInc, smallestUnit, 1),
4608
+ roundingInc > 1 && smallestUnit > 5 && largestUnit !== smallestUnit && throwRangeError("For calendar units with roundingIncrement > 1, use largestUnit = smallestUnit"),
4609
+ [ largestUnit, smallestUnit, roundingInc, roundingMode, relativeToInternals ];
4610
+ })(options, durationLargestUnit, refineRelativeTo);
4708
4611
  if (!relativeToSlots && Math.max(durationLargestUnit, largestUnit) <= 6) {
4709
4612
  return createDurationSlots(validateDurationFields(((durationFields, largestUnit, smallestUnit, roundingInc, roundingMode) => {
4710
4613
  const roundedBigNano = roundBigNanoToInc(durationDayTimeToBigNano(durationFields), computeBigNanoInc(smallestUnit, roundingInc), roundingMode);
@@ -4984,6 +4887,21 @@ function readAndRefineBagFields(bag, validFieldNames, fieldRefiners, requiredFie
4984
4887
  res;
4985
4888
  }
4986
4889
 
4890
+ function refineOverflowOptions(options) {
4891
+ return void 0 === options ? 0 : coerceOverflow(requireObjectLike(options));
4892
+ }
4893
+
4894
+ function refineZonedFieldOptions(options, defaultOffsetDisambig = 0) {
4895
+ options = normalizeOptions(options);
4896
+ const epochDisambig = coerceEpochDisambig(options);
4897
+ const offsetDisambig = coerceOffsetDisambig(options, defaultOffsetDisambig);
4898
+ return [ coerceOverflow(options), offsetDisambig, epochDisambig ];
4899
+ }
4900
+
4901
+ function refineEpochDisambigOptions(options) {
4902
+ return coerceEpochDisambig(normalizeOptions(options));
4903
+ }
4904
+
4987
4905
  function refineCalendarDateFields(fields, calendar, allowMissingDay) {
4988
4906
  const eraOrigins = getCalendarEraOrigins(calendar);
4989
4907
  void 0 !== fields.year || void 0 !== fields.era && void 0 !== fields.eraYear || throwTypeError(missingYear(eraOrigins)),
@@ -5093,8 +5011,32 @@ const timeZonePeriodDaysByName = {
5093
5011
 
5094
5012
  const minPossibleTransitionSec = -388152e4;
5095
5013
 
5014
+ function refineTimeDisplayTuple(options, maxSmallestUnit = 4) {
5015
+ const subsecDigits = coerceFractionalSecondDigits(options);
5016
+ const roundingMode = coerceRoundingMode(options, 4);
5017
+ const smallestUnit = coerceSmallestUnit(options);
5018
+ return [ roundingMode, ...resolveSmallestUnitAndSubsecDigits(validateUnitRange(smallestUnitStr, smallestUnit, 0, maxSmallestUnit), subsecDigits) ];
5019
+ }
5020
+
5021
+ function refineDateDisplayOptions(options) {
5022
+ return coerceCalendarDisplay(normalizeOptions(options));
5023
+ }
5024
+
5025
+ function refineTimeDisplayOptions(options, maxSmallestUnit) {
5026
+ return refineTimeDisplayTuple(normalizeOptions(options), maxSmallestUnit);
5027
+ }
5028
+
5029
+ function resolveSmallestUnitAndSubsecDigits(smallestUnit, subsecDigits) {
5030
+ return null != smallestUnit ? [ unitNanoMap[smallestUnit], smallestUnit < 4 ? 9 - 3 * smallestUnit : -1 ] : [ void 0 === subsecDigits ? 1 : 10 ** (9 - subsecDigits), subsecDigits ];
5031
+ }
5032
+
5096
5033
  function formatInstantIso(refineTimeZoneString, instantSlots, options) {
5097
- const [timeZoneArg, roundingMode, nanoInc, subsecDigits] = refineInstantDisplayOptions(options);
5034
+ const [timeZoneArg, roundingMode, nanoInc, subsecDigits] = (options => {
5035
+ const subsecDigits = coerceFractionalSecondDigits(options = normalizeOptions(options));
5036
+ const roundingMode = coerceRoundingMode(options, 4);
5037
+ const smallestUnit = coerceSmallestUnit(options);
5038
+ return [ options.timeZone, roundingMode, ...resolveSmallestUnitAndSubsecDigits(validateUnitRange(smallestUnitStr, smallestUnit, 0, 4), subsecDigits) ];
5039
+ })(options);
5098
5040
  const providedTimeZone = void 0 !== timeZoneArg;
5099
5041
  return ((providedTimeZone, timeZone, epochNano, roundingMode, nanoInc, subsecDigits) => {
5100
5042
  epochNano = roundBigNanoToDayOriginInc(epochNano, BigInt(nanoInc), roundingMode);
@@ -5104,7 +5046,15 @@ function formatInstantIso(refineTimeZoneString, instantSlots, options) {
5104
5046
  }
5105
5047
 
5106
5048
  function formatZonedDateTimeIso(zonedDateTimeSlots0, options) {
5107
- const displayOptions = refineZonedDateTimeDisplayOptions(options);
5049
+ const displayOptions = (options => {
5050
+ options = normalizeOptions(options);
5051
+ const calendarDisplay = coerceCalendarDisplay(options);
5052
+ const subsecDigits = coerceFractionalSecondDigits(options);
5053
+ const offsetDisplay = coerceOffsetDisplay(options);
5054
+ const roundingMode = coerceRoundingMode(options, 4);
5055
+ const smallestUnit = coerceSmallestUnit(options);
5056
+ return [ calendarDisplay, coerceTimeZoneDisplay(options), offsetDisplay, roundingMode, ...resolveSmallestUnitAndSubsecDigits(validateUnitRange(smallestUnitStr, smallestUnit, 0, 4), subsecDigits) ];
5057
+ })(options);
5108
5058
  return ((calendar, timeZoneId, timeZone, epochNano, calendarDisplay, timeZoneDisplay, offsetDisplay, roundingMode, nanoInc, subsecDigits) => {
5109
5059
  epochNano = roundBigNanoToDayOriginInc(epochNano, BigInt(nanoInc), roundingMode);
5110
5060
  const offsetNano = timeZone.B(epochNano);
@@ -5113,7 +5063,7 @@ function formatZonedDateTimeIso(zonedDateTimeSlots0, options) {
5113
5063
  }
5114
5064
 
5115
5065
  function formatPlainDateTimeIso(plainDateTimeSlots0, options) {
5116
- const displayOptions = refineDateTimeDisplayOptions(options);
5066
+ const displayOptions = (options => (options = normalizeOptions(options), [ coerceCalendarDisplay(options), ...refineTimeDisplayTuple(options) ]))(options);
5117
5067
  return ((calendar, isoDateTime, calendarDisplay, roundingMode, nanoInc, subsecDigits) => formatIsoDateTimeFields(roundDateTimeToInc(isoDateTime, nanoInc, roundingMode), subsecDigits) + formatCalendar(calendar, calendarDisplay))(plainDateTimeSlots0.calendar, plainDateTimeSlots0, ...displayOptions);
5118
5068
  }
5119
5069
 
@@ -5918,7 +5868,11 @@ function computeMonthCode(calendar, year, month) {
5918
5868
  }
5919
5869
 
5920
5870
  function totalDuration(refineRelativeTo, slots, options) {
5921
- const [totalUnit, relativeToSlots] = refineTotalOptions(options, refineRelativeTo);
5871
+ const [totalUnit, relativeToSlots] = ((options, refineRelativeTo) => {
5872
+ const relativeToInternals = refineRelativeTo((options = normalizeOptionsOrString(options, "unit")).relativeTo);
5873
+ let totalUnit = coerceTotalUnit(options);
5874
+ return totalUnit = requirePropDefined("unit", totalUnit), [ totalUnit, relativeToInternals ];
5875
+ })(options, refineRelativeTo);
5922
5876
  const maxDurationUnit = getMaxDurationUnit(slots);
5923
5877
  const maxUnit = Math.max(totalUnit, maxDurationUnit);
5924
5878
  const isZoned = relativeToSlots && isZonedEpochSlots(relativeToSlots);
@@ -6146,6 +6100,12 @@ function zonedDateTimeWithPlainTime(zonedDateTimeSlots, plainTimeFields) {
6146
6100
  createZonedEpochNanoSlots(epochNano, timeZone, zonedDateTimeSlots.calendar);
6147
6101
  }
6148
6102
 
6103
+ function refineDirectionOptions(options) {
6104
+ const normalizedOptions = normalizeOptionsOrString(options, "direction");
6105
+ const res = coerceDirection(normalizedOptions, 0);
6106
+ return res || throwRangeError(invalidEntity("direction", res)), res;
6107
+ }
6108
+
6149
6109
  function getCurrentIsoDateTime(timeZone) {
6150
6110
  const epochNano = getCurrentEpochNano();
6151
6111
  const offsetNano = timeZone.B(epochNano);
@@ -12459,27 +12419,152 @@ types['1311'] = types['1221'];
12459
12419
  types['1721'] = types['170'];
12460
12420
  const sedraCache = new QuickLRU({ maxSize: 120 });
12461
12421
  /**
12462
- * Convenience function to create an instance of {@link Sedra} or reuse a
12463
- * previously created and cached instance for the same year and schedule.
12422
+ * Convenience function to create an instance of {@link Sedra} or reuse a
12423
+ * previously created and cached instance for the same year and schedule.
12424
+ *
12425
+ * Prefer this over `new Sedra(...)` when calling repeatedly — an internal
12426
+ * LRU cache (~120 entries) avoids recomputing the keviyah-specific schedule.
12427
+ * @example
12428
+ * import {getSedra, HDate, months} from '@hebcal/core';
12429
+ * const sedra = getSedra(5784, false);
12430
+ * const {parsha} = sedra.lookup(new HDate(15, months.CHESHVAN, 5784));
12431
+ * console.log(parsha); // ['Vayera']
12432
+ * @param hyear Hebrew year
12433
+ * @param il Use Israel sedra schedule (`false` for Diaspora)
12434
+ */
12435
+ function getSedra(hyear, il) {
12436
+ const cacheKey = `${hyear}-${il ? 1 : 0}`;
12437
+ let sedra = sedraCache.get(cacheKey);
12438
+ if (!sedra) {
12439
+ sedra = new Sedra(hyear, il);
12440
+ sedraCache.set(cacheKey, sedra);
12441
+ }
12442
+ return sedra;
12443
+ }
12444
+
12445
+ const { HAVDALAH, CANDLE_LIGHTING } = holidayDesc;
12446
+ /**
12447
+ * Base class for events that have an associated wall-clock time and
12448
+ * geographic location — for example, candle lighting, havdalah, and
12449
+ * fast begin/end times.
12450
+ *
12451
+ * Stores both a `Date` (`eventTime`) and pre-formatted 24-hour
12452
+ * (`eventTimeStr`) and locale-aware (`fmtTime`) strings. May reference a
12453
+ * "linked" event such as the holiday whose candle-lighting time this
12454
+ * represents.
12455
+ */
12456
+ class TimedEvent extends Event {
12457
+ /**
12458
+ * Normally created by {@link calendar} rather than directly.
12459
+ * @param date Hebrew date the event occurs
12460
+ * @param desc Description (not translated)
12461
+ * @param mask optional holiday flags
12462
+ * @param eventTime the exact moment of the event
12463
+ * @param location geographic location used to format the time
12464
+ * @param linkedEvent optional event this time is associated with
12465
+ * @param options optional; `locale` and `hour12` affect {@link fmtTime}
12466
+ */
12467
+ constructor(date, desc, mask, eventTime, location, linkedEvent, options) {
12468
+ super(date, desc, mask);
12469
+ this.eventTime = Zmanim.roundTime(eventTime);
12470
+ this.location = location;
12471
+ const timeFormat = location.getTimeFormatter();
12472
+ this.eventTimeStr = Zmanim.formatTime(this.eventTime, timeFormat);
12473
+ const opts = { ...options, location };
12474
+ this.fmtTime = reformatTimeStr(this.eventTimeStr, 'pm', opts);
12475
+ if (linkedEvent !== undefined) {
12476
+ this.linkedEvent = linkedEvent;
12477
+ }
12478
+ }
12479
+ /**
12480
+ * @param [locale] Optional locale name (defaults to empty locale)
12481
+ */
12482
+ render(locale) {
12483
+ return `${Locale.gettext(this.getDesc(), locale)}: ${this.fmtTime}`;
12484
+ }
12485
+ /**
12486
+ * Returns translation of "Candle lighting" without the time.
12487
+ * @param [locale] Optional locale name (defaults to empty locale)
12488
+ */
12489
+ renderBrief(locale) {
12490
+ return Locale.gettext(this.getDesc(), locale);
12491
+ }
12492
+ getCategories() {
12493
+ const desc = this.getDesc();
12494
+ switch (desc) {
12495
+ // LIGHT_CANDLES or LIGHT_CANDLES_TZEIS
12496
+ case CANDLE_LIGHTING:
12497
+ return ['candles'];
12498
+ // YOM_TOV_ENDS
12499
+ case HAVDALAH:
12500
+ return ['havdalah'];
12501
+ // flags.MINOR_FAST or flags.MAJOR_FAST
12502
+ case holidayDesc.FAST_BEGINS:
12503
+ case holidayDesc.FAST_ENDS:
12504
+ return ['zmanim', 'fast'];
12505
+ case holidayDesc.SOF_ZMAN_ACHILAT_CHAMETZ:
12506
+ return ['zmanim', 'achilasChametz'];
12507
+ case holidayDesc.BIUR_CHAMETZ:
12508
+ return ['zmanim', 'biurChametz'];
12509
+ }
12510
+ /* NOTREACHED */
12511
+ return ['unknown'];
12512
+ }
12513
+ }
12514
+ /**
12515
+ * Candle-lighting event for the eve of Shabbat or a Yom Tov.
12516
+ *
12517
+ * Generated by {@link calendar} when `options.candlelighting`
12518
+ * is `true` and `options.location` is provided. By default candle lighting
12519
+ * occurs 18 minutes before sundown in the Diaspora and 20 minutes before
12520
+ * sundown in Israel (40 minutes in Jerusalem; 30 minutes in Haifa and
12521
+ * Zikhron Ya'akov), configurable via `options.candleLightingMins`.
12522
+ */
12523
+ class CandleLightingEvent extends TimedEvent {
12524
+ constructor(date, mask, eventTime, location, linkedEvent, options) {
12525
+ super(date, CANDLE_LIGHTING, mask, eventTime, location, linkedEvent, options);
12526
+ }
12527
+ getEmoji() {
12528
+ return '🕯️';
12529
+ }
12530
+ }
12531
+ /**
12532
+ * Havdalah event marking the end of Shabbat or a Yom Tov.
12464
12533
  *
12465
- * Prefer this over `new Sedra(...)` when calling repeatedly — an internal
12466
- * LRU cache (~120 entries) avoids recomputing the keviyah-specific schedule.
12467
- * @example
12468
- * import {getSedra, HDate, months} from '@hebcal/core';
12469
- * const sedra = getSedra(5784, false);
12470
- * const {parsha} = sedra.lookup(new HDate(15, months.CHESHVAN, 5784));
12471
- * console.log(parsha); // ['Vayera']
12472
- * @param hyear Hebrew year
12473
- * @param il Use Israel sedra schedule (`false` for Diaspora)
12534
+ * Generated by {@link calendar} when `options.candlelighting`
12535
+ * is `true` and `options.location` is provided. By default Havdalah is
12536
+ * calculated by *tzeit hakochavim* (8.5° solar depression); pass
12537
+ * `options.havdalahMins` to use a fixed minute offset instead, or
12538
+ * `options.havdalahDeg` to use a different degree.
12474
12539
  */
12475
- function getSedra(hyear, il) {
12476
- const cacheKey = `${hyear}-${il ? 1 : 0}`;
12477
- let sedra = sedraCache.get(cacheKey);
12478
- if (!sedra) {
12479
- sedra = new Sedra(hyear, il);
12480
- sedraCache.set(cacheKey, sedra);
12540
+ class HavdalahEvent extends TimedEvent {
12541
+ constructor(date, mask, eventTime, location, havdalahMins, linkedEvent, options) {
12542
+ super(date, HAVDALAH, mask, eventTime, location, linkedEvent, options);
12543
+ if (havdalahMins) {
12544
+ this.havdalahMins = havdalahMins;
12545
+ }
12546
+ }
12547
+ /**
12548
+ * @param [locale] Optional locale name (defaults to empty locale)
12549
+ */
12550
+ render(locale) {
12551
+ return `${this.renderBrief(locale)}: ${this.fmtTime}`;
12552
+ }
12553
+ /**
12554
+ * Returns translation of "Havdalah" without the time.
12555
+ * @param [locale] Optional locale name (defaults to empty locale)
12556
+ */
12557
+ renderBrief(locale) {
12558
+ let str = Locale.gettext(this.getDesc(), locale);
12559
+ if (this.havdalahMins) {
12560
+ const min = Locale.gettext('min', locale);
12561
+ str += ` (${this.havdalahMins} ${min})`;
12562
+ }
12563
+ return str;
12564
+ }
12565
+ getEmoji() {
12566
+ return '✨';
12481
12567
  }
12482
- return sedra;
12483
12568
  }
12484
12569
 
12485
12570
  const ykk = 'Yom Kippur Katan';
@@ -12577,18 +12662,82 @@ function addToMap(map, ...events) {
12577
12662
  const key = ev.date.toString();
12578
12663
  const arr = map.get(key);
12579
12664
  if (arr !== undefined) {
12580
- if (arr[0].hasFlag('EREV')) {
12581
- arr.unshift(ev);
12582
- }
12583
- else {
12584
- arr.push(ev);
12585
- }
12665
+ arr.push(ev);
12586
12666
  }
12587
12667
  else {
12588
12668
  map.set(key, [ev]);
12589
12669
  }
12590
12670
  }
12591
12671
  }
12672
+ /** @internal */
12673
+ const TIME_OF_DAY_DAWN = 0;
12674
+ /** @internal */
12675
+ const TIME_OF_DAY_MORNING = 1;
12676
+ /** @internal */
12677
+ const TIME_OF_DAY_MEVARCHIM = 2;
12678
+ /** @internal */
12679
+ const TIME_OF_DAY_DAY = 3;
12680
+ /** @internal */
12681
+ const TIME_OF_DAY_MIDDAY = 4;
12682
+ /** @internal */
12683
+ const TIME_OF_DAY_LEARNING = 5;
12684
+ /** @internal */
12685
+ const TIME_OF_DAY_EVENING = 6;
12686
+ /** @internal */
12687
+ const TIME_OF_DAY_NIGHT = 7;
12688
+ /**
12689
+ * Approximate time of day of an event, used to order events on the same date.
12690
+ * Events of equal rank keep the order in which they were created, and timed
12691
+ * events of equal rank are ordered by their time.
12692
+ * - Dawn: Fast begins for a minor fast, and a Latest Kiddush Levana before
12693
+ * noon (which is never later than _alot hashachar_)
12694
+ * - Morning: the parsha, special Shabbatot (tied to the Torah or Haftarah
12695
+ * reading), minor fasts (which begin at dawn) and Birkat Hachamah
12696
+ * (recited at sunrise)
12697
+ * - Molad and Shabbat Mevarchim, announced in synagogue after the Torah
12698
+ * reading
12699
+ * - Day: everything else, including Yizkor and the Omer count
12700
+ * - Midday: the deadlines for eating and burning chametz
12701
+ * - Daily learning
12702
+ * - Evening: Erev holidays, Chanukah candle-lighting and Leil Selichot
12703
+ * - Night: other timed events such as candle-lighting, Havdalah,
12704
+ * Fast ends, and a Latest Kiddush Levana after noon
12705
+ * @internal
12706
+ */
12707
+ function timeOfDay(ev) {
12708
+ if (ev instanceof TimedEvent) {
12709
+ return timedEventTimeOfDay(ev);
12710
+ }
12711
+ const desc = ev.getDesc();
12712
+ if (ev.hasAnyFlag('EREV', 'CHANUKAH_CANDLES') || desc === holidayDesc.LEIL_SELICHOT) {
12713
+ return TIME_OF_DAY_EVENING;
12714
+ }
12715
+ if (ev.hasAnyFlag('PARSHA_HASHAVUA', 'SPECIAL_SHABBAT', 'MINOR_FAST') ||
12716
+ desc === holidayDesc.BIRKAT_HACHAMAH) {
12717
+ return TIME_OF_DAY_MORNING;
12718
+ }
12719
+ if (ev.hasAnyFlag('SHABBAT_MEVARCHIM', 'MOLAD')) {
12720
+ return TIME_OF_DAY_MEVARCHIM;
12721
+ }
12722
+ if (ev.hasAnyFlag('DAILY_LEARNING', 'DAF_YOMI', 'MISHNA_YOMI', 'NACH_YOMI', 'YERUSHALMI_YOMI')) {
12723
+ return TIME_OF_DAY_LEARNING;
12724
+ }
12725
+ return TIME_OF_DAY_DAY;
12726
+ }
12727
+ function timedEventTimeOfDay(ev) {
12728
+ const desc = ev.getDesc();
12729
+ if (desc === holidayDesc.SOF_ZMAN_ACHILAT_CHAMETZ || desc === holidayDesc.BIUR_CHAMETZ) {
12730
+ return TIME_OF_DAY_MIDDAY;
12731
+ }
12732
+ // A minor fast begins at dawn, but Tish'a B'Av at sunset the day before.
12733
+ // Latest Kiddush Levana is either before dawn or after nightfall.
12734
+ if (desc === holidayDesc.FAST_BEGINS || ev.hasFlag('KIDDUSH_LEVANA')) {
12735
+ // `eventTimeStr` is 24-hour local time; some engines format midnight as 24:00
12736
+ const hour = Number.parseInt(ev.eventTimeStr, 10) % 24;
12737
+ return hour < 12 ? TIME_OF_DAY_DAWN : TIME_OF_DAY_NIGHT;
12738
+ }
12739
+ return TIME_OF_DAY_NIGHT;
12740
+ }
12592
12741
  function addStaticHolidays(map, year) {
12593
12742
  for (const h of staticHolidays) {
12594
12743
  const hd = new HDate(h.dd, h.mm, year);
@@ -12757,6 +12906,9 @@ function getHolidaysForYear_(year) {
12757
12906
  const hd = new HDate(birkatHaChama);
12758
12907
  addToMap(map, new HolidayEvent(hd, holidayDesc.BIRKAT_HACHAMAH, MINOR_HOLIDAY$1, { emoji: '☀️' }));
12759
12908
  }
12909
+ for (const arr of map.values()) {
12910
+ arr.sort((a, b) => timeOfDay(a) - timeOfDay(b));
12911
+ }
12760
12912
  yearCache.set(year, map);
12761
12913
  return map;
12762
12914
  }
@@ -12961,131 +13113,6 @@ function isFastDay(date, il) {
12961
13113
  return events.some(ev => ev.hasAnyFlag('MAJOR_FAST', 'MINOR_FAST') && !ev.hasFlag('EREV'));
12962
13114
  }
12963
13115
 
12964
- const { HAVDALAH, CANDLE_LIGHTING } = holidayDesc;
12965
- /**
12966
- * Base class for events that have an associated wall-clock time and
12967
- * geographic location — for example, candle lighting, havdalah, and
12968
- * fast begin/end times.
12969
- *
12970
- * Stores both a `Date` (`eventTime`) and pre-formatted 24-hour
12971
- * (`eventTimeStr`) and locale-aware (`fmtTime`) strings. May reference a
12972
- * "linked" event such as the holiday whose candle-lighting time this
12973
- * represents.
12974
- */
12975
- class TimedEvent extends Event {
12976
- /**
12977
- * Normally created by {@link calendar} rather than directly.
12978
- * @param date Hebrew date the event occurs
12979
- * @param desc Description (not translated)
12980
- * @param mask optional holiday flags
12981
- * @param eventTime the exact moment of the event
12982
- * @param location geographic location used to format the time
12983
- * @param linkedEvent optional event this time is associated with
12984
- * @param options optional; `locale` and `hour12` affect {@link fmtTime}
12985
- */
12986
- constructor(date, desc, mask, eventTime, location, linkedEvent, options) {
12987
- super(date, desc, mask);
12988
- this.eventTime = Zmanim.roundTime(eventTime);
12989
- this.location = location;
12990
- const timeFormat = location.getTimeFormatter();
12991
- this.eventTimeStr = Zmanim.formatTime(this.eventTime, timeFormat);
12992
- const opts = { ...options, location };
12993
- this.fmtTime = reformatTimeStr(this.eventTimeStr, 'pm', opts);
12994
- if (linkedEvent !== undefined) {
12995
- this.linkedEvent = linkedEvent;
12996
- }
12997
- }
12998
- /**
12999
- * @param [locale] Optional locale name (defaults to empty locale)
13000
- */
13001
- render(locale) {
13002
- return `${Locale.gettext(this.getDesc(), locale)}: ${this.fmtTime}`;
13003
- }
13004
- /**
13005
- * Returns translation of "Candle lighting" without the time.
13006
- * @param [locale] Optional locale name (defaults to empty locale)
13007
- */
13008
- renderBrief(locale) {
13009
- return Locale.gettext(this.getDesc(), locale);
13010
- }
13011
- getCategories() {
13012
- const desc = this.getDesc();
13013
- switch (desc) {
13014
- // LIGHT_CANDLES or LIGHT_CANDLES_TZEIS
13015
- case CANDLE_LIGHTING:
13016
- return ['candles'];
13017
- // YOM_TOV_ENDS
13018
- case HAVDALAH:
13019
- return ['havdalah'];
13020
- // flags.MINOR_FAST or flags.MAJOR_FAST
13021
- case holidayDesc.FAST_BEGINS:
13022
- case holidayDesc.FAST_ENDS:
13023
- return ['zmanim', 'fast'];
13024
- case holidayDesc.SOF_ZMAN_ACHILAT_CHAMETZ:
13025
- return ['zmanim', 'achilasChametz'];
13026
- case holidayDesc.BIUR_CHAMETZ:
13027
- return ['zmanim', 'biurChametz'];
13028
- }
13029
- /* NOTREACHED */
13030
- return ['unknown'];
13031
- }
13032
- }
13033
- /**
13034
- * Candle-lighting event for the eve of Shabbat or a Yom Tov.
13035
- *
13036
- * Generated by {@link calendar} when `options.candlelighting`
13037
- * is `true` and `options.location` is provided. By default candle lighting
13038
- * occurs 18 minutes before sundown in the Diaspora and 20 minutes before
13039
- * sundown in Israel (40 minutes in Jerusalem; 30 minutes in Haifa and
13040
- * Zikhron Ya'akov), configurable via `options.candleLightingMins`.
13041
- */
13042
- class CandleLightingEvent extends TimedEvent {
13043
- constructor(date, mask, eventTime, location, linkedEvent, options) {
13044
- super(date, CANDLE_LIGHTING, mask, eventTime, location, linkedEvent, options);
13045
- }
13046
- getEmoji() {
13047
- return '🕯️';
13048
- }
13049
- }
13050
- /**
13051
- * Havdalah event marking the end of Shabbat or a Yom Tov.
13052
- *
13053
- * Generated by {@link calendar} when `options.candlelighting`
13054
- * is `true` and `options.location` is provided. By default Havdalah is
13055
- * calculated by *tzeit hakochavim* (8.5° solar depression); pass
13056
- * `options.havdalahMins` to use a fixed minute offset instead, or
13057
- * `options.havdalahDeg` to use a different degree.
13058
- */
13059
- class HavdalahEvent extends TimedEvent {
13060
- constructor(date, mask, eventTime, location, havdalahMins, linkedEvent, options) {
13061
- super(date, HAVDALAH, mask, eventTime, location, linkedEvent, options);
13062
- if (havdalahMins) {
13063
- this.havdalahMins = havdalahMins;
13064
- }
13065
- }
13066
- /**
13067
- * @param [locale] Optional locale name (defaults to empty locale)
13068
- */
13069
- render(locale) {
13070
- return `${this.renderBrief(locale)}: ${this.fmtTime}`;
13071
- }
13072
- /**
13073
- * Returns translation of "Havdalah" without the time.
13074
- * @param [locale] Optional locale name (defaults to empty locale)
13075
- */
13076
- renderBrief(locale) {
13077
- let str = Locale.gettext(this.getDesc(), locale);
13078
- if (this.havdalahMins) {
13079
- const min = Locale.gettext('min', locale);
13080
- str += ` (${this.havdalahMins} ${min})`;
13081
- }
13082
- return str;
13083
- }
13084
- getEmoji() {
13085
- return '✨';
13086
- }
13087
- }
13088
-
13089
13116
  const { LIGHT_CANDLES: LIGHT_CANDLES$1, LIGHT_CANDLES_TZEIS: LIGHT_CANDLES_TZEIS$1 } = flags;
13090
13117
  const { FAST_BEGINS, FAST_ENDS } = holidayDesc;
13091
13118
  /** @internal */
@@ -14522,6 +14549,16 @@ class MevarchimChodeshEvent extends Event {
14522
14549
  * * `options.addHebrewDates` - print the Hebrew date for the entire date range
14523
14550
  * * `options.addHebrewDatesForEvents` - print the Hebrew date for dates with some events
14524
14551
  *
14552
+ * Events are returned in date order. Events on the same date are ordered by
14553
+ * approximate time of day: timed events before dawn (Fast begins, an early
14554
+ * Latest Kiddush Levana), then the parsha, special Shabbatot and minor fasts,
14555
+ * then the Molad and Shabbat Mevarchim, then other holidays, Yizkor and the
14556
+ * Omer, then the chametz deadlines on Erev Pesach, then daily learning, then
14557
+ * evening holidays (Erev holidays, Chanukah), and finally the remaining timed
14558
+ * events (candle-lighting, Havdalah, Fast ends) in order of time. When
14559
+ * `options.addHebrewDates` or `options.addHebrewDatesForEvents` adds a Hebrew
14560
+ * date event, it comes first.
14561
+ *
14525
14562
  * Lastly, translation and transliteration of event titles is controlled by
14526
14563
  * `options.locale` and the {@link Locale} API.
14527
14564
  * `@hebcal/core` supports three locales by default:
@@ -14612,6 +14649,15 @@ function calendar(options = {}) {
14612
14649
  let candlesEv;
14613
14650
  const holidays0 = holidaysYear.get(hd.toString()) || [];
14614
14651
  const holidays = holidays0.filter(ev => ev.observedIn(il));
14652
+ if (options.sedrot && isSaturday) {
14653
+ const parsha0 = sedra.lookup(abs);
14654
+ if (!parsha0.chag) {
14655
+ evts.push(new ParshaEvent(parsha0));
14656
+ }
14657
+ }
14658
+ if (isSaturday && (options.molad || options.shabbatMevarchim)) {
14659
+ evts.push(...makeMoladAndMevarchimChodesh(hd, options));
14660
+ }
14615
14661
  for (const ev of holidays) {
14616
14662
  candlesEv = appendHolidayAndRelated(candlesEv, evts, ev, options, isFriday, isSaturday, hasUserMask);
14617
14663
  }
@@ -14624,12 +14670,6 @@ function calendar(options = {}) {
14624
14670
  evts.push(biurEv);
14625
14671
  }
14626
14672
  }
14627
- if (options.sedrot && isSaturday) {
14628
- const parsha0 = sedra.lookup(abs);
14629
- if (!parsha0.chag) {
14630
- evts.push(new ParshaEvent(parsha0));
14631
- }
14632
- }
14633
14673
  if (options.yizkor) {
14634
14674
  if ((mm === months.TISHREI && (dd === 10 || dd === 22)) ||
14635
14675
  (mm === NISAN && dd === (il ? 21 : 22)) ||
@@ -14656,22 +14696,6 @@ function calendar(options = {}) {
14656
14696
  const omerEv = makeOmerEvent(hd, omer, options);
14657
14697
  evts.push(omerEv);
14658
14698
  }
14659
- if (isSaturday && (options.molad || options.shabbatMevarchim)) {
14660
- const events = makeMoladAndMevarchimChodesh(hd, options);
14661
- evts.push(...events);
14662
- }
14663
- if (options.kiddushLevanaMaharil && dd >= 9 && dd <= 17) {
14664
- // The event usually falls between the 11th and the 16th, but may be
14665
- // moved back to candle-lighting before a Shabbat or Yom Tov
14666
- const monthKey = hyear * 100 + mm;
14667
- if (monthKey !== kiddushLevanaMonth) {
14668
- kiddushLevanaMonth = monthKey;
14669
- kiddushLevanaEv = makeKiddushLevanaEvent(hyear, mm, options);
14670
- }
14671
- if (kiddushLevanaEv?.getDate().abs() === abs) {
14672
- evts.push(kiddushLevanaEv);
14673
- }
14674
- }
14675
14699
  if (!candlesEv && options.candlelighting && (isFriday || isSaturday)) {
14676
14700
  candlesEv = makeCandleEvent(undefined, hd, options, isFriday, isSaturday);
14677
14701
  if (isFriday && candlesEv && sedra) {
@@ -14693,6 +14717,19 @@ function calendar(options = {}) {
14693
14717
  if (candlesEv) {
14694
14718
  evts.push(candlesEv);
14695
14719
  }
14720
+ if (options.kiddushLevanaMaharil && dd >= 9 && dd <= 17) {
14721
+ // The event usually falls between the 11th and the 16th, but may be
14722
+ // moved back to candle-lighting before a Shabbat or Yom Tov
14723
+ const monthKey = hyear * 100 + mm;
14724
+ if (monthKey !== kiddushLevanaMonth) {
14725
+ kiddushLevanaMonth = monthKey;
14726
+ kiddushLevanaEv = makeKiddushLevanaEvent(hyear, mm, options);
14727
+ }
14728
+ if (kiddushLevanaEv?.getDate().abs() === abs) {
14729
+ evts.push(kiddushLevanaEv);
14730
+ }
14731
+ }
14732
+ sortByTimeOfDay(evts, prevEventsLength);
14696
14733
  if (options.addHebrewDates ||
14697
14734
  (options.addHebrewDatesForEvents &&
14698
14735
  prevEventsLength !== evts.length - numDailyLearning)) {
@@ -14998,6 +15035,29 @@ function setOptionsFromMask(options) {
14998
15035
  options.kiddushLevanaMaharil = true;
14999
15036
  return m;
15000
15037
  }
15038
+ function compareTimeOfDay(a, b) {
15039
+ const diff = timeOfDay(a) - timeOfDay(b);
15040
+ if (diff !== 0) {
15041
+ return diff;
15042
+ }
15043
+ if (a instanceof TimedEvent && b instanceof TimedEvent) {
15044
+ return a.eventTime.getTime() - b.eventTime.getTime();
15045
+ }
15046
+ return 0;
15047
+ }
15048
+ /**
15049
+ * Sorts today's events (those at index `start` and beyond) in place by
15050
+ * {@link timeOfDay}. The sort is stable, so events of equal rank keep the
15051
+ * order in which they were added, e.g. Yizkor after its holiday.
15052
+ */
15053
+ function sortByTimeOfDay(events, start) {
15054
+ if (events.length - start < 2) {
15055
+ return;
15056
+ }
15057
+ const today = events.splice(start);
15058
+ today.sort(compareTimeOfDay);
15059
+ events.push(...today);
15060
+ }
15001
15061
  /**
15002
15062
  * Appends the Event `ev` to the `events` array. Also may add related
15003
15063
  * timed events like candle-lighting or fast start/end