volleyballsimtypes 0.0.526 → 0.0.528

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/cjs/src/api/index.d.ts +4 -2
  2. package/dist/cjs/src/data/init-models.js +5 -0
  3. package/dist/cjs/src/data/models/index.d.ts +1 -0
  4. package/dist/cjs/src/data/models/index.js +1 -0
  5. package/dist/cjs/src/data/models/team-badge.d.ts +20 -0
  6. package/dist/cjs/src/data/models/team-badge.js +38 -0
  7. package/dist/cjs/src/data/models/team-jersey.d.ts +3 -1
  8. package/dist/cjs/src/data/models/team-jersey.js +4 -0
  9. package/dist/cjs/src/data/models/team.d.ts +3 -1
  10. package/dist/cjs/src/data/transformers/team.js +5 -1
  11. package/dist/cjs/src/service/team/badge.d.ts +301 -0
  12. package/dist/cjs/src/service/team/badge.js +93 -0
  13. package/dist/cjs/src/service/team/index.d.ts +2 -0
  14. package/dist/cjs/src/service/team/index.js +2 -0
  15. package/dist/cjs/src/service/team/jersey-defaults.d.ts +13 -0
  16. package/dist/cjs/src/service/team/jersey-defaults.js +81 -0
  17. package/dist/cjs/src/service/team/jersey.d.ts +31 -0
  18. package/dist/cjs/src/service/team/jersey.js +137 -1
  19. package/dist/cjs/src/service/team/schemas/team.z.d.ts +122 -0
  20. package/dist/cjs/src/service/team/schemas/team.z.js +4 -1
  21. package/dist/cjs/src/service/team/team.d.ts +4 -1
  22. package/dist/cjs/src/service/team/team.js +3 -1
  23. package/dist/esm/src/api/index.d.ts +4 -2
  24. package/dist/esm/src/data/init-models.js +6 -1
  25. package/dist/esm/src/data/models/index.d.ts +1 -0
  26. package/dist/esm/src/data/models/index.js +1 -0
  27. package/dist/esm/src/data/models/team-badge.d.ts +20 -0
  28. package/dist/esm/src/data/models/team-badge.js +34 -0
  29. package/dist/esm/src/data/models/team-jersey.d.ts +3 -1
  30. package/dist/esm/src/data/models/team-jersey.js +4 -0
  31. package/dist/esm/src/data/models/team.d.ts +3 -1
  32. package/dist/esm/src/data/transformers/team.js +5 -1
  33. package/dist/esm/src/service/team/badge.d.ts +301 -0
  34. package/dist/esm/src/service/team/badge.js +90 -0
  35. package/dist/esm/src/service/team/index.d.ts +2 -0
  36. package/dist/esm/src/service/team/index.js +2 -0
  37. package/dist/esm/src/service/team/jersey-defaults.d.ts +13 -0
  38. package/dist/esm/src/service/team/jersey-defaults.js +77 -0
  39. package/dist/esm/src/service/team/jersey.d.ts +31 -0
  40. package/dist/esm/src/service/team/jersey.js +132 -0
  41. package/dist/esm/src/service/team/schemas/team.z.d.ts +122 -0
  42. package/dist/esm/src/service/team/schemas/team.z.js +5 -2
  43. package/dist/esm/src/service/team/team.d.ts +4 -1
  44. package/dist/esm/src/service/team/team.js +3 -1
  45. package/package.json +1 -1
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JERSEY_FONT_ORDER = exports.JERSEY_CLOTHING_ORDER = exports.JERSEY_PATTERN_ORDER = exports.JERSEY_PALETTES = void 0;
4
+ exports.jerseyFromTeamId = jerseyFromTeamId;
5
+ // FNV-1a hash of a string, used to seed the PRNG below from a team id.
6
+ function hashSeed(str) {
7
+ let h = 2166136261;
8
+ for (let i = 0; i < str.length; i++) {
9
+ h ^= str.charCodeAt(i);
10
+ h = Math.imul(h, 16777619);
11
+ }
12
+ return h >>> 0;
13
+ }
14
+ // mulberry32: a tiny deterministic PRNG. Same seed -> same stream, so a team's kit is stable and reproducible.
15
+ function mulberry32(seed) {
16
+ let a = seed;
17
+ return () => {
18
+ a = (a + 0x6d2b79f5) | 0;
19
+ let t = Math.imul(a ^ (a >>> 15), 1 | a);
20
+ t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
21
+ return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
22
+ };
23
+ }
24
+ exports.JERSEY_PALETTES = [
25
+ { color1: '#606c38', color2: '#dda15e', color3: '#bc6c25', number1: '#fefae0', number2: '#283618' },
26
+ { color1: '#780000', color2: '#669bbc', color3: '#c1121f', number1: '#fdf0d5', number2: '#003049' },
27
+ { color1: '#2a9d8f', color2: '#f4a261', color3: '#e76f51', number1: '#264653', number2: '#e9c46a' },
28
+ { color1: '#219ebc', color2: '#fb8500', color3: '#8ecae6', number1: '#023047', number2: '#ffb703' },
29
+ { color1: '#1d3557', color2: '#e63946', color3: '#a8dadc', number1: '#f1faee', number2: '#457b9d' },
30
+ { color1: '#003566', color2: '#ffc300', color3: '#001d3d', number1: '#ffd60a', number2: '#000814' },
31
+ { color1: '#bc4749', color2: '#6a994e', color3: '#a7c957', number1: '#f2e8cf', number2: '#386641' },
32
+ { color1: '#6f1d1b', color2: '#99582a', color3: '#bb9457', number1: '#ffe6a7', number2: '#432818' },
33
+ { color1: '#ef476f', color2: '#118ab2', color3: '#ffd166', number1: '#ffd166', number2: '#073b4c' },
34
+ { color1: '#16425b', color2: '#3a7ca5', color3: '#81c3d7', number1: '#d9dcd6', number2: '#2f6690' },
35
+ { color1: '#ee6c4d', color2: '#3d5a80', color3: '#98c1d9', number1: '#e0fbfc', number2: '#293241' },
36
+ { color1: '#e09f3e', color2: '#335c67', color3: '#9e2a2b', number1: '#fff3b0', number2: '#540b0e' },
37
+ { color1: '#9a031e', color2: '#fb8b24', color3: '#e36414', number1: '#0f4c5c', number2: '#5f0f40' },
38
+ { color1: '#127475', color2: '#f2542d', color3: '#0e9594', number1: '#f5dfbb', number2: '#562c2c' },
39
+ { color1: '#bc4b51', color2: '#8cb369', color3: '#f4a259', number1: '#f4e285', number2: '#5b8e7d' },
40
+ { color1: '#7678ed', color2: '#f18701', color3: '#f35b04', number1: '#f7b801', number2: '#3d348b' },
41
+ { color1: '#14213d', color2: '#fca311', color3: '#e5e5e5', number1: '#ffffff', number2: '#000000' },
42
+ { color1: '#e07a5f', color2: '#81b29a', color3: '#f2cc8f', number1: '#f4f1de', number2: '#3d405b' },
43
+ { color1: '#f79824', color2: '#33a1fd', color3: '#fdca40', number1: '#33a1fd', number2: '#31393c' },
44
+ { color1: '#619b8a', color2: '#fe7f2d', color3: '#a1c181', number1: '#fcca46', number2: '#233d4d' },
45
+ { color1: '#227c9d', color2: '#17c3b2', color3: '#ffcb77', number1: '#fef9ef', number2: '#fe6d73' },
46
+ { color1: '#19647e', color2: '#119da4', color3: '#1f2041', number1: '#4b3f72', number2: '#ffc857' }
47
+ ];
48
+ exports.JERSEY_PATTERN_ORDER = [
49
+ 'solid', 'verticalStripes', 'verticalBars', 'pinstripes', 'hoops', 'checkered', 'diagonalSash', 'splitHalves',
50
+ 'chevron', 'shoulderYoke', 'sidePanels', 'centerBand', 'gradientFade', 'twoToneSplit'
51
+ ];
52
+ exports.JERSEY_CLOTHING_ORDER = [
53
+ 'shirtCrewNeck', 'shirtCrewNeckSleeveless', 'shirtVNeck', 'shirtVNeckSleeveless', 'collarAndSweater', 'collarAndSweaterSleeveless'
54
+ ];
55
+ // Free-user fonts: the id-derived random for a team's default kit picks ONLY from these (premium fonts are vector
56
+ // glyph paths that require the UI rendering pipeline).
57
+ exports.JERSEY_FONT_ORDER = ['sans', 'wide', 'mono', 'serif', 'block'];
58
+ // The full jersey a team wears by default: every category is drawn deterministically from the team id, so each team
59
+ // gets its own stable, distinct kit. Colours come from ONE randomly-assigned JERSEY_PALETTE (harmonious by design);
60
+ // clothing / pattern / font stay random per team.
61
+ function jerseyFromTeamId(teamId) {
62
+ const rng = mulberry32(hashSeed(teamId));
63
+ const pickFrom = (arr) => arr[Math.floor(rng() * arr.length)];
64
+ const palette = pickFrom(exports.JERSEY_PALETTES);
65
+ return {
66
+ clothing: pickFrom(exports.JERSEY_CLOTHING_ORDER),
67
+ pattern: pickFrom(exports.JERSEY_PATTERN_ORDER),
68
+ colors: [palette.color1, palette.color2, palette.color3],
69
+ font: pickFrom(exports.JERSEY_FONT_ORDER),
70
+ numberColor: palette.number1,
71
+ numberOutline: palette.number2,
72
+ numberOutlineEnabled: true,
73
+ numberSpacing: 0,
74
+ numberSize: 46,
75
+ brand: 'none',
76
+ brandColor1: '#ffffff',
77
+ brandColor2: '#1e293b',
78
+ brandSize: 29,
79
+ badgeSize: 48
80
+ };
81
+ }
@@ -67,8 +67,39 @@ export declare const JerseySchema: z.ZodObject<{
67
67
  }>>;
