makeables 0.10.0 → 0.11.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.
@@ -1,1393 +1,38 @@
1
- // ../design/dist/chunk-J74I2FPH.js
2
- var MAX_SVG_BYTES = 1e6;
3
- var TAG = /<([a-z][\w:.-]*)((?:\s+[^\s=<>/]+(?:\s*=\s*(?:"[^"<]*"|'[^'<]*'|[^\s"'<>]+))?)*)\s*\/?>/gi;
4
- var ATTRIBUTE = /([^\s=<>/]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'<>]+)))?/g;
5
- var CLOSING_TAG = /<\/[a-z][\w:.-]*\s*>/gi;
6
- var CSS_URL = /url\(\s*(["']?)(.*?)\1\s*\)/gi;
7
- var EMBEDDED_IMAGE = /^data:image\/(?:png|jpeg|jpg|webp|gif);base64,[a-z0-9+/=\s]+$/i;
8
- var FORBIDDEN_ELEMENTS = /* @__PURE__ */ new Set([
9
- "script",
10
- "foreignobject",
11
- "iframe",
12
- "embed",
13
- "object",
14
- "audio",
15
- "video",
16
- "canvas",
17
- "handler",
18
- "listener"
19
- ]);
20
- function fail(error) {
21
- return { ok: false, error };
22
- }
23
- function localName(name) {
24
- return name.toLowerCase().replace(/^[\w.-]+:/, "");
25
- }
26
- function checkSubmittedSvg(input) {
27
- const svg2 = input.replace(/^/, "").trim();
28
- if (!svg2) return fail("The file is empty.");
29
- if (new TextEncoder().encode(svg2).byteLength > MAX_SVG_BYTES) {
30
- return fail("The SVG must be 1 MB or smaller.");
31
- }
32
- if (/<!(?:doctype|entity)/i.test(svg2))
33
- return fail("DOCTYPE and entity declarations are not allowed.");
34
- if (/(?:java|vb)script\s*:/i.test(svg2)) return fail("Script URLs are not allowed.");
35
- if (/@import/i.test(svg2)) return fail("CSS @import is not allowed.");
36
- for (const match of svg2.matchAll(CSS_URL)) {
37
- if (!match[2]?.trim().startsWith("#")) {
38
- return fail("CSS url() may only reference elements inside the file (#id).");
39
- }
40
- }
41
- const markup = svg2.replace(/^<\?xml[^>]*\?>/i, "").replace(/<!--[\s\S]*?-->/g, "").replace(/<!\[CDATA\[[\s\S]*?\]\]>/g, "").trim();
42
- if (markup.replace(TAG, "").replace(CLOSING_TAG, "").includes("<")) {
43
- return fail("The SVG contains malformed markup.");
44
- }
45
- const tags2 = [...markup.matchAll(TAG)];
46
- const [root] = tags2;
47
- if (root?.index !== 0 || localName(root[1] ?? "") !== "svg") {
48
- return fail("The file must be an SVG document starting with <svg>.");
49
- }
50
- if (!/<\/svg\s*>$/i.test(markup)) return fail("The SVG is incomplete.");
51
- for (const [index, tag] of tags2.entries()) {
52
- const element = localName(tag[1] ?? "");
53
- if (FORBIDDEN_ELEMENTS.has(element)) return fail(`<${tag[1]}> elements are not allowed.`);
54
- for (const attribute of (tag[2] ?? "").matchAll(ATTRIBUTE)) {
55
- const name = localName(attribute[1] ?? "");
56
- const value = (attribute[2] ?? attribute[3] ?? attribute[4] ?? "").trim();
57
- if (name.startsWith("on")) {
58
- return fail("Event handler attributes (onload, onclick\u2026) are not allowed.");
59
- }
60
- if (name === "href" && !value.startsWith("#") && !EMBEDDED_IMAGE.test(value)) {
61
- return fail(
62
- "Links must point inside the file (#id) or embed a base64 PNG, JPEG, WebP, or GIF."
63
- );
64
- }
65
- if (name === "attributename" && localName(value) === "href") {
66
- return fail("Animating links is not allowed.");
67
- }
68
- if (index === 0 && name === "viewbox") {
69
- const box3 = value.split(/[\s,]+/).map(Number).join(" ");
70
- if (box3 !== "0 0 1200 756") return fail('The <svg> element needs viewBox="0 0 1200 756".');
71
- }
72
- }
73
- }
74
- if (!/\sviewBox\s*=/i.test(root[2] ?? "")) {
75
- return fail('The <svg> element needs viewBox="0 0 1200 756".');
76
- }
77
- return { ok: true, svg: svg2 };
78
- }
79
-
80
- // ../design/dist/chunk-HIVKVAE6.js
81
- var shaderFunctions = [
82
- "abs",
83
- "acos",
84
- "asin",
85
- "atan",
86
- "atan2",
87
- "ceil",
88
- "clamp",
89
- "cos",
90
- "cross",
91
- "distance",
92
- "dot",
93
- "exp",
94
- "exp2",
95
- "floor",
96
- "fract",
97
- "length",
98
- "log",
99
- "log2",
100
- "max",
101
- "min",
102
- "mix",
103
- "normalize",
104
- "pow",
105
- "reflect",
106
- "round",
107
- "select",
108
- "sign",
109
- "sin",
110
- "smoothstep",
111
- "sqrt",
112
- "step",
113
- "tan",
114
- "tanh",
115
- "trunc",
116
- "vec2f",
117
- "vec3f",
118
- "vec4f",
119
- "f32",
120
- "noise2",
121
- "cells2"
122
- ];
123
- var functions = new Set(shaderFunctions);
124
- var inputs = ["p", "t", "pointer", "seed"];
125
- function shaderCodeIssue(code) {
126
- if (!code || code.length > 4800) return "Usa una f\xF3rmula de hasta 4800 caracteres.";
127
- if (!/^[\x20-\x7e\n\r\t]+$/.test(code) || /\/[/*]|\*\//.test(code))
128
- return "La f\xF3rmula solo admite c\xF3digo sin comentarios.";
129
- const statements = code.trim().split(";");
130
- if (statements.pop()?.trim() || statements.length < 1 || statements.length > 40)
131
- return "La f\xF3rmula debe terminar en return y tener hasta 40 instrucciones.";
132
- const names = /* @__PURE__ */ new Set([...inputs, ...shaderFunctions, "true", "false"]);
133
- let tokens = 0;
134
- let calls = 0;
135
- let noiseCalls = 0;
136
- for (const [index, statement] of statements.entries()) {
137
- const last = index === statements.length - 1;
138
- const match = last ? /^\s*return\s+([\s\S]+)$/.exec(statement) : /^\s*let\s+([A-Za-z][A-Za-z0-9_]*)\s*=\s*([\s\S]+)$/.exec(statement);
139
- if (!match) return "Usa declaraciones let y un \xFAnico return final.";
140
- const name = last ? void 0 : match[1];
141
- if (name && (names.has(name) || name.startsWith("__"))) return "Nombre reservado o repetido.";
142
- const expression = last ? match[1] : match[2];
143
- const parts = expression.match(
144
- /(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?f?|[A-Za-z_][A-Za-z0-9_]*|\s+|&&|\|\||==|!=|<=|>=|[().,+\-*/%<>!]/g
145
- ) ?? [];
146
- if (parts.join("") !== expression) return "La f\xF3rmula contiene sintaxis no admitida.";
147
- const significant = parts.filter((part) => part.trim());
148
- let depth = 0;
149
- for (const [i, part] of significant.entries()) {
150
- if (++tokens > 700) return "La f\xF3rmula es demasiado compleja.";
151
- if (part === "(" && ++depth > 16) return "Demasiados niveles en la f\xF3rmula.";
152
- if (part === ")" && --depth < 0) return "Par\xE9ntesis incompletos.";
153
- if (!/^[A-Za-z_]/.test(part)) continue;
154
- if (significant[i - 1] === ".") {
155
- if (!/^[xyzwrgba]{1,4}$/.test(part)) return "Solo se permiten componentes de vectores.";
156
- } else if (significant[i + 1] === "(") {
157
- if (!functions.has(part)) return `Funci\xF3n no admitida: ${part}.`;
158
- if (++calls > 80) return "La f\xF3rmula admite hasta 80 llamadas.";
159
- if ((part === "noise2" || part === "cells2") && ++noiseCalls > 12)
160
- return "Usa como m\xE1ximo 12 muestras de ruido.";
161
- } else if (!names.has(part)) return "La f\xF3rmula usa una variable no disponible.";
162
- }
163
- if (depth !== 0) return "Par\xE9ntesis incompletos.";
164
- if (name) names.add(name);
165
- }
166
- }
167
-
168
- // ../design/dist/chunk-6WXIEGBU.js
169
- import { z } from "zod";
170
- var text = (max2) => z.string().trim().min(1).max(max2).regex(/^[^\p{Cc}\p{Cf}]+$/u);
171
- var range = (min, max2) => z.number().finite().min(min).max(max2);
172
- var color = z.string().regex(/^#[0-9a-fA-F]{6}$/);
173
- var prismFieldSchema = z.object({
174
- layers: z.array(
175
- z.object({
176
- basis: z.enum(["noise", "cells", "ribbons", "rings"]),
177
- scale: range(0.5, 6),
178
- stretch: range(0.3, 3),
179
- angle: range(-180, 180),
180
- warp: range(0, 2),
181
- drift: range(-0.5, 0.5),
182
- weight: range(0.1, 1),
183
- blend: z.enum(["add", "multiply"])
184
- }).strict()
185
- ).min(1).max(4).refine((layers) => layers[0]?.blend === "add", "Start with an additive layer."),
186
- relief: range(0, 1),
187
- refraction: range(0, 0.5),
188
- film: range(0, 1),
189
- coverage: range(0.15, 1)
190
- }).strict();
191
- var prismShaderSchema = z.object({
192
- version: z.literal(1),
193
- code: z.string().max(4800).superRefine((code, ctx) => {
194
- const issue = shaderCodeIssue(code);
195
- if (issue) ctx.addIssue({ code: z.ZodIssueCode.custom, message: issue });
196
- })
197
- }).strict();
198
- var prismStyleSchema = z.object({
199
- version: z.literal(1),
200
- name: text(48),
201
- description: text(160),
202
- surface: z.enum(["prism", "satin", "chrome"]),
203
- finish: z.enum(["crystal", "opal", "obsidian"]),
204
- palette: z.array(color).length(3),
205
- accent: color,
206
- portrait: z.object({ strength: range(0, 1), saturation: range(0, 1.5), contrast: range(0.65, 1.4) }).strict(),
207
- texture: z.object({
208
- pattern: z.enum(["none", "grain", "contours", "brushed", "grid"]),
209
- amount: range(0, 0.45),
210
- scale: range(0.25, 2)
211
- }).strict(),
212
- material: z.object({ roughness: range(0.12, 0.85), iridescence: range(0, 0.65) }).strict(),
213
- field: prismFieldSchema.optional(),
214
- shader: prismShaderSchema.optional(),
215
- motion: z.object({ speed: range(0, 1), amplitude: range(0, 0.75) }).strict(),
216
- heading: z.enum(["sans", "serif", "mono"])
217
- }).strict();
218
- var prismRecipeSchema = prismStyleSchema.extend({
219
- material: z.object({ roughness: range(0, 1), iridescence: range(0, 0.65) }).strict(),
220
- seed: z.number().int().min(0).max(4294967295),
221
- promptVersion: z.enum([
222
- "style-director-v1",
223
- "material-director-v2",
224
- "material-director-v3",
225
- "shader-director-v1",
226
- "shader-director-v2"
227
- ]),
228
- model: text(100)
229
- }).strict().refine((recipe) => !recipe.shader || Boolean(recipe.field), {
230
- path: ["field"],
231
- message: "A shader material requires a fallback field."
232
- });
233
- var styleRequestSchema = z.object({
234
- prompt: text(600),
235
- mode: z.enum(["compositor", "shader"]).optional(),
236
- current: prismRecipeSchema.optional()
237
- }).strict();
238
- var styleOutputSchema = z.object({
239
- styles: z.array(prismStyleSchema.extend({ field: prismFieldSchema })).min(1).max(3)
240
- }).strict();
241
- var generatedUnitControl = (bounds) => range(0, 1).transform((value) => Math.min(bounds.maxValue ?? 1, Math.max(bounds.minValue ?? 0, value))).pipe(bounds);
242
- var generatedColor = z.string().trim().regex(
243
- /^#{0,2}[0-9a-fA-F]{6}$/,
244
- "Use six hexadecimal digits, e.g. #e06c9f. Convert color names to hex; no CSS names or functions."
245
- ).transform((value) => `#${value.replace(/^#+/, "")}`).pipe(color).describe("A six-digit hexadecimal color with one #, e.g. #e06c9f. No color names.");
246
- var styleGenerationSchema = z.object({
247
- styles: z.array(
248
- prismStyleSchema.omit({ version: true, shader: true }).extend({
249
- field: prismFieldSchema,
250
- palette: z.array(generatedColor).length(3),
251
- accent: generatedColor,
252
- material: prismStyleSchema.shape.material.extend({
253
- roughness: generatedUnitControl(prismStyleSchema.shape.material.shape.roughness),
254
- iridescence: generatedUnitControl(prismStyleSchema.shape.material.shape.iridescence)
255
- })
256
- })
257
- ).min(1).max(3)
258
- }).strict();
259
- var shaderGenerationSchema = z.object({
260
- style: styleGenerationSchema.shape.styles.element.extend({
261
- shader: prismShaderSchema.omit({ version: true }).extend({
262
- code: prismShaderSchema.shape.code.refine(
263
- (code) => !/\bnormalize\s*\(/.test(code),
264
- "normalize can receive a zero vector. Use v / max(length(v), 0.0001) instead."
265
- )
266
- })
267
- })
268
- }).strict();
269
-
270
- // ../design/dist/chunk-XV4DY67T.js
271
- import { z as z3 } from "zod";
272
- import { z as z2 } from "zod";
273
- import { z as z22 } from "zod";
274
- var CONTACTLESS_ARCS = [
275
- "M1060 134 Q1068 143 1060 152",
276
- "M1072 124 Q1088 143 1072 162",
277
- "M1084 114 Q1108 143 1084 172",
278
- "M1096 104 Q1128 143 1096 182"
279
- ];
280
- var CONTACTLESS_STROKE_WIDTH = 7.5;
281
- var DEFAULT_CARD_DETAILS = {
282
- showChip: true,
283
- chipColor: "#d9b875",
284
- chipSlot: "middle-left",
285
- showContactless: true,
286
- contactlessColor: "#ffffff",
287
- contactlessSlot: "upper-right",
288
- network: "mastercard",
289
- networkColorMode: "brand",
290
- networkSlot: "lower-right",
291
- visaVariant: "boxed"
292
- };
293
- var CHIP_OFFSET = {
294
- "middle-left": [0, 0],
295
- "upper-left": [0, -125]
296
- };
297
- var CONTACTLESS_OFFSET = {
298
- "upper-right": [-70, 60],
299
- "middle-right": [-70, 245]
300
- };
301
- var NETWORK_ORIGIN = {
302
- "lower-right": {
303
- mastercard: [990, 585],
304
- visa: [905, 550],
305
- amex: [995, 565],
306
- discover: [925, 600]
307
- },
308
- "upper-right": {
309
- mastercard: [990, 290],
310
- visa: [905, 290],
311
- amex: [995, 280],
312
- discover: [925, 300]
313
- }
314
- };
315
- var VISA_PATH = "m 651.18503,0.50000002 c -70.93272,0 -134.32163,36.76584998 -134.32163,104.69357998 0,77.90028 112.42264,83.28082 112.42264,122.41576 0,16.47806 -18.88384,31.22851 -51.13668,31.22851 -45.77308,0 -79.98403,-20.61081 -79.98403,-20.61081 l -14.63836,68.54658 c 0,0 39.41037,17.40989 91.73375,17.40989 77.55217,0 138.57651,-38.57104 138.57651,-107.66029 0,-82.3157 -112.89106,-87.53633 -112.89106,-123.86008 0,-12.9082 15.50201,-27.05169 47.66251,-27.05169 36.28682,0 65.89216,14.98968 65.89216,14.98968 l 14.32608,-66.20444 c 0,0 -32.21317,-13.89668998 -77.64189,-13.89668998 z M 2.2175605,5.49657 0.49999253,15.48969 c 0,0 29.84159547,5.46149 56.71878047,16.35593 34.606624,12.4927 37.071853,19.7653 42.900167,42.35367 l 63.51098,244.83152 85.13673,0 131.15974,-313.53424 -84.94155,0 L 210.7069,218.67018 176.3165,37.97422 C 173.1626,17.29371 157.18709,5.49657 137.63219,5.49657 l -135.4146295,0 z m 411.8650095,0 -66.63383,313.53424 80.99895,0 66.39962,-313.53424 -80.76474,0 z m 451.75943,0 c -19.53181,0 -29.88045,10.45695 -37.47421,28.73022 l -118.66834,284.80402 84.94155,0 16.434,-47.46734 103.48348,0 9.99312,47.46734 74.94843,0 -65.3847,-313.53424 -68.27333,0 z m 11.04709,84.70733 25.17799,117.65341 -67.45359,0 42.2756,-117.65341 z";
316
- function networkMarkup(network, mode, visaVariant) {
317
- const mono = mode === "white" ? "#ffffff" : "#111111";
318
- if (network === "mastercard") {
319
- const red = mode === "brand" ? "#eb001b" : mono;
320
- const yellow = mode === "brand" ? "#f79e1b" : mono;
321
- const orange = mode === "brand" ? "#ff5f00" : mono;
322
- return `<circle cx="50" cy="42" r="39" fill="${red}"/><circle cx="96" cy="42" r="39" fill="${yellow}"/><circle cx="96" cy="42" r="39" fill="${orange}" clip-path="url(#mc-overlap)"/>`;
323
- }
324
- if (network === "visa") {
325
- const color22 = visaVariant === "boxed" || mode === "brand" ? "url(#visa-brand)" : mono;
326
- const mark = `<path d="${VISA_PATH}" fill="${color22}"/>`;
327
- return visaVariant === "boxed" ? `<rect width="240" height="120" fill="#ffffff"/><g transform="translate(10 24) scale(.22)">${mark}</g>` : `<g transform="translate(15 0) scale(.22)">${mark}</g>`;
328
- }
329
- if (network === "amex") {
330
- const background = mode === "brand" ? "#2e77bc" : mono;
331
- const foreground = mode === "black" ? "#ffffff" : mode === "white" ? "#111111" : "#ffffff";
332
- return `<rect width="142" height="94" rx="4" fill="${background}"/><text x="71" y="42" text-anchor="middle" fill="${foreground}" font-family="Arial,Helvetica,sans-serif" font-size="23" font-weight="900" letter-spacing="-1.5">AMERICAN</text><text x="71" y="70" text-anchor="middle" fill="${foreground}" font-family="Arial,Helvetica,sans-serif" font-size="27" font-weight="900" letter-spacing="-1.8">EXPRESS</text>`;
333
- }
334
- const ink = mode === "brand" ? "#202024" : mono;
335
- const sun = mode === "brand" ? "#f58220" : mono;
336
- return `<g transform="scale(.88)"><g font-family="Arial,Helvetica,sans-serif" font-size="44" font-weight="900" letter-spacing="-2" fill="${ink}"><text x="0" y="63">DISC</text><text x="153" y="63">VER</text></g><circle cx="132" cy="46" r="19" fill="none" stroke="${sun}" stroke-width="10"/></g>`;
337
- }
338
- function cardDetailsSvg(details) {
339
- const [chipX, chipY] = CHIP_OFFSET[details.chipSlot];
340
- const [contactlessX, contactlessY] = CONTACTLESS_OFFSET[details.contactlessSlot];
341
- const [networkX, networkY] = details.network === "none" ? [0, 0] : NETWORK_ORIGIN[details.networkSlot][details.network];
342
- return `<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="756" viewBox="0 0 1200 756">
343
- <defs>
344
- <linearGradient id="metal" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#fff" stop-opacity=".8"/><stop offset=".22" stop-color="#000" stop-opacity=".18"/><stop offset=".48" stop-color="#fff" stop-opacity=".55"/><stop offset=".72" stop-color="#000" stop-opacity=".26"/><stop offset="1" stop-color="#fff" stop-opacity=".35"/></linearGradient>
345
- <linearGradient id="visa-brand" x1="0" y1="0" x2="1000" y2="0" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#20225f"/><stop offset=".2" stop-color="#1a1f61"/><stop offset=".41" stop-color="#172272"/><stop offset=".6" stop-color="#152682"/><stop offset=".8" stop-color="#12288e"/><stop offset="1" stop-color="#0e2c9a"/></linearGradient>
346
- <clipPath id="mc-overlap"><circle cx="50" cy="42" r="39"/></clipPath>
347
- </defs>
348
- ${details.showChip ? `<g transform="translate(${chipX} ${chipY})"><rect x="84" y="357" width="151" height="112" rx="17" fill="#100e0b" fill-opacity=".8" stroke="${details.chipColor}" stroke-opacity=".32" stroke-width="2"/><rect x="90" y="363" width="139" height="100" rx="13" fill="${details.chipColor}" stroke="#fff" stroke-opacity=".65" stroke-width="2"/><rect x="90" y="363" width="139" height="100" rx="13" fill="url(#metal)"/><path d="M90 397H229M90 430H229M137 363V463M183 363V463" fill="none" stroke="#1b1715" stroke-opacity=".55" stroke-width="2.4"/><rect x="137" y="397" width="46" height="33" rx="8" fill="none" stroke="#1b1715" stroke-opacity=".7" stroke-width="2.4"/><path d="M137 412H90M183 412H229" stroke="#fff" stroke-opacity=".55" stroke-width="1.2"/></g>` : ""}
349
- ${details.showContactless ? `<g transform="translate(${contactlessX} ${contactlessY}) translate(1086 143) scale(1.3 1.15) translate(-1086 -143)" fill="none" stroke="${details.contactlessColor}" stroke-width="${CONTACTLESS_STROKE_WIDTH}" stroke-linecap="round" stroke-linejoin="round">${CONTACTLESS_ARCS.map((arc) => `<path d="${arc}"/>`).join("")}</g>` : ""}
350
- ${details.network === "none" ? "" : `<g transform="translate(${networkX} ${networkY + (details.network === "visa" && details.visaVariant === "plain" ? 45 : 0)})">${networkMarkup(details.network, details.networkColorMode, details.visaVariant)}</g>`}
351
- </svg>`;
352
- }
353
- var NETWORK_SIZE = {
354
- mastercard: { x: 8, y: 0, w: 130, h: 84 },
355
- visa: { x: 0, y: 0, w: 240, h: 120 },
356
- amex: { x: 0, y: 0, w: 142, h: 94 },
357
- discover: { x: 0, y: 0, w: 228, h: 66 }
358
- };
359
- function cardMarkRegion(spec) {
360
- if (spec.mark === "chip") {
361
- const [, dy] = CHIP_OFFSET[spec.slot] ?? [0, 0];
362
- return { x: 82, y: 355 + dy, w: 155, h: 116 };
363
- }
364
- if (spec.mark === "contactless") {
365
- const [dx, dy] = CONTACTLESS_OFFSET[spec.slot] ?? [0, 0];
366
- return { x: 1036 + dx, y: 86 + dy, w: 92, h: 114 };
367
- }
368
- const network = spec.network ?? "mastercard";
369
- const [ox, oy] = NETWORK_ORIGIN[spec.slot]?.[network] ?? [0, 0];
370
- const size = NETWORK_SIZE[network];
371
- if (network === "visa" && spec.visaVariant === "plain")
372
- return { x: ox + 15, y: oy + 45, w: 222, h: 76 };
373
- return { x: ox + size.x, y: oy + size.y, w: size.w, h: size.h };
374
- }
375
- function cardMarkSvg(spec) {
376
- const details = {
377
- ...DEFAULT_CARD_DETAILS,
378
- showChip: spec.mark === "chip",
379
- showContactless: spec.mark === "contactless",
380
- network: spec.mark === "network" ? spec.network ?? "mastercard" : "none"
381
- };
382
- if (spec.mark === "chip") {
383
- details.chipSlot = spec.slot;
384
- if (spec.color) details.chipColor = spec.color;
385
- } else if (spec.mark === "contactless") {
386
- details.contactlessSlot = spec.slot;
387
- if (spec.color) details.contactlessColor = spec.color;
388
- } else {
389
- details.networkSlot = spec.slot;
390
- details.networkColorMode = spec.colorMode ?? "brand";
391
- details.visaVariant = spec.visaVariant ?? "boxed";
392
- }
393
- const { x, y, w, h } = cardMarkRegion(spec);
394
- return cardDetailsSvg(details).replace(
395
- 'width="1200" height="756" viewBox="0 0 1200 756"',
396
- `width="${w}" height="${h}" viewBox="${x} ${y} ${w} ${h}"`
397
- );
398
- }
399
- var productIds = ["badge", "card", "sticker"];
400
- var designProfiles = {
401
- badge: {
402
- id: "badge",
403
- label: "Badge",
404
- width: 1024,
405
- height: 1536,
406
- kinds: ["text", "shape", "portrait", "graphic", "effect", "gradient", "image"],
407
- keepClear: [],
408
- preview: "lanyard"
409
- },
410
- card: {
411
- id: "card",
412
- label: "Card",
413
- width: 1200,
414
- height: 756,
415
- kinds: ["text", "shape", "graphic", "gradient", "effect"],
416
- // Wallet prints the masked card number here; estimated from a Wallet screenshot.
417
- keepClear: [{ label: "card number", x: 64, y: 615, w: 406, h: 100 }],
418
- preview: "card"
419
- },
420
- sticker: {
421
- id: "sticker",
422
- label: "Sticker",
423
- width: 1024,
424
- height: 1024,
425
- kinds: ["text", "shape", "graphic", "gradient", "image"],
426
- keepClear: [],
427
- preview: "die-cut"
428
- }
429
- };
430
- function designProfile(design2) {
431
- return designProfiles[design2.product ?? "badge"];
432
- }
433
- var stickerMaterialSchema = z2.object({
434
- finish: z2.enum(["glitter", "holographic", "vinyl"]),
435
- /** Die-cut border in canvas pixels; `widthMm` gives it a printed size. */
436
- border: z2.number().min(0).max(40),
437
- /** Printed width of the square canvas. Defaults to 75 mm. */
438
- widthMm: z2.number().min(10).max(300).optional(),
439
- sparkle: z2.number().min(0).max(1),
440
- gloss: z2.number().min(0).max(1.5),
441
- seed: z2.number().int().min(0).max(4294967295),
442
- holography: z2.number().min(0).max(1).optional(),
443
- relief: z2.number().min(0).max(1.5).optional(),
444
- flakes: z2.number().min(40).max(500).optional(),
445
- stock: z2.enum(["white", "holographic", "holo-glitter"]).optional(),
446
- laminate: z2.enum(["gloss", "matte"]).optional(),
447
- liner: z2.string().min(1).max(40).optional(),
448
- /** RGB = foil, glitter, relief. Follow the named image layer's placement and alpha. */
449
- effectMap: z2.object({
450
- asset: z2.string().regex(/^[a-z][a-z0-9-]{0,39}$/),
451
- layer: z2.string().min(1).max(80)
452
- }).optional(),
453
- /** Optical overrides follow editable layer geometry, including later transforms. */
454
- regions: z2.record(
455
- z2.string().min(1).max(80),
456
- z2.object({
457
- foil: z2.number().min(0).max(1),
458
- glitter: z2.number().min(0).max(1),
459
- relief: z2.number().min(0).max(1)
460
- })
461
- ).optional()
462
- });
463
- var defaultStickerMaterial = {
464
- finish: "glitter",
465
- border: 18,
466
- sparkle: 0.72,
467
- gloss: 0.5,
468
- seed: 280926
469
- };
470
- var tags = /* @__PURE__ */ new Set([
471
- "g",
472
- "defs",
473
- "rect",
474
- "circle",
475
- "ellipse",
476
- "path",
477
- "line",
478
- "polyline",
479
- "polygon",
480
- "text",
481
- "tspan",
482
- "image",
483
- "use",
484
- "symbol",
485
- "linearGradient",
486
- "radialGradient",
487
- "stop",
488
- "pattern",
489
- "clipPath",
490
- "mask",
491
- "filter",
492
- "feTurbulence",
493
- "feColorMatrix",
494
- "feGaussianBlur",
495
- "feMerge",
496
- "feMergeNode",
497
- "feDropShadow",
498
- "feOffset"
499
- ]);
500
- var attributes = /* @__PURE__ */ new Set([
501
- "viewBox",
502
- "width",
503
- "height",
504
- "role",
505
- "aria-label",
506
- "aria-labelledby",
507
- "id",
508
- "x1",
509
- "y1",
510
- "x2",
511
- "y2",
512
- "offset",
513
- "stop-color",
514
- "x",
515
- "y",
516
- "type",
517
- "baseFrequency",
518
- "numOctaves",
519
- "seed",
520
- "stitchTiles",
521
- "values",
522
- "fill",
523
- "d",
524
- "stroke",
525
- "stroke-width",
526
- "opacity",
527
- "cx",
528
- "cy",
529
- "r",
530
- "style",
531
- "clip-path",
532
- "filter",
533
- "gradientUnits",
534
- "stop-opacity",
535
- "stdDeviation",
536
- "result",
537
- "in",
538
- "mask",
539
- "rx",
540
- "transform",
541
- "ry",
542
- "patternUnits",
543
- "shape-rendering",
544
- "href",
545
- "stroke-opacity",
546
- "font-family",
547
- "font-size",
548
- "font-weight",
549
- "letter-spacing",
550
- "fill-opacity",
551
- "stroke-linecap",
552
- "stroke-linejoin",
553
- "text-anchor",
554
- "stroke-dasharray",
555
- "points",
556
- "fill-rule",
557
- "dx",
558
- "dy",
559
- "flood-color",
560
- "preserveAspectRatio",
561
- "gradientTransform",
562
- "spreadMethod",
563
- "clip-rule",
564
- "color-interpolation-filters",
565
- "filterUnits",
566
- "maskUnits"
567
- ]);
568
- var blend = /^mix-blend-mode:\s*(normal|multiply|screen|overlay|soft-light|hard-light|color-dodge|color-burn|darken|lighten);?$/;
569
- var safeAttribute = (value, key) => {
570
- if (!attributes.has(key)) return false;
571
- if (key === "href")
572
- return /^#[\w.-]+$/.test(value) || /^data:image\/(?:png|jpeg|webp|gif);base64,[A-Za-z0-9+/=]+$/.test(value);
573
- if (key === "style") return blend.test(value);
574
- if (/url\s*\(/i.test(value)) return /^url\(#[\w.-]+\)$/.test(value);
575
- return !/[<>]/.test(value);
576
- };
577
- var svgNodeSchema = z22.lazy(
578
- () => z22.object({
579
- tag: z22.string().refine((tag) => tags.has(tag), "Unsupported SVG element"),
580
- attrs: z22.record(z22.string().max(28e5)).superRefine((attrs, ctx) => {
581
- for (const [key, value] of Object.entries(attrs))
582
- if (!safeAttribute(value, key))
583
- ctx.addIssue({ code: "custom", message: `Unsupported SVG attribute: ${key}` });
584
- }).optional(),
585
- text: z22.string().max(2e3).optional(),
586
- children: z22.array(svgNodeSchema).max(1e3).optional()
587
- })
588
- );
589
- var svgSourceSchema = z22.object({
590
- definitions: z22.array(svgNodeSchema).max(100),
591
- /** Provenance of the original file, not a network location. */
592
- originalSha256: z22.string().regex(/^[a-f0-9]{64}$/),
593
- attribution: z22.string().max(5e3).optional()
594
- });
595
- var escapeSvg = (value) => value.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
596
- function svgNodeXml(node, prefix = "", colors = {}) {
597
- const attrs = Object.entries(node.attrs ?? {}).map(([key, original]) => {
598
- let value = colors[original] ?? original;
599
- if (key === "id") value = `${prefix}${value}`;
600
- else if (key === "href" && value.startsWith("#")) value = `#${prefix}${value.slice(1)}`;
601
- else value = value.replace(/url\(#([\w.-]+)\)/g, (_, id3) => `url(#${prefix}${id3})`);
602
- return ` ${key}="${escapeSvg(value)}"`;
603
- }).join("");
604
- return `<${node.tag}${attrs}>${escapeSvg(node.text ?? "")}${(node.children ?? []).map((child) => svgNodeXml(child, prefix, colors)).join("")}</${node.tag}>`;
605
- }
606
- var color2 = z3.string().regex(/^#[0-9a-f]{6}(?:[0-9a-f]{2})?$/i);
607
- var box = {
608
- id: z3.string().regex(/^[a-z][a-z0-9-]{0,39}$/),
609
- name: z3.string().min(1).max(80).optional(),
610
- // Bounds of the largest canvas; designIssues checks each product's own canvas.
611
- x: z3.number().min(0).max(1535),
612
- y: z3.number().min(0).max(1535),
613
- w: z3.number().min(1).max(1536),
614
- h: z3.number().min(1).max(1536),
615
- rotation: z3.number().min(-180).max(180).optional(),
616
- opacity: z3.number().min(0).max(1).optional(),
617
- visible: z3.boolean().optional(),
618
- channel: z3.enum(["print", "ink"]).optional(),
619
- protectMaterial: z3.boolean().optional(),
620
- /** Card-only print finish: foil catches the light, raised is embossed on the front. */
621
- finish: z3.enum(["foil", "raised"]).optional()
622
- };
623
- var text2 = z3.object({
624
- ...box,
625
- kind: z3.literal("text"),
626
- text: z3.string().max(160),
627
- binding: z3.enum([
628
- "none",
629
- "name",
630
- "role",
631
- "organization",
632
- "number",
633
- "event",
634
- "location",
635
- "date",
636
- "bio",
637
- "roleOrganization",
638
- "website",
639
- "roleCode",
640
- "admissionRole",
641
- "signature",
642
- "template"
643
- ]),
644
- color: color2,
645
- font: z3.enum([
646
- "sans",
647
- "serif",
648
- "mono",
649
- "display",
650
- "brand",
651
- "script",
652
- "pixel",
653
- "archive",
654
- "rounded"
655
- ]),
656
- strokeColor: color2.optional(),
657
- strokeWidth: z3.number().min(0).max(40).optional(),
658
- size: z3.number().min(12).max(220),
659
- weight: z3.enum(["400", "500", "600", "700", "800", "900"]),
660
- align: z3.enum(["left", "center", "right"]),
661
- tracking: z3.number().min(-8).max(40).optional(),
662
- lineHeight: z3.number().min(0.7).max(2).optional(),
663
- transform: z3.enum(["none", "uppercase", "lowercase"]).optional(),
664
- segment: z3.enum(["all", "first", "last"]).optional(),
665
- fit: z3.enum(["wrap", "shrink", "spread"]).optional(),
666
- baseline: z3.enum(["top", "alphabetic"]).optional(),
667
- italic: z3.boolean().optional(),
668
- prefix: z3.string().max(30).optional(),
669
- suffix: z3.string().max(30).optional(),
670
- highlights: z3.array(z3.object({ text: z3.string().min(1).max(40), color: color2 })).max(8).optional(),
671
- baselineOffset: z3.number().min(0).max(260).optional(),
672
- numberDigits: z3.number().int().min(1).max(8).optional()
673
- });
674
- var shape = z3.object({
675
- ...box,
676
- kind: z3.literal("shape"),
677
- shape: z3.enum(["rectangle", "ellipse", "line", "frame", "corners", "arch", "bevel"]),
678
- color: color2,
679
- radius: z3.number().min(0).max(160),
680
- stroke: z3.number().min(0).max(20),
681
- opacity: z3.number().min(0).max(1)
682
- });
683
- var portrait = z3.object({
684
- ...box,
685
- kind: z3.literal("portrait"),
686
- radius: z3.number().min(0).max(400),
687
- filter: z3.enum([
688
- "original",
689
- "mono",
690
- "rose",
691
- "blue",
692
- "warm",
693
- "thermal",
694
- "silver",
695
- "cyanotype",
696
- "vintage"
697
- ]),
698
- crop: z3.object({
699
- x: z3.number().min(0).max(1),
700
- y: z3.number().min(0).max(1),
701
- zoom: z3.number().min(1).max(12)
702
- }).optional(),
703
- cropMode: z3.enum(["cover", "focus"]).optional(),
704
- fade: z3.object({
705
- x: z3.number().min(0).max(0.5),
706
- right: z3.number().min(0).max(0.5).optional(),
707
- top: z3.number().min(0).max(0.5),
708
- bottom: z3.number().min(0).max(0.5)
709
- }).optional(),
710
- tint: color2.optional(),
711
- tintMode: z3.enum(["multiply", "color"]).optional(),
712
- tintOpacity: z3.number().min(0).max(1).optional(),
713
- contrast: z3.number().min(0.5).max(2).optional(),
714
- brightness: z3.number().min(0.3).max(1.8).optional(),
715
- blur: z3.number().min(0).max(24).optional(),
716
- saturation: z3.number().min(0).max(2).optional(),
717
- clip: z3.enum(["rectangle", "arch", "ellipse"]).optional()
718
- });
719
- var qr = z3.object({
720
- ...box,
721
- kind: z3.literal("qr"),
722
- foreground: color2.optional(),
723
- background: color2.optional(),
724
- align: z3.enum(["center", "start"]).optional(),
725
- maxCellSize: z3.number().int().min(2).max(20).optional()
726
- });
727
- var effect = z3.object({
728
- ...box,
729
- kind: z3.literal("effect"),
730
- effect: z3.enum(["ribbons", "contours", "orbits", "grain", "chromatic-flow"]),
731
- colors: z3.array(color2).length(3),
732
- scale: z3.number().min(0.5).max(6),
733
- opacity: z3.number().min(0).max(1)
734
- });
735
- var graphic = z3.object({
736
- ...box,
737
- kind: z3.literal("graphic"),
738
- pattern: z3.enum([
739
- "grid",
740
- "snow",
741
- "sky",
742
- "grain",
743
- "terrain",
744
- "seal",
745
- "cross",
746
- "window",
747
- "stamp",
748
- "scanlines",
749
- "path",
750
- "paper",
751
- "chromatic-paper",
752
- "checkerboard"
753
- ]),
754
- color: color2,
755
- ink: color2.optional(),
756
- accent: color2,
757
- density: z3.number().min(0.1).max(3),
758
- seed: z3.number().int().min(0).max(4294967295),
759
- path: z3.string().max(16e3).regex(/^[MmLlHhVvCcSsQqTtAaZz0-9.,eE+\-\s]*$/).optional(),
760
- viewBox: z3.object({
761
- width: z3.number().min(1).max(16384),
762
- height: z3.number().min(1).max(16384)
763
- }).optional(),
764
- stroke: z3.number().min(0).max(20).optional(),
765
- variant: z3.enum(["plain", "technical", "editorial", "postal", "snow", "grid", "waves"]).optional(),
766
- reverse: z3.boolean().optional(),
767
- fill: z3.boolean().optional()
768
- });
769
- var gradient = z3.object({
770
- ...box,
771
- kind: z3.literal("gradient"),
772
- direction: z3.enum(["horizontal", "vertical", "diagonal", "radial"]),
773
- stops: z3.array(z3.object({ at: z3.number().min(0).max(1), color: color2 })).min(2).max(8)
774
- });
775
- var ART_ASSET = "art";
776
- var assetId = z3.string().regex(/^[a-z][a-z0-9-]{0,39}$/);
777
- var credit = z3.object({ label: z3.string().min(1).max(120), url: z3.string().url() });
778
- var designAssetSchema = z3.discriminatedUnion("source", [
779
- // Unchanged artwork and optical maps from an attributed bundled sticker collection.
780
- z3.object({
781
- source: z3.literal("sticker"),
782
- collection: z3.enum(["typingmind", "community", "moraleja"]),
783
- slug: z3.string().regex(/^[a-z0-9-]{1,80}$/),
784
- file: z3.enum(["artwork", "effects"]),
785
- name: z3.string().min(1).max(80),
786
- credit
787
- }),
788
- // A Petdex sprite bundled with Makeables, served from /stickers/petdex/<slug>.webp.
789
- z3.object({
790
- source: z3.literal("petdex"),
791
- slug: z3.string().regex(/^[a-z0-9-]{1,80}$/),
792
- name: z3.string().min(1).max(80),
793
- credit: credit.optional()
794
- }),
795
- // A Makeables gallery artwork, served as a raster preview.
796
- z3.object({
797
- source: z3.literal("gallery"),
798
- slug: z3.string().regex(/^[a-z0-9]+(-[a-z0-9]+)*$/),
799
- /** editor-artwork.svg is the same art without baked-in card details. */
800
- file: z3.enum(["artwork.svg", "editor-artwork.svg"]).optional(),
801
- name: z3.string().min(1).max(80)
802
- }),
803
- // An image embedded in the document, so it renders anywhere without a store.
804
- z3.object({
805
- source: z3.literal("image"),
806
- name: z3.string().min(1).max(80),
807
- data: z3.string().regex(/^data:image\/(png|webp|jpeg|gif|svg\+xml);base64,[A-Za-z0-9+/=]+$/).max(28e5).superRefine((value, context) => {
808
- if (!value.startsWith("data:image/svg+xml;base64,")) return;
809
- try {
810
- const svg2 = new TextDecoder().decode(
811
- Uint8Array.from(atob(value.split(",")[1]), (c) => c.charCodeAt(0))
812
- );
813
- const checked = checkSubmittedSvg(svg2);
814
- if (!checked.ok) context.addIssue({ code: "custom", message: checked.error });
815
- } catch {
816
- context.addIssue({ code: "custom", message: "Invalid embedded SVG." });
817
- }
818
- }),
819
- pixelated: z3.boolean().optional(),
820
- /** Detail available before resizing; does not claim upsampling adds pixels. */
821
- sourcePixels: z3.object({
822
- width: z3.number().int().positive().max(24e3),
823
- height: z3.number().int().positive().max(24e3)
824
- }).strict().optional(),
825
- credit: credit.optional()
826
- })
827
- ]);
828
- var image = z3.object({
829
- ...box,
830
- kind: z3.literal("image"),
831
- asset: assetId,
832
- /** cover crops to fill the box (artwork); contain keeps the whole image (stickers). */
833
- fit: z3.enum(["cover", "contain"]).optional(),
834
- /** An intentional full-canvas backdrop may contain the image without cropping. */
835
- background: z3.boolean().optional(),
836
- opacity: z3.number().min(0).max(1),
837
- radius: z3.number().min(0).max(160)
838
- });
839
- var cardMark = z3.object({
840
- ...box,
841
- kind: z3.literal("card-mark"),
842
- mark: z3.enum(["chip", "contactless", "network"]),
843
- slot: z3.enum(["middle-left", "upper-left", "upper-right", "middle-right", "lower-right"]),
844
- color: color2.optional(),
845
- network: z3.enum(["mastercard", "visa", "amex", "discover"]).optional(),
846
- colorMode: z3.enum(["brand", "white", "black"]).optional(),
847
- visaVariant: z3.enum(["boxed", "plain"]).optional()
848
- });
849
- var svg = z3.object({
850
- ...box,
851
- kind: z3.literal("svg"),
852
- nodes: z3.array(svgNodeSchema).min(1).max(1e3),
853
- sourceBox: z3.object({
854
- x: z3.number(),
855
- y: z3.number(),
856
- w: z3.number().positive(),
857
- h: z3.number().positive()
858
- }),
859
- colors: z3.record(z3.string(), color2).optional()
860
- });
861
- var badgeLayerSchema = z3.discriminatedUnion("kind", [
862
- svg,
863
- cardMark,
864
- text2,
865
- shape,
866
- portrait,
867
- qr,
868
- effect,
869
- image,
870
- graphic,
871
- gradient
872
- ]);
873
- var face = z3.object({ background: color2, layers: z3.array(badgeLayerSchema).max(96) });
874
- var badgeDesignObjectSchema = z3.object({
875
- /** Omitted means badge. */
876
- product: z3.enum(productIds).optional(),
877
- sticker: stickerMaterialSchema.optional(),
878
- version: z3.literal(1),
879
- source: z3.string().max(60).optional(),
880
- name: z3.string().min(1).max(60),
881
- description: z3.string().max(180),
882
- artwork: z3.object({ assetId: z3.string().uuid() }).optional(),
883
- assets: z3.record(assetId, designAssetSchema).optional(),
884
- svgSource: svgSourceSchema.optional(),
885
- event: z3.string().min(1).max(80),
886
- artPrompt: z3.string().max(1200),
887
- material: z3.object({
888
- /** Physical badge holder; independent of the printed surface. Omitted means bare. */
889
- holder: z3.enum(["bare", "laminated"]).optional(),
890
- surface: z3.enum(["satin", "prism", "chrome"]),
891
- /** Card-only physical stock; omitted keeps the coated `surface`. */
892
- stock: z3.enum(["metal", "holographic", "soft-touch"]).optional(),
893
- /** Card-only optics that tune the stock to one design. */
894
- optics: z3.object({
895
- /** Brushed-metal or laminate grain: straight at `angle`, rays or rings around `center`. */
896
- grain: z3.enum(["linear", "radial", "concentric"]).optional(),
897
- angle: z3.number().min(0).max(180).optional(),
898
- center: z3.object({ x: z3.number().min(0).max(1), y: z3.number().min(0).max(1) }).optional(),
899
- grainStrength: z3.number().min(0).max(1).optional(),
900
- /** Foil color; omitted keeps each layer's own ink. */
901
- foil: color2.optional(),
902
- /** Color of the moving highlight. */
903
- light: color2.optional(),
904
- /** Three stops the holographic laminate cycles through instead of a full rainbow. */
905
- spectrum: z3.array(color2).length(3).optional(),
906
- diffraction: z3.enum(["linear", "radial"]).optional(),
907
- sparkle: z3.number().min(0).max(1).optional(),
908
- relief: z3.number().min(0).max(1).optional(),
909
- /** Width of the moving highlight, from a sharp streak to a broad glow. */
910
- sheen: z3.number().min(0).max(1).optional()
911
- }).strict().optional(),
912
- roughness: z3.number().min(0).max(1),
913
- iridescence: z3.number().min(0).max(0.65),
914
- speed: z3.number().min(0).max(1),
915
- recipe: prismRecipeSchema.optional(),
916
- effect: z3.enum(["standard", "ribbons", "topographic"]).optional(),
917
- focus: z3.object({
918
- x: z3.number().min(0).max(1),
919
- y: z3.number().min(0).max(1),
920
- radius: z3.number().min(0.1).max(0.5)
921
- }).optional()
922
- }),
923
- front: face,
924
- back: face
925
- });
926
- function isRoleBoundLayer(layer) {
927
- return layer.kind === "text" && (["role", "roleOrganization", "admissionRole"].includes(layer.binding) || layer.binding === "template" && /\{(?:role|roleOrganization|admissionRole)\}/.test(layer.text));
928
- }
929
- function overlaps(a, b) {
930
- const aa = designLayerBounds(a);
931
- const bb = designLayerBounds(b);
932
- return aa.x < bb.x + bb.w && aa.x + aa.w > bb.x && aa.y < bb.y + bb.h && aa.y + aa.h > bb.y;
933
- }
934
- function designLayerBounds(layer) {
935
- const angle = (layer.rotation ?? 0) * Math.PI / 180;
936
- const swap = Math.abs(layer.rotation ?? 0) === 90;
937
- const width = swap ? layer.h : layer.w;
938
- const height = swap ? layer.w : layer.h;
939
- const w = Math.abs(Math.cos(angle)) * width + Math.abs(Math.sin(angle)) * height;
940
- const h = Math.abs(Math.sin(angle)) * width + Math.abs(Math.cos(angle)) * height;
941
- return { x: layer.x + (layer.w - w) / 2, y: layer.y + (layer.h - h) / 2, w, h };
942
- }
943
- function luminance(hex) {
944
- const rgb = [1, 3, 5].map((start) => Number.parseInt(hex.slice(start, start + 2), 16) / 255);
945
- return rgb.map((value) => value <= 0.04045 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4).reduce((total, value, index) => total + value * [0.2126, 0.7152, 0.0722][index], 0);
946
- }
947
- function designIssues(design2) {
948
- const issues2 = [];
949
- const profile = designProfile(design2);
950
- const badge = profile.id === "badge";
951
- if (!badge && design2.material.holder) issues2.push("A holder is only available for badges.");
952
- if (profile.id !== "card" && (design2.material.stock || design2.material.optics))
953
- issues2.push("Stock and optics are only available for cards.");
954
- for (const side2 of ["front", "back"])
955
- for (const layer of design2[side2].layers) {
956
- if (!layer.finish) continue;
957
- if (profile.id !== "card")
958
- issues2.push(`${side2}.${layer.id}: finish is only available for cards.`);
959
- else if (layer.finish === "raised" && side2 === "back")
960
- issues2.push(`back.${layer.id}: raised finish is only available on the front.`);
961
- }
962
- const assets = design2.assets ?? {};
963
- if (design2.sticker?.effectMap) {
964
- const { asset, layer } = design2.sticker.effectMap;
965
- if (!assets[asset]) issues2.push(`sticker.effectMap: missing asset ${asset}`);
966
- if (!design2.front.layers.some((value) => value.id === layer && value.kind === "image"))
967
- issues2.push(`sticker.effectMap: ${layer} must name a front image layer`);
968
- }
969
- for (const id3 of Object.keys(design2.sticker?.regions ?? {}))
970
- if (!design2.front.layers.some((layer) => layer.id === id3))
971
- issues2.push(`sticker.regions: missing front layer ${id3}`);
972
- if (profile.id === "sticker" && design2.back.layers.length)
973
- issues2.push("Stickers have one editable face; keep back layers empty.");
974
- if (Object.keys(assets).length > 24) issues2.push("assets: 24 como m\xE1ximo");
975
- for (const side2 of ["front", "back"])
976
- for (const layer of design2[side2].layers)
977
- if (layer.kind === "image" && layer.asset !== ART_ASSET && !assets[layer.asset])
978
- issues2.push(`${side2}.${layer.id}: falta el asset ${layer.asset}`);
979
- for (const side2 of ["front", "back"]) {
980
- const layers = design2[side2].layers;
981
- const ids = /* @__PURE__ */ new Set();
982
- for (const [i, layer] of layers.entries()) {
983
- if (ids.has(layer.id)) issues2.push(`${side2}: ID repetido ${layer.id}`);
984
- ids.add(layer.id);
985
- const bounds = designLayerBounds(layer);
986
- if (bounds.x < -0.01 || bounds.y < -0.01 || bounds.x + bounds.w > profile.width + 0.01 || bounds.y + bounds.h > profile.height + 0.01)
987
- issues2.push(`${side2}.${layer.id}: outside the ${profile.label.toLowerCase()}`);
988
- if (profile.id === "sticker" && layer.kind === "text" && layer.binding !== "none")
989
- issues2.push("Sticker text uses free text, without participant bindings.");
990
- if (profile.id === "sticker" && layer.kind === "portrait")
991
- issues2.push("Stickers use image layers, not participant portraits.");
992
- if (!badge && layer.kind === "qr")
993
- issues2.push(`${side2}.${layer.id}: QR codes are for badges`);
994
- if (layer.kind === "svg" && !design2.svgSource)
995
- issues2.push(`${side2}.${layer.id}: missing original SVG definitions`);
996
- if (side2 === "front" && layer.visible !== false && !isBackground(layer, profile)) {
997
- for (const area2 of profile.keepClear)
998
- if (intersects(bounds, area2))
999
- issues2.push(`${side2}.${layer.id}: covers the ${area2.label} area`);
1000
- }
1001
- if (badge && ["text", "portrait", "qr"].includes(layer.kind) && bounds.y < 89.99)
1002
- issues2.push(`${side2}.${layer.id}: reserva superior de 90 px`);
1003
- if ((layer.kind === "portrait" || layer.kind === "image") && layer.channel === "ink")
1004
- issues2.push(`${side2}.${layer.id}: las im\xE1genes pertenecen a la impresi\xF3n`);
1005
- if (layer.kind === "graphic" && layer.pattern === "path") {
1006
- const path2 = layer.path?.trim() ?? "";
1007
- const numbers2 = path2.match(/[-+]?(?:\d*\.?\d+)(?:[eE][-+]?\d+)?/g) ?? [];
1008
- if (!/^[Mm]/.test(path2) || numbers2.some(
1009
- (value) => !Number.isFinite(Number(value)) || Math.abs(Number(value)) > 16384
1010
- ))
1011
- issues2.push(`${side2}.${layer.id}: trazado inv\xE1lido o fuera de rango`);
1012
- }
1013
- if (layer.kind === "qr") {
1014
- const minimum = side2 === "front" ? 128 : 280;
1015
- if (layer.w < minimum || layer.w !== layer.h || layer.rotation || (layer.opacity ?? 1) !== 1)
1016
- issues2.push(`${side2}.${layer.id}: QR cuadrado de al menos ${minimum} px`);
1017
- const foreground = layer.foreground ?? "#111111";
1018
- const background = layer.background ?? "#ffffff";
1019
- const light = Math.max(luminance(foreground), luminance(background));
1020
- const dark = Math.min(luminance(foreground), luminance(background));
1021
- if ((light + 0.05) / (dark + 0.05) < 4.5 || [foreground, background].some(
1022
- (value) => value.length > 7 && value.slice(7).toLowerCase() !== "ff"
1023
- ))
1024
- issues2.push(`${side2}.${layer.id}: el QR necesita colores opacos y contrastantes`);
1025
- if (layer.visible !== false && layers.slice(i + 1).some((l) => l.visible !== false && overlaps(layer, l)))
1026
- issues2.push(`${side2}.${layer.id}: QR tapado por otra capa`);
1027
- }
1028
- }
1029
- if (badge && layers.length < 3) issues2.push(`${side2}: al menos 3 capas`);
1030
- if (badge && !layers.some((l) => l.kind === "text" && l.binding === "name"))
1031
- issues2.push(`${side2}: falta el nombre vinculado`);
1032
- }
1033
- const portraits = design2.front.layers.filter((l) => l.kind === "portrait").length;
1034
- if (badge && (portraits < 1 || portraits > 4)) issues2.push("front: debe tener un retrato");
1035
- if (!badge && portraits > 4) issues2.push("front: 4 portraits at most");
1036
- for (const side2 of ["front", "back"])
1037
- if (design2[side2].layers.filter((layer) => layer.kind === "effect").length > 24)
1038
- issues2.push(`${side2}: m\xE1ximo 24 efectos`);
1039
- if (badge && !design2.back.layers.some((l) => l.kind === "qr")) issues2.push("back: falta el QR");
1040
- if (badge && !design2.back.layers.some(isRoleBoundLayer))
1041
- issues2.push("back: falta el rol vinculado");
1042
- return issues2;
1043
- }
1044
- function intersects(a, b) {
1045
- return a.x < b.x + b.w && b.x < a.x + a.w && a.y < b.y + b.h && b.y < a.y + a.h;
1046
- }
1047
- function isBackground(layer, profile) {
1048
- if (layer.kind === "svg" && !layer.rotation && ["x", "y", "w", "h"].every((key) => layer[key] === layer.sourceBox[key]))
1049
- return true;
1050
- return (layer.kind === "image" || layer.kind === "gradient" || layer.kind === "effect" || layer.kind === "graphic" || layer.kind === "svg") && (layer.kind !== "image" || layer.fit !== "contain" || layer.background === true) && layer.x <= 0 && layer.y <= 0 && layer.x + layer.w >= profile.width && layer.y + layer.h >= profile.height;
1051
- }
1052
- var badgeDesignSchema = badgeDesignObjectSchema.transform((design2) => {
1053
- if (design2.product !== "card") return design2;
1054
- return {
1055
- ...design2,
1056
- front: {
1057
- ...design2.front,
1058
- layers: design2.front.layers.map(
1059
- (layer) => layer.kind === "card-mark" ? { ...layer, ...cardMarkRegion(layer) } : layer
1060
- )
1061
- },
1062
- back: {
1063
- ...design2.back,
1064
- layers: design2.back.layers.map(
1065
- (layer) => layer.kind === "card-mark" ? { ...layer, ...cardMarkRegion(layer) } : layer
1066
- )
1067
- }
1068
- };
1069
- }).superRefine((design2, context) => {
1070
- for (const message of designIssues(design2))
1071
- context.addIssue({ code: z3.ZodIssueCode.custom, message });
1072
- });
1073
- var designLockSchema = z3.object({
1074
- front: z3.array(z3.string()).max(96),
1075
- back: z3.array(z3.string()).max(96),
1076
- material: z3.boolean()
1077
- });
1078
- function preserveDesignLocks(current, next, locks) {
1079
- const output = structuredClone(next);
1080
- if (locks.material) {
1081
- output.material = structuredClone(current.material);
1082
- output.sticker = current.sticker ? structuredClone(current.sticker) : void 0;
1083
- }
1084
- for (const side2 of ["front", "back"]) {
1085
- const locked = new Set(locks[side2]);
1086
- output[side2].layers = output[side2].layers.filter((l) => !locked.has(l.id));
1087
- for (const [index, layer] of current[side2].layers.entries()) {
1088
- if (locked.has(layer.id))
1089
- output[side2].layers.splice(
1090
- Math.min(index, output[side2].layers.length),
1091
- 0,
1092
- structuredClone(layer)
1093
- );
1094
- }
1095
- }
1096
- return badgeDesignSchema.parse(output);
1097
- }
1098
- function referencedDesignAssets(design2) {
1099
- return [
1100
- .../* @__PURE__ */ new Set([
1101
- ...["front", "back"].flatMap(
1102
- (side2) => design2[side2].layers.flatMap((layer) => layer.kind === "image" ? [layer.asset] : [])
1103
- ),
1104
- ...design2.sticker?.effectMap ? [design2.sticker.effectMap.asset] : []
1105
- ])
1106
- ];
1107
- }
1108
- function pruneAssets(design2) {
1109
- if (design2.sticker) {
1110
- const ids = new Set(design2.front.layers.map((layer) => layer.id));
1111
- design2 = {
1112
- ...design2,
1113
- sticker: {
1114
- ...design2.sticker,
1115
- effectMap: design2.sticker.effectMap && ids.has(design2.sticker.effectMap.layer) ? design2.sticker.effectMap : void 0,
1116
- regions: design2.sticker.regions ? Object.fromEntries(Object.entries(design2.sticker.regions).filter(([id3]) => ids.has(id3))) : void 0
1117
- }
1118
- };
1119
- }
1120
- if (!design2.assets) return design2;
1121
- const used = new Set(referencedDesignAssets(design2));
1122
- const assets = Object.fromEntries(Object.entries(design2.assets).filter(([id3]) => used.has(id3)));
1123
- return { ...design2, assets };
1124
- }
1125
- var STICKER_SIZE = 280;
1126
- var STICKER_SLOTS = [
1127
- [0.74, 0.3],
1128
- [0.26, 0.66],
1129
- [0.74, 0.66],
1130
- [0.26, 0.3]
1131
- ];
1132
- function stickerPosition(layers, w, h, canvas2, front) {
1133
- const count = layers.filter((layer) => layer.kind === "image" && layer.fit === "contain").length;
1134
- const place = ([cx, cy]) => ({
1135
- x: Math.round(Math.min(canvas2.width - 1 - w, Math.max(0, canvas2.width * cx - w / 2))),
1136
- y: Math.round(Math.min(canvas2.height - 1 - h, Math.max(0, canvas2.height * cy - h / 2)))
1137
- });
1138
- const clear = (position) => !front || canvas2.keepClear.every(
1139
- (area2) => !(position.x < area2.x + area2.w && area2.x < position.x + w && position.y < area2.y + area2.h && area2.y < position.y + h)
1140
- );
1141
- const slots = STICKER_SLOTS.map(place).filter(clear);
1142
- const usable = slots.length ? slots : STICKER_SLOTS.map(place);
1143
- const slot = usable[count % usable.length];
1144
- const nudge = Math.floor(count / usable.length) * 36;
1145
- return {
1146
- x: Math.min(canvas2.width - 1 - w, slot.x + nudge),
1147
- y: Math.min(canvas2.height - 1 - h, slot.y + nudge)
1148
- };
1149
- }
1150
- function addSticker(design2, side2, asset, size, id3) {
1151
- const canvas2 = designProfile(design2);
1152
- const longest = Math.min(STICKER_SIZE, Math.round(Math.min(canvas2.width, canvas2.height) / 3));
1153
- const ratio = longest / Math.max(size.width, size.height, 1);
1154
- const w = Math.max(1, Math.round(size.width * ratio));
1155
- const h = Math.max(1, Math.round(size.height * ratio));
1156
- const assetId2 = `sticker-${id3}`;
1157
- const layer = {
1158
- id: assetId2,
1159
- kind: "image",
1160
- asset: assetId2,
1161
- fit: "contain",
1162
- ...stickerPosition(design2[side2].layers, w, h, canvas2, side2 === "front"),
1163
- w,
1164
- h,
1165
- opacity: 1,
1166
- radius: 0
1167
- };
1168
- const layers = [...design2[side2].layers];
1169
- const qr2 = layers.findIndex((item) => item.kind === "qr");
1170
- layers.splice(qr2 < 0 ? layers.length : qr2, 0, layer);
1171
- return badgeDesignSchema.parse({
1172
- ...design2,
1173
- assets: { ...design2.assets, [assetId2]: asset },
1174
- [side2]: { ...design2[side2], layers }
1175
- });
1176
- }
1177
- function cardMarkLayer(id3, spec) {
1178
- const { x, y, w, h } = cardMarkRegion(spec);
1179
- return { id: id3, kind: "card-mark", ...spec, x, y, w, h };
1180
- }
1181
- function createCardDesign(gallery) {
1182
- const { width, height } = designProfiles.card;
1183
- return badgeDesignSchema.parse({
1184
- product: "card",
1185
- version: 1,
1186
- name: gallery.title,
1187
- description: "",
1188
- event: gallery.title,
1189
- artPrompt: "",
1190
- material: { surface: "satin", roughness: 0.4, iridescence: 0, speed: 0 },
1191
- assets: {
1192
- artwork: {
1193
- source: "gallery",
1194
- slug: gallery.slug,
1195
- name: gallery.title,
1196
- ...gallery.file ? { file: gallery.file } : {}
1197
- }
1198
- },
1199
- front: {
1200
- background: "#111111",
1201
- layers: [
1202
- {
1203
- id: "artwork",
1204
- kind: "image",
1205
- asset: "artwork",
1206
- fit: "cover",
1207
- x: 0,
1208
- y: 0,
1209
- w: width,
1210
- h: height,
1211
- opacity: 1,
1212
- radius: 0
1213
- },
1214
- cardMarkLayer("chip", { mark: "chip", slot: "middle-left", color: "#d9b875" }),
1215
- cardMarkLayer("contactless", {
1216
- mark: "contactless",
1217
- slot: "upper-right",
1218
- color: "#ffffff"
1219
- }),
1220
- cardMarkLayer("network", {
1221
- mark: "network",
1222
- slot: "lower-right",
1223
- network: "mastercard",
1224
- colorMode: "brand"
1225
- })
1226
- ]
1227
- },
1228
- back: { background: "#141414", layers: [] }
1229
- });
1230
- }
1231
-
1232
- // ../design/dist/chunk-MF6TKV3S.js
1233
- import { z as z4 } from "zod";
1234
- var printerPresets = {
1235
- generic: {
1236
- name: "Generic kiss-cut printer",
1237
- cutSpot: "CutContour",
1238
- whiteSpot: "White",
1239
- bleedMm: 1,
1240
- safeMm: 1.5,
1241
- gapMm: 3,
1242
- marginMm: 5
1243
- }
1244
- };
1245
- var sheetSizes = {
1246
- a5: { name: "A5", widthMm: 148, heightMm: 210 },
1247
- a6: { name: "A6", widthMm: 105, heightMm: 148 },
1248
- "10x15": { name: "10 \xD7 15 cm", widthMm: 100, heightMm: 150 }
1249
- };
1250
- var sheetTypes = {
1251
- classic: {
1252
- name: "Classic sheet",
1253
- cut: "kiss-cut",
1254
- sizes: ["a5"],
1255
- stock: "white",
1256
- laminate: "matte",
1257
- borderMm: 2,
1258
- white: false,
1259
- stickerWidthMm: 45
1260
- },
1261
- small: {
1262
- name: "Small sheet",
1263
- cut: "kiss-cut",
1264
- sizes: ["a6", "10x15"],
1265
- stock: "white",
1266
- laminate: "gloss",
1267
- borderMm: 2,
1268
- white: false,
1269
- stickerWidthMm: 35
1270
- },
1271
- single: {
1272
- name: "Single sticker",
1273
- cut: "die-cut",
1274
- sizes: [],
1275
- stock: "white",
1276
- laminate: "gloss",
1277
- borderMm: 2,
1278
- white: false,
1279
- stickerWidthMm: 75
1280
- },
1281
- clear: {
1282
- name: "Clear",
1283
- cut: "kiss-cut",
1284
- sizes: ["a6"],
1285
- stock: "clear",
1286
- laminate: "gloss",
1287
- borderMm: 0,
1288
- white: true,
1289
- stickerWidthMm: 35
1290
- },
1291
- holographic: {
1292
- name: "Holographic",
1293
- cut: "kiss-cut",
1294
- sizes: ["a6"],
1295
- stock: "holographic",
1296
- laminate: "gloss",
1297
- borderMm: 2,
1298
- white: true,
1299
- stickerWidthMm: 35
1300
- }
1301
- };
1302
- var sheetTypeIds = Object.keys(sheetTypes);
1303
- var id = z4.string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/);
1304
- var sheetItemSchema = z4.object({
1305
- id,
1306
- design: badgeDesignSchema,
1307
- /** Centre of the sticker canvas on the sheet. */
1308
- x: z4.number().min(-1e3).max(1e3),
1309
- y: z4.number().min(-1e3).max(1e3),
1310
- rotation: z4.number().min(-360).max(360),
1311
- /** Printed width of the square sticker canvas. */
1312
- widthMm: z4.number().min(5).max(300)
1313
- });
1314
- var stickerSheetSchema = z4.object({
1315
- format: z4.literal("makeables-sheet"),
1316
- version: z4.literal(1),
1317
- name: z4.string().min(1).max(80),
1318
- type: z4.enum(sheetTypeIds),
1319
- printer: z4.enum(Object.keys(printerPresets)),
1320
- size: z4.enum(Object.keys(sheetSizes)).optional(),
1321
- /** Border override for every sticker; the type's border otherwise. */
1322
- borderMm: z4.number().min(0).max(10).optional(),
1323
- /** Auto-pack keeps this sticker where it is. */
1324
- hero: id.optional(),
1325
- items: z4.array(sheetItemSchema).max(200)
1326
- }).superRefine((sheet, context) => {
1327
- const type = sheetTypes[sheet.type];
1328
- if (type.cut === "kiss-cut" && !sheet.size)
1329
- context.addIssue({ code: "custom", path: ["size"], message: "Kiss-cut sheets need a size." });
1330
- if (sheet.size && !type.sizes.includes(sheet.size))
1331
- context.addIssue({
1332
- code: "custom",
1333
- path: ["size"],
1334
- message: `${type.name} comes in ${type.sizes.join(", ") || "the sticker's own size"}.`
1335
- });
1336
- if (type.cut === "die-cut" && sheet.items.length > 1)
1337
- context.addIssue({
1338
- code: "custom",
1339
- path: ["items"],
1340
- message: "A single sticker file holds one sticker."
1341
- });
1342
- const ids = /* @__PURE__ */ new Set();
1343
- for (const [index, item] of sheet.items.entries()) {
1344
- if (ids.has(item.id))
1345
- context.addIssue({
1346
- code: "custom",
1347
- path: ["items", index, "id"],
1348
- message: "Duplicate id."
1349
- });
1350
- ids.add(item.id);
1351
- if (item.design.product !== "sticker")
1352
- context.addIssue({
1353
- code: "custom",
1354
- path: ["items", index, "design"],
1355
- message: "Sheet items are sticker designs."
1356
- });
1357
- }
1358
- if (sheet.hero && !ids.has(sheet.hero))
1359
- context.addIssue({ code: "custom", path: ["hero"], message: "Hero is not on the sheet." });
1360
- });
1361
- function sheetSpec(sheet) {
1362
- const type = sheetTypes[sheet.type];
1363
- const size = sheet.size ? sheetSizes[sheet.size] : void 0;
1364
- return {
1365
- ...printerPresets[sheet.printer],
1366
- type,
1367
- borderMm: sheet.borderMm ?? type.borderMm,
1368
- widthMm: size?.widthMm,
1369
- heightMm: size?.heightMm
1370
- };
1371
- }
1372
- function createStickerSheet(type, name = sheetTypes[type].name) {
1373
- const sizes = sheetTypes[type].sizes;
1374
- return {
1375
- format: "makeables-sheet",
1376
- version: 1,
1377
- name,
1378
- type,
1379
- printer: "generic",
1380
- ...sizes[0] ? { size: sizes[0] } : {},
1381
- items: []
1382
- };
1383
- }
1384
- function sheetBorderPixels(borderMm, widthMm, pixels) {
1385
- return borderMm * pixels / widthMm;
1386
- }
1
+ import {
2
+ PACKAGE_LIMIT,
3
+ addSticker,
4
+ badgeDesignObjectSchema,
5
+ badgeDesignSchema,
6
+ badgeLayerSchema,
7
+ badgeQrLayout,
8
+ cardMarkLayer,
9
+ cardMarkSvg,
10
+ createCardDesign,
11
+ defaultStickerMaterial,
12
+ designProfile,
13
+ draftPackage,
14
+ hashBytes,
15
+ importDraft,
16
+ jsonBytes,
17
+ missingAssets,
18
+ parseJson,
19
+ preserveDesignLocks,
20
+ pruneAssets,
21
+ readPackageJson,
22
+ readPackageZip,
23
+ requiredAssets,
24
+ sheetBorderPixels,
25
+ sheetSpec,
26
+ sheetTypes,
27
+ stickerMaterialSchema,
28
+ submissionMetadataSchema,
29
+ svgNodeXml,
30
+ svgPackage
31
+ } from "./chunk-DLTVENEP.js";
1387
32
 
1388
33
  // ../design/dist/chunk-VKBNWHNO.js
1389
- var t = (id3, value, x, baseline, w, size, font, color3, extra = {}) => ({
1390
- id: id3,
34
+ var t = (id, value, x, baseline, w, size, font, color, extra = {}) => ({
35
+ id,
1391
36
  kind: "text",
1392
37
  binding: value.startsWith("$") ? value.slice(1) : "none",
1393
38
  text: value.startsWith("$") ? "" : value,
@@ -1397,7 +42,7 @@ var t = (id3, value, x, baseline, w, size, font, color3, extra = {}) => ({
1397
42
  h: Math.min(size * 1.15, 1536 - baseline + size),
1398
43
  size,
1399
44
  font,
1400
- color: color3,
45
+ color,
1401
46
  weight: ["mono", "pixel", "script"].includes(font) ? "400" : "700",
1402
47
  align: "left",
1403
48
  baseline: "alphabetic",
@@ -1406,19 +51,19 @@ var t = (id3, value, x, baseline, w, size, font, color3, extra = {}) => ({
1406
51
  lineHeight: 1,
1407
52
  ...extra
1408
53
  });
1409
- var s = (id3, x, y, w, h, color3, shape2 = "rectangle", opacity = 1) => ({
1410
- id: id3,
54
+ var s = (id, x, y, w, h, color, shape = "rectangle", opacity = 1) => ({
55
+ id,
1411
56
  kind: "shape",
1412
57
  x,
1413
58
  y,
1414
59
  w,
1415
60
  h,
1416
- color: color3,
1417
- shape: shape2,
61
+ color,
62
+ shape,
1418
63
  opacity,
1419
64
  channel: "ink",
1420
65
  radius: 0,
1421
- stroke: shape2 === "corners" ? 4 : 2
66
+ stroke: shape === "corners" ? 4 : 2
1422
67
  });
1423
68
  var p = (x, y, w, h, extra = {}) => ({
1424
69
  id: "portrait",
@@ -1432,15 +77,15 @@ var p = (x, y, w, h, extra = {}) => ({
1432
77
  crop: { x: 0.5, y: 0.5, zoom: 1 },
1433
78
  ...extra
1434
79
  });
1435
- var g = (id3, pattern, x, y, w, h, color3, accent = color3, extra = {}) => ({
1436
- id: id3,
80
+ var g = (id, pattern, x, y, w, h, color, accent = color, extra = {}) => ({
81
+ id,
1437
82
  kind: "graphic",
1438
83
  pattern,
1439
84
  x,
1440
85
  y,
1441
86
  w,
1442
87
  h,
1443
- color: color3,
88
+ color,
1444
89
  accent,
1445
90
  density: 1,
1446
91
  seed: 1,
@@ -1457,7 +102,7 @@ var q = (x, y, w) => ({
1457
102
  foreground: "#090a0b"
1458
103
  });
1459
104
  var upper = { transform: "uppercase" };
1460
- var rule = (id3, y, color3, x = 84, w = 856) => s(id3, x, y, w, 1.5, color3, "rectangle", 0.35);
105
+ var rule = (id, y, color, x = 84, w = 856) => s(id, x, y, w, 1.5, color, "rectangle", 0.35);
1461
106
  var flow = () => g("flow", "chromatic-paper", 0, 0, 1024, 1536, "#f8eff3", "#f563fc");
1462
107
  function design(source, event, description, background, front, back, surface = "satin") {
1463
108
  return {
@@ -1715,7 +360,7 @@ var archive = design(
1715
360
  q(92, 931, 336)
1716
361
  ]
1717
362
  );
1718
- function classic(id3, event, title, subtitle, base, ink, accent, font, layout) {
363
+ function classic(id, event, title, subtitle, base, ink, accent, font, layout) {
1719
364
  const variant = layout === "winter" ? "snow" : layout === "postage" ? "postal" : "grid";
1720
365
  const decoration = () => [g("paper", "paper", 0, 0, 1024, 1536, base, accent, { variant, ink })];
1721
366
  const x = layout === "terminal" ? 102 : layout === "postage" ? 160 : 140;
@@ -1812,7 +457,7 @@ function classic(id3, event, title, subtitle, base, ink, accent, font, layout) {
1812
457
  { ...q(84, 823, 374), foreground: "#141414", maxCellSize: 10 }
1813
458
  ];
1814
459
  return design(
1815
- id3,
460
+ id,
1816
461
  event,
1817
462
  layout === "winter" ? "Cristal de invierno, nieve y retrato con arco." : layout === "terminal" ? "F\xF3sforo c\xE1lido, ret\xEDcula y l\xEDneas de escaneo." : "Cobre quemado, marco doble y sello de edici\xF3n.",
1818
463
  base,
@@ -1821,9 +466,9 @@ function classic(id3, event, title, subtitle, base, ink, accent, font, layout) {
1821
466
  layout === "winter" ? "prism" : "satin"
1822
467
  );
1823
468
  }
1824
- var window2 = (id3, x, y, w, h, title) => [
1825
- g(id3, "window", x, y, w, h, "#dedede", "#1807c7"),
1826
- t(`${id3}-title`, title, x + 20, y + 43, w - 150, 23, "pixel", "#ffffff")
469
+ var window2 = (id, x, y, w, h, title) => [
470
+ g(id, "window", x, y, w, h, "#dedede", "#1807c7"),
471
+ t(`${id}-title`, title, x + 20, y + 43, w - 150, 23, "pixel", "#ffffff")
1827
472
  ];
1828
473
  var sky = () => g("sky", "sky", 0, 0, 1024, 1536, "#28518b", "#79a310", { seed: 1010 });
1829
474
  var vibecode = design(
@@ -2103,9 +748,9 @@ var gtm = design(
2103
748
  q(92, 974, 360)
2104
749
  ]
2105
750
  );
2106
- var signalFrame = (id3, y, h) => [
2107
- s(`${id3}-rule`, 72, y, 660, h, "#f4f4f2", "frame", 0.22),
2108
- s(id3, 72, y, 660, h, "#f4f4f2", "corners")
751
+ var signalFrame = (id, y, h) => [
752
+ s(`${id}-rule`, 72, y, 660, h, "#f4f4f2", "frame", 0.22),
753
+ s(id, 72, y, 660, h, "#f4f4f2", "corners")
2109
754
  ];
2110
755
  var signalHeader = () => [
2111
756
  ...signalFrame("header", 148, 190),
@@ -2125,7 +770,7 @@ var signalHeader = () => [
2125
770
  }),
2126
771
  s("red-rule", 788, 148, 7, 52, "#bd0a2b")
2127
772
  ];
2128
- var numbers = (id3, y) => t(id3, "#{number} * #{number} * #{number}", 108, y, 586, 26, "mono", "#f4f4f2", {
773
+ var numbers = (id, y) => t(id, "#{number} * #{number} * #{number}", 108, y, 586, 26, "mono", "#f4f4f2", {
2129
774
  binding: "template",
2130
775
  fit: "spread",
2131
776
  opacity: 0.4
@@ -2221,7 +866,7 @@ var collectionDesigns = [
2221
866
  ].map((value) => badgeDesignSchema.parse(value));
2222
867
 
2223
868
  // ../design/dist/index.js
2224
- import { z as z5 } from "zod";
869
+ import { z } from "zod";
2225
870
  var cardFinishRecipes = {
2226
871
  // A printer's proof: CMY registration light, scanline grain, sharp glitch edges.
2227
872
  afterimage: {
@@ -2734,77 +1379,77 @@ var chrome = {
2734
1379
  iridescence: 0.1,
2735
1380
  speed: 0.12
2736
1381
  };
2737
- function named(id3, [x, y, w, h]) {
1382
+ function named(id, [x, y, w, h]) {
2738
1383
  return {
2739
- id: id3,
2740
- name: id3.replace(/-/g, " ").replace(/^./, (letter) => letter.toUpperCase()),
1384
+ id,
1385
+ name: id.replace(/-/g, " ").replace(/^./, (letter) => letter.toUpperCase()),
2741
1386
  x,
2742
1387
  y,
2743
1388
  w,
2744
1389
  h
2745
1390
  };
2746
1391
  }
2747
- function rect(id3, box3, color3, radius = 0, opacity = 1) {
1392
+ function rect(id, box2, color, radius = 0, opacity = 1) {
2748
1393
  return {
2749
- ...named(id3, box3),
1394
+ ...named(id, box2),
2750
1395
  kind: "shape",
2751
1396
  shape: "rectangle",
2752
- color: color3,
1397
+ color,
2753
1398
  radius,
2754
1399
  stroke: 0,
2755
1400
  opacity,
2756
1401
  protectMaterial: false
2757
1402
  };
2758
1403
  }
2759
- function circle(id3, cx, cy, radius, color3, stroke = 0, opacity = 1) {
1404
+ function circle(id, cx, cy, radius, color, stroke = 0, opacity = 1) {
2760
1405
  if (stroke > 0) {
2761
1406
  const r = radius - stroke / 2;
2762
1407
  return path(
2763
- id3,
1408
+ id,
2764
1409
  [cx - radius, cy - radius, radius * 2, radius * 2],
2765
1410
  `M${radius - r} ${radius}a${r} ${r} 0 1 0 ${r * 2} 0a${r} ${r} 0 1 0 ${-r * 2} 0`,
2766
- color3,
1411
+ color,
2767
1412
  stroke,
2768
1413
  opacity
2769
1414
  );
2770
1415
  }
2771
1416
  return {
2772
- ...named(id3, [cx - radius, cy - radius, radius * 2, radius * 2]),
1417
+ ...named(id, [cx - radius, cy - radius, radius * 2, radius * 2]),
2773
1418
  kind: "shape",
2774
1419
  shape: "ellipse",
2775
- color: color3,
1420
+ color,
2776
1421
  radius: 0,
2777
1422
  stroke,
2778
1423
  opacity,
2779
1424
  protectMaterial: false
2780
1425
  };
2781
1426
  }
2782
- function path(id3, box3, d, color3, stroke = 0, opacity = 1, viewBox) {
1427
+ function path(id, box2, d, color, stroke = 0, opacity = 1, viewBox) {
2783
1428
  return {
2784
- ...named(id3, box3),
1429
+ ...named(id, box2),
2785
1430
  kind: "graphic",
2786
1431
  pattern: "path",
2787
- color: color3,
2788
- accent: color3,
1432
+ color,
1433
+ accent: color,
2789
1434
  density: 1,
2790
1435
  seed: 1,
2791
1436
  path: d,
2792
- viewBox: viewBox ?? { width: box3[2], height: box3[3] },
1437
+ viewBox: viewBox ?? { width: box2[2], height: box2[3] },
2793
1438
  stroke,
2794
1439
  opacity,
2795
1440
  protectMaterial: false
2796
1441
  };
2797
1442
  }
2798
- function field(id3, d, color3, stroke = 0, opacity = 1) {
2799
- return path(id3, full, d, color3, stroke, opacity);
1443
+ function field(id, d, color, stroke = 0, opacity = 1) {
1444
+ return path(id, full, d, color, stroke, opacity);
2800
1445
  }
2801
- function text3(id3, value, box3, color3, size = 20, font = "mono", weight = "500") {
1446
+ function text(id, value, box2, color, size = 20, font = "mono", weight = "500") {
2802
1447
  return {
2803
- ...named(id3, box3),
1448
+ ...named(id, box2),
2804
1449
  kind: "text",
2805
1450
  text: value,
2806
1451
  binding: "none",
2807
- color: color3,
1452
+ color,
2808
1453
  font,
2809
1454
  size,
2810
1455
  weight,
@@ -2814,18 +1459,18 @@ function text3(id3, value, box3, color3, size = 20, font = "mono", weight = "500
2814
1459
  protectMaterial: true
2815
1460
  };
2816
1461
  }
2817
- function gradient2(id3, colors, direction = "diagonal", box3 = full) {
1462
+ function gradient(id, colors, direction = "diagonal", box2 = full) {
2818
1463
  return {
2819
- ...named(id3, box3),
1464
+ ...named(id, box2),
2820
1465
  kind: "gradient",
2821
1466
  direction,
2822
- stops: colors.map((color3, index) => ({ color: color3, at: index / (colors.length - 1) }))
1467
+ stops: colors.map((color, index) => ({ color, at: index / (colors.length - 1) }))
2823
1468
  };
2824
1469
  }
2825
- function film(id3, effect22, colors, opacity = 0.1, box3 = full) {
2826
- return { ...named(id3, box3), kind: "effect", effect: effect22, colors, scale: 1.4, opacity };
1470
+ function film(id, effect22, colors, opacity = 0.1, box2 = full) {
1471
+ return { ...named(id, box2), kind: "effect", effect: effect22, colors, scale: 1.4, opacity };
2827
1472
  }
2828
- function stars(id3, color3, seed, count = 45) {
1473
+ function stars(id, color, seed, count = 45) {
2829
1474
  let state = seed;
2830
1475
  const random2 = () => {
2831
1476
  state = state * 1664525 + 1013904223 >>> 0;
@@ -2837,7 +1482,7 @@ function stars(id3, color3, seed, count = 45) {
2837
1482
  const r = random2() > 0.85 ? 2.5 : 1.2;
2838
1483
  return `M${x - r} ${y}h${r * 2}m${-r} ${-r}v${r * 2}`;
2839
1484
  }).join("");
2840
- return field(id3, d, color3, 1.5, 0.65);
1485
+ return field(id, d, color, 1.5, 0.65);
2841
1486
  }
2842
1487
  function smallStar(x, y, r) {
2843
1488
  return `${Array.from({ length: 10 }, (_, i) => {
@@ -2846,12 +1491,12 @@ function smallStar(x, y, r) {
2846
1491
  return `${i ? "L" : "M"}${(x + Math.cos(angle) * radius).toFixed(2)} ${(y + Math.sin(angle) * radius).toFixed(2)}`;
2847
1492
  }).join("")}Z`;
2848
1493
  }
2849
- function grid(id3, box3, color3, cell, opacity = 0.2) {
2850
- const [, , w, h] = box3;
1494
+ function grid(id, box2, color, cell, opacity = 0.2) {
1495
+ const [, , w, h] = box2;
2851
1496
  let d = "";
2852
1497
  for (let x = 0; x <= w; x += cell) d += `M${x} 0V${h}`;
2853
1498
  for (let y = 0; y <= h; y += cell) d += `M0 ${y}H${w}`;
2854
- return path(id3, box3, d, color3, 1, opacity);
1499
+ return path(id, box2, d, color, 1, opacity);
2855
1500
  }
2856
1501
  var cardDirections = {
2857
1502
  afterimage: {
@@ -2977,30 +1622,30 @@ var cardDirections = {
2977
1622
  };
2978
1623
  function cardReverse(slug, original) {
2979
1624
  const { base, ink, accent } = cardDirections[slug];
2980
- const motif2 = (index, box3, opacity = 1) => {
1625
+ const motif2 = (index, box2, opacity = 1) => {
2981
1626
  const source = original[index - 1];
2982
- const scale = Math.min(box3[2] / source.w, box3[3] / source.h);
1627
+ const scale = Math.min(box2[2] / source.w, box2[3] / source.h);
2983
1628
  const w = source.w * scale, h = source.h * scale;
2984
1629
  return {
2985
1630
  ...structuredClone(source),
2986
1631
  id: `reverse-source-${index}`,
2987
1632
  name: `Reverse \xB7 ${source.name}`,
2988
- x: box3[0] + (box3[2] - w) / 2,
2989
- y: box3[1] + (box3[3] - h) / 2,
1633
+ x: box2[0] + (box2[2] - w) / 2,
1634
+ y: box2[1] + (box2[3] - h) / 2,
2990
1635
  w,
2991
1636
  h,
2992
1637
  opacity
2993
1638
  };
2994
1639
  };
2995
- const label = (id3, value, x, y, w = 900, color3 = ink) => text3(id3, value, [x, y, w, 28], color3, 14);
2996
- const title = (value, x = 80, y = 260, w = 900, size = 88, font = "sans") => text3("reverse-title", value, [x, y, w, size * 2.5], ink, size, font, "600");
2997
- const line2 = (id3, y, color3 = ink) => path(id3, [80, y, 1040, 2], "M0 1H1040", color3, 1, 0.5);
1640
+ const label = (id, value, x, y, w = 900, color = ink) => text(id, value, [x, y, w, 28], color, 14);
1641
+ const title = (value, x = 80, y = 260, w = 900, size = 88, font = "sans") => text("reverse-title", value, [x, y, w, size * 2.5], ink, size, font, "600");
1642
+ const line2 = (id, y, color = ink) => path(id, [80, y, 1040, 2], "M0 1H1040", color, 1, 0.5);
2998
1643
  const frame = () => field("reverse-frame", "M40 40H1160V716H40Z", accent, 1, 0.5);
2999
1644
  let layers;
3000
1645
  switch (slug) {
3001
1646
  case "afterimage":
3002
1647
  layers = [
3003
- gradient2("graphite", ["#11141c", "#242c37"]),
1648
+ gradient("graphite", ["#11141c", "#242c37"]),
3004
1649
  grid("registration-grid", [40, 40, 1120, 676], "#738090", 40, 0.08),
3005
1650
  ...[0, 1, 2].map(
3006
1651
  (i) => circle(
@@ -3024,7 +1669,7 @@ function cardReverse(slug, original) {
3024
1669
  break;
3025
1670
  case "blue-hour":
3026
1671
  layers = [
3027
- gradient2("nightfall", ["#111535", "#283a6b"], "vertical"),
1672
+ gradient("nightfall", ["#111535", "#283a6b"], "vertical"),
3028
1673
  stars("city-stars", "#dce6ff", 420, 55),
3029
1674
  motif2(3, [940, 76, 110, 110]),
3030
1675
  motif2(4, [0, 527, 1200, 229], 0.7),
@@ -3038,12 +1683,12 @@ function cardReverse(slug, original) {
3038
1683
  break;
3039
1684
  case "checkpoint":
3040
1685
  layers = [
3041
- gradient2("save-screen", ["#291b46", "#40204f"]),
1686
+ gradient("save-screen", ["#291b46", "#40204f"]),
3042
1687
  grid("save-pixels", [0, 0, 1200, 756], "#bf8aaf", 24, 0.07),
3043
1688
  rect("save-panel-shadow", [105, 156, 990, 400], "#130e29"),
3044
1689
  rect("save-panel", [92, 143, 990, 400], "#684369"),
3045
1690
  rect("save-inset", [104, 155, 966, 376], "#2c2047"),
3046
- text3("save-title", "SAVE COMPLETE", [158, 211, 820, 85], ink, 53, "pixel"),
1691
+ text("save-title", "SAVE COMPLETE", [158, 211, 820, 85], ink, 53, "pixel"),
3047
1692
  label("save-message", "A GOOD PLACE TO BEGIN AGAIN.", 161, 323, 860),
3048
1693
  ...Array.from(
3049
1694
  { length: 12 },
@@ -3060,9 +1705,9 @@ function cardReverse(slug, original) {
3060
1705
  rect("obsidian-veil", [0, 0, 1200, 756], "#070909", 0, 0.58),
3061
1706
  frame(),
3062
1707
  field("inner-gold-rim", "M58 58H1142V698H58Z", accent, 1, 0.2),
3063
- text3("private-reverse", "PRIVATE EDITION", [80, 79, 1030, 30], ink, 17),
1708
+ text("private-reverse", "PRIVATE EDITION", [80, 79, 1030, 30], ink, 17),
3064
1709
  motif2(8, [442, 175, 318, 137]),
3065
- text3(
1710
+ text(
3066
1711
  "builders-manifesto",
3067
1712
  "BUILD. SHIP. REPEAT.",
3068
1713
  [180, 389, 850, 75],
@@ -3078,10 +1723,10 @@ function cardReverse(slug, original) {
3078
1723
  break;
3079
1724
  case "dream-sequence":
3080
1725
  layers = [
3081
- gradient2("dream-paper", ["#8e8bc4", "#c5b0df", "#f0d5d8"], "vertical"),
1726
+ gradient("dream-paper", ["#8e8bc4", "#c5b0df", "#f0d5d8"], "vertical"),
3082
1727
  stars("dream-dust", "#fffaf6", 782, 28),
3083
1728
  motif2(3, [672, 398, 528, 358], 0.65),
3084
- text3(
1729
+ text(
3085
1730
  "dream-letter",
3086
1731
  "see you on\nthe other side.",
3087
1732
  [96, 224, 970, 235],
@@ -3098,7 +1743,7 @@ function cardReverse(slug, original) {
3098
1743
  break;
3099
1744
  case "electric-bloom":
3100
1745
  layers = [
3101
- gradient2("violet-foil", ["#130c23", "#331639", "#15142f"]),
1746
+ gradient("violet-foil", ["#130c23", "#331639", "#15142f"]),
3102
1747
  stars("pollen", "#dccbff", 119, 65),
3103
1748
  film("interference", "orbits", ["#2c183b", "#b97bca", "#73bfcf"], 0.14),
3104
1749
  ...[242, 200, 154].map(
@@ -3113,24 +1758,24 @@ function cardReverse(slug, original) {
3113
1758
  break;
3114
1759
  case "extra-life":
3115
1760
  layers = [
3116
- gradient2("arcade-panel", ["#120d20", "#341136"]),
1761
+ gradient("arcade-panel", ["#120d20", "#341136"]),
3117
1762
  grid("arcade-grid", [0, 0, 1200, 756], "#a653b8", 28, 0.07),
3118
1763
  label("arcade-index", "EXTRA LIFE / PLAYER ONE", 82, 77),
3119
- text3("continue-question", "CONTINUE?", [79, 203, 1050, 111], ink, 77, "pixel"),
1764
+ text("continue-question", "CONTINUE?", [79, 203, 1050, 111], ink, 77, "pixel"),
3120
1765
  ...[0, 1, 2].map((i) => ({
3121
1766
  ...motif2(20, [88 + i * 126, 376, 92, 85], i < 2 ? 1 : 0.22),
3122
1767
  id: `life-${i}`
3123
1768
  })),
3124
1769
  rect("yes-button-shadow", [757, 371, 310, 117], "#4b214e"),
3125
1770
  rect("yes-button", [746, 360, 310, 117], accent),
3126
- text3("yes-label", "YES +1", [785, 394, 245, 69], "#ffffff", 39, "pixel"),
1771
+ text("yes-label", "YES +1", [785, 394, 245, 69], "#ffffff", 39, "pixel"),
3127
1772
  line2("arcade-rule", 557, "#8a4c94"),
3128
1773
  label("extra-message", "ONE MORE CHANCE. MAKE IT COUNT.", 86, 612)
3129
1774
  ];
3130
1775
  break;
3131
1776
  case "form-study":
3132
1777
  layers = [
3133
- gradient2("mineral-stock", ["#f4ede1", "#ded8ca"]),
1778
+ gradient("mineral-stock", ["#f4ede1", "#ded8ca"]),
3134
1779
  film("paper-fibres", "grain", ["#ece6d9", "#b9ad94", "#ffffff"], 0.04),
3135
1780
  rect("clay-margin", [0, 0, 44, 756], "#c45b43"),
3136
1781
  circle("ochre-form", 960, 190, 120, "#d9a342"),
@@ -3144,11 +1789,11 @@ function cardReverse(slug, original) {
3144
1789
  break;
3145
1790
  case "garra-29":
3146
1791
  layers = [
3147
- gradient2("maroon-enamel", ["#8d1828", "#b02138"]),
1792
+ gradient("maroon-enamel", ["#8d1828", "#b02138"]),
3148
1793
  film("heritage-grain", "grain", ["#a6192e", "#d49a9a", "#5b1120"], 0.04),
3149
1794
  field("cream-frame", "M38 38H1162V718H38Z", ink, 1.5, 0.8),
3150
- text3("heritage-number", "29", [83, 257, 534, 302], ink, 218, "sans", "800"),
3151
- text3("one-legacy", "ONE\nLEGACY.", [704, 390, 438, 151], ink, 57, "sans", "700"),
1795
+ text("heritage-number", "29", [83, 257, 534, 302], ink, 218, "sans", "800"),
1796
+ text("one-legacy", "ONE\nLEGACY.", [704, 390, 438, 151], ink, 57, "sans", "700"),
3152
1797
  ...Array.from(
3153
1798
  { length: 29 },
3154
1799
  (_, i) => path(
@@ -3165,7 +1810,7 @@ function cardReverse(slug, original) {
3165
1810
  break;
3166
1811
  case "hunter-license-1999":
3167
1812
  layers = [
3168
- gradient2("vermilion-lacquer", ["#a83429", "#ca563b"]),
1813
+ gradient("vermilion-lacquer", ["#a83429", "#ca563b"]),
3169
1814
  frame(),
3170
1815
  rect("gold-header", [0, 73, 1200, 85], accent),
3171
1816
  label("classic-header", "HUNTER ASSOCIATION / CLASSIC EDITION", 81, 101, 1030, "#6a2d26"),
@@ -3180,7 +1825,7 @@ function cardReverse(slug, original) {
3180
1825
  case "hunter-license-green": {
3181
1826
  const green = slug.endsWith("green");
3182
1827
  layers = [
3183
- gradient2(
1828
+ gradient(
3184
1829
  "association-metal",
3185
1830
  green ? ["#123b23", "#286440", "#17432a"] : ["#dbe9ec", "#a9cbdc", "#c9dfe6"]
3186
1831
  ),
@@ -3205,10 +1850,10 @@ function cardReverse(slug, original) {
3205
1850
  }
3206
1851
  case "interval":
3207
1852
  layers = [
3208
- gradient2("warm-paper", ["#f7f2e8", "#e7e2d8"]),
1853
+ gradient("warm-paper", ["#f7f2e8", "#e7e2d8"]),
3209
1854
  grid("measuring-field", [81, 135, 1038, 479], "#bbb2a2", 39, 0.17),
3210
1855
  rect("vermilion-spine", [80, 135, 21, 478], accent),
3211
- text3("second-interval", "02", [786, 364, 337, 238], ink, 180, "sans", "400"),
1856
+ text("second-interval", "02", [786, 364, 337, 238], ink, 180, "sans", "400"),
3212
1857
  label("interval-title", "INTERVAL / THE SPACE BETWEEN", 81, 79),
3213
1858
  title("ROOM\nTO THINK.", 130, 221, 700, 73),
3214
1859
  field(
@@ -3223,7 +1868,7 @@ function cardReverse(slug, original) {
3223
1868
  break;
3224
1869
  case "moon-rabbit":
3225
1870
  layers = [
3226
- gradient2("moonlit-indigo", ["#0a1229", "#292c4c"], "vertical"),
1871
+ gradient("moonlit-indigo", ["#0a1229", "#292c4c"], "vertical"),
3227
1872
  stars("night-stars", "#dce1e8", 550, 74),
3228
1873
  motif2(8, [831, 92, 205, 205]),
3229
1874
  circle("moon-orbit", 934, 195, 133, "#d1cbed", 1, 0.3),
@@ -3236,7 +1881,7 @@ function cardReverse(slug, original) {
3236
1881
  break;
3237
1882
  case "side-quest":
3238
1883
  layers = [
3239
- gradient2("map-ocean", ["#174d6b", "#2a7892"]),
1884
+ gradient("map-ocean", ["#174d6b", "#2a7892"]),
3240
1885
  grid("map-grid", [0, 0, 1200, 756], "#a3d3dd", 36, 0.12),
3241
1886
  motif2(2, [755, 133, 365, 456], 0.75),
3242
1887
  title("TAKE A\nDETOUR.", 80, 179, 800, 74, "pixel"),
@@ -3261,8 +1906,8 @@ function cardReverse(slug, original) {
3261
1906
  break;
3262
1907
  case "soft-signal":
3263
1908
  layers = [
3264
- gradient2("porcelain", ["#f5eee5", "#e7d8cc"]),
3265
- gradient2("copper-bloom", ["#d9946355", "#d9946300"], "radial"),
1909
+ gradient("porcelain", ["#f5eee5", "#e7d8cc"]),
1910
+ gradient("copper-bloom", ["#d9946355", "#d9946300"], "radial"),
3266
1911
  ...[64, 112, 170, 238, 316].map(
3267
1912
  (r, i) => field(
3268
1913
  `receive-ring-${i}`,
@@ -3286,10 +1931,10 @@ function cardReverse(slug, original) {
3286
1931
  break;
3287
1932
  case "solstice":
3288
1933
  layers = [
3289
- gradient2("late-sunset", ["#241832", "#683151"], "vertical"),
1934
+ gradient("late-sunset", ["#241832", "#683151"], "vertical"),
3290
1935
  stars("last-stars", "#f2c8aa", 311, 35),
3291
1936
  circle("sun-outline", 959, 184, 160, "#f1b577", 1.5, 0.6),
3292
- gradient2("horizon-glow", ["#ec935644", "#ec935600"], "radial", [664, 40, 490, 400]),
1937
+ gradient("horizon-glow", ["#ec935644", "#ec935600"], "radial", [664, 40, 490, 400]),
3293
1938
  title("THE LONGEST\nLIGHT", 79, 218, 1030, 77),
3294
1939
  label("solar-index", "SOLSTICE / THE OTHER SIDE OF DAY", 84, 80),
3295
1940
  field("far-dune", "M0 586Q240 500 611 601T1200 544V756H0Z", "#5d2d4c"),
@@ -3300,11 +1945,11 @@ function cardReverse(slug, original) {
3300
1945
  break;
3301
1946
  case "streak-guardian":
3302
1947
  layers = [
3303
- gradient2("green-enamel", ["#68d311", "#48b000"]),
1948
+ gradient("green-enamel", ["#68d311", "#48b000"]),
3304
1949
  circle("duo-aura", 930, 406, 250, "#c2f078", 0, 0.2),
3305
1950
  label("practice-header", "STREAK GUARDIAN / ONE DAY AT A TIME", 83, 81),
3306
- text3("week-count", "07", [75, 206, 530, 272], "#ffffff", 210, "sans", "800"),
3307
- text3(
1951
+ text("week-count", "07", [75, 206, 530, 272], "#ffffff", 210, "sans", "800"),
1952
+ text(
3308
1953
  "week-label",
3309
1954
  "SMALL STEPS.\nREAL PROGRESS.",
3310
1955
  [92, 490, 590, 90],
@@ -3328,24 +1973,24 @@ function cardReverse(slug, original) {
3328
1973
  break;
3329
1974
  case "system-dialog":
3330
1975
  layers = [
3331
- gradient2("desktop", ["#e8ebf1", "#bcc8db"]),
1976
+ gradient("desktop", ["#e8ebf1", "#bcc8db"]),
3332
1977
  grid("desktop-grid", [0, 0, 1200, 756], "#9aa9c1", 32, 0.17),
3333
1978
  rect("status-shadow", [165, 150, 892, 446], "#647089", 0, 0.2),
3334
1979
  rect("status-frame", [152, 137, 892, 446], "#405471"),
3335
1980
  rect("status-paper", [159, 144, 878, 432], "#f3f5f9"),
3336
1981
  rect("status-titlebar", [166, 151, 864, 53], "#304976"),
3337
- text3("status-title", "REVERSE SIDE", [192, 166, 788, 37], "#ffffff", 23),
1982
+ text("status-title", "REVERSE SIDE", [192, 166, 788, 37], "#ffffff", 23),
3338
1983
  ...["LAYERS : OPEN", "MATERIAL : LIVE", "STATUS : READY"].map(
3339
- (value, i) => text3(`status-row-${i}`, value, [238, 266 + i * 69, 745, 47], ink, 28)
1984
+ (value, i) => text(`status-row-${i}`, value, [238, 266 + i * 69, 745, 47], ink, 28)
3340
1985
  ),
3341
1986
  rect("status-button", [790, 480, 194, 57], "#dfe5ee"),
3342
- text3("status-ok", "OK", [858, 495, 92, 36], ink, 24),
1987
+ text("status-ok", "OK", [858, 495, 92, 36], ink, 24),
3343
1988
  label("local-note", "SYSTEM DIALOG / LOCAL SESSION", 154, 654)
3344
1989
  ];
3345
1990
  break;
3346
1991
  default:
3347
1992
  layers = [
3348
- gradient2("brushed-silver", ["#eceee7", "#c9d1c8"]),
1993
+ gradient("brushed-silver", ["#eceee7", "#c9d1c8"]),
3349
1994
  grid("maker-grid", [40, 40, 1120, 676], "#839589", 40, 0.13),
3350
1995
  label("maker-index", "VIBECODERS / REVERSE ENGINEERING", 85, 84),
3351
1996
  path("opening-bracket", [81, 244, 82, 231], "M82 0L0 115L82 231", ink, 3),
@@ -3396,9 +2041,9 @@ function originalCards() {
3396
2041
  });
3397
2042
  }
3398
2043
  var canvas = { x: 0, y: 0, w: 1200, h: 756 };
3399
- function text22(id3, value, x, y, w, size, color3) {
2044
+ function text2(id, value, x, y, w, size, color) {
3400
2045
  return {
3401
- id: id3,
2046
+ id,
3402
2047
  kind: "text",
3403
2048
  text: value,
3404
2049
  binding: "none",
@@ -3407,36 +2052,36 @@ function text22(id3, value, x, y, w, size, color3) {
3407
2052
  w,
3408
2053
  h: size * 1.5,
3409
2054
  size,
3410
- color: color3,
2055
+ color,
3411
2056
  font: "mono",
3412
2057
  weight: "500",
3413
2058
  align: "left",
3414
2059
  tracking: 2
3415
2060
  };
3416
2061
  }
3417
- function line(id3, x, y, w, color3) {
2062
+ function line(id, x, y, w, color) {
3418
2063
  return {
3419
- id: id3,
2064
+ id,
3420
2065
  kind: "shape",
3421
2066
  shape: "line",
3422
2067
  x,
3423
2068
  y,
3424
2069
  w,
3425
2070
  h: 2,
3426
- color: color3,
2071
+ color,
3427
2072
  radius: 0,
3428
2073
  stroke: 1,
3429
2074
  opacity: 0.5
3430
2075
  };
3431
2076
  }
3432
- function effect2(id3, kind, colors, opacity) {
3433
- return { id: id3, kind: "effect", effect: kind, ...canvas, colors, scale: 1.3, opacity };
2077
+ function effect(id, kind, colors, opacity) {
2078
+ return { id, kind: "effect", effect: kind, ...canvas, colors, scale: 1.3, opacity };
3434
2079
  }
3435
- function style(id3, name, description, palette2, ink, material, layers) {
2080
+ function style(id, name, description, palette2, ink, material, layers) {
3436
2081
  return badgeDesignSchema.parse({
3437
2082
  version: 1,
3438
2083
  product: "card",
3439
- source: id3,
2084
+ source: id,
3440
2085
  name,
3441
2086
  description,
3442
2087
  event: "Makeables",
@@ -3457,10 +2102,10 @@ function style(id3, name, description, palette2, ink, material, layers) {
3457
2102
  ]
3458
2103
  },
3459
2104
  ...layers,
3460
- text22("wordmark", "makeables", 74, 62, 570, 38, ink),
3461
- text22("edition", "MATERIAL STUDIES", 76, 123, 570, 16, ink),
3462
- text22("title", name.toUpperCase(), 76, 500, 760, 25, ink),
3463
- text22("series", "DESIGNED TO BE YOURS", 78, 542, 660, 13, ink),
2105
+ text2("wordmark", "makeables", 74, 62, 570, 38, ink),
2106
+ text2("edition", "MATERIAL STUDIES", 76, 123, 570, 16, ink),
2107
+ text2("title", name.toUpperCase(), 76, 500, 760, 25, ink),
2108
+ text2("series", "DESIGNED TO BE YOURS", 78, 542, 660, 13, ink),
3464
2109
  line("title-rule", 76, 589, 1028, ink),
3465
2110
  cardMarkLayer("chip", { mark: "chip", slot: "middle-left", color: "#c7d0d9" }),
3466
2111
  cardMarkLayer("contactless", { mark: "contactless", slot: "upper-right", color: ink }),
@@ -3476,7 +2121,7 @@ function style(id3, name, description, palette2, ink, material, layers) {
3476
2121
  back: {
3477
2122
  background: palette2[0],
3478
2123
  layers: [
3479
- effect2("reverse-field", "contours", palette2, 0.3),
2124
+ effect("reverse-field", "contours", palette2, 0.3),
3480
2125
  {
3481
2126
  id: "reverse-panel",
3482
2127
  kind: "shape",
@@ -3490,11 +2135,11 @@ function style(id3, name, description, palette2, ink, material, layers) {
3490
2135
  stroke: 0,
3491
2136
  opacity: 0.9
3492
2137
  },
3493
- text22("reverse-wordmark", "makeables / material studies", 76, 310, 1040, 24, ink),
2138
+ text2("reverse-wordmark", "makeables / material studies", 76, 310, 1040, 24, ink),
3494
2139
  line("reverse-rule", 76, 380, 1048, ink),
3495
- text22("reverse-title", name.toUpperCase(), 76, 430, 1e3, 46, ink),
3496
- text22("reverse-caption", "A SMALL CANVAS. ENDLESS POSSIBILITIES.", 78, 524, 1020, 16, ink),
3497
- text22("reverse-footer", "ORIGINAL ARTWORK / MAKEABLES", 78, 658, 1e3, 13, ink)
2140
+ text2("reverse-title", name.toUpperCase(), 76, 430, 1e3, 46, ink),
2141
+ text2("reverse-caption", "A SMALL CANVAS. ENDLESS POSSIBILITIES.", 78, 524, 1020, 16, ink),
2142
+ text2("reverse-footer", "ORIGINAL ARTWORK / MAKEABLES", 78, 658, 1e3, 13, ink)
3498
2143
  ]
3499
2144
  }
3500
2145
  });
@@ -3528,7 +2173,7 @@ var materialCardStyles = [
3528
2173
  }
3529
2174
  },
3530
2175
  [
3531
- effect2("pearl-ribbons", "chromatic-flow", ["#eee8f1", "#c784d9", "#81d7df"], 0.75),
2176
+ effect("pearl-ribbons", "chromatic-flow", ["#eee8f1", "#c784d9", "#81d7df"], 0.75),
3532
2177
  {
3533
2178
  id: "orbital-seal",
3534
2179
  kind: "graphic",
@@ -3543,7 +2188,7 @@ var materialCardStyles = [
3543
2188
  seed: 81,
3544
2189
  opacity: 0.5
3545
2190
  },
3546
- text22("atelier", "STUDIO / 01", 820, 66, 280, 15, "#6c6487")
2191
+ text2("atelier", "STUDIO / 01", 820, 66, 280, 15, "#6c6487")
3547
2192
  ]
3548
2193
  ),
3549
2194
  { wordmark: "foil", "reverse-wordmark": "foil" }
@@ -3573,7 +2218,7 @@ var materialCardStyles = [
3573
2218
  }
3574
2219
  },
3575
2220
  [
3576
- effect2("engraved-contours", "contours", ["#0b101a", "#536277", "#b3c4d5"], 0.34),
2221
+ effect("engraved-contours", "contours", ["#0b101a", "#536277", "#b3c4d5"], 0.34),
3577
2222
  {
3578
2223
  id: "technical-grid",
3579
2224
  kind: "graphic",
@@ -3588,7 +2233,7 @@ var materialCardStyles = [
3588
2233
  seed: 29,
3589
2234
  opacity: 0.22
3590
2235
  },
3591
- text22("atelier", "STUDIO / 02", 820, 66, 280, 15, "#ffffff")
2236
+ text2("atelier", "STUDIO / 02", 820, 66, 280, 15, "#ffffff")
3592
2237
  ]
3593
2238
  ),
3594
2239
  { wordmark: "raised", title: "foil", "technical-grid": "foil", "reverse-title": "foil" }
@@ -3617,7 +2262,7 @@ var materialCardStyles = [
3617
2262
  }
3618
2263
  },
3619
2264
  [
3620
- effect2("solar-orbits", "orbits", ["#ecd9be", "#bd4a2e", "#efaa50"], 0.36),
2265
+ effect("solar-orbits", "orbits", ["#ecd9be", "#bd4a2e", "#efaa50"], 0.36),
3621
2266
  {
3622
2267
  id: "sun-disc",
3623
2268
  kind: "shape",
@@ -3644,7 +2289,7 @@ var materialCardStyles = [
3644
2289
  stroke: 2,
3645
2290
  opacity: 0.5
3646
2291
  },
3647
- text22("atelier", "STUDIO / 03", 820, 66, 280, 15, "#202024")
2292
+ text2("atelier", "STUDIO / 03", 820, 66, 280, 15, "#202024")
3648
2293
  ]
3649
2294
  ),
3650
2295
  { "sun-disc": "raised", "sun-ring": "foil", wordmark: "raised", "reverse-title": "foil" }
@@ -3652,16 +2297,16 @@ var materialCardStyles = [
3652
2297
  ];
3653
2298
  var curatedCardStyles = originalCards();
3654
2299
  var cardStyles = [...materialCardStyles, ...curatedCardStyles];
3655
- function findCardStyle(id3) {
3656
- return cardStyles.find((design2) => design2.source === id3);
2300
+ function findCardStyle(id) {
2301
+ return cardStyles.find((design2) => design2.source === id);
3657
2302
  }
3658
- var faceEdits = z5.object({
2303
+ var faceEdits = z.object({
3659
2304
  background: badgeDesignObjectSchema.shape.front.shape.background.optional(),
3660
- upsert: z5.array(badgeLayerSchema).max(96).optional(),
3661
- remove: z5.array(z5.string()).max(96).optional(),
3662
- order: z5.array(z5.string()).max(96).optional()
2305
+ upsert: z.array(badgeLayerSchema).max(96).optional(),
2306
+ remove: z.array(z.string()).max(96).optional(),
2307
+ order: z.array(z.string()).max(96).optional()
3663
2308
  });
3664
- var designEditsSchema = z5.object({
2309
+ var designEditsSchema = z.object({
3665
2310
  name: badgeDesignObjectSchema.shape.name.optional(),
3666
2311
  event: badgeDesignObjectSchema.shape.event.optional(),
3667
2312
  description: badgeDesignObjectSchema.shape.description.optional(),
@@ -3684,30 +2329,30 @@ function applyDesignEdits(base, input, locks) {
3684
2329
  for (const side2 of ["front", "back"]) {
3685
2330
  const change = edits[side2];
3686
2331
  if (!change) continue;
3687
- const face2 = next[side2];
3688
- if (change.background) face2.background = change.background;
3689
- for (const id3 of change.remove ?? []) {
3690
- if (!face2.layers.some((layer) => layer.id === id3))
3691
- throw new Error(`No existe ${side2}.${id3}.`);
3692
- face2.layers = face2.layers.filter((layer) => layer.id !== id3);
2332
+ const face = next[side2];
2333
+ if (change.background) face.background = change.background;
2334
+ for (const id of change.remove ?? []) {
2335
+ if (!face.layers.some((layer) => layer.id === id))
2336
+ throw new Error(`No existe ${side2}.${id}.`);
2337
+ face.layers = face.layers.filter((layer) => layer.id !== id);
3693
2338
  }
3694
2339
  const replacements = /* @__PURE__ */ new Set();
3695
2340
  for (const layer of change.upsert ?? []) {
3696
2341
  if (replacements.has(layer.id)) throw new Error(`Cambio repetido ${side2}.${layer.id}.`);
3697
2342
  replacements.add(layer.id);
3698
- const index = face2.layers.findIndex((item) => item.id === layer.id);
3699
- if (index >= 0) face2.layers[index] = layer;
2343
+ const index = face.layers.findIndex((item) => item.id === layer.id);
2344
+ if (index >= 0) face.layers[index] = layer;
3700
2345
  else {
3701
- const qr2 = face2.layers.findIndex((item) => item.kind === "qr");
3702
- face2.layers.splice(qr2 < 0 ? face2.layers.length : qr2, 0, layer);
2346
+ const qr = face.layers.findIndex((item) => item.kind === "qr");
2347
+ face.layers.splice(qr < 0 ? face.layers.length : qr, 0, layer);
3703
2348
  }
3704
2349
  }
3705
2350
  if (change.order) {
3706
- if (change.order.length !== face2.layers.length || new Set(change.order).size !== face2.layers.length)
2351
+ if (change.order.length !== face.layers.length || new Set(change.order).size !== face.layers.length)
3707
2352
  throw new Error(`El orden debe incluir todas las capas de ${side2} exactamente una vez.`);
3708
- face2.layers = change.order.map((id3) => {
3709
- const layer = face2.layers.find((item) => item.id === id3);
3710
- if (!layer) throw new Error(`No existe ${side2}.${id3}.`);
2353
+ face.layers = change.order.map((id) => {
2354
+ const layer = face.layers.find((item) => item.id === id);
2355
+ if (!layer) throw new Error(`No existe ${side2}.${id}.`);
3711
2356
  return layer;
3712
2357
  });
3713
2358
  }
@@ -6065,14 +4710,14 @@ var collection2 = [
6065
4710
  ["brew", "cf3f2e1a-4a31-42de-ad6c-8825303b2f09"]
6066
4711
  ];
6067
4712
  var communityStickerIds = collection2.map(
6068
- ([, id3]) => `community-${id3}`
4713
+ ([, id]) => `community-${id}`
6069
4714
  );
6070
- var communityStickerStyles = collection2.map(([slug, id3]) => {
4715
+ var communityStickerStyles = collection2.map(([slug, id]) => {
6071
4716
  const original = badgeDesignSchema.parse(community_sticker_sources_default[slug]);
6072
- const credit2 = { label: "Railly Hugo", url: `https://makeables.dev/submissions/${id3}` };
4717
+ const credit = { label: "Railly Hugo", url: `https://makeables.dev/submissions/${id}` };
6073
4718
  return badgeDesignSchema.parse({
6074
4719
  ...original,
6075
- source: `community-${id3}`,
4720
+ source: `community-${id}`,
6076
4721
  artPrompt: "Adapted from the original Community artwork with real Ann Nguyen / TypingMind image references: simple contemporary shapes, integrated lettering, calm negative space and selective optical finish. Keep the exact identity and wording. GPT Image 2 via Vercel AI Gateway; prompts and provenance in sticker-revisions/2026-09-30. Original editable layers are retained hidden; the new illustration is a raster layer.",
6077
4722
  assets: {
6078
4723
  ...original.assets,
@@ -6082,7 +4727,7 @@ var communityStickerStyles = collection2.map(([slug, id3]) => {
6082
4727
  slug,
6083
4728
  file: "artwork",
6084
4729
  name: original.name,
6085
- credit: credit2
4730
+ credit
6086
4731
  },
6087
4732
  "optical-map": {
6088
4733
  source: "sticker",
@@ -6090,7 +4735,7 @@ var communityStickerStyles = collection2.map(([slug, id3]) => {
6090
4735
  slug,
6091
4736
  file: "effects",
6092
4737
  name: "Foil \xB7 glitter \xB7 relief",
6093
- credit: credit2
4738
+ credit
6094
4739
  }
6095
4740
  },
6096
4741
  front: {
@@ -20011,1725 +18656,8 @@ function findDesign(source) {
20011
18656
  return designCatalog.find((design2) => design2.source === source);
20012
18657
  }
20013
18658
 
20014
- // ../design/dist/chunk-BAQXEQNG.js
20015
- import QRCode from "qrcode";
20016
- function badgeQrLayout(destination, width, maxCellSize = 20) {
20017
- const url = new URL(destination);
20018
- if (!["http:", "https:"].includes(url.protocol) || url.username || url.password || url.href.length > 400)
20019
- throw new Error("El destino del QR no es v\xE1lido.");
20020
- const matrix = QRCode.create(url.href, { errorCorrectionLevel: "M" }).modules;
20021
- const cell = Math.min(maxCellSize, Math.floor(width / (matrix.size + 8)));
20022
- if (cell < 2) throw new Error("El QR necesita m\xE1s espacio.");
20023
- return { matrix, cell };
20024
- }
20025
-
20026
- // ../design/dist/chunk-ZUAL6SF5.js
20027
- import { z as z6 } from "zod";
20028
- var COMMUNITY_IMAGE_LIMIT = 3e6;
20029
- var COMMUNITY_JSON_LIMIT = 256e3;
20030
- var digestSchema = z6.string().regex(/^[a-f0-9]{64}$/);
20031
- var secretSchema = z6.string().regex(/^\d{13}\.[a-f0-9]{64}$/);
20032
- var COMMUNITY_PREPARATION_TTL = 60 * 60 * 1e3;
20033
- var communityParticipantSchema = z6.object({
20034
- name: z6.string().trim().min(1).max(80),
20035
- role: z6.string().max(100),
20036
- organization: z6.string().max(100),
20037
- number: z6.number().int().min(1).max(999999),
20038
- eventName: z6.string().min(1).max(80),
20039
- publicUrl: z6.string().url().max(512).refine((value) => ["https:", "http:"].includes(new URL(value).protocol)),
20040
- signature: z6.object({ seed: z6.number().int().min(0).max(4294967295), version: z6.literal(1) }),
20041
- metadata: z6.object({
20042
- roleLabel: z6.string().max(100).default(""),
20043
- eventName: z6.string().max(80).default(""),
20044
- eventDate: z6.string().max(100).default(""),
20045
- location: z6.string().max(100).default(""),
20046
- website: z6.string().max(200).default(""),
20047
- bio: z6.string().max(600).default("")
20048
- }).strict()
20049
- }).strict();
20050
- var communitySnapshotSchema = z6.object({
20051
- format: z6.literal(1),
20052
- design: badgeDesignSchema,
20053
- participant: communityParticipantSchema,
20054
- images: z6.object({ portrait: digestSchema, artwork: digestSchema.nullable() }).strict()
20055
- }).strict().superRefine(({ design: design2, images, participant }, context) => {
20056
- const visible = (layer) => layer.visible !== false && (layer.opacity ?? 1) > 0;
20057
- if (Object.values(design2.assets ?? {}).some((asset) => asset.source === "image"))
20058
- context.addIssue({
20059
- code: "custom",
20060
- message: "Uploaded stickers can't be published yet. Keep Petdex stickers or remove your uploads."
20061
- });
20062
- for (const side2 of ["front", "back"]) {
20063
- if (!design2[side2].layers.some(
20064
- (layer) => visible(layer) && layer.kind === "text" && layer.binding === "name"
20065
- ))
20066
- context.addIssue({ code: "custom", message: `El nombre debe verse en ${side2}.` });
20067
- }
20068
- if (!design2.front.layers.some((layer) => visible(layer) && layer.kind === "portrait"))
20069
- context.addIssue({ code: "custom", message: "El retrato debe ser visible." });
20070
- if (!design2.back.layers.some((layer) => visible(layer) && isRoleBoundLayer(layer)))
20071
- context.addIssue({ code: "custom", message: "El rol debe ser visible." });
20072
- if (!design2.back.layers.some((layer) => visible(layer) && layer.kind === "qr"))
20073
- context.addIssue({ code: "custom", message: "El QR debe ser visible." });
20074
- for (const layer of [...design2.front.layers, ...design2.back.layers]) {
20075
- if (!visible(layer) || layer.kind !== "qr") continue;
20076
- try {
20077
- badgeQrLayout(participant.publicUrl, layer.w, layer.maxCellSize);
20078
- } catch (reason) {
20079
- context.addIssue({ code: "custom", message: reason.message });
20080
- }
20081
- }
20082
- if (Boolean(design2.artwork) !== Boolean(images.artwork) || [...design2.front.layers, ...design2.back.layers].some(
20083
- (layer) => visible(layer) && layer.kind === "image"
20084
- ) && !images.artwork)
20085
- context.addIssue({ code: "custom", message: "Falta la ilustraci\xF3n de este dise\xF1o." });
20086
- });
20087
- var intentBase = {
20088
- operationId: z6.string().uuid(),
20089
- snapshotHash: digestSchema,
20090
- title: z6.string().min(1).max(60),
20091
- participantName: z6.string().min(1).max(80)
20092
- };
20093
- var communityIntentSchema = z6.discriminatedUnion("action", [
20094
- z6.object({ ...intentBase, action: z6.literal("create") }).strict(),
20095
- z6.object({
20096
- ...intentBase,
20097
- action: z6.literal("update"),
20098
- publicationId: z6.string().uuid(),
20099
- expectedVersion: z6.number().int().positive()
20100
- }).strict(),
20101
- z6.object({
20102
- ...intentBase,
20103
- action: z6.literal("withdraw"),
20104
- publicationId: z6.string().uuid(),
20105
- expectedVersion: z6.number().int().positive()
20106
- }).strict()
20107
- ]);
20108
- function canonicalJson(value) {
20109
- return JSON.stringify(
20110
- value,
20111
- (_, item) => item && typeof item === "object" && !Array.isArray(item) ? Object.fromEntries(Object.entries(item).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)) : item
20112
- );
20113
- }
20114
- async function communityDigest(value) {
20115
- const bytes = typeof value === "string" ? new TextEncoder().encode(value) : await value.arrayBuffer();
20116
- return Array.from(new Uint8Array(await crypto.subtle.digest("SHA-256", bytes))).map((byte) => byte.toString(16).padStart(2, "0")).join("");
20117
- }
20118
- var bundleImageSchema = z6.object({
20119
- mimeType: z6.enum(["image/png", "image/jpeg", "image/webp"]),
20120
- base64: z6.string().min(4).max(4e6).regex(/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/)
20121
- }).strict();
20122
- var badgeBundleSchema = z6.object({
20123
- format: z6.literal("makeables-bundle"),
20124
- version: z6.literal(1),
20125
- snapshot: communitySnapshotSchema,
20126
- images: z6.object({
20127
- portrait: bundleImageSchema,
20128
- artwork: bundleImageSchema.nullable()
20129
- }).strict()
20130
- }).strict();
20131
- function bundleImageBytes(image2) {
20132
- return Uint8Array.from(atob(image2.base64), (character) => character.charCodeAt(0));
20133
- }
20134
- async function validateBadgeBundle(input) {
20135
- const bundle = badgeBundleSchema.parse(input);
20136
- const serialized = canonicalJson(bundle.snapshot);
20137
- if (new TextEncoder().encode(serialized).length > COMMUNITY_JSON_LIMIT)
20138
- throw new Error("The badge exceeds the 256 KB publication limit.");
20139
- for (const slot of ["portrait", "artwork"]) {
20140
- const image2 = bundle.images[slot];
20141
- if (!image2 && !bundle.snapshot.images[slot]) continue;
20142
- if (!image2) throw new Error(`Missing ${slot} image.`);
20143
- const bytes = bundleImageBytes(image2);
20144
- if (!bytes.length || bytes.length > COMMUNITY_IMAGE_LIMIT)
20145
- throw new Error(`The ${slot} exceeds the 3 MB publication limit.`);
20146
- const digest = await communityDigest(new Blob([bytes]));
20147
- if (digest !== bundle.snapshot.images[slot])
20148
- throw new Error(`The ${slot} does not match the saved badge.`);
20149
- }
20150
- return { bundle, snapshotHash: await communityDigest(serialized) };
20151
- }
20152
-
20153
- // ../../node_modules/.pnpm/fflate@0.8.2/node_modules/fflate/esm/index.mjs
20154
- import { createRequire } from "module";
20155
- var require2 = createRequire("/");
20156
- var Worker;
20157
- try {
20158
- Worker = require2("worker_threads").Worker;
20159
- } catch (e) {
20160
- }
20161
- var u8 = Uint8Array;
20162
- var u16 = Uint16Array;
20163
- var i32 = Int32Array;
20164
- var fleb = new u8([
20165
- 0,
20166
- 0,
20167
- 0,
20168
- 0,
20169
- 0,
20170
- 0,
20171
- 0,
20172
- 0,
20173
- 1,
20174
- 1,
20175
- 1,
20176
- 1,
20177
- 2,
20178
- 2,
20179
- 2,
20180
- 2,
20181
- 3,
20182
- 3,
20183
- 3,
20184
- 3,
20185
- 4,
20186
- 4,
20187
- 4,
20188
- 4,
20189
- 5,
20190
- 5,
20191
- 5,
20192
- 5,
20193
- 0,
20194
- /* unused */
20195
- 0,
20196
- 0,
20197
- /* impossible */
20198
- 0
20199
- ]);
20200
- var fdeb = new u8([
20201
- 0,
20202
- 0,
20203
- 0,
20204
- 0,
20205
- 1,
20206
- 1,
20207
- 2,
20208
- 2,
20209
- 3,
20210
- 3,
20211
- 4,
20212
- 4,
20213
- 5,
20214
- 5,
20215
- 6,
20216
- 6,
20217
- 7,
20218
- 7,
20219
- 8,
20220
- 8,
20221
- 9,
20222
- 9,
20223
- 10,
20224
- 10,
20225
- 11,
20226
- 11,
20227
- 12,
20228
- 12,
20229
- 13,
20230
- 13,
20231
- /* unused */
20232
- 0,
20233
- 0
20234
- ]);
20235
- var clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
20236
- var freb = function(eb, start) {
20237
- var b = new u16(31);
20238
- for (var i = 0; i < 31; ++i) {
20239
- b[i] = start += 1 << eb[i - 1];
20240
- }
20241
- var r = new i32(b[30]);
20242
- for (var i = 1; i < 30; ++i) {
20243
- for (var j = b[i]; j < b[i + 1]; ++j) {
20244
- r[j] = j - b[i] << 5 | i;
20245
- }
20246
- }
20247
- return { b, r };
20248
- };
20249
- var _a = freb(fleb, 2);
20250
- var fl = _a.b;
20251
- var revfl = _a.r;
20252
- fl[28] = 258, revfl[258] = 28;
20253
- var _b = freb(fdeb, 0);
20254
- var fd = _b.b;
20255
- var revfd = _b.r;
20256
- var rev = new u16(32768);
20257
- for (i = 0; i < 32768; ++i) {
20258
- x = (i & 43690) >> 1 | (i & 21845) << 1;
20259
- x = (x & 52428) >> 2 | (x & 13107) << 2;
20260
- x = (x & 61680) >> 4 | (x & 3855) << 4;
20261
- rev[i] = ((x & 65280) >> 8 | (x & 255) << 8) >> 1;
20262
- }
20263
- var x;
20264
- var i;
20265
- var hMap = (function(cd, mb, r) {
20266
- var s2 = cd.length;
20267
- var i = 0;
20268
- var l = new u16(mb);
20269
- for (; i < s2; ++i) {
20270
- if (cd[i])
20271
- ++l[cd[i] - 1];
20272
- }
20273
- var le = new u16(mb);
20274
- for (i = 1; i < mb; ++i) {
20275
- le[i] = le[i - 1] + l[i - 1] << 1;
20276
- }
20277
- var co;
20278
- if (r) {
20279
- co = new u16(1 << mb);
20280
- var rvb = 15 - mb;
20281
- for (i = 0; i < s2; ++i) {
20282
- if (cd[i]) {
20283
- var sv = i << 4 | cd[i];
20284
- var r_1 = mb - cd[i];
20285
- var v = le[cd[i] - 1]++ << r_1;
20286
- for (var m = v | (1 << r_1) - 1; v <= m; ++v) {
20287
- co[rev[v] >> rvb] = sv;
20288
- }
20289
- }
20290
- }
20291
- } else {
20292
- co = new u16(s2);
20293
- for (i = 0; i < s2; ++i) {
20294
- if (cd[i]) {
20295
- co[i] = rev[le[cd[i] - 1]++] >> 15 - cd[i];
20296
- }
20297
- }
20298
- }
20299
- return co;
20300
- });
20301
- var flt = new u8(288);
20302
- for (i = 0; i < 144; ++i)
20303
- flt[i] = 8;
20304
- var i;
20305
- for (i = 144; i < 256; ++i)
20306
- flt[i] = 9;
20307
- var i;
20308
- for (i = 256; i < 280; ++i)
20309
- flt[i] = 7;
20310
- var i;
20311
- for (i = 280; i < 288; ++i)
20312
- flt[i] = 8;
20313
- var i;
20314
- var fdt = new u8(32);
20315
- for (i = 0; i < 32; ++i)
20316
- fdt[i] = 5;
20317
- var i;
20318
- var flm = /* @__PURE__ */ hMap(flt, 9, 0);
20319
- var flrm = /* @__PURE__ */ hMap(flt, 9, 1);
20320
- var fdm = /* @__PURE__ */ hMap(fdt, 5, 0);
20321
- var fdrm = /* @__PURE__ */ hMap(fdt, 5, 1);
20322
- var max = function(a) {
20323
- var m = a[0];
20324
- for (var i = 1; i < a.length; ++i) {
20325
- if (a[i] > m)
20326
- m = a[i];
20327
- }
20328
- return m;
20329
- };
20330
- var bits = function(d, p2, m) {
20331
- var o = p2 / 8 | 0;
20332
- return (d[o] | d[o + 1] << 8) >> (p2 & 7) & m;
20333
- };
20334
- var bits16 = function(d, p2) {
20335
- var o = p2 / 8 | 0;
20336
- return (d[o] | d[o + 1] << 8 | d[o + 2] << 16) >> (p2 & 7);
20337
- };
20338
- var shft = function(p2) {
20339
- return (p2 + 7) / 8 | 0;
20340
- };
20341
- var slc = function(v, s2, e) {
20342
- if (s2 == null || s2 < 0)
20343
- s2 = 0;
20344
- if (e == null || e > v.length)
20345
- e = v.length;
20346
- return new u8(v.subarray(s2, e));
20347
- };
20348
- var ec = [
20349
- "unexpected EOF",
20350
- "invalid block type",
20351
- "invalid length/literal",
20352
- "invalid distance",
20353
- "stream finished",
20354
- "no stream handler",
20355
- ,
20356
- "no callback",
20357
- "invalid UTF-8 data",
20358
- "extra field too long",
20359
- "date not in range 1980-2099",
20360
- "filename too long",
20361
- "stream finishing",
20362
- "invalid zip data"
20363
- // determined by unknown compression method
20364
- ];
20365
- var err = function(ind, msg, nt) {
20366
- var e = new Error(msg || ec[ind]);
20367
- e.code = ind;
20368
- if (Error.captureStackTrace)
20369
- Error.captureStackTrace(e, err);
20370
- if (!nt)
20371
- throw e;
20372
- return e;
20373
- };
20374
- var inflt = function(dat, st, buf, dict) {
20375
- var sl = dat.length, dl = dict ? dict.length : 0;
20376
- if (!sl || st.f && !st.l)
20377
- return buf || new u8(0);
20378
- var noBuf = !buf;
20379
- var resize = noBuf || st.i != 2;
20380
- var noSt = st.i;
20381
- if (noBuf)
20382
- buf = new u8(sl * 3);
20383
- var cbuf = function(l2) {
20384
- var bl = buf.length;
20385
- if (l2 > bl) {
20386
- var nbuf = new u8(Math.max(bl * 2, l2));
20387
- nbuf.set(buf);
20388
- buf = nbuf;
20389
- }
20390
- };
20391
- var final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;
20392
- var tbts = sl * 8;
20393
- do {
20394
- if (!lm) {
20395
- final = bits(dat, pos, 1);
20396
- var type = bits(dat, pos + 1, 3);
20397
- pos += 3;
20398
- if (!type) {
20399
- var s2 = shft(pos) + 4, l = dat[s2 - 4] | dat[s2 - 3] << 8, t2 = s2 + l;
20400
- if (t2 > sl) {
20401
- if (noSt)
20402
- err(0);
20403
- break;
20404
- }
20405
- if (resize)
20406
- cbuf(bt + l);
20407
- buf.set(dat.subarray(s2, t2), bt);
20408
- st.b = bt += l, st.p = pos = t2 * 8, st.f = final;
20409
- continue;
20410
- } else if (type == 1)
20411
- lm = flrm, dm = fdrm, lbt = 9, dbt = 5;
20412
- else if (type == 2) {
20413
- var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;
20414
- var tl = hLit + bits(dat, pos + 5, 31) + 1;
20415
- pos += 14;
20416
- var ldt = new u8(tl);
20417
- var clt = new u8(19);
20418
- for (var i = 0; i < hcLen; ++i) {
20419
- clt[clim[i]] = bits(dat, pos + i * 3, 7);
20420
- }
20421
- pos += hcLen * 3;
20422
- var clb = max(clt), clbmsk = (1 << clb) - 1;
20423
- var clm = hMap(clt, clb, 1);
20424
- for (var i = 0; i < tl; ) {
20425
- var r = clm[bits(dat, pos, clbmsk)];
20426
- pos += r & 15;
20427
- var s2 = r >> 4;
20428
- if (s2 < 16) {
20429
- ldt[i++] = s2;
20430
- } else {
20431
- var c = 0, n = 0;
20432
- if (s2 == 16)
20433
- n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1];
20434
- else if (s2 == 17)
20435
- n = 3 + bits(dat, pos, 7), pos += 3;
20436
- else if (s2 == 18)
20437
- n = 11 + bits(dat, pos, 127), pos += 7;
20438
- while (n--)
20439
- ldt[i++] = c;
20440
- }
20441
- }
20442
- var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);
20443
- lbt = max(lt);
20444
- dbt = max(dt);
20445
- lm = hMap(lt, lbt, 1);
20446
- dm = hMap(dt, dbt, 1);
20447
- } else
20448
- err(1);
20449
- if (pos > tbts) {
20450
- if (noSt)
20451
- err(0);
20452
- break;
20453
- }
20454
- }
20455
- if (resize)
20456
- cbuf(bt + 131072);
20457
- var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;
20458
- var lpos = pos;
20459
- for (; ; lpos = pos) {
20460
- var c = lm[bits16(dat, pos) & lms], sym = c >> 4;
20461
- pos += c & 15;
20462
- if (pos > tbts) {
20463
- if (noSt)
20464
- err(0);
20465
- break;
20466
- }
20467
- if (!c)
20468
- err(2);
20469
- if (sym < 256)
20470
- buf[bt++] = sym;
20471
- else if (sym == 256) {
20472
- lpos = pos, lm = null;
20473
- break;
20474
- } else {
20475
- var add = sym - 254;
20476
- if (sym > 264) {
20477
- var i = sym - 257, b = fleb[i];
20478
- add = bits(dat, pos, (1 << b) - 1) + fl[i];
20479
- pos += b;
20480
- }
20481
- var d = dm[bits16(dat, pos) & dms], dsym = d >> 4;
20482
- if (!d)
20483
- err(3);
20484
- pos += d & 15;
20485
- var dt = fd[dsym];
20486
- if (dsym > 3) {
20487
- var b = fdeb[dsym];
20488
- dt += bits16(dat, pos) & (1 << b) - 1, pos += b;
20489
- }
20490
- if (pos > tbts) {
20491
- if (noSt)
20492
- err(0);
20493
- break;
20494
- }
20495
- if (resize)
20496
- cbuf(bt + 131072);
20497
- var end = bt + add;
20498
- if (bt < dt) {
20499
- var shift = dl - dt, dend = Math.min(dt, end);
20500
- if (shift + bt < 0)
20501
- err(3);
20502
- for (; bt < dend; ++bt)
20503
- buf[bt] = dict[shift + bt];
20504
- }
20505
- for (; bt < end; ++bt)
20506
- buf[bt] = buf[bt - dt];
20507
- }
20508
- }
20509
- st.l = lm, st.p = lpos, st.b = bt, st.f = final;
20510
- if (lm)
20511
- final = 1, st.m = lbt, st.d = dm, st.n = dbt;
20512
- } while (!final);
20513
- return bt != buf.length && noBuf ? slc(buf, 0, bt) : buf.subarray(0, bt);
20514
- };
20515
- var wbits = function(d, p2, v) {
20516
- v <<= p2 & 7;
20517
- var o = p2 / 8 | 0;
20518
- d[o] |= v;
20519
- d[o + 1] |= v >> 8;
20520
- };
20521
- var wbits16 = function(d, p2, v) {
20522
- v <<= p2 & 7;
20523
- var o = p2 / 8 | 0;
20524
- d[o] |= v;
20525
- d[o + 1] |= v >> 8;
20526
- d[o + 2] |= v >> 16;
20527
- };
20528
- var hTree = function(d, mb) {
20529
- var t2 = [];
20530
- for (var i = 0; i < d.length; ++i) {
20531
- if (d[i])
20532
- t2.push({ s: i, f: d[i] });
20533
- }
20534
- var s2 = t2.length;
20535
- var t22 = t2.slice();
20536
- if (!s2)
20537
- return { t: et, l: 0 };
20538
- if (s2 == 1) {
20539
- var v = new u8(t2[0].s + 1);
20540
- v[t2[0].s] = 1;
20541
- return { t: v, l: 1 };
20542
- }
20543
- t2.sort(function(a, b) {
20544
- return a.f - b.f;
20545
- });
20546
- t2.push({ s: -1, f: 25001 });
20547
- var l = t2[0], r = t2[1], i0 = 0, i1 = 1, i2 = 2;
20548
- t2[0] = { s: -1, f: l.f + r.f, l, r };
20549
- while (i1 != s2 - 1) {
20550
- l = t2[t2[i0].f < t2[i2].f ? i0++ : i2++];
20551
- r = t2[i0 != i1 && t2[i0].f < t2[i2].f ? i0++ : i2++];
20552
- t2[i1++] = { s: -1, f: l.f + r.f, l, r };
20553
- }
20554
- var maxSym = t22[0].s;
20555
- for (var i = 1; i < s2; ++i) {
20556
- if (t22[i].s > maxSym)
20557
- maxSym = t22[i].s;
20558
- }
20559
- var tr = new u16(maxSym + 1);
20560
- var mbt = ln(t2[i1 - 1], tr, 0);
20561
- if (mbt > mb) {
20562
- var i = 0, dt = 0;
20563
- var lft = mbt - mb, cst = 1 << lft;
20564
- t22.sort(function(a, b) {
20565
- return tr[b.s] - tr[a.s] || a.f - b.f;
20566
- });
20567
- for (; i < s2; ++i) {
20568
- var i2_1 = t22[i].s;
20569
- if (tr[i2_1] > mb) {
20570
- dt += cst - (1 << mbt - tr[i2_1]);
20571
- tr[i2_1] = mb;
20572
- } else
20573
- break;
20574
- }
20575
- dt >>= lft;
20576
- while (dt > 0) {
20577
- var i2_2 = t22[i].s;
20578
- if (tr[i2_2] < mb)
20579
- dt -= 1 << mb - tr[i2_2]++ - 1;
20580
- else
20581
- ++i;
20582
- }
20583
- for (; i >= 0 && dt; --i) {
20584
- var i2_3 = t22[i].s;
20585
- if (tr[i2_3] == mb) {
20586
- --tr[i2_3];
20587
- ++dt;
20588
- }
20589
- }
20590
- mbt = mb;
20591
- }
20592
- return { t: new u8(tr), l: mbt };
20593
- };
20594
- var ln = function(n, l, d) {
20595
- return n.s == -1 ? Math.max(ln(n.l, l, d + 1), ln(n.r, l, d + 1)) : l[n.s] = d;
20596
- };
20597
- var lc = function(c) {
20598
- var s2 = c.length;
20599
- while (s2 && !c[--s2])
20600
- ;
20601
- var cl = new u16(++s2);
20602
- var cli = 0, cln = c[0], cls = 1;
20603
- var w = function(v) {
20604
- cl[cli++] = v;
20605
- };
20606
- for (var i = 1; i <= s2; ++i) {
20607
- if (c[i] == cln && i != s2)
20608
- ++cls;
20609
- else {
20610
- if (!cln && cls > 2) {
20611
- for (; cls > 138; cls -= 138)
20612
- w(32754);
20613
- if (cls > 2) {
20614
- w(cls > 10 ? cls - 11 << 5 | 28690 : cls - 3 << 5 | 12305);
20615
- cls = 0;
20616
- }
20617
- } else if (cls > 3) {
20618
- w(cln), --cls;
20619
- for (; cls > 6; cls -= 6)
20620
- w(8304);
20621
- if (cls > 2)
20622
- w(cls - 3 << 5 | 8208), cls = 0;
20623
- }
20624
- while (cls--)
20625
- w(cln);
20626
- cls = 1;
20627
- cln = c[i];
20628
- }
20629
- }
20630
- return { c: cl.subarray(0, cli), n: s2 };
20631
- };
20632
- var clen = function(cf, cl) {
20633
- var l = 0;
20634
- for (var i = 0; i < cl.length; ++i)
20635
- l += cf[i] * cl[i];
20636
- return l;
20637
- };
20638
- var wfblk = function(out, pos, dat) {
20639
- var s2 = dat.length;
20640
- var o = shft(pos + 2);
20641
- out[o] = s2 & 255;
20642
- out[o + 1] = s2 >> 8;
20643
- out[o + 2] = out[o] ^ 255;
20644
- out[o + 3] = out[o + 1] ^ 255;
20645
- for (var i = 0; i < s2; ++i)
20646
- out[o + i + 4] = dat[i];
20647
- return (o + 4 + s2) * 8;
20648
- };
20649
- var wblk = function(dat, out, final, syms, lf, df, eb, li, bs, bl, p2) {
20650
- wbits(out, p2++, final);
20651
- ++lf[256];
20652
- var _a2 = hTree(lf, 15), dlt = _a2.t, mlb = _a2.l;
20653
- var _b2 = hTree(df, 15), ddt = _b2.t, mdb = _b2.l;
20654
- var _c = lc(dlt), lclt = _c.c, nlc = _c.n;
20655
- var _d = lc(ddt), lcdt = _d.c, ndc = _d.n;
20656
- var lcfreq = new u16(19);
20657
- for (var i = 0; i < lclt.length; ++i)
20658
- ++lcfreq[lclt[i] & 31];
20659
- for (var i = 0; i < lcdt.length; ++i)
20660
- ++lcfreq[lcdt[i] & 31];
20661
- var _e = hTree(lcfreq, 7), lct = _e.t, mlcb = _e.l;
20662
- var nlcc = 19;
20663
- for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc)
20664
- ;
20665
- var flen = bl + 5 << 3;
20666
- var ftlen = clen(lf, flt) + clen(df, fdt) + eb;
20667
- var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + 2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18];
20668
- if (bs >= 0 && flen <= ftlen && flen <= dtlen)
20669
- return wfblk(out, p2, dat.subarray(bs, bs + bl));
20670
- var lm, ll, dm, dl;
20671
- wbits(out, p2, 1 + (dtlen < ftlen)), p2 += 2;
20672
- if (dtlen < ftlen) {
20673
- lm = hMap(dlt, mlb, 0), ll = dlt, dm = hMap(ddt, mdb, 0), dl = ddt;
20674
- var llm = hMap(lct, mlcb, 0);
20675
- wbits(out, p2, nlc - 257);
20676
- wbits(out, p2 + 5, ndc - 1);
20677
- wbits(out, p2 + 10, nlcc - 4);
20678
- p2 += 14;
20679
- for (var i = 0; i < nlcc; ++i)
20680
- wbits(out, p2 + 3 * i, lct[clim[i]]);
20681
- p2 += 3 * nlcc;
20682
- var lcts = [lclt, lcdt];
20683
- for (var it = 0; it < 2; ++it) {
20684
- var clct = lcts[it];
20685
- for (var i = 0; i < clct.length; ++i) {
20686
- var len = clct[i] & 31;
20687
- wbits(out, p2, llm[len]), p2 += lct[len];
20688
- if (len > 15)
20689
- wbits(out, p2, clct[i] >> 5 & 127), p2 += clct[i] >> 12;
20690
- }
20691
- }
20692
- } else {
20693
- lm = flm, ll = flt, dm = fdm, dl = fdt;
20694
- }
20695
- for (var i = 0; i < li; ++i) {
20696
- var sym = syms[i];
20697
- if (sym > 255) {
20698
- var len = sym >> 18 & 31;
20699
- wbits16(out, p2, lm[len + 257]), p2 += ll[len + 257];
20700
- if (len > 7)
20701
- wbits(out, p2, sym >> 23 & 31), p2 += fleb[len];
20702
- var dst = sym & 31;
20703
- wbits16(out, p2, dm[dst]), p2 += dl[dst];
20704
- if (dst > 3)
20705
- wbits16(out, p2, sym >> 5 & 8191), p2 += fdeb[dst];
20706
- } else {
20707
- wbits16(out, p2, lm[sym]), p2 += ll[sym];
20708
- }
20709
- }
20710
- wbits16(out, p2, lm[256]);
20711
- return p2 + ll[256];
20712
- };
20713
- var deo = /* @__PURE__ */ new i32([65540, 131080, 131088, 131104, 262176, 1048704, 1048832, 2114560, 2117632]);
20714
- var et = /* @__PURE__ */ new u8(0);
20715
- var dflt = function(dat, lvl, plvl, pre, post, st) {
20716
- var s2 = st.z || dat.length;
20717
- var o = new u8(pre + s2 + 5 * (1 + Math.ceil(s2 / 7e3)) + post);
20718
- var w = o.subarray(pre, o.length - post);
20719
- var lst = st.l;
20720
- var pos = (st.r || 0) & 7;
20721
- if (lvl) {
20722
- if (pos)
20723
- w[0] = st.r >> 3;
20724
- var opt = deo[lvl - 1];
20725
- var n = opt >> 13, c = opt & 8191;
20726
- var msk_1 = (1 << plvl) - 1;
20727
- var prev = st.p || new u16(32768), head = st.h || new u16(msk_1 + 1);
20728
- var bs1_1 = Math.ceil(plvl / 3), bs2_1 = 2 * bs1_1;
20729
- var hsh = function(i2) {
20730
- return (dat[i2] ^ dat[i2 + 1] << bs1_1 ^ dat[i2 + 2] << bs2_1) & msk_1;
20731
- };
20732
- var syms = new i32(25e3);
20733
- var lf = new u16(288), df = new u16(32);
20734
- var lc_1 = 0, eb = 0, i = st.i || 0, li = 0, wi = st.w || 0, bs = 0;
20735
- for (; i + 2 < s2; ++i) {
20736
- var hv = hsh(i);
20737
- var imod = i & 32767, pimod = head[hv];
20738
- prev[imod] = pimod;
20739
- head[hv] = imod;
20740
- if (wi <= i) {
20741
- var rem = s2 - i;
20742
- if ((lc_1 > 7e3 || li > 24576) && (rem > 423 || !lst)) {
20743
- pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i - bs, pos);
20744
- li = lc_1 = eb = 0, bs = i;
20745
- for (var j = 0; j < 286; ++j)
20746
- lf[j] = 0;
20747
- for (var j = 0; j < 30; ++j)
20748
- df[j] = 0;
20749
- }
20750
- var l = 2, d = 0, ch_1 = c, dif = imod - pimod & 32767;
20751
- if (rem > 2 && hv == hsh(i - dif)) {
20752
- var maxn = Math.min(n, rem) - 1;
20753
- var maxd = Math.min(32767, i);
20754
- var ml = Math.min(258, rem);
20755
- while (dif <= maxd && --ch_1 && imod != pimod) {
20756
- if (dat[i + l] == dat[i + l - dif]) {
20757
- var nl = 0;
20758
- for (; nl < ml && dat[i + nl] == dat[i + nl - dif]; ++nl)
20759
- ;
20760
- if (nl > l) {
20761
- l = nl, d = dif;
20762
- if (nl > maxn)
20763
- break;
20764
- var mmd = Math.min(dif, nl - 2);
20765
- var md = 0;
20766
- for (var j = 0; j < mmd; ++j) {
20767
- var ti = i - dif + j & 32767;
20768
- var pti = prev[ti];
20769
- var cd = ti - pti & 32767;
20770
- if (cd > md)
20771
- md = cd, pimod = ti;
20772
- }
20773
- }
20774
- }
20775
- imod = pimod, pimod = prev[imod];
20776
- dif += imod - pimod & 32767;
20777
- }
20778
- }
20779
- if (d) {
20780
- syms[li++] = 268435456 | revfl[l] << 18 | revfd[d];
20781
- var lin = revfl[l] & 31, din = revfd[d] & 31;
20782
- eb += fleb[lin] + fdeb[din];
20783
- ++lf[257 + lin];
20784
- ++df[din];
20785
- wi = i + l;
20786
- ++lc_1;
20787
- } else {
20788
- syms[li++] = dat[i];
20789
- ++lf[dat[i]];
20790
- }
20791
- }
20792
- }
20793
- for (i = Math.max(i, wi); i < s2; ++i) {
20794
- syms[li++] = dat[i];
20795
- ++lf[dat[i]];
20796
- }
20797
- pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i - bs, pos);
20798
- if (!lst) {
20799
- st.r = pos & 7 | w[pos / 8 | 0] << 3;
20800
- pos -= 7;
20801
- st.h = head, st.p = prev, st.i = i, st.w = wi;
20802
- }
20803
- } else {
20804
- for (var i = st.w || 0; i < s2 + lst; i += 65535) {
20805
- var e = i + 65535;
20806
- if (e >= s2) {
20807
- w[pos / 8 | 0] = lst;
20808
- e = s2;
20809
- }
20810
- pos = wfblk(w, pos + 1, dat.subarray(i, e));
20811
- }
20812
- st.i = s2;
20813
- }
20814
- return slc(o, 0, pre + shft(pos) + post);
20815
- };
20816
- var crct = /* @__PURE__ */ (function() {
20817
- var t2 = new Int32Array(256);
20818
- for (var i = 0; i < 256; ++i) {
20819
- var c = i, k = 9;
20820
- while (--k)
20821
- c = (c & 1 && -306674912) ^ c >>> 1;
20822
- t2[i] = c;
20823
- }
20824
- return t2;
20825
- })();
20826
- var crc = function() {
20827
- var c = -1;
20828
- return {
20829
- p: function(d) {
20830
- var cr = c;
20831
- for (var i = 0; i < d.length; ++i)
20832
- cr = crct[cr & 255 ^ d[i]] ^ cr >>> 8;
20833
- c = cr;
20834
- },
20835
- d: function() {
20836
- return ~c;
20837
- }
20838
- };
20839
- };
20840
- var dopt = function(dat, opt, pre, post, st) {
20841
- if (!st) {
20842
- st = { l: 1 };
20843
- if (opt.dictionary) {
20844
- var dict = opt.dictionary.subarray(-32768);
20845
- var newDat = new u8(dict.length + dat.length);
20846
- newDat.set(dict);
20847
- newDat.set(dat, dict.length);
20848
- dat = newDat;
20849
- st.w = dict.length;
20850
- }
20851
- }
20852
- return dflt(dat, opt.level == null ? 6 : opt.level, opt.mem == null ? st.l ? Math.ceil(Math.max(8, Math.min(13, Math.log(dat.length))) * 1.5) : 20 : 12 + opt.mem, pre, post, st);
20853
- };
20854
- var mrg = function(a, b) {
20855
- var o = {};
20856
- for (var k in a)
20857
- o[k] = a[k];
20858
- for (var k in b)
20859
- o[k] = b[k];
20860
- return o;
20861
- };
20862
- var b2 = function(d, b) {
20863
- return d[b] | d[b + 1] << 8;
20864
- };
20865
- var b4 = function(d, b) {
20866
- return (d[b] | d[b + 1] << 8 | d[b + 2] << 16 | d[b + 3] << 24) >>> 0;
20867
- };
20868
- var b8 = function(d, b) {
20869
- return b4(d, b) + b4(d, b + 4) * 4294967296;
20870
- };
20871
- var wbytes = function(d, b, v) {
20872
- for (; v; ++b)
20873
- d[b] = v, v >>>= 8;
20874
- };
20875
- function deflateSync(data, opts) {
20876
- return dopt(data, opts || {}, 0, 0);
20877
- }
20878
- var Inflate = /* @__PURE__ */ (function() {
20879
- function Inflate2(opts, cb) {
20880
- if (typeof opts == "function")
20881
- cb = opts, opts = {};
20882
- this.ondata = cb;
20883
- var dict = opts && opts.dictionary && opts.dictionary.subarray(-32768);
20884
- this.s = { i: 0, b: dict ? dict.length : 0 };
20885
- this.o = new u8(32768);
20886
- this.p = new u8(0);
20887
- if (dict)
20888
- this.o.set(dict);
20889
- }
20890
- Inflate2.prototype.e = function(c) {
20891
- if (!this.ondata)
20892
- err(5);
20893
- if (this.d)
20894
- err(4);
20895
- if (!this.p.length)
20896
- this.p = c;
20897
- else if (c.length) {
20898
- var n = new u8(this.p.length + c.length);
20899
- n.set(this.p), n.set(c, this.p.length), this.p = n;
20900
- }
20901
- };
20902
- Inflate2.prototype.c = function(final) {
20903
- this.s.i = +(this.d = final || false);
20904
- var bts = this.s.b;
20905
- var dt = inflt(this.p, this.s, this.o);
20906
- this.ondata(slc(dt, bts, this.s.b), this.d);
20907
- this.o = slc(dt, this.s.b - 32768), this.s.b = this.o.length;
20908
- this.p = slc(this.p, this.s.p / 8 | 0), this.s.p &= 7;
20909
- };
20910
- Inflate2.prototype.push = function(chunk, final) {
20911
- this.e(chunk), this.c(final);
20912
- };
20913
- return Inflate2;
20914
- })();
20915
- var fltn = function(d, p2, t2, o) {
20916
- for (var k in d) {
20917
- var val = d[k], n = p2 + k, op = o;
20918
- if (Array.isArray(val))
20919
- op = mrg(o, val[1]), val = val[0];
20920
- if (val instanceof u8)
20921
- t2[n] = [val, op];
20922
- else {
20923
- t2[n += "/"] = [new u8(0), op];
20924
- fltn(val, n, t2, o);
20925
- }
20926
- }
20927
- };
20928
- var te = typeof TextEncoder != "undefined" && /* @__PURE__ */ new TextEncoder();
20929
- var td = typeof TextDecoder != "undefined" && /* @__PURE__ */ new TextDecoder();
20930
- var tds = 0;
20931
- try {
20932
- td.decode(et, { stream: true });
20933
- tds = 1;
20934
- } catch (e) {
20935
- }
20936
- var dutf8 = function(d) {
20937
- for (var r = "", i = 0; ; ) {
20938
- var c = d[i++];
20939
- var eb = (c > 127) + (c > 223) + (c > 239);
20940
- if (i + eb > d.length)
20941
- return { s: r, r: slc(d, i - 1) };
20942
- if (!eb)
20943
- r += String.fromCharCode(c);
20944
- else if (eb == 3) {
20945
- c = ((c & 15) << 18 | (d[i++] & 63) << 12 | (d[i++] & 63) << 6 | d[i++] & 63) - 65536, r += String.fromCharCode(55296 | c >> 10, 56320 | c & 1023);
20946
- } else if (eb & 1)
20947
- r += String.fromCharCode((c & 31) << 6 | d[i++] & 63);
20948
- else
20949
- r += String.fromCharCode((c & 15) << 12 | (d[i++] & 63) << 6 | d[i++] & 63);
20950
- }
20951
- };
20952
- function strToU8(str, latin1) {
20953
- if (latin1) {
20954
- var ar_1 = new u8(str.length);
20955
- for (var i = 0; i < str.length; ++i)
20956
- ar_1[i] = str.charCodeAt(i);
20957
- return ar_1;
20958
- }
20959
- if (te)
20960
- return te.encode(str);
20961
- var l = str.length;
20962
- var ar = new u8(str.length + (str.length >> 1));
20963
- var ai = 0;
20964
- var w = function(v) {
20965
- ar[ai++] = v;
20966
- };
20967
- for (var i = 0; i < l; ++i) {
20968
- if (ai + 5 > ar.length) {
20969
- var n = new u8(ai + 8 + (l - i << 1));
20970
- n.set(ar);
20971
- ar = n;
20972
- }
20973
- var c = str.charCodeAt(i);
20974
- if (c < 128 || latin1)
20975
- w(c);
20976
- else if (c < 2048)
20977
- w(192 | c >> 6), w(128 | c & 63);
20978
- else if (c > 55295 && c < 57344)
20979
- c = 65536 + (c & 1023 << 10) | str.charCodeAt(++i) & 1023, w(240 | c >> 18), w(128 | c >> 12 & 63), w(128 | c >> 6 & 63), w(128 | c & 63);
20980
- else
20981
- w(224 | c >> 12), w(128 | c >> 6 & 63), w(128 | c & 63);
20982
- }
20983
- return slc(ar, 0, ai);
20984
- }
20985
- function strFromU8(dat, latin1) {
20986
- if (latin1) {
20987
- var r = "";
20988
- for (var i = 0; i < dat.length; i += 16384)
20989
- r += String.fromCharCode.apply(null, dat.subarray(i, i + 16384));
20990
- return r;
20991
- } else if (td) {
20992
- return td.decode(dat);
20993
- } else {
20994
- var _a2 = dutf8(dat), s2 = _a2.s, r = _a2.r;
20995
- if (r.length)
20996
- err(8);
20997
- return s2;
20998
- }
20999
- }
21000
- var z64e = function(d, b) {
21001
- for (; b2(d, b) != 1; b += 4 + b2(d, b + 2))
21002
- ;
21003
- return [b8(d, b + 12), b8(d, b + 4), b8(d, b + 20)];
21004
- };
21005
- var exfl = function(ex) {
21006
- var le = 0;
21007
- if (ex) {
21008
- for (var k in ex) {
21009
- var l = ex[k].length;
21010
- if (l > 65535)
21011
- err(9);
21012
- le += l + 4;
21013
- }
21014
- }
21015
- return le;
21016
- };
21017
- var wzh = function(d, b, f, fn, u, c, ce, co) {
21018
- var fl2 = fn.length, ex = f.extra, col = co && co.length;
21019
- var exl = exfl(ex);
21020
- wbytes(d, b, ce != null ? 33639248 : 67324752), b += 4;
21021
- if (ce != null)
21022
- d[b++] = 20, d[b++] = f.os;
21023
- d[b] = 20, b += 2;
21024
- d[b++] = f.flag << 1 | (c < 0 && 8), d[b++] = u && 8;
21025
- d[b++] = f.compression & 255, d[b++] = f.compression >> 8;
21026
- var dt = new Date(f.mtime == null ? Date.now() : f.mtime), y = dt.getFullYear() - 1980;
21027
- if (y < 0 || y > 119)
21028
- err(10);
21029
- wbytes(d, b, y << 25 | dt.getMonth() + 1 << 21 | dt.getDate() << 16 | dt.getHours() << 11 | dt.getMinutes() << 5 | dt.getSeconds() >> 1), b += 4;
21030
- if (c != -1) {
21031
- wbytes(d, b, f.crc);
21032
- wbytes(d, b + 4, c < 0 ? -c - 2 : c);
21033
- wbytes(d, b + 8, f.size);
21034
- }
21035
- wbytes(d, b + 12, fl2);
21036
- wbytes(d, b + 14, exl), b += 16;
21037
- if (ce != null) {
21038
- wbytes(d, b, col);
21039
- wbytes(d, b + 6, f.attrs);
21040
- wbytes(d, b + 10, ce), b += 14;
21041
- }
21042
- d.set(fn, b);
21043
- b += fl2;
21044
- if (exl) {
21045
- for (var k in ex) {
21046
- var exf = ex[k], l = exf.length;
21047
- wbytes(d, b, +k);
21048
- wbytes(d, b + 2, l);
21049
- d.set(exf, b + 4), b += 4 + l;
21050
- }
21051
- }
21052
- if (col)
21053
- d.set(co, b), b += col;
21054
- return b;
21055
- };
21056
- var wzf = function(o, b, c, d, e) {
21057
- wbytes(o, b, 101010256);
21058
- wbytes(o, b + 8, c);
21059
- wbytes(o, b + 10, c);
21060
- wbytes(o, b + 12, d);
21061
- wbytes(o, b + 16, e);
21062
- };
21063
- function zipSync(data, opts) {
21064
- if (!opts)
21065
- opts = {};
21066
- var r = {};
21067
- var files = [];
21068
- fltn(data, "", r, opts);
21069
- var o = 0;
21070
- var tot = 0;
21071
- for (var fn in r) {
21072
- var _a2 = r[fn], file = _a2[0], p2 = _a2[1];
21073
- var compression = p2.level == 0 ? 0 : 8;
21074
- var f = strToU8(fn), s2 = f.length;
21075
- var com = p2.comment, m = com && strToU8(com), ms = m && m.length;
21076
- var exl = exfl(p2.extra);
21077
- if (s2 > 65535)
21078
- err(11);
21079
- var d = compression ? deflateSync(file, p2) : file, l = d.length;
21080
- var c = crc();
21081
- c.p(file);
21082
- files.push(mrg(p2, {
21083
- size: file.length,
21084
- crc: c.d(),
21085
- c: d,
21086
- f,
21087
- m,
21088
- u: s2 != fn.length || m && com.length != ms,
21089
- o,
21090
- compression
21091
- }));
21092
- o += 30 + s2 + exl + l;
21093
- tot += 76 + 2 * (s2 + exl) + (ms || 0) + l;
21094
- }
21095
- var out = new u8(tot + 22), oe = o, cdl = tot - o;
21096
- for (var i = 0; i < files.length; ++i) {
21097
- var f = files[i];
21098
- wzh(out, f.o, f, f.f, f.u, f.c.length);
21099
- var badd = 30 + f.f.length + exfl(f.extra);
21100
- out.set(f.c, f.o + badd);
21101
- wzh(out, o, f, f.f, f.u, f.c.length, f.o, f.m), o += 16 + badd + (f.m ? f.m.length : 0);
21102
- }
21103
- wzf(out, o, files.length, cdl, oe);
21104
- return out;
21105
- }
21106
- var UnzipPassThrough = /* @__PURE__ */ (function() {
21107
- function UnzipPassThrough2() {
21108
- }
21109
- UnzipPassThrough2.prototype.push = function(data, final) {
21110
- this.ondata(null, data, final);
21111
- };
21112
- UnzipPassThrough2.compression = 0;
21113
- return UnzipPassThrough2;
21114
- })();
21115
- var UnzipInflate = /* @__PURE__ */ (function() {
21116
- function UnzipInflate2() {
21117
- var _this = this;
21118
- this.i = new Inflate(function(dat, final) {
21119
- _this.ondata(null, dat, final);
21120
- });
21121
- }
21122
- UnzipInflate2.prototype.push = function(data, final) {
21123
- try {
21124
- this.i.push(data, final);
21125
- } catch (e) {
21126
- this.ondata(e, null, final);
21127
- }
21128
- };
21129
- UnzipInflate2.compression = 8;
21130
- return UnzipInflate2;
21131
- })();
21132
- var Unzip = /* @__PURE__ */ (function() {
21133
- function Unzip2(cb) {
21134
- this.onfile = cb;
21135
- this.k = [];
21136
- this.o = {
21137
- 0: UnzipPassThrough
21138
- };
21139
- this.p = et;
21140
- }
21141
- Unzip2.prototype.push = function(chunk, final) {
21142
- var _this = this;
21143
- if (!this.onfile)
21144
- err(5);
21145
- if (!this.p)
21146
- err(4);
21147
- if (this.c > 0) {
21148
- var len = Math.min(this.c, chunk.length);
21149
- var toAdd = chunk.subarray(0, len);
21150
- this.c -= len;
21151
- if (this.d)
21152
- this.d.push(toAdd, !this.c);
21153
- else
21154
- this.k[0].push(toAdd);
21155
- chunk = chunk.subarray(len);
21156
- if (chunk.length)
21157
- return this.push(chunk, final);
21158
- } else {
21159
- var f = 0, i = 0, is = void 0, buf = void 0;
21160
- if (!this.p.length)
21161
- buf = chunk;
21162
- else if (!chunk.length)
21163
- buf = this.p;
21164
- else {
21165
- buf = new u8(this.p.length + chunk.length);
21166
- buf.set(this.p), buf.set(chunk, this.p.length);
21167
- }
21168
- var l = buf.length, oc = this.c, add = oc && this.d;
21169
- var _loop_2 = function() {
21170
- var _a2;
21171
- var sig = b4(buf, i);
21172
- if (sig == 67324752) {
21173
- f = 1, is = i;
21174
- this_1.d = null;
21175
- this_1.c = 0;
21176
- var bf = b2(buf, i + 6), cmp_1 = b2(buf, i + 8), u = bf & 2048, dd = bf & 8, fnl = b2(buf, i + 26), es = b2(buf, i + 28);
21177
- if (l > i + 30 + fnl + es) {
21178
- var chks_3 = [];
21179
- this_1.k.unshift(chks_3);
21180
- f = 2;
21181
- var sc_1 = b4(buf, i + 18), su_1 = b4(buf, i + 22);
21182
- var fn_1 = strFromU8(buf.subarray(i + 30, i += 30 + fnl), !u);
21183
- if (sc_1 == 4294967295) {
21184
- _a2 = dd ? [-2] : z64e(buf, i), sc_1 = _a2[0], su_1 = _a2[1];
21185
- } else if (dd)
21186
- sc_1 = -1;
21187
- i += es;
21188
- this_1.c = sc_1;
21189
- var d_1;
21190
- var file_1 = {
21191
- name: fn_1,
21192
- compression: cmp_1,
21193
- start: function() {
21194
- if (!file_1.ondata)
21195
- err(5);
21196
- if (!sc_1)
21197
- file_1.ondata(null, et, true);
21198
- else {
21199
- var ctr = _this.o[cmp_1];
21200
- if (!ctr)
21201
- file_1.ondata(err(14, "unknown compression type " + cmp_1, 1), null, false);
21202
- d_1 = sc_1 < 0 ? new ctr(fn_1) : new ctr(fn_1, sc_1, su_1);
21203
- d_1.ondata = function(err2, dat3, final2) {
21204
- file_1.ondata(err2, dat3, final2);
21205
- };
21206
- for (var _i = 0, chks_4 = chks_3; _i < chks_4.length; _i++) {
21207
- var dat2 = chks_4[_i];
21208
- d_1.push(dat2, false);
21209
- }
21210
- if (_this.k[0] == chks_3 && _this.c)
21211
- _this.d = d_1;
21212
- else
21213
- d_1.push(et, true);
21214
- }
21215
- },
21216
- terminate: function() {
21217
- if (d_1 && d_1.terminate)
21218
- d_1.terminate();
21219
- }
21220
- };
21221
- if (sc_1 >= 0)
21222
- file_1.size = sc_1, file_1.originalSize = su_1;
21223
- this_1.onfile(file_1);
21224
- }
21225
- return "break";
21226
- } else if (oc) {
21227
- if (sig == 134695760) {
21228
- is = i += 12 + (oc == -2 && 8), f = 3, this_1.c = 0;
21229
- return "break";
21230
- } else if (sig == 33639248) {
21231
- is = i -= 4, f = 3, this_1.c = 0;
21232
- return "break";
21233
- }
21234
- }
21235
- };
21236
- var this_1 = this;
21237
- for (; i < l - 4; ++i) {
21238
- var state_1 = _loop_2();
21239
- if (state_1 === "break")
21240
- break;
21241
- }
21242
- this.p = et;
21243
- if (oc < 0) {
21244
- var dat = f ? buf.subarray(0, is - 12 - (oc == -2 && 8) - (b4(buf, is - 16) == 134695760 && 4)) : buf.subarray(0, i);
21245
- if (add)
21246
- add.push(dat, !!f);
21247
- else
21248
- this.k[+(f == 2)].push(dat);
21249
- }
21250
- if (f & 2)
21251
- return this.push(buf.subarray(i), final);
21252
- this.p = buf.subarray(i);
21253
- }
21254
- if (final) {
21255
- if (this.c)
21256
- err(13);
21257
- this.p = null;
21258
- }
21259
- };
21260
- Unzip2.prototype.register = function(decoder) {
21261
- this.o[decoder.compression] = decoder;
21262
- };
21263
- return Unzip2;
21264
- })();
21265
-
21266
- // ../design/dist/submission.js
21267
- import { z as z23 } from "zod";
21268
- import { z as z7 } from "zod";
21269
- var id2 = z7.string().regex(/^[a-z0-9][a-z0-9-]{0,39}$/);
21270
- var member = z7.object({ id: id2, file: z7.string().min(1).max(4096) }).strict();
21271
- var kitDocumentSchema = z7.object({
21272
- format: z7.literal("makeables-kit"),
21273
- version: z7.literal(1),
21274
- name: z7.string().trim().min(1).max(60),
21275
- items: z7.array(member).max(24),
21276
- sheets: z7.array(member).max(4).default([])
21277
- }).strict().superRefine((kit, ctx) => {
21278
- for (const key of ["items", "sheets"])
21279
- if (new Set(kit[key].map((item) => item.id)).size !== kit[key].length)
21280
- ctx.addIssue({ code: "custom", path: [key], message: "Duplicate member IDs." });
21281
- });
21282
- var FILE_LIMIT = 5e6;
21283
- var PACKAGE_LIMIT = 24e6;
21284
- var FILE_COUNT_LIMIT = 40;
21285
- var KIT_FILE_COUNT_LIMIT = 160;
21286
- var MANIFEST_LIMIT = 2e5;
21287
- var providers = { ...designProfiles, kit: { label: "Kit" } };
21288
- var pathPattern = /^[a-zA-Z0-9_-]+(?:\/[a-zA-Z0-9_-]+)*\.(?:json|svg|png|webp|jpg|jpeg|gif|pdf)$/;
21289
- var pathSchema = z23.string().max(100).regex(pathPattern);
21290
- var archivePathSchema = z23.string().max(147).regex(pathPattern);
21291
- var mimeSchema = z23.enum([
21292
- "application/json",
21293
- "image/svg+xml",
21294
- "image/png",
21295
- "image/webp",
21296
- "image/jpeg",
21297
- "image/gif",
21298
- "application/pdf"
21299
- ]);
21300
- var submissionMetadataSchema = z23.object({
21301
- title: z23.string().trim().min(1).max(60),
21302
- category: z23.enum(["Anime", "Gaming", "Minimal", "Abstract"]).default("Abstract"),
21303
- creditName: z23.string().trim().min(1).max(60),
21304
- creditUrl: z23.string().url().max(512).refine((value) => new URL(value).protocol === "https:").nullable().default(null)
21305
- }).strict();
21306
- var manifestBase = z23.object({
21307
- format: z23.literal("makeables-package"),
21308
- version: z23.literal(1),
21309
- product: z23.enum(productIds),
21310
- finish: stickerMaterialSchema.shape.finish.optional(),
21311
- title: z23.string().min(1).max(60),
21312
- document: pathSchema.optional(),
21313
- source: pathSchema.optional(),
21314
- front: pathSchema,
21315
- back: pathSchema.optional(),
21316
- portrait: pathSchema.optional(),
21317
- artwork: pathSchema.optional(),
21318
- assets: z23.record(z23.string().max(60), pathSchema).default({}),
21319
- files: z23.array(
21320
- z23.object({
21321
- path: pathSchema,
21322
- mime: mimeSchema,
21323
- bytes: z23.number().int().min(1).max(FILE_LIMIT),
21324
- sha256: z23.string().regex(/^[a-f0-9]{64}$/)
21325
- }).strict()
21326
- ).min(1).max(FILE_COUNT_LIMIT)
21327
- }).strict();
21328
- var designManifestSchema = manifestBase.superRefine((m, ctx) => {
21329
- const paths = new Set(m.files.map((f) => f.path));
21330
- const issue = (message) => ctx.addIssue({ code: "custom", message });
21331
- if (paths.has("manifest.json")) issue("manifest.json is reserved for the package index.");
21332
- if (paths.size !== m.files.length) issue("Duplicate asset paths.");
21333
- if (m.files.reduce((n, f) => n + f.bytes, 0) > PACKAGE_LIMIT) issue("The package exceeds 24 MB.");
21334
- if (!m.document && !m.source) issue("Include the editable document or original artwork.");
21335
- if (m.document && m.product !== "sticker" && !m.back) issue("Include previews of both faces.");
21336
- if (m.product === "sticker" && !m.finish) issue("Include the sticker finish.");
21337
- if (m.product !== "sticker" && m.finish) issue("Only stickers have a sticker finish.");
21338
- if (m.product === "sticker" && (m.back || m.portrait))
21339
- issue("Stickers contain one face and no participant portrait.");
21340
- for (const path2 of [
21341
- m.document,
21342
- m.source,
21343
- m.front,
21344
- m.back,
21345
- m.portrait,
21346
- m.artwork,
21347
- ...Object.values(m.assets)
21348
- ])
21349
- if (path2 && !paths.has(path2)) issue(`Missing asset: ${path2}.`);
21350
- for (const file of m.files) {
21351
- if (file.mime === "application/pdf") issue("Print PDFs belong to kit sheets.");
21352
- if (![
21353
- m.document,
21354
- m.source,
21355
- m.front,
21356
- m.back,
21357
- m.portrait,
21358
- m.artwork,
21359
- ...Object.values(m.assets)
21360
- ].includes(file.path))
21361
- issue(`Unreferenced file: ${file.path}.`);
21362
- if (file.path === m.document !== (file.mime === "application/json"))
21363
- issue("Only the editable document may contain JSON.");
21364
- if (file.path === m.source && (m.product !== "card" || !["image/svg+xml", "image/png", "image/jpeg", "image/webp"].includes(file.mime)))
21365
- issue("Original artwork must be a card SVG, PNG, JPEG or WebP.");
21366
- if ([m.front, m.back].includes(file.path) && file.path !== m.source && file.mime === "image/svg+xml")
21367
- issue("Use raster previews for layered documents.");
21368
- }
21369
- });
21370
- var kitId = z23.string().regex(/^[a-z0-9][a-z0-9-]{0,39}$/);
21371
- var kitManifestSchema = manifestBase.extend({
21372
- product: z23.literal("kit"),
21373
- files: z23.array(manifestBase.shape.files.element.extend({ path: archivePathSchema })).min(1).max(KIT_FILE_COUNT_LIMIT),
21374
- items: z23.array(z23.object({ id: kitId, manifest: designManifestSchema }).strict()).min(1).max(24),
21375
- sheets: z23.array(
21376
- z23.object({
21377
- id: kitId,
21378
- document: pathSchema,
21379
- preview: pathSchema,
21380
- pdf: pathSchema.optional()
21381
- }).strict()
21382
- ).max(4).default([])
21383
- }).superRefine((m, ctx) => {
21384
- const issue = (message) => ctx.addIssue({ code: "custom", message });
21385
- if (m.document || m.source || m.back || m.portrait || m.artwork || m.finish)
21386
- issue("A kit has a cover and member documents, not a single design.");
21387
- if (Object.keys(m.assets).length) issue("Kit images belong to their member manifests.");
21388
- if (new Set(m.items.map((item) => item.id)).size !== m.items.length)
21389
- issue("Duplicate kit item IDs.");
21390
- if (new Set(m.sheets.map((sheet) => sheet.id)).size !== m.sheets.length)
21391
- issue("Duplicate kit sheet IDs.");
21392
- const expected = /* @__PURE__ */ new Map([
21393
- [m.front, { mime: "image/png" }]
21394
- ]);
21395
- const add = (path2, file) => {
21396
- if (expected.has(path2)) issue(`Duplicate kit file: ${path2}.`);
21397
- expected.set(path2, file);
21398
- };
21399
- for (const item of m.items)
21400
- for (const file of item.manifest.files) add(`items/${item.id}/${file.path}`, file);
21401
- for (const sheet of m.sheets) {
21402
- add(sheet.document, { mime: "application/json" });
21403
- add(sheet.preview, { mime: "image/png" });
21404
- if (sheet.pdf) add(sheet.pdf, { mime: "application/pdf" });
21405
- }
21406
- if (expected.has("manifest.json")) issue("manifest.json is reserved.");
21407
- if (new Set(m.files.map((file) => file.path)).size !== m.files.length || m.files.length !== expected.size)
21408
- issue("The kit file list must contain exactly its cover, members and sheets.");
21409
- if (m.files.reduce((sum, file) => sum + file.bytes, 0) > PACKAGE_LIMIT)
21410
- issue("The package exceeds 24 MB.");
21411
- for (const file of m.files) {
21412
- const wanted = expected.get(file.path);
21413
- if (!wanted || wanted.mime !== file.mime || wanted.bytes !== void 0 && wanted.bytes !== file.bytes || wanted.sha256 !== void 0 && wanted.sha256 !== file.sha256)
21414
- issue(`Kit member metadata does not match: ${file.path}.`);
21415
- if (file.mime === "application/pdf" && !file.path.endsWith(".pdf"))
21416
- issue("Print PDFs must use .pdf paths.");
21417
- }
21418
- for (const path2 of expected.keys())
21419
- if (!m.files.some((file) => file.path === path2)) issue(`Missing kit file: ${path2}.`);
21420
- });
21421
- var manifestSchema = z23.union([designManifestSchema, kitManifestSchema]);
21422
- var documentSchema = z23.object({ design: badgeDesignSchema, participant: communityParticipantSchema.optional() }).strict();
21423
- var encoder = new TextEncoder();
21424
- var jsonBytes = (value) => encoder.encode(canonicalJson(value));
21425
- var parseJson = (bytes) => JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
21426
- var hashBytes = (bytes) => communityDigest(new Blob([new Uint8Array(bytes)]));
21427
- function requiredAssets(design2) {
21428
- const layers = [...design2.front.layers, ...design2.back.layers];
21429
- return {
21430
- portrait: layers.some((l) => l.kind === "portrait"),
21431
- artwork: Boolean(design2.artwork) || layers.some((l) => l.kind === "image" && l.asset === "art"),
21432
- assets: [
21433
- ...referencedDesignAssets(design2).filter(
21434
- (id22) => id22 !== "art" && design2.assets?.[id22]?.source !== "image"
21435
- )
21436
- ]
21437
- };
21438
- }
21439
- function missingAssets(draft) {
21440
- const required = requiredAssets(draft.design);
21441
- return [
21442
- ...required.portrait && !draft.portrait ? ["portrait"] : [],
21443
- ...required.artwork && !draft.artwork ? ["artwork"] : [],
21444
- ...required.assets.filter((id22) => !draft.assets[id22])
21445
- ];
21446
- }
21447
- async function importDraft(value) {
21448
- if (value && typeof value === "object" && "format" in value && value.format === "makeables-bundle") {
21449
- const { bundle } = await validateBadgeBundle(value);
21450
- const draft = {
21451
- design: bundle.snapshot.design,
21452
- participant: bundle.snapshot.participant,
21453
- files: {},
21454
- mime: {},
21455
- assets: {}
21456
- };
21457
- for (const slot of ["portrait", "artwork"]) {
21458
- const image2 = bundle.images[slot];
21459
- if (!image2) continue;
21460
- const path2 = `${slot}.${image2.mimeType.split("/")[1]}`;
21461
- draft[slot] = path2;
21462
- draft.files[path2] = bundleImageBytes(image2);
21463
- draft.mime[path2] = image2.mimeType;
21464
- }
21465
- return draft;
21466
- }
21467
- const document2 = documentSchema.parse(
21468
- value && typeof value === "object" && "design" in value ? value : { design: value }
21469
- );
21470
- return { ...document2, files: {}, mime: {}, assets: {} };
21471
- }
21472
- async function assemblePackage(input, files, mime) {
21473
- const manifest = manifestSchema.parse({
21474
- ...input,
21475
- format: "makeables-package",
21476
- version: 1,
21477
- files: await Promise.all(
21478
- Object.entries(files).map(async ([path2, bytes]) => ({
21479
- path: path2,
21480
- mime: mime[path2],
21481
- bytes: bytes.length,
21482
- sha256: await hashBytes(bytes)
21483
- }))
21484
- )
21485
- });
21486
- const result = { manifest, files };
21487
- await validatePackage(result);
21488
- return result;
21489
- }
21490
- async function draftPackage(draft, previews) {
21491
- const sticker = draft.design.product === "sticker";
21492
- if (!sticker && !previews.back) throw new Error("Include previews of both faces.");
21493
- const missing = missingAssets(draft);
21494
- if (missing.length) throw new Error(`Add the missing images: ${missing.join(", ")}.`);
21495
- return assemblePackage(
21496
- {
21497
- product: draft.design.product ?? "badge",
21498
- ...sticker ? { finish: draft.design.sticker?.finish ?? defaultStickerMaterial.finish } : {},
21499
- title: draft.design.name,
21500
- document: "design.json",
21501
- front: "front.png",
21502
- ...sticker ? {} : { back: "back.png" },
21503
- portrait: draft.portrait,
21504
- artwork: draft.artwork,
21505
- assets: draft.assets
21506
- },
21507
- {
21508
- ...draft.files,
21509
- "design.json": jsonBytes({
21510
- design: draft.design,
21511
- ...!sticker && draft.participant ? { participant: draft.participant } : {}
21512
- }),
21513
- "front.png": previews.front,
21514
- ...!sticker && previews.back ? { "back.png": previews.back } : {}
21515
- },
21516
- {
21517
- ...draft.mime,
21518
- "design.json": "application/json",
21519
- "front.png": "image/png",
21520
- ...sticker ? {} : { "back.png": "image/png" }
21521
- }
21522
- );
21523
- }
21524
- async function svgPackage(bytes, title = "Untitled card") {
21525
- const check = checkSubmittedSvg(new TextDecoder().decode(bytes));
21526
- if (!check.ok) throw new Error(check.error);
21527
- return assemblePackage(
21528
- { product: "card", title, source: "artwork.svg", front: "artwork.svg", assets: {} },
21529
- { "artwork.svg": bytes },
21530
- { "artwork.svg": "image/svg+xml" }
21531
- );
21532
- }
21533
- async function validatePackage(pkg) {
21534
- const manifest = manifestSchema.parse(pkg.manifest);
21535
- if (jsonBytes(manifest).length > MANIFEST_LIMIT)
21536
- throw new Error("The package manifest exceeds 200 KB.");
21537
- if (Object.keys(pkg.files).length !== manifest.files.length)
21538
- throw new Error("The package file list does not match its manifest.");
21539
- for (const file of manifest.files) {
21540
- const bytes = pkg.files[file.path];
21541
- if (!bytes || bytes.length !== file.bytes || await hashBytes(bytes) !== file.sha256)
21542
- throw new Error(`Missing or changed asset: ${file.path}.`);
21543
- }
21544
- if (manifest.product === "kit") {
21545
- for (const item of manifest.items) await validatePackage(kitMemberPackage(pkg, item.id));
21546
- for (const sheet of manifest.sheets) {
21547
- const document2 = stickerSheetSchema.parse(parseJson(pkg.files[sheet.document]));
21548
- if (!document2.items.length) throw new Error("A kit sheet must contain stickers.");
21549
- for (const item of document2.items)
21550
- if (requiredAssets(item.design).assets.length || requiredAssets(item.design).artwork)
21551
- throw new Error("Kit sheets must embed their artwork.");
21552
- if (sheet.pdf) {
21553
- const text4 = new TextDecoder("latin1").decode(pkg.files[sheet.pdf]);
21554
- if (!text4.startsWith("%PDF-") || !text4.trimEnd().endsWith("%%EOF"))
21555
- throw new Error("Invalid print PDF.");
21556
- }
21557
- }
21558
- return manifest;
21559
- }
21560
- for (const file of manifest.files.filter((f) => f.mime === "image/svg+xml")) {
21561
- const check = checkSubmittedSvg(new TextDecoder().decode(pkg.files[file.path]));
21562
- if (!check.ok) throw new Error(check.error);
21563
- }
21564
- if (manifest.document) {
21565
- const document2 = documentSchema.parse(parseJson(pkg.files[manifest.document]));
21566
- if ((document2.design.product ?? "badge") !== manifest.product)
21567
- throw new Error("The document and product do not match.");
21568
- if (manifest.product === "sticker" && manifest.finish !== (document2.design.sticker?.finish ?? defaultStickerMaterial.finish))
21569
- throw new Error("The sticker finish and document do not match.");
21570
- if (manifest.product === "sticker" && document2.participant)
21571
- throw new Error("Sticker packages must not contain participant information.");
21572
- const missing = missingAssets({ ...document2, ...manifest, files: pkg.files, mime: {} });
21573
- if (missing.length) throw new Error(`Missing images: ${missing.join(", ")}.`);
21574
- if (requiredAssets(document2.design).portrait && !document2.participant)
21575
- throw new Error(
21576
- "Include participant details with a personalized badge. Export a package from the editor."
21577
- );
21578
- }
21579
- return manifest;
21580
- }
21581
- function checkArchive(bytes) {
21582
- if (bytes.length > PACKAGE_LIMIT + MANIFEST_LIMIT) throw new Error("The ZIP exceeds 24 MB.");
21583
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
21584
- if (bytes.length < 22) throw new Error("Invalid ZIP archive.");
21585
- let end = bytes.length - 22;
21586
- while (end >= Math.max(0, bytes.length - 65557) && view.getUint32(end, true) !== 101010256)
21587
- end--;
21588
- if (end < 0 || end < bytes.length - 65557) throw new Error("Invalid ZIP directory.");
21589
- const count = view.getUint16(end + 10, true);
21590
- if (count > KIT_FILE_COUNT_LIMIT + 1 || view.getUint16(end + 4, true) || view.getUint16(end + 6, true))
21591
- throw new Error("Unsupported ZIP archive.");
21592
- let offset = view.getUint32(end + 16, true), total = 0;
21593
- const names = /* @__PURE__ */ new Set();
21594
- for (let index = 0; index < count; index++) {
21595
- if (offset + 46 > end || view.getUint32(offset, true) !== 33639248)
21596
- throw new Error("Invalid ZIP entry.");
21597
- const flags = view.getUint16(offset + 8, true), size = view.getUint32(offset + 24, true), length = view.getUint16(offset + 28, true);
21598
- const name = new TextDecoder().decode(bytes.subarray(offset + 46, offset + 46 + length));
21599
- if (flags & 1 || names.has(name) || name !== "manifest.json" && !archivePathSchema.safeParse(name).success || size > (name === "manifest.json" ? MANIFEST_LIMIT : FILE_LIMIT))
21600
- throw new Error("Unsafe, duplicate or oversized ZIP entry.");
21601
- total += size;
21602
- if (total > PACKAGE_LIMIT + MANIFEST_LIMIT) throw new Error("The expanded ZIP exceeds 24 MB.");
21603
- names.add(name);
21604
- offset += 46 + length + view.getUint16(offset + 30, true) + view.getUint16(offset + 32, true);
21605
- }
21606
- if (offset !== end || !names.has("manifest.json"))
21607
- throw new Error("Use a Makeables ZIP with manifest.json at its root.");
21608
- return names;
21609
- }
21610
- async function readPackageZip(bytes) {
21611
- const names = checkArchive(bytes);
21612
- const files = {};
21613
- const seen = /* @__PURE__ */ new Set();
21614
- let total = 0;
21615
- const archive2 = new Unzip((file) => {
21616
- if (!names.has(file.name) || seen.has(file.name) || (file.originalSize ?? 0) > FILE_LIMIT)
21617
- throw new Error("Invalid ZIP entry.");
21618
- seen.add(file.name);
21619
- const chunks = [];
21620
- let size = 0;
21621
- file.ondata = (error, chunk, final) => {
21622
- if (error) throw error;
21623
- size += chunk.length;
21624
- total += chunk.length;
21625
- if (size > (file.name === "manifest.json" ? MANIFEST_LIMIT : FILE_LIMIT) || total > PACKAGE_LIMIT + MANIFEST_LIMIT) {
21626
- file.terminate();
21627
- throw new Error("The expanded ZIP exceeds its size limit.");
21628
- }
21629
- chunks.push(chunk);
21630
- if (final) {
21631
- const data = new Uint8Array(size);
21632
- let offset = 0;
21633
- for (const part of chunks) {
21634
- data.set(part, offset);
21635
- offset += part.length;
21636
- }
21637
- files[file.name] = data;
21638
- }
21639
- };
21640
- file.start();
21641
- });
21642
- archive2.register(UnzipInflate);
21643
- for (let offset = 0; offset < bytes.length; offset += 1024)
21644
- archive2.push(bytes.subarray(offset, offset + 1024), offset + 1024 >= bytes.length);
21645
- if (Object.keys(files).length !== names.size) throw new Error("Incomplete ZIP archive.");
21646
- const manifest = manifestSchema.parse(parseJson(files["manifest.json"]));
21647
- delete files["manifest.json"];
21648
- const pkg = { manifest, files };
21649
- await validatePackage(pkg);
21650
- return pkg;
21651
- }
21652
- async function packageZip(pkg) {
21653
- await validatePackage(pkg);
21654
- return zipSync({ "manifest.json": jsonBytes(pkg.manifest), ...pkg.files }, { level: 0 });
21655
- }
21656
- function draftFromPackage(pkg) {
21657
- if (pkg.manifest.product === "kit")
21658
- throw new Error("Choose a kit member before opening its design.");
21659
- if (!pkg.manifest.document)
21660
- throw new Error("This package contains an original SVG, not a layered document.");
21661
- const doc = documentSchema.parse(parseJson(pkg.files[pkg.manifest.document]));
21662
- const paths = /* @__PURE__ */ new Set([
21663
- pkg.manifest.portrait,
21664
- pkg.manifest.artwork,
21665
- ...Object.values(pkg.manifest.assets)
21666
- ]);
21667
- return {
21668
- ...doc,
21669
- portrait: pkg.manifest.portrait,
21670
- artwork: pkg.manifest.artwork,
21671
- assets: pkg.manifest.assets,
21672
- files: Object.fromEntries(Object.entries(pkg.files).filter(([path2]) => paths.has(path2))),
21673
- mime: Object.fromEntries(
21674
- pkg.manifest.files.filter((f) => paths.has(f.path)).map((f) => [f.path, f.mime])
21675
- )
21676
- };
21677
- }
21678
- function packageJson(pkg) {
21679
- return {
21680
- format: "makeables-package",
21681
- version: 1,
21682
- manifest: pkg.manifest,
21683
- files: Object.fromEntries(
21684
- Object.entries(pkg.files).map(([path2, bytes]) => {
21685
- let binary = "";
21686
- for (const byte of bytes) binary += String.fromCharCode(byte);
21687
- return [path2, btoa(binary)];
21688
- })
21689
- )
21690
- };
21691
- }
21692
- async function readPackageJson(value) {
21693
- const input = z23.object({
21694
- format: z23.literal("makeables-package"),
21695
- version: z23.literal(1),
21696
- manifest: manifestSchema,
21697
- files: z23.record(
21698
- archivePathSchema,
21699
- z23.string().max(Math.ceil(FILE_LIMIT / 3) * 4).regex(/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/)
21700
- )
21701
- }).strict().parse(value);
21702
- if (Object.keys(input.files).length !== input.manifest.files.length)
21703
- throw new Error("The package file list does not match its manifest.");
21704
- for (const file of input.manifest.files) {
21705
- const encoded = input.files[file.path];
21706
- const length = encoded ? encoded.length / 4 * 3 - (encoded.endsWith("==") ? 2 : encoded.endsWith("=") ? 1 : 0) : 0;
21707
- if (length !== file.bytes) throw new Error(`Missing or changed asset: ${file.path}.`);
21708
- }
21709
- const files = Object.fromEntries(
21710
- Object.entries(input.files).map(([path2, base64]) => [
21711
- path2,
21712
- Uint8Array.from(atob(base64), (c) => c.charCodeAt(0))
21713
- ])
21714
- );
21715
- const pkg = { manifest: input.manifest, files };
21716
- await validatePackage(pkg);
21717
- return pkg;
21718
- }
21719
- function kitMemberPackage(pkg, id22) {
21720
- if (pkg.manifest.product !== "kit") throw new Error("This package is not a kit.");
21721
- const item = pkg.manifest.items.find((item2) => item2.id === id22);
21722
- if (!item) throw new Error("Unknown kit piece.");
21723
- return {
21724
- manifest: item.manifest,
21725
- files: Object.fromEntries(
21726
- item.manifest.files.map((file) => [file.path, pkg.files[`items/${id22}/${file.path}`]])
21727
- )
21728
- };
21729
- }
21730
-
21731
- // src/errors.ts
21732
- var InputError = class extends Error {
18659
+ // src/errors.ts
18660
+ var InputError = class extends Error {
21733
18661
  };
21734
18662
 
21735
18663
  // src/card.ts
@@ -21864,7 +18792,7 @@ function designSvgImages(design2, onlySide, masks = true) {
21864
18792
  var cardMarkImageId = (layerId) => `mark:${layerId}`;
21865
18793
 
21866
18794
  // ../renderer/src/andes.ts
21867
- import QRCode2 from "qrcode";
18795
+ import QRCode from "qrcode";
21868
18796
  function terrain(ctx, seed, top, height) {
21869
18797
  ctx.save();
21870
18798
  ctx.beginPath();
@@ -21909,7 +18837,7 @@ function contourSeal(ctx, seed, x, y) {
21909
18837
  }
21910
18838
 
21911
18839
  // ../renderer/src/edition.ts
21912
- import QRCode3 from "qrcode";
18840
+ import QRCode2 from "qrcode";
21913
18841
 
21914
18842
  // ../renderer/src/signature.ts
21915
18843
  function materialSignature(signature = { seed: 0, version: 1 }) {
@@ -22255,15 +19183,15 @@ function paintDesignGraphic(ctx, layer) {
22255
19183
  }
22256
19184
  return;
22257
19185
  }
22258
- const { w, h, color: color3, accent, density, seed, pattern } = layer;
22259
- ctx.fillStyle = color3;
19186
+ const { w, h, color, accent, density, seed, pattern } = layer;
19187
+ ctx.fillStyle = color;
22260
19188
  ctx.strokeStyle = accent;
22261
19189
  ctx.lineWidth = layer.stroke ?? 2;
22262
19190
  if (pattern === "checkerboard") {
22263
19191
  const size = 20 / density;
22264
19192
  for (let row = 0; row < h / size; row++)
22265
19193
  for (let col = 0; col < w / size; col++) {
22266
- ctx.fillStyle = (row + col) % 2 ? accent : color3;
19194
+ ctx.fillStyle = (row + col) % 2 ? accent : color;
22267
19195
  ctx.fillRect(col * size, row * size, size, size);
22268
19196
  }
22269
19197
  } else if (pattern === "path") {
@@ -22278,7 +19206,7 @@ function paintDesignGraphic(ctx, layer) {
22278
19206
  ctx.fillRect(0, 0, w - 4, h - 4);
22279
19207
  ctx.fillStyle = "#808080";
22280
19208
  ctx.fillRect(4, 4, w - 4, h - 4);
22281
- ctx.fillStyle = color3;
19209
+ ctx.fillStyle = color;
22282
19210
  ctx.fillRect(4, 4, w - 9, h - 9);
22283
19211
  ctx.fillStyle = accent;
22284
19212
  ctx.fillRect(8, 8, w - 19, 50);
@@ -22347,7 +19275,7 @@ function paintDesignGraphic(ctx, layer) {
22347
19275
  layout: layer.variant === "plain" ? "archive" : layer.variant === "technical" ? "signal" : layer.variant === "editorial" ? "editorial" : layer.variant === "postal" ? "postage" : "terminal",
22348
19276
  title: [],
22349
19277
  subtitle: "",
22350
- base: color3,
19278
+ base: color,
22351
19279
  ink: layer.ink ?? accent,
22352
19280
  accent,
22353
19281
  motif: pattern === "snow" || layer.variant === "snow" ? "snow" : layer.variant === "waves" ? "waves" : "grid",
@@ -22408,8 +19336,8 @@ function filterPixels(pixels, filter) {
22408
19336
  }
22409
19337
  const spread = Math.max(64, high - low);
22410
19338
  for (let i = 0; i < pixels.length; i += 4) {
22411
- const luminance2 = pixels[i] * 0.45 + pixels[i + 1] * 0.45 + pixels[i + 2] * 0.1;
22412
- const value = Math.max(0, Math.min(1, (luminance2 - low) / spread));
19339
+ const luminance = pixels[i] * 0.45 + pixels[i + 1] * 0.45 + pixels[i + 2] * 0.1;
19340
+ const value = Math.max(0, Math.min(1, (luminance - low) / spread));
22413
19341
  if (filter === "thermal") {
22414
19342
  palette(value ** 0.72, thermal, pixels, i);
22415
19343
  } else if (filter === "cyanotype") {
@@ -22420,33 +19348,33 @@ function filterPixels(pixels, filter) {
22420
19348
  pixels[i + 1] = silver * 0.99;
22421
19349
  pixels[i + 2] = silver * 1.03;
22422
19350
  } else if (filter === "vintage") {
22423
- pixels[i] = 24 + pixels[i] * 0.74 + luminance2 * 0.14;
22424
- pixels[i + 1] = 20 + pixels[i + 1] * 0.69 + luminance2 * 0.12;
22425
- pixels[i + 2] = 22 + pixels[i + 2] * 0.57 + luminance2 * 0.09;
19351
+ pixels[i] = 24 + pixels[i] * 0.74 + luminance * 0.14;
19352
+ pixels[i + 1] = 20 + pixels[i + 1] * 0.69 + luminance * 0.12;
19353
+ pixels[i + 2] = 22 + pixels[i + 2] * 0.57 + luminance * 0.09;
22426
19354
  }
22427
19355
  }
22428
19356
  }
22429
19357
 
22430
19358
  // ../renderer/src/design-photo.ts
22431
- function containDesignImage(ctx, image2, w, h, pixelated = false) {
22432
- const scale = Math.min(w / image2.width, h / image2.height);
22433
- const dw = image2.width * scale;
22434
- const dh = image2.height * scale;
19359
+ function containDesignImage(ctx, image, w, h, pixelated = false) {
19360
+ const scale = Math.min(w / image.width, h / image.height);
19361
+ const dw = image.width * scale;
19362
+ const dh = image.height * scale;
22435
19363
  ctx.save();
22436
19364
  ctx.imageSmoothingEnabled = !pixelated;
22437
- ctx.drawImage(image2, (w - dw) / 2, (h - dh) / 2, dw, dh);
19365
+ ctx.drawImage(image, (w - dw) / 2, (h - dh) / 2, dw, dh);
22438
19366
  ctx.restore();
22439
19367
  }
22440
- function coverDesignImage(ctx, image2, w, h, layer) {
19368
+ function coverDesignImage(ctx, image, w, h, layer) {
22441
19369
  const crop = layer?.crop;
22442
- const scale = Math.max(w / image2.width, h / image2.height) * (crop?.zoom ?? 1);
19370
+ const scale = Math.max(w / image.width, h / image.height) * (crop?.zoom ?? 1);
22443
19371
  const cw = w / scale;
22444
19372
  const ch = h / scale;
22445
- const x = layer?.cropMode === "focus" ? Math.max(0, Math.min(image2.width - cw, image2.width * (crop?.x ?? 0.5) - cw / 2)) : (image2.width - cw) * (crop?.x ?? 0.5);
22446
- const y = layer?.cropMode === "focus" ? Math.max(0, Math.min(image2.height - ch, image2.height * (crop?.y ?? 0.5) - ch / 2)) : (image2.height - ch) * (crop?.y ?? 0.5);
22447
- ctx.drawImage(image2, x, y, cw, ch, 0, 0, w, h);
19373
+ const x = layer?.cropMode === "focus" ? Math.max(0, Math.min(image.width - cw, image.width * (crop?.x ?? 0.5) - cw / 2)) : (image.width - cw) * (crop?.x ?? 0.5);
19374
+ const y = layer?.cropMode === "focus" ? Math.max(0, Math.min(image.height - ch, image.height * (crop?.y ?? 0.5) - ch / 2)) : (image.height - ch) * (crop?.y ?? 0.5);
19375
+ ctx.drawImage(image, x, y, cw, ch, 0, 0, w, h);
22448
19376
  }
22449
- function paintDesignPhoto(ctx, layer, image2) {
19377
+ function paintDesignPhoto(ctx, layer, image) {
22450
19378
  const photo = document.createElement("canvas");
22451
19379
  photo.width = Math.ceil(layer.w);
22452
19380
  photo.height = Math.ceil(layer.h);
@@ -22462,7 +19390,7 @@ function paintDesignPhoto(ctx, layer, image2) {
22462
19390
  if (layer.brightness !== void 0) filters.push(`brightness(${layer.brightness})`);
22463
19391
  if (layer.blur) filters.push(`blur(${layer.blur}px)`);
22464
19392
  surface.filter = filters.join(" ");
22465
- coverDesignImage(surface, image2, layer.w, layer.h, layer);
19393
+ coverDesignImage(surface, image, layer.w, layer.h, layer);
22466
19394
  surface.filter = "none";
22467
19395
  if (["thermal", "silver", "cyanotype", "vintage"].includes(layer.filter)) {
22468
19396
  const pixels = surface.getImageData(0, 0, photo.width, photo.height);
@@ -22495,17 +19423,17 @@ function paintDesignPhoto(ctx, layer, image2) {
22495
19423
  for (const horizontal of [true, false]) {
22496
19424
  const start = horizontal ? layer.fade.x : layer.fade.top;
22497
19425
  const end = horizontal ? layer.fade.right ?? layer.fade.x : layer.fade.bottom;
22498
- const gradient3 = surface.createLinearGradient(
19426
+ const gradient2 = surface.createLinearGradient(
22499
19427
  0,
22500
19428
  0,
22501
19429
  horizontal ? layer.w : 0,
22502
19430
  horizontal ? 0 : layer.h
22503
19431
  );
22504
- gradient3.addColorStop(0, start ? "#00000000" : "#000000");
22505
- gradient3.addColorStop(start, "#000000");
22506
- gradient3.addColorStop(1 - end, "#000000");
22507
- gradient3.addColorStop(1, end ? "#00000000" : "#000000");
22508
- surface.fillStyle = gradient3;
19432
+ gradient2.addColorStop(0, start ? "#00000000" : "#000000");
19433
+ gradient2.addColorStop(start, "#000000");
19434
+ gradient2.addColorStop(1 - end, "#000000");
19435
+ gradient2.addColorStop(1, end ? "#00000000" : "#000000");
19436
+ surface.fillStyle = gradient2;
22509
19437
  surface.fillRect(0, 0, layer.w, layer.h);
22510
19438
  }
22511
19439
  }
@@ -22592,9 +19520,15 @@ function paintDesignText(ctx, layer, data) {
22592
19520
  let wrapped;
22593
19521
  if (layer.fit === "shrink" || layer.fit === "spread") {
22594
19522
  wrapped = value.split("\n");
22595
- const measured = Math.max(...wrapped.map((line2) => ctx.measureText(line2).width), 1);
19523
+ const tracking = layer.tracking ?? 0;
19524
+ const widest = wrapped.reduce(
19525
+ (a, b) => ctx.measureText(b).width > ctx.measureText(a).width ? b : a,
19526
+ ""
19527
+ );
19528
+ const measured = Math.max(ctx.measureText(widest).width, 1);
22596
19529
  if (measured > width) {
22597
- size *= width / measured;
19530
+ const spacing = tracking * [...widest].length;
19531
+ size *= Math.max(0.05, (width - spacing) / Math.max(1, measured - spacing));
22598
19532
  font();
22599
19533
  }
22600
19534
  } else {
@@ -22656,7 +19590,7 @@ function plate(width = 1024, height = 1536) {
22656
19590
  if (!ctx) throw new Error("No se pudo preparar el dise\xF1o.");
22657
19591
  return { canvas: canvas2, ctx };
22658
19592
  }
22659
- function effect3(ctx, layer) {
19593
+ function effect2(ctx, layer) {
22660
19594
  const { w, h, colors, scale } = layer;
22661
19595
  if (layer.effect === "chromatic-flow") {
22662
19596
  const tile = document.createElement("canvas");
@@ -22684,11 +19618,11 @@ function effect3(ctx, layer) {
22684
19618
  ctx.drawImage(tile, 0, 0, w, h);
22685
19619
  return;
22686
19620
  }
22687
- const gradient3 = ctx.createLinearGradient(0, h, w, 0);
19621
+ const gradient2 = ctx.createLinearGradient(0, h, w, 0);
22688
19622
  colors.forEach((c, i) => {
22689
- gradient3.addColorStop(i / 2, c);
19623
+ gradient2.addColorStop(i / 2, c);
22690
19624
  });
22691
- ctx.fillStyle = gradient3;
19625
+ ctx.fillStyle = gradient2;
22692
19626
  ctx.fillRect(0, 0, w, h);
22693
19627
  ctx.strokeStyle = colors[2];
22694
19628
  ctx.lineWidth = 1.5;
@@ -22724,7 +19658,7 @@ function effect3(ctx, layer) {
22724
19658
  ctx.stroke();
22725
19659
  }
22726
19660
  }
22727
- function paint(ctx, input, data, portrait2, images) {
19661
+ function paint(ctx, input, data, portrait, images) {
22728
19662
  let layer = input;
22729
19663
  ctx.save();
22730
19664
  ctx.translate(layer.x, layer.y);
@@ -22749,7 +19683,7 @@ function paint(ctx, input, data, portrait2, images) {
22749
19683
  ctx.clip();
22750
19684
  ctx.globalAlpha = layer.opacity ?? 1;
22751
19685
  if (layer.kind === "text") paintDesignText(ctx, layer, data);
22752
- else if (layer.kind === "effect") effect3(ctx, layer);
19686
+ else if (layer.kind === "effect") effect2(ctx, layer);
22753
19687
  else if (layer.kind === "graphic") paintDesignGraphic(ctx, layer);
22754
19688
  else if (layer.kind === "shape") {
22755
19689
  const inset = layer.shape === "frame" ? layer.stroke / 2 : 0;
@@ -22815,7 +19749,7 @@ function paint(ctx, input, data, portrait2, images) {
22815
19749
  for (let c = 0; c < matrix.size; c++)
22816
19750
  if (matrix.get(r, c)) ctx.fillRect(offset + c * cell, offset + r * cell, cell, cell);
22817
19751
  } else if (layer.kind === "gradient") {
22818
- const gradient3 = layer.direction === "radial" ? ctx.createRadialGradient(
19752
+ const gradient2 = layer.direction === "radial" ? ctx.createRadialGradient(
22819
19753
  layer.w / 2,
22820
19754
  layer.h / 2,
22821
19755
  0,
@@ -22828,29 +19762,29 @@ function paint(ctx, input, data, portrait2, images) {
22828
19762
  layer.direction === "vertical" ? 0 : layer.w,
22829
19763
  layer.direction === "horizontal" ? 0 : layer.h
22830
19764
  );
22831
- for (const stop of layer.stops) gradient3.addColorStop(stop.at, stop.color);
22832
- ctx.fillStyle = gradient3;
19765
+ for (const stop of layer.stops) gradient2.addColorStop(stop.at, stop.color);
19766
+ ctx.fillStyle = gradient2;
22833
19767
  ctx.fillRect(0, 0, layer.w, layer.h);
22834
- } else if (layer.kind === "portrait" && portrait2) paintDesignPhoto(ctx, layer, portrait2);
19768
+ } else if (layer.kind === "portrait" && portrait) paintDesignPhoto(ctx, layer, portrait);
22835
19769
  else if (layer.kind === "card-mark") {
22836
- const image2 = images?.get(cardMarkImageId(layer.id));
22837
- if (image2) ctx.drawImage(image2, 0, 0, layer.w, layer.h);
19770
+ const image = images?.get(cardMarkImageId(layer.id));
19771
+ if (image) ctx.drawImage(image, 0, 0, layer.w, layer.h);
22838
19772
  } else if (layer.kind === "image") {
22839
- const image2 = images?.get(layer.asset);
19773
+ const image = images?.get(layer.asset);
22840
19774
  const pixelated = data.document?.assets?.[layer.asset];
22841
- if (image2 && layer.fit === "contain")
19775
+ if (image && layer.fit === "contain")
22842
19776
  containDesignImage(
22843
19777
  ctx,
22844
- image2,
19778
+ image,
22845
19779
  layer.w,
22846
19780
  layer.h,
22847
19781
  pixelated?.source === "petdex" || pixelated?.source === "image" && pixelated.pixelated
22848
19782
  );
22849
- else if (image2) coverDesignImage(ctx, image2, layer.w, layer.h);
19783
+ else if (image) coverDesignImage(ctx, image, layer.w, layer.h);
22850
19784
  }
22851
19785
  ctx.restore();
22852
19786
  }
22853
- function createDesignFace(data, side2, portrait2, images, channel) {
19787
+ function createDesignFace(data, side2, portrait, images, channel) {
22854
19788
  const design2 = data.document;
22855
19789
  if (!design2) throw new Error("Falta el documento del dise\xF1o.");
22856
19790
  const { width, height } = designProfile(design2);
@@ -22864,14 +19798,14 @@ function createDesignFace(data, side2, portrait2, images, channel) {
22864
19798
  for (const layer of design2[side2].layers) {
22865
19799
  if (layer.kind === "svg") {
22866
19800
  const run = firstInRun.get(layer.id);
22867
- const image2 = run ? images?.get(run.id) : void 0;
22868
- if (image2 && (!channel || channel === run?.channel))
22869
- ctx.drawImage(image2, 0, 0, width, height);
19801
+ const image = run ? images?.get(run.id) : void 0;
19802
+ if (image && (!channel || channel === run?.channel))
19803
+ ctx.drawImage(image, 0, 0, width, height);
22870
19804
  continue;
22871
19805
  }
22872
19806
  if (layer.visible === false) continue;
22873
19807
  const layerChannel = layer.channel ?? (["text", "qr"].includes(layer.kind) ? "ink" : "print");
22874
- if (!channel || channel === layerChannel) paint(ctx, layer, data, portrait2, images);
19808
+ if (!channel || channel === layerChannel) paint(ctx, layer, data, portrait, images);
22875
19809
  }
22876
19810
  return canvas2;
22877
19811
  }
@@ -23191,7 +20125,7 @@ function measureStickerOutline(pixels, width, height) {
23191
20125
  }
23192
20126
 
23193
20127
  // ../renderer/src/sticker.ts
23194
- var clamp = (value, min = 0, max2 = 1) => Math.min(max2, Math.max(min, value));
20128
+ var clamp = (value, min = 0, max = 1) => Math.min(max, Math.max(min, value));
23195
20129
  function hash(value) {
23196
20130
  let n = value | 0;
23197
20131
  n = Math.imul(n ^ n >>> 16, 73244475);
@@ -23343,7 +20277,7 @@ function prepareSticker(art, material, optical) {
23343
20277
  coat.clearRect(0, 0, width, height);
23344
20278
  coat.globalCompositeOperation = "source-over";
23345
20279
  const shift = light.x * width * 0.38 + light.y * width * 0.14;
23346
- const gradient3 = coat.createLinearGradient(
20280
+ const gradient2 = coat.createLinearGradient(
23347
20281
  shift - width * 0.3,
23348
20282
  0,
23349
20283
  shift + width * 1.1,
@@ -23351,11 +20285,11 @@ function prepareSticker(art, material, optical) {
23351
20285
  );
23352
20286
  if (holography > 0) {
23353
20287
  ["#edb2ef", "#aba5ef", "#96daea", "#d6efb0", "#ffe8bb", "#eab7e4", "#a3c6ed"].forEach(
23354
- (color3, i) => {
23355
- gradient3.addColorStop(i / 6, color3);
20288
+ (color, i) => {
20289
+ gradient2.addColorStop(i / 6, color);
23356
20290
  }
23357
20291
  );
23358
- coat.fillStyle = gradient3;
20292
+ coat.fillStyle = gradient2;
23359
20293
  coat.globalAlpha = authored ? holography * 0.3 : finish === "holographic" ? 0.3 : 0.12;
23360
20294
  coat.fillRect(0, 0, width, height);
23361
20295
  if (foilMask) {
@@ -23512,19 +20446,19 @@ function effectiveRasterWidth(design2, dimensions) {
23512
20446
  }
23513
20447
 
23514
20448
  // ../renderer/src/sheet-layout.ts
23515
- function placedOutline(shape2, item, holes = false) {
20449
+ function placedOutline(shape, item, holes = false) {
23516
20450
  const angle = item.rotation * Math.PI / 180;
23517
20451
  const cos = Math.cos(angle);
23518
20452
  const sin = Math.sin(angle);
23519
- return shape2.paths.filter((path2) => holes || !path2.hole).map(
20453
+ return shape.paths.filter((path2) => holes || !path2.hole).map(
23520
20454
  (path2) => path2.points.map(([px, py]) => {
23521
- const dx = px - shape2.widthMm / 2;
23522
- const dy = py - shape2.heightMm / 2;
20455
+ const dx = px - shape.widthMm / 2;
20456
+ const dy = py - shape.heightMm / 2;
23523
20457
  return [item.x + dx * cos - dy * sin, item.y + dx * sin + dy * cos];
23524
20458
  })
23525
20459
  );
23526
20460
  }
23527
- function box2(loops) {
20461
+ function box(loops) {
23528
20462
  let minX = Infinity;
23529
20463
  let minY = Infinity;
23530
20464
  let maxX = -Infinity;
@@ -23578,7 +20512,7 @@ function outlineDistance(a, b) {
23578
20512
  }
23579
20513
  function sheetViolations(spec, bounds, items) {
23580
20514
  const violations = [];
23581
- const boxes = items.map((item) => box2(item.outline));
20515
+ const boxes = items.map((item) => box(item.outline));
23582
20516
  for (const [index, item] of items.entries()) {
23583
20517
  const b = boxes[index];
23584
20518
  const m = spec.marginMm;
@@ -23634,7 +20568,7 @@ function rasterize(loops, columns, rows, originX, originY) {
23634
20568
  return mask;
23635
20569
  }
23636
20570
  function footprint(outline) {
23637
- const b = box2(outline);
20571
+ const b = box(outline);
23638
20572
  const columns = Math.ceil((b.maxX - b.minX) / cellMm) + 1;
23639
20573
  const rows = Math.ceil((b.maxY - b.minY) / cellMm) + 1;
23640
20574
  const mask = rasterize(outline, columns, rows, b.minX, b.minY);
@@ -23691,9 +20625,9 @@ var Occupancy = class {
23691
20625
  return [column * cellMm - print.offsetX, row * cellMm - print.offsetY];
23692
20626
  }
23693
20627
  };
23694
- function area(shape2) {
20628
+ function area(shape) {
23695
20629
  let total = 0;
23696
- for (const path2 of shape2.paths)
20630
+ for (const path2 of shape.paths)
23697
20631
  for (let i = 0; i < path2.points.length; i++) {
23698
20632
  const [ax, ay] = path2.points[i];
23699
20633
  const [bx, by] = path2.points[(i + 1) % path2.points.length];
@@ -23701,23 +20635,23 @@ function area(shape2) {
23701
20635
  }
23702
20636
  return Math.abs(total);
23703
20637
  }
23704
- function placeOne(occupancy, { item, shape: shape2 }, target, rotations) {
20638
+ function placeOne(occupancy, { item, shape }, target, rotations) {
23705
20639
  for (const rotation of rotations) {
23706
- const at = occupancy.nearest(footprint(placedOutline(shape2, { x: 0, y: 0, rotation })), target);
20640
+ const at = occupancy.nearest(footprint(placedOutline(shape, { x: 0, y: 0, rotation })), target);
23707
20641
  if (at) return { ...item, x: at[0], y: at[1], rotation };
23708
20642
  }
23709
20643
  }
23710
- function packSheet(spec, bounds, inputs2, hero) {
20644
+ function packSheet(spec, bounds, inputs, hero) {
23711
20645
  const occupancy = new Occupancy(bounds, spec);
23712
20646
  const placed = /* @__PURE__ */ new Map();
23713
- const anchor = inputs2.find((input) => input.item.id === hero);
20647
+ const anchor = inputs.find((input) => input.item.id === hero);
23714
20648
  let target = [bounds.widthMm / 2, bounds.heightMm / 2];
23715
20649
  if (anchor) {
23716
20650
  occupancy.add(placedOutline(anchor.shape, anchor.item));
23717
20651
  placed.set(anchor.item.id, anchor.item);
23718
20652
  target = [anchor.item.x, anchor.item.y];
23719
20653
  }
23720
- const rest = inputs2.filter((input) => input !== anchor).sort((a, b) => area(b.shape) - area(a.shape));
20654
+ const rest = inputs.filter((input) => input !== anchor).sort((a, b) => area(b.shape) - area(a.shape));
23721
20655
  const missing = [];
23722
20656
  for (const input of rest) {
23723
20657
  const rotations = [
@@ -23732,15 +20666,15 @@ function packSheet(spec, bounds, inputs2, hero) {
23732
20666
  placed.set(item.id, item);
23733
20667
  }
23734
20668
  return {
23735
- items: inputs2.map((input) => placed.get(input.item.id) ?? input.item),
20669
+ items: inputs.map((input) => placed.get(input.item.id) ?? input.item),
23736
20670
  missing
23737
20671
  };
23738
20672
  }
23739
- function placeNear(spec, bounds, inputs2, id3, target) {
20673
+ function placeNear(spec, bounds, inputs, id, target) {
23740
20674
  const occupancy = new Occupancy(bounds, spec);
23741
- for (const input of inputs2)
23742
- if (input.item.id !== id3) occupancy.add(placedOutline(input.shape, input.item));
23743
- const moving = inputs2.find((input) => input.item.id === id3);
20675
+ for (const input of inputs)
20676
+ if (input.item.id !== id) occupancy.add(placedOutline(input.shape, input.item));
20677
+ const moving = inputs.find((input) => input.item.id === id);
23744
20678
  if (!moving) return;
23745
20679
  return placeOne(occupancy, moving, target, [moving.item.rotation]);
23746
20680
  }
@@ -23833,7 +20767,7 @@ function placement(item, heightMm) {
23833
20767
  ].map(number).join(" ");
23834
20768
  }
23835
20769
  async function sheetPdf(input) {
23836
- const encoder2 = new TextEncoder();
20770
+ const encoder = new TextEncoder();
23837
20771
  const objects = [];
23838
20772
  const add = (...parts) => {
23839
20773
  objects.push(parts);
@@ -23896,17 +20830,17 @@ S`),
23896
20830
  "Q EMC"
23897
20831
  ].join("\n");
23898
20832
  const contents = add(
23899
- ...stream("/Filter /FlateDecode", await input.deflate(encoder2.encode(content)))
20833
+ ...stream("/Filter /FlateDecode", await input.deflate(encoder.encode(content)))
23900
20834
  );
23901
20835
  const W = number(input.widthMm * points);
23902
20836
  const Hp = number(H * points);
23903
- const box3 = `[0 0 ${W} ${Hp}]`;
23904
- const xobjects = images.map((id3, i) => `/Im${i} ${id3} 0 R`).join(" ");
20837
+ const box2 = `[0 0 ${W} ${Hp}]`;
20838
+ const xobjects = images.map((id, i) => `/Im${i} ${id} 0 R`).join(" ");
23905
20839
  objects[page - 1] = [
23906
- `<< /Type /Page /Parent ${pages} 0 R /MediaBox ${box3} /TrimBox ${box3} /BleedBox ${box3} /Resources << /XObject << ${xobjects} >> /ExtGState << /GSop ${overprint} 0 R >> /ColorSpace << /CSc ${cutSpace} 0 R${white ? ` /CSw ${whiteSpace} 0 R` : ""} >> /Properties << /oArt ${ocArt} 0 R /oCut ${ocCut} 0 R${white ? ` /oWhite ${ocWhite} 0 R` : ""} >> >> /Contents ${contents} 0 R >>`
20840
+ `<< /Type /Page /Parent ${pages} 0 R /MediaBox ${box2} /TrimBox ${box2} /BleedBox ${box2} /Resources << /XObject << ${xobjects} >> /ExtGState << /GSop ${overprint} 0 R >> /ColorSpace << /CSc ${cutSpace} 0 R${white ? ` /CSw ${whiteSpace} 0 R` : ""} >> /Properties << /oArt ${ocArt} 0 R /oCut ${ocCut} 0 R${white ? ` /oWhite ${ocWhite} 0 R` : ""} >> >> /Contents ${contents} 0 R >>`
23907
20841
  ];
23908
20842
  objects[pages - 1] = [`<< /Type /Pages /Kids [${page} 0 R] /Count 1 >>`];
23909
- const groups = [ocArt, ...white ? [ocWhite] : [], ocCut].map((id3) => `${id3} 0 R`).join(" ");
20843
+ const groups = [ocArt, ...white ? [ocWhite] : [], ocCut].map((id) => `${id} 0 R`).join(" ");
23910
20844
  objects[catalog - 1] = [
23911
20845
  `<< /Type /Catalog /Pages ${pages} 0 R /OCProperties << /OCGs [${groups}] /D << /Order [${groups}] /ON [${groups}] >> >> >>`
23912
20846
  ];
@@ -23914,7 +20848,7 @@ S`),
23914
20848
  const chunks = [];
23915
20849
  let length = 0;
23916
20850
  const push = (part) => {
23917
- const bytes = typeof part === "string" ? encoder2.encode(part) : part;
20851
+ const bytes = typeof part === "string" ? encoder.encode(part) : part;
23918
20852
  chunks.push(bytes);
23919
20853
  length += bytes.length;
23920
20854
  };
@@ -23982,9 +20916,9 @@ function prepareSheetItem(sheet, widthMm, source, design2) {
23982
20916
  const flat = padArt(source, border + (spec.bleedMm + 1) * source.width / widthMm);
23983
20917
  const padded = widthMm * flat.width / source.width;
23984
20918
  const pixelsPerMm = flat.width / padded;
23985
- const shape2 = stickerCut(flat.rgba, flat.width, flat.height, border, padded);
20919
+ const shape = stickerCut(flat.rgba, flat.width, flat.height, border, padded);
23986
20920
  const mask = stickerCutMask(flat.rgba, flat.width, flat.height, border, padded).mask;
23987
- const issues2 = [...shape2.issues];
20921
+ const issues2 = [...shape.issues];
23988
20922
  const dpi = Math.min(source.width, source.effectiveWidth ?? source.width) / widthMm * 25.4;
23989
20923
  if (dpi < minPrintDpi)
23990
20924
  issues2.push({
@@ -24020,7 +20954,7 @@ function prepareSheetItem(sheet, widthMm, source, design2) {
24020
20954
  preview = { width: art.width, height: art.height, rgba };
24021
20955
  }
24022
20956
  return {
24023
- shape: shape2,
20957
+ shape,
24024
20958
  art,
24025
20959
  preview,
24026
20960
  widthMm: padded,
@@ -24031,9 +20965,9 @@ function prepareSheetItem(sheet, widthMm, source, design2) {
24031
20965
  }
24032
20966
  function sheetPrintFrom(sheet, prepared) {
24033
20967
  const spec = sheetSpec(sheet);
24034
- const get = (id3) => {
24035
- const entry = prepared.get(id3);
24036
- if (!entry) throw new Error(`Missing prepared sticker for ${id3}.`);
20968
+ const get = (id) => {
20969
+ const entry = prepared.get(id);
20970
+ if (!entry) throw new Error(`Missing prepared sticker for ${id}.`);
24037
20971
  return entry;
24038
20972
  };
24039
20973
  const shapes = new Map(sheet.items.map((item) => [item.id, get(item.id).shape]));
@@ -24125,11 +21059,11 @@ function registerBadgeFonts(root) {
24125
21059
  async function renderBadgeFacePng(input) {
24126
21060
  installCanvasGlobals();
24127
21061
  const marks = ["front", "back"].flatMap(
24128
- (face2) => input.design[face2].layers.flatMap(
21062
+ (face) => input.design[face].layers.flatMap(
24129
21063
  (layer) => layer.kind === "card-mark" ? [[cardMarkImageId(layer.id), Buffer.from(cardMarkSvg(layer))]] : []
24130
21064
  )
24131
21065
  );
24132
- const [portrait2, images] = await Promise.all([
21066
+ const [portrait, images] = await Promise.all([
24133
21067
  input.portrait ? loadImage(input.portrait) : void 0,
24134
21068
  Promise.all(
24135
21069
  [
@@ -24137,10 +21071,10 @@ async function renderBadgeFacePng(input) {
24137
21071
  ...marks,
24138
21072
  ...await Promise.all(
24139
21073
  Object.entries(designSvgImages(input.design, input.side, false)).map(
24140
- async ([id3, svg2]) => [id3, await sharp(Buffer.from(svg2)).png().toBuffer()]
21074
+ async ([id, svg]) => [id, await sharp(Buffer.from(svg)).png().toBuffer()]
24141
21075
  )
24142
21076
  )
24143
- ].map(async ([id3, bytes]) => [id3, await loadImage(bytes)])
21077
+ ].map(async ([id, bytes]) => [id, await loadImage(bytes)])
24144
21078
  )
24145
21079
  ]);
24146
21080
  const data = {
@@ -24152,7 +21086,7 @@ async function renderBadgeFacePng(input) {
24152
21086
  const canvas2 = createDesignFace(
24153
21087
  data,
24154
21088
  input.side,
24155
- portrait2,
21089
+ portrait,
24156
21090
  new Map(images)
24157
21091
  );
24158
21092
  return canvas2.toBuffer("image/png");
@@ -24165,7 +21099,7 @@ async function renderStickerPng(input) {
24165
21099
  const images = new Map(
24166
21100
  await Promise.all(
24167
21101
  Object.entries(input.images ?? {}).map(
24168
- async ([id3, bytes]) => [id3, await loadImage(bytes)]
21102
+ async ([id, bytes]) => [id, await loadImage(bytes)]
24169
21103
  )
24170
21104
  )
24171
21105
  );
@@ -24173,9 +21107,9 @@ async function renderStickerPng(input) {
24173
21107
  { ...input.person, document: input.design, eventName: input.design.event, portraitUrl: "" },
24174
21108
  images,
24175
21109
  async (design2) => {
24176
- const image2 = await loadImage(await renderBadgeFacePng({ ...input, design: design2, side: "front" }));
24177
- const isolated = createCanvas(image2.width, image2.height);
24178
- isolated.getContext("2d").drawImage(image2, 0, 0);
21110
+ const image = await loadImage(await renderBadgeFacePng({ ...input, design: design2, side: "front" }));
21111
+ const isolated = createCanvas(image.width, image.height);
21112
+ isolated.getContext("2d").drawImage(image, 0, 0);
24179
21113
  return isolated;
24180
21114
  }
24181
21115
  );
@@ -24220,8 +21154,8 @@ function side(value) {
24220
21154
  }
24221
21155
  function summarizeBadgeLayers(design2) {
24222
21156
  return ["front", "back"].flatMap(
24223
- (face2) => design2[face2].layers.map((layer) => ({
24224
- side: face2,
21157
+ (face) => design2[face].layers.map((layer) => ({
21158
+ side: face,
24225
21159
  id: layer.id,
24226
21160
  kind: layer.kind,
24227
21161
  x: layer.x,
@@ -24233,29 +21167,29 @@ function summarizeBadgeLayers(design2) {
24233
21167
  }))
24234
21168
  );
24235
21169
  }
24236
- function setBadgeLayer(design2, face2, id3, changes) {
24237
- const index = design2[face2].layers.findIndex((layer) => layer.id === id3);
24238
- if (index < 0) throw new InputError(`No ${face2} layer with id ${id3}. Run makeables layer list.`);
21170
+ function setBadgeLayer(design2, face, id, changes) {
21171
+ const index = design2[face].layers.findIndex((layer) => layer.id === id);
21172
+ if (index < 0) throw new InputError(`No ${face} layer with id ${id}. Run makeables layer list.`);
24239
21173
  for (const key of ["id", "kind"])
24240
21174
  if (key in changes) throw new InputError(`A layer's ${key} can't change.`);
24241
- const layers = [...design2[face2].layers];
21175
+ const layers = [...design2[face].layers];
24242
21176
  const merged = badgeLayerSchema.safeParse({ ...layers[index], ...changes });
24243
21177
  if (!merged.success) throw new InputError(issues(merged.error));
24244
21178
  const next = merged.data;
24245
21179
  layers[index] = next.kind === "card-mark" ? cardMarkLayer(next.id, next) : next;
24246
- return parseBadge(pruneAssets({ ...design2, [face2]: { ...design2[face2], layers } }));
21180
+ return parseBadge(pruneAssets({ ...design2, [face]: { ...design2[face], layers } }));
24247
21181
  }
24248
- function removeBadgeLayer(design2, face2, id3) {
24249
- const layers = design2[face2].layers.filter((layer) => layer.id !== id3);
24250
- if (layers.length === design2[face2].layers.length)
24251
- throw new InputError(`No ${face2} layer with id ${id3}. Run makeables layer list.`);
24252
- return parseBadge(pruneAssets({ ...design2, [face2]: { ...design2[face2], layers } }));
21182
+ function removeBadgeLayer(design2, face, id) {
21183
+ const layers = design2[face].layers.filter((layer) => layer.id !== id);
21184
+ if (layers.length === design2[face].layers.length)
21185
+ throw new InputError(`No ${face} layer with id ${id}. Run makeables layer list.`);
21186
+ return parseBadge(pruneAssets({ ...design2, [face]: { ...design2[face], layers } }));
24253
21187
  }
24254
21188
  async function renderBadge(design2, options) {
24255
21189
  const root = badgeAssets();
24256
21190
  registerBadgeFonts(root);
24257
21191
  const usesSample = !options.photo;
24258
- const portrait2 = await readFile2(
21192
+ const portrait = await readFile2(
24259
21193
  options.photo ? resolve2(options.photo) : join3(root, "prism", "demo", "alex-cutout.webp")
24260
21194
  ).catch((error) => {
24261
21195
  throw new InputError(`Cannot read --photo: ${error.message}`);
@@ -24264,8 +21198,8 @@ async function renderBadge(design2, options) {
24264
21198
  const images = {};
24265
21199
  const stickers = cardAssets().stickers;
24266
21200
  const canvas2 = designProfile(design2);
24267
- for (const [id3, asset] of Object.entries(design2.assets ?? {}))
24268
- images[id3] = asset.source === "petdex" ? await readFile2(join3(stickers, "petdex", `${asset.slug}.webp`)) : asset.source === "sticker" ? await readFile2(
21201
+ for (const [id, asset] of Object.entries(design2.assets ?? {}))
21202
+ images[id] = asset.source === "petdex" ? await readFile2(join3(stickers, "petdex", `${asset.slug}.webp`)) : asset.source === "sticker" ? await readFile2(
24269
21203
  join3(
24270
21204
  stickers,
24271
21205
  asset.collection,
@@ -24279,19 +21213,19 @@ async function renderBadge(design2, options) {
24279
21213
  throw new InputError(
24280
21214
  "Static material export supports sticker fronts. Use flat for other products."
24281
21215
  );
24282
- const input = { design: design2, side: options.face, person, portrait: portrait2, images };
21216
+ const input = { design: design2, side: options.face, person, portrait, images };
24283
21217
  const png = options.appearance === "material" ? await renderStickerPng(input) : await renderBadgeFacePng(input);
24284
21218
  const dimensions = Object.fromEntries(
24285
21219
  await Promise.all(
24286
- Object.entries(images).map(async ([id3, bytes]) => {
21220
+ Object.entries(images).map(async ([id, bytes]) => {
24287
21221
  const info = await sharp2(bytes).metadata();
24288
- return [id3, { width: info.width ?? 0, height: info.height ?? 0 }];
21222
+ return [id, { width: info.width ?? 0, height: info.height ?? 0 }];
24289
21223
  })
24290
21224
  )
24291
21225
  );
24292
21226
  return { png, person, samplePortrait: usesSample, dimensions };
24293
21227
  }
24294
- async function addBadgeSticker(design2, face2, src, base) {
21228
+ async function addBadgeSticker(design2, face, src, base) {
24295
21229
  let asset;
24296
21230
  let bytes;
24297
21231
  if (src.startsWith("petdex:")) {
@@ -24324,7 +21258,7 @@ async function addBadgeSticker(design2, face2, src, base) {
24324
21258
  }
24325
21259
  const { width = 1, height = 1 } = await sharp2(bytes).metadata();
24326
21260
  try {
24327
- return addSticker(design2, face2, asset, { width, height }, crypto.randomUUID().slice(0, 8));
21261
+ return addSticker(design2, face, asset, { width, height }, crypto.randomUUID().slice(0, 8));
24328
21262
  } catch (error) {
24329
21263
  throw new InputError(error.message);
24330
21264
  }
@@ -24398,17 +21332,17 @@ async function startStudio(options = {}) {
24398
21332
  const send = (value) => peer?.stream.write(`data: ${JSON.stringify(value)}
24399
21333
 
24400
21334
  `);
24401
- function settle(id3, output) {
24402
- const call = pending.get(id3);
21335
+ function settle(id, output) {
21336
+ const call = pending.get(id);
24403
21337
  if (!call) return;
24404
21338
  clearTimeout(call.timer);
24405
- pending.delete(id3);
21339
+ pending.delete(id);
24406
21340
  call.finish(output);
24407
21341
  }
24408
21342
  function disconnect() {
24409
- for (const id3 of pending.keys())
21343
+ for (const id of pending.keys())
24410
21344
  settle(
24411
- id3,
21345
+ id,
24412
21346
  failure("DISCONNECTED", "Preview disconnected. Reconnect and inspect before retrying.")
24413
21347
  );
24414
21348
  peer?.stream.end();
@@ -24451,14 +21385,14 @@ async function startStudio(options = {}) {
24451
21385
  json(409, failure("PREVIEW_IN_USE", "Keep the original preview tab open."));
24452
21386
  return;
24453
21387
  }
24454
- const id3 = url.searchParams.get("client");
24455
- if (!id3 || !/^[a-f0-9-]{36}$/.test(id3)) throw new Error("Invalid preview client.");
21388
+ const id = url.searchParams.get("client");
21389
+ if (!id || !/^[a-f0-9-]{36}$/.test(id)) throw new Error("Invalid preview client.");
24456
21390
  response.writeHead(200, {
24457
21391
  "Content-Type": "text/event-stream",
24458
21392
  Connection: "keep-alive"
24459
21393
  });
24460
21394
  response.write(": connected\n\n");
24461
- peer = { id: id3, stream: response, tools: [] };
21395
+ peer = { id, stream: response, tools: [] };
24462
21396
  const heartbeat = setInterval(() => response.write(": heartbeat\n\n"), 15e3);
24463
21397
  response.on("close", () => {
24464
21398
  clearInterval(heartbeat);
@@ -24499,22 +21433,22 @@ async function startStudio(options = {}) {
24499
21433
  json(429, failure("BUSY", "Too many active calls. Wait for the current operation."));
24500
21434
  return;
24501
21435
  }
24502
- const id3 = randomUUID();
21436
+ const id = randomUUID();
24503
21437
  const timer = setTimeout(() => {
24504
- send({ type: "cancel", id: id3 });
21438
+ send({ type: "cancel", id });
24505
21439
  settle(
24506
- id3,
21440
+ id,
24507
21441
  failure("TIMEOUT", "Call timed out. Inspect before retrying; it may have completed.")
24508
21442
  );
24509
21443
  }, options.timeout ?? 4e4);
24510
- pending.set(id3, { timer, finish: (output) => json(200, output) });
21444
+ pending.set(id, { timer, finish: (output) => json(200, output) });
24511
21445
  response.on("close", () => {
24512
- if (pending.has(id3)) {
24513
- send({ type: "cancel", id: id3 });
24514
- settle(id3, failure("CANCELLED", "Caller disconnected."));
21446
+ if (pending.has(id)) {
21447
+ send({ type: "cancel", id });
21448
+ settle(id, failure("CANCELLED", "Caller disconnected."));
24515
21449
  }
24516
21450
  });
24517
- send({ type: "call", id: id3, name: body.name, params: body.params });
21451
+ send({ type: "call", id, name: body.name, params: body.params });
24518
21452
  return;
24519
21453
  }
24520
21454
  if (request.method === "POST" && url.pathname === "/stop") {
@@ -24561,7 +21495,7 @@ async function studioRequest(url, endpoint, body) {
24561
21495
  }
24562
21496
 
24563
21497
  // src/cloud.ts
24564
- import { z as z8 } from "zod";
21498
+ import { z as z2 } from "zod";
24565
21499
  import { createHash } from "crypto";
24566
21500
  import { mkdir } from "fs/promises";
24567
21501
  import { homedir } from "os";
@@ -24576,11 +21510,11 @@ var CloudError = class extends InputError {
24576
21510
  code;
24577
21511
  status;
24578
21512
  };
24579
- var credentialsSchema = z8.object({
24580
- accessToken: z8.string().min(1),
24581
- refreshToken: z8.string().optional(),
24582
- expiresAt: z8.number(),
24583
- clientId: z8.string()
21513
+ var credentialsSchema = z2.object({
21514
+ accessToken: z2.string().min(1),
21515
+ refreshToken: z2.string().optional(),
21516
+ expiresAt: z2.number(),
21517
+ clientId: z2.string()
24584
21518
  });
24585
21519
  function coordinatedCredentials(store, site, directory = join4(homedir(), ".config", "makeables", "credential-locks")) {
24586
21520
  async function mutate(work) {
@@ -24667,10 +21601,10 @@ async function cloudRequest(site, path2, token, body, operation) {
24667
21601
  );
24668
21602
  }
24669
21603
  async function oauthConfiguration(site) {
24670
- const config = z8.object({
24671
- clientId: z8.string().min(1),
24672
- issuer: z8.string().url(),
24673
- scopes: z8.literal("profile offline_access")
21604
+ const config = z2.object({
21605
+ clientId: z2.string().min(1),
21606
+ issuer: z2.string().url(),
21607
+ scopes: z2.literal("profile offline_access")
24674
21608
  }).parse(await cloudRequest(site, ""));
24675
21609
  const issuer = new URL(config.issuer);
24676
21610
  if (issuer.protocol !== "https:" || issuer.username || issuer.password || issuer.pathname !== "/" || issuer.search || issuer.hash || issuer.hostname !== "clerk.makeables.dev" && !(editorOrigin(site).startsWith("http://") && issuer.hostname.endsWith(".clerk.accounts.dev")))
@@ -24684,10 +21618,10 @@ async function oauthConfiguration(site) {
24684
21618
  signal: AbortSignal.timeout(15e3)
24685
21619
  })
24686
21620
  );
24687
- const endpoints = z8.object({
24688
- device_authorization_endpoint: z8.string().url(),
24689
- token_endpoint: z8.string().url(),
24690
- revocation_endpoint: z8.string().url()
21621
+ const endpoints = z2.object({
21622
+ device_authorization_endpoint: z2.string().url(),
21623
+ token_endpoint: z2.string().url(),
21624
+ revocation_endpoint: z2.string().url()
24691
21625
  }).parse(discovery);
24692
21626
  for (const endpoint of Object.values(endpoints))
24693
21627
  if (new URL(endpoint).origin !== issuer.origin)
@@ -24706,11 +21640,11 @@ async function oauthRequest(url, values) {
24706
21640
  return { ok: response.ok, data };
24707
21641
  }
24708
21642
  function tokenCredentials(data, clientId, previous) {
24709
- const value = z8.object({
24710
- access_token: z8.string().min(1),
24711
- token_type: z8.string().refine((type) => type.toLowerCase() === "bearer"),
24712
- expires_in: z8.number().positive(),
24713
- refresh_token: z8.string().optional()
21643
+ const value = z2.object({
21644
+ access_token: z2.string().min(1),
21645
+ token_type: z2.string().refine((type) => type.toLowerCase() === "bearer"),
21646
+ expires_in: z2.number().positive(),
21647
+ refresh_token: z2.string().optional()
24714
21648
  }).parse(data);
24715
21649
  return {
24716
21650
  accessToken: value.access_token,
@@ -24725,13 +21659,13 @@ async function deviceLogin(config, store, options = {}) {
24725
21659
  scope: config.scopes
24726
21660
  });
24727
21661
  if (!start.ok) throw new CloudError("LOGIN_UNAVAILABLE", "Clerk could not start device login.");
24728
- const device = z8.object({
24729
- device_code: z8.string().min(1),
24730
- user_code: z8.string().min(1),
24731
- verification_uri: z8.string().url(),
24732
- verification_uri_complete: z8.string().url().optional(),
24733
- expires_in: z8.number().positive(),
24734
- interval: z8.number().positive().default(5)
21662
+ const device = z2.object({
21663
+ device_code: z2.string().min(1),
21664
+ user_code: z2.string().min(1),
21665
+ verification_uri: z2.string().url(),
21666
+ verification_uri_complete: z2.string().url().optional(),
21667
+ expires_in: z2.number().positive(),
21668
+ interval: z2.number().positive().default(5)
24735
21669
  }).parse(start.data);
24736
21670
  const url = device.verification_uri_complete ?? device.verification_uri;
24737
21671
  const verification = new URL(url);
@@ -24739,17 +21673,21 @@ async function deviceLogin(config, store, options = {}) {
24739
21673
  const allowedHost = issuer.hostname === "clerk.makeables.dev" ? "accounts.makeables.dev" : issuer.hostname.replace(".clerk.accounts.dev", ".accounts.dev");
24740
21674
  if (verification.protocol !== "https:" || verification.username || verification.password || ![issuer.hostname, allowedHost].includes(verification.hostname))
24741
21675
  throw new CloudError("INVALID_AUTHORITY", "The device verification page changed origin.");
21676
+ const waitSeconds = Math.round(
21677
+ Math.min(device.expires_in * 1e3, options.timeout ?? 18e4) / 1e3
21678
+ );
24742
21679
  options.progress?.({
24743
21680
  state: "authorization_required",
24744
21681
  url,
24745
21682
  code: device.user_code,
24746
- message: "Sign in once to connect makeables. Publication continues automatically."
21683
+ expiresInSeconds: waitSeconds,
21684
+ message: `Show this URL and code to the user now. This command waits ${waitSeconds}s for them to sign in, then continues automatically.`
24747
21685
  });
24748
21686
  if (!options.noOpen)
24749
21687
  await openBrowser(url).catch(() => {
24750
21688
  options.progress?.({ state: "open_browser", url, code: device.user_code });
24751
21689
  });
24752
- const deadline = Date.now() + Math.min(device.expires_in * 1e3, options.timeout ?? 18e4);
21690
+ const deadline = Date.now() + waitSeconds * 1e3;
24753
21691
  let interval = Math.max(device.interval * 1e3, 1e3);
24754
21692
  while (Date.now() < deadline) {
24755
21693
  await (options.sleep ?? ((ms) => new Promise((resolve4) => setTimeout(resolve4, ms))))(interval);
@@ -24776,7 +21714,7 @@ async function deviceLogin(config, store, options = {}) {
24776
21714
  }
24777
21715
  throw new CloudError(
24778
21716
  "LOGIN_REQUIRED",
24779
- "Login timed out. Your badge is still saved. Run the same command to reconnect."
21717
+ "Login timed out before the user signed in. Nothing was published. Run makeables login in the background, show its code to the user, then repeat this command."
24780
21718
  );
24781
21719
  }
24782
21720
  async function accessToken(site, options = {}) {
@@ -24825,7 +21763,7 @@ async function connectAccount(site, options = {}) {
24825
21763
  }
24826
21764
  return {
24827
21765
  token,
24828
- account: z8.object({ id: z8.string().startsWith("user_"), name: z8.string() }).parse(account)
21766
+ account: z2.object({ id: z2.string().startsWith("user_"), name: z2.string() }).parse(account)
24829
21767
  };
24830
21768
  }
24831
21769
  async function logout(site, providedStore) {
@@ -24863,7 +21801,7 @@ async function logout(site, providedStore) {
24863
21801
  import { constants } from "fs";
24864
21802
  import { open as open2, readFile as readFile3 } from "fs/promises";
24865
21803
  import { basename as basename2, join as join5, resolve as resolve3 } from "path";
24866
- import { z as z9 } from "zod";
21804
+ import { z as z3 } from "zod";
24867
21805
  async function packageFile(file) {
24868
21806
  const handle = await open2(resolve3(file), constants.O_RDONLY | constants.O_NOFOLLOW);
24869
21807
  try {
@@ -24884,21 +21822,30 @@ async function readSubmission(file, allowKit = true) {
24884
21822
  basename2(file).replace(/\.svg$/i, "").slice(0, 60)
24885
21823
  );
24886
21824
  const value = parseJson(bytes);
21825
+ if (value && typeof value === "object" && "format" in value && value.format === "makeables-brand")
21826
+ throw new InputError(
21827
+ "A brand references kits. Use makeables submit --file brand.json, which submits its kits first."
21828
+ );
24887
21829
  if (value && typeof value === "object" && "format" in value && value.format === "makeables-kit") {
24888
21830
  if (!allowKit) throw new InputError("Nested kits are not supported.");
24889
- return (await import("./kit-YXOYCN6F.js")).prepareKit(file);
21831
+ return (await import("./kit-IEWHMBS2.js")).prepareKit(file);
24890
21832
  }
24891
21833
  if (value && typeof value === "object" && "format" in value && value.format === "makeables-package")
24892
21834
  return readPackageJson(value);
24893
21835
  return renderSubmission(await localSubmissionDraft(value));
24894
21836
  }
24895
- async function localSubmissionDraft(value) {
21837
+ async function localSubmissionDraft(value, portrait) {
24896
21838
  const draft = await importDraft(value);
21839
+ if (portrait) {
21840
+ draft.portrait = portrait.path;
21841
+ draft.files[portrait.path] = portrait.bytes;
21842
+ draft.mime[portrait.path] = portrait.mime;
21843
+ }
24897
21844
  const roots = cardAssets();
24898
- for (const id3 of requiredAssets(draft.design).assets) {
24899
- const asset = draft.design.assets?.[id3];
21845
+ for (const id of requiredAssets(draft.design).assets) {
21846
+ const asset = draft.design.assets?.[id];
24900
21847
  if (!asset || asset.source === "image") continue;
24901
- const path2 = `assets/${id3}.${asset.source === "gallery" ? "svg" : "webp"}`;
21848
+ const path2 = `assets/${id}.${asset.source === "gallery" ? "svg" : "webp"}`;
24902
21849
  draft.files[path2] = await readFile3(
24903
21850
  asset.source === "gallery" ? join5(roots.designs, asset.slug, asset.file ?? "artwork.svg") : asset.source === "sticker" ? join5(
24904
21851
  roots.stickers,
@@ -24907,7 +21854,7 @@ async function localSubmissionDraft(value) {
24907
21854
  ) : join5(roots.stickers, "petdex", `${asset.slug}.webp`)
24908
21855
  );
24909
21856
  draft.mime[path2] = asset.source === "gallery" ? "image/svg+xml" : "image/webp";
24910
- draft.assets[id3] = path2;
21857
+ draft.assets[id] = path2;
24911
21858
  }
24912
21859
  if (missingAssets(draft).length)
24913
21860
  throw new InputError(
@@ -24918,10 +21865,10 @@ async function localSubmissionDraft(value) {
24918
21865
  async function renderInput(draft) {
24919
21866
  registerBadgeFonts(badgeAssets());
24920
21867
  const images = {};
24921
- for (const [id3, asset] of Object.entries(draft.design.assets ?? {}))
24922
- if (asset.source === "image") images[id3] = Buffer.from(asset.data.split(",")[1], "base64");
24923
- for (const [id3, path2] of Object.entries(draft.assets))
24924
- images[id3] = Buffer.from(draft.files[path2]);
21868
+ for (const [id, asset] of Object.entries(draft.design.assets ?? {}))
21869
+ if (asset.source === "image") images[id] = Buffer.from(asset.data.split(",")[1], "base64");
21870
+ for (const [id, path2] of Object.entries(draft.assets))
21871
+ images[id] = Buffer.from(draft.files[path2]);
24925
21872
  if (draft.artwork) images.art = Buffer.from(draft.files[draft.artwork]);
24926
21873
  return {
24927
21874
  design: draft.design,
@@ -24949,14 +21896,14 @@ async function renderSubmission(draft) {
24949
21896
  back: await renderDraftFace(draft, "back", "flat")
24950
21897
  });
24951
21898
  }
24952
- var receiptSchema = z9.object({
24953
- id: z9.string().uuid(),
24954
- state: z9.enum(["draft", "pending", "approved", "rejected", "withdrawn"]),
24955
- url: z9.string(),
24956
- product: z9.enum(["card", "badge", "sticker", "kit"]),
24957
- title: z9.string(),
24958
- uploaded: z9.array(z9.string()).optional(),
24959
- reviewNote: z9.string().nullable().optional()
21899
+ var receiptSchema = z3.object({
21900
+ id: z3.string().uuid(),
21901
+ state: z3.enum(["draft", "pending", "approved", "rejected", "withdrawn"]),
21902
+ url: z3.string(),
21903
+ product: z3.enum(["card", "badge", "sticker", "kit", "brand"]),
21904
+ title: z3.string(),
21905
+ uploaded: z3.array(z3.string()).optional(),
21906
+ reviewNote: z3.string().nullable().optional()
24960
21907
  });
24961
21908
  function receipt(value, site) {
24962
21909
  const result = receiptSchema.parse(value);
@@ -24981,7 +21928,7 @@ async function submissionRequest(site, path2, token, body) {
24981
21928
  );
24982
21929
  }
24983
21930
  async function submitDesign(options) {
24984
- const pkg = await readSubmission(options.file), site = editorOrigin(options.site);
21931
+ const pkg = options.pkg ?? await readSubmission(options.file), site = editorOrigin(options.site);
24985
21932
  const disclosure = {
24986
21933
  product: pkg.manifest.product,
24987
21934
  title: options.title ?? pkg.manifest.title,
@@ -24991,8 +21938,9 @@ async function submitDesign(options) {
24991
21938
  `${pkg.manifest.items.length} editable pieces with included images, attribution and participant details`,
24992
21939
  `${pkg.manifest.sheets.length} print sheets`
24993
21940
  ] : [],
21941
+ ...pkg.manifest.product === "brand" ? [`brand page, logos and palette for ${pkg.manifest.kits.length} submitted kits`] : [],
24994
21942
  ...pkg.manifest.back ? ["back"] : [],
24995
- ...pkg.manifest.product === "kit" ? [] : pkg.manifest.document ? [
21943
+ ...pkg.manifest.product === "kit" || pkg.manifest.product === "brand" ? [] : pkg.manifest.document ? [
24996
21944
  pkg.manifest.product === "badge" ? "editable layers and participant details" : "editable layers"
24997
21945
  ] : ["original artwork"],
24998
21946
  "included images and attribution"
@@ -25064,20 +22012,6 @@ async function submitDesign(options) {
25064
22012
  }
25065
22013
 
25066
22014
  export {
25067
- checkSubmittedSvg,
25068
- designProfile,
25069
- stickerMaterialSchema,
25070
- defaultStickerMaterial,
25071
- svgNodeSchema,
25072
- svgNodeXml,
25073
- badgeDesignObjectSchema,
25074
- badgeDesignSchema,
25075
- sheetSizes,
25076
- sheetTypes,
25077
- sheetTypeIds,
25078
- stickerSheetSchema,
25079
- sheetSpec,
25080
- createStickerSheet,
25081
22015
  cardStyles,
25082
22016
  findCardStyle,
25083
22017
  designEditsSchema,
@@ -25086,18 +22020,6 @@ export {
25086
22020
  createStickerDesign,
25087
22021
  designCatalog,
25088
22022
  findDesign,
25089
- kitDocumentSchema,
25090
- PACKAGE_LIMIT,
25091
- designManifestSchema,
25092
- jsonBytes,
25093
- hashBytes,
25094
- assemblePackage,
25095
- readPackageZip,
25096
- packageZip,
25097
- draftFromPackage,
25098
- packageJson,
25099
- readPackageJson,
25100
- kitMemberPackage,
25101
22023
  stickerCut,
25102
22024
  stickerCutSvg,
25103
22025
  effectiveRasterWidth,
@@ -25117,6 +22039,7 @@ export {
25117
22039
  removeBadgeLayer,
25118
22040
  renderBadge,
25119
22041
  addBadgeSticker,
22042
+ editorOrigin,
25120
22043
  openBrowser,
25121
22044
  startStudio,
25122
22045
  studioRequest,