PageSourceSearch

https://generor.com/js/modules/model-speed-meter.js

js generor.com collected 2026-10-04 12:19:02 UTC 3,526 bytes, 99 lines download raw bytes

1/**
2 * Relative speed meters in expanded AI model dropdown descriptions.
3 * 100 discrete steps, red (slow) → yellow → green (fast) vs other options
4 * in the same list, using historical completions from get-generation-times.php.
5 */
6
7const cache = {};
8
9function generatorFromPanel(panel) {
10    const selectId = panel.dataset.selectId || '';
11    const container = document.querySelector(`.custom-dropdown[data-select-id="${selectId}"]`);
12    if (container && container.dataset.speedGenerator) return container.dataset.speedGenerator;
13    if (panel.dataset.speedGenerator) return panel.dataset.speedGenerator;
14    const path = (window.location.pathname || '').split('/').filter(Boolean);
15    return path[0] || '';
16}
17
18async function loadTimes(generator) {
19    if (!generator) return {};
20    if (cache[generator]) return cache[generator];
21    cache[generator] = fetch('/apis/get-generation-times.php?list=1&generator=' + encodeURIComponent(generator))
22        .then((r) => (r.ok ? r.json() : { times: {} }))
23        .then((data) => data.times || {})
24        .catch(() => ({}));
25    return cache[generator];
26}
27
28function optionTime(option, times) {
29    const ids = (option.dataset.speedIds || '').split(',').map((s) => s.trim()).filter(Boolean);
30    if (!ids.length) return null;
31    const vals = ids.map((id) => times[id]).filter((t) => typeof t === 'number' && t > 0);
32    if (!vals.length) return null;
33    return vals.reduce((a, b) => a + b, 0) / vals.length;
34}
35
36function scoreFromTimes(t, min, max) {
37    if (max <= min) return 100;
38    return Math.max(1, Math.min(100, Math.round(1 + 99 * (max - t) / (max - min))));
39}
40
41function ensureSteps(meter) {
42    const track = meter.querySelector('.model-speed-steps');
43    if (!track || track.childElementCount === 100) return track;
44    const frag = document.createDocumentFragment();
45    for (let i = 1; i <= 100; i++) {
46        const step = document.createElement('span');
47        step.className = 'model-speed-step';
48        step.style.setProperty('--i', String(i));
49        frag.appendChild(step);
50    }
51    track.appendChild(frag);
52    return track;
53}
54
55function paintMeter(meter, score) {
56    meter.hidden = false;
57    meter.dataset.score = String(score);
58    const valueEl = meter.querySelector('.model-speed-meter-value');
59    if (valueEl) valueEl.textContent = String(score);
60    const track = ensureSteps(meter);
61    if (!track) return;
62    const steps = track.children;
63    for (let i = 0; i < steps.length; i++) {
64        const n = i + 1;
65        steps[i].classList.toggle('on', n <= score);
66    }
67}
68
69export async function hydrateModelSpeedMeters(panel) {
70    if (!panel) return;
71    const meters = panel.querySelectorAll('.model-speed-meter[data-speed-ids]');
72    if (!meters.length) return;
73
74    const generator = generatorFromPanel(panel);
75    const times = await loadTimes(generator);
76
77    const optionTimes = [];
78    meters.forEach((meter) => {
79        const option = meter.closest('.custom-dropdown-option');
80        const t = option ? optionTime(option, times) : null;
81        optionTimes.push({ meter, t });
82    });
83
84    const known = optionTimes.map((o) => o.t).filter((t) => t != null);
85    if (!known.length) {
86        meters.forEach((m) => { m.hidden = true; });
87        return;
88    }
89    const min = Math.min(...known);
90    const max = Math.max(...known);
91
92    optionTimes.forEach(({ meter, t }) => {
93        if (t == null) {
94            meter.hidden = true;
95            return;
96        }
97        paintMeter(meter, scoreFromTimes(t, min, max));
98    });
99}

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.