PageSourceSearch

https://www.matejbaco.eu/cap.min.js

js matejbaco.eu collected 2026-09-25 21:46:49 UTC 17,225 bytes, 385 lines download raw bytes

1"use strict";
2!(function () {
3  let e;
4  const t = function () {
5      return window?.CAP_CUSTOM_FETCH
6        ? window.CAP_CUSTOM_FETCH(...arguments)
7        : fetch(...arguments);
8    },
9    r = (e, t = 1e4) =>
10      new Promise((r, s) => {
11        const i = setTimeout(() => {
12            s(new Error("Initialize timeout"));
13          }, t),
14          a = () => {
15            e() ? (clearTimeout(i), r()) : setTimeout(a, 500);
16          };
17        a();
18      });
19  class s extends HTMLElement {
20    #e = "";
21    #t = null;
22    #r = navigator.hardwareConcurrency || 8;
23    #s = null;
24    #i;
25    #a;
26    #n;
27    #o = !1;
28    #c;
29    static get observedAttributes() {
30      return ["onsolve", "onprogress", "onreset", "onerror", "workers"];
31    }
32    constructor() {
33      super(),
34        this.#c &&
35          this.#c.forEach((e, t) => {
36            this.removeEventListener(t.slice(2), e);
37          }),
38        (this.#c = new Map()),
39        (this.boundHandleProgress = this.handleProgress.bind(this)),
40        (this.boundHandleSolve = this.handleSolve.bind(this)),
41        (this.boundHandleError = this.handleError.bind(this)),
42        (this.boundHandleReset = this.handleReset.bind(this));
43    }
44    async initialize() {
45      this.#e && URL.revokeObjectURL(this.#e);
46      try {
47        await r(() => !!e),
48          (this.#e = URL.createObjectURL(
49            new Blob([e], { type: "application/javascript" }),
50          ));
51      } catch (e) {
52        throw (this.error("Failed to initialize worker"), e);
53      }
54    }
55    attributeChangedCallback(e, t, r) {
56      if (e.startsWith("on")) {
57        const t = e.slice(2),
58          s = this.#c.get(e);
59        if ((s && this.removeEventListener(t, s), r)) {
60          const r = (t) => {
61            const r = this.getAttribute(e);
62            "function" == typeof window[r] && window[r].call(this, t);
63          };
64          this.#c.set(e, r), this.addEventListener(t, r);
65        }
66      }
67    }
68    async connectedCallback() {
69      (this.#n = this),
70        (this.#i = this.attachShadow({ mode: "open" })),
71        (this.#a = document.createElement("div")),
72        this.createUI(),
73        this.addEventListeners(),
74        await this.initialize(),
75        this.#a.removeAttribute("disabled");
76      const e = this.getAttribute("data-cap-worker-count");
77      this.setWorkersCount(
78        parseInt(e) ? parseInt(e, 10) : navigator.hardwareConcurrency || 8,
79      ),
80        (this.#n.innerHTML = '<input type="hidden" name="cap-token">');
81    }
82    async solve() {
83      if (!this.#o)
84        try {
85          (this.#o = !0),
86            this.updateUI("verifying", "Verifying...", !0),
87            await r(() => !!this.#e),
88            this.dispatchEvent("progress", { progress: 0 });
89          try {
90            const e = this.getAttribute("data-cap-api-endpoint");
91            if (!e) throw new Error("Missing API endpoint");
92            const { challenge: r, token: s } = await (
93                await t(`${e}challenge`, { method: "POST" })
94              ).json(),
95              i = await this.solveChallenges(r),
96              a = await (
97                await t(`${e}redeem`, {
98                  method: "POST",
99                  body: JSON.stringify({ token: s, solutions: i }),
100                  headers: { "Content-Type": "application/json" },
101                })
102              ).json();
103            if ((this.dispatchEvent("progress", { progress: 100 }), !a.success))
104              throw new Error("Invalid solution");
105            this.querySelector("input[name='cap-token']") &&
106              (this.querySelector("input[name='cap-token']").value = a.token),
107              this.dispatchEvent("solve", { token: a.token }),
108              (this.#s = a.token),
109              this.#t && clearTimeout(this.#t);
110            const n = new Date(a.expires).getTime() - Date.now();
111            return (
112              n > 0 && n < 864e5
113                ? (this.#t = setTimeout(() => this.reset(), n))
114                : this.error("Invalid expiration time"),
115              { success: !0, token: this.#s }
116            );
117          } catch (e) {
118            throw (this.error(e.message), e);
119          }
120        } finally {
121          this.#o = !1;
122        }
123    }
124    async solveChallenges(e) {
125      const t = e.length;
126      let r = 0;
127      const s = Array(this.#r)
128          .fill(null)
129          .map(() => new Worker(this.#e)),
130        i = ([e, i], a) =>
131          new Promise((n, o) => {
132            const c = s[a],
133              d = setTimeout(() => {
134                c.terminate(),
135                  (s[a] = new Worker(this.#e)),
136                  o(new Error("Worker timeout"));
137              }, 3e4);
138            (c.onmessage = ({ data: s }) => {
139              s.found &&
140                (clearTimeout(d),
141                r++,
142                this.dispatchEvent("progress", {
143                  progress: Math.round((r / t) * 100),
144                }),
145                n([e, i, s.nonce]));
146            }),
147              (c.onerror = (e) => {
148                clearTimeout(d), this.error(`Error in worker: ${e}`), o(e);
149              }),
150              c.postMessage({ salt: e, target: i });
151          }),
152        a = [];
153      try {
154        for (let t = 0; t < e.length; t += this.#r) {
155          const r = e.slice(t, Math.min(t + this.#r, e.length)),
156            s = await Promise.all(r.map((e, t) => i(e, t)));
157          a.push(...s);
158        }
159      } finally {
160        s.forEach((e) => e.terminate());
161      }
162      return a;
163    }
164    setWorkersCount(e) {
165      const t = parseInt(e, 10),
166        r = Math.min(navigator.hardwareConcurrency || 8, 16);
167      this.#r =
168        !isNaN(t) && t > 0 && t <= r ? t : navigator.hardwareConcurrency || 8;
169    }
170    createUI() {
171      this.#a.classList.add("captcha"),
172        this.#a.setAttribute("role", "button"),
173        this.#a.setAttribute("tabindex", "0"),
174        this.#a.setAttribute("disabled", "true"),
175        (this.#a.innerHTML =
176          '<div class="checkbox"></div><p>I\'m a human</p><a href="https://capjs.js.org/" class="credits" target="_blank" rel="follow noopener"><span>Secured by&nbsp;</span>Cap</a>'),
177        (this.#i.innerHTML =
178          '<style>.captcha{background-color:var(--cap-background);border:1px solid var(--cap-border-color);border-radius:var(--cap-border-radius);width:var(--cap-widget-width);display:flex;align-items:center;padding:var(--cap-widget-padding);gap:var(--cap-gap);cursor:pointer;transition:filter var(--cap-transition-duration),transform var(--cap-transition-duration);position:relative;-webkit-tap-highlight-color:rgba(255,255,255,0);overflow:hidden;color:var(--cap-color)}.captcha:hover{filter:var(--cap-hover-filter)}.captcha:not([disabled]):active{transform:scale(var(--cap-active-scale))}.checkbox{width:var(--cap-checkbox-size);height:var(--cap-checkbox-size);border:var(--cap-checkbox-border);border-radius:var(--cap-checkbox-border-radius);background-color:var(--cap-checkbox-background);transition:opacity var(--cap-transition-duration);margin-top:var(--cap-checkbox-margin);margin-bottom:var(--cap-checkbox-margin)}.captcha *{font-family:var(--cap-font)}.captcha p{margin:0;font-weight:500;font-size:15px;user-select:none;transition:opacity var(--cap-transition-duration)}.captcha[data-state=verifying] .checkbox{background: none;display:flex;align-items:center;justify-content:center;transform: scale(1.1);border: none;border-radius: 50%;background: conic-gradient(var(--cap-spinner-color) 0%, var(--cap-spinner-color) var(--progress, 0%), var(--cap-spinner-background-color) var(--progress, 0%), var(--cap-spinner-background-color) 100%);position: relative;}.captcha[data-state=verifying] .checkbox::after {content: "";background-color: var(--cap-background);width: calc(100% - var(--cap-spinner-thickness));height: calc(100% - var(--cap-spinner-thickness));border-radius: 50%;margin:calc(var(--cap-spinner-thickness) / 2)}.captcha[data-state=done] .checkbox{border:1px solid transparent;background-image:var(--cap-checkmark);background-size:cover}.captcha[data-state=error] .checkbox{border:1px solid transparent;background-image:var(--cap-error-cross);background-size:cover}.captcha[disabled]{\ncursor:not-allowed}.captcha[disabled][data-state=verifying]{cursor:progress}.captcha[disabled][data-state=done]{cursor:default}.captcha .credits{position:absolute;bottom:10px;right:10px;font-size:var(--cap-credits-font-size);color:var(--cap-color);opacity:var(--cap-opacity-hover)}.captcha .credits span{display:none;text-decoration:underline}.captcha .credits:hover span{display:inline-block}</style>'),
179        this.#i.appendChild(this.#a);
180    }
181    addEventListeners() {
182      this.#a.querySelector("a").addEventListener("click", (e) => {
183        e.stopPropagation(),
184          e.preventDefault(),
185          window.open("https://capjs.js.org", "_blank");
186      }),
187        this.#a.addEventListener("click", () => {
188          this.#a.hasAttribute("disabled") || this.solve();
189        }),
190        this.#a.addEventListener("keydown", (e) => {
191          ("Enter" !== e.key && " " !== e.key) ||
192            this.#a.hasAttribute("disabled") ||
193            (e.preventDefault(), this.solve());
194        }),
195        this.addEventListener("progress", this.boundHandleProgress),
196        this.addEventListener("solve", this.boundHandleSolve),
197        this.addEventListener("error", this.boundHandleError),
198        this.addEventListener("reset", this.boundHandleReset);
199    }
200    updateUI(e, t, r = !1) {
201      this.#a.setAttribute("data-state", e),
202        (this.#a.querySelector("p").innerText = t),
203        r
204          ? this.#a.setAttribute("disabled", "true")
205          : this.#a.removeAttribute("disabled");
206    }
207    handleProgress(e) {
208      const t = this.#a.querySelector("p");
209      t &&
210        (this.#a
211          .querySelector(".checkbox")
212          .style.setProperty("--progress", `${e.detail.progress}%`),
213        (t.innerText = `Verifying... ${e.detail.progress}%`)),
214        this.executeAttributeCode("onprogress", e);
215    }
216    handleSolve(e) {
217      this.updateUI("done", "You're a human", !0),
218        this.executeAttributeCode("onsolve", e);
219    }
220    handleError(e) {
221      this.updateUI("error", "Error. Try again."),
222        this.executeAttributeCode("onerror", e);
223    }
224    handleReset(e) {
225      this.updateUI("", "I'm a human"), this.executeAttributeCode("onreset", e);
226    }
227    executeAttributeCode(e, t) {
228      const r = this.getAttribute(e);
229      if (!r) return;
230      new Function("event", r).call(this, t);
231    }
232    error(e = "Unknown error") {
233      console.error("[Cap] Error:", e),
234        this.dispatchEvent("error", { isCap: !0, message: e });
235    }
236    dispatchEvent(e, t = {}) {
237      const r = new CustomEvent(e, { bubbles: !0, composed: !0, detail: t });
238      super.dispatchEvent(r);
239    }
240    reset() {
241      this.#t && (clearTimeout(this.#t), (this.#t = null)),
242        this.dispatchEvent("reset"),
243        (this.#s = null),
244        this.querySelector("input[name='cap-token']") &&
245          (this.querySelector("input[name='cap-token']").value = "");
246    }
247    get token() {
248      return this.#s;
249    }
250    disconnectedCallback() {
251      this.removeEventListener("progress", this.boundHandleProgress),
252        this.removeEventListener("solve", this.boundHandleSolve),
253        this.removeEventListener("error", this.boundHandleError),
254        this.removeEventListener("reset", this.boundHandleReset),
255        this.#c.forEach((e, t) => {
256          this.removeEventListener(t.slice(2), e);
257        }),
258        this.#c.clear(),
259        this.#i && (this.#i.innerHTML = ""),
260        this.reset(),
261        this.cleanup();
262    }
263    cleanup() {
264      this.#t && (clearTimeout(this.#t), (this.#t = null)),
265        this.#e && (URL.revokeObjectURL(this.#e), (this.#e = ""));
266    }
267  }
268  class i {
269    constructor(e = {}, t) {
270      let r = t || document.createElement("cap-widget");
271      if (
272        (Object.entries(e).forEach(([e, t]) => {
273          r.setAttribute(e, t);
274        }),
275        !e.apiEndpoint)
276      )
277        throw (r.remove(), new Error("Missing API endpoint"));
278      r.setAttribute("data-cap-api-endpoint", e.apiEndpoint),
279        (this.widget = r),
280        (this.solve = this.widget.solve.bind(this.widget)),
281        (this.reset = this.widget.reset.bind(this.widget)),
282        (this.addEventListener = this.widget.addEventListener.bind(
283          this.widget,
284        )),
285        Object.defineProperty(this, "token", {
286          get: () => r.getToken(),
287          configurable: !0,
288          enumerable: !0,
289        }),
290        t ||
291          ((r.style.display = "none"), document.documentElement.appendChild(r));
292    }
293  }
294  const a = new CSSStyleSheet();
295  a.replaceSync(
296    'html{--cap-font:system,-apple-system,"BlinkMacSystemFont",".SFNSText-Regular","San Francisco","Roboto","Segoe UI","Helvetica Neue","Lucida Grande","Ubuntu","arial",sans-serif;--cap-color:#212121;--cap-background:#fdfdfd;--cap-border-color:#dddddd8f;--cap-border-radius:14px;--cap-checkbox-border:1px solid #aaaaaad1;--cap-checkbox-border-radius:6px;--cap-checkbox-background:#fafafa91;--cap-widget-width:240px;--cap-widget-padding:14px;--cap-checkbox-size:24px;--cap-checkbox-margin:2px;--cap-transition-duration:0.2s;--cap-gap:15px;--cap-opacity-hover:0.8;--cap-hover-filter:brightness(97%);--cap-active-scale:0.98;--cap-credits-font-size:12px;--cap-spinner-color:black;--cap-spinner-background-color:#eee;--cap-error-cross:url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'96\' height=\'96\' viewBox=\'0 0 24 24\'%3E%3Cpath fill=\'%23f55b50\' d=\'M11 15h2v2h-2zm0-8h2v6h-2zm1-5C6.47 2 2 6.5 2 12a10 10 0 0 0 10 10a10 10 0 0 0 10-10A10 10 0 0 0 12 2m0 18a8 8 0 0 1-8-8a8 8 0 0 1 8-8a8 8 0 0 1 8 8a8 8 0 0 1-8 8\'/%3E%3C/svg%3E");--cap-checkmark:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cstyle%3E%40keyframes%20anim%7B0%25%7Bstroke-dashoffset%3A23.21320343017578px%7Dto%7Bstroke-dashoffset%3A0%7D%7D%3C%2Fstyle%3E%3Cpath%20fill%3D%22none%22%20stroke%3D%22%2300a67d%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%20stroke-width%3D%222%22%20d%3D%22m5%2012%205%205L20%207%22%20style%3D%22stroke-dashoffset%3A0%3Bstroke-dasharray%3A23.21320343017578px%3Banimation%3Aanim%20.5s%20ease%22%2F%3
296E%3C%2Fsvg%3E");--cap-spinner-thickness:5px;}',
297  ),
298    document.adoptedStyleSheets.push(a);
299  const n = function () {
300    let e;
301    self.onmessage = async ({ data: { salt: t, target: r } }) => {
302      let s = 0;
303      const i = 5e4;
304      let a = 0;
305      const n = new TextEncoder();
306      if (
307        "object" != typeof WebAssembly ||
308        "function" != typeof WebAssembly.instantiate
309      ) {
310        console.log(
311          "[cap] WASM not enabled, falling back to crypto.subtle\nThis is significanty slower than the WASM implementation",
312        );
313        const e = new Uint8Array(r.length / 2);
314        for (let t = 0; t < e.length; t++)
315          e[t] = parseInt(r.substring(2 * t, 2 * t + 2), 16);
316        const o = e.length;
317        for (;;)
318          try {
319            for (let r = 0; r < i; r++) {
320              const r = t + s,
321                i = n.encode(r),
322                a = await crypto.subtle.digest("SHA-256", i),
323                c = new Uint8Array(a, 0, o);
324              let d = !0;
325              for (let t = 0; t < o; t++)
326                if (c[t] !== e[t]) {
327                  d = !1;
328                  break;
329                }
330              if (d) return void self.postMessage({ nonce: s, found: !0 });
331              s++;
332            }
333            a += i;
334          } catch (e) {
335            return (
336              console.error("[cap] fallback worker error", e),
337              void self.postMessage({ found: !1, error: e.message })
338            );
339          }
340      }
341      e || (e = await hashwasm.createSHA256());
342      const o = new Uint8Array(128);
343      for (;;)
344        try {
345          for (let a = 0; a < i; a++) {
346            const i = t + s.toString(),
347              a = n.encode(i);
348            o.set(a), e.init(), e.update(o.subarray(0, a.length));
349            if (e.digest("hex").startsWith(r))
350              return void self.postMessage({ nonce: s, found: !0 });
351            s++;
352          }
353          a += i;
354        } catch (e) {
355          return void self.postMessage({ found: !1, error: e.message });
356        }
357    };
358  };
359  setTimeout(async function () {
360    e =
361      (await (
362        await t(
363          "https://cdn.jsdelivr.net/npm/@cap.js/widget/wasm-hashes.min.js",
364        )
365      ).text()) +
366      n
367        .toString()
368        .replace(/^function\s*\([^\)]*\)\s*{|\}$/g, "")
369        .trim();
370  }, 1),
371    (window.Cap = i),
372    customElements.get("cap-widget")
373      ? console.warn(
374          "The cap-widget element has already been defined. Skipping re-defining it.",
375        )
376      : customElements.define("cap-widget", s),
377    "object" == typeof exports && "undefined" != typeof module
378      ? (module.exports = i)
379      : "function" == typeof define &&
380        define.amd &&
381        define([], function () {
382          return i;
383        }),
384    "undefined" != typeof exports && (exports.default = i);
385})();

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.