@johnmorrisdotca/dougu-sports 0.4.0 → 0.5.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.
Files changed (39) hide show
  1. package/CHANGELOG.md +29 -1
  2. package/NOTICE.md +6 -4
  3. package/README.md +6 -5
  4. package/dist/emblems/ball/ball.baseball.vintage.d.ts +10 -0
  5. package/dist/emblems/ball/ball.baseball.vintage.js +70 -0
  6. package/dist/emblems/ball/ball.core.d.ts +8 -1
  7. package/dist/emblems/ball/ball.core.js +11 -1
  8. package/dist/emblems/ball/ball.decal.d.ts +56 -0
  9. package/dist/emblems/ball/ball.decal.js +146 -0
  10. package/dist/emblems/ball/ball.engine.d.ts +7 -1
  11. package/dist/emblems/ball/ball.engine.js +10 -2
  12. package/dist/emblems/ball/ball.face.d.ts +14 -9
  13. package/dist/emblems/ball/ball.face.js +6 -5
  14. package/dist/emblems/ball/ball.family.panelled.d.ts +5 -0
  15. package/dist/emblems/ball/ball.family.panelled.js +12 -5
  16. package/dist/emblems/ball/ball.family.seamed.d.ts +8 -1
  17. package/dist/emblems/ball/ball.family.seamed.js +13 -3
  18. package/dist/emblems/ball/ball.index.js +6 -1
  19. package/dist/emblems/ball/ball.puck.print.js +1 -1
  20. package/dist/emblems/ball/ball.soccer.era.d.ts +23 -0
  21. package/dist/emblems/ball/ball.soccer.era.js +302 -0
  22. package/dist/emblems/ball/ball.soccer.store.d.ts +19 -0
  23. package/dist/emblems/ball/ball.soccer.store.js +176 -0
  24. package/dist/emblems/ball/ball.soccer.vintage.d.ts +11 -0
  25. package/dist/emblems/ball/ball.soccer.vintage.js +135 -0
  26. package/dist/emblems/ball/ball.tilings.d.ts +26 -0
  27. package/dist/emblems/ball/ball.tilings.js +87 -0
  28. package/dist/emblems/ball/ball.volleyball.flag.d.ts +12 -0
  29. package/dist/emblems/ball/ball.volleyball.flag.js +36 -0
  30. package/dist/emblems/emblem.core.d.ts +6 -2
  31. package/dist/emblems/emblem.descriptions.js +50 -0
  32. package/dist/emblems/emblem.ids.d.ts +2 -2
  33. package/dist/emblems/emblem.ids.js +3 -2
  34. package/dist/emblems-entry.d.ts +1 -1
  35. package/dist/index.d.ts +5 -0
  36. package/dist/index.js +5 -0
  37. package/dist/version.d.ts +1 -1
  38. package/dist/version.js +1 -1
  39. package/package.json +1 -1
@@ -38,7 +38,7 @@ const colourOf = (value) => {
38
38
  };
39
39
  const DESIGNS = Object.keys(LOOKS);
40
40
  /** The face, ready to draw: the design's words and colours under the caller's. `base` is the design a puck's own id starts from. */
