@hackersheet/next-document-content-kifu 0.1.0-alpha.2 → 0.1.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/kifu/kifu.d.ts +1 -1
- package/dist/cjs/components/kifu/kifu.js +4 -21
- package/dist/cjs/components/shogi-player/button.d.ts +8 -0
- package/dist/cjs/components/shogi-player/button.js +44 -0
- package/dist/cjs/components/shogi-player/index.d.ts +2 -0
- package/dist/cjs/components/shogi-player/index.js +38 -0
- package/dist/cjs/components/shogi-player/moves-area.d.ts +11 -0
- package/dist/cjs/components/shogi-player/moves-area.js +74 -0
- package/dist/cjs/components/shogi-player/shogi-board-canvas.d.ts +17 -0
- package/dist/cjs/components/shogi-player/shogi-board-canvas.js +167 -0
- package/dist/cjs/components/shogi-player/shogi-hands-canvas.d.ts +16 -0
- package/dist/cjs/components/shogi-player/shogi-hands-canvas.js +121 -0
- package/dist/cjs/components/shogi-player/shogi-player.d.ts +8 -0
- package/dist/cjs/components/shogi-player/shogi-player.js +78 -0
- package/dist/cjs/index.js +3 -3
- package/dist/esm/components/kifu/kifu.d.mts +1 -1
- package/dist/esm/components/kifu/kifu.mjs +5 -22
- package/dist/esm/components/shogi-player/button.d.mts +8 -0
- package/dist/esm/components/shogi-player/button.mjs +14 -0
- package/dist/esm/components/shogi-player/index.d.mts +2 -0
- package/dist/esm/components/shogi-player/index.mjs +4 -0
- package/dist/esm/components/shogi-player/moves-area.d.mts +11 -0
- package/dist/esm/components/shogi-player/moves-area.mjs +40 -0
- package/dist/esm/components/shogi-player/shogi-board-canvas.d.mts +17 -0
- package/dist/esm/components/shogi-player/shogi-board-canvas.mjs +137 -0
- package/dist/esm/components/shogi-player/shogi-hands-canvas.d.mts +16 -0
- package/dist/esm/components/shogi-player/shogi-hands-canvas.mjs +91 -0
- package/dist/esm/components/shogi-player/shogi-player.d.mts +8 -0
- package/dist/esm/components/shogi-player/shogi-player.mjs +48 -0
- package/package.json +13 -13
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { KifuComponentProps } from '@hackersheet/react-document-content';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
|
|
4
|
-
declare function Kifu({ code, language }: KifuComponentProps): React.JSX.Element
|
|
4
|
+
declare function Kifu({ code, language }: KifuComponentProps): React.JSX.Element;
|
|
5
5
|
|
|
6
6
|
export { Kifu as default };
|
|
@@ -32,36 +32,19 @@ __export(kifu_exports, {
|
|
|
32
32
|
default: () => Kifu
|
|
33
33
|
});
|
|
34
34
|
module.exports = __toCommonJS(kifu_exports);
|
|
35
|
-
var import_kifu_for_js = require("kifu-for-js");
|
|
36
35
|
var import_navigation = require("next/navigation");
|
|
37
36
|
var import_react = __toESM(require("react"));
|
|
37
|
+
var import_shogi_player = require("../shogi-player");
|
|
38
38
|
function Kifu({ code, language }) {
|
|
39
39
|
const [, filename] = language.split(":");
|
|
40
40
|
const searchParams = (0, import_navigation.useSearchParams)();
|
|
41
41
|
const id = filename ? `user-content-${filename}` : void 0;
|
|
42
|
-
const [kifuStore] = (0, import_react.useState)(() => new import_kifu_for_js.KifuStore({ kifu: code }));
|
|
43
|
-
(0, import_react.useEffect)(() => {
|
|
44
|
-
initKifuUserSettings();
|
|
45
|
-
}, []);
|
|
46
42
|
(0, import_react.useEffect)(() => {
|
|
47
43
|
const newPly = Number(searchParams.get("ply") ?? 0);
|
|
48
44
|
const hash = typeof window !== "undefined" ? window.location.hash.replace(/^#!?/, "") : "";
|
|
49
45
|
if (hash === id) {
|
|
50
|
-
|
|
46
|
+
console.log(newPly);
|
|
51
47
|
}
|
|
52
|
-
}, [searchParams,
|
|
53
|
-
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
|
-
return /* @__PURE__ */ import_react.default.createElement("div", { className: "kifu-block", id }, /* @__PURE__ */ import_react.default.createElement(import_kifu_for_js.KifuLite, { style: { width: "100%" }, kifuStore }));
|
|
57
|
-
}
|
|
58
|
-
function initKifuUserSettings() {
|
|
59
|
-
const LOCALSTORAGE_KEY = "kifuforjs";
|
|
60
|
-
const defaultSettings = {
|
|
61
|
-
hapticFeedback: false
|
|
62
|
-
};
|
|
63
|
-
const settings = localStorage.getItem(LOCALSTORAGE_KEY);
|
|
64
|
-
if (!settings) {
|
|
65
|
-
localStorage.setItem(LOCALSTORAGE_KEY, JSON.stringify(defaultSettings));
|
|
66
|
-
}
|
|
48
|
+
}, [searchParams, id]);
|
|
49
|
+
return /* @__PURE__ */ import_react.default.createElement("div", { className: "kifu-block", id }, /* @__PURE__ */ import_react.default.createElement(import_shogi_player.ShogiPlayer, { kifuText: code }));
|
|
67
50
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React, { MouseEventHandler, PropsWithChildren } from 'react';
|
|
2
|
+
|
|
3
|
+
type ButtonProps = {
|
|
4
|
+
onClick?: MouseEventHandler<HTMLButtonElement>;
|
|
5
|
+
} & PropsWithChildren;
|
|
6
|
+
declare function Button({ children, onClick }: ButtonProps): React.JSX.Element;
|
|
7
|
+
|
|
8
|
+
export { type ButtonProps, Button as default };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var button_exports = {};
|
|
30
|
+
__export(button_exports, {
|
|
31
|
+
default: () => Button
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(button_exports);
|
|
34
|
+
var import_react = __toESM(require("react"));
|
|
35
|
+
function Button({ children, onClick }) {
|
|
36
|
+
return /* @__PURE__ */ import_react.default.createElement(
|
|
37
|
+
"button",
|
|
38
|
+
{
|
|
39
|
+
className: "border-2 text-black p-2 border-black rounded-lg hover:bg-amber-100 cursor-pointer",
|
|
40
|
+
onClick
|
|
41
|
+
},
|
|
42
|
+
children
|
|
43
|
+
);
|
|
44
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var shogi_player_exports = {};
|
|
30
|
+
__export(shogi_player_exports, {
|
|
31
|
+
ShogiPlayer: () => import_shogi_player.default
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(shogi_player_exports);
|
|
34
|
+
var import_shogi_player = __toESM(require("./shogi-player"));
|
|
35
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
36
|
+
0 && (module.exports = {
|
|
37
|
+
ShogiPlayer
|
|
38
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IMoveFormat } from 'json-kifu-format/dist/src/Formats';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
type MovesAreaProps = {
|
|
5
|
+
moves: IMoveFormat[];
|
|
6
|
+
tesuu: number;
|
|
7
|
+
onTesuuChange?: (tesuu: number) => void;
|
|
8
|
+
};
|
|
9
|
+
declare function MovesArea(props: MovesAreaProps): React.JSX.Element;
|
|
10
|
+
|
|
11
|
+
export { MovesArea, type MovesAreaProps };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
var moves_area_exports = {};
|
|
31
|
+
__export(moves_area_exports, {
|
|
32
|
+
MovesArea: () => MovesArea
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(moves_area_exports);
|
|
35
|
+
var import_json_kifu_format = require("json-kifu-format");
|
|
36
|
+
var import_react = __toESM(require("react"));
|
|
37
|
+
function MovesArea(props) {
|
|
38
|
+
const moves = props.moves;
|
|
39
|
+
const scrollRef = (0, import_react.useRef)(null);
|
|
40
|
+
const containerRef = (0, import_react.useRef)(null);
|
|
41
|
+
(0, import_react.useEffect)(() => {
|
|
42
|
+
if (scrollRef.current && containerRef.current) {
|
|
43
|
+
const containerRect = containerRef.current.getBoundingClientRect();
|
|
44
|
+
const scrollRect = scrollRef.current.getBoundingClientRect();
|
|
45
|
+
const offset = scrollRect.top - containerRect.top + containerRef.current.scrollTop - 72;
|
|
46
|
+
containerRef.current.scrollTo({
|
|
47
|
+
top: offset,
|
|
48
|
+
behavior: "auto"
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}, [props.tesuu]);
|
|
52
|
+
return /* @__PURE__ */ import_react.default.createElement("div", { className: "absolute overflow-y-auto h-full w-full border-2 border-black text-black", ref: containerRef }, /* @__PURE__ */ import_react.default.createElement("div", { className: "w-full text-xs grid" }, 0 === props.tesuu && /* @__PURE__ */ import_react.default.createElement("div", { ref: scrollRef }), /* @__PURE__ */ import_react.default.createElement(
|
|
53
|
+
"div",
|
|
54
|
+
{
|
|
55
|
+
onClick: () => props.onTesuuChange && props.onTesuuChange(0),
|
|
56
|
+
className: 0 === props.tesuu ? "bg-yellow-100 cursor-pointer flex p-2" : "cursor-pointer hover:bg-amber-300 flex p-2"
|
|
57
|
+
},
|
|
58
|
+
/* @__PURE__ */ import_react.default.createElement("div", null, "\u958B\u59CB\u5C40\u9762")
|
|
59
|
+
), moves.map(
|
|
60
|
+
(move, index) => index > 0 && /* @__PURE__ */ import_react.default.createElement(import_react.Fragment, { key: index }, index === props.tesuu && /* @__PURE__ */ import_react.default.createElement("div", { ref: scrollRef }), /* @__PURE__ */ import_react.default.createElement(
|
|
61
|
+
"div",
|
|
62
|
+
{
|
|
63
|
+
className: index === props.tesuu ? "bg-yellow-100 border-t border-black/60 cursor-pointer grid-rows-1 p-2" : "border-t border-black/60 cursor-pointer hover:bg-amber-300 grid-rows-1 p-2",
|
|
64
|
+
onClick: () => props.onTesuuChange && props.onTesuuChange(index)
|
|
65
|
+
},
|
|
66
|
+
/* @__PURE__ */ import_react.default.createElement("div", null, /* @__PURE__ */ import_react.default.createElement("div", null, index)),
|
|
67
|
+
/* @__PURE__ */ import_react.default.createElement("div", null, import_json_kifu_format.JKFPlayer.moveToReadableKifu(move))
|
|
68
|
+
))
|
|
69
|
+
)));
|
|
70
|
+
}
|
|
71
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
72
|
+
0 && (module.exports = {
|
|
73
|
+
MovesArea
|
|
74
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { IMoveMoveFormat } from 'json-kifu-format/dist/src/Formats';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Piece } from 'shogi.js';
|
|
4
|
+
|
|
5
|
+
type Props = {
|
|
6
|
+
size?: number;
|
|
7
|
+
boardColor?: string;
|
|
8
|
+
lineColor?: string;
|
|
9
|
+
fontFamily?: string;
|
|
10
|
+
fontSizeRatio?: number;
|
|
11
|
+
pieces: Piece[][];
|
|
12
|
+
isSente?: boolean;
|
|
13
|
+
currentMove?: IMoveMoveFormat;
|
|
14
|
+
};
|
|
15
|
+
declare const ShogiBoardCanvas: React.FC<Props>;
|
|
16
|
+
|
|
17
|
+
export { ShogiBoardCanvas as default };
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
var shogi_board_canvas_exports = {};
|
|
31
|
+
__export(shogi_board_canvas_exports, {
|
|
32
|
+
default: () => shogi_board_canvas_default
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(shogi_board_canvas_exports);
|
|
35
|
+
var import_json_kifu_format = require("json-kifu-format");
|
|
36
|
+
var import_react = __toESM(require("react"));
|
|
37
|
+
var import_shogi = require("shogi.js");
|
|
38
|
+
const getCanvasDimensions = (size) => {
|
|
39
|
+
const dpr = window.devicePixelRatio || 1;
|
|
40
|
+
return { width: size * dpr, height: size * dpr, dpr };
|
|
41
|
+
};
|
|
42
|
+
const getBoardLayout = (size) => {
|
|
43
|
+
const margin = size * 0.06;
|
|
44
|
+
const boardSize = size - margin * 2;
|
|
45
|
+
const cell = boardSize / 9;
|
|
46
|
+
return { margin, boardSize, cell };
|
|
47
|
+
};
|
|
48
|
+
const drawBackground = (ctx, size, boardColor) => {
|
|
49
|
+
ctx.fillStyle = boardColor;
|
|
50
|
+
ctx.fillRect(0, 0, size, size);
|
|
51
|
+
};
|
|
52
|
+
const drawBoard = (ctx, margin, boardSize, lineColor) => {
|
|
53
|
+
ctx.strokeStyle = lineColor;
|
|
54
|
+
ctx.lineWidth = 2;
|
|
55
|
+
ctx.strokeRect(margin, margin, boardSize, boardSize);
|
|
56
|
+
ctx.lineWidth = 1;
|
|
57
|
+
Array.from({ length: 8 }).forEach((_, i) => {
|
|
58
|
+
const offset = (i + 1) * (boardSize / 9);
|
|
59
|
+
ctx.beginPath();
|
|
60
|
+
ctx.moveTo(margin + offset, margin);
|
|
61
|
+
ctx.lineTo(margin + offset, margin + boardSize);
|
|
62
|
+
ctx.stroke();
|
|
63
|
+
ctx.beginPath();
|
|
64
|
+
ctx.moveTo(margin, margin + offset);
|
|
65
|
+
ctx.lineTo(margin + boardSize, margin + offset);
|
|
66
|
+
ctx.stroke();
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
const drawPieces = (ctx, pieces, margin, cell, fontFamily, fontSizeRatio, isSente, currentMove) => {
|
|
70
|
+
ctx.textAlign = "center";
|
|
71
|
+
ctx.textBaseline = "middle";
|
|
72
|
+
pieces.forEach((row, rowIndex) => {
|
|
73
|
+
row.forEach((piece, colIndex) => {
|
|
74
|
+
if (!piece) return;
|
|
75
|
+
const x = isSente ? 8 - rowIndex : rowIndex;
|
|
76
|
+
const y = isSente ? colIndex : 8 - colIndex;
|
|
77
|
+
const px = margin + x * cell + cell / 2;
|
|
78
|
+
const py = margin + y * cell + cell / 2;
|
|
79
|
+
ctx.save();
|
|
80
|
+
ctx.translate(px, py);
|
|
81
|
+
if (isSente && piece.color === import_shogi.Color.White) {
|
|
82
|
+
ctx.rotate(Math.PI);
|
|
83
|
+
} else if (!isSente && piece.color === import_shogi.Color.Black) {
|
|
84
|
+
ctx.rotate(Math.PI);
|
|
85
|
+
}
|
|
86
|
+
const kan = import_json_kifu_format.JKFPlayer.kindToKan(piece.kind);
|
|
87
|
+
ctx.fillStyle = "#000";
|
|
88
|
+
if (currentMove) {
|
|
89
|
+
const to = currentMove.to;
|
|
90
|
+
if (to && to.x === rowIndex + 1 && to.y === colIndex + 1) {
|
|
91
|
+
ctx.fillStyle = "red";
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (kan.length === 2) {
|
|
95
|
+
const baseFontSize = cell * fontSizeRatio * 0.5;
|
|
96
|
+
ctx.font = `${baseFontSize}px ${fontFamily}`;
|
|
97
|
+
const scaleX = 2;
|
|
98
|
+
const scaleY = 1;
|
|
99
|
+
const offsetY = cell * 0.18;
|
|
100
|
+
ctx.save();
|
|
101
|
+
ctx.scale(scaleX, scaleY);
|
|
102
|
+
ctx.fillText(kan[0], 0 / scaleX, -offsetY / scaleY);
|
|
103
|
+
ctx.restore();
|
|
104
|
+
ctx.save();
|
|
105
|
+
ctx.scale(scaleX, scaleY);
|
|
106
|
+
ctx.fillText(kan[1], 0 / scaleX, offsetY / scaleY);
|
|
107
|
+
ctx.restore();
|
|
108
|
+
} else {
|
|
109
|
+
const fontSize = cell * fontSizeRatio;
|
|
110
|
+
ctx.font = `${fontSize}px ${fontFamily}`;
|
|
111
|
+
ctx.fillText(kan, 0, 0);
|
|
112
|
+
}
|
|
113
|
+
ctx.restore();
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
};
|
|
117
|
+
const drawCoordinates = (ctx, margin, boardSize, cell, fontFamily, isSente) => {
|
|
118
|
+
ctx.fillStyle = "#000";
|
|
119
|
+
ctx.font = `${cell * 0.35}px ${fontFamily}`;
|
|
120
|
+
ctx.textAlign = "center";
|
|
121
|
+
ctx.textBaseline = "middle";
|
|
122
|
+
Array.from({ length: 9 }).forEach((_, i) => {
|
|
123
|
+
const x = margin + i * cell + cell / 2;
|
|
124
|
+
const y = margin / 2;
|
|
125
|
+
const label = isSente ? (9 - i).toString() : (i + 1).toString();
|
|
126
|
+
ctx.fillText(label, x, y);
|
|
127
|
+
});
|
|
128
|
+
const kanji = ["\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D", "\u4E03", "\u516B", "\u4E5D"];
|
|
129
|
+
kanji.forEach((k, i) => {
|
|
130
|
+
const x = margin + boardSize + margin / 2;
|
|
131
|
+
const y = margin + i * cell + cell / 2;
|
|
132
|
+
const label = isSente ? k : kanji[8 - i];
|
|
133
|
+
ctx.fillText(label, x, y);
|
|
134
|
+
});
|
|
135
|
+
};
|
|
136
|
+
const ShogiBoardCanvas = ({
|
|
137
|
+
size = 360,
|
|
138
|
+
boardColor = "#f9d27a",
|
|
139
|
+
lineColor = "#000",
|
|
140
|
+
fontFamily = "serif",
|
|
141
|
+
fontSizeRatio = 0.7,
|
|
142
|
+
pieces,
|
|
143
|
+
isSente = true,
|
|
144
|
+
currentMove
|
|
145
|
+
}) => {
|
|
146
|
+
const canvasRef = import_react.default.useRef(null);
|
|
147
|
+
import_react.default.useEffect(() => {
|
|
148
|
+
const canvas = canvasRef.current;
|
|
149
|
+
if (!canvas) return;
|
|
150
|
+
const ctx = canvas.getContext("2d");
|
|
151
|
+
if (!ctx) return;
|
|
152
|
+
const { width, height, dpr } = getCanvasDimensions(size);
|
|
153
|
+
canvas.width = width;
|
|
154
|
+
canvas.height = height;
|
|
155
|
+
canvas.style.width = `${size}px`;
|
|
156
|
+
canvas.style.height = `${size}px`;
|
|
157
|
+
ctx.scale(dpr, dpr);
|
|
158
|
+
ctx.clearRect(0, 0, size, size);
|
|
159
|
+
const { margin, boardSize, cell } = getBoardLayout(size);
|
|
160
|
+
drawBackground(ctx, size, boardColor);
|
|
161
|
+
drawBoard(ctx, margin, boardSize, lineColor);
|
|
162
|
+
drawPieces(ctx, pieces, margin, cell, fontFamily, fontSizeRatio, isSente, currentMove);
|
|
163
|
+
drawCoordinates(ctx, margin, boardSize, cell, fontFamily, isSente);
|
|
164
|
+
}, [size, boardColor, lineColor, fontFamily, fontSizeRatio, pieces, isSente, currentMove]);
|
|
165
|
+
return /* @__PURE__ */ import_react.default.createElement("canvas", { ref: canvasRef, width: size, height: size });
|
|
166
|
+
};
|
|
167
|
+
var shogi_board_canvas_default = ShogiBoardCanvas;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Piece } from 'shogi.js';
|
|
3
|
+
|
|
4
|
+
type Props = {
|
|
5
|
+
size?: number;
|
|
6
|
+
boardColor?: string;
|
|
7
|
+
lineColor?: string;
|
|
8
|
+
fontFamily?: string;
|
|
9
|
+
fontSizeRatio?: number;
|
|
10
|
+
hands: Piece[][];
|
|
11
|
+
isSente?: boolean;
|
|
12
|
+
isTop?: boolean;
|
|
13
|
+
};
|
|
14
|
+
declare const ShogiHandsCanvas: React.FC<Props>;
|
|
15
|
+
|
|
16
|
+
export { ShogiHandsCanvas as default };
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
var shogi_hands_canvas_exports = {};
|
|
31
|
+
__export(shogi_hands_canvas_exports, {
|
|
32
|
+
default: () => shogi_hands_canvas_default
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(shogi_hands_canvas_exports);
|
|
35
|
+
var import_json_kifu_format = require("json-kifu-format");
|
|
36
|
+
var import_react = __toESM(require("react"));
|
|
37
|
+
var import_shogi = require("shogi.js");
|
|
38
|
+
const getCanvasDimensions = (size) => {
|
|
39
|
+
const dpr = window.devicePixelRatio || 1;
|
|
40
|
+
return { width: size * dpr, height: size * dpr, dpr };
|
|
41
|
+
};
|
|
42
|
+
const getHandsLayout = (size) => {
|
|
43
|
+
const margin = size * 0.06;
|
|
44
|
+
const boardSize = size - margin * 2;
|
|
45
|
+
const cellSize = boardSize / 9;
|
|
46
|
+
const handsHeight = cellSize + margin + 2;
|
|
47
|
+
return { margin, handsHeight, boardSize, cellSize };
|
|
48
|
+
};
|
|
49
|
+
const drawBackground = (ctx, width, height, color) => {
|
|
50
|
+
ctx.fillStyle = color;
|
|
51
|
+
ctx.fillRect(0, 0, width, height);
|
|
52
|
+
};
|
|
53
|
+
const drawHandsFrame = (ctx, x, y, width, height, lineColor, isTop) => {
|
|
54
|
+
ctx.strokeStyle = lineColor;
|
|
55
|
+
ctx.lineWidth = 2;
|
|
56
|
+
if (isTop) {
|
|
57
|
+
ctx.strokeRect(x, y, width, height);
|
|
58
|
+
} else {
|
|
59
|
+
ctx.strokeRect(x, 2, width, height);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const drawCoordinates = (ctx, fontSize, fontFamily) => {
|
|
63
|
+
ctx.fillStyle = "#000";
|
|
64
|
+
ctx.font = `${fontSize}px ${fontFamily}`;
|
|
65
|
+
ctx.textAlign = "center";
|
|
66
|
+
ctx.textBaseline = "middle";
|
|
67
|
+
};
|
|
68
|
+
const drawPieces = (ctx, hands, margin, cell, fontFamily, fontSizeRatio, isSente, isTop) => {
|
|
69
|
+
ctx.textAlign = "center";
|
|
70
|
+
ctx.textBaseline = "middle";
|
|
71
|
+
const pieces = isSente && isTop || !isSente && !isTop ? hands[import_shogi.Color.White] : hands[import_shogi.Color.Black];
|
|
72
|
+
pieces.forEach((piece, index) => {
|
|
73
|
+
if (!piece) return;
|
|
74
|
+
const px = margin + index * cell + cell / 2;
|
|
75
|
+
const py = isTop ? margin + cell / 2 : cell / 2 + 2;
|
|
76
|
+
ctx.save();
|
|
77
|
+
ctx.translate(px, py);
|
|
78
|
+
if (isSente && piece.color === import_shogi.Color.White) {
|
|
79
|
+
ctx.rotate(Math.PI);
|
|
80
|
+
} else if (!isSente && piece.color === import_shogi.Color.Black) {
|
|
81
|
+
ctx.rotate(Math.PI);
|
|
82
|
+
}
|
|
83
|
+
const fontSize = cell * fontSizeRatio;
|
|
84
|
+
const kan = import_json_kifu_format.JKFPlayer.kindToKan(piece.kind);
|
|
85
|
+
ctx.font = `${fontSize}px ${fontFamily}`;
|
|
86
|
+
ctx.fillText(kan, 0, 0);
|
|
87
|
+
ctx.restore();
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
const ShogiHandsCanvas = ({
|
|
91
|
+
size = 360,
|
|
92
|
+
boardColor = "#f9d27a",
|
|
93
|
+
lineColor = "#000",
|
|
94
|
+
fontFamily = "serif",
|
|
95
|
+
fontSizeRatio = 0.7,
|
|
96
|
+
hands,
|
|
97
|
+
isSente = true,
|
|
98
|
+
isTop = false
|
|
99
|
+
}) => {
|
|
100
|
+
const canvasRef = import_react.default.useRef(null);
|
|
101
|
+
import_react.default.useEffect(() => {
|
|
102
|
+
const canvas = canvasRef.current;
|
|
103
|
+
if (!canvas) return;
|
|
104
|
+
const ctx = canvas.getContext("2d");
|
|
105
|
+
if (!ctx) return;
|
|
106
|
+
const { margin, handsHeight, boardSize, cellSize } = getHandsLayout(size);
|
|
107
|
+
const { width: canvasWidth, dpr } = getCanvasDimensions(size);
|
|
108
|
+
canvas.width = canvasWidth;
|
|
109
|
+
canvas.height = handsHeight * dpr;
|
|
110
|
+
canvas.style.width = `${size}px`;
|
|
111
|
+
canvas.style.height = `${handsHeight}px`;
|
|
112
|
+
ctx.scale(dpr, dpr);
|
|
113
|
+
ctx.clearRect(0, 0, size, handsHeight);
|
|
114
|
+
drawBackground(ctx, size, handsHeight, boardColor);
|
|
115
|
+
drawHandsFrame(ctx, margin, margin, boardSize, cellSize, lineColor, isTop);
|
|
116
|
+
drawCoordinates(ctx, cellSize * 0.35, fontFamily);
|
|
117
|
+
drawPieces(ctx, hands, margin, cellSize, fontFamily, fontSizeRatio, isSente, isTop);
|
|
118
|
+
}, [size, boardColor, lineColor, fontFamily, fontSizeRatio, isSente, hands, isTop]);
|
|
119
|
+
return /* @__PURE__ */ import_react.default.createElement("canvas", { ref: canvasRef });
|
|
120
|
+
};
|
|
121
|
+
var shogi_hands_canvas_default = ShogiHandsCanvas;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
var shogi_player_exports = {};
|
|
31
|
+
__export(shogi_player_exports, {
|
|
32
|
+
default: () => ShogiPlayer
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(shogi_player_exports);
|
|
35
|
+
var import_json_kifu_format = require("json-kifu-format");
|
|
36
|
+
var import_react = __toESM(require("react"));
|
|
37
|
+
var import_button = __toESM(require("./button"));
|
|
38
|
+
var import_moves_area = require("./moves-area");
|
|
39
|
+
var import_shogi_board_canvas = __toESM(require("./shogi-board-canvas"));
|
|
40
|
+
var import_shogi_hands_canvas = __toESM(require("./shogi-hands-canvas"));
|
|
41
|
+
function ShogiPlayer(props) {
|
|
42
|
+
const [player] = (0, import_react.useState)(import_json_kifu_format.JKFPlayer.parse(props.kifuText.trim()));
|
|
43
|
+
const [pieces, setPieces] = (0, import_react.useState)(player.shogi.board);
|
|
44
|
+
const [hands, setHands] = (0, import_react.useState)(player.shogi.hands);
|
|
45
|
+
const [moves, setMoves] = (0, import_react.useState)(player.kifu.moves);
|
|
46
|
+
const [tesuu, setTesuu] = (0, import_react.useState)(player.tesuu);
|
|
47
|
+
const [currentMove, setCurrentMove] = (0, import_react.useState)(player.getMove());
|
|
48
|
+
const [isSente, setIsSente] = (0, import_react.useState)(true);
|
|
49
|
+
const [maxTesuu, setMaxTesuu] = (0, import_react.useState)(player.getMaxTesuu());
|
|
50
|
+
const [comments, setComments] = (0, import_react.useState)(player.getComments());
|
|
51
|
+
const size = 360;
|
|
52
|
+
const updateState = () => {
|
|
53
|
+
setPieces([...player.shogi.board]);
|
|
54
|
+
setHands([...player.shogi.hands]);
|
|
55
|
+
setMoves([...player.kifu.moves]);
|
|
56
|
+
setCurrentMove(player.getMove());
|
|
57
|
+
setMaxTesuu(player.getMaxTesuu());
|
|
58
|
+
setComments(player.getComments());
|
|
59
|
+
setTesuu(player.tesuu);
|
|
60
|
+
};
|
|
61
|
+
const handleForward = () => {
|
|
62
|
+
player.forward();
|
|
63
|
+
updateState();
|
|
64
|
+
};
|
|
65
|
+
const handleBackward = () => {
|
|
66
|
+
player.backward();
|
|
67
|
+
updateState();
|
|
68
|
+
};
|
|
69
|
+
const handleGoto = (tesuu2) => {
|
|
70
|
+
player.goto(tesuu2);
|
|
71
|
+
updateState();
|
|
72
|
+
};
|
|
73
|
+
const handeleToggle = () => {
|
|
74
|
+
setIsSente(!isSente);
|
|
75
|
+
updateState();
|
|
76
|
+
};
|
|
77
|
+
return /* @__PURE__ */ import_react.default.createElement("div", { className: "flex w-fit", tabIndex: 1 }, /* @__PURE__ */ import_react.default.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ import_react.default.createElement(import_shogi_hands_canvas.default, { size, hands, isSente, isTop: true }), /* @__PURE__ */ import_react.default.createElement(import_shogi_board_canvas.default, { size, pieces, isSente, currentMove }), /* @__PURE__ */ import_react.default.createElement(import_shogi_hands_canvas.default, { size, hands, isSente, isTop: false })), /* @__PURE__ */ import_react.default.createElement("div", { className: "flex flex-col w-fit bg-[#f9d27a] p-4 gap-4" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "flex-1 relative w-full" }, /* @__PURE__ */ import_react.default.createElement(import_moves_area.MovesArea, { moves, tesuu, onTesuuChange: handleGoto })), /* @__PURE__ */ import_react.default.createElement("div", { className: "text-black border-black border-2 p-1 text-xs" }, comments.map((comment, index) => /* @__PURE__ */ import_react.default.createElement("div", { key: index }, comment)), comments.length === 0 && /* @__PURE__ */ import_react.default.createElement("div", null, "\xA0")), /* @__PURE__ */ import_react.default.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ import_react.default.createElement(import_button.default, { onClick: () => handleGoto(0) }, "\u6700\u521D"), /* @__PURE__ */ import_react.default.createElement(import_button.default, { onClick: handleBackward }, "\u524D"), /* @__PURE__ */ import_react.default.createElement(import_button.default, { onClick: handleForward }, "\u6B21"), /* @__PURE__ */ import_react.default.createElement(import_button.default, { onClick: () => handleGoto(maxTesuu) }, "\u6700\u5F8C"), /* @__PURE__ */ import_react.default.createElement(import_button.default, { onClick: handeleToggle }, "\u53CD\u8EE2"))));
|
|
78
|
+
}
|
package/dist/cjs/index.js
CHANGED
|
@@ -13,9 +13,9 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
13
13
|
};
|
|
14
14
|
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
15
15
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
16
|
-
var
|
|
17
|
-
module.exports = __toCommonJS(
|
|
18
|
-
__reExport(
|
|
16
|
+
var index_exports = {};
|
|
17
|
+
module.exports = __toCommonJS(index_exports);
|
|
18
|
+
__reExport(index_exports, require("./components"), module.exports);
|
|
19
19
|
// Annotate the CommonJS export names for ESM import in node:
|
|
20
20
|
0 && (module.exports = {
|
|
21
21
|
...require("./components")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { KifuComponentProps } from '@hackersheet/react-document-content';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
|
|
4
|
-
declare function Kifu({ code, language }: KifuComponentProps): React.JSX.Element
|
|
4
|
+
declare function Kifu({ code, language }: KifuComponentProps): React.JSX.Element;
|
|
5
5
|
|
|
6
6
|
export { Kifu as default };
|
|
@@ -1,36 +1,19 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { KifuLite, KifuStore } from "kifu-for-js";
|
|
3
2
|
import { useSearchParams } from "next/navigation";
|
|
4
|
-
import React, { useEffect
|
|
3
|
+
import React, { useEffect } from "react";
|
|
4
|
+
import { ShogiPlayer } from "../shogi-player";
|
|
5
5
|
function Kifu({ code, language }) {
|
|
6
6
|
const [, filename] = language.split(":");
|
|
7
7
|
const searchParams = useSearchParams();
|
|
8
8
|
const id = filename ? `user-content-${filename}` : void 0;
|
|
9
|
-
const [kifuStore] = useState(() => new KifuStore({ kifu: code }));
|
|
10
|
-
useEffect(() => {
|
|
11
|
-
initKifuUserSettings();
|
|
12
|
-
}, []);
|
|
13
9
|
useEffect(() => {
|
|
14
10
|
const newPly = Number(searchParams.get("ply") ?? 0);
|
|
15
11
|
const hash = typeof window !== "undefined" ? window.location.hash.replace(/^#!?/, "") : "";
|
|
16
12
|
if (hash === id) {
|
|
17
|
-
|
|
13
|
+
console.log(newPly);
|
|
18
14
|
}
|
|
19
|
-
}, [searchParams,
|
|
20
|
-
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
return /* @__PURE__ */ React.createElement("div", { className: "kifu-block", id }, /* @__PURE__ */ React.createElement(KifuLite, { style: { width: "100%" }, kifuStore }));
|
|
24
|
-
}
|
|
25
|
-
function initKifuUserSettings() {
|
|
26
|
-
const LOCALSTORAGE_KEY = "kifuforjs";
|
|
27
|
-
const defaultSettings = {
|
|
28
|
-
hapticFeedback: false
|
|
29
|
-
};
|
|
30
|
-
const settings = localStorage.getItem(LOCALSTORAGE_KEY);
|
|
31
|
-
if (!settings) {
|
|
32
|
-
localStorage.setItem(LOCALSTORAGE_KEY, JSON.stringify(defaultSettings));
|
|
33
|
-
}
|
|
15
|
+
}, [searchParams, id]);
|
|
16
|
+
return /* @__PURE__ */ React.createElement("div", { className: "kifu-block", id }, /* @__PURE__ */ React.createElement(ShogiPlayer, { kifuText: code }));
|
|
34
17
|
}
|
|
35
18
|
export {
|
|
36
19
|
Kifu as default
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React, { MouseEventHandler, PropsWithChildren } from 'react';
|
|
2
|
+
|
|
3
|
+
type ButtonProps = {
|
|
4
|
+
onClick?: MouseEventHandler<HTMLButtonElement>;
|
|
5
|
+
} & PropsWithChildren;
|
|
6
|
+
declare function Button({ children, onClick }: ButtonProps): React.JSX.Element;
|
|
7
|
+
|
|
8
|
+
export { type ButtonProps, Button as default };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
function Button({ children, onClick }) {
|
|
3
|
+
return /* @__PURE__ */ React.createElement(
|
|
4
|
+
"button",
|
|
5
|
+
{
|
|
6
|
+
className: "border-2 text-black p-2 border-black rounded-lg hover:bg-amber-100 cursor-pointer",
|
|
7
|
+
onClick
|
|
8
|
+
},
|
|
9
|
+
children
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
Button as default
|
|
14
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IMoveFormat } from 'json-kifu-format/dist/src/Formats';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
type MovesAreaProps = {
|
|
5
|
+
moves: IMoveFormat[];
|
|
6
|
+
tesuu: number;
|
|
7
|
+
onTesuuChange?: (tesuu: number) => void;
|
|
8
|
+
};
|
|
9
|
+
declare function MovesArea(props: MovesAreaProps): React.JSX.Element;
|
|
10
|
+
|
|
11
|
+
export { MovesArea, type MovesAreaProps };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { JKFPlayer } from "json-kifu-format";
|
|
3
|
+
import React, { Fragment, useEffect, useRef } from "react";
|
|
4
|
+
function MovesArea(props) {
|
|
5
|
+
const moves = props.moves;
|
|
6
|
+
const scrollRef = useRef(null);
|
|
7
|
+
const containerRef = useRef(null);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
if (scrollRef.current && containerRef.current) {
|
|
10
|
+
const containerRect = containerRef.current.getBoundingClientRect();
|
|
11
|
+
const scrollRect = scrollRef.current.getBoundingClientRect();
|
|
12
|
+
const offset = scrollRect.top - containerRect.top + containerRef.current.scrollTop - 72;
|
|
13
|
+
containerRef.current.scrollTo({
|
|
14
|
+
top: offset,
|
|
15
|
+
behavior: "auto"
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}, [props.tesuu]);
|
|
19
|
+
return /* @__PURE__ */ React.createElement("div", { className: "absolute overflow-y-auto h-full w-full border-2 border-black text-black", ref: containerRef }, /* @__PURE__ */ React.createElement("div", { className: "w-full text-xs grid" }, 0 === props.tesuu && /* @__PURE__ */ React.createElement("div", { ref: scrollRef }), /* @__PURE__ */ React.createElement(
|
|
20
|
+
"div",
|
|
21
|
+
{
|
|
22
|
+
onClick: () => props.onTesuuChange && props.onTesuuChange(0),
|
|
23
|
+
className: 0 === props.tesuu ? "bg-yellow-100 cursor-pointer flex p-2" : "cursor-pointer hover:bg-amber-300 flex p-2"
|
|
24
|
+
},
|
|
25
|
+
/* @__PURE__ */ React.createElement("div", null, "\u958B\u59CB\u5C40\u9762")
|
|
26
|
+
), moves.map(
|
|
27
|
+
(move, index) => index > 0 && /* @__PURE__ */ React.createElement(Fragment, { key: index }, index === props.tesuu && /* @__PURE__ */ React.createElement("div", { ref: scrollRef }), /* @__PURE__ */ React.createElement(
|
|
28
|
+
"div",
|
|
29
|
+
{
|
|
30
|
+
className: index === props.tesuu ? "bg-yellow-100 border-t border-black/60 cursor-pointer grid-rows-1 p-2" : "border-t border-black/60 cursor-pointer hover:bg-amber-300 grid-rows-1 p-2",
|
|
31
|
+
onClick: () => props.onTesuuChange && props.onTesuuChange(index)
|
|
32
|
+
},
|
|
33
|
+
/* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", null, index)),
|
|
34
|
+
/* @__PURE__ */ React.createElement("div", null, JKFPlayer.moveToReadableKifu(move))
|
|
35
|
+
))
|
|
36
|
+
)));
|
|
37
|
+
}
|
|
38
|
+
export {
|
|
39
|
+
MovesArea
|
|
40
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { IMoveMoveFormat } from 'json-kifu-format/dist/src/Formats';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Piece } from 'shogi.js';
|
|
4
|
+
|
|
5
|
+
type Props = {
|
|
6
|
+
size?: number;
|
|
7
|
+
boardColor?: string;
|
|
8
|
+
lineColor?: string;
|
|
9
|
+
fontFamily?: string;
|
|
10
|
+
fontSizeRatio?: number;
|
|
11
|
+
pieces: Piece[][];
|
|
12
|
+
isSente?: boolean;
|
|
13
|
+
currentMove?: IMoveMoveFormat;
|
|
14
|
+
};
|
|
15
|
+
declare const ShogiBoardCanvas: React.FC<Props>;
|
|
16
|
+
|
|
17
|
+
export { ShogiBoardCanvas as default };
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { JKFPlayer } from "json-kifu-format";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { Color } from "shogi.js";
|
|
5
|
+
const getCanvasDimensions = (size) => {
|
|
6
|
+
const dpr = window.devicePixelRatio || 1;
|
|
7
|
+
return { width: size * dpr, height: size * dpr, dpr };
|
|
8
|
+
};
|
|
9
|
+
const getBoardLayout = (size) => {
|
|
10
|
+
const margin = size * 0.06;
|
|
11
|
+
const boardSize = size - margin * 2;
|
|
12
|
+
const cell = boardSize / 9;
|
|
13
|
+
return { margin, boardSize, cell };
|
|
14
|
+
};
|
|
15
|
+
const drawBackground = (ctx, size, boardColor) => {
|
|
16
|
+
ctx.fillStyle = boardColor;
|
|
17
|
+
ctx.fillRect(0, 0, size, size);
|
|
18
|
+
};
|
|
19
|
+
const drawBoard = (ctx, margin, boardSize, lineColor) => {
|
|
20
|
+
ctx.strokeStyle = lineColor;
|
|
21
|
+
ctx.lineWidth = 2;
|
|
22
|
+
ctx.strokeRect(margin, margin, boardSize, boardSize);
|
|
23
|
+
ctx.lineWidth = 1;
|
|
24
|
+
Array.from({ length: 8 }).forEach((_, i) => {
|
|
25
|
+
const offset = (i + 1) * (boardSize / 9);
|
|
26
|
+
ctx.beginPath();
|
|
27
|
+
ctx.moveTo(margin + offset, margin);
|
|
28
|
+
ctx.lineTo(margin + offset, margin + boardSize);
|
|
29
|
+
ctx.stroke();
|
|
30
|
+
ctx.beginPath();
|
|
31
|
+
ctx.moveTo(margin, margin + offset);
|
|
32
|
+
ctx.lineTo(margin + boardSize, margin + offset);
|
|
33
|
+
ctx.stroke();
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
const drawPieces = (ctx, pieces, margin, cell, fontFamily, fontSizeRatio, isSente, currentMove) => {
|
|
37
|
+
ctx.textAlign = "center";
|
|
38
|
+
ctx.textBaseline = "middle";
|
|
39
|
+
pieces.forEach((row, rowIndex) => {
|
|
40
|
+
row.forEach((piece, colIndex) => {
|
|
41
|
+
if (!piece) return;
|
|
42
|
+
const x = isSente ? 8 - rowIndex : rowIndex;
|
|
43
|
+
const y = isSente ? colIndex : 8 - colIndex;
|
|
44
|
+
const px = margin + x * cell + cell / 2;
|
|
45
|
+
const py = margin + y * cell + cell / 2;
|
|
46
|
+
ctx.save();
|
|
47
|
+
ctx.translate(px, py);
|
|
48
|
+
if (isSente && piece.color === Color.White) {
|
|
49
|
+
ctx.rotate(Math.PI);
|
|
50
|
+
} else if (!isSente && piece.color === Color.Black) {
|
|
51
|
+
ctx.rotate(Math.PI);
|
|
52
|
+
}
|
|
53
|
+
const kan = JKFPlayer.kindToKan(piece.kind);
|
|
54
|
+
ctx.fillStyle = "#000";
|
|
55
|
+
if (currentMove) {
|
|
56
|
+
const to = currentMove.to;
|
|
57
|
+
if (to && to.x === rowIndex + 1 && to.y === colIndex + 1) {
|
|
58
|
+
ctx.fillStyle = "red";
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (kan.length === 2) {
|
|
62
|
+
const baseFontSize = cell * fontSizeRatio * 0.5;
|
|
63
|
+
ctx.font = `${baseFontSize}px ${fontFamily}`;
|
|
64
|
+
const scaleX = 2;
|
|
65
|
+
const scaleY = 1;
|
|
66
|
+
const offsetY = cell * 0.18;
|
|
67
|
+
ctx.save();
|
|
68
|
+
ctx.scale(scaleX, scaleY);
|
|
69
|
+
ctx.fillText(kan[0], 0 / scaleX, -offsetY / scaleY);
|
|
70
|
+
ctx.restore();
|
|
71
|
+
ctx.save();
|
|
72
|
+
ctx.scale(scaleX, scaleY);
|
|
73
|
+
ctx.fillText(kan[1], 0 / scaleX, offsetY / scaleY);
|
|
74
|
+
ctx.restore();
|
|
75
|
+
} else {
|
|
76
|
+
const fontSize = cell * fontSizeRatio;
|
|
77
|
+
ctx.font = `${fontSize}px ${fontFamily}`;
|
|
78
|
+
ctx.fillText(kan, 0, 0);
|
|
79
|
+
}
|
|
80
|
+
ctx.restore();
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
const drawCoordinates = (ctx, margin, boardSize, cell, fontFamily, isSente) => {
|
|
85
|
+
ctx.fillStyle = "#000";
|
|
86
|
+
ctx.font = `${cell * 0.35}px ${fontFamily}`;
|
|
87
|
+
ctx.textAlign = "center";
|
|
88
|
+
ctx.textBaseline = "middle";
|
|
89
|
+
Array.from({ length: 9 }).forEach((_, i) => {
|
|
90
|
+
const x = margin + i * cell + cell / 2;
|
|
91
|
+
const y = margin / 2;
|
|
92
|
+
const label = isSente ? (9 - i).toString() : (i + 1).toString();
|
|
93
|
+
ctx.fillText(label, x, y);
|
|
94
|
+
});
|
|
95
|
+
const kanji = ["\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D", "\u4E03", "\u516B", "\u4E5D"];
|
|
96
|
+
kanji.forEach((k, i) => {
|
|
97
|
+
const x = margin + boardSize + margin / 2;
|
|
98
|
+
const y = margin + i * cell + cell / 2;
|
|
99
|
+
const label = isSente ? k : kanji[8 - i];
|
|
100
|
+
ctx.fillText(label, x, y);
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
const ShogiBoardCanvas = ({
|
|
104
|
+
size = 360,
|
|
105
|
+
boardColor = "#f9d27a",
|
|
106
|
+
lineColor = "#000",
|
|
107
|
+
fontFamily = "serif",
|
|
108
|
+
fontSizeRatio = 0.7,
|
|
109
|
+
pieces,
|
|
110
|
+
isSente = true,
|
|
111
|
+
currentMove
|
|
112
|
+
}) => {
|
|
113
|
+
const canvasRef = React.useRef(null);
|
|
114
|
+
React.useEffect(() => {
|
|
115
|
+
const canvas = canvasRef.current;
|
|
116
|
+
if (!canvas) return;
|
|
117
|
+
const ctx = canvas.getContext("2d");
|
|
118
|
+
if (!ctx) return;
|
|
119
|
+
const { width, height, dpr } = getCanvasDimensions(size);
|
|
120
|
+
canvas.width = width;
|
|
121
|
+
canvas.height = height;
|
|
122
|
+
canvas.style.width = `${size}px`;
|
|
123
|
+
canvas.style.height = `${size}px`;
|
|
124
|
+
ctx.scale(dpr, dpr);
|
|
125
|
+
ctx.clearRect(0, 0, size, size);
|
|
126
|
+
const { margin, boardSize, cell } = getBoardLayout(size);
|
|
127
|
+
drawBackground(ctx, size, boardColor);
|
|
128
|
+
drawBoard(ctx, margin, boardSize, lineColor);
|
|
129
|
+
drawPieces(ctx, pieces, margin, cell, fontFamily, fontSizeRatio, isSente, currentMove);
|
|
130
|
+
drawCoordinates(ctx, margin, boardSize, cell, fontFamily, isSente);
|
|
131
|
+
}, [size, boardColor, lineColor, fontFamily, fontSizeRatio, pieces, isSente, currentMove]);
|
|
132
|
+
return /* @__PURE__ */ React.createElement("canvas", { ref: canvasRef, width: size, height: size });
|
|
133
|
+
};
|
|
134
|
+
var shogi_board_canvas_default = ShogiBoardCanvas;
|
|
135
|
+
export {
|
|
136
|
+
shogi_board_canvas_default as default
|
|
137
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Piece } from 'shogi.js';
|
|
3
|
+
|
|
4
|
+
type Props = {
|
|
5
|
+
size?: number;
|
|
6
|
+
boardColor?: string;
|
|
7
|
+
lineColor?: string;
|
|
8
|
+
fontFamily?: string;
|
|
9
|
+
fontSizeRatio?: number;
|
|
10
|
+
hands: Piece[][];
|
|
11
|
+
isSente?: boolean;
|
|
12
|
+
isTop?: boolean;
|
|
13
|
+
};
|
|
14
|
+
declare const ShogiHandsCanvas: React.FC<Props>;
|
|
15
|
+
|
|
16
|
+
export { ShogiHandsCanvas as default };
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { JKFPlayer } from "json-kifu-format";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { Color } from "shogi.js";
|
|
5
|
+
const getCanvasDimensions = (size) => {
|
|
6
|
+
const dpr = window.devicePixelRatio || 1;
|
|
7
|
+
return { width: size * dpr, height: size * dpr, dpr };
|
|
8
|
+
};
|
|
9
|
+
const getHandsLayout = (size) => {
|
|
10
|
+
const margin = size * 0.06;
|
|
11
|
+
const boardSize = size - margin * 2;
|
|
12
|
+
const cellSize = boardSize / 9;
|
|
13
|
+
const handsHeight = cellSize + margin + 2;
|
|
14
|
+
return { margin, handsHeight, boardSize, cellSize };
|
|
15
|
+
};
|
|
16
|
+
const drawBackground = (ctx, width, height, color) => {
|
|
17
|
+
ctx.fillStyle = color;
|
|
18
|
+
ctx.fillRect(0, 0, width, height);
|
|
19
|
+
};
|
|
20
|
+
const drawHandsFrame = (ctx, x, y, width, height, lineColor, isTop) => {
|
|
21
|
+
ctx.strokeStyle = lineColor;
|
|
22
|
+
ctx.lineWidth = 2;
|
|
23
|
+
if (isTop) {
|
|
24
|
+
ctx.strokeRect(x, y, width, height);
|
|
25
|
+
} else {
|
|
26
|
+
ctx.strokeRect(x, 2, width, height);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const drawCoordinates = (ctx, fontSize, fontFamily) => {
|
|
30
|
+
ctx.fillStyle = "#000";
|
|
31
|
+
ctx.font = `${fontSize}px ${fontFamily}`;
|
|
32
|
+
ctx.textAlign = "center";
|
|
33
|
+
ctx.textBaseline = "middle";
|
|
34
|
+
};
|
|
35
|
+
const drawPieces = (ctx, hands, margin, cell, fontFamily, fontSizeRatio, isSente, isTop) => {
|
|
36
|
+
ctx.textAlign = "center";
|
|
37
|
+
ctx.textBaseline = "middle";
|
|
38
|
+
const pieces = isSente && isTop || !isSente && !isTop ? hands[Color.White] : hands[Color.Black];
|
|
39
|
+
pieces.forEach((piece, index) => {
|
|
40
|
+
if (!piece) return;
|
|
41
|
+
const px = margin + index * cell + cell / 2;
|
|
42
|
+
const py = isTop ? margin + cell / 2 : cell / 2 + 2;
|
|
43
|
+
ctx.save();
|
|
44
|
+
ctx.translate(px, py);
|
|
45
|
+
if (isSente && piece.color === Color.White) {
|
|
46
|
+
ctx.rotate(Math.PI);
|
|
47
|
+
} else if (!isSente && piece.color === Color.Black) {
|
|
48
|
+
ctx.rotate(Math.PI);
|
|
49
|
+
}
|
|
50
|
+
const fontSize = cell * fontSizeRatio;
|
|
51
|
+
const kan = JKFPlayer.kindToKan(piece.kind);
|
|
52
|
+
ctx.font = `${fontSize}px ${fontFamily}`;
|
|
53
|
+
ctx.fillText(kan, 0, 0);
|
|
54
|
+
ctx.restore();
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
const ShogiHandsCanvas = ({
|
|
58
|
+
size = 360,
|
|
59
|
+
boardColor = "#f9d27a",
|
|
60
|
+
lineColor = "#000",
|
|
61
|
+
fontFamily = "serif",
|
|
62
|
+
fontSizeRatio = 0.7,
|
|
63
|
+
hands,
|
|
64
|
+
isSente = true,
|
|
65
|
+
isTop = false
|
|
66
|
+
}) => {
|
|
67
|
+
const canvasRef = React.useRef(null);
|
|
68
|
+
React.useEffect(() => {
|
|
69
|
+
const canvas = canvasRef.current;
|
|
70
|
+
if (!canvas) return;
|
|
71
|
+
const ctx = canvas.getContext("2d");
|
|
72
|
+
if (!ctx) return;
|
|
73
|
+
const { margin, handsHeight, boardSize, cellSize } = getHandsLayout(size);
|
|
74
|
+
const { width: canvasWidth, dpr } = getCanvasDimensions(size);
|
|
75
|
+
canvas.width = canvasWidth;
|
|
76
|
+
canvas.height = handsHeight * dpr;
|
|
77
|
+
canvas.style.width = `${size}px`;
|
|
78
|
+
canvas.style.height = `${handsHeight}px`;
|
|
79
|
+
ctx.scale(dpr, dpr);
|
|
80
|
+
ctx.clearRect(0, 0, size, handsHeight);
|
|
81
|
+
drawBackground(ctx, size, handsHeight, boardColor);
|
|
82
|
+
drawHandsFrame(ctx, margin, margin, boardSize, cellSize, lineColor, isTop);
|
|
83
|
+
drawCoordinates(ctx, cellSize * 0.35, fontFamily);
|
|
84
|
+
drawPieces(ctx, hands, margin, cellSize, fontFamily, fontSizeRatio, isSente, isTop);
|
|
85
|
+
}, [size, boardColor, lineColor, fontFamily, fontSizeRatio, isSente, hands, isTop]);
|
|
86
|
+
return /* @__PURE__ */ React.createElement("canvas", { ref: canvasRef });
|
|
87
|
+
};
|
|
88
|
+
var shogi_hands_canvas_default = ShogiHandsCanvas;
|
|
89
|
+
export {
|
|
90
|
+
shogi_hands_canvas_default as default
|
|
91
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { JKFPlayer } from "json-kifu-format";
|
|
3
|
+
import React, { useState } from "react";
|
|
4
|
+
import Button from "./button";
|
|
5
|
+
import { MovesArea } from "./moves-area";
|
|
6
|
+
import ShogiBoardCanvas from "./shogi-board-canvas";
|
|
7
|
+
import ShogiHandsCanvas from "./shogi-hands-canvas";
|
|
8
|
+
function ShogiPlayer(props) {
|
|
9
|
+
const [player] = useState(JKFPlayer.parse(props.kifuText.trim()));
|
|
10
|
+
const [pieces, setPieces] = useState(player.shogi.board);
|
|
11
|
+
const [hands, setHands] = useState(player.shogi.hands);
|
|
12
|
+
const [moves, setMoves] = useState(player.kifu.moves);
|
|
13
|
+
const [tesuu, setTesuu] = useState(player.tesuu);
|
|
14
|
+
const [currentMove, setCurrentMove] = useState(player.getMove());
|
|
15
|
+
const [isSente, setIsSente] = useState(true);
|
|
16
|
+
const [maxTesuu, setMaxTesuu] = useState(player.getMaxTesuu());
|
|
17
|
+
const [comments, setComments] = useState(player.getComments());
|
|
18
|
+
const size = 360;
|
|
19
|
+
const updateState = () => {
|
|
20
|
+
setPieces([...player.shogi.board]);
|
|
21
|
+
setHands([...player.shogi.hands]);
|
|
22
|
+
setMoves([...player.kifu.moves]);
|
|
23
|
+
setCurrentMove(player.getMove());
|
|
24
|
+
setMaxTesuu(player.getMaxTesuu());
|
|
25
|
+
setComments(player.getComments());
|
|
26
|
+
setTesuu(player.tesuu);
|
|
27
|
+
};
|
|
28
|
+
const handleForward = () => {
|
|
29
|
+
player.forward();
|
|
30
|
+
updateState();
|
|
31
|
+
};
|
|
32
|
+
const handleBackward = () => {
|
|
33
|
+
player.backward();
|
|
34
|
+
updateState();
|
|
35
|
+
};
|
|
36
|
+
const handleGoto = (tesuu2) => {
|
|
37
|
+
player.goto(tesuu2);
|
|
38
|
+
updateState();
|
|
39
|
+
};
|
|
40
|
+
const handeleToggle = () => {
|
|
41
|
+
setIsSente(!isSente);
|
|
42
|
+
updateState();
|
|
43
|
+
};
|
|
44
|
+
return /* @__PURE__ */ React.createElement("div", { className: "flex w-fit", tabIndex: 1 }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ React.createElement(ShogiHandsCanvas, { size, hands, isSente, isTop: true }), /* @__PURE__ */ React.createElement(ShogiBoardCanvas, { size, pieces, isSente, currentMove }), /* @__PURE__ */ React.createElement(ShogiHandsCanvas, { size, hands, isSente, isTop: false })), /* @__PURE__ */ React.createElement("div", { className: "flex flex-col w-fit bg-[#f9d27a] p-4 gap-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex-1 relative w-full" }, /* @__PURE__ */ React.createElement(MovesArea, { moves, tesuu, onTesuuChange: handleGoto })), /* @__PURE__ */ React.createElement("div", { className: "text-black border-black border-2 p-1 text-xs" }, comments.map((comment, index) => /* @__PURE__ */ React.createElement("div", { key: index }, comment)), comments.length === 0 && /* @__PURE__ */ React.createElement("div", null, "\xA0")), /* @__PURE__ */ React.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React.createElement(Button, { onClick: () => handleGoto(0) }, "\u6700\u521D"), /* @__PURE__ */ React.createElement(Button, { onClick: handleBackward }, "\u524D"), /* @__PURE__ */ React.createElement(Button, { onClick: handleForward }, "\u6B21"), /* @__PURE__ */ React.createElement(Button, { onClick: () => handleGoto(maxTesuu) }, "\u6700\u5F8C"), /* @__PURE__ */ React.createElement(Button, { onClick: handeleToggle }, "\u53CD\u8EE2"))));
|
|
45
|
+
}
|
|
46
|
+
export {
|
|
47
|
+
ShogiPlayer as default
|
|
48
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hackersheet/next-document-content-kifu",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.4",
|
|
4
4
|
"description": "Hacker Sheet document content kifu components for Next.js",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"repository": {
|
|
@@ -24,22 +24,22 @@
|
|
|
24
24
|
"dist"
|
|
25
25
|
],
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
27
|
+
"shogi.js": "^5.4.1",
|
|
28
|
+
"json-kifu-format": "^5.4.1",
|
|
29
|
+
"@hackersheet/core": "0.1.0-alpha.11",
|
|
30
|
+
"@hackersheet/react-document-content": "0.1.0-alpha.12"
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
32
|
-
"@types/react": "^
|
|
33
|
-
"@types/react-dom": "^
|
|
34
|
-
"next": "
|
|
35
|
-
"react": "^
|
|
36
|
-
"react-dom": "^
|
|
37
|
-
"@hackersheet/eslint-config-custom": "0.0.0"
|
|
33
|
+
"@types/react": "^19.2.0",
|
|
34
|
+
"@types/react-dom": "^19.2.0",
|
|
35
|
+
"next": "^15.5.4",
|
|
36
|
+
"react": "^19.2.0",
|
|
37
|
+
"react-dom": "^19.2.0"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
|
-
"next": "^
|
|
41
|
-
"react": "^
|
|
42
|
-
"react-dom": "^
|
|
40
|
+
"next": "^15.0.0",
|
|
41
|
+
"react": "^19.0.0",
|
|
42
|
+
"react-dom": "^19.0.0"
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
45
|
"build": "rm -rf ./dist && pnpm tsup",
|