68
68
  brandColor1: z.ZodDefault<z.ZodString>;
69
69
  brandColor2: z.ZodDefault<z.ZodString>;
70
+ brandSize: z.ZodDefault<z.ZodNumber>;
71
+ badgeSize: z.ZodDefault<z.ZodNumber>;
70
72
  }, z.core.$strip>;
71
73
  export type JerseyConfig = z.infer<typeof JerseySchema>;
72
74
  export type JerseyClothing = JerseyConfig['clothing'];
73
75
  export type JerseyPattern = JerseyConfig['pattern'];
74
76
  export type JerseyFont = JerseyConfig['font'];
77
+ export declare const AlternateJerseySchema: z.ZodObject<{
78
+ pattern: z.ZodEnum<{
79
+ solid: "solid";
80
+ verticalStripes: "verticalStripes";
81
+ verticalBars: "verticalBars";
82
+ pinstripes: "pinstripes";
83
+ hoops: "hoops";
84
+ checkered: "checkered";
85
+ diagonalSash: "diagonalSash";
86
+ splitHalves: "splitHalves";
87
+ chevron: "chevron";
88
+ shoulderYoke: "shoulderYoke";
89
+ sidePanels: "sidePanels";
90
+ centerBand: "centerBand";
91
+ gradientFade: "gradientFade";
92
+ twoToneSplit: "twoToneSplit";
93
+ }>;
94
+ colors: z.ZodArray<z.ZodString>;
95
+ numberColor: z.ZodString;
96
+ numberOutline: z.ZodString;
97
+ numberOutlineEnabled: z.ZodDefault<z.ZodBoolean>;
98
+ brandColor1: z.ZodDefault<z.ZodString>;
99
+ brandColor2: z.ZodDefault<z.ZodString>;
100
+ }, z.core.$strip>;
101
+ export type AlternateJerseyConfig = z.infer<typeof AlternateJerseySchema>;
102
+ export declare function complementaryHex(hex: string): string;
103
+ export declare function relativeLuminance(hex: string): number;
104
+ export declare function computeComplementaryJersey(main: JerseyConfig): JerseyConfig;
105
+ export declare function mergeAlternateJersey(main: JerseyConfig, alt: AlternateJerseyConfig): JerseyConfig;
@@ -1,6 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.JerseySchema = void 0;
3
+ exports.AlternateJerseySchema = exports.JerseySchema = void 0;
4
+ exports.complementaryHex = complementaryHex;
5
+ exports.relativeLuminance = relativeLuminance;
6
+ exports.computeComplementaryJersey = computeComplementaryJersey;
7
+ exports.mergeAlternateJersey = mergeAlternateJersey;
4
8
  const zod_1 = require("zod");
