PageSourceSearch

https://www.kompex.pl/_user/tv.js

js kompex.pl collected 2026-10-07 15:24:49 UTC 16,785 bytes, 585 lines download raw bytes

1(function () {
2  "use strict";
3
4  var PACKAGE_CLASS_PREFIX = "tvpkg-";
5  var MAX_PARENT_LOOKUP = 6;
6  var DATA_URL = window.TV_DATA_URL || "_userdata/include/tv_data.php";
7
8  var dataCache = null;
9  var dataPending = false;
10  var gridCardsByKey = Object.create(null);
11  var gridRenderToken = 0;
12
13  function toArray(list) {
14    return Array.prototype.slice.call(list || []);
15  }
16
17  function normalizeKey(input) {
18    var s = String(input || "").toLowerCase();
19    s = s.replace(/\+/g, " plus ");
20    s = s.replace(/&/g, " and ");
21    s = s.replace(/[^a-z0-9]+/g, "");
22    return s;
23  }
24
25  function findPackageWrapper(fromNode) {
26    var node = fromNode;
27    var depth = 0;
28
29    while (node && node !== document.body && depth <= MAX_PARENT_LOOKUP) {
30      if (node.nodeType === 1 && node.classList && node.classList.length > 0) {
31        var prefixedClasses = toArray(node.classList).filter(function (cls) {
32          return cls.indexOf(PACKAGE_CLASS_PREFIX) === 0;
33        });
34
35        if (prefixedClasses.length > 0) {
36          var cls = prefixedClasses[0];
37          return {
38            element: node,
39            packageKey: cls.slice(PACKAGE_CLASS_PREFIX.length)
40          };
41        }
42      }
43
44      node = node.parentElement;
45      depth += 1;
46    }
47
48    return null;
49  }
50
51  function getPackageLabel(wrapperElement, shortNode) {
52    var fromWrapper = wrapperElement && wrapperElement.dataset ? (wrapperElement.dataset.label || "").trim() : "";
53    if (fromWrapper) {
54      return fromWrapper;
55    }
56
57    var labelNode = shortNode ? shortNode.querySelector("[data-label]") : null;
58    if (labelNode) {
59      var fromContent = (labelNode.getAttribute("data-label") || "").trim();
60      if (fromContent) {
61        return fromContent;
62      }
63    }
64
65    return "";
66  }
67
68  function readPackages() {
69    var shortNodes = toArray(document.querySelectorAll(".text_short"));
70    var results = [];
71    var seen = Object.create(null);
72
73    shortNodes.forEach(function (shortNode, index) {
74      var wrapperData = findPackageWrapper(shortNode);
75      var key = "";
76      var label = "";
77
78      if (wrapperData && wrapperData.element) {
79        key = (wrapperData.element.dataset && wrapperData.element.dataset.package) || wrapperData.packageKey || "";
80        label = getPackageLabel(wrapperData.element, shortNode);
81      }
82
83      if (!key || !label) {
84        return;
85      }
86
87      var norm = normalizeKey(key);
88      if (seen[norm]) {
89        return;
90      }
91      seen[norm] = true;
92
93      results.push({
94        key: key,
95        keyNorm: norm,
96        label: label,
97        labelNorm: normalizeKey(label),
98        html: shortNode.innerHTML,
99        order: Number((wrapperData && wrapperData.element && wrapperData.element.dataset && wrapperData.element.dataset.order) || index),
100        isDefault: !!(wrapperData && wrapperData.element && wrapperData.element.dataset && (wrapperData.element.dataset.default === "1" || wrapperData.element.dataset.default === "true"))
101      });
102    });
103
104    results.sort(function (a, b) {
105      return a.order - b.order;
106    });
107
108    return results;
109  }
110
111  function ensureDescriptionTarget() {
112    var target = document.querySelector("#package-description, [data-tv-description]");
113    if (target) {
114      return target;
115    }
116
117    var auto = document.createElement("div");
118    auto.id = "package-description";
119    document.body.appendChild(auto);
120    return auto;
121  }
122
123  function ensureSwitcherMounts(target) {
124    var mounts = toArray(document.querySelectorAll(".package-switcher, [data-tv-switcher]"));
125    if (mounts.length > 0) {
126      return mounts;
127    }
128
129    var div = document.createElement("div");
130    div.className = "package-switcher";
131    target.parentNode.insertBefore(div, target);
132    return [div];
133  }
134
135  function createButton(pkg) {
136    var btn = document.createElement("button");
137    btn.type = "button";
138    btn.dataset.package = pkg.key;
139    btn.textContent = pkg.label;
140    return btn;
141  }
142
143  function getGridTarget() {
144    return document.querySelector("#channels-grid, [data-tv-grid]");
145  }
146
147  function getColumnsTarget() {
148    return document.querySelector("#channels-columns, [data-tv-channels-columns]");
149  }
150
151  function getPopupTarget() {
152    return document.querySelector("#tvpopup, [data-tv-popup]");
153  }
154
155  function ensureGridAnimationStyles() {
156    if (document.getElementById("tv-grid-dynamic-styles")) {
157      return;
158    }
159
160    var style = document.createElement("style");
161    style.id = "tv-grid-dynamic-styles";
162    style.textContent =
163      "#channels-grid .channel{" +
164      "display:flex;align-items:center;justify-content:center;" +
165      "position:relative;overflow:hidden;" +
166      "background-color:#ddd;" +
167      "background-image:radial-gradient(circle at center,rgba(255,255,255,.5) 0%,rgba(255,255,255,.15) 40%,rgba(0,0,0,.08) 100%);" +
168      "border:1px solid rgba(0,0,0,.14);" +
169      "border-radius:12px;" +
170      "box-shadow:inset 0 1px 0 rgba(255,255,255,.35),0 8px 18px rgba(0,0,0,.12);" +
171      "transform-origin:center center;will-change:transform,opacity;" +
172      "transform:translate(var(--flip-x,0),var(--flip-y,0)) rotateX(var(--rx,0)) rotateY(var(--ry,0)) scale(var(--hover-scale,1));" +
173      "transition:transform 760ms cubic-bezier(0.22,1,0.36,1),opacity 360ms ease,box-shadow 260ms ease,border-color 260ms ease;" +
174      "}" +
175      "#channels-grid .channel.is-entering{opacity:0;transform:translate(var(--flip-x,0),var(--flip-y,0)) rotateX(var(--rx,0)) rotateY(var(--ry,0)) scale(.82);}" +
176      "#channels-grid .channel:hover{border-color:rgba(0,0,0,.22);box-shadow:inset 0 1px 0 rgba(255,255,255,.45),0 12px 24px rgba(0,0,0,.2);}" +
177      "#channels-grid .channel img{display:block;width:96%;height:96%;margin:auto;object-fit:contain;pointer-events:none;}";
178    document.head.appendChild(style);
179  }
180
181  function getChannelKey(ch) {
182    if (ch && (ch.id || ch.id === 0)) {
183      return "id-" + String(ch.id);
184    }
185    return "n-" + String(ch && ch.number ? ch.number : "") + "-" + normalizeKey(ch && ch.name ? ch.name : "");
186  }
187
188  function createGridCard(ch, popup) {
189    var el = document.createElement("div");
190    el.className = "channel is-entering";
191    el.style.display = "flex";
192    el.style.alignItems = "center";
193    el.style.justifyContent = "center";
194    el.style.setProperty("--flip-x", "0px");
195    el.style.setProperty("--flip-y", "0px");
196    el.style.setProperty("--rx", "0deg");
197    el.style.setProperty("--ry", "0deg");
198    el.style.setProperty("--hover-scale", "1");
199
200    el.addEventListener("mouseenter", function (e) {
201      if (!popup || !el._channelData) {
202        return;
203      }
204
205      var c = el._channelData;
206      popup.innerHTML = "<strong>Nr. " + (c.number || "-") + " " + escapeHtml(c.name || "") + "</strong><br><strong>" + escapeHtml(c.category || "inne") + "</strong>";
207      popup.style.left = e.clientX + 12 + "px";
208      popup.style.top = e.clientY + 12 + "px";
209      popup.classList.add("visible");
210    });
211
212    el.addEventListener("mouseleave", function () {
213      if (popup) {
214        popup.classList.remove("visible");
215      }
216      el.style.setProperty("--rx", "0deg");
217      el.style.setProperty("--ry", "0deg");
218      el.style.setProperty("--hover-scale", "1");
219    });
220
221    el.addEventListener("mousemove", function (e) {
222      var rect = el.getBoundingClientRect();
223      var x = e.clientX - rect.left;
224      var y = e.clientY - rect.top;
225      var nx = ((x / rect.width) * 2) - 1;
226      var ny = ((y / rect.height) * 2) - 1;
227      var maxTilt = 6.5;
228      var rotateY = nx * maxTilt;
229      var rotateX = -ny * maxTilt;
230      el.style.setProperty("--rx", rotateX.toFixed(2) + "deg");
231      el.style.setProperty("--ry", rotateY.toFixed(2) + "deg");
232      el.style.setProperty("--hover-scale", "1.035");
233    });
234
235    updateGridCard(el, ch);
236    requestAnimationFrame(function () {
237      el.classList.remove("is-entering");
238    });
239    return el;
240  }
241
242  function updateGridCard(el, ch) {
243    el.dataset.number = String(ch.number || "");
244    el.dataset.category = ch.category || "inne";
245    el._channelData = ch;
246
247    if (ch.picon_url) {
248      el.innerHTML = '<img src="' + ch.picon_url + '" alt="' + escapeHtml(ch.name || "") + '">';
249    } else {
250      el.innerHTML = '<span>' + escapeHtml((ch.number ? (ch.number + " ") : "") + (ch.name || "")) + "</span>";
251    }
252  }
253
254  function getVisiblePositions(grid) {
255    var map = Object.create(null);
256    toArray(grid.querySelectorAll(".channel")).forEach(function (el) {
257      var key = el.dataset.channelKey;
258      if (key) {
259        map[key] = el.getBoundingClientRect();
260      }
261    });
262    return map;
263  }
264
265  function animateGridFlip(grid, oldPositions) {
266    toArray(grid.querySelectorAll(".channel")).forEach(function (el) {
267      var key = el.dataset.channelKey;
268      var oldPos = oldPositions[key];
269      if (!oldPos) {
270        return;
271      }
272
273      var newPos = el.getBoundingClientRect();
274      var dx = oldPos.left - newPos.left;
275      var dy = oldPos.top - newPos.top;
276      if (!dx && !dy) {
277        return;
278      }
279
280      el.style.transition = "none";
281      el.style.setProperty("--flip-x", dx + "px");
282      el.style.setProperty("--flip-y", dy + "px");
283      el.offsetHeight;
284      el.style.transition = "transform 760ms cubic-bezier(0.22,1,0.36,1),opacity 360ms ease,box-shadow 260ms ease,border-color 260ms ease";
285      el.style.setProperty("--flip-x", "0px");
286      el.style.setProperty("--flip-y", "0px");
287    });
288  }
289
290  function renderGrid(channels) {
291    var grid = getGridTarget();
292    if (!grid) {
293      return;
294    }
295
296    ensureGridAnimationStyles();
297    var popup = getPopupTarget();
298    var oldPositions = getVisiblePositions(grid);
299    var wanted = Object.create(null);
300    gridRenderToken += 1;
301    var token = gridRenderToken;
302
303    channels.forEach(function (ch) {
304      var key = getChannelKey(ch);
305      wanted[key] = true;
306
307      var card = gridCardsByKey[key];
308      if (!card) {
309        card = createGridCard(ch, popup);
310        card.dataset.channelKey = key;
311        gridCardsByKey[key] = card;
312      } else {
313        updateGridCard(card, ch);
314      }
315
316      card._removeToken = 0;
317      card.style.opacity = "";
318      card.style.transform = "";
319      grid.appendChild(card);
320    });
321
322    Object.keys(gridCardsByKey).forEach(function (key) {
323      if (wanted[key]) {
324        return;
325      }
326      var card = gridCardsByKey[key];
327      if (card && card.parentNode === grid) {
328        card._removeToken = token;
329        card.style.opacity = "0";
330        card.style.transform = "scale(0.8)";
331        setTimeout(function () {
332          if (card._removeToken !== token) {
333            return;
334          }
335          if (card.parentNode === grid) {
336            grid.removeChild(card);
337          }
338          delete gridCardsByKey[key];
339        }, 320);
340      } else {
341        delete gridCardsByKey[key];
342      }
343    });
344
345    requestAnimationFrame(function () {
346      animateGridFlip(grid, oldPositions);
347    });
348  }
349
350  function groupByCategory(channels) {
351    var grouped = Object.create(null);
352
353    channels.forEach(function (ch) {
354      var cat = ch.category || "inne";
355      if (!grouped[cat]) {
356        grouped[cat] = [];
357      }
358      grouped[cat].push(ch);
359    });
360
361    return grouped;
362  }
363
364  function renderColumns(channels) {
365    var columnsRoot = getColumnsTarget();
366    if (!columnsRoot) {
367      return;
368    }
369
370    columnsRoot.innerHTML = "";
371
372    if (!channels || channels.length === 0) {
373      return;
374    }
375
376    var grouped = groupByCategory(channels);
377    var categoryNames = Object.keys(grouped);
378
379    var columns = [0, 1, 2].map(function () {
380      var col = document.createElement("div");
381      col.className = "channels-column";
382      col._count = 0;
383      columnsRoot.appendChild(col);
384      return col;
385    });
386
387    categoryNames.forEach(function (category) {
388      var list = grouped[category];
389      list.sort(function (a, b) {
390        var an = Number(a.number || 0);
391        var bn = Number(b.number || 0);
392        if (an !== bn) {
393          return an - bn;
394        }
395        return String(a.name || "").localeCompare(String(b.name || ""));
396      });
397
398      var target = columns.reduce(function (a, b) {
399        return a._count <= b._count ? a : b;
400      });
401
402      var group = document.createElement("div");
403      group.className = "category-group";
404
405      var title = document.createElement("div");
406      title.className = "category-title";
407      title.textContent = category + " (" + list.length + ")";
408
409      var items = document.createElement("div");
410      items.className = "category-channels";
411
412      list.forEach(function (ch) {
413        var item = document.createElement("div");
414        item.className = "channel-list-item";
415        item.innerHTML = "<span>" + escapeHtml(String(ch.number || "")) + "</span>" + escapeHtml(ch.name || "");
416        items.appendChild(item);
417      });
418
419      group.appendChild(title);
420      group.appendChild(items);
421      target.appendChild(group);
422      target._count += list.length;
423    });
424  }
425
426  function escapeHtml(value) {
427    return String(value || "")
428      .replace(/&/g, "&amp;")
429      .replace(/</g, "&lt;")
430      .replace(/>/g, "&gt;")
431      .replace(/\"/g, "&quot;")
432      .replace(/'/g, "&#039;");
433  }
434
435  function fetchData(callback) {
436    if (dataCache) {
437      callback(null, dataCache);
438      return;
439    }
440
441    if (dataPending) {
442      setTimeout(function () {
443        fetchData(callback);
444      }, 100);
445      return;
446    }
447
448    dataPending = true;
449
450    var xhr = new XMLHttpRequest();
451    xhr.open("GET", DATA_URL, true);
452    xhr.onreadystatechange = function () {
453      if (xhr.readyState !== 4) {
454        return;
455      }
456
457      dataPending = false;
458
459      if (xhr.status < 200 || xhr.status >= 300) {
460        callback(new Error("HTTP " + xhr.status));
461        return;
462      }
463
464      try {
465        dataCache = JSON.parse(xhr.responseText);
466        callback(null, dataCache);
467      } catch (err) {
468        callback(err);
469      }
470    };
471
472    xhr.send();
473  }
474
475  function resolveChannelsForPackage(pkg, data) {
476    if (!data || !data.channels_by_package) {
477      return [];
478    }
479
480    var candidates = [pkg.keyNorm, pkg.labelNorm, normalizeKey(pkg.key), normalizeKey(pkg.label)];
481    var map = data.channels_by_package;
482    var aliases = data.package_alias_to_key || {};
483
484    var i;
485    for (i = 0; i < candidates.length; i += 1) {
486      var candidate = candidates[i];
487      if (!candidate) {
488        continue;
489      }
490
491      if (map[candidate]) {
492        return map[candidate];
493      }
494
495      if (aliases[candidate] && map[aliases[candidate]]) {
496        return map[aliases[candidate]];
497      }
498    }
499
500    return [];
501  }
502
503  function init() {
504    var packages = readPackages();
505    if (packages.length === 0) {
506      console.warn("tv.js: Nie znaleziono pakietow. Uzyj klasy z prefiksem '" + PACKAGE_CLASS_PREFIX + "' i data-label.");
507      return;
508    }
509
510    var target = ensureDescriptionTarget();
511    var switchers = ensureSwitcherMounts(target);
512    switchers.forEach(function (switcher) {
513      switcher.innerHTML = "";
514    });
515
516    var map = Object.create(null);
517    packages.forEach(function (pkg) {
518      map[pkg.key] = pkg;
519      switchers.forEach(function (switcher) {
520        switcher.appendChild(createButton(pkg));
521      });
522    });
523
524    function setActive(key) {
525      switchers.forEach(function (switcher) {
526        toArray(switcher.querySelectorAll("button[data-package]")).forEach(function (btn) {
527          btn.classList.toggle("active", btn.dataset.package === key);
528        });
529      });
530    }
531
532    function renderChannelsForPackage(pkg) {
533      fetchData(function (err, data) {
534        if (err) {
535          console.warn("tv.js: Blad pobierania danych kanałow:", err);
536          renderGrid([]);
537          renderColumns([]);
538          return;
539        }
540
541        var channels = resolveChannelsForPackage(pkg, data);
542        renderGrid(channels);
543        renderColumns(channels);
544      });
545    }
546
547    function applyPackage(key) {
548      var pkg = map[key];
549      if (!pkg) {
550        return;
551      }
552
553      target.innerHTML = pkg.html;
554      setActive(key);
555      renderChannelsForPackage(pkg);
556    }
557
558    switchers.forEach(function (switcher) {
559      toArray(switcher.querySelectorAll("button[data-package]")).forEach(function (btn) {
560        btn.addEventListener("click", function () {
561          applyPackage(btn.dataset.package);
562        });
563      });
564    });
565
566    var defaultPkg = null;
567    for (var i = 0; i < packages.length; i += 1) {
568      if (packages[i].isDefault) {
569        defaultPkg = packages[i];
570        break;
571      }
572    }
573    if (!defaultPkg) {
574      defaultPkg = packages[0];
575    }
576
577    applyPackage(defaultPkg.key);
578  }
579
580  if (document.readyState === "loading") {
581    document.addEventListener("DOMContentLoaded", init);
582  } else {
583    init();
584  }
585})();

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.