volleyballsimtypes 0.0.527 → 0.0.529

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 (39) hide show
  1. package/dist/cjs/src/api/index.d.ts +3 -1
  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.d.ts +3 -1
  8. package/dist/cjs/src/data/transformers/team.js +4 -1
  9. package/dist/cjs/src/service/team/badge.d.ts +304 -0
  10. package/dist/cjs/src/service/team/badge.js +93 -0
  11. package/dist/cjs/src/service/team/index.d.ts +1 -0
  12. package/dist/cjs/src/service/team/index.js +1 -0
  13. package/dist/cjs/src/service/team/jersey-defaults.js +3 -1
  14. package/dist/cjs/src/service/team/jersey.d.ts +2 -0
  15. package/dist/cjs/src/service/team/jersey.js +14 -2
  16. package/dist/cjs/src/service/team/schemas/team.z.d.ts +99 -0
  17. package/dist/cjs/src/service/team/schemas/team.z.js +3 -1
  18. package/dist/cjs/src/service/team/team.d.ts +2 -0
  19. package/dist/cjs/src/service/team/team.js +2 -1
  20. package/dist/esm/src/api/index.d.ts +3 -1
  21. package/dist/esm/src/data/init-models.js +6 -1
  22. package/dist/esm/src/data/models/index.d.ts +1 -0
  23. package/dist/esm/src/data/models/index.js +1 -0
  24. package/dist/esm/src/data/models/team-badge.d.ts +20 -0
  25. package/dist/esm/src/data/models/team-badge.js +34 -0
  26. package/dist/esm/src/data/models/team.d.ts +3 -1
  27. package/dist/esm/src/data/transformers/team.js +4 -1
  28. package/dist/esm/src/service/team/badge.d.ts +304 -0
  29. package/dist/esm/src/service/team/badge.js +90 -0
  30. package/dist/esm/src/service/team/index.d.ts +1 -0
  31. package/dist/esm/src/service/team/index.js +1 -0
  32. package/dist/esm/src/service/team/jersey-defaults.js +3 -1
  33. package/dist/esm/src/service/team/jersey.d.ts +2 -0
  34. package/dist/esm/src/service/team/jersey.js +14 -2
  35. package/dist/esm/src/service/team/schemas/team.z.d.ts +99 -0
  36. package/dist/esm/src/service/team/schemas/team.z.js +3 -1
  37. package/dist/esm/src/service/team/team.d.ts +2 -0
  38. package/dist/esm/src/service/team/team.js +2 -1
  39. package/package.json +1 -1
@@ -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 {
@@ -198,6 +199,7 @@ export type Team = Omit<DataProps<_Team>, 'roster' | '_rating' | 'rating' | 'tac
198
199
  teamId: string;
199
200
  teamName: string;
200
201
  };
202
+ teamBadge?: BadgeConfig;
201
203
  };
