@johnmorrisdotca/kyogijo-stadiums 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 (244) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/NOTICE.md +4 -0
  3. package/README.md +71 -16
  4. package/dist/annotate.js +1 -1
  5. package/dist/athletics/describe.d.ts +8 -0
  6. package/dist/athletics/describe.js +41 -0
  7. package/dist/athletics/events.d.ts +17 -0
  8. package/dist/athletics/events.js +48 -0
  9. package/dist/athletics/facilities.d.ts +80 -0
  10. package/dist/athletics/facilities.js +176 -0
  11. package/dist/athletics/infield.d.ts +79 -0
  12. package/dist/athletics/infield.js +166 -0
  13. package/dist/athletics/layout.d.ts +13 -0
  14. package/dist/athletics/layout.js +98 -0
  15. package/dist/athletics/oval.d.ts +57 -0
  16. package/dist/athletics/oval.js +116 -0
  17. package/dist/athletics/plan.d.ts +97 -0
  18. package/dist/athletics/plan.js +355 -0
  19. package/dist/athletics/races.d.ts +102 -0
  20. package/dist/athletics/races.js +355 -0
  21. package/dist/athletics/steeplechase.d.ts +72 -0
  22. package/dist/athletics/steeplechase.js +196 -0
  23. package/dist/athletics/stencil.d.ts +13 -0
  24. package/dist/athletics/stencil.js +85 -0
  25. package/dist/athletics/track.d.ts +54 -0
  26. package/dist/athletics/track.js +105 -0
  27. package/dist/athletics/types.d.ts +77 -0
  28. package/dist/athletics/types.js +1 -0
  29. package/dist/athletics-entry.d.ts +17 -0
  30. package/dist/athletics-entry.js +11 -0
  31. package/dist/athletics.style.d.ts +16 -0
  32. package/dist/athletics.style.js +51 -0
  33. package/dist/atlas-entry.d.ts +4 -2
  34. package/dist/atlas-entry.js +3 -2
  35. package/dist/atlas.d.ts +83 -7
  36. package/dist/atlas.js +108 -8
  37. package/dist/charts-entry.d.ts +6 -1
  38. package/dist/charts-entry.js +3 -0
  39. package/dist/charts.athletics.d.ts +183 -0
  40. package/dist/charts.athletics.js +455 -0
  41. package/dist/charts.curling.heat.d.ts +24 -0
  42. package/dist/charts.curling.heat.js +116 -0
  43. package/dist/charts.curling.js +14 -3
  44. package/dist/charts.pool.d.ts +67 -0
  45. package/dist/charts.pool.js +76 -0
  46. package/dist/charts.skating.d.ts +204 -0
  47. package/dist/charts.skating.js +426 -0
  48. package/dist/charts.types.d.ts +53 -1
  49. package/dist/court.d.ts +85 -2
  50. package/dist/court.js +102 -7
  51. package/dist/court.more.d.ts +46 -0
  52. package/dist/court.more.js +219 -0
  53. package/dist/courts.style.d.ts +14 -2
  54. package/dist/courts.style.js +51 -4
  55. package/dist/crowd.d.ts +154 -0
  56. package/dist/crowd.draw.d.ts +17 -0
  57. package/dist/crowd.draw.js +198 -0
  58. package/dist/crowd.js +465 -0
  59. package/dist/crowd.park.d.ts +19 -0
  60. package/dist/crowd.park.js +153 -0
  61. package/dist/curling.stats.d.ts +271 -0
  62. package/dist/curling.stats.js +301 -0
  63. package/dist/draw.d.ts +16 -0
  64. package/dist/draw.js +318 -35
  65. package/dist/element-entry.d.ts +1 -1
  66. package/dist/element-entry.js +1 -1
  67. package/dist/element.d.ts +13 -2
  68. package/dist/element.js +77 -3
  69. package/dist/features.js +131 -0
  70. package/dist/fields.kit.d.ts +2 -2
  71. package/dist/fields.types.d.ts +18 -4
  72. package/dist/frames.providers.js +63 -8
  73. package/dist/geojson.js +3 -0
  74. package/dist/geometry-entry.d.ts +2 -1
  75. package/dist/geometry-entry.js +2 -1
  76. package/dist/geometry.d.ts +20 -0
  77. package/dist/geometry.js +78 -1
  78. package/dist/grounds.d.ts +4 -0
  79. package/dist/grounds.data.js +12 -0
  80. package/dist/hardwood.d.ts +31 -0
  81. package/dist/hardwood.js +157 -0
  82. package/dist/heat.js +4 -3
  83. package/dist/heat.types.d.ts +5 -0
  84. package/dist/heat.zones.d.ts +2 -2
  85. package/dist/heat.zones.js +154 -6
  86. package/dist/homeside.js +17 -0
  87. package/dist/index.d.ts +16 -2
  88. package/dist/index.js +10 -1
  89. package/dist/layers.d.ts +1 -1
  90. package/dist/layers.env.d.ts +3 -1
  91. package/dist/layers.env.js +4 -2
  92. package/dist/layers.js +4 -4
  93. package/dist/leagues/athletics.d.ts +63 -0
  94. package/dist/leagues/athletics.js +87 -0
  95. package/dist/leagues/courts.d.ts +269 -4
  96. package/dist/leagues/courts.js +155 -1
  97. package/dist/leagues/skating.d.ts +145 -0
  98. package/dist/leagues/skating.js +73 -0
  99. package/dist/leagues/sources.js +20 -0
  100. package/dist/leagues/types.d.ts +1 -1
  101. package/dist/leagues-entry.d.ts +4 -2
  102. package/dist/leagues-entry.js +2 -1
  103. package/dist/leagues.d.ts +14 -4
  104. package/dist/leagues.js +146 -5
  105. package/dist/look.d.ts +3 -3
  106. package/dist/look.js +39 -6
  107. package/dist/outline.d.ts +1 -1
  108. package/dist/outline.js +30 -2
  109. package/dist/pageant.d.ts +120 -0
  110. package/dist/pageant.draw.d.ts +21 -0
  111. package/dist/pageant.draw.js +171 -0
  112. package/dist/pageant.js +207 -0
  113. package/dist/pageant.style.d.ts +8 -0
  114. package/dist/pageant.style.js +42 -0
  115. package/dist/png.d.ts +8 -1
  116. package/dist/png.js +21 -1
  117. package/dist/pool.d.ts +176 -0
  118. package/dist/pool.figures.d.ts +304 -0
  119. package/dist/pool.figures.js +144 -0
  120. package/dist/pool.js +304 -0
  121. package/dist/pool.kit.d.ts +48 -0
  122. package/dist/pool.kit.js +141 -0
  123. package/dist/pool.labels.d.ts +20 -0
  124. package/dist/pool.labels.js +257 -0
  125. package/dist/pool.race.d.ts +65 -0
  126. package/dist/pool.race.js +140 -0
  127. package/dist/pool.replay.d.ts +46 -0
  128. package/dist/pool.replay.js +127 -0
  129. package/dist/pool.section.d.ts +13 -0
  130. package/dist/pool.section.js +83 -0
  131. package/dist/pool.style.d.ts +20 -0
  132. package/dist/pool.style.js +169 -0
  133. package/dist/pool.types.d.ts +145 -0
  134. package/dist/pool.types.js +3 -0
  135. package/dist/pool.words.d.ts +13 -0
  136. package/dist/pool.words.js +101 -0
  137. package/dist/ranges.names.js +47 -3
  138. package/dist/replay-entry.d.ts +3 -0
  139. package/dist/replay-entry.js +2 -0
  140. package/dist/restyle.js +1 -1
  141. package/dist/score.js +70 -5
  142. package/dist/sheet.d.ts +3 -0
  143. package/dist/sheet.js +7 -3
  144. package/dist/skating/describe.d.ts +7 -0
  145. package/dist/skating/describe.js +44 -0
  146. package/dist/skating/events.d.ts +24 -0
  147. package/dist/skating/events.js +47 -0
  148. package/dist/skating/figure.d.ts +24 -0
  149. package/dist/skating/figure.js +37 -0
  150. package/dist/skating/long.d.ts +54 -0
  151. package/dist/skating/long.js +111 -0
  152. package/dist/skating/parts.d.ts +43 -0
  153. package/dist/skating/parts.js +40 -0
  154. package/dist/skating/plan.d.ts +55 -0
  155. package/dist/skating/plan.js +197 -0
  156. package/dist/skating/short.d.ts +47 -0
  157. package/dist/skating/short.js +89 -0
  158. package/dist/skating/track.d.ts +66 -0
  159. package/dist/skating/track.js +94 -0
  160. package/dist/skating/types.d.ts +57 -0
  161. package/dist/skating/types.js +3 -0
  162. package/dist/skating-entry.d.ts +17 -0
  163. package/dist/skating-entry.js +11 -0
  164. package/dist/skating.style.d.ts +4 -0
  165. package/dist/skating.style.js +24 -0
  166. package/dist/strings.d.ts +296 -0
  167. package/dist/strings.js +328 -11
  168. package/dist/style.d.ts +2 -0
  169. package/dist/style.js +11 -1
  170. package/dist/surfaces/artistic.d.ts +9 -0
  171. package/dist/surfaces/artistic.js +94 -0
  172. package/dist/surfaces/athletics.d.ts +16 -0
  173. package/dist/surfaces/athletics.js +132 -0
  174. package/dist/surfaces/baseball.js +15 -0
  175. package/dist/surfaces/basketball.floor.d.ts +27 -0
  176. package/dist/surfaces/basketball.floor.js +83 -0
  177. package/dist/surfaces/basketball.gear.d.ts +27 -0
  178. package/dist/surfaces/basketball.gear.js +90 -0
  179. package/dist/surfaces/basketball.js +43 -21
  180. package/dist/surfaces/curling.d.ts +16 -0
  181. package/dist/surfaces/curling.fold.d.ts +67 -0
  182. package/dist/surfaces/curling.fold.js +107 -0
  183. package/dist/surfaces/curling.js +37 -3
  184. package/dist/surfaces/dive.d.ts +9 -0
  185. package/dist/surfaces/dive.js +128 -0
  186. package/dist/surfaces/field.d.ts +7 -2
  187. package/dist/surfaces/field.js +15 -9
  188. package/dist/surfaces/hockey.js +1 -0
  189. package/dist/surfaces/net.d.ts +2 -1
  190. package/dist/surfaces/net.js +160 -15
  191. package/dist/surfaces/polo.d.ts +12 -0
  192. package/dist/surfaces/polo.js +159 -0
  193. package/dist/surfaces/pool.d.ts +27 -0
  194. package/dist/surfaces/pool.js +198 -0
  195. package/dist/surfaces/skating.d.ts +6 -0
  196. package/dist/surfaces/skating.js +62 -0
  197. package/dist/surfaces/soccer.js +2 -1
  198. package/dist/surfaces/surface.d.ts +44 -0
  199. package/dist/surfaces/venue.d.ts +15 -0
  200. package/dist/surfaces/venue.js +95 -0
  201. package/dist/tenants.d.ts +77 -0
  202. package/dist/tenants.data.d.ts +8 -0
  203. package/dist/tenants.data.js +945 -0
  204. package/dist/tenants.js +46 -0
  205. package/dist/turn-entry.d.ts +12 -0
  206. package/dist/turn-entry.js +7 -0
  207. package/dist/turn.camera.d.ts +105 -0
  208. package/dist/turn.camera.js +168 -0
  209. package/dist/turn.dom.d.ts +40 -0
  210. package/dist/turn.dom.js +351 -0
  211. package/dist/turn.kit.d.ts +86 -0
  212. package/dist/turn.kit.js +110 -0
  213. package/dist/turn.markup.d.ts +48 -0
  214. package/dist/turn.markup.js +108 -0
  215. package/dist/turn.model.d.ts +78 -0
  216. package/dist/turn.model.js +91 -0
  217. package/dist/turn.style.d.ts +5 -0
  218. package/dist/turn.style.js +55 -0
  219. package/dist/types.d.ts +183 -18
  220. package/dist/units.d.ts +1 -1
  221. package/dist/units.js +15 -1
  222. package/dist/uprights.board.d.ts +17 -0
  223. package/dist/uprights.board.js +59 -0
  224. package/dist/uprights.d.ts +37 -0
  225. package/dist/uprights.fields.d.ts +32 -0
  226. package/dist/uprights.fields.js +172 -0
  227. package/dist/uprights.goal.d.ts +49 -0
  228. package/dist/uprights.goal.js +69 -0
  229. package/dist/uprights.js +160 -0
  230. package/dist/uprights.more.d.ts +7 -0
  231. package/dist/uprights.more.js +183 -0
  232. package/dist/uprights.net.d.ts +12 -0
  233. package/dist/uprights.net.js +109 -0
  234. package/dist/uprights.netkit.d.ts +28 -0
  235. package/dist/uprights.netkit.js +67 -0
  236. package/dist/uprights.pools.d.ts +8 -0
  237. package/dist/uprights.pools.js +190 -0
  238. package/dist/uprights.rinks.d.ts +27 -0
  239. package/dist/uprights.rinks.js +106 -0
  240. package/dist/uprights.track.d.ts +50 -0
  241. package/dist/uprights.track.js +246 -0
  242. package/dist/version.d.ts +1 -1
  243. package/dist/version.js +1 -1
  244. package/package.json +19 -2
