From ac0cd449cd1d1e290f7cad911bc519d8aa56ff11 Mon Sep 17 00:00:00 2001 From: GAM Date: Fri, 12 Mar 2021 07:33:43 +0100 Subject: [PATCH] images of games :) no more useless "com.example....." --- .gitignore | 2 + README.md | 16 +- db/db_init.sql | 174 +++++++++--------- .../components/leafletmap/leaflet-map.js | 0 frontend/{ => app}/views/about/about-view.css | 0 .../views/addressform/address-form-view.css | 0 .../views/cardlist/card-list-view.css | 0 .../creditcardform/credit-card-form-view.css | 0 .../views/helloworld/hello-world-view.css | 0 frontend/{ => app}/views/main/main-view.css | 0 frontend/{ => app}/views/map/map-view.css | 0 .../views/masterdetail/master-detail-view.css | 0 .../views/personform/person-form-view.css | 0 .../{ => app}/views/results/results-view.css | 0 frontend/{ => app}/views/table/table-view.css | 0 pom.xml | 2 +- .../application => app}/Application.java | 2 +- .../components/leafletmap/LeafletMap.java | 4 +- .../SeasonAndMatchdayNavigation.java | 4 +- .../data/AbstractEntity.java | 2 +- .../data/bean/CalculatedMatch.java | 6 +- .../data/bean/PlayerForTable.java | 4 +- .../data/chesscom/ChessComArchive.java | 2 +- .../data/chesscom/ChessComArchiveList.java | 2 +- .../data/chesscom/ChessComGame.java | 2 +- .../application => app}/data/entity/Game.java | 2 +- .../data/entity/GameInfo.java | 2 +- .../data/entity/Match.java | 2 +- .../data/entity/Matchday.java | 2 +- .../data/entity/Player.java | 2 +- .../data/entity/PlayerInfo.java | 2 +- .../data/entity/SampleAddress.java | 4 +- .../data/entity/SamplePerson.java | 4 +- .../data/entity/Season.java | 2 +- .../data/generator/DataGenerator.java | 4 +- .../app/data/service/ChessComService.java | 142 ++++++++++++++ .../data/service/GameInfoRepository.java | 4 +- .../data/service/GameInfoService.java | 4 +- .../data/service/GameRepository.java | 4 +- .../data/service/GameService.java | 4 +- .../data/service/MatchRepository.java | 4 +- .../data/service/MatchService.java | 10 +- .../data/service/MatchdayRepository.java | 4 +- .../data/service/MatchdayService.java | 6 +- .../data/service/PlayerInfoRepository.java | 4 +- .../data/service/PlayerInfoService.java | 4 +- .../data/service/PlayerRepository.java | 4 +- .../data/service/PlayerService.java | 10 +- .../data/service/SampleAddressRepository.java | 4 +- .../data/service/SampleAddressService.java | 4 +- .../data/service/SamplePersonRepository.java | 4 +- .../data/service/SamplePersonService.java | 4 +- .../data/service/SeasonRepository.java | 4 +- .../data/service/SeasonService.java | 4 +- src/main/java/app/image/ImageGenerator.java | 75 ++++++++ src/main/java/app/image/ImageService.java | 48 +++++ src/main/java/app/image/ImageUtils.java | 36 ++++ .../navigation/Navigation.java | 16 +- .../navigation/NavigationUtils.java | 3 +- .../navigation/UrlParameterType.java | 2 +- .../utils/ChessComUtils.java | 15 +- .../application => app}/utils/HttpUtils.java | 2 +- .../utils/StringUtils.java | 2 +- .../utils/VaadinUtils.java | 4 +- .../views/about/AboutView.java | 8 +- .../views/addressform/AddressFormView.java | 10 +- .../views/cardlist/CardListView.java | 6 +- .../views/cardlist/Person.java | 2 +- .../creditcardform/CreditCardFormView.java | 6 +- .../views/helloworld/HelloWorldView.java | 6 +- .../views/main/MainView.java | 11 +- .../views/map/MapView.java | 6 +- .../views/masterdetail/MasterDetailView.java | 10 +- .../views/personform/PersonFormView.java | 10 +- .../java/app/views/results/MatchView.java | 66 +++++++ .../views/results/MatchdayView.java | 18 +- .../views/results/ResultsView.java | 15 +- .../views/table/TableView.java | 27 ++- .../data/service/ChessComService.java | 81 -------- .../application/views/results/MatchView.java | 35 ---- .../resources/images/chess-sources/bb.png | Bin 0 -> 1395 bytes .../resources/images/chess-sources/bk.png | Bin 0 -> 1453 bytes .../resources/images/chess-sources/bn.png | Bin 0 -> 1563 bytes .../resources/images/chess-sources/board.png | Bin 0 -> 13515 bytes .../resources/images/chess-sources/bp.png | Bin 0 -> 1168 bytes .../resources/images/chess-sources/bq.png | Bin 0 -> 1901 bytes .../resources/images/chess-sources/br.png | Bin 0 -> 1303 bytes .../resources/images/chess-sources/wb.png | Bin 0 -> 1643 bytes .../resources/images/chess-sources/wk.png | Bin 0 -> 1707 bytes .../resources/images/chess-sources/wn.png | Bin 0 -> 1682 bytes .../resources/images/chess-sources/wp.png | Bin 0 -> 1183 bytes .../resources/images/chess-sources/wq.png | Bin 0 -> 2171 bytes .../resources/images/chess-sources/wr.png | Bin 0 -> 1490 bytes 93 files changed, 626 insertions(+), 370 deletions(-) rename frontend/{ => app}/components/leafletmap/leaflet-map.js (100%) rename frontend/{ => app}/views/about/about-view.css (100%) rename frontend/{ => app}/views/addressform/address-form-view.css (100%) rename frontend/{ => app}/views/cardlist/card-list-view.css (100%) rename frontend/{ => app}/views/creditcardform/credit-card-form-view.css (100%) rename frontend/{ => app}/views/helloworld/hello-world-view.css (100%) rename frontend/{ => app}/views/main/main-view.css (100%) rename frontend/{ => app}/views/map/map-view.css (100%) rename frontend/{ => app}/views/masterdetail/master-detail-view.css (100%) rename frontend/{ => app}/views/personform/person-form-view.css (100%) rename frontend/{ => app}/views/results/results-view.css (100%) rename frontend/{ => app}/views/table/table-view.css (100%) rename src/main/java/{com/example/application => app}/Application.java (94%) rename src/main/java/{com/example/application => app}/components/leafletmap/LeafletMap.java (83%) rename src/main/java/{com/example/application => app}/components/navigation/SeasonAndMatchdayNavigation.java (84%) rename src/main/java/{com/example/application => app}/data/AbstractEntity.java (95%) rename src/main/java/{com/example/application => app}/data/bean/CalculatedMatch.java (88%) rename src/main/java/{com/example/application => app}/data/bean/PlayerForTable.java (97%) rename src/main/java/{com/example/application => app}/data/chesscom/ChessComArchive.java (84%) rename src/main/java/{com/example/application => app}/data/chesscom/ChessComArchiveList.java (84%) rename src/main/java/{com/example/application => app}/data/chesscom/ChessComGame.java (98%) rename src/main/java/{com/example/application => app}/data/entity/Game.java (97%) rename src/main/java/{com/example/application => app}/data/entity/GameInfo.java (97%) rename src/main/java/{com/example/application => app}/data/entity/Match.java (97%) rename src/main/java/{com/example/application => app}/data/entity/Matchday.java (97%) rename src/main/java/{com/example/application => app}/data/entity/Player.java (98%) rename src/main/java/{com/example/application => app}/data/entity/PlayerInfo.java (96%) rename src/main/java/{com/example/application => app}/data/entity/SampleAddress.java (90%) rename src/main/java/{com/example/application => app}/data/entity/SamplePerson.java (93%) rename src/main/java/{com/example/application => app}/data/entity/Season.java (97%) rename src/main/java/{com/example/application => app}/data/generator/DataGenerator.java (94%) create mode 100644 src/main/java/app/data/service/ChessComService.java rename src/main/java/{com/example/application => app}/data/service/GameInfoRepository.java (59%) rename src/main/java/{com/example/application => app}/data/service/GameInfoService.java (83%) rename src/main/java/{com/example/application => app}/data/service/GameRepository.java (59%) rename src/main/java/{com/example/application => app}/data/service/GameService.java (83%) rename src/main/java/{com/example/application => app}/data/service/MatchRepository.java (59%) rename src/main/java/{com/example/application => app}/data/service/MatchService.java (88%) rename src/main/java/{com/example/application => app}/data/service/MatchdayRepository.java (59%) rename src/main/java/{com/example/application => app}/data/service/MatchdayService.java (93%) rename src/main/java/{com/example/application => app}/data/service/PlayerInfoRepository.java (59%) rename src/main/java/{com/example/application => app}/data/service/PlayerInfoService.java (83%) rename src/main/java/{com/example/application => app}/data/service/PlayerRepository.java (59%) rename src/main/java/{com/example/application => app}/data/service/PlayerService.java (96%) rename src/main/java/{com/example/application => app}/data/service/SampleAddressRepository.java (59%) rename src/main/java/{com/example/application => app}/data/service/SampleAddressService.java (83%) rename src/main/java/{com/example/application => app}/data/service/SamplePersonRepository.java (59%) rename src/main/java/{com/example/application => app}/data/service/SamplePersonService.java (83%) rename src/main/java/{com/example/application => app}/data/service/SeasonRepository.java (59%) rename src/main/java/{com/example/application => app}/data/service/SeasonService.java (93%) create mode 100644 src/main/java/app/image/ImageGenerator.java create mode 100644 src/main/java/app/image/ImageService.java create mode 100644 src/main/java/app/image/ImageUtils.java rename src/main/java/{com/example/application => app}/navigation/Navigation.java (97%) rename src/main/java/{com/example/application => app}/navigation/NavigationUtils.java (92%) rename src/main/java/{com/example/application => app}/navigation/UrlParameterType.java (61%) rename src/main/java/{com/example/application => app}/utils/ChessComUtils.java (75%) rename src/main/java/{com/example/application => app}/utils/HttpUtils.java (96%) rename src/main/java/{com/example/application => app}/utils/StringUtils.java (97%) rename src/main/java/{com/example/application => app}/utils/VaadinUtils.java (93%) rename src/main/java/{com/example/application => app}/views/about/AboutView.java (86%) rename src/main/java/{com/example/application => app}/views/addressform/AddressFormView.java (90%) rename src/main/java/{com/example/application => app}/views/cardlist/CardListView.java (98%) rename src/main/java/{com/example/application => app}/views/cardlist/Person.java (96%) rename src/main/java/{com/example/application => app}/views/creditcardform/CreditCardFormView.java (95%) rename src/main/java/{com/example/application => app}/views/helloworld/HelloWorldView.java (85%) rename src/main/java/{com/example/application => app}/views/main/MainView.java (94%) rename src/main/java/{com/example/application => app}/views/map/MapView.java (74%) rename src/main/java/{com/example/application => app}/views/masterdetail/MasterDetailView.java (96%) rename src/main/java/{com/example/application => app}/views/personform/PersonFormView.java (94%) create mode 100644 src/main/java/app/views/results/MatchView.java rename src/main/java/{com/example/application => app}/views/results/MatchdayView.java (90%) rename src/main/java/{com/example/application => app}/views/results/ResultsView.java (84%) rename src/main/java/{com/example/application => app}/views/table/TableView.java (89%) delete mode 100644 src/main/java/com/example/application/data/service/ChessComService.java delete mode 100644 src/main/java/com/example/application/views/results/MatchView.java create mode 100644 src/main/resources/META-INF/resources/images/chess-sources/bb.png create mode 100644 src/main/resources/META-INF/resources/images/chess-sources/bk.png create mode 100644 src/main/resources/META-INF/resources/images/chess-sources/bn.png create mode 100644 src/main/resources/META-INF/resources/images/chess-sources/board.png create mode 100644 src/main/resources/META-INF/resources/images/chess-sources/bp.png create mode 100644 src/main/resources/META-INF/resources/images/chess-sources/bq.png create mode 100644 src/main/resources/META-INF/resources/images/chess-sources/br.png create mode 100644 src/main/resources/META-INF/resources/images/chess-sources/wb.png create mode 100644 src/main/resources/META-INF/resources/images/chess-sources/wk.png create mode 100644 src/main/resources/META-INF/resources/images/chess-sources/wn.png create mode 100644 src/main/resources/META-INF/resources/images/chess-sources/wp.png create mode 100644 src/main/resources/META-INF/resources/images/chess-sources/wq.png create mode 100644 src/main/resources/META-INF/resources/images/chess-sources/wr.png diff --git a/.gitignore b/.gitignore index 4b3d37f..d2297c3 100644 --- a/.gitignore +++ b/.gitignore @@ -97,3 +97,5 @@ fabric.properties hs_err_pid* .gitignore + +src/main/resources/META-INF/resources/images/games/* \ No newline at end of file diff --git a/README.md b/README.md index ead3634..0247bf0 100644 --- a/README.md +++ b/README.md @@ -13,16 +13,16 @@ This project was created from https://start.vaadin.com. To run from the command line, use `mvn` and open http://localhost:8080 in your browser. ### Running and debugging the application in Intellij IDEA -- Locate the Application.java class in the Project view. It is in the src folder, under the main package's root. -- Right-click on the Application class -- Select "Debug 'Application.main()'" from the list +- Locate the app.Application.java class in the Project view. It is in the src folder, under the main package's root. +- Right-click on the app.Application class +- Select "Debug 'app.Application.main()'" from the list After the application has started, you can view it at http://localhost:8080/ in your browser. You can now also attach breakpoints in code for debugging purposes, by clicking next to a line number in any source file. ### Running and debugging the application in Eclipse -- Locate the Application.java class in the Package Explorer. It is in `src/main/java`, under the main package. -- Right-click on the file and select `Debug As` --> `Java Application`. +- Locate the app.Application.java class in the Package Explorer. It is in `src/main/java`, under the main package. +- Right-click on the file and select `Debug As` --> `Java app.Application`. Do not worry if the debugger breaks at a `SilentExitException`. This is a Spring Boot feature and happens on every startup. @@ -30,9 +30,9 @@ After the application has started, you can view it at http://localhost:8080/ in You can now also attach breakpoints in code for debugging purposes, by clicking next to a line number in any source file. ## Project structure -- `MainView.java` in `src/main/java` contains the navigation setup. It uses [App Layout](https://vaadin.com/components/vaadin-app-layout). -- `views` package in `src/main/java` contains the server-side Java views of your application. -- `views` folder in `frontend/` contains the client-side JavaScript views of your application. +- `MainView.java` in `src/main/java` contains the app.navigation setup. It uses [App Layout](https://vaadin.com/components/vaadin-app-layout). +- `app.views` package in `src/main/java` contains the server-side Java app.views of your application. +- `app.views` folder in `frontend/` contains the client-side JavaScript app.views of your application. ## What next? diff --git a/db/db_init.sql b/db/db_init.sql index afd0455..409333c 100644 --- a/db/db_init.sql +++ b/db/db_init.sql @@ -1,8 +1,8 @@ --- Database: chessleague +-- Database: app --- DROP DATABASE chessleague; +-- DROP DATABASE app; --- CREATE DATABASE chessleague +-- CREATE DATABASE app -- WITH -- OWNER = postgres -- ENCODING = 'UTF8' @@ -357,137 +357,137 @@ INSERT INTO "match" ("player1", "player2", "matchday") VALUES ( 9, 5, 26); INSERT INTO "match" ("player1", "player2", "matchday") VALUES ( 7, 13, 26); INSERT INTO "match" ("player1", "player2", "matchday") VALUES (14, 2, 26); -INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/live/game/8722014513'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=2 AND player2=9 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8722014513')); +INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8722014513'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=2 AND player2=9 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8722014513')); -INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/live/game/8723231941'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=2 AND player2=9 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8723231941')); +INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8723231941'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=2 AND player2=9 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8723231941')); -INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/live/game/8724907847'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=2 AND player2=9 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8724907847')); +INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8724907847'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=2 AND player2=9 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8724907847')); -INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/live/game/8725036665'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=2 AND player2=9 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8725036665')); +INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8725036665'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=2 AND player2=9 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8725036665')); -INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/live/game/8725614379'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=2 AND player2=9 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8725614379')); +INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8725614379'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=2 AND player2=9 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8725614379')); -INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/live/game/8726184583'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=2 AND player2=9 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8726184583')); +INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8726184583'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=2 AND player2=9 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8726184583')); -INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/live/game/8616485043'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=14 AND player2=7 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8616485043')); +INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8616485043'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=14 AND player2=7 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8616485043')); -INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/live/game/8618149677'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=14 AND player2=7 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8618149677')); +INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8618149677'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=14 AND player2=7 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8618149677')); -INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/live/game/8702757001'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=14 AND player2=7 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8702757001')); +INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8702757001'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=14 AND player2=7 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8702757001')); -INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/live/game/8705204521'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=14 AND player2=7 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8705204521')); +INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8705204521'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=14 AND player2=7 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8705204521')); -INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/live/game/8705796221'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=14 AND player2=7 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8705796221')); +INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8705796221'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=14 AND player2=7 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8705796221')); -INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/live/game/8706438057'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=14 AND player2=7 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8706438057')); +INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8706438057'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=14 AND player2=7 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8706438057')); -INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/live/game/8617630129'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=10 AND player2=4 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8617630129')); +INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8617630129'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=10 AND player2=4 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8617630129')); -INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/live/game/8618225533'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=10 AND player2=4 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8618225533')); +INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8618225533'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=10 AND player2=4 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8618225533')); -INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/live/game/8619306585'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=10 AND player2=4 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8619306585')); +INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8619306585'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=10 AND player2=4 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8619306585')); -INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/live/game/8619471075'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=10 AND player2=4 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8619471075')); +INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8619471075'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=10 AND player2=4 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8619471075')); -INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/live/game/8620078695'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=10 AND player2=4 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8620078695')); +INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8620078695'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=10 AND player2=4 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8620078695')); -INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/live/game/8620568591'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=10 AND player2=4 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8620568591')); +INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8620568591'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=10 AND player2=4 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8620568591')); -INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/live/game/8504667551'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=13 AND player2=6 AND matchday=1), TRUE, 0, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8504667551')); +INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8504667551'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=13 AND player2=6 AND matchday=1), TRUE, 0, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8504667551')); -INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/live/game/8505882389'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=13 AND player2=6 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8505882389')); +INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8505882389'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=13 AND player2=6 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8505882389')); -INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/live/game/8507004247'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=13 AND player2=6 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8507004247')); +INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8507004247'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=13 AND player2=6 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8507004247')); -INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/live/game/8507617133'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=13 AND player2=6 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8507617133')); +INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8507617133'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=13 AND player2=6 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8507617133')); -INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/live/game/8508203475'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=13 AND player2=6 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8508203475')); +INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8508203475'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=13 AND player2=6 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8508203475')); -INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/live/game/8508297031'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=13 AND player2=6 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8508297031')); +INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8508297031'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=13 AND player2=6 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8508297031')); -INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/live/game/8624735639'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8624735639')); +INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8624735639'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8624735639')); -INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/live/game/8625353555'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8625353555')); +INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8625353555'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8625353555')); -INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/live/game/8625963087'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8625963087')); +INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8625963087'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8625963087')); -INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/live/game/8853361491'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8853361491')); +INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8853361491'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8853361491')); -INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/live/game/8853455035'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8853455035')); +INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8853455035'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8853455035')); -INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/live/game/8854002505'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8854002505')); +INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8854002505'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=11 AND player2=8 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8854002505')); -INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/live/game/8858219835'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8858219835')); +INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8858219835'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8858219835')); -INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/live/game/8859375675'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8859375675')); +INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8859375675'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8859375675')); -INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/live/game/8859976305'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8859976305')); +INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8859976305'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8859976305')); -INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/live/game/8860591347'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8860591347')); +INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8860591347'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8860591347')); -INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/live/game/8860675419'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8860675419')); +INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8860675419'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8860675419')); -INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/live/game/8861228997'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8861228997')); +INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8861228997'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=12 AND player2=1 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8861228997')); -INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/live/game/8877523129'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8877523129')); +INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8877523129'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8877523129')); -INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/live/game/8878652939'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8878652939')); +INSERT INTO "game_info" (time_control, url)VALUES ('600', 'https://www.chess.com/game/live/8878652939'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8878652939')); -INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/live/game/8879853665'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8879853665')); +INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8879853665'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), FALSE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8879853665')); -INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/live/game/8880469509'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8880469509')); +INSERT INTO "game_info" (time_control, url)VALUES ('300', 'https://www.chess.com/game/live/8880469509'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), TRUE, 1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8880469509')); -INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/live/game/8881562307'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8881562307')); +INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8881562307'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), FALSE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8881562307')); -INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/live/game/8881610243'); -INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/live/game/8881610243')); +INSERT INTO "game_info" (time_control, url)VALUES ('180', 'https://www.chess.com/game/live/8881610243'); +INSERT INTO "game" (match, player1_is_white, result, info) VALUES ((SELECT id from match WHERE player1=5 AND player2=3 AND matchday=1), TRUE, -1, (SELECT id from game_info WHERE url='https://www.chess.com/game/live/8881610243')); diff --git a/frontend/components/leafletmap/leaflet-map.js b/frontend/app/components/leafletmap/leaflet-map.js similarity index 100% rename from frontend/components/leafletmap/leaflet-map.js rename to frontend/app/components/leafletmap/leaflet-map.js diff --git a/frontend/views/about/about-view.css b/frontend/app/views/about/about-view.css similarity index 100% rename from frontend/views/about/about-view.css rename to frontend/app/views/about/about-view.css diff --git a/frontend/views/addressform/address-form-view.css b/frontend/app/views/addressform/address-form-view.css similarity index 100% rename from frontend/views/addressform/address-form-view.css rename to frontend/app/views/addressform/address-form-view.css diff --git a/frontend/views/cardlist/card-list-view.css b/frontend/app/views/cardlist/card-list-view.css similarity index 100% rename from frontend/views/cardlist/card-list-view.css rename to frontend/app/views/cardlist/card-list-view.css diff --git a/frontend/views/creditcardform/credit-card-form-view.css b/frontend/app/views/creditcardform/credit-card-form-view.css similarity index 100% rename from frontend/views/creditcardform/credit-card-form-view.css rename to frontend/app/views/creditcardform/credit-card-form-view.css diff --git a/frontend/views/helloworld/hello-world-view.css b/frontend/app/views/helloworld/hello-world-view.css similarity index 100% rename from frontend/views/helloworld/hello-world-view.css rename to frontend/app/views/helloworld/hello-world-view.css diff --git a/frontend/views/main/main-view.css b/frontend/app/views/main/main-view.css similarity index 100% rename from frontend/views/main/main-view.css rename to frontend/app/views/main/main-view.css diff --git a/frontend/views/map/map-view.css b/frontend/app/views/map/map-view.css similarity index 100% rename from frontend/views/map/map-view.css rename to frontend/app/views/map/map-view.css diff --git a/frontend/views/masterdetail/master-detail-view.css b/frontend/app/views/masterdetail/master-detail-view.css similarity index 100% rename from frontend/views/masterdetail/master-detail-view.css rename to frontend/app/views/masterdetail/master-detail-view.css diff --git a/frontend/views/personform/person-form-view.css b/frontend/app/views/personform/person-form-view.css similarity index 100% rename from frontend/views/personform/person-form-view.css rename to frontend/app/views/personform/person-form-view.css diff --git a/frontend/views/results/results-view.css b/frontend/app/views/results/results-view.css similarity index 100% rename from frontend/views/results/results-view.css rename to frontend/app/views/results/results-view.css diff --git a/frontend/views/table/table-view.css b/frontend/app/views/table/table-view.css similarity index 100% rename from frontend/views/table/table-view.css rename to frontend/app/views/table/table-view.css diff --git a/pom.xml b/pom.xml index 21a46da..26bd1a5 100644 --- a/pom.xml +++ b/pom.xml @@ -67,7 +67,7 @@ com.vaadin - + vaadin diff --git a/src/main/java/com/example/application/Application.java b/src/main/java/app/Application.java similarity index 94% rename from src/main/java/com/example/application/Application.java rename to src/main/java/app/Application.java index bcbda61..fdf3b16 100644 --- a/src/main/java/com/example/application/Application.java +++ b/src/main/java/app/Application.java @@ -1,4 +1,4 @@ -package com.example.application; +package app; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/src/main/java/com/example/application/components/leafletmap/LeafletMap.java b/src/main/java/app/components/leafletmap/LeafletMap.java similarity index 83% rename from src/main/java/com/example/application/components/leafletmap/LeafletMap.java rename to src/main/java/app/components/leafletmap/LeafletMap.java index 41bcbda..654991b 100644 --- a/src/main/java/com/example/application/components/leafletmap/LeafletMap.java +++ b/src/main/java/app/components/leafletmap/LeafletMap.java @@ -1,4 +1,4 @@ -package com.example.application.components.leafletmap; +package app.components.leafletmap; import com.vaadin.flow.component.Component; import com.vaadin.flow.component.HasSize; @@ -7,7 +7,7 @@ import com.vaadin.flow.component.dependency.CssImport; import com.vaadin.flow.component.dependency.JsModule; @CssImport("leaflet/dist/leaflet.css") -@JsModule("./components/leafletmap/leaflet-map.js") +@JsModule("app/components/leafletmap/leaflet-map.js") @Tag("leaflet-map") public class LeafletMap extends Component implements HasSize { diff --git a/src/main/java/com/example/application/components/navigation/SeasonAndMatchdayNavigation.java b/src/main/java/app/components/navigation/SeasonAndMatchdayNavigation.java similarity index 84% rename from src/main/java/com/example/application/components/navigation/SeasonAndMatchdayNavigation.java rename to src/main/java/app/components/navigation/SeasonAndMatchdayNavigation.java index d4e433a..8171b2f 100644 --- a/src/main/java/com/example/application/components/navigation/SeasonAndMatchdayNavigation.java +++ b/src/main/java/app/components/navigation/SeasonAndMatchdayNavigation.java @@ -1,6 +1,6 @@ -package com.example.application.components.navigation; +package app.components.navigation; -import com.example.application.navigation.Navigation; +import app.navigation.Navigation; import com.vaadin.flow.component.html.Label; import com.vaadin.flow.component.orderedlayout.FlexComponent; import com.vaadin.flow.component.orderedlayout.HorizontalLayout; diff --git a/src/main/java/com/example/application/data/AbstractEntity.java b/src/main/java/app/data/AbstractEntity.java similarity index 95% rename from src/main/java/com/example/application/data/AbstractEntity.java rename to src/main/java/app/data/AbstractEntity.java index 96f139f..8fd809d 100644 --- a/src/main/java/com/example/application/data/AbstractEntity.java +++ b/src/main/java/app/data/AbstractEntity.java @@ -1,4 +1,4 @@ -package com.example.application.data; +package app.data; import javax.persistence.GeneratedValue; import javax.persistence.Id; diff --git a/src/main/java/com/example/application/data/bean/CalculatedMatch.java b/src/main/java/app/data/bean/CalculatedMatch.java similarity index 88% rename from src/main/java/com/example/application/data/bean/CalculatedMatch.java rename to src/main/java/app/data/bean/CalculatedMatch.java index 02e4b38..fbdf1cf 100644 --- a/src/main/java/com/example/application/data/bean/CalculatedMatch.java +++ b/src/main/java/app/data/bean/CalculatedMatch.java @@ -1,7 +1,7 @@ -package com.example.application.data.bean; +package app.data.bean; -import com.example.application.data.entity.Match; -import com.example.application.data.entity.Player; +import app.data.entity.Match; +import app.data.entity.Player; public class CalculatedMatch { private Match match; diff --git a/src/main/java/com/example/application/data/bean/PlayerForTable.java b/src/main/java/app/data/bean/PlayerForTable.java similarity index 97% rename from src/main/java/com/example/application/data/bean/PlayerForTable.java rename to src/main/java/app/data/bean/PlayerForTable.java index 27726ae..3fc542e 100644 --- a/src/main/java/com/example/application/data/bean/PlayerForTable.java +++ b/src/main/java/app/data/bean/PlayerForTable.java @@ -1,6 +1,6 @@ -package com.example.application.data.bean; +package app.data.bean; -import com.example.application.data.entity.Player; +import app.data.entity.Player; public class PlayerForTable { private Player player; diff --git a/src/main/java/com/example/application/data/chesscom/ChessComArchive.java b/src/main/java/app/data/chesscom/ChessComArchive.java similarity index 84% rename from src/main/java/com/example/application/data/chesscom/ChessComArchive.java rename to src/main/java/app/data/chesscom/ChessComArchive.java index c2ad97e..9283cd8 100644 --- a/src/main/java/com/example/application/data/chesscom/ChessComArchive.java +++ b/src/main/java/app/data/chesscom/ChessComArchive.java @@ -1,4 +1,4 @@ -package com.example.application.data.chesscom; +package app.data.chesscom; import java.util.List; diff --git a/src/main/java/com/example/application/data/chesscom/ChessComArchiveList.java b/src/main/java/app/data/chesscom/ChessComArchiveList.java similarity index 84% rename from src/main/java/com/example/application/data/chesscom/ChessComArchiveList.java rename to src/main/java/app/data/chesscom/ChessComArchiveList.java index fb10c17..c9b139b 100644 --- a/src/main/java/com/example/application/data/chesscom/ChessComArchiveList.java +++ b/src/main/java/app/data/chesscom/ChessComArchiveList.java @@ -1,4 +1,4 @@ -package com.example.application.data.chesscom; +package app.data.chesscom; import java.util.List; diff --git a/src/main/java/com/example/application/data/chesscom/ChessComGame.java b/src/main/java/app/data/chesscom/ChessComGame.java similarity index 98% rename from src/main/java/com/example/application/data/chesscom/ChessComGame.java rename to src/main/java/app/data/chesscom/ChessComGame.java index f7f4262..5fcc4c5 100644 --- a/src/main/java/com/example/application/data/chesscom/ChessComGame.java +++ b/src/main/java/app/data/chesscom/ChessComGame.java @@ -1,4 +1,4 @@ -package com.example.application.data.chesscom; +package app.data.chesscom; public class ChessComGame { private String url; diff --git a/src/main/java/com/example/application/data/entity/Game.java b/src/main/java/app/data/entity/Game.java similarity index 97% rename from src/main/java/com/example/application/data/entity/Game.java rename to src/main/java/app/data/entity/Game.java index 22b18fd..9d0de0b 100644 --- a/src/main/java/com/example/application/data/entity/Game.java +++ b/src/main/java/app/data/entity/Game.java @@ -1,4 +1,4 @@ -package com.example.application.data.entity; +package app.data.entity; import javax.persistence.*; import java.util.Objects; diff --git a/src/main/java/com/example/application/data/entity/GameInfo.java b/src/main/java/app/data/entity/GameInfo.java similarity index 97% rename from src/main/java/com/example/application/data/entity/GameInfo.java rename to src/main/java/app/data/entity/GameInfo.java index 4c73968..48eecef 100644 --- a/src/main/java/com/example/application/data/entity/GameInfo.java +++ b/src/main/java/app/data/entity/GameInfo.java @@ -1,4 +1,4 @@ -package com.example.application.data.entity; +package app.data.entity; import javax.persistence.*; import java.util.Objects; diff --git a/src/main/java/com/example/application/data/entity/Match.java b/src/main/java/app/data/entity/Match.java similarity index 97% rename from src/main/java/com/example/application/data/entity/Match.java rename to src/main/java/app/data/entity/Match.java index 21d21f7..554ac12 100644 --- a/src/main/java/com/example/application/data/entity/Match.java +++ b/src/main/java/app/data/entity/Match.java @@ -1,4 +1,4 @@ -package com.example.application.data.entity; +package app.data.entity; import javax.persistence.*; import java.util.Collection; diff --git a/src/main/java/com/example/application/data/entity/Matchday.java b/src/main/java/app/data/entity/Matchday.java similarity index 97% rename from src/main/java/com/example/application/data/entity/Matchday.java rename to src/main/java/app/data/entity/Matchday.java index f940dcb..f267f28 100644 --- a/src/main/java/com/example/application/data/entity/Matchday.java +++ b/src/main/java/app/data/entity/Matchday.java @@ -1,4 +1,4 @@ -package com.example.application.data.entity; +package app.data.entity; import javax.persistence.*; import java.util.Collection; diff --git a/src/main/java/com/example/application/data/entity/Player.java b/src/main/java/app/data/entity/Player.java similarity index 98% rename from src/main/java/com/example/application/data/entity/Player.java rename to src/main/java/app/data/entity/Player.java index f5e1bf7..8669b90 100644 --- a/src/main/java/com/example/application/data/entity/Player.java +++ b/src/main/java/app/data/entity/Player.java @@ -1,4 +1,4 @@ -package com.example.application.data.entity; +package app.data.entity; import javax.persistence.*; import java.util.Collection; diff --git a/src/main/java/com/example/application/data/entity/PlayerInfo.java b/src/main/java/app/data/entity/PlayerInfo.java similarity index 96% rename from src/main/java/com/example/application/data/entity/PlayerInfo.java rename to src/main/java/app/data/entity/PlayerInfo.java index 034d2a1..45adaf4 100644 --- a/src/main/java/com/example/application/data/entity/PlayerInfo.java +++ b/src/main/java/app/data/entity/PlayerInfo.java @@ -1,4 +1,4 @@ -package com.example.application.data.entity; +package app.data.entity; import javax.persistence.*; import java.util.Objects; diff --git a/src/main/java/com/example/application/data/entity/SampleAddress.java b/src/main/java/app/data/entity/SampleAddress.java similarity index 90% rename from src/main/java/com/example/application/data/entity/SampleAddress.java rename to src/main/java/app/data/entity/SampleAddress.java index 9dcea51..59e69e9 100644 --- a/src/main/java/com/example/application/data/entity/SampleAddress.java +++ b/src/main/java/app/data/entity/SampleAddress.java @@ -1,6 +1,6 @@ -package com.example.application.data.entity; +package app.data.entity; -import com.example.application.data.AbstractEntity; +import app.data.AbstractEntity; import javax.persistence.Entity; diff --git a/src/main/java/com/example/application/data/entity/SamplePerson.java b/src/main/java/app/data/entity/SamplePerson.java similarity index 93% rename from src/main/java/com/example/application/data/entity/SamplePerson.java rename to src/main/java/app/data/entity/SamplePerson.java index 0dce05b..40204be 100644 --- a/src/main/java/com/example/application/data/entity/SamplePerson.java +++ b/src/main/java/app/data/entity/SamplePerson.java @@ -1,6 +1,6 @@ -package com.example.application.data.entity; +package app.data.entity; -import com.example.application.data.AbstractEntity; +import app.data.AbstractEntity; import javax.persistence.Entity; import java.time.LocalDate; diff --git a/src/main/java/com/example/application/data/entity/Season.java b/src/main/java/app/data/entity/Season.java similarity index 97% rename from src/main/java/com/example/application/data/entity/Season.java rename to src/main/java/app/data/entity/Season.java index ecaac56..0dad9b7 100644 --- a/src/main/java/com/example/application/data/entity/Season.java +++ b/src/main/java/app/data/entity/Season.java @@ -1,4 +1,4 @@ -package com.example.application.data.entity; +package app.data.entity; import javax.persistence.*; import java.util.Collection; diff --git a/src/main/java/com/example/application/data/generator/DataGenerator.java b/src/main/java/app/data/generator/DataGenerator.java similarity index 94% rename from src/main/java/com/example/application/data/generator/DataGenerator.java rename to src/main/java/app/data/generator/DataGenerator.java index 9aab05f..10a3b61 100644 --- a/src/main/java/com/example/application/data/generator/DataGenerator.java +++ b/src/main/java/app/data/generator/DataGenerator.java @@ -1,6 +1,6 @@ -package com.example.application.data.generator; +package app.data.generator; -import com.example.application.data.service.SamplePersonRepository; +import app.data.service.SamplePersonRepository; import com.vaadin.flow.spring.annotation.SpringComponent; import org.springframework.boot.CommandLineRunner; import org.springframework.context.annotation.Bean; diff --git a/src/main/java/app/data/service/ChessComService.java b/src/main/java/app/data/service/ChessComService.java new file mode 100644 index 0000000..80ce226 --- /dev/null +++ b/src/main/java/app/data/service/ChessComService.java @@ -0,0 +1,142 @@ +package app.data.service; + +import app.data.chesscom.ChessComArchive; +import app.data.chesscom.ChessComArchiveList; +import app.data.chesscom.ChessComGame; +import app.data.entity.Game; +import app.data.entity.GameInfo; +import app.data.entity.Match; +import app.data.entity.Player; +import app.utils.ChessComUtils; +import app.utils.HttpUtils; +import com.google.gson.Gson; +import org.springframework.lang.NonNull; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@Service +public class ChessComService { + // TODO: make everything nullsafe + + private static final Gson gson = new Gson(); + private static final String ARCHIVES_ENDPOINT = "https://api.chess.com/pub/player/{username}/games/archives"; + + public ChessComService() { + } + + @NonNull + public List getLatestGamesBetweenPlayers(@NonNull Match match, int minAmountOfGames, int maxAmountOfMonths) { + List list = new ArrayList<>(); + for (String archiveUrl : getLatestArchiveUrls(match.getPlayer1(), maxAmountOfMonths)) { + list.addAll(getChessComGames(archiveUrl).stream() + .sorted(Comparator.comparingLong(ChessComGame::getEndTime).reversed()) + .filter(chessComGame -> ChessComUtils.isGameBetweenPlayers(chessComGame, match)) + .filter(ChessComUtils::hasValidTimeControl) + .map(chessComGame -> createGame(chessComGame, match)) + .collect(Collectors.toList())); + + if (list.size() >= minAmountOfGames) { + break; + } + } + return list; + } // TODO: find exactly two games of each time control + + private List getChessComGames(String archiveUrl) { + List list = new ArrayList<>(); + getChessComArchive(archiveUrl).ifPresent(chessComArchive -> list.addAll(chessComArchive.getGames())); + return list; + } + + private Optional getChessComArchive(String archiveUrl) { + String unpreparedJson = HttpUtils.getJson(archiveUrl); + if (unpreparedJson == null) { + return Optional.empty(); + } + String preparedJson = ChessComUtils.getPreparedArchiveJson(unpreparedJson); + return Optional.of(gson.fromJson(preparedJson, ChessComArchive.class)); + } + + private List getLatestArchiveUrls(@NonNull Player player, int maxAmountOfMonths) { + List archiveUrls = getArchiveUrls(player); + if (archiveUrls.size() >= maxAmountOfMonths) { + archiveUrls = archiveUrls.subList(0, maxAmountOfMonths); + } + return archiveUrls; + } + + private List getArchiveUrls(@NonNull Player player) { + String endPoint = ARCHIVES_ENDPOINT.replace("{username}", ChessComUtils.getUsernameForUrl(player)); + + List archiveUrls = gson.fromJson(HttpUtils.getJson(endPoint), ChessComArchiveList.class).getArchives(); + archiveUrls.sort(Collections.reverseOrder()); + return archiveUrls; + } + + @NonNull + private Game createGame(@NonNull ChessComGame chessComGame, @NonNull Match match) { + Game game = new Game(); + GameInfo gameInfo = new GameInfo(); + + game.setMatch(match); + game.setPlayer1IsWhite(chessComGame.getWhite().getUsername().equals(match.getPlayer1().getNickname())); + game.setResult(ChessComUtils.getResult(chessComGame)); + game.setGameInfo(gameInfo); + + gameInfo.setUrl(chessComGame.getUrl()); + gameInfo.setTimeControl(chessComGame.getTimeControl()); + gameInfo.setGame(game); + + return game; + } + + public Optional getChessComGame(@NonNull Game game) { + return getChessComGame(game, game.getMatch().getPlayer1()) + .or(() -> getChessComGame(game, game.getMatch().getPlayer2())); + } + + private Optional getChessComGame(@NonNull Game game, Player player) { + if (!(game.getMatch().getPlayer1().equals(player) || game.getMatch().getPlayer2().equals(player))) { + throw new IllegalArgumentException("Player must be participating in Game!"); + } + for (String archiveUrl : getArchiveUrls(player)) { + Optional chessComArchive = getChessComArchive(archiveUrl); + if (chessComArchive.isEmpty()) { + continue; + } + List chessComGames = chessComArchive.get().getGames(); + for (ChessComGame chessComGame : chessComGames) { + if (chessComGame.getUrl().equals(game.getGameInfo().getUrl())) { + return Optional.of(chessComGame); + } + } + } + return Optional.empty(); + } +// return getArchiveUrls(player).stream() +// .map(this::getChessComArchive) +// .flatMap(chessComArchive -> chessComArchive.orElseThrow().getGames().stream()) +// .filter(chessComGame -> chessComGame.getUrl().equals(game.getGameInfo().getUrl())) +// .findFirst(); + +// .forEach(g -> g +// .filter(chessComGame -> chessComGame.getUrl().equals(game.getGameInfo().getUrl()))) +// .findFirst(); +// } +// private Optional getChessComGame(@NonNull Game game, Player player) { +// if (!(game.getMatch().getPlayer1().equals(player) || game.getMatch().getPlayer2().equals(player))) { +// throw new IllegalArgumentException("Player must be participating in Game!"); +// } +// return getArchiveUrls(player).stream() +// .map(this::getChessComArchive) +// .flatMap((Function, Stream>) +// chessComArchive -> chessComArchive.stream() +// .flatMap(archive -> archive.getGames().stream())) +// .filter(chessComGame -> chessComGame.getUrl().equals(game.getGameInfo().getUrl())) +// .findFirst(); +// } +} diff --git a/src/main/java/com/example/application/data/service/GameInfoRepository.java b/src/main/java/app/data/service/GameInfoRepository.java similarity index 59% rename from src/main/java/com/example/application/data/service/GameInfoRepository.java rename to src/main/java/app/data/service/GameInfoRepository.java index 562fbf8..37e945a 100644 --- a/src/main/java/com/example/application/data/service/GameInfoRepository.java +++ b/src/main/java/app/data/service/GameInfoRepository.java @@ -1,6 +1,6 @@ -package com.example.application.data.service; +package app.data.service; -import com.example.application.data.entity.GameInfo; +import app.data.entity.GameInfo; import org.springframework.data.jpa.repository.JpaRepository; public interface GameInfoRepository extends JpaRepository { diff --git a/src/main/java/com/example/application/data/service/GameInfoService.java b/src/main/java/app/data/service/GameInfoService.java similarity index 83% rename from src/main/java/com/example/application/data/service/GameInfoService.java rename to src/main/java/app/data/service/GameInfoService.java index 1c04470..c0f4d72 100644 --- a/src/main/java/com/example/application/data/service/GameInfoService.java +++ b/src/main/java/app/data/service/GameInfoService.java @@ -1,6 +1,6 @@ -package com.example.application.data.service; +package app.data.service; -import com.example.application.data.entity.GameInfo; +import app.data.entity.GameInfo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.vaadin.artur.helpers.CrudService; diff --git a/src/main/java/com/example/application/data/service/GameRepository.java b/src/main/java/app/data/service/GameRepository.java similarity index 59% rename from src/main/java/com/example/application/data/service/GameRepository.java rename to src/main/java/app/data/service/GameRepository.java index 54dc4f6..fca7b4e 100644 --- a/src/main/java/com/example/application/data/service/GameRepository.java +++ b/src/main/java/app/data/service/GameRepository.java @@ -1,6 +1,6 @@ -package com.example.application.data.service; +package app.data.service; -import com.example.application.data.entity.Game; +import app.data.entity.Game; import org.springframework.data.jpa.repository.JpaRepository; public interface GameRepository extends JpaRepository { diff --git a/src/main/java/com/example/application/data/service/GameService.java b/src/main/java/app/data/service/GameService.java similarity index 83% rename from src/main/java/com/example/application/data/service/GameService.java rename to src/main/java/app/data/service/GameService.java index 2f985bb..6c77908 100644 --- a/src/main/java/com/example/application/data/service/GameService.java +++ b/src/main/java/app/data/service/GameService.java @@ -1,6 +1,6 @@ -package com.example.application.data.service; +package app.data.service; -import com.example.application.data.entity.Game; +import app.data.entity.Game; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.vaadin.artur.helpers.CrudService; diff --git a/src/main/java/com/example/application/data/service/MatchRepository.java b/src/main/java/app/data/service/MatchRepository.java similarity index 59% rename from src/main/java/com/example/application/data/service/MatchRepository.java rename to src/main/java/app/data/service/MatchRepository.java index da42e7f..7fb0627 100644 --- a/src/main/java/com/example/application/data/service/MatchRepository.java +++ b/src/main/java/app/data/service/MatchRepository.java @@ -1,6 +1,6 @@ -package com.example.application.data.service; +package app.data.service; -import com.example.application.data.entity.Match; +import app.data.entity.Match; import org.springframework.data.jpa.repository.JpaRepository; public interface MatchRepository extends JpaRepository { diff --git a/src/main/java/com/example/application/data/service/MatchService.java b/src/main/java/app/data/service/MatchService.java similarity index 88% rename from src/main/java/com/example/application/data/service/MatchService.java rename to src/main/java/app/data/service/MatchService.java index a6d6bb7..3f9a67c 100644 --- a/src/main/java/com/example/application/data/service/MatchService.java +++ b/src/main/java/app/data/service/MatchService.java @@ -1,9 +1,9 @@ -package com.example.application.data.service; +package app.data.service; -import com.example.application.data.bean.CalculatedMatch; -import com.example.application.data.entity.Game; -import com.example.application.data.entity.Match; -import com.example.application.data.entity.Matchday; +import app.data.bean.CalculatedMatch; +import app.data.entity.Game; +import app.data.entity.Match; +import app.data.entity.Matchday; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.vaadin.artur.helpers.CrudService; diff --git a/src/main/java/com/example/application/data/service/MatchdayRepository.java b/src/main/java/app/data/service/MatchdayRepository.java similarity index 59% rename from src/main/java/com/example/application/data/service/MatchdayRepository.java rename to src/main/java/app/data/service/MatchdayRepository.java index 5f69e62..a37a153 100644 --- a/src/main/java/com/example/application/data/service/MatchdayRepository.java +++ b/src/main/java/app/data/service/MatchdayRepository.java @@ -1,6 +1,6 @@ -package com.example.application.data.service; +package app.data.service; -import com.example.application.data.entity.Matchday; +import app.data.entity.Matchday; import org.springframework.data.jpa.repository.JpaRepository; public interface MatchdayRepository extends JpaRepository { diff --git a/src/main/java/com/example/application/data/service/MatchdayService.java b/src/main/java/app/data/service/MatchdayService.java similarity index 93% rename from src/main/java/com/example/application/data/service/MatchdayService.java rename to src/main/java/app/data/service/MatchdayService.java index 88e1aff..7310055 100644 --- a/src/main/java/com/example/application/data/service/MatchdayService.java +++ b/src/main/java/app/data/service/MatchdayService.java @@ -1,7 +1,7 @@ -package com.example.application.data.service; +package app.data.service; -import com.example.application.data.entity.Matchday; -import com.example.application.data.entity.Season; +import app.data.entity.Matchday; +import app.data.entity.Season; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.lang.NonNull; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/example/application/data/service/PlayerInfoRepository.java b/src/main/java/app/data/service/PlayerInfoRepository.java similarity index 59% rename from src/main/java/com/example/application/data/service/PlayerInfoRepository.java rename to src/main/java/app/data/service/PlayerInfoRepository.java index 69881e0..005f13f 100644 --- a/src/main/java/com/example/application/data/service/PlayerInfoRepository.java +++ b/src/main/java/app/data/service/PlayerInfoRepository.java @@ -1,6 +1,6 @@ -package com.example.application.data.service; +package app.data.service; -import com.example.application.data.entity.PlayerInfo; +import app.data.entity.PlayerInfo; import org.springframework.data.jpa.repository.JpaRepository; public interface PlayerInfoRepository extends JpaRepository { diff --git a/src/main/java/com/example/application/data/service/PlayerInfoService.java b/src/main/java/app/data/service/PlayerInfoService.java similarity index 83% rename from src/main/java/com/example/application/data/service/PlayerInfoService.java rename to src/main/java/app/data/service/PlayerInfoService.java index 07b4b0f..7c0b756 100644 --- a/src/main/java/com/example/application/data/service/PlayerInfoService.java +++ b/src/main/java/app/data/service/PlayerInfoService.java @@ -1,6 +1,6 @@ -package com.example.application.data.service; +package app.data.service; -import com.example.application.data.entity.PlayerInfo; +import app.data.entity.PlayerInfo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.vaadin.artur.helpers.CrudService; diff --git a/src/main/java/com/example/application/data/service/PlayerRepository.java b/src/main/java/app/data/service/PlayerRepository.java similarity index 59% rename from src/main/java/com/example/application/data/service/PlayerRepository.java rename to src/main/java/app/data/service/PlayerRepository.java index a6e7bc5..2a9414b 100644 --- a/src/main/java/com/example/application/data/service/PlayerRepository.java +++ b/src/main/java/app/data/service/PlayerRepository.java @@ -1,6 +1,6 @@ -package com.example.application.data.service; +package app.data.service; -import com.example.application.data.entity.Player; +import app.data.entity.Player; import org.springframework.data.jpa.repository.JpaRepository; public interface PlayerRepository extends JpaRepository { diff --git a/src/main/java/com/example/application/data/service/PlayerService.java b/src/main/java/app/data/service/PlayerService.java similarity index 96% rename from src/main/java/com/example/application/data/service/PlayerService.java rename to src/main/java/app/data/service/PlayerService.java index 8626cbb..f17bbbd 100644 --- a/src/main/java/com/example/application/data/service/PlayerService.java +++ b/src/main/java/app/data/service/PlayerService.java @@ -1,9 +1,9 @@ -package com.example.application.data.service; +package app.data.service; -import com.example.application.data.bean.CalculatedMatch; -import com.example.application.data.bean.PlayerForTable; -import com.example.application.data.entity.Matchday; -import com.example.application.data.entity.Player; +import app.data.bean.CalculatedMatch; +import app.data.bean.PlayerForTable; +import app.data.entity.Matchday; +import app.data.entity.Player; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.vaadin.artur.helpers.CrudService; diff --git a/src/main/java/com/example/application/data/service/SampleAddressRepository.java b/src/main/java/app/data/service/SampleAddressRepository.java similarity index 59% rename from src/main/java/com/example/application/data/service/SampleAddressRepository.java rename to src/main/java/app/data/service/SampleAddressRepository.java index f33b1c4..39a7483 100644 --- a/src/main/java/com/example/application/data/service/SampleAddressRepository.java +++ b/src/main/java/app/data/service/SampleAddressRepository.java @@ -1,6 +1,6 @@ -package com.example.application.data.service; +package app.data.service; -import com.example.application.data.entity.SampleAddress; +import app.data.entity.SampleAddress; import org.springframework.data.jpa.repository.JpaRepository; public interface SampleAddressRepository extends JpaRepository { diff --git a/src/main/java/com/example/application/data/service/SampleAddressService.java b/src/main/java/app/data/service/SampleAddressService.java similarity index 83% rename from src/main/java/com/example/application/data/service/SampleAddressService.java rename to src/main/java/app/data/service/SampleAddressService.java index fb183b8..7dd8149 100644 --- a/src/main/java/com/example/application/data/service/SampleAddressService.java +++ b/src/main/java/app/data/service/SampleAddressService.java @@ -1,6 +1,6 @@ -package com.example.application.data.service; +package app.data.service; -import com.example.application.data.entity.SampleAddress; +import app.data.entity.SampleAddress; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.vaadin.artur.helpers.CrudService; diff --git a/src/main/java/com/example/application/data/service/SamplePersonRepository.java b/src/main/java/app/data/service/SamplePersonRepository.java similarity index 59% rename from src/main/java/com/example/application/data/service/SamplePersonRepository.java rename to src/main/java/app/data/service/SamplePersonRepository.java index 59dbfb1..076f29c 100644 --- a/src/main/java/com/example/application/data/service/SamplePersonRepository.java +++ b/src/main/java/app/data/service/SamplePersonRepository.java @@ -1,6 +1,6 @@ -package com.example.application.data.service; +package app.data.service; -import com.example.application.data.entity.SamplePerson; +import app.data.entity.SamplePerson; import org.springframework.data.jpa.repository.JpaRepository; public interface SamplePersonRepository extends JpaRepository { diff --git a/src/main/java/com/example/application/data/service/SamplePersonService.java b/src/main/java/app/data/service/SamplePersonService.java similarity index 83% rename from src/main/java/com/example/application/data/service/SamplePersonService.java rename to src/main/java/app/data/service/SamplePersonService.java index 34eccee..f12a5c5 100644 --- a/src/main/java/com/example/application/data/service/SamplePersonService.java +++ b/src/main/java/app/data/service/SamplePersonService.java @@ -1,6 +1,6 @@ -package com.example.application.data.service; +package app.data.service; -import com.example.application.data.entity.SamplePerson; +import app.data.entity.SamplePerson; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.vaadin.artur.helpers.CrudService; diff --git a/src/main/java/com/example/application/data/service/SeasonRepository.java b/src/main/java/app/data/service/SeasonRepository.java similarity index 59% rename from src/main/java/com/example/application/data/service/SeasonRepository.java rename to src/main/java/app/data/service/SeasonRepository.java index f667a39..a49a594 100644 --- a/src/main/java/com/example/application/data/service/SeasonRepository.java +++ b/src/main/java/app/data/service/SeasonRepository.java @@ -1,6 +1,6 @@ -package com.example.application.data.service; +package app.data.service; -import com.example.application.data.entity.Season; +import app.data.entity.Season; import org.springframework.data.jpa.repository.JpaRepository; public interface SeasonRepository extends JpaRepository { diff --git a/src/main/java/com/example/application/data/service/SeasonService.java b/src/main/java/app/data/service/SeasonService.java similarity index 93% rename from src/main/java/com/example/application/data/service/SeasonService.java rename to src/main/java/app/data/service/SeasonService.java index 4b70688..24c2974 100644 --- a/src/main/java/com/example/application/data/service/SeasonService.java +++ b/src/main/java/app/data/service/SeasonService.java @@ -1,6 +1,6 @@ -package com.example.application.data.service; +package app.data.service; -import com.example.application.data.entity.Season; +import app.data.entity.Season; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.vaadin.artur.helpers.CrudService; diff --git a/src/main/java/app/image/ImageGenerator.java b/src/main/java/app/image/ImageGenerator.java new file mode 100644 index 0000000..4759658 --- /dev/null +++ b/src/main/java/app/image/ImageGenerator.java @@ -0,0 +1,75 @@ +package app.image; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.util.Objects; +import java.util.Set; + +public class ImageGenerator { + + private static final int FIELD_SIZE = 150; + private static final Set WHITE_PIECES = Set.of('B', 'K', 'N', 'P', 'Q', 'R'); + private static final Set BLACK_PIECES = Set.of('b', 'k', 'n', 'p', 'q', 'r'); + private static final Set BLANKS = Set.of('1', '2', '3', '4', '5', '6', '7', '8'); + private static final Character ROW_DELIMITER = '/'; + + private ImageGenerator() {} + + public static BufferedImage generateImage(String fen) { + BufferedImage image = app.image.ImageUtils.readImage("board"); + Graphics2D g = image.createGraphics(); + g.drawImage(image, 0, 0, null); + + int x = 0; + int y = 0; + for (Character c : fen.split(" ")[0].toCharArray()) { + if (isPiece(c)) { + g.drawImage(app.image.ImageUtils.readImage(getFilename(c)), x * FIELD_SIZE, y * FIELD_SIZE, null); + x += 1; + continue; + } + if (isRowDelimiter(c)) { + x = 0; + y += 1; + continue; + } + if (isBlank(c)) { + x += Character.getNumericValue(c); + continue; + } + throw new IllegalArgumentException("FEN is invalid!"); + } + g.dispose(); + return image; + } + + private static boolean isBlank(Character c) { + return BLANKS.contains(c); + } + + private static boolean isRowDelimiter(Character c) { + return Objects.equals(c, ROW_DELIMITER); + } + + private static boolean isPiece(Character c) { + return isWhite(c) || isBlack(c); + } + + private static boolean isWhite(Character c) { + return WHITE_PIECES.contains(c); + } + + private static boolean isBlack(Character c) { + return BLACK_PIECES.contains(c); + } + + private static String getFilename(Character piece) { + if (isWhite(piece)) { + return "w" + piece.toString().toLowerCase(); + } + if (isBlack(piece)) { + return "b" + piece.toString(); + } + throw new IllegalArgumentException("Character must represent a piece!"); + } +} diff --git a/src/main/java/app/image/ImageService.java b/src/main/java/app/image/ImageService.java new file mode 100644 index 0000000..ba042e0 --- /dev/null +++ b/src/main/java/app/image/ImageService.java @@ -0,0 +1,48 @@ +package app.image; + +import app.data.chesscom.ChessComGame; +import app.data.entity.Game; +import app.data.service.ChessComService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.io.File; +import java.util.Optional; + +@Service +public class ImageService { + + private final ChessComService chessComService; + + public ImageService(@Autowired ChessComService chessComService) { + this.chessComService = chessComService; + } + + public Optional getVaadinImagePath(Game game) { + return getImagePath(game).map(path -> path.replace("src/main/resources/META-INF/resources/", "")); + } + + public Optional getImagePath(Game game) { + String path = ImageUtils.IMAGE_DEST_PATH + getGameNumber(game) + ImageUtils.EXTENSION; + File f = new File(path); + if(f.isFile()) { + return Optional.of(path); + } + Optional optionalFen = getFen(game); + + if (optionalFen.isPresent()) { + ImageUtils.writeImage(ImageGenerator.generateImage(optionalFen.get()), getGameNumber(game)); + return Optional.of(path); + } + return Optional.empty(); + } + + private String getGameNumber(Game game) { + String[] url = game.getGameInfo().getUrl().split("/"); + return url[url.length -1]; + } + + private Optional getFen(Game game) { + return chessComService.getChessComGame(game).map(ChessComGame::getFen); + } +} diff --git a/src/main/java/app/image/ImageUtils.java b/src/main/java/app/image/ImageUtils.java new file mode 100644 index 0000000..67f0960 --- /dev/null +++ b/src/main/java/app/image/ImageUtils.java @@ -0,0 +1,36 @@ +package app.image; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +public class ImageUtils { + public static final String IMAGE_SOURCE_PATH = "src/main/resources/META-INF/resources/images/chess-sources/"; + public static final String IMAGE_DEST_PATH = "src/main/resources/META-INF/resources/images/games/"; + public static final String EXTENSION = ".png"; + private static final String EXTENSION_WITHOUT_DOT = "png"; + + private ImageUtils() {} + + public static BufferedImage readImage(String fileNameWithoutExtension) { + BufferedImage img = null; + try { + String path = IMAGE_SOURCE_PATH + fileNameWithoutExtension + EXTENSION; + img = ImageIO.read(new File(path)); + } catch (IOException e) { + e.printStackTrace(); + } + return img; + } + + public static void writeImage(BufferedImage img, String fileNameWithoutExtension) { + try { + String path = IMAGE_DEST_PATH + fileNameWithoutExtension + EXTENSION; + File outputFile = new File(path); + ImageIO.write(img, EXTENSION_WITHOUT_DOT, outputFile); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/example/application/navigation/Navigation.java b/src/main/java/app/navigation/Navigation.java similarity index 97% rename from src/main/java/com/example/application/navigation/Navigation.java rename to src/main/java/app/navigation/Navigation.java index b3eafe5..eb21db6 100644 --- a/src/main/java/com/example/application/navigation/Navigation.java +++ b/src/main/java/app/navigation/Navigation.java @@ -1,11 +1,11 @@ -package com.example.application.navigation; - -import com.example.application.data.entity.Match; -import com.example.application.data.entity.Matchday; -import com.example.application.data.entity.Season; -import com.example.application.data.service.MatchService; -import com.example.application.data.service.MatchdayService; -import com.example.application.data.service.SeasonService; +package app.navigation; + +import app.data.entity.Match; +import app.data.entity.Matchday; +import app.data.entity.Season; +import app.data.service.MatchService; +import app.data.service.MatchdayService; +import app.data.service.SeasonService; import com.vaadin.flow.component.*; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.html.Label; diff --git a/src/main/java/com/example/application/navigation/NavigationUtils.java b/src/main/java/app/navigation/NavigationUtils.java similarity index 92% rename from src/main/java/com/example/application/navigation/NavigationUtils.java rename to src/main/java/app/navigation/NavigationUtils.java index 980e081..2698e93 100644 --- a/src/main/java/com/example/application/navigation/NavigationUtils.java +++ b/src/main/java/app/navigation/NavigationUtils.java @@ -1,8 +1,7 @@ -package com.example.application.navigation; +package app.navigation; import com.vaadin.flow.router.WildcardParameter; import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/com/example/application/navigation/UrlParameterType.java b/src/main/java/app/navigation/UrlParameterType.java similarity index 61% rename from src/main/java/com/example/application/navigation/UrlParameterType.java rename to src/main/java/app/navigation/UrlParameterType.java index 7c9b347..9e74c9f 100644 --- a/src/main/java/com/example/application/navigation/UrlParameterType.java +++ b/src/main/java/app/navigation/UrlParameterType.java @@ -1,4 +1,4 @@ -package com.example.application.navigation; +package app.navigation; public enum UrlParameterType { SEASON, diff --git a/src/main/java/com/example/application/utils/ChessComUtils.java b/src/main/java/app/utils/ChessComUtils.java similarity index 75% rename from src/main/java/com/example/application/utils/ChessComUtils.java rename to src/main/java/app/utils/ChessComUtils.java index 2e027c4..c1364de 100644 --- a/src/main/java/com/example/application/utils/ChessComUtils.java +++ b/src/main/java/app/utils/ChessComUtils.java @@ -1,7 +1,8 @@ -package com.example.application.utils; +package app.utils; -import com.example.application.data.chesscom.ChessComGame; -import com.example.application.data.entity.Player; +import app.data.chesscom.ChessComGame; +import app.data.entity.Match; +import app.data.entity.Player; import org.springframework.lang.NonNull; public class ChessComUtils { @@ -15,7 +16,7 @@ public class ChessComUtils { .replace("time_control", "timeControl"); } - public static String getUrlPart(Player player) { + public static String getUsernameForUrl(Player player) { return player.getNickname().toLowerCase(); } @@ -29,11 +30,11 @@ public class ChessComUtils { return 0; } - public static boolean isGameBetween(@NonNull ChessComGame game, @NonNull Player player1, @NonNull Player player2) { + public static boolean isGameBetweenPlayers(@NonNull ChessComGame game, @NonNull Match match) { String white = game.getWhite().getUsername(); String black = game.getBlack().getUsername(); - String name1 = player1.getNickname(); - String name2 = player2.getNickname(); + String name1 = match.getPlayer1().getNickname(); + String name2 = match.getPlayer2().getNickname(); return (white.equals(name1) || white.equals(name2)) && (black.equals(name1) || black.equals(name2)); } diff --git a/src/main/java/com/example/application/utils/HttpUtils.java b/src/main/java/app/utils/HttpUtils.java similarity index 96% rename from src/main/java/com/example/application/utils/HttpUtils.java rename to src/main/java/app/utils/HttpUtils.java index f66e2a2..c78a8f3 100644 --- a/src/main/java/com/example/application/utils/HttpUtils.java +++ b/src/main/java/app/utils/HttpUtils.java @@ -1,4 +1,4 @@ -package com.example.application.utils; +package app.utils; import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; diff --git a/src/main/java/com/example/application/utils/StringUtils.java b/src/main/java/app/utils/StringUtils.java similarity index 97% rename from src/main/java/com/example/application/utils/StringUtils.java rename to src/main/java/app/utils/StringUtils.java index 54c8376..49be410 100644 --- a/src/main/java/com/example/application/utils/StringUtils.java +++ b/src/main/java/app/utils/StringUtils.java @@ -1,4 +1,4 @@ -package com.example.application.utils; +package app.utils; import org.apache.commons.lang3.RandomStringUtils; diff --git a/src/main/java/com/example/application/utils/VaadinUtils.java b/src/main/java/app/utils/VaadinUtils.java similarity index 93% rename from src/main/java/com/example/application/utils/VaadinUtils.java rename to src/main/java/app/utils/VaadinUtils.java index cba308a..b41978c 100644 --- a/src/main/java/com/example/application/utils/VaadinUtils.java +++ b/src/main/java/app/utils/VaadinUtils.java @@ -1,6 +1,6 @@ -package com.example.application.utils; +package app.utils; -import com.example.application.data.entity.Player; +import app.data.entity.Player; import com.vaadin.flow.data.renderer.TemplateRenderer; import com.vaadin.flow.function.ValueProvider; diff --git a/src/main/java/com/example/application/views/about/AboutView.java b/src/main/java/app/views/about/AboutView.java similarity index 86% rename from src/main/java/com/example/application/views/about/AboutView.java rename to src/main/java/app/views/about/AboutView.java index bcdcc7e..2b44756 100644 --- a/src/main/java/com/example/application/views/about/AboutView.java +++ b/src/main/java/app/views/about/AboutView.java @@ -1,14 +1,14 @@ -package com.example.application.views.about; +package app.views.about; -import com.example.application.data.service.GameService; -import com.example.application.views.main.MainView; +import app.data.service.GameService; +import app.views.main.MainView; import com.vaadin.flow.component.Text; import com.vaadin.flow.component.dependency.CssImport; import com.vaadin.flow.component.html.Div; import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; -@CssImport("./views/about/about-view.css") +@CssImport("app/views/about/about-view.css") @Route(value = "about", layout = MainView.class) @PageTitle("About") public class AboutView extends Div { diff --git a/src/main/java/com/example/application/views/addressform/AddressFormView.java b/src/main/java/app/views/addressform/AddressFormView.java similarity index 90% rename from src/main/java/com/example/application/views/addressform/AddressFormView.java rename to src/main/java/app/views/addressform/AddressFormView.java index 81c889f..a53f562 100644 --- a/src/main/java/com/example/application/views/addressform/AddressFormView.java +++ b/src/main/java/app/views/addressform/AddressFormView.java @@ -1,8 +1,8 @@ -package com.example.application.views.addressform; +package app.views.addressform; -import com.example.application.data.entity.SampleAddress; -import com.example.application.data.service.SampleAddressService; -import com.example.application.views.main.MainView; +import app.data.entity.SampleAddress; +import app.data.service.SampleAddressService; +import app.views.main.MainView; import com.vaadin.flow.component.Component; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.button.ButtonVariant; @@ -18,7 +18,7 @@ import com.vaadin.flow.data.binder.Binder; import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; -@CssImport("./views/addressform/address-form-view.css") +@CssImport("app/views/addressform/address-form-view.css") @Route(value = "address-form", layout = MainView.class) @PageTitle("Address Form") public class AddressFormView extends Div { diff --git a/src/main/java/com/example/application/views/cardlist/CardListView.java b/src/main/java/app/views/cardlist/CardListView.java similarity index 98% rename from src/main/java/com/example/application/views/cardlist/CardListView.java rename to src/main/java/app/views/cardlist/CardListView.java index ef6ebf9..d3134c7 100644 --- a/src/main/java/com/example/application/views/cardlist/CardListView.java +++ b/src/main/java/app/views/cardlist/CardListView.java @@ -1,6 +1,6 @@ -package com.example.application.views.cardlist; +package app.views.cardlist; -import com.example.application.views.main.MainView; +import app.views.main.MainView; import com.vaadin.flow.component.dependency.CssImport; import com.vaadin.flow.component.grid.Grid; import com.vaadin.flow.component.grid.GridVariant; @@ -18,7 +18,7 @@ import com.vaadin.flow.router.Route; import java.util.Arrays; import java.util.List; -@CssImport("./views/cardlist/card-list-view.css") +@CssImport("app/views/cardlist/card-list-view.css") @Route(value = "card-list", layout = MainView.class) @PageTitle("Card List") public class CardListView extends Div implements AfterNavigationObserver { diff --git a/src/main/java/com/example/application/views/cardlist/Person.java b/src/main/java/app/views/cardlist/Person.java similarity index 96% rename from src/main/java/com/example/application/views/cardlist/Person.java rename to src/main/java/app/views/cardlist/Person.java index d4a40ef..9e1a9f8 100644 --- a/src/main/java/com/example/application/views/cardlist/Person.java +++ b/src/main/java/app/views/cardlist/Person.java @@ -1,4 +1,4 @@ -package com.example.application.views.cardlist; +package app.views.cardlist; public class Person { diff --git a/src/main/java/com/example/application/views/creditcardform/CreditCardFormView.java b/src/main/java/app/views/creditcardform/CreditCardFormView.java similarity index 95% rename from src/main/java/com/example/application/views/creditcardform/CreditCardFormView.java rename to src/main/java/app/views/creditcardform/CreditCardFormView.java index e1d4f6e..2b4b1ae 100644 --- a/src/main/java/com/example/application/views/creditcardform/CreditCardFormView.java +++ b/src/main/java/app/views/creditcardform/CreditCardFormView.java @@ -1,6 +1,6 @@ -package com.example.application.views.creditcardform; +package app.views.creditcardform; -import com.example.application.views.main.MainView; +import app.views.main.MainView; import com.vaadin.flow.component.Component; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.button.ButtonVariant; @@ -17,7 +17,7 @@ import com.vaadin.flow.component.textfield.TextField; import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; -@CssImport("./views/creditcardform/credit-card-form-view.css") +@CssImport("app/views/creditcardform/credit-card-form-view.css") @Route(value = "credit-card-form", layout = MainView.class) @PageTitle("Credit Card Form") public class CreditCardFormView extends Div { diff --git a/src/main/java/com/example/application/views/helloworld/HelloWorldView.java b/src/main/java/app/views/helloworld/HelloWorldView.java similarity index 85% rename from src/main/java/com/example/application/views/helloworld/HelloWorldView.java rename to src/main/java/app/views/helloworld/HelloWorldView.java index fbdde75..92179c7 100644 --- a/src/main/java/com/example/application/views/helloworld/HelloWorldView.java +++ b/src/main/java/app/views/helloworld/HelloWorldView.java @@ -1,6 +1,6 @@ -package com.example.application.views.helloworld; +package app.views.helloworld; -import com.example.application.views.main.MainView; +import app.views.main.MainView; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.dependency.CssImport; import com.vaadin.flow.component.notification.Notification; @@ -9,7 +9,7 @@ import com.vaadin.flow.component.textfield.TextField; import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; -@CssImport("./views/helloworld/hello-world-view.css") +@CssImport("app/views/helloworld/hello-world-view.css") @Route(value = "hello", layout = MainView.class) @PageTitle("Hello World") public class HelloWorldView extends HorizontalLayout { diff --git a/src/main/java/com/example/application/views/main/MainView.java b/src/main/java/app/views/main/MainView.java similarity index 94% rename from src/main/java/com/example/application/views/main/MainView.java rename to src/main/java/app/views/main/MainView.java index 4c9f85f..e2d9693 100644 --- a/src/main/java/com/example/application/views/main/MainView.java +++ b/src/main/java/app/views/main/MainView.java @@ -1,7 +1,8 @@ -package com.example.application.views.main; +package app.views.main; -import com.example.application.views.results.ResultsView; -import com.example.application.views.table.TableView; +import app.views.cardlist.CardListView; +import app.views.results.ResultsView; +import app.views.table.TableView; import com.vaadin.flow.component.Component; import com.vaadin.flow.component.ComponentUtil; import com.vaadin.flow.component.applayout.AppLayout; @@ -25,9 +26,9 @@ import com.vaadin.flow.theme.lumo.Lumo; import java.util.Optional; /** - * The main view is a top-level placeholder for other views. + * The main view is a top-level placeholder for other chessleague.views. */ -@CssImport("./views/main/main-view.css") +@CssImport("app/views/main/main-view.css") @PWA(name = "Schachliga DACH", shortName = "Schachliga DACH", iconPath = "images/logo.png", diff --git a/src/main/java/com/example/application/views/map/MapView.java b/src/main/java/app/views/map/MapView.java similarity index 74% rename from src/main/java/com/example/application/views/map/MapView.java rename to src/main/java/app/views/map/MapView.java index c77587a..d20136c 100644 --- a/src/main/java/com/example/application/views/map/MapView.java +++ b/src/main/java/app/views/map/MapView.java @@ -1,7 +1,7 @@ -package com.example.application.views.map; +package app.views.map; -import com.example.application.components.leafletmap.LeafletMap; -import com.example.application.views.main.MainView; +import app.components.leafletmap.LeafletMap; +import app.views.main.MainView; import com.vaadin.flow.component.orderedlayout.VerticalLayout; import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; diff --git a/src/main/java/com/example/application/views/masterdetail/MasterDetailView.java b/src/main/java/app/views/masterdetail/MasterDetailView.java similarity index 96% rename from src/main/java/com/example/application/views/masterdetail/MasterDetailView.java rename to src/main/java/app/views/masterdetail/MasterDetailView.java index f4f12c9..d47d32d 100644 --- a/src/main/java/com/example/application/views/masterdetail/MasterDetailView.java +++ b/src/main/java/app/views/masterdetail/MasterDetailView.java @@ -1,8 +1,8 @@ -package com.example.application.views.masterdetail; +package app.views.masterdetail; -import com.example.application.data.entity.SamplePerson; -import com.example.application.data.service.SamplePersonService; -import com.example.application.views.main.MainView; +import app.data.entity.SamplePerson; +import app.data.service.SamplePersonService; +import app.views.main.MainView; import com.vaadin.flow.component.Component; import com.vaadin.flow.component.HasStyle; import com.vaadin.flow.component.button.Button; @@ -29,7 +29,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; -@CssImport("./views/masterdetail/master-detail-view.css") +@CssImport("app/views/masterdetail/master-detail-view.css") @Route(value = "master-detail", layout = MainView.class) @PageTitle("Master-Detail") public class MasterDetailView extends Div { diff --git a/src/main/java/com/example/application/views/personform/PersonFormView.java b/src/main/java/app/views/personform/PersonFormView.java similarity index 94% rename from src/main/java/com/example/application/views/personform/PersonFormView.java rename to src/main/java/app/views/personform/PersonFormView.java index 22e16f8..50a863f 100644 --- a/src/main/java/com/example/application/views/personform/PersonFormView.java +++ b/src/main/java/app/views/personform/PersonFormView.java @@ -1,8 +1,8 @@ -package com.example.application.views.personform; +package app.views.personform; -import com.example.application.data.entity.SamplePerson; -import com.example.application.data.service.SamplePersonService; -import com.example.application.views.main.MainView; +import app.data.entity.SamplePerson; +import app.data.service.SamplePersonService; +import app.views.main.MainView; import com.vaadin.flow.component.Component; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.button.ButtonVariant; @@ -21,7 +21,7 @@ import com.vaadin.flow.data.binder.Binder; import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; -@CssImport("./views/personform/person-form-view.css") +@CssImport("app/views/personform/person-form-view.css") @Route(value = "person-form", layout = MainView.class) @PageTitle("Person Form") public class PersonFormView extends Div { diff --git a/src/main/java/app/views/results/MatchView.java b/src/main/java/app/views/results/MatchView.java new file mode 100644 index 0000000..8926693 --- /dev/null +++ b/src/main/java/app/views/results/MatchView.java @@ -0,0 +1,66 @@ +package app.views.results; + +import app.data.entity.Game; +import com.vaadin.flow.component.html.Div; +import com.vaadin.flow.component.html.Image; +import app.data.entity.Match; +import app.image.ImageService; +import app.navigation.Navigation; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class MatchView extends VerticalLayout { + + private final ResultsView parent; + private final Navigation navigation; + private final List images = new ArrayList<>(); + + private final ImageService imageService; + +// private final ChessComService chessComService; +// private final PlayerService playerService; + + // public ResultsViewRight(@Autowired ChessComService chessComService, @Autowired PlayerService playerService) { + public MatchView(Navigation navigation, ResultsView resultsView, @Autowired ImageService imageService) { + this.parent = resultsView; + this.navigation = navigation; + this.imageService = imageService; + + navigation.addRunnableToBeRunAfterMatchSelection(this::configureContent); + navigation.addRunnableToBeRunAfterMatchSelection(this::configureParentSplit); +// this.chessComService = chessComService; +// this.playerService = playerService; + } + + private void configureParentSplit() { + navigation.getSelectedMatch().ifPresentOrElse( + match -> parent.enableSplit(), + parent::disableSplit + ); + } + + private void configureContent() { + Match match = navigation.getSelectedMatch().orElseThrow(); + + removeAll(); + for (Game game : match.getGames()) { + Image image = new Image(imageService.getVaadinImagePath(game).orElse(""), "image"); +// Image img = new Image() +// image.setWidth(200, Unit.PIXELS); +// image.setHeight(200, Unit.PIXELS); + image.setWidth("30%"); +// image.setHeight("30%"); + add(image); + } +// +// images.addAll(match.getGames().stream() +// .map(game -> new Image(imageService.getImagePath(game).orElse(""), "app/image")) +// .collect(Collectors.toList())); +// images.forEach(this::add); + } + +} diff --git a/src/main/java/com/example/application/views/results/MatchdayView.java b/src/main/java/app/views/results/MatchdayView.java similarity index 90% rename from src/main/java/com/example/application/views/results/MatchdayView.java rename to src/main/java/app/views/results/MatchdayView.java index 8df81e7..ebc871d 100644 --- a/src/main/java/com/example/application/views/results/MatchdayView.java +++ b/src/main/java/app/views/results/MatchdayView.java @@ -1,12 +1,12 @@ -package com.example.application.views.results; - -import com.example.application.components.navigation.SeasonAndMatchdayNavigation; -import com.example.application.data.bean.CalculatedMatch; -import com.example.application.data.entity.Matchday; -import com.example.application.data.service.MatchService; -import com.example.application.navigation.Navigation; -import com.example.application.utils.StringUtils; -import com.example.application.utils.VaadinUtils; +package app.views.results; + +import app.components.navigation.SeasonAndMatchdayNavigation; +import app.data.bean.CalculatedMatch; +import app.data.entity.Matchday; +import app.data.service.MatchService; +import app.navigation.Navigation; +import app.utils.StringUtils; +import app.utils.VaadinUtils; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.grid.ColumnTextAlign; import com.vaadin.flow.component.grid.Grid; diff --git a/src/main/java/com/example/application/views/results/ResultsView.java b/src/main/java/app/views/results/ResultsView.java similarity index 84% rename from src/main/java/com/example/application/views/results/ResultsView.java rename to src/main/java/app/views/results/ResultsView.java index 4a5e36b..7839042 100644 --- a/src/main/java/com/example/application/views/results/ResultsView.java +++ b/src/main/java/app/views/results/ResultsView.java @@ -1,16 +1,18 @@ -package com.example.application.views.results; +package app.views.results; -import com.example.application.data.service.*; -import com.example.application.navigation.Navigation; -import com.example.application.views.main.MainView; +import app.views.main.MainView; +import app.data.service.*; +import app.image.ImageService; +import app.navigation.Navigation; import com.vaadin.flow.component.dependency.CssImport; import com.vaadin.flow.component.html.Div; import com.vaadin.flow.component.splitlayout.SplitLayout; import com.vaadin.flow.router.*; import org.springframework.beans.factory.annotation.Autowired; -@CssImport("./views/results/results-view.css") +@CssImport("app/views/results/results-view.css") @Route(value = "results", layout = MainView.class) +@RouteAlias(value = "", layout = MainView.class) @PageTitle("Schachliga DACH - Results") public class ResultsView extends Div implements HasUrlParameter { @@ -24,6 +26,7 @@ public class ResultsView extends Div implements HasUrlParameter { public ResultsView(@Autowired SeasonService seasonService, @Autowired MatchdayService matchdayService, @Autowired MatchService matchService, + @Autowired ImageService imageService, @Autowired ChessComService chessComService, @Autowired PlayerService playerService) { @@ -31,7 +34,7 @@ public class ResultsView extends Div implements HasUrlParameter { this.navigation.setAutoselectSeason(true); this.navigation.setAutoselectMatchday(true); this.matchdayView = new MatchdayView(navigation, matchService); - this.matchView = new MatchView(navigation, this); + this.matchView = new MatchView(navigation, this, imageService); addClassName("results-view"); diff --git a/src/main/java/com/example/application/views/table/TableView.java b/src/main/java/app/views/table/TableView.java similarity index 89% rename from src/main/java/com/example/application/views/table/TableView.java rename to src/main/java/app/views/table/TableView.java index 88a0287..ad30ca9 100644 --- a/src/main/java/com/example/application/views/table/TableView.java +++ b/src/main/java/app/views/table/TableView.java @@ -1,15 +1,15 @@ -package com.example.application.views.table; - -import com.example.application.components.navigation.SeasonAndMatchdayNavigation; -import com.example.application.data.bean.PlayerForTable; -import com.example.application.data.service.MatchService; -import com.example.application.data.service.MatchdayService; -import com.example.application.data.service.PlayerService; -import com.example.application.data.service.SeasonService; -import com.example.application.utils.StringUtils; -import com.example.application.utils.VaadinUtils; -import com.example.application.navigation.Navigation; -import com.example.application.views.main.MainView; +package app.views.table; + +import app.components.navigation.SeasonAndMatchdayNavigation; +import app.data.bean.PlayerForTable; +import app.data.service.MatchService; +import app.data.service.MatchdayService; +import app.data.service.PlayerService; +import app.data.service.SeasonService; +import app.utils.StringUtils; +import app.utils.VaadinUtils; +import app.navigation.Navigation; +import app.views.main.MainView; import com.vaadin.flow.component.dependency.CssImport; import com.vaadin.flow.component.grid.ColumnTextAlign; import com.vaadin.flow.component.grid.Grid; @@ -24,9 +24,8 @@ import org.springframework.beans.factory.annotation.Autowired; import java.util.NoSuchElementException; -@CssImport("./views/table/table-view.css") +@CssImport("app/views/table/table-view.css") @Route(value = "table", layout = MainView.class) -@RouteAlias(value = "", layout = MainView.class) @PageTitle("Schachliga DACH - Table") public class TableView extends VerticalLayout implements HasUrlParameter { diff --git a/src/main/java/com/example/application/data/service/ChessComService.java b/src/main/java/com/example/application/data/service/ChessComService.java deleted file mode 100644 index 56f3007..0000000 --- a/src/main/java/com/example/application/data/service/ChessComService.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.example.application.data.service; - -import com.example.application.data.chesscom.ChessComArchive; -import com.example.application.data.chesscom.ChessComArchiveList; -import com.example.application.data.chesscom.ChessComGame; -import com.example.application.data.entity.Game; -import com.example.application.data.entity.GameInfo; -import com.example.application.data.entity.Player; -import com.example.application.utils.ChessComUtils; -import com.example.application.utils.HttpUtils; -import com.google.gson.Gson; -import org.springframework.lang.NonNull; -import org.springframework.stereotype.Service; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.stream.Collectors; - - -@Service -public class ChessComService { - // TODO: make everything nullsafe - - private static final Gson gson = new Gson(); - - public ChessComService() { - } - - @NonNull - public List getLatestGamesBetweenPlayers(@NonNull Player player1, @NonNull Player player2, int minimum_amount_of_games) { - String url = String.format("https://api.chess.com/pub/player/%s/games/archives", ChessComUtils.getUrlPart(player1)); - - List archiveUrls = gson.fromJson(HttpUtils.getJson(url), ChessComArchiveList.class).getArchives(); - archiveUrls.sort(Collections.reverseOrder()); - - if (archiveUrls.size() >= 2) { - archiveUrls = archiveUrls.subList(0, 2); - } - - List list = new ArrayList<>(); - for (String archiveUrl : archiveUrls) { - String unpreparedJson = HttpUtils.getJson(archiveUrl); - if (unpreparedJson == null) { - continue; - } - String preparedJson = ChessComUtils.getPreparedArchiveJson(unpreparedJson); - List games = gson.fromJson(preparedJson, ChessComArchive.class).getGames(); - - list.addAll(games.stream() - .sorted(Comparator.comparingLong(ChessComGame::getEndTime).reversed()) - .filter(chessComGame -> ChessComUtils.isGameBetween(chessComGame, player1, player2)) - .filter(ChessComUtils::hasValidTimeControl) - .map(chessComGame -> getGame(chessComGame, player1, player2)) - .collect(Collectors.toList())); - - if (list.size() >= minimum_amount_of_games) { - break; - } - } - return list; - } // TODO: find exactly two games of each time control - - @NonNull - private Game getGame(@NonNull ChessComGame chessComGame, @NonNull Player player1, @NonNull Player player2) { - Game game = new Game(); - GameInfo gameInfo = new GameInfo(); - - game.setPlayer1IsWhite(chessComGame.getWhite().getUsername().equals(player1.getNickname())); - game.setResult(ChessComUtils.getResult(chessComGame)); - game.setGameInfo(gameInfo); - - gameInfo.setUrl(chessComGame.getUrl()); - gameInfo.setTimeControl(chessComGame.getTimeControl()); - gameInfo.setGame(game); - - return game; // important: match is not set here! - } - -} diff --git a/src/main/java/com/example/application/views/results/MatchView.java b/src/main/java/com/example/application/views/results/MatchView.java deleted file mode 100644 index 68ace45..0000000 --- a/src/main/java/com/example/application/views/results/MatchView.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.example.application.views.results; - -import com.example.application.navigation.Navigation; -import com.vaadin.flow.component.html.Div; -import com.vaadin.flow.component.html.Label; - -public class MatchView extends Div { - - private final ResultsView parent; - private final Navigation navigation; - private final Label label = new Label(); - -// private final ChessComService chessComService; -// private final PlayerService playerService; - - // public ResultsViewRight(@Autowired ChessComService chessComService, @Autowired PlayerService playerService) { - public MatchView(Navigation navigation, ResultsView resultsView) { - this.parent = resultsView; - this.navigation = navigation; - navigation.addRunnableToBeRunAfterMatchSelection(() -> label.setText(navigation.getSelectedMatch().toString())); - navigation.addRunnableToBeRunAfterMatchSelection(this::configureSplit); - add(label); -// this.chessComService = chessComService; -// this.playerService = playerService; - } - - private void configureSplit() { - navigation.getSelectedMatch().ifPresentOrElse( - match -> parent.enableSplit(), - parent::disableSplit - ); - - } - -} diff --git a/src/main/resources/META-INF/resources/images/chess-sources/bb.png b/src/main/resources/META-INF/resources/images/chess-sources/bb.png new file mode 100644 index 0000000000000000000000000000000000000000..df2e407a2b6267f274f8cf18cf902a444a74b053 GIT binary patch literal 1395 zcmV-(1&sQMP)Px#1ZP1_K>z@;j|==^1poj5Do{*RMNDaNB_$;#B_$;#B_$;#B_$;#B_%8@EO&Ht zXJlknQ&L4jLOeP;CMG6MfFWN1000PdQchC<7Bp3YtKR#2Sn**100h%XL_t(|+U=RY zZ`(!`$MwTfR%=No0U1(cGLWs4fFip97X{jhK!YUR2sG{BBnWrX$R9un=p6glU4l=V z8zj;YI}$62-~Xk!AEYUnBJX%a(Exgzo%njW#85JE;+7_)5n=Zr-iJTOExvEgZv zV2)EmRtv9qT7-`9*^qS)QV51mN?c9E?nV*T>3gfGA%i? z_pxRpPY9jhn$PWq1SK8O!k8=1to|2ni*E>-;`dU=Cvs(pQ?61ESA+zme5{ApqQpS9 z(c;!$#(e5Fd|9Gwqr;4hyf2}C3u{qge9Jbl;XgY1>i6&=E|GG7j&G5v_EJ}O;PXKx z0iE#E$lFNRhPW^&QH(^FwXsx@Cvl0Kb;^qtDE%VsxI{wbc=cnJZYSAlDJCMIa=h$N zvI5P`wT)L&F3vhm#;e3#*~5jDE0Ciaj~92@Yc07#SIWg$3tshFvWVV>*kltil+p|L zI!dv$1Zy$5Zdo_{S8o#5R7bEb#!`Ahr4zHrRS{Ae9=!>daJ%2#nN-u zZ|Nh%{a;=D#;x?paXd-0#KbAu^FLdxt>Y+IkJYFCLo9tZOQVt9Wa=}HHe-#rgo-D~ zzsm|!tcm(5>LY0*FNld_rCC&cD6A-vejiKO!t70&C2z+l&2p3nEb;mj%id-!Rqvo( z*6|(IJX9Y0RnkVj$YrolmeuKWI=if6b=G;B#iJanxy1^MSPi*8%aE*16)Y;^D*X#B z7Rd>!(Z{+1E7X|#0+#aJ*POMNg9@n5d9*jxv8>3;FHysD`Y2@GsC)DL@cSX6p91I2m_D*4D8|*368{{oIPx#1ZP1_K>z@;j|==^1poj5Gf+%aMNDaNA|fIsB_$;#B_$;#B_$;#B_$;#B_$;# zg@b~3baZ22U{+I7PE1QfKtM7vF(xJ^&_{xB00009bW%=J01+`#e4f7F@$NwW7XSbS z14%?dRCwC$n(LaQAPj~p2X%`a?*D4{0X!mLz}R;8;hSI6>iA9)V-oXvH8nLgH8uTv zq9>7Gz#2^`*0BCTtm)6H_fKKH7fnBfC8k9Ut6`z#_A?g$UcNtMs{reZ8LVN|=k^Ut zY@dA%>%ArSMcYU3uVHPji>YBXtcKOFeh%wB{UVlHC3i4#{q*aPYPG}CKU6{Nq<#iV z{|;8SXb7-eq%U87t)}mS&~m}WKX!FO8FylglART(F-C@1LvZGD>fy}WNR$u3@MGv1 z^;h6Q#QWgt<`Y>T4o-T8(+v@R9?9&k(1)QlNn;Fsy$I_Q=MC((&FJ>Gwbn{$t&dkY zg_iFW+0nk*Y5jHNx4=3+|5Y^!SDp(YgiYiJI2mB=ztc*|?RzQJ{N;Efbx`j|N#9X~MmUtdZ7MQF1n6Ye63BDPb zPYxe2mi3}GX6%4I)Soey#Zpi&dLN36;nh`vFzpM!Lm^o0MUwNO)Fxl!6&@{}7YATy zC44CLu|SvCNhv<32(U~CsvUIPSOHZY?0m3FLGI#oxcPua^?#NFxfe-CSlVabTG zS;AcQ?jn(NcmvBMuR2501-C z`>(LbB~||_61(Q2l;w(M#@yOqo@y+8mBDjiFE83Zo%>p$}COJ}KSUSkYb zX~MsdlhHn3L#V3Wl94Qz1PpDY%u-dp(RM|W#vcFOrFwvCPu0I(Kf;AXh0KLUh029U zg~)ZFy1%7C#@u83TU7J=eT77&v8a;O$(N~;6UI8K0dM<<-Q#+Q>Y~hnQXRSz9Q8NC zOWiAFF3TJl76{uir_%G!y7MWQ`a!A6%DtpXb11>OR7P$=s;2oW341V2gbzQkoEO=J zNmiwg8z{C5xjFBO2_fET`31CK18qPJE;gV_vaDDOwS#>PU3`G!^a zn0^F{HY}(b*5|PlvNQ_TBlPx#1ZP1_K>z@;j|==^1poj5Fi=cXMNDaNB_$;#B_$;#B_$;#B_$;#B_$;#B`ho~ zcXV`SV`5fQQcg=sMM6S4IXEUJCi=Iv$p8QV33O6UQvebvNNtqB;QgzKce?-p1$0S7 zK~#9!?U_wa8%G$&jloHdNJ*P3r?xlKTW_I?TJ`2cL27SKRP{{K7xm~$O)4T1_Ploc z0c`pKif5f(i;Tt9$jtf*Az{@5_7<@J)vV2WcW1maV^&oTe$Lj<&)fXxnP*d}sZDKa zQ+rqJ=H0|l9{@`Up=J%>Bq7#EKw^%q;Pp;Ij-}Bze@n=*4E{As?PMIgh6A%yOUAJq z*fNVG8OO3Hn?;h0V>y^+ktE|--t|~DVEN-KqGk#`k44%5epz0)3TqDM16GZ-Ke`XD zl=|lb7HN7gJX@T&>kHU4%@Sh~%ii}~`*cFqhv=E6xj_bIH5kpkKbhVXaA2Ay@vUJS zlfphhKj4<<8r=uFOOq6lxm6@23hU_i#vLzPBy8IZ_Efuw2DZWx4su2v;E^Wl`emPT zFazBM-DABgaEqnP27cB&imuQtLTa?BsX^XREQwfzQbSLJuCb#yaHGySX6reY_0*XV z%RrBJ%)zma3Stl`}s~qu8!FY)V;eJXRK*QXH$sf;?91)N_Fj z*6N|;Q?-O;F9jzYSA?aOu!1+jakZ<53Q5~49hN~)5TZp}VOA4=s~jLvM>ImL221{l zLKRUKRFOtm)aWQk{e>X&7SD1pFK^TXL5MXP%Kd<~B)$CIvfz@XVOGsc{zGYq=VG@6 ztjAL6+7)EJ{gTos+r~e#Tf-G)9(|rgWleD#XMzy_f-7Jdr?S`QmZ0Yi;O!pI>PQr| zFLVod+2U9ZBoFK}KJ%7=AJA(>#E`KT;zQgt1#We3qF?7&?O4^BLr>_|lNm8Enfn^)UV+ z8xCX72HZs!{8~hTu=WvT>*|CQ^?`{MJdBb~ve(enyE+-o@p~#^= zVtFX{!9a+50#>|VSseO5ZvvffmKTRYw8pmtweeG|5c>b$aBwp3-*SA=+9m<j1 zC|!Z>l1-SAyD~OiTI!V9s@_tBA2xjh47o z2zfHJAnmE@aeQwO+d8dRD`hia#R}OTPI=GNVC-Wd-c-$TR@`7~w(k`C6o+Lq)_ynC z)~p%ewJEcbqtq5Tw$YK=uPSTSw1M(4(UnT{HCe4zF01h;o+t?FxmU0_t5!_2q!45l zyTuJ6wQAXM71kX@&35FKTyYgyf5@*$ZW0`4ucYgav_QGW>h$^eQIh`o7&WL>_1ZgZ|yi>4u}8% N002ovPDHLkV1gVs=h!tGxK7EnPy=ul~74pI?_gqrK6MN zIBlXtS<+r2$|=&mspL@V^nczV%lSH;uj@+R|N6eVu6eKLeV+UN-OF?8pBu;tg)zb?9*lv-oIn&x ze51(QXLEY(M^a6;WKr}VKu`TyR?Xo2UgChAQ&mYDE(l^A7X76`J+N?rohd-%oW>bS+Os7XZ6nAF}X7aMU7Y3Wsmj}0Y_|J|s7`Ha|RYQq4&DHCG z*~^+<8CAHB0<}GNj`6ojRp`>NQqO;W2M)?C-ofp_RV*nr+ZIqX*|n%~S=nBkU&tl9 z6RB4_2^&u{x{H0xwHJ@;IbbETbEoo&DKVM4y1|p4C#1*ik;5e?<*vI??8Dx=7tT~# zIMdLromiYbo>Z6+mv+A(`06jalV4dI$Shv%9@T<uJPO{W6%FiY{{%qFU9c!tvaO@aHyr$R zP*S~QeWBc{?l}_=WGhtCnr~KWRF|u*oqQHOTWQ9gNzyA`SI%JS;4?SNDWh5JRhb^M zVX4$D$H^5P_Pb`MXr12cgF2;OsI^;emh|kDQ)_yc-Oyc=>+Ud>wSQS{){@-$3l_18 zM4Q(K2+wkYvPBo8)cszcUCKS)eKF=$RUIb5c9~JtIQ3Yxjzg$s3BUTN?vK@5*&g&6 z8KM08f^?=sFM9{$NDJ(0de@unK30_5d?y*7Q$1^z?Jti*_7xp?s~HlCKK%3c@Sj`m zZ|COJC>YzwG#!1=<30(0jqR8`qfEg#w(;2YiSg&wLFePPUXxBTb3jSqrW`!2Q1k;) zxS>Tw@3&J<-W-i=tOgOYw=n(ZbqeL{S{2DxqZP<+Y*RJLc3Fc5K0T)HnM}y)a)za< zD3PMr^2=J=x5inyuiby#)u9rmR8;%Ztkg9r@gX&OcPHG~*o8aVq_IM${_rOM(^^6K z6>GL!32hJ5HTqM@UC=&NOjnINynlU!>ck554BGrP+tB5e=i0rG6C%Q9z18e4aM$o} zyz*?u%DofY=DqVgICrhzb&<7qmvrssHBNDK`S1|l9JK?@hp4*AYoOO!LM;2{1ZiyB zPmkAkUsdmpZO-=iG##L{Aor%s|_QK6i_3%rM`$=EBtCka5OP43QiDutB0` za;6b}*FJesR;QL6mvy#iLT&Z>V5N5<(QLt^Cjnz~m}26qY^@s`6&%g7vR+IKc1Vg) zt-z$Mm>7SlPpoK3MlG0}@L*rVI-evg-N#O(y}rIG z-ezC7Gy|rbh{-;w@h zPAb=R<|fiTg|pi^HoMiXLRewuOYf$;zfTR35F)^Ed8Pc{XOd^gg~x?TUMs+;-5cO=ZgT!%E<^ z=r(ICOgVGwx4rMRi=*@AUyEvNq4XWlx`z+!hGN?nkV9wz zyh7Q7(FL0A#JRUw3)RWuSA{mkrGY0)3OfabQxE4VhKtN_?|1s(6l358X-y1;a^KQs za!aH1_~jXkmdh)vtMO@_PaoepV%1f6rSiRP-NU=AmFJ2LqGLs4;a({vur)>D7i z!-n#P+r3S5FKUU(V8_z(UhIPD8rQkKYX0MrV{Z0Y-qd_vu;oKdR>N(L>vw~uH>-)t zx|xd-BHqb0lxdnid%0hIes`v&;>!EJ8TXen7hQYQ#9s8IeX;XW?Q-uX+o-KURk_@* z{Ts6l$pL;(a2$MvC}`2`yS}fTb_Vc^YUb?-D>B;Ua;m!^_DPZH<(;XCUx1H-f4hYDDXDeM0b?w`rJGJ&_> zrDTx#;01&Oo`Vn{%LT+9L}XY3hJ~?94zJuZ#0coLU1F$Bn})ar8vrJKKZ1754lL!* z2a+y4MdV+d1#s@`1EoA`CAhN(MMO+ThKG^ai9@pYR@ z3k<10>ZIL#GSm8lOlKxvILZF0ED9x+$g#6?qubeiJlKKbT=w#f7EY(FwQ2%9X;+f% z%v6`1aoaH`Df!`#^XJ5`zPcc|vFh$seDKxu{8Ebifw8hyYK2M$7t5%n^6_o5Nm*GL zx$8Iep3J|Dtxf1yalE{zG)5MkBJX+Oz%uK`Il7b6*0r?mYwnV_daF`B=hQ^QZu@AW z%%zv23DW~QbIs57weDhB*Jq7?v94O+OrCQ`@y;X0ya&f!wU|H9bu4F0Gkh3do#wa2 ze?^C%(7SD$j&8>G8A>YaYm_#dZOt5?DNd&3?$x}f;In1&#YNeTb5jmKuMf~TvvfA+ zK!cWp);uSSoC+yKKTlf0-PhQ|IX~Fye*1L(J37Dq?yQ83EUEc>)3vO6r@wpNG{@Pc zl)g&i@_XjZ>AKdJ3@-1#`A1Jl7}*u|!H~D-@cYJbgf4pYi6UBRTvb@xowB0(n96%f z$}6t^V8_?9V&u4?Ze4nq#kYQ;_HdCPX6dtz*HUNP7M>$lR_PFY^Ph^+B6}kK_@i^% zf|XXkMDb6k%f)~bxN-~!9JIX|&QumR%m89@nXrL4j0XefTM{y5hSdoJjR^Q4y1b6I}AX8Hw$dA zP{^a=@sW{{29bsaTz(LqXliPTCy?+Y5)M${1X1BaNQ?^?=pqpP81}G$#pm#Z9Bw!U z!GxGxk;VLL5`jR$5lA?aDSkLVSYR@;=ES@B-gEcn?^>74caxEdmY~>JAsm3l#~5 z%M=M9iyYmkm7;)hCT*epC83Wotj z1OS;hf?mi89NM4}_8=?&q6iQ-h(Ch*qrW7&Nc>8*=dwhIP`bSZ7SWf==CU|!s$^(N zG=fR6F&PIDjEOiS7MqNtP}rt8vI!G1Boc`PA_W=-MGqGUp>P(AKml+A4!~g>8Ij4x z6eAo3A_E8`!$6#=A)ASVNhT&H6p}HS2*JZ3T=^W32~g;8tq>?SfFi&YB4lV{j58q; z$UqyIfP>hk6r2e}q`+hX$%JBTB7s8ofokJMx4@DN2tzY&p^z|;%MSzT#R+F~BLzcC zUYs!4QwSk$BbpG6jZ6)VNhBiz5&VXT7QlP~2y+CLNH8FgBr9wd)d65aAlx`%P!Npg zg$GF%kd2`NbAW3hBs&1IWFA;Uwd2E(kjwYtazib!h_)C6Qj$~{^MQ1sI&)bPMhP*@ zMlx<7=WL-MyyVp!|2g7+LGlddMuz`;I76g^C^mdyB$vO`mG8<7fmy=O<9v#E5Xl2n zJAsfNMgIq*{z7NoAFxh0T873ZFw2NV=nv#U zbOAR|7zy!Vn;;MaV4p#9N%k3|KM;R2M`{xp3?sosAQ5o{LmZLlMIus(1S*k;?ceQz z-5(wEOihdpp+I1s5ljGi3I&?rAf_=JM`98n5*dOam~1#w-LGOEiAo@SG|wE5G?0&* zX^xaw27@|$yUmdjOr;}v<|*RwLOC#hWEgx*i@%{8#y^mP|HM9=te@MC%ZmaclAi8%VBElmMW= z3;81des|Y*cYTouzKHmHbbWW%7kS`|h`&eIS96#A(2W8d4vw{v;J#p0$k8X@u0f9H z`TkQlTSxEx9Rnq=Qlltl4wW7S9>jj97j zijwTwXzkS}L=6SVXBS67qhW!XzMm-$N%u+%N4F`(nWSyCw(LTWtozFz)!B?#0fM)W|sml4MwZ zywd@B@Eb z-@0IqddC@=!EqQPCrSHI zLbJ`Z_6gwJGmxe~`GIzl&KS@2;>lKN+bfekj4|mO_h!Sxi#nwVZAzM}G3@&?Q!fO$ zJI!{OYNFa|!;@7>bUv|q4a)Rbe19AInp->yC$CS0$zRf7Sd0CfL%$l?U=#j}9;0gf ze|hFhT=^vqbej3Rk0me33`vfBIz2|`W8f1ZISMDo&w2xcP66%U+e`iGA6B36JM=X&JdQsm{9yDmAn zv%h}dm3^RmrrS~^-Tw{o@k(e-^4Y@lxBD>?<4ef?%_^Xe{oWD2cZC0;%RgH6lM`EQ zIXBCu+HxLHkP_&0&u-l zn&6;=-u9-_q02}0YVwseievk4nLN2UI@T@+z&g@~zGl<^YNzmjvnoi)hPBvlQZK*p zVSSXpohw)NiROS_iXxo39j$4077MNyk-MivPx#1ZP1_K>z@;j|==^1poj5Fi=cXMNDaNBqSsyB_$;#B_$;#B_$;#B_$;#B`ho} zcXV`SV`5fQQcX%pMM6S4IXNaKCbU?*3IG5A33O6UQve?~R(hkv;QMdqU~vEd1L;Xb zK~#9!?U_wa6Hyd~TiOas;zF0;M%|Ufn7G3j65Z8*fc}EIFmYKWZh*vDPx%GVKLDIo zwkj01CFHhSk;DpU8R*Ar?o2=CPAR=Tml&h-?#klHIcLttJ3}NADpaUYp+bcU73!bX z%?Ed`iS#f7p!Vb%NYSV8^xB;D3?02UMco6OgSA}YD}a|~sF;P;hMgm#f(2*Bh?Rn~ z>Y|7Wz^Mr;4(!`2 z%IN=VpdLuE!d|Q~wA79e{QVWlU|UJiV6R4I{RJxsVY2UUpy_*v zGDZF!ids16Whlxf_c1ct4Xh}HFuL2)Pq-D!OH|3sPmEb`Bx*;>GDt0G@Du!eC!+4#bO!@RX)8EFdrjb8?8liXtMD}JINA0?|~w}B;FIkpAaVyu$Q zqG8+0f%L}cgvI)@xw%FGR++_0DhsEbBXdhn_2yb({a~=h1KZx4Z{EgFpbzKOjy|9D@Re0ZEl5yr1uw=kYQYZ@8m#b8~YUr^l+vKNzgTOsm*o zvHemJfo?auUw zve|clh~;#rS~i$z>APbss(dHsmVT+XZbStyjLNm?+czbXf<-MS>)V6E@cTs8zX+=a z9hSoWihn_u*sm~=7@XeSE_y4BJ4W|$;k(;jk_&88xM2scqchD6tKt6yllRWh0 z84}T+X2HgBI4mq$*F3vPWi=1#iet?I8r1Q=-q#$Xv@wWz_`(rVU3+Y4R~YgvP}uF3lFeYo^&T>^UgPx#1ZP1_K>z@;j|==^1poj5Gf+%aMNDaNCMG5&B_$;#B_$;#B_$;#B_$;#B`z*4 zcXV`SV`ElRQcg@uMM6S6IyxpMCLbRk@5vey00009bW%=J02Vk}b(Fl|{jCoG+yDRu z!%0LzRCwC$o9mXVDhzL2I#9V;>`SZvlk390o zBab}tNGC8tR{C)Q@BKUtXDfGVn!Wchss6X1hOpo&Fmhnsc#QDVuYh%vM*>4JL;)T$ zwzp=VROO7;#--&)G9;-AvJrD@t}asPpP!#aYpsoc6UDF-bUDfJ~gEpDOJ)29Lnee)q+MuF4fY6!DkSaHa2jL$b^VWYinPxoV&E5d&c?|vJ~KHq1d7oTnlx3o`n0|0ZoVRTJVvK1U+*WmK1 zW+)W88!^_@b6+|4N2sjP1I2vi_E)WV_m9wJk}^p@){XF?%{&bRxY46ed$@gC82NK| zK&MYpY5>JM-KMK$^(z&D@&I{Z3gxzDZU_SQ=ZgCrK0c7UkTb=dRfbD4VX7 z`Lc%|5SA(WM01A4H+0}Dnl)84T`{xytSugJ)kXV6&}UeRY3K}-C-^qP(Ox}ajrr{O zc~OgD@%BTu=2Xm`B8>lBBTlg`F0deT0D`46D~|Ldie(urUyD`tF7L3S*UpR$SuEV! z7VpzJmSY+{$ew5U8dX3uCPCEnu*6m#0|A;?#!PAgp5Uptlf%$I*{#?@pNu&Yqw20UzjKTvL~ARg%?XAyDX< zU}ZfK>bEQRa;BrT!CdE9I#|&cHcVbOl~lQ|YCGF>QUR9cz3uyqt=2k|!QFRr;#m>y zw^Iu_)pi-%X%kSck(Tnnp0gNzGS}p(}B5SkZ}S+*q-opfYI- z;8k{e9~(s=%j{eoixsWt_e&8v&QA9+|}LGjy`_! zAJwz#Ys1+v(RP^1tjfB$i!&AJG1-yF(!kg-VPPtLbAPZeQ=D5{bPmh1|J}YpHtXQV z{@`5LW#i%iG-t!~hT?a6-4MULKd4H8HEil?v6RYeHoUwO$K~F{^(B_OR?O7Kh@Gn* z%aHfk-ii*)K1cS-eTU`B&fw2mj0Muh?{9N|7!}t8h?5C30NW^JUC+6AC!IsMA|36CF+y;~f*$?Xq1< zjCYhJb+1JxMp!Er9o{9zizXDjZ8P0>`kl(koevN9V}!M$(P8iIL5527BG+A~Kd3~n zz1>WV1}RJMjQ>_*%&4sF?U6f9pHqSG?UCz=F{iT9w?{4~MnvVr?`d3gdPLRWn&-6` zfvFl?m%5Y~F;$bxrxy|2&zD)ALY`9KJF!niHrt(Sc8l#;g=>695KEe7Q9h-iMXv+% zFKcpJ^j3!6ajy5)8=n?2W0!uBcn1i>{WuAADY*^s?96Nsup!7|X%MiYJsR!%9`fIVglNK4Q7V>Xmskx0b n`;qk{k390oBab}t|CRp$w(O*H3mkD=00000NkvXXu0mjf=a8y< literal 0 HcmV?d00001 diff --git a/src/main/resources/META-INF/resources/images/chess-sources/br.png b/src/main/resources/META-INF/resources/images/chess-sources/br.png new file mode 100644 index 0000000000000000000000000000000000000000..722db00de6d73199f553ab12450cf3dd339aa342 GIT binary patch literal 1303 zcmV+y1?c*TP)Px#1ZP1_K>z@;j|==^1poj5Fi=cXMNDaNB_$;#B_$>%CM6{$CMG5&B_)W4g?M#! zZEI>^UR_pGQcX)rMM6S3H#a6GCf#T*LI3~&2XsA>v7{-6Ic0d;qGIKssP{5vXC}>Fh4-i}QNI^oPK~O}gAfe_zKnPt!fl}Za zDS-|}3W+NU6fBDZi4g3gB(ZKsN3f;DzL#Qm&wIZ8m{}i$V&Cp&cb|El_iH{58f&bv z#u{s^v7@FOUg;W$2KM-qExjYLU0OXh))h%@x30$aqS5=`00I!1^xYRONVK(`|IK{v zXz=Du;L#~i99-YBOQAB0T3dMSYv9tYe(qO!g9{(tOnE5wH*6>qQ1)+q+ zb(hOaB>*S01Ox?Zl0sY8dW^BGUbb291dHX}E)VPKX9*TRB`%Md=-&^6yysYtRu#$^ zLkrHn*G2E!*a6yAW6JB`*2M7LJbslLD|)f^(^$)D@KRpB&v)&=#7oVJm-gcoR_bx( zwOfv*LGivL)~FOKPME$k)?5XacE*ycCrUyY0(#H7#&MGirAegNcivC@z(S$I5HP&w zTzYE6PG*T$8YB_b)}Xo=>s-dKZ*sp6sIJl`9gM^df*9(r=iOUEaDZ$nW2T=(V4&Og zDAO}iW*_+NG2d8E3rf;G=9uN9Q=WVBx4uQ9D6%MXSj+|ke?RB3rX>Y_H;$DIqVA!$ zA{ND`PaNGb$hNKB3#Yn@OdL8?4PIFrOs{ygvDkLtRro+gwAkdnI~WepsqB=d>r5lqB&?u%r&J znVma|{U!DMWlI(UJqupc;ngbOWy_jj;9uH>tONH}Sa}=_Jla?G0_7=boGF%+CF=}% zSwE~^X*+H`t=cYZU!}zz)F?;mi6u3Pd%ir8v_YLtE^sW7Sl>H7P}sK7YI6E^vOAQa z7cWJpQ!u%Kw$I&B=gP#ZZhRzt`-T%%=OJ)^ zW4nlT`;}E-^^OCU`l!cmH_DxG_9A;PPQ`Tk=H|@z{PY8uHB8<$M+P#Ac;@5b>8e~k z$9lV4;Vxqs{4wq7DXdTy797&KZS1pEzE?eQs|{sax&kY3ICG}w+^~w5M^Dz3Sg!x2 ziUZc{c+GMhYI$hv{r7v{2FrPUbSiB}Ec3tAxOdt8+s8E4SYwU(*+1Doh`A(7Y;6Dl N002ovPDHLkV1j$uUJ?KR literal 0 HcmV?d00001 diff --git a/src/main/resources/META-INF/resources/images/chess-sources/wb.png b/src/main/resources/META-INF/resources/images/chess-sources/wb.png new file mode 100644 index 0000000000000000000000000000000000000000..5e26a38b911b1d038f24f8983cf7c29e60e6a43d GIT binary patch literal 1643 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 BDSZF{ literal 0 HcmV?d00001 diff --git a/src/main/resources/META-INF/resources/images/chess-sources/wn.png b/src/main/resources/META-INF/resources/images/chess-sources/wn.png new file mode 100644 index 0000000000000000000000000000000000000000..e3826759a9ec87a7428b19c7fc6ccc11e47ba615 GIT binary patch literal 1682 zcmV;D25tF?P)Px#LQqUpMNDaNMMXvU`1nRfMnptJLqkJFMMXtLMMOkI zK|w*&)6@U||C5uG?(Xj4;o)6fT~AL>q@<*7Zf>`?x5&uIf`WoLza4!5000VfQchC< zwg3N-Me*Kk9uSs-!Tgj+>0x+$tuacxCX;F7VA!2+FD(CJFa{H;S<(RwA@ly@kCDzQPgC^tHV`Te#u%&QHxfo?DguciVVyF?q6jTv1*ftJYjnc0kkvJNFYW-Y zwhr51ymmqY4>k#z2Xt1wrs|rO1GrcpkgJGajk5hft&VIUT$Sbu3Yo{td_mtK!ah@#aml2y%A z3Rb>YR|l}yd@>wAsh+7gY#SQtY5;p}G-R>tt6r(T16NgR`y{A_O+!8klP+Vg6no=Y zYRJil!6q4L*o}u=Nmq}Xu6$FpJ`b}Pncf*FYOxHGwl_1mx$Rf18 zedEBIEw7tY>RB5Ith$dU4&|`c3rkn7Z`1~(Al2)`VXYUIm*=P20HrF-xmy6RT94)? zA8P}kGDtgzG$S2;Qfy6lEJbQ>qj$f(SblgjO-Bp&_-276FE7R7XccaD7-2?z(L6jM z=k>v-LX7vT#||+G<7QwxeulQZ0AZ=iyP~~cbxOfIJ9eMO$kaI|;R~$Z2TPTQr(->S zn1&p@nQ_gjfBx|x9Fx?C(EOpn$>6@+SLtPNcc9C zHFxTg5qPpZvBt-enyeZ+7GXx%`QAOT66Awqd2H1aSTa9Nlv3_UXdTEQBR7V1#xP)c zv@GhyPCCz~&Kn86+Q2m#-KU~^Rpd-UoGHXekmkwusj#Iwz4F;o`PB#5h^ZFjLkY1) zNiM4M8=p4`Q5^3}^)4Zn%)|?kvwKvvb>7E<^nyx9i%rF;UsDU+O>Gw(GvK z^JIE9Az0f~y;?m+KMq+d)mM$a6AD!x^g0C6?C|NKSb*|S7|OKE4Rw1n1g$t<`(=y9cOS;Rq%BrW3sUH2C00wVfg2luif%1yuEO8($W-PD zdFqWNv9Y*6mcEL`#v=X|;=Wi49ZNn~50<^=udoBf@Px#07*qoM6N<$f~PDXy8r+H literal 0 HcmV?d00001 diff --git a/src/main/resources/META-INF/resources/images/chess-sources/wp.png b/src/main/resources/META-INF/resources/images/chess-sources/wp.png new file mode 100644 index 0000000000000000000000000000000000000000..6d1b1feaa4790dc03ed0035947e886b49eea7952 GIT binary patch literal 1183 zcmV;Q1YrA#P)Px#1ZP1_K>z@;j|==^1poj5JWxzjMNDaNK|w)7LqkMFL_|bHMMXtLMMXtLMgRZ* z`1ttm@9*N`;?vX9#Kgp}udkGplz@PMYiny&RaHhtMjcsvD*ylh2y{|TQve`5U45#` z;b6n+OaK4_?MXyIRCwC$o7>W>APj{o^%Mz;toMJ{eSuofw!26=|FCY`nSPUm5Ek_D zNJ>gdN=iyfN=iyfN=iyfN=i!lRb@&kmHiZw%1aC?bM+%($}22XZojxBa zXIrDS)~2;XE=8;C2>|E~)in)j+8zL)gcImY{emJQqSgVxQ_lBoOQgo=nQfI?;w+CwVR+>4~K1kfB(5pgRKE;Xd^h>A2@09pLX za?LrG0T6q81kjyPQN!E=Rs0fIZG23(fM6@*s_krxH5(JTmNZ zX-_3~PV~M=y9>pgpgS^n5U=!&P%P;|_~ZUm_l=&^Lo9`(4`_Fqs*e^V%t}=b=GJcG z>YR)x=tI>t^}&{CBmy>t>ew0K_yHS2MaM_7hBton7q()_ix2b%HGb==Z4F zh#f-VB3u&{_c708#p0UI@Jj9C<9H*gTKw*sip}EVh`Y}`TyBHKbE=q|b(Rk*fqskS zfO7nX$S_y|R&TI+nM2RYir8@3_~yf&akJ(Uuxd7gm!=I@D|sjEPuBgafsQpVSX|lb zoT%5u1=$=j?QqFvu^Mx@;c~I9@746&(k_=3e4tSQZhvrK1F>-B0NVP1%Su&OhE=fU zvoaeeWR8>oHV#Cy==6n53U{s)o5f(7ORPfI>^-kp41v(wbsJ8-eDE>Xpb2_b1Ya z%IRyW7nrvMi|poFpNzmOtP#w6sFk`kfo@3P8&uPMOLyl()ZAZMd_pynnfp4$b9!d_ z3DkHUbXR9pvlaLum48uuk9$+iVnzR>?v6P+fA!G+qaw258-50$r*EK$8W%i`#V}rd zLFLOU4;?J~EfrB8*aOJNV0}eJp`R#K{^8`8R77DtfXfHWpEQXqXbzhIRHTDuu>|@M zR764jI9xyHe7~huA=`rqLPa637oPxh7%UTTj<|d_DO2+~;OanJ0r#I`ZjpY!6#qV! x>jEh(R!IGItSYE};jghtNl8gbNlAZE{{SEr)R#jXkvjkY002ovPDHLkV1hhEAu9j? literal 0 HcmV?d00001 diff --git a/src/main/resources/META-INF/resources/images/chess-sources/wq.png b/src/main/resources/META-INF/resources/images/chess-sources/wq.png new file mode 100644 index 0000000000000000000000000000000000000000..bdc6ff35005fb4148b65fe29659c2dbfc1b6e5f4 GIT binary patch literal 2171 zcmV->2!!{EP)Px#1ZP1_K>z@;j|==^1poj5PEbr#MNDaNKtMo4LqkMFL_|bHMMXtKL_|eJMMXtL zMMXvb|Nr>-`0?@a=;-L)-rm#G)5*!nyu7@xudkq>pplW0f`Wo@aByH?U{O&~Mn*D& zNGZ!ai+>ALq9$Ce%3Q#rY#$->)4 z-L6oRR(tZffGdY4H>Q?w%&Ai++Wg5K!1~>kOf{NWm)k z0E^gBR57f#PX}DyQ~d116uz#uw-mHiQe+e_rlXjWty4c_PFTK&15YnEFW3 z`>1!GfU9G(zo9^3=!qu+F-KpXP3rMj7z^Ekf^X{9B?qu-3DL=y(qHEKe0$pZ06Y9jtd?Nr$DJNpVIwaOI zEu1YGF&nj9BX_?qj3FVgiO;QP>z5V>dc@q4#r4|A49_Ot{>sDyr|^_m~$v96{;ejb6JZCG@Pq9aHURt5x0y$S9E8d8;> znL&3=Ku6fHNUdbEa`fQ%AO~H*2nBa5P#gKpT?m)%x$?+Z=V*4S-x>QE!CH3DDNwcw z)xkzkDLv7E9B526SfHH<9jv7V#xc|lLjD<5FODl){e3yL%&gW1uF?UEEvG1h_3v9V zug{8RYF3>^t>s5m#{0BsrUt=?Ej1DEE!OF8@XxSvGdJpGb)Q0|@@vsdEpg#;!m5SD zRaU#@tuX*9ww6LEt8;sVQKod0SvBi!#TD7rN!chJvDM9bwXP#ko9wRwSY9~N%TQ4C z>5fdH!q}|^JuB$dF)Ft1w_e&!jc^LDxMDXfDjYFfa!%`T!9hnQdgU}-tr03!6*A55&=UU0diMH=V7w(B=q$o-?o{$OFPExN29$%xBc#0l0~)9dlU z<^93b&Y~3;bs=zKUCMvwIF7lz6K6F!>Zy9iiX66DqQb$CH#6UA1asgL$6+zFo>_nm z@z_-&>2wAbfvD)V$?LPno4Y(ir}+ddF; zcfxy~TxTC@=QXRh<44cK#mLp$T{XI$09C$+8Wu5nhcL)-S>kN^JVF>C;oZb|(cVX% zBFJ%B>Ta*DCYB!^ekVqc5PH(#cVfIA!eHmav0FP_3!yh1{y>ZuQ8gmi`LLT9FC`YZ z1rXxeRv1)4FLL=3Bim4QA@ACF662OwVdyXrF&e0vu(wBih|xe5hz^4gV{O0^fp3po zCq@%hAN-!iRbn(z1*1b>Vx$1o4cDbE5u=&yLFv$akKh`rM%-{+>O3(rh$<)@UM5DE zR-x(eDluYL1*SvSwX7?y3QdO>h|vWqG##EMMklE7ba;vwDRYAgPlvACbt?qkG;P~; zy|O{sIO;!!zVExPZJHbD5D_EeZ8wb5EaVXr^E{11-!(Vh9*zp>WBDEHFiP_;E-_7f zbmZxqlRqDrnZH(B0@F6UW>o#^$2O{RziGQ(#oPF1m4*bi-F}>>fz#JnqkNde`J0nR zct^^)uU|e^_wFC)d7+w`m%lByGP7XiO5dyuV9O8mLc}qy)b#`W_}4+wRwKbT+d#L} z^Yu>V3;%fRv@Or*f`m~C{m~ndi7iNnlLkF6cprQw0b)3jur>#XVijPA(!Ltu+tkN_ zw!f`A2>vZ;9T*n(Z&cG$2h+!ouM=-rA~Y=ecfun6iZKgy5cMyBB_3E0tmSreAKHSX x{4Mt1gq0Te*suI=Ess6+*kg}9_SpZ+{s9?_0NMlHk)Z$p002ovPDHLkV1mV&9<2ZX literal 0 HcmV?d00001 diff --git a/src/main/resources/META-INF/resources/images/chess-sources/wr.png b/src/main/resources/META-INF/resources/images/chess-sources/wr.png new file mode 100644 index 0000000000000000000000000000000000000000..49b7d0f7bcf0fbbd0996eed0de769810cf60a2af GIT binary patch literal 1490 zcmV;@1ugoCP)Px#1ZP1_K>z@;j|==^1poj5KTu3mMNDaNK|w)7LqkMFL_|bHMMXtLMMXtLMgRZ* z`1ttm@9*N`;?vX9#l^+6w6vh0ppTD_dU|?eV`EcOQ$|KcFD0vP00008bW%=J03t?g zm%-rhIX^A4000FYNkl zpN+NM&3w5(J{C(vL;#>0eD&vWi2m9B8rnAiKr+&|O+;H`%te~N-SxIQRZ<}UM2uJq z$eF^tTm)3r0$5^gJEO7yIJwI=q(VKct21`M!8zu|68k#*se~994~t^}^*))teed`d zcn<^%!?H~a0CegUz-Eixx6Apd;}|6`A7lq~M*!AZBLH3xoy&(MEdbYb>@V+dag$79 z9RN6FG04zZwKLWlpncC9Tm02s-9&*=4{O|?uU{B|uKy%(&TNBwR~Qo@ofkn0PY+JB z4E>|(LF*8RnXslAPJx#zmS73%1<<679jq3NhvqK-+0NWQf%bB8=iQZ*SF8U#dm;Kq zoumvY;cEHkq@Mp%&Wt0wK%48q<(tTe1s`i!ttl3AJMjR>B$Kz+7$cY|ut-3RF}9sZ zDZnA?;4{6n1Ms$Z`xLx-4SltkGq!G0rV<}`g`*%Gsg)P&rWXEo_pfbNZ(` zXS-xFT9WK%wDb}p)*5f}Df1v|-vB^66(b@cQKJdBMlugdtRk&J3BJ9t(x;sI)XSTs@jNm%X2UYS`F zAh0Wqb+;a;=Ey_Yv2MBeAgnv1$dv05SP00C6Rwnn&jhs?3(ki)G2rI)Ik9fql*ZbH zVd=`mWpd|-8Lot`XtL*rTQ8Q!3a<#bs)Q(|))cF_69ey^T$3T=V!`wG8Tc$fNe=EL8@Aj!DR~NhZ}x*7PYP|wLDhRZZ?+1itFr5&k*ryC1T0b zV2#?A#M-6JD8v_nrdWRP)rwABrd)nlQwT=)#ALPbe^V>E+Vb;!QLOYG%g>0#r^4bx zu-Y|hwWY9Pv+0ViXo}_sJ__qWYBlK*-!JIMXiEsszu9k+_qe1O763i3ZA#cqAfjLL zgfgzMiB!w{9+^UucAZAF?Keg)NV3f0+rb6DU=WC9?2A9^F)T+fy+9-VN@u^2?YsNC z(|lN$cMGUasj(?lj2Jtt@rSK=hG5BN2LPSx*1TFIjcov6e_|Fa*|q>qC&gMbn+<@& z@jh3;u958y(4VIaFJaL+EBF%dI>vpqnpeR6oOHI(G(?$p)2|kI?^a{UAAtT~!n5A| z04cv2;M+avO^BC|oObl2m=_TNk0GHGg5{j#d0!BKh;tdROdGN5D$E?vnw3}*wZAFI zx_~GRz*6SLqGrL$OcnIJ@h`?RqDEhE=Tp09L>QnU%*&5rSo_ s69eRm*Ju04zT2!4RMkNB{r;07*qoM6N<$f@NaJp#T5? literal 0 HcmV?d00001