5
9
  // 6-digit hex (#rrggbb) or 8-digit hex with alpha (#rrggbbaa). The 8-digit form comes from the UI's opacity-enabled
6
10
  // colour pickers; SVG fills render both natively.
@@ -29,5 +33,137 @@ exports.JerseySchema = zod_1.z.object({
29
33
  // configs saved before it stay valid.
30
34
  brand: zod_1.z.enum(['none', 'sigma', 'person-soccer', 'feather-pointed', 'paw-claws', 'narwhal', 'horseshoe', 'spider-black-widow', 'wreath-laurel', 'omega', 'trillium']).default('none'),
31
35
  brandColor1: hexColor.default('#ffffff'),
36
+ brandColor2: hexColor.default('#1e293b'),
37
+ // Chest-element heights in avatar-svg units, on the y=297 chest line. The brand sits at x=90 and the team badge
38
+ // at x=191, with the (non-editable) champion badge between them at x=140.5 spanning 116.5..164.5, so either one
39
+ // starts touching it past about 52. The range allows more than that on purpose: most teams have no champion
40
+ // badge, and the editor preview shows the overlap for the ones that do. Defaulted to the sizes both were fixed
41
+ // at before, so configs saved earlier stay valid and look unchanged.
42
+ brandSize: zod_1.z.number().min(16).max(64).default(29),
43
+ badgeSize: zod_1.z.number().min(16).max(64).default(48)
44
+ });
45
+ // The alternate (libero) kit stores only the fields the premium editor allows changing. Locked fields (clothing,
46
+ // font, brand icon, numberSpacing, numberSize, brandSize, badgeSize) are always inherited from the main kit at
47
+ // render time.
48
+ exports.AlternateJerseySchema = zod_1.z.object({
49
+ pattern: exports.JerseySchema.shape.pattern,
50
+ colors: exports.JerseySchema.shape.colors,
51
+ numberColor: hexColor,
52
+ numberOutline: hexColor,
53
+ numberOutlineEnabled: zod_1.z.boolean().default(true),
54
+ brandColor1: hexColor.default('#ffffff'),
32
55
  brandColor2: hexColor.default('#1e293b')
33
56
  });
