@johnmorrisdotca/kazu 1.0.0 → 1.2.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 (355) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +429 -5
  3. package/dist/akari-draw-entry.d.ts +2 -0
  4. package/dist/akari-draw-entry.js +1 -0
  5. package/dist/akari-entry.d.ts +12 -0
  6. package/dist/akari-entry.js +10 -0
  7. package/dist/akari-play-entry.d.ts +2 -0
  8. package/dist/akari-play-entry.js +1 -0
  9. package/dist/akari.constants.d.ts +2 -0
  10. package/dist/akari.constants.js +2 -0
  11. package/dist/akari.types.d.ts +33 -0
  12. package/dist/akari.types.js +1 -0
  13. package/dist/akariBoard.d.ts +11 -0
  14. package/dist/akariBoard.js +96 -0
  15. package/dist/akariDraw.d.ts +4 -0
  16. package/dist/akariDraw.js +38 -0
  17. package/dist/akariGame.d.ts +15 -0
  18. package/dist/akariGame.js +71 -0
  19. package/dist/akariGenerate.d.ts +7 -0
  20. package/dist/akariGenerate.js +78 -0
  21. package/dist/akariMount.d.ts +3 -0
  22. package/dist/akariMount.js +214 -0
  23. package/dist/akariPlay.types.d.ts +25 -0
  24. package/dist/akariPlay.types.js +1 -0
  25. package/dist/akariSolve.d.ts +6 -0
  26. package/dist/akariSolve.js +106 -0
  27. package/dist/akariStrings.d.ts +98 -0
  28. package/dist/akariStrings.js +53 -0
  29. package/dist/akariStyle.d.ts +1 -0
  30. package/dist/akariStyle.js +9 -0
  31. package/dist/draw-entry.d.ts +1 -0
  32. package/dist/draw-entry.js +1 -0
  33. package/dist/fillomino-draw-entry.d.ts +2 -0
  34. package/dist/fillomino-draw-entry.js +1 -0
  35. package/dist/fillomino-entry.d.ts +8 -0
  36. package/dist/fillomino-entry.js +7 -0
  37. package/dist/fillomino-play-entry.d.ts +4 -0
  38. package/dist/fillomino-play-entry.js +3 -0
  39. package/dist/fillomino.constants.d.ts +5 -0
  40. package/dist/fillomino.constants.js +5 -0
  41. package/dist/fillomino.types.d.ts +30 -0
  42. package/dist/fillomino.types.js +1 -0
  43. package/dist/fillominoBoard.d.ts +6 -0
  44. package/dist/fillominoBoard.js +84 -0
  45. package/dist/fillominoDraw.d.ts +3 -0
  46. package/dist/fillominoDraw.js +31 -0
  47. package/dist/fillominoGame.d.ts +13 -0
  48. package/dist/fillominoGame.js +65 -0
  49. package/dist/fillominoGenerate.d.ts +3 -0
  50. package/dist/fillominoGenerate.js +125 -0
  51. package/dist/fillominoMount.d.ts +2 -0
  52. package/dist/fillominoMount.js +211 -0
  53. package/dist/fillominoPlay.types.d.ts +25 -0
  54. package/dist/fillominoPlay.types.js +1 -0
  55. package/dist/fillominoSolve.d.ts +6 -0
  56. package/dist/fillominoSolve.js +111 -0
  57. package/dist/fillominoStrings.d.ts +102 -0
  58. package/dist/fillominoStrings.js +13 -0
  59. package/dist/fillominoStyle.d.ts +1 -0
  60. package/dist/fillominoStyle.js +13 -0
  61. package/dist/fillominoWorker.d.ts +1 -0
  62. package/dist/fillominoWorker.js +10 -0
  63. package/dist/heyawake-draw-entry.d.ts +2 -0
  64. package/dist/heyawake-draw-entry.js +1 -0
  65. package/dist/heyawake-entry.d.ts +13 -0
  66. package/dist/heyawake-entry.js +11 -0
  67. package/dist/heyawake-play-entry.d.ts +2 -0
  68. package/dist/heyawake-play-entry.js +1 -0
  69. package/dist/heyawake.constants.d.ts +5 -0
  70. package/dist/heyawake.constants.js +5 -0
  71. package/dist/heyawake.types.d.ts +35 -0
  72. package/dist/heyawake.types.js +1 -0
  73. package/dist/heyawakeBoard.d.ts +7 -0
  74. package/dist/heyawakeBoard.js +116 -0
  75. package/dist/heyawakeDraw.d.ts +3 -0
  76. package/dist/heyawakeDraw.js +27 -0
  77. package/dist/heyawakeGame.d.ts +12 -0
  78. package/dist/heyawakeGame.js +51 -0
  79. package/dist/heyawakeGenerate.d.ts +2 -0
  80. package/dist/heyawakeGenerate.js +114 -0
  81. package/dist/heyawakeMount.d.ts +2 -0
  82. package/dist/heyawakeMount.js +106 -0
  83. package/dist/heyawakePlay.types.d.ts +24 -0
  84. package/dist/heyawakePlay.types.js +1 -0
  85. package/dist/heyawakeSolve.d.ts +5 -0
  86. package/dist/heyawakeSolve.js +52 -0
  87. package/dist/heyawakeStrings.d.ts +19 -0
  88. package/dist/heyawakeStrings.js +7 -0
  89. package/dist/heyawakeStyle.d.ts +1 -0
  90. package/dist/heyawakeStyle.js +2 -0
  91. package/dist/heyawakeWorker.d.ts +1 -0
  92. package/dist/heyawakeWorker.js +10 -0
  93. package/dist/hitori-draw-entry.d.ts +2 -0
  94. package/dist/hitori-draw-entry.js +1 -0
  95. package/dist/hitori-entry.d.ts +6 -0
  96. package/dist/hitori-entry.js +6 -0
  97. package/dist/hitori-play-entry.d.ts +4 -0
  98. package/dist/hitori-play-entry.js +3 -0
  99. package/dist/hitori.constants.d.ts +2 -0
  100. package/dist/hitori.constants.js +2 -0
  101. package/dist/hitori.types.d.ts +20 -0
  102. package/dist/hitori.types.js +1 -0
  103. package/dist/hitoriBoard.d.ts +8 -0
  104. package/dist/hitoriBoard.js +72 -0
  105. package/dist/hitoriDraw.d.ts +4 -0
  106. package/dist/hitoriDraw.js +25 -0
  107. package/dist/hitoriGame.d.ts +10 -0
  108. package/dist/hitoriGame.js +48 -0
  109. package/dist/hitoriGenerate.d.ts +3 -0
  110. package/dist/hitoriGenerate.js +163 -0
  111. package/dist/hitoriMount.d.ts +3 -0
  112. package/dist/hitoriMount.js +111 -0
  113. package/dist/hitoriPlay.types.d.ts +25 -0
  114. package/dist/hitoriPlay.types.js +1 -0
  115. package/dist/hitoriSolve.d.ts +6 -0
  116. package/dist/hitoriSolve.js +69 -0
  117. package/dist/hitoriStrings.d.ts +70 -0
  118. package/dist/hitoriStrings.js +17 -0
  119. package/dist/hitoriStyle.d.ts +1 -0
  120. package/dist/hitoriStyle.js +9 -0
  121. package/dist/index.d.ts +12 -0
  122. package/dist/index.js +12 -0
  123. package/dist/juosan-draw-entry.d.ts +2 -0
  124. package/dist/juosan-draw-entry.js +1 -0
  125. package/dist/juosan-entry.d.ts +11 -0
  126. package/dist/juosan-entry.js +10 -0
  127. package/dist/juosan-play-entry.d.ts +4 -0
  128. package/dist/juosan-play-entry.js +3 -0
  129. package/dist/juosan.constants.d.ts +4 -0
  130. package/dist/juosan.constants.js +4 -0
  131. package/dist/juosan.types.d.ts +33 -0
  132. package/dist/juosan.types.js +1 -0
  133. package/dist/juosanBoard.d.ts +7 -0
  134. package/dist/juosanBoard.js +102 -0
  135. package/dist/juosanDraw.d.ts +4 -0
  136. package/dist/juosanDraw.js +49 -0
  137. package/dist/juosanGame.d.ts +20 -0
  138. package/dist/juosanGame.js +86 -0
  139. package/dist/juosanGenerate.d.ts +3 -0
  140. package/dist/juosanGenerate.js +31 -0
  141. package/dist/juosanMount.d.ts +3 -0
  142. package/dist/juosanMount.js +206 -0
  143. package/dist/juosanPlay.types.d.ts +24 -0
  144. package/dist/juosanPlay.types.js +1 -0
  145. package/dist/juosanSolve.d.ts +3 -0
  146. package/dist/juosanSolve.js +82 -0
  147. package/dist/juosanStrings.d.ts +77 -0
  148. package/dist/juosanStrings.js +43 -0
  149. package/dist/juosanStyle.d.ts +1 -0
  150. package/dist/juosanStyle.js +1 -0
  151. package/dist/kakuro-draw-entry.d.ts +2 -0
  152. package/dist/kakuro-draw-entry.js +1 -0
  153. package/dist/kakuro-entry.d.ts +12 -0
  154. package/dist/kakuro-entry.js +10 -0
  155. package/dist/kakuro-play-entry.d.ts +4 -0
  156. package/dist/kakuro-play-entry.js +3 -0
  157. package/dist/kakuro.constants.d.ts +6 -0
  158. package/dist/kakuro.constants.js +6 -0
  159. package/dist/kakuro.types.d.ts +46 -0
  160. package/dist/kakuro.types.js +1 -0
  161. package/dist/kakuroBoard.d.ts +8 -0
  162. package/dist/kakuroBoard.js +117 -0
  163. package/dist/kakuroDraw.d.ts +10 -0
  164. package/dist/kakuroDraw.js +21 -0
  165. package/dist/kakuroGame.d.ts +12 -0
  166. package/dist/kakuroGame.js +74 -0
  167. package/dist/kakuroGenerate.d.ts +3 -0
  168. package/dist/kakuroGenerate.js +130 -0
  169. package/dist/kakuroMount.d.ts +2 -0
  170. package/dist/kakuroMount.js +109 -0
  171. package/dist/kakuroPlay.types.d.ts +20 -0
  172. package/dist/kakuroPlay.types.js +1 -0
  173. package/dist/kakuroSolve.d.ts +6 -0
  174. package/dist/kakuroSolve.js +85 -0
  175. package/dist/kakuroStrings.d.ts +82 -0
  176. package/dist/kakuroStrings.js +5 -0
  177. package/dist/kakuroStyle.d.ts +1 -0
  178. package/dist/kakuroStyle.js +1 -0
  179. package/dist/masyu-draw-entry.d.ts +2 -0
  180. package/dist/masyu-draw-entry.js +1 -0
  181. package/dist/masyu-entry.d.ts +6 -0
  182. package/dist/masyu-entry.js +6 -0
  183. package/dist/masyu-play-entry.d.ts +4 -0
  184. package/dist/masyu-play-entry.js +3 -0
  185. package/dist/masyu.constants.d.ts +2 -0
  186. package/dist/masyu.constants.js +2 -0
  187. package/dist/masyu.types.d.ts +46 -0
  188. package/dist/masyu.types.js +1 -0
  189. package/dist/masyuBoard.d.ts +10 -0
  190. package/dist/masyuBoard.js +88 -0
  191. package/dist/masyuDraw.d.ts +2 -0
  192. package/dist/masyuDraw.js +33 -0
  193. package/dist/masyuGame.d.ts +9 -0
  194. package/dist/masyuGame.js +46 -0
  195. package/dist/masyuGenerate.d.ts +3 -0
  196. package/dist/masyuGenerate.js +56 -0
  197. package/dist/masyuMount.d.ts +2 -0
  198. package/dist/masyuMount.js +118 -0
  199. package/dist/masyuPlay.types.d.ts +1 -0
  200. package/dist/masyuPlay.types.js +1 -0
  201. package/dist/masyuSolve.d.ts +6 -0
  202. package/dist/masyuSolve.js +88 -0
  203. package/dist/masyuStrings.d.ts +28 -0
  204. package/dist/masyuStrings.js +4 -0
  205. package/dist/masyuStyle.d.ts +1 -0
  206. package/dist/masyuStyle.js +11 -0
  207. package/dist/nurikabe-draw-entry.d.ts +2 -0
  208. package/dist/nurikabe-draw-entry.js +1 -0
  209. package/dist/nurikabe-entry.d.ts +6 -0
  210. package/dist/nurikabe-entry.js +6 -0
  211. package/dist/nurikabe-play-entry.d.ts +4 -0
  212. package/dist/nurikabe-play-entry.js +3 -0
  213. package/dist/nurikabe.constants.d.ts +2 -0
  214. package/dist/nurikabe.constants.js +2 -0
  215. package/dist/nurikabe.types.d.ts +20 -0
  216. package/dist/nurikabe.types.js +1 -0
  217. package/dist/nurikabeBoard.d.ts +8 -0
  218. package/dist/nurikabeBoard.js +72 -0
  219. package/dist/nurikabeDraw.d.ts +4 -0
  220. package/dist/nurikabeDraw.js +15 -0
  221. package/dist/nurikabeGame.d.ts +8 -0
  222. package/dist/nurikabeGame.js +40 -0
  223. package/dist/nurikabeGenerate.d.ts +3 -0
  224. package/dist/nurikabeGenerate.js +31 -0
  225. package/dist/nurikabeMount.d.ts +3 -0
  226. package/dist/nurikabeMount.js +99 -0
  227. package/dist/nurikabePlay.types.d.ts +25 -0
  228. package/dist/nurikabePlay.types.js +1 -0
  229. package/dist/nurikabeSolve.d.ts +6 -0
  230. package/dist/nurikabeSolve.js +75 -0
  231. package/dist/nurikabeStrings.d.ts +70 -0
  232. package/dist/nurikabeStrings.js +5 -0
  233. package/dist/nurikabeStyle.d.ts +1 -0
  234. package/dist/nurikabeStyle.js +9 -0
  235. package/dist/play-entry.d.ts +1 -0
  236. package/dist/play-entry.js +1 -0
  237. package/dist/ripple-draw-entry.d.ts +2 -0
  238. package/dist/ripple-draw-entry.js +1 -0
  239. package/dist/ripple-entry.d.ts +12 -0
  240. package/dist/ripple-entry.js +11 -0
  241. package/dist/ripple-play-entry.d.ts +4 -0
  242. package/dist/ripple-play-entry.js +3 -0
  243. package/dist/ripple.constants.d.ts +4 -0
  244. package/dist/ripple.constants.js +4 -0
  245. package/dist/ripple.types.d.ts +34 -0
  246. package/dist/ripple.types.js +1 -0
  247. package/dist/rippleBoard.d.ts +7 -0
  248. package/dist/rippleBoard.js +99 -0
  249. package/dist/rippleDraw.d.ts +3 -0
  250. package/dist/rippleDraw.js +32 -0
  251. package/dist/rippleGame.d.ts +13 -0
  252. package/dist/rippleGame.js +85 -0
  253. package/dist/rippleGenerate.d.ts +3 -0
  254. package/dist/rippleGenerate.js +57 -0
  255. package/dist/rippleMount.d.ts +2 -0
  256. package/dist/rippleMount.js +179 -0
  257. package/dist/ripplePlay.types.d.ts +23 -0
  258. package/dist/ripplePlay.types.js +1 -0
  259. package/dist/rippleSolve.d.ts +6 -0
  260. package/dist/rippleSolve.js +83 -0
  261. package/dist/rippleStrings.d.ts +86 -0
  262. package/dist/rippleStrings.js +5 -0
  263. package/dist/rippleStyle.d.ts +1 -0
  264. package/dist/rippleStyle.js +1 -0
  265. package/dist/shikaku-draw-entry.d.ts +2 -0
  266. package/dist/shikaku-draw-entry.js +1 -0
  267. package/dist/shikaku-entry.d.ts +8 -0
  268. package/dist/shikaku-entry.js +8 -0
  269. package/dist/shikaku-play-entry.d.ts +4 -0
  270. package/dist/shikaku-play-entry.js +3 -0
  271. package/dist/shikaku.constants.d.ts +5 -0
  272. package/dist/shikaku.constants.js +5 -0
  273. package/dist/shikaku.types.d.ts +36 -0
  274. package/dist/shikaku.types.js +1 -0
  275. package/dist/shikakuBoard.d.ts +9 -0
  276. package/dist/shikakuBoard.js +59 -0
  277. package/dist/shikakuDraw.d.ts +4 -0
  278. package/dist/shikakuDraw.js +23 -0
  279. package/dist/shikakuGame.d.ts +14 -0
  280. package/dist/shikakuGame.js +61 -0
  281. package/dist/shikakuGenerate.d.ts +3 -0
  282. package/dist/shikakuGenerate.js +43 -0
  283. package/dist/shikakuMount.d.ts +3 -0
  284. package/dist/shikakuMount.js +143 -0
  285. package/dist/shikakuPacks.d.ts +27 -0
  286. package/dist/shikakuPacks.js +26 -0
  287. package/dist/shikakuPlay.types.d.ts +26 -0
  288. package/dist/shikakuPlay.types.js +1 -0
  289. package/dist/shikakuSolve.d.ts +6 -0
  290. package/dist/shikakuSolve.js +54 -0
  291. package/dist/shikakuStrings.d.ts +102 -0
  292. package/dist/shikakuStrings.js +5 -0
  293. package/dist/shikakuStyle.d.ts +1 -0
  294. package/dist/shikakuStyle.js +12 -0
  295. package/dist/shikakuWorker.d.ts +1 -0
  296. package/dist/shikakuWorker.js +10 -0
  297. package/dist/slitherlink-draw-entry.d.ts +2 -0
  298. package/dist/slitherlink-draw-entry.js +1 -0
  299. package/dist/slitherlink-entry.d.ts +11 -0
  300. package/dist/slitherlink-entry.js +9 -0
  301. package/dist/slitherlink-play-entry.d.ts +4 -0
  302. package/dist/slitherlink-play-entry.js +3 -0
  303. package/dist/slitherlink.constants.d.ts +2 -0
  304. package/dist/slitherlink.constants.js +2 -0
  305. package/dist/slitherlink.types.d.ts +34 -0
  306. package/dist/slitherlink.types.js +1 -0
  307. package/dist/slitherlinkBoard.d.ts +12 -0
  308. package/dist/slitherlinkBoard.js +132 -0
  309. package/dist/slitherlinkDraw.d.ts +4 -0
  310. package/dist/slitherlinkDraw.js +51 -0
  311. package/dist/slitherlinkGame.d.ts +8 -0
  312. package/dist/slitherlinkGame.js +63 -0
  313. package/dist/slitherlinkGenerate.d.ts +3 -0
  314. package/dist/slitherlinkGenerate.js +101 -0
  315. package/dist/slitherlinkMount.d.ts +3 -0
  316. package/dist/slitherlinkMount.js +267 -0
  317. package/dist/slitherlinkPlay.types.d.ts +23 -0
  318. package/dist/slitherlinkPlay.types.js +1 -0
  319. package/dist/slitherlinkSolve.d.ts +6 -0
  320. package/dist/slitherlinkSolve.js +127 -0
  321. package/dist/slitherlinkStrings.d.ts +86 -0
  322. package/dist/slitherlinkStrings.js +47 -0
  323. package/dist/slitherlinkStyle.d.ts +1 -0
  324. package/dist/slitherlinkStyle.js +18 -0
  325. package/dist/version.d.ts +1 -1
  326. package/dist/version.js +1 -1
  327. package/dist/yajilin-draw-entry.d.ts +2 -0
  328. package/dist/yajilin-draw-entry.js +1 -0
  329. package/dist/yajilin-entry.d.ts +6 -0
  330. package/dist/yajilin-entry.js +6 -0
  331. package/dist/yajilin-play-entry.d.ts +4 -0
  332. package/dist/yajilin-play-entry.js +3 -0
  333. package/dist/yajilin.constants.d.ts +2 -0
  334. package/dist/yajilin.constants.js +2 -0
  335. package/dist/yajilin.types.d.ts +63 -0
  336. package/dist/yajilin.types.js +1 -0
  337. package/dist/yajilinBoard.d.ts +9 -0
  338. package/dist/yajilinBoard.js +91 -0
  339. package/dist/yajilinDraw.d.ts +2 -0
  340. package/dist/yajilinDraw.js +33 -0
  341. package/dist/yajilinGame.d.ts +15 -0
  342. package/dist/yajilinGame.js +58 -0
  343. package/dist/yajilinGenerate.d.ts +3 -0
  344. package/dist/yajilinGenerate.js +224 -0
  345. package/dist/yajilinMount.d.ts +2 -0
  346. package/dist/yajilinMount.js +162 -0
  347. package/dist/yajilinPlay.types.d.ts +1 -0
  348. package/dist/yajilinPlay.types.js +1 -0
  349. package/dist/yajilinSolve.d.ts +6 -0
  350. package/dist/yajilinSolve.js +82 -0
  351. package/dist/yajilinStrings.d.ts +32 -0
  352. package/dist/yajilinStrings.js +4 -0
  353. package/dist/yajilinStyle.d.ts +1 -0
  354. package/dist/yajilinStyle.js +12 -0
  355. package/package.json +196 -3
