PageSourceSearch

https://www.ammina-shop.ru/bitrix/js/main/date/main.date.js?174147245734530

js ammina-shop.ru collected 2026-09-30 15:27:55 UTC 34,530 bytes, 1,144 lines download raw bytes

1;(function(window)
2{
3	/****************** ATTENTION *******************************
4	 * Please do not use Bitrix CoreJS in this class.
5	 * This class can be called on page without Bitrix Framework
6	*************************************************************/
7
8	if (!window.BX)
9	{
10		window.BX = {};
11	}
12
13	if (!window.BX.Main)
14	{
15		window.BX.Main = {};
16	}
17	else if (window.BX.Main.Date)
18	{
19		return;
20	}
21
22	var BX = window.BX;
23
24	BX.Main.Date = {
25
26		AM_PM_MODE: {
27			UPPER: 1,
28			LOWER: 2,
29			NONE: false
30		},
31
32		format: function(format, timestamp, now, utc)
33		{
34			var _this = this;
35
36			/*
37			PHP to Javascript:
38				time() = new Date()
39				mktime(...) = new Date(...)
40				gmmktime(...) = new Date(Date.UTC(...))
41				mktime(0,0,0, 1, 1, 1970) != 0          new Date(1970,0,1).getTime() != 0
42				gmmktime(0,0,0, 1, 1, 1970) == 0        new Date(Date.UTC(1970,0,1)).getTime() == 0
43				date("d.m.Y H:i:s") = BX.Main.Date.format("d.m.Y H:i:s")
44				gmdate("d.m.Y H:i:s") = BX.Main.Date.format("d.m.Y H:i:s", null, null, true);
45			*/
46			var date = Utils.isDate(timestamp) ? new Date(timestamp.getTime()) : Utils.isNumber(timestamp) ? new Date(timestamp * 1000) : new Date();
47			var nowDate = Utils.isDate(now) ? new Date(now.getTime()) : Utils.isNumber(now) ? new Date(now * 1000) : new Date();
48			var isUTC = !!utc;
49
50			if (Utils.isArray(format))
51				return _formatDateInterval(format, date, nowDate, isUTC);
52			else if (!Utils.isNotEmptyString(format))
53				return "";
54
55			var replaceMap = (format.match(/{{([^{}]*)}}/g) || []).map(function(x) { return (x.match(/[^{}]+/) || [''])[0]; });
56			if (replaceMap.length > 0)
57			{
58				replaceMap.forEach(function(element, index) {
59					format = format.replace("{{"+element+"}}", "{{"+index+"}}");
60				});
61			}
62
63			var formatRegex = /\\?(sago|iago|isago|Hago|dago|mago|Yago|sdiff|idiff|Hdiff|ddiff|mdiff|Ydiff|sshort|ishort|Hshort|dshort|mhort|Yshort|yesterday|today|tommorow|tomorrow|[a-z])/gi;
64
65			var dateFormats = {
66				d : function() {
67					// Day of the month 01 to 31
68					return Utils.strPadLeft(getDate(date).toString(), 2, "0");
69				},
70
71				D : function() {
72					//Mon through Sun
73					return _this._getMessage("DOW_" + getDay(date));
74				},
75
76				j : function() {
77					//Day of the month 1 to 31
78					return getDate(date);
79				},
80
81				l : function() {
82					//Sunday through Saturday
83					return _this._getMessage("DAY_OF_WEEK_" + getDay(date));
84				},
85
86				N : function() {
87					//1 (for Monday) through 7 (for Sunday)
88					return getDay(date) || 7;
89				},
90
91				S : function() {
92					//st, nd, rd or th. Works well with j
93					if (getDate(date) % 10 == 1 && getDate(date) != 11)
94						return "st";
95					else if (getDate(date) % 10 == 2 && getDate(date) != 12)
96						return "nd";
97					else if (getDate(date) % 10 == 3 && getDate(date) != 13)
98						return "rd";
99					else
100						return "th";
101				},
102
103				w : function() {
104					//0 (for Sunday) through 6 (for Saturday)
105					return getDay(date);
106				},
107
108				z : function() {
109					//0 through 365
110					var firstDay = new Date(getFullYear(date), 0, 1);
111					var currentDay = new Date(getFullYear(date), getMonth(date), getDate(date));
112					return Math.ceil( (currentDay - firstDay) / (24 * 3600 * 1000) );
113				},
114
115				W : function() {
116					//ISO-8601 week number of year
117					var newDate  = new Date(date.getTime());
118					var dayNumber   = (getDay(date) + 6) % 7;
119					setDate(newDate, getDate(newDate) - dayNumber + 3);
120					var firstThursday = newDate.getTime();
121					setMonth(newDate, 0, 1);
122					if (getDay(newDate) != 4)
123						setMonth(newDate, 0, 1 + ((4 - getDay(newDate)) + 7) % 7);
124					var weekNumber = 1 + Math.ceil((firstThursday - newDate) / (7 * 24 * 3600 * 1000));
125					return Utils.strPadLeft(weekNumber.toString(), 2, "0");
126				},
127
128				F : function() {
129					//January through December
130					return _this._getMessage("MONTH_" + (getMonth(date) + 1) + "_S");
131				},
132
133				f : function() {
134					//January through December
135					return _this._getMessage("MONTH_" + (getMonth(date) + 1));
136				},
137
138				m : function() {
139					//Numeric representation of a month 01 through 12
140					return Utils.strPadLeft((getMonth(date) + 1).toString(), 2, "0");
141				},
142
143				M : function() {
144					//A short textual representation of a month, three letters Jan through Dec
145					return _this._getMessage("MON_" + (getMonth(date) + 1));
146				},
147
148				n : function() {
149					//Numeric representation of a month 1 through 12
150					return getMonth(date) + 1;
151				},
152
153				t : function() {
154					//Number of days in the given month 28 through 31
155					var lastMonthDay = isUTC ? new Date(Date.UTC(getFullYear(date), getMonth(date) + 1, 0)) : new Date(getFullYear(date), getMonth(date) + 1, 0);
156					return getDate(lastMonthDay);
157				},
158
159				L : function() {
160					//1 if it is a leap year, 0 otherwise.
161					var year = getFullYear(date);
162					return (year % 4 == 0 && year % 100 != 0 || year % 400 == 0 ? 1 : 0);
163				},
164
165				o : function() {
166					//ISO-8601 year number
167					var correctDate  = new Date(date.getTime());
168					setDate(correctDate, getDate(correctDate) - ((getDay(date) + 6) % 7) + 3);
169					return getFullYear(correctDate);
170				},
171
172				Y : function() {
173					//A full numeric representation of a year, 4 digits
174					return getFullYear(date);
175				},
176
177				y : function() {
178					//A two digit representation of a year
179					return getFullYear(date).toString().slice(2);
180				},
181
182				a : function() {
183					//am or pm
184					return getHours(date) > 11 ? "pm" : "am";
185				},
186
187				A : function() {
188					//AM or PM
189					return getHours(date) > 11 ? "PM" : "AM";
190				},
191
192				B : function() {
193					//000 through 999
194					var swatch = ((date.getUTCHours() + 1) % 24) + date.getUTCMinutes() / 60 + date.getUTCSeconds() / 3600;
195					return Utils.strPadLeft(Math.floor(swatch * 1000 / 24).toString(), 3, "0");
196				},
197
198				g : function() {
199					//12-hour format of an hour without leading zeros 1 through 12
200					return getHours(date) % 12 || 12;
201				},
202
203				G : function() {
204					//24-hour format of an hour without leading zeros 0 through 23
205					return getHours(date);
206				},
207
208				h : function() {
209					//12-hour format of an hour with leading zeros 01 through 12
210					return Utils.strPadLeft((getHours(date) % 12 || 12).toString(), 2, "0");
211				},
212
213				H : function() {
214					//24-hour format of an hour with leading zeros 00 through 23
215					return Utils.strPadLeft(getHours(date).toString(), 2, "0");
216				},
217
218				i : function() {
219					//Minutes with leading zeros 00 to 59
220					return Utils.strPadLeft(getMinutes(date).toString(), 2, "0");
221				},
222
223				s : function() {
224					//Seconds, with leading zeros 00 through 59
225					return Utils.strPadLeft(getSeconds(date).toString(), 2, "0");
226				},
227
228				u : function() {
229					//Microseconds
230					return Utils.strPadLeft((getMilliseconds(date) * 1000).toString(), 6, "0");
231				},
232
233				e : function() {
234					if (isUTC)
235						return "UTC";
236					return "";
237				},
238
239				I : function() {
240					if (isUTC)
241						return 0;
242
243					//Whether or not the date is in daylight saving time 1 if Daylight Saving Time, 0 otherwise
244					var firstJanuary = new Date(getFullYear(date), 0, 1);
245					var firstJanuaryUTC = Date.UTC(getFullYear(date), 0, 1);
246					var firstJuly = new Date(getFullYear(date), 6, 0);
247					var firstJulyUTC = Date.UTC(getFullYear(date), 6, 0);
248					return 0 + ((firstJanuary - firstJanuaryUTC) !== (firstJuly - firstJulyUTC));
249				},
250
251				O : function() {
252					if (isUTC)
253						return "+0000";
254
255					//Difference to Greenwich time (GMT) in hours +0200
256					var timezoneOffset = date.getTimezoneOffset();
257					var timezoneOffsetAbs = Math.abs(timezoneOffset);
258					return (timezoneOffset > 0 ? "-" : "+") + Utils.strPadLeft((Math.floor(timezoneOffsetAbs / 60) * 100 + timezoneOffsetAbs % 60).toString(), 4, "0");
259				},
260
261				P : function() {
262					if (isUTC)
263						return "+00:00";
264
265					//Difference to Greenwich time (GMT) with colon between hours and minutes +02:00
266					var difference = this.O();
267					return difference.substr(0, 3) + ":" + difference.substr(3);
268				},
269
270				Z : function() {
271					if (isUTC)
272						return 0;
273					//Timezone offset in seconds. The offset for timezones west of UTC is always negative,
274					//and for those east of UTC is always positive.
275					return -date.getTimezoneOffset() * 60;
276				},
277
278				c : function() {
279					//ISO 8601 date
280					return "Y-m-d\\TH:i:sP".replace(formatRegex, _replaceDateFormat);
281				},
282
283				r : function() {
284					//RFC 2822 formatted date
285					return "D, d M Y H:i:s O".replace(formatRegex, _replaceDateFormat);
286				},
287
288				U : function() {
289					//Seconds since the Unix Epoch
290					return Math.floor(date.getTime() / 1000);
291				},
292
293				sago : function() {
294					return _formatDateMessage(intval((nowDate - date) / 1000), {
295						"0" : "FD_SECOND_AGO_0",
296						"1" : "FD_SECOND_AGO_1",
297						"10_20" : "FD_SECOND_AGO_10_20",
298						"MOD_1" : "FD_SECOND_AGO_MOD_1",
299						"MOD_2_4" : "FD_SECOND_AGO_MOD_2_4",
300						"MOD_OTHER" : "FD_SECOND_AGO_MOD_OTHER"
301					});
302				},
303
304				sdiff : function() {
305					return _formatDateMessage(intval((nowDate - date) / 1000), {
306						"0" : "FD_SECOND_DIFF_0",
307						"1" : "FD_SECOND_DIFF_1",
308						"10_20" : "FD_SECOND_DIFF_10_20",
309						"MOD_1" : "FD_SECOND_DIFF_MOD_1",
310						"MOD_2_4" : "FD_SECOND_DIFF_MOD_2_4",
311						"MOD_OTHER" : "FD_SECOND_DIFF_MOD_OTHER"
312					});
313				},
314
315				sshort : function() {
316					return _this._getMessage("FD_SECOND_SHORT").replace(/#VALUE#/g, intval((nowDate - date) / 1000));
317				},
318
319				iago : function() {
320					return _formatDateMessage(intval((nowDate - date) / 60 / 1000), {
321						"0" : "FD_MINUTE_AGO_0",
322						"1" : "FD_MINUTE_AGO_1",
323						"10_20" : "FD_MINUTE_AGO_10_20",
324						"MOD_1" : "FD_MINUTE_AGO_MOD_1",
325						"MOD_2_4" : "FD_MINUTE_AGO_MOD_2_4",
326						"MOD_OTHER" : "FD_MINUTE_AGO_MOD_OTHER"
327					});
328				},
329
330				idiff : function() {
331					return _formatDateMessage(intval((nowDate - date) / 60 / 1000), {
332						"0" : "FD_MINUTE_DIFF_0",
333						"1" : "FD_MINUTE_DIFF_1",
334						"10_20" : "FD_MINUTE_DIFF_10_20",
335						"MOD_1" : "FD_MINUTE_DIFF_MOD_1",
336						"MOD_2_4" : "FD_MINUTE_DIFF_MOD_2_4",
337						"MOD_OTHER" : "FD_MINUTE_DIFF_MOD_OTHER"
338					});
339				},
340
341				isago : function() {
342					var minutesAgo = intval((nowDate - date) / 60 / 1000);
343					var result = _formatDateMessage(minutesAgo, {
344						"0" : "FD_MINUTE_0",
345						"1" : "FD_MINUTE_1",
346						"10_20" : "FD_MINUTE_10_20",
347						"MOD_1" : "FD_MINUTE_MOD_1",
348						"MOD_2_4" : "FD_MINUTE_MOD_2_4",
349						"MOD_OTHER" : "FD_MINUTE_MOD_OTHER"
350					});
351
352					result += " ";
353
354					var secondsAgo = intval((nowDate - date) / 1000) - (minutesAgo * 60);
355					result += _formatDateMessage(secondsAgo, {
356						"0" : "FD_SECOND_AGO_0",
357						"1" : "FD_SECOND_AGO_1",
358						"10_20" : "FD_SECOND_AGO_10_20",
359						"MOD_1" : "FD_SECOND_AGO_MOD_1",
360						"MOD_2_4" : "FD_SECOND_AGO_MOD_2_4",
361						"MOD_OTHER" : "FD_SECOND_AGO_MOD_OTHER"
362					});
363					return result;
364				},
365
366				ishort : function() {
367					return _this._getMessage("FD_MINUTE_SHORT").replace(/#VALUE#/g, intval((nowDate - date) / 60 / 1000));
368				},
369
370				Hago : function() {
371					return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 1000), {
372						"0" : "FD_HOUR_AGO_0",
373						"1" : "FD_HOUR_AGO_1",
374						"10_20" : "FD_HOUR_AGO_10_20",
375						"MOD_1" : "FD_HOUR_AGO_MOD_1",
376						"MOD_2_4" : "FD_HOUR_AGO_MOD_2_4",
377						"MOD_OTHER" : "FD_HOUR_AGO_MOD_OTHER"
378					});
379				},
380
381				Hdiff : function() {
382					return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 1000), {
383						"0" : "FD_HOUR_DIFF_0",
384						"1" : "FD_HOUR_DIFF_1",
385						"10_20" : "FD_HOUR_DIFF_10_20",
386						"MOD_1" : "FD_HOUR_DIFF_MOD_1",
387						"MOD_2_4" : "FD_HOUR_DIFF_MOD_2_4",
388						"MOD_OTHER" : "FD_HOUR_DIFF_MOD_OTHER"
389					});
390				},
391
392				Hshort : function() {
393					return _this._getMessage("FD_HOUR_SHORT").replace(/#VALUE#/g, intval((nowDate - date) / 60 / 60 / 1000));
394				},
395
396				yesterday : function() {
397					return _this._getMessage("FD_YESTERDAY");
398				},
399
400				today : function() {
401					return _this._getMessage("FD_TODAY");
402				},
403
404				tommorow : function() {
405					return _this._getMessage("FD_TOMORROW");
406				},
407
408				tomorrow : function() {
409					return _this._getMessage("FD_TOMORROW");
410				},
411
412				dago : function() {
413					return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 1000), {
414						"0" : "FD_DAY_AGO_0",
415						"1" : "FD_DAY_AGO_1",
416						"10_20" : "FD_DAY_AGO_10_20",
417						"MOD_1" : "FD_DAY_AGO_MOD_1",
418						"MOD_2_4" : "FD_DAY_AGO_MOD_2_4",
419						"MOD_OTHER" : "FD_DAY_AGO_MOD_OTHER"
420					});
421				},
422
423				ddiff : function() {
424					return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 1000), {
425						"0" : "FD_DAY_DIFF_0",
426						"1" : "FD_DAY_DIFF_1",
427						"10_20" : "FD_DAY_DIFF_10_20",
428						"MOD_1" : "FD_DAY_DIFF_MOD_1",
429						"MOD_2_4" : "FD_DAY_DIFF_MOD_2_4",
430						"MOD_OTHER" : "FD_DAY_DIFF_MOD_OTHER"
431					});
432				},
433
434				dshort : function() {
435					return _this._getMessage("FD_DAY_SHORT").replace(/#VALUE#/g, intval((nowDate - date) / 60 / 60 / 24 / 1000));
436				},
437
438				mago : function() {
439					return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 31 / 1000), {
440						"0" : "FD_MONTH_AGO_0",
441						"1" : "FD_MONTH_AGO_1",
442						"10_20" : "FD_MONTH_AGO_10_20",
443						"MOD_1" : "FD_MONTH_AGO_MOD_1",
444						"MOD_2_4" : "FD_MONTH_AGO_MOD_2_4",
445						"MOD_OTHER" : "FD_MONTH_AGO_MOD_OTHER"
446					});
447				},
448
449				mdiff : function() {
450					return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 31 / 1000), {
451						"0" : "FD_MONTH_DIFF_0",
452						"1" : "FD_MONTH_DIFF_1",
453						"10_20" : "FD_MONTH_DIFF_10_20",
454						"MOD_1" : "FD_MONTH_DIFF_MOD_1",
455						"MOD_2_4" : "FD_MONTH_DIFF_MOD_2_4",
456						"MOD_OTHER" : "FD_MONTH_DIFF_MOD_OTHER"
457					});
458				},
459
460				mshort : function() {
461					return _this._getMessage("FD_MONTH_SHORT").replace(/#VALUE#/g, intval((nowDate - date) / 60 / 60 / 24 / 31 / 1000));
462				},
463
464				Yago : function() {
465					return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 365 / 1000), {
466						"0" : "FD_YEARS_AGO_0",
467						"1" : "FD_YEARS_AGO_1",
468						"10_20" : "FD_YEARS_AGO_10_20",
469						"MOD_1" : "FD_YEARS_AGO_MOD_1",
470						"MOD_2_4" : "FD_YEARS_AGO_MOD_2_4",
471						"MOD_OTHER" : "FD_YEARS_AGO_MOD_OTHER"
472					});
473				},
474
475				Ydiff : function() {
476					return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 365 / 1000), {
477						"0" : "FD_YEARS_DIFF_0",
478						"1" : "FD_YEARS_DIFF_1",
479						"10_20" : "FD_YEARS_DIFF_10_20",
480						"MOD_1" : "FD_YEARS_DIFF_MOD_1",
481						"MOD_2_4" : "FD_YEARS_DIFF_MOD_2_4",
482						"MOD_OTHER" : "FD_YEARS_DIFF_MOD_OTHER"
483					});
484				},
485
486				Yshort : function() {
487					return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 365 / 1000), {
488						"0" : "FD_YEARS_SHORT_0",
489						"1" : "FD_YEARS_SHORT_1",
490						"10_20" : "FD_YEARS_SHORT_10_20",
491						"MOD_1" : "FD_YEARS_SHORT_MOD_1",
492						"MOD_2_4" : "FD_YEARS_SHORT_MOD_2_4",
493						"MOD_OTHER" : "FD_YEARS_SHORT_MOD_OTHER"
494					});
495				},
496
497				x : function() {
498					var ampm = _this.isAmPmMode(true);
499					var timeFormat = (ampm === _this.AM_PM_MODE.LOWER? "g:i a" : (ampm === _this.AM_PM_MODE.UPPER? "g:i A" : "H:i"));
500
501					return _this.format([
502						["tomorrow", "tomorrow, "+timeFormat],
503						["-", _this.convertBitrixFormat(_this._getMessage("FORMAT_DATETIME")).replace(/:s/g, "")],
504						["s", "sago"],
505						["i", "iago"],
506						["today", "today, "+timeFormat],
507						["yesterday", "yesterday, "+timeFormat],
508						["", _this.convertBitrixFormat(_this._getMessage("FORMAT_DATETIME")).replace(/:s/g, "")]
509					], date, nowDate, isUTC);
510				},
511
512				X : function() {
513
514					var ampm = _this.isAmPmMode(true);
515					var timeFormat = (ampm === _this.AM_PM_MODE.LOWER? "g:i a" : (ampm === _this.AM_PM_MODE.UPPER? "g:i A" : "H:i"));
516
517					var day = _this.format([
518						["tomorrow", "tomorrow"],
519						["-", _this.convertBitrixFormat(_this._getMessage("FORMAT_DATE"))],
520						["today", "today"],
521						["yesterday", "yesterday"],
522						["", _this.convertBitrixFormat(_this._getMessage("FORMAT_DATE"))]
523					], date, nowDate, isUTC);
524
525					var time = _this.format([
526						["tomorrow", timeFormat],
527						["today", timeFormat],
528						["yesterday", timeFormat],
529						["", ""]
530					], date, nowDate, isUTC);
531
532					if (time.length > 0)
533						return _this._getMessage("FD_DAY_AT_TIME").replace(/#DAY#/g, day).replace(/#TIME#/g, time);
534					else
535						return day;
536				},
537
538				Q : function() {
539					var daysAgo = intval((nowDate - date) / 60 / 60 / 24 / 1000);
540					if(daysAgo == 0)
541						return _this._getMessage("FD_DAY_DIFF_1").replace(/#VALUE#/g, 1);
542					else
543						return _this.format([ ["d", "ddiff"], ["m", "mdiff"], ["", "Ydiff"] ], date, nowDate);
544				}
545			};
546
547			var cutZeroTime = false;
548			if (format[0] && format[0] == "^")
549			{
550				cutZeroTime = true;
551				format = format.substr(1);
552			}
553
554			var result = format.replace(formatRegex, _replaceDateFormat);
555
556			if (cutZeroTime)
557			{
558				/* 	15.04.12 13:00:00 => 15.04.12 13:00
559					00:01:00 => 00:01
560					4 may 00:00:00 => 4 may
561					01-01-12 00:00 => 01-01-12
562				*/
563
564				result = result.replace(/\s*00:00:00\s*/g, "").
565								replace(/(\d\d:\d\d)(:00)/g, "$1").
566								replace(/(\s*00:00\s*)(?!:)/g, "");
567			}
568
569			if (replaceMap.length > 0)
570			{
571				replaceMap.forEach(function(element, index) {
572					result = result.replace("{{"+index+"}}", element);
573				});
574			}
575
576			return result;
577
578			function _formatDateInterval(formats, date, nowDate, isUTC)
579			{
580				var secondsAgo = intval((nowDate - date) / 1000);
581				for (var i = 0; i < formats.length; i++)
582				{
583					var formatInterval = formats[i][0];
584					var formatValue = formats[i][1];
585					var match = null;
586					if (formatInterval == "s")
587					{
588						if (secondsAgo < 60)
589							return _this.format(formatValue, date, nowDate, isUTC);
590					}
591					else if ((match = /^s(\d+)\>?(\d+)?/.exec(formatInterval)) != null)
592					{
593						if (match[1] && match[2])
594						{
595							if (
596								secondsAgo < match[1]
597								&& secondsAgo > match[2]
598							)
599							{
600								return _this.format(formatValue, date, nowDate, isUTC);
601							}
602						}
603						else if (secondsAgo < match[1])
604						{
605							return _this.format(formatValue, date, nowDate, isUTC);
606						}
607					}
608					else if (formatInterval == "i")
609					{
610						if (secondsAgo < 60 * 60)
611							return _this.format(formatValue, date, nowDate, isUTC);
612					}
613					else if ((match = /^i(\d+)\>?(\d+)?/.exec(formatInterval)) != null)
614					{
615						if (match[1] && match[2])
616						{
617							if (
618								secondsAgo < match[1] * 60
619								&& secondsAgo > match[2] * 60
620							)
621							{
622								return _this.format(formatValue, date, nowDate, isUTC);
623							}
624						}
625						else if (secondsAgo < match[1] * 60)
626						{
627							return _this.format(formatValue, date, nowDate, isUTC);
628						}
629					}
630					else if (formatInterval == "H")
631					{
632						if (secondsAgo < 24 * 60 * 60)
633							return _this.format(formatValue, date, nowDate, isUTC);
634					}
635					else if ((match = /^H(\d+)\>?(\d+)?/.exec(formatInterval)) != null)
636					{
637						if (match[1] && match[2])
638						{
639							if (
640								secondsAgo < match[1] * 60 * 60
641								&& secondsAgo > match[2] * 60 * 60
642							)
643							{
644								return _this.format(formatValue, date, nowDate, isUTC);
645							}
646						}
647						else if (secondsAgo < match[1] * 60 * 60)
648						{
649							return _this.format(formatValue, date, nowDate, isUTC);
650						}
651					}
652					else if (formatInterval == "d")
653					{
654						if (secondsAgo < 31 *24 * 60 * 60)
655							return _this.format(formatValue, date, nowDate, isUTC);
656					}
657					else if ((match = /^d(\d+)\>?(\d+)?/.exec(formatInterval)) != null)
658					{
659						if (match[1] && match[2])
660						{
661							if (
662								secondsAgo < match[1] * 24 * 60 * 60
663								&& secondsAgo > match[2] * 24 * 60 * 60
664							)
665							{
666								return _this.format(formatValue, date, nowDate, isUTC);
667							}
668						}
669						else if (secondsAgo < match[1] * 24 * 60 * 60)
670						{
671							return _this.format(formatValue, date, nowDate, isUTC);
672						}
673					}
674					else if (formatInterval == "m")
675					{
676						if (secondsAgo < 365 * 24 * 60 * 60)
677							return _this.format(formatValue, date, nowDate, isUTC);
678					}
679					else if ((match = /^m(\d+)\>?(\d+)?/.exec(formatInterval)) != null)
680					{
681						if (match[1] && match[2])
682						{
683							if (
684								secondsAgo < match[1] * 31 * 24 * 60 * 60
685								&& secondsAgo > match[2] * 31 * 24 * 60 * 60
686							)
687							{
688								return _this.format(formatValue, date, nowDate, isUTC);
689							}
690						}
691						else if (secondsAgo < match[1] * 31 * 24 * 60 * 60)
692						{
693							return _this.format(formatValue, date, nowDate, isUTC);
694						}
695					}
696					else if (formatInterval == "now")
697					{
698						if (date.getTime() == nowDate.getTime())
699						{
700							return _this.format(formatValue, date, nowDate, isUTC);
701						}
702					}
703					else if (formatInterval == "today")
704					{
705						var year = getFullYear(nowDate), month = getMonth(nowDate), day = getDate(nowDate);
706						var todayStart = isUTC ? new Date(Date.UTC(year, month, day, 0, 0, 0, 0)) : new Date(year, month, day, 0, 0, 0, 0);
707						var todayEnd = isUTC ? new Date(Date.UTC(year, month, day+1, 0, 0, 0, 0)) : new Date(year, month, day+1, 0, 0, 0, 0);
708						if (date >= todayStart && date < todayEnd)
709							return _this.format(formatValue, date, nowDate, isUTC);
710					}
711					else if (formatInterval == "todayFuture")
712					{
713						var year = getFullYear(nowDate), month = getMonth(nowDate), day = getDate(nowDate);
714						var todayStart = nowDate.getTime();
715						var todayEnd = isUTC ? new Date(Date.UTC(year, month, day+1, 0, 0, 0, 0)) : new Date(year, month, day+1, 0, 0, 0, 0);
716						if (date >= todayStart && date < todayEnd)
717							return _this.format(formatValue, date, nowDate, isUTC);
718					}
719					else if (formatInterval == "yesterday")
720					{
721						year = getFullYear(nowDate); month = getMonth(nowDate); day = getDate(nowDate);
722						var yesterdayStart = isUTC ? new Date(Date.UTC(year, month, day-1, 0, 0, 0, 0)) : new Date(year, month, day-1, 0, 0, 0, 0);
723						var yesterdayEnd = isUTC ? new Date(Date.UTC(year, month, day, 0, 0, 0, 0)) : new Date(year, month, day, 0, 0, 0, 0);
724						if (date >= yesterdayStart && date < yesterdayEnd)
725							return _this.format(formatValue, date, nowDate, isUTC);
726					}
727					else if (formatInterval == "tommorow" || formatInterval == "tomorrow")
728					{
729						year = getFullYear(nowDate); month = getMonth(nowDate); day = getDate(nowDate);
730						var tomorrowStart = isUTC ? new Date(Date.UTC(year, month, day+1, 0, 0, 0, 0)) : new Date(year, month, day+1, 0, 0, 0, 0);
731						var tomorrowEnd = isUTC ? new Date(Date.UTC(year, month, day+2, 0, 0, 0, 0)) : new Date(year, month, day+2, 0, 0, 0, 0);
732						if (date >= tomorrowStart && date < tomorrowEnd)
733							return _this.format(formatValue, date, nowDate, isUTC);
734					}
735					else if (formatInterval == "-")
736					{
737						if (secondsAgo < 0)
738							return _this.format(formatValue, date, nowDate, isUTC);
739					}
740				}
741
742				//return formats.length > 0 ? _this.format(formats.pop()[1], date, nowDate, isUTC) : "";
743				return formats.length > 0 ? _this.format(formats[formats.length - 1][1], date, nowDate, isUTC) : "";
744			}
745
746			function getFullYear(date) { return isUTC ? date.getUTCFullYear() : date.getFullYear(); }
747			function getDate(date) { return isUTC ? date.getUTCDate() : date.getDate(); }
748			function getMonth(date) { return isUTC ? date.getUTCMonth() : date.getMonth(); }
749			function getHours(date) { return isUTC ? date.getUTCHours() : date.getHours(); }
750			function getMinutes(date) { return isUTC ? date.getUTCMinutes() : date.getMinutes(); }
751			function getSeconds(date) { return isUTC ? date.getUTCSeconds() : date.getSeconds(); }
752			function getMilliseconds(date) { return isUTC ? date.getUTCMilliseconds() : date.getMilliseconds(); }
753			function getDay(date) { return isUTC ? date.getUTCDay() : date.getDay(); }
754			function setDate(date, dayValue) { return isUTC ? date.setUTCDate(dayValue) : date.setDate(dayValue); }
755			function setMonth(date, monthValue, dayValue) { return isUTC ? date.setUTCMonth(monthValue, dayValue) : date.setMonth(monthValue, dayValue); }
756
757			function _formatDateMessage(value, messages)
758			{
759				var val = value < 100 ? Math.abs(value) : Math.abs(value % 100);
760				var dec = val % 10;
761				var message = "";
762
763				if(val == 0)
764					message = _this._getMessage(messages["0"]);
765				else if (val == 1)
766					message = _this._getMessage(messages["1"]);
767				else if (val >= 10 && val <= 20)
768					message = _this._getMessage(messages["10_20"]);
769				else if (dec == 1)
770					message = _this._getMessage(messages["MOD_1"]);
771				else if (2 <= dec && dec <= 4)
772					message = _this._getMessage(messages["MOD_2_4"]);
773				else
774					message = _this._getMessage(messages["MOD_OTHER"]);
775
776				return message.replace(/#VALUE#/g, value);
777			}
778
779			function _replaceDateFormat(match, matchFull)
780			{
781				if (dateFormats[match])
782					return dateFormats[match]();
783				else
784					return matchFull;
785			}
786
787			function intval(number)
788			{
789				return number >= 0 ? Math.floor(number) : Math.ceil(number);
790			}
791		},
792
793		convertBitrixFormat: function(format)
794		{
795			if (!Utils.isNotEmptyString(format))
796				return "";
797
798			return format.replace("YYYY", "Y")	// 1999
799						 .replace("MMMM", "F")	// January - December
800						 .replace("MM", "m")	// 01 - 12
801						 .replace("M", "M")	// Jan - Dec
802						 .replace("DD", "d")	// 01 - 31
803						 .replace("G", "g")	//  1 - 12
804						 .replace(/GG/i, "G")	//  0 - 23
805						 .replace("H", "h")	// 01 - 12
806						 .replace(/HH/i, "H")	// 00 - 24
807						 .replace("MI", "i")	// 00 - 59
808						 .replace("SS", "s")	// 00 - 59
809						 .replace("TT", "A")	// AM - PM
810						 .replace("T", "a");	// am - pm
811		},
812
813		convertToUTC: function(date)
814		{
815			if (!Utils.isDate(date))
816				return null;
817
818			return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()));
819		},
820
821		/**
822		 * Function creates and returns Javascript Date() object from server timestamp regardless of local browser (system) timezone.
823		 * For example can be used to convert timestamp from some exact date on server to the JS Date object with the same value.
824		 *
825		 * @param timestamp - timestamp in seconds
826		 * @returns {Date}
827		 */
828		getNewDate: function(timestamp)
829		{
830			return new Date(this.getBrowserTimestamp(timestamp));
831		},
832
833		/**
834		 * Function transforms server timestamp (in sec) to javascript timestamp (calculated depend on local browser timezone offset). Returns timestamp in milliseconds.
835		 * Also see BX.Main.Date.getNewDate description.
836		 *
837		 * @param timestamp - timestamp in seconds
838		 * @returns {number}
839		 */
840		getBrowserTimestamp: function(timestamp)
841		{
842			timestamp = parseInt(timestamp, 10);
843			var browserOffset = new Date(timestamp * 1000).getTimezoneOffset() * 60;
844			return (parseInt(timestamp, 10) + parseInt(this._getMessage('SERVER_TZ_OFFSET')) + browserOffset) * 1000;
845		},
846
847		/**
848		 * Function transforms local browser timestamp (in ms) to server timestamp (calculated depend on local browser timezone offset). Returns timestamp in seconds.
849		 *
850		 * @param timestamp - timestamp in milliseconds
851		 * @returns {number}
852		 */
853		getServerTimestamp: function(timestamp)
854		{
855			timestamp = parseInt(timestamp, 10);
856			var browserOffset = new Date(timestamp).getTimezoneOffset() * 60;
857			return Math.round(timestamp / 1000 - (parseInt(this._getMessage('SERVER_TZ_OFFSET'), 10) + parseInt(browserOffset, 10)));
858		},
859
860		formatLastActivityDate: function(timestamp, now, utc)
861		{
862			var ampm = this.isAmPmMode(true);
863			var timeFormat = (ampm === this.AM_PM_MODE.LOWER? "g:i a" : (ampm === this.AM_PM_MODE.UPPER? "g:i A" : "H:i"));
864
865			var format = [
866			   ["tomorrow", "#01#"+timeFormat],
867			   ["now" , "#02#"],
868			   ["todayFuture", "#03#"+timeFormat],
869			   ["yesterday", "#04#"+timeFormat],
870			   ["-", this.convertBitrixFormat(this._getMessage("FORMAT_DATETIME")).replace(/:s/g, "")],
871			   ["s60", "sago"],
872			   ["i60", "iago"],
873			   ["H5", "Hago"],
874			   ["H24", "#03#"+timeFormat],
875			   ["d31", "dago"],
876			   ["m12>1", "mago"],
877			   ["m12>0", "dago"],
878			   ["", "#05#"]
879			];
880			var formattedDate = this.format(format, timestamp, now, utc);
881			var match = null;
882			if ((match = /^#(\d+)#(.*)/.exec(formattedDate)) != null)
883			{
884				switch (match[1])
885				{
886					case "01":
887						formattedDate = this._getMessage('FD_LAST_SEEN_TOMORROW').replace("#TIME#", match[2]);
888					break;
889					case "02":
890						formattedDate = this._getMessage('FD_LAST_SEEN_NOW');
891					break;
892					case "03":
893						formattedDate = this._getMessage('FD_LAST_SEEN_TODAY').replace("#TIME#", match[2]);
894					break;
895					case "04":
896						formattedDate = this._getMessage('FD_LAST_SEEN_YESTERDAY').replace("#TIME#", match[2]);
897					break;
898					case "05":
899						formattedDate = this._getMessage('FD_LAST_SEEN_MORE_YEAR');
900					break;
901					default:
902						formattedDate = match[2];
903					break;
904				}
905			}
906
907			return formattedDate;
908		},
909
910		isAmPmMode: function(returnConst)
911		{
912			if (returnConst === true)
913			{
914				return this._getMessage('AMPM_MODE');
915			}
916
917			return this._getMessage('AMPM_MODE') !== false;
918		},
919
920		/**
921		 * The method is designed to replace the localization storage on sites without Bitrix Framework.
922		 *
923		 * @param message
924		 * @returns {*}
925		 * @private
926		 */
927		_getMessage: function(message)
928		{
929			return BX.message(message);
930		},
931
932		/**
933		 * The method used to parse date from string by given format.
934		 *
935		 * @param {string} str - date in given format
936		 * @param {boolean} isUTC - is date in UTC
937		 * @param {string} formatDate - format of the date without time
938		 * @param {string} formatDatetime - format of the date with time
939		 * @returns {Date|null} - returns Date object if string was parsed or null
940		 */
941		parse: function(str, isUTC, formatDate, formatDatetime)
942		{
943			if (Utils.isNotEmptyString(str))
944			{
945				if (!formatDate)
946					formatDate = this._getMessage('FORMAT_DATE');
947				if (!formatDatetime)
948					formatDatetime = this._getMessage('FORMAT_DATETIME');
949
950				var regMonths = '';
951				for (i = 1; i <= 12; i++)
952				{
953					regMonths = regMonths + '|' + this._getMessage('MON_'+i);
954				}
955
956				var
957					expr = new RegExp('([0-9]+|[a-z]+' + regMonths + ')', 'ig'),
958					aDate = str.match(expr),
959					aFormat = formatDate.match(/(DD|MI|MMMM|MM|M|YYYY)/ig),
960					i, cnt,
961					aDateArgs=[], aFormatArgs=[],
962					aResult={};
963
964				if (!aDate)
965				{
966					return null;
967				}
968
969				if(aDate.length > aFormat.length)
970				{
971					aFormat = formatDatetime.match(/(DD|MI|MMMM|MM|M|YYYY|HH|H|SS|TT|T|GG|G)/ig);
972				}
973
974				for(i = 0, cnt = aDate.length; i < cnt; i++)
975				{
976					if(aDate[i].trim() !== '')
977					{
978						aDateArgs[aDateArgs.length] = aDate[i];
979					}
980				}
981
982				for(i = 0, cnt = aFormat.length; i < cnt; i++)
983				{
984					if(aFormat[i].trim() !== '')
985					{
986						aFormatArgs[aFormatArgs.length] = aFormat[i];
987					}
988				}
989
990				var m = Utils.array_search('MMMM', aFormatArgs);
991				if (m > 0)
992				{
993					aDateArgs[m] = this.getMonthIndex(aDateArgs[m]);
994					aFormatArgs[m] = "MM";
995				}
996				else
997				{
998					m = Utils.array_search('M', aFormatArgs);
999					if (m > 0)
1000					{
1001						aDateArgs[m] = this.getMonthIndex(aDateArgs[m]);
1002						aFormatArgs[m] = "MM";
1003					}
1004				}
1005
1006				for(i = 0, cnt = aFormatArgs.length; i < cnt; i++)
1007				{
1008					var k = aFormatArgs[i].toUpperCase();
1009					aResult[k] = k === 'T' || k === 'TT' ? aDateArgs[i] : parseInt(aDateArgs[i], 10);
1010				}
1011
1012				if(aResult['DD'] > 0 && aResult['MM'] > 0 && aResult['YYYY'] > 0)
1013				{
1014					var d = new Date();
1015
1016					if(isUTC)
1017					{
1018						d.setUTCDate(1);
1019						d.setUTCFullYear(aResult['YYYY']);
1020						d.setUTCMonth(aResult['MM'] - 1);
1021						d.setUTCDate(aResult['DD']);
1022						d.setUTCHours(0, 0, 0, 0);
1023					}
1024					else
1025					{
1026						d.setDate(1);
1027						d.setFullYear(aResult['YYYY']);
1028						d.setMonth(aResult['MM'] - 1);
1029						d.setDate(aResult['DD']);
1030						d.setHours(0, 0, 0, 0);
1031					}
1032
1033					if(
1034						(!isNaN(aResult['HH']) || !isNaN(aResult['GG']) || !isNaN(aResult['H']) || !isNaN(aResult['G']))
1035						&& !isNaN(aResult['MI'])
1036					)
1037					{
1038						if (!isNaN(aResult['H']) || !isNaN(aResult['G']))
1039						{
1040							var
1041								bPM = (aResult['T']||aResult['TT']||'am').toUpperCase() === 'PM',
1042								h = parseInt(aResult['H']||aResult['G']||0, 10);
1043
1044							if(bPM)
1045							{
1046								aResult['HH'] = h + (h === 12 ? 0 : 12);
1047							}
1048							else
1049							{
1050								aResult['HH'] = h < 12 ? h : 0;
1051							}
1052						}
1053						else
1054						{
1055							aResult['HH'] = parseInt(aResult['HH']||aResult['GG']||0, 10);
1056						}
1057
1058						if (isNaN(aResult['SS']))
1059							aResult['SS'] = 0;
1060
1061						if(isUTC)
1062						{
1063							d.setUTCHours(aResult['HH'], aResult['MI'], aResult['SS']);
1064						}
1065						else
1066						{
1067							d.setHours(aResult['HH'], aResult['MI'], aResult['SS']);
1068						}
1069					}
1070
1071					return d;
1072				}
1073			}
1074
1075			return null;
1076		},
1077
1078		getMonthIndex: function(month)
1079		{
1080			var
1081				i,
1082				q = month.toUpperCase(),
1083				wordMonthCut = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'],
1084				wordMonth = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'];
1085
1086			for (i = 1; i <= 12; i++)
1087			{
1088				if (q === this._getMessage('MON_'+i).toUpperCase()
1089					|| q === this._getMessage('MONTH_'+i).toUpperCase()
1090					|| q === wordMonthCut[i-1].toUpperCase()
1091					|| q === wordMonth[i-1].toUpperCase())
1092				{
1093					return i;
1094				}
1095			}
1096			return month;
1097		}
1098	};
1099
1100	/**
1101	 * @private
1102	 */
1103	var Utils = {
1104		isDate: function(item) {
1105			return item && Object.prototype.toString.call(item) == "[object Date]";
1106		},
1107		isNumber: function(item) {
1108			return item === 0 ? true : (item ? (typeof (item) == "number" || item instanceof Number) : false);
1109		},
1110		isArray: function(item) {
1111			return item && Object.prototype.toString.call(item) == "[object Array]";
1112		},
1113		isString: function(item) {
1114			return item === '' ? true : (item ? (typeof (item) == "string" || item instanceof String) : false);
1115		},
1116		isNotEmptyString: function(item) {
1117			return this.isString(item) ? item.length > 0 : false;
1118		},
1119		strPadLeft: function(input, padLength, padString)
1120		{
1121			var i = input.length, q=padString.length;
1122			if (i >= padLength) return input;
1123
1124			for(;i<padLength;i+=q)
1125				input = padString + input;
1126
1127			return input;
1128		},
1129		/**
1130		 * @deprecated
1131		 * @use myArr.findIndex(item => item === needle);
1132		 */
1133		array_search: function(needle, haystack)
1134		{
1135			for(var i = 0; i < haystack.length; i++)
1136			{
1137				if(haystack[i] == needle)
1138					return i;
1139			}
1140			return -1;
1141		},
1142	};
1143
1144})(window);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.