57
+ // ---------------------------------------------------------------------------
58
+ // Colour utilities (pure math, zero deps)
59
+ // ---------------------------------------------------------------------------
60
+ function hexToRgb(hex) {
61
+ const h = hex.replace('#', '').slice(0, 6);
62
+ return [parseInt(h.slice(0, 2), 16), parseInt(h.slice(2, 4), 16), parseInt(h.slice(4, 6), 16)];
63
+ }
64
+ function rgbToHex(r, g, b) {
65
+ return '#' + [r, g, b].map(v => Math.round(Math.max(0, Math.min(255, v))).toString(16).padStart(2, '0')).join('');
66
+ }
67
+ function rgbToHsl(r, g, b) {
68
+ r /= 255;
69
+ g /= 255;
70
+ b /= 255;
71
+ const max = Math.max(r, g, b);
72
+ const min = Math.min(r, g, b);
73
+ const l = (max + min) / 2;
74
+ if (max === min)
75
+ return [0, 0, l];
76
+ const d = max - min;
77
+ const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
78
+ let h = 0;
79
+ if (max === r)
80
+ h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
81
+ else if (max === g)
82
+ h = ((b - r) / d + 2) / 6;
83
+ else
84
+ h = ((r - g) / d + 4) / 6;
85
+ return [h, s, l];
86
+ }
87
+ function hslToRgb(h, s, l) {
88
+ if (s === 0) {
89
+ const v = Math.round(l * 255);
90
+ return [v, v, v];
91
+ }
92
+ const hue2rgb = (p, q, t) => {
93
+ if (t < 0)
94
+ t += 1;
95
+ if (t > 1)
96
+ t -= 1;
97
+ if (t < 1 / 6)
98
+ return p + (q - p) * 6 * t;
99
+ if (t < 1 / 2)
100
+ return q;
101
+ if (t < 2 / 3)
102
+ return p + (q - p) * (2 / 3 - t) * 6;
103
+ return p;
104
+ };
105
+ const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
106
+ const p = 2 * l - q;
107
+ return [Math.round(hue2rgb(p, q, h + 1 / 3) * 255), Math.round(hue2rgb(p, q, h) * 255), Math.round(hue2rgb(p, q, h - 1 / 3) * 255)];
108
+ }
109
+ // Rotate a hex colour's hue by 180 degrees (complementary).
110
+ function complementaryHex(hex) {
111
+ const [r, g, b] = hexToRgb(hex);
112
+ const [h, s, l] = rgbToHsl(r, g, b);
113
+ const [cr, cg, cb] = hslToRgb((h + 0.5) % 1, s, l);
114
+ return rgbToHex(cr, cg, cb);
115
+ }
116
+ // Relative luminance (WCAG 2.x formula, 0 = black, 1 = white).
117
+ function relativeLuminance(hex) {
118
+ const [r, g, b] = hexToRgb(hex);
119
+ const srgb = [r, g, b].map(v => {
120
+ v /= 255;
121
+ return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
122
+ });
123
+ return 0.2126 * srgb[0] + 0.7152 * srgb[1] + 0.0722 * srgb[2];
124
+ }
125
+ // Build the libero alternate kit from the main kit using complementary colours. Every colour in the
126
+ // pattern and the brand is hue-rotated 180 degrees; the chest-number fill/outline are picked for
127
+ // readability against the new primary colour (dark number on light, light number on dark).
128
+ function computeComplementaryJersey(main) {
129
+ const compColors = main.colors.map(c => complementaryHex(c));
130
+ const lum = relativeLuminance(compColors[0]);
131
+ return {
132
+ // Locked fields: inherited from main
133
+ clothing: main.clothing,
134
+ font: main.font,
135
+ brand: main.brand,
136
+ numberSpacing: main.numberSpacing,
137
+ numberSize: main.numberSize,
138
+ brandSize: main.brandSize,
139
+ badgeSize: main.badgeSize,
140
+ // Editable fields: complementary-derived
141
+ pattern: main.pattern,
142
+ colors: compColors,
143
+ numberColor: lum > 0.4 ? '#1a1a1a' : '#ffffff',
144
+ numberOutline: lum > 0.4 ? '#ffffff' : '#1a1a1a',
145
+ numberOutlineEnabled: main.numberOutlineEnabled,
146
+ brandColor1: complementaryHex(main.brandColor1),
147
+ brandColor2: complementaryHex(main.brandColor2)
148
+ };
149
+ }
150
+ // Merge a stored alternate (partial, editable fields only) with the main kit's locked fields to
151
+ // produce a full JerseyConfig for rendering.
152
+ function mergeAlternateJersey(main, alt) {
153
+ return {
154
+ clothing: main.clothing,
155
+ font: main.font,
156
+ brand: main.brand,
157
+ numberSpacing: main.numberSpacing,
158
+ numberSize: main.numberSize,
159
+ brandSize: main.brandSize,
160
+ badgeSize: main.badgeSize,
161
+ pattern: alt.pattern,
162
+ colors: alt.colors,
163
+ numberColor: alt.numberColor,
164
+ numberOutline: alt.numberOutline,
165
+ numberOutlineEnabled: alt.numberOutlineEnabled,
166
+ brandColor1: alt.brandColor1,
167
+ brandColor2: alt.brandColor2
168
+ };
169
+ }
@@ -413,6 +413,128 @@ export declare const TeamInputSchema: z.ZodObject<{
413
413
  }>>;
414
414
  brandColor1: z.ZodDefault<z.ZodString>;
415
415
  brandColor2: z.ZodDefault<z.ZodString>;
