@idle-screens/saver-metaquarium 0.6.0 → 0.7.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/README.md +4 -1
- package/dist/{chunk-O676ILL6.js → chunk-RTUYWDDZ.js} +156 -21
- package/dist/chunk-RTUYWDDZ.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/{manifest-C2vsSgNu.d.ts → manifest-C25MXGwc.d.ts} +259 -156
- package/dist/manifest.d.ts +1 -1
- package/dist/manifest.js +13 -1
- package/dist/{tank-D3XVDWJM.js → tank-HZJV2GD7.js} +243 -19
- package/dist/tank-HZJV2GD7.js.map +1 -0
- package/package.json +3 -3
- package/dist/chunk-O676ILL6.js.map +0 -1
- package/dist/tank-D3XVDWJM.js.map +0 -1
package/README.md
CHANGED
|
@@ -58,12 +58,15 @@ frame loop (rAF or renderFrame(t)):
|
|
|
58
58
|
| swimSpeed | number | 1 | Swim time-scale multiplier |
|
|
59
59
|
| fogColor | color | #030009 | Atmosphere / background |
|
|
60
60
|
| fishUrl | string | ipfs://…/fish_257_….glb | GLB model URL, single-breed mode (playground can override to a local asset) |
|
|
61
|
-
| fishMix | string | "" | Mixed population DSL: `id[:count]` comma-separated, catalog ids or breed aliases (`"257:2,100:1"`). Non-empty overrides fishUrl + fishCount; counts absolute, tier-capped |
|
|
61
|
+
| fishMix | string | "" | Mixed population DSL: `id[:count][@style]` comma-separated, catalog ids or breed aliases (`"257:2,100:1"`, `"457:3@hover,257:6@school"` — per-token swim style; untagged tokens follow `swimStyle`). Non-empty overrides fishUrl + fishCount; counts absolute, tier-capped |
|
|
62
62
|
| fogNear | number | 60 | Fog start distance (the old hardcoded Fog near) |
|
|
63
63
|
| fogFar | number | 500 | Fog full-opacity distance; tank enforces > near + 20 |
|
|
64
64
|
| moteDensity | number | 0 | Plankton motes, 0–1 of the tier budget (400/250/120). 0 = off |
|
|
65
65
|
| moteColor | color | #7fd6ff | Mote tint |
|
|
66
66
|
| floorColor | color | #0a1d33 | Floor disc color (the old hardcoded navy) |
|
|
67
|
+
| swimStyle | enum | loop | `loop` (pre-style), `school`, `drift`, `hover`, `patrol`, `bottom`, `surface`; relationship styles `follow` / `pair` / `chase` bond a fish to the nearest preceding unbonded fish in the mix (and swim in its depth band); `auto` gives each untagged token its breed's default |
|
|
68
|
+
| lightSeek | number | 0 | Free fish drawn toward the room's light shafts, each to its own pool (needs rays) |
|
|
69
|
+
| formationBreathe | number | 0 | The school relaxes outward and back on a ~15 s cycle; only ever expands |
|
|
67
70
|
|
|
68
71
|
## File map
|
|
69
72
|
|
|
@@ -94,8 +94,44 @@ var SWIM_STYLES = [
|
|
|
94
94
|
{ name: "hover", label: "Hover", speedMul: 0.55, band: "free", bobAmp: 7, bobHz: 0.3, formation: false, travel: 0.12 },
|
|
95
95
|
{ name: "patrol", label: "Patrol", speedMul: 0.55, band: "mid", bobAmp: 1, bobHz: 0.09, formation: false, travel: 1 },
|
|
96
96
|
{ name: "bottom", label: "Bottom-hugger", speedMul: 0.7, band: "floor", bobAmp: 2, bobHz: 0.4, formation: false, travel: 1 },
|
|
97
|
-
{ name: "surface", label: "Surface-skimmer", speedMul: 0.9, band: "ceiling", bobAmp: 3, bobHz: 0.55, formation: false, travel: 1 }
|
|
97
|
+
{ name: "surface", label: "Surface-skimmer", speedMul: 0.9, band: "ceiling", bobAmp: 3, bobHz: 0.55, formation: false, travel: 1 },
|
|
98
|
+
// Relationships (MQ31). A bonded fish has no route of its own: it rides
|
|
99
|
+
// its leader's plan at a lag, so a `@follow` trio behind a turtle is a
|
|
100
|
+
// file, a `@pair` couple orbits a shared point, and a `@chase` closes on
|
|
101
|
+
// its leader and falls back. All three stay pure in t because the leader
|
|
102
|
+
// is — the follower samples the SAME closed form at `d - lag`.
|
|
103
|
+
{ name: "follow", label: "Follower", speedMul: 1, band: "free", bobAmp: 1.2, bobHz: 0.5, formation: false, travel: 1, bond: "follow" },
|
|
104
|
+
{ name: "pair", label: "Pair", speedMul: 0.8, band: "free", bobAmp: 2.5, bobHz: 0.35, formation: false, travel: 1, bond: "pair" },
|
|
105
|
+
{ name: "chase", label: "Chaser", speedMul: 1, band: "free", bobAmp: 1, bobHz: 0.6, formation: false, travel: 1, bond: "chase" }
|
|
98
106
|
];
|
|
107
|
+
var AUTO_STYLE_BY_BREED = {
|
|
108
|
+
angelfish: "school",
|
|
109
|
+
betafish: "drift",
|
|
110
|
+
seahorse: "hover",
|
|
111
|
+
seaturtle: "surface",
|
|
112
|
+
// The unminted NPC set.
|
|
113
|
+
blowfish: "hover",
|
|
114
|
+
hackerfish: "loop",
|
|
115
|
+
glowfish: "drift",
|
|
116
|
+
babyfish: "school",
|
|
117
|
+
shark: "patrol",
|
|
118
|
+
crab: "bottom",
|
|
119
|
+
jellyfish: "drift",
|
|
120
|
+
dori: "school"
|
|
121
|
+
};
|
|
122
|
+
function autoStyleFor(breed) {
|
|
123
|
+
const name = breed ? AUTO_STYLE_BY_BREED[breed.toLowerCase()] : void 0;
|
|
124
|
+
return swimStyleOf(name ?? "loop");
|
|
125
|
+
}
|
|
126
|
+
function formationBreathe(tSec, amount) {
|
|
127
|
+
const a = Math.max(0, Math.min(1, amount));
|
|
128
|
+
if (a <= 0) return 1;
|
|
129
|
+
return 1 + a * 0.22 * (0.5 + 0.5 * Math.sin(tSec * 0.42));
|
|
130
|
+
}
|
|
131
|
+
function idleSway(style, tSec, phase) {
|
|
132
|
+
if (style.travel >= 1 || style.formation) return 0;
|
|
133
|
+
return (1 - style.travel) * 0.5 * Math.sin(tSec * 0.45 + phase);
|
|
134
|
+
}
|
|
99
135
|
var SWIM_STYLE_NAMES = SWIM_STYLES.map((s) => s.name);
|
|
100
136
|
function swimStyleOf(name) {
|
|
101
137
|
return SWIM_STYLES.find((s) => s.name === name) ?? SWIM_STYLES[0];
|
|
@@ -128,7 +164,7 @@ function anchorFraction(style, index, variance) {
|
|
|
128
164
|
}
|
|
129
165
|
var FISH_LENGTH = 18;
|
|
130
166
|
var FORMATION_HALF_WIDTH = 62;
|
|
131
|
-
var FORMATION_SHAPES = ["phalanx", "line", "ring", "wedge", "ball"];
|
|
167
|
+
var FORMATION_SHAPES = ["phalanx", "line", "ring", "wedge", "ball", "wheel"];
|
|
132
168
|
function formationSlot(index, count, variance, halfWidth = FORMATION_HALF_WIDTH, shape = "phalanx") {
|
|
133
169
|
const j = 0.35 + 0.65 * Math.max(0, Math.min(1, variance));
|
|
134
170
|
if (shape === "line") {
|
|
@@ -152,6 +188,15 @@ function formationSlot(index, count, variance, halfWidth = FORMATION_HALF_WIDTH,
|
|
|
152
188
|
back: Math.sin(a) * r
|
|
153
189
|
};
|
|
154
190
|
}
|
|
191
|
+
if (shape === "wheel") {
|
|
192
|
+
const r = Math.max(FISH_LENGTH * 1.6, count * FISH_LENGTH * 1.35 / (Math.PI * 2));
|
|
193
|
+
const a = index / Math.max(1, count) * Math.PI * 2;
|
|
194
|
+
return {
|
|
195
|
+
side: Math.cos(a) * r,
|
|
196
|
+
up: Math.sin(a) * Math.min(r * 0.55, 24) + (fishHash(index, 5) - 0.5) * FISH_LENGTH * 0.3 * j,
|
|
197
|
+
back: Math.sin(a) * r
|
|
198
|
+
};
|
|
199
|
+
}
|
|
155
200
|
if (shape === "wedge") {
|
|
156
201
|
const VSIZE = 9;
|
|
157
202
|
const layers = Math.ceil(Math.max(1, count) / VSIZE);
|
|
@@ -210,6 +255,12 @@ function formationExtent(count, variance, shape = "phalanx") {
|
|
|
210
255
|
}
|
|
211
256
|
return { side, up, back, reach };
|
|
212
257
|
}
|
|
258
|
+
function fitBreath(extent, lattice, bounds, margin = FISH_LENGTH * 0.5) {
|
|
259
|
+
let fit = lattice;
|
|
260
|
+
if (extent.up > 0) fit = Math.min(fit, Math.max(1, (bounds.yRange / 2 - margin) / extent.up));
|
|
261
|
+
if (extent.reach > 0) fit = Math.min(fit, Math.max(1, (bounds.radius - margin) / extent.reach));
|
|
262
|
+
return fit;
|
|
263
|
+
}
|
|
213
264
|
function bandRange(band) {
|
|
214
265
|
switch (band) {
|
|
215
266
|
// Tight, because 0..0.3 of a 57-unit volume is nearly two body lengths of
|
|
@@ -247,10 +298,32 @@ function splineAt(points, g) {
|
|
|
247
298
|
catmullRom(p0[2], p1[2], p2[2], p3[2], u)
|
|
248
299
|
];
|
|
249
300
|
}
|
|
250
|
-
var PATH_SHAPES = ["wander", "orbit", "eight", "helix", "canyon"];
|
|
251
|
-
function shapeWaypoints(shape, rng, bounds) {
|
|
301
|
+
var PATH_SHAPES = ["wander", "orbit", "eight", "helix", "canyon", "crossing"];
|
|
302
|
+
function shapeWaypoints(shape, rng, bounds, opts = {}) {
|
|
252
303
|
const points = [];
|
|
253
304
|
const ySpan = bounds.yMax - bounds.yMin;
|
|
305
|
+
if (shape === "crossing") {
|
|
306
|
+
const n2 = 16;
|
|
307
|
+
const az = (opts.cameraAzimuthDeg ?? 0) * Math.PI / 180;
|
|
308
|
+
const rx = Math.cos(az), rz = -Math.sin(az);
|
|
309
|
+
const dx = Math.sin(az), dz = Math.cos(az);
|
|
310
|
+
const len = bounds.radius * 0.9;
|
|
311
|
+
const depth = bounds.radius * rng.range(0.18, 0.3);
|
|
312
|
+
const y0 = bounds.yMin + ySpan * rng.range(0.35, 0.6);
|
|
313
|
+
const lift = ySpan * rng.range(0.04, 0.1);
|
|
314
|
+
for (let i = 0; i < n2; i++) {
|
|
315
|
+
const u = i / n2 * Math.PI * 2;
|
|
316
|
+
const along = Math.sin(u) * len;
|
|
317
|
+
const toward = Math.cos(u) * depth;
|
|
318
|
+
points.push([
|
|
319
|
+
rx * along + dx * toward,
|
|
320
|
+
// The far leg rides a little higher so it never hides behind the near one.
|
|
321
|
+
y0 + (toward < 0 ? lift : 0) + ySpan * rng.range(0, 0.04),
|
|
322
|
+
rz * along + dz * toward
|
|
323
|
+
]);
|
|
324
|
+
}
|
|
325
|
+
return points;
|
|
326
|
+
}
|
|
254
327
|
if (shape === "orbit") {
|
|
255
328
|
const n2 = 14 + rng.int(0, 4);
|
|
256
329
|
const r0 = bounds.radius * rng.range(0.45, 0.8);
|
|
@@ -325,8 +398,8 @@ function shapeWaypoints(shape, rng, bounds) {
|
|
|
325
398
|
}
|
|
326
399
|
return points;
|
|
327
400
|
}
|
|
328
|
-
function compileSwimPlan(rng, bounds, shape = "wander") {
|
|
329
|
-
const points = shapeWaypoints(shape, rng, bounds);
|
|
401
|
+
function compileSwimPlan(rng, bounds, shape = "wander", opts = {}) {
|
|
402
|
+
const points = shapeWaypoints(shape, rng, bounds, opts);
|
|
330
403
|
const n = points.length;
|
|
331
404
|
const arc = new Float32Array(ARC_SAMPLES + 1);
|
|
332
405
|
let prev = splineAt(points, 0);
|
|
@@ -1126,6 +1199,20 @@ function parseFishMix(mix, catalog = FISH_CATALOG) {
|
|
|
1126
1199
|
const problems = [];
|
|
1127
1200
|
const unique = catalog === FISH_CATALOG;
|
|
1128
1201
|
const used = /* @__PURE__ */ new Set();
|
|
1202
|
+
const resolvesAsToken = (core) => {
|
|
1203
|
+
const [idRaw, countRaw, ...extra] = core.split(":");
|
|
1204
|
+
if (extra.length > 0) return false;
|
|
1205
|
+
if (countRaw !== void 0) {
|
|
1206
|
+
const count = Number(countRaw.trim());
|
|
1207
|
+
if (!Number.isInteger(count) || count < 1) return false;
|
|
1208
|
+
}
|
|
1209
|
+
const key = (idRaw ?? "").trim().toLowerCase();
|
|
1210
|
+
if (/^\d+$/.test(key)) {
|
|
1211
|
+
if (catalog.some((fish) => fish.id === Number(key))) return true;
|
|
1212
|
+
return catalog === FISH_CATALOG && fishAsset(Number(key), "3d") !== null && breedOf(Number(key)) !== null;
|
|
1213
|
+
}
|
|
1214
|
+
return catalog.some((fish) => fish.breed.toLowerCase() === key);
|
|
1215
|
+
};
|
|
1129
1216
|
const allocate = (breed, want) => {
|
|
1130
1217
|
const b = BREEDS.find((x) => x.breed === breed);
|
|
1131
1218
|
if (!b?.range) return null;
|
|
@@ -1147,7 +1234,22 @@ function parseFishMix(mix, catalog = FISH_CATALOG) {
|
|
|
1147
1234
|
for (const rawToken of mix.split(",")) {
|
|
1148
1235
|
const token = rawToken.trim();
|
|
1149
1236
|
if (token === "") continue;
|
|
1150
|
-
|
|
1237
|
+
let style;
|
|
1238
|
+
let core = token;
|
|
1239
|
+
const at = token.lastIndexOf("@");
|
|
1240
|
+
if (at >= 0) {
|
|
1241
|
+
const styleRaw = token.slice(at + 1).trim().toLowerCase();
|
|
1242
|
+
const styledCore = token.slice(0, at).trim();
|
|
1243
|
+
if (resolvesAsToken(token)) {
|
|
1244
|
+
} else if (SWIM_STYLE_NAMES.includes(styleRaw)) {
|
|
1245
|
+
core = styledCore;
|
|
1246
|
+
style = styleRaw;
|
|
1247
|
+
} else if (resolvesAsToken(styledCore)) {
|
|
1248
|
+
core = styledCore;
|
|
1249
|
+
problems.push(`"${token}": unknown style "${styleRaw}" (${SWIM_STYLE_NAMES.join(", ")}) \u2014 swimming with the scene's swimStyle`);
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
const [idRaw, countRaw, ...extra] = core.split(":");
|
|
1151
1253
|
if (extra.length > 0) {
|
|
1152
1254
|
problems.push(`"${token}": too many ':' \u2014 expected id[:count]`);
|
|
1153
1255
|
continue;
|
|
@@ -1187,12 +1289,12 @@ function parseFishMix(mix, catalog = FISH_CATALOG) {
|
|
|
1187
1289
|
}
|
|
1188
1290
|
}
|
|
1189
1291
|
if (!unique || fish.id > TOTAL_SUPPLY) {
|
|
1190
|
-
entries.push({ id: fish.id, url, count });
|
|
1292
|
+
entries.push({ id: fish.id, breed: fish.breed, url, count, ...style ? { style } : {} });
|
|
1191
1293
|
continue;
|
|
1192
1294
|
}
|
|
1193
1295
|
const breed = breedOf(fish.id);
|
|
1194
1296
|
if (!breed) {
|
|
1195
|
-
entries.push({ id: fish.id, url, count });
|
|
1297
|
+
entries.push({ id: fish.id, breed: fish.breed, url, count, ...style ? { style } : {} });
|
|
1196
1298
|
continue;
|
|
1197
1299
|
}
|
|
1198
1300
|
const isAlias = !/^\d+$/.test(key);
|
|
@@ -1212,17 +1314,22 @@ function parseFishMix(mix, catalog = FISH_CATALOG) {
|
|
|
1212
1314
|
problems.push(`fish ${got}: no asset URL`);
|
|
1213
1315
|
continue;
|
|
1214
1316
|
}
|
|
1215
|
-
entries.push({ id: got, url: gotUrl, count: 1 });
|
|
1317
|
+
entries.push({ id: got, breed: fish.breed, url: gotUrl, count: 1, ...style ? { style } : {} });
|
|
1216
1318
|
}
|
|
1217
1319
|
}
|
|
1218
1320
|
return { entries, problems };
|
|
1219
1321
|
}
|
|
1220
1322
|
function expandFishMix(entries, cap) {
|
|
1221
|
-
|
|
1323
|
+
return expandFishMixSlots(entries, cap).map((s) => s.url);
|
|
1324
|
+
}
|
|
1325
|
+
function expandFishMixSlots(entries, cap) {
|
|
1326
|
+
const slots = [];
|
|
1222
1327
|
for (const e of entries) {
|
|
1223
|
-
for (let i = 0; i < e.count &&
|
|
1328
|
+
for (let i = 0; i < e.count && slots.length < cap; i++) {
|
|
1329
|
+
slots.push(e.style ? { url: e.url, breed: e.breed, style: e.style } : { url: e.url, breed: e.breed });
|
|
1330
|
+
}
|
|
1224
1331
|
}
|
|
1225
|
-
return
|
|
1332
|
+
return slots;
|
|
1226
1333
|
}
|
|
1227
1334
|
|
|
1228
1335
|
// src/manifest.ts
|
|
@@ -1254,7 +1361,10 @@ var METAQUARIUM_PARAMS = {
|
|
|
1254
1361
|
* different angelfish). A custom catalog is a closed world (no farm/IPFS
|
|
1255
1362
|
* fallback, no uniqueness — NPC entries are species). Counts are
|
|
1256
1363
|
* absolute; the expanded total clamps to the device tier's fish cap.
|
|
1257
|
-
*
|
|
1364
|
+
* A token may carry its own swim style — `id[:count]@style`, e.g.
|
|
1365
|
+
* "457:3@hover,257:6@school,497:1@surface" — so one tank holds several
|
|
1366
|
+
* behaviours; untagged tokens follow `swimStyle`. Non-empty mix
|
|
1367
|
+
* OVERRIDES fishUrl and fishCount; empty string = single-
|
|
1258
1368
|
* breed mode. Unknown ids/bad counts degrade (good tokens still parse);
|
|
1259
1369
|
* raw URLs are not accepted here — use fishUrl for a custom single-breed GLB. */
|
|
1260
1370
|
fishMix: { type: "string", default: "", ease: "step" },
|
|
@@ -1296,15 +1406,23 @@ var METAQUARIUM_PARAMS = {
|
|
|
1296
1406
|
rayStrength: { type: "number", default: -1, min: -1, max: 1, ease: "step" },
|
|
1297
1407
|
/** How the fish move. `loop` is exactly the pre-style behaviour, so the
|
|
1298
1408
|
* default changes nothing. A small named set on purpose: a silhouette of
|
|
1299
|
-
* movement you can name is one you can choose from.
|
|
1300
|
-
|
|
1409
|
+
* movement you can name is one you can choose from. `auto` lets each
|
|
1410
|
+
* untagged fishMix token swim the way its breed does (seahorse hover,
|
|
1411
|
+
* turtle skim the surface, angelfish school, betafish drift); a token's
|
|
1412
|
+
* `@style` still wins. The relationship styles — `follow`, `pair`,
|
|
1413
|
+
* `chase` — bond a fish to the nearest preceding unbonded fish in the mix
|
|
1414
|
+
* (`seaturtle:1, 257:3@follow` is a turtle with an escort). */
|
|
1415
|
+
swimStyle: { type: "enum", default: "loop", options: [...SWIM_STYLE_NAMES, "auto"], ease: "step" },
|
|
1301
1416
|
/** The shape a fish's loop is drawn on. `wander` is the original roaming
|
|
1302
1417
|
* itinerary, so the default changes nothing. `orbit` laps, `eight` crosses
|
|
1303
|
-
* the middle, `helix` tours the water column, `canyon` sweeps low
|
|
1304
|
-
*
|
|
1418
|
+
* the middle, `helix` tours the water column, `canyon` sweeps low,
|
|
1419
|
+
* `crossing` is a camera-relative parade lane (across the frame in front,
|
|
1420
|
+
* back the other way behind; laid against cameraAzimuth when chosen) —
|
|
1421
|
+
* same spline engine, different itinerary. */
|
|
1305
1422
|
pathShape: { type: "enum", default: "wander", options: [...PATH_SHAPES], ease: "step" },
|
|
1306
1423
|
/** How a `school` holds together: the original lattice, single file, a
|
|
1307
|
-
* carousel ring, the migratory V,
|
|
1424
|
+
* carousel ring, the migratory V, a bait-ball, or the ring tilted into a
|
|
1425
|
+
* `wheel` that reads from a side camera. Ignored by every
|
|
1308
1426
|
* non-formation style; the same no-pair-inside-a-body-length law holds
|
|
1309
1427
|
* for all of them. */
|
|
1310
1428
|
formationShape: { type: "enum", default: "phalanx", options: [...FORMATION_SHAPES], ease: "step" },
|
|
@@ -1333,7 +1451,18 @@ var METAQUARIUM_PARAMS = {
|
|
|
1333
1451
|
* behaviour, and a scene already on someone's wall should not start moving
|
|
1334
1452
|
* differently because a dependency was bumped. 0.3–0.4 is the recommended
|
|
1335
1453
|
* value for a clip-less cast — the studio swim variants all set it. */
|
|
1336
|
-
bodyWiggle: { type: "number", default: 0, min: 0, max: 1, ease: "smooth" }
|
|
1454
|
+
bodyWiggle: { type: "number", default: 0, min: 0, max: 1, ease: "smooth" },
|
|
1455
|
+
/** Light-seeking: free-swimming fish are drawn toward the room's light
|
|
1456
|
+
* shafts, each fish to its own pool. 0 (default) leaves every route
|
|
1457
|
+
* where it was; 1 pulls a fish most of the way into its shaft, so the
|
|
1458
|
+
* cast gathers in the light and a `rayStrength` dial becomes a staging
|
|
1459
|
+
* dial too. Needs a room with rays; formations are steered by their
|
|
1460
|
+
* carrier and ignore it. */
|
|
1461
|
+
lightSeek: { type: "number", default: 0, min: 0, max: 1, ease: "smooth" },
|
|
1462
|
+
/** Formation breathing: the school relaxes outward and draws back in on a
|
|
1463
|
+
* slow (~15 s) cycle. 0 (default) is the rigid lattice; 1 opens it by up
|
|
1464
|
+
* to a fifth. Only ever expands, so the spacing guarantee holds. */
|
|
1465
|
+
formationBreathe: { type: "number", default: 0, min: 0, max: 1, ease: "smooth" }
|
|
1337
1466
|
};
|
|
1338
1467
|
var MIAMI_VICE_COLORS = [
|
|
1339
1468
|
"#ff6ad5",
|
|
@@ -1431,6 +1560,10 @@ export {
|
|
|
1431
1560
|
RAY_COUNT,
|
|
1432
1561
|
affordableLayers,
|
|
1433
1562
|
SWIM_STYLES,
|
|
1563
|
+
AUTO_STYLE_BY_BREED,
|
|
1564
|
+
autoStyleFor,
|
|
1565
|
+
formationBreathe,
|
|
1566
|
+
idleSway,
|
|
1434
1567
|
SWIM_STYLE_NAMES,
|
|
1435
1568
|
swimStyleOf,
|
|
1436
1569
|
fishHash,
|
|
@@ -1440,6 +1573,7 @@ export {
|
|
|
1440
1573
|
FORMATION_SHAPES,
|
|
1441
1574
|
formationSlot,
|
|
1442
1575
|
formationExtent,
|
|
1576
|
+
fitBreath,
|
|
1443
1577
|
bandRange,
|
|
1444
1578
|
PATH_SHAPES,
|
|
1445
1579
|
compileSwimPlan,
|
|
@@ -1467,6 +1601,7 @@ export {
|
|
|
1467
1601
|
NPC_CATALOG,
|
|
1468
1602
|
parseFishMix,
|
|
1469
1603
|
expandFishMix,
|
|
1604
|
+
expandFishMixSlots,
|
|
1470
1605
|
METAQUARIUM_PARAMS,
|
|
1471
1606
|
MIAMI_VICE_COLORS,
|
|
1472
1607
|
BLOOM_COLORS,
|
|
@@ -1475,4 +1610,4 @@ export {
|
|
|
1475
1610
|
paramSpaceWith,
|
|
1476
1611
|
coerceNum
|
|
1477
1612
|
};
|
|
1478
|
-
//# sourceMappingURL=chunk-
|
|
1613
|
+
//# sourceMappingURL=chunk-RTUYWDDZ.js.map
|