PageSourceSearch

https://www.abra-it.com/wp-content/themes/abra-1/assets/js/modules/timer.js?ver=1785314316

js abra-it.com collected 2026-10-02 04:44:28 UTC 4,778 bytes, 137 lines download raw bytes

1class Timer {
2  constructor(element) {
3    this.timerElement = element;
4    this.timezoneInfo = document.querySelector('.timezone-info');
5    this.init();
6  }
7
8  init() {
9    const timezoneOffset = parseInt(this.timerElement.dataset.timezone) || 0;
10    const endTimeString = this.timerElement.dataset.endtime;
11
12    this.endTime = this.createDateWithTimezone(endTimeString, timezoneOffset);
13
14    this.animationType = this.timerElement.dataset.animation || 'down';
15    this.endText = this.timerElement.previousElementSibling.dataset.endtext || 'Time is up!';
16
17    this.displayTimezoneInfo(timezoneOffset);
18
19    this.daysElement = this.timerElement.querySelector('.days');
20    this.hoursElement = this.timerElement.querySelector('.hours');
21    this.minutesElement = this.timerElement.querySelector('.minutes');
22    this.secondsElement = this.timerElement.querySelector('.seconds');
23    this.thirdDigitContainer = this.daysElement.querySelector('.third-digit');
24
25    this.updateTimer();
26  }
27
28  createDateWithTimezone(dateString, timezoneOffset) {
29    const localDate = new Date(dateString);
30
31    const userTimezoneOffset = localDate.getTimezoneOffset();
32
33    const targetTimezoneOffset = timezoneOffset * 60;
34    const timezoneDifference = targetTimezoneOffset + userTimezoneOffset;
35
36    const adjustedDate = new Date(localDate.getTime() + timezoneDifference * 60 * 1000);
37
38    return adjustedDate;
39  }
40
41  displayTimezoneInfo(timezoneOffset) {
42    if (!this.timezoneInfo) return;
43
44    const gmtText = timezoneOffset >= 0 ? `GMT+${timezoneOffset}` : `GMT${timezoneOffset}`;
45
46    const localTime = new Date();
47    const userTimezone = -localTime.getTimezoneOffset() / 60;
48    const userGmtText = userTimezone >= 0 ? `GMT+${userTimezone}` : `GMT${userTimezone}`;
49
50    this.timezoneInfo.textContent = `(Your timezone: ${userGmtText})`;
51  }
52
53  updateDigitGroup(container, newValue, isDays = false) {
54    if (!container) return;
55
56    const digitContainers = Array.from(container.querySelectorAll('.digit-container')).filter((container) => container.style.display !== 'none');
57
58    const digits = digitContainers.length;
59    const formattedValue = String(newValue).padStart(digits, '0');
60
61    if (isDays) {
62      const showThirdDigit = newValue > 99;
63      this.thirdDigitContainer.style.display = showThirdDigit ? 'block' : 'none';
64
65      const updatedContainers = Array.from(container.querySelectorAll('.digit-container')).filter((container) => container.style.display !== 'none');
66
67      this.updateVisibleDigits(updatedContainers, formattedValue);
68    } else {
69      this.updateVisibleDigits(digitContainers, formattedValue);
70    }
71  }
72
73  updateVisibleDigits(containers, formattedValue) {
74    const valueLength = formattedValue.length;
75    const containersLength = containers.length;
76
77    for (let i = 0; i < containersLength; i++) {
78      const container = containers[i];
79      const currentDigit = container.querySelector('.digit');
80      const digitIndex = valueLength - containersLength + i;
81      const newDigitValue = digitIndex >= 0 ? formattedValue[digitIndex] : '0';
82
83      if (!currentDigit || currentDigit.textContent !== newDigitValue) {
84        this.animateDigit(container, newDigitValue);
85      }
86    }
87  }
88
89  animateDigit(container, newValue) {
90    const currentDigit = container.querySelector('.digit');
91    if (!currentDigit) return;
92
93    const newDigit = document.createElement('div');
94    newDigit.className = `digit new ${this.animationType}`;
95    newDigit.textContent = newValue;
96
97    currentDigit.className = `digit old ${this.animationType}`;
98    container.appendChild(newDigit);
99
100    setTimeout(() => {
101      if (currentDigit.parentNode === container) {
102        container.removeChild(currentDigit);
103        newDigit.className = 'digit';
104      }
105    }, 300);
106  }
107
108  updateTimer() {
109    const now = new Date();
110    const timeLeft = this.endTime - now;
111
112    if (timeLeft <= 0) {
113      this.timerElement.previousElementSibling.textContent = this.endText;
114      this.timerElement.style.display = 'none';
115      return;
116    }
117
118    const days = Math.floor(timeLeft / (1000 * 60 * 60 * 24));
119    const hours = Math.floor((timeLeft % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
120    const minutes = Math.floor((timeLeft % (1000 * 60 * 60)) / (1000 * 60));
121    const seconds = Math.floor((timeLeft % (1000 * 60)) / 1000);
122
123    this.updateDigitGroup(this.daysElement, days, true);
124    this.updateDigitGroup(this.hoursElement, hours);
125    this.updateDigitGroup(this.minutesElement, minutes);
126    this.updateDigitGroup(this.secondsElement, seconds);
127
128    setTimeout(() => this.updateTimer(), 1000);
129  }
130}
131
132document.addEventListener('DOMContentLoaded', () => {
133  const timerElement = document.querySelector('.timer');
134  if (timerElement) {
135    new Timer(timerElement);
136  }
137});

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.