'use strict';

var slicedToArray = require('../slicedToArray-BcL7fKuL.js');
var defineProperty = require('../defineProperty-lChFfVqi.js');
require('../unsupportedIterableToArray-BoHMiKNA.js');
require('../typeof-D4ZZ_FlZ.js');

function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), true).forEach(function (r) { defineProperty._defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
/* eslint-disable */
// Temporary patch file. We can remove this file after the issue is fixed in Day.js.
// Ref: https://github.com/iamkun/dayjs/pull/2019

var typeToPos = {
  year: 0,
  month: 1,
  day: 2,
  hour: 3,
  minute: 4,
  second: 5
};
var dateTimeFormatDefaults = {
  year: "numeric",
  month: "2-digit",
  day: "2-digit",
  hour: "2-digit",
  minute: "2-digit",
  second: "2-digit"
};

// Timezone alias map for fallback support
// Maps newer timezone names to older/alternative names for browser compatibility
var timezoneAliases = {
  "Europe/Kyiv": "Europe/Kiev"
};
var getTimezoneAlias = function getTimezoneAlias(timezone) {
  return timezoneAliases[timezone] || null;
};

// Cache time-zone lookups from Intl.DateTimeFormat,
// as it is a *very* slow method.
var dtfCache = {};
var localeStringifierCache = {};
var getCachedIntlFormatter = function getCachedIntlFormatter(timezone, cache, getCacheKey, formatOptions) {
  var cacheKey = getCacheKey(timezone);
  var dtf = cache[cacheKey];
  if (dtf) return dtf;
  try {
    dtf = new Intl.DateTimeFormat("en-US", _objectSpread(_objectSpread(_objectSpread({}, dateTimeFormatDefaults), formatOptions), {}, {
      timeZone: timezone
    }));
    cache[cacheKey] = dtf;
    return dtf;
  } catch (error) {
    // Fallback for unsupported timezones using alias map
    var fallbackTimezone = getTimezoneAlias(timezone);
    if (!fallbackTimezone) throw error;
    var fallbackKey = getCacheKey(fallbackTimezone);
    dtf = cache[fallbackKey];
    if (dtf) return dtf;
    dtf = new Intl.DateTimeFormat("en-US", _objectSpread(_objectSpread(_objectSpread({}, dateTimeFormatDefaults), formatOptions), {}, {
      timeZone: fallbackTimezone
    }));
    cache[fallbackKey] = dtf;
    return dtf;
  }
};
var getDateTimeFormat = function getDateTimeFormat(timezone) {
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  var timeZoneName = options.timeZoneName || "short";
  return getCachedIntlFormatter(timezone, dtfCache, function (tz) {
    return "".concat(tz, "|").concat(timeZoneName);
  }, {
    hour12: false,
    timeZoneName: timeZoneName
  });
};
var getLocaleStringifier = function getLocaleStringifier(timezone) {
  return getCachedIntlFormatter(timezone, localeStringifierCache, function (tz) {
    return tz;
  }, {});
};
var timezone = (function (o, c, d) {
  var defaultTimezone;
  var makeFormatParts = function makeFormatParts(timestamp, timezone) {
    var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
    var date = new Date(timestamp);
    var dtf = getDateTimeFormat(timezone, options);
    return dtf.formatToParts(date);
  };
  var tzOffset = function tzOffset(timestamp, timezone) {
    var formatResult = makeFormatParts(timestamp, timezone);
    var filled = [];
    for (var i = 0; i < formatResult.length; i += 1) {
      var _formatResult$i = formatResult[i],
        type = _formatResult$i.type,
        value = _formatResult$i.value;
      var pos = typeToPos[type];
      if (pos >= 0) {
        filled[pos] = parseInt(value, 10);
      }
    }
    var hour = filled[3];
    // Workaround for the same behavior in different node version
    // https://github.com/nodejs/node/issues/33027
    /* istanbul ignore next */
    var fixedHour = hour === 24 ? 0 : hour;
    var utcString = "".concat(filled[0], "-").concat(filled[1], "-").concat(filled[2], " ").concat(fixedHour, ":").concat(filled[4], ":").concat(filled[5], ":000");
    var utcTs = d.utc(utcString).valueOf();
    var asTS = Number(timestamp);
    var over = asTS % 1000;
    asTS -= over;
    return (utcTs - asTS) / (60 * 1000);
  };

  // find the right offset a given local time. The o input is our guess, which determines which
  // offset we'll pick in ambiguous cases (e.g. there are two 3 AMs b/c Fallback DST)
  // https://github.com/moment/luxon/blob/master/src/datetime.js#L76
  var fixOffset = function fixOffset(localTS, o0, tz) {
    // Our UTC time is just a guess because our offset is just a guess
    var utcGuess = localTS - o0 * 60 * 1000;
    // Test whether the zone matches the offset for this ts
    var o2 = tzOffset(utcGuess, tz);
    // If so, offset didn't change and we're done
    if (o0 === o2) {
      return [utcGuess, o0];
    }
    // If not, change the ts by the difference in the offset
    utcGuess -= (o2 - o0) * 60 * 1000;
    // If that gives us the local time we want, we're done
    var o3 = tzOffset(utcGuess, tz);
    if (o2 === o3) {
      return [utcGuess, o2];
    }

    // If it's different, we're in a hole time.
    // The offset has changed, but the we don't adjust the time
    return [localTS - Math.min(o2, o3) * 60 * 1000, Math.max(o2, o3)];
  };
  var proto = c.prototype;
  proto.tz = function () {
    var timezone = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultTimezone;
    var keepLocalTime = arguments.length > 1 ? arguments[1] : undefined;
    var oldOffset = this.utcOffset();
    var date = this.toDate();
    if (!Number.isFinite(date.getTime())) return this.clone();
    var target = getLocaleStringifier(timezone).format(date);
    var diff = Math.round((date - new Date(target)) / 1000 / 60);
    var ins = d(target).$set("millisecond", this.$ms).utcOffset(-Math.round(date.getTimezoneOffset() / 15) * 15 - diff, true);
    if (keepLocalTime) {
      var newOffset = ins.utcOffset();
      ins = ins.add(oldOffset - newOffset, "minute");
    }
    ins.$x.$timezone = timezone;
    return ins;
  };
  proto.offsetName = function (type) {
    // type: short(default) / long
    var zone = this.$x.$timezone || d.tz.guess();
    var result = makeFormatParts(this.valueOf(), zone, {
      timeZoneName: type
    }).find(function (m) {
      return m.type.toLowerCase() === "timezonename";
    });
    return result && result.value;
  };
  var oldStartOf = proto.startOf;
  proto.startOf = function (units, startOf) {
    if (!this.$x || !this.$x.$timezone) {
      return oldStartOf.call(this, units, startOf);
    }
    var withoutTz = d(this.format("YYYY-MM-DD HH:mm:ss:SSS"));
    var startOfWithoutTz = oldStartOf.call(withoutTz, units, startOf);
    return startOfWithoutTz.tz(this.$x.$timezone, true);
  };
  d.tz = function (input, arg1, arg2) {
    var parseFormat = arg2 && arg1;
    var timezone = arg2 || arg1 || defaultTimezone;
    var previousOffset = tzOffset(Number(d()), timezone);
    if (typeof input !== "string") {
      // timestamp number || js Date || Day.js
      return d(input).tz(timezone);
    }
    var localTs = d.utc(input, parseFormat).valueOf();
    if (!Number.isFinite(localTs)) return d(localTs);
    var _fixOffset = fixOffset(localTs, previousOffset, timezone),
      _fixOffset2 = slicedToArray._slicedToArray(_fixOffset, 2),
      targetTs = _fixOffset2[0],
      targetOffset = _fixOffset2[1];
    var ins = d(targetTs).utcOffset(targetOffset);
    ins.$x.$timezone = timezone;
    return ins;
  };
  d.tz.guess = function () {
    try {
      return Intl.DateTimeFormat().resolvedOptions().timeZone;
    } catch (e) {
      // To prevent crashes in environments with restricted or broken Intl API support.
      return "UTC";
    }
  };
  d.tz.setDefault = function (timezone) {
    defaultTimezone = timezone;
  };
});

module.exports = timezone;
//# sourceMappingURL=timezonePlugin.js.map
