mirror of
https://github.com/multipleof4/lynchmark.git
synced 2026-05-18 04:32:12 +00:00
Compare commits
7 Commits
e58cbc2af2
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ebeee1ab97 | ||
|
|
542af993bf | ||
| 275b423549 | |||
|
|
d1bb37cfb3 | ||
| bca9ba076b | |||
|
|
d68ffe48d0 | ||
| 4dd5b479d3 |
10
README
10
README
@@ -9,20 +9,18 @@ SHARED_PROMPT: "Provide production-ready and maintainable JavaScript code. Apply
|
|||||||
The following models are included in the benchmark run.
|
The following models are included in the benchmark run.
|
||||||
|
|
||||||
<!-- MODELS_START -->
|
<!-- MODELS_START -->
|
||||||
|
google/gemini-3.1-flash-lite
|
||||||
|
openai/gpt-5.5 EFF:high
|
||||||
|
deepseek/deepseek-v4-pro
|
||||||
|
moonshotai/kimi-k2.6
|
||||||
anthropic/claude-opus-4.7 EFF:medium
|
anthropic/claude-opus-4.7 EFF:medium
|
||||||
z-ai/glm-5.1
|
z-ai/glm-5.1
|
||||||
x-ai/grok-4.20-beta
|
|
||||||
openai/gpt-5.4
|
openai/gpt-5.4
|
||||||
google/gemini-3.1-flash-lite-preview
|
google/gemini-3.1-flash-lite-preview
|
||||||
openai/gpt-5.3-codex
|
openai/gpt-5.3-codex
|
||||||
google/gemini-3.1-pro-preview
|
google/gemini-3.1-pro-preview
|
||||||
anthropic/claude-sonnet-4.6
|
|
||||||
minimax/minimax-m2.5
|
|
||||||
z-ai/glm-5
|
|
||||||
anthropic/claude-opus-4.6
|
anthropic/claude-opus-4.6
|
||||||
moonshotai/kimi-k2.5
|
moonshotai/kimi-k2.5
|
||||||
z-ai/glm-4.7
|
|
||||||
google/gemini-3-flash-preview TEMP:0.35
|
google/gemini-3-flash-preview TEMP:0.35
|
||||||
deepseek/deepseek-v3.2
|
deepseek/deepseek-v3.2
|
||||||
anthropic/claude-sonnet-4.5 TEMP:0.7
|
|
||||||
<!-- MODELS_END -->
|
<!-- MODELS_END -->
|
||||||
|
|||||||
9
tests/10_scrypt_hash/outputs/deepseek_deepseek-v4-pro.js
Normal file
9
tests/10_scrypt_hash/outputs/deepseek_deepseek-v4-pro.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
async function hashPassword(p, s) {
|
||||||
|
const e = new TextEncoder;
|
||||||
|
const { default: scrypt } = await import('https://cdn.jsdelivr.net/npm/scrypt-js@3.0.1/+esm');
|
||||||
|
const h = await scrypt(e.encode(p), e.encode(s), 1024, 8, 1, 32);
|
||||||
|
return [...h].map(b => (b < 16 ? '0' : '') + b.toString(16)).join('');
|
||||||
|
}
|
||||||
|
export default hashPassword;
|
||||||
|
// Generation time: 58.113s
|
||||||
|
// Result: FAIL
|
||||||
15
tests/10_scrypt_hash/outputs/google_gemini-3.1-flash-lite.js
Normal file
15
tests/10_scrypt_hash/outputs/google_gemini-3.1-flash-lite.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
async function hashPassword(password, salt) {
|
||||||
|
const { scrypt } = await import('https://esm.run/scrypt-js');
|
||||||
|
const enc = new TextEncoder();
|
||||||
|
|
||||||
|
const key = await scrypt(
|
||||||
|
enc.encode(password),
|
||||||
|
enc.encode(salt),
|
||||||
|
1024, 8, 1, 32
|
||||||
|
);
|
||||||
|
|
||||||
|
return [...key].map(b => b.toString(16).padStart(2, '0')).join('');
|
||||||
|
}
|
||||||
|
export default hashPassword;
|
||||||
|
// Generation time: 1.123s
|
||||||
|
// Result: PASS
|
||||||
9
tests/10_scrypt_hash/outputs/moonshotai_kimi-k2.6.js
Normal file
9
tests/10_scrypt_hash/outputs/moonshotai_kimi-k2.6.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
const hashPassword = async (password, salt) => {
|
||||||
|
const { default: scrypt } = await import('https://cdn.jsdelivr.net/npm/scrypt-js@3.0.1/+esm');
|
||||||
|
const e = new TextEncoder();
|
||||||
|
const h = await scrypt(e.encode(password), e.encode(salt), 1024, 8, 1, 32);
|
||||||
|
return [...h].map(b => b.toString(16).padStart(2, '0')).join('');
|
||||||
|
};
|
||||||
|
export default hashPassword;
|
||||||
|
// Generation time: 36.174s
|
||||||
|
// Result: FAIL
|
||||||
24
tests/10_scrypt_hash/outputs/openai_gpt-5.5 EFF_high.js
Normal file
24
tests/10_scrypt_hash/outputs/openai_gpt-5.5 EFF_high.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
const SCRYPT_CDN = 'https://cdn.jsdelivr.net/npm/scrypt-js@3.0.1/+esm';
|
||||||
|
|
||||||
|
async function hashPassword(password, salt) {
|
||||||
|
if (typeof password !== 'string' || typeof salt !== 'string')
|
||||||
|
throw new TypeError('password and salt must be strings');
|
||||||
|
|
||||||
|
const { scrypt } = await import(SCRYPT_CDN);
|
||||||
|
const enc = new TextEncoder();
|
||||||
|
const hash = await scrypt(
|
||||||
|
enc.encode(password),
|
||||||
|
enc.encode(salt),
|
||||||
|
1024,
|
||||||
|
8,
|
||||||
|
1,
|
||||||
|
32
|
||||||
|
);
|
||||||
|
|
||||||
|
return [...hash]
|
||||||
|
.map(b => b.toString(16).padStart(2, '0'))
|
||||||
|
.join('');
|
||||||
|
}
|
||||||
|
export default hashPassword;
|
||||||
|
// Generation time: 12.627s
|
||||||
|
// Result: PASS
|
||||||
17
tests/11_geospatial/outputs/deepseek_deepseek-v4-pro.js
Normal file
17
tests/11_geospatial/outputs/deepseek_deepseek-v4-pro.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
async function analyzeGPS(r, e) {
|
||||||
|
try {
|
||||||
|
const t = await import('https://cdn.jsdelivr.net/npm/@turf/turf@7.0.0/dist/turf.min.mjs');
|
||||||
|
const v = r.filter(({ loc: a }) => t.booleanPointInPolygon(t.point(a), e));
|
||||||
|
if (v.length < 2) return 0;
|
||||||
|
v.sort((a, b) => a.ts - b.ts);
|
||||||
|
const c = v.map(a => a.loc);
|
||||||
|
const l = t.lineString(c);
|
||||||
|
const n = t.length(l, { units: 'kilometers' });
|
||||||
|
return Math.round(n * 100) / 100;
|
||||||
|
} catch {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default analyzeGPS;
|
||||||
|
// Generation time: 59.388s
|
||||||
|
// Result: FAIL
|
||||||
16
tests/11_geospatial/outputs/google_gemini-3.1-flash-lite.js
Normal file
16
tests/11_geospatial/outputs/google_gemini-3.1-flash-lite.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
async function analyzeGPS(readings, boundary) {
|
||||||
|
const { booleanPointInPolygon, lineString, length } = await import('https://cdn.skypack.dev/@turf/turf');
|
||||||
|
|
||||||
|
const valid = readings
|
||||||
|
.filter(r => booleanPointInPolygon(r.loc, boundary))
|
||||||
|
.sort((a, b) => a.ts - b.ts);
|
||||||
|
|
||||||
|
if (valid.length < 2) return 0;
|
||||||
|
|
||||||
|
const dist = length(lineString(valid.map(r => r.loc)), { units: 'kilometers' });
|
||||||
|
|
||||||
|
return +dist.toFixed(2);
|
||||||
|
}
|
||||||
|
export default analyzeGPS;
|
||||||
|
// Generation time: 1.005s
|
||||||
|
// Result: PASS
|
||||||
8
tests/11_geospatial/outputs/moonshotai_kimi-k2.6.js
Normal file
8
tests/11_geospatial/outputs/moonshotai_kimi-k2.6.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
const analyzeGPS = async (readings, boundary) => {
|
||||||
|
const { booleanPointInPolygon, lineString, length } = await import('https://esm.sh/@turf/turf');
|
||||||
|
const v = readings.filter(r => booleanPointInPolygon(r.loc, boundary, { ignoreBoundary: true })).sort((a, b) => a.ts - b.ts);
|
||||||
|
return v.length < 2 ? 0 : +length(lineString(v.map(r => r.loc)), { units: 'kilometers' }).toFixed(2);
|
||||||
|
};
|
||||||
|
export default analyzeGPS;
|
||||||
|
// Generation time: 74.841s
|
||||||
|
// Result: PASS
|
||||||
19
tests/11_geospatial/outputs/openai_gpt-5.5 EFF_high.js
Normal file
19
tests/11_geospatial/outputs/openai_gpt-5.5 EFF_high.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
async function analyzeGPS(readings, boundary) {
|
||||||
|
const turf = await import("https://esm.sh/@turf/turf@7.2.0");
|
||||||
|
|
||||||
|
const valid = readings
|
||||||
|
.filter(({ loc }) =>
|
||||||
|
turf.booleanPointInPolygon(turf.point(loc), boundary, { ignoreBoundary: true })
|
||||||
|
)
|
||||||
|
.sort((a, b) => a.ts - b.ts);
|
||||||
|
|
||||||
|
if (valid.length < 2) return 0;
|
||||||
|
|
||||||
|
const line = turf.lineString(valid.map(({ loc }) => loc));
|
||||||
|
const km = turf.length(line, { units: "kilometers" });
|
||||||
|
|
||||||
|
return +km.toFixed(2);
|
||||||
|
}
|
||||||
|
export default analyzeGPS;
|
||||||
|
// Generation time: 13.413s
|
||||||
|
// Result: PASS
|
||||||
46
tests/12_mst_pipeline/outputs/deepseek_deepseek-v4-pro.js
Normal file
46
tests/12_mst_pipeline/outputs/deepseek_deepseek-v4-pro.js
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
async function computeMST(t) {
|
||||||
|
const [{ default: parse }, { Heap }, { default: table }] = await Promise.all([
|
||||||
|
import('https://cdn.jsdelivr.net/npm/smol-toml@1.2.0/dist/index.mjs'),
|
||||||
|
import('https://cdn.jsdelivr.net/npm/mnemonist@0.39.6/heap.mjs'),
|
||||||
|
import('https://cdn.jsdelivr.net/npm/text-table@0.2.0/+esm')
|
||||||
|
])
|
||||||
|
const c = parse(t)
|
||||||
|
const edges = c.edges
|
||||||
|
const nodes = new Set
|
||||||
|
edges.forEach(({ from, to }) => { nodes.add(from); nodes.add(to) })
|
||||||
|
const parent = {}
|
||||||
|
const rank = {}
|
||||||
|
nodes.forEach(n => { parent[n] = n; rank[n] = 0 })
|
||||||
|
const find = x => {
|
||||||
|
while (parent[x] !== x) {
|
||||||
|
parent[x] = parent[parent[x]]
|
||||||
|
x = parent[x]
|
||||||
|
}
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
const union = (x, y) => {
|
||||||
|
const rx = find(x)
|
||||||
|
const ry = find(y)
|
||||||
|
if (rx === ry) return !1
|
||||||
|
if (rank[rx] < rank[ry]) parent[rx] = ry
|
||||||
|
else if (rank[rx] > rank[ry]) parent[ry] = rx
|
||||||
|
else { parent[ry] = rx; rank[rx]++ }
|
||||||
|
return !0
|
||||||
|
}
|
||||||
|
const heap = new Heap((a, b) => a.weight > b.weight)
|
||||||
|
edges.forEach(e => heap.push(e))
|
||||||
|
const mst = []
|
||||||
|
const target = nodes.size - 1
|
||||||
|
let total = 0
|
||||||
|
while (heap.size && mst.length < target) {
|
||||||
|
const e = heap.pop()
|
||||||
|
if (union(e.from, e.to)) {
|
||||||
|
mst.push([e.from, e.to, String(e.weight)])
|
||||||
|
total += e.weight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { table: table([['From', 'To', 'Weight'], ...mst]), totalWeight: total }
|
||||||
|
}
|
||||||
|
export default computeMST;
|
||||||
|
// Generation time: 116.739s
|
||||||
|
// Result: FAIL
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
async function computeMST(tomlStr) {
|
||||||
|
const [{ parse }, { Heap }, { default: table }] = await Promise.all([
|
||||||
|
import("https://cdn.skypack.dev/smol-toml"),
|
||||||
|
import("https://cdn.skypack.dev/mnemonist/heap"),
|
||||||
|
import("https://cdn.skypack.dev/text-table")
|
||||||
|
]);
|
||||||
|
|
||||||
|
const { edges } = parse(tomlStr), nodes = new Set();
|
||||||
|
const heap = new Heap((a, b) => a.weight - b.weight);
|
||||||
|
|
||||||
|
edges.forEach(e => {
|
||||||
|
heap.push(e);
|
||||||
|
nodes.add(e.from);
|
||||||
|
nodes.add(e.to);
|
||||||
|
});
|
||||||
|
|
||||||
|
const parent = new Map(), rank = new Map();
|
||||||
|
nodes.forEach(n => parent.set(n, n) || rank.set(n, 0));
|
||||||
|
|
||||||
|
const find = i => {
|
||||||
|
while (parent.get(i) !== i) {
|
||||||
|
parent.set(i, parent.get(parent.get(i)));
|
||||||
|
i = parent.get(i);
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
};
|
||||||
|
|
||||||
|
const mst = [['From', 'To', 'Weight']], nCount = nodes.size;
|
||||||
|
let totalWeight = 0;
|
||||||
|
|
||||||
|
while (heap.size() > 0 && mst.length < nCount) {
|
||||||
|
const { from, to, weight } = heap.pop();
|
||||||
|
let rootU = find(from), rootV = find(to);
|
||||||
|
|
||||||
|
if (rootU !== rootV) {
|
||||||
|
if (rank.get(rootU) < rank.get(rootV)) [rootU, rootV] = [rootV, rootU];
|
||||||
|
parent.set(rootV, rootU);
|
||||||
|
if (rank.get(rootU) === rank.get(rootV)) rank.set(rootU, rank.get(rootU) + 1);
|
||||||
|
|
||||||
|
mst.push([from, to, String(weight)]);
|
||||||
|
totalWeight += weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { table: table(mst), totalWeight };
|
||||||
|
}
|
||||||
|
export default computeMST;
|
||||||
|
// Generation time: 2.142s
|
||||||
|
// Result: FAIL
|
||||||
35
tests/12_mst_pipeline/outputs/moonshotai_kimi-k2.6.js
Normal file
35
tests/12_mst_pipeline/outputs/moonshotai_kimi-k2.6.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
const computeMST=async s=>{
|
||||||
|
const[{parse},{Heap},{default:T}]=await Promise.all([
|
||||||
|
import('https://esm.sh/smol-toml'),
|
||||||
|
import('https://esm.sh/mnemonist'),
|
||||||
|
import('https://esm.sh/text-table')
|
||||||
|
]);
|
||||||
|
const E=parse(s).edges||[];
|
||||||
|
const V=[...new Set(E.flatMap(e=>[e.from,e.to]))];
|
||||||
|
const I={},P=[],R=[];
|
||||||
|
V.forEach((v,i)=>{I[v]=i;P[i]=i;R[i]=0});
|
||||||
|
const F=x=>P[x]===x?x:P[x]=F(P[x]);
|
||||||
|
const U=(x,y)=>{
|
||||||
|
let a=F(x),b=F(y);
|
||||||
|
if(a===b)return 0;
|
||||||
|
if(R[a]<R[b])[a,b]=[b,a];
|
||||||
|
P[b]=a;
|
||||||
|
R[a]+=R[a]===R[b];
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
const H=new Heap((a,b)=>a.w-b.w);
|
||||||
|
E.forEach(e=>H.push({u:e.from,v:e.to,w:e.weight}));
|
||||||
|
const M=[];
|
||||||
|
let W=0;
|
||||||
|
while(H.size&&M.length<V.length-1){
|
||||||
|
const c=H.pop();
|
||||||
|
if(U(I[c.u],I[c.v])){
|
||||||
|
M.push([c.u,c.v,String(c.w)]);
|
||||||
|
W+=c.w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return{table:T([['From','To','Weight'],...M]),totalWeight:W};
|
||||||
|
};
|
||||||
|
export default computeMST;
|
||||||
|
// Generation time: 183.408s
|
||||||
|
// Result: PASS
|
||||||
85
tests/12_mst_pipeline/outputs/openai_gpt-5.5 EFF_high.js
Normal file
85
tests/12_mst_pipeline/outputs/openai_gpt-5.5 EFF_high.js
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
const mstDeps = () => mstDeps.p ??= Promise.all([
|
||||||
|
import('https://esm.sh/smol-toml'),
|
||||||
|
import('https://esm.sh/mnemonist/heap'),
|
||||||
|
import('https://esm.sh/text-table')
|
||||||
|
]).then(([toml, heap, text]) => ({
|
||||||
|
parse: toml.parse ?? toml.default?.parse ?? toml.default,
|
||||||
|
Heap: heap.default ?? heap.Heap ?? heap,
|
||||||
|
table: text.default ?? text.table ?? text
|
||||||
|
}));
|
||||||
|
|
||||||
|
class UnionFind {
|
||||||
|
constructor(nodes) {
|
||||||
|
this.p = new Map;
|
||||||
|
this.r = new Map;
|
||||||
|
for (const n of nodes) {
|
||||||
|
this.p.set(n, n);
|
||||||
|
this.r.set(n, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
find(x) {
|
||||||
|
let p = this.p.get(x);
|
||||||
|
if (p !== x) this.p.set(x, p = this.find(p));
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
union(a, b) {
|
||||||
|
let x = this.find(a), y = this.find(b);
|
||||||
|
if (x === y) return false;
|
||||||
|
|
||||||
|
let rx = this.r.get(x), ry = this.r.get(y);
|
||||||
|
if (rx < ry) [x, y] = [y, x], [rx, ry] = [ry, rx];
|
||||||
|
|
||||||
|
this.p.set(y, x);
|
||||||
|
if (rx === ry) this.r.set(x, rx + 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function computeMST(input) {
|
||||||
|
if (typeof input !== 'string') throw new TypeError('Expected a TOML string');
|
||||||
|
|
||||||
|
const {parse, Heap, table} = await mstDeps();
|
||||||
|
const {edges: raw} = parse(input);
|
||||||
|
|
||||||
|
if (!Array.isArray(raw)) throw new TypeError('Expected TOML to contain an edges array');
|
||||||
|
|
||||||
|
const nodes = new Set;
|
||||||
|
const edges = raw.map((e, i) => {
|
||||||
|
const from = e?.from, to = e?.to, weight = Number(e?.weight);
|
||||||
|
|
||||||
|
if (typeof from !== 'string' || typeof to !== 'string' || !Number.isFinite(weight)) {
|
||||||
|
throw new TypeError(`Invalid edge at index ${i}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes.add(from);
|
||||||
|
nodes.add(to);
|
||||||
|
return {from, to, weight, i};
|
||||||
|
});
|
||||||
|
|
||||||
|
const heap = new Heap((a, b) => a.weight - b.weight || a.i - b.i);
|
||||||
|
for (const e of edges) heap.push(e);
|
||||||
|
|
||||||
|
const uf = new UnionFind(nodes);
|
||||||
|
const mst = [];
|
||||||
|
let totalWeight = 0, left = edges.length;
|
||||||
|
|
||||||
|
while (mst.length < nodes.size - 1 && left) {
|
||||||
|
left--;
|
||||||
|
|
||||||
|
const e = heap.pop();
|
||||||
|
if (!uf.union(e.from, e.to)) continue;
|
||||||
|
|
||||||
|
mst.push([e.from, e.to, String(e.weight)]);
|
||||||
|
totalWeight += e.weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
table: table([['From', 'To', 'Weight'], ...mst]),
|
||||||
|
totalWeight
|
||||||
|
};
|
||||||
|
}
|
||||||
|
export default computeMST;
|
||||||
|
// Generation time: 47.382s
|
||||||
|
// Result: PASS
|
||||||
24
tests/1_dijkstra/outputs/deepseek_deepseek-v4-pro.js
Normal file
24
tests/1_dijkstra/outputs/deepseek_deepseek-v4-pro.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
async function findShortestPath(g,s,e){
|
||||||
|
const {default:P}=await import('https://esm.sh/js-priority-queue');
|
||||||
|
const d={};
|
||||||
|
for(let k in g)d[k]=Infinity;
|
||||||
|
d[s]=0;
|
||||||
|
const q=new P({comparator:(a,b)=>a.w-b.w});
|
||||||
|
q.queue({n:s,w:0});
|
||||||
|
while(q.length){
|
||||||
|
const {n,w}=q.dequeue();
|
||||||
|
if(n===e)return w;
|
||||||
|
if(w>d[n])continue;
|
||||||
|
for(const t in g[n]){
|
||||||
|
const w2=w+g[n][t];
|
||||||
|
if(w2<d[t]){
|
||||||
|
d[t]=w2;
|
||||||
|
q.queue({n:t,w:w2});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Infinity
|
||||||
|
}
|
||||||
|
export default findShortestPath;
|
||||||
|
// Generation time: 45.490s
|
||||||
|
// Result: PASS
|
||||||
29
tests/1_dijkstra/outputs/google_gemini-3.1-flash-lite.js
Normal file
29
tests/1_dijkstra/outputs/google_gemini-3.1-flash-lite.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
async function findShortestPath(graph, start, end) {
|
||||||
|
const { PriorityQueue } = await import('https://cdn.skypack.dev/js-priority-queue');
|
||||||
|
const dist = { [start]: 0 };
|
||||||
|
const pq = new PriorityQueue({
|
||||||
|
comparator: (a, b) => a.w - b.w
|
||||||
|
});
|
||||||
|
|
||||||
|
pq.queue({ n: start, w: 0 });
|
||||||
|
|
||||||
|
while (pq.length) {
|
||||||
|
const { n, w } = pq.dequeue();
|
||||||
|
|
||||||
|
if (n === end) return w;
|
||||||
|
if (w > (dist[n] ?? Infinity)) continue;
|
||||||
|
|
||||||
|
for (const [neighbor, weight] of Object.entries(graph[n] || {})) {
|
||||||
|
const newDist = w + weight;
|
||||||
|
if (newDist < (dist[neighbor] ?? Infinity)) {
|
||||||
|
dist[neighbor] = newDist;
|
||||||
|
pq.queue({ n: neighbor, w: newDist });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Infinity;
|
||||||
|
}
|
||||||
|
export default findShortestPath;
|
||||||
|
// Generation time: 1.539s
|
||||||
|
// Result: FAIL
|
||||||
22
tests/1_dijkstra/outputs/moonshotai_kimi-k2.6.js
Normal file
22
tests/1_dijkstra/outputs/moonshotai_kimi-k2.6.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
const findShortestPath = async (g, s, e) => {
|
||||||
|
const { default: P } = await import('https://esm.sh/js-priority-queue');
|
||||||
|
const q = new P({ comparator: (a, b) => a.d - b.d });
|
||||||
|
const dist = { [s]: 0 };
|
||||||
|
q.queue({ u: s, d: 0 });
|
||||||
|
while (q.length) {
|
||||||
|
const { u, d: du } = q.dequeue();
|
||||||
|
if (du > dist[u]) continue;
|
||||||
|
if (u === e) return du;
|
||||||
|
for (const [v, w] of Object.entries(g[u] ?? {})) {
|
||||||
|
const alt = du + w;
|
||||||
|
if (alt < (dist[v] ?? Infinity)) {
|
||||||
|
dist[v] = alt;
|
||||||
|
q.queue({ u: v, d: alt });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dist[e] ?? Infinity;
|
||||||
|
};
|
||||||
|
export default findShortestPath;
|
||||||
|
// Generation time: 152.935s
|
||||||
|
// Result: PASS
|
||||||
43
tests/1_dijkstra/outputs/openai_gpt-5.5 EFF_high.js
Normal file
43
tests/1_dijkstra/outputs/openai_gpt-5.5 EFF_high.js
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
const loadPQ = (() => {
|
||||||
|
let p;
|
||||||
|
|
||||||
|
return () => p ||= import("https://esm.sh/js-priority-queue@0.1.5")
|
||||||
|
.then(m => m.default?.default ?? m.default ?? m.PriorityQueue);
|
||||||
|
})();
|
||||||
|
|
||||||
|
async function findShortestPath(graph, start, end) {
|
||||||
|
const PriorityQueue = await loadPQ();
|
||||||
|
const dist = new Map([[start, 0]]);
|
||||||
|
const q = new PriorityQueue({
|
||||||
|
comparator: (a, b) => a.cost - b.cost
|
||||||
|
});
|
||||||
|
|
||||||
|
q.queue({ node: start, cost: 0 });
|
||||||
|
|
||||||
|
while (q.length) {
|
||||||
|
const { node, cost } = q.dequeue();
|
||||||
|
|
||||||
|
if (cost > dist.get(node)) continue;
|
||||||
|
if (node === end) return cost;
|
||||||
|
|
||||||
|
for (const [next, rawWeight] of Object.entries(graph?.[node] ?? {})) {
|
||||||
|
const weight = Number(rawWeight);
|
||||||
|
|
||||||
|
if (!Number.isFinite(weight) || weight < 0) {
|
||||||
|
throw new RangeError("Edge weights must be finite non-negative numbers");
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextCost = cost + weight;
|
||||||
|
|
||||||
|
if (nextCost < (dist.get(next) ?? Infinity)) {
|
||||||
|
dist.set(next, nextCost);
|
||||||
|
q.queue({ node: next, cost: nextCost });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Infinity;
|
||||||
|
}
|
||||||
|
export default findShortestPath;
|
||||||
|
// Generation time: 55.807s
|
||||||
|
// Result: PASS
|
||||||
25
tests/2_convex_hull/outputs/deepseek_deepseek-v4-pro.js
Normal file
25
tests/2_convex_hull/outputs/deepseek_deepseek-v4-pro.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
const findConvexHull = async (points) => {
|
||||||
|
const _ = await import('https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js');
|
||||||
|
const pts = _.sortBy(_.uniqWith(points, (a, b) => a.x === b.x && a.y === b.y), ['x', 'y']);
|
||||||
|
const n = pts.length;
|
||||||
|
if (n <= 2) return pts;
|
||||||
|
const cross = (o, a, b) => (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
|
||||||
|
const lower = [];
|
||||||
|
for (let i = 0; i < n; i++) {
|
||||||
|
while (lower.length >= 2 && cross(lower[lower.length - 2], lower[lower.length - 1], pts[i]) <= 0)
|
||||||
|
lower.pop();
|
||||||
|
lower.push(pts[i]);
|
||||||
|
}
|
||||||
|
const upper = [];
|
||||||
|
for (let i = n - 1; i >= 0; i--) {
|
||||||
|
while (upper.length >= 2 && cross(upper[upper.length - 2], upper[upper.length - 1], pts[i]) <= 0)
|
||||||
|
upper.pop();
|
||||||
|
upper.push(pts[i]);
|
||||||
|
}
|
||||||
|
lower.pop();
|
||||||
|
upper.pop();
|
||||||
|
return lower.concat(upper);
|
||||||
|
};
|
||||||
|
export default findConvexHull;
|
||||||
|
// Generation time: 21.237s
|
||||||
|
// Result: FAIL
|
||||||
30
tests/2_convex_hull/outputs/google_gemini-3.1-flash-lite.js
Normal file
30
tests/2_convex_hull/outputs/google_gemini-3.1-flash-lite.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
async function findConvexHull(pts) {
|
||||||
|
const { sortBy, uniqWith, isEqual } = await import('https://cdn.skypack.dev/lodash');
|
||||||
|
|
||||||
|
const sorted = sortBy(uniqWith(pts, isEqual), ['x', 'y']);
|
||||||
|
if (sorted.length <= 2) return sorted;
|
||||||
|
|
||||||
|
const crossProduct = (a, b, c) => (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
|
||||||
|
|
||||||
|
const build = (arr) => {
|
||||||
|
const hull = [];
|
||||||
|
for (const p of arr) {
|
||||||
|
while (hull.length >= 2 && crossProduct(hull[hull.length - 2], hull[hull.length - 1], p) <= 0) {
|
||||||
|
hull.pop();
|
||||||
|
}
|
||||||
|
hull.push(p);
|
||||||
|
}
|
||||||
|
return hull;
|
||||||
|
};
|
||||||
|
|
||||||
|
const lower = build(sorted);
|
||||||
|
const upper = build([...sorted].reverse());
|
||||||
|
|
||||||
|
lower.pop();
|
||||||
|
upper.pop();
|
||||||
|
|
||||||
|
return lower.concat(upper);
|
||||||
|
}
|
||||||
|
export default findConvexHull;
|
||||||
|
// Generation time: 1.515s
|
||||||
|
// Result: PASS
|
||||||
24
tests/2_convex_hull/outputs/moonshotai_kimi-k2.6.js
Normal file
24
tests/2_convex_hull/outputs/moonshotai_kimi-k2.6.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
const findConvexHull = async (pts) => {
|
||||||
|
const { sortBy, uniqBy } = await import("https://esm.sh/lodash-es@4.17.21"),
|
||||||
|
u = uniqBy(pts, p => `${p.x},${p.y}`),
|
||||||
|
s = sortBy(u, ["x", "y"]),
|
||||||
|
n = s.length,
|
||||||
|
c = (a, b, d) => (b.x - a.x) * (d.y - a.y) - (b.y - a.y) * (d.x - a.x),
|
||||||
|
l = [],
|
||||||
|
h = [];
|
||||||
|
if (n < 3) return s;
|
||||||
|
for (let i = 0; i < n; i++) {
|
||||||
|
const p = s[i];
|
||||||
|
while (l.length > 1 && c(l[l.length - 2], l[l.length - 1], p) <= 0) l.pop();
|
||||||
|
l.push(p);
|
||||||
|
}
|
||||||
|
for (let i = n; i--; ) {
|
||||||
|
const p = s[i];
|
||||||
|
while (h.length > 1 && c(h[h.length - 2], h[h.length - 1], p) <= 0) h.pop();
|
||||||
|
h.push(p);
|
||||||
|
}
|
||||||
|
return [...l.slice(0, -1), ...h.slice(0, -1)];
|
||||||
|
};
|
||||||
|
export default findConvexHull;
|
||||||
|
// Generation time: 116.732s
|
||||||
|
// Result: PASS
|
||||||
34
tests/2_convex_hull/outputs/openai_gpt-5.5 EFF_high.js
Normal file
34
tests/2_convex_hull/outputs/openai_gpt-5.5 EFF_high.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
const findConvexHull = async points => {
|
||||||
|
const { sortBy, uniqBy } = await import(
|
||||||
|
"https://cdn.jsdelivr.net/npm/lodash-es@4.17.21/lodash.js"
|
||||||
|
)
|
||||||
|
|
||||||
|
const pts = uniqBy(
|
||||||
|
sortBy(points, ["x", "y"]),
|
||||||
|
p => `${p.x}\u0000${p.y}`
|
||||||
|
)
|
||||||
|
|
||||||
|
if (pts.length < 2) return pts
|
||||||
|
|
||||||
|
const cross = (a, b, c) =>
|
||||||
|
(b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x)
|
||||||
|
|
||||||
|
const half = arr => {
|
||||||
|
const h = []
|
||||||
|
|
||||||
|
for (const p of arr) {
|
||||||
|
while (h.length > 1 && cross(h.at(-2), h.at(-1), p) <= 0) h.pop()
|
||||||
|
h.push(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
...half(pts).slice(0, -1),
|
||||||
|
...half([...pts].reverse()).slice(0, -1)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
export default findConvexHull;
|
||||||
|
// Generation time: 14.673s
|
||||||
|
// Result: PASS
|
||||||
42
tests/3_signal_pipeline/outputs/deepseek_deepseek-v4-pro.js
Normal file
42
tests/3_signal_pipeline/outputs/deepseek_deepseek-v4-pro.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
async function analyzeSignal(y) {
|
||||||
|
const [Y, M, Nd, Fft, P] = await Promise.all([
|
||||||
|
import('https://esm.run/js-yaml@4.1.0').then(m => m.default),
|
||||||
|
import('https://esm.run/mathjs@11.8.0').then(m => m.default),
|
||||||
|
import('https://esm.run/ndarray@1.0.19').then(m => m.default),
|
||||||
|
import('https://esm.run/ndarray-fft@1.0.3').then(m => m.default),
|
||||||
|
import('https://esm.run/dompurify@3.0.5').then(m => m.default)
|
||||||
|
]);
|
||||||
|
const cfg = Y.load(y),
|
||||||
|
sr = cfg.sampleRate,
|
||||||
|
d = cfg.duration,
|
||||||
|
comps = cfg.components,
|
||||||
|
N = sr * d,
|
||||||
|
sig = Array.from({ length: N }, (_, i) => {
|
||||||
|
const t = i / sr;
|
||||||
|
return comps.reduce((s, c) => s + c.amplitude * M.sin(2 * M.pi * c.frequency * t), 0);
|
||||||
|
}),
|
||||||
|
real = Nd(new Float64Array(sig), [N]),
|
||||||
|
imag = Nd(new Float64Array(N), [N]);
|
||||||
|
Fft(1, real, imag);
|
||||||
|
const half = N / 2,
|
||||||
|
peaks = [];
|
||||||
|
for (let k = 0; k <= half; k++) {
|
||||||
|
const re = real.get(k),
|
||||||
|
im = imag.get(k),
|
||||||
|
mag = M.sqrt(re * re + im * im) / half;
|
||||||
|
if (mag > 0.1) peaks.push({ f: Math.round(k * sr / N), m: Math.round(mag * 1e2) / 1e2 });
|
||||||
|
}
|
||||||
|
peaks.sort((a, b) => b.m - a.m);
|
||||||
|
let h = '<table><tr><th>Frequency (Hz)</th><th>Magnitude</th></tr>';
|
||||||
|
for (const p of peaks) h += `<tr><td>${p.f}</td><td>${p.m}</td></tr>`;
|
||||||
|
h += '</table>';
|
||||||
|
const sH = P.sanitize(h);
|
||||||
|
return {
|
||||||
|
peaks: peaks.map(p => ({ frequencyHz: p.f, magnitude: p.m })),
|
||||||
|
html: sH,
|
||||||
|
signalLength: N
|
||||||
|
};
|
||||||
|
}
|
||||||
|
export default analyzeSignal;
|
||||||
|
// Generation time: 102.963s
|
||||||
|
// Result: FAIL
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
async function analyzeSignal(yamlStr) {
|
||||||
|
const [yaml, math, { default: ndarray }, fft, { sanitize }] = await Promise.all([
|
||||||
|
import('https://esm.sh/js-yaml'),
|
||||||
|
import('https://esm.sh/mathjs'),
|
||||||
|
import('https://esm.sh/ndarray'),
|
||||||
|
import('https://esm.sh/ndarray-fft'),
|
||||||
|
import('https://esm.sh/dompurify')
|
||||||
|
]);
|
||||||
|
|
||||||
|
const cfg = yaml.load(yamlStr);
|
||||||
|
const N = cfg.sampleRate * cfg.duration;
|
||||||
|
const real = ndarray(new Float64Array(N));
|
||||||
|
const imag = ndarray(new Float64Array(N));
|
||||||
|
|
||||||
|
for (let i = 0; i < N; i++) {
|
||||||
|
const t = i / cfg.sampleRate;
|
||||||
|
const v = cfg.components.reduce((acc, c) =>
|
||||||
|
acc + c.amplitude * math.sin(2 * math.pi * c.frequency * t), 0);
|
||||||
|
real.set(i, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
fft(1, real, imag);
|
||||||
|
|
||||||
|
const peaks = [];
|
||||||
|
for (let k = 0; k <= N / 2; k++) {
|
||||||
|
const mag = math.sqrt(real.get(k) ** 2 + imag.get(k) ** 2) / (N / 2);
|
||||||
|
if (mag > 0.1) peaks.push({ frequencyHz: Math.round(k * cfg.sampleRate / N), magnitude: +mag.toFixed(2) });
|
||||||
|
}
|
||||||
|
|
||||||
|
peaks.sort((a, b) => b.magnitude - a.magnitude);
|
||||||
|
|
||||||
|
let html = '<table><tr><th>Frequency (Hz)</th><th>Magnitude</th></tr>';
|
||||||
|
peaks.forEach(p => html += `<tr><td>${p.frequencyHz}</td><td>${p.magnitude}</td></tr>`);
|
||||||
|
html += '</table>';
|
||||||
|
|
||||||
|
return { peaks, html: sanitize(html), signalLength: N };
|
||||||
|
}
|
||||||
|
export default analyzeSignal;
|
||||||
|
// Generation time: 1.769s
|
||||||
|
// Result: FAIL
|
||||||
459
tests/3_signal_pipeline/outputs/moonshotai_kimi-k2.6.js
Normal file
459
tests/3_signal_pipeline/outputs/moonshotai_kimi-k2.6.js
Normal file
@@ -0,0 +1,459 @@
|
|||||||
|
```html
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Signal Processing Pipeline</title>
|
||||||
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&family=Inter:wght@400;600;800&display=swap" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: 'Inter', sans-serif;
|
||||||
|
background-color: #0f172a; /* Slate 900 */
|
||||||
|
color: #e2e8f0; /* Slate 200 */
|
||||||
|
}
|
||||||
|
.mono {
|
||||||
|
font-family: 'JetBrains Mono', monospace;
|
||||||
|
}
|
||||||
|
.glass-panel {
|
||||||
|
background: rgba(30, 41, 59, 0.7);
|
||||||
|
backdrop-filter: blur(12px);
|
||||||
|
border: 1px solid rgba(148, 163, 184, 0.1);
|
||||||
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
.input-focus:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #38bdf8;
|
||||||
|
box-shadow: 0 0 0 2px rgba(56, 189, 248, 0.2);
|
||||||
|
}
|
||||||
|
/* Custom Scrollbar */
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: #1e293b;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: #475569;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: #64748b;
|
||||||
|
}
|
||||||
|
.canvas-container {
|
||||||
|
position: relative;
|
||||||
|
height: 250px;
|
||||||
|
width: 100%;
|
||||||
|
background: #020617;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid #1e293b;
|
||||||
|
}
|
||||||
|
canvas {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.loader {
|
||||||
|
border: 3px solid rgba(255,255,255,0.1);
|
||||||
|
border-radius: 50%;
|
||||||
|
border-top: 3px solid #38bdf8;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
-webkit-animation: spin 1s linear infinite; /* Safari */
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
}
|
||||||
|
@keyframes spin {
|
||||||
|
0% { transform: rotate(0deg); }
|
||||||
|
100% { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body class="min-h-screen flex flex-col">
|
||||||
|
|
||||||
|
<!-- Header -->
|
||||||
|
<header class="border-b border-slate-800 bg-slate-900/80 sticky top-0 z-50 backdrop-blur-md">
|
||||||
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-16 flex items-center justify-between">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<div class="w-8 h-8 bg-cyan-500 rounded flex items-center justify-center shadow-[0_0_15px_rgba(6,182,212,0.5)]">
|
||||||
|
<svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path></svg>
|
||||||
|
</div>
|
||||||
|
<h1 class="text-xl font-bold tracking-tight text-white">Signal<span class="text-cyan-400">Forge</span> <span class="text-xs font-normal text-slate-500 ml-2 border border-slate-700 px-2 py-0.5 rounded-full">FFT Processor</span></h1>
|
||||||
|
</div>
|
||||||
|
<div class="text-xs text-slate-400 font-mono hidden sm:block">Dynamic Import Pipeline: js-yaml → mathjs → ndarray-fft → DOMPurify</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!-- Main Content -->
|
||||||
|
<main class="flex-grow p-4 sm:p-6 lg:p-8 max-w-7xl mx-auto w-full grid grid-cols-1 lg:grid-cols-12 gap-6">
|
||||||
|
|
||||||
|
<!-- Left Column: Controls -->
|
||||||
|
<div class="lg:col-span-4 flex flex-col gap-6">
|
||||||
|
|
||||||
|
<!-- Input Panel -->
|
||||||
|
<div class="glass-panel rounded-xl p-6 flex flex-col gap-4">
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<h2 class="text-lg font-semibold text-white flex items-center gap-2">
|
||||||
|
<svg class="w-4 h-4 text-cyan-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"></path></svg>
|
||||||
|
Signal Config (YAML)
|
||||||
|
</h2>
|
||||||
|
<button id="resetBtn" class="text-xs text-slate-400 hover:text-white transition-colors">Reset Default</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<textarea id="yamlInput" class="mono text-xs bg-slate-950 text-emerald-400 p-4 rounded-lg border border-slate-800 h-64 resize-none input-focus leading-relaxed" spellcheck="false"></textarea>
|
||||||
|
|
||||||
|
<div class="flex gap-3 mt-2">
|
||||||
|
<button id="runBtn" class="flex-1 bg-cyan-600 hover:bg-cyan-500 text-white font-semibold py-2 px-4 rounded-lg transition-all shadow-lg shadow-cyan-500/20 flex items-center justify-center gap-2 active:scale-95">
|
||||||
|
<span>Process Signal</span>
|
||||||
|
<div id="btnLoader" class="loader hidden"></div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="errorContainer" class="hidden bg-red-500/10 border border-red-500/30 text-red-400 text-xs p-3 rounded-lg">
|
||||||
|
<span class="font-bold">Error:</span> <span id="errorMsg"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Info Panel -->
|
||||||
|
<div class="glass-panel rounded-xl p-6">
|
||||||
|
<h3 class="text-sm font-semibold text-slate-300 mb-3">Pipeline Status</h3>
|
||||||
|
<ul class="space-y-3 text-xs text-slate-400">
|
||||||
|
<li class="flex items-center gap-2" id="status-yaml">
|
||||||
|
<span class="w-2 h-2 rounded-full bg-slate-600"></span> js-yaml (Parser)
|
||||||
|
</li>
|
||||||
|
<li class="flex items-center gap-2" id="status-math">
|
||||||
|
<span class="w-2 h-2 rounded-full bg-slate-600"></span> mathjs (Synthesis)
|
||||||
|
</li>
|
||||||
|
<li class="flex items-center gap-2" id="status-fft">
|
||||||
|
<span class="w-2 h-2 rounded-full bg-slate-600"></span> ndarray-fft (Analysis)
|
||||||
|
</li>
|
||||||
|
<li class="flex items-center gap-2" id="status-dom">
|
||||||
|
<span class="w-2 h-2 rounded-full bg-slate-600"></span> DOMPurify (Sanitization)
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Right Column: Visualization & Results -->
|
||||||
|
<div class="lg:col-span-8 flex flex-col gap-6">
|
||||||
|
|
||||||
|
<!-- Charts -->
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
|
<!-- Time Domain -->
|
||||||
|
<div class="glass-panel p-4 rounded-xl">
|
||||||
|
<div class="flex justify-between items-end mb-3">
|
||||||
|
<h3 class="text-sm font-semibold text-slate-300">Time Domain</h3>
|
||||||
|
<span class="text-xs text-slate-500 mono">signal[i]</span>
|
||||||
|
</div>
|
||||||
|
<div class="canvas-container">
|
||||||
|
<canvas id="timeCanvas"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Frequency Domain -->
|
||||||
|
<div class="glass-panel p-4 rounded-xl">
|
||||||
|
<div class="flex justify-between items-end mb-3">
|
||||||
|
<h3 class="text-sm font-semibold text-slate-300">Frequency Domain</h3>
|
||||||
|
<span class="text-xs text-slate-500 mono">|X(k)|</span>
|
||||||
|
</div>
|
||||||
|
<div class="canvas-container">
|
||||||
|
<canvas id="freqCanvas"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Results Table -->
|
||||||
|
<div class="glass-panel rounded-xl overflow-hidden flex flex-col h-full">
|
||||||
|
<div class="p-4 border-b border-slate-800 bg-slate-800/50 flex justify-between items-center">
|
||||||
|
<h3 class="text-sm font-semibold text-white">Dominant Frequencies</h3>
|
||||||
|
<span class="text-xs text-slate-500" id="signalLengthDisplay">N = 0</span>
|
||||||
|
</div>
|
||||||
|
<div class="overflow-x-auto">
|
||||||
|
<div id="htmlOutput" class="p-0">
|
||||||
|
<!-- Sanitized HTML Table will be injected here -->
|
||||||
|
<div class="p-8 text-center text-slate-500 text-sm italic">Run the pipeline to see results...</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// --- Configuration & State ---
|
||||||
|
const defaultYaml = `sampleRate: 64
|
||||||
|
duration: 1
|
||||||
|
components:
|
||||||
|
- frequency: 5
|
||||||
|
amplitude: 1.0
|
||||||
|
- frequency: 12
|
||||||
|
amplitude: 0.5`;
|
||||||
|
|
||||||
|
const yamlInput = document.getElementById('yamlInput');
|
||||||
|
const runBtn = document.getElementById('runBtn');
|
||||||
|
const resetBtn = document.getElementById('resetBtn');
|
||||||
|
const btnLoader = document.getElementById('btnLoader');
|
||||||
|
const errorContainer = document.getElementById('errorContainer');
|
||||||
|
const errorMsg = document.getElementById('errorMsg');
|
||||||
|
const htmlOutput = document.getElementById('htmlOutput');
|
||||||
|
const signalLengthDisplay = document.getElementById('signalLengthDisplay');
|
||||||
|
|
||||||
|
const timeCanvas = document.getElementById('timeCanvas');
|
||||||
|
const freqCanvas = document.getElementById('freqCanvas');
|
||||||
|
const timeCtx = timeCanvas.getContext('2d');
|
||||||
|
const freqCtx = freqCanvas.getContext('2d');
|
||||||
|
|
||||||
|
// Status Indicators
|
||||||
|
const statusEls = {
|
||||||
|
yaml: document.getElementById('status-yaml').firstElementChild,
|
||||||
|
math: document.getElementById('status-math').firstElementChild,
|
||||||
|
fft: document.getElementById('status-fft').firstElementChild,
|
||||||
|
dom: document.getElementById('status-dom').firstElementChild,
|
||||||
|
};
|
||||||
|
|
||||||
|
yamlInput.value = defaultYaml;
|
||||||
|
|
||||||
|
// --- Visualization Helpers ---
|
||||||
|
function resizeCanvas(canvas) {
|
||||||
|
const parent = canvas.parentElement;
|
||||||
|
canvas.width = parent.clientWidth;
|
||||||
|
canvas.height = parent.clientHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawTimeDomain(signal) {
|
||||||
|
resizeCanvas(timeCanvas);
|
||||||
|
const w = timeCanvas.width;
|
||||||
|
const h = timeCanvas.height;
|
||||||
|
timeCtx.clearRect(0, 0, w, h);
|
||||||
|
|
||||||
|
// Grid
|
||||||
|
timeCtx.strokeStyle = '#1e293b';
|
||||||
|
timeCtx.lineWidth = 1;
|
||||||
|
timeCtx.beginPath();
|
||||||
|
timeCtx.moveTo(0, h/2);
|
||||||
|
timeCtx.lineTo(w, h/2);
|
||||||
|
timeCtx.stroke();
|
||||||
|
|
||||||
|
// Signal
|
||||||
|
timeCtx.strokeStyle = '#38bdf8'; // Cyan 400
|
||||||
|
timeCtx.lineWidth = 2;
|
||||||
|
timeCtx.beginPath();
|
||||||
|
|
||||||
|
const step = w / signal.length;
|
||||||
|
const amp = h / 2.5; // Scale factor
|
||||||
|
|
||||||
|
for(let i=0; i<signal.length; i++) {
|
||||||
|
const x = i * step;
|
||||||
|
const y = (h/2) - (signal[i] * amp);
|
||||||
|
if(i===0) timeCtx.moveTo(x, y);
|
||||||
|
else timeCtx.lineTo(x, y);
|
||||||
|
}
|
||||||
|
timeCtx.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawFrequencyDomain(magnitude) {
|
||||||
|
resizeCanvas(freqCanvas);
|
||||||
|
const w = freqCanvas.width;
|
||||||
|
const h = freqCanvas.height;
|
||||||
|
freqCtx.clearRect(0, 0, w, h);
|
||||||
|
|
||||||
|
// Grid
|
||||||
|
freqCtx.strokeStyle = '#1e293b';
|
||||||
|
freqCtx.lineWidth = 1;
|
||||||
|
freqCtx.beginPath();
|
||||||
|
freqCtx.moveTo(0, h);
|
||||||
|
freqCtx.lineTo(w, h);
|
||||||
|
freqCtx.stroke();
|
||||||
|
|
||||||
|
// Bars
|
||||||
|
const barWidth = (w / magnitude.length) * 0.8;
|
||||||
|
const gap = (w / magnitude.length) * 0.2;
|
||||||
|
|
||||||
|
for(let i=0; i<magnitude.length; i++) {
|
||||||
|
const val = magnitude[i];
|
||||||
|
const barH = Math.min(h, val * (h * 0.9)); // Scale to fit
|
||||||
|
const x = i * (barWidth + gap);
|
||||||
|
const y = h - barH;
|
||||||
|
|
||||||
|
// Color based on magnitude intensity
|
||||||
|
const intensity = Math.min(255, Math.floor(val * 500));
|
||||||
|
freqCtx.fillStyle = `rgb(${56 + intensity/2}, ${189}, ${248})`; // Base cyan + glow
|
||||||
|
|
||||||
|
// If peak is significant, highlight
|
||||||
|
if(val > 0.1) {
|
||||||
|
freqCtx.fillStyle = '#22d3ee'; // Cyan 400
|
||||||
|
freqCtx.shadowColor = '#06b6d4';
|
||||||
|
freqCtx.shadowBlur = 10;
|
||||||
|
} else {
|
||||||
|
freqCtx.shadowBlur = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
freqCtx.fillRect(x, y, barWidth, barH);
|
||||||
|
}
|
||||||
|
freqCtx.shadowBlur = 0; // Reset
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Core Logic (The Production-Ready Async Function) ---
|
||||||
|
|
||||||
|
async function analyzeSignal(yamlString) {
|
||||||
|
// 1. Dynamic Imports (Simulating CDN loads with skypack/polyfill for robustness in this environment)
|
||||||
|
// Note: In a real build, these would be bare imports handled by bundler,
|
||||||
|
// or full URLs if left as dynamic strings.
|
||||||
|
// To ensure stability in this specific "No-Build" output, we use esm.sh which is highly reliable for raw HTML.
|
||||||
|
|
||||||
|
const setStatus = (key, active) => {
|
||||||
|
statusEls[key].className = `w-2 h-2 rounded-full ${active ? 'bg-cyan-400 shadow-[0_0_8px_rgba(34,211,238,0.8)]' : 'bg-slate-600'}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Reset status
|
||||||
|
Object.keys(statusEls).forEach(k => setStatus(k, false));
|
||||||
|
|
||||||
|
// Import Step
|
||||||
|
setStatus('yaml', true);
|
||||||
|
const yaml = await import('https://cdn.skypack.dev/js-yaml');
|
||||||
|
setStatus('yaml', false);
|
||||||
|
|
||||||
|
setStatus('math', true);
|
||||||
|
const math = await import('https://cdn.skypack.dev/mathjs');
|
||||||
|
setStatus('math', false);
|
||||||
|
|
||||||
|
setStatus('fft', true);
|
||||||
|
const ndarray = (await import('https://cdn.skypack.dev/ndarray')).default;
|
||||||
|
const fft = (await import('https://cdn.skypack.dev/ndarray-fft')).default;
|
||||||
|
setStatus('fft', false);
|
||||||
|
|
||||||
|
setStatus('dom', true);
|
||||||
|
const DOMPurify = (await import('https://cdn.skypack.dev/dompurify')).default;
|
||||||
|
setStatus('dom', false);
|
||||||
|
|
||||||
|
// 2. Parse YAML
|
||||||
|
const config = yaml.load(yamlString);
|
||||||
|
|
||||||
|
const N = config.sampleRate * config.duration;
|
||||||
|
const signal = new Array(N).fill(0);
|
||||||
|
|
||||||
|
// 3. Generate Signal
|
||||||
|
for (let i = 0; i < N; i++) {
|
||||||
|
const t = i / config.sampleRate;
|
||||||
|
let sum = 0;
|
||||||
|
for (const comp of config.components) {
|
||||||
|
sum += comp.amplitude * math.sin(2 * math.pi * comp.frequency * t);
|
||||||
|
}
|
||||||
|
signal[i] = sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Prepare FFT
|
||||||
|
const real = ndarray(new Float64Array(signal));
|
||||||
|
const imag = ndarray(new Float64Array(N).fill(0));
|
||||||
|
|
||||||
|
// 5. Execute FFT
|
||||||
|
fft(1, real, imag);
|
||||||
|
|
||||||
|
// 6. Compute Magnitude Spectrum
|
||||||
|
const halfN = N / 2;
|
||||||
|
const magnitude = new Array(halfN + 1);
|
||||||
|
for (let k = 0; k <= halfN; k++) {
|
||||||
|
const r = real.get(k);
|
||||||
|
const im = imag.get(k);
|
||||||
|
magnitude[k] = math.sqrt(r * r + im * im) / halfN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7. Find Dominant Frequencies
|
||||||
|
const peaks = [];
|
||||||
|
for (let k = 0; k <= halfN; k++) {
|
||||||
|
if (magnitude[k] > 0.1) {
|
||||||
|
const freqHz = Math.round(k * config.sampleRate / N);
|
||||||
|
const magVal = Math.round(magnitude[k] * 100) / 100;
|
||||||
|
peaks.push({ frequencyHz: freqHz, magnitude: magVal });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort by magnitude descending
|
||||||
|
peaks.sort((a, b) => b.magnitude - a.magnitude);
|
||||||
|
|
||||||
|
// 8. Build HTML Table
|
||||||
|
let html = `<table class="w-full text-sm text-left text-slate-300"><thead class="text-xs text-slate-400 uppercase bg-slate-800/50"><tr><th scope="col" class="px-6 py-3">Frequency (Hz)</th><th scope="col" class="px-6 py-3">Magnitude</th></tr></thead><tbody>`;
|
||||||
|
|
||||||
|
if (peaks.length === 0) {
|
||||||
|
html += `<tr class="bg-slate-800/20 border-b border-slate-800"><td colspan="2" class="px-6 py-4 text-center italic text-slate-500">No dominant frequencies detected (>0.1)</td></tr>`;
|
||||||
|
} else {
|
||||||
|
peaks.forEach((p, idx) => {
|
||||||
|
const rowClass = idx % 2 === 0 ? 'bg-slate-800/20' : 'bg-transparent';
|
||||||
|
html += `<tr class="${rowClass} border-b border-slate-800 hover:bg-slate-700/30 transition-colors"><td class="px-6 py-4 font-medium text-white">${p.frequencyHz}</td><td class="px-6 py-4 text-cyan-400 font-mono">${p.magnitude}</td></tr>`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
html += `</tbody></table>`;
|
||||||
|
|
||||||
|
// 9. Sanitize
|
||||||
|
const sanitizedHTML = DOMPurify.sanitize(html, {
|
||||||
|
ALLOWED_TAGS: ['table', 'thead', 'tbody', 'tr', 'th', 'td'],
|
||||||
|
ALLOWED_ATTR: ['class', 'scope', 'colspan']
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
peaks,
|
||||||
|
html: sanitizedHTML,
|
||||||
|
signalLength: N,
|
||||||
|
rawSignal: signal,
|
||||||
|
rawMagnitude: magnitude
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- UI Interaction ---
|
||||||
|
|
||||||
|
runBtn.addEventListener('click', async () => {
|
||||||
|
// UI Loading State
|
||||||
|
runBtn.disabled = true;
|
||||||
|
btnLoader.classList.remove('hidden');
|
||||||
|
errorContainer.classList.add('hidden');
|
||||||
|
htmlOutput.innerHTML = '<div class="p-8 flex justify-center"><div class="loader"></div></div>';
|
||||||
|
|
||||||
|
// Clear canvases
|
||||||
|
timeCtx.clearRect(0,0,timeCanvas.width, timeCanvas.height);
|
||||||
|
freqCtx.clearRect(0,0,freqCanvas.width, freqCanvas.height);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await analyzeSignal(yamlInput.value);
|
||||||
|
|
||||||
|
// Update UI
|
||||||
|
htmlOutput.innerHTML = result.html;
|
||||||
|
signalLengthDisplay.textContent = `N = ${result.signalLength}`;
|
||||||
|
|
||||||
|
// Draw Charts
|
||||||
|
drawTimeDomain(result.rawSignal);
|
||||||
|
drawFrequencyDomain(result.rawMagnitude);
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
errorContainer.classList.remove('hidden');
|
||||||
|
errorMsg.textContent = err.message;
|
||||||
|
htmlOutput.innerHTML = '<div class="p-8 text-center text-slate-500 text-sm italic">Error processing signal.</div>';
|
||||||
|
} finally {
|
||||||
|
runBtn.disabled = false;
|
||||||
|
btnLoader.classList.add('hidden');
|
||||||
|
// Reset status dots
|
||||||
|
Object.keys(statusEls).forEach(k => statusEls[k].className = 'w-2 h-2 rounded-full bg-slate-600');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
resetBtn.addEventListener('click', () => {
|
||||||
|
yamlInput.value = defaultYaml;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initial resize
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
// Re-draw if we have data? For now just resize canvases
|
||||||
|
resizeCanvas(timeCanvas);
|
||||||
|
resizeCanvas(freqCanvas);
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
export default analyzeSignal;
|
||||||
|
// Generation time: 141.385s
|
||||||
|
// Result: FAIL
|
||||||
76
tests/3_signal_pipeline/outputs/openai_gpt-5.5 EFF_high.js
Normal file
76
tests/3_signal_pipeline/outputs/openai_gpt-5.5 EFF_high.js
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
async function analyzeSignal(yamlString) {
|
||||||
|
const [
|
||||||
|
yamlMod,
|
||||||
|
math,
|
||||||
|
ndarrayMod,
|
||||||
|
fftMod,
|
||||||
|
purifyMod
|
||||||
|
] = await Promise.all([
|
||||||
|
import("https://cdn.jsdelivr.net/npm/js-yaml@4.1.0/+esm"),
|
||||||
|
import("https://cdn.jsdelivr.net/npm/mathjs@13.2.0/+esm"),
|
||||||
|
import("https://cdn.jsdelivr.net/npm/ndarray@1.0.19/+esm"),
|
||||||
|
import("https://cdn.jsdelivr.net/npm/ndarray-fft@1.0.3/+esm"),
|
||||||
|
import("https://cdn.jsdelivr.net/npm/dompurify@3.1.6/+esm")
|
||||||
|
]);
|
||||||
|
|
||||||
|
const yaml = yamlMod.default || yamlMod;
|
||||||
|
const ndarray = ndarrayMod.default || ndarrayMod;
|
||||||
|
const fft = fftMod.default || fftMod;
|
||||||
|
const DOMPurify = purifyMod.default || purifyMod;
|
||||||
|
|
||||||
|
const cfg = yaml.load(yamlString);
|
||||||
|
const sampleRate = Number(cfg.sampleRate);
|
||||||
|
const duration = Number(cfg.duration);
|
||||||
|
const components = Array.isArray(cfg.components) ? cfg.components : [];
|
||||||
|
const N = Math.max(0, Math.floor(sampleRate * duration));
|
||||||
|
|
||||||
|
if (!Number.isFinite(sampleRate) || sampleRate <= 0) throw new Error("Invalid sampleRate");
|
||||||
|
if (!Number.isFinite(duration) || duration <= 0) throw new Error("Invalid duration");
|
||||||
|
if (!N) throw new Error("Signal length must be greater than zero");
|
||||||
|
|
||||||
|
const signal = Float64Array.from({ length: N }, (_, i) => {
|
||||||
|
const t = i / sampleRate;
|
||||||
|
|
||||||
|
return components.reduce((sum, c) => {
|
||||||
|
const a = Number(c.amplitude);
|
||||||
|
const f = Number(c.frequency);
|
||||||
|
|
||||||
|
return Number.isFinite(a) && Number.isFinite(f)
|
||||||
|
? sum + a * math.sin(2 * math.pi * f * t)
|
||||||
|
: sum;
|
||||||
|
}, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
const real = ndarray(signal.slice(), [N]);
|
||||||
|
const imag = ndarray(new Float64Array(N), [N]);
|
||||||
|
|
||||||
|
fft(1, real, imag);
|
||||||
|
|
||||||
|
const peaks = Array.from({ length: Math.floor(N / 2) + 1 }, (_, k) => {
|
||||||
|
const re = real.get(k);
|
||||||
|
const im = imag.get(k);
|
||||||
|
const magnitude = math.sqrt(re ** 2 + im ** 2) / (N / 2);
|
||||||
|
|
||||||
|
return {
|
||||||
|
frequencyHz: Math.round(k * sampleRate / N),
|
||||||
|
magnitude: Math.round(magnitude * 100) / 100,
|
||||||
|
rawMagnitude: magnitude
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.filter(p => p.rawMagnitude > 0.1)
|
||||||
|
.sort((a, b) => b.rawMagnitude - a.rawMagnitude)
|
||||||
|
.map(({ frequencyHz, magnitude }) => ({ frequencyHz, magnitude }));
|
||||||
|
|
||||||
|
const rows = peaks
|
||||||
|
.map(p => `<tr><td>${p.frequencyHz}</td><td>${p.magnitude}</td></tr>`)
|
||||||
|
.join("");
|
||||||
|
|
||||||
|
const html = DOMPurify.sanitize(
|
||||||
|
`<table><tr><th>Frequency (Hz)</th><th>Magnitude</th></tr>${rows}</table>`
|
||||||
|
);
|
||||||
|
|
||||||
|
return { peaks, html, signalLength: N };
|
||||||
|
}
|
||||||
|
export default analyzeSignal;
|
||||||
|
// Generation time: 16.732s
|
||||||
|
// Result: PASS
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
async function hexchain(t){
|
||||||
|
const [T,S,SS,A,B,P]=await Promise.all([
|
||||||
|
import('smol-toml'),
|
||||||
|
import('seedrandom'),
|
||||||
|
import('simple-statistics'),
|
||||||
|
import('ajv'),
|
||||||
|
import('text-table'),
|
||||||
|
import('dompurify')
|
||||||
|
]);
|
||||||
|
const c=T.parse(t);
|
||||||
|
const Ajv=A.default||A,ajv=new Ajv;
|
||||||
|
const schema={
|
||||||
|
type:'object',
|
||||||
|
required:['seed','count','label'],
|
||||||
|
properties:{
|
||||||
|
seed:{type:'string'},
|
||||||
|
count:{type:'integer',minimum:1,maximum:10000},
|
||||||
|
label:{type:'string',minLength:1}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const v=ajv.compile(schema);
|
||||||
|
if(!v(c))return{valid:false,errors:ajv.errorsText(v.errors)};
|
||||||
|
const rng=new (S.default||S)(c.seed),
|
||||||
|
arr=Array.from({length:c.count},rng);
|
||||||
|
const ss=SS.default||SS;
|
||||||
|
let m=ss.mean(arr),d=ss.standardDeviation(arr),md=ss.median(arr);
|
||||||
|
m=+m.toFixed(6);
|
||||||
|
d=+d.toFixed(6);
|
||||||
|
md=+md.toFixed(6);
|
||||||
|
const tbl=(B.default||B)([
|
||||||
|
['Stat','Value'],
|
||||||
|
['mean',String(m)],
|
||||||
|
['stddev',String(d)],
|
||||||
|
['median',String(md)]
|
||||||
|
]);
|
||||||
|
const purify=P.default||P,
|
||||||
|
h=purify.sanitize(`<pre class="stats">${tbl}</pre>`);
|
||||||
|
return{
|
||||||
|
valid:true,
|
||||||
|
label:c.label,
|
||||||
|
stats:{mean:m,stddev:d,median:md},
|
||||||
|
table:h,
|
||||||
|
count:c.count
|
||||||
|
};
|
||||||
|
}
|
||||||
|
export default hexchain;
|
||||||
|
// Generation time: 121.732s
|
||||||
|
// Result: FAIL
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
async function hexchain(tomlStr) {
|
||||||
|
const [
|
||||||
|
{ parse },
|
||||||
|
{ default: seedrandom },
|
||||||
|
{ mean, standardDeviation, median },
|
||||||
|
{ default: Ajv },
|
||||||
|
{ default: table },
|
||||||
|
{ DOMPurify }
|
||||||
|
] = await Promise.all([
|
||||||
|
import('https://esm.sh/smol-toml'),
|
||||||
|
import('https://esm.sh/seedrandom'),
|
||||||
|
import('https://esm.sh/simple-statistics'),
|
||||||
|
import('https://esm.sh/ajv'),
|
||||||
|
import('https://esm.sh/text-table'),
|
||||||
|
import('https://esm.sh/dompurify')
|
||||||
|
]);
|
||||||
|
|
||||||
|
const config = parse(tomlStr);
|
||||||
|
const ajv = new Ajv();
|
||||||
|
const validate = ajv.compile({
|
||||||
|
type: 'object',
|
||||||
|
required: ['seed', 'count', 'label'],
|
||||||
|
properties: {
|
||||||
|
seed: { type: 'string' },
|
||||||
|
count: { type: 'integer', minimum: 1, maximum: 10000 },
|
||||||
|
label: { type: 'string', minLength: 1 }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!validate(config)) return { valid: false, errors: ajv.errorsText(validate.errors) };
|
||||||
|
|
||||||
|
const rng = new seedrandom(config.seed);
|
||||||
|
const nums = Array.from({ length: config.count }, rng);
|
||||||
|
const round = n => +(n.toFixed(6));
|
||||||
|
const stats = { mean: round(mean(nums)), stddev: round(standardDeviation(nums)), median: round(median(nums)) };
|
||||||
|
|
||||||
|
const tbl = table([
|
||||||
|
['Stat', 'Value'],
|
||||||
|
['mean', String(stats.mean)],
|
||||||
|
['stddev', String(stats.stddev)],
|
||||||
|
['median', String(stats.median)]
|
||||||
|
]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
valid: true,
|
||||||
|
label: config.label,
|
||||||
|
stats,
|
||||||
|
table: DOMPurify.sanitize(`<pre class="stats">${tbl}</pre>`),
|
||||||
|
count: config.count
|
||||||
|
};
|
||||||
|
}
|
||||||
|
export default hexchain;
|
||||||
|
// Generation time: 1.959s
|
||||||
|
// Result: FAIL
|
||||||
39
tests/4_hexchain_pipeline/outputs/moonshotai_kimi-k2.6.js
Normal file
39
tests/4_hexchain_pipeline/outputs/moonshotai_kimi-k2.6.js
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
const hexchain = async s => {
|
||||||
|
const [{ parse }, { default: Seed }, { mean, standardDeviation, median }, { default: Ajv }, { default: tbl }, { default: DOMPurify }] = await Promise.all([
|
||||||
|
import('https://esm.sh/smol-toml'),
|
||||||
|
import('https://esm.sh/seedrandom'),
|
||||||
|
import('https://esm.sh/simple-statistics'),
|
||||||
|
import('https://esm.sh/ajv'),
|
||||||
|
import('https://esm.sh/text-table'),
|
||||||
|
import('https://esm.sh/dompurify')
|
||||||
|
]);
|
||||||
|
const cfg = parse(s);
|
||||||
|
const ajv = new Ajv();
|
||||||
|
const schema = {
|
||||||
|
type: 'object',
|
||||||
|
required: ['seed', 'count', 'label'],
|
||||||
|
properties: {
|
||||||
|
seed: { type: 'string' },
|
||||||
|
count: { type: 'integer', minimum: 1, maximum: 10000 },
|
||||||
|
label: { type: 'string', minLength: 1 }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (!ajv.validate(schema, cfg)) return { valid: false, errors: ajv.errorsText() };
|
||||||
|
const rng = new Seed(cfg.seed);
|
||||||
|
const nums = Array.from({ length: cfg.count }, () => rng());
|
||||||
|
const r = v => +v.toFixed(6);
|
||||||
|
const m = r(mean(nums));
|
||||||
|
const d = r(standardDeviation(nums));
|
||||||
|
const e = r(median(nums));
|
||||||
|
const ascii = tbl([['Stat', 'Value'], ['mean', String(m)], ['stddev', String(d)], ['median', String(e)]]);
|
||||||
|
return {
|
||||||
|
valid: true,
|
||||||
|
label: cfg.label,
|
||||||
|
stats: { mean: m, stddev: d, median: e },
|
||||||
|
table: DOMPurify.sanitize('<pre class="stats">' + ascii + '</pre>'),
|
||||||
|
count: cfg.count
|
||||||
|
};
|
||||||
|
};
|
||||||
|
export default hexchain;
|
||||||
|
// Generation time: 147.472s
|
||||||
|
// Result: PASS
|
||||||
70
tests/4_hexchain_pipeline/outputs/openai_gpt-5.5 EFF_high.js
Normal file
70
tests/4_hexchain_pipeline/outputs/openai_gpt-5.5 EFF_high.js
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
const hexchainUrls = [
|
||||||
|
'https://esm.sh/smol-toml?bundle',
|
||||||
|
'https://esm.sh/seedrandom?bundle',
|
||||||
|
'https://esm.sh/simple-statistics?bundle',
|
||||||
|
'https://esm.sh/ajv?bundle',
|
||||||
|
'https://esm.sh/text-table?bundle',
|
||||||
|
'https://esm.sh/dompurify?bundle'
|
||||||
|
];
|
||||||
|
|
||||||
|
const hexchainSchema = {
|
||||||
|
type: 'object',
|
||||||
|
required: ['seed', 'count', 'label'],
|
||||||
|
properties: {
|
||||||
|
seed: { type: 'string' },
|
||||||
|
count: { type: 'integer', minimum: 1, maximum: 10000 },
|
||||||
|
label: { type: 'string', minLength: 1 }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let hexchainModules;
|
||||||
|
|
||||||
|
async function hexchain(tomlString) {
|
||||||
|
const [
|
||||||
|
toml,
|
||||||
|
seedMod,
|
||||||
|
ssMod,
|
||||||
|
ajvMod,
|
||||||
|
tableMod,
|
||||||
|
purifyMod
|
||||||
|
] = await (hexchainModules ||= Promise.all(hexchainUrls.map(u => import(u))));
|
||||||
|
|
||||||
|
const parse = toml.parse ?? toml.default?.parse ?? toml.default;
|
||||||
|
const seedrandom = seedMod.default ?? seedMod;
|
||||||
|
const ss = ssMod.mean ? ssMod : ssMod.default;
|
||||||
|
const Ajv = ajvMod.default ?? ajvMod.Ajv;
|
||||||
|
const textTable = tableMod.default ?? tableMod;
|
||||||
|
const purify = purifyMod.default ?? purifyMod;
|
||||||
|
const DOMPurify = purify.sanitize ? purify : purify(globalThis);
|
||||||
|
const config = parse(tomlString);
|
||||||
|
const ajv = new Ajv();
|
||||||
|
|
||||||
|
if (!ajv.validate(hexchainSchema, config))
|
||||||
|
return { valid: false, errors: ajv.errorsText() };
|
||||||
|
|
||||||
|
const rng = new seedrandom(config.seed);
|
||||||
|
const nums = Array.from({ length: config.count }, () => rng());
|
||||||
|
const round = n => Math.round((n + Number.EPSILON) * 1e6) / 1e6;
|
||||||
|
const mean = round(ss.mean(nums));
|
||||||
|
const stddev = round(ss.standardDeviation(nums));
|
||||||
|
const median = round(ss.median(nums));
|
||||||
|
const tableString = textTable([
|
||||||
|
['Stat', 'Value'],
|
||||||
|
['mean', String(mean)],
|
||||||
|
['stddev', String(stddev)],
|
||||||
|
['median', String(median)]
|
||||||
|
]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
valid: true,
|
||||||
|
label: config.label,
|
||||||
|
stats: { mean, stddev, median },
|
||||||
|
table: DOMPurify.sanitize('<pre class="stats">' + tableString + '</pre>'),
|
||||||
|
count: config.count
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
globalThis.hexchain = hexchain;
|
||||||
|
export default hexchain;
|
||||||
|
// Generation time: 137.860s
|
||||||
|
// Result: PASS
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
async function parseMarkdown(m){
|
||||||
|
const{marked}=await import('//cdn.jsdelivr.net/npm/marked@4/lib/marked.esm.js')
|
||||||
|
return marked(m)
|
||||||
|
}
|
||||||
|
export default parseMarkdown;
|
||||||
|
// Generation time: 44.452s
|
||||||
|
// Result: FAIL
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
async function parseMarkdown(md) {
|
||||||
|
const { marked } = await import("https://cdn.jsdelivr.net/npm/marked/lib/marked.esm.js");
|
||||||
|
|
||||||
|
marked.setOptions({
|
||||||
|
gfm: true,
|
||||||
|
breaks: true
|
||||||
|
});
|
||||||
|
|
||||||
|
return marked.parse(md);
|
||||||
|
}
|
||||||
|
export default parseMarkdown;
|
||||||
|
// Generation time: 0.838s
|
||||||
|
// Result: PASS
|
||||||
7
tests/5_markdown_parser/outputs/moonshotai_kimi-k2.6.js
Normal file
7
tests/5_markdown_parser/outputs/moonshotai_kimi-k2.6.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
const parseMarkdown=async(md)=>{
|
||||||
|
const{default:MarkdownIt}=await import('https://esm.sh/markdown-it@14.1.0');
|
||||||
|
return new MarkdownIt({html:false}).render(md);
|
||||||
|
};
|
||||||
|
export default parseMarkdown;
|
||||||
|
// Generation time: 95.822s
|
||||||
|
// Result: PASS
|
||||||
25
tests/5_markdown_parser/outputs/openai_gpt-5.5 EFF_high.js
Normal file
25
tests/5_markdown_parser/outputs/openai_gpt-5.5 EFF_high.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
const parseMarkdown = (() => {
|
||||||
|
let libs;
|
||||||
|
|
||||||
|
return async markdown => {
|
||||||
|
libs ||= Promise.all([
|
||||||
|
import("https://cdn.jsdelivr.net/npm/marked@13/+esm"),
|
||||||
|
import("https://cdn.jsdelivr.net/npm/dompurify@3/+esm")
|
||||||
|
]);
|
||||||
|
|
||||||
|
const [{ marked }, { default: DOMPurify }] = await libs;
|
||||||
|
|
||||||
|
marked.use({
|
||||||
|
gfm: true,
|
||||||
|
breaks: false,
|
||||||
|
async: false
|
||||||
|
});
|
||||||
|
|
||||||
|
return DOMPurify.sanitize(
|
||||||
|
marked.parse(String(markdown ?? ""))
|
||||||
|
);
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
export default parseMarkdown;
|
||||||
|
// Generation time: 13.490s
|
||||||
|
// Result: PASS
|
||||||
22
tests/6_csv_processor/outputs/deepseek_deepseek-v4-pro.js
Normal file
22
tests/6_csv_processor/outputs/deepseek_deepseek-v4-pro.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
async function processCSV(csv, c) {
|
||||||
|
const { default: P } = await import(
|
||||||
|
'https://cdn.jsdelivr.net/npm/papaparse@5/+esm'
|
||||||
|
);
|
||||||
|
const { filterColumn: f, filterValue: v, groupBy: g, aggregateColumn: a, operation: o } = c;
|
||||||
|
const rows = P.parse(csv, { header: true, skipEmptyLines: true }).data;
|
||||||
|
const filtered = rows.filter((r) => r[f] == v);
|
||||||
|
const groups = {};
|
||||||
|
for (const r of filtered) {
|
||||||
|
const k = r[g];
|
||||||
|
groups[k] = groups[k] || { n: 0, s: 0 };
|
||||||
|
groups[k].n++;
|
||||||
|
groups[k].s += +r[a] || 0;
|
||||||
|
}
|
||||||
|
return Object.entries(groups).map(([k, { n, s }]) => ({
|
||||||
|
[g]: k,
|
||||||
|
result: o === 'sum' ? s : o === 'avg' ? s / n : n,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
export default processCSV;
|
||||||
|
// Generation time: 75.337s
|
||||||
|
// Result: PASS
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
async function processCSV(csv, { filterColumn, filterValue, groupBy, aggregateColumn, operation }) {
|
||||||
|
const { parse } = await import('https://cdn.skypack.dev/papaparse');
|
||||||
|
const { data } = parse(csv, { header: true, dynamicTyping: true });
|
||||||
|
|
||||||
|
const groups = data
|
||||||
|
.filter(r => r[filterColumn] == filterValue)
|
||||||
|
.reduce((acc, r) => {
|
||||||
|
const key = r[groupBy];
|
||||||
|
const val = Number(r[aggregateColumn]) || 0;
|
||||||
|
acc[key] ??= { sum: 0, count: 0 };
|
||||||
|
acc[key].sum += val;
|
||||||
|
acc[key].count += 1;
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
return Object.entries(groups).map(([k, v]) => ({
|
||||||
|
[groupBy]: k,
|
||||||
|
result: operation === 'sum' ? v.sum :
|
||||||
|
operation === 'avg' ? v.sum / v.count : v.count
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
export default processCSV;
|
||||||
|
// Generation time: 1.360s
|
||||||
|
// Result: PASS
|
||||||
17
tests/6_csv_processor/outputs/moonshotai_kimi-k2.6.js
Normal file
17
tests/6_csv_processor/outputs/moonshotai_kimi-k2.6.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
async function processCSV(csv,{filterColumn,filterValue,groupBy:g,aggregateColumn,operation}){
|
||||||
|
const[Papa,{groupBy,sum}]=await Promise.all([
|
||||||
|
import('https://esm.sh/papaparse@5.4.1').then(m=>m.default),
|
||||||
|
import('https://esm.sh/lodash-es@4.17.21')
|
||||||
|
]);
|
||||||
|
const{data}=Papa.parse(csv,{header:true,skipEmptyLines:true});
|
||||||
|
const filtered=data.filter(r=>r[filterColumn]==filterValue);
|
||||||
|
const groups=groupBy(filtered,r=>r[g]);
|
||||||
|
return Object.entries(groups).map(([k,v])=>{
|
||||||
|
const n=v.map(r=>+r[aggregateColumn]||0);
|
||||||
|
const result=operation==='sum'?sum(n):operation==='avg'?sum(n)/n.length:v.length;
|
||||||
|
return{[g]:k,result};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
export default processCSV;
|
||||||
|
// Generation time: 205.075s
|
||||||
|
// Result: PASS
|
||||||
34
tests/6_csv_processor/outputs/openai_gpt-5.5 EFF_high.js
Normal file
34
tests/6_csv_processor/outputs/openai_gpt-5.5 EFF_high.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
const csvDeps = Promise.all([
|
||||||
|
import("https://cdn.jsdelivr.net/npm/d3-dsv@3/+esm"),
|
||||||
|
import("https://cdn.jsdelivr.net/npm/d3-array@3/+esm")
|
||||||
|
]);
|
||||||
|
|
||||||
|
async function processCSV(csv, config = {}) {
|
||||||
|
const [{ csvParse }, { rollups }] = await csvDeps;
|
||||||
|
const { filterColumn, filterValue, groupBy, aggregateColumn, operation } = config;
|
||||||
|
const ops = new Set(["sum", "avg", "count"]);
|
||||||
|
|
||||||
|
if (!ops.has(operation)) throw new TypeError("Invalid operation");
|
||||||
|
|
||||||
|
const num = r => {
|
||||||
|
const n = Number(r[aggregateColumn]);
|
||||||
|
return Number.isFinite(n) ? n : 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
const rows = csvParse(String(csv ?? ""))
|
||||||
|
.filter(r => r[filterColumn] == filterValue);
|
||||||
|
|
||||||
|
return rollups(
|
||||||
|
rows,
|
||||||
|
rs => {
|
||||||
|
if (operation === "count") return rs.length;
|
||||||
|
|
||||||
|
const sum = rs.reduce((a, r) => a + num(r), 0);
|
||||||
|
return operation === "avg" ? sum / rs.length : sum;
|
||||||
|
},
|
||||||
|
r => r[groupBy]
|
||||||
|
).map(([k, result]) => ({ [groupBy]: k, result }));
|
||||||
|
}
|
||||||
|
export default processCSV;
|
||||||
|
// Generation time: 26.121s
|
||||||
|
// Result: PASS
|
||||||
82
tests/7_scheduler/outputs/deepseek_deepseek-v4-pro.js
Normal file
82
tests/7_scheduler/outputs/deepseek_deepseek-v4-pro.js
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
let _dayjsPromise;
|
||||||
|
|
||||||
|
const loadDayjs = () => _dayjsPromise || (_dayjsPromise = (async () => {
|
||||||
|
const dayjs = (await import('https://cdn.skypack.dev/dayjs@1')).default;
|
||||||
|
const utc = (await import('https://cdn.skypack.dev/dayjs@1/plugin/utc')).default;
|
||||||
|
dayjs.extend(utc);
|
||||||
|
return dayjs;
|
||||||
|
})());
|
||||||
|
|
||||||
|
async function findAvailableSlots(cal1, cal2, constraints) {
|
||||||
|
const dayjs = await loadDayjs();
|
||||||
|
const { durationMinutes, searchRange, workHours } = constraints;
|
||||||
|
const rStart = dayjs.utc(searchRange.start);
|
||||||
|
const rEnd = dayjs.utc(searchRange.end);
|
||||||
|
const [wSh, wSm] = workHours.start.split(':').map(Number);
|
||||||
|
const [wEh, wEm] = workHours.end.split(':').map(Number);
|
||||||
|
|
||||||
|
// Merge all busy slots
|
||||||
|
const allBusy = [...cal1, ...cal2]
|
||||||
|
.map(s => ({ start: dayjs.utc(s.start), end: dayjs.utc(s.end) }))
|
||||||
|
.filter(s => s.start.isValid() && s.end.isValid() && s.start.isBefore(s.end));
|
||||||
|
|
||||||
|
allBusy.sort((a, b) => a.start.valueOf() - b.start.valueOf());
|
||||||
|
|
||||||
|
const merged = [];
|
||||||
|
for (const busy of allBusy) {
|
||||||
|
if (!merged.length || busy.start.isAfter(merged[merged.length - 1].end)) {
|
||||||
|
merged.push({ start: busy.start, end: busy.end });
|
||||||
|
} else if (busy.end.isAfter(merged[merged.length - 1].end)) {
|
||||||
|
merged[merged.length - 1].end = busy.end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = [];
|
||||||
|
let day = rStart.startOf('day');
|
||||||
|
const endDay = rEnd.startOf('day');
|
||||||
|
|
||||||
|
while (day.isBefore(endDay) || day.isSame(endDay, 'day')) {
|
||||||
|
const workStart = day.hour(wSh).minute(wSm).second(0);
|
||||||
|
const workEnd = day.hour(wEh).minute(wEm).second(0);
|
||||||
|
const dStart = dayjs.max(workStart, rStart);
|
||||||
|
const dEnd = dayjs.min(workEnd, rEnd);
|
||||||
|
|
||||||
|
if (dStart.isBefore(dEnd)) {
|
||||||
|
let gapStart = dStart;
|
||||||
|
|
||||||
|
for (const busy of merged) {
|
||||||
|
if (busy.end.isBefore(dStart) || busy.start.isAfter(dEnd)) continue;
|
||||||
|
if (busy.start.isAfter(gapStart)) {
|
||||||
|
const freeStart = gapStart;
|
||||||
|
const freeEnd = busy.start;
|
||||||
|
let slotStart = freeStart;
|
||||||
|
while (slotStart.add(durationMinutes, 'minute').isBefore(freeEnd) || slotStart.add(durationMinutes, 'minute').isSame(freeEnd)) {
|
||||||
|
const slotEnd = slotStart.add(durationMinutes, 'minute');
|
||||||
|
if (slotEnd.isAfter(freeEnd)) break;
|
||||||
|
result.push({ start: slotStart.toISOString(), end: slotEnd.toISOString() });
|
||||||
|
slotStart = slotEnd;
|
||||||
|
}
|
||||||
|
gapStart = busy.end;
|
||||||
|
} else if (busy.end.isAfter(gapStart)) {
|
||||||
|
gapStart = busy.end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gapStart.isBefore(dEnd)) {
|
||||||
|
let slotStart = gapStart;
|
||||||
|
while (slotStart.add(durationMinutes, 'minute').isBefore(dEnd) || slotStart.add(durationMinutes, 'minute').isSame(dEnd)) {
|
||||||
|
const slotEnd = slotStart.add(durationMinutes, 'minute');
|
||||||
|
if (slotEnd.isAfter(dEnd)) break;
|
||||||
|
result.push({ start: slotStart.toISOString(), end: slotEnd.toISOString() });
|
||||||
|
slotStart = slotEnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
day = day.add(1, 'day');
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.sort((a, b) => a.start.localeCompare(b.start));
|
||||||
|
}
|
||||||
|
export default findAvailableSlots;
|
||||||
|
// Generation time: 135.095s
|
||||||
|
// Result: FAIL
|
||||||
41
tests/7_scheduler/outputs/google_gemini-3.1-flash-lite.js
Normal file
41
tests/7_scheduler/outputs/google_gemini-3.1-flash-lite.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
async function findAvailableSlots(cal1, cal2, { durationMinutes, searchRange, workHours }) {
|
||||||
|
const { DateTime, Interval } = await import('https://cdn.skypack.dev/luxon');
|
||||||
|
|
||||||
|
const toUTC = (iso) => DateTime.fromISO(iso, { zone: 'utc' });
|
||||||
|
const parseTime = (t, d) => DateTime.fromISO(`${d.toISODate()}T${t}:00Z`, { zone: 'utc' });
|
||||||
|
|
||||||
|
const busy = [...cal1, ...cal2].map(s => Interval.fromDateTimes(toUTC(s.start), toUTC(s.end)));
|
||||||
|
const merged = Interval.merge(busy);
|
||||||
|
|
||||||
|
const start = toUTC(searchRange.start);
|
||||||
|
const end = toUTC(searchRange.end);
|
||||||
|
const slots = [];
|
||||||
|
|
||||||
|
let current = start;
|
||||||
|
while (current < end) {
|
||||||
|
let day = current.startOf('day');
|
||||||
|
let workStart = parseTime(workHours.start, day);
|
||||||
|
let workEnd = parseTime(workHours.end, day);
|
||||||
|
|
||||||
|
let windowStart = current > workStart ? current : workStart;
|
||||||
|
let windowEnd = workEnd;
|
||||||
|
|
||||||
|
for (let s = windowStart; s.plus({ minutes: durationMinutes }) <= windowEnd; ) {
|
||||||
|
let slotEnd = s.plus({ minutes: durationMinutes });
|
||||||
|
let interval = Interval.fromDateTimes(s, slotEnd);
|
||||||
|
|
||||||
|
if (!merged.some(b => b.overlaps(interval))) {
|
||||||
|
slots.push({ start: s.toISO(), end: slotEnd.toISO() });
|
||||||
|
s = slotEnd;
|
||||||
|
} else {
|
||||||
|
s = s.plus({ minutes: 1 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
current = day.plus({ days: 1 });
|
||||||
|
}
|
||||||
|
|
||||||
|
return slots;
|
||||||
|
}
|
||||||
|
export default findAvailableSlots;
|
||||||
|
// Generation time: 2.010s
|
||||||
|
// Result: PASS
|
||||||
50
tests/7_scheduler/outputs/moonshotai_kimi-k2.6.js
Normal file
50
tests/7_scheduler/outputs/moonshotai_kimi-k2.6.js
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
const findAvailableSlots = async (c1, c2, c) => {
|
||||||
|
const { parseISO, addMinutes, min, max, isBefore, isAfter } = await import('https://esm.sh/date-fns@3.6.0');
|
||||||
|
const dur = c.durationMinutes;
|
||||||
|
if (dur <= 0) return [];
|
||||||
|
const utc = s => parseISO(/Z|[+-]\d{2}:?\d{2}$/.test(s) ? s : s.includes('T') ? s + 'Z' : s + 'T00:00:00Z');
|
||||||
|
const mins = s => { const [h, m] = s.split(':'); return (+h * 60 + +m) * 6e4; };
|
||||||
|
const rs = utc(c.searchRange.start), re = utc(c.searchRange.end);
|
||||||
|
const ws = mins(c.workHours.start), we = mins(c.workHours.end);
|
||||||
|
const day = 864e5;
|
||||||
|
|
||||||
|
const b = [...(c1 || []), ...(c2 || [])]
|
||||||
|
.map(x => ({ s: utc(x.start), e: utc(x.end) }))
|
||||||
|
.filter(x => isBefore(x.s, re) && isAfter(x.e, rs))
|
||||||
|
.map(x => ({ s: max([x.s, rs]), e: min([x.e, re]) }))
|
||||||
|
.sort((a, b) => +a.s - +b.s || +a.e - +b.e);
|
||||||
|
|
||||||
|
const m = [];
|
||||||
|
for (const x of b) {
|
||||||
|
const l = m[m.length - 1];
|
||||||
|
if (l && +x.s <= +l.e) l.e = max([l.e, x.e]);
|
||||||
|
else m.push({ s: x.s, e: x.e });
|
||||||
|
}
|
||||||
|
|
||||||
|
const f = [];
|
||||||
|
let p = rs;
|
||||||
|
for (const x of m) {
|
||||||
|
if (isBefore(p, x.s)) f.push([p, x.s]);
|
||||||
|
p = max([p, x.e]);
|
||||||
|
}
|
||||||
|
if (isBefore(p, re)) f.push([p, re]);
|
||||||
|
|
||||||
|
const r = [];
|
||||||
|
for (const [a, z] of f) {
|
||||||
|
let cur = a;
|
||||||
|
while (!isAfter(cur, z)) {
|
||||||
|
const end = addMinutes(cur, dur);
|
||||||
|
if (isAfter(end, z)) break;
|
||||||
|
const st = +cur, en = +end;
|
||||||
|
if (Math.floor(st / day) === Math.floor(en / day)) {
|
||||||
|
const sm = st % day, em = en % day;
|
||||||
|
if (sm >= ws && em <= we) r.push({ start: cur.toISOString(), end: end.toISOString() });
|
||||||
|
}
|
||||||
|
cur = end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
};
|
||||||
|
export default findAvailableSlots;
|
||||||
|
// Generation time: 492.497s
|
||||||
|
// Result: PASS
|
||||||
127
tests/7_scheduler/outputs/openai_gpt-5.5 EFF_high.js
Normal file
127
tests/7_scheduler/outputs/openai_gpt-5.5 EFF_high.js
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
let luxonPromise;
|
||||||
|
|
||||||
|
async function findAvailableSlots(calendarA = [], calendarB = [], constraints = {}) {
|
||||||
|
const { DateTime } = await (luxonPromise ||= import("https://esm.sh/luxon@3.5.0?bundle"));
|
||||||
|
const M = 6e4, D = 864e5;
|
||||||
|
const err = (E, m) => { throw new E(m); };
|
||||||
|
|
||||||
|
const toMs = v => {
|
||||||
|
if (typeof v !== "string") err(TypeError, `Invalid ISO date: ${v}`);
|
||||||
|
const d = DateTime.fromISO(v, { zone: "utc" });
|
||||||
|
if (!d.isValid) err(TypeError, `Invalid ISO date: ${v}`);
|
||||||
|
return d.toUTC().toMillis();
|
||||||
|
};
|
||||||
|
|
||||||
|
const toMinutes = v => {
|
||||||
|
if (typeof v !== "string") err(TypeError, `Invalid UTC time: ${v}`);
|
||||||
|
const m = /^(\d{2}):(\d{2})$/.exec(v);
|
||||||
|
if (!m) err(TypeError, `Invalid UTC time: ${v}`);
|
||||||
|
|
||||||
|
const h = +m[1], n = +m[2];
|
||||||
|
if (h > 24 || n > 59 || h === 24 && n)
|
||||||
|
err(RangeError, `Invalid UTC time: ${v}`);
|
||||||
|
|
||||||
|
return h * 60 + n;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!Array.isArray(calendarA) || !Array.isArray(calendarB))
|
||||||
|
err(TypeError, "Calendars must be arrays");
|
||||||
|
|
||||||
|
if (!constraints || typeof constraints !== "object" || Array.isArray(constraints))
|
||||||
|
err(TypeError, "Constraints must be an object");
|
||||||
|
|
||||||
|
if (typeof constraints.durationMinutes !== "number")
|
||||||
|
err(TypeError, "durationMinutes must be a number");
|
||||||
|
|
||||||
|
const duration = constraints.durationMinutes * M;
|
||||||
|
if (!Number.isFinite(duration) || duration <= 0 || !Number.isInteger(duration))
|
||||||
|
err(RangeError, "durationMinutes must resolve to a positive whole millisecond value");
|
||||||
|
|
||||||
|
const rangeStart = toMs(constraints.searchRange?.start);
|
||||||
|
const rangeEnd = toMs(constraints.searchRange?.end);
|
||||||
|
|
||||||
|
if (rangeEnd <= rangeStart)
|
||||||
|
err(RangeError, "searchRange.end must be after searchRange.start");
|
||||||
|
|
||||||
|
const workStart = toMinutes(constraints.workHours?.start);
|
||||||
|
const workEnd = toMinutes(constraints.workHours?.end);
|
||||||
|
|
||||||
|
if (workStart === 1440)
|
||||||
|
err(RangeError, "workHours.start must be before 24:00");
|
||||||
|
|
||||||
|
const midnight = ms => DateTime.fromMillis(ms, { zone: "utc" }).startOf("day").toMillis();
|
||||||
|
const overnight = workEnd <= workStart;
|
||||||
|
const work = [];
|
||||||
|
|
||||||
|
const addWork = (s, e) => {
|
||||||
|
const a = Math.max(s, rangeStart), b = Math.min(e, rangeEnd);
|
||||||
|
if (a >= b) return;
|
||||||
|
|
||||||
|
const l = work[work.length - 1];
|
||||||
|
if (l && a <= l[1]) l[1] = Math.max(l[1], b);
|
||||||
|
else work.push([a, b]);
|
||||||
|
};
|
||||||
|
|
||||||
|
for (
|
||||||
|
let d = midnight(rangeStart) - (overnight ? D : 0), end = midnight(rangeEnd);
|
||||||
|
d <= end;
|
||||||
|
d += D
|
||||||
|
)
|
||||||
|
addWork(d + workStart * M, d + workEnd * M + (overnight ? D : 0));
|
||||||
|
|
||||||
|
const busy = calendarA.concat(calendarB)
|
||||||
|
.map(slot => {
|
||||||
|
if (!slot || typeof slot !== "object")
|
||||||
|
err(TypeError, "Busy slots must be objects");
|
||||||
|
|
||||||
|
const s = toMs(slot.start), e = toMs(slot.end);
|
||||||
|
if (e <= s) err(RangeError, "Busy slot end must be after start");
|
||||||
|
|
||||||
|
return [Math.max(s, rangeStart), Math.min(e, rangeEnd)];
|
||||||
|
})
|
||||||
|
.filter(([s, e]) => s < e)
|
||||||
|
.sort((a, b) => a[0] - b[0] || a[1] - b[1]);
|
||||||
|
|
||||||
|
const merged = [];
|
||||||
|
|
||||||
|
for (const [s, e] of busy) {
|
||||||
|
const l = merged[merged.length - 1];
|
||||||
|
if (l && s <= l[1]) l[1] = Math.max(l[1], e);
|
||||||
|
else merged.push([s, e]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const slots = [];
|
||||||
|
const addSlots = (s, e) => {
|
||||||
|
for (; s + duration <= e; s += duration)
|
||||||
|
slots.push([s, s + duration]);
|
||||||
|
};
|
||||||
|
|
||||||
|
let i = 0;
|
||||||
|
|
||||||
|
for (const [ws, we] of work) {
|
||||||
|
while (merged[i]?.[1] <= ws) i++;
|
||||||
|
|
||||||
|
let p = ws;
|
||||||
|
|
||||||
|
for (let j = i; merged[j]?.[0] < we; j++) {
|
||||||
|
const [bs, be] = merged[j];
|
||||||
|
|
||||||
|
if (bs > p) addSlots(p, Math.min(bs, we));
|
||||||
|
|
||||||
|
p = Math.max(p, Math.min(be, we));
|
||||||
|
if (p >= we) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p < we) addSlots(p, we);
|
||||||
|
}
|
||||||
|
|
||||||
|
const iso = ms => DateTime.fromMillis(ms, { zone: "utc" }).toISO();
|
||||||
|
|
||||||
|
return slots.map(([start, end]) => ({
|
||||||
|
start: iso(start),
|
||||||
|
end: iso(end)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
export default findAvailableSlots;
|
||||||
|
// Generation time: 263.158s
|
||||||
|
// Result: PASS
|
||||||
19
tests/8_json_validator/outputs/deepseek_deepseek-v4-pro.js
Normal file
19
tests/8_json_validator/outputs/deepseek_deepseek-v4-pro.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
let _p
|
||||||
|
async function validateJSON(d, s) {
|
||||||
|
if (!_p) _p = (async () => {
|
||||||
|
const {default: A} = await import('https://cdn.jsdelivr.net/npm/ajv@8.17.1/dist/ajv2020.esm.js')
|
||||||
|
return new A({allErrors: 1})
|
||||||
|
})()
|
||||||
|
try {
|
||||||
|
const a = await _p
|
||||||
|
const v = a.validate(s, d)
|
||||||
|
return v
|
||||||
|
? {valid: 1, errors: []}
|
||||||
|
: {valid: 0, errors: a.errors.map(e => `${e.instancePath||'/'} ${e.message}`.trim())}
|
||||||
|
} catch (e) {
|
||||||
|
return {valid: 0, errors: [e.message]}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default validateJSON;
|
||||||
|
// Generation time: 54.656s
|
||||||
|
// Result: FAIL
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
async function validateJSON(data, schema) {
|
||||||
|
const { default: Ajv } = await import('https://esm.sh/ajv@8.12.0');
|
||||||
|
const { default: addFormats } = await import('https://esm.sh/ajv-formats@2.1.1');
|
||||||
|
|
||||||
|
const ajv = new (Ajv)({ allErrors: true });
|
||||||
|
addFormats(ajv);
|
||||||
|
|
||||||
|
const validate = ajv.compile(schema);
|
||||||
|
const valid = validate(data);
|
||||||
|
|
||||||
|
return {
|
||||||
|
valid,
|
||||||
|
errors: valid ? [] : validate.errors.map(e => `${e.instancePath} ${e.message}`)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
export default validateJSON;
|
||||||
|
// Generation time: 1.038s
|
||||||
|
// Result: PASS
|
||||||
17
tests/8_json_validator/outputs/moonshotai_kimi-k2.6.js
Normal file
17
tests/8_json_validator/outputs/moonshotai_kimi-k2.6.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
let A;
|
||||||
|
const validateJSON = async (json, schema) => {
|
||||||
|
try {
|
||||||
|
A ||= (await import('https://cdn.jsdelivr.net/npm/ajv@8.12.0/dist/ajv.mjs')).default;
|
||||||
|
const v = new A({ allErrors: !0, strict: !1 }).compile(schema);
|
||||||
|
const valid = v(json);
|
||||||
|
return {
|
||||||
|
valid,
|
||||||
|
errors: valid ? [] : v.errors.map(e => `${e.instancePath || '/'} ${e.message}`.trim())
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
return { valid: !1, errors: [e.message] };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
export default validateJSON;
|
||||||
|
// Generation time: 65.490s
|
||||||
|
// Result: FAIL
|
||||||
101
tests/8_json_validator/outputs/openai_gpt-5.5 EFF_high.js
Normal file
101
tests/8_json_validator/outputs/openai_gpt-5.5 EFF_high.js
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
const _jsonSchema = (() => {
|
||||||
|
const ajvs = new Map();
|
||||||
|
const vals = new WeakMap();
|
||||||
|
const opts = {
|
||||||
|
allErrors: true,
|
||||||
|
strict: false,
|
||||||
|
allowUnionTypes: true,
|
||||||
|
addUsedSchema: false,
|
||||||
|
validateFormats: true
|
||||||
|
};
|
||||||
|
|
||||||
|
const ver = s => {
|
||||||
|
s = `${s && typeof s == "object" && s.$schema || ""}`;
|
||||||
|
return s.includes("2020-12") ? "2020" : s.includes("2019-09") ? "2019" : "7";
|
||||||
|
};
|
||||||
|
|
||||||
|
const url = v => `https://esm.sh/ajv@8.17.1${v == "7" ? "" : `/dist/${v}`}?bundle`;
|
||||||
|
|
||||||
|
const load = v => {
|
||||||
|
let p = ajvs.get(v);
|
||||||
|
if (p) return p;
|
||||||
|
|
||||||
|
p = Promise.all([
|
||||||
|
import(url(v)),
|
||||||
|
import("https://esm.sh/ajv-formats@3.0.1?bundle&deps=ajv@8.17.1")
|
||||||
|
]).then(([a, f]) => {
|
||||||
|
const Ajv = a.default || a.Ajv || a;
|
||||||
|
const addFormats = f.default || f.addFormats || f;
|
||||||
|
const ajv = new Ajv({ ...opts });
|
||||||
|
addFormats(ajv);
|
||||||
|
return ajv;
|
||||||
|
}).catch(e => {
|
||||||
|
ajvs.delete(v);
|
||||||
|
throw e;
|
||||||
|
});
|
||||||
|
|
||||||
|
ajvs.set(v, p);
|
||||||
|
return p;
|
||||||
|
};
|
||||||
|
|
||||||
|
const part = s => /^(0|[1-9]\d*)$/.test(s)
|
||||||
|
? `[${s}]`
|
||||||
|
: /^[A-Za-z_$][\w$]*$/.test(s)
|
||||||
|
? `.${s}`
|
||||||
|
: `[${JSON.stringify(s)}]`;
|
||||||
|
|
||||||
|
const loc = p => p
|
||||||
|
? `$${p.split("/").slice(1).map(s => part(s.replace(/~1/g, "/").replace(/~0/g, "~"))).join("")}`
|
||||||
|
: "$";
|
||||||
|
|
||||||
|
const msg = e => {
|
||||||
|
const x = e.params || {};
|
||||||
|
const extra = e.keyword == "additionalProperties"
|
||||||
|
? `: ${x.additionalProperty}`
|
||||||
|
: e.keyword == "required"
|
||||||
|
? `: ${x.missingProperty}`
|
||||||
|
: "";
|
||||||
|
|
||||||
|
return `${loc(e.instancePath)} ${e.message || "is invalid"}${extra}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
return { load, vals, ver, msg };
|
||||||
|
})();
|
||||||
|
|
||||||
|
async function validateJSON(data, schema) {
|
||||||
|
const isSchema = typeof schema == "boolean" ||
|
||||||
|
schema && typeof schema == "object" && !Array.isArray(schema);
|
||||||
|
|
||||||
|
if (!isSchema) {
|
||||||
|
return {
|
||||||
|
valid: false,
|
||||||
|
errors: ["Schema must be a JSON Schema object or boolean"]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const cacheable = schema && typeof schema == "object";
|
||||||
|
let validate = cacheable && _jsonSchema.vals.get(schema);
|
||||||
|
|
||||||
|
if (!validate) {
|
||||||
|
const ajv = await _jsonSchema.load(_jsonSchema.ver(schema));
|
||||||
|
validate = ajv.compile(schema);
|
||||||
|
if (cacheable) _jsonSchema.vals.set(schema, validate);
|
||||||
|
}
|
||||||
|
|
||||||
|
const valid = validate(data);
|
||||||
|
|
||||||
|
return {
|
||||||
|
valid,
|
||||||
|
errors: valid ? [] : (validate.errors || []).map(_jsonSchema.msg)
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
return {
|
||||||
|
valid: false,
|
||||||
|
errors: [e?.message || String(e)]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default validateJSON;
|
||||||
|
// Generation time: 143.247s
|
||||||
|
// Result: PASS
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
const createStreamVisualizer = async (feed, { p = 1000, a = .25, w, h, y }) => {
|
||||||
|
const d3 = (await import('https://esm.sh/d3@7')).default
|
||||||
|
const data = []
|
||||||
|
for await (const { timestamp: t, value: v } of feed) {
|
||||||
|
const e = data.length ? a * v + (1 - a) * data[data.length - 1].ema : v
|
||||||
|
data.push({ timestamp: t, value: v, ema: e })
|
||||||
|
if (data.length > p) data.shift()
|
||||||
|
}
|
||||||
|
if (!data.length) return { data: [], path: '' }
|
||||||
|
const x = d3.scaleLinear()
|
||||||
|
.domain([data[0].timestamp, data[data.length - 1].timestamp])
|
||||||
|
.range([0, w])
|
||||||
|
const y = d3.scaleLinear()
|
||||||
|
.domain(y)
|
||||||
|
.range([h, 0])
|
||||||
|
const line = d3.line()
|
||||||
|
.x(d => x(d.timestamp))
|
||||||
|
.y(d => y(d.ema))
|
||||||
|
return { data, path: line(data) }
|
||||||
|
}
|
||||||
|
export default createStreamVisualizer;
|
||||||
|
// Generation time: 71.592s
|
||||||
|
// Result: FAIL
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
async function createStreamVisualizer(it, { maxPoints, alpha, width, height, yDomain }) {
|
||||||
|
const [{ scaleLinear, line, extent }] = await Promise.all([import('https://cdn.skypack.dev/d3')]);
|
||||||
|
const data = [];
|
||||||
|
let prevEma;
|
||||||
|
|
||||||
|
for await (const { timestamp, value } of it) {
|
||||||
|
prevEma = prevEma === undefined ? value : alpha * value + (1 - alpha) * prevEma;
|
||||||
|
data.push({ timestamp, value, ema: prevEma });
|
||||||
|
if (data.length > maxPoints) data.shift();
|
||||||
|
}
|
||||||
|
|
||||||
|
const x = scaleLinear().domain(extent(data, d => d.timestamp)).range([0, width]);
|
||||||
|
const y = scaleLinear().domain(yDomain).range([height, 0]);
|
||||||
|
const path = line().x(d => x(d.timestamp)).y(d => y(d.ema))(data);
|
||||||
|
|
||||||
|
return { data, path };
|
||||||
|
}
|
||||||
|
export default createStreamVisualizer;
|
||||||
|
// Generation time: 1.461s
|
||||||
|
// Result: PASS
|
||||||
19
tests/9_stream_visualizer/outputs/moonshotai_kimi-k2.6.js
Normal file
19
tests/9_stream_visualizer/outputs/moonshotai_kimi-k2.6.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
const createStreamVisualizer = async (stream, options = {}) => {
|
||||||
|
const { scaleLinear, line } = await import("https://cdn.jsdelivr.net/npm/d3@7/+esm");
|
||||||
|
const { maxPoints = 1e3, alpha = .2, width = 600, height = 400, yDomain } = options;
|
||||||
|
const data = [];
|
||||||
|
let ema;
|
||||||
|
for await (const { timestamp, value } of stream) {
|
||||||
|
ema = data.length ? alpha * value + (1 - alpha) * ema : value;
|
||||||
|
data.push({ timestamp, value, ema });
|
||||||
|
if (data.length > maxPoints) data.shift();
|
||||||
|
}
|
||||||
|
if (!data.length) return { data, path: "" };
|
||||||
|
const x = scaleLinear().domain([data[0].timestamp, data.at(-1).timestamp]).range([0, width]);
|
||||||
|
const y = scaleLinear().domain(yDomain).range([height, 0]);
|
||||||
|
const path = line().x(d => x(d.timestamp)).y(d => y(d.ema))(data);
|
||||||
|
return { data, path };
|
||||||
|
};
|
||||||
|
export default createStreamVisualizer;
|
||||||
|
// Generation time: 68.920s
|
||||||
|
// Result: PASS
|
||||||
76
tests/9_stream_visualizer/outputs/openai_gpt-5.5 EFF_high.js
Normal file
76
tests/9_stream_visualizer/outputs/openai_gpt-5.5 EFF_high.js
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
const d3$ = import("https://cdn.jsdelivr.net/npm/d3@7/+esm");
|
||||||
|
|
||||||
|
async function createStreamVisualizer(asyncIterable, options = {}) {
|
||||||
|
const {
|
||||||
|
maxPoints,
|
||||||
|
alpha,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
yDomain
|
||||||
|
} = options;
|
||||||
|
|
||||||
|
if (!asyncIterable?.[Symbol.asyncIterator])
|
||||||
|
throw new TypeError("asyncIterable must be an async iterable");
|
||||||
|
|
||||||
|
if (!Number.isInteger(maxPoints) || maxPoints < 1)
|
||||||
|
throw new RangeError("maxPoints must be a positive integer");
|
||||||
|
|
||||||
|
if (!Number.isFinite(alpha) || alpha < 0 || alpha > 1)
|
||||||
|
throw new RangeError("alpha must be between 0 and 1");
|
||||||
|
|
||||||
|
if (!Number.isFinite(width) || width <= 0 || !Number.isFinite(height) || height <= 0)
|
||||||
|
throw new RangeError("width and height must be positive numbers");
|
||||||
|
|
||||||
|
if (!Array.isArray(yDomain) || yDomain.length !== 2)
|
||||||
|
throw new TypeError("yDomain must be [min, max]");
|
||||||
|
|
||||||
|
const [yMin, yMax] = yDomain.map(Number);
|
||||||
|
|
||||||
|
if (!Number.isFinite(yMin) || !Number.isFinite(yMax) || yMin === yMax)
|
||||||
|
throw new RangeError("yDomain values must be finite and distinct");
|
||||||
|
|
||||||
|
const d3 = await d3$;
|
||||||
|
const data = [];
|
||||||
|
let ema;
|
||||||
|
|
||||||
|
for await (const item of asyncIterable) {
|
||||||
|
const source = Array.isArray(item)
|
||||||
|
? { timestamp: item[0], value: item[1] }
|
||||||
|
: item;
|
||||||
|
|
||||||
|
const timestamp = +source?.timestamp;
|
||||||
|
const value = +source?.value;
|
||||||
|
|
||||||
|
if (!Number.isFinite(timestamp) || !Number.isFinite(value))
|
||||||
|
throw new TypeError("stream items must include finite timestamp and value");
|
||||||
|
|
||||||
|
ema = ema === undefined
|
||||||
|
? value
|
||||||
|
: alpha * value + (1 - alpha) * ema;
|
||||||
|
|
||||||
|
data.push({ timestamp, value, ema });
|
||||||
|
|
||||||
|
if (data.length > maxPoints)
|
||||||
|
data.splice(0, data.length - maxPoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.length)
|
||||||
|
return { data, path: "" };
|
||||||
|
|
||||||
|
const x = d3.scaleLinear()
|
||||||
|
.domain([data[0].timestamp, data.at(-1).timestamp])
|
||||||
|
.range([0, width]);
|
||||||
|
|
||||||
|
const y = d3.scaleLinear()
|
||||||
|
.domain([yMin, yMax])
|
||||||
|
.range([height, 0]);
|
||||||
|
|
||||||
|
const path = d3.line()
|
||||||
|
.x(d => x(d.timestamp))
|
||||||
|
.y(d => y(d.ema))(data) || "";
|
||||||
|
|
||||||
|
return { data, path };
|
||||||
|
}
|
||||||
|
export default createStreamVisualizer;
|
||||||
|
// Generation time: 27.168s
|
||||||
|
// Result: PASS
|
||||||
Reference in New Issue
Block a user