@almadar/evaluator 2.12.2 → 2.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -21,7 +21,7 @@ function createEffectContext(base, handlers) {
21
21
  }
22
22
  function createChildContext(parent, locals) {
23
23
  const mergedLocals = new Map(parent.locals);
24
- locals.forEach((value, key) => mergedLocals.set(key, value));
24
+ locals.forEach((value, key2) => mergedLocals.set(key2, value));
25
25
  return {
26
26
  ...parent,
27
27
  locals: mergedLocals
@@ -222,7 +222,7 @@ function deepEqual(a, b) {
222
222
  const keysB = Object.keys(b);
223
223
  if (keysA.length !== keysB.length) return false;
224
224
  return keysA.every(
225
- (key) => deepEqual(a[key], b[key])
225
+ (key2) => deepEqual(a[key2], b[key2])
226
226
  );
227
227
  }
228
228
  return false;
@@ -518,13 +518,13 @@ function evalCallService(args, evaluate2, ctx) {
518
518
  }
519
519
  function evaluateNestedProps(obj, evaluate2, ctx) {
520
520
  const result = {};
521
- for (const [key, value] of Object.entries(obj)) {
521
+ for (const [key2, value] of Object.entries(obj)) {
522
522
  if (Array.isArray(value) && value.length > 0 && typeof value[0] === "string") {
523
- result[key] = evaluate2(value, ctx);
523
+ result[key2] = evaluate2(value, ctx);
524
524
  } else if (typeof value === "object" && value !== null && !Array.isArray(value)) {
525
- result[key] = evaluateNestedProps(value, evaluate2, ctx);
525
+ result[key2] = evaluateNestedProps(value, evaluate2, ctx);
526
526
  } else {
527
- result[key] = value;
527
+ result[key2] = value;
528
528
  }
529
529
  }
530
530
  return result;
@@ -733,6 +733,50 @@ function evalMathDefault(args, evaluate2, ctx) {
733
733
  }
734
734
  return n;
735
735
  }
736
+ function evalMathSin(args, evaluate2, ctx) {
737
+ return Math.sin(evaluate2(args[0], ctx));
738
+ }
739
+ function evalMathCos(args, evaluate2, ctx) {
740
+ return Math.cos(evaluate2(args[0], ctx));
741
+ }
742
+ function evalMathTan(args, evaluate2, ctx) {
743
+ return Math.tan(evaluate2(args[0], ctx));
744
+ }
745
+ function evalMathAtan2(args, evaluate2, ctx) {
746
+ const y = evaluate2(args[0], ctx);
747
+ const x = evaluate2(args[1], ctx);
748
+ return Math.atan2(y, x);
749
+ }
750
+ function evalMathHypot(args, evaluate2, ctx) {
751
+ const a = evaluate2(args[0], ctx);
752
+ const b = evaluate2(args[1], ctx);
753
+ return Math.hypot(a, b);
754
+ }
755
+ function evalMathDegRad(args, evaluate2, ctx) {
756
+ return evaluate2(args[0], ctx) * (Math.PI / 180);
757
+ }
758
+ function evalMathRadDeg(args, evaluate2, ctx) {
759
+ return evaluate2(args[0], ctx) * (180 / Math.PI);
760
+ }
761
+ function evalMathWrap(args, evaluate2, ctx) {
762
+ const v = evaluate2(args[0], ctx);
763
+ const min = evaluate2(args[1], ctx);
764
+ const max = evaluate2(args[2], ctx);
765
+ const r = max - min;
766
+ if (r <= 0) {
767
+ return min;
768
+ }
769
+ return min + ((v - min) % r + r) % r;
770
+ }
771
+ function evalMathApproach(args, evaluate2, ctx) {
772
+ const cur = evaluate2(args[0], ctx);
773
+ const target = evaluate2(args[1], ctx);
774
+ const maxD = evaluate2(args[2], ctx);
775
+ if (Math.abs(target - cur) <= maxD) {
776
+ return target;
777
+ }
778
+ return cur + Math.sign(target - cur) * maxD;
779
+ }
736
780
 
737
781
  // std/str.ts
738
782
  function evalStrLen(args, evaluate2, ctx) {
@@ -871,8 +915,8 @@ function evalStrTemplate(args, evaluate2, ctx) {
871
915
  const template = evaluate2(args[0], ctx);
872
916
  const vars = evaluate2(args[1], ctx);
873
917
  if (!template) return "";
874
- return template.replace(/\{(\w+)\}/g, (_, key) => {
875
- const value = vars?.[key];
918
+ return template.replace(/\{(\w+)\}/g, (_, key2) => {
919
+ const value = vars?.[key2];
876
920
  return value !== void 0 ? String(value) : "";
877
921
  });
878
922
  }
@@ -896,15 +940,15 @@ function evalWithItem(expr, evaluate2, ctx, item, index) {
896
940
  const params = fnArgs[0];
897
941
  const body = fnArgs[1];
898
942
  if (typeof params === "string") {
899
- const key = params.startsWith("@") ? params.slice(1) : params;
900
- locals.set(key, item);
943
+ const key2 = params.startsWith("@") ? params.slice(1) : params;
944
+ locals.set(key2, item);
901
945
  } else if (Array.isArray(params)) {
902
946
  const paramNames = params;
903
947
  const values = [item, index];
904
948
  for (let i = 0; i < paramNames.length; i++) {
905
- const p = paramNames[i];
906
- const key = p.startsWith("@") ? p.slice(1) : p;
907
- locals.set(key, values[i]);
949
+ const p2 = paramNames[i];
950
+ const key2 = p2.startsWith("@") ? p2.slice(1) : p2;
951
+ locals.set(key2, values[i]);
908
952
  }
909
953
  }
910
954
  const childCtx2 = createChildContext(ctx, locals);
@@ -927,13 +971,13 @@ function evalReduceLambda(lambdaExpr, evaluate2, ctx, acc, item) {
927
971
  if (Array.isArray(params)) {
928
972
  const paramNames = params;
929
973
  const values = [acc, item];
930
- paramNames.forEach((p, i) => {
931
- const key = p.startsWith("@") ? p.slice(1) : p;
932
- locals.set(key, values[i]);
974
+ paramNames.forEach((p2, i) => {
975
+ const key2 = p2.startsWith("@") ? p2.slice(1) : p2;
976
+ locals.set(key2, values[i]);
933
977
  });
934
978
  } else if (typeof params === "string") {
935
- const key = params.startsWith("@") ? params.slice(1) : params;
936
- locals.set(key, acc);
979
+ const key2 = params.startsWith("@") ? params.slice(1) : params;
980
+ locals.set(key2, acc);
937
981
  }
938
982
  const childCtx2 = createChildContext(ctx, locals);
939
983
  return evaluate2(body, childCtx2);
@@ -1015,13 +1059,13 @@ function evalArrayReverse(args, evaluate2, ctx) {
1015
1059
  }
1016
1060
  function evalArraySort(args, evaluate2, ctx) {
1017
1061
  const arr = evaluate2(args[0], ctx);
1018
- const key = args.length > 1 ? evaluate2(args[1], ctx) : void 0;
1062
+ const key2 = args.length > 1 ? evaluate2(args[1], ctx) : void 0;
1019
1063
  const dir = args.length > 2 ? evaluate2(args[2], ctx) : "asc";
1020
1064
  const result = [...arr ?? []];
1021
- if (key) {
1065
+ if (key2) {
1022
1066
  result.sort((a, b) => {
1023
- const aVal = a[key];
1024
- const bVal = b[key];
1067
+ const aVal = a[key2];
1068
+ const bVal = b[key2];
1025
1069
  if (aVal < bVal) return dir === "asc" ? -1 : 1;
1026
1070
  if (aVal > bVal) return dir === "asc" ? 1 : -1;
1027
1071
  return 0;
@@ -1128,18 +1172,18 @@ function evalArrayCount(args, evaluate2, ctx) {
1128
1172
  }
1129
1173
  function evalArraySum(args, evaluate2, ctx) {
1130
1174
  const arr = evaluate2(args[0], ctx);
1131
- const key = args.length > 1 ? evaluate2(args[1], ctx) : void 0;
1175
+ const key2 = args.length > 1 ? evaluate2(args[1], ctx) : void 0;
1132
1176
  return (arr ?? []).reduce((sum, item) => {
1133
- const value = key ? item[key] : item;
1177
+ const value = key2 ? item[key2] : item;
1134
1178
  return sum + (typeof value === "number" ? value : 0);
1135
1179
  }, 0);
1136
1180
  }
1137
1181
  function evalArrayAvg(args, evaluate2, ctx) {
1138
1182
  const arr = evaluate2(args[0], ctx);
1139
1183
  if (!arr || arr.length === 0) return 0;
1140
- const key = args.length > 1 ? evaluate2(args[1], ctx) : void 0;
1184
+ const key2 = args.length > 1 ? evaluate2(args[1], ctx) : void 0;
1141
1185
  const sum = arr.reduce((s, item) => {
1142
- const value = key ? item[key] : item;
1186
+ const value = key2 ? item[key2] : item;
1143
1187
  return s + (typeof value === "number" ? value : 0);
1144
1188
  }, 0);
1145
1189
  return sum / arr.length;
@@ -1147,9 +1191,9 @@ function evalArrayAvg(args, evaluate2, ctx) {
1147
1191
  function evalArrayMin(args, evaluate2, ctx) {
1148
1192
  const arr = evaluate2(args[0], ctx);
1149
1193
  if (!arr || arr.length === 0) return 0;
1150
- const key = args.length > 1 ? evaluate2(args[1], ctx) : void 0;
1194
+ const key2 = args.length > 1 ? evaluate2(args[1], ctx) : void 0;
1151
1195
  const values = arr.map((item) => {
1152
- const value = key ? item[key] : item;
1196
+ const value = key2 ? item[key2] : item;
1153
1197
  return typeof value === "number" ? value : Infinity;
1154
1198
  });
1155
1199
  return Math.min(...values);
@@ -1157,19 +1201,19 @@ function evalArrayMin(args, evaluate2, ctx) {
1157
1201
  function evalArrayMax(args, evaluate2, ctx) {
1158
1202
  const arr = evaluate2(args[0], ctx);
1159
1203
  if (!arr || arr.length === 0) return 0;
1160
- const key = args.length > 1 ? evaluate2(args[1], ctx) : void 0;
1204
+ const key2 = args.length > 1 ? evaluate2(args[1], ctx) : void 0;
1161
1205
  const values = arr.map((item) => {
1162
- const value = key ? item[key] : item;
1206
+ const value = key2 ? item[key2] : item;
1163
1207
  return typeof value === "number" ? value : -Infinity;
1164
1208
  });
1165
1209
  return Math.max(...values);
1166
1210
  }
1167
1211
  function evalArrayGroupBy(args, evaluate2, ctx) {
1168
1212
  const arr = evaluate2(args[0], ctx);
1169
- const key = evaluate2(args[1], ctx);
1213
+ const key2 = evaluate2(args[1], ctx);
1170
1214
  const result = {};
1171
1215
  for (const item of arr ?? []) {
1172
- const groupKey = String(item[key] ?? "undefined");
1216
+ const groupKey = String(item[key2] ?? "undefined");
1173
1217
  if (!result[groupKey]) {
1174
1218
  result[groupKey] = [];
1175
1219
  }
@@ -1227,8 +1271,8 @@ function evalLambda(lambdaExpr, evaluate2, ctx, ...values) {
1227
1271
  values.forEach((v, i) => {
1228
1272
  if (paramNames[i]) {
1229
1273
  const paramName = paramNames[i];
1230
- const key = paramName.startsWith("@") ? paramName.slice(1) : paramName;
1231
- newLocals.set(key, v);
1274
+ const key2 = paramName.startsWith("@") ? paramName.slice(1) : paramName;
1275
+ newLocals.set(key2, v);
1232
1276
  }
1233
1277
  });
1234
1278
  } else if (typeof params === "string") {
@@ -1276,7 +1320,7 @@ function evalObjectSet(args, evaluate2, ctx) {
1276
1320
  if (!path) return obj ?? {};
1277
1321
  const result = structuredClone(obj ?? {});
1278
1322
  const parts = path.split(".");
1279
- if (parts.some((p) => FORBIDDEN_KEYS.has(p))) {
1323
+ if (parts.some((p2) => FORBIDDEN_KEYS.has(p2))) {
1280
1324
  return result;
1281
1325
  }
1282
1326
  let current = result;
@@ -1315,15 +1359,15 @@ function evalObjectDeepMerge(args, evaluate2, ctx) {
1315
1359
  const objects = args.map((a) => evaluate2(a, ctx));
1316
1360
  function deepMerge(target, source) {
1317
1361
  const result = { ...target };
1318
- for (const key of Object.keys(source)) {
1319
- if (FORBIDDEN_KEYS.has(key)) continue;
1320
- if (source[key] !== null && typeof source[key] === "object" && !Array.isArray(source[key]) && target[key] !== null && typeof target[key] === "object" && !Array.isArray(target[key])) {
1321
- result[key] = deepMerge(
1322
- target[key],
1323
- source[key]
1362
+ for (const key2 of Object.keys(source)) {
1363
+ if (FORBIDDEN_KEYS.has(key2)) continue;
1364
+ if (source[key2] !== null && typeof source[key2] === "object" && !Array.isArray(source[key2]) && target[key2] !== null && typeof target[key2] === "object" && !Array.isArray(target[key2])) {
1365
+ result[key2] = deepMerge(
1366
+ target[key2],
1367
+ source[key2]
1324
1368
  );
1325
1369
  } else {
1326
- result[key] = source[key];
1370
+ result[key2] = source[key2];
1327
1371
  }
1328
1372
  }
1329
1373
  return result;
@@ -1334,9 +1378,9 @@ function evalObjectPick(args, evaluate2, ctx) {
1334
1378
  const obj = evaluate2(args[0], ctx);
1335
1379
  const keys = evaluate2(args[1], ctx);
1336
1380
  const result = {};
1337
- for (const key of keys ?? []) {
1338
- if (obj && Object.prototype.hasOwnProperty.call(obj, key)) {
1339
- result[key] = obj[key];
1381
+ for (const key2 of keys ?? []) {
1382
+ if (obj && Object.prototype.hasOwnProperty.call(obj, key2)) {
1383
+ result[key2] = obj[key2];
1340
1384
  }
1341
1385
  }
1342
1386
  return result;
@@ -1346,9 +1390,9 @@ function evalObjectOmit(args, evaluate2, ctx) {
1346
1390
  const keys = evaluate2(args[1], ctx);
1347
1391
  const keysSet = new Set(keys ?? []);
1348
1392
  const result = {};
1349
- for (const key of Object.keys(obj ?? {})) {
1350
- if (!keysSet.has(key)) {
1351
- result[key] = obj[key];
1393
+ for (const key2 of Object.keys(obj ?? {})) {
1394
+ if (!keysSet.has(key2)) {
1395
+ result[key2] = obj[key2];
1352
1396
  }
1353
1397
  }
1354
1398
  return result;
@@ -1357,8 +1401,8 @@ function evalObjectMapValues(args, evaluate2, ctx) {
1357
1401
  const obj = evaluate2(args[0], ctx);
1358
1402
  const lambda = args[1];
1359
1403
  const result = {};
1360
- for (const [key, value] of Object.entries(obj ?? {})) {
1361
- result[key] = evalLambda(lambda, evaluate2, ctx, value);
1404
+ for (const [key2, value] of Object.entries(obj ?? {})) {
1405
+ result[key2] = evalLambda(lambda, evaluate2, ctx, value);
1362
1406
  }
1363
1407
  return result;
1364
1408
  }
@@ -1366,8 +1410,8 @@ function evalObjectMapKeys(args, evaluate2, ctx) {
1366
1410
  const obj = evaluate2(args[0], ctx);
1367
1411
  const lambda = args[1];
1368
1412
  const result = {};
1369
- for (const [key, value] of Object.entries(obj ?? {})) {
1370
- const newKey = String(evalLambda(lambda, evaluate2, ctx, key));
1413
+ for (const [key2, value] of Object.entries(obj ?? {})) {
1414
+ const newKey = String(evalLambda(lambda, evaluate2, ctx, key2));
1371
1415
  result[newKey] = value;
1372
1416
  }
1373
1417
  return result;
@@ -1376,9 +1420,9 @@ function evalObjectFilter(args, evaluate2, ctx) {
1376
1420
  const obj = evaluate2(args[0], ctx);
1377
1421
  const lambda = args[1];
1378
1422
  const result = {};
1379
- for (const [key, value] of Object.entries(obj ?? {})) {
1380
- if (evalLambda(lambda, evaluate2, ctx, key, value)) {
1381
- result[key] = value;
1423
+ for (const [key2, value] of Object.entries(obj ?? {})) {
1424
+ if (evalLambda(lambda, evaluate2, ctx, key2, value)) {
1425
+ result[key2] = value;
1382
1426
  }
1383
1427
  }
1384
1428
  return result;
@@ -1398,8 +1442,8 @@ function evalObjectEquals(args, evaluate2, ctx) {
1398
1442
  const xKeys = Object.keys(x);
1399
1443
  const yKeys = Object.keys(y);
1400
1444
  if (xKeys.length !== yKeys.length) return false;
1401
- for (const key of xKeys) {
1402
- if (!deepEqual2(x[key], y[key])) {
1445
+ for (const key2 of xKeys) {
1446
+ if (!deepEqual2(x[key2], y[key2])) {
1403
1447
  return false;
1404
1448
  }
1405
1449
  }
@@ -1577,8 +1621,8 @@ function evalValidateEquals(args, evaluate2, ctx) {
1577
1621
  const xKeys = Object.keys(x);
1578
1622
  const yKeys = Object.keys(y);
1579
1623
  if (xKeys.length !== yKeys.length) return false;
1580
- for (const key of xKeys) {
1581
- if (!deepEqual2(x[key], y[key])) {
1624
+ for (const key2 of xKeys) {
1625
+ if (!deepEqual2(x[key2], y[key2])) {
1582
1626
  return false;
1583
1627
  }
1584
1628
  }
@@ -2248,8 +2292,8 @@ function evalProbSeed(args, evaluate2, ctx) {
2248
2292
  ctx._probSeed = { state: n | 0 };
2249
2293
  }
2250
2294
  function evalProbFlip(args, evaluate2, ctx) {
2251
- const p = evaluate2(args[0], ctx);
2252
- return getRandom(ctx) < p;
2295
+ const p2 = evaluate2(args[0], ctx);
2296
+ return getRandom(ctx) < p2;
2253
2297
  }
2254
2298
  function evalProbGaussian(args, evaluate2, ctx) {
2255
2299
  const mu = evaluate2(args[0], ctx);
@@ -2283,11 +2327,11 @@ function evalProbPoisson(args, evaluate2, ctx) {
2283
2327
  const lambda = evaluate2(args[0], ctx);
2284
2328
  const limit = Math.exp(-lambda);
2285
2329
  let k = 0;
2286
- let p = 1;
2330
+ let p2 = 1;
2287
2331
  do {
2288
2332
  k++;
2289
- p *= getRandom(ctx);
2290
- } while (p > limit);
2333
+ p2 *= getRandom(ctx);
2334
+ } while (p2 > limit);
2291
2335
  return k - 1;
2292
2336
  }
2293
2337
  function evalProbCondition(args, evaluate2, ctx) {
@@ -2399,10 +2443,10 @@ function evalProbHistogram(args, evaluate2, ctx) {
2399
2443
  }
2400
2444
  function evalProbPercentile(args, evaluate2, ctx) {
2401
2445
  const samples = evaluate2(args[0], ctx);
2402
- const p = evaluate2(args[1], ctx);
2446
+ const p2 = evaluate2(args[1], ctx);
2403
2447
  if (samples.length === 0) return 0;
2404
2448
  const sorted = [...samples].sort((a, b) => a - b);
2405
- const idx = p / 100 * (sorted.length - 1);
2449
+ const idx = p2 / 100 * (sorted.length - 1);
2406
2450
  const lo = Math.floor(idx);
2407
2451
  const hi = Math.ceil(idx);
2408
2452
  if (lo === hi) return sorted[lo];
@@ -2575,6 +2619,948 @@ function evalAgentSearchCode(args, evaluate2, ctx) {
2575
2619
  return ctx.agent.searchCode(query, language);
2576
2620
  }
2577
2621
 
2622
+ // std/vector.ts
2623
+ function asVec(v) {
2624
+ const o = v ?? {};
2625
+ const x = typeof o.x === "number" ? o.x : 0;
2626
+ const y = typeof o.y === "number" ? o.y : 0;
2627
+ const z2 = typeof o.z === "number" ? o.z : void 0;
2628
+ return z2 === void 0 ? { x, y } : { x, y, z: z2 };
2629
+ }
2630
+ function has3(v) {
2631
+ return v.z !== void 0;
2632
+ }
2633
+ function z(v) {
2634
+ return v.z ?? 0;
2635
+ }
2636
+ function make(x, y, zVal, is3d) {
2637
+ return is3d ? { x, y, z: zVal } : { x, y };
2638
+ }
2639
+ function evalVecAdd(args, evaluate2, ctx) {
2640
+ const a = asVec(evaluate2(args[0], ctx));
2641
+ const b = asVec(evaluate2(args[1], ctx));
2642
+ return make(a.x + b.x, a.y + b.y, z(a) + z(b), has3(a));
2643
+ }
2644
+ function evalVecSub(args, evaluate2, ctx) {
2645
+ const a = asVec(evaluate2(args[0], ctx));
2646
+ const b = asVec(evaluate2(args[1], ctx));
2647
+ return make(a.x - b.x, a.y - b.y, z(a) - z(b), has3(a));
2648
+ }
2649
+ function evalVecScale(args, evaluate2, ctx) {
2650
+ const a = asVec(evaluate2(args[0], ctx));
2651
+ const k = evaluate2(args[1], ctx);
2652
+ return make(a.x * k, a.y * k, z(a) * k, has3(a));
2653
+ }
2654
+ function evalVecDot(args, evaluate2, ctx) {
2655
+ const a = asVec(evaluate2(args[0], ctx));
2656
+ const b = asVec(evaluate2(args[1], ctx));
2657
+ return a.x * b.x + a.y * b.y + z(a) * z(b);
2658
+ }
2659
+ function evalVecCross(args, evaluate2, ctx) {
2660
+ const a = asVec(evaluate2(args[0], ctx));
2661
+ const b = asVec(evaluate2(args[1], ctx));
2662
+ if (has3(a)) {
2663
+ const ax = a.x, ay = a.y, az = z(a);
2664
+ const bx = b.x, by = b.y, bz = z(b);
2665
+ return { x: ay * bz - az * by, y: az * bx - ax * bz, z: ax * by - ay * bx };
2666
+ }
2667
+ return a.x * b.y - a.y * b.x;
2668
+ }
2669
+ function evalVecLength(args, evaluate2, ctx) {
2670
+ const a = asVec(evaluate2(args[0], ctx));
2671
+ return Math.sqrt(a.x * a.x + a.y * a.y + z(a) * z(a));
2672
+ }
2673
+ function evalVecLengthSq(args, evaluate2, ctx) {
2674
+ const a = asVec(evaluate2(args[0], ctx));
2675
+ return a.x * a.x + a.y * a.y + z(a) * z(a);
2676
+ }
2677
+ function evalVecNormalize(args, evaluate2, ctx) {
2678
+ const a = asVec(evaluate2(args[0], ctx));
2679
+ const len = Math.sqrt(a.x * a.x + a.y * a.y + z(a) * z(a));
2680
+ if (len === 0) {
2681
+ return make(0, 0, 0, has3(a));
2682
+ }
2683
+ return make(a.x / len, a.y / len, z(a) / len, has3(a));
2684
+ }
2685
+ function evalVecDistance(args, evaluate2, ctx) {
2686
+ const a = asVec(evaluate2(args[0], ctx));
2687
+ const b = asVec(evaluate2(args[1], ctx));
2688
+ const dx = a.x - b.x, dy = a.y - b.y, dz = z(a) - z(b);
2689
+ return Math.sqrt(dx * dx + dy * dy + dz * dz);
2690
+ }
2691
+ function evalVecDistanceSq(args, evaluate2, ctx) {
2692
+ const a = asVec(evaluate2(args[0], ctx));
2693
+ const b = asVec(evaluate2(args[1], ctx));
2694
+ const dx = a.x - b.x, dy = a.y - b.y, dz = z(a) - z(b);
2695
+ return dx * dx + dy * dy + dz * dz;
2696
+ }
2697
+ function evalVecLerp(args, evaluate2, ctx) {
2698
+ const a = asVec(evaluate2(args[0], ctx));
2699
+ const b = asVec(evaluate2(args[1], ctx));
2700
+ const t = evaluate2(args[2], ctx);
2701
+ return make(
2702
+ a.x + (b.x - a.x) * t,
2703
+ a.y + (b.y - a.y) * t,
2704
+ z(a) + (z(b) - z(a)) * t,
2705
+ has3(a)
2706
+ );
2707
+ }
2708
+ function evalVecAngle(args, evaluate2, ctx) {
2709
+ const a = asVec(evaluate2(args[0], ctx));
2710
+ if (args.length < 2) {
2711
+ return Math.atan2(a.y, a.x);
2712
+ }
2713
+ const b = asVec(evaluate2(args[1], ctx));
2714
+ const la = Math.sqrt(a.x * a.x + a.y * a.y + z(a) * z(a));
2715
+ const lb = Math.sqrt(b.x * b.x + b.y * b.y + z(b) * z(b));
2716
+ if (la === 0 || lb === 0) {
2717
+ return 0;
2718
+ }
2719
+ const d = (a.x * b.x + a.y * b.y + z(a) * z(b)) / (la * lb);
2720
+ const clamped = Math.min(Math.max(d, -1), 1);
2721
+ return Math.acos(clamped);
2722
+ }
2723
+ function evalVecRotate(args, evaluate2, ctx) {
2724
+ const a = asVec(evaluate2(args[0], ctx));
2725
+ const rad = evaluate2(args[1], ctx);
2726
+ const c = Math.cos(rad), s = Math.sin(rad);
2727
+ return make(a.x * c - a.y * s, a.x * s + a.y * c, z(a), has3(a));
2728
+ }
2729
+ function evalVecClampLength(args, evaluate2, ctx) {
2730
+ const a = asVec(evaluate2(args[0], ctx));
2731
+ const max = evaluate2(args[1], ctx);
2732
+ const len = Math.sqrt(a.x * a.x + a.y * a.y + z(a) * z(a));
2733
+ if (len > max) {
2734
+ if (len === 0) {
2735
+ return make(0, 0, 0, has3(a));
2736
+ }
2737
+ const k = max / len;
2738
+ return make(a.x * k, a.y * k, z(a) * k, has3(a));
2739
+ }
2740
+ return make(a.x, a.y, z(a), has3(a));
2741
+ }
2742
+
2743
+ // std/geo.ts
2744
+ function num(o, k) {
2745
+ return typeof o[k] === "number" ? o[k] : 0;
2746
+ }
2747
+ function asVec2(v) {
2748
+ const o = v ?? {};
2749
+ const z2 = typeof o.z === "number" ? o.z : void 0;
2750
+ return z2 === void 0 ? { x: num(o, "x"), y: num(o, "y") } : { x: num(o, "x"), y: num(o, "y"), z: z2 };
2751
+ }
2752
+ function asRect(v) {
2753
+ const o = v ?? {};
2754
+ return { x: num(o, "x"), y: num(o, "y"), w: num(o, "w"), h: num(o, "h") };
2755
+ }
2756
+ function asCircle(v) {
2757
+ const o = v ?? {};
2758
+ return { x: num(o, "x"), y: num(o, "y"), r: num(o, "r") };
2759
+ }
2760
+ function asSegment(v) {
2761
+ const o = v ?? {};
2762
+ return { x1: num(o, "x1"), y1: num(o, "y1"), x2: num(o, "x2"), y2: num(o, "y2") };
2763
+ }
2764
+ function clamp(n, lo, hi) {
2765
+ return Math.min(Math.max(n, lo), hi);
2766
+ }
2767
+ function evalGeoAabbOverlap(args, evaluate2, ctx) {
2768
+ const a = asRect(evaluate2(args[0], ctx));
2769
+ const b = asRect(evaluate2(args[1], ctx));
2770
+ return a.x < b.x + b.w && a.x + a.w > b.x && a.y < b.y + b.h && a.y + a.h > b.y;
2771
+ }
2772
+ function evalGeoCircleOverlap(args, evaluate2, ctx) {
2773
+ const a = asCircle(evaluate2(args[0], ctx));
2774
+ const b = asCircle(evaluate2(args[1], ctx));
2775
+ const dx = a.x - b.x, dy = a.y - b.y;
2776
+ return Math.sqrt(dx * dx + dy * dy) <= a.r + b.r;
2777
+ }
2778
+ function evalGeoRectCircleOverlap(args, evaluate2, ctx) {
2779
+ const r = asRect(evaluate2(args[0], ctx));
2780
+ const c = asCircle(evaluate2(args[1], ctx));
2781
+ const cx = clamp(c.x, r.x, r.x + r.w);
2782
+ const cy = clamp(c.y, r.y, r.y + r.h);
2783
+ const dx = c.x - cx, dy = c.y - cy;
2784
+ return dx * dx + dy * dy <= c.r * c.r;
2785
+ }
2786
+ function evalGeoPointInRect(args, evaluate2, ctx) {
2787
+ const p2 = asVec2(evaluate2(args[0], ctx));
2788
+ const r = asRect(evaluate2(args[1], ctx));
2789
+ return p2.x >= r.x && p2.x <= r.x + r.w && p2.y >= r.y && p2.y <= r.y + r.h;
2790
+ }
2791
+ function evalGeoPointInCircle(args, evaluate2, ctx) {
2792
+ const p2 = asVec2(evaluate2(args[0], ctx));
2793
+ const c = asCircle(evaluate2(args[1], ctx));
2794
+ const dx = p2.x - c.x, dy = p2.y - c.y;
2795
+ return dx * dx + dy * dy <= c.r * c.r;
2796
+ }
2797
+ function evalGeoReflect(args, evaluate2, ctx) {
2798
+ const v = asVec2(evaluate2(args[0], ctx));
2799
+ const n = asVec2(evaluate2(args[1], ctx));
2800
+ const is3d = v.z !== void 0;
2801
+ const vz = v.z ?? 0, nz = n.z ?? 0;
2802
+ const d = v.x * n.x + v.y * n.y + vz * nz;
2803
+ const rx = v.x - n.x * 2 * d;
2804
+ const ry = v.y - n.y * 2 * d;
2805
+ const rz = vz - nz * 2 * d;
2806
+ return is3d ? { x: rx, y: ry, z: rz } : { x: rx, y: ry };
2807
+ }
2808
+ function evalGeoSegmentIntersect(args, evaluate2, ctx) {
2809
+ const s1 = asSegment(evaluate2(args[0], ctx));
2810
+ const s2 = asSegment(evaluate2(args[1], ctx));
2811
+ const r_x = s1.x2 - s1.x1, r_y = s1.y2 - s1.y1;
2812
+ const s_x = s2.x2 - s2.x1, s_y = s2.y2 - s2.y1;
2813
+ const denom = r_x * s_y - r_y * s_x;
2814
+ if (denom === 0) {
2815
+ return null;
2816
+ }
2817
+ const qpx = s2.x1 - s1.x1, qpy = s2.y1 - s1.y1;
2818
+ const t = (qpx * s_y - qpy * s_x) / denom;
2819
+ const u = (qpx * r_y - qpy * r_x) / denom;
2820
+ if (t < 0 || t > 1 || u < 0 || u > 1) {
2821
+ return null;
2822
+ }
2823
+ return { x: s1.x1 + t * r_x, y: s1.y1 + t * r_y };
2824
+ }
2825
+
2826
+ // std/grid.ts
2827
+ function num2(o, k) {
2828
+ return typeof o[k] === "number" ? o[k] : 0;
2829
+ }
2830
+ function asCell(v) {
2831
+ const o = v ?? {};
2832
+ return { x: num2(o, "x"), y: num2(o, "y") };
2833
+ }
2834
+ function evalGridToWorld(args, evaluate2, ctx) {
2835
+ const cell = asCell(evaluate2(args[0], ctx));
2836
+ const cellSize = evaluate2(args[1], ctx);
2837
+ return { x: (cell.x + 0.5) * cellSize, y: (cell.y + 0.5) * cellSize };
2838
+ }
2839
+ function evalGridFromWorld(args, evaluate2, ctx) {
2840
+ const point = asCell(evaluate2(args[0], ctx));
2841
+ const cellSize = evaluate2(args[1], ctx);
2842
+ return { x: Math.floor(point.x / cellSize), y: Math.floor(point.y / cellSize) };
2843
+ }
2844
+ function evalGridIsoToScreen(args, evaluate2, ctx) {
2845
+ const cell = asCell(evaluate2(args[0], ctx));
2846
+ const tileW = evaluate2(args[1], ctx);
2847
+ const tileH = evaluate2(args[2], ctx);
2848
+ return { x: (cell.x - cell.y) * tileW / 2, y: (cell.x + cell.y) * tileH / 2 };
2849
+ }
2850
+ function evalGridScreenToIso(args, evaluate2, ctx) {
2851
+ const point = asCell(evaluate2(args[0], ctx));
2852
+ const tileW = evaluate2(args[1], ctx);
2853
+ const tileH = evaluate2(args[2], ctx);
2854
+ const halfW = tileW / 2;
2855
+ const halfH = tileH / 2;
2856
+ return {
2857
+ x: (point.x / halfW + point.y / halfH) / 2,
2858
+ y: (point.y / halfH - point.x / halfW) / 2
2859
+ };
2860
+ }
2861
+ function evalGridDistance(args, evaluate2, ctx) {
2862
+ const a = asCell(evaluate2(args[0], ctx));
2863
+ const b = asCell(evaluate2(args[1], ctx));
2864
+ return Math.max(Math.abs(a.x - b.x), Math.abs(a.y - b.y));
2865
+ }
2866
+ function evalGridManhattanDistance(args, evaluate2, ctx) {
2867
+ const a = asCell(evaluate2(args[0], ctx));
2868
+ const b = asCell(evaluate2(args[1], ctx));
2869
+ return Math.abs(a.x - b.x) + Math.abs(a.y - b.y);
2870
+ }
2871
+ function evalGridNeighbors(args, evaluate2, ctx) {
2872
+ const cell = asCell(evaluate2(args[0], ctx));
2873
+ const diagonal = args.length > 1 ? Boolean(evaluate2(args[1], ctx)) : false;
2874
+ const result = [
2875
+ { x: cell.x, y: cell.y - 1 },
2876
+ // N
2877
+ { x: cell.x + 1, y: cell.y },
2878
+ // E
2879
+ { x: cell.x, y: cell.y + 1 },
2880
+ // S
2881
+ { x: cell.x - 1, y: cell.y }
2882
+ // W
2883
+ ];
2884
+ if (diagonal) {
2885
+ result.push(
2886
+ { x: cell.x + 1, y: cell.y - 1 },
2887
+ // NE
2888
+ { x: cell.x + 1, y: cell.y + 1 },
2889
+ // SE
2890
+ { x: cell.x - 1, y: cell.y + 1 },
2891
+ // SW
2892
+ { x: cell.x - 1, y: cell.y - 1 }
2893
+ // NW
2894
+ );
2895
+ }
2896
+ return result;
2897
+ }
2898
+ function evalGridCellsInRadius(args, evaluate2, ctx) {
2899
+ const cell = asCell(evaluate2(args[0], ctx));
2900
+ const r = evaluate2(args[1], ctx);
2901
+ const rf = Math.floor(r);
2902
+ const r2 = r * r;
2903
+ const result = [];
2904
+ for (let dy = -rf; dy <= rf; dy++) {
2905
+ for (let dx = -rf; dx <= rf; dx++) {
2906
+ if (dx * dx + dy * dy <= r2) {
2907
+ result.push({ x: cell.x + dx, y: cell.y + dy });
2908
+ }
2909
+ }
2910
+ }
2911
+ return result;
2912
+ }
2913
+ function evalGridLine(args, evaluate2, ctx) {
2914
+ const a = asCell(evaluate2(args[0], ctx));
2915
+ const b = asCell(evaluate2(args[1], ctx));
2916
+ let x0 = a.x, y0 = a.y;
2917
+ const x1 = b.x, y1 = b.y;
2918
+ const dx = Math.abs(x1 - x0);
2919
+ const dy = Math.abs(y1 - y0);
2920
+ const sx = x0 < x1 ? 1 : -1;
2921
+ const sy = y0 < y1 ? 1 : -1;
2922
+ let err = dx - dy;
2923
+ const result = [];
2924
+ for (; ; ) {
2925
+ result.push({ x: x0, y: y0 });
2926
+ if (x0 === x1 && y0 === y1) {
2927
+ break;
2928
+ }
2929
+ const e2 = 2 * err;
2930
+ if (e2 > -dy) {
2931
+ err -= dy;
2932
+ x0 += sx;
2933
+ }
2934
+ if (e2 < dx) {
2935
+ err += dx;
2936
+ y0 += sy;
2937
+ }
2938
+ }
2939
+ return result;
2940
+ }
2941
+ function evalGridInBounds(args, evaluate2, ctx) {
2942
+ const cell = asCell(evaluate2(args[0], ctx));
2943
+ const w = evaluate2(args[1], ctx);
2944
+ const h = evaluate2(args[2], ctx);
2945
+ return cell.x >= 0 && cell.x < w && cell.y >= 0 && cell.y < h;
2946
+ }
2947
+
2948
+ // std/anim.ts
2949
+ function evalAnimFrameAt(args, evaluate2, ctx) {
2950
+ const elapsed = evaluate2(args[0], ctx);
2951
+ const frameDur = evaluate2(args[1], ctx);
2952
+ const frameCount = evaluate2(args[2], ctx);
2953
+ const loop = args.length > 3 ? Boolean(evaluate2(args[3], ctx)) : true;
2954
+ if (frameCount <= 0) {
2955
+ return 0;
2956
+ }
2957
+ const i = Math.floor(elapsed / frameDur);
2958
+ if (loop) {
2959
+ return (i % frameCount + frameCount) % frameCount;
2960
+ }
2961
+ return Math.min(i, frameCount - 1);
2962
+ }
2963
+ function evalAnimSheetRect(args, evaluate2, ctx) {
2964
+ const frameIndex = evaluate2(args[0], ctx);
2965
+ const cols = evaluate2(args[1], ctx);
2966
+ const frameW = evaluate2(args[2], ctx);
2967
+ const frameH = evaluate2(args[3], ctx);
2968
+ return {
2969
+ sx: frameIndex % cols * frameW,
2970
+ sy: Math.floor(frameIndex / cols) * frameH,
2971
+ sw: frameW,
2972
+ sh: frameH
2973
+ };
2974
+ }
2975
+ function evalAnimDirectionFromDelta(args, evaluate2, ctx) {
2976
+ const dx = evaluate2(args[0], ctx);
2977
+ const dy = evaluate2(args[1], ctx);
2978
+ const ways = args.length > 2 ? evaluate2(args[2], ctx) : 4;
2979
+ const angle = Math.atan2(dy, dx);
2980
+ if (ways === 8) {
2981
+ const sector2 = Math.round(angle / (Math.PI / 4));
2982
+ const idx2 = (sector2 % 8 + 8) % 8;
2983
+ const dirs8 = [
2984
+ "right",
2985
+ "down-right",
2986
+ "down",
2987
+ "down-left",
2988
+ "left",
2989
+ "up-left",
2990
+ "up",
2991
+ "up-right"
2992
+ ];
2993
+ return dirs8[idx2];
2994
+ }
2995
+ const sector = Math.round(angle / (Math.PI / 2));
2996
+ const idx = (sector % 4 + 4) % 4;
2997
+ const dirs4 = ["right", "down", "left", "up"];
2998
+ return dirs4[idx];
2999
+ }
3000
+
3001
+ // std/ease.ts
3002
+ function clamp01(t) {
3003
+ return Math.min(Math.max(t, 0), 1);
3004
+ }
3005
+ function applyCurve(curve, tRaw) {
3006
+ const t = clamp01(tRaw);
3007
+ switch (curve) {
3008
+ case "in-quad":
3009
+ return t * t;
3010
+ case "out-quad":
3011
+ return t * (2 - t);
3012
+ case "in-out-quad":
3013
+ return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
3014
+ case "in-cubic":
3015
+ return t * t * t;
3016
+ case "out-cubic": {
3017
+ const u = t - 1;
3018
+ return u * u * u + 1;
3019
+ }
3020
+ case "in-out-cubic":
3021
+ return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
3022
+ case "elastic-out": {
3023
+ if (t === 0) {
3024
+ return 0;
3025
+ }
3026
+ if (t === 1) {
3027
+ return 1;
3028
+ }
3029
+ const c4 = 2 * Math.PI / 3;
3030
+ return Math.pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * c4) + 1;
3031
+ }
3032
+ case "bounce-out": {
3033
+ const n1 = 7.5625;
3034
+ const d1 = 2.75;
3035
+ let u = t;
3036
+ if (u < 1 / d1) {
3037
+ return n1 * u * u;
3038
+ } else if (u < 2 / d1) {
3039
+ u -= 1.5 / d1;
3040
+ return n1 * u * u + 0.75;
3041
+ } else if (u < 2.5 / d1) {
3042
+ u -= 2.25 / d1;
3043
+ return n1 * u * u + 0.9375;
3044
+ } else {
3045
+ u -= 2.625 / d1;
3046
+ return n1 * u * u + 0.984375;
3047
+ }
3048
+ }
3049
+ case "linear":
3050
+ default:
3051
+ return t;
3052
+ }
3053
+ }
3054
+ function evalEaseApply(args, evaluate2, ctx) {
3055
+ const curve = evaluate2(args[0], ctx);
3056
+ const t = evaluate2(args[1], ctx);
3057
+ return applyCurve(curve, t);
3058
+ }
3059
+ function evalEaseSmoothstep(args, evaluate2, ctx) {
3060
+ const edge0 = evaluate2(args[0], ctx);
3061
+ const edge1 = evaluate2(args[1], ctx);
3062
+ const x = evaluate2(args[2], ctx);
3063
+ if (edge0 === edge1) {
3064
+ return 0;
3065
+ }
3066
+ const t = clamp01((x - edge0) / (edge1 - edge0));
3067
+ return t * t * (3 - 2 * t);
3068
+ }
3069
+
3070
+ // std/noise.ts
3071
+ var PERM = [
3072
+ 151,
3073
+ 160,
3074
+ 137,
3075
+ 91,
3076
+ 90,
3077
+ 15,
3078
+ 131,
3079
+ 13,
3080
+ 201,
3081
+ 95,
3082
+ 96,
3083
+ 53,
3084
+ 194,
3085
+ 233,
3086
+ 7,
3087
+ 225,
3088
+ 140,
3089
+ 36,
3090
+ 103,
3091
+ 30,
3092
+ 69,
3093
+ 142,
3094
+ 8,
3095
+ 99,
3096
+ 37,
3097
+ 240,
3098
+ 21,
3099
+ 10,
3100
+ 23,
3101
+ 190,
3102
+ 6,
3103
+ 148,
3104
+ 247,
3105
+ 120,
3106
+ 234,
3107
+ 75,
3108
+ 0,
3109
+ 26,
3110
+ 197,
3111
+ 62,
3112
+ 94,
3113
+ 252,
3114
+ 219,
3115
+ 203,
3116
+ 117,
3117
+ 35,
3118
+ 11,
3119
+ 32,
3120
+ 57,
3121
+ 177,
3122
+ 33,
3123
+ 88,
3124
+ 237,
3125
+ 149,
3126
+ 56,
3127
+ 87,
3128
+ 174,
3129
+ 20,
3130
+ 125,
3131
+ 136,
3132
+ 171,
3133
+ 168,
3134
+ 68,
3135
+ 175,
3136
+ 74,
3137
+ 165,
3138
+ 71,
3139
+ 134,
3140
+ 139,
3141
+ 48,
3142
+ 27,
3143
+ 166,
3144
+ 77,
3145
+ 146,
3146
+ 158,
3147
+ 231,
3148
+ 83,
3149
+ 111,
3150
+ 229,
3151
+ 122,
3152
+ 60,
3153
+ 211,
3154
+ 133,
3155
+ 230,
3156
+ 220,
3157
+ 105,
3158
+ 92,
3159
+ 41,
3160
+ 55,
3161
+ 46,
3162
+ 245,
3163
+ 40,
3164
+ 244,
3165
+ 102,
3166
+ 143,
3167
+ 54,
3168
+ 65,
3169
+ 25,
3170
+ 63,
3171
+ 161,
3172
+ 1,
3173
+ 216,
3174
+ 80,
3175
+ 73,
3176
+ 209,
3177
+ 76,
3178
+ 132,
3179
+ 187,
3180
+ 208,
3181
+ 89,
3182
+ 18,
3183
+ 169,
3184
+ 200,
3185
+ 196,
3186
+ 135,
3187
+ 130,
3188
+ 116,
3189
+ 188,
3190
+ 159,
3191
+ 86,
3192
+ 164,
3193
+ 100,
3194
+ 109,
3195
+ 198,
3196
+ 173,
3197
+ 186,
3198
+ 3,
3199
+ 64,
3200
+ 52,
3201
+ 217,
3202
+ 226,
3203
+ 250,
3204
+ 124,
3205
+ 123,
3206
+ 5,
3207
+ 202,
3208
+ 38,
3209
+ 147,
3210
+ 118,
3211
+ 126,
3212
+ 255,
3213
+ 82,
3214
+ 85,
3215
+ 212,
3216
+ 207,
3217
+ 206,
3218
+ 59,
3219
+ 227,
3220
+ 47,
3221
+ 16,
3222
+ 58,
3223
+ 17,
3224
+ 182,
3225
+ 189,
3226
+ 28,
3227
+ 42,
3228
+ 223,
3229
+ 183,
3230
+ 170,
3231
+ 213,
3232
+ 119,
3233
+ 248,
3234
+ 152,
3235
+ 2,
3236
+ 44,
3237
+ 154,
3238
+ 163,
3239
+ 70,
3240
+ 221,
3241
+ 153,
3242
+ 101,
3243
+ 155,
3244
+ 167,
3245
+ 43,
3246
+ 172,
3247
+ 9,
3248
+ 129,
3249
+ 22,
3250
+ 39,
3251
+ 253,
3252
+ 19,
3253
+ 98,
3254
+ 108,
3255
+ 110,
3256
+ 79,
3257
+ 113,
3258
+ 224,
3259
+ 232,
3260
+ 178,
3261
+ 185,
3262
+ 112,
3263
+ 104,
3264
+ 218,
3265
+ 246,
3266
+ 97,
3267
+ 228,
3268
+ 251,
3269
+ 34,
3270
+ 242,
3271
+ 193,
3272
+ 238,
3273
+ 210,
3274
+ 144,
3275
+ 12,
3276
+ 191,
3277
+ 179,
3278
+ 162,
3279
+ 241,
3280
+ 81,
3281
+ 51,
3282
+ 145,
3283
+ 235,
3284
+ 249,
3285
+ 14,
3286
+ 239,
3287
+ 107,
3288
+ 49,
3289
+ 192,
3290
+ 214,
3291
+ 31,
3292
+ 181,
3293
+ 199,
3294
+ 106,
3295
+ 157,
3296
+ 184,
3297
+ 84,
3298
+ 204,
3299
+ 176,
3300
+ 115,
3301
+ 121,
3302
+ 50,
3303
+ 45,
3304
+ 127,
3305
+ 4,
3306
+ 150,
3307
+ 254,
3308
+ 138,
3309
+ 236,
3310
+ 205,
3311
+ 93,
3312
+ 222,
3313
+ 114,
3314
+ 67,
3315
+ 29,
3316
+ 24,
3317
+ 72,
3318
+ 243,
3319
+ 141,
3320
+ 128,
3321
+ 195,
3322
+ 78,
3323
+ 66,
3324
+ 215,
3325
+ 61,
3326
+ 156,
3327
+ 180
3328
+ ];
3329
+ function p(i) {
3330
+ return PERM[i & 255];
3331
+ }
3332
+ function fade(t) {
3333
+ return t * t * t * (t * (t * 6 - 15) + 10);
3334
+ }
3335
+ function lerp(a, b, t) {
3336
+ return a + t * (b - a);
3337
+ }
3338
+ function grad2(hash, x, y) {
3339
+ const h = hash & 7;
3340
+ const u = h < 4 ? x : y;
3341
+ const v = h < 4 ? y : x;
3342
+ return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v);
3343
+ }
3344
+ function perlin(x, y, seed) {
3345
+ const s = Math.floor(seed) & 255;
3346
+ const X = Math.floor(x) + s & 255;
3347
+ const Y = Math.floor(y) + s & 255;
3348
+ const xf = x - Math.floor(x);
3349
+ const yf = y - Math.floor(y);
3350
+ const u = fade(xf);
3351
+ const v = fade(yf);
3352
+ const aa = p(p(X) + Y);
3353
+ const ab = p(p(X) + Y + 1);
3354
+ const ba = p(p(X + 1) + Y);
3355
+ const bb = p(p(X + 1) + Y + 1);
3356
+ const x1 = lerp(grad2(aa, xf, yf), grad2(ba, xf - 1, yf), u);
3357
+ const x2 = lerp(grad2(ab, xf, yf - 1), grad2(bb, xf - 1, yf - 1), u);
3358
+ return lerp(x1, x2, v);
3359
+ }
3360
+ function simplex(x, y, seed) {
3361
+ return (perlin(x, y, seed) + perlin(x * 2 + 5.2, y * 2 + 1.3, seed) * 0.5 + perlin(x * 4 + 9.1, y * 4 + 7.7, seed) * 0.25) / 1.75;
3362
+ }
3363
+ function fbm(x, y, octaves, seed) {
3364
+ let n = Math.floor(octaves);
3365
+ if (n < 1) n = 1;
3366
+ if (n > 8) n = 8;
3367
+ let total = 0;
3368
+ let freq = 1;
3369
+ let amp = 1;
3370
+ let max = 0;
3371
+ for (let i = 0; i < n; i++) {
3372
+ total += perlin(x * freq, y * freq, seed) * amp;
3373
+ max += amp;
3374
+ freq *= 2;
3375
+ amp *= 0.5;
3376
+ }
3377
+ return total / max;
3378
+ }
3379
+ function evalNoisePerlin(args, evaluate2, ctx) {
3380
+ const x = evaluate2(args[0], ctx);
3381
+ const y = args.length > 1 ? evaluate2(args[1], ctx) : 0;
3382
+ const seed = args.length > 2 ? evaluate2(args[2], ctx) : 0;
3383
+ return perlin(x, y, seed);
3384
+ }
3385
+ function evalNoiseSimplex(args, evaluate2, ctx) {
3386
+ const x = evaluate2(args[0], ctx);
3387
+ const y = evaluate2(args[1], ctx);
3388
+ const seed = args.length > 2 ? evaluate2(args[2], ctx) : 0;
3389
+ return simplex(x, y, seed);
3390
+ }
3391
+ function evalNoiseFbm(args, evaluate2, ctx) {
3392
+ const x = evaluate2(args[0], ctx);
3393
+ const y = evaluate2(args[1], ctx);
3394
+ const octaves = evaluate2(args[2], ctx);
3395
+ const seed = args.length > 3 ? evaluate2(args[3], ctx) : 0;
3396
+ return fbm(x, y, octaves, seed);
3397
+ }
3398
+
3399
+ // std/path.ts
3400
+ function asCell2(v) {
3401
+ const o = v ?? {};
3402
+ const x = typeof o.x === "number" ? o.x : 0;
3403
+ const y = typeof o.y === "number" ? o.y : 0;
3404
+ return { x, y };
3405
+ }
3406
+ function key(x, y) {
3407
+ return `${x},${y}`;
3408
+ }
3409
+ var DIRS4 = [
3410
+ [0, -1],
3411
+ [1, 0],
3412
+ [0, 1],
3413
+ [-1, 0]
3414
+ ];
3415
+ var DIRS_DIAG = [
3416
+ [1, -1],
3417
+ [1, 1],
3418
+ [-1, 1],
3419
+ [-1, -1]
3420
+ ];
3421
+ function neighbors(diagonal) {
3422
+ return diagonal ? [...DIRS4, ...DIRS_DIAG] : DIRS4;
3423
+ }
3424
+ function blockedSet(blocked) {
3425
+ const set = /* @__PURE__ */ new Set();
3426
+ for (const b of blocked) {
3427
+ const c = asCell2(b);
3428
+ set.add(key(c.x, c.y));
3429
+ }
3430
+ return set;
3431
+ }
3432
+ function evalPathAstar(args, evaluate2, ctx) {
3433
+ const start = asCell2(evaluate2(args[0], ctx));
3434
+ const goal = asCell2(evaluate2(args[1], ctx));
3435
+ const blockedArr = evaluate2(args[2], ctx) ?? [];
3436
+ const w = evaluate2(args[3], ctx);
3437
+ const h = evaluate2(args[4], ctx);
3438
+ const diagonal = args.length > 5 ? Boolean(evaluate2(args[5], ctx)) : false;
3439
+ const blocked = blockedSet(blockedArr);
3440
+ const dirs = neighbors(diagonal);
3441
+ const heuristic = (x, y) => {
3442
+ const dx = Math.abs(x - goal.x);
3443
+ const dy = Math.abs(y - goal.y);
3444
+ return diagonal ? Math.max(dx, dy) : dx + dy;
3445
+ };
3446
+ const startKey = key(start.x, start.y);
3447
+ const goalKey = key(goal.x, goal.y);
3448
+ if (start.x < 0 || start.x >= w || start.y < 0 || start.y >= h || goal.x < 0 || goal.x >= w || goal.y < 0 || goal.y >= h || blocked.has(startKey) || blocked.has(goalKey)) {
3449
+ return [];
3450
+ }
3451
+ const open = [];
3452
+ const gScore = /* @__PURE__ */ new Map();
3453
+ const cameFrom = /* @__PURE__ */ new Map();
3454
+ let counter = 0;
3455
+ gScore.set(startKey, 0);
3456
+ open.push({
3457
+ x: start.x,
3458
+ y: start.y,
3459
+ g: 0,
3460
+ h: heuristic(start.x, start.y),
3461
+ f: heuristic(start.x, start.y),
3462
+ order: counter++
3463
+ });
3464
+ while (open.length > 0) {
3465
+ let bestIdx = 0;
3466
+ for (let i = 1; i < open.length; i++) {
3467
+ const a = open[i];
3468
+ const b = open[bestIdx];
3469
+ if (a.f < b.f || a.f === b.f && a.h < b.h || a.f === b.f && a.h === b.h && a.order < b.order) {
3470
+ bestIdx = i;
3471
+ }
3472
+ }
3473
+ const current = open[bestIdx];
3474
+ open.splice(bestIdx, 1);
3475
+ const curKey = key(current.x, current.y);
3476
+ if (curKey === goalKey) {
3477
+ const path = [];
3478
+ let k = curKey;
3479
+ while (k !== void 0) {
3480
+ const parts = k.split(",");
3481
+ path.push({ x: Number(parts[0]), y: Number(parts[1]) });
3482
+ k = cameFrom.get(k);
3483
+ }
3484
+ path.reverse();
3485
+ return path;
3486
+ }
3487
+ const recordedG = gScore.get(curKey);
3488
+ if (recordedG !== void 0 && current.g > recordedG) {
3489
+ continue;
3490
+ }
3491
+ for (const [dx, dy] of dirs) {
3492
+ const nx = current.x + dx;
3493
+ const ny = current.y + dy;
3494
+ if (nx < 0 || nx >= w || ny < 0 || ny >= h) {
3495
+ continue;
3496
+ }
3497
+ const nKey = key(nx, ny);
3498
+ if (blocked.has(nKey)) {
3499
+ continue;
3500
+ }
3501
+ const tentativeG = current.g + 1;
3502
+ const existingG = gScore.get(nKey);
3503
+ if (existingG === void 0 || tentativeG < existingG) {
3504
+ gScore.set(nKey, tentativeG);
3505
+ cameFrom.set(nKey, curKey);
3506
+ const nh = heuristic(nx, ny);
3507
+ open.push({
3508
+ x: nx,
3509
+ y: ny,
3510
+ g: tentativeG,
3511
+ h: nh,
3512
+ f: tentativeG + nh,
3513
+ order: counter++
3514
+ });
3515
+ }
3516
+ }
3517
+ }
3518
+ return [];
3519
+ }
3520
+ function evalPathReachable(args, evaluate2, ctx) {
3521
+ const start = asCell2(evaluate2(args[0], ctx));
3522
+ const steps = Math.floor(evaluate2(args[1], ctx));
3523
+ const blockedArr = evaluate2(args[2], ctx) ?? [];
3524
+ const w = evaluate2(args[3], ctx);
3525
+ const h = evaluate2(args[4], ctx);
3526
+ const diagonal = args.length > 5 ? Boolean(evaluate2(args[5], ctx)) : false;
3527
+ const blocked = blockedSet(blockedArr);
3528
+ const dirs = neighbors(diagonal);
3529
+ const startKey = key(start.x, start.y);
3530
+ const visited = /* @__PURE__ */ new Set();
3531
+ if (start.x < 0 || start.x >= w || start.y < 0 || start.y >= h || blocked.has(startKey)) {
3532
+ return [];
3533
+ }
3534
+ visited.add(startKey);
3535
+ let frontier = [{ x: start.x, y: start.y }];
3536
+ for (let depth = 0; depth < steps; depth++) {
3537
+ const next = [];
3538
+ for (const cell of frontier) {
3539
+ for (const [dx, dy] of dirs) {
3540
+ const nx = cell.x + dx;
3541
+ const ny = cell.y + dy;
3542
+ if (nx < 0 || nx >= w || ny < 0 || ny >= h) {
3543
+ continue;
3544
+ }
3545
+ const nKey = key(nx, ny);
3546
+ if (blocked.has(nKey) || visited.has(nKey)) {
3547
+ continue;
3548
+ }
3549
+ visited.add(nKey);
3550
+ next.push({ x: nx, y: ny });
3551
+ }
3552
+ }
3553
+ frontier = next;
3554
+ }
3555
+ const result = [];
3556
+ for (const k of visited) {
3557
+ const parts = k.split(",");
3558
+ result.push({ x: Number(parts[0]), y: Number(parts[1]) });
3559
+ }
3560
+ result.sort((a, b) => a.y !== b.y ? a.y - b.y : a.x - b.x);
3561
+ return result;
3562
+ }
3563
+
2578
3564
  // SExpressionEvaluator.ts
2579
3565
  var jitCache = /* @__PURE__ */ new Map();
2580
3566
  var MAX_JIT_CACHE_SIZE = 1e3;
@@ -2646,8 +3632,8 @@ var SExpressionEvaluator = class {
2646
3632
  * @returns Function that evaluates the expression given a context
2647
3633
  */
2648
3634
  compile(expr) {
2649
- const key = JSON.stringify(expr);
2650
- const cached = jitCache.get(key);
3635
+ const key2 = JSON.stringify(expr);
3636
+ const cached = jitCache.get(key2);
2651
3637
  if (cached) {
2652
3638
  return cached;
2653
3639
  }
@@ -2658,7 +3644,7 @@ var SExpressionEvaluator = class {
2658
3644
  jitCache.delete(firstKey);
2659
3645
  }
2660
3646
  }
2661
- jitCache.set(key, fn);
3647
+ jitCache.set(key2, fn);
2662
3648
  return fn;
2663
3649
  }
2664
3650
  /**
@@ -2841,6 +3827,127 @@ var SExpressionEvaluator = class {
2841
3827
  return evalMathRandomInt(args, evaluate2, ctx);
2842
3828
  case "math/default":
2843
3829
  return evalMathDefault(args, evaluate2, ctx);
3830
+ case "math/sin":
3831
+ return evalMathSin(args, evaluate2, ctx);
3832
+ case "math/cos":
3833
+ return evalMathCos(args, evaluate2, ctx);
3834
+ case "math/tan":
3835
+ return evalMathTan(args, evaluate2, ctx);
3836
+ case "math/atan2":
3837
+ return evalMathAtan2(args, evaluate2, ctx);
3838
+ case "math/hypot":
3839
+ return evalMathHypot(args, evaluate2, ctx);
3840
+ case "math/deg-rad":
3841
+ return evalMathDegRad(args, evaluate2, ctx);
3842
+ case "math/rad-deg":
3843
+ return evalMathRadDeg(args, evaluate2, ctx);
3844
+ case "math/wrap":
3845
+ return evalMathWrap(args, evaluate2, ctx);
3846
+ case "math/approach":
3847
+ return evalMathApproach(args, evaluate2, ctx);
3848
+ // ===============================
3849
+ // Standard Library: vec/*
3850
+ // ===============================
3851
+ case "vec/add":
3852
+ return evalVecAdd(args, evaluate2, ctx);
3853
+ case "vec/sub":
3854
+ return evalVecSub(args, evaluate2, ctx);
3855
+ case "vec/scale":
3856
+ return evalVecScale(args, evaluate2, ctx);
3857
+ case "vec/dot":
3858
+ return evalVecDot(args, evaluate2, ctx);
3859
+ case "vec/cross":
3860
+ return evalVecCross(args, evaluate2, ctx);
3861
+ case "vec/length":
3862
+ return evalVecLength(args, evaluate2, ctx);
3863
+ case "vec/length-sq":
3864
+ return evalVecLengthSq(args, evaluate2, ctx);
3865
+ case "vec/normalize":
3866
+ return evalVecNormalize(args, evaluate2, ctx);
3867
+ case "vec/distance":
3868
+ return evalVecDistance(args, evaluate2, ctx);
3869
+ case "vec/distance-sq":
3870
+ return evalVecDistanceSq(args, evaluate2, ctx);
3871
+ case "vec/lerp":
3872
+ return evalVecLerp(args, evaluate2, ctx);
3873
+ case "vec/angle":
3874
+ return evalVecAngle(args, evaluate2, ctx);
3875
+ case "vec/rotate":
3876
+ return evalVecRotate(args, evaluate2, ctx);
3877
+ case "vec/clamp-length":
3878
+ return evalVecClampLength(args, evaluate2, ctx);
3879
+ // ===============================
3880
+ // Standard Library: geo/*
3881
+ // ===============================
3882
+ case "geo/aabb-overlap":
3883
+ return evalGeoAabbOverlap(args, evaluate2, ctx);
3884
+ case "geo/circle-overlap":
3885
+ return evalGeoCircleOverlap(args, evaluate2, ctx);
3886
+ case "geo/rect-circle-overlap":
3887
+ return evalGeoRectCircleOverlap(args, evaluate2, ctx);
3888
+ case "geo/point-in-rect":
3889
+ return evalGeoPointInRect(args, evaluate2, ctx);
3890
+ case "geo/point-in-circle":
3891
+ return evalGeoPointInCircle(args, evaluate2, ctx);
3892
+ case "geo/reflect":
3893
+ return evalGeoReflect(args, evaluate2, ctx);
3894
+ case "geo/segment-intersect":
3895
+ return evalGeoSegmentIntersect(args, evaluate2, ctx);
3896
+ // ===============================
3897
+ // Standard Library: grid/*
3898
+ // ===============================
3899
+ case "grid/to-world":
3900
+ return evalGridToWorld(args, evaluate2, ctx);
3901
+ case "grid/from-world":
3902
+ return evalGridFromWorld(args, evaluate2, ctx);
3903
+ case "grid/iso-to-screen":
3904
+ return evalGridIsoToScreen(args, evaluate2, ctx);
3905
+ case "grid/screen-to-iso":
3906
+ return evalGridScreenToIso(args, evaluate2, ctx);
3907
+ case "grid/distance":
3908
+ return evalGridDistance(args, evaluate2, ctx);
3909
+ case "grid/manhattan-distance":
3910
+ return evalGridManhattanDistance(args, evaluate2, ctx);
3911
+ case "grid/neighbors":
3912
+ return evalGridNeighbors(args, evaluate2, ctx);
3913
+ case "grid/cells-in-radius":
3914
+ return evalGridCellsInRadius(args, evaluate2, ctx);
3915
+ case "grid/line":
3916
+ return evalGridLine(args, evaluate2, ctx);
3917
+ case "grid/in-bounds":
3918
+ return evalGridInBounds(args, evaluate2, ctx);
3919
+ // ===============================
3920
+ // Standard Library: anim/*
3921
+ // ===============================
3922
+ case "anim/frame-at":
3923
+ return evalAnimFrameAt(args, evaluate2, ctx);
3924
+ case "anim/sheet-rect":
3925
+ return evalAnimSheetRect(args, evaluate2, ctx);
3926
+ case "anim/direction-from-delta":
3927
+ return evalAnimDirectionFromDelta(args, evaluate2, ctx);
3928
+ // ===============================
3929
+ // Standard Library: ease/*
3930
+ // ===============================
3931
+ case "ease/apply":
3932
+ return evalEaseApply(args, evaluate2, ctx);
3933
+ case "ease/smoothstep":
3934
+ return evalEaseSmoothstep(args, evaluate2, ctx);
3935
+ // ===============================
3936
+ // Standard Library: noise/*
3937
+ // ===============================
3938
+ case "noise/perlin":
3939
+ return evalNoisePerlin(args, evaluate2, ctx);
3940
+ case "noise/simplex":
3941
+ return evalNoiseSimplex(args, evaluate2, ctx);
3942
+ case "noise/fbm":
3943
+ return evalNoiseFbm(args, evaluate2, ctx);
3944
+ // ===============================
3945
+ // Standard Library: path/*
3946
+ // ===============================
3947
+ case "path/astar":
3948
+ return evalPathAstar(args, evaluate2, ctx);
3949
+ case "path/reachable":
3950
+ return evalPathReachable(args, evaluate2, ctx);
2844
3951
  // ===============================
2845
3952
  // Standard Library: str/*
2846
3953
  // ===============================