PageSourceSearch

https://shadowfight2.com/js/main.js?v=20260928-root-launch

js shadowfight2.com collected 2026-10-01 12:06:48 UTC 12,099 bytes, 407 lines download raw bytes

1(function () {
2  'use strict';
3
4  var measurementId = '__SHF2_GA_MEASUREMENT_ID__';
5
6  if (!measurementId || measurementId === '__SHF2_GA_MEASUREMENT_ID__') {
7    measurementId = 'G-XWDG5MR6KK';
8  }
9
10  function findTrackedLink(node) {
11    while (node && node !== document) {
12      if (node.tagName === 'A' && node.getAttribute('data-ga-event')) {
13        return node;
14      }
15
16      node = node.parentNode;
17    }
18
19    return null;
20  }
21
22  function isMobileLaunch() {
23    var userAgent = navigator.userAgent || '';
24    var hasMobileUserAgent = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile/i.test(
25      userAgent
26    );
27    var isTouchMac = navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1;
28    var hasCoarsePointer = typeof window.matchMedia === 'function' && window.matchMedia('(pointer: coarse)').matches;
29    var hasSmallViewport =
30      typeof window.matchMedia === 'function' && window.matchMedia('(max-width: 1024px)').matches;
31
32    return hasMobileUserAgent || isTouchMac || (hasCoarsePointer && hasSmallViewport);
33  }
34
35  function initAnalytics() {
36    window.dataLayer = window.dataLayer || [];
37    window.gtag = function () {
38      window.dataLayer.push(arguments);
39    };
40
41    window.gtag('js', new Date());
42    window.gtag('config', measurementId);
43
44    function loadAnalyticsScript() {
45      var gaScript = document.createElement('script');
46      gaScript.async = true;
47      gaScript.src = 'https://www.googletagmanager.com/gtag/js?id=' + encodeURIComponent(measurementId);
48      document.head.appendChild(gaScript);
49    }
50
51    function loadAnalyticsWhenIdle() {
52      if (typeof window.requestIdleCallback === 'function') {
53        window.requestIdleCallback(loadAnalyticsScript, { timeout: 3000 });
54      } else {
55        window.setTimeout(loadAnalyticsScript, 1200);
56      }
57    }
58
59    if (document.readyState === 'complete') {
60      loadAnalyticsWhenIdle();
61    } else {
62      window.addEventListener('load', loadAnalyticsWhenIdle, { once: true });
63    }
64  }
65
66  function initTrackedLinks() {
67    document.addEventListener('click', function (event) {
68      var trackedLink = findTrackedLink(event.target);
69
70      if (!trackedLink) {
71        return;
72      }
73
74      window.gtag('event', trackedLink.getAttribute('data-ga-event'), {
75        link_url: trackedLink.href,
76        transport_type: 'beacon'
77      });
78
79      var mobileHref = trackedLink.getAttribute('data-mobile-href');
80      var isModifiedClick = event.metaKey || event.ctrlKey || event.shiftKey || event.altKey || event.button !== 0;
81
82      if (!mobileHref || isModifiedClick || trackedLink.target === '_blank' || !isMobileLaunch()) {
83        return;
84      }
85
86      event.preventDefault();
87      window.location.assign(mobileHref);
88    });
89  }
90
91  function initHeader() {
92    var header = document.querySelector('[data-header]');
93
94    if (!header) {
95      return;
96    }
97
98    function updateHeader() {
99      header.classList.toggle('is-scrolled', window.scrollY > 24);
100    }
101
102    updateHeader();
103    window.addEventListener('scroll', updateHeader, { passive: true });
104  }
105
106  function initLaunchRain() {
107    var canvas = document.querySelector('[data-launch-rain]');
108    var reducedMotion =
109      typeof window.matchMedia === 'function' && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
110
111    if (!canvas || reducedMotion) {
112      return;
113    }
114
115    var context = canvas.getContext('2d');
116
117    if (!context) {
118      return;
119    }
120
121    var drops = [];
122    var width = 0;
123    var height = 0;
124    var pixelRatio = 1;
125    var lastFrameTime = 0;
126
127    function resetDrop(drop, isInitialDrop) {
128      var depth = Math.pow(Math.random(), 1.45);
129
130      drop.x = Math.random() * (width + 180) - 70;
131      drop.y = isInitialDrop ? Math.random() * height : -20 - Math.random() * height * 0.24;
132      drop.length = 13 + Math.random() * 17 + depth * 35;
133      drop.speed = 470 + Math.random() * 310 + depth * 570;
134      drop.drift = -32 - Math.random() * 40 - depth * 50;
135      drop.opacity = 0.08 + Math.random() * 0.08 + depth * 0.2;
136      drop.lineWidth = 0.55 + depth * 0.95;
137    }
138
139    function resizeRain() {
140      var bounds = canvas.getBoundingClientRect();
141      var targetDropCount;
142
143      width = Math.max(1, bounds.width);
144      height = Math.max(1, bounds.height);
145      pixelRatio = Math.min(window.devicePixelRatio || 1, 2);
146      canvas.width = Math.round(width * pixelRatio);
147      canvas.height = Math.round(height * pixelRatio);
148      context.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
149
150      targetDropCount = Math.max(100, Math.min(320, Math.round((width * height) / 4500)));
151      drops = Array.from({ length: targetDropCount }, function () {
152        var drop = {};
153        resetDrop(drop, true);
154        return drop;
155      });
156    }
157
158    function drawRain(frameTime) {
159      var deltaSeconds;
160
161      if (!lastFrameTime) {
162        lastFrameTime = frameTime;
163      }
164
165      deltaSeconds = Math.min((frameTime - lastFrameTime) / 1000, 0.035);
166      lastFrameTime = frameTime;
167      context.clearRect(0, 0, width, height);
168      context.lineCap = 'round';
169
170      drops.forEach(function (drop) {
171        var horizontalLength = (drop.drift / drop.speed) * drop.length;
172
173        context.beginPath();
174        context.moveTo(drop.x, drop.y);
175        context.lineTo(drop.x + horizontalLength, drop.y + drop.length);
176        context.lineWidth = drop.lineWidth;
177        context.strokeStyle = 'rgba(220, 238, 243, ' + drop.opacity + ')';
178        context.stroke();
179
180        drop.x += drop.drift * deltaSeconds;
181        drop.y += drop.speed * deltaSeconds;
182
183        if (drop.y > height + drop.length || drop.x < -100) {
184          resetDrop(drop, false);
185        }
186      });
187
188      window.requestAnimationFrame(drawRain);
189    }
190
191    resizeRain();
192
193    if (typeof ResizeObserver === 'function') {
194      new ResizeObserver(resizeRain).observe(canvas.parentNode);
195    } else {
196      window.addEventListener('resize', resizeRain);
197    }
198
199    window.requestAnimationFrame(drawRain);
200  }
201
202  function initLaunchLightning() {
203    var weather = document.querySelector('.launch-weather');
204    var reducedMotion =
205      typeof window.matchMedia === 'function' && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
206
207    if (!weather || reducedMotion) {
208      return;
209    }
210
211    function scheduleLightning(isFirstStrike) {
212      var delay = isFirstStrike ? 1400 + Math.random() * 3200 : 3800 + Math.random() * 8200;
213
214      window.setTimeout(triggerLightning, delay);
215    }
216
217    function triggerLightning() {
218      var direction = Math.random() > 0.5 ? 1 : -1;
219
220      weather.style.setProperty('--lightning-x', 10 + Math.random() * 80 + '%');
221      weather.style.setProperty('--lightning-y', 2 + Math.random() * 18 + '%');
222      weather.style.setProperty('--lightning-width', 72 + Math.random() * 78 + 'px');
223      weather.style.setProperty('--lightning-height', 42 + Math.random() * 27 + '%');
224      weather.style.setProperty('--lightning-rotation', -11 + Math.random() * 22 + 'deg');
225      weather.style.setProperty('--lightning-direction', direction);
226      weather.style.setProperty('--lightning-opacity', 0.72 + Math.random() * 0.26);
227      weather.classList.remove('is-lightning');
228
229      window.requestAnimationFrame(function () {
230        weather.classList.add('is-lightning');
231
232        window.setTimeout(function () {
233          weather.classList.remove('is-lightning');
234          scheduleLightning(false);
235        }, 720);
236      });
237    }
238
239    scheduleLightning(true);
240  }
241
242  function initImageViewer() {
243    var viewer = document.querySelector('[data-image-viewer]');
244    var triggers = Array.prototype.slice.call(document.querySelectorAll('[data-image-viewer-trigger]'));
245
246    if (!viewer || !triggers.length) {
247      return;
248    }
249
250    var viewerImage = viewer.querySelector('[data-image-viewer-image]');
251    var viewerCaption = viewer.querySelector('[data-image-viewer-caption]');
252    var closeButton = viewer.querySelector('[data-image-viewer-close]');
253    var previousButton = viewer.querySelector('[data-image-viewer-prev]');
254    var nextButton = viewer.querySelector('[data-image-viewer-next]');
255    var currentIndex = 0;
256
257    function showImage(index) {
258      currentIndex = (index + triggers.length) % triggers.length;
259
260      var trigger = triggers[currentIndex];
261      var thumbnail = trigger.querySelector('img');
262      var figure = trigger.closest('figure');
263      var caption = figure ? figure.querySelector('figcaption') : null;
264
265      viewerImage.src = trigger.href;
266      viewerImage.alt = thumbnail ? thumbnail.alt : '';
267      viewerCaption.textContent = caption ? caption.textContent : viewerImage.alt;
268    }
269
270    function openViewer(index) {
271      showImage(index);
272
273      if (typeof viewer.showModal === 'function') {
274        viewer.showModal();
275      } else {
276        viewer.setAttribute('open', '');
277      }
278
279      closeButton.focus();
280    }
281
282    function closeViewer() {
283      if (typeof viewer.close === 'function') {
284        viewer.close();
285      } else {
286        viewer.removeAttribute('open');
287      }
288    }
289
290    triggers.forEach(function (trigger, index) {
291      trigger.addEventListener('click', function (event) {
292        event.preventDefault();
293        openViewer(index);
294      });
295    });
296
297    closeButton.addEventListener('click', closeViewer);
298    previousButton.addEventListener('click', function () {
299      showImage(currentIndex - 1);
300    });
301    nextButton.addEventListener('click', function () {
302      showImage(currentIndex + 1);
303    });
304
305    viewer.addEventListener('click', function (event) {
306      if (event.target === viewer) {
307        closeViewer();
308      }
309    });
310
311    viewer.addEventListener('keydown', function (event) {
312      if (event.key === 'ArrowLeft') {
313        event.preventDefault();
314        showImage(currentIndex - 1);
315      } else if (event.key === 'ArrowRight') {
316        event.preventDefault();
317        showImage(currentIndex + 1);
318      }
319    });
320  }
321
322  function initLaunchFighterAfterLoad() {
323    var fighter = document.querySelector('.launch-fighter');
324
325    if (!fighter) {
326      return;
327    }
328
329    var image = fighter.querySelector('img[data-src]');
330    var stillFrame = fighter.querySelector('source[data-srcset]');
331
332    if (!image) {
333      return;
334    }
335
336    function loadFighter() {
337      image.addEventListener('load', function () {
338        fighter.classList.add('is-loaded');
339      }, { once: true });
340
341      if (stillFrame) {
342        stillFrame.srcset = stillFrame.getAttribute('data-srcset');
343      }
344
345      image.src = image.getAttribute('data-src');
346
347      if (image.complete && image.naturalWidth) {
348        fighter.classList.add('is-loaded');
349      }
350    }
351
352    function scheduleFighter() {
353      if (typeof window.requestIdleCallback === 'function') {
354        window.requestIdleCallback(loadFighter, { timeout: 2500 });
355      } else {
356        window.setTimeout(loadFighter, 300);
357      }
358    }
359
360    function observeFighter() {
361      if (typeof IntersectionObserver !== 'function') {
362        scheduleFighter();
363        return;
364      }
365
366      var observer = new IntersectionObserver(function (entries) {
367        if (!entries.some(function (entry) { return entry.isIntersecting; })) {
368          return;
369        }
370
371        observer.disconnect();
372        scheduleFighter();
373      }, { rootMargin: '200px 0px' });
374
375      observer.observe(fighter);
376    }
377
378    // Keep decorative animation off the critical page-load path.
379    if (document.readyState === 'complete') {
380      observeFighter();
381    } else {
382      window.addEventListener('load', observeFighter, { once: true });
383    }
384  }
385
386  function initLaunchEffectsAfterLoad() {
387    function startEffects() {
388      window.requestAnimationFrame(function () {
389        initLaunchRain();
390        initLaunchLightning();
391      });
392    }
393
394    if (document.readyState === 'complete') {
395      startEffects();
396    } else {
397      window.addEventListener('load', startEffects, { once: true });
398    }
399  }
400
401  initAnalytics();
402  initTrackedLinks();
403  initHeader();
404  initLaunchFighterAfterLoad();
405  initLaunchEffectsAfterLoad();
406  initImageViewer();
407})();

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.