416
+ brandSize: z.ZodDefault<z.ZodNumber>;
417
+ badgeSize: z.ZodDefault<z.ZodNumber>;
418
+ }, z.core.$strip>>;
419
+ alternateJerseyConfig: z.ZodOptional<z.ZodObject<{
420
+ pattern: z.ZodEnum<{
421
+ solid: "solid";
422
+ verticalStripes: "verticalStripes";
423
+ verticalBars: "verticalBars";
424
+ pinstripes: "pinstripes";
425
+ hoops: "hoops";
426
+ checkered: "checkered";
427
+ diagonalSash: "diagonalSash";
428
+ splitHalves: "splitHalves";
429
+ chevron: "chevron";
430
+ shoulderYoke: "shoulderYoke";
431
+ sidePanels: "sidePanels";
432
+ centerBand: "centerBand";
433
+ gradientFade: "gradientFade";
434
+ twoToneSplit: "twoToneSplit";
435
+ }>;
436
+ colors: z.ZodArray<z.ZodString>;
437
+ numberColor: z.ZodString;
438
+ numberOutline: z.ZodString;
439
+ numberOutlineEnabled: z.ZodDefault<z.ZodBoolean>;
440
+ brandColor1: z.ZodDefault<z.ZodString>;
441
+ brandColor2: z.ZodDefault<z.ZodString>;
442
+ }, z.core.$strip>>;
443
+ badgeConfig: z.ZodOptional<z.ZodObject<{
444
+ layers: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
445
+ x: z.ZodNumber;
446
+ y: z.ZodNumber;
447
+ size: z.ZodNumber;
448
+ rotation: z.ZodNumber;
449
+ type: z.ZodLiteral<"shape">;
450
+ shape: z.ZodString;
451
+ colors: z.ZodArray<z.ZodString>;
452
+ }, z.core.$strip>, z.ZodObject<{
453
+ x: z.ZodNumber;
454
+ y: z.ZodNumber;
455
+ size: z.ZodNumber;
456
+ rotation: z.ZodNumber;
457
+ type: z.ZodLiteral<"icon">;
458
+ icon: z.ZodEnum<{
459
+ star: "star";
460
+ crown: "crown";
461
+ bolt: "bolt";
462
+ fire: "fire";
463
+ heart: "heart";
464
+ gem: "gem";
465
+ skull: "skull";
466
+ ghost: "ghost";
467
+ anchor: "anchor";
468
+ compass: "compass";
469
+ sun: "sun";
470
+ moon: "moon";
471
+ snowflake: "snowflake";
472
+ leaf: "leaf";
473
+ seedling: "seedling";
474
+ tree: "tree";
475
+ mountain: "mountain";
476
+ water: "water";
477
+ wind: "wind";
478
+ meteor: "meteor";
479
+ rocket: "rocket";
480
+ bell: "bell";
481
+ flag: "flag";
482
+ feather: "feather";
483
+ "shield-halved": "shield-halved";
484
+ "chess-knight": "chess-knight";
485
+ "chess-rook": "chess-rook";
486
+ hammer: "hammer";
487
+ crosshairs: "crosshairs";
488
+ medal: "medal";
489
+ trophy: "trophy";
490
+ award: "award";
491
+ volleyball: "volleyball";
492
+ dragon: "dragon";
493
+ cat: "cat";
494
+ crow: "crow";
495
+ turtle: "turtle";
496
+ unicorn: "unicorn";
497
+ horse: "horse";
498
+ dove: "dove";
499
+ fish: "fish";
500
+ paw: "paw";
501
+ spider: "spider";
502
+ otter: "otter";
503
+ frog: "frog";
504
+ dog: "dog";
505
+ }>;
506
+ color: z.ZodString;
507
+ }, z.core.$strip>, z.ZodObject<{
508
+ x: z.ZodNumber;
509
+ y: z.ZodNumber;
510
+ size: z.ZodNumber;
511
+ rotation: z.ZodNumber;
512
+ type: z.ZodLiteral<"text">;
513
+ text: z.ZodString;
514
+ font: z.ZodEnum<{
515
+ block: "block";
516
+ sans: "sans";
517
+ wide: "wide";
518
+ mono: "mono";
519
+ serif: "serif";
520
+ permanentMarker: "permanentMarker";
521
+ kaushanScript: "kaushanScript";
522
+ russoOne: "russoOne";
523
+ teko: "teko";
524
+ saira: "saira";
525
+ michroma: "michroma";
526
+ zillaSlab: "zillaSlab";
527
+ changaOne: "changaOne";
528
+ stardosStencil: "stardosStencil";
529
+ wallpoet: "wallpoet";
530
+ orbitron: "orbitron";
531
+ tourney: "tourney";
532
+ bebasNeue: "bebasNeue";
533
+ anton: "anton";
534
+ jersey25: "jersey25";
535
+ }>;
536
+ color: z.ZodString;
537
+ }, z.core.$strip>], "type">>;
416
538
  }, z.core.$strip>>;
417
539
  }, z.core.$strip>;
418
540
  export type TeamInput = z.infer<typeof TeamInputSchema>;
@@ -6,6 +6,7 @@ const player_1 = require("../../player");
6
6
  const country_1 = require("../../country");
7
7
  const tactics_z_1 = require("./tactics.z");
8
8
  const jersey_1 = require("../jersey");
9
+ const badge_1 = require("../badge");
9
10
  const playerInstanceSchema = zod_1.z.custom((v) => v instanceof player_1.Player, {
10
11
  message: 'INVALID_PLAYER_INSTANCE'
11
12
  });
