{"version":3,"file":"index.cjs","sources":["../node_modules/react-usestateref/dist/index.js","../node_modules/date-fns/constants.js","../node_modules/date-fns/constructFrom.js","../node_modules/date-fns/toDate.js","../node_modules/date-fns/_lib/defaultOptions.js","../node_modules/date-fns/_lib/getTimezoneOffsetInMilliseconds.js","../node_modules/date-fns/_lib/normalizeDates.js","../node_modules/date-fns/compareAsc.js","../node_modules/date-fns/isLastDayOfMonth.js","../node_modules/date-fns/endOfDay.js","../node_modules/date-fns/endOfMonth.js","../node_modules/date-fns/differenceInMonths.js","../node_modules/date-fns/differenceInCalendarMonths.js","../node_modules/date-fns/differenceInSeconds.js","../node_modules/date-fns/differenceInMilliseconds.js","../node_modules/date-fns/_lib/getRoundingMethod.js","../node_modules/date-fns/locale/en-US/_lib/formatDistance.js","../node_modules/date-fns/locale/_lib/buildFormatLongFn.js","../node_modules/date-fns/locale/en-US/_lib/formatLong.js","../node_modules/date-fns/locale/en-US/_lib/formatRelative.js","../node_modules/date-fns/locale/_lib/buildLocalizeFn.js","../node_modules/date-fns/locale/_lib/buildMatchFn.js","../node_modules/date-fns/locale/_lib/buildMatchPatternFn.js","../node_modules/date-fns/locale/en-US.js","../node_modules/date-fns/locale/en-US/_lib/localize.js","../node_modules/date-fns/locale/en-US/_lib/match.js","../node_modules/date-fns/formatDistanceToNow.js","../node_modules/date-fns/formatDistance.js","../node_modules/date-fns/constructNow.js","../src/types/index.ts","../src/hooks/useBlockList.ts","../src/helpers.ts","../src/hooks/useUsers.ts","../src/ChatContext.tsx","../src/hooks/useNetworkStatus.ts"],"sourcesContent":["\"use strict\";\nvar react_1 = require(\"react\");\nvar isFunction = function (setStateAction) {\n    return typeof setStateAction === \"function\";\n};\nvar useStateRef = function (initialState) {\n    var _a = react_1.useState(initialState), state = _a[0], setState = _a[1];\n    var ref = react_1.useRef(state);\n    var dispatch = react_1.useCallback(function (setStateAction) {\n        ref.current = isFunction(setStateAction) ? setStateAction(ref.current) : setStateAction;\n        setState(ref.current);\n    }, []);\n    return [state, dispatch, ref];\n};\nmodule.exports = useStateRef;\n","/**\n * @module constants\n * @summary Useful constants\n * @description\n * Collection of useful date constants.\n *\n * The constants could be imported from `date-fns/constants`:\n *\n * ```ts\n * import { maxTime, minTime } from \"./constants/date-fns/constants\";\n *\n * function isAllowedTime(time) {\n *   return time <= maxTime && time >= minTime;\n * }\n * ```\n */\n\n/**\n * @constant\n * @name daysInWeek\n * @summary Days in 1 week.\n */\nexport const daysInWeek = 7;\n\n/**\n * @constant\n * @name daysInYear\n * @summary Days in 1 year.\n *\n * @description\n * How many days in a year.\n *\n * One years equals 365.2425 days according to the formula:\n *\n * > Leap year occurs every 4 years, except for years that are divisible by 100 and not divisible by 400.\n * > 1 mean year = (365+1/4-1/100+1/400) days = 365.2425 days\n */\nexport const daysInYear = 365.2425;\n\n/**\n * @constant\n * @name maxTime\n * @summary Maximum allowed time.\n *\n * @example\n * import { maxTime } from \"./constants/date-fns/constants\";\n *\n * const isValid = 8640000000000001 <= maxTime;\n * //=> false\n *\n * new Date(8640000000000001);\n * //=> Invalid Date\n */\nexport const maxTime = Math.pow(10, 8) * 24 * 60 * 60 * 1000;\n\n/**\n * @constant\n * @name minTime\n * @summary Minimum allowed time.\n *\n * @example\n * import { minTime } from \"./constants/date-fns/constants\";\n *\n * const isValid = -8640000000000001 >= minTime;\n * //=> false\n *\n * new Date(-8640000000000001)\n * //=> Invalid Date\n */\nexport const minTime = -maxTime;\n\n/**\n * @constant\n * @name millisecondsInWeek\n * @summary Milliseconds in 1 week.\n */\nexport const millisecondsInWeek = 604800000;\n\n/**\n * @constant\n * @name millisecondsInDay\n * @summary Milliseconds in 1 day.\n */\nexport const millisecondsInDay = 86400000;\n\n/**\n * @constant\n * @name millisecondsInMinute\n * @summary Milliseconds in 1 minute\n */\nexport const millisecondsInMinute = 60000;\n\n/**\n * @constant\n * @name millisecondsInHour\n * @summary Milliseconds in 1 hour\n */\nexport const millisecondsInHour = 3600000;\n\n/**\n * @constant\n * @name millisecondsInSecond\n * @summary Milliseconds in 1 second\n */\nexport const millisecondsInSecond = 1000;\n\n/**\n * @constant\n * @name minutesInYear\n * @summary Minutes in 1 year.\n */\nexport const minutesInYear = 525600;\n\n/**\n * @constant\n * @name minutesInMonth\n * @summary Minutes in 1 month.\n */\nexport const minutesInMonth = 43200;\n\n/**\n * @constant\n * @name minutesInDay\n * @summary Minutes in 1 day.\n */\nexport const minutesInDay = 1440;\n\n/**\n * @constant\n * @name minutesInHour\n * @summary Minutes in 1 hour.\n */\nexport const minutesInHour = 60;\n\n/**\n * @constant\n * @name monthsInQuarter\n * @summary Months in 1 quarter.\n */\nexport const monthsInQuarter = 3;\n\n/**\n * @constant\n * @name monthsInYear\n * @summary Months in 1 year.\n */\nexport const monthsInYear = 12;\n\n/**\n * @constant\n * @name quartersInYear\n * @summary Quarters in 1 year\n */\nexport const quartersInYear = 4;\n\n/**\n * @constant\n * @name secondsInHour\n * @summary Seconds in 1 hour.\n */\nexport const secondsInHour = 3600;\n\n/**\n * @constant\n * @name secondsInMinute\n * @summary Seconds in 1 minute.\n */\nexport const secondsInMinute = 60;\n\n/**\n * @constant\n * @name secondsInDay\n * @summary Seconds in 1 day.\n */\nexport const secondsInDay = secondsInHour * 24;\n\n/**\n * @constant\n * @name secondsInWeek\n * @summary Seconds in 1 week.\n */\nexport const secondsInWeek = secondsInDay * 7;\n\n/**\n * @constant\n * @name secondsInYear\n * @summary Seconds in 1 year.\n */\nexport const secondsInYear = secondsInDay * daysInYear;\n\n/**\n * @constant\n * @name secondsInMonth\n * @summary Seconds in 1 month\n */\nexport const secondsInMonth = secondsInYear / 12;\n\n/**\n * @constant\n * @name secondsInQuarter\n * @summary Seconds in 1 quarter.\n */\nexport const secondsInQuarter = secondsInMonth * 3;\n\n/**\n * @constant\n * @name constructFromSymbol\n * @summary Symbol enabling Date extensions to inherit properties from the reference date.\n *\n * The symbol is used to enable the `constructFrom` function to construct a date\n * using a reference date and a value. It allows to transfer extra properties\n * from the reference date to the new date. It's useful for extensions like\n * [`TZDate`](https://github.com/date-fns/tz) that accept a time zone as\n * a constructor argument.\n */\nexport const constructFromSymbol = Symbol.for(\"constructDateFrom\");\n","import { constructFromSymbol } from \"./constants.js\";\n\n/**\n * @name constructFrom\n * @category Generic Helpers\n * @summary Constructs a date using the reference date and the value\n *\n * @description\n * The function constructs a new date using the constructor from the reference\n * date and the given value. It helps to build generic functions that accept\n * date extensions.\n *\n * It defaults to `Date` if the passed reference date is a number or a string.\n *\n * Starting from v3.7.0, it allows to construct a date using `[Symbol.for(\"constructDateFrom\")]`\n * enabling to transfer extra properties from the reference date to the new date.\n * It's useful for extensions like [`TZDate`](https://github.com/date-fns/tz)\n * that accept a time zone as a constructor argument.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n *\n * @param date - The reference date to take constructor from\n * @param value - The value to create the date\n *\n * @returns Date initialized using the given date and value\n *\n * @example\n * import { constructFrom } from \"./constructFrom/date-fns\";\n *\n * // A function that clones a date preserving the original type\n * function cloneDate<DateType extends Date>(date: DateType): DateType {\n *   return constructFrom(\n *     date, // Use constructor from the given date\n *     date.getTime() // Use the date value to create a new date\n *   );\n * }\n */\nexport function constructFrom(date, value) {\n  if (typeof date === \"function\") return date(value);\n\n  if (date && typeof date === \"object\" && constructFromSymbol in date)\n    return date[constructFromSymbol](value);\n\n  if (date instanceof Date) return new date.constructor(value);\n\n  return new Date(value);\n}\n\n// Fallback for modularized imports:\nexport default constructFrom;\n","import { constructFrom } from \"./constructFrom.js\";\n\n/**\n * @name toDate\n * @category Common Helpers\n * @summary Convert the given argument to an instance of Date.\n *\n * @description\n * Convert the given argument to an instance of Date.\n *\n * If the argument is an instance of Date, the function returns its clone.\n *\n * If the argument is a number, it is treated as a timestamp.\n *\n * If the argument is none of the above, the function returns Invalid Date.\n *\n * Starting from v3.7.0, it clones a date using `[Symbol.for(\"constructDateFrom\")]`\n * enabling to transfer extra properties from the reference date to the new date.\n * It's useful for extensions like [`TZDate`](https://github.com/date-fns/tz)\n * that accept a time zone as a constructor argument.\n *\n * **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.\n *\n * @param argument - The value to convert\n *\n * @returns The parsed date in the local time zone\n *\n * @example\n * // Clone the date:\n * const result = toDate(new Date(2014, 1, 11, 11, 30, 30))\n * //=> Tue Feb 11 2014 11:30:30\n *\n * @example\n * // Convert the timestamp to date:\n * const result = toDate(1392098430000)\n * //=> Tue Feb 11 2014 11:30:30\n */\nexport function toDate(argument, context) {\n  // [TODO] Get rid of `toDate` or `constructFrom`?\n  return constructFrom(context || argument, argument);\n}\n\n// Fallback for modularized imports:\nexport default toDate;\n","let defaultOptions = {};\n\nexport function getDefaultOptions() {\n  return defaultOptions;\n}\n\nexport function setDefaultOptions(newOptions) {\n  defaultOptions = newOptions;\n}\n","import { toDate } from \"../toDate.js\";\n\n/**\n * Google Chrome as of 67.0.3396.87 introduced timezones with offset that includes seconds.\n * They usually appear for dates that denote time before the timezones were introduced\n * (e.g. for 'Europe/Prague' timezone the offset is GMT+00:57:44 before 1 October 1891\n * and GMT+01:00:00 after that date)\n *\n * Date#getTimezoneOffset returns the offset in minutes and would return 57 for the example above,\n * which would lead to incorrect calculations.\n *\n * This function returns the timezone offset in milliseconds that takes seconds in account.\n */\nexport function getTimezoneOffsetInMilliseconds(date) {\n  const _date = toDate(date);\n  const utcDate = new Date(\n    Date.UTC(\n      _date.getFullYear(),\n      _date.getMonth(),\n      _date.getDate(),\n      _date.getHours(),\n      _date.getMinutes(),\n      _date.getSeconds(),\n      _date.getMilliseconds(),\n    ),\n  );\n  utcDate.setUTCFullYear(_date.getFullYear());\n  return +date - +utcDate;\n}\n","import { constructFrom } from \"../constructFrom.js\";\n\nexport function normalizeDates(context, ...dates) {\n  const normalize = constructFrom.bind(\n    null,\n    context || dates.find((date) => typeof date === \"object\"),\n  );\n  return dates.map(normalize);\n}\n","import { toDate } from \"./toDate.js\";\n\n/**\n * @name compareAsc\n * @category Common Helpers\n * @summary Compare the two dates and return -1, 0 or 1.\n *\n * @description\n * Compare the two dates and return 1 if the first date is after the second,\n * -1 if the first date is before the second or 0 if dates are equal.\n *\n * @param dateLeft - The first date to compare\n * @param dateRight - The second date to compare\n *\n * @returns The result of the comparison\n *\n * @example\n * // Compare 11 February 1987 and 10 July 1989:\n * const result = compareAsc(new Date(1987, 1, 11), new Date(1989, 6, 10))\n * //=> -1\n *\n * @example\n * // Sort the array of dates:\n * const result = [\n *   new Date(1995, 6, 2),\n *   new Date(1987, 1, 11),\n *   new Date(1989, 6, 10)\n * ].sort(compareAsc)\n * //=> [\n * //   Wed Feb 11 1987 00:00:00,\n * //   Mon Jul 10 1989 00:00:00,\n * //   Sun Jul 02 1995 00:00:00\n * // ]\n */\nexport function compareAsc(dateLeft, dateRight) {\n  const diff = +toDate(dateLeft) - +toDate(dateRight);\n\n  if (diff < 0) return -1;\n  else if (diff > 0) return 1;\n\n  // Return 0 if diff is 0; return NaN if diff is NaN\n  return diff;\n}\n\n// Fallback for modularized imports:\nexport default compareAsc;\n","import { endOfDay } from \"./endOfDay.js\";\nimport { endOfMonth } from \"./endOfMonth.js\";\nimport { toDate } from \"./toDate.js\";\n\n/**\n * @name isLastDayOfMonth\n * @category Month Helpers\n * @summary Is the given date the last day of a month?\n *\n * @description\n * Is the given date the last day of a month?\n *\n * @param date - The date to check\n * @param options - An object with options\n *\n * @returns The date is the last day of a month\n *\n * @example\n * // Is 28 February 2014 the last day of a month?\n * const result = isLastDayOfMonth(new Date(2014, 1, 28))\n * //=> true\n */\nexport function isLastDayOfMonth(date, options) {\n  const _date = toDate(date, options?.in);\n  return +endOfDay(_date, options) === +endOfMonth(_date, options);\n}\n\n// Fallback for modularized imports:\nexport default isLastDayOfMonth;\n","import { toDate } from \"./toDate.js\";\n\n/**\n * The {@link endOfDay} function options.\n */\n\n/**\n * @name endOfDay\n * @category Day Helpers\n * @summary Return the end of a day for the given date.\n *\n * @description\n * Return the end of a day for the given date.\n * The result will be in the local timezone.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.\n *\n * @param date - The original date\n * @param options - An object with options\n *\n * @returns The end of a day\n *\n * @example\n * // The end of a day for 2 September 2014 11:55:00:\n * const result = endOfDay(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Tue Sep 02 2014 23:59:59.999\n */\nexport function endOfDay(date, options) {\n  const _date = toDate(date, options?.in);\n  _date.setHours(23, 59, 59, 999);\n  return _date;\n}\n\n// Fallback for modularized imports:\nexport default endOfDay;\n","import { toDate } from \"./toDate.js\";\n\n/**\n * The {@link endOfMonth} function options.\n */\n\n/**\n * @name endOfMonth\n * @category Month Helpers\n * @summary Return the end of a month for the given date.\n *\n * @description\n * Return the end of a month for the given date.\n * The result will be in the local timezone.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.\n *\n * @param date - The original date\n * @param options - An object with options\n *\n * @returns The end of a month\n *\n * @example\n * // The end of a month for 2 September 2014 11:55:00:\n * const result = endOfMonth(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Tue Sep 30 2014 23:59:59.999\n */\nexport function endOfMonth(date, options) {\n  const _date = toDate(date, options?.in);\n  const month = _date.getMonth();\n  _date.setFullYear(_date.getFullYear(), month + 1, 0);\n  _date.setHours(23, 59, 59, 999);\n  return _date;\n}\n\n// Fallback for modularized imports:\nexport default endOfMonth;\n","import { normalizeDates } from \"./_lib/normalizeDates.js\";\nimport { compareAsc } from \"./compareAsc.js\";\nimport { differenceInCalendarMonths } from \"./differenceInCalendarMonths.js\";\nimport { isLastDayOfMonth } from \"./isLastDayOfMonth.js\";\n\n/**\n * The {@link differenceInMonths} function options.\n */\n\n/**\n * @name differenceInMonths\n * @category Month Helpers\n * @summary Get the number of full months between the given dates.\n *\n * @param laterDate - The later date\n * @param earlierDate - The earlier date\n * @param options - An object with options\n *\n * @returns The number of full months\n *\n * @example\n * // How many full months are between 31 January 2014 and 1 September 2014?\n * const result = differenceInMonths(new Date(2014, 8, 1), new Date(2014, 0, 31))\n * //=> 7\n */\nexport function differenceInMonths(laterDate, earlierDate, options) {\n  const [laterDate_, workingLaterDate, earlierDate_] = normalizeDates(\n    options?.in,\n    laterDate,\n    laterDate,\n    earlierDate,\n  );\n\n  const sign = compareAsc(workingLaterDate, earlierDate_);\n  const difference = Math.abs(\n    differenceInCalendarMonths(workingLaterDate, earlierDate_),\n  );\n\n  if (difference < 1) return 0;\n\n  if (workingLaterDate.getMonth() === 1 && workingLaterDate.getDate() > 27)\n    workingLaterDate.setDate(30);\n\n  workingLaterDate.setMonth(workingLaterDate.getMonth() - sign * difference);\n\n  let isLastMonthNotFull = compareAsc(workingLaterDate, earlierDate_) === -sign;\n\n  if (\n    isLastDayOfMonth(laterDate_) &&\n    difference === 1 &&\n    compareAsc(laterDate_, earlierDate_) === 1\n  ) {\n    isLastMonthNotFull = false;\n  }\n\n  const result = sign * (difference - +isLastMonthNotFull);\n  return result === 0 ? 0 : result;\n}\n\n// Fallback for modularized imports:\nexport default differenceInMonths;\n","import { normalizeDates } from \"./_lib/normalizeDates.js\";\n\n/**\n * The {@link differenceInCalendarMonths} function options.\n */\n\n/**\n * @name differenceInCalendarMonths\n * @category Month Helpers\n * @summary Get the number of calendar months between the given dates.\n *\n * @description\n * Get the number of calendar months between the given dates.\n *\n * @param laterDate - The later date\n * @param earlierDate - The earlier date\n * @param options - An object with options\n *\n * @returns The number of calendar months\n *\n * @example\n * // How many calendar months are between 31 January 2014 and 1 September 2014?\n * const result = differenceInCalendarMonths(\n *   new Date(2014, 8, 1),\n *   new Date(2014, 0, 31)\n * )\n * //=> 8\n */\nexport function differenceInCalendarMonths(laterDate, earlierDate, options) {\n  const [laterDate_, earlierDate_] = normalizeDates(\n    options?.in,\n    laterDate,\n    earlierDate,\n  );\n\n  const yearsDiff = laterDate_.getFullYear() - earlierDate_.getFullYear();\n  const monthsDiff = laterDate_.getMonth() - earlierDate_.getMonth();\n\n  return yearsDiff * 12 + monthsDiff;\n}\n\n// Fallback for modularized imports:\nexport default differenceInCalendarMonths;\n","import { getRoundingMethod } from \"./_lib/getRoundingMethod.js\";\nimport { differenceInMilliseconds } from \"./differenceInMilliseconds.js\";\n\n/**\n * The {@link differenceInSeconds} function options.\n */\n\n/**\n * @name differenceInSeconds\n * @category Second Helpers\n * @summary Get the number of seconds between the given dates.\n *\n * @description\n * Get the number of seconds between the given dates.\n *\n * @param laterDate - The later date\n * @param earlierDate - The earlier date\n * @param options - An object with options.\n *\n * @returns The number of seconds\n *\n * @example\n * // How many seconds are between\n * // 2 July 2014 12:30:07.999 and 2 July 2014 12:30:20.000?\n * const result = differenceInSeconds(\n *   new Date(2014, 6, 2, 12, 30, 20, 0),\n *   new Date(2014, 6, 2, 12, 30, 7, 999)\n * )\n * //=> 12\n */\nexport function differenceInSeconds(laterDate, earlierDate, options) {\n  const diff = differenceInMilliseconds(laterDate, earlierDate) / 1000;\n  return getRoundingMethod(options?.roundingMethod)(diff);\n}\n\n// Fallback for modularized imports:\nexport default differenceInSeconds;\n","import { toDate } from \"./toDate.js\";\n\n/**\n * @name differenceInMilliseconds\n * @category Millisecond Helpers\n * @summary Get the number of milliseconds between the given dates.\n *\n * @description\n * Get the number of milliseconds between the given dates.\n *\n * @param laterDate - The later date\n * @param earlierDate - The earlier date\n *\n * @returns The number of milliseconds\n *\n * @example\n * // How many milliseconds are between\n * // 2 July 2014 12:30:20.600 and 2 July 2014 12:30:21.700?\n * const result = differenceInMilliseconds(\n *   new Date(2014, 6, 2, 12, 30, 21, 700),\n *   new Date(2014, 6, 2, 12, 30, 20, 600)\n * )\n * //=> 1100\n */\nexport function differenceInMilliseconds(laterDate, earlierDate) {\n  return +toDate(laterDate) - +toDate(earlierDate);\n}\n\n// Fallback for modularized imports:\nexport default differenceInMilliseconds;\n","export function getRoundingMethod(method) {\n  return (number) => {\n    const round = method ? Math[method] : Math.trunc;\n    const result = round(number);\n    // Prevent negative zero\n    return result === 0 ? 0 : result;\n  };\n}\n","const formatDistanceLocale = {\n  lessThanXSeconds: {\n    one: \"less than a second\",\n    other: \"less than {{count}} seconds\",\n  },\n\n  xSeconds: {\n    one: \"1 second\",\n    other: \"{{count}} seconds\",\n  },\n\n  halfAMinute: \"half a minute\",\n\n  lessThanXMinutes: {\n    one: \"less than a minute\",\n    other: \"less than {{count}} minutes\",\n  },\n\n  xMinutes: {\n    one: \"1 minute\",\n    other: \"{{count}} minutes\",\n  },\n\n  aboutXHours: {\n    one: \"about 1 hour\",\n    other: \"about {{count}} hours\",\n  },\n\n  xHours: {\n    one: \"1 hour\",\n    other: \"{{count}} hours\",\n  },\n\n  xDays: {\n    one: \"1 day\",\n    other: \"{{count}} days\",\n  },\n\n  aboutXWeeks: {\n    one: \"about 1 week\",\n    other: \"about {{count}} weeks\",\n  },\n\n  xWeeks: {\n    one: \"1 week\",\n    other: \"{{count}} weeks\",\n  },\n\n  aboutXMonths: {\n    one: \"about 1 month\",\n    other: \"about {{count}} months\",\n  },\n\n  xMonths: {\n    one: \"1 month\",\n    other: \"{{count}} months\",\n  },\n\n  aboutXYears: {\n    one: \"about 1 year\",\n    other: \"about {{count}} years\",\n  },\n\n  xYears: {\n    one: \"1 year\",\n    other: \"{{count}} years\",\n  },\n\n  overXYears: {\n    one: \"over 1 year\",\n    other: \"over {{count}} years\",\n  },\n\n  almostXYears: {\n    one: \"almost 1 year\",\n    other: \"almost {{count}} years\",\n  },\n};\n\nexport const formatDistance = (token, count, options) => {\n  let result;\n\n  const tokenValue = formatDistanceLocale[token];\n  if (typeof tokenValue === \"string\") {\n    result = tokenValue;\n  } else if (count === 1) {\n    result = tokenValue.one;\n  } else {\n    result = tokenValue.other.replace(\"{{count}}\", count.toString());\n  }\n\n  if (options?.addSuffix) {\n    if (options.comparison && options.comparison > 0) {\n      return \"in \" + result;\n    } else {\n      return result + \" ago\";\n    }\n  }\n\n  return result;\n};\n","export function buildFormatLongFn(args) {\n  return (options = {}) => {\n    // TODO: Remove String()\n    const width = options.width ? String(options.width) : args.defaultWidth;\n    const format = args.formats[width] || args.formats[args.defaultWidth];\n    return format;\n  };\n}\n","import { buildFormatLongFn } from \"../../_lib/buildFormatLongFn.js\";\n\nconst dateFormats = {\n  full: \"EEEE, MMMM do, y\",\n  long: \"MMMM do, y\",\n  medium: \"MMM d, y\",\n  short: \"MM/dd/yyyy\",\n};\n\nconst timeFormats = {\n  full: \"h:mm:ss a zzzz\",\n  long: \"h:mm:ss a z\",\n  medium: \"h:mm:ss a\",\n  short: \"h:mm a\",\n};\n\nconst dateTimeFormats = {\n  full: \"{{date}} 'at' {{time}}\",\n  long: \"{{date}} 'at' {{time}}\",\n  medium: \"{{date}}, {{time}}\",\n  short: \"{{date}}, {{time}}\",\n};\n\nexport const formatLong = {\n  date: buildFormatLongFn({\n    formats: dateFormats,\n    defaultWidth: \"full\",\n  }),\n\n  time: buildFormatLongFn({\n    formats: timeFormats,\n    defaultWidth: \"full\",\n  }),\n\n  dateTime: buildFormatLongFn({\n    formats: dateTimeFormats,\n    defaultWidth: \"full\",\n  }),\n};\n","const formatRelativeLocale = {\n  lastWeek: \"'last' eeee 'at' p\",\n  yesterday: \"'yesterday at' p\",\n  today: \"'today at' p\",\n  tomorrow: \"'tomorrow at' p\",\n  nextWeek: \"eeee 'at' p\",\n  other: \"P\",\n};\n\nexport const formatRelative = (token, _date, _baseDate, _options) =>\n  formatRelativeLocale[token];\n","/**\n * The localize function argument callback which allows to convert raw value to\n * the actual type.\n *\n * @param value - The value to convert\n *\n * @returns The converted value\n */\n\n/**\n * The map of localized values for each width.\n */\n\n/**\n * The index type of the locale unit value. It types conversion of units of\n * values that don't start at 0 (i.e. quarters).\n */\n\n/**\n * Converts the unit value to the tuple of values.\n */\n\n/**\n * The tuple of localized era values. The first element represents BC,\n * the second element represents AD.\n */\n\n/**\n * The tuple of localized quarter values. The first element represents Q1.\n */\n\n/**\n * The tuple of localized day values. The first element represents Sunday.\n */\n\n/**\n * The tuple of localized month values. The first element represents January.\n */\n\nexport function buildLocalizeFn(args) {\n  return (value, options) => {\n    const context = options?.context ? String(options.context) : \"standalone\";\n\n    let valuesArray;\n    if (context === \"formatting\" && args.formattingValues) {\n      const defaultWidth = args.defaultFormattingWidth || args.defaultWidth;\n      const width = options?.width ? String(options.width) : defaultWidth;\n\n      valuesArray =\n        args.formattingValues[width] || args.formattingValues[defaultWidth];\n    } else {\n      const defaultWidth = args.defaultWidth;\n      const width = options?.width ? String(options.width) : args.defaultWidth;\n\n      valuesArray = args.values[width] || args.values[defaultWidth];\n    }\n    const index = args.argumentCallback ? args.argumentCallback(value) : value;\n\n    // @ts-expect-error - For some reason TypeScript just don't want to match it, no matter how hard we try. I challenge you to try to remove it!\n    return valuesArray[index];\n  };\n}\n","export function buildMatchFn(args) {\n  return (string, options = {}) => {\n    const width = options.width;\n\n    const matchPattern =\n      (width && args.matchPatterns[width]) ||\n      args.matchPatterns[args.defaultMatchWidth];\n    const matchResult = string.match(matchPattern);\n\n    if (!matchResult) {\n      return null;\n    }\n    const matchedString = matchResult[0];\n\n    const parsePatterns =\n      (width && args.parsePatterns[width]) ||\n      args.parsePatterns[args.defaultParseWidth];\n\n    const key = Array.isArray(parsePatterns)\n      ? findIndex(parsePatterns, (pattern) => pattern.test(matchedString))\n      : // [TODO] -- I challenge you to fix the type\n        findKey(parsePatterns, (pattern) => pattern.test(matchedString));\n\n    let value;\n\n    value = args.valueCallback ? args.valueCallback(key) : key;\n    value = options.valueCallback\n      ? // [TODO] -- I challenge you to fix the type\n        options.valueCallback(value)\n      : value;\n\n    const rest = string.slice(matchedString.length);\n\n    return { value, rest };\n  };\n}\n\nfunction findKey(object, predicate) {\n  for (const key in object) {\n    if (\n      Object.prototype.hasOwnProperty.call(object, key) &&\n      predicate(object[key])\n    ) {\n      return key;\n    }\n  }\n  return undefined;\n}\n\nfunction findIndex(array, predicate) {\n  for (let key = 0; key < array.length; key++) {\n    if (predicate(array[key])) {\n      return key;\n    }\n  }\n  return undefined;\n}\n","export function buildMatchPatternFn(args) {\n  return (string, options = {}) => {\n    const matchResult = string.match(args.matchPattern);\n    if (!matchResult) return null;\n    const matchedString = matchResult[0];\n\n    const parseResult = string.match(args.parsePattern);\n    if (!parseResult) return null;\n    let value = args.valueCallback\n      ? args.valueCallback(parseResult[0])\n      : parseResult[0];\n\n    // [TODO] I challenge you to fix the type\n    value = options.valueCallback ? options.valueCallback(value) : value;\n\n    const rest = string.slice(matchedString.length);\n\n    return { value, rest };\n  };\n}\n","import { formatDistance } from \"./en-US/_lib/formatDistance.js\";\nimport { formatLong } from \"./en-US/_lib/formatLong.js\";\nimport { formatRelative } from \"./en-US/_lib/formatRelative.js\";\nimport { localize } from \"./en-US/_lib/localize.js\";\nimport { match } from \"./en-US/_lib/match.js\";\n\n/**\n * @category Locales\n * @summary English locale (United States).\n * @language English\n * @iso-639-2 eng\n * @author Sasha Koss [@kossnocorp](https://github.com/kossnocorp)\n * @author Lesha Koss [@leshakoss](https://github.com/leshakoss)\n */\nexport const enUS = {\n  code: \"en-US\",\n  formatDistance: formatDistance,\n  formatLong: formatLong,\n  formatRelative: formatRelative,\n  localize: localize,\n  match: match,\n  options: {\n    weekStartsOn: 0 /* Sunday */,\n    firstWeekContainsDate: 1,\n  },\n};\n\n// Fallback for modularized imports:\nexport default enUS;\n","import { buildLocalizeFn } from \"../../_lib/buildLocalizeFn.js\";\n\nconst eraValues = {\n  narrow: [\"B\", \"A\"],\n  abbreviated: [\"BC\", \"AD\"],\n  wide: [\"Before Christ\", \"Anno Domini\"],\n};\n\nconst quarterValues = {\n  narrow: [\"1\", \"2\", \"3\", \"4\"],\n  abbreviated: [\"Q1\", \"Q2\", \"Q3\", \"Q4\"],\n  wide: [\"1st quarter\", \"2nd quarter\", \"3rd quarter\", \"4th quarter\"],\n};\n\n// Note: in English, the names of days of the week and months are capitalized.\n// If you are making a new locale based on this one, check if the same is true for the language you're working on.\n// Generally, formatted dates should look like they are in the middle of a sentence,\n// e.g. in Spanish language the weekdays and months should be in the lowercase.\nconst monthValues = {\n  narrow: [\"J\", \"F\", \"M\", \"A\", \"M\", \"J\", \"J\", \"A\", \"S\", \"O\", \"N\", \"D\"],\n  abbreviated: [\n    \"Jan\",\n    \"Feb\",\n    \"Mar\",\n    \"Apr\",\n    \"May\",\n    \"Jun\",\n    \"Jul\",\n    \"Aug\",\n    \"Sep\",\n    \"Oct\",\n    \"Nov\",\n    \"Dec\",\n  ],\n\n  wide: [\n    \"January\",\n    \"February\",\n    \"March\",\n    \"April\",\n    \"May\",\n    \"June\",\n    \"July\",\n    \"August\",\n    \"September\",\n    \"October\",\n    \"November\",\n    \"December\",\n  ],\n};\n\nconst dayValues = {\n  narrow: [\"S\", \"M\", \"T\", \"W\", \"T\", \"F\", \"S\"],\n  short: [\"Su\", \"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\"],\n  abbreviated: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n  wide: [\n    \"Sunday\",\n    \"Monday\",\n    \"Tuesday\",\n    \"Wednesday\",\n    \"Thursday\",\n    \"Friday\",\n    \"Saturday\",\n  ],\n};\n\nconst dayPeriodValues = {\n  narrow: {\n    am: \"a\",\n    pm: \"p\",\n    midnight: \"mi\",\n    noon: \"n\",\n    morning: \"morning\",\n    afternoon: \"afternoon\",\n    evening: \"evening\",\n    night: \"night\",\n  },\n  abbreviated: {\n    am: \"AM\",\n    pm: \"PM\",\n    midnight: \"midnight\",\n    noon: \"noon\",\n    morning: \"morning\",\n    afternoon: \"afternoon\",\n    evening: \"evening\",\n    night: \"night\",\n  },\n  wide: {\n    am: \"a.m.\",\n    pm: \"p.m.\",\n    midnight: \"midnight\",\n    noon: \"noon\",\n    morning: \"morning\",\n    afternoon: \"afternoon\",\n    evening: \"evening\",\n    night: \"night\",\n  },\n};\n\nconst formattingDayPeriodValues = {\n  narrow: {\n    am: \"a\",\n    pm: \"p\",\n    midnight: \"mi\",\n    noon: \"n\",\n    morning: \"in the morning\",\n    afternoon: \"in the afternoon\",\n    evening: \"in the evening\",\n    night: \"at night\",\n  },\n  abbreviated: {\n    am: \"AM\",\n    pm: \"PM\",\n    midnight: \"midnight\",\n    noon: \"noon\",\n    morning: \"in the morning\",\n    afternoon: \"in the afternoon\",\n    evening: \"in the evening\",\n    night: \"at night\",\n  },\n  wide: {\n    am: \"a.m.\",\n    pm: \"p.m.\",\n    midnight: \"midnight\",\n    noon: \"noon\",\n    morning: \"in the morning\",\n    afternoon: \"in the afternoon\",\n    evening: \"in the evening\",\n    night: \"at night\",\n  },\n};\n\nconst ordinalNumber = (dirtyNumber, _options) => {\n  const number = Number(dirtyNumber);\n\n  // If ordinal numbers depend on context, for example,\n  // if they are different for different grammatical genders,\n  // use `options.unit`.\n  //\n  // `unit` can be 'year', 'quarter', 'month', 'week', 'date', 'dayOfYear',\n  // 'day', 'hour', 'minute', 'second'.\n\n  const rem100 = number % 100;\n  if (rem100 > 20 || rem100 < 10) {\n    switch (rem100 % 10) {\n      case 1:\n        return number + \"st\";\n      case 2:\n        return number + \"nd\";\n      case 3:\n        return number + \"rd\";\n    }\n  }\n  return number + \"th\";\n};\n\nexport const localize = {\n  ordinalNumber,\n\n  era: buildLocalizeFn({\n    values: eraValues,\n    defaultWidth: \"wide\",\n  }),\n\n  quarter: buildLocalizeFn({\n    values: quarterValues,\n    defaultWidth: \"wide\",\n    argumentCallback: (quarter) => quarter - 1,\n  }),\n\n  month: buildLocalizeFn({\n    values: monthValues,\n    defaultWidth: \"wide\",\n  }),\n\n  day: buildLocalizeFn({\n    values: dayValues,\n    defaultWidth: \"wide\",\n  }),\n\n  dayPeriod: buildLocalizeFn({\n    values: dayPeriodValues,\n    defaultWidth: \"wide\",\n    formattingValues: formattingDayPeriodValues,\n    defaultFormattingWidth: \"wide\",\n  }),\n};\n","import { buildMatchFn } from \"../../_lib/buildMatchFn.js\";\nimport { buildMatchPatternFn } from \"../../_lib/buildMatchPatternFn.js\";\n\nconst matchOrdinalNumberPattern = /^(\\d+)(th|st|nd|rd)?/i;\nconst parseOrdinalNumberPattern = /\\d+/i;\n\nconst matchEraPatterns = {\n  narrow: /^(b|a)/i,\n  abbreviated: /^(b\\.?\\s?c\\.?|b\\.?\\s?c\\.?\\s?e\\.?|a\\.?\\s?d\\.?|c\\.?\\s?e\\.?)/i,\n  wide: /^(before christ|before common era|anno domini|common era)/i,\n};\nconst parseEraPatterns = {\n  any: [/^b/i, /^(a|c)/i],\n};\n\nconst matchQuarterPatterns = {\n  narrow: /^[1234]/i,\n  abbreviated: /^q[1234]/i,\n  wide: /^[1234](th|st|nd|rd)? quarter/i,\n};\nconst parseQuarterPatterns = {\n  any: [/1/i, /2/i, /3/i, /4/i],\n};\n\nconst matchMonthPatterns = {\n  narrow: /^[jfmasond]/i,\n  abbreviated: /^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i,\n  wide: /^(january|february|march|april|may|june|july|august|september|october|november|december)/i,\n};\nconst parseMonthPatterns = {\n  narrow: [\n    /^j/i,\n    /^f/i,\n    /^m/i,\n    /^a/i,\n    /^m/i,\n    /^j/i,\n    /^j/i,\n    /^a/i,\n    /^s/i,\n    /^o/i,\n    /^n/i,\n    /^d/i,\n  ],\n\n  any: [\n    /^ja/i,\n    /^f/i,\n    /^mar/i,\n    /^ap/i,\n    /^may/i,\n    /^jun/i,\n    /^jul/i,\n    /^au/i,\n    /^s/i,\n    /^o/i,\n    /^n/i,\n    /^d/i,\n  ],\n};\n\nconst matchDayPatterns = {\n  narrow: /^[smtwf]/i,\n  short: /^(su|mo|tu|we|th|fr|sa)/i,\n  abbreviated: /^(sun|mon|tue|wed|thu|fri|sat)/i,\n  wide: /^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i,\n};\nconst parseDayPatterns = {\n  narrow: [/^s/i, /^m/i, /^t/i, /^w/i, /^t/i, /^f/i, /^s/i],\n  any: [/^su/i, /^m/i, /^tu/i, /^w/i, /^th/i, /^f/i, /^sa/i],\n};\n\nconst matchDayPeriodPatterns = {\n  narrow: /^(a|p|mi|n|(in the|at) (morning|afternoon|evening|night))/i,\n  any: /^([ap]\\.?\\s?m\\.?|midnight|noon|(in the|at) (morning|afternoon|evening|night))/i,\n};\nconst parseDayPeriodPatterns = {\n  any: {\n    am: /^a/i,\n    pm: /^p/i,\n    midnight: /^mi/i,\n    noon: /^no/i,\n    morning: /morning/i,\n    afternoon: /afternoon/i,\n    evening: /evening/i,\n    night: /night/i,\n  },\n};\n\nexport const match = {\n  ordinalNumber: buildMatchPatternFn({\n    matchPattern: matchOrdinalNumberPattern,\n    parsePattern: parseOrdinalNumberPattern,\n    valueCallback: (value) => parseInt(value, 10),\n  }),\n\n  era: buildMatchFn({\n    matchPatterns: matchEraPatterns,\n    defaultMatchWidth: \"wide\",\n    parsePatterns: parseEraPatterns,\n    defaultParseWidth: \"any\",\n  }),\n\n  quarter: buildMatchFn({\n    matchPatterns: matchQuarterPatterns,\n    defaultMatchWidth: \"wide\",\n    parsePatterns: parseQuarterPatterns,\n    defaultParseWidth: \"any\",\n    valueCallback: (index) => index + 1,\n  }),\n\n  month: buildMatchFn({\n    matchPatterns: matchMonthPatterns,\n    defaultMatchWidth: \"wide\",\n    parsePatterns: parseMonthPatterns,\n    defaultParseWidth: \"any\",\n  }),\n\n  day: buildMatchFn({\n    matchPatterns: matchDayPatterns,\n    defaultMatchWidth: \"wide\",\n    parsePatterns: parseDayPatterns,\n    defaultParseWidth: \"any\",\n  }),\n\n  dayPeriod: buildMatchFn({\n    matchPatterns: matchDayPeriodPatterns,\n    defaultMatchWidth: \"any\",\n    parsePatterns: parseDayPeriodPatterns,\n    defaultParseWidth: \"any\",\n  }),\n};\n","import { constructNow } from \"./constructNow.js\";\n\nimport { formatDistance } from \"./formatDistance.js\";\n\n/**\n * The {@link formatDistanceToNow} function options.\n */\n\n/**\n * @name formatDistanceToNow\n * @category Common Helpers\n * @summary Return the distance between the given date and now in words.\n * @pure false\n *\n * @description\n * Return the distance between the given date and now in words.\n *\n * | Distance to now                                                   | Result              |\n * |-------------------------------------------------------------------|---------------------|\n * | 0 ... 30 secs                                                     | less than a minute  |\n * | 30 secs ... 1 min 30 secs                                         | 1 minute            |\n * | 1 min 30 secs ... 44 mins 30 secs                                 | [2..44] minutes     |\n * | 44 mins ... 30 secs ... 89 mins 30 secs                           | about 1 hour        |\n * | 89 mins 30 secs ... 23 hrs 59 mins 30 secs                        | about [2..24] hours |\n * | 23 hrs 59 mins 30 secs ... 41 hrs 59 mins 30 secs                 | 1 day               |\n * | 41 hrs 59 mins 30 secs ... 29 days 23 hrs 59 mins 30 secs         | [2..30] days        |\n * | 29 days 23 hrs 59 mins 30 secs ... 44 days 23 hrs 59 mins 30 secs | about 1 month       |\n * | 44 days 23 hrs 59 mins 30 secs ... 59 days 23 hrs 59 mins 30 secs | about 2 months      |\n * | 59 days 23 hrs 59 mins 30 secs ... 1 yr                           | [2..12] months      |\n * | 1 yr ... 1 yr 3 months                                            | about 1 year        |\n * | 1 yr 3 months ... 1 yr 9 month s                                  | over 1 year         |\n * | 1 yr 9 months ... 2 yrs                                           | almost 2 years      |\n * | N yrs ... N yrs 3 months                                          | about N years       |\n * | N yrs 3 months ... N yrs 9 months                                 | over N years        |\n * | N yrs 9 months ... N+1 yrs                                        | almost N+1 years    |\n *\n * With `options.includeSeconds == true`:\n * | Distance to now     | Result               |\n * |---------------------|----------------------|\n * | 0 secs ... 5 secs   | less than 5 seconds  |\n * | 5 secs ... 10 secs  | less than 10 seconds |\n * | 10 secs ... 20 secs | less than 20 seconds |\n * | 20 secs ... 40 secs | half a minute        |\n * | 40 secs ... 60 secs | less than a minute   |\n * | 60 secs ... 90 secs | 1 minute             |\n *\n * @param date - The given date\n * @param options - The object with options\n *\n * @returns The distance in words\n *\n * @throws `date` must not be Invalid Date\n * @throws `options.locale` must contain `formatDistance` property\n *\n * @example\n * // If today is 1 January 2015, what is the distance to 2 July 2014?\n * const result = formatDistanceToNow(\n *   new Date(2014, 6, 2)\n * )\n * //=> '6 months'\n *\n * @example\n * // If now is 1 January 2015 00:00:00,\n * // what is the distance to 1 January 2015 00:00:15, including seconds?\n * const result = formatDistanceToNow(\n *   new Date(2015, 0, 1, 0, 0, 15),\n *   {includeSeconds: true}\n * )\n * //=> 'less than 20 seconds'\n *\n * @example\n * // If today is 1 January 2015,\n * // what is the distance to 1 January 2016, with a suffix?\n * const result = formatDistanceToNow(\n *   new Date(2016, 0, 1),\n *   {addSuffix: true}\n * )\n * //=> 'in about 1 year'\n *\n * @example\n * // If today is 1 January 2015,\n * // what is the distance to 1 August 2016 in Esperanto?\n * const eoLocale = require('date-fns/locale/eo')\n * const result = formatDistanceToNow(\n *   new Date(2016, 7, 1),\n *   {locale: eoLocale}\n * )\n * //=> 'pli ol 1 jaro'\n */\nexport function formatDistanceToNow(date, options) {\n  return formatDistance(date, constructNow(date), options);\n}\n\n// Fallback for modularized imports:\nexport default formatDistanceToNow;\n","import { defaultLocale } from \"./_lib/defaultLocale.js\";\nimport { getDefaultOptions } from \"./_lib/defaultOptions.js\";\nimport { getTimezoneOffsetInMilliseconds } from \"./_lib/getTimezoneOffsetInMilliseconds.js\";\nimport { normalizeDates } from \"./_lib/normalizeDates.js\";\nimport { compareAsc } from \"./compareAsc.js\";\nimport { minutesInDay, minutesInMonth } from \"./constants.js\";\nimport { differenceInMonths } from \"./differenceInMonths.js\";\nimport { differenceInSeconds } from \"./differenceInSeconds.js\";\n\n/**\n * The {@link formatDistance} function options.\n */\n\n/**\n * @name formatDistance\n * @category Common Helpers\n * @summary Return the distance between the given dates in words.\n *\n * @description\n * Return the distance between the given dates in words.\n *\n * | Distance between dates                                            | Result              |\n * |-------------------------------------------------------------------|---------------------|\n * | 0 ... 30 secs                                                     | less than a minute  |\n * | 30 secs ... 1 min 30 secs                                         | 1 minute            |\n * | 1 min 30 secs ... 44 mins 30 secs                                 | [2..44] minutes     |\n * | 44 mins ... 30 secs ... 89 mins 30 secs                           | about 1 hour        |\n * | 89 mins 30 secs ... 23 hrs 59 mins 30 secs                        | about [2..24] hours |\n * | 23 hrs 59 mins 30 secs ... 41 hrs 59 mins 30 secs                 | 1 day               |\n * | 41 hrs 59 mins 30 secs ... 29 days 23 hrs 59 mins 30 secs         | [2..30] days        |\n * | 29 days 23 hrs 59 mins 30 secs ... 44 days 23 hrs 59 mins 30 secs | about 1 month       |\n * | 44 days 23 hrs 59 mins 30 secs ... 59 days 23 hrs 59 mins 30 secs | about 2 months      |\n * | 59 days 23 hrs 59 mins 30 secs ... 1 yr                           | [2..12] months      |\n * | 1 yr ... 1 yr 3 months                                            | about 1 year        |\n * | 1 yr 3 months ... 1 yr 9 month s                                  | over 1 year         |\n * | 1 yr 9 months ... 2 yrs                                           | almost 2 years      |\n * | N yrs ... N yrs 3 months                                          | about N years       |\n * | N yrs 3 months ... N yrs 9 months                                 | over N years        |\n * | N yrs 9 months ... N+1 yrs                                        | almost N+1 years    |\n *\n * With `options.includeSeconds == true`:\n * | Distance between dates | Result               |\n * |------------------------|----------------------|\n * | 0 secs ... 5 secs      | less than 5 seconds  |\n * | 5 secs ... 10 secs     | less than 10 seconds |\n * | 10 secs ... 20 secs    | less than 20 seconds |\n * | 20 secs ... 40 secs    | half a minute        |\n * | 40 secs ... 60 secs    | less than a minute   |\n * | 60 secs ... 90 secs    | 1 minute             |\n *\n * @param laterDate - The date\n * @param earlierDate - The date to compare with\n * @param options - An object with options\n *\n * @returns The distance in words\n *\n * @throws `date` must not be Invalid Date\n * @throws `baseDate` must not be Invalid Date\n * @throws `options.locale` must contain `formatDistance` property\n *\n * @example\n * // What is the distance between 2 July 2014 and 1 January 2015?\n * const result = formatDistance(new Date(2014, 6, 2), new Date(2015, 0, 1))\n * //=> '6 months'\n *\n * @example\n * // What is the distance between 1 January 2015 00:00:15\n * // and 1 January 2015 00:00:00, including seconds?\n * const result = formatDistance(\n *   new Date(2015, 0, 1, 0, 0, 15),\n *   new Date(2015, 0, 1, 0, 0, 0),\n *   { includeSeconds: true }\n * )\n * //=> 'less than 20 seconds'\n *\n * @example\n * // What is the distance from 1 January 2016\n * // to 1 January 2015, with a suffix?\n * const result = formatDistance(new Date(2015, 0, 1), new Date(2016, 0, 1), {\n *   addSuffix: true\n * })\n * //=> 'about 1 year ago'\n *\n * @example\n * // What is the distance between 1 August 2016 and 1 January 2015 in Esperanto?\n * import { eoLocale } from 'date-fns/locale/eo'\n * const result = formatDistance(new Date(2016, 7, 1), new Date(2015, 0, 1), {\n *   locale: eoLocale\n * })\n * //=> 'pli ol 1 jaro'\n */\nexport function formatDistance(laterDate, earlierDate, options) {\n  const defaultOptions = getDefaultOptions();\n  const locale = options?.locale ?? defaultOptions.locale ?? defaultLocale;\n  const minutesInAlmostTwoDays = 2520;\n\n  const comparison = compareAsc(laterDate, earlierDate);\n\n  if (isNaN(comparison)) throw new RangeError(\"Invalid time value\");\n\n  const localizeOptions = Object.assign({}, options, {\n    addSuffix: options?.addSuffix,\n    comparison: comparison,\n  });\n\n  const [laterDate_, earlierDate_] = normalizeDates(\n    options?.in,\n    ...(comparison > 0 ? [earlierDate, laterDate] : [laterDate, earlierDate]),\n  );\n\n  const seconds = differenceInSeconds(earlierDate_, laterDate_);\n  const offsetInSeconds =\n    (getTimezoneOffsetInMilliseconds(earlierDate_) -\n      getTimezoneOffsetInMilliseconds(laterDate_)) /\n    1000;\n  const minutes = Math.round((seconds - offsetInSeconds) / 60);\n  let months;\n\n  // 0 up to 2 mins\n  if (minutes < 2) {\n    if (options?.includeSeconds) {\n      if (seconds < 5) {\n        return locale.formatDistance(\"lessThanXSeconds\", 5, localizeOptions);\n      } else if (seconds < 10) {\n        return locale.formatDistance(\"lessThanXSeconds\", 10, localizeOptions);\n      } else if (seconds < 20) {\n        return locale.formatDistance(\"lessThanXSeconds\", 20, localizeOptions);\n      } else if (seconds < 40) {\n        return locale.formatDistance(\"halfAMinute\", 0, localizeOptions);\n      } else if (seconds < 60) {\n        return locale.formatDistance(\"lessThanXMinutes\", 1, localizeOptions);\n      } else {\n        return locale.formatDistance(\"xMinutes\", 1, localizeOptions);\n      }\n    } else {\n      if (minutes === 0) {\n        return locale.formatDistance(\"lessThanXMinutes\", 1, localizeOptions);\n      } else {\n        return locale.formatDistance(\"xMinutes\", minutes, localizeOptions);\n      }\n    }\n\n    // 2 mins up to 0.75 hrs\n  } else if (minutes < 45) {\n    return locale.formatDistance(\"xMinutes\", minutes, localizeOptions);\n\n    // 0.75 hrs up to 1.5 hrs\n  } else if (minutes < 90) {\n    return locale.formatDistance(\"aboutXHours\", 1, localizeOptions);\n\n    // 1.5 hrs up to 24 hrs\n  } else if (minutes < minutesInDay) {\n    const hours = Math.round(minutes / 60);\n    return locale.formatDistance(\"aboutXHours\", hours, localizeOptions);\n\n    // 1 day up to 1.75 days\n  } else if (minutes < minutesInAlmostTwoDays) {\n    return locale.formatDistance(\"xDays\", 1, localizeOptions);\n\n    // 1.75 days up to 30 days\n  } else if (minutes < minutesInMonth) {\n    const days = Math.round(minutes / minutesInDay);\n    return locale.formatDistance(\"xDays\", days, localizeOptions);\n\n    // 1 month up to 2 months\n  } else if (minutes < minutesInMonth * 2) {\n    months = Math.round(minutes / minutesInMonth);\n    return locale.formatDistance(\"aboutXMonths\", months, localizeOptions);\n  }\n\n  months = differenceInMonths(earlierDate_, laterDate_);\n\n  // 2 months up to 12 months\n  if (months < 12) {\n    const nearestMonth = Math.round(minutes / minutesInMonth);\n    return locale.formatDistance(\"xMonths\", nearestMonth, localizeOptions);\n\n    // 1 year up to max Date\n  } else {\n    const monthsSinceStartOfYear = months % 12;\n    const years = Math.trunc(months / 12);\n\n    // N years up to 1 years 3 months\n    if (monthsSinceStartOfYear < 3) {\n      return locale.formatDistance(\"aboutXYears\", years, localizeOptions);\n\n      // N years 3 months up to N years 9 months\n    } else if (monthsSinceStartOfYear < 9) {\n      return locale.formatDistance(\"overXYears\", years, localizeOptions);\n\n      // N years 9 months up to N year 12 months\n    } else {\n      return locale.formatDistance(\"almostXYears\", years + 1, localizeOptions);\n    }\n  }\n}\n\n// Fallback for modularized imports:\nexport default formatDistance;\n","import { constructFrom } from \"./constructFrom.js\";\n\n/**\n * @name constructNow\n * @category Generic Helpers\n * @summary Constructs a new current date using the passed value constructor.\n * @pure false\n *\n * @description\n * The function constructs a new current date using the constructor from\n * the reference date. It helps to build generic functions that accept date\n * extensions and use the current date.\n *\n * It defaults to `Date` if the passed reference date is a number or a string.\n *\n * @param date - The reference date to take constructor from\n *\n * @returns Current date initialized using the given date constructor\n *\n * @example\n * import { constructNow, isSameDay } from 'date-fns'\n *\n * function isToday<DateType extends Date>(\n *   date: DateArg<DateType>,\n * ): boolean {\n *   // If we were to use `new Date()` directly, the function would  behave\n *   // differently in different timezones and return false for the same date.\n *   return isSameDay(date, constructNow(date));\n * }\n */\nexport function constructNow(date) {\n  return constructFrom(date, Date.now());\n}\n\n// Fallback for modularized imports:\nexport default constructNow;\n","import { Chat, Dialogs, Messages } from \"connectycube/types\";\nimport { ReactNode } from \"react\";\nimport { BlockListHook } from \"../hooks/useBlockList\";\nimport { UsersHookExports } from \"../hooks/useUsers\";\nimport { NetworkStatusHook } from \"../hooks/useNetworkStatus\";\n\nexport interface ChatProviderType {\n  children?: ReactNode;\n}\n\nexport interface ChatContextType extends BlockListHook, UsersHookExports, NetworkStatusHook {\n  isConnected: boolean;\n  chatStatus: ChatStatus;\n  connect: (credentials: Chat.ConnectionParams) => Promise<boolean>;\n  disconnect: () => Promise<boolean>;\n  terminate: () => void;\n  currentUserId?: number;\n  createChat: (userId: number, extensions?: { [key: string]: any }) => Promise<Dialogs.Dialog>;\n  createGroupChat: (\n    usersIds: number[],\n    name: string,\n    photo?: string,\n    extensions?: { [key: string]: any },\n  ) => Promise<Dialogs.Dialog>;\n  getDialogs: (filters?: Dialogs.ListParams) => Promise<Dialogs.Dialog[]>;\n  getNextDialogs: () => Promise<Dialogs.Dialog[]>;\n  totalDialogReached: boolean;\n  dialogs: Dialogs.Dialog[];\n  selectedDialog?: Dialogs.Dialog;\n  selectDialog: (dialog?: Dialogs.Dialog) => Promise<void>;\n  getDialogOpponentId: (dialog?: Dialogs.Dialog) => number | undefined;\n  unreadMessagesCount: { total: number; [dialogId: string]: number };\n  getMessages: (dialogId: string) => Promise<Messages.Message[]>;\n  getNextMessages: (dialogId: string) => Promise<Messages.Message[]>;\n  totalMessagesReached: { [dialogId: string]: boolean };\n  messages: { [key: string]: Messages.Message[] };\n  markDialogAsRead: (dialog: Dialogs.Dialog) => Promise<void>;\n  addUsersToGroupChat: (usersIds: number[]) => Promise<void>;\n  removeUsersFromGroupChat: (usersIds: number[]) => Promise<void>;\n  leaveGroupChat: () => Promise<void>;\n  sendSignal: (userIdOrIds: number | number[], signal: string, params?: any) => void;\n  sendMessage: (body: string, dialog?: Dialogs.Dialog) => void;\n  sendMessageWithAttachment: (files: File[], dialog?: Dialogs.Dialog) => Promise<void>;\n  readMessage: (messageId: string, userId: number, dialogId: string) => void;\n  sendTypingStatus: (dialog?: Dialogs.Dialog, isTyping?: boolean) => void;\n  typingStatus: { [dialogId: string]: number[] };\n  lastMessageSentTimeString: (dialog: Dialogs.Dialog) => string;\n  messageSentTimeString: (message: Messages.Message) => string;\n  processOnSignal: (fn: Chat.OnMessageSystemListener | null) => void;\n  processOnMessage: (fn: Chat.OnMessageListener | null) => void;\n  processOnMessageError: (fn: Chat.OnMessageErrorListener | null) => void;\n  processOnMessageSent: (fn: Chat.OnMessageSentListener | null) => void;\n}\n\nexport enum DialogEventSignal {\n  ADDED_TO_DIALOG = \"dialog/ADDED_TO_DIALOG\",\n  REMOVED_FROM_DIALOG = \"dialog/REMOVED_FROM_DIALOG\",\n  ADD_PARTICIPANTS = \"dialog/ADD_PARTICIPANTS\",\n  REMOVE_PARTICIPANTS = \"dialog/REMOVE_PARTICIPANTS\",\n  NEW_DIALOG = \"dialog/NEW_DIALOG\",\n}\n\nexport enum MessageStatus {\n  WAIT = \"wait\",\n  LOST = \"lost\",\n  SENT = \"sent\",\n  READ = \"read\",\n}\n\nexport enum ChatStatus {\n  DISCONNECTED = \"disconnected\",\n  CONNECTING = \"connecting\",\n  CONNECTED = \"connected\",\n  NOT_AUTHORIZED = \"not-authorized\",\n  ERROR = \"error\",\n}\n","import ConnectyCube from \"connectycube\";\nimport { PrivacyListAction } from \"connectycube/types\";\nimport { useEffect, useState, useRef } from \"react\";\n\nexport const BLOCK_LIST_LOG_TAG = \"[useChat][useBlockList]\";\nexport const BLOCK_LIST_NAME = \"ConnectyCubeBlockList\";\n\nexport type BlockListHook = {\n  blockedUsers: number[];\n  isBlockedUser: (userId: number) => boolean;\n  unblockUser: (userId: number) => Promise<void>;\n  blockUser: (userId: number) => Promise<void>;\n};\n\nfunction useBlockList(isConnected: boolean): BlockListHook {\n  const [state, setState] = useState<Set<number>>(new Set<number>());\n  const isApplied = useRef<boolean>(false);\n\n  const isBlocked = (userId: number): boolean => state.has(userId);\n\n  const fetch = async (): Promise<void> => {\n    if (!isConnected) {\n      console.warn(`${BLOCK_LIST_LOG_TAG}[fetch]: chat is not connected`);\n      return;\n    }\n\n    const blackListNames = await ConnectyCube.chat.privacylist.getNames();\n\n    if (blackListNames.default === BLOCK_LIST_NAME) {\n      const blockList = await ConnectyCube.chat.privacylist.getList(BLOCK_LIST_NAME);\n      const newState = blockList.items.reduce((list: Set<number>, item) => {\n        if (item.action === PrivacyListAction.DENY) {\n          list.add(+item.user_id);\n        }\n        return list;\n      }, new Set<number>());\n\n      isApplied.current = true;\n\n      setState(newState);\n    }\n  };\n\n  const upsert = async (user_id: number, action: PrivacyListAction): Promise<void> => {\n    if (!isConnected) {\n      console.warn(`${BLOCK_LIST_LOG_TAG}[upsert]: ${action} user ${user_id} failed, chat is not connected`);\n      return;\n    }\n\n    const newState = new Set(state);\n\n    const blockList = {\n      name: BLOCK_LIST_NAME,\n      items: [{ user_id, action, mutualBlock: true }],\n    };\n\n    try {\n      if (action === PrivacyListAction.DENY) {\n        newState.add(user_id);\n      } else if (action === PrivacyListAction.ALLOW) {\n        newState.delete(user_id);\n      }\n\n      if (isApplied.current) {\n        await ConnectyCube.chat.privacylist.setAsDefault(null);\n        await ConnectyCube.chat.privacylist.update(blockList);\n        if (newState.size > 0) {\n          await ConnectyCube.chat.privacylist.setAsDefault(BLOCK_LIST_NAME);\n        }\n      } else {\n        await ConnectyCube.chat.privacylist.create(blockList);\n        await ConnectyCube.chat.privacylist.setAsDefault(BLOCK_LIST_NAME);\n      }\n    } catch (error) {\n      return;\n    } finally {\n      setState(newState);\n    }\n  };\n\n  const unblock = async (userId: number): Promise<void> => {\n    if (!isBlocked(userId)) {\n      console.warn(`${BLOCK_LIST_LOG_TAG}[unblock]: user ${userId} is not blocked`);\n      return;\n    }\n\n    await upsert(userId, PrivacyListAction.ALLOW);\n  };\n\n  const block = async (userId: number): Promise<void> => {\n    if (isBlocked(userId)) {\n      console.warn(`${BLOCK_LIST_LOG_TAG}[block]: user ${userId} is already blocked`);\n      return;\n    }\n\n    await upsert(userId, PrivacyListAction.DENY);\n  };\n\n  useEffect(() => {\n    if (isConnected) {\n      fetch();\n    }\n  }, [isConnected]);\n\n  return {\n    blockedUsers: Array.from(state),\n    isBlockedUser: isBlocked,\n    unblockUser: unblock,\n    blockUser: block,\n  };\n}\n\nexport default useBlockList;\n","import { DateOrTimestamp, Dialogs } from \"connectycube/types\";\n\nexport const parseDate = (date: DateOrTimestamp): number | undefined => {\n  let result: number | undefined;\n\n  if (typeof date === \"string\") {\n    const t = new Date(date).getTime();\n    result = isNaN(t) ? undefined : t;\n  } else if (typeof date === \"number\") {\n    result = date * 1000;\n  }\n\n  return result;\n};\n\nexport const getLastActivityText = (seconds: number): string => {\n  let status: string;\n\n  const MINUTE_IN_SEC = 60;\n  const HOUR_IN_SEC = 3600;\n  const DAY_IN_SEC = 86400;\n  const ONLINE_IN_SEC = MINUTE_IN_SEC / 2;\n\n  if (seconds <= ONLINE_IN_SEC) {\n    status = \"Online\";\n  } else if (seconds < HOUR_IN_SEC) {\n    status = `Last seen ${Math.ceil(seconds / MINUTE_IN_SEC)} minutes ago`;\n  } else if (seconds < DAY_IN_SEC) {\n    status = `Last seen ${Math.ceil(seconds / HOUR_IN_SEC)} hours ago`;\n  } else {\n    const lastLoggedInTime = new Date(Date.now() - seconds * 1000);\n    const day = lastLoggedInTime.getUTCDate();\n    const month = (lastLoggedInTime.getMonth() + 1).toString().padStart(2, \"0\");\n    const year = lastLoggedInTime.getFullYear();\n    status = `Last seen ${day}/${month}/${year}`;\n  }\n\n  return status;\n};\n\nexport const getDialogTimestamp = (dialog: Dialogs.Dialog) =>\n  parseDate(dialog.last_message_date_sent) || parseDate(dialog.updated_at) || parseDate(dialog.created_at) || 0;\n","import ConnectyCube from \"connectycube\";\nimport { Chat, ChatEvent, Users } from \"connectycube/types\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { getLastActivityText } from \"../helpers\";\n\nexport const USERS_LOG_TAG = \"[useChat][useUsers]\";\nexport const LIMIT_ONLINE_USERS_INTERVAL = 60000;\nexport const LIMIT_FETCH_USER_INTERVAL = 30000;\nexport const MAX_REQUEST_LIMIT = 100;\n\nexport type FetchUsersLastRequestAt = { [userId: Users.User[\"id\"]]: number };\nexport type OnlineUsersLastRequestAt = number;\nexport type UsersArray = Users.User[];\nexport type UsersObject = { [userId: Users.User[\"id\"]]: Users.User };\nexport type UsersLastActivity = { [userId: number]: string };\n\nexport type UsersHookExports = {\n  users: UsersObject;\n  getAndStoreUsers: (params: Users.GetV2Params) => Promise<Users.User[]>;\n  searchUsers: (term: string) => Promise<UsersArray>;\n  fetchUserById: (id: Users.User[\"id\"], force?: boolean) => Promise<Users.User>;\n  listOnlineUsers: (force?: boolean) => Promise<UsersArray>;\n  listOnlineUsersWithParams: (params: Users.ListOnlineParams) => Promise<UsersArray>;\n  onlineUsers: UsersArray;\n  getOnlineUsersCount: () => Promise<number>;\n  onlineUsersCount: number;\n  lastActivity: UsersLastActivity;\n  getLastActivity: (userId: number) => Promise<string>;\n  subscribeToUserLastActivityStatus: (userId: number) => void;\n  unsubscribeFromUserLastActivityStatus: (userId: number) => void;\n};\n\nexport type UsersHook = {\n  exports: UsersHookExports;\n  _retrieveAndStoreUsers: (usersIds: number[]) => Promise<void>;\n};\n\nfunction useUsers(currentUserId?: number): UsersHook {\n  const [users, setUsers] = useState<UsersObject>({});\n  const [onlineUsers, setOnlineUsers] = useState<UsersObject>({});\n  const [onlineUsersCount, setOnlineUsersCount] = useState<number>(0);\n  const [lastActivity, setLastActivity] = useState<UsersLastActivity>({});\n\n  const onlineUsersLastRequestAtRef = useRef<OnlineUsersLastRequestAt>(0);\n  const fetchUsersLastRequestAtRef = useRef<FetchUsersLastRequestAt>({});\n\n  const getAndStoreUsers = async (params: Users.GetV2Params): Promise<Users.User[]> => {\n    const { items } = await ConnectyCube.users.getV2(params);\n\n    setUsers((prevUsersState) =>\n      items.reduce<UsersObject>((map, user) => ({ ...map, [user.id]: user }), { ...prevUsersState }),\n    );\n    setOnlineUsers((prevState) =>\n      items.reduce<UsersObject>((map, user) => (map[user.id] ? { ...map, [user.id]: user } : map), { ...prevState }),\n    );\n\n    items.forEach((user) => {\n      fetchUsersLastRequestAtRef.current[user.id] = Date.now();\n    });\n\n    return items;\n  };\n\n  const _retrieveAndStoreUsers = async (usersIds: number[]): Promise<void> => {\n    const usersToFind = usersIds.filter((userId) => !users[userId]);\n\n    if (usersToFind.length > 0) {\n      await getAndStoreUsers({ limit: MAX_REQUEST_LIMIT, id: { in: usersToFind } });\n    }\n  };\n\n  const fetchUserById = async (id: Users.User[\"id\"], force: boolean = false): Promise<Users.User> => {\n    const lastRequestedAt = fetchUsersLastRequestAtRef.current[id] || 0;\n    const currentTimestamp = Date.now();\n    const shouldRequest = currentTimestamp - lastRequestedAt > LIMIT_FETCH_USER_INTERVAL;\n\n    let user = users[id];\n\n    if (shouldRequest || force) {\n      const result = await ConnectyCube.users.getV2({ id, limit: 1 });\n      const fetchedUser = result?.items?.[0];\n\n      if (fetchedUser) {\n        setUsers((prevState) => ({ ...prevState, [id]: fetchedUser }));\n        setOnlineUsers((prevState) => (prevState[id] ? { ...prevState, [id]: fetchedUser } : prevState));\n        fetchUsersLastRequestAtRef.current[id] = Date.now();\n        user = fetchedUser;\n      }\n    }\n\n    return user;\n  };\n\n  const searchUsers = useCallback(\n    async (term: string): Promise<UsersArray> => {\n      const { items: usersWithFullName } = await ConnectyCube.users.getV2({\n        full_name: { start_with: term },\n        limit: MAX_REQUEST_LIMIT,\n      });\n      const { items: usersWithLogin } = await ConnectyCube.users.getV2({\n        login: { start_with: term },\n        limit: MAX_REQUEST_LIMIT,\n      });\n      const usersMap: Map<number, Users.User> = new Map();\n\n      [...usersWithFullName, ...usersWithLogin].forEach((user) => {\n        usersMap.set(user.id, user);\n      });\n\n      return Array.from(usersMap.values()).filter((user) => user.id !== currentUserId);\n    },\n    [currentUserId],\n  );\n\n  const getOnlineUsersCount = async (): Promise<number> => {\n    let nextOnlineUsersCount = onlineUsersCount;\n\n    try {\n      const { count } = await ConnectyCube.users.getOnlineCount();\n      nextOnlineUsersCount = count;\n      setOnlineUsersCount(nextOnlineUsersCount);\n    } catch (error) {\n      console.error(`${USERS_LOG_TAG}[getOnlineCount][Error]:`, error);\n    }\n\n    return nextOnlineUsersCount;\n  };\n\n  const _listOnline = async (): Promise<UsersObject> => {\n    const onlineUsersCount = await getOnlineUsersCount();\n    const promises = [];\n\n    let onlineUsersState: UsersObject = {};\n\n    try {\n      let limit = MAX_REQUEST_LIMIT;\n      let offset = 0;\n\n      while (offset < onlineUsersCount) {\n        promises.push(ConnectyCube.users.listOnline({ limit, offset }).then(({ users }) => users));\n        offset += limit;\n      }\n\n      const results = await Promise.all(promises);\n      const allUsers = results.flat();\n\n      onlineUsersState = allUsers.reduce<UsersObject>((map, user) => {\n        map[user.id] = user;\n        return map;\n      }, {});\n\n      setUsers((prevUsersState) => ({ ...prevUsersState, ...onlineUsersState }));\n      setOnlineUsers(onlineUsersState);\n    } catch (error) {\n      console.error(`${USERS_LOG_TAG}[listOnline][Error]:`, error);\n    }\n\n    return onlineUsersState;\n  };\n\n  const listOnlineUsersWithParams = async (params: Users.ListOnlineParams): Promise<UsersArray> => {\n    let onlineUsersState: UsersObject = {};\n\n    try {\n      const { users: allUsers } = await ConnectyCube.users.listOnline(params);\n\n      onlineUsersState = allUsers.reduce<UsersObject>((map, user) => {\n        map[user.id] = user;\n        return map;\n      }, {});\n\n      setUsers((prevUsersState) => ({ ...prevUsersState, ...onlineUsersState }));\n      setOnlineUsers(onlineUsersState);\n    } catch (error) {\n      console.error(`${USERS_LOG_TAG}[listOnlineWithParams][Error]:`, error);\n    }\n\n    return Object.values(onlineUsersState);\n  };\n\n  const listOnlineUsers = async (force: boolean = false): Promise<UsersArray> => {\n    const lastRequestedAt = onlineUsersLastRequestAtRef.current;\n    const currentTimestamp = Date.now();\n    const shouldRequest = currentTimestamp - lastRequestedAt > LIMIT_ONLINE_USERS_INTERVAL;\n\n    let onlineUsersState = onlineUsers;\n\n    if (shouldRequest || force) {\n      onlineUsersState = await _listOnline();\n      onlineUsersLastRequestAtRef.current = Date.now();\n    }\n\n    return Object.values(onlineUsersState);\n  };\n\n  const getLastActivity = async (userId: number): Promise<string> => {\n    let status = \"Last seen recently\";\n\n    try {\n      const { seconds } = await ConnectyCube.chat.getLastUserActivity(userId);\n      status = getLastActivityText(seconds);\n    } catch (error) {\n      console.error(`${USERS_LOG_TAG}[getLastActivity][Error]:`, error);\n    } finally {\n      setLastActivity((prevLastActivity) => ({ ...prevLastActivity, [userId]: status }));\n      return status;\n    }\n  };\n\n  const subscribeToUserLastActivityStatus = (userId: number): void => {\n    ConnectyCube.chat.subscribeToUserLastActivityStatus(userId);\n  };\n\n  const unsubscribeFromUserLastActivityStatus = (userId: number): void => {\n    ConnectyCube.chat.unsubscribeFromUserLastActivityStatus(userId);\n  };\n\n  useEffect(() => {\n    const processUserLastActivityChange = (\n      userId: Chat.LastActivity[\"userId\"],\n      seconds: Chat.LastActivity[\"seconds\"],\n    ) => {\n      if (typeof userId === \"number\" && seconds >= 0) {\n        const status = getLastActivityText(seconds);\n        setLastActivity((prevLastActivity) => ({ ...prevLastActivity, [userId]: status }));\n      }\n    };\n\n    ConnectyCube.chat.addListener(ChatEvent.USER_LAST_ACTIVITY, processUserLastActivityChange);\n\n    return () => {\n      ConnectyCube.chat.removeListener(ChatEvent.USER_LAST_ACTIVITY);\n    };\n  }, []);\n\n  return {\n    _retrieveAndStoreUsers,\n    exports: {\n      users,\n      getAndStoreUsers,\n      searchUsers,\n      fetchUserById,\n      listOnlineUsers,\n      listOnlineUsersWithParams,\n      onlineUsers: Object.values(onlineUsers),\n      getOnlineUsersCount,\n      onlineUsersCount,\n      lastActivity,\n      getLastActivity,\n      subscribeToUserLastActivityStatus,\n      unsubscribeFromUserLastActivityStatus,\n    },\n  };\n}\n\nexport default useUsers;\n","import { createContext, useContext, useEffect, useRef, useState } from \"react\";\nimport useStateRef from \"react-usestateref\";\nimport ConnectyCube from \"connectycube\";\nimport { Chat, ChatEvent, ChatType, Dialogs, DialogType, Messages } from \"connectycube/types\";\nimport { formatDistanceToNow } from \"date-fns\";\nimport { ChatContextType, ChatProviderType, ChatStatus, DialogEventSignal, MessageStatus } from \"./types\";\nimport { useBlockList, useNetworkStatus, useUsers } from \"./hooks\";\nimport { getDialogTimestamp, parseDate } from \"./helpers\";\n\nconst ChatContext = createContext<ChatContextType | undefined>(undefined);\nChatContext.displayName = \"ChatContext\";\n\nexport const useChat = (): ChatContextType => {\n  const context = useContext(ChatContext);\n\n  if (!context) {\n    throw new Error(\"useChat must be within ChatProvider\");\n  }\n\n  return context;\n};\n\nexport const ChatProvider = ({ children }: ChatProviderType): React.ReactElement => {\n  // state\n  const [isConnected, setIsConnected] = useState(false);\n  const [unreadMessagesCount, setUnreadMessagesCount] = useState<ChatContextType[\"unreadMessagesCount\"]>({ total: 0 });\n  const [typingStatus, setTypingStatus] = useState<{ [dialogId: string]: number[] }>({});\n  const [totalMessagesReached, setTotalMessagesReached] = useState<{ [dialogId: string]: boolean }>({});\n  const [totalDialogReached, setTotalDialogReached] = useState<boolean>(false);\n  // state refs\n  const [messages, setMessages, messagesRef] = useStateRef<{ [dialogId: string]: Messages.Message[] }>({});\n  const [dialogs, setDialogs, dialogsRef] = useStateRef<Dialogs.Dialog[]>([]);\n  const [currentUserId, setCurrentUserId, currentUserIdRef] = useStateRef<number | undefined>();\n  const [selectedDialog, setSelectedDialog, selectedDialogRef] = useStateRef<Dialogs.Dialog | undefined>();\n  const [chatStatus, setChatStatus, chatStatusRef] = useStateRef(ChatStatus.DISCONNECTED);\n  // refs\n  const typingTimers = useRef<{ [dialogId: string]: { [userId: number | string]: NodeJS.Timeout } }>({});\n  const onMessageRef = useRef<Chat.OnMessageListener | null>(null);\n  const onSignalRef = useRef<Chat.OnMessageSystemListener | null>(null);\n  const onMessageSentRef = useRef<Chat.OnMessageSentListener | null>(null);\n  const onMessageErrorRef = useRef<Chat.OnMessageErrorListener | null>(null);\n  const activatedDialogsRef = useRef<{ [dialogId: string]: boolean }>({});\n  const privateDialogsIdsRef = useRef<{ [userId: number | string]: string }>({});\n  // internal hooks\n  const chatBlockList = useBlockList(isConnected);\n  const chatUsers = useUsers(currentUserId);\n  const { isOnline } = useNetworkStatus();\n  const { _retrieveAndStoreUsers } = chatUsers;\n\n  const connect = async (credentials: Chat.ConnectionParams): Promise<boolean> => {\n    setChatStatus(ChatStatus.CONNECTING);\n\n    try {\n      const _isConnected = await ConnectyCube.chat.connect(credentials);\n\n      if (_isConnected) {\n        setChatStatus(ChatStatus.CONNECTED);\n        setIsConnected(_isConnected);\n        setCurrentUserId(credentials.userId);\n      }\n\n      return _isConnected;\n    } catch (error) {\n      setChatStatus(ChatStatus.DISCONNECTED);\n      console.error(`Failed to connect due to ${error}`);\n\n      return false;\n    }\n  };\n\n  const disconnect = async (status: ChatStatus = ChatStatus.DISCONNECTED): Promise<boolean> => {\n    let disconnected = false;\n\n    if (ConnectyCube.chat.isConnected) {\n      disconnected = await ConnectyCube.chat.disconnect();\n\n      setIsConnected(false);\n      setCurrentUserId(undefined);\n      setChatStatus(status);\n      _resetDialogsAndMessagesProgress();\n    }\n\n    return disconnected;\n  };\n\n  const terminate = (status: ChatStatus = ChatStatus.DISCONNECTED): void => {\n    ConnectyCube.chat.terminate();\n    setChatStatus(status);\n    _resetDialogsAndMessagesProgress();\n    _markMessagesAsLostInStore();\n  };\n\n  const _resetDialogsAndMessagesProgress = () => {\n    activatedDialogsRef.current = {};\n    setTotalDialogReached(false);\n    setTotalMessagesReached({});\n  };\n\n  const _establishConnection = async (online: boolean) => {\n    if (online) {\n      if (chatStatusRef.current === ChatStatus.DISCONNECTED) {\n        setChatStatus(ChatStatus.CONNECTING);\n      }\n    } else {\n      try {\n        await ConnectyCube.chat.pingWithTimeout(1000);\n      } catch (error) {\n        terminate();\n      }\n    }\n  };\n\n  const createChat = async (userId: number, extensions?: { [key: string]: any }): Promise<Dialogs.Dialog> => {\n    const params = { type: DialogType.PRIVATE, occupants_ids: [userId], extensions };\n    const dialog = await ConnectyCube.chat.dialog.create(params);\n\n    setDialogs((prevDialogs) => [dialog, ...prevDialogs.filter((d) => d._id !== dialog._id)]);\n    setTotalMessagesReached((prevState) => ({ ...prevState, [dialog._id]: true }));\n\n    privateDialogsIdsRef.current[userId] = dialog._id;\n\n    _notifyUsers(DialogEventSignal.NEW_DIALOG, dialog._id, userId);\n    _retrieveAndStoreUsers([userId, currentUserId as number]);\n\n    return dialog;\n  };\n\n  const createGroupChat = async (\n    usersIds: number[],\n    name: string,\n    photo?: string,\n    extensions?: { [key: string]: any },\n  ): Promise<Dialogs.Dialog> => {\n    const params = { name, photo, type: DialogType.GROUP, occupants_ids: usersIds, extensions };\n    const dialog = await ConnectyCube.chat.dialog.create(params);\n\n    setDialogs((prevDialogs) => [dialog, ...prevDialogs.filter((d) => d._id !== dialog._id)]);\n    setTotalMessagesReached((prevState) => ({ ...prevState, [dialog._id]: true }));\n\n    usersIds.forEach((userId) => {\n      _notifyUsers(DialogEventSignal.NEW_DIALOG, dialog._id, userId);\n    });\n    _retrieveAndStoreUsers([...usersIds, currentUserId as number]);\n\n    return dialog;\n  };\n\n  const getDialogs = async (filters?: Dialogs.ListParams): Promise<Dialogs.Dialog[]> => {\n    const params = { sort_desc: \"date_sent\", limit: 100, skip: 0, ...filters };\n    const { items: fetchedDialogs, skip, limit, total_entries } = await ConnectyCube.chat.dialog.list(params);\n    const reached = skip + limit >= total_entries;\n\n    setTotalDialogReached(reached);\n    setDialogs((prevDialogs) => {\n      const allDialogs = [...prevDialogs, ...fetchedDialogs];\n      const uniqueDialogs = Array.from(new Map(allDialogs.map((d) => [d._id, d])).values());\n      return uniqueDialogs.sort((a, b) => getDialogTimestamp(b) - getDialogTimestamp(a));\n    });\n\n    const usersIds = fetchedDialogs.flatMap((dialog) => dialog.occupants_ids);\n    const uniqueUsersIds = Array.from(new Set(usersIds));\n\n    _retrieveAndStoreUsers(uniqueUsersIds);\n\n    return fetchedDialogs;\n  };\n\n  const getNextDialogs = async (): Promise<Dialogs.Dialog[]> => {\n    const skip = dialogsRef.current.length;\n\n    return getDialogs({ skip });\n  };\n\n  const _listMessagesByDialogId = async (\n    dialogId: string,\n    listParams: Messages.ListParams = {},\n  ): Promise<Messages.Message[]> => {\n    const params = { chat_dialog_id: dialogId, sort_desc: \"date_sent\", limit: 100, skip: 0, ...listParams };\n\n    try {\n      const { items: fetchedMessages, skip, limit } = await ConnectyCube.chat.message.list(params);\n      const existedMessages = messagesRef.current[dialogId] ?? [];\n      const reached = skip + limit > fetchedMessages.length + existedMessages.length;\n\n      setTotalMessagesReached((prevState) => ({ ...prevState, [dialogId]: reached }));\n\n      return fetchedMessages\n        .sort((a: Messages.Message, b: Messages.Message) => {\n          return a._id.toString().localeCompare(b._id.toString()); // revers sort\n        })\n        .map((msg) => {\n          const attachments = msg.attachments?.map((attachment) => ({\n            ...attachment,\n            url: ConnectyCube.storage.privateUrl(attachment.uid),\n          }));\n          return { ...msg, attachments, status: msg.read ? MessageStatus.READ : MessageStatus.SENT };\n        });\n    } catch (error: any) {\n      if (error.code === 404) {\n        return []; // dialog not found\n      }\n      throw error;\n    }\n  };\n\n  const getMessages = async (dialogId: string): Promise<Messages.Message[]> => {\n    try {\n      const retrievedMessages = await _listMessagesByDialogId(dialogId);\n\n      setMessages((prevMessages) => ({ ...prevMessages, [dialogId]: retrievedMessages }));\n\n      return retrievedMessages;\n    } catch (error: any) {\n      throw error;\n    }\n  };\n\n  const getNextMessages = async (dialogId: string): Promise<Messages.Message[]> => {\n    const dialogMessages = messagesRef.current[dialogId] ?? [];\n    const skip = dialogMessages.length;\n\n    try {\n      const retrievedMessages = await _listMessagesByDialogId(dialogId, { skip });\n      const allDialogMessages = [...retrievedMessages, ...dialogMessages];\n\n      setMessages((prevMessages) => ({ ...prevMessages, [dialogId]: allDialogMessages }));\n\n      return allDialogMessages;\n    } catch (error: any) {\n      throw error;\n    }\n  };\n\n  const selectDialog = async (dialog?: Dialogs.Dialog): Promise<void> => {\n    setSelectedDialog(dialog);\n\n    if (!dialog) return;\n\n    // retrieve messages if chat is not activated yet\n    if (!activatedDialogsRef.current[dialog._id]) {\n      await getMessages(dialog._id);\n      activatedDialogsRef.current[dialog._id] = true;\n    }\n\n    if (dialog.unread_messages_count > 0) {\n      await markDialogAsRead(dialog).catch((_error) => {});\n    }\n  };\n\n  const getDialogOpponentId = (dialog?: Dialogs.Dialog): number | undefined => {\n    dialog ??= selectedDialog;\n\n    if (!dialog) {\n      throw \"No dialog provided. You need to provide a dialog via function argument or select a dialog via 'selectDialog'.\";\n    }\n\n    if (dialog.type !== DialogType.PRIVATE) {\n      return undefined;\n    }\n\n    const opponentId = dialog.occupants_ids.find((oid) => oid !== currentUserId);\n\n    if (opponentId) {\n      privateDialogsIdsRef.current[opponentId] = dialog._id;\n    }\n\n    return opponentId;\n  };\n\n  const _updateUnreadMessagesCount = () => {\n    const count: ChatContextType[\"unreadMessagesCount\"] = { total: 0 };\n\n    dialogs.forEach(({ _id, unread_messages_count = 0 }: Dialogs.Dialog) => {\n      if (_id !== selectedDialog?._id) {\n        count[_id] = unread_messages_count;\n        count.total += unread_messages_count;\n      }\n    });\n\n    setUnreadMessagesCount(count);\n  };\n\n  const markDialogAsRead = async (dialog: Dialogs.Dialog): Promise<void> => {\n    const params = { read: 1, chat_dialog_id: dialog._id };\n    await ConnectyCube.chat.message.update(\"\", params);\n\n    setDialogs((prevDialogs) =>\n      prevDialogs.map((d) => (d._id === dialog._id ? { ...d, unread_messages_count: 0 } : d)),\n    );\n  };\n\n  const addUsersToGroupChat = async (usersIds: number[]): Promise<void> => {\n    if (!selectedDialog) {\n      throw new Error(\"No dialog selected\");\n    }\n\n    const dialogId = selectedDialog._id;\n    const toUpdateParams = { push_all: { occupants_ids: usersIds } };\n\n    await ConnectyCube.chat.dialog.update(dialogId, toUpdateParams);\n\n    selectedDialog.occupants_ids\n      .filter((userId) => userId !== currentUserId)\n      .forEach((userId) => {\n        _notifyUsers(DialogEventSignal.ADD_PARTICIPANTS, dialogId, userId, {\n          addedParticipantsIds: usersIds.join(),\n        });\n      });\n\n    usersIds.forEach((userId) => {\n      _notifyUsers(DialogEventSignal.ADDED_TO_DIALOG, dialogId, userId);\n    });\n\n    _retrieveAndStoreUsers(usersIds);\n\n    const updatedDialog = {\n      ...selectedDialog,\n      occupants_ids: Array.from(new Set([...selectedDialog.occupants_ids, ...usersIds])),\n    };\n\n    setDialogs((prevDialogs) => prevDialogs.map((d) => (d._id === dialogId ? updatedDialog : d)));\n    setSelectedDialog(updatedDialog);\n  };\n\n  const removeUsersFromGroupChat = async (usersIds: number[]): Promise<void> => {\n    if (!selectedDialog) {\n      throw new Error(\"No dialog selected\");\n    }\n\n    const dialogId = selectedDialog._id;\n    const toUpdateParams = { pull_all: { occupants_ids: usersIds } };\n\n    await ConnectyCube.chat.dialog.update(dialogId, toUpdateParams);\n\n    usersIds.forEach((userId) => {\n      _notifyUsers(DialogEventSignal.REMOVED_FROM_DIALOG, dialogId, userId);\n    });\n\n    selectedDialog.occupants_ids\n      .filter((userId) => {\n        return !usersIds.includes(userId) && userId !== currentUserId;\n      })\n      .forEach((userId) => {\n        _notifyUsers(DialogEventSignal.REMOVE_PARTICIPANTS, dialogId, userId, {\n          removedParticipantsIds: usersIds.join(),\n        });\n      });\n\n    const updatedDialog = {\n      ...selectedDialog,\n      occupants_ids: selectedDialog.occupants_ids.filter((userId) => !usersIds.includes(userId)),\n    };\n\n    setDialogs((prevDialogs) => prevDialogs.map((d) => (d._id === dialogId ? updatedDialog : d)));\n    setSelectedDialog(updatedDialog);\n  };\n\n  const leaveGroupChat = async (): Promise<void> => {\n    if (!selectedDialog) {\n      throw new Error(\"No dialog selected\");\n    }\n\n    await ConnectyCube.chat.dialog.delete(selectedDialog._id);\n\n    selectedDialog.occupants_ids\n      .filter((userId) => userId !== currentUserId)\n      .forEach((userId) => {\n        _notifyUsers(DialogEventSignal.REMOVED_FROM_DIALOG, selectedDialog._id, userId);\n      });\n\n    setDialogs(dialogs.filter((dialog) => dialog._id !== selectedDialog._id));\n    setSelectedDialog(undefined);\n  };\n\n  const sendMessage = (body: string, dialog?: Dialogs.Dialog) => {\n    dialog ??= selectedDialog;\n\n    if (!dialog) {\n      throw \"No dialog provided. You need to provide a dialog via function argument or select a dialog via 'selectDialog'.\";\n    }\n\n    const opponentId = getDialogOpponentId(dialog);\n    const messageId = _sendMessage(body, null, dialog, opponentId);\n\n    _addMessageToStore(messageId, body, dialog._id, currentUserId as number, opponentId);\n  };\n\n  const sendMessageWithAttachment = async (files: File[], dialog?: Dialogs.Dialog): Promise<void> => {\n    dialog ??= selectedDialog;\n\n    if (!dialog) {\n      throw \"No dialog provided. You need to provide a dialog via function argument or select a dialog via 'selectDialog'.\";\n    }\n\n    const opponentId = getDialogOpponentId(dialog);\n    const tempId = Date.now() + \"\";\n    const attachments = files.map((file, index) => ({\n      uid: `local-${tempId}-${index}`, // temporary uid\n      type: file.type,\n      url: URL.createObjectURL(file),\n    }));\n\n    _addMessageToStore(tempId, \"Attachment\", dialog._id, currentUserId as number, opponentId, attachments, true);\n\n    const uploadFilesPromises = files.map((file) => {\n      const { name, type, size } = file;\n      const fileParams = { file, name, type, size, public: false };\n      return ConnectyCube.storage.createAndUpload(fileParams);\n    });\n    const uploadedFilesResults = await Promise.all(uploadFilesPromises);\n    const uploadedAttachments = uploadedFilesResults.map(({ uid, content_type = \"\" }) => ({\n      uid,\n      type: content_type,\n      url: ConnectyCube.storage.privateUrl(uid),\n    }));\n    const messageId = _sendMessage(\"Attachment\", uploadedAttachments, dialog, opponentId);\n\n    setMessages((prevMessages) => ({\n      ...prevMessages,\n      [dialog._id]: prevMessages[dialog._id].map((msg) =>\n        msg._id === tempId\n          ? {\n              ...msg,\n              _id: messageId,\n              attachments,\n              isLoading: false,\n              status: chatStatusRef.current === ChatStatus.CONNECTED ? MessageStatus.WAIT : MessageStatus.LOST,\n            }\n          : msg,\n      ),\n    }));\n  };\n\n  const _sendMessage = (\n    body: string,\n    attachments: Messages.Attachment[] | null,\n    dialog: Dialogs.Dialog,\n    opponentId?: number,\n  ): string => {\n    const messageParams: Chat.MessageParams = {\n      type: dialog.type === DialogType.PRIVATE ? ChatType.CHAT : ChatType.GROUPCHAT,\n      body,\n      extension: {\n        save_to_history: 1,\n        dialog_id: dialog._id,\n      },\n    };\n\n    if (attachments) {\n      messageParams.extension.attachments = attachments;\n    }\n\n    const messageId = ConnectyCube.chat.send(\n      dialog.type === DialogType.PRIVATE ? (opponentId as number) : dialog._id,\n      messageParams,\n    );\n\n    return messageId;\n  };\n\n  const _addMessageToStore = (\n    messageId: string,\n    body: string,\n    dialogId: string,\n    senderId: number,\n    recipientId?: number,\n    attachments?: Messages.Attachment[],\n    isLoading?: boolean,\n  ) => {\n    const ts = Math.round(new Date().getTime() / 1000);\n\n    setDialogs((prevDialogs) =>\n      prevDialogs\n        .map((dialog) =>\n          dialog._id === dialogId\n            ? {\n                ...dialog,\n                last_message: body,\n                last_message_user_id: senderId,\n                last_message_date_sent: ts,\n              }\n            : dialog,\n        )\n        .sort((a, b) => {\n          const dateA = parseDate(a.last_message_date_sent) || (parseDate(a.created_at) as number);\n          const dateB = parseDate(b.last_message_date_sent) || (parseDate(b.created_at) as number);\n          return dateB - dateA;\n        }),\n    );\n\n    setMessages((prevMessages) => ({\n      ...prevMessages,\n      [dialogId]: [\n        ...(prevMessages[dialogId] || []),\n        {\n          _id: messageId,\n          created_at: ts,\n          updated_at: ts,\n          chat_dialog_id: dialogId,\n          message: body,\n          sender_id: senderId,\n          recipient_id: recipientId as any,\n          date_sent: ts,\n          read: 0,\n          read_ids: [senderId],\n          delivered_ids: [senderId],\n          views_count: 0,\n          attachments: attachments ? attachments : [],\n          reactions: {} as any,\n          isLoading,\n          status: chatStatusRef.current === ChatStatus.CONNECTED ? MessageStatus.WAIT : MessageStatus.LOST,\n        },\n      ],\n    }));\n  };\n\n  const _updateMessageStatusInStore = (status: MessageStatus, messageId: string, dialogId: string, userId?: number) => {\n    setMessages((prevMessages) => ({\n      ...prevMessages,\n      [dialogId]:\n        prevMessages[dialogId]?.map((message) =>\n          message._id === messageId\n            ? {\n                ...message,\n                read_ids: userId\n                  ? message.read_ids\n                    ? [...new Set([...message.read_ids, userId])]\n                    : [userId]\n                  : message.read_ids,\n                read: status === MessageStatus.READ ? 1 : message.read,\n                status:\n                  status === MessageStatus.SENT && message.status === MessageStatus.LOST ? message.status : status,\n              }\n            : message,\n        ) ?? [],\n    }));\n  };\n\n  const _markMessagesAsLostInStore = () => {\n    setMessages((prevMessages) =>\n      Object.fromEntries(\n        Object.entries(prevMessages).map(([dialogId, messages]) => [\n          dialogId,\n          messages.map((message) =>\n            message.status === MessageStatus.WAIT ? { ...message, status: MessageStatus.LOST } : message,\n          ),\n        ]),\n      ),\n    );\n  };\n\n  const readMessage = (messageId: string, userId: number, dialogId: string) => {\n    ConnectyCube.chat.sendReadStatus({ messageId, userId, dialogId });\n\n    _updateMessageStatusInStore(MessageStatus.READ, messageId, dialogId, userId);\n\n    setDialogs((prevDialogs) =>\n      prevDialogs.map((dialog) =>\n        dialog._id === dialogId\n          ? {\n              ...dialog,\n              unread_messages_count: Math.max(0, dialog.unread_messages_count - 1),\n            }\n          : dialog,\n      ),\n    );\n  };\n\n  const _notifyUsers = (command: string, dialogId: string, userId: number, params: any = {}) => {\n    const msg = { body: command, extension: { dialogId, ...params } };\n\n    ConnectyCube.chat.sendSystemMessage(userId, msg);\n  };\n\n  const sendSignal = (userIdOrIds: number | number[], signal: string, params: any = {}) => {\n    const receivers = Array.isArray(userIdOrIds) ? userIdOrIds : [userIdOrIds];\n    const msg = { body: signal, extension: params };\n\n    receivers.forEach((userId) => {\n      ConnectyCube.chat.sendSystemMessage(userId, msg);\n    });\n  };\n\n  const sendTypingStatus = (dialog?: Dialogs.Dialog) => {\n    dialog ??= selectedDialog;\n\n    if (!dialog) {\n      throw \"No dialog provided. You need to provide a dialog via function argument or select a dialog via 'selectDialog'.\";\n    }\n\n    ConnectyCube.chat.sendIsTypingStatus(\n      dialog.type === DialogType.PRIVATE ? (getDialogOpponentId(dialog) as number) : dialog._id,\n    );\n  };\n\n  const _updateTypingStatus = (dialogId: string, userId: number, isTyping: boolean) => {\n    setTypingStatus((prevTypingStatus) => {\n      const prevUsersIds = prevTypingStatus[dialogId];\n      const nextUsersIds = prevUsersIds ? new Set<number>(prevUsersIds) : new Set<number>();\n\n      isTyping ? nextUsersIds.add(userId) : nextUsersIds.delete(userId);\n\n      return { ...prevTypingStatus, [dialogId]: [...nextUsersIds] };\n    });\n  };\n\n  const _clearTypingStatus = (dialogId: string, userId: number) => {\n    _updateTypingStatus(dialogId, userId, false);\n    clearTimeout(typingTimers.current[dialogId]?.[userId]);\n    delete typingTimers.current[dialogId]?.[userId];\n  };\n\n  const _getPrivateDialogIdByUserId = (userId: number): string | undefined => {\n    let dialogId: string | undefined = privateDialogsIdsRef.current[userId];\n\n    if (!dialogId) {\n      const dialog = dialogsRef.current.find(\n        (dialog) => dialog.type === DialogType.PRIVATE && getDialogOpponentId(dialog) === userId,\n      );\n\n      if (dialog) {\n        dialogId = dialog._id;\n        privateDialogsIdsRef.current[userId] = dialogId;\n      }\n    }\n\n    return dialogId;\n  };\n\n  const lastMessageSentTimeString = (dialog: Dialogs.Dialog): string => {\n    return formatDistanceToNow(\n      dialog.last_message_date_sent ? (dialog.last_message_date_sent as number) * 1000 : (dialog.created_at as string),\n      {\n        addSuffix: true,\n      },\n    );\n  };\n\n  const messageSentTimeString = (message: Messages.Message): string => {\n    return formatDistanceToNow((message.date_sent as number) * 1000, {\n      addSuffix: true,\n    });\n  };\n\n  const processOnMessage = (callbackFn: Chat.OnMessageListener | null) => {\n    onMessageRef.current = callbackFn;\n  };\n\n  const processOnSignal = (callbackFn: Chat.OnMessageSystemListener | null) => {\n    onSignalRef.current = callbackFn;\n  };\n\n  const processOnMessageError = (callbackFn: Chat.OnMessageErrorListener | null) => {\n    onMessageErrorRef.current = callbackFn;\n  };\n\n  const processOnMessageSent = (callbackFn: Chat.OnMessageSentListener | null) => {\n    onMessageSentRef.current = callbackFn;\n  };\n\n  const _processDisconnect = () => {\n    if (chatStatusRef.current !== ChatStatus.CONNECTING) {\n      setChatStatus(ChatStatus.DISCONNECTED);\n      _resetDialogsAndMessagesProgress();\n    }\n\n    _markMessagesAsLostInStore();\n  };\n\n  const _processReconnect = () => {\n    setChatStatus(ChatStatus.CONNECTED);\n  };\n\n  const _processConnectionError = async (\n    error: {\n      name?: string;\n      text?: string;\n      condition?: string;\n      [key: string]: any;\n    } = {},\n  ) => {\n    if (\n      error?.condition === \"not-authorized\" ||\n      error?.text === \"Password not verified\" ||\n      error?.name === \"SASLError\"\n    ) {\n      const isDisconnected = await disconnect(ChatStatus.NOT_AUTHORIZED);\n\n      if (!isDisconnected) {\n        terminate(ChatStatus.NOT_AUTHORIZED);\n      }\n    } else {\n      setChatStatus(ChatStatus.ERROR);\n    }\n  };\n\n  const _processMessage = (userId: number, message: Chat.Message) => {\n    if (onMessageRef.current) {\n      onMessageRef.current(userId, message);\n    }\n\n    // TODO: handle multi-device & delivered private messages with delay (from offline)\n    if (userId === currentUserIdRef.current || (message.delay && message.type === ChatType.CHAT)) {\n      return;\n    }\n\n    const currentDialog = selectedDialogRef.current;\n    const dialogId = message.dialog_id as string;\n    const messageId = message.id;\n    const body = message.body || \"\";\n    const opponentId = message.type === ChatType.CHAT ? (currentUserIdRef.current as number) : undefined;\n\n    const attachments =\n      message.extension.attachments?.length > 0\n        ? message.extension.attachments.map((attachment: Messages.Attachment) => ({\n            ...attachment,\n            url: ConnectyCube.storage.privateUrl(attachment.uid),\n          }))\n        : undefined;\n\n    _addMessageToStore(messageId, body, dialogId, userId, opponentId, attachments);\n    _clearTypingStatus(dialogId, userId);\n\n    setDialogs((prevDialogs) =>\n      prevDialogs.map((dialog) =>\n        dialog._id === dialogId\n          ? {\n              ...dialog,\n              unread_messages_count:\n                !currentDialog || currentDialog._id !== message.dialog_id\n                  ? (dialog.unread_messages_count || 0) + 1\n                  : dialog.unread_messages_count,\n              last_message: message.body,\n              last_message_date_sent: parseInt(message.extension.date_sent),\n            }\n          : dialog,\n      ),\n    );\n  };\n\n  const _processErrorMessage = (messageId: string, error: { code: number; info: string }) => {\n    if (onMessageErrorRef.current) {\n      onMessageErrorRef.current(messageId, error);\n    }\n  };\n\n  const _processSentMessage = (lost: Chat.MessageParams | null, sent: Chat.MessageParams | null) => {\n    if (onMessageSentRef.current) {\n      onMessageSentRef.current(lost, sent);\n    }\n\n    const dialogId = sent?.extension.dialog_id;\n    const messageId = sent?.id;\n\n    if (dialogId && messageId) {\n      _updateMessageStatusInStore(MessageStatus.SENT, messageId, dialogId);\n    }\n  };\n\n  const _processSystemMessage = async (message: Chat.SystemMessage) => {\n    const dialogId = message.extension.dialogId;\n    const senderId = message.userId;\n\n    if (onSignalRef.current) {\n      onSignalRef.current(message);\n    }\n\n    // TODO: handle multi-device\n    if (senderId === currentUserIdRef.current) return;\n\n    switch (message.body) {\n      case DialogEventSignal.NEW_DIALOG:\n      case DialogEventSignal.ADDED_TO_DIALOG: {\n        const result = await ConnectyCube.chat.dialog.list({ _id: dialogId });\n        const dialog = result.items[0];\n\n        _retrieveAndStoreUsers(dialog.occupants_ids);\n        setDialogs((prevDialogs) => [dialog, ...prevDialogs.filter((d) => d._id !== dialog._id)]);\n\n        break;\n      }\n\n      case DialogEventSignal.ADD_PARTICIPANTS: {\n        const usersIds = message.extension.addedParticipantsIds.split(\",\").map(Number) as number[];\n\n        _retrieveAndStoreUsers(usersIds);\n        setDialogs((prevDialogs) =>\n          prevDialogs.map((d) => {\n            if (d._id === dialogId) {\n              d.occupants_ids = Array.from(new Set([...d.occupants_ids, ...usersIds]));\n            }\n            return d;\n          }),\n        );\n\n        break;\n      }\n\n      case DialogEventSignal.REMOVE_PARTICIPANTS: {\n        const usersIds = message.extension.removedParticipantsIds.split(\",\").map(Number);\n\n        setDialogs((prevDialogs) =>\n          prevDialogs.map((d) => {\n            if (d._id === dialogId) {\n              d.occupants_ids = d.occupants_ids.filter((id) => !usersIds.includes(id));\n            }\n            return d;\n          }),\n        );\n\n        break;\n      }\n\n      case DialogEventSignal.REMOVED_FROM_DIALOG: {\n        setDialogs((prevDialogs) =>\n          prevDialogs.map((d) => {\n            if (d._id === dialogId && d.type !== DialogType.PRIVATE) {\n              d.occupants_ids = d.occupants_ids.filter((id) => id !== senderId);\n            }\n            return d;\n          }),\n        );\n\n        break;\n      }\n    }\n  };\n\n  const _processReadMessageStatus = (messageId: string, dialogId: string, userId: number) => {\n    // TODO: handle multi-device\n    if (userId === currentUserIdRef.current) return;\n\n    _updateMessageStatusInStore(MessageStatus.READ, messageId, dialogId, userId);\n  };\n\n  const _processTypingMessageStatus = (isTyping: boolean, userId: number, dialogId: string | null) => {\n    const _dialogId = dialogId || _getPrivateDialogIdByUserId(userId);\n\n    // TODO: handle multi-device\n    if (!_dialogId || !userId || userId === currentUserIdRef.current) return;\n\n    _updateTypingStatus(_dialogId, userId, isTyping);\n\n    if (!typingTimers.current[_dialogId]) {\n      typingTimers.current[_dialogId] = {};\n    }\n\n    if (isTyping) {\n      if (typingTimers.current[_dialogId][userId]) {\n        clearTimeout(typingTimers.current[_dialogId][userId]);\n        delete typingTimers.current[_dialogId][userId];\n      }\n\n      typingTimers.current[_dialogId][userId] = setTimeout(() => {\n        _clearTypingStatus(_dialogId, userId);\n      }, 6000);\n    } else {\n      _clearTypingStatus(_dialogId, userId);\n    }\n  };\n\n  useEffect(() => {\n    ConnectyCube.chat.addListener(ChatEvent.DISCONNECTED, _processDisconnect);\n    ConnectyCube.chat.addListener(ChatEvent.RECONNECTED, _processReconnect);\n    ConnectyCube.chat.addListener(ChatEvent.ERROR, _processConnectionError);\n    ConnectyCube.chat.addListener(ChatEvent.MESSAGE, _processMessage);\n    ConnectyCube.chat.addListener(ChatEvent.ERROR_MESSAGE, _processErrorMessage);\n    ConnectyCube.chat.addListener(ChatEvent.SENT_MESSAGE, _processSentMessage);\n    ConnectyCube.chat.addListener(ChatEvent.SYSTEM_MESSAGE, _processSystemMessage);\n    ConnectyCube.chat.addListener(ChatEvent.READ_MESSAGE, _processReadMessageStatus);\n    ConnectyCube.chat.addListener(ChatEvent.TYPING_MESSAGE, _processTypingMessageStatus);\n\n    return () => {\n      ConnectyCube.chat.removeAllListeners();\n    };\n  }, []);\n\n  useEffect(() => {\n    _updateUnreadMessagesCount();\n  }, [dialogs]);\n\n  useEffect(() => {\n    _establishConnection(isOnline);\n  }, [isOnline]);\n\n  return (\n    <ChatContext.Provider\n      value={{\n        isOnline,\n        isConnected,\n        chatStatus,\n        connect,\n        disconnect,\n        terminate,\n        currentUserId,\n        selectDialog,\n        selectedDialog,\n        getDialogOpponentId,\n        unreadMessagesCount,\n        getMessages,\n        getNextMessages,\n        totalMessagesReached,\n        messages,\n        sendSignal,\n        sendMessage,\n        dialogs,\n        getDialogs,\n        getNextDialogs,\n        totalDialogReached,\n        createChat,\n        createGroupChat,\n        sendTypingStatus,\n        typingStatus,\n        sendMessageWithAttachment,\n        markDialogAsRead,\n        removeUsersFromGroupChat,\n        addUsersToGroupChat,\n        leaveGroupChat,\n        readMessage,\n        lastMessageSentTimeString,\n        messageSentTimeString,\n        processOnSignal,\n        processOnMessage,\n        processOnMessageError,\n        processOnMessageSent,\n        ...chatBlockList,\n        ...chatUsers.exports,\n      }}\n    >\n      {children}\n    </ChatContext.Provider>\n  );\n};\n","import { useEffect, useState } from \"react\";\n\nexport type NetworkStatusHook = {\n  isOnline: boolean;\n};\n\nfunction useNetworkStatus(): NetworkStatusHook {\n  const [isOnline, setIsOnline] = useState<boolean>(navigator.onLine);\n\n  useEffect(() => {\n    const abortController1 = new AbortController();\n    const abortController2 = new AbortController();\n\n    window.addEventListener(\n      \"online\",\n      () => {\n        setIsOnline(true);\n      },\n      {\n        signal: abortController1.signal,\n      },\n    );\n    window.addEventListener(\n      \"offline\",\n      () => {\n        setIsOnline(false);\n      },\n      {\n        signal: abortController2.signal,\n      },\n    );\n\n    return () => {\n      abortController1.abort();\n      abortController2.abort();\n    };\n  }, []);\n\n  return {\n    isOnline,\n  };\n}\n\nexport default useNetworkStatus;\n"],"names":["react_1","require$$0","dist","initialState","_a","useState","state","setState","ref","useRef","useCallback","setStateAction","current","isFunction","minutesInMonth","constructFromSymbol","Symbol","for","constructFrom","date","value","Date","constructor","toDate","argument","context","defaultOptions","getDefaultOptions","getTimezoneOffsetInMilliseconds","_date","utcDate","UTC","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","getMilliseconds","setUTCFullYear","normalizeDates","dates","normalize","bind","find","map","compareAsc","dateLeft","dateRight","diff","isLastDayOfMonth","options","setHours","endOfDay","month","setFullYear","endOfMonth","differenceInMonths","laterDate","earlierDate","laterDate_","workingLaterDate","earlierDate_","in","sign","difference","Math","abs","differenceInCalendarMonths","setDate","setMonth","isLastMonthNotFull","result","differenceInSeconds","differenceInMilliseconds","method","roundingMethod","number","trunc","formatDistanceLocale","lessThanXSeconds","one","other","xSeconds","halfAMinute","lessThanXMinutes","xMinutes","aboutXHours","xHours","xDays","aboutXWeeks","xWeeks","aboutXMonths","xMonths","aboutXYears","xYears","overXYears","almostXYears","buildFormatLongFn","args","width","String","defaultWidth","formats","formatLong","full","long","medium","short","time","dateTime","formatRelativeLocale","lastWeek","yesterday","today","tomorrow","nextWeek","buildLocalizeFn","valuesArray","formattingValues","defaultFormattingWidth","values","argumentCallback","buildMatchFn","string","matchPattern","matchPatterns","defaultMatchWidth","matchResult","match","matchedString","parsePatterns","defaultParseWidth","key","Array","isArray","array","predicate","length","findIndex","pattern","test","object","Object","prototype","hasOwnProperty","call","findKey","valueCallback","rest","slice","enUS","code","formatDistance","token","count","tokenValue","replace","toString","addSuffix","comparison","formatRelative","_baseDate","_options","localize","ordinalNumber","dirtyNumber","Number","rem100","era","narrow","abbreviated","wide","quarter","day","dayPeriod","am","pm","midnight","noon","morning","afternoon","evening","night","parsePattern","parseInt","parseResult","any","index","weekStartsOn","firstWeekContainsDate","formatDistanceToNow","locale","defaultLocale","isNaN","RangeError","localizeOptions","assign","seconds","offsetInSeconds","minutes","round","months","includeSeconds","hours","days","nearestMonth","monthsSinceStartOfYear","years","now","constructNow","DialogEventSignal","MessageStatus","ChatStatus","BLOCK_LIST_LOG_TAG","BLOCK_LIST_NAME","useBlockList","isConnected","Set","isApplied","isBlocked","userId","has","upsert","async","user_id","action","console","warn","newState","blockList","name","items","mutualBlock","PrivacyListAction","DENY","add","ALLOW","delete","ConnectyCube","chat","privacylist","setAsDefault","update","size","create","error","useEffect","getNames","default","getList","reduce","list","item","fetch","blockedUsers","from","isBlockedUser","unblockUser","blockUser","parseDate","t","getTime","undefined","getLastActivityText","status","MINUTE_IN_SEC","ceil","lastLoggedInTime","getUTCDate","padStart","getDialogTimestamp","dialog","last_message_date_sent","updated_at","created_at","USERS_LOG_TAG","MAX_REQUEST_LIMIT","useUsers","currentUserId","users","setUsers","onlineUsers","setOnlineUsers","onlineUsersCount","setOnlineUsersCount","lastActivity","setLastActivity","onlineUsersLastRequestAtRef","fetchUsersLastRequestAtRef","getAndStoreUsers","params","getV2","prevUsersState","user","id","prevState","forEach","searchUsers","term","usersWithFullName","full_name","start_with","limit","usersWithLogin","login","usersMap","Map","set","filter","getOnlineUsersCount","nextOnlineUsersCount","getOnlineCount","addListener","ChatEvent","USER_LAST_ACTIVITY","prevLastActivity","removeListener","_retrieveAndStoreUsers","usersIds","usersToFind","exports","fetchUserById","force","lastRequestedAt","shouldRequest","fetchedUser","listOnlineUsers","currentTimestamp","onlineUsersState","promises","offset","push","listOnline","then","allUsers","Promise","all","flat","_listOnline","listOnlineUsersWithParams","getLastActivity","getLastUserActivity","subscribeToUserLastActivityStatus","unsubscribeFromUserLastActivityStatus","ChatContext","createContext","displayName","children","setIsConnected","unreadMessagesCount","setUnreadMessagesCount","total","typingStatus","setTypingStatus","totalMessagesReached","setTotalMessagesReached","totalDialogReached","setTotalDialogReached","messages","setMessages","messagesRef","useStateRef","dialogs","setDialogs","dialogsRef","setCurrentUserId","currentUserIdRef","selectedDialog","setSelectedDialog","selectedDialogRef","chatStatus","setChatStatus","chatStatusRef","DISCONNECTED","typingTimers","onMessageRef","onSignalRef","onMessageSentRef","onMessageErrorRef","activatedDialogsRef","privateDialogsIdsRef","chatBlockList","chatUsers","isOnline","setIsOnline","navigator","onLine","abortController1","AbortController","abortController2","window","addEventListener","signal","abort","useNetworkStatus","disconnect","disconnected","_resetDialogsAndMessagesProgress","terminate","_markMessagesAsLostInStore","getDialogs","filters","sort_desc","skip","fetchedDialogs","total_entries","prevDialogs","allDialogs","d","_id","sort","a","b","flatMap","occupants_ids","uniqueUsersIds","_listMessagesByDialogId","dialogId","listParams","chat_dialog_id","fetchedMessages","message","existedMessages","reached","localeCompare","msg","attachments","attachment","url","storage","privateUrl","uid","read","READ","SENT","getMessages","retrievedMessages","prevMessages","getDialogOpponentId","type","DialogType","PRIVATE","opponentId","oid","markDialogAsRead","unread_messages_count","_sendMessage","body","messageParams","ChatType","CHAT","GROUPCHAT","extension","save_to_history","dialog_id","send","_addMessageToStore","messageId","senderId","recipientId","isLoading","ts","last_message","last_message_user_id","dateA","sender_id","recipient_id","date_sent","read_ids","delivered_ids","views_count","reactions","CONNECTED","WAIT","LOST","_updateMessageStatusInStore","fromEntries","entries","_notifyUsers","command","sendSystemMessage","_updateTypingStatus","isTyping","prevTypingStatus","prevUsersIds","nextUsersIds","_clearTypingStatus","clearTimeout","_processDisconnect","CONNECTING","_processReconnect","_processConnectionError","condition","text","NOT_AUTHORIZED","ERROR","_processMessage","delay","currentDialog","_processErrorMessage","_processSentMessage","lost","sent","_processSystemMessage","NEW_DIALOG","ADDED_TO_DIALOG","ADD_PARTICIPANTS","addedParticipantsIds","split","REMOVE_PARTICIPANTS","removedParticipantsIds","includes","REMOVED_FROM_DIALOG","_processReadMessageStatus","_processTypingMessageStatus","_dialogId","_getPrivateDialogIdByUserId","setTimeout","RECONNECTED","MESSAGE","ERROR_MESSAGE","SENT_MESSAGE","SYSTEM_MESSAGE","READ_MESSAGE","TYPING_MESSAGE","removeAllListeners","_updateUnreadMessagesCount","online","pingWithTimeout","_establishConnection","_jsx","Provider","connect","credentials","_isConnected","selectDialog","catch","_error","getNextMessages","dialogMessages","allDialogMessages","sendSignal","userIdOrIds","receivers","sendMessage","getNextDialogs","createChat","extensions","createGroupChat","photo","GROUP","sendTypingStatus","sendIsTypingStatus","sendMessageWithAttachment","files","tempId","file","URL","createObjectURL","uploadFilesPromises","fileParams","public","createAndUpload","uploadedAttachments","content_type","removeUsersFromGroupChat","Error","toUpdateParams","pull_all","join","updatedDialog","addUsersToGroupChat","push_all","leaveGroupChat","readMessage","sendReadStatus","max","lastMessageSentTimeString","messageSentTimeString","processOnSignal","callbackFn","processOnMessage","processOnMessageError","processOnMessageSent","useContext"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28]}