kokopu-react 1.11.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (526) hide show
  1. package/.eslintrc.yml +84 -0
  2. package/.nycrc.yml +0 -1
  3. package/README.md +1 -1
  4. package/{src/css/chessboard.css → dist/lib/chessboard/Chessboard.css} +2 -2
  5. package/dist/lib/chessboard/Chessboard.d.ts +171 -0
  6. package/dist/lib/chessboard/Chessboard.js +365 -0
  7. package/dist/lib/chessboard/Chessboard.js.map +1 -0
  8. package/dist/lib/chessboard/ChessboardImpl.d.ts +119 -0
  9. package/dist/lib/chessboard/ChessboardImpl.js +471 -0
  10. package/dist/lib/chessboard/ChessboardImpl.js.map +1 -0
  11. package/dist/lib/chessboard/Draggable.d.ts +62 -0
  12. package/dist/lib/chessboard/Draggable.js +157 -0
  13. package/dist/lib/chessboard/Draggable.js.map +1 -0
  14. package/dist/lib/chessboard/Motion.d.ts +28 -0
  15. package/dist/lib/chessboard/Motion.js +74 -0
  16. package/dist/lib/chessboard/Motion.js.map +1 -0
  17. package/dist/lib/chessboard/colorsets.d.ts +5 -0
  18. package/dist/lib/{impl → chessboard}/colorsets.js +43 -47
  19. package/dist/lib/chessboard/colorsets.js.map +1 -0
  20. package/dist/lib/chessboard/piecesets.d.ts +5 -0
  21. package/dist/lib/chessboard/piecesets.js +214 -0
  22. package/dist/lib/chessboard/piecesets.js.map +1 -0
  23. package/dist/lib/{sprites → chessboard/sprites}/cburnett-bb.png +0 -0
  24. package/dist/lib/{sprites → chessboard/sprites}/cburnett-bk.png +0 -0
  25. package/dist/lib/{sprites → chessboard/sprites}/cburnett-bn.png +0 -0
  26. package/dist/lib/{sprites → chessboard/sprites}/cburnett-bp.png +0 -0
  27. package/dist/lib/{sprites → chessboard/sprites}/cburnett-bq.png +0 -0
  28. package/dist/lib/{sprites → chessboard/sprites}/cburnett-br.png +0 -0
  29. package/dist/lib/{sprites → chessboard/sprites}/cburnett-bx.png +0 -0
  30. package/dist/lib/{sprites → chessboard/sprites}/cburnett-wb.png +0 -0
  31. package/dist/lib/{sprites → chessboard/sprites}/cburnett-wk.png +0 -0
  32. package/dist/lib/{sprites → chessboard/sprites}/cburnett-wn.png +0 -0
  33. package/dist/lib/{sprites → chessboard/sprites}/cburnett-wp.png +0 -0
  34. package/dist/lib/{sprites → chessboard/sprites}/cburnett-wq.png +0 -0
  35. package/dist/lib/{sprites → chessboard/sprites}/cburnett-wr.png +0 -0
  36. package/dist/lib/{sprites → chessboard/sprites}/cburnett-wx.png +0 -0
  37. package/dist/lib/{sprites → chessboard/sprites}/celtic-bb.png +0 -0
  38. package/dist/lib/{sprites → chessboard/sprites}/celtic-bk.png +0 -0
  39. package/dist/lib/{sprites → chessboard/sprites}/celtic-bn.png +0 -0
  40. package/dist/lib/{sprites → chessboard/sprites}/celtic-bp.png +0 -0
  41. package/dist/lib/{sprites → chessboard/sprites}/celtic-bq.png +0 -0
  42. package/dist/lib/{sprites → chessboard/sprites}/celtic-br.png +0 -0
  43. package/dist/lib/{sprites → chessboard/sprites}/celtic-bx.png +0 -0
  44. package/dist/lib/{sprites → chessboard/sprites}/celtic-wb.png +0 -0
  45. package/dist/lib/{sprites → chessboard/sprites}/celtic-wk.png +0 -0
  46. package/dist/lib/{sprites → chessboard/sprites}/celtic-wn.png +0 -0
  47. package/dist/lib/{sprites → chessboard/sprites}/celtic-wp.png +0 -0
  48. package/dist/lib/{sprites → chessboard/sprites}/celtic-wq.png +0 -0
  49. package/dist/lib/{sprites → chessboard/sprites}/celtic-wr.png +0 -0
  50. package/dist/lib/{sprites → chessboard/sprites}/celtic-wx.png +0 -0
  51. package/dist/lib/{sprites → chessboard/sprites}/eyes-bb.png +0 -0
  52. package/dist/lib/{sprites → chessboard/sprites}/eyes-bk.png +0 -0
  53. package/dist/lib/{sprites → chessboard/sprites}/eyes-bn.png +0 -0
  54. package/dist/lib/{sprites → chessboard/sprites}/eyes-bp.png +0 -0
  55. package/dist/lib/{sprites → chessboard/sprites}/eyes-bq.png +0 -0
  56. package/dist/lib/{sprites → chessboard/sprites}/eyes-br.png +0 -0
  57. package/dist/lib/{sprites → chessboard/sprites}/eyes-spatial-bx.png +0 -0
  58. package/dist/lib/{sprites → chessboard/sprites}/eyes-spatial-wx.png +0 -0
  59. package/dist/lib/{sprites → chessboard/sprites}/eyes-wb.png +0 -0
  60. package/dist/lib/{sprites → chessboard/sprites}/eyes-wk.png +0 -0
  61. package/dist/lib/{sprites → chessboard/sprites}/eyes-wn.png +0 -0
  62. package/dist/lib/{sprites → chessboard/sprites}/eyes-wp.png +0 -0
  63. package/dist/lib/{sprites → chessboard/sprites}/eyes-wq.png +0 -0
  64. package/dist/lib/{sprites → chessboard/sprites}/eyes-wr.png +0 -0
  65. package/dist/lib/{sprites → chessboard/sprites}/fantasy-bb.png +0 -0
  66. package/dist/lib/{sprites → chessboard/sprites}/fantasy-bk.png +0 -0
  67. package/dist/lib/{sprites → chessboard/sprites}/fantasy-bn.png +0 -0
  68. package/dist/lib/{sprites → chessboard/sprites}/fantasy-bp.png +0 -0
  69. package/dist/lib/{sprites → chessboard/sprites}/fantasy-bq.png +0 -0
  70. package/dist/lib/{sprites → chessboard/sprites}/fantasy-br.png +0 -0
  71. package/dist/lib/{sprites → chessboard/sprites}/fantasy-bx.png +0 -0
  72. package/dist/lib/{sprites → chessboard/sprites}/fantasy-wb.png +0 -0
  73. package/dist/lib/{sprites → chessboard/sprites}/fantasy-wk.png +0 -0
  74. package/dist/lib/{sprites → chessboard/sprites}/fantasy-wn.png +0 -0
  75. package/dist/lib/{sprites → chessboard/sprites}/fantasy-wp.png +0 -0
  76. package/dist/lib/{sprites → chessboard/sprites}/fantasy-wq.png +0 -0
  77. package/dist/lib/{sprites → chessboard/sprites}/fantasy-wr.png +0 -0
  78. package/dist/lib/{sprites → chessboard/sprites}/fantasy-wx.png +0 -0
  79. package/dist/lib/{sprites → chessboard/sprites}/skulls-bb.png +0 -0
  80. package/dist/lib/{sprites → chessboard/sprites}/skulls-bk.png +0 -0
  81. package/dist/lib/{sprites → chessboard/sprites}/skulls-bn.png +0 -0
  82. package/dist/lib/{sprites → chessboard/sprites}/skulls-bp.png +0 -0
  83. package/dist/lib/{sprites → chessboard/sprites}/skulls-bq.png +0 -0
  84. package/dist/lib/{sprites → chessboard/sprites}/skulls-br.png +0 -0
  85. package/dist/lib/{sprites → chessboard/sprites}/skulls-bx.png +0 -0
  86. package/dist/lib/{sprites → chessboard/sprites}/skulls-wb.png +0 -0
  87. package/dist/lib/{sprites → chessboard/sprites}/skulls-wk.png +0 -0
  88. package/dist/lib/{sprites → chessboard/sprites}/skulls-wn.png +0 -0
  89. package/dist/lib/{sprites → chessboard/sprites}/skulls-wp.png +0 -0
  90. package/dist/lib/{sprites → chessboard/sprites}/skulls-wq.png +0 -0
  91. package/dist/lib/{sprites → chessboard/sprites}/skulls-wr.png +0 -0
  92. package/dist/lib/{sprites → chessboard/sprites}/skulls-wx.png +0 -0
  93. package/dist/lib/{sprites → chessboard/sprites}/spatial-bb.png +0 -0
  94. package/dist/lib/{sprites → chessboard/sprites}/spatial-bk.png +0 -0
  95. package/dist/lib/{sprites → chessboard/sprites}/spatial-bn.png +0 -0
  96. package/dist/lib/{sprites → chessboard/sprites}/spatial-bp.png +0 -0
  97. package/dist/lib/{sprites → chessboard/sprites}/spatial-bq.png +0 -0
  98. package/dist/lib/{sprites → chessboard/sprites}/spatial-br.png +0 -0
  99. package/dist/lib/{sprites → chessboard/sprites}/spatial-wb.png +0 -0
  100. package/dist/lib/{sprites → chessboard/sprites}/spatial-wk.png +0 -0
  101. package/dist/lib/{sprites → chessboard/sprites}/spatial-wn.png +0 -0
  102. package/dist/lib/{sprites → chessboard/sprites}/spatial-wp.png +0 -0
  103. package/dist/lib/{sprites → chessboard/sprites}/spatial-wq.png +0 -0
  104. package/dist/lib/{sprites → chessboard/sprites}/spatial-wr.png +0 -0
  105. package/dist/lib/{css/error_box.css → errorbox/ErrorBox.css} +2 -2
  106. package/dist/lib/errorbox/ErrorBox.d.ts +28 -0
  107. package/dist/lib/errorbox/ErrorBox.js +84 -0
  108. package/dist/lib/errorbox/ErrorBox.js.map +1 -0
  109. package/dist/lib/exception.d.ts +18 -0
  110. package/dist/lib/exception.js +40 -0
  111. package/dist/lib/exception.js.map +1 -0
  112. package/dist/lib/i18n.d.ts +18 -0
  113. package/dist/lib/i18n.js +20 -33
  114. package/dist/lib/i18n.js.map +1 -0
  115. package/{src/css/symbol.css → dist/lib/icons/AnnotationSymbolShape.css} +2 -2
  116. package/dist/lib/icons/AnnotationSymbolShape.d.ts +30 -0
  117. package/dist/lib/{impl/ArrowTip.js → icons/AnnotationSymbolShape.js} +21 -35
  118. package/dist/lib/icons/AnnotationSymbolShape.js.map +1 -0
  119. package/dist/lib/icons/ArrowMarkerIcon.d.ts +20 -0
  120. package/dist/lib/icons/ArrowMarkerIcon.js +53 -0
  121. package/dist/lib/icons/ArrowMarkerIcon.js.map +1 -0
  122. package/dist/lib/icons/ArrowTip.d.ts +16 -0
  123. package/dist/lib/icons/ArrowTip.js +29 -0
  124. package/dist/lib/icons/ArrowTip.js.map +1 -0
  125. package/dist/lib/icons/SquareMarkerIcon.d.ts +18 -0
  126. package/{src/i18n.js → dist/lib/icons/SquareMarkerIcon.js} +24 -23
  127. package/dist/lib/icons/SquareMarkerIcon.js.map +1 -0
  128. package/dist/lib/icons/TextMarkerIcon.d.ts +23 -0
  129. package/dist/lib/icons/TextMarkerIcon.js +45 -0
  130. package/dist/lib/icons/TextMarkerIcon.js.map +1 -0
  131. package/{src/css → dist/lib/icons}/arrow.css +2 -2
  132. package/dist/lib/index.d.ts +10 -0
  133. package/dist/lib/index.js +31 -105
  134. package/dist/lib/index.js.map +1 -0
  135. package/dist/lib/{css/movetext.css → movetext/Movetext.css} +2 -2
  136. package/dist/lib/movetext/Movetext.d.ts +136 -0
  137. package/dist/lib/movetext/Movetext.js +167 -0
  138. package/dist/lib/movetext/Movetext.js.map +1 -0
  139. package/dist/lib/movetext/MovetextImpl.d.ts +85 -0
  140. package/dist/lib/movetext/MovetextImpl.js +411 -0
  141. package/dist/lib/movetext/MovetextImpl.js.map +1 -0
  142. package/dist/lib/{fonts → movetext/fonts}/chessalpha.woff +0 -0
  143. package/dist/lib/{fonts → movetext/fonts}/chessalpha.woff2 +0 -0
  144. package/dist/lib/{css → movetext}/fonts.css +4 -4
  145. package/dist/lib/movetext/htmlFilter.d.ts +7 -0
  146. package/dist/lib/movetext/htmlFilter.js +169 -0
  147. package/dist/lib/movetext/htmlFilter.js.map +1 -0
  148. package/dist/lib/movetext/moveFormatter.d.ts +20 -0
  149. package/dist/lib/movetext/moveFormatter.js +93 -0
  150. package/dist/lib/movetext/moveFormatter.js.map +1 -0
  151. package/dist/lib/sanitization.d.ts +6 -0
  152. package/dist/lib/sanitization.js +39 -0
  153. package/dist/lib/sanitization.js.map +1 -0
  154. package/dist/lib/types.d.ts +151 -0
  155. package/dist/lib/types.js +162 -0
  156. package/dist/lib/types.js.map +1 -0
  157. package/dist/lib/util.d.ts +2 -0
  158. package/dist/lib/util.js +36 -0
  159. package/dist/lib/util.js.map +1 -0
  160. package/doc_src/demo/{PageChessboardBase.js → PageChessboardBase.tsx} +30 -24
  161. package/doc_src/demo/{PageChessboardInteraction.js → PageChessboardInteraction.tsx} +95 -66
  162. package/doc_src/demo/{PageChessboardMove.js → PageChessboardMove.tsx} +66 -54
  163. package/doc_src/demo/{PageChessboardSmallScreens.js → PageChessboardSmallScreens.tsx} +23 -14
  164. package/doc_src/demo/{PageMovetextBase.js → PageMovetextBase.tsx} +62 -49
  165. package/doc_src/demo/{PageMovetextInteraction.js → PageMovetextInteraction.tsx} +58 -43
  166. package/doc_src/demo/decs.d.ts +31 -0
  167. package/doc_src/demo/demo.css +2 -2
  168. package/doc_src/demo/{util.js → util.ts} +3 -3
  169. package/doc_src/migrate_to_2.md +26 -0
  170. package/doc_src/theming/LogoRenderer.js +5 -5
  171. package/doc_src/theming/theming.css +8 -2
  172. package/package.json +31 -24
  173. package/scripts/docker-compose.yml +1 -1
  174. package/scripts/test-graphic.tsconfig.json +7 -0
  175. package/scripts/test-graphic.webpack.config.js +33 -17
  176. package/scripts/test-headless.webpack.config.js +6 -10
  177. package/{dist/lib/css/chessboard.css → src/chessboard/Chessboard.css} +2 -2
  178. package/src/chessboard/Chessboard.tsx +575 -0
  179. package/src/chessboard/ChessboardImpl.tsx +632 -0
  180. package/src/chessboard/Draggable.tsx +252 -0
  181. package/src/{impl/Motion.js → chessboard/Motion.tsx} +37 -27
  182. package/src/chessboard/colorsets.ts +134 -0
  183. package/src/chessboard/piecesets.ts +229 -0
  184. package/src/{sprites → chessboard/sprites}/cburnett-bb.png +0 -0
  185. package/src/{sprites → chessboard/sprites}/cburnett-bk.png +0 -0
  186. package/src/{sprites → chessboard/sprites}/cburnett-bn.png +0 -0
  187. package/src/{sprites → chessboard/sprites}/cburnett-bp.png +0 -0
  188. package/src/{sprites → chessboard/sprites}/cburnett-bq.png +0 -0
  189. package/src/{sprites → chessboard/sprites}/cburnett-br.png +0 -0
  190. package/src/{sprites → chessboard/sprites}/cburnett-bx.png +0 -0
  191. package/src/{sprites → chessboard/sprites}/cburnett-wb.png +0 -0
  192. package/src/{sprites → chessboard/sprites}/cburnett-wk.png +0 -0
  193. package/src/{sprites → chessboard/sprites}/cburnett-wn.png +0 -0
  194. package/src/{sprites → chessboard/sprites}/cburnett-wp.png +0 -0
  195. package/src/{sprites → chessboard/sprites}/cburnett-wq.png +0 -0
  196. package/src/{sprites → chessboard/sprites}/cburnett-wr.png +0 -0
  197. package/src/{sprites → chessboard/sprites}/cburnett-wx.png +0 -0
  198. package/src/{sprites → chessboard/sprites}/celtic-bb.png +0 -0
  199. package/src/{sprites → chessboard/sprites}/celtic-bk.png +0 -0
  200. package/src/{sprites → chessboard/sprites}/celtic-bn.png +0 -0
  201. package/src/{sprites → chessboard/sprites}/celtic-bp.png +0 -0
  202. package/src/{sprites → chessboard/sprites}/celtic-bq.png +0 -0
  203. package/src/{sprites → chessboard/sprites}/celtic-br.png +0 -0
  204. package/src/{sprites → chessboard/sprites}/celtic-bx.png +0 -0
  205. package/src/{sprites → chessboard/sprites}/celtic-wb.png +0 -0
  206. package/src/{sprites → chessboard/sprites}/celtic-wk.png +0 -0
  207. package/src/{sprites → chessboard/sprites}/celtic-wn.png +0 -0
  208. package/src/{sprites → chessboard/sprites}/celtic-wp.png +0 -0
  209. package/src/{sprites → chessboard/sprites}/celtic-wq.png +0 -0
  210. package/src/{sprites → chessboard/sprites}/celtic-wr.png +0 -0
  211. package/src/{sprites → chessboard/sprites}/celtic-wx.png +0 -0
  212. package/src/{sprites → chessboard/sprites}/eyes-bb.png +0 -0
  213. package/src/{sprites → chessboard/sprites}/eyes-bk.png +0 -0
  214. package/src/{sprites → chessboard/sprites}/eyes-bn.png +0 -0
  215. package/src/{sprites → chessboard/sprites}/eyes-bp.png +0 -0
  216. package/src/{sprites → chessboard/sprites}/eyes-bq.png +0 -0
  217. package/src/{sprites → chessboard/sprites}/eyes-br.png +0 -0
  218. package/src/{sprites → chessboard/sprites}/eyes-spatial-bx.png +0 -0
  219. package/src/{sprites → chessboard/sprites}/eyes-spatial-wx.png +0 -0
  220. package/src/{sprites → chessboard/sprites}/eyes-wb.png +0 -0
  221. package/src/{sprites → chessboard/sprites}/eyes-wk.png +0 -0
  222. package/src/{sprites → chessboard/sprites}/eyes-wn.png +0 -0
  223. package/src/{sprites → chessboard/sprites}/eyes-wp.png +0 -0
  224. package/src/{sprites → chessboard/sprites}/eyes-wq.png +0 -0
  225. package/src/{sprites → chessboard/sprites}/eyes-wr.png +0 -0
  226. package/src/{sprites → chessboard/sprites}/fantasy-bb.png +0 -0
  227. package/src/{sprites → chessboard/sprites}/fantasy-bk.png +0 -0
  228. package/src/{sprites → chessboard/sprites}/fantasy-bn.png +0 -0
  229. package/src/{sprites → chessboard/sprites}/fantasy-bp.png +0 -0
  230. package/src/{sprites → chessboard/sprites}/fantasy-bq.png +0 -0
  231. package/src/{sprites → chessboard/sprites}/fantasy-br.png +0 -0
  232. package/src/{sprites → chessboard/sprites}/fantasy-bx.png +0 -0
  233. package/src/{sprites → chessboard/sprites}/fantasy-wb.png +0 -0
  234. package/src/{sprites → chessboard/sprites}/fantasy-wk.png +0 -0
  235. package/src/{sprites → chessboard/sprites}/fantasy-wn.png +0 -0
  236. package/src/{sprites → chessboard/sprites}/fantasy-wp.png +0 -0
  237. package/src/{sprites → chessboard/sprites}/fantasy-wq.png +0 -0
  238. package/src/{sprites → chessboard/sprites}/fantasy-wr.png +0 -0
  239. package/src/{sprites → chessboard/sprites}/fantasy-wx.png +0 -0
  240. package/src/{sprites → chessboard/sprites}/skulls-bb.png +0 -0
  241. package/src/{sprites → chessboard/sprites}/skulls-bk.png +0 -0
  242. package/src/{sprites → chessboard/sprites}/skulls-bn.png +0 -0
  243. package/src/{sprites → chessboard/sprites}/skulls-bp.png +0 -0
  244. package/src/{sprites → chessboard/sprites}/skulls-bq.png +0 -0
  245. package/src/{sprites → chessboard/sprites}/skulls-br.png +0 -0
  246. package/src/{sprites → chessboard/sprites}/skulls-bx.png +0 -0
  247. package/src/{sprites → chessboard/sprites}/skulls-wb.png +0 -0
  248. package/src/{sprites → chessboard/sprites}/skulls-wk.png +0 -0
  249. package/src/{sprites → chessboard/sprites}/skulls-wn.png +0 -0
  250. package/src/{sprites → chessboard/sprites}/skulls-wp.png +0 -0
  251. package/src/{sprites → chessboard/sprites}/skulls-wq.png +0 -0
  252. package/src/{sprites → chessboard/sprites}/skulls-wr.png +0 -0
  253. package/src/{sprites → chessboard/sprites}/skulls-wx.png +0 -0
  254. package/src/{sprites → chessboard/sprites}/spatial-bb.png +0 -0
  255. package/src/{sprites → chessboard/sprites}/spatial-bk.png +0 -0
  256. package/src/{sprites → chessboard/sprites}/spatial-bn.png +0 -0
  257. package/src/{sprites → chessboard/sprites}/spatial-bp.png +0 -0
  258. package/src/{sprites → chessboard/sprites}/spatial-bq.png +0 -0
  259. package/src/{sprites → chessboard/sprites}/spatial-br.png +0 -0
  260. package/src/{sprites → chessboard/sprites}/spatial-wb.png +0 -0
  261. package/src/{sprites → chessboard/sprites}/spatial-wk.png +0 -0
  262. package/src/{sprites → chessboard/sprites}/spatial-wn.png +0 -0
  263. package/src/{sprites → chessboard/sprites}/spatial-wp.png +0 -0
  264. package/src/{sprites → chessboard/sprites}/spatial-wq.png +0 -0
  265. package/src/{sprites → chessboard/sprites}/spatial-wr.png +0 -0
  266. package/src/decs.d.ts +26 -0
  267. package/src/{css/error_box.css → errorbox/ErrorBox.css} +2 -2
  268. package/src/errorbox/ErrorBox.tsx +129 -0
  269. package/src/exception.ts +51 -0
  270. package/src/i18n.ts +43 -0
  271. package/{dist/lib/css/symbol.css → src/icons/AnnotationSymbolShape.css} +2 -2
  272. package/src/{impl/TextSymbol.js → icons/AnnotationSymbolShape.tsx} +32 -30
  273. package/src/{ArrowMarkerIcon.js → icons/ArrowMarkerIcon.tsx} +39 -36
  274. package/src/{impl/ArrowTip.js → icons/ArrowTip.tsx} +20 -20
  275. package/src/{SquareMarkerIcon.js → icons/SquareMarkerIcon.tsx} +35 -28
  276. package/src/{TextMarkerIcon.js → icons/TextMarkerIcon.tsx} +40 -32
  277. package/{dist/lib/css → src/icons}/arrow.css +2 -2
  278. package/src/index.ts +38 -0
  279. package/src/{css/movetext.css → movetext/Movetext.css} +2 -2
  280. package/src/movetext/Movetext.tsx +278 -0
  281. package/src/movetext/MovetextImpl.tsx +493 -0
  282. package/src/{fonts → movetext/fonts}/chessalpha.woff +0 -0
  283. package/src/{fonts → movetext/fonts}/chessalpha.woff2 +0 -0
  284. package/src/{css → movetext}/fonts.css +4 -4
  285. package/src/movetext/htmlFilter.tsx +188 -0
  286. package/src/{formatmove.js → movetext/moveFormatter.tsx} +39 -26
  287. package/src/sanitization.ts +51 -0
  288. package/src/types.ts +311 -0
  289. package/src/util.ts +39 -0
  290. package/test/.eslintrc.yml +3 -3
  291. package/test/{1_markers.js → 01_types.js} +89 -4
  292. package/test/{2_chessboard_util.js → 02_chessboard_util.js} +16 -7
  293. package/test/{3_marker_icons_graphic.js → 03_error_box_graphic.js} +20 -14
  294. package/test/04_marker_icons_graphic.js +49 -0
  295. package/test/05_chessboard_graphic.js +92 -0
  296. package/test/06_chessboard_animation.js +71 -0
  297. package/test/07_chessboard_interaction.js +130 -0
  298. package/test/08_chessboard_play_moves.js +98 -0
  299. package/test/{7_movetext_graphic.js → 09_movetext_graphic.js} +32 -16
  300. package/test/{8_movetext_interaction.js → 10_movetext_interaction.js} +18 -23
  301. package/test/common/graphic.js +67 -33
  302. package/test/graphic_references/03_error_box_graphic/base/cut_beginning_of_text.png +0 -0
  303. package/test/graphic_references/03_error_box_graphic/base/cut_end_of_text.png +0 -0
  304. package/test/graphic_references/03_error_box_graphic/base/cut_on_line_breaks.png +0 -0
  305. package/test/graphic_references/03_error_box_graphic/base/error_index_not_integer.png +0 -0
  306. package/test/graphic_references/03_error_box_graphic/base/full.png +0 -0
  307. package/test/graphic_references/03_error_box_graphic/base/minimal.png +0 -0
  308. package/test/graphic_references/03_error_box_graphic/base/missing_error_index.png +0 -0
  309. package/test/graphic_references/03_error_box_graphic/base/missing_error_text.png +0 -0
  310. package/test/graphic_references/03_error_box_graphic/base/negative_error_index.png +0 -0
  311. package/test/graphic_references/03_error_box_graphic/base/single_character_text.png +0 -0
  312. package/test/graphic_references/03_error_box_graphic/base/too_large_error_index.png +0 -0
  313. package/test/graphic_references/03_error_box_graphic/localization/default.png +0 -0
  314. package/test/graphic_references/04_marker_icons_graphic/base/colorized_arrow.png +0 -0
  315. package/test/{references/01_marker_icons/1.png → graphic_references/04_marker_icons_graphic/base/colorized_square.png} +0 -0
  316. package/test/graphic_references/04_marker_icons_graphic/base/colorized_symbol.png +0 -0
  317. package/test/graphic_references/04_marker_icons_graphic/base/colorized_text.png +0 -0
  318. package/test/graphic_references/04_marker_icons_graphic/base/default_arrow.png +0 -0
  319. package/test/{references/01_marker_icons/0.png → graphic_references/04_marker_icons_graphic/base/default_square.png} +0 -0
  320. package/test/graphic_references/04_marker_icons_graphic/base/default_text.png +0 -0
  321. package/test/graphic_references/04_marker_icons_graphic/base/invalid_arrow_size.png +0 -0
  322. package/test/graphic_references/04_marker_icons_graphic/base/invalid_square_size.png +0 -0
  323. package/test/graphic_references/04_marker_icons_graphic/base/invalid_symbol.png +0 -0
  324. package/test/graphic_references/04_marker_icons_graphic/base/invalid_text_size.png +0 -0
  325. package/test/graphic_references/04_marker_icons_graphic/base/wrapped_arrow.png +0 -0
  326. package/test/{references/01_marker_icons/2.png → graphic_references/04_marker_icons_graphic/base/wrapped_square.png} +0 -0
  327. package/test/graphic_references/04_marker_icons_graphic/base/wrapped_symbol.png +0 -0
  328. package/test/graphic_references/04_marker_icons_graphic/base/wrapped_text.png +0 -0
  329. package/test/{references/04_chessboard_annotations/4.png → graphic_references/05_chessboard_graphic/annotations/overlap.png} +0 -0
  330. package/test/{references/04_chessboard_annotations/5.png → graphic_references/05_chessboard_graphic/annotations/overlap_and_flip.png} +0 -0
  331. package/test/{references/04_chessboard_annotations/0.png → graphic_references/05_chessboard_graphic/annotations/with_coordinates.png} +0 -0
  332. package/test/{references/04_chessboard_annotations/1.png → graphic_references/05_chessboard_graphic/annotations/with_coordinates_and_flip.png} +0 -0
  333. package/test/{references/04_chessboard_annotations/2.png → graphic_references/05_chessboard_graphic/annotations/without_coordinates.png} +0 -0
  334. package/test/{references/04_chessboard_annotations/3.png → graphic_references/05_chessboard_graphic/annotations/without_coordinates_and_flip.png} +0 -0
  335. package/test/{references/02_chessboard_simple/0.png → graphic_references/05_chessboard_graphic/base/default.png} +0 -0
  336. package/test/{references/02_chessboard_simple/1.png → graphic_references/05_chessboard_graphic/base/empty.png} +0 -0
  337. package/test/{references/02_chessboard_simple/3.png → graphic_references/05_chessboard_graphic/base/from_fen.png} +0 -0
  338. package/test/{references/02_chessboard_simple/4.png → graphic_references/05_chessboard_graphic/base/from_kokopu_object.png} +0 -0
  339. package/test/{references/02_chessboard_simple/2.png → graphic_references/05_chessboard_graphic/base/parsing_error.png} +0 -0
  340. package/test/graphic_references/05_chessboard_graphic/base/wrong_position_type.png +0 -0
  341. package/test/graphic_references/05_chessboard_graphic/chess_variants/chess960.png +0 -0
  342. package/test/graphic_references/05_chessboard_graphic/chess_variants/chess960_with_move.png +0 -0
  343. package/test/graphic_references/05_chessboard_graphic/chess_variants/invalid_variant.png +0 -0
  344. package/test/graphic_references/05_chessboard_graphic/chess_variants/invalid_variant_with_fen.png +0 -0
  345. package/test/graphic_references/05_chessboard_graphic/chess_variants/special_code.png +0 -0
  346. package/test/graphic_references/05_chessboard_graphic/chess_variants/variant_with_std_initial_position.png +0 -0
  347. package/test/{references/03_chessboard_flipped/2.png → graphic_references/05_chessboard_graphic/chess_variants/variant_without_std_initial_position.png} +0 -0
  348. package/test/{references/03_chessboard_flipped/0.png → graphic_references/05_chessboard_graphic/flipped/default.png} +0 -0
  349. package/test/{references/03_chessboard_flipped/1.png → graphic_references/05_chessboard_graphic/flipped/empty.png} +0 -0
  350. package/test/{references/03_chessboard_flipped/3.png → graphic_references/05_chessboard_graphic/flipped/from_fen.png} +0 -0
  351. package/test/{references/03_chessboard_flipped/4.png → graphic_references/05_chessboard_graphic/flipped/from_kokopu_object.png} +0 -0
  352. package/test/graphic_references/05_chessboard_graphic/flipped/parsing_error.png +0 -0
  353. package/test/{references/05_chessboard_move/4.png → graphic_references/05_chessboard_graphic/move/capture.png} +0 -0
  354. package/test/{references/05_chessboard_move/5.png → graphic_references/05_chessboard_graphic/move/castling_move.png} +0 -0
  355. package/test/{references/05_chessboard_move/0.png → graphic_references/05_chessboard_graphic/move/default.png} +0 -0
  356. package/test/{references/05_chessboard_move/6.png → graphic_references/05_chessboard_graphic/move/en-passant.png} +0 -0
  357. package/test/{references/05_chessboard_move/1.png → graphic_references/05_chessboard_graphic/move/no_move_arrow.png} +0 -0
  358. package/test/{references/05_chessboard_move/2.png → graphic_references/05_chessboard_graphic/move/parsing_error.png} +0 -0
  359. package/test/{references/05_chessboard_move/7.png → graphic_references/05_chessboard_graphic/move/promotion.png} +0 -0
  360. package/test/{references/05_chessboard_move/3.png → graphic_references/05_chessboard_graphic/move/with_forced_move_arrow_and_flip.png} +0 -0
  361. package/test/graphic_references/05_chessboard_graphic/move/wrong_move_arrow_color_type.png +0 -0
  362. package/test/graphic_references/05_chessboard_graphic/move/wrong_move_type.png +0 -0
  363. package/test/{references/07_chessboard_theme/3.png → graphic_references/05_chessboard_graphic/theme/custom_1.png} +0 -0
  364. package/test/{references/07_chessboard_theme/4.png → graphic_references/05_chessboard_graphic/theme/custom_2.png} +0 -0
  365. package/test/{references/07_chessboard_theme/5.png → graphic_references/05_chessboard_graphic/theme/custom_3.png} +0 -0
  366. package/test/{references/07_chessboard_theme/6.png → graphic_references/05_chessboard_graphic/theme/custom_4.png} +0 -0
  367. package/test/{references/07_chessboard_theme/7.png → graphic_references/05_chessboard_graphic/theme/custom_5.png} +0 -0
  368. package/test/{references/07_chessboard_theme/8.png → graphic_references/05_chessboard_graphic/theme/custom_6.png} +0 -0
  369. package/test/{references/07_chessboard_theme/0.png → graphic_references/05_chessboard_graphic/theme/default.png} +0 -0
  370. package/test/{references/07_chessboard_theme/1.png → graphic_references/05_chessboard_graphic/theme/large.png} +0 -0
  371. package/test/{references/07_chessboard_theme/2.png → graphic_references/05_chessboard_graphic/theme/small.png} +0 -0
  372. package/test/graphic_references/05_chessboard_graphic/theme/wrong_colorset.png +0 -0
  373. package/test/graphic_references/05_chessboard_graphic/theme/wrong_pieceset.png +0 -0
  374. package/test/graphic_references/05_chessboard_graphic/theme/wrong_square_size_type.png +0 -0
  375. package/test/{references/06a_chessboard_animated_move/2.png → graphic_references/06_chessboard_animation/base_1/capture.png} +0 -0
  376. package/test/{references/06a_chessboard_animated_move/3.png → graphic_references/06_chessboard_animation/base_1/castling_move.png} +0 -0
  377. package/test/{references/06a_chessboard_animated_move/4.png → graphic_references/06_chessboard_animation/base_1/en-passant.png} +0 -0
  378. package/test/{references/06a_chessboard_animated_move/0.png → graphic_references/06_chessboard_animation/base_1/move_1.png} +0 -0
  379. package/test/{references/06a_chessboard_animated_move/1.png → graphic_references/06_chessboard_animation/base_1/move_2.png} +0 -0
  380. package/test/{references/06a_chessboard_animated_move/5.png → graphic_references/06_chessboard_animation/base_1/promotion.png} +0 -0
  381. package/test/{references/06b_chessboard_animated_move/2.png → graphic_references/06_chessboard_animation/base_2/capture.png} +0 -0
  382. package/test/{references/06b_chessboard_animated_move/3.png → graphic_references/06_chessboard_animation/base_2/castling_move.png} +0 -0
  383. package/test/{references/06b_chessboard_animated_move/4.png → graphic_references/06_chessboard_animation/base_2/en-passant.png} +0 -0
  384. package/test/{references/06b_chessboard_animated_move/0.png → graphic_references/06_chessboard_animation/base_2/move_1.png} +0 -0
  385. package/test/{references/06b_chessboard_animated_move/1.png → graphic_references/06_chessboard_animation/base_2/move_2.png} +0 -0
  386. package/test/{references/06b_chessboard_animated_move/5.png → graphic_references/06_chessboard_animation/base_2/promotion.png} +0 -0
  387. package/test/{references/06c_chessboard_animated_move/2.png → graphic_references/06_chessboard_animation/base_3/capture.png} +0 -0
  388. package/test/{references/06c_chessboard_animated_move/3.png → graphic_references/06_chessboard_animation/base_3/castling_move.png} +0 -0
  389. package/test/{references/06c_chessboard_animated_move/4.png → graphic_references/06_chessboard_animation/base_3/en-passant.png} +0 -0
  390. package/test/{references/06c_chessboard_animated_move/0.png → graphic_references/06_chessboard_animation/base_3/move_1.png} +0 -0
  391. package/test/{references/06c_chessboard_animated_move/1.png → graphic_references/06_chessboard_animation/base_3/move_2.png} +0 -0
  392. package/test/{references/06c_chessboard_animated_move/5.png → graphic_references/06_chessboard_animation/base_3/promotion.png} +0 -0
  393. package/test/graphic_references/06_chessboard_animation/on_redraw/final_state.png +0 -0
  394. package/test/graphic_references/06_chessboard_animation/on_redraw/initial_state.png +0 -0
  395. package/test/{references/10_chessboard_edit_arrows → graphic_references/07_chessboard_interaction/edit_arrows}/base_1.png +0 -0
  396. package/test/{references/10_chessboard_edit_arrows → graphic_references/07_chessboard_interaction/edit_arrows}/base_2.png +0 -0
  397. package/test/{references/10_chessboard_edit_arrows/null_vector.png → graphic_references/07_chessboard_interaction/edit_arrows/from_==_to.png} +0 -0
  398. package/test/{references/10_chessboard_edit_arrows → graphic_references/07_chessboard_interaction/edit_arrows}/out_of_board.png +0 -0
  399. package/test/{references/10_chessboard_edit_arrows → graphic_references/07_chessboard_interaction/edit_arrows}/over_arrow_marker.png +0 -0
  400. package/test/{references/10_chessboard_edit_arrows → graphic_references/07_chessboard_interaction/edit_arrows}/over_square_marker.png +0 -0
  401. package/test/graphic_references/07_chessboard_interaction/error/edit_color_not_set.png +0 -0
  402. package/test/graphic_references/07_chessboard_interaction/error/wrong_interaction_mode.png +0 -0
  403. package/test/{references/09_chessboard_move_pieces → graphic_references/07_chessboard_interaction/move_pieces}/after_move.png +0 -0
  404. package/test/{references/09_chessboard_move_pieces/null_vector.png → graphic_references/07_chessboard_interaction/move_pieces/from_==_to.png} +0 -0
  405. package/test/{references/09_chessboard_move_pieces/empty_square.png → graphic_references/07_chessboard_interaction/move_pieces/move_empty_square.png} +0 -0
  406. package/test/{references/09_chessboard_move_pieces → graphic_references/07_chessboard_interaction/move_pieces}/out_of_board.png +0 -0
  407. package/test/{references/09_chessboard_move_pieces → graphic_references/07_chessboard_interaction/move_pieces}/over_arrow_marker.png +0 -0
  408. package/test/{references/09_chessboard_move_pieces → graphic_references/07_chessboard_interaction/move_pieces}/over_empty.png +0 -0
  409. package/test/{references/09_chessboard_move_pieces/over_non_empty_1.png → graphic_references/07_chessboard_interaction/move_pieces/over_non-empty_1.png} +0 -0
  410. package/test/{references/09_chessboard_move_pieces/over_non_empty_2.png → graphic_references/07_chessboard_interaction/move_pieces/over_non-empty_2.png} +0 -0
  411. package/test/{references/09_chessboard_move_pieces → graphic_references/07_chessboard_interaction/move_pieces}/over_square_marker.png +0 -0
  412. package/test/{references/09_chessboard_move_pieces → graphic_references/07_chessboard_interaction/move_pieces}/over_text_marker.png +0 -0
  413. package/test/{references/11_chessboard_play_moves → graphic_references/08_chessboard_play_moves/base}/castling_move.png +0 -0
  414. package/test/{references/11_chessboard_play_moves → graphic_references/08_chessboard_play_moves/base}/chess960_ambiguous_king_move.png +0 -0
  415. package/test/{references/11_chessboard_play_moves → graphic_references/08_chessboard_play_moves/base}/chess960_castling_move_1.png +0 -0
  416. package/test/{references/11_chessboard_play_moves → graphic_references/08_chessboard_play_moves/base}/chess960_castling_move_2.png +0 -0
  417. package/test/{references/11_chessboard_play_moves/chess960_non_kxr_castling.png → graphic_references/08_chessboard_play_moves/base/chess960_non-kxr_castling.png} +0 -0
  418. package/test/{references/11_chessboard_play_moves/null_vector.png → graphic_references/08_chessboard_play_moves/base/from_==_to.png} +0 -0
  419. package/test/{references/11_chessboard_play_moves → graphic_references/08_chessboard_play_moves/base}/illegal_move.png +0 -0
  420. package/test/{references/11_chessboard_play_moves → graphic_references/08_chessboard_play_moves/base}/illegal_position.png +0 -0
  421. package/test/{references/11_chessboard_play_moves → graphic_references/08_chessboard_play_moves/base}/out_of_board.png +0 -0
  422. package/test/{references/11_chessboard_play_moves → graphic_references/08_chessboard_play_moves/base}/regular_move_1.png +0 -0
  423. package/test/{references/11_chessboard_play_moves → graphic_references/08_chessboard_play_moves/base}/regular_move_2.png +0 -0
  424. package/test/{references/10_chessboard_edit_arrows/edit_color_not_set.png → graphic_references/08_chessboard_play_moves/base/wrong_color_moved.png} +0 -0
  425. package/test/{references/12_chessboard_play_promotions → graphic_references/08_chessboard_play_moves/promotions}/antichess_promotion.png +0 -0
  426. package/test/{references/12_chessboard_play_promotions → graphic_references/08_chessboard_play_moves/promotions}/cancel_promotion.png +0 -0
  427. package/test/{references/12_chessboard_play_promotions → graphic_references/08_chessboard_play_moves/promotions}/regular_promotion_1.png +0 -0
  428. package/test/{references/12_chessboard_play_promotions → graphic_references/08_chessboard_play_moves/promotions}/regular_promotion_2.png +0 -0
  429. package/test/{references/13_movetext_simple/0.png → graphic_references/09_movetext_graphic/base/game_1.png} +0 -0
  430. package/test/{references/13_movetext_simple/1.png → graphic_references/09_movetext_graphic/base/game_2.png} +0 -0
  431. package/test/{references/13_movetext_simple/2.png → graphic_references/09_movetext_graphic/base/game_3.png} +0 -0
  432. package/test/{references/13_movetext_simple/3.png → graphic_references/09_movetext_graphic/base/game_4.png} +0 -0
  433. package/test/{references/14_movetext_error/2.png → graphic_references/09_movetext_graphic/error/pgn_parsing_error_1.png} +0 -0
  434. package/test/{references/14_movetext_error/3.png → graphic_references/09_movetext_graphic/error/pgn_parsing_error_2.png} +0 -0
  435. package/test/{references/14_movetext_error/0.png → graphic_references/09_movetext_graphic/error/wrong_game_index_1.png} +0 -0
  436. package/test/{references/14_movetext_error/1.png → graphic_references/09_movetext_graphic/error/wrong_game_index_2.png} +0 -0
  437. package/test/graphic_references/09_movetext_graphic/error/wrong_game_index_type.png +0 -0
  438. package/test/graphic_references/09_movetext_graphic/error/wrong_game_type.png +0 -0
  439. package/test/{references/15_movetext_html/2.png → graphic_references/09_movetext_graphic/html/filtered_tags_and_attributes.png} +0 -0
  440. package/test/{references/15_movetext_html/1.png → graphic_references/09_movetext_graphic/html/html_in_comments.png} +0 -0
  441. package/test/{references/15_movetext_html/0.png → graphic_references/09_movetext_graphic/html/html_in_headers.png} +0 -0
  442. package/test/{references/16_movetext_options/1.png → graphic_references/09_movetext_graphic/options/custom_piece_symbols.png} +0 -0
  443. package/test/{references/16_movetext_options/2.png → graphic_references/09_movetext_graphic/options/figurine_piece_symbols_and_diagram_options.png} +0 -0
  444. package/test/{references/16_movetext_options/3.png → graphic_references/09_movetext_graphic/options/hidden_diagrams.png} +0 -0
  445. package/test/{references/16_movetext_options/0.png → graphic_references/09_movetext_graphic/options/localized_piece_symbols.png} +0 -0
  446. package/test/graphic_references/09_movetext_graphic/options/wrong_diagram_options_1.png +0 -0
  447. package/test/graphic_references/09_movetext_graphic/options/wrong_diagram_options_2.png +0 -0
  448. package/test/graphic_references/10_movetext_interaction/error/wrong_interaction_mode.png +0 -0
  449. package/test/{references/17_movetext_interaction/0.png → graphic_references/10_movetext_interaction/select_moves/click_on_disabled.png} +0 -0
  450. package/test/{references/17_movetext_interaction/1.png → graphic_references/10_movetext_interaction/select_moves/click_on_unselected.png} +0 -0
  451. package/test/{references/17_movetext_interaction/2.png → graphic_references/10_movetext_interaction/select_moves/click_on_with_variations.png} +0 -0
  452. package/test/graphic_test_app/.eslintrc.yml +5 -0
  453. package/test/graphic_test_app/03_error_box_graphic/base.tsx +46 -0
  454. package/{scripts/clean-graphic-output.js → test/graphic_test_app/03_error_box_graphic/localization.tsx} +10 -7
  455. package/{graphic_test_src/01_marker_icons.js → test/graphic_test_app/04_marker_icons_graphic/base.tsx} +15 -7
  456. package/{graphic_test_src/04_chessboard_annotations.js → test/graphic_test_app/05_chessboard_graphic/annotations.tsx} +23 -14
  457. package/{graphic_test_src/02_chessboard_simple.js → test/graphic_test_app/05_chessboard_graphic/base.tsx} +6 -6
  458. package/test/graphic_test_app/05_chessboard_graphic/chess_variants.tsx +35 -0
  459. package/{graphic_test_src/03_chessboard_flipped.js → test/graphic_test_app/05_chessboard_graphic/flipped.tsx} +5 -5
  460. package/{graphic_test_src/05_chessboard_move.js → test/graphic_test_app/05_chessboard_graphic/move.tsx} +9 -8
  461. package/{graphic_test_src/07_chessboard_theme.js → test/graphic_test_app/05_chessboard_graphic/theme.tsx} +14 -11
  462. package/{graphic_test_src/06a_chessboard_animated_move.js → test/graphic_test_app/06_chessboard_animation/base_1.tsx} +5 -5
  463. package/{graphic_test_src/06b_chessboard_animated_move.js → test/graphic_test_app/06_chessboard_animation/base_2.tsx} +5 -5
  464. package/{graphic_test_src/06c_chessboard_animated_move.js → test/graphic_test_app/06_chessboard_animation/base_3.tsx} +5 -5
  465. package/test/graphic_test_app/06_chessboard_animation/on_redraw.tsx +49 -0
  466. package/{graphic_test_src/08_chessboard_click_squares.js → test/graphic_test_app/07_chessboard_interaction/click_squares.tsx} +7 -6
  467. package/{graphic_test_src/10_chessboard_edit_arrows.js → test/graphic_test_app/07_chessboard_interaction/edit_arrows.tsx} +7 -7
  468. package/test/graphic_test_app/07_chessboard_interaction/error.tsx +30 -0
  469. package/{graphic_test_src/09_chessboard_move_pieces.js → test/graphic_test_app/07_chessboard_interaction/move_pieces.tsx} +7 -6
  470. package/{graphic_test_src/11_chessboard_play_moves.js → test/graphic_test_app/08_chessboard_play_moves/base.tsx} +6 -6
  471. package/{graphic_test_src/12_chessboard_play_promotions.js → test/graphic_test_app/08_chessboard_play_moves/promotions.tsx} +6 -6
  472. package/{graphic_test_src/13_movetext_simple.js → test/graphic_test_app/09_movetext_graphic/base.tsx} +8 -8
  473. package/{graphic_test_src/14_movetext_error.js → test/graphic_test_app/09_movetext_graphic/error.tsx} +10 -9
  474. package/{graphic_test_src/15_movetext_html.js → test/graphic_test_app/09_movetext_graphic/html.tsx} +7 -7
  475. package/{graphic_test_src/16_movetext_options.js → test/graphic_test_app/09_movetext_graphic/options.tsx} +9 -6
  476. package/test/graphic_test_app/10_movetext_interaction/error.tsx +31 -0
  477. package/{graphic_test_src/17_movetext_interaction.js → test/graphic_test_app/10_movetext_interaction/select_moves.tsx} +7 -7
  478. package/test/graphic_test_app/common/decs.d.ts +26 -0
  479. package/{graphic_test_src → test/graphic_test_app}/common/dummy.pgn +0 -0
  480. package/{graphic_test_src → test/graphic_test_app}/common/games.pgn +1 -1
  481. package/{graphic_test_src → test/graphic_test_app}/common/heartbeat.txt +0 -0
  482. package/{graphic_test_src → test/graphic_test_app}/common/smiley.png +0 -0
  483. package/{graphic_test_src → test/graphic_test_app}/common/test_app.css +11 -2
  484. package/{graphic_test_src/common/test_app.js → test/graphic_test_app/common/test_app.tsx} +62 -14
  485. package/tsconfig.json +15 -0
  486. package/.babelrc +0 -3
  487. package/dist/lib/ArrowMarkerIcon.js +0 -85
  488. package/dist/lib/Chessboard.js +0 -1276
  489. package/dist/lib/ErrorBox.js +0 -125
  490. package/dist/lib/Movetext.js +0 -805
  491. package/dist/lib/SquareMarkerIcon.js +0 -69
  492. package/dist/lib/TextMarkerIcon.js +0 -74
  493. package/dist/lib/formatmove.js +0 -107
  494. package/dist/lib/impl/DraggableHandle.js +0 -268
  495. package/dist/lib/impl/HtmlSanitizer.js +0 -145
  496. package/dist/lib/impl/Motion.js +0 -109
  497. package/dist/lib/impl/TextSymbol.js +0 -89
  498. package/dist/lib/impl/piecesets.js +0 -219
  499. package/dist/lib/impl/util.js +0 -71
  500. package/dist/lib/markers.js +0 -144
  501. package/doc_src/.eslintrc.yml +0 -2
  502. package/src/Chessboard.js +0 -1034
  503. package/src/ErrorBox.js +0 -132
  504. package/src/Movetext.js +0 -671
  505. package/src/impl/DraggableHandle.js +0 -232
  506. package/src/impl/HtmlSanitizer.js +0 -126
  507. package/src/impl/colorsets.js +0 -119
  508. package/src/impl/piecesets.js +0 -218
  509. package/src/impl/util.js +0 -68
  510. package/src/index.js +0 -31
  511. package/src/markers.js +0 -115
  512. package/test/4_chessboard_graphic.js +0 -49
  513. package/test/5_chessboard_interaction.js +0 -135
  514. package/test/6_chessboard_play_moves.js +0 -107
  515. package/test/references/01_marker_icons/10.png +0 -0
  516. package/test/references/01_marker_icons/3.png +0 -0
  517. package/test/references/01_marker_icons/4.png +0 -0
  518. package/test/references/01_marker_icons/5.png +0 -0
  519. package/test/references/01_marker_icons/6.png +0 -0
  520. package/test/references/01_marker_icons/7.png +0 -0
  521. package/test/references/01_marker_icons/8.png +0 -0
  522. package/test/references/01_marker_icons/9.png +0 -0
  523. package/test/references/02_chessboard_simple/5.png +0 -0
  524. package/test/references/05_chessboard_move/8.png +0 -0
  525. package/test/references/11_chessboard_play_moves/wrong_color.png +0 -0
  526. package/test/references/14_movetext_error/4.png +0 -0