202
204
  export type Standing = DataProps<_Standing> & {
203
205
  position: number;
@@ -10,6 +10,7 @@ function initModels(sequelize) {
10
10
  const CurrencyTransaction = models_1.CurrencyTransactionModel.initModel(sequelize);
11
11
  const Tactics = models_1.TacticsModel.initModel(sequelize);
12
12
  const TeamJersey = models_1.TeamJerseyModel.initModel(sequelize);
13
+ const TeamBadge = models_1.TeamBadgeModel.initModel(sequelize);
13
14
  const LineupPreset = models_1.LineupPresetModel.initModel(sequelize);
14
15
  const MatchPreset = models_1.MatchPresetModel.initModel(sequelize);
15
16
  const Event = models_1.EventModel.initModel(sequelize);
@@ -255,6 +256,10 @@ function initModels(sequelize) {
255
256
  // and the effective-jersey resolver include it, so the simulator's team loads are unchanged.
256
257
  Team.hasOne(TeamJersey, { as: 'TeamJersey', foreignKey: 'team_id' });
257
258
  TeamJersey.belongsTo(Team, { as: 'team', foreignKey: 'team_id' });
259
+ // Saved premium badge. Same rule as TeamJersey: NOT in Team.defaultScope, included explicitly only by the
260
+ // management API (badge editor load), so the simulator's team loads are unchanged.
261
+ Team.hasOne(TeamBadge, { as: 'TeamBadge', foreignKey: 'team_id' });
262
+ TeamBadge.belongsTo(Team, { as: 'team', foreignKey: 'team_id' });
258
263
  // Lineup presets are loaded only by the management API; deliberately NOT in Team.defaultScope so the
259
264
  // simulator's team loads are unchanged (it reads the active config from the mirrored Tactics row).
260
265
  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';
@@ -61,6 +61,7 @@ __exportStar(require("./team"), exports);
61
61
  __exportStar(require("./team-replacement"), exports);
62
62
  __exportStar(require("./tactics"), exports);
63
63
  __exportStar(require("./team-jersey"), exports);
64
+ __exportStar(require("./team-badge"), exports);
64
65
  __exportStar(require("./lineup-preset"), exports);
65
66
  __exportStar(require("./base-position-preset"), exports);
66
67
  __exportStar(require("./premium-grant"), exports);
@@ -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,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TeamBadgeModel = void 0;
4
+ const sequelize_1 = require("sequelize");
5
+ class TeamBadgeModel extends sequelize_1.Model {
6
+ static initModel(sequelize) {
7
+ return TeamBadgeModel.init({
8
+ team_id: {
9
+ type: sequelize_1.DataTypes.UUID,
10
+ allowNull: false,
11
+ primaryKey: true,
12
+ references: {
13
+ model: 'Team',
14
+ key: 'team_id'
15
+ }
16
+ },
17
+ config: {
18
+ type: sequelize_1.DataTypes.JSONB,
19
+ allowNull: false
20
+ }
21
+ }, {
22
+ sequelize,
23
+ tableName: 'TeamBadge',
24
+ schema: 'public',
25
+ timestamps: false,
26
+ indexes: [
27
+ {
28
+ name: 'TeamBadge_pk',
29
+ unique: true,
30
+ fields: [
31
+ { name: 'team_id' }
32
+ ]
33
+ }
34
+ ]
35
+ });
36
+ }
37
+ }
38
+ exports.TeamBadgeModel = TeamBadgeModel;
@@ -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>;
@@ -54,6 +54,9 @@ function transformToObject(model, currentIteration, tacticsOverride) {
54
54
  // Present only when the caller explicitly included the TeamJersey association (editor / effective-jersey
55
55
  // resolver); undefined on ordinary team loads, which heals to the id-derived default in the UI.
56
56
  jerseyConfig: model.TeamJersey?.config,
57
- alternateJerseyConfig: model.TeamJersey?.alternate_config ?? undefined
57
+ alternateJerseyConfig: model.TeamJersey?.alternate_config ?? undefined,
58
+ // Present only when the caller explicitly included the TeamBadge association (the badge editor load);
59
+ // undefined on ordinary team loads.
60
+ badgeConfig: model.TeamBadge?.config
58
61
  });
59
62
  }
@@ -0,0 +1,304 @@
1
+ import { z } from 'zod';
2
+ export declare const BADGE_CANVAS = 200;
3
+ export declare const BADGE_ICONS: readonly ["star", "crown", "bolt", "fire", "heart", "gem", "skull", "ghost", "anchor", "compass", "sun", "moon", "snowflake", "leaf", "seedling", "tree", "mountain", "water", "wind", "meteor", "rocket", "bell", "flag", "feather", "shield-halved", "chess-knight", "chess-rook", "hammer", "crosshairs", "medal", "trophy", "award", "volleyball", "dragon", "cat", "crow", "turtle", "unicorn", "horse", "dove", "fish", "paw", "spider", "otter", "frog", "dog", "pear"];
4
+ export type BadgeIconName = typeof BADGE_ICONS[number];
5
+ export declare const BADGE_TEXT_FONTS: readonly ["sans", "wide", "mono", "serif", "block", "permanentMarker", "kaushanScript", "russoOne", "teko", "saira", "michroma", "zillaSlab", "changaOne", "stardosStencil", "wallpoet", "orbitron", "tourney", "bebasNeue", "anton", "jersey25"];
6
+ export type BadgeTextFont = typeof BADGE_TEXT_FONTS[number];
7
+ export declare const BADGE_SHAPES: readonly ["star5-solid", "star5-slim-solid", "star6-solid", "cross-solid", "star5-outline", "star5-slim-outline", "star6-outline", "cross-outline", "pentagon-solid", "hexagon-solid", "octagon-solid", "pentagon-outline", "hexagon-outline", "octagon-outline", "square-solid", "triangle-solid", "diamond-solid", "square-outline", "triangle-outline", "diamond-outline", "rectangle-solid", "burst-solid", "trapezoid-solid", "rectangle-outline", "burst-outline", "trapezoid-outline", "circle-solid", "heptagon-solid", "nonagon-solid", "ellipse-solid", "parallelogram-solid", "heart-solid", "moon-solid", "semicircle-solid", "triangle-right-solid", "triangle-tall-solid", "trapezoid-tall-solid", "kite-solid"];
8
+ export type BadgeShapeName = typeof BADGE_SHAPES[number];
9
+ declare const shapeLayer: z.ZodObject<{
10
+ x: z.ZodNumber;
11
+ y: z.ZodNumber;
12
+ size: z.ZodNumber;
13
+ rotation: z.ZodNumber;
14
+ type: z.ZodLiteral<"shape">;
15
+ shape: z.ZodString;
16
+ colors: z.ZodArray<z.ZodString>;
17
+ }, z.core.$strip>;
18
+ declare const iconLayer: z.ZodObject<{
19
+ x: z.ZodNumber;
20
+ y: z.ZodNumber;
21
+ size: z.ZodNumber;
22
+ rotation: z.ZodNumber;
23
+ type: z.ZodLiteral<"icon">;
24
+ icon: z.ZodEnum<{
25
+ star: "star";
26
+ crown: "crown";
27
+ bolt: "bolt";
28
+ fire: "fire";
29
+ heart: "heart";
30
+ gem: "gem";
31
+ skull: "skull";
32
+ ghost: "ghost";
33
+ anchor: "anchor";
34
+ compass: "compass";
35
+ sun: "sun";
36
+ moon: "moon";
37
+ snowflake: "snowflake";
38
+ leaf: "leaf";
39
+ seedling: "seedling";
40
+ tree: "tree";
41
+ mountain: "mountain";
42
+ water: "water";
43
+ wind: "wind";
44
+ meteor: "meteor";
45
+ rocket: "rocket";
46
+ bell: "bell";
47
+ flag: "flag";
48
+ feather: "feather";
49
+ "shield-halved": "shield-halved";
50
+ "chess-knight": "chess-knight";
51
+ "chess-rook": "chess-rook";
52
+ hammer: "hammer";
53
+ crosshairs: "crosshairs";
54
+ medal: "medal";
55
+ trophy: "trophy";
56
+ award: "award";
57
+ volleyball: "volleyball";
58
+ dragon: "dragon";
59
+ cat: "cat";
60
+ crow: "crow";
61
+ turtle: "turtle";
62
+ unicorn: "unicorn";
63
+ horse: "horse";
64
+ dove: "dove";
65
+ fish: "fish";
66
+ paw: "paw";
67
+ spider: "spider";
68
+ otter: "otter";
69
+ frog: "frog";
70
+ dog: "dog";
71
+ pear: "pear";
72
+ }>;
73
+ color: z.ZodString;
74
+ }, z.core.$strip>;
75
+ declare const textLayer: z.ZodObject<{
76
+ x: z.ZodNumber;
77
+ y: z.ZodNumber;
78
+ size: z.ZodNumber;
79
+ rotation: z.ZodNumber;
80
+ type: z.ZodLiteral<"text">;
81
+ text: z.ZodString;
82
+ font: z.ZodEnum<{
83
+ block: "block";
84
+ sans: "sans";
85
+ wide: "wide";
86
+ mono: "mono";
87
+ serif: "serif";
88
+ permanentMarker: "permanentMarker";
89
+ kaushanScript: "kaushanScript";
90
+ russoOne: "russoOne";
91
+ teko: "teko";
92
+ saira: "saira";
93
+ michroma: "michroma";
94
+ zillaSlab: "zillaSlab";
95
+ changaOne: "changaOne";
96
+ stardosStencil: "stardosStencil";
97
+ wallpoet: "wallpoet";
98
+ orbitron: "orbitron";
99
+ tourney: "tourney";
100
+ bebasNeue: "bebasNeue";
101
+ anton: "anton";
102
+ jersey25: "jersey25";
103
+ }>;
104
+ color: z.ZodString;
105
+ }, z.core.$strip>;
106
+ export declare const BadgeLayerSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
107
+ x: z.ZodNumber;
108
+ y: z.ZodNumber;
109
+ size: z.ZodNumber;
110
+ rotation: z.ZodNumber;
111
+ type: z.ZodLiteral<"shape">;
112
+ shape: z.ZodString;
113
+ colors: z.ZodArray<z.ZodString>;
114
+ }, z.core.$strip>, z.ZodObject<{
115
+ x: z.ZodNumber;
116
+ y: z.ZodNumber;
117
+ size: z.ZodNumber;
118
+ rotation: z.ZodNumber;
119
+ type: z.ZodLiteral<"icon">;
120
+ icon: z.ZodEnum<{
121
+ star: "star";
122
+ crown: "crown";
123
+ bolt: "bolt";
124
+ fire: "fire";
125
+ heart: "heart";
126
+ gem: "gem";
127
+ skull: "skull";
128
+ ghost: "ghost";
129
+ anchor: "anchor";
130
+ compass: "compass";
131
+ sun: "sun";
132
+ moon: "moon";
133
+ snowflake: "snowflake";
134
+ leaf: "leaf";
135
+ seedling: "seedling";
136
+ tree: "tree";
137
+ mountain: "mountain";
138
+ water: "water";
139
+ wind: "wind";
140
+ meteor: "meteor";
141
+ rocket: "rocket";
142
+ bell: "bell";
143
+ flag: "flag";
144
+ feather: "feather";
145
+ "shield-halved": "shield-halved";
146
+ "chess-knight": "chess-knight";
147
+ "chess-rook": "chess-rook";
148
+ hammer: "hammer";
149
+ crosshairs: "crosshairs";
150
+ medal: "medal";
151
+ trophy: "trophy";
152
+ award: "award";
153
+ volleyball: "volleyball";
154
+ dragon: "dragon";
155
+ cat: "cat";
156
+ crow: "crow";
157
+ turtle: "turtle";
158
+ unicorn: "unicorn";
159
+ horse: "horse";
160
+ dove: "dove";
161
+ fish: "fish";
162
+ paw: "paw";
163
+ spider: "spider";
164
+ otter: "otter";
165
+ frog: "frog";
166
+ dog: "dog";
167
+ pear: "pear";
168
+ }>;
169
+ color: z.ZodString;
170
+ }, z.core.$strip>, z.ZodObject<{
171
+ x: z.ZodNumber;
172
+ y: z.ZodNumber;
173
+ size: z.ZodNumber;
174
+ rotation: z.ZodNumber;
175
+ type: z.ZodLiteral<"text">;
176
+ text: z.ZodString;
177
+ font: z.ZodEnum<{
178
+ block: "block";
179
+ sans: "sans";
180
+ wide: "wide";
181
+ mono: "mono";
182
+ serif: "serif";
183
+ permanentMarker: "permanentMarker";
184
+ kaushanScript: "kaushanScript";
185
+ russoOne: "russoOne";
186
+ teko: "teko";
187
+ saira: "saira";
188
+ michroma: "michroma";
189
+ zillaSlab: "zillaSlab";
190
+ changaOne: "changaOne";
191
+ stardosStencil: "stardosStencil";
192
+ wallpoet: "wallpoet";
193
+ orbitron: "orbitron";
194
+ tourney: "tourney";
195
+ bebasNeue: "bebasNeue";
196
+ anton: "anton";
197
+ jersey25: "jersey25";
198
+ }>;
199
+ color: z.ZodString;
200
+ }, z.core.$strip>], "type">;
201
+ export declare const BADGE_MAX_LAYERS = 25;
202
+ export declare const BadgeSchema: z.ZodObject<{
203
+ layers: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
204
+ x: z.ZodNumber;
205
+ y: z.ZodNumber;
206
+ size: z.ZodNumber;
207
+ rotation: z.ZodNumber;
208
+ type: z.ZodLiteral<"shape">;
209
+ shape: z.ZodString;
210
+ colors: z.ZodArray<z.ZodString>;
211
+ }, z.core.$strip>, z.ZodObject<{
212
+ x: z.ZodNumber;
213
+ y: z.ZodNumber;
214
+ size: z.ZodNumber;
215
+ rotation: z.ZodNumber;
216
+ type: z.ZodLiteral<"icon">;
217
+ icon: z.ZodEnum<{
218
+ star: "star";
219
+ crown: "crown";
220
+ bolt: "bolt";
221
+ fire: "fire";
222
+ heart: "heart";
223
+ gem: "gem";
224
+ skull: "skull";
225
+ ghost: "ghost";
226
+ anchor: "anchor";
227
+ compass: "compass";
228
+ sun: "sun";
229
+ moon: "moon";
230
+ snowflake: "snowflake";
231
+ leaf: "leaf";
232
+ seedling: "seedling";
233
+ tree: "tree";
234
+ mountain: "mountain";
235
+ water: "water";
236
+ wind: "wind";
237
+ meteor: "meteor";
238
+ rocket: "rocket";
239
+ bell: "bell";
240
+ flag: "flag";
241
+ feather: "feather";
242
+ "shield-halved": "shield-halved";
243
+ "chess-knight": "chess-knight";
244
+ "chess-rook": "chess-rook";
245
+ hammer: "hammer";
246
+ crosshairs: "crosshairs";
247
+ medal: "medal";
248
+ trophy: "trophy";
249
+ award: "award";
250
+ volleyball: "volleyball";
251
+ dragon: "dragon";
252
+ cat: "cat";
253
+ crow: "crow";
254
+ turtle: "turtle";
255
+ unicorn: "unicorn";
256
+ horse: "horse";
257
+ dove: "dove";
258
+ fish: "fish";
259
+ paw: "paw";
260
+ spider: "spider";
261
+ otter: "otter";
262
+ frog: "frog";
263
+ dog: "dog";
264
+ pear: "pear";
265
+ }>;
266
+ color: z.ZodString;
267
+ }, z.core.$strip>, z.ZodObject<{
268
+ x: z.ZodNumber;
269
+ y: z.ZodNumber;
270
+ size: z.ZodNumber;
271
+ rotation: z.ZodNumber;
272
+ type: z.ZodLiteral<"text">;
273
+ text: z.ZodString;
274
+ font: z.ZodEnum<{
275
+ block: "block";
276
+ sans: "sans";
277
+ wide: "wide";
278
+ mono: "mono";
279
+ serif: "serif";
280
+ permanentMarker: "permanentMarker";
281
+ kaushanScript: "kaushanScript";
282
+ russoOne: "russoOne";
283
+ teko: "teko";
284
+ saira: "saira";
285
+ michroma: "michroma";
286
+ zillaSlab: "zillaSlab";
287
+ changaOne: "changaOne";
288
+ stardosStencil: "stardosStencil";
289
+ wallpoet: "wallpoet";
290
+ orbitron: "orbitron";
291
+ tourney: "tourney";
292
+ bebasNeue: "bebasNeue";
293
+ anton: "anton";
294
+ jersey25: "jersey25";
295
+ }>;
296
+ color: z.ZodString;
297
+ }, z.core.$strip>], "type">>;
298
+ }, z.core.$strip>;
299
+ export type BadgeConfig = z.infer<typeof BadgeSchema>;
300
+ export type BadgeLayer = z.infer<typeof BadgeLayerSchema>;
301
+ export type BadgeShapeLayer = z.infer<typeof shapeLayer>;
302
+ export type BadgeIconLayer = z.infer<typeof iconLayer>;
303
+ export type BadgeTextLayer = z.infer<typeof textLayer>;
304
+ export {};
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BadgeSchema = exports.BADGE_MAX_LAYERS = exports.BadgeLayerSchema = exports.BADGE_SHAPES = exports.BADGE_TEXT_FONTS = exports.BADGE_ICONS = exports.BADGE_CANVAS = void 0;
4
+ const zod_1 = require("zod");
5
+ // 6-digit hex (#rrggbb) or 8-digit hex with alpha (#rrggbbaa), the same convention as the jersey colours (the
6
+ // 8-digit form comes from the UI's opacity-enabled colour pickers; SVG fills render both).
7
+ const hexColor = zod_1.z.string().regex(/^#[0-9a-fA-F]{6}([0-9a-fA-F]{2})?$/, 'INVALID_HEX_COLOR');
8
+ // The badge canvas is a fixed square coordinate space. Layer x/y are the layer's centre in canvas units and
9
+ // `size` is the layer's height in the same units; positions may overhang the canvas a little (clipped at render).
10
+ exports.BADGE_CANVAS = 200;
11
+ // Curated FontAwesome icon names offered as badge layers (owner decision 2026-08-31: curated set, not a full
12
+ // catalog). The UI maps each name to its solid-icon path data (view/badge/badge-icons.ts, a Record keyed by this
13
+ // type so the two lists cannot drift); this list is what the API validates against.
14
+ exports.BADGE_ICONS = [
15
+ 'star', 'crown', 'bolt', 'fire', 'heart', 'gem', 'skull', 'ghost', 'anchor', 'compass',
16
+ 'sun', 'moon', 'snowflake', 'leaf', 'seedling', 'tree', 'mountain', 'water', 'wind', 'meteor',
17
+ 'rocket', 'bell', 'flag', 'feather', 'shield-halved', 'chess-knight', 'chess-rook', 'hammer', 'crosshairs',
18
+ 'medal', 'trophy', 'award', 'volleyball', 'dragon', 'cat', 'crow', 'turtle', 'unicorn', 'horse', 'dove',
19
+ 'fish', 'paw', 'spider', 'otter', 'frog', 'dog', 'pear'
20
+ ];
21
+ // Text layers offer the same 20 faces as the jersey number editor (JERSEY_FONT_ALL): five generic stacks, then
22
+ // the fifteen display families. The jersey renders its number from GENERATED DIGIT GLYPHS because it lives in a
23
+ // data-uri <img> where @font-face does not load; the badge canvas is inline SVG in the document, so it uses the
24
+ // real webfonts instead, which also means badge text is not limited to the digits those glyph sets cover.
25
+ exports.BADGE_TEXT_FONTS = [
26
+ 'sans', 'wide', 'mono', 'serif', 'block',
27
+ 'permanentMarker', 'kaushanScript', 'russoOne', 'teko', 'saira', 'michroma', 'zillaSlab', 'changaOne',
28
+ 'stardosStencil', 'wallpoet', 'orbitron', 'tourney', 'bebasNeue', 'anton', 'jersey25'
29
+ ];
30
+ // Basic geometric shapes (VolleyballSimUI/public/shapes), extracted from the two source sets 2026-08-31. The
31
+ // crest sets are positional (shield-a01, ribbon-07), but these are named, so the vocabulary is spelled out
32
+ // rather than pattern-matched: this list IS the allow list, and every entry has a file of the same name.
33
+ // `-outline` is the hollow cut, whose interior is a real hole in the path (so layers underneath show through,
34
+ // no transparent fill slot needed). Order is the picker order, grouped by family.
35
+ // The rounded-corner cut of every shape, plus the split square and the pie, were dropped by the owner
36
+ // 2026-08-31; only the sharp cuts ship.
37
+ exports.BADGE_SHAPES = [
38
+ 'star5-solid', 'star5-slim-solid', 'star6-solid', 'cross-solid',
39
+ 'star5-outline', 'star5-slim-outline', 'star6-outline', 'cross-outline',
40
+ 'pentagon-solid', 'hexagon-solid', 'octagon-solid',
41
+ 'pentagon-outline', 'hexagon-outline', 'octagon-outline',
42
+ 'square-solid', 'triangle-solid', 'diamond-solid',
43
+ 'square-outline', 'triangle-outline', 'diamond-outline',
44
+ 'rectangle-solid', 'burst-solid', 'trapezoid-solid',
45
+ 'rectangle-outline', 'burst-outline', 'trapezoid-outline',
46
+ 'circle-solid', 'heptagon-solid', 'nonagon-solid', 'ellipse-solid', 'parallelogram-solid',
47
+ 'heart-solid', 'moon-solid', 'semicircle-solid', 'triangle-right-solid', 'triangle-tall-solid',
48
+ 'trapezoid-tall-solid', 'kite-solid'
49
+ ];
50
+ // The extracted vector sets in VolleyballSimUI/public/shields + public/ribbons + public/shapes:
51
+ // shield-a01..a17 / shield-b01..b16, each -solid|-bordered|-outline; ribbon-01..ribbon-49; and shape-<name>
52
+ // for every name in BADGE_SHAPES.
53
+ const CREST_ID = /^(shield-(a(0[1-9]|1[0-7])|b(0[1-9]|1[0-6]))-(solid|bordered|outline)|ribbon-(0[1-9]|[1-4][0-9]))$/;
54
+ const BASIC_ID = new RegExp(`^shape-(${exports.BADGE_SHAPES.join('|')})$`);
55
+ const shapeId = zod_1.z.string().refine(v => CREST_ID.test(v) || BASIC_ID.test(v), 'INVALID_BADGE_SHAPE');
56
+ const layerBase = {
57
+ x: zod_1.z.number().min(-100).max(300),
58
+ y: zod_1.z.number().min(-100).max(300),
59
+ size: zod_1.z.number().min(4).max(400),
60
+ rotation: zod_1.z.number().min(-180).max(180)
61
+ };
62
+ // One colour per DISTINCT fill in the source art (solid shields 1, bordered 3, ribbons up to 4, basic shapes 1),
63
+ // applied in the order the fills first appear in the file. Extra entries are ignored at render; missing ones
64
+ // fall back to the source colour.
65
+ const shapeLayer = zod_1.z.object({
66
+ type: zod_1.z.literal('shape'),
67
+ shape: shapeId,
68
+ colors: zod_1.z.array(hexColor).min(1).max(6),
69
+ ...layerBase
70
+ });
71
+ const iconLayer = zod_1.z.object({
72
+ type: zod_1.z.literal('icon'),
73
+ icon: zod_1.z.enum(exports.BADGE_ICONS),
74
+ color: hexColor,
75
+ ...layerBase
76
+ });
77
+ const textLayer = zod_1.z.object({
78
+ type: zod_1.z.literal('text'),
79
+ text: zod_1.z.string().min(1).max(24),
80
+ font: zod_1.z.enum(exports.BADGE_TEXT_FONTS),
81
+ color: hexColor,
82
+ ...layerBase
83
+ });
84
+ exports.BadgeLayerSchema = zod_1.z.discriminatedUnion('type', [shapeLayer, iconLayer, textLayer]);
85
+ // The most layers one badge may stack. Not a technical ceiling (25 layers is under 3 KB of jsonb and a trivial
86
+ // number of SVG paths): past roughly a dozen you cannot tell the elements apart at the size a crest is shown,
87
+ // and the one-step-per-click reordering gets tedious. Exported so the editor gates on the SAME number the save
88
+ // validates against, rather than keeping its own copy that can drift.
89
+ exports.BADGE_MAX_LAYERS = 25;
90
+ // The full team badge: an ordered stack of layers (index 0 renders first, i.e. at the back).
91
+ exports.BadgeSchema = zod_1.z.object({
92
+ layers: zod_1.z.array(exports.BadgeLayerSchema).min(1).max(exports.BADGE_MAX_LAYERS)
93
+ });
@@ -1,6 +1,7 @@
1
1
  export * from './team';
2
2
  export * from './jersey';
3
3
  export * from './jersey-defaults';
4
+ export * from './badge';
4
5
  export * from './team-generator';
5
6
  export * from './formation';
6
7
  export * from './tactics';
@@ -17,6 +17,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./team"), exports);
18
18
  __exportStar(require("./jersey"), exports);
19
19
  __exportStar(require("./jersey-defaults"), exports);
20
+ __exportStar(require("./badge"), exports);
20
21
  __exportStar(require("./team-generator"), exports);
21
22
  __exportStar(require("./formation"), exports);
22
23
  __exportStar(require("./tactics"), exports);
@@ -74,6 +74,8 @@ function jerseyFromTeamId(teamId) {
74
74
  numberSize: 46,
75
75
  brand: 'none',
76
76
  brandColor1: '#ffffff',
77
- brandColor2: '#1e293b'
77
+ brandColor2: '#1e293b',
78
+ brandSize: 29,
79
+ badgeSize: 48
78
80
  };
79
81
  }
