Promotion #2

Merged
owenrees merged 5 commits from promotion into main 2026-06-21 19:09:57 +00:00
11 changed files with 10534 additions and 342 deletions
Showing only changes of commit b1b76522b8 - Show all commits
+4
View File
@@ -0,0 +1,4 @@
{
"$schema": "./node_modules/oxfmt/configuration_schema.json",
"ignorePatterns": []
}
+11
View File
@@ -0,0 +1,11 @@
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"plugins": ["typescript", "unicorn", "oxc"],
"categories": {
"correctness": "error"
},
"rules": {},
"env": {
"builtin": true
}
}
+4 -1
View File
@@ -108,6 +108,9 @@
@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *)); @custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));
/* Make LiveView wrapper divs transparent for layout */ /* Make LiveView wrapper divs transparent for layout */
[data-phx-session], [data-phx-teleported-src] { display: contents } [data-phx-session],
[data-phx-teleported-src] {
display: contents;
}
/* This file is for your main application CSS */ /* This file is for your main application CSS */
+38 -35
View File
@@ -18,39 +18,39 @@
// To load it, simply add a second `<link>` to your `root.html.heex` file. // To load it, simply add a second `<link>` to your `root.html.heex` file.
// Include phoenix_html to handle method=PUT/DELETE in forms and buttons. // Include phoenix_html to handle method=PUT/DELETE in forms and buttons.
import "phoenix_html" import "phoenix_html";
// Establish Phoenix Socket and LiveView configuration. // Establish Phoenix Socket and LiveView configuration.
import {Socket} from "phoenix" import { Socket } from "phoenix";
import {LiveSocket} from "phoenix_live_view" import { LiveSocket } from "phoenix_live_view";
import {hooks as colocatedHooks} from "phoenix-colocated/chesstrainer" import { hooks as colocatedHooks } from "phoenix-colocated/chesstrainer";
import topbar from "../vendor/topbar" import topbar from "../vendor/topbar";
import { ChessBoard } from "./hooks/chessBoard" import { ChessBoard } from "./hooks/chessBoard";
let Hooks = { let Hooks = {
...colocatedHooks, ...colocatedHooks,
ChessBoard ChessBoard,
} };
const csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content") const csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content");
const liveSocket = new LiveSocket("/live", Socket, { const liveSocket = new LiveSocket("/live", Socket, {
longPollFallbackMs: 2500, longPollFallbackMs: 2500,
params: {_csrf_token: csrfToken}, params: { _csrf_token: csrfToken },
hooks: Hooks, hooks: Hooks,
}) });
// Show progress bar on live navigation and form submits // Show progress bar on live navigation and form submits
topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"}) topbar.config({ barColors: { 0: "#29d" }, shadowColor: "rgba(0, 0, 0, .3)" });
window.addEventListener("phx:page-loading-start", _info => topbar.show(300)) window.addEventListener("phx:page-loading-start", (_info) => topbar.show(300));
window.addEventListener("phx:page-loading-stop", _info => topbar.hide()) window.addEventListener("phx:page-loading-stop", (_info) => topbar.hide());
// connect if there are any LiveViews on the page // connect if there are any LiveViews on the page
liveSocket.connect() liveSocket.connect();
// expose liveSocket on window for web console debug logs and latency simulation: // expose liveSocket on window for web console debug logs and latency simulation:
// >> liveSocket.enableDebug() // >> liveSocket.enableDebug()
// >> liveSocket.enableLatencySim(1000) // enabled for duration of browser session // >> liveSocket.enableLatencySim(1000) // enabled for duration of browser session
// >> liveSocket.disableLatencySim() // >> liveSocket.disableLatencySim()
window.liveSocket = liveSocket window.liveSocket = liveSocket;
// The lines below enable quality of life phoenix_live_reload // The lines below enable quality of life phoenix_live_reload
// development features: // development features:
@@ -59,31 +59,34 @@ window.liveSocket = liveSocket
// 2. click on elements to jump to their definitions in your code editor // 2. click on elements to jump to their definitions in your code editor
// //
if (process.env.NODE_ENV === "development") { if (process.env.NODE_ENV === "development") {
window.addEventListener("phx:live_reload:attached", ({detail: reloader}) => { window.addEventListener("phx:live_reload:attached", ({ detail: reloader }) => {
// Enable server log streaming to client. // Enable server log streaming to client.
// Disable with reloader.disableServerLogs() // Disable with reloader.disableServerLogs()
reloader.enableServerLogs() reloader.enableServerLogs();
// Open configured PLUG_EDITOR at file:line of the clicked element's HEEx component // Open configured PLUG_EDITOR at file:line of the clicked element's HEEx component
// //
// * click with "c" key pressed to open at caller location // * click with "c" key pressed to open at caller location
// * click with "d" key pressed to open at function component definition location // * click with "d" key pressed to open at function component definition location
let keyDown let keyDown;
window.addEventListener("keydown", e => keyDown = e.key) window.addEventListener("keydown", (e) => (keyDown = e.key));
window.addEventListener("keyup", _e => keyDown = null) window.addEventListener("keyup", (_e) => (keyDown = null));
window.addEventListener("click", e => { window.addEventListener(
if(keyDown === "c"){ "click",
e.preventDefault() (e) => {
e.stopImmediatePropagation() if (keyDown === "c") {
reloader.openEditorAtCaller(e.target) e.preventDefault();
} else if(keyDown === "d"){ e.stopImmediatePropagation();
e.preventDefault() reloader.openEditorAtCaller(e.target);
e.stopImmediatePropagation() } else if (keyDown === "d") {
reloader.openEditorAtDef(e.target) e.preventDefault();
} e.stopImmediatePropagation();
}, true) reloader.openEditorAtDef(e.target);
}
},
true,
);
window.liveReloader = reloader window.liveReloader = reloader;
}) });
} }
+54 -46
View File
@@ -1,49 +1,49 @@
import { Chessground } from 'chessground'; import { Chessground } from "chessground";
import { Chess } from 'chess.js'; import { Chess } from "chess.js";
export const ChessBoard = { export const ChessBoard = {
mounted() { mounted() {
this.chess = new Chess(); this.chess = new Chess();
this.ground = Chessground(this.el, { this.ground = Chessground(this.el, {
fen: this.chess.fen(), fen: this.chess.fen(),
movable: { movable: {
color: 'white', color: "white",
free: false, free: false,
dests: this.getValidDests() dests: this.getValidDests(),
}, },
events: { events: {
move: (orig, dest, _metadata) => { move: (orig, dest, _metadata) => {
this.handleMove(orig, dest); this.handleMove(orig, dest);
} },
} },
}); });
this.handleEvent("set_fen", ({ fen }) => { this.handleEvent("set_fen", ({ fen }) => {
try { try {
this.chess.load(fen); this.chess.load(fen);
const currentTurnColor = this.chess.turn() === 'w' ? 'white' : 'black'; const currentTurnColor = this.chess.turn() === "w" ? "white" : "black";
this.ground.set({ this.ground.set({
fen: fen, fen: fen,
turnColor: currentTurnColor, turnColor: currentTurnColor,
movable: { movable: {
color: currentTurnColor, color: currentTurnColor,
dests: this.getValidDests() dests: this.getValidDests(),
} },
});
} catch (error) {
console.error("Invalid FEN string submitted:", error);
alert("Invalid FEN configuration!");
}
}); });
} catch (error) {
console.error("Invalid FEN string submitted:", error);
alert("Invalid FEN configuration!");
}
});
}, },
getValidDests() { getValidDests() {
// Convert chess.js moves into the Map format Chessground expects // Convert chess.js moves into the Map format Chessground expects
const dests = new Map(); const dests = new Map();
this.chess.moves({ verbose: true }).forEach(m => { this.chess.moves({ verbose: true }).forEach((m) => {
if (!dests.has(m.from)) dests.set(m.from, []); if (!dests.has(m.from)) dests.set(m.from, []);
dests.get(m.from).push(m.to); dests.get(m.from).push(m.to);
}); });
@@ -51,27 +51,35 @@ export const ChessBoard = {
}, },
handleMove(orig, dest) { handleMove(orig, dest) {
const move = this.chess.move({ from: orig, to: dest, promotion: 'q' }); const move = this.chess.move({ from: orig, to: dest, promotion: "q" });
if (move) { if (move) {
this.pushEvent("move_played", { const piece = this.chess.get(orig);
from: orig,
to: dest, if (piece && piece.type === "p" && (dest[1] === "8" || dest[1] === "1")) {
this.pendingPromotion = { orig, dest };
this.showPromotionDialog();
return;
}
this.pushEvent("move_played", {
from: orig,
to: dest,
fen: this.chess.fen(), fen: this.chess.fen(),
san: move.san, san: move.san,
}); });
const nextTurnColor = this.chess.turn() === 'w' ? 'white' : 'black'; const nextTurnColor = this.chess.turn() === "w" ? "white" : "black";
this.ground.set({ this.ground.set({
turnColor: nextTurnColor, turnColor: nextTurnColor,
movable: { movable: {
color: nextTurnColor, color: nextTurnColor,
dests: this.getValidDests() dests: this.getValidDests(),
} },
}); });
} else { } else {
this.ground.set({ fen: this.chess.fen() }); this.ground.set({ fen: this.chess.fen() });
} }
} },
} };
+809
View File
@@ -11,6 +11,704 @@
"dependencies": { "dependencies": {
"chess.js": "^1.4.0", "chess.js": "^1.4.0",
"chessground": "^9.2.1" "chessground": "^9.2.1"
},
"devDependencies": {
"oxfmt": "^0.55.0",
"oxlint": "^1.70.0"
}
},
"node_modules/@oxfmt/binding-android-arm-eabi": {
"version": "0.55.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm-eabi/-/binding-android-arm-eabi-0.55.0.tgz",
"integrity": "sha512-+rFDOqQe5LOWgxrAJaZgLRudr6GQm0wGI6gtu7vVkrdLGjNMUSGbAlaCr8j7F2H2Er97vYQCU8WDb30onqMM1g==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-android-arm64": {
"version": "0.55.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm64/-/binding-android-arm64-0.55.0.tgz",
"integrity": "sha512-ctulLq8s3x8Zmvw6+iccB09TIKERAklRSmbJ10gk8mlAn05qZxoyo52dj3Hi9IJcmDSwF54fQaTVh2CbL6PInw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-darwin-arm64": {
"version": "0.55.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-arm64/-/binding-darwin-arm64-0.55.0.tgz",
"integrity": "sha512-xDQczLH9pw/RBk1h/GH0qcGMm8hQtmtVHBNLSH3lk1gEIR09hZ4L+mJQl4VqiVAvPK9VG9PYrWWuSQLt7xTbiA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-darwin-x64": {
"version": "0.55.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-x64/-/binding-darwin-x64-0.55.0.tgz",
"integrity": "sha512-JaNoFCkF2CJdGgpPSMbuO9HVyXyoNGIhMHPvp6NYAjeVKw9XEYc0HcUWJLPQa3Q69WV5wMa9m5jPMJPtbLtcRg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-freebsd-x64": {
"version": "0.55.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-freebsd-x64/-/binding-freebsd-x64-0.55.0.tgz",
"integrity": "sha512-DNbszhpg6S2MIzax5azdHFTTBIVkR5xr8yyRZuA4yoDAwOkzIp3tmldgKZM2+VlT+hJIG0xUksA+elISzMEAfA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-linux-arm-gnueabihf": {
"version": "0.55.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.55.0.tgz",
"integrity": "sha512-2snoaoRfFFyGnbOcKUK36rREBYxe/Xgz3uHbiA5zbCB/s6R4DQj4mHqYAaWWhgizCUSDxV8cE9zAZ0XleNpKGw==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-linux-arm-musleabihf": {
"version": "0.55.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.55.0.tgz",
"integrity": "sha512-q1aktHF/WRpSK81BX1dE/9vWrS2jGw1Nax2kb4DBLGAewubCLcoNyp4Zl/NSMgbv3vUS46Z33wIQkBVYOP3PYg==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-linux-arm64-gnu": {
"version": "0.55.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.55.0.tgz",
"integrity": "sha512-VD0y36aENezl/3tsclA/4G53Cc7iV+7Uoh7gz4yvcOTaEYBtJpQsE6PKDGTtUtOvGS4kv51ybfXY/nWZejO5IA==",
"cpu": [
"arm64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-linux-arm64-musl": {
"version": "0.55.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.55.0.tgz",
"integrity": "sha512-r8xlKJFcsRmn0H5jZrdORae6RX9jDBrZVvOoxF+bCQtampQJClv80aZEHsv+NsLsp2KCE5ql79O7DpPVzYWpXA==",
"cpu": [
"arm64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-linux-ppc64-gnu": {
"version": "0.55.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.55.0.tgz",
"integrity": "sha512-GRKv/HXHcwIVld/WU61rF0g0R16hl5EJ+ScKdpjevT57lnLnagj/U2YUbXf2mT+2Pg1uCzWC+mvGicPV3CDdLQ==",
"cpu": [
"ppc64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-linux-riscv64-gnu": {
"version": "0.55.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.55.0.tgz",
"integrity": "sha512-rdv57enTiPtpSYRMKfAiEbQb0Puw5t9N7isVinDoo5qeLDScro2gznmZqSgSWbVZRzLisTeCTW8Qwgw0bOHv3A==",
"cpu": [
"riscv64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-linux-riscv64-musl": {
"version": "0.55.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.55.0.tgz",
"integrity": "sha512-7v1nNrlD43VY6+sYQ6efYyb3lE6QY182304PD/768ZxTjOmFd/3dQa3u/nGBUAXYdGSWOQc5N3PnS0QzUXyEIA==",
"cpu": [
"riscv64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-linux-s390x-gnu": {
"version": "0.55.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.55.0.tgz",
"integrity": "sha512-f4lJLUSPOgScjFl9LiflKCTocyNRwE25JmTMbN4XQdDjoZzEHjqf3wA3VESF1/csg7i8m7+EQLbrZyYDqe10UQ==",
"cpu": [
"s390x"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-linux-x64-gnu": {
"version": "0.55.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.55.0.tgz",
"integrity": "sha512-MihqiPziJNoWy4MqNSV+jVA1g+07iQDjZiR0vaCaDoPgFEiJpCMsxamktzLV07cEeQsSJ04vQaU4CzCQwIvtDA==",
"cpu": [
"x64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-linux-x64-musl": {
"version": "0.55.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-musl/-/binding-linux-x64-musl-0.55.0.tgz",
"integrity": "sha512-Yqghym7KYAVjP9MmSrNZiDeerMuoejNjo0r3ox5H3GDKk8eAfl8VyJm9i+pWCLDCTnAbcTUMMN2ZKjUYXH1v3g==",
"cpu": [
"x64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-openharmony-arm64": {
"version": "0.55.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-openharmony-arm64/-/binding-openharmony-arm64-0.55.0.tgz",
"integrity": "sha512-s5SDvVVSbyQl1V5UU3Yl12M+XLUQ3rl5SglNqgAA2K4PXUtQhyNSS00wivONPEnNo5W01rCou8WkDNyvI/RGHg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openharmony"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-win32-arm64-msvc": {
"version": "0.55.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.55.0.tgz",
"integrity": "sha512-7p9FB5R32tw2KyyNX3wpQrR2WHwEHvMEiBlGXxeTCaRMCVNx3UtFMAUbaQ/pRNWIrEUZmYhJ6tcUH52uPTRYjQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-win32-ia32-msvc": {
"version": "0.55.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.55.0.tgz",
"integrity": "sha512-ZYqj3fDnOT1IaVGMP5kpmkQl4F3tQIm2ZyAxvqkJYmI0xgWWak4ss4XYwv3VDfM+TWXeC9K4uQ/wW5jm/5XABA==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxfmt/binding-win32-x64-msvc": {
"version": "0.55.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.55.0.tgz",
"integrity": "sha512-eEYT5tivGnGbPHuOHuQpi6CGLObhh0re/5jcNQHihD2GRYkTM85dyi5a19zjP8Q00t1uqAx+/QGLUGdHeqzWyg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxlint/binding-android-arm-eabi": {
"version": "1.70.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.70.0.tgz",
"integrity": "sha512-zFh0P4cswmRvw6nkyb89dr18rRanuaCPAsEXsFDoQY8WdaquI8Pt4NWFjaMJg6L23cy5NeN8J9cBnREbWzZhaw==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxlint/binding-android-arm64": {
"version": "1.70.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm64/-/binding-android-arm64-1.70.0.tgz",
"integrity": "sha512-qI8o4HZjeGiBrWv+pJv4lH0Yi2Gl/JSp/EumBUApezJprIKa5PS4nU0lQsQngtky8k+SplQIOjv6hwu0SSxeyg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxlint/binding-darwin-arm64": {
"version": "1.70.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-arm64/-/binding-darwin-arm64-1.70.0.tgz",
"integrity": "sha512-8KjgVVHI5F9nVwHCRwwA78Ty7zNKP4Wd9OeN5PSv3iu/F/u1RVXoOCgLhWqust6HmwQG6xc8c+RCyaWENy24+w==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxlint/binding-darwin-x64": {
"version": "1.70.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-x64/-/binding-darwin-x64-1.70.0.tgz",
"integrity": "sha512-WVydssv5PSUBXFJTdNBWlmGkbNmvPGaFt/2SUT/EZRB6bq6bEOHmMlbnupZD5jmlEvi9+mZJHi8TCw15lyfSfQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxlint/binding-freebsd-x64": {
"version": "1.70.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-freebsd-x64/-/binding-freebsd-x64-1.70.0.tgz",
"integrity": "sha512-hJucmUf8OlinHNb1R7fI4Fw6WsAstOz7i8nmkWQfiHoZXtbufNm+MxiDTIMk1ggh2Ro4vLzgQ+bKvRY54MZoRA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxlint/binding-linux-arm-gnueabihf": {
"version": "1.70.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.70.0.tgz",
"integrity": "sha512-1BnS7wbCYDSXwWzJJ+mc3NURoha6m6m6RT5c6vgAY3oz7C3OVXP+S0awo2mRq97arrJkVvO3qRQfyAHL+76xtQ==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxlint/binding-linux-arm-musleabihf": {
"version": "1.70.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-1.70.0.tgz",
"integrity": "sha512-yKy/UdbR55+M2yEcuiV5DCNC/gdQAjr/GioUy50QwBzSrKm8ueWADqyRLS9Xk+qjNeCYGg6A8FvUBds56ttfqg==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxlint/binding-linux-arm64-gnu": {
"version": "1.70.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.70.0.tgz",
"integrity": "sha512-0A5XJ4alvmqFUFP/4oYSyaO+qLto/HrKEWTSaegiVl+HOufFngK2BjYw9x4RbwBt/du5QG6l5q1zeWiJYYG5yg==",
"cpu": [
"arm64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxlint/binding-linux-arm64-musl": {
"version": "1.70.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.70.0.tgz",
"integrity": "sha512-JiylyurlB0CLSedNtx1gzv3FvfWPF1h/2Y3BJszPLNt5XQFlBsH5ke0Jle3iJb3uqu5m2e7A/DwzpuCAHdiU+A==",
"cpu": [
"arm64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxlint/binding-linux-ppc64-gnu": {
"version": "1.70.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.70.0.tgz",
"integrity": "sha512-J8VPG7I3/HmgaU4u8pNU2kFx2+0U+vPLS1dXFxXOaR/2TQ0f8AC7DRz0SRGRI1bfphnX2hVYTTtLuhL4nYKL+Q==",
"cpu": [
"ppc64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxlint/binding-linux-riscv64-gnu": {
"version": "1.70.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-1.70.0.tgz",
"integrity": "sha512-N2+4lV2KLN+oXTIIIwmWDhwkrnvqf5oX7Hw0zPjk+RuIVgiBQSOlJWF7uQoFx2siEYX0ZQ5cfSbEAHm+J3t7Wg==",
"cpu": [
"riscv64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxlint/binding-linux-riscv64-musl": {
"version": "1.70.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-1.70.0.tgz",
"integrity": "sha512-1e2L7cFCvx9QDzq6NPP+0tABKb5z6nWHyddWTNKprEsjO9xNrAtPowuCGpjNXxkTdsMiZ4jc8YQ5SstZd4XK6g==",
"cpu": [
"riscv64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxlint/binding-linux-s390x-gnu": {
"version": "1.70.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.70.0.tgz",
"integrity": "sha512-Kwu/l/8GcYibCWA9m9N5pRXMIKVSsL/YbgpLzYkqDhWTiqdRfnNJ/+nqIKRKQiFbHWsdlHEhzMwruJK+qcEruA==",
"cpu": [
"s390x"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxlint/binding-linux-x64-gnu": {
"version": "1.70.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.70.0.tgz",
"integrity": "sha512-tap04CsHYOl0nSAQJfPNIuBxqEPB2HnhQqwaOXLg1jnp2XfRo8Fa814dA4QC4zpvTWXCjAAaCY1W5LOORkEQuQ==",
"cpu": [
"x64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxlint/binding-linux-x64-musl": {
"version": "1.70.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-musl/-/binding-linux-x64-musl-1.70.0.tgz",
"integrity": "sha512-hzJa/WgvtJpbBD9rgfy0qe+MjbxOXNUT0bfR1S6EQQzfTtBFA9xg5q8KSwRrQ2QfSS+TaP4j+4mVPQrfNc6UNg==",
"cpu": [
"x64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxlint/binding-openharmony-arm64": {
"version": "1.70.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-openharmony-arm64/-/binding-openharmony-arm64-1.70.0.tgz",
"integrity": "sha512-xbsaNSNzVSnaJACCUYr1HQMyY/Q/Q1LkePmHG3UvZPvGCYGNxrsZp9OmtA6ick8xH47ltRRbRrPCM1YXYcyC+A==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openharmony"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxlint/binding-win32-arm64-msvc": {
"version": "1.70.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.70.0.tgz",
"integrity": "sha512-icAEsUI7JbW1TMRdEXV83mVAInhRVQYuuAlPpxdGwJ95chNdnCzjloRW8GglT0WvzOEZSio6fnYSk2DJ2Hv7LQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxlint/binding-win32-ia32-msvc": {
"version": "1.70.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.70.0.tgz",
"integrity": "sha512-FHMSWbVsPVs/f+Jcl04ws4JJ2wUnauyTzlpxWRG/lSO/8GpX08Fo2gQZqdA6CrRFI+zvkxl+N/KwJGWfUwYVZA==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@oxlint/binding-win32-x64-msvc": {
"version": "1.70.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.70.0.tgz",
"integrity": "sha512-ptOlKwCz7n4AKs5VweMqG6DAg677FmKOK+vBkkL9DMNgFATIQ+upqUYBTOEwRQyRAx1ncGlPlXleV2hIcm3z4g==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": "^20.19.0 || >=22.12.0"
} }
}, },
"node_modules/chess.js": { "node_modules/chess.js": {
@@ -28,6 +726,117 @@
"funding": { "funding": {
"url": "https://lichess.org/patron" "url": "https://lichess.org/patron"
} }
},
"node_modules/oxfmt": {
"version": "0.55.0",
"resolved": "https://registry.npmjs.org/oxfmt/-/oxfmt-0.55.0.tgz",
"integrity": "sha512-jSj2wCTakwgPMxkfiVZX0jf+nX+Nz6xlyAZjqNE0qXTFdCBPYlP6JAN+ODjmealw7DXBjOzYbdsqwBMAZnPZ6A==",
"dev": true,
"license": "MIT",
"dependencies": {
"tinypool": "2.1.0"
},
"bin": {
"oxfmt": "bin/oxfmt"
},
"engines": {
"node": "^20.19.0 || >=22.12.0"
},
"funding": {
"url": "https://github.com/sponsors/Boshen"
},
"optionalDependencies": {
"@oxfmt/binding-android-arm-eabi": "0.55.0",
"@oxfmt/binding-android-arm64": "0.55.0",
"@oxfmt/binding-darwin-arm64": "0.55.0",
"@oxfmt/binding-darwin-x64": "0.55.0",
"@oxfmt/binding-freebsd-x64": "0.55.0",
"@oxfmt/binding-linux-arm-gnueabihf": "0.55.0",
"@oxfmt/binding-linux-arm-musleabihf": "0.55.0",
"@oxfmt/binding-linux-arm64-gnu": "0.55.0",
"@oxfmt/binding-linux-arm64-musl": "0.55.0",
"@oxfmt/binding-linux-ppc64-gnu": "0.55.0",
"@oxfmt/binding-linux-riscv64-gnu": "0.55.0",
"@oxfmt/binding-linux-riscv64-musl": "0.55.0",
"@oxfmt/binding-linux-s390x-gnu": "0.55.0",
"@oxfmt/binding-linux-x64-gnu": "0.55.0",
"@oxfmt/binding-linux-x64-musl": "0.55.0",
"@oxfmt/binding-openharmony-arm64": "0.55.0",
"@oxfmt/binding-win32-arm64-msvc": "0.55.0",
"@oxfmt/binding-win32-ia32-msvc": "0.55.0",
"@oxfmt/binding-win32-x64-msvc": "0.55.0"
},
"peerDependencies": {
"svelte": "^5.0.0",
"vite-plus": "*"
},
"peerDependenciesMeta": {
"svelte": {
"optional": true
},
"vite-plus": {
"optional": true
}
}
},
"node_modules/oxlint": {
"version": "1.70.0",
"resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.70.0.tgz",
"integrity": "sha512-D6JgHtzkhRwvEC+A0Nw5AEc5bk8x5i1pHzvZIEf/a0C4hOzmAACNGtkDGPyFaxxX3ZVGxCPeig3P3rMM8XU3/g==",
"dev": true,
"license": "MIT",
"bin": {
"oxlint": "bin/oxlint"
},
"engines": {
"node": "^20.19.0 || >=22.12.0"
},
"funding": {
"url": "https://github.com/sponsors/Boshen"
},
"optionalDependencies": {
"@oxlint/binding-android-arm-eabi": "1.70.0",
"@oxlint/binding-android-arm64": "1.70.0",
"@oxlint/binding-darwin-arm64": "1.70.0",
"@oxlint/binding-darwin-x64": "1.70.0",
"@oxlint/binding-freebsd-x64": "1.70.0",
"@oxlint/binding-linux-arm-gnueabihf": "1.70.0",
"@oxlint/binding-linux-arm-musleabihf": "1.70.0",
"@oxlint/binding-linux-arm64-gnu": "1.70.0",
"@oxlint/binding-linux-arm64-musl": "1.70.0",
"@oxlint/binding-linux-ppc64-gnu": "1.70.0",
"@oxlint/binding-linux-riscv64-gnu": "1.70.0",
"@oxlint/binding-linux-riscv64-musl": "1.70.0",
"@oxlint/binding-linux-s390x-gnu": "1.70.0",
"@oxlint/binding-linux-x64-gnu": "1.70.0",
"@oxlint/binding-linux-x64-musl": "1.70.0",
"@oxlint/binding-openharmony-arm64": "1.70.0",
"@oxlint/binding-win32-arm64-msvc": "1.70.0",
"@oxlint/binding-win32-ia32-msvc": "1.70.0",
"@oxlint/binding-win32-x64-msvc": "1.70.0"
},
"peerDependencies": {
"oxlint-tsgolint": ">=0.22.1",
"vite-plus": "*"
},
"peerDependenciesMeta": {
"oxlint-tsgolint": {
"optional": true
},
"vite-plus": {
"optional": true
}
}
},
"node_modules/tinypool": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/tinypool/-/tinypool-2.1.0.tgz",
"integrity": "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^20.0.0 || >=22.0.0"
}
} }
} }
} }
+6
View File
@@ -7,10 +7,16 @@
"type": "commonjs", "type": "commonjs",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"fmt": "oxfmt",
"lint": "oxlint",
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
}, },
"dependencies": { "dependencies": {
"chess.js": "^1.4.0", "chess.js": "^1.4.0",
"chessground": "^9.2.1" "chessground": "^9.2.1"
},
"devDependencies": {
"oxfmt": "^0.55.0",
"oxlint": "^1.70.0"
} }
} }
+1110 -20
View File
File diff suppressed because one or more lines are too long
+8449 -188
View File
File diff suppressed because one or more lines are too long
+43 -37
View File
@@ -1,43 +1,49 @@
const plugin = require("tailwindcss/plugin") const plugin = require("tailwindcss/plugin");
const fs = require("fs") const fs = require("fs");
const path = require("path") const path = require("path");
module.exports = plugin(function({matchComponents, theme}) { module.exports = plugin(function ({ matchComponents, theme }) {
let iconsDir = path.join(__dirname, "../../deps/heroicons/optimized") let iconsDir = path.join(__dirname, "../../deps/heroicons/optimized");
let values = {} let values = {};
let icons = [ let icons = [
["", "/24/outline"], ["", "/24/outline"],
["-solid", "/24/solid"], ["-solid", "/24/solid"],
["-mini", "/20/solid"], ["-mini", "/20/solid"],
["-micro", "/16/solid"] ["-micro", "/16/solid"],
] ];
icons.forEach(([suffix, dir]) => { icons.forEach(([suffix, dir]) => {
fs.readdirSync(path.join(iconsDir, dir)).forEach(file => { fs.readdirSync(path.join(iconsDir, dir)).forEach((file) => {
let name = path.basename(file, ".svg") + suffix let name = path.basename(file, ".svg") + suffix;
values[name] = {name, fullPath: path.join(iconsDir, dir, file)} values[name] = { name, fullPath: path.join(iconsDir, dir, file) };
}) });
}) });
matchComponents({ matchComponents(
"hero": ({name, fullPath}) => { {
let content = fs.readFileSync(fullPath).toString().replace(/\r?\n|\r/g, "") hero: ({ name, fullPath }) => {
content = encodeURIComponent(content) let content = fs
let size = theme("spacing.6") .readFileSync(fullPath)
if (name.endsWith("-mini")) { .toString()
size = theme("spacing.5") .replace(/\r?\n|\r/g, "");
} else if (name.endsWith("-micro")) { content = encodeURIComponent(content);
size = theme("spacing.4") let size = theme("spacing.6");
} if (name.endsWith("-mini")) {
return { size = theme("spacing.5");
[`--hero-${name}`]: `url('data:image/svg+xml;utf8,${content}')`, } else if (name.endsWith("-micro")) {
"-webkit-mask": `var(--hero-${name})`, size = theme("spacing.4");
"mask": `var(--hero-${name})`, }
"mask-repeat": "no-repeat", return {
"background-color": "currentColor", [`--hero-${name}`]: `url('data:image/svg+xml;utf8,${content}')`,
"vertical-align": "middle", "-webkit-mask": `var(--hero-${name})`,
"display": "inline-block", mask: `var(--hero-${name})`,
"width": size, "mask-repeat": "no-repeat",
"height": size "background-color": "currentColor",
} "vertical-align": "middle",
} display: "inline-block",
}, {values}) width: size,
}) height: size,
};
},
},
{ values },
);
});
+6 -15
View File
@@ -41,15 +41,11 @@
ctx.shadowColor = options.shadowColor; ctx.shadowColor = options.shadowColor;
var lineGradient = ctx.createLinearGradient(0, 0, canvas.width, 0); var lineGradient = ctx.createLinearGradient(0, 0, canvas.width, 0);
for (var stop in options.barColors) for (var stop in options.barColors) lineGradient.addColorStop(stop, options.barColors[stop]);
lineGradient.addColorStop(stop, options.barColors[stop]);
ctx.lineWidth = options.barThickness; ctx.lineWidth = options.barThickness;
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(0, options.barThickness / 2); ctx.moveTo(0, options.barThickness / 2);
ctx.lineTo( ctx.lineTo(Math.ceil(currentProgress * canvas.width), options.barThickness / 2);
Math.ceil(currentProgress * canvas.width),
options.barThickness / 2
);
ctx.strokeStyle = lineGradient; ctx.strokeStyle = lineGradient;
ctx.stroke(); ctx.stroke();
}, },
@@ -65,8 +61,7 @@
}, },
topbar = { topbar = {
config: function (opts) { config: function (opts) {
for (var key in opts) for (var key in opts) if (options.hasOwnProperty(key)) options[key] = opts[key];
if (options.hasOwnProperty(key)) options[key] = opts[key];
}, },
show: function (delay) { show: function (delay) {
if (showing) return; if (showing) return;
@@ -84,9 +79,7 @@
if (options.autoRun) { if (options.autoRun) {
(function loop() { (function loop() {
progressTimerId = window.requestAnimationFrame(loop); progressTimerId = window.requestAnimationFrame(loop);
topbar.progress( topbar.progress("+" + 0.05 * Math.pow(1 - Math.sqrt(currentProgress), 2));
"+" + 0.05 * Math.pow(1 - Math.sqrt(currentProgress), 2)
);
})(); })();
} }
} }
@@ -95,9 +88,7 @@
if (typeof to === "undefined") return currentProgress; if (typeof to === "undefined") return currentProgress;
if (typeof to === "string") { if (typeof to === "string") {
to = to =
(to.indexOf("+") >= 0 || to.indexOf("-") >= 0 (to.indexOf("+") >= 0 || to.indexOf("-") >= 0 ? currentProgress : 0) + parseFloat(to);
? currentProgress
: 0) + parseFloat(to);
} }
currentProgress = to > 1 ? 1 : to; currentProgress = to > 1 ? 1 : to;
repaint(); repaint();
@@ -135,4 +126,4 @@
} else { } else {
this.topbar = topbar; this.topbar = topbar;
} }
}.call(this, window, document)); }).call(this, window, document);