41
- function resolve(face, base, own) {
41
+ function resolve(face, base, own, flags, theme) {
42
42
  const f = typeof face === "object" && face !== null ? face : {};
43
43
  const design = (typeof f.design === "string" && DESIGNS.includes(f.design) ? f.design : own?.design ?? base);
44
44
  const words = { ...WORDS[design], ...own, ...definedOnly(f) };
@@ -60,7 +60,8 @@ function resolve(face, base, own) {
60
60
  look,
61
61
  image: typeof words.image === "string" ? words.image : undefined,
62
62
  flag: typeof words.flag === "string" ? words.flag.trim().toLowerCase().slice(0, 12) : undefined,
63
- flags: typeof words.flags === "function" ? words.flags : undefined,
63
+ flags,
64
+ theme,
64
65
  text: cleanText(words.text),
65
66
  ring,
66
67
  number: number === "" ? undefined : number,
@@ -112,7 +113,7 @@ function picture(f, prefix, cx, cy, w, h) {
112
113
  if (f.flags !== undefined) {
113
114
  let svg;
114
115
  try {
115
- svg = f.flags(code, { shape: "4:3", size: 120, theme: "light" });
116
+ svg = f.flags(code, { shape: "rect", size: 120, theme: f.theme });
116
117
  }
117
118
  catch {
118
119
  svg = undefined;
@@ -182,8 +183,8 @@ function leaf(cx, cy, w, fill) {
182
183
  return `<path d="${LEAF_PATH}" transform="translate(${num(cx, 3)} ${num(cy, 3)}) scale(${num(w / 2, 4)})" fill="${fill}"/>`;
183
184
  }
184
185
  /** The face of a design, in the face's units (a disc of radius 1, up is up): its definitions and its drawing. `prefix` makes every id unique to this puck. */
185
- export function faceMarkup(face, design, own, prefix) {
186
- const f = resolve(face, design, own);
186
+ export function faceMarkup(face, design, own, prefix, flags, theme = "inherit") {
187
+ const f = resolve(face, design, own, typeof flags === "function" ? flags : undefined, theme);
187
188
  const look = f.look;
188
189
  const clip = `${prefix}clip`;
189
190
  let defs = `<clipPath id="${clip}"><circle r=".965"/></clipPath>`;
@@ -1,4 +1,9 @@
1
+ import { type V3 } from "./ball.math.ts";
1
2
  import type { Surface } from "./ball.engine.ts";
3
+ /** The 18 panels of a ball, painted and not outlined. `colours[i]` is the three strips of face i, or one colour for the middle strip and one for the outer two. */
4
+ export declare function paint18(s: Surface, colours: ReadonlyArray<readonly [string, string]>): string;
5
+ /** The seams of the 18-panel layout, each once: the lines between strips and the twelve edges of the cube. */
6
+ export declare function seams18(): V3[][];
2
7
  /** The 18 panels of a ball. `colours[i]` is the three strips of face i, or one colour for the middle strip and one for the outer two. */
3
8
  export declare function strips18(s: Surface, colours: ReadonlyArray<readonly [string, string]>, seam: string, width?: number): string;
4
9
  /** The 8 panels of an octahedral ball: the octants, coloured by `pick(sx, sy, sz)`. */
@@ -19,8 +19,8 @@ const onFace = (f, p, q) => {
19
19
  v[f.q] = q;
20
20
  return norm(v);
21
21
  };
22
- /** The 18 panels of a ball. `colours[i]` is the three strips of face i, or one colour for the middle strip and one for the outer two. */
23
- export function strips18(s, colours, seam, width = 1.1) {
22
+ /** The 18 panels of a ball, painted and not outlined. `colours[i]` is the three strips of face i, or one colour for the middle strip and one for the outer two. */
23
+ export function paint18(s, colours) {
24
24
  let out = "";
25
25
  FACES.forEach((f, fi) => {
26
26
  const [outer, middle] = colours[fi % colours.length];
@@ -30,6 +30,10 @@ export function strips18(s, colours, seam, width = 1.1) {
30
30
  out += s.panel(ring, i === 1 ? middle : outer, { n: 6, ink: false });
31
31
  }
32
32
  });
33
+ return out;
34
+ }
35
+ /** The seams of the 18-panel layout, each once: the lines between strips and the twelve edges of the cube. */
36
+ export function seams18() {
33
37
  const curves = [];
34
38
  for (const f of FACES)
35
39
  for (const q of [-SPLIT, SPLIT])
@@ -40,9 +44,12 @@ export function strips18(s, colours, seam, width = 1.1) {
40
44
  curves.push(arc(norm([a, -1, b]), norm([a, 1, b]), 12));
41
45
  curves.push(arc(norm([-1, a, b]), norm([1, a, b]), 12));
42
46
  }
43
- out += s.strokes(curves, seam, width);
44
- out += s.strokes(curves, "#fff", width * 0.35, { deco: true, opacity: 0.4, dx: 0.25, dy: 0.3 });
45
- return out;
47
+ return curves;
48
+ }
49
+ /** The 18 panels of a ball. `colours[i]` is the three strips of face i, or one colour for the middle strip and one for the outer two. */
50
+ export function strips18(s, colours, seam, width = 1.1) {
51
+ const curves = seams18();
52
+ return paint18(s, colours) + s.strokes(curves, seam, width) + s.strokes(curves, "#fff", width * 0.35, { deco: true, opacity: 0.4, dx: 0.25, dy: 0.3 });
46
53
  }
47
54
  /** The 8 panels of an octahedral ball: the octants, coloured by `pick(sx, sy, sz)`. */
48
55
  export function octants8(s, pick, seam, width = 1.1) {
@@ -17,14 +17,21 @@ export interface SeamedOptions {
17
17
  width: number;
18
18
  raised?: boolean;
19
19
  };
20
- /** Stitches across the seam: colour, count, the half-length across it (radians) and the stroke width. */
20
+ /** Stitches across the seam: colour, count, the half-length across it (radians) and the stroke width. With `colour2` every other stitch is in that colour (a two-thread seam). */
21
21
  stitch?: {
22
22
  colour: string;
23
+ colour2?: string;
23
24
  count: number;
24
25
  half: number;
25
26
  width: number;
26
27
  lean: number;
27
28
  };
29
+ /** Scuffs of wear: the number of dark and of pale patches. */
30
+ wear?: {
31
+ dark: number;
32
+ pale: number;
33
+ seed?: number;
34
+ };
28
35
  /** A thin groove along the seam. */
29
36
  groove?: string;
30
37
  }
@@ -1,6 +1,8 @@
1
1
  // Balls with the seam of a baseball or a tennis ball: one closed curve that winds twice round the sphere, x=(1-b)cos t + b cos 3t, y=(1-b)sin t - b sin 3t, z=2sqrt(b(1-b)) sin 2t.
2
2
  // A baseball and a softball have red stitches that cross it in Vs; a tennis or padel ball has a white rubber strip along it; a sliotar a raised rib.
3
3
  import { defineBall } from "./ball.engine.js";
4
+ import { mix } from "./ball.core.js";
5
+ import { scuffs } from "./ball.decal.js";
4
6
  import { seamCurve } from "./ball.math.js";
5
7
  import { stitches } from "./ball.stitch.js";
6
8
  export function seamedBall(o) {
@@ -8,15 +10,23 @@ export function seamedBall(o) {
8
10
  view: o.view ?? { yaw: 0, pitch: 0, roll: 0 },
9
11
  base: o.base,
10
12
  mat: o.mat,
11
- draw: (s) => {
13
+ draw: (s, base) => {
12
14
  const seam = seamCurve(o.b, 160);
13
15
  let out = "";
14
16
  if (o.groove !== undefined)
15
17
  out += s.stroke(seam, o.groove, 0.8, { closed: true, opacity: 0.55 });
16
18
  if (o.strip !== undefined)
17
19
  out += o.strip.raised === true ? s.seam(seam, o.strip.colour, o.strip.width, { closed: true }) : s.stroke(seam, o.strip.colour, o.strip.width, { closed: true });
18
- if (o.stitch !== undefined)
19
- out += s.strokes(stitches(seam, true, o.stitch.count, o.stitch.half, { v: true, lean: o.stitch.lean }), o.stitch.colour, o.stitch.width, { ink: false });
20
+ if (o.wear !== undefined)
21
+ out += scuffs(s, mix(base, -0.55), mix(base, 0.6), { dark: o.wear.dark, pale: o.wear.pale, seed: o.wear.seed });
22
+ if (o.stitch !== undefined) {
23
+ const marks = stitches(seam, true, o.stitch.count, o.stitch.half, { v: true, lean: o.stitch.lean });
24
+ const second = o.stitch.colour2;
25
+ if (second === undefined)
26
+ out += s.strokes(marks, o.stitch.colour, o.stitch.width, { ink: false });
27
+ else
28
+ out += s.strokes(marks.filter((_, i) => i % 2 === 0), o.stitch.colour, o.stitch.width, { ink: false }) + s.strokes(marks.filter((_, i) => i % 2 === 1), second, o.stitch.width, { ink: false });
29
+ }
20
30
  if (o.strip === undefined && o.stitch === undefined)
21
31
  out += s.stroke(seam, "currentColor", 1.6, { closed: true });
22
32
  return out;
@@ -27,13 +27,18 @@ import { BALL_SOCCER, BALL_SOCCER_COLOUR } from "./ball.soccer.js";
27
27
  import { BALL_SOCCER_26, BALL_SOCCER_18, BALL_SOCCER_14, BALL_SOCCER_12, BALL_SOCCER_6, BALL_SOCCER_ORANGE, BALL_SOCCER_26_ORANGE, BALL_SOCCER_18_ORANGE, BALL_SOCCER_14_ORANGE, BALL_SOCCER_12_ORANGE, BALL_SOCCER_6_ORANGE, BALL_SOCCER_YELLOW, BALL_SOCCER_26_YELLOW, BALL_SOCCER_18_YELLOW, BALL_SOCCER_14_YELLOW, BALL_SOCCER_12_YELLOW, BALL_SOCCER_6_YELLOW } from "./ball.soccer.panels.js";
28
28
  import { BALL_FUTSAL, BALL_BEACH_SOCCER } from "./ball.soccer.indoor.js";
29
29
  import { BALL_SOFTBALL } from "./ball.softball.js";
30
+ import { BALL_SOCCER_1870_HAND_STITCHED, BALL_SOCCER_1900_LACED, BALL_SOCCER_1930_18_PANEL, BALL_SOCCER_1950_12_PANEL, BALL_SOCCER_1960_32_PANEL_LEATHER } from "./ball.soccer.vintage.js";
31
+ import { BALL_SOCCER_1970_BLACK_WHITE, BALL_SOCCER_1978_TRIAD, BALL_SOCCER_1986_DECORATED_TRIAD, BALL_SOCCER_1998_COLOURED_TRIAD, BALL_SOCCER_2002_TRIANGLE_SWEEP, BALL_SOCCER_2006_PROPELLER, BALL_SOCCER_2010_GROOVED, BALL_SOCCER_2014_RIBBON, BALL_SOCCER_2018_PIXEL, BALL_SOCCER_2022_SPEED_SHELL, BALL_SOCCER_TRAINING_HIGH_VIS } from "./ball.soccer.era.js";
32
+ import { BALL_SOCCER_STARS_BLUE, BALL_SOCCER_STARS_RED, BALL_SOCCER_STARS_NIGHT, BALL_SOCCER_HEXAGONS_CYAN, BALL_SOCCER_HEXAGONS_MAGENTA, BALL_SOCCER_HEXAGONS_LIME, BALL_SOCCER_FLAMES_FIRE, BALL_SOCCER_FLAMES_ICE, BALL_SOCCER_FLAMES_TOXIC, BALL_SOCCER_CHEVRONS_RED, BALL_SOCCER_CHEVRONS_GREEN, BALL_SOCCER_CHEVRONS_BLUE, BALL_SOCCER_SWIRL_BLUE, BALL_SOCCER_SWIRL_RED, BALL_SOCCER_SWIRL_TEAL, BALL_SOCCER_METALLIC_GOLD, BALL_SOCCER_METALLIC_SILVER, BALL_SOCCER_METALLIC_COBALT } from "./ball.soccer.store.js";
33
+ import { BALL_BASEBALL_LEMON_PEEL, BALL_BASEBALL_RED_BLUE, BALL_BASEBALL_BLACK_RED, BALL_BASEBALL_VINTAGE_LEATHER, BALL_SOFTBALL_11_OPTIC } from "./ball.baseball.vintage.js";
34
+ import { BALL_VOLLEYBALL_COLOURS, BALL_VOLLEYBALL_BRAZIL, BALL_VOLLEYBALL_JAPAN, BALL_VOLLEYBALL_CANADA, BALL_VOLLEYBALL_USA, BALL_VOLLEYBALL_ITALY, BALL_VOLLEYBALL_POLAND, BALL_VOLLEYBALL_FRANCE, BALL_VOLLEYBALL_SERBIA, BALL_VOLLEYBALL_NETHERLANDS, BALL_VOLLEYBALL_GERMANY } from "./ball.volleyball.flag.js";
30
35
  import { BALL_SQUASH_DOUBLE_YELLOW, BALL_SQUASH_YELLOW, BALL_SQUASH_RED, BALL_SQUASH_BLUE, BALL_SQUASH_GREEN } from "./ball.squash.js";
31
36
  import { BALL_TENNIS } from "./ball.tennis.js";
32
37
  import { BALL_TEQBALL } from "./ball.teqball.js";
33
38
  import { BALL_VOLLEYBALL, BALL_VOLLEYBALL_8, BALL_BEACH_VOLLEYBALL } from "./ball.volleyball.js";
34
39
  import { BALL_WATER_POLO } from "./ball.waterpolo.js";
35
40
  /** Every ball, in the order a gallery shows them. */
36
- export const BALLS = [BALL_SOCCER, BALL_SOCCER_COLOUR, BALL_SOCCER_26, BALL_SOCCER_18, BALL_SOCCER_14, BALL_SOCCER_12, BALL_SOCCER_6, BALL_SOCCER_ORANGE, BALL_SOCCER_26_ORANGE, BALL_SOCCER_18_ORANGE, BALL_SOCCER_14_ORANGE, BALL_SOCCER_12_ORANGE, BALL_SOCCER_6_ORANGE, BALL_SOCCER_YELLOW, BALL_SOCCER_26_YELLOW, BALL_SOCCER_18_YELLOW, BALL_SOCCER_14_YELLOW, BALL_SOCCER_12_YELLOW, BALL_SOCCER_6_YELLOW, BALL_FUTSAL, BALL_BEACH_SOCCER, BALL_TEQBALL, BALL_BASKETBALL, BALL_BASKETBALL_6, BALL_BASKETBALL_3X3, BALL_BASEBALL, BALL_SOFTBALL, BALL_TENNIS, BALL_PADEL, BALL_SLIOTAR, BALL_VOLLEYBALL, BALL_VOLLEYBALL_8, BALL_BEACH_VOLLEYBALL, BALL_CRICKET_RED, BALL_CRICKET_WHITE, BALL_CRICKET_PINK, BALL_FOOTBALL, BALL_FOOTBALL_CFL, BALL_FOOTBALL_IFAF, BALL_RUGBY, BALL_AFL, BALL_GAELIC_FOOTBALL, BALL_NETBALL, BALL_PICKLEBALL_OUTDOOR, BALL_PICKLEBALL_INDOOR, BALL_SQUASH_DOUBLE_YELLOW, BALL_SQUASH_YELLOW, BALL_SQUASH_GREEN, BALL_SQUASH_RED, BALL_SQUASH_BLUE, BALL_RACQUETBALL, BALL_LACROSSE, BALL_FIELD_HOCKEY, BALL_TABLE_TENNIS, BALL_HANDBALL, BALL_WATER_POLO, BALL_GOLF, BALL_PUCK, BALL_CURLING_STONE, BALL_SHOT, BALL_DISCUS, BALL_HAMMER, BALL_SEPAK_TAKRAW, BALL_ROUNDNET, BALL_SHUTTLECOCK_FEATHER, BALL_SHUTTLECOCK_NYLON];
41
+ export const BALLS = [BALL_SOCCER, BALL_SOCCER_COLOUR, BALL_SOCCER_26, BALL_SOCCER_18, BALL_SOCCER_14, BALL_SOCCER_12, BALL_SOCCER_6, BALL_SOCCER_ORANGE, BALL_SOCCER_26_ORANGE, BALL_SOCCER_18_ORANGE, BALL_SOCCER_14_ORANGE, BALL_SOCCER_12_ORANGE, BALL_SOCCER_6_ORANGE, BALL_SOCCER_YELLOW, BALL_SOCCER_26_YELLOW, BALL_SOCCER_18_YELLOW, BALL_SOCCER_14_YELLOW, BALL_SOCCER_12_YELLOW, BALL_SOCCER_6_YELLOW, BALL_FUTSAL, BALL_BEACH_SOCCER, BALL_SOCCER_1870_HAND_STITCHED, BALL_SOCCER_1900_LACED, BALL_SOCCER_1930_18_PANEL, BALL_SOCCER_1950_12_PANEL, BALL_SOCCER_1960_32_PANEL_LEATHER, BALL_SOCCER_1970_BLACK_WHITE, BALL_SOCCER_1978_TRIAD, BALL_SOCCER_1986_DECORATED_TRIAD, BALL_SOCCER_1998_COLOURED_TRIAD, BALL_SOCCER_2002_TRIANGLE_SWEEP, BALL_SOCCER_2006_PROPELLER, BALL_SOCCER_2010_GROOVED, BALL_SOCCER_2014_RIBBON, BALL_SOCCER_2018_PIXEL, BALL_SOCCER_2022_SPEED_SHELL, BALL_SOCCER_TRAINING_HIGH_VIS, BALL_SOCCER_STARS_BLUE, BALL_SOCCER_STARS_RED, BALL_SOCCER_STARS_NIGHT, BALL_SOCCER_HEXAGONS_CYAN, BALL_SOCCER_HEXAGONS_MAGENTA, BALL_SOCCER_HEXAGONS_LIME, BALL_SOCCER_FLAMES_FIRE, BALL_SOCCER_FLAMES_ICE, BALL_SOCCER_FLAMES_TOXIC, BALL_SOCCER_CHEVRONS_RED, BALL_SOCCER_CHEVRONS_GREEN, BALL_SOCCER_CHEVRONS_BLUE, BALL_SOCCER_SWIRL_BLUE, BALL_SOCCER_SWIRL_RED, BALL_SOCCER_SWIRL_TEAL, BALL_SOCCER_METALLIC_GOLD, BALL_SOCCER_METALLIC_SILVER, BALL_SOCCER_METALLIC_COBALT, BALL_TEQBALL, BALL_BASKETBALL, BALL_BASKETBALL_6, BALL_BASKETBALL_3X3, BALL_BASEBALL, BALL_SOFTBALL, BALL_BASEBALL_LEMON_PEEL, BALL_BASEBALL_RED_BLUE, BALL_BASEBALL_BLACK_RED, BALL_BASEBALL_VINTAGE_LEATHER, BALL_SOFTBALL_11_OPTIC, BALL_TENNIS, BALL_PADEL, BALL_SLIOTAR, BALL_VOLLEYBALL, BALL_VOLLEYBALL_8, BALL_BEACH_VOLLEYBALL, BALL_VOLLEYBALL_COLOURS, BALL_VOLLEYBALL_BRAZIL, BALL_VOLLEYBALL_JAPAN, BALL_VOLLEYBALL_CANADA, BALL_VOLLEYBALL_USA, BALL_VOLLEYBALL_ITALY, BALL_VOLLEYBALL_POLAND, BALL_VOLLEYBALL_FRANCE, BALL_VOLLEYBALL_SERBIA, BALL_VOLLEYBALL_NETHERLANDS, BALL_VOLLEYBALL_GERMANY, BALL_CRICKET_RED, BALL_CRICKET_WHITE, BALL_CRICKET_PINK, BALL_FOOTBALL, BALL_FOOTBALL_CFL, BALL_FOOTBALL_IFAF, BALL_RUGBY, BALL_AFL, BALL_GAELIC_FOOTBALL, BALL_NETBALL, BALL_PICKLEBALL_OUTDOOR, BALL_PICKLEBALL_INDOOR, BALL_SQUASH_DOUBLE_YELLOW, BALL_SQUASH_YELLOW, BALL_SQUASH_GREEN, BALL_SQUASH_RED, BALL_SQUASH_BLUE, BALL_RACQUETBALL, BALL_LACROSSE, BALL_FIELD_HOCKEY, BALL_TABLE_TENNIS, BALL_HANDBALL, BALL_WATER_POLO, BALL_GOLF, BALL_PUCK, BALL_CURLING_STONE, BALL_SHOT, BALL_DISCUS, BALL_HAMMER, BALL_SEPAK_TAKRAW, BALL_ROUNDNET, BALL_SHUTTLECOCK_FEATHER, BALL_SHUTTLECOCK_NYLON];
37
42
  /** The id of every ball: `"ball:soccer"`, `"ball:cricket-red"`. */
38
43
  export const BALL_IDS = BALLS.map((b) => b.id);
39
44
  const TABLE = new Map([...BALLS, ...PUCKS].map((b) => [b.id, b]));
@@ -24,7 +24,7 @@ function definePuck(def) {
24
24
  // The top face's plane in the box: its centre, and where a step of 1 along the puck's x and z axes goes (the face's right, and its down).
25
25
  const o = cx.at([0, PUCK_H, 0]), ex = cx.at([1, PUCK_H, 0]), ez = cx.at([0, PUCK_H, 1]);
26
26
  const m = [ex[0] - o[0], ex[1] - o[1], ez[0] - o[0], ez[1] - o[1], o[0], o[1]].map((v) => num(v, 4)).join(" ");
27
- const face = faceMarkup(cx.opts.face, def.design, def.own, `${cx.id}p`);
27
+ const face = faceMarkup(cx.opts.face, def.design, def.own, `${cx.id}p`, cx.opts.flags, cx.opts.theme === "light" || cx.opts.theme === "dark" ? cx.opts.theme : "inherit");
28
28
  // A light from the upper left and a falling-off at the far edge, over the print, in the box's own space so the light stays put while the puck turns.
29
29
  const gid = `${cx.id}fl`;
30
30
  const defs = `${face.defs}<radialGradient id="${gid}" cx=".36" cy=".3" r=".85"><stop offset="0" stop-color="#fff" stop-opacity=".34"/><stop offset=".4" stop-color="#fff" stop-opacity="0"/><stop offset="1" stop-color="#000" stop-opacity=".42"/></radialGradient>`;
@@ -0,0 +1,23 @@
1
+ import { type BallSpec } from "./ball.engine.ts";
2
+ /** The 1970s: twelve black pentagons with a white ring round a small boss, and twenty white hexagons that each hold a pale dished hexagon and a dot. */
3
+ export declare const BALL_SOCCER_1970_BLACK_WHITE: import("./ball.core.ts").Piece<BallSpec>;
4
+ /** The late 1970s: a pinwheel of three bold curved triangles on each of the twenty hexagons, black on white; their points meet round each of the twelve pentagons. */
5
+ export declare const BALL_SOCCER_1978_TRIAD: import("./ball.core.ts").Piece<BallSpec>;
6
+ /** The 1980s: the same triads in a warm clay, each blade ornamented with a row of white beads along its spine, and gold-ringed dark pentagons. */
7
+ export declare const BALL_SOCCER_1986_DECORATED_TRIAD: import("./ball.core.ts").Piece<BallSpec>;
8
+ /** The 1990s: the triads in three colours (blue, red and gold) on a white ground, with deep navy pentagons. */
9
+ export declare const BALL_SOCCER_1998_COLOURED_TRIAD: import("./ball.core.ts").Piece<BallSpec>;
10
+ /** The early 2000s: long thin triangles that sweep across each hexagon from one side to the next, in graphite and gold, with a red spark, over charcoal pentagons. */
11
+ export declare const BALL_SOCCER_2002_TRIANGLE_SWEEP: import("./ball.core.ts").Piece<BallSpec>;
12
+ /** The mid 2000s: the 14-panel propeller layout (six propellers and eight triangles), with a fine line following each curved seam inside the panel, and a small ring on each triangle. */
13
+ export declare const BALL_SOCCER_2006_PROPELLER: import("./ball.core.ts").Piece<BallSpec>;
14
+ /** The early 2010s: the 8-panel layout, an octahedron whose edges are bent into S curves, with grooves for seams and fine contour lines across each panel. */
15
+ export declare const BALL_SOCCER_2010_GROOVED: import("./ball.core.ts").Piece<BallSpec>;
16
+ /** The mid 2010s: six twisted panels in white, crossed by wide ribbons that swirl round the ball in teal, orange and violet. */
17
+ export declare const BALL_SOCCER_2014_RIBBON: import("./ball.core.ts").Piece<BallSpec>;
18
+ /** The late 2010s: six panels covered with square pixel blocks, thick where the ball is dark and thinning out toward the lighter side. */
19
+ export declare const BALL_SOCCER_2018_PIXEL: import("./ball.core.ts").Piece<BallSpec>;
20
+ /** The early 2020s: twenty triangles (an icosahedron) in three warm tones, each carrying a shell of nested edges and a trail of speed lines. */
21
+ export declare const BALL_SOCCER_2022_SPEED_SHELL: import("./ball.core.ts").Piece<BallSpec>;
22
+ /** A modern high-visibility training ball: 32 panels in fluorescent yellow-green, hot pink pentagons ringed in black, and three dark speed marks across each hexagon. */
23
+ export declare const BALL_SOCCER_TRAINING_HIGH_VIS: import("./ball.core.ts").Piece<BallSpec>;
@@ -0,0 +1,302 @@
1
+ // Soccer balls in the style of an era's match balls, each on the construction of its time and with graphics of our own that only evoke the period: the black and white 32 panels of the early 1970s, curved
2
+ // triangles in threes (late 1970s, 1980s and 1990s), a triangular sweep, the 14-panel propeller, the 8-panel grooved ball, 6 panels with ribbons, pixel blocks, 20 panels with a shell of lines, and a modern
3
+ // high-visibility training ball. The panel counts are facts of the constructions (docs/references.md); the drawings are not the real balls' and use none of their marks, names or patterns.
4
+ import { defineBall } from "./ball.engine.js";
5
+ import { mix } from "./ball.core.js";
6
+ import { frameAt, noise, place, spiral, tongue, turned } from "./ball.decal.js";
7
+ import { shrink, truncatedIcosahedron } from "./ball.polyhedra.js";
8
+ import { gorePoint, gores, icosahedron, octahedron8, propellers14 } from "./ball.tilings.js";
9
+ import { SOCCER_SIZE } from "./ball.soccer.size.js";
10
+ const INK = "#1b1d22";
11
+ const WHITE = "#f8f8f6";
12
+ const GREY = "#6b7180";
13
+ const VIEW = { yaw: 30, pitch: 24, roll: 8 };
14
+ const GLOSS = { gloss: 0.8, shade: "#2a3450", grain: { f: 1.1, a: 0.16 } };
15
+ /** The highlight laid on a seam, so that it reads as a raised edge. */
16
+ const lit = (s, seams, width = 0.45) => s.strokes(seams, "#fff", width, { deco: true, opacity: 0.45, dx: 0.3, dy: 0.35 });
17
+ const ball = (id, en, ja, spec) => defineBall({ id, en, ja, size: SOCCER_SIZE, spec });
18
+ /** What lies on the 32 panels: a frame at the middle of each hexagon, with x toward one of the three sides it shares with a pentagon. */
19
+ const hexFrames = (t) => t.hexagonCentres.map((c, i) => frameAt(c, t.hexagonPentagonSides[i][0]));
20
+ /** Three curved blades in a pinwheel about the middle of a hexagon (a triad): each is a leaf along a spiral, `sweep` radians of turn, `w` wide. */
21
+ const triad = (r0, r1, sweep, w, start = 0.5) => [0, 1, 2].map((k) => tongue(spiral(r0, r1, start + (2 * Math.PI * k) / 3, sweep), (u) => w * Math.min(1, u * 5) * (1 - u) ** 0.7, 5));
22
+ /** The hexagons of a 32-panel ball carrying a triad each, over a ground; `colours` has one fill for each blade. */
23
+ function laidTriads(s, t, frames, blades, colours, edge, ew = 0.5) {
24
+ let out = "";
25
+ for (let k = 0; k < blades.length; k++)
26
+ out += s.panels(frames.map((f) => place(f, blades[k])), colours[k % colours.length], { n: 1 });
27
+ // The colour drawing is filled and needs no outline; the line drawing is the outline alone.
28
+ if (s.line) {
29
+ const rings = [];
30
+ for (const f of frames)
31
+ for (const b of blades)
32
+ rings.push(place(f, b));
33
+ out += s.strokes(rings, edge, ew, { closed: true });
34
+ }
35
+ void t;
36
+ return out;
37
+ }
38
+ /** The 1970s: twelve black pentagons with a white ring round a small boss, and twenty white hexagons that each hold a pale dished hexagon and a dot. */
39
+ export const BALL_SOCCER_1970_BLACK_WHITE = /* @__PURE__ */ ball("ball:soccer-1970-black-white", "Soccer, 1970s black-white", "70年代風・白黒", {
40
+ view: VIEW,
41
+ base: INK,
42
+ ground: WHITE,
43
+ mat: GLOSS,
44
+ draw(s, base, accent) {
45
+ const t = truncatedIcosahedron();
46
+ let out = "";
47
+ t.hexagons.forEach((h, i) => {
48
+ out += s.panel(shrink(h, t.hexagonCentres[i], 0.5), accent ?? "#e4e5e1", { n: 2 });
49
+ });
50
+ for (const p of t.pentagons)
51
+ out += s.panel(p, base, { ink: true });
52
+ t.pentagons.forEach((p, i) => {
53
+ out += s.strokes([shrink(p, t.pentagonCentres[i], 0.45)], "#fff", 0.5, { closed: true, deco: true, opacity: 0.85 });
54
+ });
55
+ out += s.dots(t.hexagonCentres, 0.03, base, { light: false });
56
+ out += s.strokes(t.edges, GREY, 1.15);
57
+ return out + lit(s, t.edges);
58
+ },
59
+ });
60
+ /** The late 1970s: a pinwheel of three bold curved triangles on each of the twenty hexagons, black on white; their points meet round each of the twelve pentagons. */
61
+ export const BALL_SOCCER_1978_TRIAD = /* @__PURE__ */ ball("ball:soccer-1978-triad", "Soccer, late-1970s triads", "70年代後期風・三つ巴", {
62
+ view: VIEW,
63
+ base: INK,
64
+ ground: WHITE,
65
+ mat: GLOSS,
66
+ draw(s, base) {
67
+ const t = truncatedIcosahedron();
68
+ let out = laidTriads(s, t, hexFrames(t), triad(0.0, 0.32, -0.85, 0.17, 0.3), [base], base, 0.4);
69
+ out += s.strokes(t.edges, mix(base, 0.45), 0.8);
70
+ return out + lit(s, t.edges, 0.4);
71
+ },
72
+ });
73
+ /** The 1980s: the same triads in a warm clay, each blade ornamented with a row of white beads along its spine, and gold-ringed dark pentagons. */
74
+ export const BALL_SOCCER_1986_DECORATED_TRIAD = /* @__PURE__ */ ball("ball:soccer-1986-decorated-triad", "Soccer, decorated triads", "80年代風・飾り三つ巴", {
75
+ view: VIEW,
76
+ base: "#c4563a",
77
+ ground: WHITE,
78
+ mat: GLOSS,
79
+ draw(s, base, accent) {
80
+ const t = truncatedIcosahedron();
81
+ const hf = hexFrames(t);
82
+ const gold = accent ?? "#e0a526";
83
+ let out = "";
84
+ for (const p of t.pentagons)
85
+ out += s.panel(p, "#3a2a2c", { ink: true });
86
+ t.pentagons.forEach((p, i) => {
87
+ out += s.strokes([shrink(p, t.pentagonCentres[i], 0.4)], gold, 0.6, { closed: true, deco: true });
88
+ });
89
+ out += laidTriads(s, t, hf, triad(0.0, 0.31, -0.85, 0.16, 0.3), [base], mix(base, -0.45), 0.5);
90
+ const spines = [];
91
+ for (const f of hf)
92
+ for (let k = 0; k < 3; k++)
93
+ spines.push(Array.from({ length: 6 }, (_, j) => f(...spiral(0.06, 0.26, 0.3 + (2 * Math.PI * k) / 3, -0.85)(j / 5))));
94
+ out += s.strokes(spines, "#fff7e6", 1.1, { dash: "0 2.3", deco: true });
95
+ return out + s.strokes(t.edges, mix(base, -0.5), 1);
96
+ },
97
+ });
98
+ /** The 1990s: the triads in three colours (blue, red and gold) on a white ground, with deep navy pentagons. */
99
+ export const BALL_SOCCER_1998_COLOURED_TRIAD = /* @__PURE__ */ ball("ball:soccer-1998-coloured-triad", "Soccer, coloured triads", "90年代風・色つき三つ巴", {
100
+ view: VIEW,
101
+ base: "#1e56b8",
102
+ ground: WHITE,
103
+ mat: GLOSS,
104
+ draw(s, base, accent) {
105
+ const t = truncatedIcosahedron();
106
+ let out = "";
107
+ for (const p of t.pentagons)
108
+ out += s.panel(p, mix(base, -0.55), { ink: true });
109
+ out += laidTriads(s, t, hexFrames(t), triad(0.0, 0.31, 0.9, 0.16, 0.2), [base, "#d8322f", accent ?? "#f2bf1b"], "#ffffff", 0.35);
110
+ out += s.strokes(t.edges, GREY, 0.9);
111
+ return out + lit(s, t.edges, 0.4);
112
+ },
113
+ });
114
+ /** The early 2000s: long thin triangles that sweep across each hexagon from one side to the next, in graphite and gold, with a red spark, over charcoal pentagons. */
115
+ export const BALL_SOCCER_2002_TRIANGLE_SWEEP = /* @__PURE__ */ ball("ball:soccer-2002-triangle-sweep", "Soccer, triangle sweep", "00年代風・三角の流れ", {
116
+ view: VIEW,
117
+ base: "#4a4f5c",
118
+ ground: "#f3efe4",
119
+ mat: GLOSS,
120
+ draw(s, base, accent) {
121
+ const t = truncatedIcosahedron();
122
+ const gold = accent ?? "#d9a420";
123
+ let out = "";
124
+ for (const p of t.pentagons)
125
+ out += s.panel(p, mix(base, -0.45), { ink: true });
126
+ const big = [[0.3, -0.03], [0.02, 0.2], [-0.05, 0.04]];
127
+ const small = [[0.27, 0.035], [0.12, 0.16], [0.1, 0.07]];
128
+ const frames = hexFrames(t);
129
+ const turns = [0, 1, 2].map((k) => (2 * Math.PI * k) / 3);
130
+ out += s.panels(frames.flatMap((f) => turns.map((a) => place(f, turned(big, a)))), base, { n: 1 });
131
+ out += s.panels(frames.flatMap((f) => turns.map((a) => place(f, turned(small, a + 0.1)))), gold, { n: 1 });
132
+ out += s.strokes(t.edges, GREY, 0.9);
133
+ return out + lit(s, t.edges, 0.4);
134
+ },
135
+ });
136
+ /** The mid 2000s: the 14-panel propeller layout (six propellers and eight triangles), with a fine line following each curved seam inside the panel, and a small ring on each triangle. */
137
+ export const BALL_SOCCER_2006_PROPELLER = /* @__PURE__ */ ball("ball:soccer-2006-propeller", "Soccer, 14-panel propeller", "14枚貼り・プロペラ形", {
138
+ view: { yaw: 40, pitch: 36, roll: 0 },
139
+ base: "#1f232b",
140
+ ground: "#f4f2ea",
141
+ mat: GLOSS,
142
+ draw(s, base, accent) {
143
+ const g = propellers14();
144
+ const gold = accent ?? "#c9962b";
145
+ let out = "";
146
+ for (const p of g.triangles)
147
+ out += s.panel(p, base, { n: 6, ink: true });
148
+ g.triangles.forEach((p, i) => {
149
+ out += s.panel(shrink(p, g.triangleCentres[i], 0.55), gold, { n: 4 });
150
+ });
151
+ // A line a little inside each propeller, following its seam.
152
+ g.propellers.forEach((p, i) => {
153
+ out += s.strokes([shrink(p, g.propellerCentres[i], 0.16).filter((_, j) => j % 2 === 0)], gold, 0.55, { closed: true, deco: true, opacity: 0.95 });
154
+ });
155
+ out += s.strokes(g.seams, "#3a3f4a", 1.4);
156
+ return out + lit(s, g.seams);
157
+ },
158
+ });
159
+ /** The early 2010s: the 8-panel layout, an octahedron whose edges are bent into S curves, with grooves for seams and fine contour lines across each panel. */
160
+ export const BALL_SOCCER_2010_GROOVED = /* @__PURE__ */ ball("ball:soccer-2010-grooved", "Soccer, 8-panel grooved", "8枚貼り・溝つき", {
161
+ view: { yaw: 32, pitch: 26, roll: 0 },
162
+ base: "#e9ecee",
163
+ ground: "#eceff0",
164
+ mat: { gloss: 0.7, shade: "#33404c", grain: { f: 1.6, a: 0.2 } },
165
+ draw(s, base, accent) {
166
+ const g = octahedron8();
167
+ const tone = [base, accent ?? "#cfe3d6"];
168
+ let out = "";
169
+ g.panels.forEach((p, i) => {
170
+ if (g.parity[i] === 1)
171
+ out += s.panel(p, tone[1], { n: 1 });
172
+ });
173
+ const groove = "#3f4b57";
174
+ g.panels.forEach((p, i) => {
175
+ out += s.strokes([shrink(p, g.centres[i], 0.4).filter((_, j) => j % 2 === 0)], groove, 0.35, { closed: true, deco: true, opacity: 0.6 });
176
+ });
177
+ out += s.strokes(g.seams, groove, 1.8);
178
+ out += s.strokes(g.seams, "#fff", 0.55, { deco: true, opacity: 0.55, dx: 0.5, dy: 0.55 });
179
+ return out;
180
+ },
181
+ });
182
+ /** The six gores of the thermobonded layout (see ball.soccer.panels.ts), for the layers drawn on them: only the gores whose tone is not the ground's are painted. */
183
+ function sixGores(s, tilt, tone, twist = 180) {
184
+ const g = gores(6, twist, tilt);
185
+ let out = "";
186
+ for (const { ring, gore } of g.pieces) {
187
+ if (gore % 3 !== 1)
188
+ continue;
189
+ out += s.panel(ring, tone, { n: 1 });
190
+ out += s.strokes([ring], tone, 0.5, { closed: true, deco: true });
191
+ }
192
+ return { g, out };
193
+ }
194
+ /** The mid 2010s: six twisted panels in white, crossed by wide ribbons that swirl round the ball in teal, orange and violet. */
195
+ export const BALL_SOCCER_2014_RIBBON = /* @__PURE__ */ ball("ball:soccer-2014-ribbon", "Soccer, 6-panel ribbons", "6枚貼り・リボン柄", {
196
+ view: { yaw: 20, pitch: 22, roll: 0 },
197
+ base: "#14a7a0",
198
+ ground: "#f5f5f1",
199
+ mat: { gloss: 0.9, shade: "#2a3450", grain: { f: 0.7, a: 0.07 } },
200
+ draw(s, base, accent) {
201
+ const { g, out: panels } = sixGores(s, [0, 0, 28], "#ebebe5");
202
+ const at = gorePoint(6, 180, [0, 0, 28]);
203
+ const cols = [base, accent ?? "#f08a24", "#7a4bc2"];
204
+ let out = panels;
205
+ // Three ribbons on a gore, spiralling: each is a leaf whose spine follows a curve across the gore.
206
+ for (let i = 0; i < 6; i++) {
207
+ for (let k = 0; k < 2; k++) {
208
+ const c = cols[(i + k) % 3];
209
+ const left = [];
210
+ const right = [];
211
+ const s0 = -0.75 + k * 0.7 + (i % 2) * 0.12;
212
+ for (let j = 0; j <= 10; j++) {
213
+ const u = j / 10;
214
+ const lat = s0 + 0.5 * u;
215
+ const w = 0.1 + 0.16 * Math.sin(Math.PI * u) ** 0.8;
216
+ left.push(at(i, 0.12 + 0.76 * u, lat));
217
+ right.push(at(i, 0.12 + 0.76 * u, lat + w));
218
+ }
219
+ out += s.panel([...left, ...right.reverse()], c, { n: 1 });
220
+ }
221
+ }
222
+ out += s.strokes(g.seams, GREY, 0.85);
223
+ return out + lit(s, g.seams, 0.5);
224
+ },
225
+ });
226
+ /** The late 2010s: six panels covered with square pixel blocks, thick where the ball is dark and thinning out toward the lighter side. */
227
+ export const BALL_SOCCER_2018_PIXEL = /* @__PURE__ */ ball("ball:soccer-2018-pixel", "Soccer, pixel blocks", "ピクセル柄", {
228
+ view: { yaw: 20, pitch: 22, roll: 0 },
229
+ base: "#2a2f3a",
230
+ ground: "#f2f2ee",
231
+ mat: { gloss: 0.9, shade: "#2a3450", grain: { f: 0.7, a: 0.07 } },
232
+ draw(s, base, accent) {
233
+ const { g, out: panels } = sixGores(s, [0, 0, 28], "#e7e7e1", 90);
234
+ const pal = [base, mix(base, 0.4), accent ?? "#d4472f", "#e6b53a", mix(base, 0.4)];
235
+ let out = panels;
236
+ const groups = pal.map(() => []);
237
+ const rows = 17, cols = 34;
238
+ for (let r = 1; r < rows - 1; r++) {
239
+ for (let c = 0; c < cols; c++) {
240
+ const lon = (2 * Math.PI * c) / cols, lat = Math.PI * (r / rows - 0.5);
241
+ // Dense on one side (longitude near 0.8 turns), a few scattered elsewhere.
242
+ const band = Math.cos(lon - 3.2 * lat - 4.1);
243
+ const density = band > 0 ? 0.04 + 0.8 * band ** 0.9 : 0.02;
244
+ if (noise(r, c) > density)
245
+ continue;
246
+ const d = (Math.PI / cols) * 1.7, e = (Math.PI / rows) * 0.85;
247
+ const corner = (a, b) => [Math.sin(lon + a) * Math.cos(lat + b), Math.sin(lat + b), Math.cos(lon + a) * Math.cos(lat + b)];
248
+ const k = Math.floor(noise(c, r + 50) * pal.length);
249
+ groups[k].push([corner(0, 0), corner(d, 0), corner(d, e), corner(0, e)]);
250
+ }
251
+ }
252
+ pal.forEach((c, k) => {
253
+ out += s.panels(groups[k], c, { n: 1, ink: k === 0 });
254
+ });
255
+ out += s.strokes(g.seams, GREY, 0.85);
256
+ return out + lit(s, g.seams, 0.5);
257
+ },
258
+ });
259
+ /** The early 2020s: twenty triangles (an icosahedron) in three warm tones, each carrying a shell of nested edges and a trail of speed lines. */
260
+ export const BALL_SOCCER_2022_SPEED_SHELL = /* @__PURE__ */ ball("ball:soccer-2022-speed-shell", "Soccer, 20-panel shell", "20枚貼り・貝殻柄", {
261
+ view: { yaw: 30, pitch: 24, roll: 8 },
262
+ base: "#8c1d3b",
263
+ ground: "#f1ece0",
264
+ mat: GLOSS,
265
+ draw(s, base, accent) {
266
+ const g = icosahedron();
267
+ const gold = accent ?? "#d9a93a";
268
+ const fill = [mix(base, 0.0), "#f1ece0", gold, mix(base, 0.35)];
269
+ let out = "";
270
+ fill.forEach((c, k) => {
271
+ out += s.panels(g.panels.filter((_, i) => g.colour[i] === k), c, { n: 4, ink: k === 0 });
272
+ });
273
+ g.panels.forEach((p, i) => {
274
+ const inner = g.colour[i] === 0 ? "#f1ece0" : base;
275
+ for (const k of [0.3, 0.58])
276
+ out += s.strokes([shrink(p, g.centres[i], k)], inner, 0.45, { closed: true, deco: true, opacity: 0.85 });
277
+ });
278
+ out += s.strokes(g.seams, mix(base, -0.5), 1.1);
279
+ return out + lit(s, g.seams);
280
+ },
281
+ });
282
+ /** A modern high-visibility training ball: 32 panels in fluorescent yellow-green, hot pink pentagons ringed in black, and three dark speed marks across each hexagon. */
283
+ export const BALL_SOCCER_TRAINING_HIGH_VIS = /* @__PURE__ */ ball("ball:soccer-training-high-vis", "Soccer, high-vis training", "蛍光トレーニングボール", {
284
+ view: VIEW,
285
+ base: "#ff2f7d",
286
+ ground: "#d8f21f",
287
+ mat: { gloss: 0.7, shade: "#3a5010", grain: { f: 1.3, a: 0.2 } },
288
+ draw(s, base, accent) {
289
+ const t = truncatedIcosahedron();
290
+ let out = "";
291
+ for (const p of t.pentagons)
292
+ out += s.panel(p, base, { ink: true });
293
+ t.pentagons.forEach((p, i) => {
294
+ out += s.strokes([shrink(p, t.pentagonCentres[i], 0.4)], accent ?? INK, 0.7, { closed: true, deco: true });
295
+ });
296
+ const dash = [[-0.1, -0.06], [0.1, -0.06], [0.1, -0.035], [-0.1, -0.035]];
297
+ const moved = dash.map(([x, y]) => [x + 0.05, y - 0.04]);
298
+ out += s.panels(hexFrames(t).flatMap((f) => [0, 1, 2].map((k) => place(f, turned(moved, (2 * Math.PI * k) / 3 + 0.5)))), accent ?? INK, { n: 1 });
299
+ out += s.strokes(t.edges, "#6d8a10", 1.1);
300
+ return out + lit(s, t.edges);
301
+ },
302
+ });
@@ -0,0 +1,19 @@
1
+ import { type BallSpec } from "./ball.engine.ts";
2
+ export declare const BALL_SOCCER_STARS_BLUE: import("./ball.core.ts").Piece<BallSpec>;
3
+ export declare const BALL_SOCCER_STARS_RED: import("./ball.core.ts").Piece<BallSpec>;
4
+ export declare const BALL_SOCCER_STARS_NIGHT: import("./ball.core.ts").Piece<BallSpec>;
5
+ export declare const BALL_SOCCER_HEXAGONS_CYAN: import("./ball.core.ts").Piece<BallSpec>;
6
+ export declare const BALL_SOCCER_HEXAGONS_MAGENTA: import("./ball.core.ts").Piece<BallSpec>;
7
+ export declare const BALL_SOCCER_HEXAGONS_LIME: import("./ball.core.ts").Piece<BallSpec>;
8
+ export declare const BALL_SOCCER_FLAMES_FIRE: import("./ball.core.ts").Piece<BallSpec>;
9
+ export declare const BALL_SOCCER_FLAMES_ICE: import("./ball.core.ts").Piece<BallSpec>;
10
+ export declare const BALL_SOCCER_FLAMES_TOXIC: import("./ball.core.ts").Piece<BallSpec>;
11
+ export declare const BALL_SOCCER_CHEVRONS_RED: import("./ball.core.ts").Piece<BallSpec>;
12
+ export declare const BALL_SOCCER_CHEVRONS_GREEN: import("./ball.core.ts").Piece<BallSpec>;
13
+ export declare const BALL_SOCCER_CHEVRONS_BLUE: import("./ball.core.ts").Piece<BallSpec>;
14
+ export declare const BALL_SOCCER_SWIRL_BLUE: import("./ball.core.ts").Piece<BallSpec>;
15
+ export declare const BALL_SOCCER_SWIRL_RED: import("./ball.core.ts").Piece<BallSpec>;
16
+ export declare const BALL_SOCCER_SWIRL_TEAL: import("./ball.core.ts").Piece<BallSpec>;
17
+ export declare const BALL_SOCCER_METALLIC_GOLD: import("./ball.core.ts").Piece<BallSpec>;
18
+ export declare const BALL_SOCCER_METALLIC_SILVER: import("./ball.core.ts").Piece<BallSpec>;
19
+ export declare const BALL_SOCCER_METALLIC_COBALT: import("./ball.core.ts").Piece<BallSpec>;