{"id":24397508,"url":"https://github.com/hacihaciyev/chess","last_synced_at":"2025-04-11T17:22:00.211Z","repository":{"id":258776653,"uuid":"828241833","full_name":"HaciHaciyev/Chess","owner":"HaciHaciyev","description":"Chessland - A platform for Chess lovers.","archived":false,"fork":false,"pushed_at":"2025-04-06T00:14:44.000Z","size":2041,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-06T01:19:24.410Z","etag":null,"topics":["backend","chess","chess-game","chess-puzzle","chessboard","chessland","fen","java","pgn","programming","quarkus","webapp","websocket"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/HaciHaciyev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-13T14:38:38.000Z","updated_at":"2025-04-06T00:14:48.000Z","dependencies_parsed_at":"2024-11-23T02:19:36.084Z","dependency_job_id":"823cbc19-43ef-4a5f-9868-117b42d50de8","html_url":"https://github.com/HaciHaciyev/Chess","commit_stats":null,"previous_names":["hacihaciyev/chess"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HaciHaciyev%2FChess","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HaciHaciyev%2FChess/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HaciHaciyev%2FChess/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HaciHaciyev%2FChess/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HaciHaciyev","download_url":"https://codeload.github.com/HaciHaciyev/Chess/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248447789,"owners_count":21105177,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backend","chess","chess-game","chess-puzzle","chessboard","chessland","fen","java","pgn","programming","quarkus","webapp","websocket"],"created_at":"2025-01-19T22:27:41.215Z","updated_at":"2025-04-11T17:22:00.198Z","avatar_url":"https://github.com/HaciHaciyev.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Chessland\nChessland - A platform for Chess lovers.\nThe server side consists of two applications:\n- https://github.com/HaciHaciyev/Chess\n- https://github.com/HaciHaciyev/MessagingService\n\n## Features\n- User registration, authentication, and email verification\n- Chess game creation and participation (player \u0026 observer modes)\n- Real-time game updates and chat functionality\n- Handling various game actions (moves, undo requests, resignations, draws, threefold repetition, etc.)\n- Rating system based on Glicko2\n- Partnership management, including partner games\n- Storing game history and results\n\n## Technologies Used\n- **Programming Language:** Java 21\n- **Framework:** Quarkus (3.18.2)\n- **Database:** PostgreSQL (JDBC, Agroal, Flyway)\n- **Authentication \u0026 Security:** SmallRye JWT, Argon2\n- **Caching \u0026 Distributed Processing:** Redis, Redisson\n- **Real-Time Communication:** WebSockets\n- **Email Services:** Quarkus Mailer, Mailpit\n- **File Parsing:** Apache Tika\n- **Logging:** JBoss LogManager\n- **Testing:** JUnit 5, Rest-Assured, AssertJ, Awaitility, Testcontainers, DataFaker\n- **Build \u0026 Dependency Management:** Maven\n\n## Base URL\nAll API endpoints are prefixed with:\n```\n/chessland\n```\n\n## Authentication \u0026 Authorization\nMost endpoints require authentication using JWT. Except login, registration endpoints.\n\n---\n\n## Authentication\n\n### Login\n**Endpoint:**\n```\nPOST /account/login\n```\n**Request Body:** (JSON)\n```json\n{\n  \"username\": \"string\",\n  \"password\": \"string\"\n}\n```\n**Responses:**\n- `200 OK` – Returns JWT token and refreshToken upon successful authentication. Body:\n```json\n{\n  \"token\": \"string\",\n  \"refreshToken\": \"string\"\n}\n```\n- `400 BAD REQUEST` – If the login form is null.\n\n---\n\n### Registration\n**Endpoint:**\n```\nPOST /account/registration\n```\n**Request Body:** (JSON)\n```json\n{\n  \"firstname\": \"string\",\n  \"surname\": \"string\",\n  \"username\": \"string\",\n  \"email\": \"string\",\n  \"password\": \"string\",\n  \"passwordConfirmation\": \"string\"\n}\n```\n**Responses:**\n- `200 OK` – Registration successful. Email verification is required.\n- `400 BAD REQUEST` – If the registration form is null.\n\n---\n\n### Email Verification\n**Endpoint:**\n```\nPATCH /account/token/verification?token={token}\n```\n**Responses:**\n- `200 OK` – Account is now enabled.\n- `400 BAD REQUEST` – If the token is null or invalid.\n\n---\n\n### Refresh Token\n**Endpoint:**\n```\nPATCH /account/refresh-token\n```\n**Headers:**\n```\nRefresh-Token: string\n```\n**Responses:**\n- `200 OK` – Returns a new access token.\n- `400 BAD REQUEST` – If the refresh token is invalid or blank.\n\n---\n\n## User Data\n\n### Get User Properties\n**Endpoint:**\n```\nGET /account/user-properties\n```\n**Responses:**\n- `200 OK` – Returns user properties. Body:\n```json\n{\n  \"firstname\": \"string\",\n  \"surname\": \"string\",\n  \"username\": \"string\",\n  \"email\": \"string\",\n  \"rating\": \"number\",\n  \"bulletRating\": \"number\",\n  \"blitzRating\": \"number\",\n  \"rapidRating\": \"number\",\n  \"puzzlesRating\": \"number\"\n}\n```\n- `400 BAD REQUEST` – If user properties are not found.\n\n---\n\n## Game History\n\n### Get Game History\n**Endpoint:**\n```\nGET /account/game-history?pageNumber={pageNumber}\u0026pageSize={pageSize}\n```\n**Responses:**\n- `200 OK` – Returns a list of game history. Fixed size of page is 10. Body\n```json\n{\n  \"gameHistory\": [\n    {\n      \"chessHistoryId\": \"string (UUID)\",\n      \"pgn\": \"string\",\n      \"fenRepresentations\": \"string[]\",\n      \"playerForWhite\": {\n        \"username\": \"string\"\n      },\n      \"playerForBlack\": {\n        \"username\": \"string\"\n      },\n      \"timeControl\": \"\\\"BULLET\\\" | \\\"BLITZ\\\" | \\\"RAPID\\\" | \\\"CLASSIC\\\" | \\\"DEFAULT\\\"\",\n      \"gameResult\": \"\\\"DRAW\\\" | \\\"WHITE_WIN\\\" | \\\"BLACK_WIN\\\"\",\n      \"whitePlayerRating\": \"number\",\n      \"blackPlayerRating\": \"number\",\n      \"gameStart\": \"string (ISO 8601 datetime)\",\n      \"gameEnd\": \"string (ISO 8601 datetime)\"\n    }\n  ]\n}\n```\n- `400 BAD REQUEST` – If the user does not exist.\n\n---\n\n## Profile Pictures\n\n### Upload Profile Picture\n**Endpoint:**\n```\nPUT /account/put-profile-picture\n```\n**Consumes:**\n```\napplication/octet-stream\n```\n**Request Body:**\nBinary image file.\n\n**Responses:**\n- `202 ACCEPTED` – Successfully uploaded.\n- `400 BAD REQUEST` – If the picture is null or the username is invalid.\n\n---\n\n### Get Profile Picture\n**Endpoint:**\n```\nGET /account/profile-picture\n```\n**Responses:**\n- `200 OK` – Returns the profile picture and its type.\n- `400 BAD REQUEST` – If the username is invalid.\n\n---\n\n### Delete Profile Picture\n**Endpoint:**\n```\nDELETE /account/delete-profile-picture\n```\n**Responses:**\n- `202 ACCEPTED` – Successfully deleted.\n- `400 BAD REQUEST` – If the username is invalid.\n\n---\n\n## Partners\n\n### Get List of Partners\n**Endpoint:**\n```\nGET /account/partners?pageNumber={pageNumber}\u0026pageSize={pageSize}\n```\n**Responses:**\n- `200 OK` – Returns a list of partners usernames. Fixed size 10.\n\n---\n\n### Remove Partner\n**Endpoint:**\n```\nDELETE /account/remove-partner?partner={partner}\n```\n**Responses:**\n- `204 NO CONTENT` – Partner removed successfully.\n\n---\n\n## Puzzles\n\n---\n\n### Get Puzzle by ID\n**Endpoint:**\n```\nGET /puzzles/{id}\n```\n**Responses:**\n- `200 OK` – Returns puzzle. Body:\n```json\n{\n  \"puzzleId\": \"string (UUID)\",\n  \"PGN\": \"string (Portable Game Notation)\", \n  \"startPosition\": \"number\",\n  \"rating\": {\n     \"rating\": \"number\",\n     \"ratingDeviation\": \"number\",\n     \"volatility\": \"number\"\n  }\n}\n```\n- `400 BAD REQUEST` – If puzzle are not found.\n\n---\n\n### List of puzzles\n**Endpoint:**\n```\nGET /puzzles/page?pageNumber={pageNumber}\u0026pageSize={pageSize}\n```\n**Responses:**\n- `200 OK` - Returns list of puzzles, related to defined page and user rating.\n- `400 BAD REQUEST` - puzzles not found.\n\n---\n\n---\n\n### Save puzzle\n**Endpoint:**\n```\nPOST /puzzles/save\n```\nBody:\n```json\n{\n   \"PGN\": \"string (PGN - Portable Game Notation)\",\n   \"startPositionOfPuzzle\": \"number\"\n}\n```\n**Responses:**\n- `200 OK` - Successfully saved a chess puzzle.\n- `400 BAD REQUEST` - Invalid puzzle.\n---\n\n## Root Endpoint\n\n### Base API Path\nAll requests are under:\n```\n/chessland\n```\n\n### WebSocket API\n\n### Overview\nThe WebSocket API includes two endpoints for different services:\n1. **User Session Service** - Handles partnerships management.\n2. **Chess Game Service** - Allows players to initialize, play and observe chess games.\n\n### 1. User Session WebSocket\n\n**Endpoint:** `/chessland/user-session?token={token}`\n\nWhen a user connects to the `/chessland/user-session` endpoint, the server:\n1. **Token Validation**: The server checks the validity of the user's token.\n2. **Session Initialization**: If the token is valid, the server processes the user's session and checks for pending partnership requests.\n\nThe server can return a list of **pending partnership requests** as soon as the connection is established,\nif there are any requests for partnership or other types of messages while the user was not online:\n\n```json\n[\n   {\n      \"type\": \"PARTNERSHIP_REQUEST\",\n      \"message\": \"You have a pending partnership request from User123.\",\n      \"partner\": \"User123\"\n   }\n]\n```\n\nThe message format for a **partnership request** is as follows:\n\n```json\n{\n  \"type\": \"PARTNERSHIP_REQUEST\",\n  \"message\": \"You have a pending partnership request from User123.\",\n  \"partner\": \"User123\"\n}\n```\n\nIn order to respond to a partnership request you must send:\nTo agree to a partnership:\n```json\n{\n  \"type\": \"PARTNERSHIP_REQUEST\",\n  \"message\": \"Hi\",\n  \"partner\": \"UserThatSendYouPartnershipRequest\"\n}\n```\nTo decline to a partnership:\n```json\n{\n  \"type\": \"PARTNERSHIP_DECLINE\",\n  \"partner\": \"UserThatSendYouPartnershipRequest\"\n}\n```\n\n---\n\n#### 1. Chess Game WebSocket\n\n**Endpoint:** `/chessland/chess-game?token={token}`\n\nWhen a user connects to the `/chessland/chess-game` endpoint, the server performs the following actions:\n1. **Token Validation**: The server checks if the user's token is valid.\n2. **Session Initialization**: If the token is valid, the server initiates a chess game session.\n3. **Sending Pending Partnership Invitations**: If there are any pending partnership invitations\n   or requests for the user (messages that were sent while the user was offline), these invitations are sent as a list of messages.\n\nThe message format for a **partnership invitation** is structured as follows:\n\n```json\n{\n  \"type\": \"INVITATION\",\n  \"message\": \"User123 has invited you to a game.\",\n  \"partner\": \"User123\",\n  \"color\": \"white\",\n  \"time\": \"\\\"BULLET\\\" | \\\"BLITZ\\\" | \\\"RAPID\\\" | \\\"CLASSIC\\\" | \\\"DEFAULT\\\"\",\n  \"isCasualGame\": true\n}\n```\n\nThis response will be returned as a **list of messages** when the user connects:\n\n```json\n[\n  {\n    \"type\": \"INVITATION\",\n    \"message\": \"User123 has invited you to a game.\",\n    \"partner\": \"User123\",\n    \"color\": \"white\",\n    \"time\": \"\\\"BULLET\\\" | \\\"BLITZ\\\" | \\\"RAPID\\\" | \\\"CLASSIC\\\" | \\\"DEFAULT\\\"\",\n    \"isCasualGame\": true\n  }\n]\n```\n\n### Chess Game initialization, reconnection and observing\n\nRandom game. Always will be with rating changes. For playing chess-game with random opponent you must send:\n\n```json\n{\n   \"type\": \"GAME_INIT\"\n}\n```\n\nAlso, you can define parameters for a game:\n\n```json\n{\n   \"type\": \"GAME_INIT\",\n   \"color\": \"\\\"WHITE\\\" | \\\"BLACK\\\"\",\n   \"time\": \"\\\"BULLET\\\" | \\\"BLITZ\\\" | \\\"RAPID\\\" | \\\"CLASSIC\\\" | \\\"DEFAULT\\\"\"\n}\n```\n\nTo cancel the game search:\n\n```json\n{\n   \"type\": \"GAME_INIT\",\n   \"respond\": \"NO\"\n}\n```\n\nTo connect to an existing game you must send a message below. \nIf you were a player in this chess game you will be reconnected as a player, otherwise you will be connected as an observer.\n\n```json\n{\n   \"type\": \"GAME_INIT\",\n   \"gameID\": \"string (UUID)\"\n}\n```\n\nFor partnership games you must send a message below. \nPlease note that you must have a partnership with the player you are inviting.\nYou also cannot invite a player again if the previous invitation was not accepted or declined, or has expired.\n\n```json\n{\n   \"type\": \"GAME_INIT\",\n   \"partner\": \"User123\"\n}\n```\n\nYou can also define game parameters:\n```json\n{\n   \"type\": \"GAME_INIT\",\n   \"partner\": \"User123\",\n   \"color\": \"white\",\n   \"time\": \"\\\"BULLET\\\" | \\\"BLITZ\\\" | \\\"RAPID\\\" | \\\"CLASSIC\\\" | \\\"DEFAULT\\\"\",\n   \"isCasualGame\": \"boolean\",\n   \"FEN\": \"string (Forsyth-Edwards Notation)\",\n   \"PGN\": \"string (Portable Game Notation)\"\n}\n```\n\nTo respond to an invitation to a partner chess game:\n```json\n{\n   \"type\": \"GAME_INIT\",\n   \"partner\": \"UserThatInviteYouToPartnershipGame\",\n   \"respond\": \"\\\"YES\\\" | \\\"NO\\\"\"\n}\n```\n\nWhen a player successfully starts a game, the server sends two WebSocket messages containing game-related information.\n\nMessage: GAME_START_INFO\n\nSent when the game starts, providing details about the players and game settings.\n\nPayload Example:\n```json\n{\n  \"type\": \"GAME_START_INFO\",\n  \"gameID\": \"string (UUID)\",\n  \"whitePlayerUsername\": \"Player1\",\n  \"blackPlayerUsername\": \"Player2\",\n  \"whitePlayerRating\": 1500,\n  \"blackPlayerRating\": 1450,\n  \"time\": \"\\\"BULLET\\\" | \\\"BLITZ\\\" | \\\"RAPID\\\" | \\\"CLASSIC\\\" | \\\"DEFAULT\\\"\"\n}\n```\n\nMessage: FEN_PGN\n\nSent after the game starts, providing the initial FEN position and PGN history.\n\nPayload Example:\n```json\n{\n  \"type\": \"FEN_PGN\",\n  \"gameID\": \"string (UUID)\",\n  \"FEN\": \"string (Forsyth-Edwards Notation)\",\n  \"PGN\": \"string (Portable Game Notation)\"\n}\n```\n\nNotes\n\nThese messages are only sent when the game has successfully started.\n\nClients should handle these messages to update the game UI accordingly.\n\n### Game features\n\nChess Board Coordinates format:\n```json\n{\n   \"coordinate\": \"\\\"a8\\\" | \\\"b8\\\" | \\\"c8\\\" | \\\"d8\\\" | \\\"e8\\\" | \\\"f8\\\" | \\\"g8\\\" | \\\"h8\\\" | \\\"a7\\\" | \\\"b7\\\" | \\\"c7\\\" | \\\"d7\\\" | \\\"e7\\\" | \\\"f7\\\" | \\\"g7\\\" | \\\"h7\\\" | \\\"a6\\\" | \\\"b6\\\" | \\\"c6\\\" | \\\"d6\\\" | \\\"e6\\\" | \\\"f6\\\" | \\\"g6\\\" | \\\"h6\\\" | \\\"a5\\\" | \\\"b5\\\" | \\\"c5\\\" | \\\"d5\\\" | \\\"e5\\\" | \\\"f5\\\" | \\\"g5\\\" | \\\"h5\\\" | \\\"a4\\\" | \\\"b4\\\" | \\\"c4\\\" | \\\"d4\\\" | \\\"e4\\\" | \\\"f4\\\" | \\\"g4\\\" | \\\"h4\\\" | \\\"a3\\\" | \\\"b3\\\" | \\\"c3\\\" | \\\"d3\\\" | \\\"e3\\\" | \\\"f3\\\" | \\\"g3\\\" | \\\"h3\\\" | \\\"a2\\\" | \\\"b2\\\" | \\\"c2\\\" | \\\"d2\\\" | \\\"e2\\\" | \\\"f2\\\" | \\\"g2\\\" | \\\"h2\\\" | \\\"a1\\\" | \\\"b1\\\" | \\\"c1\\\" | \\\"d1\\\" | \\\"e1\\\" | \\\"f1\\\" | \\\"g1\\\" | \\\"h1\\\"\"\n}\n```\n\nFor move:\n```json\n{\n   \"type\": \"MOVE\",\n   \"gameID\": \"string (UUID)\",\n   \"from\": \"coordinate\",\n   \"to\": \"coordinate\",\n   \"inCaseOfPromotion\": \"null | \\\"Q\\\" | \\\"B\\\" | \\\"N\\\" | \\\"R\\\" | \\\"q\\\" | \\\"b\\\" | \\\"n\\\" | \\\"r\\\"\"\n}\n```\n\nFor undo move you must send message below.\nThe opponent will have to send a similar request to agree if he wants, otherwise, he can make a move and the request will be cancelled.\n```json\n{\n   \"type\": \"RETURN_MOVE\",\n   \"gameID\": \"string (UUID)\"\n}\n```\n\nFor write a message for game chat:\n```json\n{\n   \"type\": \"MESSAGE\",\n   \"gameID\": \"string (UUID)\",\n   \"message\": \"string\"\n}\n```\n\nFor agreement request you must send message below.\nThe opponent will have to send a similar request to agree if he wants, otherwise, he can make a move and the request will be cancelled.\n```json\n{\n   \"type\": \"AGREEMENT\",\n   \"gameID\": \"string (UUID)\"\n}\n```\n\nFor resignation:\n```json\n{\n   \"type\": \"RESIGNATION\",\n   \"gameID\": \"string (UUID)\"\n}\n```\n\nIf a ThreeFold occurs on the board, either player may request that the game end in a draw:\n```json\n{\n   \"type\": \"TREE_FOLD\",\n   \"gameID\": \"string (UUID)\"\n}\n```\n\nAfter a successful move or return of a move, the client will receive:\n```json\n{\n   \"type\": \"FEN_PGN\",\n   \"gameID\": \"string (UUID)\",\n   \"FEN\": \"string (Forsyth-Edwards Notation)\",\n   \"PGN\": \"string (Portable Game Notation)\",\n   \"timeLeft\": \"\\\"BULLET\\\" | \\\"BLITZ\\\" | \\\"RAPID\\\" | \\\"CLASSIC\\\" | \\\"DEFAULT\\\"\",\n   \"isThreeFoldActive\": \"boolean\"\n}\n```\n\nIn case of any error, the client will receive:\n\n```json\n{\n   \"type\": \"ERROR\",\n   \"message\": \"string\"\n}\n```\n\nor\n\n```json\n{\n   \"type\": \"ERROR\",\n   \"gameID\": \"gameID\",\n   \"message\": \"string\"\n}\n```\n\nChess Puzzles\n\nFor starting new puzzle you must send a message below. \nThe server will load a random puzzle corresponding to the player's rating, making sure that the user has not solved this puzzle before:\n\n```json\n{\n   \"type\": \"PUZZLE\"\n}\n```\n\nThe response will be either:\n\n```json\n{\n   \"type\": \"ERROR\",\n   \"message\": \"error description\"\n}\n```\n\nor\n\n```json\n{\n   \"type\": \"PUZZLE\",\n   \"gameID\": \"string (UUID)\",\n   \"FEN\": \"string (Forsyth-Edwards Notation)\",\n   \"PGN\": \"string (Portable Game Notation)\"\n}\n```\n\nFor making move for solving puzzle:\n\n```json\n{\n   \"type\": \"PUZZLE_MOVE\",\n   \"gameID\": \"string (UUID)\",\n   \"from\": \"coordinate\",\n   \"to\": \"coordinate\",\n   \"inCaseOfPromotion\": \"null | \\\"Q\\\" | \\\"B\\\" | \\\"N\\\" | \\\"R\\\" | \\\"q\\\" | \\\"b\\\" | \\\"n\\\" | \\\"r\\\"\"\n}\n```\n\nThe response will be either:\n\n```json\n{\n   \"type\": \"ERROR\",\n   \"message\": \"error description\"\n}\n```\n\nor\n\n```json\n{\n   \"type\": \"PUZZLE_MOVE\",\n   \"gameID\": \"string (UUID)\",\n   \"FEN\": \"string (Forsyth-Edwards Notation)\",\n   \"PGN\": \"string (Portable Game Notation)\",\n   \"isPuzzleEnded\": \"boolean\",\n   \"isPuzzleSolved\": \"boolean\"\n}\n```\n\n## Contributing\nWe welcome contributions to the Chess Game Backend project. We also welcome front-end developers and designers for the client side.\nIf you find any issues or have suggestions for improvements, please feel free to open an issue or submit a pull request.\n\n## License\n\nThis project is licensed under the **Prosperity Public License 3.0.0**.  \nYou are free to use, modify, and distribute this software **for non-commercial purposes**.\n\nFor commercial use, please contact the author for a separate license agreement.  \nThe full text of the license is available in the [LICENSE](./LICENSE) file or at [prosperitylicense.com](https://prosperitylicense.com/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhacihaciyev%2Fchess","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhacihaciyev%2Fchess","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhacihaciyev%2Fchess/lists"}