piximps 0.1.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.
Files changed (40) hide show
  1. package/.github/workflows/ci.yml +20 -0
  2. package/.github/workflows/demo.yml +22 -0
  3. package/.github/workflows/release.yml +22 -0
  4. package/README.md +110 -0
  5. package/docs/browser.global.js +1539 -0
  6. package/docs/index.html +442 -0
  7. package/package.json +42 -0
  8. package/src/piximps/browser.ts +114 -0
  9. package/src/piximps/common/templates/accessories.ts +174 -0
  10. package/src/piximps/common/templates/body.ts +390 -0
  11. package/src/piximps/common/templates/eyes.ts +95 -0
  12. package/src/piximps/common/templates/horns.ts +152 -0
  13. package/src/piximps/common/templates/mouth.ts +96 -0
  14. package/src/piximps/common/templates/types.ts +4 -0
  15. package/src/piximps/domain/color-palette.ts +22 -0
  16. package/src/piximps/domain/imp-traits.ts +35 -0
  17. package/src/piximps/domain/template.ts +35 -0
  18. package/src/piximps/domain/types.ts +34 -0
  19. package/src/piximps/entrypoints/renderers/to-png-binary.ts +13 -0
  20. package/src/piximps/entrypoints/renderers/to-rgba-buffer.ts +26 -0
  21. package/src/piximps/entrypoints/renderers/to-svg-string.ts +28 -0
  22. package/src/piximps/index.ts +117 -0
  23. package/src/piximps/services/edge-detector.ts +60 -0
  24. package/src/piximps/services/hash-to-byte-sequence.ts +75 -0
  25. package/src/piximps/services/layer-compositor.ts +157 -0
  26. package/src/piximps/services/palette-deriver.ts +75 -0
  27. package/src/piximps/services/trait-extractor.ts +88 -0
  28. package/tests/functional/test-domain-models.test.ts +136 -0
  29. package/tests/functional/test-edge-detector.test.ts +64 -0
  30. package/tests/functional/test-hash-to-byte-sequence.test.ts +39 -0
  31. package/tests/functional/test-layer-compositor.test.ts +107 -0
  32. package/tests/functional/test-palette-deriver.test.ts +43 -0
  33. package/tests/functional/test-renderers.test.ts +105 -0
  34. package/tests/functional/test-trait-extractor.test.ts +50 -0
  35. package/tests/integration/test-determinism.test.ts +40 -0
  36. package/tests/integration/test-generator-builder.test.ts +56 -0
  37. package/tests/integration/test-output-formats.test.ts +47 -0
  38. package/tsconfig.json +24 -0
  39. package/tsup.config.ts +11 -0
  40. package/vitest.config.ts +18 -0
