diff --git a/assets/base.css b/assets/base.css
new file mode 100644
index 0000000..1d54c2b
--- /dev/null
+++ b/assets/base.css
@@ -0,0 +1,88 @@
+/*
+ * Chessground base css properties, for clarity.
+ *
+ * You can then include either desktop.css or mobile.css.
+ *
+ * And you need to include the css files in themes folder in order to have the
+ * board and pieces displayed!
+ */
+
+.cg-board-wrap {
+ width: 100%;
+ height: 100%;
+}
+.cg-board {
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ line-height: 0;
+ background-size: cover;
+ position: relative;
+ width: 100%;
+ height: 100%;
+}
+square {
+ position: absolute;
+ width: 12.5%;
+ height: 12.5%;
+}
+square[data-coord-x]::after {
+ position: absolute;
+ left: 1px;
+ bottom: 1px;
+ font-size: 10px;
+ line-height: 10px;
+ content: attr(data-coord-x);
+ color: #fff;
+ opacity: 0.5;
+}
+square[data-coord-y]::before {
+ position: absolute;
+ right: 1px;
+ top: 1px;
+ font-size: 10px;
+ line-height: 10px;
+ content: attr(data-coord-y);
+ color: #fff;
+ opacity: 0.5;
+}
+square.move-dest {
+ background: radial-gradient(rgba(20, 85, 30, 0.5) 22%, #208530 0, rgba(0, 0, 0, 0.3) 0, rgba(0, 0, 0, 0) 0);
+}
+square.premove-dest {
+ background: radial-gradient(rgba(20, 30, 85, 0.5) 22%, #203085 0, rgba(0, 0, 0, 0.3) 0, rgba(0, 0, 0, 0) 0);
+}
+square.last-move {
+ background-color: rgba(155, 199, 0, 0.41);
+}
+square.selected {
+ background-color: rgba(20, 85, 30, 0.5);
+}
+square.check {
+ background: radial-gradient(ellipse at center, rgba(255, 0, 0, 1) 0%, rgba(231, 0, 0, 1) 25%, rgba(169, 0, 0, 0) 89%, rgba(158, 0, 0, 0) 100%);
+}
+square.current-premove {
+ background-color: rgba(20, 30, 85, 0.5);
+}
+piece {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-size: cover;
+ z-index: 2;
+ will-change: transform;
+}
+piece.dragging {
+ z-index: 9;
+}
+piece.ghost {
+ opacity: 0.3;
+}
+.minimal-dom piece {
+ position: absolute;
+ width: 12.5%;
+ height: 12.5%;
+}
diff --git a/assets/desktop.css b/assets/desktop.css
new file mode 100644
index 0000000..6912f12
--- /dev/null
+++ b/assets/desktop.css
@@ -0,0 +1,10 @@
+.cg-board {
+ cursor: pointer;
+}
+.cg-board .cg-square.move-dest.drag-over,
+.cg-board .cg-square.premove-dest.drag-over {
+ box-shadow: inset 0 0 10px 2px rgba(216, 85, 0, 0.9);
+}
+piece.dragging {
+ cursor: move;
+}
diff --git a/assets/images/board/3d/Light-Wood.png b/assets/images/board/3d/Light-Wood.png
new file mode 100644
index 0000000..53502ac
Binary files /dev/null and b/assets/images/board/3d/Light-Wood.png differ
diff --git a/assets/images/board/blue2.jpg b/assets/images/board/blue2.jpg
new file mode 100644
index 0000000..dc56e98
Binary files /dev/null and b/assets/images/board/blue2.jpg differ
diff --git a/assets/images/board/marble.jpg b/assets/images/board/marble.jpg
new file mode 100644
index 0000000..4ae2849
Binary files /dev/null and b/assets/images/board/marble.jpg differ
diff --git a/assets/images/board/wood2.jpg b/assets/images/board/wood2.jpg
new file mode 100644
index 0000000..81f5fbc
Binary files /dev/null and b/assets/images/board/wood2.jpg differ
diff --git a/assets/images/pieces/cburnett/bB.svg b/assets/images/pieces/cburnett/bB.svg
new file mode 100644
index 0000000..466f962
--- /dev/null
+++ b/assets/images/pieces/cburnett/bB.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/cburnett/bK-full.svg b/assets/images/pieces/cburnett/bK-full.svg
new file mode 100644
index 0000000..fbda5aa
--- /dev/null
+++ b/assets/images/pieces/cburnett/bK-full.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/cburnett/bK.svg b/assets/images/pieces/cburnett/bK.svg
new file mode 100644
index 0000000..b432e6b
--- /dev/null
+++ b/assets/images/pieces/cburnett/bK.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/cburnett/bN.svg b/assets/images/pieces/cburnett/bN.svg
new file mode 100644
index 0000000..9404a88
--- /dev/null
+++ b/assets/images/pieces/cburnett/bN.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/cburnett/bP.svg b/assets/images/pieces/cburnett/bP.svg
new file mode 100644
index 0000000..b47f5f9
--- /dev/null
+++ b/assets/images/pieces/cburnett/bP.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/cburnett/bQ.svg b/assets/images/pieces/cburnett/bQ.svg
new file mode 100644
index 0000000..4ee8e14
--- /dev/null
+++ b/assets/images/pieces/cburnett/bQ.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/cburnett/bR.svg b/assets/images/pieces/cburnett/bR.svg
new file mode 100644
index 0000000..1fdc0b4
--- /dev/null
+++ b/assets/images/pieces/cburnett/bR.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/cburnett/wB.svg b/assets/images/pieces/cburnett/wB.svg
new file mode 100644
index 0000000..52f5219
--- /dev/null
+++ b/assets/images/pieces/cburnett/wB.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/cburnett/wK-full.svg b/assets/images/pieces/cburnett/wK-full.svg
new file mode 100644
index 0000000..d157e59
--- /dev/null
+++ b/assets/images/pieces/cburnett/wK-full.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/cburnett/wK.svg b/assets/images/pieces/cburnett/wK.svg
new file mode 100644
index 0000000..ae7a45c
--- /dev/null
+++ b/assets/images/pieces/cburnett/wK.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/cburnett/wN.svg b/assets/images/pieces/cburnett/wN.svg
new file mode 100644
index 0000000..7bdb17d
--- /dev/null
+++ b/assets/images/pieces/cburnett/wN.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/cburnett/wP.svg b/assets/images/pieces/cburnett/wP.svg
new file mode 100644
index 0000000..af2726c
--- /dev/null
+++ b/assets/images/pieces/cburnett/wP.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/cburnett/wQ.svg b/assets/images/pieces/cburnett/wQ.svg
new file mode 100644
index 0000000..ed6f693
--- /dev/null
+++ b/assets/images/pieces/cburnett/wQ.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/cburnett/wR.svg b/assets/images/pieces/cburnett/wR.svg
new file mode 100644
index 0000000..c79866c
--- /dev/null
+++ b/assets/images/pieces/cburnett/wR.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/cburnett/wbK.svg b/assets/images/pieces/cburnett/wbK.svg
new file mode 100644
index 0000000..3ede807
--- /dev/null
+++ b/assets/images/pieces/cburnett/wbK.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/merida/bB.svg b/assets/images/pieces/merida/bB.svg
new file mode 100644
index 0000000..1ef6430
--- /dev/null
+++ b/assets/images/pieces/merida/bB.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/merida/bK.svg b/assets/images/pieces/merida/bK.svg
new file mode 100644
index 0000000..4a7cbbe
--- /dev/null
+++ b/assets/images/pieces/merida/bK.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/merida/bN.svg b/assets/images/pieces/merida/bN.svg
new file mode 100644
index 0000000..bc3ca0b
--- /dev/null
+++ b/assets/images/pieces/merida/bN.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/merida/bP.svg b/assets/images/pieces/merida/bP.svg
new file mode 100644
index 0000000..a64bd91
--- /dev/null
+++ b/assets/images/pieces/merida/bP.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/merida/bQ.svg b/assets/images/pieces/merida/bQ.svg
new file mode 100644
index 0000000..cf5063d
--- /dev/null
+++ b/assets/images/pieces/merida/bQ.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/merida/bR.svg b/assets/images/pieces/merida/bR.svg
new file mode 100644
index 0000000..40328cf
--- /dev/null
+++ b/assets/images/pieces/merida/bR.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/merida/wB.svg b/assets/images/pieces/merida/wB.svg
new file mode 100644
index 0000000..1767c7b
--- /dev/null
+++ b/assets/images/pieces/merida/wB.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/merida/wK.svg b/assets/images/pieces/merida/wK.svg
new file mode 100644
index 0000000..88a56c8
--- /dev/null
+++ b/assets/images/pieces/merida/wK.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/merida/wN.svg b/assets/images/pieces/merida/wN.svg
new file mode 100644
index 0000000..f4eeac5
--- /dev/null
+++ b/assets/images/pieces/merida/wN.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/merida/wP.svg b/assets/images/pieces/merida/wP.svg
new file mode 100644
index 0000000..df8def9
--- /dev/null
+++ b/assets/images/pieces/merida/wP.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/merida/wQ.svg b/assets/images/pieces/merida/wQ.svg
new file mode 100644
index 0000000..7664924
--- /dev/null
+++ b/assets/images/pieces/merida/wQ.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/merida/wR.svg b/assets/images/pieces/merida/wR.svg
new file mode 100644
index 0000000..c37b03a
--- /dev/null
+++ b/assets/images/pieces/merida/wR.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/pirouetti/bB.svg b/assets/images/pieces/pirouetti/bB.svg
new file mode 100644
index 0000000..d48404d
--- /dev/null
+++ b/assets/images/pieces/pirouetti/bB.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/pirouetti/bK.svg b/assets/images/pieces/pirouetti/bK.svg
new file mode 100644
index 0000000..a5af7ae
--- /dev/null
+++ b/assets/images/pieces/pirouetti/bK.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/pirouetti/bN.svg b/assets/images/pieces/pirouetti/bN.svg
new file mode 100644
index 0000000..2a8eb75
--- /dev/null
+++ b/assets/images/pieces/pirouetti/bN.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/pirouetti/bP.svg b/assets/images/pieces/pirouetti/bP.svg
new file mode 100644
index 0000000..c2ad153
--- /dev/null
+++ b/assets/images/pieces/pirouetti/bP.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/pirouetti/bQ.svg b/assets/images/pieces/pirouetti/bQ.svg
new file mode 100644
index 0000000..c6051f7
--- /dev/null
+++ b/assets/images/pieces/pirouetti/bQ.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/pirouetti/bR.svg b/assets/images/pieces/pirouetti/bR.svg
new file mode 100644
index 0000000..72c79a5
--- /dev/null
+++ b/assets/images/pieces/pirouetti/bR.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/pirouetti/invert/bB.svg b/assets/images/pieces/pirouetti/invert/bB.svg
new file mode 100644
index 0000000..b316f8c
--- /dev/null
+++ b/assets/images/pieces/pirouetti/invert/bB.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/pirouetti/invert/bK.svg b/assets/images/pieces/pirouetti/invert/bK.svg
new file mode 100644
index 0000000..19193c6
--- /dev/null
+++ b/assets/images/pieces/pirouetti/invert/bK.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/pirouetti/invert/bN.svg b/assets/images/pieces/pirouetti/invert/bN.svg
new file mode 100644
index 0000000..a2d5b42
--- /dev/null
+++ b/assets/images/pieces/pirouetti/invert/bN.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/pirouetti/invert/bP.svg b/assets/images/pieces/pirouetti/invert/bP.svg
new file mode 100644
index 0000000..aea2f2e
--- /dev/null
+++ b/assets/images/pieces/pirouetti/invert/bP.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/pirouetti/invert/bQ.svg b/assets/images/pieces/pirouetti/invert/bQ.svg
new file mode 100644
index 0000000..14213ff
--- /dev/null
+++ b/assets/images/pieces/pirouetti/invert/bQ.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/pirouetti/invert/bR.svg b/assets/images/pieces/pirouetti/invert/bR.svg
new file mode 100644
index 0000000..1d542fa
--- /dev/null
+++ b/assets/images/pieces/pirouetti/invert/bR.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/pirouetti/invert/wB.svg b/assets/images/pieces/pirouetti/invert/wB.svg
new file mode 100644
index 0000000..dd53c85
--- /dev/null
+++ b/assets/images/pieces/pirouetti/invert/wB.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/pirouetti/invert/wK.svg b/assets/images/pieces/pirouetti/invert/wK.svg
new file mode 100644
index 0000000..8efa85f
--- /dev/null
+++ b/assets/images/pieces/pirouetti/invert/wK.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/pirouetti/invert/wN.svg b/assets/images/pieces/pirouetti/invert/wN.svg
new file mode 100644
index 0000000..5581e55
--- /dev/null
+++ b/assets/images/pieces/pirouetti/invert/wN.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/pirouetti/invert/wP.svg b/assets/images/pieces/pirouetti/invert/wP.svg
new file mode 100644
index 0000000..e3749c1
--- /dev/null
+++ b/assets/images/pieces/pirouetti/invert/wP.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/pirouetti/invert/wQ.svg b/assets/images/pieces/pirouetti/invert/wQ.svg
new file mode 100644
index 0000000..85046d8
--- /dev/null
+++ b/assets/images/pieces/pirouetti/invert/wQ.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/pirouetti/invert/wR.svg b/assets/images/pieces/pirouetti/invert/wR.svg
new file mode 100644
index 0000000..43e5f8c
--- /dev/null
+++ b/assets/images/pieces/pirouetti/invert/wR.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/pirouetti/wB.svg b/assets/images/pieces/pirouetti/wB.svg
new file mode 100644
index 0000000..bb93141
--- /dev/null
+++ b/assets/images/pieces/pirouetti/wB.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/pirouetti/wK.svg b/assets/images/pieces/pirouetti/wK.svg
new file mode 100644
index 0000000..7ec53ee
--- /dev/null
+++ b/assets/images/pieces/pirouetti/wK.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/pirouetti/wN.svg b/assets/images/pieces/pirouetti/wN.svg
new file mode 100644
index 0000000..2ccf68c
--- /dev/null
+++ b/assets/images/pieces/pirouetti/wN.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/pirouetti/wP.svg b/assets/images/pieces/pirouetti/wP.svg
new file mode 100644
index 0000000..8f23d67
--- /dev/null
+++ b/assets/images/pieces/pirouetti/wP.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/pirouetti/wQ.svg b/assets/images/pieces/pirouetti/wQ.svg
new file mode 100644
index 0000000..82529a8
--- /dev/null
+++ b/assets/images/pieces/pirouetti/wQ.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/pirouetti/wR.svg b/assets/images/pieces/pirouetti/wR.svg
new file mode 100644
index 0000000..be3b6d9
--- /dev/null
+++ b/assets/images/pieces/pirouetti/wR.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/pieces/staunton/basic/Black-Bishop-Flipped.png b/assets/images/pieces/staunton/basic/Black-Bishop-Flipped.png
new file mode 100644
index 0000000..96aefcf
Binary files /dev/null and b/assets/images/pieces/staunton/basic/Black-Bishop-Flipped.png differ
diff --git a/assets/images/pieces/staunton/basic/Black-Bishop.png b/assets/images/pieces/staunton/basic/Black-Bishop.png
new file mode 100644
index 0000000..737dc17
Binary files /dev/null and b/assets/images/pieces/staunton/basic/Black-Bishop.png differ
diff --git a/assets/images/pieces/staunton/basic/Black-King.png b/assets/images/pieces/staunton/basic/Black-King.png
new file mode 100644
index 0000000..e635e8c
Binary files /dev/null and b/assets/images/pieces/staunton/basic/Black-King.png differ
diff --git a/assets/images/pieces/staunton/basic/Black-Knight-Flipped.png b/assets/images/pieces/staunton/basic/Black-Knight-Flipped.png
new file mode 100644
index 0000000..bc3841e
Binary files /dev/null and b/assets/images/pieces/staunton/basic/Black-Knight-Flipped.png differ
diff --git a/assets/images/pieces/staunton/basic/Black-Knight.png b/assets/images/pieces/staunton/basic/Black-Knight.png
new file mode 100644
index 0000000..0e8181a
Binary files /dev/null and b/assets/images/pieces/staunton/basic/Black-Knight.png differ
diff --git a/assets/images/pieces/staunton/basic/Black-Pawn.png b/assets/images/pieces/staunton/basic/Black-Pawn.png
new file mode 100644
index 0000000..d5f30ec
Binary files /dev/null and b/assets/images/pieces/staunton/basic/Black-Pawn.png differ
diff --git a/assets/images/pieces/staunton/basic/Black-Queen.png b/assets/images/pieces/staunton/basic/Black-Queen.png
new file mode 100644
index 0000000..72f408a
Binary files /dev/null and b/assets/images/pieces/staunton/basic/Black-Queen.png differ
diff --git a/assets/images/pieces/staunton/basic/Black-Rook.png b/assets/images/pieces/staunton/basic/Black-Rook.png
new file mode 100644
index 0000000..e4173e6
Binary files /dev/null and b/assets/images/pieces/staunton/basic/Black-Rook.png differ
diff --git a/assets/images/pieces/staunton/basic/White-Bishop-Flipped.png b/assets/images/pieces/staunton/basic/White-Bishop-Flipped.png
new file mode 100644
index 0000000..4ab4a69
Binary files /dev/null and b/assets/images/pieces/staunton/basic/White-Bishop-Flipped.png differ
diff --git a/assets/images/pieces/staunton/basic/White-Bishop.png b/assets/images/pieces/staunton/basic/White-Bishop.png
new file mode 100644
index 0000000..b86b552
Binary files /dev/null and b/assets/images/pieces/staunton/basic/White-Bishop.png differ
diff --git a/assets/images/pieces/staunton/basic/White-King.png b/assets/images/pieces/staunton/basic/White-King.png
new file mode 100644
index 0000000..92d5a0c
Binary files /dev/null and b/assets/images/pieces/staunton/basic/White-King.png differ
diff --git a/assets/images/pieces/staunton/basic/White-Knight-Flipped.png b/assets/images/pieces/staunton/basic/White-Knight-Flipped.png
new file mode 100644
index 0000000..4252a0b
Binary files /dev/null and b/assets/images/pieces/staunton/basic/White-Knight-Flipped.png differ
diff --git a/assets/images/pieces/staunton/basic/White-Knight.png b/assets/images/pieces/staunton/basic/White-Knight.png
new file mode 100644
index 0000000..d473212
Binary files /dev/null and b/assets/images/pieces/staunton/basic/White-Knight.png differ
diff --git a/assets/images/pieces/staunton/basic/White-Pawn.png b/assets/images/pieces/staunton/basic/White-Pawn.png
new file mode 100644
index 0000000..14b43d1
Binary files /dev/null and b/assets/images/pieces/staunton/basic/White-Pawn.png differ
diff --git a/assets/images/pieces/staunton/basic/White-Queen.png b/assets/images/pieces/staunton/basic/White-Queen.png
new file mode 100644
index 0000000..f40a76c
Binary files /dev/null and b/assets/images/pieces/staunton/basic/White-Queen.png differ
diff --git a/assets/images/pieces/staunton/basic/White-Rook.png b/assets/images/pieces/staunton/basic/White-Rook.png
new file mode 100644
index 0000000..255a00f
Binary files /dev/null and b/assets/images/pieces/staunton/basic/White-Rook.png differ
diff --git a/assets/mobile.css b/assets/mobile.css
new file mode 100644
index 0000000..316c02a
--- /dev/null
+++ b/assets/mobile.css
@@ -0,0 +1,16 @@
+.cg-square.selected {
+ background: rgba(216, 85, 0, 0.3);
+}
+piece.dragging {
+ width: 200%;
+ height: 200%;
+ top: -22.5px;
+ left: -22.5px;
+}
+#cg-square-target {
+ position: absolute;
+ background-color: rgba(0, 0, 0, 0.2);
+ border-radius: 50%;
+ -webkit-transform: translate3d(0,0,0);
+ z-index: 9;
+}
diff --git a/assets/theme.css b/assets/theme.css
new file mode 100644
index 0000000..921c8e8
--- /dev/null
+++ b/assets/theme.css
@@ -0,0 +1,214 @@
+/*
+ * Board
+ */
+.blue .cg-board {
+ background-image: url('images/board/blue2.jpg');
+}
+.wood .cg-board {
+ background-image: url('images/board/wood2.jpg');
+}
+.marble .cg-board {
+ background-image: url('images/board/marble.jpg');
+}
+.chessground.light-wood-3d .cg-board-wrap {
+ position: relative;
+ background-image: url('images/board/3d/Light-Wood.png');
+ background-size: cover;
+}
+.chessground.small.light-wood-3d .cg-board-wrap {
+ width: calc(1400px / 4.6666);
+ height: calc(1310px / 4.6666);
+}
+.chessground.large.light-wood-3d .cg-board-wrap {
+ width: calc(1400px / 1);
+ height: calc(1310px / 1);
+}
+.light-wood-3d .cg-board {
+ position: absolute;
+ left: 0;
+ top: 0.6168702%;
+ width: 100%;
+ height: 97.0229%;
+}
+/*
+whole: 1400x1310
+useful: 1400x1271,
+top: 8, bottom: 31
+
+
+/*
+ * Pieces
+ */
+.pirouetti piece {
+ bottom: 0;
+ left: -15%;
+ width: 130%;
+ height: 130%;
+}
+.pirouetti piece.pawn.white {
+ background-image: url('images/pieces/pirouetti/wP.svg');
+}
+.pirouetti piece.bishop.white {
+ background-image: url('images/pieces/pirouetti/wB.svg');
+}
+.pirouetti piece.knight.white {
+ background-image: url('images/pieces/pirouetti/wN.svg');
+}
+.pirouetti piece.rook.white {
+ background-image: url('images/pieces/pirouetti/wR.svg');
+}
+.pirouetti piece.queen.white {
+ background-image: url('images/pieces/pirouetti/wQ.svg');
+}
+.pirouetti piece.king.white {
+ background-image: url('images/pieces/pirouetti/wK.svg');
+}
+.pirouetti piece.pawn.black {
+ background-image: url('images/pieces/pirouetti/bP.svg');
+}
+.pirouetti piece.bishop.black {
+ background-image: url('images/pieces/pirouetti/bB.svg');
+}
+.pirouetti piece.knight.black {
+ background-image: url('images/pieces/pirouetti/bN.svg');
+}
+.pirouetti piece.rook.black {
+ background-image: url('images/pieces/pirouetti/bR.svg');
+}
+.pirouetti piece.queen.black {
+ background-image: url('images/pieces/pirouetti/bQ.svg');
+}
+.pirouetti piece.king.black {
+ background-image: url('images/pieces/pirouetti/bK.svg');
+}
+.cburnett piece.pawn.white {
+ background-image: url('images/pieces/cburnett/wP.svg');
+}
+.cburnett piece.bishop.white {
+ background-image: url('images/pieces/cburnett/wB.svg');
+}
+.cburnett piece.knight.white {
+ background-image: url('images/pieces/cburnett/wN.svg');
+}
+.cburnett piece.rook.white {
+ background-image: url('images/pieces/cburnett/wR.svg');
+}
+.cburnett piece.queen.white {
+ background-image: url('images/pieces/cburnett/wQ.svg');
+}
+.cburnett piece.king.white {
+ background-image: url('images/pieces/cburnett/wK.svg');
+}
+.cburnett piece.pawn.black {
+ background-image: url('images/pieces/cburnett/bP.svg');
+}
+.cburnett piece.bishop.black {
+ background-image: url('images/pieces/cburnett/bB.svg');
+}
+.cburnett piece.knight.black {
+ background-image: url('images/pieces/cburnett/bN.svg');
+}
+.cburnett piece.rook.black {
+ background-image: url('images/pieces/cburnett/bR.svg');
+}
+.cburnett piece.queen.black {
+ background-image: url('images/pieces/cburnett/bQ.svg');
+}
+.cburnett piece.king.black {
+ background-image: url('images/pieces/cburnett/bK.svg');
+}
+.merida piece.pawn.white {
+ background-image: url('images/pieces/merida/wP.svg');
+}
+.merida piece.bishop.white {
+ background-image: url('images/pieces/merida/wB.svg');
+}
+.merida piece.knight.white {
+ background-image: url('images/pieces/merida/wN.svg');
+}
+.merida piece.rook.white {
+ background-image: url('images/pieces/merida/wR.svg');
+}
+.merida piece.queen.white {
+ background-image: url('images/pieces/merida/wQ.svg');
+}
+.merida piece.king.white {
+ background-image: url('images/pieces/merida/wK.svg');
+}
+.merida piece.pawn.black {
+ background-image: url('images/pieces/merida/bP.svg');
+}
+.merida piece.bishop.black {
+ background-image: url('images/pieces/merida/bB.svg');
+}
+.merida piece.knight.black {
+ background-image: url('images/pieces/merida/bN.svg');
+}
+.merida piece.rook.black {
+ background-image: url('images/pieces/merida/bR.svg');
+}
+.merida piece.queen.black {
+ background-image: url('images/pieces/merida/bQ.svg');
+}
+.merida piece.king.black {
+ background-image: url('images/pieces/merida/bK.svg');
+}
+.staunton piece.pawn.white {
+ background-image: url('images/pieces/staunton/basic/White-Pawn.png');
+}
+.staunton piece.bishop.white {
+ background-image: url('images/pieces/staunton/basic/White-Bishop.png');
+}
+.staunton .cg-board.orientation-black div.bishop.white {
+ background-image: url('images/pieces/staunton/basic/White-Bishop-Flipped.png');
+}
+.staunton piece.knight.white,
+#top div.piece_demo.staunton {
+ background-image: url('images/pieces/staunton/basic/White-Knight.png');
+}
+.staunton .cg-board.orientation-black div.knight.white {
+ background-image: url('images/pieces/staunton/basic/White-Knight-Flipped.png');
+}
+.staunton piece.rook.white {
+ background-image: url('images/pieces/staunton/basic/White-Rook.png');
+}
+.staunton piece.queen.white {
+ background-image: url('images/pieces/staunton/basic/White-Queen.png');
+}
+.staunton piece.king.white {
+ background-image: url('images/pieces/staunton/basic/White-King.png');
+}
+.staunton piece.pawn.black {
+ background-image: url('images/pieces/staunton/basic/Black-Pawn.png');
+}
+.staunton piece.bishop.black {
+ background-image: url('images/pieces/staunton/basic/Black-Bishop.png');
+}
+.staunton .cg-board.orientation-white div.bishop.black {
+ background-image: url('images/pieces/staunton/basic/Black-Bishop-Flipped.png');
+}
+.staunton piece.knight.black {
+ background-image: url('images/pieces/staunton/basic/Black-Knight.png');
+}
+.staunton .cg-board.orientation-white div.knight.black {
+ background-image: url('images/pieces/staunton/basic/Black-Knight-Flipped.png');
+}
+.staunton piece.rook.black {
+ background-image: url('images/pieces/staunton/basic/Black-Rook.png');
+}
+.staunton piece.queen.black {
+ background-image: url('images/pieces/staunton/basic/Black-Queen.png');
+}
+.staunton piece.king.black {
+ background-image: url('images/pieces/staunton/basic/Black-King.png');
+}
+.staunton piece {
+ /* original size:
+ width: 140.625%;
+ height: 179.6875%; */
+ /* size on 3D board, with height/width = 90.78571% */
+ width: 140.625%;
+ height: 197.92486231313927%;
+ left: -18%;
+ top: -77%;
+}
diff --git a/chess.min.js b/chess.min.js
new file mode 100644
index 0000000..60789ad
--- /dev/null
+++ b/chess.min.js
@@ -0,0 +1,6 @@
+"use strict";
+/*! Copyright (c) 2014, Jeff Hlywa (jhlywa@gmail.com)
+ * Released under the BSD license
+ * https://github.com/jhlywa/chess.js/blob/master/LICENSE
+ */
+;var Chess=function(ao){var p="b";var k="w";var E=-1;var X="p";var S="n";var s="b";var H="r";var j="q";var ad="k";var f="pnbrqkPNBRQK";var an="rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";var B=["1-0","0-1","1/2-1/2","*"];var u={b:[16,32,17,15],w:[-16,-32,-17,-15]};var J={n:[-18,-33,-31,-14,18,33,31,14],b:[-17,-15,17,15],r:[-16,1,16,-1],q:[-17,-16,-15,1,17,16,15,-1],k:[-17,-16,-15,1,17,16,15,-1]};var ac=[20,0,0,0,0,0,0,24,0,0,0,0,0,0,20,0,0,20,0,0,0,0,0,24,0,0,0,0,0,20,0,0,0,0,20,0,0,0,0,24,0,0,0,0,20,0,0,0,0,0,0,20,0,0,0,24,0,0,0,20,0,0,0,0,0,0,0,0,20,0,0,24,0,0,20,0,0,0,0,0,0,0,0,0,0,20,2,24,2,20,0,0,0,0,0,0,0,0,0,0,0,2,53,56,53,2,0,0,0,0,0,0,24,24,24,24,24,24,56,0,56,24,24,24,24,24,24,0,0,0,0,0,0,2,53,56,53,2,0,0,0,0,0,0,0,0,0,0,0,20,2,24,2,20,0,0,0,0,0,0,0,0,0,0,20,0,0,24,0,0,20,0,0,0,0,0,0,0,0,20,0,0,0,24,0,0,0,20,0,0,0,0,0,0,20,0,0,0,0,24,0,0,0,0,20,0,0,0,0,20,0,0,0,0,0,24,0,0,0,0,0,20,0,0,20,0,0,0,0,0,0,24,0,0,0,0,0,0,20];var o=[17,0,0,0,0,0,0,16,0,0,0,0,0,0,15,0,0,17,0,0,0,0,0,16,0,0,0,0,0,15,0,0,0,0,17,0,0,0,0,16,0,0,0,0,15,0,0,0,0,0,0,17,0,0,0,16,0,0,0,15,0,0,0,0,0,0,0,0,17,0,0,16,0,0,15,0,0,0,0,0,0,0,0,0,0,17,0,16,0,15,0,0,0,0,0,0,0,0,0,0,0,0,17,16,15,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,-15,-16,-17,0,0,0,0,0,0,0,0,0,0,0,0,-15,0,-16,0,-17,0,0,0,0,0,0,0,0,0,0,-15,0,0,-16,0,0,-17,0,0,0,0,0,0,0,0,-15,0,0,0,-16,0,0,0,-17,0,0,0,0,0,0,-15,0,0,0,0,-16,0,0,0,0,-17,0,0,0,0,-15,0,0,0,0,0,-16,0,0,0,0,0,-17,0,0,-15,0,0,0,0,0,0,-16,0,0,0,0,0,0,-17];var av={p:0,n:1,b:2,r:3,q:4,k:5};var aj={NORMAL:"n",CAPTURE:"c",BIG_PAWN:"b",EP_CAPTURE:"e",PROMOTION:"p",KSIDE_CASTLE:"k",QSIDE_CASTLE:"q"};var D={NORMAL:1,CAPTURE:2,BIG_PAWN:4,EP_CAPTURE:8,PROMOTION:16,KSIDE_CASTLE:32,QSIDE_CASTLE:64};var W=7;var T=6;var Q=5;var P=4;var O=3;var N=2;var M=1;var K=0;var v={a8:0,b8:1,c8:2,d8:3,e8:4,f8:5,g8:6,h8:7,a7:16,b7:17,c7:18,d7:19,e7:20,f7:21,g7:22,h7:23,a6:32,b6:33,c6:34,d6:35,e6:36,f6:37,g6:38,h6:39,a5:48,b5:49,c5:50,d5:51,e5:52,f5:53,g5:54,h5:55,a4:64,b4:65,c4:66,d4:67,e4:68,f4:69,g4:70,h4:71,a3:80,b3:81,c3:82,d3:83,e3:84,f3:85,g3:86,h3:87,a2:96,b2:97,c2:98,d2:99,e2:100,f2:101,g2:102,h2:103,a1:112,b1:113,c1:114,d1:115,e1:116,f1:117,g1:118,h1:119};var V={w:[{square:v.a1,flag:D.QSIDE_CASTLE},{square:v.h1,flag:D.KSIDE_CASTLE}],b:[{square:v.a8,flag:D.QSIDE_CASTLE},{square:v.h8,flag:D.KSIDE_CASTLE}]};var C=new Array(128);var ak={w:E,b:E};var t=k;var d={w:0,b:0};var x=E;var n=0;var g=1;var Z=[];var ab={};if(typeof ao==="undefined"){h(an)}else{h(ao)}function ae(){C=new Array(128);ak={w:E,b:E};t=k;d={w:0,b:0};x=E;n=0;g=1;Z=[];ab={};q(z())}function Y(){h(an)}function h(ay){var aD=ay.split(/\s+/);var aw=aD[0];var aC=0;var aB=f+"12345678/";if(!aa(ay).valid){return false}ae();for(var az=0;az-1){d.w|=D.KSIDE_CASTLE}if(aD[2].indexOf("Q")>-1){d.w|=D.QSIDE_CASTLE}if(aD[2].indexOf("k")>-1){d.b|=D.KSIDE_CASTLE}if(aD[2].indexOf("q")>-1){d.b|=D.QSIDE_CASTLE}x=(aD[3]==="-")?E:v[aD[3]];n=parseInt(aD[4],10);g=parseInt(aD[5],10);q(z());return true}function aa(ay){var aD={0:"No errors.",1:"FEN string must contain six space-delimited fields.",2:"6th field (move number) must be a positive integer.",3:"5th field (half move counter) must be a non-negative integer.",4:"4th field (en-passant square) is invalid.",5:"3rd field (castling availability) is invalid.",6:"2nd field (side to move) is invalid.",7:"1st field (piece positions) does not contain 8 '/'-delimited rows.",8:"1st field (piece positions) is invalid [consecutive numbers].",9:"1st field (piece positions) is invalid [invalid piece].",10:"1st field (piece positions) is invalid [row too large]."};var aC=ay.split(/\s+/);if(aC.length!==6){return{valid:false,error_number:1,error:aD[1]}}if(isNaN(aC[5])||(parseInt(aC[5],10)<=0)){return{valid:false,error_number:2,error:aD[2]}}if(isNaN(aC[4])||(parseInt(aC[4],10)<0)){return{valid:false,error_number:3,error:aD[3]}}if(!/^(-|[abcdefgh][36])$/.test(aC[3])){return{valid:false,error_number:4,error:aD[4]}}if(!/^(KQ?k?q?|Qk?q?|kq?|q|-)$/.test(aC[2])){return{valid:false,error_number:5,error:aD[5]}}if(!/^(w|b)$/.test(aC[1])){return{valid:false,error_number:6,error:aD[6]}}var aB=aC[0].split("/");if(aB.length!==8){return{valid:false,error_number:7,error:aD[7]}}for(var az=0;az0){ay+=aC;aC=0}var ax=C[aA].color;var aB=C[aA].type;ay+=(ax===k)?aB.toUpperCase():aB.toLowerCase()}if((aA+1)&136){if(aC>0){ay+=aC}if(aA!==v.h1){ay+="/"}aC=0;aA+=8}}var az="";if(d[k]&D.KSIDE_CASTLE){az+="K"}if(d[k]&D.QSIDE_CASTLE){az+="Q"}if(d[p]&D.KSIDE_CASTLE){az+="k"}if(d[p]&D.QSIDE_CASTLE){az+="q"}az=az||"-";var aw=(x===E)?"-":m(x);return[ay,t,az,aw,n,g].join(" ")}function at(aw){for(var ax=0;ax0){return}if(aw!==an){ab.SetUp="1";ab.FEN=aw}else{delete ab.SetUp;delete ab.FEN}}function ag(ax){var aw=C[v[ax]];return(aw)?{type:aw.type,color:aw.color}:null}function aq(aw,ay){if(!("type" in aw&&"color" in aw)){return false}if(f.indexOf(aw.type.toLowerCase())===-1){return false}if(!(ay in v)){return false}var ax=v[ay];if(aw.type==ad&&!(ak[aw.color]==E||ak[aw.color]==ax)){return false}C[ax]={type:aw.type,color:aw.color};if(aw.type===ad){ak[aw.color]=ax}q(z());return true}function F(ax){var aw=ag(ax);C[v[ax]]=null;if(aw&&aw.type===ad){ak[aw.color]=E}q(z());return aw}function am(ay,aB,aA,ax,az){var aw={color:t,from:aB,to:aA,flags:ax,piece:ay[aB].type};if(az){aw.flags|=D.PROMOTION;aw.promotion=az}if(ay[aA]){aw.captured=ay[aA].type}else{if(ax&D.EP_CAPTURE){aw.captured=X}}return aw}function b(ay){function aN(aT,aR,aW,aV,aQ){if(aT[aW].type===X&&(U(aV)===K||U(aV)===W)){var aU=[j,H,s,S];for(var aS=0,aP=aU.length;aS0){if(aE.color===k){return true}}else{if(aE.color===p){return true}}continue}if(aE.type==="n"||aE.type==="k"){return true}var ay=o[aC];var az=aA+ay;var aB=false;while(az!==aD){if(C[az]!=null){aB=true;break}az+=ay}if(!aB){return true}}}return false}function L(aw){return af(au(aw),ak[aw])}function R(){return L(t)}function I(){return R()&&b().length===0}function ah(){return !R()&&b().length===0}function A(){var aC={};var aB=[];var ax=0;var aD=0;for(var ay=v.a8;ay<=v.h1;ay++){aD=(aD+1)%2;if(ay&136){ay+=7;continue}var aA=C[ay];if(aA){aC[aA.type]=(aA.type in aC)?aC[aA.type]+1:1;if(aA.type===s){aB.push(aD)}ax++}}if(ax===2){return true}else{if(ax===3&&(aC[s]===1||aC[S]===1)){return true}else{if(ax===aC[s]+2){var az=0;var aw=aB.length;for(var ay=0;ay=3){aA=true}if(!ay.length){break}al(ay.pop())}return aA}function e(aw){Z.push({move:aw,kings:{b:ak.b,w:ak.w},turn:t,castling:{b:d.b,w:d.w},ep_square:x,half_moves:n,move_number:g})}function al(ax){var aB=t;var aC=au(aB);e(ax);C[ax.to]=C[ax.from];C[ax.from]=null;if(ax.flags&D.EP_CAPTURE){if(t===p){C[ax.to-16]=null}else{C[ax.to+16]=null}}if(ax.flags&D.PROMOTION){C[ax.to]={type:ax.promotion,color:aB}}if(C[ax.to].type===ad){ak[C[ax.to].color]=ax.to;if(ax.flags&D.KSIDE_CASTLE){var az=ax.to-1;var aA=ax.to+1;C[az]=C[aA];C[aA]=null}else{if(ax.flags&D.QSIDE_CASTLE){var az=ax.to+1;var aA=ax.to-2;C[az]=C[aA];C[aA]=null}}d[aB]=""}if(d[aB]){for(var ay=0,aw=V[aB].length;ay0){if(aD>0&&aB>0){return m(aE)}else{if(aB>0){return m(aE).charAt(1)}else{return m(aE).charAt(0)}}}return""}function a(){var az=" +------------------------+\n";for(var ax=v.a8;ax<=v.h1;ax++){if(y(ax)===0){az+=" 87654321"[U(ax)]+" |"}if(C[ax]==null){az+=" . "}else{var ay=C[ax].type;var aw=C[ax].color;var aA=(aw===k)?ay.toUpperCase():ay.toLowerCase();az+=" "+aA+" "}if((ax+1)&136){az+="|\n";ax+=8}}az+=" +------------------------+\n";az+=" a b c d e f g h\n";return az}function U(aw){return aw>>4}function y(aw){return aw&15}function m(aw){var ay=y(aw),ax=U(aw);return"abcdefgh".substring(ay,ay+1)+"87654321".substring(ax,ax+1)}function au(aw){return aw===k?p:k}function r(aw){return"0123456789".indexOf(aw)!==-1}function l(az){var ay=w(az);ay.san=ar(ay);ay.to=m(ay.to);ay.from=m(ay.from);var ax="";for(var aw in D){if(D[aw]&ay.flags){ax+=aj[aw]}}ay.flags=ax;return ay}function w(ay){var aw=(ay instanceof Array)?[]:{};for(var ax in ay){if(typeof ax==="object"){aw[ax]=w(ay[ax])}else{aw[ax]=ay[ax]}}return aw}function ap(aw){return aw.replace(/^\s+|\s+$/g,"")}function ai(aC){var ax=b({legal:false});var az=0;var ay=t;for(var aA=0,aw=ax.length;aA0){var aB=ai(aC-1);az+=aB}else{az++}}G()}return az}return{WHITE:k,BLACK:p,PAWN:X,KNIGHT:S,BISHOP:s,ROOK:H,QUEEN:j,KING:ad,SQUARES:(function(){var ax=[];for(var aw=v.a8;aw<=v.h1;aw++){if(aw&136){aw+=7;continue}ax.push(m(aw))}return ax})(),FLAGS:aj,load:function(aw){return h(aw)},reset:function(){return Y()},moves:function(az){var ay=b(az);var ax=[];for(var aA=0,aw=ay.length;aA=100||ah()||A()||i()},insufficient_material:function(){return A()},in_threefold_repetition:function(){return i()},game_over:function(){return n>=100||I()||ah()||A()||i()},validate_fen:function(aw){return aa(aw)},fen:function(){return z()},pgn:function(aG){var az=(typeof aG==="object"&&typeof aG.newline_char==="string")?aG.newline_char:"\n";var aF=(typeof aG==="object"&&typeof aG.max_width==="number")?aG.max_width:0;var aH=[];var aD=false;for(var aB in ab){aH.push("["+aB+' "'+ab[aB]+'"]'+az);aD=true}if(aD&&Z.length){aH.push(az)}var aE=[];while(Z.length>0){aE.push(G())}var ax=[];var ay="";var aw=1;while(aE.length>0){var aA=aE.pop();if(aw===1&&aA.color==="b"){ay="1. ...";aw++}else{if(aA.color==="w"){if(ay.length){ax.push(ay)}ay=aw+".";aw++}}ay=ay+" "+ar(aA);al(aA)}if(ay.length){ax.push(ay)}if(typeof ab.Result!=="undefined"){ax.push(ab.Result)}if(aF===0){return aH.join("")+ax.join(" ")}var aC=0;for(var aB=0;aBaF&&aB!==0){if(aH[aH.length-1]===" "){aH.pop()}aH.push(az);aC=0}else{if(aB!==0){aH.push(" ");aC++}}aH.push(ax[aB]);aC+=ax[aB].length}return aH.join("")},load_pgn:function(aG,aK){function aL(aM){return aM.replace(/\\/g,"\\")}function az(aO){var aN=b();for(var aP=0,aM=aN.length;aP0){aQ[aO]=aP}}return aQ}var aB=(typeof aK==="object"&&typeof aK.newline_char==="string")?aK.newline_char:"\r?\n";var aH=new RegExp("^(\\[(.|"+aL(aB)+")*\\])("+aL(aB)+")*1.("+aL(aB)+"|.)*$","g");var aD=aG.replace(aH,"$1");if(aD[0]!=="["){aD=""}Y();var aA=aI(aD,aK);for(var aJ in aA){at([aJ,aA[aJ]])}var ay=aG.replace(aD,"").replace(new RegExp(aL(aB),"g")," ");ay=ay.replace(/(\{[^}]+\})+?/g,"");ay=ay.replace(/\d+\./g,"");var ax=ap(ay).split(new RegExp(/\s+/));ax=ax.join(",").replace(/,,+/g,",").split(",");var aC="";for(var aF=0;aF-1){if(aw(ab)&&typeof ab.Result==="undefined"){at(["Result",aC])}}else{aC=aE(aC);if(aC==null){return false}else{al(aC)}}return true},header:function(){return at(arguments)},ascii:function(){return a()},turn:function(){return t},move:function(aA){var az=null;var ay=b();if(typeof aA==="string"){for(var aB=0,ax=ay.length;aB0){aA.push(G())}while(aA.length>0){var aw=aA.pop();if(ax){az.push(l(aw))}else{az.push(ar(aw))}al(aw)}return az}}};if(typeof exports!=="undefined"){exports.Chess=Chess}if(typeof define!=="undefined"){define(function(){return Chess})};
diff --git a/chessground.js b/chessground.js
new file mode 100644
index 0000000..b5825bc
--- /dev/null
+++ b/chessground.js
@@ -0,0 +1,3333 @@
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Chessground = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o div.classname#id[param=one][param2=two]
+ * Which describes a DOM node
+ */
+
+ /**
+ *
+ * @param {Tag} The DOM node tag
+ * @param {Object=[]} optional key-value pairs to be mapped to DOM attrs
+ * @param {...mNode=[]} Zero or more Mithril child nodes. Can be an array, or splat (optional)
+ *
+ */
+ function m(tag, pairs) {
+ for (var args = [], i = 1; i < arguments.length; i++) {
+ args[i - 1] = arguments[i];
+ }
+ if (isObject(tag)) return parameterize(tag, args);
+ var hasAttrs = pairs != null && isObject(pairs) && !("tag" in pairs || "view" in pairs || "subtree" in pairs);
+ var attrs = hasAttrs ? pairs : {};
+ var classAttrName = "class" in attrs ? "class" : "className";
+ var cell = {tag: "div", attrs: {}};
+ var match, classes = [];
+ if (!isString(tag)) throw new Error("selector in m(selector, attrs, children) should be a string");
+ while ((match = parser.exec(tag)) != null) {
+ if (match[1] === "" && match[2]) cell.tag = match[2];
+ else if (match[1] === "#") cell.attrs.id = match[2];
+ else if (match[1] === ".") classes.push(match[2]);
+ else if (match[3][0] === "[") {
+ var pair = attrParser.exec(match[3]);
+ cell.attrs[pair[1]] = pair[3] || (pair[2] ? "" :true);
+ }
+ }
+
+ var children = hasAttrs ? args.slice(1) : args;
+ if (children.length === 1 && isArray(children[0])) {
+ cell.children = children[0];
+ }
+ else {
+ cell.children = children;
+ }
+
+ for (var attrName in attrs) {
+ if (attrs.hasOwnProperty(attrName)) {
+ if (attrName === classAttrName && attrs[attrName] != null && attrs[attrName] !== "") {
+ classes.push(attrs[attrName]);
+ cell.attrs[attrName] = ""; //create key in correct iteration order
+ }
+ else cell.attrs[attrName] = attrs[attrName];
+ }
+ }
+ if (classes.length) cell.attrs[classAttrName] = classes.join(" ");
+
+ return cell;
+ }
+ function forEach(list, f) {
+ for (var i = 0; i < list.length && !f(list[i], i++);) {}
+ }
+ function forKeys(list, f) {
+ forEach(list, function (attrs, i) {
+ return (attrs = attrs && attrs.attrs) && attrs.key != null && f(attrs, i);
+ });
+ }
+ // This function was causing deopts in Chrome.
+ // Well no longer
+ function dataToString(data) {
+ if (data == null || data.toString() == null) return "";
+ return data;
+ }
+ // This function was causing deopts in Chrome.
+ function injectTextNode(parentElement, first, index, data) {
+ try {
+ insertNode(parentElement, first, index);
+ first.nodeValue = data;
+ } catch (e) {} //IE erroneously throws error when appending an empty text node after a null
+ }
+
+ function flatten(list) {
+ //recursively flatten array
+ for (var i = 0; i < list.length; i++) {
+ if (isArray(list[i])) {
+ list = list.concat.apply([], list);
+ //check current index again and flatten until there are no more nested arrays at that index
+ i--;
+ }
+ }
+ return list;
+ }
+
+ function insertNode(parentElement, node, index) {
+ parentElement.insertBefore(node, parentElement.childNodes[index] || null);
+ }
+
+ var DELETION = 1, INSERTION = 2, MOVE = 3;
+
+ function handleKeysDiffer(data, existing, cached, parentElement) {
+ forKeys(data, function (key, i) {
+ existing[key = key.key] = existing[key] ? {
+ action: MOVE,
+ index: i,
+ from: existing[key].index,
+ element: cached.nodes[existing[key].index] || $document.createElement("div")
+ } : {action: INSERTION, index: i};
+ });
+ var actions = [];
+ for (var prop in existing) actions.push(existing[prop]);
+ var changes = actions.sort(sortChanges), newCached = new Array(cached.length);
+ newCached.nodes = cached.nodes.slice();
+
+ forEach(changes, function (change) {
+ var index = change.index;
+ if (change.action === DELETION) {
+ clear(cached[index].nodes, cached[index]);
+ newCached.splice(index, 1);
+ }
+ if (change.action === INSERTION) {
+ var dummy = $document.createElement("div");
+ dummy.key = data[index].attrs.key;
+ insertNode(parentElement, dummy, index);
+ newCached.splice(index, 0, {
+ attrs: {key: data[index].attrs.key},
+ nodes: [dummy]
+ });
+ newCached.nodes[index] = dummy;
+ }
+
+ if (change.action === MOVE) {
+ var changeElement = change.element;
+ var maybeChanged = parentElement.childNodes[index];
+ if (maybeChanged !== changeElement && changeElement !== null) {
+ parentElement.insertBefore(changeElement, maybeChanged || null);
+ }
+ newCached[index] = cached[change.from];
+ newCached.nodes[index] = changeElement;
+ }
+ });
+
+ return newCached;
+ }
+
+ function diffKeys(data, cached, existing, parentElement) {
+ var keysDiffer = data.length !== cached.length;
+ if (!keysDiffer) {
+ forKeys(data, function (attrs, i) {
+ var cachedCell = cached[i];
+ return keysDiffer = cachedCell && cachedCell.attrs && cachedCell.attrs.key !== attrs.key;
+ });
+ }
+
+ return keysDiffer ? handleKeysDiffer(data, existing, cached, parentElement) : cached;
+ }
+
+ function diffArray(data, cached, nodes) {
+ //diff the array itself
+
+ //update the list of DOM nodes by collecting the nodes from each item
+ forEach(data, function (_, i) {
+ if (cached[i] != null) nodes.push.apply(nodes, cached[i].nodes);
+ })
+ //remove items from the end of the array if the new array is shorter than the old one. if errors ever happen here, the issue is most likely
+ //a bug in the construction of the `cached` data structure somewhere earlier in the program
+ forEach(cached.nodes, function (node, i) {
+ if (node.parentNode != null && nodes.indexOf(node) < 0) clear([node], [cached[i]]);
+ })
+ if (data.length < cached.length) cached.length = data.length;
+ cached.nodes = nodes;
+ }
+
+ function buildArrayKeys(data) {
+ var guid = 0;
+ forKeys(data, function () {
+ forEach(data, function (attrs) {
+ if ((attrs = attrs && attrs.attrs) && attrs.key == null) attrs.key = "__mithril__" + guid++;
+ })
+ return 1;
+ });
+ }
+
+ function maybeRecreateObject(data, cached, dataAttrKeys) {
+ //if an element is different enough from the one in cache, recreate it
+ if (data.tag !== cached.tag ||
+ dataAttrKeys.sort().join() !== Object.keys(cached.attrs).sort().join() ||
+ data.attrs.id !== cached.attrs.id ||
+ data.attrs.key !== cached.attrs.key ||
+ (m.redraw.strategy() === "all" && (!cached.configContext || cached.configContext.retain !== true)) ||
+ (m.redraw.strategy() === "diff" && cached.configContext && cached.configContext.retain === false)) {
+ if (cached.nodes.length) clear(cached.nodes);
+ if (cached.configContext && isFunction(cached.configContext.onunload)) cached.configContext.onunload();
+ if (cached.controllers) {
+ forEach(cached.controllers, function (controller) {
+ if (controller.unload) controller.onunload({preventDefault: noop});
+ });
+ }
+ }
+ }
+
+ function getObjectNamespace(data, namespace) {
+ return data.attrs.xmlns ? data.attrs.xmlns :
+ data.tag === "svg" ? "http://www.w3.org/2000/svg" :
+ data.tag === "math" ? "http://www.w3.org/1998/Math/MathML" :
+ namespace;
+ }
+
+ function unloadCachedControllers(cached, views, controllers) {
+ if (controllers.length) {
+ cached.views = views;
+ cached.controllers = controllers;
+ forEach(controllers, function (controller) {
+ if (controller.onunload && controller.onunload.$old) controller.onunload = controller.onunload.$old;
+ if (pendingRequests && controller.onunload) {
+ var onunload = controller.onunload;
+ controller.onunload = noop;
+ controller.onunload.$old = onunload;
+ }
+ });
+ }
+ }
+
+ function scheduleConfigsToBeCalled(configs, data, node, isNew, cached) {
+ //schedule configs to be called. They are called after `build`
+ //finishes running
+ if (isFunction(data.attrs.config)) {
+ var context = cached.configContext = cached.configContext || {};
+
+ //bind
+ configs.push(function() {
+ return data.attrs.config.call(data, node, !isNew, context, cached);
+ });
+ }
+ }
+
+ function buildUpdatedNode(cached, data, editable, hasKeys, namespace, views, configs, controllers) {
+ var node = cached.nodes[0];
+ if (hasKeys) setAttributes(node, data.tag, data.attrs, cached.attrs, namespace);
+ cached.children = build(node, data.tag, undefined, undefined, data.children, cached.children, false, 0, data.attrs.contenteditable ? node : editable, namespace, configs);
+ cached.nodes.intact = true;
+
+ if (controllers.length) {
+ cached.views = views;
+ cached.controllers = controllers;
+ }
+
+ return node;
+ }
+
+ function handleNonexistentNodes(data, parentElement, index) {
+ var nodes;
+ if (data.$trusted) {
+ nodes = injectHTML(parentElement, index, data);
+ }
+ else {
+ nodes = [$document.createTextNode(data)];
+ if (!parentElement.nodeName.match(voidElements)) insertNode(parentElement, nodes[0], index);
+ }
+
+ var cached = typeof data === "string" || typeof data === "number" || typeof data === "boolean" ? new data.constructor(data) : data;
+ cached.nodes = nodes;
+ return cached;
+ }
+
+ function reattachNodes(data, cached, parentElement, editable, index, parentTag) {
+ var nodes = cached.nodes;
+ if (!editable || editable !== $document.activeElement) {
+ if (data.$trusted) {
+ clear(nodes, cached);
+ nodes = injectHTML(parentElement, index, data);
+ }
+ //corner case: replacing the nodeValue of a text node that is a child of a textarea/contenteditable doesn't work
+ //we need to update the value property of the parent textarea or the innerHTML of the contenteditable element instead
+ else if (parentTag === "textarea") {
+ parentElement.value = data;
+ }
+ else if (editable) {
+ editable.innerHTML = data;
+ }
+ else {
+ //was a trusted string
+ if (nodes[0].nodeType === 1 || nodes.length > 1) {
+ clear(cached.nodes, cached);
+ nodes = [$document.createTextNode(data)];
+ }
+ injectTextNode(parentElement, nodes[0], index, data);
+ }
+ }
+ cached = new data.constructor(data);
+ cached.nodes = nodes;
+ return cached;
+ }
+
+ function handleText(cached, data, index, parentElement, shouldReattach, editable, parentTag) {
+ //handle text nodes
+ return cached.nodes.length === 0 ? handleNonexistentNodes(data, parentElement, index) :
+ cached.valueOf() !== data.valueOf() || shouldReattach === true ?
+ reattachNodes(data, cached, parentElement, editable, index, parentTag) :
+ (cached.nodes.intact = true, cached);
+ }
+
+ function getSubArrayCount(item) {
+ if (item.$trusted) {
+ //fix offset of next element if item was a trusted string w/ more than one html element
+ //the first clause in the regexp matches elements
+ //the second clause (after the pipe) matches text nodes
+ var match = item.match(/<[^\/]|\>\s*[^<]/g);
+ if (match != null) return match.length;
+ }
+ else if (isArray(item)) {
+ return item.length;
+ }
+ return 1;
+ }
+
+ function buildArray(data, cached, parentElement, index, parentTag, shouldReattach, editable, namespace, configs) {
+ data = flatten(data);
+ var nodes = [], intact = cached.length === data.length, subArrayCount = 0;
+
+ //keys algorithm: sort elements without recreating them if keys are present
+ //1) create a map of all existing keys, and mark all for deletion
+ //2) add new keys to map and mark them for addition
+ //3) if key exists in new list, change action from deletion to a move
+ //4) for each key, handle its corresponding action as marked in previous steps
+ var existing = {}, shouldMaintainIdentities = false;
+ forKeys(cached, function (attrs, i) {
+ shouldMaintainIdentities = true;
+ existing[cached[i].attrs.key] = {action: DELETION, index: i};
+ });
+
+ buildArrayKeys(data);
+ if (shouldMaintainIdentities) cached = diffKeys(data, cached, existing, parentElement);
+ //end key algorithm
+
+ var cacheCount = 0;
+ //faster explicitly written
+ for (var i = 0, len = data.length; i < len; i++) {
+ //diff each item in the array
+ var item = build(parentElement, parentTag, cached, index, data[i], cached[cacheCount], shouldReattach, index + subArrayCount || subArrayCount, editable, namespace, configs);
+
+ if (item !== undefined) {
+ intact = intact && item.nodes.intact;
+ subArrayCount += getSubArrayCount(item);
+ cached[cacheCount++] = item;
+ }
+ }
+
+ if (!intact) diffArray(data, cached, nodes);
+ return cached
+ }
+
+ function makeCache(data, cached, index, parentIndex, parentCache) {
+ if (cached != null) {
+ if (type.call(cached) === type.call(data)) return cached;
+
+ if (parentCache && parentCache.nodes) {
+ var offset = index - parentIndex, end = offset + (isArray(data) ? data : cached.nodes).length;
+ clear(parentCache.nodes.slice(offset, end), parentCache.slice(offset, end));
+ } else if (cached.nodes) {
+ clear(cached.nodes, cached);
+ }
+ }
+
+ cached = new data.constructor();
+ //if constructor creates a virtual dom element, use a blank object
+ //as the base cached node instead of copying the virtual el (#277)
+ if (cached.tag) cached = {};
+ cached.nodes = [];
+ return cached;
+ }
+
+ function constructNode(data, namespace) {
+ return namespace === undefined ?
+ data.attrs.is ? $document.createElement(data.tag, data.attrs.is) : $document.createElement(data.tag) :
+ data.attrs.is ? $document.createElementNS(namespace, data.tag, data.attrs.is) : $document.createElementNS(namespace, data.tag);
+ }
+
+ function constructAttrs(data, node, namespace, hasKeys) {
+ return hasKeys ? setAttributes(node, data.tag, data.attrs, {}, namespace) : data.attrs;
+ }
+
+ function constructChildren(data, node, cached, editable, namespace, configs) {
+ return data.children != null && data.children.length > 0 ?
+ build(node, data.tag, undefined, undefined, data.children, cached.children, true, 0, data.attrs.contenteditable ? node : editable, namespace, configs) :
+ data.children;
+ }
+
+ function reconstructCached(data, attrs, children, node, namespace, views, controllers) {
+ var cached = {tag: data.tag, attrs: attrs, children: children, nodes: [node]};
+ unloadCachedControllers(cached, views, controllers);
+ if (cached.children && !cached.children.nodes) cached.children.nodes = [];
+ //edge case: setting value on