Compare commits

..

No commits in common. "master" and "v0.4.8" have entirely different histories.

17 changed files with 6727 additions and 18904 deletions

View File

@ -1,21 +0,0 @@
module.exports = {
"env": {
"browser": true,
"commonjs": true,
"jquery": true,
"es6": true
},
"extends": "eslint:recommended",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
"rules": {
"no-console": "off",
"semi": "warn",
}
};

View File

@ -1,13 +0,0 @@
# Road Map
- [x] Block castling through check (middle square needs to be clear of check).
- [x] Notifications for games other than the currently selected game.
- [ ] Protocol and UI for offering and accepting a draw.
- [ ] In-browser local, private games.
- [ ] Password-protected user accounts.
- [ ] Server-side storage for settings across browsers.
- [ ] Persistent (but changeable) display names.
- [ ] Games "owned" by specific player accounts.
- [ ] Invite specific other players to join new games.
- [ ] Create open games for other players to join.
- [ ] Create games controlled entirely by one player.

View File

@ -2,375 +2,92 @@
box-sizing: border-box;
}
html, body, #page {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
background: white;
}
body {
font-family: 'Roboto', sans-serif;
padding: 0;
margin: 0;
}
body > #page {
position: fixed;
top: 0;
left: 0;
#page {
width: 100%;
display: flex;
flex-flow: row nowrap;
}
#board_ui {
height: 100vh;
display: flex;
flex-flow: column nowrap;
justify-content: stretch;
align-items: center;
width: 100%;
height: 100%;
background-color: #FFFFF0;
}
#page.horizontal-layout #board_ui {
border-left: 10px solid #C4B28F;
border-image:
linear-gradient(
to right,
#C4B28F,
#F5DEB3 15%,
#C4B28F 45%,
#FFFFF0 80%,
#C4B28F) 1 100%;
}
#header {
display: flex;
flex-flow: row nowrap;
flex: 0 0 auto;
width: 100%;
height: 2.5rem;
font-size: 2rem;
line-height: 2.4rem;
margin: 0;
background-image: linear-gradient(#FFFFF0, #F5DEB3);
border-bottom: 1px solid black;
align-items: center;
}
#header > h1 {
h1 {
font-family: 'Vollkorn', serif;
text-align: center;
font-size: 1.2rem;
line-height: 2.4rem;
margin: 0;
padding: 0;
padding-top: 0.1rem;
height: 2.5rem;
white-space: nowrap;
flex: 1 0 auto;
font-size: 2em;
line-height: 1.4em;
height: 1.4em;
margin-top: 8px;
margin-left: 8px;
margin-bottom: 0;
}
#header > button {
flex: 0 0 auto;
width: 2.5rem;
height: 2.5rem;
border: none;
background: none;
padding: 0;
margin: 0;
a.plain-link {
font-family: inherit;
font-size: inherit;
font-weight: inherit;
line-height: inherit;
color: inherit;
background-color: inherit;
text-decoration: inherit;
}
#header > button:active {
background-image: linear-gradient(#F5DEB3, #FFFFF0);
.media-button-svg {
width: 12pt;
height: 12pt;
}
input.image-checkbox {
display: inline-block;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
padding: 0;
margin: 0;
button:disabled .silhouette {
fill: #c0c0c0;
}
input.image-checkbox:checked {
color: #00f;
}
input.image-checkbox:focus {
outline: blue solid medium;
outline: -webkit-focus-ring-color solid medium;
outline-offset: 3px;
}
#header > .checkbox-container {
flex: 0 0 auto;
#content {
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
width: 2.5rem;
height: 2.5rem;
border: none;
background: none;
flex-flow: row nowrap;
}
button#settings, button#cb_choose_game {
border-right: 1px solid #DCC8A1;
#cb_outer2 {
flex: 1 1 auto;
width: 100%;
max-width: calc(100vh - (8px + 2.8em + 8px));
margin-left: 8px;
}
#header > .checkbox-container, button#help {
border-left: 1px solid #DCC8A1;
#cb_outer {
width: 100%;
max-width: calc(100vw - (8px + 24px));
}
#cb_container {
width: 100%;
flex: 1 1 auto;
position: relative;
width: 100%;
padding-top: 100%;
}
#page.horizontal-layout #cb_container {
flex: 0 0.5 auto;
#cb_inner {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
#cb_board {
position: absolute;
position: relative;
width: 100%;
height: 100%;
border-collapse: collapse;
border-style: hidden;
padding-top: 100%;
box-shadow: 0 0 0 1px black, 2px 2px 4px #00000080;
border-radius: 6pt;
overflow: hidden;
background-color: #FAEED2;
}
#cb_status {
display: flex;
position: relative;
flex-flow: column nowrap;
width: 100%;
padding-top: 0.25rem;
padding-left: 0.25rem;
padding-right: 0.25rem;
padding-bottom: 0.5rem;
}
#page.horizontal-layout #cb_status {
flex: 1 1 auto;
}
#cb_status::after {
content: '';
display: block;
position: absolute;
width: 100%;
height: 1.5em;
left: 0;
bottom: 0.5rem;
background: linear-gradient(rgba(255,255,240,0),rgba(255,255,240,1));
pointer-events: none;
}
#cb_message {
height: 1.2em;
margin-bottom: 0.1rem;
flex: 1 1 auto;
}
#cb_explain_check {
color: red;
height: 2.4em;
margin-bottom: 0.1em;
}
#cb_scrollable {
flex: 0 0 auto;
overflow: auto;
height: 4.8em;
padding-bottom: 1.2em;
}
#page.horizontal-layout #cb_scrollable {
flex: 1 1 auto;
}
#cb_history {
color: black;
}
#cb_history_future {
color: grey;
}
#cb_times {
display: flex;
flex-flow: row nowrap;
white-space: nowrap;
justify-content: stretch;
align-items: flex-end;
width: 100%;
padding-left: 3rem;
padding-right: 3rem;
}
#cb_times.cb-hide-times {
visibility: hidden;
}
#cb_light_time, #cb_dark_time {
width: 100%;
}
#cb_light_time {
text-align: left;
}
#cb_dark_time {
text-align: right;
}
#cb_names {
position: relative;
display: flex;
flex-flow: row nowrap;
white-space: nowrap;
justify-content: stretch;
align-items: flex-end;
font-size: 1.5rem;
width: 100%;
height: 3rem;
padding-left: 2rem;
padding-right: 2rem;
}
#cb_names_text {
display: flex;
flex-flow: row nowrap;
white-space: nowrap;
justify-content: stretch;
align-items: baseline;
width: 100%;
z-index: 1;
}
#cb_names::before {
content: '';
display: block;
background-image: url(../svg/pacosako-theme.svg#light_king_left);
background-size: contain;
background-repeat: no-repeat;
position: absolute;
bottom: 0;
left: 0.5rem;
width: 3rem;
height: 3rem;
}
#cb_names.cb-light-turn::before {
filter: drop-shadow(0 0 5px blue);
-webkit-filter: drop-shadow(0 0 5px blue);
}
#cb_names.cb-light-won::before {
filter: drop-shadow(0 0 5px darkviolet);
-webkit-filter: drop-shadow(0 0 5px darkviolet);
}
#cb_names::after {
content: '';
display: block;
background-image: url(../svg/pacosako-theme.svg#dark_king_right);
background-size: contain;
background-repeat: no-repeat;
position: absolute;
bottom: 0;
right: 0.5rem;
width: 3rem;
height: 3rem;
}
#cb_names.cb-dark-turn::after {
filter: drop-shadow(0 0 5px blue);
-webkit-filter: drop-shadow(0 0 5px blue);
}
#cb_names.cb-dark-won::after {
filter: drop-shadow(0 0 5px darkviolet);
-webkit-filter: drop-shadow(0 0 5px darkviolet);
}
#cb_names .cb-names-vs {
padding-left: 0.25em;
padding-right: 0.25em;
}
#cb_names input {
flex: 1 1 auto;
width: 4em;
background-color: inherit;
border: none;
margin: 2px;
font-size: 1.5rem;
}
#cb_names input:focus {
outline: 1px solid blue;
outline-offset: 2px;
}
#cb_dark_name {
text-align: right;
}
#cb_navigate {
display: flex;
flex-flow: row nowrap;
align-items: stretch;
justify-content: stretch;
border-top: 1px solid black;
background-image: linear-gradient(#FFFFF0, #F5DEB3);
white-space: nowrap;
width: 100%;
flex: 0 1 auto;
font-size: 1.25rem;
}
#cb_navigate .nav-spacer {
flex: 1 1 auto;
min-width: 1rem;
width: 100%;
background: none;
background-color: #DCC8A140;
}
#cb_navigate button {
padding: 0;
margin: 0;
border: none;
width: 2rem;
min-width: 2rem;
min-height: 2rem;
background: none;
font-size: inherit;
}
#cb_navigate button:active {
background-image: linear-gradient(#F5DEB3, #FFFFF0);
}
#cb_navigate > .nav-spacer, #cb_navigate > button {
border-left: 1px solid #DCC8A1;
}
#cb_navigate > .nav-spacer:first-child, #cb_navigate > button:first-child {
border-left: none;
}
#cb_board tr {
position: relative;
}
@ -380,14 +97,163 @@ button#settings, button#cb_choose_game {
position: relative;
}
#cb_light_name, #cb_dark_name {
width: 8em;
}
#cb_control_container {
display: flex;
flex-flow: column nowrap;
flex: 0 1000 auto;
margin-left: 1em;
width: 100%;
min-width: 24em;
max-height: calc(100vh - (8px + 2.8em));
padding-right: calc(3.25em + 10px);
}
#cb_control_form {
flex: 0 1 auto;
display: flex;
flex-flow: column nowrap;
margin-right: auto;
border-radius: 6pt;
padding: 1.125em;
background-color: #FFFFF0;
box-shadow: 0 0 0 1px black, 2px 2px 4px #00000080;
}
#cb_controls, #cb_theme, #cb_names, #cb_navigate {
white-space: nowrap;
}
#cb_theme, #cb_names, #cb_navigate {
margin-top: 1.125em;
}
#cb_names input {
background-color: inherit;
border: none;
border-bottom: 1px solid black;
margin: 2px;
}
#cb_names input:focus {
outline: 1px solid blue;
outline-offset: 2px;
}
#cb_scrollable {
flex: 1 1000 auto;
padding-bottom: 0.5em;
overflow: auto;
}
#cb_message {
margin-top: 0.5em;
margin-bottom: 1em;
}
#cb_theme {
display: flex;
flex-flow: row nowrap;
align-items: baseline;
}
.cb-spacer {
flex: 1 1 auto;
}
#cb_choose_game {
margin-left: 0.2em;
}
#cb_theme label {
flex: 0 0 auto;
padding-right: 0.2em;
}
#cb_undo {
margin-left: auto;
margin-right: 0.1em;
}
#cb_redo {
margin-left: 0.1em;
margin-right: auto;
}
#cb_resign {
margin-left: 0.1em;
margin-right: 0;
}
#cb_navigate {
display: flex;
flex-flow: row nowrap;
justify-items: center;
justify-content: center;
padding-left: 1em;
}
#cb_navigate button {
margin-left: 0.1em;
margin-right: 0.1em;
}
#cb_navigate button:first-child {
margin-left: 0;
}
#cb_navigate button:last-child {
margin-right: 0;
}
#cb_history {
max-width: 7.5in;
margin-bottom: 0.5em;
}
#cb_history_future {
color: grey;
}
#cb_explain_check {
color: red;
margin-top: 0.5em;
}
.cb-hbox {
display: flex;
flex-flow: row nowrap;
align-items: center;
}
.cb-vbox {
display: flex;
flex-flow: column nowrap;
align-items: center;
}
.cb-align-start {
align-items: start;
}
.cb-align-stretch {
align-items: stretch;
}
.cb-square {
position: relative;
width: calc((100% - 16pt) / 8);
height: calc((100% - 16pt) / 8);
border: 1px solid black;
padding: 0;
}
.cb-horiz-label {
position: relative;
width: calc((100% - 16pt) / 8);
height: 8pt;
border: 1px solid black;
padding: 0;
@ -395,7 +261,7 @@ button#settings, button#cb_choose_game {
.cb-horiz-label div {
position: absolute;
top: calc(50% - 3pt);
top: calc(50% - (1em / 2));
left: 0;
bottom: 0;
right: 0;
@ -407,6 +273,7 @@ button#settings, button#cb_choose_game {
.cb-vert-label {
position: relative;
width: 8pt;
height: calc((100% - 16pt) / 8);
border: 1px solid black;
padding: 0;
}
@ -471,20 +338,20 @@ button#settings, button#cb_choose_game {
height: 100%;
}
.cb-phantom .cb-lt-piece,
.cb-phantom .cb-dk-piece {
#cb_phantom .cb-lt-piece,
#cb_phantom .cb-dk-piece {
top: 5%;
}
#cb_board .cb-phantom .cb-lt-piece,
#cb_board.cb-reversed .cb-phantom .cb-dk-piece {
#cb_board #cb_phantom .cb-lt-piece,
#cb_board.cb-reversed #cb_phantom .cb-dk-piece {
left: 15%;
right: auto;
clip-path: inset(0 15% 0 0);
}
#cb_board .cb-phantom .cb-dk-piece,
#cb_board.cb-reversed .cb-phantom .cb-lt-piece {
#cb_board #cb_phantom .cb-dk-piece,
#cb_board.cb-reversed #cb_phantom .cb-lt-piece {
left: auto;
right: 15%;
clip-path: inset(0 0 0 15%);
@ -526,62 +393,13 @@ button#settings, button#cb_choose_game {
z-index: 1;
}
.cb-private .cb-hide-if-private {
display: none !important;
}
.cb-show-if-private {
display: none !important;
}
.cb-private .cb-show-if-private {
display: initial !important;
}
div.hbox {
display: flex;
flex-flow: row nowrap;
justify-content: stretch;
align-items: stretch;
}
.private-link {
flex: 0 1 auto;
margin: 0.1em;
color: black;
}
.private-link:visited {
color: black;
}
.private-link:hover {
color: blue;
}
.jBox-wrapper.jBox-hasTitle > .jBox-container {
padding: 4px; /* same as border-radius */
}
.jBox-title h2 {
margin: 0;
}
.rules {
display: block;
max-width: 80vw;
}
.badges {
position: static;
bottom: auto;
right: auto;
margin-top: 0;
margin-bottom: 0;
margin-left: auto;
margin-right: 5px;
position: fixed;
bottom: 5px;
right: 5px;
margin: 0;
display: flex;
flex-flow: row nowrap;
flex-flow: column nowrap;
justify-content: flex-end;
align-items: center;
}
@ -591,31 +409,23 @@ div.hbox {
}
.badge img {
width: 3rem;
height: 3rem;
width: 3em;
height: 3em;
opacity: 0.5;
margin: 0;
}
#cb_theme {
display: flex;
flex-flow: row nowrap;
align-items: baseline;
margin-top: 1rem;
}
#cb_theme label {
flex: 0 0 auto;
padding-right: 0.2rem;
.badge.game-link-badge img {
width: 1.8em;
height: 1.8em;
margin: 0.6em;
}
.game-tiles {
width: calc(100vw - 6rem);
max-width: calc(100vw - 6rem);
max-height: calc(100vh - 12rem);
display: grid;
grid-template-columns: repeat(auto-fill, minmax(15em, auto));
align-items: center;
justify-items: center;
max-width: 80vw;
max-height: 80vh;
overflow-y: auto;
text-align: center;
}
.game-tiles > * {
@ -624,14 +434,14 @@ div.hbox {
.game-tile {
position: relative;
display: flex;
display: inline-flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
width: 14em;
height: 14em;
box-shadow: 0 0 0 1px black, 5px 5px 3px #00000080;
margin: 0.5em;
margin: 1em;
padding: 0.5em;
border-radius: 6pt;
background-color: #FFFFF0;
@ -664,7 +474,6 @@ div.hbox {
font-size: 3em;
text-shadow: 2px 2px 4px #000000c0;
font-weight: bold;
text-align: center;
}
.new-game-text::before {
@ -787,46 +596,77 @@ div.hbox {
margin-top: 0.5em;
}
.game-tiles {
font-size: calc(12in * 0.014);
.game-tile {
font-size: calc(12in * 0.015);
}
@media only screen and (min-width: 6in) and (max-width: 12in) {
.game-tiles {
font-size: 1.4vw;
.game-tile {
font-size: 1.5vw;
}
}
@media only screen and (max-width: 6in) {
.game-tiles {
font-size: calc(6in * 0.014);
.game-tile {
font-size: calc(6in * 0.015);
}
}
.cb-dk-piece.cb-king { content: url(../svg/pacosako-theme.svg#dark_king_right); }
.cb-dk-piece.cb-queen { content: url(../svg/pacosako-theme.svg#dark_queen_right); }
.cb-dk-piece.cb-bishop { content: url(../svg/pacosako-theme.svg#dark_bishop_right); }
.cb-dk-piece.cb-knight { content: url(../svg/pacosako-theme.svg#dark_knight_right); }
.cb-dk-piece.cb-rook { content: url(../svg/pacosako-theme.svg#dark_rook_right); }
.cb-dk-piece.cb-pawn { content: url(../svg/pacosako-theme.svg#dark_pawn_right); }
.cb-lt-piece.cb-king { content: url(../svg/pacosako-theme.svg#light_king_left); }
.cb-lt-piece.cb-queen { content: url(../svg/pacosako-theme.svg#light_queen_left); }
.cb-lt-piece.cb-bishop { content: url(../svg/pacosako-theme.svg#light_bishop_left); }
.cb-lt-piece.cb-knight { content: url(../svg/pacosako-theme.svg#light_knight_left); }
.cb-lt-piece.cb-rook { content: url(../svg/pacosako-theme.svg#light_rook_left); }
.cb-lt-piece.cb-pawn { content: url(../svg/pacosako-theme.svg#light_pawn_left); }
@media only screen and (max-aspect-ratio: 3/2) {
#content {
flex-flow: column nowrap;
}
.cb-reversed .cb-dk-piece.cb-king { content: url(../svg/pacosako-theme.svg#dark_king_left); }
.cb-reversed .cb-dk-piece.cb-queen { content: url(../svg/pacosako-theme.svg#dark_queen_left); }
.cb-reversed .cb-dk-piece.cb-bishop { content: url(../svg/pacosako-theme.svg#dark_bishop_left); }
.cb-reversed .cb-dk-piece.cb-knight { content: url(../svg/pacosako-theme.svg#dark_knight_left); }
.cb-reversed .cb-dk-piece.cb-rook { content: url(../svg/pacosako-theme.svg#dark_rook_left); }
.cb-reversed .cb-dk-piece.cb-pawn { content: url(../svg/pacosako-theme.svg#dark_pawn_left); }
.cb-reversed .cb-lt-piece.cb-king { content: url(../svg/pacosako-theme.svg#light_king_right); }
.cb-reversed .cb-lt-piece.cb-queen { content: url(../svg/pacosako-theme.svg#light_queen_right); }
.cb-reversed .cb-lt-piece.cb-bishop { content: url(../svg/pacosako-theme.svg#light_bishop_right); }
.cb-reversed .cb-lt-piece.cb-knight { content: url(../svg/pacosako-theme.svg#light_knight_right); }
.cb-reversed .cb-lt-piece.cb-rook { content: url(../svg/pacosako-theme.svg#light_rook_right); }
.cb-reversed .cb-lt-piece.cb-pawn { content: url(../svg/pacosako-theme.svg#light_pawn_right); }
#cb_outer2 {
width: auto;
}
#cb_control_container {
margin-top: 1em;
margin-left: 8px;
max-height: none;
overflow: visible;
width: 100%;
max-width: calc(100vw - (8px + 24px));
padding-right: 0;
}
.badges {
position: static;
bottom: auto;
right: auto;
margin-left: auto;
margin-right: 5px;
display: flex;
flex-flow: row nowrap;
justify-content: flex-end;
}
}
.cb-dk-piece.cb-king { content: url(../svg/traditional-theme.svg#dark_king_right); }
.cb-dk-piece.cb-queen { content: url(../svg/traditional-theme.svg#dark_queen_right); }
.cb-dk-piece.cb-bishop { content: url(../svg/traditional-theme.svg#dark_bishop_right); }
.cb-dk-piece.cb-knight { content: url(../svg/traditional-theme.svg#dark_knight_right); }
.cb-dk-piece.cb-rook { content: url(../svg/traditional-theme.svg#dark_rook_right); }
.cb-dk-piece.cb-pawn { content: url(../svg/traditional-theme.svg#dark_pawn_right); }
.cb-lt-piece.cb-king { content: url(../svg/traditional-theme.svg#light_king_left); }
.cb-lt-piece.cb-queen { content: url(../svg/traditional-theme.svg#light_queen_left); }
.cb-lt-piece.cb-bishop { content: url(../svg/traditional-theme.svg#light_bishop_left); }
.cb-lt-piece.cb-knight { content: url(../svg/traditional-theme.svg#light_knight_left); }
.cb-lt-piece.cb-rook { content: url(../svg/traditional-theme.svg#light_rook_left); }
.cb-lt-piece.cb-pawn { content: url(../svg/traditional-theme.svg#light_pawn_left); }
.cb-reversed .cb-dk-piece.cb-king { content: url(../svg/traditional-theme.svg#dark_king_left); }
.cb-reversed .cb-dk-piece.cb-queen { content: url(../svg/traditional-theme.svg#dark_queen_left); }
.cb-reversed .cb-dk-piece.cb-bishop { content: url(../svg/traditional-theme.svg#dark_bishop_left); }
.cb-reversed .cb-dk-piece.cb-knight { content: url(../svg/traditional-theme.svg#dark_knight_left); }
.cb-reversed .cb-dk-piece.cb-rook { content: url(../svg/traditional-theme.svg#dark_rook_left); }
.cb-reversed .cb-dk-piece.cb-pawn { content: url(../svg/traditional-theme.svg#dark_pawn_left); }
.cb-reversed .cb-lt-piece.cb-king { content: url(../svg/traditional-theme.svg#light_king_right); }
.cb-reversed .cb-lt-piece.cb-queen { content: url(../svg/traditional-theme.svg#light_queen_right); }
.cb-reversed .cb-lt-piece.cb-bishop { content: url(../svg/traditional-theme.svg#light_bishop_right); }
.cb-reversed .cb-lt-piece.cb-knight { content: url(../svg/traditional-theme.svg#light_knight_right); }
.cb-reversed .cb-lt-piece.cb-rook { content: url(../svg/traditional-theme.svg#light_rook_right); }
.cb-reversed .cb-lt-piece.cb-pawn { content: url(../svg/traditional-theme.svg#light_pawn_right); }
/* vim: set expandtab sw=3 ts=8: */

View File

@ -1,25 +0,0 @@
.cb-theme-traditional .cb-dk-piece.cb-king { content: url(../../svg/traditional-theme.svg#dark_king_right); }
.cb-theme-traditional .cb-dk-piece.cb-queen { content: url(../../svg/traditional-theme.svg#dark_queen_right); }
.cb-theme-traditional .cb-dk-piece.cb-bishop { content: url(../../svg/traditional-theme.svg#dark_bishop_right); }
.cb-theme-traditional .cb-dk-piece.cb-knight { content: url(../../svg/traditional-theme.svg#dark_knight_right); }
.cb-theme-traditional .cb-dk-piece.cb-rook { content: url(../../svg/traditional-theme.svg#dark_rook_right); }
.cb-theme-traditional .cb-dk-piece.cb-pawn { content: url(../../svg/traditional-theme.svg#dark_pawn_right); }
.cb-theme-traditional .cb-lt-piece.cb-king { content: url(../../svg/traditional-theme.svg#light_king_left); }
.cb-theme-traditional .cb-lt-piece.cb-queen { content: url(../../svg/traditional-theme.svg#light_queen_left); }
.cb-theme-traditional .cb-lt-piece.cb-bishop { content: url(../../svg/traditional-theme.svg#light_bishop_left); }
.cb-theme-traditional .cb-lt-piece.cb-knight { content: url(../../svg/traditional-theme.svg#light_knight_left); }
.cb-theme-traditional .cb-lt-piece.cb-rook { content: url(../../svg/traditional-theme.svg#light_rook_left); }
.cb-theme-traditional .cb-lt-piece.cb-pawn { content: url(../../svg/traditional-theme.svg#light_pawn_left); }
.cb-theme-traditional.cb-reversed .cb-dk-piece.cb-king { content: url(../../svg/traditional-theme.svg#dark_king_left); }
.cb-theme-traditional.cb-reversed .cb-dk-piece.cb-queen { content: url(../../svg/traditional-theme.svg#dark_queen_left); }
.cb-theme-traditional.cb-reversed .cb-dk-piece.cb-bishop { content: url(../../svg/traditional-theme.svg#dark_bishop_left); }
.cb-theme-traditional.cb-reversed .cb-dk-piece.cb-knight { content: url(../../svg/traditional-theme.svg#dark_knight_left); }
.cb-theme-traditional.cb-reversed .cb-dk-piece.cb-rook { content: url(../../svg/traditional-theme.svg#dark_rook_left); }
.cb-theme-traditional.cb-reversed .cb-dk-piece.cb-pawn { content: url(../../svg/traditional-theme.svg#dark_pawn_left); }
.cb-theme-traditional.cb-reversed .cb-lt-piece.cb-king { content: url(../../svg/traditional-theme.svg#light_king_right); }
.cb-theme-traditional.cb-reversed .cb-lt-piece.cb-queen { content: url(../../svg/traditional-theme.svg#light_queen_right); }
.cb-theme-traditional.cb-reversed .cb-lt-piece.cb-bishop { content: url(../../svg/traditional-theme.svg#light_bishop_right); }
.cb-theme-traditional.cb-reversed .cb-lt-piece.cb-knight { content: url(../../svg/traditional-theme.svg#light_knight_right); }
.cb-theme-traditional.cb-reversed .cb-lt-piece.cb-rook { content: url(../../svg/traditional-theme.svg#light_rook_right); }
.cb-theme-traditional.cb-reversed .cb-lt-piece.cb-pawn { content: url(../../svg/traditional-theme.svg#light_pawn_right); }

View File

@ -1,4 +1,3 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
@ -15,212 +14,262 @@
</head>
<body>
<div id="page">
<div id="board_ui">
<div id="header">
<button id="settings" title="Settings" type="button"><span class="fas fa-cog"></span></button>
<button id="cb_choose_game" title="Choose Game" type="button" class="cb-hide-if-private"><span class="fas fa-list"></span></button>
<h1>Paco Ŝako<span class="cb-show-if-private" style="display: none"> - Private Mode</span></h1>
<div class="checkbox-container"><input id="cb_reverse" title="Reverse Board" type="checkbox" autocomplete="off" class="image-checkbox fas fa-sync"></div>
<div class="checkbox-container cb-hide-if-private"><input id="cb_notify" title="Notify" type="checkbox" autocomplete="off" class="image-checkbox fas fa-bell-slash"></div>
<button id="help" title="Help" type="button"><span class="fas fa-question-circle"></span></button>
</div>
<h1><a href="." class="plain-link">Paco Ŝako</a></h1>
<div id="cb_container">
<table id="cb_board" class="noselect cb-theme-pacosako" style="visibility: hidden">
<tr id="cb_row9">
<td id="cb_L9" class="cb-corner"></td>
<td id="cb_a9" class="cb-horiz-label"><div>A</div></td>
<td id="cb_b9" class="cb-horiz-label"><div>B</div></td>
<td id="cb_c9" class="cb-horiz-label"><div>C</div></td>
<td id="cb_d9" class="cb-horiz-label"><div>D</div></td>
<td id="cb_e9" class="cb-horiz-label"><div>E</div></td>
<td id="cb_f9" class="cb-horiz-label"><div>F</div></td>
<td id="cb_g9" class="cb-horiz-label"><div>G</div></td>
<td id="cb_h9" class="cb-horiz-label"><div>H</div></td>
<td id="cb_R9" class="cb-corner"></td>
</tr>
<tr id="cb_row8">
<td id="cb_L8" class="cb-vert-label"><div>8</div></td>
<td id="cb_a8" class="cb-square cb-lt-bg"></td>
<td id="cb_b8" class="cb-square cb-dk-bg"></td>
<td id="cb_c8" class="cb-square cb-lt-bg"></td>
<td id="cb_d8" class="cb-square cb-dk-bg"></td>
<td id="cb_e8" class="cb-square cb-lt-bg"></td>
<td id="cb_f8" class="cb-square cb-dk-bg"></td>
<td id="cb_g8" class="cb-square cb-lt-bg"></td>
<td id="cb_h8" class="cb-square cb-dk-bg"></td>
<td id="cb_R8" class="cb-vert-label"><div>8</div></td>
</tr>
<tr id="cb_row7">
<td id="cb_L7" class="cb-vert-label"><div>7</div></td>
<td id="cb_a7" class="cb-square cb-dk-bg"></td>
<td id="cb_b7" class="cb-square cb-lt-bg"></td>
<td id="cb_c7" class="cb-square cb-dk-bg"></td>
<td id="cb_d7" class="cb-square cb-lt-bg"></td>
<td id="cb_e7" class="cb-square cb-dk-bg"></td>
<td id="cb_f7" class="cb-square cb-lt-bg"></td>
<td id="cb_g7" class="cb-square cb-dk-bg"></td>
<td id="cb_h7" class="cb-square cb-lt-bg"></td>
<td id="cb_R7" class="cb-vert-label"><div>7</div></td>
</tr>
<tr id="cb_row6">
<td id="cb_L6" class="cb-vert-label"><div>6</div></td>
<td id="cb_a6" class="cb-square cb-lt-bg"></td>
<td id="cb_b6" class="cb-square cb-dk-bg"></td>
<td id="cb_c6" class="cb-square cb-lt-bg"></td>
<td id="cb_d6" class="cb-square cb-dk-bg"></td>
<td id="cb_e6" class="cb-square cb-lt-bg"></td>
<td id="cb_f6" class="cb-square cb-dk-bg"></td>
<td id="cb_g6" class="cb-square cb-lt-bg"></td>
<td id="cb_h6" class="cb-square cb-dk-bg"></td>
<td id="cb_R6" class="cb-vert-label"><div>6</div></td>
</tr>
<tr id="cb_row5">
<td id="cb_L5" class="cb-vert-label"><div>5</div></td>
<td id="cb_a5" class="cb-square cb-dk-bg"></td>
<td id="cb_b5" class="cb-square cb-lt-bg"></td>
<td id="cb_c5" class="cb-square cb-dk-bg"></td>
<td id="cb_d5" class="cb-square cb-lt-bg"></td>
<td id="cb_e5" class="cb-square cb-dk-bg"></td>
<td id="cb_f5" class="cb-square cb-lt-bg"></td>
<td id="cb_g5" class="cb-square cb-dk-bg"></td>
<td id="cb_h5" class="cb-square cb-lt-bg"></td>
<td id="cb_R5" class="cb-vert-label"><div>5</div></td>
</tr>
<tr id="cb_row4">
<td id="cb_L4" class="cb-vert-label"><div>4</div></td>
<td id="cb_a4" class="cb-square cb-lt-bg"></td>
<td id="cb_b4" class="cb-square cb-dk-bg"></td>
<td id="cb_c4" class="cb-square cb-lt-bg"></td>
<td id="cb_d4" class="cb-square cb-dk-bg"></td>
<td id="cb_e4" class="cb-square cb-lt-bg"></td>
<td id="cb_f4" class="cb-square cb-dk-bg"></td>
<td id="cb_g4" class="cb-square cb-lt-bg"></td>
<td id="cb_h4" class="cb-square cb-dk-bg"></td>
<td id="cb_R4" class="cb-vert-label"><div>4</div></td>
</tr>
<tr id="cb_row3">
<td id="cb_L3" class="cb-vert-label"><div>3</div></td>
<td id="cb_a3" class="cb-square cb-dk-bg"></td>
<td id="cb_b3" class="cb-square cb-lt-bg"></td>
<td id="cb_c3" class="cb-square cb-dk-bg"></td>
<td id="cb_d3" class="cb-square cb-lt-bg"></td>
<td id="cb_e3" class="cb-square cb-dk-bg"></td>
<td id="cb_f3" class="cb-square cb-lt-bg"></td>
<td id="cb_g3" class="cb-square cb-dk-bg"></td>
<td id="cb_h3" class="cb-square cb-lt-bg"></td>
<td id="cb_R3" class="cb-vert-label"><div>3</div></td>
</tr>
<tr id="cb_row2">
<td id="cb_L2" class="cb-vert-label"><div>2</div></td>
<td id="cb_a2" class="cb-square cb-lt-bg"></td>
<td id="cb_b2" class="cb-square cb-dk-bg"></td>
<td id="cb_c2" class="cb-square cb-lt-bg"></td>
<td id="cb_d2" class="cb-square cb-dk-bg"></td>
<td id="cb_e2" class="cb-square cb-lt-bg"></td>
<td id="cb_f2" class="cb-square cb-dk-bg"></td>
<td id="cb_g2" class="cb-square cb-lt-bg"></td>
<td id="cb_h2" class="cb-square cb-dk-bg"></td>
<td id="cb_R2" class="cb-vert-label"><div>2</div></td>
</tr>
<tr id="cb_row1">
<td id="cb_L1" class="cb-vert-label"><div>1</div></td>
<td id="cb_a1" class="cb-square cb-dk-bg"></td>
<td id="cb_b1" class="cb-square cb-lt-bg"></td>
<td id="cb_c1" class="cb-square cb-dk-bg"></td>
<td id="cb_d1" class="cb-square cb-lt-bg"></td>
<td id="cb_e1" class="cb-square cb-dk-bg"></td>
<td id="cb_f1" class="cb-square cb-lt-bg"></td>
<td id="cb_g1" class="cb-square cb-dk-bg"></td>
<td id="cb_h1" class="cb-square cb-lt-bg"></td>
<td id="cb_R1" class="cb-vert-label"><div>1</div></td>
</tr>
<tr id="cb_row0">
<td id="cb_L0" class="cb-corner"></td>
<td id="cb_a0" class="cb-horiz-label"><div>A</div></td>
<td id="cb_b0" class="cb-horiz-label"><div>B</div></td>
<td id="cb_c0" class="cb-horiz-label"><div>C</div></td>
<td id="cb_d0" class="cb-horiz-label"><div>D</div></td>
<td id="cb_e0" class="cb-horiz-label"><div>E</div></td>
<td id="cb_f0" class="cb-horiz-label"><div>F</div></td>
<td id="cb_g0" class="cb-horiz-label"><div>G</div></td>
<td id="cb_h0" class="cb-horiz-label"><div>H</div></td>
<td id="cb_R0" class="cb-corner"></td>
</tr>
</table>
</div>
<div id="cb_status">
<div class="hbox">
<div id="cb_message"></div>
<div class="cb-hide-if-private"><a class="private-link" target="_blank" title="Open Private Copy"><span class="fas fa-copy"></span></a></div>
</div>
<div id="cb_explain_check"></div>
<div id="cb_scrollable">
<div id="cb_history">
<span id="cb_history_past"></span><span id="cb_history_future"></span>
<div id="content">
<div id="cb_outer2">
<div id="cb_outer">
<div id="cb_container">
<div id="cb_inner">
<table id="cb_board" class="noselect">
<tr id="cb_row9">
<td id="cb_L9" class="cb-corner"></td>
<td id="cb_a9" class="cb-horiz-label"><div>A</div></td>
<td id="cb_b9" class="cb-horiz-label"><div>B</div></td>
<td id="cb_c9" class="cb-horiz-label"><div>C</div></td>
<td id="cb_d9" class="cb-horiz-label"><div>D</div></td>
<td id="cb_e9" class="cb-horiz-label"><div>E</div></td>
<td id="cb_f9" class="cb-horiz-label"><div>F</div></td>
<td id="cb_g9" class="cb-horiz-label"><div>G</div></td>
<td id="cb_h9" class="cb-horiz-label"><div>H</div></td>
<td id="cb_R9" class="cb-corner"></td>
</tr>
<tr id="cb_row8">
<td id="cb_L8" class="cb-vert-label"><div>8</div></td>
<td id="cb_a8" class="cb-square cb-lt-bg"></td>
<td id="cb_b8" class="cb-square cb-dk-bg"></td>
<td id="cb_c8" class="cb-square cb-lt-bg"></td>
<td id="cb_d8" class="cb-square cb-dk-bg"></td>
<td id="cb_e8" class="cb-square cb-lt-bg"></td>
<td id="cb_f8" class="cb-square cb-dk-bg"></td>
<td id="cb_g8" class="cb-square cb-lt-bg"></td>
<td id="cb_h8" class="cb-square cb-dk-bg"></td>
<td id="cb_R8" class="cb-vert-label"><div>8</div></td>
</tr>
<tr id="cb_row7">
<td id="cb_L7" class="cb-vert-label"><div>7</div></td>
<td id="cb_a7" class="cb-square cb-dk-bg"></td>
<td id="cb_b7" class="cb-square cb-lt-bg"></td>
<td id="cb_c7" class="cb-square cb-dk-bg"></td>
<td id="cb_d7" class="cb-square cb-lt-bg"></td>
<td id="cb_e7" class="cb-square cb-dk-bg"></td>
<td id="cb_f7" class="cb-square cb-lt-bg"></td>
<td id="cb_g7" class="cb-square cb-dk-bg"></td>
<td id="cb_h7" class="cb-square cb-lt-bg"></td>
<td id="cb_R7" class="cb-vert-label"><div>7</div></td>
</tr>
<tr id="cb_row6">
<td id="cb_L6" class="cb-vert-label"><div>6</div></td>
<td id="cb_a6" class="cb-square cb-lt-bg"></td>
<td id="cb_b6" class="cb-square cb-dk-bg"></td>
<td id="cb_c6" class="cb-square cb-lt-bg"></td>
<td id="cb_d6" class="cb-square cb-dk-bg"></td>
<td id="cb_e6" class="cb-square cb-lt-bg"></td>
<td id="cb_f6" class="cb-square cb-dk-bg"></td>
<td id="cb_g6" class="cb-square cb-lt-bg"></td>
<td id="cb_h6" class="cb-square cb-dk-bg"></td>
<td id="cb_R6" class="cb-vert-label"><div>6</div></td>
</tr>
<tr id="cb_row5">
<td id="cb_L5" class="cb-vert-label"><div>5</div></td>
<td id="cb_a5" class="cb-square cb-dk-bg"></td>
<td id="cb_b5" class="cb-square cb-lt-bg"></td>
<td id="cb_c5" class="cb-square cb-dk-bg"></td>
<td id="cb_d5" class="cb-square cb-lt-bg"></td>
<td id="cb_e5" class="cb-square cb-dk-bg"></td>
<td id="cb_f5" class="cb-square cb-lt-bg"></td>
<td id="cb_g5" class="cb-square cb-dk-bg"></td>
<td id="cb_h5" class="cb-square cb-lt-bg"></td>
<td id="cb_R5" class="cb-vert-label"><div>5</div></td>
</tr>
<tr id="cb_row4">
<td id="cb_L4" class="cb-vert-label"><div>4</div></td>
<td id="cb_a4" class="cb-square cb-lt-bg"></td>
<td id="cb_b4" class="cb-square cb-dk-bg"></td>
<td id="cb_c4" class="cb-square cb-lt-bg"></td>
<td id="cb_d4" class="cb-square cb-dk-bg"></td>
<td id="cb_e4" class="cb-square cb-lt-bg"></td>
<td id="cb_f4" class="cb-square cb-dk-bg"></td>
<td id="cb_g4" class="cb-square cb-lt-bg"></td>
<td id="cb_h4" class="cb-square cb-dk-bg"></td>
<td id="cb_R4" class="cb-vert-label"><div>4</div></td>
</tr>
<tr id="cb_row3">
<td id="cb_L3" class="cb-vert-label"><div>3</div></td>
<td id="cb_a3" class="cb-square cb-dk-bg"></td>
<td id="cb_b3" class="cb-square cb-lt-bg"></td>
<td id="cb_c3" class="cb-square cb-dk-bg"></td>
<td id="cb_d3" class="cb-square cb-lt-bg"></td>
<td id="cb_e3" class="cb-square cb-dk-bg"></td>
<td id="cb_f3" class="cb-square cb-lt-bg"></td>
<td id="cb_g3" class="cb-square cb-dk-bg"></td>
<td id="cb_h3" class="cb-square cb-lt-bg"></td>
<td id="cb_R3" class="cb-vert-label"><div>3</div></td>
</tr>
<tr id="cb_row2">
<td id="cb_L2" class="cb-vert-label"><div>2</div></td>
<td id="cb_a2" class="cb-square cb-lt-bg"></td>
<td id="cb_b2" class="cb-square cb-dk-bg"></td>
<td id="cb_c2" class="cb-square cb-lt-bg"></td>
<td id="cb_d2" class="cb-square cb-dk-bg"></td>
<td id="cb_e2" class="cb-square cb-lt-bg"></td>
<td id="cb_f2" class="cb-square cb-dk-bg"></td>
<td id="cb_g2" class="cb-square cb-lt-bg"></td>
<td id="cb_h2" class="cb-square cb-dk-bg"></td>
<td id="cb_R2" class="cb-vert-label"><div>2</div></td>
</tr>
<tr id="cb_row1">
<td id="cb_L1" class="cb-vert-label"><div>1</div></td>
<td id="cb_a1" class="cb-square cb-dk-bg"></td>
<td id="cb_b1" class="cb-square cb-lt-bg"></td>
<td id="cb_c1" class="cb-square cb-dk-bg"></td>
<td id="cb_d1" class="cb-square cb-lt-bg"></td>
<td id="cb_e1" class="cb-square cb-dk-bg"></td>
<td id="cb_f1" class="cb-square cb-lt-bg"></td>
<td id="cb_g1" class="cb-square cb-dk-bg"></td>
<td id="cb_h1" class="cb-square cb-lt-bg"></td>
<td id="cb_R1" class="cb-vert-label"><div>1</div></td>
</tr>
<tr id="cb_row0">
<td id="cb_L0" class="cb-corner"></td>
<td id="cb_a0" class="cb-horiz-label"><div>A</div></td>
<td id="cb_b0" class="cb-horiz-label"><div>B</div></td>
<td id="cb_c0" class="cb-horiz-label"><div>C</div></td>
<td id="cb_d0" class="cb-horiz-label"><div>D</div></td>
<td id="cb_e0" class="cb-horiz-label"><div>E</div></td>
<td id="cb_f0" class="cb-horiz-label"><div>F</div></td>
<td id="cb_g0" class="cb-horiz-label"><div>G</div></td>
<td id="cb_h0" class="cb-horiz-label"><div>H</div></td>
<td id="cb_R0" class="cb-corner"></td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div id="cb_names" class="cb-hide-if-private">
<div id="cb_names_text">
<input id="cb_light_name" autocomplete="off" placeholder="Light">
<span class="cb-names-vs">vs.</span>
<input id="cb_dark_name" autocomplete="off" placeholder="Dark">
<div id="cb_control_container">
<form id="cb_control_form" autocomplete="off" onsubmit="return false;">
<div id="cb_controls">
<div class="cb-hbox">
<div class="cb-vbox cb-align-start">
<div><input id="cb_notify" type="checkbox"><label for="cb_notify">Notify</label></div>
<div><input id="cb_sound" type="checkbox"><label for="cb_sound">Sound</label></div>
<div><input id="cb_reverse" type="checkbox"><label for="cb_reverse">Reverse</label></div>
</div>
<div class="cb-spacer"></div>
<div class="cb-vbox cb-align-stretch">
<div class="cb-hbox">
<button id="cb_undo" type="button" disabled="true">Undo</button>
<button id="cb_redo" type="button" disabled="true">Redo</button>
<button id="cb_resign" type="button" disabled="true">Resign</button>
</div>
<div id="cb_navigate">
<button id="cb_nav_first" title="View First Turn" type="button" disabled="true">
<svg viewBox="0 0 144 144" class="media-button-svg silhouette">
<path d="M 6 24 H 24 V 120 H 6"/>
<path d="M 18 72 L 90 24 V 120"/>
<path d="M 66 72 L 138 24 V 120"/>
</svg>
</button>
<button id="cb_nav_prev_turn" title="View Prior Turn" type="button" disabled="true">
<svg viewBox="0 0 144 144" class="media-button-svg silhouette">
<path d="M 12 72 L 84 24 V 120"/>
<path d="M 60 72 L 132 24 V 120"/>
</svg>
</button>
<button id="cb_nav_prev_state" title="View Prior State" type="button" disabled="true">
<svg viewBox="0 0 144 144" class="media-button-svg silhouette">
<path d="M 36 72 L 108 24 V 120"/>
</svg>
</button>
<button id="cb_nav_next_state" title="View Next State" type="button" disabled="true">
<svg viewBox="0 0 144 144" class="media-button-svg silhouette">
<path d="M 108 72 L 36 24 V 120"/>
</svg>
</button>
<button id="cb_nav_next_turn" title="View Next Turn" type="button" disabled="true">
<svg viewBox="0 0 144 144" class="media-button-svg silhouette">
<path d="M 84 72 L 12 24 V 120"/>
<path d="M 132 72 L 60 24 V 120"/>
</svg>
</button>
<button id="cb_nav_last" title="View Current Move" type="button" disabled="true">
<svg viewBox="0 0 144 144" class="media-button-svg silhouette">
<path d="M 78 72 L 6 24 V 120"/>
<path d="M 126 72 L 54 24 V 120"/>
<path d="M 138 24 H 120 V 120 H 138"/>
</svg>
</button>
</div>
</div>
</div>
</div>
<div id="cb_theme">
<label for="cb_select_theme">Theme:</label>
<select id="cb_select_theme">
<option value="traditional">Traditional</option>
<option value="pacosako">Paco Ŝako</option>
</select>
<div class="cb-spacer"></div>
<button id="cb_choose_game">Choose Game…</button>
</div>
<div id="cb_names">
<label for="cb_light_name">Players:</label>
<input id="cb_light_name" placeholder="Light"> vs. <input id="cb_dark_name" placeholder="Dark">
</div>
</form>
<div id="cb_message"></div>
<div id="cb_scrollable">
<div id="cb_history">
<span id="cb_history_past"></span><span id="cb_history_future"></span>
<div id="cb_explain_check"></div>
</div>
<details>
<summary>Rule Reference</summary>
<p>The basic movement for each piece is the same as traditional chess.</p>
<p>Pieces are never removed from the board. Instead, the capturing piece shares the square with the captured piece, and the two pieces become a joined pair.</p>
<p>When either piece moves from a square containing two pieces, the other piece moves with it.
Each player can only move a joined pair according to the rules for their own piece. Joined pieces cannot capture other pieces.</p>
<p>A free (non-joined) piece may move into a square occupied by pieces of both colors.
When it does, the other piece of the same color becomes a free piece and must move to a new location following the normal movement rules.
This process may be repeated multiple times in the same turn.</p>
<p>Ŝako (checkmate) occurs when an opposing piece joins with the king.
<strong>Important:</strong> The king is not permitted to join with (capture) other pieces.</p>
<p>Due to joined movement, it is possible for a pawn to be moved backward to, or past, its starting row.
Pawns may move forward two spaces from either of the first two rows on their own side of the board.</p>
<p>When a pawn is captured <i>en passant</i> while joined with another piece, the captured pawn moves back one square to become joined with the capturing pawn
and the joined piece from the capturing side moves to a new location from its original position as with any other capture.</p>
<p>Pawns are promoted when they reach the final row on the opposite side of the board, even if they were moved there by the other player as part of a joined pair.</p>
</details>
</div>
</div>
<div id="cb_times" class="cb-hide-if-private">
<div id="cb_light_time">0:00:00</div>
<div id="cb_dark_time">0:00:00</div>
</div>
<div id="cb_navigate">
<button id="cb_undo" title="Undo" type="button" disabled="true"><span class="fas fa-undo"></span></button>
<button id="cb_redo" title="Redo" type="button" disabled="true"><span class="fas fa-redo"></span></button>
<div class="nav-spacer"></div>
<button id="cb_resign" title="Resign" type="button" disabled="true"><span class="fas fa-flag"></span></button>
<div class="nav-spacer"></div>
<button id="cb_nav_first" title="View First Turn" type="button" disabled="true"><span class="fas fa-fast-backward"></span></button>
<button id="cb_nav_prev_turn" title="View Prior Turn" type="button" disabled="true"><span class="fas fa-backward"></span></button>
<button id="cb_nav_prev_state" title="View Prior Move" type="button" disabled="true"><span class="fas fa-play fa-flip-horizontal"></span></button>
<button id="cb_nav_next_state" title="View Next Move" type="button" disabled="true"><span class="fas fa-play"></span></button>
<button id="cb_nav_next_turn" title="View Next Turn" type="button" disabled="true"><span class="fas fa-forward"></span></button>
<button id="cb_nav_last" title="View Current Move" type="button" disabled="true"><span class="fas fa-fast-forward"></span></button>
</div>
</div> <!-- board_ui -->
</div>
<div id="rules_content" style="display: none">
<div id="rules" class="rules">
<p>The basic movement for each piece is the same as traditional chess.</p>
<p>Pieces are never removed from the board. Instead, the capturing piece shares the square with the captured piece, and the two pieces become a joined pair.</p>
<p>When either piece moves from a square containing two pieces, the other piece moves with it.
Each player can only move a joined pair according to the rules for their own piece. Joined pieces cannot capture other pieces.</p>
<p>A free (non-joined) piece may move into a square occupied by pieces of both colors.
When it does, the other piece of the same color becomes a free piece and must move to a new location following the normal movement rules.
This process may be repeated multiple times in the same turn.</p>
<p>Ŝako (checkmate) occurs when an opposing piece joins with the king.
<strong>Important:</strong> The king is not permitted to join with (capture) other pieces.</p>
<p>Due to joined movement, it is possible for a pawn to be moved backward to, or past, its starting row.
Pawns may move forward two spaces from either of the first two rows on their own side of the board.</p>
<p>When a pawn is captured <i>en passant</i> while joined with another piece, the captured pawn moves back one square to become joined with the capturing pawn
and the joined piece from the capturing side moves to a new location from its original position as with any other capture.</p>
<p>Pawns are promoted when they reach the final row on the opposite side of the board, even if they were moved there by the other player as part of a joined pair.</p>
</div>
<div class="badges">
<!-- "external-link-alt" by Font Awesome (fontawesome.com/icons/external-link-alt?style=solid) / CC BY 4.0 (creativecommons.org/licenses/by/4.0) -->
<div class="badge game-link-badge"><a id="game_link" href="#" rel="noopener noreferer" target="_blank"><img src="<%=require('./svg/external-link-alt-solid.svg')%>" alt="This Game" title="Link to This Game"></a></div>
<div class="badge official-badge"><a href="https://pacosako.com/" rel="noopener noreferer" target="_blank"><img src="<%=require('./svg/pacosako-logo.svg')%>" alt="Official Site" title="Official Site"></a></div>
<div class="badge jitsi-badge"><a id="jitsi_link" href="https://meet.jit.si/PacoSako" rel="noopener noreferer" target="_blank"><img src="<%=require('./svg/jitsi-logo-blue.svg')%>" alt="Jitsi Meet" title="Jitsi Meet"></a></div>
<div class="badge gogs-badge"><a href="https://jessemcdonald.info/gogs/nybble/paco_sako" rel="noopener noreferer" target="_blank"><img src="<%=require('./png/gogs.png')%>" alt="Source Code" title="Source Code"></a></div>
</div>
</div>
<div id="settings_content" style="display: none">
<div id="settings">
<div><input id="cb_sound" type="checkbox"><label for="cb_sound">Sound</label></div>
<div id="cb_theme">
<label for="cb_select_theme">Theme:</label>
<select id="cb_select_theme">
<option value="pacosako">Paco Ŝako</option>
<option value="traditional">Traditional</option>
</select>
<div id="cb_hidden" style="display: none">
<div id="cb_phantom" class="cb-phantom"></div>
<div id="cb_pieces" style="display: none">
<div id="cb_piece_kd" class="cb-piece cb-dk-piece cb-king" ><img src="<%=require('./svg/traditional-theme.svg')%>#dark_king_right" alt="kd"></div>
<div id="cb_piece_qd" class="cb-piece cb-dk-piece cb-queen" ><img src="<%=require('./svg/traditional-theme.svg')%>#dark_queen_right" alt="qd"></div>
<div id="cb_piece_bd" class="cb-piece cb-dk-piece cb-bishop" ><img src="<%=require('./svg/traditional-theme.svg')%>#dark_bishop_right" alt="bd"></div>
<div id="cb_piece_nd" class="cb-piece cb-dk-piece cb-knight" ><img src="<%=require('./svg/traditional-theme.svg')%>#dark_knight_right" alt="nd"></div>
<div id="cb_piece_rd" class="cb-piece cb-dk-piece cb-rook" ><img src="<%=require('./svg/traditional-theme.svg')%>#dark_rook_right" alt="rd"></div>
<div id="cb_piece_pd" class="cb-piece cb-dk-piece cb-pawn" ><img src="<%=require('./svg/traditional-theme.svg')%>#dark_pawn_right" alt="pd"></div>
<div id="cb_piece_kl" class="cb-piece cb-lt-piece cb-king" ><img src="<%=require('./svg/traditional-theme.svg')%>#light_king_left" alt="kl"></div>
<div id="cb_piece_ql" class="cb-piece cb-lt-piece cb-queen" ><img src="<%=require('./svg/traditional-theme.svg')%>#light_queen_left" alt="ql"></div>
<div id="cb_piece_bl" class="cb-piece cb-lt-piece cb-bishop" ><img src="<%=require('./svg/traditional-theme.svg')%>#light_bishop_left" alt="bl"></div>
<div id="cb_piece_nl" class="cb-piece cb-lt-piece cb-knight" ><img src="<%=require('./svg/traditional-theme.svg')%>#light_knight_left" alt="nl"></div>
<div id="cb_piece_rl" class="cb-piece cb-lt-piece cb-rook" ><img src="<%=require('./svg/traditional-theme.svg')%>#light_rook_left" alt="rl"></div>
<div id="cb_piece_pl" class="cb-piece cb-lt-piece cb-pawn" ><img src="<%=require('./svg/traditional-theme.svg')%>#light_pawn_left" alt="pl"></div>
</div>
</div>
</div>

View File

@ -1,8 +1,4 @@
import './css/chess.css';
import './css/theme/pacosako.css';
import './css/theme/traditional.css';
import '@fortawesome/fontawesome-free/css/fontawesome.css';
import '@fortawesome/fontawesome-free/css/solid.css';
import './js/pacosako_ui.js';

View File

@ -90,9 +90,6 @@ export class Iterator {
}
flatMap(f) {
if (typeof f === 'undefined') {
f = identity;
}
const next = this.next;
let innerNext;
@ -111,8 +108,7 @@ export class Iterator {
return z;
}
const mapped = f(z.value);
const iter = mapped.__proto__[Symbol.iterator].call(mapped);
const iter = y.value.__proto__[Symbol.iterator].call(y.value);
innerNext = iter.next.bind(iter);
}
});
@ -198,6 +194,6 @@ export class Iterator {
strictlyIncludes(x) {
return this.some(function matches(y) { return y === x; });
}
}
};
export default Iterator;

View File

@ -1,7 +1,6 @@
'use strict';
import {Iterator} from './iterator.js';
import {Buffer} from 'buffer';
/* Game states */
const PLAYING = 'playing';
@ -32,39 +31,26 @@ const INITIAL_EDGE_ROW = ROOK + KNIGHT + BISHOP + QUEEN + KING + BISHOP + KNIGHT
const ROWS = '12345678';
const COLUMNS = 'abcdefgh';
/*
* Rule Version
*
* Increment this whenever a change in the rules would make some previously
* illegal moves illegal. The implementation in the Game class needs to check
* this._version and apply the appropriate rules based on which rules were in
* effect when the game was started.
*
* Version 1: Initial version. (Default if version field is missing.)
* Version 2: Prohibit moving through check.
*/
const CURRENT_VERSION = 2;
function otherSide(side) {
if (side === LIGHT) {
return DARK;
} else if (side === DARK) {
return LIGHT;
} else {
throw new Error(`invalid side: ${side}`);
throw { message: 'invalid side', side: side };
}
}
function squareIndex(square) {
if (typeof square !== 'string' || square.length !== 2) {
throw new Error(`invalid square: ${square}`);
throw { message: 'invalid square', square: square };
}
const column = COLUMNS.indexOf(square[0].toLowerCase());
const row = ROWS.indexOf(square[1]);
if (column < 0 || row < 0) {
throw new Error(`invalid square: ${square}`);
throw { message: 'invalid square', square: square };
}
return (row * 8) + column;
@ -86,7 +72,7 @@ function encodePiece(side, type) {
let result = ALL_PIECES.indexOf(type);
if (result < 0) {
throw new Error(`invalid piece: ${type}`);
throw { message: 'invalid piece', piece: type };
}
if (side === LIGHT) {
@ -94,7 +80,7 @@ function encodePiece(side, type) {
} else if (side === DARK) {
return result;
} else {
throw new Error(`invalid side: ${side}`);
throw { message: 'invalid side', side: side };
}
}
@ -106,7 +92,7 @@ function decodePiece(side, value) {
} else if (side === DARK) {
sideShift = 0;
} else {
throw new Error(`invalid side: ${side}`);
throw { message: 'invalid side', side: side };
}
let pieceValue = (value >>> sideShift) & 0b1111;
@ -114,7 +100,7 @@ function decodePiece(side, value) {
if (pieceValue < ALL_PIECES.length) {
return ALL_PIECES[pieceValue];
} else {
throw new Error(`invalid encoded piece: ${pieceValue}`);
throw { message: 'invalid encoded piece', value: pieceValue };
}
}
@ -122,7 +108,7 @@ class Board {
constructor(original) {
if (original !== null && original !== undefined) {
if (!(original instanceof this.constructor)) {
throw new TypeError(`can only clone from another Board instance`);
throw { message: 'can only clone from another Board instance' };
}
this._board = new Uint8Array(original._board);
@ -189,7 +175,7 @@ class Board {
if (type !== EMPTY) {
if (this._phantom) {
throw new Error(`phantom square is already occupied`);
throw { message: 'phantom square is already occupied' };
}
this.putPiece(side, square, EMPTY);
@ -204,17 +190,17 @@ class Board {
move(from, to) {
if (this._phantom && from !== PHANTOM) {
throw new Error(`must complete prior move before moving other pieces`);
throw { message: 'must complete prior move before moving other pieces' };
}
let lightPiece = this.getPiece(LIGHT, from);
let darkPiece = this.getPiece(DARK, from);
if (lightPiece === EMPTY && darkPiece === EMPTY) {
throw new Error(`cannot move from empty square: ${from}${to}`);
throw { message: 'cannot move from empty square' };
} else if (lightPiece !== EMPTY && darkPiece !== EMPTY) {
if (!this.isEmpty(to)) {
throw new Error(`cannot capture with joined pieces`);
throw { message: 'cannot capture with joined pieces' };
}
const fromIndex = squareIndex(from);
@ -228,7 +214,7 @@ class Board {
const displaced = this.getPiece(moving, to);
if (displaced !== EMPTY && this.getPiece(other, to) === EMPTY) {
throw new Error(`cannot join with piece of same color`);
throw { message: 'cannot join with piece of same color' };
}
if (from === PHANTOM) {
@ -272,7 +258,7 @@ class Board {
function testFunction(getPiece, match) {
if (match === undefined) {
return function(/*here*/) { return true; };
return function(here) { return true; }
} else if (match === false) {
return function(here) { return getPiece(here) === EMPTY; };
} else if (match === true) {
@ -287,7 +273,7 @@ class Board {
const test = function(here) { return testSide(here) && testOther(here); };
if (this._phantom && this._phantom.side === side) {
const getPhantom = (/*here*/) => this._phantom.type;
const getPhantom = (here) => this._phantom.type;
const testPhantom = testFunction(getPhantom, type);
if (testPhantom(PHANTOM)) {
yield this._phantom.from;
@ -316,8 +302,8 @@ const KNIGHT_DIR =
[-1, -2], [ 1, -2]];
const NBSP = '\u00a0'; /* non-breaking space */
const SHY = '\u00ad'; /* soft hyphen */
/* const ZWSP = '\u200b'; */ /* zero-width space */
const SHY = '\u00ad' /* soft hyphen */
const ZWSP = '\u200b'; /* zero-width space */
function addHistory(game) {
const prior = game._undo;
@ -476,38 +462,9 @@ function diffHistory(game1, game2) {
class Game {
constructor(original) {
if (typeof original === 'string') {
const moves = JSON.parse(original);
original = new Game();
if ('version' in moves === false) {
original._version = 1;
} else if (!Number.isInteger(moves.version) ||
moves.version < 1 || moves.version > CURRENT_VERSION) {
throw new Error('invalid version');
} else {
original._version = moves.version;
}
for (const move of moves.past) {
original.replayMove(move);
}
let n = 0;
for (const move of moves.future.slice().reverse()) {
original.replayMove(move);
n += 1;
}
for (let i = 0; i < n; ++i) {
original.undo();
}
}
if (original !== undefined) {
if (!(original instanceof this.constructor)) {
throw new TypeError(`can only clone from another Game instance`);
throw { message: 'can only clone from another Game instance' };
}
Object.assign(this, original, {
@ -531,7 +488,6 @@ class Game {
this._undo = null;
this._checkCache = {};
this._ignoreCheck = false;
this._version = CURRENT_VERSION;
/* set to false when the king or rook moves */
this._castling = {
@ -569,41 +525,6 @@ class Game {
this._ignoreCheck = !!value;
}
get version() {
return this._version;
}
toJSON(style) {
function shrinkMove(move) {
if (move.resign) {
return { side: move.side, resign: true };
} else if (move.phantom) {
return { side: move.side, phantom: true, to: move.to };
} else {
return { side: move.side, from: move.from, to: move.to };
}
}
if (style === 'minify') {
/* Just the fields that are used by the constructor to replay the game */
/* Omits metadata and extra annotation fields */
const state = { past: [], future: [], version: this._version };
for (const move of this._moves) {
state.past.push(shrinkMove(move));
}
for (const move of this._redo) {
state.future.push(shrinkMove(move));
}
return JSON.stringify(state);
}
return JSON.stringify({
past: this._moves,
future: this._redo,
version: this._version,
});
}
canCapture(side, from) {
if (from === PHANTOM) {
return true;
@ -647,18 +568,7 @@ class Game {
board.isEmpty('f' + row) &&
board.isEmpty('g' + row)) {
if (!this.isInCheck(side)) {
if (this._version < 2) {
yield 'g' + row;
} else {
/* Prohibit castling through check */
const testGame = new Game(this);
testGame._board.putPiece(side, 'e' + row, EMPTY);
testGame._board.putPiece(side, 'f' + row, KING);
testGame._checkCache = {};
if (!testGame.isInCheck(side)) {
yield 'g' + row;
}
}
yield 'g' + row;
}
}
@ -667,18 +577,7 @@ class Game {
board.isEmpty('c' + row) &&
board.isEmpty('b' + row)) {
if (!this.isInCheck(side)) {
if (this._version < 2) {
yield 'c' + row;
} else {
/* Prohibit castling through check */
const testGame = new Game(this);
testGame._board.putPiece(side, 'e' + row, EMPTY);
testGame._board.putPiece(side, 'd' + row, KING);
testGame._checkCache = {};
if (!testGame.isInCheck(side)) {
yield 'c' + row;
}
}
yield 'c' + row;
}
}
}
@ -772,6 +671,8 @@ class Game {
/* if a piece has few moves (king, pawn, knight) then just enumerate them */
/* if movement is more extensive (bishop, rook, queen) then we can do better */
if (type === BISHOP || type === ROOK || type === QUEEN) {
const ortho = (type === ROOK || type === QUEEN);
const diag = (type === BISHOP || type === QUEEN);
const fromIndex = squareIndex(fromSquare);
const toIndex = squareIndex(to);
const rowsDiff = (toIndex >>> 3) - (fromIndex >>> 3);
@ -831,7 +732,7 @@ class Game {
const kings = [...this._board.findPieces(side, KING)];
if (kings.length !== 1) {
throw new Error(`there should be exactly one king per side`);
throw { message: 'there should be exactly one king per side' };
}
const king = kings[0];
@ -855,7 +756,7 @@ class Game {
try {
sim.move(from, king);
check = diffHistory(this, sim) || true;
} catch(err) {/*ignore*/}
} catch(err) {}
}
return recordCheck(this, check);
}
@ -911,7 +812,7 @@ class Game {
try {
game2.move(PHANTOM, king);
check = diffHistory(this, game2) || true;
} catch(err) {/*ignore*/}
} catch(err) {}
}
return recordCheck(this, check);
}
@ -993,7 +894,7 @@ class Game {
move(from, to, meta) {
if (this._status !== PLAYING) {
throw new Error(`can't move, game is already over`);
throw { message: "can't move, game is already over" };
}
const side = this._player;
@ -1005,13 +906,13 @@ class Game {
const alongside = board.getPiece(other, from);
if (from === PHANTOM && !board.phantom) {
throw new Error(`attempted to continue a completed move`);
throw { message: "attempted to continue a completed move" };
}
const fromSquare = (from === PHANTOM) ? board.phantom.from : from;
if (!this.isLegalMove(side, from, to, alongside === EMPTY)) {
throw new Error(`illegal move by ${side} side: ${fromSquare}${to}`);
throw { message: "illegal move", side: side, from: fromSquare, to: to };
}
const move = {
@ -1152,7 +1053,7 @@ class Game {
resign(meta) {
if (this._status !== PLAYING) {
throw new Error(`can't resign, game is already over`);
throw { message: "can't resign, game is already over" };
}
const move = {
@ -1200,8 +1101,8 @@ class Game {
}
replayMove(move) {
if (otherSide(move.side) === this._player) {
throw new Error(`other player's move`);
if (!move || move.side !== this._player) {
throw { message: "other player's move", move: move };
}
if (move.resign) {
@ -1263,7 +1164,6 @@ class Game {
renderHistory() {
if (this._history === undefined) {
const replay = new Game();
replay._version = this._version;
for (const move of this._moves) {
replay.replayMove(move);
}
@ -1290,9 +1190,6 @@ export default {
/* Coordinates */
ROWS, COLUMNS, PHANTOM,
/* Versioning */
CURRENT_VERSION,
/* Miscellaneous */
Util: { otherSide, offsetSquare, diffHistory },
};

View File

@ -23,7 +23,7 @@ const meta = {
};
const stateListeners = {};
let stateNextId = 1;
const stateNextId = 1;
/* One-time request, no caching or polling */
function getGameState(gameId, retries) {
@ -37,7 +37,7 @@ function getGameState(gameId, retries) {
url: `${API_BASE}/game/${gameId}`,
cache: false,
timeout: SHORT_TIMEOUT,
}).done((data/*, textStatus, jqXHR*/) => {
}).done((data, textStatus, jqXHR) => {
resolve(data);
}).fail((jqXHR, textStatus, errorThrown) => {
if ((!jqXHR.status || jqXHR.status < 400 || jqXHR.status > 499) && retries > 0) {
@ -63,7 +63,7 @@ function getGameMeta(gameId, retries) {
url: `${API_BASE}/meta/${gameId}`,
cache: false,
timeout: SHORT_TIMEOUT,
}).done((data/*, textStatus, jqXHR*/) => {
}).done((data, textStatus, jqXHR) => {
resolve(data);
}).fail((jqXHR, textStatus, errorThrown) => {
if ((!jqXHR.status || jqXHR.status < 400 || jqXHR.status > 499) && retries > 0) {
@ -106,7 +106,7 @@ function onGameUpdate(gameId, callback) {
stopGamePoll(gameId);
}
}
};
}
}
function getCachedGame(gameId) {
@ -150,7 +150,7 @@ function onMetaUpdate(callback) {
stopMetaPoll();
}
}
};
}
}
function sendUpdate(gameId, data, retries) {
@ -306,7 +306,7 @@ function startGamePoll(gameId, afterTime) {
setConnectionState(game, 'polling');
startGamePoll(gameId, afterTime);
}
}).fail((/*jqXHR, textStatus, errorThrown*/) => {
}).fail((jqXHR, textStatus, errorThrown) => {
if (game.currentRequest === thisRequest) {
setConnectionState(game, 'failed');
setTimeout(() => {
@ -370,9 +370,9 @@ function startMetaPoll(afterTime) {
const thisRequest = meta.currentRequest = $.ajax({
dataType: 'json',
contentType: 'application/json',
url: `${API_BASE}/games${(afterTime === undefined) ? '' : `/poll/${afterTime}`}`,
url: `${API_BASE}/games${!afterTime ? '' : `/poll/${afterTime}`}`,
cache: false,
timeout: (afterTime === undefined) ? SHORT_TIMEOUT : LONG_TIMEOUT,
timeout: afterTime ? LONG_TIMEOUT : SHORT_TIMEOUT,
}).done((data, textStatus, jqXHR) => {
if (meta.currentRequest === thisRequest) {
meta.currentRequest = null;
@ -383,7 +383,7 @@ function startMetaPoll(afterTime) {
setConnectionState('polling');
startMetaPoll(afterTime);
}
}).fail((/*jqXHR, textStatus, errorThrown*/) => {
}).fail((jqXHR, textStatus, errorThrown) => {
if (meta.currentRequest === thisRequest) {
setConnectionState('failed');
setTimeout(() => {

File diff suppressed because it is too large Load Diff

Binary file not shown.

23083
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "paco-sako",
"version": "0.8.7",
"version": "0.4.8",
"description": "Online version of the Paco Ŝako chess variation",
"keywords": [
"game",
@ -31,35 +31,28 @@
"url": "https://jessemcdonald.info/gogs/nybble/paco_sako.git"
},
"devDependencies": {
"@fortawesome/fontawesome-free": "^5.13.0",
"buffer": "^6.0.3",
"clean-webpack-plugin": "^4.0.0",
"copy-webpack-plugin": "^6.4.1",
"css-element-queries": "^1.2.3",
"clean-webpack-plugin": "^3.0.0",
"copy-webpack-plugin": "^5.1.1",
"deep-equal": "git+https://jessemcdonald.info/gogs/nybble/node-deep-equal",
"extract-loader": "^5.0.1",
"html-webpack-plugin": "^4.5.2",
"html-webpack-plugin": "^4.3.0",
"jbox": "^1.2.0",
"jquery-ui-touch-punch": "^0.2.3",
"lodash": "^4.17.15",
"mini-css-extract-plugin": "^1.6.2",
"optimize-css-assets-webpack-plugin": "^6.0.1",
"pako": "^2.0.4",
"sprintf-js": "^1.0.3",
"svgo": "^2.7.0",
"svgo-loader": "^3.0.0",
"webpack": "^4.46.0",
"webpack-cli": "^4.8.0",
"mini-css-extract-plugin": "^0.9.0",
"optimize-css-assets-webpack-plugin": "^5.0.3",
"svgo": "^1.3.2",
"svgo-loader": "^2.2.1",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11",
"webpack-jquery-ui": "^2.0.1",
"workbox-precaching": "^6.3.0",
"workbox-routing": "^6.3.0",
"workbox-strategies": "^6.3.0",
"workbox-webpack-plugin": "^6.3.0",
"workbox-window": "^6.3.0"
},
"dependencies": {
"paco-sako-server": "git+https://jessemcdonald.info/gogs/nybble/paco_sako_server"
"workbox-precaching": "^5.1.3",
"workbox-routing": "^5.1.3",
"workbox-strategies": "^5.1.3",
"workbox-webpack-plugin": "^5.1.3",
"workbox-window": "^5.1.3"
},
"dependencies": {},
"optionalDependencies": {
"paco-sako-server": "git+https://jessemcdonald.info/gogs/nybble/paco_sako_server"
},

View File

@ -0,0 +1 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="external-link-alt" class="svg-inline--fa fa-external-link-alt fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"></path></svg>

After

Width:  |  Height:  |  Size: 597 B

160
svg/jitsi-logo-blue.svg Normal file
View File

@ -0,0 +1,160 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="160"
height="160"
viewBox="0 0 150 150.00001"
id="svg3526"
version="1.1"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
inkscape:export-filename="/Users/ystamcheva/Dropbox/Designs/appLogo.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
sodipodi:docname="jitsi-logo-blue.svg">
<defs
id="defs3528">
<filter
style="color-interpolation-filters:sRGB;"
inkscape:label="Blur"
id="filter921">
<feGaussianBlur
stdDeviation="4 4"
result="blur"
id="feGaussianBlur919" />
</filter>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="4"
inkscape:cx="89.185304"
inkscape:cy="80.953412"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="999"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
units="px"
inkscape:snap-bbox="true"
inkscape:snap-page="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:pagecheckerboard="true" />
<metadata
id="metadata3531">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-902.36211)"
style="opacity:1">
<path
style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.91489375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal;filter:url(#filter921)"
d="M 142.5,977.36212 A 67.499998,67.499998 0 0 1 74.999998,1044.8621 67.499998,67.499998 0 0 1 7.5,977.36212 a 67.499998,67.499998 0 0 1 67.499998,-67.5 67.499998,67.499998 0 0 1 67.500002,67.5 z"
id="path1006-7"
inkscape:connector-curvature="0"
transform="matrix(0.97916666,0,0,0.97916666,1.562503,20.361715)" />
<path
style="opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.87500012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
d="M 141.09375,977.36212 A 66.09375,66.09375 0 0 1 75.000003,1043.4558 66.09375,66.09375 0 0 1 8.9062529,977.36212 66.09375,66.09375 0 0 1 75.000003,911.26837 66.09375,66.09375 0 0 1 141.09375,977.36212 Z"
id="path1006"
inkscape:connector-curvature="0" />
<g
id="g1247"
transform="matrix(0.93034217,0,0,0.93034217,4.9699418,67.566622)"
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333">
<path
inkscape:connector-curvature="0"
id="path3618"
d=""
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333" />
<path
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333"
inkscape:connector-curvature="0"
id="path35"
d="m 66.150479,984.58608 c 3.546945,0 11.036812,-2.11769 15.990996,-3.51965 0.720489,-0.20282 1.392044,-0.39263 2.002303,-0.56287 0.09877,-0.0272 0.194448,-0.0519 0.284976,-0.0746 -0.27828,-0.27544 -0.741093,-0.6937 -1.495321,-1.32572 -3.300213,-2.23667 -6.416409,-3.27807 -9.805606,-3.27807 -0.73929,0 -1.507554,0.0453 -2.344712,0.14011 -2.869465,0.32644 -5.26015,1.01023 -6.408683,1.33796 -0.582186,0.16689 -0.757576,0.21672 -0.939018,0.21672 -0.346144,0 -0.643483,-0.20591 -0.759765,-0.52398 -0.116412,-0.31974 -0.01674,-0.67258 0.253555,-0.89897 l 0.01635,-0.0131 c 1.980412,-1.65899 5.670166,-4.74737 12.67005,-6.12731 1.214078,-0.23862 2.512891,-0.36006 3.859091,-0.36006 3.133581,0 6.378164,0.64722 9.641162,1.92195 4.444111,1.7351 7.480982,3.9625 9.923563,5.75233 1.31491,0.96438 2.45057,1.79755 3.43891,2.2556 0.25252,0.11744 0.38361,0.15053 0.44465,0.15916 0.0449,-0.0582 0.14243,-0.21891 0.28575,-0.64052 0.0384,-0.11165 0.31588,-1.29018 -1.67496,-7.99311 -1.15703,-3.89116 -2.552556,-7.86512 -3.279226,-9.62945 -1.405694,-3.41366 -1.060709,-5.83293 -0.62803,-7.2479 -1.190899,0.4377 -2.408198,1.11879 -3.688853,2.05948 l -0.07984,0.059 c -0.639877,0.4744 -1.29173,1.01126 -1.993675,1.63864 -4.13029,3.69813 -7.224723,5.62613 -9.201529,5.73095 l -0.05447,0.003 -0.05421,-0.005 c -1.741536,-0.14783 -4.380754,-2.68287 -5.460393,-3.96636 -0.224453,-0.15054 -0.480197,-0.21879 -0.817713,-0.21879 -0.338933,0 -0.718944,0.0712 -1.086593,0.14101 -0.267463,0.0507 -0.543168,0.10237 -0.816555,0.13006 -0.871412,0.0874 -2.092831,0.36919 -3.271626,0.64052 -0.568278,0.13058 -1.154714,0.26566 -1.690799,0.37628 -0.01017,0.002 -0.240292,0.0492 -0.651595,0.15762 -2.913377,0.86188 -5.108841,1.85073 -6.182685,2.78512 -0.01172,0.0102 -0.04636,0.0371 -0.101603,0.0777 -0.726284,0.51625 -2.472327,1.98916 -2.99914,4.4951 l -0.0055,0.0209 c -1.099856,4.61487 0.567635,10.33796 2.783445,13.60701 1.042166,1.53653 2.165202,2.49512 3.083359,2.62956 0.228573,0.0324 0.502861,0.0497 0.813978,0.0497 z" />
<path
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333"
inkscape:connector-curvature="0"
id="path39"
d="m 82.429799,960.11108 c 0.0707,0.0139 0.15337,0.0209 0.24467,0.0209 1.90392,0 6.155901,-2.75679 6.942451,-4.01838 l 0.06258,-0.10045 0.08937,-0.0787 c 0.268236,-0.26476 1.042938,-1.65925 1.418958,-2.49396 -4.032164,-1.2097 -4.477077,-3.3928 -4.870352,-5.33252 -0.04572,-0.22523 -0.08589,-0.42804 -0.12182,-0.60936 -0.04597,-0.2372 -0.09413,-0.47813 -0.13547,-0.66434 -6.00678,1.99226 -7.842965,3.1104 -8.845083,3.94189 -0.518572,0.43075 -0.823894,1.65577 0.671555,5.04652 0.763886,1.7284 3.397825,4.06809 4.543138,4.28842 z" />
<path
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333"
inkscape:connector-curvature="0"
id="path43"
d="m 51.013383,1000.8062 c -0.746759,-0.88008 -1.063414,-1.98921 -0.939147,-3.29974 0.528616,-6.36104 -0.19638,-7.8977 -0.532093,-8.26238 -0.081,-0.0882 -0.124782,-0.0882 -0.159422,-0.0882 -0.01301,0 -0.02511,7.7e-4 -0.03812,0.002 -0.623265,0.14899 -4.821418,2.98729 -5.748203,11.46142 -0.446973,4.0896 0.336228,9.3415 1.003663,12.5359 0.536342,-1.886 1.383287,-3.9635 3.023994,-6.1018 1.527514,-1.9888 3.193718,-3.5571 5.260665,-4.9318 -0.642581,-0.2672 -1.332293,-0.6791 -1.87134,-1.3155 z" />
<path
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333"
inkscape:connector-curvature="0"
id="path47"
d="m 95.474451,928.32276 c -0.501702,3.30962 -1.318514,6.4535 -2.842938,9.77174 1.661697,-1.88125 2.63278,-3.92515 2.958062,-6.21925 0.135341,-0.95035 0.263342,-1.85937 -0.115124,-3.55249 z" />
<path
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333"
inkscape:connector-curvature="0"
id="path51"
d="m 86.212271,943.73132 c 2.97918,-2.69331 4.792959,-7.14115 5.547315,-9.78307 -2.594662,2.49911 -5.747945,3.84003 -7.771624,4.70178 -0.696924,0.29721 -1.29804,0.55309 -1.658349,0.76312 -0.151695,0.0882 -0.304807,0.17693 -0.459851,0.26643 -1.2276,0.71019 -3.080783,1.78352 -3.35095,2.44503 l -0.0077,0.0215 -0.01004,0.0213 c -0.840764,1.76678 -1.314522,4.42364 -1.466347,5.94729 1.948991,-1.19013 3.958248,-1.98441 5.627284,-2.6436 1.549149,-0.61206 2.888653,-1.14132 3.550293,-1.73973 z" />
<path
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333"
inkscape:connector-curvature="0"
id="path55"
d="m 89.217464,946.05955 c -0.01816,0.046 -0.0376,0.0895 -0.05859,0.13096 -0.49359,1.43492 0.186206,3.38675 1.445743,4.12295 0.335069,0.19599 0.660866,0.31575 0.9734,0.35696 0.04301,0.002 0.08576,0.003 0.128903,0.003 0.978809,0 1.777206,-0.71599 2.369437,-2.12722 0.372929,-1.07397 0.425983,-2.34754 0.14487,-3.49724 -0.2184,-0.89317 -0.783459,-1.95929 -1.143511,-2.49087 -0.67207,0.46127 -2.000242,1.47601 -2.912218,2.28136 -0.636915,0.61515 -0.867034,1.0025 -0.948032,1.21962 z" />
<path
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333"
inkscape:connector-curvature="0"
id="path59"
d="m 97.64004,982.53162 c 1.082085,-0.29489 1.941393,-0.53634 2.57522,-0.72409 -1.305382,-0.90928 -2.816414,-2.04055 -4.870613,-3.63825 -5.034538,-3.91524 -10.43312,-5.90119 -16.043535,-5.90119 -3.07267,0 -5.749361,0.59133 -7.867818,1.30719 0.528101,-0.0328 1.065087,-0.0485 1.616625,-0.0485 0.655201,0 1.341823,0.0231 2.040034,0.0697 2.182586,0.14628 7.80575,1.139 12.891025,7.20244 1.024524,1.21936 2.125668,2.22869 5.257575,2.22869 1.117627,0 2.420431,-0.12453 3.980783,-0.38104 0.09645,-0.0269 0.242352,-0.0667 0.420704,-0.11487 z" />
<path
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333"
inkscape:connector-curvature="0"
id="path63"
d="m 104.77707,956.11317 c -0.99864,-1.55082 -2.25329,-2.51418 -3.27214,-2.51418 -0.18853,0 -0.36855,0.0332 -0.53493,0.0985 -0.54587,0.21531 -1.41033,2.70966 -1.027486,4.52331 0.260506,1.23391 1.760336,5.40335 2.480436,7.40707 0.27584,0.76723 0.4095,1.14209 0.45419,1.28142 0.0354,0.10985 0.0863,0.26747 0.15066,0.46629 0.58168,1.77257 2.07468,6.32859 2.51908,10.0177 0.92395,-3.93455 1.44728,-8.6742 1.24228,-14.34655 -0.0931,-2.60111 -0.80793,-5.06378 -2.01209,-6.93357 z" />
<path
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333"
inkscape:connector-curvature="0"
id="path67"
d="m 86.080664,982.55557 c -0.0197,-0.0258 -0.03863,-0.0511 -0.0573,-0.0753 -0.07907,0.0129 -0.208099,0.0411 -0.410145,0.0999 l -0.0846,0.0254 c -1.031607,0.37988 -2.924066,1.01834 -5.111545,1.75647 -2.625311,0.88468 -5.598697,1.88769 -8.088022,2.78087 -3.167319,1.18021 -4.194419,1.64586 -4.516482,1.80901 -0.05846,0.15685 -0.124009,0.35696 -0.197024,0.57768 -0.749077,2.27994 -2.4646,7.4985 -10.924006,11.1469 1.747203,1.7699 5.550278,4.9468 13.037055,4.9468 0.648376,0 1.320961,-0.024 1.99522,-0.073 5.652653,-0.4019 10.966115,-2.903 14.964283,-7.04037 3.635669,-3.76149 5.699397,-8.45284 5.731333,-12.97525 -0.884804,-0.0735 -2.384761,-0.29373 -3.7732,-0.95292 -0.0161,-0.008 -1.602847,-0.7729 -2.565559,-2.02626 z" />
<path
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333"
inkscape:connector-curvature="0"
id="path71"
d="m 53.890317,990.77391 c -0.01571,1.33075 -0.191744,2.60703 -0.363142,3.85124 -0.0922,0.67168 -0.188525,1.36693 -0.25935,2.06566 -0.09607,1.40544 0.207583,1.89516 0.342409,2.03836 0.07353,0.081 0.194835,0.17333 0.455344,0.17333 0.20063,0 0.440149,-0.0556 0.693189,-0.1611 2.51199,-1.05285 4.897523,-2.88028 6.044254,-3.8945 -1.76008,-0.78488 -4.467033,-2.48018 -6.912704,-4.07299 z" />
<path
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333"
inkscape:connector-curvature="0"
id="path75"
d="m 95.375553,985.509 c -0.07108,0.93464 -0.22368,2.69768 -0.467577,4.04066 -0.295536,1.62628 -0.784876,3.00172 -1.069466,3.72015 0.508012,0.46976 1.014479,0.93077 1.342981,1.2218 1.321863,-0.8651 5.661019,-4.15901 8.654629,-11.63703 -0.95898,0.64774 -2.30583,1.21769 -4.051869,1.71682 -1.776691,0.50595 -3.503161,0.80213 -4.408698,0.9376 z" />
<path
d="m 113.82909,953.6111 c -1.81082,-3.78531 -4.33568,-5.69644 -6.07954,-6.80467 -1.46622,-0.93142 -3.15225,-1.60825 -5.02372,-2.01878 -0.20887,-1.30809 -0.56622,-2.64527 -1.05569,-3.9464 3.15586,-4.70424 3.91563,-9.99349 2.19019,-15.35151 -1.32521,-4.11947 -2.35412,-6.77569 -3.23905,-8.36102 -1.911774,-3.42899 -4.56065,-4.14858 -6.446413,-4.14858 -1.943196,0 -3.803719,0.8257 -5.108069,2.26771 -1.335383,1.47601 -1.959035,3.40761 -1.755701,5.43786 0.173716,1.73149 -0.280469,4.87692 -0.581928,6.00008 -0.0052,0.0151 -0.541108,1.51644 -4.528716,3.44908 -0.09606,0.0345 -0.3003,0.10443 -0.614637,0.20977 -2.293718,0.76814 -6.556258,2.19714 -9.395719,5.9518 -2.169451,2.62788 -2.702317,5.23194 -3.317984,8.24615 -0.368036,1.79704 -0.752812,4.14484 -0.65739,6.92095 -7.127627,1.58275 -12.26261,4.80815 -15.273726,9.59879 -3.116711,4.96037 -3.657432,11.10957 -1.605551,18.28497 l 0.01803,0.0533 c 0.0376,0.13058 0.07726,0.26064 0.118601,0.39019 -0.350007,-0.06 -0.703749,-0.11049 -1.066891,-0.15054 -0.317942,-0.0366 -0.6458,-0.0541 -0.970954,-0.0541 -3.558791,0 -7.345641,2.23693 -10.130116,5.98463 -2.115366,2.84564 -4.655943,7.87207 -4.74557,15.65802 -0.06735,5.7826 0.551023,11.1139 1.839276,15.8461 0.96078,3.526 2.032564,5.6921 2.443997,6.4503 l 8.729958,16.3644 3.999713,-18.1224 c 1.365002,-6.1728 2.712748,-8.7931 4.451837,-10.525 4.046715,2.4388 8.826282,3.7217 13.899968,3.7217 5.655614,0 11.552937,-1.6311 16.603314,-4.5923 3.280769,-1.9257 6.07722,-4.2913 8.322519,-7.0385 0.03039,0 0.06039,0 0.09066,0 h 0.239133 c 1.388438,-0.047 3.286563,-0.7336 5.206829,-1.884 1.5995,-0.9571 4.01092,-2.71815 6.43174,-5.67428 2.43963,-2.98176 4.43007,-6.60919 5.91407,-10.78236 1.73845,-4.88554 2.79658,-10.57425 3.1426,-16.90438 0.41889,-5.88793 -0.2676,-10.75686 -2.04507,-14.47211 z m -4.00796,14.09132 c -0.31098,5.76971 -1.2549,10.90199 -2.80263,15.25209 -1.25078,3.51578 -2.89766,6.53385 -4.89404,8.97425 -3.437747,4.19944 -6.797068,5.32543 -7.153514,5.3396 h -0.02833 c -0.32554,0 -0.51664,-0.1329 -1.428745,-0.7711 -0.254843,-0.17758 -0.639877,-0.44646 -0.957562,-0.65352 -1.907525,3.7101 -5.040848,6.91526 -9.099024,9.29556 -4.13338,2.424 -8.941019,3.7604 -13.534121,3.7604 -5.453826,0 -10.241634,-1.8001 -13.887219,-5.2144 -4.973371,3.1622 -7.962467,5.8005 -10.38586,16.7757 l -0.458692,2.0806 -1.002762,-1.8788 c -0.25304,-0.4625 -1.121233,-2.1754 -1.938946,-5.1807 -1.14042,-4.19 -1.688224,-8.9624 -1.627314,-14.1831 0.121563,-10.41898 5.714078,-15.64835 8.811602,-15.64835 0.101988,0 0.203205,0.005 0.299785,0.0165 2.936041,0.3285 4.854641,1.59705 8.337456,3.90069 0.360052,0.23862 0.739162,0.48934 1.138747,0.75178 1.247817,0.819 3.011631,1.81893 3.455643,1.90469 0.845014,-0.0491 1.672256,-1.94178 1.912677,-3.69748 0.01468,-0.10675 0.0291,-0.20578 0.04301,-0.29811 0.01893,-0.20758 0.02923,-0.39019 0.03477,-0.54008 -0.147317,-0.0514 -0.300429,-0.1119 -0.45676,-0.18067 l -0.03477,-0.0117 c -2.190699,-0.75422 -5.3915,-4.45879 -7.002459,-9.83638 -1.555716,-5.43554 -1.247947,-9.93129 0.914164,-13.37058 3.505351,-5.57951 11.114077,-6.89132 13.630573,-7.3222 0.786679,-0.15633 1.609414,-0.30275 2.446573,-0.435 0.390828,-0.0981 0.658033,-0.18015 0.830462,-0.25471 0.07469,-0.0519 0.107526,-0.10727 0.05653,-0.30945 l 0.06825,-0.0191 -0.06606,0.0148 c -0.03052,-0.13714 -0.07276,-0.29759 -0.121176,-0.48328 -0.06709,-0.25717 -0.142037,-0.54807 -0.219559,-0.89318 -0.779081,-3.49505 -0.381428,-6.42375 0.111132,-8.8286 0.553341,-2.70669 0.859951,-4.20523 2.138288,-5.70197 1.693632,-2.33119 4.73926,-3.35134 6.561409,-3.96237 0.508399,-0.17024 0.947646,-0.31704 1.201588,-0.43938 5.581569,-2.67707 7.358776,-5.49168 7.866917,-7.38105 0.402675,-1.49918 1.041007,-5.44108 0.763757,-8.19387 -0.03078,-0.31228 0.04198,-0.56931 0.218271,-0.76428 0.156461,-0.17268 0.378853,-0.27094 0.611418,-0.27094 0.52295,0 1.23919,0 3.91176,8.30308 1.409944,4.37779 0.358635,8.48207 -3.12199,12.20002 -0.04468,0.0483 -0.09014,0.0956 -0.133925,0.14101 -0.09504,0.0979 -0.237974,0.24583 -0.257419,0.29953 7.73e-4,0 -0.0062,0.13418 0.225998,0.51909 1.47124,2.42918 2.270668,5.45009 2.038746,7.6959 -0.05524,0.52308 -0.155301,1.02646 -0.241966,1.46944 -0.05151,0.25343 -0.113192,0.56364 -0.144999,0.80368 0.01429,0 0.0291,0 0.04468,0 0.397654,-0.0421 1.013064,-0.0901 1.754929,-0.0901 1.745657,0 4.245547,0.26747 6.245917,1.53898 1.20816,0.76646 2.73709,1.94925 3.86077,4.30156 1.32392,2.76503 1.81519,6.62579 1.46402,11.47554 z"
id="path87"
inkscape:connector-curvature="0"
style="fill:#0096d5;fill-opacity:1;stroke-width:1.07487333" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

4
sw.js
View File

@ -14,7 +14,3 @@ addEventListener('message', (event) => {
skipWaiting();
}
});
self.addEventListener('activate', (event) => {
event.waitUntil(clients.claim());
});

View File

@ -23,7 +23,7 @@ module.exports = {
loaders: [MiniCssExtractPlugin.loader, "css-loader"]
},
{
test: { and: [ /\.(jpe?g|png|gif|svg|ttf|eot|woff2?)$/i, /jquery-ui/i ] },
test: { and: [ /\.(jpe?g|png|gif|svg)$/i, /jquery-ui/i ] },
loader: "file-loader",
options: {
name: '[name].[contenthash].[ext]',
@ -31,7 +31,7 @@ module.exports = {
}
},
{
test: { and: [ /\.(jpe?g|png|gif|mp3|wav|ttf|eot|woff2?)$/i, { not: [ /jquery-ui/i ] } ] },
test: { and: [ /\.(jpe?g|png|gif|mp3|wav)$/i, { not: [ /jquery-ui/i ] } ] },
loader: "file-loader",
options: {
name: '[path][name].[contenthash].[ext]',
@ -52,14 +52,7 @@ module.exports = {
loader: "svgo-loader",
options: {
plugins: [
{
name: "preset-default",
params: {
overrides: {
cleanupIDs: false,
}
}
},
{ cleanupIDs: false }
]
}
}
@ -95,14 +88,12 @@ module.exports = {
"window.jQuery": "jquery'",
"window.$": "jquery"
}),
new CopyPlugin({
patterns: [
{ from: '.htaccess' },
],
}),
new CopyPlugin([
{ from: '.htaccess' },
]),
new InjectManifest({
swSrc: './sw.js',
dontCacheBustURLsMatching: /\.[0-9a-f]{16,}\.\w{2,4}$/,
dontCacheBustURLsMatching: /\.[0-9a-f]{16,}\.(css|js|svg|png|jpg|wav)$/,
exclude: [ /(^|[/\\])\.htaccess$/ ],
}),
],