@@ -0,0 +1,58 @@
1
+ import { isYajilinBoard, yajilinEdgeCount } from "./yajilinBoard.js";
2
+ import { solveYajilin } from "./yajilinSolve.js";
3
+ export function newYajilin(board) {
4
+ if (!isYajilinBoard(board))
5
+ throw new RangeError("Invalid Yajilin board");
6
+ return { board: { width: board.width, height: board.height, clues: board.clues.map(clue => clue ? { ...clue } : null) }, shaded: Array(board.width * board.height).fill(false), edges: [], history: [], helped: false };
7
+ }
8
+ function snapshot(game) { return { shaded: [...game.shaded], edges: [...game.edges] }; }
9
+ export function toggleYajilinShade(game, cell) {
10
+ if (!Number.isInteger(cell) || cell < 0 || cell >= game.shaded.length || game.board.clues[cell])
11
+ return game;
12
+ const shaded = [...game.shaded];
13
+ shaded[cell] = !shaded[cell];
14
+ return { ...game, shaded, history: [...game.history, snapshot(game)] };
15
+ }
16
+ export function toggleYajilinEdge(game, edge) {
17
+ if (!Number.isInteger(edge) || edge < 0 || edge >= yajilinEdgeCount(game.board))
18
+ return game;
19
+ const edges = game.edges.includes(edge) ? game.edges.filter(value => value !== edge) : [...game.edges, edge].sort((a, b) => a - b);
20
+ return { ...game, edges, history: [...game.history, snapshot(game)] };
21
+ }
22
+ export function undoYajilin(game) {
23
+ const previous = game.history.at(-1);
24
+ return previous ? { ...game, shaded: [...previous.shaded], edges: [...previous.edges], history: game.history.slice(0, -1) } : game;
25
+ }
26
+ export function restartYajilin(game) { return { ...newYajilin(game.board), helped: false }; }
27
+ export function hintYajilin(game) {
28
+ const result = solveYajilin(game.board);
29
+ if (!result.complete || result.count !== 1)
30
+ return null;
31
+ const cell = result.solution.shaded.findIndex((value, index) => value !== game.shaded[index]);
32
+ if (cell >= 0)
33
+ return { type: "shade", cell };
34
+ const edge = result.solution.edges.find(value => !game.edges.includes(value));
35
+ return edge === undefined ? null : { type: "edge", edge };
36
+ }
37
+ export function encodeYajilin(game) {
38
+ return JSON.stringify({ version: 1, board: game.board, shaded: game.shaded, edges: game.edges, helped: game.helped });
39
+ }
40
+ export function decodeYajilin(code) {
41
+ try {
42
+ if (code.length > 40000)
43
+ return null;
44
+ const value = JSON.parse(code);
45
+ if (value.version !== 1 || !isYajilinBoard(value.board) || !Array.isArray(value.shaded)
46
+ || value.shaded.length !== value.board.width * value.board.height || !value.shaded.every((cell) => typeof cell === "boolean")
47
+ || !Array.isArray(value.edges) || !value.edges.every((edge) => Number.isInteger(edge))
48
+ || typeof value.helped !== "boolean")
49
+ return null;
50
+ const edges = [...new Set(value.edges)].sort((a, b) => a - b);
51
+ if (edges.length !== value.edges.length || edges.some(edge => edge < 0 || edge >= yajilinEdgeCount(value.board)))
52
+ return null;
53
+ return { ...newYajilin(value.board), shaded: [...value.shaded], edges, helped: value.helped };
54
+ }
55
+ catch {
56
+ return null;
57
+ }
58
+ }
@@ -0,0 +1,3 @@
1
+ import type { YajilinPuzzle } from "./yajilin.types.ts";
2
+ /** Seeded original 5×5 families, accepted only after a completed uniqueness proof. */
3
+ export declare function generateYajilin(size?: 5, seed?: number): YajilinPuzzle;
@@ -0,0 +1,224 @@
1
+ import { isKazuSeed, seededRandom } from "./random.js";
2
+ import { checkYajilin, isYajilinBoard, yajilinNeighbors } from "./yajilinBoard.js";
3
+ import { solveYajilin } from "./yajilinSolve.js";
4
+ const layouts = [
5
+ {
6
+ loop: [6, 7, 8, 13, 18, 17, 16, 11],
7
+ shaded: [1, 22, 5, 9, 24, 12, 20],
8
+ clues: [
9
+ [0, "left", 0],
10
+ [2, "up", 0],
11
+ [3, "up", 0],
12
+ [4, "down", 2],
13
+ [10, "up", 1],
14
+ [14, "down", 1],
15
+ [15, "left", 0],
16
+ [19, "up", 1],
17
+ [21, "down", 0],
18
+ [23, "up", 0],
19
+ ],
20
+ },
21
+ {
22
+ loop: [6, 7, 8, 13, 18, 17, 16, 11],
23
+ shaded: [0, 21, 15, 2, 14, 4, 12],
24
+ clues: [
25
+ [1, "right", 2],
26
+ [3, "left", 2],
27
+ [5, "down", 1],
28
+ [9, "right", 0],
29
+ [10, "down", 1],
30
+ [19, "up", 2],
31
+ [20, "left", 0],
32
+ [22, "up", 2],
33
+ [23, "right", 0],
34
+ [24, "down", 0],
35
+ ],
36
+ },
37
+ {
38
+ loop: [6, 7, 8, 13, 18, 17, 16, 11],
39
+ shaded: [24, 12, 22, 4, 15, 0, 2],
40
+ clues: [
41
+ [1, "right", 2],
42
+ [3, "down", 0],
43
+ [5, "down", 1],
44
+ [9, "right", 0],
45
+ [10, "left", 0],
46
+ [14, "up", 1],
47
+ [19, "left", 1],
48
+ [20, "left", 0],
49
+ [21, "down", 0],
50
+ [23, "right", 1],
51
+ ],
52
+ },
53
+ {
54
+ loop: [6, 7, 8, 13, 18, 17, 16, 11],
55
+ shaded: [12, 9, 2, 21, 0, 19, 10],
56
+ clues: [
57
+ [1, "right", 1],
58
+ [3, "up", 0],
59
+ [4, "down", 2],
60
+ [5, "up", 1],
61
+ [14, "left", 2],
62
+ [15, "right", 1],
63
+ [20, "down", 0],
64
+ [22, "up", 2],
65
+ [23, "up", 0],
66
+ [24, "up", 2],
67
+ ],
68
+ },
69
+ {
70
+ loop: [6, 7, 8, 13, 18, 17, 16, 11],
71
+ shaded: [20, 3, 22, 14, 1, 12, 24],
72
+ clues: [
73
+ [0, "left", 0],
74
+ [2, "down", 2],
75
+ [4, "up", 0],
76
+ [5, "right", 0],
77
+ [9, "down", 2],
78
+ [10, "up", 0],
79
+ [15, "right", 0],
80
+ [19, "up", 1],
81
+ [21, "right", 2],
82
+ [23, "up", 1],
83
+ ],
84
+ },
85
+ {
86
+ loop: [6, 7, 8, 13, 18, 17, 16, 11],
87
+ shaded: [14, 3, 21, 15, 24, 0, 12],
88
+ clues: [
89
+ [1, "up", 0],
90
+ [2, "right", 1],
91
+ [4, "left", 2],
92
+ [5, "right", 0],
93
+ [9, "left", 0],
94
+ [10, "down", 1],
95
+ [19, "left", 1],
96
+ [20, "right", 2],
97
+ [22, "right", 1],
98
+ [23, "left", 1],
99
+ ],
100
+ },
101
+ {
102
+ loop: [6, 7, 8, 13, 18, 17, 16, 11],
103
+ shaded: [15, 24, 9, 21, 5, 3, 1],
104
+ clues: [
105
+ [0, "left", 0],
106
+ [2, "right", 1],
107
+ [4, "right", 0],
108
+ [10, "up", 1],
109
+ [12, "down", 0],
110
+ [14, "right", 0],
111
+ [19, "left", 1],
112
+ [20, "down", 0],
113
+ [22, "up", 0],
114
+ [23, "down", 0],
115
+ ],
116
+ },
117
+ {
118
+ loop: [6, 7, 8, 13, 18, 17, 16, 11],
119
+ shaded: [4, 2, 0, 10, 23, 21, 19],
120
+ clues: [
121
+ [1, "right", 2],
122
+ [3, "left", 2],
123
+ [5, "up", 1],
124
+ [9, "down", 1],
125
+ [12, "down", 0],
126
+ [14, "up", 1],
127
+ [15, "right", 1],
128
+ [20, "right", 2],
129
+ [22, "right", 1],
130
+ [24, "up", 2],
131
+ ],
132
+ },
133
+ {
134
+ loop: [6, 7, 8, 13, 18, 23, 22, 21, 16, 11],
135
+ shaded: [10, 4, 2, 17, 0, 24],
136
+ clues: [
137
+ [1, "right", 2],
138
+ [3, "up", 0],
139
+ [5, "down", 1],
140
+ [9, "down", 1],
141
+ [12, "down", 1],
142
+ [14, "up", 1],
143
+ [15, "right", 1],
144
+ [19, "left", 1],
145
+ [20, "down", 0],
146
+ ],
147
+ },
148
+ {
149
+ loop: [6, 7, 8, 13, 18, 23, 22, 21, 16, 11],
150
+ shaded: [3, 15, 19, 17, 1, 5],
151
+ clues: [
152
+ [0, "left", 0],
153
+ [2, "right", 1],
154
+ [4, "down", 1],
155
+ [9, "down", 1],
156
+ [10, "down", 1],
157
+ [12, "right", 0],
158
+ [14, "down", 1],
159
+ [20, "left", 0],
160
+ [24, "up", 1],
161
+ ],
162
+ },
163
+ {
164
+ loop: [6, 7, 8, 13, 18, 23, 22, 21, 16, 11],
165
+ shaded: [2, 17, 4, 0, 20, 10],
166
+ clues: [
167
+ [1, "left", 1],
168
+ [3, "right", 1],
169
+ [5, "up", 1],
170
+ [9, "left", 0],
171
+ [12, "up", 1],
172
+ [14, "down", 0],
173
+ [15, "up", 2],
174
+ [19, "right", 0],
175
+ [24, "down", 0],
176
+ ],
177
+ },
178
+ ];
179
+ function transformCell(cell, turns, reflect) {
180
+ let x = cell % 5, y = Math.floor(cell / 5);
181
+ if (reflect)
182
+ x = 4 - x;
183
+ for (let turn = 0; turn < turns; turn += 1)
184
+ [x, y] = [4 - y, x];
185
+ return y * 5 + x;
186
+ }
187
+ function transformDirection(direction, turns, reflect) {
188
+ const vector = { up: [0, -1], right: [1, 0], down: [0, 1], left: [-1, 0] };
189
+ let [x, y] = vector[direction];
190
+ if (reflect)
191
+ x = -x;
192
+ for (let turn = 0; turn < turns; turn += 1)
193
+ [x, y] = [-y, x];
194
+ return (Object.entries(vector).find(([, value]) => value[0] === x && value[1] === y)?.[0] ?? "up");
195
+ }
196
+ function edgesFromLoop(board, loop) {
197
+ return loop.map((cell, index) => {
198
+ const next = loop[(index + 1) % loop.length];
199
+ return yajilinNeighbors(board, cell).find(item => item.cell === next).edge;
200
+ }).sort((a, b) => a - b);
201
+ }
202
+ /** Seeded original 5×5 families, accepted only after a completed uniqueness proof. */
203
+ export function generateYajilin(size = 5, seed = 1) {
204
+ if (size !== 5 || !isKazuSeed(seed))
205
+ throw new RangeError("Invalid Yajilin settings");
206
+ const random = seededRandom(seed), layout = layouts[Math.floor(random() * layouts.length)];
207
+ const turns = Math.floor(random() * 4), reflect = random() < 0.5;
208
+ const clues = Array(25).fill(null);
209
+ for (const [cell, direction, count] of layout.clues) {
210
+ const transformed = transformCell(cell, turns, reflect);
211
+ clues[transformed] = { direction: transformDirection(direction, turns, reflect), count };
212
+ }
213
+ const board = { width: 5, height: 5, clues };
214
+ const shaded = Array(25).fill(false);
215
+ for (const cell of layout.shaded)
216
+ shaded[transformCell(cell, turns, reflect)] = true;
217
+ const expectedEdges = edgesFromLoop(board, layout.loop.map(cell => transformCell(cell, turns, reflect)));
218
+ if (!isYajilinBoard(board) || !checkYajilin(board, shaded, expectedEdges).ok)
219
+ throw new Error("Invalid Yajilin layout");
220
+ const proof = solveYajilin(board);
221
+ if (!proof.complete || proof.count !== 1 || !proof.solution)
222
+ throw new Error("No uniquely proved Yajilin found within the generation budget; try another seed");
223
+ return { ...board, seed, solution: proof.solution };
224
+ }
@@ -0,0 +1,2 @@
1
+ import type { YajilinMount, YajilinMountOptions } from "./yajilin.types.ts";
2
+ export declare function mountYajilin(element: HTMLElement, initial: YajilinMountOptions): YajilinMount;
@@ -0,0 +1,162 @@
1
+ import { checkYajilin, yajilinNeighbors } from "./yajilinBoard.js";
2
+ import { decodeYajilin, encodeYajilin, hintYajilin, newYajilin, restartYajilin, toggleYajilinEdge, toggleYajilinShade, undoYajilin } from "./yajilinGame.js";
3
+ import { drawYajilin } from "./yajilinDraw.js";
4
+ import { YAJILIN_PLAY_STYLE } from "./yajilinStyle.js";
5
+ import { YAJILIN_STRINGS } from "./yajilinStrings.js";
6
+ export function mountYajilin(element, initial) {
7
+ const document = element.ownerDocument, style = document.createElement("style");
8
+ style.textContent = YAJILIN_PLAY_STYLE;
9
+ const root = document.createElement("section");
10
+ root.className = "kazu-yajilin";
11
+ const help = document.createElement("p"), board = document.createElement("div");
12
+ board.className = "ky-board";
13
+ const modes = document.createElement("div");
14
+ modes.className = "ky-tools ky-modes";
15
+ const tools = document.createElement("div");
16
+ tools.className = "ky-tools";
17
+ const status = document.createElement("p");
18
+ status.className = "ky-status";
19
+ status.setAttribute("aria-live", "polite");
20
+ root.append(help, modes, board, tools, status);
21
+ element.replaceChildren(style, root);
22
+ let options = { ...initial };
23
+ let game = initial.progress ? decodeYajilin(initial.progress) : null;
24
+ const sameBoard = game && game.board.width === initial.board.width && game.board.height === initial.board.height
25
+ && game.board.clues.every((clue, cell) => JSON.stringify(clue) === JSON.stringify(initial.board.clues[cell]));
26
+ if (!sameBoard)
27
+ game = newYajilin(initial.board);
28
+ let selected = 0, anchor = null, mode = "line";
29
+ let errors = [], message = "", dead = false;
30
+ const words = () => YAJILIN_STRINGS[options.language ?? "en"];
31
+ const copy = () => ({ ...game, board: { ...game.board, clues: game.board.clues.map(clue => clue ? { ...clue } : null) }, shaded: [...game.shaded], edges: [...game.edges], history: game.history.map(turn => ({ shaded: [...turn.shaded], edges: [...turn.edges] })) });
32
+ const changed = () => { options.onChange?.(copy()); if (checkYajilin(game.board, game.shaded, game.edges).ok)
33
+ options.onFinish?.(copy()); };
34
+ const toggleBetween = (first, second) => {
35
+ const edge = yajilinNeighbors(game.board, first).find(next => next.cell === second)?.edge;
36
+ if (edge === undefined)
37
+ return;
38
+ game = toggleYajilinEdge(game, edge);
39
+ anchor = second;
40
+ selected = second;
41
+ errors = [];
42
+ message = "";
43
+ render();
44
+ changed();
45
+ };
46
+ const render = () => {
47
+ if (dead)
48
+ return;
49
+ const w = words();
50
+ help.textContent = w.help;
51
+ board.innerHTML = drawYajilin(game.board, { ...options, shaded: game.shaded, edges: game.edges, selected, errors });
52
+ const controls = document.createElement("div");
53
+ controls.className = "ky-cells";
54
+ controls.style.gridTemplateColumns = `repeat(${game.board.width}, 1fr)`;
55
+ controls.style.gridTemplateRows = `repeat(${game.board.height}, 1fr)`;
56
+ game.board.clues.forEach((clue, cell) => {
57
+ const button = document.createElement("button");
58
+ button.type = "button";
59
+ button.className = "ky-cell";
60
+ button.dataset.cell = String(cell);
61
+ if (clue)
62
+ button.dataset.clue = "true";
63
+ button.textContent = clue ? `${clue.direction} ${clue.count}` : String(cell + 1);
64
+ button.setAttribute("aria-label", clue ? `${clue.direction} ${clue.count}` : `row ${Math.floor(cell / game.board.width) + 1}, column ${cell % game.board.width + 1}${game.shaded[cell] ? ", shaded" : ""}`);
65
+ button.setAttribute("aria-pressed", String(selected === cell));
66
+ button.tabIndex = selected === cell ? 0 : -1;
67
+ button.onclick = () => {
68
+ selected = cell;
69
+ if (mode === "shade") {
70
+ game = toggleYajilinShade(game, cell);
71
+ errors = [];
72
+ changed();
73
+ }
74
+ else if (anchor === null)
75
+ anchor = cell;
76
+ else if (anchor !== cell)
77
+ toggleBetween(anchor, cell);
78
+ render();
79
+ };
80
+ button.onkeydown = event => {
81
+ const x = cell % game.board.width, y = Math.floor(cell / game.board.width);
82
+ const moves = { ArrowUp: [0, -1], ArrowDown: [0, 1], ArrowLeft: [-1, 0], ArrowRight: [1, 0] };
83
+ if (event.key in moves) {
84
+ event.preventDefault();
85
+ const [dx, dy] = moves[event.key], nextX = x + dx, nextY = y + dy;
86
+ if (nextX >= 0 && nextX < game.board.width && nextY >= 0 && nextY < game.board.height) {
87
+ selected = nextY * game.board.width + nextX;
88
+ render();
89
+ board.querySelectorAll(".ky-cell")[selected]?.focus();
90
+ }
91
+ }
92
+ else if (event.key === "Enter") {
93
+ event.preventDefault();
94
+ if (mode === "shade") {
95
+ game = toggleYajilinShade(game, cell);
96
+ errors = [];
97
+ changed();
98
+ }
99
+ else if (anchor === null)
100
+ anchor = cell;
101
+ else if (anchor !== cell)
102
+ toggleBetween(anchor, cell);
103
+ render();
104
+ board.querySelectorAll(".ky-cell")[selected]?.focus();
105
+ }
106
+ else if (event.key === " ") {
107
+ event.preventDefault();
108
+ mode = "shade";
109
+ game = toggleYajilinShade(game, cell);
110
+ errors = [];
111
+ changed();
112
+ render();
113
+ board.querySelectorAll(".ky-cell")[selected]?.focus();
114
+ }
115
+ else if (event.key.toLowerCase() === "l") {
116
+ mode = "line";
117
+ render();
118
+ board.querySelectorAll(".ky-cell")[selected]?.focus();
119
+ }
120
+ else if (event.key.toLowerCase() === "s") {
121
+ mode = "shade";
122
+ render();
123
+ board.querySelectorAll(".ky-cell")[selected]?.focus();
124
+ }
125
+ };
126
+ controls.append(button);
127
+ });
128
+ board.append(controls);
129
+ modes.replaceChildren();
130
+ tools.replaceChildren();
131
+ const add = (host, label, action, pressed) => {
132
+ const button = document.createElement("button");
133
+ button.type = "button";
134
+ button.textContent = label;
135
+ if (pressed !== undefined)
136
+ button.setAttribute("aria-pressed", String(pressed));
137
+ button.onclick = action;
138
+ host.append(button);
139
+ };
140
+ add(modes, w.line, () => { mode = "line"; render(); }, mode === "line");
141
+ add(modes, w.shade, () => { mode = "shade"; render(); }, mode === "shade");
142
+ add(tools, w.undo, () => { game = undoYajilin(game); errors = []; message = ""; render(); changed(); });
143
+ add(tools, w.hint, () => {
144
+ const hint = hintYajilin(game);
145
+ if (!hint)
146
+ message = w.bad;
147
+ else {
148
+ game = hint.type === "shade" ? toggleYajilinShade(game, hint.cell) : toggleYajilinEdge(game, hint.edge);
149
+ game = { ...game, helped: true };
150
+ selected = hint.type === "shade" ? hint.cell : selected;
151
+ message = w.good;
152
+ changed();
153
+ }
154
+ render();
155
+ });
156
+ add(tools, w.check, () => { errors = checkYajilin(game.board, game.shaded, game.edges).errors; message = errors.length ? w.bad : w.good; render(); });
157
+ add(tools, w.restart, () => { game = restartYajilin(game); anchor = null; errors = []; message = ""; render(); changed(); });
158
+ status.textContent = checkYajilin(game.board, game.shaded, game.edges).ok ? (game.helped ? w.helped : w.won) : message;
159
+ };
160
+ render();
161
+ return { game: copy, progress: () => encodeYajilin(game), set: next => { options = { ...options, ...next }; render(); }, restart: () => { game = restartYajilin(game); anchor = null; render(); changed(); }, destroy: () => { dead = true; element.replaceChildren(); } };
162
+ }
@@ -0,0 +1 @@
1
+ export type { YajilinDrawOptions as YajilinDrawOptions, YajilinMount as YajilinMount, YajilinMountOptions as YajilinMountOptions } from "./yajilin.types.ts";
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ import type { YajilinBoard, YajilinSolve } from "./yajilin.types.ts";
2
+ /** Counts public shade patterns whose remaining cells form the single required loop. */
3
+ export declare function solveYajilin(board: YajilinBoard, options?: {
4
+ limit?: number;
5
+ nodes?: number;
6
+ }): YajilinSolve;
@@ -0,0 +1,82 @@
1
+ import { YAJILIN_NODE_BUDGET } from "./yajilin.constants.js";
2
+ import { checkYajilin, isYajilinBoard, yajilinNeighbors, yajilinRay } from "./yajilinBoard.js";
3
+ /** Counts public shade patterns whose remaining cells form the single required loop. */
4
+ export function solveYajilin(board, options = {}) {
5
+ if (!isYajilinBoard(board))
6
+ throw new RangeError("Invalid Yajilin board");
7
+ const limit = options.limit ?? 2, budget = options.nodes ?? YAJILIN_NODE_BUDGET;
8
+ if (!Number.isInteger(limit) || limit < 1 || !Number.isInteger(budget) || budget < 1)
9
+ throw new RangeError("Invalid search bounds");
10
+ const total = board.width * board.height, state = Array(total).fill(-1), shadeable = [];
11
+ const rays = board.clues.flatMap((clue, cell) => clue ? [{ cell, clue, cells: yajilinRay(board, cell, clue.direction) }] : []);
12
+ board.clues.forEach((clue, cell) => { if (clue)
13
+ state[cell] = 2;
14
+ else
15
+ shadeable.push(cell); });
16
+ let count = 0, nodes = 0, complete = true, solution = null;
17
+ const candidateEdges = (shaded) => {
18
+ const edges = [];
19
+ for (let cell = 0; cell < total; cell += 1) {
20
+ if (board.clues[cell] || shaded[cell])
21
+ continue;
22
+ for (const next of yajilinNeighbors(board, cell))
23
+ if (cell < next.cell && !board.clues[next.cell] && !shaded[next.cell])
24
+ edges.push(next.edge);
25
+ }
26
+ return edges;
27
+ };
28
+ const raysPossible = () => rays.every(({ clue, cells }) => {
29
+ const shaded = cells.filter(cell => state[cell] === 1).length;
30
+ const unknown = cells.filter(cell => state[cell] === -1).length;
31
+ return shaded <= clue.count && shaded + unknown >= clue.count;
32
+ });
33
+ const visit = (depth) => {
34
+ if (++nodes > budget) {
35
+ complete = false;
36
+ return;
37
+ }
38
+ if (!raysPossible())
39
+ return;
40
+ if (depth === shadeable.length) {
41
+ const shaded = state.map(value => value === 1), edges = candidateEdges(shaded);
42
+ if (!checkYajilin(board, shaded, edges).ok)
43
+ return;
44
+ count += 1;
45
+ solution ?? (solution = { shaded, edges });
46
+ if (count >= limit)
47
+ complete = false;
48
+ return;
49
+ }
50
+ let chosen = -1, bestScore = -1;
51
+ for (const cell of shadeable) {
52
+ if (state[cell] !== -1)
53
+ continue;
54
+ let score = 0;
55
+ for (const clue of rays)
56
+ if (clue.cells.includes(cell))
57
+ score += 1;
58
+ if (score > bestScore) {
59
+ chosen = cell;
60
+ bestScore = score;
61
+ }
62
+ }
63
+ if (chosen < 0)
64
+ return;
65
+ state[chosen] = 0;
66
+ visit(depth + 1);
67
+ if (!complete) {
68
+ state[chosen] = -1;
69
+ return;
70
+ }
71
+ const x = chosen % board.width, y = Math.floor(chosen / board.width);
72
+ const touchesShade = (x > 0 && state[chosen - 1] === 1) || (x + 1 < board.width && state[chosen + 1] === 1)
73
+ || (y > 0 && state[chosen - board.width] === 1) || (y + 1 < board.height && state[chosen + board.width] === 1);
74
+ if (!touchesShade) {
75
+ state[chosen] = 1;
76
+ visit(depth + 1);
77
+ }
78
+ state[chosen] = -1;
79
+ };
80
+ visit(0);
81
+ return { count, solution, complete, nodes };
82
+ }
@@ -0,0 +1,32 @@
1
+ export declare const YAJILIN_STRINGS: {
2
+ readonly en: {
3
+ readonly title: "Yajilin";
4
+ readonly help: "Shade the number of cells each arrow points to. Shaded cells cannot touch. Every other empty cell is part of one loop.";
5
+ readonly line: "Line";
6
+ readonly shade: "Shade";
7
+ readonly undo: "Undo";
8
+ readonly hint: "Hint";
9
+ readonly check: "Check";
10
+ readonly restart: "Restart";
11
+ readonly won: "Solved!";
12
+ readonly helped: "Solved with help.";
13
+ readonly good: "Keep going; the loop is not complete yet.";
14
+ readonly bad: "Check the marked cells, arrows, and line.";
15
+ readonly cell: "cell";
16
+ };
17
+ readonly ja: {
18
+ readonly title: "やじりん";
19
+ readonly help: "矢印の先にある黒マスの数を合わせます。黒マスは辺で隣り合えません。残りの空きマスを一つの輪にします。";
20
+ readonly line: "線";
21
+ readonly shade: "黒マス";
22
+ readonly undo: "戻す";
23
+ readonly hint: "ヒント";
24
+ readonly check: "確認";
25
+ readonly restart: "やり直す";
26
+ readonly won: "完成!";
27
+ readonly helped: "ヒントを使って完成。";
28
+ readonly good: "輪はまだ完成していません。続けましょう。";
29
+ readonly bad: "印のついたマス、矢印、線を確認してください。";
30
+ readonly cell: "マス";
31
+ };
32
+ };
@@ -0,0 +1,4 @@
1
+ export const YAJILIN_STRINGS = {
2
+ en: { title: "Yajilin", help: "Shade the number of cells each arrow points to. Shaded cells cannot touch. Every other empty cell is part of one loop.", line: "Line", shade: "Shade", undo: "Undo", hint: "Hint", check: "Check", restart: "Restart", won: "Solved!", helped: "Solved with help.", good: "Keep going; the loop is not complete yet.", bad: "Check the marked cells, arrows, and line.", cell: "cell" },
3
+ ja: { title: "やじりん", help: "矢印の先にある黒マスの数を合わせます。黒マスは辺で隣り合えません。残りの空きマスを一つの輪にします。", line: "線", shade: "黒マス", undo: "戻す", hint: "ヒント", check: "確認", restart: "やり直す", won: "完成!", helped: "ヒントを使って完成。", good: "輪はまだ完成していません。続けましょう。", bad: "印のついたマス、矢印、線を確認してください。", cell: "マス" },
4
+ };
@@ -0,0 +1 @@
1
+ export declare const YAJILIN_PLAY_STYLE = "\n.kazu-yajilin { color:var(--kz-ink,#1f2320); font:16px/1.4 system-ui,sans-serif; }\n.kazu-yajilin .ky-board { position:relative; max-width:440px; margin:auto; }\n.kazu-yajilin svg { border:1px solid var(--kz-frame,#a98954); border-radius:4px; }\n.kazu-yajilin .ky-cells { position:absolute; inset:6%; display:grid; }\n.kazu-yajilin .ky-cell { border:0; background:transparent; color:transparent; cursor:pointer; }\n.kazu-yajilin .ky-cell:focus-visible { outline:3px solid var(--kz-focus,#c57d2d); outline-offset:-5px; }\n.kazu-yajilin .ky-tools { display:flex; flex-wrap:wrap; gap:.5rem; justify-content:center; margin:.8rem 0; }\n.kazu-yajilin button { font:inherit; padding:.45rem .8rem; }\n.kazu-yajilin .ky-status { min-height:1.5em; text-align:center; }\n.kazu-yajilin .ky-modes [aria-pressed=\"true\"] { outline:2px solid var(--kz-frame,#a98954); }\n";
@@ -0,0 +1,12 @@
1
+ export const YAJILIN_PLAY_STYLE = `
2
+ .kazu-yajilin { color:var(--kz-ink,#1f2320); font:16px/1.4 system-ui,sans-serif; }
3
+ .kazu-yajilin .ky-board { position:relative; max-width:440px; margin:auto; }
4
+ .kazu-yajilin svg { border:1px solid var(--kz-frame,#a98954); border-radius:4px; }
5
+ .kazu-yajilin .ky-cells { position:absolute; inset:6%; display:grid; }
6
+ .kazu-yajilin .ky-cell { border:0; background:transparent; color:transparent; cursor:pointer; }
7
+ .kazu-yajilin .ky-cell:focus-visible { outline:3px solid var(--kz-focus,#c57d2d); outline-offset:-5px; }
8
+ .kazu-yajilin .ky-tools { display:flex; flex-wrap:wrap; gap:.5rem; justify-content:center; margin:.8rem 0; }
9
+ .kazu-yajilin button { font:inherit; padding:.45rem .8rem; }
10
+ .kazu-yajilin .ky-status { min-height:1.5em; text-align:center; }
11
+ .kazu-yajilin .ky-modes [aria-pressed="true"] { outline:2px solid var(--kz-frame,#a98954); }
12
+ `;