@tungstenstudio/outschart-generator 1.0.0-rc.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.
package/dist/index.js ADDED
@@ -0,0 +1,1155 @@
1
+ // src/types.ts
2
+ var OutsChartError = class extends Error {
3
+ constructor(code, message) {
4
+ super(message);
5
+ this.name = "OutsChartError";
6
+ this.code = code;
7
+ }
8
+ };
9
+
10
+ // src/data/dartboard-layout.json
11
+ var dartboard_layout_default = {
12
+ meta: {
13
+ description: "Physical dartboard layout: number order, neighbors, and miss targets for each bed",
14
+ notes: "Board order is clockwise starting from the top. Each number has two lateral neighbors (clockwise/counterclockwise) and each bed has radial neighbors (closer to or farther from the center)."
15
+ },
16
+ boardOrder: [20, 1, 18, 4, 13, 6, 10, 15, 2, 17, 3, 19, 7, 16, 8, 11, 14, 9, 12, 5],
17
+ neighbors: {
18
+ "1": { clockwise: 18, counterClockwise: 20 },
19
+ "2": { clockwise: 17, counterClockwise: 15 },
20
+ "3": { clockwise: 19, counterClockwise: 17 },
21
+ "4": { clockwise: 13, counterClockwise: 18 },
22
+ "5": { clockwise: 20, counterClockwise: 12 },
23
+ "6": { clockwise: 10, counterClockwise: 13 },
24
+ "7": { clockwise: 16, counterClockwise: 19 },
25
+ "8": { clockwise: 11, counterClockwise: 16 },
26
+ "9": { clockwise: 12, counterClockwise: 14 },
27
+ "10": { clockwise: 15, counterClockwise: 6 },
28
+ "11": { clockwise: 14, counterClockwise: 8 },
29
+ "12": { clockwise: 5, counterClockwise: 9 },
30
+ "13": { clockwise: 6, counterClockwise: 4 },
31
+ "14": { clockwise: 9, counterClockwise: 11 },
32
+ "15": { clockwise: 2, counterClockwise: 10 },
33
+ "16": { clockwise: 8, counterClockwise: 7 },
34
+ "17": { clockwise: 3, counterClockwise: 2 },
35
+ "18": { clockwise: 4, counterClockwise: 1 },
36
+ "19": { clockwise: 7, counterClockwise: 3 },
37
+ "20": { clockwise: 5, counterClockwise: 1 }
38
+ },
39
+ radialBeds: {
40
+ description: "From center outward: Bull, 25, smallSingle, treble, largeSingle, double, off-board",
41
+ order: ["Bull", "25", "smallSingle", "treble", "largeSingle", "double", "off"]
42
+ },
43
+ missTargets: {
44
+ description: "For each bed type, the possible miss results: radial (in/out from center) and lateral (adjacent numbers). 'off' means off the board (no score).",
45
+ Bull: {
46
+ radialOut: "25",
47
+ radialIn: null,
48
+ lateralMiss: false
49
+ },
50
+ "25": {
51
+ radialOut: "smallSingle",
52
+ radialIn: "Bull",
53
+ lateralMiss: false
54
+ },
55
+ smallSingle: {
56
+ radialOut: "treble",
57
+ radialIn: "25",
58
+ lateralMiss: true
59
+ },
60
+ treble: {
61
+ radialOut: "largeSingle",
62
+ radialIn: "smallSingle",
63
+ lateralMiss: true
64
+ },
65
+ largeSingle: {
66
+ radialOut: "double",
67
+ radialIn: "treble",
68
+ lateralMiss: true
69
+ },
70
+ double: {
71
+ radialOut: "off",
72
+ radialIn: "largeSingle",
73
+ lateralMiss: true
74
+ }
75
+ }
76
+ };
77
+
78
+ // src/dartboard.ts
79
+ var boardLayout = dartboard_layout_default;
80
+ var BOARD_ORDER = boardLayout.boardOrder;
81
+ function getNeighbors(num) {
82
+ const n = boardLayout.neighbors[String(num)];
83
+ return { cw: n.clockwise, ccw: n.counterClockwise };
84
+ }
85
+ function parseTarget(target) {
86
+ if (target === "Bull") return { bed: "Bull", number: null, value: 50 };
87
+ if (target === "25") return { bed: "25", number: null, value: 25 };
88
+ const m = target.match(/^([TD]?)(\d+)$/);
89
+ if (!m) return null;
90
+ const num = parseInt(m[2]);
91
+ if (num < 1 || num > 20) return null;
92
+ const prefix = m[1];
93
+ if (prefix === "T") return { bed: "treble", number: num, value: num * 3 };
94
+ if (prefix === "D") return { bed: "double", number: num, value: num * 2 };
95
+ return { bed: null, number: num, value: num };
96
+ }
97
+ function formatTarget(bed, number) {
98
+ if (bed === "Bull") return { label: "Bull", value: 50 };
99
+ if (bed === "25") return { label: "25", value: 25 };
100
+ if (bed === "off") return { label: "off", value: 0 };
101
+ if (bed === "treble") return { label: `T${number}`, value: number * 3 };
102
+ if (bed === "double") return { label: `D${number}`, value: number * 2 };
103
+ return { label: `${number}`, value: number };
104
+ }
105
+ function getMissTargets(target) {
106
+ const parsed = parseTarget(target);
107
+ if (!parsed) return [];
108
+ const misses = [];
109
+ const missInfo = getMissInfo(parsed);
110
+ if (missInfo.radialIn) {
111
+ misses.push({ ...missInfo.radialIn, missType: "radialIn" });
112
+ }
113
+ if (missInfo.radialOut) {
114
+ misses.push({ ...missInfo.radialOut, missType: "radialOut" });
115
+ }
116
+ if (parsed.number) {
117
+ const { cw, ccw } = getNeighbors(parsed.number);
118
+ if (parsed.bed === "treble") {
119
+ misses.push({ label: `T${cw}`, value: cw * 3, missType: "lateralCW" });
120
+ misses.push({ label: `T${ccw}`, value: ccw * 3, missType: "lateralCCW" });
121
+ } else if (parsed.bed === "double") {
122
+ misses.push({ label: `D${cw}`, value: cw * 2, missType: "lateralCW" });
123
+ misses.push({ label: `D${ccw}`, value: ccw * 2, missType: "lateralCCW" });
124
+ } else {
125
+ misses.push({ label: `${cw}`, value: cw, missType: "lateralCW" });
126
+ misses.push({ label: `${ccw}`, value: ccw, missType: "lateralCCW" });
127
+ }
128
+ }
129
+ return misses;
130
+ }
131
+ function getMissInfo(parsed) {
132
+ const result = {
133
+ radialIn: null,
134
+ radialOut: null
135
+ };
136
+ if (parsed.bed === "Bull") {
137
+ result.radialOut = formatTarget("25", null);
138
+ } else if (parsed.bed === "25") {
139
+ result.radialIn = formatTarget("Bull", null);
140
+ } else if (parsed.bed === "treble") {
141
+ result.radialIn = formatTarget("smallSingle", parsed.number);
142
+ result.radialOut = formatTarget("largeSingle", parsed.number);
143
+ } else if (parsed.bed === "double") {
144
+ result.radialIn = formatTarget("largeSingle", parsed.number);
145
+ result.radialOut = formatTarget("off", null);
146
+ } else {
147
+ result.radialIn = formatTarget("treble", parsed.number);
148
+ result.radialOut = formatTarget("double", parsed.number);
149
+ }
150
+ return result;
151
+ }
152
+ function evaluateThrow(target, remaining) {
153
+ const parsed = parseTarget(target);
154
+ if (!parsed) return null;
155
+ const misses = getMissTargets(target);
156
+ const evaluatedMisses = misses.map((miss) => {
157
+ const newRemaining = remaining - miss.value;
158
+ return {
159
+ ...miss,
160
+ newRemaining,
161
+ busts: newRemaining < 0
162
+ };
163
+ });
164
+ return {
165
+ target,
166
+ targetValue: parsed.value,
167
+ remaining,
168
+ misses: evaluatedMisses,
169
+ bustCount: evaluatedMisses.filter((m) => m.busts).length,
170
+ totalMisses: evaluatedMisses.length
171
+ };
172
+ }
173
+
174
+ // src/data/double-out-checkouts.ts
175
+ var DOUBLE_OUT_BOGEY_NUMBERS = [159, 162, 163, 165, 166, 168, 169];
176
+ var DOUBLE_OUT_CHECKOUTS = {
177
+ 2: { darts: ["D1"], numDarts: 1 },
178
+ 3: { darts: ["1", "D1"], numDarts: 2 },
179
+ 4: { darts: ["D2"], numDarts: 1 },
180
+ 5: { darts: ["1", "D2"], numDarts: 2 },
181
+ 6: { darts: ["D3"], numDarts: 1 },
182
+ 7: { darts: ["3", "D2"], numDarts: 2 },
183
+ 8: { darts: ["D4"], numDarts: 1 },
184
+ 9: { darts: ["1", "D4"], numDarts: 2 },
185
+ 10: { darts: ["D5"], numDarts: 1 },
186
+ 11: { darts: ["3", "D4"], numDarts: 2 },
187
+ 12: { darts: ["D6"], numDarts: 1 },
188
+ 13: { darts: ["5", "D4"], numDarts: 2 },
189
+ 14: { darts: ["D7"], numDarts: 1 },
190
+ 15: { darts: ["7", "D4"], numDarts: 2 },
191
+ 16: { darts: ["D8"], numDarts: 1 },
192
+ 17: { darts: ["1", "D8"], numDarts: 2 },
193
+ 18: { darts: ["D9"], numDarts: 1 },
194
+ 19: { darts: ["3", "D8"], numDarts: 2 },
195
+ 20: { darts: ["D10"], numDarts: 1 },
196
+ 21: { darts: ["5", "D8"], numDarts: 2 },
197
+ 22: { darts: ["D11"], numDarts: 1 },
198
+ 23: { darts: ["7", "D8"], numDarts: 2 },
199
+ 24: { darts: ["D12"], numDarts: 1 },
200
+ 25: { darts: ["9", "D8"], numDarts: 2 },
201
+ 26: { darts: ["D13"], numDarts: 1 },
202
+ 27: { darts: ["3", "D12"], numDarts: 2 },
203
+ 28: { darts: ["D14"], numDarts: 1 },
204
+ 29: { darts: ["5", "D12"], numDarts: 2 },
205
+ 30: { darts: ["D15"], numDarts: 1 },
206
+ 31: { darts: ["7", "D12"], numDarts: 2 },
207
+ 32: { darts: ["D16"], numDarts: 1 },
208
+ 33: { darts: ["1", "D16"], numDarts: 2 },
209
+ 34: { darts: ["D17"], numDarts: 1 },
210
+ 35: { darts: ["3", "D16"], numDarts: 2 },
211
+ 36: { darts: ["D18"], numDarts: 1 },
212
+ 37: { darts: ["5", "D16"], numDarts: 2 },
213
+ 38: { darts: ["D19"], numDarts: 1 },
214
+ 39: { darts: ["7", "D16"], numDarts: 2 },
215
+ 40: { darts: ["D20"], numDarts: 1 },
216
+ 41: { darts: ["9", "D16"], numDarts: 2 },
217
+ 42: { darts: ["10", "D16"], numDarts: 2 },
218
+ 43: { darts: ["11", "D16"], numDarts: 2 },
219
+ 44: { darts: ["12", "D16"], numDarts: 2 },
220
+ 45: { darts: ["13", "D16"], numDarts: 2 },
221
+ 46: { darts: ["14", "D16"], numDarts: 2 },
222
+ 47: { darts: ["15", "D16"], numDarts: 2 },
223
+ 48: { darts: ["16", "D16"], numDarts: 2 },
224
+ 49: { darts: ["9", "D20"], numDarts: 2 },
225
+ 50: { darts: ["Bull"], numDarts: 1 },
226
+ 51: { darts: ["11", "D20"], numDarts: 2 },
227
+ 52: { darts: ["12", "D20"], numDarts: 2 },
228
+ 53: { darts: ["13", "D20"], numDarts: 2 },
229
+ 54: { darts: ["14", "D20"], numDarts: 2 },
230
+ 55: { darts: ["15", "D20"], numDarts: 2 },
231
+ 56: { darts: ["16", "D20"], numDarts: 2 },
232
+ 57: { darts: ["17", "D20"], numDarts: 2 },
233
+ 58: { darts: ["18", "D20"], numDarts: 2 },
234
+ 59: { darts: ["19", "D20"], numDarts: 2 },
235
+ 60: { darts: ["20", "D20"], numDarts: 2 },
236
+ 61: { darts: ["T15", "D8"], numDarts: 2 },
237
+ 62: { darts: ["T10", "D16"], numDarts: 2 },
238
+ 63: { darts: ["T13", "D12"], numDarts: 2 },
239
+ 64: { darts: ["T16", "D8"], numDarts: 2 },
240
+ 65: { darts: ["T19", "D4"], numDarts: 2 },
241
+ 66: { darts: ["T10", "D18"], numDarts: 2 },
242
+ 67: { darts: ["T17", "D8"], numDarts: 2 },
243
+ 68: { darts: ["T20", "D4"], numDarts: 2 },
244
+ 69: { darts: ["T15", "D12"], numDarts: 2 },
245
+ 70: { darts: ["T10", "D20"], numDarts: 2 },
246
+ 71: { darts: ["T13", "D16"], numDarts: 2 },
247
+ 72: { darts: ["T16", "D12"], numDarts: 2 },
248
+ 73: { darts: ["T19", "D8"], numDarts: 2 },
249
+ 74: { darts: ["T14", "D16"], numDarts: 2 },
250
+ 75: { darts: ["T17", "D12"], numDarts: 2 },
251
+ 76: { darts: ["T20", "D8"], numDarts: 2 },
252
+ 77: { darts: ["T19", "D10"], numDarts: 2 },
253
+ 78: { darts: ["T18", "D12"], numDarts: 2 },
254
+ 79: { darts: ["T13", "D20"], numDarts: 2 },
255
+ 80: { darts: ["T20", "D10"], numDarts: 2 },
256
+ 81: { darts: ["T19", "D12"], numDarts: 2 },
257
+ 82: { darts: ["T14", "D20"], numDarts: 2 },
258
+ 83: { darts: ["T17", "D16"], numDarts: 2 },
259
+ 84: { darts: ["T20", "D12"], numDarts: 2 },
260
+ 85: { darts: ["T15", "D20"], numDarts: 2 },
261
+ 86: { darts: ["T18", "D16"], numDarts: 2 },
262
+ 87: { darts: ["T17", "D18"], numDarts: 2 },
263
+ 88: { darts: ["T16", "D20"], numDarts: 2 },
264
+ 89: { darts: ["T19", "D16"], numDarts: 2 },
265
+ 90: { darts: ["T20", "D15"], numDarts: 2 },
266
+ 91: { darts: ["T17", "D20"], numDarts: 2 },
267
+ 92: { darts: ["T20", "D16"], numDarts: 2 },
268
+ 93: { darts: ["T19", "D18"], numDarts: 2 },
269
+ 94: { darts: ["T18", "D20"], numDarts: 2 },
270
+ 95: { darts: ["T19", "D19"], numDarts: 2 },
271
+ 96: { darts: ["T20", "D18"], numDarts: 2 },
272
+ 97: { darts: ["T19", "D20"], numDarts: 2 },
273
+ 98: { darts: ["T20", "D19"], numDarts: 2 },
274
+ 99: { darts: ["T19", "10", "D16"], numDarts: 3 },
275
+ 100: { darts: ["T20", "D20"], numDarts: 2 },
276
+ 101: { darts: ["T17", "Bull"], numDarts: 2 },
277
+ 102: { darts: ["T20", "10", "D16"], numDarts: 3 },
278
+ 103: { darts: ["T19", "10", "D18"], numDarts: 3 },
279
+ 104: { darts: ["T18", "Bull"], numDarts: 2 },
280
+ 105: { darts: ["T20", "13", "D16"], numDarts: 3 },
281
+ 106: { darts: ["T20", "14", "D16"], numDarts: 3 },
282
+ 107: { darts: ["T19", "Bull"], numDarts: 2 },
283
+ 108: { darts: ["T20", "16", "D16"], numDarts: 3 },
284
+ 109: { darts: ["T20", "17", "D16"], numDarts: 3 },
285
+ 110: { darts: ["T20", "Bull"], numDarts: 2 },
286
+ 111: { darts: ["T20", "19", "D16"], numDarts: 3 },
287
+ 112: { darts: ["T20", "12", "D20"], numDarts: 3 },
288
+ 113: { darts: ["T20", "13", "D20"], numDarts: 3 },
289
+ 114: { darts: ["T20", "14", "D20"], numDarts: 3 },
290
+ 115: { darts: ["T20", "15", "D20"], numDarts: 3 },
291
+ 116: { darts: ["T20", "16", "D20"], numDarts: 3 },
292
+ 117: { darts: ["T20", "17", "D20"], numDarts: 3 },
293
+ 118: { darts: ["T20", "18", "D20"], numDarts: 3 },
294
+ 119: { darts: ["T19", "T10", "D16"], numDarts: 3 },
295
+ 120: { darts: ["T20", "20", "D20"], numDarts: 3 },
296
+ 121: { darts: ["T17", "T10", "D20"], numDarts: 3 },
297
+ 122: { darts: ["T18", "T20", "D4"], numDarts: 3 },
298
+ 123: { darts: ["T19", "T16", "D9"], numDarts: 3 },
299
+ 124: { darts: ["T20", "T14", "D11"], numDarts: 3 },
300
+ 125: { darts: ["25", "T20", "D20"], numDarts: 3 },
301
+ 126: { darts: ["T19", "T19", "D6"], numDarts: 3 },
302
+ 127: { darts: ["T20", "T17", "D8"], numDarts: 3 },
303
+ 128: { darts: ["T18", "T14", "D16"], numDarts: 3 },
304
+ 129: { darts: ["T19", "T16", "D12"], numDarts: 3 },
305
+ 130: { darts: ["T20", "20", "Bull"], numDarts: 3 },
306
+ 131: { darts: ["T20", "T13", "D16"], numDarts: 3 },
307
+ 132: { darts: ["Bull", "T14", "D20"], numDarts: 3 },
308
+ 133: { darts: ["T20", "T19", "D8"], numDarts: 3 },
309
+ 134: { darts: ["T20", "T14", "D16"], numDarts: 3 },
310
+ 135: { darts: ["Bull", "T15", "D20"], numDarts: 3 },
311
+ 136: { darts: ["T20", "T20", "D8"], numDarts: 3 },
312
+ 137: { darts: ["T20", "T19", "D10"], numDarts: 3 },
313
+ 138: { darts: ["T20", "T18", "D12"], numDarts: 3 },
314
+ 139: { darts: ["T19", "T14", "D20"], numDarts: 3 },
315
+ 140: { darts: ["T20", "T20", "D10"], numDarts: 3 },
316
+ 141: { darts: ["T20", "T19", "D12"], numDarts: 3 },
317
+ 142: { darts: ["T20", "T14", "D20"], numDarts: 3 },
318
+ 143: { darts: ["T20", "T17", "D16"], numDarts: 3 },
319
+ 144: { darts: ["T20", "T20", "D12"], numDarts: 3 },
320
+ 145: { darts: ["T20", "T15", "D20"], numDarts: 3 },
321
+ 146: { darts: ["T20", "T18", "D16"], numDarts: 3 },
322
+ 147: { darts: ["T20", "T17", "D18"], numDarts: 3 },
323
+ 148: { darts: ["T20", "T16", "D20"], numDarts: 3 },
324
+ 149: { darts: ["T20", "T19", "D16"], numDarts: 3 },
325
+ 150: { darts: ["T20", "T18", "D18"], numDarts: 3 },
326
+ 151: { darts: ["T20", "T17", "D20"], numDarts: 3 },
327
+ 152: { darts: ["T20", "T20", "D16"], numDarts: 3 },
328
+ 153: { darts: ["T20", "T19", "D18"], numDarts: 3 },
329
+ 154: { darts: ["T20", "T18", "D20"], numDarts: 3 },
330
+ 155: { darts: ["T20", "T19", "D19"], numDarts: 3 },
331
+ 156: { darts: ["T20", "T20", "D18"], numDarts: 3 },
332
+ 157: { darts: ["T20", "T19", "D20"], numDarts: 3 },
333
+ 158: { darts: ["T20", "T20", "D19"], numDarts: 3 },
334
+ 160: { darts: ["T20", "T20", "D20"], numDarts: 3 },
335
+ 161: { darts: ["T20", "T17", "Bull"], numDarts: 3 },
336
+ 164: { darts: ["T20", "T18", "Bull"], numDarts: 3 },
337
+ 167: { darts: ["T20", "T19", "Bull"], numDarts: 3 },
338
+ 170: { darts: ["T20", "T20", "Bull"], numDarts: 3 }
339
+ };
340
+
341
+ // src/data/single-out-checkouts.ts
342
+ var SINGLE_OUT_BOGEY_NUMBERS = [163, 166, 169, 172, 173, 175, 176, 178, 179];
343
+ var SINGLE_OUT_CHECKOUTS = {
344
+ 1: { darts: ["1"], numDarts: 1 },
345
+ 2: { darts: ["2"], numDarts: 1 },
346
+ 3: { darts: ["3"], numDarts: 1 },
347
+ 4: { darts: ["4"], numDarts: 1 },
348
+ 5: { darts: ["5"], numDarts: 1 },
349
+ 6: { darts: ["6"], numDarts: 1 },
350
+ 7: { darts: ["7"], numDarts: 1 },
351
+ 8: { darts: ["8"], numDarts: 1 },
352
+ 9: { darts: ["9"], numDarts: 1 },
353
+ 10: { darts: ["10"], numDarts: 1 },
354
+ 11: { darts: ["11"], numDarts: 1 },
355
+ 12: { darts: ["12"], numDarts: 1 },
356
+ 13: { darts: ["13"], numDarts: 1 },
357
+ 14: { darts: ["14"], numDarts: 1 },
358
+ 15: { darts: ["15"], numDarts: 1 },
359
+ 16: { darts: ["16"], numDarts: 1 },
360
+ 17: { darts: ["17"], numDarts: 1 },
361
+ 18: { darts: ["18"], numDarts: 1 },
362
+ 19: { darts: ["19"], numDarts: 1 },
363
+ 20: { darts: ["20"], numDarts: 1 },
364
+ 21: { darts: ["7", "14"], numDarts: 2, alternates: [["1", "20"], ["2", "19"], ["3", "18"], ["4", "17"], ["5", "16"]] },
365
+ 22: { darts: ["D11"], numDarts: 1, alternates: [["2", "20"], ["3", "19"], ["4", "18"], ["5", "17"], ["6", "16"]] },
366
+ 23: { darts: ["3", "20"], numDarts: 2, alternates: [["4", "19"], ["5", "18"], ["6", "17"], ["7", "16"], ["8", "15"]] },
367
+ 24: { darts: ["D12"], numDarts: 1, alternates: [["8", "16"], ["4", "20"], ["5", "19"], ["6", "18"], ["7", "17"]] },
368
+ 25: { darts: ["9", "16"], numDarts: 2, alternates: [["25"], ["5", "20"], ["6", "19"], ["7", "18"], ["8", "17"]] },
369
+ 26: { darts: ["D13"], numDarts: 1, alternates: [["6", "20"], ["7", "19"], ["8", "18"], ["13", "13"], ["2", "D12"]] },
370
+ 27: { darts: ["9", "18"], numDarts: 2, alternates: [["7", "20"], ["8", "19"], ["3", "D12"], ["10", "17"], ["11", "16"]] },
371
+ 28: { darts: ["D14"], numDarts: 1, alternates: [["8", "20"], ["9", "19"], ["14", "14"], ["4", "D12"], ["10", "18"]] },
372
+ 29: { darts: ["9", "20"], numDarts: 2, alternates: [["5", "D12"], ["11", "18"], ["12", "17"], ["14", "15"]] },
373
+ 30: { darts: ["D15"], numDarts: 1, alternates: [["10", "20"], ["15", "15"], ["6", "D12"], ["11", "19"], ["12", "18"]] },
374
+ 31: { darts: ["12", "19"], numDarts: 2, alternates: [["7", "D12"], ["13", "18"], ["14", "17"], ["3", "D14"], ["11", "20"]] },
375
+ 32: { darts: ["D16"], numDarts: 1, alternates: [["16", "16"], ["8", "D12"], ["13", "19"], ["15", "17"], ["4", "D14"]] },
376
+ 33: { darts: ["14", "19"], numDarts: 2, alternates: [["1", "D16"], ["9", "D12"], ["16", "17"], ["5", "D14"], ["13", "20"]] },
377
+ 34: { darts: ["D17"], numDarts: 1, alternates: [["2", "D16"], ["10", "D12"], ["15", "19"], ["16", "18"], ["6", "D14"]] },
378
+ 35: { darts: ["15", "20"], numDarts: 2, alternates: [["3", "D16"], ["11", "D12"], ["16", "19"], ["17", "18"], ["7", "D14"]] },
379
+ 36: { darts: ["D18"], numDarts: 1, alternates: [["4", "D16"], ["17", "19"], ["8", "D14"], ["12", "D12"], ["18", "18"]] },
380
+ 37: { darts: ["18", "19"], numDarts: 2, alternates: [["5", "D16"], ["1", "D18"], ["17", "20"], ["3", "D17"], ["7", "D15"]] },
381
+ 38: { darts: ["D19"], numDarts: 1, alternates: [["6", "D16"], ["18", "20"], ["4", "D17"], ["8", "D15"], ["2", "D18"]] },
382
+ 39: { darts: ["19", "20"], numDarts: 2, alternates: [["7", "D16"], ["3", "D18"], ["9", "D15"], ["1", "D19"], ["5", "D17"]] },
383
+ 40: { darts: ["D20"], numDarts: 1, alternates: [["8", "D16"], ["4", "D18"], ["20", "20"], ["6", "D17"], ["10", "D15"]] },
384
+ 41: { darts: ["9", "D16"], numDarts: 2, alternates: [["1", "D20"], ["7", "D17"], ["11", "D15"], ["3", "D19"], ["5", "D18"]] },
385
+ 42: { darts: ["T14"], numDarts: 1, alternates: [["10", "D16"], ["2", "D20"], ["14", "D14"], ["6", "D18"], ["4", "D19"]] },
386
+ 43: { darts: ["3", "D20"], numDarts: 2, alternates: [["11", "D16"], ["7", "D18"], ["13", "D15"], ["19", "D12"], ["5", "D19"]] },
387
+ 44: { darts: ["12", "D16"], numDarts: 2, alternates: [["8", "D18"], ["4", "D20"], ["6", "D19"], ["10", "D17"], ["14", "D15"]] },
388
+ 45: { darts: ["T15"], numDarts: 1, alternates: [["13", "D16"], ["5", "D20"], ["9", "D18"], ["7", "D19"], ["15", "D15"]] },
389
+ 46: { darts: ["6", "D20"], numDarts: 2, alternates: [["14", "D16"], ["10", "D18"], ["8", "D19"]] },
390
+ 47: { darts: ["15", "D16"], numDarts: 2, alternates: [["11", "D18"], ["7", "D20"], ["9", "D19"]] },
391
+ 48: { darts: ["T16"], numDarts: 1, alternates: [["16", "D16"], ["8", "D20"], ["10", "D19"], ["12", "D18"], ["14", "D17"]] },
392
+ 49: { darts: ["13", "D18"], numDarts: 2, alternates: [["15", "D17"], ["9", "D20"], ["11", "D19"], ["17", "D16"], ["19", "D15"]] },
393
+ 50: { darts: ["10", "D20"], numDarts: 2, alternates: [["Bull"], ["14", "D18"], ["12", "D19"], ["16", "D17"], ["D16", "18"]] },
394
+ 51: { darts: ["T17"], numDarts: 1, alternates: [["17", "D17"], ["13", "D19"], ["11", "D20"], ["19", "D16"], ["15", "D18"]] },
395
+ 52: { darts: ["16", "D18"], numDarts: 2, alternates: [["12", "D20"], ["20", "D16"], ["14", "D19"], ["18", "D17"]] },
396
+ 53: { darts: ["17", "D18"], numDarts: 2, alternates: [["13", "D20"], ["15", "D19"]] },
397
+ 54: { darts: ["T18"], numDarts: 1, alternates: [["14", "D20"], ["18", "D18"], ["16", "D19"], ["20", "D17"]] },
398
+ 55: { darts: ["15", "D20"], numDarts: 2, alternates: [["17", "D19"]] },
399
+ 56: { darts: ["16", "D20"], numDarts: 2, alternates: [["18", "D19"]] },
400
+ 57: { darts: ["T19"], numDarts: 1, alternates: [["19", "D19"], ["17", "D20"]] },
401
+ 58: { darts: ["18", "D20"], numDarts: 2 },
402
+ 59: { darts: ["19", "D20"], numDarts: 2 },
403
+ 60: { darts: ["T20"], numDarts: 1, alternates: [["20", "D20"]] },
404
+ 61: { darts: ["T16", "13"], numDarts: 2, alternates: [["T7", "D20"], ["T14", "19"]] },
405
+ 62: { darts: ["T14", "20"], numDarts: 2, alternates: [["D11", "D20"], ["D15", "D16"], ["T15", "17"], ["T16", "14"], ["D13", "D18"]] },
406
+ 63: { darts: ["T15", "18"], numDarts: 2, alternates: [["T13", "D12"], ["T16", "15"], ["T17", "12"]] },
407
+ 64: { darts: ["T16", "16"], numDarts: 2, alternates: [["D16", "D16"]] },
408
+ 65: { darts: ["T15", "20"], numDarts: 2, alternates: [["T17", "14"], ["T11", "D16"], ["25", "D20"], ["T16", "17"]] },
409
+ 66: { darts: ["T16", "18"], numDarts: 2, alternates: [["T18", "12"], ["T17", "15"]] },
410
+ 67: { darts: ["T16", "19"], numDarts: 2, alternates: [["T17", "16"], ["T18", "13"]] },
411
+ 68: { darts: ["T17", "17"], numDarts: 2, alternates: [["T18", "14"], ["D18", "D16"], ["D14", "D20"], ["T16", "20"]] },
412
+ 69: { darts: ["T19", "12"], numDarts: 2, alternates: [["T18", "15"]] },
413
+ 70: { darts: ["T19", "13"], numDarts: 2, alternates: [["T10", "D20"], ["D16", "D19"], ["D20", "D15"], ["T17", "19"], ["T18", "16"]] },
414
+ 71: { darts: ["T17", "20"], numDarts: 2, alternates: [["T19", "14"], ["T18", "17"]] },
415
+ 72: { darts: ["T18", "18"], numDarts: 2, alternates: [["T12", "D18"]] },
416
+ 73: { darts: ["T19", "16"], numDarts: 2, alternates: [["T18", "19"], ["T20", "13"]] },
417
+ 74: { darts: ["T20", "14"], numDarts: 2, alternates: [["T14", "D16"], ["D17", "D20"], ["T18", "20"], ["T19", "17"]] },
418
+ 75: { darts: ["T19", "18"], numDarts: 2, alternates: [["T20", "15"], ["T15", "D15"]] },
419
+ 76: { darts: ["T19", "19"], numDarts: 2, alternates: [["T20", "16"]] },
420
+ 77: { darts: ["T20", "17"], numDarts: 2, alternates: [["T19", "20"]] },
421
+ 78: { darts: ["T18", "D12"], numDarts: 2, alternates: [["T14", "D18"], ["D19", "D20"], ["T16", "D15"], ["18", "T20"]] },
422
+ 79: { darts: ["T20", "19"], numDarts: 2, alternates: [["T13", "D20"]] },
423
+ 80: { darts: ["T20", "20"], numDarts: 2, alternates: [["D20", "D20"]] },
424
+ 81: { darts: ["T19", "D12"], numDarts: 2, alternates: [["T15", "D18"], ["T20", "T7"], ["T19", "T8"], ["T18", "T9"], ["T16", "T11"]] },
425
+ 82: { darts: ["T14", "D20"], numDarts: 2, alternates: [["Bull", "D16"], ["T18", "D14"], ["T16", "D17"]] },
426
+ 83: { darts: ["T17", "D16"], numDarts: 2, alternates: [["T15", "D19"], ["T19", "D13"]] },
427
+ 84: { darts: ["T16", "D18"], numDarts: 2, alternates: [["T20", "D12"], ["T20", "T8"], ["T19", "T9"], ["T17", "T11"], ["T14", "T14"]] },
428
+ 85: { darts: ["T15", "D20"], numDarts: 2, alternates: [["T19", "D14"], ["T17", "D17"]] },
429
+ 86: { darts: ["T18", "D16"], numDarts: 2, alternates: [["T16", "D19"], ["T20", "D13"]] },
430
+ 87: { darts: ["T20", "T9"], numDarts: 2, alternates: [["T15", "T14"], ["T17", "D18"], ["T19", "D15"], ["T19", "T10"], ["T18", "T11"]] },
431
+ 88: { darts: ["T16", "D20"], numDarts: 2, alternates: [["T20", "D14"], ["T18", "D17"], ["Bull", "D19"]] },
432
+ 89: { darts: ["T19", "D16"], numDarts: 2, alternates: [["T17", "D19"]] },
433
+ 90: { darts: ["T18", "D18"], numDarts: 2, alternates: [["T20", "D15"], ["Bull", "D20"], ["T20", "T10"], ["T19", "T11"], ["T16", "T14"]] },
434
+ 91: { darts: ["T17", "D20"], numDarts: 2, alternates: [["T19", "D17"]] },
435
+ 92: { darts: ["T20", "D16"], numDarts: 2, alternates: [["T18", "D19"]] },
436
+ 93: { darts: ["T19", "D18"], numDarts: 2, alternates: [["T20", "T11"], ["T17", "T14"], ["T19", "T12"], ["T18", "T13"], ["T16", "T15"]] },
437
+ 94: { darts: ["T18", "D20"], numDarts: 2, alternates: [["T20", "D17"]] },
438
+ 95: { darts: ["T19", "D19"], numDarts: 2 },
439
+ 96: { darts: ["T20", "D18"], numDarts: 2, alternates: [["T20", "T12"], ["T19", "T13"], ["T18", "T14"], ["T17", "T15"], ["T16", "T16"]] },
440
+ 97: { darts: ["T19", "D20"], numDarts: 2 },
441
+ 98: { darts: ["T20", "D19"], numDarts: 2 },
442
+ 99: { darts: ["T20", "T13"], numDarts: 2, alternates: [["T19", "T14"], ["T18", "T15"], ["T17", "T16"]] },
443
+ 100: { darts: ["T20", "D20"], numDarts: 2 },
444
+ 101: { darts: ["T17", "Bull"], numDarts: 2 },
445
+ 102: { darts: ["T20", "T14"], numDarts: 2, alternates: [["T19", "T15"], ["T18", "T16"], ["T17", "T17"]] },
446
+ 103: { darts: ["T19", "6", "D20"], numDarts: 3, alternates: [["T15", "18", "D20"], ["T20", "3", "D20"], ["T19", "14", "D16"], ["T20", "11", "D16"], ["T20", "7", "D18"]] },
447
+ 104: { darts: ["T18", "Bull"], numDarts: 2 },
448
+ 105: { darts: ["T20", "T15"], numDarts: 2, alternates: [["T19", "T16"], ["T18", "T17"]] },
449
+ 106: { darts: ["T16", "18", "D20"], numDarts: 3, alternates: [["T20", "6", "D20"], ["T20", "14", "D16"], ["T17", "15", "D20"], ["T18", "16", "D18"], ["T20", "10", "D18"]] },
450
+ 107: { darts: ["T19", "Bull"], numDarts: 2 },
451
+ 108: { darts: ["T20", "T16"], numDarts: 2, alternates: [["T19", "T17"], ["T18", "T18"]] },
452
+ 109: { darts: ["T17", "18", "D20"], numDarts: 3, alternates: [["T18", "15", "D20"], ["T19", "16", "D18"], ["T20", "13", "D18"], ["T19", "12", "D20"], ["T20", "15", "D17"]] },
453
+ 110: { darts: ["T20", "Bull"], numDarts: 2 },
454
+ 111: { darts: ["T20", "T17"], numDarts: 2, alternates: [["T19", "T18"]] },
455
+ 112: { darts: ["T18", "18", "D20"], numDarts: 3, alternates: [["T19", "15", "D20"], ["T20", "16", "D18"], ["T20", "12", "D20"], ["T20", "20", "D16"]] },
456
+ 113: { darts: ["T20", "17", "D18"], numDarts: 3, alternates: [["T19", "16", "D20"], ["T18", "19", "D20"], ["T20", "13", "D20"], ["T20", "15", "D19"], ["T19", "18", "D19"]] },
457
+ 114: { darts: ["T20", "T18"], numDarts: 2, alternates: [["T19", "T19"]] },
458
+ 115: { darts: ["T19", "18", "D20"], numDarts: 3, alternates: [["T20", "15", "D20"]] },
459
+ 116: { darts: ["T20", "16", "D20"], numDarts: 3, alternates: [["T19", "19", "D20"], ["T20", "18", "D19"]] },
460
+ 117: { darts: ["T20", "T19"], numDarts: 2 },
461
+ 118: { darts: ["T20", "18", "D20"], numDarts: 3 },
462
+ 119: { darts: ["T20", "19", "D20"], numDarts: 3 },
463
+ 120: { darts: ["T20", "T20"], numDarts: 2 },
464
+ 121: { darts: ["T19", "T16", "16"], numDarts: 3, alternates: [["T20", "T16", "13"], ["T19", "D16", "D16"], ["T19", "T15", "19"], ["T19", "T17", "13"], ["T18", "T16", "19"]] },
465
+ 122: { darts: ["T20", "T14", "20"], numDarts: 3, alternates: [["T20", "T15", "17"], ["T20", "T16", "14"], ["T17", "T17", "20"], ["T18", "T18", "14"], ["T18", "D18", "D16"]] },
466
+ 123: { darts: ["T19", "T18", "12"], numDarts: 3, alternates: [["T19", "T16", "18"], ["T20", "T15", "18"], ["T18", "T17", "18"], ["T18", "T18", "15"], ["T20", "T13", "D12"]] },
467
+ 124: { darts: ["T20", "T16", "16"], numDarts: 3, alternates: [["T20", "D16", "D16"], ["T19", "T16", "19"], ["T19", "T17", "16"], ["T19", "T18", "13"], ["T18", "D19", "D16"]] },
468
+ 125: { darts: ["T20", "T15", "20"], numDarts: 3, alternates: [["T20", "T16", "17"], ["T20", "T17", "14"], ["T19", "D18", "D16"], ["T17", "T14", "D16"], ["T20", "T11", "D16"]] },
469
+ 126: { darts: ["T19", "T19", "12"], numDarts: 3, alternates: [["T20", "T16", "18"], ["T18", "T18", "18"], ["T19", "T18", "15"], ["T20", "T18", "12"]] },
470
+ 127: { darts: ["T19", "T17", "19"], numDarts: 3, alternates: [["T19", "T18", "16"], ["T19", "T19", "13"], ["T19", "T10", "D20"], ["T19", "D16", "D19"], ["T19", "D20", "D15"]] },
471
+ 128: { darts: ["T20", "T16", "20"], numDarts: 3, alternates: [["T20", "T17", "17"], ["T20", "T18", "14"], ["T20", "D18", "D16"], ["T18", "T14", "D16"], ["T20", "D14", "D20"]] },
472
+ 129: { darts: ["T20", "T19", "12"], numDarts: 3, alternates: [["T19", "T18", "18"], ["T20", "T18", "15"]] },
473
+ 130: { darts: ["T19", "T18", "19"], numDarts: 3, alternates: [["T19", "T19", "16"], ["T20", "T10", "D20"], ["T20", "D16", "D19"], ["T20", "D20", "D15"], ["T20", "T17", "19"]] },
474
+ 131: { darts: ["T20", "T17", "20"], numDarts: 3, alternates: [["T20", "T18", "17"], ["T20", "T19", "14"], ["T19", "T14", "D16"], ["T17", "D20", "D20"], ["T19", "D17", "D20"]] },
475
+ 132: { darts: ["T20", "T18", "18"], numDarts: 3, alternates: [["T20", "T12", "D18"], ["T19", "T19", "18"], ["T20", "T19", "15"], ["T20", "T20", "12"]] },
476
+ 133: { darts: ["T19", "T19", "19"], numDarts: 3, alternates: [["T20", "T18", "19"], ["T20", "T19", "16"], ["T20", "T20", "13"]] },
477
+ 134: { darts: ["T20", "T18", "20"], numDarts: 3, alternates: [["T20", "T19", "17"], ["T20", "T20", "14"], ["T20", "T14", "D16"], ["T18", "D20", "D20"], ["T20", "D17", "D20"]] },
478
+ 135: { darts: ["T20", "T19", "18"], numDarts: 3, alternates: [["T20", "T20", "15"], ["T20", "T15", "D15"], ["T19", "T14", "D18"], ["T19", "D19", "D20"], ["T19", "T18", "D12"]] },
479
+ 136: { darts: ["T20", "T19", "19"], numDarts: 3, alternates: [["T20", "T20", "16"]] },
480
+ 137: { darts: ["T20", "T19", "20"], numDarts: 3, alternates: [["T20", "T20", "17"], ["T19", "D20", "D20"]] },
481
+ 138: { darts: ["T20", "T18", "D12"], numDarts: 3, alternates: [["T20", "T14", "D18"], ["T20", "D19", "D20"], ["T19", "T19", "D12"], ["T20", "T16", "D15"], ["T18", "T16", "D18"]] },
482
+ 139: { darts: ["T20", "T20", "19"], numDarts: 3, alternates: [["T19", "Bull", "D16"], ["T20", "T13", "D20"], ["T19", "T14", "D20"], ["T18", "T15", "D20"], ["T17", "T16", "D20"]] },
483
+ 140: { darts: ["T20", "T20", "20"], numDarts: 3, alternates: [["T20", "D20", "D20"]] },
484
+ 141: { darts: ["T20", "T19", "D12"], numDarts: 3, alternates: [["T18", "T20", "T9"], ["T18", "T15", "T14"], ["T19", "T20", "T8"], ["T19", "T19", "T9"], ["T19", "T14", "T14"]] },
485
+ 142: { darts: ["T20", "Bull", "D16"], numDarts: 3, alternates: [["T20", "T14", "D20"], ["T19", "T15", "D20"], ["T18", "T16", "D20"], ["T17", "T17", "D20"], ["T20", "T18", "D14"]] },
486
+ 143: { darts: ["T20", "T17", "D16"], numDarts: 3, alternates: [["T19", "T18", "D16"], ["T20", "T15", "D19"], ["T19", "T16", "D19"], ["T18", "T17", "D19"], ["T20", "T19", "D13"]] },
487
+ 144: { darts: ["T20", "T16", "D18"], numDarts: 3, alternates: [["T20", "T20", "D12"], ["T19", "T17", "D18"], ["T18", "T18", "D18"], ["T20", "T18", "D15"], ["T19", "T19", "D15"]] },
488
+ 145: { darts: ["T20", "T15", "D20"], numDarts: 3, alternates: [["T19", "T16", "D20"], ["T18", "T17", "D20"], ["T20", "T19", "D14"], ["T20", "T17", "D17"], ["T19", "T18", "D17"]] },
489
+ 146: { darts: ["T20", "T18", "D16"], numDarts: 3, alternates: [["T19", "T19", "D16"], ["T20", "T16", "D19"], ["T19", "T17", "D19"], ["T18", "T18", "D19"], ["T20", "T20", "D13"]] },
490
+ 147: { darts: ["T20", "T17", "D18"], numDarts: 3, alternates: [["T20", "T20", "T9"], ["T19", "T18", "D18"], ["T20", "T19", "D15"], ["T19", "Bull", "D20"], ["T19", "T20", "T10"]] },
491
+ 148: { darts: ["T20", "T16", "D20"], numDarts: 3, alternates: [["T19", "T17", "D20"], ["T18", "T18", "D20"], ["T20", "T20", "D14"], ["T20", "T18", "D17"], ["T19", "T19", "D17"]] },
492
+ 149: { darts: ["T20", "T19", "D16"], numDarts: 3, alternates: [["T20", "T17", "D19"], ["T19", "T18", "D19"]] },
493
+ 150: { darts: ["T20", "T18", "D18"], numDarts: 3, alternates: [["T19", "T19", "D18"], ["T20", "T20", "D15"], ["T20", "Bull", "D20"], ["T20", "T20", "T10"], ["T19", "T20", "T11"]] },
494
+ 151: { darts: ["T20", "T17", "D20"], numDarts: 3, alternates: [["T19", "T18", "D20"], ["T20", "T19", "D17"]] },
495
+ 152: { darts: ["T20", "T20", "D16"], numDarts: 3, alternates: [["T20", "T18", "D19"], ["T19", "T19", "D19"]] },
496
+ 153: { darts: ["T20", "T19", "D18"], numDarts: 3, alternates: [["T20", "T20", "T11"], ["T19", "T20", "T12"], ["T18", "T20", "T13"], ["T19", "T19", "T13"], ["T17", "T20", "T14"]] },
497
+ 154: { darts: ["T20", "T18", "D20"], numDarts: 3, alternates: [["T19", "T19", "D20"], ["T20", "T20", "D17"]] },
498
+ 155: { darts: ["T20", "T19", "D19"], numDarts: 3 },
499
+ 156: { darts: ["T20", "T20", "D18"], numDarts: 3, alternates: [["T20", "T20", "T12"], ["T19", "T20", "T13"], ["T18", "T20", "T14"], ["T19", "T19", "T14"], ["T17", "T20", "T15"]] },
500
+ 157: { darts: ["T20", "T19", "D20"], numDarts: 3 },
501
+ 158: { darts: ["T20", "T20", "D19"], numDarts: 3 },
502
+ 159: { darts: ["T20", "T20", "T13"], numDarts: 3, alternates: [["T19", "T20", "T14"], ["T18", "T20", "T15"], ["T19", "T19", "T15"], ["T17", "T20", "T16"], ["T18", "T19", "T16"]] },
503
+ 160: { darts: ["T20", "T20", "D20"], numDarts: 3 },
504
+ 161: { darts: ["T20", "T17", "Bull"], numDarts: 3, alternates: [["T19", "T18", "Bull"]] },
505
+ 162: { darts: ["T20", "T20", "T14"], numDarts: 3, alternates: [["T19", "T20", "T15"], ["T18", "T20", "T16"], ["T19", "T19", "T16"], ["T17", "T20", "T17"], ["T18", "T19", "T17"]] },
506
+ 164: { darts: ["T20", "T18", "Bull"], numDarts: 3, alternates: [["T19", "T19", "Bull"]] },
507
+ 165: { darts: ["T20", "T20", "T15"], numDarts: 3, alternates: [["T19", "T20", "T16"], ["T18", "T20", "T17"], ["T19", "T19", "T17"], ["T18", "T19", "T18"]] },
508
+ 167: { darts: ["T20", "T19", "Bull"], numDarts: 3 },
509
+ 168: { darts: ["T20", "T20", "T16"], numDarts: 3, alternates: [["T19", "T20", "T17"], ["T18", "T20", "T18"], ["T19", "T19", "T18"]] },
510
+ 170: { darts: ["T20", "T20", "Bull"], numDarts: 3 },
511
+ 171: { darts: ["T20", "T20", "T17"], numDarts: 3, alternates: [["T19", "T20", "T18"], ["T19", "T19", "T19"]] },
512
+ 174: { darts: ["T20", "T20", "T18"], numDarts: 3, alternates: [["T19", "T20", "T19"]] },
513
+ 177: { darts: ["T20", "T20", "T19"], numDarts: 3 },
514
+ 180: { darts: ["T20", "T20", "T20"], numDarts: 3 }
515
+ };
516
+
517
+ // src/lookup.ts
518
+ function getChartForMode(outMode) {
519
+ return outMode === "double" ? DOUBLE_OUT_CHECKOUTS : SINGLE_OUT_CHECKOUTS;
520
+ }
521
+ function getBogeyNumbersForMode(outMode) {
522
+ return outMode === "double" ? DOUBLE_OUT_BOGEY_NUMBERS : SINGLE_OUT_BOGEY_NUMBERS;
523
+ }
524
+ function getCheckout(score, outMode = "double") {
525
+ const chart = getChartForMode(outMode);
526
+ return chart[score] ?? null;
527
+ }
528
+ function getCheckoutChart(outMode = "double", range) {
529
+ const chart = getChartForMode(outMode);
530
+ if (!range) return { ...chart };
531
+ const min = range.min ?? 0;
532
+ const max = range.max ?? Infinity;
533
+ const filtered = {};
534
+ for (const [scoreStr, entry] of Object.entries(chart)) {
535
+ const score = Number(scoreStr);
536
+ if (score >= min && score <= max) {
537
+ filtered[score] = entry;
538
+ }
539
+ }
540
+ return filtered;
541
+ }
542
+ function getBogeyNumbers(outMode = "double") {
543
+ return [...getBogeyNumbersForMode(outMode)];
544
+ }
545
+ function isCheckable(score, outMode = "double") {
546
+ const chart = getChartForMode(outMode);
547
+ return score in chart;
548
+ }
549
+
550
+ // src/generate.ts
551
+ function buildTargets() {
552
+ const targets = [];
553
+ for (let i = 1; i <= 20; i++) {
554
+ targets.push({ label: `${i}`, value: i });
555
+ targets.push({ label: `D${i}`, value: i * 2 });
556
+ targets.push({ label: `T${i}`, value: i * 3 });
557
+ }
558
+ targets.push({ label: "25", value: 25 });
559
+ targets.push({ label: "Bull", value: 50 });
560
+ return targets;
561
+ }
562
+ function buildFinishingDoubles() {
563
+ const doubles = [];
564
+ for (let i = 1; i <= 20; i++) {
565
+ doubles.push({ label: `D${i}`, value: i * 2 });
566
+ }
567
+ doubles.push({ label: "Bull", value: 50 });
568
+ return doubles;
569
+ }
570
+ function generateAllCheckouts(options) {
571
+ const { outMode } = options;
572
+ const isDouble = outMode === "double";
573
+ const min = options.min ?? (isDouble ? 2 : 1);
574
+ const max = options.max ?? 170;
575
+ const allTargets2 = buildTargets();
576
+ const finishingTargets = isDouble ? buildFinishingDoubles() : allTargets2;
577
+ const checkouts = {};
578
+ const bogeyNumbers = [];
579
+ let totalOptions = 0;
580
+ for (let score = min; score <= max; score++) {
581
+ const opts = [];
582
+ for (const d of finishingTargets) {
583
+ if (d.value === score) {
584
+ opts.push([d.label]);
585
+ }
586
+ }
587
+ for (const d1 of allTargets2) {
588
+ if (d1.value >= score) continue;
589
+ const remainder = score - d1.value;
590
+ for (const d2 of finishingTargets) {
591
+ if (d2.value === remainder) {
592
+ opts.push([d1.label, d2.label]);
593
+ }
594
+ }
595
+ }
596
+ if (score > (isDouble ? 2 : 1)) {
597
+ for (const d1 of allTargets2) {
598
+ if (d1.value >= score) continue;
599
+ for (const d2 of allTargets2) {
600
+ if (d1.value + d2.value >= score) continue;
601
+ const remainder = score - d1.value - d2.value;
602
+ for (const d3 of finishingTargets) {
603
+ if (d3.value === remainder) {
604
+ opts.push([d1.label, d2.label, d3.label]);
605
+ }
606
+ }
607
+ }
608
+ }
609
+ }
610
+ if (opts.length > 0) {
611
+ checkouts[score] = { options: opts, count: opts.length };
612
+ totalOptions += opts.length;
613
+ } else {
614
+ bogeyNumbers.push(score);
615
+ }
616
+ }
617
+ return { checkouts, bogeyNumbers, totalOptions };
618
+ }
619
+
620
+ // src/data/dartboard-dimensions.json
621
+ var dartboard_dimensions_default = {
622
+ meta: {
623
+ description: "Standard steel-tip dartboard dimensions and segment areas",
624
+ units: "millimeters (mm) and square millimeters (sq mm)",
625
+ sources: [
626
+ "dartbase.com/wwwboard/messages/1280.html",
627
+ "dartsnutz.net/forum/thread-40058.html",
628
+ "pages.cs.wisc.edu/~bolo/darts/dartboard.html",
629
+ "dimensions.com/element/dartboard",
630
+ "darting.com/Darts-Rules/General/"
631
+ ],
632
+ notes: "Measurements reflect the official WDF/BDO standard board. Modern competition boards (Winmau Blade, Unicorn Eclipse) may have slightly wider beds due to thinner blade wire dividers."
633
+ },
634
+ board: {
635
+ overallDiameter: 451,
636
+ playableDiameter: 340,
637
+ typicalDepth: 38.1,
638
+ wireWidth: 1.5,
639
+ numberHeight: 25.4
640
+ },
641
+ radialMeasurements: {
642
+ description: "Distance from board center to each ring boundary",
643
+ innerBullRadius: 6.35,
644
+ outerBullRadius: 15.9,
645
+ trebleRingInnerEdge: 99,
646
+ trebleRingOuterEdge: 107,
647
+ doubleRingInnerEdge: 162,
648
+ doubleRingOuterEdge: 170
649
+ },
650
+ ringWidths: {
651
+ trebleRing: 8,
652
+ doubleRing: 8,
653
+ outerBull: 9.55,
654
+ smallSingleBed: 83.1,
655
+ largeSingleBed: 55
656
+ },
657
+ segmentAreas: {
658
+ description: "Area of a single 1/20th segment of each ring, in sq mm",
659
+ doubleBull: 126.45,
660
+ singleBull: 665.16,
661
+ trebleBed: 309.03,
662
+ doubleBed: 498.71,
663
+ smallSingle: 1481.93,
664
+ largeSingle: 2288.38
665
+ },
666
+ totalRingAreas: {
667
+ description: "Total area of each full ring (all 20 segments combined), in sq mm",
668
+ doubleBull: 126.45,
669
+ singleBull: 665.16,
670
+ trebleRing: 5174.18,
671
+ doubleRing: 8341.92,
672
+ smallSingleRing: 29638.6,
673
+ largeSingleRing: 45767.6
674
+ },
675
+ segmentAreaRatios: {
676
+ description: "Size of each segment relative to other segments",
677
+ doubleBedVsTrebleBed: 1.61,
678
+ largeSingleVsTrebleBed: 7.41,
679
+ largeSingleVsDoubleBed: 4.59,
680
+ smallSingleVsTrebleBed: 4.8,
681
+ smallSingleVsDoubleBed: 2.97,
682
+ singleBullVsDoubleBull: 5.26,
683
+ doubleBedVsDoubleBull: 3.94,
684
+ trebleBedVsDoubleBull: 2.44
685
+ },
686
+ boardVariation: {
687
+ description: "Measured treble/double widths across popular competition boards (mm). Variation comes from differing wire/blade thickness.",
688
+ boards: {
689
+ bullsAdvantage501: { treble: 9.9, double: 9.65, bull: 12.9 },
690
+ unicornEclipseHD2: { treble: 9.68, double: 9.53, bull: 11.64 },
691
+ winmauBlade5: { treble: 9.42, double: 9.16, bull: 12.33 },
692
+ missionSamurai: { treble: 9.7 },
693
+ one80Gladiator3: { treble: 9.22, double: 9.26 },
694
+ shotBanditPlus: { treble: 9.09, double: 9.2 }
695
+ }
696
+ }
697
+ };
698
+
699
+ // src/recommend.ts
700
+ function buildTargets2() {
701
+ const targets = [];
702
+ for (let i = 1; i <= 20; i++) {
703
+ targets.push({ label: `${i}`, value: i });
704
+ targets.push({ label: `D${i}`, value: i * 2 });
705
+ targets.push({ label: `T${i}`, value: i * 3 });
706
+ }
707
+ targets.push({ label: "25", value: 25 });
708
+ targets.push({ label: "Bull", value: 50 });
709
+ return targets;
710
+ }
711
+ function buildFinishingDoubles2() {
712
+ const doubles = [];
713
+ for (let i = 1; i <= 20; i++) {
714
+ doubles.push({ label: `D${i}`, value: i * 2 });
715
+ }
716
+ doubles.push({ label: "Bull", value: 50 });
717
+ return doubles;
718
+ }
719
+ var allTargets = buildTargets2();
720
+ var finishingDoubles = buildFinishingDoubles2();
721
+ var AREA = {
722
+ treble: dartboard_dimensions_default.segmentAreas.trebleBed,
723
+ double: dartboard_dimensions_default.segmentAreas.doubleBed,
724
+ largeSingle: dartboard_dimensions_default.segmentAreas.largeSingle,
725
+ smallSingle: dartboard_dimensions_default.segmentAreas.smallSingle,
726
+ bull: dartboard_dimensions_default.segmentAreas.doubleBull,
727
+ outerBull: dartboard_dimensions_default.segmentAreas.singleBull
728
+ };
729
+ var oneDartScores = new Set(allTargets.map((t) => t.value));
730
+ function missWeight(target, missType) {
731
+ const parsed = parseTarget(target);
732
+ if (!parsed) return 0.5;
733
+ if (missType === "radialIn") {
734
+ if (!parsed.bed || parsed.bed === null) return AREA.treble / AREA.largeSingle;
735
+ if (parsed.bed === "double") return 1;
736
+ if (parsed.bed === "treble") return 1;
737
+ return 0.5;
738
+ }
739
+ if (missType === "radialOut") {
740
+ if (!parsed.bed || parsed.bed === null) return AREA.double / AREA.largeSingle;
741
+ if (parsed.bed === "double") return 0.5;
742
+ if (parsed.bed === "treble") return 1;
743
+ return 0.5;
744
+ }
745
+ return 0.7;
746
+ }
747
+ function evaluatePath(score, darts, outMode, checkableScores) {
748
+ let penalty = 0;
749
+ let remaining = score;
750
+ const isDoubleOut = outMode === "double";
751
+ for (let i = 0; i < darts.length; i++) {
752
+ const dart = darts[i];
753
+ const parsed = parseTarget(dart);
754
+ if (!parsed) return Infinity;
755
+ const evaluation = evaluateThrow(dart, remaining);
756
+ if (!evaluation) return Infinity;
757
+ for (const miss of evaluation.misses) {
758
+ const weight = missWeight(dart, miss.missType);
759
+ if (miss.busts) {
760
+ penalty += 6 * weight;
761
+ } else if (isDoubleOut) {
762
+ const missRemaining = remaining - miss.value;
763
+ if (missRemaining === 1) {
764
+ penalty += 6 * weight;
765
+ } else if (missRemaining === 0) {
766
+ } else if (checkableScores && checkableScores.has(missRemaining)) {
767
+ penalty -= 0.5 * weight;
768
+ }
769
+ } else {
770
+ const missRemaining = remaining - miss.value;
771
+ if (missRemaining === 0) {
772
+ penalty -= 1 * weight;
773
+ } else if (missRemaining > 0 && oneDartScores.has(missRemaining)) {
774
+ penalty -= 0.5 * weight;
775
+ }
776
+ }
777
+ }
778
+ let targetArea;
779
+ if (parsed.bed === "treble") targetArea = AREA.treble;
780
+ else if (parsed.bed === "double") targetArea = AREA.double;
781
+ else if (dart === "Bull") targetArea = AREA.bull;
782
+ else if (dart === "25") targetArea = AREA.outerBull;
783
+ else targetArea = AREA.largeSingle;
784
+ penalty += (1 - targetArea / AREA.largeSingle) * 5.5;
785
+ if ((parsed.bed === "treble" || parsed.bed === "double") && parsed.value <= 20) {
786
+ penalty += 5;
787
+ }
788
+ if (i > 0) {
789
+ const difficulty = (d) => {
790
+ if (/^T\d+$/.test(d)) return 3;
791
+ if (d === "Bull") return 2;
792
+ if (/^D\d+$/.test(d)) return 1.5;
793
+ if (d === "25") return 1;
794
+ return 0;
795
+ };
796
+ const prev = difficulty(darts[i - 1]);
797
+ const curr = difficulty(dart);
798
+ if (curr > prev && (parsed.bed === "treble" || dart === "Bull")) {
799
+ penalty += 4;
800
+ }
801
+ }
802
+ remaining -= parsed.value;
803
+ }
804
+ const lastDart = darts[darts.length - 1];
805
+ const lastMatch = lastDart.match(/^D(\d+)$/);
806
+ if (lastMatch) {
807
+ let val = parseInt(lastMatch[1]);
808
+ let chainLen = 0;
809
+ while (val % 2 === 0) {
810
+ val /= 2;
811
+ chainLen++;
812
+ }
813
+ chainLen++;
814
+ penalty -= chainLen * 0.2;
815
+ }
816
+ return penalty;
817
+ }
818
+ function sortTrebles(darts) {
819
+ const sorted = [...darts];
820
+ for (let i = 0; i < sorted.length - 1; i++) {
821
+ const m1 = sorted[i].match(/^T(\d+)$/);
822
+ const m2 = sorted[i + 1].match(/^T(\d+)$/);
823
+ if (m1 && m2 && parseInt(m1[1]) < parseInt(m2[1])) {
824
+ [sorted[i], sorted[i + 1]] = [sorted[i + 1], sorted[i]];
825
+ }
826
+ }
827
+ return sorted;
828
+ }
829
+ function pathKey(darts) {
830
+ return [...darts].sort().join(",");
831
+ }
832
+ var SINGLE_OUT_OVERRIDES = {
833
+ 1: { darts: ["1"] },
834
+ 2: { darts: ["2"] },
835
+ 3: { darts: ["3"] },
836
+ 4: { darts: ["4"] },
837
+ 5: { darts: ["5"] },
838
+ 6: { darts: ["6"] },
839
+ 7: { darts: ["7"] },
840
+ 8: { darts: ["8"] },
841
+ 9: { darts: ["9"] },
842
+ 10: { darts: ["10"] },
843
+ 11: { darts: ["11"] },
844
+ 12: { darts: ["12"] },
845
+ 13: { darts: ["13"] },
846
+ 14: { darts: ["14"] },
847
+ 15: { darts: ["15"] },
848
+ 16: { darts: ["16"] },
849
+ 17: { darts: ["17"] },
850
+ 18: { darts: ["18"] },
851
+ 19: { darts: ["19"] },
852
+ 20: { darts: ["20"] },
853
+ 21: { darts: ["7", "14"] },
854
+ 23: { darts: ["3", "20"] },
855
+ 25: { darts: ["9", "16"] },
856
+ 27: { darts: ["9", "18"] },
857
+ 29: { darts: ["9", "20"] },
858
+ 31: { darts: ["12", "19"] },
859
+ 33: { darts: ["14", "19"] },
860
+ 35: { darts: ["15", "20"] },
861
+ 37: { darts: ["18", "19"] },
862
+ 39: { darts: ["19", "20"] },
863
+ 50: { darts: ["10", "D20"] },
864
+ 80: { darts: ["T20", "20"] },
865
+ 82: { darts: ["T14", "D20"] },
866
+ 92: { darts: ["T20", "D16"] },
867
+ 100: { darts: ["T20", "D20"] },
868
+ 103: { darts: ["T19", "6", "D20"] },
869
+ 147: { darts: ["T20", "T17", "D18"] }
870
+ };
871
+ function findBestCheckout(score, outMode, altThreshold, includeAlternates, overrides) {
872
+ const isDoubleOut = outMode === "double";
873
+ const finishing = isDoubleOut ? finishingDoubles : allTargets;
874
+ let best = null;
875
+ let bestPenalty = Infinity;
876
+ let bestNumDarts = Infinity;
877
+ for (const t of finishing) {
878
+ if (t.value !== score) continue;
879
+ const parsed = parseTarget(t.label);
880
+ const priority = !isDoubleOut && parsed?.bed === "treble" && score <= 40 ? 2 : 1;
881
+ const penalty = evaluatePath(score, [t.label], outMode);
882
+ if (priority < bestNumDarts || priority === bestNumDarts && penalty < bestPenalty) {
883
+ best = [t.label];
884
+ bestPenalty = penalty;
885
+ bestNumDarts = priority;
886
+ }
887
+ }
888
+ for (const d1 of allTargets) {
889
+ if (d1.value >= score) continue;
890
+ const remainder = score - d1.value;
891
+ for (const d2 of finishing) {
892
+ if (d2.value !== remainder) continue;
893
+ const path = [d1.label, d2.label];
894
+ const penalty = evaluatePath(score, path, outMode);
895
+ if (2 < bestNumDarts || 2 === bestNumDarts && penalty < bestPenalty) {
896
+ best = path;
897
+ bestPenalty = penalty;
898
+ bestNumDarts = 2;
899
+ }
900
+ }
901
+ }
902
+ if (bestNumDarts > 2 || score > 110) {
903
+ for (const d1 of allTargets) {
904
+ if (d1.value >= score) continue;
905
+ for (const d2 of allTargets) {
906
+ if (d1.value + d2.value >= score) continue;
907
+ const remainder = score - d1.value - d2.value;
908
+ for (const d3 of finishing) {
909
+ if (d3.value !== remainder) continue;
910
+ const path = [d1.label, d2.label, d3.label];
911
+ const penalty = evaluatePath(score, path, outMode);
912
+ if (3 < bestNumDarts || 3 === bestNumDarts && penalty < bestPenalty) {
913
+ best = path;
914
+ bestPenalty = penalty;
915
+ bestNumDarts = 3;
916
+ }
917
+ }
918
+ }
919
+ }
920
+ }
921
+ if (!best) return null;
922
+ best = sortTrebles(best);
923
+ if (!includeAlternates) {
924
+ return { darts: best, numDarts: best.length, penalty: bestPenalty, alternates: [] };
925
+ }
926
+ const alternates = [];
927
+ const seen = /* @__PURE__ */ new Set();
928
+ seen.add(pathKey(best));
929
+ const collectAlt = (path, penalty) => {
930
+ if (penalty > bestPenalty + altThreshold) return;
931
+ const key = pathKey(path);
932
+ if (seen.has(key)) return;
933
+ seen.add(key);
934
+ alternates.push({ darts: sortTrebles(path), penalty });
935
+ };
936
+ if (bestNumDarts === 1) {
937
+ for (const t of finishing) {
938
+ if (t.value !== score) continue;
939
+ collectAlt([t.label], evaluatePath(score, [t.label], outMode));
940
+ }
941
+ }
942
+ if (bestNumDarts <= 2) {
943
+ for (const d1 of allTargets) {
944
+ if (d1.value >= score) continue;
945
+ const remainder = score - d1.value;
946
+ for (const d2 of finishing) {
947
+ if (d2.value !== remainder) continue;
948
+ collectAlt([d1.label, d2.label], evaluatePath(score, [d1.label, d2.label], outMode));
949
+ }
950
+ }
951
+ }
952
+ if (bestNumDarts === 3) {
953
+ for (const d1 of allTargets) {
954
+ if (d1.value >= score) continue;
955
+ for (const d2 of allTargets) {
956
+ if (d1.value + d2.value >= score) continue;
957
+ const remainder = score - d1.value - d2.value;
958
+ for (const d3 of finishing) {
959
+ if (d3.value !== remainder) continue;
960
+ collectAlt(
961
+ [d1.label, d2.label, d3.label],
962
+ evaluatePath(score, [d1.label, d2.label, d3.label], outMode)
963
+ );
964
+ }
965
+ }
966
+ }
967
+ }
968
+ alternates.sort((a, b) => a.penalty - b.penalty);
969
+ return {
970
+ darts: best,
971
+ numDarts: best.length,
972
+ penalty: bestPenalty,
973
+ alternates: alternates.slice(0, 5).map((a) => a.darts)
974
+ };
975
+ }
976
+ function validateOverrides(overrides, outMode) {
977
+ const isDoubleOut = outMode === "double";
978
+ for (const [scoreStr, entry] of Object.entries(overrides)) {
979
+ const score = Number(scoreStr);
980
+ if (!Array.isArray(entry.darts) || entry.darts.length === 0 || entry.darts.length > 3) {
981
+ throw new OutsChartError(
982
+ "INVALID_OVERRIDE",
983
+ `Override for score ${score}: must have 1-3 darts`
984
+ );
985
+ }
986
+ let sum = 0;
987
+ for (const dart of entry.darts) {
988
+ const parsed = parseTarget(dart);
989
+ if (!parsed) {
990
+ throw new OutsChartError(
991
+ "INVALID_OVERRIDE",
992
+ `Override for score ${score}: invalid dart notation '${dart}'`
993
+ );
994
+ }
995
+ sum += parsed.value;
996
+ }
997
+ if (sum !== score) {
998
+ throw new OutsChartError(
999
+ "INVALID_OVERRIDE",
1000
+ `Override for score ${score}: darts sum to ${sum}, expected ${score}`
1001
+ );
1002
+ }
1003
+ const lastDart = entry.darts[entry.darts.length - 1];
1004
+ const lastParsed = parseTarget(lastDart);
1005
+ if (isDoubleOut && lastParsed.bed !== "double" && lastParsed.bed !== "Bull") {
1006
+ throw new OutsChartError(
1007
+ "INVALID_OVERRIDE",
1008
+ `Override for score ${score}: last dart '${lastDart}' is not a valid double-out finish`
1009
+ );
1010
+ }
1011
+ }
1012
+ }
1013
+ function generateRecommended(options) {
1014
+ const { outMode } = options;
1015
+ const isDoubleOut = outMode === "double";
1016
+ const min = options.min ?? (isDoubleOut ? 2 : 1);
1017
+ const max = options.max ?? (isDoubleOut ? 170 : 180);
1018
+ const includeAlternates = options.includeAlternates ?? outMode === "single";
1019
+ const altThreshold = options.altThreshold ?? 1;
1020
+ const overrides = {};
1021
+ if (!isDoubleOut) {
1022
+ Object.assign(overrides, SINGLE_OUT_OVERRIDES);
1023
+ }
1024
+ if (options.overrides) {
1025
+ validateOverrides(options.overrides, outMode);
1026
+ Object.assign(overrides, options.overrides);
1027
+ }
1028
+ const checkouts = {};
1029
+ const bogeyNumbers = [];
1030
+ for (let score = min; score <= max; score++) {
1031
+ const result = findBestCheckout(score, outMode, altThreshold, includeAlternates, overrides);
1032
+ if (overrides[score]) {
1033
+ const ov = overrides[score];
1034
+ checkouts[score] = {
1035
+ darts: ov.darts,
1036
+ numDarts: ov.darts.length
1037
+ };
1038
+ if (includeAlternates && result && result.alternates.length > 0 && ov.darts.length > 1) {
1039
+ const overrideKey = pathKey(ov.darts);
1040
+ const alts = result.alternates.filter((a) => pathKey(a) !== overrideKey);
1041
+ if (pathKey(result.darts) !== overrideKey) {
1042
+ alts.unshift(result.darts);
1043
+ }
1044
+ if (alts.length > 0) checkouts[score].alternates = alts;
1045
+ }
1046
+ continue;
1047
+ }
1048
+ if (result) {
1049
+ checkouts[score] = {
1050
+ darts: result.darts,
1051
+ numDarts: result.numDarts
1052
+ };
1053
+ if (includeAlternates && result.alternates.length > 0) {
1054
+ checkouts[score].alternates = result.alternates;
1055
+ }
1056
+ } else {
1057
+ bogeyNumbers.push(score);
1058
+ }
1059
+ }
1060
+ return { checkouts, bogeyNumbers };
1061
+ }
1062
+
1063
+ // src/filter.ts
1064
+ function normalizeTargetLabel(str) {
1065
+ if (str === "Bull") return "Bull";
1066
+ if (str === "25") return "25";
1067
+ const m = str.match(/^([SDT])(\d+)$/);
1068
+ if (m) {
1069
+ return m[1] === "S" ? m[2] : `${m[1]}${m[2]}`;
1070
+ }
1071
+ if (/^\d+$/.test(str)) return str;
1072
+ return str;
1073
+ }
1074
+ function filterByPreferredTargets(checkouts, preferredTargets) {
1075
+ const preferredLabels = new Set(preferredTargets.map(normalizeTargetLabel));
1076
+ const filtered = {};
1077
+ for (const [score, entry] of Object.entries(checkouts)) {
1078
+ const matching = entry.options.filter(
1079
+ (darts) => preferredLabels.has(darts[darts.length - 1])
1080
+ );
1081
+ if (matching.length > 0) {
1082
+ filtered[Number(score)] = {
1083
+ options: matching,
1084
+ count: matching.length
1085
+ };
1086
+ }
1087
+ }
1088
+ return filtered;
1089
+ }
1090
+
1091
+ // src/notation.ts
1092
+ var NOTATIONS = {
1093
+ default: { treble: "T", double: "D", single: "", bull: "Bull", outerBull: "25" },
1094
+ british: { treble: "T", double: "D", single: "S", bull: "DB", outerBull: "SB" },
1095
+ american: { treble: "T", double: "D", single: "", bull: "DB", outerBull: "SB" },
1096
+ explicit: { treble: "T", double: "D", single: "S", bull: "Bull", outerBull: "25" }
1097
+ };
1098
+ function formatDart(dart, notation) {
1099
+ const parsed = parseTarget(dart);
1100
+ if (!parsed) {
1101
+ throw new OutsChartError("INVALID_TARGET", `Cannot format invalid dart notation '${dart}'`);
1102
+ }
1103
+ if (parsed.bed === "Bull") return notation.bull;
1104
+ if (parsed.bed === "25") return notation.outerBull;
1105
+ if (parsed.bed === "treble") return `${notation.treble}${parsed.number}`;
1106
+ if (parsed.bed === "double") return `${notation.double}${parsed.number}`;
1107
+ return `${notation.single}${parsed.number}`;
1108
+ }
1109
+ function formatCheckoutChart(chart, notation) {
1110
+ const map = resolveNotation(notation);
1111
+ const result = {};
1112
+ for (const [scoreStr, entry] of Object.entries(chart)) {
1113
+ const score = Number(scoreStr);
1114
+ const formatted = {
1115
+ darts: entry.darts.map((d) => formatDart(d, map)),
1116
+ numDarts: entry.numDarts
1117
+ };
1118
+ if (entry.alternates) {
1119
+ formatted.alternates = entry.alternates.map(
1120
+ (alt) => alt.map((d) => formatDart(d, map))
1121
+ );
1122
+ }
1123
+ result[score] = formatted;
1124
+ }
1125
+ return result;
1126
+ }
1127
+ function resolveNotation(notation) {
1128
+ if (typeof notation === "string") {
1129
+ const preset = NOTATIONS[notation];
1130
+ if (!preset) {
1131
+ throw new OutsChartError(
1132
+ "INVALID_TARGET",
1133
+ `Unknown notation preset '${notation}'. Available: ${Object.keys(NOTATIONS).join(", ")}`
1134
+ );
1135
+ }
1136
+ return preset;
1137
+ }
1138
+ return notation;
1139
+ }
1140
+ export {
1141
+ NOTATIONS,
1142
+ OutsChartError,
1143
+ filterByPreferredTargets,
1144
+ formatCheckoutChart,
1145
+ formatDart,
1146
+ formatTarget,
1147
+ generateAllCheckouts,
1148
+ generateRecommended,
1149
+ getBogeyNumbers,
1150
+ getCheckout,
1151
+ getCheckoutChart,
1152
+ isCheckable,
1153
+ parseTarget
1154
+ };
1155
+ //# sourceMappingURL=index.js.map