PageSourceSearch

https://getwordloot.com/js/shows.js

js getwordloot.com collected 2026-10-02 01:30:26 UTC 3,507 bytes, 110 lines download raw bytes

1(function initShowsPage() {
2  const grid = document.getElementById("showsGrid");
3  const countEl = document.getElementById("showsCount");
4  const searchInput = document.getElementById("showsSearch");
5  if (!grid) return;
6  let allShows = [];
7
8  function crunchyrollUrl(show) {
9    if (show.url) return show.url;
10    const slug = String(show.search || show.title || "")
11      .trim()
12      .replace(/\s+/g, "-");
13    return `https://www.crunchyroll.com/search?q=${encodeURIComponent(slug)}`;
14  }
15
16  function escapeHtml(value) {
17    return String(value)
18      .replace(/&/g, "&")
19      .replace(/</g, "&lt;")
20      .replace(/>/g, "&gt;");
21  }
22
23  function groupByLetter(shows) {
24    const groups = new Map();
25    for (const show of shows) {
26      const title = String(show.title || show.search || "Untitled").trim();
27      const first = title.charAt(0).toUpperCase();
28      const letter = /[A-Z]/.test(first) ? first : "#";
29      const list = groups.get(letter) ?? [];
30      list.push(show);
31      groups.set(letter, list);
32    }
33    return Array.from(groups.entries()).sort((a, b) => {
34      if (a[0] === "#") return 1;
35      if (b[0] === "#") return -1;
36      return a[0].localeCompare(b[0]);
37    });
38  }
39
40  function renderShows(shows, query = "") {
41    if (countEl) {
42      const base = `${shows.length} show${shows.length === 1 ? "" : "s"} with Japanese subtitles`;
43      countEl.textContent = query ? `${base} (filtered by "${query}")` : base;
44    }
45
46    if (shows.length === 0) {
47      grid.innerHTML = `
48        <div class="shows-empty">
49          No shows found${query ? ` for "${escapeHtml(query)}"` : ""}.
50        </div>
51      `;
52      return;
53    }
54
55    const groups = groupByLetter(shows);
56    grid.innerHTML = groups
57      .map(([letter, entries]) => {
58        const cards = entries
59          .map((show) => {
60            const title = show.title || show.search || "Untitled";
61            const href = crunchyrollUrl(show);
62            return `
63              <a class="show-card" href="${href}" target="_blank" rel="noopener noreferrer">
64                <span class="show-card__body">
65                  <span class="show-card__title">${escapeHtml(title)}</span>
66                  <span class="show-card__meta">Open on Crunchyroll</span>
67                </span>
68              </a>
69            `;
70          })
71          .join("");
72        return `
73          <section class="shows-group">
74            <h2 class="shows-group__title">${letter}</h2>
75            <div class="shows-group__grid">${cards}</div>
76          </section>
77        `;
78      })
79      .join("");
80  }
81
82  function applyFilter() {
83    const query = String(searchInput?.value ?? "").trim().toLowerCase();
84    if (!query) {
85      renderShows(allShows);
86      return;
87    }
88    const filtered = allShows.filter((show) =>
89      `${show.title || ""} ${show.search || ""}`.toLowerCase().includes(query),
90    );
91    renderShows(filtered, query);
92  }
93
94  fetch("data/available-shows.json")
95    .then((res) => {
96      if (!res.ok) throw new Error("Failed to load shows");
97      return res.json();
98    })
99    .then((shows) => {
100      if (!Array.isArray(shows)) throw new Error("Invalid shows data");
101      shows.sort((a, b) => String(a.title || "").localeCompare(String(b.title || "")));
102      allShows = shows;
103      renderShows(allShows);
104      searchInput?.addEventListener("input", applyFilter);
105    })
106    .catch(() => {
107      if (countEl) countEl.textContent = "Could not load supported shows.";
108      grid.innerHTML = "";
109    });
110})();

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.