@@ -22,7 +23,9 @@ exports.TeamInputSchema = zod_1.z.object({
22
23
  country: countrySchema,
23
24
  legacyFlagCountry: countrySchema.optional(),
24
25
  tactics: tactics_z_1.TacticsInputSchema.optional(),
25
- jerseyConfig: jersey_1.JerseySchema.optional()
26
+ jerseyConfig: jersey_1.JerseySchema.optional(),
27
+ alternateJerseyConfig: jersey_1.AlternateJerseySchema.optional(),
28
+ badgeConfig: badge_1.BadgeSchema.optional()
26
29
  }).superRefine((data, ctx) => {
27
30
  const ids = data.roster.map(p => p.id);
28
31
  if (new Set(ids).size !== ids.length) {
@@ -1,7 +1,8 @@
1
1
  import { Player } from '../player';
2
2
  import { Country } from '../country';
3
3
  import { Tactics } from './tactics';
4
- import type { JerseyConfig } from './jersey';
4
+ import type { JerseyConfig, AlternateJerseyConfig } from './jersey';
5
+ import type { BadgeConfig } from './badge';
5
6
  export declare class Team {
6
7
  readonly id: string;
7
8
  readonly roster: Player[];
@@ -12,6 +13,8 @@ export declare class Team {
12
13
  readonly country: Country;
13
14
  readonly legacyFlagCountry?: Country;
14
15
  readonly jerseyConfig?: JerseyConfig;
16
+ readonly alternateJerseyConfig?: AlternateJerseyConfig;
17
+ readonly badgeConfig?: BadgeConfig;
15
18
  private _rating;
16
19
  static create(input: unknown): Team;
17
20
  private constructor();
@@ -19,7 +19,7 @@ class Team {
19
19
  tactics: result.data.tactics != null ? tactics_1.Tactics.create(result.data.tactics) : undefined
20
20
  });
21
21
  }
22
- constructor({ id, rating, name, shortName, divisionId, country, legacyFlagCountry, roster, tactics, jerseyConfig }) {
22
+ constructor({ id, rating, name, shortName, divisionId, country, legacyFlagCountry, roster, tactics, jerseyConfig, alternateJerseyConfig, badgeConfig }) {
23
23
  this.id = id;
24
24
  this._rating = rating;
25
25
  this.roster = roster;
@@ -30,6 +30,8 @@ class Team {
30
30
  this.country = country;
31
31
  this.legacyFlagCountry = legacyFlagCountry;
32
32
  this.jerseyConfig = jerseyConfig;
33
+ this.alternateJerseyConfig = alternateJerseyConfig;
34
+ this.badgeConfig = badgeConfig;
33
35
  }
34
36
  get rating() {
35
37
  return this._rating;
@@ -1,4 +1,4 @@
1
- import { BaseConfig, BoxScore, DataProps, DeclineStatus, JerseyConfig, Division as _Division, League as _League, Match as _Match, MatchSet as _MatchSet, Player as _Player, PlayerPosition, Qualifier as _Qualifier, QualifierMatch as _QualifierMatch, Rally as _Rally, RallyEvent as _RallyEvent, PointBreakdown, RallyMetrics, Season as _Season, Standing as _Standing, Team as _Team, Tournament as _Tournament, TournamentMatch as _TournamentMatch, National as _National, NationalMatch as _NationalMatch, Country as _Country, DefenceFormation, LineupFunction, CourtPosition, ConditionLogic, EnergyBand, MatchForfeitType, PerformanceStats, PinchCondition, RotationSystemEnum, SubBackMode, SubBand } from '../service';
1
+ import { BadgeConfig, BaseConfig, BoxScore, DataProps, DeclineStatus, JerseyConfig, Division as _Division, League as _League, Match as _Match, MatchSet as _MatchSet, Player as _Player, PlayerPosition, Qualifier as _Qualifier, QualifierMatch as _QualifierMatch, Rally as _Rally, RallyEvent as _RallyEvent, PointBreakdown, RallyMetrics, Season as _Season, Standing as _Standing, Team as _Team, Tournament as _Tournament, TournamentMatch as _TournamentMatch, National as _National, NationalMatch as _NationalMatch, Country as _Country, DefenceFormation, LineupFunction, CourtPosition, ConditionLogic, EnergyBand, MatchForfeitType, PerformanceStats, PinchCondition, RotationSystemEnum, SubBackMode, SubBand } from '../service';
2
2
  export * from './tactics-player-refs';
3
3
  export type Rally = DataProps<_Rally> & {
4
4
  homePlayerPosition: PlayerPosition[];
@@ -85,6 +85,7 @@ export type Player = Omit<DataProps<_Player>, 'stats' | 'birthAge' | 'birthItera
85
85
  nickname?: string;
86
86
  jerseyConfig?: JerseyConfig;
87
87
  championBadge?: ChampionBadgeSpec;
88
+ teamBadge?: BadgeConfig;
88
89
  nationalFlagAlpha2?: string;
89
90
  };
90
91
  export interface StartingLineup {
@@ -196,8 +197,9 @@ export type Team = Omit<DataProps<_Team>, 'roster' | '_rating' | 'rating' | 'tac
196
197
  nationalManager?: {
197
198
  displayName: string;
198
199
  teamId: string;
199
- teamShortName: string;
200
+ teamName: string;
200
201
  };
202
+ teamBadge?: BadgeConfig;
201
203
  };
202
204
  export type Standing = DataProps<_Standing> & {
203
205
  position: number;
@@ -1,4 +1,4 @@
1
- import { AuthIdentityModel, AuthSessionModel, AuthUserModel, BoxScoreModel, CoachModel, ScoutModel, PhysicianModel, PhysiotherapistModel, BoxScoreTotalsModel, CompetitionChampionModel, JerseyBadgeModel, CurrencyTransactionModel, GachaPityModel, GachaPullHistoryModel, WishlistModel, UserSettingsModel, UserAchievementsModel, UserDeviceTokenModel, BasePositionPresetModel, CompetitionMatchModel, CompetitionMVPModel, CompetitionModel, CompetitionStandingsMatchModel, CompetitionStandingsModel, CompetitionTeamsModel, CountryModel, DivisionModel, DivisionSeasonModel, IterationModel, LeagueModel, MatchModel, MatchRatingModel, MatchResultModel, MatchSetModel, PerformanceStatsModel, PlayerModel, PlayerImprovementLogModel, PlayerDeclineLogModel, PlayerTeamModel, RetiredPlayerModel, PromotionMatchModel, FriendlyModel, RegionQualifierModel, NationalCountryModel, NationalTeamModel, NationalTeamClaimModel, WnlSquadModel, WnlCallupModel, WnlSeasonModel, RallyModel, MatchInputSnapshotModel, TacticsModel, TeamJerseyModel, LineupPresetModel, MatchPresetModel, EventModel, EventCompetitionModel, EventSquadModel, EventPackModel, EventPackPlayerModel, EventResultModel, EventBotTeamModel, TeamModel, TeamReplacementModel, UserCurrencyModel, UserPlayerProgressModel, UserPullGrantModel, PremiumGrantModel, UserTeamModel, VPERModel, NotificationModel, AppConfigModel, LegacyTeamFlagModel } from './models';
1
+ import { AuthIdentityModel, AuthSessionModel, AuthUserModel, BoxScoreModel, CoachModel, ScoutModel, PhysicianModel, PhysiotherapistModel, BoxScoreTotalsModel, CompetitionChampionModel, JerseyBadgeModel, CurrencyTransactionModel, GachaPityModel, GachaPullHistoryModel, WishlistModel, UserSettingsModel, UserAchievementsModel, UserDeviceTokenModel, BasePositionPresetModel, CompetitionMatchModel, CompetitionMVPModel, CompetitionModel, CompetitionStandingsMatchModel, CompetitionStandingsModel, CompetitionTeamsModel, CountryModel, DivisionModel, DivisionSeasonModel, IterationModel, LeagueModel, MatchModel, MatchRatingModel, MatchResultModel, MatchSetModel, PerformanceStatsModel, PlayerModel, PlayerImprovementLogModel, PlayerDeclineLogModel, PlayerTeamModel, RetiredPlayerModel, PromotionMatchModel, FriendlyModel, RegionQualifierModel, NationalCountryModel, NationalTeamModel, NationalTeamClaimModel, WnlSquadModel, WnlCallupModel, WnlSeasonModel, RallyModel, MatchInputSnapshotModel, TacticsModel, TeamJerseyModel, TeamBadgeModel, LineupPresetModel, MatchPresetModel, EventModel, EventCompetitionModel, EventSquadModel, EventPackModel, EventPackPlayerModel, EventResultModel, EventBotTeamModel, TeamModel, TeamReplacementModel, UserCurrencyModel, UserPlayerProgressModel, UserPullGrantModel, PremiumGrantModel, UserTeamModel, VPERModel, NotificationModel, AppConfigModel, LegacyTeamFlagModel } from './models';
2
2
  export function initModels(sequelize) {
3
3
  const Coach = CoachModel.initModel(sequelize);
4
4
  const Scout = ScoutModel.initModel(sequelize);
@@ -7,6 +7,7 @@ export function initModels(sequelize) {
7
7
  const CurrencyTransaction = CurrencyTransactionModel.initModel(sequelize);
8
8
  const Tactics = TacticsModel.initModel(sequelize);
9
9
  const TeamJersey = TeamJerseyModel.initModel(sequelize);
10
+ const TeamBadge = TeamBadgeModel.initModel(sequelize);
10
11
  const LineupPreset = LineupPresetModel.initModel(sequelize);
11
12
  const MatchPreset = MatchPresetModel.initModel(sequelize);
12
13
  const Event = EventModel.initModel(sequelize);
@@ -252,6 +253,10 @@ export function initModels(sequelize) {
252
253
  // and the effective-jersey resolver include it, so the simulator's team loads are unchanged.
253
254
  Team.hasOne(TeamJersey, { as: 'TeamJersey', foreignKey: 'team_id' });
254
255
  TeamJersey.belongsTo(Team, { as: 'team', foreignKey: 'team_id' });
256
+ // Saved premium badge. Same rule as TeamJersey: NOT in Team.defaultScope, included explicitly only by the
257
+ // management API (badge editor load), so the simulator's team loads are unchanged.
258
+ Team.hasOne(TeamBadge, { as: 'TeamBadge', foreignKey: 'team_id' });
259
+ TeamBadge.belongsTo(Team, { as: 'team', foreignKey: 'team_id' });
255
260
  // Lineup presets are loaded only by the management API; deliberately NOT in Team.defaultScope so the
256
261
  // simulator's team loads are unchanged (it reads the active config from the mirrored Tactics row).
257
262
  Team.hasMany(LineupPreset, { as: 'lineupPresets', foreignKey: 'team_id' });
@@ -45,6 +45,7 @@ export * from './team';
45
45
  export * from './team-replacement';
46
46
  export * from './tactics';
47
47
  export * from './team-jersey';
48
+ export * from './team-badge';
48
49
  export * from './lineup-preset';
49
50
  export * from './base-position-preset';
50
51
  export * from './premium-grant';
@@ -45,6 +45,7 @@ export * from './team';
45
45
  export * from './team-replacement';
46
46
  export * from './tactics';
47
47
  export * from './team-jersey';
48
+ export * from './team-badge';
48
49
  export * from './lineup-preset';
49
50
  export * from './base-position-preset';
50
51
  export * from './premium-grant';
@@ -0,0 +1,20 @@
1
+ import * as Sequelize from 'sequelize';
2
+ import { Model } from 'sequelize';
3
+ import { TeamId, TeamModel } from '.';
4
+ import { BadgeConfig } from '../../service';
5
+ export interface TeamBadgeAttributes {
6
+ team_id: string;
7
+ config: BadgeConfig;
8
+ }
9
+ export type TeamBadgePk = 'team_id';
10
+ export type TeamBadgeId = TeamBadgeModel[TeamBadgePk];
11
+ export type TeamBadgeCreationAttributes = TeamBadgeAttributes;
12
+ export declare class TeamBadgeModel extends Model<TeamBadgeAttributes, TeamBadgeCreationAttributes> implements TeamBadgeAttributes {
13
+ team_id: string;
14
+ config: BadgeConfig;
15
+ team: TeamModel;
16
+ getTeam: Sequelize.BelongsToGetAssociationMixin<TeamModel>;
17
+ setTeam: Sequelize.BelongsToSetAssociationMixin<TeamModel, TeamId>;
18
+ createTeam: Sequelize.BelongsToCreateAssociationMixin<TeamModel>;
19
+ static initModel(sequelize: Sequelize.Sequelize): typeof TeamBadgeModel;
20
+ }
@@ -0,0 +1,34 @@
1
+ import { DataTypes, Model } from 'sequelize';
2
+ export class TeamBadgeModel extends Model {
3
+ static initModel(sequelize) {
4
+ return TeamBadgeModel.init({
5
+ team_id: {
6
+ type: DataTypes.UUID,
7
+ allowNull: false,
8
+ primaryKey: true,
9
+ references: {
10
+ model: 'Team',
11
+ key: 'team_id'
12
+ }
13
+ },
14
+ config: {
15
+ type: DataTypes.JSONB,
16
+ allowNull: false
17
+ }
18
+ }, {
19
+ sequelize,
20
+ tableName: 'TeamBadge',
21
+ schema: 'public',
22
+ timestamps: false,
23
+ indexes: [
24
+ {
25
+ name: 'TeamBadge_pk',
26
+ unique: true,
27
+ fields: [
28
+ { name: 'team_id' }
29
+ ]
30
+ }
31
+ ]
32
+ });
33
+ }
34
+ }
@@ -1,10 +1,11 @@
1
1
  import * as Sequelize from 'sequelize';
2
2
  import { Model } from 'sequelize';
3
3
  import { TeamId, TeamModel } from '.';
4
- import { JerseyConfig } from '../../service';
4
+ import { JerseyConfig, AlternateJerseyConfig } from '../../service';
5
5
  export interface TeamJerseyAttributes {
6
6
  team_id: string;
7
7
  config: JerseyConfig;
8
+ alternate_config?: AlternateJerseyConfig | null;
8
9
  }
9
10
  export type TeamJerseyPk = 'team_id';
10
11
  export type TeamJerseyId = TeamJerseyModel[TeamJerseyPk];
@@ -12,6 +13,7 @@ export type TeamJerseyCreationAttributes = TeamJerseyAttributes;
12
13
  export declare class TeamJerseyModel extends Model<TeamJerseyAttributes, TeamJerseyCreationAttributes> implements TeamJerseyAttributes {
13
14
  team_id: string;
14
15
  config: JerseyConfig;
16
+ alternate_config?: AlternateJerseyConfig | null;
15
17
  team: TeamModel;
16
18
  getTeam: Sequelize.BelongsToGetAssociationMixin<TeamModel>;
17
19
  setTeam: Sequelize.BelongsToSetAssociationMixin<TeamModel, TeamId>;
@@ -14,6 +14,10 @@ export class TeamJerseyModel extends Model {
14
14
  config: {
15
15
  type: DataTypes.JSONB,
16
16
  allowNull: false
17
+ },
18
+ alternate_config: {
19
+ type: DataTypes.JSONB,
20
+ allowNull: true
17
21
  }
18
22
  }, {
19
23
  sequelize,
@@ -1,6 +1,6 @@
1
1
  import * as Sequelize from 'sequelize';
2
2
  import { Model, Optional } from 'sequelize';
3
- import { CompetitionChampionId, CompetitionChampionModel, CompetitionId, CompetitionModel, CompetitionTeamsId, CompetitionTeamsModel, CountryId, CountryModel, DivisionAttributes, DivisionId, DivisionModel, LegacyTeamFlagModel, MatchId, MatchModel, MatchRatingId, MatchRatingModel, PlayerAttributes, PlayerId, PlayerModel, PlayerTeamId, PlayerTeamModel, RallyId, RallyModel, TacticsAttributes, TacticsId, TacticsModel, TeamJerseyModel } from '.';
3
+ import { CompetitionChampionId, CompetitionChampionModel, CompetitionId, CompetitionModel, CompetitionTeamsId, CompetitionTeamsModel, CountryId, CountryModel, DivisionAttributes, DivisionId, DivisionModel, LegacyTeamFlagModel, MatchId, MatchModel, MatchRatingId, MatchRatingModel, PlayerAttributes, PlayerId, PlayerModel, PlayerTeamId, PlayerTeamModel, RallyId, RallyModel, TacticsAttributes, TacticsId, TacticsModel, TeamJerseyModel, TeamBadgeModel } from '.';
4
4
  export interface TeamAttributes {
5
5
  team_id: string;
6
6
  name: string;
@@ -31,6 +31,8 @@ export declare class TeamModel extends Model<TeamAttributes, TeamCreationAttribu
31
31
  createTactics: Sequelize.HasOneCreateAssociationMixin<TacticsModel>;
32
32
  TeamJersey?: TeamJerseyModel;
33
33
  getTeamJersey: Sequelize.HasOneGetAssociationMixin<TeamJerseyModel>;
34
+ TeamBadge?: TeamBadgeModel;
35
+ getTeamBadge: Sequelize.HasOneGetAssociationMixin<TeamBadgeModel>;
34
36
  country: CountryModel;
35
37
  getCountry: Sequelize.BelongsToGetAssociationMixin<CountryModel>;
36
38
  setCountry: Sequelize.BelongsToSetAssociationMixin<CountryModel, CountryId>;
@@ -46,7 +46,11 @@ function transformToObject(model, currentIteration, tacticsOverride) {
46
46
  divisionId: model.division_id,
47
47
  // Present only when the caller explicitly included the TeamJersey association (editor / effective-jersey
48
48
  // resolver); undefined on ordinary team loads, which heals to the id-derived default in the UI.
49
- jerseyConfig: model.TeamJersey?.config
49
+ jerseyConfig: model.TeamJersey?.config,
50
+ alternateJerseyConfig: model.TeamJersey?.alternate_config ?? undefined,
51
+ // Present only when the caller explicitly included the TeamBadge association (the badge editor load);
52
+ // undefined on ordinary team loads.
53
+ badgeConfig: model.TeamBadge?.config
50
54
  });
51
55
  }
52
56
  export { transformToObject as transformToTeam, transformToAttributes as transformFromTeam };