@@ -0,0 +1,1539 @@
1
+ "use strict";
2
+ var Piximps = (() => {
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/piximps/browser.ts
22
+ var browser_exports = {};
23
+ __export(browser_exports, {
24
+ ImpGenerator: () => ImpGenerator
25
+ });
26
+
27
+ // src/piximps/services/hash-to-byte-sequence.ts
28
+ function murmurhash3_32(key, seed) {
29
+ let h1 = seed >>> 0;
30
+ const remainder = key.length & 3;
31
+ const bytes = key.length - remainder;
32
+ const c1 = 3432918353;
33
+ const c2 = 461845907;
34
+ let i = 0;
35
+ while (i < bytes) {
36
+ let k12 = key.charCodeAt(i) & 255 | (key.charCodeAt(i + 1) & 255) << 8 | (key.charCodeAt(i + 2) & 255) << 16 | (key.charCodeAt(i + 3) & 255) << 24;
37
+ i += 4;
38
+ k12 = Math.imul(k12, c1);
39
+ k12 = k12 << 15 | k12 >>> 17;
40
+ k12 = Math.imul(k12, c2);
41
+ h1 ^= k12;
42
+ h1 = h1 << 13 | h1 >>> 19;
43
+ h1 = Math.imul(h1, 5) + 3864292196;
44
+ }
45
+ let k1 = 0;
46
+ switch (remainder) {
47
+ case 3:
48
+ k1 ^= (key.charCodeAt(i + 2) & 255) << 16;
49
+ // falls through
50
+ case 2:
51
+ k1 ^= (key.charCodeAt(i + 1) & 255) << 8;
52
+ // falls through
53
+ case 1:
54
+ k1 ^= key.charCodeAt(i) & 255;
55
+ k1 = Math.imul(k1, c1);
56
+ k1 = k1 << 15 | k1 >>> 17;
57
+ k1 = Math.imul(k1, c2);
58
+ h1 ^= k1;
59
+ }
60
+ h1 ^= key.length;
61
+ h1 ^= h1 >>> 16;
62
+ h1 = Math.imul(h1, 2246822507);
63
+ h1 ^= h1 >>> 13;
64
+ h1 = Math.imul(h1, 3266489909);
65
+ h1 ^= h1 >>> 16;
66
+ return h1 >>> 0;
67
+ }
68
+ function hashToByteSequence(input) {
69
+ const seedCount = 8;
70
+ const bytes = new Uint8Array(seedCount * 4);
71
+ for (let seed = 0; seed < seedCount; seed++) {
72
+ const hash = murmurhash3_32(input, seed);
73
+ const offset = seed * 4;
74
+ bytes[offset] = hash & 255;
75
+ bytes[offset + 1] = hash >> 8 & 255;
76
+ bytes[offset + 2] = hash >> 16 & 255;
77
+ bytes[offset + 3] = hash >> 24 & 255;
78
+ }
79
+ return bytes;
80
+ }
81
+
82
+ // src/piximps/domain/color-palette.ts
83
+ var ColorPalette = class {
84
+ constructor(config) {
85
+ this.skin = config.skin;
86
+ this.accent = config.accent;
87
+ this.glow = config.glow;
88
+ this.secondary = config.secondary;
89
+ }
90
+ };
91
+
92
+ // src/piximps/services/palette-deriver.ts
93
+ function readRgb(bytes, offset) {
94
+ return [bytes[offset], bytes[offset + 1], bytes[offset + 2], 255];
95
+ }
96
+ function boostSaturationAndBrightness(color) {
97
+ const max = Math.max(color[0], color[1], color[2]);
98
+ const min = Math.min(color[0], color[1], color[2]);
99
+ if (max === 0) return [255, 200, 0, 255];
100
+ const boosted = [color[0], color[1], color[2], 255];
101
+ const scale = 255 / max;
102
+ boosted[0] = Math.min(255, Math.round(boosted[0] * scale));
103
+ boosted[1] = Math.min(255, Math.round(boosted[1] * scale));
104
+ boosted[2] = Math.min(255, Math.round(boosted[2] * scale));
105
+ const maxBoosted = Math.max(boosted[0], boosted[1], boosted[2]);
106
+ if (maxBoosted <= 150) {
107
+ const idx = [boosted[0], boosted[1], boosted[2]].indexOf(maxBoosted);
108
+ boosted[idx] = 220;
109
+ }
110
+ return boosted;
111
+ }
112
+ function ensureColorDistance(skin, accent, minimumDistance) {
113
+ const distance = Math.abs(skin[0] - accent[0]) + Math.abs(skin[1] - accent[1]) + Math.abs(skin[2] - accent[2]);
114
+ if (distance >= minimumDistance) return accent;
115
+ const adjusted = [
116
+ (accent[0] + 80) % 256,
117
+ (accent[1] + 40) % 256,
118
+ (accent[2] + 120) % 256,
119
+ 255
120
+ ];
121
+ return adjusted;
122
+ }
123
+ function derivePalette(bytes) {
124
+ const rawSkin = readRgb(bytes, 0);
125
+ const rawAccent = readRgb(bytes, 3);
126
+ const rawGlow = readRgb(bytes, 6);
127
+ const rawSecondary = readRgb(bytes, 9);
128
+ const glow = boostSaturationAndBrightness(rawGlow);
129
+ const accent = ensureColorDistance(rawSkin, rawAccent, 60);
130
+ return new ColorPalette({
131
+ skin: rawSkin,
132
+ accent,
133
+ glow,
134
+ secondary: rawSecondary
135
+ });
136
+ }
137
+
138
+ // src/piximps/domain/imp-traits.ts
139
+ var ImpTraits = class {
140
+ constructor(config) {
141
+ this.bodyIndex = config.bodyIndex;
142
+ this.hornsIndex = config.hornsIndex;
143
+ this.eyesIndex = config.eyesIndex;
144
+ this.mouthIndex = config.mouthIndex;
145
+ this.accessoryIndices = config.accessoryIndices;
146
+ this.probabilisticBits = config.probabilisticBits;
147
+ this.symmetryBreakSide = config.symmetryBreakSide;
148
+ }
149
+ };
150
+
151
+ // src/piximps/domain/template.ts
152
+ var Template = class {
153
+ constructor(config) {
154
+ this.grid = config.grid;
155
+ this.anchors = config.anchors;
156
+ this.compatibleWith = config.compatibleWith;
157
+ this.symmetric = config.symmetric;
158
+ }
159
+ get width() {
160
+ return this.grid[0]?.length ?? 0;
161
+ }
162
+ get height() {
163
+ return this.grid.length;
164
+ }
165
+ get mirroredWidth() {
166
+ if (!this.symmetric) return this.width;
167
+ return this.width * 2 - 1;
168
+ }
169
+ };
170
+
171
+ // src/piximps/common/templates/body.ts
172
+ var _ = -1 /* AlwaysEmpty */;
173
+ var P = 0 /* Probabilistic */;
174
+ var F = 1 /* AlwaysFilled */;
175
+ var B = 2 /* InnerBody */;
176
+ var stocky8 = new Template({
177
+ grid: [
178
+ [_, _, F, F],
179
+ // pointed head top
180
+ [_, _, B, B],
181
+ // head
182
+ [_, F, B, B],
183
+ // shoulders (wide)
184
+ [_, P, F, B],
185
+ // arms out + torso
186
+ [_, _, F, B],
187
+ // waist
188
+ [_, _, B, B],
189
+ // hips
190
+ [_, _, F, F],
191
+ // upper legs
192
+ [_, _, F, _]
193
+ // feet apart
194
+ ],
195
+ anchors: {
196
+ horns: { row: 0, columnStart: 2, columnEnd: 3 },
197
+ eyes: { row: 1, columnStart: 2, columnEnd: 3 },
198
+ mouth: { row: 2, columnStart: 2, columnEnd: 3 }
199
+ },
200
+ compatibleWith: ["wide-horns", "small-horns", "single-eye", "double-eye", "fangs", "grin"],
201
+ symmetric: true
202
+ });
203
+ var lanky8 = new Template({
204
+ grid: [
205
+ [_, _, F, F],
206
+ // pointed head
207
+ [_, _, B, B],
208
+ // head
209
+ [_, _, F, B],
210
+ // narrow shoulders
211
+ [_, P, F, B],
212
+ // arm + torso
213
+ [_, _, F, B],
214
+ // waist
215
+ [_, _, F, F],
216
+ // hips
217
+ [_, _, F, _],
218
+ // legs
219
+ [_, _, F, _]
220
+ // feet
221
+ ],
222
+ anchors: {
223
+ horns: { row: 0, columnStart: 2, columnEnd: 3 },
224
+ eyes: { row: 1, columnStart: 2, columnEnd: 3 },
225
+ mouth: { row: 2, columnStart: 2, columnEnd: 3 }
226
+ },
227
+ compatibleWith: ["tall-horns", "small-horns", "single-eye", "double-eye", "fangs", "smirk"],
228
+ symmetric: true
229
+ });
230
+ var brawler8 = new Template({
231
+ grid: [
232
+ [_, _, F, F],
233
+ // head top
234
+ [_, F, B, B],
235
+ // head (wider)
236
+ [F, F, B, B],
237
+ // big shoulders
238
+ [F, P, F, B],
239
+ // arms out wide
240
+ [_, _, F, B],
241
+ // narrow waist
242
+ [_, _, B, B],
243
+ // hips
244
+ [_, _, F, F],
245
+ // legs
246
+ [_, F, _, F]
247
+ // wide stance
248
+ ],
249
+ anchors: {
250
+ horns: { row: 0, columnStart: 2, columnEnd: 3 },
251
+ eyes: { row: 1, columnStart: 1, columnEnd: 3 },
252
+ mouth: { row: 2, columnStart: 1, columnEnd: 3 }
253
+ },
254
+ compatibleWith: ["wide-horns", "small-horns", "triple-eye", "double-eye", "fangs", "grin"],
255
+ symmetric: true
256
+ });
257
+ var classic16 = new Template({
258
+ grid: [
259
+ [_, _, _, _, _, _, _, _],
260
+ // row 0
261
+ [_, _, _, _, _, _, _, _],
262
+ // row 1
263
+ [_, _, _, _, _, _, F, F],
264
+ // row 2: head top (pointed)
265
+ [_, _, _, _, _, F, B, B],
266
+ // row 3: head
267
+ [_, _, _, _, _, F, B, B],
268
+ // row 4: head
269
+ [_, _, _, _, _, F, B, B],
270
+ // row 5: lower head
271
+ [_, _, _, _, _, _, F, F],
272
+ // row 6: neck
273
+ [_, _, _, _, F, F, B, F],
274
+ // row 7: shoulders
275
+ [_, _, _, P, F, B, B, F],
276
+ // row 8: arms + upper torso
277
+ [_, _, _, _, F, B, B, F],
278
+ // row 9: torso
279
+ [_, _, _, _, _, F, B, F],
280
+ // row 10: waist (narrow)
281
+ [_, _, _, _, _, F, B, F],
282
+ // row 11: hips
283
+ [_, _, _, _, _, F, F, F],
284
+ // row 12: upper legs
285
+ [_, _, _, _, _, F, _, F],
286
+ // row 13: legs apart
287
+ [_, _, _, _, _, F, _, F],
288
+ // row 14: lower legs
289
+ [_, _, _, _, F, F, _, _]
290
+ // row 15: feet (digitigrade)
291
+ ],
292
+ anchors: {
293
+ horns: { row: 2, columnStart: 6, columnEnd: 7 },
294
+ eyes: { row: 4, columnStart: 5, columnEnd: 7 },
295
+ mouth: { row: 5, columnStart: 5, columnEnd: 7 }
296
+ },
297
+ compatibleWith: ["wide-horns", "small-horns", "single-eye", "double-eye", "fangs", "grin"],
298
+ symmetric: true
299
+ });
300
+ var lanky16 = new Template({
301
+ grid: [
302
+ [_, _, _, _, _, _, _, _],
303
+ // row 0
304
+ [_, _, _, _, _, _, F, F],
305
+ // row 1: head top
306
+ [_, _, _, _, _, _, B, B],
307
+ // row 2: head
308
+ [_, _, _, _, _, F, B, B],
309
+ // row 3: head
310
+ [_, _, _, _, _, F, B, B],
311
+ // row 4: lower head
312
+ [_, _, _, _, _, _, F, F],
313
+ // row 5: neck
314
+ [_, _, _, _, _, F, B, F],
315
+ // row 6: shoulders
316
+ [_, _, _, _, P, F, B, F],
317
+ // row 7: arm + torso
318
+ [_, _, _, _, _, F, B, F],
319
+ // row 8: torso
320
+ [_, _, _, _, _, F, B, F],
321
+ // row 9: torso
322
+ [_, _, _, _, _, _, F, F],
323
+ // row 10: waist
324
+ [_, _, _, _, _, _, F, F],
325
+ // row 11: hips
326
+ [_, _, _, _, _, _, F, _],
327
+ // row 12: legs
328
+ [_, _, _, _, _, _, F, _],
329
+ // row 13: legs
330
+ [_, _, _, _, _, _, F, _],
331
+ // row 14: lower legs
332
+ [_, _, _, _, _, F, F, _]
333
+ // row 15: feet
334
+ ],
335
+ anchors: {
336
+ horns: { row: 1, columnStart: 6, columnEnd: 7 },
337
+ eyes: { row: 3, columnStart: 5, columnEnd: 7 },
338
+ mouth: { row: 4, columnStart: 5, columnEnd: 7 }
339
+ },
340
+ compatibleWith: ["tall-horns", "small-horns", "single-eye", "double-eye", "fangs", "smirk"],
341
+ symmetric: true
342
+ });
343
+ var brute16 = new Template({
344
+ grid: [
345
+ [_, _, _, _, _, _, _, _],
346
+ // row 0
347
+ [_, _, _, _, _, _, _, _],
348
+ // row 1
349
+ [_, _, _, _, _, _, F, F],
350
+ // row 2: head top
351
+ [_, _, _, _, _, F, B, B],
352
+ // row 3: head
353
+ [_, _, _, _, _, F, B, B],
354
+ // row 4: head
355
+ [_, _, _, _, _, F, B, B],
356
+ // row 5: jaw
357
+ [_, _, _, _, _, _, F, F],
358
+ // row 6: neck
359
+ [_, _, _, _, F, F, B, F],
360
+ // row 7: shoulders
361
+ [_, _, _, F, F, B, B, F],
362
+ // row 8: big arms
363
+ [_, _, P, F, F, B, B, F],
364
+ // row 9: forearms
365
+ [_, _, _, _, F, B, B, F],
366
+ // row 10: torso
367
+ [_, _, _, _, _, F, B, F],
368
+ // row 11: waist
369
+ [_, _, _, _, _, F, B, F],
370
+ // row 12: hips
371
+ [_, _, _, _, _, F, F, F],
372
+ // row 13: upper legs
373
+ [_, _, _, _, F, F, _, F],
374
+ // row 14: legs apart
375
+ [_, _, _, _, F, _, _, F]
376
+ // row 15: wide stance
377
+ ],
378
+ anchors: {
379
+ horns: { row: 2, columnStart: 6, columnEnd: 7 },
380
+ eyes: { row: 4, columnStart: 5, columnEnd: 7 },
381
+ mouth: { row: 5, columnStart: 5, columnEnd: 7 }
382
+ },
383
+ compatibleWith: ["wide-horns", "small-horns", "triple-eye", "double-eye", "fangs", "grin"],
384
+ symmetric: true
385
+ });
386
+ var hunched16 = new Template({
387
+ grid: [
388
+ [_, _, _, _, _, _, _, _],
389
+ // row 0
390
+ [_, _, _, _, _, _, _, _],
391
+ // row 1
392
+ [_, _, _, _, _, _, _, _],
393
+ // row 2
394
+ [_, _, _, _, _, _, F, F],
395
+ // row 3: head top
396
+ [_, _, _, _, _, F, B, B],
397
+ // row 4: head
398
+ [_, _, _, _, _, F, B, B],
399
+ // row 5: head
400
+ [_, _, _, _, _, F, F, F],
401
+ // row 6: neck (forward)
402
+ [_, _, _, _, F, F, B, F],
403
+ // row 7: hunched shoulders
404
+ [_, _, _, P, F, B, B, F],
405
+ // row 8: long arms
406
+ [_, _, P, F, F, B, B, F],
407
+ // row 9: arms reaching down
408
+ [_, _, _, _, F, F, B, F],
409
+ // row 10: torso
410
+ [_, _, _, _, _, F, B, F],
411
+ // row 11: waist
412
+ [_, _, _, _, _, F, F, F],
413
+ // row 12: hips
414
+ [_, _, _, _, _, F, _, F],
415
+ // row 13: legs
416
+ [_, _, _, _, _, F, _, F],
417
+ // row 14: lower legs
418
+ [_, _, _, _, F, F, _, _]
419
+ // row 15: feet
420
+ ],
421
+ anchors: {
422
+ horns: { row: 3, columnStart: 6, columnEnd: 7 },
423
+ eyes: { row: 4, columnStart: 5, columnEnd: 7 },
424
+ mouth: { row: 5, columnStart: 5, columnEnd: 7 }
425
+ },
426
+ compatibleWith: ["wide-horns", "tall-horns", "single-eye", "double-eye", "fangs", "smirk"],
427
+ symmetric: true
428
+ });
429
+ var classic32 = new Template({
430
+ grid: [
431
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
432
+ // 0
433
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
434
+ // 1
435
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
436
+ // 2
437
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
438
+ // 3
439
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, F, F, F],
440
+ // 4: head top
441
+ [_, _, _, _, _, _, _, _, _, _, _, _, F, B, B, B],
442
+ // 5: head
443
+ [_, _, _, _, _, _, _, _, _, _, _, F, B, B, B, B],
444
+ // 6: head wide
445
+ [_, _, _, _, _, _, _, _, _, _, _, F, B, B, B, B],
446
+ // 7: head
447
+ [_, _, _, _, _, _, _, _, _, _, _, F, B, B, B, B],
448
+ // 8: lower head
449
+ [_, _, _, _, _, _, _, _, _, _, _, F, B, B, B, B],
450
+ // 9: jaw
451
+ [_, _, _, _, _, _, _, _, _, _, _, _, F, F, F, F],
452
+ // 10: chin
453
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, F, F, _],
454
+ // 11: neck
455
+ [_, _, _, _, _, _, _, _, _, _, F, F, F, B, F, _],
456
+ // 12: shoulders
457
+ [_, _, _, _, _, _, _, _, _, F, F, B, B, B, F, _],
458
+ // 13: upper torso
459
+ [_, _, _, _, _, _, _, _, P, F, B, B, B, B, F, _],
460
+ // 14: arms out
461
+ [_, _, _, _, _, _, _, P, F, F, B, B, B, B, F, _],
462
+ // 15: forearms
463
+ [_, _, _, _, _, _, _, _, _, F, F, B, B, B, F, _],
464
+ // 16: torso
465
+ [_, _, _, _, _, _, _, _, _, _, F, B, B, B, F, _],
466
+ // 17: torso
467
+ [_, _, _, _, _, _, _, _, _, _, _, F, B, B, F, _],
468
+ // 18: waist
469
+ [_, _, _, _, _, _, _, _, _, _, _, F, B, B, F, _],
470
+ // 19: waist
471
+ [_, _, _, _, _, _, _, _, _, _, _, F, B, B, F, _],
472
+ // 20: hips
473
+ [_, _, _, _, _, _, _, _, _, _, _, F, F, F, F, _],
474
+ // 21: upper legs
475
+ [_, _, _, _, _, _, _, _, _, _, _, F, F, _, F, _],
476
+ // 22: legs split
477
+ [_, _, _, _, _, _, _, _, _, _, _, F, _, _, F, _],
478
+ // 23: legs
479
+ [_, _, _, _, _, _, _, _, _, _, _, F, _, _, F, _],
480
+ // 24: legs
481
+ [_, _, _, _, _, _, _, _, _, _, _, F, _, _, F, _],
482
+ // 25: lower legs
483
+ [_, _, _, _, _, _, _, _, _, _, F, F, _, _, F, _],
484
+ // 26: ankles
485
+ [_, _, _, _, _, _, _, _, _, _, F, _, _, F, F, _],
486
+ // 27: digitigrade feet
487
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
488
+ // 28
489
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
490
+ // 29
491
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
492
+ // 30
493
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]
494
+ // 31
495
+ ],
496
+ anchors: {
497
+ horns: { row: 4, columnStart: 13, columnEnd: 15 },
498
+ eyes: { row: 7, columnStart: 11, columnEnd: 15 },
499
+ mouth: { row: 9, columnStart: 11, columnEnd: 15 }
500
+ },
501
+ compatibleWith: ["wide-horns", "small-horns", "single-eye", "double-eye", "fangs", "grin"],
502
+ symmetric: true
503
+ });
504
+ var lanky32 = new Template({
505
+ grid: [
506
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
507
+ // 0
508
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
509
+ // 1
510
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
511
+ // 2
512
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, F, F],
513
+ // 3: head top
514
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, F, B, B],
515
+ // 4: head
516
+ [_, _, _, _, _, _, _, _, _, _, _, _, F, B, B, B],
517
+ // 5: head
518
+ [_, _, _, _, _, _, _, _, _, _, _, _, F, B, B, B],
519
+ // 6: head
520
+ [_, _, _, _, _, _, _, _, _, _, _, _, F, B, B, B],
521
+ // 7: lower head
522
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, F, F, F],
523
+ // 8: chin
524
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, F, _],
525
+ // 9: thin neck
526
+ [_, _, _, _, _, _, _, _, _, _, _, _, F, F, F, _],
527
+ // 10: shoulders
528
+ [_, _, _, _, _, _, _, _, _, _, _, P, F, B, F, _],
529
+ // 11: arms
530
+ [_, _, _, _, _, _, _, _, _, _, P, F, F, B, F, _],
531
+ // 12: forearms
532
+ [_, _, _, _, _, _, _, _, _, _, _, _, F, B, F, _],
533
+ // 13: torso
534
+ [_, _, _, _, _, _, _, _, _, _, _, _, F, B, F, _],
535
+ // 14: torso
536
+ [_, _, _, _, _, _, _, _, _, _, _, _, F, B, F, _],
537
+ // 15: torso
538
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, F, F, _],
539
+ // 16: waist
540
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, F, F, _],
541
+ // 17: hips
542
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, F, F, _],
543
+ // 18: upper legs
544
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, F, _, _],
545
+ // 19: legs
546
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, F, _, _],
547
+ // 20: legs
548
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, F, _, _],
549
+ // 21: legs
550
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, F, _, _],
551
+ // 22: legs
552
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, F, _, _],
553
+ // 23: legs
554
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, F, _, _],
555
+ // 24: legs
556
+ [_, _, _, _, _, _, _, _, _, _, _, _, F, F, _, _],
557
+ // 25: ankles
558
+ [_, _, _, _, _, _, _, _, _, _, _, _, F, _, _, _],
559
+ // 26: feet
560
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
561
+ // 27
562
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
563
+ // 28
564
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
565
+ // 29
566
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
567
+ // 30
568
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]
569
+ // 31
570
+ ],
571
+ anchors: {
572
+ horns: { row: 3, columnStart: 14, columnEnd: 15 },
573
+ eyes: { row: 5, columnStart: 12, columnEnd: 15 },
574
+ mouth: { row: 7, columnStart: 12, columnEnd: 15 }
575
+ },
576
+ compatibleWith: ["tall-horns", "small-horns", "single-eye", "double-eye", "fangs", "smirk"],
577
+ symmetric: true
578
+ });
579
+ var brute32 = new Template({
580
+ grid: [
581
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
582
+ // 0
583
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
584
+ // 1
585
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
586
+ // 2
587
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
588
+ // 3
589
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, F, F, F],
590
+ // 4: head top
591
+ [_, _, _, _, _, _, _, _, _, _, _, _, F, B, B, B],
592
+ // 5: head
593
+ [_, _, _, _, _, _, _, _, _, _, _, F, B, B, B, B],
594
+ // 6: head
595
+ [_, _, _, _, _, _, _, _, _, _, _, F, B, B, B, B],
596
+ // 7: head
597
+ [_, _, _, _, _, _, _, _, _, _, _, F, B, B, B, B],
598
+ // 8: lower head
599
+ [_, _, _, _, _, _, _, _, _, _, _, _, F, F, F, F],
600
+ // 9: chin
601
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, F, F, _],
602
+ // 10: neck
603
+ [_, _, _, _, _, _, _, _, _, F, F, F, F, B, F, _],
604
+ // 11: wide shoulders
605
+ [_, _, _, _, _, _, _, _, F, F, B, B, B, B, F, _],
606
+ // 12: big arms
607
+ [_, _, _, _, _, _, _, F, F, B, B, B, B, B, F, _],
608
+ // 13: arms
609
+ [_, _, _, _, _, _, P, F, F, B, B, B, B, B, F, _],
610
+ // 14: forearms + claws
611
+ [_, _, _, _, _, _, _, F, F, F, B, B, B, B, F, _],
612
+ // 15: forearms
613
+ [_, _, _, _, _, _, _, _, _, F, F, B, B, B, F, _],
614
+ // 16: torso
615
+ [_, _, _, _, _, _, _, _, _, _, F, B, B, B, F, _],
616
+ // 17: torso
617
+ [_, _, _, _, _, _, _, _, _, _, F, B, B, B, F, _],
618
+ // 18: torso
619
+ [_, _, _, _, _, _, _, _, _, _, _, F, B, B, F, _],
620
+ // 19: waist
621
+ [_, _, _, _, _, _, _, _, _, _, _, F, B, B, F, _],
622
+ // 20: hips
623
+ [_, _, _, _, _, _, _, _, _, _, _, F, F, F, F, _],
624
+ // 21: upper legs
625
+ [_, _, _, _, _, _, _, _, _, _, F, F, _, _, F, F],
626
+ // 22: legs wide
627
+ [_, _, _, _, _, _, _, _, _, _, F, _, _, _, _, F],
628
+ // 23: legs
629
+ [_, _, _, _, _, _, _, _, _, _, F, _, _, _, _, F],
630
+ // 24: legs
631
+ [_, _, _, _, _, _, _, _, _, F, F, _, _, _, F, F],
632
+ // 25: ankles
633
+ [_, _, _, _, _, _, _, _, _, F, _, _, _, _, F, _],
634
+ // 26: feet
635
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
636
+ // 27
637
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
638
+ // 28
639
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
640
+ // 29
641
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
642
+ // 30
643
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]
644
+ // 31
645
+ ],
646
+ anchors: {
647
+ horns: { row: 4, columnStart: 13, columnEnd: 15 },
648
+ eyes: { row: 7, columnStart: 11, columnEnd: 15 },
649
+ mouth: { row: 8, columnStart: 11, columnEnd: 15 }
650
+ },
651
+ compatibleWith: ["wide-horns", "small-horns", "triple-eye", "double-eye", "fangs", "grin"],
652
+ symmetric: true
653
+ });
654
+ var hunched32 = new Template({
655
+ grid: [
656
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
657
+ // 0
658
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
659
+ // 1
660
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
661
+ // 2
662
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
663
+ // 3
664
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
665
+ // 4
666
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, F, F, F],
667
+ // 5: head top
668
+ [_, _, _, _, _, _, _, _, _, _, _, _, F, B, B, B],
669
+ // 6: head
670
+ [_, _, _, _, _, _, _, _, _, _, _, F, B, B, B, B],
671
+ // 7: head
672
+ [_, _, _, _, _, _, _, _, _, _, _, F, B, B, B, B],
673
+ // 8: head
674
+ [_, _, _, _, _, _, _, _, _, _, _, _, F, F, F, F],
675
+ // 9: chin
676
+ [_, _, _, _, _, _, _, _, _, _, _, F, F, B, F, _],
677
+ // 10: hunched neck
678
+ [_, _, _, _, _, _, _, _, _, _, F, F, B, B, F, _],
679
+ // 11: shoulders
680
+ [_, _, _, _, _, _, _, _, _, F, F, B, B, B, F, _],
681
+ // 12: torso
682
+ [_, _, _, _, _, _, _, _, P, F, B, B, B, B, F, _],
683
+ // 13: long arms
684
+ [_, _, _, _, _, _, _, P, F, F, B, B, B, B, F, _],
685
+ // 14: arms reaching
686
+ [_, _, _, _, _, _, P, F, F, _, F, B, B, B, F, _],
687
+ // 15: claws dangling
688
+ [_, _, _, _, _, _, _, _, _, _, F, B, B, B, F, _],
689
+ // 16: torso
690
+ [_, _, _, _, _, _, _, _, _, _, _, F, B, B, F, _],
691
+ // 17: waist
692
+ [_, _, _, _, _, _, _, _, _, _, _, F, B, B, F, _],
693
+ // 18: hips
694
+ [_, _, _, _, _, _, _, _, _, _, _, F, F, F, F, _],
695
+ // 19: upper legs
696
+ [_, _, _, _, _, _, _, _, _, _, _, F, _, _, F, _],
697
+ // 20: legs
698
+ [_, _, _, _, _, _, _, _, _, _, _, F, _, _, F, _],
699
+ // 21: legs
700
+ [_, _, _, _, _, _, _, _, _, _, _, F, _, _, F, _],
701
+ // 22: legs
702
+ [_, _, _, _, _, _, _, _, _, _, F, F, _, _, F, _],
703
+ // 23: ankles
704
+ [_, _, _, _, _, _, _, _, _, _, F, _, _, F, F, _],
705
+ // 24: feet
706
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
707
+ // 25
708
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
709
+ // 26
710
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
711
+ // 27
712
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
713
+ // 28
714
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
715
+ // 29
716
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _],
717
+ // 30
718
+ [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]
719
+ // 31
720
+ ],
721
+ anchors: {
722
+ horns: { row: 5, columnStart: 13, columnEnd: 15 },
723
+ eyes: { row: 7, columnStart: 11, columnEnd: 15 },
724
+ mouth: { row: 8, columnStart: 11, columnEnd: 15 }
725
+ },
726
+ compatibleWith: ["wide-horns", "tall-horns", "single-eye", "double-eye", "fangs", "smirk"],
727
+ symmetric: true
728
+ });
729
+ var bodyTemplates = {
730
+ 8: [stocky8, lanky8, brawler8],
731
+ 16: [classic16, lanky16, brute16, hunched16],
732
+ 32: [classic32, lanky32, brute32, hunched32]
733
+ };
734
+
735
+ // src/piximps/common/templates/horns.ts
736
+ var _2 = -1 /* AlwaysEmpty */;
737
+ var F2 = 1 /* AlwaysFilled */;
738
+ var wideHorns8 = new Template({
739
+ grid: [
740
+ [F2, _2, _2, _2],
741
+ [_2, F2, _2, _2]
742
+ ],
743
+ anchors: {},
744
+ compatibleWith: ["wide-horns"],
745
+ symmetric: true
746
+ });
747
+ var smallHorns8 = new Template({
748
+ grid: [
749
+ [_2, _2, F2, _2]
750
+ ],
751
+ anchors: {},
752
+ compatibleWith: ["small-horns"],
753
+ symmetric: true
754
+ });
755
+ var tallHorns8 = new Template({
756
+ grid: [
757
+ [_2, F2, _2, _2],
758
+ [_2, F2, _2, _2],
759
+ [_2, _2, _2, _2]
760
+ ],
761
+ anchors: {},
762
+ compatibleWith: ["tall-horns"],
763
+ symmetric: true
764
+ });
765
+ var curvedHorns16 = new Template({
766
+ grid: [
767
+ [F2, _2, _2, _2],
768
+ [_2, F2, _2, _2],
769
+ [_2, _2, F2, _2]
770
+ ],
771
+ anchors: {},
772
+ compatibleWith: ["wide-horns"],
773
+ symmetric: true
774
+ });
775
+ var straightHorns16 = new Template({
776
+ grid: [
777
+ [_2, F2, _2],
778
+ [_2, F2, _2],
779
+ [_2, F2, _2]
780
+ ],
781
+ anchors: {},
782
+ compatibleWith: ["tall-horns"],
783
+ symmetric: true
784
+ });
785
+ var branchingHorns16 = new Template({
786
+ grid: [
787
+ [F2, _2, _2, _2, _2],
788
+ [_2, F2, _2, _2, _2],
789
+ [_2, F2, F2, _2, _2],
790
+ [_2, _2, _2, F2, _2]
791
+ ],
792
+ anchors: {},
793
+ compatibleWith: ["wide-horns"],
794
+ symmetric: true
795
+ });
796
+ var stubbyHorns16 = new Template({
797
+ grid: [
798
+ [F2, _2, _2],
799
+ [_2, F2, _2]
800
+ ],
801
+ anchors: {},
802
+ compatibleWith: ["small-horns"],
803
+ symmetric: true
804
+ });
805
+ var longCurved32 = new Template({
806
+ grid: [
807
+ [F2, _2, _2, _2, _2, _2, _2, _2],
808
+ [_2, F2, _2, _2, _2, _2, _2, _2],
809
+ [_2, _2, F2, _2, _2, _2, _2, _2],
810
+ [_2, _2, _2, F2, F2, _2, _2, _2],
811
+ [_2, _2, _2, _2, _2, F2, _2, _2],
812
+ [_2, _2, _2, _2, _2, _2, F2, _2]
813
+ ],
814
+ anchors: {},
815
+ compatibleWith: ["wide-horns"],
816
+ symmetric: true
817
+ });
818
+ var shortStubby32 = new Template({
819
+ grid: [
820
+ [_2, _2, F2, _2, _2],
821
+ [_2, _2, _2, F2, _2],
822
+ [_2, _2, _2, _2, F2]
823
+ ],
824
+ anchors: {},
825
+ compatibleWith: ["small-horns"],
826
+ symmetric: true
827
+ });
828
+ var branching32 = new Template({
829
+ grid: [
830
+ [F2, _2, _2, _2, _2, _2, _2, _2],
831
+ [_2, F2, _2, _2, _2, _2, _2, _2],
832
+ [_2, _2, F2, F2, _2, _2, _2, _2],
833
+ [_2, _2, F2, _2, F2, _2, _2, _2],
834
+ [_2, _2, _2, _2, _2, F2, _2, _2],
835
+ [_2, _2, _2, _2, _2, _2, F2, _2]
836
+ ],
837
+ anchors: {},
838
+ compatibleWith: ["wide-horns"],
839
+ symmetric: true
840
+ });
841
+ var ramStyle32 = new Template({
842
+ grid: [
843
+ [_2, F2, F2, _2, _2, _2],
844
+ [F2, _2, _2, F2, _2, _2],
845
+ [F2, _2, _2, _2, F2, _2],
846
+ [_2, F2, _2, _2, F2, _2],
847
+ [_2, _2, F2, F2, _2, _2]
848
+ ],
849
+ anchors: {},
850
+ compatibleWith: ["wide-horns"],
851
+ symmetric: true
852
+ });
853
+ var singleSpike32 = new Template({
854
+ grid: [
855
+ [_2, F2, _2],
856
+ [_2, F2, _2],
857
+ [_2, F2, _2],
858
+ [_2, F2, _2],
859
+ [_2, F2, _2],
860
+ [_2, F2, _2]
861
+ ],
862
+ anchors: {},
863
+ compatibleWith: ["tall-horns"],
864
+ symmetric: true
865
+ });
866
+ var hornTemplates = {
867
+ 8: [wideHorns8, smallHorns8, tallHorns8],
868
+ 16: [curvedHorns16, straightHorns16, branchingHorns16, stubbyHorns16],
869
+ 32: [longCurved32, shortStubby32, branching32, ramStyle32, singleSpike32]
870
+ };
871
+
872
+ // src/piximps/common/templates/eyes.ts
873
+ var _3 = -1 /* AlwaysEmpty */;
874
+ var F3 = 1 /* AlwaysFilled */;
875
+ var singleEye8 = new Template({
876
+ grid: [[_3, _3, _3, F3]],
877
+ anchors: {},
878
+ compatibleWith: ["single-eye"],
879
+ symmetric: true
880
+ });
881
+ var doubleEye8 = new Template({
882
+ grid: [[_3, F3, _3, _3]],
883
+ anchors: {},
884
+ compatibleWith: ["double-eye"],
885
+ symmetric: true
886
+ });
887
+ var tripleEye8 = new Template({
888
+ grid: [[_3, F3, _3, F3]],
889
+ anchors: {},
890
+ compatibleWith: ["triple-eye"],
891
+ symmetric: true
892
+ });
893
+ var singleEye16 = new Template({
894
+ grid: [
895
+ [_3, _3, _3, F3, F3],
896
+ [_3, _3, _3, F3, F3]
897
+ ],
898
+ anchors: {},
899
+ compatibleWith: ["single-eye"],
900
+ symmetric: true
901
+ });
902
+ var doubleEye16 = new Template({
903
+ grid: [
904
+ [_3, F3, F3, _3, _3],
905
+ [_3, F3, F3, _3, _3]
906
+ ],
907
+ anchors: {},
908
+ compatibleWith: ["double-eye"],
909
+ symmetric: true
910
+ });
911
+ var tripleEye16 = new Template({
912
+ grid: [
913
+ [_3, F3, _3, F3, F3],
914
+ [_3, F3, _3, F3, F3]
915
+ ],
916
+ anchors: {},
917
+ compatibleWith: ["triple-eye"],
918
+ symmetric: true
919
+ });
920
+ var singleEye32 = new Template({
921
+ grid: [
922
+ [_3, _3, _3, _3, _3, _3, F3, F3, F3],
923
+ [_3, _3, _3, _3, _3, _3, F3, F3, F3],
924
+ [_3, _3, _3, _3, _3, _3, F3, F3, F3]
925
+ ],
926
+ anchors: {},
927
+ compatibleWith: ["single-eye"],
928
+ symmetric: true
929
+ });
930
+ var doubleEye32 = new Template({
931
+ grid: [
932
+ [_3, _3, F3, F3, _3, _3, _3, _3],
933
+ [_3, _3, F3, F3, _3, _3, _3, _3]
934
+ ],
935
+ anchors: {},
936
+ compatibleWith: ["double-eye"],
937
+ symmetric: true
938
+ });
939
+ var tripleEye32 = new Template({
940
+ grid: [
941
+ [_3, _3, F3, F3, _3, _3, F3, F3, F3],
942
+ [_3, _3, F3, F3, _3, _3, F3, F3, F3],
943
+ [_3, _3, _3, _3, _3, _3, _3, _3, _3]
944
+ ],
945
+ anchors: {},
946
+ compatibleWith: ["triple-eye"],
947
+ symmetric: true
948
+ });
949
+ var eyeTemplates = {
950
+ 8: [singleEye8, doubleEye8, tripleEye8],
951
+ 16: [singleEye16, doubleEye16, tripleEye16],
952
+ 32: [singleEye32, doubleEye32, tripleEye32]
953
+ };
954
+
955
+ // src/piximps/common/templates/mouth.ts
956
+ var _4 = -1 /* AlwaysEmpty */;
957
+ var F4 = 1 /* AlwaysFilled */;
958
+ var fangs8 = new Template({
959
+ grid: [[_4, F4, _4, F4]],
960
+ anchors: {},
961
+ compatibleWith: ["fangs"],
962
+ symmetric: true
963
+ });
964
+ var grin8 = new Template({
965
+ grid: [[_4, F4, F4, F4]],
966
+ anchors: {},
967
+ compatibleWith: ["grin"],
968
+ symmetric: true
969
+ });
970
+ var smirk8 = new Template({
971
+ grid: [[_4, _4, F4, F4]],
972
+ anchors: {},
973
+ compatibleWith: ["smirk"],
974
+ symmetric: false
975
+ });
976
+ var fangs16 = new Template({
977
+ grid: [
978
+ [_4, F4, _4, F4],
979
+ [F4, _4, F4, _4]
980
+ ],
981
+ anchors: {},
982
+ compatibleWith: ["fangs"],
983
+ symmetric: true
984
+ });
985
+ var grin16 = new Template({
986
+ grid: [
987
+ [_4, F4, F4, F4],
988
+ [_4, _4, F4, F4]
989
+ ],
990
+ anchors: {},
991
+ compatibleWith: ["grin"],
992
+ symmetric: true
993
+ });
994
+ var smirk16 = new Template({
995
+ grid: [
996
+ [_4, _4, F4, F4],
997
+ [_4, F4, F4, _4]
998
+ ],
999
+ anchors: {},
1000
+ compatibleWith: ["smirk"],
1001
+ symmetric: false
1002
+ });
1003
+ var multiFangs32 = new Template({
1004
+ grid: [
1005
+ [_4, _4, F4, _4, F4, _4, F4, _4],
1006
+ [_4, F4, _4, F4, _4, F4, _4, _4],
1007
+ [F4, _4, _4, _4, _4, _4, _4, _4]
1008
+ ],
1009
+ anchors: {},
1010
+ compatibleWith: ["fangs"],
1011
+ symmetric: true
1012
+ });
1013
+ var wideGrin32 = new Template({
1014
+ grid: [
1015
+ [_4, _4, F4, F4, F4, F4, F4, F4],
1016
+ [_4, _4, _4, F4, F4, F4, F4, F4],
1017
+ [_4, _4, _4, _4, F4, F4, F4, F4]
1018
+ ],
1019
+ anchors: {},
1020
+ compatibleWith: ["grin"],
1021
+ symmetric: true
1022
+ });
1023
+ var asymSmirk32 = new Template({
1024
+ grid: [
1025
+ [_4, _4, _4, _4, F4, F4, F4, F4],
1026
+ [_4, _4, _4, F4, F4, F4, _4, _4],
1027
+ [_4, _4, F4, F4, _4, _4, _4, _4]
1028
+ ],
1029
+ anchors: {},
1030
+ compatibleWith: ["smirk"],
1031
+ symmetric: false
1032
+ });
1033
+ var mouthTemplates = {
1034
+ 8: [fangs8, grin8, smirk8],
1035
+ 16: [fangs16, grin16, smirk16],
1036
+ 32: [multiFangs32, wideGrin32, asymSmirk32]
1037
+ };
1038
+
1039
+ // src/piximps/common/templates/accessories.ts
1040
+ var _5 = -1 /* AlwaysEmpty */;
1041
+ var F5 = 1 /* AlwaysFilled */;
1042
+ var P2 = 0 /* Probabilistic */;
1043
+ var tail8 = new Template({
1044
+ grid: [
1045
+ [_5, _5, _5, _5],
1046
+ [_5, _5, _5, _5],
1047
+ [_5, _5, _5, _5],
1048
+ [_5, _5, _5, _5],
1049
+ [_5, _5, _5, _5],
1050
+ [_5, _5, _5, _5],
1051
+ [F5, _5, _5, _5],
1052
+ [_5, F5, _5, _5]
1053
+ ],
1054
+ anchors: {},
1055
+ compatibleWith: [],
1056
+ symmetric: false
1057
+ });
1058
+ var wings8 = new Template({
1059
+ grid: [
1060
+ [_5, _5, _5, _5],
1061
+ [_5, _5, _5, _5],
1062
+ [_5, _5, _5, _5],
1063
+ [F5, P2, _5, _5],
1064
+ [F5, F5, _5, _5],
1065
+ [_5, _5, _5, _5],
1066
+ [_5, _5, _5, _5],
1067
+ [_5, _5, _5, _5]
1068
+ ],
1069
+ anchors: {},
1070
+ compatibleWith: [],
1071
+ symmetric: false
1072
+ });
1073
+ var tail16 = new Template({
1074
+ grid: [
1075
+ [_5, _5, _5, _5, _5, _5, _5, _5],
1076
+ [_5, _5, _5, _5, _5, _5, _5, _5],
1077
+ [_5, _5, _5, _5, _5, _5, _5, _5],
1078
+ [_5, _5, _5, _5, _5, _5, _5, _5],
1079
+ [_5, _5, _5, _5, _5, _5, _5, _5],
1080
+ [_5, _5, _5, _5, _5, _5, _5, _5],
1081
+ [_5, _5, _5, _5, _5, _5, _5, _5],
1082
+ [_5, _5, _5, _5, _5, _5, _5, _5],
1083
+ [_5, _5, _5, _5, _5, _5, _5, _5],
1084
+ [_5, _5, _5, _5, _5, _5, _5, _5],
1085
+ [_5, _5, _5, _5, _5, _5, _5, _5],
1086
+ [F5, _5, _5, _5, _5, _5, _5, _5],
1087
+ [_5, F5, _5, _5, _5, _5, _5, _5],
1088
+ [_5, _5, F5, _5, _5, _5, _5, _5],
1089
+ [_5, _5, F5, _5, _5, _5, _5, _5],
1090
+ [_5, F5, P2, _5, _5, _5, _5, _5]
1091
+ ],
1092
+ anchors: {},
1093
+ compatibleWith: [],
1094
+ symmetric: false
1095
+ });
1096
+ var wings16 = new Template({
1097
+ grid: [
1098
+ [_5, _5, _5, _5, _5, _5, _5, _5],
1099
+ [_5, _5, _5, _5, _5, _5, _5, _5],
1100
+ [_5, _5, _5, _5, _5, _5, _5, _5],
1101
+ [_5, _5, _5, _5, _5, _5, _5, _5],
1102
+ [_5, _5, _5, _5, _5, _5, _5, _5],
1103
+ [_5, _5, _5, _5, _5, _5, _5, _5],
1104
+ [F5, _5, _5, _5, _5, _5, _5, _5],
1105
+ [F5, F5, _5, _5, _5, _5, _5, _5],
1106
+ [F5, F5, P2, _5, _5, _5, _5, _5],
1107
+ [F5, F5, F5, _5, _5, _5, _5, _5],
1108
+ [_5, F5, F5, _5, _5, _5, _5, _5],
1109
+ [_5, _5, F5, _5, _5, _5, _5, _5],
1110
+ [_5, _5, _5, _5, _5, _5, _5, _5],
1111
+ [_5, _5, _5, _5, _5, _5, _5, _5],
1112
+ [_5, _5, _5, _5, _5, _5, _5, _5],
1113
+ [_5, _5, _5, _5, _5, _5, _5, _5]
1114
+ ],
1115
+ anchors: {},
1116
+ compatibleWith: [],
1117
+ symmetric: false
1118
+ });
1119
+ var tail32 = new Template({
1120
+ grid: [
1121
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1122
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1123
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1124
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1125
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1126
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1127
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1128
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1129
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1130
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1131
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1132
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1133
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1134
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1135
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1136
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1137
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1138
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1139
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1140
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1141
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1142
+ [F5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1143
+ [_5, F5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1144
+ [_5, _5, F5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1145
+ [_5, _5, _5, F5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1146
+ [_5, _5, _5, _5, F5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1147
+ [_5, _5, _5, _5, F5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1148
+ [_5, _5, _5, _5, F5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1149
+ [_5, _5, _5, F5, F5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1150
+ [_5, _5, F5, P2, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1151
+ [_5, F5, F5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1152
+ [P2, F5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5]
1153
+ ],
1154
+ anchors: {},
1155
+ compatibleWith: [],
1156
+ symmetric: false
1157
+ });
1158
+ var wings32 = new Template({
1159
+ grid: [
1160
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1161
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1162
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1163
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1164
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1165
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1166
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1167
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1168
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1169
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1170
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1171
+ [F5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1172
+ [F5, F5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1173
+ [F5, F5, F5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1174
+ [F5, F5, F5, F5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1175
+ [F5, F5, P2, F5, F5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1176
+ [F5, F5, P2, P2, F5, F5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1177
+ [F5, P2, F5, P2, F5, F5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1178
+ [_5, F5, F5, F5, F5, F5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1179
+ [_5, _5, F5, F5, F5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1180
+ [_5, _5, _5, F5, F5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1181
+ [_5, _5, _5, _5, F5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1182
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1183
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1184
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1185
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1186
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1187
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1188
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1189
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1190
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5],
1191
+ [_5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5, _5]
1192
+ ],
1193
+ anchors: {},
1194
+ compatibleWith: [],
1195
+ symmetric: false
1196
+ });
1197
+ var accessoryTemplates = {
1198
+ tail: { 8: [tail8], 16: [tail16], 32: [tail32] },
1199
+ wings: { 8: [wings8], 16: [wings16], 32: [wings32] },
1200
+ weapon: { 8: [], 16: [], 32: [] },
1201
+ hat: { 8: [], 16: [], 32: [] }
1202
+ };
1203
+
1204
+ // src/piximps/services/trait-extractor.ts
1205
+ var ACCESSORY_PRESENCE_THRESHOLD = 128;
1206
+ var ByteConsumer = class {
1207
+ constructor(bytes, startOffset = 12) {
1208
+ this.bytes = bytes;
1209
+ this.offset = startOffset;
1210
+ }
1211
+ next() {
1212
+ const value = this.bytes[this.offset % this.bytes.length];
1213
+ this.offset++;
1214
+ return value;
1215
+ }
1216
+ selectIndex(count) {
1217
+ if (count <= 0) return 0;
1218
+ return this.next() % count;
1219
+ }
1220
+ selectBool() {
1221
+ return this.next() >= ACCESSORY_PRESENCE_THRESHOLD;
1222
+ }
1223
+ nextBits(count) {
1224
+ const bits = [];
1225
+ for (let i = 0; i < count; i++) {
1226
+ bits.push((this.next() & 1 << i % 8) !== 0);
1227
+ }
1228
+ return bits;
1229
+ }
1230
+ };
1231
+ function extractTraits(bytes, gridSize) {
1232
+ const consumer = new ByteConsumer(bytes);
1233
+ const bodyCount = bodyTemplates[gridSize].length;
1234
+ const hornCount = hornTemplates[gridSize].length;
1235
+ const eyeCount = eyeTemplates[gridSize].length;
1236
+ const mouthCount = mouthTemplates[gridSize].length;
1237
+ const bodyIndex = consumer.selectIndex(bodyCount);
1238
+ const hornsIndex = consumer.selectIndex(hornCount);
1239
+ const eyesIndex = consumer.selectIndex(eyeCount);
1240
+ const mouthIndex = consumer.selectIndex(mouthCount);
1241
+ const accessoryTypes = ["tail", "wings", "weapon", "hat"];
1242
+ const accessoryIndices = {
1243
+ tail: null,
1244
+ wings: null,
1245
+ weapon: null,
1246
+ hat: null
1247
+ };
1248
+ for (const accType of accessoryTypes) {
1249
+ const isPresent = consumer.selectBool();
1250
+ const templates = accessoryTemplates[accType]?.[gridSize] ?? [];
1251
+ if (isPresent && templates.length > 0) {
1252
+ accessoryIndices[accType] = consumer.selectIndex(templates.length);
1253
+ } else {
1254
+ consumer.next();
1255
+ }
1256
+ }
1257
+ const symmetryBreakSide = consumer.next() % 2 === 0 ? "left" : "right";
1258
+ const probabilisticBits = consumer.nextBits(32);
1259
+ return new ImpTraits({
1260
+ bodyIndex,
1261
+ hornsIndex,
1262
+ eyesIndex,
1263
+ mouthIndex,
1264
+ accessoryIndices,
1265
+ probabilisticBits,
1266
+ symmetryBreakSide
1267
+ });
1268
+ }
1269
+
1270
+ // src/piximps/services/layer-compositor.ts
1271
+ function createEmptyGrid(size) {
1272
+ const cells = [];
1273
+ const colors = [];
1274
+ for (let r = 0; r < size; r++) {
1275
+ cells.push(new Array(size).fill(0 /* Empty */));
1276
+ colors.push(new Array(size).fill(null));
1277
+ }
1278
+ return { cells, colors, width: size, height: size };
1279
+ }
1280
+ function colorForLayer(palette, layerType, cellType) {
1281
+ switch (layerType) {
1282
+ case "body":
1283
+ return cellType === 2 /* InnerBody */ ? palette.accent : palette.skin;
1284
+ case "eyes":
1285
+ return palette.glow;
1286
+ case "horns":
1287
+ return palette.secondary;
1288
+ case "mouth":
1289
+ return palette.skin;
1290
+ case "accessory":
1291
+ return palette.secondary;
1292
+ }
1293
+ }
1294
+ function stampTemplate(grid, template, anchorRow, anchorCol, layerType, palette, probabilisticBits, bitOffset) {
1295
+ for (let r = 0; r < template.height; r++) {
1296
+ for (let c = 0; c < template.width; c++) {
1297
+ const cell = template.grid[r][c];
1298
+ const targetRow = anchorRow + r;
1299
+ const targetCol = anchorCol + c;
1300
+ if (targetRow < 0 || targetRow >= grid.height) continue;
1301
+ if (targetCol < 0 || targetCol >= grid.width) continue;
1302
+ let shouldFill = false;
1303
+ let renderedType = 0 /* Empty */;
1304
+ switch (cell) {
1305
+ case -1 /* AlwaysEmpty */:
1306
+ continue;
1307
+ case 1 /* AlwaysFilled */:
1308
+ shouldFill = true;
1309
+ renderedType = 1 /* Body */;
1310
+ break;
1311
+ case 2 /* InnerBody */:
1312
+ shouldFill = true;
1313
+ renderedType = 2 /* InnerBody */;
1314
+ break;
1315
+ case 0 /* Probabilistic */: {
1316
+ const bit = probabilisticBits[bitOffset.value % probabilisticBits.length] ?? false;
1317
+ bitOffset.value++;
1318
+ shouldFill = bit;
1319
+ renderedType = 1 /* Body */;
1320
+ break;
1321
+ }
1322
+ }
1323
+ if (shouldFill) {
1324
+ grid.cells[targetRow][targetCol] = renderedType;
1325
+ grid.colors[targetRow][targetCol] = colorForLayer(palette, layerType, cell);
1326
+ }
1327
+ }
1328
+ }
1329
+ if (template.symmetric) {
1330
+ const centerCol = anchorCol + template.width - 1;
1331
+ for (let r = 0; r < template.height; r++) {
1332
+ for (let c = 0; c < template.width - 1; c++) {
1333
+ const sourceCol = anchorCol + c;
1334
+ const mirrorCol = centerCol + (template.width - 1 - c);
1335
+ const targetRow = anchorRow + r;
1336
+ if (targetRow < 0 || targetRow >= grid.height) continue;
1337
+ if (mirrorCol < 0 || mirrorCol >= grid.width) continue;
1338
+ if (grid.cells[targetRow][sourceCol] !== 0 /* Empty */) {
1339
+ grid.cells[targetRow][mirrorCol] = grid.cells[targetRow][sourceCol];
1340
+ grid.colors[targetRow][mirrorCol] = grid.colors[targetRow][sourceCol];
1341
+ }
1342
+ }
1343
+ }
1344
+ }
1345
+ }
1346
+ function composeLayers(input) {
1347
+ const grid = createEmptyGrid(input.gridSize);
1348
+ const bitOffset = { value: 0 };
1349
+ const bodyOffsetCol = Math.floor((input.gridSize - input.body.mirroredWidth) / 2);
1350
+ const bodyOffsetRow = Math.floor((input.gridSize - input.body.height) / 2);
1351
+ stampTemplate(grid, input.body, bodyOffsetRow, bodyOffsetCol, "body", input.palette, input.probabilisticBits, bitOffset);
1352
+ if (input.horns && input.body.anchors["horns"]) {
1353
+ const anchor = input.body.anchors["horns"];
1354
+ const hornRow = bodyOffsetRow + anchor.row - input.horns.height;
1355
+ const hornCol = bodyOffsetCol + anchor.columnStart;
1356
+ stampTemplate(grid, input.horns, hornRow, hornCol, "horns", input.palette, input.probabilisticBits, bitOffset);
1357
+ }
1358
+ if (input.eyes && input.body.anchors["eyes"]) {
1359
+ const anchor = input.body.anchors["eyes"];
1360
+ const eyeRow = bodyOffsetRow + anchor.row;
1361
+ const eyeCol = bodyOffsetCol + anchor.columnStart;
1362
+ stampTemplate(grid, input.eyes, eyeRow, eyeCol, "eyes", input.palette, input.probabilisticBits, bitOffset);
1363
+ }
1364
+ if (input.mouth && input.body.anchors["mouth"]) {
1365
+ const anchor = input.body.anchors["mouth"];
1366
+ const mouthRow = bodyOffsetRow + anchor.row;
1367
+ const mouthCol = bodyOffsetCol + anchor.columnStart;
1368
+ stampTemplate(grid, input.mouth, mouthRow, mouthCol, "mouth", input.palette, input.probabilisticBits, bitOffset);
1369
+ }
1370
+ for (const accessory of input.accessories) {
1371
+ const accCol = input.symmetryBreakSide === "left" ? 0 : input.gridSize - accessory.width;
1372
+ stampTemplate(grid, accessory, 0, accCol, "accessory", input.palette, input.probabilisticBits, bitOffset);
1373
+ }
1374
+ return grid;
1375
+ }
1376
+
1377
+ // src/piximps/services/edge-detector.ts
1378
+ var DARKEN_FACTOR = 0.4;
1379
+ function darkenColor(color) {
1380
+ const multiplier = 1 - DARKEN_FACTOR;
1381
+ return [
1382
+ Math.round(color[0] * multiplier),
1383
+ Math.round(color[1] * multiplier),
1384
+ Math.round(color[2] * multiplier),
1385
+ color[3]
1386
+ ];
1387
+ }
1388
+ function isFilled(cellType) {
1389
+ return cellType !== 0 /* Empty */;
1390
+ }
1391
+ function hasEmptyNeighbor(cells, row, col, height, width) {
1392
+ if (row === 0 || row === height - 1 || col === 0 || col === width - 1) {
1393
+ return true;
1394
+ }
1395
+ const neighbors = [
1396
+ cells[row - 1][col],
1397
+ cells[row + 1][col],
1398
+ cells[row][col - 1],
1399
+ cells[row][col + 1]
1400
+ ];
1401
+ return neighbors.some((n) => !isFilled(n));
1402
+ }
1403
+ function detectEdges(grid) {
1404
+ const { cells, colors, width, height } = grid;
1405
+ const newCells = cells.map((row) => [...row]);
1406
+ const newColors = colors.map((row) => [...row]);
1407
+ for (let r = 0; r < height; r++) {
1408
+ for (let c = 0; c < width; c++) {
1409
+ if (!isFilled(cells[r][c])) continue;
1410
+ if (hasEmptyNeighbor(cells, r, c, height, width)) {
1411
+ newCells[r][c] = 3 /* Edge */;
1412
+ if (colors[r][c]) {
1413
+ newColors[r][c] = darkenColor(colors[r][c]);
1414
+ }
1415
+ }
1416
+ }
1417
+ }
1418
+ return { cells: newCells, colors: newColors, width, height };
1419
+ }
1420
+
1421
+ // src/piximps/entrypoints/renderers/to-rgba-buffer.ts
1422
+ function toRgbaBuffer(grid, outputSize) {
1423
+ const buffer = new Uint8Array(outputSize * outputSize * 4);
1424
+ const scale = outputSize / grid.width;
1425
+ for (let y = 0; y < outputSize; y++) {
1426
+ for (let x = 0; x < outputSize; x++) {
1427
+ const gridRow = Math.floor(y / scale);
1428
+ const gridCol = Math.floor(x / scale);
1429
+ const pixelOffset = (y * outputSize + x) * 4;
1430
+ const cell = grid.cells[gridRow]?.[gridCol];
1431
+ const color = grid.colors[gridRow]?.[gridCol];
1432
+ if (cell !== void 0 && cell !== 0 /* Empty */ && color) {
1433
+ buffer[pixelOffset] = color[0];
1434
+ buffer[pixelOffset + 1] = color[1];
1435
+ buffer[pixelOffset + 2] = color[2];
1436
+ buffer[pixelOffset + 3] = color[3];
1437
+ }
1438
+ }
1439
+ }
1440
+ return buffer;
1441
+ }
1442
+
1443
+ // src/piximps/entrypoints/renderers/to-svg-string.ts
1444
+ function toSvgString(grid, outputSize) {
1445
+ const pixelSize = outputSize / grid.width;
1446
+ const rects = [];
1447
+ for (let r = 0; r < grid.height; r++) {
1448
+ for (let c = 0; c < grid.width; c++) {
1449
+ const cell = grid.cells[r][c];
1450
+ const color = grid.colors[r][c];
1451
+ if (cell === 0 /* Empty */ || !color) continue;
1452
+ const x = c * pixelSize;
1453
+ const y = r * pixelSize;
1454
+ rects.push(
1455
+ `<rect x="${x}" y="${y}" width="${pixelSize}" height="${pixelSize}" fill="rgb(${color[0]},${color[1]},${color[2]})" opacity="${color[3] / 255}"/>`
1456
+ );
1457
+ }
1458
+ }
1459
+ return [
1460
+ `<svg xmlns="http://www.w3.org/2000/svg" width="${outputSize}" height="${outputSize}" viewBox="0 0 ${outputSize} ${outputSize}">`,
1461
+ ...rects,
1462
+ "</svg>"
1463
+ ].join("\n");
1464
+ }
1465
+
1466
+ // src/piximps/browser.ts
1467
+ var _ImpGenerator = class _ImpGenerator {
1468
+ constructor(options) {
1469
+ const grid = options?.grid ?? 16;
1470
+ const size = options?.size ?? 128;
1471
+ if (!_ImpGenerator.VALID_GRID_SIZES.includes(grid)) {
1472
+ throw new RangeError(`Grid size must be one of: ${_ImpGenerator.VALID_GRID_SIZES.join(", ")}`);
1473
+ }
1474
+ if (size <= 0 || size > _ImpGenerator.MAX_OUTPUT_SIZE) {
1475
+ throw new RangeError(`Output size must be between 1 and ${_ImpGenerator.MAX_OUTPUT_SIZE}`);
1476
+ }
1477
+ this.options = {
1478
+ size,
1479
+ grid,
1480
+ format: options?.format ?? "svg"
1481
+ };
1482
+ }
1483
+ getOptions() {
1484
+ return { ...this.options };
1485
+ }
1486
+ size(value) {
1487
+ return new _ImpGenerator({ ...this.options, size: value });
1488
+ }
1489
+ grid(value) {
1490
+ return new _ImpGenerator({ ...this.options, grid: value });
1491
+ }
1492
+ format(value) {
1493
+ return new _ImpGenerator({ ...this.options, format: value });
1494
+ }
1495
+ async generate(input) {
1496
+ const bytes = input !== void 0 ? hashToByteSequence(input) : crypto.getRandomValues(new Uint8Array(32));
1497
+ const palette = derivePalette(bytes);
1498
+ const traits = extractTraits(bytes, this.options.grid);
1499
+ const body = bodyTemplates[this.options.grid][traits.bodyIndex];
1500
+ if (!body) {
1501
+ throw new Error(`No body template at index ${traits.bodyIndex} for grid size ${this.options.grid}`);
1502
+ }
1503
+ const horns = hornTemplates[this.options.grid][traits.hornsIndex] ?? null;
1504
+ const eyes = eyeTemplates[this.options.grid][traits.eyesIndex] ?? null;
1505
+ const mouth = mouthTemplates[this.options.grid][traits.mouthIndex] ?? null;
1506
+ const accessories = [];
1507
+ const accessoryTypes = ["tail", "wings", "weapon", "hat"];
1508
+ for (const accType of accessoryTypes) {
1509
+ const idx = traits.accessoryIndices[accType];
1510
+ if (idx !== null) {
1511
+ const template = accessoryTemplates[accType]?.[this.options.grid]?.[idx];
1512
+ if (template) accessories.push(template);
1513
+ }
1514
+ }
1515
+ const composited = composeLayers({
1516
+ gridSize: this.options.grid,
1517
+ body,
1518
+ horns,
1519
+ eyes,
1520
+ mouth,
1521
+ accessories,
1522
+ palette,
1523
+ probabilisticBits: traits.probabilisticBits,
1524
+ symmetryBreakSide: traits.symmetryBreakSide
1525
+ });
1526
+ const edgeDetected = detectEdges(composited);
1527
+ switch (this.options.format) {
1528
+ case "buffer":
1529
+ return toRgbaBuffer(edgeDetected, this.options.size);
1530
+ case "svg":
1531
+ return toSvgString(edgeDetected, this.options.size);
1532
+ }
1533
+ }
1534
+ };
1535
+ _ImpGenerator.VALID_GRID_SIZES = [8, 16, 32];
1536
+ _ImpGenerator.MAX_OUTPUT_SIZE = 4096;
1537
+ var ImpGenerator = _ImpGenerator;
1538
+ return __toCommonJS(browser_exports);
1539
+ })();