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.
- package/README.md +2 -1
- package/dist/badge-package-CMFI3BIR.js +53 -0
- package/dist/brand-NMENEWIZ.js +37 -0
- package/dist/brand-preview-W4FTJJM3.js +48 -0
- package/dist/chunk-4WLCMPRH.js +74 -0
- package/dist/{chunk-TRIRNJSG.js → chunk-6RBOBRL4.js} +13 -11
- package/dist/chunk-BYXBJQAS.js +0 -0
- package/dist/chunk-DLTVENEP.js +3295 -0
- package/dist/{chunk-G6OTYITI.js → chunk-YB2YJCBS.js} +386 -3463
- package/dist/chunk-ZZA6CR6X.js +700 -0
- package/dist/cli.js +2317 -224
- package/dist/{kit-YXOYCN6F.js → kit-IEWHMBS2.js} +3 -2
- package/dist/{mcp-VS5XYXVM.js → mcp-YBRUVIWG.js} +11 -18
- package/dist/submission-ATVS5YTK.js +76 -0
- package/package.json +3 -2
- package/dist/chunk-SZTWKHNA.js +0 -95
|
@@ -1,1393 +1,38 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
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 = (
|
|
1390
|
-
id
|
|
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
|
|
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 = (
|
|
1410
|
-
id
|
|
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
|
|
1417
|
-
shape
|
|
61
|
+
color,
|
|
62
|
+
shape,
|
|
1418
63
|
opacity,
|
|
1419
64
|
channel: "ink",
|
|
1420
65
|
radius: 0,
|
|
1421
|
-
stroke:
|
|
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 = (
|
|
1436
|
-
id
|
|
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
|
|
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 = (
|
|
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(
|
|
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
|
-
|
|
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 = (
|
|
1825
|
-
g(
|
|
1826
|
-
t(`${
|
|
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 = (
|
|
2107
|
-
s(`${
|
|
2108
|
-
s(
|
|
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 = (
|
|
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
|
|
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(
|
|
1382
|
+
function named(id, [x, y, w, h]) {
|
|
2738
1383
|
return {
|
|
2739
|
-
id
|
|
2740
|
-
name:
|
|
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(
|
|
1392
|
+
function rect(id, box2, color, radius = 0, opacity = 1) {
|
|
2748
1393
|
return {
|
|
2749
|
-
...named(
|
|
1394
|
+
...named(id, box2),
|
|
2750
1395
|
kind: "shape",
|
|
2751
1396
|
shape: "rectangle",
|
|
2752
|
-
color
|
|
1397
|
+
color,
|
|
2753
1398
|
radius,
|
|
2754
1399
|
stroke: 0,
|
|
2755
1400
|
opacity,
|
|
2756
1401
|
protectMaterial: false
|
|
2757
1402
|
};
|
|
2758
1403
|
}
|
|
2759
|
-
function circle(
|
|
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
|
-
|
|
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
|
-
|
|
1411
|
+
color,
|
|
2767
1412
|
stroke,
|
|
2768
1413
|
opacity
|
|
2769
1414
|
);
|
|
2770
1415
|
}
|
|
2771
1416
|
return {
|
|
2772
|
-
...named(
|
|
1417
|
+
...named(id, [cx - radius, cy - radius, radius * 2, radius * 2]),
|
|
2773
1418
|
kind: "shape",
|
|
2774
1419
|
shape: "ellipse",
|
|
2775
|
-
color
|
|
1420
|
+
color,
|
|
2776
1421
|
radius: 0,
|
|
2777
1422
|
stroke,
|
|
2778
1423
|
opacity,
|
|
2779
1424
|
protectMaterial: false
|
|
2780
1425
|
};
|
|
2781
1426
|
}
|
|
2782
|
-
function path(
|
|
1427
|
+
function path(id, box2, d, color, stroke = 0, opacity = 1, viewBox) {
|
|
2783
1428
|
return {
|
|
2784
|
-
...named(
|
|
1429
|
+
...named(id, box2),
|
|
2785
1430
|
kind: "graphic",
|
|
2786
1431
|
pattern: "path",
|
|
2787
|
-
color
|
|
2788
|
-
accent:
|
|
1432
|
+
color,
|
|
1433
|
+
accent: color,
|
|
2789
1434
|
density: 1,
|
|
2790
1435
|
seed: 1,
|
|
2791
1436
|
path: d,
|
|
2792
|
-
viewBox: viewBox ?? { width:
|
|
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(
|
|
2799
|
-
return path(
|
|
1443
|
+
function field(id, d, color, stroke = 0, opacity = 1) {
|
|
1444
|
+
return path(id, full, d, color, stroke, opacity);
|
|
2800
1445
|
}
|
|
2801
|
-
function
|
|
1446
|
+
function text(id, value, box2, color, size = 20, font = "mono", weight = "500") {
|
|
2802
1447
|
return {
|
|
2803
|
-
...named(
|
|
1448
|
+
...named(id, box2),
|
|
2804
1449
|
kind: "text",
|
|
2805
1450
|
text: value,
|
|
2806
1451
|
binding: "none",
|
|
2807
|
-
color
|
|
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
|
|
1462
|
+
function gradient(id, colors, direction = "diagonal", box2 = full) {
|
|
2818
1463
|
return {
|
|
2819
|
-
...named(
|
|
1464
|
+
...named(id, box2),
|
|
2820
1465
|
kind: "gradient",
|
|
2821
1466
|
direction,
|
|
2822
|
-
stops: colors.map((
|
|
1467
|
+
stops: colors.map((color, index) => ({ color, at: index / (colors.length - 1) }))
|
|
2823
1468
|
};
|
|
2824
1469
|
}
|
|
2825
|
-
function film(
|
|
2826
|
-
return { ...named(
|
|
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(
|
|
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(
|
|
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(
|
|
2850
|
-
const [, , w, h] =
|
|
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(
|
|
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,
|
|
1625
|
+
const motif2 = (index, box2, opacity = 1) => {
|
|
2981
1626
|
const source = original[index - 1];
|
|
2982
|
-
const scale = Math.min(
|
|
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:
|
|
2989
|
-
y:
|
|
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 = (
|
|
2996
|
-
const title = (value, x = 80, y = 260, w = 900, size = 88, font = "sans") =>
|
|
2997
|
-
const line2 = (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1708
|
+
text("private-reverse", "PRIVATE EDITION", [80, 79, 1030, 30], ink, 17),
|
|
3064
1709
|
motif2(8, [442, 175, 318, 137]),
|
|
3065
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3151
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3265
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3307
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1982
|
+
text("status-title", "REVERSE SIDE", [192, 166, 788, 37], "#ffffff", 23),
|
|
3338
1983
|
...["LAYERS : OPEN", "MATERIAL : LIVE", "STATUS : READY"].map(
|
|
3339
|
-
(value, i) =>
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
2044
|
+
function text2(id, value, x, y, w, size, color) {
|
|
3400
2045
|
return {
|
|
3401
|
-
id
|
|
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
|
|
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(
|
|
2062
|
+
function line(id, x, y, w, color) {
|
|
3418
2063
|
return {
|
|
3419
|
-
id
|
|
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
|
|
2071
|
+
color,
|
|
3427
2072
|
radius: 0,
|
|
3428
2073
|
stroke: 1,
|
|
3429
2074
|
opacity: 0.5
|
|
3430
2075
|
};
|
|
3431
2076
|
}
|
|
3432
|
-
function
|
|
3433
|
-
return { id
|
|
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(
|
|
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:
|
|
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
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2138
|
+
text2("reverse-wordmark", "makeables / material studies", 76, 310, 1040, 24, ink),
|
|
3494
2139
|
line("reverse-rule", 76, 380, 1048, ink),
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
3656
|
-
return cardStyles.find((design2) => design2.source ===
|
|
2300
|
+
function findCardStyle(id) {
|
|
2301
|
+
return cardStyles.find((design2) => design2.source === id);
|
|
3657
2302
|
}
|
|
3658
|
-
var faceEdits =
|
|
2303
|
+
var faceEdits = z.object({
|
|
3659
2304
|
background: badgeDesignObjectSchema.shape.front.shape.background.optional(),
|
|
3660
|
-
upsert:
|
|
3661
|
-
remove:
|
|
3662
|
-
order:
|
|
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 =
|
|
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
|
|
3688
|
-
if (change.background)
|
|
3689
|
-
for (const
|
|
3690
|
-
if (!
|
|
3691
|
-
throw new Error(`No existe ${side2}.${
|
|
3692
|
-
|
|
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 =
|
|
3699
|
-
if (index >= 0)
|
|
2343
|
+
const index = face.layers.findIndex((item) => item.id === layer.id);
|
|
2344
|
+
if (index >= 0) face.layers[index] = layer;
|
|
3700
2345
|
else {
|
|
3701
|
-
const
|
|
3702
|
-
|
|
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 !==
|
|
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
|
-
|
|
3709
|
-
const layer =
|
|
3710
|
-
if (!layer) throw new Error(`No existe ${side2}.${
|
|
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
|
-
([,
|
|
4713
|
+
([, id]) => `community-${id}`
|
|
6069
4714
|
);
|
|
6070
|
-
var communityStickerStyles = collection2.map(([slug,
|
|
4715
|
+
var communityStickerStyles = collection2.map(([slug, id]) => {
|
|
6071
4716
|
const original = badgeDesignSchema.parse(community_sticker_sources_default[slug]);
|
|
6072
|
-
const
|
|
4717
|
+
const credit = { label: "Railly Hugo", url: `https://makeables.dev/submissions/${id}` };
|
|
6073
4718
|
return badgeDesignSchema.parse({
|
|
6074
4719
|
...original,
|
|
6075
|
-
source: `community-${
|
|
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
|
|
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
|
|
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
|
-
//
|
|
20015
|
-
|
|
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
|
|
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
|
|
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
|
|
22259
|
-
ctx.fillStyle =
|
|
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 :
|
|
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 =
|
|
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:
|
|
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
|
|
22412
|
-
const value = Math.max(0, Math.min(1, (
|
|
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 +
|
|
22424
|
-
pixels[i + 1] = 20 + pixels[i + 1] * 0.69 +
|
|
22425
|
-
pixels[i + 2] = 22 + pixels[i + 2] * 0.57 +
|
|
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,
|
|
22432
|
-
const scale = Math.min(w /
|
|
22433
|
-
const dw =
|
|
22434
|
-
const dh =
|
|
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(
|
|
19365
|
+
ctx.drawImage(image, (w - dw) / 2, (h - dh) / 2, dw, dh);
|
|
22438
19366
|
ctx.restore();
|
|
22439
19367
|
}
|
|
22440
|
-
function coverDesignImage(ctx,
|
|
19368
|
+
function coverDesignImage(ctx, image, w, h, layer) {
|
|
22441
19369
|
const crop = layer?.crop;
|
|
22442
|
-
const scale = Math.max(w /
|
|
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(
|
|
22446
|
-
const y = layer?.cropMode === "focus" ? Math.max(0, Math.min(
|
|
22447
|
-
ctx.drawImage(
|
|
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,
|
|
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,
|
|
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
|
|
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
|
-
|
|
22505
|
-
|
|
22506
|
-
|
|
22507
|
-
|
|
22508
|
-
surface.fillStyle =
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
19621
|
+
const gradient2 = ctx.createLinearGradient(0, h, w, 0);
|
|
22688
19622
|
colors.forEach((c, i) => {
|
|
22689
|
-
|
|
19623
|
+
gradient2.addColorStop(i / 2, c);
|
|
22690
19624
|
});
|
|
22691
|
-
ctx.fillStyle =
|
|
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,
|
|
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")
|
|
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
|
|
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)
|
|
22832
|
-
ctx.fillStyle =
|
|
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" &&
|
|
19768
|
+
} else if (layer.kind === "portrait" && portrait) paintDesignPhoto(ctx, layer, portrait);
|
|
22835
19769
|
else if (layer.kind === "card-mark") {
|
|
22836
|
-
const
|
|
22837
|
-
if (
|
|
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
|
|
19773
|
+
const image = images?.get(layer.asset);
|
|
22840
19774
|
const pixelated = data.document?.assets?.[layer.asset];
|
|
22841
|
-
if (
|
|
19775
|
+
if (image && layer.fit === "contain")
|
|
22842
19776
|
containDesignImage(
|
|
22843
19777
|
ctx,
|
|
22844
|
-
|
|
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 (
|
|
19783
|
+
else if (image) coverDesignImage(ctx, image, layer.w, layer.h);
|
|
22850
19784
|
}
|
|
22851
19785
|
ctx.restore();
|
|
22852
19786
|
}
|
|
22853
|
-
function createDesignFace(data, side2,
|
|
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
|
|
22868
|
-
if (
|
|
22869
|
-
ctx.drawImage(
|
|
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,
|
|
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,
|
|
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
|
|
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
|
-
(
|
|
23355
|
-
|
|
20288
|
+
(color, i) => {
|
|
20289
|
+
gradient2.addColorStop(i / 6, color);
|
|
23356
20290
|
}
|
|
23357
20291
|
);
|
|
23358
|
-
coat.fillStyle =
|
|
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(
|
|
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
|
|
20453
|
+
return shape.paths.filter((path2) => holes || !path2.hole).map(
|
|
23520
20454
|
(path2) => path2.points.map(([px, py]) => {
|
|
23521
|
-
const dx = px -
|
|
23522
|
-
const dy = py -
|
|
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
|
|
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) =>
|
|
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 =
|
|
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(
|
|
20628
|
+
function area(shape) {
|
|
23695
20629
|
let total = 0;
|
|
23696
|
-
for (const path2 of
|
|
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
|
|
20638
|
+
function placeOne(occupancy, { item, shape }, target, rotations) {
|
|
23705
20639
|
for (const rotation of rotations) {
|
|
23706
|
-
const at = occupancy.nearest(footprint(placedOutline(
|
|
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,
|
|
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 =
|
|
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 =
|
|
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:
|
|
20669
|
+
items: inputs.map((input) => placed.get(input.item.id) ?? input.item),
|
|
23736
20670
|
missing
|
|
23737
20671
|
};
|
|
23738
20672
|
}
|
|
23739
|
-
function placeNear(spec, bounds,
|
|
20673
|
+
function placeNear(spec, bounds, inputs, id, target) {
|
|
23740
20674
|
const occupancy = new Occupancy(bounds, spec);
|
|
23741
|
-
for (const input of
|
|
23742
|
-
if (input.item.id !==
|
|
23743
|
-
const moving =
|
|
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
|
|
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(
|
|
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
|
|
23904
|
-
const xobjects = images.map((
|
|
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 ${
|
|
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((
|
|
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" ?
|
|
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
|
|
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 = [...
|
|
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
|
|
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 = (
|
|
24035
|
-
const entry = prepared.get(
|
|
24036
|
-
if (!entry) throw new Error(`Missing prepared sticker for ${
|
|
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
|
-
(
|
|
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 [
|
|
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 ([
|
|
21074
|
+
async ([id, svg]) => [id, await sharp(Buffer.from(svg)).png().toBuffer()]
|
|
24141
21075
|
)
|
|
24142
21076
|
)
|
|
24143
|
-
].map(async ([
|
|
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
|
-
|
|
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 ([
|
|
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
|
|
24177
|
-
const isolated = createCanvas(
|
|
24178
|
-
isolated.getContext("2d").drawImage(
|
|
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
|
-
(
|
|
24224
|
-
side:
|
|
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,
|
|
24237
|
-
const index = design2[
|
|
24238
|
-
if (index < 0) throw new InputError(`No ${
|
|
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[
|
|
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, [
|
|
21180
|
+
return parseBadge(pruneAssets({ ...design2, [face]: { ...design2[face], layers } }));
|
|
24247
21181
|
}
|
|
24248
|
-
function removeBadgeLayer(design2,
|
|
24249
|
-
const layers = design2[
|
|
24250
|
-
if (layers.length === design2[
|
|
24251
|
-
throw new InputError(`No ${
|
|
24252
|
-
return parseBadge(pruneAssets({ ...design2, [
|
|
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
|
|
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 [
|
|
24268
|
-
images[
|
|
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
|
|
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 ([
|
|
21220
|
+
Object.entries(images).map(async ([id, bytes]) => {
|
|
24287
21221
|
const info = await sharp2(bytes).metadata();
|
|
24288
|
-
return [
|
|
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,
|
|
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,
|
|
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(
|
|
24402
|
-
const call = pending.get(
|
|
21335
|
+
function settle(id, output) {
|
|
21336
|
+
const call = pending.get(id);
|
|
24403
21337
|
if (!call) return;
|
|
24404
21338
|
clearTimeout(call.timer);
|
|
24405
|
-
pending.delete(
|
|
21339
|
+
pending.delete(id);
|
|
24406
21340
|
call.finish(output);
|
|
24407
21341
|
}
|
|
24408
21342
|
function disconnect() {
|
|
24409
|
-
for (const
|
|
21343
|
+
for (const id of pending.keys())
|
|
24410
21344
|
settle(
|
|
24411
|
-
|
|
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
|
|
24455
|
-
if (!
|
|
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
|
|
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
|
|
21436
|
+
const id = randomUUID();
|
|
24503
21437
|
const timer = setTimeout(() => {
|
|
24504
|
-
send({ type: "cancel", id
|
|
21438
|
+
send({ type: "cancel", id });
|
|
24505
21439
|
settle(
|
|
24506
|
-
|
|
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(
|
|
21444
|
+
pending.set(id, { timer, finish: (output) => json(200, output) });
|
|
24511
21445
|
response.on("close", () => {
|
|
24512
|
-
if (pending.has(
|
|
24513
|
-
send({ type: "cancel", id
|
|
24514
|
-
settle(
|
|
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
|
|
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
|
|
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 =
|
|
24580
|
-
accessToken:
|
|
24581
|
-
refreshToken:
|
|
24582
|
-
expiresAt:
|
|
24583
|
-
clientId:
|
|
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 =
|
|
24671
|
-
clientId:
|
|
24672
|
-
issuer:
|
|
24673
|
-
scopes:
|
|
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 =
|
|
24688
|
-
device_authorization_endpoint:
|
|
24689
|
-
token_endpoint:
|
|
24690
|
-
revocation_endpoint:
|
|
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 =
|
|
24710
|
-
access_token:
|
|
24711
|
-
token_type:
|
|
24712
|
-
expires_in:
|
|
24713
|
-
refresh_token:
|
|
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 =
|
|
24729
|
-
device_code:
|
|
24730
|
-
user_code:
|
|
24731
|
-
verification_uri:
|
|
24732
|
-
verification_uri_complete:
|
|
24733
|
-
expires_in:
|
|
24734
|
-
interval:
|
|
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
|
-
|
|
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() +
|
|
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
|
|
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:
|
|
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
|
|
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-
|
|
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
|
|
24899
|
-
const asset = draft.design.assets?.[
|
|
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/${
|
|
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[
|
|
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 [
|
|
24922
|
-
if (asset.source === "image") images[
|
|
24923
|
-
for (const [
|
|
24924
|
-
images[
|
|
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 =
|
|
24953
|
-
id:
|
|
24954
|
-
state:
|
|
24955
|
-
url:
|
|
24956
|
-
product:
|
|
24957
|
-
title:
|
|
24958
|
-
uploaded:
|
|
24959
|
-
reviewNote:
|
|
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,
|