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.
- package/dist/cjs/src/api/index.d.ts +4 -2
- package/dist/cjs/src/data/init-models.js +5 -0
- package/dist/cjs/src/data/models/index.d.ts +1 -0
- package/dist/cjs/src/data/models/index.js +1 -0
- package/dist/cjs/src/data/models/team-badge.d.ts +20 -0
- package/dist/cjs/src/data/models/team-badge.js +38 -0
- package/dist/cjs/src/data/models/team-jersey.d.ts +3 -1
- package/dist/cjs/src/data/models/team-jersey.js +4 -0
- package/dist/cjs/src/data/models/team.d.ts +3 -1
- package/dist/cjs/src/data/transformers/team.js +5 -1
- package/dist/cjs/src/service/team/badge.d.ts +301 -0
- package/dist/cjs/src/service/team/badge.js +93 -0
- package/dist/cjs/src/service/team/index.d.ts +2 -0
- package/dist/cjs/src/service/team/index.js +2 -0
- package/dist/cjs/src/service/team/jersey-defaults.d.ts +13 -0
- package/dist/cjs/src/service/team/jersey-defaults.js +81 -0
- package/dist/cjs/src/service/team/jersey.d.ts +31 -0
- package/dist/cjs/src/service/team/jersey.js +137 -1
- package/dist/cjs/src/service/team/schemas/team.z.d.ts +122 -0
- package/dist/cjs/src/service/team/schemas/team.z.js +4 -1
- package/dist/cjs/src/service/team/team.d.ts +4 -1
- package/dist/cjs/src/service/team/team.js +3 -1
- package/dist/esm/src/api/index.d.ts +4 -2
- package/dist/esm/src/data/init-models.js +6 -1
- package/dist/esm/src/data/models/index.d.ts +1 -0
- package/dist/esm/src/data/models/index.js +1 -0
- package/dist/esm/src/data/models/team-badge.d.ts +20 -0
- package/dist/esm/src/data/models/team-badge.js +34 -0
- package/dist/esm/src/data/models/team-jersey.d.ts +3 -1
- package/dist/esm/src/data/models/team-jersey.js +4 -0
- package/dist/esm/src/data/models/team.d.ts +3 -1
- package/dist/esm/src/data/transformers/team.js +5 -1
- package/dist/esm/src/service/team/badge.d.ts +301 -0
- package/dist/esm/src/service/team/badge.js +90 -0
- package/dist/esm/src/service/team/index.d.ts +2 -0
- package/dist/esm/src/service/team/index.js +2 -0
- package/dist/esm/src/service/team/jersey-defaults.d.ts +13 -0
- package/dist/esm/src/service/team/jersey-defaults.js +77 -0
- package/dist/esm/src/service/team/jersey.d.ts +31 -0
- package/dist/esm/src/service/team/jersey.js +132 -0
- package/dist/esm/src/service/team/schemas/team.z.d.ts +122 -0
- package/dist/esm/src/service/team/schemas/team.z.js +5 -2
- package/dist/esm/src/service/team/team.d.ts +4 -1
- package/dist/esm/src/service/team/team.js +3 -1
- package/package.json +1 -1
|
@@ -26,5 +26,137 @@ export const JerseySchema = z.object({
|
|
|
26
26
|
// configs saved before it stay valid.
|
|
27
27
|
brand: z.enum(['none', 'sigma', 'person-soccer', 'feather-pointed', 'paw-claws', 'narwhal', 'horseshoe', 'spider-black-widow', 'wreath-laurel', 'omega', 'trillium']).default('none'),
|
|
28
28
|
brandColor1: hexColor.default('#ffffff'),
|
|
29
|
+
brandColor2: hexColor.default('#1e293b'),
|
|
30
|
+
// Chest-element heights in avatar-svg units, on the y=297 chest line. The brand sits at x=90 and the team badge
|
|
31
|
+
// at x=191, with the (non-editable) champion badge between them at x=140.5 spanning 116.5..164.5, so either one
|
|
32
|
+
// starts touching it past about 52. The range allows more than that on purpose: most teams have no champion
|
|
33
|
+
// badge, and the editor preview shows the overlap for the ones that do. Defaulted to the sizes both were fixed
|
|
34
|
+
// at before, so configs saved earlier stay valid and look unchanged.
|
|
35
|
+
brandSize: z.number().min(16).max(64).default(29),
|
|
36
|
+
badgeSize: z.number().min(16).max(64).default(48)
|
|
37
|
+
});
|
|
38
|
+
// The alternate (libero) kit stores only the fields the premium editor allows changing. Locked fields (clothing,
|
|
39
|
+
// font, brand icon, numberSpacing, numberSize, brandSize, badgeSize) are always inherited from the main kit at
|
|
40
|
+
// render time.
|
|
41
|
+
export const AlternateJerseySchema = z.object({
|
|
42
|
+
pattern: JerseySchema.shape.pattern,
|
|
43
|
+
colors: JerseySchema.shape.colors,
|
|
44
|
+
numberColor: hexColor,
|
|
45
|
+
numberOutline: hexColor,
|
|
46
|
+
numberOutlineEnabled: z.boolean().default(true),
|
|
47
|
+
brandColor1: hexColor.default('#ffffff'),
|
|
29
48
|
brandColor2: hexColor.default('#1e293b')
|
|
30
49
|
});
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
// Colour utilities (pure math, zero deps)
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
function hexToRgb(hex) {
|
|
54
|
+
const h = hex.replace('#', '').slice(0, 6);
|
|
55
|
+
return [parseInt(h.slice(0, 2), 16), parseInt(h.slice(2, 4), 16), parseInt(h.slice(4, 6), 16)];
|
|
56
|
+
}
|
|
57
|
+
function rgbToHex(r, g, b) {
|
|
58
|
+
return '#' + [r, g, b].map(v => Math.round(Math.max(0, Math.min(255, v))).toString(16).padStart(2, '0')).join('');
|
|
59
|
+
}
|
|
60
|
+
function rgbToHsl(r, g, b) {
|
|
61
|
+
r /= 255;
|
|
62
|
+
g /= 255;
|
|
63
|
+
b /= 255;
|
|
64
|
+
const max = Math.max(r, g, b);
|
|
65
|
+
const min = Math.min(r, g, b);
|
|
66
|
+
const l = (max + min) / 2;
|
|
67
|
+
if (max === min)
|
|
68
|
+
return [0, 0, l];
|
|
69
|
+
const d = max - min;
|
|
70
|
+
const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
71
|
+
let h = 0;
|
|
72
|
+
if (max === r)
|
|
73
|
+
h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
|
|
74
|
+
else if (max === g)
|
|
75
|
+
h = ((b - r) / d + 2) / 6;
|
|
76
|
+
else
|
|
77
|
+
h = ((r - g) / d + 4) / 6;
|
|
78
|
+
return [h, s, l];
|
|
79
|
+
}
|
|
80
|
+
function hslToRgb(h, s, l) {
|
|
81
|
+
if (s === 0) {
|
|
82
|
+
const v = Math.round(l * 255);
|
|
83
|
+
return [v, v, v];
|
|
84
|
+
}
|
|
85
|
+
const hue2rgb = (p, q, t) => {
|
|
86
|
+
if (t < 0)
|
|
87
|
+
t += 1;
|
|
88
|
+
if (t > 1)
|
|
89
|
+
t -= 1;
|
|
90
|
+
if (t < 1 / 6)
|
|
91
|
+
return p + (q - p) * 6 * t;
|
|
92
|
+
if (t < 1 / 2)
|
|
93
|
+
return q;
|
|
94
|
+
if (t < 2 / 3)
|
|
95
|
+
return p + (q - p) * (2 / 3 - t) * 6;
|
|
96
|
+
return p;
|
|
97
|
+
};
|
|
98
|
+
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
99
|
+
const p = 2 * l - q;
|
|
100
|
+
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)];
|
|
101
|
+
}
|
|
102
|
+
// Rotate a hex colour's hue by 180 degrees (complementary).
|
|
103
|
+
export function complementaryHex(hex) {
|
|
104
|
+
const [r, g, b] = hexToRgb(hex);
|
|
105
|
+
const [h, s, l] = rgbToHsl(r, g, b);
|
|
106
|
+
const [cr, cg, cb] = hslToRgb((h + 0.5) % 1, s, l);
|
|
107
|
+
return rgbToHex(cr, cg, cb);
|
|
108
|
+
}
|
|
109
|
+
// Relative luminance (WCAG 2.x formula, 0 = black, 1 = white).
|
|
110
|
+
export function relativeLuminance(hex) {
|
|
111
|
+
const [r, g, b] = hexToRgb(hex);
|
|
112
|
+
const srgb = [r, g, b].map(v => {
|
|
113
|
+
v /= 255;
|
|
114
|
+
return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
|
|
115
|
+
});
|
|
116
|
+
return 0.2126 * srgb[0] + 0.7152 * srgb[1] + 0.0722 * srgb[2];
|
|
117
|
+
}
|
|
118
|
+
// Build the libero alternate kit from the main kit using complementary colours. Every colour in the
|
|
119
|
+
// pattern and the brand is hue-rotated 180 degrees; the chest-number fill/outline are picked for
|
|
120
|
+
// readability against the new primary colour (dark number on light, light number on dark).
|
|
121
|
+
export function computeComplementaryJersey(main) {
|
|
122
|
+
const compColors = main.colors.map(c => complementaryHex(c));
|
|
123
|
+
const lum = relativeLuminance(compColors[0]);
|
|
124
|
+
return {
|
|
125
|
+
// Locked fields: inherited from main
|
|
126
|
+
clothing: main.clothing,
|
|
127
|
+
font: main.font,
|
|
128
|
+
brand: main.brand,
|
|
129
|
+
numberSpacing: main.numberSpacing,
|
|
130
|
+
numberSize: main.numberSize,
|
|
131
|
+
brandSize: main.brandSize,
|
|
132
|
+
badgeSize: main.badgeSize,
|
|
133
|
+
// Editable fields: complementary-derived
|
|
134
|
+
pattern: main.pattern,
|
|
135
|
+
colors: compColors,
|
|
136
|
+
numberColor: lum > 0.4 ? '#1a1a1a' : '#ffffff',
|
|
137
|
+
numberOutline: lum > 0.4 ? '#ffffff' : '#1a1a1a',
|
|
138
|
+
numberOutlineEnabled: main.numberOutlineEnabled,
|
|
139
|
+
brandColor1: complementaryHex(main.brandColor1),
|
|
140
|
+
brandColor2: complementaryHex(main.brandColor2)
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
// Merge a stored alternate (partial, editable fields only) with the main kit's locked fields to
|
|
144
|
+
// produce a full JerseyConfig for rendering.
|
|
145
|
+
export function mergeAlternateJersey(main, alt) {
|
|
146
|
+
return {
|
|
147
|
+
clothing: main.clothing,
|
|
148
|
+
font: main.font,
|
|
149
|
+
brand: main.brand,
|
|
150
|
+
numberSpacing: main.numberSpacing,
|
|
151
|
+
numberSize: main.numberSize,
|
|
152
|
+
brandSize: main.brandSize,
|
|
153
|
+
badgeSize: main.badgeSize,
|
|
154
|
+
pattern: alt.pattern,
|
|
155
|
+
colors: alt.colors,
|
|
156
|
+
numberColor: alt.numberColor,
|
|
157
|
+
numberOutline: alt.numberOutline,
|
|
158
|
+
numberOutlineEnabled: alt.numberOutlineEnabled,
|
|
159
|
+
brandColor1: alt.brandColor1,
|
|
160
|
+
brandColor2: alt.brandColor2
|
|
161
|
+
};
|
|
162
|
+
}
|
|
@@ -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>;
|
|
@@ -2,7 +2,8 @@ import { z } from 'zod';
|
|
|
2
2
|
import { Player } from '../../player';
|
|
3
3
|
import { Country } from '../../country';
|
|
4
4
|
import { TacticsInputSchema } from './tactics.z';
|
|
5
|
-
import { JerseySchema } from '../jersey';
|
|
5
|
+
import { JerseySchema, AlternateJerseySchema } from '../jersey';
|
|
6
|
+
import { BadgeSchema } from '../badge';
|
|
6
7
|
const playerInstanceSchema = z.custom((v) => v instanceof Player, {
|
|
7
8
|
message: 'INVALID_PLAYER_INSTANCE'
|
|
8
9
|
});
|
|
@@ -19,7 +20,9 @@ export const TeamInputSchema = z.object({
|
|
|
19
20
|
country: countrySchema,
|
|
20
21
|
legacyFlagCountry: countrySchema.optional(),
|
|
21
22
|
tactics: TacticsInputSchema.optional(),
|
|
22
|
-
jerseyConfig: JerseySchema.optional()
|
|
23
|
+
jerseyConfig: JerseySchema.optional(),
|
|
24
|
+
alternateJerseyConfig: AlternateJerseySchema.optional(),
|
|
25
|
+
badgeConfig: BadgeSchema.optional()
|
|
23
26
|
}).superRefine((data, ctx) => {
|
|
24
27
|
const ids = data.roster.map(p => p.id);
|
|
25
28
|
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();
|
|
@@ -16,7 +16,7 @@ export class Team {
|
|
|
16
16
|
tactics: result.data.tactics != null ? Tactics.create(result.data.tactics) : undefined
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
|
-
constructor({ id, rating, name, shortName, divisionId, country, legacyFlagCountry, roster, tactics, jerseyConfig }) {
|
|
19
|
+
constructor({ id, rating, name, shortName, divisionId, country, legacyFlagCountry, roster, tactics, jerseyConfig, alternateJerseyConfig, badgeConfig }) {
|
|
20
20
|
this.id = id;
|
|
21
21
|
this._rating = rating;
|
|
22
22
|
this.roster = roster;
|
|
@@ -27,6 +27,8 @@ export class Team {
|
|
|
27
27
|
this.country = country;
|
|
28
28
|
this.legacyFlagCountry = legacyFlagCountry;
|
|
29
29
|
this.jerseyConfig = jerseyConfig;
|
|
30
|
+
this.alternateJerseyConfig = alternateJerseyConfig;
|
|
31
|
+
this.badgeConfig = badgeConfig;
|
|
30
32
|
}
|
|
31
33
|
get rating() {
|
|
32
34
|
return this._rating;
|