@@ -0,0 +1,198 @@
1
+ import { el, num } from "../format.js";
2
+ import { feet } from "../pool.js";
3
+ import { box, deckMarkup, leastWidth, paintDefs, poolIds, ropeMarkup, waterMarkup } from "../pool.kit.js";
4
+ import { raceArt } from "../pool.labels.js";
5
+ import { sectionOf } from "../pool.section.js";
6
+ import { SWIMMING } from "../pool.figures.js";
7
+ import { atEnds, edges, ft, quarterTurn, textOn } from "./surface.js";
8
+ /** The gutter round the water, in metres: the width of the coping the pool is drawn with. */
9
+ export const GUTTER = 0.4;
10
+ /**
11
+ * The body of a swimming pool: every figure is the rules' (`SWIMMING`, pool.figures.ts). The lane markings on the floor are 46 m (21 m in a 25 m pool) long and end 2 m from the walls in a cross line 1 m long (CR 16.2.15); a
12
+ * cross line 0.5 m long at 15 m from each end; the touch panels 2.4 m wide at the walls with the target lines; the ropes in the rules' colours with red floats within 5 m of the walls and a mark at 15 m and 25 m;
13
+ * the starting blocks with their lane numbers; the backstroke flags 5 m from each end, and the false start rope 15 m from the starting end.
14
+ */
15
+ export function swimBody(o, plan, ids) {
16
+ const L = plan.length;
17
+ const W = plan.width;
18
+ const full = o.detail === "full";
19
+ // Small fixtures are drawn a little larger than they stand, as lines are, unless the true sizes are asked for.
20
+ const s = o.exact ? 1 : 1.5;
21
+ let base = box(o, "gutter", "ky-boards", -GUTTER, -GUTTER, L + GUTTER, W + GUTTER);
22
+ base += waterMarkup(o, ids, plan.look, 0, 0, L, W);
23
+ let lines = "";
24
+ const lw = leastWidth(o, SWIMMING.laneLine.width, 0.32);
25
+ const marks = [];
26
+ // Under pace bars the lanes are the whole race laid flat, not one length of the pool: the furniture that belongs to a length (floor lines and crosses, the marks at 15 m and 25 m, the red ends of the ropes,
27
+ // flags, the false start rope, blocks and panels) is left off and the ropes are plain, so that the picture reads as a chart.
28
+ const neutral = plan.race?.pace !== null && plan.race?.pace !== undefined;
29
+ // The lane markings and their cross lines on the floor: a line along the middle of each lane, 2 m short of each wall, ending in a cross line 1 m long.
30
+ const gap = SWIMMING.laneLine.endGap;
31
+ const half = SWIMMING.laneLine.cross / 2;
32
+ let d = "";
33
+ let crosses = "";
34
+ for (const lane of plan.lanes) {
35
+ d += `M${num(feet(gap))} ${num(feet(lane.y))}H${num(feet(L - gap))}`;
36
+ d += `M${num(feet(gap))} ${num(feet(lane.y - half))}V${num(feet(lane.y + half))}M${num(feet(L - gap))} ${num(feet(lane.y - half))}V${num(feet(lane.y + half))}`;
37
+ if (full)
38
+ for (const x of [SWIMMING.markAt15, L - SWIMMING.markAt15])
39
+ crosses += `M${num(feet(x))} ${num(feet(lane.y - SWIMMING.target.crossAt15 / 2))}V${num(feet(lane.y + SWIMMING.target.crossAt15 / 2))}`;
40
+ }
41
+ if (!neutral)
42
+ lines += el("path", { class: ft(o, "lane-lines", "ky-line"), d: d + crosses, "stroke-width": lw, fill: "none" });
43
+ // The touch panels on the end walls, 2.4 m wide in each lane, with the target line down the middle and its cross line.
44
+ if (plan.pads && !neutral) {
45
+ const depth = o.exact ? 0.05 : 0.3;
46
+ const pad = SWIMMING.pad.width;
47
+ let pads = "";
48
+ let targets = "";
49
+ for (const lane of plan.lanes) {
50
+ for (const end of [0, 1]) {
51
+ const x0 = end === 0 ? 0 : L - depth;
52
+ pads += `M${num(feet(x0))} ${num(feet(lane.y - pad / 2))}h${num(feet(depth))}v${num(feet(pad))}h${num(feet(-depth))}Z`;
53
+ const wall = end === 0 ? 0 : L;
54
+ const inward = end === 0 ? 1 : -1;
55
+ targets += `M${num(feet(wall))} ${num(feet(lane.y))}h${num(feet(inward * depth))}`;
56
+ if (full)
57
+ targets += `M${num(feet(wall + inward * depth * 0.5))} ${num(feet(lane.y - SWIMMING.target.cross / 2))}v${num(feet(SWIMMING.target.cross))}`;
58
+ }
59
+ }
60
+ lines += el("path", { class: ft(o, "touch-pads", "ky-pl-pad"), d: pads });
61
+ lines += el("path", { class: ft(o, "lane-lines", "ky-line"), d: targets, "stroke-width": lw * 0.85, fill: "none" });
62
+ }
63
+ // The ropes: floats in the lane's colour, red within 5 m of each wall, and a distinct run at 15 m and 25 m from the walls.
64
+ const runs = [];
65
+ const red = SWIMMING.redEnds;
66
+ const run = SWIMMING.markRun / 2;
67
+ for (const rope of plan.ropes) {
68
+ if (neutral) {
69
+ runs.push(["white", 0, L, rope.y]);
70
+ continue;
71
+ }
72
+ runs.push([rope.colour, red, L - red, rope.y]);
73
+ runs.push(["red", 0, red, rope.y], ["red", L - red, L, rope.y]);
74
+ const at = [SWIMMING.markAt15, L - SWIMMING.markAt15, ...(plan.course === "long" ? [SWIMMING.markAt25] : [])];
75
+ for (const x of at)
76
+ runs.push(["white", Math.max(0, x - run), Math.min(L, x + run), rope.y]);
77
+ }
78
+ lines += ropeMarkup(o, runs, SWIMMING.floatDiameter, 0.45);
79
+ // The marks on the deck at 15 m (and 25 m) from the walls, and the standards of the flags: on both sides of the pool (CR 16.1.10).
80
+ if (full && !neutral) {
81
+ let ticks = "";
82
+ for (const x of [SWIMMING.markAt15, L - SWIMMING.markAt15, ...(plan.course === "long" ? [SWIMMING.markAt25] : [])]) {
83
+ for (const [y0, y1] of [[-GUTTER, 0], [W, W + GUTTER]])
84
+ ticks += `M${num(feet(x))} ${num(feet(y0))}V${num(feet(y1))}`;
85
+ }
86
+ lines += el("path", { class: ft(o, "lane-lines", "ky-line"), d: ticks, "stroke-width": feet(0.22), fill: "none" });
87
+ }
88
+ // The false start rope, 15 m from the starting end, on its standards.
89
+ if (plan.falseStart && !neutral) {
90
+ const x = SWIMMING.falseStart.at;
91
+ lines += el("path", { class: ft(o, "false-start-rope", "ky-pl-fs"), d: `M${num(feet(x))} ${num(feet(-0.7))}V${num(feet(W + 0.7))}`, "stroke-width": feet(0.1) * s, fill: "none", "stroke-dasharray": `${num(feet(0.5))} ${num(feet(0.3))}` });
92
+ if (full)
93
+ for (const y of [-0.7, W + 0.7])
94
+ lines += el("circle", { class: "ky-pl-st", cx: feet(x), cy: feet(y), r: feet(0.22) * s });
95
+ }
96
+ // The backstroke flags: a rope across the pool 5 m from each wall, flags of two colours hanging from it.
97
+ if (plan.flags && !neutral) {
98
+ for (const x of [SWIMMING.flags.at, L - SWIMMING.flags.at]) {
99
+ const fx = feet(x);
100
+ lines += el("path", { class: ft(o, "backstroke-flags", "ky-pl-fa"), d: `M${num(fx)} ${num(feet(-0.6))}V${num(feet(W + 0.6))}`, "stroke-width": feet(0.26) * s, fill: "none", "stroke-dasharray": `${num(feet(0.4))} ${num(feet(0.4))}` });
101
+ lines += el("path", { class: ft(o, "backstroke-flags", "ky-pl-fb2"), d: `M${num(fx)} ${num(feet(-0.6))}V${num(feet(W + 0.6))}`, "stroke-width": feet(0.26) * s, fill: "none", "stroke-dasharray": `0 ${num(feet(0.4))} ${num(feet(0.4))} 0` });
102
+ if (full)
103
+ for (const y of [-0.6, W + 0.6])
104
+ lines += el("circle", { class: "ky-pl-st", cx: fx, cy: feet(y), r: feet(0.22) * s });
105
+ }
106
+ }
107
+ // The starting blocks, 0.5 by 0.6 m, one in each lane at each end, numbered on the top (CR 16.2.8 and 16.2.9).
108
+ if (plan.blocks && !neutral) {
109
+ const bw = SWIMMING.block.width * s;
110
+ const bl = SWIMMING.block.length * s;
111
+ let blocks = "";
112
+ let numbers = "";
113
+ for (const lane of plan.lanes) {
114
+ for (const end of [0, 1]) {
115
+ const x0 = end === 0 ? -0.08 - bl : L + 0.08;
116
+ blocks += `M${num(feet(x0))} ${num(feet(lane.y - bw / 2))}h${num(feet(bl))}v${num(feet(bw))}h${num(feet(-bl))}Z`;
117
+ if (full)
118
+ numbers += textOn(o.portrait, feet(x0 + bl / 2), feet(lane.y) + feet(bw) * 0.32, String(lane.number), { size: feet(bw) * 0.72, anchor: "middle", cls: "ky-pl-bn", weight: 800 });
119
+ }
120
+ }
121
+ lines += el("path", { class: ft(o, "starting-blocks", "ky-pl-bk"), d: blocks });
122
+ lines += numbers;
123
+ }
124
+ if (o.landmarks === true) {
125
+ const top = plan.lanes[0];
126
+ const mid = plan.lanes[Math.floor(plan.lanes.length / 2)];
127
+ const ropeY = plan.ropes[1]?.y ?? plan.ropes[0].y;
128
+ marks.push({ id: "lane-rope", x: feet(L * 0.62), y: feet(ropeY), side: "top" });
129
+ if (!neutral) {
130
+ marks.push({ id: "lane-line", x: feet(L * 0.35), y: feet(mid.y), side: "bottom" }, { id: "lane-end-cross", x: feet(SWIMMING.laneLine.endGap), y: feet(top.y), side: "top" }, { id: "fifteen-metre-mark", x: feet(SWIMMING.markAt15), y: 0, side: "top" });
131
+ }
132
+ if (plan.pads && !neutral)
133
+ marks.push({ id: "touch-pad", x: feet(0.15), y: feet(plan.lanes[plan.lanes.length - 1].y), side: "bottom" });
134
+ if (plan.blocks && !neutral)
135
+ marks.push({ id: "starting-block", x: feet(-0.6), y: feet(plan.lanes[plan.lanes.length - 1].y), side: "bottom" });
136
+ if (plan.flags && !neutral)
137
+ marks.push({ id: "backstroke-flags", x: feet(SWIMMING.flags.at), y: feet(W), side: "bottom" });
138
+ if (plan.falseStart && !neutral)
139
+ marks.push({ id: "false-start-rope", x: feet(SWIMMING.falseStart.at), y: feet(W), side: "bottom" });
140
+ marks.push({ id: "gutter", x: feet(L * 0.8), y: feet(W + GUTTER / 2), side: "bottom" });
141
+ }
142
+ return { base, lines, marks, line: lw };
143
+ }
144
+ /**
145
+ * A swimming pool lying wide with its deck: the body, the deck round it in the colour or the tiles asked for, the data of a race at the walls and over the water, and a side section under the plan if
146
+ * it is asked for. The pool's water is the surface's `box`; the deck is the margin.
147
+ */
148
+ export function swimming(o, plan, ctx = {}) {
149
+ const L = feet(plan.length);
150
+ const W = feet(plan.width);
151
+ const ids = ctx.ids ?? poolIds(o.id);
152
+ const m = ctx.bare === true ? 0 : (o.margin ?? feet(SWIMMING.deck));
153
+ const body = swimBody(o, plan, ids);
154
+ const art = ctx.bare === true ? raceArt({ ...plan, race: undefined }, o) : raceArt(plan, o);
155
+ const section = ctx.bare === true ? sectionOf({ ...plan, section: undefined }, o, 0) : sectionOf(plan, o, W + feet(GUTTER) + m);
156
+ // The view: the deck all round, the plates at the walls, the title or the distances above, the section below.
157
+ // The depth of a section is written to the left of it.
158
+ const left = m + Math.max(art.reachLeft, section.height > 0 ? feet(4) : 0);
159
+ const right = m + art.reachRight;
160
+ const topExtra = Math.max(0, art.reachTop, plan.race?.event === undefined ? 0 : feet(1.6));
161
+ const view0 = { x: -left, y: -m - topExtra, w: L + left + right, h: W + 2 * m + topExtra + (section.height > 0 ? section.height + feet(0.6) : 0) };
162
+ const defs = ctx.bare === true ? "" : paintDefs(ids, plan.look, plan.deck, plan.seed) + section.defs;
163
+ const basis = (ctx.bare === true ? "" : deckMarkup(o, ids, plan.deck, view0.x, view0.y, view0.w, view0.h)) + body.base;
164
+ let lines = body.lines + art.pace + art.left + art.right + art.top;
165
+ if (section.markup !== "")
166
+ lines += section.markup;
167
+ const turned = o.portrait;
168
+ const cy = W / 2;
169
+ // How far the blocks reach beyond the walls, in feet.
170
+ const blockReach = feet(0.08 + SWIMMING.block.length * (o.exact ? 1 : 1.5));
171
+ const plate = turned ? { cx: L / 2, cy, w: W * 0.9, h: L * 0.34 } : { cx: L / 2, cy, w: L * 0.34, h: W * 0.62 };
172
+ const surface = {
173
+ sport: "swimming",
174
+ view: view0,
175
+ base: basis,
176
+ lines,
177
+ defs,
178
+ // The teams' names stand on the deck beyond the blocks.
179
+ left: { cx: -(blockReach + (m - blockReach) / 2), cy, w: W, h: Math.max(1, m - blockReach), rot: -90 },
180
+ right: { cx: L + blockReach + (m - blockReach) / 2, cy, w: W, h: Math.max(1, m - blockReach), rot: 90 },
181
+ plate,
182
+ turned,
183
+ };
184
+ surface.box = { x: 0, y: 0, w: L, h: W };
185
+ surface.lineRef = { width: body.line, feet: 1 };
186
+ surface.ranges = {
187
+ half: atEnds((end) => (end === "left" ? edges(0, 0, L / 2, W) : edges(L / 2, 0, L, W))),
188
+ "pool-end": atEnds((end) => (end === "left" ? edges(0, 0, feet(15), W) : edges(L - feet(15), 0, L, W))),
189
+ };
190
+ if (o.landmarks === true)
191
+ surface.marks = o.detail === "full" ? body.marks : body.marks.filter((mark) => !["lane-end-cross", "fifteen-metre-mark"].includes(mark.id));
192
+ if (turned) {
193
+ const t = quarterTurn(view0);
194
+ surface.view = t.view;
195
+ surface.turn = t.turn;
196
+ }
197
+ return surface;
198
+ }
@@ -0,0 +1,6 @@
1
+ import type { SkatingPlan } from "../skating/plan.ts";
2
+ import { type BuildOptions, type Surface } from "./surface.ts";
3
+ /** Feet in a metre. */
4
+ export declare const K: number;
5
+ /** The surface of the plan lying wide. `margin` is the ground round what is drawn, in feet. */
6
+ export declare function skatingSurface(o: BuildOptions, plan: SkatingPlan, margin: number): Surface;
@@ -0,0 +1,62 @@
1
+ // The skating rink's surface lying wide, from its plan (skating/plan.ts): the ice, the floor of the infield, the warm-up lane, the padding, the boards, the furniture, then every painted line and the
2
+ // blocks. The plan is in metres; the drawing is in feet, as every surface lies, so the whole is drawn inside a group that scales metres to feet and moves the rink's box to the origin.
3
+ import { el } from "../format.js";
4
+ import { areaD, marks, strokes } from "./field.js";
5
+ import { atEnds, edges, ft, quarterTurn } from "./surface.js";
6
+ /** Feet in a metre. */
7
+ export const K = 1 / 0.3048;
8
+ const feetBox = (b, ox, oy) => edges((b.x0 - ox) * K, (b.y0 - oy) * K, (b.x1 - ox) * K, (b.y1 - oy) * K);
9
+ /** A plan's named range in feet, as a surface lists them. */
10
+ function rangeOf(r, ox, oy) {
11
+ return "left" in r ? atEnds((end) => feetBox(end === "left" ? r.left : r.right, ox, oy)) : feetBox(r, ox, oy);
12
+ }
13
+ /** The surface of the plan lying wide. `margin` is the ground round what is drawn, in feet. */
14
+ export function skatingSurface(o, plan, margin) {
15
+ const ox = plan.box.x0;
16
+ const oy = plan.box.y0;
17
+ const full = o.detail === "full";
18
+ const view0 = { x: (plan.extent.x0 - ox) * K - margin, y: (plan.extent.y0 - oy) * K - margin, w: (plan.extent.x1 - plan.extent.x0) * K + 2 * margin, h: (plan.extent.y1 - plan.extent.y0) * K + 2 * margin };
19
+ const place = `scale(${K.toFixed(6)}) translate(${(-ox).toFixed(4)} ${(-oy).toFixed(4)})`;
20
+ const group = (inner, cls) => el("g", { class: cls, transform: place }, inner);
21
+ const turned = o.portrait;
22
+ // Under everything: the apron, then the ice, the floor, the warm-up lane, the padding and the furniture, in the plan's order.
23
+ let base = el("rect", { class: ft(o, "apron", "ky-apron"), x: view0.x, y: view0.y, width: view0.w, height: view0.h });
24
+ let ground = "";
25
+ for (const a of plan.areas)
26
+ ground += el("path", { class: ft(o, a.feature, a.cls), d: areaD(a), "fill-rule": a.evenodd === true ? "evenodd" : undefined });
27
+ base += group(ground, "ky-ska-ground");
28
+ const thick = o.exact ? plan.lineWidth : plan.drawnLine;
29
+ const lines = group(strokes(plan, o) + marks(plan, o), "ky-ska-lines");
30
+ const W = (plan.box.x1 - plan.box.x0) * K;
31
+ const H = (plan.box.y1 - plan.box.y0) * K;
32
+ const surface = {
33
+ sport: "skating",
34
+ view: view0,
35
+ base,
36
+ lines,
37
+ defs: "",
38
+ // A team's name, in a score, is written on the ice either side of the middle.
39
+ left: { cx: W * 0.27, cy: H / 2, w: W * 0.2, h: H * 0.11, rot: 0 },
40
+ right: { cx: W * 0.73, cy: H / 2, w: W * 0.2, h: H * 0.11, rot: 0 },
41
+ plate: { cx: W / 2, cy: H / 2, w: Math.min(W * 0.34, 140), h: Math.min(W * 0.34, 140) * 0.52 },
42
+ turned,
43
+ bannersOver: true,
44
+ onColour: false,
45
+ };
46
+ surface.box = { x: 0, y: 0, w: W, h: H };
47
+ surface.lineRef = { width: thick, feet: K };
48
+ const ranges = {};
49
+ for (const [name, r] of Object.entries(plan.ranges))
50
+ ranges[name] = rangeOf(r, ox, oy);
51
+ surface.ranges = ranges;
52
+ if (o.landmarks === true) {
53
+ const m = plan.marks.map((p) => ({ id: p.id, x: (p.x - ox) * K, y: (p.y - oy) * K, side: p.side }));
54
+ surface.marks = full ? m : m.filter((p) => !p.id.startsWith("~"));
55
+ }
56
+ if (turned) {
57
+ const t = quarterTurn(view0);
58
+ surface.view = t.view;
59
+ surface.turn = t.turn;
60
+ }
61
+ return surface;
62
+ }
@@ -140,7 +140,7 @@ export function soccer(b, o) {
140
140
  // The ends in the team's colour, in a score: the penalty area (or what a small pitch has in its place).
141
141
  const zoneDepth = Math.max(spec.penaltyDepth, L * 0.12);
142
142
  const zoneWidth = Math.max(spec.area === "arcs" ? spec.areaLine + 2 * spec.penaltyDepth : spec.area === "semicircle" ? 2 * spec.penaltyDepth : lay.penaltyHalfWidth * 2, W * 0.4);
143
- if (o.score) {
143
+ if (o.score && o.pageant !== true) {
144
144
  // A rectangle at each end: the penalty area on a full pitch, a box that holds the name on the others (their areas are curved).
145
145
  for (const side of [0, 1])
146
146
  inside += el("rect", { class: `ky-zone ky-zone-${side === 0 ? "left" : "right"}`, x: side === 0 ? 0 : L - zoneDepth, y: cy - zoneWidth / 2, width: zoneDepth, height: zoneWidth });
@@ -231,6 +231,7 @@ export function soccer(b, o) {
231
231
  };
232
232
  surface.lineRef = { width: lw, feet: K };
233
233
  surface.box = { x: 0, y: 0, w: Lf, h: Wf };
234
+ surface.centreRadius = spec.centreRadius * K;
234
235
  // The penalty area reaches as far as its lines do: the area, the arc beyond it and a small pitch's curved area; and a little more.
235
236
  const arcBeyond = spec.arcRadius > 0 && lay.spot > 0 && lay.penaltyDepth > lay.spot ? Math.max(0, spec.arcRadius - (lay.penaltyDepth - lay.spot)) : 0;
236
237
  const curved = spec.area === "arcs" || spec.area === "semicircle" ? spec.penaltyDepth : 0;
@@ -1,4 +1,5 @@
1
1
  import type { Ballpark } from "../ballpark.ts";
2
+ import type { Hardwood } from "../hardwood.ts";
2
3
  import type { Box, Detail, GoalInfo, GoalStyle, Sport, StripePattern } from "../types.ts";
3
4
  /** Where a team's name and logo go, and how its words lie. */
4
5
  export interface Zone {
@@ -20,6 +21,26 @@ export interface PlateSpot {
20
21
  w: number;
21
22
  h: number;
22
23
  }
24
+ /** A place on a surface for a pageant's picture, in the surface's frame in feet; a `disc` is the diameter of the round room the picture must lie in (a curling house). */
25
+ export interface PageantSpot extends PlateSpot {
26
+ disc?: number;
27
+ }
28
+ /** What a surface says of where a pageant's pictures go, when it is not the plain halves and the middle. */
29
+ export interface PageantPlan {
30
+ /** Where the first (left) team's picture goes, and the second's (right), when not in the halves: a diamond's outfield and infield, a sheet's two houses. */
31
+ left?: PageantSpot;
32
+ right?: PageantSpot;
33
+ /** The emblem's place: its centre and the radius of the circle it lies in; the middle of the surface, with the centre circle's radius, when missing. */
34
+ centre?: {
35
+ cx: number;
36
+ cy: number;
37
+ r: number;
38
+ };
39
+ /** Half the length, along the surface, that the pictures keep clear in the middle (a cricket pitch's). */
40
+ clear?: number;
41
+ /** The first picture is the away team's and the second the home team's, whichever side each is on (a diamond's outfield is the visitors', its infield the home team's). */
42
+ byRole?: boolean;
43
+ }
23
44
  /** The parts of a surface a drawing can be cropped to, by name: one box, or one at each end (`left` and `right` as the surface lies wide), in feet in the wide frame. */
24
45
  export type SurfaceRanges = Readonly<Record<string, Box | {
25
46
  left: Box;
@@ -84,11 +105,28 @@ export interface Surface {
84
105
  plateFits?: boolean;
85
106
  /** For a surface set inside another (a special game): the transform that carries the surface's own frame to the drawing's, which data in the surface's frame (`layers`) is put through. */
86
107
  frame?: string;
108
+ /** A surface drawn in parts, one of which is shown again larger beside it (a folded curling sheet): for each copy, the transform that carries the surface's frame to it and the id of the clip that cuts it. The data layers are drawn in each. */
109
+ panels?: {
110
+ transform: string;
111
+ clip: string;
112
+ }[];
113
+ /** Markup drawn over the data layers: the labels of a surface's panels. */
114
+ over?: string;
115
+ /** True for a surface whose frame has parts the annotations (axes, direction, landmarks) have no margin to stand in. */
116
+ folded?: boolean;
117
+ /** The radius of the centre circle in feet, where the surface has one: the emblem of a pageant lies in it. */
118
+ centreRadius?: number;
119
+ /** Where a pageant's pictures go, when the halves and the middle are not the place. */
120
+ pageant?: PageantPlan;
121
+ /** For a surface whose own frame is turned to an angle that is not a quarter (a close-up of an athletics start): the turn, in degrees, that a layer's texts and logos are given to read upright. */
122
+ upright?: number;
87
123
  /** How wide the surface's ordinary line is drawn, in the units of the `lines` markup, and how many feet one of those units is: what `lineWidth` scales. */
88
124
  lineRef?: {
89
125
  width: number;
90
126
  feet: number;
91
127
  };
128
+ /** For a surface with a crowd: the margin it was drawn with, which holds the stands. */
129
+ crowdMargin?: number;
92
130
  }
93
131
  /** A part of a surface to label: its anchor on the surface in feet and the margin its label stands in (the top or the bottom as the surface lies wide). */
94
132
  export interface Mark {
@@ -114,9 +152,15 @@ export interface BuildOptions {
114
152
  baselineText?: [string, string];
115
153
  centreLogo?: string;
116
154
  paintThreePoint?: boolean;
155
+ /** The realistic floor, when asked for (`court.hardwood`), its options read. */
156
+ hardwood?: Hardwood;
157
+ /** Words along the sidelines, `[top, bottom]`, on a hardwood floor. */
158
+ sidelineText?: [string, string];
117
159
  };
118
160
  /** True in a score drawing, so that panels are made room for. */
119
161
  score: boolean;
162
+ /** True when the drawing is a pageant: the teams' pictures lie over the halves, so the ends are not painted in the teams' colours. */
163
+ pageant?: boolean;
120
164
  /** The names of the features that have a colour of their own, so that their elements carry the class that colour is given to. */
121
165
  features?: ReadonlySet<string>;
122
166
  /** How the grass is mown, when the options say (a football field and a ballpark have their own default). */
@@ -0,0 +1,15 @@
1
+ import { type VenueLayout } from "../pool.ts";
2
+ import type { Language, PoolStyle } from "../types.ts";
3
+ import { type BuildOptions, type Surface } from "./surface.ts";
4
+ /** The name each pool of a hall is called on the plan, in a language. */
5
+ export declare function venueName(item: VenueLayout["items"][number], language: Language): string;
6
+ /**
7
+ * Several pools in one hall, to scale: each pool is drawn by its own sport's builder (the competition pool of 8 lanes, a diving well, a warm-up pool, a water polo pool or an artistic swimming area) and set at its place,
8
+ * with the deck round the hall drawn once and the paint of the water and the deck defined once for all of them. The pools stand at least 8 m apart, 10 m by default, as the rules keep a swimming pool and a diving well
9
+ * (CR 16.2.17). The water of the whole hall is the surface's `box`.
10
+ */
11
+ export declare function natatorium(o: BuildOptions, style: PoolStyle, look: {
12
+ look: "flat" | "water" | "tiled";
13
+ deck: "plain" | "tiled";
14
+ seed: number;
15
+ }, language: Language): Surface;
@@ -0,0 +1,95 @@
1
+ import { el, num } from "../format.js";
2
+ import { feet, reachOf, venueLayout } from "../pool.js";
3
+ import { deckMarkup, paintDefs, poolIds } from "../pool.kit.js";
4
+ import { KYOGIJO_STRINGS } from "../strings.js";
5
+ import { artistic } from "./artistic.js";
6
+ import { diving } from "./dive.js";
7
+ import { swimming } from "./pool.js";
8
+ import { waterPolo } from "./polo.js";
9
+ import { quarterTurn, textOn } from "./surface.js";
10
+ /** One pool of a hall drawn on its own with no deck: the surface its sport's builder makes. */
11
+ function built(o, plan, ctx) {
12
+ switch (plan.sport) {
13
+ case "swimming":
14
+ return swimming(o, { ...plan, race: undefined, section: undefined }, ctx);
15
+ case "waterpolo":
16
+ return waterPolo(o, plan, ctx);
17
+ case "diving":
18
+ return diving(o, plan, ctx);
19
+ default:
20
+ return artistic(o, plan, ctx);
21
+ }
22
+ }
23
+ /** The name each pool of a hall is called on the plan, in a language. */
24
+ export function venueName(item, language) {
25
+ if (item.pool.name !== undefined)
26
+ return item.pool.name;
27
+ const names = KYOGIJO_STRINGS[language].pool.names;
28
+ const plan = item.plan;
29
+ return plan.sport === "swimming" ? (plan.kind === "warm-up" ? names.warmUp : names.competition) : plan.sport === "diving" ? names.diving : plan.sport === "waterpolo" ? names.waterPolo : names.artistic;
30
+ }
31
+ /**
32
+ * Several pools in one hall, to scale: each pool is drawn by its own sport's builder (the competition pool of 8 lanes, a diving well, a warm-up pool, a water polo pool or an artistic swimming area) and set at its place,
33
+ * with the deck round the hall drawn once and the paint of the water and the deck defined once for all of them. The pools stand at least 8 m apart, 10 m by default, as the rules keep a swimming pool and a diving well
34
+ * (CR 16.2.17). The water of the whole hall is the surface's `box`.
35
+ */
36
+ export function natatorium(o, style, look, language) {
37
+ const layout = venueLayout(style);
38
+ const ids = poolIds(o.id);
39
+ const m = o.margin ?? feet(3.5);
40
+ const W = feet(layout.width);
41
+ const H = feet(layout.height);
42
+ const label = 3.2;
43
+ const labelRoom = layout.labels ? feet(3.4) : 0;
44
+ const reach = layout.reach;
45
+ // The hall inside its walls: the water of every pool, what stands beyond it, the deck round it and the names under the pools.
46
+ const hall = { x: -feet(reach.left) - m, y: -feet(reach.top) - m, w: W + feet(reach.left + reach.right) + 2 * m, h: H + feet(reach.top + reach.bottom) + 2 * m + labelRoom };
47
+ const seats = layout.seating ? feet(6) : 0;
48
+ const rim = m * 0.4;
49
+ const view0 = { x: hall.x - rim, y: hall.y - seats - (layout.seating ? feet(1) : 0) - rim, w: hall.w + 2 * rim, h: hall.h + seats + (layout.seating ? feet(1) : 0) + 2 * rim };
50
+ let base = deckMarkup(o, ids, look.deck, view0.x, view0.y, view0.w, view0.h);
51
+ base += el("rect", { class: "ky-pl-hw", x: hall.x, y: hall.y, width: hall.w, height: hall.h });
52
+ if (layout.seating) {
53
+ const top = hall.y - feet(1) - seats;
54
+ let rows = "";
55
+ for (let r = 1; r < 6; r += 1)
56
+ rows += `M${num(hall.x)} ${num(top + (seats * r) / 6)}H${num(hall.x + hall.w)}`;
57
+ base += el("rect", { class: "ky-pl-seat", x: hall.x, y: top, width: hall.w, height: seats });
58
+ base += el("path", { class: "ky-pl-rows", d: rows });
59
+ }
60
+ let lines = "";
61
+ let names = "";
62
+ for (const [i, item] of layout.items.entries()) {
63
+ const child = built({ ...o, margin: 0, score: false, landmarks: false, portrait: false, id: `${o.id}-${i}` }, item.plan, { ids, bare: true });
64
+ const move = `translate(${num(feet(item.x))} ${num(feet(item.y))})`;
65
+ base += el("g", { class: "ky-pl-hall", transform: move }, child.base);
66
+ lines += el("g", { class: "ky-pl-hall", transform: move }, child.lines);
67
+ if (layout.labels) {
68
+ const below = feet(item.y + item.plan.width + reachOf(item.plan).bottom);
69
+ names += textOn(o.portrait, feet(item.x + item.plan.length / 2), below + feet(1.2) + label * 0.36, venueName(item, language), { size: label, anchor: "middle", cls: "ky-pl-vn", weight: 800 });
70
+ }
71
+ }
72
+ if (layout.seating)
73
+ names += textOn(o.portrait, hall.x + hall.w / 2, hall.y - feet(1) - seats / 2 + label * 0.36, KYOGIJO_STRINGS[language].pool.names.seating, { size: label, anchor: "middle", cls: "ky-pl-vn", weight: 800 });
74
+ const cy = H / 2;
75
+ const turned = o.portrait;
76
+ const surface = {
77
+ sport: "swimming",
78
+ view: view0,
79
+ base,
80
+ lines: lines + names,
81
+ defs: paintDefs(ids, look.look, look.deck, look.seed),
82
+ left: { cx: hall.x + m / 2, cy, w: H, h: m, rot: -90 },
83
+ right: { cx: hall.x + hall.w - m / 2, cy, w: H, h: m, rot: 90 },
84
+ plate: turned ? { cx: W / 2, cy, w: H * 0.8, h: W * 0.3 } : { cx: W / 2, cy, w: W * 0.3, h: H * 0.4 },
85
+ turned,
86
+ };
87
+ surface.box = { x: 0, y: 0, w: W, h: H };
88
+ surface.lineRef = { width: 0.8, feet: 1 };
89
+ if (turned) {
90
+ const t = quarterTurn(view0);
91
+ surface.view = t.view;
92
+ surface.turn = t.turn;
93
+ }
94
+ return surface;
95
+ }
@@ -0,0 +1,77 @@
1
+ /** The sport a tenant plays: what decides the surface a place offers for it (`surfaceOf`). */
2
+ export type TenantSport = "baseball" | "soccer" | "american-football" | "canadian-football" | "basketball" | "ice-hockey" | "rugby-union" | "rugby-league" | "australian-football" | "lacrosse" | "cricket";
3
+ /** The article of English Wikipedia, at a revision, that a place's tenants were read from. */
4
+ export interface TenantArticle {
5
+ title: string;
6
+ revision: number;
7
+ }
8
+ /** Where a tenant was read. */
9
+ export interface TenantSource {
10
+ /** The Wikidata statement that names the club as a tenant (CC0): `P466` (the place lists the club as an occupant), `P115` (the club lists the place as its home venue), or both. Absent where only the article names it. */
11
+ wikidata?: "P466" | "P115" | "P466 P115";
12
+ /** The article and revision of English Wikipedia (CC BY-SA 4.0) whose `tenants` line in the place's infobox lists the club. Absent where only Wikidata names it. */
13
+ wikipedia?: TenantArticle;
14
+ /** Where the years were read: Wikidata's qualifiers (start time P580, end time P582), or the article. Absent when neither gives any. */
15
+ years?: "wikidata" | "wikipedia";
16
+ }
17
+ /** Why a club's name in Japanese is not Wikidata's label: the label is a transliteration of an abbreviation (`abbreviation`), of a formal name or a suffix such as FC that Japanese media do not use (`formal`), a page title with a disambiguator or "history of" (`title`), or the club's name in another period (`era`). */
18
+ export type TenantNameKind = "abbreviation" | "formal" | "title" | "era";
19
+ /** The everyday Japanese form of a club's name where it is not Wikidata's label, and the source of it. */
20
+ export interface TenantNameJa {
21
+ /** The name Japanese media use, which the atlas shows as `clubJa`. */
22
+ ja: string;
23
+ kind: TenantNameKind;
24
+ /** What was checked, where and when. */
25
+ note: string;
26
+ }
27
+ /** A tenant as the data gives it. */
28
+ export interface TenantData {
29
+ club: string;
30
+ clubJa?: string;
31
+ aliasesJa?: string[];
32
+ league: string;
33
+ sport: TenantSport;
34
+ from?: number;
35
+ to?: number;
36
+ wikidata: string;
37
+ statements?: "P466" | "P115" | "P466 P115";
38
+ /** The place's article lists the club in its tenants line. */
39
+ listed?: true;
40
+ years?: "wikidata" | "wikipedia";
41
+ }
42
+ /** A club that plays, or played, its home matches in a place, and when. */
43
+ export interface Tenant {
44
+ /** The club's name in English: the one the place's article gives it (`Montreal Expos`, `Boston Braves` for a club named differently then), else Wikidata's label. */
45
+ club: string;
46
+ /** The club's name in Japanese as Japanese media say it (`BCライオンズ`), where there is one for this name of the club: the curated form in `TENANT_NAMES_JA` if the club has one, else Wikidata's label. */
47
+ clubJa?: string;
48
+ /** Other names the club is found by in Japanese: Wikidata's label where `clubJa` is the curated form instead (`ブリティッシュ・コロンビア・ライオンズ`). */
49
+ aliasesJa?: readonly string[];
50
+ /** The league it played in there: `MLB`, `CFL`, `MLS`, `NPB`, `Premier League`... A league that has had several names or several seasons of the same name has one (`NASL` is the league of 1968 to 1984). */
51
+ league: string;
52
+ sport: TenantSport;
53
+ /** The first year it played there. Not given where neither source gives it. */
54
+ from?: number;
55
+ /** The last year it played there: a club still there has none. */
56
+ to?: number;
57
+ /** The club's Wikidata item (`Q919062`), the key to join a tenant to other data. */
58
+ wikidata: string;
59
+ source: TenantSource;
60
+ }
61
+ /** The tenants of every place that has any, by the place's key: the current ones first, by the year they came, then those that have left, the latest to leave first. */
62
+ export declare const TENANTS: Readonly<Record<string, readonly Tenant[]>>;
63
+ /** The leagues of a list of tenants, each once, in the order they first come. */
64
+ export declare const leaguesOf: (tenants: readonly Tenant[]) => string[];
65
+ /** True when a tenant played there in `year`; a year the data does not give for a bound does not shut it out. */
66
+ export declare const playedIn: (tenant: Tenant, year: number) => boolean;
67
+ /** The draw sport a tenant's sport is drawn as, and any league of its rulebook: the field of play a club's sport asks for. `undefined` where the package draws none. */
68
+ export declare const SURFACE_OF_SPORT: Readonly<Record<TenantSport, {
69
+ sport: "mlb" | "soccer" | "nfl" | "cfl" | "nba" | "nhl" | "rugby" | "afl" | "cricket";
70
+ league?: "nrl";
71
+ } | undefined>>;
72
+ /** True when the package draws a surface for the tenant's sport and league. */
73
+ export declare const hasSurface: (tenant: Tenant) => boolean;
74
+ /** The clubs whose name in Japanese is the everyday form and not Wikidata's label, by Wikidata item, with why and the source of each: `nameJaOf(tenant)` finds a tenant's. */
75
+ export declare const TENANT_JAPANESE_NAMES: Readonly<Record<string, TenantNameJa>>;
76
+ /** The note on a tenant's name in Japanese, if its everyday form is a curated one. */
77
+ export declare const nameJaOf: (tenant: Pick<Tenant, "wikidata">) => TenantNameJa | undefined;
@@ -0,0 +1,8 @@
1
+ import type { TenantArticle, TenantData, TenantNameJa } from "./tenants.ts";
2
+ /** The article of English Wikipedia, at the revision read, that the tenants of a place are listed in. */
3
+ export declare const TENANT_ARTICLES: Readonly<Record<string, TenantArticle>>;
4
+ /** The leagues whose field or court is not the one the package draws for their sport (arena football, a basketball league that played on another court): their clubs ask for no surface. */
5
+ export declare const TENANT_NO_SURFACE: readonly string[];
6
+ /** The clubs whose name in Japanese is not Wikidata's label, by the club's Wikidata item: the everyday form, why Wikidata's label is not it, and the source of each. See scripts/tenants.names-ja.json. */
7
+ export declare const TENANT_NAMES_JA: Readonly<Record<string, TenantNameJa>>;
8
+ export declare const TENANT_DATA: Readonly<Record<string, TenantData[]>>;