@tungstenstudio/dartboard-input 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.cjs ADDED
@@ -0,0 +1,450 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ DEFAULT_OPTIONS: () => DEFAULT_OPTIONS,
24
+ DEFAULT_RINGS: () => DEFAULT_RINGS,
25
+ DEFAULT_SEGMENTS: () => DEFAULT_SEGMENTS,
26
+ Dartboard: () => Dartboard,
27
+ MOBILE_OPTIONS: () => MOBILE_OPTIONS,
28
+ addRingToSegments: () => addRingToSegments,
29
+ asPercent: () => asPercent,
30
+ buildThrowDetail: () => buildThrowDetail,
31
+ parseBed: () => parseBed
32
+ });
33
+ module.exports = __toCommonJS(index_exports);
34
+
35
+ // src/dartboard.ts
36
+ var import_d3_selection = require("d3-selection");
37
+ var import_d3_shape = require("d3-shape");
38
+
39
+ // src/constants.ts
40
+ var DEFAULT_OPTIONS = {
41
+ size: null,
42
+ missPercent: 10,
43
+ doublePercent: 10,
44
+ outerSinglePercent: 25,
45
+ triplePercent: 10,
46
+ innerSinglePercent: 30,
47
+ singleBullPercent: 8,
48
+ doubleBullPercent: 7
49
+ };
50
+ var DEFAULT_RINGS = {
51
+ MISS: { name: "miss", abbr: "M", multiplier: 0 },
52
+ DOUBLE: { name: "double", abbr: "D", multiplier: 2 },
53
+ OUTER_SINGLE: { name: "outerSingle", abbr: "S", multiplier: 1 },
54
+ TRIPLE: { name: "triple", abbr: "T", multiplier: 3 },
55
+ INNER_SINGLE: { name: "innerSingle", abbr: "S", multiplier: 1 },
56
+ SINGLE_BULL: { name: "singleBull", abbr: "B", multiplier: 1 },
57
+ DOUBLE_BULL: { name: "doubleBull", abbr: "DB", multiplier: 2 }
58
+ };
59
+ var MOBILE_OPTIONS = {
60
+ missPercent: 7,
61
+ doublePercent: 14,
62
+ outerSinglePercent: 21,
63
+ triplePercent: 14,
64
+ innerSinglePercent: 26,
65
+ singleBullPercent: 9,
66
+ doubleBullPercent: 9
67
+ };
68
+ var DEFAULT_SEGMENTS = [
69
+ { segment: 20, position: 1, color: "Dark" },
70
+ { segment: 1, position: 2, color: "Light" },
71
+ { segment: 18, position: 3, color: "Dark" },
72
+ { segment: 4, position: 4, color: "Light" },
73
+ { segment: 13, position: 5, color: "Dark" },
74
+ { segment: 6, position: 6, color: "Light" },
75
+ { segment: 10, position: 7, color: "Dark" },
76
+ { segment: 15, position: 8, color: "Light" },
77
+ { segment: 2, position: 9, color: "Dark" },
78
+ { segment: 17, position: 10, color: "Light" },
79
+ { segment: 3, position: 11, color: "Dark" },
80
+ { segment: 19, position: 12, color: "Light" },
81
+ { segment: 7, position: 13, color: "Dark" },
82
+ { segment: 16, position: 14, color: "Light" },
83
+ { segment: 8, position: 15, color: "Dark" },
84
+ { segment: 11, position: 16, color: "Light" },
85
+ { segment: 14, position: 17, color: "Dark" },
86
+ { segment: 9, position: 18, color: "Light" },
87
+ { segment: 12, position: 19, color: "Dark" },
88
+ { segment: 5, position: 20, color: "Light" }
89
+ ];
90
+
91
+ // src/utils.ts
92
+ var SCORING_RINGS = [
93
+ "DOUBLE",
94
+ "TRIPLE",
95
+ "OUTER_SINGLE",
96
+ "INNER_SINGLE",
97
+ "SINGLE_BULL",
98
+ "DOUBLE_BULL"
99
+ ];
100
+ function buildThrowDetail(bed) {
101
+ return {
102
+ bed: bed.ring.abbr + bed.segment,
103
+ ring: bed.ring.name,
104
+ score: bed.segment * bed.ring.multiplier
105
+ };
106
+ }
107
+ function asPercent(n) {
108
+ return parseFloat((n / 100).toFixed(2));
109
+ }
110
+ function addRingToSegments(ring, segments) {
111
+ return segments.map((segment) => ({ ...segment, ring }));
112
+ }
113
+ function parseBed(bed, rings, segments) {
114
+ if (bed.toLowerCase() === "miss") {
115
+ if (!segments) {
116
+ throw new Error(
117
+ 'parseBed: segments are required to resolve the "miss" keyword'
118
+ );
119
+ }
120
+ return segments.map((s) => ({ segment: s.segment, ring: "MISS" }));
121
+ }
122
+ const numOnly = bed.match(/^(\d+)$/);
123
+ if (numOnly) {
124
+ const segment2 = parseInt(numOnly[1], 10);
125
+ return SCORING_RINGS.filter((key) => key in rings).map((ring) => ({ segment: segment2, ring }));
126
+ }
127
+ const match = bed.match(/^([A-Za-z]+)(\d+)$/);
128
+ if (!match) {
129
+ throw new Error(`Invalid bed format: "${bed}"`);
130
+ }
131
+ const [, abbr, numStr] = match.map((s, i) => i === 1 ? s.toUpperCase() : s);
132
+ const segment = parseInt(numStr, 10);
133
+ const targets = [];
134
+ for (const [key, ring] of Object.entries(rings)) {
135
+ if (ring.abbr === abbr) {
136
+ targets.push({ segment, ring: key });
137
+ }
138
+ }
139
+ if (targets.length === 0) {
140
+ throw new Error(`Unknown bed abbreviation: "${abbr}"`);
141
+ }
142
+ return targets;
143
+ }
144
+
145
+ // src/dartboard.ts
146
+ function buildAriaLabel(bed) {
147
+ const detail = buildThrowDetail(bed);
148
+ return `${detail.bed}, scores ${detail.score}`;
149
+ }
150
+ var Dartboard = class {
151
+ constructor(container, options = {}, segments = DEFAULT_SEGMENTS, rings = DEFAULT_RINGS) {
152
+ this.board = null;
153
+ this.sizes = null;
154
+ this.rendered = false;
155
+ this._disabled = false;
156
+ this.options = { ...DEFAULT_OPTIONS, ...options };
157
+ this.segments = segments;
158
+ this.rings = rings;
159
+ const percentSum = this.options.missPercent + this.options.doublePercent + this.options.outerSinglePercent + this.options.triplePercent + this.options.innerSinglePercent + this.options.singleBullPercent + this.options.doubleBullPercent;
160
+ if (percentSum !== 100) {
161
+ throw new Error(
162
+ `Dartboard: ring percentages must sum to 100 (got ${percentSum})`
163
+ );
164
+ }
165
+ const boardContainer = typeof container === "string" ? document.querySelector(container) : container;
166
+ if (!boardContainer) {
167
+ throw new Error(`Dartboard: container not found`);
168
+ }
169
+ const width = this.options.size || Math.min(boardContainer.offsetHeight, boardContainer.offsetWidth);
170
+ const segmentWidth = 360 / segments.length;
171
+ const radius = width / 2;
172
+ const rotation = segmentWidth / -2;
173
+ const wrapper = (0, import_d3_selection.select)(boardContainer).append("div").classed("c-Dartboard", true);
174
+ const svg = wrapper.append("svg").attr("viewBox", `0 0 ${width} ${width}`).attr("role", "group").attr("aria-label", "Dartboard").append("g").attr(
175
+ "transform",
176
+ `translate(${radius}, ${radius}) rotate(${rotation})`
177
+ );
178
+ const pieFn = (0, import_d3_shape.pie)().sort((a, b) => (a.position ?? 0) - (b.position ?? 0)).value(() => segmentWidth);
179
+ this.board = {
180
+ container: boardContainer,
181
+ wrapper,
182
+ width,
183
+ height: width,
184
+ radius,
185
+ rotation,
186
+ segmentWidth,
187
+ svg,
188
+ pie: pieFn
189
+ };
190
+ this.sizes = {
191
+ miss: radius * asPercent(this.options.missPercent),
192
+ double: radius * asPercent(this.options.doublePercent),
193
+ outerSingle: radius * asPercent(this.options.outerSinglePercent),
194
+ triple: radius * asPercent(this.options.triplePercent),
195
+ innerSingle: radius * asPercent(this.options.innerSinglePercent),
196
+ singleBull: radius * asPercent(this.options.singleBullPercent),
197
+ doubleBull: radius * asPercent(this.options.doubleBullPercent)
198
+ };
199
+ }
200
+ render() {
201
+ if (!this.board || !this.sizes) return this;
202
+ if (this.rendered) return this;
203
+ this.rendered = true;
204
+ const { board, sizes } = this;
205
+ let innerRadius = 0;
206
+ let outerRadius = innerRadius + sizes.doubleBull;
207
+ this.renderBeds(
208
+ board,
209
+ this.rings.DOUBLE_BULL,
210
+ [{ segment: 25, color: "Dark" }],
211
+ outerRadius,
212
+ innerRadius
213
+ );
214
+ innerRadius = outerRadius;
215
+ outerRadius = innerRadius + sizes.singleBull;
216
+ this.renderBeds(
217
+ board,
218
+ this.rings.SINGLE_BULL,
219
+ [{ segment: 25, color: "Light" }],
220
+ outerRadius,
221
+ innerRadius
222
+ );
223
+ innerRadius = outerRadius;
224
+ outerRadius = innerRadius + sizes.innerSingle;
225
+ this.renderBeds(
226
+ board,
227
+ this.rings.INNER_SINGLE,
228
+ this.segments,
229
+ outerRadius,
230
+ innerRadius
231
+ );
232
+ innerRadius = outerRadius;
233
+ outerRadius = innerRadius + sizes.triple;
234
+ this.renderBeds(
235
+ board,
236
+ this.rings.TRIPLE,
237
+ this.segments,
238
+ outerRadius,
239
+ innerRadius
240
+ );
241
+ innerRadius = outerRadius;
242
+ outerRadius = innerRadius + sizes.outerSingle;
243
+ this.renderBeds(
244
+ board,
245
+ this.rings.OUTER_SINGLE,
246
+ this.segments,
247
+ outerRadius,
248
+ innerRadius
249
+ );
250
+ innerRadius = outerRadius;
251
+ outerRadius = innerRadius + sizes.double;
252
+ this.renderBeds(
253
+ board,
254
+ this.rings.DOUBLE,
255
+ this.segments,
256
+ outerRadius,
257
+ innerRadius
258
+ );
259
+ innerRadius = board.radius - sizes.miss;
260
+ outerRadius = board.radius;
261
+ this.renderMissRing(
262
+ board,
263
+ this.rings.MISS,
264
+ this.segments,
265
+ outerRadius,
266
+ innerRadius
267
+ );
268
+ return this;
269
+ }
270
+ destroy() {
271
+ if (this.board) {
272
+ this.board.wrapper.selectAll(".c-Dartboard-bed").on("pointerup", null).on("pointerenter", null).on("pointerleave", null).on("keydown", null);
273
+ this.board.wrapper.remove();
274
+ this.board = null;
275
+ this.sizes = null;
276
+ this.rendered = false;
277
+ }
278
+ }
279
+ get disabled() {
280
+ return this._disabled;
281
+ }
282
+ disable() {
283
+ this._disabled = true;
284
+ if (this.board) {
285
+ this.board.wrapper.classed("is-disabled", true);
286
+ }
287
+ return this;
288
+ }
289
+ enable() {
290
+ this._disabled = false;
291
+ if (this.board) {
292
+ this.board.wrapper.classed("is-disabled", false);
293
+ }
294
+ return this;
295
+ }
296
+ throwAt(target) {
297
+ if (!this.board || this._disabled) return;
298
+ const targets = this.resolveTargets([target]);
299
+ if (targets.length === 0) return;
300
+ const first = targets[0];
301
+ if (!this.isValidTarget(first)) {
302
+ throw new Error(`Dartboard: invalid throw target \u2014 segment ${first.segment} does not exist`);
303
+ }
304
+ const ring = this.rings[first.ring];
305
+ const bed = { segment: first.segment, color: "Dark", ring };
306
+ const detail = buildThrowDetail(bed);
307
+ this.board.container.dispatchEvent(
308
+ new CustomEvent("throw", { detail })
309
+ );
310
+ }
311
+ highlight(targets, options = {}) {
312
+ if (!this.board) return;
313
+ const className = options.className || "is-highlighted";
314
+ for (const target of this.resolveTargets(targets)) {
315
+ const ring = this.rings[target.ring];
316
+ const selector = `.c-Dartboard-${ring.name} .c-Dartboard-bed--${target.segment}`;
317
+ this.board.wrapper.selectAll(selector).classed(className, true);
318
+ }
319
+ }
320
+ unhighlight(targets, options = {}) {
321
+ if (!this.board) return;
322
+ const className = options.className || "is-highlighted";
323
+ for (const target of this.resolveTargets(targets)) {
324
+ const ring = this.rings[target.ring];
325
+ const selector = `.c-Dartboard-${ring.name} .c-Dartboard-bed--${target.segment}`;
326
+ this.board.wrapper.selectAll(selector).classed(className, false);
327
+ }
328
+ }
329
+ reset(className = "is-highlighted") {
330
+ if (!this.board) return;
331
+ this.board.wrapper.selectAll(`.${className}`).classed(className, false);
332
+ }
333
+ isValidTarget(target) {
334
+ const isBull = target.ring === "DOUBLE_BULL" || target.ring === "SINGLE_BULL";
335
+ if (isBull) {
336
+ return target.segment === 25;
337
+ }
338
+ return this.segments.some((s) => s.segment === target.segment);
339
+ }
340
+ resolveTargets(inputs) {
341
+ return inputs.flatMap((input) => {
342
+ if (typeof input === "number") {
343
+ return parseBed(String(input), this.rings, this.segments);
344
+ }
345
+ if (typeof input === "string") {
346
+ return parseBed(input, this.rings, this.segments);
347
+ }
348
+ if (!input.ring) {
349
+ return parseBed(String(input.segment), this.rings, this.segments);
350
+ }
351
+ return [input];
352
+ });
353
+ }
354
+ dispatchThrow(bed) {
355
+ if (!this.board || this._disabled) return;
356
+ const detail = buildThrowDetail(bed);
357
+ this.board.container.dispatchEvent(
358
+ new CustomEvent("throw", { detail })
359
+ );
360
+ }
361
+ dispatchHover(bed, hovering) {
362
+ if (!this.board || this._disabled) return;
363
+ const throwDetail = buildThrowDetail(bed);
364
+ const detail = { ...throwDetail, hovering };
365
+ this.board.container.dispatchEvent(
366
+ new CustomEvent("hover", { detail })
367
+ );
368
+ }
369
+ renderBeds(board, ring, segments, outerRadius, innerRadius) {
370
+ const className = `c-Dartboard-${ring.name}`;
371
+ const arcFn = (0, import_d3_shape.arc)().outerRadius(outerRadius).innerRadius(innerRadius);
372
+ const beds = board.svg.append("g").classed(className, true).selectAll("arc").data(board.pie(addRingToSegments(ring, segments))).enter().append("g").attr(
373
+ "class",
374
+ (d) => `c-Dartboard-bed c-Dartboard-bed--${d.data.segment} ${className}--${d.data.segment} is${d.data.color}`
375
+ ).attr("role", "button").attr("tabindex", "0").attr(
376
+ "aria-label",
377
+ (d) => buildAriaLabel(d.data)
378
+ ).on(
379
+ "pointerup",
380
+ (_event, d) => {
381
+ this.dispatchThrow(d.data);
382
+ }
383
+ ).on(
384
+ "pointerenter",
385
+ (_event, d) => {
386
+ (0, import_d3_selection.select)(_event.currentTarget).classed("is-hovered", true);
387
+ this.dispatchHover(d.data, true);
388
+ }
389
+ ).on(
390
+ "pointerleave",
391
+ (_event, d) => {
392
+ (0, import_d3_selection.select)(_event.currentTarget).classed("is-hovered", false);
393
+ this.dispatchHover(d.data, false);
394
+ }
395
+ ).on(
396
+ "keydown",
397
+ (_event, d) => {
398
+ if (_event.key === "Enter" || _event.key === " ") {
399
+ _event.preventDefault();
400
+ this.dispatchThrow(d.data);
401
+ }
402
+ }
403
+ );
404
+ beds.append("path").attr("d", arcFn);
405
+ }
406
+ renderMissRing(board, ring, segments, outerRadius, innerRadius) {
407
+ const missArc = (0, import_d3_shape.arc)().outerRadius(outerRadius).innerRadius(innerRadius);
408
+ const missBeds = board.svg.append("g").classed("c-Dartboard-miss", true).selectAll("arc").data(board.pie(addRingToSegments(ring, segments))).enter().append("g").attr(
409
+ "class",
410
+ (d) => `c-Dartboard-bed c-Dartboard-bed--${d.data.segment} c-Dartboard-miss--${d.data.segment}`
411
+ ).attr("role", "button").attr("tabindex", "0").attr(
412
+ "aria-label",
413
+ (d) => buildAriaLabel(d.data)
414
+ ).on(
415
+ "pointerup",
416
+ (_event, d) => {
417
+ this.dispatchThrow(d.data);
418
+ }
419
+ ).on(
420
+ "keydown",
421
+ (_event, d) => {
422
+ if (_event.key === "Enter" || _event.key === " ") {
423
+ _event.preventDefault();
424
+ this.dispatchThrow(d.data);
425
+ }
426
+ }
427
+ );
428
+ missBeds.append("path").attr("d", missArc);
429
+ const determineRotation = (bedData) => -board.rotation + board.segmentWidth * ((bedData.position ?? 0) - 1);
430
+ const determineX = (d) => missArc.centroid(d)[0];
431
+ const determineY = (d) => missArc.centroid(d)[1];
432
+ missBeds.append("text").classed("c-Dartboard-missLabel", true).attr("x", (d) => determineX(d)).attr("y", (d) => determineY(d)).attr("dy", ".35em").attr(
433
+ "transform",
434
+ (d) => `rotate(${determineRotation(d.data)}, ${determineX(d)}, ${determineY(d)})`
435
+ ).attr("text-anchor", "middle").text((d) => d.data.segment);
436
+ }
437
+ };
438
+ // Annotate the CommonJS export names for ESM import in node:
439
+ 0 && (module.exports = {
440
+ DEFAULT_OPTIONS,
441
+ DEFAULT_RINGS,
442
+ DEFAULT_SEGMENTS,
443
+ Dartboard,
444
+ MOBILE_OPTIONS,
445
+ addRingToSegments,
446
+ asPercent,
447
+ buildThrowDetail,
448
+ parseBed
449
+ });
450
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/dartboard.ts","../src/constants.ts","../src/utils.ts"],"sourcesContent":["import './dartboard.css';\nexport { Dartboard } from './dartboard';\nexport type {\n Ring,\n Rings,\n Segment,\n Bed,\n DartboardOptions,\n ThrowDetail,\n HoverDetail,\n BedTarget,\n BedInput,\n HighlightOptions,\n} from './types';\nexport { DEFAULT_OPTIONS, MOBILE_OPTIONS, DEFAULT_RINGS, DEFAULT_SEGMENTS } from './constants';\nexport { buildThrowDetail, asPercent, addRingToSegments, parseBed } from './utils';\n","import { select, type Selection } from 'd3-selection';\nimport { arc, pie, type PieArcDatum } from 'd3-shape';\nimport type {\n DartboardOptions,\n Rings,\n Ring,\n Segment,\n Bed,\n ThrowDetail,\n HoverDetail,\n BedTarget,\n BedInput,\n HighlightOptions,\n} from './types';\nimport { DEFAULT_OPTIONS, DEFAULT_RINGS, DEFAULT_SEGMENTS } from './constants';\nimport { buildThrowDetail, asPercent, addRingToSegments, parseBed } from './utils';\n\n// D3's selection generics are deeply nested and don't compose well across\n// chained calls. Using `any` for internal state avoids 100+ lines of type\n// gymnastics while keeping the public API fully typed.\n/* eslint-disable @typescript-eslint/no-explicit-any */\ninterface BoardState {\n container: HTMLElement;\n wrapper: Selection<any, any, any, any>;\n width: number;\n height: number;\n radius: number;\n rotation: number;\n segmentWidth: number;\n svg: Selection<any, any, any, any>;\n pie: ReturnType<typeof pie<Bed>>;\n}\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\ninterface SizeMap {\n miss: number;\n double: number;\n outerSingle: number;\n triple: number;\n innerSingle: number;\n singleBull: number;\n doubleBull: number;\n}\n\nfunction buildAriaLabel(bed: Bed): string {\n const detail = buildThrowDetail(bed);\n return `${detail.bed}, scores ${detail.score}`;\n}\n\nexport class Dartboard {\n private board: BoardState | null = null;\n private sizes: SizeMap | null = null;\n private rendered = false;\n private _disabled = false;\n private readonly options: DartboardOptions;\n readonly segments: Segment[];\n readonly rings: Rings;\n\n constructor(\n container: string | HTMLElement,\n options: Partial<DartboardOptions> = {},\n segments: Segment[] = DEFAULT_SEGMENTS,\n rings: Rings = DEFAULT_RINGS,\n ) {\n this.options = { ...DEFAULT_OPTIONS, ...options };\n this.segments = segments;\n this.rings = rings;\n\n const percentSum =\n this.options.missPercent +\n this.options.doublePercent +\n this.options.outerSinglePercent +\n this.options.triplePercent +\n this.options.innerSinglePercent +\n this.options.singleBullPercent +\n this.options.doubleBullPercent;\n\n if (percentSum !== 100) {\n throw new Error(\n `Dartboard: ring percentages must sum to 100 (got ${percentSum})`,\n );\n }\n\n const boardContainer =\n typeof container === 'string'\n ? document.querySelector<HTMLElement>(container)\n : container;\n\n if (!boardContainer) {\n throw new Error(`Dartboard: container not found`);\n }\n\n const width =\n this.options.size ||\n Math.min(boardContainer.offsetHeight, boardContainer.offsetWidth);\n const segmentWidth = 360 / segments.length;\n const radius = width / 2;\n const rotation = segmentWidth / -2;\n\n const wrapper = select(boardContainer)\n .append('div')\n .classed('c-Dartboard', true);\n\n const svg = wrapper\n .append('svg')\n .attr('viewBox', `0 0 ${width} ${width}`)\n .attr('role', 'group')\n .attr('aria-label', 'Dartboard')\n .append('g')\n .attr(\n 'transform',\n `translate(${radius}, ${radius}) rotate(${rotation})`,\n );\n\n const pieFn = pie<Bed>()\n .sort((a, b) => (a.position ?? 0) - (b.position ?? 0))\n .value(() => segmentWidth);\n\n this.board = {\n container: boardContainer,\n wrapper,\n width,\n height: width,\n radius,\n rotation,\n segmentWidth,\n svg,\n pie: pieFn,\n };\n\n this.sizes = {\n miss: radius * asPercent(this.options.missPercent),\n double: radius * asPercent(this.options.doublePercent),\n outerSingle: radius * asPercent(this.options.outerSinglePercent),\n triple: radius * asPercent(this.options.triplePercent),\n innerSingle: radius * asPercent(this.options.innerSinglePercent),\n singleBull: radius * asPercent(this.options.singleBullPercent),\n doubleBull: radius * asPercent(this.options.doubleBullPercent),\n };\n }\n\n render(): this {\n if (!this.board || !this.sizes) return this;\n if (this.rendered) return this;\n this.rendered = true;\n\n const { board, sizes } = this;\n\n let innerRadius = 0;\n let outerRadius = innerRadius + sizes.doubleBull;\n this.renderBeds(\n board,\n this.rings.DOUBLE_BULL,\n [{ segment: 25, color: 'Dark' }],\n outerRadius,\n innerRadius,\n );\n\n innerRadius = outerRadius;\n outerRadius = innerRadius + sizes.singleBull;\n this.renderBeds(\n board,\n this.rings.SINGLE_BULL,\n [{ segment: 25, color: 'Light' }],\n outerRadius,\n innerRadius,\n );\n\n innerRadius = outerRadius;\n outerRadius = innerRadius + sizes.innerSingle;\n this.renderBeds(\n board,\n this.rings.INNER_SINGLE,\n this.segments,\n outerRadius,\n innerRadius,\n );\n\n innerRadius = outerRadius;\n outerRadius = innerRadius + sizes.triple;\n this.renderBeds(\n board,\n this.rings.TRIPLE,\n this.segments,\n outerRadius,\n innerRadius,\n );\n\n innerRadius = outerRadius;\n outerRadius = innerRadius + sizes.outerSingle;\n this.renderBeds(\n board,\n this.rings.OUTER_SINGLE,\n this.segments,\n outerRadius,\n innerRadius,\n );\n\n innerRadius = outerRadius;\n outerRadius = innerRadius + sizes.double;\n this.renderBeds(\n board,\n this.rings.DOUBLE,\n this.segments,\n outerRadius,\n innerRadius,\n );\n\n innerRadius = board.radius - sizes.miss;\n outerRadius = board.radius;\n this.renderMissRing(\n board,\n this.rings.MISS,\n this.segments,\n outerRadius,\n innerRadius,\n );\n\n return this;\n }\n\n destroy(): void {\n if (this.board) {\n // Remove all D3 event listeners before removing from DOM\n this.board.wrapper.selectAll('.c-Dartboard-bed')\n .on('pointerup', null)\n .on('pointerenter', null)\n .on('pointerleave', null)\n .on('keydown', null);\n this.board.wrapper.remove();\n this.board = null;\n this.sizes = null;\n this.rendered = false;\n }\n }\n\n get disabled(): boolean {\n return this._disabled;\n }\n\n disable(): this {\n this._disabled = true;\n if (this.board) {\n this.board.wrapper.classed('is-disabled', true);\n }\n return this;\n }\n\n enable(): this {\n this._disabled = false;\n if (this.board) {\n this.board.wrapper.classed('is-disabled', false);\n }\n return this;\n }\n\n throwAt(target: BedInput): void {\n if (!this.board || this._disabled) return;\n\n const targets = this.resolveTargets([target]);\n if (targets.length === 0) return;\n const first = targets[0];\n\n if (!this.isValidTarget(first)) {\n throw new Error(`Dartboard: invalid throw target — segment ${first.segment} does not exist`);\n }\n\n const ring = this.rings[first.ring];\n const bed: Bed = { segment: first.segment, color: 'Dark', ring };\n const detail = buildThrowDetail(bed);\n\n this.board.container.dispatchEvent(\n new CustomEvent<ThrowDetail>('throw', { detail }),\n );\n }\n\n highlight(targets: BedInput[], options: HighlightOptions = {}): void {\n if (!this.board) return;\n const className = options.className || 'is-highlighted';\n\n for (const target of this.resolveTargets(targets)) {\n const ring = this.rings[target.ring];\n const selector = `.c-Dartboard-${ring.name} .c-Dartboard-bed--${target.segment}`;\n this.board.wrapper.selectAll(selector).classed(className, true);\n }\n }\n\n unhighlight(targets: BedInput[], options: HighlightOptions = {}): void {\n if (!this.board) return;\n const className = options.className || 'is-highlighted';\n\n for (const target of this.resolveTargets(targets)) {\n const ring = this.rings[target.ring];\n const selector = `.c-Dartboard-${ring.name} .c-Dartboard-bed--${target.segment}`;\n this.board.wrapper.selectAll(selector).classed(className, false);\n }\n }\n\n reset(className = 'is-highlighted'): void {\n if (!this.board) return;\n this.board.wrapper.selectAll(`.${className}`).classed(className, false);\n }\n\n private isValidTarget(target: Required<BedTarget>): boolean {\n const isBull = target.ring === 'DOUBLE_BULL' || target.ring === 'SINGLE_BULL';\n if (isBull) {\n return target.segment === 25;\n }\n return this.segments.some((s) => s.segment === target.segment);\n }\n\n private resolveTargets(inputs: BedInput[]): Required<BedTarget>[] {\n return inputs.flatMap((input): Required<BedTarget>[] => {\n if (typeof input === 'number') {\n return parseBed(String(input), this.rings, this.segments) as Required<BedTarget>[];\n }\n if (typeof input === 'string') {\n return parseBed(input, this.rings, this.segments) as Required<BedTarget>[];\n }\n if (!input.ring) {\n return parseBed(String(input.segment), this.rings, this.segments) as Required<BedTarget>[];\n }\n return [input as Required<BedTarget>];\n });\n }\n\n private dispatchThrow(bed: Bed): void {\n if (!this.board || this._disabled) return;\n const detail = buildThrowDetail(bed);\n this.board.container.dispatchEvent(\n new CustomEvent<ThrowDetail>('throw', { detail }),\n );\n }\n\n private dispatchHover(bed: Bed, hovering: boolean): void {\n if (!this.board || this._disabled) return;\n const throwDetail = buildThrowDetail(bed);\n const detail: HoverDetail = { ...throwDetail, hovering };\n this.board.container.dispatchEvent(\n new CustomEvent<HoverDetail>('hover', { detail }),\n );\n }\n\n private renderBeds(\n board: BoardState,\n ring: Ring,\n segments: Segment[],\n outerRadius: number,\n innerRadius: number,\n ): void {\n const className = `c-Dartboard-${ring.name}`;\n const arcFn = arc<PieArcDatum<Bed>>()\n .outerRadius(outerRadius)\n .innerRadius(innerRadius);\n\n const beds = board.svg\n .append('g')\n .classed(className, true)\n .selectAll<SVGGElement, PieArcDatum<Bed>>('arc')\n .data(board.pie(addRingToSegments(ring, segments)))\n .enter()\n .append('g')\n .attr(\n 'class',\n (d: PieArcDatum<Bed>) =>\n `c-Dartboard-bed c-Dartboard-bed--${d.data.segment} ${className}--${d.data.segment} is${d.data.color}`,\n )\n .attr('role', 'button')\n .attr('tabindex', '0')\n .attr('aria-label', (d: PieArcDatum<Bed>) =>\n buildAriaLabel(d.data),\n )\n .on(\n 'pointerup',\n (_event: PointerEvent, d: PieArcDatum<Bed>) => {\n this.dispatchThrow(d.data);\n },\n )\n .on(\n 'pointerenter',\n (_event: PointerEvent, d: PieArcDatum<Bed>) => {\n select(_event.currentTarget as Element).classed('is-hovered', true);\n this.dispatchHover(d.data, true);\n },\n )\n .on(\n 'pointerleave',\n (_event: PointerEvent, d: PieArcDatum<Bed>) => {\n select(_event.currentTarget as Element).classed('is-hovered', false);\n this.dispatchHover(d.data, false);\n },\n )\n .on(\n 'keydown',\n (_event: KeyboardEvent, d: PieArcDatum<Bed>) => {\n if (_event.key === 'Enter' || _event.key === ' ') {\n _event.preventDefault();\n this.dispatchThrow(d.data);\n }\n },\n );\n\n beds.append('path').attr('d', arcFn as never);\n }\n\n private renderMissRing(\n board: BoardState,\n ring: Ring,\n segments: Segment[],\n outerRadius: number,\n innerRadius: number,\n ): void {\n const missArc = arc<PieArcDatum<Bed>>()\n .outerRadius(outerRadius)\n .innerRadius(innerRadius);\n\n const missBeds = board.svg\n .append('g')\n .classed('c-Dartboard-miss', true)\n .selectAll<SVGGElement, PieArcDatum<Bed>>('arc')\n .data(board.pie(addRingToSegments(ring, segments)))\n .enter()\n .append('g')\n .attr(\n 'class',\n (d: PieArcDatum<Bed>) =>\n `c-Dartboard-bed c-Dartboard-bed--${d.data.segment} c-Dartboard-miss--${d.data.segment}`,\n )\n .attr('role', 'button')\n .attr('tabindex', '0')\n .attr('aria-label', (d: PieArcDatum<Bed>) =>\n buildAriaLabel(d.data),\n )\n .on(\n 'pointerup',\n (_event: PointerEvent, d: PieArcDatum<Bed>) => {\n this.dispatchThrow(d.data);\n },\n )\n .on(\n 'keydown',\n (_event: KeyboardEvent, d: PieArcDatum<Bed>) => {\n if (_event.key === 'Enter' || _event.key === ' ') {\n _event.preventDefault();\n this.dispatchThrow(d.data);\n }\n },\n );\n\n missBeds.append('path').attr('d', missArc as never);\n\n const determineRotation = (bedData: Bed) =>\n -board.rotation + board.segmentWidth * ((bedData.position ?? 0) - 1);\n\n const determineX = (d: PieArcDatum<Bed>) =>\n missArc.centroid(d)[0];\n\n const determineY = (d: PieArcDatum<Bed>) =>\n missArc.centroid(d)[1];\n\n missBeds\n .append('text')\n .classed('c-Dartboard-missLabel', true)\n .attr('x', (d: PieArcDatum<Bed>) => determineX(d))\n .attr('y', (d: PieArcDatum<Bed>) => determineY(d))\n .attr('dy', '.35em')\n .attr(\n 'transform',\n (d: PieArcDatum<Bed>) =>\n `rotate(${determineRotation(d.data)}, ${determineX(d)}, ${determineY(d)})`,\n )\n .attr('text-anchor', 'middle')\n .text((d: PieArcDatum<Bed>) => d.data.segment);\n }\n}\n","import type { DartboardOptions, Rings, Segment } from './types';\n\nexport const DEFAULT_OPTIONS: DartboardOptions = {\n size: null,\n missPercent: 10,\n doublePercent: 10,\n outerSinglePercent: 25,\n triplePercent: 10,\n innerSinglePercent: 30,\n singleBullPercent: 8,\n doubleBullPercent: 7,\n};\n\nexport const DEFAULT_RINGS: Rings = {\n MISS: { name: 'miss', abbr: 'M', multiplier: 0 },\n DOUBLE: { name: 'double', abbr: 'D', multiplier: 2 },\n OUTER_SINGLE: { name: 'outerSingle', abbr: 'S', multiplier: 1 },\n TRIPLE: { name: 'triple', abbr: 'T', multiplier: 3 },\n INNER_SINGLE: { name: 'innerSingle', abbr: 'S', multiplier: 1 },\n SINGLE_BULL: { name: 'singleBull', abbr: 'B', multiplier: 1 },\n DOUBLE_BULL: { name: 'doubleBull', abbr: 'DB', multiplier: 2 },\n};\n\nexport const MOBILE_OPTIONS: Partial<DartboardOptions> = {\n missPercent: 7,\n doublePercent: 14,\n outerSinglePercent: 21,\n triplePercent: 14,\n innerSinglePercent: 26,\n singleBullPercent: 9,\n doubleBullPercent: 9,\n};\n\nexport const DEFAULT_SEGMENTS: Segment[] = [\n { segment: 20, position: 1, color: 'Dark' },\n { segment: 1, position: 2, color: 'Light' },\n { segment: 18, position: 3, color: 'Dark' },\n { segment: 4, position: 4, color: 'Light' },\n { segment: 13, position: 5, color: 'Dark' },\n { segment: 6, position: 6, color: 'Light' },\n { segment: 10, position: 7, color: 'Dark' },\n { segment: 15, position: 8, color: 'Light' },\n { segment: 2, position: 9, color: 'Dark' },\n { segment: 17, position: 10, color: 'Light' },\n { segment: 3, position: 11, color: 'Dark' },\n { segment: 19, position: 12, color: 'Light' },\n { segment: 7, position: 13, color: 'Dark' },\n { segment: 16, position: 14, color: 'Light' },\n { segment: 8, position: 15, color: 'Dark' },\n { segment: 11, position: 16, color: 'Light' },\n { segment: 14, position: 17, color: 'Dark' },\n { segment: 9, position: 18, color: 'Light' },\n { segment: 12, position: 19, color: 'Dark' },\n { segment: 5, position: 20, color: 'Light' },\n];\n","import type { Ring, Rings, Segment, Bed, BedTarget, ThrowDetail } from './types';\n\nconst SCORING_RINGS: (keyof Rings)[] = [\n 'DOUBLE',\n 'TRIPLE',\n 'OUTER_SINGLE',\n 'INNER_SINGLE',\n 'SINGLE_BULL',\n 'DOUBLE_BULL',\n];\n\nexport function buildThrowDetail(bed: Bed): ThrowDetail {\n return {\n bed: bed.ring.abbr + bed.segment,\n ring: bed.ring.name,\n score: bed.segment * bed.ring.multiplier,\n };\n}\n\nexport function asPercent(n: number): number {\n return parseFloat((n / 100).toFixed(2));\n}\n\nexport function addRingToSegments(ring: Ring, segments: Segment[]): Bed[] {\n return segments.map((segment) => ({ ...segment, ring }));\n}\n\nexport function parseBed(\n bed: string,\n rings: Rings,\n segments?: Segment[],\n): BedTarget[] {\n // 'miss' keyword — target all segments in the miss ring\n if (bed.toLowerCase() === 'miss') {\n if (!segments) {\n throw new Error(\n 'parseBed: segments are required to resolve the \"miss\" keyword',\n );\n }\n return segments.map((s) => ({ segment: s.segment, ring: 'MISS' as keyof Rings }));\n }\n\n // Number-only string — target all scoring rings on that segment\n const numOnly = bed.match(/^(\\d+)$/);\n if (numOnly) {\n const segment = parseInt(numOnly[1], 10);\n return SCORING_RINGS\n .filter((key) => key in rings)\n .map((ring) => ({ segment, ring }));\n }\n\n const match = bed.match(/^([A-Za-z]+)(\\d+)$/);\n if (!match) {\n throw new Error(`Invalid bed format: \"${bed}\"`);\n }\n\n const [, abbr, numStr] = match.map((s, i) => i === 1 ? s.toUpperCase() : s);\n const segment = parseInt(numStr, 10);\n\n const targets: BedTarget[] = [];\n for (const [key, ring] of Object.entries(rings)) {\n if (ring.abbr === abbr) {\n targets.push({ segment, ring: key as keyof Rings });\n }\n }\n\n if (targets.length === 0) {\n throw new Error(`Unknown bed abbreviation: \"${abbr}\"`);\n }\n\n return targets;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,0BAAuC;AACvC,sBAA2C;;;ACCpC,IAAM,kBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,aAAa;AAAA,EACb,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,mBAAmB;AACrB;AAEO,IAAM,gBAAuB;AAAA,EAClC,MAAM,EAAE,MAAM,QAAQ,MAAM,KAAK,YAAY,EAAE;AAAA,EAC/C,QAAQ,EAAE,MAAM,UAAU,MAAM,KAAK,YAAY,EAAE;AAAA,EACnD,cAAc,EAAE,MAAM,eAAe,MAAM,KAAK,YAAY,EAAE;AAAA,EAC9D,QAAQ,EAAE,MAAM,UAAU,MAAM,KAAK,YAAY,EAAE;AAAA,EACnD,cAAc,EAAE,MAAM,eAAe,MAAM,KAAK,YAAY,EAAE;AAAA,EAC9D,aAAa,EAAE,MAAM,cAAc,MAAM,KAAK,YAAY,EAAE;AAAA,EAC5D,aAAa,EAAE,MAAM,cAAc,MAAM,MAAM,YAAY,EAAE;AAC/D;AAEO,IAAM,iBAA4C;AAAA,EACvD,aAAa;AAAA,EACb,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,mBAAmB;AACrB;AAEO,IAAM,mBAA8B;AAAA,EACzC,EAAE,SAAS,IAAI,UAAU,GAAG,OAAO,OAAO;AAAA,EAC1C,EAAE,SAAS,GAAG,UAAU,GAAG,OAAO,QAAQ;AAAA,EAC1C,EAAE,SAAS,IAAI,UAAU,GAAG,OAAO,OAAO;AAAA,EAC1C,EAAE,SAAS,GAAG,UAAU,GAAG,OAAO,QAAQ;AAAA,EAC1C,EAAE,SAAS,IAAI,UAAU,GAAG,OAAO,OAAO;AAAA,EAC1C,EAAE,SAAS,GAAG,UAAU,GAAG,OAAO,QAAQ;AAAA,EAC1C,EAAE,SAAS,IAAI,UAAU,GAAG,OAAO,OAAO;AAAA,EAC1C,EAAE,SAAS,IAAI,UAAU,GAAG,OAAO,QAAQ;AAAA,EAC3C,EAAE,SAAS,GAAG,UAAU,GAAG,OAAO,OAAO;AAAA,EACzC,EAAE,SAAS,IAAI,UAAU,IAAI,OAAO,QAAQ;AAAA,EAC5C,EAAE,SAAS,GAAG,UAAU,IAAI,OAAO,OAAO;AAAA,EAC1C,EAAE,SAAS,IAAI,UAAU,IAAI,OAAO,QAAQ;AAAA,EAC5C,EAAE,SAAS,GAAG,UAAU,IAAI,OAAO,OAAO;AAAA,EAC1C,EAAE,SAAS,IAAI,UAAU,IAAI,OAAO,QAAQ;AAAA,EAC5C,EAAE,SAAS,GAAG,UAAU,IAAI,OAAO,OAAO;AAAA,EAC1C,EAAE,SAAS,IAAI,UAAU,IAAI,OAAO,QAAQ;AAAA,EAC5C,EAAE,SAAS,IAAI,UAAU,IAAI,OAAO,OAAO;AAAA,EAC3C,EAAE,SAAS,GAAG,UAAU,IAAI,OAAO,QAAQ;AAAA,EAC3C,EAAE,SAAS,IAAI,UAAU,IAAI,OAAO,OAAO;AAAA,EAC3C,EAAE,SAAS,GAAG,UAAU,IAAI,OAAO,QAAQ;AAC7C;;;ACpDA,IAAM,gBAAiC;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,iBAAiB,KAAuB;AACtD,SAAO;AAAA,IACL,KAAK,IAAI,KAAK,OAAO,IAAI;AAAA,IACzB,MAAM,IAAI,KAAK;AAAA,IACf,OAAO,IAAI,UAAU,IAAI,KAAK;AAAA,EAChC;AACF;AAEO,SAAS,UAAU,GAAmB;AAC3C,SAAO,YAAY,IAAI,KAAK,QAAQ,CAAC,CAAC;AACxC;AAEO,SAAS,kBAAkB,MAAY,UAA4B;AACxE,SAAO,SAAS,IAAI,CAAC,aAAa,EAAE,GAAG,SAAS,KAAK,EAAE;AACzD;AAEO,SAAS,SACd,KACA,OACA,UACa;AAEb,MAAI,IAAI,YAAY,MAAM,QAAQ;AAChC,QAAI,CAAC,UAAU;AACb,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,WAAO,SAAS,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,MAAM,OAAsB,EAAE;AAAA,EAClF;AAGA,QAAM,UAAU,IAAI,MAAM,SAAS;AACnC,MAAI,SAAS;AACX,UAAMA,WAAU,SAAS,QAAQ,CAAC,GAAG,EAAE;AACvC,WAAO,cACJ,OAAO,CAAC,QAAQ,OAAO,KAAK,EAC5B,IAAI,CAAC,UAAU,EAAE,SAAAA,UAAS,KAAK,EAAE;AAAA,EACtC;AAEA,QAAM,QAAQ,IAAI,MAAM,oBAAoB;AAC5C,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,MAAM,wBAAwB,GAAG,GAAG;AAAA,EAChD;AAEA,QAAM,CAAC,EAAE,MAAM,MAAM,IAAI,MAAM,IAAI,CAAC,GAAG,MAAM,MAAM,IAAI,EAAE,YAAY,IAAI,CAAC;AAC1E,QAAM,UAAU,SAAS,QAAQ,EAAE;AAEnC,QAAM,UAAuB,CAAC;AAC9B,aAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,KAAK,GAAG;AAC/C,QAAI,KAAK,SAAS,MAAM;AACtB,cAAQ,KAAK,EAAE,SAAS,MAAM,IAAmB,CAAC;AAAA,IACpD;AAAA,EACF;AAEA,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,IAAI,MAAM,8BAA8B,IAAI,GAAG;AAAA,EACvD;AAEA,SAAO;AACT;;;AF3BA,SAAS,eAAe,KAAkB;AACxC,QAAM,SAAS,iBAAiB,GAAG;AACnC,SAAO,GAAG,OAAO,GAAG,YAAY,OAAO,KAAK;AAC9C;AAEO,IAAM,YAAN,MAAgB;AAAA,EASrB,YACE,WACA,UAAqC,CAAC,GACtC,WAAsB,kBACtB,QAAe,eACf;AAbF,SAAQ,QAA2B;AACnC,SAAQ,QAAwB;AAChC,SAAQ,WAAW;AACnB,SAAQ,YAAY;AAWlB,SAAK,UAAU,EAAE,GAAG,iBAAiB,GAAG,QAAQ;AAChD,SAAK,WAAW;AAChB,SAAK,QAAQ;AAEb,UAAM,aACJ,KAAK,QAAQ,cACb,KAAK,QAAQ,gBACb,KAAK,QAAQ,qBACb,KAAK,QAAQ,gBACb,KAAK,QAAQ,qBACb,KAAK,QAAQ,oBACb,KAAK,QAAQ;AAEf,QAAI,eAAe,KAAK;AACtB,YAAM,IAAI;AAAA,QACR,oDAAoD,UAAU;AAAA,MAChE;AAAA,IACF;AAEA,UAAM,iBACJ,OAAO,cAAc,WACjB,SAAS,cAA2B,SAAS,IAC7C;AAEN,QAAI,CAAC,gBAAgB;AACnB,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AAEA,UAAM,QACJ,KAAK,QAAQ,QACb,KAAK,IAAI,eAAe,cAAc,eAAe,WAAW;AAClE,UAAM,eAAe,MAAM,SAAS;AACpC,UAAM,SAAS,QAAQ;AACvB,UAAM,WAAW,eAAe;AAEhC,UAAM,cAAU,4BAAO,cAAc,EAClC,OAAO,KAAK,EACZ,QAAQ,eAAe,IAAI;AAE9B,UAAM,MAAM,QACT,OAAO,KAAK,EACZ,KAAK,WAAW,OAAO,KAAK,IAAI,KAAK,EAAE,EACvC,KAAK,QAAQ,OAAO,EACpB,KAAK,cAAc,WAAW,EAC9B,OAAO,GAAG,EACV;AAAA,MACC;AAAA,MACA,aAAa,MAAM,KAAK,MAAM,YAAY,QAAQ;AAAA,IACpD;AAEF,UAAM,YAAQ,qBAAS,EACpB,KAAK,CAAC,GAAG,OAAO,EAAE,YAAY,MAAM,EAAE,YAAY,EAAE,EACpD,MAAM,MAAM,YAAY;AAE3B,SAAK,QAAQ;AAAA,MACX,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,KAAK;AAAA,IACP;AAEA,SAAK,QAAQ;AAAA,MACX,MAAM,SAAS,UAAU,KAAK,QAAQ,WAAW;AAAA,MACjD,QAAQ,SAAS,UAAU,KAAK,QAAQ,aAAa;AAAA,MACrD,aAAa,SAAS,UAAU,KAAK,QAAQ,kBAAkB;AAAA,MAC/D,QAAQ,SAAS,UAAU,KAAK,QAAQ,aAAa;AAAA,MACrD,aAAa,SAAS,UAAU,KAAK,QAAQ,kBAAkB;AAAA,MAC/D,YAAY,SAAS,UAAU,KAAK,QAAQ,iBAAiB;AAAA,MAC7D,YAAY,SAAS,UAAU,KAAK,QAAQ,iBAAiB;AAAA,IAC/D;AAAA,EACF;AAAA,EAEA,SAAe;AACb,QAAI,CAAC,KAAK,SAAS,CAAC,KAAK,MAAO,QAAO;AACvC,QAAI,KAAK,SAAU,QAAO;AAC1B,SAAK,WAAW;AAEhB,UAAM,EAAE,OAAO,MAAM,IAAI;AAEzB,QAAI,cAAc;AAClB,QAAI,cAAc,cAAc,MAAM;AACtC,SAAK;AAAA,MACH;AAAA,MACA,KAAK,MAAM;AAAA,MACX,CAAC,EAAE,SAAS,IAAI,OAAO,OAAO,CAAC;AAAA,MAC/B;AAAA,MACA;AAAA,IACF;AAEA,kBAAc;AACd,kBAAc,cAAc,MAAM;AAClC,SAAK;AAAA,MACH;AAAA,MACA,KAAK,MAAM;AAAA,MACX,CAAC,EAAE,SAAS,IAAI,OAAO,QAAQ,CAAC;AAAA,MAChC;AAAA,MACA;AAAA,IACF;AAEA,kBAAc;AACd,kBAAc,cAAc,MAAM;AAClC,SAAK;AAAA,MACH;AAAA,MACA,KAAK,MAAM;AAAA,MACX,KAAK;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAEA,kBAAc;AACd,kBAAc,cAAc,MAAM;AAClC,SAAK;AAAA,MACH;AAAA,MACA,KAAK,MAAM;AAAA,MACX,KAAK;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAEA,kBAAc;AACd,kBAAc,cAAc,MAAM;AAClC,SAAK;AAAA,MACH;AAAA,MACA,KAAK,MAAM;AAAA,MACX,KAAK;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAEA,kBAAc;AACd,kBAAc,cAAc,MAAM;AAClC,SAAK;AAAA,MACH;AAAA,MACA,KAAK,MAAM;AAAA,MACX,KAAK;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAEA,kBAAc,MAAM,SAAS,MAAM;AACnC,kBAAc,MAAM;AACpB,SAAK;AAAA,MACH;AAAA,MACA,KAAK,MAAM;AAAA,MACX,KAAK;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,UAAgB;AACd,QAAI,KAAK,OAAO;AAEd,WAAK,MAAM,QAAQ,UAAU,kBAAkB,EAC5C,GAAG,aAAa,IAAI,EACpB,GAAG,gBAAgB,IAAI,EACvB,GAAG,gBAAgB,IAAI,EACvB,GAAG,WAAW,IAAI;AACrB,WAAK,MAAM,QAAQ,OAAO;AAC1B,WAAK,QAAQ;AACb,WAAK,QAAQ;AACb,WAAK,WAAW;AAAA,IAClB;AAAA,EACF;AAAA,EAEA,IAAI,WAAoB;AACtB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,UAAgB;AACd,SAAK,YAAY;AACjB,QAAI,KAAK,OAAO;AACd,WAAK,MAAM,QAAQ,QAAQ,eAAe,IAAI;AAAA,IAChD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,SAAe;AACb,SAAK,YAAY;AACjB,QAAI,KAAK,OAAO;AACd,WAAK,MAAM,QAAQ,QAAQ,eAAe,KAAK;AAAA,IACjD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,QAAwB;AAC9B,QAAI,CAAC,KAAK,SAAS,KAAK,UAAW;AAEnC,UAAM,UAAU,KAAK,eAAe,CAAC,MAAM,CAAC;AAC5C,QAAI,QAAQ,WAAW,EAAG;AAC1B,UAAM,QAAQ,QAAQ,CAAC;AAEvB,QAAI,CAAC,KAAK,cAAc,KAAK,GAAG;AAC9B,YAAM,IAAI,MAAM,kDAA6C,MAAM,OAAO,iBAAiB;AAAA,IAC7F;AAEA,UAAM,OAAO,KAAK,MAAM,MAAM,IAAI;AAClC,UAAM,MAAW,EAAE,SAAS,MAAM,SAAS,OAAO,QAAQ,KAAK;AAC/D,UAAM,SAAS,iBAAiB,GAAG;AAEnC,SAAK,MAAM,UAAU;AAAA,MACnB,IAAI,YAAyB,SAAS,EAAE,OAAO,CAAC;AAAA,IAClD;AAAA,EACF;AAAA,EAEA,UAAU,SAAqB,UAA4B,CAAC,GAAS;AACnE,QAAI,CAAC,KAAK,MAAO;AACjB,UAAM,YAAY,QAAQ,aAAa;AAEvC,eAAW,UAAU,KAAK,eAAe,OAAO,GAAG;AACjD,YAAM,OAAO,KAAK,MAAM,OAAO,IAAI;AACnC,YAAM,WAAW,gBAAgB,KAAK,IAAI,sBAAsB,OAAO,OAAO;AAC9E,WAAK,MAAM,QAAQ,UAAU,QAAQ,EAAE,QAAQ,WAAW,IAAI;AAAA,IAChE;AAAA,EACF;AAAA,EAEA,YAAY,SAAqB,UAA4B,CAAC,GAAS;AACrE,QAAI,CAAC,KAAK,MAAO;AACjB,UAAM,YAAY,QAAQ,aAAa;AAEvC,eAAW,UAAU,KAAK,eAAe,OAAO,GAAG;AACjD,YAAM,OAAO,KAAK,MAAM,OAAO,IAAI;AACnC,YAAM,WAAW,gBAAgB,KAAK,IAAI,sBAAsB,OAAO,OAAO;AAC9E,WAAK,MAAM,QAAQ,UAAU,QAAQ,EAAE,QAAQ,WAAW,KAAK;AAAA,IACjE;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,kBAAwB;AACxC,QAAI,CAAC,KAAK,MAAO;AACjB,SAAK,MAAM,QAAQ,UAAU,IAAI,SAAS,EAAE,EAAE,QAAQ,WAAW,KAAK;AAAA,EACxE;AAAA,EAEQ,cAAc,QAAsC;AAC1D,UAAM,SAAS,OAAO,SAAS,iBAAiB,OAAO,SAAS;AAChE,QAAI,QAAQ;AACV,aAAO,OAAO,YAAY;AAAA,IAC5B;AACA,WAAO,KAAK,SAAS,KAAK,CAAC,MAAM,EAAE,YAAY,OAAO,OAAO;AAAA,EAC/D;AAAA,EAEQ,eAAe,QAA2C;AAChE,WAAO,OAAO,QAAQ,CAAC,UAAiC;AACtD,UAAI,OAAO,UAAU,UAAU;AAC7B,eAAO,SAAS,OAAO,KAAK,GAAG,KAAK,OAAO,KAAK,QAAQ;AAAA,MAC1D;AACA,UAAI,OAAO,UAAU,UAAU;AAC7B,eAAO,SAAS,OAAO,KAAK,OAAO,KAAK,QAAQ;AAAA,MAClD;AACA,UAAI,CAAC,MAAM,MAAM;AACf,eAAO,SAAS,OAAO,MAAM,OAAO,GAAG,KAAK,OAAO,KAAK,QAAQ;AAAA,MAClE;AACA,aAAO,CAAC,KAA4B;AAAA,IACtC,CAAC;AAAA,EACH;AAAA,EAEQ,cAAc,KAAgB;AACpC,QAAI,CAAC,KAAK,SAAS,KAAK,UAAW;AACnC,UAAM,SAAS,iBAAiB,GAAG;AACnC,SAAK,MAAM,UAAU;AAAA,MACnB,IAAI,YAAyB,SAAS,EAAE,OAAO,CAAC;AAAA,IAClD;AAAA,EACF;AAAA,EAEQ,cAAc,KAAU,UAAyB;AACvD,QAAI,CAAC,KAAK,SAAS,KAAK,UAAW;AACnC,UAAM,cAAc,iBAAiB,GAAG;AACxC,UAAM,SAAsB,EAAE,GAAG,aAAa,SAAS;AACvD,SAAK,MAAM,UAAU;AAAA,MACnB,IAAI,YAAyB,SAAS,EAAE,OAAO,CAAC;AAAA,IAClD;AAAA,EACF;AAAA,EAEQ,WACN,OACA,MACA,UACA,aACA,aACM;AACN,UAAM,YAAY,eAAe,KAAK,IAAI;AAC1C,UAAM,YAAQ,qBAAsB,EACjC,YAAY,WAAW,EACvB,YAAY,WAAW;AAE1B,UAAM,OAAO,MAAM,IAChB,OAAO,GAAG,EACV,QAAQ,WAAW,IAAI,EACvB,UAAyC,KAAK,EAC9C,KAAK,MAAM,IAAI,kBAAkB,MAAM,QAAQ,CAAC,CAAC,EACjD,MAAM,EACN,OAAO,GAAG,EACV;AAAA,MACC;AAAA,MACA,CAAC,MACC,oCAAoC,EAAE,KAAK,OAAO,IAAI,SAAS,KAAK,EAAE,KAAK,OAAO,MAAM,EAAE,KAAK,KAAK;AAAA,IACxG,EACC,KAAK,QAAQ,QAAQ,EACrB,KAAK,YAAY,GAAG,EACpB;AAAA,MAAK;AAAA,MAAc,CAAC,MACnB,eAAe,EAAE,IAAI;AAAA,IACvB,EACC;AAAA,MACC;AAAA,MACA,CAAC,QAAsB,MAAwB;AAC7C,aAAK,cAAc,EAAE,IAAI;AAAA,MAC3B;AAAA,IACF,EACC;AAAA,MACC;AAAA,MACA,CAAC,QAAsB,MAAwB;AAC7C,wCAAO,OAAO,aAAwB,EAAE,QAAQ,cAAc,IAAI;AAClE,aAAK,cAAc,EAAE,MAAM,IAAI;AAAA,MACjC;AAAA,IACF,EACC;AAAA,MACC;AAAA,MACA,CAAC,QAAsB,MAAwB;AAC7C,wCAAO,OAAO,aAAwB,EAAE,QAAQ,cAAc,KAAK;AACnE,aAAK,cAAc,EAAE,MAAM,KAAK;AAAA,MAClC;AAAA,IACF,EACC;AAAA,MACC;AAAA,MACA,CAAC,QAAuB,MAAwB;AAC9C,YAAI,OAAO,QAAQ,WAAW,OAAO,QAAQ,KAAK;AAChD,iBAAO,eAAe;AACtB,eAAK,cAAc,EAAE,IAAI;AAAA,QAC3B;AAAA,MACF;AAAA,IACF;AAEF,SAAK,OAAO,MAAM,EAAE,KAAK,KAAK,KAAc;AAAA,EAC9C;AAAA,EAEQ,eACN,OACA,MACA,UACA,aACA,aACM;AACN,UAAM,cAAU,qBAAsB,EACnC,YAAY,WAAW,EACvB,YAAY,WAAW;AAE1B,UAAM,WAAW,MAAM,IACpB,OAAO,GAAG,EACV,QAAQ,oBAAoB,IAAI,EAChC,UAAyC,KAAK,EAC9C,KAAK,MAAM,IAAI,kBAAkB,MAAM,QAAQ,CAAC,CAAC,EACjD,MAAM,EACN,OAAO,GAAG,EACV;AAAA,MACC;AAAA,MACA,CAAC,MACC,oCAAoC,EAAE,KAAK,OAAO,sBAAsB,EAAE,KAAK,OAAO;AAAA,IAC1F,EACC,KAAK,QAAQ,QAAQ,EACrB,KAAK,YAAY,GAAG,EACpB;AAAA,MAAK;AAAA,MAAc,CAAC,MACnB,eAAe,EAAE,IAAI;AAAA,IACvB,EACC;AAAA,MACC;AAAA,MACA,CAAC,QAAsB,MAAwB;AAC7C,aAAK,cAAc,EAAE,IAAI;AAAA,MAC3B;AAAA,IACF,EACC;AAAA,MACC;AAAA,MACA,CAAC,QAAuB,MAAwB;AAC9C,YAAI,OAAO,QAAQ,WAAW,OAAO,QAAQ,KAAK;AAChD,iBAAO,eAAe;AACtB,eAAK,cAAc,EAAE,IAAI;AAAA,QAC3B;AAAA,MACF;AAAA,IACF;AAEF,aAAS,OAAO,MAAM,EAAE,KAAK,KAAK,OAAgB;AAElD,UAAM,oBAAoB,CAAC,YACzB,CAAC,MAAM,WAAW,MAAM,iBAAiB,QAAQ,YAAY,KAAK;AAEpE,UAAM,aAAa,CAAC,MAClB,QAAQ,SAAS,CAAC,EAAE,CAAC;AAEvB,UAAM,aAAa,CAAC,MAClB,QAAQ,SAAS,CAAC,EAAE,CAAC;AAEvB,aACG,OAAO,MAAM,EACb,QAAQ,yBAAyB,IAAI,EACrC,KAAK,KAAK,CAAC,MAAwB,WAAW,CAAC,CAAC,EAChD,KAAK,KAAK,CAAC,MAAwB,WAAW,CAAC,CAAC,EAChD,KAAK,MAAM,OAAO,EAClB;AAAA,MACC;AAAA,MACA,CAAC,MACC,UAAU,kBAAkB,EAAE,IAAI,CAAC,KAAK,WAAW,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC;AAAA,IAC3E,EACC,KAAK,eAAe,QAAQ,EAC5B,KAAK,CAAC,MAAwB,EAAE,KAAK,OAAO;AAAA,EACjD;AACF;","names":["segment"]}
package/dist/index.css ADDED
@@ -0,0 +1,91 @@
1
+ /* src/dartboard.css */
2
+ .c-Dartboard {
3
+ --dartboard-dark: #1a1a1a;
4
+ --dartboard-light: #f5f5dc;
5
+ --dartboard-scoring-dark: #e32636;
6
+ --dartboard-scoring-light: #228b22;
7
+ --dartboard-miss: #000;
8
+ --dartboard-miss-label: #fff;
9
+ --dartboard-stroke: silver;
10
+ --dartboard-stroke-width: 2px;
11
+ --dartboard-highlight-color: #ffd700;
12
+ --dartboard-good: #228b22;
13
+ --dartboard-bad: #e32636;
14
+ --dartboard-neutral: #4a6fa5;
15
+ stroke: var(--dartboard-stroke);
16
+ stroke-width: var(--dartboard-stroke-width);
17
+ touch-action: none;
18
+ }
19
+ .c-Dartboard svg {
20
+ width: 100%;
21
+ height: auto;
22
+ display: block;
23
+ }
24
+ .c-Dartboard-miss {
25
+ fill: var(--dartboard-miss);
26
+ }
27
+ .c-Dartboard-missLabel {
28
+ font-family: sans-serif;
29
+ fill: var(--dartboard-miss-label);
30
+ stroke-width: 0;
31
+ }
32
+ .c-Dartboard-bed.isDark {
33
+ fill: var(--dartboard-dark);
34
+ }
35
+ .c-Dartboard-bed.isLight {
36
+ fill: var(--dartboard-light);
37
+ }
38
+ .c-Dartboard-double .c-Dartboard-bed.isDark,
39
+ .c-Dartboard-triple .c-Dartboard-bed.isDark,
40
+ .c-Dartboard-doubleBull .c-Dartboard-bed.isDark,
41
+ .c-Dartboard-singleBull .c-Dartboard-bed.isDark {
42
+ fill: var(--dartboard-scoring-dark);
43
+ }
44
+ .c-Dartboard-double .c-Dartboard-bed.isLight,
45
+ .c-Dartboard-triple .c-Dartboard-bed.isLight,
46
+ .c-Dartboard-doubleBull .c-Dartboard-bed.isLight,
47
+ .c-Dartboard-singleBull .c-Dartboard-bed.isLight {
48
+ fill: var(--dartboard-scoring-light);
49
+ }
50
+ .c-Dartboard-bed.is-hovered,
51
+ .c-Dartboard-miss .c-Dartboard-bed:hover {
52
+ fill-opacity: 0.6;
53
+ cursor: pointer;
54
+ }
55
+ .c-Dartboard-bed.is-highlighted,
56
+ .c-Dartboard .c-Dartboard-bed.is-highlighted.isDark,
57
+ .c-Dartboard .c-Dartboard-bed.is-highlighted.isLight {
58
+ fill: var(--dartboard-highlight-color);
59
+ stroke: #fff;
60
+ stroke-width: 3px;
61
+ animation: dartboard-pulse 0.6s ease-in-out infinite alternate;
62
+ }
63
+ @keyframes dartboard-pulse {
64
+ from {
65
+ fill-opacity: 0.5;
66
+ }
67
+ to {
68
+ fill-opacity: 1;
69
+ }
70
+ }
71
+ .c-Dartboard .c-Dartboard-bed.is-good.isDark,
72
+ .c-Dartboard .c-Dartboard-bed.is-good.isLight {
73
+ fill: var(--dartboard-good);
74
+ }
75
+ .c-Dartboard .c-Dartboard-bed.is-bad.isDark,
76
+ .c-Dartboard .c-Dartboard-bed.is-bad.isLight {
77
+ fill: var(--dartboard-bad);
78
+ }
79
+ .c-Dartboard .c-Dartboard-bed.is-neutral.isDark,
80
+ .c-Dartboard .c-Dartboard-bed.is-neutral.isLight {
81
+ fill: var(--dartboard-neutral);
82
+ }
83
+ .c-Dartboard-bed:focus-visible {
84
+ outline: 2px solid var(--dartboard-highlight-color);
85
+ outline-offset: -2px;
86
+ }
87
+ .c-Dartboard.is-disabled {
88
+ pointer-events: none;
89
+ opacity: 0.5;
90
+ }
91
+ /*# sourceMappingURL=index.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/dartboard.css"],"sourcesContent":[".c-Dartboard {\n --dartboard-dark: #1a1a1a;\n --dartboard-light: #f5f5dc;\n --dartboard-scoring-dark: #e32636;\n --dartboard-scoring-light: #228b22;\n --dartboard-miss: #000;\n --dartboard-miss-label: #fff;\n --dartboard-stroke: silver;\n --dartboard-stroke-width: 2px;\n --dartboard-highlight-color: #ffd700;\n --dartboard-good: #228b22;\n --dartboard-bad: #e32636;\n --dartboard-neutral: #4a6fa5;\n\n stroke: var(--dartboard-stroke);\n stroke-width: var(--dartboard-stroke-width);\n touch-action: none;\n}\n\n.c-Dartboard svg {\n width: 100%;\n height: auto;\n display: block;\n}\n\n.c-Dartboard-miss {\n fill: var(--dartboard-miss);\n}\n\n.c-Dartboard-missLabel {\n font-family: sans-serif;\n fill: var(--dartboard-miss-label);\n stroke-width: 0;\n}\n\n.c-Dartboard-bed.isDark {\n fill: var(--dartboard-dark);\n}\n\n.c-Dartboard-bed.isLight {\n fill: var(--dartboard-light);\n}\n\n.c-Dartboard-double .c-Dartboard-bed.isDark,\n.c-Dartboard-triple .c-Dartboard-bed.isDark,\n.c-Dartboard-doubleBull .c-Dartboard-bed.isDark,\n.c-Dartboard-singleBull .c-Dartboard-bed.isDark {\n fill: var(--dartboard-scoring-dark);\n}\n\n.c-Dartboard-double .c-Dartboard-bed.isLight,\n.c-Dartboard-triple .c-Dartboard-bed.isLight,\n.c-Dartboard-doubleBull .c-Dartboard-bed.isLight,\n.c-Dartboard-singleBull .c-Dartboard-bed.isLight {\n fill: var(--dartboard-scoring-light);\n}\n\n.c-Dartboard-bed.is-hovered,\n.c-Dartboard-miss .c-Dartboard-bed:hover {\n fill-opacity: 0.6;\n cursor: pointer;\n}\n\n.c-Dartboard-bed.is-highlighted,\n.c-Dartboard .c-Dartboard-bed.is-highlighted.isDark,\n.c-Dartboard .c-Dartboard-bed.is-highlighted.isLight {\n fill: var(--dartboard-highlight-color);\n stroke: #fff;\n stroke-width: 3px;\n animation: dartboard-pulse 0.6s ease-in-out infinite alternate;\n}\n\n@keyframes dartboard-pulse {\n from {\n fill-opacity: 0.5;\n }\n to {\n fill-opacity: 1;\n }\n}\n\n.c-Dartboard .c-Dartboard-bed.is-good.isDark,\n.c-Dartboard .c-Dartboard-bed.is-good.isLight {\n fill: var(--dartboard-good);\n}\n\n.c-Dartboard .c-Dartboard-bed.is-bad.isDark,\n.c-Dartboard .c-Dartboard-bed.is-bad.isLight {\n fill: var(--dartboard-bad);\n}\n\n.c-Dartboard .c-Dartboard-bed.is-neutral.isDark,\n.c-Dartboard .c-Dartboard-bed.is-neutral.isLight {\n fill: var(--dartboard-neutral);\n}\n\n.c-Dartboard-bed:focus-visible {\n outline: 2px solid var(--dartboard-highlight-color);\n outline-offset: -2px;\n}\n\n.c-Dartboard.is-disabled {\n pointer-events: none;\n opacity: 0.5;\n}\n"],"mappings":";AAAA,CAAC;AACC,oBAAkB;AAClB,qBAAmB;AACnB,4BAA0B;AAC1B,6BAA2B;AAC3B,oBAAkB;AAClB,0BAAwB;AACxB,sBAAoB;AACpB,4BAA0B;AAC1B,+BAA6B;AAC7B,oBAAkB;AAClB,mBAAiB;AACjB,uBAAqB;AAErB,UAAQ,IAAI;AACZ,gBAAc,IAAI;AAClB,gBAAc;AAChB;AAEA,CAnBC,YAmBY;AACX,SAAO;AACP,UAAQ;AACR,WAAS;AACX;AAEA,CAAC;AACC,QAAM,IAAI;AACZ;AAEA,CAAC;AACC,eAAa;AACb,QAAM,IAAI;AACV,gBAAc;AAChB;AAEA,CAAC,eAAe,CAAC;AACf,QAAM,IAAI;AACZ;AAEA,CAJC,eAIe,CAAC;AACf,QAAM,IAAI;AACZ;AAEA,CAAC,mBAAmB,CARnB,eAQmC,CARnB;AASjB,CAAC,mBAAmB,CATnB,eASmC,CATnB;AAUjB,CAAC,uBAAuB,CAVvB,eAUuC,CAVvB;AAWjB,CAAC,uBAAuB,CAXvB,eAWuC,CAXvB;AAYf,QAAM,IAAI;AACZ;AAEA,CAPC,mBAOmB,CAfnB,eAemC,CAXnB;AAYjB,CAPC,mBAOmB,CAhBnB,eAgBmC,CAZnB;AAajB,CAPC,uBAOuB,CAjBvB,eAiBuC,CAbvB;AAcjB,CAPC,uBAOuB,CAlBvB,eAkBuC,CAdvB;AAef,QAAM,IAAI;AACZ;AAEA,CAtBC,eAsBe,CAAC;AACjB,CAjCC,iBAiCiB,CAvBjB,eAuBiC;AAChC,gBAAc;AACd,UAAQ;AACV;AAEA,CA5BC,eA4Be,CAAC;AACjB,CAhEC,YAgEY,CA7BZ,eA6B4B,CADZ,cAC2B,CA7B3B;AA8BjB,CAjEC,YAiEY,CA9BZ,eA8B4B,CAFZ,cAE2B,CA1B3B;AA2Bf,QAAM,IAAI;AACV,UAAQ;AACR,gBAAc;AACd,aAAW,gBAAgB,KAAK,YAAY,SAAS;AACvD;AAEA,WAHa;AAIX;AACE,kBAAc;AAChB;AACA;AACE,kBAAc;AAChB;AACF;AAEA,CAjFC,YAiFY,CA9CZ,eA8C4B,CAAC,OAAO,CA9CpB;AA+CjB,CAlFC,YAkFY,CA/CZ,eA+C4B,CADC,OACO,CA3CpB;AA4Cf,QAAM,IAAI;AACZ;AAEA,CAtFC,YAsFY,CAnDZ,eAmD4B,CAAC,MAAM,CAnDnB;AAoDjB,CAvFC,YAuFY,CApDZ,eAoD4B,CADC,MACM,CAhDnB;AAiDf,QAAM,IAAI;AACZ;AAEA,CA3FC,YA2FY,CAxDZ,eAwD4B,CAAC,UAAU,CAxDvB;AAyDjB,CA5FC,YA4FY,CAzDZ,eAyD4B,CADC,UACU,CArDvB;AAsDf,QAAM,IAAI;AACZ;AAEA,CA7DC,eA6De;AACd,WAAS,IAAI,MAAM,IAAI;AACvB,kBAAgB;AAClB;AAEA,CArGC,WAqGW,CAAC;AACX,kBAAgB;AAChB,WAAS;AACX;","names":[]}