chessboard-kit 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Danyal Khattak
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,254 @@
1
+ # chessboard-kit
2
+
3
+ > Modern, strongly typed chessboard UI for the web. DOM-based rendering, SVG boards and pieces, smooth move animation, keyboard access, and a small publishable footprint.
4
+
5
+ <!-- Badges can be wired to your final GitHub repo URL when you publish. -->
6
+
7
+ ## Overview
8
+
9
+ `chessboard-kit` is a production-ready TypeScript chessboard library inspired by chessboard.js, but designed with a cleaner API and modern architecture.
10
+
11
+ It uses regular DOM elements instead of canvas, keeps the rendering tree-shakeable, and ships with built-in board themes plus a default SVG chess piece set sourced from the assets in this repository.
12
+
13
+ ## Features
14
+
15
+ - Responsive board sizing
16
+ - Drag-and-drop moves
17
+ - Click-to-move interaction
18
+ - Touch support
19
+ - Board flipping
20
+ - Coordinates
21
+ - FEN load and save
22
+ - PGN loading
23
+ - Board resize handling
24
+ - Move animation
25
+ - Last-move highlighting
26
+ - Selected-square styling
27
+ - Legal-move highlighting
28
+ - Custom square styling hooks
29
+ - Promotion callback
30
+ - Event system
31
+ - `destroy()`, `setPosition()`, `move()`, `clear()`, `reset()`
32
+ - Keyboard navigation and ARIA labels
33
+
34
+ ## Install
35
+
36
+ ```bash
37
+ npm install chessboard-kit
38
+ ```
39
+
40
+ ## Import
41
+
42
+ ```ts
43
+ import { Chessboard } from 'chessboard-kit';
44
+ import 'chessboard-kit/style.css';
45
+ ```
46
+
47
+ ## Quick Start
48
+
49
+ ```ts
50
+ import { Chessboard } from 'chessboard-kit';
51
+ import 'chessboard-kit/style.css';
52
+
53
+ const board = new Chessboard('#board', {
54
+ theme: 'classicWood',
55
+ pieces: 'default',
56
+ orientation: 'white',
57
+ draggable: true,
58
+ coordinates: true,
59
+ animation: true,
60
+ fen: 'start',
61
+ });
62
+
63
+ board.move('e2', 'e4');
64
+ board.flip();
65
+ board.loadFEN('start');
66
+ console.log(board.getFEN());
67
+ board.destroy();
68
+ ```
69
+
70
+ ## API at a Glance
71
+
72
+ ```ts
73
+ const board = new Chessboard('#board', options);
74
+
75
+ board.move('e2', 'e4');
76
+ board.flip();
77
+ board.setTheme('green');
78
+ board.setPieceSet('default');
79
+ board.loadFEN(fen);
80
+ board.loadPGN(pgn);
81
+ board.setPosition('start');
82
+ board.clear();
83
+ board.reset();
84
+ board.destroy();
85
+ ```
86
+
87
+ ## Options
88
+
89
+ | Option | Type | Description |
90
+ | ----------------- | ---------------- | --------------------------------------- |
91
+ | `theme` | `string` | Built-in or custom board theme |
92
+ | `pieces` | `string` | Built-in or custom piece set |
93
+ | `orientation` | `white \| black` | Initial board orientation |
94
+ | `draggable` | `boolean` | Enable drag-and-drop moves |
95
+ | `coordinates` | `boolean` | Show board coordinates |
96
+ | `animation` | `boolean` | Enable move animation |
97
+ | `fen` | `string` | Initial FEN, or `start` |
98
+ | `position` | `string` | Alias for initial FEN |
99
+ | `showLegalMoves` | `boolean` | Highlight legal targets after selection |
100
+ | `squareClassName` | function | Add custom square classes |
101
+ | `squareStyle` | function | Add custom square styles |
102
+
103
+ ## Events
104
+
105
+ The library exposes both callback props and an event emitter style API.
106
+
107
+ Supported events:
108
+
109
+ - `onMove`
110
+ - `onDrop`
111
+ - `onDragStart`
112
+ - `onDragEnd`
113
+ - `onSquareClick`
114
+ - `onPositionChange`
115
+ - `onBoardFlip`
116
+ - `onPromotion`
117
+
118
+ Example:
119
+
120
+ ```ts
121
+ const board = new Chessboard('#board', {
122
+ onMove: (event) => {
123
+ console.log(event.from, event.to, event.san);
124
+ },
125
+ onPromotion: () => 'q',
126
+ });
127
+
128
+ board.on('positionchange', (event) => {
129
+ console.log(event.fen);
130
+ });
131
+ ```
132
+
133
+ ## Themes
134
+
135
+ The package automatically registers these built-in board themes:
136
+
137
+ - `classicWood`
138
+ - `blue`
139
+ - `green`
140
+ - `dark`
141
+ - `tournamentMarble`
142
+
143
+ Switch themes at runtime:
144
+
145
+ ```ts
146
+ board.setTheme('green');
147
+ ```
148
+
149
+ Register a custom theme:
150
+
151
+ ```ts
152
+ import { registerBoardTheme } from 'chessboard-kit';
153
+
154
+ registerBoardTheme(
155
+ 'midnight',
156
+ 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 8"></svg>',
157
+ );
158
+ ```
159
+
160
+ See [docs/theme-guide.md](docs/theme-guide.md) for the full guide.
161
+
162
+ ## Pieces
163
+
164
+ The supplied SVG piece set is registered as the default piece set.
165
+
166
+ ```ts
167
+ board.setPieceSet('default');
168
+ ```
169
+
170
+ Register a custom piece set:
171
+
172
+ ```ts
173
+ import { registerPieceSet } from 'chessboard-kit';
174
+
175
+ registerPieceSet('minimal', {
176
+ white_king: '/pieces/white-king.svg',
177
+ white_queen: '/pieces/white-queen.svg',
178
+ white_rook: '/pieces/white-rook.svg',
179
+ white_bishop: '/pieces/white-bishop.svg',
180
+ white_knight: '/pieces/white-knight.svg',
181
+ white_pawn: '/pieces/white-pawn.svg',
182
+ black_king: '/pieces/black-king.svg',
183
+ black_queen: '/pieces/black-queen.svg',
184
+ black_rook: '/pieces/black-rook.svg',
185
+ black_bishop: '/pieces/black-bishop.svg',
186
+ black_knight: '/pieces/black-knight.svg',
187
+ black_pawn: '/pieces/black-pawn.svg',
188
+ });
189
+ ```
190
+
191
+ See [docs/custom-piece-guide.md](docs/custom-piece-guide.md) for a full example.
192
+
193
+ ## Public Methods
194
+
195
+ | Method | Description |
196
+ | ----------------------------- | ------------------------------------ |
197
+ | `move(from, to, promotion?)` | Make a move programmatically |
198
+ | `flip()` | Flip the board orientation |
199
+ | `setOrientation(orientation)` | Set the board orientation explicitly |
200
+ | `setTheme(name)` | Change the active board theme |
201
+ | `setPieceSet(name)` | Change the active piece set |
202
+ | `loadFEN(fen)` | Load a FEN position |
203
+ | `getFEN()` | Read the current FEN |
204
+ | `loadPGN(pgn)` | Load a PGN string |
205
+ | `setPosition(position)` | Set the board position |
206
+ | `clear()` | Remove all pieces from the board |
207
+ | `reset()` | Restore the starting position |
208
+ | `destroy()` | Tear down the board and listeners |
209
+ | `on(event, handler)` | Subscribe to events |
210
+ | `off(event, handler)` | Remove an event listener |
211
+
212
+ ## Accessibility
213
+
214
+ `chessboard-kit` includes keyboard navigation, focus states, and ARIA labels so the board can be used without drag-and-drop alone.
215
+
216
+ ## Examples
217
+
218
+ - [Vanilla JavaScript](examples/vanilla/index.html)
219
+ - [TypeScript](examples/typescript/main.ts)
220
+ - [React](examples/react/App.tsx)
221
+ - [Vue](examples/vue/App.vue)
222
+ - [Angular](examples/angular/chessboard.component.ts)
223
+ - [Svelte](examples/svelte/App.svelte)
224
+
225
+ ## Documentation
226
+
227
+ - [API documentation](docs/api.md)
228
+ - [Theme guide](docs/theme-guide.md)
229
+ - [Custom piece guide](docs/custom-piece-guide.md)
230
+ - [Example screenshots](docs/screenshots.md)
231
+ - [npm publishing guide](docs/npm-publishing-guide.md)
232
+
233
+ ## Development
234
+
235
+ ```bash
236
+ npm install
237
+ npm run typecheck
238
+ npm run test
239
+ npm run build
240
+ npm run lint
241
+ ```
242
+
243
+ ## Package Output
244
+
245
+ The package is configured for:
246
+
247
+ - ESM and CommonJS builds
248
+ - Type declaration output
249
+ - CSS export via `chessboard-kit/style.css`
250
+ - Tree-shakeable public entrypoints
251
+
252
+ ## License
253
+
254
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";var S=Object.defineProperty;var E=(o,e,t)=>e in o?S(o,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[e]=t;var h=(o,e,t)=>E(o,typeof e!="symbol"?e+"":e,t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const y=require("chess.js");var n=typeof document<"u"?document.currentScript:null;class R{constructor(){h(this,"listeners",new Map)}on(e,t){const i=this.listeners.get(e)??new Set;return i.add(t),this.listeners.set(e,i),()=>this.off(e,t)}off(e,t){var i;(i=this.listeners.get(e))==null||i.delete(t)}emit(e,t){var i;(i=this.listeners.get(e))==null||i.forEach(r=>{r(t)})}clear(){this.listeners.clear()}}const g={classicWood:new URL("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='480'%20height='480'%20viewBox='0%200%20480%20480'%3e%3crect%20width='480'%20height='480'%20fill='%23f0d9b5'/%3e%3c!--%20Dark%20squares%20--%3e%3cg%20fill='%23b58863'%3e%3crect%20x='60'%20y='0'%20width='60'%20height='60'/%3e%3crect%20x='180'%20y='0'%20width='60'%20height='60'/%3e%3crect%20x='300'%20y='0'%20width='60'%20height='60'/%3e%3crect%20x='420'%20y='0'%20width='60'%20height='60'/%3e%3crect%20x='0'%20y='60'%20width='60'%20height='60'/%3e%3crect%20x='120'%20y='60'%20width='60'%20height='60'/%3e%3crect%20x='240'%20y='60'%20width='60'%20height='60'/%3e%3crect%20x='360'%20y='60'%20width='60'%20height='60'/%3e%3crect%20x='60'%20y='120'%20width='60'%20height='60'/%3e%3crect%20x='180'%20y='120'%20width='60'%20height='60'/%3e%3crect%20x='300'%20y='120'%20width='60'%20height='60'/%3e%3crect%20x='420'%20y='120'%20width='60'%20height='60'/%3e%3crect%20x='0'%20y='180'%20width='60'%20height='60'/%3e%3crect%20x='120'%20y='180'%20width='60'%20height='60'/%3e%3crect%20x='240'%20y='180'%20width='60'%20height='60'/%3e%3crect%20x='360'%20y='180'%20width='60'%20height='60'/%3e%3crect%20x='60'%20y='240'%20width='60'%20height='60'/%3e%3crect%20x='180'%20y='240'%20width='60'%20height='60'/%3e%3crect%20x='300'%20y='240'%20width='60'%20height='60'/%3e%3crect%20x='420'%20y='240'%20width='60'%20height='60'/%3e%3crect%20x='0'%20y='300'%20width='60'%20height='60'/%3e%3crect%20x='120'%20y='300'%20width='60'%20height='60'/%3e%3crect%20x='240'%20y='300'%20width='60'%20height='60'/%3e%3crect%20x='360'%20y='300'%20width='60'%20height='60'/%3e%3crect%20x='60'%20y='360'%20width='60'%20height='60'/%3e%3crect%20x='180'%20y='360'%20width='60'%20height='60'/%3e%3crect%20x='300'%20y='360'%20width='60'%20height='60'/%3e%3crect%20x='420'%20y='360'%20width='60'%20height='60'/%3e%3crect%20x='0'%20y='420'%20width='60'%20height='60'/%3e%3crect%20x='120'%20y='420'%20width='60'%20height='60'/%3e%3crect%20x='240'%20y='420'%20width='60'%20height='60'/%3e%3crect%20x='360'%20y='420'%20width='60'%20height='60'/%3e%3c/g%3e%3c/svg%3e",typeof document>"u"?require("url").pathToFileURL(__filename).href:n&&n.tagName.toUpperCase()==="SCRIPT"&&n.src||new URL("index.cjs",document.baseURI).href).href,blue:new URL("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='480'%20height='480'%3e%3cdefs%3e%3cpattern%20id='board'%20width='120'%20height='120'%20patternUnits='userSpaceOnUse'%3e%3crect%20width='120'%20height='120'%20fill='%23dee3e6'/%3e%3crect%20width='60'%20height='60'%20fill='%234a6fa5'/%3e%3crect%20x='60'%20y='60'%20width='60'%20height='60'%20fill='%234a6fa5'/%3e%3c/pattern%3e%3c/defs%3e%3crect%20width='480'%20height='480'%20fill='url(%23board)'/%3e%3c/svg%3e",typeof document>"u"?require("url").pathToFileURL(__filename).href:n&&n.tagName.toUpperCase()==="SCRIPT"&&n.src||new URL("index.cjs",document.baseURI).href).href,green:new URL("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='480'%20height='480'%3e%3cdefs%3e%3cpattern%20id='board'%20width='120'%20height='120'%20patternUnits='userSpaceOnUse'%3e%3crect%20width='120'%20height='120'%20fill='%23eeeed2'/%3e%3crect%20width='60'%20height='60'%20fill='%23769656'/%3e%3crect%20x='60'%20y='60'%20width='60'%20height='60'%20fill='%23769656'/%3e%3c/pattern%3e%3c/defs%3e%3crect%20width='480'%20height='480'%20fill='url(%23board)'/%3e%3c/svg%3e",typeof document>"u"?require("url").pathToFileURL(__filename).href:n&&n.tagName.toUpperCase()==="SCRIPT"&&n.src||new URL("index.cjs",document.baseURI).href).href,dark:new URL("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='480'%20height='480'%3e%3cdefs%3e%3cpattern%20id='board'%20width='120'%20height='120'%20patternUnits='userSpaceOnUse'%3e%3crect%20width='120'%20height='120'%20fill='%233c3c3c'/%3e%3crect%20width='60'%20height='60'%20fill='%231e1e1e'/%3e%3crect%20x='60'%20y='60'%20width='60'%20height='60'%20fill='%231e1e1e'/%3e%3c/pattern%3e%3c/defs%3e%3crect%20width='480'%20height='480'%20fill='url(%23board)'/%3e%3c/svg%3e",typeof document>"u"?require("url").pathToFileURL(__filename).href:n&&n.tagName.toUpperCase()==="SCRIPT"&&n.src||new URL("index.cjs",document.baseURI).href).href,tournamentMarble:new URL("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='480'%20height='480'%3e%3cdefs%3e%3cpattern%20id='board'%20width='120'%20height='120'%20patternUnits='userSpaceOnUse'%3e%3crect%20width='120'%20height='120'%20fill='%23f8f8f8'/%3e%3crect%20width='60'%20height='60'%20fill='%238c8c8c'/%3e%3crect%20x='60'%20y='60'%20width='60'%20height='60'%20fill='%238c8c8c'/%3e%3c/pattern%3e%3cfilter%20id='grain'%3e%3cfeTurbulence%20type='fractalNoise'%20baseFrequency='0.8'%20numOctaves='2'/%3e%3cfeColorMatrix%20values='%201%200%200%200%200%200%201%200%200%200%200%200%201%200%200%200%200%200%20.1%200'/%3e%3c/filter%3e%3c/defs%3e%3crect%20width='480'%20height='480'%20fill='url(%23board)'/%3e%3crect%20width='480'%20height='480'%20filter='url(%23grain)'%20opacity='.25'/%3e%3c/svg%3e",typeof document>"u"?require("url").pathToFileURL(__filename).href:n&&n.tagName.toUpperCase()==="SCRIPT"&&n.src||new URL("index.cjs",document.baseURI).href).href},d={white_king:new URL("data:image/svg+xml,%3csvg%20width='90'%20height='90'%20viewBox='0%200%2090%2090'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M45%2023.26V12'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'/%3e%3cpath%20d='M40%2016H50'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'/%3e%3cpath%20d='M45%2050C45%2050%2054%2035%2051%2029C51%2029%2049%2024%2045%2024C41%2024%2039%2029%2039%2029C36%2035%2045%2050%2045%2050Z'%20fill='white'%20stroke='black'%20stroke-width='3'/%3e%3cpath%20d='M23%2074C34%2081%2054%2081%2065%2074V60C65%2060%2083%2051%2077%2039C69%2026%2050%2032%2045%2047C39%2032%2019%2026%2013%2039C7.00001%2051%2023%2059%2023%2060V74Z'%20fill='white'/%3e%3cpath%20d='M45%2047C50%2032%2069%2026%2077%2039C83%2051%2065%2060%2065%2060V74C54%2081%2034%2081%2023%2074V60C23%2059%207.00001%2051%2013%2039C19%2026%2039%2032%2045%2047ZM45%2047V54'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M23%2060C34%2054%2054%2054%2065%2060'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M23%2067C34%2061%2054%2061%2065%2067'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M23%2074C34%2068%2054%2068%2065%2074'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e",typeof document>"u"?require("url").pathToFileURL(__filename).href:n&&n.tagName.toUpperCase()==="SCRIPT"&&n.src||new URL("index.cjs",document.baseURI).href).href,white_queen:new URL("data:image/svg+xml,%3csvg%20width='90'%20height='90'%20viewBox='0%200%2090%2090'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M12%2029.5C15.0376%2029.5%2017.5%2027.0376%2017.5%2024C17.5%2020.9624%2015.0376%2018.5%2012%2018.5C8.96243%2018.5%206.5%2020.9624%206.5%2024C6.5%2027.0376%208.96243%2029.5%2012%2029.5Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M28%2023.5C31.0376%2023.5%2033.5%2021.0376%2033.5%2018C33.5%2014.9624%2031.0376%2012.5%2028%2012.5C24.9624%2012.5%2022.5%2014.9624%2022.5%2018C22.5%2021.0376%2024.9624%2023.5%2028%2023.5Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M45%2021.5C48.0376%2021.5%2050.5%2019.0376%2050.5%2016C50.5%2012.9624%2048.0376%2010.5%2045%2010.5C41.9624%2010.5%2039.5%2012.9624%2039.5%2016C39.5%2019.0376%2041.9624%2021.5%2045%2021.5Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M62%2023.5C65.0376%2023.5%2067.5%2021.0376%2067.5%2018C67.5%2014.9624%2065.0376%2012.5%2062%2012.5C58.9624%2012.5%2056.5%2014.9624%2056.5%2018C56.5%2021.0376%2058.9624%2023.5%2062%2023.5Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M78%2029.5C81.0376%2029.5%2083.5%2027.0376%2083.5%2024C83.5%2020.9624%2081.0376%2018.5%2078%2018.5C74.9624%2018.5%2072.5%2020.9624%2072.5%2024C72.5%2027.0376%2074.9624%2029.5%2078%2029.5Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M18%2052C35%2049%2060%2049%2072%2052L77%2027L62%2050L61.4%2021.8L51%2049L45%2020L39%2049L28.6%2021.8L28%2050L13%2027L18%2052Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M18%2052C18%2056%2021%2056%2023%2060C25%2063%2025%2062%2024%2067C21%2069%2021%2072%2021%2072C18%2075%2022%2077%2022%2077C35%2079%2055%2079%2068%2077C68%2077%2071%2075%2068%2072C68%2072%2069%2069%2066%2067C65%2062%2065%2063%2067%2060C69%2056%2072%2056%2072%2052C55%2049%2035%2049%2018%2052Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M23%2060C30%2058%2060%2058%2067%2060'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M24%2067C30%2065%2060%2065%2066%2067'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e",typeof document>"u"?require("url").pathToFileURL(__filename).href:n&&n.tagName.toUpperCase()==="SCRIPT"&&n.src||new URL("index.cjs",document.baseURI).href).href,white_rook:new URL("data:image/svg+xml,%3csvg%20width='90'%20height='90'%20viewBox='0%200%2090%2090'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M18%2078H72V72H18V78Z'%20fill='white'%20stroke='black'%20stroke-width='3'/%3e%3cpath%20d='M25%2064L28%2059H62L65%2064H25Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M24%2072V64H66V72H24Z'%20fill='white'%20stroke='black'%20stroke-width='3'/%3e%3cpath%20d='M28%2059V33H62V59H28Z'%20fill='white'%20stroke='black'%20stroke-width='3'/%3e%3cpath%20d='M28%2033L22%2028H68L62%2033H28Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M22%2028V18H30V22H40V18H50V22H60V18H68V28H22Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M72%2072H18'%20stroke='white'%20stroke-width='2'%20stroke-linecap='round'/%3e%3cpath%20d='M25%2064H65'%20stroke='white'%20stroke-width='2'%20stroke-linecap='round'/%3e%3cpath%20d='M28%2059H62'%20stroke='white'%20stroke-width='2'%20stroke-linecap='round'/%3e%3cpath%20d='M28%2033H62'%20stroke='white'%20stroke-width='2'%20stroke-linecap='round'/%3e%3cpath%20d='M22%2028H68'%20stroke='white'%20stroke-width='2'%20stroke-linecap='round'/%3e%3c/svg%3e",typeof document>"u"?require("url").pathToFileURL(__filename).href:n&&n.tagName.toUpperCase()==="SCRIPT"&&n.src||new URL("index.cjs",document.baseURI).href).href,white_bishop:new URL("data:image/svg+xml,%3csvg%20width='90'%20height='90'%20viewBox='0%200%2090%2090'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M18%2072C24.78%2070.06%2038.22%2072.86%2045%2068C51.78%2072.86%2065.22%2070.06%2072%2072C72%2072%2075.3%2073.08%2078%2076C76.64%2077.94%2074.7%2077.98%2072%2077C65.22%2075.06%2051.78%2077.92%2045%2075C38.22%2077.92%2024.78%2075.06%2018%2077C15.292%2077.98%2013.354%2077.94%2012%2076C14.708%2072.12%2018%2072%2018%2072Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M30%2064C35%2069%2055%2069%2060%2064C61%2061%2060%2060%2060%2060C60%2055%2055%2052%2055%2052C66%2049%2067%2029%2045%2021C23%2029%2024%2049%2035%2052C35%2052%2030%2055%2030%2060C30%2060%2029%2061%2030%2064Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M50%2016C50%2017.3261%2049.4732%2018.5979%2048.5355%2019.5355C47.5979%2020.4732%2046.3261%2021%2045%2021C43.6739%2021%2042.4021%2020.4732%2041.4645%2019.5355C40.5268%2018.5979%2040%2017.3261%2040%2016C40%2014.6739%2040.5268%2013.4021%2041.4645%2012.4645C42.4021%2011.5268%2043.6739%2011%2045%2011C46.3261%2011%2047.5979%2011.5268%2048.5355%2012.4645C49.4732%2013.4021%2050%2014.6739%2050%2016Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M35%2052H55M30%2060H60'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M45%2031V41M40%2036H50'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'/%3e%3c/svg%3e",typeof document>"u"?require("url").pathToFileURL(__filename).href:n&&n.tagName.toUpperCase()==="SCRIPT"&&n.src||new URL("index.cjs",document.baseURI).href).href,white_knight:new URL("data:image/svg+xml,%3csvg%20width='90'%20height='90'%20viewBox='0%200%2090%2090'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M44%2020C65%2022%2077%2036%2076%2078H30C30%2060%2050%2065%2046%2036'%20fill='white'/%3e%3cpath%20d='M44%2020C65%2022%2077%2036%2076%2078H30C30%2060%2050%2065%2046%2036'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M48%2036C48.76%2041.82%2036.9%2050.74%2032%2054C26%2058%2026.36%2062.68%2022%2062C19.916%2060.12%2024.82%2055.92%2022%2056C20%2056%2022.38%2058.46%2020%2060C18%2060%2011.994%2062%2012%2052C12%2048%2024%2028%2024%2028C24%2028%2027.78%2024.2%2028%2021C26.54%2019.012%2027%2017%2027%2015C29%2013%2033%2020%2033%2020H37C37%2020%2038.56%2016.016%2042%2014C44%2014%2044%2020%2044%2020'%20fill='white'/%3e%3cpath%20d='M48%2036C48.76%2041.82%2036.9%2050.74%2032%2054C26%2058%2026.36%2062.68%2022%2062C19.916%2060.12%2024.82%2055.92%2022%2056C20%2056%2022.38%2058.46%2020%2060C18%2060%2011.994%2062%2012%2052C12%2048%2024%2028%2024%2028C24%2028%2027.78%2024.2%2028%2021C26.54%2019.012%2027%2017%2027%2015C29%2013%2033%2020%2033%2020H37C37%2020%2038.56%2016.016%2042%2014C44%2014%2044%2020%2044%2020'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M19%2052C19.5523%2052%2020%2051.5523%2020%2051C20%2050.4477%2019.5523%2050%2019%2050C18.4477%2050%2018%2050.4477%2018%2051C18%2051.5523%2018.4477%2052%2019%2052Z'%20fill='black'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M28.866%2031.5C28.4682%2032.189%2027.9954%2032.7972%2027.5517%2033.1907C27.108%2033.5841%2026.7297%2033.7307%2026.5%2033.5981C26.2703%2033.4655%2026.2081%2033.0646%2026.327%2032.4836C26.4459%2031.9026%2026.7361%2031.189%2027.134%2030.5C27.5318%2029.8109%2028.0046%2029.2028%2028.4483%2028.8093C28.892%2028.4159%2029.2703%2028.2693%2029.5%2028.4019C29.7297%2028.5345%2029.7919%2028.9354%2029.673%2029.5164C29.5541%2030.0974%2029.2638%2030.8109%2028.866%2031.5Z'%20fill='black'%20stroke='black'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M49.1%2020.8L48.2%2023.7L49.2%2024C55.5%2026%2060.5%2028.98%2065%2037.5C69.5%2046.02%2071.5%2058.12%2070.5%2078L70.4%2079H74.9L75%2078C76%2057.88%2073.24%2044.3%2068.5%2035.32C63.76%2026.34%2056.92%2022.04%2050.12%2021L49.1%2020.8Z'%20fill='black'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e",typeof document>"u"?require("url").pathToFileURL(__filename).href:n&&n.tagName.toUpperCase()==="SCRIPT"&&n.src||new URL("index.cjs",document.baseURI).href).href,white_pawn:new URL("data:image/svg+xml,%3csvg%20width='90'%20height='90'%20viewBox='0%200%2090%2090'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M44%2018C39.58%2018%2036%2021.58%2036%2026C36%2028.84%2037.52%2031.32%2039.82%2032.76C34.98%2034.26%2031.42%2038.72%2031.34%2044H58.66C58.58%2038.72%2055.02%2034.26%2050.18%2032.76C52.48%2031.32%2054%2028.84%2054%2026C54%2021.58%2050.42%2018%2046%2018H44Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M23%2074H67V68H23V74Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M24%2072H66L64%2054L58%2050H32L26%2054L24%2072Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3c/svg%3e",typeof document>"u"?require("url").pathToFileURL(__filename).href:n&&n.tagName.toUpperCase()==="SCRIPT"&&n.src||new URL("index.cjs",document.baseURI).href).href,black_king:new URL("data:image/svg+xml,%3csvg%20width='90'%20height='90'%20viewBox='0%200%2090%2090'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M45%2023.26V12'%20stroke='white'%20stroke-width='3'%20stroke-linecap='round'/%3e%3cpath%20d='M40%2016H50'%20stroke='white'%20stroke-width='3'%20stroke-linecap='round'/%3e%3cpath%20d='M45%2050C45%2050%2054%2035%2051%2029C51%2029%2049%2024%2045%2024C41%2024%2039%2029%2039%2029C36%2035%2045%2050%2045%2050Z'%20fill='%23202020'%20stroke='%23202020'%20stroke-width='3'/%3e%3cpath%20d='M23%2074C34%2081%2054%2081%2065%2074V60C65%2060%2083%2051%2077%2039C69%2026%2050%2032%2045%2047C39%2032%2019%2026%2013%2039C7.00001%2051%2023%2059%2023%2060V74Z'%20fill='%23202020'/%3e%3cpath%20d='M45%2047C50%2032%2069%2026%2077%2039C83%2051%2065%2060%2065%2060V74C54%2081%2034%2081%2023%2074V60C23%2059%207.00001%2051%2013%2039C19%2026%2039%2032%2045%2047ZM45%2047V54'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M23%2060C34%2054%2054%2054%2065%2060'%20stroke='white'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M23%2067C34%2061%2054%2061%2065%2067'%20stroke='white'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M23%2074C34%2068%2054%2068%2065%2074'%20stroke='white'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e",typeof document>"u"?require("url").pathToFileURL(__filename).href:n&&n.tagName.toUpperCase()==="SCRIPT"&&n.src||new URL("index.cjs",document.baseURI).href).href,black_queen:new URL("data:image/svg+xml,%3csvg%20width='90'%20height='90'%20viewBox='0%200%2090%2090'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M12%2029.5C15.0376%2029.5%2017.5%2027.0376%2017.5%2024C17.5%2020.9624%2015.0376%2018.5%2012%2018.5C8.96243%2018.5%206.5%2020.9624%206.5%2024C6.5%2027.0376%208.96243%2029.5%2012%2029.5Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M28%2023.5C31.0376%2023.5%2033.5%2021.0376%2033.5%2018C33.5%2014.9624%2031.0376%2012.5%2028%2012.5C24.9624%2012.5%2022.5%2014.9624%2022.5%2018C22.5%2021.0376%2024.9624%2023.5%2028%2023.5Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M45%2021.5C48.0376%2021.5%2050.5%2019.0376%2050.5%2016C50.5%2012.9624%2048.0376%2010.5%2045%2010.5C41.9624%2010.5%2039.5%2012.9624%2039.5%2016C39.5%2019.0376%2041.9624%2021.5%2045%2021.5Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M62%2023.5C65.0376%2023.5%2067.5%2021.0376%2067.5%2018C67.5%2014.9624%2065.0376%2012.5%2062%2012.5C58.9624%2012.5%2056.5%2014.9624%2056.5%2018C56.5%2021.0376%2058.9624%2023.5%2062%2023.5Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M78%2029.5C81.0376%2029.5%2083.5%2027.0376%2083.5%2024C83.5%2020.9624%2081.0376%2018.5%2078%2018.5C74.9624%2018.5%2072.5%2020.9624%2072.5%2024C72.5%2027.0376%2074.9624%2029.5%2078%2029.5Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M18%2052C35%2049%2060%2049%2072%2052L77%2027L62%2050L61.4%2021.8L51%2049L45%2020L39%2049L28.6%2021.8L28%2050L13%2027L18%2052Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M18%2052C18%2056%2021%2056%2023%2060C25%2063%2025%2062%2024%2067C21%2069%2021%2072%2021%2072C18%2075%2022%2077%2022%2077C35%2079%2055%2079%2068%2077C68%2077%2071%2075%2068%2072C68%2072%2069%2069%2066%2067C65%2062%2065%2063%2067%2060C69%2056%2072%2056%2072%2052C55%2049%2035%2049%2018%2052Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M23%2060C30%2058%2060%2058%2067%2060'%20stroke='white'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M24%2067C30%2065%2060%2065%2066%2067'%20stroke='white'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e",typeof document>"u"?require("url").pathToFileURL(__filename).href:n&&n.tagName.toUpperCase()==="SCRIPT"&&n.src||new URL("index.cjs",document.baseURI).href).href,black_rook:new URL("data:image/svg+xml,%3csvg%20width='90'%20height='90'%20viewBox='0%200%2090%2090'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M18%2078H72V72H18V78Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'/%3e%3cpath%20d='M25%2064L28%2059H62L65%2064H25Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M24%2072V64H66V72H24Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'/%3e%3cpath%20d='M28%2059V33H62V59H28Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'/%3e%3cpath%20d='M28%2033L22%2028H68L62%2033H28Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M22%2028V18H30V22H40V18H50V22H60V18H68V28H22Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M72%2072H18'%20stroke='white'%20stroke-width='2'%20stroke-linecap='round'/%3e%3cpath%20d='M25%2064H65'%20stroke='white'%20stroke-width='2'%20stroke-linecap='round'/%3e%3cpath%20d='M28%2059H62'%20stroke='white'%20stroke-width='2'%20stroke-linecap='round'/%3e%3cpath%20d='M28%2033H62'%20stroke='white'%20stroke-width='2'%20stroke-linecap='round'/%3e%3cpath%20d='M22%2028H68'%20stroke='white'%20stroke-width='2'%20stroke-linecap='round'/%3e%3c/svg%3e",typeof document>"u"?require("url").pathToFileURL(__filename).href:n&&n.tagName.toUpperCase()==="SCRIPT"&&n.src||new URL("index.cjs",document.baseURI).href).href,black_bishop:new URL("data:image/svg+xml,%3csvg%20width='90'%20height='90'%20viewBox='0%200%2090%2090'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M18%2072C24.78%2070.06%2038.22%2072.86%2045%2068C51.78%2072.86%2065.22%2070.06%2072%2072C72%2072%2075.3%2073.08%2078%2076C76.64%2077.94%2074.7%2077.98%2072%2077C65.22%2075.06%2051.78%2077.92%2045%2075C38.22%2077.92%2024.78%2075.06%2018%2077C15.292%2077.98%2013.354%2077.94%2012%2076C14.708%2072.12%2018%2072%2018%2072Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M30%2064C35%2069%2055%2069%2060%2064C61%2061%2060%2060%2060%2060C60%2055%2055%2052%2055%2052C66%2049%2067%2029%2045%2021C23%2029%2024%2049%2035%2052C35%2052%2030%2055%2030%2060C30%2060%2029%2061%2030%2064Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M50%2016C50%2017.3261%2049.4732%2018.5979%2048.5355%2019.5355C47.5979%2020.4732%2046.3261%2021%2045%2021C43.6739%2021%2042.4021%2020.4732%2041.4645%2019.5355C40.5268%2018.5979%2040%2017.3261%2040%2016C40%2014.6739%2040.5268%2013.4021%2041.4645%2012.4645C42.4021%2011.5268%2043.6739%2011%2045%2011C46.3261%2011%2047.5979%2011.5268%2048.5355%2012.4645C49.4732%2013.4021%2050%2014.6739%2050%2016Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M35%2052H55M30%2060H60'%20stroke='white'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M45%2031V41M40%2036H50'%20stroke='white'%20stroke-width='3'%20stroke-linecap='round'/%3e%3c/svg%3e",typeof document>"u"?require("url").pathToFileURL(__filename).href:n&&n.tagName.toUpperCase()==="SCRIPT"&&n.src||new URL("index.cjs",document.baseURI).href).href,black_knight:new URL("data:image/svg+xml,%3csvg%20width='90'%20height='90'%20viewBox='0%200%2090%2090'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M44%2020C65%2022%2077%2036%2076%2078H30C30%2060%2050%2065%2046%2036'%20fill='%23202020'/%3e%3cpath%20d='M44%2020C65%2022%2077%2036%2076%2078H30C30%2060%2050%2065%2046%2036'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M48%2036C48.76%2041.82%2036.9%2050.74%2032%2054C26%2058%2026.36%2062.68%2022%2062C19.916%2060.12%2024.82%2055.92%2022%2056C20%2056%2022.38%2058.46%2020%2060C18%2060%2011.994%2062%2012%2052C12%2048%2024%2028%2024%2028C24%2028%2027.78%2024.2%2028%2021C26.54%2019.012%2027%2017%2027%2015C29%2013%2033%2020%2033%2020H37C37%2020%2038.56%2016.016%2042%2014C44%2014%2044%2020%2044%2020'%20fill='%23202020'/%3e%3cpath%20d='M48%2036C48.76%2041.82%2036.9%2050.74%2032%2054C26%2058%2026.36%2062.68%2022%2062C19.916%2060.12%2024.82%2055.92%2022%2056C20%2056%2022.38%2058.46%2020%2060C18%2060%2011.994%2062%2012%2052C12%2048%2024%2028%2024%2028C24%2028%2027.78%2024.2%2028%2021C26.54%2019.012%2027%2017%2027%2015C29%2013%2033%2020%2033%2020H37C37%2020%2038.56%2016.016%2042%2014C44%2014%2044%2020%2044%2020'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M19%2052C19.5523%2052%2020%2051.5523%2020%2051C20%2050.4477%2019.5523%2050%2019%2050C18.4477%2050%2018%2050.4477%2018%2051C18%2051.5523%2018.4477%2052%2019%2052Z'%20fill='white'%20stroke='white'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M28.866%2031.5C28.4682%2032.189%2027.9954%2032.7972%2027.5517%2033.1907C27.108%2033.5841%2026.7297%2033.7307%2026.5%2033.5981C26.2703%2033.4655%2026.2081%2033.0646%2026.327%2032.4836C26.4459%2031.9026%2026.7361%2031.189%2027.134%2030.5C27.5318%2029.8109%2028.0046%2029.2028%2028.4483%2028.8093C28.892%2028.4159%2029.2703%2028.2693%2029.5%2028.4019C29.7297%2028.5345%2029.7919%2028.9354%2029.673%2029.5164C29.5541%2030.0974%2029.2638%2030.8109%2028.866%2031.5Z'%20fill='white'%20stroke='white'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M49.1%2020.8L48.2%2023.7L49.2%2024C55.5%2026%2060.5%2028.98%2065%2037.5C69.5%2046.02%2071.5%2058.12%2070.5%2078L70.4%2079H74.9L75%2078C76%2057.88%2073.24%2044.3%2068.5%2035.32C63.76%2026.34%2056.92%2022.04%2050.12%2021L49.1%2020.8Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e",typeof document>"u"?require("url").pathToFileURL(__filename).href:n&&n.tagName.toUpperCase()==="SCRIPT"&&n.src||new URL("index.cjs",document.baseURI).href).href,black_pawn:new URL("data:image/svg+xml,%3csvg%20width='90'%20height='90'%20viewBox='0%200%2090%2090'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M44%2018C39.58%2018%2036%2021.58%2036%2026C36%2028.84%2037.52%2031.32%2039.82%2032.76C34.98%2034.26%2031.42%2038.72%2031.34%2044H58.66C58.58%2038.72%2055.02%2034.26%2050.18%2032.76C52.48%2031.32%2054%2028.84%2054%2026C54%2021.58%2050.42%2018%2046%2018H44Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M23%2074H67V68H23V74Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M24%2072H66L64%2054L58%2050H32L26%2054L24%2072Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3c/svg%3e",typeof document>"u"?require("url").pathToFileURL(__filename).href:n&&n.tagName.toUpperCase()==="SCRIPT"&&n.src||new URL("index.cjs",document.baseURI).href).href},f=new Map;function U(){[["classicWood",g.classicWood],["blue",g.blue],["green",g.green],["dark",g.dark],["tournamentMarble",g.tournamentMarble]].forEach(([o,e])=>{f.set(o,{name:o,svg:e})})}U();function j(o,e){f.set(o,{name:o,svg:e})}function q(o){return f.get(o)??f.get("classicWood")}function _(){return[...f.values()]}const m=new Map,v={white_king:d.white_king,white_queen:d.white_queen,white_rook:d.white_rook,white_bishop:d.white_bishop,white_knight:d.white_knight,white_pawn:d.white_pawn,black_king:d.black_king,black_queen:d.black_queen,black_rook:d.black_rook,black_bishop:d.black_bishop,black_knight:d.black_knight,black_pawn:d.black_pawn};m.set("default",{name:"default",assets:v});function H(o,e){m.set(o,{name:o,assets:e})}function M(o){return m.get(o)??m.get("default")}function P(o,e,t){const i=e==="w"?"white":"black",s={k:"king",q:"queen",r:"rook",b:"bishop",n:"knight",p:"pawn"}[t];return M(o).assets[`${i}_${s}`]??v[`${i}_${s}`]}function I(o){return!o||o==="start"?new y.Chess:new y.Chess(o)}function T(o){if(!(!o||o==="start"))return o}function B(o,e){return o==="w"&&e.endsWith("8")||o==="b"&&e.endsWith("1")}function N(o){const e=o.charCodeAt(0)-97,t=Number.parseInt(o[1]??"1",10)-1;return{file:e,rank:t}}const C=["a","b","c","d","e","f","g","h"],w=["1","2","3","4","5","6","7","8"];function F(o){const e=document.createElement("div");e.className="ck-board",e.tabIndex=0;const t=document.createElement("div");t.className="ck-squares";const i=document.createElement("div");i.className="ck-pieces";const r=document.createElement("div");return r.className="ck-coordinates",e.append(t,i,r),o.replaceChildren(e),{boardEl:e,squaresEl:t,piecesEl:i,coordsEl:r,squareSize:0,orientation:"white",pieceSet:"default",theme:"classicWood"}}function L(o,e){const t=q(e);o.style.setProperty("--ck-board-theme",`url("${t.svg}")`),o.dataset.theme=e}function Z(o,e){o.style.setProperty("--ck-board-size",`${e}px`),o.style.width=`${e}px`,o.style.height=`${e}px`}function V(o,e,t,i,r){o.squaresEl.replaceChildren(),e.clear(),t.forEach(s=>{const a=document.createElement("div");if(a.className="ck-square",a.dataset.square=s.square,a.dataset.light=String(s.isLight),a.setAttribute("role","gridcell"),a.setAttribute("aria-label",s.square),i){const c=i(s.square,s);Array.isArray(c)?a.classList.add(...c.filter(Boolean)):c&&a.classList.add(...c.split(/\s+/).filter(Boolean))}if(r){const c=r(s.square,s);c&&Object.assign(a.style,c)}s.isSelected&&a.classList.add("is-selected"),s.isLegalTarget&&a.classList.add("is-legal-target"),s.isLastMove&&a.classList.add("is-last-move"),e.set(s.square,a),o.squaresEl.append(a)})}function A(o){o.coordsEl.replaceChildren();const e=o.orientation==="black";C.forEach((t,i)=>{const r=document.createElement("div");r.className="ck-coordinate ck-coordinate-file",r.textContent=e?C[C.length-1-i]??t:t,r.style.left=`calc(${i} * (100% / 8) + (100% / 16))`,o.coordsEl.append(r)}),w.forEach((t,i)=>{const r=document.createElement("div");r.className="ck-coordinate ck-coordinate-rank",r.textContent=e?w[i]??t:w[w.length-1-i]??t,r.style.top=`calc(${i} * (100% / 8) + (100% / 16))`,o.coordsEl.append(r)})}function p(o,e,t){const{file:i,rank:r}=N(o),s=e==="white"?i:7-i,a=e==="white"?7-r:r;return{x:s*t,y:a*t}}function $(o,e,t){const i=new Set(t.keys());e.forEach(r=>{const s=t.get(r.id)??O(r.id),a=s.querySelector("img");a&&(a.src=P(o.pieceSet,r.piece.color,r.piece.type),a.alt=`${r.piece.color==="w"?"White":"Black"} ${r.piece.type}`),s.dataset.square=r.square,s.dataset.color=r.piece.color,s.dataset.type=r.piece.type,s.style.transitionDuration=`${Math.max(0,Math.round(.001*1e3))}ms`,t.set(r.id,s),i.delete(r.id),s.isConnected||o.piecesEl.append(s)}),i.forEach(r=>{var s;(s=t.get(r))==null||s.remove(),t.delete(r)})}function O(o){const e=document.createElement("div");e.className="ck-piece",e.dataset.id=o,e.setAttribute("role","button"),e.setAttribute("tabindex","0");const t=document.createElement("img");return t.draggable=!1,t.alt="",e.append(t),e}function k(o,e,t,i,r){o.style.width=`${i}px`,o.style.height=`${i}px`,o.style.transform=`translate(${e}px, ${t}px)`,o.style.transitionProperty=r?"transform, opacity":"none"}const z=["a8","b8","c8","d8","e8","f8","g8","h8","a7","b7","c7","d7","e7","f7","g7","h7","a6","b6","c6","d6","e6","f6","g6","h6","a5","b5","c5","d5","e5","f5","g5","h5","a4","b4","c4","d4","e4","f4","g4","h4","a3","b3","c3","d3","e3","f3","g3","h3","a2","b2","c2","d2","e2","f2","g2","h2","a1","b1","c1","d1","e1","f1","g1","h1"];class D{constructor(e,t={}){h(this,"container");h(this,"chess");h(this,"emitter",new R);h(this,"options");h(this,"squareElements",new Map);h(this,"pieceElements",new Map);h(this,"piecesBySquare",new Map);h(this,"squareOrder",z);h(this,"selection",{square:null,legalTargets:[]});h(this,"resizeObserver");h(this,"piecePositionCache",new Map);h(this,"pieceIdsBySquare",new Map);h(this,"boardElement");h(this,"squaresLayer");h(this,"piecesLayer");h(this,"coordinatesLayer");h(this,"orientation");h(this,"themeName");h(this,"pieceSetName");h(this,"coordinatesEnabled");h(this,"draggable");h(this,"animationEnabled");h(this,"legalMovesEnabled");h(this,"moveAnimationDuration");h(this,"focusedSquare","e1");h(this,"lastMove",null);h(this,"draggingId",null);h(this,"dragPointerId",null);h(this,"dragOrigin",null);h(this,"dragSquare",null);h(this,"handleBoardClick",e=>{const t=this.getSquareFromEventTarget(e.target);if(!t)return;const i=this.getPieceFromSquare(t)??null;if(this.emit("squareclick",{square:t,piece:(i==null?void 0:i.piece)??null}),this.selection.square&&this.selection.legalTargets.includes(t)){this.performMove({from:this.selection.square,to:t});return}if(i&&i.piece.color===this.chess.turn()){this.setSelection(t);return}this.clearSelection()});h(this,"handleBoardKeyDown",e=>{var i;const t={ArrowUp:[0,1],ArrowDown:[0,-1],ArrowLeft:[-1,0],ArrowRight:[1,0]};if(e.key in t){e.preventDefault();const r=t[e.key];if(!r)return;const[s,a]=r,c=this.focusedSquare.charCodeAt(0)-97+s*(this.orientation==="white"?1:-1),l=this.focusedSquare[1]??"1",u=Number.parseInt(l,10)-1+a*(this.orientation==="white"?-1:1);c>=0&&c<8&&u>=0&&u<8&&(this.focusedSquare=`${String.fromCharCode(97+c)}${u+1}`,(i=this.boardElement.querySelector(`[data-square="${this.focusedSquare}"]`))==null||i.focus());return}if(e.key==="Enter"||e.key===" "){e.preventDefault();const r=this.getPieceFromSquare(this.focusedSquare)??null;if(this.selection.square&&this.selection.legalTargets.includes(this.focusedSquare)){this.performMove({from:this.selection.square,to:this.focusedSquare});return}r&&r.piece.color===this.chess.turn()&&this.setSelection(this.focusedSquare)}e.key==="Escape"&&this.clearSelection()});h(this,"handlePointerDown",e=>{if(!this.draggable)return;const t=this.getSquareFromEventTarget(e.target);if(!t)return;const i=this.getPieceFromSquare(t);if(!i||i.piece.color!==this.chess.turn())return;this.draggingId=i.id,this.dragPointerId=e.pointerId,this.dragOrigin={x:e.clientX,y:e.clientY},this.dragSquare=t;const r=this.pieceElements.get(i.id);r&&(r.setPointerCapture(e.pointerId),r.classList.add("is-dragging"),this.emit("dragstart",{square:t,piece:i.piece}))});h(this,"handlePointerMove",e=>{if(!this.draggingId||this.dragPointerId!==e.pointerId||!this.dragOrigin)return;const t=this.pieceElements.get(this.draggingId);if(!t)return;const i=this.squareSize(),r=e.clientX-this.dragOrigin.x,s=e.clientY-this.dragOrigin.y,a=this.dragSquare?p(this.dragSquare,this.orientation,i):{x:0,y:0};k(t,a.x+r,a.y+s,i,!1)});h(this,"handlePointerUp",e=>{if(!this.draggingId||this.dragPointerId!==e.pointerId)return;const t=this.pieceElements.get(this.draggingId),i=[...this.piecesBySquare.values()].find(s=>s.id===this.draggingId),r=this.getSquareFromEventTarget(e.target);if(t&&t.classList.remove("is-dragging"),i&&r&&this.selection.square!==r){const s=this.performMove({from:i.square,to:r});this.emit("dragend",{square:r,piece:i.piece,accepted:!!s})}else if(i){const{x:s,y:a}=p(i.square,this.orientation,this.squareSize());t&&k(t,s,a,this.squareSize(),!0),this.emit("dragend",{square:r,piece:i.piece,accepted:!1})}this.draggingId=null,this.dragPointerId=null,this.dragOrigin=null,this.dragSquare=null});h(this,"handlePointerCancel",e=>{if(!this.draggingId||this.dragPointerId!==e.pointerId)return;const t=[...this.piecesBySquare.values()].find(i=>i.id===this.draggingId);if(t){const i=this.pieceElements.get(this.draggingId);if(i){const r=this.squareSize(),{x:s,y:a}=p(t.square,this.orientation,r);k(i,s,a,r,!0)}}this.draggingId=null,this.dragPointerId=null,this.dragOrigin=null,this.dragSquare=null});const i=typeof e=="string"?document.querySelector(e):e;if(!i)throw new Error("Chessboard container was not found.");this.container=i,this.options=t,this.chess=I(T(t.fen??t.position)),this.orientation=t.orientation??"white",this.themeName=t.theme??"classicWood",this.pieceSetName=t.pieces??"default",this.coordinatesEnabled=t.coordinates??!0,this.draggable=t.draggable??!0,this.animationEnabled=t.animation??!0,this.legalMovesEnabled=t.showLegalMoves??!0,this.moveAnimationDuration=t.moveAnimationDuration??180;const r=F(this.container);this.boardElement=r.boardEl,this.squaresLayer=r.squaresEl,this.piecesLayer=r.piecesEl,this.coordinatesLayer=r.coordsEl,L(this.boardElement,this.themeName),this.boardElement.dataset.orientation=this.orientation,this.boardElement.dataset.draggable=String(this.draggable),this.boardElement.dataset.coordinates=String(this.coordinatesEnabled),this.boardElement.dataset.animation=String(this.animationEnabled),this.boardElement.setAttribute("role","grid"),this.boardElement.setAttribute("aria-label","Chessboard"),this.buildBoard(),this.syncFromChess(!0),this.attachListeners(),this.observeResize(),t.position&&t.position!=="start"&&this.loadFEN(t.position)}on(e,t){return this.emitter.on(e,t)}off(e,t){this.emitter.off(e,t)}flip(){this.orientation=this.orientation==="white"?"black":"white",this.boardElement.dataset.orientation=this.orientation,this.render(),this.emit("boardflip",{orientation:this.orientation})}setTheme(e){this.themeName=e,L(this.boardElement,e)}setPieceSet(e){this.pieceSetName=e,this.renderPieces()}setOrientation(e){this.orientation!==e&&(this.orientation=e,this.boardElement.dataset.orientation=e,this.render())}getOrientation(){return this.orientation}loadFEN(e){if(e==="start"){this.reset();return}this.chess.load(e),this.selection.square=null,this.selection.legalTargets=[],this.lastMove=null,this.syncFromChess(),this.emit("positionchange",{fen:this.getFEN()})}getFEN(){return this.chess.fen()}loadPGN(e){try{return this.chess.loadPgn(e),this.syncFromChess(),this.emit("positionchange",{fen:this.getFEN()}),!0}catch{return!1}}move(e,t,i){return this.performMove(i===void 0?{from:e,to:t}:{from:e,to:t,promotion:i})}setPosition(e){if(e==="start"){this.reset();return}this.loadFEN(e)}clear(){this.chess.clear(),this.syncFromChess(),this.emit("positionchange",{fen:this.getFEN()})}reset(){this.chess.reset(),this.syncFromChess(),this.emit("positionchange",{fen:this.getFEN()})}destroy(){var e;(e=this.resizeObserver)==null||e.disconnect(),this.emitter.clear(),this.boardElement.remove(),this.squareElements.clear(),this.pieceElements.forEach(t=>t.remove()),this.pieceElements.clear(),this.piecesBySquare.clear(),this.pieceIdsBySquare.clear()}getPositionSnapshot(){return{fen:this.getFEN(),pieces:[...this.piecesBySquare.values()]}}buildBoard(){const e=this.squareOrder.map(t=>({square:t,piece:null,isSelected:!1,isLegalTarget:!1,isLastMove:!1,isLight:!1}));V(this.getRendererContext(),this.squareElements,e,(t,i)=>{var r,s;return(s=(r=this.options).squareClassName)==null?void 0:s.call(r,t,{piece:i.piece,selected:i.isSelected,legalTarget:i.isLegalTarget,lastMove:i.isLastMove,light:i.isLight,orientation:this.orientation})},(t,i)=>{var r,s;return(s=(r=this.options).squareStyle)==null?void 0:s.call(r,t,{piece:i.piece,selected:i.isSelected,legalTarget:i.isLegalTarget,lastMove:i.isLastMove,light:i.isLight,orientation:this.orientation})}),this.renderCoordinatesLayer()}renderCoordinatesLayer(){if(!this.coordinatesEnabled){this.coordinatesLayer.replaceChildren(),this.coordinatesLayer.hidden=!0;return}this.coordinatesLayer.hidden=!1,A(this.getRendererContext())}render(){this.buildBoard(),this.renderPieces(),this.positionAllPieces(!1)}renderPieces(){$(this.getRendererContext(),[...this.piecesBySquare.values()],this.pieceElements),this.pieceElements.forEach((e,t)=>{const i=[...this.piecesBySquare.values()].find(a=>a.id===t);if(!i)return;const{x:r,y:s}=p(i.square,this.orientation,this.squareSize());k(e,r,s,this.squareSize(),this.animationEnabled)})}squareSize(){const e=this.boardElement.getBoundingClientRect();return Math.max(1,Math.floor(Math.min(e.width,e.height)/8))}positionAllPieces(e){const t=this.squareSize();Z(this.boardElement,t*8),this.piecesBySquare.forEach(i=>{const r=this.pieceElements.get(i.id);if(!r)return;const{x:s,y:a}=p(i.square,this.orientation,t);k(r,s,a,t,e&&this.animationEnabled),r.style.zIndex=this.draggingId===i.id?"20":"10"})}syncFromChess(e=!1){var s;const t=new Map(this.pieceIdsBySquare);this.piecesBySquare.clear(),this.pieceIdsBySquare.clear();const i=this.chess.board();let r=0;for(let a=0;a<8;a+=1)for(let c=0;c<8;c+=1){const l=((s=i[a])==null?void 0:s[c])??null;if(!l)continue;const u=`${String.fromCharCode(97+c)}${8-a}`,b=e?`piece-${r+=1}`:t.get(u)??`piece-${r+=1}`,x={id:b,piece:l,square:u};this.piecesBySquare.set(u,x),this.pieceIdsBySquare.set(u,b)}this.render()}attachListeners(){this.boardElement.addEventListener("click",this.handleBoardClick),this.boardElement.addEventListener("keydown",this.handleBoardKeyDown),this.boardElement.addEventListener("pointerdown",this.handlePointerDown),this.boardElement.addEventListener("pointermove",this.handlePointerMove),this.boardElement.addEventListener("pointerup",this.handlePointerUp),this.boardElement.addEventListener("pointercancel",this.handlePointerCancel)}observeResize(){if(typeof ResizeObserver>"u")return;const e=new ResizeObserver(()=>{this.positionAllPieces(!1),this.renderCoordinatesLayer()});e.observe(this.container),this.resizeObserver=e}getRendererContext(){return{boardEl:this.boardElement,squaresEl:this.squaresLayer,piecesEl:this.piecesLayer,coordsEl:this.coordinatesLayer,squareSize:this.squareSize(),orientation:this.orientation,pieceSet:this.pieceSetName,theme:this.themeName}}emit(e,t){this.emitter.emit(e,t);const i={move:"onMove",drop:"onDrop",dragstart:"onDragStart",dragend:"onDragEnd",squareclick:"onSquareClick",positionchange:"onPositionChange",boardflip:"onBoardFlip",promotion:"onPromotion"},r=this.options[i[e]];r==null||r(t)}getSquareFromEventTarget(e){var t;return e instanceof HTMLElement?((t=e.closest("[data-square]"))==null?void 0:t.getAttribute("data-square"))??null:null}getPieceFromSquare(e){return this.piecesBySquare.get(e)}getLegalTargets(e){return this.chess.moves({square:e,verbose:!0}).map(t=>t.to)}clearSelection(){this.selection.square=null,this.selection.legalTargets=[],this.render()}setSelection(e){this.selection.square=e,this.selection.legalTargets=e&&this.legalMovesEnabled?this.getLegalTargets(e):[],this.focusedSquare=e??this.focusedSquare,this.render()}performMove(e){const t=this.chess.get(e.from);if(!t)return null;const i=this.resolvePromotion(t,e.from,e.to,e.promotion),r=i===void 0?{from:e.from,to:e.to}:{from:e.from,to:e.to,promotion:i},s=this.chess.move(r);if(!s)return null;this.lastMove={from:e.from,to:e.to},this.selection.square=null,this.selection.legalTargets=[],this.syncPieceStateFromMove(s,i);const a={from:s.from,to:s.to,san:s.san,piece:s.piece,color:s.color,fen:this.getFEN()};return s.promotion&&(a.promotion=s.promotion),this.emit("move",a),this.emit("drop",{...a,accepted:!0}),this.emit("positionchange",{fen:this.getFEN()}),this.render(),s}syncPieceStateFromMove(e,t){var c,l;const i=this.piecesBySquare.get(e.from);if(!i){this.syncFromChess();return}const r=this.piecesBySquare.get(e.to),s=e.flags.includes("e")?`${e.to[0]}${e.from[1]}`:null,a=s?this.piecesBySquare.get(s):void 0;this.piecesBySquare.delete(e.from),i.square=e.to,i.piece={...i.piece,type:t??i.piece.type},this.piecesBySquare.set(e.to,i),this.pieceIdsBySquare.delete(e.from),this.pieceIdsBySquare.set(e.to,i.id),r&&r.id!==i.id&&(this.piecesBySquare.delete(e.to),(c=this.pieceElements.get(r.id))==null||c.remove(),this.pieceElements.delete(r.id)),a&&s&&(this.piecesBySquare.delete(s),(l=this.pieceElements.get(a.id))==null||l.remove(),this.pieceElements.delete(a.id))}resolvePromotion(e,t,i,r){var c,l;if(r)return r;if(e.type!=="p"||!B(e.color,i))return;const s={from:t,to:i,piece:e.type,color:e.color};return((l=(c=this.options).onPromotion)==null?void 0:l.call(c,s))??"q"}}exports.Chessboard=D;exports.getBoardTheme=q;exports.getPieceSet=M;exports.listBoardThemes=_;exports.registerBoardTheme=j;exports.registerPieceSet=H;
package/dist/index.js ADDED
@@ -0,0 +1,652 @@
1
+ var q = Object.defineProperty;
2
+ var E = (o, e, t) => e in o ? q(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t;
3
+ var a = (o, e, t) => E(o, typeof e != "symbol" ? e + "" : e, t);
4
+ import { Chess as b } from "chess.js";
5
+ class x {
6
+ constructor() {
7
+ a(this, "listeners", /* @__PURE__ */ new Map());
8
+ }
9
+ on(e, t) {
10
+ const i = this.listeners.get(e) ?? /* @__PURE__ */ new Set();
11
+ return i.add(t), this.listeners.set(e, i), () => this.off(e, t);
12
+ }
13
+ off(e, t) {
14
+ var i;
15
+ (i = this.listeners.get(e)) == null || i.delete(t);
16
+ }
17
+ emit(e, t) {
18
+ var i;
19
+ (i = this.listeners.get(e)) == null || i.forEach((r) => {
20
+ r(t);
21
+ });
22
+ }
23
+ clear() {
24
+ this.listeners.clear();
25
+ }
26
+ }
27
+ const u = {
28
+ classicWood: new URL("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='480'%20height='480'%20viewBox='0%200%20480%20480'%3e%3crect%20width='480'%20height='480'%20fill='%23f0d9b5'/%3e%3c!--%20Dark%20squares%20--%3e%3cg%20fill='%23b58863'%3e%3crect%20x='60'%20y='0'%20width='60'%20height='60'/%3e%3crect%20x='180'%20y='0'%20width='60'%20height='60'/%3e%3crect%20x='300'%20y='0'%20width='60'%20height='60'/%3e%3crect%20x='420'%20y='0'%20width='60'%20height='60'/%3e%3crect%20x='0'%20y='60'%20width='60'%20height='60'/%3e%3crect%20x='120'%20y='60'%20width='60'%20height='60'/%3e%3crect%20x='240'%20y='60'%20width='60'%20height='60'/%3e%3crect%20x='360'%20y='60'%20width='60'%20height='60'/%3e%3crect%20x='60'%20y='120'%20width='60'%20height='60'/%3e%3crect%20x='180'%20y='120'%20width='60'%20height='60'/%3e%3crect%20x='300'%20y='120'%20width='60'%20height='60'/%3e%3crect%20x='420'%20y='120'%20width='60'%20height='60'/%3e%3crect%20x='0'%20y='180'%20width='60'%20height='60'/%3e%3crect%20x='120'%20y='180'%20width='60'%20height='60'/%3e%3crect%20x='240'%20y='180'%20width='60'%20height='60'/%3e%3crect%20x='360'%20y='180'%20width='60'%20height='60'/%3e%3crect%20x='60'%20y='240'%20width='60'%20height='60'/%3e%3crect%20x='180'%20y='240'%20width='60'%20height='60'/%3e%3crect%20x='300'%20y='240'%20width='60'%20height='60'/%3e%3crect%20x='420'%20y='240'%20width='60'%20height='60'/%3e%3crect%20x='0'%20y='300'%20width='60'%20height='60'/%3e%3crect%20x='120'%20y='300'%20width='60'%20height='60'/%3e%3crect%20x='240'%20y='300'%20width='60'%20height='60'/%3e%3crect%20x='360'%20y='300'%20width='60'%20height='60'/%3e%3crect%20x='60'%20y='360'%20width='60'%20height='60'/%3e%3crect%20x='180'%20y='360'%20width='60'%20height='60'/%3e%3crect%20x='300'%20y='360'%20width='60'%20height='60'/%3e%3crect%20x='420'%20y='360'%20width='60'%20height='60'/%3e%3crect%20x='0'%20y='420'%20width='60'%20height='60'/%3e%3crect%20x='120'%20y='420'%20width='60'%20height='60'/%3e%3crect%20x='240'%20y='420'%20width='60'%20height='60'/%3e%3crect%20x='360'%20y='420'%20width='60'%20height='60'/%3e%3c/g%3e%3c/svg%3e", import.meta.url).href,
29
+ blue: new URL("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='480'%20height='480'%3e%3cdefs%3e%3cpattern%20id='board'%20width='120'%20height='120'%20patternUnits='userSpaceOnUse'%3e%3crect%20width='120'%20height='120'%20fill='%23dee3e6'/%3e%3crect%20width='60'%20height='60'%20fill='%234a6fa5'/%3e%3crect%20x='60'%20y='60'%20width='60'%20height='60'%20fill='%234a6fa5'/%3e%3c/pattern%3e%3c/defs%3e%3crect%20width='480'%20height='480'%20fill='url(%23board)'/%3e%3c/svg%3e", import.meta.url).href,
30
+ green: new URL("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='480'%20height='480'%3e%3cdefs%3e%3cpattern%20id='board'%20width='120'%20height='120'%20patternUnits='userSpaceOnUse'%3e%3crect%20width='120'%20height='120'%20fill='%23eeeed2'/%3e%3crect%20width='60'%20height='60'%20fill='%23769656'/%3e%3crect%20x='60'%20y='60'%20width='60'%20height='60'%20fill='%23769656'/%3e%3c/pattern%3e%3c/defs%3e%3crect%20width='480'%20height='480'%20fill='url(%23board)'/%3e%3c/svg%3e", import.meta.url).href,
31
+ dark: new URL("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='480'%20height='480'%3e%3cdefs%3e%3cpattern%20id='board'%20width='120'%20height='120'%20patternUnits='userSpaceOnUse'%3e%3crect%20width='120'%20height='120'%20fill='%233c3c3c'/%3e%3crect%20width='60'%20height='60'%20fill='%231e1e1e'/%3e%3crect%20x='60'%20y='60'%20width='60'%20height='60'%20fill='%231e1e1e'/%3e%3c/pattern%3e%3c/defs%3e%3crect%20width='480'%20height='480'%20fill='url(%23board)'/%3e%3c/svg%3e", import.meta.url).href,
32
+ tournamentMarble: new URL("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='480'%20height='480'%3e%3cdefs%3e%3cpattern%20id='board'%20width='120'%20height='120'%20patternUnits='userSpaceOnUse'%3e%3crect%20width='120'%20height='120'%20fill='%23f8f8f8'/%3e%3crect%20width='60'%20height='60'%20fill='%238c8c8c'/%3e%3crect%20x='60'%20y='60'%20width='60'%20height='60'%20fill='%238c8c8c'/%3e%3c/pattern%3e%3cfilter%20id='grain'%3e%3cfeTurbulence%20type='fractalNoise'%20baseFrequency='0.8'%20numOctaves='2'/%3e%3cfeColorMatrix%20values='%201%200%200%200%200%200%201%200%200%200%200%200%201%200%200%200%200%200%20.1%200'/%3e%3c/filter%3e%3c/defs%3e%3crect%20width='480'%20height='480'%20fill='url(%23board)'/%3e%3crect%20width='480'%20height='480'%20filter='url(%23grain)'%20opacity='.25'/%3e%3c/svg%3e", import.meta.url).href
33
+ }, c = {
34
+ white_king: new URL("data:image/svg+xml,%3csvg%20width='90'%20height='90'%20viewBox='0%200%2090%2090'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M45%2023.26V12'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'/%3e%3cpath%20d='M40%2016H50'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'/%3e%3cpath%20d='M45%2050C45%2050%2054%2035%2051%2029C51%2029%2049%2024%2045%2024C41%2024%2039%2029%2039%2029C36%2035%2045%2050%2045%2050Z'%20fill='white'%20stroke='black'%20stroke-width='3'/%3e%3cpath%20d='M23%2074C34%2081%2054%2081%2065%2074V60C65%2060%2083%2051%2077%2039C69%2026%2050%2032%2045%2047C39%2032%2019%2026%2013%2039C7.00001%2051%2023%2059%2023%2060V74Z'%20fill='white'/%3e%3cpath%20d='M45%2047C50%2032%2069%2026%2077%2039C83%2051%2065%2060%2065%2060V74C54%2081%2034%2081%2023%2074V60C23%2059%207.00001%2051%2013%2039C19%2026%2039%2032%2045%2047ZM45%2047V54'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M23%2060C34%2054%2054%2054%2065%2060'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M23%2067C34%2061%2054%2061%2065%2067'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M23%2074C34%2068%2054%2068%2065%2074'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e", import.meta.url).href,
35
+ white_queen: new URL("data:image/svg+xml,%3csvg%20width='90'%20height='90'%20viewBox='0%200%2090%2090'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M12%2029.5C15.0376%2029.5%2017.5%2027.0376%2017.5%2024C17.5%2020.9624%2015.0376%2018.5%2012%2018.5C8.96243%2018.5%206.5%2020.9624%206.5%2024C6.5%2027.0376%208.96243%2029.5%2012%2029.5Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M28%2023.5C31.0376%2023.5%2033.5%2021.0376%2033.5%2018C33.5%2014.9624%2031.0376%2012.5%2028%2012.5C24.9624%2012.5%2022.5%2014.9624%2022.5%2018C22.5%2021.0376%2024.9624%2023.5%2028%2023.5Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M45%2021.5C48.0376%2021.5%2050.5%2019.0376%2050.5%2016C50.5%2012.9624%2048.0376%2010.5%2045%2010.5C41.9624%2010.5%2039.5%2012.9624%2039.5%2016C39.5%2019.0376%2041.9624%2021.5%2045%2021.5Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M62%2023.5C65.0376%2023.5%2067.5%2021.0376%2067.5%2018C67.5%2014.9624%2065.0376%2012.5%2062%2012.5C58.9624%2012.5%2056.5%2014.9624%2056.5%2018C56.5%2021.0376%2058.9624%2023.5%2062%2023.5Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M78%2029.5C81.0376%2029.5%2083.5%2027.0376%2083.5%2024C83.5%2020.9624%2081.0376%2018.5%2078%2018.5C74.9624%2018.5%2072.5%2020.9624%2072.5%2024C72.5%2027.0376%2074.9624%2029.5%2078%2029.5Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M18%2052C35%2049%2060%2049%2072%2052L77%2027L62%2050L61.4%2021.8L51%2049L45%2020L39%2049L28.6%2021.8L28%2050L13%2027L18%2052Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M18%2052C18%2056%2021%2056%2023%2060C25%2063%2025%2062%2024%2067C21%2069%2021%2072%2021%2072C18%2075%2022%2077%2022%2077C35%2079%2055%2079%2068%2077C68%2077%2071%2075%2068%2072C68%2072%2069%2069%2066%2067C65%2062%2065%2063%2067%2060C69%2056%2072%2056%2072%2052C55%2049%2035%2049%2018%2052Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M23%2060C30%2058%2060%2058%2067%2060'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M24%2067C30%2065%2060%2065%2066%2067'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e", import.meta.url).href,
36
+ white_rook: new URL("data:image/svg+xml,%3csvg%20width='90'%20height='90'%20viewBox='0%200%2090%2090'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M18%2078H72V72H18V78Z'%20fill='white'%20stroke='black'%20stroke-width='3'/%3e%3cpath%20d='M25%2064L28%2059H62L65%2064H25Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M24%2072V64H66V72H24Z'%20fill='white'%20stroke='black'%20stroke-width='3'/%3e%3cpath%20d='M28%2059V33H62V59H28Z'%20fill='white'%20stroke='black'%20stroke-width='3'/%3e%3cpath%20d='M28%2033L22%2028H68L62%2033H28Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M22%2028V18H30V22H40V18H50V22H60V18H68V28H22Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M72%2072H18'%20stroke='white'%20stroke-width='2'%20stroke-linecap='round'/%3e%3cpath%20d='M25%2064H65'%20stroke='white'%20stroke-width='2'%20stroke-linecap='round'/%3e%3cpath%20d='M28%2059H62'%20stroke='white'%20stroke-width='2'%20stroke-linecap='round'/%3e%3cpath%20d='M28%2033H62'%20stroke='white'%20stroke-width='2'%20stroke-linecap='round'/%3e%3cpath%20d='M22%2028H68'%20stroke='white'%20stroke-width='2'%20stroke-linecap='round'/%3e%3c/svg%3e", import.meta.url).href,
37
+ white_bishop: new URL("data:image/svg+xml,%3csvg%20width='90'%20height='90'%20viewBox='0%200%2090%2090'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M18%2072C24.78%2070.06%2038.22%2072.86%2045%2068C51.78%2072.86%2065.22%2070.06%2072%2072C72%2072%2075.3%2073.08%2078%2076C76.64%2077.94%2074.7%2077.98%2072%2077C65.22%2075.06%2051.78%2077.92%2045%2075C38.22%2077.92%2024.78%2075.06%2018%2077C15.292%2077.98%2013.354%2077.94%2012%2076C14.708%2072.12%2018%2072%2018%2072Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M30%2064C35%2069%2055%2069%2060%2064C61%2061%2060%2060%2060%2060C60%2055%2055%2052%2055%2052C66%2049%2067%2029%2045%2021C23%2029%2024%2049%2035%2052C35%2052%2030%2055%2030%2060C30%2060%2029%2061%2030%2064Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M50%2016C50%2017.3261%2049.4732%2018.5979%2048.5355%2019.5355C47.5979%2020.4732%2046.3261%2021%2045%2021C43.6739%2021%2042.4021%2020.4732%2041.4645%2019.5355C40.5268%2018.5979%2040%2017.3261%2040%2016C40%2014.6739%2040.5268%2013.4021%2041.4645%2012.4645C42.4021%2011.5268%2043.6739%2011%2045%2011C46.3261%2011%2047.5979%2011.5268%2048.5355%2012.4645C49.4732%2013.4021%2050%2014.6739%2050%2016Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M35%2052H55M30%2060H60'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M45%2031V41M40%2036H50'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'/%3e%3c/svg%3e", import.meta.url).href,
38
+ white_knight: new URL("data:image/svg+xml,%3csvg%20width='90'%20height='90'%20viewBox='0%200%2090%2090'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M44%2020C65%2022%2077%2036%2076%2078H30C30%2060%2050%2065%2046%2036'%20fill='white'/%3e%3cpath%20d='M44%2020C65%2022%2077%2036%2076%2078H30C30%2060%2050%2065%2046%2036'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M48%2036C48.76%2041.82%2036.9%2050.74%2032%2054C26%2058%2026.36%2062.68%2022%2062C19.916%2060.12%2024.82%2055.92%2022%2056C20%2056%2022.38%2058.46%2020%2060C18%2060%2011.994%2062%2012%2052C12%2048%2024%2028%2024%2028C24%2028%2027.78%2024.2%2028%2021C26.54%2019.012%2027%2017%2027%2015C29%2013%2033%2020%2033%2020H37C37%2020%2038.56%2016.016%2042%2014C44%2014%2044%2020%2044%2020'%20fill='white'/%3e%3cpath%20d='M48%2036C48.76%2041.82%2036.9%2050.74%2032%2054C26%2058%2026.36%2062.68%2022%2062C19.916%2060.12%2024.82%2055.92%2022%2056C20%2056%2022.38%2058.46%2020%2060C18%2060%2011.994%2062%2012%2052C12%2048%2024%2028%2024%2028C24%2028%2027.78%2024.2%2028%2021C26.54%2019.012%2027%2017%2027%2015C29%2013%2033%2020%2033%2020H37C37%2020%2038.56%2016.016%2042%2014C44%2014%2044%2020%2044%2020'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M19%2052C19.5523%2052%2020%2051.5523%2020%2051C20%2050.4477%2019.5523%2050%2019%2050C18.4477%2050%2018%2050.4477%2018%2051C18%2051.5523%2018.4477%2052%2019%2052Z'%20fill='black'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M28.866%2031.5C28.4682%2032.189%2027.9954%2032.7972%2027.5517%2033.1907C27.108%2033.5841%2026.7297%2033.7307%2026.5%2033.5981C26.2703%2033.4655%2026.2081%2033.0646%2026.327%2032.4836C26.4459%2031.9026%2026.7361%2031.189%2027.134%2030.5C27.5318%2029.8109%2028.0046%2029.2028%2028.4483%2028.8093C28.892%2028.4159%2029.2703%2028.2693%2029.5%2028.4019C29.7297%2028.5345%2029.7919%2028.9354%2029.673%2029.5164C29.5541%2030.0974%2029.2638%2030.8109%2028.866%2031.5Z'%20fill='black'%20stroke='black'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M49.1%2020.8L48.2%2023.7L49.2%2024C55.5%2026%2060.5%2028.98%2065%2037.5C69.5%2046.02%2071.5%2058.12%2070.5%2078L70.4%2079H74.9L75%2078C76%2057.88%2073.24%2044.3%2068.5%2035.32C63.76%2026.34%2056.92%2022.04%2050.12%2021L49.1%2020.8Z'%20fill='black'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e", import.meta.url).href,
39
+ white_pawn: new URL("data:image/svg+xml,%3csvg%20width='90'%20height='90'%20viewBox='0%200%2090%2090'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M44%2018C39.58%2018%2036%2021.58%2036%2026C36%2028.84%2037.52%2031.32%2039.82%2032.76C34.98%2034.26%2031.42%2038.72%2031.34%2044H58.66C58.58%2038.72%2055.02%2034.26%2050.18%2032.76C52.48%2031.32%2054%2028.84%2054%2026C54%2021.58%2050.42%2018%2046%2018H44Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M23%2074H67V68H23V74Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M24%2072H66L64%2054L58%2050H32L26%2054L24%2072Z'%20fill='white'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3c/svg%3e", import.meta.url).href,
40
+ black_king: new URL("data:image/svg+xml,%3csvg%20width='90'%20height='90'%20viewBox='0%200%2090%2090'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M45%2023.26V12'%20stroke='white'%20stroke-width='3'%20stroke-linecap='round'/%3e%3cpath%20d='M40%2016H50'%20stroke='white'%20stroke-width='3'%20stroke-linecap='round'/%3e%3cpath%20d='M45%2050C45%2050%2054%2035%2051%2029C51%2029%2049%2024%2045%2024C41%2024%2039%2029%2039%2029C36%2035%2045%2050%2045%2050Z'%20fill='%23202020'%20stroke='%23202020'%20stroke-width='3'/%3e%3cpath%20d='M23%2074C34%2081%2054%2081%2065%2074V60C65%2060%2083%2051%2077%2039C69%2026%2050%2032%2045%2047C39%2032%2019%2026%2013%2039C7.00001%2051%2023%2059%2023%2060V74Z'%20fill='%23202020'/%3e%3cpath%20d='M45%2047C50%2032%2069%2026%2077%2039C83%2051%2065%2060%2065%2060V74C54%2081%2034%2081%2023%2074V60C23%2059%207.00001%2051%2013%2039C19%2026%2039%2032%2045%2047ZM45%2047V54'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M23%2060C34%2054%2054%2054%2065%2060'%20stroke='white'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M23%2067C34%2061%2054%2061%2065%2067'%20stroke='white'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M23%2074C34%2068%2054%2068%2065%2074'%20stroke='white'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e", import.meta.url).href,
41
+ black_queen: new URL("data:image/svg+xml,%3csvg%20width='90'%20height='90'%20viewBox='0%200%2090%2090'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M12%2029.5C15.0376%2029.5%2017.5%2027.0376%2017.5%2024C17.5%2020.9624%2015.0376%2018.5%2012%2018.5C8.96243%2018.5%206.5%2020.9624%206.5%2024C6.5%2027.0376%208.96243%2029.5%2012%2029.5Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M28%2023.5C31.0376%2023.5%2033.5%2021.0376%2033.5%2018C33.5%2014.9624%2031.0376%2012.5%2028%2012.5C24.9624%2012.5%2022.5%2014.9624%2022.5%2018C22.5%2021.0376%2024.9624%2023.5%2028%2023.5Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M45%2021.5C48.0376%2021.5%2050.5%2019.0376%2050.5%2016C50.5%2012.9624%2048.0376%2010.5%2045%2010.5C41.9624%2010.5%2039.5%2012.9624%2039.5%2016C39.5%2019.0376%2041.9624%2021.5%2045%2021.5Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M62%2023.5C65.0376%2023.5%2067.5%2021.0376%2067.5%2018C67.5%2014.9624%2065.0376%2012.5%2062%2012.5C58.9624%2012.5%2056.5%2014.9624%2056.5%2018C56.5%2021.0376%2058.9624%2023.5%2062%2023.5Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M78%2029.5C81.0376%2029.5%2083.5%2027.0376%2083.5%2024C83.5%2020.9624%2081.0376%2018.5%2078%2018.5C74.9624%2018.5%2072.5%2020.9624%2072.5%2024C72.5%2027.0376%2074.9624%2029.5%2078%2029.5Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M18%2052C35%2049%2060%2049%2072%2052L77%2027L62%2050L61.4%2021.8L51%2049L45%2020L39%2049L28.6%2021.8L28%2050L13%2027L18%2052Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M18%2052C18%2056%2021%2056%2023%2060C25%2063%2025%2062%2024%2067C21%2069%2021%2072%2021%2072C18%2075%2022%2077%2022%2077C35%2079%2055%2079%2068%2077C68%2077%2071%2075%2068%2072C68%2072%2069%2069%2066%2067C65%2062%2065%2063%2067%2060C69%2056%2072%2056%2072%2052C55%2049%2035%2049%2018%2052Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M23%2060C30%2058%2060%2058%2067%2060'%20stroke='white'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M24%2067C30%2065%2060%2065%2066%2067'%20stroke='white'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e", import.meta.url).href,
42
+ black_rook: new URL("data:image/svg+xml,%3csvg%20width='90'%20height='90'%20viewBox='0%200%2090%2090'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M18%2078H72V72H18V78Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'/%3e%3cpath%20d='M25%2064L28%2059H62L65%2064H25Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M24%2072V64H66V72H24Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'/%3e%3cpath%20d='M28%2059V33H62V59H28Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'/%3e%3cpath%20d='M28%2033L22%2028H68L62%2033H28Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M22%2028V18H30V22H40V18H50V22H60V18H68V28H22Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M72%2072H18'%20stroke='white'%20stroke-width='2'%20stroke-linecap='round'/%3e%3cpath%20d='M25%2064H65'%20stroke='white'%20stroke-width='2'%20stroke-linecap='round'/%3e%3cpath%20d='M28%2059H62'%20stroke='white'%20stroke-width='2'%20stroke-linecap='round'/%3e%3cpath%20d='M28%2033H62'%20stroke='white'%20stroke-width='2'%20stroke-linecap='round'/%3e%3cpath%20d='M22%2028H68'%20stroke='white'%20stroke-width='2'%20stroke-linecap='round'/%3e%3c/svg%3e", import.meta.url).href,
43
+ black_bishop: new URL("data:image/svg+xml,%3csvg%20width='90'%20height='90'%20viewBox='0%200%2090%2090'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M18%2072C24.78%2070.06%2038.22%2072.86%2045%2068C51.78%2072.86%2065.22%2070.06%2072%2072C72%2072%2075.3%2073.08%2078%2076C76.64%2077.94%2074.7%2077.98%2072%2077C65.22%2075.06%2051.78%2077.92%2045%2075C38.22%2077.92%2024.78%2075.06%2018%2077C15.292%2077.98%2013.354%2077.94%2012%2076C14.708%2072.12%2018%2072%2018%2072Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M30%2064C35%2069%2055%2069%2060%2064C61%2061%2060%2060%2060%2060C60%2055%2055%2052%2055%2052C66%2049%2067%2029%2045%2021C23%2029%2024%2049%2035%2052C35%2052%2030%2055%2030%2060C30%2060%2029%2061%2030%2064Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M50%2016C50%2017.3261%2049.4732%2018.5979%2048.5355%2019.5355C47.5979%2020.4732%2046.3261%2021%2045%2021C43.6739%2021%2042.4021%2020.4732%2041.4645%2019.5355C40.5268%2018.5979%2040%2017.3261%2040%2016C40%2014.6739%2040.5268%2013.4021%2041.4645%2012.4645C42.4021%2011.5268%2043.6739%2011%2045%2011C46.3261%2011%2047.5979%2011.5268%2048.5355%2012.4645C49.4732%2013.4021%2050%2014.6739%2050%2016Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M35%2052H55M30%2060H60'%20stroke='white'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M45%2031V41M40%2036H50'%20stroke='white'%20stroke-width='3'%20stroke-linecap='round'/%3e%3c/svg%3e", import.meta.url).href,
44
+ black_knight: new URL("data:image/svg+xml,%3csvg%20width='90'%20height='90'%20viewBox='0%200%2090%2090'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M44%2020C65%2022%2077%2036%2076%2078H30C30%2060%2050%2065%2046%2036'%20fill='%23202020'/%3e%3cpath%20d='M44%2020C65%2022%2077%2036%2076%2078H30C30%2060%2050%2065%2046%2036'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M48%2036C48.76%2041.82%2036.9%2050.74%2032%2054C26%2058%2026.36%2062.68%2022%2062C19.916%2060.12%2024.82%2055.92%2022%2056C20%2056%2022.38%2058.46%2020%2060C18%2060%2011.994%2062%2012%2052C12%2048%2024%2028%2024%2028C24%2028%2027.78%2024.2%2028%2021C26.54%2019.012%2027%2017%2027%2015C29%2013%2033%2020%2033%2020H37C37%2020%2038.56%2016.016%2042%2014C44%2014%2044%2020%2044%2020'%20fill='%23202020'/%3e%3cpath%20d='M48%2036C48.76%2041.82%2036.9%2050.74%2032%2054C26%2058%2026.36%2062.68%2022%2062C19.916%2060.12%2024.82%2055.92%2022%2056C20%2056%2022.38%2058.46%2020%2060C18%2060%2011.994%2062%2012%2052C12%2048%2024%2028%2024%2028C24%2028%2027.78%2024.2%2028%2021C26.54%2019.012%2027%2017%2027%2015C29%2013%2033%2020%2033%2020H37C37%2020%2038.56%2016.016%2042%2014C44%2014%2044%2020%2044%2020'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M19%2052C19.5523%2052%2020%2051.5523%2020%2051C20%2050.4477%2019.5523%2050%2019%2050C18.4477%2050%2018%2050.4477%2018%2051C18%2051.5523%2018.4477%2052%2019%2052Z'%20fill='white'%20stroke='white'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M28.866%2031.5C28.4682%2032.189%2027.9954%2032.7972%2027.5517%2033.1907C27.108%2033.5841%2026.7297%2033.7307%2026.5%2033.5981C26.2703%2033.4655%2026.2081%2033.0646%2026.327%2032.4836C26.4459%2031.9026%2026.7361%2031.189%2027.134%2030.5C27.5318%2029.8109%2028.0046%2029.2028%2028.4483%2028.8093C28.892%2028.4159%2029.2703%2028.2693%2029.5%2028.4019C29.7297%2028.5345%2029.7919%2028.9354%2029.673%2029.5164C29.5541%2030.0974%2029.2638%2030.8109%2028.866%2031.5Z'%20fill='white'%20stroke='white'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M49.1%2020.8L48.2%2023.7L49.2%2024C55.5%2026%2060.5%2028.98%2065%2037.5C69.5%2046.02%2071.5%2058.12%2070.5%2078L70.4%2079H74.9L75%2078C76%2057.88%2073.24%2044.3%2068.5%2035.32C63.76%2026.34%2056.92%2022.04%2050.12%2021L49.1%2020.8Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e", import.meta.url).href,
45
+ black_pawn: new URL("data:image/svg+xml,%3csvg%20width='90'%20height='90'%20viewBox='0%200%2090%2090'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M44%2018C39.58%2018%2036%2021.58%2036%2026C36%2028.84%2037.52%2031.32%2039.82%2032.76C34.98%2034.26%2031.42%2038.72%2031.34%2044H58.66C58.58%2038.72%2055.02%2034.26%2050.18%2032.76C52.48%2031.32%2054%2028.84%2054%2026C54%2021.58%2050.42%2018%2046%2018H44Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M23%2074H67V68H23V74Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3cpath%20d='M24%2072H66L64%2054L58%2050H32L26%2054L24%2072Z'%20fill='%23202020'%20stroke='black'%20stroke-width='3'%20stroke-linejoin='round'/%3e%3c/svg%3e", import.meta.url).href
46
+ }, p = /* @__PURE__ */ new Map();
47
+ function L() {
48
+ [
49
+ ["classicWood", u.classicWood],
50
+ ["blue", u.blue],
51
+ ["green", u.green],
52
+ ["dark", u.dark],
53
+ ["tournamentMarble", u.tournamentMarble]
54
+ ].forEach(([o, e]) => {
55
+ p.set(o, {
56
+ name: o,
57
+ svg: e
58
+ });
59
+ });
60
+ }
61
+ L();
62
+ function O(o, e) {
63
+ p.set(o, { name: o, svg: e });
64
+ }
65
+ function S(o) {
66
+ return p.get(o) ?? p.get("classicWood");
67
+ }
68
+ function z() {
69
+ return [...p.values()];
70
+ }
71
+ const f = /* @__PURE__ */ new Map(), v = {
72
+ white_king: c.white_king,
73
+ white_queen: c.white_queen,
74
+ white_rook: c.white_rook,
75
+ white_bishop: c.white_bishop,
76
+ white_knight: c.white_knight,
77
+ white_pawn: c.white_pawn,
78
+ black_king: c.black_king,
79
+ black_queen: c.black_queen,
80
+ black_rook: c.black_rook,
81
+ black_bishop: c.black_bishop,
82
+ black_knight: c.black_knight,
83
+ black_pawn: c.black_pawn
84
+ };
85
+ f.set("default", {
86
+ name: "default",
87
+ assets: v
88
+ });
89
+ function D(o, e) {
90
+ f.set(o, { name: o, assets: e });
91
+ }
92
+ function H(o) {
93
+ return f.get(o) ?? f.get("default");
94
+ }
95
+ function B(o, e, t) {
96
+ const i = e === "w" ? "white" : "black", s = {
97
+ k: "king",
98
+ q: "queen",
99
+ r: "rook",
100
+ b: "bishop",
101
+ n: "knight",
102
+ p: "pawn"
103
+ }[t];
104
+ return H(o).assets[`${i}_${s}`] ?? v[`${i}_${s}`];
105
+ }
106
+ function j(o) {
107
+ return !o || o === "start" ? new b() : new b(o);
108
+ }
109
+ function P(o) {
110
+ if (!(!o || o === "start"))
111
+ return o;
112
+ }
113
+ function Z(o, e) {
114
+ return o === "w" && e.endsWith("8") || o === "b" && e.endsWith("1");
115
+ }
116
+ function V(o) {
117
+ const e = o.charCodeAt(0) - 97, t = Number.parseInt(o[1] ?? "1", 10) - 1;
118
+ return { file: e, rank: t };
119
+ }
120
+ const m = ["a", "b", "c", "d", "e", "f", "g", "h"], w = ["1", "2", "3", "4", "5", "6", "7", "8"];
121
+ function _(o) {
122
+ const e = document.createElement("div");
123
+ e.className = "ck-board", e.tabIndex = 0;
124
+ const t = document.createElement("div");
125
+ t.className = "ck-squares";
126
+ const i = document.createElement("div");
127
+ i.className = "ck-pieces";
128
+ const r = document.createElement("div");
129
+ return r.className = "ck-coordinates", e.append(t, i, r), o.replaceChildren(e), {
130
+ boardEl: e,
131
+ squaresEl: t,
132
+ piecesEl: i,
133
+ coordsEl: r,
134
+ squareSize: 0,
135
+ orientation: "white",
136
+ pieceSet: "default",
137
+ theme: "classicWood"
138
+ };
139
+ }
140
+ function y(o, e) {
141
+ const t = S(e);
142
+ o.style.setProperty("--ck-board-theme", `url("${t.svg}")`), o.dataset.theme = e;
143
+ }
144
+ function N(o, e) {
145
+ o.style.setProperty("--ck-board-size", `${e}px`), o.style.width = `${e}px`, o.style.height = `${e}px`;
146
+ }
147
+ function F(o, e, t, i, r) {
148
+ o.squaresEl.replaceChildren(), e.clear(), t.forEach((s) => {
149
+ const n = document.createElement("div");
150
+ if (n.className = "ck-square", n.dataset.square = s.square, n.dataset.light = String(s.isLight), n.setAttribute("role", "gridcell"), n.setAttribute("aria-label", s.square), i) {
151
+ const h = i(s.square, s);
152
+ Array.isArray(h) ? n.classList.add(...h.filter(Boolean)) : h && n.classList.add(...h.split(/\s+/).filter(Boolean));
153
+ }
154
+ if (r) {
155
+ const h = r(s.square, s);
156
+ h && Object.assign(n.style, h);
157
+ }
158
+ s.isSelected && n.classList.add("is-selected"), s.isLegalTarget && n.classList.add("is-legal-target"), s.isLastMove && n.classList.add("is-last-move"), e.set(s.square, n), o.squaresEl.append(n);
159
+ });
160
+ }
161
+ function I(o) {
162
+ o.coordsEl.replaceChildren();
163
+ const e = o.orientation === "black";
164
+ m.forEach((t, i) => {
165
+ const r = document.createElement("div");
166
+ r.className = "ck-coordinate ck-coordinate-file", r.textContent = e ? m[m.length - 1 - i] ?? t : t, r.style.left = `calc(${i} * (100% / 8) + (100% / 16))`, o.coordsEl.append(r);
167
+ }), w.forEach((t, i) => {
168
+ const r = document.createElement("div");
169
+ r.className = "ck-coordinate ck-coordinate-rank", r.textContent = e ? w[i] ?? t : w[w.length - 1 - i] ?? t, r.style.top = `calc(${i} * (100% / 8) + (100% / 16))`, o.coordsEl.append(r);
170
+ });
171
+ }
172
+ function g(o, e, t) {
173
+ const { file: i, rank: r } = V(o), s = e === "white" ? i : 7 - i, n = e === "white" ? 7 - r : r;
174
+ return { x: s * t, y: n * t };
175
+ }
176
+ function R(o, e, t) {
177
+ const i = new Set(t.keys());
178
+ e.forEach((r) => {
179
+ const s = t.get(r.id) ?? T(r.id), n = s.querySelector("img");
180
+ n && (n.src = B(o.pieceSet, r.piece.color, r.piece.type), n.alt = `${r.piece.color === "w" ? "White" : "Black"} ${r.piece.type}`), s.dataset.square = r.square, s.dataset.color = r.piece.color, s.dataset.type = r.piece.type, s.style.transitionDuration = `${Math.max(0, Math.round(1e-3 * 1e3))}ms`, t.set(r.id, s), i.delete(r.id), s.isConnected || o.piecesEl.append(s);
181
+ }), i.forEach((r) => {
182
+ var s;
183
+ (s = t.get(r)) == null || s.remove(), t.delete(r);
184
+ });
185
+ }
186
+ function T(o) {
187
+ const e = document.createElement("div");
188
+ e.className = "ck-piece", e.dataset.id = o, e.setAttribute("role", "button"), e.setAttribute("tabindex", "0");
189
+ const t = document.createElement("img");
190
+ return t.draggable = !1, t.alt = "", e.append(t), e;
191
+ }
192
+ function k(o, e, t, i, r) {
193
+ o.style.width = `${i}px`, o.style.height = `${i}px`, o.style.transform = `translate(${e}px, ${t}px)`, o.style.transitionProperty = r ? "transform, opacity" : "none";
194
+ }
195
+ const U = [
196
+ "a8",
197
+ "b8",
198
+ "c8",
199
+ "d8",
200
+ "e8",
201
+ "f8",
202
+ "g8",
203
+ "h8",
204
+ "a7",
205
+ "b7",
206
+ "c7",
207
+ "d7",
208
+ "e7",
209
+ "f7",
210
+ "g7",
211
+ "h7",
212
+ "a6",
213
+ "b6",
214
+ "c6",
215
+ "d6",
216
+ "e6",
217
+ "f6",
218
+ "g6",
219
+ "h6",
220
+ "a5",
221
+ "b5",
222
+ "c5",
223
+ "d5",
224
+ "e5",
225
+ "f5",
226
+ "g5",
227
+ "h5",
228
+ "a4",
229
+ "b4",
230
+ "c4",
231
+ "d4",
232
+ "e4",
233
+ "f4",
234
+ "g4",
235
+ "h4",
236
+ "a3",
237
+ "b3",
238
+ "c3",
239
+ "d3",
240
+ "e3",
241
+ "f3",
242
+ "g3",
243
+ "h3",
244
+ "a2",
245
+ "b2",
246
+ "c2",
247
+ "d2",
248
+ "e2",
249
+ "f2",
250
+ "g2",
251
+ "h2",
252
+ "a1",
253
+ "b1",
254
+ "c1",
255
+ "d1",
256
+ "e1",
257
+ "f1",
258
+ "g1",
259
+ "h1"
260
+ ];
261
+ class W {
262
+ constructor(e, t = {}) {
263
+ a(this, "container");
264
+ a(this, "chess");
265
+ a(this, "emitter", new x());
266
+ a(this, "options");
267
+ a(this, "squareElements", /* @__PURE__ */ new Map());
268
+ a(this, "pieceElements", /* @__PURE__ */ new Map());
269
+ a(this, "piecesBySquare", /* @__PURE__ */ new Map());
270
+ a(this, "squareOrder", U);
271
+ a(this, "selection", {
272
+ square: null,
273
+ legalTargets: []
274
+ });
275
+ a(this, "resizeObserver");
276
+ a(this, "piecePositionCache", /* @__PURE__ */ new Map());
277
+ a(this, "pieceIdsBySquare", /* @__PURE__ */ new Map());
278
+ a(this, "boardElement");
279
+ a(this, "squaresLayer");
280
+ a(this, "piecesLayer");
281
+ a(this, "coordinatesLayer");
282
+ a(this, "orientation");
283
+ a(this, "themeName");
284
+ a(this, "pieceSetName");
285
+ a(this, "coordinatesEnabled");
286
+ a(this, "draggable");
287
+ a(this, "animationEnabled");
288
+ a(this, "legalMovesEnabled");
289
+ a(this, "moveAnimationDuration");
290
+ a(this, "focusedSquare", "e1");
291
+ a(this, "lastMove", null);
292
+ a(this, "draggingId", null);
293
+ a(this, "dragPointerId", null);
294
+ a(this, "dragOrigin", null);
295
+ a(this, "dragSquare", null);
296
+ a(this, "handleBoardClick", (e) => {
297
+ const t = this.getSquareFromEventTarget(e.target);
298
+ if (!t)
299
+ return;
300
+ const i = this.getPieceFromSquare(t) ?? null;
301
+ if (this.emit("squareclick", { square: t, piece: (i == null ? void 0 : i.piece) ?? null }), this.selection.square && this.selection.legalTargets.includes(t)) {
302
+ this.performMove({ from: this.selection.square, to: t });
303
+ return;
304
+ }
305
+ if (i && i.piece.color === this.chess.turn()) {
306
+ this.setSelection(t);
307
+ return;
308
+ }
309
+ this.clearSelection();
310
+ });
311
+ a(this, "handleBoardKeyDown", (e) => {
312
+ var i;
313
+ const t = {
314
+ ArrowUp: [0, 1],
315
+ ArrowDown: [0, -1],
316
+ ArrowLeft: [-1, 0],
317
+ ArrowRight: [1, 0]
318
+ };
319
+ if (e.key in t) {
320
+ e.preventDefault();
321
+ const r = t[e.key];
322
+ if (!r)
323
+ return;
324
+ const [s, n] = r, h = this.focusedSquare.charCodeAt(0) - 97 + s * (this.orientation === "white" ? 1 : -1), l = this.focusedSquare[1] ?? "1", d = Number.parseInt(l, 10) - 1 + n * (this.orientation === "white" ? -1 : 1);
325
+ h >= 0 && h < 8 && d >= 0 && d < 8 && (this.focusedSquare = `${String.fromCharCode(97 + h)}${d + 1}`, (i = this.boardElement.querySelector(`[data-square="${this.focusedSquare}"]`)) == null || i.focus());
326
+ return;
327
+ }
328
+ if (e.key === "Enter" || e.key === " ") {
329
+ e.preventDefault();
330
+ const r = this.getPieceFromSquare(this.focusedSquare) ?? null;
331
+ if (this.selection.square && this.selection.legalTargets.includes(this.focusedSquare)) {
332
+ this.performMove({ from: this.selection.square, to: this.focusedSquare });
333
+ return;
334
+ }
335
+ r && r.piece.color === this.chess.turn() && this.setSelection(this.focusedSquare);
336
+ }
337
+ e.key === "Escape" && this.clearSelection();
338
+ });
339
+ a(this, "handlePointerDown", (e) => {
340
+ if (!this.draggable)
341
+ return;
342
+ const t = this.getSquareFromEventTarget(e.target);
343
+ if (!t)
344
+ return;
345
+ const i = this.getPieceFromSquare(t);
346
+ if (!i || i.piece.color !== this.chess.turn())
347
+ return;
348
+ this.draggingId = i.id, this.dragPointerId = e.pointerId, this.dragOrigin = { x: e.clientX, y: e.clientY }, this.dragSquare = t;
349
+ const r = this.pieceElements.get(i.id);
350
+ r && (r.setPointerCapture(e.pointerId), r.classList.add("is-dragging"), this.emit("dragstart", { square: t, piece: i.piece }));
351
+ });
352
+ a(this, "handlePointerMove", (e) => {
353
+ if (!this.draggingId || this.dragPointerId !== e.pointerId || !this.dragOrigin)
354
+ return;
355
+ const t = this.pieceElements.get(this.draggingId);
356
+ if (!t)
357
+ return;
358
+ const i = this.squareSize(), r = e.clientX - this.dragOrigin.x, s = e.clientY - this.dragOrigin.y, n = this.dragSquare ? g(this.dragSquare, this.orientation, i) : { x: 0, y: 0 };
359
+ k(t, n.x + r, n.y + s, i, !1);
360
+ });
361
+ a(this, "handlePointerUp", (e) => {
362
+ if (!this.draggingId || this.dragPointerId !== e.pointerId)
363
+ return;
364
+ const t = this.pieceElements.get(this.draggingId), i = [...this.piecesBySquare.values()].find((s) => s.id === this.draggingId), r = this.getSquareFromEventTarget(e.target);
365
+ if (t && t.classList.remove("is-dragging"), i && r && this.selection.square !== r) {
366
+ const s = this.performMove({ from: i.square, to: r });
367
+ this.emit("dragend", {
368
+ square: r,
369
+ piece: i.piece,
370
+ accepted: !!s
371
+ });
372
+ } else if (i) {
373
+ const { x: s, y: n } = g(i.square, this.orientation, this.squareSize());
374
+ t && k(t, s, n, this.squareSize(), !0), this.emit("dragend", {
375
+ square: r,
376
+ piece: i.piece,
377
+ accepted: !1
378
+ });
379
+ }
380
+ this.draggingId = null, this.dragPointerId = null, this.dragOrigin = null, this.dragSquare = null;
381
+ });
382
+ a(this, "handlePointerCancel", (e) => {
383
+ if (!this.draggingId || this.dragPointerId !== e.pointerId)
384
+ return;
385
+ const t = [...this.piecesBySquare.values()].find((i) => i.id === this.draggingId);
386
+ if (t) {
387
+ const i = this.pieceElements.get(this.draggingId);
388
+ if (i) {
389
+ const r = this.squareSize(), { x: s, y: n } = g(t.square, this.orientation, r);
390
+ k(i, s, n, r, !0);
391
+ }
392
+ }
393
+ this.draggingId = null, this.dragPointerId = null, this.dragOrigin = null, this.dragSquare = null;
394
+ });
395
+ const i = typeof e == "string" ? document.querySelector(e) : e;
396
+ if (!i)
397
+ throw new Error("Chessboard container was not found.");
398
+ this.container = i, this.options = t, this.chess = j(P(t.fen ?? t.position)), this.orientation = t.orientation ?? "white", this.themeName = t.theme ?? "classicWood", this.pieceSetName = t.pieces ?? "default", this.coordinatesEnabled = t.coordinates ?? !0, this.draggable = t.draggable ?? !0, this.animationEnabled = t.animation ?? !0, this.legalMovesEnabled = t.showLegalMoves ?? !0, this.moveAnimationDuration = t.moveAnimationDuration ?? 180;
399
+ const r = _(this.container);
400
+ this.boardElement = r.boardEl, this.squaresLayer = r.squaresEl, this.piecesLayer = r.piecesEl, this.coordinatesLayer = r.coordsEl, y(this.boardElement, this.themeName), this.boardElement.dataset.orientation = this.orientation, this.boardElement.dataset.draggable = String(this.draggable), this.boardElement.dataset.coordinates = String(this.coordinatesEnabled), this.boardElement.dataset.animation = String(this.animationEnabled), this.boardElement.setAttribute("role", "grid"), this.boardElement.setAttribute("aria-label", "Chessboard"), this.buildBoard(), this.syncFromChess(!0), this.attachListeners(), this.observeResize(), t.position && t.position !== "start" && this.loadFEN(t.position);
401
+ }
402
+ on(e, t) {
403
+ return this.emitter.on(e, t);
404
+ }
405
+ off(e, t) {
406
+ this.emitter.off(e, t);
407
+ }
408
+ flip() {
409
+ this.orientation = this.orientation === "white" ? "black" : "white", this.boardElement.dataset.orientation = this.orientation, this.render(), this.emit("boardflip", { orientation: this.orientation });
410
+ }
411
+ setTheme(e) {
412
+ this.themeName = e, y(this.boardElement, e);
413
+ }
414
+ setPieceSet(e) {
415
+ this.pieceSetName = e, this.renderPieces();
416
+ }
417
+ setOrientation(e) {
418
+ this.orientation !== e && (this.orientation = e, this.boardElement.dataset.orientation = e, this.render());
419
+ }
420
+ getOrientation() {
421
+ return this.orientation;
422
+ }
423
+ loadFEN(e) {
424
+ if (e === "start") {
425
+ this.reset();
426
+ return;
427
+ }
428
+ this.chess.load(e), this.selection.square = null, this.selection.legalTargets = [], this.lastMove = null, this.syncFromChess(), this.emit("positionchange", { fen: this.getFEN() });
429
+ }
430
+ getFEN() {
431
+ return this.chess.fen();
432
+ }
433
+ loadPGN(e) {
434
+ try {
435
+ return this.chess.loadPgn(e), this.syncFromChess(), this.emit("positionchange", { fen: this.getFEN() }), !0;
436
+ } catch {
437
+ return !1;
438
+ }
439
+ }
440
+ move(e, t, i) {
441
+ return this.performMove(i === void 0 ? { from: e, to: t } : { from: e, to: t, promotion: i });
442
+ }
443
+ setPosition(e) {
444
+ if (e === "start") {
445
+ this.reset();
446
+ return;
447
+ }
448
+ this.loadFEN(e);
449
+ }
450
+ clear() {
451
+ this.chess.clear(), this.syncFromChess(), this.emit("positionchange", { fen: this.getFEN() });
452
+ }
453
+ reset() {
454
+ this.chess.reset(), this.syncFromChess(), this.emit("positionchange", { fen: this.getFEN() });
455
+ }
456
+ destroy() {
457
+ var e;
458
+ (e = this.resizeObserver) == null || e.disconnect(), this.emitter.clear(), this.boardElement.remove(), this.squareElements.clear(), this.pieceElements.forEach((t) => t.remove()), this.pieceElements.clear(), this.piecesBySquare.clear(), this.pieceIdsBySquare.clear();
459
+ }
460
+ getPositionSnapshot() {
461
+ return {
462
+ fen: this.getFEN(),
463
+ pieces: [...this.piecesBySquare.values()]
464
+ };
465
+ }
466
+ buildBoard() {
467
+ const e = this.squareOrder.map((t) => ({
468
+ square: t,
469
+ piece: null,
470
+ isSelected: !1,
471
+ isLegalTarget: !1,
472
+ isLastMove: !1,
473
+ isLight: !1
474
+ }));
475
+ F(this.getRendererContext(), this.squareElements, e, (t, i) => {
476
+ var r, s;
477
+ return (s = (r = this.options).squareClassName) == null ? void 0 : s.call(r, t, {
478
+ piece: i.piece,
479
+ selected: i.isSelected,
480
+ legalTarget: i.isLegalTarget,
481
+ lastMove: i.isLastMove,
482
+ light: i.isLight,
483
+ orientation: this.orientation
484
+ });
485
+ }, (t, i) => {
486
+ var r, s;
487
+ return (s = (r = this.options).squareStyle) == null ? void 0 : s.call(r, t, {
488
+ piece: i.piece,
489
+ selected: i.isSelected,
490
+ legalTarget: i.isLegalTarget,
491
+ lastMove: i.isLastMove,
492
+ light: i.isLight,
493
+ orientation: this.orientation
494
+ });
495
+ }), this.renderCoordinatesLayer();
496
+ }
497
+ renderCoordinatesLayer() {
498
+ if (!this.coordinatesEnabled) {
499
+ this.coordinatesLayer.replaceChildren(), this.coordinatesLayer.hidden = !0;
500
+ return;
501
+ }
502
+ this.coordinatesLayer.hidden = !1, I(this.getRendererContext());
503
+ }
504
+ render() {
505
+ this.buildBoard(), this.renderPieces(), this.positionAllPieces(!1);
506
+ }
507
+ renderPieces() {
508
+ R(this.getRendererContext(), [...this.piecesBySquare.values()], this.pieceElements), this.pieceElements.forEach((e, t) => {
509
+ const i = [...this.piecesBySquare.values()].find((n) => n.id === t);
510
+ if (!i)
511
+ return;
512
+ const { x: r, y: s } = g(i.square, this.orientation, this.squareSize());
513
+ k(e, r, s, this.squareSize(), this.animationEnabled);
514
+ });
515
+ }
516
+ squareSize() {
517
+ const e = this.boardElement.getBoundingClientRect();
518
+ return Math.max(1, Math.floor(Math.min(e.width, e.height) / 8));
519
+ }
520
+ positionAllPieces(e) {
521
+ const t = this.squareSize();
522
+ N(this.boardElement, t * 8), this.piecesBySquare.forEach((i) => {
523
+ const r = this.pieceElements.get(i.id);
524
+ if (!r)
525
+ return;
526
+ const { x: s, y: n } = g(i.square, this.orientation, t);
527
+ k(r, s, n, t, e && this.animationEnabled), r.style.zIndex = this.draggingId === i.id ? "20" : "10";
528
+ });
529
+ }
530
+ syncFromChess(e = !1) {
531
+ var s;
532
+ const t = new Map(this.pieceIdsBySquare);
533
+ this.piecesBySquare.clear(), this.pieceIdsBySquare.clear();
534
+ const i = this.chess.board();
535
+ let r = 0;
536
+ for (let n = 0; n < 8; n += 1)
537
+ for (let h = 0; h < 8; h += 1) {
538
+ const l = ((s = i[n]) == null ? void 0 : s[h]) ?? null;
539
+ if (!l)
540
+ continue;
541
+ const d = `${String.fromCharCode(97 + h)}${8 - n}`, C = e ? `piece-${r += 1}` : t.get(d) ?? `piece-${r += 1}`, M = { id: C, piece: l, square: d };
542
+ this.piecesBySquare.set(d, M), this.pieceIdsBySquare.set(d, C);
543
+ }
544
+ this.render();
545
+ }
546
+ attachListeners() {
547
+ this.boardElement.addEventListener("click", this.handleBoardClick), this.boardElement.addEventListener("keydown", this.handleBoardKeyDown), this.boardElement.addEventListener("pointerdown", this.handlePointerDown), this.boardElement.addEventListener("pointermove", this.handlePointerMove), this.boardElement.addEventListener("pointerup", this.handlePointerUp), this.boardElement.addEventListener("pointercancel", this.handlePointerCancel);
548
+ }
549
+ observeResize() {
550
+ if (typeof ResizeObserver > "u")
551
+ return;
552
+ const e = new ResizeObserver(() => {
553
+ this.positionAllPieces(!1), this.renderCoordinatesLayer();
554
+ });
555
+ e.observe(this.container), this.resizeObserver = e;
556
+ }
557
+ getRendererContext() {
558
+ return {
559
+ boardEl: this.boardElement,
560
+ squaresEl: this.squaresLayer,
561
+ piecesEl: this.piecesLayer,
562
+ coordsEl: this.coordinatesLayer,
563
+ squareSize: this.squareSize(),
564
+ orientation: this.orientation,
565
+ pieceSet: this.pieceSetName,
566
+ theme: this.themeName
567
+ };
568
+ }
569
+ emit(e, t) {
570
+ this.emitter.emit(e, t);
571
+ const i = {
572
+ move: "onMove",
573
+ drop: "onDrop",
574
+ dragstart: "onDragStart",
575
+ dragend: "onDragEnd",
576
+ squareclick: "onSquareClick",
577
+ positionchange: "onPositionChange",
578
+ boardflip: "onBoardFlip",
579
+ promotion: "onPromotion"
580
+ }, r = this.options[i[e]];
581
+ r == null || r(t);
582
+ }
583
+ getSquareFromEventTarget(e) {
584
+ var t;
585
+ return e instanceof HTMLElement ? ((t = e.closest("[data-square]")) == null ? void 0 : t.getAttribute("data-square")) ?? null : null;
586
+ }
587
+ getPieceFromSquare(e) {
588
+ return this.piecesBySquare.get(e);
589
+ }
590
+ getLegalTargets(e) {
591
+ return this.chess.moves({ square: e, verbose: !0 }).map((t) => t.to);
592
+ }
593
+ clearSelection() {
594
+ this.selection.square = null, this.selection.legalTargets = [], this.render();
595
+ }
596
+ setSelection(e) {
597
+ this.selection.square = e, this.selection.legalTargets = e && this.legalMovesEnabled ? this.getLegalTargets(e) : [], this.focusedSquare = e ?? this.focusedSquare, this.render();
598
+ }
599
+ performMove(e) {
600
+ const t = this.chess.get(e.from);
601
+ if (!t)
602
+ return null;
603
+ const i = this.resolvePromotion(t, e.from, e.to, e.promotion), r = i === void 0 ? { from: e.from, to: e.to } : { from: e.from, to: e.to, promotion: i }, s = this.chess.move(r);
604
+ if (!s)
605
+ return null;
606
+ this.lastMove = { from: e.from, to: e.to }, this.selection.square = null, this.selection.legalTargets = [], this.syncPieceStateFromMove(s, i);
607
+ const n = {
608
+ from: s.from,
609
+ to: s.to,
610
+ san: s.san,
611
+ piece: s.piece,
612
+ color: s.color,
613
+ fen: this.getFEN()
614
+ };
615
+ return s.promotion && (n.promotion = s.promotion), this.emit("move", n), this.emit("drop", { ...n, accepted: !0 }), this.emit("positionchange", { fen: this.getFEN() }), this.render(), s;
616
+ }
617
+ syncPieceStateFromMove(e, t) {
618
+ var h, l;
619
+ const i = this.piecesBySquare.get(e.from);
620
+ if (!i) {
621
+ this.syncFromChess();
622
+ return;
623
+ }
624
+ const r = this.piecesBySquare.get(e.to), s = e.flags.includes("e") ? `${e.to[0]}${e.from[1]}` : null, n = s ? this.piecesBySquare.get(s) : void 0;
625
+ this.piecesBySquare.delete(e.from), i.square = e.to, i.piece = {
626
+ ...i.piece,
627
+ type: t ?? i.piece.type
628
+ }, this.piecesBySquare.set(e.to, i), this.pieceIdsBySquare.delete(e.from), this.pieceIdsBySquare.set(e.to, i.id), r && r.id !== i.id && (this.piecesBySquare.delete(e.to), (h = this.pieceElements.get(r.id)) == null || h.remove(), this.pieceElements.delete(r.id)), n && s && (this.piecesBySquare.delete(s), (l = this.pieceElements.get(n.id)) == null || l.remove(), this.pieceElements.delete(n.id));
629
+ }
630
+ resolvePromotion(e, t, i, r) {
631
+ var h, l;
632
+ if (r)
633
+ return r;
634
+ if (e.type !== "p" || !Z(e.color, i))
635
+ return;
636
+ const s = {
637
+ from: t,
638
+ to: i,
639
+ piece: e.type,
640
+ color: e.color
641
+ };
642
+ return ((l = (h = this.options).onPromotion) == null ? void 0 : l.call(h, s)) ?? "q";
643
+ }
644
+ }
645
+ export {
646
+ W as Chessboard,
647
+ S as getBoardTheme,
648
+ H as getPieceSet,
649
+ z as listBoardThemes,
650
+ O as registerBoardTheme,
651
+ D as registerPieceSet
652
+ };
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "chessboard-kit",
3
+ "version": "0.1.0",
4
+ "description": "Modern TypeScript chessboard library with SVG themes, pieces, animations, and framework-friendly DOM rendering.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "dist/index.cjs",
8
+ "module": "dist/index.js",
9
+ "types": "dist/index.d.ts",
10
+ "files": [
11
+ "dist",
12
+ "README.md",
13
+ "LICENSE"
14
+ ],
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "import": "./dist/index.js",
19
+ "require": "./dist/index.cjs"
20
+ },
21
+ "./style.css": "./dist/style.css",
22
+ "./package.json": "./package.json"
23
+ },
24
+ "sideEffects": [
25
+ "**/*.css"
26
+ ],
27
+ "scripts": {
28
+ "build": "tsc -p tsconfig.build.json && vite build",
29
+ "dev": "vite",
30
+ "typecheck": "tsc -p tsconfig.json --noEmit",
31
+ "lint": "eslint . --ext .ts,.tsx",
32
+ "format": "prettier --write .",
33
+ "format:check": "prettier --check .",
34
+ "test": "vitest run",
35
+ "test:watch": "vitest",
36
+ "preview": "vite preview"
37
+ },
38
+ "dependencies": {
39
+ "chess.js": "^1.4.0"
40
+ },
41
+ "devDependencies": {
42
+ "@eslint/js": "^9.30.1",
43
+ "@types/node": "^22.15.21",
44
+ "@typescript-eslint/eslint-plugin": "^8.37.0",
45
+ "@typescript-eslint/parser": "^8.37.0",
46
+ "@vitest/coverage-v8": "^3.2.4",
47
+ "eslint": "^9.30.1",
48
+ "eslint-config-prettier": "^10.1.5",
49
+ "jsdom": "^26.1.0",
50
+ "prettier": "^3.5.3",
51
+ "typescript": "^5.8.3",
52
+ "vite": "^6.3.5",
53
+ "vitest": "^3.2.4"
54
+ }
55
+ }