@@ -67,6 +67,8 @@ 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'];
@@ -33,10 +33,18 @@ exports.JerseySchema = zod_1.z.object({
33
33
  // configs saved before it stay valid.
34
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'),
35
35
  brandColor1: hexColor.default('#ffffff'),
36
- brandColor2: hexColor.default('#1e293b')
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)
37
44
  });
38
45
  // The alternate (libero) kit stores only the fields the premium editor allows changing. Locked fields (clothing,
39
- // font, brand icon, numberSpacing, numberSize) are always inherited from the main kit at render time.
46
+ // font, brand icon, numberSpacing, numberSize, brandSize, badgeSize) are always inherited from the main kit at
47
+ // render time.
40
48
  exports.AlternateJerseySchema = zod_1.z.object({
41
49
  pattern: exports.JerseySchema.shape.pattern,
42
50
  colors: exports.JerseySchema.shape.colors,
@@ -127,6 +135,8 @@ function computeComplementaryJersey(main) {
127
135
  brand: main.brand,
128
136
  numberSpacing: main.numberSpacing,
129
137
  numberSize: main.numberSize,
138
+ brandSize: main.brandSize,
139
+ badgeSize: main.badgeSize,
130
140
  // Editable fields: complementary-derived
131
141
  pattern: main.pattern,
132
142
  colors: compColors,
@@ -146,6 +156,8 @@ function mergeAlternateJersey(main, alt) {
146
156
  brand: main.brand,
147
157
  numberSpacing: main.numberSpacing,
148
158
  numberSize: main.numberSize,
159
+ brandSize: main.brandSize,
160
+ badgeSize: main.badgeSize,
149
161
  pattern: alt.pattern,
150
162
  colors: alt.colors,
151
163
  numberColor: alt.numberColor,