package/src/Chessboard.js DELETED
@@ -1,1034 +0,0 @@
1
- /******************************************************************************
2
- * *
3
- * This file is part of Kokopu-React, a JavaScript chess library. *
4
- * Copyright (C) 2021-2023 Yoann Le Montagner <yo35 -at- melix.net> *
5
- * *
6
- * This program is free software: you can redistribute it and/or *
7
- * modify it under the terms of the GNU Lesser General Public License *
8
- * as published by the Free Software Foundation, either version 3 of *
9
- * the License, or (at your option) any later version. *
10
- * *
11
- * This program is distributed in the hope that it will be useful, *
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
- * GNU Lesser General Public License for more details. *
15
- * *
16
- * You should have received a copy of the GNU Lesser General *
17
- * Public License along with this program. If not, see *
18
- * <http://www.gnu.org/licenses/>. *
19
- * *
20
- ******************************************************************************/
21
-
22
-
23
- import PropTypes from 'prop-types';
24
- import React from 'react';
25
- import { exception, MoveDescriptor, Position, coordinatesToSquare, forEachSquare, oppositeColor, squareColor, squareToCoordinates } from 'kokopu';
26
-
27
- import colorsets from './impl/colorsets';
28
- import piecesets from './impl/piecesets';
29
- import ArrowTip from './impl/ArrowTip';
30
- import DraggableHandle from './impl/DraggableHandle';
31
- import Motion from './impl/Motion';
32
- import TextSymbol from './impl/TextSymbol';
33
- import ErrorBox from './ErrorBox';
34
- import i18n from './i18n';
35
- import { parseSquareMarkers, parseTextMarkers, parseArrowMarkers } from './markers';
36
- import { MIN_SQUARE_SIZE, MAX_SQUARE_SIZE, sanitizeInteger, generateRandomId, isValidSquare, isValidVector, isValidColor, isValidSymbol } from './impl/util';
37
-
38
- import './css/chessboard.css';
39
- import './css/arrow.css';
40
-
41
- const TURN_FLAG_SPACING_FACTOR = 0.1;
42
- const RANK_COORDINATE_WIDTH_FACTOR = 1;
43
- const FILE_COORDINATE_HEIGHT_FACTOR = 1.4;
44
- const HOVER_MARKER_THICKNESS_FACTOR = 0.1;
45
- const STROKE_THICKNESS_FACTOR = 0.15;
46
- const ARROW_TIP_OFFSET_FACTOR = 0.3;
47
-
48
- const MOTION_DURATION = 150;
49
-
50
- const RANK_LABELS = '12345678';
51
- const FILE_LABELS = 'abcdefgh';
52
-
53
-
54
- /**
55
- * SVG image representing a chessboard diagram. Optionally, the user may interact with the board (move pieces, click on squares...).
56
- * Annotations such as square markers or arrows can also be added to the board.
57
- */
58
- export default class Chessboard extends React.Component {
59
-
60
- constructor(props) {
61
- super(props);
62
- this.state = {
63
- inhibitedSquare: '-',
64
- draggedSquare: '-',
65
- hoveredSquare: '-',
66
- promotionDrawer: false,
67
- windowWidth: window.innerWidth,
68
- };
69
- this.arrowTipIdSuffix = generateRandomId();
70
- }
71
-
72
- componentDidMount() {
73
- this.windowResizeListener = () => this.handleWindowResize();
74
- window.addEventListener('resize', this.windowResizeListener);
75
- }
76
-
77
- componentWillUnmount() {
78
- if (this.windowResizeListener) {
79
- window.removeEventListener('resize', this.windowResizeListener);
80
- this.windowResizeListener = null;
81
- }
82
- }
83
-
84
- render() {
85
-
86
- // Compute the current position.
87
- let info = this.getPositionAndMoveInfo();
88
- if (info.positionError) {
89
- return <ErrorBox title={i18n.INVALID_FEN_ERROR_TITLE} message={info.message} />;
90
- }
91
- else if (info.moveError) {
92
- return <ErrorBox title={i18n.INVALID_NOTATION_ERROR_TITLE} message={info.message} />;
93
- }
94
- let { position, move, positionBefore } = info;
95
-
96
- // Compute the attributes.
97
- let squareSize = this.getSquareSize();
98
- let coordinateVisible = this.isCoordinateVisible();
99
- let fontSize = computeCoordinateFontSize(squareSize);
100
- let colorset = colorsets[this.props.colorset];
101
- let pieceset = piecesets[this.props.pieceset];
102
- if (isNaN(squareSize) || !colorset || !pieceset) {
103
- return undefined;
104
- }
105
-
106
- // Render the squares.
107
- let squares = [];
108
- forEachSquare(sq => squares.push(this.renderSquare(squareSize, colorset, sq)));
109
-
110
- // Render coordinates.
111
- let rankCoordinates = [];
112
- let fileCoordinates = [];
113
- if (coordinateVisible) {
114
- for (let c = 0; c < 8; ++c) {
115
- rankCoordinates.push(this.renderRankCoordinate(squareSize, fontSize, c));
116
- fileCoordinates.push(this.renderFileCoordinate(squareSize, fontSize, c));
117
- }
118
- }
119
-
120
- // Render the whole canvas.
121
- let xmin = coordinateVisible ? Math.round(-RANK_COORDINATE_WIDTH_FACTOR * fontSize) : 0;
122
- let ymin = 0;
123
- let xmax = 9 * squareSize + Math.round(TURN_FLAG_SPACING_FACTOR * squareSize);
124
- let ymax = 8 * squareSize + (coordinateVisible ? Math.round(FILE_COORDINATE_HEIGHT_FACTOR * fontSize) : 0);
125
- let viewBox = `${xmin} ${ymin} ${xmax - xmin} ${ymax - ymin}`;
126
- return (
127
- <svg className="kokopu-chessboard" viewBox={viewBox} width={xmax - xmin} height={ymax - ymin}>
128
- <defs>
129
- {this.renderArrowTip(colorset, 'b')}
130
- {this.renderArrowTip(colorset, 'g')}
131
- {this.renderArrowTip(colorset, 'r')}
132
- {this.renderArrowTip(colorset, 'y')}
133
- </defs>
134
- {squares}
135
- {rankCoordinates}
136
- {fileCoordinates}
137
- {this.renderBoardContent(position, positionBefore, move, squareSize, colorset, pieceset)}
138
- </svg>
139
- );
140
- }
141
-
142
- renderBoardContent(position, positionBefore, move, squareSize, colorset, pieceset) {
143
- if (move && this.props.animated) {
144
- let key = positionBefore.variant() + '|' + positionBefore.fen() + '|' + move.toString();
145
- return (
146
- <Motion key={key} duration={MOTION_DURATION}>
147
- {motionCursor => (motionCursor === 1 ? this.renderBoardContentStill(position, move, squareSize, colorset, pieceset)
148
- : this.renderBoardContentAnimated(positionBefore, move, motionCursor, squareSize, colorset, pieceset))}
149
- </Motion>
150
- );
151
- }
152
- else {
153
- return this.renderBoardContentStill(position, move, squareSize, colorset, pieceset);
154
- }
155
- }
156
-
157
- /**
158
- * Render the board content during the animation.
159
- */
160
- renderBoardContentAnimated(positionBefore, move, motionCursor, squareSize, colorset, pieceset) {
161
- let pieces = [];
162
- forEachSquare(sq => pieces.push(this.renderPieceAnimated(positionBefore, move, motionCursor, squareSize, pieceset, sq)));
163
- return (
164
- <>
165
- {pieces}
166
- {this.renderMoveArrow(move, motionCursor, squareSize, colorset)}
167
- {this.renderTurnFlag(oppositeColor(positionBefore.turn()), squareSize, pieceset)}
168
- </>
169
- );
170
- }
171
-
172
- /**
173
- * Render the board content when the animation has been completed (or if there is no animation).
174
- */
175
- renderBoardContentStill(position, move, squareSize, colorset, pieceset) {
176
-
177
- // Compute the annotations.
178
- let sqm = parseMarkers(this.props.squareMarkers, parseSquareMarkers, isValidSquare, isValidColor);
179
- let txtm = parseMarkers(this.props.textMarkers, parseTextMarkers, isValidSquare, value => value && isValidSymbol(value.symbol) && isValidColor(value.color));
180
- let arm = parseMarkers(this.props.arrowMarkers, parseArrowMarkers, isValidVector, isValidColor);
181
-
182
- // Render the square-related objects.
183
- let pieces = [];
184
- let handles = [];
185
- forEachSquare(sq => {
186
- pieces.push(this.renderPiece(position, squareSize, pieceset, sq));
187
- if (this.props.interactionMode) {
188
- handles.push(this.renderSquareHandle(position, squareSize, sq));
189
- }
190
- });
191
- return (
192
- <>
193
- {this.renderSquareMarkers(sqm, squareSize, colorset)}
194
- {this.renderHoveredSquare(squareSize, colorset)}
195
- {pieces}
196
- {this.renderTextMarkers(txtm, squareSize, colorset)}
197
- {this.renderArrowMarkers(arm, squareSize, colorset)}
198
- {this.renderMoveArrow(move, 1, squareSize, colorset)}
199
- {handles}
200
- {this.renderPromotionDrawer(position, squareSize, colorset, pieceset)}
201
- {this.renderDraggedPiece(position, squareSize, pieceset)}
202
- {this.renderDraggedArrow(squareSize, colorset)}
203
- {this.renderTurnFlag(position.turn(), squareSize, pieceset)}
204
- </>
205
- );
206
- }
207
-
208
- renderSquare(squareSize, colorset, sq) {
209
- let { x, y } = this.getSquareCoordinates(squareSize, sq);
210
- return <rect key={sq} x={x} y={y} width={squareSize} height={squareSize} fill={colorset[squareColor(sq)]} />;
211
- }
212
-
213
- renderHoveredSquare(squareSize, colorset) {
214
- if (this.state.hoveredSquare === '-') {
215
- return undefined;
216
- }
217
- let { x, y } = this.getSquareCoordinates(squareSize, this.state.hoveredSquare);
218
- let thickness = Math.max(2, Math.round(HOVER_MARKER_THICKNESS_FACTOR * squareSize));
219
- let size = squareSize - thickness;
220
- let color = this.isEditArrowModeEnabled() ? this.props.editedArrowColor : this.props.moveArrowColor;
221
- return <rect className="kokopu-hoveredSquare" x={x + thickness/2} y={y + thickness/2} width={size} height={size} stroke={colorset['c' + color]} strokeWidth={thickness} />;
222
- }
223
-
224
- renderPiece(position, squareSize, pieceset, sq) {
225
- let cp = position.square(sq);
226
- if (cp === '-' || this.state.inhibitedSquare === sq) {
227
- return undefined;
228
- }
229
- let { x, y } = this.getSquareCoordinates(squareSize, sq);
230
- return <image key={'piece-' + sq} x={x} y={y} width={squareSize} height={squareSize} href={pieceset[cp]} />;
231
- }
232
-
233
- renderPieceAnimated(positionBefore, move, motionCursor, squareSize, pieceset, sq) {
234
- let cp = positionBefore.square(sq);
235
- if (cp === '-' || move.to() === sq || (move.isEnPassant() && move.enPassantSquare() === sq)) {
236
- return undefined;
237
- }
238
- let { x, y } = this.getSquareCoordinates(squareSize, sq);
239
- if (sq === move.from()) {
240
- let { x: xTo, y: yTo } = this.getSquareCoordinates(squareSize, move.to());
241
- x = xTo * motionCursor + x * (1 - motionCursor);
242
- y = yTo * motionCursor + y * (1 - motionCursor);
243
- if (move.isPromotion() && motionCursor > 0.8) {
244
- cp = move.coloredPromotion();
245
- }
246
- }
247
- else if (move.isCastling() && sq === move.rookFrom()) {
248
- let { x: xTo, y: yTo } = this.getSquareCoordinates(squareSize, move.rookTo());
249
- x = xTo * motionCursor + x * (1 - motionCursor);
250
- y = yTo * motionCursor + y * (1 - motionCursor);
251
- }
252
- return <image key={'piece-' + sq} x={x} y={y} width={squareSize} height={squareSize} href={pieceset[cp]} />;
253
- }
254
-
255
- renderDraggedPiece(position, squareSize, pieceset) {
256
- if (!(this.isMovePieceModeEnabled() || this.isPlayMoveModeEnabled()) || this.state.draggedSquare === '-') {
257
- return undefined;
258
- }
259
- let { x, y } = this.getSquareCoordinates(squareSize, this.state.draggedSquare);
260
- x = Math.min(Math.max(x + this.state.dragPosition.x, 0), 7 * squareSize);
261
- y = Math.min(Math.max(y + this.state.dragPosition.y, 0), 7 * squareSize);
262
- let cp = position.square(this.state.draggedSquare);
263
- return <image className="kokopu-pieceDraggable kokopu-dragging" x={x} y={y} width={squareSize} height={squareSize} href={pieceset[cp]} />;
264
- }
265
-
266
- renderDraggedArrow(squareSize, colorset) {
267
- if (!this.isEditArrowModeEnabled() || this.state.draggedSquare === '-') {
268
- return undefined;
269
- }
270
- let strokeWidth = squareSize * STROKE_THICKNESS_FACTOR;
271
- let arrowTipId = this.getArrowTipId(this.props.editedArrowColor);
272
- let { x, y } = this.getSquareCoordinates(squareSize, this.state.draggedSquare);
273
- let xFrom = x + squareSize / 2;
274
- let yFrom = y + squareSize / 2;
275
- let xTo = Math.min(Math.max(x + this.state.dragPosition.x + this.state.cursorOffset.x, squareSize/2), 15 * squareSize / 2);
276
- let yTo = Math.min(Math.max(y + this.state.dragPosition.y + this.state.cursorOffset.y, squareSize/2), 15 * squareSize / 2);
277
- return (
278
- <line
279
- className="kokopu-annotation kokopu-arrow kokopu-arrowDraggable kokopu-dragging" x1={xFrom} y1={yFrom} x2={xTo} y2={yTo}
280
- stroke={colorset['c' + this.props.editedArrowColor]} strokeWidth={strokeWidth} markerEnd={`url(#${arrowTipId})`}
281
- />
282
- );
283
- }
284
-
285
- renderPromotionDrawer(position, squareSize, colorset, pieceset) {
286
- if (!this.state.promotionDrawer) {
287
- return undefined;
288
- }
289
- let { x, y } = this.getSquareCoordinates(squareSize, this.state.promotionDrawer.origin);
290
- let inverted = position.turn() === (this.props.flipped ? 'w' : 'b'); // false==top-to-bottom true==bottom-to-top
291
- let y0 = inverted ? y - squareSize * (this.state.promotionDrawer.buttons.length - 1) : y;
292
- let buttons = this.state.promotionDrawer.buttons.map((p, i) => {
293
- let cp = position.turn() + p;
294
- return <image key={'drawer-piece-' + p} className="kokopu-clickable" x={x} y={y + i * (inverted ? -squareSize : squareSize)}
295
- width={squareSize} height={squareSize} href={pieceset[cp]} onClick={() => this.handleDrawerButtonClicked(p)} />;
296
- });
297
- return (
298
- <>
299
- <rect className="kokopu-handle" x={0} y={0} width={squareSize * 8} height={squareSize * 8} onClick={() => this.handleDrawerCancelButtonClicked()} />
300
- <rect x={x} y={y0} width={squareSize} height={squareSize * this.state.promotionDrawer.buttons.length} fill={colorset.b} />
301
- <rect x={x} y={y0} width={squareSize} height={squareSize * this.state.promotionDrawer.buttons.length} className="kokopu-drawerMask" fill={colorset.w} />
302
- {buttons}
303
- </>
304
- );
305
- }
306
-
307
- renderSquareHandle(position, squareSize, sq) {
308
- let { x, y } = this.getSquareCoordinates(squareSize, sq);
309
- let dragEnabledForMovePieces = this.isMovePieceModeEnabled() && position.square(sq) !== '-';
310
- let dragEnabledForEditArrows = this.isEditArrowModeEnabled();
311
- let dragEnabledForPlayMoves = this.isPlayMoveModeEnabled() && position.isLegal() && position.square(sq).startsWith(position.turn()) && !this.state.promotionDrawer;
312
- if (dragEnabledForMovePieces || dragEnabledForEditArrows || dragEnabledForPlayMoves) {
313
- return (
314
- <DraggableHandle key={'handle-' + sq} x={x} y={y} width={squareSize} height={squareSize} isArrowHandle={this.isEditArrowModeEnabled()}
315
- onDragStart={(x0, y0) => this.handleDragStart(sq, x0, y0)}
316
- onDrag={(dx, dy) => this.handleDrag(sq, dx, dy)}
317
- onDragStop={(dx, dy) => this.handleDragStop(sq, dx, dy)}
318
- onDragCanceled={() => this.handleDragCanceled()}
319
- />
320
- );
321
- }
322
- else if (this.props.interactionMode === 'clickSquares') {
323
- return (
324
- <rect
325
- key={'handle-' + sq} className="kokopu-handle kokopu-clickable" x={x} y={y} width={squareSize} height={squareSize}
326
- onClick={() => this.handleSquareClicked(sq)}
327
- />
328
- );
329
- }
330
- else {
331
- return undefined;
332
- }
333
- }
334
-
335
- renderSquareMarkers(sqm, squareSize, colorset) {
336
- let result = [];
337
- Object.entries(sqm).forEach(([ sq, color ]) => {
338
- let { x, y } = this.getSquareCoordinates(squareSize, sq);
339
- result.push(<rect key={'sqm-' + sq} className="kokopu-annotation" x={x} y={y} width={squareSize} height={squareSize} fill={colorset['c' + color]} />);
340
- });
341
- return result;
342
- }
343
-
344
- renderTextMarkers(txtm, squareSize, colorset) {
345
- let result = [];
346
- Object.entries(txtm).forEach(([ sq, value ]) => {
347
- let { x, y } = this.getSquareCoordinates(squareSize, sq);
348
- x += squareSize / 2;
349
- y += squareSize / 2;
350
- result.push(
351
- <g key={'txtm-' + sq} className="kokopu-annotation">
352
- <TextSymbol x={x} y={y} size={squareSize} symbol={value.symbol} color={colorset['c' + value.color]} />
353
- </g>
354
- );
355
- });
356
- return result;
357
- }
358
-
359
- renderArrowMarkers(arm, squareSize, colorset) {
360
- let result = [];
361
- let strokeWidth = squareSize * STROKE_THICKNESS_FACTOR;
362
- Object.entries(arm).forEach(([ vect, color ]) => {
363
- let from = vect.substring(0, 2);
364
- let to = vect.substring(2, 4);
365
- if (from === to) {
366
- return;
367
- }
368
- let { x: xFrom, y: yFrom } = this.getSquareCoordinates(squareSize, from);
369
- let { x: xTo, y: yTo } = this.getSquareCoordinates(squareSize, to);
370
- xFrom += squareSize / 2;
371
- yFrom += squareSize / 2;
372
- xTo += squareSize / 2;
373
- yTo += squareSize / 2;
374
- xTo += Math.sign(xFrom - xTo) * ARROW_TIP_OFFSET_FACTOR * squareSize;
375
- yTo += Math.sign(yFrom - yTo) * ARROW_TIP_OFFSET_FACTOR * squareSize;
376
- let arrowTipId = this.getArrowTipId(color);
377
- result.push(
378
- <line
379
- key={'arm-' + vect} className="kokopu-annotation kokopu-arrow" x1={xFrom} y1={yFrom} x2={xTo} y2={yTo}
380
- stroke={colorset['c' + color]} strokeWidth={strokeWidth} markerEnd={`url(#${arrowTipId})`}
381
- />
382
- );
383
- });
384
- return result;
385
- }
386
-
387
- renderMoveArrow(move, motionCursor, squareSize, colorset) {
388
- if (!move || motionCursor < 0.1 || !this.props.moveArrowVisible || move.from() === move.to()) {
389
- return undefined;
390
- }
391
- let { x: xFrom, y: yFrom } = this.getSquareCoordinates(squareSize, move.from());
392
- xFrom += squareSize / 2;
393
- yFrom += squareSize / 2;
394
- let { x: xTo, y: yTo } = this.getSquareCoordinates(squareSize, move.to());
395
- xTo += squareSize / 2;
396
- yTo += squareSize / 2;
397
- xTo += Math.sign(xFrom - xTo) * ARROW_TIP_OFFSET_FACTOR * squareSize;
398
- yTo += Math.sign(yFrom - yTo) * ARROW_TIP_OFFSET_FACTOR * squareSize;
399
- let x = xTo * motionCursor + xFrom * (1 - motionCursor);
400
- let y = yTo * motionCursor + yFrom * (1 - motionCursor);
401
- let color = this.props.moveArrowColor;
402
- return (
403
- <line
404
- className="kokopu-annotation kokopu-arrow" x1={xFrom} y1={yFrom} x2={x} y2={y} stroke={colorset['c' + color]}
405
- strokeWidth={squareSize * STROKE_THICKNESS_FACTOR} markerEnd={`url(#${this.getArrowTipId(color)})`}
406
- />
407
- );
408
- }
409
-
410
- renderArrowTip(colorset, color) {
411
- return <ArrowTip id={this.getArrowTipId(color)} color={colorset['c' + color]} />;
412
- }
413
-
414
- renderTurnFlag(turn, squareSize, pieceset) {
415
- let x = 8 * squareSize + Math.round(TURN_FLAG_SPACING_FACTOR * squareSize);
416
- let y = turn === (this.props.flipped ? 'b' : 'w') ? 7 * squareSize : 0;
417
- return <image key={'turn-' + turn} x={x} y={y} width={squareSize} height={squareSize} href={pieceset[turn + 'x']} />;
418
- }
419
-
420
- renderRankCoordinate(squareSize, fontSize, rank) {
421
- let x = Math.round(-RANK_COORDINATE_WIDTH_FACTOR * fontSize) / 2;
422
- let y = (this.props.flipped ? rank + 0.5 : 7.5 - rank) * squareSize;
423
- let label = RANK_LABELS[rank];
424
- return <text key={'rank-' + label} className="kokopu-coordinate" x={x} y={y} fontSize={fontSize}>{label}</text>;
425
- }
426
-
427
- renderFileCoordinate(squareSize, fontSize, file) {
428
- let x = (this.props.flipped ? 7.5 - file : 0.5 + file) * squareSize;
429
- let y = 8 * squareSize + Math.round(FILE_COORDINATE_HEIGHT_FACTOR * fontSize) / 2;
430
- let label = FILE_LABELS[file];
431
- return <text key={'file-' + label} className="kokopu-coordinate" x={x} y={y} fontSize={fontSize}>{label}</text>;
432
- }
433
-
434
- handleWindowResize() {
435
- this.setState({ windowWidth: window.innerWidth });
436
- }
437
-
438
- handleDragStart(sq, x0, y0) {
439
- this.setState({
440
- inhibitedSquare: this.isMovePieceModeEnabled() || this.isPlayMoveModeEnabled() ? sq : '-',
441
- draggedSquare: sq,
442
- hoveredSquare: sq,
443
- cursorOffset: { x: x0, y: y0 },
444
- dragPosition: { x: 0, y: 0 },
445
- });
446
- }
447
-
448
- handleDrag(sq, dx, dy) {
449
- let squareSize = this.getSquareSize();
450
- let { x, y } = this.getSquareCoordinates(squareSize, sq);
451
- let targetSq = this.getSquareAt(squareSize, x + dx + this.state.cursorOffset.x, y + dy + this.state.cursorOffset.y);
452
- this.setState({
453
- hoveredSquare: targetSq,
454
- dragPosition: { x: dx, y: dy },
455
- });
456
- }
457
-
458
- handleDragStop(sq, dx, dy) {
459
- let squareSize = this.getSquareSize();
460
- let { x, y } = this.getSquareCoordinates(squareSize, sq);
461
- let targetSq = this.getSquareAt(squareSize, x + dx + this.state.cursorOffset.x, y + dy + this.state.cursorOffset.y);
462
- this.setState({
463
- inhibitedSquare: '-',
464
- draggedSquare: '-',
465
- hoveredSquare: '-',
466
- });
467
- if (sq === targetSq || targetSq === '-') {
468
- return;
469
- }
470
- if (this.isMovePieceModeEnabled() && this.props.onPieceMoved) {
471
- this.props.onPieceMoved(sq, targetSq);
472
- }
473
- else if (this.isEditArrowModeEnabled() && this.props.onArrowEdited) {
474
- this.props.onArrowEdited(sq, targetSq);
475
- }
476
- else if (this.isPlayMoveModeEnabled()) {
477
- let { position } = this.getPositionAndMoveInfo();
478
- let info = position.isMoveLegal(sq, targetSq);
479
- if (!info) {
480
- return;
481
- }
482
- switch (info.status) {
483
-
484
- // Regular move.
485
- case 'regular':
486
- if (this.props.onMovePlayed) {
487
- this.props.onMovePlayed(position.notation(info()));
488
- }
489
- break;
490
-
491
- // Promotion move.
492
- case 'promotion':
493
- this.setState({
494
- inhibitedSquare: sq,
495
- promotionDrawer: {
496
- origin: targetSq,
497
- buttons: position.variant() === 'antichess' ? [ 'q', 'r', 'b', 'n', 'k' ] : [ 'q', 'r', 'b', 'n' ],
498
- builder: piece => position.notation(info(piece)),
499
- },
500
- });
501
- break;
502
-
503
- // Other cases are not supposed to happen.
504
- // istanbul ignore next
505
- default:
506
- break;
507
- }
508
- }
509
- }
510
-
511
- handleDragCanceled() {
512
- this.setState({
513
- inhibitedSquare: '-',
514
- draggedSquare: '-',
515
- hoveredSquare: '-',
516
- });
517
- }
518
-
519
- handleDrawerCancelButtonClicked() {
520
- this.setState({
521
- inhibitedSquare: '-',
522
- promotionDrawer: false,
523
- });
524
- }
525
-
526
- handleDrawerButtonClicked(piece) {
527
- let builder = this.state.promotionDrawer.builder;
528
- this.setState({
529
- inhibitedSquare: '-',
530
- promotionDrawer: false,
531
- });
532
- if (this.props.onMovePlayed) {
533
- this.props.onMovePlayed(builder(piece));
534
- }
535
- }
536
-
537
- handleSquareClicked(sq) {
538
- if (this.props.onSquareClicked) {
539
- this.props.onSquareClicked(sq);
540
- }
541
- }
542
-
543
- /**
544
- * Whether the "move piece" mode is enabled or not.
545
- */
546
- isMovePieceModeEnabled() {
547
- return this.props.interactionMode === 'movePieces';
548
- }
549
-
550
- /**
551
- * Whether the "play move" mode is enabled or not.
552
- */
553
- isPlayMoveModeEnabled() {
554
- return this.props.interactionMode === 'playMoves';
555
- }
556
-
557
- /**
558
- * Whether the "edit arrow" mode is enabled or not.
559
- */
560
- isEditArrowModeEnabled() {
561
- return this.props.interactionMode === 'editArrows' && isValidColor(this.props.editedArrowColor);
562
- }
563
-
564
- /**
565
- * Return the (sanitized) square size.
566
- */
567
- getSquareSize() {
568
- let squareSize = sanitizeInteger(this.props.squareSize, MIN_SQUARE_SIZE, MAX_SQUARE_SIZE);
569
- let limit = computeSmallScreenLimits('squareSize', this.props.smallScreenLimits, this.state.windowWidth);
570
- return isNaN(limit) ? squareSize : sanitizeInteger(limit, MIN_SQUARE_SIZE, squareSize);
571
- }
572
-
573
- /**
574
- * Whether the file/rank coordinates are visible or not.
575
- */
576
- isCoordinateVisible() {
577
- let limit = computeSmallScreenLimits('coordinateVisible', this.props.smallScreenLimits, this.state.windowWidth);
578
- return this.props.coordinateVisible && (limit === undefined || limit);
579
- }
580
-
581
- /**
582
- * Return the (x,y) coordinates of the given square in the SVG canvas.
583
- */
584
- getSquareCoordinates(squareSize, sq) {
585
- let { file, rank } = squareToCoordinates(sq);
586
- let x = this.props.flipped ? (7 - file) * squareSize : file * squareSize;
587
- let y = this.props.flipped ? rank * squareSize : (7 - rank) * squareSize;
588
- return { x: x, y: y };
589
- }
590
-
591
- /**
592
- * Return information regarding the currently displayed position and move, or parsing error message if something went wrong.
593
- */
594
- getPositionAndMoveInfo() {
595
-
596
- // Parse the position.
597
- let positionInfo = parsePosition(this.props.position);
598
- if (positionInfo.error) {
599
- return { positionError: true, moveError: true, message: positionInfo.message };
600
- }
601
-
602
- // Nothing else to do if no move is defined.
603
- if (!this.props.move) {
604
- return { positionError: false, moveError: false, position: positionInfo.position };
605
- }
606
-
607
- // Parse the move.
608
- let moveInfo = parseMove(positionInfo.position, this.props.move);
609
- if (moveInfo.error) {
610
- return { positionError: false, moveError: true, message: moveInfo.message, positionBefore: positionInfo.position };
611
- }
612
-
613
- // Compute the position after the move and return the result.
614
- let positionAfter = new Position(positionInfo.position);
615
- positionAfter.play(moveInfo.move);
616
- return { positionError: false, moveError: false, positionBefore: positionInfo.position, move: moveInfo.move, position: positionAfter };
617
- }
618
-
619
- /**
620
- * Return the square at the given location.
621
- */
622
- getSquareAt(squareSize, x, y) {
623
- let file = this.props.flipped ? 7 - Math.floor(x / squareSize) : Math.floor(x / squareSize);
624
- let rank = this.props.flipped ? Math.floor(y / squareSize) : 7 - Math.floor(y / squareSize);
625
- return file >= 0 && file < 8 && rank >= 0 && rank < 8 ? coordinatesToSquare(file, rank) : '-';
626
- }
627
-
628
- /**
629
- * Return the DOM ID of an arrow tip with the given color.
630
- */
631
- getArrowTipId(color) {
632
- return 'kokopu-arrowTip-' + color + '-' + this.arrowTipIdSuffix;
633
- }
634
-
635
- /**
636
- * Return the size of the chessboard, assuming it is built with the given attributes.
637
- *
638
- * @param {number} squareSize
639
- * @param {boolean} coordinateVisible
640
- * @param {{width:number, squareSize:number, coordinateVisible:boolean}[]} smallScreenLimits
641
- * @returns {{width:number, height:number}}
642
- * @public
643
- */
644
- static size(squareSize, coordinateVisible, smallScreenLimits) {
645
-
646
- // Enforce small-screen limits, if any.
647
- if (typeof window !== 'undefined') {
648
- let squareSizeLimit = computeSmallScreenLimits('squareSize', smallScreenLimits, window.innerWidth);
649
- let coordinateVisibleLimit = computeSmallScreenLimits('coordinateVisible', smallScreenLimits, window.innerWidth);
650
- if (!isNaN(squareSizeLimit)) {
651
- squareSize = sanitizeInteger(squareSizeLimit, MIN_SQUARE_SIZE, squareSize);
652
- }
653
- coordinateVisible = coordinateVisible && (coordinateVisibleLimit === undefined || coordinateVisibleLimit);
654
- }
655
-
656
- // Compute the dimensions.
657
- let width = 9 * squareSize + Math.round(TURN_FLAG_SPACING_FACTOR * squareSize);
658
- let height = 8 * squareSize;
659
- if (coordinateVisible) {
660
- let fontSize = computeCoordinateFontSize(squareSize);
661
- width += Math.round(RANK_COORDINATE_WIDTH_FACTOR * fontSize);
662
- height += Math.round(FILE_COORDINATE_HEIGHT_FACTOR * fontSize);
663
- }
664
- return { width: width, height: height };
665
- }
666
-
667
- /**
668
- * Return the maximum square size that would allow the chessboard to fit in a rectangle of size `width x height`.
669
- *
670
- * @param {number} width
671
- * @param {number} height
672
- * @param {boolean} coordinateVisible
673
- * @param {{width:number, squareSize:number, coordinateVisible:boolean}[]} smallScreenLimits
674
- * @returns {number}
675
- * @public
676
- */
677
- static adaptSquareSize(width, height, coordinateVisible, smallScreenLimits) {
678
- let maxSquareSize = MAX_SQUARE_SIZE;
679
-
680
- // Enforce small-screen limits, if any.
681
- if (typeof window !== 'undefined') {
682
- let squareSizeLimit = computeSmallScreenLimits('squareSize', smallScreenLimits, window.innerWidth);
683
- let coordinateVisibleLimit = computeSmallScreenLimits('coordinateVisible', smallScreenLimits, window.innerWidth);
684
- if (!isNaN(squareSizeLimit)) {
685
- maxSquareSize = sanitizeInteger(squareSizeLimit, MIN_SQUARE_SIZE, maxSquareSize);
686
- }
687
- coordinateVisible = coordinateVisible && (coordinateVisibleLimit === undefined || coordinateVisibleLimit);
688
- }
689
-
690
- function isAdapted(squareSize) {
691
- let actualWidth = 9 * squareSize + Math.round(TURN_FLAG_SPACING_FACTOR * squareSize);
692
- let actualHeight = 8 * squareSize;
693
- if (coordinateVisible) {
694
- let fontSize = computeCoordinateFontSize(squareSize);
695
- actualWidth += Math.round(RANK_COORDINATE_WIDTH_FACTOR * fontSize);
696
- actualHeight += Math.round(FILE_COORDINATE_HEIGHT_FACTOR * fontSize);
697
- }
698
- return actualWidth <= width && actualHeight <= height;
699
- }
700
-
701
- // Check min/max bounds.
702
- if (isAdapted(maxSquareSize)) {
703
- return maxSquareSize;
704
- }
705
- else if (!isAdapted(MIN_SQUARE_SIZE)) {
706
- return MIN_SQUARE_SIZE;
707
- }
708
-
709
- // Dichotomic search, between a (inclusive) and b (exclusive).
710
- let a = MIN_SQUARE_SIZE;
711
- let b = maxSquareSize;
712
- while (a + 1 < b) {
713
- let mid = Math.floor((a + b) / 2);
714
- if (isAdapted(mid)) {
715
- a = mid;
716
- }
717
- else {
718
- b = mid;
719
- }
720
- }
721
- return a;
722
- }
723
-
724
- /**
725
- * Minimum square size (inclusive).
726
- *
727
- * @returns {number}
728
- * @public
729
- */
730
- static minSquareSize() {
731
- return MIN_SQUARE_SIZE;
732
- }
733
-
734
- /**
735
- * Maximum square size (inclusive).
736
- *
737
- * @returns {number}
738
- * @public
739
- */
740
- static maxSquareSize() {
741
- return MAX_SQUARE_SIZE;
742
- }
743
-
744
- /**
745
- * Available colorsets for theming.
746
- *
747
- * @returns {Object.<string, { w: string, b: string, cb: string, cg: string, cr: string, cy: string }>}
748
- * @public
749
- */
750
- static colorsets() {
751
- return colorsets;
752
- }
753
-
754
- /**
755
- * Available piecesets for theming.
756
- *
757
- * @returns {Object.<string, { bb: string, bk: string, bn: string, bp: string, bq: string, br: string, bx: string,
758
- * wb: string, wk: string, wn: string, wp: string, wq: string, wr: string, wx: string }>}
759
- * @public
760
- */
761
- static piecesets() {
762
- return piecesets;
763
- }
764
- }
765
-
766
-
767
- Chessboard.propTypes = {
768
-
769
- /**
770
- * Displayed position. Can be a [kokopu.Position](https://kokopu.yo35.org/docs/current/classes/Position.html) object,
771
- * a [FEN string](https://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation),
772
- * `'start'` (usual starting position), or `'empty'` (empty board).
773
- *
774
- * Optionally, the FEN string can be prefixed with `'variant:'`, `variant` corresponding to one of the
775
- * [game variant](https://kokopu.yo35.org/docs/current/types/GameVariant.html) supported by Kokopu. For instance:
776
- * `'chess960:nrkbqrbn/pppppppp/8/8/8/8/PPPPPPPP/NRKBQRBN w KQkq - 0 1'`.
777
- */
778
- position: PropTypes.oneOfType([
779
- PropTypes.instanceOf(Position),
780
- PropTypes.string
781
- ]),
782
-
783
- /**
784
- * Displayed move (optional), defined either as a [kokopu.MoveDescriptor](https://kokopu.yo35.org/docs/current/classes/MoveDescriptor.html) object
785
- * or as a [SAN string](https://en.wikipedia.org/wiki/Algebraic_notation_(chess)) (e.g. `'Nf3'`). In both cases, it must represent
786
- * a legal move in position defined in attribute `position`.
787
- */
788
- move: PropTypes.oneOfType([
789
- PropTypes.instanceOf(MoveDescriptor),
790
- PropTypes.string
791
- ]),
792
-
793
- /**
794
- * Square markers, defined as a "square -> color" struct (e.g. `{ e4: 'g', d5: 'r' }`) or as a comma-separated CSL string (e.g. `'Rd5,Ge4'`).
795
- */
796
- squareMarkers: PropTypes.oneOfType([
797
- PropTypes.objectOf(PropTypes.oneOf([ 'b', 'g', 'r', 'y' ])),
798
- PropTypes.string
799
- ]),
800
-
801
- /**
802
- * Text markers, defined as a "square -> (symbol, color)" struct (e.g. `{ e4: { symbol: 'A', color: 'g' }, d5: { symbol: 'z', color: 'r' }}`)
803
- * or as a comma-separated CTL string (e.g. `'Rzd5,GAe4'`).
804
- */
805
- textMarkers: PropTypes.oneOfType([
806
- PropTypes.objectOf(PropTypes.shape({
807
- symbol: PropTypes.string.isRequired,
808
- color: PropTypes.oneOf([ 'b', 'g', 'r', 'y' ]).isRequired
809
- })),
810
- PropTypes.string
811
- ]),
812
-
813
- /**
814
- * Arrow markers, defined as a "squareFromSquareTo -> color" struct (e.g. `{ e2e4: 'g', g8f6: 'r', g8h6: 'y' }`)
815
- * or as a comma-separated CAL string (e.g. `'Ge2e4,Rg8f6,Yg8h6'`).
816
- */
817
- arrowMarkers: PropTypes.oneOfType([
818
- PropTypes.objectOf(PropTypes.oneOf([ 'b', 'g', 'r', 'y' ])),
819
- PropTypes.string
820
- ]),
821
-
822
- /**
823
- * Whether the board is flipped (i.e. seen from Black's point of view) or not.
824
- */
825
- flipped: PropTypes.bool,
826
-
827
- /**
828
- * Size of the squares (in pixels). Must be an integer between `Chessboard.minSquareSize()` and `Chessboard.maxSquareSize()`.
829
- */
830
- squareSize: PropTypes.number,
831
-
832
- /**
833
- * Whether the row and column coordinates are visible or not.
834
- */
835
- coordinateVisible: PropTypes.bool,
836
-
837
- /**
838
- * Whether moves are highlighted with an arrow or not.
839
- */
840
- moveArrowVisible: PropTypes.bool,
841
-
842
- /**
843
- * Color of the move arrow.
844
- */
845
- moveArrowColor: PropTypes.oneOf([ 'b', 'g', 'r', 'y' ]),
846
-
847
- /**
848
- * Whether moves are animated or not.
849
- */
850
- animated: PropTypes.bool,
851
-
852
- /**
853
- * Color theme ID.
854
- */
855
- colorset: PropTypes.oneOf(Object.keys(colorsets)),
856
-
857
- /**
858
- * Piece theme ID.
859
- */
860
- pieceset: PropTypes.oneOf(Object.keys(piecesets)),
861
-
862
- /**
863
- * Limits applicable on small-screen devices. For instance, if set to
864
- * ```
865
- * [
866
- * { width: 768, squareSize: 40 },
867
- * { width: 375, squareSize: 24, coordinateVisible: false }
868
- * ]
869
- * ```
870
- * then on screens with resolution ≤768 pixels, the square size will be limited to 40 (whatever the value
871
- * of the `squareSize` attribute); in addition, on screens with resolution ≤375 pixels, the square size
872
- * will be limited to 24 and the row and column coordinates will always be hidden (whatever the value of the
873
- * `coordinateVisible` attribute).
874
- */
875
- smallScreenLimits: PropTypes.arrayOf(PropTypes.shape({
876
- width: PropTypes.number.isRequired,
877
- squareSize: PropTypes.number,
878
- coordinateVisible: PropTypes.bool,
879
- })),
880
-
881
- /**
882
- * Type of action allowed with the mouse on the chessboard. If undefined, then the user cannot interact with the component.
883
- *
884
- * - `'movePieces'` allows the user to drag & drop the chess pieces from one square to another (regardless of the chess rules),
885
- * - `'clickSquares'` allows the user to click on squares,
886
- * - `'editArrows'` allows the user to draw arrow markers from one square to another (warning: attribute `editedArrowColor` must be set),
887
- * - `'playMoves'` allows the user to play legal chess moves (thus no interaction is possible if the displayed position is not legal).
888
- */
889
- interactionMode: PropTypes.oneOf([ 'movePieces', 'clickSquares', 'editArrows', 'playMoves' ]),
890
-
891
- /**
892
- * Color of the edited arrow (only used if `interactionMode` is set to `'editArrows'`).
893
- */
894
- editedArrowColor: PropTypes.oneOf([ 'b', 'g', 'r', 'y' ]),
895
-
896
- /**
897
- * Callback invoked when a piece is moved through drag&drop (only if `interactionMode` is set to `'movePieces'`).
898
- *
899
- * @param {string} from Origin square (e.g. `'g1'`).
900
- * @param {string} to Target square (e.g. `'f3'`).
901
- */
902
- onPieceMoved: PropTypes.func,
903
-
904
- /**
905
- * Callback invoked when the user clicks on a square (only if `interactionMode` is set to `'clickSquares'`).
906
- *
907
- * @param {string} square Clicked square (e.g. `e4`).
908
- */
909
- onSquareClicked: PropTypes.func,
910
-
911
- /**
912
- * Callback invoked when an arrow is dragged (only if `interactionMode` is set to `'editArrows'`).
913
- *
914
- * @param {string} from Origin square (e.g. `'g1'`).
915
- * @param {string} to Target square (e.g. `'f3'`).
916
- */
917
- onArrowEdited: PropTypes.func,
918
-
919
- /**
920
- * Callback invoked when a move is played (only if `interactionMode` is set to `'playMoves'`).
921
- *
922
- * @param {string} move SAN notation representing the played move (e.g. `Nxe5`).
923
- */
924
- onMovePlayed: PropTypes.func,
925
- };
926
-
927
-
928
- Chessboard.defaultProps = {
929
- position: 'start',
930
- flipped: false,
931
- squareSize: 40,
932
- coordinateVisible: true,
933
- moveArrowVisible: true,
934
- moveArrowColor: 'b',
935
- animated: false,
936
- colorset: 'original',
937
- pieceset: 'cburnett',
938
- };
939
-
940
-
941
- /**
942
- * Compute the limit applicable to the given window width.
943
- */
944
- function computeSmallScreenLimits(key, smallScreenLimits, windowWidth) {
945
- if (!(smallScreenLimits instanceof Array)) {
946
- return undefined;
947
- }
948
- let applicableLimits = smallScreenLimits
949
- .filter(limit => limit && key in limit && windowWidth <= limit.width)
950
- .sort((la, lb) => la.width - lb.width);
951
- return applicableLimits.length > 0 ? applicableLimits[0][key] : undefined;
952
- }
953
-
954
-
955
- /**
956
- * Return the font size to use for coordinates assuming the given square size.
957
- */
958
- function computeCoordinateFontSize(squareSize) {
959
- return squareSize <= 32 ? 8 : 8 + (squareSize - 32) * 0.2;
960
- }
961
-
962
-
963
- /**
964
- * Try to interpret the given object as a chess position.
965
- */
966
- function parsePosition(position) {
967
- if (position instanceof Position) {
968
- return { error: false, position: position };
969
- }
970
- else if (typeof position === 'string') {
971
- try {
972
- return { error: false, position: new Position(position) };
973
- }
974
- catch (e) {
975
- // istanbul ignore else
976
- if (e instanceof exception.InvalidFEN) {
977
- return { error: true, message: e.message };
978
- }
979
- else {
980
- throw e;
981
- }
982
- }
983
- }
984
- else {
985
- return { error: true, message: i18n.INVALID_POSITION_ATTRIBUTE_ERROR_MESSAGE };
986
- }
987
- }
988
-
989
-
990
- /**
991
- * Try to interpret the given object `move` as a move descriptor based on the given position.
992
- */
993
- function parseMove(position, move) {
994
- if (move instanceof MoveDescriptor) {
995
- return { error: false, move: move };
996
- }
997
- else if (typeof move === 'string') {
998
- try {
999
- return { error: false, move: position.notation(move) };
1000
- }
1001
- catch (e) {
1002
- // istanbul ignore else
1003
- if (e instanceof exception.InvalidNotation) {
1004
- return { error: true, message: e.message };
1005
- }
1006
- else {
1007
- throw e;
1008
- }
1009
- }
1010
- }
1011
- else {
1012
- return { error: true, message: i18n.INVALID_MOVE_ATTRIBUTE_ERROR_MESSAGE };
1013
- }
1014
- }
1015
-
1016
-
1017
- /**
1018
- * Try to interpret the given object as a list of markers.
1019
- */
1020
- function parseMarkers(markers, parse, isValidKey, isValidValue) {
1021
- if (typeof markers === 'string') {
1022
- return parse(markers);
1023
- }
1024
- else if (typeof markers === 'object') {
1025
- let result = {};
1026
- Object.entries(markers)
1027
- .filter(([ key, value ]) => isValidKey(key) && isValidValue(value))
1028
- .forEach(([ key, value ]) => { result[key] = value; });
1029
- return result;
1030
- }
1031
- else {
1032
- return {};
1033
- }
1034
- }